From 292ebbf0643060fe2199cf4cf1b48af6e3fbf827 Mon Sep 17 00:00:00 2001 From: Loudrob Date: Wed, 4 Mar 2015 17:51:50 -0500 Subject: [PATCH] PyCrypto --- .../Lib/site-packages/Crypto/Cipher/AES.py | 115 ++ .../Lib/site-packages/Crypto/Cipher/AES.pyo | Bin 0 -> 3543 bytes .../Lib/site-packages/Crypto/Cipher/ARC2.py | 130 ++ .../Lib/site-packages/Crypto/Cipher/ARC2.pyo | Bin 0 -> 4241 bytes .../Lib/site-packages/Crypto/Cipher/ARC4.py | 120 ++ .../Lib/site-packages/Crypto/Cipher/ARC4.pyo | Bin 0 -> 4023 bytes .../site-packages/Crypto/Cipher/Blowfish.py | 121 ++ .../site-packages/Crypto/Cipher/Blowfish.pyo | Bin 0 -> 3786 bytes .../Lib/site-packages/Crypto/Cipher/CAST.py | 123 ++ .../Lib/site-packages/Crypto/Cipher/CAST.pyo | Bin 0 -> 3823 bytes .../Lib/site-packages/Crypto/Cipher/DES.py | 118 ++ .../Lib/site-packages/Crypto/Cipher/DES.pyo | Bin 0 -> 3714 bytes .../Lib/site-packages/Crypto/Cipher/DES3.py | 133 ++ .../Lib/site-packages/Crypto/Cipher/DES3.pyo | Bin 0 -> 4457 bytes .../site-packages/Crypto/Cipher/PKCS1_OAEP.py | 255 +++ .../Crypto/Cipher/PKCS1_OAEP.pyo | Bin 0 -> 8579 bytes .../site-packages/Crypto/Cipher/PKCS1_v1_5.py | 226 +++ .../Crypto/Cipher/PKCS1_v1_5.pyo | Bin 0 -> 9203 bytes .../Lib/site-packages/Crypto/Cipher/XOR.py | 86 + .../Lib/site-packages/Crypto/Cipher/XOR.pyo | Bin 0 -> 2495 bytes .../Lib/site-packages/Crypto/Cipher/_AES.pyd | Bin 0 -> 29184 bytes .../Lib/site-packages/Crypto/Cipher/_ARC2.pyd | Bin 0 -> 16384 bytes .../Lib/site-packages/Crypto/Cipher/_ARC4.pyd | Bin 0 -> 8704 bytes .../site-packages/Crypto/Cipher/_Blowfish.pyd | Bin 0 -> 19968 bytes .../Lib/site-packages/Crypto/Cipher/_CAST.pyd | Bin 0 -> 26112 bytes .../Lib/site-packages/Crypto/Cipher/_DES.pyd | Bin 0 -> 54272 bytes .../Lib/site-packages/Crypto/Cipher/_DES3.pyd | Bin 0 -> 54784 bytes .../Lib/site-packages/Crypto/Cipher/_XOR.pyd | Bin 0 -> 8704 bytes .../site-packages/Crypto/Cipher/__init__.py | 83 + .../site-packages/Crypto/Cipher/__init__.pyo | Bin 0 -> 2641 bytes .../site-packages/Crypto/Cipher/blockalgo.py | 296 ++++ .../site-packages/Crypto/Cipher/blockalgo.pyo | Bin 0 -> 6239 bytes .../Lib/site-packages/Crypto/Hash/HMAC.py | 212 +++ .../Lib/site-packages/Crypto/Hash/HMAC.pyo | Bin 0 -> 6126 bytes .../Lib/site-packages/Crypto/Hash/MD2.py | 91 ++ .../Lib/site-packages/Crypto/Hash/MD2.pyo | Bin 0 -> 2152 bytes .../Lib/site-packages/Crypto/Hash/MD4.py | 91 ++ .../Lib/site-packages/Crypto/Hash/MD4.pyo | Bin 0 -> 2139 bytes .../Lib/site-packages/Crypto/Hash/MD5.py | 97 ++ .../Lib/site-packages/Crypto/Hash/MD5.pyo | Bin 0 -> 2184 bytes .../Lib/site-packages/Crypto/Hash/RIPEMD.py | 94 ++ .../Lib/site-packages/Crypto/Hash/RIPEMD.pyo | Bin 0 -> 2379 bytes .../Lib/site-packages/Crypto/Hash/SHA.py | 98 ++ .../Lib/site-packages/Crypto/Hash/SHA.pyo | Bin 0 -> 2169 bytes .../Lib/site-packages/Crypto/Hash/SHA224.py | 95 ++ .../Lib/site-packages/Crypto/Hash/SHA224.pyo | Bin 0 -> 2225 bytes .../Lib/site-packages/Crypto/Hash/SHA256.py | 95 ++ .../Lib/site-packages/Crypto/Hash/SHA256.pyo | Bin 0 -> 2225 bytes .../Lib/site-packages/Crypto/Hash/SHA384.py | 96 ++ .../Lib/site-packages/Crypto/Hash/SHA384.pyo | Bin 0 -> 2225 bytes .../Lib/site-packages/Crypto/Hash/SHA512.py | 95 ++ .../Lib/site-packages/Crypto/Hash/SHA512.pyo | Bin 0 -> 2225 bytes .../Lib/site-packages/Crypto/Hash/_MD2.pyd | Bin 0 -> 9728 bytes .../Lib/site-packages/Crypto/Hash/_MD4.pyd | Bin 0 -> 10752 bytes .../site-packages/Crypto/Hash/_RIPEMD160.pyd | Bin 0 -> 10752 bytes .../Lib/site-packages/Crypto/Hash/_SHA224.pyd | Bin 0 -> 10240 bytes .../Lib/site-packages/Crypto/Hash/_SHA256.pyd | Bin 0 -> 10240 bytes .../Lib/site-packages/Crypto/Hash/_SHA384.pyd | Bin 0 -> 13824 bytes .../Lib/site-packages/Crypto/Hash/_SHA512.pyd | Bin 0 -> 13824 bytes .../Lib/site-packages/Crypto/Hash/__init__.py | 56 + .../site-packages/Crypto/Hash/__init__.pyo | Bin 0 -> 1662 bytes .../Lib/site-packages/Crypto/Hash/hashalgo.py | 116 ++ .../site-packages/Crypto/Hash/hashalgo.pyo | Bin 0 -> 3925 bytes .../Crypto/Protocol/AllOrNothing.py | 319 ++++ .../Crypto/Protocol/AllOrNothing.pyo | Bin 0 -> 8026 bytes .../site-packages/Crypto/Protocol/Chaffing.py | 245 +++ .../Crypto/Protocol/Chaffing.pyo | Bin 0 -> 8525 bytes .../Lib/site-packages/Crypto/Protocol/KDF.py | 123 ++ .../Lib/site-packages/Crypto/Protocol/KDF.pyo | Bin 0 -> 4678 bytes .../site-packages/Crypto/Protocol/__init__.py | 41 + .../Crypto/Protocol/__init__.pyo | Bin 0 -> 790 bytes .../Lib/site-packages/Crypto/PublicKey/DSA.py | 379 +++++ .../site-packages/Crypto/PublicKey/DSA.pyo | Bin 0 -> 14604 bytes .../site-packages/Crypto/PublicKey/ElGamal.py | 373 +++++ .../Crypto/PublicKey/ElGamal.pyo | Bin 0 -> 13203 bytes .../Lib/site-packages/Crypto/PublicKey/RSA.py | 719 ++++++++ .../site-packages/Crypto/PublicKey/RSA.pyo | Bin 0 -> 26461 bytes .../site-packages/Crypto/PublicKey/_DSA.py | 115 ++ .../site-packages/Crypto/PublicKey/_DSA.pyo | Bin 0 -> 3264 bytes .../site-packages/Crypto/PublicKey/_RSA.py | 81 + .../site-packages/Crypto/PublicKey/_RSA.pyo | Bin 0 -> 1854 bytes .../Crypto/PublicKey/__init__.py | 41 + .../Crypto/PublicKey/__init__.pyo | Bin 0 -> 1093 bytes .../Crypto/PublicKey/_slowmath.py | 187 +++ .../Crypto/PublicKey/_slowmath.pyo | Bin 0 -> 5978 bytes .../site-packages/Crypto/PublicKey/pubkey.py | 240 +++ .../site-packages/Crypto/PublicKey/pubkey.pyo | Bin 0 -> 8938 bytes .../Random/Fortuna/FortunaAccumulator.py | 171 ++ .../Random/Fortuna/FortunaAccumulator.pyo | Bin 0 -> 5405 bytes .../Crypto/Random/Fortuna/FortunaGenerator.py | 132 ++ .../Random/Fortuna/FortunaGenerator.pyo | Bin 0 -> 3951 bytes .../Crypto/Random/Fortuna/SHAd256.py | 98 ++ .../Crypto/Random/Fortuna/SHAd256.pyo | Bin 0 -> 2861 bytes .../Crypto/Random/Fortuna/__init__.py | 0 .../Crypto/Random/Fortuna/__init__.pyo | Bin 0 -> 162 bytes .../Crypto/Random/OSRNG/__init__.py | 40 + .../Crypto/Random/OSRNG/__init__.pyo | Bin 0 -> 677 bytes .../Crypto/Random/OSRNG/fallback.py | 46 + .../Crypto/Random/OSRNG/fallback.pyo | Bin 0 -> 1193 bytes .../site-packages/Crypto/Random/OSRNG/nt.py | 74 + .../site-packages/Crypto/Random/OSRNG/nt.pyo | Bin 0 -> 2311 bytes .../Crypto/Random/OSRNG/posix.py | 86 + .../Crypto/Random/OSRNG/posix.pyo | Bin 0 -> 2059 bytes .../Crypto/Random/OSRNG/rng_base.py | 88 + .../Crypto/Random/OSRNG/rng_base.pyo | Bin 0 -> 3306 bytes .../Crypto/Random/OSRNG/winrandom.pyd | Bin 0 -> 9728 bytes .../Crypto/Random/_UserFriendlyRNG.py | 230 +++ .../Crypto/Random/_UserFriendlyRNG.pyo | Bin 0 -> 8746 bytes .../site-packages/Crypto/Random/__init__.py | 43 + .../site-packages/Crypto/Random/__init__.pyo | Bin 0 -> 1099 bytes .../Lib/site-packages/Crypto/Random/random.py | 142 ++ .../site-packages/Crypto/Random/random.pyo | Bin 0 -> 4585 bytes .../Crypto/SelfTest/Cipher/__init__.py | 48 + .../Crypto/SelfTest/Cipher/__init__.pyo | Bin 0 -> 1552 bytes .../Crypto/SelfTest/Cipher/common.py | 399 +++++ .../Crypto/SelfTest/Cipher/common.pyo | Bin 0 -> 15675 bytes .../Crypto/SelfTest/Cipher/test_AES.py | 1433 ++++++++++++++++ .../Crypto/SelfTest/Cipher/test_AES.pyo | Bin 0 -> 76637 bytes .../Crypto/SelfTest/Cipher/test_ARC2.py | 124 ++ .../Crypto/SelfTest/Cipher/test_ARC2.pyo | Bin 0 -> 4075 bytes .../Crypto/SelfTest/Cipher/test_ARC4.py | 81 + .../Crypto/SelfTest/Cipher/test_ARC4.pyo | Bin 0 -> 2647 bytes .../Crypto/SelfTest/Cipher/test_Blowfish.py | 113 ++ .../Crypto/SelfTest/Cipher/test_Blowfish.pyo | Bin 0 -> 5418 bytes .../Crypto/SelfTest/Cipher/test_CAST.py | 57 + .../Crypto/SelfTest/Cipher/test_CAST.pyo | Bin 0 -> 1345 bytes .../Crypto/SelfTest/Cipher/test_DES.py | 339 ++++ .../Crypto/SelfTest/Cipher/test_DES.pyo | Bin 0 -> 13336 bytes .../Crypto/SelfTest/Cipher/test_DES3.py | 333 ++++ .../Crypto/SelfTest/Cipher/test_DES3.pyo | Bin 0 -> 12931 bytes .../Crypto/SelfTest/Cipher/test_XOR.py | 72 + .../Crypto/SelfTest/Cipher/test_XOR.pyo | Bin 0 -> 2056 bytes .../Crypto/SelfTest/Cipher/test_pkcs1_15.py | 174 ++ .../Crypto/SelfTest/Cipher/test_pkcs1_15.pyo | Bin 0 -> 10821 bytes .../Crypto/SelfTest/Cipher/test_pkcs1_oaep.py | 372 +++++ .../SelfTest/Cipher/test_pkcs1_oaep.pyo | Bin 0 -> 15589 bytes .../Crypto/SelfTest/Hash/__init__.py | 52 + .../Crypto/SelfTest/Hash/__init__.pyo | Bin 0 -> 1728 bytes .../Crypto/SelfTest/Hash/common.py | 197 +++ .../Crypto/SelfTest/Hash/common.pyo | Bin 0 -> 6723 bytes .../Crypto/SelfTest/Hash/test_HMAC.py | 223 +++ .../Crypto/SelfTest/Hash/test_HMAC.pyo | Bin 0 -> 5465 bytes .../Crypto/SelfTest/Hash/test_MD2.py | 64 + .../Crypto/SelfTest/Hash/test_MD2.pyo | Bin 0 -> 1818 bytes .../Crypto/SelfTest/Hash/test_MD4.py | 64 + .../Crypto/SelfTest/Hash/test_MD4.pyo | Bin 0 -> 1818 bytes .../Crypto/SelfTest/Hash/test_MD5.py | 64 + .../Crypto/SelfTest/Hash/test_MD5.pyo | Bin 0 -> 1818 bytes .../Crypto/SelfTest/Hash/test_RIPEMD.py | 73 + .../Crypto/SelfTest/Hash/test_RIPEMD.pyo | Bin 0 -> 2021 bytes .../Crypto/SelfTest/Hash/test_SHA.py | 64 + .../Crypto/SelfTest/Hash/test_SHA.pyo | Bin 0 -> 1355 bytes .../Crypto/SelfTest/Hash/test_SHA224.py | 65 + .../Crypto/SelfTest/Hash/test_SHA224.pyo | Bin 0 -> 1864 bytes .../Crypto/SelfTest/Hash/test_SHA256.py | 96 ++ .../Crypto/SelfTest/Hash/test_SHA256.pyo | Bin 0 -> 3016 bytes .../Crypto/SelfTest/Hash/test_SHA384.py | 63 + .../Crypto/SelfTest/Hash/test_SHA384.pyo | Bin 0 -> 1914 bytes .../Crypto/SelfTest/Hash/test_SHA512.py | 60 + .../Crypto/SelfTest/Hash/test_SHA512.pyo | Bin 0 -> 2072 bytes .../Crypto/SelfTest/Protocol/__init__.py | 41 + .../Crypto/SelfTest/Protocol/__init__.pyo | Bin 0 -> 1068 bytes .../SelfTest/Protocol/test_AllOrNothing.py | 76 + .../SelfTest/Protocol/test_AllOrNothing.pyo | Bin 0 -> 2505 bytes .../Crypto/SelfTest/Protocol/test_KDF.py | 98 ++ .../Crypto/SelfTest/Protocol/test_KDF.pyo | Bin 0 -> 3649 bytes .../Crypto/SelfTest/Protocol/test_chaffing.py | 74 + .../SelfTest/Protocol/test_chaffing.pyo | Bin 0 -> 2585 bytes .../Crypto/SelfTest/Protocol/test_rfc1751.py | 62 + .../Crypto/SelfTest/Protocol/test_rfc1751.pyo | Bin 0 -> 2312 bytes .../Crypto/SelfTest/PublicKey/__init__.py | 44 + .../Crypto/SelfTest/PublicKey/__init__.pyo | Bin 0 -> 1157 bytes .../Crypto/SelfTest/PublicKey/test_DSA.py | 244 +++ .../Crypto/SelfTest/PublicKey/test_DSA.pyo | Bin 0 -> 11141 bytes .../Crypto/SelfTest/PublicKey/test_ElGamal.py | 210 +++ .../SelfTest/PublicKey/test_ElGamal.pyo | Bin 0 -> 9001 bytes .../Crypto/SelfTest/PublicKey/test_RSA.py | 415 +++++ .../Crypto/SelfTest/PublicKey/test_RSA.pyo | Bin 0 -> 17597 bytes .../SelfTest/PublicKey/test_importKey.py | 345 ++++ .../SelfTest/PublicKey/test_importKey.pyo | Bin 0 -> 19058 bytes .../SelfTest/Random/Fortuna/__init__.py | 44 + .../SelfTest/Random/Fortuna/__init__.pyo | Bin 0 -> 1145 bytes .../Random/Fortuna/test_FortunaAccumulator.py | 189 +++ .../Fortuna/test_FortunaAccumulator.pyo | Bin 0 -> 5723 bytes .../Random/Fortuna/test_FortunaGenerator.py | 83 + .../Random/Fortuna/test_FortunaGenerator.pyo | Bin 0 -> 2863 bytes .../SelfTest/Random/Fortuna/test_SHAd256.py | 55 + .../SelfTest/Random/Fortuna/test_SHAd256.pyo | Bin 0 -> 1482 bytes .../Crypto/SelfTest/Random/OSRNG/__init__.py | 49 + .../Crypto/SelfTest/Random/OSRNG/__init__.pyo | Bin 0 -> 1370 bytes .../SelfTest/Random/OSRNG/test_fallback.py | 48 + .../SelfTest/Random/OSRNG/test_fallback.pyo | Bin 0 -> 1542 bytes .../SelfTest/Random/OSRNG/test_generic.py | 48 + .../SelfTest/Random/OSRNG/test_generic.pyo | Bin 0 -> 1494 bytes .../Crypto/SelfTest/Random/OSRNG/test_nt.py | 48 + .../Crypto/SelfTest/Random/OSRNG/test_nt.pyo | Bin 0 -> 1488 bytes .../SelfTest/Random/OSRNG/test_posix.py | 48 + .../SelfTest/Random/OSRNG/test_posix.pyo | Bin 0 -> 1515 bytes .../SelfTest/Random/OSRNG/test_winrandom.py | 48 + .../SelfTest/Random/OSRNG/test_winrandom.pyo | Bin 0 -> 1518 bytes .../Crypto/SelfTest/Random/__init__.py | 43 + .../Crypto/SelfTest/Random/__init__.pyo | Bin 0 -> 1211 bytes .../SelfTest/Random/test__UserFriendlyRNG.py | 171 ++ .../SelfTest/Random/test__UserFriendlyRNG.pyo | Bin 0 -> 5064 bytes .../Crypto/SelfTest/Random/test_random.py | 171 ++ .../Crypto/SelfTest/Random/test_random.pyo | Bin 0 -> 4534 bytes .../SelfTest/Random/test_rpoolcompat.py | 55 + .../SelfTest/Random/test_rpoolcompat.pyo | Bin 0 -> 1772 bytes .../Crypto/SelfTest/Signature/__init__.py | 40 + .../Crypto/SelfTest/Signature/__init__.pyo | Bin 0 -> 960 bytes .../SelfTest/Signature/test_pkcs1_15.py | 219 +++ .../SelfTest/Signature/test_pkcs1_15.pyo | Bin 0 -> 7964 bytes .../SelfTest/Signature/test_pkcs1_pss.py | 446 +++++ .../SelfTest/Signature/test_pkcs1_pss.pyo | Bin 0 -> 17009 bytes .../Crypto/SelfTest/Util/__init__.py | 44 + .../Crypto/SelfTest/Util/__init__.pyo | Bin 0 -> 1109 bytes .../Crypto/SelfTest/Util/test_Counter.py | 165 ++ .../Crypto/SelfTest/Util/test_Counter.pyo | Bin 0 -> 7358 bytes .../Crypto/SelfTest/Util/test_asn1.py | 293 ++++ .../Crypto/SelfTest/Util/test_asn1.pyo | Bin 0 -> 11034 bytes .../Crypto/SelfTest/Util/test_number.py | 295 ++++ .../Crypto/SelfTest/Util/test_number.pyo | Bin 0 -> 10867 bytes .../Crypto/SelfTest/Util/test_winrandom.py | 48 + .../Crypto/SelfTest/Util/test_winrandom.pyo | Bin 0 -> 1464 bytes .../site-packages/Crypto/SelfTest/__init__.py | 92 ++ .../Crypto/SelfTest/__init__.pyo | Bin 0 -> 3030 bytes .../Crypto/SelfTest/st_common.py | 62 + .../Crypto/SelfTest/st_common.pyo | Bin 0 -> 1972 bytes .../Crypto/Signature/PKCS1_PSS.py | 355 ++++ .../Crypto/Signature/PKCS1_PSS.pyo | Bin 0 -> 11411 bytes .../Crypto/Signature/PKCS1_v1_5.py | 236 +++ .../Crypto/Signature/PKCS1_v1_5.pyo | Bin 0 -> 7129 bytes .../Crypto/Signature/__init__.py | 31 + .../Crypto/Signature/__init__.pyo | Bin 0 -> 412 bytes .../Lib/site-packages/Crypto/Util/Counter.py | 127 ++ .../Lib/site-packages/Crypto/Util/Counter.pyo | Bin 0 -> 4231 bytes .../Lib/site-packages/Crypto/Util/RFC1751.py | 364 +++++ .../Lib/site-packages/Crypto/Util/RFC1751.pyo | Bin 0 -> 29278 bytes .../Lib/site-packages/Crypto/Util/__init__.py | 37 + .../site-packages/Crypto/Util/__init__.pyo | Bin 0 -> 725 bytes .../site-packages/Crypto/Util/_counter.pyd | Bin 0 -> 10240 bytes .../site-packages/Crypto/Util/_number_new.py | 119 ++ .../site-packages/Crypto/Util/_number_new.pyo | Bin 0 -> 3460 bytes .../Lib/site-packages/Crypto/Util/asn1.py | 286 ++++ .../Lib/site-packages/Crypto/Util/asn1.pyo | Bin 0 -> 13950 bytes .../Lib/site-packages/Crypto/Util/number.py | 1456 +++++++++++++++++ .../Lib/site-packages/Crypto/Util/number.pyo | Bin 0 -> 113620 bytes .../site-packages/Crypto/Util/py21compat.py | 84 + .../site-packages/Crypto/Util/py21compat.pyo | Bin 0 -> 1447 bytes .../site-packages/Crypto/Util/py3compat.py | 107 ++ .../site-packages/Crypto/Util/py3compat.pyo | Bin 0 -> 4189 bytes .../Lib/site-packages/Crypto/Util/randpool.py | 82 + .../site-packages/Crypto/Util/randpool.pyo | Bin 0 -> 3332 bytes .../Lib/site-packages/Crypto/Util/strxor.pyd | Bin 0 -> 7680 bytes .../site-packages/Crypto/Util/winrandom.py | 28 + .../site-packages/Crypto/Util/winrandom.pyo | Bin 0 -> 247 bytes .../Lib/site-packages/Crypto/__init__.py | 51 + .../Lib/site-packages/Crypto/__init__.pyo | Bin 0 -> 1139 bytes .../Lib/site-packages/Crypto/pct_warnings.py | 60 + .../Lib/site-packages/Crypto/pct_warnings.pyo | Bin 0 -> 2251 bytes .../jsonrpclib-0.1.3-py2.7.egg-info/PKG-INFO | 10 + .../SOURCES.txt | 11 + .../dependency_links.txt | 1 + .../installed-files.txt | 17 + .../top_level.txt | 1 + .../jsonrpclib/SimpleJSONRPCServer.py | 229 +++ .../Lib/site-packages/jsonrpclib/__init__.py | 6 + .../Lib/site-packages/jsonrpclib/config.py | 38 + .../Lib/site-packages/jsonrpclib/history.py | 40 + .../Lib/site-packages/jsonrpclib/jsonclass.py | 145 ++ .../Lib/site-packages/jsonrpclib/jsonrpc.py | 556 +++++++ tools/generate_key.py | 38 + tools/key.txt | 0 273 files changed, 20613 insertions(+) create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/AES.py create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/AES.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/ARC2.py create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/ARC2.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/ARC4.py create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/ARC4.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/Blowfish.py create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/Blowfish.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/CAST.py create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/CAST.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/DES.py create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/DES.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/DES3.py create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/DES3.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/PKCS1_OAEP.py create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/PKCS1_OAEP.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/PKCS1_v1_5.py create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/PKCS1_v1_5.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/XOR.py create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/XOR.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/_AES.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/_ARC2.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/_ARC4.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/_Blowfish.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/_CAST.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/_DES.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/_DES3.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/_XOR.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/blockalgo.py create mode 100644 panda/python/Lib/site-packages/Crypto/Cipher/blockalgo.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/HMAC.py create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/HMAC.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/MD2.py create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/MD2.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/MD4.py create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/MD4.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/MD5.py create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/MD5.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/RIPEMD.py create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/RIPEMD.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/SHA.py create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/SHA.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/SHA224.py create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/SHA224.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/SHA256.py create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/SHA256.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/SHA384.py create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/SHA384.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/SHA512.py create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/SHA512.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/_MD2.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/_MD4.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/_RIPEMD160.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/_SHA224.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/_SHA256.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/_SHA384.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/_SHA512.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/hashalgo.py create mode 100644 panda/python/Lib/site-packages/Crypto/Hash/hashalgo.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Protocol/AllOrNothing.py create mode 100644 panda/python/Lib/site-packages/Crypto/Protocol/AllOrNothing.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Protocol/Chaffing.py create mode 100644 panda/python/Lib/site-packages/Crypto/Protocol/Chaffing.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Protocol/KDF.py create mode 100644 panda/python/Lib/site-packages/Crypto/Protocol/KDF.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Protocol/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/Protocol/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/DSA.py create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/DSA.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/ElGamal.py create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/ElGamal.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/RSA.py create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/RSA.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/_DSA.py create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/_DSA.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/_RSA.py create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/_RSA.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/_slowmath.py create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/_slowmath.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/pubkey.py create mode 100644 panda/python/Lib/site-packages/Crypto/PublicKey/pubkey.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Random/Fortuna/FortunaAccumulator.py create mode 100644 panda/python/Lib/site-packages/Crypto/Random/Fortuna/FortunaAccumulator.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Random/Fortuna/FortunaGenerator.py create mode 100644 panda/python/Lib/site-packages/Crypto/Random/Fortuna/FortunaGenerator.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Random/Fortuna/SHAd256.py create mode 100644 panda/python/Lib/site-packages/Crypto/Random/Fortuna/SHAd256.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Random/Fortuna/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/Random/Fortuna/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Random/OSRNG/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/Random/OSRNG/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Random/OSRNG/fallback.py create mode 100644 panda/python/Lib/site-packages/Crypto/Random/OSRNG/fallback.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Random/OSRNG/nt.py create mode 100644 panda/python/Lib/site-packages/Crypto/Random/OSRNG/nt.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Random/OSRNG/posix.py create mode 100644 panda/python/Lib/site-packages/Crypto/Random/OSRNG/posix.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Random/OSRNG/rng_base.py create mode 100644 panda/python/Lib/site-packages/Crypto/Random/OSRNG/rng_base.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Random/OSRNG/winrandom.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Random/_UserFriendlyRNG.py create mode 100644 panda/python/Lib/site-packages/Crypto/Random/_UserFriendlyRNG.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Random/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/Random/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Random/random.py create mode 100644 panda/python/Lib/site-packages/Crypto/Random/random.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/common.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/common.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_AES.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_AES.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_ARC2.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_ARC2.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_ARC4.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_ARC4.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_Blowfish.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_Blowfish.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_CAST.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_CAST.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_DES.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_DES.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_DES3.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_DES3.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_XOR.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_XOR.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_pkcs1_15.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_pkcs1_15.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_pkcs1_oaep.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/common.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/common.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_HMAC.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_HMAC.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD2.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD2.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD4.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD4.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD5.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD5.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_RIPEMD.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_RIPEMD.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA224.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA224.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA256.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA256.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA384.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA384.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA512.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA512.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_AllOrNothing.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_AllOrNothing.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_KDF.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_KDF.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_chaffing.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_chaffing.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_rfc1751.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_rfc1751.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_DSA.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_DSA.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_ElGamal.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_ElGamal.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_RSA.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_RSA.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_importKey.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_importKey.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/test_FortunaGenerator.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/test_FortunaGenerator.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/test_SHAd256.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/test_SHAd256.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_fallback.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_fallback.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_generic.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_generic.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_nt.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_nt.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_posix.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_posix.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_winrandom.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_winrandom.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/test__UserFriendlyRNG.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/test__UserFriendlyRNG.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/test_random.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/test_random.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/test_rpoolcompat.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Random/test_rpoolcompat.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Signature/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Signature/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Signature/test_pkcs1_15.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Signature/test_pkcs1_15.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Signature/test_pkcs1_pss.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Signature/test_pkcs1_pss.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Util/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Util/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_Counter.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_Counter.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_asn1.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_asn1.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_number.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_number.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_winrandom.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_winrandom.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/st_common.py create mode 100644 panda/python/Lib/site-packages/Crypto/SelfTest/st_common.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Signature/PKCS1_PSS.py create mode 100644 panda/python/Lib/site-packages/Crypto/Signature/PKCS1_PSS.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Signature/PKCS1_v1_5.py create mode 100644 panda/python/Lib/site-packages/Crypto/Signature/PKCS1_v1_5.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Signature/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/Signature/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Util/Counter.py create mode 100644 panda/python/Lib/site-packages/Crypto/Util/Counter.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Util/RFC1751.py create mode 100644 panda/python/Lib/site-packages/Crypto/Util/RFC1751.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Util/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/Util/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Util/_counter.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Util/_number_new.py create mode 100644 panda/python/Lib/site-packages/Crypto/Util/_number_new.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Util/asn1.py create mode 100644 panda/python/Lib/site-packages/Crypto/Util/asn1.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Util/number.py create mode 100644 panda/python/Lib/site-packages/Crypto/Util/number.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Util/py21compat.py create mode 100644 panda/python/Lib/site-packages/Crypto/Util/py21compat.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Util/py3compat.py create mode 100644 panda/python/Lib/site-packages/Crypto/Util/py3compat.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Util/randpool.py create mode 100644 panda/python/Lib/site-packages/Crypto/Util/randpool.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/Util/strxor.pyd create mode 100644 panda/python/Lib/site-packages/Crypto/Util/winrandom.py create mode 100644 panda/python/Lib/site-packages/Crypto/Util/winrandom.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/__init__.py create mode 100644 panda/python/Lib/site-packages/Crypto/__init__.pyo create mode 100644 panda/python/Lib/site-packages/Crypto/pct_warnings.py create mode 100644 panda/python/Lib/site-packages/Crypto/pct_warnings.pyo create mode 100644 panda/python/Lib/site-packages/jsonrpclib-0.1.3-py2.7.egg-info/PKG-INFO create mode 100644 panda/python/Lib/site-packages/jsonrpclib-0.1.3-py2.7.egg-info/SOURCES.txt create mode 100644 panda/python/Lib/site-packages/jsonrpclib-0.1.3-py2.7.egg-info/dependency_links.txt create mode 100644 panda/python/Lib/site-packages/jsonrpclib-0.1.3-py2.7.egg-info/installed-files.txt create mode 100644 panda/python/Lib/site-packages/jsonrpclib-0.1.3-py2.7.egg-info/top_level.txt create mode 100644 panda/python/Lib/site-packages/jsonrpclib/SimpleJSONRPCServer.py create mode 100644 panda/python/Lib/site-packages/jsonrpclib/__init__.py create mode 100644 panda/python/Lib/site-packages/jsonrpclib/config.py create mode 100644 panda/python/Lib/site-packages/jsonrpclib/history.py create mode 100644 panda/python/Lib/site-packages/jsonrpclib/jsonclass.py create mode 100644 panda/python/Lib/site-packages/jsonrpclib/jsonrpc.py create mode 100644 tools/generate_key.py create mode 100644 tools/key.txt diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/AES.py b/panda/python/Lib/site-packages/Crypto/Cipher/AES.py new file mode 100644 index 00000000..14f68d8c --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Cipher/AES.py @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- +# +# Cipher/AES.py : AES +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== +"""AES symmetric cipher + +AES `(Advanced Encryption Standard)`__ is a symmetric block cipher standardized +by NIST_ . It has a fixed data block size of 16 bytes. +Its keys can be 128, 192, or 256 bits long. + +AES is very fast and secure, and it is the de facto standard for symmetric +encryption. + +As an example, encryption can be done as follows: + + >>> from Crypto.Cipher import AES + >>> from Crypto import Random + >>> + >>> key = b'Sixteen byte key' + >>> iv = Random.new().read(AES.block_size) + >>> cipher = AES.new(key, AES.MODE_CFB, iv) + >>> msg = iv + cipher.encrypt(b'Attack at dawn') + +.. __: http://en.wikipedia.org/wiki/Advanced_Encryption_Standard +.. _NIST: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf + +:undocumented: __revision__, __package__ +""" + +__revision__ = "$Id$" + +from Crypto.Cipher import blockalgo +from Crypto.Cipher import _AES + +class AESCipher (blockalgo.BlockAlgo): + """AES cipher object""" + + def __init__(self, key, *args, **kwargs): + """Initialize an AES cipher object + + See also `new()` at the module level.""" + blockalgo.BlockAlgo.__init__(self, _AES, key, *args, **kwargs) + +def new(key, *args, **kwargs): + """Create a new AES cipher + + :Parameters: + key : byte string + The secret key to use in the symmetric cipher. + It must be 16 (*AES-128*), 24 (*AES-192*), or 32 (*AES-256*) bytes long. + :Keywords: + mode : a *MODE_** constant + The chaining mode to use for encryption or decryption. + Default is `MODE_ECB`. + IV : byte string + The initialization vector to use for encryption or decryption. + + It is ignored for `MODE_ECB` and `MODE_CTR`. + + For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption + and `block_size` +2 bytes for decryption (in the latter case, it is + actually the *encrypted* IV which was prefixed to the ciphertext). + It is mandatory. + + For all other modes, it must be `block_size` bytes longs. It is optional and + when not present it will be given a default value of all zeroes. + counter : callable + (*Only* `MODE_CTR`). A stateful function that returns the next + *counter block*, which is a byte string of `block_size` bytes. + For better performance, use `Crypto.Util.Counter`. + segment_size : integer + (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext + are segmented in. + It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8. + + :Return: an `AESCipher` object + """ + return AESCipher(key, *args, **kwargs) + +#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`. +MODE_ECB = 1 +#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`. +MODE_CBC = 2 +#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`. +MODE_CFB = 3 +#: This mode should not be used. +MODE_PGP = 4 +#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`. +MODE_OFB = 5 +#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`. +MODE_CTR = 6 +#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`. +MODE_OPENPGP = 7 +#: Size of a data block (in bytes) +block_size = 16 +#: Size of a key (in bytes) +key_size = ( 16, 24, 32 ) + diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/AES.pyo b/panda/python/Lib/site-packages/Crypto/Cipher/AES.pyo new file mode 100644 index 0000000000000000000000000000000000000000..60177c28ea2aaaa2dabe7d940ebb4ba608c76ece GIT binary patch literal 3543 zcmb_eTTdHD6dq$jzzGe#NNuG)jH*-^$1H)QNw6AJa7cyP0y1f&T1e~h&e$GU?^-)! z8%OC=`_QNS+5Uj`JF^#)G*VS5Mmx;xo;mZ)cdq5XRx8Py^H#vJUm5?u$7BA)AQ@|8 zEU|Wp$pt3MEL>p2GHaJviPnp5y~x^&Sl?i(%r0)Q9%Pr;AB_FZ*stv+CU4TBeUr&$ z)?Q|Eg|%0htgv>4$y=;_i^6LbM8O z`-f-T%!Wf{6CLnCj|M8KROoG|x-Tap3Y6rBQIO0=R>u)Pvm%lrksBS~=h|>_ZFe_} zgUd_@H<_S*rDUZ$#hAMx(YD&tj-tl^hx zW_TbX-c@{i=SiJ!@9xxjoba7*A*Ue`#!=r(F$2&PiepAvDdu<)~yFDUK`k;xLS-rctSI{PyUei&_^>7p?mV@B;N#&ngz#b2CiTpot!JqQ(`kB76N`Vs4L@(D12|a;8y4#D? zw7TIXO2{gX^Bl=Ok-Sler}oAc5+HdftGmU|C(jQ3=JSI(*OR&Y(DWgUL+)i}_A)xE z-SvHI1u0Te*+sXBdTlAIhSIi>9;_i{WtN+HYTEfb%U~trlupg(dNXiFe?i>E6rVa4c{b<_( z9`iW{g-AvGVnleCT;P^j>#Vv!0v}_*{yb#j?u80$K%eM{B|Im1498#@yC|`X1@;>A zGJ9QOuQ4yPH){yLl+y1bUaf)bP2}O)MxF0G%-6d+v_=kn zu#>$)cCKxtc|1$dgs$#jRy#3lnz?}Al$(~z`>$E`K00* zbjsP+vN2W?*Gub^S8RW#dSV>9)ZcMu95xR+`RAjTINW8?_mD*{?E=YV7!(#%jO70v zUZ4Prs6DzL#R-ZYA)kYB#VK7jU$lU&*!8@SJ2^c(KK78p-JN0v7 z3T;#m-`a9-C)-7M=G^gW<`ki@a4nQMgSzLc=Ui7{$07`8&UtFtVM^8r-gKaY0iU8G zjuMqtd031xN?LBLy0RO&1voVXpk_#c4}NFGhvF<^0cY_TDiY@b#=-dy8jR~TpgMM) ziwKG5Lg{pX`WeNRFd7sFy5Cge6!>{xPw-KIlGJr3A{@KUgiyRvNld*7xig2ij!{$+ zcu|0lq8qB>glg?13TL&<&}7*SkMC2TKTuWsKNVo{gaT2BNNd$rlHMRT* zXY5)%qZju=-$eC4^;~M4-ZF01LZvV{Clb5L*>j{47#xHLFe~MNPS&FQVs+>>(;F2b zVpN|Br)wN=O^xgJ(IV!0-?`=U1Kg4#HX0AR;035$k4DxXg$QCYzH|7wFBG~&LK(^( zhak~WPO|fn+}Z-}A6kuGjFdltk$e0;r5-Y-8L2?`w35z2a(fD6Q2Zr@F0A_`3$RAZ zQI6yj@eZsHTNvzZ4A;9KyNVZY^{1}DyDHvt zH>T5Dw9S?IJb%s?&4cE(#q)#t0@-T5IJy1>q2Q1>ZCPS-rFovt+)gwN&g>> from Crypto.Cipher import ARC2 + >>> from Crypto import Random + >>> + >>> key = b'Sixteen byte key' + >>> iv = Random.new().read(ARC2.block_size) + >>> cipher = ARC2.new(key, ARC2.MODE_CFB, iv) + >>> msg = iv + cipher.encrypt(b'Attack at dawn') + +.. _RC2: http://en.wikipedia.org/wiki/RC2 +.. _RFC2268: http://tools.ietf.org/html/rfc2268 + +:undocumented: __revision__, __package__ +""" + +__revision__ = "$Id$" + +from Crypto.Cipher import blockalgo +from Crypto.Cipher import _ARC2 + +class RC2Cipher (blockalgo.BlockAlgo): + """RC2 cipher object""" + + def __init__(self, key, *args, **kwargs): + """Initialize an ARC2 cipher object + + See also `new()` at the module level.""" + blockalgo.BlockAlgo.__init__(self, _ARC2, key, *args, **kwargs) + +def new(key, *args, **kwargs): + """Create a new RC2 cipher + + :Parameters: + key : byte string + The secret key to use in the symmetric cipher. + Its length can vary from 1 to 128 bytes. + :Keywords: + mode : a *MODE_** constant + The chaining mode to use for encryption or decryption. + Default is `MODE_ECB`. + IV : byte string + The initialization vector to use for encryption or decryption. + + It is ignored for `MODE_ECB` and `MODE_CTR`. + + For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption + and `block_size` +2 bytes for decryption (in the latter case, it is + actually the *encrypted* IV which was prefixed to the ciphertext). + It is mandatory. + + For all other modes, it must be `block_size` bytes longs. It is optional and + when not present it will be given a default value of all zeroes. + counter : callable + (*Only* `MODE_CTR`). A stateful function that returns the next + *counter block*, which is a byte string of `block_size` bytes. + For better performance, use `Crypto.Util.Counter`. + segment_size : integer + (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext + are segmented in. + It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8. + effective_keylen : integer + Maximum cryptographic strength of the key, in bits. + It can vary from 0 to 1024. The default value is 1024. + + :Return: an `RC2Cipher` object + """ + return RC2Cipher(key, *args, **kwargs) + +#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`. +MODE_ECB = 1 +#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`. +MODE_CBC = 2 +#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`. +MODE_CFB = 3 +#: This mode should not be used. +MODE_PGP = 4 +#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`. +MODE_OFB = 5 +#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`. +MODE_CTR = 6 +#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`. +MODE_OPENPGP = 7 +#: Size of a data block (in bytes) +block_size = 8 +#: Size of a key (in bytes) +key_size = xrange(1,16+1) + diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/ARC2.pyo b/panda/python/Lib/site-packages/Crypto/Cipher/ARC2.pyo new file mode 100644 index 0000000000000000000000000000000000000000..1111d059ab3b528af1368191bde910d67abe4b86 GIT binary patch literal 4241 zcmb_f&u`nv6&~4+6En$fvU?~B^e~4lENQ)T>=wI@(M{J@?84}7Y|z;)Dj1+fp2Cp|ncLVEtLa&QA_rw5uH^pCs_*sZQcQ-|P zpBCNwB7Gpb4@9~px?3U*L^lxWL(zRG(nq5ENTiQN_pwMn5#3Kj`l;xCD)bXNl71$B zUK8D?B7G_@o1c?uC-;PiI{VVi$7AiSNn~OsBW;5KZ)4ev%#C(_+sO{UmN(iuQ{-~L zC8cpvtsLxUMRHvom#KDUnCmp?&t-)Dr5tH;x%d3wn^3+U>BUy(mGwH6io{K9F|kJD z)x46i6Znzxa)!@VlX@+6J~X-3mJa1~75RKzOkFmYlfscKX#COXT>Dbv^RL6;w6M~T zV6)ZA75NSpTB>YVSmQ@ymOn7od6}pzgNXJKeug@2OTwplgnMfza3)VQA5Dt!MCEfl z!@6PyU(1cr<&k`;ypm^m61HS&QkfT!TI3K9JtGap7EWn6=#|Nw%(S}3ag+N(PNw|~ zQAmri0$4LRNd{+dEh((ki4TK-!K>5*lH5;u10QuGlH{EnOtVb7iB8PGB+66JATT=Z z?C*bl5JL*NHDb^Q<`#!iGP(?+GjFvl2J%4m=U%%|eh>DVH}CrhzTS z!GVPBd;2(m4WT^GwVWWVCYff+a#XeTa}q#m5e0^gLy(a9L1O0OZo&;I!)k5aAOo@lClaZtu0(V0Z7nTOoyX|evZkiPKK~= zi))SCFrJ~IO?{2CDp%S3ErctF$Q70(AtXTW=;U$-K{d&U>mhT694O=l&X7fX0^)Yc)eq+{PvXw$F)+Vbo*26!wnNXCRhI}W zNSgiaBkvU&4XQ3xvwXW11Ysy+NIsM!?-MYc{a*TevYE)Mm<8XtyFJ82BT8%aA2_&3|<67?=A6ZW_HF699J%hz7U*brD@Q z*J#62+;D!;MT`C$)J8&|$dXN5=eV52%?t6SA>OQscX(bG?;7GAp4Y|ub!8iANJarDQE|Adb zH!r{13!jJ2t|oI-YJT;->0deH^;cD_+*MgDS0(aSoRgDzL@GPD9DyM=N;^vPax{`S z_5t3}Y0t+qifs7~7iZUIV{madL$YOMOAX~AC@JL9&GYq9cUUlPA3*KmAWz7J+&{4 z6pHr0(uc4IQ*lY&kCE?<^XIh4`F_r`$W45#vPF`L7;i9)A zVe)ti7K545TlV5!Iml&J0HnLX)Y4eZ>X9$^t5bAfiJfd#LC=(@IhQDhk%ftA+)@?~ zbxcS~j&>CV;!-fL9G1lACRUf!1EA5ya!z=C>syNmNLfNNrqTw!^ZG-ri%`JumIXvu z&H%^e{0|twQcBSUXN1ZK=UOOeTF$%;HiAgPIZ#joEx>gM1_DX|NXpc?QQ4H~5?S$9 z+X9TK5|k8E3=WGdB37yTnXWZ7+vj;UZ?8nQ70M$pAJi+j8~9ret^)?ZObKN-wK>ry zjZ(f{rhj{(f+N>n78lmud5b37;7BH#c#L0GBAdlkF*(VHynlpfV3 z;`ES)BTsy|2@VU=Z2yy&r^mfk_?mo}j{Cp`RuN%jw9)S*bs zN)aQFi)br6W!`{Bk?;cqc_5!jct>2WqQg4n1X;vWIfntCQt2YP2MbVYwi%<}p@n_G zyC2l88BfQO+sc0^J6zkG_DMh zA47&1GQ^M}hQ`+`Lu97;8E(---25ZlR;iYMj2BfFmSdZ_1QUjc-6KsA9b-nZXynU9 z=eV=7I6Yo2&^DKg^VKitwrmMYt2!)`fMt_pI&y1OKGZA(nZlK@#Fw8w3djW4?@IRZ b;yIq(uW;L3+gy9nc(V4(t*s_Kum1ZdY|FLK literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/ARC4.py b/panda/python/Lib/site-packages/Crypto/Cipher/ARC4.py new file mode 100644 index 00000000..b745e7ce --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Cipher/ARC4.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +# +# Cipher/ARC4.py : ARC4 +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== +"""ARC4 symmetric cipher + +ARC4_ (Alleged RC4) is an implementation of RC4 (Rivest's Cipher version 4), +a symmetric stream cipher designed by Ron Rivest in 1987. + +The cipher started as a proprietary design, that was reverse engineered and +anonymously posted on Usenet in 1994. The company that owns RC4 (RSA Data +Inc.) never confirmed the correctness of the leaked algorithm. + +Unlike RC2, the company has never published the full specification of RC4, +of whom it still holds the trademark. + +ARC4 keys can vary in length from 40 to 2048 bits. + +One problem of ARC4 is that it does not take a nonce or an IV. If it is required +to encrypt multiple messages with the same long-term key, a distinct +independent nonce must be created for each message, and a short-term key must +be derived from the combination of the long-term key and the nonce. +Due to the weak key scheduling algorithm of RC2, the combination must be carried +out with a complex function (e.g. a cryptographic hash) and not by simply +concatenating key and nonce. + +New designs should not use ARC4. A good alternative is AES +(`Crypto.Cipher.AES`) in any of the modes that turn it into a stream cipher (OFB, CFB, or CTR). + +As an example, encryption can be done as follows: + + >>> from Crypto.Cipher import ARC4 + >>> from Crypto.Hash import SHA + >>> from Crypto import Random + >>> + >>> key = b'Very long and confidential key' + >>> nonce = Random.new().read(16) + >>> tempkey = SHA.new(key+nonce).digest() + >>> cipher = ARC4.new(tempkey) + >>> msg = nonce + cipher.encrypt(b'Open the pod bay doors, HAL') + +.. _ARC4: http://en.wikipedia.org/wiki/RC4 + +:undocumented: __revision__, __package__ +""" + +__revision__ = "$Id$" + +from Crypto.Cipher import _ARC4 + +class ARC4Cipher: + """ARC4 cipher object""" + + + def __init__(self, key, *args, **kwargs): + """Initialize an ARC4 cipher object + + See also `new()` at the module level.""" + + self._cipher = _ARC4.new(key, *args, **kwargs) + self.block_size = self._cipher.block_size + self.key_size = self._cipher.key_size + + def encrypt(self, plaintext): + """Encrypt a piece of data. + + :Parameters: + plaintext : byte string + The piece of data to encrypt. It can be of any size. + :Return: the encrypted data (byte string, as long as the + plaintext). + """ + return self._cipher.encrypt(plaintext) + + def decrypt(self, ciphertext): + """Decrypt a piece of data. + + :Parameters: + ciphertext : byte string + The piece of data to decrypt. It can be of any size. + :Return: the decrypted data (byte string, as long as the + ciphertext). + """ + return self._cipher.decrypt(ciphertext) + +def new(key, *args, **kwargs): + """Create a new ARC4 cipher + + :Parameters: + key : byte string + The secret key to use in the symmetric cipher. + It can have any length, with a minimum of 40 bytes. + Its cryptograpic strength is always capped to 2048 bits (256 bytes). + + :Return: an `ARC4Cipher` object + """ + return ARC4Cipher(key, *args, **kwargs) + +#: Size of a data block (in bytes) +block_size = 1 +#: Size of a key (in bytes) +key_size = xrange(1,256+1) + diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/ARC4.pyo b/panda/python/Lib/site-packages/Crypto/Cipher/ARC4.pyo new file mode 100644 index 0000000000000000000000000000000000000000..63afe1b24514e42c205199c7b1b1522fada995fa GIT binary patch literal 4023 zcmb_f-*4MS5?)D(Q#0*dulI6~3$%bKRAGM9*ET}q*0p8~FbPZuf5t zxe#Xz%4W)K6HBy&V zp-N?Z>a{h}&gi2IWBo!ozvtu;YmhHg?dbdda1^AM3^-q_wCwE2Tsb{AFfd)o7}Bj4 zsg1n<@Y7GCAb7S=Ygy;h+Cwyj8?vfxRcnP;t4_&C`bFyH5}#{D)|FIdu8mSPEi!qK z8f#XiZCtUEm35>GCckycDBqfVxF1QjXv-=!t5&038rSXd^iUqBJ`GMx77e8#GcvPg zrt1>QJo#$tT4mlS=O{Gvs!-_#c~H!4t^K0JuD&&ezEDv5fV`$vt-S@DZ?#sU%(>6e4$oOX29?Tg$+S2 z5Fx*ivl`Nqg*18I$% z&I8*Zk0~4}XGWo3%2|WGQ$2+$nn(13!f5ApS}jnvNSwux{USh6OpeNQ6(Bj0FN!t; zPslL}Mdx?$L@m4GaTJ`Upif>lC>;Vjl816`Eu}7yARR9h;d%JgX%L(%5@| zPy!Qd7U_w4nc1SSOE(SziR<9tpat@Zdqi5mo_Fol_U{4UMzLLvyp4dRqF)G1UxmPrCu z*3=S`WQ19jW*4aYBncd~x(`nB5A+|n!X9S+CI+_T13Zz*HqSE5_#&wTltH(xw4NZd%yvB5^S7-@+#(4^KD_ zo`a!^8L!4Cev#I5=W#9&7fX5!@g#U~pX2FhJoyIspMG?F=YI4sx;Lp-eqqhzYdxJf z?bV$QRyS$uZ_>gx;e>=NIgun90ZEd_cy?q--26xHuRV@G#fxGC^naYZ8J{B0LIkv{5jQ74hAeA?p^QzmRt_ykrr5$#qo04SS>Dl8>Om zwdb5rF(J(`uZxz#6;l}fE{4tKt{1rYHgwZT)R8%{`zB!hjs?ex`;~lSu)19SKhVls zlW&Grx9APg+B*5a;p#NEATnIUY}=LBjMqC*KEd7L6|%*)`V49!Nthmzq-7LLnK=?L zc9O*886zH(nyqL2bR9epQxzYRd*sqiZ)dQ(yL&sMx0K%-1||jo1A_!w1_u3h3^0Q1 z5uf*vQ((T!wAwPjYpS0*>FaC$8OYTkVemtMgi!2s2*PoOSohDrj^omDJTKC4$~tyj+FGJNpQ zk6T@IOd@R?zCm|6-}cIL*)}$oVcz7hhZNzM;EpNyF|o!L;%h;dIAV^wO}^WjaMc3i z6E>uKcnryI{5K4qev4i{9(c;SE9WF@O4?f?D#-M{Sg{|ndIUqt`_ literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/Blowfish.py b/panda/python/Lib/site-packages/Crypto/Cipher/Blowfish.py new file mode 100644 index 00000000..3f12bea2 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Cipher/Blowfish.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +# +# Cipher/Blowfish.py : Blowfish +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== +"""Blowfish symmetric cipher + +Blowfish_ is a symmetric block cipher designed by Bruce Schneier. + +It has a fixed data block size of 8 bytes and its keys can vary in length +from 32 to 448 bits (4 to 56 bytes). + +Blowfish is deemed secure and it is fast. However, its keys should be chosen +to be big enough to withstand a brute force attack (e.g. at least 16 bytes). + +As an example, encryption can be done as follows: + + >>> from Crypto.Cipher import Blowfish + >>> from Crypto import Random + >>> from struct import pack + >>> + >>> bs = Blowfish.block_size + >>> key = b'An arbitrarily long key' + >>> iv = Random.new().read(bs) + >>> cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv) + >>> plaintext = b'docendo discimus ' + >>> plen = bs - divmod(len(plaintext),bs)[1] + >>> padding = [plen]*plen + >>> padding = pack('b'*plen, *padding) + >>> msg = iv + cipher.encrypt(plaintext + padding) + +.. _Blowfish: http://www.schneier.com/blowfish.html + +:undocumented: __revision__, __package__ +""" + +__revision__ = "$Id$" + +from Crypto.Cipher import blockalgo +from Crypto.Cipher import _Blowfish + +class BlowfishCipher (blockalgo.BlockAlgo): + """Blowfish cipher object""" + + def __init__(self, key, *args, **kwargs): + """Initialize a Blowfish cipher object + + See also `new()` at the module level.""" + blockalgo.BlockAlgo.__init__(self, _Blowfish, key, *args, **kwargs) + +def new(key, *args, **kwargs): + """Create a new Blowfish cipher + + :Parameters: + key : byte string + The secret key to use in the symmetric cipher. + Its length can vary from 4 to 56 bytes. + :Keywords: + mode : a *MODE_** constant + The chaining mode to use for encryption or decryption. + Default is `MODE_ECB`. + IV : byte string + The initialization vector to use for encryption or decryption. + + It is ignored for `MODE_ECB` and `MODE_CTR`. + + For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption + and `block_size` +2 bytes for decryption (in the latter case, it is + actually the *encrypted* IV which was prefixed to the ciphertext). + It is mandatory. + + For all other modes, it must be `block_size` bytes longs. It is optional and + when not present it will be given a default value of all zeroes. + counter : callable + (*Only* `MODE_CTR`). A stateful function that returns the next + *counter block*, which is a byte string of `block_size` bytes. + For better performance, use `Crypto.Util.Counter`. + segment_size : integer + (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext + are segmented in. + It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8. + + :Return: a `BlowfishCipher` object + """ + return BlowfishCipher(key, *args, **kwargs) + +#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`. +MODE_ECB = 1 +#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`. +MODE_CBC = 2 +#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`. +MODE_CFB = 3 +#: This mode should not be used. +MODE_PGP = 4 +#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`. +MODE_OFB = 5 +#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`. +MODE_CTR = 6 +#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`. +MODE_OPENPGP = 7 +#: Size of a data block (in bytes) +block_size = 8 +#: Size of a key (in bytes) +key_size = xrange(4,56+1) + diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/Blowfish.pyo b/panda/python/Lib/site-packages/Crypto/Cipher/Blowfish.pyo new file mode 100644 index 0000000000000000000000000000000000000000..f3e4a4a65236b783a1b305970d3c53d9afa3e592 GIT binary patch literal 3786 zcmb_eTaObr6n2tjVZ)tDtt$1ws;J0@Ww^G2sGza|+ErV26=3l-a z{%kR}8z#%CHUT%QC{i}nKKJ!JP-(keE{(W0T&xL9!o+`Bh;gZmp2bS?$%^l$nXmX0 zKZuo9sn>4rSsn=5Jk_rtB83$^-);13#gi$&jeS-@B$ixT!(XbE;l7CZLZmCMV;-t_ zW`p)LO(K5t2Db^nbqkwFwsVW7Uw@Myv5osm$b?ub72!^!{47<)`Sg7%jP>{r$xH|jf+P!}hT?vZ7!|j1HYO82<0?+FSwNR9wGE6Vuuvq;tm4xoh0elS0h@G`H}fz7 zYTUxFuR*&{I&$?&MDtMX;7C7R&8<#ir!6j$NsM!VFA3oj(`&ame)sO(<4*TJi6>s) zIfv_Lo}`wS`hG~XloOyU`N@lqwI7m&+Qc(Gb`w!Ksd*_oK_N+b`t^$ST5r|i@ae%^oZaMa)J z!)1$l=R6cTw(6C2SY+ZWXv?KGzK$}(YZS10OfrUF!SW(XWCve5)&A`r0D5-)d4*{% zq}0&mE`LUQpLc2ez$#gDV3* ztey9+UR^Gio+%T{Pok^vh)Y~Auu<4<_cG}1XOV(2WRH(Vsaj}*@EVPFFe8v+rbeT- zp~`e|PhQl2meW#Iujba155Q7Y+8J$==|-#ojd78@#vJJF1!u z6ft)y3M<=-wbde|k|L^rDGOA7g>xJwRQ2*iK{_-EAG@F&Q`*`6;1(|F$A#tAkvw!q}$6Sy>{@%++g~6 z>-P>1kfY+}gDcm)JKnX!`N{@KeE5@|92#xamBM-EFs}iJxd#qQTYB@=fUdoZ$B<3f zMvf(i7>fvgw{3hMjdJBMJ?^Fm8K9@lHKvaXjPUgExUk!7Y&Lze6&Z(ab-q4_7x)@p z&RzVDd`nVB9fNgHEKp_zhnL>>ZC)aK2O@=zR;4JKro}QfAH|}!S@H_9S+E- z-j?`xJfW0x)H5!61xGPQ4O5*))O=*iJlMJkqB8q%0ibcEM==F1rsuVG5M$GA=3~EwGF+&Sndhb0gAMHX*%GfxICa?=oxqg(qU-c6% z;OkhZ&Jt)wi|ddiI zb>ZFHMS}GP&g4{l#wB0m^fBgZ#OTWHfNFK8g<(KkH6V%@5Qo&<@Ui&Hu_Fq4AE)P( z^`)kYuL*)C2%6|Yqy95ZU^Icz1V-P+@L1o$*tvjVa1w((g<-wtv8VCjNXzUv+!6J_ zsYo{sXq#j5vS`*5bee0EN4xa|C90n6udg8f9TIn1QOz9j)-}wv0k2XK&y+g^Oy#1k nwy}HrXoe<}eVeoXy_>> from Crypto.Cipher import CAST + >>> from Crypto import Random + >>> + >>> key = b'Sixteen byte key' + >>> iv = Random.new().read(CAST.block_size) + >>> cipher = CAST.new(key, CAST.MODE_OPENPGP, iv) + >>> plaintext = b'sona si latine loqueris ' + >>> msg = cipher.encrypt(plaintext) + >>> + ... + >>> eiv = msg[:CAST.block_size+2] + >>> ciphertext = msg[CAST.block_size+2:] + >>> cipher = CAST.new(key, CAST.MODE_OPENPGP, eiv) + >>> print cipher.decrypt(ciphertext) + +.. _CAST-128: http://en.wikipedia.org/wiki/CAST-128 +.. _RFC2144: http://tools.ietf.org/html/rfc2144 + +:undocumented: __revision__, __package__ +""" + +__revision__ = "$Id$" + +from Crypto.Cipher import blockalgo +from Crypto.Cipher import _CAST + +class CAST128Cipher(blockalgo.BlockAlgo): + """CAST-128 cipher object""" + + def __init__(self, key, *args, **kwargs): + """Initialize a CAST-128 cipher object + + See also `new()` at the module level.""" + blockalgo.BlockAlgo.__init__(self, _CAST, key, *args, **kwargs) + +def new(key, *args, **kwargs): + """Create a new CAST-128 cipher + + :Parameters: + key : byte string + The secret key to use in the symmetric cipher. + Its length may vary from 5 to 16 bytes. + :Keywords: + mode : a *MODE_** constant + The chaining mode to use for encryption or decryption. + Default is `MODE_ECB`. + IV : byte string + The initialization vector to use for encryption or decryption. + + It is ignored for `MODE_ECB` and `MODE_CTR`. + + For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption + and `block_size` +2 bytes for decryption (in the latter case, it is + actually the *encrypted* IV which was prefixed to the ciphertext). + It is mandatory. + + For all other modes, it must be `block_size` bytes longs. It is optional and + when not present it will be given a default value of all zeroes. + counter : callable + (*Only* `MODE_CTR`). A stateful function that returns the next + *counter block*, which is a byte string of `block_size` bytes. + For better performance, use `Crypto.Util.Counter`. + segment_size : integer + (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext + are segmented in. + It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8. + + :Return: an `CAST128Cipher` object + """ + return CAST128Cipher(key, *args, **kwargs) + +#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`. +MODE_ECB = 1 +#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`. +MODE_CBC = 2 +#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`. +MODE_CFB = 3 +#: This mode should not be used. +MODE_PGP = 4 +#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`. +MODE_OFB = 5 +#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`. +MODE_CTR = 6 +#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`. +MODE_OPENPGP = 7 +#: Size of a data block (in bytes) +block_size = 8 +#: Size of a key (in bytes) +key_size = xrange(5,16+1) diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/CAST.pyo b/panda/python/Lib/site-packages/Crypto/Cipher/CAST.pyo new file mode 100644 index 0000000000000000000000000000000000000000..016cec64b5eea20c4d22e712ec9ed6ed4ee18e8a GIT binary patch literal 3823 zcmb_eZEqXL5nhtAY@O}IPJspi`e9I{Fh$EJ+jRnmsNGn!RS0b@fpQCkQE^<}Ey=Zx zcg*dcCD(uJ$_1Ny;vxl>5xLboU6?9s!suR(~Nla#V%<>azl0! zr{Q_IgUnKeda6}KI-%j=;PIm;PXgcbjx5b3@0;pNe2k=(RBSZ*dqwG#p3-D(mGSAw z8ah{N3S~kUGF!8zSS2$%_oi98peGN>ro?zB+8XF)SPUvsY60E&I8hX4>!nR+nOx3w zDC2ldMumB%_Gpq@!bZxCoGIRyq?T4XQf8Sc8TsCy)!Hy3lTW8Q)GD#1eKPYjk0Vx} zo5B*dT(H0-%dMhmnuUs_wK6<6Ubn(XGEIKVnh z+__;PN)xCu&>6?+%Je;t@O%FJIXN#3-1+>03l!?D(9elg--j}Z(nTdv{deAe zMw5G|`qCd0VGKBoyS03gKiK0Wcn8$&6|27< zzkC%OpS*f~@~4wM(ihFHWh`}K)uqM8$vu-MNHa~bv>L96)9-SXAzTfrg_%LJu;rH? z?AA(Zy$+S{`!zb{j)UFb_OG1a{^NhtQia|U4h#Q8wtrRl|2Z&>*T`s@;lR}iBIRfStNlvM?J4hGy~Un&mNE*7 zH$Y`VDVBujT#ac_L;EK(!}+YrP*pj!Zd9GS9C2;_p&&y>U= zze<=ziD89IVg+f@LaqxQb9MU*M_yl+WarHEK{%^4i)u7*xS~Fe&~vr2*P}2^jFpM~ z5v*{IatW-Qd5YCCGEmSanP63x72M_q-b*!=c?=#jG4q6EwO)o4ZznbE8)h zl8Sl^Z-q8wPAd>PT85$tg40-Vquf^!;QV3NEcklEzw7!#ZHv7CTa-dY<}$!IIRC>9 zuD@c{>5}6oWA<~cbTtS2b2|i#hT9sPZ>3=cew}GFI>^bWOq~lE=dN*M6yK{XMekNB z3ey}!k|B$@^OBQT)fT$F<0M}9HX^(0(+eaT?(8&=X__aYODsD_S;ei(v&1+zCFl!k zHNDD&i(GH7bT7_@wzA1w?&5x$4;4%zcH%_2crI0jfWzS-!pawETy|K0vpV(%#fj=G zV$_Vu(seyJCU-3}^vitn`FG`%hX>qm^{6G@9rsJtUltgIV|FEKUAY}{t?qU(44I>bObm z8Hi>enyKQozKgN@35MZK4E7d=%@(IsahwgZ6X~^3gdshXsSqu&a8;iq( zW`Q2JSsZVEK~-}|HrruGxJ@x~)PI@DWTu=Fv;{8X8vnZ42XQjH>kkFfKmQVQ^BWA? U?d|rR)}8ieJ3GJQ`R3n$0RSu-WB>pF literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/DES.py b/panda/python/Lib/site-packages/Crypto/Cipher/DES.py new file mode 100644 index 00000000..2fae42fd --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Cipher/DES.py @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- +# +# Cipher/DES.py : DES +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== +"""DES symmetric cipher + +DES `(Data Encryption Standard)`__ is a symmetric block cipher standardized +by NIST_ . It has a fixed data block size of 8 bytes. +Its keys are 64 bits long, even though 8 bits were used for integrity (now they +are ignored) and do not contribute to securty. + +DES is cryptographically secure, but its key length is too short by nowadays +standards and it could be brute forced with some effort. + +DES should not be used for new designs. Use `AES`. + +As an example, encryption can be done as follows: + + >>> from Crypto.Cipher import DES3 + >>> from Crypto import Random + >>> + >>> key = b'Sixteen byte key' + >>> iv = Random.new().read(DES3.block_size) + >>> cipher = DES3.new(key, DES3.MODE_OFB, iv) + >>> plaintext = b'sona si latine loqueris ' + >>> msg = iv + cipher.encrypt(plaintext) + +.. __: http://en.wikipedia.org/wiki/Data_Encryption_Standard +.. _NIST: http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf + +:undocumented: __revision__, __package__ +""" + +__revision__ = "$Id$" + +from Crypto.Cipher import blockalgo +from Crypto.Cipher import _DES + +class DESCipher(blockalgo.BlockAlgo): + """DES cipher object""" + + def __init__(self, key, *args, **kwargs): + """Initialize a DES cipher object + + See also `new()` at the module level.""" + blockalgo.BlockAlgo.__init__(self, _DES, key, *args, **kwargs) + +def new(key, *args, **kwargs): + """Create a new DES cipher + + :Parameters: + key : byte string + The secret key to use in the symmetric cipher. + It must be 8 byte long. The parity bits will be ignored. + :Keywords: + mode : a *MODE_** constant + The chaining mode to use for encryption or decryption. + Default is `MODE_ECB`. + IV : byte string + The initialization vector to use for encryption or decryption. + + It is ignored for `MODE_ECB` and `MODE_CTR`. + + For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption + and `block_size` +2 bytes for decryption (in the latter case, it is + actually the *encrypted* IV which was prefixed to the ciphertext). + It is mandatory. + + For all other modes, it must be `block_size` bytes longs. It is optional and + when not present it will be given a default value of all zeroes. + counter : callable + (*Only* `MODE_CTR`). A stateful function that returns the next + *counter block*, which is a byte string of `block_size` bytes. + For better performance, use `Crypto.Util.Counter`. + segment_size : integer + (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext + are segmented in. + It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8. + + :Return: an `DESCipher` object + """ + return DESCipher(key, *args, **kwargs) + +#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`. +MODE_ECB = 1 +#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`. +MODE_CBC = 2 +#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`. +MODE_CFB = 3 +#: This mode should not be used. +MODE_PGP = 4 +#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`. +MODE_OFB = 5 +#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`. +MODE_CTR = 6 +#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`. +MODE_OPENPGP = 7 +#: Size of a data block (in bytes) +block_size = 8 +#: Size of a key (in bytes) +key_size = 8 diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/DES.pyo b/panda/python/Lib/site-packages/Crypto/Cipher/DES.pyo new file mode 100644 index 0000000000000000000000000000000000000000..0180f2b81bf94a6a34a27791316bb9005a82ff0c GIT binary patch literal 3714 zcmb_fU2oe)79ClR6EjKcJ{1M_;bPH6WYwYDO;Mz3YplPrFm^XKWU7pH{E(uj5e{pBUD$sx+A8L-4eeD@v{*B9Bm1C zmlvbELf#XjdqQrD(YBC*7zIM!7o+<^J`ke^LOv9uheCcNMjr|Ju^4^q#vLJd#AWXj zw&*{w?d0^5%xbYvw$uqFx|pjn2>9)|cM{u}PP3$36;|gNUD`O4aVdAlQAFBMd~4?< z&6DeTKbcxk|D8EVQa+`pG+9|?!r;srx>hR) zmx{jmnkE`A(mb2(k-AYC*?C^g<}A-YEES|G1D(^nB%N6`E45uwFUyw@RjYv2=vkJR zO70TeAemE^TT1c_o=+;P$mV2JQk8ZU`Ut>9=X*XY<6^FpI89exMC}o_5FZUADOK6b z&N(DDhmv_-TKEC|%UH%M6RhI_Z*a2aQ>#?cMA4+=lVNlM+m{+jOukU0rg&v*GoX*9 z*;?#qyv)>+q%v^Ig!IxV8Xulsj{bqITnrrjV2LyDpS&8;m4 z`}-;jm-<>4O6oYw%h^7!_W1%u?FEX~7szeqOVR94Oqqn4Ha48)H~U33Nl|Wm>CFCA z7k>Eqo5xSwiYH+qr$I2N5cQ;5DEKD_FsM{F+F)B0?O|2K$#pzaQ52X>T=>t=b3BGHSRr0@#H$VQ2J^0X(-Chl?~1pKi5*~-Q}_~+XPLG- zP8ljR!PMk5c7-*j*fJQVXdToIBQRMx? z@~&H=GGI7wZq4~%HnAyB@wmd;>TGQ!93c(~ALx?1g9(z0wECRBQPaLs`Q zF)@y{$@Ew>xQI)5W>pDv;+&F0l7Yt$1H{f|O`2aIr2y_yStkS-2S$PfT&~~ewy@a- zGFnu|VX9{xM=v3qoxTI1exI3zao;uv zvf^Y8EQ0Y|gN||7ROYN(D2iD%elcV!^2QN8!+HLP^NZ8x7k|AN z@3G12_>WtlA3HBR)xQ^*MjMmpJ6pc^bG?h5X=6vdx(I;vC?!f_13m=(YSZdUY~^^J zfuUb#LCHRww*=?UX$ht*O66M?1dRnf2{EVat}{T~-5@jzzUYWAnuyx_^|y-x&Y~PD zN>>5Kne!WA0KI$FxogAXl;hkeUCu$P+#A3~10G=imUYR_G`C7ILgGv3CQd8YX0a7N zsWRtI%Ug+#1RPSLinz^*C#h;q==IODbk(mD$eG;@>5!W|tEN>-(<)0`e`x0bSX{%Z z%+LuTOc?^ysOhhdaLMlP)!{|R&;)W@;47EAz;}{cH-xuKX`);{3soZF2zY|D@7fGJdmxKc5WST-Hda9Ll1+va(Yz(+w^3??( zJ*_X;VCX^)@X2TlB=zJmCQrJ~C{vmI3 z#Jxtyc5!@kd~5OSs9gY$+6CIjc7bAdmiWffLzg4l7O>> from Crypto.Cipher import DES + >>> from Crypto import Random + >>> from Crypto.Util import Counter + >>> + >>> key = b'-8B key-' + >>> nonce = Random.new().read(DES.block_size/2) + >>> ctr = Counter.new(DES.block_size*8/2, prefix=nonce) + >>> cipher = DES.new(key, DES.MODE_CTR, counter=ctr) + >>> plaintext = b'We are no longer the knights who say ni!' + >>> msg = nonce + cipher.encrypt(plaintext) + +.. __: http://en.wikipedia.org/wiki/Triple_DES +.. _NIST: http://csrc.nist.gov/publications/nistpubs/800-67/SP800-67.pdf + +:undocumented: __revision__, __package__ +""" + +__revision__ = "$Id$" + +from Crypto.Cipher import blockalgo +from Crypto.Cipher import _DES3 + +class DES3Cipher(blockalgo.BlockAlgo): + """TDES cipher object""" + + def __init__(self, key, *args, **kwargs): + """Initialize a TDES cipher object + + See also `new()` at the module level.""" + blockalgo.BlockAlgo.__init__(self, _DES3, key, *args, **kwargs) + +def new(key, *args, **kwargs): + """Create a new TDES cipher + + :Parameters: + key : byte string + The secret key to use in the symmetric cipher. + It must be 16 or 24 bytes long. The parity bits will be ignored. + :Keywords: + mode : a *MODE_** constant + The chaining mode to use for encryption or decryption. + Default is `MODE_ECB`. + IV : byte string + The initialization vector to use for encryption or decryption. + + It is ignored for `MODE_ECB` and `MODE_CTR`. + + For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption + and `block_size` +2 bytes for decryption (in the latter case, it is + actually the *encrypted* IV which was prefixed to the ciphertext). + It is mandatory. + + For all other modes, it must be `block_size` bytes longs. It is optional and + when not present it will be given a default value of all zeroes. + counter : callable + (*Only* `MODE_CTR`). A stateful function that returns the next + *counter block*, which is a byte string of `block_size` bytes. + For better performance, use `Crypto.Util.Counter`. + segment_size : integer + (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext + are segmented in. + It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8. + + :Attention: it is important that all 8 byte subkeys are different, + otherwise TDES would degrade to single `DES`. + :Return: an `DES3Cipher` object + """ + return DES3Cipher(key, *args, **kwargs) + +#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`. +MODE_ECB = 1 +#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`. +MODE_CBC = 2 +#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`. +MODE_CFB = 3 +#: This mode should not be used. +MODE_PGP = 4 +#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`. +MODE_OFB = 5 +#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`. +MODE_CTR = 6 +#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`. +MODE_OPENPGP = 7 +#: Size of a data block (in bytes) +block_size = 8 +#: Size of a key (in bytes) +key_size = ( 16, 24 ) diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/DES3.pyo b/panda/python/Lib/site-packages/Crypto/Cipher/DES3.pyo new file mode 100644 index 0000000000000000000000000000000000000000..b86c36ff96e8d5abfb664ca52b6e477a94c43b67 GIT binary patch literal 4457 zcmb_fU2ogS6&+cQ6En$fcDF!Vpbt|ZKxC~<#deW;h1#v{I9(&HZOHBx6%0@mIg%!( zNP#o7qD9`?hd$-Uwm+af_YNg0L5f9z*dR4S&fM?0=dk|o$6o&arW=X!ua4h8;4=Tj zEf%7OdrkCeB3=`5T_kH_QWw3tsL_0#=j)=kj`=;I>f+5kF~r&p@ed*XF2vt@8zR0> zliqz1KM=hKBHk3eO%Z#d=ZW~C=sgtiBhh;#;>V)*Sj1n5-WMYNQuMwQ@i(IPM8sc< ztH#gBqQ-_0*SVf1O1?b3l4d@cD4Xj@MtV9{x##t(xBVcHjVzbfw9@?^(eEDSTT&Yt zuIwKqS#(=Uk;aB;9Okk9QN?mFm*;0!*MaYySvd}A+fcv7i#W8Qbo&fe%4{h2vDzx* z%QI`_t(s$TuH??{zHBrvrdDUE+-Yu+5j)@QdIODB%NM(Nk!0z}_rA|&>Q3b?xg)c} zmU3w=Y%UBm4LRz_Kha108oq|H2|q9WIJ?#t`3l4>|qk=1vK zER%^!M|Mmib7iLPMKYH=JG*S&3%CN6zUOiHAlGOE6X2wUEXC7Hd`LKIn-&G zz|3lEID+hjfW4+K*;iK%3zd~PEG6@Eimy>}5~iuj$w@p!O2}u94p+wj0ftBHa;}to z@f&`x(^yRvZmE@~7*Lu!rSZ+zFqHGrd<|Plxk&$tTr*9e1o6mtQ@NV<%}~J#1%^Nz zxb3JoSc1T2IZD#P_RvZMV4;`GE7nMC4r^L6gLC;z!!yp>EGrU}h8pEz>l>Zp+;e?@@NfYOXR3$jMVf1B#j7)N6c0>$|M~On7r$*^UAlokjfbAs!KuumVuFHKaR)}=Fl&R2 zLD0f%8b-I_NCkms)`1vL&*G>0Klp3ZFteMuakj!_l(|Ru@Q6&@vmQn?a3vRE#(%W& z7?=4uZVE64aKjzgS7TJGi|$opjTU^3n`@UYec9j*8f!%F$QEFixWHv3ZdQmlHSuOm zyu-LI-qplAjO*e(;c5+d#}a?Q%Cl5k9VP@Zp*z>EyGbXW>y1v%a&U!S6(%N=eXi5K zMAM+ePqMhc=}&N|6aTzHCUtSSs2mdj9w93B0UiZ`hSnhHlJmUM(sHAcA&eCQ<;V}h zd}J*7bvvVB10%sV^Lva=IyaYuqb{9{^i8-5--9f4L2?GARJUXu>-$2<~@*Y(!if0bvB4 zhQu701OQzDIasVm==Cagf;z9&e3s?$(oAGQ$qxK#a*t{@i6sz~vP;EeZ!`vA!wD)! z0wp$?7|jYoU{+!_&UIz?OEnCOgkh-9I!;fH0W};XdG-U8lNX-~5>+#wAxBv5a4ezY z|5Cnmq6B3Z3+7^#F^uMJiXKfc=!}!{74*3m7ni5!mw&wMx5(s09{LrA^jC7h;;XG+0K;a-!OAR3D zX)dn}KLQ6qv)W-4%#IQgigK~$z6 zdHL!XUebw8i^%}B1FQIpg|fe70$lJ_Ei7Fn+EJ=Q&FGawj2c;FJH#ll{51#R`}k}c z%IDON=u?J1O7u{xm>=IUW3Ct>x`W&Fi@C;-*hh&GF zPc=c0CiR-sYr-i_v`3R6nheooh$h_9zrgLB*+(^Re1(VIhq&2CxUF(7`xp;C;OfjN zm^gIVTT>> from Crypto.Cipher import PKCS1_OAEP + >>> from Crypto.PublicKey import RSA + >>> + >>> message = 'To be encrypted' + >>> key = RSA.importKey(open('pubkey.der').read()) + >>> cipher = PKCS1_OAEP.new(key) + >>> ciphertext = cipher.encrypt(message) + +At the receiver side, decryption can be done using the private part of +the RSA key: + + >>> key = RSA.importKey(open('privkey.der').read()) + >>> cipher = PKCS1_OAP.new(key) + >>> message = cipher.decrypt(ciphertext) + +:undocumented: __revision__, __package__ + +.. __: http://www.ietf.org/rfc/rfc3447.txt +.. __: http://www.rsa.com/rsalabs/node.asp?id=2125. +""" + +from __future__ import nested_scopes + +__revision__ = "$Id$" +__all__ = [ 'new', 'PKCS1OAEP_Cipher' ] + +import Crypto.Signature.PKCS1_PSS +import Crypto.Hash.SHA + +from Crypto.Util.py3compat import * +import Crypto.Util.number +from Crypto.Util.number import ceil_div +from Crypto.Util.strxor import strxor + +class PKCS1OAEP_Cipher: + """This cipher can perform PKCS#1 v1.5 OAEP encryption or decryption.""" + + def __init__(self, key, hashAlgo, mgfunc, label): + """Initialize this PKCS#1 OAEP cipher object. + + :Parameters: + key : an RSA key object + If a private half is given, both encryption and decryption are possible. + If a public half is given, only encryption is possible. + hashAlgo : hash object + The hash function to use. This can be a module under `Crypto.Hash` + or an existing hash object created from any of such modules. If not specified, + `Crypto.Hash.SHA` (that is, SHA-1) is used. + mgfunc : callable + A mask generation function that accepts two parameters: a string to + use as seed, and the lenth of the mask to generate, in bytes. + If not specified, the standard MGF1 is used (a safe choice). + label : string + A label to apply to this particular encryption. If not specified, + an empty string is used. Specifying a label does not improve + security. + + :attention: Modify the mask generation function only if you know what you are doing. + Sender and receiver must use the same one. + """ + self._key = key + + if hashAlgo: + self._hashObj = hashAlgo + else: + self._hashObj = Crypto.Hash.SHA + + if mgfunc: + self._mgf = mgfunc + else: + self._mgf = lambda x,y: Crypto.Signature.PKCS1_PSS.MGF1(x,y,self._hashObj) + + self._label = label + + def can_encrypt(self): + """Return True/1 if this cipher object can be used for encryption.""" + return self._key.can_encrypt() + + def can_decrypt(self): + """Return True/1 if this cipher object can be used for decryption.""" + return self._key.can_decrypt() + + def encrypt(self, message): + """Produce the PKCS#1 OAEP encryption of a message. + + This function is named ``RSAES-OAEP-ENCRYPT``, and is specified in + section 7.1.1 of RFC3447. + + :Parameters: + message : string + The message to encrypt, also known as plaintext. It can be of + variable length, but not longer than the RSA modulus (in bytes) + minus 2, minus twice the hash output size. + + :Return: A string, the ciphertext in which the message is encrypted. + It is as long as the RSA modulus (in bytes). + :Raise ValueError: + If the RSA key length is not sufficiently long to deal with the given + message. + """ + # TODO: Verify the key is RSA + + randFunc = self._key._randfunc + + # See 7.1.1 in RFC3447 + modBits = Crypto.Util.number.size(self._key.n) + k = ceil_div(modBits,8) # Convert from bits to bytes + hLen = self._hashObj.digest_size + mLen = len(message) + + # Step 1b + ps_len = k-mLen-2*hLen-2 + if ps_len<0: + raise ValueError("Plaintext is too long.") + # Step 2a + lHash = self._hashObj.new(self._label).digest() + # Step 2b + ps = bchr(0x00)*ps_len + # Step 2c + db = lHash + ps + bchr(0x01) + message + # Step 2d + ros = randFunc(hLen) + # Step 2e + dbMask = self._mgf(ros, k-hLen-1) + # Step 2f + maskedDB = strxor(db, dbMask) + # Step 2g + seedMask = self._mgf(maskedDB, hLen) + # Step 2h + maskedSeed = strxor(ros, seedMask) + # Step 2i + em = bchr(0x00) + maskedSeed + maskedDB + # Step 3a (OS2IP), step 3b (RSAEP), part of step 3c (I2OSP) + m = self._key.encrypt(em, 0)[0] + # Complete step 3c (I2OSP) + c = bchr(0x00)*(k-len(m)) + m + return c + + def decrypt(self, ct): + """Decrypt a PKCS#1 OAEP ciphertext. + + This function is named ``RSAES-OAEP-DECRYPT``, and is specified in + section 7.1.2 of RFC3447. + + :Parameters: + ct : string + The ciphertext that contains the message to recover. + + :Return: A string, the original message. + :Raise ValueError: + If the ciphertext length is incorrect, or if the decryption does not + succeed. + :Raise TypeError: + If the RSA key has no private half. + """ + # TODO: Verify the key is RSA + + # See 7.1.2 in RFC3447 + modBits = Crypto.Util.number.size(self._key.n) + k = ceil_div(modBits,8) # Convert from bits to bytes + hLen = self._hashObj.digest_size + + # Step 1b and 1c + if len(ct) != k or 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 from Crypto.Cipher import PKCS1_v1_5 + >>> from Crypto.PublicKey import RSA + >>> from Crypto.Hash import SHA + >>> + >>> message = 'To be encrypted' + >>> h = SHA.new(message) + >>> + >>> key = RSA.importKey(open('pubkey.der').read()) + >>> cipher = PKCS1_v1_5.new(key) + >>> ciphertext = cipher.encrypt(message+h.digest()) + +At the receiver side, decryption can be done using the private part of +the RSA key: + + >>> From Crypto.Hash import SHA + >>> from Crypto import Random + >>> + >>> key = RSA.importKey(open('privkey.der').read()) + >>> + >>> dsize = SHA.digest_size + >>> sentinel = Random.new().read(15+dsize) # Let's assume that average data length is 15 + >>> + >>> cipher = PKCS1_v1_5.new(key) + >>> message = cipher.decrypt(ciphertext, sentinel) + >>> + >>> digest = SHA.new(message[:-dsize]).digest() + >>> if digest==message[-dsize:]: # Note how we DO NOT look for the sentinel + >>> print "Encryption was correct." + >>> else: + >>> print "Encryption was not correct." + +:undocumented: __revision__, __package__ + +.. __: http://www.ietf.org/rfc/rfc3447.txt +.. __: http://www.rsa.com/rsalabs/node.asp?id=2125. +""" + +__revision__ = "$Id$" +__all__ = [ 'new', 'PKCS115_Cipher' ] + +from Crypto.Util.number import ceil_div +from Crypto.Util.py3compat import * +import Crypto.Util.number + +class PKCS115_Cipher: + """This cipher can perform PKCS#1 v1.5 RSA encryption or decryption.""" + + def __init__(self, key): + """Initialize this PKCS#1 v1.5 cipher object. + + :Parameters: + key : an RSA key object + If a private half is given, both encryption and decryption are possible. + If a public half is given, only encryption is possible. + """ + self._key = key + + def can_encrypt(self): + """Return True if this cipher object can be used for encryption.""" + return self._key.can_encrypt() + + def can_decrypt(self): + """Return True if this cipher object can be used for decryption.""" + return self._key.can_decrypt() + + def encrypt(self, message): + """Produce the PKCS#1 v1.5 encryption of a message. + + This function is named ``RSAES-PKCS1-V1_5-ENCRYPT``, and is specified in + section 7.2.1 of RFC3447. + For a complete example see `Crypto.Cipher.PKCS1_v1_5`. + + :Parameters: + message : byte string + The message to encrypt, also known as plaintext. It can be of + variable length, but not longer than the RSA modulus (in bytes) minus 11. + + :Return: A byte string, the ciphertext in which the message is encrypted. + It is as long as the RSA modulus (in bytes). + :Raise ValueError: + If the RSA key length is not sufficiently long to deal with the given + message. + + """ + # TODO: Verify the key is RSA + + randFunc = self._key._randfunc + + # See 7.2.1 in RFC3447 + modBits = Crypto.Util.number.size(self._key.n) + k = ceil_div(modBits,8) # Convert from bits to bytes + mLen = len(message) + + # Step 1 + if mLen > k-11: + raise ValueError("Plaintext is too long.") + # Step 2a + class nonZeroRandByte: + def __init__(self, rf): self.rf=rf + def __call__(self, c): + while bord(c)==0x00: c=self.rf(1)[0] + return c + ps = tobytes(map(nonZeroRandByte(randFunc), randFunc(k-mLen-3))) + # Step 2b + em = b('\x00\x02') + ps + bchr(0x00) + message + # Step 3a (OS2IP), step 3b (RSAEP), part of step 3c (I2OSP) + m = self._key.encrypt(em, 0)[0] + # Complete step 3c (I2OSP) + c = bchr(0x00)*(k-len(m)) + m + return c + + def decrypt(self, ct, sentinel): + """Decrypt a PKCS#1 v1.5 ciphertext. + + This function is named ``RSAES-PKCS1-V1_5-DECRYPT``, and is specified in + section 7.2.2 of RFC3447. + For a complete example see `Crypto.Cipher.PKCS1_v1_5`. + + :Parameters: + ct : byte string + The ciphertext that contains the message to recover. + sentinel : any type + The object to return to indicate that an error was detected during decryption. + + :Return: A byte string. It is either the original message or the ``sentinel`` (in case of an error). + :Raise ValueError: + If the ciphertext length is incorrect + :Raise TypeError: + If the RSA key has no private half. + + :attention: + You should **never** let the party who submitted the ciphertext know that + this function returned the ``sentinel`` value. + Armed with such knowledge (for a fair amount of carefully crafted but invalid ciphertexts), + an attacker is able to recontruct the plaintext of any other encryption that were carried out + with the same RSA public key (see `Bleichenbacher's`__ attack). + + In general, it should not be possible for the other party to distinguish + whether processing at the server side failed because the value returned + was a ``sentinel`` as opposed to a random, invalid message. + + In fact, the second option is not that unlikely: encryption done according to PKCS#1 v1.5 + embeds no good integrity check. There is roughly one chance + in 2^16 for a random ciphertext to be returned as a valid message + (although random looking). + + It is therefore advisabled to: + + 1. Select as ``sentinel`` a value that resembles a plausable random, invalid message. + 2. Not report back an error as soon as you detect a ``sentinel`` value. + Put differently, you should not explicitly check if the returned value is the ``sentinel`` or not. + 3. Cover all possible errors with a single, generic error indicator. + 4. Embed into the definition of ``message`` (at the protocol level) a digest (e.g. ``SHA-1``). + It is recommended for it to be the rightmost part ``message``. + 5. Where possible, monitor the number of errors due to ciphertexts originating from the same party, + and slow down the rate of the requests from such party (or even blacklist it altogether). + + **If you are designing a new protocol, consider using the more robust PKCS#1 OAEP.** + + .. __: http://www.bell-labs.com/user/bleichen/papers/pkcs.ps + + """ + + # TODO: Verify the key is RSA + + # See 7.2.1 in RFC3447 + modBits = Crypto.Util.number.size(self._key.n) + k = ceil_div(modBits,8) # Convert from bits to bytes + + # Step 1 + if len(ct) != k: + raise ValueError("Ciphertext with incorrect length.") + # Step 2a (O2SIP), 2b (RSADP), and part of 2c (I2OSP) + m = self._key.decrypt(ct) + # Complete step 2c (I2OSP) + em = bchr(0x00)*(k-len(m)) + m + # Step 3 + sep = em.find(bchr(0x00),2) + if not em.startswith(b('\x00\x02')) or sep<10: + return sentinel + # Step 4 + return em[sep+1:] + +def new(key): + """Return a cipher object `PKCS115_Cipher` that can be used to perform PKCS#1 v1.5 encryption or decryption. + + :Parameters: + key : RSA key object + The key to use to encrypt or decrypt the message. This is a `Crypto.PublicKey.RSA` object. + Decryption is only possible if *key* is a private RSA key. + + """ + return PKCS115_Cipher(key) + diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/PKCS1_v1_5.pyo b/panda/python/Lib/site-packages/Crypto/Cipher/PKCS1_v1_5.pyo new file mode 100644 index 0000000000000000000000000000000000000000..1d02904513e417e9e264725d6b3ddf1b395eb31b GIT binary patch literal 9203 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 H*Z%Zh-Q%H* literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/XOR.py b/panda/python/Lib/site-packages/Crypto/Cipher/XOR.py new file mode 100644 index 00000000..26ec1b10 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Cipher/XOR.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +# +# Cipher/XOR.py : XOR +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== +"""XOR toy cipher + +XOR is one the simplest stream ciphers. Encryption and decryption are +performed by XOR-ing data with a keystream made by contatenating +the key. + +Do not use it for real applications! + +:undocumented: __revision__, __package__ +""" + +__revision__ = "$Id$" + +from Crypto.Cipher import _XOR + +class XORCipher: + """XOR cipher object""" + + def __init__(self, key, *args, **kwargs): + """Initialize a XOR cipher object + + See also `new()` at the module level.""" + self._cipher = _XOR.new(key, *args, **kwargs) + self.block_size = self._cipher.block_size + self.key_size = self._cipher.key_size + + def encrypt(self, plaintext): + """Encrypt a piece of data. + + :Parameters: + plaintext : byte string + The piece of data to encrypt. It can be of any size. + :Return: the encrypted data (byte string, as long as the + plaintext). + """ + return self._cipher.encrypt(plaintext) + + def decrypt(self, ciphertext): + """Decrypt a piece of data. + + :Parameters: + ciphertext : byte string + The piece of data to decrypt. It can be of any size. + :Return: the decrypted data (byte string, as long as the + ciphertext). + """ + return self._cipher.decrypt(ciphertext) + +def new(key, *args, **kwargs): + """Create a new XOR cipher + + :Parameters: + key : byte string + The secret key to use in the symmetric cipher. + Its length may vary from 1 to 32 bytes. + + :Return: an `XORCipher` object + """ + return XORCipher(key, *args, **kwargs) + +#: Size of a data block (in bytes) +block_size = 1 +#: Size of a key (in bytes) +key_size = xrange(1,32+1) + diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/XOR.pyo b/panda/python/Lib/site-packages/Crypto/Cipher/XOR.pyo new file mode 100644 index 0000000000000000000000000000000000000000..d28746039bb4f0c111c69b17e55c825c73cd8cc3 GIT binary patch literal 2495 zcmb_eU2o$=6rDJ2+PG9K;)OSErA2b3ZL}Xx1hhh=AXP%!#RZ9tBDqt0noetvEzhLg ztoE%u^ON`w{1ae*0GvB^lOWiKqC}nRneoh>@j3V0+wQyF@XuGj9;c%HZQ%J8n*AOo z6JiY85#x@?0+Dq^9*CkV#$D0LHbfSRY*YL!#H|po#u)c_Fy0i|mKgVh+Tu>OBW?pR z-WFM3oJ1e6>)&C1I*!Seb4qn}q3ST?v9?qiMeah8)kT#n>&UuV$)a6m2lS0e>v`pL zX-JxkGPNAmDy&p}Ue<-m=xk1Kd7#adGU+7UXm>%9uGGBsSjbHAs**ta*|b*>lBMiWB0;vI5Sz9&I)Cm%7&CAwYt_8FO%dEMwLvj z7`O;=~TvWPkQYm?NW|mbreTfbqZ14XOPtIwuMXb6e7>Q8&^4DM{yPFUo9|E6UZi z$_Fo^O}LKHgzLg!soTOcX+Fw@=%3|fdX-ol?6xrkb$;MM@c3GlpZnc-Y!!RPDUJt<)qPUG|)&Ac53+`vGGag!;S}^0pm78vkzbxSi1>|^D>K8PJBetQeHxVctThU2P=2nU%K_t6f@DD<<@aC z%P@MCEIw|nyu~~4{}|0OIii0buHIq8VUvaK&s7`A|AVYH@!gNCcGEq{T3+(~Y_*9e=>$WcHWFm&B#HTAp75C6EHCDJYe)hy zOZYRs9p9+e=>`4m{!YrX9NdfC%koF=MFwbcFA{Gn|KIRtglYrrNo1M~jqzv~h}D*kr}iw(fZ0`^@ICi5P~MDTx`On5*BChIKH&D*hI&iH}e-_L^W` z_;d6gx)C26bDebjPswWKb{rT@ejhYn;){^Ke9XRMCeas>*R?cL6?36leuD3<;X8ae a`LYS(=bz#T%Qx)>z2HIc@m_zo7yJ!Ib7(jK literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/_AES.pyd b/panda/python/Lib/site-packages/Crypto/Cipher/_AES.pyd new file mode 100644 index 0000000000000000000000000000000000000000..f78a0357437b3e7d869e85fd05707baf413dcb74 GIT binary patch literal 29184 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 WL=IvXM=X!{FoNCwC;l&Jf&T}3Fz{Fa literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/_ARC2.pyd b/panda/python/Lib/site-packages/Crypto/Cipher/_ARC2.pyd new file mode 100644 index 0000000000000000000000000000000000000000..69e4eac2fea5e0d5800c0628e9b1d8fa3fd3d787 GIT binary patch literal 16384 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 F_+K$=p``!- literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/_CAST.pyd b/panda/python/Lib/site-packages/Crypto/Cipher/_CAST.pyd new file mode 100644 index 0000000000000000000000000000000000000000..c07fc3ab63e06fbff49f7e2e87bdb72da4c18307 GIT binary patch literal 26112 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 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/_DES.pyd b/panda/python/Lib/site-packages/Crypto/Cipher/_DES.pyd new file mode 100644 index 0000000000000000000000000000000000000000..47d1ac1d9024a378ef3127d6a306a12c4e929b74 GIT binary patch literal 54272 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∾I1+qD=AUe%zrlMld`cBO*)GoP*0b$F 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 bZ`S@;fI-Ga#sm<;T3Fe#S1X?$#d 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 ZzMX$se0Pd>$Gd;_=D+Yk0+av% literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/blockalgo.py b/panda/python/Lib/site-packages/Crypto/Cipher/blockalgo.py new file mode 100644 index 00000000..dd183dcb --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Cipher/blockalgo.py @@ -0,0 +1,296 @@ +# -*- coding: utf-8 -*- +# +# Cipher/blockalgo.py +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== +"""Module with definitions common to all block ciphers.""" + +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * +from Crypto.Util.py3compat import * + +#: *Electronic Code Book (ECB)*. +#: This is the simplest encryption mode. Each of the plaintext blocks +#: is directly encrypted into a ciphertext block, independently of +#: any other block. This mode exposes frequency of symbols +#: in your plaintext. Other modes (e.g. *CBC*) should be used instead. +#: +#: See `NIST SP800-38A`_ , Section 6.1 . +#: +#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf +MODE_ECB = 1 + +#: *Cipher-Block Chaining (CBC)*. Each of the ciphertext blocks depends +#: on the current and all previous plaintext blocks. An Initialization Vector +#: (*IV*) is required. +#: +#: The *IV* is a data block to be transmitted to the receiver. +#: The *IV* can be made public, but it must be authenticated by the receiver and +#: it should be picked randomly. +#: +#: See `NIST SP800-38A`_ , Section 6.2 . +#: +#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf +MODE_CBC = 2 + +#: *Cipher FeedBack (CFB)*. This mode is similar to CBC, but it transforms +#: the underlying block cipher into a stream cipher. Plaintext and ciphertext +#: are processed in *segments* of **s** bits. The mode is therefore sometimes +#: labelled **s**-bit CFB. An Initialization Vector (*IV*) is required. +#: +#: When encrypting, each ciphertext segment contributes to the encryption of +#: the next plaintext segment. +#: +#: This *IV* is a data block to be transmitted to the receiver. +#: The *IV* can be made public, but it should be picked randomly. +#: Reusing the same *IV* for encryptions done with the same key lead to +#: catastrophic cryptographic failures. +#: +#: See `NIST SP800-38A`_ , Section 6.3 . +#: +#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf +MODE_CFB = 3 + +#: This mode should not be used. +MODE_PGP = 4 + +#: *Output FeedBack (OFB)*. This mode is very similar to CBC, but it +#: transforms the underlying block cipher into a stream cipher. +#: The keystream is the iterated block encryption of an Initialization Vector (*IV*). +#: +#: The *IV* is a data block to be transmitted to the receiver. +#: The *IV* can be made public, but it should be picked randomly. +#: +#: Reusing the same *IV* for encryptions done with the same key lead to +#: catastrophic cryptograhic failures. +#: +#: See `NIST SP800-38A`_ , Section 6.4 . +#: +#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf +MODE_OFB = 5 + +#: *CounTeR (CTR)*. This mode is very similar to ECB, in that +#: encryption of one block is done independently of all other blocks. +#: Unlike ECB, the block *position* contributes to the encryption and no +#: information leaks about symbol frequency. +#: +#: Each message block is associated to a *counter* which must be unique +#: across all messages that get encrypted with the same key (not just within +#: the same message). The counter is as big as the block size. +#: +#: Counters can be generated in several ways. The most straightword one is +#: to choose an *initial counter block* (which can be made public, similarly +#: to the *IV* for the other modes) and increment its lowest **m** bits by +#: one (modulo *2^m*) for each block. In most cases, **m** is chosen to be half +#: the block size. +#: +#: Reusing the same *initial counter block* for encryptions done with the same +#: key lead to catastrophic cryptograhic failures. +#: +#: See `NIST SP800-38A`_ , Section 6.5 (for the mode) and Appendix B (for how +#: to manage the *initial counter block*). +#: +#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf +MODE_CTR = 6 + +#: OpenPGP. This mode is a variant of CFB, and it is only used in PGP and OpenPGP_ applications. +#: An Initialization Vector (*IV*) is required. +#: +#: Unlike CFB, the IV is not transmitted to the receiver. Instead, the *encrypted* IV is. +#: The IV is a random data block. Two of its bytes are duplicated to act as a checksum +#: for the correctness of the key. The encrypted IV is therefore 2 bytes longer than +#: the clean IV. +#: +#: .. _OpenPGP: http://tools.ietf.org/html/rfc4880 +MODE_OPENPGP = 7 + +def _getParameter(name, index, args, kwargs, default=None): + """Find a parameter in tuple and dictionary arguments a function receives""" + param = kwargs.get(name) + if len(args)>index: + if param: + raise ValueError("Parameter '%s' is specified twice" % name) + param = args[index] + return param or default + +class BlockAlgo: + """Class modelling an abstract block cipher.""" + + def __init__(self, factory, key, *args, **kwargs): + self.mode = _getParameter('mode', 0, args, kwargs, default=MODE_ECB) + self.block_size = factory.block_size + + if self.mode != MODE_OPENPGP: + self._cipher = factory.new(key, *args, **kwargs) + self.IV = self._cipher.IV + else: + # OPENPGP mode. For details, see 13.9 in RCC4880. + # + # A few members are specifically created for this mode: + # - _encrypted_iv, set in this constructor + # - _done_first_block, set to True after the first encryption + # - _done_last_block, set to True after a partial block is processed + + self._done_first_block = False + self._done_last_block = False + self.IV = _getParameter('iv', 1, args, kwargs) + if not self.IV: + raise ValueError("MODE_OPENPGP requires an IV") + + # Instantiate a temporary cipher to process the IV + IV_cipher = factory.new(key, MODE_CFB, + b('\x00')*self.block_size, # IV for CFB + segment_size=self.block_size*8) + + # The cipher will be used for... + if len(self.IV) == self.block_size: + # ... encryption + self._encrypted_IV = IV_cipher.encrypt( + self.IV + self.IV[-2:] + # Plaintext + b('\x00')*(self.block_size-2) # Padding + )[:self.block_size+2] + elif len(self.IV) == self.block_size+2: + # ... decryption + self._encrypted_IV = self.IV + self.IV = IV_cipher.decrypt(self.IV + # Ciphertext + b('\x00')*(self.block_size-2) # Padding + )[:self.block_size+2] + if self.IV[-2:] != self.IV[-4:-2]: + raise ValueError("Failed integrity check for OPENPGP IV") + self.IV = self.IV[:-2] + else: + raise ValueError("Length of IV must be %d or %d bytes for MODE_OPENPGP" + % (self.block_size, self.block_size+2)) + + # Instantiate the cipher for the real PGP data + self._cipher = factory.new(key, MODE_CFB, + self._encrypted_IV[-self.block_size:], + segment_size=self.block_size*8) + + def encrypt(self, plaintext): + """Encrypt data with the key and the parameters set at initialization. + + The cipher object is stateful; encryption of a long block + of data can be broken up in two or more calls to `encrypt()`. + That is, the statement: + + >>> c.encrypt(a) + c.encrypt(b) + + is always equivalent to: + + >>> c.encrypt(a+b) + + That also means that you cannot reuse an object for encrypting + or decrypting other data with the same key. + + This function does not perform any padding. + + - For `MODE_ECB`, `MODE_CBC`, and `MODE_OFB`, *plaintext* length + (in bytes) must be a multiple of *block_size*. + + - For `MODE_CFB`, *plaintext* length (in bytes) must be a multiple + of *segment_size*/8. + + - For `MODE_CTR`, *plaintext* can be of any length. + + - For `MODE_OPENPGP`, *plaintext* must be a multiple of *block_size*, + unless it is the last chunk of the message. + + :Parameters: + plaintext : byte string + The piece of data to encrypt. + :Return: + the encrypted data, as a byte string. It is as long as + *plaintext* with one exception: when encrypting the first message + chunk with `MODE_OPENPGP`, the encypted IV is prepended to the + returned ciphertext. + """ + + if self.mode == MODE_OPENPGP: + padding_length = (self.block_size - len(plaintext) % self.block_size) % self.block_size + if padding_length>0: + # CFB mode requires ciphertext to have length multiple of block size, + # but PGP mode allows the last block to be shorter + if self._done_last_block: + raise ValueError("Only the last chunk is allowed to have length not multiple of %d bytes", + self.block_size) + self._done_last_block = True + padded = plaintext + b('\x00')*padding_length + res = self._cipher.encrypt(padded)[:len(plaintext)] + else: + res = self._cipher.encrypt(plaintext) + if not self._done_first_block: + res = self._encrypted_IV + res + self._done_first_block = True + return res + + return self._cipher.encrypt(plaintext) + + def decrypt(self, ciphertext): + """Decrypt data with the key and the parameters set at initialization. + + The cipher object is stateful; decryption of a long block + of data can be broken up in two or more calls to `decrypt()`. + That is, the statement: + + >>> c.decrypt(a) + c.decrypt(b) + + is always equivalent to: + + >>> c.decrypt(a+b) + + That also means that you cannot reuse an object for encrypting + or decrypting other data with the same key. + + This function does not perform any padding. + + - For `MODE_ECB`, `MODE_CBC`, and `MODE_OFB`, *ciphertext* length + (in bytes) must be a multiple of *block_size*. + + - For `MODE_CFB`, *ciphertext* length (in bytes) must be a multiple + of *segment_size*/8. + + - For `MODE_CTR`, *ciphertext* can be of any length. + + - For `MODE_OPENPGP`, *plaintext* must be a multiple of *block_size*, + unless it is the last chunk of the message. + + :Parameters: + ciphertext : byte string + The piece of data to decrypt. + :Return: the decrypted data (byte string, as long as *ciphertext*). + """ + if self.mode == MODE_OPENPGP: + padding_length = (self.block_size - len(ciphertext) % self.block_size) % self.block_size + if padding_length>0: + # CFB mode requires ciphertext to have length multiple of block size, + # but PGP mode allows the last block to be shorter + if self._done_last_block: + raise ValueError("Only the last chunk is allowed to have length not multiple of %d bytes", + self.block_size) + self._done_last_block = True + padded = ciphertext + b('\x00')*padding_length + res = self._cipher.decrypt(padded)[:len(ciphertext)] + else: + res = self._cipher.decrypt(ciphertext) + return res + + return self._cipher.decrypt(ciphertext) + diff --git a/panda/python/Lib/site-packages/Crypto/Cipher/blockalgo.pyo b/panda/python/Lib/site-packages/Crypto/Cipher/blockalgo.pyo new file mode 100644 index 0000000000000000000000000000000000000000..d3d6a676773f3924cb1f2a8c88ce8d548eadb32e GIT binary patch literal 6239 zcmd^DUvC^q5%1Yuud{1Aj(z6r9Cw$_Az#)`vd0k~z=tgG#y&;5i_M&gU}b4Cp6Rt` zJv*~Z_uAQ$^MZrK(>?Nlc;$@`fW&!v}?kzi*{Z3Q=&aZ{QPP0 z0xV~QkN;WWUl%WgI1}P$?dvrBS>pyt`CSyB#{M8w@+2^a(pQ}z3QQ13T6%G>7e~^> z(hWnoAI9F1^n(7ON^~>$7ycdxSS^AQ6&8vH6^4q{fbOI&AQ1@y2-(yry`>T<{STYpZ+?5P zKQxDNwD(D{zo!GE?)P2q$URVcuayk@Cf;lD8Se3cy5T|G#DWkVthGBva}$Pj*nbsmk5*zlJ*1ayT7C=XY(_2yE5g}>1?=anVqpso zTSpiDsB;PLgQkzlBJs#@x)W?cyzmP)EvHJ8yH(MhYt1yd##RnEF zygQo>rL5rgw-zr@L=ae7Sj-uqxhOH)xgnx2UqPD2iTs~QW!biGkTZ4XGFJZ~ebyKV zkW86$)6}?4`i2&vl9_@^m>GsyHt1Qh($bx$hXu=lY@O1`;qw!N7Ks6*WED=`x~N0+ z<0O57P%sNadCcxbCdM(#zJ@+T69lDW4qf`2sDHZsaMRh|*?he7@eVxy=Yt?ohz5~- z^n|0D09V+YI-oG&=-_h|5S`$kh=pks{0C}!8GT!B5F#oBkx>UpV208=R0yA)IFTa; zkDhS!{X|6v2)uCzTx4&cVe(2Y`w}xz?hg$_pk+nj8uMUbQ(S>PW^!+~Hf$1)!wvg3 zOUNP@*K$~j)QKSSPNOQotchn@xN?b5V0 zjoO^`jx}q&f&RBJXU_6SAEaQ?R|}v1D+)4SYzQz1|N9F!5ujlFh+t`afbB2QEc`x4 zG~=L3nD}d+j7nSJ+z?>XNoS=j-~dL*2N0JmItD~VB3Kd&i_cTvx+c0cieBi>8OrAs z5zRBHbeP3JClRj;{U@$WQJ7ssZ^om}*bCI9S%r03i2o^ey_wp8^j+honT9!35~s>2 zO!XX~fvU<#*T8v@h`3?!xl0h;tjp{#uk2!3YQQqy?<$}LL9%g;>I}k&&NK)Z(|t-dE| zAIzTu#9GdUnu`u{Nzm&n_EbXX7&}GBxx>^* zXXr$mW8roWv4K37@?(TDV%b*-xb(nuh-3GCP|TH?GnDt`7MMQe*oENs^j=nPZM0CQ zZUnT?VuLvQIGU$;8LmkBslgWJGl#j{QwC!QD@tN!)2zJ z+lO4Ul^G;ak+@`8vY9|#S_=!IM4k>k7RI7cnj64S}7G)*gTBBVFa0U|>lmn8weMN_f8* z%di?IKGp_jGknk4j=~|+E}RmFk1#$-2_L%0IKwpEAU7=9|8kaU*w+C{4ay@pnXoz0 zpk#pI++Ly@0T`!KyU9S=Z&B9*6_i5Ri&VUgqCr?^zl(z5IyV4hwnAiH@1)Z3jfc9F z&tQ+N>k2@f<@+O;YZ6M_nYC_P)8!hjHnRZo1?yI69=|gH?@H-qu>KND2;OqA{yjJU zJHh(3Q2ZO*xgMrr{6h4;S|}bt$E8AXM)WeEctk3L;!(4RqhAY(M+DseODG-(s;kE0 zmpNS}7#F$yPowd8BVQMeGs7MO&h+pV_H`OW^_&d zYB00EMN`H=_70i__#y&hf$e3Q{5}xzJ1!n|L^!T!L4}jRX|lKr5EP(qDn7` zj>9*9$H5~9o^#RU3qG#vp5xf>flvz2yg8zK6_QVZ?l19alB;S}OSK2Jk5WeT3S-|z z!4R*9nqMZ4@tBPC3Rmq;Y~I9Z`bOFOi3viyOMd4=JVN(fW4`gy(1UcurZLROhSZ>TGqXI)&cazX2yv07C!( literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Hash/HMAC.py b/panda/python/Lib/site-packages/Crypto/Hash/HMAC.py new file mode 100644 index 00000000..6244db46 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Hash/HMAC.py @@ -0,0 +1,212 @@ +# HMAC.py - Implements the HMAC algorithm as described by RFC 2104. +# +# =================================================================== +# Portions Copyright (c) 2001, 2002, 2003 Python Software Foundation; +# All Rights Reserved +# +# This file contains code from the Python 2.2 hmac.py module (the +# "Original Code"), with modifications made after it was incorporated +# into PyCrypto (the "Modifications"). +# +# To the best of our knowledge, the Python Software Foundation is the +# copyright holder of the Original Code, and has licensed it under the +# Python 2.2 license. See the file LEGAL/copy/LICENSE.python-2.2 for +# details. +# +# The Modifications to this file are dedicated to the public domain. +# To the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. No rights are +# reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + + +"""HMAC (Hash-based Message Authentication Code) algorithm + +HMAC is a MAC defined in RFC2104_ and FIPS-198_ and constructed using +a cryptograpic hash algorithm. +It is usually named *HMAC-X*, where *X* is the hash algorithm; for +instance *HMAC-SHA1* or *HMAC-MD5*. + +The strength of an HMAC depends on: + + - the strength of the hash algorithm + - the length and entropy of the secret key + +An example of possible usage is the following: + + >>> from Crypto.Hash import HMAC + >>> + >>> secret = b'Swordfish' + >>> h = HMAC.new(secret) + >>> h.update(b'Hello') + >>> print h.hexdigest() + +.. _RFC2104: http://www.ietf.org/rfc/rfc2104.txt +.. _FIPS-198: http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf +""" + +# This is just a copy of the Python 2.2 HMAC module, modified to work when +# used on versions of Python before 2.2. + +__revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'HMAC' ] + +from Crypto.Util.strxor import strxor_c +from Crypto.Util.py3compat import * + +#: The size of the authentication tag produced by the MAC. +#: It matches the digest size on the underlying +#: hashing module used. +digest_size = None + +class HMAC: + """Class that implements HMAC""" + + #: The size of the authentication tag produced by the MAC. + #: It matches the digest size on the underlying + #: hashing module used. + digest_size = None + + def __init__(self, key, msg = None, digestmod = None): + """Create a new HMAC object. + + :Parameters: + key : byte string + secret key for the MAC object. + It must be long enough to match the expected security level of the + MAC. However, there is no benefit in using keys longer than the + `digest_size` of the underlying hash algorithm. + msg : byte string + The very first chunk of the message to authenticate. + It is equivalent to an early call to `update()`. Optional. + :Parameter digestmod: + The hash algorithm the HMAC is based on. + Default is `Crypto.Hash.MD5`. + :Type digestmod: + A hash module or object instantiated from `Crypto.Hash` + """ + if digestmod is None: + import MD5 + digestmod = MD5 + + self.digestmod = digestmod + self.outer = digestmod.new() + self.inner = digestmod.new() + try: + self.digest_size = digestmod.digest_size + except AttributeError: + self.digest_size = len(self.outer.digest()) + + try: + # The block size is 128 bytes for SHA384 and SHA512 and 64 bytes + # for the others hash function + blocksize = digestmod.block_size + except AttributeError: + blocksize = 64 + + ipad = 0x36 + opad = 0x5C + + if len(key) > blocksize: + key = digestmod.new(key).digest() + + key = key + bchr(0) * (blocksize - len(key)) + self.outer.update(strxor_c(key, opad)) + self.inner.update(strxor_c(key, ipad)) + if (msg): + self.update(msg) + + def update(self, msg): + """Continue authentication of a message by consuming the next chunk of data. + + Repeated calls are equivalent to a single call with the concatenation + of all the arguments. In other words: + + >>> m.update(a); m.update(b) + + is equivalent to: + + >>> m.update(a+b) + + :Parameters: + msg : byte string + The next chunk of the message being authenticated + """ + + self.inner.update(msg) + + def copy(self): + """Return a copy ("clone") of the MAC object. + + The copy will have the same internal state as the original MAC + object. + This can be used to efficiently compute the MAC of strings that + share a common initial substring. + + :Returns: An `HMAC` object + """ + other = HMAC(b("")) + other.digestmod = self.digestmod + other.inner = self.inner.copy() + other.outer = self.outer.copy() + return other + + def digest(self): + """Return the **binary** (non-printable) MAC of the message that has + been authenticated so far. + + This method does not change the state of the MAC object. + You can continue updating the object after calling this function. + + :Return: A byte string of `digest_size` bytes. It may contain non-ASCII + characters, including null bytes. + """ + h = self.outer.copy() + h.update(self.inner.digest()) + return h.digest() + + def hexdigest(self): + """Return the **printable** MAC of the message that has been + authenticated so far. + + This method does not change the state of the MAC object. + + :Return: A string of 2* `digest_size` bytes. It contains only + hexadecimal ASCII digits. + """ + return "".join(["%02x" % bord(x) + for x in tuple(self.digest())]) + +def new(key, msg = None, digestmod = None): + """Create a new HMAC object. + + :Parameters: + key : byte string + key for the MAC object. + It must be long enough to match the expected security level of the + MAC. However, there is no benefit in using keys longer than the + `digest_size` of the underlying hash algorithm. + msg : byte string + The very first chunk of the message to authenticate. + It is equivalent to an early call to `HMAC.update()`. + Optional. + :Parameter digestmod: + The hash to use to implement the HMAC. Default is `Crypto.Hash.MD5`. + :Type digestmod: + A hash module or instantiated object from `Crypto.Hash` + :Returns: An `HMAC` object + """ + return HMAC(key, msg, digestmod) + diff --git a/panda/python/Lib/site-packages/Crypto/Hash/HMAC.pyo b/panda/python/Lib/site-packages/Crypto/Hash/HMAC.pyo new file mode 100644 index 0000000000000000000000000000000000000000..80e50abcca3e355f508b4ae2f0317a8461fe14f3 GIT binary patch literal 6126 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 from Crypto.Hash import MD2 + >>> + >>> h = MD2.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +MD2 stand for Message Digest version 2, and it was invented by Rivest in 1989. + +This algorithm is both slow and insecure. Do not use it for new designs. + +.. _RFC1319: http://tools.ietf.org/html/rfc1319 +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'MD2Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +import Crypto.Hash._MD2 as _MD2 +hashFactory = _MD2 + +class MD2Hash(HashAlgo): + """Class that implements an MD2 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-md2 OBJECT IDENTIFIER ::= { + #: iso(1) member-body(2) us(840) rsadsi(113549) + #: digestAlgorithm(2) 2 + #: } + #: + #: This value uniquely identifies the MD2 algorithm. + oid = b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02') + + digest_size = 16 + block_size = 16 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return MD2Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `MD2Hash.update()`. + Optional. + + :Return: An `MD2Hash` object + """ + return MD2Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = MD2Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = MD2Hash.block_size + diff --git a/panda/python/Lib/site-packages/Crypto/Hash/MD2.pyo b/panda/python/Lib/site-packages/Crypto/Hash/MD2.pyo new file mode 100644 index 0000000000000000000000000000000000000000..5bcc1c6732e279eb89d335c119640344ac78dfd8 GIT binary patch literal 2152 zcmcIlO>f&q5FJr6Z7a4D1Wk+H_Fy1N(9p4ciG{>yYQwOB#tj(vP(c7qkt=a+ipz3W zc2(r&G{^p&{;?ibKR(RhV=E7aiq8s$D+tQNP!nMy-cWuk^kra~1WJUQCk-#v&#TwrfSS?P3=NF!_}#qQoKF~DJ} zM$%ZJhawhZX-qtla3}B_9v+HerN`pPT^*eAooZa_$_iXJx0(NnOuXUqppdtnXUo%I zQl_z$ox#&nndkcH@>N->!ip@&vgI5R0Z>5&9a z8*~RwwV1XbB}?CNw&}PA(&4b>^mPh9bbR)6262?fhM5rqym6V!F(3tS1((#(%~jNi z?xaX{GGPmucEupq$+b(!y)|uk^Vgn#KK=a9rst_g*d`n@FNWj@%X|Z2iLM&-5sF72 z5qA?kMBqIGaNc3iLbkVzLKLY&*(h=tGW$>B#Oi9=VXv0WjLe5l0o&pZ4#)}f8ro5} z{~nZz_m5xf1_!~*emS+7F8V*JLEk7VUzBlj4d$DE&GkNm-e)qG({P0yU>UxO8jD&`i0aii&tF0T-V{(HM=N^OnPi zB2*7LM>ufY)G7^m=d73IbZDOILOKXS7<>`^J%P&zy~Hvb5Pr*VZ+L#g_codd2gGXu zGZP6g-_2RG0NePm3#FY@g@`e-B+sdWhe#rMu<^KK$_PEUl8K#-x9I(o-NZTC zg)PuhGOqHeNa8%_gUi_nm=DTlmrDmfl@{|Z&gU`LS$4(SV)5DKEG>6wO*V$CE*As% zztE0HMoqg1orio0&o>> from Crypto.Hash import MD4 + >>> + >>> h = MD4.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +MD4 stand for Message Digest version 4, and it was invented by Rivest in 1990. + +This algorithm is insecure. Do not use it for new designs. + +.. _RFC1320: http://tools.ietf.org/html/rfc1320 +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'MD4Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +import Crypto.Hash._MD4 as _MD4 +hashFactory = _MD4 + +class MD4Hash(HashAlgo): + """Class that implements an MD4 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-md2 OBJECT IDENTIFIER ::= { + #: iso(1) member-body(2) us(840) rsadsi(113549) + #: digestAlgorithm(2) 4 + #: } + #: + #: This value uniquely identifies the MD4 algorithm. + oid = b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x04') + + digest_size = 16 + block_size = 64 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return MD4Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `MD4Hash.update()`. + Optional. + + :Return: A `MD4Hash` object + """ + return MD4Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = MD4Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = MD4Hash.block_size + diff --git a/panda/python/Lib/site-packages/Crypto/Hash/MD4.pyo b/panda/python/Lib/site-packages/Crypto/Hash/MD4.pyo new file mode 100644 index 0000000000000000000000000000000000000000..a02328c7e11090c33ef723fc989bec66ab14e770 GIT binary patch literal 2139 zcmcIlOK;mo5FSwv+luW3K_BRC4+f$H4Q}Ym(c6a8RZ${0(x4PAz!yu;l*TnBj4D$y>LNtJE z(4awyM@f^C7EPKofZnF0Ls^q9SzDv5MR}VBZEEm*ow5#HuhI274c19QZtzjrrZH~X zpbtcMM86EWY?^fG1D@C<*`@0(8f-abn+Dsw`?hzF-TA9Q^!ntvh^tv?^`wf*RK+5V zOe&&mqAO+7-0ybTL>Xa98LP39iBN?IPLKBwp6!JqDiTpvI+@1O2%Ac=|Li+4QdT5t zB8?S#EFzIhW1@+~T>{_H(UBNeIv2<8UH^<9RC%c@EAZCBX7MXh@jb8mg?!h0yju0A zWfEE08$CLcS*9PYw#rHsR-}F^f2+N~F&Blg?Cw}s;&ttjIH|q7m6cJt5YNAL0m1!u zkwKidvakqvG!uckxnW|X_8g>>zlCp(s@gu5)~uZ}G= z>UU|^Fb75qrTQ0N52+=~;z_NpL*?C9NbE(7iTgarA27@jgak9eBuI}WXxX4UP^iT$ z1qVUYL5KMX&M~#XG3aflZ&2{I$1a$2h~q3W%!LSW4_<%Q1%e8p0A?H|RYSkKV)i zChCU3bw=T$$H)b2ZyAa(RE4r(=zwI#pGL9O)vU+2S~fE>8#@Igi+WffC(H|I$Nk|O zFey4XdAjc(`g_B2W>Z}Ze^jHPQC2=Jqxc4dH^Z9ZLq>kc94==;n=imH{1i2ovGCNb zbJU21Luf4B=O6+$aUKQ?cEEvrPS0>1onp*AyXZMj_?0j$qFe$lUJ1h-^`7yR-3UXZ z5ITD}as<^X33%qLS2=ZPUg$zP2m%;<;{9g=ml4{-Fq;saR;Rn^bs8OSvl+8PJeDvs zn*j6Of;CI9O&fNBw9~2(5jvIR_Ed21h$Z(k?s7~Sp-0y;w)3vme-l-}$fA?<9edH~ zm^uQqo>?i3MOT_EcElwvLD!jyv8vEl;&fWvEH0n7OJTKp$6p>gM@1PSf1Rq^C_~M# z1?oyhRW=iGlx4hdHSYt9{`mN6b-_=iMVpJVh0k@Aeer5}>S`X9d$Z;mBUWdN@%vv` z$8Do#-M!v@euVp*tIe>Iw~Bl7l5GeR`j;@6|9|{!RffVkh;?2@)_$?t;j;5NRotiR z;^(Y?^1tJUK+6%6ZJoj^K?i28+ydtgX5=UxY(rbs+~;Af>qsx^qB`2a1BPShcpdM) S*KIuT9)iJNeY3f}(fkiiHu(7f literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Hash/MD5.py b/panda/python/Lib/site-packages/Crypto/Hash/MD5.py new file mode 100644 index 00000000..18e9e7bf --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Hash/MD5.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""MD5 cryptographic hash algorithm. + +MD5 is specified in RFC1321_ and produces the 128 bit digest of a message. + + >>> from Crypto.Hash import MD5 + >>> + >>> h = MD5.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +MD5 stand for Message Digest version 5, and it was invented by Rivest in 1991. + +This algorithm is insecure. Do not use it for new designs. + +.. _RFC1321: http://tools.ietf.org/html/rfc1321 +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'MD5Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +try: + # The md5 module is deprecated in Python 2.6, so use hashlib when possible. + import hashlib + hashFactory = hashlib.md5 + +except ImportError: + import md5 + hashFactory = md5 + +class MD5Hash(HashAlgo): + """Class that implements an MD5 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-md5 OBJECT IDENTIFIER ::= { + #: iso(1) member-body(2) us(840) rsadsi(113549) + #: digestAlgorithm(2) 5 + #: } + #: + #: This value uniquely identifies the MD5 algorithm. + oid = b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05') + + digest_size = 16 + block_size = 64 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return MD5Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `MD5Hash.update()`. + Optional. + + :Return: A `MD5Hash` object + """ + return MD5Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = MD5Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = MD5Hash.block_size + diff --git a/panda/python/Lib/site-packages/Crypto/Hash/MD5.pyo b/panda/python/Lib/site-packages/Crypto/Hash/MD5.pyo new file mode 100644 index 0000000000000000000000000000000000000000..d21e11139f9521f509f84e5a5d9dda3d2851999f GIT binary patch literal 2184 zcmcIlO>f&q5FJthKpKAjih!18%UghcF_U z?#ii(+#KZCpV3qQT@O9BZgW@KoH9BK$jnXbx7i%WSmAJuq&3ML`UxIngT`>UK_7^&iGCim*f4I<2Sm~)*`kXM4LVlY zq`@Yio_6nW)PFccuMT%bRL%>NPs*@JR3ws6Cn8KId8te?^;#`9QCjFiMry2NEL0}^ z7YDtaC%r&~SuBb&k7tq8!X#4ko_s4t%7|D^q&6ZSi%?9Z*5O3rE`eu%e_xEtd@2sC zU+;(=s%epzM!?t7X89`;@g47bnS9rMc(d!xia0c~J9=;=(=>l@b5xWnGa~U4`D+yg zKC@Y9!{LteQoO1n5{FfkSF+S9&&2LmHX(%nF4V~LN@fNLkLJQxSDX$~@9pjNkjYsB zOja;4Kq}KRnw8QMhq=gdBW79(T*dwnyNIP$lT71V&lAA{!M;e0Df-*nCeKstDQU)D zUQV_XGflV4al|N#mad~-TgUO1sX@VIh6`9F7ijgHG;4SVNQ|ZW2TvEZCBx!TrLIHe z)90w{$%?@)cE88c`w$Wg29+RPlAy0c*Wgf{*$l3N&|oNd4AL>TKr-kJt8b8h+T{@R zF~mU{Y9>PnyrxAer$7-{Wn4u|FIz+_`m-#~qZwPsxGzR&9$ngm?5S?yw&wbyk4GQ> z?zjzg53lMOM8t9PVq6Ze^yd(U=)$4*P+WSC;A`X{nNyqpNtcoH+1@Y|L7*~ag1`dF zlz$OMCNJk*zSXdqmg(3kU|HD323et>LObXW-+)Tt&f(*px95F5EaoQ3v*AlM8fsX70k>gz&9RXU;jTG8oEKQat;tZEy?99bj zl^85hGRrQPmoMg}FuC>Ptv)(NM`fR#l7f`(If18W&fryVJePPI$iA-V924rFb~6 z*oHKre+q-eAIMvyQZ&|1luwJ$m``p_xa~YH6%XpF`I)i2ld6iV(|Ff!E}b3Qf1w}B zGB0hf`8F1ulI63%3GJrgZiljV96hZ%YJUq3^cN6Kx9Q$>Th2YV=C+-V+i}`X%l+(r Idvl}qF98Gp>Hq)$ literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Hash/RIPEMD.py b/panda/python/Lib/site-packages/Crypto/Hash/RIPEMD.py new file mode 100644 index 00000000..33099cb8 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Hash/RIPEMD.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""RIPEMD-160 cryptographic hash algorithm. + +RIPEMD-160_ produces the 160 bit digest of a message. + + >>> from Crypto.Hash import RIPEMD + >>> + >>> h = RIPEMD.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +RIPEMD-160 stands for RACE Integrity Primitives Evaluation Message Digest +with a 160 bit digest. It was invented by Dobbertin, Bosselaers, and Preneel. + +This algorithm is considered secure, although it has not been scrutinized as +extensively as SHA-1. Moreover, it provides an informal security level of just +80bits. + +.. _RIPEMD-160: http://homes.esat.kuleuven.be/~bosselae/ripemd160.html +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'RIPEMD160Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +import Crypto.Hash._RIPEMD160 as _RIPEMD160 +hashFactory = _RIPEMD160 + +class RIPEMD160Hash(HashAlgo): + """Class that implements a RIPMD-160 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-ripemd160 OBJECT IDENTIFIER ::= { + #: iso(1) identified-organization(3) teletrust(36) + #: algorithm(3) hashAlgorithm(2) ripemd160(1) + #: } + #: + #: This value uniquely identifies the RIPMD-160 algorithm. + oid = b("\x06\x05\x2b\x24\x03\x02\x01") + + digest_size = 20 + block_size = 64 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return RIPEMD160Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `RIPEMD160Hash.update()`. + Optional. + + :Return: A `RIPEMD160Hash` object + """ + return RIPEMD160Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = RIPEMD160Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = RIPEMD160Hash.block_size + diff --git a/panda/python/Lib/site-packages/Crypto/Hash/RIPEMD.pyo b/panda/python/Lib/site-packages/Crypto/Hash/RIPEMD.pyo new file mode 100644 index 0000000000000000000000000000000000000000..7c0e10caf62c46ce29e847aa48e9a2fe49bb485d GIT binary patch literal 2379 zcmcIlO>f&q5M4=@Vl%dr7Hx{&_7K2I8`B946s^#@ahwD;khlhu9x4c+SL8@sn_uNF z<){dHNqX&{?GI?*EM+OlIVG^mS?=uYe7t$={Ilg%e~*GlES?VDk1)(%m|`J@m|J4l z5^-C^9TBgIX-5npcSYP2X-B+b>4r$xMAj9%Mrkv1X8XUE#gSWn4VSxlso85yIdgkuuV z!NGx?R7EC_+!g*Y+tyiGR8}@-uhp*KGLb(mw)~u~`uA2FeqF}OQh&U2Olex|thUNZ z=T;_uLa!TNaO^#|rLiiHjhqyf3=WT;%9GsE6yeR~S*0^=^$Za`ovE}|Ru{Q^(F7r% zxWK$CBm$v*7_Ki*th`c2>U>797t8TnJ}Jgys;tiM%g2Q=lq#yseTmy~6XirH67wq2 zW|d%xMO5TQ$5g?Hp{TA1M^c*<^%U7cV7MhOtQ-^N(nM8_3-ljQR>q^(mT-7R=^RV> z^7wG~p)X$)6%{k8?(=cfYzFJNGl#QCLZ;H@9?n2YILo!WsEzf$e}IA-IO+Q`ToryG z6Kl)C-d<9mz&;se{mVL~8ln4R+WT|7h<2~iC1o*E6=Dehse8!0Oo0gg?oTw@fgD#U?Maa8Uk}$5W1@+ z-l7xMxY^K3=(k~y+YGJ49fDSY+;#GX2wwJYu$@y(N2xLlaAg^)DP<@xlE(J#Gdou{2XDJuP|95E?VLZ zgtmAC_d6f}fu`j=oc1|`0qa{%Mi>GFHVj=t*`a4DvPCuTvsKG#fZxOk=o;0>2jM33 zGo+)z=nSY-`(Ob72misSoC9z9=(!$`jJC8}s^}7ZY(`DzjyU(DrcQo254y1N48!nk zqO}Z%mo6L+0>a@aTFVGHj(}C1lL2QY;8;GfbFe5*Fc!|8_MJ0)Q5fbbBP5N#gkc6U zOL@tjgdwU3nVlRvxE4ANc;&QLWpz0{Epl>M2%zv@0G}?!oTq&Zvx%v<*7G*oy;iTi z*@@UE9?N9k#sbNHdkvpu%FSoc3&_@0E)|%Vn0|An!-%-&nZ+49vKU`bWEZSGI8znU zWWiknhhZ=|V@Lwrb4#F8@a^<^N4|m)aLrs!bcNqQl+^jJ;6!9~D`ttY!9i z??>u$<@iV4kiwmhb{F&wR&{{o25w-#Olr`>5!a7_a}6uu03U2aS~cY-!?Yu=ADgZ_ c*ufo!L+Z7A?OScHb-VpJ@O|g&&FziOe^;+caR2}S literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Hash/SHA.py b/panda/python/Lib/site-packages/Crypto/Hash/SHA.py new file mode 100644 index 00000000..0bc59170 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Hash/SHA.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""SHA-1 cryptographic hash algorithm. + +SHA-1_ produces the 160 bit digest of a message. + + >>> from Crypto.Hash import SHA + >>> + >>> h = SHA.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +*SHA* stands for Secure Hash Algorithm. + +This algorithm is not considered secure. Do not use it for new designs. + +.. _SHA-1: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'SHA1Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +try: + # The sha module is deprecated in Python 2.6, so use hashlib when possible. + import hashlib + hashFactory = hashlib.sha1 + +except ImportError: + import sha + hashFactory = sha + +class SHA1Hash(HashAlgo): + """Class that implements a SHA-1 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-sha1 OBJECT IDENTIFIER ::= { + #: iso(1) identified-organization(3) oiw(14) secsig(3) + #: algorithms(2) 26 + #: } + #: + #: This value uniquely identifies the SHA-1 algorithm. + oid = b('\x06\x05\x2b\x0e\x03\x02\x1a') + + digest_size = 20 + block_size = 64 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return SHA1Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `SHA1Hash.update()`. + Optional. + + :Return: A `SHA1Hash` object + """ + return SHA1Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = SHA1Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = SHA1Hash.block_size + + diff --git a/panda/python/Lib/site-packages/Crypto/Hash/SHA.pyo b/panda/python/Lib/site-packages/Crypto/Hash/SHA.pyo new file mode 100644 index 0000000000000000000000000000000000000000..77b02a667f5e2dfab58472aeb81c1aaf8c904ead GIT binary patch literal 2169 zcmcIl+iu%N5FJt%+q7)wp%_U z?#iu-yg9G!m-O%Y0qvR9%^%|D>z*8bV@s=xX{O!KdS|4R)0H%LO%19hn9 zP~uWjqohuw8uh?8C}~nwqf6%2D67-BLA?e!)5msmow6qNnk1Way+*xt`YHc{>T-i_ zJgPJ~j>88bgHubhGvqQZd z-o0pVve$n)L>H&W`yCNi)6x{9Dk@VIi!{=yh_X>pDU*(U&$B|ID61lw#8L~BO3`_K zCwYeO zYd>AB`jaw=jBF2{oXRXKo~*XYO65kReky;Td4Xfz9#rfJZK6EUVpvq-LdKIy3TyrN zUQm~*(yJ&1CV62*T;y6MvXY6=_Mk6b6?SK$r9ix_5*~^~YBkC=V)cCy+6;9?YE0QZ zIEZx>`?=D_9~HL;~zGUU_pB)h9wXS4C;cFp}veFR>;1c}*e9-NjF4E-sHA-ZY%~}nMX_*Zz1B^v&ERZGo1-O%L|1Dq? zJ$tp^@xSp8`{mT6Mc#j{27RrJ+%Kc}26)%~8N&OV_dcTc%W1&9;S58wDRP#v@YKfQ zfk7-Bg0pm=3mLG8^)TSH1YFUF^bG3gHOAbt^S1Sbt%PA7jV02>D`7asbL2`u_pdR0)H&GRCcHU$Cp?s@+}$>j_^$Iva1X1(dP+@{lXTeX-S;;~Hg zBTSIyy9H{N$<}L-3#6G;xrorHBzLEr8%Hd;opF<6$cSQaEn_opYTdU{g&Y}K>8^z? z8XZGN0Mk<=(Rk35MvEPB2_?6(nu?*S&?Vz^lHV+p&%32Cg|*`^51rvYX(4}|sM{#R zg<**(7c#1{sfeR2ctuS zUvT#Zif6dnY;$D-ZgBQ?hLyZk8eT8)hCso841xIr^3JFXSL<0^jLXOv?i2T(7N3j7 zuh#7PGiG@uQ-j$>PoqxITv$7^&(QZ(g~y0n22R>*7wlkSb6}wzY-75*dk=$N+nHX> lF4xg68~+@n={DUR*K;1ZHMiw#xm!-l@!U@yx3)KG{{b=I`eXnA literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Hash/SHA224.py b/panda/python/Lib/site-packages/Crypto/Hash/SHA224.py new file mode 100644 index 00000000..959b56da --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Hash/SHA224.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""SHA-224 cryptographic hash algorithm. + +SHA-224 belongs to the SHA-2_ family of cryptographic hashes. +It produces the 224 bit digest of a message. + + >>> from Crypto.Hash import SHA224 + >>> + >>> h = SHA224.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +*SHA* stands for Secure Hash Algorithm. + +.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'SHA224Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +try: + import hashlib + hashFactory = hashlib.sha224 + +except ImportError: + from Crypto.Hash import _SHA224 + hashFactory = _SHA224 + +class SHA224Hash(HashAlgo): + """Class that implements a SHA-224 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-sha224 OBJECT IDENTIFIER ::= { + #: joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) + #: nistalgorithm(4) hashalgs(2) 4 + #: } + #: + #: This value uniquely identifies the SHA-224 algorithm. + oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04') + + digest_size = 28 + block_size = 64 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return SHA224Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `SHA224Hash.update()`. + Optional. + + :Return: A `SHA224Hash` object + """ + return SHA224Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = SHA224Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = SHA224Hash.block_size + diff --git a/panda/python/Lib/site-packages/Crypto/Hash/SHA224.pyo b/panda/python/Lib/site-packages/Crypto/Hash/SHA224.pyo new file mode 100644 index 0000000000000000000000000000000000000000..47b49a6ca8b4607ccdb14ac8a8931e53308ddd4e GIT binary patch literal 2225 zcmcIl+iu%N5FJt%Ta+BTKraZ;hXoqIN&wS|lZRGl-MH?>E>bt3Q?wNX&=k3n)}~07 zyK<@`Zw~Uw&)F{3 zWs9ynDqoZ1IJ~h%sYlZ`_1ok~{5C0b=oeU#4I06yM{kL4h<@#NDA}Z>O>g1NJ(3-| z+@}7v6?UkQ zG|$Fbm|U2N6m~ikqiCwqxyVQVag5ZycWOjY=E*FU*okdyaHxz()L3f6`yw%wT1R6E zTLRzV;h`9n`BWTRzx)$+NKK2pG;9A{8^DiMs|n0Co)a* z-Lmq$*xO-HIn-E#cKAu%m8<=7r0oaPUF6O>M(}(CJm<#%#cS(Y_ z4&8t^b!IU*3L=A<;4g^Ad;+l`H>}*E;JnM{>lf&b(@1l2Bg1J*%!ulJt#pZSjm#oSEtZ16%22U;1qS48m@SgZ#XZwH)?L506x%!4M* z_zq38HF8$r@X&_CX+}64g|mu)QylOT>tw)T1T7w--Jx@Q+V^M+=gzv;8MYRNSu~XZ zjc3AeimROR(6TE;CLyzvLrdRWC4r?TuU@CtVtSTm(xMPRcPoIqgP3u8hNij1HS0~U z<2Ie9+o{Fu6So!EI~V}$nft+<9UcSJtCl(AXV ztlrD01WZPjx@UQeI>sClAo$!!R1{R3@lqpR;gD-t&c#TTD1z~1mR&6mUlcN-ksdw4~Z2^p2Bzj2hNJaMru6wA{0@M3+&j|EqxC|$Z;1=Mra zVzZVj-Z5@f+8D+Ei-AAj?23Wy?t5&9^Js5tSjuaq;rfbsh!^q)Sg?2|eljY>J$oAG z(;_nF{k4WKqR&|Jt5%f*W-rgAYH0XkLWeRL@U*peYM+~L$`X$bSEO4{QNXXiy^;Zw z$f9C7A8cc|zL$4KYg@ZMuP)x^PqL;r-6NR_$L> CqXPZ_ literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Hash/SHA256.py b/panda/python/Lib/site-packages/Crypto/Hash/SHA256.py new file mode 100644 index 00000000..b0a99b31 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Hash/SHA256.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""SHA-256 cryptographic hash algorithm. + +SHA-256 belongs to the SHA-2_ family of cryptographic hashes. +It produces the 256 bit digest of a message. + + >>> from Crypto.Hash import SHA256 + >>> + >>> h = SHA256.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +*SHA* stands for Secure Hash Algorithm. + +.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'SHA256Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +try: + import hashlib + hashFactory = hashlib.sha256 + +except ImportError: + from Crypto.Hash import _SHA256 + hashFactory = _SHA256 + +class SHA256Hash(HashAlgo): + """Class that implements a SHA-256 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-sha256 OBJECT IDENTIFIER ::= { + #: joint-iso-itu-t(2) country(16) us(840) organization(1) + #: gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 + #: } + #: + #: This value uniquely identifies the SHA-256 algorithm. + oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01') + + digest_size = 32 + block_size = 64 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return SHA256Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `SHA256Hash.update()`. + Optional. + + :Return: A `SHA256Hash` object + """ + return SHA256Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = SHA256Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = SHA256Hash.block_size + diff --git a/panda/python/Lib/site-packages/Crypto/Hash/SHA256.pyo b/panda/python/Lib/site-packages/Crypto/Hash/SHA256.pyo new file mode 100644 index 0000000000000000000000000000000000000000..4bdf526036f0e45ba1a52a81caeaceeb88b96e96 GIT binary patch literal 2225 zcmcIl+iu%N5FJt%Ta+BTKraZ;hXoqIN&wTjv_&hlZd~_b7pWW23EBz*Xo_4(Yf~i4 zT{%^eHwSs_xAfoo0qvQkE`I2vOJIky*O@tUcDDBSmRJ5c2x3}%4g8;?>AxTnqCTWU zeTNd4k{Ts-8rP@~y+KKn(i**BZG+M}O&ip2kTbt)CpRf=Qol*ENf#T`-=v?jU8>6# zU3yf$BFAxfV~bLcrfurC$&vVNQs&Svup%2Yf>Dp&5M2}f+V4=ZNlBaDz?(ZHJ9M#4 z{cWr4P=AMK&$=D<{H;TDc6_+^_>)gXT+R!VkISf-s8~!QJrPkl&P!z`Q{VHJ%Z4(| zv#}N?7iJ=b9S+4PnyPdz^3i`BBen0H7*UjYGK(d4VjCMADkBm#mfG;XNKB>H(OANk zz;|$PAVy_A6-U-D|Ck+8(;_bo8^r<3Wy`;qh%XmYekNaa@2@BPS&>9Wc89yiGEMW{ z^;A)+%!r9Uk-t~IV4L><1|A4)qAby3l$YX6#%-vq6>#! zLviUf0;rLLfX*xer(H%g;Pr;_2}6}B6NVOGcIvw*HhDSk@~MWGX_=0!0?tHT43HK2 zD`-c(!E?|edh*TQBmZ;%;h>nCNuCX!so_8?Bln6Zz66W)pyKU-(=n*<_ltSZ#2MeC zX|_hrDje?Ga5&8fhof*-5paqFUSgdLIEBTL=0JVqU34hax^ZX_xSs?B&gBVOQ;D_PFPNR=pp@nn`=E)QQ6LoTyy$6swi zB~@C;-)8D6N^yI5MU)8{m8idQl%_mzzAhBY(s%!Sea24(SEMLix?Kg@6Nfi9o-bmv zmMh*dZdKYC#s7TgcqU#NmExW~iSua@ z8T0OXhA*PeSn{h@l>=rkkECj7_+nxXWisGlYwyH9H{X^e9v!YoH=d$^Uw?Zg116D0 z#d1E_Mt6NLZ;jTrc70J@yn~NmLw^X-berzB>p44a&FMH>?v}ITc<%dmJ9k>Oe*wSf B15W?| literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Hash/SHA384.py b/panda/python/Lib/site-packages/Crypto/Hash/SHA384.py new file mode 100644 index 00000000..3490b021 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Hash/SHA384.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""SHA-384 cryptographic hash algorithm. + +SHA-384 belongs to the SHA-2_ family of cryptographic hashes. +It produces the 384 bit digest of a message. + + >>> from Crypto.Hash import SHA384 + >>> + >>> h = SHA384.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +*SHA* stands for Secure Hash Algorithm. + +.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'SHA384Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +try: + import hashlib + hashFactory = hashlib.sha384 + +except ImportError: + from Crypto.Hash import _SHA384 + hashFactory = _SHA384 + +class SHA384Hash(HashAlgo): + """Class that implements a SHA-384 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-sha384 OBJECT IDENTIFIER ::= { + #: joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) + #: nistalgorithm(4) hashalgs(2) 2 + #: } + #: + #: This value uniquely identifies the SHA-384 algorithm. + oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02') + + digest_size = 48 + block_size = 128 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return SHA384Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `SHA384Hash.update()`. + Optional. + + :Return: A `SHA384Hash` object + """ + return SHA384Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = SHA384Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = SHA384Hash.block_size + + diff --git a/panda/python/Lib/site-packages/Crypto/Hash/SHA384.pyo b/panda/python/Lib/site-packages/Crypto/Hash/SHA384.pyo new file mode 100644 index 0000000000000000000000000000000000000000..48f0df4f5b74185abd2146a0b2be229ce6750994 GIT binary patch literal 2225 zcmcIlOK;mo5FSzzZBcUU0%?l?JuJ`wRt%VS;v5p8b?dqhyGY%DPS92mK(EM^xHezi zT{%^eLjeal_P6xE^#`;wOFew((Iv3M+2_oB^X+Wo?+su5ISgZ%e=YofiB127A^{kn zbYS2>;zH7ZqzRJ-3{Y=D;z8DcSEQ{$)`YwTgBCcm2X=BDG7knG2oEmTV6YB972D7h zZMgD5y#dE@Xk!~PAMy?iI^YQWtwZ6!&uB%oV2nn6cn5F;@XMeJ$vPw*c!%EH1JQ-c zO&DxiWeWydG<)9blIQOofb)~1-GgUOS*&K2DJP0osf=05b;@`)DU~#79{B!Z*+^t% zG11JF%%pC zhTq}gAseeQXUEpB;Dj8Kc~vSyM)82fvc;dJ?DP3lP>46ZN2`foS|!|w-e~(oWLder znyQp63`>Jl{8syd+x#6gu*0DQze-7;pi49LBJx5K%b??RQ?>^g5QRYIB7IQ0Adt2W z+#qk7#A4(q5*e9^{6(S>pO9Fnx2)cV@VrOo>lY}FGp;GQ+)$b_k&D7;Oe^6-=}yrv zn-MGe(;_M3DJ>F7pN+CIzOr%JSxv!v?Thy(j%YMpSMFn9{(&MU->DH^$Jq48C=9@* z18-4r;VlNx00#p)w+Ni|2+@$%8^R}wWFbuyS%Ar@Z+UD=HS5u-hL&lOjje*5;XNDx zEA$tr9ruSXkrw>m>)pq}^I(5i%}iPr!xwTi)Y6FEipN*TVm+*RJEU|BYy5+17J7Kb zci1#p17{fyb!|A5W(CZVM!tzM;zU1QnlxDncx%T2T!n?yz!nDPl9P zS^bw>AxuUn-M2i(Iz}8~Nbs2vSW&RrOcpcj6&`Xe)QpX#!Xg-_)8cAz_`DcWnI${H zauZfkshRk7DzABlw})2nf(fp${>D7ZXy9U1C>Evf(Z%YFA1kUzJX^S32ij*xw>MtQ zW3!fP-Vttf+6cw}i-AAj*);<@y${F^<3jx`EV1vt9yB8w6?YDv-;v4eu_5qCn!AEb2nYz*>W3B*V%A4oGr(9KYGx;*KYg^ D^n3%r literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Hash/SHA512.py b/panda/python/Lib/site-packages/Crypto/Hash/SHA512.py new file mode 100644 index 00000000..d57548d3 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Hash/SHA512.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""SHA-512 cryptographic hash algorithm. + +SHA-512 belongs to the SHA-2_ family of cryptographic hashes. +It produces the 512 bit digest of a message. + + >>> from Crypto.Hash import SHA512 + >>> + >>> h = SHA512.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +*SHA* stands for Secure Hash Algorithm. + +.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'SHA512Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +try: + import hashlib + hashFactory = hashlib.sha512 + +except ImportError: + from Crypto.Hash import _SHA512 + hashFactory = _SHA512 + +class SHA512Hash(HashAlgo): + """Class that implements a SHA-512 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-sha512 OBJECT IDENTIFIER ::= { + #: joint-iso-itu-t(2) + #: country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 + #: } + #: + #: This value uniquely identifies the SHA-512 algorithm. + oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03') + + digest_size = 64 + block_size = 128 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return SHA512Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `SHA512Hash.update()`. + Optional. + + :Return: A `SHA512Hash` object + """ + return SHA512Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = SHA512Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = SHA512Hash.block_size + diff --git a/panda/python/Lib/site-packages/Crypto/Hash/SHA512.pyo b/panda/python/Lib/site-packages/Crypto/Hash/SHA512.pyo new file mode 100644 index 0000000000000000000000000000000000000000..85cfe8bdfe15f4515f8ef0530829f378d644d856 GIT binary patch literal 2225 zcmcIlZExH}5FXoiPR@5}f>c12_^=X{a*Y(HNs9z02o2#SK_yg9E8ujJvuE#}H}TnK zcQ55oKOm**M}7wC!uJ_buWo_(E}XP%w){@w`GpMxlY`Pan%Gi>@V6e&O- zr2~BjQWsJW(gut@=%e0*)Q8-Im!z#h-hfFH`b}_V5A5VR2^ zT5uJBdJT@_(8dD*L!Q5L0M1X2c0buaV2PSlrW`9?WinwI*BRsaxKz?)lQ0Mt%Z4H^ zi?L>=WF`}gh7V#k;uD$ASULKSV}uTaQ^P7%rqe{=PTWQYhtjZAj)gX~kF$x;nvVtA zV)z{%9B6&B)k_t9!1oK`6}qC4C^5qVy2 zucj&`3&XN76Tj8I;I?1~4eT&&c#�Diu2y$y5nueK@)WN*J=(BG6-*F;#DGFVQLq z3#m;wF0c2h=`fcGH?l1B-bhxp*#GqL?t$%EEv(W}pc|Nvho|X7Mk^!V_!x zyD$Ov>%hqk`44_wOdl8$JGHuwD$SCQXZ6q;4v~)t*pj&}j(vqqAEFS*T%-?57X;GQ zfg9vagIJ6lMIs|Jk-tbZ;u8`J^`_NZ5S@4FeEl57an3a*mm5k`E+(Qd8q-SnP`Wep z%Vxxi-n2-|WJ-%f+GE4KOs;I4c2-mHe(U1hi6gv*>&a)>mw%v0$aiXl*D*HzAqoR< z>A)LQTzG>4c;H|_=N5spE+HDxdPDfcu`HyCV+$}j^({|Ksb*a|)zC66@{v`LGrWrf zV1@n?wd3C41=4~)`FeLh{49JtsAeWBi@|d_9B668ZpD);WU(I9yd6+F1~vX+HH&;a z<2!7ctbwx(hq^W#N;8H-Q8>#8D8&&iu}(%5M%1D%wmWo=PWv9)+_|%^b%w0Palt17 zL8Fm4p5Rr^scYF4V6K>@Dmd*f$IMEFsrzTo(y5RR!Z%hXfU$f+|8Hs9I4CBkr(rcqtMy zuUWkpTp>(GDBZI>#yUnEVo30r5m-^M+Kd-7>?Iy@E!2#Sq{1SYWYgkmarnF#Qkf+? z;c^pJQmL8vbtK}I&uQRdRVWsv@6pBTj2|niNIYM-T?g7@N4Ga# z%ww~bYu*uVb=nBU|BHb?;Mp|;+uirb4&~9_)>w&asnPW%^Dti2-^T^>XX2HSIo`7; zNja&wG51$9bP+?sl3umC91weHB$q=&7Zc~OQbjau?VZ}^<{PE((V>cT>nV!p^|x0t zA`)3tEa#(5?5^(RozdFXuFva>cla^d&>x}jUEkew182+ioQ|{MZa7;`;C}F+bFbz7 E3sma^VE_OC literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Hash/_MD2.pyd b/panda/python/Lib/site-packages/Crypto/Hash/_MD2.pyd new file mode 100644 index 0000000000000000000000000000000000000000..43046930e5b7060a60fa61e908f4b47660e5b093 GIT binary patch literal 9728 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 HdEkEl5ih9q literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Hash/_MD4.pyd b/panda/python/Lib/site-packages/Crypto/Hash/_MD4.pyd new file mode 100644 index 0000000000000000000000000000000000000000..3dedd83ab43942cb5b94d2e2f93113e3f523bd93 GIT binary patch literal 10752 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 Ta9g<@co+Kg`ZNN6PXzuO(-W~% literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Hash/_RIPEMD160.pyd b/panda/python/Lib/site-packages/Crypto/Hash/_RIPEMD160.pyd new file mode 100644 index 0000000000000000000000000000000000000000..1fba081692f700dcdc3d50451b89416e764037b0 GIT binary patch literal 10752 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 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Hash/_SHA224.pyd b/panda/python/Lib/site-packages/Crypto/Hash/_SHA224.pyd new file mode 100644 index 0000000000000000000000000000000000000000..04d47bbfb74bb472732732dd66f30f9247bdab6c GIT binary patch literal 10240 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 R6P{fm_V?@W8ThL*@Ly!~_q+fA literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Hash/_SHA256.pyd b/panda/python/Lib/site-packages/Crypto/Hash/_SHA256.pyd new file mode 100644 index 0000000000000000000000000000000000000000..9efa9fc833f608f7b4284e4a85c0efb4a4f26fc5 GIT binary patch literal 10240 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 G1^yF{U4+H} literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Hash/_SHA512.pyd b/panda/python/Lib/site-packages/Crypto/Hash/_SHA512.pyd new file mode 100644 index 0000000000000000000000000000000000000000..24a3109895a5711272e044f23bd2c53fdd95ee27 GIT binary patch literal 13824 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 KM=$qY?)?jcYz-6u literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Hash/hashalgo.py b/panda/python/Lib/site-packages/Crypto/Hash/hashalgo.py new file mode 100644 index 00000000..b38b3a6c --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Hash/hashalgo.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +from binascii import hexlify + +class HashAlgo: + """A generic class for an abstract cryptographic hash algorithm. + + :undocumented: block_size + """ + + #: The size of the resulting hash in bytes. + digest_size = None + #: The internal block size of the hash algorithm in bytes. + block_size = None + + def __init__(self, hashFactory, data=None): + """Initialize the hash object. + + :Parameters: + hashFactory : callable + An object that will generate the actual hash implementation. + *hashFactory* must have a *new()* method, or must be directly + callable. + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `update()`. + """ + if hasattr(hashFactory, 'new'): + self._hash = hashFactory.new() + else: + self._hash = hashFactory() + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Repeated calls are equivalent to a single call with the concatenation + of all the arguments. In other words: + + >>> m.update(a); m.update(b) + + is equivalent to: + + >>> m.update(a+b) + + :Parameters: + data : byte string + The next chunk of the message being hashed. + """ + return self._hash.update(data) + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + This method does not change the state of the hash object. + You can continue updating the object after calling this function. + + :Return: A byte string of `digest_size` bytes. It may contain non-ASCII + characters, including null bytes. + """ + return self._hash.digest() + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + This method does not change the state of the hash object. + + :Return: A string of 2* `digest_size` characters. It contains only + hexadecimal ASCII digits. + """ + return self._hash.hexdigest() + + def copy(self): + """Return a copy ("clone") of the hash object. + + The copy will have the same internal state as the original hash + object. + This can be used to efficiently compute the digests of strings that + share a common initial substring. + + :Return: A hash object of the same type + """ + return self._hash.copy() + + def new(self, data=None): + """Return a fresh instance of the hash object. + + Unlike the `copy` method, the internal state of the object is empty. + + :Parameters: + data : byte string + The next chunk of the message being hashed. + + :Return: A hash object of the same type + """ + pass + diff --git a/panda/python/Lib/site-packages/Crypto/Hash/hashalgo.pyo b/panda/python/Lib/site-packages/Crypto/Hash/hashalgo.pyo new file mode 100644 index 0000000000000000000000000000000000000000..1e7508e550ec71b7d65a234bf327d21f440ebe82 GIT binary patch literal 3925 zcmc&%TW=dh6dpUN8#^gfMTj>v^aaN>7S{(1iU>x~NGPf{1*wrGXS_SMr`eq~JF`iR z`j$TP#{b~I@dMyHXYJi>nuj7KVwIiD&gERcbMeOC_d3}hqaYNkX9NGg!|OiA5aF*O zVj+@-IBAGR)D+Pj5p9T9LR<>*>;&JN;<($wS@RE`ZUZxa7sFh?h|P5Aw=jRK-25P( zr6rRl7Qe^qe#M{#(FQA`c2}Hi@(4C}iTNvVZV503%M+|H?~^U!ODk;>h$bCA-{SMz zA~^06V+Y#eK+d$)nF(bWE9c}i&7`tYO`OkE=w+BK7e1Y3YB9%|Ib@Xz!e++LlYU3y z;bD;5C=K&OTd$*moWyB(Hg@KB&ATDlZT$|3^-mbQ5HF!xLtHjR_7TmWV~#~3#!X>& zXr=soi8DjmdcGkrzl6Ol?B9faiLm<6Go2Xy?=nx}>Z_jVM?hdTE^0zvbp! z#n6jR0Vi5z@sj1Bh0}Zi{<^z+T3zAchN)Nf-_vl(xYo?Wa99^3(D!@=l@vXT1YhrQ4GU-v&9EtW8&9sO)3BWJwcTd431 z3cAsdK|Oj5t|KB$i0G7^ynctYe;)&35`PVb zYXf+sD0hEh9H!PAn-@rgC&uU5aPd4v?KtXMiR&{xMLH0Sb>Wl?#3>U8s}T1rmC+LbX|%yv@#qDw9hlkj_dU%#;R=D z>&dQ7?cM@G?oOO&Q)}jcmP2DUqF;*A5?BEY7}|!^WGIFR=#0R z5{%$QCsSK5gJ`8xq(hUS^s;kFN#n2gTpI?(gWex;C}Ar^OQ(&f}^ zBJ66(rv{K(YFV4Wkyd`WsQR;7a8mjvOWa~;?tsOp^lqnY3n+PW;wBl;*B-N2?!&rM zr o?M{1VW!(*IvbNMNxX>6%P=YVtidf9++rpOn?}HUrvir?{0gb=>bN~PV literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Protocol/AllOrNothing.py b/panda/python/Lib/site-packages/Crypto/Protocol/AllOrNothing.py new file mode 100644 index 00000000..acc92d5c --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Protocol/AllOrNothing.py @@ -0,0 +1,319 @@ +# +# AllOrNothing.py : all-or-nothing package transformations +# +# Part of the Python Cryptography Toolkit +# +# Written by Andrew M. Kuchling and others +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""This file implements all-or-nothing package transformations. + +An all-or-nothing package transformation is one in which some text is +transformed into message blocks, such that all blocks must be obtained before +the reverse transformation can be applied. Thus, if any blocks are corrupted +or lost, the original message cannot be reproduced. + +An all-or-nothing package transformation is not encryption, although a block +cipher algorithm is used. The encryption key is randomly generated and is +extractable from the message blocks. + +This class implements the All-Or-Nothing package transformation algorithm +described in: + +Ronald L. Rivest. "All-Or-Nothing Encryption and The Package Transform" +http://theory.lcs.mit.edu/~rivest/fusion.pdf + +""" + +__revision__ = "$Id$" + +import operator +import sys +from Crypto.Util.number import bytes_to_long, long_to_bytes +from Crypto.Util.py3compat import * + +def isInt(x): + test = 0 + try: + test += x + except TypeError: + return 0 + return 1 + +class AllOrNothing: + """Class implementing the All-or-Nothing package transform. + + Methods for subclassing: + + _inventkey(key_size): + Returns a randomly generated key. Subclasses can use this to + implement better random key generating algorithms. The default + algorithm is probably not very cryptographically secure. + + """ + + def __init__(self, ciphermodule, mode=None, IV=None): + """AllOrNothing(ciphermodule, mode=None, IV=None) + + ciphermodule is a module implementing the cipher algorithm to + use. It must provide the PEP272 interface. + + Note that the encryption key is randomly generated + automatically when needed. Optional arguments mode and IV are + passed directly through to the ciphermodule.new() method; they + are the feedback mode and initialization vector to use. All + three arguments must be the same for the object used to create + the digest, and to undigest'ify the message blocks. + """ + + self.__ciphermodule = ciphermodule + self.__mode = mode + self.__IV = IV + self.__key_size = ciphermodule.key_size + if not isInt(self.__key_size) or self.__key_size==0: + self.__key_size = 16 + + __K0digit = bchr(0x69) + + def digest(self, text): + """digest(text:string) : [string] + + Perform the All-or-Nothing package transform on the given + string. Output is a list of message blocks describing the + transformed text, where each block is a string of bit length equal + to the ciphermodule's block_size. + """ + + # generate a random session key and K0, the key used to encrypt the + # hash blocks. Rivest calls this a fixed, publically-known encryption + # key, but says nothing about the security implications of this key or + # how to choose it. + key = self._inventkey(self.__key_size) + K0 = self.__K0digit * self.__key_size + + # we need two cipher objects here, one that is used to encrypt the + # message blocks and one that is used to encrypt the hashes. The + # former uses the randomly generated key, while the latter uses the + # well-known key. + mcipher = self.__newcipher(key) + hcipher = self.__newcipher(K0) + + # Pad the text so that its length is a multiple of the cipher's + # block_size. Pad with trailing spaces, which will be eliminated in + # the undigest() step. + block_size = self.__ciphermodule.block_size + padbytes = block_size - (len(text) % block_size) + text = text + b(' ') * padbytes + + # Run through the algorithm: + # s: number of message blocks (size of text / block_size) + # input sequence: m1, m2, ... ms + # random key K' (`key' in the code) + # Compute output sequence: m'1, m'2, ... m's' for s' = s + 1 + # Let m'i = mi ^ E(K', i) for i = 1, 2, 3, ..., s + # Let m's' = K' ^ h1 ^ h2 ^ ... hs + # where hi = E(K0, m'i ^ i) for i = 1, 2, ... s + # + # The one complication I add is that the last message block is hard + # coded to the number of padbytes added, so that these can be stripped + # during the undigest() step + s = divmod(len(text), block_size)[0] + blocks = [] + hashes = [] + for i in range(1, s+1): + start = (i-1) * block_size + end = start + block_size + mi = text[start:end] + assert len(mi) == block_size + cipherblock = mcipher.encrypt(long_to_bytes(i, block_size)) + mticki = bytes_to_long(mi) ^ bytes_to_long(cipherblock) + blocks.append(mticki) + # calculate the hash block for this block + hi = hcipher.encrypt(long_to_bytes(mticki ^ i, block_size)) + hashes.append(bytes_to_long(hi)) + + # Add the padbytes length as a message block + i = i + 1 + cipherblock = mcipher.encrypt(long_to_bytes(i, block_size)) + mticki = padbytes ^ bytes_to_long(cipherblock) + blocks.append(mticki) + + # calculate this block's hash + hi = hcipher.encrypt(long_to_bytes(mticki ^ i, block_size)) + hashes.append(bytes_to_long(hi)) + + # Now calculate the last message block of the sequence 1..s'. This + # will contain the random session key XOR'd with all the hash blocks, + # so that for undigest(), once all the hash blocks are calculated, the + # session key can be trivially extracted. Calculating all the hash + # blocks requires that all the message blocks be received, thus the + # All-or-Nothing algorithm succeeds. + mtick_stick = bytes_to_long(key) ^ reduce(operator.xor, hashes) + blocks.append(mtick_stick) + + # we convert the blocks to strings since in Python, byte sequences are + # always represented as strings. This is more consistent with the + # model that encryption and hash algorithms always operate on strings. + return [long_to_bytes(i,self.__ciphermodule.block_size) for i in blocks] + + + def undigest(self, blocks): + """undigest(blocks : [string]) : string + + Perform the reverse package transformation on a list of message + blocks. Note that the ciphermodule used for both transformations + must be the same. blocks is a list of strings of bit length + equal to the ciphermodule's block_size. + """ + + # better have at least 2 blocks, for the padbytes package and the hash + # block accumulator + if len(blocks) < 2: + raise ValueError, "List must be at least length 2." + + # blocks is a list of strings. We need to deal with them as long + # integers + blocks = map(bytes_to_long, blocks) + + # Calculate the well-known key, to which the hash blocks are + # encrypted, and create the hash cipher. + K0 = self.__K0digit * self.__key_size + hcipher = self.__newcipher(K0) + block_size = self.__ciphermodule.block_size + + # Since we have all the blocks (or this method would have been called + # prematurely), we can calculate all the hash blocks. + hashes = [] + for i in range(1, len(blocks)): + mticki = blocks[i-1] ^ i + hi = hcipher.encrypt(long_to_bytes(mticki, block_size)) + hashes.append(bytes_to_long(hi)) + + # now we can calculate K' (key). remember the last block contains + # m's' which we don't include here + key = blocks[-1] ^ reduce(operator.xor, hashes) + + # and now we can create the cipher object + mcipher = self.__newcipher(long_to_bytes(key, self.__key_size)) + + # And we can now decode the original message blocks + parts = [] + for i in range(1, len(blocks)): + cipherblock = mcipher.encrypt(long_to_bytes(i, block_size)) + mi = blocks[i-1] ^ bytes_to_long(cipherblock) + parts.append(mi) + + # The last message block contains the number of pad bytes appended to + # the original text string, such that its length was an even multiple + # of the cipher's block_size. This number should be small enough that + # the conversion from long integer to integer should never overflow + padbytes = int(parts[-1]) + text = b('').join(map(long_to_bytes, parts[:-1])) + return text[:-padbytes] + + def _inventkey(self, key_size): + # Return key_size random bytes + from Crypto import Random + return Random.new().read(key_size) + + def __newcipher(self, key): + if self.__mode is None and self.__IV is None: + return self.__ciphermodule.new(key) + elif self.__IV is None: + return self.__ciphermodule.new(key, self.__mode) + else: + return self.__ciphermodule.new(key, self.__mode, self.__IV) + + + +if __name__ == '__main__': + import sys + import getopt + import base64 + + usagemsg = '''\ +Test module usage: %(program)s [-c cipher] [-l] [-h] + +Where: + --cipher module + -c module + Cipher module to use. Default: %(ciphermodule)s + + --aslong + -l + Print the encoded message blocks as long integers instead of base64 + encoded strings + + --help + -h + Print this help message +''' + + ciphermodule = 'AES' + aslong = 0 + + def usage(code, msg=None): + if msg: + print msg + print usagemsg % {'program': sys.argv[0], + 'ciphermodule': ciphermodule} + sys.exit(code) + + try: + opts, args = getopt.getopt(sys.argv[1:], + 'c:l', ['cipher=', 'aslong']) + except getopt.error, msg: + usage(1, msg) + + if args: + usage(1, 'Too many arguments') + + for opt, arg in opts: + if opt in ('-h', '--help'): + usage(0) + elif opt in ('-c', '--cipher'): + ciphermodule = arg + elif opt in ('-l', '--aslong'): + aslong = 1 + + # ugly hack to force __import__ to give us the end-path module + module = __import__('Crypto.Cipher.'+ciphermodule, None, None, ['new']) + + x = AllOrNothing(module) + print 'Original text:\n==========' + print __doc__ + print '==========' + msgblocks = x.digest(b(__doc__)) + print 'message blocks:' + for i, blk in zip(range(len(msgblocks)), msgblocks): + # base64 adds a trailing newline + print ' %3d' % i, + if aslong: + print bytes_to_long(blk) + else: + print base64.encodestring(blk)[:-1] + # + # get a new undigest-only object so there's no leakage + y = AllOrNothing(module) + text = y.undigest(msgblocks) + if text == b(__doc__): + print 'They match!' + else: + print 'They differ!' diff --git a/panda/python/Lib/site-packages/Crypto/Protocol/AllOrNothing.pyo b/panda/python/Lib/site-packages/Crypto/Protocol/AllOrNothing.pyo new file mode 100644 index 0000000000000000000000000000000000000000..58039065dd308427d89ecb90d8d92afed47b5806 GIT binary patch literal 8026 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 GWc~}Tl$RU; literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Protocol/Chaffing.py b/panda/python/Lib/site-packages/Crypto/Protocol/Chaffing.py new file mode 100644 index 00000000..c19e0375 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Protocol/Chaffing.py @@ -0,0 +1,245 @@ +# +# Chaffing.py : chaffing & winnowing support +# +# Part of the Python Cryptography Toolkit +# +# Written by Andrew M. Kuchling, Barry A. Warsaw, and others +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== +# +"""This file implements the chaffing algorithm. + +Winnowing and chaffing is a technique for enhancing privacy without requiring +strong encryption. In short, the technique takes a set of authenticated +message blocks (the wheat) and adds a number of chaff blocks which have +randomly chosen data and MAC fields. This means that to an adversary, the +chaff blocks look as valid as the wheat blocks, and so the authentication +would have to be performed on every block. By tailoring the number of chaff +blocks added to the message, the sender can make breaking the message +computationally infeasible. There are many other interesting properties of +the winnow/chaff technique. + +For example, say Alice is sending a message to Bob. She packetizes the +message and performs an all-or-nothing transformation on the packets. Then +she authenticates each packet with a message authentication code (MAC). The +MAC is a hash of the data packet, and there is a secret key which she must +share with Bob (key distribution is an exercise left to the reader). She then +adds a serial number to each packet, and sends the packets to Bob. + +Bob receives the packets, and using the shared secret authentication key, +authenticates the MACs for each packet. Those packets that have bad MACs are +simply discarded. The remainder are sorted by serial number, and passed +through the reverse all-or-nothing transform. The transform means that an +eavesdropper (say Eve) must acquire all the packets before any of the data can +be read. If even one packet is missing, the data is useless. + +There's one twist: by adding chaff packets, Alice and Bob can make Eve's job +much harder, since Eve now has to break the shared secret key, or try every +combination of wheat and chaff packet to read any of the message. The cool +thing is that Bob doesn't need to add any additional code; the chaff packets +are already filtered out because their MACs don't match (in all likelihood -- +since the data and MACs for the chaff packets are randomly chosen it is +possible, but very unlikely that a chaff MAC will match the chaff data). And +Alice need not even be the party adding the chaff! She could be completely +unaware that a third party, say Charles, is adding chaff packets to her +messages as they are transmitted. + +For more information on winnowing and chaffing see this paper: + +Ronald L. Rivest, "Chaffing and Winnowing: Confidentiality without Encryption" +http://theory.lcs.mit.edu/~rivest/chaffing.txt + +""" + +__revision__ = "$Id$" + +from Crypto.Util.number import bytes_to_long + +class Chaff: + """Class implementing the chaff adding algorithm. + + Methods for subclasses: + + _randnum(size): + Returns a randomly generated number with a byte-length equal + to size. Subclasses can use this to implement better random + data and MAC generating algorithms. The default algorithm is + probably not very cryptographically secure. It is most + important that the chaff data does not contain any patterns + that can be used to discern it from wheat data without running + the MAC. + + """ + + def __init__(self, factor=1.0, blocksper=1): + """Chaff(factor:float, blocksper:int) + + factor is the number of message blocks to add chaff to, + expressed as a percentage between 0.0 and 1.0. blocksper is + the number of chaff blocks to include for each block being + chaffed. Thus the defaults add one chaff block to every + message block. By changing the defaults, you can adjust how + computationally difficult it could be for an adversary to + brute-force crack the message. The difficulty is expressed + as: + + pow(blocksper, int(factor * number-of-blocks)) + + For ease of implementation, when factor < 1.0, only the first + int(factor*number-of-blocks) message blocks are chaffed. + """ + + if not (0.0<=factor<=1.0): + raise ValueError, "'factor' must be between 0.0 and 1.0" + if blocksper < 0: + raise ValueError, "'blocksper' must be zero or more" + + self.__factor = factor + self.__blocksper = blocksper + + + def chaff(self, blocks): + """chaff( [(serial-number:int, data:string, MAC:string)] ) + : [(int, string, string)] + + Add chaff to message blocks. blocks is a list of 3-tuples of the + form (serial-number, data, MAC). + + Chaff is created by choosing a random number of the same + byte-length as data, and another random number of the same + byte-length as MAC. The message block's serial number is + placed on the chaff block and all the packet's chaff blocks + are randomly interspersed with the single wheat block. This + method then returns a list of 3-tuples of the same form. + Chaffed blocks will contain multiple instances of 3-tuples + with the same serial number, but the only way to figure out + which blocks are wheat and which are chaff is to perform the + MAC hash and compare values. + """ + + chaffedblocks = [] + + # count is the number of blocks to add chaff to. blocksper is the + # number of chaff blocks to add per message block that is being + # chaffed. + count = len(blocks) * self.__factor + blocksper = range(self.__blocksper) + for i, wheat in zip(range(len(blocks)), blocks): + # it shouldn't matter which of the n blocks we add chaff to, so for + # ease of implementation, we'll just add them to the first count + # blocks + if i < count: + serial, data, mac = wheat + datasize = len(data) + macsize = len(mac) + addwheat = 1 + # add chaff to this block + for j in blocksper: + import sys + chaffdata = self._randnum(datasize) + chaffmac = self._randnum(macsize) + chaff = (serial, chaffdata, chaffmac) + # mix up the order, if the 5th bit is on then put the + # wheat on the list + if addwheat and bytes_to_long(self._randnum(16)) & 0x40: + chaffedblocks.append(wheat) + addwheat = 0 + chaffedblocks.append(chaff) + if addwheat: + chaffedblocks.append(wheat) + else: + # just add the wheat + chaffedblocks.append(wheat) + return chaffedblocks + + def _randnum(self, size): + from Crypto import Random + return Random.new().read(size) + + +if __name__ == '__main__': + text = """\ +We hold these truths to be self-evident, that all men are created equal, that +they are endowed by their Creator with certain unalienable Rights, that among +these are Life, Liberty, and the pursuit of Happiness. That to secure these +rights, Governments are instituted among Men, deriving their just powers from +the consent of the governed. That whenever any Form of Government becomes +destructive of these ends, it is the Right of the People to alter or to +abolish it, and to institute new Government, laying its foundation on such +principles and organizing its powers in such form, as to them shall seem most +likely to effect their Safety and Happiness. +""" + print 'Original text:\n==========' + print text + print '==========' + + # first transform the text into packets + blocks = [] ; size = 40 + for i in range(0, len(text), size): + blocks.append( text[i:i+size] ) + + # now get MACs for all the text blocks. The key is obvious... + print 'Calculating MACs...' + from Crypto.Hash import HMAC, SHA + key = 'Jefferson' + macs = [HMAC.new(key, block, digestmod=SHA).digest() + for block in blocks] + + assert len(blocks) == len(macs) + + # put these into a form acceptable as input to the chaffing procedure + source = [] + m = zip(range(len(blocks)), blocks, macs) + print m + for i, data, mac in m: + source.append((i, data, mac)) + + # now chaff these + print 'Adding chaff...' + c = Chaff(factor=0.5, blocksper=2) + chaffed = c.chaff(source) + + from base64 import encodestring + + # print the chaffed message blocks. meanwhile, separate the wheat from + # the chaff + + wheat = [] + print 'chaffed message blocks:' + for i, data, mac in chaffed: + # do the authentication + h = HMAC.new(key, data, digestmod=SHA) + pmac = h.digest() + if pmac == mac: + tag = '-->' + wheat.append(data) + else: + tag = ' ' + # base64 adds a trailing newline + print tag, '%3d' % i, \ + repr(data), encodestring(mac)[:-1] + + # now decode the message packets and check it against the original text + print 'Undigesting wheat...' + # PY3K: This is meant to be text, do not change to bytes (data) + newtext = "".join(wheat) + if newtext == text: + print 'They match!' + else: + print 'They differ!' diff --git a/panda/python/Lib/site-packages/Crypto/Protocol/Chaffing.pyo b/panda/python/Lib/site-packages/Crypto/Protocol/Chaffing.pyo new file mode 100644 index 0000000000000000000000000000000000000000..cf567c27478683e5df6c251071bd2448afcb5d36 GIT binary patch literal 8525 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: + raise ValueError("Selected hash algorithm has a too short digest (%d bytes)." % digest) + if len(salt)!=8: + raise ValueError("Salt is not 8 bytes long.") + for i in xrange(count-1): + pHash = pHash.new(pHash.digest()) + return pHash.digest()[:dkLen] + +def PBKDF2(password, salt, dkLen=16, count=1000, prf=None): + """Derive one or more keys from a password (or passphrase). + + This performs key derivation according to the PKCS#5 standard (v2.0), + by means of the ``PBKDF2`` algorithm. + + :Parameters: + password : string + The secret password or pass phrase to generate the key from. + salt : string + A string to use for better protection from dictionary attacks. + This value does not need to be kept secret, but it should be randomly + chosen for each derivation. It is recommended to be at least 8 bytes long. + dkLen : integer + The cumulative length of the desired keys. Default is 16 bytes, suitable for instance for `Crypto.Cipher.AES`. + count : integer + The number of iterations to carry out. It's recommended to use at least 1000. + prf : callable + A pseudorandom function. It must be a function that returns a pseudorandom string + from two parameters: a secret and a salt. If not specified, HMAC-SHA1 is used. + + :Return: A byte string of length `dkLen` that can be used as key material. + If you wanted multiple keys, just break up this string into segments of the desired length. +""" + password = tobytes(password) + if prf is None: + prf = lambda p,s: HMAC.new(p,s,SHA1).digest() + key = b('') + i = 1 + while len(key)I", i)) + for j in xrange(count-1): + previousU = t = prf(password,previousU) + U = strxor(U,t) + key += U + i = i + 1 + return key[:dkLen] + diff --git a/panda/python/Lib/site-packages/Crypto/Protocol/KDF.pyo b/panda/python/Lib/site-packages/Crypto/Protocol/KDF.pyo new file mode 100644 index 0000000000000000000000000000000000000000..73ecce9313b02c651fa4030a7938b8337ccb231a GIT binary patch literal 4678 zcmdT{-EJGl6`my}N@DFeh>_T7dNF8RlrAJfQjpdr0wb#Az(!I-plk;aREWdf5xLTG zcRe#JiGhRym4Ot!=-c$R7rpHh^bLC72WY=1|2ckkj3E+Y7h@oH0}<6kR2NB2>|#>R>teU==W`;N6VJIjFOqpNYKYwh zFV}AxM77ftufgypPj^~Bq6&Wrgm^xTtvrYm zEyFBzDo(9bm?nu1U7V#dJCN3?G*Tv#M|vzHZQ^6)j}D5|)7W;ix$&mM@&j#UmTH+9 zIm(QdRznzAjyW^h@ndLVvQd*{xrs-Y4qHl&ly%y88Q`I0uB?^$&?u|#L%KHtcDQjK zhbl>+Ci%Eb!k!{g4)ftvYYRWUA1?8cJ?6!$KZviVTM#UFS~SJ}9p-K^PZ2z%0VBrTl4ahU zWJu)}!onn)<&eamvKXqgmbo?unHkyZsjb2gEaG$^73w32y9j*6~{VQ$&;Je(<7HGC&O6a3qnuOk5qwUT^!?Uv7P|*6X$9<71tIT~-W+GIk`g zE>05ElnqVX*O6xxlSWIXxpkM6d4nRAvgJwC%%JT$e#2SY{ zNQa4qElX%pz6GinUBOEOCE7=+_Ii&c=d_BDxiq%3t&AFJRIly$4exdzgAS}QaAUa* z+UI4BvLP@wo~VjbRqQOKfljrVl=LLFrDvs8iIW}KAEV;0G2ck#gUbhGMXL~E+1HNk z1vTxew&(LDihX}$E2;{&661A6G>%nLX!IJifi!b6)rcS1_L+0JtD4)g>=%d~mZd9k zYT&wTl#HjAhr`Sw)YQc{q*<4(Bt}PH;k*OqIz7;4`XODG=yc%F#C-2zZo~$9z%y;R zr4LjAmq6FGUwZ59vb06)yNegcXsI+T{m|PqtVrqE|0X{z zMtyh>@?&_h${V;LR0f{Q3fGoT-OsHw==vkHv8ePConN+DWbNAO>S`rwsO)e9g#l@! zEGiOx#aN!oS>2RDT$YNkRg$ygvM~FHh-F#$ERTt8Pr#su{0iCJFUJ#sj0dcs%AcbG za|A2R7&*fP0WPE{P#+A`=M}}G%GER7;Pf7v?-~d_Wv8oMVbYG=xRQtPTP3k#Ofe4L zODP>*ifA3f>ABbrTHKB%KI7z?JFtWwTvn+(v8eU4s0{x7cFaa^KO_&<3Up-VmX%>; zlBI)oOaN(-&f^A6a0^^ztSjq51)ak24pF*n-^Sl)*TniIE8?*+@K+s67=~^x#3?d< zp#8M`qGV4QlS=opSig=v+`HJ%eC9b)(pDyh-_9AwE>-Y&7q>7Iez2cow%OU+=B?$E zt(CR*!}jW4K1Lr+_r8kzdlqTBQYC=hD^q@N8?~R|-m{0^+XgYUE*tR*X7(-y@smcd z6x;}ISL1uZt>8}ZVGzHIGY_IvhaYa@Xa9x)@Oc?EaeX^l6y_db@%0p0{e2Hm2N=cO z3>bR)MTZZLv&65HgPp^QRlnl0tEi) z^Q=YUF2CxspLP9`ZM%Fg5&3ctDE4gw3K8tHM2-59dX!^s@gqJ6;qlf|r$+pS~pulnu{E^l&phr=xl9*dEq{(m^X`yMxG z>IiHkSVPE*YLqEE=?EtFo5q13~X7g6GGk7OxQFnjq z*x$$NcYoi}tjlj-Z$C0_*d-_TK8EV{`U39}K=>zorQ_bt=vF8G&Oo!vxYOm1uDJXm zQVXwE460uLGW(v*8P72ZpR?P literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Protocol/__init__.py b/panda/python/Lib/site-packages/Crypto/Protocol/__init__.py new file mode 100644 index 00000000..cacc685a --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Protocol/__init__.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Cryptographic protocols + +Implements various cryptographic protocols. (Don't expect to find +network protocols here.) + +Crypto.Protocol.AllOrNothing + Transforms a message into a set of message blocks, such that the blocks + can be recombined to get the message back. + +Crypto.Protocol.Chaffing + Takes a set of authenticated message blocks (the wheat) and adds a number + of randomly generated blocks (the chaff). + +Crypto.Protocol.KDF + A collection of standard key derivation functions. + +:undocumented: __revision__ +""" + +__all__ = ['AllOrNothing', 'Chaffing', 'KDF'] +__revision__ = "$Id$" diff --git a/panda/python/Lib/site-packages/Crypto/Protocol/__init__.pyo b/panda/python/Lib/site-packages/Crypto/Protocol/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..3563102ee454046c2d5e877287ab686e78db34b0 GIT binary patch literal 790 zcmZva-)j^x5XW=9S|up{3C=^&JFtu5lSRaGr%;r(pf4T^A)CzIhTBb+WcJ$o=lrAe zU7XyHwqO@_GBZ2#nQt~3{&^;U|NM1n#O@jL`ibB4f{hho#&#g=fv`id7>XJDhhoOz zBk_H7lneh3gqXy2M`00lS33h;3=~Xgl9cCd*ILX8oNv6S1X#no}K@gh*|{6fNysC}A;*e1}>VoG{};5=hB zBqRv)+icYYvrMlc^`-`@H4m>5wpj^Ad#Dg1n$T9xqs`J5OvpuhaHY+%_+Qeb)^pxP zmZO)LmF!0Ap1VCcqltmHl#LJ=W%6~6n#Q2L1#N9^^?h4mlvz3N&4#vFvks4O!`RB* z_L@9){D7XX(=QUvfDfnPf9!(KutZGL(ZUkfU@^Lt-h7((ep8beblUSk)90f^dkRWL zT)D&mr6fJ&dvO2f(-ThYw@yP2cy2o6_4wQ#UyO2w9zcwf9JyEWCpm)~4fCP#SE@p15Zr*eBo%KaTFm2%#ZQU!Npl^@z* Q`vyP0WPhXZ=-~O_AM-5t&;S4c literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/PublicKey/DSA.py b/panda/python/Lib/site-packages/Crypto/PublicKey/DSA.py new file mode 100644 index 00000000..d6bffd67 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/PublicKey/DSA.py @@ -0,0 +1,379 @@ +# -*- coding: utf-8 -*- +# +# PublicKey/DSA.py : DSA signature primitive +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""DSA public-key signature algorithm. + +DSA_ is a widespread public-key signature algorithm. Its security is +based on the discrete logarithm problem (DLP_). Given a cyclic +group, a generator *g*, and an element *h*, it is hard +to find an integer *x* such that *g^x = h*. The problem is believed +to be difficult, and it has been proved such (and therefore secure) for +more than 30 years. + +The group is actually a sub-group over the integers modulo *p*, with *p* prime. +The sub-group order is *q*, which is prime too; it always holds that *(p-1)* is a multiple of *q*. +The cryptographic strength is linked to the magnitude of *p* and *q*. +The signer holds a value *x* (*0>> from Crypto.Random import random + >>> from Crypto.PublicKey import DSA + >>> from Crypto.Hash import SHA + >>> + >>> message = "Hello" + >>> key = DSA.generate(1024) + >>> h = SHA.new(message).digest() + >>> k = random.StrongRandom().randint(1,key.q-1) + >>> sig = key.sign(h,k) + >>> ... + >>> if key.verify(h,sig): + >>> print "OK" + >>> else: + >>> print "Incorrect signature" + +.. _DSA: http://en.wikipedia.org/wiki/Digital_Signature_Algorithm +.. _DLP: http://www.cosic.esat.kuleuven.be/publications/talk-78.pdf +.. _ECRYPT: http://www.ecrypt.eu.org/documents/D.SPA.17.pdf +""" + +__revision__ = "$Id$" + +__all__ = ['generate', 'construct', 'error', 'DSAImplementation', '_DSAobj'] + +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * + +from Crypto.PublicKey import _DSA, _slowmath, pubkey +from Crypto import Random + +try: + from Crypto.PublicKey import _fastmath +except ImportError: + _fastmath = None + +class _DSAobj(pubkey.pubkey): + """Class defining an actual DSA key. + + :undocumented: __getstate__, __setstate__, __repr__, __getattr__ + """ + #: Dictionary of DSA parameters. + #: + #: A public key will only have the following entries: + #: + #: - **y**, the public key. + #: - **g**, the generator. + #: - **p**, the modulus. + #: - **q**, the order of the sub-group. + #: + #: A private key will also have: + #: + #: - **x**, the private key. + keydata = ['y', 'g', 'p', 'q', 'x'] + + def __init__(self, implementation, key): + self.implementation = implementation + self.key = key + + def __getattr__(self, attrname): + if attrname in self.keydata: + # For backward compatibility, allow the user to get (not set) the + # DSA key parameters directly from this object. + return getattr(self.key, attrname) + else: + raise AttributeError("%s object has no %r attribute" % (self.__class__.__name__, attrname,)) + + def sign(self, M, K): + """Sign a piece of data with DSA. + + :Parameter M: The piece of data to sign with DSA. It may + not be longer in bit size than the sub-group order (*q*). + :Type M: byte string or long + + :Parameter K: A secret number, chosen randomly in the closed + range *[1,q-1]*. + :Type K: long (recommended) or byte string (not recommended) + + :attention: selection of *K* is crucial for security. Generating a + random number larger than *q* and taking the modulus by *q* is + **not** secure, since smaller values will occur more frequently. + Generating a random number systematically smaller than *q-1* + (e.g. *floor((q-1)/8)* random bytes) is also **not** secure. In general, + it shall not be possible for an attacker to know the value of `any + bit of K`__. + + :attention: The number *K* shall not be reused for any other + operation and shall be discarded immediately. + + :attention: M must be a digest cryptographic hash, otherwise + an attacker may mount an existential forgery attack. + + :Return: A tuple with 2 longs. + + .. __: http://www.di.ens.fr/~pnguyen/pub_NgSh00.htm + """ + return pubkey.pubkey.sign(self, M, K) + + def verify(self, M, signature): + """Verify the validity of a DSA signature. + + :Parameter M: The expected message. + :Type M: byte string or long + + :Parameter signature: The DSA signature to verify. + :Type signature: A tuple with 2 longs as return by `sign` + + :Return: True if the signature is correct, False otherwise. + """ + return pubkey.pubkey.verify(self, M, signature) + + def _encrypt(self, c, K): + raise TypeError("DSA cannot encrypt") + + def _decrypt(self, c): + raise TypeError("DSA cannot decrypt") + + def _blind(self, m, r): + raise TypeError("DSA cannot blind") + + def _unblind(self, m, r): + raise TypeError("DSA cannot unblind") + + def _sign(self, m, k): + return self.key._sign(m, k) + + def _verify(self, m, sig): + (r, s) = sig + return self.key._verify(m, r, s) + + def has_private(self): + return self.key.has_private() + + def size(self): + return self.key.size() + + def can_blind(self): + return False + + def can_encrypt(self): + return False + + def can_sign(self): + return True + + def publickey(self): + return self.implementation.construct((self.key.y, self.key.g, self.key.p, self.key.q)) + + def __getstate__(self): + d = {} + for k in self.keydata: + try: + d[k] = getattr(self.key, k) + except AttributeError: + pass + return d + + def __setstate__(self, d): + if not hasattr(self, 'implementation'): + self.implementation = DSAImplementation() + t = [] + for k in self.keydata: + if not d.has_key(k): + break + t.append(d[k]) + self.key = self.implementation._math.dsa_construct(*tuple(t)) + + def __repr__(self): + attrs = [] + for k in self.keydata: + if k == 'p': + attrs.append("p(%d)" % (self.size()+1,)) + elif hasattr(self.key, k): + attrs.append(k) + if self.has_private(): + attrs.append("private") + # PY3K: This is meant to be text, do not change to bytes (data) + return "<%s @0x%x %s>" % (self.__class__.__name__, id(self), ",".join(attrs)) + +class DSAImplementation(object): + """ + A DSA key factory. + + This class is only internally used to implement the methods of the + `Crypto.PublicKey.DSA` module. + """ + + def __init__(self, **kwargs): + """Create a new DSA key factory. + + :Keywords: + use_fast_math : bool + Specify which mathematic library to use: + + - *None* (default). Use fastest math available. + - *True* . Use fast math. + - *False* . Use slow math. + default_randfunc : callable + Specify how to collect random data: + + - *None* (default). Use Random.new().read(). + - not *None* . Use the specified function directly. + :Raise RuntimeError: + When **use_fast_math** =True but fast math is not available. + """ + use_fast_math = kwargs.get('use_fast_math', None) + if use_fast_math is None: # Automatic + if _fastmath is not None: + self._math = _fastmath + else: + self._math = _slowmath + + elif use_fast_math: # Explicitly select fast math + if _fastmath is not None: + self._math = _fastmath + else: + raise RuntimeError("fast math module not available") + + else: # Explicitly select slow math + self._math = _slowmath + + self.error = self._math.error + + # 'default_randfunc' parameter: + # None (default) - use Random.new().read + # not None - use the specified function + self._default_randfunc = kwargs.get('default_randfunc', None) + self._current_randfunc = None + + def _get_randfunc(self, randfunc): + if randfunc is not None: + return randfunc + elif self._current_randfunc is None: + self._current_randfunc = Random.new().read + return self._current_randfunc + + def generate(self, bits, randfunc=None, progress_func=None): + """Randomly generate a fresh, new DSA key. + + :Parameters: + bits : int + Key length, or size (in bits) of the DSA modulus + *p*. + It must be a multiple of 64, in the closed + interval [512,1024]. + randfunc : callable + Random number generation function; it should accept + a single integer N and return a string of random data + N bytes long. + If not specified, a new one will be instantiated + from ``Crypto.Random``. + progress_func : callable + Optional function that will be called with a short string + containing the key parameter currently being generated; + it's useful for interactive applications where a user is + waiting for a key to be generated. + + :attention: You should always use a cryptographically secure random number generator, + such as the one defined in the ``Crypto.Random`` module; **don't** just use the + current time and the ``random`` module. + + :Return: A DSA key object (`_DSAobj`). + + :Raise ValueError: + When **bits** is too little, too big, or not a multiple of 64. + """ + + # Check against FIPS 186-2, which says that the size of the prime p + # must be a multiple of 64 bits between 512 and 1024 + for i in (0, 1, 2, 3, 4, 5, 6, 7, 8): + if bits == 512 + 64*i: + return self._generate(bits, randfunc, progress_func) + + # The March 2006 draft of FIPS 186-3 also allows 2048 and 3072-bit + # primes, but only with longer q values. Since the current DSA + # implementation only supports a 160-bit q, we don't support larger + # values. + raise ValueError("Number of bits in p must be a multiple of 64 between 512 and 1024, not %d bits" % (bits,)) + + def _generate(self, bits, randfunc=None, progress_func=None): + rf = self._get_randfunc(randfunc) + obj = _DSA.generate_py(bits, rf, progress_func) # TODO: Don't use legacy _DSA module + key = self._math.dsa_construct(obj.y, obj.g, obj.p, obj.q, obj.x) + return _DSAobj(self, key) + + def construct(self, tup): + """Construct a DSA key from a tuple of valid DSA components. + + The modulus *p* must be a prime. + + The following equations must apply: + + - p-1 = 0 mod q + - g^x = y mod p + - 0 < x < q + - 1 < g < p + + :Parameters: + tup : tuple + A tuple of long integers, with 4 or 5 items + in the following order: + + 1. Public key (*y*). + 2. Sub-group generator (*g*). + 3. Modulus, finite field order (*p*). + 4. Sub-group order (*q*). + 5. Private key (*x*). Optional. + + :Return: A DSA key object (`_DSAobj`). + """ + key = self._math.dsa_construct(*tup) + return _DSAobj(self, key) + +_impl = DSAImplementation() +generate = _impl.generate +construct = _impl.construct +error = _impl.error + +# vim:set ts=4 sw=4 sts=4 expandtab: + diff --git a/panda/python/Lib/site-packages/Crypto/PublicKey/DSA.pyo b/panda/python/Lib/site-packages/Crypto/PublicKey/DSA.pyo new file mode 100644 index 0000000000000000000000000000000000000000..8ec41c84ab00819f02f72e68f3c2ded825705384 GIT binary patch literal 14604 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 IQe3P2A0j{Tr2qf` literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/PublicKey/ElGamal.py b/panda/python/Lib/site-packages/Crypto/PublicKey/ElGamal.py new file mode 100644 index 00000000..99af71c4 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/PublicKey/ElGamal.py @@ -0,0 +1,373 @@ +# +# ElGamal.py : ElGamal encryption/decryption and signatures +# +# Part of the Python Cryptography Toolkit +# +# Originally written by: A.M. Kuchling +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""ElGamal public-key algorithm (randomized encryption and signature). + +Signature algorithm +------------------- +The security of the ElGamal signature scheme is based (like DSA) on the discrete +logarithm problem (DLP_). Given a cyclic group, a generator *g*, +and an element *h*, it is hard to find an integer *x* such that *g^x = h*. + +The group is the largest multiplicative sub-group of the integers modulo *p*, +with *p* prime. +The signer holds a value *x* (*0>> from Crypto import Random + >>> from Crypto.Random import random + >>> from Crypto.PublicKey import ElGamal + >>> from Crypto.Util.number import GCD + >>> from Crypto.Hash import SHA + >>> + >>> message = "Hello" + >>> key = ElGamal.generate(1024, Random.new().read) + >>> h = SHA.new(message).digest() + >>> while 1: + >>> k = random.StrongRandom().randint(1,key.p-1) + >>> if GCD(k,key.p-1)==1: break + >>> sig = key.sign(h,k) + >>> ... + >>> if key.verify(h,sig): + >>> print "OK" + >>> else: + >>> print "Incorrect signature" + +.. _DLP: http://www.cosic.esat.kuleuven.be/publications/talk-78.pdf +.. _CDH: http://en.wikipedia.org/wiki/Computational_Diffie%E2%80%93Hellman_assumption +.. _ECRYPT: http://www.ecrypt.eu.org/documents/D.SPA.17.pdf +""" + +__revision__ = "$Id$" + +__all__ = ['generate', 'construct', 'error', 'ElGamalobj'] + +from Crypto.PublicKey.pubkey import * +from Crypto.Util import number + +class error (Exception): + pass + +# Generate an ElGamal key with N bits +def generate(bits, randfunc, progress_func=None): + """Randomly generate a fresh, new ElGamal key. + + The key will be safe for use for both encryption and signature + (although it should be used for **only one** purpose). + + :Parameters: + bits : int + Key length, or size (in bits) of the modulus *p*. + Recommended value is 2048. + randfunc : callable + Random number generation function; it should accept + a single integer N and return a string of random data + N bytes long. + progress_func : callable + Optional function that will be called with a short string + containing the key parameter currently being generated; + it's useful for interactive applications where a user is + waiting for a key to be generated. + + :attention: You should always use a cryptographically secure random number generator, + such as the one defined in the ``Crypto.Random`` module; **don't** just use the + current time and the ``random`` module. + + :Return: An ElGamal key object (`ElGamalobj`). + """ + obj=ElGamalobj() + # Generate a safe prime p + # See Algorithm 4.86 in Handbook of Applied Cryptography + if progress_func: + progress_func('p\n') + while 1: + q = bignum(getPrime(bits-1, randfunc)) + obj.p = 2*q+1 + if number.isPrime(obj.p, randfunc=randfunc): + break + # Generate generator g + # See Algorithm 4.80 in Handbook of Applied Cryptography + # Note that the order of the group is n=p-1=2q, where q is prime + if progress_func: + progress_func('g\n') + while 1: + # We must avoid g=2 because of Bleichenbacher's attack described + # in "Generating ElGamal signatures without knowning the secret key", + # 1996 + # + obj.g = number.getRandomRange(3, obj.p, randfunc) + safe = 1 + if pow(obj.g, 2, obj.p)==1: + safe=0 + if safe and pow(obj.g, q, obj.p)==1: + safe=0 + # Discard g if it divides p-1 because of the attack described + # in Note 11.67 (iii) in HAC + if safe and divmod(obj.p-1, obj.g)[1]==0: + safe=0 + # g^{-1} must not divide p-1 because of Khadir's attack + # described in "Conditions of the generator for forging ElGamal + # signature", 2011 + ginv = number.inverse(obj.g, obj.p) + if safe and divmod(obj.p-1, ginv)[1]==0: + safe=0 + if safe: + break + # Generate private key x + if progress_func: + progress_func('x\n') + obj.x=number.getRandomRange(2, obj.p-1, randfunc) + # Generate public key y + if progress_func: + progress_func('y\n') + obj.y = pow(obj.g, obj.x, obj.p) + return obj + +def construct(tup): + """Construct an ElGamal key from a tuple of valid ElGamal components. + + The modulus *p* must be a prime. + + The following conditions must apply: + + - 1 < g < p-1 + - g^{p-1} = 1 mod p + - 1 < x < p-1 + - g^x = y mod p + + :Parameters: + tup : tuple + A tuple of long integers, with 3 or 4 items + in the following order: + + 1. Modulus (*p*). + 2. Generator (*g*). + 3. Public key (*y*). + 4. Private key (*x*). Optional. + + :Return: An ElGamal key object (`ElGamalobj`). + """ + + obj=ElGamalobj() + if len(tup) not in [3,4]: + raise ValueError('argument for construct() wrong length') + for i in range(len(tup)): + field = obj.keydata[i] + setattr(obj, field, tup[i]) + return obj + +class ElGamalobj(pubkey): + """Class defining an ElGamal key. + + :undocumented: __getstate__, __setstate__, __repr__, __getattr__ + """ + + #: Dictionary of ElGamal parameters. + #: + #: A public key will only have the following entries: + #: + #: - **y**, the public key. + #: - **g**, the generator. + #: - **p**, the modulus. + #: + #: A private key will also have: + #: + #: - **x**, the private key. + keydata=['p', 'g', 'y', 'x'] + + def encrypt(self, plaintext, K): + """Encrypt a piece of data with ElGamal. + + :Parameter plaintext: The piece of data to encrypt with ElGamal. + It must be numerically smaller than the module (*p*). + :Type plaintext: byte string or long + + :Parameter K: A secret number, chosen randomly in the closed + range *[1,p-2]*. + :Type K: long (recommended) or byte string (not recommended) + + :Return: A tuple with two items. Each item is of the same type as the + plaintext (string or long). + + :attention: selection of *K* is crucial for security. Generating a + random number larger than *p-1* and taking the modulus by *p-1* is + **not** secure, since smaller values will occur more frequently. + Generating a random number systematically smaller than *p-1* + (e.g. *floor((p-1)/8)* random bytes) is also **not** secure. + In general, it shall not be possible for an attacker to know + the value of any bit of K. + + :attention: The number *K* shall not be reused for any other + operation and shall be discarded immediately. + """ + return pubkey.encrypt(self, plaintext, K) + + def decrypt(self, ciphertext): + """Decrypt a piece of data with ElGamal. + + :Parameter ciphertext: The piece of data to decrypt with ElGamal. + :Type ciphertext: byte string, long or a 2-item tuple as returned + by `encrypt` + + :Return: A byte string if ciphertext was a byte string or a tuple + of byte strings. A long otherwise. + """ + return pubkey.decrypt(self, ciphertext) + + def sign(self, M, K): + """Sign a piece of data with ElGamal. + + :Parameter M: The piece of data to sign with ElGamal. It may + not be longer in bit size than *p-1*. + :Type M: byte string or long + + :Parameter K: A secret number, chosen randomly in the closed + range *[1,p-2]* and such that *gcd(k,p-1)=1*. + :Type K: long (recommended) or byte string (not recommended) + + :attention: selection of *K* is crucial for security. Generating a + random number larger than *p-1* and taking the modulus by *p-1* is + **not** secure, since smaller values will occur more frequently. + Generating a random number systematically smaller than *p-1* + (e.g. *floor((p-1)/8)* random bytes) is also **not** secure. + In general, it shall not be possible for an attacker to know + the value of any bit of K. + + :attention: The number *K* shall not be reused for any other + operation and shall be discarded immediately. + + :attention: M must be be a cryptographic hash, otherwise an + attacker may mount an existential forgery attack. + + :Return: A tuple with 2 longs. + """ + return pubkey.sign(self, M, K) + + def verify(self, M, signature): + """Verify the validity of an ElGamal signature. + + :Parameter M: The expected message. + :Type M: byte string or long + + :Parameter signature: The ElGamal signature to verify. + :Type signature: A tuple with 2 longs as return by `sign` + + :Return: True if the signature is correct, False otherwise. + """ + return pubkey.verify(self, M, signature) + + def _encrypt(self, M, K): + a=pow(self.g, K, self.p) + b=( M*pow(self.y, K, self.p) ) % self.p + return ( a,b ) + + def _decrypt(self, M): + if (not hasattr(self, 'x')): + raise TypeError('Private key not available in this object') + ax=pow(M[0], self.x, self.p) + plaintext=(M[1] * inverse(ax, self.p ) ) % self.p + return plaintext + + def _sign(self, M, K): + if (not hasattr(self, 'x')): + raise TypeError('Private key not available in this object') + p1=self.p-1 + if (GCD(K, p1)!=1): + raise ValueError('Bad K value: GCD(K,p-1)!=1') + a=pow(self.g, K, self.p) + t=(M-self.x*a) % p1 + while t<0: t=t+p1 + b=(t*inverse(K, p1)) % p1 + return (a, b) + + def _verify(self, M, sig): + if sig[0]<1 or sig[0]>self.p-1: + return 0 + v1=pow(self.y, sig[0], self.p) + v1=(v1*pow(sig[0], sig[1], self.p)) % self.p + v2=pow(self.g, M, self.p) + if v1==v2: + return 1 + return 0 + + def size(self): + return number.size(self.p) - 1 + + def has_private(self): + if hasattr(self, 'x'): + return 1 + else: + return 0 + + def publickey(self): + return construct((self.p, self.g, self.y)) + + +object=ElGamalobj diff --git a/panda/python/Lib/site-packages/Crypto/PublicKey/ElGamal.pyo b/panda/python/Lib/site-packages/Crypto/PublicKey/ElGamal.pyo new file mode 100644 index 0000000000000000000000000000000000000000..6880505375f25d71522f4724c9f780025224a893 GIT binary patch literal 13203 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 K_2Ro{fB!#QHPF=n literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/PublicKey/RSA.py b/panda/python/Lib/site-packages/Crypto/PublicKey/RSA.py new file mode 100644 index 00000000..99d851dd --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/PublicKey/RSA.py @@ -0,0 +1,719 @@ +# -*- coding: utf-8 -*- +# +# PublicKey/RSA.py : RSA public key primitive +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""RSA public-key cryptography algorithm (signature and encryption). + +RSA_ is the most widespread and used public key algorithm. Its security is +based on the difficulty of factoring large integers. The algorithm has +withstood attacks for 30 years, and it is therefore considered reasonably +secure for new designs. + +The algorithm can be used for both confidentiality (encryption) and +authentication (digital signature). It is worth noting that signing and +decryption are significantly slower than verification and encryption. +The cryptograhic strength is primarily linked to the length of the modulus *n*. +In 2012, a sufficient length is deemed to be 2048 bits. For more information, +see the most recent ECRYPT_ report. + +Both RSA ciphertext and RSA signature are as big as the modulus *n* (256 +bytes if *n* is 2048 bit long). + +This module provides facilities for generating fresh, new RSA keys, constructing +them from known components, exporting them, and importing them. + + >>> from Crypto.PublicKey import RSA + >>> + >>> key = RSA.generate(2048) + >>> f = open('mykey.pem','w') + >>> f.write(RSA.exportKey('PEM')) + >>> f.close() + ... + >>> f = open('mykey.pem','r') + >>> key = RSA.importKey(f.read()) + +Even though you may choose to directly use the methods of an RSA key object +to perform the primitive cryptographic operations (e.g. `_RSAobj.encrypt`), +it is recommended to use one of the standardized schemes instead (like +`Crypto.Cipher.PKCS1_v1_5` or `Crypto.Signature.PKCS1_v1_5`). + +.. _RSA: http://en.wikipedia.org/wiki/RSA_%28algorithm%29 +.. _ECRYPT: http://www.ecrypt.eu.org/documents/D.SPA.17.pdf + +:sort: generate,construct,importKey,error +""" + +__revision__ = "$Id$" + +__all__ = ['generate', 'construct', 'error', 'importKey', 'RSAImplementation', '_RSAobj'] + +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * +from Crypto.Util.py3compat import * +#from Crypto.Util.python_compat import * +from Crypto.Util.number import getRandomRange, bytes_to_long, long_to_bytes + +from Crypto.PublicKey import _RSA, _slowmath, pubkey +from Crypto import Random + +from Crypto.Util.asn1 import DerObject, DerSequence, DerNull +import binascii +import struct + +from Crypto.Util.number import inverse + +from Crypto.Util.number import inverse + +try: + from Crypto.PublicKey import _fastmath +except ImportError: + _fastmath = None + +class _RSAobj(pubkey.pubkey): + """Class defining an actual RSA key. + + :undocumented: __getstate__, __setstate__, __repr__, __getattr__ + """ + #: Dictionary of RSA parameters. + #: + #: A public key will only have the following entries: + #: + #: - **n**, the modulus. + #: - **e**, the public exponent. + #: + #: A private key will also have: + #: + #: - **d**, the private exponent. + #: - **p**, the first factor of n. + #: - **q**, the second factor of n. + #: - **u**, the CRT coefficient (1/p) mod q. + keydata = ['n', 'e', 'd', 'p', 'q', 'u'] + + def __init__(self, implementation, key, randfunc=None): + self.implementation = implementation + self.key = key + if randfunc is None: + randfunc = Random.new().read + self._randfunc = randfunc + + def __getattr__(self, attrname): + if attrname in self.keydata: + # For backward compatibility, allow the user to get (not set) the + # RSA key parameters directly from this object. + return getattr(self.key, attrname) + else: + raise AttributeError("%s object has no %r attribute" % (self.__class__.__name__, attrname,)) + + def encrypt(self, plaintext, K): + """Encrypt a piece of data with RSA. + + :Parameter plaintext: The piece of data to encrypt with RSA. It may not + be numerically larger than the RSA module (**n**). + :Type plaintext: byte string or long + + :Parameter K: A random parameter (*for compatibility only. This + value will be ignored*) + :Type K: byte string or long + + :attention: this function performs the plain, primitive RSA encryption + (*textbook*). In real applications, you always need to use proper + cryptographic padding, and you should not directly encrypt data with + this method. Failure to do so may lead to security vulnerabilities. + It is recommended to use modules + `Crypto.Cipher.PKCS1_OAEP` or `Crypto.Cipher.PKCS1_v1_5` instead. + + :Return: A tuple with two items. The first item is the ciphertext + of the same type as the plaintext (string or long). The second item + is always None. + """ + return pubkey.pubkey.encrypt(self, plaintext, K) + + def decrypt(self, ciphertext): + """Decrypt a piece of data with RSA. + + Decryption always takes place with blinding. + + :attention: this function performs the plain, primitive RSA decryption + (*textbook*). In real applications, you always need to use proper + cryptographic padding, and you should not directly decrypt data with + this method. Failure to do so may lead to security vulnerabilities. + It is recommended to use modules + `Crypto.Cipher.PKCS1_OAEP` or `Crypto.Cipher.PKCS1_v1_5` instead. + + :Parameter ciphertext: The piece of data to decrypt with RSA. It may + not be numerically larger than the RSA module (**n**). If a tuple, + the first item is the actual ciphertext; the second item is ignored. + + :Type ciphertext: byte string, long or a 2-item tuple as returned by + `encrypt` + + :Return: A byte string if ciphertext was a byte string or a tuple + of byte strings. A long otherwise. + """ + return pubkey.pubkey.decrypt(self, ciphertext) + + def sign(self, M, K): + """Sign a piece of data with RSA. + + Signing always takes place with blinding. + + :attention: this function performs the plain, primitive RSA decryption + (*textbook*). In real applications, you always need to use proper + cryptographic padding, and you should not directly sign data with + this method. Failure to do so may lead to security vulnerabilities. + It is recommended to use modules + `Crypto.Signature.PKCS1_PSS` or `Crypto.Signature.PKCS1_v1_5` instead. + + :Parameter M: The piece of data to sign with RSA. It may + not be numerically larger than the RSA module (**n**). + :Type M: byte string or long + + :Parameter K: A random parameter (*for compatibility only. This + value will be ignored*) + :Type K: byte string or long + + :Return: A 2-item tuple. The first item is the actual signature (a + long). The second item is always None. + """ + return pubkey.pubkey.sign(self, M, K) + + def verify(self, M, signature): + """Verify the validity of an RSA signature. + + :attention: this function performs the plain, primitive RSA encryption + (*textbook*). In real applications, you always need to use proper + cryptographic padding, and you should not directly verify data with + this method. Failure to do so may lead to security vulnerabilities. + It is recommended to use modules + `Crypto.Signature.PKCS1_PSS` or `Crypto.Signature.PKCS1_v1_5` instead. + + :Parameter M: The expected message. + :Type M: byte string or long + + :Parameter signature: The RSA signature to verify. The first item of + the tuple is the actual signature (a long not larger than the modulus + **n**), whereas the second item is always ignored. + :Type signature: A 2-item tuple as return by `sign` + + :Return: True if the signature is correct, False otherwise. + """ + return pubkey.pubkey.verify(self, M, signature) + + def _encrypt(self, c, K): + return (self.key._encrypt(c),) + + def _decrypt(self, c): + #(ciphertext,) = c + (ciphertext,) = c[:1] # HACK - We should use the previous line + # instead, but this is more compatible and we're + # going to replace the Crypto.PublicKey API soon + # anyway. + + # Blinded RSA decryption (to prevent timing attacks): + # Step 1: Generate random secret blinding factor r, such that 0 < r < n-1 + r = getRandomRange(1, self.key.n-1, randfunc=self._randfunc) + # Step 2: Compute c' = c * r**e mod n + cp = self.key._blind(ciphertext, r) + # Step 3: Compute m' = c'**d mod n (ordinary RSA decryption) + mp = self.key._decrypt(cp) + # Step 4: Compute m = m**(r-1) mod n + return self.key._unblind(mp, r) + + def _blind(self, m, r): + return self.key._blind(m, r) + + def _unblind(self, m, r): + return self.key._unblind(m, r) + + def _sign(self, m, K=None): + return (self.key._sign(m),) + + def _verify(self, m, sig): + #(s,) = sig + (s,) = sig[:1] # HACK - We should use the previous line instead, but + # this is more compatible and we're going to replace + # the Crypto.PublicKey API soon anyway. + return self.key._verify(m, s) + + def has_private(self): + return self.key.has_private() + + def size(self): + return self.key.size() + + def can_blind(self): + return True + + def can_encrypt(self): + return True + + def can_sign(self): + return True + + def publickey(self): + return self.implementation.construct((self.key.n, self.key.e)) + + def __getstate__(self): + d = {} + for k in self.keydata: + try: + d[k] = getattr(self.key, k) + except AttributeError: + pass + return d + + def __setstate__(self, d): + if not hasattr(self, 'implementation'): + self.implementation = RSAImplementation() + t = [] + for k in self.keydata: + if not d.has_key(k): + break + t.append(d[k]) + self.key = self.implementation._math.rsa_construct(*tuple(t)) + + def __repr__(self): + attrs = [] + for k in self.keydata: + if k == 'n': + attrs.append("n(%d)" % (self.size()+1,)) + elif hasattr(self.key, k): + attrs.append(k) + if self.has_private(): + attrs.append("private") + # PY3K: This is meant to be text, do not change to bytes (data) + return "<%s @0x%x %s>" % (self.__class__.__name__, id(self), ",".join(attrs)) + + def exportKey(self, format='PEM', passphrase=None, pkcs=1): + """Export this RSA key. + + :Parameter format: The format to use for wrapping the key. + + - *'DER'*. Binary encoding, always unencrypted. + - *'PEM'*. Textual encoding, done according to `RFC1421`_/`RFC1423`_. + Unencrypted (default) or encrypted. + - *'OpenSSH'*. Textual encoding, done according to OpenSSH specification. + Only suitable for public keys (not private keys). + :Type format: string + + :Parameter passphrase: In case of PEM, the pass phrase to derive the encryption key from. + :Type passphrase: string + + :Parameter pkcs: The PKCS standard to follow for assembling the key. + You have two choices: + + - with **1**, the public key is embedded into an X.509 `SubjectPublicKeyInfo` DER SEQUENCE. + The private key is embedded into a `PKCS#1`_ `RSAPrivateKey` DER SEQUENCE. + This mode is the default. + - with **8**, the private key is embedded into a `PKCS#8`_ `PrivateKeyInfo` DER SEQUENCE. + This mode is not available for public keys. + + PKCS standards are not relevant for the *OpenSSH* format. + :Type pkcs: integer + + :Return: A byte string with the encoded public or private half. + :Raise ValueError: + When the format is unknown. + + .. _RFC1421: http://www.ietf.org/rfc/rfc1421.txt + .. _RFC1423: http://www.ietf.org/rfc/rfc1423.txt + .. _`PKCS#1`: http://www.ietf.org/rfc/rfc3447.txt + .. _`PKCS#8`: http://www.ietf.org/rfc/rfc5208.txt + """ + if passphrase is not None: + passphrase = tobytes(passphrase) + if format=='OpenSSH': + eb = long_to_bytes(self.e) + nb = long_to_bytes(self.n) + if bord(eb[0]) & 0x80: eb=bchr(0x00)+eb + if bord(nb[0]) & 0x80: nb=bchr(0x00)+nb + keyparts = [ 'ssh-rsa', eb, nb ] + keystring = ''.join([ struct.pack(">I",len(kp))+kp for kp in keyparts]) + return 'ssh-rsa '+binascii.b2a_base64(keystring)[:-1] + + # DER format is always used, even in case of PEM, which simply + # encodes it into BASE64. + der = DerSequence() + if self.has_private(): + keyType= { 1: 'RSA PRIVATE', 8: 'PRIVATE' }[pkcs] + der[:] = [ 0, self.n, self.e, self.d, self.p, self.q, + self.d % (self.p-1), self.d % (self.q-1), + inverse(self.q, self.p) ] + if pkcs==8: + derkey = der.encode() + der = DerSequence([0]) + der.append(algorithmIdentifier) + der.append(DerObject('OCTET STRING', derkey).encode()) + else: + keyType = "PUBLIC" + der.append(algorithmIdentifier) + bitmap = DerObject('BIT STRING') + derPK = DerSequence( [ self.n, self.e ] ) + bitmap.payload = bchr(0x00) + derPK.encode() + der.append(bitmap.encode()) + if format=='DER': + return der.encode() + if format=='PEM': + pem = b("-----BEGIN " + keyType + " KEY-----\n") + objenc = None + if passphrase and keyType.endswith('PRIVATE'): + # We only support 3DES for encryption + import Crypto.Hash.MD5 + from Crypto.Cipher import DES3 + from Crypto.Protocol.KDF import PBKDF1 + salt = self._randfunc(8) + key = PBKDF1(passphrase, salt, 16, 1, Crypto.Hash.MD5) + key += PBKDF1(key+passphrase, salt, 8, 1, Crypto.Hash.MD5) + objenc = DES3.new(key, Crypto.Cipher.DES3.MODE_CBC, salt) + pem += b('Proc-Type: 4,ENCRYPTED\n') + pem += b('DEK-Info: DES-EDE3-CBC,') + binascii.b2a_hex(salt).upper() + b('\n\n') + + binaryKey = der.encode() + if objenc: + # Add PKCS#7-like padding + padding = objenc.block_size-len(binaryKey)%objenc.block_size + binaryKey = objenc.encrypt(binaryKey+bchr(padding)*padding) + + # Each BASE64 line can take up to 64 characters (=48 bytes of data) + chunks = [ binascii.b2a_base64(binaryKey[i:i+48]) for i in range(0, len(binaryKey), 48) ] + pem += b('').join(chunks) + pem += b("-----END " + keyType + " KEY-----") + return pem + return ValueError("Unknown key format '%s'. Cannot export the RSA key." % format) + +class RSAImplementation(object): + """ + An RSA key factory. + + This class is only internally used to implement the methods of the `Crypto.PublicKey.RSA` module. + + :sort: __init__,generate,construct,importKey + :undocumented: _g*, _i* + """ + + def __init__(self, **kwargs): + """Create a new RSA key factory. + + :Keywords: + use_fast_math : bool + Specify which mathematic library to use: + + - *None* (default). Use fastest math available. + - *True* . Use fast math. + - *False* . Use slow math. + default_randfunc : callable + Specify how to collect random data: + + - *None* (default). Use Random.new().read(). + - not *None* . Use the specified function directly. + :Raise RuntimeError: + When **use_fast_math** =True but fast math is not available. + """ + use_fast_math = kwargs.get('use_fast_math', None) + if use_fast_math is None: # Automatic + if _fastmath is not None: + self._math = _fastmath + else: + self._math = _slowmath + + elif use_fast_math: # Explicitly select fast math + if _fastmath is not None: + self._math = _fastmath + else: + raise RuntimeError("fast math module not available") + + else: # Explicitly select slow math + self._math = _slowmath + + self.error = self._math.error + + self._default_randfunc = kwargs.get('default_randfunc', None) + self._current_randfunc = None + + def _get_randfunc(self, randfunc): + if randfunc is not None: + return randfunc + elif self._current_randfunc is None: + self._current_randfunc = Random.new().read + return self._current_randfunc + + def generate(self, bits, randfunc=None, progress_func=None, e=65537): + """Randomly generate a fresh, new RSA key. + + :Parameters: + bits : int + Key length, or size (in bits) of the RSA modulus. + It must be a multiple of 256, and no smaller than 1024. + + randfunc : callable + Random number generation function; it should accept + a single integer N and return a string of random data + N bytes long. + If not specified, a new one will be instantiated + from ``Crypto.Random``. + + progress_func : callable + Optional function that will be called with a short string + containing the key parameter currently being generated; + it's useful for interactive applications where a user is + waiting for a key to be generated. + + e : int + Public RSA exponent. It must be an odd positive integer. + It is typically a small number with very few ones in its + binary representation. + The default value 65537 (= ``0b10000000000000001`` ) is a safe + choice: other common values are 5, 7, 17, and 257. + + :attention: You should always use a cryptographically secure random number generator, + such as the one defined in the ``Crypto.Random`` module; **don't** just use the + current time and the ``random`` module. + + :attention: Exponent 3 is also widely used, but it requires very special care when padding + the message. + + :Return: An RSA key object (`_RSAobj`). + + :Raise ValueError: + When **bits** is too little or not a multiple of 256, or when + **e** is not odd or smaller than 2. + """ + if bits < 1024 or (bits & 0xff) != 0: + # pubkey.getStrongPrime doesn't like anything that's not a multiple of 256 and >= 1024 + raise ValueError("RSA modulus length must be a multiple of 256 and >= 1024") + if e%2==0 or e<3: + raise ValueError("RSA public exponent must be a positive, odd integer larger than 2.") + rf = self._get_randfunc(randfunc) + obj = _RSA.generate_py(bits, rf, progress_func, e) # TODO: Don't use legacy _RSA module + key = self._math.rsa_construct(obj.n, obj.e, obj.d, obj.p, obj.q, obj.u) + return _RSAobj(self, key) + + def construct(self, tup): + """Construct an RSA key from a tuple of valid RSA components. + + The modulus **n** must be the product of two primes. + The public exponent **e** must be odd and larger than 1. + + In case of a private key, the following equations must apply: + + - e != 1 + - p*q = n + - e*d = 1 mod (p-1)(q-1) + - p*u = 1 mod q + + :Parameters: + tup : tuple + A tuple of long integers, with at least 2 and no + more than 6 items. The items come in the following order: + + 1. RSA modulus (n). + 2. Public exponent (e). + 3. Private exponent (d). Only required if the key is private. + 4. First factor of n (p). Optional. + 5. Second factor of n (q). Optional. + 6. CRT coefficient, (1/p) mod q (u). Optional. + + :Return: An RSA key object (`_RSAobj`). + """ + key = self._math.rsa_construct(*tup) + return _RSAobj(self, key) + + def _importKeyDER(self, externKey): + """Import an RSA key (public or private half), encoded in DER form.""" + + try: + + der = DerSequence() + der.decode(externKey, True) + + # Try PKCS#1 first, for a private key + if len(der)==9 and der.hasOnlyInts() and der[0]==0: + # ASN.1 RSAPrivateKey element + del der[6:] # Remove d mod (p-1), d mod (q-1), and q^{-1} mod p + der.append(inverse(der[4],der[5])) # Add p^{-1} mod q + del der[0] # Remove version + return self.construct(der[:]) + + # Keep on trying PKCS#1, but now for a public key + if len(der)==2: + # The DER object is an RSAPublicKey SEQUENCE with two elements + if der.hasOnlyInts(): + return self.construct(der[:]) + # The DER object is a SubjectPublicKeyInfo SEQUENCE with two elements: + # an 'algorithm' (or 'algorithmIdentifier') SEQUENCE and a 'subjectPublicKey' BIT STRING. + # 'algorithm' takes the value given a few lines above. + # 'subjectPublicKey' encapsulates the actual ASN.1 RSAPublicKey element. + if der[0]==algorithmIdentifier: + bitmap = DerObject() + bitmap.decode(der[1], True) + if bitmap.isType('BIT STRING') and bord(bitmap.payload[0])==0x00: + der.decode(bitmap.payload[1:], True) + if len(der)==2 and der.hasOnlyInts(): + return self.construct(der[:]) + + # Try unencrypted PKCS#8 + if der[0]==0: + # The second element in the SEQUENCE is algorithmIdentifier. + # It must say RSA (see above for description). + if der[1]==algorithmIdentifier: + privateKey = DerObject() + privateKey.decode(der[2], True) + if privateKey.isType('OCTET STRING'): + return self._importKeyDER(privateKey.payload) + + except ValueError, IndexError: + pass + + raise ValueError("RSA key format is not supported") + + def importKey(self, externKey, passphrase=None): + """Import an RSA key (public or private half), encoded in standard form. + + :Parameter externKey: + The RSA key to import, encoded as a string. + + An RSA public key can be in any of the following formats: + + - X.509 `subjectPublicKeyInfo` DER SEQUENCE (binary or PEM encoding) + - `PKCS#1`_ `RSAPublicKey` DER SEQUENCE (binary or PEM encoding) + - OpenSSH (textual public key only) + + An RSA private key can be in any of the following formats: + + - PKCS#1 `RSAPrivateKey` DER SEQUENCE (binary or PEM encoding) + - `PKCS#8`_ `PrivateKeyInfo` DER SEQUENCE (binary or PEM encoding) + - OpenSSH (textual public key only) + + For details about the PEM encoding, see `RFC1421`_/`RFC1423`_. + + In case of PEM encoding, the private key can be encrypted with DES or 3TDES according to a certain ``pass phrase``. + Only OpenSSL-compatible pass phrases are supported. + :Type externKey: string + + :Parameter passphrase: + In case of an encrypted PEM key, this is the pass phrase from which the encryption key is derived. + :Type passphrase: string + + :Return: An RSA key object (`_RSAobj`). + + :Raise ValueError/IndexError/TypeError: + When the given key cannot be parsed (possibly because the pass phrase is wrong). + + .. _RFC1421: http://www.ietf.org/rfc/rfc1421.txt + .. _RFC1423: http://www.ietf.org/rfc/rfc1423.txt + .. _`PKCS#1`: http://www.ietf.org/rfc/rfc3447.txt + .. _`PKCS#8`: http://www.ietf.org/rfc/rfc5208.txt + """ + externKey = tobytes(externKey) + if passphrase is not None: + passphrase = tobytes(passphrase) + + if externKey.startswith(b('-----')): + # This is probably a PEM encoded key + lines = externKey.replace(b(" "),b('')).split() + keyobj = None + + # The encrypted PEM format + if lines[1].startswith(b('Proc-Type:4,ENCRYPTED')): + DEK = lines[2].split(b(':')) + if len(DEK)!=2 or DEK[0]!=b('DEK-Info') or not passphrase: + raise ValueError("PEM encryption format not supported.") + algo, salt = DEK[1].split(b(',')) + salt = binascii.a2b_hex(salt) + import Crypto.Hash.MD5 + from Crypto.Cipher import DES, DES3 + from Crypto.Protocol.KDF import PBKDF1 + if algo==b("DES-CBC"): + # This is EVP_BytesToKey in OpenSSL + key = PBKDF1(passphrase, salt, 8, 1, Crypto.Hash.MD5) + keyobj = DES.new(key, Crypto.Cipher.DES.MODE_CBC, salt) + elif algo==b("DES-EDE3-CBC"): + # Note that EVP_BytesToKey is note exactly the same as PBKDF1 + key = PBKDF1(passphrase, salt, 16, 1, Crypto.Hash.MD5) + key += PBKDF1(key+passphrase, salt, 8, 1, Crypto.Hash.MD5) + keyobj = DES3.new(key, Crypto.Cipher.DES3.MODE_CBC, salt) + else: + raise ValueError("Unsupport PEM encryption algorithm.") + lines = lines[2:] + + der = binascii.a2b_base64(b('').join(lines[1:-1])) + if keyobj: + der = keyobj.decrypt(der) + padding = bord(der[-1]) + der = der[:-padding] + return self._importKeyDER(der) + + if externKey.startswith(b('ssh-rsa ')): + # This is probably an OpenSSH key + keystring = binascii.a2b_base64(externKey.split(b(' '))[1]) + keyparts = [] + while len(keystring)>4: + l = struct.unpack(">I",keystring[:4])[0] + keyparts.append(keystring[4:4+l]) + keystring = keystring[4+l:] + e = bytes_to_long(keyparts[1]) + n = bytes_to_long(keyparts[2]) + return self.construct([n, e]) + if bord(externKey[0])==0x30: + # This is probably a DER encoded key + return self._importKeyDER(externKey) + + raise ValueError("RSA key format is not supported") + +#: This is the ASN.1 DER object that qualifies an algorithm as +#: compliant to PKCS#1 (that is, the standard RSA). +# It is found in all 'algorithm' fields (also called 'algorithmIdentifier'). +# It is a SEQUENCE with the oid assigned to RSA and with its parameters (none). +# 0x06 0x09 OBJECT IDENTIFIER, 9 bytes of payload +# 0x2A 0x86 0x48 0x86 0xF7 0x0D 0x01 0x01 0x01 +# rsaEncryption (1 2 840 113549 1 1 1) (PKCS #1) +# 0x05 0x00 NULL +algorithmIdentifier = DerSequence( + [ b('\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01'), + DerNull().encode() ] + ).encode() + +_impl = RSAImplementation() +#: +#: Randomly generate a fresh, new RSA key object. +#: +#: See `RSAImplementation.generate`. +#: +generate = _impl.generate +#: +#: Construct an RSA key object from a tuple of valid RSA components. +#: +#: See `RSAImplementation.construct`. +#: +construct = _impl.construct +#: +#: Import an RSA key (public or private half), encoded in standard form. +#: +#: See `RSAImplementation.importKey`. +#: +importKey = _impl.importKey +error = _impl.error + +# vim:set ts=4 sw=4 sts=4 expandtab: + diff --git a/panda/python/Lib/site-packages/Crypto/PublicKey/RSA.pyo b/panda/python/Lib/site-packages/Crypto/PublicKey/RSA.pyo new file mode 100644 index 0000000000000000000000000000000000000000..bc077b73d0d417b388619b45df7ed3f2c8a637c5 GIT binary patch literal 26461 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 5) & 15 + powb=pow(bignum(2), b) + powL1=pow(bignum(2), bits-1) + while C<4096: + for k in range(0, n+1): + V[k]=bytes_to_long(SHA.new(S+bstr(N)+bstr(k)).digest()) + W=V[n] % powb + for k in range(n-1, -1, -1): + W=(W<<160L)+V[k] + X=W+powL1 + p=X-(X%(2*obj.q)-1) + if powL1<=p and isPrime(p): + break + C, N = C+1, N+n+1 + if C<4096: + break + if progress_func: + progress_func('4096 multiples failed\n') + + obj.p = p + power=divmod(p-1, obj.q)[0] + if progress_func: + progress_func('h,g\n') + while (1): + h=bytes_to_long(randfunc(bits)) % (p-1) + g=pow(h, power, p) + if 11: + break + obj.g=g + if progress_func: + progress_func('x,y\n') + while (1): + x=bytes_to_long(randfunc(20)) + if 0 < x < obj.q: + break + obj.x, obj.y = x, pow(g, x, p) + return obj + +class DSAobj: + pass + diff --git a/panda/python/Lib/site-packages/Crypto/PublicKey/_DSA.pyo b/panda/python/Lib/site-packages/Crypto/PublicKey/_DSA.pyo new file mode 100644 index 0000000000000000000000000000000000000000..60ab638be2c590e7b48d44cae7e690198580f136 GIT binary patch literal 3264 zcmcIm&2Jl35TCdHiXG?s!%3m-9*Sa6>LwJmO;nXOX+;rL6gJR+Wn`_r8)uWX*WO*X zwzQTI=@}t<;?#=&0f_?=H*Wj~oDnB3+_=DRW^K1Ua4W0b+4ttXnKy6d_hw$=uc@5> zb;YRD@JZl*8(;7(h(%NeRb*-8D*A+5334@RCa9bs#r-6?NouC3oT6r$%ITP!A~!?L z2`W#-eaL4apC&s;N07?U6QVPs&&!i!O>n22CktPchnx55l(T!)xR3-td+1;+} zn=Q+{diU~XX{)qRY4^ipuT^>A)GC1!+LzmA{nTvOL1owPw?nV8->tb${Uf_ysop)f zQ)>4Ow(%0{<1MCDoh{7ZWBx9_;0idA1n*4IKv76^q9{^??uo{}A812nn4mB@973cE znDJr~#!?)0){>-Nm%=o65&AQY?tWp>AVpz@B8{RHtzs5;5~I$YL7JNoIMv91MiGRQ zv;%Gn=3yWu13$`uHXcY4pt6X`1+3Yr(P8f#g%cDd*^Jv%zU;q$&TRf(tO|NTUNp3NVAluYgE|zBmcT?Kz8}4*S!=N6wc_7MKv2 z4*MHtf#_NMdrrX;dON12cl1Z5+qLzE-Lic%v@KC+Fk0baSYSVf^AHmUp$!dY8LUp2 zHKzg43if=n)vyr}z}E9E_!G+p`@Yk(MNQj#9OhZJ+X}(E$4D*mBzTAj!q!o@RhJWS zAo`BY;COS~dRIm|LLH&?7Z`m_@PzA$MsE0c4V^#-A(dB4>MhV^bpdorzIipHrd3Jh zRGnSI?q@IU;tT$Se_|9Pg8mx}SRgbG84v{X&j4h=4d}YgG)AhzSnqok0uO@aipJmt zEUPipp(RNxF@^!bRbUuDU=ATqXh7#6Lj&L~K_`HEhTaFbZV$426d3+#wjdH<4RWtC zW6eO^V3K-&3#_w@KK}>R+vBr=br|790N0)q$tDs3*5>}3%wJx zkTJ0=%*xZv&Tn+cO&A~LXn8P2y$v~fqI-qYC!n3c3M;%qB)RlfEWBF4^v*4H2yQfq zV>C^Xyx3U0<;7+8&&pti$DU%()K$`8eXv2E?5V%zme6a$E)8M zu5O7lu=-#@!n!bA<7X}2!+43OQ2SKF8!d==P`)rUkEd2)D=3UkAPLPf?*9N8ou6XO z34?8?6|U=}!@XTMUDvF+_PXBoy@qcGL6r~vnE!Szr{noxn2B^#N8Qj*?Y{0E>8_0$ zc&x9n-nDhT8#t|ozBbamriY%6{38mO={0rB3{4$PeeIRyAnY8$0z0tTI>=d0(00wf z$cD%E*g9U8`)t8*Uyj!*$vo#d@0gP)3f#!JoBHOp4V^8NYTsV(mMzatfE6 zDrp&R^J*tX0mBAoreOkqgz|1oGn1>mG0B9Dl4Ngi9**;O5c&q^LW3_Ml5E>T8$x?R z`$bVK`5yZ<7yxobdBxX~`q`AZk*1bN?+V=$`cP<1mPVDRNzO;(!KMtH3OyA1neis; zVIN|G?F;kRIFG(@0p#_U1oqJg($#i<3*7*>OQMN93P4s%qZ}kq9tvtv&EdZa?m2ZG zrQtlvMGpNHl|(xanpU$~7NfDuIW@1=RYqlp{dsi}y^G3Nh4wlx!4KE$9en?Bhcme5 z7+gkQY+YKfsU(Uq9bTVtl2&{1G7@aA=GCfiKXL+`3S1!>Zt>NxG`{+k+T9wC530g= z?9(%Xc2!rIZ vDMvt%wdb{L;|fG&OaG6z>1, obj.e, 1e-12, randfunc) + q = pubkey.getStrongPrime(bits - (bits>>1), obj.e, 1e-12, randfunc) + + # It's OK for p to be larger than q, but let's be + # kind to the function that will invert it for + # th calculation of u. + if p > q: + (p, q)=(q, p) + obj.p = p + obj.q = q + + if progress_func: + progress_func('u\n') + obj.u = pubkey.inverse(obj.p, obj.q) + obj.n = obj.p*obj.q + + if progress_func: + progress_func('d\n') + obj.d=pubkey.inverse(obj.e, (obj.p-1)*(obj.q-1)) + + assert bits <= 1+obj.size(), "Generated key is too small" + + return obj + +class RSAobj(pubkey.pubkey): + + def size(self): + """size() : int + Return the maximum number of bits that can be handled by this key. + """ + return number.size(self.n) - 1 + diff --git a/panda/python/Lib/site-packages/Crypto/PublicKey/_RSA.pyo b/panda/python/Lib/site-packages/Crypto/PublicKey/_RSA.pyo new file mode 100644 index 0000000000000000000000000000000000000000..16e4fd91117da80ca8552f89857b212b108fcfd8 GIT binary patch literal 1854 zcmcIk&2A$_5Uv@I$B8##vm%F}MWPQYd9pYbXfI2|e~?zdYKg`|Xd_F*jHhFdGe6FB z&l02LfU?g3;yJkU96SR@cmVjS>?F!^T}JAfuI{Spud2VU*58}mzn=g8&6rkS3;$0s zObC$@9YH#jx|BOqxOC)_!+MMI78M>HdC=D=^(bxAOYHlU`lMZ&xpWM>4!tD0Bzk_- zA=nLrb&l;pJoqwwko|)%aG+TqV%{VtdU2zdO_At2bI74FyL2$x7zY^U3EZs2zVOI8 zbl##%NRJ|y&RweCWeKQQbV?-Ql6TRj3!ly+vMri%N-T)uh(OM6axC_So%q6}~5{NGdK>IQ&fE zVpVmla$QdBRP{K150RQA&&Eoh&8t$ER`ql*_+grjr>ba-Rf(2ZRhsVhRb#SpqIy?& zddgO6qOAa|3YEq-#$l=I-GbNaONi_ksI|cvefCQ;Gtc9NvQvGX4Z~xdk*?~HRpmh3 zg|YMgX&0}6Ku2&A#k%+B-cP^&a{7^Rp*3CkrQKi?n(!HUSINvWb@K{&vy%>4%9_c3 z)cnfGz5#($hPH;;VVxCPZ090REniPozRN3aXJ)I_u8emhWsjUFU7@9jDjcaJHOvXWiws z`_7y4f9Qo=(lLg7Trvh`?m=iYC3F_z&VqIn4y9p?*@g!@N`u(O1Px*)&l?XJ?;P!5 zXBe=B`JM$XAlOy=3bd7LX5xn0HgzdXDB`oMXbQFLL(C5@F}7l>#^80L)f9Egb*d8P zQf8PuOU7_0VM)N%mP-%0cZFP;WsBpxFgibe?bVlqo^o_fl{|qU%!r~gE_4*xF4m){ zsM02fDh@X=WcHevAQ$=76&Bxp7OX+B8*+ZFUt|W441l(KVnoY~c!3A6Gd~37( k=KVZF&j^_ja>oAyU#j-uvQ8i0$61Eq`|g&r<=%bxFHNDFmH+?% literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/PublicKey/__init__.py b/panda/python/Lib/site-packages/Crypto/PublicKey/__init__.py new file mode 100644 index 00000000..503809fa --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/PublicKey/__init__.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Public-key encryption and signature algorithms. + +Public-key encryption uses two different keys, one for encryption and +one for decryption. The encryption key can be made public, and the +decryption key is kept private. Many public-key algorithms can also +be used to sign messages, and some can *only* be used for signatures. + +======================== ============================================= +Module Description +======================== ============================================= +Crypto.PublicKey.DSA Digital Signature Algorithm (Signature only) +Crypto.PublicKey.ElGamal (Signing and encryption) +Crypto.PublicKey.RSA (Signing, encryption, and blinding) +======================== ============================================= + +:undocumented: _DSA, _RSA, _fastmath, _slowmath, pubkey +""" + +__all__ = ['RSA', 'DSA', 'ElGamal'] +__revision__ = "$Id$" + diff --git a/panda/python/Lib/site-packages/Crypto/PublicKey/__init__.pyo b/panda/python/Lib/site-packages/Crypto/PublicKey/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..ee5362f35f7ae00a441d28504862a6211043f98a GIT binary patch literal 1093 zcmb_b?`qpH5LcV78)9RRu=~(KS`xD{7%XgKrP;>VI!d!o!5|dt;)vRkvE&xNL|?Wq zu#=p`WlO(RVCkg0-~Ii0aQA}Ox9MfZ)@wlL7y8^Q+7x4R+V_~+XKKLm0h^P2z~*#) z!e+z6VECRO7tNy3+4u@uK$F#N<+U{+jRL20BYjgN$RfA3_N&q*obLuS4juR#3ra7S zSflYkF5L*ML0H=QALo4YtZ)-E0r<1R`*tCxOd41qlu{v7G1XB_&aaU7*bob}qoeXr z)%sd`B!B19v};r>u&*Qfm4&mMoKx-!yp07ziO$I!Df8F^TVk|5v8HHGLMqWZRJ83+ z=*p)D7Qh3F-Ov2os-{5Lv8L#M_5K)aH&GDnv&nJyhHfu`a zE2;?ys(%E6a-n@GoiC+dk?0D0(}~1E;u`niXCt$C639QL`?_j(K=RQKb@Y1}tfEQ? z3M0f?mPJAGb5aUX|nE(I) literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/PublicKey/_slowmath.py b/panda/python/Lib/site-packages/Crypto/PublicKey/_slowmath.py new file mode 100644 index 00000000..d926596e --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/PublicKey/_slowmath.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- +# +# PubKey/RSA/_slowmath.py : Pure Python implementation of the RSA portions of _fastmath +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Pure Python implementation of the RSA-related portions of Crypto.PublicKey._fastmath.""" + +__revision__ = "$Id$" + +__all__ = ['rsa_construct'] + +import sys + +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * +from Crypto.Util.number import size, inverse, GCD + +class error(Exception): + pass + +class _RSAKey(object): + def _blind(self, m, r): + # compute r**e * m (mod n) + return m * pow(r, self.e, self.n) + + def _unblind(self, m, r): + # compute m / r (mod n) + return inverse(r, self.n) * m % self.n + + def _decrypt(self, c): + # compute c**d (mod n) + if not self.has_private(): + raise TypeError("No private key") + if (hasattr(self,'p') and hasattr(self,'q') and hasattr(self,'u')): + m1 = pow(c, self.d % (self.p-1), self.p) + m2 = pow(c, self.d % (self.q-1), self.q) + h = m2 - m1 + if (h<0): + h = h + self.q + h = h*self.u % self.q + return h*self.p+m1 + return pow(c, self.d, self.n) + + def _encrypt(self, m): + # compute m**d (mod n) + return pow(m, self.e, self.n) + + def _sign(self, m): # alias for _decrypt + if not self.has_private(): + raise TypeError("No private key") + return self._decrypt(m) + + def _verify(self, m, sig): + return self._encrypt(sig) == m + + def has_private(self): + return hasattr(self, 'd') + + def size(self): + """Return the maximum number of bits that can be encrypted""" + return size(self.n) - 1 + +def rsa_construct(n, e, d=None, p=None, q=None, u=None): + """Construct an RSAKey object""" + assert isinstance(n, long) + assert isinstance(e, long) + assert isinstance(d, (long, type(None))) + assert isinstance(p, (long, type(None))) + assert isinstance(q, (long, type(None))) + assert isinstance(u, (long, type(None))) + obj = _RSAKey() + obj.n = n + obj.e = e + if d is None: + return obj + obj.d = d + if p is not None and q is not None: + obj.p = p + obj.q = q + else: + # Compute factors p and q from the private exponent d. + # We assume that n has no more than two factors. + # See 8.2.2(i) in Handbook of Applied Cryptography. + ktot = d*e-1 + # The quantity d*e-1 is a multiple of phi(n), even, + # and can be represented as t*2^s. + t = ktot + while t%2==0: + t=divmod(t,2)[0] + # Cycle through all multiplicative inverses in Zn. + # The algorithm is non-deterministic, but there is a 50% chance + # any candidate a leads to successful factoring. + # See "Digitalized Signatures and Public Key Functions as Intractable + # as Factorization", M. Rabin, 1979 + spotted = 0 + a = 2 + while not spotted and a<100: + k = t + # Cycle through all values a^{t*2^i}=a^k + while k77_nn%HHzX1d_S&xUsjAae=T_%Z z?!RZI{`JXczi7+wr;7h~(TdN}MIt-sjqDhS9C-r3k;s*(A{|$DT!~$IT9K$KHzQ9D z9myY#rfQg~4X5};T{=~Hm|`~!8q)EkTa%rdbnCKHmu^FL8e*a;iKk>AhfT|Kk#mtx zcBUn2O5D`hneprlX_)-Y%JYis%ts7oYFxz zi~1c5Ef%Ikq2ePz8z1g&g=rLi``*gh>JL`GwcAtq?EXC2+bxnZUg?GH!|+L5>{=P@ zj%BdhDmvLSl|gS1kkEJ03KHQNWu^sjLRkMx`WA33>99Gdo_1ywfVnsdK;NzcRVtA< z9xabRO<;Zm>H?!9(4Yv&c$;!#BRLyr#T)2Ojg;seITd+ow0Gp(mHBN|#-`N+KkH@B zR5h{o=>-MFoqe6_YM)O;d6`lyJR2YKzKP^>Aw-?KAtRM0fY_5H7jyY7A(F!YaSacZoha|od;|$^Nw#8l>KJr_wwWz zuEsx%2WnM4?T@tYtFutwvD^T9NgW=9MQiv`$;pRsHg6rr5 z`oG{cc4`NdzS@DF(}s{mx@-2|9i2P4O1p^SHl67jPAwMDiPJQ5X2raN-zn2H*UUV| zZBoTnK~tM2E^XfG_`)q7nY&s#c@OCIEU(;QV)IwYR-7tZKf-|*&3(j%vcU6cBd;)b zF6l+a1=v<+{xVCk_jsO+z0U3yIz_&6K500uB6*T3Gjvq~eL+{0JR6zSH5!{`6n6pK zKxs%9Mv9_o25+Hz!6j+X!~R#KCSJW3qHD50_!&T}CDSG~Y-B)*r+1{GX(|NIGgL*e zhPbtl0Rh}`A(l*9iK$JoLgN26V;V1xE7-0zrRgF9VJW1a*{0dQ@ zdOxelX-&@Ra`JUKMOx&@0@5d@=${H=gPnpcWAY}jj!xt;z_SK1&!*($&vM$3X8zcm zPBGm&MAQRZm$PX(`L&!*b9YWYFbM9z;SAWr7EL*A()12p$=3~F%#$KJCN`EqsA3Zj zG_4y%FZ-O?9RNyHYn1E zP4-ee^}66m4?HZhQd59ZGm4^zVI1j9sQsa$!D&R3+jglJ4FpPnR@^02Zy5eIO$GfD zq3W#bnb*vs=NZo|7|)qAH=OUdfPgdW%;Nu?dlO$Youy$Fa_<#Y$Tx66jOqcd^Z%$q zP+?Hi<9I=jqw(U)@xwgj%3}_B`W@ORgQ1PH(Ug?eSHwm&jgv1qIR1W2sLep=gsCAV z^p61G5MGsP(IYuhapBXl?<%50|CT!9nBoBo1-QqFbAe-47l!l$0^Szx1|CW4ygzk@Ap%{Q(Bp4badYhTuw%0O;w!1n;@69b+dT8CN^sw#^sy4(!f ze?ZeHY7_srkwD%sZ<|}DO>r>Jj?2T(FhEQgYwC@mN=KS%!bx!59cuE!7uWN9EGf5H zM_To0u%UwR74%{)M708x3lpB!iqI!et*W(#WKn0;u2J0 z?XPlfa^GHt!qwn5x`}`;Q#Se*8C`sf{0q*q*UqysRpY8OjXsas=ekyuwee_3|IljX z@o`e%{Sy;fIkm!02QWiHF(?#?PnE<-(*3MtQ8aueeN-l$)!yLF8Z#g~NzgN0T(WgY zpytB;Yz{+*b^oLt_xS3n?}?i0*mTQgM=DsLNuaX-9-xW*F5STN9c$e_p8oJA&eHb^ Z&+(jw({#ROX3Q;T!CiR&_4S3f{tI=!m*M~b literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/PublicKey/pubkey.py b/panda/python/Lib/site-packages/Crypto/PublicKey/pubkey.py new file mode 100644 index 00000000..e44de8fc --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/PublicKey/pubkey.py @@ -0,0 +1,240 @@ +# +# pubkey.py : Internal functions for public key operations +# +# Part of the Python Cryptography Toolkit +# +# Written by Andrew Kuchling, Paul Swartz, and others +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== +# + +__revision__ = "$Id$" + +import types, warnings +from Crypto.Util.number import * + +# Basic public key class +class pubkey: + """An abstract class for a public key object. + + :undocumented: __getstate__, __setstate__, __eq__, __ne__, validate + """ + def __init__(self): + pass + + def __getstate__(self): + """To keep key objects platform-independent, the key data is + converted to standard Python long integers before being + written out. It will then be reconverted as necessary on + restoration.""" + d=self.__dict__ + for key in self.keydata: + if d.has_key(key): d[key]=long(d[key]) + return d + + def __setstate__(self, d): + """On unpickling a key object, the key data is converted to the big +number representation being used, whether that is Python long +integers, MPZ objects, or whatever.""" + for key in self.keydata: + if d.has_key(key): self.__dict__[key]=bignum(d[key]) + + def encrypt(self, plaintext, K): + """Encrypt a piece of data. + + :Parameter plaintext: The piece of data to encrypt. + :Type plaintext: byte string or long + + :Parameter K: A random parameter required by some algorithms + :Type K: byte string or long + + :Return: A tuple with two items. Each item is of the same type as the + plaintext (string or long). + """ + wasString=0 + if isinstance(plaintext, types.StringType): + plaintext=bytes_to_long(plaintext) ; wasString=1 + if isinstance(K, types.StringType): + K=bytes_to_long(K) + ciphertext=self._encrypt(plaintext, K) + if wasString: return tuple(map(long_to_bytes, ciphertext)) + else: return ciphertext + + def decrypt(self, ciphertext): + """Decrypt a piece of data. + + :Parameter ciphertext: The piece of data to decrypt. + :Type ciphertext: byte string, long or a 2-item tuple as returned by `encrypt` + + :Return: A byte string if ciphertext was a byte string or a tuple + of byte strings. A long otherwise. + """ + wasString=0 + if not isinstance(ciphertext, types.TupleType): + ciphertext=(ciphertext,) + if isinstance(ciphertext[0], types.StringType): + ciphertext=tuple(map(bytes_to_long, ciphertext)) ; wasString=1 + plaintext=self._decrypt(ciphertext) + if wasString: return long_to_bytes(plaintext) + else: return plaintext + + def sign(self, M, K): + """Sign a piece of data. + + :Parameter M: The piece of data to encrypt. + :Type M: byte string or long + + :Parameter K: A random parameter required by some algorithms + :Type K: byte string or long + + :Return: A tuple with two items. + """ + if (not self.has_private()): + raise TypeError('Private key not available in this object') + if isinstance(M, types.StringType): M=bytes_to_long(M) + if isinstance(K, types.StringType): K=bytes_to_long(K) + return self._sign(M, K) + + def verify (self, M, signature): + """Verify the validity of a signature. + + :Parameter M: The expected message. + :Type M: byte string or long + + :Parameter signature: The signature to verify. + :Type signature: tuple with two items, as return by `sign` + + :Return: True if the signature is correct, False otherwise. + """ + if isinstance(M, types.StringType): M=bytes_to_long(M) + return self._verify(M, signature) + + # alias to compensate for the old validate() name + def validate (self, M, signature): + warnings.warn("validate() method name is obsolete; use verify()", + DeprecationWarning) + + def blind(self, M, B): + """Blind a message to prevent certain side-channel attacks. + + :Parameter M: The message to blind. + :Type M: byte string or long + + :Parameter B: Blinding factor. + :Type B: byte string or long + + :Return: A byte string if M was so. A long otherwise. + """ + wasString=0 + if isinstance(M, types.StringType): + M=bytes_to_long(M) ; wasString=1 + if isinstance(B, types.StringType): B=bytes_to_long(B) + blindedmessage=self._blind(M, B) + if wasString: return long_to_bytes(blindedmessage) + else: return blindedmessage + + def unblind(self, M, B): + """Unblind a message after cryptographic processing. + + :Parameter M: The encoded message to unblind. + :Type M: byte string or long + + :Parameter B: Blinding factor. + :Type B: byte string or long + """ + wasString=0 + if isinstance(M, types.StringType): + M=bytes_to_long(M) ; wasString=1 + if isinstance(B, types.StringType): B=bytes_to_long(B) + unblindedmessage=self._unblind(M, B) + if wasString: return long_to_bytes(unblindedmessage) + else: return unblindedmessage + + + # The following methods will usually be left alone, except for + # signature-only algorithms. They both return Boolean values + # recording whether this key's algorithm can sign and encrypt. + def can_sign (self): + """Tell if the algorithm can deal with cryptographic signatures. + + This property concerns the *algorithm*, not the key itself. + It may happen that this particular key object hasn't got + the private information required to generate a signature. + + :Return: boolean + """ + return 1 + + def can_encrypt (self): + """Tell if the algorithm can deal with data encryption. + + This property concerns the *algorithm*, not the key itself. + It may happen that this particular key object hasn't got + the private information required to decrypt data. + + :Return: boolean + """ + return 1 + + def can_blind (self): + """Tell if the algorithm can deal with data blinding. + + This property concerns the *algorithm*, not the key itself. + It may happen that this particular key object hasn't got + the private information required carry out blinding. + + :Return: boolean + """ + return 0 + + # The following methods will certainly be overridden by + # subclasses. + + def size (self): + """Tell the maximum number of bits that can be handled by this key. + + :Return: int + """ + return 0 + + def has_private (self): + """Tell if the key object contains private components. + + :Return: bool + """ + return 0 + + def publickey (self): + """Construct a new key carrying only the public information. + + :Return: A new `pubkey` object. + """ + return self + + def __eq__ (self, other): + """__eq__(other): 0, 1 + Compare us to other for equality. + """ + return self.__getstate__() == other.__getstate__() + + def __ne__ (self, other): + """__ne__(other): 0, 1 + Compare us to other for inequality. + """ + return not self.__eq__(other) diff --git a/panda/python/Lib/site-packages/Crypto/PublicKey/pubkey.pyo b/panda/python/Lib/site-packages/Crypto/PublicKey/pubkey.pyo new file mode 100644 index 0000000000000000000000000000000000000000..8c61844d0b921e9ff1671d915257a21393808e03 GIT binary patch literal 8938 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 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Random/Fortuna/FortunaAccumulator.py b/panda/python/Lib/site-packages/Crypto/Random/Fortuna/FortunaAccumulator.py new file mode 100644 index 00000000..6ffbdc5a --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Random/Fortuna/FortunaAccumulator.py @@ -0,0 +1,171 @@ +# -*- coding: ascii -*- +# +# FortunaAccumulator.py : Fortuna's internal accumulator +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +__revision__ = "$Id$" + +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * +from Crypto.Util.py3compat import * + +from binascii import b2a_hex +import time +import warnings + +from Crypto.pct_warnings import ClockRewindWarning +import SHAd256 + +import FortunaGenerator + +class FortunaPool(object): + """Fortuna pool type + + This object acts like a hash object, with the following differences: + + - It keeps a count (the .length attribute) of the number of bytes that + have been added to the pool + - It supports a .reset() method for in-place reinitialization + - The method to add bytes to the pool is .append(), not .update(). + """ + + digest_size = SHAd256.digest_size + + def __init__(self): + self.reset() + + def append(self, data): + self._h.update(data) + self.length += len(data) + + def digest(self): + return self._h.digest() + + def hexdigest(self): + if sys.version_info[0] == 2: + return b2a_hex(self.digest()) + else: + return b2a_hex(self.digest()).decode() + + def reset(self): + self._h = SHAd256.new() + self.length = 0 + +def which_pools(r): + """Return a list of pools indexes (in range(32)) that are to be included during reseed number r. + + According to _Practical Cryptography_, chapter 10.5.2 "Pools": + + "Pool P_i is included if 2**i is a divisor of r. Thus P_0 is used + every reseed, P_1 every other reseed, P_2 every fourth reseed, etc." + """ + # This is a separate function so that it can be unit-tested. + assert r >= 1 + retval = [] + mask = 0 + for i in range(32): + # "Pool P_i is included if 2**i is a divisor of [reseed_count]" + if (r & mask) == 0: + retval.append(i) + else: + break # optimization. once this fails, it always fails + mask = (mask << 1) | 1L + return retval + +class FortunaAccumulator(object): + + # An estimate of how many bytes we must append to pool 0 before it will + # contain 128 bits of entropy (with respect to an attack). We reseed the + # generator only after pool 0 contains `min_pool_size` bytes. Note that + # unlike with some other PRNGs, Fortuna's security does not rely on the + # accuracy of this estimate---we can accord to be optimistic here. + min_pool_size = 64 # size in bytes + + # If an attacker can predict some (but not all) of our entropy sources, the + # `min_pool_size` check may not be sufficient to prevent a successful state + # compromise extension attack. To resist this attack, Fortuna spreads the + # input across 32 pools, which are then consumed (to reseed the output + # generator) with exponentially decreasing frequency. + # + # In order to prevent an attacker from gaining knowledge of all 32 pools + # before we have a chance to fill them with enough information that the + # attacker cannot predict, we impose a rate limit of 10 reseeds/second (one + # per 100 ms). This ensures that a hypothetical 33rd pool would only be + # needed after a minimum of 13 years of sustained attack. + reseed_interval = 0.100 # time in seconds + + def __init__(self): + self.reseed_count = 0 + self.generator = FortunaGenerator.AESGenerator() + self.last_reseed = None + + # Initialize 32 FortunaPool instances. + # NB: This is _not_ equivalent to [FortunaPool()]*32, which would give + # us 32 references to the _same_ FortunaPool instance (and cause the + # assertion below to fail). + self.pools = [FortunaPool() for i in range(32)] # 32 pools + assert(self.pools[0] is not self.pools[1]) + + def _forget_last_reseed(self): + # This is not part of the standard Fortuna definition, and using this + # function frequently can weaken Fortuna's ability to resist a state + # compromise extension attack, but we need this in order to properly + # implement Crypto.Random.atfork(). Otherwise, forked child processes + # might continue to use their parent's PRNG state for up to 100ms in + # some cases. (e.g. CVE-2013-1445) + self.last_reseed = None + + def random_data(self, bytes): + current_time = time.time() + if (self.last_reseed is not None and self.last_reseed > current_time): # Avoid float comparison to None to make Py3k happy + warnings.warn("Clock rewind detected. Resetting last_reseed.", ClockRewindWarning) + self.last_reseed = None + if (self.pools[0].length >= self.min_pool_size and + (self.last_reseed is None or + current_time > self.last_reseed + self.reseed_interval)): + self._reseed(current_time) + # The following should fail if we haven't seeded the pool yet. + return self.generator.pseudo_random_data(bytes) + + def _reseed(self, current_time=None): + if current_time is None: + current_time = time.time() + seed = [] + self.reseed_count += 1 + self.last_reseed = current_time + for i in which_pools(self.reseed_count): + seed.append(self.pools[i].digest()) + self.pools[i].reset() + + seed = b("").join(seed) + self.generator.reseed(seed) + + def add_random_event(self, source_number, pool_number, data): + assert 1 <= len(data) <= 32 + assert 0 <= source_number <= 255 + assert 0 <= pool_number <= 31 + self.pools[pool_number].append(bchr(source_number)) + self.pools[pool_number].append(bchr(len(data))) + self.pools[pool_number].append(data) + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/Random/Fortuna/FortunaAccumulator.pyo b/panda/python/Lib/site-packages/Crypto/Random/Fortuna/FortunaAccumulator.pyo new file mode 100644 index 0000000000000000000000000000000000000000..dfd18c5d547d1013914b1595a60aa9cac3df9eef GIT binary patch literal 5405 zcmcgwU2hv%89w7UPV6|Fu%(5RWjVCn#VLttQgzX;VEd77p$J9Mq)UYr7>#F6>~ZWF z@62)2thN`Zd&LD;2nlXM;y3V5_#gZLc%Ju+V?(*EBh8!hecsRKeUF#^wcg18aN`QDk@%5TX9vLRaE}jbZ8kv%jFPv)YNcEJxkqo zbgJqZhgZ~aS&eF{Q&V1f@QUiJOfOkgomFYCs$pG?8miN{T(_n=Ytwa2)oH4@uFSeR z#i|zN60*+t;>l^l3I6W)P&Omn9i3)Yw5I5`NY zk0AI6?ShW2yomq!kr@$T8x1GIz*Ap&>b0jl^s9(+yHpPRxDp`dXVP)ABK}?Y!<5%TL%lkUuTa8=oGZH@~(KBl{Xdi z9;TdvATe}8Cx(xsvE;m&s&w+V#HDHQogphAg~+>f>9PvhU}8nAc(Ul2z(|dNkvXqL6LlEd@9SQUB!(4H`wAmGk=!W z+k+*a&PBu#A=uMeY-?2xD-5z*y?3Bg`U+ev1702q%28rJiHSv3PoMA0F)+JIRrOkQ)oj zRK@gDAg9FUB~n%^Np&8kJ=40ozr8IPOozE)uId`BiiQ)Wu6U9&aT4s&EAw97cF7aS zoaHg+u`4*rk&2Tj9BK#Wy*wQEFM=H%^~146y4<_dzSrK@H&{FrH|7$sjOe2vVWzsg zIyu$*w{Oc>h|K*WDUcE&N8V-uFe$L%4mV5+6JI7ogTTHh+1IY)$Ux1}z6GSy?Ud_8w*#ww)-n*V<43$}SF1tot%0HsVBYbZZ zbnwOw5XKd8DC=AihqBHUaVYCh(4mgQG8A;RSwXjo(~<`uy}$gKfB(2ILBWeIgM#dq zD251^YW%fBHvu)G+cKjDN}fi_215wwfOWq`473FTaWm5$&n;7cMzckv6XIDBi%r3$W z1Pmv*tRRXiukLMl_1XvjC(kkwLs!(SlDQfGCQKPkHa%(E)H$bhI7;A$|_>k1xWQx)Jz z$DQI|TZ0wptg5qRmH%<>$W>K*O>B0Tkk-|=c(Pm6;GBT8J8ex3nq{?FI%Tm-zWKfa z?(l)7V`K4@F>zb_d<9rS>YVIt0izbpC9qnOFPp{}^c zAWKqTtjn^=SzD5rSk(U!S91$f{^C$;2RHtSw|*0Z=G#Ed0&>B4*S)Kit6oH&rk@zl z#{l&TT7j++(6E<0^rjl0pW&lV$|p>|F<%x|F?CHXA3BAI4yjF1NH^-|K0$S+Es3iF zMMPu*R~?B<68p=(&!0^e5(~^__yJ%Vs3?3=`&W#)r$qI-r@cd|wSB7Cze;kO?Qw29A$=8S)7y}cU7e;>C6_*@;mQd>tQ-K^K^&E|TGWxc>mfQ*ZJkPo=P z=T8+r!OUI*akXdrbDIqDYr+0rl#Ryt0f)l=_tf2TW)(BtBn^uwN!&|NB8qZKE-H78 zBO6RX)?q7Q#@Ad%)wy4zB>TGxcAbhTe!Kn4pOT$y$`*0uYt<1=`~3! L&C0d!*RTEuP07QU literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Random/Fortuna/FortunaGenerator.py b/panda/python/Lib/site-packages/Crypto/Random/Fortuna/FortunaGenerator.py new file mode 100644 index 00000000..723fa630 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Random/Fortuna/FortunaGenerator.py @@ -0,0 +1,132 @@ +# -*- coding: ascii -*- +# +# FortunaGenerator.py : Fortuna's internal PRNG +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +__revision__ = "$Id$" + +import sys +if sys.version_info[0] is 2 and sys.version_info[1] is 1: + from Crypto.Util.py21compat import * +from Crypto.Util.py3compat import * + +import struct + +from Crypto.Util.number import ceil_shift, exact_log2, exact_div +from Crypto.Util import Counter +from Crypto.Cipher import AES + +import SHAd256 + +class AESGenerator(object): + """The Fortuna "generator" + + This is used internally by the Fortuna PRNG to generate arbitrary amounts + of pseudorandom data from a smaller amount of seed data. + + The output is generated by running AES-256 in counter mode and re-keying + after every mebibyte (2**16 blocks) of output. + """ + + block_size = AES.block_size # output block size in octets (128 bits) + key_size = 32 # key size in octets (256 bits) + + # Because of the birthday paradox, we expect to find approximately one + # collision for every 2**64 blocks of output from a real random source. + # However, this code generates pseudorandom data by running AES in + # counter mode, so there will be no collisions until the counter + # (theoretically) wraps around at 2**128 blocks. Thus, in order to prevent + # Fortuna's pseudorandom output from deviating perceptibly from a true + # random source, Ferguson and Schneier specify a limit of 2**16 blocks + # without rekeying. + max_blocks_per_request = 2**16 # Allow no more than this number of blocks per _pseudo_random_data request + + _four_kiblocks_of_zeros = b("\0") * block_size * 4096 + + def __init__(self): + self.counter = Counter.new(nbits=self.block_size*8, initial_value=0, little_endian=True) + self.key = None + + # Set some helper constants + self.block_size_shift = exact_log2(self.block_size) + assert (1 << self.block_size_shift) == self.block_size + + self.blocks_per_key = exact_div(self.key_size, self.block_size) + assert self.key_size == self.blocks_per_key * self.block_size + + self.max_bytes_per_request = self.max_blocks_per_request * self.block_size + + def reseed(self, seed): + if self.key is None: + self.key = b("\0") * self.key_size + + self._set_key(SHAd256.new(self.key + seed).digest()) + self.counter() # increment counter + assert len(self.key) == self.key_size + + def pseudo_random_data(self, bytes): + assert bytes >= 0 + + num_full_blocks = bytes >> 20 + remainder = bytes & ((1<<20)-1) + + retval = [] + for i in xrange(num_full_blocks): + retval.append(self._pseudo_random_data(1<<20)) + retval.append(self._pseudo_random_data(remainder)) + + return b("").join(retval) + + def _set_key(self, key): + self.key = key + self._cipher = AES.new(key, AES.MODE_CTR, counter=self.counter) + + def _pseudo_random_data(self, bytes): + if not (0 <= bytes <= self.max_bytes_per_request): + raise AssertionError("You cannot ask for more than 1 MiB of data per request") + + num_blocks = ceil_shift(bytes, self.block_size_shift) # num_blocks = ceil(bytes / self.block_size) + + # Compute the output + retval = self._generate_blocks(num_blocks)[:bytes] + + # Switch to a new key to avoid later compromises of this output (i.e. + # state compromise extension attacks) + self._set_key(self._generate_blocks(self.blocks_per_key)) + + assert len(retval) == bytes + assert len(self.key) == self.key_size + + return retval + + def _generate_blocks(self, num_blocks): + if self.key is None: + raise AssertionError("generator must be seeded before use") + assert 0 <= num_blocks <= self.max_blocks_per_request + retval = [] + for i in xrange(num_blocks >> 12): # xrange(num_blocks / 4096) + retval.append(self._cipher.encrypt(self._four_kiblocks_of_zeros)) + remaining_bytes = (num_blocks & 4095) << self.block_size_shift # (num_blocks % 4095) * self.block_size + retval.append(self._cipher.encrypt(self._four_kiblocks_of_zeros[:remaining_bytes])) + return b("").join(retval) + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/Random/Fortuna/FortunaGenerator.pyo b/panda/python/Lib/site-packages/Crypto/Random/Fortuna/FortunaGenerator.pyo new file mode 100644 index 0000000000000000000000000000000000000000..7ecc17e2a2c48e9141b744b806f19313851e3ade GIT binary patch literal 3951 zcmcgv?QR>#6}`KpD3X#a$5!LmNRzD-B#c_AwbK}AQ6zR`Hw}=e!AfmmLcw6k9ZD;a zyUfnel>+%s)8BoCK1rXd573@-XY~=Ze{DiDd*}Pkx#!+HYW;hyU;pDE9ZU0T;rkfH z{R>qtGDICo9?LY6VI($^<5=>R+|Ao^(v|wzMb{F#mYOcE=*YAs`(;>;MqBoqjh1A% zq?<0wv?H@+87|ALE5okLdNS-u#Cctr_GPvr!E&U{sm(bgXi{~X25 zP+0&B)ltV{TXNi%VVlqppj8=m#4Zbf{sF+ZWdrzb03|?+n*ykOS%p5)V$X`?Jr!07 z3wzcYSO8SIH(2AbAK|+DM>hF=Rr^JmCHD_6RJ`BsC;06j6)wTw!r442c(XE_PS29j zS>ms)`zGD}BJowyEVoHkj|yLB^;we5h=|kOs!1|;c9B;e7OlpsUn3y z9+NdJ$^d*_%?TpMuxBLa5a1^w^n zz{Ir8B_wWX|Eioj|0x1MAB^}<3?Tsi=(ox4?ObrBFwNor4ou2u#YO1Z74PM8*U z#ps03+uf9$;A+i<#a(a65NgIIXj&U@D;7x9;BV$9()4= zWFJ4>da(VQ?Oz?t&-_tU9(+}d4qV~w);t@ZWQW!r?9^v-Umc{%&V$A&F20xEyN&g{ zgfT?bm?w}OgM~zcsMosHdaE@i1}s!*2gN-{MN?`VWvm>C2PY!BGy7Yjb_DEUURz+s z<4&{YJd!(@c)ZM*1|i~-E*nu!yYr~slvWuqE~P|2T}P!P9i_J@s?N@OMVWK={_rG+ zx1=i^C3W%wDEO2{(JfQjLJdq`d=0QtiQ4k8T}Tb6>(Sl#y{I24sGLE5E2wh_fCeaj z_7biEX-OWxY{{X>%eI_u(gn|B0`~OVx8>!MoVV$c1P|DEI6yGJ`%wOJedHX@8AiZq zxGWk7#+U(NZ$RXBiw)G8HgE(aK^Q<*Sr5{H8Y-fvh;)Zm#cV!@pZVJuG9e0@5C#on zT>2K5kS@nnQK};c^tly-lk>D^xtN*BVmfWSL$gqAXIW9^w$@{6>*3^T_u@5JjLiDq z+x!{5jx>^1KkCPw=yr53dNaOsi%Sb`V+!mBix^yA-xFw30P?|7fITMP4btEh*Oj9r zL*P0$3_K>wzy9OXXJ%(VRVHh&GUH-?gtSaYQCxM|tH&q3iv!0f`u32h7g$U?w@@xw z%)3U?Zk$MgN+h60lUEXFo61! z?x6RczHq_|$UTB0&#Of;&dRd#N#;(HNmV0p))q-VE0YJw*Tv_|hMKPtr;$rFAgeE= zjLM$&c;XyLSXAY+x~}S!2{CZ6qrAu245j3GNC4>voPzRd zBYOHXoPf9?j*m5o-i_AdTdmveyGu%1@{4M!!Tt$>xL(HccdlZ2Fc1S!ET_L_CWSd* zyU$>}r{CTe8YWg-sd<_RkGS51qE8Ttu%IQ6c|un{MIigX3lNTyW)Y$QUKMEYp`aAl z(+ITdh-ZU4ExK?%8CiW;;b}FpFtg>;uHc;uL@!C-fiz%3xXK~v&)IyJRl;f$l{%Fz z$4r?14m!-FS|EQHP1dd^=6hRLPVKL;ExnIfs#Y-d7Pq2p(+^Q;a0`J9FEpb8?==|x z7dZM1#gU;Bt;6V@=uVVGZ=fKkM>5bX%AjIQna!**%1>kPu3X^hWI}i`c{MgB)i6Xb zHRGmC65;Z{q(q$3pR(fBf&-9tDb={TtxB)z<&rXH@&w1+-syJYUexJ#;*Ges*6X6Q zd$$Jaw7iBfwS7@IxHK->;;J*J|IOgtti44!sr1Dbo=)3;^2HSIqlXX1)oh-H7u%1A zK5j;+hx7Gf>^*bH^+|C4k!|9K25g?}Ny=-p!b6pB+op3zBYZHyJucu0)#%uc{pF>v lq5P@<)@Ro50y{os^mk-ICti&{h}Mt`SL3&%o6${t{|g$jYU}_2 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Random/Fortuna/SHAd256.py b/panda/python/Lib/site-packages/Crypto/Random/Fortuna/SHAd256.py new file mode 100644 index 00000000..2e135c9a --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Random/Fortuna/SHAd256.py @@ -0,0 +1,98 @@ +# -*- coding: ascii -*- +# +# Random/Fortuna/SHAd256.py : SHA_d-256 hash function implementation +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""\ +SHA_d-256 hash function implementation. + +This module should comply with PEP 247. +""" + +__revision__ = "$Id$" +__all__ = ['new', 'digest_size'] + +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * +from Crypto.Util.py3compat import * + +from binascii import b2a_hex + +from Crypto.Hash import SHA256 + +assert SHA256.digest_size == 32 + +class _SHAd256(object): + """SHA-256, doubled. + + Returns SHA-256(SHA-256(data)). + """ + + digest_size = SHA256.digest_size + + _internal = object() + + def __init__(self, internal_api_check, sha256_hash_obj): + if internal_api_check is not self._internal: + raise AssertionError("Do not instantiate this class directly. Use %s.new()" % (__name__,)) + self._h = sha256_hash_obj + + # PEP 247 "copy" method + def copy(self): + """Return a copy of this hashing object""" + return _SHAd256(SHAd256._internal, self._h.copy()) + + # PEP 247 "digest" method + def digest(self): + """Return the hash value of this object as a binary string""" + retval = SHA256.new(self._h.digest()).digest() + assert len(retval) == 32 + return retval + + # PEP 247 "hexdigest" method + def hexdigest(self): + """Return the hash value of this object as a (lowercase) hexadecimal string""" + retval = b2a_hex(self.digest()) + assert len(retval) == 64 + if sys.version_info[0] == 2: + return retval + else: + return retval.decode() + + # PEP 247 "update" method + def update(self, data): + self._h.update(data) + +# PEP 247 module-level "digest_size" variable +digest_size = _SHAd256.digest_size + +# PEP 247 module-level "new" function +def new(data=None): + """Return a new SHAd256 hashing object""" + if not data: + data=b("") + sha = _SHAd256(_SHAd256._internal, SHA256.new(data)) + sha.new = globals()['new'] + return sha + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/Random/Fortuna/SHAd256.pyo b/panda/python/Lib/site-packages/Crypto/Random/Fortuna/SHAd256.pyo new file mode 100644 index 0000000000000000000000000000000000000000..f3ce6ae166827fd814d2683123acea097a0b2386 GIT binary patch literal 2861 zcmcImZEqVz5S}|bj_t&4XlYPDpcS;}QW1-$l!{l;rbQ`&P|mGTEla2M-6nU=`Odms zw-}{gXnzpDfFA`v0G`=BCq?1|9~xUbp55Eqoq6V&88`mwb^mQo%gi`ZmkA+qT#S5s9O$LyOT`XIS#7@W zxC~nyCtx&OSKGD@thQ8)If$b|PE{1a9_&s7w%+jTTIGl45|rf$k(^~woT~WPSYo9T zC`C-Ds2ooM>?AAnchL4eA3c;sB5&T?xzYcu|M6(HFlkwgzR$)Zof)+=lku?xT}FG= zVrI%wh~4FM^exPq7jjewzK_=|5#UE=qUbh`)*LDFE_$0@%zWU%R$IKcpcqTCi3N0G z^YI0e#RsgsRbPd0!4wkgo-IUq=rCnpvf@a<9iSSl@J1Gfd0JZ(^6eo*Yf<9&?Xh7O zOXmhc$cTT1p*c+CTgO@DVI6-T3LKv}uK5JV*=w&>o@3oxBETrt2$)p4n($QSb9IV@ zLqJFkh{jnVtA)^}0ydUeA@d`|sDWTeT<%-qS||)JR?6Vq^Fw6=cihFW<%sJ8ims1*b2tKP=}{~xR%FQ2I@mRfBKR5h8X zIGf76M(?a19yoS2_;B{Z)=|CCW*w8Ks?tbOaQ?8gIO3EtQD@+WZ(!HC!DEVgUu+t25j{75 z!cAN|z;Maq1&ndXE*VbRC~^%CHIVZ>ijp#pBFAxdz(&9&giHP&7HvY>$c0yU%2%8@ zV71p=2W=(V!8Mxs(rUK+4u4ynmCkCXds+}UHTQVeJqQFvUt#)#=?Kbmv}*VR`h({_ za}I3B9y~&Mgy2Dvla;&E0paTWHlu>I8b`mwd# zL3dg>EYwGNIhMJ01bGWDxhzP}kqT@Y{=|{y$dlhf8+pgu@B+p(w9SLb5k-}Hn%Nv& zl0xP=NWuLuybNJD;I4J`ADb*kquRZ}f0d*$Oo)F!x>-MA&T%=_ah8RQtNq(l@7+iD zajbhAPaJ5Le+=3|Sty4qCa*B-{eElwN((GpoIIa8Z-iKb#>-ro1MsxFe Gr|}Q|ly0g3 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Random/Fortuna/__init__.py b/panda/python/Lib/site-packages/Crypto/Random/Fortuna/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/panda/python/Lib/site-packages/Crypto/Random/Fortuna/__init__.pyo b/panda/python/Lib/site-packages/Crypto/Random/Fortuna/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..5e84e4bba96f7ae165ccf099a2eda2260e75b0ff GIT binary patch literal 162 zcmZSn%**vDa-V-P0~9aTV}gLH^K)a|@{3AJ^Acm? f<1_OzOXB18fciLq=Go-tr24V&PW7{UW literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Random/OSRNG/__init__.py b/panda/python/Lib/site-packages/Crypto/Random/OSRNG/__init__.py new file mode 100644 index 00000000..2fbbecbf --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Random/OSRNG/__init__.py @@ -0,0 +1,40 @@ +# +# Random/OSRNG/__init__.py : Platform-independent OS RNG API +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Provides a platform-independent interface to the random number generators +supplied by various operating systems.""" + +__revision__ = "$Id$" + +import os + +if os.name == 'posix': + from Crypto.Random.OSRNG.posix import new +elif os.name == 'nt': + from Crypto.Random.OSRNG.nt import new +elif hasattr(os, 'urandom'): + from Crypto.Random.OSRNG.fallback import new +else: + raise ImportError("Not implemented") + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/Random/OSRNG/__init__.pyo b/panda/python/Lib/site-packages/Crypto/Random/OSRNG/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..b7656b3367dbb9ae6cda97c79ed0bbdf76f241d6 GIT binary patch literal 677 zcmZ{g&x;c=6vyAp^w-wPf`TA;$YBq?bWl9GhzKfDkZ$RoECV5JUfZ}cNl0F+y?Ai% z{z?8(`UmKnX}g{_knej*K6&q(WPcv^e}DdUwS?oyIKJf>f3j$RIcoy*1at~IgEEDA z3Yfx|40H=_QV5sLQ5(t@RBf2IA+ggF(P@a{M0D z8Z8DzF2sJ^dS4pUVzC!H6^z?P;e35+>{`TqB&=c{Tiom&5kZF`jciaqOt_C06VW^{~%-4J4&@ODSo<8&U?`nP{Bljk=JFRCl$i zLVC){yRi4<@>%ne{OWo(`It8zW{rm@_aH|<8x<8%plA1BD^->YwY;GR42&!90(}U< zg&{BDzr=BU|FW2}3-$8-=tcf2e_r@KZJaGWnMDx|;mC6#wZ>Q+JQoMgMdP`U(pW=M g=6tKi)m~RlZ%cerzcD^y>7<=>ke(-xljBVP0cYT@8~^|S literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Random/OSRNG/fallback.py b/panda/python/Lib/site-packages/Crypto/Random/OSRNG/fallback.py new file mode 100644 index 00000000..5bb61260 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Random/OSRNG/fallback.py @@ -0,0 +1,46 @@ +# +# Random/OSRNG/fallback.py : Fallback entropy source for systems with os.urandom +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + + +__revision__ = "$Id$" +__all__ = ['PythonOSURandomRNG'] + +import os + +from rng_base import BaseRNG + +class PythonOSURandomRNG(BaseRNG): + + name = "" + + def __init__(self): + self._read = os.urandom + BaseRNG.__init__(self) + + def _close(self): + self._read = None + +def new(*args, **kwargs): + return PythonOSURandomRNG(*args, **kwargs) + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/Random/OSRNG/fallback.pyo b/panda/python/Lib/site-packages/Crypto/Random/OSRNG/fallback.pyo new file mode 100644 index 0000000000000000000000000000000000000000..f3aa8b604a3152376d9d067d98358415632f5fec GIT binary patch literal 1193 zcmcIj!D`z;5S^7|HA$TkdI?ON}$+5riTc@B3rVnM3#(q(_qLg zJ@=FPQSAq`@2wO2&}$+zv$MOSo%fz*{Xe@qzb}3b#&ZAo7(c;GA1)V3;FV03Bua8m za$hP>5(IbyseG9Qk_4iVR0J|XQcHe_+=*NyEy+Vpl91mGqh~xffa{#)9s3f&`OcQ}9oYi?Vi~FC;zj*qQ!lq^ZNoEQxukmr?1ZEE43Y?9K@Ia$nDWAw#Gmv-~k&S7? z9W|zVy>La2$2^1P!Fn+B8qSJbD!CQWo>*Tl1IBj>%mmPx-j7<$<5!Jw;Ot z%VXx*Elzb=msaZ)6OuMXHHk2abLI?D?_+unOxgR>!*|^e-M8u7>5+aZN2w`oaX8P$ zSJ|{MX>YNd+a_Jfln#cFB%NecH9|snzKn^W19S3sTxY57R zsknKA;XzwoCd;d!(W&1{Q#LgO<*L?bB&}nIlA12+sUGp(tr^5Gu)IP01X8<8bF})= T$FES$@YjcG+iQD!-v0A{B6I$B literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Random/OSRNG/nt.py b/panda/python/Lib/site-packages/Crypto/Random/OSRNG/nt.py new file mode 100644 index 00000000..c1c2f44e --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Random/OSRNG/nt.py @@ -0,0 +1,74 @@ +# +# Random/OSRNG/nt.py : OS entropy source for MS Windows +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + + +__revision__ = "$Id$" +__all__ = ['WindowsRNG'] + +import winrandom +from rng_base import BaseRNG + +class WindowsRNG(BaseRNG): + + name = "" + + def __init__(self): + self.__winrand = winrandom.new() + BaseRNG.__init__(self) + + def flush(self): + """Work around weakness in Windows RNG. + + The CryptGenRandom mechanism in some versions of Windows allows an + attacker to learn 128 KiB of past and future output. As a workaround, + this function reads 128 KiB of 'random' data from Windows and discards + it. + + For more information about the weaknesses in CryptGenRandom, see + _Cryptanalysis of the Random Number Generator of the Windows Operating + System_, by Leo Dorrendorf and Zvi Gutterman and Benny Pinkas + http://eprint.iacr.org/2007/419 + """ + if self.closed: + raise ValueError("I/O operation on closed file") + data = self.__winrand.get_bytes(128*1024) + assert (len(data) == 128*1024) + BaseRNG.flush(self) + + def _close(self): + self.__winrand = None + + def _read(self, N): + # Unfortunately, research shows that CryptGenRandom doesn't provide + # forward secrecy and fails the next-bit test unless we apply a + # workaround, which we do here. See http://eprint.iacr.org/2007/419 + # for information on the vulnerability. + self.flush() + data = self.__winrand.get_bytes(N) + self.flush() + return data + +def new(*args, **kwargs): + return WindowsRNG(*args, **kwargs) + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/Random/OSRNG/nt.pyo b/panda/python/Lib/site-packages/Crypto/Random/OSRNG/nt.pyo new file mode 100644 index 0000000000000000000000000000000000000000..8bba88bf1cb1097ffe6452d85cf7ebec11f02a18 GIT binary patch literal 2311 zcmcIlZHpsC5U!a_RugZz;}lU4Z17;iv6p>O&|A+#cTbnYBYVz@haoU@GM%Kelb+Ds z*$}t`asBL1^iK$W)u(#0$?f-bNcU8#yQ`jhs=B83_jdE2pZ+=@(CVq-{Vj&;V9JTQ zm?IiR)Qu>QDX&oxQx^h$2^BS(Ce%$R!X}l_5S!}s2hkPLuiZN3Tl}ZH#pljj@37qj z(}U;v1K))3N}Ie~xU_Ss|Had3MNoR)cPyQPdX0-0jxpRJCIy@Dgc&HJ;G)Ke*jK{7 zSb+B=2wRk%x9WWM9;PQJb~*E>%A^v$r%wlLnMaIqg5d-vPc(@*iq}M0Ouj~wgypLU zp%P-@6P;kyHy|#wvB4g85*fAdAK;yB;>)ttmXuHWcX>6_M*A$Qf=-}usu;HLrZ721 zb8^&s3B&U9XO9lrkK6mb+0u_o(|e)&J*T~TG?Rl1Ia00{;wpPpSiQ4zu-7xbJzJ(6 z`)3$|dy4KxA!d%3!Lk?kH70~NA+jHl2e$}5qTeGjl|H5k7_PJOO+-GSNqtR60y?(X z$U~TXRoV+7Z8PASjHYL3W6Uqu-ib6?i#KGZL;zxbV$7a%bY|h1S?&nsCa_(ny-xlIK z*boa~t|0HO&H1r**lh+Lu7y=HcW)cqsj|Hza_OZQ+H$&q1~<8O18H-&HmChtQU6d{ zF)aZ@n_+3EGPsa^fD#^rT+^lkaX0DN6;7$O)hsMZBa5X2Tm;JJs|paE`Lqu@Q0dA_ z50|Uu>r9-@Sg*}!ZSH*OyqadaqQ4X`R4Ja7)+$^QI}F@)FSR(Gd#?c51kJHBW+`53 zb0IgOj=i59?d_?V)hItL2ew_>(caQAHG~r@&G+)n9WS%Rn+7vp-FS3}c@2xFu$~P!n#*y+_f9aL0?i!c>u$a4Xi%ULb z11MnhHKgu;xNY3mb}$^@aoTR+zTJ<*jl0ohwy~I3{Ux-r>z2Y81H4XYRER0`hXDKb z(FQuRz~>PhJN8b|fM47j_#OJgLkLxWxWYP15lv!x9oobj2%&d`wRqhf*+R;6gfLR> zldYf&DF_`jeUFtGx7+eO=RD(E`wfID6ZK|vKWawdE41prMov|hg*wWzX_?Op{>!z& zE1_>z_&HhWT}&IOLAtdT4b$`~hGV+6;;p!mG~RF22CTnM#u=|O5`3J%H@N?E^Ce<7 zQw$149%7Jo +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + + +__revision__ = "$Id$" +__all__ = ['DevURandomRNG'] + +import errno +import os +import stat + +from rng_base import BaseRNG +from Crypto.Util.py3compat import b + +class DevURandomRNG(BaseRNG): + + def __init__(self, devname=None): + if devname is None: + self.name = "/dev/urandom" + else: + self.name = devname + + # Test that /dev/urandom is a character special device + f = open(self.name, "rb", 0) + fmode = os.fstat(f.fileno())[stat.ST_MODE] + if not stat.S_ISCHR(fmode): + f.close() + raise TypeError("%r is not a character special device" % (self.name,)) + + self.__file = f + + BaseRNG.__init__(self) + + def _close(self): + self.__file.close() + + def _read(self, N): + # Starting with Python 3 open with buffering=0 returns a FileIO object. + # FileIO.read behaves like read(2) and not like fread(3) and thus we + # have to handle the case that read returns less data as requested here + # more carefully. + data = b("") + while len(data) < N: + try: + d = self.__file.read(N - len(data)) + except IOError, e: + # read(2) has been interrupted by a signal; redo the read + if e.errno == errno.EINTR: + continue + raise + + if d is None: + # __file is in non-blocking mode and no data is available + return data + if len(d) == 0: + # __file is in blocking mode and arrived at EOF + return data + + data += d + return data + +def new(*args, **kwargs): + return DevURandomRNG(*args, **kwargs) + + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/Random/OSRNG/posix.pyo b/panda/python/Lib/site-packages/Crypto/Random/OSRNG/posix.pyo new file mode 100644 index 0000000000000000000000000000000000000000..6e33aaeaa10bb5d1a71364c6ded0d1b0c2d43137 GIT binary patch literal 2059 zcmcIl&2HO95S}F|N^<1b3F06wau86v;3aa401Z+UMN!*r4YX20IY=W2AZT*!P@+hM zyKy2wzSutZ+Masrr4P}EY9FBeW*Eol-4U?k+2QQ`elvFeSzY=2#b1Mj-u+zs{Tj!d zf}}(vP(>$-Mv790QkQavMqp~*rICBZdo=Qd_b6}B%%_o0iuD?lH)+7`6f0R z;#$Dcqxac3{29l50;1soei1LxB@zOo#H~cl{u>ky19qJ7LuUBw;+Wq-mUvAxZBg}r zpDu|aMMazCHE$heCRdfZaOun;>(a!dr9+bjr+cBu`ZQ_M=9w#8iPeJ*$z!sSp%OG!Wsq*gxEJ7(4ADD?!2y~V2FvRI?6!FY=LZ7 z-OO~0(stu+@-nXC#OkVR<~qsZyo;AvqJ!H|w48juEVM91Jgb>HJuXBX9|kb&u=7W@V}aTuF%e7ToR^ULTu~%fj~x5BQBs&x;;;=+ktC zs#m1WJW@-K2LTP5_%wB>n$oK^2KG5oq3CDK0t&-3cFw+rY*EGoi-gsG6Dd!DOHU9L z9zSQjz(u%y#7iVlmn9N%ZkRtJ08noh^@)LqAOZmWL4^JnW3 z;W3CJY!IFo%)sj$SII|k8*bo3*af+U*NqPdtkcIhhU4;`&YiZKu#6kR{TSdF20J>2 zsQ`3-;T2Yo1Je+PWH6-Yadlz@xYIYxUPpd|Q!PL#^c!~lZYqLX;IV1Bk`*?i$;twy z<;507ah{{DAAt{95OTq#1yykp9q~UUPQ-G#>t)h=X0sgY<8e~X=CKuYN}l01bgpx{ f>263+U)D(YY7?#u?=N4q9V{-au64EU+~4^RyB(ob literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Random/OSRNG/rng_base.py b/panda/python/Lib/site-packages/Crypto/Random/OSRNG/rng_base.py new file mode 100644 index 00000000..54c3aa0d --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Random/OSRNG/rng_base.py @@ -0,0 +1,88 @@ +# +# Random/OSRNG/rng_base.py : Base class for OSRNG +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +__revision__ = "$Id$" + +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * + +class BaseRNG(object): + + def __init__(self): + self.closed = False + self._selftest() + + def __del__(self): + self.close() + + def _selftest(self): + # Test that urandom can return data + data = self.read(16) + if len(data) != 16: + raise AssertionError("read truncated") + + # Test that we get different data every time (if we don't, the RNG is + # probably malfunctioning) + data2 = self.read(16) + if data == data2: + raise AssertionError("OS RNG returned duplicate data") + + # PEP 343: Support for the "with" statement + def __enter__(self): + pass + def __exit__(self): + """PEP 343 support""" + self.close() + + def close(self): + if not self.closed: + self._close() + self.closed = True + + def flush(self): + pass + + def read(self, N=-1): + """Return N bytes from the RNG.""" + if self.closed: + raise ValueError("I/O operation on closed file") + if not isinstance(N, (long, int)): + raise TypeError("an integer is required") + if N < 0: + raise ValueError("cannot read to end of infinite stream") + elif N == 0: + return "" + data = self._read(N) + if len(data) != N: + raise AssertionError("%s produced truncated output (requested %d, got %d)" % (self.name, N, len(data))) + return data + + def _close(self): + raise NotImplementedError("child class must implement this") + + def _read(self, N): + raise NotImplementedError("child class must implement this") + + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/Random/OSRNG/rng_base.pyo b/panda/python/Lib/site-packages/Crypto/Random/OSRNG/rng_base.pyo new file mode 100644 index 0000000000000000000000000000000000000000..cdd8a4d4e00b8821b8756bc13b8f53133c4e78ab GIT binary patch literal 3306 zcmd5;ZExH}5FXo?mrD~;1t_gRuo4X%h=#VQkfaAK*v94}j+xCzn=&Z@sEfc5b{o>z$c><{3wSFD?A_;Ln}Doc%@k{Q|=! z5Shq6WFT26MIifu*gzhJl0|YYYsqma_15{+45ntzrnqBPib(cKY@ZX`k^!dX9&byMyv%))80dNp610O!X!Ke`dj$$3(z|;)B3fuf8izU_ zGr*}iO#~!KW{V`b4%IRH(s<15PA=moJTx8y15W~Z91ugNs$=FjlKQ52AOx2b$ghC_ zrq9@iG(HU#&iiT^U0CX!@`AegWk|>T)HcnGug7IS^)_>FV`^vDAnB&Ieq5I}Gue1l zeB`ed<(aFx?kAR^Icy$XKSBV;nEwag00l{)xMhg@TldZSops~J zqfu4+ZsRy%_5wm^O3?no68wZ7DV)Pe0Z!ojE*2Yjx+|&x$OsUi1%|Nzs?IJhfKZAl zlwuOCO@+>0J+{*iD`xiYVmLA!8D;6E0S(D%P>kKt=k!n09cbI>Q)kZT^ClPnfM{}F zUnO}oMAA?Nvkpdy1Zf?BLPBx(NQBSO3ARLXjPm|bx3|vu<1+Vh3C;76{b!fQ%$~8+ z<51A&z&zk3*paDz7mzjD6V2Ls@VUVtk}DVd#fHkWgXKs2PbGMW>8l{n48 zRmPT?sRr0GU{A5ed8`c45#i7}#Hur+y2{3VFyVwJO*QtTu{RyQ9=#81tJz295bs^h zKIkl9UxQ?7KcvOjDkXY8<}NRtPs_ela2Hj1s4NPnwW02vjLxii>k0jg^@Z%;x}{8q z_9=EHVRU2i-PBl>q_u(Ju0lxI4wi%0F&1^SAXkFbi(;A7Kf4SvIf0-SJ6F5z9mxJs zUSznx)HyR8J8$ygsIWtDBd$DmTJru?npb}Ne92}_cVX01ZQ3!t{|@7vpy~Me&{BI2 z;l;$f(z?bHzsX08X?!}x*YMswjI)3`gv{CZ6d{!)iq9k&0`3JKW0Fctw%4{Av&YBm zK1!AG3N<1_Go^38a9y?M`{@_+%K3rfUW1qo+pTugUTX7qrX4LVx1$an_6#dQ-8@32 zRVAV#Ke`jA3y*BAv#9sVlP;R?&9(1+Uf}cc_N{(39Hm}cP<8Oo_PriE)xh))?loEe Rj1}gX^Vx7QcrREA{{_WN&Zz(Z literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Random/OSRNG/winrandom.pyd b/panda/python/Lib/site-packages/Crypto/Random/OSRNG/winrandom.pyd new file mode 100644 index 0000000000000000000000000000000000000000..bae1c2ca6ea7049c6cb96561ee2e795e9b6e25ba GIT binary patch literal 9728 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 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Random/_UserFriendlyRNG.py b/panda/python/Lib/site-packages/Crypto/Random/_UserFriendlyRNG.py new file mode 100644 index 00000000..957e006f --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Random/_UserFriendlyRNG.py @@ -0,0 +1,230 @@ +# -*- coding: utf-8 -*- +# +# Random/_UserFriendlyRNG.py : A user-friendly random number generator +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +__revision__ = "$Id$" + +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * + +import os +import threading +import struct +import time +from math import floor + +from Crypto.Random import OSRNG +from Crypto.Random.Fortuna import FortunaAccumulator + +class _EntropySource(object): + def __init__(self, accumulator, src_num): + self._fortuna = accumulator + self._src_num = src_num + self._pool_num = 0 + + def feed(self, data): + self._fortuna.add_random_event(self._src_num, self._pool_num, data) + self._pool_num = (self._pool_num + 1) & 31 + +class _EntropyCollector(object): + + def __init__(self, accumulator): + self._osrng = OSRNG.new() + self._osrng_es = _EntropySource(accumulator, 255) + self._time_es = _EntropySource(accumulator, 254) + self._clock_es = _EntropySource(accumulator, 253) + + def reinit(self): + # Add 256 bits to each of the 32 pools, twice. (For a total of 16384 + # bits collected from the operating system.) + for i in range(2): + block = self._osrng.read(32*32) + for p in range(32): + self._osrng_es.feed(block[p*32:(p+1)*32]) + block = None + self._osrng.flush() + + def collect(self): + # Collect 64 bits of entropy from the operating system and feed it to Fortuna. + self._osrng_es.feed(self._osrng.read(8)) + + # Add the fractional part of time.time() + t = time.time() + self._time_es.feed(struct.pack("@I", int(2**30 * (t - floor(t))))) + + # Add the fractional part of time.clock() + t = time.clock() + self._clock_es.feed(struct.pack("@I", int(2**30 * (t - floor(t))))) + + +class _UserFriendlyRNG(object): + + def __init__(self): + self.closed = False + self._fa = FortunaAccumulator.FortunaAccumulator() + self._ec = _EntropyCollector(self._fa) + self.reinit() + + def reinit(self): + """Initialize the random number generator and seed it with entropy from + the operating system. + """ + + # Save the pid (helps ensure that Crypto.Random.atfork() gets called) + self._pid = os.getpid() + + # Collect entropy from the operating system and feed it to + # FortunaAccumulator + self._ec.reinit() + + # Override FortunaAccumulator's 100ms minimum re-seed interval. This + # is necessary to avoid a race condition between this function and + # self.read(), which that can otherwise cause forked child processes to + # produce identical output. (e.g. CVE-2013-1445) + # + # Note that if this function can be called frequently by an attacker, + # (and if the bits from OSRNG are insufficiently random) it will weaken + # Fortuna's ability to resist a state compromise extension attack. + self._fa._forget_last_reseed() + + def close(self): + self.closed = True + self._osrng = None + self._fa = None + + def flush(self): + pass + + def read(self, N): + """Return N bytes from the RNG.""" + if self.closed: + raise ValueError("I/O operation on closed file") + if not isinstance(N, (long, int)): + raise TypeError("an integer is required") + if N < 0: + raise ValueError("cannot read to end of infinite stream") + + # Collect some entropy and feed it to Fortuna + self._ec.collect() + + # Ask Fortuna to generate some bytes + retval = self._fa.random_data(N) + + # Check that we haven't forked in the meantime. (If we have, we don't + # want to use the data, because it might have been duplicated in the + # parent process. + self._check_pid() + + # Return the random data. + return retval + + def _check_pid(self): + # Lame fork detection to remind developers to invoke Random.atfork() + # after every call to os.fork(). Note that this check is not reliable, + # since process IDs can be reused on most operating systems. + # + # You need to do Random.atfork() in the child process after every call + # to os.fork() to avoid reusing PRNG state. If you want to avoid + # leaking PRNG state to child processes (for example, if you are using + # os.setuid()) then you should also invoke Random.atfork() in the + # *parent* process. + if os.getpid() != self._pid: + raise AssertionError("PID check failed. RNG must be re-initialized after fork(). Hint: Try Random.atfork()") + + +class _LockingUserFriendlyRNG(_UserFriendlyRNG): + def __init__(self): + self._lock = threading.Lock() + _UserFriendlyRNG.__init__(self) + + def close(self): + self._lock.acquire() + try: + return _UserFriendlyRNG.close(self) + finally: + self._lock.release() + + def reinit(self): + self._lock.acquire() + try: + return _UserFriendlyRNG.reinit(self) + finally: + self._lock.release() + + def read(self, bytes): + self._lock.acquire() + try: + return _UserFriendlyRNG.read(self, bytes) + finally: + self._lock.release() + +class RNGFile(object): + def __init__(self, singleton): + self.closed = False + self._singleton = singleton + + # PEP 343: Support for the "with" statement + def __enter__(self): + """PEP 343 support""" + def __exit__(self): + """PEP 343 support""" + self.close() + + def close(self): + # Don't actually close the singleton, just close this RNGFile instance. + self.closed = True + self._singleton = None + + def read(self, bytes): + if self.closed: + raise ValueError("I/O operation on closed file") + return self._singleton.read(bytes) + + def flush(self): + if self.closed: + raise ValueError("I/O operation on closed file") + +_singleton_lock = threading.Lock() +_singleton = None +def _get_singleton(): + global _singleton + _singleton_lock.acquire() + try: + if _singleton is None: + _singleton = _LockingUserFriendlyRNG() + return _singleton + finally: + _singleton_lock.release() + +def new(): + return RNGFile(_get_singleton()) + +def reinit(): + _get_singleton().reinit() + +def get_random_bytes(n): + """Return the specified number of cryptographically-strong random bytes.""" + return _get_singleton().read(n) + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/Random/_UserFriendlyRNG.pyo b/panda/python/Lib/site-packages/Crypto/Random/_UserFriendlyRNG.pyo new file mode 100644 index 0000000000000000000000000000000000000000..93547a1adc63bf3cf92f3d0c9e7c414849caa740 GIT binary patch literal 8746 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 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Random/__init__.py b/panda/python/Lib/site-packages/Crypto/Random/__init__.py new file mode 100644 index 00000000..659ffee4 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Random/__init__.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# +# Random/__init__.py : PyCrypto random number generation +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +__revision__ = "$Id$" +__all__ = ['new'] + +from Crypto.Random import OSRNG +from Crypto.Random import _UserFriendlyRNG + +def new(*args, **kwargs): + """Return a file-like object that outputs cryptographically random bytes.""" + return _UserFriendlyRNG.new(*args, **kwargs) + +def atfork(): + """Call this whenever you call os.fork()""" + _UserFriendlyRNG.reinit() + +def get_random_bytes(n): + """Return the specified number of cryptographically-strong random bytes.""" + return _UserFriendlyRNG.get_random_bytes(n) + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/Random/__init__.pyo b/panda/python/Lib/site-packages/Crypto/Random/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..f4032b8f6356c40f42917d10e4291f3cc9f5664c GIT binary patch literal 1099 zcmb_aL5tHs6n;t5b}O#*>d66DjE4rrld_0VT@j>}6c3ibkS5b~wrM8JOtu8}wx0b- z{wVzc`rf42gLrFTUcQ%^yzhPUz22|$dq2Pam}hW!e0;yfWo8(1fF(u`3J;bZ?PU2uD;mz;N*~zpy<7mDtPQ_=FxN zwvS=Hh-V+Vbc`wgVuZfZQdD`_;*RT+dZfSSxD1`L0M{Pe0^EA=9gvC2nJWyju#K)* z%GR$x{S!Oq>Wva1tV-3r6TU%A=wBE=pEz6eaw93_vty(Kg6cS_X0s?TU zB_XLUj2$4@?g@r&mx7sMn7&RvW0~~jyUB~_RrEZmTf0$J@=2}|BdwU!X|_!ZVUnri zPhv-!a4supIgjc#recq%AhCn*^b;b5#9KwseSMNxav-CZF zK3Hluf|*)maxF#9s%E!Bb!z>ul@nvNs*3+PYH5H9VR`2`caC=hNR-v_B2IM&@eu1i z#dT0W3(qjI_c3s;#f>ylRh(No#yNV0nC_z+lBgS!n3_9|WK2Wo3LpDDt#Q=j;14O80|x*A literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Random/random.py b/panda/python/Lib/site-packages/Crypto/Random/random.py new file mode 100644 index 00000000..bef02e65 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Random/random.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- +# +# Random/random.py : Strong alternative for the standard 'random' module +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""A cryptographically strong version of Python's standard "random" module.""" + +__revision__ = "$Id$" +__all__ = ['StrongRandom', 'getrandbits', 'randrange', 'randint', 'choice', 'shuffle', 'sample'] + +from Crypto import Random +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * + +class StrongRandom(object): + def __init__(self, rng=None, randfunc=None): + if randfunc is None and rng is None: + self._randfunc = None + elif randfunc is not None and rng is None: + self._randfunc = randfunc + elif randfunc is None and rng is not None: + self._randfunc = rng.read + else: + raise ValueError("Cannot specify both 'rng' and 'randfunc'") + + def getrandbits(self, k): + """Return a python long integer with k random bits.""" + if self._randfunc is None: + self._randfunc = Random.new().read + mask = (1L << k) - 1 + return mask & bytes_to_long(self._randfunc(ceil_div(k, 8))) + + def randrange(self, *args): + """randrange([start,] stop[, step]): + Return a randomly-selected element from range(start, stop, step).""" + if len(args) == 3: + (start, stop, step) = args + elif len(args) == 2: + (start, stop) = args + step = 1 + elif len(args) == 1: + (stop,) = args + start = 0 + step = 1 + else: + raise TypeError("randrange expected at most 3 arguments, got %d" % (len(args),)) + if (not isinstance(start, (int, long)) + or not isinstance(stop, (int, long)) + or not isinstance(step, (int, long))): + raise TypeError("randrange requires integer arguments") + if step == 0: + raise ValueError("randrange step argument must not be zero") + + num_choices = ceil_div(stop - start, step) + if num_choices < 0: + num_choices = 0 + if num_choices < 1: + raise ValueError("empty range for randrange(%r, %r, %r)" % (start, stop, step)) + + # Pick a random number in the range of possible numbers + r = num_choices + while r >= num_choices: + r = self.getrandbits(size(num_choices)) + + return start + (step * r) + + def randint(self, a, b): + """Return a random integer N such that a <= N <= b.""" + if not isinstance(a, (int, long)) or not isinstance(b, (int, long)): + raise TypeError("randint requires integer arguments") + N = self.randrange(a, b+1) + assert a <= N <= b + return N + + def choice(self, seq): + """Return a random element from a (non-empty) sequence. + + If the seqence is empty, raises IndexError. + """ + if len(seq) == 0: + raise IndexError("empty sequence") + return seq[self.randrange(len(seq))] + + def shuffle(self, x): + """Shuffle the sequence in place.""" + # Make a (copy) of the list of objects we want to shuffle + items = list(x) + + # Choose a random item (without replacement) until all the items have been + # chosen. + for i in xrange(len(x)): + x[i] = items.pop(self.randrange(len(items))) + + def sample(self, population, k): + """Return a k-length list of unique elements chosen from the population sequence.""" + + num_choices = len(population) + if k > num_choices: + raise ValueError("sample larger than population") + + retval = [] + selected = {} # we emulate a set using a dict here + for i in xrange(k): + r = None + while r is None or selected.has_key(r): + r = self.randrange(num_choices) + retval.append(population[r]) + selected[r] = 1 + return retval + +_r = StrongRandom() +getrandbits = _r.getrandbits +randrange = _r.randrange +randint = _r.randint +choice = _r.choice +shuffle = _r.shuffle +sample = _r.sample + +# These are at the bottom to avoid problems with recursive imports +from Crypto.Util.number import ceil_div, bytes_to_long, long_to_bytes, size + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/Random/random.pyo b/panda/python/Lib/site-packages/Crypto/Random/random.pyo new file mode 100644 index 0000000000000000000000000000000000000000..5877e8b5caaa6cec12c218b6f7dd660d6d6a1d1e GIT binary patch literal 4585 zcmb_fZF3_>5$;_{wq?sNXW#kG1j5AJVI5_wk{nb)FsTbZid+CCwN5Z7x?0xSk-XMw zSKb-qSzC5p=wS14Yfc#+~I>Mc?W^eV;6l$K~vrdF9e{$8Q9Lahqv z3Y~+yMmzB;^?fQXr=&HI)+Qugu}H6Ci(#v$d zLah}+YSgL;vP!L0LDs0XCdfLq)&<$1)`pz%4yAW!ut}{=8f;N(iw1Y8b(aSBsC5sg zUZLaqCSUzyfR9wC7!PgUE2809(uvY^tc)%4tfww@VUj#kc~^Zlwr6>^XD}6Iaa6== zw*Zn4cGVz{N2zX@GK4*R9zV1-Ajcvh5Ei=vLQh*>aGF?StN7**43OCn{FP+ZE&%VG z>-<0?ac*@N)_M@4(OZfUFhWQ*Pi9(OElPOP?ijQyb0QaXnPo_MOlTUfTFZlV4twvTZ@wG>Pk-d)V ze3+)G^O2$~%dIj)-ATG*b(-5VwO3@lJp~N{1MH5n&R)F?X3Lv z7l_RLt2f{v z3HVbKn(3DThmljJeFnm#VUiy^l#e$0gG>77(O@o z>)t(Y&Fe6g&&(?MHHLW&iiOriSI{dbMu~-XiJ;q8fMv?gZ}9lS^BZ2$27~ZG;mme) zgRLZNBVqGc4onK>3Fi*qAHh1?8cBBB1qLk67A>*Ic40-IYUc06RFJ-fT7HvS{6j=9 zuTx6C=$ofy$W)mlXP9 zloZ;`B5SrlGToe!?=zF81|vx49C)hLSGvf}BS_VQp&h#msBT^`<_=bWRO~A^9*gcI z3R4`575Vvi=u)3#!o(yQmqipUxiIP&Cr}Q~fNNo}#ehS@CCTI~?c!YGlv!~D1G~dQ zY!Sx=n@kWrlnR=S2BE8sMuNMz^_b>_`4c|H`v6qh^!T^tRROEsf>-r-ylwei2X)=w zlDV4q-O_@$?(O(e1Nk~Ujxfv@04@Y^VuaW<-u8uxD7;B6e$J7G95D+Y_G~yXvM~bN zr~4d12#ONg7gqF}IhRcbXPlnX+eatVkXHLNytjHq0(oGA|g_|8^zUN3cnP z2Ml%?e22k(2COM5mGfL1iBV1kHgDZDeBTp{NxI#K!na+8eVD+L7~tr)IUwk(D=?orv)T@Bk2(H8+Y@cVbzLLhFF5jhp>>e)8mii_fWsj~pz-C02VL0{au-dVFD zhT$fHDx1)IXR2}bjw7D?6kw)H6rrobiD$dA2kkz4Q5V;hZo|2?t3#M`f9&NYI=uKk zoxpCcbu({6@UiQGr#cmF!^_n$jiC0XbRRC?B*rz+S8(s14n%9Lmtj8qHix~EjDv1# z;POdw>&jyVonbiTm1^Z3PjbW(Xfv1n8$RaBlWGY?^vhK2iR0eL2R-680KS5%dDWGg zEpGkn#UHrlaqVBEs|H=8QHO{nGUr?rIfqD5F0RG#QH0UJp-e8)#iw+F8i|J+>wl4U zK=zPounJ#?7f)sSSVG-2anf06^bb%BdT8lVsGVO(qbxxvOk>3;q-vuxS0OnbV1-c{ zS$wB=z9Pa?!x=(N%agH&ZR;g5zO0t0JvW4+B z;2rdl%{rfW(&T5+K!>5ke;B&QW*EBmcmrHgSmo{kJA1&66-eUdt>)(!>~>xs{Ena> zV92Wj#c#Q~Slz8IRjbuyR~4kTmz4itc3gTlz1HYTs}G literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/__init__.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/__init__.py new file mode 100644 index 00000000..63e9c570 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/__init__.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Cipher/__init__.py: Self-test for cipher modules +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test for cipher modules""" + +__revision__ = "$Id$" + +def get_tests(config={}): + tests = [] + from Crypto.SelfTest.Cipher import test_AES; tests += test_AES.get_tests(config=config) + from Crypto.SelfTest.Cipher import test_ARC2; tests += test_ARC2.get_tests(config=config) + from Crypto.SelfTest.Cipher import test_ARC4; tests += test_ARC4.get_tests(config=config) + from Crypto.SelfTest.Cipher import test_Blowfish; tests += test_Blowfish.get_tests(config=config) + from Crypto.SelfTest.Cipher import test_CAST; tests += test_CAST.get_tests(config=config) + from Crypto.SelfTest.Cipher import test_DES3; tests += test_DES3.get_tests(config=config) + from Crypto.SelfTest.Cipher import test_DES; tests += test_DES.get_tests(config=config) + from Crypto.SelfTest.Cipher import test_XOR; tests += test_XOR.get_tests(config=config) + from Crypto.SelfTest.Cipher import test_pkcs1_15; tests += test_pkcs1_15.get_tests(config=config) + from Crypto.SelfTest.Cipher import test_pkcs1_oaep; tests += test_pkcs1_oaep.get_tests(config=config) + return tests + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/__init__.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..a12945b97324456f7c14fc708a6435e3e3177ac3 GIT binary patch literal 1552 zcmcJP-)q!B5XWcp>wZ=XLP1dILm%?s9o8zMNU>h~Ae6Rj`k*DSq)F~BZ7vD7drF~s zYVptVkJ3LtXLkDo+B_&|V87W+K07-zJBj^ssr%#e_x%{IE*tOfamWLd1mFmj!4ZQD zCl*}d+=A4G#D-G~=DUzMkhqXLaD)>NE^&zqsRJh-BrQnVZ~=@JxY&ij?~vywC_$Q! z2P&0nbzII@%J2Z6PZ$y&^C(#JuD5f1qcEfav6QBW984lrX-Tfoj4 zoLg{WQDEmlo4&rH98K9!+lI0mDNF%!UP(8d75&eb`9k=QY}q+PT0S3b;nShMyjW&F4SE^bsMR^rg~8K4Ar|wVXXsy3D09M z`-PWJ$E4aMc%WiyCr}0oWS3Cp%p%f+(j9^ z4G*Fsi8i(e>%%w0=V5iGrezWCX2+q-R63}l_%xcNGBinr*GYvYsZfZl$dnMn>WotX zo|5NhD8M|n3@d*$bSDTgi?Ra!QG@K={9UL-`a@pEi2^ubpe+1Y;euL<%CYBD1+|X_ z#zKYBWv1E(3rs=>rgOfPf1bVG|6LxUEpZ|2b5Xmif(YKE_QYh3Q$I M)ql`ueb!;W0ZkV)v;Y7A literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/common.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/common.py new file mode 100644 index 00000000..8bebed9c --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/common.py @@ -0,0 +1,399 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Hash/common.py: Common code for Crypto.SelfTest.Hash +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-testing for PyCrypto hash modules""" + +__revision__ = "$Id$" + +import sys +import unittest +from binascii import a2b_hex, b2a_hex +from Crypto.Util.py3compat import * + +# For compatibility with Python 2.1 and Python 2.2 +if sys.hexversion < 0x02030000: + # Python 2.1 doesn't have a dict() function + # Python 2.2 dict() function raises TypeError if you do dict(MD5='blah') + def dict(**kwargs): + return kwargs.copy() +else: + dict = dict + +class _NoDefault: pass # sentinel object +def _extract(d, k, default=_NoDefault): + """Get an item from a dictionary, and remove it from the dictionary.""" + try: + retval = d[k] + except KeyError: + if default is _NoDefault: + raise + return default + del d[k] + return retval + +# Generic cipher test case +class CipherSelfTest(unittest.TestCase): + + def __init__(self, module, params): + unittest.TestCase.__init__(self) + self.module = module + + # Extract the parameters + params = params.copy() + self.description = _extract(params, 'description') + self.key = b(_extract(params, 'key')) + self.plaintext = b(_extract(params, 'plaintext')) + self.ciphertext = b(_extract(params, 'ciphertext')) + self.module_name = _extract(params, 'module_name', None) + + mode = _extract(params, 'mode', None) + self.mode_name = str(mode) + if mode is not None: + # Block cipher + self.mode = getattr(self.module, "MODE_" + mode) + self.iv = _extract(params, 'iv', None) + if self.iv is not None: self.iv = b(self.iv) + + # Only relevant for OPENPGP mode + self.encrypted_iv = _extract(params, 'encrypted_iv', None) + if self.encrypted_iv is not None: + self.encrypted_iv = b(self.encrypted_iv) + else: + # Stream cipher + self.mode = None + self.iv = None + + self.extra_params = params + + def shortDescription(self): + return self.description + + def _new(self, do_decryption=0): + params = self.extra_params.copy() + + # Handle CTR mode parameters. By default, we use Counter.new(self.module.block_size) + if hasattr(self.module, "MODE_CTR") and self.mode == self.module.MODE_CTR: + from Crypto.Util import Counter + ctr_class = _extract(params, 'ctr_class', Counter.new) + ctr_params = _extract(params, 'ctr_params', {}).copy() + if ctr_params.has_key('prefix'): ctr_params['prefix'] = a2b_hex(b(ctr_params['prefix'])) + if ctr_params.has_key('suffix'): ctr_params['suffix'] = a2b_hex(b(ctr_params['suffix'])) + if not ctr_params.has_key('nbits'): + ctr_params['nbits'] = 8*(self.module.block_size - len(ctr_params.get('prefix', '')) - len(ctr_params.get('suffix', ''))) + params['counter'] = ctr_class(**ctr_params) + + if self.mode is None: + # Stream cipher + return self.module.new(a2b_hex(self.key), **params) + elif self.iv is None: + # Block cipher without iv + return self.module.new(a2b_hex(self.key), self.mode, **params) + else: + # Block cipher with iv + if do_decryption and self.mode == self.module.MODE_OPENPGP: + # In PGP mode, the IV to feed for decryption is the *encrypted* one + return self.module.new(a2b_hex(self.key), self.mode, a2b_hex(self.encrypted_iv), **params) + else: + return self.module.new(a2b_hex(self.key), self.mode, a2b_hex(self.iv), **params) + + def runTest(self): + plaintext = a2b_hex(self.plaintext) + ciphertext = a2b_hex(self.ciphertext) + + ct1 = b2a_hex(self._new().encrypt(plaintext)) + pt1 = b2a_hex(self._new(1).decrypt(ciphertext)) + ct2 = b2a_hex(self._new().encrypt(plaintext)) + pt2 = b2a_hex(self._new(1).decrypt(ciphertext)) + + if hasattr(self.module, "MODE_OPENPGP") and self.mode == self.module.MODE_OPENPGP: + # In PGP mode, data returned by the first encrypt() + # is prefixed with the encrypted IV. + # Here we check it and then remove it from the ciphertexts. + eilen = len(self.encrypted_iv) + self.assertEqual(self.encrypted_iv, ct1[:eilen]) + self.assertEqual(self.encrypted_iv, ct2[:eilen]) + ct1 = ct1[eilen:] + ct2 = ct2[eilen:] + + self.assertEqual(self.ciphertext, ct1) # encrypt + self.assertEqual(self.ciphertext, ct2) # encrypt (second time) + self.assertEqual(self.plaintext, pt1) # decrypt + self.assertEqual(self.plaintext, pt2) # decrypt (second time) + +class CipherStreamingSelfTest(CipherSelfTest): + + def shortDescription(self): + desc = self.module_name + if self.mode is not None: + desc += " in %s mode" % (self.mode_name,) + return "%s should behave like a stream cipher" % (desc,) + + def runTest(self): + plaintext = a2b_hex(self.plaintext) + ciphertext = a2b_hex(self.ciphertext) + + # The cipher should work like a stream cipher + + # Test counter mode encryption, 3 bytes at a time + ct3 = [] + cipher = self._new() + for i in range(0, len(plaintext), 3): + ct3.append(cipher.encrypt(plaintext[i:i+3])) + ct3 = b2a_hex(b("").join(ct3)) + self.assertEqual(self.ciphertext, ct3) # encryption (3 bytes at a time) + + # Test counter mode decryption, 3 bytes at a time + pt3 = [] + cipher = self._new() + for i in range(0, len(ciphertext), 3): + pt3.append(cipher.encrypt(ciphertext[i:i+3])) + # PY3K: This is meant to be text, do not change to bytes (data) + pt3 = b2a_hex(b("").join(pt3)) + self.assertEqual(self.plaintext, pt3) # decryption (3 bytes at a time) + +class CTRSegfaultTest(unittest.TestCase): + + def __init__(self, module, params): + unittest.TestCase.__init__(self) + self.module = module + self.key = b(params['key']) + self.module_name = params.get('module_name', None) + + def shortDescription(self): + return """Regression test: %s.new(key, %s.MODE_CTR) should raise TypeError, not segfault""" % (self.module_name, self.module_name) + + def runTest(self): + self.assertRaises(TypeError, self.module.new, a2b_hex(self.key), self.module.MODE_CTR) + +class CTRWraparoundTest(unittest.TestCase): + + def __init__(self, module, params): + unittest.TestCase.__init__(self) + self.module = module + self.key = b(params['key']) + self.module_name = params.get('module_name', None) + + def shortDescription(self): + return """Regression test: %s with MODE_CTR should raise OverflowError on wraparound when shortcut used""" % (self.module_name,) + + def runTest(self): + from Crypto.Util import Counter + + for disable_shortcut in (0, 1): # (False, True) Test CTR-mode shortcut and PyObject_CallObject code paths + for little_endian in (0, 1): # (False, True) Test both endiannesses + ctr = Counter.new(8*self.module.block_size, initial_value=2L**(8*self.module.block_size)-1, little_endian=little_endian, disable_shortcut=disable_shortcut) + cipher = self.module.new(a2b_hex(self.key), self.module.MODE_CTR, counter=ctr) + block = b("\x00") * self.module.block_size + cipher.encrypt(block) + self.assertRaises(OverflowError, cipher.encrypt, block) + +class CFBSegmentSizeTest(unittest.TestCase): + + def __init__(self, module, params): + unittest.TestCase.__init__(self) + self.module = module + self.key = b(params['key']) + self.description = params['description'] + + def shortDescription(self): + return self.description + + def runTest(self): + """Regression test: m.new(key, m.MODE_CFB, segment_size=N) should require segment_size to be a multiple of 8 bits""" + for i in range(1, 8): + self.assertRaises(ValueError, self.module.new, a2b_hex(self.key), self.module.MODE_CFB, segment_size=i) + self.module.new(a2b_hex(self.key), self.module.MODE_CFB, "\0"*self.module.block_size, segment_size=8) # should succeed + +class RoundtripTest(unittest.TestCase): + def __init__(self, module, params): + from Crypto import Random + unittest.TestCase.__init__(self) + self.module = module + self.iv = Random.get_random_bytes(module.block_size) + self.key = b(params['key']) + self.plaintext = 100 * b(params['plaintext']) + self.module_name = params.get('module_name', None) + + def shortDescription(self): + return """%s .decrypt() output of .encrypt() should not be garbled""" % (self.module_name,) + + def runTest(self): + for mode in (self.module.MODE_ECB, self.module.MODE_CBC, self.module.MODE_CFB, self.module.MODE_OFB, self.module.MODE_OPENPGP): + encryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv) + ciphertext = encryption_cipher.encrypt(self.plaintext) + + if mode != self.module.MODE_OPENPGP: + decryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv) + else: + eiv = ciphertext[:self.module.block_size+2] + ciphertext = ciphertext[self.module.block_size+2:] + decryption_cipher = self.module.new(a2b_hex(self.key), mode, eiv) + decrypted_plaintext = decryption_cipher.decrypt(ciphertext) + self.assertEqual(self.plaintext, decrypted_plaintext) + +class PGPTest(unittest.TestCase): + def __init__(self, module, params): + unittest.TestCase.__init__(self) + self.module = module + self.key = b(params['key']) + + def shortDescription(self): + return "MODE_PGP was implemented incorrectly and insecurely. It's completely banished now." + + def runTest(self): + self.assertRaises(ValueError, self.module.new, a2b_hex(self.key), + self.module.MODE_PGP) + +class IVLengthTest(unittest.TestCase): + def __init__(self, module, params): + unittest.TestCase.__init__(self) + self.module = module + self.key = b(params['key']) + + def shortDescription(self): + return "Check that all modes except MODE_ECB and MODE_CTR require an IV of the proper length" + + def runTest(self): + self.assertRaises(ValueError, self.module.new, a2b_hex(self.key), + self.module.MODE_CBC, "") + self.assertRaises(ValueError, self.module.new, a2b_hex(self.key), + self.module.MODE_CFB, "") + self.assertRaises(ValueError, self.module.new, a2b_hex(self.key), + self.module.MODE_OFB, "") + self.assertRaises(ValueError, self.module.new, a2b_hex(self.key), + self.module.MODE_OPENPGP, "") + self.module.new(a2b_hex(self.key), self.module.MODE_ECB, "") + self.module.new(a2b_hex(self.key), self.module.MODE_CTR, "", counter=self._dummy_counter) + + def _dummy_counter(self): + return "\0" * self.module.block_size + +def make_block_tests(module, module_name, test_data): + tests = [] + extra_tests_added = 0 + for i in range(len(test_data)): + row = test_data[i] + + # Build the "params" dictionary + params = {'mode': 'ECB'} + if len(row) == 3: + (params['plaintext'], params['ciphertext'], params['key']) = row + elif len(row) == 4: + (params['plaintext'], params['ciphertext'], params['key'], params['description']) = row + elif len(row) == 5: + (params['plaintext'], params['ciphertext'], params['key'], params['description'], extra_params) = row + params.update(extra_params) + else: + raise AssertionError("Unsupported tuple size %d" % (len(row),)) + + # Build the display-name for the test + p2 = params.copy() + p_key = _extract(p2, 'key') + p_plaintext = _extract(p2, 'plaintext') + p_ciphertext = _extract(p2, 'ciphertext') + p_description = _extract(p2, 'description', None) + p_mode = p2.get('mode', 'ECB') + if p_mode == 'ECB': + _extract(p2, 'mode', 'ECB') + + if p_description is not None: + description = p_description + elif p_mode == 'ECB' and not p2: + description = "p=%s, k=%s" % (p_plaintext, p_key) + else: + description = "p=%s, k=%s, %r" % (p_plaintext, p_key, p2) + name = "%s #%d: %s" % (module_name, i+1, description) + params['description'] = name + params['module_name'] = module_name + + # Add extra test(s) to the test suite before the current test + if not extra_tests_added: + tests += [ + CTRSegfaultTest(module, params), + CTRWraparoundTest(module, params), + CFBSegmentSizeTest(module, params), + RoundtripTest(module, params), + PGPTest(module, params), + IVLengthTest(module, params), + ] + extra_tests_added = 1 + + # Add the current test to the test suite + tests.append(CipherSelfTest(module, params)) + + # When using CTR mode, test that the interface behaves like a stream cipher + if p_mode == 'CTR': + tests.append(CipherStreamingSelfTest(module, params)) + + # When using CTR mode, test the non-shortcut code path. + if p_mode == 'CTR' and not params.has_key('ctr_class'): + params2 = params.copy() + params2['description'] += " (shortcut disabled)" + ctr_params2 = params.get('ctr_params', {}).copy() + params2['ctr_params'] = ctr_params2 + if not params2['ctr_params'].has_key('disable_shortcut'): + params2['ctr_params']['disable_shortcut'] = 1 + tests.append(CipherSelfTest(module, params2)) + return tests + +def make_stream_tests(module, module_name, test_data): + tests = [] + for i in range(len(test_data)): + row = test_data[i] + + # Build the "params" dictionary + params = {} + if len(row) == 3: + (params['plaintext'], params['ciphertext'], params['key']) = row + elif len(row) == 4: + (params['plaintext'], params['ciphertext'], params['key'], params['description']) = row + elif len(row) == 5: + (params['plaintext'], params['ciphertext'], params['key'], params['description'], extra_params) = row + params.update(extra_params) + else: + raise AssertionError("Unsupported tuple size %d" % (len(row),)) + + # Build the display-name for the test + p2 = params.copy() + p_key = _extract(p2, 'key') + p_plaintext = _extract(p2, 'plaintext') + p_ciphertext = _extract(p2, 'ciphertext') + p_description = _extract(p2, 'description', None) + + if p_description is not None: + description = p_description + elif not p2: + description = "p=%s, k=%s" % (p_plaintext, p_key) + else: + description = "p=%s, k=%s, %r" % (p_plaintext, p_key, p2) + name = "%s #%d: %s" % (module_name, i+1, description) + params['description'] = name + params['module_name'] = module_name + + # Add the test to the test suite + tests.append(CipherSelfTest(module, params)) + tests.append(CipherStreamingSelfTest(module, params)) + return tests + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/common.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/common.pyo new file mode 100644 index 0000000000000000000000000000000000000000..86d89065304269f3105b9701206ced9b1a5110e4 GIT binary patch literal 15675 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 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_AES.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_AES.py new file mode 100644 index 00000000..ea7c323a --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_AES.py @@ -0,0 +1,1433 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Cipher/AES.py: Self-test for the AES cipher +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Cipher.AES""" + +__revision__ = "$Id$" + +from common import dict # For compatibility with Python 2.1 and 2.2 +from Crypto.Util.py3compat import * +from binascii import hexlify + +# This is a list of (plaintext, ciphertext, key[, description[, params]]) tuples. +test_data = [ + # FIPS PUB 197 test vectors + # http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf + + ('00112233445566778899aabbccddeeff', '69c4e0d86a7b0430d8cdb78070b4c55a', + '000102030405060708090a0b0c0d0e0f', 'FIPS 197 C.1 (AES-128)'), + + ('00112233445566778899aabbccddeeff', 'dda97ca4864cdfe06eaf70a0ec0d7191', + '000102030405060708090a0b0c0d0e0f1011121314151617', + 'FIPS 197 C.2 (AES-192)'), + + ('00112233445566778899aabbccddeeff', '8ea2b7ca516745bfeafc49904b496089', + '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', + 'FIPS 197 C.3 (AES-256)'), + + # Rijndael128 test vectors + # Downloaded 2008-09-13 from + # http://www.iaik.tugraz.at/Research/krypto/AES/old/~rijmen/rijndael/testvalues.tar.gz + + # ecb_tbl.txt, KEYSIZE=128 + ('506812a45f08c889b97f5980038b8359', 'd8f532538289ef7d06b506a4fd5be9c9', + '00010203050607080a0b0c0d0f101112', + 'ecb-tbl-128: I=1'), + ('5c6d71ca30de8b8b00549984d2ec7d4b', '59ab30f4d4ee6e4ff9907ef65b1fb68c', + '14151617191a1b1c1e1f202123242526', + 'ecb-tbl-128: I=2'), + ('53f3f4c64f8616e4e7c56199f48f21f6', 'bf1ed2fcb2af3fd41443b56d85025cb1', + '28292a2b2d2e2f30323334353738393a', + 'ecb-tbl-128: I=3'), + ('a1eb65a3487165fb0f1c27ff9959f703', '7316632d5c32233edcb0780560eae8b2', + '3c3d3e3f41424344464748494b4c4d4e', + 'ecb-tbl-128: I=4'), + ('3553ecf0b1739558b08e350a98a39bfa', '408c073e3e2538072b72625e68b8364b', + '50515253555657585a5b5c5d5f606162', + 'ecb-tbl-128: I=5'), + ('67429969490b9711ae2b01dc497afde8', 'e1f94dfa776597beaca262f2f6366fea', + '64656667696a6b6c6e6f707173747576', + 'ecb-tbl-128: I=6'), + ('93385c1f2aec8bed192f5a8e161dd508', 'f29e986c6a1c27d7b29ffd7ee92b75f1', + '78797a7b7d7e7f80828384858788898a', + 'ecb-tbl-128: I=7'), + ('b5bf946be19beb8db3983b5f4c6e8ddb', '131c886a57f8c2e713aba6955e2b55b5', + '8c8d8e8f91929394969798999b9c9d9e', + 'ecb-tbl-128: I=8'), + ('41321ee10e21bd907227c4450ff42324', 'd2ab7662df9b8c740210e5eeb61c199d', + 'a0a1a2a3a5a6a7a8aaabacadafb0b1b2', + 'ecb-tbl-128: I=9'), + ('00a82f59c91c8486d12c0a80124f6089', '14c10554b2859c484cab5869bbe7c470', + 'b4b5b6b7b9babbbcbebfc0c1c3c4c5c6', + 'ecb-tbl-128: I=10'), + ('7ce0fd076754691b4bbd9faf8a1372fe', 'db4d498f0a49cf55445d502c1f9ab3b5', + 'c8c9cacbcdcecfd0d2d3d4d5d7d8d9da', + 'ecb-tbl-128: I=11'), + ('23605a8243d07764541bc5ad355b3129', '6d96fef7d66590a77a77bb2056667f7f', + 'dcdddedfe1e2e3e4e6e7e8e9ebecedee', + 'ecb-tbl-128: I=12'), + ('12a8cfa23ea764fd876232b4e842bc44', '316fb68edba736c53e78477bf913725c', + 'f0f1f2f3f5f6f7f8fafbfcfdfe010002', + 'ecb-tbl-128: I=13'), + ('bcaf32415e8308b3723e5fdd853ccc80', '6936f2b93af8397fd3a771fc011c8c37', + '04050607090a0b0c0e0f101113141516', + 'ecb-tbl-128: I=14'), + ('89afae685d801ad747ace91fc49adde0', 'f3f92f7a9c59179c1fcc2c2ba0b082cd', + '2c2d2e2f31323334363738393b3c3d3e', + 'ecb-tbl-128: I=15'), + ('f521d07b484357c4a69e76124a634216', '6a95ea659ee3889158e7a9152ff04ebc', + '40414243454647484a4b4c4d4f505152', + 'ecb-tbl-128: I=16'), + ('3e23b3bc065bcc152407e23896d77783', '1959338344e945670678a5d432c90b93', + '54555657595a5b5c5e5f606163646566', + 'ecb-tbl-128: I=17'), + ('79f0fba002be1744670e7e99290d8f52', 'e49bddd2369b83ee66e6c75a1161b394', + '68696a6b6d6e6f70727374757778797a', + 'ecb-tbl-128: I=18'), + ('da23fe9d5bd63e1d72e3dafbe21a6c2a', 'd3388f19057ff704b70784164a74867d', + '7c7d7e7f81828384868788898b8c8d8e', + 'ecb-tbl-128: I=19'), + ('e3f5698ba90b6a022efd7db2c7e6c823', '23aa03e2d5e4cd24f3217e596480d1e1', + 'a4a5a6a7a9aaabacaeafb0b1b3b4b5b6', + 'ecb-tbl-128: I=20'), + ('bdc2691d4f1b73d2700679c3bcbf9c6e', 'c84113d68b666ab2a50a8bdb222e91b9', + 'e0e1e2e3e5e6e7e8eaebecedeff0f1f2', + 'ecb-tbl-128: I=21'), + ('ba74e02093217ee1ba1b42bd5624349a', 'ac02403981cd4340b507963db65cb7b6', + '08090a0b0d0e0f10121314151718191a', + 'ecb-tbl-128: I=22'), + ('b5c593b5851c57fbf8b3f57715e8f680', '8d1299236223359474011f6bf5088414', + '6c6d6e6f71727374767778797b7c7d7e', + 'ecb-tbl-128: I=23'), + ('3da9bd9cec072381788f9387c3bbf4ee', '5a1d6ab8605505f7977e55b9a54d9b90', + '80818283858687888a8b8c8d8f909192', + 'ecb-tbl-128: I=24'), + ('4197f3051121702ab65d316b3c637374', '72e9c2d519cf555e4208805aabe3b258', + '94959697999a9b9c9e9fa0a1a3a4a5a6', + 'ecb-tbl-128: I=25'), + ('9f46c62ec4f6ee3f6e8c62554bc48ab7', 'a8f3e81c4a23a39ef4d745dffe026e80', + 'a8a9aaabadaeafb0b2b3b4b5b7b8b9ba', + 'ecb-tbl-128: I=26'), + ('0220673fe9e699a4ebc8e0dbeb6979c8', '546f646449d31458f9eb4ef5483aee6c', + 'bcbdbebfc1c2c3c4c6c7c8c9cbcccdce', + 'ecb-tbl-128: I=27'), + ('b2b99171337ded9bc8c2c23ff6f18867', '4dbe4bc84ac797c0ee4efb7f1a07401c', + 'd0d1d2d3d5d6d7d8dadbdcdddfe0e1e2', + 'ecb-tbl-128: I=28'), + ('a7facf4e301e984e5efeefd645b23505', '25e10bfb411bbd4d625ac8795c8ca3b3', + 'e4e5e6e7e9eaebeceeeff0f1f3f4f5f6', + 'ecb-tbl-128: I=29'), + ('f7c762e4a9819160fd7acfb6c4eedcdd', '315637405054ec803614e43def177579', + 'f8f9fafbfdfefe00020304050708090a', + 'ecb-tbl-128: I=30'), + ('9b64fc21ea08709f4915436faa70f1be', '60c5bc8a1410247295c6386c59e572a8', + '0c0d0e0f11121314161718191b1c1d1e', + 'ecb-tbl-128: I=31'), + ('52af2c3de07ee6777f55a4abfc100b3f', '01366fc8ca52dfe055d6a00a76471ba6', + '20212223252627282a2b2c2d2f303132', + 'ecb-tbl-128: I=32'), + ('2fca001224386c57aa3f968cbe2c816f', 'ecc46595516ec612449c3f581e7d42ff', + '34353637393a3b3c3e3f404143444546', + 'ecb-tbl-128: I=33'), + ('4149c73658a4a9c564342755ee2c132f', '6b7ffe4c602a154b06ee9c7dab5331c9', + '48494a4b4d4e4f50525354555758595a', + 'ecb-tbl-128: I=34'), + ('af60005a00a1772f7c07a48a923c23d2', '7da234c14039a240dd02dd0fbf84eb67', + '5c5d5e5f61626364666768696b6c6d6e', + 'ecb-tbl-128: I=35'), + ('6fccbc28363759914b6f0280afaf20c6', 'c7dc217d9e3604ffe7e91f080ecd5a3a', + '70717273757677787a7b7c7d7f808182', + 'ecb-tbl-128: I=36'), + ('7d82a43ddf4fefa2fc5947499884d386', '37785901863f5c81260ea41e7580cda5', + '84858687898a8b8c8e8f909193949596', + 'ecb-tbl-128: I=37'), + ('5d5a990eaab9093afe4ce254dfa49ef9', 'a07b9338e92ed105e6ad720fccce9fe4', + '98999a9b9d9e9fa0a2a3a4a5a7a8a9aa', + 'ecb-tbl-128: I=38'), + ('4cd1e2fd3f4434b553aae453f0ed1a02', 'ae0fb9722418cc21a7da816bbc61322c', + 'acadaeafb1b2b3b4b6b7b8b9bbbcbdbe', + 'ecb-tbl-128: I=39'), + ('5a2c9a9641d4299125fa1b9363104b5e', 'c826a193080ff91ffb21f71d3373c877', + 'c0c1c2c3c5c6c7c8cacbcccdcfd0d1d2', + 'ecb-tbl-128: I=40'), + ('b517fe34c0fa217d341740bfd4fe8dd4', '1181b11b0e494e8d8b0aa6b1d5ac2c48', + 'd4d5d6d7d9dadbdcdedfe0e1e3e4e5e6', + 'ecb-tbl-128: I=41'), + ('014baf2278a69d331d5180103643e99a', '6743c3d1519ab4f2cd9a78ab09a511bd', + 'e8e9eaebedeeeff0f2f3f4f5f7f8f9fa', + 'ecb-tbl-128: I=42'), + ('b529bd8164f20d0aa443d4932116841c', 'dc55c076d52bacdf2eefd952946a439d', + 'fcfdfeff01020304060708090b0c0d0e', + 'ecb-tbl-128: I=43'), + ('2e596dcbb2f33d4216a1176d5bd1e456', '711b17b590ffc72b5c8e342b601e8003', + '10111213151617181a1b1c1d1f202122', + 'ecb-tbl-128: I=44'), + ('7274a1ea2b7ee2424e9a0e4673689143', '19983bb0950783a537e1339f4aa21c75', + '24252627292a2b2c2e2f303133343536', + 'ecb-tbl-128: I=45'), + ('ae20020bd4f13e9d90140bee3b5d26af', '3ba7762e15554169c0f4fa39164c410c', + '38393a3b3d3e3f40424344454748494a', + 'ecb-tbl-128: I=46'), + ('baac065da7ac26e855e79c8849d75a02', 'a0564c41245afca7af8aa2e0e588ea89', + '4c4d4e4f51525354565758595b5c5d5e', + 'ecb-tbl-128: I=47'), + ('7c917d8d1d45fab9e2540e28832540cc', '5e36a42a2e099f54ae85ecd92e2381ed', + '60616263656667686a6b6c6d6f707172', + 'ecb-tbl-128: I=48'), + ('bde6f89e16daadb0e847a2a614566a91', '770036f878cd0f6ca2268172f106f2fe', + '74757677797a7b7c7e7f808183848586', + 'ecb-tbl-128: I=49'), + ('c9de163725f1f5be44ebb1db51d07fbc', '7e4e03908b716116443ccf7c94e7c259', + '88898a8b8d8e8f90929394959798999a', + 'ecb-tbl-128: I=50'), + ('3af57a58f0c07dffa669572b521e2b92', '482735a48c30613a242dd494c7f9185d', + '9c9d9e9fa1a2a3a4a6a7a8a9abacadae', + 'ecb-tbl-128: I=51'), + ('3d5ebac306dde4604f1b4fbbbfcdae55', 'b4c0f6c9d4d7079addf9369fc081061d', + 'b0b1b2b3b5b6b7b8babbbcbdbfc0c1c2', + 'ecb-tbl-128: I=52'), + ('c2dfa91bceb76a1183c995020ac0b556', 'd5810fe0509ac53edcd74f89962e6270', + 'c4c5c6c7c9cacbcccecfd0d1d3d4d5d6', + 'ecb-tbl-128: I=53'), + ('c70f54305885e9a0746d01ec56c8596b', '03f17a16b3f91848269ecdd38ebb2165', + 'd8d9dadbdddedfe0e2e3e4e5e7e8e9ea', + 'ecb-tbl-128: I=54'), + ('c4f81b610e98012ce000182050c0c2b2', 'da1248c3180348bad4a93b4d9856c9df', + 'ecedeeeff1f2f3f4f6f7f8f9fbfcfdfe', + 'ecb-tbl-128: I=55'), + ('eaab86b1d02a95d7404eff67489f97d4', '3d10d7b63f3452c06cdf6cce18be0c2c', + '00010203050607080a0b0c0d0f101112', + 'ecb-tbl-128: I=56'), + ('7c55bdb40b88870b52bec3738de82886', '4ab823e7477dfddc0e6789018fcb6258', + '14151617191a1b1c1e1f202123242526', + 'ecb-tbl-128: I=57'), + ('ba6eaa88371ff0a3bd875e3f2a975ce0', 'e6478ba56a77e70cfdaa5c843abde30e', + '28292a2b2d2e2f30323334353738393a', + 'ecb-tbl-128: I=58'), + ('08059130c4c24bd30cf0575e4e0373dc', '1673064895fbeaf7f09c5429ff75772d', + '3c3d3e3f41424344464748494b4c4d4e', + 'ecb-tbl-128: I=59'), + ('9a8eab004ef53093dfcf96f57e7eda82', '4488033ae9f2efd0ca9383bfca1a94e9', + '50515253555657585a5b5c5d5f606162', + 'ecb-tbl-128: I=60'), + ('0745b589e2400c25f117b1d796c28129', '978f3b8c8f9d6f46626cac3c0bcb9217', + '64656667696a6b6c6e6f707173747576', + 'ecb-tbl-128: I=61'), + ('2f1777781216cec3f044f134b1b92bbe', 'e08c8a7e582e15e5527f1d9e2eecb236', + '78797a7b7d7e7f80828384858788898a', + 'ecb-tbl-128: I=62'), + ('353a779ffc541b3a3805d90ce17580fc', 'cec155b76ac5ffda4cf4f9ca91e49a7a', + '8c8d8e8f91929394969798999b9c9d9e', + 'ecb-tbl-128: I=63'), + ('1a1eae4415cefcf08c4ac1c8f68bea8f', 'd5ac7165763225dd2a38cdc6862c29ad', + 'a0a1a2a3a5a6a7a8aaabacadafb0b1b2', + 'ecb-tbl-128: I=64'), + ('e6e7e4e5b0b3b2b5d4d5aaab16111013', '03680fe19f7ce7275452020be70e8204', + 'b4b5b6b7b9babbbcbebfc0c1c3c4c5c6', + 'ecb-tbl-128: I=65'), + ('f8f9fafbfbf8f9e677767170efe0e1e2', '461df740c9781c388e94bb861ceb54f6', + 'c8c9cacbcdcecfd0d2d3d4d5d7d8d9da', + 'ecb-tbl-128: I=66'), + ('63626160a1a2a3a445444b4a75727370', '451bd60367f96483042742219786a074', + 'dcdddedfe1e2e3e4e6e7e8e9ebecedee', + 'ecb-tbl-128: I=67'), + ('717073720605040b2d2c2b2a05fafbf9', 'e4dfa42671a02e57ef173b85c0ea9f2b', + 'f0f1f2f3f5f6f7f8fafbfcfdfe010002', + 'ecb-tbl-128: I=68'), + ('78797a7beae9e8ef3736292891969794', 'ed11b89e76274282227d854700a78b9e', + '04050607090a0b0c0e0f101113141516', + 'ecb-tbl-128: I=69'), + ('838281803231300fdddcdbdaa0afaead', '433946eaa51ea47af33895f2b90b3b75', + '18191a1b1d1e1f20222324252728292a', + 'ecb-tbl-128: I=70'), + ('18191a1bbfbcbdba75747b7a7f78797a', '6bc6d616a5d7d0284a5910ab35022528', + '2c2d2e2f31323334363738393b3c3d3e', + 'ecb-tbl-128: I=71'), + ('848586879b989996a3a2a5a4849b9a99', 'd2a920ecfe919d354b5f49eae9719c98', + '40414243454647484a4b4c4d4f505152', + 'ecb-tbl-128: I=72'), + ('0001020322212027cacbf4f551565754', '3a061b17f6a92885efbd0676985b373d', + '54555657595a5b5c5e5f606163646566', + 'ecb-tbl-128: I=73'), + ('cecfcccdafacadb2515057564a454447', 'fadeec16e33ea2f4688499d157e20d8f', + '68696a6b6d6e6f70727374757778797a', + 'ecb-tbl-128: I=74'), + ('92939091cdcecfc813121d1c80878685', '5cdefede59601aa3c3cda36fa6b1fa13', + '7c7d7e7f81828384868788898b8c8d8e', + 'ecb-tbl-128: I=75'), + ('d2d3d0d16f6c6d6259585f5ed1eeefec', '9574b00039844d92ebba7ee8719265f8', + '90919293959697989a9b9c9d9fa0a1a2', + 'ecb-tbl-128: I=76'), + ('acadaeaf878485820f0e1110d5d2d3d0', '9a9cf33758671787e5006928188643fa', + 'a4a5a6a7a9aaabacaeafb0b1b3b4b5b6', + 'ecb-tbl-128: I=77'), + ('9091929364676619e6e7e0e1757a7b78', '2cddd634c846ba66bb46cbfea4a674f9', + 'b8b9babbbdbebfc0c2c3c4c5c7c8c9ca', + 'ecb-tbl-128: I=78'), + ('babbb8b98a89888f74757a7b92959497', 'd28bae029393c3e7e26e9fafbbb4b98f', + 'cccdcecfd1d2d3d4d6d7d8d9dbdcddde', + 'ecb-tbl-128: I=79'), + ('8d8c8f8e6e6d6c633b3a3d3ccad5d4d7', 'ec27529b1bee0a9ab6a0d73ebc82e9b7', + 'e0e1e2e3e5e6e7e8eaebecedeff0f1f2', + 'ecb-tbl-128: I=80'), + ('86878485010203040808f7f767606162', '3cb25c09472aff6ee7e2b47ccd7ccb17', + 'f4f5f6f7f9fafbfcfefe010103040506', + 'ecb-tbl-128: I=81'), + ('8e8f8c8d656667788a8b8c8d010e0f0c', 'dee33103a7283370d725e44ca38f8fe5', + '08090a0b0d0e0f10121314151718191a', + 'ecb-tbl-128: I=82'), + ('c8c9cacb858687807a7b7475e7e0e1e2', '27f9bcd1aac64bffc11e7815702c1a69', + '1c1d1e1f21222324262728292b2c2d2e', + 'ecb-tbl-128: I=83'), + ('6d6c6f6e5053525d8c8d8a8badd2d3d0', '5df534ffad4ed0749a9988e9849d0021', + '30313233353637383a3b3c3d3f404142', + 'ecb-tbl-128: I=84'), + ('28292a2b393a3b3c0607181903040506', 'a48bee75db04fb60ca2b80f752a8421b', + '44454647494a4b4c4e4f505153545556', + 'ecb-tbl-128: I=85'), + ('a5a4a7a6b0b3b28ddbdadddcbdb2b3b0', '024c8cf70bc86ee5ce03678cb7af45f9', + '58595a5b5d5e5f60626364656768696a', + 'ecb-tbl-128: I=86'), + ('323330316467666130313e3f2c2b2a29', '3c19ac0f8a3a3862ce577831301e166b', + '6c6d6e6f71727374767778797b7c7d7e', + 'ecb-tbl-128: I=87'), + ('27262524080b0a05171611100b141516', 'c5e355b796a57421d59ca6be82e73bca', + '80818283858687888a8b8c8d8f909192', + 'ecb-tbl-128: I=88'), + ('040506074142434435340b0aa3a4a5a6', 'd94033276417abfb05a69d15b6e386e2', + '94959697999a9b9c9e9fa0a1a3a4a5a6', + 'ecb-tbl-128: I=89'), + ('242526271112130c61606766bdb2b3b0', '24b36559ea3a9b9b958fe6da3e5b8d85', + 'a8a9aaabadaeafb0b2b3b4b5b7b8b9ba', + 'ecb-tbl-128: I=90'), + ('4b4a4948252627209e9f9091cec9c8cb', '20fd4feaa0e8bf0cce7861d74ef4cb72', + 'bcbdbebfc1c2c3c4c6c7c8c9cbcccdce', + 'ecb-tbl-128: I=91'), + ('68696a6b6665646b9f9e9998d9e6e7e4', '350e20d5174277b9ec314c501570a11d', + 'd0d1d2d3d5d6d7d8dadbdcdddfe0e1e2', + 'ecb-tbl-128: I=92'), + ('34353637c5c6c7c0f0f1eeef7c7b7a79', '87a29d61b7c604d238fe73045a7efd57', + 'e4e5e6e7e9eaebeceeeff0f1f3f4f5f6', + 'ecb-tbl-128: I=93'), + ('32333031c2c1c13f0d0c0b0a050a0b08', '2c3164c1cc7d0064816bdc0faa362c52', + 'f8f9fafbfdfefe00020304050708090a', + 'ecb-tbl-128: I=94'), + ('cdcccfcebebdbcbbabaaa5a4181f1e1d', '195fe5e8a05a2ed594f6e4400eee10b3', + '0c0d0e0f11121314161718191b1c1d1e', + 'ecb-tbl-128: I=95'), + ('212023223635343ba0a1a6a7445b5a59', 'e4663df19b9a21a5a284c2bd7f905025', + '20212223252627282a2b2c2d2f303132', + 'ecb-tbl-128: I=96'), + ('0e0f0c0da8abaaad2f2e515002050407', '21b88714cfb4e2a933bd281a2c4743fd', + '34353637393a3b3c3e3f404143444546', + 'ecb-tbl-128: I=97'), + ('070605042a2928378e8f8889bdb2b3b0', 'cbfc3980d704fd0fc54378ab84e17870', + '48494a4b4d4e4f50525354555758595a', + 'ecb-tbl-128: I=98'), + ('cbcac9c893909196a9a8a7a6a5a2a3a0', 'bc5144baa48bdeb8b63e22e03da418ef', + '5c5d5e5f61626364666768696b6c6d6e', + 'ecb-tbl-128: I=99'), + ('80818283c1c2c3cc9c9d9a9b0cf3f2f1', '5a1dbaef1ee2984b8395da3bdffa3ccc', + '70717273757677787a7b7c7d7f808182', + 'ecb-tbl-128: I=100'), + ('1213101125262720fafbe4e5b1b6b7b4', 'f0b11cd0729dfcc80cec903d97159574', + '84858687898a8b8c8e8f909193949596', + 'ecb-tbl-128: I=101'), + ('7f7e7d7c3033320d97969190222d2c2f', '9f95314acfddc6d1914b7f19a9cc8209', + '98999a9b9d9e9fa0a2a3a4a5a7a8a9aa', + 'ecb-tbl-128: I=102'), + ('4e4f4c4d484b4a4d81808f8e53545556', '595736f6f0f70914a94e9e007f022519', + 'acadaeafb1b2b3b4b6b7b8b9bbbcbdbe', + 'ecb-tbl-128: I=103'), + ('dcdddedfb0b3b2bd15141312a1bebfbc', '1f19f57892cae586fcdfb4c694deb183', + 'c0c1c2c3c5c6c7c8cacbcccdcfd0d1d2', + 'ecb-tbl-128: I=104'), + ('93929190282b2a2dc4c5fafb92959497', '540700ee1f6f3dab0b3eddf6caee1ef5', + 'd4d5d6d7d9dadbdcdedfe0e1e3e4e5e6', + 'ecb-tbl-128: I=105'), + ('f5f4f7f6c4c7c6d9373631307e717073', '14a342a91019a331687a2254e6626ca2', + 'e8e9eaebedeeeff0f2f3f4f5f7f8f9fa', + 'ecb-tbl-128: I=106'), + ('93929190b6b5b4b364656a6b05020300', '7b25f3c3b2eea18d743ef283140f29ff', + 'fcfdfeff01020304060708090b0c0d0e', + 'ecb-tbl-128: I=107'), + ('babbb8b90d0e0f00a4a5a2a3043b3a39', '46c2587d66e5e6fa7f7ca6411ad28047', + '10111213151617181a1b1c1d1f202122', + 'ecb-tbl-128: I=108'), + ('d8d9dadb7f7c7d7a10110e0f787f7e7d', '09470e72229d954ed5ee73886dfeeba9', + '24252627292a2b2c2e2f303133343536', + 'ecb-tbl-128: I=109'), + ('fefffcfdefeced923b3a3d3c6768696a', 'd77c03de92d4d0d79ef8d4824ef365eb', + '38393a3b3d3e3f40424344454748494a', + 'ecb-tbl-128: I=110'), + ('d6d7d4d58a89888f96979899a5a2a3a0', '1d190219f290e0f1715d152d41a23593', + '4c4d4e4f51525354565758595b5c5d5e', + 'ecb-tbl-128: I=111'), + ('18191a1ba8abaaa5303136379b848586', 'a2cd332ce3a0818769616292e87f757b', + '60616263656667686a6b6c6d6f707172', + 'ecb-tbl-128: I=112'), + ('6b6a6968a4a7a6a1d6d72829b0b7b6b5', 'd54afa6ce60fbf9341a3690e21385102', + '74757677797a7b7c7e7f808183848586', + 'ecb-tbl-128: I=113'), + ('000102038a89889755545352a6a9a8ab', '06e5c364ded628a3f5e05e613e356f46', + '88898a8b8d8e8f90929394959798999a', + 'ecb-tbl-128: I=114'), + ('2d2c2f2eb3b0b1b6b6b7b8b9f2f5f4f7', 'eae63c0e62556dac85d221099896355a', + '9c9d9e9fa1a2a3a4a6a7a8a9abacadae', + 'ecb-tbl-128: I=115'), + ('979695943536373856575051e09f9e9d', '1fed060e2c6fc93ee764403a889985a2', + 'b0b1b2b3b5b6b7b8babbbcbdbfc0c1c2', + 'ecb-tbl-128: I=116'), + ('a4a5a6a7989b9a9db1b0afae7a7d7c7f', 'c25235c1a30fdec1c7cb5c5737b2a588', + 'c4c5c6c7c9cacbcccecfd0d1d3d4d5d6', + 'ecb-tbl-128: I=117'), + ('c1c0c3c2686b6a55a8a9aeafeae5e4e7', '796dbef95147d4d30873ad8b7b92efc0', + 'd8d9dadbdddedfe0e2e3e4e5e7e8e9ea', + 'ecb-tbl-128: I=118'), + ('c1c0c3c2141716118c8d828364636261', 'cbcf0fb34d98d0bd5c22ce37211a46bf', + 'ecedeeeff1f2f3f4f6f7f8f9fbfcfdfe', + 'ecb-tbl-128: I=119'), + ('93929190cccfcec196979091e0fffefd', '94b44da6466126cafa7c7fd09063fc24', + '00010203050607080a0b0c0d0f101112', + 'ecb-tbl-128: I=120'), + ('b4b5b6b7f9fafbfc25241b1a6e69686b', 'd78c5b5ebf9b4dbda6ae506c5074c8fe', + '14151617191a1b1c1e1f202123242526', + 'ecb-tbl-128: I=121'), + ('868784850704051ac7c6c1c08788898a', '6c27444c27204b043812cf8cf95f9769', + '28292a2b2d2e2f30323334353738393a', + 'ecb-tbl-128: I=122'), + ('f4f5f6f7aaa9a8affdfcf3f277707172', 'be94524ee5a2aa50bba8b75f4c0aebcf', + '3c3d3e3f41424344464748494b4c4d4e', + 'ecb-tbl-128: I=123'), + ('d3d2d1d00605040bc3c2c5c43e010003', 'a0aeaae91ba9f31f51aeb3588cf3a39e', + '50515253555657585a5b5c5d5f606162', + 'ecb-tbl-128: I=124'), + ('73727170424140476a6b74750d0a0b08', '275297779c28266ef9fe4c6a13c08488', + '64656667696a6b6c6e6f707173747576', + 'ecb-tbl-128: I=125'), + ('c2c3c0c10a0908f754555253a1aeafac', '86523d92bb8672cb01cf4a77fd725882', + '78797a7b7d7e7f80828384858788898a', + 'ecb-tbl-128: I=126'), + ('6d6c6f6ef8fbfafd82838c8df8fffefd', '4b8327640e9f33322a04dd96fcbf9a36', + '8c8d8e8f91929394969798999b9c9d9e', + 'ecb-tbl-128: I=127'), + ('f5f4f7f684878689a6a7a0a1d2cdcccf', 'ce52af650d088ca559425223f4d32694', + 'a0a1a2a3a5a6a7a8aaabacadafb0b1b2', + 'ecb-tbl-128: I=128'), + + # ecb_tbl.txt, KEYSIZE=192 + ('2d33eef2c0430a8a9ebf45e809c40bb6', 'dff4945e0336df4c1c56bc700eff837f', + '00010203050607080a0b0c0d0f10111214151617191a1b1c', + 'ecb-tbl-192: I=1'), + ('6aa375d1fa155a61fb72353e0a5a8756', 'b6fddef4752765e347d5d2dc196d1252', + '1e1f20212324252628292a2b2d2e2f30323334353738393a', + 'ecb-tbl-192: I=2'), + ('bc3736518b9490dcb8ed60eb26758ed4', 'd23684e3d963b3afcf1a114aca90cbd6', + '3c3d3e3f41424344464748494b4c4d4e5051525355565758', + 'ecb-tbl-192: I=3'), + ('aa214402b46cffb9f761ec11263a311e', '3a7ac027753e2a18c2ceab9e17c11fd0', + '5a5b5c5d5f60616264656667696a6b6c6e6f707173747576', + 'ecb-tbl-192: I=4'), + ('02aea86e572eeab66b2c3af5e9a46fd6', '8f6786bd007528ba26603c1601cdd0d8', + '78797a7b7d7e7f80828384858788898a8c8d8e8f91929394', + 'ecb-tbl-192: I=5'), + ('e2aef6acc33b965c4fa1f91c75ff6f36', 'd17d073b01e71502e28b47ab551168b3', + '969798999b9c9d9ea0a1a2a3a5a6a7a8aaabacadafb0b1b2', + 'ecb-tbl-192: I=6'), + ('0659df46427162b9434865dd9499f91d', 'a469da517119fab95876f41d06d40ffa', + 'b4b5b6b7b9babbbcbebfc0c1c3c4c5c6c8c9cacbcdcecfd0', + 'ecb-tbl-192: I=7'), + ('49a44239c748feb456f59c276a5658df', '6091aa3b695c11f5c0b6ad26d3d862ff', + 'd2d3d4d5d7d8d9dadcdddedfe1e2e3e4e6e7e8e9ebecedee', + 'ecb-tbl-192: I=8'), + ('66208f6e9d04525bdedb2733b6a6be37', '70f9e67f9f8df1294131662dc6e69364', + 'f0f1f2f3f5f6f7f8fafbfcfdfe01000204050607090a0b0c', + 'ecb-tbl-192: I=9'), + ('3393f8dfc729c97f5480b950bc9666b0', 'd154dcafad8b207fa5cbc95e9996b559', + '0e0f10111314151618191a1b1d1e1f20222324252728292a', + 'ecb-tbl-192: I=10'), + ('606834c8ce063f3234cf1145325dbd71', '4934d541e8b46fa339c805a7aeb9e5da', + '2c2d2e2f31323334363738393b3c3d3e4041424345464748', + 'ecb-tbl-192: I=11'), + ('fec1c04f529bbd17d8cecfcc4718b17f', '62564c738f3efe186e1a127a0c4d3c61', + '4a4b4c4d4f50515254555657595a5b5c5e5f606163646566', + 'ecb-tbl-192: I=12'), + ('32df99b431ed5dc5acf8caf6dc6ce475', '07805aa043986eb23693e23bef8f3438', + '68696a6b6d6e6f70727374757778797a7c7d7e7f81828384', + 'ecb-tbl-192: I=13'), + ('7fdc2b746f3f665296943b83710d1f82', 'df0b4931038bade848dee3b4b85aa44b', + '868788898b8c8d8e90919293959697989a9b9c9d9fa0a1a2', + 'ecb-tbl-192: I=14'), + ('8fba1510a3c5b87e2eaa3f7a91455ca2', '592d5fded76582e4143c65099309477c', + 'a4a5a6a7a9aaabacaeafb0b1b3b4b5b6b8b9babbbdbebfc0', + 'ecb-tbl-192: I=15'), + ('2c9b468b1c2eed92578d41b0716b223b', 'c9b8d6545580d3dfbcdd09b954ed4e92', + 'c2c3c4c5c7c8c9cacccdcecfd1d2d3d4d6d7d8d9dbdcddde', + 'ecb-tbl-192: I=16'), + ('0a2bbf0efc6bc0034f8a03433fca1b1a', '5dccd5d6eb7c1b42acb008201df707a0', + 'e0e1e2e3e5e6e7e8eaebecedeff0f1f2f4f5f6f7f9fafbfc', + 'ecb-tbl-192: I=17'), + ('25260e1f31f4104d387222e70632504b', 'a2a91682ffeb6ed1d34340946829e6f9', + 'fefe01010304050608090a0b0d0e0f10121314151718191a', + 'ecb-tbl-192: I=18'), + ('c527d25a49f08a5228d338642ae65137', 'e45d185b797000348d9267960a68435d', + '1c1d1e1f21222324262728292b2c2d2e3031323335363738', + 'ecb-tbl-192: I=19'), + ('3b49fc081432f5890d0e3d87e884a69e', '45e060dae5901cda8089e10d4f4c246b', + '3a3b3c3d3f40414244454647494a4b4c4e4f505153545556', + 'ecb-tbl-192: I=20'), + ('d173f9ed1e57597e166931df2754a083', 'f6951afacc0079a369c71fdcff45df50', + '58595a5b5d5e5f60626364656768696a6c6d6e6f71727374', + 'ecb-tbl-192: I=21'), + ('8c2b7cafa5afe7f13562daeae1adede0', '9e95e00f351d5b3ac3d0e22e626ddad6', + '767778797b7c7d7e80818283858687888a8b8c8d8f909192', + 'ecb-tbl-192: I=22'), + ('aaf4ec8c1a815aeb826cab741339532c', '9cb566ff26d92dad083b51fdc18c173c', + '94959697999a9b9c9e9fa0a1a3a4a5a6a8a9aaabadaeafb0', + 'ecb-tbl-192: I=23'), + ('40be8c5d9108e663f38f1a2395279ecf', 'c9c82766176a9b228eb9a974a010b4fb', + 'd0d1d2d3d5d6d7d8dadbdcdddfe0e1e2e4e5e6e7e9eaebec', + 'ecb-tbl-192: I=24'), + ('0c8ad9bc32d43e04716753aa4cfbe351', 'd8e26aa02945881d5137f1c1e1386e88', + '2a2b2c2d2f30313234353637393a3b3c3e3f404143444546', + 'ecb-tbl-192: I=25'), + ('1407b1d5f87d63357c8dc7ebbaebbfee', 'c0e024ccd68ff5ffa4d139c355a77c55', + '48494a4b4d4e4f50525354555758595a5c5d5e5f61626364', + 'ecb-tbl-192: I=26'), + ('e62734d1ae3378c4549e939e6f123416', '0b18b3d16f491619da338640df391d43', + '84858687898a8b8c8e8f90919394959698999a9b9d9e9fa0', + 'ecb-tbl-192: I=27'), + ('5a752cff2a176db1a1de77f2d2cdee41', 'dbe09ac8f66027bf20cb6e434f252efc', + 'a2a3a4a5a7a8a9aaacadaeafb1b2b3b4b6b7b8b9bbbcbdbe', + 'ecb-tbl-192: I=28'), + ('a9c8c3a4eabedc80c64730ddd018cd88', '6d04e5e43c5b9cbe05feb9606b6480fe', + 'c0c1c2c3c5c6c7c8cacbcccdcfd0d1d2d4d5d6d7d9dadbdc', + 'ecb-tbl-192: I=29'), + ('ee9b3dbbdb86180072130834d305999a', 'dd1d6553b96be526d9fee0fbd7176866', + '1a1b1c1d1f20212224252627292a2b2c2e2f303133343536', + 'ecb-tbl-192: I=30'), + ('a7fa8c3586b8ebde7568ead6f634a879', '0260ca7e3f979fd015b0dd4690e16d2a', + '38393a3b3d3e3f40424344454748494a4c4d4e4f51525354', + 'ecb-tbl-192: I=31'), + ('37e0f4a87f127d45ac936fe7ad88c10a', '9893734de10edcc8a67c3b110b8b8cc6', + '929394959798999a9c9d9e9fa1a2a3a4a6a7a8a9abacadae', + 'ecb-tbl-192: I=32'), + ('3f77d8b5d92bac148e4e46f697a535c5', '93b30b750516b2d18808d710c2ee84ef', + '464748494b4c4d4e50515253555657585a5b5c5d5f606162', + 'ecb-tbl-192: I=33'), + ('d25ebb686c40f7e2c4da1014936571ca', '16f65fa47be3cb5e6dfe7c6c37016c0e', + '828384858788898a8c8d8e8f91929394969798999b9c9d9e', + 'ecb-tbl-192: I=34'), + ('4f1c769d1e5b0552c7eca84dea26a549', 'f3847210d5391e2360608e5acb560581', + 'a0a1a2a3a5a6a7a8aaabacadafb0b1b2b4b5b6b7b9babbbc', + 'ecb-tbl-192: I=35'), + ('8548e2f882d7584d0fafc54372b6633a', '8754462cd223366d0753913e6af2643d', + 'bebfc0c1c3c4c5c6c8c9cacbcdcecfd0d2d3d4d5d7d8d9da', + 'ecb-tbl-192: I=36'), + ('87d7a336cb476f177cd2a51af2a62cdf', '1ea20617468d1b806a1fd58145462017', + 'dcdddedfe1e2e3e4e6e7e8e9ebecedeef0f1f2f3f5f6f7f8', + 'ecb-tbl-192: I=37'), + ('03b1feac668c4e485c1065dfc22b44ee', '3b155d927355d737c6be9dda60136e2e', + 'fafbfcfdfe01000204050607090a0b0c0e0f101113141516', + 'ecb-tbl-192: I=38'), + ('bda15e66819fa72d653a6866aa287962', '26144f7b66daa91b6333dbd3850502b3', + '18191a1b1d1e1f20222324252728292a2c2d2e2f31323334', + 'ecb-tbl-192: I=39'), + ('4d0c7a0d2505b80bf8b62ceb12467f0a', 'e4f9a4ab52ced8134c649bf319ebcc90', + '363738393b3c3d3e40414243454647484a4b4c4d4f505152', + 'ecb-tbl-192: I=40'), + ('626d34c9429b37211330986466b94e5f', 'b9ddd29ac6128a6cab121e34a4c62b36', + '54555657595a5b5c5e5f60616364656668696a6b6d6e6f70', + 'ecb-tbl-192: I=41'), + ('333c3e6bf00656b088a17e5ff0e7f60a', '6fcddad898f2ce4eff51294f5eaaf5c9', + '727374757778797a7c7d7e7f81828384868788898b8c8d8e', + 'ecb-tbl-192: I=42'), + ('687ed0cdc0d2a2bc8c466d05ef9d2891', 'c9a6fe2bf4028080bea6f7fc417bd7e3', + '90919293959697989a9b9c9d9fa0a1a2a4a5a6a7a9aaabac', + 'ecb-tbl-192: I=43'), + ('487830e78cc56c1693e64b2a6660c7b6', '6a2026846d8609d60f298a9c0673127f', + 'aeafb0b1b3b4b5b6b8b9babbbdbebfc0c2c3c4c5c7c8c9ca', + 'ecb-tbl-192: I=44'), + ('7a48d6b7b52b29392aa2072a32b66160', '2cb25c005e26efea44336c4c97a4240b', + 'cccdcecfd1d2d3d4d6d7d8d9dbdcdddee0e1e2e3e5e6e7e8', + 'ecb-tbl-192: I=45'), + ('907320e64c8c5314d10f8d7a11c8618d', '496967ab8680ddd73d09a0e4c7dcc8aa', + 'eaebecedeff0f1f2f4f5f6f7f9fafbfcfefe010103040506', + 'ecb-tbl-192: I=46'), + ('b561f2ca2d6e65a4a98341f3ed9ff533', 'd5af94de93487d1f3a8c577cb84a66a4', + '08090a0b0d0e0f10121314151718191a1c1d1e1f21222324', + 'ecb-tbl-192: I=47'), + ('df769380d212792d026f049e2e3e48ef', '84bdac569cae2828705f267cc8376e90', + '262728292b2c2d2e30313233353637383a3b3c3d3f404142', + 'ecb-tbl-192: I=48'), + ('79f374bc445bdabf8fccb8843d6054c6', 'f7401dda5ad5ab712b7eb5d10c6f99b6', + '44454647494a4b4c4e4f50515354555658595a5b5d5e5f60', + 'ecb-tbl-192: I=49'), + ('4e02f1242fa56b05c68dbae8fe44c9d6', '1c9d54318539ebd4c3b5b7e37bf119f0', + '626364656768696a6c6d6e6f71727374767778797b7c7d7e', + 'ecb-tbl-192: I=50'), + ('cf73c93cbff57ac635a6f4ad2a4a1545', 'aca572d65fb2764cffd4a6eca090ea0d', + '80818283858687888a8b8c8d8f90919294959697999a9b9c', + 'ecb-tbl-192: I=51'), + ('9923548e2875750725b886566784c625', '36d9c627b8c2a886a10ccb36eae3dfbb', + '9e9fa0a1a3a4a5a6a8a9aaabadaeafb0b2b3b4b5b7b8b9ba', + 'ecb-tbl-192: I=52'), + ('4888336b723a022c9545320f836a4207', '010edbf5981e143a81d646e597a4a568', + 'bcbdbebfc1c2c3c4c6c7c8c9cbcccdced0d1d2d3d5d6d7d8', + 'ecb-tbl-192: I=53'), + ('f84d9a5561b0608b1160dee000c41ba8', '8db44d538dc20cc2f40f3067fd298e60', + 'dadbdcdddfe0e1e2e4e5e6e7e9eaebeceeeff0f1f3f4f5f6', + 'ecb-tbl-192: I=54'), + ('c23192a0418e30a19b45ae3e3625bf22', '930eb53bc71e6ac4b82972bdcd5aafb3', + 'f8f9fafbfdfefe00020304050708090a0c0d0e0f11121314', + 'ecb-tbl-192: I=55'), + ('b84e0690b28b0025381ad82a15e501a7', '6c42a81edcbc9517ccd89c30c95597b4', + '161718191b1c1d1e20212223252627282a2b2c2d2f303132', + 'ecb-tbl-192: I=56'), + ('acef5e5c108876c4f06269f865b8f0b0', 'da389847ad06df19d76ee119c71e1dd3', + '34353637393a3b3c3e3f40414344454648494a4b4d4e4f50', + 'ecb-tbl-192: I=57'), + ('0f1b3603e0f5ddea4548246153a5e064', 'e018fdae13d3118f9a5d1a647a3f0462', + '525354555758595a5c5d5e5f61626364666768696b6c6d6e', + 'ecb-tbl-192: I=58'), + ('fbb63893450d42b58c6d88cd3c1809e3', '2aa65db36264239d3846180fabdfad20', + '70717273757677787a7b7c7d7f80818284858687898a8b8c', + 'ecb-tbl-192: I=59'), + ('4bef736df150259dae0c91354e8a5f92', '1472163e9a4f780f1ceb44b07ecf4fdb', + '8e8f90919394959698999a9b9d9e9fa0a2a3a4a5a7a8a9aa', + 'ecb-tbl-192: I=60'), + ('7d2d46242056ef13d3c3fc93c128f4c7', 'c8273fdc8f3a9f72e91097614b62397c', + 'acadaeafb1b2b3b4b6b7b8b9bbbcbdbec0c1c2c3c5c6c7c8', + 'ecb-tbl-192: I=61'), + ('e9c1ba2df415657a256edb33934680fd', '66c8427dcd733aaf7b3470cb7d976e3f', + 'cacbcccdcfd0d1d2d4d5d6d7d9dadbdcdedfe0e1e3e4e5e6', + 'ecb-tbl-192: I=62'), + ('e23ee277b0aa0a1dfb81f7527c3514f1', '146131cb17f1424d4f8da91e6f80c1d0', + 'e8e9eaebedeeeff0f2f3f4f5f7f8f9fafcfdfeff01020304', + 'ecb-tbl-192: I=63'), + ('3e7445b0b63caaf75e4a911e12106b4c', '2610d0ad83659081ae085266a88770dc', + '060708090b0c0d0e10111213151617181a1b1c1d1f202122', + 'ecb-tbl-192: I=64'), + ('767774752023222544455a5be6e1e0e3', '38a2b5a974b0575c5d733917fb0d4570', + '24252627292a2b2c2e2f30313334353638393a3b3d3e3f40', + 'ecb-tbl-192: I=65'), + ('72737475717e7f7ce9e8ebea696a6b6c', 'e21d401ebc60de20d6c486e4f39a588b', + '424344454748494a4c4d4e4f51525354565758595b5c5d5e', + 'ecb-tbl-192: I=66'), + ('dfdedddc25262728c9c8cfcef1eeefec', 'e51d5f88c670b079c0ca1f0c2c4405a2', + '60616263656667686a6b6c6d6f70717274757677797a7b7c', + 'ecb-tbl-192: I=67'), + ('fffe0100707776755f5e5d5c7675746b', '246a94788a642fb3d1b823c8762380c8', + '7e7f80818384858688898a8b8d8e8f90929394959798999a', + 'ecb-tbl-192: I=68'), + ('e0e1e2e3424140479f9e9190292e2f2c', 'b80c391c5c41a4c3b30c68e0e3d7550f', + '9c9d9e9fa1a2a3a4a6a7a8a9abacadaeb0b1b2b3b5b6b7b8', + 'ecb-tbl-192: I=69'), + ('2120272690efeeed3b3a39384e4d4c4b', 'b77c4754fc64eb9a1154a9af0bb1f21c', + 'babbbcbdbfc0c1c2c4c5c6c7c9cacbcccecfd0d1d3d4d5d6', + 'ecb-tbl-192: I=70'), + ('ecedeeef5350516ea1a0a7a6a3acadae', 'fb554de520d159a06bf219fc7f34a02f', + 'd8d9dadbdddedfe0e2e3e4e5e7e8e9eaecedeeeff1f2f3f4', + 'ecb-tbl-192: I=71'), + ('32333c3d25222320e9e8ebeacecdccc3', 'a89fba152d76b4927beed160ddb76c57', + 'f6f7f8f9fbfcfdfe00010203050607080a0b0c0d0f101112', + 'ecb-tbl-192: I=72'), + ('40414243626160678a8bb4b511161714', '5676eab4a98d2e8473b3f3d46424247c', + '14151617191a1b1c1e1f20212324252628292a2b2d2e2f30', + 'ecb-tbl-192: I=73'), + ('94959293f5fafbf81f1e1d1c7c7f7e79', '4e8f068bd7ede52a639036ec86c33568', + '323334353738393a3c3d3e3f41424344464748494b4c4d4e', + 'ecb-tbl-192: I=74'), + ('bebfbcbd191a1b14cfcec9c8546b6a69', 'f0193c4d7aff1791ee4c07eb4a1824fc', + '50515253555657585a5b5c5d5f60616264656667696a6b6c', + 'ecb-tbl-192: I=75'), + ('2c2d3233898e8f8cbbbab9b8333031ce', 'ac8686eeca9ba761afe82d67b928c33f', + '6e6f70717374757678797a7b7d7e7f80828384858788898a', + 'ecb-tbl-192: I=76'), + ('84858687bfbcbdba37363938fdfafbf8', '5faf8573e33b145b6a369cd3606ab2c9', + '8c8d8e8f91929394969798999b9c9d9ea0a1a2a3a5a6a7a8', + 'ecb-tbl-192: I=77'), + ('828384857669686b909192930b08090e', '31587e9944ab1c16b844ecad0df2e7da', + 'aaabacadafb0b1b2b4b5b6b7b9babbbcbebfc0c1c3c4c5c6', + 'ecb-tbl-192: I=78'), + ('bebfbcbd9695948b707176779e919093', 'd017fecd91148aba37f6f3068aa67d8a', + 'c8c9cacbcdcecfd0d2d3d4d5d7d8d9dadcdddedfe1e2e3e4', + 'ecb-tbl-192: I=79'), + ('8b8a85846067666521202322d0d3d2dd', '788ef2f021a73cba2794b616078a8500', + 'e6e7e8e9ebecedeef0f1f2f3f5f6f7f8fafbfcfdfe010002', + 'ecb-tbl-192: I=80'), + ('76777475f1f2f3f4f8f9e6e777707172', '5d1ef20dced6bcbc12131ac7c54788aa', + '04050607090a0b0c0e0f10111314151618191a1b1d1e1f20', + 'ecb-tbl-192: I=81'), + ('a4a5a2a34f404142b4b5b6b727242522', 'b3c8cf961faf9ea05fdde6d1e4d8f663', + '222324252728292a2c2d2e2f31323334363738393b3c3d3e', + 'ecb-tbl-192: I=82'), + ('94959697e1e2e3ec16171011839c9d9e', '143075c70605861c7fac6526199e459f', + '40414243454647484a4b4c4d4f50515254555657595a5b5c', + 'ecb-tbl-192: I=83'), + ('03023d3c06010003dedfdcddfffcfde2', 'a5ae12eade9a87268d898bfc8fc0252a', + '5e5f60616364656668696a6b6d6e6f70727374757778797a', + 'ecb-tbl-192: I=84'), + ('10111213f1f2f3f4cecfc0c1dbdcddde', '0924f7cf2e877a4819f5244a360dcea9', + '7c7d7e7f81828384868788898b8c8d8e9091929395969798', + 'ecb-tbl-192: I=85'), + ('67666160724d4c4f1d1c1f1e73707176', '3d9e9635afcc3e291cc7ab3f27d1c99a', + '9a9b9c9d9fa0a1a2a4a5a6a7a9aaabacaeafb0b1b3b4b5b6', + 'ecb-tbl-192: I=86'), + ('e6e7e4e5a8abaad584858283909f9e9d', '9d80feebf87510e2b8fb98bb54fd788c', + 'b8b9babbbdbebfc0c2c3c4c5c7c8c9cacccdcecfd1d2d3d4', + 'ecb-tbl-192: I=87'), + ('71707f7e565150537d7c7f7e6162636c', '5f9d1a082a1a37985f174002eca01309', + 'd6d7d8d9dbdcdddee0e1e2e3e5e6e7e8eaebecedeff0f1f2', + 'ecb-tbl-192: I=88'), + ('64656667212223245555aaaa03040506', 'a390ebb1d1403930184a44b4876646e4', + 'f4f5f6f7f9fafbfcfefe01010304050608090a0b0d0e0f10', + 'ecb-tbl-192: I=89'), + ('9e9f9899aba4a5a6cfcecdcc2b28292e', '700fe918981c3195bb6c4bcb46b74e29', + '121314151718191a1c1d1e1f21222324262728292b2c2d2e', + 'ecb-tbl-192: I=90'), + ('c7c6c5c4d1d2d3dc626364653a454447', '907984406f7bf2d17fb1eb15b673d747', + '30313233353637383a3b3c3d3f40414244454647494a4b4c', + 'ecb-tbl-192: I=91'), + ('f6f7e8e9e0e7e6e51d1c1f1e5b585966', 'c32a956dcfc875c2ac7c7cc8b8cc26e1', + '4e4f50515354555658595a5b5d5e5f60626364656768696a', + 'ecb-tbl-192: I=92'), + ('bcbdbebf5d5e5f5868696667f4f3f2f1', '02646e2ebfa9b820cf8424e9b9b6eb51', + '6c6d6e6f71727374767778797b7c7d7e8081828385868788', + 'ecb-tbl-192: I=93'), + ('40414647b0afaead9b9a99989b98999e', '621fda3a5bbd54c6d3c685816bd4ead8', + '8a8b8c8d8f90919294959697999a9b9c9e9fa0a1a3a4a5a6', + 'ecb-tbl-192: I=94'), + ('69686b6a0201001f0f0e0908b4bbbab9', 'd4e216040426dfaf18b152469bc5ac2f', + 'a8a9aaabadaeafb0b2b3b4b5b7b8b9babcbdbebfc1c2c3c4', + 'ecb-tbl-192: I=95'), + ('c7c6c9c8d8dfdedd5a5b5859bebdbcb3', '9d0635b9d33b6cdbd71f5d246ea17cc8', + 'c6c7c8c9cbcccdced0d1d2d3d5d6d7d8dadbdcdddfe0e1e2', + 'ecb-tbl-192: I=96'), + ('dedfdcdd787b7a7dfffee1e0b2b5b4b7', '10abad1bd9bae5448808765583a2cc1a', + 'e4e5e6e7e9eaebeceeeff0f1f3f4f5f6f8f9fafbfdfefe00', + 'ecb-tbl-192: I=97'), + ('4d4c4b4a606f6e6dd0d1d2d3fbf8f9fe', '6891889e16544e355ff65a793c39c9a8', + '020304050708090a0c0d0e0f11121314161718191b1c1d1e', + 'ecb-tbl-192: I=98'), + ('b7b6b5b4d7d4d5dae5e4e3e2e1fefffc', 'cc735582e68072c163cd9ddf46b91279', + '20212223252627282a2b2c2d2f30313234353637393a3b3c', + 'ecb-tbl-192: I=99'), + ('cecfb0b1f7f0f1f2aeafacad3e3d3c23', 'c5c68b9aeeb7f878df578efa562f9574', + '3e3f40414344454648494a4b4d4e4f50525354555758595a', + 'ecb-tbl-192: I=100'), + ('cacbc8c9cdcecfc812131c1d494e4f4c', '5f4764395a667a47d73452955d0d2ce8', + '5c5d5e5f61626364666768696b6c6d6e7071727375767778', + 'ecb-tbl-192: I=101'), + ('9d9c9b9ad22d2c2fb1b0b3b20c0f0e09', '701448331f66106cefddf1eb8267c357', + '7a7b7c7d7f80818284858687898a8b8c8e8f909193949596', + 'ecb-tbl-192: I=102'), + ('7a7b787964676659959493924f404142', 'cb3ee56d2e14b4e1941666f13379d657', + '98999a9b9d9e9fa0a2a3a4a5a7a8a9aaacadaeafb1b2b3b4', + 'ecb-tbl-192: I=103'), + ('aaaba4a5cec9c8cb1f1e1d1caba8a9a6', '9fe16efd18ab6e1981191851fedb0764', + 'b6b7b8b9bbbcbdbec0c1c2c3c5c6c7c8cacbcccdcfd0d1d2', + 'ecb-tbl-192: I=104'), + ('93929190282b2a2dc4c5fafb92959497', '3dc9ba24e1b223589b147adceb4c8e48', + 'd4d5d6d7d9dadbdcdedfe0e1e3e4e5e6e8e9eaebedeeeff0', + 'ecb-tbl-192: I=105'), + ('efeee9e8ded1d0d339383b3a888b8a8d', '1c333032682e7d4de5e5afc05c3e483c', + 'f2f3f4f5f7f8f9fafcfdfeff01020304060708090b0c0d0e', + 'ecb-tbl-192: I=106'), + ('7f7e7d7ca2a1a0af78797e7f112e2f2c', 'd593cc99a95afef7e92038e05a59d00a', + '10111213151617181a1b1c1d1f20212224252627292a2b2c', + 'ecb-tbl-192: I=107'), + ('84859a9b2b2c2d2e868784852625245b', '51e7f96f53b4353923452c222134e1ec', + '2e2f30313334353638393a3b3d3e3f40424344454748494a', + 'ecb-tbl-192: I=108'), + ('b0b1b2b3070405026869666710171615', '4075b357a1a2b473400c3b25f32f81a4', + '4c4d4e4f51525354565758595b5c5d5e6061626365666768', + 'ecb-tbl-192: I=109'), + ('acadaaabbda2a3a00d0c0f0e595a5b5c', '302e341a3ebcd74f0d55f61714570284', + '6a6b6c6d6f70717274757677797a7b7c7e7f808183848586', + 'ecb-tbl-192: I=110'), + ('121310115655544b5253545569666764', '57abdd8231280da01c5042b78cf76522', + '88898a8b8d8e8f90929394959798999a9c9d9e9fa1a2a3a4', + 'ecb-tbl-192: I=111'), + ('dedfd0d166616063eaebe8e94142434c', '17f9ea7eea17ac1adf0e190fef799e92', + 'a6a7a8a9abacadaeb0b1b2b3b5b6b7b8babbbcbdbfc0c1c2', + 'ecb-tbl-192: I=112'), + ('dbdad9d81417161166677879e0e7e6e5', '2e1bdd563dd87ee5c338dd6d098d0a7a', + 'c4c5c6c7c9cacbcccecfd0d1d3d4d5d6d8d9dadbdddedfe0', + 'ecb-tbl-192: I=113'), + ('6a6b6c6de0efeeed2b2a2928c0c3c2c5', 'eb869996e6f8bfb2bfdd9e0c4504dbb2', + 'e2e3e4e5e7e8e9eaecedeeeff1f2f3f4f6f7f8f9fbfcfdfe', + 'ecb-tbl-192: I=114'), + ('b1b0b3b21714151a1a1b1c1d5649484b', 'c2e01549e9decf317468b3e018c61ba8', + '00010203050607080a0b0c0d0f10111214151617191a1b1c', + 'ecb-tbl-192: I=115'), + ('39380706a3a4a5a6c4c5c6c77271706f', '8da875d033c01dd463b244a1770f4a22', + '1e1f20212324252628292a2b2d2e2f30323334353738393a', + 'ecb-tbl-192: I=116'), + ('5c5d5e5f1013121539383736e2e5e4e7', '8ba0dcf3a186844f026d022f8839d696', + '3c3d3e3f41424344464748494b4c4d4e5051525355565758', + 'ecb-tbl-192: I=117'), + ('43424544ead5d4d72e2f2c2d64676661', 'e9691ff9a6cc6970e51670a0fd5b88c1', + '5a5b5c5d5f60616264656667696a6b6c6e6f707173747576', + 'ecb-tbl-192: I=118'), + ('55545756989b9a65f8f9feff18171615', 'f2baec06faeed30f88ee63ba081a6e5b', + '78797a7b7d7e7f80828384858788898a8c8d8e8f91929394', + 'ecb-tbl-192: I=119'), + ('05040b0a525554573c3d3e3f4a494847', '9c39d4c459ae5753394d6094adc21e78', + '969798999b9c9d9ea0a1a2a3a5a6a7a8aaabacadafb0b1b2', + 'ecb-tbl-192: I=120'), + ('14151617595a5b5c8584fbfa8e89888b', '6345b532a11904502ea43ba99c6bd2b2', + 'b4b5b6b7b9babbbcbebfc0c1c3c4c5c6c8c9cacbcdcecfd0', + 'ecb-tbl-192: I=121'), + ('7c7d7a7bfdf2f3f029282b2a51525354', '5ffae3061a95172e4070cedce1e428c8', + 'd2d3d4d5d7d8d9dadcdddedfe1e2e3e4e6e7e8e9ebecedee', + 'ecb-tbl-192: I=122'), + ('38393a3b1e1d1c1341404746c23d3c3e', '0a4566be4cdf9adce5dec865b5ab34cd', + 'f0f1f2f3f5f6f7f8fafbfcfdfe01000204050607090a0b0c', + 'ecb-tbl-192: I=123'), + ('8d8c939240474645818083827c7f7e41', 'ca17fcce79b7404f2559b22928f126fb', + '0e0f10111314151618191a1b1d1e1f20222324252728292a', + 'ecb-tbl-192: I=124'), + ('3b3a39381a19181f32333c3d45424340', '97ca39b849ed73a6470a97c821d82f58', + '2c2d2e2f31323334363738393b3c3d3e4041424345464748', + 'ecb-tbl-192: I=125'), + ('f0f1f6f738272625828380817f7c7d7a', '8198cb06bc684c6d3e9b7989428dcf7a', + '4a4b4c4d4f50515254555657595a5b5c5e5f606163646566', + 'ecb-tbl-192: I=126'), + ('89888b8a0407061966676061141b1a19', 'f53c464c705ee0f28d9a4c59374928bd', + '68696a6b6d6e6f70727374757778797a7c7d7e7f81828384', + 'ecb-tbl-192: I=127'), + ('d3d2dddcaaadacaf9c9d9e9fe8ebeae5', '9adb3d4cca559bb98c3e2ed73dbf1154', + '868788898b8c8d8e90919293959697989a9b9c9d9fa0a1a2', + 'ecb-tbl-192: I=128'), + + # ecb_tbl.txt, KEYSIZE=256 + ('834eadfccac7e1b30664b1aba44815ab', '1946dabf6a03a2a2c3d0b05080aed6fc', + '00010203050607080a0b0c0d0f10111214151617191a1b1c1e1f202123242526', + 'ecb-tbl-256: I=1'), + ('d9dc4dba3021b05d67c0518f72b62bf1', '5ed301d747d3cc715445ebdec62f2fb4', + '28292a2b2d2e2f30323334353738393a3c3d3e3f41424344464748494b4c4d4e', + 'ecb-tbl-256: I=2'), + ('a291d86301a4a739f7392173aa3c604c', '6585c8f43d13a6beab6419fc5935b9d0', + '50515253555657585a5b5c5d5f60616264656667696a6b6c6e6f707173747576', + 'ecb-tbl-256: I=3'), + ('4264b2696498de4df79788a9f83e9390', '2a5b56a596680fcc0e05f5e0f151ecae', + '78797a7b7d7e7f80828384858788898a8c8d8e8f91929394969798999b9c9d9e', + 'ecb-tbl-256: I=4'), + ('ee9932b3721804d5a83ef5949245b6f6', 'f5d6ff414fd2c6181494d20c37f2b8c4', + 'a0a1a2a3a5a6a7a8aaabacadafb0b1b2b4b5b6b7b9babbbcbebfc0c1c3c4c5c6', + 'ecb-tbl-256: I=5'), + ('e6248f55c5fdcbca9cbbb01c88a2ea77', '85399c01f59fffb5204f19f8482f00b8', + 'c8c9cacbcdcecfd0d2d3d4d5d7d8d9dadcdddedfe1e2e3e4e6e7e8e9ebecedee', + 'ecb-tbl-256: I=6'), + ('b8358e41b9dff65fd461d55a99266247', '92097b4c88a041ddf98144bc8d22e8e7', + 'f0f1f2f3f5f6f7f8fafbfcfdfe01000204050607090a0b0c0e0f101113141516', + 'ecb-tbl-256: I=7'), + ('f0e2d72260af58e21e015ab3a4c0d906', '89bd5b73b356ab412aef9f76cea2d65c', + '18191a1b1d1e1f20222324252728292a2c2d2e2f31323334363738393b3c3d3e', + 'ecb-tbl-256: I=8'), + ('475b8b823ce8893db3c44a9f2a379ff7', '2536969093c55ff9454692f2fac2f530', + '40414243454647484a4b4c4d4f50515254555657595a5b5c5e5f606163646566', + 'ecb-tbl-256: I=9'), + ('688f5281945812862f5f3076cf80412f', '07fc76a872843f3f6e0081ee9396d637', + '68696a6b6d6e6f70727374757778797a7c7d7e7f81828384868788898b8c8d8e', + 'ecb-tbl-256: I=10'), + ('08d1d2bc750af553365d35e75afaceaa', 'e38ba8ec2aa741358dcc93e8f141c491', + '90919293959697989a9b9c9d9fa0a1a2a4a5a6a7a9aaabacaeafb0b1b3b4b5b6', + 'ecb-tbl-256: I=11'), + ('8707121f47cc3efceca5f9a8474950a1', 'd028ee23e4a89075d0b03e868d7d3a42', + 'b8b9babbbdbebfc0c2c3c4c5c7c8c9cacccdcecfd1d2d3d4d6d7d8d9dbdcddde', + 'ecb-tbl-256: I=12'), + ('e51aa0b135dba566939c3b6359a980c5', '8cd9423dfc459e547155c5d1d522e540', + 'e0e1e2e3e5e6e7e8eaebecedeff0f1f2f4f5f6f7f9fafbfcfefe010103040506', + 'ecb-tbl-256: I=13'), + ('069a007fc76a459f98baf917fedf9521', '080e9517eb1677719acf728086040ae3', + '08090a0b0d0e0f10121314151718191a1c1d1e1f21222324262728292b2c2d2e', + 'ecb-tbl-256: I=14'), + ('726165c1723fbcf6c026d7d00b091027', '7c1700211a3991fc0ecded0ab3e576b0', + '30313233353637383a3b3c3d3f40414244454647494a4b4c4e4f505153545556', + 'ecb-tbl-256: I=15'), + ('d7c544de91d55cfcde1f84ca382200ce', 'dabcbcc855839251db51e224fbe87435', + '58595a5b5d5e5f60626364656768696a6c6d6e6f71727374767778797b7c7d7e', + 'ecb-tbl-256: I=16'), + ('fed3c9a161b9b5b2bd611b41dc9da357', '68d56fad0406947a4dd27a7448c10f1d', + '80818283858687888a8b8c8d8f90919294959697999a9b9c9e9fa0a1a3a4a5a6', + 'ecb-tbl-256: I=17'), + ('4f634cdc6551043409f30b635832cf82', 'da9a11479844d1ffee24bbf3719a9925', + 'a8a9aaabadaeafb0b2b3b4b5b7b8b9babcbdbebfc1c2c3c4c6c7c8c9cbcccdce', + 'ecb-tbl-256: I=18'), + ('109ce98db0dfb36734d9f3394711b4e6', '5e4ba572f8d23e738da9b05ba24b8d81', + 'd0d1d2d3d5d6d7d8dadbdcdddfe0e1e2e4e5e6e7e9eaebeceeeff0f1f3f4f5f6', + 'ecb-tbl-256: I=19'), + ('4ea6dfaba2d8a02ffdffa89835987242', 'a115a2065d667e3f0b883837a6e903f8', + '70717273757677787a7b7c7d7f80818284858687898a8b8c8e8f909193949596', + 'ecb-tbl-256: I=20'), + ('5ae094f54af58e6e3cdbf976dac6d9ef', '3e9e90dc33eac2437d86ad30b137e66e', + '98999a9b9d9e9fa0a2a3a4a5a7a8a9aaacadaeafb1b2b3b4b6b7b8b9bbbcbdbe', + 'ecb-tbl-256: I=21'), + ('764d8e8e0f29926dbe5122e66354fdbe', '01ce82d8fbcdae824cb3c48e495c3692', + 'c0c1c2c3c5c6c7c8cacbcccdcfd0d1d2d4d5d6d7d9dadbdcdedfe0e1e3e4e5e6', + 'ecb-tbl-256: I=22'), + ('3f0418f888cdf29a982bf6b75410d6a9', '0c9cff163ce936faaf083cfd3dea3117', + 'e8e9eaebedeeeff0f2f3f4f5f7f8f9fafcfdfeff01020304060708090b0c0d0e', + 'ecb-tbl-256: I=23'), + ('e4a3e7cb12cdd56aa4a75197a9530220', '5131ba9bd48f2bba85560680df504b52', + '10111213151617181a1b1c1d1f20212224252627292a2b2c2e2f303133343536', + 'ecb-tbl-256: I=24'), + ('211677684aac1ec1a160f44c4ebf3f26', '9dc503bbf09823aec8a977a5ad26ccb2', + '38393a3b3d3e3f40424344454748494a4c4d4e4f51525354565758595b5c5d5e', + 'ecb-tbl-256: I=25'), + ('d21e439ff749ac8f18d6d4b105e03895', '9a6db0c0862e506a9e397225884041d7', + '60616263656667686a6b6c6d6f70717274757677797a7b7c7e7f808183848586', + 'ecb-tbl-256: I=26'), + ('d9f6ff44646c4725bd4c0103ff5552a7', '430bf9570804185e1ab6365fc6a6860c', + '88898a8b8d8e8f90929394959798999a9c9d9e9fa1a2a3a4a6a7a8a9abacadae', + 'ecb-tbl-256: I=27'), + ('0b1256c2a00b976250cfc5b0c37ed382', '3525ebc02f4886e6a5a3762813e8ce8a', + 'b0b1b2b3b5b6b7b8babbbcbdbfc0c1c2c4c5c6c7c9cacbcccecfd0d1d3d4d5d6', + 'ecb-tbl-256: I=28'), + ('b056447ffc6dc4523a36cc2e972a3a79', '07fa265c763779cce224c7bad671027b', + 'd8d9dadbdddedfe0e2e3e4e5e7e8e9eaecedeeeff1f2f3f4f6f7f8f9fbfcfdfe', + 'ecb-tbl-256: I=29'), + ('5e25ca78f0de55802524d38da3fe4456', 'e8b72b4e8be243438c9fff1f0e205872', + '00010203050607080a0b0c0d0f10111214151617191a1b1c1e1f202123242526', + 'ecb-tbl-256: I=30'), + ('a5bcf4728fa5eaad8567c0dc24675f83', '109d4f999a0e11ace1f05e6b22cbcb50', + '28292a2b2d2e2f30323334353738393a3c3d3e3f41424344464748494b4c4d4e', + 'ecb-tbl-256: I=31'), + ('814e59f97ed84646b78b2ca022e9ca43', '45a5e8d4c3ed58403ff08d68a0cc4029', + '50515253555657585a5b5c5d5f60616264656667696a6b6c6e6f707173747576', + 'ecb-tbl-256: I=32'), + ('15478beec58f4775c7a7f5d4395514d7', '196865964db3d417b6bd4d586bcb7634', + '78797a7b7d7e7f80828384858788898a8c8d8e8f91929394969798999b9c9d9e', + 'ecb-tbl-256: I=33'), + ('253548ffca461c67c8cbc78cd59f4756', '60436ad45ac7d30d99195f815d98d2ae', + 'a0a1a2a3a5a6a7a8aaabacadafb0b1b2b4b5b6b7b9babbbcbebfc0c1c3c4c5c6', + 'ecb-tbl-256: I=34'), + ('fd7ad8d73b9b0f8cc41600640f503d65', 'bb07a23f0b61014b197620c185e2cd75', + 'c8c9cacbcdcecfd0d2d3d4d5d7d8d9dadcdddedfe1e2e3e4e6e7e8e9ebecedee', + 'ecb-tbl-256: I=35'), + ('06199de52c6cbf8af954cd65830bcd56', '5bc0b2850129c854423aff0751fe343b', + 'f0f1f2f3f5f6f7f8fafbfcfdfe01000204050607090a0b0c0e0f101113141516', + 'ecb-tbl-256: I=36'), + ('f17c4ffe48e44c61bd891e257e725794', '7541a78f96738e6417d2a24bd2beca40', + '18191a1b1d1e1f20222324252728292a2c2d2e2f31323334363738393b3c3d3e', + 'ecb-tbl-256: I=37'), + ('9a5b4a402a3e8a59be6bf5cd8154f029', 'b0a303054412882e464591f1546c5b9e', + '40414243454647484a4b4c4d4f50515254555657595a5b5c5e5f606163646566', + 'ecb-tbl-256: I=38'), + ('79bd40b91a7e07dc939d441782ae6b17', '778c06d8a355eeee214fcea14b4e0eef', + '68696a6b6d6e6f70727374757778797a7c7d7e7f81828384868788898b8c8d8e', + 'ecb-tbl-256: I=39'), + ('d8ceaaf8976e5fbe1012d8c84f323799', '09614206d15cbace63227d06db6beebb', + '90919293959697989a9b9c9d9fa0a1a2a4a5a6a7a9aaabacaeafb0b1b3b4b5b6', + 'ecb-tbl-256: I=40'), + ('3316e2751e2e388b083da23dd6ac3fbe', '41b97fb20e427a9fdbbb358d9262255d', + 'b8b9babbbdbebfc0c2c3c4c5c7c8c9cacccdcecfd1d2d3d4d6d7d8d9dbdcddde', + 'ecb-tbl-256: I=41'), + ('8b7cfbe37de7dca793521819242c5816', 'c1940f703d845f957652c2d64abd7adf', + 'e0e1e2e3e5e6e7e8eaebecedeff0f1f2f4f5f6f7f9fafbfcfefe010103040506', + 'ecb-tbl-256: I=42'), + ('f23f033c0eebf8ec55752662fd58ce68', 'd2d44fcdae5332343366db297efcf21b', + '08090a0b0d0e0f10121314151718191a1c1d1e1f21222324262728292b2c2d2e', + 'ecb-tbl-256: I=43'), + ('59eb34f6c8bdbacc5fc6ad73a59a1301', 'ea8196b79dbe167b6aa9896e287eed2b', + '30313233353637383a3b3c3d3f40414244454647494a4b4c4e4f505153545556', + 'ecb-tbl-256: I=44'), + ('dcde8b6bd5cf7cc22d9505e3ce81261a', 'd6b0b0c4ba6c7dbe5ed467a1e3f06c2d', + '58595a5b5d5e5f60626364656768696a6c6d6e6f71727374767778797b7c7d7e', + 'ecb-tbl-256: I=45'), + ('e33cf7e524fed781e7042ff9f4b35dc7', 'ec51eb295250c22c2fb01816fb72bcae', + '80818283858687888a8b8c8d8f90919294959697999a9b9c9e9fa0a1a3a4a5a6', + 'ecb-tbl-256: I=46'), + ('27963c8facdf73062867d164df6d064c', 'aded6630a07ce9c7408a155d3bd0d36f', + 'a8a9aaabadaeafb0b2b3b4b5b7b8b9babcbdbebfc1c2c3c4c6c7c8c9cbcccdce', + 'ecb-tbl-256: I=47'), + ('77b1ce386b551b995f2f2a1da994eef8', '697c9245b9937f32f5d1c82319f0363a', + 'd0d1d2d3d5d6d7d8dadbdcdddfe0e1e2e4e5e6e7e9eaebeceeeff0f1f3f4f5f6', + 'ecb-tbl-256: I=48'), + ('f083388b013679efcf0bb9b15d52ae5c', 'aad5ad50c6262aaec30541a1b7b5b19c', + 'f8f9fafbfdfefe00020304050708090a0c0d0e0f11121314161718191b1c1d1e', + 'ecb-tbl-256: I=49'), + ('c5009e0dab55db0abdb636f2600290c8', '7d34b893855341ec625bd6875ac18c0d', + '20212223252627282a2b2c2d2f30313234353637393a3b3c3e3f404143444546', + 'ecb-tbl-256: I=50'), + ('7804881e26cd532d8514d3683f00f1b9', '7ef05105440f83862f5d780e88f02b41', + '48494a4b4d4e4f50525354555758595a5c5d5e5f61626364666768696b6c6d6e', + 'ecb-tbl-256: I=51'), + ('46cddcd73d1eb53e675ca012870a92a3', 'c377c06403382061af2c9c93a8e70df6', + '70717273757677787a7b7c7d7f80818284858687898a8b8c8e8f909193949596', + 'ecb-tbl-256: I=52'), + ('a9fb44062bb07fe130a8e8299eacb1ab', '1dbdb3ffdc052dacc83318853abc6de5', + '98999a9b9d9e9fa0a2a3a4a5a7a8a9aaacadaeafb1b2b3b4b6b7b8b9bbbcbdbe', + 'ecb-tbl-256: I=53'), + ('2b6ff8d7a5cc3a28a22d5a6f221af26b', '69a6eab00432517d0bf483c91c0963c7', + 'c0c1c2c3c5c6c7c8cacbcccdcfd0d1d2d4d5d6d7d9dadbdcdedfe0e1e3e4e5e6', + 'ecb-tbl-256: I=54'), + ('1a9527c29b8add4b0e3e656dbb2af8b4', '0797f41dc217c80446e1d514bd6ab197', + 'e8e9eaebedeeeff0f2f3f4f5f7f8f9fafcfdfeff01020304060708090b0c0d0e', + 'ecb-tbl-256: I=55'), + ('7f99cf2c75244df015eb4b0c1050aeae', '9dfd76575902a637c01343c58e011a03', + '10111213151617181a1b1c1d1f20212224252627292a2b2c2e2f303133343536', + 'ecb-tbl-256: I=56'), + ('e84ff85b0d9454071909c1381646c4ed', 'acf4328ae78f34b9fa9b459747cc2658', + '38393a3b3d3e3f40424344454748494a4c4d4e4f51525354565758595b5c5d5e', + 'ecb-tbl-256: I=57'), + ('89afd40f99521280d5399b12404f6db4', 'b0479aea12bac4fe2384cf98995150c6', + '60616263656667686a6b6c6d6f70717274757677797a7b7c7e7f808183848586', + 'ecb-tbl-256: I=58'), + ('a09ef32dbc5119a35ab7fa38656f0329', '9dd52789efe3ffb99f33b3da5030109a', + '88898a8b8d8e8f90929394959798999a9c9d9e9fa1a2a3a4a6a7a8a9abacadae', + 'ecb-tbl-256: I=59'), + ('61773457f068c376c7829b93e696e716', 'abbb755e4621ef8f1214c19f649fb9fd', + 'b0b1b2b3b5b6b7b8babbbcbdbfc0c1c2c4c5c6c7c9cacbcccecfd0d1d3d4d5d6', + 'ecb-tbl-256: I=60'), + ('a34f0cae726cce41dd498747d891b967', 'da27fb8174357bce2bed0e7354f380f9', + 'd8d9dadbdddedfe0e2e3e4e5e7e8e9eaecedeeeff1f2f3f4f6f7f8f9fbfcfdfe', + 'ecb-tbl-256: I=61'), + ('856f59496c7388ee2d2b1a27b7697847', 'c59a0663f0993838f6e5856593bdc5ef', + '00010203050607080a0b0c0d0f10111214151617191a1b1c1e1f202123242526', + 'ecb-tbl-256: I=62'), + ('cb090c593ef7720bd95908fb93b49df4', 'ed60b264b5213e831607a99c0ce5e57e', + '28292a2b2d2e2f30323334353738393a3c3d3e3f41424344464748494b4c4d4e', + 'ecb-tbl-256: I=63'), + ('a0ac75cd2f1923d460fc4d457ad95baf', 'e50548746846f3eb77b8c520640884ed', + '50515253555657585a5b5c5d5f60616264656667696a6b6c6e6f707173747576', + 'ecb-tbl-256: I=64'), + ('2a2b282974777689e8e9eeef525d5c5f', '28282cc7d21d6a2923641e52d188ef0c', + '78797a7b7d7e7f80828384858788898a8c8d8e8f91929394969798999b9c9d9e', + 'ecb-tbl-256: I=65'), + ('909192939390919e0f0e09089788898a', '0dfa5b02abb18e5a815305216d6d4f8e', + 'a0a1a2a3a5a6a7a8aaabacadafb0b1b2b4b5b6b7b9babbbcbebfc0c1c3c4c5c6', + 'ecb-tbl-256: I=66'), + ('777675748d8e8f907170777649464744', '7359635c0eecefe31d673395fb46fb99', + 'c8c9cacbcdcecfd0d2d3d4d5d7d8d9dadcdddedfe1e2e3e4e6e7e8e9ebecedee', + 'ecb-tbl-256: I=67'), + ('717073720605040b2d2c2b2a05fafbf9', '73c679f7d5aef2745c9737bb4c47fb36', + 'f0f1f2f3f5f6f7f8fafbfcfdfe01000204050607090a0b0c0e0f101113141516', + 'ecb-tbl-256: I=68'), + ('64656667fefdfcc31b1a1d1ca5aaaba8', 'b192bd472a4d2eafb786e97458967626', + '18191a1b1d1e1f20222324252728292a2c2d2e2f31323334363738393b3c3d3e', + 'ecb-tbl-256: I=69'), + ('dbdad9d86a696867b5b4b3b2c8d7d6d5', '0ec327f6c8a2b147598ca3fde61dc6a4', + '40414243454647484a4b4c4d4f50515254555657595a5b5c5e5f606163646566', + 'ecb-tbl-256: I=70'), + ('5c5d5e5fe3e0e1fe31303736333c3d3e', 'fc418eb3c41b859b38d4b6f646629729', + '68696a6b6d6e6f70727374757778797a7c7d7e7f81828384868788898b8c8d8e', + 'ecb-tbl-256: I=71'), + ('545556574b48494673727574546b6a69', '30249e5ac282b1c981ea64b609f3a154', + '90919293959697989a9b9c9d9fa0a1a2a4a5a6a7a9aaabacaeafb0b1b3b4b5b6', + 'ecb-tbl-256: I=72'), + ('ecedeeefc6c5c4bb56575051f5fafbf8', '5e6e08646d12150776bb43c2d78a9703', + 'b8b9babbbdbebfc0c2c3c4c5c7c8c9cacccdcecfd1d2d3d4d6d7d8d9dbdcddde', + 'ecb-tbl-256: I=73'), + ('464744452724252ac9c8cfced2cdcccf', 'faeb3d5de652cd3447dceb343f30394a', + 'e0e1e2e3e5e6e7e8eaebecedeff0f1f2f4f5f6f7f9fafbfcfefe010103040506', + 'ecb-tbl-256: I=74'), + ('e6e7e4e54142435c878681801c131211', 'a8e88706823f6993ef80d05c1c7b2cf0', + '08090a0b0d0e0f10121314151718191a1c1d1e1f21222324262728292b2c2d2e', + 'ecb-tbl-256: I=75'), + ('72737071cfcccdc2f9f8fffe710e0f0c', '8ced86677e6e00a1a1b15968f2d3cce6', + '30313233353637383a3b3c3d3f40414244454647494a4b4c4e4f505153545556', + 'ecb-tbl-256: I=76'), + ('505152537370714ec3c2c5c4010e0f0c', '9fc7c23858be03bdebb84e90db6786a9', + '58595a5b5d5e5f60626364656768696a6c6d6e6f71727374767778797b7c7d7e', + 'ecb-tbl-256: I=77'), + ('a8a9aaab5c5f5e51aeafa8a93d222320', 'b4fbd65b33f70d8cf7f1111ac4649c36', + '80818283858687888a8b8c8d8f90919294959697999a9b9c9e9fa0a1a3a4a5a6', + 'ecb-tbl-256: I=78'), + ('dedfdcddf6f5f4eb10111617fef1f0f3', 'c5c32d5ed03c4b53cc8c1bd0ef0dbbf6', + 'a8a9aaabadaeafb0b2b3b4b5b7b8b9babcbdbebfc1c2c3c4c6c7c8c9cbcccdce', + 'ecb-tbl-256: I=79'), + ('bdbcbfbe5e5d5c530b0a0d0cfac5c4c7', 'd1a7f03b773e5c212464b63709c6a891', + 'd0d1d2d3d5d6d7d8dadbdcdddfe0e1e2e4e5e6e7e9eaebeceeeff0f1f3f4f5f6', + 'ecb-tbl-256: I=80'), + ('8a8b8889050606f8f4f5f2f3636c6d6e', '6b7161d8745947ac6950438ea138d028', + 'f8f9fafbfdfefe00020304050708090a0c0d0e0f11121314161718191b1c1d1e', + 'ecb-tbl-256: I=81'), + ('a6a7a4a54d4e4f40b2b3b4b539262724', 'fd47a9f7e366ee7a09bc508b00460661', + '20212223252627282a2b2c2d2f30313234353637393a3b3c3e3f404143444546', + 'ecb-tbl-256: I=82'), + ('9c9d9e9fe9eaebf40e0f08099b949596', '00d40b003dc3a0d9310b659b98c7e416', + '48494a4b4d4e4f50525354555758595a5c5d5e5f61626364666768696b6c6d6e', + 'ecb-tbl-256: I=83'), + ('2d2c2f2e1013121dcccdcacbed121310', 'eea4c79dcc8e2bda691f20ac48be0717', + '70717273757677787a7b7c7d7f80818284858687898a8b8c8e8f909193949596', + 'ecb-tbl-256: I=84'), + ('f4f5f6f7edeeefd0eaebecedf7f8f9fa', 'e78f43b11c204403e5751f89d05a2509', + '98999a9b9d9e9fa0a2a3a4a5a7a8a9aaacadaeafb1b2b3b4b6b7b8b9bbbcbdbe', + 'ecb-tbl-256: I=85'), + ('3d3c3f3e282b2a2573727574150a0b08', 'd0f0e3d1f1244bb979931e38dd1786ef', + 'c0c1c2c3c5c6c7c8cacbcccdcfd0d1d2d4d5d6d7d9dadbdcdedfe0e1e3e4e5e6', + 'ecb-tbl-256: I=86'), + ('b6b7b4b5f8fbfae5b4b5b2b3a0afaead', '042e639dc4e1e4dde7b75b749ea6f765', + 'e8e9eaebedeeeff0f2f3f4f5f7f8f9fafcfdfeff01020304060708090b0c0d0e', + 'ecb-tbl-256: I=87'), + ('b7b6b5b4989b9a95878681809ba4a5a6', 'bc032fdd0efe29503a980a7d07ab46a8', + '10111213151617181a1b1c1d1f20212224252627292a2b2c2e2f303133343536', + 'ecb-tbl-256: I=88'), + ('a8a9aaabe5e6e798e9e8efee4748494a', '0c93ac949c0da6446effb86183b6c910', + '38393a3b3d3e3f40424344454748494a4c4d4e4f51525354565758595b5c5d5e', + 'ecb-tbl-256: I=89'), + ('ecedeeefd9dadbd4b9b8bfbe657a7b78', 'e0d343e14da75c917b4a5cec4810d7c2', + '60616263656667686a6b6c6d6f70717274757677797a7b7c7e7f808183848586', + 'ecb-tbl-256: I=90'), + ('7f7e7d7c696a6b74cacbcccd929d9c9f', '0eafb821748408279b937b626792e619', + '88898a8b8d8e8f90929394959798999a9c9d9e9fa1a2a3a4a6a7a8a9abacadae', + 'ecb-tbl-256: I=91'), + ('08090a0b0605040bfffef9f8b9c6c7c4', 'fa1ac6e02d23b106a1fef18b274a553f', + 'b0b1b2b3b5b6b7b8babbbcbdbfc0c1c2c4c5c6c7c9cacbcccecfd0d1d3d4d5d6', + 'ecb-tbl-256: I=92'), + ('08090a0bf1f2f3ccfcfdfafb68676665', '0dadfe019cd12368075507df33c1a1e9', + 'd8d9dadbdddedfe0e2e3e4e5e7e8e9eaecedeeeff1f2f3f4f6f7f8f9fbfcfdfe', + 'ecb-tbl-256: I=93'), + ('cacbc8c93a393837050403020d121310', '3a0879b414465d9ffbaf86b33a63a1b9', + '00010203050607080a0b0c0d0f10111214151617191a1b1c1e1f202123242526', + 'ecb-tbl-256: I=94'), + ('e9e8ebea8281809f8f8e8988343b3a39', '62199fadc76d0be1805d3ba0b7d914bf', + '28292a2b2d2e2f30323334353738393a3c3d3e3f41424344464748494b4c4d4e', + 'ecb-tbl-256: I=95'), + ('515053524645444bd0d1d6d7340b0a09', '1b06d6c5d333e742730130cf78e719b4', + '50515253555657585a5b5c5d5f60616264656667696a6b6c6e6f707173747576', + 'ecb-tbl-256: I=96'), + ('42434041ecefee1193929594c6c9c8cb', 'f1f848824c32e9dcdcbf21580f069329', + '78797a7b7d7e7f80828384858788898a8c8d8e8f91929394969798999b9c9d9e', + 'ecb-tbl-256: I=97'), + ('efeeedecc2c1c0cf76777071455a5b58', '1a09050cbd684f784d8e965e0782f28a', + 'a0a1a2a3a5a6a7a8aaabacadafb0b1b2b4b5b6b7b9babbbcbebfc0c1c3c4c5c6', + 'ecb-tbl-256: I=98'), + ('5f5e5d5c3f3c3d221d1c1b1a19161714', '79c2969e7ded2ba7d088f3f320692360', + 'c8c9cacbcdcecfd0d2d3d4d5d7d8d9dadcdddedfe1e2e3e4e6e7e8e9ebecedee', + 'ecb-tbl-256: I=99'), + ('000102034142434c1c1d1a1b8d727371', '091a658a2f7444c16accb669450c7b63', + 'f0f1f2f3f5f6f7f8fafbfcfdfe01000204050607090a0b0c0e0f101113141516', + 'ecb-tbl-256: I=100'), + ('8e8f8c8db1b2b38c56575051050a0b08', '97c1e3a72cca65fa977d5ed0e8a7bbfc', + '18191a1b1d1e1f20222324252728292a2c2d2e2f31323334363738393b3c3d3e', + 'ecb-tbl-256: I=101'), + ('a7a6a5a4e8ebeae57f7e7978cad5d4d7', '70c430c6db9a17828937305a2df91a2a', + '40414243454647484a4b4c4d4f50515254555657595a5b5c5e5f606163646566', + 'ecb-tbl-256: I=102'), + ('8a8b888994979689454443429f909192', '629553457fbe2479098571c7c903fde8', + '68696a6b6d6e6f70727374757778797a7c7d7e7f81828384868788898b8c8d8e', + 'ecb-tbl-256: I=103'), + ('8c8d8e8fe0e3e2ed45444342f1cecfcc', 'a25b25a61f612669e7d91265c7d476ba', + '90919293959697989a9b9c9d9fa0a1a2a4a5a6a7a9aaabacaeafb0b1b3b4b5b6', + 'ecb-tbl-256: I=104'), + ('fffefdfc4c4f4e31d8d9dedfb6b9b8bb', 'eb7e4e49b8ae0f024570dda293254fed', + 'b8b9babbbdbebfc0c2c3c4c5c7c8c9cacccdcecfd1d2d3d4d6d7d8d9dbdcddde', + 'ecb-tbl-256: I=105'), + ('fdfcfffecccfcec12f2e29286679787b', '38fe15d61cca84516e924adce5014f67', + 'e0e1e2e3e5e6e7e8eaebecedeff0f1f2f4f5f6f7f9fafbfcfefe010103040506', + 'ecb-tbl-256: I=106'), + ('67666564bab9b8a77071767719161714', '3ad208492249108c9f3ebeb167ad0583', + '08090a0b0d0e0f10121314151718191a1c1d1e1f21222324262728292b2c2d2e', + 'ecb-tbl-256: I=107'), + ('9a9b98992d2e2f2084858283245b5a59', '299ba9f9bf5ab05c3580fc26edd1ed12', + '30313233353637383a3b3c3d3f40414244454647494a4b4c4e4f505153545556', + 'ecb-tbl-256: I=108'), + ('a4a5a6a70b0809365c5d5a5b2c232221', '19dc705b857a60fb07717b2ea5717781', + '58595a5b5d5e5f60626364656768696a6c6d6e6f71727374767778797b7c7d7e', + 'ecb-tbl-256: I=109'), + ('464744455754555af3f2f5f4afb0b1b2', 'ffc8aeb885b5efcad06b6dbebf92e76b', + '80818283858687888a8b8c8d8f90919294959697999a9b9c9e9fa0a1a3a4a5a6', + 'ecb-tbl-256: I=110'), + ('323330317675746b7273747549464744', 'f58900c5e0b385253ff2546250a0142b', + 'a8a9aaabadaeafb0b2b3b4b5b7b8b9babcbdbebfc1c2c3c4c6c7c8c9cbcccdce', + 'ecb-tbl-256: I=111'), + ('a8a9aaab181b1a15808186872b141516', '2ee67b56280bc462429cee6e3370cbc1', + 'd0d1d2d3d5d6d7d8dadbdcdddfe0e1e2e4e5e6e7e9eaebeceeeff0f1f3f4f5f6', + 'ecb-tbl-256: I=112'), + ('e7e6e5e4202323ddaaabacad343b3a39', '20db650a9c8e9a84ab4d25f7edc8f03f', + 'f8f9fafbfdfefe00020304050708090a0c0d0e0f11121314161718191b1c1d1e', + 'ecb-tbl-256: I=113'), + ('a8a9aaab2221202fedecebea1e010003', '3c36da169525cf818843805f25b78ae5', + '20212223252627282a2b2c2d2f30313234353637393a3b3c3e3f404143444546', + 'ecb-tbl-256: I=114'), + ('f9f8fbfa5f5c5d42424344450e010003', '9a781d960db9e45e37779042fea51922', + '48494a4b4d4e4f50525354555758595a5c5d5e5f61626364666768696b6c6d6e', + 'ecb-tbl-256: I=115'), + ('57565554f5f6f7f89697909120dfdedd', '6560395ec269c672a3c288226efdba77', + '70717273757677787a7b7c7d7f80818284858687898a8b8c8e8f909193949596', + 'ecb-tbl-256: I=116'), + ('f8f9fafbcccfcef1dddcdbda0e010003', '8c772b7a189ac544453d5916ebb27b9a', + '98999a9b9d9e9fa0a2a3a4a5a7a8a9aaacadaeafb1b2b3b4b6b7b8b9bbbcbdbe', + 'ecb-tbl-256: I=117'), + ('d9d8dbda7073727d80818687c2dddcdf', '77ca5468cc48e843d05f78eed9d6578f', + 'c0c1c2c3c5c6c7c8cacbcccdcfd0d1d2d4d5d6d7d9dadbdcdedfe0e1e3e4e5e6', + 'ecb-tbl-256: I=118'), + ('c5c4c7c6080b0a1588898e8f68676665', '72cdcc71dc82c60d4429c9e2d8195baa', + 'e8e9eaebedeeeff0f2f3f4f5f7f8f9fafcfdfeff01020304060708090b0c0d0e', + 'ecb-tbl-256: I=119'), + ('83828180dcdfded186878081f0cfcecd', '8080d68ce60e94b40b5b8b69eeb35afa', + '10111213151617181a1b1c1d1f20212224252627292a2b2c2e2f303133343536', + 'ecb-tbl-256: I=120'), + ('98999a9bdddedfa079787f7e0a050407', '44222d3cde299c04369d58ac0eba1e8e', + '38393a3b3d3e3f40424344454748494a4c4d4e4f51525354565758595b5c5d5e', + 'ecb-tbl-256: I=121'), + ('cecfcccd4f4c4d429f9e9998dfc0c1c2', '9b8721b0a8dfc691c5bc5885dbfcb27a', + '60616263656667686a6b6c6d6f70717274757677797a7b7c7e7f808183848586', + 'ecb-tbl-256: I=122'), + ('404142436665647b29282f2eaba4a5a6', '0dc015ce9a3a3414b5e62ec643384183', + '88898a8b8d8e8f90929394959798999a9c9d9e9fa1a2a3a4a6a7a8a9abacadae', + 'ecb-tbl-256: I=123'), + ('33323130e6e5e4eb23222524dea1a0a3', '705715448a8da412025ce38345c2a148', + 'b0b1b2b3b5b6b7b8babbbcbdbfc0c1c2c4c5c6c7c9cacbcccecfd0d1d3d4d5d6', + 'ecb-tbl-256: I=124'), + ('cfcecdccf6f5f4cbe6e7e0e199969794', 'c32b5b0b6fbae165266c569f4b6ecf0b', + 'd8d9dadbdddedfe0e2e3e4e5e7e8e9eaecedeeeff1f2f3f4f6f7f8f9fbfcfdfe', + 'ecb-tbl-256: I=125'), + ('babbb8b97271707fdcdddadb29363734', '4dca6c75192a01ddca9476af2a521e87', + '00010203050607080a0b0c0d0f10111214151617191a1b1c1e1f202123242526', + 'ecb-tbl-256: I=126'), + ('c9c8cbca4447465926272021545b5a59', '058691e627ecbc36ac07b6db423bd698', + '28292a2b2d2e2f30323334353738393a3c3d3e3f41424344464748494b4c4d4e', + 'ecb-tbl-256: I=127'), + ('050407067477767956575051221d1c1f', '7444527095838fe080fc2bcdd30847eb', + '50515253555657585a5b5c5d5f60616264656667696a6b6c6e6f707173747576', + 'ecb-tbl-256: I=128'), + + # FIPS PUB 800-38A test vectors, 2001 edition. Annex F. + + ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ + '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', + '3ad77bb40d7a3660a89ecaf32466ef97'+'f5d3d58503b9699de785895a96fdbaaf'+ + '43b1cd7f598ece23881b00e3ed030688'+'7b0c785e27e8ad3f8223207104725dd4', + '2b7e151628aed2a6abf7158809cf4f3c', + 'NIST 800-38A, F.1.1, ECB and AES-128'), + + ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ + '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', + 'bd334f1d6e45f25ff712a214571fa5cc'+'974104846d0ad3ad7734ecb3ecee4eef'+ + 'ef7afd2270e2e60adce0ba2face6444e'+'9a4b41ba738d6c72fb16691603c18e0e', + '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', + 'NIST 800-38A, F.1.3, ECB and AES-192'), + + ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ + '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', + 'f3eed1bdb5d2a03c064b5a7e3db181f8'+'591ccb10d410ed26dc5ba74a31362870'+ + 'b6ed21b99ca6f4f9f153e7b1beafed1d'+'23304b7a39f9f3ff067d8d8f9e24ecc7', + '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', + 'NIST 800-38A, F.1.3, ECB and AES-256'), + + ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ + '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', + '7649abac8119b246cee98e9b12e9197d'+'5086cb9b507219ee95db113a917678b2'+ + '73bed6b8e3c1743b7116e69e22229516'+'3ff1caa1681fac09120eca307586e1a7', + '2b7e151628aed2a6abf7158809cf4f3c', + 'NIST 800-38A, F.2.1, CBC and AES-128', + dict(mode='CBC', iv='000102030405060708090a0b0c0d0e0f')), + + ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ + '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', + '4f021db243bc633d7178183a9fa071e8'+'b4d9ada9ad7dedf4e5e738763f69145a'+ + '571b242012fb7ae07fa9baac3df102e0'+'08b0e27988598881d920a9e64f5615cd', + '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', + 'NIST 800-38A, F.2.1, CBC and AES-192', + dict(mode='CBC', iv='000102030405060708090a0b0c0d0e0f')), + + ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ + '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', + 'f58c4c04d6e5f1ba779eabfb5f7bfbd6'+'9cfc4e967edb808d679f777bc6702c7d'+ + '39f23369a9d9bacfa530e26304231461'+'b2eb05e2c39be9fcda6c19078c6a9d1b', + '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', + 'NIST 800-38A, F.2.1, CBC and AES-256', + dict(mode='CBC', iv='000102030405060708090a0b0c0d0e0f')), + + # Skip CFB-1 since it is not supported by PyCrypto + + ('6bc1bee22e409f96e93d7e117393172aae2d','3b79424c9c0dd436bace9e0ed4586a4f32b9', + '2b7e151628aed2a6abf7158809cf4f3c', + 'NIST 800-38A, F.3.7, CFB-8 and AES-128', + dict(mode='CFB', iv='000102030405060708090a0b0c0d0e0f', segment_size=8)), + + ('6bc1bee22e409f96e93d7e117393172aae2d','cda2521ef0a905ca44cd057cbf0d47a0678a', + '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', + 'NIST 800-38A, F.3.9, CFB-8 and AES-192', + dict(mode='CFB', iv='000102030405060708090a0b0c0d0e0f', segment_size=8)), + + ('6bc1bee22e409f96e93d7e117393172aae2d','dc1f1a8520a64db55fcc8ac554844e889700', + '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', + 'NIST 800-38A, F.3.11, CFB-8 and AES-256', + dict(mode='CFB', iv='000102030405060708090a0b0c0d0e0f', segment_size=8)), + + ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ + '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', + '3b3fd92eb72dad20333449f8e83cfb4a'+'c8a64537a0b3a93fcde3cdad9f1ce58b'+ + '26751f67a3cbb140b1808cf187a4f4df'+'c04b05357c5d1c0eeac4c66f9ff7f2e6', + '2b7e151628aed2a6abf7158809cf4f3c', + 'NIST 800-38A, F.3.13, CFB-128 and AES-128', + dict(mode='CFB', iv='000102030405060708090a0b0c0d0e0f', segment_size=128)), + + ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ + '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', + 'cdc80d6fddf18cab34c25909c99a4174'+'67ce7f7f81173621961a2b70171d3d7a'+ + '2e1e8a1dd59b88b1c8e60fed1efac4c9'+'c05f9f9ca9834fa042ae8fba584b09ff', + '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', + 'NIST 800-38A, F.3.15, CFB-128 and AES-192', + dict(mode='CFB', iv='000102030405060708090a0b0c0d0e0f', segment_size=128)), + + ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ + '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', + 'dc7e84bfda79164b7ecd8486985d3860'+'39ffed143b28b1c832113c6331e5407b'+ + 'df10132415e54b92a13ed0a8267ae2f9'+'75a385741ab9cef82031623d55b1e471', + '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', + 'NIST 800-38A, F.3.17, CFB-128 and AES-256', + dict(mode='CFB', iv='000102030405060708090a0b0c0d0e0f', segment_size=128)), + + ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ + '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', + '3b3fd92eb72dad20333449f8e83cfb4a'+'7789508d16918f03f53c52dac54ed825'+ + '9740051e9c5fecf64344f7a82260edcc'+'304c6528f659c77866a510d9c1d6ae5e', + '2b7e151628aed2a6abf7158809cf4f3c', + 'NIST 800-38A, F.4.1, OFB and AES-128', + dict(mode='OFB', iv='000102030405060708090a0b0c0d0e0f')), + + ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ + '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', + 'cdc80d6fddf18cab34c25909c99a4174'+'fcc28b8d4c63837c09e81700c1100401'+ + '8d9a9aeac0f6596f559c6d4daf59a5f2'+'6d9f200857ca6c3e9cac524bd9acc92a', + '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', + 'NIST 800-38A, F.4.3, OFB and AES-192', + dict(mode='OFB', iv='000102030405060708090a0b0c0d0e0f')), + + ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ + '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', + 'dc7e84bfda79164b7ecd8486985d3860'+'4febdc6740d20b3ac88f6ad82a4fb08d'+ + '71ab47a086e86eedf39d1c5bba97c408'+'0126141d67f37be8538f5a8be740e484', + '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', + 'NIST 800-38A, F.4.5, OFB and AES-256', + dict(mode='OFB', iv='000102030405060708090a0b0c0d0e0f')), + + ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ + '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', + '874d6191b620e3261bef6864990db6ce'+'9806f66b7970fdff8617187bb9fffdff'+ + '5ae4df3edbd5d35e5b4f09020db03eab'+'1e031dda2fbe03d1792170a0f3009cee', + '2b7e151628aed2a6abf7158809cf4f3c', + 'NIST 800-38A, F.5.1, CTR and AES-128', + dict(mode='CTR', ctr_params=dict(nbits=16, prefix='f0f1f2f3f4f5f6f7f8f9fafbfcfd', initial_value=0xfeff))), + + ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ + '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', + '1abc932417521ca24f2b0459fe7e6e0b'+'090339ec0aa6faefd5ccc2c6f4ce8e94'+ + '1e36b26bd1ebc670d1bd1d665620abf7'+'4f78a7f6d29809585a97daec58c6b050', + '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', + 'NIST 800-38A, F.5.3, CTR and AES-192', + dict(mode='CTR', ctr_params=dict(nbits=16, prefix='f0f1f2f3f4f5f6f7f8f9fafbfcfd', initial_value=0xfeff))), + + ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ + '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', + '601ec313775789a5b7a7f504bbf3d228'+'f443e3ca4d62b59aca84e990cacaf5c5'+ + '2b0930daa23de94ce87017ba2d84988d'+'dfc9c58db67aada613c2dd08457941a6', + '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', + 'NIST 800-38A, F.5.5, CTR and AES-256', + dict(mode='CTR', ctr_params=dict(nbits=16, prefix='f0f1f2f3f4f5f6f7f8f9fafbfcfd', initial_value=0xfeff))), + + # RFC 3686 test vectors + # This is a list of (plaintext, ciphertext, key[, description[, params]]) tuples. + ('53696e676c6520626c6f636b206d7367', 'e4095d4fb7a7b3792d6175a3261311b8', + 'ae6852f8121067cc4bf7a5765577f39e', + 'RFC 3686 Test Vector #1: Encrypting 16 octets using AES-CTR with 128-bit key', + dict(mode='CTR', ctr_params=dict(nbits=32, prefix='00000030'+'0000000000000000'))), + ('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', + '5104a106168a72d9790d41ee8edad388eb2e1efc46da57c8fce630df9141be28', + '7e24067817fae0d743d6ce1f32539163', + 'RFC 3686 Test Vector #2: Encrypting 32 octets using AES-CTR with 128-bit key', + dict(mode='CTR', ctr_params=dict(nbits=32, prefix='006cb6db'+'c0543b59da48d90b'))), + ('000102030405060708090a0b0c0d0e0f'+'101112131415161718191a1b1c1d1e1f'+'20212223', + 'c1cf48a89f2ffdd9cf4652e9efdb72d7'+'4540a42bde6d7836d59a5ceaaef31053'+'25b2072f', + '7691be035e5020a8ac6e618529f9a0dc', + 'RFC 3686 Test Vector #3: Encrypting 36 octets using AES-CTR with 128-bit key', + dict(mode='CTR', ctr_params=dict(nbits=32, prefix='00e0017b'+'27777f3f4a1786f0'))), + ('53696e676c6520626c6f636b206d7367', + '4b55384fe259c9c84e7935a003cbe928', + '16af5b145fc9f579c175f93e3bfb0eed'+'863d06ccfdb78515', + 'RFC 3686 Test Vector #4: Encrypting 16 octets using AES-CTR with 192-bit key', + dict(mode='CTR', ctr_params=dict(nbits=32, prefix='00000048'+'36733c147d6d93cb'))), + ('000102030405060708090a0b0c0d0e0f'+'101112131415161718191a1b1c1d1e1f', + '453243fc609b23327edfaafa7131cd9f'+'8490701c5ad4a79cfc1fe0ff42f4fb00', + '7c5cb2401b3dc33c19e7340819e0f69c'+'678c3db8e6f6a91a', + 'RFC 3686 Test Vector #5: Encrypting 32 octets using AES-CTR with 192-bit key', + dict(mode='CTR', ctr_params=dict(nbits=32, prefix='0096b03b'+'020c6eadc2cb500d'))), + ('000102030405060708090a0b0c0d0e0f'+'101112131415161718191a1b1c1d1e1f'+'20212223', + '96893fc55e5c722f540b7dd1ddf7e758'+'d288bc95c69165884536c811662f2188'+'abee0935', + '02bf391ee8ecb159b959617b0965279b'+'f59b60a786d3e0fe', + 'RFC 3686 Test Vector #6: Encrypting 36 octets using AES-CTR with 192-bit key', + dict(mode='CTR', ctr_params=dict(nbits=32, prefix='0007bdfd'+'5cbd60278dcc0912'))), + ('53696e676c6520626c6f636b206d7367', + '145ad01dbf824ec7560863dc71e3e0c0', + '776beff2851db06f4c8a0542c8696f6c'+'6a81af1eec96b4d37fc1d689e6c1c104', + 'RFC 3686 Test Vector #7: Encrypting 16 octets using AES-CTR with 256-bit key', + dict(mode='CTR', ctr_params=dict(nbits=32, prefix='00000060'+'db5672c97aa8f0b2'))), + ('000102030405060708090a0b0c0d0e0f'+'101112131415161718191a1b1c1d1e1f', + 'f05e231b3894612c49ee000b804eb2a9'+'b8306b508f839d6a5530831d9344af1c', + 'f6d66d6bd52d59bb0796365879eff886'+'c66dd51a5b6a99744b50590c87a23884', + 'RFC 3686 Test Vector #8: Encrypting 32 octets using AES-CTR with 256-bit key', + dict(mode='CTR', ctr_params=dict(nbits=32, prefix='00faac24'+'c1585ef15a43d875'))), + ('000102030405060708090a0b0c0d0e0f'+'101112131415161718191a1b1c1d1e1f'+'20212223', + 'eb6c52821d0bbbf7ce7594462aca4faa'+'b407df866569fd07f48cc0b583d6071f'+'1ec0e6b8', + 'ff7a617ce69148e4f1726e2f43581de2'+'aa62d9f805532edff1eed687fb54153d', + 'RFC 3686 Test Vector #9: Encrypting 36 octets using AES-CTR with 256-bit key', + dict(mode='CTR', ctr_params=dict(nbits=32, prefix='001cc5b7'+'51a51d70a1c11148'))), + + # The following test vectors have been generated with gpg v1.4.0. + # The command line used was: + # + # gpg -c -z 0 --cipher-algo AES --passphrase secret_passphrase \ + # --disable-mdc --s2k-mode 0 --output ct pt + # + # As result, the content of the file 'pt' is encrypted with a key derived + # from 'secret_passphrase' and written to file 'ct'. + # Test vectors must be extracted from 'ct', which is a collection of + # TLVs (see RFC4880 for all details): + # - the encrypted data (with the encrypted IV as prefix) is the payload + # of the TLV with tag 9 (Symmetrical Encrypted Data Packet). + # This is the ciphertext in the test vector. + # - inside the encrypted part, there is a further layer of TLVs. One must + # look for tag 11 (Literal Data Packet); in its payload, after a short + # but time dependent header, there is the content of file 'pt'. + # In the test vector, the plaintext is the complete set of TLVs that gets + # encrypted. It is not just the content of 'pt'. + # - the key is the leftmost 16 bytes of the SHA1 digest of the password. + # The test vector contains such shortened digest. + # + # Note that encryption uses a clear IV, and decryption an encrypted IV + ( 'ac18620270744fb4f647426c61636b4361745768697465436174', # Plaintext, 'BlackCatWhiteCat' + 'dc6b9e1f095de609765c59983db5956ae4f63aea7405389d2ebb', # Ciphertext + '5baa61e4c9b93f3f0682250b6cf8331b', # Key (hash of 'password') + 'GPG Test Vector #1', + dict(mode='OPENPGP', iv='3d7d3e62282add7eb203eeba5c800733', encrypted_iv='fd934601ef49cb58b6d9aebca6056bdb96ef' ) ), +] + +def get_tests(config={}): + from Crypto.Cipher import AES + from common import make_block_tests + return make_block_tests(AES, "AES", test_data) + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_AES.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_AES.pyo new file mode 100644 index 0000000000000000000000000000000000000000..63b7504768c3d6766b04a2904dfdb98ee642a8d6 GIT binary patch literal 76637 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 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_ARC2.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_ARC2.py new file mode 100644 index 00000000..b6bc519c --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_ARC2.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Cipher/ARC2.py: Self-test for the Alleged-RC2 cipher +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Cipher.ARC2""" + +__revision__ = "$Id$" + +from common import dict # For compatibility with Python 2.1 and 2.2 + +import unittest +from Crypto.Util.py3compat import * + +# This is a list of (plaintext, ciphertext, key[, description[, extra_params]]) tuples. +test_data = [ + # Test vectors from RFC 2268 + + # 63-bit effective key length + ('0000000000000000', 'ebb773f993278eff', '0000000000000000', + 'RFC2268-1', dict(effective_keylen=63)), + + # 64-bit effective key length + ('ffffffffffffffff', '278b27e42e2f0d49', 'ffffffffffffffff', + 'RFC2268-2', dict(effective_keylen=64)), + ('1000000000000001', '30649edf9be7d2c2', '3000000000000000', + 'RFC2268-3', dict(effective_keylen=64)), + ('0000000000000000', '61a8a244adacccf0', '88', + 'RFC2268-4', dict(effective_keylen=64)), + ('0000000000000000', '6ccf4308974c267f', '88bca90e90875a', + 'RFC2268-5', dict(effective_keylen=64)), + ('0000000000000000', '1a807d272bbe5db1', '88bca90e90875a7f0f79c384627bafb2', + 'RFC2268-6', dict(effective_keylen=64)), + + # 128-bit effective key length + ('0000000000000000', '2269552ab0f85ca6', '88bca90e90875a7f0f79c384627bafb2', + "RFC2268-7", dict(effective_keylen=128)), + ('0000000000000000', '5b78d3a43dfff1f1', + '88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e', + "RFC2268-8", dict(effective_keylen=129)), + + # Test vectors from PyCrypto 2.0.1's testdata.py + # 1024-bit effective key length + ('0000000000000000', '624fb3e887419e48', '5068696c6970476c617373', + 'PCTv201-0'), + ('ffffffffffffffff', '79cadef44c4a5a85', '5068696c6970476c617373', + 'PCTv201-1'), + ('0001020304050607', '90411525b34e4c2c', '5068696c6970476c617373', + 'PCTv201-2'), + ('0011223344556677', '078656aaba61cbfb', '5068696c6970476c617373', + 'PCTv201-3'), + ('0000000000000000', 'd7bcc5dbb4d6e56a', 'ffffffffffffffff', + 'PCTv201-4'), + ('ffffffffffffffff', '7259018ec557b357', 'ffffffffffffffff', + 'PCTv201-5'), + ('0001020304050607', '93d20a497f2ccb62', 'ffffffffffffffff', + 'PCTv201-6'), + ('0011223344556677', 'cb15a7f819c0014d', 'ffffffffffffffff', + 'PCTv201-7'), + ('0000000000000000', '63ac98cdf3843a7a', 'ffffffffffffffff5065746572477265656e6177617953e5ffe553', + 'PCTv201-8'), + ('ffffffffffffffff', '3fb49e2fa12371dd', 'ffffffffffffffff5065746572477265656e6177617953e5ffe553', + 'PCTv201-9'), + ('0001020304050607', '46414781ab387d5f', 'ffffffffffffffff5065746572477265656e6177617953e5ffe553', + 'PCTv201-10'), + ('0011223344556677', 'be09dc81feaca271', 'ffffffffffffffff5065746572477265656e6177617953e5ffe553', + 'PCTv201-11'), + ('0000000000000000', 'e64221e608be30ab', '53e5ffe553', + 'PCTv201-12'), + ('ffffffffffffffff', '862bc60fdcd4d9a9', '53e5ffe553', + 'PCTv201-13'), + ('0001020304050607', '6a34da50fa5e47de', '53e5ffe553', + 'PCTv201-14'), + ('0011223344556677', '584644c34503122c', '53e5ffe553', + 'PCTv201-15'), +] + +class BufferOverflowTest(unittest.TestCase): + # Test a buffer overflow found in older versions of PyCrypto + + def setUp(self): + global ARC2 + from Crypto.Cipher import ARC2 + + def runTest(self): + """ARC2 with keylength > 128""" + key = "x" * 16384 + mode = ARC2.MODE_ECB + self.assertRaises(ValueError, ARC2.new, key, mode) + +def get_tests(config={}): + from Crypto.Cipher import ARC2 + from common import make_block_tests + + tests = make_block_tests(ARC2, "ARC2", test_data) + tests.append(BufferOverflowTest()) + + return tests + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_ARC2.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_ARC2.pyo new file mode 100644 index 0000000000000000000000000000000000000000..5aa4083fb5b874fa49d8d6acbc66441449caaba0 GIT binary patch literal 4075 zcmcgvdvn~j5ntY&WJ{J)RdEtK&r9N_YFcSX5Fp4->$<);(=_p;l$_S8S`J76GOc@P zj+9)_*fZ@oU!s5XtMo%PAE4a@@9d*}e{?!YIRhNX{q163*u{0fy}16b`~SRC!0dSk zf3M@H{^0>=fCHR8IPgGsKzCu-fl(I@y5P}!4~9KB=sDU73|C-ZuYx`YG@l341-%A( z9iD+_S3q9?z2WAIbJA;b(hopyg8m`styf4W>UGeUK)=@Xpx%+T)CrmFkZX<3`TolN_K>En}nvO6eG9+>Iw zuhRjmdI-Jxg}z$;8=q|qFVyr&mqmTMd8Kck)|)u{FFo#~$#W?~nke)c$1NmpkVxjCA19I*ERwc<%^~wb zCB8}gSPIqR5{?VS`>2p)d2WQxgS!6;m$bf>NfE|8Vlr1YXDvCAlY?$egkUQ7Z7d2E zwIH(mD@t`Zk;_IyDxyUCT;gvaLm4^|cL)1t%nx>arz~2nw6PpFR6@m~ z1!>}n5e$6hhd%dFtS=p3;`1O7OynUq7>uID*MuI~0>;9Sb0MNgHhjK}BM~W;t0*XP zo45Fye9$s43Jg@vbz~6Rf;5RBnMnK~HiZx}4~1+&ny4qCX1?Nyw5%xds0rxY_9mc3 z9tb6E93%zm%5_Uhqiz(cB8dxaF*QOZRUM&oUphG!y&@#X!MKzR%@dJ9hf5rZ2#vrq zC`8-&v2$W*b38H3s(^(u&}{`02jLM9xQqjphq2VcR_mz1+>D@!VQ&0H7ja;XDio7J z8#5~e5oatgkss$K^i^JyoCW1tVw?EI5zC9nx4O_=Cn{-+ot<43a;=1Kl`vdt)5bKx z!fcK(zd|nj5EG(kV?@1$n%p==Cr$61nW-I49_?f8eBJ@62+|3v-p0vb1;*M9t`uX( z^W35f>E1R~je@{5=w*PTx`Y#=usaR`Mjj{+TP2q0?Jg2-zf^juEIT>%MdDv9+38R4 z%ZnmiVTs?yFW{!?7Qughcvp?J3P0Nkc9UKI@Z@p*U@|`Zs>}~7Yy&$dsyJ3hraEi{ zA5xnjOAni-a7Y~^BNcX$a|I<d+_b;_Wx)$r8ZoK7cG+#FzR9yvd!KgAdK1vhd{ zZZy&6d-dNr+;Mt3CjUObWwnYEbk@B!&)M&6$+EE;nJjavXBp~rI>guXX9!I>PA@cc ztM5L{Dalnh++|?3yVi3trU=n+G5#DEiy4f8_UL_n`NMd77+wrA-a^p1&${rm3s1W6 za0TjBy5T%S4t(EppZF-xX zEgZ8n7^!lcWd+jR^SpSFSDHhGcap}Dd#(oDc4_UnPse3VhPb`fahZrzWnSGST+oAxdP@7X^xzA6&_AG85n@4)cb6if1wGzdijWI> zyibS^aBArhFX+)R4%DB4VPDd(;e?S1Lb#w;*PY0$c^w%gkt23NdJFA_|&W5*s mZq3{3;=nG^8t&Vw*Y&orhjy`={;y-Ld*$NB+J?7*JNyTwyfiWZ literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_ARC4.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_ARC4.py new file mode 100644 index 00000000..4e039d1c --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_ARC4.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Cipher/ARC4.py: Self-test for the Alleged-RC4 cipher +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Cipher.ARC4""" + +__revision__ = "$Id$" + +from Crypto.Util.py3compat import * + +# This is a list of (plaintext, ciphertext, key[, description]) tuples. +test_data = [ + # Test vectors from Eric Rescorla's message with the subject + # "RC4 compatibility testing", sent to the cipherpunks mailing list on + # September 13, 1994. + # http://cypherpunks.venona.com/date/1994/09/msg00420.html + + ('0123456789abcdef', '75b7878099e0c596', '0123456789abcdef', + 'Test vector 0'), + + ('0000000000000000', '7494c2e7104b0879', '0123456789abcdef', + 'Test vector 1'), + + ('0000000000000000', 'de188941a3375d3a', '0000000000000000', + 'Test vector 2'), + + ('00000000000000000000', 'd6a141a7ec3c38dfbd61', 'ef012345', + 'Test vector 3'), + + ('01' * 512, + '7595c3e6114a09780c4ad452338e1ffd9a1be9498f813d76533449b6778dcad8' + + 'c78a8d2ba9ac66085d0e53d59c26c2d1c490c1ebbe0ce66d1b6b1b13b6b919b8' + + '47c25a91447a95e75e4ef16779cde8bf0a95850e32af9689444fd377108f98fd' + + 'cbd4e726567500990bcc7e0ca3c4aaa304a387d20f3b8fbbcd42a1bd311d7a43' + + '03dda5ab078896ae80c18b0af66dff319616eb784e495ad2ce90d7f772a81747' + + 'b65f62093b1e0db9e5ba532fafec47508323e671327df9444432cb7367cec82f' + + '5d44c0d00b67d650a075cd4b70dedd77eb9b10231b6b5b741347396d62897421' + + 'd43df9b42e446e358e9c11a9b2184ecbef0cd8e7a877ef968f1390ec9b3d35a5' + + '585cb009290e2fcde7b5ec66d9084be44055a619d9dd7fc3166f9487f7cb2729' + + '12426445998514c15d53a18c864ce3a2b7555793988126520eacf2e3066e230c' + + '91bee4dd5304f5fd0405b35bd99c73135d3d9bc335ee049ef69b3867bf2d7bd1' + + 'eaa595d8bfc0066ff8d31509eb0c6caa006c807a623ef84c3d33c195d23ee320' + + 'c40de0558157c822d4b8c569d849aed59d4e0fd7f379586b4b7ff684ed6a189f' + + '7486d49b9c4bad9ba24b96abf924372c8a8fffb10d55354900a77a3db5f205e1' + + 'b99fcd8660863a159ad4abe40fa48934163ddde542a6585540fd683cbfd8c00f' + + '12129a284deacc4cdefe58be7137541c047126c8d49e2755ab181ab7e940b0c0', + '0123456789abcdef', + "Test vector 4"), +] + +def get_tests(config={}): + from Crypto.Cipher import ARC4 + from common import make_stream_tests + return make_stream_tests(ARC4, "ARC4", test_data) + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_ARC4.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_ARC4.pyo new file mode 100644 index 0000000000000000000000000000000000000000..35df5444d63097f0669763bccfb2c5fc9501be60 GIT binary patch literal 2647 zcmcguTaQ#l5bm?HEP_jdiXx)8D(HG))Ax%ph*=Y3qQngNLMEAXcXh+S&g^FAKth5~ z`0U^D!Jp+1(67%SDp_CkOsY?x?yBml`l_pD^82~7$G^;`nLU4A!uuv@{Tl{i>@LQR z-R&4{Fq*J~4R(h!lfdINM3^d{&M=q=D?(A%JQ zKvzKTf_6affi@Yv&*~<-cZ%Jeum#Tifc=bPH(5Ew=qh`-!H$0&Ot{7lw%FY*Mjx`D zVcls~w%CK07=6TOmpx-$w}S9Bc6;}FbK*k`x647j-j{X1vwpPb%T7H!-q}BXa?~I0 z?Jth*m*c&!ru%xm3D&FM($&Qucy>E{^=Q<{q~ZxS*A&pA3%hJRkw01F=;!M${3LF%GiBFYd)f--vj5S!qP3ua^A;`YMJQ^)Yq>Gal zXc`Xec*@z~)TrQBjEd{1yd%l0O1>t*ttC7pB?P&s)u4ncqG)2`4)EAm5ES7Pj}@lZ zszk8D7G#GmI+#c@m%zzY=VbK4X*VcI)>JEbP)QU{DHM~UQL@HbvW9V9Nrc@AB^}k~ zj8-xyr>x5*dszo1hP2L{I7h(A8XmbbFgZC+g~+**LK0l67Et7?7D_u6ELrJ;(^3pd zNGqI>v@BZNqKq#g3lT$-0xsl)Y{}${iyjJFXsb|xmmHEJWuh4^@g^rkRANU~AmWlK z0Gk5$IzclxCR!0Fz^ZN|{o)4y9T+;;lIi%$1K)7}zpRLD9-7#^igNV-&m)XK?> zn^kKC%4Cc(xJW!Y7ZoK_B{yYsCxrk^e7k!V5j6pKI06-3qxL~*VUf~Q43gdA5*cie z^(v=I9sw9F5mLwyrPqY8XWc4cF+QP;p*(4kxpqJ$dstf}kcvro5tBoC;0PN(QEhZ? zHFg4O<#!*n<`~d%&~6SGTXyWHj&<#O=sn8``)Px9PdC_8EN!xWlRcZD*q?&Xt$$SR zrma==v5vojuVs8#=Ij2r#O1s-gZ1<+tPX;GtJ^Phgki7W!g4-bE)Q4J%b50O+5pix z#Xjyfqo1>^>f+uYGVtwUgAK#_d(8GfpZyS56xG+)#a`Isv!f^d{lnGlyG5F<(T}bl z#r!bdE9=>4!mRbH)Gp~gRB>{*A%wfNr}ooRjH(Q47R1BZi}6}MZ@obF)jZ@>O4=b8au z9K>a!c;go4YY^*S#(+eNj}H1~P~Wf~I{9uxdDK7GF}w|_Ip_?FCz)&B&?@{k@KlpB|D>hN!BYh!EU>>1Wg Ya1H;a)91hJCf)XA`_y)~-JR+F1g2?mQ2+n{ literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_Blowfish.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_Blowfish.py new file mode 100644 index 00000000..e8f73a6a --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_Blowfish.py @@ -0,0 +1,113 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Cipher/test_Blowfish.py: Self-test for the Blowfish cipher +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Cipher.Blowfish""" + +__revision__ = "$Id$" + +from Crypto.Util.py3compat import * + +# This is a list of (plaintext, ciphertext, key) tuples. +test_data = [ + # Test vectors from http://www.schneier.com/code/vectors.txt + ('0000000000000000', '4ef997456198dd78', '0000000000000000'), + ('ffffffffffffffff', '51866fd5b85ecb8a', 'ffffffffffffffff'), + ('1000000000000001', '7d856f9a613063f2', '3000000000000000'), + ('1111111111111111', '2466dd878b963c9d', '1111111111111111'), + ('1111111111111111', '61f9c3802281b096', '0123456789abcdef'), + ('0123456789abcdef', '7d0cc630afda1ec7', '1111111111111111'), + ('0000000000000000', '4ef997456198dd78', '0000000000000000'), + ('0123456789abcdef', '0aceab0fc6a0a28d', 'fedcba9876543210'), + ('01a1d6d039776742', '59c68245eb05282b', '7ca110454a1a6e57'), + ('5cd54ca83def57da', 'b1b8cc0b250f09a0', '0131d9619dc1376e'), + ('0248d43806f67172', '1730e5778bea1da4', '07a1133e4a0b2686'), + ('51454b582ddf440a', 'a25e7856cf2651eb', '3849674c2602319e'), + ('42fd443059577fa2', '353882b109ce8f1a', '04b915ba43feb5b6'), + ('059b5e0851cf143a', '48f4d0884c379918', '0113b970fd34f2ce'), + ('0756d8e0774761d2', '432193b78951fc98', '0170f175468fb5e6'), + ('762514b829bf486a', '13f04154d69d1ae5', '43297fad38e373fe'), + ('3bdd119049372802', '2eedda93ffd39c79', '07a7137045da2a16'), + ('26955f6835af609a', 'd887e0393c2da6e3', '04689104c2fd3b2f'), + ('164d5e404f275232', '5f99d04f5b163969', '37d06bb516cb7546'), + ('6b056e18759f5cca', '4a057a3b24d3977b', '1f08260d1ac2465e'), + ('004bd6ef09176062', '452031c1e4fada8e', '584023641aba6176'), + ('480d39006ee762f2', '7555ae39f59b87bd', '025816164629b007'), + ('437540c8698f3cfa', '53c55f9cb49fc019', '49793ebc79b3258f'), + ('072d43a077075292', '7a8e7bfa937e89a3', '4fb05e1515ab73a7'), + ('02fe55778117f12a', 'cf9c5d7a4986adb5', '49e95d6d4ca229bf'), + ('1d9d5c5018f728c2', 'd1abb290658bc778', '018310dc409b26d6'), + ('305532286d6f295a', '55cb3774d13ef201', '1c587f1c13924fef'), + ('0123456789abcdef', 'fa34ec4847b268b2', '0101010101010101'), + ('0123456789abcdef', 'a790795108ea3cae', '1f1f1f1f0e0e0e0e'), + ('0123456789abcdef', 'c39e072d9fac631d', 'e0fee0fef1fef1fe'), + ('ffffffffffffffff', '014933e0cdaff6e4', '0000000000000000'), + ('0000000000000000', 'f21e9a77b71c49bc', 'ffffffffffffffff'), + ('0000000000000000', '245946885754369a', '0123456789abcdef'), + ('ffffffffffffffff', '6b5c5a9c5d9e0a5a', 'fedcba9876543210'), + ('fedcba9876543210', 'f9ad597c49db005e', 'f0'), + ('fedcba9876543210', 'e91d21c1d961a6d6', 'f0e1'), + ('fedcba9876543210', 'e9c2b70a1bc65cf3', 'f0e1d2'), + ('fedcba9876543210', 'be1e639408640f05', 'f0e1d2c3'), + ('fedcba9876543210', 'b39e44481bdb1e6e', 'f0e1d2c3b4'), + ('fedcba9876543210', '9457aa83b1928c0d', 'f0e1d2c3b4a5'), + ('fedcba9876543210', '8bb77032f960629d', 'f0e1d2c3b4a596'), + ('fedcba9876543210', 'e87a244e2cc85e82', 'f0e1d2c3b4a59687'), + ('fedcba9876543210', '15750e7a4f4ec577', 'f0e1d2c3b4a5968778'), + ('fedcba9876543210', '122ba70b3ab64ae0', 'f0e1d2c3b4a596877869'), + ('fedcba9876543210', '3a833c9affc537f6', 'f0e1d2c3b4a5968778695a'), + ('fedcba9876543210', '9409da87a90f6bf2', 'f0e1d2c3b4a5968778695a4b'), + ('fedcba9876543210', '884f80625060b8b4', 'f0e1d2c3b4a5968778695a4b3c'), + ('fedcba9876543210', '1f85031c19e11968', 'f0e1d2c3b4a5968778695a4b3c2d'), + ('fedcba9876543210', '79d9373a714ca34f', 'f0e1d2c3b4a5968778695a4b3c2d1e'), + ('fedcba9876543210', '93142887ee3be15c', + 'f0e1d2c3b4a5968778695a4b3c2d1e0f'), + ('fedcba9876543210', '03429e838ce2d14b', + 'f0e1d2c3b4a5968778695a4b3c2d1e0f00'), + ('fedcba9876543210', 'a4299e27469ff67b', + 'f0e1d2c3b4a5968778695a4b3c2d1e0f0011'), + ('fedcba9876543210', 'afd5aed1c1bc96a8', + 'f0e1d2c3b4a5968778695a4b3c2d1e0f001122'), + ('fedcba9876543210', '10851c0e3858da9f', + 'f0e1d2c3b4a5968778695a4b3c2d1e0f00112233'), + ('fedcba9876543210', 'e6f51ed79b9db21f', + 'f0e1d2c3b4a5968778695a4b3c2d1e0f0011223344'), + ('fedcba9876543210', '64a6e14afd36b46f', + 'f0e1d2c3b4a5968778695a4b3c2d1e0f001122334455'), + ('fedcba9876543210', '80c7d7d45a5479ad', + 'f0e1d2c3b4a5968778695a4b3c2d1e0f00112233445566'), + ('fedcba9876543210', '05044b62fa52d080', + 'f0e1d2c3b4a5968778695a4b3c2d1e0f0011223344556677'), +] + +def get_tests(config={}): + from Crypto.Cipher import Blowfish + from common import make_block_tests + return make_block_tests(Blowfish, "Blowfish", test_data) + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_Blowfish.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_Blowfish.pyo new file mode 100644 index 0000000000000000000000000000000000000000..f1069de19d8cb6c1fcbba43f7738a59e290ac040 GIT binary patch literal 5418 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 GbMikWNje_@ literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_CAST.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_CAST.py new file mode 100644 index 00000000..1cfcec03 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_CAST.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Cipher/CAST.py: Self-test for the CAST-128 (CAST5) cipher +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Cipher.CAST""" + +__revision__ = "$Id$" + +from Crypto.Util.py3compat import * + +# This is a list of (plaintext, ciphertext, key) tuples. +test_data = [ + # Test vectors from RFC 2144, B.1 + ('0123456789abcdef', '238b4fe5847e44b2', + '0123456712345678234567893456789a', + '128-bit key'), + + ('0123456789abcdef', 'eb6a711a2c02271b', + '01234567123456782345', + '80-bit key'), + + ('0123456789abcdef', '7ac816d16e9b302e', + '0123456712', + '40-bit key'), +] + +def get_tests(config={}): + from Crypto.Cipher import CAST + from common import make_block_tests + return make_block_tests(CAST, "CAST", test_data) + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_CAST.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_CAST.pyo new file mode 100644 index 0000000000000000000000000000000000000000..4f995af575d032c645e5f38c2e228920ea64a4bf GIT binary patch literal 1345 zcmcgrU2hUW6uq+x^h2tst;RPV8beG#cA-FxX*Bp^qSY+*L9)qac4wel_Jc5kNt5=e z{ayYj{Q-LK04+7~QJ3sxcIKR!d(S;%|J>RB@%8(s2$oL?|KH%NVhjRch>^jNfv`Z> zkXUdcc0ufccmiV^hBhEj+=puf6+jk2Jb;M>GieAFNJ=m)fp`elxYq{A5}a*8U5(^ENX^xqCnQ~{y;@5O%n z3!fUpFHPZvu3&6BZmWIJ>GlqJ7zsHtlWwaQwny@y*Y3)8J9Kq*4Y?w$cq_WPhaku8 z)x%gs{Sx95$N%^jx3jng1aUeTDt6PkA)qW2yW_3O@Pc1ds6- zZtyAFfGp8KCgm`edQrkl{7{r7unPV(RTKm%kFy{+zVW+-vqo4_K?9sI&=y(~t{4hO z@*gjXA^JRvH63UUqAUjFQSUx3-PZN5ilYQxCp--WKkDFE;R~7!iWcYdL{mbVT5WDl zjhgIH0Up)pQAhr?^BTsW4f(EV*C3>&w?W$wbg$6D +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Cipher.DES""" + +__revision__ = "$Id$" + +from common import dict # For compatibility with Python 2.1 and 2.2 +from Crypto.Util.py3compat import * +import unittest + +# This is a list of (plaintext, ciphertext, key, description) tuples. +SP800_17_B1_KEY = '01' * 8 +SP800_17_B2_PT = '00' * 8 +test_data = [ + # Test vectors from Appendix A of NIST SP 800-17 + # "Modes of Operation Validation System (MOVS): Requirements and Procedures" + # http://csrc.nist.gov/publications/nistpubs/800-17/800-17.pdf + + # Appendix A - "Sample Round Outputs for the DES" + ('0000000000000000', '82dcbafbdeab6602', '10316e028c8f3b4a', + "NIST SP800-17 A"), + + # Table B.1 - Variable Plaintext Known Answer Test + ('8000000000000000', '95f8a5e5dd31d900', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #0'), + ('4000000000000000', 'dd7f121ca5015619', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #1'), + ('2000000000000000', '2e8653104f3834ea', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #2'), + ('1000000000000000', '4bd388ff6cd81d4f', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #3'), + ('0800000000000000', '20b9e767b2fb1456', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #4'), + ('0400000000000000', '55579380d77138ef', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #5'), + ('0200000000000000', '6cc5defaaf04512f', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #6'), + ('0100000000000000', '0d9f279ba5d87260', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #7'), + ('0080000000000000', 'd9031b0271bd5a0a', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #8'), + ('0040000000000000', '424250b37c3dd951', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #9'), + ('0020000000000000', 'b8061b7ecd9a21e5', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #10'), + ('0010000000000000', 'f15d0f286b65bd28', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #11'), + ('0008000000000000', 'add0cc8d6e5deba1', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #12'), + ('0004000000000000', 'e6d5f82752ad63d1', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #13'), + ('0002000000000000', 'ecbfe3bd3f591a5e', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #14'), + ('0001000000000000', 'f356834379d165cd', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #15'), + ('0000800000000000', '2b9f982f20037fa9', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #16'), + ('0000400000000000', '889de068a16f0be6', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #17'), + ('0000200000000000', 'e19e275d846a1298', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #18'), + ('0000100000000000', '329a8ed523d71aec', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #19'), + ('0000080000000000', 'e7fce22557d23c97', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #20'), + ('0000040000000000', '12a9f5817ff2d65d', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #21'), + ('0000020000000000', 'a484c3ad38dc9c19', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #22'), + ('0000010000000000', 'fbe00a8a1ef8ad72', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #23'), + ('0000008000000000', '750d079407521363', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #24'), + ('0000004000000000', '64feed9c724c2faf', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #25'), + ('0000002000000000', 'f02b263b328e2b60', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #26'), + ('0000001000000000', '9d64555a9a10b852', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #27'), + ('0000000800000000', 'd106ff0bed5255d7', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #28'), + ('0000000400000000', 'e1652c6b138c64a5', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #29'), + ('0000000200000000', 'e428581186ec8f46', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #30'), + ('0000000100000000', 'aeb5f5ede22d1a36', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #31'), + ('0000000080000000', 'e943d7568aec0c5c', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #32'), + ('0000000040000000', 'df98c8276f54b04b', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #33'), + ('0000000020000000', 'b160e4680f6c696f', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #34'), + ('0000000010000000', 'fa0752b07d9c4ab8', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #35'), + ('0000000008000000', 'ca3a2b036dbc8502', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #36'), + ('0000000004000000', '5e0905517bb59bcf', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #37'), + ('0000000002000000', '814eeb3b91d90726', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #38'), + ('0000000001000000', '4d49db1532919c9f', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #39'), + ('0000000000800000', '25eb5fc3f8cf0621', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #40'), + ('0000000000400000', 'ab6a20c0620d1c6f', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #41'), + ('0000000000200000', '79e90dbc98f92cca', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #42'), + ('0000000000100000', '866ecedd8072bb0e', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #43'), + ('0000000000080000', '8b54536f2f3e64a8', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #44'), + ('0000000000040000', 'ea51d3975595b86b', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #45'), + ('0000000000020000', 'caffc6ac4542de31', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #46'), + ('0000000000010000', '8dd45a2ddf90796c', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #47'), + ('0000000000008000', '1029d55e880ec2d0', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #48'), + ('0000000000004000', '5d86cb23639dbea9', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #49'), + ('0000000000002000', '1d1ca853ae7c0c5f', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #50'), + ('0000000000001000', 'ce332329248f3228', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #51'), + ('0000000000000800', '8405d1abe24fb942', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #52'), + ('0000000000000400', 'e643d78090ca4207', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #53'), + ('0000000000000200', '48221b9937748a23', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #54'), + ('0000000000000100', 'dd7c0bbd61fafd54', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #55'), + ('0000000000000080', '2fbc291a570db5c4', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #56'), + ('0000000000000040', 'e07c30d7e4e26e12', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #57'), + ('0000000000000020', '0953e2258e8e90a1', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #58'), + ('0000000000000010', '5b711bc4ceebf2ee', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #59'), + ('0000000000000008', 'cc083f1e6d9e85f6', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #60'), + ('0000000000000004', 'd2fd8867d50d2dfe', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #61'), + ('0000000000000002', '06e7ea22ce92708f', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #62'), + ('0000000000000001', '166b40b44aba4bd6', SP800_17_B1_KEY, + 'NIST SP800-17 B.1 #63'), + + # Table B.2 - Variable Key Known Answer Test + (SP800_17_B2_PT, '95a8d72813daa94d', '8001010101010101', + 'NIST SP800-17 B.2 #0'), + (SP800_17_B2_PT, '0eec1487dd8c26d5', '4001010101010101', + 'NIST SP800-17 B.2 #1'), + (SP800_17_B2_PT, '7ad16ffb79c45926', '2001010101010101', + 'NIST SP800-17 B.2 #2'), + (SP800_17_B2_PT, 'd3746294ca6a6cf3', '1001010101010101', + 'NIST SP800-17 B.2 #3'), + (SP800_17_B2_PT, '809f5f873c1fd761', '0801010101010101', + 'NIST SP800-17 B.2 #4'), + (SP800_17_B2_PT, 'c02faffec989d1fc', '0401010101010101', + 'NIST SP800-17 B.2 #5'), + (SP800_17_B2_PT, '4615aa1d33e72f10', '0201010101010101', + 'NIST SP800-17 B.2 #6'), + (SP800_17_B2_PT, '2055123350c00858', '0180010101010101', + 'NIST SP800-17 B.2 #7'), + (SP800_17_B2_PT, 'df3b99d6577397c8', '0140010101010101', + 'NIST SP800-17 B.2 #8'), + (SP800_17_B2_PT, '31fe17369b5288c9', '0120010101010101', + 'NIST SP800-17 B.2 #9'), + (SP800_17_B2_PT, 'dfdd3cc64dae1642', '0110010101010101', + 'NIST SP800-17 B.2 #10'), + (SP800_17_B2_PT, '178c83ce2b399d94', '0108010101010101', + 'NIST SP800-17 B.2 #11'), + (SP800_17_B2_PT, '50f636324a9b7f80', '0104010101010101', + 'NIST SP800-17 B.2 #12'), + (SP800_17_B2_PT, 'a8468ee3bc18f06d', '0102010101010101', + 'NIST SP800-17 B.2 #13'), + (SP800_17_B2_PT, 'a2dc9e92fd3cde92', '0101800101010101', + 'NIST SP800-17 B.2 #14'), + (SP800_17_B2_PT, 'cac09f797d031287', '0101400101010101', + 'NIST SP800-17 B.2 #15'), + (SP800_17_B2_PT, '90ba680b22aeb525', '0101200101010101', + 'NIST SP800-17 B.2 #16'), + (SP800_17_B2_PT, 'ce7a24f350e280b6', '0101100101010101', + 'NIST SP800-17 B.2 #17'), + (SP800_17_B2_PT, '882bff0aa01a0b87', '0101080101010101', + 'NIST SP800-17 B.2 #18'), + (SP800_17_B2_PT, '25610288924511c2', '0101040101010101', + 'NIST SP800-17 B.2 #19'), + (SP800_17_B2_PT, 'c71516c29c75d170', '0101020101010101', + 'NIST SP800-17 B.2 #20'), + (SP800_17_B2_PT, '5199c29a52c9f059', '0101018001010101', + 'NIST SP800-17 B.2 #21'), + (SP800_17_B2_PT, 'c22f0a294a71f29f', '0101014001010101', + 'NIST SP800-17 B.2 #22'), + (SP800_17_B2_PT, 'ee371483714c02ea', '0101012001010101', + 'NIST SP800-17 B.2 #23'), + (SP800_17_B2_PT, 'a81fbd448f9e522f', '0101011001010101', + 'NIST SP800-17 B.2 #24'), + (SP800_17_B2_PT, '4f644c92e192dfed', '0101010801010101', + 'NIST SP800-17 B.2 #25'), + (SP800_17_B2_PT, '1afa9a66a6df92ae', '0101010401010101', + 'NIST SP800-17 B.2 #26'), + (SP800_17_B2_PT, 'b3c1cc715cb879d8', '0101010201010101', + 'NIST SP800-17 B.2 #27'), + (SP800_17_B2_PT, '19d032e64ab0bd8b', '0101010180010101', + 'NIST SP800-17 B.2 #28'), + (SP800_17_B2_PT, '3cfaa7a7dc8720dc', '0101010140010101', + 'NIST SP800-17 B.2 #29'), + (SP800_17_B2_PT, 'b7265f7f447ac6f3', '0101010120010101', + 'NIST SP800-17 B.2 #30'), + (SP800_17_B2_PT, '9db73b3c0d163f54', '0101010110010101', + 'NIST SP800-17 B.2 #31'), + (SP800_17_B2_PT, '8181b65babf4a975', '0101010108010101', + 'NIST SP800-17 B.2 #32'), + (SP800_17_B2_PT, '93c9b64042eaa240', '0101010104010101', + 'NIST SP800-17 B.2 #33'), + (SP800_17_B2_PT, '5570530829705592', '0101010102010101', + 'NIST SP800-17 B.2 #34'), + (SP800_17_B2_PT, '8638809e878787a0', '0101010101800101', + 'NIST SP800-17 B.2 #35'), + (SP800_17_B2_PT, '41b9a79af79ac208', '0101010101400101', + 'NIST SP800-17 B.2 #36'), + (SP800_17_B2_PT, '7a9be42f2009a892', '0101010101200101', + 'NIST SP800-17 B.2 #37'), + (SP800_17_B2_PT, '29038d56ba6d2745', '0101010101100101', + 'NIST SP800-17 B.2 #38'), + (SP800_17_B2_PT, '5495c6abf1e5df51', '0101010101080101', + 'NIST SP800-17 B.2 #39'), + (SP800_17_B2_PT, 'ae13dbd561488933', '0101010101040101', + 'NIST SP800-17 B.2 #40'), + (SP800_17_B2_PT, '024d1ffa8904e389', '0101010101020101', + 'NIST SP800-17 B.2 #41'), + (SP800_17_B2_PT, 'd1399712f99bf02e', '0101010101018001', + 'NIST SP800-17 B.2 #42'), + (SP800_17_B2_PT, '14c1d7c1cffec79e', '0101010101014001', + 'NIST SP800-17 B.2 #43'), + (SP800_17_B2_PT, '1de5279dae3bed6f', '0101010101012001', + 'NIST SP800-17 B.2 #44'), + (SP800_17_B2_PT, 'e941a33f85501303', '0101010101011001', + 'NIST SP800-17 B.2 #45'), + (SP800_17_B2_PT, 'da99dbbc9a03f379', '0101010101010801', + 'NIST SP800-17 B.2 #46'), + (SP800_17_B2_PT, 'b7fc92f91d8e92e9', '0101010101010401', + 'NIST SP800-17 B.2 #47'), + (SP800_17_B2_PT, 'ae8e5caa3ca04e85', '0101010101010201', + 'NIST SP800-17 B.2 #48'), + (SP800_17_B2_PT, '9cc62df43b6eed74', '0101010101010180', + 'NIST SP800-17 B.2 #49'), + (SP800_17_B2_PT, 'd863dbb5c59a91a0', '0101010101010140', + 'NIST SP800-17 B.2 #50'), + (SP800_17_B2_PT, 'a1ab2190545b91d7', '0101010101010120', + 'NIST SP800-17 B.2 #51'), + (SP800_17_B2_PT, '0875041e64c570f7', '0101010101010110', + 'NIST SP800-17 B.2 #52'), + (SP800_17_B2_PT, '5a594528bebef1cc', '0101010101010108', + 'NIST SP800-17 B.2 #53'), + (SP800_17_B2_PT, 'fcdb3291de21f0c0', '0101010101010104', + 'NIST SP800-17 B.2 #54'), + (SP800_17_B2_PT, '869efd7f9f265a09', '0101010101010102', + 'NIST SP800-17 B.2 #55'), +] + +class RonRivestTest(unittest.TestCase): + """ Ronald L. Rivest's DES test, see + http://people.csail.mit.edu/rivest/Destest.txt + ABSTRACT + -------- + + We present a simple way to test the correctness of a DES implementation: + Use the recurrence relation: + + X0 = 9474B8E8C73BCA7D (hexadecimal) + + X(i+1) = IF (i is even) THEN E(Xi,Xi) ELSE D(Xi,Xi) + + to compute a sequence of 64-bit values: X0, X1, X2, ..., X16. Here + E(X,K) denotes the DES encryption of X using key K, and D(X,K) denotes + the DES decryption of X using key K. If you obtain + + X16 = 1B1A2DDB4C642438 + + your implementation does not have any of the 36,568 possible single-fault + errors described herein. + """ + def runTest(self): + from Crypto.Cipher import DES + from binascii import b2a_hex + + X = [] + X[0:] = [b('\x94\x74\xB8\xE8\xC7\x3B\xCA\x7D')] + + for i in range(16): + c = DES.new(X[i],DES.MODE_ECB) + if not (i&1): # (num&1) returns 1 for odd numbers + X[i+1:] = [c.encrypt(X[i])] # even + else: + X[i+1:] = [c.decrypt(X[i])] # odd + + self.assertEqual(b2a_hex(X[16]), + b2a_hex(b('\x1B\x1A\x2D\xDB\x4C\x64\x24\x38'))) + +def get_tests(config={}): + from Crypto.Cipher import DES + from common import make_block_tests + return make_block_tests(DES, "DES", test_data) + [RonRivestTest()] + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_DES.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_DES.pyo new file mode 100644 index 0000000000000000000000000000000000000000..de2427a87dedf39f52f5efa7b36f60b3c27f8cd6 GIT binary patch literal 13336 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 a1s~)8kKg~t>%Vh!_gy=;?&Lc$#{UhmA(_Jf literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_DES3.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_DES3.py new file mode 100644 index 00000000..50e969b9 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_DES3.py @@ -0,0 +1,333 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Cipher/DES3.py: Self-test for the Triple-DES cipher +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Cipher.DES3""" + +__revision__ = "$Id$" + +from common import dict # For compatibility with Python 2.1 and 2.2 +from Crypto.Util.py3compat import * +from binascii import hexlify + +# This is a list of (plaintext, ciphertext, key, description) tuples. +SP800_20_A1_KEY = '01' * 24 +SP800_20_A2_PT = '00' * 8 +test_data = [ + # Test vector from Appendix B of NIST SP 800-67 + # "Recommendation for the Triple Data Encryption Algorithm (TDEA) Block + # Cipher" + # http://csrc.nist.gov/publications/nistpubs/800-67/SP800-67.pdf + ('54686520717566636b2062726f776e20666f78206a756d70', + 'a826fd8ce53b855fcce21c8112256fe668d5c05dd9b6b900', + '0123456789abcdef23456789abcdef01456789abcdef0123', + 'NIST SP800-67 B.1'), + + # Test vectors "The Multi-block Message Test (MMT) for DES and TDES" + # http://csrc.nist.gov/groups/STM/cavp/documents/des/DESMMT.pdf + ('326a494cd33fe756', 'b22b8d66de970692', + '627f460e08104a1043cd265d5840eaf1313edf97df2a8a8c', + 'DESMMT #1', dict(mode='CBC', iv='8e29f75ea77e5475')), + + ('84401f78fe6c10876d8ea23094ea5309', '7b1f7c7e3b1c948ebd04a75ffba7d2f5', + '37ae5ebf46dff2dc0754b94f31cbb3855e7fd36dc870bfae', + 'DESMMT #2', dict(mode='CBC', iv='3d1de3cc132e3b65')), + + # Test vectors from Appendix A of NIST SP 800-20 + # "Modes of Operation Validation System for the Triple Data Encryption + # Algorithm (TMOVS): Requirements and Procedures" + # http://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf + + # Table A.1 - Variable Plaintext Known Answer Test + ('8000000000000000', '95f8a5e5dd31d900', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #0'), + ('4000000000000000', 'dd7f121ca5015619', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #1'), + ('2000000000000000', '2e8653104f3834ea', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #2'), + ('1000000000000000', '4bd388ff6cd81d4f', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #3'), + ('0800000000000000', '20b9e767b2fb1456', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #4'), + ('0400000000000000', '55579380d77138ef', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #5'), + ('0200000000000000', '6cc5defaaf04512f', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #6'), + ('0100000000000000', '0d9f279ba5d87260', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #7'), + ('0080000000000000', 'd9031b0271bd5a0a', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #8'), + ('0040000000000000', '424250b37c3dd951', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #9'), + ('0020000000000000', 'b8061b7ecd9a21e5', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #10'), + ('0010000000000000', 'f15d0f286b65bd28', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #11'), + ('0008000000000000', 'add0cc8d6e5deba1', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #12'), + ('0004000000000000', 'e6d5f82752ad63d1', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #13'), + ('0002000000000000', 'ecbfe3bd3f591a5e', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #14'), + ('0001000000000000', 'f356834379d165cd', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #15'), + ('0000800000000000', '2b9f982f20037fa9', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #16'), + ('0000400000000000', '889de068a16f0be6', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #17'), + ('0000200000000000', 'e19e275d846a1298', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #18'), + ('0000100000000000', '329a8ed523d71aec', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #19'), + ('0000080000000000', 'e7fce22557d23c97', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #20'), + ('0000040000000000', '12a9f5817ff2d65d', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #21'), + ('0000020000000000', 'a484c3ad38dc9c19', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #22'), + ('0000010000000000', 'fbe00a8a1ef8ad72', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #23'), + ('0000008000000000', '750d079407521363', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #24'), + ('0000004000000000', '64feed9c724c2faf', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #25'), + ('0000002000000000', 'f02b263b328e2b60', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #26'), + ('0000001000000000', '9d64555a9a10b852', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #27'), + ('0000000800000000', 'd106ff0bed5255d7', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #28'), + ('0000000400000000', 'e1652c6b138c64a5', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #29'), + ('0000000200000000', 'e428581186ec8f46', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #30'), + ('0000000100000000', 'aeb5f5ede22d1a36', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #31'), + ('0000000080000000', 'e943d7568aec0c5c', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #32'), + ('0000000040000000', 'df98c8276f54b04b', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #33'), + ('0000000020000000', 'b160e4680f6c696f', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #34'), + ('0000000010000000', 'fa0752b07d9c4ab8', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #35'), + ('0000000008000000', 'ca3a2b036dbc8502', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #36'), + ('0000000004000000', '5e0905517bb59bcf', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #37'), + ('0000000002000000', '814eeb3b91d90726', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #38'), + ('0000000001000000', '4d49db1532919c9f', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #39'), + ('0000000000800000', '25eb5fc3f8cf0621', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #40'), + ('0000000000400000', 'ab6a20c0620d1c6f', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #41'), + ('0000000000200000', '79e90dbc98f92cca', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #42'), + ('0000000000100000', '866ecedd8072bb0e', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #43'), + ('0000000000080000', '8b54536f2f3e64a8', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #44'), + ('0000000000040000', 'ea51d3975595b86b', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #45'), + ('0000000000020000', 'caffc6ac4542de31', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #46'), + ('0000000000010000', '8dd45a2ddf90796c', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #47'), + ('0000000000008000', '1029d55e880ec2d0', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #48'), + ('0000000000004000', '5d86cb23639dbea9', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #49'), + ('0000000000002000', '1d1ca853ae7c0c5f', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #50'), + ('0000000000001000', 'ce332329248f3228', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #51'), + ('0000000000000800', '8405d1abe24fb942', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #52'), + ('0000000000000400', 'e643d78090ca4207', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #53'), + ('0000000000000200', '48221b9937748a23', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #54'), + ('0000000000000100', 'dd7c0bbd61fafd54', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #55'), + ('0000000000000080', '2fbc291a570db5c4', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #56'), + ('0000000000000040', 'e07c30d7e4e26e12', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #57'), + ('0000000000000020', '0953e2258e8e90a1', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #58'), + ('0000000000000010', '5b711bc4ceebf2ee', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #59'), + ('0000000000000008', 'cc083f1e6d9e85f6', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #60'), + ('0000000000000004', 'd2fd8867d50d2dfe', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #61'), + ('0000000000000002', '06e7ea22ce92708f', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #62'), + ('0000000000000001', '166b40b44aba4bd6', SP800_20_A1_KEY, + 'NIST SP800-20 A.1 #63'), + + # Table A.2 - Variable Key Known Answer Test + (SP800_20_A2_PT, '95a8d72813daa94d', '8001010101010101'*3, + 'NIST SP800-20 A.2 #0'), + (SP800_20_A2_PT, '0eec1487dd8c26d5', '4001010101010101'*3, + 'NIST SP800-20 A.2 #1'), + (SP800_20_A2_PT, '7ad16ffb79c45926', '2001010101010101'*3, + 'NIST SP800-20 A.2 #2'), + (SP800_20_A2_PT, 'd3746294ca6a6cf3', '1001010101010101'*3, + 'NIST SP800-20 A.2 #3'), + (SP800_20_A2_PT, '809f5f873c1fd761', '0801010101010101'*3, + 'NIST SP800-20 A.2 #4'), + (SP800_20_A2_PT, 'c02faffec989d1fc', '0401010101010101'*3, + 'NIST SP800-20 A.2 #5'), + (SP800_20_A2_PT, '4615aa1d33e72f10', '0201010101010101'*3, + 'NIST SP800-20 A.2 #6'), + (SP800_20_A2_PT, '2055123350c00858', '0180010101010101'*3, + 'NIST SP800-20 A.2 #7'), + (SP800_20_A2_PT, 'df3b99d6577397c8', '0140010101010101'*3, + 'NIST SP800-20 A.2 #8'), + (SP800_20_A2_PT, '31fe17369b5288c9', '0120010101010101'*3, + 'NIST SP800-20 A.2 #9'), + (SP800_20_A2_PT, 'dfdd3cc64dae1642', '0110010101010101'*3, + 'NIST SP800-20 A.2 #10'), + (SP800_20_A2_PT, '178c83ce2b399d94', '0108010101010101'*3, + 'NIST SP800-20 A.2 #11'), + (SP800_20_A2_PT, '50f636324a9b7f80', '0104010101010101'*3, + 'NIST SP800-20 A.2 #12'), + (SP800_20_A2_PT, 'a8468ee3bc18f06d', '0102010101010101'*3, + 'NIST SP800-20 A.2 #13'), + (SP800_20_A2_PT, 'a2dc9e92fd3cde92', '0101800101010101'*3, + 'NIST SP800-20 A.2 #14'), + (SP800_20_A2_PT, 'cac09f797d031287', '0101400101010101'*3, + 'NIST SP800-20 A.2 #15'), + (SP800_20_A2_PT, '90ba680b22aeb525', '0101200101010101'*3, + 'NIST SP800-20 A.2 #16'), + (SP800_20_A2_PT, 'ce7a24f350e280b6', '0101100101010101'*3, + 'NIST SP800-20 A.2 #17'), + (SP800_20_A2_PT, '882bff0aa01a0b87', '0101080101010101'*3, + 'NIST SP800-20 A.2 #18'), + (SP800_20_A2_PT, '25610288924511c2', '0101040101010101'*3, + 'NIST SP800-20 A.2 #19'), + (SP800_20_A2_PT, 'c71516c29c75d170', '0101020101010101'*3, + 'NIST SP800-20 A.2 #20'), + (SP800_20_A2_PT, '5199c29a52c9f059', '0101018001010101'*3, + 'NIST SP800-20 A.2 #21'), + (SP800_20_A2_PT, 'c22f0a294a71f29f', '0101014001010101'*3, + 'NIST SP800-20 A.2 #22'), + (SP800_20_A2_PT, 'ee371483714c02ea', '0101012001010101'*3, + 'NIST SP800-20 A.2 #23'), + (SP800_20_A2_PT, 'a81fbd448f9e522f', '0101011001010101'*3, + 'NIST SP800-20 A.2 #24'), + (SP800_20_A2_PT, '4f644c92e192dfed', '0101010801010101'*3, + 'NIST SP800-20 A.2 #25'), + (SP800_20_A2_PT, '1afa9a66a6df92ae', '0101010401010101'*3, + 'NIST SP800-20 A.2 #26'), + (SP800_20_A2_PT, 'b3c1cc715cb879d8', '0101010201010101'*3, + 'NIST SP800-20 A.2 #27'), + (SP800_20_A2_PT, '19d032e64ab0bd8b', '0101010180010101'*3, + 'NIST SP800-20 A.2 #28'), + (SP800_20_A2_PT, '3cfaa7a7dc8720dc', '0101010140010101'*3, + 'NIST SP800-20 A.2 #29'), + (SP800_20_A2_PT, 'b7265f7f447ac6f3', '0101010120010101'*3, + 'NIST SP800-20 A.2 #30'), + (SP800_20_A2_PT, '9db73b3c0d163f54', '0101010110010101'*3, + 'NIST SP800-20 A.2 #31'), + (SP800_20_A2_PT, '8181b65babf4a975', '0101010108010101'*3, + 'NIST SP800-20 A.2 #32'), + (SP800_20_A2_PT, '93c9b64042eaa240', '0101010104010101'*3, + 'NIST SP800-20 A.2 #33'), + (SP800_20_A2_PT, '5570530829705592', '0101010102010101'*3, + 'NIST SP800-20 A.2 #34'), + (SP800_20_A2_PT, '8638809e878787a0', '0101010101800101'*3, + 'NIST SP800-20 A.2 #35'), + (SP800_20_A2_PT, '41b9a79af79ac208', '0101010101400101'*3, + 'NIST SP800-20 A.2 #36'), + (SP800_20_A2_PT, '7a9be42f2009a892', '0101010101200101'*3, + 'NIST SP800-20 A.2 #37'), + (SP800_20_A2_PT, '29038d56ba6d2745', '0101010101100101'*3, + 'NIST SP800-20 A.2 #38'), + (SP800_20_A2_PT, '5495c6abf1e5df51', '0101010101080101'*3, + 'NIST SP800-20 A.2 #39'), + (SP800_20_A2_PT, 'ae13dbd561488933', '0101010101040101'*3, + 'NIST SP800-20 A.2 #40'), + (SP800_20_A2_PT, '024d1ffa8904e389', '0101010101020101'*3, + 'NIST SP800-20 A.2 #41'), + (SP800_20_A2_PT, 'd1399712f99bf02e', '0101010101018001'*3, + 'NIST SP800-20 A.2 #42'), + (SP800_20_A2_PT, '14c1d7c1cffec79e', '0101010101014001'*3, + 'NIST SP800-20 A.2 #43'), + (SP800_20_A2_PT, '1de5279dae3bed6f', '0101010101012001'*3, + 'NIST SP800-20 A.2 #44'), + (SP800_20_A2_PT, 'e941a33f85501303', '0101010101011001'*3, + 'NIST SP800-20 A.2 #45'), + (SP800_20_A2_PT, 'da99dbbc9a03f379', '0101010101010801'*3, + 'NIST SP800-20 A.2 #46'), + (SP800_20_A2_PT, 'b7fc92f91d8e92e9', '0101010101010401'*3, + 'NIST SP800-20 A.2 #47'), + (SP800_20_A2_PT, 'ae8e5caa3ca04e85', '0101010101010201'*3, + 'NIST SP800-20 A.2 #48'), + (SP800_20_A2_PT, '9cc62df43b6eed74', '0101010101010180'*3, + 'NIST SP800-20 A.2 #49'), + (SP800_20_A2_PT, 'd863dbb5c59a91a0', '0101010101010140'*3, + 'NIST SP800-20 A.2 #50'), + (SP800_20_A2_PT, 'a1ab2190545b91d7', '0101010101010120'*3, + 'NIST SP800-20 A.2 #51'), + (SP800_20_A2_PT, '0875041e64c570f7', '0101010101010110'*3, + 'NIST SP800-20 A.2 #52'), + (SP800_20_A2_PT, '5a594528bebef1cc', '0101010101010108'*3, + 'NIST SP800-20 A.2 #53'), + (SP800_20_A2_PT, 'fcdb3291de21f0c0', '0101010101010104'*3, + 'NIST SP800-20 A.2 #54'), + (SP800_20_A2_PT, '869efd7f9f265a09', '0101010101010102'*3, + 'NIST SP800-20 A.2 #55'), + + # "Two-key 3DES". Test vector generated using PyCrypto 2.0.1. + # This test is designed to test the DES3 API, not the correctness of the + # output. + ('21e81b7ade88a259', '5c577d4d9b20c0f8', + '9b397ebf81b1181e282f4bb8adbadc6b', 'Two-key 3DES'), + + # The following test vectors have been generated with gpg v1.4.0. + # The command line used was: + # gpg -c -z 0 --cipher-algo 3DES --passphrase secret_passphrase \ + # --disable-mdc --s2k-mode 0 --output ct pt + # For an explanation, see test_AES.py . + ( 'ac1762037074324fb53ba3596f73656d69746556616c6c6579', # Plaintext, 'YosemiteValley' + '9979238528357b90e2e0be549cb0b2d5999b9a4a447e5c5c7d', # Ciphertext + '7ade65b460f5ea9be35f9e14aa883a2048e3824aa616c0b2', # Key (hash of 'BearsAhead') + 'GPG Test Vector #1', + dict(mode='OPENPGP', iv='cd47e2afb8b7e4b0', encrypted_iv='6a7eef0b58050e8b904a' ) ), +] + +def get_tests(config={}): + from Crypto.Cipher import DES3 + from common import make_block_tests + return make_block_tests(DES3, "DES3", test_data) + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_DES3.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_DES3.pyo new file mode 100644 index 0000000000000000000000000000000000000000..21ccc73d966ca09d6bf9da254e9edcfd9ae637f2 GIT binary patch literal 12931 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 +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Cipher.XOR""" + +import unittest + +__revision__ = "$Id$" + +from Crypto.Util.py3compat import * + +# This is a list of (plaintext, ciphertext, key) tuples. +test_data = [ + # Test vectors written from scratch. (Nobody posts XOR test vectors on the web? How disappointing.) + ('01', '01', + '00', + 'zero key'), + + ('0102040810204080', '0003050911214181', + '01', + '1-byte key'), + + ('0102040810204080', 'cda8c8a2dc8a8c2a', + 'ccaa', + '2-byte key'), + + ('ff'*64, 'fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0'*2, + '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', + '32-byte key'), +] + +class TruncationSelfTest(unittest.TestCase): + + def runTest(self): + """33-byte key (should raise ValueError under current implementation)""" + # Crypto.Cipher.XOR previously truncated its inputs at 32 bytes. Now + # it should raise a ValueError if the length is too long. + self.assertRaises(ValueError, XOR.new, "x"*33) + +def get_tests(config={}): + global XOR + from Crypto.Cipher import XOR + from common import make_stream_tests + return make_stream_tests(XOR, "XOR", test_data) + [TruncationSelfTest()] + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_XOR.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_XOR.pyo new file mode 100644 index 0000000000000000000000000000000000000000..54507c9cd226d993f681b8484507e840396c4968 GIT binary patch literal 2056 zcmcgsZEqVz5T3hp+$6XmEh!1XGQk9}}K&@rzw7#89F1b5f zw`(A%d`kZaANU*mDEI*|v**@HKT}TH+1=aO*=L@43I4vh{@05?pCz#PZqWRghWUep z0vM6>K>3h)Frq~OBj5e0K^DNVx(n(PP@jU@0QEj>sZCI~Xu1vR1JE@%slliQY75YV zvlY-};SRh4xCD4HszXZFKZI9g`Uc=CsBJj+q5S>&lOOSg(V8={4r&L~$8_KG3cBpW zu=N?ky-#9@nclT%Y}3qBi%mT(n}hOVW~Y0Dbasm6-t%Ws`VW0arbhbrzEk&F9xW`3 z2i7Mk!fFy`m3F^kIc=Wfh23;VqAm7CFRUg}{S=}jx}qP3?QlQrg=U>J!`;aRz5n`R zqGT`W$+jZVOWM-%<4Gc=Q*JMn8GzR5W11`rtu<<;6Ft#V_jOMn>I2=?`?{msI@AI+ zA}UO9f)e}K!$Um4F79Io+Zduq*`Tu|gkabm!rv7K;!yNNUq~?#iBJNC4n@cwbjXKp zcn}_vC;d={lQ0QYh@m#`k)_TRsJCf1oVzoB7nkw6L`1s+@+ zeTasR^n`VItk4+HFdWF20B0^B6o#{4kqBFt0eF;p!xl4V*l?%whPGzQoKEMNYL+rJ z*!)pub9_>k6#RLiuxuvtvc$qR(|nd;PAdobOBeKC(l5x^k+W+Xw3NnRX(P5|EXQ(b z&IYul403aUKUb;a5Rv;WIs_-oQ(6rkj=z_MlAUjN!@d5V7|$;3>9iO>O($bR$+;T7cK2`IK zwh@!R#Px2#MNCqchC@~NU04|)6XU}AkQR#`0+4$kJqo64C7BO-0Kd`xrN>36YCyF? z!L}>hAx=El9=13=j$G9`!lMn^SJbn6xje_%*b-$PGi9bauhWseN#a`lyEDsY$u!TW zMYP3gYb=;;C9QPsv>5+Fuh8j<(_0ex-v^i>oS>~d_?k9`L4v>OZF-9c=Q1tgIN{&? zF+#^KcP2|kLj?Lv+NDQj!ew=|%#V4ITK3Sn%2_nz{uu3$*3zqYlO7KJSDDNwNF-R@1$r!geF(@~u|eVgRnL z;#f@+s+GI^gF8SRm-tg^sH;&y-Ju_g6#BuY85LuPQfDS@w9WdfBpCld8g!ZCIE}bD yMxV0+L*&T)KQvc`|A^yi9+0T}4ZrTMuTY!y0{^Pq@B*(9?5sBG4X@#?dH({qRnG4K literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_pkcs1_15.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_pkcs1_15.py new file mode 100644 index 00000000..7aa17033 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_pkcs1_15.py @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Cipher/test_pkcs1_15.py: Self-test for PKCS#1 v1.5 encryption +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +__revision__ = "$Id$" + +import unittest +import sys + +from Crypto.PublicKey import RSA +from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex +from Crypto import Random +from Crypto.Cipher import PKCS1_v1_5 as PKCS +from Crypto.Util.py3compat import * + +def rws(t): + """Remove white spaces, tabs, and new lines from a string""" + for c in ['\n', '\t', ' ']: + t = t.replace(c,'') + return t + +def t2b(t): + """Convert a text string with bytes in hex form to a byte string""" + clean = b(rws(t)) + if len(clean)%2 == 1: + print clean + raise ValueError("Even number of characters expected") + return a2b_hex(clean) + +class PKCS1_15_Tests(unittest.TestCase): + + def setUp(self): + self.rng = Random.new().read + self.key1024 = RSA.generate(1024, self.rng) + + # List of tuples with test data for PKCS#1 v1.5. + # Each tuple is made up by: + # Item #0: dictionary with RSA key component, or key to import + # Item #1: plaintext + # Item #2: ciphertext + # Item #3: random data + + _testData = ( + + # + # Generated with openssl 0.9.8o + # + ( + # Private key + '''-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDAiAnvIAOvqVwJTaYzsKnefZftgtXGE2hPJppGsWl78yz9jeXY +W/FxX/gTPURArNhdnhP6n3p2ZaDIBrO2zizbgIXs0IsljTTcr4vnI8fMXzyNUOjA +zP3nzMqZDZK6757XQAobOssMkBFqRWwilT/3DsBhRpl3iMUhF+wvpTSHewIDAQAB +AoGAC4HV/inOrpgTvSab8Wj0riyZgQOZ3U3ZpSlsfR8ra9Ib9Uee3jCYnKscu6Gk +y6zI/cdt8EPJ4PuwAWSNJzbpbVaDvUq25OD+CX8/uRT08yBS4J8TzBitZJTD4lS7 +atdTnKT0Wmwk+u8tDbhvMKwnUHdJLcuIsycts9rwJVapUtkCQQDvDpx2JMun0YKG +uUttjmL8oJ3U0m3ZvMdVwBecA0eebZb1l2J5PvI3EJD97eKe91Nsw8T3lwpoN40k +IocSVDklAkEAzi1HLHE6EzVPOe5+Y0kGvrIYRRhncOb72vCvBZvD6wLZpQgqo6c4 +d3XHFBBQWA6xcvQb5w+VVEJZzw64y25sHwJBAMYReRl6SzL0qA0wIYrYWrOt8JeQ +8mthulcWHXmqTgC6FEXP9Es5GD7/fuKl4wqLKZgIbH4nqvvGay7xXLCXD/ECQH9a +1JYNMtRen5unSAbIOxRcKkWz92F0LKpm9ZW/S9vFHO+mBcClMGoKJHiuQxLBsLbT +NtEZfSJZAeS2sUtn3/0CQDb2M2zNBTF8LlM0nxmh0k9VGm5TVIyBEMcipmvOgqIs +HKukWBcq9f/UOmS0oEhai/6g+Uf7VHJdWaeO5LzuvwU= +-----END RSA PRIVATE KEY-----''', + # Plaintext + '''THIS IS PLAINTEXT\x0A''', + # Ciphertext + '''3f dc fd 3c cd 5c 9b 12 af 65 32 e3 f7 d0 da 36 + 8f 8f d9 e3 13 1c 7f c8 b3 f9 c1 08 e4 eb 79 9c + 91 89 1f 96 3b 94 77 61 99 a4 b1 ee 5d e6 17 c9 + 5d 0a b5 63 52 0a eb 00 45 38 2a fb b0 71 3d 11 + f7 a1 9e a7 69 b3 af 61 c0 bb 04 5b 5d 4b 27 44 + 1f 5b 97 89 ba 6a 08 95 ee 4f a2 eb 56 64 e5 0f + da 7c f9 9a 61 61 06 62 ed a0 bc 5f aa 6c 31 78 + 70 28 1a bb 98 3c e3 6a 60 3c d1 0b 0f 5a f4 75''', + # Random data + '''eb d7 7d 86 a4 35 23 a3 54 7e 02 0b 42 1d + 61 6c af 67 b8 4e 17 56 80 66 36 04 64 34 26 8a + 47 dd 44 b3 1a b2 17 60 f4 91 2e e2 b5 95 64 cc + f9 da c8 70 94 54 86 4c ef 5b 08 7d 18 c4 ab 8d + 04 06 33 8f ca 15 5f 52 60 8a a1 0c f5 08 b5 4c + bb 99 b8 94 25 04 9c e6 01 75 e6 f9 63 7a 65 61 + 13 8a a7 47 77 81 ae 0d b8 2c 4d 50 a5''' + ), + ) + + def testEncrypt1(self): + for test in self._testData: + # Build the key + key = RSA.importKey(test[0]) + # RNG that takes its random numbers from a pool given + # at initialization + class randGen: + def __init__(self, data): + self.data = data + self.idx = 0 + def __call__(self, N): + r = self.data[self.idx:N] + self.idx += N + return r + # The real test + key._randfunc = randGen(t2b(test[3])) + cipher = PKCS.new(key) + ct = cipher.encrypt(b(test[1])) + self.assertEqual(ct, t2b(test[2])) + + def testEncrypt2(self): + # Verify that encryption fail if plaintext is too long + pt = '\x00'*(128-11+1) + cipher = PKCS.new(self.key1024) + self.assertRaises(ValueError, cipher.encrypt, pt) + + def testVerify1(self): + for test in self._testData: + # Build the key + key = RSA.importKey(test[0]) + # The real test + cipher = PKCS.new(key) + pt = cipher.decrypt(t2b(test[2]), "---") + self.assertEqual(pt, b(test[1])) + + def testVerify2(self): + # Verify that decryption fails if ciphertext is not as long as + # RSA modulus + cipher = PKCS.new(self.key1024) + self.assertRaises(ValueError, cipher.decrypt, '\x00'*127, "---") + self.assertRaises(ValueError, cipher.decrypt, '\x00'*129, "---") + + # Verify that decryption fails if there are less then 8 non-zero padding + # bytes + pt = b('\x00\x02' + '\xFF'*7 + '\x00' + '\x45'*118) + ct = self.key1024.encrypt(pt, 0)[0] + ct = b('\x00'*(128-len(ct))) + ct + self.assertEqual("---", cipher.decrypt(ct, "---")) + + def testEncryptVerify1(self): + # Encrypt/Verify messages of length [0..RSAlen-11] + # and therefore padding [8..117] + for pt_len in xrange(0,128-11+1): + pt = self.rng(pt_len) + cipher = PKCS.new(self.key1024) + ct = cipher.encrypt(pt) + pt2 = cipher.decrypt(ct, "---") + self.assertEqual(pt,pt2) + + +def get_tests(config={}): + tests = [] + tests += list_test_cases(PKCS1_15_Tests) + return tests + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_pkcs1_15.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_pkcs1_15.pyo new file mode 100644 index 0000000000000000000000000000000000000000..3499deaeb7fd4de90f1ec37fdd77e8147cbeedd2 GIT binary patch literal 10821 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 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py new file mode 100644 index 00000000..accca613 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py @@ -0,0 +1,372 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Cipher/test_pkcs1_oaep.py: Self-test for PKCS#1 OAEP encryption +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +from __future__ import nested_scopes + +__revision__ = "$Id$" + +import unittest + +from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex + +from Crypto.Util.py3compat import * +from Crypto.PublicKey import RSA +from Crypto.Cipher import PKCS1_OAEP as PKCS +from Crypto.Hash import MD2,MD5,SHA as SHA1,SHA256,RIPEMD +from Crypto import Random + +def rws(t): + """Remove white spaces, tabs, and new lines from a string""" + for c in ['\n', '\t', ' ']: + t = t.replace(c,'') + return t + +def t2b(t): + """Convert a text string with bytes in hex form to a byte string""" + clean = rws(t) + if len(clean)%2 == 1: + raise ValueError("Even number of characters expected") + return a2b_hex(clean) + +class PKCS1_OAEP_Tests(unittest.TestCase): + + def setUp(self): + self.rng = Random.new().read + self.key1024 = RSA.generate(1024, self.rng) + + # List of tuples with test data for PKCS#1 OAEP + # Each tuple is made up by: + # Item #0: dictionary with RSA key component + # Item #1: plaintext + # Item #2: ciphertext + # Item #3: random data (=seed) + # Item #4: hash object + + _testData = ( + + # + # From in oaep-int.txt to be found in + # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip + # + ( + # Private key + { + 'n':'''bb f8 2f 09 06 82 ce 9c 23 38 ac 2b 9d a8 71 f7 + 36 8d 07 ee d4 10 43 a4 40 d6 b6 f0 74 54 f5 1f + b8 df ba af 03 5c 02 ab 61 ea 48 ce eb 6f cd 48 + 76 ed 52 0d 60 e1 ec 46 19 71 9d 8a 5b 8b 80 7f + af b8 e0 a3 df c7 37 72 3e e6 b4 b7 d9 3a 25 84 + ee 6a 64 9d 06 09 53 74 88 34 b2 45 45 98 39 4e + e0 aa b1 2d 7b 61 a5 1f 52 7a 9a 41 f6 c1 68 7f + e2 53 72 98 ca 2a 8f 59 46 f8 e5 fd 09 1d bd cb''', + # Public key + 'e':'11', + # In the test vector, only p and q were given... + # d is computed offline as e^{-1} mod (p-1)(q-1) + 'd':'''a5dafc5341faf289c4b988db30c1cdf83f31251e0 + 668b42784813801579641b29410b3c7998d6bc465745e5c3 + 92669d6870da2c082a939e37fdcb82ec93edac97ff3ad595 + 0accfbc111c76f1a9529444e56aaf68c56c092cd38dc3bef + 5d20a939926ed4f74a13eddfbe1a1cecc4894af9428c2b7b + 8883fe4463a4bc85b1cb3c1''' + } + , + # Plaintext + '''d4 36 e9 95 69 fd 32 a7 c8 a0 5b bc 90 d3 2c 49''', + # Ciphertext + '''12 53 e0 4d c0 a5 39 7b b4 4a 7a b8 7e 9b f2 a0 + 39 a3 3d 1e 99 6f c8 2a 94 cc d3 00 74 c9 5d f7 + 63 72 20 17 06 9e 52 68 da 5d 1c 0b 4f 87 2c f6 + 53 c1 1d f8 23 14 a6 79 68 df ea e2 8d ef 04 bb + 6d 84 b1 c3 1d 65 4a 19 70 e5 78 3b d6 eb 96 a0 + 24 c2 ca 2f 4a 90 fe 9f 2e f5 c9 c1 40 e5 bb 48 + da 95 36 ad 87 00 c8 4f c9 13 0a de a7 4e 55 8d + 51 a7 4d df 85 d8 b5 0d e9 68 38 d6 06 3e 09 55''', + # Random + '''aa fd 12 f6 59 ca e6 34 89 b4 79 e5 07 6d de c2 + f0 6c b5 8f''', + # Hash + SHA1, + ), + + # + # From in oaep-vect.txt to be found in Example 1.1 + # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip + # + ( + # Private key + { + 'n':'''a8 b3 b2 84 af 8e b5 0b 38 70 34 a8 60 f1 46 c4 + 91 9f 31 87 63 cd 6c 55 98 c8 ae 48 11 a1 e0 ab + c4 c7 e0 b0 82 d6 93 a5 e7 fc ed 67 5c f4 66 85 + 12 77 2c 0c bc 64 a7 42 c6 c6 30 f5 33 c8 cc 72 + f6 2a e8 33 c4 0b f2 58 42 e9 84 bb 78 bd bf 97 + c0 10 7d 55 bd b6 62 f5 c4 e0 fa b9 84 5c b5 14 + 8e f7 39 2d d3 aa ff 93 ae 1e 6b 66 7b b3 d4 24 + 76 16 d4 f5 ba 10 d4 cf d2 26 de 88 d3 9f 16 fb''', + 'e':'''01 00 01''', + 'd':'''53 33 9c fd b7 9f c8 46 6a 65 5c 73 16 ac a8 5c + 55 fd 8f 6d d8 98 fd af 11 95 17 ef 4f 52 e8 fd + 8e 25 8d f9 3f ee 18 0f a0 e4 ab 29 69 3c d8 3b + 15 2a 55 3d 4a c4 d1 81 2b 8b 9f a5 af 0e 7f 55 + fe 73 04 df 41 57 09 26 f3 31 1f 15 c4 d6 5a 73 + 2c 48 31 16 ee 3d 3d 2d 0a f3 54 9a d9 bf 7c bf + b7 8a d8 84 f8 4d 5b eb 04 72 4d c7 36 9b 31 de + f3 7d 0c f5 39 e9 cf cd d3 de 65 37 29 ea d5 d1 ''' + } + , + # Plaintext + '''66 28 19 4e 12 07 3d b0 3b a9 4c da 9e f9 53 23 + 97 d5 0d ba 79 b9 87 00 4a fe fe 34''', + # Ciphertext + '''35 4f e6 7b 4a 12 6d 5d 35 fe 36 c7 77 79 1a 3f + 7b a1 3d ef 48 4e 2d 39 08 af f7 22 fa d4 68 fb + 21 69 6d e9 5d 0b e9 11 c2 d3 17 4f 8a fc c2 01 + 03 5f 7b 6d 8e 69 40 2d e5 45 16 18 c2 1a 53 5f + a9 d7 bf c5 b8 dd 9f c2 43 f8 cf 92 7d b3 13 22 + d6 e8 81 ea a9 1a 99 61 70 e6 57 a0 5a 26 64 26 + d9 8c 88 00 3f 84 77 c1 22 70 94 a0 d9 fa 1e 8c + 40 24 30 9c e1 ec cc b5 21 00 35 d4 7a c7 2e 8a''', + # Random + '''18 b7 76 ea 21 06 9d 69 77 6a 33 e9 6b ad 48 e1 + dd a0 a5 ef''', + SHA1 + ), + + # + # From in oaep-vect.txt to be found in Example 2.1 + # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip + # + ( + # Private key + { + 'n':'''01 94 7c 7f ce 90 42 5f 47 27 9e 70 85 1f 25 d5 + e6 23 16 fe 8a 1d f1 93 71 e3 e6 28 e2 60 54 3e + 49 01 ef 60 81 f6 8c 0b 81 41 19 0d 2a e8 da ba + 7d 12 50 ec 6d b6 36 e9 44 ec 37 22 87 7c 7c 1d + 0a 67 f1 4b 16 94 c5 f0 37 94 51 a4 3e 49 a3 2d + de 83 67 0b 73 da 91 a1 c9 9b c2 3b 43 6a 60 05 + 5c 61 0f 0b af 99 c1 a0 79 56 5b 95 a3 f1 52 66 + 32 d1 d4 da 60 f2 0e da 25 e6 53 c4 f0 02 76 6f + 45''', + 'e':'''01 00 01''', + 'd':'''08 23 f2 0f ad b5 da 89 08 8a 9d 00 89 3e 21 fa + 4a 1b 11 fb c9 3c 64 a3 be 0b aa ea 97 fb 3b 93 + c3 ff 71 37 04 c1 9c 96 3c 1d 10 7a ae 99 05 47 + 39 f7 9e 02 e1 86 de 86 f8 7a 6d de fe a6 d8 cc + d1 d3 c8 1a 47 bf a7 25 5b e2 06 01 a4 a4 b2 f0 + 8a 16 7b 5e 27 9d 71 5b 1b 45 5b dd 7e ab 24 59 + 41 d9 76 8b 9a ce fb 3c cd a5 95 2d a3 ce e7 25 + 25 b4 50 16 63 a8 ee 15 c9 e9 92 d9 24 62 fe 39''' + }, + # Plaintext + '''8f f0 0c aa 60 5c 70 28 30 63 4d 9a 6c 3d 42 c6 + 52 b5 8c f1 d9 2f ec 57 0b ee e7''', + # Ciphertext + '''01 81 af 89 22 b9 fc b4 d7 9d 92 eb e1 98 15 99 + 2f c0 c1 43 9d 8b cd 49 13 98 a0 f4 ad 3a 32 9a + 5b d9 38 55 60 db 53 26 83 c8 b7 da 04 e4 b1 2a + ed 6a ac df 47 1c 34 c9 cd a8 91 ad dc c2 df 34 + 56 65 3a a6 38 2e 9a e5 9b 54 45 52 57 eb 09 9d + 56 2b be 10 45 3f 2b 6d 13 c5 9c 02 e1 0f 1f 8a + bb 5d a0 d0 57 09 32 da cf 2d 09 01 db 72 9d 0f + ef cc 05 4e 70 96 8e a5 40 c8 1b 04 bc ae fe 72 + 0e''', + # Random + '''8c 40 7b 5e c2 89 9e 50 99 c5 3e 8c e7 93 bf 94 + e7 1b 17 82''', + SHA1 + ), + + # + # From in oaep-vect.txt to be found in Example 10.1 + # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip + # + ( + # Private key + { + 'n':'''ae 45 ed 56 01 ce c6 b8 cc 05 f8 03 93 5c 67 4d + db e0 d7 5c 4c 09 fd 79 51 fc 6b 0c ae c3 13 a8 + df 39 97 0c 51 8b ff ba 5e d6 8f 3f 0d 7f 22 a4 + 02 9d 41 3f 1a e0 7e 4e be 9e 41 77 ce 23 e7 f5 + 40 4b 56 9e 4e e1 bd cf 3c 1f b0 3e f1 13 80 2d + 4f 85 5e b9 b5 13 4b 5a 7c 80 85 ad ca e6 fa 2f + a1 41 7e c3 76 3b e1 71 b0 c6 2b 76 0e de 23 c1 + 2a d9 2b 98 08 84 c6 41 f5 a8 fa c2 6b da d4 a0 + 33 81 a2 2f e1 b7 54 88 50 94 c8 25 06 d4 01 9a + 53 5a 28 6a fe b2 71 bb 9b a5 92 de 18 dc f6 00 + c2 ae ea e5 6e 02 f7 cf 79 fc 14 cf 3b dc 7c d8 + 4f eb bb f9 50 ca 90 30 4b 22 19 a7 aa 06 3a ef + a2 c3 c1 98 0e 56 0c d6 4a fe 77 95 85 b6 10 76 + 57 b9 57 85 7e fd e6 01 09 88 ab 7d e4 17 fc 88 + d8 f3 84 c4 e6 e7 2c 3f 94 3e 0c 31 c0 c4 a5 cc + 36 f8 79 d8 a3 ac 9d 7d 59 86 0e aa da 6b 83 bb''', + 'e':'''01 00 01''', + 'd':'''05 6b 04 21 6f e5 f3 54 ac 77 25 0a 4b 6b 0c 85 + 25 a8 5c 59 b0 bd 80 c5 64 50 a2 2d 5f 43 8e 59 + 6a 33 3a a8 75 e2 91 dd 43 f4 8c b8 8b 9d 5f c0 + d4 99 f9 fc d1 c3 97 f9 af c0 70 cd 9e 39 8c 8d + 19 e6 1d b7 c7 41 0a 6b 26 75 df bf 5d 34 5b 80 + 4d 20 1a dd 50 2d 5c e2 df cb 09 1c e9 99 7b be + be 57 30 6f 38 3e 4d 58 81 03 f0 36 f7 e8 5d 19 + 34 d1 52 a3 23 e4 a8 db 45 1d 6f 4a 5b 1b 0f 10 + 2c c1 50 e0 2f ee e2 b8 8d ea 4a d4 c1 ba cc b2 + 4d 84 07 2d 14 e1 d2 4a 67 71 f7 40 8e e3 05 64 + fb 86 d4 39 3a 34 bc f0 b7 88 50 1d 19 33 03 f1 + 3a 22 84 b0 01 f0 f6 49 ea f7 93 28 d4 ac 5c 43 + 0a b4 41 49 20 a9 46 0e d1 b7 bc 40 ec 65 3e 87 + 6d 09 ab c5 09 ae 45 b5 25 19 01 16 a0 c2 61 01 + 84 82 98 50 9c 1c 3b f3 a4 83 e7 27 40 54 e1 5e + 97 07 50 36 e9 89 f6 09 32 80 7b 52 57 75 1e 79''' + }, + # Plaintext + '''8b ba 6b f8 2a 6c 0f 86 d5 f1 75 6e 97 95 68 70 + b0 89 53 b0 6b 4e b2 05 bc 16 94 ee''', + # Ciphertext + '''53 ea 5d c0 8c d2 60 fb 3b 85 85 67 28 7f a9 15 + 52 c3 0b 2f eb fb a2 13 f0 ae 87 70 2d 06 8d 19 + ba b0 7f e5 74 52 3d fb 42 13 9d 68 c3 c5 af ee + e0 bf e4 cb 79 69 cb f3 82 b8 04 d6 e6 13 96 14 + 4e 2d 0e 60 74 1f 89 93 c3 01 4b 58 b9 b1 95 7a + 8b ab cd 23 af 85 4f 4c 35 6f b1 66 2a a7 2b fc + c7 e5 86 55 9d c4 28 0d 16 0c 12 67 85 a7 23 eb + ee be ff 71 f1 15 94 44 0a ae f8 7d 10 79 3a 87 + 74 a2 39 d4 a0 4c 87 fe 14 67 b9 da f8 52 08 ec + 6c 72 55 79 4a 96 cc 29 14 2f 9a 8b d4 18 e3 c1 + fd 67 34 4b 0c d0 82 9d f3 b2 be c6 02 53 19 62 + 93 c6 b3 4d 3f 75 d3 2f 21 3d d4 5c 62 73 d5 05 + ad f4 cc ed 10 57 cb 75 8f c2 6a ee fa 44 12 55 + ed 4e 64 c1 99 ee 07 5e 7f 16 64 61 82 fd b4 64 + 73 9b 68 ab 5d af f0 e6 3e 95 52 01 68 24 f0 54 + bf 4d 3c 8c 90 a9 7b b6 b6 55 32 84 eb 42 9f cc''', + # Random + '''47 e1 ab 71 19 fe e5 6c 95 ee 5e aa d8 6f 40 d0 + aa 63 bd 33''', + SHA1 + ), + ) + + def testEncrypt1(self): + # Verify encryption using all test vectors + for test in self._testData: + # Build the key + comps = [ long(rws(test[0][x]),16) for x in ('n','e') ] + key = RSA.construct(comps) + # RNG that takes its random numbers from a pool given + # at initialization + class randGen: + def __init__(self, data): + self.data = data + self.idx = 0 + def __call__(self, N): + r = self.data[self.idx:N] + self.idx += N + return r + # The real test + key._randfunc = randGen(t2b(test[3])) + cipher = PKCS.new(key, test[4]) + ct = cipher.encrypt(t2b(test[1])) + self.assertEqual(ct, t2b(test[2])) + + def testEncrypt2(self): + # Verify that encryption fails if plaintext is too long + pt = '\x00'*(128-2*20-2+1) + cipher = PKCS.new(self.key1024) + self.assertRaises(ValueError, cipher.encrypt, pt) + + def testDecrypt1(self): + # Verify decryption using all test vectors + for test in self._testData: + # Build the key + comps = [ long(rws(test[0][x]),16) for x in ('n','e','d') ] + key = RSA.construct(comps) + # The real test + cipher = PKCS.new(key, test[4]) + pt = cipher.decrypt(t2b(test[2])) + self.assertEqual(pt, t2b(test[1])) + + def testDecrypt2(self): + # Simplest possible negative tests + for ct_size in (127,128,129): + cipher = PKCS.new(self.key1024) + self.assertRaises(ValueError, cipher.decrypt, bchr(0x00)*ct_size) + + def testEncryptDecrypt1(self): + # Encrypt/Decrypt messages of length [0..128-2*20-2] + for pt_len in xrange(0,128-2*20-2): + pt = self.rng(pt_len) + ct = PKCS.encrypt(pt, self.key1024) + pt2 = PKCS.decrypt(ct, self.key1024) + self.assertEqual(pt,pt2) + + def testEncryptDecrypt1(self): + # Helper function to monitor what's requested from RNG + global asked + def localRng(N): + global asked + asked += N + return self.rng(N) + # Verify that OAEP is friendly to all hashes + for hashmod in (MD2,MD5,SHA1,SHA256,RIPEMD): + # Verify that encrypt() asks for as many random bytes + # as the hash output size + asked = 0 + pt = self.rng(40) + self.key1024._randfunc = localRng + cipher = PKCS.new(self.key1024, hashmod) + ct = cipher.encrypt(pt) + self.assertEqual(cipher.decrypt(ct), pt) + self.failUnless(asked > hashmod.digest_size) + + def testEncryptDecrypt2(self): + # Verify that OAEP supports labels + pt = self.rng(35) + xlabel = self.rng(22) + cipher = PKCS.new(self.key1024, label=xlabel) + ct = cipher.encrypt(pt) + self.assertEqual(cipher.decrypt(ct), pt) + + def testEncryptDecrypt3(self): + # Verify that encrypt() uses the custom MGF + global mgfcalls + # Helper function to monitor what's requested from MGF + def newMGF(seed,maskLen): + global mgfcalls + mgfcalls += 1 + return bchr(0x00)*maskLen + mgfcalls = 0 + pt = self.rng(32) + cipher = PKCS.new(self.key1024, mgfunc=newMGF) + ct = cipher.encrypt(pt) + self.assertEqual(mgfcalls, 2) + self.assertEqual(cipher.decrypt(ct), pt) + +def get_tests(config={}): + tests = [] + tests += list_test_cases(PKCS1_OAEP_Tests) + return tests + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_pkcs1_oaep.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Cipher/test_pkcs1_oaep.pyo new file mode 100644 index 0000000000000000000000000000000000000000..3ec7ec2fd74e5c58bd551c3f4adc3973c79c8504 GIT binary patch literal 15589 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 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/__init__.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/__init__.py new file mode 100644 index 00000000..bb19f9b3 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/__init__.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Hash/__init__.py: Self-test for hash modules +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test for hash modules""" + +__revision__ = "$Id$" + +def get_tests(config={}): + tests = [] + from Crypto.SelfTest.Hash import test_HMAC; tests += test_HMAC.get_tests(config=config) + from Crypto.SelfTest.Hash import test_MD2; tests += test_MD2.get_tests(config=config) + from Crypto.SelfTest.Hash import test_MD4; tests += test_MD4.get_tests(config=config) + from Crypto.SelfTest.Hash import test_MD5; tests += test_MD5.get_tests(config=config) + from Crypto.SelfTest.Hash import test_RIPEMD; tests += test_RIPEMD.get_tests(config=config) + from Crypto.SelfTest.Hash import test_SHA; tests += test_SHA.get_tests(config=config) + from Crypto.SelfTest.Hash import test_SHA256; tests += test_SHA256.get_tests(config=config) + try: + from Crypto.SelfTest.Hash import test_SHA224; tests += test_SHA224.get_tests(config=config) + from Crypto.SelfTest.Hash import test_SHA384; tests += test_SHA384.get_tests(config=config) + from Crypto.SelfTest.Hash import test_SHA512; tests += test_SHA512.get_tests(config=config) + except ImportError: + import sys + sys.stderr.write("SelfTest: warning: not testing SHA224/SHA384/SHA512 modules (not available)\n") + return tests + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/__init__.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..6abf66d3ccfad8a656aaecb14fae4a54e556c01b GIT binary patch literal 1728 zcmcgtOKaOe5T2E7`JIL~v@}rAAqVwfw{em_LJ18{ASp=*a-by$gks5#99c5jb%Mb< zCFlN|Ui!EC1KOEgyDhPL=%E$tXgvGvJieKgbKmNf%TMd1OQqhxT- zAV5WfJJdDsbKvFRN`vGGygYaX2=j1`iVk;pqyT;%20C~}@JetCj750303EYTo>x(H z{IJ&$J{LwWPK-;JUmC;M8;3sUdE8z*^wzozl{&5ht~M_I6)k;$lu=5UOb9S!kZQoD z45k_kG)ij<6!P^9m6xa-q&bDkWumYE^p%G+uTYqNhA&;B3Xm2Qs*s5)N|X+%u26a= zsw7cGNQ(+p%tVzXssw3Cp-Ky=$+aY-B7tQ{%L-Ut01{*5T>?@!maH=V1393@xp#R~g3E zEW}TTh}?LSVcc48@gs~%6Mcr&Y#TRj5(QCz+lXReP=WZvpg^t77s?C0@Z5al4U>@W zwHt))Md&}Tn9Eeg3W|0z8Hu<#ciud}n_{6|vDf#7Ljky@p~<4VYti+w=*n2cs8u9E zTv|l8RY4)Bro-VVPQ-qaprmtr!etA%@cbkZ=x!o(b?{iy`V9!agi3Hnmf+!G< z(;Q8#8oGOii*KR;rn6;u{Ku91ZD*C$S&gkQK@2(0&@K^c&f&&@-UFZ%kJa=au)8V*Ot3AKx zjzdA&$i8w)$)v#$Bpk +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-testing for PyCrypto hash modules""" + +__revision__ = "$Id$" + +import sys +import unittest +import binascii +from Crypto.Util.py3compat import * + +# For compatibility with Python 2.1 and Python 2.2 +if sys.hexversion < 0x02030000: + # Python 2.1 doesn't have a dict() function + # Python 2.2 dict() function raises TypeError if you do dict(MD5='blah') + def dict(**kwargs): + return kwargs.copy() +else: + dict = dict + + +class HashDigestSizeSelfTest(unittest.TestCase): + + def __init__(self, hashmod, description, expected): + unittest.TestCase.__init__(self) + self.hashmod = hashmod + self.expected = expected + self.description = description + + def shortDescription(self): + return self.description + + def runTest(self): + self.failUnless(hasattr(self.hashmod, "digest_size")) + self.assertEquals(self.hashmod.digest_size, self.expected) + h = self.hashmod.new() + self.failUnless(hasattr(h, "digest_size")) + self.assertEquals(h.digest_size, self.expected) + + +class HashSelfTest(unittest.TestCase): + + def __init__(self, hashmod, description, expected, input): + unittest.TestCase.__init__(self) + self.hashmod = hashmod + self.expected = expected + self.input = input + self.description = description + + def shortDescription(self): + return self.description + + def runTest(self): + h = self.hashmod.new() + h.update(self.input) + + out1 = binascii.b2a_hex(h.digest()) + out2 = h.hexdigest() + + h = self.hashmod.new(self.input) + + out3 = h.hexdigest() + out4 = binascii.b2a_hex(h.digest()) + + # PY3K: hexdigest() should return str(), and digest() bytes + self.assertEqual(self.expected, out1) # h = .new(); h.update(data); h.digest() + if sys.version_info[0] == 2: + self.assertEqual(self.expected, out2) # h = .new(); h.update(data); h.hexdigest() + self.assertEqual(self.expected, out3) # h = .new(data); h.hexdigest() + else: + self.assertEqual(self.expected.decode(), out2) # h = .new(); h.update(data); h.hexdigest() + self.assertEqual(self.expected.decode(), out3) # h = .new(data); h.hexdigest() + self.assertEqual(self.expected, out4) # h = .new(data); h.digest() + + # Verify that new() object method produces a fresh hash object + h2 = h.new() + h2.update(self.input) + out5 = binascii.b2a_hex(h2.digest()) + self.assertEqual(self.expected, out5) + +class HashTestOID(unittest.TestCase): + def __init__(self, hashmod, oid): + unittest.TestCase.__init__(self) + self.hashmod = hashmod + self.oid = oid + + def runTest(self): + h = self.hashmod.new() + if self.oid==None: + try: + raised = 0 + a = h.oid + except AttributeError: + raised = 1 + self.assertEqual(raised,1) + else: + self.assertEqual(h.oid, self.oid) + +class MACSelfTest(unittest.TestCase): + + def __init__(self, hashmod, description, expected_dict, input, key, hashmods): + unittest.TestCase.__init__(self) + self.hashmod = hashmod + self.expected_dict = expected_dict + self.input = input + self.key = key + self.hashmods = hashmods + self.description = description + + def shortDescription(self): + return self.description + + def runTest(self): + for hashname in self.expected_dict.keys(): + hashmod = self.hashmods[hashname] + key = binascii.a2b_hex(b(self.key)) + data = binascii.a2b_hex(b(self.input)) + + # Strip whitespace from the expected string (which should be in lowercase-hex) + expected = b("".join(self.expected_dict[hashname].split())) + + h = self.hashmod.new(key, digestmod=hashmod) + h.update(data) + out1 = binascii.b2a_hex(h.digest()) + out2 = h.hexdigest() + + h = self.hashmod.new(key, data, hashmod) + + out3 = h.hexdigest() + out4 = binascii.b2a_hex(h.digest()) + + # Test .copy() + h2 = h.copy() + h.update(b("blah blah blah")) # Corrupt the original hash object + out5 = binascii.b2a_hex(h2.digest()) # The copied hash object should return the correct result + + # PY3K: hexdigest() should return str(), and digest() bytes + self.assertEqual(expected, out1) + if sys.version_info[0] == 2: + self.assertEqual(expected, out2) + self.assertEqual(expected, out3) + else: + self.assertEqual(expected.decode(), out2) + self.assertEqual(expected.decode(), out3) + self.assertEqual(expected, out4) + self.assertEqual(expected, out5) + +def make_hash_tests(module, module_name, test_data, digest_size, oid=None): + tests = [] + for i in range(len(test_data)): + row = test_data[i] + (expected, input) = map(b,row[0:2]) + if len(row) < 3: + description = repr(input) + else: + description = row[2].encode('latin-1') + name = "%s #%d: %s" % (module_name, i+1, description) + tests.append(HashSelfTest(module, name, expected, input)) + if oid is not None: + oid = b(oid) + name = "%s #%d: digest_size" % (module_name, i+1) + tests.append(HashDigestSizeSelfTest(module, name, digest_size)) + tests.append(HashTestOID(module, oid)) + return tests + +def make_mac_tests(module, module_name, test_data, hashmods): + tests = [] + for i in range(len(test_data)): + row = test_data[i] + (key, data, results, description) = row + name = "%s #%d: %s" % (module_name, i+1, description) + tests.append(MACSelfTest(module, name, results, data, key, hashmods)) + return tests + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/common.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/common.pyo new file mode 100644 index 0000000000000000000000000000000000000000..ed1504b44f569b07053df26a3204e8fd1c9703eb GIT binary patch literal 6723 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 E25-~_5&!@I literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_HMAC.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_HMAC.py new file mode 100644 index 00000000..c01c97b6 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_HMAC.py @@ -0,0 +1,223 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Hash/HMAC.py: Self-test for the HMAC module +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Hash.HMAC""" + +__revision__ = "$Id$" + +from common import dict # For compatibility with Python 2.1 and 2.2 +from Crypto.Util.py3compat import * + +# This is a list of (key, data, results, description) tuples. +test_data = [ + ## Test vectors from RFC 2202 ## + # Test that the default hashmod is MD5 + ('0b' * 16, + '4869205468657265', + dict(default='9294727a3638bb1c13f48ef8158bfc9d'), + 'default-is-MD5'), + + # Test case 1 (MD5) + ('0b' * 16, + '4869205468657265', + dict(MD5='9294727a3638bb1c13f48ef8158bfc9d'), + 'RFC 2202 #1-MD5 (HMAC-MD5)'), + + # Test case 1 (SHA1) + ('0b' * 20, + '4869205468657265', + dict(SHA1='b617318655057264e28bc0b6fb378c8ef146be00'), + 'RFC 2202 #1-SHA1 (HMAC-SHA1)'), + + # Test case 2 + ('4a656665', + '7768617420646f2079612077616e7420666f72206e6f7468696e673f', + dict(MD5='750c783e6ab0b503eaa86e310a5db738', + SHA1='effcdf6ae5eb2fa2d27416d5f184df9c259a7c79'), + 'RFC 2202 #2 (HMAC-MD5/SHA1)'), + + # Test case 3 (MD5) + ('aa' * 16, + 'dd' * 50, + dict(MD5='56be34521d144c88dbb8c733f0e8b3f6'), + 'RFC 2202 #3-MD5 (HMAC-MD5)'), + + # Test case 3 (SHA1) + ('aa' * 20, + 'dd' * 50, + dict(SHA1='125d7342b9ac11cd91a39af48aa17b4f63f175d3'), + 'RFC 2202 #3-SHA1 (HMAC-SHA1)'), + + # Test case 4 + ('0102030405060708090a0b0c0d0e0f10111213141516171819', + 'cd' * 50, + dict(MD5='697eaf0aca3a3aea3a75164746ffaa79', + SHA1='4c9007f4026250c6bc8414f9bf50c86c2d7235da'), + 'RFC 2202 #4 (HMAC-MD5/SHA1)'), + + # Test case 5 (MD5) + ('0c' * 16, + '546573742057697468205472756e636174696f6e', + dict(MD5='56461ef2342edc00f9bab995690efd4c'), + 'RFC 2202 #5-MD5 (HMAC-MD5)'), + + # Test case 5 (SHA1) + # NB: We do not implement hash truncation, so we only test the full hash here. + ('0c' * 20, + '546573742057697468205472756e636174696f6e', + dict(SHA1='4c1a03424b55e07fe7f27be1d58bb9324a9a5a04'), + 'RFC 2202 #5-SHA1 (HMAC-SHA1)'), + + # Test case 6 + ('aa' * 80, + '54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a' + + '65204b6579202d2048617368204b6579204669727374', + dict(MD5='6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd', + SHA1='aa4ae5e15272d00e95705637ce8a3b55ed402112'), + 'RFC 2202 #6 (HMAC-MD5/SHA1)'), + + # Test case 7 + ('aa' * 80, + '54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a' + + '65204b657920616e64204c6172676572205468616e204f6e6520426c6f636b2d' + + '53697a652044617461', + dict(MD5='6f630fad67cda0ee1fb1f562db3aa53e', + SHA1='e8e99d0f45237d786d6bbaa7965c7808bbff1a91'), + 'RFC 2202 #7 (HMAC-MD5/SHA1)'), + + ## Test vectors from RFC 4231 ## + # 4.2. Test Case 1 + ('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', + '4869205468657265', + dict(SHA256=''' + b0344c61d8db38535ca8afceaf0bf12b + 881dc200c9833da726e9376c2e32cff7 + '''), + 'RFC 4231 #1 (HMAC-SHA256)'), + + # 4.3. Test Case 2 - Test with a key shorter than the length of the HMAC + # output. + ('4a656665', + '7768617420646f2079612077616e7420666f72206e6f7468696e673f', + dict(SHA256=''' + 5bdcc146bf60754e6a042426089575c7 + 5a003f089d2739839dec58b964ec3843 + '''), + 'RFC 4231 #2 (HMAC-SHA256)'), + + # 4.4. Test Case 3 - Test with a combined length of key and data that is + # larger than 64 bytes (= block-size of SHA-224 and SHA-256). + ('aa' * 20, + 'dd' * 50, + dict(SHA256=''' + 773ea91e36800e46854db8ebd09181a7 + 2959098b3ef8c122d9635514ced565fe + '''), + 'RFC 4231 #3 (HMAC-SHA256)'), + + # 4.5. Test Case 4 - Test with a combined length of key and data that is + # larger than 64 bytes (= block-size of SHA-224 and SHA-256). + ('0102030405060708090a0b0c0d0e0f10111213141516171819', + 'cd' * 50, + dict(SHA256=''' + 82558a389a443c0ea4cc819899f2083a + 85f0faa3e578f8077a2e3ff46729665b + '''), + 'RFC 4231 #4 (HMAC-SHA256)'), + + # 4.6. Test Case 5 - Test with a truncation of output to 128 bits. + # + # Not included because we do not implement hash truncation. + # + + # 4.7. Test Case 6 - Test with a key larger than 128 bytes (= block-size of + # SHA-384 and SHA-512). + ('aa' * 131, + '54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a' + + '65204b6579202d2048617368204b6579204669727374', + dict(SHA256=''' + 60e431591ee0b67f0d8a26aacbf5b77f + 8e0bc6213728c5140546040f0ee37f54 + '''), + 'RFC 4231 #6 (HMAC-SHA256)'), + + # 4.8. Test Case 7 - Test with a key and data that is larger than 128 bytes + # (= block-size of SHA-384 and SHA-512). + ('aa' * 131, + '5468697320697320612074657374207573696e672061206c6172676572207468' + + '616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074' + + '68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565' + + '647320746f20626520686173686564206265666f7265206265696e6720757365' + + '642062792074686520484d414320616c676f726974686d2e', + dict(SHA256=''' + 9b09ffa71b942fcb27635fbcd5b0e944 + bfdc63644f0713938a7f51535c3a35e2 + '''), + 'RFC 4231 #7 (HMAC-SHA256)'), +] + +hashlib_test_data = [ + # Test case 8 (SHA224) + ('4a656665', + '7768617420646f2079612077616e74' + + '20666f72206e6f7468696e673f', + dict(SHA224='a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44'), + 'RFC 4634 8.4 SHA224 (HMAC-SHA224)'), + + # Test case 9 (SHA384) + ('4a656665', + '7768617420646f2079612077616e74' + + '20666f72206e6f7468696e673f', + dict(SHA384='af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649'), + 'RFC 4634 8.4 SHA384 (HMAC-SHA384)'), + + # Test case 10 (SHA512) + ('4a656665', + '7768617420646f2079612077616e74' + + '20666f72206e6f7468696e673f', + dict(SHA512='164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737'), + 'RFC 4634 8.4 SHA512 (HMAC-SHA512)'), + +] + +def get_tests(config={}): + global test_data + from Crypto.Hash import HMAC, MD5, SHA as SHA1, SHA256 + from common import make_mac_tests + hashmods = dict(MD5=MD5, SHA1=SHA1, SHA256=SHA256, default=None) + try: + from Crypto.Hash import SHA224, SHA384, SHA512 + hashmods.update(dict(SHA224=SHA224, SHA384=SHA384, SHA512=SHA512)) + test_data += hashlib_test_data + except ImportError: + import sys + sys.stderr.write("SelfTest: warning: not testing HMAC-SHA224/384/512 (not available)\n") + return make_mac_tests(HMAC, "HMAC", test_data, hashmods) + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_HMAC.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_HMAC.pyo new file mode 100644 index 0000000000000000000000000000000000000000..16b9077b7b1eccf8148063674973beef04436aff GIT binary patch literal 5465 zcmcgwdv9FD6`%DwPV6`#fdJ)Ex`ecKD0b#O_oft*252ad(oHBRvgFR4N7%$`N8TGy zBwMN!{_ZEM_yASaKl&B=0ovc0-SuOg(Ed?%tvmP5oHJ+6d(Lt9pJ$eK{=D7~Z1Q^% z?`wEQf1hJ4GIkeZhu!V4ILBg_ZO*Y_m)-5M4$bG;<~+L-Pq4VaF2s{8by+;c;v#zj z_!7(W>?rK?6t+Bto!Q@amc{4FzHn`mEAv`!if492FgDx zu%Ay)UIFYfi*K`+C!GDFP=BXTU!B2PV=u=m`E2%*;T`bz3jF=U@M|ny2iL#Ga|6!@WA1_bVZr@~ zaPOUG9&Q0Hf5YO~}1FUSPj3l;M60Yyh|Hv+v-U z@H)8MZT4V}?fi9)yz&m)Tx53_S^R>12M1naX_4KBgZzQTFNscP3!Cq-+bds@pI^do zJ8kCGHjUce=+U4}y}Z5CyRq~5VY|I{(~rJhyZPDm8>4w3Uivs*8vF~tl@4YtEyY1- z$1_@byG7VA-VDwWoCaOlT5_XpWsQ^8v?s9`Q}&NG+qQ@ATGrZ0=ap4e(}*Bc)>X=t zFjbR79Y<#mHmnXttDk*f+Afyx9=(cp|Dzi{DY@*uB?#7AA#UmG^56o%g~{7DuZwmC zv&IUi1XwYgxY0>gP2i2qjdE4Mu|nG>aXxx|hB8r@kfzVe?I|E=Z;iE(slvoLh$x(v z+-jR8ceNE5ofS5fRco^Yqc-79>ZtMMR4z(zh6h)vWPQUM!&UOWvPlWCU13iB!F z5VQ5kq(){hqjXx>XtJnu%yp2a_Aa=3^x6^T<$+4BjCm&;d0$Kw<3M6om@p7sX(L4x zT8FBNO;ZJ@ROYE_RJJqfRx|1@JPK)|Q(88)4?=`k3$JPqi+V3yqq9|6I1|;3g4OCV z1ru9baLEtzGh&``{J+5*`OU z4dv(Ty{ikuI@FxIthuxjMzBq&w9vV3GG>(xGCHYD^fOA;PgN>MEP!ozyK#z)ZXB3^ zu_*%J6#=WVyLN=)V}t{b3LPVb4=@l&&e6C9hCvHjGa|-9l*V`j$(Nd)o^dDOB*1OvW<)e z*v_}_fQU5!H9$rRfV*-e1H>PxW4fv>kR>T=Y_dl92K?(Lx+Yf{p(&FM$%>|q9Cju3 zdao%4gpp20&Qon1H&(fjDz8Wb5!Qrf%$Up`Ga1Qwm_-Uz3#&a-O4zL6ACk6x9z@0> z7Z8jI^NO)F&65I0H5kh9xI9=(EdC|PT%1d{cH|1lGnk8@#~7y_l^jLW!VTnMi=4G}vc_d~V7?h$OjFuK7lS9T*KxC0Xh8`B zl_UhG%RE+ITJHlAX5(Bw$_j9TMT&N^3Qz>q0m$aKP?B=l=zZiFR;HmkVP%?-aA!J& z8+1I!i zaw%@ljQc*-$s)HRi6$>miQpp92;?e9Zj#ocH*rkKNml7zwWfQ-qC6Z4QeU1XOC*x^ zkJx~6#z2|Ka=Ox7QR$Ig6=j1MwGA{GTtc|%jI1OY?GkSGpkOow(%K;5ULl&@!f8Bdb=X(C;0b4gz!`>vp3I}!qAupvxObwqsk9~3 zsr1Q}OG5+K>tDoV+)WYw&_75ULmxJ%HyahqKDAE;txsfDs1xeHO#{_i{k7xM5owt^ zygMLrwfC*x*&1x!yV~2@ZhJ%*lU`|=#;$(_zICOTjS&1dez57A&2)LGPYGw`1q?0O z?@)hOAY<+XAceaUGhur;+}`R_CEv$07W&rqR+{0sAU}E-eVbbH3u0>nGvA)a>}#~3 zn}en(VZ2J`e>{A+z0-cUvxAY8FnT;HWJYaFJ3H+OEPcC!W_E>;C){l1!M#Jw9;lKy zEFB%4HQbJ)83y}Tfk5@uco=(o=P7a2+KYuHCZ-%IV-&VRvV^b!U(cd>J>^Jb^pdA)P7bGCD) zv)sARDSU3gEe2Z~8@B@C(T{pMvh?U2hL*AW9fn@$3BsWR@1v-@Rh*@4f3!7diGgzP z9emuTzQ6xIunwdwU;lGaPvMMrH~p}Q{=L89dxU4~QImfP5Iej-q!v5>D z{2_)Clcd-Giw@vsk2ceLR27fD$FMNBFn6xAv~UvkUhXV(XW!lNdV!prV2t10PI({f znLoUDo^T1)Jw5)KCrS%ltR4C~2^!P2$=4!LnV+nlJn=<0TL$3(fBFujTpWv&%ST GvGZ>U8f_Q= literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD2.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD2.py new file mode 100644 index 00000000..db636d4c --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD2.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Hash/MD2.py: Self-test for the MD2 hash function +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Hash.MD2""" + +__revision__ = "$Id$" + +from Crypto.Util.py3compat import * + +# This is a list of (expected_result, input[, description]) tuples. +test_data = [ + # Test vectors from RFC 1319 + ('8350e5a3e24c153df2275c9f80692773', '', "'' (empty string)"), + ('32ec01ec4a6dac72c0ab96fb34c0b5d1', 'a'), + ('da853b0d3f88d99b30283a69e6ded6bb', 'abc'), + ('ab4f496bfb2a530b219ff33031fe06b0', 'message digest'), + + ('4e8ddff3650292ab5a4108c3aa47940b', 'abcdefghijklmnopqrstuvwxyz', + 'a-z'), + + ('da33def2a42df13975352846c30338cd', + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', + 'A-Z, a-z, 0-9'), + + ('d5976f79d83d3a0dc9806c3c66f3efd8', + '1234567890123456789012345678901234567890123456' + + '7890123456789012345678901234567890', + "'1234567890' * 8"), +] + +def get_tests(config={}): + from Crypto.Hash import MD2 + from common import make_hash_tests + return make_hash_tests(MD2, "MD2", test_data, + digest_size=16, + oid="\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02") + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD2.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD2.pyo new file mode 100644 index 0000000000000000000000000000000000000000..8b499b3d6e0ce4b12f8c08924d9cadcf415f7df0 GIT binary patch literal 1818 zcmcgs-E-SS5MRlOlZJ$rff7O?AQ~{TVNYBI@h*t>KsX@Y2XPI=>mc3$aT!*{n@}`hxB&eIlxVsNPtbY}lt>Y|W0RdeYhEYQJ;umZ#=W@A_?Vz5ElumW7-qvY{QM5er-ya3(!J?*>d1p4SWV zxQN^^_If?0Q3up(NY>Y#mK;y@v7_{?tcD*Nd*;d9?aJKeq2PJX%UzzuVUaOEce6lr zO(rKQRbOn_;HvOna2a>W?nZg3dUU4 zEuAJmyr;t83wKwdprxc-*uy$aqjnG-_7)uI*5?PaKAh_ z9F42V^v9XfM-PAc`S?Vc9NH&m2{VRz9``*_bXnXBSl~r|m}43&%7xxUU!Q)qb?fsl zzTCcj=c~K-cD}yoGqFdr_=b$VIz&QXe z3yWSXA|@DjMIK{6a+Zf-!DJyK-9fXzot(RS$xdHG6O8y06*^UyP;LF(^}4g+L^N~ZgiLdB|IE(Em&kqruYEUOIpjq9+Faw&*feDBechHOy7)o7N>LX)n z0qYX}E?P}X)4iwZn3q+W?&Qdr&qivxVX6Q)ut3}RPQa;!Zv^#hr>=&~kE&8rOcRXK z*rf*}S;eFC!v2%$DEiG2A7_GZevEsC>#UWs;721(*=TB)dBaS~31y#9fiHf0T6C09 zs}g$NYSy?Q8BSg;SwQ9mFGU@K@=ECHpACI2CKx3Iw13W~L9HgIX(}dpn(Ae +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Hash.MD4""" + +__revision__ = "$Id$" + +from Crypto.Util.py3compat import * + +# This is a list of (expected_result, input[, description]) tuples. +test_data = [ + # Test vectors from RFC 1320 + ('31d6cfe0d16ae931b73c59d7e0c089c0', '', "'' (empty string)"), + ('bde52cb31de33e46245e05fbdbd6fb24', 'a'), + ('a448017aaf21d8525fc10ae87aa6729d', 'abc'), + ('d9130a8164549fe818874806e1c7014b', 'message digest'), + + ('d79e1c308aa5bbcdeea8ed63df412da9', 'abcdefghijklmnopqrstuvwxyz', + 'a-z'), + + ('043f8582f241db351ce627e153e7f0e4', + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', + 'A-Z, a-z, 0-9'), + + ('e33b4ddc9c38f2199c3e7b164fcc0536', + '1234567890123456789012345678901234567890123456' + + '7890123456789012345678901234567890', + "'1234567890' * 8"), +] + +def get_tests(config={}): + from Crypto.Hash import MD4 + from common import make_hash_tests + return make_hash_tests(MD4, "MD4", test_data, + digest_size=16, + oid="\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x04") + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD4.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD4.pyo new file mode 100644 index 0000000000000000000000000000000000000000..bc96f286d8c02f21b1815ffe22e274518107c63b GIT binary patch literal 1818 zcmcgs>u=md5Fh(4moy}_2uetyU`nMNQSapU1C$ z_M5h}3d0ukTEMTsV{|ePq6G&Fz~2S_9-M+ePQ#I*sGr8ZryXDI!%3Z(3uUCKL(>9P(MAnss)N^=Pl)~mt$VB2fdE^yA!Xsf9 zcAONpLK%>6AX!_p+F~?S$CgyHYCQN@>*rhqZjqxI;d#OjT|W?ZQ06@6VVS$WcEz+P z^ZnR%BF0MB;c?&wW#QON#JCeiZo*Xqy|BE{!aQ+2o5fD(2YynD*oor^)kEPFk?r`o zd>w^HLP|Ce7Ow_af?6+1P{gxi#)3RAxDYHBJoI?!J1%F5x>7sgq8#j32ZzJacryKY zCe_h{Uw%D4kvfLXiMD0?UKt0mTe`l(b1!fT5xS9Z0#8JxEqt|swm$!2bL-2mzTUod z`|N9?){Hcej{ErvgaXmi>qd1YvWTMl%VX@B14a@E%+B4QN_cC2umdktT~zzm$ho-}{HbfGf*xNWLZ|W)imjcSUbEJ%xFEbxWfpL4 z;*vL!-~=H2hu8)K9vNT|uV-P@fJY`64^4Q8TTM_+;D~g@^*rzeIBl4_ZJMZ^XAnu& z5v(;lFCsHyha%fY3}*yynbMwm4N2YXOjakNqF^;_CKZ>9$g~#LpKL$*YuRkJ=bkD& zGY_?u7M>K7(P%PGwE>ESoMfCS)}}~QEix{vfmYFSZ9D)?&kL zFB&aFQQfm_#Hw+Y?G(u9$3&{Tp|b!uFhH4jPr#{xcLeopr_P4dkH(cEpV}FPu}c?5 zx`IdNiM^EU$otJ98|9pBe2V`P*I6q?$&QAKqEXZ?eTV6gQ;I&N1fPHRwCO0NR;6^k z)vPu_dpLRZ&O9>DxhZNF6jw^6e>(K_Ho+(*p#66?HEI=M|CxAD$!dbl zQI~P!3~={VHN@_E2(>9wDV^wYpLKK0Mk347RocFa1gC^hUyWZyJ4O?JG!z@;T#~<* d*)kXB8isyxb{n{e65lkI8cXv_#*%Tt_y^U`mXZJf literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD5.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD5.py new file mode 100644 index 00000000..2e293fc8 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD5.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Hash/MD5.py: Self-test for the MD5 hash function +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Hash.MD5""" + +__revision__ = "$Id$" + +from Crypto.Util.py3compat import * + +# This is a list of (expected_result, input[, description]) tuples. +test_data = [ + # Test vectors from RFC 1321 + ('d41d8cd98f00b204e9800998ecf8427e', '', "'' (empty string)"), + ('0cc175b9c0f1b6a831c399e269772661', 'a'), + ('900150983cd24fb0d6963f7d28e17f72', 'abc'), + ('f96b697d7cb7938d525a2f31aaf161d0', 'message digest'), + + ('c3fcd3d76192e4007dfb496cca67e13b', 'abcdefghijklmnopqrstuvwxyz', + 'a-z'), + + ('d174ab98d277d9f5a5611c2c9f419d9f', + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', + 'A-Z, a-z, 0-9'), + + ('57edf4a22be3c955ac49da2e2107b67a', + '1234567890123456789012345678901234567890123456' + + '7890123456789012345678901234567890', + "'1234567890' * 8"), +] + +def get_tests(config={}): + from Crypto.Hash import MD5 + from common import make_hash_tests + return make_hash_tests(MD5, "MD5", test_data, + digest_size=16, + oid="\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05") + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD5.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_MD5.pyo new file mode 100644 index 0000000000000000000000000000000000000000..5bf1f20f9dd039dc38938466c2e84319efbf9050 GIT binary patch literal 1818 zcmcgs-ESL35TCOXCk+WLf)Y|F9HmlBR9pAuyIWKuAO+IWhH^>yuq>VSZugu^e75m! z3W-`CNYzLFSsr+VnZ1-$qVx^U+VRfpeD3^ao4>Ct&3+psIh=hL@c$EB>Q^KJppVpo zz6GKIq6wo0?1`%&-Uaa<2ph!vAg+OU9mE?TF2kyL6N)Ab7ogvS5=~d(30lvAoCon1 z95!I~i}ADuqZagAAg;g@46*>S1qX{D-UjgwoPuSI(RdAZ+aFLaM0Vw<=xC|5t&U19 z?P4;sw`RvvJ?U<9wcovWtEc8r@A_?Vz5EluwuPJ~vY~CHB5*~V3lB0t9Z;_!Szou?vYP5+Tj^Oj9)4)-ojiA=UdD2#aI=udzMK1uNiSqkDsU*y6UQRp&H296VnA`4iU=RAz0>u35(9Yn}txL+O| zj;irw`r}OLqlZ8Je0-uz4xJO@OSng(!Cf5YaTlN+|vVJ31f zlA;K>=Vj8*S+B?QfC=tN&vl|KjJWQi+22mi-MwU|ub~M>e2EI3s!OQ0e(rkR-mv4G z@Ip7Uh-(X%x`_lQ0O3EvHdyf30*iPv3sn;yH^6$-fJZ2r13d=+C&Bkt< zCTiz7M3Q#|YYoqf$W;7Lru&HDl;EurlId5F)Xh#+c_K?n*1%>`3blkxYjNZ0_R~LB z8uRV>X9myBL+z!7C;6nRCga37pj;?OD!Art%0$;HcWIVWAW&?$@*qQSD5YedybpivL)jbR|pvfGVfLL)C%_xDP)ODo+ zGNu-=F5&N@)v`3*dzx0f9H;3{j*R&lNKH3P6#xeo=mx$MaBATjK|R~4t0D8Faj7Y$ z2}Wt`(u0w#;?a3w|4DTe{pN^Qnc$lr<6hx9Yo#ps(MVG^n%ZUFFq3jZ*(X%si{G9$ z9VOJNgr2vWH7-bolUGX?ka@vNQHP+s61w_lLtl#tMhOA!pR;LDtI27aib kn-pA8yjG*tSekEI=7+P}#6^_&IcvGOys&I7TNkXq06}_{UH||9 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_RIPEMD.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_RIPEMD.py new file mode 100644 index 00000000..6673a934 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_RIPEMD.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Hash/test_RIPEMD.py: Self-test for the RIPEMD-160 hash function +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +#"""Self-test suite for Crypto.Hash.RIPEMD""" + +__revision__ = "$Id$" + +from Crypto.Util.py3compat import * + +# This is a list of (expected_result, input[, description]) tuples. +test_data = [ + # Test vectors downloaded 2008-09-12 from + # http://homes.esat.kuleuven.be/~bosselae/ripemd160.html + ('9c1185a5c5e9fc54612808977ee8f548b2258d31', '', "'' (empty string)"), + ('0bdc9d2d256b3ee9daae347be6f4dc835a467ffe', 'a'), + ('8eb208f7e05d987a9b044a8e98c6b087f15a0bfc', 'abc'), + ('5d0689ef49d2fae572b881b123a85ffa21595f36', 'message digest'), + + ('f71c27109c692c1b56bbdceb5b9d2865b3708dbc', + 'abcdefghijklmnopqrstuvwxyz', + 'a-z'), + + ('12a053384a9c0c88e405a06c27dcf49ada62eb2b', + 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', + 'abcdbcd...pnopq'), + + ('b0e20b6e3116640286ed3a87a5713079b21f5189', + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', + 'A-Z, a-z, 0-9'), + + ('9b752e45573d4b39f4dbd3323cab82bf63326bfb', + '1234567890' * 8, + "'1234567890' * 8"), + + ('52783243c1697bdbe16d37f97f68f08325dc1528', + 'a' * 10**6, + '"a" * 10**6'), +] + +def get_tests(config={}): + from Crypto.Hash import RIPEMD + from common import make_hash_tests + return make_hash_tests(RIPEMD, "RIPEMD", test_data, + digest_size=20, + oid="\x06\x05\x2b\x24\x03\02\x01") + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_RIPEMD.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_RIPEMD.pyo new file mode 100644 index 0000000000000000000000000000000000000000..af087c6cf9b1ab4f123bad2ce75d3f474e58f2d3 GIT binary patch literal 2021 zcmcIlTXPge6h5;{Hh@9U0ugVl7|jyM*4%og$BGn^fJ8}*6Y#RNRa@QD-J2nMiRliS z6g-7DtMteE1N5AkXta!v%Jv~4pgN##g1Q3gEl^kCvU(d#6Vx?Ov!E8S{T{W4=b+bs5^>&# zmmc(*pwEE%0CpO%_e%wS9Y!;zLk3;0Qc#g3i}rt8 zQ;|tOjs@2lFB0kV)C5fU(iE9E2KLgBM0;<3mIzu;WQJ}OU;M-?bkD3OF1t91MrQx;0& z&k#7_69usl5pfY6F%l{961BZ};@s_atGE=AAIp}?aQwot#5q2`Axp{_{q25eg8ub7x;f-^>J}ymZUth7YJgh zce^c?4sW;prL0nr$&`gUW-N_VETarFE>#qTQ6VG`rAhERkw&`n=>9jDU!KLLy@Y1r zq;sLY*ya@~3sWA2aa06JmP#dckfmq`2w2EVLM>Z_^%|NR;s!zl{^DX% z&^D(;5zz`hb{Wlab>i;u;DrYswVN<%z_Lz zTl39^*O{RKn!U1ju-TpL-1cC? z9-dm1wv9R$5XXG(szj8hG<%i^R1>=-B{k>HUDLs T-mKSZkezGJ&CYpq-Z}42_&ds^ literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA.py new file mode 100644 index 00000000..7d72e772 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Hash/SHA.py: Self-test for the SHA-1 hash function +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Hash.SHA""" + +__revision__ = "$Id$" + +from Crypto.Util.py3compat import * + +# Test vectors from various sources +# This is a list of (expected_result, input[, description]) tuples. +test_data = [ + # FIPS PUB 180-2, A.1 - "One-Block Message" + ('a9993e364706816aba3e25717850c26c9cd0d89d', 'abc'), + + # FIPS PUB 180-2, A.2 - "Multi-Block Message" + ('84983e441c3bd26ebaae4aa1f95129e5e54670f1', + 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'), + + # FIPS PUB 180-2, A.3 - "Long Message" +# ('34aa973cd4c4daa4f61eeb2bdbad27316534016f', +# 'a' * 10**6, +# '"a" * 10**6'), + + # RFC 3174: Section 7.3, "TEST4" (multiple of 512 bits) + ('dea356a2cddd90c7a7ecedc5ebb563934f460452', + '01234567' * 80, + '"01234567" * 80'), +] + +def get_tests(config={}): + from Crypto.Hash import SHA + from common import make_hash_tests + return make_hash_tests(SHA, "SHA", test_data, + digest_size=20, + oid="\x06\x05\x2B\x0E\x03\x02\x1A") + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA.pyo new file mode 100644 index 0000000000000000000000000000000000000000..9670d352284829956a929376a1ab28da42624588 GIT binary patch literal 1355 zcmcgrOK;Oa5T3PLr!DD=#{o_eaEL&SocNI#6$B~=K&V0qTq;Y}+PhA-^&@1rNFaJD zXZ|cd0A@Bt@CU&8cCtI3*?D|p_s90u@_RZh;QCp||L3^$ClmtU1SNwL2Eqa1Lgm1F zaTCNX5E~#iL2SWoaRW*h<}RGLpwPSv-_TVd2r%^*oAL+aR;Oa zXL!pVh<&&M#u{|qfm#1H#eaZeCadzmNNsxhLK)dB+hy-)`FUa5!7Hv$2eVf%^cvbd zd@UZTpZN3{o(zdcrjL>*NfO8)4#$2x8OA*4fgDBS;dm1H#V9V4Lil2m2;-7*URb9| zm`nm0hQlJr#VD3J=Q8AcSSHbMl*mX%VLbNBp_#0lL|zDqC=qkSDMBI65a);rQ6m~e zi&!8&+DJn3Ad2~@5JDt=G3H}gNKr&G&!adMY%kO<%Q{QmFa4%ubPujA+u+4(iMe6hh5Wk!kfsD&o_2xK%=vg}45A z$93-YY1pjwU!<Zs4T$9q(2Ww9OS397 z#Dm^K0c;O{yUb&jqAaVqYO?IOpm+2*xGWWWxG?}{42*-r4p$5Zod`Q#RYO%?G|Es+ z8;sJJ(bP|=&wmR0C)H8(!;06r;Lo1oUgNsvQI`CoGL(%Wy6lJ8r?RG$y(TK~!&zzQ zFr^RD4vrzJvrM!_mYJ^IFXbntRf{b$cTjOn`v;>c>~VmEFSwa*;~QJ_bx#{!%PgDj vlbXD6P-*Z~^FNwWx8kCb&+cMKeGi4_c+QsRy1?8Gmvvaz?RL7X%Qo3B>$) +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Hash.SHA224""" + +__revision__ = "$Id$" + +# Test vectors from various sources +# This is a list of (expected_result, input[, description]) tuples. +test_data = [ + + # RFC 3874: Section 3.1, "Test Vector #1 + ('23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7', 'abc'), + + # RFC 3874: Section 3.2, "Test Vector #2 + ('75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525', 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'), + + # RFC 3874: Section 3.3, "Test Vector #3 + ('20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67', 'a' * 10**6, "'a' * 10**6"), + + # Examples from http://de.wikipedia.org/wiki/Secure_Hash_Algorithm + ('d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f', ''), + + ('49b08defa65e644cbf8a2dd9270bdededabc741997d1dadd42026d7b', + 'Franz jagt im komplett verwahrlosten Taxi quer durch Bayern'), + + ('58911e7fccf2971a7d07f93162d8bd13568e71aa8fc86fc1fe9043d1', + 'Frank jagt im komplett verwahrlosten Taxi quer durch Bayern'), + +] + +def get_tests(config={}): + from Crypto.Hash import SHA224 + from common import make_hash_tests + return make_hash_tests(SHA224, "SHA224", test_data, + digest_size=28, + oid='\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04') + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA224.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA224.pyo new file mode 100644 index 0000000000000000000000000000000000000000..b2087db82d573c3e6c9417e2c0393f17659698c6 GIT binary patch literal 1864 zcmcIk-*4PR5FX!ME=>q(C;?h1$PX1gMM`9^e?t_N2B9E9R9*TMon+QK>pSPpc5>b; zq-vj1@yI{R9{@9UNO_Lbz1g|l@$NS>JNs?_?~gZ^e@(^;ZrVEiKcn8PNFl%(X$#IQ zz=wd30Ed9 z8sKN}j&O&d*WjG6J_q~)uEDY@+Pnj&qi@*#x1>(>BHuH*F?O>mjJET7X&)`GE=;|D zESuT>>G2Oj_|1TpKKU7+n3x8_bCL*!@O&r0Sco|Eh4iB+Ln(qF^MsU`DecqT$-F$$ zUZ@h3k?GTBnW+{e3cNVZ+%RxO6opC!n8^U8n`4|fZs25&3jH8ZnV$!=E(t^+NP>1V zfshB(Bss~HWJXeuoRiE+79=G}MN*SokX&}*J5l0?L6F3bN?eSyEc2DCWfFyMEd4BZ zyxbQ->?VGk39WstBZ*;TEDpceBwY+iH6M|BDxccBw(IQfhAlX{zH~&ag!H7yRN@n; zBeG1yF`bw4-GI!Fo5v#7G89tLd1+tdhOnST@RQ7mDJdBSI`n;&<*^iqiHMvGHT@|0 z$afPefr}E+7mf%q%9`&9;isjnUfbt#YV4x4=XH6p(8k!W^zwH(TQ2Ix=*oU6|0wLs zm0sGoTB@1-TwdvA)jAL2#C3I)E0v2Ra%F^0lqa4W3OXlry&#M=nPr@-ILwus>%{Rr zbZ?!{@8(?b+4A+cNBxL;b3lq%fjw9Nloq_Tz~Xry7Ck8Y@U{omn;yI&(*O+dfNp(9 zoO^KH@12e|2;ijnhuVn24VSFD&E5Py%}Y7g>5T4q$`okETwB9s#bQc^v?*Te;xQXJ zwz|N!=EIHO{yesHf6yC@*8bb^KhktC>`&EYSyy95G#n3mNl_X(V!SpaRabd2ZMU@R zM)Uz%)%;4Mqwgj!WQEfEanIdP_MOSam6_Gm7@Y+Teazu(=IJ>6dYJMykW;>z42-H}8i z4##kGX^OQ +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Hash.SHA256""" + +__revision__ = "$Id$" + +import unittest +from Crypto.Util.py3compat import * + +class LargeSHA256Test(unittest.TestCase): + def runTest(self): + """SHA256: 512/520 MiB test""" + from Crypto.Hash import SHA256 + zeros = bchr(0x00) * (1024*1024) + + h = SHA256.new(zeros) + for i in xrange(511): + h.update(zeros) + + # This test vector is from PyCrypto's old testdata.py file. + self.assertEqual('9acca8e8c22201155389f65abbf6bc9723edc7384ead80503839f49dcc56d767', h.hexdigest()) # 512 MiB + + for i in xrange(8): + h.update(zeros) + + # This test vector is from PyCrypto's old testdata.py file. + self.assertEqual('abf51ad954b246009dfe5a50ecd582fd5b8f1b8b27f30393853c3ef721e7fa6e', h.hexdigest()) # 520 MiB + +def get_tests(config={}): + # Test vectors from FIPS PUB 180-2 + # This is a list of (expected_result, input[, description]) tuples. + test_data = [ + # FIPS PUB 180-2, B.1 - "One-Block Message" + ('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad', + 'abc'), + + # FIPS PUB 180-2, B.2 - "Multi-Block Message" + ('248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1', + 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'), + + # FIPS PUB 180-2, B.3 - "Long Message" + ('cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0', + 'a' * 10**6, + '"a" * 10**6'), + + # Test for an old PyCrypto bug. + ('f7fd017a3c721ce7ff03f3552c0813adcc48b7f33f07e5e2ba71e23ea393d103', + 'This message is precisely 55 bytes long, to test a bug.', + 'Length = 55 (mod 64)'), + + # Example from http://de.wikipedia.org/wiki/Secure_Hash_Algorithm + ('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', ''), + + ('d32b568cd1b96d459e7291ebf4b25d007f275c9f13149beeb782fac0716613f8', + 'Franz jagt im komplett verwahrlosten Taxi quer durch Bayern'), + ] + + from Crypto.Hash import SHA256 + from common import make_hash_tests + tests = make_hash_tests(SHA256, "SHA256", test_data, + digest_size=32, + oid="\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01") + + if config.get('slow_tests'): + tests += [LargeSHA256Test()] + + return tests + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA256.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA256.pyo new file mode 100644 index 0000000000000000000000000000000000000000..2e19e5e12a04cb35e93fecfca90e0e1d07ed5816 GIT binary patch literal 3016 zcmcgu+io1k5v|#!mKQUSWXg)=OENYLV?$WX^xVgB3`Mj91(1bc$sh*N0e zJk6gWG|>^HM@Js%9_c>KdUS*i+8WLJbf|BT>Cwp=S*#e)cSM&&e>l2974+8WJE#uG ztdriL(;n4-`k|RkRyf*lCN@cLk$wyMp0|KvMux69h! zug}lg<=!LNO!p2R{VGh-W(`X}`HlXh`X0Y0Ll482#cq2O^0BNZrdxRkQ?HNAD<0x$ zZbKM2grku2tVg2*XGQUv8+aI=eLT%SAOH-Im=VoAdgYPVI*2YYyG3_i_2|N*lRjPa z2ve{6^x`9G*9eGV_|>;N^lFVR`gC&RYK8ao3;O*9(aC_3h|lWD>-X7F`k+ix|#r&Az!(( z)F1#myFB&M)XT<2*3`*rh)Hsy`3AlH&yRmA7g|PN-4}bsUT}PN-cFZ`o`!E>;3*z6X6%{EoWG%?-y{7# zrvf5fe?WH-rnXP|L()GX{ZpC@IG^-w(r^Dey^sYw-eCrs_c@(BqzH0L-{Cyd?~uMr z`p2Z-rOSSgQwy1dY`e!fQ~!l7)~H415luYG@ER0@se_>pZ=Se_EM=C9w6wVmgtA7) z0)K%viIxW89+g25r9wtUDzZ!#s*FWoZ7OUS1R{~z1)40CGZx0VPGu@|7^G2N<|a`= zm=;lhAWjj_GK!RmlOm0+4Mm#S)F`8MEDBu)sS<4tzhF$GAtj7Oo1jh6Dzp={Q?wb{ z9BqNNL_0%!>O4?L#1z{Wg@|oggt?GHWhTsHoxz99iaaP}oXZ$#8w4hZQympbsZ5Aa z>A(fHtT=`$PMwA`~1m`X=snWVYWqAXI4J2P2W2m@^74e!#o^k1!57h)2vs9Z)<}%lUk{7=4JY!w99p@mI(D-HL^+Cax+tRz}T`PQO!f z^?|{^=G8Y)0JtW>weFT844PdCu&UPw4fgweZ`~W9=lUSZ%|42Qchehqn_MD#S5;vy ztHpS%Se1W#+xvJLt_ukF6OZr#bBQkw54^~<{p7l)tQJ+v05~KL(K+Dnu+gVjb$xW# zdjsd+z%F0RyB zB`_GVr!B|z)n~)++G>VU8zCUhWb5!^oBOgcE+E`NNBn&_`ixci Y +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Hash.SHA384""" + +__revision__ = "$Id$" + +# Test vectors from various sources +# This is a list of (expected_result, input[, description]) tuples. +test_data = [ + + # RFC 4634: Section Page 8.4, "Test 1" + ('cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7', 'abc'), + + # RFC 4634: Section Page 8.4, "Test 2.2" + ('09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039', 'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu'), + + # RFC 4634: Section Page 8.4, "Test 3" + ('9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985', 'a' * 10**6, "'a' * 10**6"), + + # Taken from http://de.wikipedia.org/wiki/Secure_Hash_Algorithm + ('38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b', ''), + + # Example from http://de.wikipedia.org/wiki/Secure_Hash_Algorithm + ('71e8383a4cea32d6fd6877495db2ee353542f46fa44bc23100bca48f3366b84e809f0708e81041f427c6d5219a286677', + 'Franz jagt im komplett verwahrlosten Taxi quer durch Bayern'), + +] + +def get_tests(config={}): + from Crypto.Hash import SHA384 + from common import make_hash_tests + return make_hash_tests(SHA384, "SHA384", test_data, + digest_size=48, + oid='\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02') + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA384.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA384.pyo new file mode 100644 index 0000000000000000000000000000000000000000..7af8bc9a175a1e8d2d9966d01aae354b4344488c GIT binary patch literal 1914 zcmcH(U2oh(aD10sni7=s1KPriA1Zo^lxWwx_S#TYr9mi2P@zkoqLZ%snK(JyiM>~7 z)jqZ2kw421fLZ%cc}KOivpci1^F1^E>+_rKpYxf9^*6!&DXy+XU;s`LMsON|`4Y@M zFcUCaVD7_Ra}(Sc%mXlA!PzF9j-W)=UHE|9W3U@w_TX{^Z4KrYnA@;Ko=q@!-~$Ss zfZc=(6m%EN7w{gUsK&>);bi)C(ESa96T5T=-gZ9jR;9PGYufmzeSPJd!(-WvAnU`Q%tQYY4_Xl-Qs#InS!#2oQc0M}ibCov#j8Xlnk7;ZYpkIeqcT?+NhN2_ zrOKL|rUD#)xLj2}-%JIWx3KoECYa4OJZN zpp+^qm|}{gCP|zmL4idS-yo|NT2Ps$!X`!)S*DpSoGhr|8DWLL8k8C9&d!zYw{pE* z4A{kGxGOI%m+P$>u&VBfRo#R;+^*K!^?+TsJ@LBj!X0jYy{&rB3PUW-Ng-&)1;?PG z(K+LmQ6jmd8e_)`TWCUD!t*o{1;*9tR1mHcnJOYwu9(p*w_0iOv(O!)*HccMKU5qN~JC`Otm%zON3PzQ_C`$P-hf|o^oZ0 z;FuzU0aY$zF0<6gL~zWqa#mz6OPw+($Rv((v_KW9@~9JfO@g9#Ig?yl$r6(}ljTD2 zA~h)~Q#rR7DMtj!ZB7ZNjweEACQWD|lRV3W=)OZu zKen=d6JN+PAD2~p*;H3c>wWynw!g{qcG+~^*6|DZdl_G^Y#W?*p+4kOMohZcM(JZAH#A4)fnE5AbLB3w@BImkFAJ}H#F`Ict0MUOt(?M z^YU-}ra`z5Sr{5>z;_X^Fs>{`=xTeLIK=`gBuOO+5=$;CtCYsF7YygS_4(-PEo;>!0*|Q@ns4bid%~ z=-c_PvNn?aa6k`>Lo&a5?a!Nf{&T739nOq{E2%Ff8ap2hn1`A20@cjJ1epi77K7J^ z_%hgVX8qtTL!=9)L9~beZZwH}2>)VH$+BK7`q(|!fgyY&TzzKt@PL(d5rH4!T!Z%! z&a@EX=Yv;4#;PuT(A{ec=A489H@k&bA07NuUIqgmFJ+~Sd=kp2!?jMUb#k@z!5|+p z*N@$4@N5=%x{wu|eFLQ@2TJ+$*)9yUkkr{0f&mSh{%`3|gAgBNE*7TIi-q6m&#iq` zc4dQ!n1xd9W4F#vEh~%UJAr%;0hWKL<+AQ0`VoAB3JS(Pt{Ssi+9wb2+}%eo8BMmv T`0e3>XnSL4YbV-?wxfRl93t1I literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA512.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA512.py new file mode 100644 index 00000000..cb86177e --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA512.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Hash/test_SHA512.py: Self-test for the SHA-512 hash function +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Hash.SHA512""" + +__revision__ = "$Id$" + +# Test vectors from various sources +# This is a list of (expected_result, input[, description]) tuples. +test_data = [ + + # RFC 4634: Section Page 8.4, "Test 1" + ('ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f', 'abc'), + + # RFC 4634: Section Page 8.4, "Test 2.1" + ('8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909', 'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu'), + + # RFC 4634: Section Page 8.4, "Test 3" + ('e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b', 'a' * 10**6, "'a' * 10**6"), + + # Taken from http://de.wikipedia.org/wiki/Secure_Hash_Algorithm + ('cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e', ''), + + ('af9ed2de700433b803240a552b41b5a472a6ef3fe1431a722b2063c75e9f07451f67a28e37d09cde769424c96aea6f8971389db9e1993d6c565c3c71b855723c', 'Franz jagt im komplett verwahrlosten Taxi quer durch Bayern'), +] + +def get_tests(config={}): + from Crypto.Hash import SHA512 + from common import make_hash_tests + return make_hash_tests(SHA512, "SHA512", test_data, + digest_size=64, + oid="\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03") + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA512.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Hash/test_SHA512.pyo new file mode 100644 index 0000000000000000000000000000000000000000..4292f40c526fb9d5f4716b707dbd2a44e5c1dd79 GIT binary patch literal 2072 zcmcIl-ESN<5cl3Cm!qsEkZ?t3MGB2PCEQCPByvQOK$fH zty&4G6_5P0`~fiDJ*m8-I@+;kY>$64zq!fq?@zC;{+b>IvKb?sAK}-mP((srpe)FX zg2Y=S-X?KG;tq+Qlbi7>NkbCvkoW~T*(NUrq{5^76=B3C23B z!Ex#=;3%b6Dhlg3v)o$lxRxm}XGH0p2wXUk0KAV<$tWckr4#`S1@5d1Rwk!paMGrB zh#;H~9T)>vS+7-eAee~Ggd~&ZhGpMUB$Kq(Hk9CP(#bK6PdjkYm&RDijG`=ZV?kO< zlLjdS^VUWPh!zzWbQB!%`!YseDyhJhpp-XSda%^C7d@B=>EzUhZmKrZS+AX)=e_Fe ze7>0$y|$=3XJ)AB!(`Bz+t~%r8s>ypewVP?(MGl%7X+)#}bZJW|frI2h`@oc! zr7*yfHJ%BNv`B7LDY!FKxP-I_@DXTATuP&nq>?%rJe7h6P+AAf0(eSoP=N=e)}im5 zHI9r&69ToqEpp`5Rg_h(=jIa>U%Riz_r{FgyH|D~Lox!GP#Pe4<6~kfL!q%OqoGvC zl2edWQLi*pF&L4gvz$dy2CxC7jx;h6R5U7akBE(61{p)p5O^wuw}>@LjWy^Db4nP& zwM&-k=mfNgiF8QN1d&J36r&U#6Tu~QN^vilS59i~N=R6OST)RP&M|GJ2pS1bR7=HD zsU0^U5RpZKG3S!YU`wo~G8wCxFgAJ%%vur4ph^|+I`c*;%|&RwMI=A0T>W}{=1$si zwHTi-7Z-DA+wn_S{pLqyXfFq^$(6o zcHU+d`yYI-@1wqO=P*0PRxrz5qB+WU+RSvUPS7xGs@G6G%EpXsS;ejlM!UcM`LuxH z)?hf<&YSthfBH)ACchV!i^Z}&%2m{MzO&QlS~to5I!Iwzr|P7;(w&>&2I)leGp?R| zGyTQYNcQ*l*`Yn8(~DQ_>9U^wRQYLxJ?;L53+E2OPI~~;-1DB}Gt=DRra7!xAN3*L z%ot9f?W3irG#MHx4)AZk7!_?!|7^B!RXv+^xqBA!fjkEIb<7;#0xR#VAngGAE_qjA z&&?@*)<>0ntm~@HZ+9((4*`CxC^LWubGPu(J+!!P@Y~P|$*t#Y2GnNe zx_=9k9NAGm(_~h#_x6^~oGsO($NQwWWm1oJQ1ohk>Hn7gBs*!d&)F<4!)(^>b?X(p zteR?xL>%Q(?Q*x_r*;cK^Nno2jRMO**K$>N8T}wWLIq{84;IU~p2NdCxNdHt7!5`{ TLmUUg;b3>Tx3gF56}!d1Rf7eC literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/__init__.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/__init__.py new file mode 100644 index 00000000..a62c670f --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/__init__.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Protocol/__init__.py: Self-tests for Crypto.Protocol +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test for Crypto.Protocol""" + +__revision__ = "$Id$" + +def get_tests(config={}): + tests = [] + from Crypto.SelfTest.Protocol import test_chaffing; tests += test_chaffing.get_tests(config=config) + from Crypto.SelfTest.Protocol import test_rfc1751; tests += test_rfc1751.get_tests(config=config) + from Crypto.SelfTest.Protocol import test_AllOrNothing; tests += test_AllOrNothing.get_tests(config=config) + return tests + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/__init__.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..1f7f90ba53b0d125f7d92acc29124cc8a7407203 GIT binary patch literal 1068 zcmcIi%WB&|6ul$Ka?(1GZc4i-WD$xsHZ`S$loC?hO(8f&?xsdCC>qI@BTGgz4jAlJ z@?HI?_5<2;$B&fKZ3J^Py1I{Z&W!u(=-JQjKduwnJ}%yuSb6|ZL?fV}k)RwKhaRwZ zD0NA>bn8%kMam=9pu(dOHa8^Bcf0EwZ*rwK>VE z`lMGc=ceim>dI6}RcH?xr(e}+BCu&-aiE8#SAa3mS}-f{DTro*)((l4pp`>YhnXP@ zQ_r?pp3QP;?QXK%|7Jl0dU>?=Hd#>cPcKXu20jS%^WS&^CTETqphG5;ILq>KY&avS z$}AsmGFrQgI!n4|AG(|9i(T|{QC!#k%1lrjuvYU5uyurO`iAa%YeM`Z!#0jnBYCh6 z9ejm+ZniwMv}_~$7jgP4g+BuZ-3RnOMuWIi@%u0BZs)x7E}AdRq$;DU{3g=5N!#-{ zxsAuEjy8m%9ieDnHwoP^JU0W`E>O$fP^oO>E(Wz1H`19#d(PucCf#{bu7W2 zFBcl3sUYLv4C$UdXGQ&h71|yP%wy%&26kt-098BODtm+{&}bQaD&pCViZ9-RlExzQ z9H7!HUKEBI8FoT5t)R)j8KhKIBBkN`AZ4B2dcHP~* zxUQ0?_IL54;0M4rduJu$y{Ft}c6WAW_M30!-2LZf`uEGfo@LZNUHtzEuYZFfCpy8H zP~M?3p%V!B>r&aFs!JzbN_f6OY?Fqy zZF&c#9a1UfJ9O3|cOJEGuu@{6(V>%S{HHi@Tqq;75us3GU~A`9G=p#d#}iDXZiQ-GtzqSneur!Bv|)PCj^4gEav7iCh3LaOP0Fh}c-fpK%7F zmDIK7AKP=~4DJwow5*LsGHSj^LxSIw*$0|VpM%A1@Tav8U|M9x%-Jd?8uap&4ZFtfGE8ybVjzRrqt;k3y#iVX;XbJoqJ z(QnoVS{RT$R_5|#4oA)))CzoLl6VENvOc7xK2s%FV1=5^BE2IYMslVCxB>@PsY}DH z|Fw}9fG5LRe7KwZjMv}BpwI--#)#Y4Nr#4`*l{w}*~ZH~YJk_Hd#zg~QI*hT(zM6e zE-yRu`cDd7?w0705C0g_WtYMRoo>)Y!b_JBFx{lki&F^KcYAcv)==K?g)pJ>rJe z=gp|fr5~*i*<@f)bsS#@4yE$*X=$@FAJHw z@XPUH6$)#{DCDu%K^-h)b|w+vxVhJO1izf}@pET`&1^Ylm?qaTI)sfa*mkvH&2J!j zW({?3CA*s+CVQQ|?q0H&^dmTYqshd`N=+t#KVFkbW%IhkbjU2a3i!Q8J?y~WeY~E9 zUMEtOk>z*5>l|N*ALV%h#_)Rcb&W?GUU0V2d1iWk75aO{n)5wZVZw>5#2NQ=IPsm>%I6^0DCuyvO9`IIa+h(tCx4gZiPN(vKfQ_8dvCvzy#X(oXmGPUoXL IyWQR7KP>ymTL1t6 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_KDF.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_KDF.py new file mode 100644 index 00000000..119836bb --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_KDF.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Protocol/test_KDF.py: Self-test for key derivation functions +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +__revision__ = "$Id$" + +import unittest +from binascii import unhexlify + +from Crypto.SelfTest.st_common import list_test_cases +from Crypto.Hash import SHA as SHA1,HMAC + +from Crypto.Protocol.KDF import * + +def t2b(t): return unhexlify(b(t)) + +class PBKDF1_Tests(unittest.TestCase): + + # List of tuples with test data. + # Each tuple is made up by: + # Item #0: a pass phrase + # Item #1: salt (8 bytes encoded in hex) + # Item #2: output key length + # Item #3: iterations to use + # Item #4: expected result (encoded in hex) + _testData = ( + # From http://www.di-mgt.com.au/cryptoKDFs.html#examplespbkdf + ("password","78578E5A5D63CB06",16,1000,"DC19847E05C64D2FAF10EBFB4A3D2A20"), + ) + + def test1(self): + v = self._testData[0] + res = PBKDF1(v[0], t2b(v[1]), v[2], v[3], SHA1) + self.assertEqual(res, t2b(v[4])) + +class PBKDF2_Tests(unittest.TestCase): + + # List of tuples with test data. + # Each tuple is made up by: + # Item #0: a pass phrase + # Item #1: salt (encoded in hex) + # Item #2: output key length + # Item #3: iterations to use + # Item #4: expected result (encoded in hex) + _testData = ( + # From http://www.di-mgt.com.au/cryptoKDFs.html#examplespbkdf + ("password","78578E5A5D63CB06",24,2048,"BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643"), + # From RFC 6050 + ("password","73616c74", 20, 1, "0c60c80f961f0e71f3a9b524af6012062fe037a6"), + ("password","73616c74", 20, 2, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"), + ("password","73616c74", 20, 4096, "4b007901b765489abead49d926f721d065a429c1"), + ("passwordPASSWORDpassword","73616c7453414c5473616c7453414c5473616c7453414c5473616c7453414c5473616c74", + 25, 4096, "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038"), + ( 'pass\x00word',"7361006c74",16,4096, "56fa6aa75548099dcc37d7f03425e0c3"), + ) + + def test1(self): + # Test only for HMAC-SHA1 as PRF + + def prf(p,s): + return HMAC.new(p,s,SHA1).digest() + + for i in xrange(len(self._testData)): + v = self._testData[i] + res = PBKDF2(v[0], t2b(v[1]), v[2], v[3]) + res2 = PBKDF2(v[0], t2b(v[1]), v[2], v[3], prf) + self.assertEqual(res, t2b(v[4])) + self.assertEqual(res, res2) + +def get_tests(config={}): + tests = [] + tests += list_test_cases(PBKDF1_Tests) + tests += list_test_cases(PBKDF2_Tests) + return tests + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_KDF.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_KDF.pyo new file mode 100644 index 0000000000000000000000000000000000000000..a4501aa273e269cbfd5a4cab9ab0658c46601137 GIT binary patch literal 3649 zcmcgvS&th<5U!b7JMkXLCLxEDKoW?M35qrMco2&4sYQWh)s7UhGP1_gGn?7?*m!1h zNV`v)XCC<%`~)6&;J@(B4}hu~d%b`l2x()xYr3bax~uE>x~%=Swmkj5CqkHgG<<%6 zE&TH#kp|luC^TMz;S!7ruwBT<1sE1#bOyH1!l(q>rTlFX zhRg6so`E;G=nBZQ5Gk;`3NfxwqL)ViPqx=UE}xiKIi5HN32L$mZ%~c%5Uqn;gJ&vC ze+GGum%PAY7eSr}xsHn|$`}Py=vFS!ah8zW{Zigde#g&dMZsZKLb5-88oe4O@$3B6 zd3-fY(yX6FNWvhE(uzvFWS8znJ)?CtzOFZOc3S3MNR%4!G_j@YNHY8>aDeAh=+|X| zOLFk>z-^O1@XiQcTxHk%k$s3SQe zAx9^)e?nfakRdomI2c+%7Gxxm8%>;{S>nT}FtQcwpe3Sd)_%Sp3@fw>&!*@VcJ&K( z!4%^Or%un$tTg)5FmRWY^aW*2sVaOLK@l&Okt{qTNOcawx3JJz+2#HII2c9!ent!R z`=g26AL39@M2SnZ8nzSU6vA0h=zWBZ^SZcF)E4n<{w1DCOOEGHurrJ2D*aos0~ct2z=KLV>8x0-Kud?l2*XTLk=c2be*kB zn8R@6xN+bHf#=|nb>Ej^XnE3$b;~xLNDnQB8_Ez$Wrmxdu!Gq01^}Vv)sG7d-&JQY z-umu`Ij|tSAov_=bT=Gmj6|66)I%g9Ou`<55j_ZZmf&#dzp)~U5quRGzL26=zHadt zz6jWO=AZxsXU}iJV@Z%kN7)Ps$fz+q;WK4pqYPh2xIW_Hkp{bnlO#l;xLF})!MH_a z9K96h@X3%T6TD}#{30agJw~)sMl#Z3ZyM8Gn9^ZD`DdsmFS4euronh8VyGQPV}_&! zXqyb$g6??6enFukJ|Bm*Y-)`7rToQC$Glc(1N-)DQ;s}a_f8`=mi|cRWB4iOa=3Iio@_ig~S~Kp5 z4~}PVVNcwqSu%J&dk1@Y$dPX1GLd(Afn322U2JUC;)OnLr@GhiR&Jc z9fk$U9u62xaSvf)HfDgBjprFf(t;w3uPZ@Y<~c;+8cxP>vXjm4>r+l9y7)0KxROb~ z#Q_HiC`Dx*zq4z76eQz*Kg3!7kOBDcjHrwrgd1GZo;)H;?~jv=>P^OGDk!`ASfq+7 zuCd4=?wvv+u?C+HgV8_+5Bj)eUgA<^BcnLjA7-Qx+d3t+DwKF!G4%V>=tYty6Fj)k z=`E$)AQ=Z~m?U|jPAQYu*wuNBU8O$|)7RN8JfJul9y zSb66)ByC9QHSy2JB2d_Jf^)-01_mVZ&$}{aUe!GyP)P|wit4JeuC6Or)Md4#mM@h* KTrI9DCFKukX5c{p literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_chaffing.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_chaffing.py new file mode 100644 index 00000000..5fa01209 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_chaffing.py @@ -0,0 +1,74 @@ +# +# Test script for Crypto.Protocol.Chaffing +# +# Part of the Python Cryptography Toolkit +# +# Written by Andrew Kuchling and others +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +__revision__ = "$Id$" + +import unittest +from Crypto.Protocol import Chaffing + +text = """\ +When in the Course of human events, it becomes necessary for one people to +dissolve the political bands which have connected them with another, and to +assume among the powers of the earth, the separate and equal station to which +the Laws of Nature and of Nature's God entitle them, a decent respect to the +opinions of mankind requires that they should declare the causes which impel +them to the separation. + +We hold these truths to be self-evident, that all men are created equal, that +they are endowed by their Creator with certain unalienable Rights, that among +these are Life, Liberty, and the pursuit of Happiness. That to secure these +rights, Governments are instituted among Men, deriving their just powers from +the consent of the governed. That whenever any Form of Government becomes +destructive of these ends, it is the Right of the People to alter or to +abolish it, and to institute new Government, laying its foundation on such +principles and organizing its powers in such form, as to them shall seem most +likely to effect their Safety and Happiness. +""" + +class ChaffingTest (unittest.TestCase): + + def runTest(self): + "Simple tests of chaffing and winnowing" + # Test constructors + Chaffing.Chaff() + Chaffing.Chaff(0.5, 1) + self.assertRaises(ValueError, Chaffing.Chaff, factor=-1) + self.assertRaises(ValueError, Chaffing.Chaff, blocksper=-1) + + data = [(1, 'data1', 'data1'), (2, 'data2', 'data2')] + c = Chaffing.Chaff(1.0, 1) + c.chaff(data) + chaff = c.chaff(data) + self.assertEqual(len(chaff), 4) + + c = Chaffing.Chaff(0.0, 1) + chaff = c.chaff(data) + self.assertEqual(len(chaff), 2) + +def get_tests(config={}): + return [ChaffingTest()] + +if __name__ == "__main__": + unittest.main() diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_chaffing.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Protocol/test_chaffing.pyo new file mode 100644 index 0000000000000000000000000000000000000000..7d5f84fd5ec92cf6d78681ce40cae95c4a8e4556 GIT binary patch literal 2585 zcmcIl-EJF26rNotPO?qf&>}>*nv1IVBC%-U281ZWv<0bz$gZerS+d5vv))N|XUxoO zj8SrxJ{PaSEsucU0pL5cYZ8gx#>$+W**X8`n=_ri_maQf{PttY+Fu9%zs7Q>AQ@w0 z(1>L*Dw#j6~PB&SO<1Ty4*cD@M#$BeMy~W-_b&JVu zmTj}MnAto??~qWWArZ4tZ-;ztfIR#@d#L`w@3$gD$g~)TI=k5_CUKdhxrMWL8 zADG%Y$xY6Sx)PepbE&;MKuX~7GDuRP^~ zun-B)kgWFHO1D6~WDX~ZStt$b!5FG^rr_7Yv4R`~1OyAY;;t}tnURfBz#oN>irPV@ zDTS&QvZTnW)-Z1~f$e^hyq3H$(1!q8;%)5jl72Yf&nx#SFz5s(C>mX#7w=$QoiI zUoTZI4?$;8T(!-k<^xAHP=f-0Cl;s|Fw^I+LTwDSn{*FjOI+uE!hovbecy5ZpfMI|85a1mUAJG90&Zd;og zZqxFH??YaS6(y%ogWS|QYhVl{yE-kBg;hFLxNN8pFlX#sX!Yw_p)CWtN5XVH3Bv(1 z2(T7q8;z ze+QfEgKUpwciB8JpW~UqM0?r~Bzp=UOF!Hs@e3xBx=r~JACu$?Q z^KKjOP}>S>*)B%!JxcHq$Ot!_h6$<_W<}bL-B8=5(%OK`=a9tjkEbfk=PvkMq_~k` zYI_>wv(ltz7(v!k0Ral}SjFJ}+dgTH{P|Q-ncE#>$Gr}=!SIj{0%^XH{*cTC(%T{q ztFaj#h|qG3VYnR%g}LPuoc|=sT0XPZG{JFOL=?Jri^3CIh=#crzKn zE}?O9VvRScDJN9z>AKQ==u>94)+F^ASoa|a>m<>BbPyfHyV3nnk>$D9XRm9UWo%TZ5G*6~ei&xCyy+ff% zq}IxluBS3LE$**7+n_TbO8(-5IQ4WOoDAs>A3$fg4-$YzzOFM4+^wZep?}#x1fw! z3^*s}cl6L7(jV3SfOcjn#6f-NA#e!oXdkn)^Z54L%-@^qf1UiKfEj<3Rum%yH`UF1Xk?Rm{K(GZ<9TvYU?L6()V${%KQ22p-C8u9G z!K>&W{CWiqhjIl4Z=0n?t&~pC>}$D&(r#5M?MB148x^ZstX0HMIO#f;%^cUh6<)>m}SGZYRyuyR&UwWcC*;Fs@0NNt5h5Hy4XP_ZVdKW>j*{H z=^U_5zkk45hQ(Uk=`!Q3W3fG>-Nq@$WxVgQ!@h+|Z*6sg-EQxc+RawGW!7tzTCrI! znwHh5mg<(hQ!F+`gZ$*UrF-Ps%r%@2J2rTinfnH32mRh2+c%6oW;*T(YxTL!`pmVB z4l|BB@(FpD=EDtz^rq$TOVKGcEo|Z`iV%yAbpk2}R+$e}`o^S_!A7|@u?Yvo#}-Hc z>)kGlboivfCmo~)7br7uqrt8E;rtE2MHb{ExX3N%Z*;iTL3_Uf$B3IjK_`<8g?S#1 zr)-?WAHs!<;t89E*MiA}+3{o+iSu58Dl6AWP#l3TeYuLG(gXL z$_O1GsA@U=9=5{rbc`$N`@YyhR3X|BcK5JF{@%mZ5>rgb1wu{1jNq1Hj8pcx;*nMA z5#%@}{SH4%;1GszpQ;hhlg1_qLYS(95)XtKRrfNU^k1-WqB>4D`g=m-8J<@pZ&GL| z+8_wfP|*f?g`9DV63YZIAr>c%p5g$7ElyTa)}|UD8JtCv2hXJ9lu0N(x|L!V4^}~d zrs&1<=6)1=Uh1WytN(j8Qq>F@`j)pLHKSqMR-?1PP-Hg6{%AG?uz)3cS8B| kbIOdr{D@Ad7e1%wwY;{at?L;LG-_*^m#Z(=^O?N%FB9$j%>V!Z literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/__init__.py b/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/__init__.py new file mode 100644 index 00000000..61ba53f2 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/__init__.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/PublicKey/__init__.py: Self-test for public key crypto +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test for public-key crypto""" + +__revision__ = "$Id$" + +import os + +def get_tests(config={}): + tests = [] + from Crypto.SelfTest.PublicKey import test_DSA; tests += test_DSA.get_tests(config=config) + from Crypto.SelfTest.PublicKey import test_RSA; tests += test_RSA.get_tests(config=config) + from Crypto.SelfTest.PublicKey import test_importKey; tests += test_importKey.get_tests(config=config) + from Crypto.SelfTest.PublicKey import test_ElGamal; tests += test_ElGamal.get_tests(config=config) + return tests + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/__init__.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..c51cac076357e32d0d57cefc8d2336c67cd9be3d GIT binary patch literal 1157 zcmcIiO>fgc5S{f`Q%F${2#FIp^k5E&KpYSVRa7ZL2$WVf2NYRaIo?g!#9#7mkRm0g z_RNpqFY*ImW}UQZ)N8Hm%kKEC=e?P6{~kSRekV}|+sDQKkGOP#AOOaQ48{zE1Hy&e zfw2P$gC1OC+y&`@@L}OV^JB;HVeEql;2N(7Abpr0fWTh|u7I%;FS`(jhm_?7LM-!X z-$-qG)2iv!%So=X{z9&LS+lB5r9I@Fd=V$=A3mdu;W5BP;UO;l2Vn-VL5)^s4p1=I zIKb8n)(*_A@-=sIK-Sk(KG=v8CV!_IVTw3G@ZR@O^Tb zmLh#~-hVxKH+YrQEAz7|lW%I0Xk}!-PP0WilR9a&B|B}&jkbhyRVu^zpk75}g(gHl zMF1ACV|aFF*&=dYq^jinW`@a&os47L7=Sqg<6!sUiuypVMj=_Xx0jfW{MmX?o#G`b zwW+PKTX+bIR>FroEhZv8eTkYhE-;S~gq)_!+>j(gP0*w(v{OT)#JQ+4&JFdS^G5zs zT2)vDbP7;uYhYWRGA$(M5j8wILNL@~s@bhKyL&i;MJ1NGJf*4BG{}JyI9;dP>9Q_6 GWd8w9iu=0& literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_DSA.py b/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_DSA.py new file mode 100644 index 00000000..b05f69ac --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_DSA.py @@ -0,0 +1,244 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/PublicKey/test_DSA.py: Self-test for the DSA primitive +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.PublicKey.DSA""" + +__revision__ = "$Id$" + +import sys +import os +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * +from Crypto.Util.py3compat import * + +import unittest +from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex + +def _sws(s): + """Remove whitespace from a text or byte string""" + if isinstance(s,str): + return "".join(s.split()) + else: + return b("").join(s.split()) + +class DSATest(unittest.TestCase): + # Test vector from "Appendix 5. Example of the DSA" of + # "Digital Signature Standard (DSS)", + # U.S. Department of Commerce/National Institute of Standards and Technology + # FIPS 186-2 (+Change Notice), 2000 January 27. + # http://csrc.nist.gov/publications/fips/fips186-2/fips186-2-change1.pdf + + y = _sws("""19131871 d75b1612 a819f29d 78d1b0d7 346f7aa7 7bb62a85 + 9bfd6c56 75da9d21 2d3a36ef 1672ef66 0b8c7c25 5cc0ec74 + 858fba33 f44c0669 9630a76b 030ee333""") + + g = _sws("""626d0278 39ea0a13 413163a5 5b4cb500 299d5522 956cefcb + 3bff10f3 99ce2c2e 71cb9de5 fa24babf 58e5b795 21925c9c + c42e9f6f 464b088c c572af53 e6d78802""") + + p = _sws("""8df2a494 492276aa 3d25759b b06869cb eac0d83a fb8d0cf7 + cbb8324f 0d7882e5 d0762fc5 b7210eaf c2e9adac 32ab7aac + 49693dfb f83724c2 ec0736ee 31c80291""") + + q = _sws("""c773218c 737ec8ee 993b4f2d ed30f48e dace915f""") + + x = _sws("""2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614""") + + k = _sws("""358dad57 1462710f 50e254cf 1a376b2b deaadfbf""") + k_inverse = _sws("""0d516729 8202e49b 4116ac10 4fc3f415 ae52f917""") + m = b2a_hex(b("abc")) + m_hash = _sws("""a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d""") + r = _sws("""8bac1ab6 6410435c b7181f95 b16ab97c 92b341c0""") + s = _sws("""41e2345f 1f56df24 58f426d1 55b4ba2d b6dcd8c8""") + + def setUp(self): + global DSA, Random, bytes_to_long, size + from Crypto.PublicKey import DSA + from Crypto import Random + from Crypto.Util.number import bytes_to_long, inverse, size + + self.dsa = DSA + + def test_generate_1arg(self): + """DSA (default implementation) generated key (1 argument)""" + dsaObj = self.dsa.generate(1024) + self._check_private_key(dsaObj) + pub = dsaObj.publickey() + self._check_public_key(pub) + + def test_generate_2arg(self): + """DSA (default implementation) generated key (2 arguments)""" + dsaObj = self.dsa.generate(1024, Random.new().read) + self._check_private_key(dsaObj) + pub = dsaObj.publickey() + self._check_public_key(pub) + + def test_construct_4tuple(self): + """DSA (default implementation) constructed key (4-tuple)""" + (y, g, p, q) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q)] + dsaObj = self.dsa.construct((y, g, p, q)) + self._test_verification(dsaObj) + + def test_construct_5tuple(self): + """DSA (default implementation) constructed key (5-tuple)""" + (y, g, p, q, x) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q, self.x)] + dsaObj = self.dsa.construct((y, g, p, q, x)) + self._test_signing(dsaObj) + self._test_verification(dsaObj) + + def _check_private_key(self, dsaObj): + # Check capabilities + self.assertEqual(1, dsaObj.has_private()) + self.assertEqual(1, dsaObj.can_sign()) + self.assertEqual(0, dsaObj.can_encrypt()) + self.assertEqual(0, dsaObj.can_blind()) + + # Check dsaObj.[ygpqx] -> dsaObj.key.[ygpqx] mapping + self.assertEqual(dsaObj.y, dsaObj.key.y) + self.assertEqual(dsaObj.g, dsaObj.key.g) + self.assertEqual(dsaObj.p, dsaObj.key.p) + self.assertEqual(dsaObj.q, dsaObj.key.q) + self.assertEqual(dsaObj.x, dsaObj.key.x) + + # Sanity check key data + self.assertEqual(1, dsaObj.p > dsaObj.q) # p > q + self.assertEqual(160, size(dsaObj.q)) # size(q) == 160 bits + self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q) # q is a divisor of p-1 + self.assertEqual(dsaObj.y, pow(dsaObj.g, dsaObj.x, dsaObj.p)) # y == g**x mod p + self.assertEqual(1, 0 < dsaObj.x < dsaObj.q) # 0 < x < q + + def _check_public_key(self, dsaObj): + k = a2b_hex(self.k) + m_hash = a2b_hex(self.m_hash) + + # Check capabilities + self.assertEqual(0, dsaObj.has_private()) + self.assertEqual(1, dsaObj.can_sign()) + self.assertEqual(0, dsaObj.can_encrypt()) + self.assertEqual(0, dsaObj.can_blind()) + + # Check dsaObj.[ygpq] -> dsaObj.key.[ygpq] mapping + self.assertEqual(dsaObj.y, dsaObj.key.y) + self.assertEqual(dsaObj.g, dsaObj.key.g) + self.assertEqual(dsaObj.p, dsaObj.key.p) + self.assertEqual(dsaObj.q, dsaObj.key.q) + + # Check that private parameters are all missing + self.assertEqual(0, hasattr(dsaObj, 'x')) + self.assertEqual(0, hasattr(dsaObj.key, 'x')) + + # Sanity check key data + self.assertEqual(1, dsaObj.p > dsaObj.q) # p > q + self.assertEqual(160, size(dsaObj.q)) # size(q) == 160 bits + self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q) # q is a divisor of p-1 + + # Public-only key objects should raise an error when .sign() is called + self.assertRaises(TypeError, dsaObj.sign, m_hash, k) + + # Check __eq__ and __ne__ + self.assertEqual(dsaObj.publickey() == dsaObj.publickey(),True) # assert_ + self.assertEqual(dsaObj.publickey() != dsaObj.publickey(),False) # failIf + + def _test_signing(self, dsaObj): + k = a2b_hex(self.k) + m_hash = a2b_hex(self.m_hash) + r = bytes_to_long(a2b_hex(self.r)) + s = bytes_to_long(a2b_hex(self.s)) + (r_out, s_out) = dsaObj.sign(m_hash, k) + self.assertEqual((r, s), (r_out, s_out)) + + def _test_verification(self, dsaObj): + m_hash = a2b_hex(self.m_hash) + r = bytes_to_long(a2b_hex(self.r)) + s = bytes_to_long(a2b_hex(self.s)) + self.assertEqual(1, dsaObj.verify(m_hash, (r, s))) + self.assertEqual(0, dsaObj.verify(m_hash + b("\0"), (r, s))) + +class DSAFastMathTest(DSATest): + def setUp(self): + DSATest.setUp(self) + self.dsa = DSA.DSAImplementation(use_fast_math=True) + + def test_generate_1arg(self): + """DSA (_fastmath implementation) generated key (1 argument)""" + DSATest.test_generate_1arg(self) + + def test_generate_2arg(self): + """DSA (_fastmath implementation) generated key (2 arguments)""" + DSATest.test_generate_2arg(self) + + def test_construct_4tuple(self): + """DSA (_fastmath implementation) constructed key (4-tuple)""" + DSATest.test_construct_4tuple(self) + + def test_construct_5tuple(self): + """DSA (_fastmath implementation) constructed key (5-tuple)""" + DSATest.test_construct_5tuple(self) + +class DSASlowMathTest(DSATest): + def setUp(self): + DSATest.setUp(self) + self.dsa = DSA.DSAImplementation(use_fast_math=False) + + def test_generate_1arg(self): + """DSA (_slowmath implementation) generated key (1 argument)""" + DSATest.test_generate_1arg(self) + + def test_generate_2arg(self): + """DSA (_slowmath implementation) generated key (2 arguments)""" + DSATest.test_generate_2arg(self) + + def test_construct_4tuple(self): + """DSA (_slowmath implementation) constructed key (4-tuple)""" + DSATest.test_construct_4tuple(self) + + def test_construct_5tuple(self): + """DSA (_slowmath implementation) constructed key (5-tuple)""" + DSATest.test_construct_5tuple(self) + + +def get_tests(config={}): + tests = [] + tests += list_test_cases(DSATest) + try: + from Crypto.PublicKey import _fastmath + tests += list_test_cases(DSAFastMathTest) + except ImportError: + from distutils.sysconfig import get_config_var + import inspect + _fm_path = os.path.normpath(os.path.dirname(os.path.abspath( + inspect.getfile(inspect.currentframe()))) + +"/../../PublicKey/_fastmath"+get_config_var("SO")) + if os.path.exists(_fm_path): + raise ImportError("While the _fastmath module exists, importing "+ + "it failed. This may point to the gmp or mpir shared library "+ + "not being in the path. _fastmath was found at "+_fm_path) + tests += list_test_cases(DSASlowMathTest) + return tests + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_DSA.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_DSA.pyo new file mode 100644 index 0000000000000000000000000000000000000000..ad600298a5a0bf9fb6f234218f010ab968c17b53 GIT binary patch literal 11141 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 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_ElGamal.py b/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_ElGamal.py new file mode 100644 index 00000000..cdee8cf6 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_ElGamal.py @@ -0,0 +1,210 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/PublicKey/test_ElGamal.py: Self-test for the ElGamal primitive +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.PublicKey.ElGamal""" + +__revision__ = "$Id$" + +import unittest +from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex +from Crypto import Random +from Crypto.PublicKey import ElGamal +from Crypto.Util.number import * +from Crypto.Util.py3compat import * + +class ElGamalTest(unittest.TestCase): + + # + # Test vectors + # + # There seem to be no real ElGamal test vectors available in the + # public domain. The following test vectors have been generated + # with libgcrypt 1.5.0. + # + # Encryption + tve=[ + { + # 256 bits + 'p' :'BA4CAEAAED8CBE952AFD2126C63EB3B345D65C2A0A73D2A3AD4138B6D09BD933', + 'g' :'05', + 'y' :'60D063600ECED7C7C55146020E7A31C4476E9793BEAED420FEC9E77604CAE4EF', + 'x' :'1D391BA2EE3C37FE1BA175A69B2C73A11238AD77675932', + 'k' :'F5893C5BAB4131264066F57AB3D8AD89E391A0B68A68A1', + 'pt' :'48656C6C6F207468657265', + 'ct1':'32BFD5F487966CEA9E9356715788C491EC515E4ED48B58F0F00971E93AAA5EC7', + 'ct2':'7BE8FBFF317C93E82FCEF9BD515284BA506603FEA25D01C0CB874A31F315EE68' + }, + + { + # 512 bits + 'p' :'F1B18AE9F7B4E08FDA9A04832F4E919D89462FD31BF12F92791A93519F75076D6CE3942689CDFF2F344CAFF0F82D01864F69F3AECF566C774CBACF728B81A227', + 'g' :'07', + 'y' :'688628C676E4F05D630E1BE39D0066178CA7AA83836B645DE5ADD359B4825A12B02EF4252E4E6FA9BEC1DB0BE90F6D7C8629CABB6E531F472B2664868156E20C', + 'x' :'14E60B1BDFD33436C0DA8A22FDC14A2CCDBBED0627CE68', + 'k' :'38DBF14E1F319BDA9BAB33EEEADCAF6B2EA5250577ACE7', + 'pt' :'48656C6C6F207468657265', + 'ct1':'290F8530C2CC312EC46178724F196F308AD4C523CEABB001FACB0506BFED676083FE0F27AC688B5C749AB3CB8A80CD6F7094DBA421FB19442F5A413E06A9772B', + 'ct2':'1D69AAAD1DC50493FB1B8E8721D621D683F3BF1321BE21BC4A43E11B40C9D4D9C80DE3AAC2AB60D31782B16B61112E68220889D53C4C3136EE6F6CE61F8A23A0' + } + ] + + # Signature + tvs=[ + { + # 256 bits + 'p' :'D2F3C41EA66530838A704A48FFAC9334F4701ECE3A97CEE4C69DD01AE7129DD7', + 'g' :'05', + 'y' :'C3F9417DC0DAFEA6A05C1D2333B7A95E63B3F4F28CC962254B3256984D1012E7', + 'x' :'165E4A39BE44D5A2D8B1332D416BC559616F536BC735BB', + 'k' :'C7F0C794A7EAD726E25A47FF8928013680E73C51DD3D7D99BFDA8F492585928F', + 'h' :'48656C6C6F207468657265', + 'sig1':'35CA98133779E2073EF31165AFCDEB764DD54E96ADE851715495F9C635E1E7C2', + 'sig2':'0135B88B1151279FE5D8078D4FC685EE81177EE9802AB123A73925FC1CB059A7', + }, + { + # 512 bits + 'p' :'E24CF3A4B8A6AF749DCA6D714282FE4AABEEE44A53BB6ED15FBE32B5D3C3EF9CC4124A2ECA331F3C1C1B667ACA3766825217E7B5F9856648D95F05330C6A19CF', + 'g' :'0B', + 'y' :'2AD3A1049CA5D4ED207B2431C79A8719BB4073D4A94E450EA6CEE8A760EB07ADB67C0D52C275EE85D7B52789061EE45F2F37D9B2AE522A51C28329766BFE68AC', + 'x' :'16CBB4F46D9ECCF24FF9F7E63CAA3BD8936341555062AB', + 'k' :'8A3D89A4E429FD2476D7D717251FB79BF900FFE77444E6BB8299DC3F84D0DD57ABAB50732AE158EA52F5B9E7D8813E81FD9F79470AE22F8F1CF9AEC820A78C69', + 'h' :'48656C6C6F207468657265', + 'sig1':'BE001AABAFFF976EC9016198FBFEA14CBEF96B000CCC0063D3324016F9E91FE80D8F9325812ED24DDB2B4D4CF4430B169880B3CE88313B53255BD4EC0378586F', + 'sig2':'5E266F3F837BA204E3BBB6DBECC0611429D96F8C7CE8F4EFDF9D4CB681C2A954468A357BF4242CEC7418B51DFC081BCD21299EF5B5A0DDEF3A139A1817503DDE', + } + ] + + def test_generate_128(self): + self._test_random_key(128) + + def test_generate_512(self): + self._test_random_key(512) + + def test_encryption(self): + for tv in self.tve: + for as_longs in (0,1): + d = self.convert_tv(tv, as_longs) + key = ElGamal.construct(d['key']) + ct = key.encrypt(d['pt'], d['k']) + self.assertEquals(ct[0], d['ct1']) + self.assertEquals(ct[1], d['ct2']) + + def test_decryption(self): + for tv in self.tve: + for as_longs in (0,1): + d = self.convert_tv(tv, as_longs) + key = ElGamal.construct(d['key']) + pt = key.decrypt((d['ct1'], d['ct2'])) + self.assertEquals(pt, d['pt']) + + def test_signing(self): + for tv in self.tvs: + for as_longs in (0,1): + d = self.convert_tv(tv, as_longs) + key = ElGamal.construct(d['key']) + sig1, sig2 = key.sign(d['h'], d['k']) + self.assertEquals(sig1, d['sig1']) + self.assertEquals(sig2, d['sig2']) + + def test_verification(self): + for tv in self.tvs: + for as_longs in (0,1): + d = self.convert_tv(tv, as_longs) + key = ElGamal.construct(d['key']) + # Positive test + res = key.verify( d['h'], (d['sig1'],d['sig2']) ) + self.failUnless(res) + # Negative test + res = key.verify( d['h'], (d['sig1']+1,d['sig2']) ) + self.failIf(res) + + def convert_tv(self, tv, as_longs=0): + """Convert a test vector from textual form (hexadecimal ascii + to either integers or byte strings.""" + key_comps = 'p','g','y','x' + tv2 = {} + for c in tv.keys(): + tv2[c] = a2b_hex(tv[c]) + if as_longs or c in key_comps or c in ('sig1','sig2'): + tv2[c] = bytes_to_long(tv2[c]) + tv2['key']=[] + for c in key_comps: + tv2['key'] += [tv2[c]] + del tv2[c] + return tv2 + + def _test_random_key(self, bits): + elgObj = ElGamal.generate(bits, Random.new().read) + self._check_private_key(elgObj) + self._exercise_primitive(elgObj) + pub = elgObj.publickey() + self._check_public_key(pub) + self._exercise_public_primitive(elgObj) + + def _check_private_key(self, elgObj): + + # Check capabilities + self.failUnless(elgObj.has_private()) + self.failUnless(elgObj.can_sign()) + self.failUnless(elgObj.can_encrypt()) + + # Sanity check key data + self.failUnless(17ES9hTm;DmM}lVQxsnRCvJ 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 b3o{Fl)^C7R7m@s*ow@pF=jYESOUZu$2hU0| literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_RSA.py b/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_RSA.py new file mode 100644 index 00000000..c971042b --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_RSA.py @@ -0,0 +1,415 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/PublicKey/test_RSA.py: Self-test for the RSA primitive +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.PublicKey.RSA""" + +__revision__ = "$Id$" + +import sys +import os +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * +from Crypto.Util.py3compat import * + +import unittest +from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex + +class RSATest(unittest.TestCase): + # Test vectors from "RSA-OAEP and RSA-PSS test vectors (.zip file)" + # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip + # See RSADSI's PKCS#1 page at + # http://www.rsa.com/rsalabs/node.asp?id=2125 + + # from oaep-int.txt + + # TODO: PyCrypto treats the message as starting *after* the leading "00" + # TODO: That behaviour should probably be changed in the future. + plaintext = """ + eb 7a 19 ac e9 e3 00 63 50 e3 29 50 4b 45 e2 + ca 82 31 0b 26 dc d8 7d 5c 68 f1 ee a8 f5 52 67 + c3 1b 2e 8b b4 25 1f 84 d7 e0 b2 c0 46 26 f5 af + f9 3e dc fb 25 c9 c2 b3 ff 8a e1 0e 83 9a 2d db + 4c dc fe 4f f4 77 28 b4 a1 b7 c1 36 2b aa d2 9a + b4 8d 28 69 d5 02 41 21 43 58 11 59 1b e3 92 f9 + 82 fb 3e 87 d0 95 ae b4 04 48 db 97 2f 3a c1 4f + 7b c2 75 19 52 81 ce 32 d2 f1 b7 6d 4d 35 3e 2d + """ + + ciphertext = """ + 12 53 e0 4d c0 a5 39 7b b4 4a 7a b8 7e 9b f2 a0 + 39 a3 3d 1e 99 6f c8 2a 94 cc d3 00 74 c9 5d f7 + 63 72 20 17 06 9e 52 68 da 5d 1c 0b 4f 87 2c f6 + 53 c1 1d f8 23 14 a6 79 68 df ea e2 8d ef 04 bb + 6d 84 b1 c3 1d 65 4a 19 70 e5 78 3b d6 eb 96 a0 + 24 c2 ca 2f 4a 90 fe 9f 2e f5 c9 c1 40 e5 bb 48 + da 95 36 ad 87 00 c8 4f c9 13 0a de a7 4e 55 8d + 51 a7 4d df 85 d8 b5 0d e9 68 38 d6 06 3e 09 55 + """ + + modulus = """ + bb f8 2f 09 06 82 ce 9c 23 38 ac 2b 9d a8 71 f7 + 36 8d 07 ee d4 10 43 a4 40 d6 b6 f0 74 54 f5 1f + b8 df ba af 03 5c 02 ab 61 ea 48 ce eb 6f cd 48 + 76 ed 52 0d 60 e1 ec 46 19 71 9d 8a 5b 8b 80 7f + af b8 e0 a3 df c7 37 72 3e e6 b4 b7 d9 3a 25 84 + ee 6a 64 9d 06 09 53 74 88 34 b2 45 45 98 39 4e + e0 aa b1 2d 7b 61 a5 1f 52 7a 9a 41 f6 c1 68 7f + e2 53 72 98 ca 2a 8f 59 46 f8 e5 fd 09 1d bd cb + """ + + e = 0x11L # public exponent + + prime_factor = """ + c9 7f b1 f0 27 f4 53 f6 34 12 33 ea aa d1 d9 35 + 3f 6c 42 d0 88 66 b1 d0 5a 0f 20 35 02 8b 9d 86 + 98 40 b4 16 66 b4 2e 92 ea 0d a3 b4 32 04 b5 cf + ce 33 52 52 4d 04 16 a5 a4 41 e7 00 af 46 15 03 + """ + + def setUp(self): + global RSA, Random, bytes_to_long + from Crypto.PublicKey import RSA + from Crypto import Random + from Crypto.Util.number import bytes_to_long, inverse + self.n = bytes_to_long(a2b_hex(self.modulus)) + self.p = bytes_to_long(a2b_hex(self.prime_factor)) + + # Compute q, d, and u from n, e, and p + self.q = divmod(self.n, self.p)[0] + self.d = inverse(self.e, (self.p-1)*(self.q-1)) + self.u = inverse(self.p, self.q) # u = e**-1 (mod q) + + self.rsa = RSA + + def test_generate_1arg(self): + """RSA (default implementation) generated key (1 argument)""" + rsaObj = self.rsa.generate(1024) + self._check_private_key(rsaObj) + self._exercise_primitive(rsaObj) + pub = rsaObj.publickey() + self._check_public_key(pub) + self._exercise_public_primitive(rsaObj) + + def test_generate_2arg(self): + """RSA (default implementation) generated key (2 arguments)""" + rsaObj = self.rsa.generate(1024, Random.new().read) + self._check_private_key(rsaObj) + self._exercise_primitive(rsaObj) + pub = rsaObj.publickey() + self._check_public_key(pub) + self._exercise_public_primitive(rsaObj) + + def test_generate_3args(self): + rsaObj = self.rsa.generate(1024, Random.new().read,e=65537) + self._check_private_key(rsaObj) + self._exercise_primitive(rsaObj) + pub = rsaObj.publickey() + self._check_public_key(pub) + self._exercise_public_primitive(rsaObj) + self.assertEqual(65537,rsaObj.e) + + def test_construct_2tuple(self): + """RSA (default implementation) constructed key (2-tuple)""" + pub = self.rsa.construct((self.n, self.e)) + self._check_public_key(pub) + self._check_encryption(pub) + self._check_verification(pub) + + def test_construct_3tuple(self): + """RSA (default implementation) constructed key (3-tuple)""" + rsaObj = self.rsa.construct((self.n, self.e, self.d)) + self._check_encryption(rsaObj) + self._check_decryption(rsaObj) + self._check_signing(rsaObj) + self._check_verification(rsaObj) + + def test_construct_4tuple(self): + """RSA (default implementation) constructed key (4-tuple)""" + rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p)) + self._check_encryption(rsaObj) + self._check_decryption(rsaObj) + self._check_signing(rsaObj) + self._check_verification(rsaObj) + + def test_construct_5tuple(self): + """RSA (default implementation) constructed key (5-tuple)""" + rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q)) + self._check_private_key(rsaObj) + self._check_encryption(rsaObj) + self._check_decryption(rsaObj) + self._check_signing(rsaObj) + self._check_verification(rsaObj) + + def test_construct_6tuple(self): + """RSA (default implementation) constructed key (6-tuple)""" + rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q, self.u)) + self._check_private_key(rsaObj) + self._check_encryption(rsaObj) + self._check_decryption(rsaObj) + self._check_signing(rsaObj) + self._check_verification(rsaObj) + + def test_factoring(self): + rsaObj = self.rsa.construct([self.n, self.e, self.d]) + self.failUnless(rsaObj.p==self.p or rsaObj.p==self.q) + self.failUnless(rsaObj.q==self.p or rsaObj.q==self.q) + self.failUnless(rsaObj.q*rsaObj.p == self.n) + + self.assertRaises(ValueError, self.rsa.construct, [self.n, self.e, self.n-1]) + + def _check_private_key(self, rsaObj): + # Check capabilities + self.assertEqual(1, rsaObj.has_private()) + self.assertEqual(1, rsaObj.can_sign()) + self.assertEqual(1, rsaObj.can_encrypt()) + self.assertEqual(1, rsaObj.can_blind()) + + # Check rsaObj.[nedpqu] -> rsaObj.key.[nedpqu] mapping + self.assertEqual(rsaObj.n, rsaObj.key.n) + self.assertEqual(rsaObj.e, rsaObj.key.e) + self.assertEqual(rsaObj.d, rsaObj.key.d) + self.assertEqual(rsaObj.p, rsaObj.key.p) + self.assertEqual(rsaObj.q, rsaObj.key.q) + self.assertEqual(rsaObj.u, rsaObj.key.u) + + # Sanity check key data + self.assertEqual(rsaObj.n, rsaObj.p * rsaObj.q) # n = pq + self.assertEqual(1, rsaObj.d * rsaObj.e % ((rsaObj.p-1) * (rsaObj.q-1))) # ed = 1 (mod (p-1)(q-1)) + self.assertEqual(1, rsaObj.p * rsaObj.u % rsaObj.q) # pu = 1 (mod q) + self.assertEqual(1, rsaObj.p > 1) # p > 1 + self.assertEqual(1, rsaObj.q > 1) # q > 1 + self.assertEqual(1, rsaObj.e > 1) # e > 1 + self.assertEqual(1, rsaObj.d > 1) # d > 1 + + def _check_public_key(self, rsaObj): + ciphertext = a2b_hex(self.ciphertext) + + # Check capabilities + self.assertEqual(0, rsaObj.has_private()) + self.assertEqual(1, rsaObj.can_sign()) + self.assertEqual(1, rsaObj.can_encrypt()) + self.assertEqual(1, rsaObj.can_blind()) + + # Check rsaObj.[ne] -> rsaObj.key.[ne] mapping + self.assertEqual(rsaObj.n, rsaObj.key.n) + self.assertEqual(rsaObj.e, rsaObj.key.e) + + # Check that private parameters are all missing + self.assertEqual(0, hasattr(rsaObj, 'd')) + self.assertEqual(0, hasattr(rsaObj, 'p')) + self.assertEqual(0, hasattr(rsaObj, 'q')) + self.assertEqual(0, hasattr(rsaObj, 'u')) + self.assertEqual(0, hasattr(rsaObj.key, 'd')) + self.assertEqual(0, hasattr(rsaObj.key, 'p')) + self.assertEqual(0, hasattr(rsaObj.key, 'q')) + self.assertEqual(0, hasattr(rsaObj.key, 'u')) + + # Sanity check key data + self.assertEqual(1, rsaObj.e > 1) # e > 1 + + # Public keys should not be able to sign or decrypt + self.assertRaises(TypeError, rsaObj.sign, ciphertext, b("")) + self.assertRaises(TypeError, rsaObj.decrypt, ciphertext) + + # Check __eq__ and __ne__ + self.assertEqual(rsaObj.publickey() == rsaObj.publickey(),True) # assert_ + self.assertEqual(rsaObj.publickey() != rsaObj.publickey(),False) # failIf + + def _exercise_primitive(self, rsaObj): + # Since we're using a randomly-generated key, we can't check the test + # vector, but we can make sure encryption and decryption are inverse + # operations. + ciphertext = a2b_hex(self.ciphertext) + + # Test decryption + plaintext = rsaObj.decrypt((ciphertext,)) + + # Test encryption (2 arguments) + (new_ciphertext2,) = rsaObj.encrypt(plaintext, b("")) + self.assertEqual(b2a_hex(ciphertext), b2a_hex(new_ciphertext2)) + + # Test blinded decryption + blinding_factor = Random.new().read(len(ciphertext)-1) + blinded_ctext = rsaObj.blind(ciphertext, blinding_factor) + blinded_ptext = rsaObj.decrypt((blinded_ctext,)) + unblinded_plaintext = rsaObj.unblind(blinded_ptext, blinding_factor) + self.assertEqual(b2a_hex(plaintext), b2a_hex(unblinded_plaintext)) + + # Test signing (2 arguments) + signature2 = rsaObj.sign(ciphertext, b("")) + self.assertEqual((bytes_to_long(plaintext),), signature2) + + # Test verification + self.assertEqual(1, rsaObj.verify(ciphertext, (bytes_to_long(plaintext),))) + + def _exercise_public_primitive(self, rsaObj): + plaintext = a2b_hex(self.plaintext) + + # Test encryption (2 arguments) + (new_ciphertext2,) = rsaObj.encrypt(plaintext, b("")) + + # Exercise verification + rsaObj.verify(new_ciphertext2, (bytes_to_long(plaintext),)) + + def _check_encryption(self, rsaObj): + plaintext = a2b_hex(self.plaintext) + ciphertext = a2b_hex(self.ciphertext) + + # Test encryption (2 arguments) + (new_ciphertext2,) = rsaObj.encrypt(plaintext, b("")) + self.assertEqual(b2a_hex(ciphertext), b2a_hex(new_ciphertext2)) + + def _check_decryption(self, rsaObj): + plaintext = a2b_hex(self.plaintext) + ciphertext = a2b_hex(self.ciphertext) + + # Test plain decryption + new_plaintext = rsaObj.decrypt((ciphertext,)) + self.assertEqual(b2a_hex(plaintext), b2a_hex(new_plaintext)) + + # Test blinded decryption + blinding_factor = Random.new().read(len(ciphertext)-1) + blinded_ctext = rsaObj.blind(ciphertext, blinding_factor) + blinded_ptext = rsaObj.decrypt((blinded_ctext,)) + unblinded_plaintext = rsaObj.unblind(blinded_ptext, blinding_factor) + self.assertEqual(b2a_hex(plaintext), b2a_hex(unblinded_plaintext)) + + def _check_verification(self, rsaObj): + signature = bytes_to_long(a2b_hex(self.plaintext)) + message = a2b_hex(self.ciphertext) + + # Test verification + t = (signature,) # rsaObj.verify expects a tuple + self.assertEqual(1, rsaObj.verify(message, t)) + + # Test verification with overlong tuple (this is a + # backward-compatibility hack to support some harmless misuse of the + # API) + t2 = (signature, '') + self.assertEqual(1, rsaObj.verify(message, t2)) # extra garbage at end of tuple + + def _check_signing(self, rsaObj): + signature = bytes_to_long(a2b_hex(self.plaintext)) + message = a2b_hex(self.ciphertext) + + # Test signing (2 argument) + self.assertEqual((signature,), rsaObj.sign(message, b(""))) + +class RSAFastMathTest(RSATest): + def setUp(self): + RSATest.setUp(self) + self.rsa = RSA.RSAImplementation(use_fast_math=True) + + def test_generate_1arg(self): + """RSA (_fastmath implementation) generated key (1 argument)""" + RSATest.test_generate_1arg(self) + + def test_generate_2arg(self): + """RSA (_fastmath implementation) generated key (2 arguments)""" + RSATest.test_generate_2arg(self) + + def test_construct_2tuple(self): + """RSA (_fastmath implementation) constructed key (2-tuple)""" + RSATest.test_construct_2tuple(self) + + def test_construct_3tuple(self): + """RSA (_fastmath implementation) constructed key (3-tuple)""" + RSATest.test_construct_3tuple(self) + + def test_construct_4tuple(self): + """RSA (_fastmath implementation) constructed key (4-tuple)""" + RSATest.test_construct_4tuple(self) + + def test_construct_5tuple(self): + """RSA (_fastmath implementation) constructed key (5-tuple)""" + RSATest.test_construct_5tuple(self) + + def test_construct_6tuple(self): + """RSA (_fastmath implementation) constructed key (6-tuple)""" + RSATest.test_construct_6tuple(self) + + def test_factoring(self): + RSATest.test_factoring(self) + +class RSASlowMathTest(RSATest): + def setUp(self): + RSATest.setUp(self) + self.rsa = RSA.RSAImplementation(use_fast_math=False) + + def test_generate_1arg(self): + """RSA (_slowmath implementation) generated key (1 argument)""" + RSATest.test_generate_1arg(self) + + def test_generate_2arg(self): + """RSA (_slowmath implementation) generated key (2 arguments)""" + RSATest.test_generate_2arg(self) + + def test_construct_2tuple(self): + """RSA (_slowmath implementation) constructed key (2-tuple)""" + RSATest.test_construct_2tuple(self) + + def test_construct_3tuple(self): + """RSA (_slowmath implementation) constructed key (3-tuple)""" + RSATest.test_construct_3tuple(self) + + def test_construct_4tuple(self): + """RSA (_slowmath implementation) constructed key (4-tuple)""" + RSATest.test_construct_4tuple(self) + + def test_construct_5tuple(self): + """RSA (_slowmath implementation) constructed key (5-tuple)""" + RSATest.test_construct_5tuple(self) + + def test_construct_6tuple(self): + """RSA (_slowmath implementation) constructed key (6-tuple)""" + RSATest.test_construct_6tuple(self) + + def test_factoring(self): + RSATest.test_factoring(self) + +def get_tests(config={}): + tests = [] + tests += list_test_cases(RSATest) + try: + from Crypto.PublicKey import _fastmath + tests += list_test_cases(RSAFastMathTest) + except ImportError: + from distutils.sysconfig import get_config_var + import inspect + _fm_path = os.path.normpath(os.path.dirname(os.path.abspath( + inspect.getfile(inspect.currentframe()))) + +"/../../PublicKey/_fastmath"+get_config_var("SO")) + if os.path.exists(_fm_path): + raise ImportError("While the _fastmath module exists, importing "+ + "it failed. This may point to the gmp or mpir shared library "+ + "not being in the path. _fastmath was found at "+_fm_path) + if config.get('slow_tests',1): + tests += list_test_cases(RSASlowMathTest) + return tests + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_RSA.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_RSA.pyo new file mode 100644 index 0000000000000000000000000000000000000000..f73d7c6282ca4f992e590a1dd8012b731999f9c8 GIT binary patch literal 17597 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 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_importKey.py b/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_importKey.py new file mode 100644 index 00000000..28a7eee8 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_importKey.py @@ -0,0 +1,345 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/PublicKey/test_importKey.py: Self-test for importing RSA keys +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +from __future__ import nested_scopes + +__revision__ = "$Id$" + +import unittest + +from Crypto.PublicKey import RSA +from Crypto.SelfTest.st_common import * +from Crypto.Util.py3compat import * +from Crypto.Util.number import inverse +from Crypto.Util import asn1 + +def der2pem(der, text='PUBLIC'): + import binascii + chunks = [ binascii.b2a_base64(der[i:i+48]) for i in range(0, len(der), 48) ] + pem = b('-----BEGIN %s KEY-----\n' % text) + pem += b('').join(chunks) + pem += b('-----END %s KEY-----' % text) + return pem + +class ImportKeyTests(unittest.TestCase): + # 512-bit RSA key generated with openssl + rsaKeyPEM = u'''-----BEGIN RSA PRIVATE KEY----- +MIIBOwIBAAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+TLr7UkvEtFrRhDDKMtuII +q19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQJACUSDEp8RTe32ftq8IwG8 +Wojl5mAd1wFiIOrZ/Uv8b963WJOJiuQcVN29vxU5+My9GPZ7RA3hrDBEAoHUDPrI +OQIhAPIPLz4dphiD9imAkivY31Rc5AfHJiQRA7XixTcjEkojAiEAyh/pJHks/Mlr ++rdPNEpotBjfV4M4BkgGAA/ipcmaAjcCIQCHvhwwKVBLzzTscT2HeUdEeBMoiXXK +JACAr3sJQJGxIQIgarRp+m1WSKV1MciwMaTOnbU7wxFs9DP1pva76lYBzgUCIQC9 +n0CnZCJ6IZYqSt0H5N7+Q+2Ro64nuwV/OSQfM6sBwQ== +-----END RSA PRIVATE KEY-----''' + + # As above, but this is actually an unencrypted PKCS#8 key + rsaKeyPEM8 = u'''-----BEGIN PRIVATE KEY----- +MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvx4nkAqgiyNRGlwS +ga5tkzEsPv6RP5MuvtSS8S0WtGEMMoy24girX0WsvilQgzKY8xIsGfeEkt7fQPDj +wZAzhQIDAQABAkAJRIMSnxFN7fZ+2rwjAbxaiOXmYB3XAWIg6tn9S/xv3rdYk4mK +5BxU3b2/FTn4zL0Y9ntEDeGsMEQCgdQM+sg5AiEA8g8vPh2mGIP2KYCSK9jfVFzk +B8cmJBEDteLFNyMSSiMCIQDKH+kkeSz8yWv6t080Smi0GN9XgzgGSAYAD+KlyZoC +NwIhAIe+HDApUEvPNOxxPYd5R0R4EyiJdcokAICvewlAkbEhAiBqtGn6bVZIpXUx +yLAxpM6dtTvDEWz0M/Wm9rvqVgHOBQIhAL2fQKdkInohlipK3Qfk3v5D7ZGjrie7 +BX85JB8zqwHB +-----END PRIVATE KEY-----''' + + # The same RSA private key as in rsaKeyPEM, but now encrypted + rsaKeyEncryptedPEM=( + + # With DES and passphrase 'test' + ('test', u'''-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-CBC,AF8F9A40BD2FA2FC + +Ckl9ex1kaVEWhYC2QBmfaF+YPiR4NFkRXA7nj3dcnuFEzBnY5XULupqQpQI3qbfA +u8GYS7+b3toWWiHZivHbAAUBPDIZG9hKDyB9Sq2VMARGsX1yW1zhNvZLIiVJzUHs +C6NxQ1IJWOXzTew/xM2I26kPwHIvadq+/VaT8gLQdjdH0jOiVNaevjWnLgrn1mLP +BCNRMdcexozWtAFNNqSzfW58MJL2OdMi21ED184EFytIc1BlB+FZiGZduwKGuaKy +9bMbdb/1PSvsSzPsqW7KSSrTw6MgJAFJg6lzIYvR5F4poTVBxwBX3+EyEmShiaNY +IRX3TgQI0IjrVuLmvlZKbGWP18FXj7I7k9tSsNOOzllTTdq3ny5vgM3A+ynfAaxp +dysKznQ6P+IoqML1WxAID4aGRMWka+uArOJ148Rbj9s= +-----END RSA PRIVATE KEY-----''', + "\xAF\x8F\x9A\x40\xBD\x2F\xA2\xFC"), + + # With Triple-DES and passphrase 'rocking' + ('rocking', u'''-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,C05D6C07F7FC02F6 + +w4lwQrXaVoTTJ0GgwY566htTA2/t1YlimhxkxYt9AEeCcidS5M0Wq9ClPiPz9O7F +m6K5QpM1rxo1RUE/ZyI85gglRNPdNwkeTOqit+kum7nN73AToX17+irVmOA4Z9E+ +4O07t91GxGMcjUSIFk0ucwEU4jgxRvYscbvOMvNbuZszGdVNzBTVddnShKCsy9i7 +nJbPlXeEKYi/OkRgO4PtfqqWQu5GIEFVUf9ev1QV7AvC+kyWTR1wWYnHX265jU5c +sopxQQtP8XEHIJEdd5/p1oieRcWTCNyY8EkslxDSsrf0OtZp6mZH9N+KU47cgQtt +9qGORmlWnsIoFFKcDohbtOaWBTKhkj5h6OkLjFjfU/sBeV1c+7wDT3dAy5tawXjG +YSxC7qDQIT/RECvV3+oQKEcmpEujn45wAnkTi12BH30= +-----END RSA PRIVATE KEY-----''', + "\xC0\x5D\x6C\x07\xF7\xFC\x02\xF6"), + ) + + rsaPublicKeyPEM = u'''-----BEGIN PUBLIC KEY----- +MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+T +Lr7UkvEtFrRhDDKMtuIIq19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQ== +-----END PUBLIC KEY-----''' + + # Obtained using 'ssh-keygen -i -m PKCS8 -f rsaPublicKeyPEM' + rsaPublicKeyOpenSSH = '''ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAQQC/HieQCqCLI1EaXBKBrm2TMSw+/pE/ky6+1JLxLRa0YQwyjLbiCKtfRay+KVCDMpjzEiwZ94SS3t9A8OPBkDOF comment\n''' + + # The private key, in PKCS#1 format encoded with DER + rsaKeyDER = a2b_hex( + '''3082013b020100024100bf1e27900aa08b23511a5c1281ae6d93312c3efe + 913f932ebed492f12d16b4610c328cb6e208ab5f45acbe2950833298f312 + 2c19f78492dedf40f0e3c190338502030100010240094483129f114dedf6 + 7edabc2301bc5a88e5e6601dd7016220ead9fd4bfc6fdeb75893898ae41c + 54ddbdbf1539f8ccbd18f67b440de1ac30440281d40cfac839022100f20f + 2f3e1da61883f62980922bd8df545ce407c726241103b5e2c53723124a23 + 022100ca1fe924792cfcc96bfab74f344a68b418df578338064806000fe2 + a5c99a023702210087be1c3029504bcf34ec713d877947447813288975ca + 240080af7b094091b12102206ab469fa6d5648a57531c8b031a4ce9db53b + c3116cf433f5a6f6bbea5601ce05022100bd9f40a764227a21962a4add07 + e4defe43ed91a3ae27bb057f39241f33ab01c1 + '''.replace(" ","")) + + # The private key, in unencrypted PKCS#8 format encoded with DER + rsaKeyDER8 = a2b_hex( + '''30820155020100300d06092a864886f70d01010105000482013f3082013 + b020100024100bf1e27900aa08b23511a5c1281ae6d93312c3efe913f932 + ebed492f12d16b4610c328cb6e208ab5f45acbe2950833298f3122c19f78 + 492dedf40f0e3c190338502030100010240094483129f114dedf67edabc2 + 301bc5a88e5e6601dd7016220ead9fd4bfc6fdeb75893898ae41c54ddbdb + f1539f8ccbd18f67b440de1ac30440281d40cfac839022100f20f2f3e1da + 61883f62980922bd8df545ce407c726241103b5e2c53723124a23022100c + a1fe924792cfcc96bfab74f344a68b418df578338064806000fe2a5c99a0 + 23702210087be1c3029504bcf34ec713d877947447813288975ca240080a + f7b094091b12102206ab469fa6d5648a57531c8b031a4ce9db53bc3116cf + 433f5a6f6bbea5601ce05022100bd9f40a764227a21962a4add07e4defe4 + 3ed91a3ae27bb057f39241f33ab01c1 + '''.replace(" ","")) + + rsaPublicKeyDER = a2b_hex( + '''305c300d06092a864886f70d0101010500034b003048024100bf1e27900a + a08b23511a5c1281ae6d93312c3efe913f932ebed492f12d16b4610c328c + b6e208ab5f45acbe2950833298f3122c19f78492dedf40f0e3c190338502 + 03010001 + '''.replace(" ","")) + + n = long('BF 1E 27 90 0A A0 8B 23 51 1A 5C 12 81 AE 6D 93 31 2C 3E FE 91 3F 93 2E BE D4 92 F1 2D 16 B4 61 0C 32 8C B6 E2 08 AB 5F 45 AC BE 29 50 83 32 98 F3 12 2C 19 F7 84 92 DE DF 40 F0 E3 C1 90 33 85'.replace(" ",""),16) + e = 65537L + d = long('09 44 83 12 9F 11 4D ED F6 7E DA BC 23 01 BC 5A 88 E5 E6 60 1D D7 01 62 20 EA D9 FD 4B FC 6F DE B7 58 93 89 8A E4 1C 54 DD BD BF 15 39 F8 CC BD 18 F6 7B 44 0D E1 AC 30 44 02 81 D4 0C FA C8 39'.replace(" ",""),16) + p = long('00 F2 0F 2F 3E 1D A6 18 83 F6 29 80 92 2B D8 DF 54 5C E4 07 C7 26 24 11 03 B5 E2 C5 37 23 12 4A 23'.replace(" ",""),16) + q = long('00 CA 1F E9 24 79 2C FC C9 6B FA B7 4F 34 4A 68 B4 18 DF 57 83 38 06 48 06 00 0F E2 A5 C9 9A 02 37'.replace(" ",""),16) + + # This is q^{-1} mod p). fastmath and slowmath use pInv (p^{-1} + # mod q) instead! + qInv = long('00 BD 9F 40 A7 64 22 7A 21 96 2A 4A DD 07 E4 DE FE 43 ED 91 A3 AE 27 BB 05 7F 39 24 1F 33 AB 01 C1'.replace(" ",""),16) + pInv = inverse(p,q) + + def testImportKey1(self): + """Verify import of RSAPrivateKey DER SEQUENCE""" + key = self.rsa.importKey(self.rsaKeyDER) + self.failUnless(key.has_private()) + self.assertEqual(key.n, self.n) + self.assertEqual(key.e, self.e) + self.assertEqual(key.d, self.d) + self.assertEqual(key.p, self.p) + self.assertEqual(key.q, self.q) + + def testImportKey2(self): + """Verify import of SubjectPublicKeyInfo DER SEQUENCE""" + key = self.rsa.importKey(self.rsaPublicKeyDER) + self.failIf(key.has_private()) + self.assertEqual(key.n, self.n) + self.assertEqual(key.e, self.e) + + def testImportKey3unicode(self): + """Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as unicode""" + key = RSA.importKey(self.rsaKeyPEM) + self.assertEqual(key.has_private(),True) # assert_ + self.assertEqual(key.n, self.n) + self.assertEqual(key.e, self.e) + self.assertEqual(key.d, self.d) + self.assertEqual(key.p, self.p) + self.assertEqual(key.q, self.q) + + def testImportKey3bytes(self): + """Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as byte string""" + key = RSA.importKey(b(self.rsaKeyPEM)) + self.assertEqual(key.has_private(),True) # assert_ + self.assertEqual(key.n, self.n) + self.assertEqual(key.e, self.e) + self.assertEqual(key.d, self.d) + self.assertEqual(key.p, self.p) + self.assertEqual(key.q, self.q) + + def testImportKey4unicode(self): + """Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as unicode""" + key = RSA.importKey(self.rsaPublicKeyPEM) + self.assertEqual(key.has_private(),False) # failIf + self.assertEqual(key.n, self.n) + self.assertEqual(key.e, self.e) + + def testImportKey4bytes(self): + """Verify import of SubjectPublicKeyInfo DER SEQUENCE, encoded with PEM as byte string""" + key = RSA.importKey(b(self.rsaPublicKeyPEM)) + self.assertEqual(key.has_private(),False) # failIf + self.assertEqual(key.n, self.n) + self.assertEqual(key.e, self.e) + + def testImportKey5(self): + """Verifies that the imported key is still a valid RSA pair""" + key = RSA.importKey(self.rsaKeyPEM) + idem = key.encrypt(key.decrypt(b("Test")),0) + self.assertEqual(idem[0],b("Test")) + + def testImportKey6(self): + """Verifies that the imported key is still a valid RSA pair""" + key = RSA.importKey(self.rsaKeyDER) + idem = key.encrypt(key.decrypt(b("Test")),0) + self.assertEqual(idem[0],b("Test")) + + def testImportKey7(self): + """Verify import of OpenSSH public key""" + key = self.rsa.importKey(self.rsaPublicKeyOpenSSH) + self.assertEqual(key.n, self.n) + self.assertEqual(key.e, self.e) + + def testImportKey8(self): + """Verify import of encrypted PrivateKeyInfo DER SEQUENCE""" + for t in self.rsaKeyEncryptedPEM: + key = self.rsa.importKey(t[1], t[0]) + self.failUnless(key.has_private()) + self.assertEqual(key.n, self.n) + self.assertEqual(key.e, self.e) + self.assertEqual(key.d, self.d) + self.assertEqual(key.p, self.p) + self.assertEqual(key.q, self.q) + + def testImportKey9(self): + """Verify import of unencrypted PrivateKeyInfo DER SEQUENCE""" + key = self.rsa.importKey(self.rsaKeyDER8) + self.failUnless(key.has_private()) + self.assertEqual(key.n, self.n) + self.assertEqual(key.e, self.e) + self.assertEqual(key.d, self.d) + self.assertEqual(key.p, self.p) + self.assertEqual(key.q, self.q) + + def testImportKey10(self): + """Verify import of unencrypted PrivateKeyInfo DER SEQUENCE, encoded with PEM""" + key = self.rsa.importKey(self.rsaKeyPEM8) + self.failUnless(key.has_private()) + self.assertEqual(key.n, self.n) + self.assertEqual(key.e, self.e) + self.assertEqual(key.d, self.d) + self.assertEqual(key.p, self.p) + self.assertEqual(key.q, self.q) + + def testImportKey11(self): + """Verify import of RSAPublicKey DER SEQUENCE""" + der = asn1.DerSequence([17, 3]).encode() + key = self.rsa.importKey(der) + self.assertEqual(key.n, 17) + self.assertEqual(key.e, 3) + + def testImportKey12(self): + """Verify import of RSAPublicKey DER SEQUENCE, encoded with PEM""" + der = asn1.DerSequence([17, 3]).encode() + pem = der2pem(der) + key = self.rsa.importKey(pem) + self.assertEqual(key.n, 17) + self.assertEqual(key.e, 3) + + ### + def testExportKey1(self): + key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) + derKey = key.exportKey("DER") + self.assertEqual(derKey, self.rsaKeyDER) + + def testExportKey2(self): + key = self.rsa.construct([self.n, self.e]) + derKey = key.exportKey("DER") + self.assertEqual(derKey, self.rsaPublicKeyDER) + + def testExportKey3(self): + key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) + pemKey = key.exportKey("PEM") + self.assertEqual(pemKey, b(self.rsaKeyPEM)) + + def testExportKey4(self): + key = self.rsa.construct([self.n, self.e]) + pemKey = key.exportKey("PEM") + self.assertEqual(pemKey, b(self.rsaPublicKeyPEM)) + + def testExportKey5(self): + key = self.rsa.construct([self.n, self.e]) + openssh_1 = key.exportKey("OpenSSH").split() + openssh_2 = self.rsaPublicKeyOpenSSH.split() + self.assertEqual(openssh_1[0], openssh_2[0]) + self.assertEqual(openssh_1[1], openssh_2[1]) + + def testExportKey4(self): + key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) + # Tuple with index #1 is encrypted with 3DES + t = map(b,self.rsaKeyEncryptedPEM[1]) + # Force the salt being used when exporting + key._randfunc = lambda N: (t[2]*divmod(N+len(t[2]),len(t[2]))[0])[:N] + pemKey = key.exportKey("PEM", t[0]) + self.assertEqual(pemKey, t[1]) + + def testExportKey5(self): + key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) + derKey = key.exportKey("DER", pkcs=8) + self.assertEqual(derKey, self.rsaKeyDER8) + + def testExportKey6(self): + key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) + pemKey = key.exportKey("PEM", pkcs=8) + self.assertEqual(pemKey, b(self.rsaKeyPEM8)) + +class ImportKeyTestsSlow(ImportKeyTests): + def setUp(self): + self.rsa = RSA.RSAImplementation(use_fast_math=0) + +class ImportKeyTestsFast(ImportKeyTests): + def setUp(self): + self.rsa = RSA.RSAImplementation(use_fast_math=1) + +if __name__ == '__main__': + unittest.main() + +def get_tests(config={}): + tests = [] + try: + from Crypto.PublicKey import _fastmath + tests += list_test_cases(ImportKeyTestsFast) + except ImportError: + pass + tests += list_test_cases(ImportKeyTestsSlow) + return tests + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_importKey.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/PublicKey/test_importKey.pyo new file mode 100644 index 0000000000000000000000000000000000000000..4a46dcc59d0e450f87e3d9799b8fd171ffffd9d9 GIT binary patch literal 19058 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 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/__init__.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/__init__.py new file mode 100644 index 00000000..81a0e13c --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/__init__.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Random/Fortuna/__init__.py: Self-test for Fortuna modules +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test for the Crypto.Random.Fortuna package""" + +__revision__ = "$Id$" + +import os + +def get_tests(config={}): + tests = [] + from Crypto.SelfTest.Random.Fortuna import test_FortunaAccumulator; tests += test_FortunaAccumulator.get_tests(config=config) + from Crypto.SelfTest.Random.Fortuna import test_FortunaGenerator; tests += test_FortunaGenerator.get_tests(config=config) + from Crypto.SelfTest.Random.Fortuna import test_SHAd256; tests += test_SHAd256.get_tests(config=config) + return tests + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/__init__.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..b9243e7a0b8bd5bff941bb6c64e49fc775444e1e GIT binary patch literal 1145 zcmcIjOK;Oa5T5lbEd{Z(3G8bE2G{S3B#?Ai^4-( zdWA3pSfgeuI|IlWtQ}x01}g{V)(Nsu&8wE>0kK?IyA8|zFUz+q57u78^8R6Ag>e|5 zfRR-fk~s5#0R8dS$x)Kjd7TM^#)zAg#WbBY++C7U;V%kpLjrw_Fg%FA;Bds= z+y1k`{@`i6Senzah(Dz#u}+QZZ)O!Yvf_=bxS46(b|U6HEmFhzV6lv-_G7BBg8(dG zJ8=JUnJtWQo{O~L{PMPv1v_&}F#vN0#=*J5In99_jY4v0vumtG&TSj0N8=i$+OpQ! z72KFdtK)Sh@)Iczsh-9K<~D* +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-tests for Crypto.Random.Fortuna.FortunaAccumulator""" + +__revision__ = "$Id$" + +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * +from Crypto.Util.py3compat import * + +import unittest +from binascii import b2a_hex + +class FortunaAccumulatorTests(unittest.TestCase): + def setUp(self): + global FortunaAccumulator + from Crypto.Random.Fortuna import FortunaAccumulator + + def test_FortunaPool(self): + """FortunaAccumulator.FortunaPool""" + pool = FortunaAccumulator.FortunaPool() + self.assertEqual(0, pool.length) + self.assertEqual("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456", pool.hexdigest()) + + pool.append(b('abc')) + + self.assertEqual(3, pool.length) + self.assertEqual("4f8b42c22dd3729b519ba6f68d2da7cc5b2d606d05daed5ad5128cc03e6c6358", pool.hexdigest()) + + pool.append(b("dbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")) + + self.assertEqual(56, pool.length) + self.assertEqual(b('0cffe17f68954dac3a84fb1458bd5ec99209449749b2b308b7cb55812f9563af'), b2a_hex(pool.digest())) + + pool.reset() + + self.assertEqual(0, pool.length) + + pool.append(b('a') * 10**6) + + self.assertEqual(10**6, pool.length) + self.assertEqual(b('80d1189477563e1b5206b2749f1afe4807e5705e8bd77887a60187a712156688'), b2a_hex(pool.digest())) + + def test_which_pools(self): + """FortunaAccumulator.which_pools""" + + # which_pools(0) should fail + self.assertRaises(AssertionError, FortunaAccumulator.which_pools, 0) + + self.assertEqual(FortunaAccumulator.which_pools(1), [0]) + self.assertEqual(FortunaAccumulator.which_pools(2), [0, 1]) + self.assertEqual(FortunaAccumulator.which_pools(3), [0]) + self.assertEqual(FortunaAccumulator.which_pools(4), [0, 1, 2]) + self.assertEqual(FortunaAccumulator.which_pools(5), [0]) + self.assertEqual(FortunaAccumulator.which_pools(6), [0, 1]) + self.assertEqual(FortunaAccumulator.which_pools(7), [0]) + self.assertEqual(FortunaAccumulator.which_pools(8), [0, 1, 2, 3]) + for i in range(1, 32): + self.assertEqual(FortunaAccumulator.which_pools(2L**i-1), [0]) + self.assertEqual(FortunaAccumulator.which_pools(2L**i), range(i+1)) + self.assertEqual(FortunaAccumulator.which_pools(2L**i+1), [0]) + self.assertEqual(FortunaAccumulator.which_pools(2L**31), range(32)) + self.assertEqual(FortunaAccumulator.which_pools(2L**32), range(32)) + self.assertEqual(FortunaAccumulator.which_pools(2L**33), range(32)) + self.assertEqual(FortunaAccumulator.which_pools(2L**34), range(32)) + self.assertEqual(FortunaAccumulator.which_pools(2L**35), range(32)) + self.assertEqual(FortunaAccumulator.which_pools(2L**36), range(32)) + self.assertEqual(FortunaAccumulator.which_pools(2L**64), range(32)) + self.assertEqual(FortunaAccumulator.which_pools(2L**128), range(32)) + + def test_accumulator(self): + """FortunaAccumulator.FortunaAccumulator""" + fa = FortunaAccumulator.FortunaAccumulator() + + # This should fail, because we haven't seeded the PRNG yet + self.assertRaises(AssertionError, fa.random_data, 1) + + # Spread some test data across the pools (source number 42) + # This would be horribly insecure in a real system. + for p in range(32): + fa.add_random_event(42, p, b("X") * 32) + self.assertEqual(32+2, fa.pools[p].length) + + # This should still fail, because we haven't seeded the PRNG with 64 bytes yet + self.assertRaises(AssertionError, fa.random_data, 1) + + # Add more data + for p in range(32): + fa.add_random_event(42, p, b("X") * 32) + self.assertEqual((32+2)*2, fa.pools[p].length) + + # The underlying RandomGenerator should get seeded with Pool 0 + # s = SHAd256(chr(42) + chr(32) + "X"*32 + chr(42) + chr(32) + "X"*32) + # = SHA256(h'edd546f057b389155a31c32e3975e736c1dec030ddebb137014ecbfb32ed8c6f') + # = h'aef42a5dcbddab67e8efa118e1b47fde5d697f89beb971b99e6e8e5e89fbf064' + # The counter and the key before reseeding is: + # C_0 = 0 + # K_0 = "\x00" * 32 + # The counter after reseeding is 1, and the new key after reseeding is + # C_1 = 1 + # K_1 = SHAd256(K_0 || s) + # = SHA256(h'0eae3e401389fab86640327ac919ecfcb067359d95469e18995ca889abc119a6') + # = h'aafe9d0409fbaaafeb0a1f2ef2014a20953349d3c1c6e6e3b962953bea6184dd' + # The first block of random data, therefore, is + # r_1 = AES-256(K_1, 1) + # = AES-256(K_1, h'01000000000000000000000000000000') + # = h'b7b86bd9a27d96d7bb4add1b6b10d157' + # The second block of random data is + # r_2 = AES-256(K_1, 2) + # = AES-256(K_1, h'02000000000000000000000000000000') + # = h'2350b1c61253db2f8da233be726dc15f' + # The third and fourth blocks of random data (which become the new key) are + # r_3 = AES-256(K_1, 3) + # = AES-256(K_1, h'03000000000000000000000000000000') + # = h'f23ad749f33066ff53d307914fbf5b21' + # r_4 = AES-256(K_1, 4) + # = AES-256(K_1, h'04000000000000000000000000000000') + # = h'da9667c7e86ba247655c9490e9d94a7c' + # K_2 = r_3 || r_4 + # = h'f23ad749f33066ff53d307914fbf5b21da9667c7e86ba247655c9490e9d94a7c' + # The final counter value is 5. + self.assertEqual("aef42a5dcbddab67e8efa118e1b47fde5d697f89beb971b99e6e8e5e89fbf064", + fa.pools[0].hexdigest()) + self.assertEqual(None, fa.generator.key) + self.assertEqual(0, fa.generator.counter.next_value()) + + result = fa.random_data(32) + + self.assertEqual(b("b7b86bd9a27d96d7bb4add1b6b10d157" "2350b1c61253db2f8da233be726dc15f"), b2a_hex(result)) + self.assertEqual(b("f23ad749f33066ff53d307914fbf5b21da9667c7e86ba247655c9490e9d94a7c"), b2a_hex(fa.generator.key)) + self.assertEqual(5, fa.generator.counter.next_value()) + + def test_accumulator_pool_length(self): + """FortunaAccumulator.FortunaAccumulator minimum pool length""" + fa = FortunaAccumulator.FortunaAccumulator() + + # This test case is hard-coded to assume that FortunaAccumulator.min_pool_size is 64. + self.assertEqual(fa.min_pool_size, 64) + + # The PRNG should not allow us to get random data from it yet + self.assertRaises(AssertionError, fa.random_data, 1) + + # Add 60 bytes, 4 at a time (2 header + 2 payload) to each of the 32 pools + for i in range(15): + for p in range(32): + # Add the bytes to the pool + fa.add_random_event(2, p, b("XX")) + + # The PRNG should not allow us to get random data from it yet + self.assertRaises(AssertionError, fa.random_data, 1) + + # Add 4 more bytes to pool 0 + fa.add_random_event(2, 0, b("XX")) + + # We should now be able to get data from the accumulator + fa.random_data(1) + +def get_tests(config={}): + from Crypto.SelfTest.st_common import list_test_cases + return list_test_cases(FortunaAccumulatorTests) + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.pyo new file mode 100644 index 0000000000000000000000000000000000000000..f9792684b70d007bf76ccd97b31f9971fda05de7 GIT binary patch literal 5723 zcmc&&TW{RP6&`X|tBWPutsL2k9Y=K>cag&ClFMt68cw7XC=#dvWh0ItcQND)CCYn| zmR#2^Y@k4bJ_qP)|3+VmA`ksZ?GH%5bI84+gS;i0V_r|3m!pe}X6>_CO7>X9#5qRTEuP?3qHF;;1H6U977)@yry%&&O2_R5hw9 z>M<|6b@8YVA?3@QcvJ~$h`k2aE{N{D=q-r71!1T~p&R08QKT4fNqj5BH$r^9w7HXNt_+F?LYP7e)-7X7-=L-551`SygyUnXK7awF-chmcY&Wn5_9Sk?N zhA)qc!Db};YS7#K&0tuJ`f~jLNs^3uqpmCl!@Q2ZcYmwyWpz zp&_E(<{Ww^B!_;a*%p5JH4q3u*RBvfLr4SGg%z5#z&kvdQsbZE{j`=%5>&hca;Bjo zl2Z1sqm;w8P5cWcJiD!5?SBc|%J%ksYct$z?H|7^4hQ}HFS2+)&kBA2SSHWpfzJ2K z0rqKq$Ts`slI&MH?bDKVPAj+xc{KA}7mttcQGqlTCR>7vq!(M_9_&&Gab%D$y*9)v zl-ani4D#Y{Okq@2rl6`iwc}d6%!vYCidN_i3sw#5-0(+z=g#Zf_^-b6r~1+e3)HG8 zc_>2x3`m+mhediH4-NgNYEKkI6Rh=RacxG)E3++m&NR^SIRhb(s$jVd!<}L8s_M(Z zpvyr}JVZNJrJinS+xM)t8>)6o2Db0E+(6r5m?lZ99awJLaUC~x-6VC|+Ofi*ow~|N zLdW%r8idF=$>^UYI%yC)c4FH~wS7B`T`P>GmwJJ+mGqOujcw(%Jk@fQ)XJ60wd{Zf z(q7`V-JqaAQgNa*o)pgkoS4H>B=Q|$yTU%P(G)fmI~gTR+w%L4T++j2cG2zIiEpI#A6nk1P+u(*WM z%*yb)%yT^~K06u7E>>KKuI?Wchs7d_fF+e7=n7`Y<73@dtZf_-dT?#kfP!nN5nc=h z5xo`^Q^#?LnTsBsXHFMP*(>vx8-mc?48N(u(VvBlw2Y8@B zhCswzxs@T>YGsVo$5kfBlpzkPNJNhbj{%{C*8{YxAY{S@gdiNx?mAcT%5Csq3L=x< zj2P$io}czUYhZ?vbGnuo!CL|V4LisI)P&|Q{w#o`q|Oq(Z$BN4QF5ZuC4!PwG`Vs9 zyvjD-3H2NTE7#Hi)A`-Q6?bT^y%>v3Qm40I12x7V_ZIC zjK7p)K!Zlb#VKL^2ytGeU6?SK3=~Jp;%H?8BB(7hB-CCON0jK7JkE$p1H8tZSpX$F zWma`nykfi_W6?aDgyFCN51q?VrZ9tnmd1?PfuPiGliV-=5aj$MX(rw0V*&?aM&7`i z?Guh&PIshE9b398iItME=j%YH5_tj=1jk4E;wmrn(;$p>9QsxqhT20DWC>v!r!CK! zred)l2VSf~Y5OYllpn{ARLY9I*h1#v`gYrG#a7~3w%b;*od!zU?RKnv+f#|_CYN;unXnj*^9pZc-&}@=&@{G4ylYFQQdcPGg=?FrtPLiRF}J zXVBN2-W=$@9@43e^U7!XB{FIpjs~NCfsAMg5K0z!_qkvs(XpF(bC~GdiuH*0 z^ynAF!0!#8jcIJomuH-)oJVPpzk;9B*`FM0m0fAoT(8}(t=F35I9L%OI-S1k=}w13 zr_<>T)ToQsh&HH*t~a9hh}*89 +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-tests for Crypto.Random.Fortuna.FortunaGenerator""" + +__revision__ = "$Id$" + +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * +from Crypto.Util.py3compat import * + +import unittest +from binascii import b2a_hex + +class FortunaGeneratorTests(unittest.TestCase): + def setUp(self): + global FortunaGenerator + from Crypto.Random.Fortuna import FortunaGenerator + + def test_generator(self): + """FortunaGenerator.AESGenerator""" + fg = FortunaGenerator.AESGenerator() + + # We shouldn't be able to read data until we've seeded the generator + self.assertRaises(Exception, fg.pseudo_random_data, 1) + self.assertEqual(0, fg.counter.next_value()) + + # Seed the generator, which should set the key and increment the counter. + fg.reseed(b("Hello")) + self.assertEqual(b("0ea6919d4361551364242a4ba890f8f073676e82cf1a52bb880f7e496648b565"), b2a_hex(fg.key)) + self.assertEqual(1, fg.counter.next_value()) + + # Read 2 full blocks from the generator + self.assertEqual(b("7cbe2c17684ac223d08969ee8b565616") + # counter=1 + b("717661c0d2f4758bd6ba140bf3791abd"), # counter=2 + b2a_hex(fg.pseudo_random_data(32))) + + # Meanwhile, the generator will have re-keyed itself and incremented its counter + self.assertEqual(b("33a1bb21987859caf2bbfc5615bef56d") + # counter=3 + b("e6b71ff9f37112d0c193a135160862b7"), # counter=4 + b2a_hex(fg.key)) + self.assertEqual(5, fg.counter.next_value()) + + # Read another 2 blocks from the generator + self.assertEqual(b("fd6648ba3086e919cee34904ef09a7ff") + # counter=5 + b("021f77580558b8c3e9248275f23042bf"), # counter=6 + b2a_hex(fg.pseudo_random_data(32))) + + + # Try to read more than 2**20 bytes using the internal function. This should fail. + self.assertRaises(AssertionError, fg._pseudo_random_data, 2**20+1) + +def get_tests(config={}): + from Crypto.SelfTest.st_common import list_test_cases + return list_test_cases(FortunaGeneratorTests) + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/test_FortunaGenerator.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/test_FortunaGenerator.pyo new file mode 100644 index 0000000000000000000000000000000000000000..7c92dc9975a84b674384c286bc5e521cab3d7ef0 GIT binary patch literal 2863 zcmcgu+iu%N5FJvoY{_!sHf>rLEfN%IAOwiPi$sw{5F~Zo3sR&3?L0&fKrFdShYm%m zO%QDLU-IJAhMw7n2@jXkioHVI-TN`XKx4<2}eN5}ItW+BJ~) zcO7*MgIu=YV6aVR86i1Pd3s-~TGzMJvbw!joy>K)8;U}fv)!M{N-qkr`u?m6RS8{I zbsIJB{3`Ec|Kjf{MgfqSL<}SYBAUp(X1b2k*b&i7^+tb=^QGA{bBE;q3~EyR0Z086 z5{0M0GXoz7u`+nlg79EK{t^c^=C*>3en5~W(EiY;lpDN=mwv1yiHJqz~w;L zCWrV@973|uXcGW6LN~xKFsTL3_P(D!L+FJ2<9&NK*tMqf6aBI*roUzJw9d4;KNra> zair>L<6uhg)A6Sb;?reBQ@WApa(KIFZH*o4=kvQXp<{!|DA1IcjKU+tL<1Zflqi21 z@D}GL=oY*+;J8fyowmTB-8F)Wb}_%!N&3`82Cg?icPUp+Q5G?5WNE8SYu#g|O=gou zV+uW8HpL9mTVp+(bZGL$(gFs9ZrKNWJ`>+qiFYrGUv}7p@xR#5EU+wj?q9U<5r>FO zp99|l`3WO~ujOFyDWX|_gXDvIc)Wjbmb{$u`~vuHeo=W|>PM($Dd7cnAcwAJk4CoZ z4V|GQhOzJiEA>-r?0REQ`A(ABV&ufJ?_23u4Fk^``tisc>Dy>zoW#mW?6Kz$MdCQF zwEVyelwt|b_8KANdv;<;CmoJQek{FM*h4E$-Em-xSY~92C0$q8aqQTEKlVpKB2x65 zCL;_mR_Vx-ETp`6Y^P~}>bC7jE3pGqb4Rvk`JNMxGfFd-OeF^^Tx2LbYoe4p46LC_ ztw4;^l!YwEPRAIQHNw#R#8rVa^qui2bzE!c#A#DF=-pBw*`^w@4TEdA=J$qI18@;= z-Vk-IDjkZf#)r~HiTyW;n(M4AG+o=gRts516_>F{3N7>|ZZ}%{e=J0R(xOX)>2;%L++@1FTD1pMaa$JT4RQNTL^Mmp1YHDFfpnivg+fm2pwv$yWAPyHo>LC}~0oFpQZrY@h@L^N9 zj^cTSrI$fV1ZEdE4!uJLo8Gu8*}Eu~l(Sh`gtw5((KHQ&U`fg%&5oFJ4$jr!!tdco zHHWC5U@#027~973HfJI$q9{QQ|IW~&p4hYv0tkBnVMLfdZBU?GSQMEiblA%wP7W5> z*g{IF^MhVt7VwcC}@$eZ&QR4u9?oy>6;YkfbN)Ie-z0w!K9`F6GfGJ zoz?iFaf4oZeNr>ywW@eGE7DTmM8+};p6e{fe(czo0&}4+{?o8zxeX`0L;eW4I4eY* zWLZ;AXon)(!zAO}VF*L&HzC2N>Gjb?F_!1#igJj;d(b@ehm`#Fmq +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Random.Fortuna.SHAd256""" + +__revision__ = "$Id$" +from Crypto.Util.py3compat import * + +# This is a list of (expected_result, input[, description]) tuples. +test_data = [ + # I could not find any test vectors for SHAd256, so I made these vectors by + # feeding some sample data into several plain SHA256 implementations + # (including OpenSSL, the "sha256sum" tool, and this implementation). + # This is a subset of the resulting test vectors. The complete list can be + # found at: http://www.dlitz.net/crypto/shad256-test-vectors/ + ('5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456', + '', "'' (empty string)"), + ('4f8b42c22dd3729b519ba6f68d2da7cc5b2d606d05daed5ad5128cc03e6c6358', + 'abc'), + ('0cffe17f68954dac3a84fb1458bd5ec99209449749b2b308b7cb55812f9563af', + 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') +] + +def get_tests(config={}): + from Crypto.Random.Fortuna import SHAd256 + from Crypto.SelfTest.Hash.common import make_hash_tests + return make_hash_tests(SHAd256, "SHAd256", test_data, 32) + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/test_SHAd256.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/Fortuna/test_SHAd256.pyo new file mode 100644 index 0000000000000000000000000000000000000000..c1427c279f4a41e0f19fb1678c52a9f1cbb07dfa GIT binary patch literal 1482 zcmcgr+l~`Q5UsYoh6Qg}AUq^_@dFZ0q_yVO;~9hyXrqWo(Sl})1gnuoJzYKC*`15y zX(O!!Ps?}ZqmmCGRbxl+z%%3OOLIGz2 zZ~!=jY5=eCF5o@D`>-6s*$`+W-iD8~X#{2uZ~~VDSeyR90aRl+8v}j^AIaAZFk`s5 z33vza5UxRph7KRV>Fj&H(j_=GRdHlZXQ$n!v}Rhg>*?|OYGvDbq8e=L`ETvoZW=W| zeeoPU8Fn1;!{6~?`H8-nppj+x#XcjHScJwg-Xe5;8Kdv0$XiH9M#hWdLTks5TW~yK1lR$+8@Lu!XC~}qn-?G7G^OP``-`|Dr~H7D16ul= z;y1{XV|h}kI!E<1pngXU>}>*)quNxKW3$Y1|HAtO63!*zbie-AX1tUzg&hMunC%RE zNw|!&o@^FTmSL;2%uf3L+Po{fvZbniDXBkgSrH{Zsb!^X!m;&r+R@Oc+GJV6GEMFi skhWQ{W%KRpShu*T%+ntzfbK_v@n9@&?SmN7TjaJsoa{}+MC^ +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test for Crypto.Random.OSRNG package""" + +__revision__ = "$Id$" + +import os + +def get_tests(config={}): + tests = [] + if os.name == 'nt': + from Crypto.SelfTest.Random.OSRNG import test_nt; tests += test_nt.get_tests(config=config) + from Crypto.SelfTest.Random.OSRNG import test_winrandom; tests += test_winrandom.get_tests(config=config) + elif os.name == 'posix': + from Crypto.SelfTest.Random.OSRNG import test_posix; tests += test_posix.get_tests(config=config) + if hasattr(os, 'urandom'): + from Crypto.SelfTest.Random.OSRNG import test_fallback; tests += test_fallback.get_tests(config=config) + from Crypto.SelfTest.Random.OSRNG import test_generic; tests += test_generic.get_tests(config=config) + return tests + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/__init__.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..720e955ede06bfec2c9a5bb0b23e1a41c72cb498 GIT binary patch literal 1370 zcmcIjO>fgc5S_JSrzt7)fRHL7=%EL5NCe`*hfsx7B!q-g_(y?Y-uB;p$Ba&D~unK)uc&Vy- z+@2ou>0cPvWn2uaj>mN_;{aTjpyUJE^^I{o#;w6B@;Ef>KUU-y5?klO9;{+t7+)$x zQRCzqS}<|}#>%lx3Auz9V?c{#=+w@#lx-rv)&mnHLb=0&fFSWakoAajAB)mnI|8zfP0W>Xh z?Iek?DNSigB$>;H+~&?TDTz$iFeJRAi&%-r&@mUlzlt#r2?d*C*n672K@;+aF9r{W zPlori#j*QPSJ`WGkXhsOpdH4{lg?VwnIGAVM>dnvRK`g;TpXw5!(BT64h9ghxFI&- z7OpMcwUKg;=u27Vrjqi{OG!$2z&CN@M;lvwii1lnCt;(6EMfE#? +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Random.OSRNG.fallback""" + +__revision__ = "$Id$" + +import unittest + +class SimpleTest(unittest.TestCase): + def runTest(self): + """Crypto.Random.OSRNG.fallback.new()""" + # Import the OSRNG.nt module and try to use it + import Crypto.Random.OSRNG.fallback + randobj = Crypto.Random.OSRNG.fallback.new() + x = randobj.read(16) + y = randobj.read(16) + self.assertNotEqual(x, y) + +def get_tests(config={}): + return [SimpleTest()] + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_fallback.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_fallback.pyo new file mode 100644 index 0000000000000000000000000000000000000000..853cc3b76647d0b72ac5082bdcd1f98ace57b4c6 GIT binary patch literal 1542 zcmcgsU279T6uq;XY}1(ffru0YgY;qhkfq|2B1McMf~2x5NW;Rg$xPBsH@k6Xq88Gp z_ILTC^atpp1XAS0j>d^|@CX+Z5bn5@PZP1En7SIaku=hwHRuVE~^N4Tx3$duwU&7rrtNb>M z!wo3=;2&-_fWbObmdUtm*%nrp8MDj}!7an6b*Ai1EHYzsZ3mTo{b`vMA-g&QgL=4_ zYpj+*)Le+s%yPoMI(-siNluxMSoNQ!?_rcZdDVLyJ&pF##fd$t%Jf}6N)5`|TcC8= zRGV}iHs!K&!O}JK)WJ@<59B582r=C4%aSd-xW;g`$?u4J;ubz3Gjm*}EVH?m(zSz> z^GYoXY~w8$TtU5dyfMRj2r(X1AY6-a)>vGNF#+qwXDZMcd_Hj6xw@6h{ +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Random.OSRNG""" + +__revision__ = "$Id$" + +import unittest + +class SimpleTest(unittest.TestCase): + def runTest(self): + """Crypto.Random.OSRNG.new()""" + # Import the OSRNG module and try to use it + import Crypto.Random.OSRNG + randobj = Crypto.Random.OSRNG.new() + x = randobj.read(16) + y = randobj.read(16) + self.assertNotEqual(x, y) + +def get_tests(config={}): + return [SimpleTest()] + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_generic.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_generic.pyo new file mode 100644 index 0000000000000000000000000000000000000000..cccfdb421c9c6c3ce220d9c0830cf6c13c0da51d GIT binary patch literal 1494 zcmcIk-)j>=5T3nD(l)04s37#oJQTb>Bq%;9Qp6}CNLnr;G#o6~+fBUmau>53wU9ow zf0uuh{sH>Uq*_H^bLmd!W@mQ3Z)Wzw@7v99$6pUKx_UzVe~#sH2tzc4R5Vm%0x}^L z0S%$l$ObeCX#{(nE{QIPj)yfukZI5*0_tQNWH#tDpt&Wp$xg!!3EL#IMW%@urAh>Z zG>C3+$_EewTZ}s1I^TAS+}rl3nzwuNvzf2Daax*c+C3b^{nxGr-@P|xFaLq3@0%Q& zPiKXFhuGh26wEKM+#LuD1i(uIC7^f^@pi_dj>XJ-Sndb{oI$uCI#;w*G{K(`2G8?= zme6Yq{6f)r`1fm#mPC^}En%IE&dz(S~TI*?L76o487WS@@ zt{ZNQY;+&X1rQA-Z-8QG%vNzV3&uP2^F42P{H*3fUh{l{THE-x412fGWUF}=N#O`0pHtL#u%1A zTC+}qjO1C7PESmF(1Gqawdb#jv7>ZRct$4IMLsJLgO$nC+Ef{ail<2Hx&4&8yh1VJ z9roa3IkJ~JEA10r@ixryJ$B&h#?`xSqiAcVx|;q2{-8L%>5ZTfw1VAc3m0cg{RCjj BUQqx5 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_nt.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_nt.py new file mode 100644 index 00000000..a7a83385 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_nt.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Util/test_generic.py: Self-test for the OSRNG.nt.new() function +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Random.OSRNG.nt""" + +__revision__ = "$Id$" + +import unittest + +class SimpleTest(unittest.TestCase): + def runTest(self): + """Crypto.Random.OSRNG.nt.new()""" + # Import the OSRNG.nt module and try to use it + import Crypto.Random.OSRNG.nt + randobj = Crypto.Random.OSRNG.nt.new() + x = randobj.read(16) + y = randobj.read(16) + self.assertNotEqual(x, y) + +def get_tests(config={}): + return [SimpleTest()] + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_nt.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_nt.pyo new file mode 100644 index 0000000000000000000000000000000000000000..190cf04b80c03070d1c13865d53e4f9de1505dfa GIT binary patch literal 1488 zcmcgsO>fgc5S_IXw+Sg9LVzkEkwXtIQY;WB5ULOXAtaQ7&83m0m7Cq9P8~aVH$bK2 z)c!7h6#M{qv#E%X;8^U;WItwh-kX`V|6`~9{pj1_h%O%=|1TgWhf+jCXhB0k$|L1d z;n5I-25FC`K8>;7qzj^RqN8Dh;G_b&fJ2jXKx&IlJ*qXSZ8jQiIk#<6EmCdx2vNep zrzE__As<2|x)}GYHnwXPxz*iqRd@UK+1yr9oRzAYMTbc|coUV@G+@5>R_*0K@eFL6 zz4O_;&>!Lcn~=crONhAzr2ztv$)WKmPD0)uv1&q?d>>*GD9{Gyf@mdZDQJqH<2-FJ z+m%O4Oq&efbxslSB#Yd-l+n1x$V_U=C& zY=EtGUMv%Exv?HbrM1ik2U-qV>rC0}7-Yui+72rF`qLsSLUwWn26=a}^0^A<`Iu=mErVx&z^wh%?3FnuwuWcQqygwdeJL)6Uh6T*gOLInE~=&{ve%7UEB| zm7Hv|kBI|L;xe7HEH9-TVck7U%CX=!1Pio3`sy5XHe7t(;$key-14!OV{qvbzPmBs zxDBl +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Random.OSRNG.posix""" + +__revision__ = "$Id$" + +import unittest + +class SimpleTest(unittest.TestCase): + def runTest(self): + """Crypto.Random.OSRNG.posix.new()""" + # Import the OSRNG.nt module and try to use it + import Crypto.Random.OSRNG.posix + randobj = Crypto.Random.OSRNG.posix.new() + x = randobj.read(16) + y = randobj.read(16) + self.assertNotEqual(x, y) + +def get_tests(config={}): + return [SimpleTest()] + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_posix.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_posix.pyo new file mode 100644 index 0000000000000000000000000000000000000000..c6ddf29316b8c5681fd7c110c9bb67fb54350cc3 GIT binary patch literal 1515 zcmcgsOK;Oa5T3OYw+$%|A%uD&haTKRED$FUst^GoB$Oh%mqwN>H@gW=9Xoh8&`Rm4 z{aySh_yO?Eq)>5yTXDM6eay^$-#pg;zTNqD^z~p&SD%mnFEMNZp@~M2ibjgGN7|>- zqY)-8G9Jx*nqa?8mqZstN23_a4`ob;Wsu4k8pGrdXO^ajn@!qrinSGt}@2T4498!c*EoZ1#FcHimU;s?H= z>#&1jz9`KhJpAUQu>A_d-h(i}0n{XbJc^T$kH;+97|efwVG{^22knyRT+vF=41Yp< z)?&iv9<8u!GlL67=l-9|7OjY80j;nPeUB7;B_Tt$kNB3qv5G45CEQz6D(*rv+<U=)=27vRm?pVKV$`NGmhQ=CAzNqeSRn`V+p*#>v}t#E*fS_{RE2P BWmEtF literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_winrandom.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_winrandom.py new file mode 100644 index 00000000..3010eb72 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_winrandom.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Util/test_winrandom.py: Self-test for the winrandom module +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Random.OSRNG.winrandom""" + +__revision__ = "$Id$" + +import unittest + +class SimpleTest(unittest.TestCase): + def runTest(self): + """Crypto.Random.OSRNG.winrandom""" + # Import the winrandom module and try to use it + from Crypto.Random.OSRNG import winrandom + randobj = winrandom.new() + x = randobj.get_bytes(16) + y = randobj.get_bytes(16) + self.assertNotEqual(x, y) + +def get_tests(config={}): + return [SimpleTest()] + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_winrandom.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/OSRNG/test_winrandom.pyo new file mode 100644 index 0000000000000000000000000000000000000000..4ee3b133ea80e75f20c7c783f6047683b22f71ed GIT binary patch literal 1518 zcmcgs-)|B@5T3oG6cDvWU;1F=p%3@~vFVe>G)6SW#87kiV96z$gI)0G{XllHlC)3l z-{l{re}H~7R2mcGTRk$v?XWXD-}lWD{%##(pl3w6qH{&+ zOwlZ0yypR(2?+pjf#1SEmlZlAn!zJpp^JbNSR1stzI(_A{0o#|k*0hddpBUy9jy9N z#NYpWk%&=vhEUj3$(~xTM=R#^4x)*3cH#S_fBkuxWb0B)p#$;j+-2=_YrTsXYqRokQ}_~?027bpTzT(|5O(7yL1#gDA$=M;{DgX-h9Im z&Z9>#7r<4Oj1lw3CS$}MdATD~g%RL*U%aHQWv(JPE{jPzz3%;HdFH|5(O?DKV=Sb9 zQdi{WNm^(%?B!co_q6hCAq;iQzG-HwJFCKttJ9mFYK4pr6uTy1bq!r&g>=5 piiCnJ;=0iTF2VPS`TPH1*SFws7Y#V3yBbu3X0Y36hD}vhzW}uYXiNYA literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/__init__.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/__init__.py new file mode 100644 index 00000000..f972bf0b --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/__init__.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Random/__init__.py: Self-test for random number generation modules +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test for random number generators""" + +__revision__ = "$Id$" + +def get_tests(config={}): + tests = [] + from Crypto.SelfTest.Random import Fortuna; tests += Fortuna.get_tests(config=config) + from Crypto.SelfTest.Random import OSRNG; tests += OSRNG.get_tests(config=config) + from Crypto.SelfTest.Random import test_random; tests += test_random.get_tests(config=config) + from Crypto.SelfTest.Random import test_rpoolcompat; tests += test_rpoolcompat.get_tests(config=config) + from Crypto.SelfTest.Random import test__UserFriendlyRNG; tests += test__UserFriendlyRNG.get_tests(config=config) + return tests + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/__init__.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..df1d56f6198fe3620f8ff33a0a280f1efa6dedc2 GIT binary patch literal 1211 zcmcIjO=}x55FPE8V@)|TvUvb$PV+JeD* zO3wXV{XhKy?Tq9khxphoXgtz9&Ac}w`@bI_)<2VY3A@k7-w(L-1sVY`N6TQ&AVbH4 z8}vPpJ_sMKJg6ri0uUkO0nE{f;0CXRAOpCJKy*MHz%?*d;^h!#gDz!$iDoAA)zC<7 z`YToU>$DWA=$B2gkad48OIfEz)mjG#J^3t7mJFQ^E;<c#zmgqM))@^>+?F3rN}pwjcS@>G~;?x88xB_eZ|D1*bXPg2pF2*S{hCjb?o6T zrUw(#SYl#k)5KN;Z5<9B*bAn>fQ+7?8NW*|uvYr!`SxF1h`~iJbX=XO%o%9(*bF>IU1}>T5W@xLZXd>kXP3_@as3qs7XZ>3K$aJQ#5tjC@HDy{zJUK*2`~;1mNmIY> d6 +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for generic Crypto.Random stuff """ + +from __future__ import nested_scopes + +__revision__ = "$Id$" + +import binascii +import pprint +import unittest +import os +import time +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * +from Crypto.Util.py3compat import * + +try: + import multiprocessing +except ImportError: + multiprocessing = None + +import Crypto.Random._UserFriendlyRNG +import Crypto.Random.random + +class RNGForkTest(unittest.TestCase): + + def _get_reseed_count(self): + """ + Get `FortunaAccumulator.reseed_count`, the global count of the + number of times that the PRNG has been reseeded. + """ + rng_singleton = Crypto.Random._UserFriendlyRNG._get_singleton() + rng_singleton._lock.acquire() + try: + return rng_singleton._fa.reseed_count + finally: + rng_singleton._lock.release() + + def runTest(self): + # Regression test for CVE-2013-1445. We had a bug where, under the + # right conditions, two processes might see the same random sequence. + + if sys.platform.startswith('win'): # windows can't fork + assert not hasattr(os, 'fork') # ... right? + return + + # Wait 150 ms so that we don't trigger the rate-limit prematurely. + time.sleep(0.15) + + reseed_count_before = self._get_reseed_count() + + # One or both of these calls together should trigger a reseed right here. + Crypto.Random._UserFriendlyRNG._get_singleton().reinit() + Crypto.Random.get_random_bytes(1) + + reseed_count_after = self._get_reseed_count() + self.assertNotEqual(reseed_count_before, reseed_count_after) # sanity check: test should reseed parent before forking + + rfiles = [] + for i in range(10): + rfd, wfd = os.pipe() + if os.fork() == 0: + # child + os.close(rfd) + f = os.fdopen(wfd, "wb") + + Crypto.Random.atfork() + + data = Crypto.Random.get_random_bytes(16) + + f.write(data) + f.close() + os._exit(0) + # parent + os.close(wfd) + rfiles.append(os.fdopen(rfd, "rb")) + + results = [] + results_dict = {} + for f in rfiles: + data = binascii.hexlify(f.read()) + results.append(data) + results_dict[data] = 1 + f.close() + + if len(results) != len(results_dict.keys()): + raise AssertionError("RNG output duplicated across fork():\n%s" % + (pprint.pformat(results))) + + +# For RNGMultiprocessingForkTest +def _task_main(q): + a = Crypto.Random.get_random_bytes(16) + time.sleep(0.1) # wait 100 ms + b = Crypto.Random.get_random_bytes(16) + q.put(binascii.b2a_hex(a)) + q.put(binascii.b2a_hex(b)) + q.put(None) # Wait for acknowledgment + + +class RNGMultiprocessingForkTest(unittest.TestCase): + + def runTest(self): + # Another regression test for CVE-2013-1445. This is basically the + # same as RNGForkTest, but less compatible with old versions of Python, + # and a little easier to read. + + n_procs = 5 + manager = multiprocessing.Manager() + queues = [manager.Queue(1) for i in range(n_procs)] + + # Reseed the pool + time.sleep(0.15) + Crypto.Random._UserFriendlyRNG._get_singleton().reinit() + Crypto.Random.get_random_bytes(1) + + # Start the child processes + pool = multiprocessing.Pool(processes=n_procs, initializer=Crypto.Random.atfork) + map_result = pool.map_async(_task_main, queues) + + # Get the results, ensuring that no pool processes are reused. + aa = [queues[i].get(30) for i in range(n_procs)] + bb = [queues[i].get(30) for i in range(n_procs)] + res = list(zip(aa, bb)) + + # Shut down the pool + map_result.get(30) + pool.close() + pool.join() + + # Check that the results are unique + if len(set(aa)) != len(aa) or len(set(res)) != len(res): + raise AssertionError("RNG output duplicated across fork():\n%s" % + (pprint.pformat(res),)) + + +def get_tests(config={}): + tests = [] + tests += [RNGForkTest()] + if multiprocessing is not None: + tests += [RNGMultiprocessingForkTest()] + return tests + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/test__UserFriendlyRNG.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/test__UserFriendlyRNG.pyo new file mode 100644 index 0000000000000000000000000000000000000000..5b9fa035ca2c4cff4879d65878f94078e257efe0 GIT binary patch literal 5064 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 N*VisD%q@6z?>`)7QpW%Q literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/test_random.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/test_random.py new file mode 100644 index 00000000..f9ffc663 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/test_random.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Util/test_generic.py: Self-test for the Crypto.Random.new() function +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Random.new()""" + +__revision__ = "$Id$" + +import unittest +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * +from Crypto.Util.py3compat import * + +class SimpleTest(unittest.TestCase): + def runTest(self): + """Crypto.Random.new()""" + # Import the Random module and try to use it + from Crypto import Random + randobj = Random.new() + x = randobj.read(16) + y = randobj.read(16) + self.assertNotEqual(x, y) + z = Random.get_random_bytes(16) + self.assertNotEqual(x, z) + self.assertNotEqual(y, z) + # Test the Random.random module, which + # implements a subset of Python's random API + # Not implemented: + # seed(), getstate(), setstate(), jumpahead() + # random(), uniform(), triangular(), betavariate() + # expovariate(), gammavariate(), gauss(), + # longnormvariate(), normalvariate(), + # vonmisesvariate(), paretovariate() + # weibullvariate() + # WichmannHill(), whseed(), SystemRandom() + from Crypto.Random import random + x = random.getrandbits(16*8) + y = random.getrandbits(16*8) + self.assertNotEqual(x, y) + # Test randrange + if x>y: + start = y + stop = x + else: + start = x + stop = y + for step in range(1,10): + x = random.randrange(start,stop,step) + y = random.randrange(start,stop,step) + self.assertNotEqual(x, y) + self.assertEqual(start <= x < stop, True) + self.assertEqual(start <= y < stop, True) + self.assertEqual((x - start) % step, 0) + self.assertEqual((y - start) % step, 0) + for i in range(10): + self.assertEqual(random.randrange(1,2), 1) + self.assertRaises(ValueError, random.randrange, start, start) + self.assertRaises(ValueError, random.randrange, stop, start, step) + self.assertRaises(TypeError, random.randrange, start, stop, step, step) + self.assertRaises(TypeError, random.randrange, start, stop, "1") + self.assertRaises(TypeError, random.randrange, "1", stop, step) + self.assertRaises(TypeError, random.randrange, 1, "2", step) + self.assertRaises(ValueError, random.randrange, start, stop, 0) + # Test randint + x = random.randint(start,stop) + y = random.randint(start,stop) + self.assertNotEqual(x, y) + self.assertEqual(start <= x <= stop, True) + self.assertEqual(start <= y <= stop, True) + for i in range(10): + self.assertEqual(random.randint(1,1), 1) + self.assertRaises(ValueError, random.randint, stop, start) + self.assertRaises(TypeError, random.randint, start, stop, step) + self.assertRaises(TypeError, random.randint, "1", stop) + self.assertRaises(TypeError, random.randint, 1, "2") + # Test choice + seq = range(10000) + x = random.choice(seq) + y = random.choice(seq) + self.assertNotEqual(x, y) + self.assertEqual(x in seq, True) + self.assertEqual(y in seq, True) + for i in range(10): + self.assertEqual(random.choice((1,2,3)) in (1,2,3), True) + self.assertEqual(random.choice([1,2,3]) in [1,2,3], True) + if sys.version_info[0] is 3: + self.assertEqual(random.choice(bytearray(b('123'))) in bytearray(b('123')), True) + self.assertEqual(1, random.choice([1])) + self.assertRaises(IndexError, random.choice, []) + self.assertRaises(TypeError, random.choice, 1) + # Test shuffle. Lacks random parameter to specify function. + # Make copies of seq + seq = range(500) + x = list(seq) + y = list(seq) + random.shuffle(x) + random.shuffle(y) + self.assertNotEqual(x, y) + self.assertEqual(len(seq), len(x)) + self.assertEqual(len(seq), len(y)) + for i in range(len(seq)): + self.assertEqual(x[i] in seq, True) + self.assertEqual(y[i] in seq, True) + self.assertEqual(seq[i] in x, True) + self.assertEqual(seq[i] in y, True) + z = [1] + random.shuffle(z) + self.assertEqual(z, [1]) + if sys.version_info[0] == 3: + z = bytearray(b('12')) + random.shuffle(z) + self.assertEqual(b('1') in z, True) + self.assertRaises(TypeError, random.shuffle, b('12')) + self.assertRaises(TypeError, random.shuffle, 1) + self.assertRaises(TypeError, random.shuffle, "1") + self.assertRaises(TypeError, random.shuffle, (1,2)) + # 2to3 wraps a list() around it, alas - but I want to shoot + # myself in the foot here! :D + # if sys.version_info[0] == 3: + # self.assertRaises(TypeError, random.shuffle, range(3)) + # Test sample + x = random.sample(seq, 20) + y = random.sample(seq, 20) + self.assertNotEqual(x, y) + for i in range(20): + self.assertEqual(x[i] in seq, True) + self.assertEqual(y[i] in seq, True) + z = random.sample([1], 1) + self.assertEqual(z, [1]) + z = random.sample((1,2,3), 1) + self.assertEqual(z[0] in (1,2,3), True) + z = random.sample("123", 1) + self.assertEqual(z[0] in "123", True) + z = random.sample(range(3), 1) + self.assertEqual(z[0] in range(3), True) + if sys.version_info[0] == 3: + z = random.sample(b("123"), 1) + self.assertEqual(z[0] in b("123"), True) + z = random.sample(bytearray(b("123")), 1) + self.assertEqual(z[0] in bytearray(b("123")), True) + self.assertRaises(TypeError, random.sample, 1) + +def get_tests(config={}): + return [SimpleTest()] + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/test_random.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/test_random.pyo new file mode 100644 index 0000000000000000000000000000000000000000..08d2ae4ffc6c25b200442a32094f3f997104b79a GIT binary patch literal 4534 zcmcInPj4GV6o0d8J9gqEPTZz(s7gc&xIjabhyztsA<{}9P(V%~B64MIyz6umdmZnN zOM+qvNY8u<4xEtShTzB*g!lk_1TG-1@Oy98f0ICklx%jqGw=WJ&AfeU|1mipeo-z} zDgLwZ`v&glTMRDIHbzC;id>6ao9Y&A#j(c1wGaUX0ql_7-c+aB(d>I?&Cfk`uVi#!}#YT)Y`2 zzYb-9$wPp7&rXJLEYPg)*fI?d=qyxgTaGuh=jyRi%J`! zpvpX1++(=ca7VwT1y%r2Cu%6_C{o9Y_AHLSW6?1{u{od<(Cp!9f{uwHKgN23PAnst z>~bdu$Vo#s?2s^XHSTofO1Vw3j9~-!*2Ymt=Z|F)_QJpzv3=-x*^^I%x{B z@_;E8({%U~=?o$NNIQJI|L_OuWQa|T(=nLRbey3RNJ8D|#WTzzhzXIjDPiv`YQCeO zWS=Oo$Wl7n3)OHXVy@QtT(CSw^KfGh+fZ;cHeh^sz4be79p09B5R5`F&rt_q7{sP zTpiqY&kt|A8FDYPNq25QPirM15Olp_kKyVh?MgLquMF_&S=!5Ustcg+rz!j;(cjcF zq%V=aECp7v8T^l|^u0&7&|z21WpUp6d;Kl0AwEY9UWx33Mq^{WGl#u^xU9sdH$eglUJLGw?k*sJ{O&7=RxJ z#;Gurs~9?1KZk;pFvT9oKr9ne5(AXhH_0u7VFxAM#EbeJhX?^wd;>AO9Zn=(!r!Ih zROMI%|7R=V^rCnu*49sEoGp`=dD#O-4YCs_8g;Epj?*?G#A-)VJWuYtSw%PtoDp}1 zt7TkO23G*$NFop4l9K=dPQ{)7n~K)mu`Nb(Ax4kAhX>}ZIf81;SCE}K!o+80VGuK; zbLu?asZ+eX&nG#WGhBf79=V^FQ(68oZCvb~(sNXG4{={rEH`|>&ygNx>gyQY3IZu7 z-JL}v_6+wqd2V=4H(kh7B~~N8 zq6gL7frg&rqEjGpqR0#NdQ(4WwVk?VOm;n8F=$kFj<}DVr?orf_YtSFdjHn)((6mN%LhmLQ8OsN>+h5!d|KQ(aH{*xt{0U}Qp)`4!QTkw zlI-C!=Pb_P5@f~IcEB7r*rlJ@oSjoyHH|ALcW#1zF|)ENr7~6uo=903(ZHjQVE=fSE)#*E0spmZPzg^y$o6( z<_p8R#9v<5aYuaOQmV@H?!CtAyv4PAcA{G`pKI$)k-vaQvWBsqzy4F->CNB7qq8(4WZ%B;G0ANNgstbUW}ht2Kuh4;%bd zTzVCxeo*psA(62Qck51L$93*~h35!2X|6=BS998R&8I;smVB)jxx~pqsZ`u%75j&e ze5De4kA0~qmC`a6O7lDvn0F3CToXUgejVp*Wx3jH95@;;$5GO1OkuCs@R}2Ol5fGI u^a_?suVIk-z^Dr_{o&#uG6&=yhZJ#0DJzBZo5hKrRO43Rvn)<*M*Rc(L`f?E literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/test_rpoolcompat.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/test_rpoolcompat.py new file mode 100644 index 00000000..be538da4 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/test_rpoolcompat.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Util/test_winrandom.py: Self-test for the winrandom module +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test for the Crypto.Util.randpool.RandomPool wrapper class""" + +__revision__ = "$Id$" + +import sys +import unittest + +class SimpleTest(unittest.TestCase): + def runTest(self): + """Crypto.Util.randpool.RandomPool""" + # Import the winrandom module and try to use it + from Crypto.Util.randpool import RandomPool + sys.stderr.write("SelfTest: You can ignore the RandomPool_DeprecationWarning that follows.\n") + rpool = RandomPool() + x = rpool.get_bytes(16) + y = rpool.get_bytes(16) + self.assertNotEqual(x, y) + self.assertNotEqual(rpool.entropy, 0) + + rpool.randomize() + rpool.stir('foo') + rpool.add_event('foo') + +def get_tests(config={}): + return [SimpleTest()] + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Random/test_rpoolcompat.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Random/test_rpoolcompat.pyo new file mode 100644 index 0000000000000000000000000000000000000000..ca15afef7737f5ba7ed9d1b251780899751e44b0 GIT binary patch literal 1772 zcmcgs&2G~`5T3Q0v<)eQKOw{cBXP*35eP0+s2~CdBvepRgc?P%w)Q4C*j}@{X$fji z?Gx}oJQO?te6yxRNQhgpvy++Gnc10dW*vUtXnouJ`Z}RsPl*4gSauGQ5{*CwjRd6u zr6J`3jlk4=NTZO_6;dJ1R%im72AvX}5bcc`l)5M6Kx{*UPXPgsGRP-by?msvP>(j^WFfAF5ZBR z4vnlTWuhdP*4h=sxcf4_oBhDE<60atE2>=WBIfUk1=P>5>}3#z%uomU6ayLzyS$w+ zX<#ureJuM01h@c*oTw0VEJ(P3W*!MtaRT{BFcilD9bu!vKtX#P{wc1|5z(wkN6^C{ zfLkrY2cR`-6@)boCO8xTYt{!qXq^ebci3Iy+-`G{{|3q<;!E?WED^LX;mo)*L|f6G zo=1r+qikAgqkIdNw()aS8I?$v>GGX4WmZmMA-P+5t`BXmm30seb3o)6xrx?0zPs)k zq`##&V4%INU0BzIU|p(=aSZ;U$((ZQ;HJvO`wO0oi;&Q2W!#Q-FFwv??pC2vr8Bx( zcw?RuU1Xn?<9V~idS4|UfWu*&doIZo)4r;9FF^2F|f>u-(UAhdk& zeDi+qQSaUu=e^hE_*J$)w#am|lF0`-Rd!rgIzEGSTthhK{9}JgqKitp9s+RkW?nM- zcfeW(io%ZQh;?xZZ%14WT4Fq+ExC%T+u(`DZ0hxFMTaTn}8&XIG+Ev`W= zWLCy;!YY1v&lkcIjY4LEaNSQ((XyP7x7d4LW{$)9IpbCi=a`4Vb!;sw^W6EB$9X)? zWwD>i?T6qk7CHX3rfMSRx#PV2wX&RC*Efi#FOE~4V4T{XH|ij>xZfBkzCD8*AihR+ t?@OzE|9okKD{OF!4cL?c{J+)KqrZIMEFz-FA=DQ^dXo5{C9veO+q%~@3E7EI=sn&2 zUH(z}2k6YU$00uJlKDD2JKOobuW9h}1#S3sX{DO^sV0p^4P<^r??9Y7^v zF2Pc905?<*zzjf#u#(VyzU>KN9)gbGhOS3oLbyBtP0t}*gAg@c4j@a8c*+xk%v6gJ z8i&J0(+!i zEF}X}sxl*>asMNUKq>{e#F@=i>Ktv*jhd%I-_DZb_TPs!a zAun$Craqtqf!#q#=D{`F!lY+A8~AolQ&_ZjfH`D6G4vzvRQc>*Nb>^TRK@y27iUk2 zj-vp)N1)B3=qqGO-g3vh5~hp?1WM_qR0`P=r8@J?I@^#7q!gfWUcla-x>y^fQho{2 hV*=#gl0Exx0(bv{vqv=7@w*ktNX9abViAiY@f$1Z+$aD5 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Signature/test_pkcs1_15.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Signature/test_pkcs1_15.py new file mode 100644 index 00000000..bc366962 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Signature/test_pkcs1_15.py @@ -0,0 +1,219 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Signature/test_pkcs1_15.py: Self-test for PKCS#1 v1.5 signatures +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +__revision__ = "$Id$" + +import unittest + +from Crypto.PublicKey import RSA +from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex +from Crypto.Hash import * +from Crypto import Random +from Crypto.Signature import PKCS1_v1_5 as PKCS +from Crypto.Util.py3compat import * + +def isStr(s): + t = '' + try: + t += s + except TypeError: + return 0 + return 1 + +def rws(t): + """Remove white spaces, tabs, and new lines from a string""" + for c in ['\n', '\t', ' ']: + t = t.replace(c,'') + return t + +def t2b(t): + """Convert a text string with bytes in hex form to a byte string""" + clean = b(rws(t)) + if len(clean)%2 == 1: + raise ValueError("Even number of characters expected") + return a2b_hex(clean) + +class PKCS1_15_Tests(unittest.TestCase): + + # List of tuples with test data for PKCS#1 v1.5. + # Each tuple is made up by: + # Item #0: dictionary with RSA key component, or key to import + # Item #1: data to hash and sign + # Item #2: signature of the data #1, done with the key #0, after + # hashing it with #3 + # Item #3: hash object generator + + _testData = ( + + # + # Taken from ftp://ftp.rsa.com/pub/pkcs/ascii/examples.asc + # "Some Examples of the PKCS Standards", 1999 + # + ( + + # Private key, from 2.1 + { + 'n':'''0a 66 79 1d c6 98 81 68 de 7a b7 74 19 bb 7f b0 c0 01 c6 + 27 10 27 00 75 14 29 42 e1 9a 8d 8c 51 d0 53 b3 e3 78 2a 1d + e5 dc 5a f4 eb e9 94 68 17 01 14 a1 df e6 7c dc 9a 9a f5 5d + 65 56 20 bb ab''', + 'e':'''01 00 + 01''', + 'd':'''01 23 c5 b6 1b a3 6e db 1d 36 79 90 41 99 a8 9e a8 0c 09 + b9 12 2e 14 00 c0 9a dc f7 78 46 76 d0 1d 23 35 6a 7d 44 d6 + bd 8b d5 0e 94 bf c7 23 fa 87 d8 86 2b 75 17 76 91 c1 1d 75 + 76 92 df 88 81''' + }, + # Data to sign, from 3.1 + '''30 81 a4 02 01 00 30 42 31 0b 30 09 06 + 03 55 04 06 13 02 55 53 31 1d 30 1b 06 03 55 04 0a 13 14 + 45 78 61 6d 70 6c 65 20 4f 72 67 61 6e 69 7a 61 74 69 6f + 6e 31 14 30 12 06 03 55 04 03 13 0b 54 65 73 74 20 55 73 + 65 72 20 31 30 5b 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 + 05 00 03 4a 00 30 47 02 40 + 0a 66 79 1d c6 98 81 68 de 7a b7 74 19 bb 7f b0 + c0 01 c6 27 10 27 00 75 14 29 42 e1 9a 8d 8c 51 + d0 53 b3 e3 78 2a 1d e5 dc 5a f4 eb e9 94 68 17 + 01 14 a1 df e6 7c dc 9a 9a f5 5d 65 56 20 bb ab + 02 03 01 00 01''', + # Signature, from 3.2 (at the very end) + '''06 db 36 cb 18 d3 47 5b 9c 01 db 3c 78 95 28 08 + 02 79 bb ae ff 2b 7d 55 8e d6 61 59 87 c8 51 86 + 3f 8a 6c 2c ff bc 89 c3 f7 5a 18 d9 6b 12 7c 71 + 7d 54 d0 d8 04 8d a8 a0 54 46 26 d1 7a 2a 8f be''', + MD2 + ), + + # + # RSA keypair generated with openssl + # + ( + """-----BEGIN RSA PRIVATE KEY----- + MIIBOwIBAAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+TLr7UkvEtFrRhDDKMtuII + q19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQJACUSDEp8RTe32ftq8IwG8 + Wojl5mAd1wFiIOrZ/Uv8b963WJOJiuQcVN29vxU5+My9GPZ7RA3hrDBEAoHUDPrI + OQIhAPIPLz4dphiD9imAkivY31Rc5AfHJiQRA7XixTcjEkojAiEAyh/pJHks/Mlr + +rdPNEpotBjfV4M4BkgGAA/ipcmaAjcCIQCHvhwwKVBLzzTscT2HeUdEeBMoiXXK + JACAr3sJQJGxIQIgarRp+m1WSKV1MciwMaTOnbU7wxFs9DP1pva76lYBzgUCIQC9 + n0CnZCJ6IZYqSt0H5N7+Q+2Ro64nuwV/OSQfM6sBwQ== + -----END RSA PRIVATE KEY-----""", + "This is a test\x0a", + # + # PKCS#1 signature computed with openssl + # + '''4a700a16432a291a3194646952687d5316458b8b86fb0a25aa30e0dcecdb + 442676759ac63d56ec1499c3ae4c0013c2053cabd5b5804848994541ac16 + fa243a4d''', + SHA + ), + + # + # Test vector from http://www.di-mgt.com.au/rsa_alg.html#signpkcs1 + # + ( + { + 'n':'''E08973398DD8F5F5E88776397F4EB005BB5383DE0FB7ABDC7DC775290D052E6D + 12DFA68626D4D26FAA5829FC97ECFA82510F3080BEB1509E4644F12CBBD832CF + C6686F07D9B060ACBEEE34096A13F5F7050593DF5EBA3556D961FF197FC981E6 + F86CEA874070EFAC6D2C749F2DFA553AB9997702A648528C4EF357385774575F''', + 'e':'''010001''', + 'd':'''00A403C327477634346CA686B57949014B2E8AD2C862B2C7D748096A8B91F736 + F275D6E8CD15906027314735644D95CD6763CEB49F56AC2F376E1CEE0EBF282D + F439906F34D86E085BD5656AD841F313D72D395EFE33CBFF29E4030B3D05A28F + B7F18EA27637B07957D32F2BDE8706227D04665EC91BAF8B1AC3EC9144AB7F21''' + }, + "abc", + '''60AD5A78FB4A4030EC542C8974CD15F55384E836554CEDD9A322D5F4135C6267 + A9D20970C54E6651070B0144D43844C899320DD8FA7819F7EBC6A7715287332E + C8675C136183B3F8A1F81EF969418267130A756FDBB2C71D9A667446E34E0EAD + 9CF31BFB66F816F319D0B7E430A5F2891553986E003720261C7E9022C0D9F11F''', + SHA + ) + + ) + + def testSign1(self): + for i in range(len(self._testData)): + row = self._testData[i] + # Build the key + if isStr(row[0]): + key = RSA.importKey(row[0]) + else: + comps = [ long(rws(row[0][x]),16) for x in ('n','e','d') ] + key = RSA.construct(comps) + h = row[3].new() + # Data to sign can either be in hex form or not + try: + h.update(t2b(row[1])) + except: + h.update(b(row[1])) + # The real test + signer = PKCS.new(key) + self.failUnless(signer.can_sign()) + s = signer.sign(h) + self.assertEqual(s, t2b(row[2])) + + def testVerify1(self): + for i in range(len(self._testData)): + row = self._testData[i] + # Build the key + if isStr(row[0]): + key = RSA.importKey(row[0]).publickey() + else: + comps = [ long(rws(row[0][x]),16) for x in ('n','e') ] + key = RSA.construct(comps) + h = row[3].new() + # Data to sign can either be in hex form or not + try: + h.update(t2b(row[1])) + except: + h.update(b(row[1])) + # The real test + verifier = PKCS.new(key) + self.failIf(verifier.can_sign()) + result = verifier.verify(h, t2b(row[2])) + self.failUnless(result) + + def testSignVerify(self): + rng = Random.new().read + key = RSA.generate(1024, rng) + + for hashmod in (MD2,MD5,SHA,SHA224,SHA256,SHA384,SHA512,RIPEMD): + h = hashmod.new() + h.update(b('blah blah blah')) + + signer = PKCS.new(key) + s = signer.sign(h) + result = signer.verify(h, s) + self.failUnless(result) + + +def get_tests(config={}): + tests = [] + tests += list_test_cases(PKCS1_15_Tests) + return tests + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Signature/test_pkcs1_15.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Signature/test_pkcs1_15.pyo new file mode 100644 index 0000000000000000000000000000000000000000..fa2ce2ce4c7826ec9a697582745677466f378cc3 GIT binary patch literal 7964 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 XEh_Vkxl401bF;Vq;mY(CWls5Tuxn(P literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Signature/test_pkcs1_pss.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Signature/test_pkcs1_pss.py new file mode 100644 index 00000000..f5256a51 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Signature/test_pkcs1_pss.py @@ -0,0 +1,446 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Signature/test_pkcs1_pss.py: Self-test for PKCS#1 PSS signatures +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +from __future__ import nested_scopes + +__revision__ = "$Id$" + +import unittest + +from Crypto.PublicKey import RSA +from Crypto import Random +from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex +from Crypto.Hash import * +from Crypto.Signature import PKCS1_PSS as PKCS +from Crypto.Util.py3compat import * + +def isStr(s): + t = '' + try: + t += s + except TypeError: + return 0 + return 1 + +def rws(t): + """Remove white spaces, tabs, and new lines from a string""" + for c in ['\t', '\n', ' ']: + t = t.replace(c,'') + return t + +def t2b(t): + """Convert a text string with bytes in hex form to a byte string""" + clean = b(rws(t)) + if len(clean)%2 == 1: + raise ValueError("Even number of characters expected") + return a2b_hex(clean) + +# Helper class to count how many bytes have been requested +# from the key's private RNG, w/o counting those used for blinding +class MyKey: + def __init__(self, key): + self._key = key + self.n = key.n + self.asked = 0 + def _randfunc(self, N): + self.asked += N + return self._key._randfunc(N) + def sign(self, m): + return self._key.sign(m) + def has_private(self): + return self._key.has_private() + def decrypt(self, m): + return self._key.decrypt(m) + def verify(self, m, p): + return self._key.verify(m, p) + def encrypt(self, m, p): + return self._key.encrypt(m, p) + +class PKCS1_PSS_Tests(unittest.TestCase): + + # List of tuples with test data for PKCS#1 PSS + # Each tuple is made up by: + # Item #0: dictionary with RSA key component, or key to import + # Item #1: data to hash and sign + # Item #2: signature of the data #1, done with the key #0, + # and salt #3 after hashing it with #4 + # Item #3: salt + # Item #4: hash object generator + + _testData = ( + + # + # From in pss-vect.txt to be found in + # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip + # + ( + # Private key + { + 'n':'''a2 ba 40 ee 07 e3 b2 bd 2f 02 ce 22 7f 36 a1 95 + 02 44 86 e4 9c 19 cb 41 bb bd fb ba 98 b2 2b 0e + 57 7c 2e ea ff a2 0d 88 3a 76 e6 5e 39 4c 69 d4 + b3 c0 5a 1e 8f ad da 27 ed b2 a4 2b c0 00 fe 88 + 8b 9b 32 c2 2d 15 ad d0 cd 76 b3 e7 93 6e 19 95 + 5b 22 0d d1 7d 4e a9 04 b1 ec 10 2b 2e 4d e7 75 + 12 22 aa 99 15 10 24 c7 cb 41 cc 5e a2 1d 00 ee + b4 1f 7c 80 08 34 d2 c6 e0 6b ce 3b ce 7e a9 a5''', + 'e':'''01 00 01''', + # In the test vector, only p and q were given... + # d is computed offline as e^{-1} mod (p-1)(q-1) + 'd':'''50e2c3e38d886110288dfc68a9533e7e12e27d2aa56 + d2cdb3fb6efa990bcff29e1d2987fb711962860e7391b1ce01 + ebadb9e812d2fbdfaf25df4ae26110a6d7a26f0b810f54875e + 17dd5c9fb6d641761245b81e79f8c88f0e55a6dcd5f133abd3 + 5f8f4ec80adf1bf86277a582894cb6ebcd2162f1c7534f1f49 + 47b129151b71''' + }, + + # Data to sign + '''85 9e ef 2f d7 8a ca 00 30 8b dc 47 11 93 bf 55 + bf 9d 78 db 8f 8a 67 2b 48 46 34 f3 c9 c2 6e 64 + 78 ae 10 26 0f e0 dd 8c 08 2e 53 a5 29 3a f2 17 + 3c d5 0c 6d 5d 35 4f eb f7 8b 26 02 1c 25 c0 27 + 12 e7 8c d4 69 4c 9f 46 97 77 e4 51 e7 f8 e9 e0 + 4c d3 73 9c 6b bf ed ae 48 7f b5 56 44 e9 ca 74 + ff 77 a5 3c b7 29 80 2f 6e d4 a5 ff a8 ba 15 98 + 90 fc''', + # Signature + '''8d aa 62 7d 3d e7 59 5d 63 05 6c 7e c6 59 e5 44 + 06 f1 06 10 12 8b aa e8 21 c8 b2 a0 f3 93 6d 54 + dc 3b dc e4 66 89 f6 b7 95 1b b1 8e 84 05 42 76 + 97 18 d5 71 5d 21 0d 85 ef bb 59 61 92 03 2c 42 + be 4c 29 97 2c 85 62 75 eb 6d 5a 45 f0 5f 51 87 + 6f c6 74 3d ed dd 28 ca ec 9b b3 0e a9 9e 02 c3 + 48 82 69 60 4f e4 97 f7 4c cd 7c 7f ca 16 71 89 + 71 23 cb d3 0d ef 5d 54 a2 b5 53 6a d9 0a 74 7e''', + # Salt + '''e3 b5 d5 d0 02 c1 bc e5 0c 2b 65 ef 88 a1 88 d8 + 3b ce 7e 61''', + # Hash algorithm + SHA + ), + + # + # Example 1.1 to be found in + # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip + # + ( + # Private key + { + 'n':'''a5 6e 4a 0e 70 10 17 58 9a 51 87 dc 7e a8 41 d1 + 56 f2 ec 0e 36 ad 52 a4 4d fe b1 e6 1f 7a d9 91 + d8 c5 10 56 ff ed b1 62 b4 c0 f2 83 a1 2a 88 a3 + 94 df f5 26 ab 72 91 cb b3 07 ce ab fc e0 b1 df + d5 cd 95 08 09 6d 5b 2b 8b 6d f5 d6 71 ef 63 77 + c0 92 1c b2 3c 27 0a 70 e2 59 8e 6f f8 9d 19 f1 + 05 ac c2 d3 f0 cb 35 f2 92 80 e1 38 6b 6f 64 c4 + ef 22 e1 e1 f2 0d 0c e8 cf fb 22 49 bd 9a 21 37''', + 'e':'''01 00 01''', + 'd':'''33 a5 04 2a 90 b2 7d 4f 54 51 ca 9b bb d0 b4 47 + 71 a1 01 af 88 43 40 ae f9 88 5f 2a 4b be 92 e8 + 94 a7 24 ac 3c 56 8c 8f 97 85 3a d0 7c 02 66 c8 + c6 a3 ca 09 29 f1 e8 f1 12 31 88 44 29 fc 4d 9a + e5 5f ee 89 6a 10 ce 70 7c 3e d7 e7 34 e4 47 27 + a3 95 74 50 1a 53 26 83 10 9c 2a ba ca ba 28 3c + 31 b4 bd 2f 53 c3 ee 37 e3 52 ce e3 4f 9e 50 3b + d8 0c 06 22 ad 79 c6 dc ee 88 35 47 c6 a3 b3 25''' + }, + # Message + '''cd c8 7d a2 23 d7 86 df 3b 45 e0 bb bc 72 13 26 + d1 ee 2a f8 06 cc 31 54 75 cc 6f 0d 9c 66 e1 b6 + 23 71 d4 5c e2 39 2e 1a c9 28 44 c3 10 10 2f 15 + 6a 0d 8d 52 c1 f4 c4 0b a3 aa 65 09 57 86 cb 76 + 97 57 a6 56 3b a9 58 fe d0 bc c9 84 e8 b5 17 a3 + d5 f5 15 b2 3b 8a 41 e7 4a a8 67 69 3f 90 df b0 + 61 a6 e8 6d fa ae e6 44 72 c0 0e 5f 20 94 57 29 + cb eb e7 7f 06 ce 78 e0 8f 40 98 fb a4 1f 9d 61 + 93 c0 31 7e 8b 60 d4 b6 08 4a cb 42 d2 9e 38 08 + a3 bc 37 2d 85 e3 31 17 0f cb f7 cc 72 d0 b7 1c + 29 66 48 b3 a4 d1 0f 41 62 95 d0 80 7a a6 25 ca + b2 74 4f d9 ea 8f d2 23 c4 25 37 02 98 28 bd 16 + be 02 54 6f 13 0f d2 e3 3b 93 6d 26 76 e0 8a ed + 1b 73 31 8b 75 0a 01 67 d0''', + # Signature + '''90 74 30 8f b5 98 e9 70 1b 22 94 38 8e 52 f9 71 + fa ac 2b 60 a5 14 5a f1 85 df 52 87 b5 ed 28 87 + e5 7c e7 fd 44 dc 86 34 e4 07 c8 e0 e4 36 0b c2 + 26 f3 ec 22 7f 9d 9e 54 63 8e 8d 31 f5 05 12 15 + df 6e bb 9c 2f 95 79 aa 77 59 8a 38 f9 14 b5 b9 + c1 bd 83 c4 e2 f9 f3 82 a0 d0 aa 35 42 ff ee 65 + 98 4a 60 1b c6 9e b2 8d eb 27 dc a1 2c 82 c2 d4 + c3 f6 6c d5 00 f1 ff 2b 99 4d 8a 4e 30 cb b3 3c''', + # Salt + '''de e9 59 c7 e0 64 11 36 14 20 ff 80 18 5e d5 7f + 3e 67 76 af''', + # Hash + SHA + ), + + # + # Example 1.2 to be found in + # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip + # + ( + # Private key + { + 'n':'''a5 6e 4a 0e 70 10 17 58 9a 51 87 dc 7e a8 41 d1 + 56 f2 ec 0e 36 ad 52 a4 4d fe b1 e6 1f 7a d9 91 + d8 c5 10 56 ff ed b1 62 b4 c0 f2 83 a1 2a 88 a3 + 94 df f5 26 ab 72 91 cb b3 07 ce ab fc e0 b1 df + d5 cd 95 08 09 6d 5b 2b 8b 6d f5 d6 71 ef 63 77 + c0 92 1c b2 3c 27 0a 70 e2 59 8e 6f f8 9d 19 f1 + 05 ac c2 d3 f0 cb 35 f2 92 80 e1 38 6b 6f 64 c4 + ef 22 e1 e1 f2 0d 0c e8 cf fb 22 49 bd 9a 21 37''', + 'e':'''01 00 01''', + 'd':'''33 a5 04 2a 90 b2 7d 4f 54 51 ca 9b bb d0 b4 47 + 71 a1 01 af 88 43 40 ae f9 88 5f 2a 4b be 92 e8 + 94 a7 24 ac 3c 56 8c 8f 97 85 3a d0 7c 02 66 c8 + c6 a3 ca 09 29 f1 e8 f1 12 31 88 44 29 fc 4d 9a + e5 5f ee 89 6a 10 ce 70 7c 3e d7 e7 34 e4 47 27 + a3 95 74 50 1a 53 26 83 10 9c 2a ba ca ba 28 3c + 31 b4 bd 2f 53 c3 ee 37 e3 52 ce e3 4f 9e 50 3b + d8 0c 06 22 ad 79 c6 dc ee 88 35 47 c6 a3 b3 25''' + }, + # Message + '''85 13 84 cd fe 81 9c 22 ed 6c 4c cb 30 da eb 5c + f0 59 bc 8e 11 66 b7 e3 53 0c 4c 23 3e 2b 5f 8f + 71 a1 cc a5 82 d4 3e cc 72 b1 bc a1 6d fc 70 13 + 22 6b 9e''', + # Signature + '''3e f7 f4 6e 83 1b f9 2b 32 27 41 42 a5 85 ff ce + fb dc a7 b3 2a e9 0d 10 fb 0f 0c 72 99 84 f0 4e + f2 9a 9d f0 78 07 75 ce 43 73 9b 97 83 83 90 db + 0a 55 05 e6 3d e9 27 02 8d 9d 29 b2 19 ca 2c 45 + 17 83 25 58 a5 5d 69 4a 6d 25 b9 da b6 60 03 c4 + cc cd 90 78 02 19 3b e5 17 0d 26 14 7d 37 b9 35 + 90 24 1b e5 1c 25 05 5f 47 ef 62 75 2c fb e2 14 + 18 fa fe 98 c2 2c 4d 4d 47 72 4f db 56 69 e8 43''', + # Salt + '''ef 28 69 fa 40 c3 46 cb 18 3d ab 3d 7b ff c9 8f + d5 6d f4 2d''', + # Hash + SHA + ), + + # + # Example 2.1 to be found in + # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip + # + ( + # Private key + { + 'n':'''01 d4 0c 1b cf 97 a6 8a e7 cd bd 8a 7b f3 e3 4f + a1 9d cc a4 ef 75 a4 74 54 37 5f 94 51 4d 88 fe + d0 06 fb 82 9f 84 19 ff 87 d6 31 5d a6 8a 1f f3 + a0 93 8e 9a bb 34 64 01 1c 30 3a d9 91 99 cf 0c + 7c 7a 8b 47 7d ce 82 9e 88 44 f6 25 b1 15 e5 e9 + c4 a5 9c f8 f8 11 3b 68 34 33 6a 2f d2 68 9b 47 + 2c bb 5e 5c ab e6 74 35 0c 59 b6 c1 7e 17 68 74 + fb 42 f8 fc 3d 17 6a 01 7e dc 61 fd 32 6c 4b 33 + c9''', + 'e':'''01 00 01''', + 'd':'''02 7d 14 7e 46 73 05 73 77 fd 1e a2 01 56 57 72 + 17 6a 7d c3 83 58 d3 76 04 56 85 a2 e7 87 c2 3c + 15 57 6b c1 6b 9f 44 44 02 d6 bf c5 d9 8a 3e 88 + ea 13 ef 67 c3 53 ec a0 c0 dd ba 92 55 bd 7b 8b + b5 0a 64 4a fd fd 1d d5 16 95 b2 52 d2 2e 73 18 + d1 b6 68 7a 1c 10 ff 75 54 5f 3d b0 fe 60 2d 5f + 2b 7f 29 4e 36 01 ea b7 b9 d1 ce cd 76 7f 64 69 + 2e 3e 53 6c a2 84 6c b0 c2 dd 48 6a 39 fa 75 b1''' + }, + # Message + '''da ba 03 20 66 26 3f ae db 65 98 48 11 52 78 a5 + 2c 44 fa a3 a7 6f 37 51 5e d3 36 32 10 72 c4 0a + 9d 9b 53 bc 05 01 40 78 ad f5 20 87 51 46 aa e7 + 0f f0 60 22 6d cb 7b 1f 1f c2 7e 93 60''', + # Signature + '''01 4c 5b a5 33 83 28 cc c6 e7 a9 0b f1 c0 ab 3f + d6 06 ff 47 96 d3 c1 2e 4b 63 9e d9 13 6a 5f ec + 6c 16 d8 88 4b dd 99 cf dc 52 14 56 b0 74 2b 73 + 68 68 cf 90 de 09 9a db 8d 5f fd 1d ef f3 9b a4 + 00 7a b7 46 ce fd b2 2d 7d f0 e2 25 f5 46 27 dc + 65 46 61 31 72 1b 90 af 44 53 63 a8 35 8b 9f 60 + 76 42 f7 8f ab 0a b0 f4 3b 71 68 d6 4b ae 70 d8 + 82 78 48 d8 ef 1e 42 1c 57 54 dd f4 2c 25 89 b5 + b3''', + # Salt + '''57 bf 16 0b cb 02 bb 1d c7 28 0c f0 45 85 30 b7 + d2 83 2f f7''', + SHA + ), + + # + # Example 8.1 to be found in + # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip + # + ( + # Private key + { + 'n':'''49 53 70 a1 fb 18 54 3c 16 d3 63 1e 31 63 25 5d + f6 2b e6 ee e8 90 d5 f2 55 09 e4 f7 78 a8 ea 6f + bb bc df 85 df f6 4e 0d 97 20 03 ab 36 81 fb ba + 6d d4 1f d5 41 82 9b 2e 58 2d e9 f2 a4 a4 e0 a2 + d0 90 0b ef 47 53 db 3c ee 0e e0 6c 7d fa e8 b1 + d5 3b 59 53 21 8f 9c ce ea 69 5b 08 66 8e de aa + dc ed 94 63 b1 d7 90 d5 eb f2 7e 91 15 b4 6c ad + 4d 9a 2b 8e fa b0 56 1b 08 10 34 47 39 ad a0 73 + 3f''', + 'e':'''01 00 01''', + 'd':'''6c 66 ff e9 89 80 c3 8f cd ea b5 15 98 98 83 61 + 65 f4 b4 b8 17 c4 f6 a8 d4 86 ee 4e a9 13 0f e9 + b9 09 2b d1 36 d1 84 f9 5f 50 4a 60 7e ac 56 58 + 46 d2 fd d6 59 7a 89 67 c7 39 6e f9 5a 6e ee bb + 45 78 a6 43 96 6d ca 4d 8e e3 de 84 2d e6 32 79 + c6 18 15 9c 1a b5 4a 89 43 7b 6a 61 20 e4 93 0a + fb 52 a4 ba 6c ed 8a 49 47 ac 64 b3 0a 34 97 cb + e7 01 c2 d6 26 6d 51 72 19 ad 0e c6 d3 47 db e9''' + }, + # Message + '''81 33 2f 4b e6 29 48 41 5e a1 d8 99 79 2e ea cf + 6c 6e 1d b1 da 8b e1 3b 5c ea 41 db 2f ed 46 70 + 92 e1 ff 39 89 14 c7 14 25 97 75 f5 95 f8 54 7f + 73 56 92 a5 75 e6 92 3a f7 8f 22 c6 99 7d db 90 + fb 6f 72 d7 bb 0d d5 74 4a 31 de cd 3d c3 68 58 + 49 83 6e d3 4a ec 59 63 04 ad 11 84 3c 4f 88 48 + 9f 20 97 35 f5 fb 7f da f7 ce c8 ad dc 58 18 16 + 8f 88 0a cb f4 90 d5 10 05 b7 a8 e8 4e 43 e5 42 + 87 97 75 71 dd 99 ee a4 b1 61 eb 2d f1 f5 10 8f + 12 a4 14 2a 83 32 2e db 05 a7 54 87 a3 43 5c 9a + 78 ce 53 ed 93 bc 55 08 57 d7 a9 fb''', + # Signature + '''02 62 ac 25 4b fa 77 f3 c1 ac a2 2c 51 79 f8 f0 + 40 42 2b 3c 5b af d4 0a 8f 21 cf 0f a5 a6 67 cc + d5 99 3d 42 db af b4 09 c5 20 e2 5f ce 2b 1e e1 + e7 16 57 7f 1e fa 17 f3 da 28 05 2f 40 f0 41 9b + 23 10 6d 78 45 aa f0 11 25 b6 98 e7 a4 df e9 2d + 39 67 bb 00 c4 d0 d3 5b a3 55 2a b9 a8 b3 ee f0 + 7c 7f ec db c5 42 4a c4 db 1e 20 cb 37 d0 b2 74 + 47 69 94 0e a9 07 e1 7f bb ca 67 3b 20 52 23 80 + c5''', + # Salt + '''1d 65 49 1d 79 c8 64 b3 73 00 9b e6 f6 f2 46 7b + ac 4c 78 fa''', + SHA + ) + ) + + def testSign1(self): + for i in range(len(self._testData)): + # Build the key + comps = [ long(rws(self._testData[i][0][x]),16) for x in ('n','e','d') ] + key = MyKey(RSA.construct(comps)) + # Hash function + h = self._testData[i][4].new() + # Data to sign + h.update(t2b(self._testData[i][1])) + # Salt + test_salt = t2b(self._testData[i][3]) + key._randfunc = lambda N: test_salt + # The real test + signer = PKCS.new(key) + self.failUnless(signer.can_sign()) + s = signer.sign(h) + self.assertEqual(s, t2b(self._testData[i][2])) + + def testVerify1(self): + for i in range(len(self._testData)): + # Build the key + comps = [ long(rws(self._testData[i][0][x]),16) for x in ('n','e') ] + key = MyKey(RSA.construct(comps)) + # Hash function + h = self._testData[i][4].new() + # Data to sign + h.update(t2b(self._testData[i][1])) + # Salt + test_salt = t2b(self._testData[i][3]) + # The real test + key._randfunc = lambda N: test_salt + verifier = PKCS.new(key) + self.failIf(verifier.can_sign()) + result = verifier.verify(h, t2b(self._testData[i][2])) + self.failUnless(result) + + def testSignVerify(self): + h = SHA.new() + h.update(b('blah blah blah')) + + rng = Random.new().read + key = MyKey(RSA.generate(1024,rng)) + + # Helper function to monitor what's request from MGF + global mgfcalls + def newMGF(seed,maskLen): + global mgfcalls + mgfcalls += 1 + return bchr(0x00)*maskLen + + # Verify that PSS is friendly to all ciphers + for hashmod in (MD2,MD5,SHA,SHA224,SHA256,SHA384,RIPEMD): + h = hashmod.new() + h.update(b('blah blah blah')) + + # Verify that sign() asks for as many random bytes + # as the hash output size + key.asked = 0 + signer = PKCS.new(key) + s = signer.sign(h) + self.failUnless(signer.verify(h, s)) + self.assertEqual(key.asked, h.digest_size) + + h = SHA.new() + h.update(b('blah blah blah')) + + # Verify that sign() uses a different salt length + for sLen in (0,3,21): + key.asked = 0 + signer = PKCS.new(key, saltLen=sLen) + s = signer.sign(h) + self.assertEqual(key.asked, sLen) + self.failUnless(signer.verify(h, s)) + + # Verify that sign() uses the custom MGF + mgfcalls = 0 + signer = PKCS.new(key, newMGF) + s = signer.sign(h) + self.assertEqual(mgfcalls, 1) + self.failUnless(signer.verify(h, s)) + + # Verify that sign() does not call the RNG + # when salt length is 0, even when a new MGF is provided + key.asked = 0 + mgfcalls = 0 + signer = PKCS.new(key, newMGF, 0) + s = signer.sign(h) + self.assertEqual(key.asked,0) + self.assertEqual(mgfcalls, 1) + self.failUnless(signer.verify(h, s)) + +def get_tests(config={}): + tests = [] + tests += list_test_cases(PKCS1_PSS_Tests) + return tests + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Signature/test_pkcs1_pss.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Signature/test_pkcs1_pss.pyo new file mode 100644 index 0000000000000000000000000000000000000000..a28874928a67e0702643f00c37632f82c762bbeb GIT binary patch literal 17009 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 +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test for utility modules""" + +__revision__ = "$Id$" + +import os + +def get_tests(config={}): + tests = [] + if os.name == 'nt': + from Crypto.SelfTest.Util import test_winrandom; tests += test_winrandom.get_tests(config=config) + from Crypto.SelfTest.Util import test_number; tests += test_number.get_tests(config=config) + from Crypto.SelfTest.Util import test_Counter; tests += test_Counter.get_tests(config=config) + return tests + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Util/__init__.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Util/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..8e8b3df3eadc0ca14e757acc152766c41ca836ce GIT binary patch literal 1109 zcmcIjO^Xvj5UrlC&1!TP5n&Hv4tp363CbQsks!p2B0(k!5(b({x)VD)A7Q#?mq2pb zJ@23O2WVA~afQ9=F!iRV=2h3LsviHxgM0N&n#|$%<?MS)LM1biU}L zw%A)#b+18_8{G7YN;SE*HXz372X$(G(lwq7dJW0gJtDI=1WSOO00dZ(PT|B1_hLLK zeAsy)wgR>utVnJETVN@#D2UZiWg%Bqgs}5lqJM|TtjMt<*aa;sxWl3(llXunjnN}4 z(aDZkH9lmZGUcTy>#S5&ff2dpRk<+BmU4ejDVt)Z>(<%bJ4aPhB6)d#w|!-i`%q?u z#>cc6)tfa|18(RSN;LRNy-ZwgZuU~62{dV`q3ek2&Z zNk5bJ?CgF2<>2+;MY`VL_o_@knOSNL>i#;LpJz*L(^gEn7n8D>R7z7Clyb1%BpurB z8Sndu07N8?#4((ZJ#mKoUCJUerIdfpCu?!zEc$HpcO^&R__1v@(cg~ literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_Counter.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_Counter.py new file mode 100644 index 00000000..33c9bd7d --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_Counter.py @@ -0,0 +1,165 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Util/test_Counter: Self-test for the Crypto.Util.Counter module +# +# Written in 2009 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-tests for Crypto.Util.Counter""" + +__revision__ = "$Id$" + +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * +from Crypto.Util.py3compat import * + +import unittest + +class CounterTests(unittest.TestCase): + def setUp(self): + global Counter + from Crypto.Util import Counter + + def test_BE_shortcut(self): + """Big endian, shortcut enabled""" + c = Counter.new(128) + self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_ + c = Counter.new(128, little_endian=False) + self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_ + c = Counter.new(128, disable_shortcut=False) + self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_ + c = Counter.new(128, little_endian=False, disable_shortcut=False) + self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_ + + def test_LE_shortcut(self): + """Little endian, shortcut enabled""" + c = Counter.new(128, little_endian=True) + self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_ + c = Counter.new(128, little_endian=True, disable_shortcut=False) + self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_ + + def test_BE_no_shortcut(self): + """Big endian, shortcut disabled""" + c = Counter.new(128, disable_shortcut=True) + self.assertRaises(AttributeError, getattr, c, '__PCT_CTR_SHORTCUT__') + c = Counter.new(128, little_endian=False, disable_shortcut=True) + self.assertRaises(AttributeError, getattr, c, '__PCT_CTR_SHORTCUT__') + + def test_LE_no_shortcut(self): + """Little endian, shortcut disabled""" + c = Counter.new(128, little_endian=True, disable_shortcut=True) + self.assertRaises(AttributeError, getattr, c, '__PCT_CTR_SHORTCUT__') + + def test_BE_defaults(self): + """128-bit, Big endian, defaults""" + c = Counter.new(128) + self.assertEqual(1, c.next_value()) + self.assertEqual(b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"), c()) + self.assertEqual(2, c.next_value()) + self.assertEqual(b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"), c()) + for i in xrange(3, 256): + self.assertEqual(i, c.next_value()) + self.assertEqual(b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")+bchr(i), c()) + self.assertEqual(256, c.next_value()) + self.assertEqual(b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00"), c()) + + def test_LE_defaults(self): + """128-bit, Little endian, defaults""" + c = Counter.new(128, little_endian=True) + self.assertEqual(1, c.next_value()) + self.assertEqual(b("\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), c()) + self.assertEqual(2, c.next_value()) + self.assertEqual(b("\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), c()) + for i in xrange(3, 256): + self.assertEqual(i, c.next_value()) + self.assertEqual(bchr(i)+b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), c()) + self.assertEqual(256, c.next_value()) + self.assertEqual(b("\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), c()) + + def test_BE8_wraparound(self): + """8-bit, Big endian, wraparound""" + c = Counter.new(8) + for i in xrange(1, 256): + self.assertEqual(i, c.next_value()) + self.assertEqual(bchr(i), c()) + self.assertRaises(OverflowError, c.next_value) + self.assertRaises(OverflowError, c) + self.assertRaises(OverflowError, c.next_value) + self.assertRaises(OverflowError, c) + + def test_LE8_wraparound(self): + """8-bit, Little endian, wraparound""" + c = Counter.new(8, little_endian=True) + for i in xrange(1, 256): + self.assertEqual(i, c.next_value()) + self.assertEqual(bchr(i), c()) + self.assertRaises(OverflowError, c.next_value) + self.assertRaises(OverflowError, c) + self.assertRaises(OverflowError, c.next_value) + self.assertRaises(OverflowError, c) + + def test_BE8_wraparound_allowed(self): + """8-bit, Big endian, wraparound with allow_wraparound=True""" + c = Counter.new(8, allow_wraparound=True) + for i in xrange(1, 256): + self.assertEqual(i, c.next_value()) + self.assertEqual(bchr(i), c()) + self.assertEqual(0, c.next_value()) + self.assertEqual(b("\x00"), c()) + self.assertEqual(1, c.next_value()) + + def test_LE8_wraparound_allowed(self): + """8-bit, Little endian, wraparound with allow_wraparound=True""" + c = Counter.new(8, little_endian=True, allow_wraparound=True) + for i in xrange(1, 256): + self.assertEqual(i, c.next_value()) + self.assertEqual(bchr(i), c()) + self.assertEqual(0, c.next_value()) + self.assertEqual(b("\x00"), c()) + self.assertEqual(1, c.next_value()) + + def test_BE8_carry(self): + """8-bit, Big endian, carry attribute""" + c = Counter.new(8) + for i in xrange(1, 256): + self.assertEqual(0, c.carry) + self.assertEqual(i, c.next_value()) + self.assertEqual(bchr(i), c()) + self.assertEqual(1, c.carry) + + def test_LE8_carry(self): + """8-bit, Little endian, carry attribute""" + c = Counter.new(8, little_endian=True) + for i in xrange(1, 256): + self.assertEqual(0, c.carry) + self.assertEqual(i, c.next_value()) + self.assertEqual(bchr(i), c()) + self.assertEqual(1, c.carry) + +def get_tests(config={}): + from Crypto.SelfTest.st_common import list_test_cases + return list_test_cases(CounterTests) + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_Counter.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_Counter.pyo new file mode 100644 index 0000000000000000000000000000000000000000..5b2762b37f0cb61c2adb280b3ab0ed3adc00c739 GIT binary patch literal 7358 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 +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-tests for (some of) Crypto.Util.number""" + +__revision__ = "$Id$" + +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * + +import unittest + +# NB: In some places, we compare tuples instead of just output values so that +# if any inputs cause a test failure, we'll be able to tell which ones. + +class MiscTests(unittest.TestCase): + def setUp(self): + global number, math + from Crypto.Util import number + import math + + def test_ceil_shift(self): + """Util.number.ceil_shift""" + self.assertRaises(AssertionError, number.ceil_shift, -1, 1) + self.assertRaises(AssertionError, number.ceil_shift, 1, -1) + + # b = 0 + self.assertEqual(0, number.ceil_shift(0, 0)) + self.assertEqual(1, number.ceil_shift(1, 0)) + self.assertEqual(2, number.ceil_shift(2, 0)) + self.assertEqual(3, number.ceil_shift(3, 0)) + + # b = 1 + self.assertEqual(0, number.ceil_shift(0, 1)) + self.assertEqual(1, number.ceil_shift(1, 1)) + self.assertEqual(1, number.ceil_shift(2, 1)) + self.assertEqual(2, number.ceil_shift(3, 1)) + + # b = 2 + self.assertEqual(0, number.ceil_shift(0, 2)) + self.assertEqual(1, number.ceil_shift(1, 2)) + self.assertEqual(1, number.ceil_shift(2, 2)) + self.assertEqual(1, number.ceil_shift(3, 2)) + self.assertEqual(1, number.ceil_shift(4, 2)) + self.assertEqual(2, number.ceil_shift(5, 2)) + self.assertEqual(2, number.ceil_shift(6, 2)) + self.assertEqual(2, number.ceil_shift(7, 2)) + self.assertEqual(2, number.ceil_shift(8, 2)) + self.assertEqual(3, number.ceil_shift(9, 2)) + + for b in range(3, 1+129, 3): # 3, 6, ... , 129 + self.assertEqual(0, number.ceil_shift(0, b)) + + n = 1L + while n <= 2L**(b+2): + (q, r) = divmod(n-1, 2L**b) + expected = q + int(not not r) + self.assertEqual((n-1, b, expected), + (n-1, b, number.ceil_shift(n-1, b))) + + (q, r) = divmod(n, 2L**b) + expected = q + int(not not r) + self.assertEqual((n, b, expected), + (n, b, number.ceil_shift(n, b))) + + (q, r) = divmod(n+1, 2L**b) + expected = q + int(not not r) + self.assertEqual((n+1, b, expected), + (n+1, b, number.ceil_shift(n+1, b))) + + n *= 2 + + def test_ceil_div(self): + """Util.number.ceil_div""" + self.assertRaises(TypeError, number.ceil_div, "1", 1) + self.assertRaises(ZeroDivisionError, number.ceil_div, 1, 0) + self.assertRaises(ZeroDivisionError, number.ceil_div, -1, 0) + + # b = -1 + self.assertEqual(0, number.ceil_div(0, -1)) + self.assertEqual(-1, number.ceil_div(1, -1)) + self.assertEqual(-2, number.ceil_div(2, -1)) + self.assertEqual(-3, number.ceil_div(3, -1)) + + # b = 1 + self.assertEqual(0, number.ceil_div(0, 1)) + self.assertEqual(1, number.ceil_div(1, 1)) + self.assertEqual(2, number.ceil_div(2, 1)) + self.assertEqual(3, number.ceil_div(3, 1)) + + # b = 2 + self.assertEqual(0, number.ceil_div(0, 2)) + self.assertEqual(1, number.ceil_div(1, 2)) + self.assertEqual(1, number.ceil_div(2, 2)) + self.assertEqual(2, number.ceil_div(3, 2)) + self.assertEqual(2, number.ceil_div(4, 2)) + self.assertEqual(3, number.ceil_div(5, 2)) + + # b = 3 + self.assertEqual(0, number.ceil_div(0, 3)) + self.assertEqual(1, number.ceil_div(1, 3)) + self.assertEqual(1, number.ceil_div(2, 3)) + self.assertEqual(1, number.ceil_div(3, 3)) + self.assertEqual(2, number.ceil_div(4, 3)) + self.assertEqual(2, number.ceil_div(5, 3)) + self.assertEqual(2, number.ceil_div(6, 3)) + self.assertEqual(3, number.ceil_div(7, 3)) + + # b = 4 + self.assertEqual(0, number.ceil_div(0, 4)) + self.assertEqual(1, number.ceil_div(1, 4)) + self.assertEqual(1, number.ceil_div(2, 4)) + self.assertEqual(1, number.ceil_div(3, 4)) + self.assertEqual(1, number.ceil_div(4, 4)) + self.assertEqual(2, number.ceil_div(5, 4)) + self.assertEqual(2, number.ceil_div(6, 4)) + self.assertEqual(2, number.ceil_div(7, 4)) + self.assertEqual(2, number.ceil_div(8, 4)) + self.assertEqual(3, number.ceil_div(9, 4)) + + # b = -4 + self.assertEqual(3, number.ceil_div(-9, -4)) + self.assertEqual(2, number.ceil_div(-8, -4)) + self.assertEqual(2, number.ceil_div(-7, -4)) + self.assertEqual(2, number.ceil_div(-6, -4)) + self.assertEqual(2, number.ceil_div(-5, -4)) + self.assertEqual(1, number.ceil_div(-4, -4)) + self.assertEqual(1, number.ceil_div(-3, -4)) + self.assertEqual(1, number.ceil_div(-2, -4)) + self.assertEqual(1, number.ceil_div(-1, -4)) + self.assertEqual(0, number.ceil_div(0, -4)) + self.assertEqual(0, number.ceil_div(1, -4)) + self.assertEqual(0, number.ceil_div(2, -4)) + self.assertEqual(0, number.ceil_div(3, -4)) + self.assertEqual(-1, number.ceil_div(4, -4)) + self.assertEqual(-1, number.ceil_div(5, -4)) + self.assertEqual(-1, number.ceil_div(6, -4)) + self.assertEqual(-1, number.ceil_div(7, -4)) + self.assertEqual(-2, number.ceil_div(8, -4)) + self.assertEqual(-2, number.ceil_div(9, -4)) + + def test_exact_log2(self): + """Util.number.exact_log2""" + self.assertRaises(TypeError, number.exact_log2, "0") + self.assertRaises(ValueError, number.exact_log2, -1) + self.assertRaises(ValueError, number.exact_log2, 0) + self.assertEqual(0, number.exact_log2(1)) + self.assertEqual(1, number.exact_log2(2)) + self.assertRaises(ValueError, number.exact_log2, 3) + self.assertEqual(2, number.exact_log2(4)) + self.assertRaises(ValueError, number.exact_log2, 5) + self.assertRaises(ValueError, number.exact_log2, 6) + self.assertRaises(ValueError, number.exact_log2, 7) + e = 3 + n = 8 + while e < 16: + if n == 2**e: + self.assertEqual(e, number.exact_log2(n), "expected=2**%d, n=%d" % (e, n)) + e += 1 + else: + self.assertRaises(ValueError, number.exact_log2, n) + n += 1 + + for e in range(16, 1+64, 2): + self.assertRaises(ValueError, number.exact_log2, 2L**e-1) + self.assertEqual(e, number.exact_log2(2L**e)) + self.assertRaises(ValueError, number.exact_log2, 2L**e+1) + + def test_exact_div(self): + """Util.number.exact_div""" + + # Positive numbers + self.assertEqual(1, number.exact_div(1, 1)) + self.assertRaises(ValueError, number.exact_div, 1, 2) + self.assertEqual(1, number.exact_div(2, 2)) + self.assertRaises(ValueError, number.exact_div, 3, 2) + self.assertEqual(2, number.exact_div(4, 2)) + + # Negative numbers + self.assertEqual(-1, number.exact_div(-1, 1)) + self.assertEqual(-1, number.exact_div(1, -1)) + self.assertRaises(ValueError, number.exact_div, -1, 2) + self.assertEqual(1, number.exact_div(-2, -2)) + self.assertEqual(-2, number.exact_div(-4, 2)) + + # Zero dividend + self.assertEqual(0, number.exact_div(0, 1)) + self.assertEqual(0, number.exact_div(0, 2)) + + # Zero divisor (allow_divzero == False) + self.assertRaises(ZeroDivisionError, number.exact_div, 0, 0) + self.assertRaises(ZeroDivisionError, number.exact_div, 1, 0) + + # Zero divisor (allow_divzero == True) + self.assertEqual(0, number.exact_div(0, 0, allow_divzero=True)) + self.assertRaises(ValueError, number.exact_div, 1, 0, allow_divzero=True) + + def test_floor_div(self): + """Util.number.floor_div""" + self.assertRaises(TypeError, number.floor_div, "1", 1) + for a in range(-10, 10): + for b in range(-10, 10): + if b == 0: + self.assertRaises(ZeroDivisionError, number.floor_div, a, b) + else: + self.assertEqual((a, b, int(math.floor(float(a) / b))), + (a, b, number.floor_div(a, b))) + + def test_getStrongPrime(self): + """Util.number.getStrongPrime""" + self.assertRaises(ValueError, number.getStrongPrime, 256) + self.assertRaises(ValueError, number.getStrongPrime, 513) + bits = 512 + x = number.getStrongPrime(bits) + self.assertNotEqual(x % 2, 0) + self.assertEqual(x > (1L << bits-1)-1, 1) + self.assertEqual(x < (1L << bits), 1) + e = 2**16+1 + x = number.getStrongPrime(bits, e) + self.assertEqual(number.GCD(x-1, e), 1) + self.assertNotEqual(x % 2, 0) + self.assertEqual(x > (1L << bits-1)-1, 1) + self.assertEqual(x < (1L << bits), 1) + e = 2**16+2 + x = number.getStrongPrime(bits, e) + self.assertEqual(number.GCD((x-1)>>1, e), 1) + self.assertNotEqual(x % 2, 0) + self.assertEqual(x > (1L << bits-1)-1, 1) + self.assertEqual(x < (1L << bits), 1) + + def test_isPrime(self): + """Util.number.isPrime""" + self.assertEqual(number.isPrime(-3), False) # Regression test: negative numbers should not be prime + self.assertEqual(number.isPrime(-2), False) # Regression test: negative numbers should not be prime + self.assertEqual(number.isPrime(1), False) # Regression test: isPrime(1) caused some versions of PyCrypto to crash. + self.assertEqual(number.isPrime(2), True) + self.assertEqual(number.isPrime(3), True) + self.assertEqual(number.isPrime(4), False) + self.assertEqual(number.isPrime(2L**1279-1), True) + self.assertEqual(number.isPrime(-(2L**1279-1)), False) # Regression test: negative numbers should not be prime + # test some known gmp pseudo-primes taken from + # http://www.trnicely.net/misc/mpzspsp.html + for composite in (43 * 127 * 211, 61 * 151 * 211, 15259 * 30517, + 346141L * 692281L, 1007119L * 2014237L, 3589477L * 7178953L, + 4859419L * 9718837L, 2730439L * 5460877L, + 245127919L * 490255837L, 963939391L * 1927878781L, + 4186358431L * 8372716861L, 1576820467L * 3153640933L): + self.assertEqual(number.isPrime(long(composite)), False) + + def test_size(self): + self.assertEqual(number.size(2),2) + self.assertEqual(number.size(3),2) + self.assertEqual(number.size(0xa2),8) + self.assertEqual(number.size(0xa2ba40),8*3) + self.assertEqual(number.size(0xa2ba40ee07e3b2bd2f02ce227f36a195024486e49c19cb41bbbdfbba98b22b0e577c2eeaffa20d883a76e65e394c69d4b3c05a1e8fadda27edb2a42bc000fe888b9b32c22d15add0cd76b3e7936e19955b220dd17d4ea904b1ec102b2e4de7751222aa99151024c7cb41cc5ea21d00eeb41f7c800834d2c6e06bce3bce7ea9a5L), 1024) + + def test_negative_number_roundtrip_mpzToLongObj_longObjToMPZ(self): + """Test that mpzToLongObj and longObjToMPZ (internal functions) roundtrip negative numbers correctly.""" + n = -100000000000000000000000000000000000L + e = 2L + k = number._fastmath.rsa_construct(n, e) + self.assertEqual(n, k.n) + self.assertEqual(e, k.e) + +def get_tests(config={}): + from Crypto.SelfTest.st_common import list_test_cases + return list_test_cases(MiscTests) + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_number.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_number.pyo new file mode 100644 index 0000000000000000000000000000000000000000..da11e6e0b61456c693f788afc3366caa1350a463 GIT binary patch literal 10867 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 TB+`jisfD*T^}N}dV)*_K;6xJm literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_winrandom.py b/panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_winrandom.py new file mode 100644 index 00000000..3fc5145a --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_winrandom.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/Util/test_winrandom.py: Self-test for the winrandom module +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test suite for Crypto.Util.winrandom""" + +__revision__ = "$Id$" + +import unittest + +class WinRandomImportTest(unittest.TestCase): + def runTest(self): + """winrandom: simple test""" + # Import the winrandom module and try to use it + from Crypto.Util import winrandom + randobj = winrandom.new() + x = randobj.get_bytes(16) + y = randobj.get_bytes(16) + self.assertNotEqual(x, y) + +def get_tests(config={}): + return [WinRandomImportTest()] + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_winrandom.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/Util/test_winrandom.pyo new file mode 100644 index 0000000000000000000000000000000000000000..ec80318801f48c2b0ca79121a96e4714ce91822b GIT binary patch literal 1464 zcmcgr&2AGx4EF4%Ng4tafslG4haSQq5r`8Nst|!gB^0U+2sK)1w8>1uru!2z6H27^ z)IJvv1rGq9osyOZC==P)@r*tGKHK51yN#d6KR%4y>OhOOh`cQxm>={w6=vOFw=JU+97`C91Z2b1k zOX&`Feew28)(uV~PTOj*Uuhw}Yd}%BqnheIer-nN>rh%3Np7|Fd_n8HG|LRzh_}}{ z-d>^+-k~QD7eG~&^a=CCB7MS{c$tE!LXFwp7cH*qa#mp+m&GKVUgvx}ymI4k3ozp{ zRFXHTD>CyWEwmovk}Sp~Ah^Q-Vy4JTf1{`WLfMpJS)`uBN}F-v20Wz^x7jtS+pB~i zc$Fpj$Rr0HJnA4M17YkWS!OcxUS^CFYcmznXIh(bj23Fbp!LFjOI=!mhDcD?VP!PE r#91ksAc}a +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self tests + +These tests should perform quickly and can ideally be used every time an +application runs. +""" + +__revision__ = "$Id$" + +import sys +import unittest +from StringIO import StringIO + +class SelfTestError(Exception): + def __init__(self, message, result): + Exception.__init__(self, message, result) + self.message = message + self.result = result + +def run(module=None, verbosity=0, stream=None, tests=None, config=None, **kwargs): + """Execute self-tests. + + This raises SelfTestError if any test is unsuccessful. + + You may optionally pass in a sub-module of SelfTest if you only want to + perform some of the tests. For example, the following would test only the + hash modules: + + Crypto.SelfTest.run(Crypto.SelfTest.Hash) + + """ + if config is None: + config = {} + suite = unittest.TestSuite() + if module is None: + if tests is None: + tests = get_tests(config=config) + suite.addTests(tests) + else: + if tests is None: + suite.addTests(module.get_tests(config=config)) + else: + raise ValueError("'module' and 'tests' arguments are mutually exclusive") + if stream is None: + kwargs['stream'] = StringIO() + runner = unittest.TextTestRunner(verbosity=verbosity, **kwargs) + result = runner.run(suite) + if not result.wasSuccessful(): + if stream is None: + sys.stderr.write(stream.getvalue()) + raise SelfTestError("Self-test failed", result) + return result + +def get_tests(config={}): + tests = [] + from Crypto.SelfTest import Cipher; tests += Cipher.get_tests(config=config) + from Crypto.SelfTest import Hash; tests += Hash.get_tests(config=config) + from Crypto.SelfTest import Protocol; tests += Protocol.get_tests(config=config) + from Crypto.SelfTest import PublicKey; tests += PublicKey.get_tests(config=config) + from Crypto.SelfTest import Random; tests += Random.get_tests(config=config) + from Crypto.SelfTest import Util; tests += Util.get_tests(config=config) + from Crypto.SelfTest import Signature; tests += Signature.get_tests(config=config) + return tests + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/__init__.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..189762de338882fd6f808119f30ab07bb7fb4dfc GIT binary patch literal 3030 zcmcImTW=dh6h7-)9LH@#Zvs?cD22L$SRihqswzYXqAG-H9gu1)ttPwUc%8kNo!KOo zoEOqpc;tb+TlMKy}*l+XZ(7VV!?tu(UGFHx5 zXFHvpiLs^{C_Bl^BvLa|jPoK@zm##fpUjocA{FXP#gWko#=Az9)}besiMqmzhfJ)b?ZTNEB*)HcF)7mwb{Na;%x815AMR!nH~7DRTOz~7E|W^ z3eCO(Vz4a)hh%>>@&}?StYe8Ao7qIOcR(D`)T0H_0<=aab@I4J6x4Xk9mEnoh>qj@W-6YRO-^IHl8#}Wx)8Rfe+tFq*pSgU*C&R%Qo!alu=04kc z56!ZD@~(KRUS*$S83dV54IJ&rAkCvP!BB*rdLz9T=n@~#yJ)rs((;g!L?H)&BgxTt zh-R;YZPDPY-fvTJjWhSSK}bjE(G+KcVT(^>$?!8Ra5NS3LvrZj;2NC5$90xkv}oF3 zo)eF}?2~7>Pfpix_|J$5Uzc2yD-MHSB_);?{vww2^$AR`xT* zXY0s>r8A22XhUkU-{~lPJCoR|LdVuvb($7ZBPt%F-cWeR69pdBS{a5&(Q%n9Wgq9I zO7&djlF(ALGi|MkGo_U+cQ>juQTg~xHEW$iEYDEkhdOi0<>JRF8rU3l4goh=!bM-H zZ}LK!Bc09?^MNdk^CZa+QQYcKphSEWl@Jqk6KyA|GH>rzJLTP0`QJa?XdejDdw%X) zh~BA0q!hzE8^?S0Q-tz%rSZ04)olqQ`o&(En#@`Bj7m#aN+irtn3Og?sOs6e!st{G z0C2XOqb%ok9V*!sIS@70ablwF-X+XR&2Q(K5tJx_5o}DvchDJ>sA?GjE&}mG7`ci4F@k z%zyyH2W-IS8trjC3U3u4e+^@wp+cm@LH~?r{}3UwvSMW;0(j!l%R{#-aOQn9%MeH1 zF3_zjf0w=WTGzXQ*7erCYu+W9ea*Yq}gQItC+#fc8ps>uH6Knje4zB;E$4& z+ZRv+F!_ARg&P=Lbpp7^6@gpx9ImEtH5j;rt8p$@OSqbJ+^o2o=W?wGSBp_kbOF!K zvDg-_6$1DO7XauSu2tb`GbRZaaOpWNpxB_tN4+igZ*~3hiEhTTi7DjRt4RiIF0N|C zN%W}5T^{C1HN&BPRPN$>e`w}U_4v5j^7N^SA6@*6z#!hsv?~i!bd-w?IUJxa+^pb0YTt5@37b*DyQ!J(^V@Y`+U|Z iV9FtS$s4S&@BSMwX|IB`YOM-YYS&w@-t4Y1=KKpPFP38f literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/st_common.py b/panda/python/Lib/site-packages/Crypto/SelfTest/st_common.py new file mode 100644 index 00000000..c56eac5f --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/SelfTest/st_common.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/st_common.py: Common functions for SelfTest modules +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Common functions for SelfTest modules""" + +__revision__ = "$Id$" + +import unittest +import binascii +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * +from Crypto.Util.py3compat import * + +class _list_testloader(unittest.TestLoader): + suiteClass = list + +def list_test_cases(class_): + """Return a list of TestCase instances given a TestCase class + + This is useful when you have defined test* methods on your TestCase class. + """ + return _list_testloader().loadTestsFromTestCase(class_) + +def strip_whitespace(s): + """Remove whitespace from a text or byte string""" + if isinstance(s,str): + return b("".join(s.split())) + else: + return b("").join(s.split()) + +def a2b_hex(s): + """Convert hexadecimal to binary, ignoring whitespace""" + return binascii.a2b_hex(strip_whitespace(s)) + +def b2a_hex(s): + """Convert binary to hexadecimal""" + # For completeness + return binascii.b2a_hex(s) + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/SelfTest/st_common.pyo b/panda/python/Lib/site-packages/Crypto/SelfTest/st_common.pyo new file mode 100644 index 0000000000000000000000000000000000000000..0a9148431f07f0fa4814045b41e57bb481886ad6 GIT binary patch literal 1972 zcmcIlUvC>l5TCnqoWzZ3DFTrPqhFtjOvsoU|K$-Nw(!XH0hA;&|;5NhmO@Ay-cYox1ugY-AfU_y-#(Q&MXdZ zH~Vy^4oIi8IG_rb9n$YaZ-`z@4oUTRGwG4K6`5P4jv{kJsvns?yEYztzgkIdVZeYs>e0r4owF!Du zOYhsap`*z8r{G3kPk)hC$wxmtcsP7A{A#+|gt@cRXJ$6_c=5qXmM`VG_R~?bSp_%U z20exIWkhAT+T`r>36|$@yGhA=Uc4P)d5$>51S}Hz4NL-f*~0$;lIyT;tdN4e7OoNu z>qvSnjP*g^n9=f8f(w^ZT><$FEp_MX0bvS z&e*`FepQ>WYmaMndXrFc1+tf`Vi(GgWt>AwZzsp;|MC0?Dg=d^1zK&{GIVX_o4g_FHn!pLT~`V+M2*4A&>6H^4$1niiAcxV=EUvfoVJXhQ9_= zW7wTO#N1oS5NE^Nsz;X^p2s{Wp2f)?CrQqC#_UG;b9Q={-N@Z!wexM?w0{WS9)tIv Xf^^evdX(_zi=?0Q(&OxKAD_;D2sqeT literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Signature/PKCS1_PSS.py b/panda/python/Lib/site-packages/Crypto/Signature/PKCS1_PSS.py new file mode 100644 index 00000000..4f50eb85 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Signature/PKCS1_PSS.py @@ -0,0 +1,355 @@ +# -*- coding: utf-8 -*- +# +# Signature/PKCS1_PSS.py : PKCS#1 PPS +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""RSA digital signature protocol with appendix according to PKCS#1 PSS. + +See RFC3447__ or the `original RSA Labs specification`__. + +This scheme is more properly called ``RSASSA-PSS``. + +For example, a sender may authenticate a message using SHA-1 and PSS like +this: + + >>> from Crypto.Signature import PKCS1_PSS + >>> from Crypto.Hash import SHA + >>> from Crypto.PublicKey import RSA + >>> from Crypto import Random + >>> + >>> message = 'To be signed' + >>> key = RSA.importKey(open('privkey.der').read()) + >>> h = SHA.new() + >>> h.update(message) + >>> signer = PKCS1_PSS.new(key) + >>> signature = PKCS1_PSS.sign(key) + +At the receiver side, verification can be done like using the public part of +the RSA key: + + >>> key = RSA.importKey(open('pubkey.der').read()) + >>> h = SHA.new() + >>> h.update(message) + >>> verifier = PKCS1_PSS.new(key) + >>> if verifier.verify(h, signature): + >>> print "The signature is authentic." + >>> else: + >>> print "The signature is not authentic." + +:undocumented: __revision__, __package__ + +.. __: http://www.ietf.org/rfc/rfc3447.txt +.. __: http://www.rsa.com/rsalabs/node.asp?id=2125 +""" + +# Allow nested scopes in Python 2.1 +# See http://oreilly.com/pub/a/python/2001/04/19/pythonnews.html +from __future__ import nested_scopes + +__revision__ = "$Id$" +__all__ = [ 'new', 'PSS_SigScheme' ] + +from Crypto.Util.py3compat import * +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * +import Crypto.Util.number +from Crypto.Util.number import ceil_shift, ceil_div, long_to_bytes +from Crypto.Util.strxor import strxor + +class PSS_SigScheme: + """This signature scheme can perform PKCS#1 PSS RSA signature or verification.""" + + def __init__(self, key, mgfunc, saltLen): + """Initialize this PKCS#1 PSS signature scheme object. + + :Parameters: + key : an RSA key object + If a private half is given, both signature and verification are possible. + If a public half is given, only verification is possible. + mgfunc : callable + A mask generation function that accepts two parameters: a string to + use as seed, and the lenth of the mask to generate, in bytes. + saltLen : int + Length of the salt, in bytes. + """ + self._key = key + self._saltLen = saltLen + self._mgfunc = mgfunc + + def can_sign(self): + """Return True if this cipher object can be used for signing messages.""" + return self._key.has_private() + + def sign(self, mhash): + """Produce the PKCS#1 PSS signature of a message. + + This function is named ``RSASSA-PSS-SIGN``, and is specified in + section 8.1.1 of RFC3447. + + :Parameters: + mhash : hash object + The hash that was carried out over the message. This is an object + belonging to the `Crypto.Hash` module. + + :Return: The PSS signature encoded as a string. + :Raise ValueError: + If the RSA key length is not sufficiently long to deal with the given + hash algorithm. + :Raise TypeError: + If the RSA key has no private half. + + :attention: Modify the salt length and the mask generation function only + if you know what you are doing. + The receiver must use the same parameters too. + """ + # TODO: Verify the key is RSA + + randfunc = self._key._randfunc + + # Set defaults for salt length and mask generation function + if self._saltLen == None: + sLen = mhash.digest_size + else: + sLen = self._saltLen + if self._mgfunc: + mgf = self._mgfunc + else: + mgf = lambda x,y: MGF1(x,y,mhash) + + modBits = Crypto.Util.number.size(self._key.n) + + # See 8.1.1 in RFC3447 + k = ceil_div(modBits,8) # Convert from bits to bytes + # Step 1 + em = EMSA_PSS_ENCODE(mhash, modBits-1, randfunc, mgf, sLen) + # Step 2a (OS2IP) and 2b (RSASP1) + m = self._key.decrypt(em) + # Step 2c (I2OSP) + S = bchr(0x00)*(k-len(m)) + m + return S + + def verify(self, mhash, S): + """Verify that a certain PKCS#1 PSS signature is authentic. + + This function checks if the party holding the private half of the given + RSA key has really signed the message. + + This function is called ``RSASSA-PSS-VERIFY``, and is specified in section + 8.1.2 of RFC3447. + + :Parameters: + mhash : hash object + The hash that was carried out over the message. This is an object + belonging to the `Crypto.Hash` module. + S : string + The signature that needs to be validated. + + :Return: True if verification is correct. False otherwise. + """ + # TODO: Verify the key is RSA + + # Set defaults for salt length and mask generation function + if self._saltLen == None: + sLen = mhash.digest_size + else: + sLen = self._saltLen + if self._mgfunc: + mgf = self._mgfunc + else: + mgf = lambda x,y: MGF1(x,y,mhash) + + modBits = Crypto.Util.number.size(self._key.n) + + # See 8.1.2 in RFC3447 + k = ceil_div(modBits,8) # Convert from bits to bytes + # Step 1 + if len(S) != k: + return False + # Step 2a (O2SIP), 2b (RSAVP1), and partially 2c (I2OSP) + # Note that signature must be smaller than the module + # but RSA.py won't complain about it. + # TODO: Fix RSA object; don't do it here. + em = self._key.encrypt(S, 0)[0] + # Step 2c + emLen = ceil_div(modBits-1,8) + em = bchr(0x00)*(emLen-len(em)) + em + # Step 3 + try: + result = EMSA_PSS_VERIFY(mhash, em, modBits-1, mgf, sLen) + except ValueError: + return False + # Step 4 + return result + +def MGF1(mgfSeed, maskLen, hash): + """Mask Generation Function, described in B.2.1""" + T = b("") + for counter in xrange(ceil_div(maskLen, hash.digest_size)): + c = long_to_bytes(counter, 4) + T = T + hash.new(mgfSeed + c).digest() + assert(len(T)>=maskLen) + return T[:maskLen] + +def EMSA_PSS_ENCODE(mhash, emBits, randFunc, mgf, sLen): + """ + Implement the ``EMSA-PSS-ENCODE`` function, as defined + in PKCS#1 v2.1 (RFC3447, 9.1.1). + + The original ``EMSA-PSS-ENCODE`` actually accepts the message ``M`` as input, + and hash it internally. Here, we expect that the message has already + been hashed instead. + + :Parameters: + mhash : hash object + The hash object that holds the digest of the message being signed. + emBits : int + Maximum length of the final encoding, in bits. + randFunc : callable + An RNG function that accepts as only parameter an int, and returns + a string of random bytes, to be used as salt. + mgf : callable + A mask generation function that accepts two parameters: a string to + use as seed, and the lenth of the mask to generate, in bytes. + sLen : int + Length of the salt, in bytes. + + :Return: An ``emLen`` byte long string that encodes the hash + (with ``emLen = \ceil(emBits/8)``). + + :Raise ValueError: + When digest or salt length are too big. + """ + + emLen = ceil_div(emBits,8) + + # Bitmask of digits that fill up + lmask = 0 + for i in xrange(8*emLen-emBits): + lmask = lmask>>1 | 0x80 + + # Step 1 and 2 have been already done + # Step 3 + if emLen < mhash.digest_size+sLen+2: + raise ValueError("Digest or salt length are too long for given key size.") + # Step 4 + salt = b("") + if randFunc and sLen>0: + salt = randFunc(sLen) + # Step 5 and 6 + h = mhash.new(bchr(0x00)*8 + mhash.digest() + salt) + # Step 7 and 8 + db = bchr(0x00)*(emLen-sLen-mhash.digest_size-2) + bchr(0x01) + salt + # Step 9 + dbMask = mgf(h.digest(), emLen-mhash.digest_size-1) + # Step 10 + maskedDB = strxor(db,dbMask) + # Step 11 + maskedDB = bchr(bord(maskedDB[0]) & ~lmask) + maskedDB[1:] + # Step 12 + em = maskedDB + h.digest() + bchr(0xBC) + return em + +def EMSA_PSS_VERIFY(mhash, em, emBits, mgf, sLen): + """ + Implement the ``EMSA-PSS-VERIFY`` function, as defined + in PKCS#1 v2.1 (RFC3447, 9.1.2). + + ``EMSA-PSS-VERIFY`` actually accepts the message ``M`` as input, + and hash it internally. Here, we expect that the message has already + been hashed instead. + + :Parameters: + mhash : hash object + The hash object that holds the digest of the message to be verified. + em : string + The signature to verify, therefore proving that the sender really signed + the message that was received. + emBits : int + Length of the final encoding (em), in bits. + mgf : callable + A mask generation function that accepts two parameters: a string to + use as seed, and the lenth of the mask to generate, in bytes. + sLen : int + Length of the salt, in bytes. + + :Return: 0 if the encoding is consistent, 1 if it is inconsistent. + + :Raise ValueError: + When digest or salt length are too big. + """ + + emLen = ceil_div(emBits,8) + + # Bitmask of digits that fill up + lmask = 0 + for i in xrange(8*emLen-emBits): + lmask = lmask>>1 | 0x80 + + # Step 1 and 2 have been already done + # Step 3 + if emLen < mhash.digest_size+sLen+2: + return False + # Step 4 + if ord(em[-1:])!=0xBC: + return False + # Step 5 + maskedDB = em[:emLen-mhash.digest_size-1] + h = em[emLen-mhash.digest_size-1:-1] + # Step 6 + if lmask & bord(em[0]): + return False + # Step 7 + dbMask = mgf(h, emLen-mhash.digest_size-1) + # Step 8 + db = strxor(maskedDB, dbMask) + # Step 9 + db = bchr(bord(db[0]) & ~lmask) + db[1:] + # Step 10 + if not db.startswith(bchr(0x00)*(emLen-mhash.digest_size-sLen-2) + bchr(0x01)): + return False + # Step 11 + salt = b("") + if sLen: salt = db[-sLen:] + # Step 12 and 13 + hp = mhash.new(bchr(0x00)*8 + mhash.digest() + salt).digest() + # Step 14 + if h!=hp: + return False + return True + +def new(key, mgfunc=None, saltLen=None): + """Return a signature scheme object `PSS_SigScheme` that + can be used to perform PKCS#1 PSS signature or verification. + + :Parameters: + key : RSA key object + The key to use to sign or verify the message. This is a `Crypto.PublicKey.RSA` object. + Signing is only possible if *key* is a private RSA key. + mgfunc : callable + A mask generation function that accepts two parameters: a string to + use as seed, and the lenth of the mask to generate, in bytes. + If not specified, the standard MGF1 is used. + saltLen : int + Length of the salt, in bytes. If not specified, it matches the output + size of the hash function. + + """ + return PSS_SigScheme(key, mgfunc, saltLen) + diff --git a/panda/python/Lib/site-packages/Crypto/Signature/PKCS1_PSS.pyo b/panda/python/Lib/site-packages/Crypto/Signature/PKCS1_PSS.pyo new file mode 100644 index 0000000000000000000000000000000000000000..c31684e9d2fb6a01f378655d724c373239a3032c GIT binary patch literal 11411 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 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Signature/PKCS1_v1_5.py b/panda/python/Lib/site-packages/Crypto/Signature/PKCS1_v1_5.py new file mode 100644 index 00000000..73ac251c --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Signature/PKCS1_v1_5.py @@ -0,0 +1,236 @@ +# -*- coding: utf-8 -*- +# +# Signature/PKCS1-v1_5.py : PKCS#1 v1.5 +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +""" +RSA digital signature protocol according to PKCS#1 v1.5 + +See RFC3447__ or the `original RSA Labs specification`__. + +This scheme is more properly called ``RSASSA-PKCS1-v1_5``. + +For example, a sender may authenticate a message using SHA-1 like +this: + + >>> from Crypto.Signature import PKCS1_v1_5 + >>> from Crypto.Hash import SHA + >>> from Crypto.PublicKey import RSA + >>> + >>> message = 'To be signed' + >>> key = RSA.importKey(open('privkey.der').read()) + >>> h = SHA.new(message) + >>> signer = PKCS1_v1_5.new(key) + >>> signature = signer.sign(h) + +At the receiver side, verification can be done using the public part of +the RSA key: + + >>> key = RSA.importKey(open('pubkey.der').read()) + >>> h = SHA.new(message) + >>> verifier = PKCS1_v1_5.new(key) + >>> if verifier.verify(h, signature): + >>> print "The signature is authentic." + >>> else: + >>> print "The signature is not authentic." + +:undocumented: __revision__, __package__ + +.. __: http://www.ietf.org/rfc/rfc3447.txt +.. __: http://www.rsa.com/rsalabs/node.asp?id=2125 +""" + +__revision__ = "$Id$" +__all__ = [ 'new', 'PKCS115_SigScheme' ] + +import Crypto.Util.number +from Crypto.Util.number import ceil_div +from Crypto.Util.asn1 import DerSequence, DerNull, DerOctetString +from Crypto.Util.py3compat import * + +class PKCS115_SigScheme: + """This signature scheme can perform PKCS#1 v1.5 RSA signature or verification.""" + + def __init__(self, key): + """Initialize this PKCS#1 v1.5 signature scheme object. + + :Parameters: + key : an RSA key object + If a private half is given, both signature and verification are possible. + If a public half is given, only verification is possible. + """ + self._key = key + + def can_sign(self): + """Return True if this cipher object can be used for signing messages.""" + return self._key.has_private() + + def sign(self, mhash): + """Produce the PKCS#1 v1.5 signature of a message. + + This function is named ``RSASSA-PKCS1-V1_5-SIGN``, and is specified in + section 8.2.1 of RFC3447. + + :Parameters: + mhash : hash object + The hash that was carried out over the message. This is an object + belonging to the `Crypto.Hash` module. + + :Return: The signature encoded as a string. + :Raise ValueError: + If the RSA key length is not sufficiently long to deal with the given + hash algorithm. + :Raise TypeError: + If the RSA key has no private half. + """ + # TODO: Verify the key is RSA + + # See 8.2.1 in RFC3447 + modBits = Crypto.Util.number.size(self._key.n) + k = ceil_div(modBits,8) # Convert from bits to bytes + + # Step 1 + em = EMSA_PKCS1_V1_5_ENCODE(mhash, k) + # Step 2a (OS2IP) and 2b (RSASP1) + m = self._key.decrypt(em) + # Step 2c (I2OSP) + S = bchr(0x00)*(k-len(m)) + m + return S + + def verify(self, mhash, S): + """Verify that a certain PKCS#1 v1.5 signature is authentic. + + This function checks if the party holding the private half of the key + really signed the message. + + This function is named ``RSASSA-PKCS1-V1_5-VERIFY``, and is specified in + section 8.2.2 of RFC3447. + + :Parameters: + mhash : hash object + The hash that was carried out over the message. This is an object + belonging to the `Crypto.Hash` module. + S : string + The signature that needs to be validated. + + :Return: True if verification is correct. False otherwise. + """ + # TODO: Verify the key is RSA + + # See 8.2.2 in RFC3447 + modBits = Crypto.Util.number.size(self._key.n) + k = ceil_div(modBits,8) # Convert from bits to bytes + + # Step 1 + if len(S) != k: + return 0 + # Step 2a (O2SIP) and 2b (RSAVP1) + # Note that signature must be smaller than the module + # but RSA.py won't complain about it. + # TODO: Fix RSA object; don't do it here. + m = self._key.encrypt(S, 0)[0] + # Step 2c (I2OSP) + em1 = bchr(0x00)*(k-len(m)) + m + # Step 3 + try: + em2 = EMSA_PKCS1_V1_5_ENCODE(mhash, k) + except ValueError: + return 0 + # Step 4 + # By comparing the full encodings (as opposed to checking each + # of its components one at a time) we avoid attacks to the padding + # scheme like Bleichenbacher's (see http://www.mail-archive.com/cryptography@metzdowd.com/msg06537). + # + return em1==em2 + +def EMSA_PKCS1_V1_5_ENCODE(hash, emLen): + """ + Implement the ``EMSA-PKCS1-V1_5-ENCODE`` function, as defined + in PKCS#1 v2.1 (RFC3447, 9.2). + + ``EMSA-PKCS1-V1_5-ENCODE`` actually accepts the message ``M`` as input, + and hash it internally. Here, we expect that the message has already + been hashed instead. + + :Parameters: + hash : hash object + The hash object that holds the digest of the message being signed. + emLen : int + The length the final encoding must have, in bytes. + + :attention: the early standard (RFC2313) stated that ``DigestInfo`` + had to be BER-encoded. This means that old signatures + might have length tags in indefinite form, which + is not supported in DER. Such encoding cannot be + reproduced by this function. + + :attention: the same standard defined ``DigestAlgorithm`` to be + of ``AlgorithmIdentifier`` type, where the PARAMETERS + item is optional. Encodings for ``MD2/4/5`` without + ``PARAMETERS`` cannot be reproduced by this function. + + :Return: An ``emLen`` byte long string that encodes the hash. + """ + + # First, build the ASN.1 DER object DigestInfo: + # + # DigestInfo ::= SEQUENCE { + # digestAlgorithm AlgorithmIdentifier, + # digest OCTET STRING + # } + # + # where digestAlgorithm identifies the hash function and shall be an + # algorithm ID with an OID in the set PKCS1-v1-5DigestAlgorithms. + # + # PKCS1-v1-5DigestAlgorithms ALGORITHM-IDENTIFIER ::= { + # { OID id-md2 PARAMETERS NULL }| + # { OID id-md5 PARAMETERS NULL }| + # { OID id-sha1 PARAMETERS NULL }| + # { OID id-sha256 PARAMETERS NULL }| + # { OID id-sha384 PARAMETERS NULL }| + # { OID id-sha512 PARAMETERS NULL } + # } + # + digestAlgo = DerSequence([hash.oid, DerNull().encode()]) + digest = DerOctetString(hash.digest()) + digestInfo = DerSequence([ + digestAlgo.encode(), + digest.encode() + ]).encode() + + # We need at least 11 bytes for the remaining data: 3 fixed bytes and + # at least 8 bytes of padding). + if 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 +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== +"""Fast counter functions for CTR cipher modes. + +CTR is a chaining mode for symmetric block encryption or decryption. +Messages are divideded into blocks, and the cipher operation takes +place on each block using the secret key and a unique *counter block*. + +The most straightforward way to fulfil the uniqueness property is +to start with an initial, random *counter block* value, and increment it as +the next block is processed. + +The block ciphers from `Crypto.Cipher` (when configured in *MODE_CTR* mode) +invoke a callable object (the *counter* parameter) to get the next *counter block*. +Unfortunately, the Python calling protocol leads to major performance degradations. + +The counter functions instantiated by this module will be invoked directly +by the ciphers in `Crypto.Cipher`. The fact that the Python layer is bypassed +lead to more efficient (and faster) execution of CTR cipher modes. + +An example of usage is the following: + + >>> from Crypto.Cipher import AES + >>> from Crypto.Util import Counter + >>> + >>> pt = b'\x00'*1000000 + >>> ctr = Counter.new(128) + >>> cipher = AES.new(b'\x00'*16, AES.MODE_CTR, counter=ctr) + >>> ct = cipher.encrypt(pt) + +:undocumented: __package__ +""" +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * +from Crypto.Util.py3compat import * + +from Crypto.Util import _counter +import struct + +# Factory function +def new(nbits, prefix=b(""), suffix=b(""), initial_value=1, overflow=0, little_endian=False, allow_wraparound=False, disable_shortcut=False): + """Create a stateful counter block function suitable for CTR encryption modes. + + Each call to the function returns the next counter block. + Each counter block is made up by three parts:: + + prefix || counter value || postfix + + The counter value is incremented by one at each call. + + :Parameters: + nbits : integer + Length of the desired counter, in bits. It must be a multiple of 8. + prefix : byte string + The constant prefix of the counter block. By default, no prefix is + used. + suffix : byte string + The constant postfix of the counter block. By default, no suffix is + used. + initial_value : integer + The initial value of the counter. Default value is 1. + little_endian : boolean + If True, the counter number will be encoded in little endian format. + If False (default), in big endian format. + allow_wraparound : boolean + If True, the function will raise an *OverflowError* exception as soon + as the counter wraps around. If False (default), the counter will + simply restart from zero. + disable_shortcut : boolean + If True, do not make ciphers from `Crypto.Cipher` bypass the Python + layer when invoking the counter block function. + If False (default), bypass the Python layer. + :Returns: + The counter block function. + """ + + # Sanity-check the message size + (nbytes, remainder) = divmod(nbits, 8) + if remainder != 0: + # In the future, we might support arbitrary bit lengths, but for now we don't. + raise ValueError("nbits must be a multiple of 8; got %d" % (nbits,)) + if nbytes < 1: + raise ValueError("nbits too small") + elif nbytes > 0xffff: + raise ValueError("nbits too large") + + initval = _encode(initial_value, nbytes, little_endian) + + if little_endian: + return _counter._newLE(bstr(prefix), bstr(suffix), initval, allow_wraparound=allow_wraparound, disable_shortcut=disable_shortcut) + else: + return _counter._newBE(bstr(prefix), bstr(suffix), initval, allow_wraparound=allow_wraparound, disable_shortcut=disable_shortcut) + +def _encode(n, nbytes, little_endian=False): + retval = [] + n = long(n) + for i in range(nbytes): + if little_endian: + retval.append(bchr(n & 0xff)) + else: + retval.insert(0, bchr(n & 0xff)) + n >>= 8 + return b("").join(retval) + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/Util/Counter.pyo b/panda/python/Lib/site-packages/Crypto/Util/Counter.pyo new file mode 100644 index 0000000000000000000000000000000000000000..0c8a4e5d1eaa8c90747c6534d0f03c2ff4583b41 GIT binary patch literal 4231 zcmb_fUy~cf5uaV%>CTHC2nnu=^T50qbjqRPph$=kJBIU7MameLd_c-2N{n_#(%h|f zmzi1Xl+snDfM>o1PkG5V;zRHO%&%v5biVW1F(}i#^(6a+_t_>|1CE3rK?=d8PT!uCVXGnb2*Pu!A^I=F6=o3 z_q>D$jMYL-XBKuZgwFUvEIE!dsq=}-olq~Mz}b1F={$A`S0rFER%pu?%Fdt;W+$-UDB&v8^9!rX&$a68y;mh%nOfB!w z8G@g>yb@XPmv`iz0e9~RF1tbp@uT?i}l<*s9Vu(UG-iIh-mV2v%)GUvGz znIVaDafIZ6GqH6p3dA&%Q!O$VYf3l@P>9-DcB%qCFW_bi`^JdW48B5+)-YtD@|=$) z;y@;5NH7h<@@3-qLPiSfUD`WW1~d#UmjToCPJ4SWYG? zRTRh$CGG?@MJ|&kGOc|DOfIXY50JknVqTH^C%mSjARXl5Ntx&60#55E3CHL5?b|-w z=c3Kkyn@g92L}%?<@(Gbc^jU6U*mx<{PN23TYUT`d$YUuw)?CpsnsAg`+9|3boSnP zf9H(sq2U&3cT_Lr&%5qH$hh4QzFQFY)MnD^^SIX_MW?bmNz$)THEB&%A+tUojVh5I z!!e^#qMqP$Ujez8is=&J(xHo`OV=+6j7Lq%Sgct}PYCbmcOPH#BQ7AV9L|0lvti6m zx7q0xwgODX?6}4BUq~jP6g-oNT?fW~6EOhu3P=kOXG{+q$0orqk^bmNZFaoD^xToQ z0tw1uwt}o}wgP{PohG!<|6{hrjy9OxWUGjnX%W+6l@PG6+6(}`f}B?TkXYOQA1jc) z0r+$i7Hf$zL8+r;tOTHifHWu*s*0OhSqB9H`=3Jafd7<=2L!oP(vg*y_2=@w=OT|5${eHsTCJyM36LrE@tM%y}j?#k) z_zjw`6RO~#)pJ1l8fQIPlm*;jed{1Q05fD)|3Lsd1HJB3jFmOK4*^zArEZ>beoq!t zpgoF~Ohs!1#$-Y7E@%R0SlgP|{0+K7FQ(xxqr zd{CZsDcRca_!fCVX^-Fa1~ycLbuSo{D{FH(l0~M_fMHiz0-lSt@gGn4p{Axw(F#Ts z^?VFW5A6cUjv0rh5bnicfN|nnXR<*R=MeUh$c^Nk#^XCpz^9k*K!TNv(LxKPG}1o% zrSq-p(VYxa2~@$V?x&B@B_ZlS>r!{oI8y1SD`B`P%QI_n|FoT?nMN(rjf}kH^yj$I zJ=cCSXdU?yW$h;%H*Wk}>M}SZQ-%OzWM*hW=yWeKEh~|jC~_b~2-h${tJh^JYvsi;ZC~W)E{^t3ot;r`64BXI*aQ|<|bAiHJ(%W zf8$fQ;b!KVmw9>3Zc7Z3a~hPMJVA>(PsoMF?DYzmFJ_Z_crgz5J6mA2ZCo&31G{a4 z<>xeby6mw;M!8VN4_yBw))6}Vy#tGP0yYK^x$X4q!vpuWfacVg<|rPJ-O?Any$1TZ zD!1g8vPoM7XPNsL{caxr@1j)qa2Y0JD~O z_wHMJy}$O}9#(GF9Ntsop;1=8)yxfM=qIKj%|gR{-*|dpChf59ANVoXabY)Ki>}7k zqpQ)&^o?JQ+tHuml-S5}^3XoM=0CVh89Qw?BLv#@DPt%9qMq;D_}wr6$xb(@mE%nh zeIGA>(B`L&J7C9uRNQcs4VpL36Jr(;Ym423*sot_U%>GgIj{-+AJVXR*r5~MS4b3} zb}j)2G!yyAlT-5&J&O479)jed^NXqisQCz|Gaq4$((tnzpvI1JRI0+sch8E!Z?SPe zspmwX#UmDuq<-ay3|!Jeks)m?Y9kE4!}UgdBl=C$xk^WHi95o8I2ySCnx(NsK$01} zX^s@$K`ceH8IvjK2=+UBX*sWiwXZ!xdbgp_fcVs=v$8-b)TtfZ0NuIMf&bw5xOE3U jbHcBfo7<57cmFc00g;<~u` literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Util/RFC1751.py b/panda/python/Lib/site-packages/Crypto/Util/RFC1751.py new file mode 100644 index 00000000..9786e6f5 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Util/RFC1751.py @@ -0,0 +1,364 @@ +# rfc1751.py : Converts between 128-bit strings and a human-readable +# sequence of words, as defined in RFC1751: "A Convention for +# Human-Readable 128-bit Keys", by Daniel L. McDonald. +# +# Part of the Python Cryptography Toolkit +# +# Written by Andrew M. Kuchling and others +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +__revision__ = "$Id$" + + +import binascii +from Crypto.Util.py3compat import * + +binary={0:'0000', 1:'0001', 2:'0010', 3:'0011', 4:'0100', 5:'0101', + 6:'0110', 7:'0111', 8:'1000', 9:'1001', 10:'1010', 11:'1011', + 12:'1100', 13:'1101', 14:'1110', 15:'1111'} + +def _key2bin(s): + "Convert a key into a string of binary digits" + kl=map(lambda x: bord(x), s) + kl=map(lambda x: binary[x>>4]+binary[x&15], kl) + return ''.join(kl) + +def _extract(key, start, length): + """Extract a bitstring(2.x)/bytestring(2.x) from a string of binary digits, and return its + numeric value.""" + k=key[start:start+length] + return reduce(lambda x,y: x*2+ord(y)-48, k, 0) + +def key_to_english (key): + """key_to_english(key:string(2.x)/bytes(3.x)) : string + Transform an arbitrary key into a string containing English words. + The key length must be a multiple of 8. + """ + english='' + for index in range(0, len(key), 8): # Loop over 8-byte subkeys + subkey=key[index:index+8] + # Compute the parity of the key + skbin=_key2bin(subkey) ; p=0 + for i in range(0, 64, 2): p=p+_extract(skbin, i, 2) + # Append parity bits to the subkey + skbin=_key2bin(subkey+bchr((p<<6) & 255)) + for i in range(0, 64, 11): + english=english+wordlist[_extract(skbin, i, 11)]+' ' + + return english[:-1] # Remove the trailing space + +def english_to_key (s): + """english_to_key(string):string(2.x)/bytes(2.x) + Transform a string into a corresponding key. + The string must contain words separated by whitespace; the number + of words must be a multiple of 6. + """ + + L=s.upper().split() ; key=b('') + for index in range(0, len(L), 6): + sublist=L[index:index+6] ; char=9*[0] ; bits=0 + for i in sublist: + index = wordlist.index(i) + shift = (8-(bits+11)%8) %8 + y = index << shift + cl, cc, cr = (y>>16), (y>>8)&0xff, y & 0xff + if (shift>5): + char[bits>>3] = char[bits>>3] | cl + char[(bits>>3)+1] = char[(bits>>3)+1] | cc + char[(bits>>3)+2] = char[(bits>>3)+2] | cr + elif shift>-3: + char[bits>>3] = char[bits>>3] | cc + char[(bits>>3)+1] = char[(bits>>3)+1] | cr + else: char[bits>>3] = char[bits>>3] | cr + bits=bits+11 + subkey=reduce(lambda x,y:x+bchr(y), char, b('')) + + # Check the parity of the resulting key + skbin=_key2bin(subkey) + p=0 + for i in range(0, 64, 2): p=p+_extract(skbin, i, 2) + if (p&3) != _extract(skbin, 64, 2): + raise ValueError, "Parity error in resulting key" + key=key+subkey[0:8] + return key + +wordlist=[ "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD", + "AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA", + "AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK", + "ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE", + "AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM", + "BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET", + "BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO", + "BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT", + "BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT", + "CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY", + "CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN", + "DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG", + "DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB", + "DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO", + "ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE", + "EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW", + "FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR", + "FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP", + "GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO", + "GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD", + "HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM", + "HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT", + "HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE", + "HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL", + "INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT", + "ITS", "IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET", + "JIG", "JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT", + "KAY", "KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB", + "LAC", "LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", + "LEG", "LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT", + "LO", "LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG", + "LYE", "MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW", + "MAY", "ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT", + "MOB", "MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG", + "MUM", "MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED", + "NEE", "NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD", + "NON", "NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF", + "OAK", "OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL", + "OK", "OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT", + "OUR", "OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD", + "PAL", "PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG", + "PEN", "PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT", + "PLY", "PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB", + "PUG", "PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT", + "RAW", "RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM", + "RIO", "RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB", + "RUE", "RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM", + "SAN", "SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET", + "SEW", "SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY", + "SLY", "SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY", + "SUB", "SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN", + "TAP", "TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE", + "TIM", "TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP", + "TOW", "TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP", + "US", "USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS", + "WAY", "WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT", + "WOK", "WON", "WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", + "YEA", "YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT", + "ACHE", "ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS", + "ADEN", "AFAR", "AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE", + "AIDS", "AIRY", "AJAR", "AKIN", "ALAN", "ALEC", "ALGA", "ALIA", + "ALLY", "ALMA", "ALOE", "ALSO", "ALTO", "ALUM", "ALVA", "AMEN", + "AMES", "AMID", "AMMO", "AMOK", "AMOS", "AMRA", "ANDY", "ANEW", + "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB", "ARCH", "AREA", + "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS", "ATOM", + "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW", + "AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL", + "BAIT", "BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM", + "BAND", "BANE", "BANG", "BANK", "BARB", "BARD", "BARE", "BARK", + "BARN", "BARR", "BASE", "BASH", "BASK", "BASS", "BATE", "BATH", + "BAWD", "BAWL", "BEAD", "BEAK", "BEAM", "BEAN", "BEAR", "BEAT", + "BEAU", "BECK", "BEEF", "BEEN", "BEER", + "BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN", + "BERT", "BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", + "BIEN", "BILE", "BILK", "BILL", "BIND", "BING", "BIRD", "BITE", + "BITS", "BLAB", "BLAT", "BLED", "BLEW", "BLOB", "BLOC", "BLOT", + "BLOW", "BLUE", "BLUM", "BLUR", "BOAR", "BOAT", "BOCA", "BOCK", + "BODE", "BODY", "BOGY", "BOHR", "BOIL", "BOLD", "BOLO", "BOLT", + "BOMB", "BONA", "BOND", "BONE", "BONG", "BONN", "BONY", "BOOK", + "BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE", "BOSS", + "BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN", + "BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", + "BUFF", "BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", + "BURL", "BURN", "BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", + "BUSY", "BYTE", "CADY", "CAFE", "CAGE", "CAIN", "CAKE", "CALF", + "CALL", "CALM", "CAME", "CANE", "CANT", "CARD", "CARE", "CARL", + "CARR", "CART", "CASE", "CASH", "CASK", "CAST", "CAVE", "CEIL", + "CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT", "CHAW", "CHEF", + "CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB", "CHUG", + "CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY", + "CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", + "COCK", "COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN", + "COKE", "COLA", "COLD", "COLT", "COMA", "COMB", "COME", "COOK", + "COOL", "COON", "COOT", "CORD", "CORE", "CORK", "CORN", "COST", + "COVE", "COWL", "CRAB", "CRAG", "CRAM", "CRAY", "CREW", "CRIB", + "CROW", "CRUD", "CUBA", "CUBE", "CUFF", "CULL", "CULT", "CUNY", + "CURB", "CURD", "CURE", "CURL", "CURT", "CUTS", "DADE", "DALE", + "DAME", "DANA", "DANE", "DANG", "DANK", "DARE", "DARK", "DARN", + "DART", "DASH", "DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS", + "DEAD", "DEAF", "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", + "DEEM", "DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", + "DIAL", "DICE", "DIED", "DIET", "DIME", "DINE", "DING", "DINT", + "DIRE", "DIRT", "DISC", "DISH", "DISK", "DIVE", "DOCK", "DOES", + "DOLE", "DOLL", "DOLT", "DOME", "DONE", "DOOM", "DOOR", "DORA", + "DOSE", "DOTE", "DOUG", "DOUR", "DOVE", "DOWN", "DRAB", "DRAG", + "DRAM", "DRAW", "DREW", "DRUB", "DRUG", "DRUM", "DUAL", "DUCK", + "DUCT", "DUEL", "DUET", "DUKE", "DULL", "DUMB", "DUNE", "DUNK", + "DUSK", "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST", + "EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", + "EDNA", "EGAN", "ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", + "EMMA", "ENDS", "ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", + "FACE", "FACT", "FADE", "FAIL", "FAIN", "FAIR", "FAKE", "FALL", + "FAME", "FANG", "FARM", "FAST", "FATE", "FAWN", "FEAR", "FEAT", + "FEED", "FEEL", "FEET", "FELL", "FELT", "FEND", "FERN", "FEST", + "FEUD", "FIEF", "FIGS", "FILE", "FILL", "FILM", "FIND", "FINE", + "FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS", "FIVE", + "FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW", + "FLIT", "FLOC", "FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", + "FOGY", "FOIL", "FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", + "FOOT", "FORD", "FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", + "FOUR", "FOWL", "FRAU", "FRAY", "FRED", "FREE", "FRET", "FREY", + "FROG", "FROM", "FUEL", "FULL", "FUME", "FUND", "FUNK", "FURY", + "FUSE", "FUSS", "GAFF", "GAGE", "GAIL", "GAIN", "GAIT", "GALA", + "GALE", "GALL", "GALT", "GAME", "GANG", "GARB", "GARY", "GASH", + "GATE", "GAUL", "GAUR", "GAVE", "GAWK", "GEAR", "GELD", "GENE", + "GENT", "GERM", "GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT", + "GINA", "GIRD", "GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", + "GLIB", "GLOB", "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", + "GOAL", "GOAT", "GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", + "GOOD", "GOOF", "GORE", "GORY", "GOSH", "GOUT", "GOWN", "GRAB", + "GRAD", "GRAY", "GREG", "GREW", "GREY", "GRID", "GRIM", "GRIN", + "GRIT", "GROW", "GRUB", "GULF", "GULL", "GUNK", "GURU", "GUSH", + "GUST", "GWEN", "GWYN", "HAAG", "HAAS", "HACK", "HAIL", "HAIR", + "HALE", "HALF", "HALL", "HALO", "HALT", "HAND", "HANG", "HANK", + "HANS", "HARD", "HARK", "HARM", "HART", "HASH", "HAST", "HATE", + "HATH", "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", + "HEAT", "HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", + "HELM", "HERB", "HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", + "HICK", "HIDE", "HIGH", "HIKE", "HILL", "HILT", "HIND", "HINT", + "HIRE", "HISS", "HIVE", "HOBO", "HOCK", "HOFF", "HOLD", "HOLE", + "HOLM", "HOLT", "HOME", "HONE", "HONK", "HOOD", "HOOF", "HOOK", + "HOOT", "HORN", "HOSE", "HOST", "HOUR", "HOVE", "HOWE", "HOWL", + "HOYT", "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO", "HULK", + "HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE", + "HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", + "INTO", "IONS", "IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", + "ITCH", "ITEM", "IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", + "JAVA", "JEAN", "JEFF", "JERK", "JESS", "JEST", "JIBE", "JILL", + "JILT", "JIVE", "JOAN", "JOBS", "JOCK", "JOEL", "JOEY", "JOHN", + "JOIN", "JOKE", "JOLT", "JOVE", "JUDD", "JUDE", "JUDO", "JUDY", + "JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO", "JURY", "JUST", + "JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", "KATE", "KEEL", + "KEEN", "KENO", "KENT", "KERN", "KERR", "KEYS", "KICK", "KILL", + "KIND", "KING", "KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", + "KNIT", "KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", + "KURT", "KYLE", "LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", + "LAIR", "LAKE", "LAMB", "LAME", "LAND", "LANE", "LANG", "LARD", + "LARK", "LASS", "LAST", "LATE", "LAUD", "LAVA", "LAWN", "LAWS", + "LAYS", "LEAD", "LEAF", "LEAK", "LEAN", "LEAR", "LEEK", "LEER", + "LEFT", "LEND", "LENS", "LENT", "LEON", "LESK", "LESS", "LEST", + "LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES", "LIEU", + "LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB", + "LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST", + "LIVE", "LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", + "LOIS", "LOLA", "LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", + "LORE", "LOSE", "LOSS", "LOST", "LOUD", "LOVE", "LOWE", "LUCK", + "LUCY", "LUGE", "LUKE", "LULU", "LUND", "LUNG", "LURA", "LURE", + "LURK", "LUSH", "LUST", "LYLE", "LYNN", "LYON", "LYRA", "MACE", + "MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE", "MALE", "MALI", + "MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE", "MARK", + "MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE", + "MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", + "MEET", "MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", + "MESS", "MICE", "MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", + "MIMI", "MIND", "MINE", "MINI", "MINK", "MINT", "MIRE", "MISS", + "MIST", "MITE", "MITT", "MOAN", "MOAT", "MOCK", "MODE", "MOLD", + "MOLE", "MOLL", "MOLT", "MONA", "MONK", "MONT", "MOOD", "MOON", + "MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS", "MOST", "MOTH", + "MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL", "MURK", + "MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL", + "NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", + "NEAT", "NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", + "NEST", "NEWS", "NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", + "NINE", "NOAH", "NODE", "NOEL", "NOLL", "NONE", "NOOK", "NOON", + "NORM", "NOSE", "NOTE", "NOUN", "NOVA", "NUDE", "NULL", "NUMB", + "OATH", "OBEY", "OBOE", "ODIN", "OHIO", "OILY", "OINT", "OKAY", + "OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN", "OMIT", "ONCE", + "ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO", "OTIS", + "OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY", + "OWNS", "QUAD", "QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", + "RAGE", "RAID", "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", + "RASH", "RATE", "RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", + "RECK", "REED", "REEF", "REEK", "REEL", "REID", "REIN", "RENA", + "REND", "RENT", "REST", "RICE", "RICH", "RICK", "RIDE", "RIFT", + "RILL", "RIME", "RING", "RINK", "RISE", "RISK", "RITE", "ROAD", + "ROAM", "ROAR", "ROBE", "ROCK", "RODE", "ROIL", "ROLL", "ROME", + "ROOD", "ROOF", "ROOK", "ROOM", "ROOT", "ROSA", "ROSE", "ROSS", + "ROSY", "ROTH", "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY", + "RUDE", "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", + "RUSH", "RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", + "SAID", "SAIL", "SALE", "SALK", "SALT", "SAME", "SAND", "SANE", + "SANG", "SANK", "SARA", "SAUL", "SAVE", "SAYS", "SCAN", "SCAR", + "SCAT", "SCOT", "SEAL", "SEAM", "SEAR", "SEAT", "SEED", "SEEK", + "SEEM", "SEEN", "SEES", "SELF", "SELL", "SEND", "SENT", "SETS", + "SEWN", "SHAG", "SHAM", "SHAW", "SHAY", "SHED", "SHIM", "SHIN", + "SHOD", "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK", "SIDE", + "SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", "SINE", + "SING", "SINK", "SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", + "SKID", "SKIM", "SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", + "SLED", "SLEW", "SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", + "SLOW", "SLUG", "SLUM", "SLUR", "SMOG", "SMUG", "SNAG", "SNOB", + "SNOW", "SNUB", "SNUG", "SOAK", "SOAR", "SOCK", "SODA", "SOFA", + "SOFT", "SOIL", "SOLD", "SOME", "SONG", "SOON", "SOOT", "SORE", + "SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG", "STAN", "STAR", + "STAY", "STEM", "STEW", "STIR", "STOW", "STUB", "STUN", "SUCH", + "SUDS", "SUIT", "SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF", + "SWAB", "SWAG", "SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", + "TACK", "TACT", "TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", + "TASK", "TATE", "TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", + "TEEN", "TEET", "TELL", "TEND", "TENT", "TERM", "TERN", "TESS", + "TEST", "THAN", "THAT", "THEE", "THEM", "THEN", "THEY", "THIN", + "THIS", "THUD", "THUG", "TICK", "TIDE", "TIDY", "TIED", "TIER", + "TILE", "TILL", "TILT", "TIME", "TINA", "TINE", "TINT", "TINY", + "TIRE", "TOAD", "TOGO", "TOIL", "TOLD", "TOLL", "TONE", "TONG", + "TONY", "TOOK", "TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR", + "TOUT", "TOWN", "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", + "TRIM", "TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", + "TUCK", "TUFT", "TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", + "TWIG", "TWIN", "TWIT", "ULAN", "UNIT", "URGE", "USED", "USER", + "USES", "UTAH", "VAIL", "VAIN", "VALE", "VARY", "VASE", "VAST", + "VEAL", "VEDA", "VEIL", "VEIN", "VEND", "VENT", "VERB", "VERY", + "VETO", "VICE", "VIEW", "VINE", "VISE", "VOID", "VOLT", "VOTE", + "WACK", "WADE", "WAGE", "WAIL", "WAIT", "WAKE", "WALE", "WALK", + "WALL", "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM", + "WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", + "WAYS", "WEAK", "WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", + "WELD", "WELL", "WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", + "WHAT", "WHEE", "WHEN", "WHET", "WHOA", "WHOM", "WICK", "WIFE", + "WILD", "WILL", "WIND", "WINE", "WING", "WINK", "WINO", "WIRE", + "WISE", "WISH", "WITH", "WOLF", "WONT", "WOOD", "WOOL", "WORD", + "WORE", "WORK", "WORM", "WORN", "WOVE", "WRIT", "WYNN", "YALE", + "YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH", "YEAR", + "YELL", "YOGA", "YOKE" ] + +if __name__=='__main__': + data = [('EB33F77EE73D4053', 'TIDE ITCH SLOW REIN RULE MOT'), + ('CCAC2AED591056BE4F90FD441C534766', + 'RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE'), + ('EFF81F9BFBC65350920CDD7416DE8009', + 'TROD MUTE TAIL WARM CHAR KONG HAAG CITY BORE O TEAL AWL') + ] + + for key, words in data: + print 'Trying key', key + key=binascii.a2b_hex(key) + w2=key_to_english(key) + if w2!=words: + print 'key_to_english fails on key', repr(key), ', producing', str(w2) + k2=english_to_key(words) + if k2!=key: + print 'english_to_key fails on key', repr(key), ', producing', repr(k2) + + diff --git a/panda/python/Lib/site-packages/Crypto/Util/RFC1751.pyo b/panda/python/Lib/site-packages/Crypto/Util/RFC1751.pyo new file mode 100644 index 0000000000000000000000000000000000000000..233a170a19bedd52454bf024da8225c187d39a69 GIT binary patch literal 29278 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 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Util/__init__.py b/panda/python/Lib/site-packages/Crypto/Util/__init__.py new file mode 100644 index 00000000..a3bef8ae --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Util/__init__.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Miscellaneous modules + +Contains useful modules that don't belong into any of the +other Crypto.* subpackages. + +Crypto.Util.number Number-theoretic functions (primality testing, etc.) +Crypto.Util.randpool Random number generation +Crypto.Util.RFC1751 Converts between 128-bit keys and human-readable + strings of words. +Crypto.Util.asn1 Minimal support for ASN.1 DER encoding + +""" + +__all__ = ['randpool', 'RFC1751', 'number', 'strxor', 'asn1' ] + +__revision__ = "$Id$" + diff --git a/panda/python/Lib/site-packages/Crypto/Util/__init__.pyo b/panda/python/Lib/site-packages/Crypto/Util/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..4c2a3f3c0cf1f260e5cf96002028710708d71dd8 GIT binary patch literal 725 zcmZWn-HOvd6rOFjT?u;W{kd4NiU~#$e-Lr$DhO_oF5Z;DFv*;@!%kCgJtZj7dba`N z$b)iw@N4#B;#mZkhkZ>xdk(QFYgJvT4aSVicIKaCZ04F>$&vk89JG{^eLyl5tQ%L6 z@jSw;4rZsUp*;{rGH&w%kgDw2y>dZ0U3+i4dP~;)4*DJ&bQn}y?Ow|A>pXw^ChsR; z%GVeuGBLVAbdbM#mzIX$3ipv2YS=bA<~>^m|yeBDVtc$-Qp0PUrQ2gLUsMqIdp1sdr u7WJOC-WA_XSwusa4o_Wle2ey>3n`f*NttnUOX6eqmwf`phv}xH$D==G+0NYn literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Util/_counter.pyd b/panda/python/Lib/site-packages/Crypto/Util/_counter.pyd new file mode 100644 index 0000000000000000000000000000000000000000..8ea43c5ce7fc51b03534c5271e921104962ea65e GIT binary patch literal 10240 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 UV@3Om4&dGXMft)5zs&>x32qKD+yDRo literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Util/_number_new.py b/panda/python/Lib/site-packages/Crypto/Util/_number_new.py new file mode 100644 index 00000000..b040025f --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Util/_number_new.py @@ -0,0 +1,119 @@ +# -*- coding: ascii -*- +# +# Util/_number_new.py : utility functions +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +## NOTE: Do not import this module directly. Import these functions from Crypto.Util.number. + +__revision__ = "$Id$" +__all__ = ['ceil_shift', 'ceil_div', 'floor_div', 'exact_log2', 'exact_div'] + +import sys +if sys.version_info[0] == 2 and sys.version_info[1] == 1: + from Crypto.Util.py21compat import * + +def ceil_shift(n, b): + """Return ceil(n / 2**b) without performing any floating-point or division operations. + + This is done by right-shifting n by b bits and incrementing the result by 1 + if any '1' bits were shifted out. + """ + if not isinstance(n, (int, long)) or not isinstance(b, (int, long)): + raise TypeError("unsupported operand type(s): %r and %r" % (type(n).__name__, type(b).__name__)) + + assert n >= 0 and b >= 0 # I haven't tested or even thought about negative values + mask = (1L << b) - 1 + if n & mask: + return (n >> b) + 1 + else: + return n >> b + +def ceil_div(a, b): + """Return ceil(a / b) without performing any floating-point operations.""" + + if not isinstance(a, (int, long)) or not isinstance(b, (int, long)): + raise TypeError("unsupported operand type(s): %r and %r" % (type(a).__name__, type(b).__name__)) + + (q, r) = divmod(a, b) + if r: + return q + 1 + else: + return q + +def floor_div(a, b): + if not isinstance(a, (int, long)) or not isinstance(b, (int, long)): + raise TypeError("unsupported operand type(s): %r and %r" % (type(a).__name__, type(b).__name__)) + + (q, r) = divmod(a, b) + return q + +def exact_log2(num): + """Find and return an integer i >= 0 such that num == 2**i. + + If no such integer exists, this function raises ValueError. + """ + + if not isinstance(num, (int, long)): + raise TypeError("unsupported operand type: %r" % (type(num).__name__,)) + + n = long(num) + if n <= 0: + raise ValueError("cannot compute logarithm of non-positive number") + + i = 0 + while n != 0: + if (n & 1) and n != 1: + raise ValueError("No solution could be found") + i += 1 + n >>= 1 + i -= 1 + + assert num == (1L << i) + return i + +def exact_div(p, d, allow_divzero=False): + """Find and return an integer n such that p == n * d + + If no such integer exists, this function raises ValueError. + + Both operands must be integers. + + If the second operand is zero, this function will raise ZeroDivisionError + unless allow_divzero is true (default: False). + """ + + if not isinstance(p, (int, long)) or not isinstance(d, (int, long)): + raise TypeError("unsupported operand type(s): %r and %r" % (type(p).__name__, type(d).__name__)) + + if d == 0 and allow_divzero: + n = 0 + if p != n * d: + raise ValueError("No solution could be found") + else: + (n, r) = divmod(p, d) + if r != 0: + raise ValueError("No solution could be found") + + assert p == n * d + return n + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/Util/_number_new.pyo b/panda/python/Lib/site-packages/Crypto/Util/_number_new.pyo new file mode 100644 index 0000000000000000000000000000000000000000..1754e2ec5cfdf2ece0e87a63953f4e4f40d96786 GIT binary patch literal 3460 zcmcImZEsXX6h3ozyKR@2Rs_VC=)~}{R9a{?QHfL{F9`{$<`yN^HJiKl&TcQgJ9n9x z+pXbnQg1q)N#cb;oE8ni?hJlm)aFkP7GqW+&+NWRf-lGHWAM z9jf|J#XI&pm^%=pd(sYyy^>As+~I-j-Lc!m9{LL9x4 z9CdYcVwGksyPkHOn-~p~bkj{@(8==Lw0OiT)vYLYtt{^@`N?vK$@DM$R#L2>G+-eh z8Y~=(xtNs|G!D!KH2VXDBf8^PxPUqV-3w^Sp7L73`*yVEIyr;}sw(feC+NnQ?~7p{ zyAMNqR}e=fpgV$=5$Yq`=;Dxo&YSOiPtd2(zqZO+^jDKABEnAD-yuTf3Zo^*qoL(# zximM|J}I|Sx1JYH_Lb@6rkCojjPyVvGLgezzMrSs$=pZ|giUiTb1cPNuI)m-F7dmz zo?3~&B-cu|2hyb7bvN%r&gL}h+OnNG3)6{Ab!=2mX*Mt2x{^lOB6GZI(c4Qq-h~s3 zC(2D*$|&j0sYJrp1;5H3$2S$)7X5y19M7;{uhGmU1ek{m(R&F z(iZVLC^vEviyw@+Bl6Y|=gJ-BGbM`^w%>gZ@n~J>z1^R@xZ(!pJ z9L%%AyAkI_mdLh}oxIS=a{$nD{*KoreKQhpO31A0(>>h_B=RYj(ELYG?T~mUm=aTB zCa8%SaTu*GK<1U0*D;MhqVnG`coLg0rH~jx7Nyuvj3Y=OnAsd$11abrgYw~HaK8DF z^ciyFk3Rwx+D7Gq!Vekn#1@n+FgJV+-bV601EqQwK>G|&E$3uX78(Bsp1xlAEO+ap z8o|n5VNr3YQG$$08JxluiB)lqJQ`ILK>uxJ@_#16R+?pHHpn$hUmO-lzGU!67CKWF zMNgLHTU=$b5iXRRDU@s^suQ8^IV&$mnN=rWxT-1h=|9qfsqfjZVE8I8@#M^~^GVS6 zGI9JAKIXm8lRYDBrsQwY>_G_H$Aot=N zP9Zz6ju&kz!xd{Q)t%fOhN7&m7P!7bO|`Vh3=}zETZQ~Cg#2WLY{GFY{KbUq)eb56 o-b*X%d_nmM3XmdG%WvW!%a37A90ETa7t_Jy?Bvws_~enl0W?}1VE_OC literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Util/asn1.py b/panda/python/Lib/site-packages/Crypto/Util/asn1.py new file mode 100644 index 00000000..dd5ec31d --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Util/asn1.py @@ -0,0 +1,286 @@ +# -*- coding: ascii -*- +# +# Util/asn1.py : Minimal support for ASN.1 DER binary encoding. +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +from Crypto.Util.number import long_to_bytes, bytes_to_long +import sys +from Crypto.Util.py3compat import * + +__all__ = [ 'DerObject', 'DerInteger', 'DerOctetString', 'DerNull', 'DerSequence', 'DerObjectId' ] + +class DerObject: + """Base class for defining a single DER object. + + Instantiate this class ONLY when you have to decode a DER element. + """ + + # Known TAG types + typeTags = { 'SEQUENCE': 0x30, 'BIT STRING': 0x03, 'INTEGER': 0x02, + 'OCTET STRING': 0x04, 'NULL': 0x05, 'OBJECT IDENTIFIER': 0x06 } + + def __init__(self, ASN1Type=None, payload=b('')): + """Initialize the DER object according to a specific type. + + The ASN.1 type is either specified as the ASN.1 string (e.g. + 'SEQUENCE'), directly with its numerical tag or with no tag + at all (None).""" + if isInt(ASN1Type) or ASN1Type is None: + self.typeTag = ASN1Type + else: + if len(ASN1Type)==1: + self.typeTag = ord(ASN1Type) + else: + self.typeTag = self.typeTags.get(ASN1Type) + self.payload = payload + + def isType(self, ASN1Type): + return self.typeTags[ASN1Type]==self.typeTag + + def _lengthOctets(self, payloadLen): + """Return a byte string that encodes the given payload length (in + bytes) in a format suitable for a DER length tag (L). + """ + if payloadLen>127: + encoding = long_to_bytes(payloadLen) + return bchr(len(encoding)+128) + encoding + return bchr(payloadLen) + + def encode(self): + """Return a complete DER element, fully encoded as a TLV.""" + return bchr(self.typeTag) + self._lengthOctets(len(self.payload)) + self.payload + + def _decodeLen(self, idx, der): + """Given a (part of a) DER element, and an index to the first byte of + a DER length tag (L), return a tuple with the payload size, + and the index of the first byte of the such payload (V). + + Raises a ValueError exception if the DER length is invalid. + Raises an IndexError exception if the DER element is too short. + """ + length = bord(der[idx]) + if length<=127: + return (length,idx+1) + payloadLength = bytes_to_long(der[idx+1:idx+1+(length & 0x7F)]) + if payloadLength<=127: + raise ValueError("Not a DER length tag.") + return (payloadLength, idx+1+(length & 0x7F)) + + def decode(self, derEle, noLeftOvers=0): + """Decode a complete DER element, and re-initializes this + object with it. + + @param derEle A complete DER element. It must start with a DER T + tag. + @param noLeftOvers Indicate whether it is acceptable to complete the + parsing of the DER element and find that not all + bytes in derEle have been used. + @return Index of the first unused byte in the given DER element. + + Raises a ValueError exception in case of parsing errors. + Raises an IndexError exception if the DER element is too short. + """ + try: + self.typeTag = bord(derEle[0]) + if (self.typeTag & 0x1F)==0x1F: + raise ValueError("Unsupported DER tag") + (length,idx) = self._decodeLen(1, derEle) + if noLeftOvers and len(derEle) != (idx+length): + raise ValueError("Not a DER structure") + self.payload = derEle[idx:idx+length] + except IndexError: + raise ValueError("Not a valid DER SEQUENCE.") + return idx+length + +class DerInteger(DerObject): + def __init__(self, value = 0): + """Class to model an INTEGER DER element. + + Limitation: only non-negative values are supported. + """ + DerObject.__init__(self, 'INTEGER') + self.value = value + + def encode(self): + """Return a complete INTEGER DER element, fully encoded as a TLV.""" + self.payload = long_to_bytes(self.value) + if bord(self.payload[0])>127: + self.payload = bchr(0x00) + self.payload + return DerObject.encode(self) + + def decode(self, derEle, noLeftOvers=0): + """Decode a complete INTEGER DER element, and re-initializes this + object with it. + + @param derEle A complete INTEGER DER element. It must start with a DER + INTEGER tag. + @param noLeftOvers Indicate whether it is acceptable to complete the + parsing of the DER element and find that not all + bytes in derEle have been used. + @return Index of the first unused byte in the given DER element. + + Raises a ValueError exception if the DER element is not a + valid non-negative INTEGER. + Raises an IndexError exception if the DER element is too short. + """ + tlvLength = DerObject.decode(self, derEle, noLeftOvers) + if self.typeTag!=self.typeTags['INTEGER']: + raise ValueError ("Not a DER INTEGER.") + if bord(self.payload[0])>127: + raise ValueError ("Negative INTEGER.") + self.value = bytes_to_long(self.payload) + return tlvLength + +class DerSequence(DerObject): + """Class to model a SEQUENCE DER element. + + This object behave like a dynamic Python sequence. + Sub-elements that are INTEGERs, look like Python integers. + Any other sub-element is a binary string encoded as the complete DER + sub-element (TLV). + """ + + def __init__(self, startSeq=None): + """Initialize the SEQUENCE DER object. Always empty + initially.""" + DerObject.__init__(self, 'SEQUENCE') + if startSeq==None: + self._seq = [] + else: + self._seq = startSeq + + ## A few methods to make it behave like a python sequence + + def __delitem__(self, n): + del self._seq[n] + def __getitem__(self, n): + return self._seq[n] + def __setitem__(self, key, value): + self._seq[key] = value + def __setslice__(self,i,j,sequence): + self._seq[i:j] = sequence + def __delslice__(self,i,j): + del self._seq[i:j] + def __getslice__(self, i, j): + return self._seq[max(0, i):max(0, j)] + def __len__(self): + return len(self._seq) + def append(self, item): + return self._seq.append(item) + + def hasInts(self): + """Return the number of items in this sequence that are numbers.""" + return len(filter(isInt, self._seq)) + + def hasOnlyInts(self): + """Return True if all items in this sequence are numbers.""" + return self._seq and self.hasInts()==len(self._seq) + + def encode(self): + """Return the DER encoding for the ASN.1 SEQUENCE, containing + the non-negative integers and longs added to this object. + + Limitation: Raises a ValueError exception if it some elements + in the sequence are neither Python integers nor complete DER INTEGERs. + """ + self.payload = b('') + for item in self._seq: + try: + self.payload += item + except: + try: + self.payload += DerInteger(item).encode() + except: + raise ValueError("Trying to DER encode an unknown object") + return DerObject.encode(self) + + def decode(self, derEle, noLeftOvers=0): + """Decode a complete SEQUENCE DER element, and re-initializes this + object with it. + + @param derEle A complete SEQUENCE DER element. It must start with a DER + SEQUENCE tag. + @param noLeftOvers Indicate whether it is acceptable to complete the + parsing of the DER element and find that not all + bytes in derEle have been used. + @return Index of the first unused byte in the given DER element. + + DER INTEGERs are decoded into Python integers. Any other DER + element is not decoded. Its validity is not checked. + + Raises a ValueError exception if the DER element is not a + valid DER SEQUENCE. + Raises an IndexError exception if the DER element is too short. + """ + + self._seq = [] + try: + tlvLength = DerObject.decode(self, derEle, noLeftOvers) + if self.typeTag!=self.typeTags['SEQUENCE']: + raise ValueError("Not a DER SEQUENCE.") + # Scan one TLV at once + idx = 0 + while idxcgU>g=3WyCmz|-thHXtYp?BmsWfQQZ{ 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 literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Util/number.py b/panda/python/Lib/site-packages/Crypto/Util/number.py new file mode 100644 index 00000000..2b5beb64 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Util/number.py @@ -0,0 +1,1456 @@ +# +# number.py : Number-theoretic functions +# +# Part of the Python Cryptography Toolkit +# +# Written by Andrew M. Kuchling, Barry A. Warsaw, and others +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== +# + +__revision__ = "$Id$" + +from Crypto.pct_warnings import GetRandomNumber_DeprecationWarning, PowmInsecureWarning +from warnings import warn as _warn +import math +import sys +from Crypto.Util.py3compat import * + +bignum = long +try: + from Crypto.PublicKey import _fastmath +except ImportError: + # For production, we are going to let import issues due to gmp/mpir shared + # libraries not loading slide silently and use slowmath. If you'd rather + # see an exception raised if _fastmath exists but cannot be imported, + # uncomment the below + # + # from distutils.sysconfig import get_config_var + # import inspect, os + # _fm_path = os.path.normpath(os.path.dirname(os.path.abspath( + # inspect.getfile(inspect.currentframe()))) + # +"/../../PublicKey/_fastmath"+get_config_var("SO")) + # if os.path.exists(_fm_path): + # raise ImportError("While the _fastmath module exists, importing "+ + # "it failed. This may point to the gmp or mpir shared library "+ + # "not being in the path. _fastmath was found at "+_fm_path) + _fastmath = None + +# You need libgmp v5 or later to get mpz_powm_sec. Warn if it's not available. +if _fastmath is not None and not _fastmath.HAVE_DECL_MPZ_POWM_SEC: + _warn("Not using mpz_powm_sec. You should rebuild using libgmp >= 5 to avoid timing attack vulnerability.", PowmInsecureWarning) + +# New functions +from _number_new import * + +# Commented out and replaced with faster versions below +## def long2str(n): +## s='' +## while n>0: +## s=chr(n & 255)+s +## n=n>>8 +## return s + +## import types +## def str2long(s): +## if type(s)!=types.StringType: return s # Integers will be left alone +## return reduce(lambda x,y : x*256+ord(y), s, 0L) + +def size (N): + """size(N:long) : int + Returns the size of the number N in bits. + """ + bits = 0 + while N >> bits: + bits += 1 + return bits + +def getRandomNumber(N, randfunc=None): + """Deprecated. Use getRandomInteger or getRandomNBitInteger instead.""" + warnings.warn("Crypto.Util.number.getRandomNumber has confusing semantics"+ + "and has been deprecated. Use getRandomInteger or getRandomNBitInteger instead.", + GetRandomNumber_DeprecationWarning) + return getRandomNBitInteger(N, randfunc) + +def getRandomInteger(N, randfunc=None): + """getRandomInteger(N:int, randfunc:callable):long + Return a random number with at most N bits. + + If randfunc is omitted, then Random.new().read is used. + + This function is for internal use only and may be renamed or removed in + the future. + """ + if randfunc is None: + _import_Random() + randfunc = Random.new().read + + S = randfunc(N>>3) + odd_bits = N % 8 + if odd_bits != 0: + char = ord(randfunc(1)) >> (8-odd_bits) + S = bchr(char) + S + value = bytes_to_long(S) + return value + +def getRandomRange(a, b, randfunc=None): + """getRandomRange(a:int, b:int, randfunc:callable):long + Return a random number n so that a <= n < b. + + If randfunc is omitted, then Random.new().read is used. + + This function is for internal use only and may be renamed or removed in + the future. + """ + range_ = b - a - 1 + bits = size(range_) + value = getRandomInteger(bits, randfunc) + while value > range_: + value = getRandomInteger(bits, randfunc) + return a + value + +def getRandomNBitInteger(N, randfunc=None): + """getRandomInteger(N:int, randfunc:callable):long + Return a random number with exactly N-bits, i.e. a random number + between 2**(N-1) and (2**N)-1. + + If randfunc is omitted, then Random.new().read is used. + + This function is for internal use only and may be renamed or removed in + the future. + """ + value = getRandomInteger (N-1, randfunc) + value |= 2L ** (N-1) # Ensure high bit is set + assert size(value) >= N + return value + +def GCD(x,y): + """GCD(x:long, y:long): long + Return the GCD of x and y. + """ + x = abs(x) ; y = abs(y) + while x > 0: + x, y = y % x, x + return y + +def inverse(u, v): + """inverse(u:long, v:long):long + Return the inverse of u mod v. + """ + u3, v3 = long(u), long(v) + u1, v1 = 1L, 0L + while v3 > 0: + q=divmod(u3, v3)[0] + u1, v1 = v1, u1 - v1*q + u3, v3 = v3, u3 - v3*q + while u1<0: + u1 = u1 + v + return u1 + +# Given a number of bits to generate and a random generation function, +# find a prime number of the appropriate size. + +def getPrime(N, randfunc=None): + """getPrime(N:int, randfunc:callable):long + Return a random N-bit prime number. + + If randfunc is omitted, then Random.new().read is used. + """ + if randfunc is None: + _import_Random() + randfunc = Random.new().read + + number=getRandomNBitInteger(N, randfunc) | 1 + while (not isPrime(number, randfunc=randfunc)): + number=number+2 + return number + + +def _rabinMillerTest(n, rounds, randfunc=None): + """_rabinMillerTest(n:long, rounds:int, randfunc:callable):int + Tests if n is prime. + Returns 0 when n is definitly composite. + Returns 1 when n is probably prime. + Returns 2 when n is definitly prime. + + If randfunc is omitted, then Random.new().read is used. + + This function is for internal use only and may be renamed or removed in + the future. + """ + # check special cases (n==2, n even, n < 2) + if n < 3 or (n & 1) == 0: + return n == 2 + # n might be very large so it might be beneficial to precalculate n-1 + n_1 = n - 1 + # determine m and b so that 2**b * m = n - 1 and b maximal + b = 0 + m = n_1 + while (m & 1) == 0: + b += 1 + m >>= 1 + + tested = [] + # we need to do at most n-2 rounds. + for i in xrange (min (rounds, n-2)): + # randomly choose a < n and make sure it hasn't been tested yet + a = getRandomRange (2, n, randfunc) + while a in tested: + a = getRandomRange (2, n, randfunc) + tested.append (a) + # do the rabin-miller test + z = pow (a, m, n) # (a**m) % n + if z == 1 or z == n_1: + continue + composite = 1 + for r in xrange (b): + z = (z * z) % n + if z == 1: + return 0 + elif z == n_1: + composite = 0 + break + if composite: + return 0 + return 1 + +def getStrongPrime(N, e=0, false_positive_prob=1e-6, randfunc=None): + """getStrongPrime(N:int, e:int, false_positive_prob:float, randfunc:callable):long + Return a random strong N-bit prime number. + In this context p is a strong prime if p-1 and p+1 have at + least one large prime factor. + N should be a multiple of 128 and > 512. + + If e is provided the returned prime p-1 will be coprime to e + and thus suitable for RSA where e is the public exponent. + + The optional false_positive_prob is the statistical probability + that true is returned even though it is not (pseudo-prime). + It defaults to 1e-6 (less than 1:1000000). + Note that the real probability of a false-positive is far less. This is + just the mathematically provable limit. + + randfunc should take a single int parameter and return that + many random bytes as a string. + If randfunc is omitted, then Random.new().read is used. + """ + # This function was implemented following the + # instructions found in the paper: + # "FAST GENERATION OF RANDOM, STRONG RSA PRIMES" + # by Robert D. Silverman + # RSA Laboratories + # May 17, 1997 + # which by the time of writing could be freely downloaded here: + # http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.17.2713&rep=rep1&type=pdf + + # Use the accelerator if available + if _fastmath is not None: + return _fastmath.getStrongPrime(long(N), long(e), false_positive_prob, + randfunc) + + if (N < 512) or ((N % 128) != 0): + raise ValueError ("bits must be multiple of 128 and > 512") + + rabin_miller_rounds = int(math.ceil(-math.log(false_positive_prob)/math.log(4))) + + # calculate range for X + # lower_bound = sqrt(2) * 2^{511 + 128*x} + # upper_bound = 2^{512 + 128*x} - 1 + x = (N - 512) >> 7; + # We need to approximate the sqrt(2) in the lower_bound by an integer + # expression because floating point math overflows with these numbers + lower_bound = divmod(14142135623730950489L * (2L ** (511 + 128*x)), + 10000000000000000000L)[0] + upper_bound = (1L << (512 + 128*x)) - 1 + # Randomly choose X in calculated range + X = getRandomRange (lower_bound, upper_bound, randfunc) + + # generate p1 and p2 + p = [0, 0] + for i in (0, 1): + # randomly choose 101-bit y + y = getRandomNBitInteger (101, randfunc) + # initialize the field for sieving + field = [0] * 5 * len (sieve_base) + # sieve the field + for prime in sieve_base: + offset = y % prime + for j in xrange ((prime - offset) % prime, len (field), prime): + field[j] = 1 + + # look for suitable p[i] starting at y + result = 0 + for j in range(len(field)): + composite = field[j] + # look for next canidate + if composite: + continue + tmp = y + j + result = _rabinMillerTest (tmp, rabin_miller_rounds) + if result > 0: + p[i] = tmp + break + if result == 0: + raise RuntimeError ("Couln't find prime in field. " + "Developer: Increase field_size") + + # Calculate R + # R = (p2^{-1} mod p1) * p2 - (p1^{-1} mod p2) * p1 + tmp1 = inverse (p[1], p[0]) * p[1] # (p2^-1 mod p1)*p2 + tmp2 = inverse (p[0], p[1]) * p[0] # (p1^-1 mod p2)*p1 + R = tmp1 - tmp2 # (p2^-1 mod p1)*p2 - (p1^-1 mod p2)*p1 + + # search for final prime number starting by Y0 + # Y0 = X + (R - X mod p1p2) + increment = p[0] * p[1] + X = X + (R - (X % increment)) + while 1: + is_possible_prime = 1 + # first check candidate against sieve_base + for prime in sieve_base: + if (X % prime) == 0: + is_possible_prime = 0 + break + # if e is given make sure that e and X-1 are coprime + # this is not necessarily a strong prime criterion but useful when + # creating them for RSA where the p-1 and q-1 should be coprime to + # the public exponent e + if e and is_possible_prime: + if e & 1: + if GCD (e, X-1) != 1: + is_possible_prime = 0 + else: + if GCD (e, divmod((X-1),2)[0]) != 1: + is_possible_prime = 0 + + # do some Rabin-Miller-Tests + if is_possible_prime: + result = _rabinMillerTest (X, rabin_miller_rounds) + if result > 0: + break + X += increment + # abort when X has more bits than requested + # TODO: maybe we shouldn't abort but rather start over. + if X >= 1L << N: + raise RuntimeError ("Couln't find prime in field. " + "Developer: Increase field_size") + return X + +def isPrime(N, false_positive_prob=1e-6, randfunc=None): + """isPrime(N:long, false_positive_prob:float, randfunc:callable):bool + Return true if N is prime. + + The optional false_positive_prob is the statistical probability + that true is returned even though it is not (pseudo-prime). + It defaults to 1e-6 (less than 1:1000000). + Note that the real probability of a false-positive is far less. This is + just the mathematically provable limit. + + If randfunc is omitted, then Random.new().read is used. + """ + if _fastmath is not None: + return _fastmath.isPrime(long(N), false_positive_prob, randfunc) + + if N < 3 or N & 1 == 0: + return N == 2 + for p in sieve_base: + if N == p: + return 1 + if N % p == 0: + return 0 + + rounds = int(math.ceil(-math.log(false_positive_prob)/math.log(4))) + return _rabinMillerTest(N, rounds, randfunc) + + +# Improved conversion functions contributed by Barry Warsaw, after +# careful benchmarking + +import struct + +def long_to_bytes(n, blocksize=0): + """long_to_bytes(n:long, blocksize:int) : string + Convert a long integer to a byte string. + + If optional blocksize is given and greater than zero, pad the front of the + byte string with binary zeros so that the length is a multiple of + blocksize. + """ + # after much testing, this algorithm was deemed to be the fastest + s = b('') + n = long(n) + pack = struct.pack + while n > 0: + s = pack('>I', n & 0xffffffffL) + s + n = n >> 32 + # strip off leading zeros + for i in range(len(s)): + if s[i] != b('\000')[0]: + break + else: + # only happens when n == 0 + s = b('\000') + i = 0 + s = s[i:] + # add back some pad bytes. this could be done more efficiently w.r.t. the + # de-padding being done above, but sigh... + if blocksize > 0 and len(s) % blocksize: + s = (blocksize - len(s) % blocksize) * b('\000') + s + return s + +def bytes_to_long(s): + """bytes_to_long(string) : long + Convert a byte string to a long integer. + + This is (essentially) the inverse of long_to_bytes(). + """ + acc = 0L + unpack = struct.unpack + length = len(s) + if length % 4: + extra = (4 - length % 4) + s = b('\000') * extra + s + length = length + extra + for i in range(0, length, 4): + acc = (acc << 32) + unpack('>I', s[i:i+4])[0] + return acc + +# For backwards compatibility... +import warnings +def long2str(n, blocksize=0): + warnings.warn("long2str() has been replaced by long_to_bytes()") + return long_to_bytes(n, blocksize) +def str2long(s): + warnings.warn("str2long() has been replaced by bytes_to_long()") + return bytes_to_long(s) + +def _import_Random(): + # This is called in a function instead of at the module level in order to + # avoid problems with recursive imports + global Random, StrongRandom + from Crypto import Random + from Crypto.Random.random import StrongRandom + + + +# The first 10000 primes used for checking primality. +# This should be enough to eliminate most of the odd +# numbers before needing to do a Rabin-Miller test at all. +sieve_base = ( + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, + 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, + 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, + 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, + 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, + 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, + 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, + 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, + 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, + 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, + 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, + 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, + 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, + 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, + 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, + 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, + 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, + 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, + 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, + 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, + 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, + 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, + 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, + 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, + 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, + 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, + 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, + 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, + 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, + 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, + 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, + 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, + 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, + 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, + 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, + 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, + 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, + 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, + 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, + 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, + 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, + 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, + 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, + 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, + 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, + 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, + 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, + 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, + 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, + 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, + 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, + 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, + 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, + 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, + 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, + 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, + 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, + 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, + 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, + 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, + 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, + 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, + 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, + 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, + 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, + 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, + 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, + 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, + 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, + 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, + 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, + 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, + 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, + 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, + 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, + 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, + 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, + 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, + 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, + 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, + 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, + 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, + 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, + 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, + 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, + 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, + 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, + 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, + 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, + 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, + 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, + 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, + 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, + 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, + 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, + 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, + 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, + 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, + 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, + 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, + 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, + 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, + 8117, 8123, 8147, 8161, 8167, 8171, 8179, 8191, 8209, 8219, + 8221, 8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, + 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387, + 8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501, + 8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597, + 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, + 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, + 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, + 8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, + 8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, + 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, + 9127, 9133, 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199, + 9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, + 9293, 9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, + 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439, + 9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533, + 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631, + 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, + 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, + 9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, + 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973, 10007, + 10009, 10037, 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, + 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, 10169, 10177, + 10181, 10193, 10211, 10223, 10243, 10247, 10253, 10259, 10267, 10271, + 10273, 10289, 10301, 10303, 10313, 10321, 10331, 10333, 10337, 10343, + 10357, 10369, 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, + 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, 10559, 10567, + 10589, 10597, 10601, 10607, 10613, 10627, 10631, 10639, 10651, 10657, + 10663, 10667, 10687, 10691, 10709, 10711, 10723, 10729, 10733, 10739, + 10753, 10771, 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, + 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, 10939, 10949, + 10957, 10973, 10979, 10987, 10993, 11003, 11027, 11047, 11057, 11059, + 11069, 11071, 11083, 11087, 11093, 11113, 11117, 11119, 11131, 11149, + 11159, 11161, 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, + 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317, 11321, 11329, + 11351, 11353, 11369, 11383, 11393, 11399, 11411, 11423, 11437, 11443, + 11447, 11467, 11471, 11483, 11489, 11491, 11497, 11503, 11519, 11527, + 11549, 11551, 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, + 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, 11743, 11777, + 11779, 11783, 11789, 11801, 11807, 11813, 11821, 11827, 11831, 11833, + 11839, 11863, 11867, 11887, 11897, 11903, 11909, 11923, 11927, 11933, + 11939, 11941, 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, + 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, 12107, 12109, + 12113, 12119, 12143, 12149, 12157, 12161, 12163, 12197, 12203, 12211, + 12227, 12239, 12241, 12251, 12253, 12263, 12269, 12277, 12281, 12289, + 12301, 12323, 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, + 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473, 12479, 12487, + 12491, 12497, 12503, 12511, 12517, 12527, 12539, 12541, 12547, 12553, + 12569, 12577, 12583, 12589, 12601, 12611, 12613, 12619, 12637, 12641, + 12647, 12653, 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, + 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, 12823, 12829, + 12841, 12853, 12889, 12893, 12899, 12907, 12911, 12917, 12919, 12923, + 12941, 12953, 12959, 12967, 12973, 12979, 12983, 13001, 13003, 13007, + 13009, 13033, 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, + 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177, 13183, 13187, + 13217, 13219, 13229, 13241, 13249, 13259, 13267, 13291, 13297, 13309, + 13313, 13327, 13331, 13337, 13339, 13367, 13381, 13397, 13399, 13411, + 13417, 13421, 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, + 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597, 13613, 13619, + 13627, 13633, 13649, 13669, 13679, 13681, 13687, 13691, 13693, 13697, + 13709, 13711, 13721, 13723, 13729, 13751, 13757, 13759, 13763, 13781, + 13789, 13799, 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, + 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, 13963, 13967, + 13997, 13999, 14009, 14011, 14029, 14033, 14051, 14057, 14071, 14081, + 14083, 14087, 14107, 14143, 14149, 14153, 14159, 14173, 14177, 14197, + 14207, 14221, 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, + 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407, 14411, 14419, + 14423, 14431, 14437, 14447, 14449, 14461, 14479, 14489, 14503, 14519, + 14533, 14537, 14543, 14549, 14551, 14557, 14561, 14563, 14591, 14593, + 14621, 14627, 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, + 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, 14759, 14767, + 14771, 14779, 14783, 14797, 14813, 14821, 14827, 14831, 14843, 14851, + 14867, 14869, 14879, 14887, 14891, 14897, 14923, 14929, 14939, 14947, + 14951, 14957, 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, + 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, 15139, 15149, + 15161, 15173, 15187, 15193, 15199, 15217, 15227, 15233, 15241, 15259, + 15263, 15269, 15271, 15277, 15287, 15289, 15299, 15307, 15313, 15319, + 15329, 15331, 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, + 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, 15493, 15497, + 15511, 15527, 15541, 15551, 15559, 15569, 15581, 15583, 15601, 15607, + 15619, 15629, 15641, 15643, 15647, 15649, 15661, 15667, 15671, 15679, + 15683, 15727, 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, + 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, 15877, 15881, + 15887, 15889, 15901, 15907, 15913, 15919, 15923, 15937, 15959, 15971, + 15973, 15991, 16001, 16007, 16033, 16057, 16061, 16063, 16067, 16069, + 16073, 16087, 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, + 16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249, 16253, 16267, + 16273, 16301, 16319, 16333, 16339, 16349, 16361, 16363, 16369, 16381, + 16411, 16417, 16421, 16427, 16433, 16447, 16451, 16453, 16477, 16481, + 16487, 16493, 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, + 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661, 16673, 16691, + 16693, 16699, 16703, 16729, 16741, 16747, 16759, 16763, 16787, 16811, + 16823, 16829, 16831, 16843, 16871, 16879, 16883, 16889, 16901, 16903, + 16921, 16927, 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, + 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, 17077, 17093, + 17099, 17107, 17117, 17123, 17137, 17159, 17167, 17183, 17189, 17191, + 17203, 17207, 17209, 17231, 17239, 17257, 17291, 17293, 17299, 17317, + 17321, 17327, 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, + 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467, 17471, 17477, + 17483, 17489, 17491, 17497, 17509, 17519, 17539, 17551, 17569, 17573, + 17579, 17581, 17597, 17599, 17609, 17623, 17627, 17657, 17659, 17669, + 17681, 17683, 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, + 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863, 17881, 17891, + 17903, 17909, 17911, 17921, 17923, 17929, 17939, 17957, 17959, 17971, + 17977, 17981, 17987, 17989, 18013, 18041, 18043, 18047, 18049, 18059, + 18061, 18077, 18089, 18097, 18119, 18121, 18127, 18131, 18133, 18143, + 18149, 18169, 18181, 18191, 18199, 18211, 18217, 18223, 18229, 18233, + 18251, 18253, 18257, 18269, 18287, 18289, 18301, 18307, 18311, 18313, + 18329, 18341, 18353, 18367, 18371, 18379, 18397, 18401, 18413, 18427, + 18433, 18439, 18443, 18451, 18457, 18461, 18481, 18493, 18503, 18517, + 18521, 18523, 18539, 18541, 18553, 18583, 18587, 18593, 18617, 18637, + 18661, 18671, 18679, 18691, 18701, 18713, 18719, 18731, 18743, 18749, + 18757, 18773, 18787, 18793, 18797, 18803, 18839, 18859, 18869, 18899, + 18911, 18913, 18917, 18919, 18947, 18959, 18973, 18979, 19001, 19009, + 19013, 19031, 19037, 19051, 19069, 19073, 19079, 19081, 19087, 19121, + 19139, 19141, 19157, 19163, 19181, 19183, 19207, 19211, 19213, 19219, + 19231, 19237, 19249, 19259, 19267, 19273, 19289, 19301, 19309, 19319, + 19333, 19373, 19379, 19381, 19387, 19391, 19403, 19417, 19421, 19423, + 19427, 19429, 19433, 19441, 19447, 19457, 19463, 19469, 19471, 19477, + 19483, 19489, 19501, 19507, 19531, 19541, 19543, 19553, 19559, 19571, + 19577, 19583, 19597, 19603, 19609, 19661, 19681, 19687, 19697, 19699, + 19709, 19717, 19727, 19739, 19751, 19753, 19759, 19763, 19777, 19793, + 19801, 19813, 19819, 19841, 19843, 19853, 19861, 19867, 19889, 19891, + 19913, 19919, 19927, 19937, 19949, 19961, 19963, 19973, 19979, 19991, + 19993, 19997, 20011, 20021, 20023, 20029, 20047, 20051, 20063, 20071, + 20089, 20101, 20107, 20113, 20117, 20123, 20129, 20143, 20147, 20149, + 20161, 20173, 20177, 20183, 20201, 20219, 20231, 20233, 20249, 20261, + 20269, 20287, 20297, 20323, 20327, 20333, 20341, 20347, 20353, 20357, + 20359, 20369, 20389, 20393, 20399, 20407, 20411, 20431, 20441, 20443, + 20477, 20479, 20483, 20507, 20509, 20521, 20533, 20543, 20549, 20551, + 20563, 20593, 20599, 20611, 20627, 20639, 20641, 20663, 20681, 20693, + 20707, 20717, 20719, 20731, 20743, 20747, 20749, 20753, 20759, 20771, + 20773, 20789, 20807, 20809, 20849, 20857, 20873, 20879, 20887, 20897, + 20899, 20903, 20921, 20929, 20939, 20947, 20959, 20963, 20981, 20983, + 21001, 21011, 21013, 21017, 21019, 21023, 21031, 21059, 21061, 21067, + 21089, 21101, 21107, 21121, 21139, 21143, 21149, 21157, 21163, 21169, + 21179, 21187, 21191, 21193, 21211, 21221, 21227, 21247, 21269, 21277, + 21283, 21313, 21317, 21319, 21323, 21341, 21347, 21377, 21379, 21383, + 21391, 21397, 21401, 21407, 21419, 21433, 21467, 21481, 21487, 21491, + 21493, 21499, 21503, 21517, 21521, 21523, 21529, 21557, 21559, 21563, + 21569, 21577, 21587, 21589, 21599, 21601, 21611, 21613, 21617, 21647, + 21649, 21661, 21673, 21683, 21701, 21713, 21727, 21737, 21739, 21751, + 21757, 21767, 21773, 21787, 21799, 21803, 21817, 21821, 21839, 21841, + 21851, 21859, 21863, 21871, 21881, 21893, 21911, 21929, 21937, 21943, + 21961, 21977, 21991, 21997, 22003, 22013, 22027, 22031, 22037, 22039, + 22051, 22063, 22067, 22073, 22079, 22091, 22093, 22109, 22111, 22123, + 22129, 22133, 22147, 22153, 22157, 22159, 22171, 22189, 22193, 22229, + 22247, 22259, 22271, 22273, 22277, 22279, 22283, 22291, 22303, 22307, + 22343, 22349, 22367, 22369, 22381, 22391, 22397, 22409, 22433, 22441, + 22447, 22453, 22469, 22481, 22483, 22501, 22511, 22531, 22541, 22543, + 22549, 22567, 22571, 22573, 22613, 22619, 22621, 22637, 22639, 22643, + 22651, 22669, 22679, 22691, 22697, 22699, 22709, 22717, 22721, 22727, + 22739, 22741, 22751, 22769, 22777, 22783, 22787, 22807, 22811, 22817, + 22853, 22859, 22861, 22871, 22877, 22901, 22907, 22921, 22937, 22943, + 22961, 22963, 22973, 22993, 23003, 23011, 23017, 23021, 23027, 23029, + 23039, 23041, 23053, 23057, 23059, 23063, 23071, 23081, 23087, 23099, + 23117, 23131, 23143, 23159, 23167, 23173, 23189, 23197, 23201, 23203, + 23209, 23227, 23251, 23269, 23279, 23291, 23293, 23297, 23311, 23321, + 23327, 23333, 23339, 23357, 23369, 23371, 23399, 23417, 23431, 23447, + 23459, 23473, 23497, 23509, 23531, 23537, 23539, 23549, 23557, 23561, + 23563, 23567, 23581, 23593, 23599, 23603, 23609, 23623, 23627, 23629, + 23633, 23663, 23669, 23671, 23677, 23687, 23689, 23719, 23741, 23743, + 23747, 23753, 23761, 23767, 23773, 23789, 23801, 23813, 23819, 23827, + 23831, 23833, 23857, 23869, 23873, 23879, 23887, 23893, 23899, 23909, + 23911, 23917, 23929, 23957, 23971, 23977, 23981, 23993, 24001, 24007, + 24019, 24023, 24029, 24043, 24049, 24061, 24071, 24077, 24083, 24091, + 24097, 24103, 24107, 24109, 24113, 24121, 24133, 24137, 24151, 24169, + 24179, 24181, 24197, 24203, 24223, 24229, 24239, 24247, 24251, 24281, + 24317, 24329, 24337, 24359, 24371, 24373, 24379, 24391, 24407, 24413, + 24419, 24421, 24439, 24443, 24469, 24473, 24481, 24499, 24509, 24517, + 24527, 24533, 24547, 24551, 24571, 24593, 24611, 24623, 24631, 24659, + 24671, 24677, 24683, 24691, 24697, 24709, 24733, 24749, 24763, 24767, + 24781, 24793, 24799, 24809, 24821, 24841, 24847, 24851, 24859, 24877, + 24889, 24907, 24917, 24919, 24923, 24943, 24953, 24967, 24971, 24977, + 24979, 24989, 25013, 25031, 25033, 25037, 25057, 25073, 25087, 25097, + 25111, 25117, 25121, 25127, 25147, 25153, 25163, 25169, 25171, 25183, + 25189, 25219, 25229, 25237, 25243, 25247, 25253, 25261, 25301, 25303, + 25307, 25309, 25321, 25339, 25343, 25349, 25357, 25367, 25373, 25391, + 25409, 25411, 25423, 25439, 25447, 25453, 25457, 25463, 25469, 25471, + 25523, 25537, 25541, 25561, 25577, 25579, 25583, 25589, 25601, 25603, + 25609, 25621, 25633, 25639, 25643, 25657, 25667, 25673, 25679, 25693, + 25703, 25717, 25733, 25741, 25747, 25759, 25763, 25771, 25793, 25799, + 25801, 25819, 25841, 25847, 25849, 25867, 25873, 25889, 25903, 25913, + 25919, 25931, 25933, 25939, 25943, 25951, 25969, 25981, 25997, 25999, + 26003, 26017, 26021, 26029, 26041, 26053, 26083, 26099, 26107, 26111, + 26113, 26119, 26141, 26153, 26161, 26171, 26177, 26183, 26189, 26203, + 26209, 26227, 26237, 26249, 26251, 26261, 26263, 26267, 26293, 26297, + 26309, 26317, 26321, 26339, 26347, 26357, 26371, 26387, 26393, 26399, + 26407, 26417, 26423, 26431, 26437, 26449, 26459, 26479, 26489, 26497, + 26501, 26513, 26539, 26557, 26561, 26573, 26591, 26597, 26627, 26633, + 26641, 26647, 26669, 26681, 26683, 26687, 26693, 26699, 26701, 26711, + 26713, 26717, 26723, 26729, 26731, 26737, 26759, 26777, 26783, 26801, + 26813, 26821, 26833, 26839, 26849, 26861, 26863, 26879, 26881, 26891, + 26893, 26903, 26921, 26927, 26947, 26951, 26953, 26959, 26981, 26987, + 26993, 27011, 27017, 27031, 27043, 27059, 27061, 27067, 27073, 27077, + 27091, 27103, 27107, 27109, 27127, 27143, 27179, 27191, 27197, 27211, + 27239, 27241, 27253, 27259, 27271, 27277, 27281, 27283, 27299, 27329, + 27337, 27361, 27367, 27397, 27407, 27409, 27427, 27431, 27437, 27449, + 27457, 27479, 27481, 27487, 27509, 27527, 27529, 27539, 27541, 27551, + 27581, 27583, 27611, 27617, 27631, 27647, 27653, 27673, 27689, 27691, + 27697, 27701, 27733, 27737, 27739, 27743, 27749, 27751, 27763, 27767, + 27773, 27779, 27791, 27793, 27799, 27803, 27809, 27817, 27823, 27827, + 27847, 27851, 27883, 27893, 27901, 27917, 27919, 27941, 27943, 27947, + 27953, 27961, 27967, 27983, 27997, 28001, 28019, 28027, 28031, 28051, + 28057, 28069, 28081, 28087, 28097, 28099, 28109, 28111, 28123, 28151, + 28163, 28181, 28183, 28201, 28211, 28219, 28229, 28277, 28279, 28283, + 28289, 28297, 28307, 28309, 28319, 28349, 28351, 28387, 28393, 28403, + 28409, 28411, 28429, 28433, 28439, 28447, 28463, 28477, 28493, 28499, + 28513, 28517, 28537, 28541, 28547, 28549, 28559, 28571, 28573, 28579, + 28591, 28597, 28603, 28607, 28619, 28621, 28627, 28631, 28643, 28649, + 28657, 28661, 28663, 28669, 28687, 28697, 28703, 28711, 28723, 28729, + 28751, 28753, 28759, 28771, 28789, 28793, 28807, 28813, 28817, 28837, + 28843, 28859, 28867, 28871, 28879, 28901, 28909, 28921, 28927, 28933, + 28949, 28961, 28979, 29009, 29017, 29021, 29023, 29027, 29033, 29059, + 29063, 29077, 29101, 29123, 29129, 29131, 29137, 29147, 29153, 29167, + 29173, 29179, 29191, 29201, 29207, 29209, 29221, 29231, 29243, 29251, + 29269, 29287, 29297, 29303, 29311, 29327, 29333, 29339, 29347, 29363, + 29383, 29387, 29389, 29399, 29401, 29411, 29423, 29429, 29437, 29443, + 29453, 29473, 29483, 29501, 29527, 29531, 29537, 29567, 29569, 29573, + 29581, 29587, 29599, 29611, 29629, 29633, 29641, 29663, 29669, 29671, + 29683, 29717, 29723, 29741, 29753, 29759, 29761, 29789, 29803, 29819, + 29833, 29837, 29851, 29863, 29867, 29873, 29879, 29881, 29917, 29921, + 29927, 29947, 29959, 29983, 29989, 30011, 30013, 30029, 30047, 30059, + 30071, 30089, 30091, 30097, 30103, 30109, 30113, 30119, 30133, 30137, + 30139, 30161, 30169, 30181, 30187, 30197, 30203, 30211, 30223, 30241, + 30253, 30259, 30269, 30271, 30293, 30307, 30313, 30319, 30323, 30341, + 30347, 30367, 30389, 30391, 30403, 30427, 30431, 30449, 30467, 30469, + 30491, 30493, 30497, 30509, 30517, 30529, 30539, 30553, 30557, 30559, + 30577, 30593, 30631, 30637, 30643, 30649, 30661, 30671, 30677, 30689, + 30697, 30703, 30707, 30713, 30727, 30757, 30763, 30773, 30781, 30803, + 30809, 30817, 30829, 30839, 30841, 30851, 30853, 30859, 30869, 30871, + 30881, 30893, 30911, 30931, 30937, 30941, 30949, 30971, 30977, 30983, + 31013, 31019, 31033, 31039, 31051, 31063, 31069, 31079, 31081, 31091, + 31121, 31123, 31139, 31147, 31151, 31153, 31159, 31177, 31181, 31183, + 31189, 31193, 31219, 31223, 31231, 31237, 31247, 31249, 31253, 31259, + 31267, 31271, 31277, 31307, 31319, 31321, 31327, 31333, 31337, 31357, + 31379, 31387, 31391, 31393, 31397, 31469, 31477, 31481, 31489, 31511, + 31513, 31517, 31531, 31541, 31543, 31547, 31567, 31573, 31583, 31601, + 31607, 31627, 31643, 31649, 31657, 31663, 31667, 31687, 31699, 31721, + 31723, 31727, 31729, 31741, 31751, 31769, 31771, 31793, 31799, 31817, + 31847, 31849, 31859, 31873, 31883, 31891, 31907, 31957, 31963, 31973, + 31981, 31991, 32003, 32009, 32027, 32029, 32051, 32057, 32059, 32063, + 32069, 32077, 32083, 32089, 32099, 32117, 32119, 32141, 32143, 32159, + 32173, 32183, 32189, 32191, 32203, 32213, 32233, 32237, 32251, 32257, + 32261, 32297, 32299, 32303, 32309, 32321, 32323, 32327, 32341, 32353, + 32359, 32363, 32369, 32371, 32377, 32381, 32401, 32411, 32413, 32423, + 32429, 32441, 32443, 32467, 32479, 32491, 32497, 32503, 32507, 32531, + 32533, 32537, 32561, 32563, 32569, 32573, 32579, 32587, 32603, 32609, + 32611, 32621, 32633, 32647, 32653, 32687, 32693, 32707, 32713, 32717, + 32719, 32749, 32771, 32779, 32783, 32789, 32797, 32801, 32803, 32831, + 32833, 32839, 32843, 32869, 32887, 32909, 32911, 32917, 32933, 32939, + 32941, 32957, 32969, 32971, 32983, 32987, 32993, 32999, 33013, 33023, + 33029, 33037, 33049, 33053, 33071, 33073, 33083, 33091, 33107, 33113, + 33119, 33149, 33151, 33161, 33179, 33181, 33191, 33199, 33203, 33211, + 33223, 33247, 33287, 33289, 33301, 33311, 33317, 33329, 33331, 33343, + 33347, 33349, 33353, 33359, 33377, 33391, 33403, 33409, 33413, 33427, + 33457, 33461, 33469, 33479, 33487, 33493, 33503, 33521, 33529, 33533, + 33547, 33563, 33569, 33577, 33581, 33587, 33589, 33599, 33601, 33613, + 33617, 33619, 33623, 33629, 33637, 33641, 33647, 33679, 33703, 33713, + 33721, 33739, 33749, 33751, 33757, 33767, 33769, 33773, 33791, 33797, + 33809, 33811, 33827, 33829, 33851, 33857, 33863, 33871, 33889, 33893, + 33911, 33923, 33931, 33937, 33941, 33961, 33967, 33997, 34019, 34031, + 34033, 34039, 34057, 34061, 34123, 34127, 34129, 34141, 34147, 34157, + 34159, 34171, 34183, 34211, 34213, 34217, 34231, 34253, 34259, 34261, + 34267, 34273, 34283, 34297, 34301, 34303, 34313, 34319, 34327, 34337, + 34351, 34361, 34367, 34369, 34381, 34403, 34421, 34429, 34439, 34457, + 34469, 34471, 34483, 34487, 34499, 34501, 34511, 34513, 34519, 34537, + 34543, 34549, 34583, 34589, 34591, 34603, 34607, 34613, 34631, 34649, + 34651, 34667, 34673, 34679, 34687, 34693, 34703, 34721, 34729, 34739, + 34747, 34757, 34759, 34763, 34781, 34807, 34819, 34841, 34843, 34847, + 34849, 34871, 34877, 34883, 34897, 34913, 34919, 34939, 34949, 34961, + 34963, 34981, 35023, 35027, 35051, 35053, 35059, 35069, 35081, 35083, + 35089, 35099, 35107, 35111, 35117, 35129, 35141, 35149, 35153, 35159, + 35171, 35201, 35221, 35227, 35251, 35257, 35267, 35279, 35281, 35291, + 35311, 35317, 35323, 35327, 35339, 35353, 35363, 35381, 35393, 35401, + 35407, 35419, 35423, 35437, 35447, 35449, 35461, 35491, 35507, 35509, + 35521, 35527, 35531, 35533, 35537, 35543, 35569, 35573, 35591, 35593, + 35597, 35603, 35617, 35671, 35677, 35729, 35731, 35747, 35753, 35759, + 35771, 35797, 35801, 35803, 35809, 35831, 35837, 35839, 35851, 35863, + 35869, 35879, 35897, 35899, 35911, 35923, 35933, 35951, 35963, 35969, + 35977, 35983, 35993, 35999, 36007, 36011, 36013, 36017, 36037, 36061, + 36067, 36073, 36083, 36097, 36107, 36109, 36131, 36137, 36151, 36161, + 36187, 36191, 36209, 36217, 36229, 36241, 36251, 36263, 36269, 36277, + 36293, 36299, 36307, 36313, 36319, 36341, 36343, 36353, 36373, 36383, + 36389, 36433, 36451, 36457, 36467, 36469, 36473, 36479, 36493, 36497, + 36523, 36527, 36529, 36541, 36551, 36559, 36563, 36571, 36583, 36587, + 36599, 36607, 36629, 36637, 36643, 36653, 36671, 36677, 36683, 36691, + 36697, 36709, 36713, 36721, 36739, 36749, 36761, 36767, 36779, 36781, + 36787, 36791, 36793, 36809, 36821, 36833, 36847, 36857, 36871, 36877, + 36887, 36899, 36901, 36913, 36919, 36923, 36929, 36931, 36943, 36947, + 36973, 36979, 36997, 37003, 37013, 37019, 37021, 37039, 37049, 37057, + 37061, 37087, 37097, 37117, 37123, 37139, 37159, 37171, 37181, 37189, + 37199, 37201, 37217, 37223, 37243, 37253, 37273, 37277, 37307, 37309, + 37313, 37321, 37337, 37339, 37357, 37361, 37363, 37369, 37379, 37397, + 37409, 37423, 37441, 37447, 37463, 37483, 37489, 37493, 37501, 37507, + 37511, 37517, 37529, 37537, 37547, 37549, 37561, 37567, 37571, 37573, + 37579, 37589, 37591, 37607, 37619, 37633, 37643, 37649, 37657, 37663, + 37691, 37693, 37699, 37717, 37747, 37781, 37783, 37799, 37811, 37813, + 37831, 37847, 37853, 37861, 37871, 37879, 37889, 37897, 37907, 37951, + 37957, 37963, 37967, 37987, 37991, 37993, 37997, 38011, 38039, 38047, + 38053, 38069, 38083, 38113, 38119, 38149, 38153, 38167, 38177, 38183, + 38189, 38197, 38201, 38219, 38231, 38237, 38239, 38261, 38273, 38281, + 38287, 38299, 38303, 38317, 38321, 38327, 38329, 38333, 38351, 38371, + 38377, 38393, 38431, 38447, 38449, 38453, 38459, 38461, 38501, 38543, + 38557, 38561, 38567, 38569, 38593, 38603, 38609, 38611, 38629, 38639, + 38651, 38653, 38669, 38671, 38677, 38693, 38699, 38707, 38711, 38713, + 38723, 38729, 38737, 38747, 38749, 38767, 38783, 38791, 38803, 38821, + 38833, 38839, 38851, 38861, 38867, 38873, 38891, 38903, 38917, 38921, + 38923, 38933, 38953, 38959, 38971, 38977, 38993, 39019, 39023, 39041, + 39043, 39047, 39079, 39089, 39097, 39103, 39107, 39113, 39119, 39133, + 39139, 39157, 39161, 39163, 39181, 39191, 39199, 39209, 39217, 39227, + 39229, 39233, 39239, 39241, 39251, 39293, 39301, 39313, 39317, 39323, + 39341, 39343, 39359, 39367, 39371, 39373, 39383, 39397, 39409, 39419, + 39439, 39443, 39451, 39461, 39499, 39503, 39509, 39511, 39521, 39541, + 39551, 39563, 39569, 39581, 39607, 39619, 39623, 39631, 39659, 39667, + 39671, 39679, 39703, 39709, 39719, 39727, 39733, 39749, 39761, 39769, + 39779, 39791, 39799, 39821, 39827, 39829, 39839, 39841, 39847, 39857, + 39863, 39869, 39877, 39883, 39887, 39901, 39929, 39937, 39953, 39971, + 39979, 39983, 39989, 40009, 40013, 40031, 40037, 40039, 40063, 40087, + 40093, 40099, 40111, 40123, 40127, 40129, 40151, 40153, 40163, 40169, + 40177, 40189, 40193, 40213, 40231, 40237, 40241, 40253, 40277, 40283, + 40289, 40343, 40351, 40357, 40361, 40387, 40423, 40427, 40429, 40433, + 40459, 40471, 40483, 40487, 40493, 40499, 40507, 40519, 40529, 40531, + 40543, 40559, 40577, 40583, 40591, 40597, 40609, 40627, 40637, 40639, + 40693, 40697, 40699, 40709, 40739, 40751, 40759, 40763, 40771, 40787, + 40801, 40813, 40819, 40823, 40829, 40841, 40847, 40849, 40853, 40867, + 40879, 40883, 40897, 40903, 40927, 40933, 40939, 40949, 40961, 40973, + 40993, 41011, 41017, 41023, 41039, 41047, 41051, 41057, 41077, 41081, + 41113, 41117, 41131, 41141, 41143, 41149, 41161, 41177, 41179, 41183, + 41189, 41201, 41203, 41213, 41221, 41227, 41231, 41233, 41243, 41257, + 41263, 41269, 41281, 41299, 41333, 41341, 41351, 41357, 41381, 41387, + 41389, 41399, 41411, 41413, 41443, 41453, 41467, 41479, 41491, 41507, + 41513, 41519, 41521, 41539, 41543, 41549, 41579, 41593, 41597, 41603, + 41609, 41611, 41617, 41621, 41627, 41641, 41647, 41651, 41659, 41669, + 41681, 41687, 41719, 41729, 41737, 41759, 41761, 41771, 41777, 41801, + 41809, 41813, 41843, 41849, 41851, 41863, 41879, 41887, 41893, 41897, + 41903, 41911, 41927, 41941, 41947, 41953, 41957, 41959, 41969, 41981, + 41983, 41999, 42013, 42017, 42019, 42023, 42043, 42061, 42071, 42073, + 42083, 42089, 42101, 42131, 42139, 42157, 42169, 42179, 42181, 42187, + 42193, 42197, 42209, 42221, 42223, 42227, 42239, 42257, 42281, 42283, + 42293, 42299, 42307, 42323, 42331, 42337, 42349, 42359, 42373, 42379, + 42391, 42397, 42403, 42407, 42409, 42433, 42437, 42443, 42451, 42457, + 42461, 42463, 42467, 42473, 42487, 42491, 42499, 42509, 42533, 42557, + 42569, 42571, 42577, 42589, 42611, 42641, 42643, 42649, 42667, 42677, + 42683, 42689, 42697, 42701, 42703, 42709, 42719, 42727, 42737, 42743, + 42751, 42767, 42773, 42787, 42793, 42797, 42821, 42829, 42839, 42841, + 42853, 42859, 42863, 42899, 42901, 42923, 42929, 42937, 42943, 42953, + 42961, 42967, 42979, 42989, 43003, 43013, 43019, 43037, 43049, 43051, + 43063, 43067, 43093, 43103, 43117, 43133, 43151, 43159, 43177, 43189, + 43201, 43207, 43223, 43237, 43261, 43271, 43283, 43291, 43313, 43319, + 43321, 43331, 43391, 43397, 43399, 43403, 43411, 43427, 43441, 43451, + 43457, 43481, 43487, 43499, 43517, 43541, 43543, 43573, 43577, 43579, + 43591, 43597, 43607, 43609, 43613, 43627, 43633, 43649, 43651, 43661, + 43669, 43691, 43711, 43717, 43721, 43753, 43759, 43777, 43781, 43783, + 43787, 43789, 43793, 43801, 43853, 43867, 43889, 43891, 43913, 43933, + 43943, 43951, 43961, 43963, 43969, 43973, 43987, 43991, 43997, 44017, + 44021, 44027, 44029, 44041, 44053, 44059, 44071, 44087, 44089, 44101, + 44111, 44119, 44123, 44129, 44131, 44159, 44171, 44179, 44189, 44201, + 44203, 44207, 44221, 44249, 44257, 44263, 44267, 44269, 44273, 44279, + 44281, 44293, 44351, 44357, 44371, 44381, 44383, 44389, 44417, 44449, + 44453, 44483, 44491, 44497, 44501, 44507, 44519, 44531, 44533, 44537, + 44543, 44549, 44563, 44579, 44587, 44617, 44621, 44623, 44633, 44641, + 44647, 44651, 44657, 44683, 44687, 44699, 44701, 44711, 44729, 44741, + 44753, 44771, 44773, 44777, 44789, 44797, 44809, 44819, 44839, 44843, + 44851, 44867, 44879, 44887, 44893, 44909, 44917, 44927, 44939, 44953, + 44959, 44963, 44971, 44983, 44987, 45007, 45013, 45053, 45061, 45077, + 45083, 45119, 45121, 45127, 45131, 45137, 45139, 45161, 45179, 45181, + 45191, 45197, 45233, 45247, 45259, 45263, 45281, 45289, 45293, 45307, + 45317, 45319, 45329, 45337, 45341, 45343, 45361, 45377, 45389, 45403, + 45413, 45427, 45433, 45439, 45481, 45491, 45497, 45503, 45523, 45533, + 45541, 45553, 45557, 45569, 45587, 45589, 45599, 45613, 45631, 45641, + 45659, 45667, 45673, 45677, 45691, 45697, 45707, 45737, 45751, 45757, + 45763, 45767, 45779, 45817, 45821, 45823, 45827, 45833, 45841, 45853, + 45863, 45869, 45887, 45893, 45943, 45949, 45953, 45959, 45971, 45979, + 45989, 46021, 46027, 46049, 46051, 46061, 46073, 46091, 46093, 46099, + 46103, 46133, 46141, 46147, 46153, 46171, 46181, 46183, 46187, 46199, + 46219, 46229, 46237, 46261, 46271, 46273, 46279, 46301, 46307, 46309, + 46327, 46337, 46349, 46351, 46381, 46399, 46411, 46439, 46441, 46447, + 46451, 46457, 46471, 46477, 46489, 46499, 46507, 46511, 46523, 46549, + 46559, 46567, 46573, 46589, 46591, 46601, 46619, 46633, 46639, 46643, + 46649, 46663, 46679, 46681, 46687, 46691, 46703, 46723, 46727, 46747, + 46751, 46757, 46769, 46771, 46807, 46811, 46817, 46819, 46829, 46831, + 46853, 46861, 46867, 46877, 46889, 46901, 46919, 46933, 46957, 46993, + 46997, 47017, 47041, 47051, 47057, 47059, 47087, 47093, 47111, 47119, + 47123, 47129, 47137, 47143, 47147, 47149, 47161, 47189, 47207, 47221, + 47237, 47251, 47269, 47279, 47287, 47293, 47297, 47303, 47309, 47317, + 47339, 47351, 47353, 47363, 47381, 47387, 47389, 47407, 47417, 47419, + 47431, 47441, 47459, 47491, 47497, 47501, 47507, 47513, 47521, 47527, + 47533, 47543, 47563, 47569, 47581, 47591, 47599, 47609, 47623, 47629, + 47639, 47653, 47657, 47659, 47681, 47699, 47701, 47711, 47713, 47717, + 47737, 47741, 47743, 47777, 47779, 47791, 47797, 47807, 47809, 47819, + 47837, 47843, 47857, 47869, 47881, 47903, 47911, 47917, 47933, 47939, + 47947, 47951, 47963, 47969, 47977, 47981, 48017, 48023, 48029, 48049, + 48073, 48079, 48091, 48109, 48119, 48121, 48131, 48157, 48163, 48179, + 48187, 48193, 48197, 48221, 48239, 48247, 48259, 48271, 48281, 48299, + 48311, 48313, 48337, 48341, 48353, 48371, 48383, 48397, 48407, 48409, + 48413, 48437, 48449, 48463, 48473, 48479, 48481, 48487, 48491, 48497, + 48523, 48527, 48533, 48539, 48541, 48563, 48571, 48589, 48593, 48611, + 48619, 48623, 48647, 48649, 48661, 48673, 48677, 48679, 48731, 48733, + 48751, 48757, 48761, 48767, 48779, 48781, 48787, 48799, 48809, 48817, + 48821, 48823, 48847, 48857, 48859, 48869, 48871, 48883, 48889, 48907, + 48947, 48953, 48973, 48989, 48991, 49003, 49009, 49019, 49031, 49033, + 49037, 49043, 49057, 49069, 49081, 49103, 49109, 49117, 49121, 49123, + 49139, 49157, 49169, 49171, 49177, 49193, 49199, 49201, 49207, 49211, + 49223, 49253, 49261, 49277, 49279, 49297, 49307, 49331, 49333, 49339, + 49363, 49367, 49369, 49391, 49393, 49409, 49411, 49417, 49429, 49433, + 49451, 49459, 49463, 49477, 49481, 49499, 49523, 49529, 49531, 49537, + 49547, 49549, 49559, 49597, 49603, 49613, 49627, 49633, 49639, 49663, + 49667, 49669, 49681, 49697, 49711, 49727, 49739, 49741, 49747, 49757, + 49783, 49787, 49789, 49801, 49807, 49811, 49823, 49831, 49843, 49853, + 49871, 49877, 49891, 49919, 49921, 49927, 49937, 49939, 49943, 49957, + 49991, 49993, 49999, 50021, 50023, 50033, 50047, 50051, 50053, 50069, + 50077, 50087, 50093, 50101, 50111, 50119, 50123, 50129, 50131, 50147, + 50153, 50159, 50177, 50207, 50221, 50227, 50231, 50261, 50263, 50273, + 50287, 50291, 50311, 50321, 50329, 50333, 50341, 50359, 50363, 50377, + 50383, 50387, 50411, 50417, 50423, 50441, 50459, 50461, 50497, 50503, + 50513, 50527, 50539, 50543, 50549, 50551, 50581, 50587, 50591, 50593, + 50599, 50627, 50647, 50651, 50671, 50683, 50707, 50723, 50741, 50753, + 50767, 50773, 50777, 50789, 50821, 50833, 50839, 50849, 50857, 50867, + 50873, 50891, 50893, 50909, 50923, 50929, 50951, 50957, 50969, 50971, + 50989, 50993, 51001, 51031, 51043, 51047, 51059, 51061, 51071, 51109, + 51131, 51133, 51137, 51151, 51157, 51169, 51193, 51197, 51199, 51203, + 51217, 51229, 51239, 51241, 51257, 51263, 51283, 51287, 51307, 51329, + 51341, 51343, 51347, 51349, 51361, 51383, 51407, 51413, 51419, 51421, + 51427, 51431, 51437, 51439, 51449, 51461, 51473, 51479, 51481, 51487, + 51503, 51511, 51517, 51521, 51539, 51551, 51563, 51577, 51581, 51593, + 51599, 51607, 51613, 51631, 51637, 51647, 51659, 51673, 51679, 51683, + 51691, 51713, 51719, 51721, 51749, 51767, 51769, 51787, 51797, 51803, + 51817, 51827, 51829, 51839, 51853, 51859, 51869, 51871, 51893, 51899, + 51907, 51913, 51929, 51941, 51949, 51971, 51973, 51977, 51991, 52009, + 52021, 52027, 52051, 52057, 52067, 52069, 52081, 52103, 52121, 52127, + 52147, 52153, 52163, 52177, 52181, 52183, 52189, 52201, 52223, 52237, + 52249, 52253, 52259, 52267, 52289, 52291, 52301, 52313, 52321, 52361, + 52363, 52369, 52379, 52387, 52391, 52433, 52453, 52457, 52489, 52501, + 52511, 52517, 52529, 52541, 52543, 52553, 52561, 52567, 52571, 52579, + 52583, 52609, 52627, 52631, 52639, 52667, 52673, 52691, 52697, 52709, + 52711, 52721, 52727, 52733, 52747, 52757, 52769, 52783, 52807, 52813, + 52817, 52837, 52859, 52861, 52879, 52883, 52889, 52901, 52903, 52919, + 52937, 52951, 52957, 52963, 52967, 52973, 52981, 52999, 53003, 53017, + 53047, 53051, 53069, 53077, 53087, 53089, 53093, 53101, 53113, 53117, + 53129, 53147, 53149, 53161, 53171, 53173, 53189, 53197, 53201, 53231, + 53233, 53239, 53267, 53269, 53279, 53281, 53299, 53309, 53323, 53327, + 53353, 53359, 53377, 53381, 53401, 53407, 53411, 53419, 53437, 53441, + 53453, 53479, 53503, 53507, 53527, 53549, 53551, 53569, 53591, 53593, + 53597, 53609, 53611, 53617, 53623, 53629, 53633, 53639, 53653, 53657, + 53681, 53693, 53699, 53717, 53719, 53731, 53759, 53773, 53777, 53783, + 53791, 53813, 53819, 53831, 53849, 53857, 53861, 53881, 53887, 53891, + 53897, 53899, 53917, 53923, 53927, 53939, 53951, 53959, 53987, 53993, + 54001, 54011, 54013, 54037, 54049, 54059, 54083, 54091, 54101, 54121, + 54133, 54139, 54151, 54163, 54167, 54181, 54193, 54217, 54251, 54269, + 54277, 54287, 54293, 54311, 54319, 54323, 54331, 54347, 54361, 54367, + 54371, 54377, 54401, 54403, 54409, 54413, 54419, 54421, 54437, 54443, + 54449, 54469, 54493, 54497, 54499, 54503, 54517, 54521, 54539, 54541, + 54547, 54559, 54563, 54577, 54581, 54583, 54601, 54617, 54623, 54629, + 54631, 54647, 54667, 54673, 54679, 54709, 54713, 54721, 54727, 54751, + 54767, 54773, 54779, 54787, 54799, 54829, 54833, 54851, 54869, 54877, + 54881, 54907, 54917, 54919, 54941, 54949, 54959, 54973, 54979, 54983, + 55001, 55009, 55021, 55049, 55051, 55057, 55061, 55073, 55079, 55103, + 55109, 55117, 55127, 55147, 55163, 55171, 55201, 55207, 55213, 55217, + 55219, 55229, 55243, 55249, 55259, 55291, 55313, 55331, 55333, 55337, + 55339, 55343, 55351, 55373, 55381, 55399, 55411, 55439, 55441, 55457, + 55469, 55487, 55501, 55511, 55529, 55541, 55547, 55579, 55589, 55603, + 55609, 55619, 55621, 55631, 55633, 55639, 55661, 55663, 55667, 55673, + 55681, 55691, 55697, 55711, 55717, 55721, 55733, 55763, 55787, 55793, + 55799, 55807, 55813, 55817, 55819, 55823, 55829, 55837, 55843, 55849, + 55871, 55889, 55897, 55901, 55903, 55921, 55927, 55931, 55933, 55949, + 55967, 55987, 55997, 56003, 56009, 56039, 56041, 56053, 56081, 56087, + 56093, 56099, 56101, 56113, 56123, 56131, 56149, 56167, 56171, 56179, + 56197, 56207, 56209, 56237, 56239, 56249, 56263, 56267, 56269, 56299, + 56311, 56333, 56359, 56369, 56377, 56383, 56393, 56401, 56417, 56431, + 56437, 56443, 56453, 56467, 56473, 56477, 56479, 56489, 56501, 56503, + 56509, 56519, 56527, 56531, 56533, 56543, 56569, 56591, 56597, 56599, + 56611, 56629, 56633, 56659, 56663, 56671, 56681, 56687, 56701, 56711, + 56713, 56731, 56737, 56747, 56767, 56773, 56779, 56783, 56807, 56809, + 56813, 56821, 56827, 56843, 56857, 56873, 56891, 56893, 56897, 56909, + 56911, 56921, 56923, 56929, 56941, 56951, 56957, 56963, 56983, 56989, + 56993, 56999, 57037, 57041, 57047, 57059, 57073, 57077, 57089, 57097, + 57107, 57119, 57131, 57139, 57143, 57149, 57163, 57173, 57179, 57191, + 57193, 57203, 57221, 57223, 57241, 57251, 57259, 57269, 57271, 57283, + 57287, 57301, 57329, 57331, 57347, 57349, 57367, 57373, 57383, 57389, + 57397, 57413, 57427, 57457, 57467, 57487, 57493, 57503, 57527, 57529, + 57557, 57559, 57571, 57587, 57593, 57601, 57637, 57641, 57649, 57653, + 57667, 57679, 57689, 57697, 57709, 57713, 57719, 57727, 57731, 57737, + 57751, 57773, 57781, 57787, 57791, 57793, 57803, 57809, 57829, 57839, + 57847, 57853, 57859, 57881, 57899, 57901, 57917, 57923, 57943, 57947, + 57973, 57977, 57991, 58013, 58027, 58031, 58043, 58049, 58057, 58061, + 58067, 58073, 58099, 58109, 58111, 58129, 58147, 58151, 58153, 58169, + 58171, 58189, 58193, 58199, 58207, 58211, 58217, 58229, 58231, 58237, + 58243, 58271, 58309, 58313, 58321, 58337, 58363, 58367, 58369, 58379, + 58391, 58393, 58403, 58411, 58417, 58427, 58439, 58441, 58451, 58453, + 58477, 58481, 58511, 58537, 58543, 58549, 58567, 58573, 58579, 58601, + 58603, 58613, 58631, 58657, 58661, 58679, 58687, 58693, 58699, 58711, + 58727, 58733, 58741, 58757, 58763, 58771, 58787, 58789, 58831, 58889, + 58897, 58901, 58907, 58909, 58913, 58921, 58937, 58943, 58963, 58967, + 58979, 58991, 58997, 59009, 59011, 59021, 59023, 59029, 59051, 59053, + 59063, 59069, 59077, 59083, 59093, 59107, 59113, 59119, 59123, 59141, + 59149, 59159, 59167, 59183, 59197, 59207, 59209, 59219, 59221, 59233, + 59239, 59243, 59263, 59273, 59281, 59333, 59341, 59351, 59357, 59359, + 59369, 59377, 59387, 59393, 59399, 59407, 59417, 59419, 59441, 59443, + 59447, 59453, 59467, 59471, 59473, 59497, 59509, 59513, 59539, 59557, + 59561, 59567, 59581, 59611, 59617, 59621, 59627, 59629, 59651, 59659, + 59663, 59669, 59671, 59693, 59699, 59707, 59723, 59729, 59743, 59747, + 59753, 59771, 59779, 59791, 59797, 59809, 59833, 59863, 59879, 59887, + 59921, 59929, 59951, 59957, 59971, 59981, 59999, 60013, 60017, 60029, + 60037, 60041, 60077, 60083, 60089, 60091, 60101, 60103, 60107, 60127, + 60133, 60139, 60149, 60161, 60167, 60169, 60209, 60217, 60223, 60251, + 60257, 60259, 60271, 60289, 60293, 60317, 60331, 60337, 60343, 60353, + 60373, 60383, 60397, 60413, 60427, 60443, 60449, 60457, 60493, 60497, + 60509, 60521, 60527, 60539, 60589, 60601, 60607, 60611, 60617, 60623, + 60631, 60637, 60647, 60649, 60659, 60661, 60679, 60689, 60703, 60719, + 60727, 60733, 60737, 60757, 60761, 60763, 60773, 60779, 60793, 60811, + 60821, 60859, 60869, 60887, 60889, 60899, 60901, 60913, 60917, 60919, + 60923, 60937, 60943, 60953, 60961, 61001, 61007, 61027, 61031, 61043, + 61051, 61057, 61091, 61099, 61121, 61129, 61141, 61151, 61153, 61169, + 61211, 61223, 61231, 61253, 61261, 61283, 61291, 61297, 61331, 61333, + 61339, 61343, 61357, 61363, 61379, 61381, 61403, 61409, 61417, 61441, + 61463, 61469, 61471, 61483, 61487, 61493, 61507, 61511, 61519, 61543, + 61547, 61553, 61559, 61561, 61583, 61603, 61609, 61613, 61627, 61631, + 61637, 61643, 61651, 61657, 61667, 61673, 61681, 61687, 61703, 61717, + 61723, 61729, 61751, 61757, 61781, 61813, 61819, 61837, 61843, 61861, + 61871, 61879, 61909, 61927, 61933, 61949, 61961, 61967, 61979, 61981, + 61987, 61991, 62003, 62011, 62017, 62039, 62047, 62053, 62057, 62071, + 62081, 62099, 62119, 62129, 62131, 62137, 62141, 62143, 62171, 62189, + 62191, 62201, 62207, 62213, 62219, 62233, 62273, 62297, 62299, 62303, + 62311, 62323, 62327, 62347, 62351, 62383, 62401, 62417, 62423, 62459, + 62467, 62473, 62477, 62483, 62497, 62501, 62507, 62533, 62539, 62549, + 62563, 62581, 62591, 62597, 62603, 62617, 62627, 62633, 62639, 62653, + 62659, 62683, 62687, 62701, 62723, 62731, 62743, 62753, 62761, 62773, + 62791, 62801, 62819, 62827, 62851, 62861, 62869, 62873, 62897, 62903, + 62921, 62927, 62929, 62939, 62969, 62971, 62981, 62983, 62987, 62989, + 63029, 63031, 63059, 63067, 63073, 63079, 63097, 63103, 63113, 63127, + 63131, 63149, 63179, 63197, 63199, 63211, 63241, 63247, 63277, 63281, + 63299, 63311, 63313, 63317, 63331, 63337, 63347, 63353, 63361, 63367, + 63377, 63389, 63391, 63397, 63409, 63419, 63421, 63439, 63443, 63463, + 63467, 63473, 63487, 63493, 63499, 63521, 63527, 63533, 63541, 63559, + 63577, 63587, 63589, 63599, 63601, 63607, 63611, 63617, 63629, 63647, + 63649, 63659, 63667, 63671, 63689, 63691, 63697, 63703, 63709, 63719, + 63727, 63737, 63743, 63761, 63773, 63781, 63793, 63799, 63803, 63809, + 63823, 63839, 63841, 63853, 63857, 63863, 63901, 63907, 63913, 63929, + 63949, 63977, 63997, 64007, 64013, 64019, 64033, 64037, 64063, 64067, + 64081, 64091, 64109, 64123, 64151, 64153, 64157, 64171, 64187, 64189, + 64217, 64223, 64231, 64237, 64271, 64279, 64283, 64301, 64303, 64319, + 64327, 64333, 64373, 64381, 64399, 64403, 64433, 64439, 64451, 64453, + 64483, 64489, 64499, 64513, 64553, 64567, 64577, 64579, 64591, 64601, + 64609, 64613, 64621, 64627, 64633, 64661, 64663, 64667, 64679, 64693, + 64709, 64717, 64747, 64763, 64781, 64783, 64793, 64811, 64817, 64849, + 64853, 64871, 64877, 64879, 64891, 64901, 64919, 64921, 64927, 64937, + 64951, 64969, 64997, 65003, 65011, 65027, 65029, 65033, 65053, 65063, + 65071, 65089, 65099, 65101, 65111, 65119, 65123, 65129, 65141, 65147, + 65167, 65171, 65173, 65179, 65183, 65203, 65213, 65239, 65257, 65267, + 65269, 65287, 65293, 65309, 65323, 65327, 65353, 65357, 65371, 65381, + 65393, 65407, 65413, 65419, 65423, 65437, 65447, 65449, 65479, 65497, + 65519, 65521, 65537, 65539, 65543, 65551, 65557, 65563, 65579, 65581, + 65587, 65599, 65609, 65617, 65629, 65633, 65647, 65651, 65657, 65677, + 65687, 65699, 65701, 65707, 65713, 65717, 65719, 65729, 65731, 65761, + 65777, 65789, 65809, 65827, 65831, 65837, 65839, 65843, 65851, 65867, + 65881, 65899, 65921, 65927, 65929, 65951, 65957, 65963, 65981, 65983, + 65993, 66029, 66037, 66041, 66047, 66067, 66071, 66083, 66089, 66103, + 66107, 66109, 66137, 66161, 66169, 66173, 66179, 66191, 66221, 66239, + 66271, 66293, 66301, 66337, 66343, 66347, 66359, 66361, 66373, 66377, + 66383, 66403, 66413, 66431, 66449, 66457, 66463, 66467, 66491, 66499, + 66509, 66523, 66529, 66533, 66541, 66553, 66569, 66571, 66587, 66593, + 66601, 66617, 66629, 66643, 66653, 66683, 66697, 66701, 66713, 66721, + 66733, 66739, 66749, 66751, 66763, 66791, 66797, 66809, 66821, 66841, + 66851, 66853, 66863, 66877, 66883, 66889, 66919, 66923, 66931, 66943, + 66947, 66949, 66959, 66973, 66977, 67003, 67021, 67033, 67043, 67049, + 67057, 67061, 67073, 67079, 67103, 67121, 67129, 67139, 67141, 67153, + 67157, 67169, 67181, 67187, 67189, 67211, 67213, 67217, 67219, 67231, + 67247, 67261, 67271, 67273, 67289, 67307, 67339, 67343, 67349, 67369, + 67391, 67399, 67409, 67411, 67421, 67427, 67429, 67433, 67447, 67453, + 67477, 67481, 67489, 67493, 67499, 67511, 67523, 67531, 67537, 67547, + 67559, 67567, 67577, 67579, 67589, 67601, 67607, 67619, 67631, 67651, + 67679, 67699, 67709, 67723, 67733, 67741, 67751, 67757, 67759, 67763, + 67777, 67783, 67789, 67801, 67807, 67819, 67829, 67843, 67853, 67867, + 67883, 67891, 67901, 67927, 67931, 67933, 67939, 67943, 67957, 67961, + 67967, 67979, 67987, 67993, 68023, 68041, 68053, 68059, 68071, 68087, + 68099, 68111, 68113, 68141, 68147, 68161, 68171, 68207, 68209, 68213, + 68219, 68227, 68239, 68261, 68279, 68281, 68311, 68329, 68351, 68371, + 68389, 68399, 68437, 68443, 68447, 68449, 68473, 68477, 68483, 68489, + 68491, 68501, 68507, 68521, 68531, 68539, 68543, 68567, 68581, 68597, + 68611, 68633, 68639, 68659, 68669, 68683, 68687, 68699, 68711, 68713, + 68729, 68737, 68743, 68749, 68767, 68771, 68777, 68791, 68813, 68819, + 68821, 68863, 68879, 68881, 68891, 68897, 68899, 68903, 68909, 68917, + 68927, 68947, 68963, 68993, 69001, 69011, 69019, 69029, 69031, 69061, + 69067, 69073, 69109, 69119, 69127, 69143, 69149, 69151, 69163, 69191, + 69193, 69197, 69203, 69221, 69233, 69239, 69247, 69257, 69259, 69263, + 69313, 69317, 69337, 69341, 69371, 69379, 69383, 69389, 69401, 69403, + 69427, 69431, 69439, 69457, 69463, 69467, 69473, 69481, 69491, 69493, + 69497, 69499, 69539, 69557, 69593, 69623, 69653, 69661, 69677, 69691, + 69697, 69709, 69737, 69739, 69761, 69763, 69767, 69779, 69809, 69821, + 69827, 69829, 69833, 69847, 69857, 69859, 69877, 69899, 69911, 69929, + 69931, 69941, 69959, 69991, 69997, 70001, 70003, 70009, 70019, 70039, + 70051, 70061, 70067, 70079, 70099, 70111, 70117, 70121, 70123, 70139, + 70141, 70157, 70163, 70177, 70181, 70183, 70199, 70201, 70207, 70223, + 70229, 70237, 70241, 70249, 70271, 70289, 70297, 70309, 70313, 70321, + 70327, 70351, 70373, 70379, 70381, 70393, 70423, 70429, 70439, 70451, + 70457, 70459, 70481, 70487, 70489, 70501, 70507, 70529, 70537, 70549, + 70571, 70573, 70583, 70589, 70607, 70619, 70621, 70627, 70639, 70657, + 70663, 70667, 70687, 70709, 70717, 70729, 70753, 70769, 70783, 70793, + 70823, 70841, 70843, 70849, 70853, 70867, 70877, 70879, 70891, 70901, + 70913, 70919, 70921, 70937, 70949, 70951, 70957, 70969, 70979, 70981, + 70991, 70997, 70999, 71011, 71023, 71039, 71059, 71069, 71081, 71089, + 71119, 71129, 71143, 71147, 71153, 71161, 71167, 71171, 71191, 71209, + 71233, 71237, 71249, 71257, 71261, 71263, 71287, 71293, 71317, 71327, + 71329, 71333, 71339, 71341, 71347, 71353, 71359, 71363, 71387, 71389, + 71399, 71411, 71413, 71419, 71429, 71437, 71443, 71453, 71471, 71473, + 71479, 71483, 71503, 71527, 71537, 71549, 71551, 71563, 71569, 71593, + 71597, 71633, 71647, 71663, 71671, 71693, 71699, 71707, 71711, 71713, + 71719, 71741, 71761, 71777, 71789, 71807, 71809, 71821, 71837, 71843, + 71849, 71861, 71867, 71879, 71881, 71887, 71899, 71909, 71917, 71933, + 71941, 71947, 71963, 71971, 71983, 71987, 71993, 71999, 72019, 72031, + 72043, 72047, 72053, 72073, 72077, 72089, 72091, 72101, 72103, 72109, + 72139, 72161, 72167, 72169, 72173, 72211, 72221, 72223, 72227, 72229, + 72251, 72253, 72269, 72271, 72277, 72287, 72307, 72313, 72337, 72341, + 72353, 72367, 72379, 72383, 72421, 72431, 72461, 72467, 72469, 72481, + 72493, 72497, 72503, 72533, 72547, 72551, 72559, 72577, 72613, 72617, + 72623, 72643, 72647, 72649, 72661, 72671, 72673, 72679, 72689, 72701, + 72707, 72719, 72727, 72733, 72739, 72763, 72767, 72797, 72817, 72823, + 72859, 72869, 72871, 72883, 72889, 72893, 72901, 72907, 72911, 72923, + 72931, 72937, 72949, 72953, 72959, 72973, 72977, 72997, 73009, 73013, + 73019, 73037, 73039, 73043, 73061, 73063, 73079, 73091, 73121, 73127, + 73133, 73141, 73181, 73189, 73237, 73243, 73259, 73277, 73291, 73303, + 73309, 73327, 73331, 73351, 73361, 73363, 73369, 73379, 73387, 73417, + 73421, 73433, 73453, 73459, 73471, 73477, 73483, 73517, 73523, 73529, + 73547, 73553, 73561, 73571, 73583, 73589, 73597, 73607, 73609, 73613, + 73637, 73643, 73651, 73673, 73679, 73681, 73693, 73699, 73709, 73721, + 73727, 73751, 73757, 73771, 73783, 73819, 73823, 73847, 73849, 73859, + 73867, 73877, 73883, 73897, 73907, 73939, 73943, 73951, 73961, 73973, + 73999, 74017, 74021, 74027, 74047, 74051, 74071, 74077, 74093, 74099, + 74101, 74131, 74143, 74149, 74159, 74161, 74167, 74177, 74189, 74197, + 74201, 74203, 74209, 74219, 74231, 74257, 74279, 74287, 74293, 74297, + 74311, 74317, 74323, 74353, 74357, 74363, 74377, 74381, 74383, 74411, + 74413, 74419, 74441, 74449, 74453, 74471, 74489, 74507, 74509, 74521, + 74527, 74531, 74551, 74561, 74567, 74573, 74587, 74597, 74609, 74611, + 74623, 74653, 74687, 74699, 74707, 74713, 74717, 74719, 74729, 74731, + 74747, 74759, 74761, 74771, 74779, 74797, 74821, 74827, 74831, 74843, + 74857, 74861, 74869, 74873, 74887, 74891, 74897, 74903, 74923, 74929, + 74933, 74941, 74959, 75011, 75013, 75017, 75029, 75037, 75041, 75079, + 75083, 75109, 75133, 75149, 75161, 75167, 75169, 75181, 75193, 75209, + 75211, 75217, 75223, 75227, 75239, 75253, 75269, 75277, 75289, 75307, + 75323, 75329, 75337, 75347, 75353, 75367, 75377, 75389, 75391, 75401, + 75403, 75407, 75431, 75437, 75479, 75503, 75511, 75521, 75527, 75533, + 75539, 75541, 75553, 75557, 75571, 75577, 75583, 75611, 75617, 75619, + 75629, 75641, 75653, 75659, 75679, 75683, 75689, 75703, 75707, 75709, + 75721, 75731, 75743, 75767, 75773, 75781, 75787, 75793, 75797, 75821, + 75833, 75853, 75869, 75883, 75913, 75931, 75937, 75941, 75967, 75979, + 75983, 75989, 75991, 75997, 76001, 76003, 76031, 76039, 76079, 76081, + 76091, 76099, 76103, 76123, 76129, 76147, 76157, 76159, 76163, 76207, + 76213, 76231, 76243, 76249, 76253, 76259, 76261, 76283, 76289, 76303, + 76333, 76343, 76367, 76369, 76379, 76387, 76403, 76421, 76423, 76441, + 76463, 76471, 76481, 76487, 76493, 76507, 76511, 76519, 76537, 76541, + 76543, 76561, 76579, 76597, 76603, 76607, 76631, 76649, 76651, 76667, + 76673, 76679, 76697, 76717, 76733, 76753, 76757, 76771, 76777, 76781, + 76801, 76819, 76829, 76831, 76837, 76847, 76871, 76873, 76883, 76907, + 76913, 76919, 76943, 76949, 76961, 76963, 76991, 77003, 77017, 77023, + 77029, 77041, 77047, 77069, 77081, 77093, 77101, 77137, 77141, 77153, + 77167, 77171, 77191, 77201, 77213, 77237, 77239, 77243, 77249, 77261, + 77263, 77267, 77269, 77279, 77291, 77317, 77323, 77339, 77347, 77351, + 77359, 77369, 77377, 77383, 77417, 77419, 77431, 77447, 77471, 77477, + 77479, 77489, 77491, 77509, 77513, 77521, 77527, 77543, 77549, 77551, + 77557, 77563, 77569, 77573, 77587, 77591, 77611, 77617, 77621, 77641, + 77647, 77659, 77681, 77687, 77689, 77699, 77711, 77713, 77719, 77723, + 77731, 77743, 77747, 77761, 77773, 77783, 77797, 77801, 77813, 77839, + 77849, 77863, 77867, 77893, 77899, 77929, 77933, 77951, 77969, 77977, + 77983, 77999, 78007, 78017, 78031, 78041, 78049, 78059, 78079, 78101, + 78121, 78137, 78139, 78157, 78163, 78167, 78173, 78179, 78191, 78193, + 78203, 78229, 78233, 78241, 78259, 78277, 78283, 78301, 78307, 78311, + 78317, 78341, 78347, 78367, 78401, 78427, 78437, 78439, 78467, 78479, + 78487, 78497, 78509, 78511, 78517, 78539, 78541, 78553, 78569, 78571, + 78577, 78583, 78593, 78607, 78623, 78643, 78649, 78653, 78691, 78697, + 78707, 78713, 78721, 78737, 78779, 78781, 78787, 78791, 78797, 78803, + 78809, 78823, 78839, 78853, 78857, 78877, 78887, 78889, 78893, 78901, + 78919, 78929, 78941, 78977, 78979, 78989, 79031, 79039, 79043, 79063, + 79087, 79103, 79111, 79133, 79139, 79147, 79151, 79153, 79159, 79181, + 79187, 79193, 79201, 79229, 79231, 79241, 79259, 79273, 79279, 79283, + 79301, 79309, 79319, 79333, 79337, 79349, 79357, 79367, 79379, 79393, + 79397, 79399, 79411, 79423, 79427, 79433, 79451, 79481, 79493, 79531, + 79537, 79549, 79559, 79561, 79579, 79589, 79601, 79609, 79613, 79621, + 79627, 79631, 79633, 79657, 79669, 79687, 79691, 79693, 79697, 79699, + 79757, 79769, 79777, 79801, 79811, 79813, 79817, 79823, 79829, 79841, + 79843, 79847, 79861, 79867, 79873, 79889, 79901, 79903, 79907, 79939, + 79943, 79967, 79973, 79979, 79987, 79997, 79999, 80021, 80039, 80051, + 80071, 80077, 80107, 80111, 80141, 80147, 80149, 80153, 80167, 80173, + 80177, 80191, 80207, 80209, 80221, 80231, 80233, 80239, 80251, 80263, + 80273, 80279, 80287, 80309, 80317, 80329, 80341, 80347, 80363, 80369, + 80387, 80407, 80429, 80447, 80449, 80471, 80473, 80489, 80491, 80513, + 80527, 80537, 80557, 80567, 80599, 80603, 80611, 80621, 80627, 80629, + 80651, 80657, 80669, 80671, 80677, 80681, 80683, 80687, 80701, 80713, + 80737, 80747, 80749, 80761, 80777, 80779, 80783, 80789, 80803, 80809, + 80819, 80831, 80833, 80849, 80863, 80897, 80909, 80911, 80917, 80923, + 80929, 80933, 80953, 80963, 80989, 81001, 81013, 81017, 81019, 81023, + 81031, 81041, 81043, 81047, 81049, 81071, 81077, 81083, 81097, 81101, + 81119, 81131, 81157, 81163, 81173, 81181, 81197, 81199, 81203, 81223, + 81233, 81239, 81281, 81283, 81293, 81299, 81307, 81331, 81343, 81349, + 81353, 81359, 81371, 81373, 81401, 81409, 81421, 81439, 81457, 81463, + 81509, 81517, 81527, 81533, 81547, 81551, 81553, 81559, 81563, 81569, + 81611, 81619, 81629, 81637, 81647, 81649, 81667, 81671, 81677, 81689, + 81701, 81703, 81707, 81727, 81737, 81749, 81761, 81769, 81773, 81799, + 81817, 81839, 81847, 81853, 81869, 81883, 81899, 81901, 81919, 81929, + 81931, 81937, 81943, 81953, 81967, 81971, 81973, 82003, 82007, 82009, + 82013, 82021, 82031, 82037, 82039, 82051, 82067, 82073, 82129, 82139, + 82141, 82153, 82163, 82171, 82183, 82189, 82193, 82207, 82217, 82219, + 82223, 82231, 82237, 82241, 82261, 82267, 82279, 82301, 82307, 82339, + 82349, 82351, 82361, 82373, 82387, 82393, 82421, 82457, 82463, 82469, + 82471, 82483, 82487, 82493, 82499, 82507, 82529, 82531, 82549, 82559, + 82561, 82567, 82571, 82591, 82601, 82609, 82613, 82619, 82633, 82651, + 82657, 82699, 82721, 82723, 82727, 82729, 82757, 82759, 82763, 82781, + 82787, 82793, 82799, 82811, 82813, 82837, 82847, 82883, 82889, 82891, + 82903, 82913, 82939, 82963, 82981, 82997, 83003, 83009, 83023, 83047, + 83059, 83063, 83071, 83077, 83089, 83093, 83101, 83117, 83137, 83177, + 83203, 83207, 83219, 83221, 83227, 83231, 83233, 83243, 83257, 83267, + 83269, 83273, 83299, 83311, 83339, 83341, 83357, 83383, 83389, 83399, + 83401, 83407, 83417, 83423, 83431, 83437, 83443, 83449, 83459, 83471, + 83477, 83497, 83537, 83557, 83561, 83563, 83579, 83591, 83597, 83609, + 83617, 83621, 83639, 83641, 83653, 83663, 83689, 83701, 83717, 83719, + 83737, 83761, 83773, 83777, 83791, 83813, 83833, 83843, 83857, 83869, + 83873, 83891, 83903, 83911, 83921, 83933, 83939, 83969, 83983, 83987, + 84011, 84017, 84047, 84053, 84059, 84061, 84067, 84089, 84121, 84127, + 84131, 84137, 84143, 84163, 84179, 84181, 84191, 84199, 84211, 84221, + 84223, 84229, 84239, 84247, 84263, 84299, 84307, 84313, 84317, 84319, + 84347, 84349, 84377, 84389, 84391, 84401, 84407, 84421, 84431, 84437, + 84443, 84449, 84457, 84463, 84467, 84481, 84499, 84503, 84509, 84521, + 84523, 84533, 84551, 84559, 84589, 84629, 84631, 84649, 84653, 84659, + 84673, 84691, 84697, 84701, 84713, 84719, 84731, 84737, 84751, 84761, + 84787, 84793, 84809, 84811, 84827, 84857, 84859, 84869, 84871, 84913, + 84919, 84947, 84961, 84967, 84977, 84979, 84991, 85009, 85021, 85027, + 85037, 85049, 85061, 85081, 85087, 85091, 85093, 85103, 85109, 85121, + 85133, 85147, 85159, 85193, 85199, 85201, 85213, 85223, 85229, 85237, + 85243, 85247, 85259, 85297, 85303, 85313, 85331, 85333, 85361, 85363, + 85369, 85381, 85411, 85427, 85429, 85439, 85447, 85451, 85453, 85469, + 85487, 85513, 85517, 85523, 85531, 85549, 85571, 85577, 85597, 85601, + 85607, 85619, 85621, 85627, 85639, 85643, 85661, 85667, 85669, 85691, + 85703, 85711, 85717, 85733, 85751, 85781, 85793, 85817, 85819, 85829, + 85831, 85837, 85843, 85847, 85853, 85889, 85903, 85909, 85931, 85933, + 85991, 85999, 86011, 86017, 86027, 86029, 86069, 86077, 86083, 86111, + 86113, 86117, 86131, 86137, 86143, 86161, 86171, 86179, 86183, 86197, + 86201, 86209, 86239, 86243, 86249, 86257, 86263, 86269, 86287, 86291, + 86293, 86297, 86311, 86323, 86341, 86351, 86353, 86357, 86369, 86371, + 86381, 86389, 86399, 86413, 86423, 86441, 86453, 86461, 86467, 86477, + 86491, 86501, 86509, 86531, 86533, 86539, 86561, 86573, 86579, 86587, + 86599, 86627, 86629, 86677, 86689, 86693, 86711, 86719, 86729, 86743, + 86753, 86767, 86771, 86783, 86813, 86837, 86843, 86851, 86857, 86861, + 86869, 86923, 86927, 86929, 86939, 86951, 86959, 86969, 86981, 86993, + 87011, 87013, 87037, 87041, 87049, 87071, 87083, 87103, 87107, 87119, + 87121, 87133, 87149, 87151, 87179, 87181, 87187, 87211, 87221, 87223, + 87251, 87253, 87257, 87277, 87281, 87293, 87299, 87313, 87317, 87323, + 87337, 87359, 87383, 87403, 87407, 87421, 87427, 87433, 87443, 87473, + 87481, 87491, 87509, 87511, 87517, 87523, 87539, 87541, 87547, 87553, + 87557, 87559, 87583, 87587, 87589, 87613, 87623, 87629, 87631, 87641, + 87643, 87649, 87671, 87679, 87683, 87691, 87697, 87701, 87719, 87721, + 87739, 87743, 87751, 87767, 87793, 87797, 87803, 87811, 87833, 87853, + 87869, 87877, 87881, 87887, 87911, 87917, 87931, 87943, 87959, 87961, + 87973, 87977, 87991, 88001, 88003, 88007, 88019, 88037, 88069, 88079, + 88093, 88117, 88129, 88169, 88177, 88211, 88223, 88237, 88241, 88259, + 88261, 88289, 88301, 88321, 88327, 88337, 88339, 88379, 88397, 88411, + 88423, 88427, 88463, 88469, 88471, 88493, 88499, 88513, 88523, 88547, + 88589, 88591, 88607, 88609, 88643, 88651, 88657, 88661, 88663, 88667, + 88681, 88721, 88729, 88741, 88747, 88771, 88789, 88793, 88799, 88801, + 88807, 88811, 88813, 88817, 88819, 88843, 88853, 88861, 88867, 88873, + 88883, 88897, 88903, 88919, 88937, 88951, 88969, 88993, 88997, 89003, + 89009, 89017, 89021, 89041, 89051, 89057, 89069, 89071, 89083, 89087, + 89101, 89107, 89113, 89119, 89123, 89137, 89153, 89189, 89203, 89209, + 89213, 89227, 89231, 89237, 89261, 89269, 89273, 89293, 89303, 89317, + 89329, 89363, 89371, 89381, 89387, 89393, 89399, 89413, 89417, 89431, + 89443, 89449, 89459, 89477, 89491, 89501, 89513, 89519, 89521, 89527, + 89533, 89561, 89563, 89567, 89591, 89597, 89599, 89603, 89611, 89627, + 89633, 89653, 89657, 89659, 89669, 89671, 89681, 89689, 89753, 89759, + 89767, 89779, 89783, 89797, 89809, 89819, 89821, 89833, 89839, 89849, + 89867, 89891, 89897, 89899, 89909, 89917, 89923, 89939, 89959, 89963, + 89977, 89983, 89989, 90001, 90007, 90011, 90017, 90019, 90023, 90031, + 90053, 90059, 90067, 90071, 90073, 90089, 90107, 90121, 90127, 90149, + 90163, 90173, 90187, 90191, 90197, 90199, 90203, 90217, 90227, 90239, + 90247, 90263, 90271, 90281, 90289, 90313, 90353, 90359, 90371, 90373, + 90379, 90397, 90401, 90403, 90407, 90437, 90439, 90469, 90473, 90481, + 90499, 90511, 90523, 90527, 90529, 90533, 90547, 90583, 90599, 90617, + 90619, 90631, 90641, 90647, 90659, 90677, 90679, 90697, 90703, 90709, + 90731, 90749, 90787, 90793, 90803, 90821, 90823, 90833, 90841, 90847, + 90863, 90887, 90901, 90907, 90911, 90917, 90931, 90947, 90971, 90977, + 90989, 90997, 91009, 91019, 91033, 91079, 91081, 91097, 91099, 91121, + 91127, 91129, 91139, 91141, 91151, 91153, 91159, 91163, 91183, 91193, + 91199, 91229, 91237, 91243, 91249, 91253, 91283, 91291, 91297, 91303, + 91309, 91331, 91367, 91369, 91373, 91381, 91387, 91393, 91397, 91411, + 91423, 91433, 91453, 91457, 91459, 91463, 91493, 91499, 91513, 91529, + 91541, 91571, 91573, 91577, 91583, 91591, 91621, 91631, 91639, 91673, + 91691, 91703, 91711, 91733, 91753, 91757, 91771, 91781, 91801, 91807, + 91811, 91813, 91823, 91837, 91841, 91867, 91873, 91909, 91921, 91939, + 91943, 91951, 91957, 91961, 91967, 91969, 91997, 92003, 92009, 92033, + 92041, 92051, 92077, 92083, 92107, 92111, 92119, 92143, 92153, 92173, + 92177, 92179, 92189, 92203, 92219, 92221, 92227, 92233, 92237, 92243, + 92251, 92269, 92297, 92311, 92317, 92333, 92347, 92353, 92357, 92363, + 92369, 92377, 92381, 92383, 92387, 92399, 92401, 92413, 92419, 92431, + 92459, 92461, 92467, 92479, 92489, 92503, 92507, 92551, 92557, 92567, + 92569, 92581, 92593, 92623, 92627, 92639, 92641, 92647, 92657, 92669, + 92671, 92681, 92683, 92693, 92699, 92707, 92717, 92723, 92737, 92753, + 92761, 92767, 92779, 92789, 92791, 92801, 92809, 92821, 92831, 92849, + 92857, 92861, 92863, 92867, 92893, 92899, 92921, 92927, 92941, 92951, + 92957, 92959, 92987, 92993, 93001, 93047, 93053, 93059, 93077, 93083, + 93089, 93097, 93103, 93113, 93131, 93133, 93139, 93151, 93169, 93179, + 93187, 93199, 93229, 93239, 93241, 93251, 93253, 93257, 93263, 93281, + 93283, 93287, 93307, 93319, 93323, 93329, 93337, 93371, 93377, 93383, + 93407, 93419, 93427, 93463, 93479, 93481, 93487, 93491, 93493, 93497, + 93503, 93523, 93529, 93553, 93557, 93559, 93563, 93581, 93601, 93607, + 93629, 93637, 93683, 93701, 93703, 93719, 93739, 93761, 93763, 93787, + 93809, 93811, 93827, 93851, 93871, 93887, 93889, 93893, 93901, 93911, + 93913, 93923, 93937, 93941, 93949, 93967, 93971, 93979, 93983, 93997, + 94007, 94009, 94033, 94049, 94057, 94063, 94079, 94099, 94109, 94111, + 94117, 94121, 94151, 94153, 94169, 94201, 94207, 94219, 94229, 94253, + 94261, 94273, 94291, 94307, 94309, 94321, 94327, 94331, 94343, 94349, + 94351, 94379, 94397, 94399, 94421, 94427, 94433, 94439, 94441, 94447, + 94463, 94477, 94483, 94513, 94529, 94531, 94541, 94543, 94547, 94559, + 94561, 94573, 94583, 94597, 94603, 94613, 94621, 94649, 94651, 94687, + 94693, 94709, 94723, 94727, 94747, 94771, 94777, 94781, 94789, 94793, + 94811, 94819, 94823, 94837, 94841, 94847, 94849, 94873, 94889, 94903, + 94907, 94933, 94949, 94951, 94961, 94993, 94999, 95003, 95009, 95021, + 95027, 95063, 95071, 95083, 95087, 95089, 95093, 95101, 95107, 95111, + 95131, 95143, 95153, 95177, 95189, 95191, 95203, 95213, 95219, 95231, + 95233, 95239, 95257, 95261, 95267, 95273, 95279, 95287, 95311, 95317, + 95327, 95339, 95369, 95383, 95393, 95401, 95413, 95419, 95429, 95441, + 95443, 95461, 95467, 95471, 95479, 95483, 95507, 95527, 95531, 95539, + 95549, 95561, 95569, 95581, 95597, 95603, 95617, 95621, 95629, 95633, + 95651, 95701, 95707, 95713, 95717, 95723, 95731, 95737, 95747, 95773, + 95783, 95789, 95791, 95801, 95803, 95813, 95819, 95857, 95869, 95873, + 95881, 95891, 95911, 95917, 95923, 95929, 95947, 95957, 95959, 95971, + 95987, 95989, 96001, 96013, 96017, 96043, 96053, 96059, 96079, 96097, + 96137, 96149, 96157, 96167, 96179, 96181, 96199, 96211, 96221, 96223, + 96233, 96259, 96263, 96269, 96281, 96289, 96293, 96323, 96329, 96331, + 96337, 96353, 96377, 96401, 96419, 96431, 96443, 96451, 96457, 96461, + 96469, 96479, 96487, 96493, 96497, 96517, 96527, 96553, 96557, 96581, + 96587, 96589, 96601, 96643, 96661, 96667, 96671, 96697, 96703, 96731, + 96737, 96739, 96749, 96757, 96763, 96769, 96779, 96787, 96797, 96799, + 96821, 96823, 96827, 96847, 96851, 96857, 96893, 96907, 96911, 96931, + 96953, 96959, 96973, 96979, 96989, 96997, 97001, 97003, 97007, 97021, + 97039, 97073, 97081, 97103, 97117, 97127, 97151, 97157, 97159, 97169, + 97171, 97177, 97187, 97213, 97231, 97241, 97259, 97283, 97301, 97303, + 97327, 97367, 97369, 97373, 97379, 97381, 97387, 97397, 97423, 97429, + 97441, 97453, 97459, 97463, 97499, 97501, 97511, 97523, 97547, 97549, + 97553, 97561, 97571, 97577, 97579, 97583, 97607, 97609, 97613, 97649, + 97651, 97673, 97687, 97711, 97729, 97771, 97777, 97787, 97789, 97813, + 97829, 97841, 97843, 97847, 97849, 97859, 97861, 97871, 97879, 97883, + 97919, 97927, 97931, 97943, 97961, 97967, 97973, 97987, 98009, 98011, + 98017, 98041, 98047, 98057, 98081, 98101, 98123, 98129, 98143, 98179, + 98207, 98213, 98221, 98227, 98251, 98257, 98269, 98297, 98299, 98317, + 98321, 98323, 98327, 98347, 98369, 98377, 98387, 98389, 98407, 98411, + 98419, 98429, 98443, 98453, 98459, 98467, 98473, 98479, 98491, 98507, + 98519, 98533, 98543, 98561, 98563, 98573, 98597, 98621, 98627, 98639, + 98641, 98663, 98669, 98689, 98711, 98713, 98717, 98729, 98731, 98737, + 98773, 98779, 98801, 98807, 98809, 98837, 98849, 98867, 98869, 98873, + 98887, 98893, 98897, 98899, 98909, 98911, 98927, 98929, 98939, 98947, + 98953, 98963, 98981, 98993, 98999, 99013, 99017, 99023, 99041, 99053, + 99079, 99083, 99089, 99103, 99109, 99119, 99131, 99133, 99137, 99139, + 99149, 99173, 99181, 99191, 99223, 99233, 99241, 99251, 99257, 99259, + 99277, 99289, 99317, 99347, 99349, 99367, 99371, 99377, 99391, 99397, + 99401, 99409, 99431, 99439, 99469, 99487, 99497, 99523, 99527, 99529, + 99551, 99559, 99563, 99571, 99577, 99581, 99607, 99611, 99623, 99643, + 99661, 99667, 99679, 99689, 99707, 99709, 99713, 99719, 99721, 99733, + 99761, 99767, 99787, 99793, 99809, 99817, 99823, 99829, 99833, 99839, + 99859, 99871, 99877, 99881, 99901, 99907, 99923, 99929, 99961, 99971, + 99989, 99991, 100003, 100019, 100043, 100049, 100057, 100069, 100103, 100109, +100129, 100151, 100153, 100169, 100183, 100189, 100193, 100207, 100213, 100237, +100267, 100271, 100279, 100291, 100297, 100313, 100333, 100343, 100357, 100361, +100363, 100379, 100391, 100393, 100403, 100411, 100417, 100447, 100459, 100469, +100483, 100493, 100501, 100511, 100517, 100519, 100523, 100537, 100547, 100549, +100559, 100591, 100609, 100613, 100621, 100649, 100669, 100673, 100693, 100699, +100703, 100733, 100741, 100747, 100769, 100787, 100799, 100801, 100811, 100823, +100829, 100847, 100853, 100907, 100913, 100927, 100931, 100937, 100943, 100957, +100981, 100987, 100999, 101009, 101021, 101027, 101051, 101063, 101081, 101089, +101107, 101111, 101113, 101117, 101119, 101141, 101149, 101159, 101161, 101173, +101183, 101197, 101203, 101207, 101209, 101221, 101267, 101273, 101279, 101281, +101287, 101293, 101323, 101333, 101341, 101347, 101359, 101363, 101377, 101383, +101399, 101411, 101419, 101429, 101449, 101467, 101477, 101483, 101489, 101501, +101503, 101513, 101527, 101531, 101533, 101537, 101561, 101573, 101581, 101599, +101603, 101611, 101627, 101641, 101653, 101663, 101681, 101693, 101701, 101719, +101723, 101737, 101741, 101747, 101749, 101771, 101789, 101797, 101807, 101833, +101837, 101839, 101863, 101869, 101873, 101879, 101891, 101917, 101921, 101929, +101939, 101957, 101963, 101977, 101987, 101999, 102001, 102013, 102019, 102023, +102031, 102043, 102059, 102061, 102071, 102077, 102079, 102101, 102103, 102107, +102121, 102139, 102149, 102161, 102181, 102191, 102197, 102199, 102203, 102217, +102229, 102233, 102241, 102251, 102253, 102259, 102293, 102299, 102301, 102317, +102329, 102337, 102359, 102367, 102397, 102407, 102409, 102433, 102437, 102451, +102461, 102481, 102497, 102499, 102503, 102523, 102533, 102539, 102547, 102551, +102559, 102563, 102587, 102593, 102607, 102611, 102643, 102647, 102653, 102667, +102673, 102677, 102679, 102701, 102761, 102763, 102769, 102793, 102797, 102811, +102829, 102841, 102859, 102871, 102877, 102881, 102911, 102913, 102929, 102931, +102953, 102967, 102983, 103001, 103007, 103043, 103049, 103067, 103069, 103079, +103087, 103091, 103093, 103099, 103123, 103141, 103171, 103177, 103183, 103217, +103231, 103237, 103289, 103291, 103307, 103319, 103333, 103349, 103357, 103387, +103391, 103393, 103399, 103409, 103421, 103423, 103451, 103457, 103471, 103483, +103511, 103529, 103549, 103553, 103561, 103567, 103573, 103577, 103583, 103591, +103613, 103619, 103643, 103651, 103657, 103669, 103681, 103687, 103699, 103703, +103723, 103769, 103787, 103801, 103811, 103813, 103837, 103841, 103843, 103867, +103889, 103903, 103913, 103919, 103951, 103963, 103967, 103969, 103979, 103981, +103991, 103993, 103997, 104003, 104009, 104021, 104033, 104047, 104053, 104059, +104087, 104089, 104107, 104113, 104119, 104123, 104147, 104149, 104161, 104173, +104179, 104183, 104207, 104231, 104233, 104239, 104243, 104281, 104287, 104297, +104309, 104311, 104323, 104327, 104347, 104369, 104381, 104383, 104393, 104399, +104417, 104459, 104471, 104473, 104479, 104491, 104513, 104527, 104537, 104543, +104549, 104551, 104561, 104579, 104593, 104597, 104623, 104639, 104651, 104659, +104677, 104681, 104683, 104693, 104701, 104707, 104711, 104717, 104723, 104729, +) diff --git a/panda/python/Lib/site-packages/Crypto/Util/number.pyo b/panda/python/Lib/site-packages/Crypto/Util/number.pyo new file mode 100644 index 0000000000000000000000000000000000000000..7b5bb4a0f4bac2fe5fd80f26e7114566fe3b17cd GIT binary patch literal 113620 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

#z;Gu@8rE6yrFFOSp`yxP}LKgvWS> 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 Qp1{u&_;~{V|4!il2CwJFl>h($ literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Util/py21compat.py b/panda/python/Lib/site-packages/Crypto/Util/py21compat.py new file mode 100644 index 00000000..624408bd --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Util/py21compat.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +# +# Util/py21compat.py : Compatibility code for Python 2.1 +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Compatibility code for Python 2.1 + +Currently, this just defines: + - True and False + - object + - isinstance +""" + +__revision__ = "$Id$" +__all__ = [] + +import sys +import __builtin__ + +# 'True' and 'False' aren't defined in Python 2.1. Define them. +try: + True, False +except NameError: + (True, False) = (1, 0) + __all__ += ['True', 'False'] + +# New-style classes were introduced in Python 2.2. Defining "object" in Python +# 2.1 lets us use new-style classes in versions of Python that support them, +# while still maintaining backward compatibility with old-style classes +try: + object +except NameError: + class object: pass + __all__ += ['object'] + +# Starting with Python 2.2, isinstance allows a tuple for the second argument. +# Also, builtins like "tuple", "list", "str", "unicode", "int", and "long" +# became first-class types, rather than functions. We want to support +# constructs like: +# isinstance(x, (int, long)) +# So we hack it for Python 2.1. +try: + isinstance(5, (int, long)) +except TypeError: + __all__ += ['isinstance'] + _builtin_type_map = { + tuple: type(()), + list: type([]), + str: type(""), + unicode: type(u""), + int: type(0), + long: type(0L), + } + def isinstance(obj, t): + if not __builtin__.isinstance(t, type(())): + # t is not a tuple + return __builtin__.isinstance(obj, _builtin_type_map.get(t, t)) + else: + # t is a tuple + for typ in t: + if __builtin__.isinstance(obj, _builtin_type_map.get(typ, typ)): + return True + return False + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/Util/py21compat.pyo b/panda/python/Lib/site-packages/Crypto/Util/py21compat.pyo new file mode 100644 index 0000000000000000000000000000000000000000..7813a43acdf7ec609fbcc79e9fcc45a628b6cd5d GIT binary patch literal 1447 zcmb_bOK;Oa5dPLq($r1*ph$2)-~)#oXw;UfKzRreK&pf)loS=LAj{2e(=DzYyc>iC zoXVL$!B6A|z|6XBkho%b$Mem8v-8-o|EnDoKZgAg&YwDcpVBgq1t5Wlq(CGvCf$Ri z*GK9j@-Ornq8iFYs5(>wM;^pMwuYLT!-oLH7(xiSjG>39j;H}eCo~}EF!pedPRs<} zmQAQ8`)yqM{d9g!$Q8(Wdrxm4j%UWBhpdz@$CW_Ke9defp%nN7<(p*_|nJee9BN_C_& zWp;v)p0#kln5r()bn%A9_ zeU7_D%dpab=KNjgS=roeOj)EXM$GhSae%vY1A15^? z&`VqN4nD6lc>cbFZ{9yd4__UNh{Z!tUk4u_;()q3kf1r>B=)MN%yIYy5^;Pu)v484 z9QR!vd@Ht`D7(VD7n^K}Pm>8{1dNsK(+7RNn+{u?nJ&(<#X3YDv;P0L)^m!xv`mWx z#C7k6-xfDTQ@G-0!!---rr&bCaV+x@4GFu(aiKoZb>&p|`DT))q;oZ zTY2W4U%&%Dj~@W%UeA8fl!vODYP_Bq`}*8-&b6mYe{ZGL@5h~7)PD(nzr^MLLZgLv zinbx1HiS-uUJ^wjo+iR1;%rIiW$}()5$B1hei3?A{D#rXLa%XWMd)?ztO~usowf0_ z6w^|k=7he%@7Be$KZV|``>rkY7WWbECU+3-7IzTtE$*xdz0I9}9L$$uJri*=!FVB2?hT7dA&XH5MbQxU4EJ)yQLfsfRh(QFY#u zvL=w~q6VluKPW4EioA;~y@$MIWt5JTD%rDzkrpvxOhjnbobg)OEXDiT)eOb+{9dS$ zEL}m0Mxy7KVD4g?X-rc>Z^qVaPC4X|#E~m6fl?2hRxW^%ucR}VG5J=miULYCn`{x% zwohr6vI{0XXeB$%$Shk^nUxz!2pDWWEL4RUtULIHfJl8z{o z=s`6afHh?=;I$zAa4;yL15Dn<@R=fJW3bc6%Ds|Er(u0lAhonNbUCFLYl-zn*mGkB z%tK{-7?(j|yA{PS~Rdb~?f<;UQY1+z4iY@t`D4m!CmCe}yFs8{oBh#EFT z=@e%`x{h}^&VFv+zjppE!_ zpYutXVK{~DQY=q+L}P-8ZW&REP7ng1UNk1SXj)i8LrT+42bXyB@Q65a(>?sYCPLVI z;RvzD{ntlGZeKKqSmT>1LQBg{q$V9%>K$}O+a&cFfBcc)Pu#X>G#dB_JZp?i@Pj6Y z(zHXrhPJ@5;M#j|2|Pf?3HTZl@xv#OglDC7i%gL~)MfrHx_%vvXe>3halM>on?|#v zVgDESh<%q+#%C^Wkuv4FG|u(M8WbT-iM(EA1E-noJJ z-{bPcxoF&KY$cPFCq=x4S97wmOmpf*j0Aa+Xvug_aJ{ma327APG^)X94!I30co{eI z#nnrPeEs7!5GQ5w{siL0KOrG{$v=rWiZ|>esuL1no@t8I*`$UX)VYafk(?82KjFI0 zA;jYWy(1(@;iZFTF&le_%H(HSm)My(b|xf$j>mIFdYj?Zj}oriyX6G;Y9NFE z;houL-ih)^{-O;}<=MsMX&<2STu!J&TeL237AGgV%uh}N;W{~~%yVoerNaZF!jC+^ zs6QJ|tm~B>_CCGskg`lA?*h}~mwRvO6M?q6&+tt?EX)_55~laitR}0;W^%i+k;H$u O8=I?}tK47NNd5( self.bits: + self.entropy = self.bits + + def _randomize(self, N=0, devname="/dev/urandom"): + """Dummy _randomize() function""" + self.__rng.flush() + + def randomize(self, N=0): + """Dummy randomize() function""" + self.__rng.flush() + + def stir(self, s=''): + """Dummy stir() function""" + self.__rng.flush() + + def stir_n(self, N=3): + """Dummy stir_n() function""" + self.__rng.flush() + + def add_event(self, s=''): + """Dummy add_event() function""" + self.__rng.flush() + + def getBytes(self, N): + """Dummy getBytes() function""" + return self.get_bytes(N) + + def addEvent(self, event, s=""): + """Dummy addEvent() function""" + return self.add_event() diff --git a/panda/python/Lib/site-packages/Crypto/Util/randpool.pyo b/panda/python/Lib/site-packages/Crypto/Util/randpool.pyo new file mode 100644 index 0000000000000000000000000000000000000000..32139e60513c1759fb5ecd4180188a505af34aca GIT binary patch literal 3332 zcmcImZEqVz5S}|biS0T~D3o{TRjQCd#G&E?P*tepMFORAq6-yjWNCG|+r*dHcgO8I zQBc1nU-%dN5`Gl?0C;BBZ&Z~?BAi^k1^1)u7_tlmzN*zZw&9h&kGE1}Lj&1yB$i&D6G;g4o-yt-Nghi0P zn6pZW`}=fN6&ovTku#7Lv5_rZqAMU;Vv~~^U3qj+qohtrLv$#2C~1n`koINK(Rf!T zY)a#bG%i!P-+GHp>Ozd6=%gJ4FN_Wx%yy>FTb~DMW~`2qcB2vC+1EPgSzA0=Uq3%T zZxH*1GweyTGWpZ_Awe6L`WS>(eEOvK2b1 z(#Zm|@rp<-(koAtC6*@u?$bNmQIonz1=s}Ac;b%v74qj^YJ#XJ`l%x)7#eLxh?ux9 zgY#Y*_X3RC2zPh3I{+Bu{X~~Rsrx#@Xn5fUFw+`VZ87zhwR0B?##Tp_5O1=J5S!vE zQJsf@mK>-^I~yY z^mHi$dXedga+LOU3wpQndilUlu2MDb~K ztWDQh-+f`zes|0?_?MNHO0(1|^%-U~Oet{+Nc;df~IyeOJesf6xdyb;jsD}UyWfP zh);>iFF2YxLc!|85kkg^-YS(l(lQw!`D$O#by8l?0hJuWCe7exsxuCNxs&%UW>&)@ ziLBmsakXu1IzaU?dJG#w-U@zAkSSIQz3YiSTOV>1kh_wj+lg&-;4%-d^_ zWY5k&ZaKNK4bS*3+tp7w25$uCJ$x{Qqq1uOx*d)2F=ZA}r~2+TC*q9jrJ49CRv z@bH$rm6)5@@#7mHF=vu2mZ7+0F?$f0576wmL2BOMQ*Z{2oE72Q7;@Wtr-n7g20Vv8 z&ITN7Tqe7Q6NiIw$@dX%pTPiEY`?~c!|*A_P4k-^`9fWIE37b@u_=3Oq1!o~)?HLa z2RWxzrQ|BB)F4lWeXjC}tW=W6(0T85@=S+(j0+1PCx-BS7R+1tF$=jbGrsTvi-!=? zFcWP)7m$#B&9fU$ri;}@?|!XbsV}Wmo1K2x31>a7TD)m`vaNqzAhmpJ6w2RoP r@%_zR+c-K$ouQm|A)^o3Z?f*KAQC2?I^TcKfnaJ7i~cH3;imsDj(Fcz literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Util/strxor.pyd b/panda/python/Lib/site-packages/Crypto/Util/strxor.pyd new file mode 100644 index 0000000000000000000000000000000000000000..d97aa9806719454816a774675c1ade8d87108c62 GIT binary patch literal 7680 zcmeHM4{#ILnSZh+TQ+j6Bvt|!lB|i`m;@ZjD`86uIRh4fVh0%;8;3tame#ENM>4Bj zYUkqCsc?c=JmoG-Cv(Z%gfnx^F?W+RlP09OHUbk2SGYP%>(E}BbM7b=2W?D9!ATtU zes5PMHjvI-ZfQWXo2SGN+W%RTkGFrQ(J!_SYj`Xp_a7Qw z8wm+i=TroKA0agcBbju)Uq3|~BU#0>40#9w6su0Xct>W;XmhJZ&mzR6v#(*|2Z1IH z4Qw9}kHo{!DH<<6ADKcYLCh^@8DESt2 z)IS<)#&3+Y#t^clObiF5AR%cQCG)R-0IZ=kVgZ6Z~aI8>y(n~r?0s)-{; z<)|(*qx`P<2m91PW1TQ^or6-#lTX-Q70gbLS^jbx2Vgg+6$s z+9WLrjjF91gXZSJ-HV8Ia3?w>#l)tnHV-AfM$*f0s|s1Oi8Wn}(Xi28bSK6(jGNii zW~f`IT&SyKQy!m1zQto&39H{+tQJt5=(QM>f+wh%y!ytbWWf_qUfBOLSPv@&^rlvN zjEcJy0!g36|K<*`&(CI4=Z@p1=7yy^g)|~kZ3`gKMw;r?QSA9|&gTyMEc7bh*9ZBw ztj&lmukGISBY0e#Uo5-|Vc{Rp4Vx&R3Z}mXR&z7ta-lo|lJFvx+K(=6q`ah?%Cc&+ zr`IBzVaetI&$DC?sM1`4qV(M~WaubRWox47}O;7RSPOHktG!%B#D|l_XChsH{Bh@Ex;{xv>EB@PZjQXTI0|yQ%98v z#b*J-n(Q?vJ~VQ@7O^hz=R~@s+B#?~xzahcLLE)|CUinFS6w%ut5ru;H&sG;qe|@r z&Z(!?Dw{k$v-E1R)|#xfBz1$Y{Gf0O8U;Q$CI^_Np~fxCFz^wF3MJqRywjdS$pQ( z>xhpVmrRMPS#sIF6zp<`By&?^y*h%miQY4$aK|%{0VN&BX#tU@r7uHT3TssEszJ7+ za+oH6eR?5iID+-*<&f7@VoP%PH}DZUGe zS;&g<(5)Z#O1lBcgLgIuP2&Z2Gvw5hkNZ3M?xCe%AsE0F&3A#D7EZ5WhIlr~d zoZd~>QBS7!8QIXc8a0Gk85{78`3HPw{M53WUIU=}(`&FS>3dI=�r?=Bo0TI*J=y z+wPfBy_a4AcZOi>cFjpGCa6n4iU_ZqzAJU*bo0th^wv383g>@JyC!9VI~p%ka*@p} zbtExtl^tH&T2*%T}-U7UUB$x8Z?Eq}Wl*cS6(Gc2($u^MdWqh&8+q8&CXrhT-GMn06D|s25DKR_{<9_&98I(8pjL{r&QSwrSH8m zk{B~&wnC{L4<`$#nr1kq{2EEn3e&)zT7ugxrG-ulGb7KYZd`FfEeX^8FR9Y{#adsD zUW-aA(%TYC=n*7xo>pddjB$u*mEzf>#jCoh6L^wZlO1@90UjLtBJ@dwj)+wmH`Qdu z6D?N}p{fww`5iVW5zJ)Y0E6`-7hhQvmWHzlXdXO$ywHzn-3GMXNH@)@f z*{V0+#9>i!?-ukANqJXB2CK31{FcT6-vr(bifDlHBrD@moK52yS8c8go~vPa2RVky z`95ZS48fZR0tN)Ums~kNvW}P*jbW@kEj3(XGz~;b)<3no6N-R@LYP8<3 z^$qB`0xBwJT^c% z${Y-1Hf&mtKF>%}!={ZI7f&bZd9wdBmh7W(Ci~yRP_+>RF!&+}ZHBZ5F*VbdEF*}* z5p=4}j6Si13J}>085@-msBYC}0S_s*0@0jp0S5O^?f+c{x=RRo4Dc}E0l*!ANjo8D z0V%-W0d@g80AawRfDr&~d+#IUDZnd$BY-sEBLD&447dkS33wbd0k9t62P^|P0DlXh z%?dm@59F5(&mqxu7i-w+8${G0r#0 zT^(52nC~PIwA{= z4cL}QG$`>IaYFw7Mjhl~!_I+HxV$j9L>S?yc< zsIP`C*DLLdBm7zBoAoK2ZF)CN!75xU<%iLcQ zzaJjV)cNo=oj6+YjHUm9UR0H+dFq6c_w}A1?|H^*Muz%q2 zPmdmb`@l`?2Vpl<4uB7#MHz5!><$LMqJ4coOM_kv7BDRo&1V)q%mC--ujM6Kj50xH z{hGB*OBur~i%9~exC59LrW1D&BLuhej3n?(92X7K!AG}BLRmf`_4wiJ6>}9z>#tsb-d$v*YR7&94F%} zaXOrwbCt8fxz#B;d!5fY-*O&xo^+ma{=#|I`CI45&QF}Ayturyd{w!>ys5ms{BZg4 z^7G}zY$^K?`*n5=yN>N*d)Pj27wnxn*~+`$hLl?pNJ!xKr+v?)TlFxy_51 zMe#*1EJ`o3RoqumR^h5xS+S`?sOYQsZpC25SjDd^aw=z49;-ZA`EQk9UvkfJ`?;66H@Ory!u_24SMCGu z3U`&uSxn!}@SnWwIN~_wusE$wzjM8FqqEz&*ZC~H&>Vym0TI^7T39Pv#Li{u^na`U E7n+OkLjV8( literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/Util/winrandom.py b/panda/python/Lib/site-packages/Crypto/Util/winrandom.py new file mode 100644 index 00000000..0242815a --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/Util/winrandom.py @@ -0,0 +1,28 @@ +# +# Util/winrandom.py : Stub for Crypto.Random.OSRNG.winrandom +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +__revision__ = "$Id$" + +from Crypto.Random.OSRNG.winrandom import * + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/Util/winrandom.pyo b/panda/python/Lib/site-packages/Crypto/Util/winrandom.pyo new file mode 100644 index 0000000000000000000000000000000000000000..90f06b18dc1e62e31e40aff0c52a0a0f01420849 GIT binary patch literal 247 zcmZSn%**vDa-V-P0~9a;X$K%K76B3|3=B~~l93^Wi6MuPAtZ&FAy|V2Bnu)`JX2IM z{{w*rBal}DBDDN8Kn9fX0EzhcqSUg?;>`TK`1lf8pn!8xWkE^4UQl9QN`9`Me{hhW zyIy%_UJ;nD0aU<%Ac~zp8mwXhfRc&EF1m(#mU;#;1(hWk`FSxunMpClnI);Z1&PVo qiRr1uF%Y9;LQ67pV&F#V0hMzAjj_qiPbtkwwUYp{i$Ts~V*&t`5f literal 0 HcmV?d00001 diff --git a/panda/python/Lib/site-packages/Crypto/__init__.py b/panda/python/Lib/site-packages/Crypto/__init__.py new file mode 100644 index 00000000..c27402e3 --- /dev/null +++ b/panda/python/Lib/site-packages/Crypto/__init__.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Python Cryptography Toolkit + +A collection of cryptographic modules implementing various algorithms +and protocols. + +Subpackages: + +Crypto.Cipher + Secret-key (AES, DES, ARC4) and public-key encryption (RSA PKCS#1) algorithms +Crypto.Hash + Hashing algorithms (MD5, SHA, HMAC) +Crypto.Protocol + Cryptographic protocols (Chaffing, all-or-nothing transform, key derivation + functions). This package does not contain any network protocols. +Crypto.PublicKey + Public-key encryption and signature algorithms (RSA, DSA) +Crypto.Signature + Public-key signature algorithms (RSA PKCS#1) +Crypto.Util + Various useful modules and functions (long-to-string conversion, random number + generation, number theoretic functions) +""" + +__all__ = ['Cipher', 'Hash', 'Protocol', 'PublicKey', 'Util', 'Signature'] + +__version__ = '2.6.1' # See also below and setup.py +__revision__ = "$Id$" + +# New software should look at this instead of at __version__ above. +version_info = (2, 6, 1, 'final', 0) # See also above and setup.py + diff --git a/panda/python/Lib/site-packages/Crypto/__init__.pyo b/panda/python/Lib/site-packages/Crypto/__init__.pyo new file mode 100644 index 0000000000000000000000000000000000000000..510c008141a81bc54ede2e6ac06e64cad3187d73 GIT binary patch literal 1139 zcmZ`&ZEw>s5cayQ8|L*RA5UT*Qj|mt1`^YRh&rU90jie4hbmI!CQf2CwJX~x>Yv~* z@uT{)z@_mvYko=J3 zLsAaO6oW@(it%GI#jVF=io1_U>^*UR{~Qo9S=&lU80+=Ys#3FMwT4@z>bbC#Mv$qx z=9v`;Q3Yf>l*nMA@}}kn#9~?V1(#OH5>`wL)fixPskE@w!cZo2SZZYzl9`awxS1_k zHfJR_=ag$-=-RH8+$K~eT#1Txc z$MLgMgzb**$gh~GC^+j<-0g$+`SP_7@m1u*)#qqD+GaE9(xrb2gC+N6fH$sKQ6Qa< ze0897AeC+Dt!B~`N-unHRpeZY6>|zwC>q&nX+|O3R>DB11LO*IL;}=XS|%ixx(3PZ zcctgML&HA3R)lN5rZD-Z9!@DEO37@a`JIAMDAY8L`cmU9><-s|f9_S@=JM5wn!>lP z?Tz6@Q};e8n%~91R$SrL zz%KNRBWm3!Z0?RdK-cxy9;37EpuOi7TfJJ0%eW2qrJF+py$s)kr^b<-e9TV-&IS>V zUF@N;4uS1vwLph_@!a|^Ov|#vv=DoQxHQdGmZqJL*9HCiZM-WV*ALpY<}2a!=mOhq zAq(Xpfb5L9z~%TnnV@d$)n#xRz71a_%XXTRPhyrBVR^8fvt%;}Nty~NY?_7$bShnJ TX87H6^o +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +# +# Base classes. All our warnings inherit from one of these in order to allow +# the user to specifically filter them. +# + +class CryptoWarning(Warning): + """Base class for PyCrypto warnings""" + +class CryptoDeprecationWarning(DeprecationWarning, CryptoWarning): + """Base PyCrypto DeprecationWarning class""" + +class CryptoRuntimeWarning(RuntimeWarning, CryptoWarning): + """Base PyCrypto RuntimeWarning class""" + +# +# Warnings that we might actually use +# + +class RandomPool_DeprecationWarning(CryptoDeprecationWarning): + """Issued when Crypto.Util.randpool.RandomPool is instantiated.""" + +class ClockRewindWarning(CryptoRuntimeWarning): + """Warning for when the system clock moves backwards.""" + +class GetRandomNumber_DeprecationWarning(CryptoDeprecationWarning): + """Issued when Crypto.Util.number.getRandomNumber is invoked.""" + +class PowmInsecureWarning(CryptoRuntimeWarning): + """Warning for when _fastmath is built without mpz_powm_sec""" + +# By default, we want this warning to be shown every time we compensate for +# clock rewinding. +import warnings as _warnings +_warnings.filterwarnings('always', category=ClockRewindWarning, append=1) + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/panda/python/Lib/site-packages/Crypto/pct_warnings.pyo b/panda/python/Lib/site-packages/Crypto/pct_warnings.pyo new file mode 100644 index 0000000000000000000000000000000000000000..7099d0fda2359996993e58ab87840abcd48f3eee GIT binary patch literal 2251 zcmcgtZEF)j5T465FHK*ptrYt~Sw$ouJ*@gcOOetRq#z}15wQf0&Fv;Rb8p=4^@v~V zXaASK#~+}xd(9;w2nI_o*}2`>y=V5B*`2X}Z8Xy#9qPgDQ^WT$Hu)0;2M_=~3%CW} z0d4@kT;ZSs0{<5DD!}b>!Unzq0{_KCwVbE|uYs@)PQBFDfHy!?jdr!v)`2(2Yu8F` z1Ni!Q?MA6x1-=RV9t2IeS_82LU)OQV0aK&Zo0kTmWC{EK+qTBT8&j|wc37htkw<092S;kpqE zh3l%O8H6#<0zIsoA&))RZDAKCLLTGr^sv)r5ofQ@_79wQ&dW|RQiC|^eDu2==_|3H zFmK5ELUszvoy1e_*t(O9sK$JZO;%9UEcFmy#nLm8q{3s$kE4aTKSvb9y<|L(R`|tu zfNF4@h|(-lekc|u`4kamNzNiInP3&S^K6RXBkWT= z8*$i<2TqD65;WjUY!P1)Kaz@}UzrlzSz3^F zDta;HgKg}e2C+A!BKIS{aEM>w_qQLJ3vAe{fgo}ul?XAyh)u%yT1e8xo0hYb%jMD4 z$-$YTt54(yp^8XcWMNmN{}uN`#QR&^BLnaBXU!F%zmA8?jCupNc`)UM9qhN`JUox2 z@UnFAoBb96=ECmwm{cKC1I@9U`GF$2kI6PuBuu`!2^w_K-qOzcDsJ-4gth-0p9`gL z01I-4=To}{^S9{7>8Q{riHNwblWj{EHd9<~d746?^nIC66jbL 0: + response = '[%s]' % ','.join(responses) + else: + response = '' + else: + result = validate_request(request) + if type(result) is Fault: + return result.response() + response = self._marshaled_single_dispatch(request) + return response + + def _marshaled_single_dispatch(self, request): + # TODO - Use the multiprocessing and skip the response if + # it is a notification + # Put in support for custom dispatcher here + # (See SimpleXMLRPCServer._marshaled_dispatch) + method = request.get('method') + params = request.get('params') + try: + response = self._dispatch(method, params) + except: + exc_type, exc_value, exc_tb = sys.exc_info() + fault = Fault(-32603, '%s:%s' % (exc_type, exc_value)) + return fault.response() + if 'id' not in request.keys() or request['id'] == None: + # It's a notification + return None + try: + response = jsonrpclib.dumps(response, + methodresponse=True, + rpcid=request['id'] + ) + return response + except: + exc_type, exc_value, exc_tb = sys.exc_info() + fault = Fault(-32603, '%s:%s' % (exc_type, exc_value)) + return fault.response() + + def _dispatch(self, method, params): + func = None + try: + func = self.funcs[method] + except KeyError: + if self.instance is not None: + if hasattr(self.instance, '_dispatch'): + return self.instance._dispatch(method, params) + else: + try: + func = SimpleXMLRPCServer.resolve_dotted_attribute( + self.instance, + method, + True + ) + except AttributeError: + pass + if func is not None: + try: + if type(params) is types.ListType: + response = func(*params) + else: + response = func(**params) + return response + except TypeError: + return Fault(-32602, 'Invalid parameters.') + except: + err_lines = traceback.format_exc().splitlines() + trace_string = '%s | %s' % (err_lines[-3], err_lines[-1]) + fault = jsonrpclib.Fault(-32603, 'Server error: %s' % + trace_string) + return fault + else: + return Fault(-32601, 'Method %s not supported.' % method) + +class SimpleJSONRPCRequestHandler( + SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): + + def do_POST(self): + if not self.is_rpc_path_valid(): + self.report_404() + return + try: + max_chunk_size = 10*1024*1024 + size_remaining = int(self.headers["content-length"]) + L = [] + while size_remaining: + chunk_size = min(size_remaining, max_chunk_size) + L.append(self.rfile.read(chunk_size)) + size_remaining -= len(L[-1]) + data = ''.join(L) + response = self.server._marshaled_dispatch(data) + self.send_response(200) + except Exception, e: + self.send_response(500) + err_lines = traceback.format_exc().splitlines() + trace_string = '%s | %s' % (err_lines[-3], err_lines[-1]) + fault = jsonrpclib.Fault(-32603, 'Server error: %s' % trace_string) + response = fault.response() + if response == None: + response = '' + self.send_header("Content-type", "application/json-rpc") + self.send_header("Content-length", str(len(response))) + self.end_headers() + self.wfile.write(response) + self.wfile.flush() + self.connection.shutdown(1) + +class SimpleJSONRPCServer(SocketServer.TCPServer, SimpleJSONRPCDispatcher): + + allow_reuse_address = True + + def __init__(self, addr, requestHandler=SimpleJSONRPCRequestHandler, + logRequests=True, encoding=None, bind_and_activate=True, + address_family=socket.AF_INET): + self.logRequests = logRequests + SimpleJSONRPCDispatcher.__init__(self, encoding) + # TCPServer.__init__ has an extra parameter on 2.6+, so + # check Python version and decide on how to call it + vi = sys.version_info + self.address_family = address_family + if USE_UNIX_SOCKETS and address_family == socket.AF_UNIX: + # Unix sockets can't be bound if they already exist in the + # filesystem. The convention of e.g. X11 is to unlink + # before binding again. + if os.path.exists(addr): + try: + os.unlink(addr) + except OSError: + logging.warning("Could not unlink socket %s", addr) + # if python 2.5 and lower + if vi[0] < 3 and vi[1] < 6: + SocketServer.TCPServer.__init__(self, addr, requestHandler) + else: + SocketServer.TCPServer.__init__(self, addr, requestHandler, + bind_and_activate) + if fcntl is not None and hasattr(fcntl, 'FD_CLOEXEC'): + flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD) + flags |= fcntl.FD_CLOEXEC + fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags) + +class CGIJSONRPCRequestHandler(SimpleJSONRPCDispatcher): + + def __init__(self, encoding=None): + SimpleJSONRPCDispatcher.__init__(self, encoding) + + def handle_jsonrpc(self, request_text): + response = self._marshaled_dispatch(request_text) + print 'Content-Type: application/json-rpc' + print 'Content-Length: %d' % len(response) + print + sys.stdout.write(response) + + handle_xmlrpc = handle_jsonrpc diff --git a/panda/python/Lib/site-packages/jsonrpclib/__init__.py b/panda/python/Lib/site-packages/jsonrpclib/__init__.py new file mode 100644 index 00000000..6e884b83 --- /dev/null +++ b/panda/python/Lib/site-packages/jsonrpclib/__init__.py @@ -0,0 +1,6 @@ +from jsonrpclib.config import Config +config = Config.instance() +from jsonrpclib.history import History +history = History.instance() +from jsonrpclib.jsonrpc import Server, MultiCall, Fault +from jsonrpclib.jsonrpc import ProtocolError, loads, dumps diff --git a/panda/python/Lib/site-packages/jsonrpclib/config.py b/panda/python/Lib/site-packages/jsonrpclib/config.py new file mode 100644 index 00000000..4d28f1b1 --- /dev/null +++ b/panda/python/Lib/site-packages/jsonrpclib/config.py @@ -0,0 +1,38 @@ +import sys + +class LocalClasses(dict): + def add(self, cls): + self[cls.__name__] = cls + +class Config(object): + """ + This is pretty much used exclusively for the 'jsonclass' + functionality... set use_jsonclass to False to turn it off. + You can change serialize_method and ignore_attribute, or use + the local_classes.add(class) to include "local" classes. + """ + use_jsonclass = True + # Change to False to keep __jsonclass__ entries raw. + serialize_method = '_serialize' + # The serialize_method should be a string that references the + # method on a custom class object which is responsible for + # returning a tuple of the constructor arguments and a dict of + # attributes. + ignore_attribute = '_ignore' + # The ignore attribute should be a string that references the + # attribute on a custom class object which holds strings and / or + # references of the attributes the class translator should ignore. + classes = LocalClasses() + # The list of classes to use for jsonclass translation. + version = 2.0 + # Version of the JSON-RPC spec to support + user_agent = 'jsonrpclib/0.1 (Python %s)' % \ + '.'.join([str(ver) for ver in sys.version_info[0:3]]) + # User agent to use for calls. + _instance = None + + @classmethod + def instance(cls): + if not cls._instance: + cls._instance = cls() + return cls._instance diff --git a/panda/python/Lib/site-packages/jsonrpclib/history.py b/panda/python/Lib/site-packages/jsonrpclib/history.py new file mode 100644 index 00000000..d11863dc --- /dev/null +++ b/panda/python/Lib/site-packages/jsonrpclib/history.py @@ -0,0 +1,40 @@ +class History(object): + """ + This holds all the response and request objects for a + session. A server using this should call "clear" after + each request cycle in order to keep it from clogging + memory. + """ + requests = [] + responses = [] + _instance = None + + @classmethod + def instance(cls): + if not cls._instance: + cls._instance = cls() + return cls._instance + + def add_response(self, response_obj): + self.responses.append(response_obj) + + def add_request(self, request_obj): + self.requests.append(request_obj) + + @property + def request(self): + if len(self.requests) == 0: + return None + else: + return self.requests[-1] + + @property + def response(self): + if len(self.responses) == 0: + return None + else: + return self.responses[-1] + + def clear(self): + del self.requests[:] + del self.responses[:] diff --git a/panda/python/Lib/site-packages/jsonrpclib/jsonclass.py b/panda/python/Lib/site-packages/jsonrpclib/jsonclass.py new file mode 100644 index 00000000..298c3da3 --- /dev/null +++ b/panda/python/Lib/site-packages/jsonrpclib/jsonclass.py @@ -0,0 +1,145 @@ +import types +import inspect +import re +import traceback + +from jsonrpclib import config + +iter_types = [ + types.DictType, + types.ListType, + types.TupleType +] + +string_types = [ + types.StringType, + types.UnicodeType +] + +numeric_types = [ + types.IntType, + types.LongType, + types.FloatType +] + +value_types = [ + types.BooleanType, + types.NoneType +] + +supported_types = iter_types+string_types+numeric_types+value_types +invalid_module_chars = r'[^a-zA-Z0-9\_\.]' + +class TranslationError(Exception): + pass + +def dump(obj, serialize_method=None, ignore_attribute=None, ignore=[]): + if not serialize_method: + serialize_method = config.serialize_method + if not ignore_attribute: + ignore_attribute = config.ignore_attribute + obj_type = type(obj) + # Parse / return default "types"... + if obj_type in numeric_types+string_types+value_types: + return obj + if obj_type in iter_types: + if obj_type in (types.ListType, types.TupleType): + new_obj = [] + for item in obj: + new_obj.append(dump(item, serialize_method, + ignore_attribute, ignore)) + if obj_type is types.TupleType: + new_obj = tuple(new_obj) + return new_obj + # It's a dict... + else: + new_obj = {} + for key, value in obj.iteritems(): + new_obj[key] = dump(value, serialize_method, + ignore_attribute, ignore) + return new_obj + # It's not a standard type, so it needs __jsonclass__ + module_name = inspect.getmodule(obj).__name__ + class_name = obj.__class__.__name__ + json_class = class_name + if module_name not in ['', '__main__']: + json_class = '%s.%s' % (module_name, json_class) + return_obj = {"__jsonclass__":[json_class,]} + # If a serialization method is defined.. + if serialize_method in dir(obj): + # Params can be a dict (keyword) or list (positional) + # Attrs MUST be a dict. + serialize = getattr(obj, serialize_method) + params, attrs = serialize() + return_obj['__jsonclass__'].append(params) + return_obj.update(attrs) + return return_obj + # Otherwise, try to figure it out + # Obviously, we can't assume to know anything about the + # parameters passed to __init__ + return_obj['__jsonclass__'].append([]) + attrs = {} + ignore_list = getattr(obj, ignore_attribute, [])+ignore + for attr_name, attr_value in obj.__dict__.iteritems(): + if type(attr_value) in supported_types and \ + attr_name not in ignore_list and \ + attr_value not in ignore_list: + attrs[attr_name] = dump(attr_value, serialize_method, + ignore_attribute, ignore) + return_obj.update(attrs) + return return_obj + +def load(obj): + if type(obj) in string_types+numeric_types+value_types: + return obj + if type(obj) is types.ListType: + return_list = [] + for entry in obj: + return_list.append(load(entry)) + return return_list + # Othewise, it's a dict type + if '__jsonclass__' not in obj.keys(): + return_dict = {} + for key, value in obj.iteritems(): + new_value = load(value) + return_dict[key] = new_value + return return_dict + # It's a dict, and it's a __jsonclass__ + orig_module_name = obj['__jsonclass__'][0] + params = obj['__jsonclass__'][1] + if orig_module_name == '': + raise TranslationError('Module name empty.') + json_module_clean = re.sub(invalid_module_chars, '', orig_module_name) + if json_module_clean != orig_module_name: + raise TranslationError('Module name %s has invalid characters.' % + orig_module_name) + json_module_parts = json_module_clean.split('.') + json_class = None + if len(json_module_parts) == 1: + # Local class name -- probably means it won't work + if json_module_parts[0] not in config.classes.keys(): + raise TranslationError('Unknown class or module %s.' % + json_module_parts[0]) + json_class = config.classes[json_module_parts[0]] + else: + json_class_name = json_module_parts.pop() + json_module_tree = '.'.join(json_module_parts) + try: + temp_module = __import__(json_module_tree) + except ImportError: + raise TranslationError('Could not import %s from module %s.' % + (json_class_name, json_module_tree)) + json_class = getattr(temp_module, json_class_name) + # Creating the object... + new_obj = None + if type(params) is types.ListType: + new_obj = json_class(*params) + elif type(params) is types.DictType: + new_obj = json_class(**params) + else: + raise TranslationError('Constructor args must be a dict or list.') + for key, value in obj.iteritems(): + if key == '__jsonclass__': + continue + setattr(new_obj, key, value) + return new_obj diff --git a/panda/python/Lib/site-packages/jsonrpclib/jsonrpc.py b/panda/python/Lib/site-packages/jsonrpclib/jsonrpc.py new file mode 100644 index 00000000..e11939ae --- /dev/null +++ b/panda/python/Lib/site-packages/jsonrpclib/jsonrpc.py @@ -0,0 +1,556 @@ +""" +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +============================ +JSONRPC Library (jsonrpclib) +============================ + +This library is a JSON-RPC v.2 (proposed) implementation which +follows the xmlrpclib API for portability between clients. It +uses the same Server / ServerProxy, loads, dumps, etc. syntax, +while providing features not present in XML-RPC like: + +* Keyword arguments +* Notifications +* Versioning +* Batches and batch notifications + +Eventually, I'll add a SimpleXMLRPCServer compatible library, +and other things to tie the thing off nicely. :) + +For a quick-start, just open a console and type the following, +replacing the server address, method, and parameters +appropriately. +>>> import jsonrpclib +>>> server = jsonrpclib.Server('http://localhost:8181') +>>> server.add(5, 6) +11 +>>> server._notify.add(5, 6) +>>> batch = jsonrpclib.MultiCall(server) +>>> batch.add(3, 50) +>>> batch.add(2, 3) +>>> batch._notify.add(3, 5) +>>> batch() +[53, 5] + +See http://code.google.com/p/jsonrpclib/ for more info. +""" + +import types +import sys +from xmlrpclib import Transport as XMLTransport +from xmlrpclib import SafeTransport as XMLSafeTransport +from xmlrpclib import ServerProxy as XMLServerProxy +from xmlrpclib import _Method as XML_Method +import time +import string +import random + +# Library includes +import jsonrpclib +from jsonrpclib import config +from jsonrpclib import history + +# JSON library importing +cjson = None +json = None +try: + import cjson +except ImportError: + try: + import json + except ImportError: + try: + import simplejson as json + except ImportError: + raise ImportError( + 'You must have the cjson, json, or simplejson ' + + 'module(s) available.' + ) + +IDCHARS = string.ascii_lowercase+string.digits + +class UnixSocketMissing(Exception): + """ + Just a properly named Exception if Unix Sockets usage is + attempted on a platform that doesn't support them (Windows) + """ + pass + +#JSON Abstractions + +def jdumps(obj, encoding='utf-8'): + # Do 'serialize' test at some point for other classes + global cjson + if cjson: + return cjson.encode(obj) + else: + return json.dumps(obj, encoding=encoding) + +def jloads(json_string): + global cjson + if cjson: + return cjson.decode(json_string) + else: + return json.loads(json_string) + + +# XMLRPClib re-implementations + +class ProtocolError(Exception): + pass + +class TransportMixIn(object): + """ Just extends the XMLRPC transport where necessary. """ + user_agent = config.user_agent + # for Python 2.7 support + _connection = None + + def send_content(self, connection, request_body): + connection.putheader("Content-Type", "application/json-rpc") + connection.putheader("Content-Length", str(len(request_body))) + connection.endheaders() + if request_body: + connection.send(request_body) + + def getparser(self): + target = JSONTarget() + return JSONParser(target), target + +class JSONParser(object): + def __init__(self, target): + self.target = target + + def feed(self, data): + self.target.feed(data) + + def close(self): + pass + +class JSONTarget(object): + def __init__(self): + self.data = [] + + def feed(self, data): + self.data.append(data) + + def close(self): + return ''.join(self.data) + +class Transport(TransportMixIn, XMLTransport): + pass + +class SafeTransport(TransportMixIn, XMLSafeTransport): + pass +from httplib import HTTP, HTTPConnection +from socket import socket + +USE_UNIX_SOCKETS = False + +try: + from socket import AF_UNIX, SOCK_STREAM + USE_UNIX_SOCKETS = True +except ImportError: + pass + +if (USE_UNIX_SOCKETS): + + class UnixHTTPConnection(HTTPConnection): + def connect(self): + self.sock = socket(AF_UNIX, SOCK_STREAM) + self.sock.connect(self.host) + + class UnixHTTP(HTTP): + _connection_class = UnixHTTPConnection + + class UnixTransport(TransportMixIn, XMLTransport): + def make_connection(self, host): + import httplib + host, extra_headers, x509 = self.get_host_info(host) + return UnixHTTP(host) + + +class ServerProxy(XMLServerProxy): + """ + Unfortunately, much more of this class has to be copied since + so much of it does the serialization. + """ + + def __init__(self, uri, transport=None, encoding=None, + verbose=0, version=None): + import urllib + if not version: + version = config.version + self.__version = version + schema, uri = urllib.splittype(uri) + if schema not in ('http', 'https', 'unix'): + raise IOError('Unsupported JSON-RPC protocol.') + if schema == 'unix': + if not USE_UNIX_SOCKETS: + # Don't like the "generic" Exception... + raise UnixSocketMissing("Unix sockets not available.") + self.__host = uri + self.__handler = '/' + else: + self.__host, self.__handler = urllib.splithost(uri) + if not self.__handler: + # Not sure if this is in the JSON spec? + #self.__handler = '/' + self.__handler == '/' + if transport is None: + if schema == 'unix': + transport = UnixTransport() + elif schema == 'https': + transport = SafeTransport() + else: + transport = Transport() + self.__transport = transport + self.__encoding = encoding + self.__verbose = verbose + + def _request(self, methodname, params, rpcid=None): + request = dumps(params, methodname, encoding=self.__encoding, + rpcid=rpcid, version=self.__version) + response = self._run_request(request) + check_for_errors(response) + return response['result'] + + def _request_notify(self, methodname, params, rpcid=None): + request = dumps(params, methodname, encoding=self.__encoding, + rpcid=rpcid, version=self.__version, notify=True) + response = self._run_request(request, notify=True) + check_for_errors(response) + return + + def _run_request(self, request, notify=None): + history.add_request(request) + + response = self.__transport.request( + self.__host, + self.__handler, + request, + verbose=self.__verbose + ) + + # Here, the XMLRPC library translates a single list + # response to the single value -- should we do the + # same, and require a tuple / list to be passed to + # the response object, or expect the Server to be + # outputting the response appropriately? + + history.add_response(response) + if not response: + return None + return_obj = loads(response) + return return_obj + + def __getattr__(self, name): + # Same as original, just with new _Method reference + return _Method(self._request, name) + + @property + def _notify(self): + # Just like __getattr__, but with notify namespace. + return _Notify(self._request_notify) + + +class _Method(XML_Method): + + def __call__(self, *args, **kwargs): + if len(args) > 0 and len(kwargs) > 0: + raise ProtocolError('Cannot use both positional ' + + 'and keyword arguments (according to JSON-RPC spec.)') + if len(args) > 0: + return self.__send(self.__name, args) + else: + return self.__send(self.__name, kwargs) + + def __getattr__(self, name): + self.__name = '%s.%s' % (self.__name, name) + return self + # The old method returned a new instance, but this seemed wasteful. + # The only thing that changes is the name. + #return _Method(self.__send, "%s.%s" % (self.__name, name)) + +class _Notify(object): + def __init__(self, request): + self._request = request + + def __getattr__(self, name): + return _Method(self._request, name) + +# Batch implementation + +class MultiCallMethod(object): + + def __init__(self, method, notify=False): + self.method = method + self.params = [] + self.notify = notify + + def __call__(self, *args, **kwargs): + if len(kwargs) > 0 and len(args) > 0: + raise ProtocolError('JSON-RPC does not support both ' + + 'positional and keyword arguments.') + if len(kwargs) > 0: + self.params = kwargs + else: + self.params = args + + def request(self, encoding=None, rpcid=None): + return dumps(self.params, self.method, version=2.0, + encoding=encoding, rpcid=rpcid, notify=self.notify) + + def __repr__(self): + return '%s' % self.request() + + def __getattr__(self, method): + new_method = '%s.%s' % (self.method, method) + self.method = new_method + return self + +class MultiCallNotify(object): + + def __init__(self, multicall): + self.multicall = multicall + + def __getattr__(self, name): + new_job = MultiCallMethod(name, notify=True) + self.multicall._job_list.append(new_job) + return new_job + +class MultiCallIterator(object): + + def __init__(self, results): + self.results = results + + def __iter__(self): + for i in range(0, len(self.results)): + yield self[i] + raise StopIteration + + def __getitem__(self, i): + item = self.results[i] + check_for_errors(item) + return item['result'] + + def __len__(self): + return len(self.results) + +class MultiCall(object): + + def __init__(self, server): + self._server = server + self._job_list = [] + + def _request(self): + if len(self._job_list) < 1: + # Should we alert? This /is/ pretty obvious. + return + request_body = '[ %s ]' % ','.join([job.request() for + job in self._job_list]) + responses = self._server._run_request(request_body) + del self._job_list[:] + if not responses: + responses = [] + return MultiCallIterator(responses) + + @property + def _notify(self): + return MultiCallNotify(self) + + def __getattr__(self, name): + new_job = MultiCallMethod(name) + self._job_list.append(new_job) + return new_job + + __call__ = _request + +# These lines conform to xmlrpclib's "compatibility" line. +# Not really sure if we should include these, but oh well. +Server = ServerProxy + +class Fault(object): + # JSON-RPC error class + def __init__(self, code=-32000, message='Server error', rpcid=None): + self.faultCode = code + self.faultString = message + self.rpcid = rpcid + + def error(self): + return {'code':self.faultCode, 'message':self.faultString} + + def response(self, rpcid=None, version=None): + if not version: + version = config.version + if rpcid: + self.rpcid = rpcid + return dumps( + self, methodresponse=True, rpcid=self.rpcid, version=version + ) + + def __repr__(self): + return '' % (self.faultCode, self.faultString) + +def random_id(length=8): + return_id = '' + for i in range(length): + return_id += random.choice(IDCHARS) + return return_id + +class Payload(dict): + def __init__(self, rpcid=None, version=None): + if not version: + version = config.version + self.id = rpcid + self.version = float(version) + + def request(self, method, params=[]): + if type(method) not in types.StringTypes: + raise ValueError('Method name must be a string.') + if not self.id: + self.id = random_id() + request = { 'id':self.id, 'method':method } + if params: + request['params'] = params + if self.version >= 2: + request['jsonrpc'] = str(self.version) + return request + + def notify(self, method, params=[]): + request = self.request(method, params) + if self.version >= 2: + del request['id'] + else: + request['id'] = None + return request + + def response(self, result=None): + response = {'result':result, 'id':self.id} + if self.version >= 2: + response['jsonrpc'] = str(self.version) + else: + response['error'] = None + return response + + def error(self, code=-32000, message='Server error.'): + error = self.response() + if self.version >= 2: + del error['result'] + else: + error['result'] = None + error['error'] = {'code':code, 'message':message} + return error + +def dumps(params=[], methodname=None, methodresponse=None, + encoding=None, rpcid=None, version=None, notify=None): + """ + This differs from the Python implementation in that it implements + the rpcid argument since the 2.0 spec requires it for responses. + """ + if not version: + version = config.version + valid_params = (types.TupleType, types.ListType, types.DictType) + if methodname in types.StringTypes and \ + type(params) not in valid_params and \ + not isinstance(params, Fault): + """ + If a method, and params are not in a listish or a Fault, + error out. + """ + raise TypeError('Params must be a dict, list, tuple or Fault ' + + 'instance.') + # Begin parsing object + payload = Payload(rpcid=rpcid, version=version) + if not encoding: + encoding = 'utf-8' + if type(params) is Fault: + response = payload.error(params.faultCode, params.faultString) + return jdumps(response, encoding=encoding) + if type(methodname) not in types.StringTypes and methodresponse != True: + raise ValueError('Method name must be a string, or methodresponse '+ + 'must be set to True.') + if config.use_jsonclass == True: + from jsonrpclib import jsonclass + params = jsonclass.dump(params) + if methodresponse is True: + if rpcid is None: + raise ValueError('A method response must have an rpcid.') + response = payload.response(params) + return jdumps(response, encoding=encoding) + request = None + if notify == True: + request = payload.notify(methodname, params) + else: + request = payload.request(methodname, params) + return jdumps(request, encoding=encoding) + +def loads(data): + """ + This differs from the Python implementation, in that it returns + the request structure in Dict format instead of the method, params. + It will return a list in the case of a batch request / response. + """ + if data == '': + # notification + return None + result = jloads(data) + # if the above raises an error, the implementing server code + # should return something like the following: + # { 'jsonrpc':'2.0', 'error': fault.error(), id: None } + if config.use_jsonclass == True: + from jsonrpclib import jsonclass + result = jsonclass.load(result) + return result + +def check_for_errors(result): + if not result: + # Notification + return result + if type(result) is not types.DictType: + raise TypeError('Response is not a dict.') + if 'jsonrpc' in result.keys() and float(result['jsonrpc']) > 2.0: + raise NotImplementedError('JSON-RPC version not yet supported.') + if 'result' not in result.keys() and 'error' not in result.keys(): + raise ValueError('Response does not have a result or error key.') + if 'error' in result.keys() and result['error'] != None: + code = result['error']['code'] + message = result['error']['message'] + raise ProtocolError((code, message)) + return result + +def isbatch(result): + if type(result) not in (types.ListType, types.TupleType): + return False + if len(result) < 1: + return False + if type(result[0]) is not types.DictType: + return False + if 'jsonrpc' not in result[0].keys(): + return False + try: + version = float(result[0]['jsonrpc']) + except ValueError: + raise ProtocolError('"jsonrpc" key must be a float(able) value.') + if version < 2: + return False + return True + +def isnotification(request): + if 'id' not in request.keys(): + # 2.0 notification + return True + if request['id'] == None: + # 1.0 notification + return True + return False diff --git a/tools/generate_key.py b/tools/generate_key.py new file mode 100644 index 00000000..84fd4736 --- /dev/null +++ b/tools/generate_key.py @@ -0,0 +1,38 @@ +from Crypto.Cipher import AES +from Crypto import Random +import base64 +import os + +# the block size for the cipher object; must be 16, 24, or 32 for AES +BLOCK_SIZE = 16 + +# the character used for padding--with a block cipher such as AES, the value +# you encrypt must be a multiple of BLOCK_SIZE in length. This character is +# used to ensure that your value is always a multiple of BLOCK_SIZE +PADDING = '{' + +# one-liner to sufficiently pad the text to be encrypted +pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING + +# one-liners to encrypt/encode and decrypt/decode a string +# encrypt with AES, encode with base64 +EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s))) +DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING) + +# generate a random secret key +secret = os.urandom(BLOCK_SIZE) + +# create a cipher object using the random secret +cipher = AES.new( secret, AES.MODE_CBC, secret ) + +# encode a string +encoded = EncodeAES(cipher, 'tturpclib691256') +print 'Encrypted string:', encoded + +# decode the encoded string +decoded = DecodeAES(cipher, encoded) +print 'Decrypted string:', decoded + + + + diff --git a/tools/key.txt b/tools/key.txt new file mode 100644 index 00000000..e69de29b