From c4d90bf4ea0c5b7a016028ed994de19638d3113b Mon Sep 17 00:00:00 2001 From: Determinant Date: Tue, 17 Nov 2020 20:04:09 -0500 Subject: support saving as a keystore file --- README.rst | 25 +- frozen_deps/Crypto/Cipher/AES.py | 115 -- frozen_deps/Crypto/Cipher/ARC2.py | 130 -- frozen_deps/Crypto/Cipher/ARC4.py | 120 -- frozen_deps/Crypto/Cipher/Blowfish.py | 121 -- frozen_deps/Crypto/Cipher/CAST.py | 123 -- frozen_deps/Crypto/Cipher/DES.py | 118 -- frozen_deps/Crypto/Cipher/DES3.py | 133 -- frozen_deps/Crypto/Cipher/PKCS1_OAEP.py | 255 ---- frozen_deps/Crypto/Cipher/PKCS1_v1_5.py | 226 --- frozen_deps/Crypto/Cipher/XOR.py | 86 -- .../Cipher/_AES.cpython-38-x86_64-linux-gnu.so | Bin 43640 -> 0 bytes .../Cipher/_ARC2.cpython-38-x86_64-linux-gnu.so | Bin 26904 -> 0 bytes .../Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so | Bin 18064 -> 0 bytes .../_Blowfish.cpython-38-x86_64-linux-gnu.so | Bin 35368 -> 0 bytes .../Cipher/_CAST.cpython-38-x86_64-linux-gnu.so | Bin 35320 -> 0 bytes .../Cipher/_DES.cpython-38-x86_64-linux-gnu.so | Bin 68560 -> 0 bytes .../Cipher/_DES3.cpython-38-x86_64-linux-gnu.so | Bin 68560 -> 0 bytes .../Cipher/_XOR.cpython-38-x86_64-linux-gnu.so | Bin 18096 -> 0 bytes frozen_deps/Crypto/Cipher/__init__.py | 83 -- frozen_deps/Crypto/Cipher/blockalgo.py | 296 ---- frozen_deps/Crypto/Hash/HMAC.py | 212 --- frozen_deps/Crypto/Hash/MD2.py | 91 -- frozen_deps/Crypto/Hash/MD4.py | 91 -- frozen_deps/Crypto/Hash/MD5.py | 97 -- frozen_deps/Crypto/Hash/RIPEMD.py | 94 -- frozen_deps/Crypto/Hash/SHA.py | 98 -- frozen_deps/Crypto/Hash/SHA224.py | 95 -- frozen_deps/Crypto/Hash/SHA256.py | 95 -- frozen_deps/Crypto/Hash/SHA384.py | 96 -- frozen_deps/Crypto/Hash/SHA512.py | 95 -- .../Hash/_MD2.cpython-38-x86_64-linux-gnu.so | Bin 18464 -> 0 bytes .../Hash/_MD4.cpython-38-x86_64-linux-gnu.so | Bin 18552 -> 0 bytes .../Hash/_RIPEMD160.cpython-38-x86_64-linux-gnu.so | Bin 22888 -> 0 bytes .../Hash/_SHA224.cpython-38-x86_64-linux-gnu.so | Bin 18496 -> 0 bytes .../Hash/_SHA256.cpython-38-x86_64-linux-gnu.so | Bin 18496 -> 0 bytes .../Hash/_SHA384.cpython-38-x86_64-linux-gnu.so | Bin 22592 -> 0 bytes .../Hash/_SHA512.cpython-38-x86_64-linux-gnu.so | Bin 22592 -> 0 bytes frozen_deps/Crypto/Hash/__init__.py | 56 - frozen_deps/Crypto/Hash/hashalgo.py | 116 -- frozen_deps/Crypto/Protocol/AllOrNothing.py | 320 ----- frozen_deps/Crypto/Protocol/Chaffing.py | 245 ---- frozen_deps/Crypto/Protocol/KDF.py | 123 -- frozen_deps/Crypto/Protocol/__init__.py | 41 - frozen_deps/Crypto/PublicKey/DSA.py | 379 ----- frozen_deps/Crypto/PublicKey/ElGamal.py | 373 ----- frozen_deps/Crypto/PublicKey/RSA.py | 719 ---------- frozen_deps/Crypto/PublicKey/_DSA.py | 115 -- frozen_deps/Crypto/PublicKey/_RSA.py | 81 -- frozen_deps/Crypto/PublicKey/__init__.py | 41 - .../_fastmath.cpython-38-x86_64-linux-gnu.so | Bin 78864 -> 0 bytes frozen_deps/Crypto/PublicKey/_slowmath.py | 187 --- frozen_deps/Crypto/PublicKey/pubkey.py | 240 ---- .../Crypto/Random/Fortuna/FortunaAccumulator.py | 171 --- .../Crypto/Random/Fortuna/FortunaGenerator.py | 132 -- frozen_deps/Crypto/Random/Fortuna/SHAd256.py | 98 -- frozen_deps/Crypto/Random/Fortuna/__init__.py | 0 frozen_deps/Crypto/Random/OSRNG/__init__.py | 40 - frozen_deps/Crypto/Random/OSRNG/fallback.py | 46 - frozen_deps/Crypto/Random/OSRNG/posix.py | 86 -- frozen_deps/Crypto/Random/OSRNG/rng_base.py | 88 -- frozen_deps/Crypto/Random/_UserFriendlyRNG.py | 230 --- frozen_deps/Crypto/Random/__init__.py | 43 - frozen_deps/Crypto/Random/random.py | 142 -- frozen_deps/Crypto/Signature/PKCS1_PSS.py | 355 ----- frozen_deps/Crypto/Signature/PKCS1_v1_5.py | 236 ---- frozen_deps/Crypto/Signature/__init__.py | 31 - frozen_deps/Crypto/Util/Counter.py | 127 -- frozen_deps/Crypto/Util/RFC1751.py | 365 ----- frozen_deps/Crypto/Util/__init__.py | 37 - .../Util/_counter.cpython-38-x86_64-linux-gnu.so | Bin 22856 -> 0 bytes frozen_deps/Crypto/Util/_number_new.py | 119 -- frozen_deps/Crypto/Util/asn1.py | 286 ---- frozen_deps/Crypto/Util/number.py | 1456 ------------------- frozen_deps/Crypto/Util/py3compat.py | 107 -- frozen_deps/Crypto/Util/randpool.py | 82 -- .../Util/strxor.cpython-38-x86_64-linux-gnu.so | Bin 16784 -> 0 bytes frozen_deps/Crypto/Util/winrandom.py | 28 - frozen_deps/Crypto/__init__.py | 51 - frozen_deps/Crypto/pct_warnings.py | 60 - frozen_deps/Cryptodome/Cipher/AES.py | 250 ++++ frozen_deps/Cryptodome/Cipher/AES.pyi | 47 + frozen_deps/Cryptodome/Cipher/ARC2.py | 175 +++ frozen_deps/Cryptodome/Cipher/ARC2.pyi | 35 + frozen_deps/Cryptodome/Cipher/ARC4.py | 137 ++ frozen_deps/Cryptodome/Cipher/ARC4.pyi | 16 + frozen_deps/Cryptodome/Cipher/Blowfish.py | 159 +++ frozen_deps/Cryptodome/Cipher/Blowfish.pyi | 35 + frozen_deps/Cryptodome/Cipher/CAST.py | 159 +++ frozen_deps/Cryptodome/Cipher/CAST.pyi | 35 + frozen_deps/Cryptodome/Cipher/ChaCha20.py | 286 ++++ frozen_deps/Cryptodome/Cipher/ChaCha20.pyi | 25 + frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.py | 336 +++++ .../Cryptodome/Cipher/ChaCha20_Poly1305.pyi | 28 + frozen_deps/Cryptodome/Cipher/DES.py | 158 +++ frozen_deps/Cryptodome/Cipher/DES.pyi | 35 + frozen_deps/Cryptodome/Cipher/DES3.py | 187 +++ frozen_deps/Cryptodome/Cipher/DES3.pyi | 37 + frozen_deps/Cryptodome/Cipher/PKCS1_OAEP.py | 239 ++++ frozen_deps/Cryptodome/Cipher/PKCS1_OAEP.pyi | 35 + frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.py | 199 +++ frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.pyi | 17 + frozen_deps/Cryptodome/Cipher/Salsa20.py | 167 +++ frozen_deps/Cryptodome/Cipher/Salsa20.pyi | 27 + .../Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 14354 bytes frozen_deps/Cryptodome/Cipher/_EKSBlowfish.py | 131 ++ frozen_deps/Cryptodome/Cipher/_EKSBlowfish.pyi | 15 + .../Cipher/_Salsa20.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 21734 bytes frozen_deps/Cryptodome/Cipher/__init__.py | 79 ++ frozen_deps/Cryptodome/Cipher/__init__.pyi | 0 .../_chacha20.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 25741 bytes frozen_deps/Cryptodome/Cipher/_mode_cbc.py | 293 ++++ frozen_deps/Cryptodome/Cipher/_mode_cbc.pyi | 25 + frozen_deps/Cryptodome/Cipher/_mode_ccm.py | 650 +++++++++ frozen_deps/Cryptodome/Cipher/_mode_ccm.pyi | 47 + frozen_deps/Cryptodome/Cipher/_mode_cfb.py | 293 ++++ frozen_deps/Cryptodome/Cipher/_mode_cfb.pyi | 26 + frozen_deps/Cryptodome/Cipher/_mode_ctr.py | 393 ++++++ frozen_deps/Cryptodome/Cipher/_mode_ctr.pyi | 27 + frozen_deps/Cryptodome/Cipher/_mode_eax.py | 408 ++++++ frozen_deps/Cryptodome/Cipher/_mode_eax.pyi | 45 + frozen_deps/Cryptodome/Cipher/_mode_ecb.py | 218 +++ frozen_deps/Cryptodome/Cipher/_mode_ecb.pyi | 19 + frozen_deps/Cryptodome/Cipher/_mode_gcm.py | 620 +++++++++ frozen_deps/Cryptodome/Cipher/_mode_gcm.pyi | 45 + frozen_deps/Cryptodome/Cipher/_mode_ocb.py | 525 +++++++ frozen_deps/Cryptodome/Cipher/_mode_ocb.pyi | 36 + frozen_deps/Cryptodome/Cipher/_mode_ofb.py | 282 ++++ frozen_deps/Cryptodome/Cipher/_mode_ofb.pyi | 25 + frozen_deps/Cryptodome/Cipher/_mode_openpgp.py | 206 +++ frozen_deps/Cryptodome/Cipher/_mode_openpgp.pyi | 20 + frozen_deps/Cryptodome/Cipher/_mode_siv.py | 392 ++++++ frozen_deps/Cryptodome/Cipher/_mode_siv.pyi | 38 + .../Cipher/_raw_aes.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 54112 bytes .../_raw_aesni.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 52331 bytes .../_raw_arc2.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 18917 bytes .../_raw_blowfish.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 26938 bytes .../_raw_cast.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 44422 bytes .../Cipher/_raw_cbc.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 17215 bytes .../Cipher/_raw_cfb.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 22696 bytes .../Cipher/_raw_ctr.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 23249 bytes .../Cipher/_raw_des.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 62525 bytes .../_raw_des3.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 63370 bytes .../Cipher/_raw_ecb.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 10893 bytes ..._raw_eksblowfish.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 58926 bytes .../Cipher/_raw_ocb.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 30281 bytes .../Cipher/_raw_ofb.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 14743 bytes frozen_deps/Cryptodome/Hash/BLAKE2b.py | 247 ++++ frozen_deps/Cryptodome/Hash/BLAKE2b.pyi | 31 + frozen_deps/Cryptodome/Hash/BLAKE2s.py | 247 ++++ frozen_deps/Cryptodome/Hash/BLAKE2s.pyi | 26 + frozen_deps/Cryptodome/Hash/CMAC.py | 305 ++++ frozen_deps/Cryptodome/Hash/CMAC.pyi | 30 + frozen_deps/Cryptodome/Hash/HMAC.py | 213 +++ frozen_deps/Cryptodome/Hash/HMAC.pyi | 25 + frozen_deps/Cryptodome/Hash/MD2.py | 166 +++ frozen_deps/Cryptodome/Hash/MD2.pyi | 19 + frozen_deps/Cryptodome/Hash/MD4.py | 185 +++ frozen_deps/Cryptodome/Hash/MD4.pyi | 19 + frozen_deps/Cryptodome/Hash/MD5.py | 184 +++ frozen_deps/Cryptodome/Hash/MD5.pyi | 19 + frozen_deps/Cryptodome/Hash/Poly1305.py | 217 +++ frozen_deps/Cryptodome/Hash/Poly1305.pyi | 24 + frozen_deps/Cryptodome/Hash/RIPEMD.py | 26 + frozen_deps/Cryptodome/Hash/RIPEMD.pyi | 3 + frozen_deps/Cryptodome/Hash/RIPEMD160.py | 169 +++ frozen_deps/Cryptodome/Hash/RIPEMD160.pyi | 19 + frozen_deps/Cryptodome/Hash/SHA.py | 24 + frozen_deps/Cryptodome/Hash/SHA.pyi | 4 + frozen_deps/Cryptodome/Hash/SHA1.py | 185 +++ frozen_deps/Cryptodome/Hash/SHA1.pyi | 19 + frozen_deps/Cryptodome/Hash/SHA224.py | 186 +++ frozen_deps/Cryptodome/Hash/SHA224.pyi | 19 + frozen_deps/Cryptodome/Hash/SHA256.py | 185 +++ frozen_deps/Cryptodome/Hash/SHA256.pyi | 18 + frozen_deps/Cryptodome/Hash/SHA384.py | 186 +++ frozen_deps/Cryptodome/Hash/SHA384.pyi | 19 + frozen_deps/Cryptodome/Hash/SHA3_224.py | 147 ++ frozen_deps/Cryptodome/Hash/SHA3_224.pyi | 16 + frozen_deps/Cryptodome/Hash/SHA3_256.py | 147 ++ frozen_deps/Cryptodome/Hash/SHA3_256.pyi | 16 + frozen_deps/Cryptodome/Hash/SHA3_384.py | 147 ++ frozen_deps/Cryptodome/Hash/SHA3_384.pyi | 16 + frozen_deps/Cryptodome/Hash/SHA3_512.py | 148 ++ frozen_deps/Cryptodome/Hash/SHA3_512.pyi | 16 + frozen_deps/Cryptodome/Hash/SHA512.py | 204 +++ frozen_deps/Cryptodome/Hash/SHA512.pyi | 22 + frozen_deps/Cryptodome/Hash/SHAKE128.py | 127 ++ frozen_deps/Cryptodome/Hash/SHAKE128.pyi | 13 + frozen_deps/Cryptodome/Hash/SHAKE256.py | 127 ++ frozen_deps/Cryptodome/Hash/SHAKE256.pyi | 13 + .../Hash/_BLAKE2b.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 20015 bytes .../Hash/_BLAKE2s.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 20807 bytes .../Hash/_MD2.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 16919 bytes .../Hash/_MD4.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 19072 bytes .../Hash/_MD5.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 25434 bytes .../Hash/_RIPEMD160.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 27226 bytes .../Hash/_SHA1.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 84273 bytes .../Hash/_SHA224.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 35822 bytes .../Hash/_SHA256.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 35806 bytes .../Hash/_SHA384.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 41869 bytes .../Hash/_SHA512.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 41967 bytes frozen_deps/Cryptodome/Hash/__init__.py | 22 + frozen_deps/Cryptodome/Hash/__init__.pyi | 0 .../_ghash_clmul.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 34203 bytes .../_ghash_portable.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 18711 bytes .../Hash/_keccak.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 26749 bytes .../Hash/_poly1305.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 25921 bytes frozen_deps/Cryptodome/Hash/keccak.py | 173 +++ frozen_deps/Cryptodome/Hash/keccak.pyi | 23 + frozen_deps/Cryptodome/IO/PEM.py | 189 +++ frozen_deps/Cryptodome/IO/PEM.pyi | 10 + frozen_deps/Cryptodome/IO/PKCS8.py | 231 +++ frozen_deps/Cryptodome/IO/PKCS8.pyi | 14 + frozen_deps/Cryptodome/IO/_PBES.py | 435 ++++++ frozen_deps/Cryptodome/IO/_PBES.pyi | 19 + frozen_deps/Cryptodome/IO/__init__.py | 31 + frozen_deps/Cryptodome/Math/Numbers.py | 42 + frozen_deps/Cryptodome/Math/Numbers.pyi | 4 + frozen_deps/Cryptodome/Math/Primality.py | 368 +++++ frozen_deps/Cryptodome/Math/Primality.pyi | 18 + frozen_deps/Cryptodome/Math/_IntegerBase.py | 392 ++++++ frozen_deps/Cryptodome/Math/_IntegerBase.pyi | 61 + frozen_deps/Cryptodome/Math/_IntegerCustom.py | 111 ++ frozen_deps/Cryptodome/Math/_IntegerCustom.pyi | 8 + frozen_deps/Cryptodome/Math/_IntegerGMP.py | 708 ++++++++++ frozen_deps/Cryptodome/Math/_IntegerGMP.pyi | 3 + frozen_deps/Cryptodome/Math/_IntegerNative.py | 380 +++++ frozen_deps/Cryptodome/Math/_IntegerNative.pyi | 3 + frozen_deps/Cryptodome/Math/__init__.py | 0 .../Math/_modexp.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 207274 bytes frozen_deps/Cryptodome/Protocol/KDF.py | 574 ++++++++ frozen_deps/Cryptodome/Protocol/KDF.pyi | 24 + frozen_deps/Cryptodome/Protocol/SecretSharing.py | 278 ++++ frozen_deps/Cryptodome/Protocol/SecretSharing.pyi | 22 + frozen_deps/Cryptodome/Protocol/__init__.py | 31 + frozen_deps/Cryptodome/Protocol/__init__.pyi | 1 + .../_scrypt.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 16510 bytes frozen_deps/Cryptodome/PublicKey/DSA.py | 679 +++++++++ frozen_deps/Cryptodome/PublicKey/DSA.pyi | 30 + frozen_deps/Cryptodome/PublicKey/ECC.py | 1184 ++++++++++++++++ frozen_deps/Cryptodome/PublicKey/ECC.pyi | 62 + frozen_deps/Cryptodome/PublicKey/ElGamal.py | 286 ++++ frozen_deps/Cryptodome/PublicKey/ElGamal.pyi | 18 + frozen_deps/Cryptodome/PublicKey/RSA.py | 796 +++++++++++ frozen_deps/Cryptodome/PublicKey/RSA.pyi | 50 + frozen_deps/Cryptodome/PublicKey/__init__.py | 95 ++ frozen_deps/Cryptodome/PublicKey/__init__.pyi | 0 .../_ec_ws.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 1000375 bytes frozen_deps/Cryptodome/PublicKey/_openssh.py | 135 ++ frozen_deps/Cryptodome/PublicKey/_openssh.pyi | 7 + frozen_deps/Cryptodome/Random/__init__.py | 57 + frozen_deps/Cryptodome/Random/__init__.pyi | 19 + frozen_deps/Cryptodome/Random/random.py | 138 ++ frozen_deps/Cryptodome/Random/random.pyi | 20 + frozen_deps/Cryptodome/Signature/DSS.py | 413 ++++++ frozen_deps/Cryptodome/Signature/DSS.pyi | 27 + frozen_deps/Cryptodome/Signature/PKCS1_PSS.py | 55 + frozen_deps/Cryptodome/Signature/PKCS1_PSS.pyi | 7 + frozen_deps/Cryptodome/Signature/PKCS1_v1_5.py | 53 + frozen_deps/Cryptodome/Signature/PKCS1_v1_5.pyi | 6 + frozen_deps/Cryptodome/Signature/__init__.py | 36 + frozen_deps/Cryptodome/Signature/pkcs1_15.py | 222 +++ frozen_deps/Cryptodome/Signature/pkcs1_15.pyi | 17 + frozen_deps/Cryptodome/Signature/pss.py | 386 +++++ frozen_deps/Cryptodome/Signature/pss.pyi | 30 + frozen_deps/Cryptodome/Util/Counter.py | 70 + frozen_deps/Cryptodome/Util/Counter.pyi | 5 + frozen_deps/Cryptodome/Util/Padding.py | 106 ++ frozen_deps/Cryptodome/Util/Padding.pyi | 6 + frozen_deps/Cryptodome/Util/RFC1751.py | 386 +++++ frozen_deps/Cryptodome/Util/RFC1751.pyi | 7 + frozen_deps/Cryptodome/Util/__init__.py | 41 + frozen_deps/Cryptodome/Util/_cpu_features.py | 46 + frozen_deps/Cryptodome/Util/_cpu_features.pyi | 2 + .../Util/_cpuid_c.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 10899 bytes frozen_deps/Cryptodome/Util/_file_system.py | 54 + frozen_deps/Cryptodome/Util/_file_system.pyi | 4 + frozen_deps/Cryptodome/Util/_raw_api.py | 327 +++++ frozen_deps/Cryptodome/Util/_raw_api.pyi | 27 + .../Util/_strxor.cpython-38-x86_64-linux-gnu.so | Bin 0 -> 13213 bytes frozen_deps/Cryptodome/Util/asn1.py | 940 +++++++++++++ frozen_deps/Cryptodome/Util/asn1.pyi | 74 + frozen_deps/Cryptodome/Util/number.py | 1469 ++++++++++++++++++++ frozen_deps/Cryptodome/Util/number.pyi | 19 + frozen_deps/Cryptodome/Util/py3compat.py | 164 +++ frozen_deps/Cryptodome/Util/py3compat.pyi | 35 + frozen_deps/Cryptodome/Util/strxor.py | 137 ++ frozen_deps/Cryptodome/Util/strxor.pyi | 6 + frozen_deps/Cryptodome/__init__.py | 6 + frozen_deps/Cryptodome/__init__.pyi | 4 + frozen_deps/Cryptodome/py.typed | 0 frozen_deps/bin/keytree.py | 46 +- frozen_deps/keytree.py-0.2.dist-info/METADATA | 2 +- frozen_deps/keytree.py-0.2.dist-info/RECORD | 4 +- frozen_deps/pycrypto-2.6.1.dist-info/INSTALLER | 1 - frozen_deps/pycrypto-2.6.1.dist-info/METADATA | 22 - frozen_deps/pycrypto-2.6.1.dist-info/RECORD | 261 ---- frozen_deps/pycrypto-2.6.1.dist-info/WHEEL | 5 - frozen_deps/pycrypto-2.6.1.dist-info/top_level.txt | 1 - .../pycryptodomex-3.9.9.dist-info/AUTHORS.rst | 49 + .../pycryptodomex-3.9.9.dist-info/INSTALLER | 1 + .../pycryptodomex-3.9.9.dist-info/LICENSE.rst | 274 ++++ frozen_deps/pycryptodomex-3.9.9.dist-info/METADATA | 84 ++ frozen_deps/pycryptodomex-3.9.9.dist-info/RECORD | 794 +++++++++++ frozen_deps/pycryptodomex-3.9.9.dist-info/WHEEL | 5 + .../pycryptodomex-3.9.9.dist-info/top_level.txt | 1 + keytree.py | 46 +- setup.py | 2 +- 309 files changed, 26106 insertions(+), 10637 deletions(-) delete mode 100644 frozen_deps/Crypto/Cipher/AES.py delete mode 100644 frozen_deps/Crypto/Cipher/ARC2.py delete mode 100644 frozen_deps/Crypto/Cipher/ARC4.py delete mode 100644 frozen_deps/Crypto/Cipher/Blowfish.py delete mode 100644 frozen_deps/Crypto/Cipher/CAST.py delete mode 100644 frozen_deps/Crypto/Cipher/DES.py delete mode 100644 frozen_deps/Crypto/Cipher/DES3.py delete mode 100644 frozen_deps/Crypto/Cipher/PKCS1_OAEP.py delete mode 100644 frozen_deps/Crypto/Cipher/PKCS1_v1_5.py delete mode 100644 frozen_deps/Crypto/Cipher/XOR.py delete mode 100755 frozen_deps/Crypto/Cipher/_AES.cpython-38-x86_64-linux-gnu.so delete mode 100755 frozen_deps/Crypto/Cipher/_ARC2.cpython-38-x86_64-linux-gnu.so delete mode 100755 frozen_deps/Crypto/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so delete mode 100755 frozen_deps/Crypto/Cipher/_Blowfish.cpython-38-x86_64-linux-gnu.so delete mode 100755 frozen_deps/Crypto/Cipher/_CAST.cpython-38-x86_64-linux-gnu.so delete mode 100755 frozen_deps/Crypto/Cipher/_DES.cpython-38-x86_64-linux-gnu.so delete mode 100755 frozen_deps/Crypto/Cipher/_DES3.cpython-38-x86_64-linux-gnu.so delete mode 100755 frozen_deps/Crypto/Cipher/_XOR.cpython-38-x86_64-linux-gnu.so delete mode 100644 frozen_deps/Crypto/Cipher/__init__.py delete mode 100644 frozen_deps/Crypto/Cipher/blockalgo.py delete mode 100644 frozen_deps/Crypto/Hash/HMAC.py delete mode 100644 frozen_deps/Crypto/Hash/MD2.py delete mode 100644 frozen_deps/Crypto/Hash/MD4.py delete mode 100644 frozen_deps/Crypto/Hash/MD5.py delete mode 100644 frozen_deps/Crypto/Hash/RIPEMD.py delete mode 100644 frozen_deps/Crypto/Hash/SHA.py delete mode 100644 frozen_deps/Crypto/Hash/SHA224.py delete mode 100644 frozen_deps/Crypto/Hash/SHA256.py delete mode 100644 frozen_deps/Crypto/Hash/SHA384.py delete mode 100644 frozen_deps/Crypto/Hash/SHA512.py delete mode 100755 frozen_deps/Crypto/Hash/_MD2.cpython-38-x86_64-linux-gnu.so delete mode 100755 frozen_deps/Crypto/Hash/_MD4.cpython-38-x86_64-linux-gnu.so delete mode 100755 frozen_deps/Crypto/Hash/_RIPEMD160.cpython-38-x86_64-linux-gnu.so delete mode 100755 frozen_deps/Crypto/Hash/_SHA224.cpython-38-x86_64-linux-gnu.so delete mode 100755 frozen_deps/Crypto/Hash/_SHA256.cpython-38-x86_64-linux-gnu.so delete mode 100755 frozen_deps/Crypto/Hash/_SHA384.cpython-38-x86_64-linux-gnu.so delete mode 100755 frozen_deps/Crypto/Hash/_SHA512.cpython-38-x86_64-linux-gnu.so delete mode 100644 frozen_deps/Crypto/Hash/__init__.py delete mode 100644 frozen_deps/Crypto/Hash/hashalgo.py delete mode 100644 frozen_deps/Crypto/Protocol/AllOrNothing.py delete mode 100644 frozen_deps/Crypto/Protocol/Chaffing.py delete mode 100644 frozen_deps/Crypto/Protocol/KDF.py delete mode 100644 frozen_deps/Crypto/Protocol/__init__.py delete mode 100644 frozen_deps/Crypto/PublicKey/DSA.py delete mode 100644 frozen_deps/Crypto/PublicKey/ElGamal.py delete mode 100644 frozen_deps/Crypto/PublicKey/RSA.py delete mode 100644 frozen_deps/Crypto/PublicKey/_DSA.py delete mode 100644 frozen_deps/Crypto/PublicKey/_RSA.py delete mode 100644 frozen_deps/Crypto/PublicKey/__init__.py delete mode 100755 frozen_deps/Crypto/PublicKey/_fastmath.cpython-38-x86_64-linux-gnu.so delete mode 100644 frozen_deps/Crypto/PublicKey/_slowmath.py delete mode 100644 frozen_deps/Crypto/PublicKey/pubkey.py delete mode 100644 frozen_deps/Crypto/Random/Fortuna/FortunaAccumulator.py delete mode 100644 frozen_deps/Crypto/Random/Fortuna/FortunaGenerator.py delete mode 100644 frozen_deps/Crypto/Random/Fortuna/SHAd256.py delete mode 100644 frozen_deps/Crypto/Random/Fortuna/__init__.py delete mode 100644 frozen_deps/Crypto/Random/OSRNG/__init__.py delete mode 100644 frozen_deps/Crypto/Random/OSRNG/fallback.py delete mode 100644 frozen_deps/Crypto/Random/OSRNG/posix.py delete mode 100644 frozen_deps/Crypto/Random/OSRNG/rng_base.py delete mode 100644 frozen_deps/Crypto/Random/_UserFriendlyRNG.py delete mode 100644 frozen_deps/Crypto/Random/__init__.py delete mode 100644 frozen_deps/Crypto/Random/random.py delete mode 100644 frozen_deps/Crypto/Signature/PKCS1_PSS.py delete mode 100644 frozen_deps/Crypto/Signature/PKCS1_v1_5.py delete mode 100644 frozen_deps/Crypto/Signature/__init__.py delete mode 100644 frozen_deps/Crypto/Util/Counter.py delete mode 100644 frozen_deps/Crypto/Util/RFC1751.py delete mode 100644 frozen_deps/Crypto/Util/__init__.py delete mode 100755 frozen_deps/Crypto/Util/_counter.cpython-38-x86_64-linux-gnu.so delete mode 100644 frozen_deps/Crypto/Util/_number_new.py delete mode 100644 frozen_deps/Crypto/Util/asn1.py delete mode 100644 frozen_deps/Crypto/Util/number.py delete mode 100644 frozen_deps/Crypto/Util/py3compat.py delete mode 100644 frozen_deps/Crypto/Util/randpool.py delete mode 100755 frozen_deps/Crypto/Util/strxor.cpython-38-x86_64-linux-gnu.so delete mode 100644 frozen_deps/Crypto/Util/winrandom.py delete mode 100644 frozen_deps/Crypto/__init__.py delete mode 100644 frozen_deps/Crypto/pct_warnings.py create mode 100644 frozen_deps/Cryptodome/Cipher/AES.py create mode 100644 frozen_deps/Cryptodome/Cipher/AES.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/ARC2.py create mode 100644 frozen_deps/Cryptodome/Cipher/ARC2.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/ARC4.py create mode 100644 frozen_deps/Cryptodome/Cipher/ARC4.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/Blowfish.py create mode 100644 frozen_deps/Cryptodome/Cipher/Blowfish.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/CAST.py create mode 100644 frozen_deps/Cryptodome/Cipher/CAST.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/ChaCha20.py create mode 100644 frozen_deps/Cryptodome/Cipher/ChaCha20.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.py create mode 100644 frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/DES.py create mode 100644 frozen_deps/Cryptodome/Cipher/DES.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/DES3.py create mode 100644 frozen_deps/Cryptodome/Cipher/DES3.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/PKCS1_OAEP.py create mode 100644 frozen_deps/Cryptodome/Cipher/PKCS1_OAEP.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.py create mode 100644 frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/Salsa20.py create mode 100644 frozen_deps/Cryptodome/Cipher/Salsa20.pyi create mode 100755 frozen_deps/Cryptodome/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so create mode 100644 frozen_deps/Cryptodome/Cipher/_EKSBlowfish.py create mode 100644 frozen_deps/Cryptodome/Cipher/_EKSBlowfish.pyi create mode 100755 frozen_deps/Cryptodome/Cipher/_Salsa20.cpython-38-x86_64-linux-gnu.so create mode 100644 frozen_deps/Cryptodome/Cipher/__init__.py create mode 100644 frozen_deps/Cryptodome/Cipher/__init__.pyi create mode 100755 frozen_deps/Cryptodome/Cipher/_chacha20.cpython-38-x86_64-linux-gnu.so create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_cbc.py create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_cbc.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_ccm.py create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_ccm.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_cfb.py create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_cfb.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_ctr.py create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_ctr.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_eax.py create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_eax.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_ecb.py create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_ecb.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_gcm.py create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_gcm.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_ocb.py create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_ocb.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_ofb.py create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_ofb.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_openpgp.py create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_openpgp.pyi create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_siv.py create mode 100644 frozen_deps/Cryptodome/Cipher/_mode_siv.pyi create mode 100755 frozen_deps/Cryptodome/Cipher/_raw_aes.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Cipher/_raw_aesni.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Cipher/_raw_arc2.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Cipher/_raw_blowfish.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Cipher/_raw_cast.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Cipher/_raw_cbc.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Cipher/_raw_cfb.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Cipher/_raw_ctr.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Cipher/_raw_des.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Cipher/_raw_des3.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Cipher/_raw_ecb.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Cipher/_raw_eksblowfish.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Cipher/_raw_ocb.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Cipher/_raw_ofb.cpython-38-x86_64-linux-gnu.so create mode 100644 frozen_deps/Cryptodome/Hash/BLAKE2b.py create mode 100644 frozen_deps/Cryptodome/Hash/BLAKE2b.pyi create mode 100644 frozen_deps/Cryptodome/Hash/BLAKE2s.py create mode 100644 frozen_deps/Cryptodome/Hash/BLAKE2s.pyi create mode 100644 frozen_deps/Cryptodome/Hash/CMAC.py create mode 100644 frozen_deps/Cryptodome/Hash/CMAC.pyi create mode 100644 frozen_deps/Cryptodome/Hash/HMAC.py create mode 100644 frozen_deps/Cryptodome/Hash/HMAC.pyi create mode 100644 frozen_deps/Cryptodome/Hash/MD2.py create mode 100644 frozen_deps/Cryptodome/Hash/MD2.pyi create mode 100644 frozen_deps/Cryptodome/Hash/MD4.py create mode 100644 frozen_deps/Cryptodome/Hash/MD4.pyi create mode 100644 frozen_deps/Cryptodome/Hash/MD5.py create mode 100644 frozen_deps/Cryptodome/Hash/MD5.pyi create mode 100644 frozen_deps/Cryptodome/Hash/Poly1305.py create mode 100644 frozen_deps/Cryptodome/Hash/Poly1305.pyi create mode 100644 frozen_deps/Cryptodome/Hash/RIPEMD.py create mode 100644 frozen_deps/Cryptodome/Hash/RIPEMD.pyi create mode 100644 frozen_deps/Cryptodome/Hash/RIPEMD160.py create mode 100644 frozen_deps/Cryptodome/Hash/RIPEMD160.pyi create mode 100644 frozen_deps/Cryptodome/Hash/SHA.py create mode 100644 frozen_deps/Cryptodome/Hash/SHA.pyi create mode 100644 frozen_deps/Cryptodome/Hash/SHA1.py create mode 100644 frozen_deps/Cryptodome/Hash/SHA1.pyi create mode 100644 frozen_deps/Cryptodome/Hash/SHA224.py create mode 100644 frozen_deps/Cryptodome/Hash/SHA224.pyi create mode 100644 frozen_deps/Cryptodome/Hash/SHA256.py create mode 100644 frozen_deps/Cryptodome/Hash/SHA256.pyi create mode 100644 frozen_deps/Cryptodome/Hash/SHA384.py create mode 100644 frozen_deps/Cryptodome/Hash/SHA384.pyi create mode 100644 frozen_deps/Cryptodome/Hash/SHA3_224.py create mode 100644 frozen_deps/Cryptodome/Hash/SHA3_224.pyi create mode 100644 frozen_deps/Cryptodome/Hash/SHA3_256.py create mode 100644 frozen_deps/Cryptodome/Hash/SHA3_256.pyi create mode 100644 frozen_deps/Cryptodome/Hash/SHA3_384.py create mode 100644 frozen_deps/Cryptodome/Hash/SHA3_384.pyi create mode 100644 frozen_deps/Cryptodome/Hash/SHA3_512.py create mode 100644 frozen_deps/Cryptodome/Hash/SHA3_512.pyi create mode 100644 frozen_deps/Cryptodome/Hash/SHA512.py create mode 100644 frozen_deps/Cryptodome/Hash/SHA512.pyi create mode 100644 frozen_deps/Cryptodome/Hash/SHAKE128.py create mode 100644 frozen_deps/Cryptodome/Hash/SHAKE128.pyi create mode 100644 frozen_deps/Cryptodome/Hash/SHAKE256.py create mode 100644 frozen_deps/Cryptodome/Hash/SHAKE256.pyi create mode 100755 frozen_deps/Cryptodome/Hash/_BLAKE2b.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Hash/_BLAKE2s.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Hash/_MD2.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Hash/_MD4.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Hash/_MD5.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Hash/_RIPEMD160.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Hash/_SHA1.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Hash/_SHA224.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Hash/_SHA256.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Hash/_SHA384.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Hash/_SHA512.cpython-38-x86_64-linux-gnu.so create mode 100644 frozen_deps/Cryptodome/Hash/__init__.py create mode 100644 frozen_deps/Cryptodome/Hash/__init__.pyi create mode 100755 frozen_deps/Cryptodome/Hash/_ghash_clmul.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Hash/_ghash_portable.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Hash/_keccak.cpython-38-x86_64-linux-gnu.so create mode 100755 frozen_deps/Cryptodome/Hash/_poly1305.cpython-38-x86_64-linux-gnu.so create mode 100644 frozen_deps/Cryptodome/Hash/keccak.py create mode 100644 frozen_deps/Cryptodome/Hash/keccak.pyi create mode 100644 frozen_deps/Cryptodome/IO/PEM.py create mode 100644 frozen_deps/Cryptodome/IO/PEM.pyi create mode 100644 frozen_deps/Cryptodome/IO/PKCS8.py create mode 100644 frozen_deps/Cryptodome/IO/PKCS8.pyi create mode 100644 frozen_deps/Cryptodome/IO/_PBES.py create mode 100644 frozen_deps/Cryptodome/IO/_PBES.pyi create mode 100644 frozen_deps/Cryptodome/IO/__init__.py create mode 100644 frozen_deps/Cryptodome/Math/Numbers.py create mode 100644 frozen_deps/Cryptodome/Math/Numbers.pyi create mode 100644 frozen_deps/Cryptodome/Math/Primality.py create mode 100644 frozen_deps/Cryptodome/Math/Primality.pyi create mode 100644 frozen_deps/Cryptodome/Math/_IntegerBase.py create mode 100644 frozen_deps/Cryptodome/Math/_IntegerBase.pyi create mode 100644 frozen_deps/Cryptodome/Math/_IntegerCustom.py create mode 100644 frozen_deps/Cryptodome/Math/_IntegerCustom.pyi create mode 100644 frozen_deps/Cryptodome/Math/_IntegerGMP.py create mode 100644 frozen_deps/Cryptodome/Math/_IntegerGMP.pyi create mode 100644 frozen_deps/Cryptodome/Math/_IntegerNative.py create mode 100644 frozen_deps/Cryptodome/Math/_IntegerNative.pyi create mode 100644 frozen_deps/Cryptodome/Math/__init__.py create mode 100755 frozen_deps/Cryptodome/Math/_modexp.cpython-38-x86_64-linux-gnu.so create mode 100644 frozen_deps/Cryptodome/Protocol/KDF.py create mode 100644 frozen_deps/Cryptodome/Protocol/KDF.pyi create mode 100644 frozen_deps/Cryptodome/Protocol/SecretSharing.py create mode 100644 frozen_deps/Cryptodome/Protocol/SecretSharing.pyi create mode 100644 frozen_deps/Cryptodome/Protocol/__init__.py create mode 100644 frozen_deps/Cryptodome/Protocol/__init__.pyi create mode 100755 frozen_deps/Cryptodome/Protocol/_scrypt.cpython-38-x86_64-linux-gnu.so create mode 100644 frozen_deps/Cryptodome/PublicKey/DSA.py create mode 100644 frozen_deps/Cryptodome/PublicKey/DSA.pyi create mode 100644 frozen_deps/Cryptodome/PublicKey/ECC.py create mode 100644 frozen_deps/Cryptodome/PublicKey/ECC.pyi create mode 100644 frozen_deps/Cryptodome/PublicKey/ElGamal.py create mode 100644 frozen_deps/Cryptodome/PublicKey/ElGamal.pyi create mode 100644 frozen_deps/Cryptodome/PublicKey/RSA.py create mode 100644 frozen_deps/Cryptodome/PublicKey/RSA.pyi create mode 100644 frozen_deps/Cryptodome/PublicKey/__init__.py create mode 100644 frozen_deps/Cryptodome/PublicKey/__init__.pyi create mode 100755 frozen_deps/Cryptodome/PublicKey/_ec_ws.cpython-38-x86_64-linux-gnu.so create mode 100644 frozen_deps/Cryptodome/PublicKey/_openssh.py create mode 100644 frozen_deps/Cryptodome/PublicKey/_openssh.pyi create mode 100644 frozen_deps/Cryptodome/Random/__init__.py create mode 100644 frozen_deps/Cryptodome/Random/__init__.pyi create mode 100644 frozen_deps/Cryptodome/Random/random.py create mode 100644 frozen_deps/Cryptodome/Random/random.pyi create mode 100644 frozen_deps/Cryptodome/Signature/DSS.py create mode 100644 frozen_deps/Cryptodome/Signature/DSS.pyi create mode 100644 frozen_deps/Cryptodome/Signature/PKCS1_PSS.py create mode 100644 frozen_deps/Cryptodome/Signature/PKCS1_PSS.pyi create mode 100644 frozen_deps/Cryptodome/Signature/PKCS1_v1_5.py create mode 100644 frozen_deps/Cryptodome/Signature/PKCS1_v1_5.pyi create mode 100644 frozen_deps/Cryptodome/Signature/__init__.py create mode 100644 frozen_deps/Cryptodome/Signature/pkcs1_15.py create mode 100644 frozen_deps/Cryptodome/Signature/pkcs1_15.pyi create mode 100644 frozen_deps/Cryptodome/Signature/pss.py create mode 100644 frozen_deps/Cryptodome/Signature/pss.pyi create mode 100644 frozen_deps/Cryptodome/Util/Counter.py create mode 100644 frozen_deps/Cryptodome/Util/Counter.pyi create mode 100644 frozen_deps/Cryptodome/Util/Padding.py create mode 100644 frozen_deps/Cryptodome/Util/Padding.pyi create mode 100644 frozen_deps/Cryptodome/Util/RFC1751.py create mode 100644 frozen_deps/Cryptodome/Util/RFC1751.pyi create mode 100644 frozen_deps/Cryptodome/Util/__init__.py create mode 100644 frozen_deps/Cryptodome/Util/_cpu_features.py create mode 100644 frozen_deps/Cryptodome/Util/_cpu_features.pyi create mode 100755 frozen_deps/Cryptodome/Util/_cpuid_c.cpython-38-x86_64-linux-gnu.so create mode 100644 frozen_deps/Cryptodome/Util/_file_system.py create mode 100644 frozen_deps/Cryptodome/Util/_file_system.pyi create mode 100644 frozen_deps/Cryptodome/Util/_raw_api.py create mode 100644 frozen_deps/Cryptodome/Util/_raw_api.pyi create mode 100755 frozen_deps/Cryptodome/Util/_strxor.cpython-38-x86_64-linux-gnu.so create mode 100644 frozen_deps/Cryptodome/Util/asn1.py create mode 100644 frozen_deps/Cryptodome/Util/asn1.pyi create mode 100644 frozen_deps/Cryptodome/Util/number.py create mode 100644 frozen_deps/Cryptodome/Util/number.pyi create mode 100644 frozen_deps/Cryptodome/Util/py3compat.py create mode 100644 frozen_deps/Cryptodome/Util/py3compat.pyi create mode 100644 frozen_deps/Cryptodome/Util/strxor.py create mode 100644 frozen_deps/Cryptodome/Util/strxor.pyi create mode 100644 frozen_deps/Cryptodome/__init__.py create mode 100644 frozen_deps/Cryptodome/__init__.pyi create mode 100644 frozen_deps/Cryptodome/py.typed delete mode 100644 frozen_deps/pycrypto-2.6.1.dist-info/INSTALLER delete mode 100644 frozen_deps/pycrypto-2.6.1.dist-info/METADATA delete mode 100644 frozen_deps/pycrypto-2.6.1.dist-info/RECORD delete mode 100644 frozen_deps/pycrypto-2.6.1.dist-info/WHEEL delete mode 100644 frozen_deps/pycrypto-2.6.1.dist-info/top_level.txt create mode 100644 frozen_deps/pycryptodomex-3.9.9.dist-info/AUTHORS.rst create mode 100644 frozen_deps/pycryptodomex-3.9.9.dist-info/INSTALLER create mode 100644 frozen_deps/pycryptodomex-3.9.9.dist-info/LICENSE.rst create mode 100644 frozen_deps/pycryptodomex-3.9.9.dist-info/METADATA create mode 100644 frozen_deps/pycryptodomex-3.9.9.dist-info/RECORD create mode 100644 frozen_deps/pycryptodomex-3.9.9.dist-info/WHEEL create mode 100644 frozen_deps/pycryptodomex-3.9.9.dist-info/top_level.txt diff --git a/README.rst b/README.rst index ecfd3d5..504d734 100644 --- a/README.rst +++ b/README.rst @@ -3,15 +3,20 @@ keytree.py - Make sure you have Python >= 3.7 - CD into the cloned repo -- Make sure dependencies are installed: ``pip3 install --user .`` -- Derive 10 keys from the given mnemonic: ``./keytree.py --end-idx 10`` -- Generate a new mnemonic and derive 10 keys from it: ``./keytree.py --end-idx 10 --gen-mnemonic`` -- You can also load the mnemonic from an existing JSON keystore file (generated - by the official AVAX Wallet): ``./keytree.py --from-avax-keystore``. + +Examples +-------- +- Derive 10 keys from a given mnemonic: ``./keytree.py --end-idx 10`` +- Generate a new mnemonic, print 10 derived addresses from it, then also save the mnemonic to an encrypted keystore file: ``./keytree.py --end-idx 10 --gen-mnemonic --save-keystore mykeystore.json`` +- Load the mnemonic from an existing keystore file: ``./keytree.py --load-keystore mykeystore.json`` - To see all private keys and the mnemonic phrase, use ``--show-private`` (only use it after you look around and ensure there is no one else looking at your - screen). -- Caveat: the above instructions use a frozen, full clone of all dependencies - (recommended). If you instead do a normal pip install and use - ``keytree.py`` (without ``./`` prefix), it will use the latest deps fetched - by pip. + screen) + +Caveat +------ +The above instructions use a frozen, full clone of all dependencies that is +shipped in this repo (more secure, recommended, only works on x86-64 Linux). +If you instead do a normal pip install (``pip3 install --user .``) and use +``keytree.py`` (without ``./`` prefix), it will use the latest deps fetched by +pip. diff --git a/frozen_deps/Crypto/Cipher/AES.py b/frozen_deps/Crypto/Cipher/AES.py deleted file mode 100644 index 14f68d8..0000000 --- a/frozen_deps/Crypto/Cipher/AES.py +++ /dev/null @@ -1,115 +0,0 @@ -# -*- 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/frozen_deps/Crypto/Cipher/ARC2.py b/frozen_deps/Crypto/Cipher/ARC2.py deleted file mode 100644 index b5234e6..0000000 --- a/frozen_deps/Crypto/Cipher/ARC2.py +++ /dev/null @@ -1,130 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Cipher/ARC2.py : ARC2.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. -# =================================================================== -"""RC2 symmetric cipher - -RC2_ (Rivest's Cipher version 2) is a symmetric block cipher designed -by Ron Rivest in 1987. The cipher started as a proprietary design, -that was reverse engineered and anonymously posted on Usenet in 1996. -For this reason, the algorithm was first called *Alleged* RC2 (ARC2), -since the company that owned RC2 (RSA Data Inc.) did not confirm whether -the details leaked into public domain were really correct. - -The company eventually published its full specification in RFC2268_. - -RC2 has a fixed data block size of 8 bytes. Length of its keys can vary from -8 to 128 bits. One particular property of RC2 is that the actual -cryptographic strength of the key (*effective key length*) can be reduced -via a parameter. - -Even though RC2 is not cryptographically broken, it has not been analyzed as -thoroughly as AES, which is also faster than RC2. - -New designs should not use RC2. - -As an example, encryption can be done as follows: - - >>> 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 = range(1,16+1) - diff --git a/frozen_deps/Crypto/Cipher/ARC4.py b/frozen_deps/Crypto/Cipher/ARC4.py deleted file mode 100644 index d83f75b..0000000 --- a/frozen_deps/Crypto/Cipher/ARC4.py +++ /dev/null @@ -1,120 +0,0 @@ -# -*- 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 = range(1,256+1) - diff --git a/frozen_deps/Crypto/Cipher/Blowfish.py b/frozen_deps/Crypto/Cipher/Blowfish.py deleted file mode 100644 index 8c81d96..0000000 --- a/frozen_deps/Crypto/Cipher/Blowfish.py +++ /dev/null @@ -1,121 +0,0 @@ -# -*- 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 = range(4,56+1) - diff --git a/frozen_deps/Crypto/Cipher/CAST.py b/frozen_deps/Crypto/Cipher/CAST.py deleted file mode 100644 index 89543b2..0000000 --- a/frozen_deps/Crypto/Cipher/CAST.py +++ /dev/null @@ -1,123 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Cipher/CAST.py : CAST -# -# =================================================================== -# 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. -# =================================================================== -"""CAST-128 symmetric cipher - -CAST-128_ (or CAST5) is a symmetric block cipher specified in RFC2144_. - -It has a fixed data block size of 8 bytes. Its key can vary in length -from 40 to 128 bits. - -CAST is deemed to be cryptographically secure, but its usage is not widespread. -Keys of sufficient length should be used to prevent brute force attacks -(128 bits are recommended). - -As an example, encryption can be done as follows: - - >>> 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 = range(5,16+1) diff --git a/frozen_deps/Crypto/Cipher/DES.py b/frozen_deps/Crypto/Cipher/DES.py deleted file mode 100644 index 2fae42f..0000000 --- a/frozen_deps/Crypto/Cipher/DES.py +++ /dev/null @@ -1,118 +0,0 @@ -# -*- 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/frozen_deps/Crypto/Cipher/DES3.py b/frozen_deps/Crypto/Cipher/DES3.py deleted file mode 100644 index 7fedac8..0000000 --- a/frozen_deps/Crypto/Cipher/DES3.py +++ /dev/null @@ -1,133 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Cipher/DES3.py : DES3 -# -# =================================================================== -# 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. -# =================================================================== -"""Triple DES symmetric cipher - -`Triple DES`__ (or TDES or TDEA or 3DES) is a symmetric block cipher standardized by NIST_. -It has a fixed data block size of 8 bytes. Its keys are 128 (*Option 1*) or 192 -bits (*Option 2*) long. -However, 1 out of 8 bits is used for redundancy and do not contribute to -security. The effective key length is respectively 112 or 168 bits. - -TDES consists of the concatenation of 3 simple `DES` ciphers. - -The plaintext is first DES encrypted with *K1*, then decrypted with *K2*, -and finally encrypted again with *K3*. The ciphertext is decrypted in the reverse manner. - -The 192 bit key is a bundle of three 64 bit independent subkeys: *K1*, *K2*, and *K3*. - -The 128 bit key is split into *K1* and *K2*, whereas *K1=K3*. - -It is important that all subkeys are different, otherwise TDES would degrade to -single `DES`. - -TDES is cryptographically secure, even though it is neither as secure nor as fast -as `AES`. - -As an example, encryption can be done as follows: - - >>> 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/frozen_deps/Crypto/Cipher/PKCS1_OAEP.py b/frozen_deps/Crypto/Cipher/PKCS1_OAEP.py deleted file mode 100644 index 2738ce3..0000000 --- a/frozen_deps/Crypto/Cipher/PKCS1_OAEP.py +++ /dev/null @@ -1,255 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Cipher/PKCS1_OAEP.py : PKCS#1 OAEP -# -# =================================================================== -# 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 encryption protocol according to PKCS#1 OAEP - -See RFC3447__ or the `original RSA Labs specification`__ . - -This scheme is more properly called ``RSAES-OAEP``. - -As an example, a sender may encrypt a message in this way: - - >>> 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. -""" - - - -__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 k>> 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(list(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/frozen_deps/Crypto/Cipher/XOR.py b/frozen_deps/Crypto/Cipher/XOR.py deleted file mode 100644 index 46b8464..0000000 --- a/frozen_deps/Crypto/Cipher/XOR.py +++ /dev/null @@ -1,86 +0,0 @@ -# -*- 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 = range(1,32+1) - diff --git a/frozen_deps/Crypto/Cipher/_AES.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Cipher/_AES.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index e9ffeb9..0000000 Binary files a/frozen_deps/Crypto/Cipher/_AES.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Cipher/_ARC2.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Cipher/_ARC2.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index b325488..0000000 Binary files a/frozen_deps/Crypto/Cipher/_ARC2.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index 982a28d..0000000 Binary files a/frozen_deps/Crypto/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Cipher/_Blowfish.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Cipher/_Blowfish.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index 2648636..0000000 Binary files a/frozen_deps/Crypto/Cipher/_Blowfish.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Cipher/_CAST.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Cipher/_CAST.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index 439731a..0000000 Binary files a/frozen_deps/Crypto/Cipher/_CAST.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Cipher/_DES.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Cipher/_DES.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index e025c0d..0000000 Binary files a/frozen_deps/Crypto/Cipher/_DES.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Cipher/_DES3.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Cipher/_DES3.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index faef3f9..0000000 Binary files a/frozen_deps/Crypto/Cipher/_DES3.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Cipher/_XOR.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Cipher/_XOR.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index 43f0560..0000000 Binary files a/frozen_deps/Crypto/Cipher/_XOR.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Cipher/__init__.py b/frozen_deps/Crypto/Cipher/__init__.py deleted file mode 100644 index 7afed2d..0000000 --- a/frozen_deps/Crypto/Cipher/__init__.py +++ /dev/null @@ -1,83 +0,0 @@ -# -*- 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. -# =================================================================== - -"""Symmetric- and asymmetric-key encryption algorithms. - -Encryption algorithms transform plaintext in some way that -is dependent on a key or key pair, producing ciphertext. - -Symmetric algorithms --------------------- - -Encryption can easily be reversed, if (and, hopefully, only if) -one knows the same key. -In other words, sender and receiver share the same key. - -The symmetric encryption modules here all support the interface described in PEP -272, "API for Block Encryption Algorithms". - -If you don't know which algorithm to choose, use AES because it's -standard and has undergone a fair bit of examination. - -======================== ======= ======================== -Module name Type Description -======================== ======= ======================== -`Crypto.Cipher.AES` Block Advanced Encryption Standard -`Crypto.Cipher.ARC2` Block Alleged RC2 -`Crypto.Cipher.ARC4` Stream Alleged RC4 -`Crypto.Cipher.Blowfish` Block Blowfish -`Crypto.Cipher.CAST` Block CAST -`Crypto.Cipher.DES` Block The Data Encryption Standard. - Very commonly used in the past, - but today its 56-bit keys are too small. -`Crypto.Cipher.DES3` Block Triple DES. -`Crypto.Cipher.XOR` Stream The simple XOR cipher. -======================== ======= ======================== - - -Asymmetric algorithms ---------------------- - -For asymmetric algorithms, the key to be used for decryption is totally -different and cannot be derived in a feasible way from the key used -for encryption. Put differently, sender and receiver each own one half -of a key pair. The encryption key is often called ``public`` whereas -the decryption key is called ``private``. - -========================== ======================= -Module name Description -========================== ======================= -`Crypto.Cipher.PKCS1_v1_5` PKCS#1 v1.5 encryption, based on RSA key pairs -`Crypto.Cipher.PKCS1_OAEP` PKCS#1 OAEP encryption, based on RSA key pairs -========================== ======================= - -:undocumented: __revision__, __package__, _AES, _ARC2, _ARC4, _Blowfish - _CAST, _DES, _DES3, _XOR -""" - -__all__ = ['AES', 'ARC2', 'ARC4', - 'Blowfish', 'CAST', 'DES', 'DES3', - 'XOR', - 'PKCS1_v1_5', 'PKCS1_OAEP' - ] - -__revision__ = "$Id$" - - diff --git a/frozen_deps/Crypto/Cipher/blockalgo.py b/frozen_deps/Crypto/Cipher/blockalgo.py deleted file mode 100644 index dd183dc..0000000 --- a/frozen_deps/Crypto/Cipher/blockalgo.py +++ /dev/null @@ -1,296 +0,0 @@ -# -*- 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/frozen_deps/Crypto/Hash/HMAC.py b/frozen_deps/Crypto/Hash/HMAC.py deleted file mode 100644 index 324f534..0000000 --- a/frozen_deps/Crypto/Hash/HMAC.py +++ /dev/null @@ -1,212 +0,0 @@ -# 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: - from . 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/frozen_deps/Crypto/Hash/MD2.py b/frozen_deps/Crypto/Hash/MD2.py deleted file mode 100644 index dac959e..0000000 --- a/frozen_deps/Crypto/Hash/MD2.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- 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. -# =================================================================== - -"""MD2 cryptographic hash algorithm. - -MD2 is specified in RFC1319_ and it produces the 128 bit digest of a message. - - >>> 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/frozen_deps/Crypto/Hash/MD4.py b/frozen_deps/Crypto/Hash/MD4.py deleted file mode 100644 index e28a201..0000000 --- a/frozen_deps/Crypto/Hash/MD4.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- 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. -# =================================================================== - -"""MD4 cryptographic hash algorithm. - -MD4 is specified in RFC1320_ and produces the 128 bit digest of a message. - - >>> 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/frozen_deps/Crypto/Hash/MD5.py b/frozen_deps/Crypto/Hash/MD5.py deleted file mode 100644 index 18e9e7b..0000000 --- a/frozen_deps/Crypto/Hash/MD5.py +++ /dev/null @@ -1,97 +0,0 @@ -# -*- 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/frozen_deps/Crypto/Hash/RIPEMD.py b/frozen_deps/Crypto/Hash/RIPEMD.py deleted file mode 100644 index 33099cb..0000000 --- a/frozen_deps/Crypto/Hash/RIPEMD.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- 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/frozen_deps/Crypto/Hash/SHA.py b/frozen_deps/Crypto/Hash/SHA.py deleted file mode 100644 index 0bc5917..0000000 --- a/frozen_deps/Crypto/Hash/SHA.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- 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/frozen_deps/Crypto/Hash/SHA224.py b/frozen_deps/Crypto/Hash/SHA224.py deleted file mode 100644 index 959b56d..0000000 --- a/frozen_deps/Crypto/Hash/SHA224.py +++ /dev/null @@ -1,95 +0,0 @@ -# -*- 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/frozen_deps/Crypto/Hash/SHA256.py b/frozen_deps/Crypto/Hash/SHA256.py deleted file mode 100644 index b0a99b3..0000000 --- a/frozen_deps/Crypto/Hash/SHA256.py +++ /dev/null @@ -1,95 +0,0 @@ -# -*- 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/frozen_deps/Crypto/Hash/SHA384.py b/frozen_deps/Crypto/Hash/SHA384.py deleted file mode 100644 index 3490b02..0000000 --- a/frozen_deps/Crypto/Hash/SHA384.py +++ /dev/null @@ -1,96 +0,0 @@ -# -*- 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/frozen_deps/Crypto/Hash/SHA512.py b/frozen_deps/Crypto/Hash/SHA512.py deleted file mode 100644 index d57548d..0000000 --- a/frozen_deps/Crypto/Hash/SHA512.py +++ /dev/null @@ -1,95 +0,0 @@ -# -*- 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/frozen_deps/Crypto/Hash/_MD2.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Hash/_MD2.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index 6fbfc79..0000000 Binary files a/frozen_deps/Crypto/Hash/_MD2.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Hash/_MD4.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Hash/_MD4.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index 286f3ec..0000000 Binary files a/frozen_deps/Crypto/Hash/_MD4.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Hash/_RIPEMD160.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Hash/_RIPEMD160.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index a66d804..0000000 Binary files a/frozen_deps/Crypto/Hash/_RIPEMD160.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Hash/_SHA224.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Hash/_SHA224.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index eac6cae..0000000 Binary files a/frozen_deps/Crypto/Hash/_SHA224.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Hash/_SHA256.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Hash/_SHA256.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index 0155f47..0000000 Binary files a/frozen_deps/Crypto/Hash/_SHA256.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Hash/_SHA384.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Hash/_SHA384.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index 3d1049b..0000000 Binary files a/frozen_deps/Crypto/Hash/_SHA384.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Hash/_SHA512.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Hash/_SHA512.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index e3c5c5c..0000000 Binary files a/frozen_deps/Crypto/Hash/_SHA512.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Hash/__init__.py b/frozen_deps/Crypto/Hash/__init__.py deleted file mode 100644 index 4582c66..0000000 --- a/frozen_deps/Crypto/Hash/__init__.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- 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. -# =================================================================== - -"""Hashing algorithms - -Hash functions take arbitrary binary strings as input, and produce a random-like output -of fixed size that is dependent on the input; it should be practically infeasible -to derive the original input data given only the hash function's -output. In other words, the hash function is *one-way*. - -It should also not be practically feasible to find a second piece of data -(a *second pre-image*) whose hash is the same as the original message -(*weak collision resistance*). - -Finally, it should not be feasible to find two arbitrary messages with the -same hash (*strong collision resistance*). - -The output of the hash function is called the *digest* of the input message. -In general, the security of a hash function is related to the length of the -digest. If the digest is *n* bits long, its security level is roughly comparable -to the the one offered by an *n/2* bit encryption algorithm. - -Hash functions can be used simply as a integrity check, or, in -association with a public-key algorithm, can be used to implement -digital signatures. - -The hashing modules here all support the interface described in `PEP -247`_ , "API for Cryptographic Hash Functions". - -.. _`PEP 247` : http://www.python.org/dev/peps/pep-0247/ - -:undocumented: _MD2, _MD4, _RIPEMD160, _SHA224, _SHA256, _SHA384, _SHA512 -""" - -__all__ = ['HMAC', 'MD2', 'MD4', 'MD5', 'RIPEMD', 'SHA', - 'SHA224', 'SHA256', 'SHA384', 'SHA512'] -__revision__ = "$Id$" - - diff --git a/frozen_deps/Crypto/Hash/hashalgo.py b/frozen_deps/Crypto/Hash/hashalgo.py deleted file mode 100644 index b38b3a6..0000000 --- a/frozen_deps/Crypto/Hash/hashalgo.py +++ /dev/null @@ -1,116 +0,0 @@ -# -*- 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/frozen_deps/Crypto/Protocol/AllOrNothing.py b/frozen_deps/Crypto/Protocol/AllOrNothing.py deleted file mode 100644 index dd20536..0000000 --- a/frozen_deps/Crypto/Protocol/AllOrNothing.py +++ /dev/null @@ -1,320 +0,0 @@ -# -# 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 * -from functools import reduce - -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 = list(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 as 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(list(range(len(msgblocks))), msgblocks): - # base64 adds a trailing newline - print(' %3d' % i, end=' ') - 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/frozen_deps/Crypto/Protocol/Chaffing.py b/frozen_deps/Crypto/Protocol/Chaffing.py deleted file mode 100644 index bbfcbda..0000000 --- a/frozen_deps/Crypto/Protocol/Chaffing.py +++ /dev/null @@ -1,245 +0,0 @@ -# -# 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 = list(range(self.__blocksper)) - for i, wheat in zip(list(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 = list(zip(list(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/frozen_deps/Crypto/Protocol/KDF.py b/frozen_deps/Crypto/Protocol/KDF.py deleted file mode 100644 index af4e2a6..0000000 --- a/frozen_deps/Crypto/Protocol/KDF.py +++ /dev/null @@ -1,123 +0,0 @@ -# -# KDF.py : a collection of Key Derivation Functions -# -# Part of the Python Cryptography Toolkit -# -# =================================================================== -# 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 contains a collection of standard key derivation functions. - -A key derivation function derives one or more secondary secret keys from -one primary secret (a master key or a pass phrase). - -This is typically done to insulate the secondary keys from each other, -to avoid that leakage of a secondary key compromises the security of the -master key, or to thwart attacks on pass phrases (e.g. via rainbow tables). - -:undocumented: __revision__ -""" - -__revision__ = "$Id$" - -import math -import struct - -from Crypto.Util.py3compat import * -from Crypto.Hash import SHA as SHA1, HMAC -from Crypto.Util.strxor import strxor - -def PBKDF1(password, salt, dkLen, count=1000, hashAlgo=None): - """Derive one key from a password (or passphrase). - - This function performs key derivation according an old version of - the PKCS#5 standard (v1.5). - - This algorithm is called ``PBKDF1``. Even though it is still described - in the latest version of the PKCS#5 standard (version 2, or RFC2898), - newer applications should use the more secure and versatile `PBKDF2` instead. - - :Parameters: - password : string - The secret password or pass phrase to generate the key from. - salt : byte string - An 8 byte 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. - dkLen : integer - The length of the desired key. 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. - hashAlgo : module - The hash algorithm to use, as a module or an object from the `Crypto.Hash` package. - The digest length must be no shorter than ``dkLen``. - The default algorithm is `SHA1`. - - :Return: A byte string of length `dkLen` that can be used as key. - """ - if not hashAlgo: - hashAlgo = SHA1 - password = tobytes(password) - pHash = hashAlgo.new(password+salt) - digest = pHash.digest_size - if dkLen>digest: - 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 range(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 range(count-1): - previousU = t = prf(password,previousU) - U = strxor(U,t) - key += U - i = i + 1 - return key[:dkLen] - diff --git a/frozen_deps/Crypto/Protocol/__init__.py b/frozen_deps/Crypto/Protocol/__init__.py deleted file mode 100644 index cacc685..0000000 --- a/frozen_deps/Crypto/Protocol/__init__.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- 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/frozen_deps/Crypto/PublicKey/DSA.py b/frozen_deps/Crypto/PublicKey/DSA.py deleted file mode 100644 index 648f4b2..0000000 --- a/frozen_deps/Crypto/PublicKey/DSA.py +++ /dev/null @@ -1,379 +0,0 @@ -# -*- 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 k not in d: - 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/frozen_deps/Crypto/PublicKey/ElGamal.py b/frozen_deps/Crypto/PublicKey/ElGamal.py deleted file mode 100644 index 99af71c..0000000 --- a/frozen_deps/Crypto/PublicKey/ElGamal.py +++ /dev/null @@ -1,373 +0,0 @@ -# -# 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/frozen_deps/Crypto/PublicKey/RSA.py b/frozen_deps/Crypto/PublicKey/RSA.py deleted file mode 100644 index debe39e..0000000 --- a/frozen_deps/Crypto/PublicKey/RSA.py +++ /dev/null @@ -1,719 +0,0 @@ -# -*- 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 k not in d: - 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 as 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/frozen_deps/Crypto/PublicKey/_DSA.py b/frozen_deps/Crypto/PublicKey/_DSA.py deleted file mode 100644 index 1787ced..0000000 --- a/frozen_deps/Crypto/PublicKey/_DSA.py +++ /dev/null @@ -1,115 +0,0 @@ - -# -# DSA.py : Digital Signature Algorithm -# -# 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$" - -from Crypto.PublicKey.pubkey import * -from Crypto.Util import number -from Crypto.Util.number import bytes_to_long, long_to_bytes -from Crypto.Hash import SHA -from Crypto.Util.py3compat import * - -class error (Exception): - pass - -def generateQ(randfunc): - S=randfunc(20) - hash1=SHA.new(S).digest() - hash2=SHA.new(long_to_bytes(bytes_to_long(S)+1)).digest() - q = bignum(0) - for i in range(0,20): - c=bord(hash1[i])^bord(hash2[i]) - if i==0: - c=c | 128 - if i==19: - c= c | 1 - q=q*256+c - while (not isPrime(q)): - q=q+2 - if pow(2,159) < q < pow(2,160): - return S, q - raise RuntimeError('Bad q value generated') - -def generate_py(bits, randfunc, progress_func=None): - """generate(bits:int, randfunc:callable, progress_func:callable) - - Generate a DSA key of length 'bits', using 'randfunc' to get - random data and 'progress_func', if present, to display - the progress of the key generation. - """ - - if bits<160: - raise ValueError('Key length < 160 bits') - obj=DSAobj() - # Generate string S and prime q - if progress_func: - progress_func('p,q\n') - while (1): - S, obj.q = generateQ(randfunc) - n=divmod(bits-1, 160)[0] - C, N, V = 0, 2, {} - b=(obj.q >> 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<<160)+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/frozen_deps/Crypto/PublicKey/_RSA.py b/frozen_deps/Crypto/PublicKey/_RSA.py deleted file mode 100644 index 601ab7c..0000000 --- a/frozen_deps/Crypto/PublicKey/_RSA.py +++ /dev/null @@ -1,81 +0,0 @@ -# -# RSA.py : RSA encryption/decryption -# -# 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$" - -from Crypto.PublicKey import pubkey -from Crypto.Util import number - -def generate_py(bits, randfunc, progress_func=None, e=65537): - """generate(bits:int, randfunc:callable, progress_func:callable, e:int) - - Generate an RSA key of length 'bits', public exponent 'e'(which must be - odd), using 'randfunc' to get random data and 'progress_func', - if present, to display the progress of the key generation. - """ - obj=RSAobj() - obj.e = int(e) - - # Generate the prime factors of n - if progress_func: - progress_func('p,q\n') - p = q = 1 - while number.size(p*q) < bits: - # Note that q might be one bit longer than p if somebody specifies an odd - # number of bits for the key. (Why would anyone do that? You don't get - # more security.) - p = pubkey.getStrongPrime(bits>>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/frozen_deps/Crypto/PublicKey/__init__.py b/frozen_deps/Crypto/PublicKey/__init__.py deleted file mode 100644 index 503809f..0000000 --- a/frozen_deps/Crypto/PublicKey/__init__.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- 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/frozen_deps/Crypto/PublicKey/_fastmath.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/PublicKey/_fastmath.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index f0fe708..0000000 Binary files a/frozen_deps/Crypto/PublicKey/_fastmath.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/PublicKey/_slowmath.py b/frozen_deps/Crypto/PublicKey/_slowmath.py deleted file mode 100644 index c87bdd2..0000000 --- a/frozen_deps/Crypto/PublicKey/_slowmath.py +++ /dev/null @@ -1,187 +0,0 @@ -# -*- 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, int) - assert isinstance(e, int) - assert isinstance(d, (int, type(None))) - assert isinstance(p, (int, type(None))) - assert isinstance(q, (int, type(None))) - assert isinstance(u, (int, 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 k -# -# =================================================================== -# 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 -from . import SHAd256 - -from . 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) | 1 - 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/frozen_deps/Crypto/Random/Fortuna/FortunaGenerator.py b/frozen_deps/Crypto/Random/Fortuna/FortunaGenerator.py deleted file mode 100644 index 489c81e..0000000 --- a/frozen_deps/Crypto/Random/Fortuna/FortunaGenerator.py +++ /dev/null @@ -1,132 +0,0 @@ -# -*- 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 - -from . 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 range(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 range(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/frozen_deps/Crypto/Random/Fortuna/SHAd256.py b/frozen_deps/Crypto/Random/Fortuna/SHAd256.py deleted file mode 100644 index 2e135c9..0000000 --- a/frozen_deps/Crypto/Random/Fortuna/SHAd256.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- 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/frozen_deps/Crypto/Random/Fortuna/__init__.py b/frozen_deps/Crypto/Random/Fortuna/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/frozen_deps/Crypto/Random/OSRNG/__init__.py b/frozen_deps/Crypto/Random/OSRNG/__init__.py deleted file mode 100644 index 2fbbecb..0000000 --- a/frozen_deps/Crypto/Random/OSRNG/__init__.py +++ /dev/null @@ -1,40 +0,0 @@ -# -# 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/frozen_deps/Crypto/Random/OSRNG/fallback.py b/frozen_deps/Crypto/Random/OSRNG/fallback.py deleted file mode 100644 index 6d4130d..0000000 --- a/frozen_deps/Crypto/Random/OSRNG/fallback.py +++ /dev/null @@ -1,46 +0,0 @@ -# -# 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/frozen_deps/Crypto/Random/OSRNG/posix.py b/frozen_deps/Crypto/Random/OSRNG/posix.py deleted file mode 100644 index ceea7b7..0000000 --- a/frozen_deps/Crypto/Random/OSRNG/posix.py +++ /dev/null @@ -1,86 +0,0 @@ -# -# Random/OSRNG/posix.py : OS entropy source for POSIX systems -# -# 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__ = ['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 as 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/frozen_deps/Crypto/Random/OSRNG/rng_base.py b/frozen_deps/Crypto/Random/OSRNG/rng_base.py deleted file mode 100644 index 546f2e9..0000000 --- a/frozen_deps/Crypto/Random/OSRNG/rng_base.py +++ /dev/null @@ -1,88 +0,0 @@ -# -# 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, 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/frozen_deps/Crypto/Random/_UserFriendlyRNG.py b/frozen_deps/Crypto/Random/_UserFriendlyRNG.py deleted file mode 100644 index 937c17d..0000000 --- a/frozen_deps/Crypto/Random/_UserFriendlyRNG.py +++ /dev/null @@ -1,230 +0,0 @@ -# -*- 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, 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/frozen_deps/Crypto/Random/__init__.py b/frozen_deps/Crypto/Random/__init__.py deleted file mode 100644 index 659ffee..0000000 --- a/frozen_deps/Crypto/Random/__init__.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- 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/frozen_deps/Crypto/Random/random.py b/frozen_deps/Crypto/Random/random.py deleted file mode 100644 index cd9a221..0000000 --- a/frozen_deps/Crypto/Random/random.py +++ /dev/null @@ -1,142 +0,0 @@ -# -*- 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 = (1 << 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) - or not isinstance(stop, int) - or not isinstance(step, int)): - 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) or not isinstance(b, int): - 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 range(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 range(k): - r = None - while r is None or r in selected: - 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/frozen_deps/Crypto/Signature/PKCS1_PSS.py b/frozen_deps/Crypto/Signature/PKCS1_PSS.py deleted file mode 100644 index 319851e..0000000 --- a/frozen_deps/Crypto/Signature/PKCS1_PSS.py +++ /dev/null @@ -1,355 +0,0 @@ -# -*- 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 - - -__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 range(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 range(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 range(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/frozen_deps/Crypto/Signature/PKCS1_v1_5.py b/frozen_deps/Crypto/Signature/PKCS1_v1_5.py deleted file mode 100644 index 73ac251..0000000 --- a/frozen_deps/Crypto/Signature/PKCS1_v1_5.py +++ /dev/null @@ -1,236 +0,0 @@ -# -*- 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 emLen -# -# =================================================================== -# 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 = int(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/frozen_deps/Crypto/Util/RFC1751.py b/frozen_deps/Crypto/Util/RFC1751.py deleted file mode 100644 index 1c10c4a..0000000 --- a/frozen_deps/Crypto/Util/RFC1751.py +++ /dev/null @@ -1,365 +0,0 @@ -# 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 * -from functools import reduce - -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=[bord(x) for x in s] - kl=[binary[x>>4]+binary[x&15] for x in 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/frozen_deps/Crypto/Util/__init__.py b/frozen_deps/Crypto/Util/__init__.py deleted file mode 100644 index a3bef8a..0000000 --- a/frozen_deps/Crypto/Util/__init__.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- 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/frozen_deps/Crypto/Util/_counter.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Util/_counter.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index 77cd132..0000000 Binary files a/frozen_deps/Crypto/Util/_counter.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Util/_number_new.py b/frozen_deps/Crypto/Util/_number_new.py deleted file mode 100644 index 5f29176..0000000 --- a/frozen_deps/Crypto/Util/_number_new.py +++ /dev/null @@ -1,119 +0,0 @@ -# -*- 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) or not isinstance(b, int): - 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 = (1 << 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) or not isinstance(b, int): - 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) or not isinstance(b, int): - 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): - raise TypeError("unsupported operand type: %r" % (type(num).__name__,)) - - n = int(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 == (1 << 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) or not isinstance(d, int): - 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/frozen_deps/Crypto/Util/asn1.py b/frozen_deps/Crypto/Util/asn1.py deleted file mode 100644 index 9a97d97..0000000 --- a/frozen_deps/Crypto/Util/asn1.py +++ /dev/null @@ -1,286 +0,0 @@ -# -*- 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(list(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 idx= 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 |= 2 ** (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 = int(u), int(v) - u1, v1 = 1, 0 - 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 range (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 range (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(int(N), int(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(14142135623730950489 * (2 ** (511 + 128*x)), - 10000000000000000000)[0] - upper_bound = (1 << (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 range ((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 >= 1 << 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(int(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 = int(n) - pack = struct.pack - while n > 0: - s = pack('>I', n & 0xffffffff) + 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 = 0 - 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/frozen_deps/Crypto/Util/py3compat.py b/frozen_deps/Crypto/Util/py3compat.py deleted file mode 100644 index f8367c9..0000000 --- a/frozen_deps/Crypto/Util/py3compat.py +++ /dev/null @@ -1,107 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Util/py3compat.py : Compatibility code for handling Py3k / Python 2.x -# -# Written in 2010 by Thorsten Behrens -# -# =================================================================== -# 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 handling string/bytes changes from Python 2.x to Py3k - -In Python 2.x, strings (of type ''str'') contain binary data, including encoded -Unicode text (e.g. UTF-8). The separate type ''unicode'' holds Unicode text. -Unicode literals are specified via the u'...' prefix. Indexing or slicing -either type always produces a string of the same type as the original. -Data read from a file is always of '''str'' type. - -In Python 3.x, strings (type ''str'') may only contain Unicode text. The u'...' -prefix and the ''unicode'' type are now redundant. A new type (called -''bytes'') has to be used for binary data (including any particular -''encoding'' of a string). The b'...' prefix allows one to specify a binary -literal. Indexing or slicing a string produces another string. Slicing a byte -string produces another byte string, but the indexing operation produces an -integer. Data read from a file is of '''str'' type if the file was opened in -text mode, or of ''bytes'' type otherwise. - -Since PyCrypto aims at supporting both Python 2.x and 3.x, the following helper -functions are used to keep the rest of the library as independent as possible -from the actual Python version. - -In general, the code should always deal with binary strings, and use integers -instead of 1-byte character strings. - -b(s) - Take a text string literal (with no prefix or with u'...' prefix) and - make a byte string. -bchr(c) - Take an integer and make a 1-character byte string. -bord(c) - Take the result of indexing on a byte string and make an integer. -tobytes(s) - Take a text string, a byte string, or a sequence of character taken from - a byte string and make a byte string. -""" - -__revision__ = "$Id$" - -import sys - -if sys.version_info[0] == 2: - def b(s): - return s - def bchr(s): - return chr(s) - def bstr(s): - return str(s) - def bord(s): - return ord(s) - if sys.version_info[1] == 1: - def tobytes(s): - try: - return s.encode('latin-1') - except: - return ''.join(s) - else: - def tobytes(s): - if isinstance(s, str): - return s.encode("latin-1") - else: - return ''.join(s) -else: - def b(s): - return s.encode("latin-1") # utf-8 would cause some side-effects we don't want - def bchr(s): - return bytes([s]) - def bstr(s): - if isinstance(s,str): - return bytes(s,"latin-1") - else: - return bytes(s) - def bord(s): - return s - def tobytes(s): - if isinstance(s,bytes): - return s - else: - if isinstance(s,str): - return s.encode("latin-1") - else: - return bytes(s) - -# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/frozen_deps/Crypto/Util/randpool.py b/frozen_deps/Crypto/Util/randpool.py deleted file mode 100644 index 8b5a0b7..0000000 --- a/frozen_deps/Crypto/Util/randpool.py +++ /dev/null @@ -1,82 +0,0 @@ -# -# randpool.py : Cryptographically strong random number generation -# -# Part of the Python Cryptography Toolkit -# -# Written by Andrew M. Kuchling, Mark Moraes, 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 RandomPool_DeprecationWarning -import Crypto.Random -import warnings - -class RandomPool: - """Deprecated. Use Random.new() instead. - - See http://www.pycrypto.org/randpool-broken - """ - def __init__(self, numbytes = 160, cipher=None, hash=None, file=None): - warnings.warn("This application uses RandomPool, which is BROKEN in older releases. See http://www.pycrypto.org/randpool-broken", - RandomPool_DeprecationWarning) - self.__rng = Crypto.Random.new() - self.bytes = numbytes - self.bits = self.bytes * 8 - self.entropy = self.bits - - def get_bytes(self, N): - return self.__rng.read(N) - - def _updateEntropyEstimate(self, nbits): - self.entropy += nbits - if self.entropy < 0: - self.entropy = 0 - elif self.entropy > 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/frozen_deps/Crypto/Util/strxor.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Crypto/Util/strxor.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index 8358023..0000000 Binary files a/frozen_deps/Crypto/Util/strxor.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/frozen_deps/Crypto/Util/winrandom.py b/frozen_deps/Crypto/Util/winrandom.py deleted file mode 100644 index 0242815..0000000 --- a/frozen_deps/Crypto/Util/winrandom.py +++ /dev/null @@ -1,28 +0,0 @@ -# -# 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/frozen_deps/Crypto/__init__.py b/frozen_deps/Crypto/__init__.py deleted file mode 100644 index c27402e..0000000 --- a/frozen_deps/Crypto/__init__.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- 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/frozen_deps/Crypto/pct_warnings.py b/frozen_deps/Crypto/pct_warnings.py deleted file mode 100644 index 9b4361e..0000000 --- a/frozen_deps/Crypto/pct_warnings.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: ascii -*- -# -# pct_warnings.py : PyCrypto warnings file -# -# 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. -# =================================================================== - -# -# 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/frozen_deps/Cryptodome/Cipher/AES.py b/frozen_deps/Cryptodome/Cipher/AES.py new file mode 100644 index 0000000..dd2671a --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/AES.py @@ -0,0 +1,250 @@ +# -*- 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. +# =================================================================== +""" +Module's constants for the modes of operation supported with AES: + +:var MODE_ECB: :ref:`Electronic Code Book (ECB) ` +:var MODE_CBC: :ref:`Cipher-Block Chaining (CBC) ` +:var MODE_CFB: :ref:`Cipher FeedBack (CFB) ` +:var MODE_OFB: :ref:`Output FeedBack (OFB) ` +:var MODE_CTR: :ref:`CounTer Mode (CTR) ` +:var MODE_OPENPGP: :ref:`OpenPGP Mode ` +:var MODE_CCM: :ref:`Counter with CBC-MAC (CCM) Mode ` +:var MODE_EAX: :ref:`EAX Mode ` +:var MODE_GCM: :ref:`Galois Counter Mode (GCM) ` +:var MODE_SIV: :ref:`Syntethic Initialization Vector (SIV) ` +:var MODE_OCB: :ref:`Offset Code Book (OCB) ` +""" + +import sys + +from Cryptodome.Cipher import _create_cipher +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + c_size_t, c_uint8_ptr) + +from Cryptodome.Util import _cpu_features +from Cryptodome.Random import get_random_bytes + + +_cproto = """ + int AES_start_operation(const uint8_t key[], + size_t key_len, + void **pResult); + int AES_encrypt(const void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int AES_decrypt(const void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int AES_stop_operation(void *state); + """ + + +# Load portable AES +_raw_aes_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_aes", + _cproto) + +# Try to load AES with AES NI instructions +try: + _raw_aesni_lib = None + if _cpu_features.have_aes_ni(): + _raw_aesni_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_aesni", + _cproto.replace("AES", + "AESNI")) +# _raw_aesni may not have been compiled in +except OSError: + pass + + +def _create_base_cipher(dict_parameters): + """This method instantiates and returns a handle to a low-level + base cipher. It will absorb named parameters in the process.""" + + use_aesni = dict_parameters.pop("use_aesni", True) + + try: + key = dict_parameters.pop("key") + except KeyError: + raise TypeError("Missing 'key' parameter") + + if len(key) not in key_size: + raise ValueError("Incorrect AES key length (%d bytes)" % len(key)) + + if use_aesni and _raw_aesni_lib: + start_operation = _raw_aesni_lib.AESNI_start_operation + stop_operation = _raw_aesni_lib.AESNI_stop_operation + else: + start_operation = _raw_aes_lib.AES_start_operation + stop_operation = _raw_aes_lib.AES_stop_operation + + cipher = VoidPointer() + result = start_operation(c_uint8_ptr(key), + c_size_t(len(key)), + cipher.address_of()) + if result: + raise ValueError("Error %X while instantiating the AES cipher" + % result) + return SmartPointer(cipher.get(), stop_operation) + + +def _derive_Poly1305_key_pair(key, nonce): + """Derive a tuple (r, s, nonce) for a Poly1305 MAC. + + If nonce is ``None``, a new 16-byte nonce is generated. + """ + + if len(key) != 32: + raise ValueError("Poly1305 with AES requires a 32-byte key") + + if nonce is None: + nonce = get_random_bytes(16) + elif len(nonce) != 16: + raise ValueError("Poly1305 with AES requires a 16-byte nonce") + + s = new(key[:16], MODE_ECB).encrypt(nonce) + return key[16:], s, nonce + + +def new(key, mode, *args, **kwargs): + """Create a new AES cipher. + + :param key: + The secret key to use in the symmetric cipher. + + It must be 16, 24 or 32 bytes long (respectively for *AES-128*, + *AES-192* or *AES-256*). + + For ``MODE_SIV`` only, it doubles to 32, 48, or 64 bytes. + :type key: bytes/bytearray/memoryview + + :param mode: + The chaining mode to use for encryption or decryption. + If in doubt, use ``MODE_EAX``. + :type mode: One of the supported ``MODE_*`` constants + + :Keyword Arguments: + * **iv** (*bytes*, *bytearray*, *memoryview*) -- + (Only applicable for ``MODE_CBC``, ``MODE_CFB``, ``MODE_OFB``, + and ``MODE_OPENPGP`` modes). + + The initialization vector to use for encryption or decryption. + + For ``MODE_CBC``, ``MODE_CFB``, and ``MODE_OFB`` it must be 16 bytes long. + + For ``MODE_OPENPGP`` mode only, + it must be 16 bytes long for encryption + and 18 bytes for decryption (in the latter case, it is + actually the *encrypted* IV which was prefixed to the ciphertext). + + If not provided, a random byte string is generated (you must then + read its value with the :attr:`iv` attribute). + + * **nonce** (*bytes*, *bytearray*, *memoryview*) -- + (Only applicable for ``MODE_CCM``, ``MODE_EAX``, ``MODE_GCM``, + ``MODE_SIV``, ``MODE_OCB``, and ``MODE_CTR``). + + A value that must never be reused for any other encryption done + with this key (except possibly for ``MODE_SIV``, see below). + + For ``MODE_EAX``, ``MODE_GCM`` and ``MODE_SIV`` there are no + restrictions on its length (recommended: **16** bytes). + + For ``MODE_CCM``, its length must be in the range **[7..13]**. + Bear in mind that with CCM there is a trade-off between nonce + length and maximum message size. Recommendation: **11** bytes. + + For ``MODE_OCB``, its length must be in the range **[1..15]** + (recommended: **15**). + + For ``MODE_CTR``, its length must be in the range **[0..15]** + (recommended: **8**). + + For ``MODE_SIV``, the nonce is optional, if it is not specified, + then no nonce is being used, which renders the encryption + deterministic. + + If not provided, for modes other than ``MODE_SIV```, a random + byte string of the recommended length is used (you must then + read its value with the :attr:`nonce` attribute). + + * **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 not specified, it will be assumed to be 8. + + * **mac_len** : (*integer*) -- + (Only ``MODE_EAX``, ``MODE_GCM``, ``MODE_OCB``, ``MODE_CCM``) + Length of the authentication tag, in bytes. + + It must be even and in the range **[4..16]**. + The recommended value (and the default, if not specified) is **16**. + + * **msg_len** : (*integer*) -- + (Only ``MODE_CCM``). Length of the message to (de)cipher. + If not specified, ``encrypt`` must be called with the entire message. + Similarly, ``decrypt`` can only be called once. + + * **assoc_len** : (*integer*) -- + (Only ``MODE_CCM``). Length of the associated data. + If not specified, all associated data is buffered internally, + which may represent a problem for very large messages. + + * **initial_value** : (*integer* or *bytes/bytearray/memoryview*) -- + (Only ``MODE_CTR``). + The initial value for the counter. If not present, the cipher will + start counting from 0. The value is incremented by one for each block. + The counter number is encoded in big endian mode. + + * **counter** : (*object*) -- + Instance of ``Cryptodome.Util.Counter``, which allows full customization + of the counter block. This parameter is incompatible to both ``nonce`` + and ``initial_value``. + + * **use_aesni** : (*boolean*) -- + Use Intel AES-NI hardware extensions (default: use if available). + + :Return: an AES object, of the applicable mode. + """ + + kwargs["add_aes_modes"] = True + return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs) + + +MODE_ECB = 1 +MODE_CBC = 2 +MODE_CFB = 3 +MODE_OFB = 5 +MODE_CTR = 6 +MODE_OPENPGP = 7 +MODE_CCM = 8 +MODE_EAX = 9 +MODE_SIV = 10 +MODE_GCM = 11 +MODE_OCB = 12 + +# Size of a data block (in bytes) +block_size = 16 +# Size of a key (in bytes) +key_size = (16, 24, 32) diff --git a/frozen_deps/Cryptodome/Cipher/AES.pyi b/frozen_deps/Cryptodome/Cipher/AES.pyi new file mode 100644 index 0000000..c150efb --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/AES.pyi @@ -0,0 +1,47 @@ +from typing import Union, Tuple, Optional, Dict + +from Cryptodome.Cipher._mode_ecb import EcbMode +from Cryptodome.Cipher._mode_cbc import CbcMode +from Cryptodome.Cipher._mode_cfb import CfbMode +from Cryptodome.Cipher._mode_ofb import OfbMode +from Cryptodome.Cipher._mode_ctr import CtrMode +from Cryptodome.Cipher._mode_openpgp import OpenPgpMode +from Cryptodome.Cipher._mode_ccm import CcmMode +from Cryptodome.Cipher._mode_eax import EaxMode +from Cryptodome.Cipher._mode_gcm import GcmMode +from Cryptodome.Cipher._mode_siv import SivMode +from Cryptodome.Cipher._mode_ocb import OcbMode + +AESMode = int + +MODE_ECB: AESMode +MODE_CBC: AESMode +MODE_CFB: AESMode +MODE_OFB: AESMode +MODE_CTR: AESMode +MODE_OPENPGP: AESMode +MODE_CCM: AESMode +MODE_EAX: AESMode +MODE_GCM: AESMode +MODE_SIV: AESMode +MODE_OCB: AESMode + +Buffer = Union[bytes, bytearray, memoryview] + +def new(key: Buffer, + mode: AESMode, + iv : Buffer = ..., + IV : Buffer = ..., + nonce : Buffer = ..., + segment_size : int = ..., + mac_len : int = ..., + assoc_len : int = ..., + initial_value : Union[int, Buffer] = ..., + counter : Dict = ..., + use_aesni : bool = ...) -> \ + Union[EcbMode, CbcMode, CfbMode, OfbMode, CtrMode, + OpenPgpMode, CcmMode, EaxMode, GcmMode, + SivMode, OcbMode]: ... + +block_size: int +key_size: Tuple[int, int, int] diff --git a/frozen_deps/Cryptodome/Cipher/ARC2.py b/frozen_deps/Cryptodome/Cipher/ARC2.py new file mode 100644 index 0000000..4dc1bb8 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/ARC2.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# +# Cipher/ARC2.py : ARC2.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's constants for the modes of operation supported with ARC2: + +:var MODE_ECB: :ref:`Electronic Code Book (ECB) ` +:var MODE_CBC: :ref:`Cipher-Block Chaining (CBC) ` +:var MODE_CFB: :ref:`Cipher FeedBack (CFB) ` +:var MODE_OFB: :ref:`Output FeedBack (OFB) ` +:var MODE_CTR: :ref:`CounTer Mode (CTR) ` +:var MODE_OPENPGP: :ref:`OpenPGP Mode ` +:var MODE_EAX: :ref:`EAX Mode ` +""" + +import sys + +from Cryptodome.Cipher import _create_cipher +from Cryptodome.Util.py3compat import byte_string +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + c_size_t, c_uint8_ptr) + +_raw_arc2_lib = load_pycryptodome_raw_lib( + "Cryptodome.Cipher._raw_arc2", + """ + int ARC2_start_operation(const uint8_t key[], + size_t key_len, + size_t effective_key_len, + void **pResult); + int ARC2_encrypt(const void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int ARC2_decrypt(const void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int ARC2_stop_operation(void *state); + """ + ) + + +def _create_base_cipher(dict_parameters): + """This method instantiates and returns a handle to a low-level + base cipher. It will absorb named parameters in the process.""" + + try: + key = dict_parameters.pop("key") + except KeyError: + raise TypeError("Missing 'key' parameter") + + effective_keylen = dict_parameters.pop("effective_keylen", 1024) + + if len(key) not in key_size: + raise ValueError("Incorrect ARC2 key length (%d bytes)" % len(key)) + + if not (40 <= effective_keylen <= 1024): + raise ValueError("'effective_key_len' must be at least 40 and no larger than 1024 " + "(not %d)" % effective_keylen) + + start_operation = _raw_arc2_lib.ARC2_start_operation + stop_operation = _raw_arc2_lib.ARC2_stop_operation + + cipher = VoidPointer() + result = start_operation(c_uint8_ptr(key), + c_size_t(len(key)), + c_size_t(effective_keylen), + cipher.address_of()) + if result: + raise ValueError("Error %X while instantiating the ARC2 cipher" + % result) + + return SmartPointer(cipher.get(), stop_operation) + + +def new(key, mode, *args, **kwargs): + """Create a new RC2 cipher. + + :param key: + The secret key to use in the symmetric cipher. + Its length can vary from 5 to 128 bytes; the actual search space + (and the cipher strength) can be reduced with the ``effective_keylen`` parameter. + :type key: bytes, bytearray, memoryview + + :param mode: + The chaining mode to use for encryption or decryption. + :type mode: One of the supported ``MODE_*`` constants + + :Keyword Arguments: + * **iv** (*bytes*, *bytearray*, *memoryview*) -- + (Only applicable for ``MODE_CBC``, ``MODE_CFB``, ``MODE_OFB``, + and ``MODE_OPENPGP`` modes). + + The initialization vector to use for encryption or decryption. + + For ``MODE_CBC``, ``MODE_CFB``, and ``MODE_OFB`` it must be 8 bytes long. + + For ``MODE_OPENPGP`` mode only, + it must be 8 bytes long for encryption + and 10 bytes for decryption (in the latter case, it is + actually the *encrypted* IV which was prefixed to the ciphertext). + + If not provided, a random byte string is generated (you must then + read its value with the :attr:`iv` attribute). + + * **nonce** (*bytes*, *bytearray*, *memoryview*) -- + (Only applicable for ``MODE_EAX`` and ``MODE_CTR``). + + A value that must never be reused for any other encryption done + with this key. + + For ``MODE_EAX`` there are no + restrictions on its length (recommended: **16** bytes). + + For ``MODE_CTR``, its length must be in the range **[0..7]**. + + If not provided for ``MODE_EAX``, a random byte string is generated (you + can read it back via the ``nonce`` attribute). + + * **effective_keylen** (*integer*) -- + Optional. Maximum strength in bits of the actual key used by the ARC2 algorithm. + If the supplied ``key`` parameter is longer (in bits) of the value specified + here, it will be weakened to match it. + If not specified, no limitation is applied. + + * **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 not specified, it will be assumed to be 8. + + * **mac_len** : (*integer*) -- + (Only ``MODE_EAX``) + Length of the authentication tag, in bytes. + It must be no longer than 8 (default). + + * **initial_value** : (*integer*) -- + (Only ``MODE_CTR``). The initial value for the counter within + the counter block. By default it is **0**. + + :Return: an ARC2 object, of the applicable mode. + """ + + return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs) + +MODE_ECB = 1 +MODE_CBC = 2 +MODE_CFB = 3 +MODE_OFB = 5 +MODE_CTR = 6 +MODE_OPENPGP = 7 +MODE_EAX = 9 + +# Size of a data block (in bytes) +block_size = 8 +# Size of a key (in bytes) +key_size = range(5, 128 + 1) diff --git a/frozen_deps/Cryptodome/Cipher/ARC2.pyi b/frozen_deps/Cryptodome/Cipher/ARC2.pyi new file mode 100644 index 0000000..9659c68 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/ARC2.pyi @@ -0,0 +1,35 @@ +from typing import Union, Dict, Iterable + +from Cryptodome.Cipher._mode_ecb import EcbMode +from Cryptodome.Cipher._mode_cbc import CbcMode +from Cryptodome.Cipher._mode_cfb import CfbMode +from Cryptodome.Cipher._mode_ofb import OfbMode +from Cryptodome.Cipher._mode_ctr import CtrMode +from Cryptodome.Cipher._mode_openpgp import OpenPgpMode +from Cryptodome.Cipher._mode_eax import EaxMode + +ARC2Mode = int + +MODE_ECB: ARC2Mode +MODE_CBC: ARC2Mode +MODE_CFB: ARC2Mode +MODE_OFB: ARC2Mode +MODE_CTR: ARC2Mode +MODE_OPENPGP: ARC2Mode +MODE_EAX: ARC2Mode + +Buffer = Union[bytes, bytearray, memoryview] + +def new(key: Buffer, + mode: ARC2Mode, + iv : Buffer = ..., + IV : Buffer = ..., + nonce : Buffer = ..., + segment_size : int = ..., + mac_len : int = ..., + initial_value : Union[int, Buffer] = ..., + counter : Dict = ...) -> \ + Union[EcbMode, CbcMode, CfbMode, OfbMode, CtrMode, OpenPgpMode]: ... + +block_size: int +key_size: Iterable[int] diff --git a/frozen_deps/Cryptodome/Cipher/ARC4.py b/frozen_deps/Cryptodome/Cipher/ARC4.py new file mode 100644 index 0000000..e640e77 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/ARC4.py @@ -0,0 +1,137 @@ +# -*- 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. +# =================================================================== + +from Cryptodome.Util.py3compat import b + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer, + create_string_buffer, get_raw_buffer, + SmartPointer, c_size_t, c_uint8_ptr) + + +_raw_arc4_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._ARC4", """ + int ARC4_stream_encrypt(void *rc4State, const uint8_t in[], + uint8_t out[], size_t len); + int ARC4_stream_init(uint8_t *key, size_t keylen, + void **pRc4State); + int ARC4_stream_destroy(void *rc4State); + """) + + +class ARC4Cipher: + """ARC4 cipher object. Do not create it directly. Use + :func:`Cryptodome.Cipher.ARC4.new` instead. + """ + + def __init__(self, key, *args, **kwargs): + """Initialize an ARC4 cipher object + + See also `new()` at the module level.""" + + if len(args) > 0: + ndrop = args[0] + args = args[1:] + else: + ndrop = kwargs.pop('drop', 0) + + if len(key) not in key_size: + raise ValueError("Incorrect ARC4 key length (%d bytes)" % + len(key)) + + self._state = VoidPointer() + result = _raw_arc4_lib.ARC4_stream_init(c_uint8_ptr(key), + c_size_t(len(key)), + self._state.address_of()) + if result != 0: + raise ValueError("Error %d while creating the ARC4 cipher" + % result) + self._state = SmartPointer(self._state.get(), + _raw_arc4_lib.ARC4_stream_destroy) + + if ndrop > 0: + # This is OK even if the cipher is used for decryption, + # since encrypt and decrypt are actually the same thing + # with ARC4. + self.encrypt(b'\x00' * ndrop) + + self.block_size = 1 + self.key_size = len(key) + + def encrypt(self, plaintext): + """Encrypt a piece of data. + + :param plaintext: The data to encrypt, of any size. + :type plaintext: bytes, bytearray, memoryview + :returns: the encrypted byte string, of equal length as the + plaintext. + """ + + ciphertext = create_string_buffer(len(plaintext)) + result = _raw_arc4_lib.ARC4_stream_encrypt(self._state.get(), + c_uint8_ptr(plaintext), + ciphertext, + c_size_t(len(plaintext))) + if result: + raise ValueError("Error %d while encrypting with RC4" % result) + return get_raw_buffer(ciphertext) + + def decrypt(self, ciphertext): + """Decrypt a piece of data. + + :param ciphertext: The data to decrypt, of any size. + :type ciphertext: bytes, bytearray, memoryview + :returns: the decrypted byte string, of equal length as the + ciphertext. + """ + + try: + return self.encrypt(ciphertext) + except ValueError as e: + raise ValueError(str(e).replace("enc", "dec")) + + +def new(key, *args, **kwargs): + """Create a new ARC4 cipher. + + :param key: + The secret key to use in the symmetric cipher. + Its length must be in the range ``[5..256]``. + The recommended length is 16 bytes. + :type key: bytes, bytearray, memoryview + + :Keyword Arguments: + * *drop* (``integer``) -- + The amount of bytes to discard from the initial part of the keystream. + In fact, such part has been found to be distinguishable from random + data (while it shouldn't) and also correlated to key. + + The recommended value is 3072_ bytes. The default value is 0. + + :Return: an `ARC4Cipher` object + + .. _3072: http://eprint.iacr.org/2002/067.pdf + """ + return ARC4Cipher(key, *args, **kwargs) + +# Size of a data block (in bytes) +block_size = 1 +# Size of a key (in bytes) +key_size = range(5, 256+1) diff --git a/frozen_deps/Cryptodome/Cipher/ARC4.pyi b/frozen_deps/Cryptodome/Cipher/ARC4.pyi new file mode 100644 index 0000000..2e75d6f --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/ARC4.pyi @@ -0,0 +1,16 @@ +from typing import Any, Union, Iterable + +Buffer = Union[bytes, bytearray, memoryview] + +class ARC4Cipher: + block_size: int + key_size: int + + def __init__(self, key: Buffer, *args: Any, **kwargs: Any) -> None: ... + def encrypt(self, plaintext: Buffer) -> bytes: ... + def decrypt(self, ciphertext: Buffer) -> bytes: ... + +def new(key: Buffer, drop : int = ...) -> ARC4Cipher: ... + +block_size: int +key_size: Iterable[int] diff --git a/frozen_deps/Cryptodome/Cipher/Blowfish.py b/frozen_deps/Cryptodome/Cipher/Blowfish.py new file mode 100644 index 0000000..536cbc8 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/Blowfish.py @@ -0,0 +1,159 @@ +# -*- 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. +# =================================================================== +""" +Module's constants for the modes of operation supported with Blowfish: + +:var MODE_ECB: :ref:`Electronic Code Book (ECB) ` +:var MODE_CBC: :ref:`Cipher-Block Chaining (CBC) ` +:var MODE_CFB: :ref:`Cipher FeedBack (CFB) ` +:var MODE_OFB: :ref:`Output FeedBack (OFB) ` +:var MODE_CTR: :ref:`CounTer Mode (CTR) ` +:var MODE_OPENPGP: :ref:`OpenPGP Mode ` +:var MODE_EAX: :ref:`EAX Mode ` +""" + +import sys + +from Cryptodome.Cipher import _create_cipher +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, c_size_t, + c_uint8_ptr) + +_raw_blowfish_lib = load_pycryptodome_raw_lib( + "Cryptodome.Cipher._raw_blowfish", + """ + int Blowfish_start_operation(const uint8_t key[], + size_t key_len, + void **pResult); + int Blowfish_encrypt(const void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int Blowfish_decrypt(const void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int Blowfish_stop_operation(void *state); + """ + ) + + +def _create_base_cipher(dict_parameters): + """This method instantiates and returns a smart pointer to + a low-level base cipher. It will absorb named parameters in + the process.""" + + try: + key = dict_parameters.pop("key") + except KeyError: + raise TypeError("Missing 'key' parameter") + + if len(key) not in key_size: + raise ValueError("Incorrect Blowfish key length (%d bytes)" % len(key)) + + start_operation = _raw_blowfish_lib.Blowfish_start_operation + stop_operation = _raw_blowfish_lib.Blowfish_stop_operation + + void_p = VoidPointer() + result = start_operation(c_uint8_ptr(key), + c_size_t(len(key)), + void_p.address_of()) + if result: + raise ValueError("Error %X while instantiating the Blowfish cipher" + % result) + return SmartPointer(void_p.get(), stop_operation) + + +def new(key, mode, *args, **kwargs): + """Create a new Blowfish cipher + + :param key: + The secret key to use in the symmetric cipher. + Its length can vary from 5 to 56 bytes. + :type key: bytes, bytearray, memoryview + + :param mode: + The chaining mode to use for encryption or decryption. + :type mode: One of the supported ``MODE_*`` constants + + :Keyword Arguments: + * **iv** (*bytes*, *bytearray*, *memoryview*) -- + (Only applicable for ``MODE_CBC``, ``MODE_CFB``, ``MODE_OFB``, + and ``MODE_OPENPGP`` modes). + + The initialization vector to use for encryption or decryption. + + For ``MODE_CBC``, ``MODE_CFB``, and ``MODE_OFB`` it must be 8 bytes long. + + For ``MODE_OPENPGP`` mode only, + it must be 8 bytes long for encryption + and 10 bytes for decryption (in the latter case, it is + actually the *encrypted* IV which was prefixed to the ciphertext). + + If not provided, a random byte string is generated (you must then + read its value with the :attr:`iv` attribute). + + * **nonce** (*bytes*, *bytearray*, *memoryview*) -- + (Only applicable for ``MODE_EAX`` and ``MODE_CTR``). + + A value that must never be reused for any other encryption done + with this key. + + For ``MODE_EAX`` there are no + restrictions on its length (recommended: **16** bytes). + + For ``MODE_CTR``, its length must be in the range **[0..7]**. + + If not provided for ``MODE_EAX``, a random byte string is generated (you + can read it back via the ``nonce`` attribute). + + * **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 not specified, it will be assumed to be 8. + + * **mac_len** : (*integer*) -- + (Only ``MODE_EAX``) + Length of the authentication tag, in bytes. + It must be no longer than 8 (default). + + * **initial_value** : (*integer*) -- + (Only ``MODE_CTR``). The initial value for the counter within + the counter block. By default it is **0**. + + :Return: a Blowfish object, of the applicable mode. + """ + + return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs) + +MODE_ECB = 1 +MODE_CBC = 2 +MODE_CFB = 3 +MODE_OFB = 5 +MODE_CTR = 6 +MODE_OPENPGP = 7 +MODE_EAX = 9 + +# Size of a data block (in bytes) +block_size = 8 +# Size of a key (in bytes) +key_size = range(4, 56 + 1) diff --git a/frozen_deps/Cryptodome/Cipher/Blowfish.pyi b/frozen_deps/Cryptodome/Cipher/Blowfish.pyi new file mode 100644 index 0000000..a669240 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/Blowfish.pyi @@ -0,0 +1,35 @@ +from typing import Union, Dict, Iterable + +from Cryptodome.Cipher._mode_ecb import EcbMode +from Cryptodome.Cipher._mode_cbc import CbcMode +from Cryptodome.Cipher._mode_cfb import CfbMode +from Cryptodome.Cipher._mode_ofb import OfbMode +from Cryptodome.Cipher._mode_ctr import CtrMode +from Cryptodome.Cipher._mode_openpgp import OpenPgpMode +from Cryptodome.Cipher._mode_eax import EaxMode + +BlowfishMode = int + +MODE_ECB: BlowfishMode +MODE_CBC: BlowfishMode +MODE_CFB: BlowfishMode +MODE_OFB: BlowfishMode +MODE_CTR: BlowfishMode +MODE_OPENPGP: BlowfishMode +MODE_EAX: BlowfishMode + +Buffer = Union[bytes, bytearray, memoryview] + +def new(key: Buffer, + mode: BlowfishMode, + iv : Buffer = ..., + IV : Buffer = ..., + nonce : Buffer = ..., + segment_size : int = ..., + mac_len : int = ..., + initial_value : Union[int, Buffer] = ..., + counter : Dict = ...) -> \ + Union[EcbMode, CbcMode, CfbMode, OfbMode, CtrMode, OpenPgpMode]: ... + +block_size: int +key_size: Iterable[int] diff --git a/frozen_deps/Cryptodome/Cipher/CAST.py b/frozen_deps/Cryptodome/Cipher/CAST.py new file mode 100644 index 0000000..84eb88e --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/CAST.py @@ -0,0 +1,159 @@ +# -*- coding: utf-8 -*- +# +# Cipher/CAST.py : CAST +# +# =================================================================== +# 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's constants for the modes of operation supported with CAST: + +:var MODE_ECB: :ref:`Electronic Code Book (ECB) ` +:var MODE_CBC: :ref:`Cipher-Block Chaining (CBC) ` +:var MODE_CFB: :ref:`Cipher FeedBack (CFB) ` +:var MODE_OFB: :ref:`Output FeedBack (OFB) ` +:var MODE_CTR: :ref:`CounTer Mode (CTR) ` +:var MODE_OPENPGP: :ref:`OpenPGP Mode ` +:var MODE_EAX: :ref:`EAX Mode ` +""" + +import sys + +from Cryptodome.Cipher import _create_cipher +from Cryptodome.Util.py3compat import byte_string +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + c_size_t, c_uint8_ptr) + +_raw_cast_lib = load_pycryptodome_raw_lib( + "Cryptodome.Cipher._raw_cast", + """ + int CAST_start_operation(const uint8_t key[], + size_t key_len, + void **pResult); + int CAST_encrypt(const void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int CAST_decrypt(const void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int CAST_stop_operation(void *state); + """) + + +def _create_base_cipher(dict_parameters): + """This method instantiates and returns a handle to a low-level + base cipher. It will absorb named parameters in the process.""" + + try: + key = dict_parameters.pop("key") + except KeyError: + raise TypeError("Missing 'key' parameter") + + if len(key) not in key_size: + raise ValueError("Incorrect CAST key length (%d bytes)" % len(key)) + + start_operation = _raw_cast_lib.CAST_start_operation + stop_operation = _raw_cast_lib.CAST_stop_operation + + cipher = VoidPointer() + result = start_operation(c_uint8_ptr(key), + c_size_t(len(key)), + cipher.address_of()) + if result: + raise ValueError("Error %X while instantiating the CAST cipher" + % result) + + return SmartPointer(cipher.get(), stop_operation) + + +def new(key, mode, *args, **kwargs): + """Create a new CAST cipher + + :param key: + The secret key to use in the symmetric cipher. + Its length can vary from 5 to 16 bytes. + :type key: bytes, bytearray, memoryview + + :param mode: + The chaining mode to use for encryption or decryption. + :type mode: One of the supported ``MODE_*`` constants + + :Keyword Arguments: + * **iv** (*bytes*, *bytearray*, *memoryview*) -- + (Only applicable for ``MODE_CBC``, ``MODE_CFB``, ``MODE_OFB``, + and ``MODE_OPENPGP`` modes). + + The initialization vector to use for encryption or decryption. + + For ``MODE_CBC``, ``MODE_CFB``, and ``MODE_OFB`` it must be 8 bytes long. + + For ``MODE_OPENPGP`` mode only, + it must be 8 bytes long for encryption + and 10 bytes for decryption (in the latter case, it is + actually the *encrypted* IV which was prefixed to the ciphertext). + + If not provided, a random byte string is generated (you must then + read its value with the :attr:`iv` attribute). + + * **nonce** (*bytes*, *bytearray*, *memoryview*) -- + (Only applicable for ``MODE_EAX`` and ``MODE_CTR``). + + A value that must never be reused for any other encryption done + with this key. + + For ``MODE_EAX`` there are no + restrictions on its length (recommended: **16** bytes). + + For ``MODE_CTR``, its length must be in the range **[0..7]**. + + If not provided for ``MODE_EAX``, a random byte string is generated (you + can read it back via the ``nonce`` attribute). + + * **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 not specified, it will be assumed to be 8. + + * **mac_len** : (*integer*) -- + (Only ``MODE_EAX``) + Length of the authentication tag, in bytes. + It must be no longer than 8 (default). + + * **initial_value** : (*integer*) -- + (Only ``MODE_CTR``). The initial value for the counter within + the counter block. By default it is **0**. + + :Return: a CAST object, of the applicable mode. + """ + + return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs) + +MODE_ECB = 1 +MODE_CBC = 2 +MODE_CFB = 3 +MODE_OFB = 5 +MODE_CTR = 6 +MODE_OPENPGP = 7 +MODE_EAX = 9 + +# Size of a data block (in bytes) +block_size = 8 +# Size of a key (in bytes) +key_size = range(5, 16 + 1) diff --git a/frozen_deps/Cryptodome/Cipher/CAST.pyi b/frozen_deps/Cryptodome/Cipher/CAST.pyi new file mode 100644 index 0000000..6b411cf --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/CAST.pyi @@ -0,0 +1,35 @@ +from typing import Union, Dict, Iterable + +from Cryptodome.Cipher._mode_ecb import EcbMode +from Cryptodome.Cipher._mode_cbc import CbcMode +from Cryptodome.Cipher._mode_cfb import CfbMode +from Cryptodome.Cipher._mode_ofb import OfbMode +from Cryptodome.Cipher._mode_ctr import CtrMode +from Cryptodome.Cipher._mode_openpgp import OpenPgpMode +from Cryptodome.Cipher._mode_eax import EaxMode + +CASTMode = int + +MODE_ECB: CASTMode +MODE_CBC: CASTMode +MODE_CFB: CASTMode +MODE_OFB: CASTMode +MODE_CTR: CASTMode +MODE_OPENPGP: CASTMode +MODE_EAX: CASTMode + +Buffer = Union[bytes, bytearray, memoryview] + +def new(key: Buffer, + mode: CASTMode, + iv : Buffer = ..., + IV : Buffer = ..., + nonce : Buffer = ..., + segment_size : int = ..., + mac_len : int = ..., + initial_value : Union[int, Buffer] = ..., + counter : Dict = ...) -> \ + Union[EcbMode, CbcMode, CfbMode, OfbMode, CtrMode, OpenPgpMode]: ... + +block_size: int +key_size : Iterable[int] diff --git a/frozen_deps/Cryptodome/Cipher/ChaCha20.py b/frozen_deps/Cryptodome/Cipher/ChaCha20.py new file mode 100644 index 0000000..0cd9102 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/ChaCha20.py @@ -0,0 +1,286 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Random import get_random_bytes + +from Cryptodome.Util.py3compat import _copy_bytes +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + create_string_buffer, + get_raw_buffer, VoidPointer, + SmartPointer, c_size_t, + c_uint8_ptr, c_ulong, + is_writeable_buffer) + +_raw_chacha20_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._chacha20", + """ + int chacha20_init(void **pState, + const uint8_t *key, + size_t keySize, + const uint8_t *nonce, + size_t nonceSize); + + int chacha20_destroy(void *state); + + int chacha20_encrypt(void *state, + const uint8_t in[], + uint8_t out[], + size_t len); + + int chacha20_seek(void *state, + unsigned long block_high, + unsigned long block_low, + unsigned offset); + int hchacha20( const uint8_t key[32], + const uint8_t nonce16[16], + uint8_t subkey[32]); + """) + + +def _HChaCha20(key, nonce): + + assert(len(key) == 32) + assert(len(nonce) == 16) + + subkey = bytearray(32) + result = _raw_chacha20_lib.hchacha20( + c_uint8_ptr(key), + c_uint8_ptr(nonce), + c_uint8_ptr(subkey)) + if result: + raise ValueError("Error %d when deriving subkey with HChaCha20" % result) + + return subkey + + +class ChaCha20Cipher(object): + """ChaCha20 (or XChaCha20) cipher object. + Do not create it directly. Use :py:func:`new` instead. + + :var nonce: The nonce with length 8, 12 or 24 bytes + :vartype nonce: bytes + """ + + block_size = 1 + + def __init__(self, key, nonce): + """Initialize a ChaCha20/XChaCha20 cipher object + + See also `new()` at the module level.""" + + # XChaCha20 requires a key derivation with HChaCha20 + # See 2.3 in https://tools.ietf.org/html/draft-arciszewski-xchacha-03 + if len(nonce) == 24: + key = _HChaCha20(key, nonce[:16]) + nonce = b'\x00' * 4 + nonce[16:] + self._name = "XChaCha20" + else: + self._name = "ChaCha20" + + self.nonce = _copy_bytes(None, None, nonce) + + self._next = ( self.encrypt, self.decrypt ) + + self._state = VoidPointer() + result = _raw_chacha20_lib.chacha20_init( + self._state.address_of(), + c_uint8_ptr(key), + c_size_t(len(key)), + self.nonce, + c_size_t(len(nonce))) + if result: + raise ValueError("Error %d instantiating a %s cipher" % (result, + self._name)) + self._state = SmartPointer(self._state.get(), + _raw_chacha20_lib.chacha20_destroy) + + def encrypt(self, plaintext, output=None): + """Encrypt a piece of data. + + Args: + plaintext(bytes/bytearray/memoryview): The data to encrypt, of any size. + Keyword Args: + output(bytes/bytearray/memoryview): The location where the ciphertext + is written to. If ``None``, the ciphertext is returned. + Returns: + If ``output`` is ``None``, the ciphertext is returned as ``bytes``. + Otherwise, ``None``. + """ + + if self.encrypt not in self._next: + raise TypeError("Cipher object can only be used for decryption") + self._next = ( self.encrypt, ) + return self._encrypt(plaintext, output) + + def _encrypt(self, plaintext, output): + """Encrypt without FSM checks""" + + if output is None: + ciphertext = create_string_buffer(len(plaintext)) + else: + ciphertext = output + + if not is_writeable_buffer(output): + raise TypeError("output must be a bytearray or a writeable memoryview") + + if len(plaintext) != len(output): + raise ValueError("output must have the same length as the input" + " (%d bytes)" % len(plaintext)) + + result = _raw_chacha20_lib.chacha20_encrypt( + self._state.get(), + c_uint8_ptr(plaintext), + c_uint8_ptr(ciphertext), + c_size_t(len(plaintext))) + if result: + raise ValueError("Error %d while encrypting with %s" % (result, self._name)) + + if output is None: + return get_raw_buffer(ciphertext) + else: + return None + + def decrypt(self, ciphertext, output=None): + """Decrypt a piece of data. + + Args: + ciphertext(bytes/bytearray/memoryview): The data to decrypt, of any size. + Keyword Args: + output(bytes/bytearray/memoryview): The location where the plaintext + is written to. If ``None``, the plaintext is returned. + Returns: + If ``output`` is ``None``, the plaintext is returned as ``bytes``. + Otherwise, ``None``. + """ + + if self.decrypt not in self._next: + raise TypeError("Cipher object can only be used for encryption") + self._next = ( self.decrypt, ) + + try: + return self._encrypt(ciphertext, output) + except ValueError as e: + raise ValueError(str(e).replace("enc", "dec")) + + def seek(self, position): + """Seek to a certain position in the key stream. + + Args: + position (integer): + The absolute position within the key stream, in bytes. + """ + + position, offset = divmod(position, 64) + block_low = position & 0xFFFFFFFF + block_high = position >> 32 + + result = _raw_chacha20_lib.chacha20_seek( + self._state.get(), + c_ulong(block_high), + c_ulong(block_low), + offset + ) + if result: + raise ValueError("Error %d while seeking with %s" % (result, self._name)) + + +def _derive_Poly1305_key_pair(key, nonce): + """Derive a tuple (r, s, nonce) for a Poly1305 MAC. + + If nonce is ``None``, a new 12-byte nonce is generated. + """ + + if len(key) != 32: + raise ValueError("Poly1305 with ChaCha20 requires a 32-byte key") + + if nonce is None: + padded_nonce = nonce = get_random_bytes(12) + elif len(nonce) == 8: + # See RFC7538, 2.6: [...] ChaCha20 as specified here requires a 96-bit + # nonce. So if the provided nonce is only 64-bit, then the first 32 + # bits of the nonce will be set to a constant number. + # This will usually be zero, but for protocols with multiple senders it may be + # different for each sender, but should be the same for all + # invocations of the function with the same key by a particular + # sender. + padded_nonce = b'\x00\x00\x00\x00' + nonce + elif len(nonce) == 12: + padded_nonce = nonce + else: + raise ValueError("Poly1305 with ChaCha20 requires an 8- or 12-byte nonce") + + rs = new(key=key, nonce=padded_nonce).encrypt(b'\x00' * 32) + return rs[:16], rs[16:], nonce + + +def new(**kwargs): + """Create a new ChaCha20 or XChaCha20 cipher + + Keyword Args: + key (bytes/bytearray/memoryview): The secret key to use. + It must be 32 bytes long. + nonce (bytes/bytearray/memoryview): A mandatory value that + must never be reused for any other encryption + done with this key. + + For ChaCha20, it must be 8 or 12 bytes long. + + For XChaCha20, it must be 24 bytes long. + + If not provided, 8 bytes will be randomly generated + (you can find them back in the ``nonce`` attribute). + + :Return: a :class:`Cryptodome.Cipher.ChaCha20.ChaCha20Cipher` object + """ + + try: + key = kwargs.pop("key") + except KeyError as e: + raise TypeError("Missing parameter %s" % e) + + nonce = kwargs.pop("nonce", None) + if nonce is None: + nonce = get_random_bytes(8) + + if len(key) != 32: + raise ValueError("ChaCha20/XChaCha20 key must be 32 bytes long") + + if len(nonce) not in (8, 12, 24): + raise ValueError("Nonce must be 8/12 bytes(ChaCha20) or 24 bytes (XChaCha20)") + + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + return ChaCha20Cipher(key, nonce) + +# Size of a data block (in bytes) +block_size = 1 + +# Size of a key (in bytes) +key_size = 32 diff --git a/frozen_deps/Cryptodome/Cipher/ChaCha20.pyi b/frozen_deps/Cryptodome/Cipher/ChaCha20.pyi new file mode 100644 index 0000000..3d00a1d --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/ChaCha20.pyi @@ -0,0 +1,25 @@ +from typing import Union, overload + +Buffer = Union[bytes, bytearray, memoryview] + +def _HChaCha20(key: Buffer, nonce: Buffer) -> bytearray: ... + +class ChaCha20Cipher: + block_size: int + nonce: bytes + + def __init__(self, key: Buffer, nonce: Buffer) -> None: ... + @overload + def encrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + @overload + def decrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + def seek(self, position: int) -> None: ... + +def new(key: Buffer, nonce: Buffer = ...) -> ChaCha20Cipher: ... + +block_size: int +key_size: int diff --git a/frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.py b/frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.py new file mode 100644 index 0000000..b6bc7a6 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.py @@ -0,0 +1,336 @@ +# =================================================================== +# +# Copyright (c) 2018, Helder Eijs +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from binascii import unhexlify + +from Cryptodome.Cipher import ChaCha20 +from Cryptodome.Cipher.ChaCha20 import _HChaCha20 +from Cryptodome.Hash import Poly1305, BLAKE2s + +from Cryptodome.Random import get_random_bytes + +from Cryptodome.Util.number import long_to_bytes +from Cryptodome.Util.py3compat import _copy_bytes, bord +from Cryptodome.Util._raw_api import is_buffer + + +def _enum(**enums): + return type('Enum', (), enums) + + +_CipherStatus = _enum(PROCESSING_AUTH_DATA=1, + PROCESSING_CIPHERTEXT=2, + PROCESSING_DONE=3) + + +class ChaCha20Poly1305Cipher(object): + """ChaCha20-Poly1305 and XChaCha20-Poly1305 cipher object. + Do not create it directly. Use :py:func:`new` instead. + + :var nonce: The nonce with length 8, 12 or 24 bytes + :vartype nonce: byte string + """ + + def __init__(self, key, nonce): + """Initialize a ChaCha20-Poly1305 AEAD cipher object + + See also `new()` at the module level.""" + + self.nonce = _copy_bytes(None, None, nonce) + + self._next = (self.update, self.encrypt, self.decrypt, self.digest, + self.verify) + + self._authenticator = Poly1305.new(key=key, nonce=nonce, cipher=ChaCha20) + + self._cipher = ChaCha20.new(key=key, nonce=nonce) + self._cipher.seek(64) # Block counter starts at 1 + + self._len_aad = 0 + self._len_ct = 0 + self._mac_tag = None + self._status = _CipherStatus.PROCESSING_AUTH_DATA + + def update(self, data): + """Protect the associated data. + + Associated data (also known as *additional authenticated data* - AAD) + is the piece of the message that must stay in the clear, while + still allowing the receiver to verify its integrity. + An example is packet headers. + + The associated data (possibly split into multiple segments) is + fed into :meth:`update` before any call to :meth:`decrypt` or :meth:`encrypt`. + If there is no associated data, :meth:`update` is not called. + + :param bytes/bytearray/memoryview assoc_data: + A piece of associated data. There are no restrictions on its size. + """ + + if self.update not in self._next: + raise TypeError("update() method cannot be called") + + self._len_aad += len(data) + self._authenticator.update(data) + + def _pad_aad(self): + + assert(self._status == _CipherStatus.PROCESSING_AUTH_DATA) + if self._len_aad & 0x0F: + self._authenticator.update(b'\x00' * (16 - (self._len_aad & 0x0F))) + self._status = _CipherStatus.PROCESSING_CIPHERTEXT + + def encrypt(self, plaintext, output=None): + """Encrypt a piece of data. + + Args: + plaintext(bytes/bytearray/memoryview): The data to encrypt, of any size. + Keyword Args: + output(bytes/bytearray/memoryview): The location where the ciphertext + is written to. If ``None``, the ciphertext is returned. + Returns: + If ``output`` is ``None``, the ciphertext is returned as ``bytes``. + Otherwise, ``None``. + """ + + if self.encrypt not in self._next: + raise TypeError("encrypt() method cannot be called") + + if self._status == _CipherStatus.PROCESSING_AUTH_DATA: + self._pad_aad() + + self._next = (self.encrypt, self.digest) + + result = self._cipher.encrypt(plaintext, output=output) + self._len_ct += len(plaintext) + if output is None: + self._authenticator.update(result) + else: + self._authenticator.update(output) + return result + + def decrypt(self, ciphertext, output=None): + """Decrypt a piece of data. + + Args: + ciphertext(bytes/bytearray/memoryview): The data to decrypt, of any size. + Keyword Args: + output(bytes/bytearray/memoryview): The location where the plaintext + is written to. If ``None``, the plaintext is returned. + Returns: + If ``output`` is ``None``, the plaintext is returned as ``bytes``. + Otherwise, ``None``. + """ + + if self.decrypt not in self._next: + raise TypeError("decrypt() method cannot be called") + + if self._status == _CipherStatus.PROCESSING_AUTH_DATA: + self._pad_aad() + + self._next = (self.decrypt, self.verify) + + self._len_ct += len(ciphertext) + self._authenticator.update(ciphertext) + return self._cipher.decrypt(ciphertext, output=output) + + def _compute_mac(self): + """Finalize the cipher (if not done already) and return the MAC.""" + + if self._mac_tag: + assert(self._status == _CipherStatus.PROCESSING_DONE) + return self._mac_tag + + assert(self._status != _CipherStatus.PROCESSING_DONE) + + if self._status == _CipherStatus.PROCESSING_AUTH_DATA: + self._pad_aad() + + if self._len_ct & 0x0F: + self._authenticator.update(b'\x00' * (16 - (self._len_ct & 0x0F))) + + self._status = _CipherStatus.PROCESSING_DONE + + self._authenticator.update(long_to_bytes(self._len_aad, 8)[::-1]) + self._authenticator.update(long_to_bytes(self._len_ct, 8)[::-1]) + self._mac_tag = self._authenticator.digest() + return self._mac_tag + + def digest(self): + """Compute the *binary* authentication tag (MAC). + + :Return: the MAC tag, as 16 ``bytes``. + """ + + if self.digest not in self._next: + raise TypeError("digest() method cannot be called") + self._next = (self.digest,) + + return self._compute_mac() + + def hexdigest(self): + """Compute the *printable* authentication tag (MAC). + + This method is like :meth:`digest`. + + :Return: the MAC tag, as a hexadecimal string. + """ + return "".join(["%02x" % bord(x) for x in self.digest()]) + + def verify(self, received_mac_tag): + """Validate the *binary* authentication tag (MAC). + + The receiver invokes this method at the very end, to + check if the associated data (if any) and the decrypted + messages are valid. + + :param bytes/bytearray/memoryview received_mac_tag: + This is the 16-byte *binary* MAC, as received from the sender. + :Raises ValueError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + if self.verify not in self._next: + raise TypeError("verify() cannot be called" + " when encrypting a message") + self._next = (self.verify,) + + secret = get_random_bytes(16) + + self._compute_mac() + + mac1 = BLAKE2s.new(digest_bits=160, key=secret, + data=self._mac_tag) + mac2 = BLAKE2s.new(digest_bits=160, key=secret, + data=received_mac_tag) + + if mac1.digest() != mac2.digest(): + raise ValueError("MAC check failed") + + def hexverify(self, hex_mac_tag): + """Validate the *printable* authentication tag (MAC). + + This method is like :meth:`verify`. + + :param string hex_mac_tag: + This is the *printable* MAC. + :Raises ValueError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + self.verify(unhexlify(hex_mac_tag)) + + def encrypt_and_digest(self, plaintext): + """Perform :meth:`encrypt` and :meth:`digest` in one step. + + :param plaintext: The data to encrypt, of any size. + :type plaintext: bytes/bytearray/memoryview + :return: a tuple with two ``bytes`` objects: + + - the ciphertext, of equal length as the plaintext + - the 16-byte MAC tag + """ + + return self.encrypt(plaintext), self.digest() + + def decrypt_and_verify(self, ciphertext, received_mac_tag): + """Perform :meth:`decrypt` and :meth:`verify` in one step. + + :param ciphertext: The piece of data to decrypt. + :type ciphertext: bytes/bytearray/memoryview + :param bytes received_mac_tag: + This is the 16-byte *binary* MAC, as received from the sender. + :return: the decrypted data (as ``bytes``) + :raises ValueError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + plaintext = self.decrypt(ciphertext) + self.verify(received_mac_tag) + return plaintext + + +def new(**kwargs): + """Create a new ChaCha20-Poly1305 or XChaCha20-Poly1305 AEAD cipher. + + :keyword key: The secret key to use. It must be 32 bytes long. + :type key: byte string + + :keyword nonce: + A value that must never be reused for any other encryption + done with this key. + + For ChaCha20-Poly1305, it must be 8 or 12 bytes long. + + For XChaCha20-Poly1305, it must be 24 bytes long. + + If not provided, 12 ``bytes`` will be generated randomly + (you can find them back in the ``nonce`` attribute). + :type nonce: bytes, bytearray, memoryview + + :Return: a :class:`Cryptodome.Cipher.ChaCha20.ChaCha20Poly1305Cipher` object + """ + + try: + key = kwargs.pop("key") + except KeyError as e: + raise TypeError("Missing parameter %s" % e) + + self._len_ct += len(plaintext) + + if len(key) != 32: + raise ValueError("Key must be 32 bytes long") + + nonce = kwargs.pop("nonce", None) + if nonce is None: + nonce = get_random_bytes(12) + + if len(nonce) in (8, 12): + pass + elif len(nonce) == 24: + key = _HChaCha20(key, nonce[:16]) + nonce = b'\x00\x00\x00\x00' + nonce[16:] + else: + raise ValueError("Nonce must be 8, 12 or 24 bytes long") + + if not is_buffer(nonce): + raise TypeError("nonce must be bytes, bytearray or memoryview") + + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + return ChaCha20Poly1305Cipher(key, nonce) + + +# Size of a key (in bytes) +key_size = 32 diff --git a/frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.pyi b/frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.pyi new file mode 100644 index 0000000..ef0450f --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.pyi @@ -0,0 +1,28 @@ +from typing import Union, Tuple, overload + +Buffer = Union[bytes, bytearray, memoryview] + +class ChaCha20Poly1305Cipher: + nonce: bytes + + def __init__(self, key: Buffer, nonce: Buffer) -> None: ... + def update(self, data: Buffer) -> None: ... + @overload + def encrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + @overload + def decrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def verify(self, received_mac_tag: Buffer) -> None: ... + def hexverify(self, received_mac_tag: str) -> None: ... + def encrypt_and_digest(self, plaintext: Buffer) -> Tuple[bytes, bytes]: ... + def decrypt_and_verify(self, ciphertext: Buffer, received_mac_tag: Buffer) -> bytes: ... + +def new(key: Buffer, nonce: Buffer = ...) -> ChaCha20Poly1305Cipher: ... + +block_size: int +key_size: int diff --git a/frozen_deps/Cryptodome/Cipher/DES.py b/frozen_deps/Cryptodome/Cipher/DES.py new file mode 100644 index 0000000..026b491 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/DES.py @@ -0,0 +1,158 @@ +# -*- 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. +# =================================================================== +""" +Module's constants for the modes of operation supported with Single DES: + +:var MODE_ECB: :ref:`Electronic Code Book (ECB) ` +:var MODE_CBC: :ref:`Cipher-Block Chaining (CBC) ` +:var MODE_CFB: :ref:`Cipher FeedBack (CFB) ` +:var MODE_OFB: :ref:`Output FeedBack (OFB) ` +:var MODE_CTR: :ref:`CounTer Mode (CTR) ` +:var MODE_OPENPGP: :ref:`OpenPGP Mode ` +:var MODE_EAX: :ref:`EAX Mode ` +""" + +import sys + +from Cryptodome.Cipher import _create_cipher +from Cryptodome.Util.py3compat import byte_string +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + c_size_t, c_uint8_ptr) + +_raw_des_lib = load_pycryptodome_raw_lib( + "Cryptodome.Cipher._raw_des", + """ + int DES_start_operation(const uint8_t key[], + size_t key_len, + void **pResult); + int DES_encrypt(const void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int DES_decrypt(const void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int DES_stop_operation(void *state); + """) + + +def _create_base_cipher(dict_parameters): + """This method instantiates and returns a handle to a low-level + base cipher. It will absorb named parameters in the process.""" + + try: + key = dict_parameters.pop("key") + except KeyError: + raise TypeError("Missing 'key' parameter") + + if len(key) != key_size: + raise ValueError("Incorrect DES key length (%d bytes)" % len(key)) + + start_operation = _raw_des_lib.DES_start_operation + stop_operation = _raw_des_lib.DES_stop_operation + + cipher = VoidPointer() + result = start_operation(c_uint8_ptr(key), + c_size_t(len(key)), + cipher.address_of()) + if result: + raise ValueError("Error %X while instantiating the DES cipher" + % result) + return SmartPointer(cipher.get(), stop_operation) + + +def new(key, mode, *args, **kwargs): + """Create a new DES cipher. + + :param key: + The secret key to use in the symmetric cipher. + It must be 8 byte long. The parity bits will be ignored. + :type key: bytes/bytearray/memoryview + + :param mode: + The chaining mode to use for encryption or decryption. + :type mode: One of the supported ``MODE_*`` constants + + :Keyword Arguments: + * **iv** (*byte string*) -- + (Only applicable for ``MODE_CBC``, ``MODE_CFB``, ``MODE_OFB``, + and ``MODE_OPENPGP`` modes). + + The initialization vector to use for encryption or decryption. + + For ``MODE_CBC``, ``MODE_CFB``, and ``MODE_OFB`` it must be 8 bytes long. + + For ``MODE_OPENPGP`` mode only, + it must be 8 bytes long for encryption + and 10 bytes for decryption (in the latter case, it is + actually the *encrypted* IV which was prefixed to the ciphertext). + + If not provided, a random byte string is generated (you must then + read its value with the :attr:`iv` attribute). + + * **nonce** (*byte string*) -- + (Only applicable for ``MODE_EAX`` and ``MODE_CTR``). + + A value that must never be reused for any other encryption done + with this key. + + For ``MODE_EAX`` there are no + restrictions on its length (recommended: **16** bytes). + + For ``MODE_CTR``, its length must be in the range **[0..7]**. + + If not provided for ``MODE_EAX``, a random byte string is generated (you + can read it back via the ``nonce`` attribute). + + * **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 not specified, it will be assumed to be 8. + + * **mac_len** : (*integer*) -- + (Only ``MODE_EAX``) + Length of the authentication tag, in bytes. + It must be no longer than 8 (default). + + * **initial_value** : (*integer*) -- + (Only ``MODE_CTR``). The initial value for the counter within + the counter block. By default it is **0**. + + :Return: a DES object, of the applicable mode. + """ + + return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs) + +MODE_ECB = 1 +MODE_CBC = 2 +MODE_CFB = 3 +MODE_OFB = 5 +MODE_CTR = 6 +MODE_OPENPGP = 7 +MODE_EAX = 9 + +# Size of a data block (in bytes) +block_size = 8 +# Size of a key (in bytes) +key_size = 8 diff --git a/frozen_deps/Cryptodome/Cipher/DES.pyi b/frozen_deps/Cryptodome/Cipher/DES.pyi new file mode 100644 index 0000000..1ba2752 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/DES.pyi @@ -0,0 +1,35 @@ +from typing import Union, Dict, Iterable + +from Cryptodome.Cipher._mode_ecb import EcbMode +from Cryptodome.Cipher._mode_cbc import CbcMode +from Cryptodome.Cipher._mode_cfb import CfbMode +from Cryptodome.Cipher._mode_ofb import OfbMode +from Cryptodome.Cipher._mode_ctr import CtrMode +from Cryptodome.Cipher._mode_openpgp import OpenPgpMode +from Cryptodome.Cipher._mode_eax import EaxMode + +DESMode = int + +MODE_ECB: DESMode +MODE_CBC: DESMode +MODE_CFB: DESMode +MODE_OFB: DESMode +MODE_CTR: DESMode +MODE_OPENPGP: DESMode +MODE_EAX: DESMode + +Buffer = Union[bytes, bytearray, memoryview] + +def new(key: Buffer, + mode: DESMode, + iv : Buffer = ..., + IV : Buffer = ..., + nonce : Buffer = ..., + segment_size : int = ..., + mac_len : int = ..., + initial_value : Union[int, Buffer] = ..., + counter : Dict = ...) -> \ + Union[EcbMode, CbcMode, CfbMode, OfbMode, CtrMode, OpenPgpMode]: ... + +block_size: int +key_size: int diff --git a/frozen_deps/Cryptodome/Cipher/DES3.py b/frozen_deps/Cryptodome/Cipher/DES3.py new file mode 100644 index 0000000..3b2828e --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/DES3.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- +# +# Cipher/DES3.py : DES3 +# +# =================================================================== +# 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's constants for the modes of operation supported with Triple DES: + +:var MODE_ECB: :ref:`Electronic Code Book (ECB) ` +:var MODE_CBC: :ref:`Cipher-Block Chaining (CBC) ` +:var MODE_CFB: :ref:`Cipher FeedBack (CFB) ` +:var MODE_OFB: :ref:`Output FeedBack (OFB) ` +:var MODE_CTR: :ref:`CounTer Mode (CTR) ` +:var MODE_OPENPGP: :ref:`OpenPGP Mode ` +:var MODE_EAX: :ref:`EAX Mode ` +""" + +import sys + +from Cryptodome.Cipher import _create_cipher +from Cryptodome.Util.py3compat import byte_string, bchr, bord, bstr +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + c_size_t) + +_raw_des3_lib = load_pycryptodome_raw_lib( + "Cryptodome.Cipher._raw_des3", + """ + int DES3_start_operation(const uint8_t key[], + size_t key_len, + void **pResult); + int DES3_encrypt(const void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int DES3_decrypt(const void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int DES3_stop_operation(void *state); + """) + + +def adjust_key_parity(key_in): + """Set the parity bits in a TDES key. + + :param key_in: the TDES key whose bits need to be adjusted + :type key_in: byte string + + :returns: a copy of ``key_in``, with the parity bits correctly set + :rtype: byte string + + :raises ValueError: if the TDES key is not 16 or 24 bytes long + :raises ValueError: if the TDES key degenerates into Single DES + """ + + def parity_byte(key_byte): + parity = 1 + for i in range(1, 8): + parity ^= (key_byte >> i) & 1 + return (key_byte & 0xFE) | parity + + if len(key_in) not in key_size: + raise ValueError("Not a valid TDES key") + + key_out = b"".join([ bchr(parity_byte(bord(x))) for x in key_in ]) + + if key_out[:8] == key_out[8:16] or key_out[-16:-8] == key_out[-8:]: + raise ValueError("Triple DES key degenerates to single DES") + + return key_out + + +def _create_base_cipher(dict_parameters): + """This method instantiates and returns a handle to a low-level base cipher. + It will absorb named parameters in the process.""" + + try: + key_in = dict_parameters.pop("key") + except KeyError: + raise TypeError("Missing 'key' parameter") + + key = adjust_key_parity(bstr(key_in)) + + start_operation = _raw_des3_lib.DES3_start_operation + stop_operation = _raw_des3_lib.DES3_stop_operation + + cipher = VoidPointer() + result = start_operation(key, + c_size_t(len(key)), + cipher.address_of()) + if result: + raise ValueError("Error %X while instantiating the TDES cipher" + % result) + return SmartPointer(cipher.get(), stop_operation) + + +def new(key, mode, *args, **kwargs): + """Create a new Triple DES cipher. + + :param key: + The secret key to use in the symmetric cipher. + It must be 16 or 24 byte long. The parity bits will be ignored. + :type key: bytes/bytearray/memoryview + + :param mode: + The chaining mode to use for encryption or decryption. + :type mode: One of the supported ``MODE_*`` constants + + :Keyword Arguments: + * **iv** (*bytes*, *bytearray*, *memoryview*) -- + (Only applicable for ``MODE_CBC``, ``MODE_CFB``, ``MODE_OFB``, + and ``MODE_OPENPGP`` modes). + + The initialization vector to use for encryption or decryption. + + For ``MODE_CBC``, ``MODE_CFB``, and ``MODE_OFB`` it must be 8 bytes long. + + For ``MODE_OPENPGP`` mode only, + it must be 8 bytes long for encryption + and 10 bytes for decryption (in the latter case, it is + actually the *encrypted* IV which was prefixed to the ciphertext). + + If not provided, a random byte string is generated (you must then + read its value with the :attr:`iv` attribute). + + * **nonce** (*bytes*, *bytearray*, *memoryview*) -- + (Only applicable for ``MODE_EAX`` and ``MODE_CTR``). + + A value that must never be reused for any other encryption done + with this key. + + For ``MODE_EAX`` there are no + restrictions on its length (recommended: **16** bytes). + + For ``MODE_CTR``, its length must be in the range **[0..7]**. + + If not provided for ``MODE_EAX``, a random byte string is generated (you + can read it back via the ``nonce`` attribute). + + * **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 not specified, it will be assumed to be 8. + + * **mac_len** : (*integer*) -- + (Only ``MODE_EAX``) + Length of the authentication tag, in bytes. + It must be no longer than 8 (default). + + * **initial_value** : (*integer*) -- + (Only ``MODE_CTR``). The initial value for the counter within + the counter block. By default it is **0**. + + :Return: a Triple DES object, of the applicable mode. + """ + + return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs) + +MODE_ECB = 1 +MODE_CBC = 2 +MODE_CFB = 3 +MODE_OFB = 5 +MODE_CTR = 6 +MODE_OPENPGP = 7 +MODE_EAX = 9 + +# Size of a data block (in bytes) +block_size = 8 +# Size of a key (in bytes) +key_size = (16, 24) diff --git a/frozen_deps/Cryptodome/Cipher/DES3.pyi b/frozen_deps/Cryptodome/Cipher/DES3.pyi new file mode 100644 index 0000000..c1a524f --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/DES3.pyi @@ -0,0 +1,37 @@ +from typing import Union, Dict, Tuple + +from Cryptodome.Cipher._mode_ecb import EcbMode +from Cryptodome.Cipher._mode_cbc import CbcMode +from Cryptodome.Cipher._mode_cfb import CfbMode +from Cryptodome.Cipher._mode_ofb import OfbMode +from Cryptodome.Cipher._mode_ctr import CtrMode +from Cryptodome.Cipher._mode_openpgp import OpenPgpMode +from Cryptodome.Cipher._mode_eax import EaxMode + +def adjust_key_parity(key_in: bytes) -> bytes: ... + +DES3Mode = int + +MODE_ECB: DES3Mode +MODE_CBC: DES3Mode +MODE_CFB: DES3Mode +MODE_OFB: DES3Mode +MODE_CTR: DES3Mode +MODE_OPENPGP: DES3Mode +MODE_EAX: DES3Mode + +Buffer = Union[bytes, bytearray, memoryview] + +def new(key: Buffer, + mode: DES3Mode, + iv : Buffer = ..., + IV : Buffer = ..., + nonce : Buffer = ..., + segment_size : int = ..., + mac_len : int = ..., + initial_value : Union[int, Buffer] = ..., + counter : Dict = ...) -> \ + Union[EcbMode, CbcMode, CfbMode, OfbMode, CtrMode, OpenPgpMode]: ... + +block_size: int +key_size: Tuple[int, int] diff --git a/frozen_deps/Cryptodome/Cipher/PKCS1_OAEP.py b/frozen_deps/Cryptodome/Cipher/PKCS1_OAEP.py new file mode 100644 index 0000000..3207bbe --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/PKCS1_OAEP.py @@ -0,0 +1,239 @@ +# -*- coding: utf-8 -*- +# +# Cipher/PKCS1_OAEP.py : PKCS#1 OAEP +# +# =================================================================== +# 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 Cryptodome.Signature.pss import MGF1 +import Cryptodome.Hash.SHA1 + +from Cryptodome.Util.py3compat import bord, _copy_bytes +import Cryptodome.Util.number +from Cryptodome.Util.number import ceil_div, bytes_to_long, long_to_bytes +from Cryptodome.Util.strxor import strxor +from Cryptodome import Random + +class PKCS1OAEP_Cipher: + """Cipher object for PKCS#1 v1.5 OAEP. + Do not create directly: use :func:`new` instead.""" + + def __init__(self, key, hashAlgo, mgfunc, label, randfunc): + """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 `Cryptodome.Hash` + or an existing hash object created from any of such modules. If not specified, + `Cryptodome.Hash.SHA1` 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 consistent with ``hashAlgo`` is used (a safe choice). + label : bytes/bytearray/memoryview + A label to apply to this particular encryption. If not specified, + an empty string is used. Specifying a label does not improve + security. + randfunc : callable + A function that returns random bytes. + + :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 = Cryptodome.Hash.SHA1 + + if mgfunc: + self._mgf = mgfunc + else: + self._mgf = lambda x,y: MGF1(x,y,self._hashObj) + + self._label = _copy_bytes(None, None, label) + self._randfunc = randfunc + + def can_encrypt(self): + """Legacy function to check if you can call :meth:`encrypt`. + + .. deprecated:: 3.0""" + return self._key.can_encrypt() + + def can_decrypt(self): + """Legacy function to check if you can call :meth:`decrypt`. + + .. deprecated:: 3.0""" + return self._key.can_decrypt() + + def encrypt(self, message): + """Encrypt a message with PKCS#1 OAEP. + + :param message: + 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. + For instance, if you use RSA 2048 and SHA-256, the longest message + you can encrypt is 190 byte long. + :type message: bytes/bytearray/memoryview + + :returns: The ciphertext, as large as the RSA modulus. + :rtype: bytes + + :raises ValueError: + if the message is too long. + """ + + # See 7.1.1 in RFC3447 + modBits = Cryptodome.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 = b'\x00' * ps_len + # Step 2c + db = lHash + ps + b'\x01' + _copy_bytes(None, None, message) + # Step 2d + ros = self._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 = b'\x00' + maskedSeed + maskedDB + # Step 3a (OS2IP) + em_int = bytes_to_long(em) + # Step 3b (RSAEP) + m_int = self._key._encrypt(em_int) + # Step 3c (I2OSP) + c = long_to_bytes(m_int, k) + return c + + def decrypt(self, ciphertext): + """Decrypt a message with PKCS#1 OAEP. + + :param ciphertext: The encrypted message. + :type ciphertext: bytes/bytearray/memoryview + + :returns: The original message (plaintext). + :rtype: bytes + + :raises ValueError: + if the ciphertext has the wrong length, or if decryption + fails the integrity check (in which case, the decryption + key is probably wrong). + :raises TypeError: + if the RSA key has no private half (i.e. you are trying + to decrypt using a public key). + """ + + # See 7.1.2 in RFC3447 + modBits = Cryptodome.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(ciphertext) != k or k Any: ... + +class HashLikeModule(Protocol): + digest_size : int + @staticmethod + def new(data: Optional[bytes] = ...) -> Any: ... + +HashLike = Union[HashLikeClass, HashLikeModule] + +Buffer = Union[bytes, bytearray, memoryview] + +class PKCS1OAEP_Cipher: + def __init__(self, + key: RsaKey, + hashAlgo: HashLike, + mgfunc: Callable[[bytes, int], bytes], + label: Buffer, + randfunc: Callable[[int], bytes]) -> None: ... + def can_encrypt(self) -> bool: ... + def can_decrypt(self) -> bool: ... + def encrypt(self, message: Buffer) -> bytes: ... + def decrypt(self, ciphertext: Buffer) -> bytes: ... + +def new(key: RsaKey, + hashAlgo: Optional[HashLike] = ..., + mgfunc: Optional[Callable[[bytes, int], bytes]] = ..., + label: Optional[Buffer] = ..., + randfunc: Optional[Callable[[int], bytes]] = ...) -> PKCS1OAEP_Cipher: ... diff --git a/frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.py b/frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.py new file mode 100644 index 0000000..1fd1626 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.py @@ -0,0 +1,199 @@ +# -*- coding: utf-8 -*- +# +# Cipher/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. +# =================================================================== + +__all__ = [ 'new', 'PKCS115_Cipher' ] + +from Cryptodome.Util.number import ceil_div, bytes_to_long, long_to_bytes +from Cryptodome.Util.py3compat import bord, _copy_bytes +import Cryptodome.Util.number +from Cryptodome import Random + +class PKCS115_Cipher: + """This cipher can perform PKCS#1 v1.5 RSA encryption or decryption. + Do not instantiate directly. Use :func:`Cryptodome.Cipher.PKCS1_v1_5.new` instead.""" + + def __init__(self, key, randfunc): + """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. + randfunc : callable + Function that returns random bytes. + """ + + self._key = key + self._randfunc = randfunc + + 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 it is specified in + `section 7.2.1 of RFC8017 + `_. + + :param message: + 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. + :type message: bytes/bytearray/memoryview + + :Returns: A byte string, the ciphertext in which the message is encrypted. + It is as long as the RSA modulus (in bytes). + + :Raises ValueError: + If the RSA key length is not sufficiently long to deal with the given + message. + """ + + # See 7.2.1 in RFC8017 + modBits = Cryptodome.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 + ps = [] + while len(ps) != k - mLen - 3: + new_byte = self._randfunc(1) + if bord(new_byte[0]) == 0x00: + continue + ps.append(new_byte) + ps = b"".join(ps) + assert(len(ps) == k - mLen - 3) + # Step 2b + em = b'\x00\x02' + ps + b'\x00' + _copy_bytes(None, None, message) + # Step 3a (OS2IP) + em_int = bytes_to_long(em) + # Step 3b (RSAEP) + m_int = self._key._encrypt(em_int) + # Step 3c (I2OSP) + c = long_to_bytes(m_int, k) + return c + + def decrypt(self, ciphertext, sentinel): + r"""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 RFC8017 + `_. + + :param ciphertext: + The ciphertext that contains the message to recover. + :type ciphertext: bytes/bytearray/memoryview + + :param sentinel: + The object to return whenever an error is detected. + :type sentinel: any type + + :Returns: A byte string. It is either the original message or the ``sentinel`` (in case of an error). + + :Raises ValueError: + If the ciphertext length is incorrect + :Raises TypeError: + If the RSA key has no private half (i.e. it cannot be used for + decyption). + + .. warning:: + 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\ :sup:`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 + + """ + + # See 7.2.1 in RFC3447 + modBits = Cryptodome.Util.number.size(self._key.n) + k = ceil_div(modBits,8) # Convert from bits to bytes + + # Step 1 + if len(ciphertext) != k: + raise ValueError("Ciphertext with incorrect length.") + # Step 2a (O2SIP) + ct_int = bytes_to_long(ciphertext) + # Step 2b (RSADP) + m_int = self._key._decrypt(ct_int) + # Complete step 2c (I2OSP) + em = long_to_bytes(m_int, k) + # Step 3 + sep = em.find(b'\x00', 2) + if not em.startswith(b'\x00\x02') or sep < 10: + return sentinel + # Step 4 + return em[sep + 1:] + + +def new(key, randfunc=None): + """Create a cipher for performing PKCS#1 v1.5 encryption or decryption. + + :param key: + The key to use to encrypt or decrypt the message. This is a `Cryptodome.PublicKey.RSA` object. + Decryption is only possible if *key* is a private RSA key. + :type key: RSA key object + + :param randfunc: + Function that return random bytes. + The default is :func:`Cryptodome.Random.get_random_bytes`. + :type randfunc: callable + + :returns: A cipher object `PKCS115_Cipher`. + """ + + if randfunc is None: + randfunc = Random.get_random_bytes + return PKCS115_Cipher(key, randfunc) + diff --git a/frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.pyi b/frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.pyi new file mode 100644 index 0000000..ff4e3f2 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.pyi @@ -0,0 +1,17 @@ +from typing import Callable, Union, Any, Optional + +from Cryptodome.PublicKey.RSA import RsaKey + +Buffer = Union[bytes, bytearray, memoryview] + +class PKCS115_Cipher: + def __init__(self, + key: RsaKey, + randfunc: Callable[[int], bytes]) -> None: ... + def can_encrypt(self) -> bool: ... + def can_decrypt(self) -> bool: ... + def encrypt(self, message: Buffer) -> bytes: ... + def decrypt(self, ciphertext: Buffer) -> bytes: ... + +def new(key: RsaKey, + randfunc: Optional[Callable[[int], bytes]] = ...) -> PKCS115_Cipher: ... diff --git a/frozen_deps/Cryptodome/Cipher/Salsa20.py b/frozen_deps/Cryptodome/Cipher/Salsa20.py new file mode 100644 index 0000000..79e6701 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/Salsa20.py @@ -0,0 +1,167 @@ +# -*- coding: utf-8 -*- +# +# Cipher/Salsa20.py : Salsa20 stream cipher (http://cr.yp.to/snuffle.html) +# +# Contributed by Fabrizio Tarizzo . +# +# =================================================================== +# 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 Cryptodome.Util.py3compat import _copy_bytes +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + create_string_buffer, + get_raw_buffer, VoidPointer, + SmartPointer, c_size_t, + c_uint8_ptr, is_writeable_buffer) + +from Cryptodome.Random import get_random_bytes + +_raw_salsa20_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._Salsa20", + """ + int Salsa20_stream_init(uint8_t *key, size_t keylen, + uint8_t *nonce, size_t nonce_len, + void **pSalsaState); + int Salsa20_stream_destroy(void *salsaState); + int Salsa20_stream_encrypt(void *salsaState, + const uint8_t in[], + uint8_t out[], size_t len); + """) + + +class Salsa20Cipher: + """Salsa20 cipher object. Do not create it directly. Use :py:func:`new` + instead. + + :var nonce: The nonce with length 8 + :vartype nonce: byte string + """ + + def __init__(self, key, nonce): + """Initialize a Salsa20 cipher object + + See also `new()` at the module level.""" + + if len(key) not in key_size: + raise ValueError("Incorrect key length for Salsa20 (%d bytes)" % len(key)) + + if len(nonce) != 8: + raise ValueError("Incorrect nonce length for Salsa20 (%d bytes)" % + len(nonce)) + + self.nonce = _copy_bytes(None, None, nonce) + + self._state = VoidPointer() + result = _raw_salsa20_lib.Salsa20_stream_init( + c_uint8_ptr(key), + c_size_t(len(key)), + c_uint8_ptr(nonce), + c_size_t(len(nonce)), + self._state.address_of()) + if result: + raise ValueError("Error %d instantiating a Salsa20 cipher") + self._state = SmartPointer(self._state.get(), + _raw_salsa20_lib.Salsa20_stream_destroy) + + self.block_size = 1 + self.key_size = len(key) + + def encrypt(self, plaintext, output=None): + """Encrypt a piece of data. + + Args: + plaintext(bytes/bytearray/memoryview): The data to encrypt, of any size. + Keyword Args: + output(bytes/bytearray/memoryview): The location where the ciphertext + is written to. If ``None``, the ciphertext is returned. + Returns: + If ``output`` is ``None``, the ciphertext is returned as ``bytes``. + Otherwise, ``None``. + """ + + if output is None: + ciphertext = create_string_buffer(len(plaintext)) + else: + ciphertext = output + + if not is_writeable_buffer(output): + raise TypeError("output must be a bytearray or a writeable memoryview") + + if len(plaintext) != len(output): + raise ValueError("output must have the same length as the input" + " (%d bytes)" % len(plaintext)) + + result = _raw_salsa20_lib.Salsa20_stream_encrypt( + self._state.get(), + c_uint8_ptr(plaintext), + c_uint8_ptr(ciphertext), + c_size_t(len(plaintext))) + if result: + raise ValueError("Error %d while encrypting with Salsa20" % result) + + if output is None: + return get_raw_buffer(ciphertext) + else: + return None + + def decrypt(self, ciphertext, output=None): + """Decrypt a piece of data. + + Args: + ciphertext(bytes/bytearray/memoryview): The data to decrypt, of any size. + Keyword Args: + output(bytes/bytearray/memoryview): The location where the plaintext + is written to. If ``None``, the plaintext is returned. + Returns: + If ``output`` is ``None``, the plaintext is returned as ``bytes``. + Otherwise, ``None``. + """ + + try: + return self.encrypt(ciphertext, output=output) + except ValueError as e: + raise ValueError(str(e).replace("enc", "dec")) + + +def new(key, nonce=None): + """Create a new Salsa20 cipher + + :keyword key: The secret key to use. It must be 16 or 32 bytes long. + :type key: bytes/bytearray/memoryview + + :keyword nonce: + A value that must never be reused for any other encryption + done with this key. It must be 8 bytes long. + + If not provided, a random byte string will be generated (you can read + it back via the ``nonce`` attribute of the returned object). + :type nonce: bytes/bytearray/memoryview + + :Return: a :class:`Cryptodome.Cipher.Salsa20.Salsa20Cipher` object + """ + + if nonce is None: + nonce = get_random_bytes(8) + + return Salsa20Cipher(key, nonce) + +# Size of a data block (in bytes) +block_size = 1 + +# Size of a key (in bytes) +key_size = (16, 32) + diff --git a/frozen_deps/Cryptodome/Cipher/Salsa20.pyi b/frozen_deps/Cryptodome/Cipher/Salsa20.pyi new file mode 100644 index 0000000..9178f0d --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/Salsa20.pyi @@ -0,0 +1,27 @@ +from typing import Union, Tuple, Optional, overload + + +Buffer = Union[bytes, bytearray, memoryview] + +class Salsa20Cipher: + nonce: bytes + block_size: int + key_size: int + + def __init__(self, + key: Buffer, + nonce: Buffer) -> None: ... + @overload + def encrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + @overload + def decrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + +def new(key: Buffer, nonce: Optional[Buffer] = ...) -> Salsa20Cipher: ... + +block_size: int +key_size: Tuple[int, int] + diff --git a/frozen_deps/Cryptodome/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..e4d89af Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/_EKSBlowfish.py b/frozen_deps/Cryptodome/Cipher/_EKSBlowfish.py new file mode 100644 index 0000000..c1c3249 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_EKSBlowfish.py @@ -0,0 +1,131 @@ +# =================================================================== +# +# Copyright (c) 2019, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +import sys + +from Cryptodome.Cipher import _create_cipher +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, c_size_t, + c_uint8_ptr, c_uint) + +_raw_blowfish_lib = load_pycryptodome_raw_lib( + "Cryptodome.Cipher._raw_eksblowfish", + """ + int EKSBlowfish_start_operation(const uint8_t key[], + size_t key_len, + const uint8_t salt[16], + size_t salt_len, + unsigned cost, + unsigned invert, + void **pResult); + int EKSBlowfish_encrypt(const void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int EKSBlowfish_decrypt(const void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int EKSBlowfish_stop_operation(void *state); + """ + ) + + +def _create_base_cipher(dict_parameters): + """This method instantiates and returns a smart pointer to + a low-level base cipher. It will absorb named parameters in + the process.""" + + try: + key = dict_parameters.pop("key") + salt = dict_parameters.pop("salt") + cost = dict_parameters.pop("cost") + except KeyError as e: + raise TypeError("Missing EKSBlowfish parameter: " + str(e)) + invert = dict_parameters.pop("invert", True) + + if len(key) not in key_size: + raise ValueError("Incorrect EKSBlowfish key length (%d bytes)" % len(key)) + + start_operation = _raw_blowfish_lib.EKSBlowfish_start_operation + stop_operation = _raw_blowfish_lib.EKSBlowfish_stop_operation + + void_p = VoidPointer() + result = start_operation(c_uint8_ptr(key), + c_size_t(len(key)), + c_uint8_ptr(salt), + c_size_t(len(salt)), + c_uint(cost), + c_uint(int(invert)), + void_p.address_of()) + if result: + raise ValueError("Error %X while instantiating the EKSBlowfish cipher" + % result) + return SmartPointer(void_p.get(), stop_operation) + + +def new(key, mode, salt, cost, invert): + """Create a new EKSBlowfish cipher + + Args: + + key (bytes, bytearray, memoryview): + The secret key to use in the symmetric cipher. + Its length can vary from 0 to 72 bytes. + + mode (one of the supported ``MODE_*`` constants): + The chaining mode to use for encryption or decryption. + + salt (bytes, bytearray, memoryview): + The salt that bcrypt uses to thwart rainbow table attacks + + cost (integer): + The complexity factor in bcrypt + + invert (bool): + If ``False``, in the inner loop use ``ExpandKey`` first over the salt + and then over the key, as defined in + the `original bcrypt specification `_. + If ``True``, reverse the order, as in the first implementation of + `bcrypt` in OpenBSD. + + :Return: an EKSBlowfish object + """ + + kwargs = { 'salt':salt, 'cost':cost, 'invert':invert } + return _create_cipher(sys.modules[__name__], key, mode, **kwargs) + + +MODE_ECB = 1 + +# Size of a data block (in bytes) +block_size = 8 +# Size of a key (in bytes) +key_size = range(0, 72 + 1) diff --git a/frozen_deps/Cryptodome/Cipher/_EKSBlowfish.pyi b/frozen_deps/Cryptodome/Cipher/_EKSBlowfish.pyi new file mode 100644 index 0000000..49c8448 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_EKSBlowfish.pyi @@ -0,0 +1,15 @@ +from typing import Union, Iterable + +from Cryptodome.Cipher._mode_ecb import EcbMode + +MODE_ECB: int + +Buffer = Union[bytes, bytearray, memoryview] + +def new(key: Buffer, + mode: int, + salt: Buffer, + cost: int) -> EcbMode: ... + +block_size: int +key_size: Iterable[int] diff --git a/frozen_deps/Cryptodome/Cipher/_Salsa20.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_Salsa20.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..df9884e Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_Salsa20.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/__init__.py b/frozen_deps/Cryptodome/Cipher/__init__.py new file mode 100644 index 0000000..9bf067f --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/__init__.py @@ -0,0 +1,79 @@ +# +# A block cipher is instantiated as a combination of: +# 1. A base cipher (such as AES) +# 2. A mode of operation (such as CBC) +# +# Both items are implemented as C modules. +# +# The API of #1 is (replace "AES" with the name of the actual cipher): +# - AES_start_operaion(key) --> base_cipher_state +# - AES_encrypt(base_cipher_state, in, out, length) +# - AES_decrypt(base_cipher_state, in, out, length) +# - AES_stop_operation(base_cipher_state) +# +# Where base_cipher_state is AES_State, a struct with BlockBase (set of +# pointers to encrypt/decrypt/stop) followed by cipher-specific data. +# +# The API of #2 is (replace "CBC" with the name of the actual mode): +# - CBC_start_operation(base_cipher_state) --> mode_state +# - CBC_encrypt(mode_state, in, out, length) +# - CBC_decrypt(mode_state, in, out, length) +# - CBC_stop_operation(mode_state) +# +# where mode_state is a a pointer to base_cipher_state plus mode-specific data. + +import os + +from Cryptodome.Cipher._mode_ecb import _create_ecb_cipher +from Cryptodome.Cipher._mode_cbc import _create_cbc_cipher +from Cryptodome.Cipher._mode_cfb import _create_cfb_cipher +from Cryptodome.Cipher._mode_ofb import _create_ofb_cipher +from Cryptodome.Cipher._mode_ctr import _create_ctr_cipher +from Cryptodome.Cipher._mode_openpgp import _create_openpgp_cipher +from Cryptodome.Cipher._mode_ccm import _create_ccm_cipher +from Cryptodome.Cipher._mode_eax import _create_eax_cipher +from Cryptodome.Cipher._mode_siv import _create_siv_cipher +from Cryptodome.Cipher._mode_gcm import _create_gcm_cipher +from Cryptodome.Cipher._mode_ocb import _create_ocb_cipher + +_modes = { 1:_create_ecb_cipher, + 2:_create_cbc_cipher, + 3:_create_cfb_cipher, + 5:_create_ofb_cipher, + 6:_create_ctr_cipher, + 7:_create_openpgp_cipher, + 9:_create_eax_cipher + } + +_extra_modes = { 8:_create_ccm_cipher, + 10:_create_siv_cipher, + 11:_create_gcm_cipher, + 12:_create_ocb_cipher + } + +def _create_cipher(factory, key, mode, *args, **kwargs): + + kwargs["key"] = key + + modes = dict(_modes) + if kwargs.pop("add_aes_modes", False): + modes.update(_extra_modes) + if not mode in modes: + raise ValueError("Mode not supported") + + if args: + if mode in (8, 9, 10, 11, 12): + if len(args) > 1: + raise TypeError("Too many arguments for this mode") + kwargs["nonce"] = args[0] + elif mode in (2, 3, 5, 7): + if len(args) > 1: + raise TypeError("Too many arguments for this mode") + kwargs["IV"] = args[0] + elif mode == 6: + if len(args) > 0: + raise TypeError("Too many arguments for this mode") + elif mode == 1: + raise TypeError("IV is not meaningful for the ECB mode") + + return modes[mode](factory, **kwargs) diff --git a/frozen_deps/Cryptodome/Cipher/__init__.pyi b/frozen_deps/Cryptodome/Cipher/__init__.pyi new file mode 100644 index 0000000..e69de29 diff --git a/frozen_deps/Cryptodome/Cipher/_chacha20.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_chacha20.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..ded8fd8 Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_chacha20.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/_mode_cbc.py b/frozen_deps/Cryptodome/Cipher/_mode_cbc.py new file mode 100644 index 0000000..edc29ca --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_cbc.py @@ -0,0 +1,293 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +""" +Ciphertext Block Chaining (CBC) mode. +""" + +__all__ = ['CbcMode'] + +from Cryptodome.Util.py3compat import _copy_bytes +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer, + create_string_buffer, get_raw_buffer, + SmartPointer, c_size_t, c_uint8_ptr, + is_writeable_buffer) + +from Cryptodome.Random import get_random_bytes + +raw_cbc_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_cbc", """ + int CBC_start_operation(void *cipher, + const uint8_t iv[], + size_t iv_len, + void **pResult); + int CBC_encrypt(void *cbcState, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int CBC_decrypt(void *cbcState, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int CBC_stop_operation(void *state); + """ + ) + + +class CbcMode(object): + """*Cipher-Block Chaining (CBC)*. + + Each of the ciphertext blocks depends on the current + and all previous plaintext blocks. + + An Initialization Vector (*IV*) is required. + + See `NIST SP800-38A`_ , Section 6.2 . + + .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + + :undocumented: __init__ + """ + + def __init__(self, block_cipher, iv): + """Create a new block cipher, configured in CBC mode. + + :Parameters: + block_cipher : C pointer + A smart pointer to the low-level block cipher instance. + + iv : bytes/bytearray/memoryview + The initialization vector to use for encryption or decryption. + It is as long as the cipher block. + + **The IV must be unpredictable**. Ideally it is picked randomly. + + Reusing the *IV* for encryptions performed with the same key + compromises confidentiality. + """ + + self._state = VoidPointer() + result = raw_cbc_lib.CBC_start_operation(block_cipher.get(), + c_uint8_ptr(iv), + c_size_t(len(iv)), + self._state.address_of()) + if result: + raise ValueError("Error %d while instantiating the CBC mode" + % result) + + # Ensure that object disposal of this Python object will (eventually) + # free the memory allocated by the raw library for the cipher mode + self._state = SmartPointer(self._state.get(), + raw_cbc_lib.CBC_stop_operation) + + # Memory allocated for the underlying block cipher is now owed + # by the cipher mode + block_cipher.release() + + self.block_size = len(iv) + """The block size of the underlying cipher, in bytes.""" + + self.iv = _copy_bytes(None, None, iv) + """The Initialization Vector originally used to create the object. + The value does not change.""" + + self.IV = self.iv + """Alias for `iv`""" + + self._next = [ self.encrypt, self.decrypt ] + + def encrypt(self, plaintext, output=None): + """Encrypt data with the key and the parameters set at initialization. + + A cipher object is stateful: once you have encrypted a message + you cannot encrypt (or decrypt) another message using the same + object. + + The data to encrypt can be broken up in two or + more pieces and `encrypt` can be called multiple times. + + That is, the statement: + + >>> c.encrypt(a) + c.encrypt(b) + + is 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 add any padding to the plaintext. + + :Parameters: + plaintext : bytes/bytearray/memoryview + The piece of data to encrypt. + Its lenght must be multiple of the cipher block size. + :Keywords: + output : bytearray/memoryview + The location where the ciphertext must be written to. + If ``None``, the ciphertext is returned. + :Return: + If ``output`` is ``None``, the ciphertext is returned as ``bytes``. + Otherwise, ``None``. + """ + + if self.encrypt not in self._next: + raise TypeError("encrypt() cannot be called after decrypt()") + self._next = [ self.encrypt ] + + if output is None: + ciphertext = create_string_buffer(len(plaintext)) + else: + ciphertext = output + + if not is_writeable_buffer(output): + raise TypeError("output must be a bytearray or a writeable memoryview") + + if len(plaintext) != len(output): + raise ValueError("output must have the same length as the input" + " (%d bytes)" % len(plaintext)) + + result = raw_cbc_lib.CBC_encrypt(self._state.get(), + c_uint8_ptr(plaintext), + c_uint8_ptr(ciphertext), + c_size_t(len(plaintext))) + if result: + if result == 3: + raise ValueError("Data must be padded to %d byte boundary in CBC mode" % self.block_size) + raise ValueError("Error %d while encrypting in CBC mode" % result) + + if output is None: + return get_raw_buffer(ciphertext) + else: + return None + + def decrypt(self, ciphertext, output=None): + """Decrypt data with the key and the parameters set at initialization. + + A cipher object is stateful: once you have decrypted a message + you cannot decrypt (or encrypt) another message with the same + object. + + The data to decrypt can be broken up in two or + more pieces and `decrypt` can be called multiple times. + + That is, the statement: + + >>> c.decrypt(a) + c.decrypt(b) + + is equivalent to: + + >>> c.decrypt(a+b) + + This function does not remove any padding from the plaintext. + + :Parameters: + ciphertext : bytes/bytearray/memoryview + The piece of data to decrypt. + Its length must be multiple of the cipher block size. + :Keywords: + output : bytearray/memoryview + The location where the plaintext must be written to. + If ``None``, the plaintext is returned. + :Return: + If ``output`` is ``None``, the plaintext is returned as ``bytes``. + Otherwise, ``None``. + """ + + if self.decrypt not in self._next: + raise TypeError("decrypt() cannot be called after encrypt()") + self._next = [ self.decrypt ] + + if output is None: + plaintext = create_string_buffer(len(ciphertext)) + else: + plaintext = output + + if not is_writeable_buffer(output): + raise TypeError("output must be a bytearray or a writeable memoryview") + + if len(ciphertext) != len(output): + raise ValueError("output must have the same length as the input" + " (%d bytes)" % len(plaintext)) + + result = raw_cbc_lib.CBC_decrypt(self._state.get(), + c_uint8_ptr(ciphertext), + c_uint8_ptr(plaintext), + c_size_t(len(ciphertext))) + if result: + if result == 3: + raise ValueError("Data must be padded to %d byte boundary in CBC mode" % self.block_size) + raise ValueError("Error %d while decrypting in CBC mode" % result) + + if output is None: + return get_raw_buffer(plaintext) + else: + return None + + +def _create_cbc_cipher(factory, **kwargs): + """Instantiate a cipher object that performs CBC encryption/decryption. + + :Parameters: + factory : module + The underlying block cipher, a module from ``Cryptodome.Cipher``. + + :Keywords: + iv : bytes/bytearray/memoryview + The IV to use for CBC. + + IV : bytes/bytearray/memoryview + Alias for ``iv``. + + Any other keyword will be passed to the underlying block cipher. + See the relevant documentation for details (at least ``key`` will need + to be present). + """ + + cipher_state = factory._create_base_cipher(kwargs) + iv = kwargs.pop("IV", None) + IV = kwargs.pop("iv", None) + + if (None, None) == (iv, IV): + iv = get_random_bytes(factory.block_size) + if iv is not None: + if IV is not None: + raise TypeError("You must either use 'iv' or 'IV', not both") + else: + iv = IV + + if len(iv) != factory.block_size: + raise ValueError("Incorrect IV length (it must be %d bytes long)" % + factory.block_size) + + if kwargs: + raise TypeError("Unknown parameters for CBC: %s" % str(kwargs)) + + return CbcMode(cipher_state, iv) diff --git a/frozen_deps/Cryptodome/Cipher/_mode_cbc.pyi b/frozen_deps/Cryptodome/Cipher/_mode_cbc.pyi new file mode 100644 index 0000000..526632e --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_cbc.pyi @@ -0,0 +1,25 @@ +from typing import Union, overload + +from Cryptodome.Util._raw_api import SmartPointer + +Buffer = Union[bytes, bytearray, memoryview] + +__all__ = ['CbcMode'] + +class CbcMode(object): + block_size: int + iv: Buffer + IV: Buffer + + def __init__(self, + block_cipher: SmartPointer, + iv: Buffer) -> None: ... + @overload + def encrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + @overload + def decrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ccm.py b/frozen_deps/Cryptodome/Cipher/_mode_ccm.py new file mode 100644 index 0000000..0e1c2f6 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_ccm.py @@ -0,0 +1,650 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +""" +Counter with CBC-MAC (CCM) mode. +""" + +__all__ = ['CcmMode'] + +import struct +from binascii import unhexlify + +from Cryptodome.Util.py3compat import (byte_string, bord, + _copy_bytes) +from Cryptodome.Util._raw_api import is_writeable_buffer + +from Cryptodome.Util.strxor import strxor +from Cryptodome.Util.number import long_to_bytes + +from Cryptodome.Hash import BLAKE2s +from Cryptodome.Random import get_random_bytes + + +def enum(**enums): + return type('Enum', (), enums) + +MacStatus = enum(NOT_STARTED=0, PROCESSING_AUTH_DATA=1, PROCESSING_PLAINTEXT=2) + + +class CcmMode(object): + """Counter with CBC-MAC (CCM). + + This is an Authenticated Encryption with Associated Data (`AEAD`_) mode. + It provides both confidentiality and authenticity. + + The header of the message may be left in the clear, if needed, and it will + still be subject to authentication. The decryption step tells the receiver + if the message comes from a source that really knowns the secret key. + Additionally, decryption detects if any part of the message - including the + header - has been modified or corrupted. + + This mode requires a nonce. The nonce shall never repeat for two + different messages encrypted with the same key, but it does not need + to be random. + Note that there is a trade-off between the size of the nonce and the + maximum size of a single message you can encrypt. + + It is important to use a large nonce if the key is reused across several + messages and the nonce is chosen randomly. + + It is acceptable to us a short nonce if the key is only used a few times or + if the nonce is taken from a counter. + + The following table shows the trade-off when the nonce is chosen at + random. The column on the left shows how many messages it takes + for the keystream to repeat **on average**. In practice, you will want to + stop using the key way before that. + + +--------------------+---------------+-------------------+ + | Avg. # of messages | nonce | Max. message | + | before keystream | size | size | + | repeats | (bytes) | (bytes) | + +====================+===============+===================+ + | 2^52 | 13 | 64K | + +--------------------+---------------+-------------------+ + | 2^48 | 12 | 16M | + +--------------------+---------------+-------------------+ + | 2^44 | 11 | 4G | + +--------------------+---------------+-------------------+ + | 2^40 | 10 | 1T | + +--------------------+---------------+-------------------+ + | 2^36 | 9 | 64P | + +--------------------+---------------+-------------------+ + | 2^32 | 8 | 16E | + +--------------------+---------------+-------------------+ + + This mode is only available for ciphers that operate on 128 bits blocks + (e.g. AES but not TDES). + + See `NIST SP800-38C`_ or RFC3610_. + + .. _`NIST SP800-38C`: http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C.pdf + .. _RFC3610: https://tools.ietf.org/html/rfc3610 + .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html + + :undocumented: __init__ + """ + + def __init__(self, factory, key, nonce, mac_len, msg_len, assoc_len, + cipher_params): + + self.block_size = factory.block_size + """The block size of the underlying cipher, in bytes.""" + + self.nonce = _copy_bytes(None, None, nonce) + """The nonce used for this cipher instance""" + + self._factory = factory + self._key = _copy_bytes(None, None, key) + self._mac_len = mac_len + self._msg_len = msg_len + self._assoc_len = assoc_len + self._cipher_params = cipher_params + + self._mac_tag = None # Cache for MAC tag + + if self.block_size != 16: + raise ValueError("CCM mode is only available for ciphers" + " that operate on 128 bits blocks") + + # MAC tag length (Tlen) + if mac_len not in (4, 6, 8, 10, 12, 14, 16): + raise ValueError("Parameter 'mac_len' must be even" + " and in the range 4..16 (not %d)" % mac_len) + + # Nonce value + if not (nonce and 7 <= len(nonce) <= 13): + raise ValueError("Length of parameter 'nonce' must be" + " in the range 7..13 bytes") + + # Create MAC object (the tag will be the last block + # bytes worth of ciphertext) + self._mac = self._factory.new(key, + factory.MODE_CBC, + iv=b'\x00' * 16, + **cipher_params) + self._mac_status = MacStatus.NOT_STARTED + self._t = None + + # Allowed transitions after initialization + self._next = [self.update, self.encrypt, self.decrypt, + self.digest, self.verify] + + # Cumulative lengths + self._cumul_assoc_len = 0 + self._cumul_msg_len = 0 + + # Cache for unaligned associated data/plaintext. + # This is a list with byte strings, but when the MAC starts, + # it will become a binary string no longer than the block size. + self._cache = [] + + # Start CTR cipher, by formatting the counter (A.3) + q = 15 - len(nonce) # length of Q, the encoded message length + self._cipher = self._factory.new(key, + self._factory.MODE_CTR, + nonce=struct.pack("B", q - 1) + self.nonce, + **cipher_params) + + # S_0, step 6 in 6.1 for j=0 + self._s_0 = self._cipher.encrypt(b'\x00' * 16) + + # Try to start the MAC + if None not in (assoc_len, msg_len): + self._start_mac() + + def _start_mac(self): + + assert(self._mac_status == MacStatus.NOT_STARTED) + assert(None not in (self._assoc_len, self._msg_len)) + assert(isinstance(self._cache, list)) + + # Formatting control information and nonce (A.2.1) + q = 15 - len(self.nonce) # length of Q, the encoded message length + flags = (64 * (self._assoc_len > 0) + 8 * ((self._mac_len - 2) // 2) + + (q - 1)) + b_0 = struct.pack("B", flags) + self.nonce + long_to_bytes(self._msg_len, q) + + # Formatting associated data (A.2.2) + # Encoded 'a' is concatenated with the associated data 'A' + assoc_len_encoded = b'' + if self._assoc_len > 0: + if self._assoc_len < (2 ** 16 - 2 ** 8): + enc_size = 2 + elif self._assoc_len < (2 ** 32): + assoc_len_encoded = b'\xFF\xFE' + enc_size = 4 + else: + assoc_len_encoded = b'\xFF\xFF' + enc_size = 8 + assoc_len_encoded += long_to_bytes(self._assoc_len, enc_size) + + # b_0 and assoc_len_encoded must be processed first + self._cache.insert(0, b_0) + self._cache.insert(1, assoc_len_encoded) + + # Process all the data cached so far + first_data_to_mac = b"".join(self._cache) + self._cache = b"" + self._mac_status = MacStatus.PROCESSING_AUTH_DATA + self._update(first_data_to_mac) + + def _pad_cache_and_update(self): + + assert(self._mac_status != MacStatus.NOT_STARTED) + assert(len(self._cache) < self.block_size) + + # Associated data is concatenated with the least number + # of zero bytes (possibly none) to reach alignment to + # the 16 byte boundary (A.2.3) + len_cache = len(self._cache) + if len_cache > 0: + self._update(b'\x00' * (self.block_size - len_cache)) + + def update(self, assoc_data): + """Protect associated data + + If there is any associated data, the caller has to invoke + this function one or more times, before using + ``decrypt`` or ``encrypt``. + + By *associated data* it is meant any data (e.g. packet headers) that + will not be encrypted and will be transmitted in the clear. + However, the receiver is still able to detect any modification to it. + In CCM, the *associated data* is also called + *additional authenticated data* (AAD). + + If there is no associated data, this method must not be called. + + The caller may split associated data in segments of any size, and + invoke this method multiple times, each time with the next segment. + + :Parameters: + assoc_data : bytes/bytearray/memoryview + A piece of associated data. There are no restrictions on its size. + """ + + if self.update not in self._next: + raise TypeError("update() can only be called" + " immediately after initialization") + + self._next = [self.update, self.encrypt, self.decrypt, + self.digest, self.verify] + + self._cumul_assoc_len += len(assoc_data) + if self._assoc_len is not None and \ + self._cumul_assoc_len > self._assoc_len: + raise ValueError("Associated data is too long") + + self._update(assoc_data) + return self + + def _update(self, assoc_data_pt=b""): + """Update the MAC with associated data or plaintext + (without FSM checks)""" + + # If MAC has not started yet, we just park the data into a list. + # If the data is mutable, we create a copy and store that instead. + if self._mac_status == MacStatus.NOT_STARTED: + if is_writeable_buffer(assoc_data_pt): + assoc_data_pt = _copy_bytes(None, None, assoc_data_pt) + self._cache.append(assoc_data_pt) + return + + assert(len(self._cache) < self.block_size) + + if len(self._cache) > 0: + filler = min(self.block_size - len(self._cache), + len(assoc_data_pt)) + self._cache += _copy_bytes(None, filler, assoc_data_pt) + assoc_data_pt = _copy_bytes(filler, None, assoc_data_pt) + + if len(self._cache) < self.block_size: + return + + # The cache is exactly one block + self._t = self._mac.encrypt(self._cache) + self._cache = b"" + + update_len = len(assoc_data_pt) // self.block_size * self.block_size + self._cache = _copy_bytes(update_len, None, assoc_data_pt) + if update_len > 0: + self._t = self._mac.encrypt(assoc_data_pt[:update_len])[-16:] + + def encrypt(self, plaintext, output=None): + """Encrypt data with the key set at initialization. + + A cipher object is stateful: once you have encrypted a message + you cannot encrypt (or decrypt) another message using the same + object. + + This method can be called only **once** if ``msg_len`` was + not passed at initialization. + + If ``msg_len`` was given, the data to encrypt can be broken + up in two or more pieces and `encrypt` can be called + multiple times. + + That is, the statement: + + >>> c.encrypt(a) + c.encrypt(b) + + is equivalent to: + + >>> c.encrypt(a+b) + + This function does not add any padding to the plaintext. + + :Parameters: + plaintext : bytes/bytearray/memoryview + The piece of data to encrypt. + It can be of any length. + :Keywords: + output : bytearray/memoryview + The location where the ciphertext must be written to. + If ``None``, the ciphertext is returned. + :Return: + If ``output`` is ``None``, the ciphertext as ``bytes``. + Otherwise, ``None``. + """ + + if self.encrypt not in self._next: + raise TypeError("encrypt() can only be called after" + " initialization or an update()") + self._next = [self.encrypt, self.digest] + + # No more associated data allowed from now + if self._assoc_len is None: + assert(isinstance(self._cache, list)) + self._assoc_len = sum([len(x) for x in self._cache]) + if self._msg_len is not None: + self._start_mac() + else: + if self._cumul_assoc_len < self._assoc_len: + raise ValueError("Associated data is too short") + + # Only once piece of plaintext accepted if message length was + # not declared in advance + if self._msg_len is None: + self._msg_len = len(plaintext) + self._start_mac() + self._next = [self.digest] + + self._cumul_msg_len += len(plaintext) + if self._cumul_msg_len > self._msg_len: + raise ValueError("Message is too long") + + if self._mac_status == MacStatus.PROCESSING_AUTH_DATA: + # Associated data is concatenated with the least number + # of zero bytes (possibly none) to reach alignment to + # the 16 byte boundary (A.2.3) + self._pad_cache_and_update() + self._mac_status = MacStatus.PROCESSING_PLAINTEXT + + self._update(plaintext) + return self._cipher.encrypt(plaintext, output=output) + + def decrypt(self, ciphertext, output=None): + """Decrypt data with the key set at initialization. + + A cipher object is stateful: once you have decrypted a message + you cannot decrypt (or encrypt) another message with the same + object. + + This method can be called only **once** if ``msg_len`` was + not passed at initialization. + + If ``msg_len`` was given, the data to decrypt can be + broken up in two or more pieces and `decrypt` can be + called multiple times. + + That is, the statement: + + >>> c.decrypt(a) + c.decrypt(b) + + is equivalent to: + + >>> c.decrypt(a+b) + + This function does not remove any padding from the plaintext. + + :Parameters: + ciphertext : bytes/bytearray/memoryview + The piece of data to decrypt. + It can be of any length. + :Keywords: + output : bytearray/memoryview + The location where the plaintext must be written to. + If ``None``, the plaintext is returned. + :Return: + If ``output`` is ``None``, the plaintext as ``bytes``. + Otherwise, ``None``. + """ + + if self.decrypt not in self._next: + raise TypeError("decrypt() can only be called" + " after initialization or an update()") + self._next = [self.decrypt, self.verify] + + # No more associated data allowed from now + if self._assoc_len is None: + assert(isinstance(self._cache, list)) + self._assoc_len = sum([len(x) for x in self._cache]) + if self._msg_len is not None: + self._start_mac() + else: + if self._cumul_assoc_len < self._assoc_len: + raise ValueError("Associated data is too short") + + # Only once piece of ciphertext accepted if message length was + # not declared in advance + if self._msg_len is None: + self._msg_len = len(ciphertext) + self._start_mac() + self._next = [self.verify] + + self._cumul_msg_len += len(ciphertext) + if self._cumul_msg_len > self._msg_len: + raise ValueError("Message is too long") + + if self._mac_status == MacStatus.PROCESSING_AUTH_DATA: + # Associated data is concatenated with the least number + # of zero bytes (possibly none) to reach alignment to + # the 16 byte boundary (A.2.3) + self._pad_cache_and_update() + self._mac_status = MacStatus.PROCESSING_PLAINTEXT + + # Encrypt is equivalent to decrypt with the CTR mode + plaintext = self._cipher.encrypt(ciphertext, output=output) + if output is None: + self._update(plaintext) + else: + self._update(output) + return plaintext + + def digest(self): + """Compute the *binary* MAC tag. + + The caller invokes this function at the very end. + + This method returns the MAC that shall be sent to the receiver, + together with the ciphertext. + + :Return: the MAC, as a byte string. + """ + + if self.digest not in self._next: + raise TypeError("digest() cannot be called when decrypting" + " or validating a message") + self._next = [self.digest] + return self._digest() + + def _digest(self): + if self._mac_tag: + return self._mac_tag + + if self._assoc_len is None: + assert(isinstance(self._cache, list)) + self._assoc_len = sum([len(x) for x in self._cache]) + if self._msg_len is not None: + self._start_mac() + else: + if self._cumul_assoc_len < self._assoc_len: + raise ValueError("Associated data is too short") + + if self._msg_len is None: + self._msg_len = 0 + self._start_mac() + + if self._cumul_msg_len != self._msg_len: + raise ValueError("Message is too short") + + # Both associated data and payload are concatenated with the least + # number of zero bytes (possibly none) that align it to the + # 16 byte boundary (A.2.2 and A.2.3) + self._pad_cache_and_update() + + # Step 8 in 6.1 (T xor MSB_Tlen(S_0)) + self._mac_tag = strxor(self._t, self._s_0)[:self._mac_len] + + return self._mac_tag + + def hexdigest(self): + """Compute the *printable* MAC tag. + + This method is like `digest`. + + :Return: the MAC, as a hexadecimal string. + """ + return "".join(["%02x" % bord(x) for x in self.digest()]) + + def verify(self, received_mac_tag): + """Validate the *binary* MAC tag. + + The caller invokes this function at the very end. + + This method checks if the decrypted message is indeed valid + (that is, if the key is correct) and it has not been + tampered with while in transit. + + :Parameters: + received_mac_tag : bytes/bytearray/memoryview + This is the *binary* MAC, as received from the sender. + :Raises ValueError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + if self.verify not in self._next: + raise TypeError("verify() cannot be called" + " when encrypting a message") + self._next = [self.verify] + + self._digest() + secret = get_random_bytes(16) + + mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=self._mac_tag) + mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=received_mac_tag) + + if mac1.digest() != mac2.digest(): + raise ValueError("MAC check failed") + + def hexverify(self, hex_mac_tag): + """Validate the *printable* MAC tag. + + This method is like `verify`. + + :Parameters: + hex_mac_tag : string + This is the *printable* MAC, as received from the sender. + :Raises ValueError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + self.verify(unhexlify(hex_mac_tag)) + + def encrypt_and_digest(self, plaintext, output=None): + """Perform encrypt() and digest() in one step. + + :Parameters: + plaintext : bytes/bytearray/memoryview + The piece of data to encrypt. + :Keywords: + output : bytearray/memoryview + The location where the ciphertext must be written to. + If ``None``, the ciphertext is returned. + :Return: + a tuple with two items: + + - the ciphertext, as ``bytes`` + - the MAC tag, as ``bytes`` + + The first item becomes ``None`` when the ``output`` parameter + specified a location for the result. + """ + + return self.encrypt(plaintext, output=output), self.digest() + + def decrypt_and_verify(self, ciphertext, received_mac_tag, output=None): + """Perform decrypt() and verify() in one step. + + :Parameters: + ciphertext : bytes/bytearray/memoryview + The piece of data to decrypt. + received_mac_tag : bytes/bytearray/memoryview + This is the *binary* MAC, as received from the sender. + :Keywords: + output : bytearray/memoryview + The location where the plaintext must be written to. + If ``None``, the plaintext is returned. + :Return: the plaintext as ``bytes`` or ``None`` when the ``output`` + parameter specified a location for the result. + :Raises ValueError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + plaintext = self.decrypt(ciphertext, output=output) + self.verify(received_mac_tag) + return plaintext + + +def _create_ccm_cipher(factory, **kwargs): + """Create a new block cipher, configured in CCM mode. + + :Parameters: + factory : module + A symmetric cipher module from `Cryptodome.Cipher` (like + `Cryptodome.Cipher.AES`). + + :Keywords: + key : bytes/bytearray/memoryview + The secret key to use in the symmetric cipher. + + nonce : bytes/bytearray/memoryview + A value that must never be reused for any other encryption. + + Its length must be in the range ``[7..13]``. + 11 or 12 bytes are reasonable values in general. Bear in + mind that with CCM there is a trade-off between nonce length and + maximum message size. + + If not specified, a 11 byte long random string is used. + + mac_len : integer + Length of the MAC, in bytes. It must be even and in + the range ``[4..16]``. The default is 16. + + msg_len : integer + Length of the message to (de)cipher. + If not specified, ``encrypt`` or ``decrypt`` may only be called once. + + assoc_len : integer + Length of the associated data. + If not specified, all data is internally buffered. + """ + + try: + key = key = kwargs.pop("key") + except KeyError as e: + raise TypeError("Missing parameter: " + str(e)) + + nonce = kwargs.pop("nonce", None) # N + if nonce is None: + nonce = get_random_bytes(11) + mac_len = kwargs.pop("mac_len", factory.block_size) + msg_len = kwargs.pop("msg_len", None) # p + assoc_len = kwargs.pop("assoc_len", None) # a + cipher_params = dict(kwargs) + + return CcmMode(factory, key, nonce, mac_len, msg_len, + assoc_len, cipher_params) diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ccm.pyi b/frozen_deps/Cryptodome/Cipher/_mode_ccm.pyi new file mode 100644 index 0000000..4b9f620 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_ccm.pyi @@ -0,0 +1,47 @@ +from types import ModuleType +from typing import Union, overload, Dict, Tuple, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +__all__ = ['CcmMode'] + +class CcmMode(object): + block_size: int + nonce: bytes + + def __init__(self, + factory: ModuleType, + key: Buffer, + nonce: Buffer, + mac_len: int, + msg_len: int, + assoc_len: int, + cipher_params: Dict) -> None: ... + + def update(self, assoc_data: Buffer) -> CcmMode: ... + + @overload + def encrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + @overload + def decrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def verify(self, received_mac_tag: Buffer) -> None: ... + def hexverify(self, hex_mac_tag: str) -> None: ... + + @overload + def encrypt_and_digest(self, + plaintext: Buffer) -> Tuple[bytes, bytes]: ... + @overload + def encrypt_and_digest(self, + plaintext: Buffer, + output: Buffer) -> Tuple[None, bytes]: ... + def decrypt_and_verify(self, + ciphertext: Buffer, + received_mac_tag: Buffer, + output: Optional[Union[bytearray, memoryview]] = ...) -> bytes: ... diff --git a/frozen_deps/Cryptodome/Cipher/_mode_cfb.py b/frozen_deps/Cryptodome/Cipher/_mode_cfb.py new file mode 100644 index 0000000..b790dd4 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_cfb.py @@ -0,0 +1,293 @@ +# -*- coding: utf-8 -*- +# +# Cipher/mode_cfb.py : CFB mode +# +# =================================================================== +# 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. +# =================================================================== + +""" +Counter Feedback (CFB) mode. +""" + +__all__ = ['CfbMode'] + +from Cryptodome.Util.py3compat import _copy_bytes +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer, + create_string_buffer, get_raw_buffer, + SmartPointer, c_size_t, c_uint8_ptr, + is_writeable_buffer) + +from Cryptodome.Random import get_random_bytes + +raw_cfb_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_cfb",""" + int CFB_start_operation(void *cipher, + const uint8_t iv[], + size_t iv_len, + size_t segment_len, /* In bytes */ + void **pResult); + int CFB_encrypt(void *cfbState, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int CFB_decrypt(void *cfbState, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int CFB_stop_operation(void *state);""" + ) + + +class CfbMode(object): + """*Cipher FeedBack (CFB)*. + + This mode is similar to CFB, 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. + + See `NIST SP800-38A`_ , Section 6.3. + + .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + + :undocumented: __init__ + """ + + def __init__(self, block_cipher, iv, segment_size): + """Create a new block cipher, configured in CFB mode. + + :Parameters: + block_cipher : C pointer + A smart pointer to the low-level block cipher instance. + + iv : bytes/bytearray/memoryview + The initialization vector to use for encryption or decryption. + It is as long as the cipher block. + + **The IV must be unpredictable**. Ideally it is picked randomly. + + Reusing the *IV* for encryptions performed with the same key + compromises confidentiality. + + segment_size : integer + The number of bytes the plaintext and ciphertext are segmented in. + """ + + self._state = VoidPointer() + result = raw_cfb_lib.CFB_start_operation(block_cipher.get(), + c_uint8_ptr(iv), + c_size_t(len(iv)), + c_size_t(segment_size), + self._state.address_of()) + if result: + raise ValueError("Error %d while instantiating the CFB mode" % result) + + # Ensure that object disposal of this Python object will (eventually) + # free the memory allocated by the raw library for the cipher mode + self._state = SmartPointer(self._state.get(), + raw_cfb_lib.CFB_stop_operation) + + # Memory allocated for the underlying block cipher is now owed + # by the cipher mode + block_cipher.release() + + self.block_size = len(iv) + """The block size of the underlying cipher, in bytes.""" + + self.iv = _copy_bytes(None, None, iv) + """The Initialization Vector originally used to create the object. + The value does not change.""" + + self.IV = self.iv + """Alias for `iv`""" + + self._next = [ self.encrypt, self.decrypt ] + + def encrypt(self, plaintext, output=None): + """Encrypt data with the key and the parameters set at initialization. + + A cipher object is stateful: once you have encrypted a message + you cannot encrypt (or decrypt) another message using the same + object. + + The data to encrypt can be broken up in two or + more pieces and `encrypt` can be called multiple times. + + That is, the statement: + + >>> c.encrypt(a) + c.encrypt(b) + + is equivalent to: + + >>> c.encrypt(a+b) + + This function does not add any padding to the plaintext. + + :Parameters: + plaintext : bytes/bytearray/memoryview + The piece of data to encrypt. + It can be of any length. + :Keywords: + output : bytearray/memoryview + The location where the ciphertext must be written to. + If ``None``, the ciphertext is returned. + :Return: + If ``output`` is ``None``, the ciphertext is returned as ``bytes``. + Otherwise, ``None``. + """ + + if self.encrypt not in self._next: + raise TypeError("encrypt() cannot be called after decrypt()") + self._next = [ self.encrypt ] + + if output is None: + ciphertext = create_string_buffer(len(plaintext)) + else: + ciphertext = output + + if not is_writeable_buffer(output): + raise TypeError("output must be a bytearray or a writeable memoryview") + + if len(plaintext) != len(output): + raise ValueError("output must have the same length as the input" + " (%d bytes)" % len(plaintext)) + + result = raw_cfb_lib.CFB_encrypt(self._state.get(), + c_uint8_ptr(plaintext), + c_uint8_ptr(ciphertext), + c_size_t(len(plaintext))) + if result: + raise ValueError("Error %d while encrypting in CFB mode" % result) + + if output is None: + return get_raw_buffer(ciphertext) + else: + return None + + def decrypt(self, ciphertext, output=None): + """Decrypt data with the key and the parameters set at initialization. + + A cipher object is stateful: once you have decrypted a message + you cannot decrypt (or encrypt) another message with the same + object. + + The data to decrypt can be broken up in two or + more pieces and `decrypt` can be called multiple times. + + That is, the statement: + + >>> c.decrypt(a) + c.decrypt(b) + + is equivalent to: + + >>> c.decrypt(a+b) + + This function does not remove any padding from the plaintext. + + :Parameters: + ciphertext : bytes/bytearray/memoryview + The piece of data to decrypt. + It can be of any length. + :Keywords: + output : bytearray/memoryview + The location where the plaintext must be written to. + If ``None``, the plaintext is returned. + :Return: + If ``output`` is ``None``, the plaintext is returned as ``bytes``. + Otherwise, ``None``. + """ + + if self.decrypt not in self._next: + raise TypeError("decrypt() cannot be called after encrypt()") + self._next = [ self.decrypt ] + + if output is None: + plaintext = create_string_buffer(len(ciphertext)) + else: + plaintext = output + + if not is_writeable_buffer(output): + raise TypeError("output must be a bytearray or a writeable memoryview") + + if len(ciphertext) != len(output): + raise ValueError("output must have the same length as the input" + " (%d bytes)" % len(plaintext)) + + result = raw_cfb_lib.CFB_decrypt(self._state.get(), + c_uint8_ptr(ciphertext), + c_uint8_ptr(plaintext), + c_size_t(len(ciphertext))) + if result: + raise ValueError("Error %d while decrypting in CFB mode" % result) + + if output is None: + return get_raw_buffer(plaintext) + else: + return None + + +def _create_cfb_cipher(factory, **kwargs): + """Instantiate a cipher object that performs CFB encryption/decryption. + + :Parameters: + factory : module + The underlying block cipher, a module from ``Cryptodome.Cipher``. + + :Keywords: + iv : bytes/bytearray/memoryview + The IV to use for CFB. + + IV : bytes/bytearray/memoryview + Alias for ``iv``. + + segment_size : integer + The number of bit the plaintext and ciphertext are segmented in. + If not present, the default is 8. + + Any other keyword will be passed to the underlying block cipher. + See the relevant documentation for details (at least ``key`` will need + to be present). + """ + + cipher_state = factory._create_base_cipher(kwargs) + + iv = kwargs.pop("IV", None) + IV = kwargs.pop("iv", None) + + if (None, None) == (iv, IV): + iv = get_random_bytes(factory.block_size) + if iv is not None: + if IV is not None: + raise TypeError("You must either use 'iv' or 'IV', not both") + else: + iv = IV + + if len(iv) != factory.block_size: + raise ValueError("Incorrect IV length (it must be %d bytes long)" % + factory.block_size) + + segment_size_bytes, rem = divmod(kwargs.pop("segment_size", 8), 8) + if segment_size_bytes == 0 or rem != 0: + raise ValueError("'segment_size' must be positive and multiple of 8 bits") + + if kwargs: + raise TypeError("Unknown parameters for CFB: %s" % str(kwargs)) + return CfbMode(cipher_state, iv, segment_size_bytes) diff --git a/frozen_deps/Cryptodome/Cipher/_mode_cfb.pyi b/frozen_deps/Cryptodome/Cipher/_mode_cfb.pyi new file mode 100644 index 0000000..228e464 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_cfb.pyi @@ -0,0 +1,26 @@ +from typing import Union, overload + +from Cryptodome.Util._raw_api import SmartPointer + +Buffer = Union[bytes, bytearray, memoryview] + +__all__ = ['CfbMode'] + + +class CfbMode(object): + block_size: int + iv: Buffer + IV: Buffer + + def __init__(self, + block_cipher: SmartPointer, + iv: Buffer, + segment_size: int) -> None: ... + @overload + def encrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + @overload + def decrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ctr.py b/frozen_deps/Cryptodome/Cipher/_mode_ctr.py new file mode 100644 index 0000000..99712d0 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_ctr.py @@ -0,0 +1,393 @@ +# -*- coding: utf-8 -*- +# +# Cipher/mode_ctr.py : CTR mode +# +# =================================================================== +# 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. +# =================================================================== + +""" +Counter (CTR) mode. +""" + +__all__ = ['CtrMode'] + +import struct + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer, + create_string_buffer, get_raw_buffer, + SmartPointer, c_size_t, c_uint8_ptr, + is_writeable_buffer) + +from Cryptodome.Random import get_random_bytes +from Cryptodome.Util.py3compat import _copy_bytes, is_native_int +from Cryptodome.Util.number import long_to_bytes + +raw_ctr_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_ctr", """ + int CTR_start_operation(void *cipher, + uint8_t initialCounterBlock[], + size_t initialCounterBlock_len, + size_t prefix_len, + unsigned counter_len, + unsigned littleEndian, + void **pResult); + int CTR_encrypt(void *ctrState, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int CTR_decrypt(void *ctrState, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int CTR_stop_operation(void *ctrState);""" + ) + + +class CtrMode(object): + """*CounTeR (CTR)* mode. + + 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. + + 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 + + :undocumented: __init__ + """ + + def __init__(self, block_cipher, initial_counter_block, + prefix_len, counter_len, little_endian): + """Create a new block cipher, configured in CTR mode. + + :Parameters: + block_cipher : C pointer + A smart pointer to the low-level block cipher instance. + + initial_counter_block : bytes/bytearray/memoryview + The initial plaintext to use to generate the key stream. + + It is as large as the cipher block, and it embeds + the initial value of the counter. + + This value must not be reused. + It shall contain a nonce or a random component. + Reusing the *initial counter block* for encryptions + performed with the same key compromises confidentiality. + + prefix_len : integer + The amount of bytes at the beginning of the counter block + that never change. + + counter_len : integer + The length in bytes of the counter embedded in the counter + block. + + little_endian : boolean + True if the counter in the counter block is an integer encoded + in little endian mode. If False, it is big endian. + """ + + if len(initial_counter_block) == prefix_len + counter_len: + self.nonce = _copy_bytes(None, prefix_len, initial_counter_block) + """Nonce; not available if there is a fixed suffix""" + + self._state = VoidPointer() + result = raw_ctr_lib.CTR_start_operation(block_cipher.get(), + c_uint8_ptr(initial_counter_block), + c_size_t(len(initial_counter_block)), + c_size_t(prefix_len), + counter_len, + little_endian, + self._state.address_of()) + if result: + raise ValueError("Error %X while instantiating the CTR mode" + % result) + + # Ensure that object disposal of this Python object will (eventually) + # free the memory allocated by the raw library for the cipher mode + self._state = SmartPointer(self._state.get(), + raw_ctr_lib.CTR_stop_operation) + + # Memory allocated for the underlying block cipher is now owed + # by the cipher mode + block_cipher.release() + + self.block_size = len(initial_counter_block) + """The block size of the underlying cipher, in bytes.""" + + self._next = [self.encrypt, self.decrypt] + + def encrypt(self, plaintext, output=None): + """Encrypt data with the key and the parameters set at initialization. + + A cipher object is stateful: once you have encrypted a message + you cannot encrypt (or decrypt) another message using the same + object. + + The data to encrypt can be broken up in two or + more pieces and `encrypt` can be called multiple times. + + That is, the statement: + + >>> c.encrypt(a) + c.encrypt(b) + + is equivalent to: + + >>> c.encrypt(a+b) + + This function does not add any padding to the plaintext. + + :Parameters: + plaintext : bytes/bytearray/memoryview + The piece of data to encrypt. + It can be of any length. + :Keywords: + output : bytearray/memoryview + The location where the ciphertext must be written to. + If ``None``, the ciphertext is returned. + :Return: + If ``output`` is ``None``, the ciphertext is returned as ``bytes``. + Otherwise, ``None``. + """ + + if self.encrypt not in self._next: + raise TypeError("encrypt() cannot be called after decrypt()") + self._next = [self.encrypt] + + if output is None: + ciphertext = create_string_buffer(len(plaintext)) + else: + ciphertext = output + + if not is_writeable_buffer(output): + raise TypeError("output must be a bytearray or a writeable memoryview") + + if len(plaintext) != len(output): + raise ValueError("output must have the same length as the input" + " (%d bytes)" % len(plaintext)) + + result = raw_ctr_lib.CTR_encrypt(self._state.get(), + c_uint8_ptr(plaintext), + c_uint8_ptr(ciphertext), + c_size_t(len(plaintext))) + if result: + if result == 0x60002: + raise OverflowError("The counter has wrapped around in" + " CTR mode") + raise ValueError("Error %X while encrypting in CTR mode" % result) + + if output is None: + return get_raw_buffer(ciphertext) + else: + return None + + def decrypt(self, ciphertext, output=None): + """Decrypt data with the key and the parameters set at initialization. + + A cipher object is stateful: once you have decrypted a message + you cannot decrypt (or encrypt) another message with the same + object. + + The data to decrypt can be broken up in two or + more pieces and `decrypt` can be called multiple times. + + That is, the statement: + + >>> c.decrypt(a) + c.decrypt(b) + + is equivalent to: + + >>> c.decrypt(a+b) + + This function does not remove any padding from the plaintext. + + :Parameters: + ciphertext : bytes/bytearray/memoryview + The piece of data to decrypt. + It can be of any length. + :Keywords: + output : bytearray/memoryview + The location where the plaintext must be written to. + If ``None``, the plaintext is returned. + :Return: + If ``output`` is ``None``, the plaintext is returned as ``bytes``. + Otherwise, ``None``. + """ + + if self.decrypt not in self._next: + raise TypeError("decrypt() cannot be called after encrypt()") + self._next = [self.decrypt] + + if output is None: + plaintext = create_string_buffer(len(ciphertext)) + else: + plaintext = output + + if not is_writeable_buffer(output): + raise TypeError("output must be a bytearray or a writeable memoryview") + + if len(ciphertext) != len(output): + raise ValueError("output must have the same length as the input" + " (%d bytes)" % len(plaintext)) + + + result = raw_ctr_lib.CTR_decrypt(self._state.get(), + c_uint8_ptr(ciphertext), + c_uint8_ptr(plaintext), + c_size_t(len(ciphertext))) + if result: + if result == 0x60002: + raise OverflowError("The counter has wrapped around in" + " CTR mode") + raise ValueError("Error %X while decrypting in CTR mode" % result) + + if output is None: + return get_raw_buffer(plaintext) + else: + return None + + +def _create_ctr_cipher(factory, **kwargs): + """Instantiate a cipher object that performs CTR encryption/decryption. + + :Parameters: + factory : module + The underlying block cipher, a module from ``Cryptodome.Cipher``. + + :Keywords: + nonce : bytes/bytearray/memoryview + The fixed part at the beginning of the counter block - the rest is + the counter number that gets increased when processing the next block. + The nonce must be such that no two messages are encrypted under the + same key and the same nonce. + + The nonce must be shorter than the block size (it can have + zero length; the counter is then as long as the block). + + If this parameter is not present, a random nonce will be created with + length equal to half the block size. No random nonce shorter than + 64 bits will be created though - you must really think through all + security consequences of using such a short block size. + + initial_value : posive integer or bytes/bytearray/memoryview + The initial value for the counter. If not present, the cipher will + start counting from 0. The value is incremented by one for each block. + The counter number is encoded in big endian mode. + + counter : object + Instance of ``Cryptodome.Util.Counter``, which allows full customization + of the counter block. This parameter is incompatible to both ``nonce`` + and ``initial_value``. + + Any other keyword will be passed to the underlying block cipher. + See the relevant documentation for details (at least ``key`` will need + to be present). + """ + + cipher_state = factory._create_base_cipher(kwargs) + + counter = kwargs.pop("counter", None) + nonce = kwargs.pop("nonce", None) + initial_value = kwargs.pop("initial_value", None) + if kwargs: + raise TypeError("Invalid parameters for CTR mode: %s" % str(kwargs)) + + if counter is not None and (nonce, initial_value) != (None, None): + raise TypeError("'counter' and 'nonce'/'initial_value'" + " are mutually exclusive") + + if counter is None: + # Cryptodome.Util.Counter is not used + if nonce is None: + if factory.block_size < 16: + raise TypeError("Impossible to create a safe nonce for short" + " block sizes") + nonce = get_random_bytes(factory.block_size // 2) + else: + if len(nonce) >= factory.block_size: + raise ValueError("Nonce is too long") + + # What is not nonce is counter + counter_len = factory.block_size - len(nonce) + + if initial_value is None: + initial_value = 0 + + if is_native_int(initial_value): + if (1 << (counter_len * 8)) - 1 < initial_value: + raise ValueError("Initial counter value is too large") + initial_counter_block = nonce + long_to_bytes(initial_value, counter_len) + else: + if len(initial_value) != counter_len: + raise ValueError("Incorrect length for counter byte string (%d bytes, expected %d)" % (len(initial_value), counter_len)) + initial_counter_block = nonce + initial_value + + return CtrMode(cipher_state, + initial_counter_block, + len(nonce), # prefix + counter_len, + False) # little_endian + + # Cryptodome.Util.Counter is used + + # 'counter' used to be a callable object, but now it is + # just a dictionary for backward compatibility. + _counter = dict(counter) + try: + counter_len = _counter.pop("counter_len") + prefix = _counter.pop("prefix") + suffix = _counter.pop("suffix") + initial_value = _counter.pop("initial_value") + little_endian = _counter.pop("little_endian") + except KeyError: + raise TypeError("Incorrect counter object" + " (use Cryptodome.Util.Counter.new)") + + # Compute initial counter block + words = [] + while initial_value > 0: + words.append(struct.pack('B', initial_value & 255)) + initial_value >>= 8 + words += [ b'\x00' ] * max(0, counter_len - len(words)) + if not little_endian: + words.reverse() + initial_counter_block = prefix + b"".join(words) + suffix + + if len(initial_counter_block) != factory.block_size: + raise ValueError("Size of the counter block (%d bytes) must match" + " block size (%d)" % (len(initial_counter_block), + factory.block_size)) + + return CtrMode(cipher_state, initial_counter_block, + len(prefix), counter_len, little_endian) diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ctr.pyi b/frozen_deps/Cryptodome/Cipher/_mode_ctr.pyi new file mode 100644 index 0000000..a68a890 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_ctr.pyi @@ -0,0 +1,27 @@ +from typing import Union, overload + +from Cryptodome.Util._raw_api import SmartPointer + +Buffer = Union[bytes, bytearray, memoryview] + +__all__ = ['CtrMode'] + +class CtrMode(object): + block_size: int + nonce: bytes + + def __init__(self, + block_cipher: SmartPointer, + initial_counter_block: Buffer, + prefix_len: int, + counter_len: int, + little_endian: bool) -> None: ... + @overload + def encrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + @overload + def decrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + diff --git a/frozen_deps/Cryptodome/Cipher/_mode_eax.py b/frozen_deps/Cryptodome/Cipher/_mode_eax.py new file mode 100644 index 0000000..8efb77a --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_eax.py @@ -0,0 +1,408 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +""" +EAX mode. +""" + +__all__ = ['EaxMode'] + +import struct +from binascii import unhexlify + +from Cryptodome.Util.py3compat import byte_string, bord, _copy_bytes + +from Cryptodome.Util._raw_api import is_buffer + +from Cryptodome.Util.strxor import strxor +from Cryptodome.Util.number import long_to_bytes, bytes_to_long + +from Cryptodome.Hash import CMAC, BLAKE2s +from Cryptodome.Random import get_random_bytes + + +class EaxMode(object): + """*EAX* mode. + + This is an Authenticated Encryption with Associated Data + (`AEAD`_) mode. It provides both confidentiality and authenticity. + + The header of the message may be left in the clear, if needed, + and it will still be subject to authentication. + + The decryption step tells the receiver if the message comes + from a source that really knowns the secret key. + Additionally, decryption detects if any part of the message - + including the header - has been modified or corrupted. + + This mode requires a *nonce*. + + This mode is only available for ciphers that operate on 64 or + 128 bits blocks. + + There are no official standards defining EAX. + The implementation is based on `a proposal`__ that + was presented to NIST. + + .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html + .. __: http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/eax/eax-spec.pdf + + :undocumented: __init__ + """ + + def __init__(self, factory, key, nonce, mac_len, cipher_params): + """EAX cipher mode""" + + self.block_size = factory.block_size + """The block size of the underlying cipher, in bytes.""" + + self.nonce = _copy_bytes(None, None, nonce) + """The nonce originally used to create the object.""" + + self._mac_len = mac_len + self._mac_tag = None # Cache for MAC tag + + # Allowed transitions after initialization + self._next = [self.update, self.encrypt, self.decrypt, + self.digest, self.verify] + + # MAC tag length + if not (4 <= self._mac_len <= self.block_size): + raise ValueError("Parameter 'mac_len' must not be larger than %d" + % self.block_size) + + # Nonce cannot be empty and must be a byte string + if len(self.nonce) == 0: + raise ValueError("Nonce cannot be empty in EAX mode") + if not is_buffer(nonce): + raise TypeError("nonce must be bytes, bytearray or memoryview") + + self._omac = [ + CMAC.new(key, + b'\x00' * (self.block_size - 1) + struct.pack('B', i), + ciphermod=factory, + cipher_params=cipher_params) + for i in range(0, 3) + ] + + # Compute MAC of nonce + self._omac[0].update(self.nonce) + self._signer = self._omac[1] + + # MAC of the nonce is also the initial counter for CTR encryption + counter_int = bytes_to_long(self._omac[0].digest()) + self._cipher = factory.new(key, + factory.MODE_CTR, + initial_value=counter_int, + nonce=b"", + **cipher_params) + + def update(self, assoc_data): + """Protect associated data + + If there is any associated data, the caller has to invoke + this function one or more times, before using + ``decrypt`` or ``encrypt``. + + By *associated data* it is meant any data (e.g. packet headers) that + will not be encrypted and will be transmitted in the clear. + However, the receiver is still able to detect any modification to it. + + If there is no associated data, this method must not be called. + + The caller may split associated data in segments of any size, and + invoke this method multiple times, each time with the next segment. + + :Parameters: + assoc_data : bytes/bytearray/memoryview + A piece of associated data. There are no restrictions on its size. + """ + + if self.update not in self._next: + raise TypeError("update() can only be called" + " immediately after initialization") + + self._next = [self.update, self.encrypt, self.decrypt, + self.digest, self.verify] + + self._signer.update(assoc_data) + return self + + def encrypt(self, plaintext, output=None): + """Encrypt data with the key and the parameters set at initialization. + + A cipher object is stateful: once you have encrypted a message + you cannot encrypt (or decrypt) another message using the same + object. + + The data to encrypt can be broken up in two or + more pieces and `encrypt` can be called multiple times. + + That is, the statement: + + >>> c.encrypt(a) + c.encrypt(b) + + is equivalent to: + + >>> c.encrypt(a+b) + + This function does not add any padding to the plaintext. + + :Parameters: + plaintext : bytes/bytearray/memoryview + The piece of data to encrypt. + It can be of any length. + :Keywords: + output : bytearray/memoryview + The location where the ciphertext must be written to. + If ``None``, the ciphertext is returned. + :Return: + If ``output`` is ``None``, the ciphertext as ``bytes``. + Otherwise, ``None``. + """ + + if self.encrypt not in self._next: + raise TypeError("encrypt() can only be called after" + " initialization or an update()") + self._next = [self.encrypt, self.digest] + ct = self._cipher.encrypt(plaintext, output=output) + if output is None: + self._omac[2].update(ct) + else: + self._omac[2].update(output) + return ct + + def decrypt(self, ciphertext, output=None): + """Decrypt data with the key and the parameters set at initialization. + + A cipher object is stateful: once you have decrypted a message + you cannot decrypt (or encrypt) another message with the same + object. + + The data to decrypt can be broken up in two or + more pieces and `decrypt` can be called multiple times. + + That is, the statement: + + >>> c.decrypt(a) + c.decrypt(b) + + is equivalent to: + + >>> c.decrypt(a+b) + + This function does not remove any padding from the plaintext. + + :Parameters: + ciphertext : bytes/bytearray/memoryview + The piece of data to decrypt. + It can be of any length. + :Keywords: + output : bytearray/memoryview + The location where the plaintext must be written to. + If ``None``, the plaintext is returned. + :Return: + If ``output`` is ``None``, the plaintext as ``bytes``. + Otherwise, ``None``. + """ + + if self.decrypt not in self._next: + raise TypeError("decrypt() can only be called" + " after initialization or an update()") + self._next = [self.decrypt, self.verify] + self._omac[2].update(ciphertext) + return self._cipher.decrypt(ciphertext, output=output) + + def digest(self): + """Compute the *binary* MAC tag. + + The caller invokes this function at the very end. + + This method returns the MAC that shall be sent to the receiver, + together with the ciphertext. + + :Return: the MAC, as a byte string. + """ + + if self.digest not in self._next: + raise TypeError("digest() cannot be called when decrypting" + " or validating a message") + self._next = [self.digest] + + if not self._mac_tag: + tag = b'\x00' * self.block_size + for i in range(3): + tag = strxor(tag, self._omac[i].digest()) + self._mac_tag = tag[:self._mac_len] + + return self._mac_tag + + def hexdigest(self): + """Compute the *printable* MAC tag. + + This method is like `digest`. + + :Return: the MAC, as a hexadecimal string. + """ + return "".join(["%02x" % bord(x) for x in self.digest()]) + + def verify(self, received_mac_tag): + """Validate the *binary* MAC tag. + + The caller invokes this function at the very end. + + This method checks if the decrypted message is indeed valid + (that is, if the key is correct) and it has not been + tampered with while in transit. + + :Parameters: + received_mac_tag : bytes/bytearray/memoryview + This is the *binary* MAC, as received from the sender. + :Raises MacMismatchError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + if self.verify not in self._next: + raise TypeError("verify() cannot be called" + " when encrypting a message") + self._next = [self.verify] + + if not self._mac_tag: + tag = b'\x00' * self.block_size + for i in range(3): + tag = strxor(tag, self._omac[i].digest()) + self._mac_tag = tag[:self._mac_len] + + secret = get_random_bytes(16) + + mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=self._mac_tag) + mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=received_mac_tag) + + if mac1.digest() != mac2.digest(): + raise ValueError("MAC check failed") + + def hexverify(self, hex_mac_tag): + """Validate the *printable* MAC tag. + + This method is like `verify`. + + :Parameters: + hex_mac_tag : string + This is the *printable* MAC, as received from the sender. + :Raises MacMismatchError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + self.verify(unhexlify(hex_mac_tag)) + + def encrypt_and_digest(self, plaintext, output=None): + """Perform encrypt() and digest() in one step. + + :Parameters: + plaintext : bytes/bytearray/memoryview + The piece of data to encrypt. + :Keywords: + output : bytearray/memoryview + The location where the ciphertext must be written to. + If ``None``, the ciphertext is returned. + :Return: + a tuple with two items: + + - the ciphertext, as ``bytes`` + - the MAC tag, as ``bytes`` + + The first item becomes ``None`` when the ``output`` parameter + specified a location for the result. + """ + + return self.encrypt(plaintext, output=output), self.digest() + + def decrypt_and_verify(self, ciphertext, received_mac_tag, output=None): + """Perform decrypt() and verify() in one step. + + :Parameters: + ciphertext : bytes/bytearray/memoryview + The piece of data to decrypt. + received_mac_tag : bytes/bytearray/memoryview + This is the *binary* MAC, as received from the sender. + :Keywords: + output : bytearray/memoryview + The location where the plaintext must be written to. + If ``None``, the plaintext is returned. + :Return: the plaintext as ``bytes`` or ``None`` when the ``output`` + parameter specified a location for the result. + :Raises MacMismatchError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + pt = self.decrypt(ciphertext, output=output) + self.verify(received_mac_tag) + return pt + + +def _create_eax_cipher(factory, **kwargs): + """Create a new block cipher, configured in EAX mode. + + :Parameters: + factory : module + A symmetric cipher module from `Cryptodome.Cipher` (like + `Cryptodome.Cipher.AES`). + + :Keywords: + key : bytes/bytearray/memoryview + The secret key to use in the symmetric cipher. + + nonce : bytes/bytearray/memoryview + A value that must never be reused for any other encryption. + There are no restrictions on its length, but it is recommended to use + at least 16 bytes. + + The nonce shall never repeat for two different messages encrypted with + the same key, but it does not need to be random. + + If not specified, a 16 byte long random string is used. + + mac_len : integer + Length of the MAC, in bytes. It must be no larger than the cipher + block bytes (which is the default). + """ + + try: + key = kwargs.pop("key") + nonce = kwargs.pop("nonce", None) + if nonce is None: + nonce = get_random_bytes(16) + mac_len = kwargs.pop("mac_len", factory.block_size) + except KeyError as e: + raise TypeError("Missing parameter: " + str(e)) + + return EaxMode(factory, key, nonce, mac_len, kwargs) diff --git a/frozen_deps/Cryptodome/Cipher/_mode_eax.pyi b/frozen_deps/Cryptodome/Cipher/_mode_eax.pyi new file mode 100644 index 0000000..cbfa467 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_eax.pyi @@ -0,0 +1,45 @@ +from types import ModuleType +from typing import Any, Union, Tuple, Dict, overload, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +__all__ = ['EaxMode'] + +class EaxMode(object): + block_size: int + nonce: bytes + + def __init__(self, + factory: ModuleType, + key: Buffer, + nonce: Buffer, + mac_len: int, + cipher_params: Dict) -> None: ... + + def update(self, assoc_data: Buffer) -> EaxMode: ... + + @overload + def encrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + @overload + def decrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def verify(self, received_mac_tag: Buffer) -> None: ... + def hexverify(self, hex_mac_tag: str) -> None: ... + + @overload + def encrypt_and_digest(self, + plaintext: Buffer) -> Tuple[bytes, bytes]: ... + @overload + def encrypt_and_digest(self, + plaintext: Buffer, + output: Buffer) -> Tuple[None, bytes]: ... + def decrypt_and_verify(self, + ciphertext: Buffer, + received_mac_tag: Buffer, + output: Optional[Union[bytearray, memoryview]] = ...) -> bytes: ... diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ecb.py b/frozen_deps/Cryptodome/Cipher/_mode_ecb.py new file mode 100644 index 0000000..4c381f7 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_ecb.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +# +# Cipher/mode_ecb.py : ECB mode +# +# =================================================================== +# 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. +# =================================================================== + +""" +Electronic Code Book (ECB) mode. +""" + +__all__ = [ 'EcbMode' ] + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, create_string_buffer, + get_raw_buffer, SmartPointer, + c_size_t, c_uint8_ptr, + is_writeable_buffer) + +raw_ecb_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_ecb", """ + int ECB_start_operation(void *cipher, + void **pResult); + int ECB_encrypt(void *ecbState, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int ECB_decrypt(void *ecbState, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int ECB_stop_operation(void *state); + """ + ) + + +class EcbMode(object): + """*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 is dangerous because it 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 + + :undocumented: __init__ + """ + + def __init__(self, block_cipher): + """Create a new block cipher, configured in ECB mode. + + :Parameters: + block_cipher : C pointer + A smart pointer to the low-level block cipher instance. + """ + + self._state = VoidPointer() + result = raw_ecb_lib.ECB_start_operation(block_cipher.get(), + self._state.address_of()) + if result: + raise ValueError("Error %d while instantiating the ECB mode" + % result) + + # Ensure that object disposal of this Python object will (eventually) + # free the memory allocated by the raw library for the cipher + # mode + self._state = SmartPointer(self._state.get(), + raw_ecb_lib.ECB_stop_operation) + + # Memory allocated for the underlying block cipher is now owned + # by the cipher mode + block_cipher.release() + + def encrypt(self, plaintext, output=None): + """Encrypt data with the key set at initialization. + + The data to encrypt can be broken up in two or + more pieces and `encrypt` can be called multiple times. + + That is, the statement: + + >>> c.encrypt(a) + c.encrypt(b) + + is equivalent to: + + >>> c.encrypt(a+b) + + This function does not add any padding to the plaintext. + + :Parameters: + plaintext : bytes/bytearray/memoryview + The piece of data to encrypt. + The length must be multiple of the cipher block length. + :Keywords: + output : bytearray/memoryview + The location where the ciphertext must be written to. + If ``None``, the ciphertext is returned. + :Return: + If ``output`` is ``None``, the ciphertext is returned as ``bytes``. + Otherwise, ``None``. + """ + + if output is None: + ciphertext = create_string_buffer(len(plaintext)) + else: + ciphertext = output + + if not is_writeable_buffer(output): + raise TypeError("output must be a bytearray or a writeable memoryview") + + if len(plaintext) != len(output): + raise ValueError("output must have the same length as the input" + " (%d bytes)" % len(plaintext)) + + result = raw_ecb_lib.ECB_encrypt(self._state.get(), + c_uint8_ptr(plaintext), + c_uint8_ptr(ciphertext), + c_size_t(len(plaintext))) + if result: + if result == 3: + raise ValueError("Data must be aligned to block boundary in ECB mode") + raise ValueError("Error %d while encrypting in ECB mode" % result) + + if output is None: + return get_raw_buffer(ciphertext) + else: + return None + + def decrypt(self, ciphertext, output=None): + """Decrypt data with the key set at initialization. + + The data to decrypt can be broken up in two or + more pieces and `decrypt` can be called multiple times. + + That is, the statement: + + >>> c.decrypt(a) + c.decrypt(b) + + is equivalent to: + + >>> c.decrypt(a+b) + + This function does not remove any padding from the plaintext. + + :Parameters: + ciphertext : bytes/bytearray/memoryview + The piece of data to decrypt. + The length must be multiple of the cipher block length. + :Keywords: + output : bytearray/memoryview + The location where the plaintext must be written to. + If ``None``, the plaintext is returned. + :Return: + If ``output`` is ``None``, the plaintext is returned as ``bytes``. + Otherwise, ``None``. + """ + + if output is None: + plaintext = create_string_buffer(len(ciphertext)) + else: + plaintext = output + + if not is_writeable_buffer(output): + raise TypeError("output must be a bytearray or a writeable memoryview") + + if len(ciphertext) != len(output): + raise ValueError("output must have the same length as the input" + " (%d bytes)" % len(plaintext)) + + result = raw_ecb_lib.ECB_decrypt(self._state.get(), + c_uint8_ptr(ciphertext), + c_uint8_ptr(plaintext), + c_size_t(len(ciphertext))) + if result: + if result == 3: + raise ValueError("Data must be aligned to block boundary in ECB mode") + raise ValueError("Error %d while decrypting in ECB mode" % result) + + if output is None: + return get_raw_buffer(plaintext) + else: + return None + + +def _create_ecb_cipher(factory, **kwargs): + """Instantiate a cipher object that performs ECB encryption/decryption. + + :Parameters: + factory : module + The underlying block cipher, a module from ``Cryptodome.Cipher``. + + All keywords are passed to the underlying block cipher. + See the relevant documentation for details (at least ``key`` will need + to be present""" + + cipher_state = factory._create_base_cipher(kwargs) + if kwargs: + raise TypeError("Unknown parameters for ECB: %s" % str(kwargs)) + return EcbMode(cipher_state) diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ecb.pyi b/frozen_deps/Cryptodome/Cipher/_mode_ecb.pyi new file mode 100644 index 0000000..936195f --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_ecb.pyi @@ -0,0 +1,19 @@ +from typing import Union, overload + +from Cryptodome.Util._raw_api import SmartPointer + +Buffer = Union[bytes, bytearray, memoryview] + +__all__ = [ 'EcbMode' ] + +class EcbMode(object): + def __init__(self, block_cipher: SmartPointer) -> None: ... + @overload + def encrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + @overload + def decrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + diff --git a/frozen_deps/Cryptodome/Cipher/_mode_gcm.py b/frozen_deps/Cryptodome/Cipher/_mode_gcm.py new file mode 100644 index 0000000..c90061b --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_gcm.py @@ -0,0 +1,620 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +""" +Galois/Counter Mode (GCM). +""" + +__all__ = ['GcmMode'] + +from binascii import unhexlify + +from Cryptodome.Util.py3compat import bord, _copy_bytes + +from Cryptodome.Util._raw_api import is_buffer + +from Cryptodome.Util.number import long_to_bytes, bytes_to_long +from Cryptodome.Hash import BLAKE2s +from Cryptodome.Random import get_random_bytes + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer, + create_string_buffer, get_raw_buffer, + SmartPointer, c_size_t, c_uint8_ptr) + +from Cryptodome.Util import _cpu_features + + +# C API by module implementing GHASH +_ghash_api_template = """ + int ghash_%imp%(uint8_t y_out[16], + const uint8_t block_data[], + size_t len, + const uint8_t y_in[16], + const void *exp_key); + int ghash_expand_%imp%(const uint8_t h[16], + void **ghash_tables); + int ghash_destroy_%imp%(void *ghash_tables); +""" + +def _build_impl(lib, postfix): + from collections import namedtuple + + funcs = ( "ghash", "ghash_expand", "ghash_destroy" ) + GHASH_Imp = namedtuple('_GHash_Imp', funcs) + try: + imp_funcs = [ getattr(lib, x + "_" + postfix) for x in funcs ] + except AttributeError: # Make sphinx stop complaining with its mocklib + imp_funcs = [ None ] * 3 + params = dict(zip(funcs, imp_funcs)) + return GHASH_Imp(**params) + + +def _get_ghash_portable(): + api = _ghash_api_template.replace("%imp%", "portable") + lib = load_pycryptodome_raw_lib("Cryptodome.Hash._ghash_portable", api) + result = _build_impl(lib, "portable") + return result +_ghash_portable = _get_ghash_portable() + + +def _get_ghash_clmul(): + """Return None if CLMUL implementation is not available""" + + if not _cpu_features.have_clmul(): + return None + try: + api = _ghash_api_template.replace("%imp%", "clmul") + lib = load_pycryptodome_raw_lib("Cryptodome.Hash._ghash_clmul", api) + result = _build_impl(lib, "clmul") + except OSError: + result = None + return result +_ghash_clmul = _get_ghash_clmul() + + +class _GHASH(object): + """GHASH function defined in NIST SP 800-38D, Algorithm 2. + + If X_1, X_2, .. X_m are the blocks of input data, the function + computes: + + X_1*H^{m} + X_2*H^{m-1} + ... + X_m*H + + in the Galois field GF(2^256) using the reducing polynomial + (x^128 + x^7 + x^2 + x + 1). + """ + + def __init__(self, subkey, ghash_c): + assert len(subkey) == 16 + + self.ghash_c = ghash_c + + self._exp_key = VoidPointer() + result = ghash_c.ghash_expand(c_uint8_ptr(subkey), + self._exp_key.address_of()) + if result: + raise ValueError("Error %d while expanding the GHASH key" % result) + + self._exp_key = SmartPointer(self._exp_key.get(), + ghash_c.ghash_destroy) + + # create_string_buffer always returns a string of zeroes + self._last_y = create_string_buffer(16) + + def update(self, block_data): + assert len(block_data) % 16 == 0 + + result = self.ghash_c.ghash(self._last_y, + c_uint8_ptr(block_data), + c_size_t(len(block_data)), + self._last_y, + self._exp_key.get()) + if result: + raise ValueError("Error %d while updating GHASH" % result) + + return self + + def digest(self): + return get_raw_buffer(self._last_y) + + +def enum(**enums): + return type('Enum', (), enums) + + +MacStatus = enum(PROCESSING_AUTH_DATA=1, PROCESSING_CIPHERTEXT=2) + + +class GcmMode(object): + """Galois Counter Mode (GCM). + + This is an Authenticated Encryption with Associated Data (`AEAD`_) mode. + It provides both confidentiality and authenticity. + + The header of the message may be left in the clear, if needed, and it will + still be subject to authentication. The decryption step tells the receiver + if the message comes from a source that really knowns the secret key. + Additionally, decryption detects if any part of the message - including the + header - has been modified or corrupted. + + This mode requires a *nonce*. + + This mode is only available for ciphers that operate on 128 bits blocks + (e.g. AES but not TDES). + + See `NIST SP800-38D`_. + + .. _`NIST SP800-38D`: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf + .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html + + :undocumented: __init__ + """ + + def __init__(self, factory, key, nonce, mac_len, cipher_params, ghash_c): + + self.block_size = factory.block_size + if self.block_size != 16: + raise ValueError("GCM mode is only available for ciphers" + " that operate on 128 bits blocks") + + if len(nonce) == 0: + raise ValueError("Nonce cannot be empty") + + if not is_buffer(nonce): + raise TypeError("Nonce must be bytes, bytearray or memoryview") + + # See NIST SP 800 38D, 5.2.1.1 + if len(nonce) > 2**64 - 1: + raise ValueError("Nonce exceeds maximum length") + + + self.nonce = _copy_bytes(None, None, nonce) + """Nonce""" + + self._factory = factory + self._key = _copy_bytes(None, None, key) + self._tag = None # Cache for MAC tag + + self._mac_len = mac_len + if not (4 <= mac_len <= 16): + raise ValueError("Parameter 'mac_len' must be in the range 4..16") + + # Allowed transitions after initialization + self._next = [self.update, self.encrypt, self.decrypt, + self.digest, self.verify] + + self._no_more_assoc_data = False + + # Length of associated data + self._auth_len = 0 + + # Length of the ciphertext or plaintext + self._msg_len = 0 + + # Step 1 in SP800-38D, Algorithm 4 (encryption) - Compute H + # See also Algorithm 5 (decryption) + hash_subkey = factory.new(key, + self._factory.MODE_ECB, + **cipher_params + ).encrypt(b'\x00' * 16) + + # Step 2 - Compute J0 + if len(self.nonce) == 12: + j0 = self.nonce + b"\x00\x00\x00\x01" + else: + fill = (16 - (len(nonce) % 16)) % 16 + 8 + ghash_in = (self.nonce + + b'\x00' * fill + + long_to_bytes(8 * len(nonce), 8)) + j0 = _GHASH(hash_subkey, ghash_c).update(ghash_in).digest() + + # Step 3 - Prepare GCTR cipher for encryption/decryption + nonce_ctr = j0[:12] + iv_ctr = (bytes_to_long(j0) + 1) & 0xFFFFFFFF + self._cipher = factory.new(key, + self._factory.MODE_CTR, + initial_value=iv_ctr, + nonce=nonce_ctr, + **cipher_params) + + # Step 5 - Bootstrat GHASH + self._signer = _GHASH(hash_subkey, ghash_c) + + # Step 6 - Prepare GCTR cipher for GMAC + self._tag_cipher = factory.new(key, + self._factory.MODE_CTR, + initial_value=j0, + nonce=b"", + **cipher_params) + + # Cache for data to authenticate + self._cache = b"" + + self._status = MacStatus.PROCESSING_AUTH_DATA + + def update(self, assoc_data): + """Protect associated data + + If there is any associated data, the caller has to invoke + this function one or more times, before using + ``decrypt`` or ``encrypt``. + + By *associated data* it is meant any data (e.g. packet headers) that + will not be encrypted and will be transmitted in the clear. + However, the receiver is still able to detect any modification to it. + In GCM, the *associated data* is also called + *additional authenticated data* (AAD). + + If there is no associated data, this method must not be called. + + The caller may split associated data in segments of any size, and + invoke this method multiple times, each time with the next segment. + + :Parameters: + assoc_data : bytes/bytearray/memoryview + A piece of associated data. There are no restrictions on its size. + """ + + if self.update not in self._next: + raise TypeError("update() can only be called" + " immediately after initialization") + + self._next = [self.update, self.encrypt, self.decrypt, + self.digest, self.verify] + + self._update(assoc_data) + self._auth_len += len(assoc_data) + + # See NIST SP 800 38D, 5.2.1.1 + if self._auth_len > 2**64 - 1: + raise ValueError("Additional Authenticated Data exceeds maximum length") + + return self + + def _update(self, data): + assert(len(self._cache) < 16) + + if len(self._cache) > 0: + filler = min(16 - len(self._cache), len(data)) + self._cache += _copy_bytes(None, filler, data) + data = data[filler:] + + if len(self._cache) < 16: + return + + # The cache is exactly one block + self._signer.update(self._cache) + self._cache = b"" + + update_len = len(data) // 16 * 16 + self._cache = _copy_bytes(update_len, None, data) + if update_len > 0: + self._signer.update(data[:update_len]) + + def _pad_cache_and_update(self): + assert(len(self._cache) < 16) + + # The authenticated data A is concatenated to the minimum + # number of zero bytes (possibly none) such that the + # - ciphertext C is aligned to the 16 byte boundary. + # See step 5 in section 7.1 + # - ciphertext C is aligned to the 16 byte boundary. + # See step 6 in section 7.2 + len_cache = len(self._cache) + if len_cache > 0: + self._update(b'\x00' * (16 - len_cache)) + + def encrypt(self, plaintext, output=None): + """Encrypt data with the key and the parameters set at initialization. + + A cipher object is stateful: once you have encrypted a message + you cannot encrypt (or decrypt) another message using the same + object. + + The data to encrypt can be broken up in two or + more pieces and `encrypt` can be called multiple times. + + That is, the statement: + + >>> c.encrypt(a) + c.encrypt(b) + + is equivalent to: + + >>> c.encrypt(a+b) + + This function does not add any padding to the plaintext. + + :Parameters: + plaintext : bytes/bytearray/memoryview + The piece of data to encrypt. + It can be of any length. + :Keywords: + output : bytearray/memoryview + The location where the ciphertext must be written to. + If ``None``, the ciphertext is returned. + :Return: + If ``output`` is ``None``, the ciphertext as ``bytes``. + Otherwise, ``None``. + """ + + if self.encrypt not in self._next: + raise TypeError("encrypt() can only be called after" + " initialization or an update()") + self._next = [self.encrypt, self.digest] + + ciphertext = self._cipher.encrypt(plaintext, output=output) + + if self._status == MacStatus.PROCESSING_AUTH_DATA: + self._pad_cache_and_update() + self._status = MacStatus.PROCESSING_CIPHERTEXT + + self._update(ciphertext if output is None else output) + self._msg_len += len(plaintext) + + # See NIST SP 800 38D, 5.2.1.1 + if self._msg_len > 2**39 - 256: + raise ValueError("Plaintext exceeds maximum length") + + return ciphertext + + def decrypt(self, ciphertext, output=None): + """Decrypt data with the key and the parameters set at initialization. + + A cipher object is stateful: once you have decrypted a message + you cannot decrypt (or encrypt) another message with the same + object. + + The data to decrypt can be broken up in two or + more pieces and `decrypt` can be called multiple times. + + That is, the statement: + + >>> c.decrypt(a) + c.decrypt(b) + + is equivalent to: + + >>> c.decrypt(a+b) + + This function does not remove any padding from the plaintext. + + :Parameters: + ciphertext : bytes/bytearray/memoryview + The piece of data to decrypt. + It can be of any length. + :Keywords: + output : bytearray/memoryview + The location where the plaintext must be written to. + If ``None``, the plaintext is returned. + :Return: + If ``output`` is ``None``, the plaintext as ``bytes``. + Otherwise, ``None``. + """ + + if self.decrypt not in self._next: + raise TypeError("decrypt() can only be called" + " after initialization or an update()") + self._next = [self.decrypt, self.verify] + + if self._status == MacStatus.PROCESSING_AUTH_DATA: + self._pad_cache_and_update() + self._status = MacStatus.PROCESSING_CIPHERTEXT + + self._update(ciphertext) + self._msg_len += len(ciphertext) + + return self._cipher.decrypt(ciphertext, output=output) + + def digest(self): + """Compute the *binary* MAC tag in an AEAD mode. + + The caller invokes this function at the very end. + + This method returns the MAC that shall be sent to the receiver, + together with the ciphertext. + + :Return: the MAC, as a byte string. + """ + + if self.digest not in self._next: + raise TypeError("digest() cannot be called when decrypting" + " or validating a message") + self._next = [self.digest] + + return self._compute_mac() + + def _compute_mac(self): + """Compute MAC without any FSM checks.""" + + if self._tag: + return self._tag + + # Step 5 in NIST SP 800-38D, Algorithm 4 - Compute S + self._pad_cache_and_update() + self._update(long_to_bytes(8 * self._auth_len, 8)) + self._update(long_to_bytes(8 * self._msg_len, 8)) + s_tag = self._signer.digest() + + # Step 6 - Compute T + self._tag = self._tag_cipher.encrypt(s_tag)[:self._mac_len] + + return self._tag + + def hexdigest(self): + """Compute the *printable* MAC tag. + + This method is like `digest`. + + :Return: the MAC, as a hexadecimal string. + """ + return "".join(["%02x" % bord(x) for x in self.digest()]) + + def verify(self, received_mac_tag): + """Validate the *binary* MAC tag. + + The caller invokes this function at the very end. + + This method checks if the decrypted message is indeed valid + (that is, if the key is correct) and it has not been + tampered with while in transit. + + :Parameters: + received_mac_tag : bytes/bytearray/memoryview + This is the *binary* MAC, as received from the sender. + :Raises ValueError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + if self.verify not in self._next: + raise TypeError("verify() cannot be called" + " when encrypting a message") + self._next = [self.verify] + + secret = get_random_bytes(16) + + mac1 = BLAKE2s.new(digest_bits=160, key=secret, + data=self._compute_mac()) + mac2 = BLAKE2s.new(digest_bits=160, key=secret, + data=received_mac_tag) + + if mac1.digest() != mac2.digest(): + raise ValueError("MAC check failed") + + def hexverify(self, hex_mac_tag): + """Validate the *printable* MAC tag. + + This method is like `verify`. + + :Parameters: + hex_mac_tag : string + This is the *printable* MAC, as received from the sender. + :Raises ValueError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + self.verify(unhexlify(hex_mac_tag)) + + def encrypt_and_digest(self, plaintext, output=None): + """Perform encrypt() and digest() in one step. + + :Parameters: + plaintext : bytes/bytearray/memoryview + The piece of data to encrypt. + :Keywords: + output : bytearray/memoryview + The location where the ciphertext must be written to. + If ``None``, the ciphertext is returned. + :Return: + a tuple with two items: + + - the ciphertext, as ``bytes`` + - the MAC tag, as ``bytes`` + + The first item becomes ``None`` when the ``output`` parameter + specified a location for the result. + """ + + return self.encrypt(plaintext, output=output), self.digest() + + def decrypt_and_verify(self, ciphertext, received_mac_tag, output=None): + """Perform decrypt() and verify() in one step. + + :Parameters: + ciphertext : bytes/bytearray/memoryview + The piece of data to decrypt. + received_mac_tag : byte string + This is the *binary* MAC, as received from the sender. + :Keywords: + output : bytearray/memoryview + The location where the plaintext must be written to. + If ``None``, the plaintext is returned. + :Return: the plaintext as ``bytes`` or ``None`` when the ``output`` + parameter specified a location for the result. + :Raises ValueError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + plaintext = self.decrypt(ciphertext, output=output) + self.verify(received_mac_tag) + return plaintext + + +def _create_gcm_cipher(factory, **kwargs): + """Create a new block cipher, configured in Galois Counter Mode (GCM). + + :Parameters: + factory : module + A block cipher module, taken from `Cryptodome.Cipher`. + The cipher must have block length of 16 bytes. + GCM has been only defined for `Cryptodome.Cipher.AES`. + + :Keywords: + key : bytes/bytearray/memoryview + The secret key to use in the symmetric cipher. + It must be 16 (e.g. *AES-128*), 24 (e.g. *AES-192*) + or 32 (e.g. *AES-256*) bytes long. + + nonce : bytes/bytearray/memoryview + A value that must never be reused for any other encryption. + + There are no restrictions on its length, + but it is recommended to use at least 16 bytes. + + The nonce shall never repeat for two + different messages encrypted with the same key, + but it does not need to be random. + + If not provided, a 16 byte nonce will be randomly created. + + mac_len : integer + Length of the MAC, in bytes. + It must be no larger than 16 bytes (which is the default). + """ + + try: + key = kwargs.pop("key") + except KeyError as e: + raise TypeError("Missing parameter:" + str(e)) + + nonce = kwargs.pop("nonce", None) + if nonce is None: + nonce = get_random_bytes(16) + mac_len = kwargs.pop("mac_len", 16) + + # Not documented - only used for testing + use_clmul = kwargs.pop("use_clmul", True) + if use_clmul and _ghash_clmul: + ghash_c = _ghash_clmul + else: + ghash_c = _ghash_portable + + return GcmMode(factory, key, nonce, mac_len, kwargs, ghash_c) diff --git a/frozen_deps/Cryptodome/Cipher/_mode_gcm.pyi b/frozen_deps/Cryptodome/Cipher/_mode_gcm.pyi new file mode 100644 index 0000000..8912955 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_gcm.pyi @@ -0,0 +1,45 @@ +from types import ModuleType +from typing import Union, Tuple, Dict, overload, Optional + +__all__ = ['GcmMode'] + +Buffer = Union[bytes, bytearray, memoryview] + +class GcmMode(object): + block_size: int + nonce: Buffer + + def __init__(self, + factory: ModuleType, + key: Buffer, + nonce: Buffer, + mac_len: int, + cipher_params: Dict) -> None: ... + + def update(self, assoc_data: Buffer) -> GcmMode: ... + + @overload + def encrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + @overload + def decrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def verify(self, received_mac_tag: Buffer) -> None: ... + def hexverify(self, hex_mac_tag: str) -> None: ... + + @overload + def encrypt_and_digest(self, + plaintext: Buffer) -> Tuple[bytes, bytes]: ... + @overload + def encrypt_and_digest(self, + plaintext: Buffer, + output: Buffer) -> Tuple[None, bytes]: ... + def decrypt_and_verify(self, + ciphertext: Buffer, + received_mac_tag: Buffer, + output: Optional[Union[bytearray, memoryview]] = ...) -> bytes: ... diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ocb.py b/frozen_deps/Cryptodome/Cipher/_mode_ocb.py new file mode 100644 index 0000000..27c2797 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_ocb.py @@ -0,0 +1,525 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +""" +Offset Codebook (OCB) mode. + +OCB is Authenticated Encryption with Associated Data (AEAD) cipher mode +designed by Prof. Phillip Rogaway and specified in `RFC7253`_. + +The algorithm provides both authenticity and privacy, it is very efficient, +it uses only one key and it can be used in online mode (so that encryption +or decryption can start before the end of the message is available). + +This module implements the third and last variant of OCB (OCB3) and it only +works in combination with a 128-bit block symmetric cipher, like AES. + +OCB is patented in US but `free licenses`_ exist for software implementations +meant for non-military purposes. + +Example: + >>> from Cryptodome.Cipher import AES + >>> from Cryptodome.Random import get_random_bytes + >>> + >>> key = get_random_bytes(32) + >>> cipher = AES.new(key, AES.MODE_OCB) + >>> plaintext = b"Attack at dawn" + >>> ciphertext, mac = cipher.encrypt_and_digest(plaintext) + >>> # Deliver cipher.nonce, ciphertext and mac + ... + >>> cipher = AES.new(key, AES.MODE_OCB, nonce=nonce) + >>> try: + >>> plaintext = cipher.decrypt_and_verify(ciphertext, mac) + >>> except ValueError: + >>> print "Invalid message" + >>> else: + >>> print plaintext + +:undocumented: __package__ + +.. _RFC7253: http://www.rfc-editor.org/info/rfc7253 +.. _free licenses: http://web.cs.ucdavis.edu/~rogaway/ocb/license.htm +""" + +import struct +from binascii import unhexlify + +from Cryptodome.Util.py3compat import bord, _copy_bytes +from Cryptodome.Util.number import long_to_bytes, bytes_to_long +from Cryptodome.Util.strxor import strxor + +from Cryptodome.Hash import BLAKE2s +from Cryptodome.Random import get_random_bytes + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer, + create_string_buffer, get_raw_buffer, + SmartPointer, c_size_t, c_uint8_ptr, + is_buffer) + +_raw_ocb_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_ocb", """ + int OCB_start_operation(void *cipher, + const uint8_t *offset_0, + size_t offset_0_len, + void **pState); + int OCB_encrypt(void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int OCB_decrypt(void *state, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int OCB_update(void *state, + const uint8_t *in, + size_t data_len); + int OCB_digest(void *state, + uint8_t *tag, + size_t tag_len); + int OCB_stop_operation(void *state); + """) + + +class OcbMode(object): + """Offset Codebook (OCB) mode. + + :undocumented: __init__ + """ + + def __init__(self, factory, nonce, mac_len, cipher_params): + + if factory.block_size != 16: + raise ValueError("OCB mode is only available for ciphers" + " that operate on 128 bits blocks") + + self.block_size = 16 + """The block size of the underlying cipher, in bytes.""" + + self.nonce = _copy_bytes(None, None, nonce) + """Nonce used for this session.""" + if len(nonce) not in range(1, 16): + raise ValueError("Nonce must be at most 15 bytes long") + if not is_buffer(nonce): + raise TypeError("Nonce must be bytes, bytearray or memoryview") + + self._mac_len = mac_len + if not 8 <= mac_len <= 16: + raise ValueError("MAC tag must be between 8 and 16 bytes long") + + # Cache for MAC tag + self._mac_tag = None + + # Cache for unaligned associated data + self._cache_A = b"" + + # Cache for unaligned ciphertext/plaintext + self._cache_P = b"" + + # Allowed transitions after initialization + self._next = [self.update, self.encrypt, self.decrypt, + self.digest, self.verify] + + # Compute Offset_0 + params_without_key = dict(cipher_params) + key = params_without_key.pop("key") + nonce = (struct.pack('B', self._mac_len << 4 & 0xFF) + + b'\x00' * (14 - len(nonce)) + + b'\x01' + self.nonce) + + bottom_bits = bord(nonce[15]) & 0x3F # 6 bits, 0..63 + top_bits = bord(nonce[15]) & 0xC0 # 2 bits + + ktop_cipher = factory.new(key, + factory.MODE_ECB, + **params_without_key) + ktop = ktop_cipher.encrypt(struct.pack('15sB', + nonce[:15], + top_bits)) + + stretch = ktop + strxor(ktop[:8], ktop[1:9]) # 192 bits + offset_0 = long_to_bytes(bytes_to_long(stretch) >> + (64 - bottom_bits), 24)[8:] + + # Create low-level cipher instance + raw_cipher = factory._create_base_cipher(cipher_params) + if cipher_params: + raise TypeError("Unknown keywords: " + str(cipher_params)) + + self._state = VoidPointer() + result = _raw_ocb_lib.OCB_start_operation(raw_cipher.get(), + offset_0, + c_size_t(len(offset_0)), + self._state.address_of()) + if result: + raise ValueError("Error %d while instantiating the OCB mode" + % result) + + # Ensure that object disposal of this Python object will (eventually) + # free the memory allocated by the raw library for the cipher mode + self._state = SmartPointer(self._state.get(), + _raw_ocb_lib.OCB_stop_operation) + + # Memory allocated for the underlying block cipher is now owed + # by the cipher mode + raw_cipher.release() + + def _update(self, assoc_data, assoc_data_len): + result = _raw_ocb_lib.OCB_update(self._state.get(), + c_uint8_ptr(assoc_data), + c_size_t(assoc_data_len)) + if result: + raise ValueError("Error %d while computing MAC in OCB mode" % result) + + def update(self, assoc_data): + """Process the associated data. + + If there is any associated data, the caller has to invoke + this method one or more times, before using + ``decrypt`` or ``encrypt``. + + By *associated data* it is meant any data (e.g. packet headers) that + will not be encrypted and will be transmitted in the clear. + However, the receiver shall still able to detect modifications. + + If there is no associated data, this method must not be called. + + The caller may split associated data in segments of any size, and + invoke this method multiple times, each time with the next segment. + + :Parameters: + assoc_data : bytes/bytearray/memoryview + A piece of associated data. + """ + + if self.update not in self._next: + raise TypeError("update() can only be called" + " immediately after initialization") + + self._next = [self.encrypt, self.decrypt, self.digest, + self.verify, self.update] + + if len(self._cache_A) > 0: + filler = min(16 - len(self._cache_A), len(assoc_data)) + self._cache_A += _copy_bytes(None, filler, assoc_data) + assoc_data = assoc_data[filler:] + + if len(self._cache_A) < 16: + return self + + # Clear the cache, and proceeding with any other aligned data + self._cache_A, seg = b"", self._cache_A + self.update(seg) + + update_len = len(assoc_data) // 16 * 16 + self._cache_A = _copy_bytes(update_len, None, assoc_data) + self._update(assoc_data, update_len) + return self + + def _transcrypt_aligned(self, in_data, in_data_len, + trans_func, trans_desc): + + out_data = create_string_buffer(in_data_len) + result = trans_func(self._state.get(), + in_data, + out_data, + c_size_t(in_data_len)) + if result: + raise ValueError("Error %d while %sing in OCB mode" + % (result, trans_desc)) + return get_raw_buffer(out_data) + + def _transcrypt(self, in_data, trans_func, trans_desc): + # Last piece to encrypt/decrypt + if in_data is None: + out_data = self._transcrypt_aligned(self._cache_P, + len(self._cache_P), + trans_func, + trans_desc) + self._cache_P = b"" + return out_data + + # Try to fill up the cache, if it already contains something + prefix = b"" + if len(self._cache_P) > 0: + filler = min(16 - len(self._cache_P), len(in_data)) + self._cache_P += _copy_bytes(None, filler, in_data) + in_data = in_data[filler:] + + if len(self._cache_P) < 16: + # We could not manage to fill the cache, so there is certainly + # no output yet. + return b"" + + # Clear the cache, and proceeding with any other aligned data + prefix = self._transcrypt_aligned(self._cache_P, + len(self._cache_P), + trans_func, + trans_desc) + self._cache_P = b"" + + # Process data in multiples of the block size + trans_len = len(in_data) // 16 * 16 + result = self._transcrypt_aligned(c_uint8_ptr(in_data), + trans_len, + trans_func, + trans_desc) + if prefix: + result = prefix + result + + # Left-over + self._cache_P = _copy_bytes(trans_len, None, in_data) + + return result + + def encrypt(self, plaintext=None): + """Encrypt the next piece of plaintext. + + After the entire plaintext has been passed (but before `digest`), + you **must** call this method one last time with no arguments to collect + the final piece of ciphertext. + + If possible, use the method `encrypt_and_digest` instead. + + :Parameters: + plaintext : bytes/bytearray/memoryview + The next piece of data to encrypt or ``None`` to signify + that encryption has finished and that any remaining ciphertext + has to be produced. + :Return: + the ciphertext, as a byte string. + Its length may not match the length of the *plaintext*. + """ + + if self.encrypt not in self._next: + raise TypeError("encrypt() can only be called after" + " initialization or an update()") + + if plaintext is None: + self._next = [self.digest] + else: + self._next = [self.encrypt] + return self._transcrypt(plaintext, _raw_ocb_lib.OCB_encrypt, "encrypt") + + def decrypt(self, ciphertext=None): + """Decrypt the next piece of ciphertext. + + After the entire ciphertext has been passed (but before `verify`), + you **must** call this method one last time with no arguments to collect + the remaining piece of plaintext. + + If possible, use the method `decrypt_and_verify` instead. + + :Parameters: + ciphertext : bytes/bytearray/memoryview + The next piece of data to decrypt or ``None`` to signify + that decryption has finished and that any remaining plaintext + has to be produced. + :Return: + the plaintext, as a byte string. + Its length may not match the length of the *ciphertext*. + """ + + if self.decrypt not in self._next: + raise TypeError("decrypt() can only be called after" + " initialization or an update()") + + if ciphertext is None: + self._next = [self.verify] + else: + self._next = [self.decrypt] + return self._transcrypt(ciphertext, + _raw_ocb_lib.OCB_decrypt, + "decrypt") + + def _compute_mac_tag(self): + + if self._mac_tag is not None: + return + + if self._cache_A: + self._update(self._cache_A, len(self._cache_A)) + self._cache_A = b"" + + mac_tag = create_string_buffer(16) + result = _raw_ocb_lib.OCB_digest(self._state.get(), + mac_tag, + c_size_t(len(mac_tag)) + ) + if result: + raise ValueError("Error %d while computing digest in OCB mode" + % result) + self._mac_tag = get_raw_buffer(mac_tag)[:self._mac_len] + + def digest(self): + """Compute the *binary* MAC tag. + + Call this method after the final `encrypt` (the one with no arguments) + to obtain the MAC tag. + + The MAC tag is needed by the receiver to determine authenticity + of the message. + + :Return: the MAC, as a byte string. + """ + + if self.digest not in self._next: + raise TypeError("digest() cannot be called now for this cipher") + + assert(len(self._cache_P) == 0) + + self._next = [self.digest] + + if self._mac_tag is None: + self._compute_mac_tag() + + return self._mac_tag + + def hexdigest(self): + """Compute the *printable* MAC tag. + + This method is like `digest`. + + :Return: the MAC, as a hexadecimal string. + """ + return "".join(["%02x" % bord(x) for x in self.digest()]) + + def verify(self, received_mac_tag): + """Validate the *binary* MAC tag. + + Call this method after the final `decrypt` (the one with no arguments) + to check if the message is authentic and valid. + + :Parameters: + received_mac_tag : bytes/bytearray/memoryview + This is the *binary* MAC, as received from the sender. + :Raises ValueError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + if self.verify not in self._next: + raise TypeError("verify() cannot be called now for this cipher") + + assert(len(self._cache_P) == 0) + + self._next = [self.verify] + + if self._mac_tag is None: + self._compute_mac_tag() + + secret = get_random_bytes(16) + mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=self._mac_tag) + mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=received_mac_tag) + + if mac1.digest() != mac2.digest(): + raise ValueError("MAC check failed") + + def hexverify(self, hex_mac_tag): + """Validate the *printable* MAC tag. + + This method is like `verify`. + + :Parameters: + hex_mac_tag : string + This is the *printable* MAC, as received from the sender. + :Raises ValueError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + self.verify(unhexlify(hex_mac_tag)) + + def encrypt_and_digest(self, plaintext): + """Encrypt the message and create the MAC tag in one step. + + :Parameters: + plaintext : bytes/bytearray/memoryview + The entire message to encrypt. + :Return: + a tuple with two byte strings: + + - the encrypted data + - the MAC + """ + + return self.encrypt(plaintext) + self.encrypt(), self.digest() + + def decrypt_and_verify(self, ciphertext, received_mac_tag): + """Decrypted the message and verify its authenticity in one step. + + :Parameters: + ciphertext : bytes/bytearray/memoryview + The entire message to decrypt. + received_mac_tag : byte string + This is the *binary* MAC, as received from the sender. + + :Return: the decrypted data (byte string). + :Raises ValueError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + plaintext = self.decrypt(ciphertext) + self.decrypt() + self.verify(received_mac_tag) + return plaintext + + +def _create_ocb_cipher(factory, **kwargs): + """Create a new block cipher, configured in OCB mode. + + :Parameters: + factory : module + A symmetric cipher module from `Cryptodome.Cipher` + (like `Cryptodome.Cipher.AES`). + + :Keywords: + nonce : bytes/bytearray/memoryview + A value that must never be reused for any other encryption. + Its length can vary from 1 to 15 bytes. + If not specified, a random 15 bytes long nonce is generated. + + mac_len : integer + Length of the MAC, in bytes. + It must be in the range ``[8..16]``. + The default is 16 (128 bits). + + Any other keyword will be passed to the underlying block cipher. + See the relevant documentation for details (at least ``key`` will need + to be present). + """ + + try: + nonce = kwargs.pop("nonce", None) + if nonce is None: + nonce = get_random_bytes(15) + mac_len = kwargs.pop("mac_len", 16) + except KeyError as e: + raise TypeError("Keyword missing: " + str(e)) + + return OcbMode(factory, nonce, mac_len, kwargs) diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ocb.pyi b/frozen_deps/Cryptodome/Cipher/_mode_ocb.pyi new file mode 100644 index 0000000..a1909fc --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_ocb.pyi @@ -0,0 +1,36 @@ +from types import ModuleType +from typing import Union, Any, Optional, Tuple, Dict, overload + +Buffer = Union[bytes, bytearray, memoryview] + +class OcbMode(object): + block_size: int + nonce: Buffer + + def __init__(self, + factory: ModuleType, + nonce: Buffer, + mac_len: int, + cipher_params: Dict) -> None: ... + + def update(self, assoc_data: Buffer) -> OcbMode: ... + + @overload + def encrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + @overload + def decrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def verify(self, received_mac_tag: Buffer) -> None: ... + def hexverify(self, hex_mac_tag: str) -> None: ... + + def encrypt_and_digest(self, + plaintext: Buffer) -> Tuple[bytes, bytes]: ... + def decrypt_and_verify(self, + ciphertext: Buffer, + received_mac_tag: Buffer) -> bytes: ... diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ofb.py b/frozen_deps/Cryptodome/Cipher/_mode_ofb.py new file mode 100644 index 0000000..04aaccf --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_ofb.py @@ -0,0 +1,282 @@ +# -*- coding: utf-8 -*- +# +# Cipher/mode_ofb.py : OFB mode +# +# =================================================================== +# 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. +# =================================================================== + +""" +Output Feedback (CFB) mode. +""" + +__all__ = ['OfbMode'] + +from Cryptodome.Util.py3compat import _copy_bytes +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer, + create_string_buffer, get_raw_buffer, + SmartPointer, c_size_t, c_uint8_ptr, + is_writeable_buffer) + +from Cryptodome.Random import get_random_bytes + +raw_ofb_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_ofb", """ + int OFB_start_operation(void *cipher, + const uint8_t iv[], + size_t iv_len, + void **pResult); + int OFB_encrypt(void *ofbState, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int OFB_decrypt(void *ofbState, + const uint8_t *in, + uint8_t *out, + size_t data_len); + int OFB_stop_operation(void *state); + """ + ) + + +class OfbMode(object): + """*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 the + previous ciphertext block. + + An Initialization Vector (*IV*) is required. + + See `NIST SP800-38A`_ , Section 6.4. + + .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + + :undocumented: __init__ + """ + + def __init__(self, block_cipher, iv): + """Create a new block cipher, configured in OFB mode. + + :Parameters: + block_cipher : C pointer + A smart pointer to the low-level block cipher instance. + + iv : bytes/bytearray/memoryview + The initialization vector to use for encryption or decryption. + It is as long as the cipher block. + + **The IV must be a nonce, to to be reused for any other + message**. It shall be a nonce or a random value. + + Reusing the *IV* for encryptions performed with the same key + compromises confidentiality. + """ + + self._state = VoidPointer() + result = raw_ofb_lib.OFB_start_operation(block_cipher.get(), + c_uint8_ptr(iv), + c_size_t(len(iv)), + self._state.address_of()) + if result: + raise ValueError("Error %d while instantiating the OFB mode" + % result) + + # Ensure that object disposal of this Python object will (eventually) + # free the memory allocated by the raw library for the cipher mode + self._state = SmartPointer(self._state.get(), + raw_ofb_lib.OFB_stop_operation) + + # Memory allocated for the underlying block cipher is now owed + # by the cipher mode + block_cipher.release() + + self.block_size = len(iv) + """The block size of the underlying cipher, in bytes.""" + + self.iv = _copy_bytes(None, None, iv) + """The Initialization Vector originally used to create the object. + The value does not change.""" + + self.IV = self.iv + """Alias for `iv`""" + + self._next = [ self.encrypt, self.decrypt ] + + def encrypt(self, plaintext, output=None): + """Encrypt data with the key and the parameters set at initialization. + + A cipher object is stateful: once you have encrypted a message + you cannot encrypt (or decrypt) another message using the same + object. + + The data to encrypt can be broken up in two or + more pieces and `encrypt` can be called multiple times. + + That is, the statement: + + >>> c.encrypt(a) + c.encrypt(b) + + is equivalent to: + + >>> c.encrypt(a+b) + + This function does not add any padding to the plaintext. + + :Parameters: + plaintext : bytes/bytearray/memoryview + The piece of data to encrypt. + It can be of any length. + :Keywords: + output : bytearray/memoryview + The location where the ciphertext must be written to. + If ``None``, the ciphertext is returned. + :Return: + If ``output`` is ``None``, the ciphertext is returned as ``bytes``. + Otherwise, ``None``. + """ + + if self.encrypt not in self._next: + raise TypeError("encrypt() cannot be called after decrypt()") + self._next = [ self.encrypt ] + + if output is None: + ciphertext = create_string_buffer(len(plaintext)) + else: + ciphertext = output + + if not is_writeable_buffer(output): + raise TypeError("output must be a bytearray or a writeable memoryview") + + if len(plaintext) != len(output): + raise ValueError("output must have the same length as the input" + " (%d bytes)" % len(plaintext)) + + result = raw_ofb_lib.OFB_encrypt(self._state.get(), + c_uint8_ptr(plaintext), + c_uint8_ptr(ciphertext), + c_size_t(len(plaintext))) + if result: + raise ValueError("Error %d while encrypting in OFB mode" % result) + + if output is None: + return get_raw_buffer(ciphertext) + else: + return None + + def decrypt(self, ciphertext, output=None): + """Decrypt data with the key and the parameters set at initialization. + + A cipher object is stateful: once you have decrypted a message + you cannot decrypt (or encrypt) another message with the same + object. + + The data to decrypt can be broken up in two or + more pieces and `decrypt` can be called multiple times. + + That is, the statement: + + >>> c.decrypt(a) + c.decrypt(b) + + is equivalent to: + + >>> c.decrypt(a+b) + + This function does not remove any padding from the plaintext. + + :Parameters: + ciphertext : bytes/bytearray/memoryview + The piece of data to decrypt. + It can be of any length. + :Keywords: + output : bytearray/memoryview + The location where the plaintext is written to. + If ``None``, the plaintext is returned. + :Return: + If ``output`` is ``None``, the plaintext is returned as ``bytes``. + Otherwise, ``None``. + """ + + if self.decrypt not in self._next: + raise TypeError("decrypt() cannot be called after encrypt()") + self._next = [ self.decrypt ] + + if output is None: + plaintext = create_string_buffer(len(ciphertext)) + else: + plaintext = output + + if not is_writeable_buffer(output): + raise TypeError("output must be a bytearray or a writeable memoryview") + + if len(ciphertext) != len(output): + raise ValueError("output must have the same length as the input" + " (%d bytes)" % len(plaintext)) + + result = raw_ofb_lib.OFB_decrypt(self._state.get(), + c_uint8_ptr(ciphertext), + c_uint8_ptr(plaintext), + c_size_t(len(ciphertext))) + if result: + raise ValueError("Error %d while decrypting in OFB mode" % result) + + if output is None: + return get_raw_buffer(plaintext) + else: + return None + + +def _create_ofb_cipher(factory, **kwargs): + """Instantiate a cipher object that performs OFB encryption/decryption. + + :Parameters: + factory : module + The underlying block cipher, a module from ``Cryptodome.Cipher``. + + :Keywords: + iv : bytes/bytearray/memoryview + The IV to use for OFB. + + IV : bytes/bytearray/memoryview + Alias for ``iv``. + + Any other keyword will be passed to the underlying block cipher. + See the relevant documentation for details (at least ``key`` will need + to be present). + """ + + cipher_state = factory._create_base_cipher(kwargs) + iv = kwargs.pop("IV", None) + IV = kwargs.pop("iv", None) + + if (None, None) == (iv, IV): + iv = get_random_bytes(factory.block_size) + if iv is not None: + if IV is not None: + raise TypeError("You must either use 'iv' or 'IV', not both") + else: + iv = IV + + if len(iv) != factory.block_size: + raise ValueError("Incorrect IV length (it must be %d bytes long)" % + factory.block_size) + + if kwargs: + raise TypeError("Unknown parameters for OFB: %s" % str(kwargs)) + + return OfbMode(cipher_state, iv) diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ofb.pyi b/frozen_deps/Cryptodome/Cipher/_mode_ofb.pyi new file mode 100644 index 0000000..d28608e --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_ofb.pyi @@ -0,0 +1,25 @@ +from typing import Union, overload + +from Cryptodome.Util._raw_api import SmartPointer + +Buffer = Union[bytes, bytearray, memoryview] + +__all__ = ['OfbMode'] + +class OfbMode(object): + block_size: int + iv: Buffer + IV: Buffer + + def __init__(self, + block_cipher: SmartPointer, + iv: Buffer) -> None: ... + @overload + def encrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + @overload + def decrypt(self, plaintext: Buffer) -> bytes: ... + @overload + def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ... + diff --git a/frozen_deps/Cryptodome/Cipher/_mode_openpgp.py b/frozen_deps/Cryptodome/Cipher/_mode_openpgp.py new file mode 100644 index 0000000..d86ed19 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_openpgp.py @@ -0,0 +1,206 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +""" +OpenPGP mode. +""" + +__all__ = ['OpenPgpMode'] + +from Cryptodome.Util.py3compat import _copy_bytes +from Cryptodome.Random import get_random_bytes + +class OpenPgpMode(object): + """OpenPGP mode. + + This mode is a variant of CFB, and it is only used in PGP and + OpenPGP_ applications. If in doubt, use another mode. + + An Initialization Vector (*IV*) is required. + + Unlike CFB, the *encrypted* IV (not the IV itself) is + transmitted to the receiver. + + The IV is a random data block. For legacy reasons, two of its bytes are + duplicated to act as a checksum for the correctness of the key, which is now + known to be insecure and is ignored. The encrypted IV is therefore 2 bytes + longer than the clean IV. + + .. _OpenPGP: http://tools.ietf.org/html/rfc4880 + + :undocumented: __init__ + """ + + def __init__(self, factory, key, iv, cipher_params): + + #: The block size of the underlying cipher, in bytes. + self.block_size = factory.block_size + + self._done_first_block = False # True after the first encryption + + # Instantiate a temporary cipher to process the IV + IV_cipher = factory.new( + key, + factory.MODE_CFB, + IV=b'\x00' * self.block_size, + segment_size=self.block_size * 8, + **cipher_params) + + iv = _copy_bytes(None, None, iv) + + # The cipher will be used for... + if len(iv) == self.block_size: + # ... encryption + self._encrypted_IV = IV_cipher.encrypt(iv + iv[-2:]) + elif len(iv) == self.block_size + 2: + # ... decryption + self._encrypted_IV = iv + # Last two bytes are for a deprecated "quick check" feature that + # should not be used. (https://eprint.iacr.org/2005/033) + iv = IV_cipher.decrypt(iv)[:-2] + else: + raise ValueError("Length of IV must be %d or %d bytes" + " for MODE_OPENPGP" + % (self.block_size, self.block_size + 2)) + + self.iv = self.IV = iv + + # Instantiate the cipher for the real PGP data + self._cipher = factory.new( + key, + factory.MODE_CFB, + IV=self._encrypted_IV[-self.block_size:], + segment_size=self.block_size * 8, + **cipher_params) + + def encrypt(self, plaintext): + """Encrypt data with the key and the parameters set at initialization. + + A cipher object is stateful: once you have encrypted a message + you cannot encrypt (or decrypt) another message using the same + object. + + The data to encrypt can be broken up in two or + more pieces and `encrypt` can be called multiple times. + + That is, the statement: + + >>> c.encrypt(a) + c.encrypt(b) + + is equivalent to: + + >>> c.encrypt(a+b) + + This function does not add any padding to the plaintext. + + :Parameters: + plaintext : bytes/bytearray/memoryview + 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, + the encypted IV is prepended to the returned ciphertext. + """ + + res = self._cipher.encrypt(plaintext) + if not self._done_first_block: + res = self._encrypted_IV + res + self._done_first_block = True + return res + + def decrypt(self, ciphertext): + """Decrypt data with the key and the parameters set at initialization. + + A cipher object is stateful: once you have decrypted a message + you cannot decrypt (or encrypt) another message with the same + object. + + The data to decrypt can be broken up in two or + more pieces and `decrypt` can be called multiple times. + + That is, the statement: + + >>> c.decrypt(a) + c.decrypt(b) + + is equivalent to: + + >>> c.decrypt(a+b) + + This function does not remove any padding from the plaintext. + + :Parameters: + ciphertext : bytes/bytearray/memoryview + The piece of data to decrypt. + + :Return: the decrypted data (byte string). + """ + + return self._cipher.decrypt(ciphertext) + + +def _create_openpgp_cipher(factory, **kwargs): + """Create a new block cipher, configured in OpenPGP mode. + + :Parameters: + factory : module + The module. + + :Keywords: + key : bytes/bytearray/memoryview + The secret key to use in the symmetric cipher. + + IV : bytes/bytearray/memoryview + The initialization vector to use for encryption or decryption. + + For encryption, the IV must be as long as the cipher block size. + + For decryption, it must be 2 bytes longer (it is actually the + *encrypted* IV which was prefixed to the ciphertext). + """ + + iv = kwargs.pop("IV", None) + IV = kwargs.pop("iv", None) + + if (None, None) == (iv, IV): + iv = get_random_bytes(factory.block_size) + if iv is not None: + if IV is not None: + raise TypeError("You must either use 'iv' or 'IV', not both") + else: + iv = IV + + try: + key = kwargs.pop("key") + except KeyError as e: + raise TypeError("Missing component: " + str(e)) + + return OpenPgpMode(factory, key, iv, kwargs) diff --git a/frozen_deps/Cryptodome/Cipher/_mode_openpgp.pyi b/frozen_deps/Cryptodome/Cipher/_mode_openpgp.pyi new file mode 100644 index 0000000..14b8105 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_openpgp.pyi @@ -0,0 +1,20 @@ +from types import ModuleType +from typing import Union, Dict + +Buffer = Union[bytes, bytearray, memoryview] + +__all__ = ['OpenPgpMode'] + +class OpenPgpMode(object): + block_size: int + iv: Union[bytes, bytearray, memoryview] + IV: Union[bytes, bytearray, memoryview] + + def __init__(self, + factory: ModuleType, + key: Buffer, + iv: Buffer, + cipher_params: Dict) -> None: ... + def encrypt(self, plaintext: Buffer) -> bytes: ... + def decrypt(self, plaintext: Buffer) -> bytes: ... + diff --git a/frozen_deps/Cryptodome/Cipher/_mode_siv.py b/frozen_deps/Cryptodome/Cipher/_mode_siv.py new file mode 100644 index 0000000..d10c4dc --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_siv.py @@ -0,0 +1,392 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +""" +Synthetic Initialization Vector (SIV) mode. +""" + +__all__ = ['SivMode'] + +from binascii import hexlify, unhexlify + +from Cryptodome.Util.py3compat import bord, _copy_bytes + +from Cryptodome.Util._raw_api import is_buffer + +from Cryptodome.Util.number import long_to_bytes, bytes_to_long +from Cryptodome.Protocol.KDF import _S2V +from Cryptodome.Hash import BLAKE2s +from Cryptodome.Random import get_random_bytes + + +class SivMode(object): + """Synthetic Initialization Vector (SIV). + + This is an Authenticated Encryption with Associated Data (`AEAD`_) mode. + It provides both confidentiality and authenticity. + + The header of the message may be left in the clear, if needed, and it will + still be subject to authentication. The decryption step tells the receiver + if the message comes from a source that really knowns the secret key. + Additionally, decryption detects if any part of the message - including the + header - has been modified or corrupted. + + Unlike other AEAD modes such as CCM, EAX or GCM, accidental reuse of a + nonce is not catastrophic for the confidentiality of the message. The only + effect is that an attacker can tell when the same plaintext (and same + associated data) is protected with the same key. + + The length of the MAC is fixed to the block size of the underlying cipher. + The key size is twice the length of the key of the underlying cipher. + + This mode is only available for AES ciphers. + + +--------------------+---------------+-------------------+ + | Cipher | SIV MAC size | SIV key length | + | | (bytes) | (bytes) | + +====================+===============+===================+ + | AES-128 | 16 | 32 | + +--------------------+---------------+-------------------+ + | AES-192 | 16 | 48 | + +--------------------+---------------+-------------------+ + | AES-256 | 16 | 64 | + +--------------------+---------------+-------------------+ + + See `RFC5297`_ and the `original paper`__. + + .. _RFC5297: https://tools.ietf.org/html/rfc5297 + .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html + .. __: http://www.cs.ucdavis.edu/~rogaway/papers/keywrap.pdf + + :undocumented: __init__ + """ + + def __init__(self, factory, key, nonce, kwargs): + + self.block_size = factory.block_size + """The block size of the underlying cipher, in bytes.""" + + self._factory = factory + + self._cipher_params = kwargs + + if len(key) not in (32, 48, 64): + raise ValueError("Incorrect key length (%d bytes)" % len(key)) + + if nonce is not None: + if not is_buffer(nonce): + raise TypeError("When provided, the nonce must be bytes, bytearray or memoryview") + + if len(nonce) == 0: + raise ValueError("When provided, the nonce must be non-empty") + + self.nonce = _copy_bytes(None, None, nonce) + """Public attribute is only available in case of non-deterministic + encryption.""" + + subkey_size = len(key) // 2 + + self._mac_tag = None # Cache for MAC tag + self._kdf = _S2V(key[:subkey_size], + ciphermod=factory, + cipher_params=self._cipher_params) + self._subkey_cipher = key[subkey_size:] + + # Purely for the purpose of verifying that cipher_params are OK + factory.new(key[:subkey_size], factory.MODE_ECB, **kwargs) + + # Allowed transitions after initialization + self._next = [self.update, self.encrypt, self.decrypt, + self.digest, self.verify] + + def _create_ctr_cipher(self, v): + """Create a new CTR cipher from V in SIV mode""" + + v_int = bytes_to_long(v) + q = v_int & 0xFFFFFFFFFFFFFFFF7FFFFFFF7FFFFFFF + return self._factory.new( + self._subkey_cipher, + self._factory.MODE_CTR, + initial_value=q, + nonce=b"", + **self._cipher_params) + + def update(self, component): + """Protect one associated data component + + For SIV, the associated data is a sequence (*vector*) of non-empty + byte strings (*components*). + + This method consumes the next component. It must be called + once for each of the components that constitue the associated data. + + Note that the components have clear boundaries, so that: + + >>> cipher.update(b"builtin") + >>> cipher.update(b"securely") + + is not equivalent to: + + >>> cipher.update(b"built") + >>> cipher.update(b"insecurely") + + If there is no associated data, this method must not be called. + + :Parameters: + component : bytes/bytearray/memoryview + The next associated data component. + """ + + if self.update not in self._next: + raise TypeError("update() can only be called" + " immediately after initialization") + + self._next = [self.update, self.encrypt, self.decrypt, + self.digest, self.verify] + + return self._kdf.update(component) + + def encrypt(self, plaintext): + """ + For SIV, encryption and MAC authentication must take place at the same + point. This method shall not be used. + + Use `encrypt_and_digest` instead. + """ + + raise TypeError("encrypt() not allowed for SIV mode." + " Use encrypt_and_digest() instead.") + + def decrypt(self, ciphertext): + """ + For SIV, decryption and verification must take place at the same + point. This method shall not be used. + + Use `decrypt_and_verify` instead. + """ + + raise TypeError("decrypt() not allowed for SIV mode." + " Use decrypt_and_verify() instead.") + + def digest(self): + """Compute the *binary* MAC tag. + + The caller invokes this function at the very end. + + This method returns the MAC that shall be sent to the receiver, + together with the ciphertext. + + :Return: the MAC, as a byte string. + """ + + if self.digest not in self._next: + raise TypeError("digest() cannot be called when decrypting" + " or validating a message") + self._next = [self.digest] + if self._mac_tag is None: + self._mac_tag = self._kdf.derive() + return self._mac_tag + + def hexdigest(self): + """Compute the *printable* MAC tag. + + This method is like `digest`. + + :Return: the MAC, as a hexadecimal string. + """ + return "".join(["%02x" % bord(x) for x in self.digest()]) + + def verify(self, received_mac_tag): + """Validate the *binary* MAC tag. + + The caller invokes this function at the very end. + + This method checks if the decrypted message is indeed valid + (that is, if the key is correct) and it has not been + tampered with while in transit. + + :Parameters: + received_mac_tag : bytes/bytearray/memoryview + This is the *binary* MAC, as received from the sender. + :Raises ValueError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + if self.verify not in self._next: + raise TypeError("verify() cannot be called" + " when encrypting a message") + self._next = [self.verify] + + if self._mac_tag is None: + self._mac_tag = self._kdf.derive() + + secret = get_random_bytes(16) + + mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=self._mac_tag) + mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=received_mac_tag) + + if mac1.digest() != mac2.digest(): + raise ValueError("MAC check failed") + + def hexverify(self, hex_mac_tag): + """Validate the *printable* MAC tag. + + This method is like `verify`. + + :Parameters: + hex_mac_tag : string + This is the *printable* MAC, as received from the sender. + :Raises ValueError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + self.verify(unhexlify(hex_mac_tag)) + + def encrypt_and_digest(self, plaintext, output=None): + """Perform encrypt() and digest() in one step. + + :Parameters: + plaintext : bytes/bytearray/memoryview + The piece of data to encrypt. + :Keywords: + output : bytearray/memoryview + The location where the ciphertext must be written to. + If ``None``, the ciphertext is returned. + :Return: + a tuple with two items: + + - the ciphertext, as ``bytes`` + - the MAC tag, as ``bytes`` + + The first item becomes ``None`` when the ``output`` parameter + specified a location for the result. + """ + + if self.encrypt not in self._next: + raise TypeError("encrypt() can only be called after" + " initialization or an update()") + + self._next = [ self.digest ] + + # Compute V (MAC) + if hasattr(self, 'nonce'): + self._kdf.update(self.nonce) + self._kdf.update(plaintext) + self._mac_tag = self._kdf.derive() + + cipher = self._create_ctr_cipher(self._mac_tag) + + return cipher.encrypt(plaintext, output=output), self._mac_tag + + def decrypt_and_verify(self, ciphertext, mac_tag, output=None): + """Perform decryption and verification in one step. + + A cipher object is stateful: once you have decrypted a message + you cannot decrypt (or encrypt) another message with the same + object. + + You cannot reuse an object for encrypting + or decrypting other data with the same key. + + This function does not remove any padding from the plaintext. + + :Parameters: + ciphertext : bytes/bytearray/memoryview + The piece of data to decrypt. + It can be of any length. + mac_tag : bytes/bytearray/memoryview + This is the *binary* MAC, as received from the sender. + :Keywords: + output : bytearray/memoryview + The location where the plaintext must be written to. + If ``None``, the plaintext is returned. + :Return: the plaintext as ``bytes`` or ``None`` when the ``output`` + parameter specified a location for the result. + :Raises ValueError: + if the MAC does not match. The message has been tampered with + or the key is incorrect. + """ + + if self.decrypt not in self._next: + raise TypeError("decrypt() can only be called" + " after initialization or an update()") + self._next = [ self.verify ] + + # Take the MAC and start the cipher for decryption + self._cipher = self._create_ctr_cipher(mac_tag) + + plaintext = self._cipher.decrypt(ciphertext, output=output) + + if hasattr(self, 'nonce'): + self._kdf.update(self.nonce) + self._kdf.update(plaintext if output is None else output) + self.verify(mac_tag) + + return plaintext + + +def _create_siv_cipher(factory, **kwargs): + """Create a new block cipher, configured in + Synthetic Initializaton Vector (SIV) mode. + + :Parameters: + + factory : object + A symmetric cipher module from `Cryptodome.Cipher` + (like `Cryptodome.Cipher.AES`). + + :Keywords: + + key : bytes/bytearray/memoryview + The secret key to use in the symmetric cipher. + It must be 32, 48 or 64 bytes long. + If AES is the chosen cipher, the variants *AES-128*, + *AES-192* and or *AES-256* will be used internally. + + nonce : bytes/bytearray/memoryview + For deterministic encryption, it is not present. + + Otherwise, it is a value that must never be reused + for encrypting message under this key. + + There are no restrictions on its length, + but it is recommended to use at least 16 bytes. + """ + + try: + key = kwargs.pop("key") + except KeyError as e: + raise TypeError("Missing parameter: " + str(e)) + + nonce = kwargs.pop("nonce", None) + + return SivMode(factory, key, nonce, kwargs) diff --git a/frozen_deps/Cryptodome/Cipher/_mode_siv.pyi b/frozen_deps/Cryptodome/Cipher/_mode_siv.pyi new file mode 100644 index 0000000..2934f23 --- /dev/null +++ b/frozen_deps/Cryptodome/Cipher/_mode_siv.pyi @@ -0,0 +1,38 @@ +from types import ModuleType +from typing import Union, Tuple, Dict, Optional, overload + +Buffer = Union[bytes, bytearray, memoryview] + +__all__ = ['SivMode'] + +class SivMode(object): + block_size: int + nonce: bytes + + def __init__(self, + factory: ModuleType, + key: Buffer, + nonce: Buffer, + kwargs: Dict) -> None: ... + + def update(self, component: Buffer) -> SivMode: ... + + def encrypt(self, plaintext: Buffer) -> bytes: ... + def decrypt(self, plaintext: Buffer) -> bytes: ... + + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def verify(self, received_mac_tag: Buffer) -> None: ... + def hexverify(self, hex_mac_tag: str) -> None: ... + + @overload + def encrypt_and_digest(self, + plaintext: Buffer) -> Tuple[bytes, bytes]: ... + @overload + def encrypt_and_digest(self, + plaintext: Buffer, + output: Buffer) -> Tuple[None, bytes]: ... + def decrypt_and_verify(self, + ciphertext: Buffer, + received_mac_tag: Buffer, + output: Optional[Union[bytearray, memoryview]] = ...) -> bytes: ... diff --git a/frozen_deps/Cryptodome/Cipher/_raw_aes.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_aes.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..e62f4d1 Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_raw_aes.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/_raw_aesni.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_aesni.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..b92e170 Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_raw_aesni.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/_raw_arc2.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_arc2.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..07a720a Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_raw_arc2.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/_raw_blowfish.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_blowfish.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..05abfd1 Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_raw_blowfish.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/_raw_cast.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_cast.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..2523fcb Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_raw_cast.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/_raw_cbc.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_cbc.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..1b013f3 Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_raw_cbc.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/_raw_cfb.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_cfb.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..6a28991 Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_raw_cfb.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/_raw_ctr.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_ctr.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..0529cf8 Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_raw_ctr.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/_raw_des.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_des.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..1d73854 Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_raw_des.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/_raw_des3.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_des3.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..8c4afa5 Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_raw_des3.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/_raw_ecb.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_ecb.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..0775c0b Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_raw_ecb.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/_raw_eksblowfish.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_eksblowfish.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..979fe63 Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_raw_eksblowfish.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/_raw_ocb.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_ocb.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..d545618 Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_raw_ocb.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Cipher/_raw_ofb.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_ofb.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..7157784 Binary files /dev/null and b/frozen_deps/Cryptodome/Cipher/_raw_ofb.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/BLAKE2b.py b/frozen_deps/Cryptodome/Hash/BLAKE2b.py new file mode 100644 index 0000000..d7e968f --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/BLAKE2b.py @@ -0,0 +1,247 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from binascii import unhexlify + +from Cryptodome.Util.py3compat import bord, tobytes + +from Cryptodome.Random import get_random_bytes +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +_raw_blake2b_lib = load_pycryptodome_raw_lib("Cryptodome.Hash._BLAKE2b", + """ + int blake2b_init(void **state, + const uint8_t *key, + size_t key_size, + size_t digest_size); + int blake2b_destroy(void *state); + int blake2b_update(void *state, + const uint8_t *buf, + size_t len); + int blake2b_digest(const void *state, + uint8_t digest[64]); + int blake2b_copy(const void *src, void *dst); + """) + + +class BLAKE2b_Hash(object): + """A BLAKE2b hash object. + Do not instantiate directly. Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + + :ivar block_size: the size in bytes of the internal message block, + input to the compression function + :vartype block_size: integer + + :ivar digest_size: the size in bytes of the resulting hash + :vartype digest_size: integer + """ + + # The internal block size of the hash algorithm in bytes. + block_size = 64 + + def __init__(self, data, key, digest_bytes, update_after_digest): + + # The size of the resulting hash in bytes. + self.digest_size = digest_bytes + + self._update_after_digest = update_after_digest + self._digest_done = False + + # See https://tools.ietf.org/html/rfc7693 + if digest_bytes in (20, 32, 48, 64) and not key: + self.oid = "1.3.6.1.4.1.1722.12.2.1." + str(digest_bytes) + + state = VoidPointer() + result = _raw_blake2b_lib.blake2b_init(state.address_of(), + c_uint8_ptr(key), + c_size_t(len(key)), + c_size_t(digest_bytes) + ) + if result: + raise ValueError("Error %d while instantiating BLAKE2b" % result) + self._state = SmartPointer(state.get(), + _raw_blake2b_lib.blake2b_destroy) + if data: + self.update(data) + + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (bytes/bytearray/memoryview): The next chunk of the message being hashed. + """ + + if self._digest_done and not self._update_after_digest: + raise TypeError("You can only call 'digest' or 'hexdigest' on this object") + + result = _raw_blake2b_lib.blake2b_update(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while hashing BLAKE2b data" % result) + return self + + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + bfr = create_string_buffer(64) + result = _raw_blake2b_lib.blake2b_digest(self._state.get(), + bfr) + if result: + raise ValueError("Error %d while creating BLAKE2b digest" % result) + + self._digest_done = True + + return get_raw_buffer(bfr)[:self.digest_size] + + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in tuple(self.digest())]) + + + def verify(self, mac_tag): + """Verify that a given **binary** MAC (computed by another party) + is valid. + + Args: + mac_tag (bytes/bytearray/memoryview): the expected MAC of the message. + + Raises: + ValueError: if the MAC does not match. It means that the message + has been tampered with or that the MAC key is incorrect. + """ + + secret = get_random_bytes(16) + + mac1 = new(digest_bits=160, key=secret, data=mac_tag) + mac2 = new(digest_bits=160, key=secret, data=self.digest()) + + if mac1.digest() != mac2.digest(): + raise ValueError("MAC check failed") + + + def hexverify(self, hex_mac_tag): + """Verify that a given **printable** MAC (computed by another party) + is valid. + + Args: + hex_mac_tag (string): the expected MAC of the message, as a hexadecimal string. + + Raises: + ValueError: if the MAC does not match. It means that the message + has been tampered with or that the MAC key is incorrect. + """ + + self.verify(unhexlify(tobytes(hex_mac_tag))) + + + def new(self, **kwargs): + """Return a new instance of a BLAKE2b hash object. + See :func:`new`. + """ + + if "digest_bytes" not in kwargs and "digest_bits" not in kwargs: + kwargs["digest_bytes"] = self.digest_size + + return new(**kwargs) + + +def new(**kwargs): + """Create a new hash object. + + Args: + data (bytes/bytearray/memoryview): + Optional. The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`BLAKE2b_Hash.update`. + digest_bytes (integer): + Optional. The size of the digest, in bytes (1 to 64). Default is 64. + digest_bits (integer): + Optional and alternative to ``digest_bytes``. + The size of the digest, in bits (8 to 512, in steps of 8). + Default is 512. + key (bytes/bytearray/memoryview): + Optional. The key to use to compute the MAC (1 to 64 bytes). + If not specified, no key will be used. + update_after_digest (boolean): + Optional. By default, a hash object cannot be updated anymore after + the digest is computed. When this flag is ``True``, such check + is no longer enforced. + + Returns: + A :class:`BLAKE2b_Hash` hash object + """ + + data = kwargs.pop("data", None) + update_after_digest = kwargs.pop("update_after_digest", False) + + digest_bytes = kwargs.pop("digest_bytes", None) + digest_bits = kwargs.pop("digest_bits", None) + if None not in (digest_bytes, digest_bits): + raise TypeError("Only one digest parameter must be provided") + if (None, None) == (digest_bytes, digest_bits): + digest_bytes = 64 + if digest_bytes is not None: + if not (1 <= digest_bytes <= 64): + raise ValueError("'digest_bytes' not in range 1..64") + else: + if not (8 <= digest_bits <= 512) or (digest_bits % 8): + raise ValueError("'digest_bytes' not in range 8..512, " + "with steps of 8") + digest_bytes = digest_bits // 8 + + key = kwargs.pop("key", b"") + if len(key) > 64: + raise ValueError("BLAKE2s key cannot exceed 64 bytes") + + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + return BLAKE2b_Hash(data, key, digest_bytes, update_after_digest) diff --git a/frozen_deps/Cryptodome/Hash/BLAKE2b.pyi b/frozen_deps/Cryptodome/Hash/BLAKE2b.pyi new file mode 100644 index 0000000..ac3bf57 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/BLAKE2b.pyi @@ -0,0 +1,31 @@ +from typing import Any, Union + +Buffer = Union[bytes, bytearray, memoryview] + +class BLAKE2b_Hash(object): + block_size: int + digest_size: int + oid: str + + def __init__(self, + data: Buffer, + key: Buffer, + digest_bytes: bytes, + update_after_digest: bool) -> None: ... + def update(self, data: Buffer) -> BLAKE2b_Hash: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def verify(self, mac_tag: Buffer) -> None: ... + def hexverify(self, hex_mac_tag: str) -> None: ... + def new(self, + data: Buffer = ..., + digest_bytes: int = ..., + digest_bits: int = ..., + key: Buffer = ..., + update_after_digest: bool = ...) -> BLAKE2b_Hash: ... + +def new(data: Buffer = ..., + digest_bytes: int = ..., + digest_bits: int = ..., + key: Buffer = ..., + update_after_digest: bool = ...) -> BLAKE2b_Hash: ... diff --git a/frozen_deps/Cryptodome/Hash/BLAKE2s.py b/frozen_deps/Cryptodome/Hash/BLAKE2s.py new file mode 100644 index 0000000..a16b515 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/BLAKE2s.py @@ -0,0 +1,247 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from binascii import unhexlify + +from Cryptodome.Util.py3compat import bord, tobytes + +from Cryptodome.Random import get_random_bytes +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +_raw_blake2s_lib = load_pycryptodome_raw_lib("Cryptodome.Hash._BLAKE2s", + """ + int blake2s_init(void **state, + const uint8_t *key, + size_t key_size, + size_t digest_size); + int blake2s_destroy(void *state); + int blake2s_update(void *state, + const uint8_t *buf, + size_t len); + int blake2s_digest(const void *state, + uint8_t digest[32]); + int blake2s_copy(const void *src, void *dst); + """) + + +class BLAKE2s_Hash(object): + """A BLAKE2s hash object. + Do not instantiate directly. Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + + :ivar block_size: the size in bytes of the internal message block, + input to the compression function + :vartype block_size: integer + + :ivar digest_size: the size in bytes of the resulting hash + :vartype digest_size: integer + """ + + # The internal block size of the hash algorithm in bytes. + block_size = 32 + + def __init__(self, data, key, digest_bytes, update_after_digest): + + # The size of the resulting hash in bytes. + self.digest_size = digest_bytes + + self._update_after_digest = update_after_digest + self._digest_done = False + + # See https://tools.ietf.org/html/rfc7693 + if digest_bytes in (16, 20, 28, 32) and not key: + self.oid = "1.3.6.1.4.1.1722.12.2.2." + str(digest_bytes) + + state = VoidPointer() + result = _raw_blake2s_lib.blake2s_init(state.address_of(), + c_uint8_ptr(key), + c_size_t(len(key)), + c_size_t(digest_bytes) + ) + if result: + raise ValueError("Error %d while instantiating BLAKE2s" % result) + self._state = SmartPointer(state.get(), + _raw_blake2s_lib.blake2s_destroy) + if data: + self.update(data) + + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + if self._digest_done and not self._update_after_digest: + raise TypeError("You can only call 'digest' or 'hexdigest' on this object") + + result = _raw_blake2s_lib.blake2s_update(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while hashing BLAKE2s data" % result) + return self + + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + bfr = create_string_buffer(32) + result = _raw_blake2s_lib.blake2s_digest(self._state.get(), + bfr) + if result: + raise ValueError("Error %d while creating BLAKE2s digest" % result) + + self._digest_done = True + + return get_raw_buffer(bfr)[:self.digest_size] + + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in tuple(self.digest())]) + + + def verify(self, mac_tag): + """Verify that a given **binary** MAC (computed by another party) + is valid. + + Args: + mac_tag (byte string/byte array/memoryview): the expected MAC of the message. + + Raises: + ValueError: if the MAC does not match. It means that the message + has been tampered with or that the MAC key is incorrect. + """ + + secret = get_random_bytes(16) + + mac1 = new(digest_bits=160, key=secret, data=mac_tag) + mac2 = new(digest_bits=160, key=secret, data=self.digest()) + + if mac1.digest() != mac2.digest(): + raise ValueError("MAC check failed") + + + def hexverify(self, hex_mac_tag): + """Verify that a given **printable** MAC (computed by another party) + is valid. + + Args: + hex_mac_tag (string): the expected MAC of the message, as a hexadecimal string. + + Raises: + ValueError: if the MAC does not match. It means that the message + has been tampered with or that the MAC key is incorrect. + """ + + self.verify(unhexlify(tobytes(hex_mac_tag))) + + + def new(self, **kwargs): + """Return a new instance of a BLAKE2s hash object. + See :func:`new`. + """ + + if "digest_bytes" not in kwargs and "digest_bits" not in kwargs: + kwargs["digest_bytes"] = self.digest_size + + return new(**kwargs) + + +def new(**kwargs): + """Create a new hash object. + + Args: + data (byte string/byte array/memoryview): + Optional. The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`BLAKE2s_Hash.update`. + digest_bytes (integer): + Optional. The size of the digest, in bytes (1 to 32). Default is 32. + digest_bits (integer): + Optional and alternative to ``digest_bytes``. + The size of the digest, in bits (8 to 256, in steps of 8). + Default is 256. + key (byte string): + Optional. The key to use to compute the MAC (1 to 64 bytes). + If not specified, no key will be used. + update_after_digest (boolean): + Optional. By default, a hash object cannot be updated anymore after + the digest is computed. When this flag is ``True``, such check + is no longer enforced. + + Returns: + A :class:`BLAKE2s_Hash` hash object + """ + + data = kwargs.pop("data", None) + update_after_digest = kwargs.pop("update_after_digest", False) + + digest_bytes = kwargs.pop("digest_bytes", None) + digest_bits = kwargs.pop("digest_bits", None) + if None not in (digest_bytes, digest_bits): + raise TypeError("Only one digest parameter must be provided") + if (None, None) == (digest_bytes, digest_bits): + digest_bytes = 32 + if digest_bytes is not None: + if not (1 <= digest_bytes <= 32): + raise ValueError("'digest_bytes' not in range 1..32") + else: + if not (8 <= digest_bits <= 256) or (digest_bits % 8): + raise ValueError("'digest_bytes' not in range 8..256, " + "with steps of 8") + digest_bytes = digest_bits // 8 + + key = kwargs.pop("key", b"") + if len(key) > 32: + raise ValueError("BLAKE2s key cannot exceed 32 bytes") + + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + return BLAKE2s_Hash(data, key, digest_bytes, update_after_digest) diff --git a/frozen_deps/Cryptodome/Hash/BLAKE2s.pyi b/frozen_deps/Cryptodome/Hash/BLAKE2s.pyi new file mode 100644 index 0000000..374b3a4 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/BLAKE2s.pyi @@ -0,0 +1,26 @@ +from typing import Any, Union + +Buffer = Union[bytes, bytearray, memoryview] + +class BLAKE2s_Hash(object): + block_size: int + digest_size: int + oid: str + + def __init__(self, + data: Buffer, + key: Buffer, + digest_bytes: bytes, + update_after_digest: bool) -> None: ... + def update(self, data: Buffer) -> BLAKE2s_Hash: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def verify(self, mac_tag: Buffer) -> None: ... + def hexverify(self, hex_mac_tag: str) -> None: ... + def new(self, **kwargs: Any) -> BLAKE2s_Hash: ... + +def new(data: Buffer = ..., + digest_bytes: int = ..., + digest_bits: int = ..., + key: Buffer = ..., + update_after_digest: bool = ...) -> BLAKE2s_Hash: ... diff --git a/frozen_deps/Cryptodome/Hash/CMAC.py b/frozen_deps/Cryptodome/Hash/CMAC.py new file mode 100644 index 0000000..df69f00 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/CMAC.py @@ -0,0 +1,305 @@ +# -*- coding: utf-8 -*- +# +# Hash/CMAC.py - Implements the CMAC algorithm +# +# =================================================================== +# 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. +# =================================================================== + +import sys +from binascii import unhexlify + +from Cryptodome.Hash import BLAKE2s +from Cryptodome.Util.strxor import strxor +from Cryptodome.Util.number import long_to_bytes, bytes_to_long +from Cryptodome.Util.py3compat import bord, tobytes, _copy_bytes +from Cryptodome.Random import get_random_bytes + +if sys.version_info[:2] == (2, 6): + memoryview = bytes + +# The size of the authentication tag produced by the MAC. +digest_size = None + + +def _shift_bytes(bs, xor_lsb=0): + num = (bytes_to_long(bs) << 1) ^ xor_lsb + return long_to_bytes(num, len(bs))[-len(bs):] + + +class CMAC(object): + """A CMAC hash object. + Do not instantiate directly. Use the :func:`new` function. + + :ivar digest_size: the size in bytes of the resulting MAC tag + :vartype digest_size: integer + """ + + digest_size = None + + def __init__(self, key, msg, ciphermod, cipher_params, mac_len, + update_after_digest): + + self.digest_size = mac_len + + self._key = _copy_bytes(None, None, key) + self._factory = ciphermod + self._cipher_params = cipher_params + self._block_size = bs = ciphermod.block_size + self._mac_tag = None + self._update_after_digest = update_after_digest + + # Section 5.3 of NIST SP 800 38B and Appendix B + if bs == 8: + const_Rb = 0x1B + self._max_size = 8 * (2 ** 21) + elif bs == 16: + const_Rb = 0x87 + self._max_size = 16 * (2 ** 48) + else: + raise TypeError("CMAC requires a cipher with a block size" + " of 8 or 16 bytes, not %d" % bs) + + # Compute sub-keys + zero_block = b'\x00' * bs + self._ecb = ciphermod.new(key, + ciphermod.MODE_ECB, + **self._cipher_params) + L = self._ecb.encrypt(zero_block) + if bord(L[0]) & 0x80: + self._k1 = _shift_bytes(L, const_Rb) + else: + self._k1 = _shift_bytes(L) + if bord(self._k1[0]) & 0x80: + self._k2 = _shift_bytes(self._k1, const_Rb) + else: + self._k2 = _shift_bytes(self._k1) + + # Initialize CBC cipher with zero IV + self._cbc = ciphermod.new(key, + ciphermod.MODE_CBC, + zero_block, + **self._cipher_params) + + # Cache for outstanding data to authenticate + self._cache = bytearray(bs) + self._cache_n = 0 + + # Last piece of ciphertext produced + self._last_ct = zero_block + + # Last block that was encrypted with AES + self._last_pt = None + + # Counter for total message size + self._data_size = 0 + + if msg: + self.update(msg) + + def update(self, msg): + """Authenticate the next chunk of message. + + Args: + data (byte string/byte array/memoryview): The next chunk of data + """ + + if self._mac_tag is not None and not self._update_after_digest: + raise TypeError("update() cannot be called after digest() or verify()") + + self._data_size += len(msg) + bs = self._block_size + + if self._cache_n > 0: + filler = min(bs - self._cache_n, len(msg)) + self._cache[self._cache_n:self._cache_n+filler] = msg[:filler] + self._cache_n += filler + + if self._cache_n < bs: + return self + + msg = memoryview(msg)[filler:] + self._update(self._cache) + self._cache_n = 0 + + remain = len(msg) % bs + if remain > 0: + self._update(msg[:-remain]) + self._cache[:remain] = msg[-remain:] + else: + self._update(msg) + self._cache_n = remain + return self + + def _update(self, data_block): + """Update a block aligned to the block boundary""" + + bs = self._block_size + assert len(data_block) % bs == 0 + + if len(data_block) == 0: + return + + ct = self._cbc.encrypt(data_block) + if len(data_block) == bs: + second_last = self._last_ct + else: + second_last = ct[-bs*2:-bs] + self._last_ct = ct[-bs:] + self._last_pt = strxor(second_last, data_block[-bs:]) + + def copy(self): + """Return a copy ("clone") of the CMAC object. + + The copy will have the same internal state as the original CMAC + object. + This can be used to efficiently compute the MAC tag of byte + strings that share a common initial substring. + + :return: An :class:`CMAC` + """ + + obj = self.__new__(CMAC) + obj.__dict__ = self.__dict__.copy() + obj._cbc = self._factory.new(self._key, + self._factory.MODE_CBC, + self._last_ct, + **self._cipher_params) + obj._cache = self._cache[:] + obj._last_ct = self._last_ct[:] + return obj + + def digest(self): + """Return the **binary** (non-printable) MAC tag of the message + that has been authenticated so far. + + :return: The MAC tag, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + bs = self._block_size + + if self._mac_tag is not None and not self._update_after_digest: + return self._mac_tag + + if self._data_size > self._max_size: + raise ValueError("MAC is unsafe for this message") + + if self._cache_n == 0 and self._data_size > 0: + # Last block was full + pt = strxor(self._last_pt, self._k1) + else: + # Last block is partial (or message length is zero) + partial = self._cache[:] + partial[self._cache_n:] = b'\x80' + b'\x00' * (bs - self._cache_n - 1) + pt = strxor(strxor(self._last_ct, partial), self._k2) + + self._mac_tag = self._ecb.encrypt(pt)[:self.digest_size] + + return self._mac_tag + + def hexdigest(self): + """Return the **printable** MAC tag of the message authenticated so far. + + :return: The MAC tag, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) + for x in tuple(self.digest())]) + + def verify(self, mac_tag): + """Verify that a given **binary** MAC (computed by another party) + is valid. + + Args: + mac_tag (byte string/byte array/memoryview): the expected MAC of the message. + + Raises: + ValueError: if the MAC does not match. It means that the message + has been tampered with or that the MAC key is incorrect. + """ + + secret = get_random_bytes(16) + + mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=mac_tag) + mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=self.digest()) + + if mac1.digest() != mac2.digest(): + raise ValueError("MAC check failed") + + def hexverify(self, hex_mac_tag): + """Return the **printable** MAC tag of the message authenticated so far. + + :return: The MAC tag, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + self.verify(unhexlify(tobytes(hex_mac_tag))) + + +def new(key, msg=None, ciphermod=None, cipher_params=None, mac_len=None, + update_after_digest=False): + """Create a new MAC object. + + Args: + key (byte string/byte array/memoryview): + key for the CMAC object. + The key must be valid for the underlying cipher algorithm. + For instance, it must be 16 bytes long for AES-128. + ciphermod (module): + A cipher module from :mod:`Cryptodome.Cipher`. + The cipher's block size has to be 128 bits, + like :mod:`Cryptodome.Cipher.AES`, to reduce the probability + of collisions. + msg (byte string/byte array/memoryview): + Optional. The very first chunk of the message to authenticate. + It is equivalent to an early call to `CMAC.update`. Optional. + cipher_params (dict): + Optional. A set of parameters to use when instantiating a cipher + object. + mac_len (integer): + Length of the MAC, in bytes. + It must be at least 4 bytes long. + The default (and recommended) length matches the size of a cipher block. + update_after_digest (boolean): + Optional. By default, a hash object cannot be updated anymore after + the digest is computed. When this flag is ``True``, such check + is no longer enforced. + Returns: + A :class:`CMAC` object + """ + + if ciphermod is None: + raise TypeError("ciphermod must be specified (try AES)") + + cipher_params = {} if cipher_params is None else dict(cipher_params) + + if mac_len is None: + mac_len = ciphermod.block_size + + if mac_len < 4: + raise ValueError("MAC tag length must be at least 4 bytes long") + + if mac_len > ciphermod.block_size: + raise ValueError("MAC tag length cannot be larger than a cipher block (%d) bytes" % ciphermod.block_size) + + return CMAC(key, msg, ciphermod, cipher_params, mac_len, + update_after_digest) diff --git a/frozen_deps/Cryptodome/Hash/CMAC.pyi b/frozen_deps/Cryptodome/Hash/CMAC.pyi new file mode 100644 index 0000000..33773aa --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/CMAC.pyi @@ -0,0 +1,30 @@ +from types import ModuleType +from typing import Union, Dict + +Buffer = Union[bytes, bytearray, memoryview] + +digest_size: int + +class CMAC(object): + digest_size: int + + def __init__(self, + key: Buffer, + msg: Buffer, + ciphermod: ModuleType, + cipher_params: dict, + mac_len: int, update_after_digest: bool) -> None: ... + def update(self, data: Buffer) -> CMAC: ... + def copy(self) -> CMAC: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def verify(self, mac_tag: Buffer) -> None: ... + def hexverify(self, hex_mac_tag: str) -> None: ... + + +def new(key: Buffer, + msg: Buffer = ..., + ciphermod: ModuleType = ..., + cipher_params: Dict = ..., + mac_len: int = ..., + update_after_digest: bool = ...) -> CMAC: ... diff --git a/frozen_deps/Cryptodome/Hash/HMAC.py b/frozen_deps/Cryptodome/Hash/HMAC.py new file mode 100644 index 0000000..ac94b20 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/HMAC.py @@ -0,0 +1,213 @@ +# +# HMAC.py - Implements the HMAC algorithm as described by RFC 2104. +# +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Util.py3compat import bord, tobytes, _memoryview + +from binascii import unhexlify + +from Cryptodome.Hash import MD5 +from Cryptodome.Hash import BLAKE2s +from Cryptodome.Util.strxor import strxor +from Cryptodome.Random import get_random_bytes + +__all__ = ['new', 'HMAC'] + + +class HMAC(object): + """An HMAC hash object. + Do not instantiate directly. Use the :func:`new` function. + + :ivar digest_size: the size in bytes of the resulting MAC tag + :vartype digest_size: integer + """ + + def __init__(self, key, msg=b"", digestmod=None): + + if digestmod is None: + digestmod = MD5 + + if msg is None: + msg = b"" + + # Size of the MAC tag + self.digest_size = digestmod.digest_size + + self._digestmod = digestmod + + if isinstance(key, _memoryview): + key = key.tobytes() + + try: + if len(key) <= digestmod.block_size: + # Step 1 or 2 + key_0 = key + b"\x00" * (digestmod.block_size - len(key)) + else: + # Step 3 + hash_k = digestmod.new(key).digest() + key_0 = hash_k + b"\x00" * (digestmod.block_size - len(hash_k)) + except AttributeError: + # Not all hash types have "block_size" + raise ValueError("Hash type incompatible to HMAC") + + # Step 4 + key_0_ipad = strxor(key_0, b"\x36" * len(key_0)) + + # Start step 5 and 6 + self._inner = digestmod.new(key_0_ipad) + self._inner.update(msg) + + # Step 7 + key_0_opad = strxor(key_0, b"\x5c" * len(key_0)) + + # Start step 8 and 9 + self._outer = digestmod.new(key_0_opad) + + def update(self, msg): + """Authenticate the next chunk of message. + + Args: + data (byte string/byte array/memoryview): The next chunk of data + """ + + self._inner.update(msg) + return self + + def _pbkdf2_hmac_assist(self, first_digest, iterations): + """Carry out the expensive inner loop for PBKDF2-HMAC""" + + result = self._digestmod._pbkdf2_hmac_assist( + self._inner, + self._outer, + first_digest, + iterations) + return result + + def copy(self): + """Return a copy ("clone") of the HMAC object. + + The copy will have the same internal state as the original HMAC + object. + This can be used to efficiently compute the MAC tag of byte + strings that share a common initial substring. + + :return: An :class:`HMAC` + """ + + new_hmac = HMAC(b"fake key", digestmod=self._digestmod) + + # Syncronize the state + new_hmac._inner = self._inner.copy() + new_hmac._outer = self._outer.copy() + + return new_hmac + + def digest(self): + """Return the **binary** (non-printable) MAC tag of the message + authenticated so far. + + :return: The MAC tag digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + frozen_outer_hash = self._outer.copy() + frozen_outer_hash.update(self._inner.digest()) + return frozen_outer_hash.digest() + + def verify(self, mac_tag): + """Verify that a given **binary** MAC (computed by another party) + is valid. + + Args: + mac_tag (byte string/byte string/memoryview): the expected MAC of the message. + + Raises: + ValueError: if the MAC does not match. It means that the message + has been tampered with or that the MAC key is incorrect. + """ + + secret = get_random_bytes(16) + + mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=mac_tag) + mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=self.digest()) + + if mac1.digest() != mac2.digest(): + raise ValueError("MAC check failed") + + def hexdigest(self): + """Return the **printable** MAC tag of the message authenticated so far. + + :return: The MAC tag, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) + for x in tuple(self.digest())]) + + def hexverify(self, hex_mac_tag): + """Verify that a given **printable** MAC (computed by another party) + is valid. + + Args: + hex_mac_tag (string): the expected MAC of the message, + as a hexadecimal string. + + Raises: + ValueError: if the MAC does not match. It means that the message + has been tampered with or that the MAC key is incorrect. + """ + + self.verify(unhexlify(tobytes(hex_mac_tag))) + + +def new(key, msg=b"", digestmod=None): + """Create a new MAC object. + + Args: + key (bytes/bytearray/memoryview): + key for the MAC object. + It must be long enough to match the expected security level of the + MAC. + msg (bytes/bytearray/memoryview): + Optional. The very first chunk of the message to authenticate. + It is equivalent to an early call to :meth:`HMAC.update`. + digestmod (module): + The hash to use to implement the HMAC. + Default is :mod:`Cryptodome.Hash.MD5`. + + Returns: + An :class:`HMAC` object + """ + + return HMAC(key, msg, digestmod) diff --git a/frozen_deps/Cryptodome/Hash/HMAC.pyi b/frozen_deps/Cryptodome/Hash/HMAC.pyi new file mode 100644 index 0000000..b577230 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/HMAC.pyi @@ -0,0 +1,25 @@ +from types import ModuleType +from typing import Union, Dict + +Buffer = Union[bytes, bytearray, memoryview] + +digest_size: int + +class HMAC(object): + digest_size: int + + def __init__(self, + key: Buffer, + msg: Buffer, + digestmod: ModuleType) -> None: ... + def update(self, msg: Buffer) -> HMAC: ... + def copy(self) -> HMAC: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def verify(self, mac_tag: Buffer) -> None: ... + def hexverify(self, hex_mac_tag: str) -> None: ... + + +def new(key: Buffer, + msg: Buffer = ..., + digestmod: ModuleType = ...) -> HMAC: ... diff --git a/frozen_deps/Cryptodome/Hash/MD2.py b/frozen_deps/Cryptodome/Hash/MD2.py new file mode 100644 index 0000000..47ecc05 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/MD2.py @@ -0,0 +1,166 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Util.py3compat import bord + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +_raw_md2_lib = load_pycryptodome_raw_lib( + "Cryptodome.Hash._MD2", + """ + int md2_init(void **shaState); + int md2_destroy(void *shaState); + int md2_update(void *hs, + const uint8_t *buf, + size_t len); + int md2_digest(const void *shaState, + uint8_t digest[20]); + int md2_copy(const void *src, void *dst); + """) + + +class MD2Hash(object): + """An MD2 hash object. + Do not instantiate directly. Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + + :ivar block_size: the size in bytes of the internal message block, + input to the compression function + :vartype block_size: integer + + :ivar digest_size: the size in bytes of the resulting hash + :vartype digest_size: integer + """ + + # The size of the resulting hash in bytes. + digest_size = 16 + # The internal block size of the hash algorithm in bytes. + block_size = 16 + # ASN.1 Object ID + oid = "1.2.840.113549.2.2" + + def __init__(self, data=None): + state = VoidPointer() + result = _raw_md2_lib.md2_init(state.address_of()) + if result: + raise ValueError("Error %d while instantiating MD2" + % result) + self._state = SmartPointer(state.get(), + _raw_md2_lib.md2_destroy) + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + result = _raw_md2_lib.md2_update(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while instantiating MD2" + % result) + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + bfr = create_string_buffer(self.digest_size) + result = _raw_md2_lib.md2_digest(self._state.get(), + bfr) + if result: + raise ValueError("Error %d while instantiating MD2" + % result) + + return get_raw_buffer(bfr) + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in self.digest()]) + + 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 + """ + + clone = MD2Hash() + result = _raw_md2_lib.md2_copy(self._state.get(), + clone._state.get()) + if result: + raise ValueError("Error %d while copying MD2" % result) + return clone + + def new(self, data=None): + return MD2Hash(data) + + +def new(data=None): + """Create a new hash object. + + :parameter data: + Optional. The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`MD2Hash.update`. + :type data: bytes/bytearray/memoryview + + :Return: A :class:`MD2Hash` hash 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/frozen_deps/Cryptodome/Hash/MD2.pyi b/frozen_deps/Cryptodome/Hash/MD2.pyi new file mode 100644 index 0000000..95a97a9 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/MD2.pyi @@ -0,0 +1,19 @@ +from typing import Union + +Buffer = Union[bytes, bytearray, memoryview] + +class MD4Hash(object): + digest_size: int + block_size: int + oid: str + + def __init__(self, data: Buffer = ...) -> None: ... + def update(self, data: Buffer) -> None: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def copy(self) -> MD4Hash: ... + def new(self, data: Buffer = ...) -> MD4Hash: ... + +def new(data: Buffer = ...) -> MD4Hash: ... +digest_size: int +block_size: int diff --git a/frozen_deps/Cryptodome/Hash/MD4.py b/frozen_deps/Cryptodome/Hash/MD4.py new file mode 100644 index 0000000..668fa65 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/MD4.py @@ -0,0 +1,185 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +""" +MD4 is specified in RFC1320_ and produces the 128 bit digest of a message. + + >>> from Cryptodome.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 +""" + +from Cryptodome.Util.py3compat import bord + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +_raw_md4_lib = load_pycryptodome_raw_lib( + "Cryptodome.Hash._MD4", + """ + int md4_init(void **shaState); + int md4_destroy(void *shaState); + int md4_update(void *hs, + const uint8_t *buf, + size_t len); + int md4_digest(const void *shaState, + uint8_t digest[20]); + int md4_copy(const void *src, void *dst); + """) + + +class MD4Hash(object): + """Class that implements an MD4 hash + """ + + #: The size of the resulting hash in bytes. + digest_size = 16 + #: The internal block size of the hash algorithm in bytes. + block_size = 64 + #: ASN.1 Object ID + oid = "1.2.840.113549.2.4" + + def __init__(self, data=None): + state = VoidPointer() + result = _raw_md4_lib.md4_init(state.address_of()) + if result: + raise ValueError("Error %d while instantiating MD4" + % result) + self._state = SmartPointer(state.get(), + _raw_md4_lib.md4_destroy) + 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/byte array/memoryview + The next chunk of the message being hashed. + """ + + result = _raw_md4_lib.md4_update(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while instantiating MD4" + % result) + + 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. + """ + + bfr = create_string_buffer(self.digest_size) + result = _raw_md4_lib.md4_digest(self._state.get(), + bfr) + if result: + raise ValueError("Error %d while instantiating MD4" + % result) + + return get_raw_buffer(bfr) + + 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 "".join(["%02x" % bord(x) for x in self.digest()]) + + 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 + """ + + clone = MD4Hash() + result = _raw_md4_lib.md4_copy(self._state.get(), + clone._state.get()) + if result: + raise ValueError("Error %d while copying MD4" % result) + return clone + + def new(self, data=None): + return MD4Hash(data) + + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string/byte array/memoryview + 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/frozen_deps/Cryptodome/Hash/MD4.pyi b/frozen_deps/Cryptodome/Hash/MD4.pyi new file mode 100644 index 0000000..a9a7295 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/MD4.pyi @@ -0,0 +1,19 @@ +from typing import Union, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +class MD4Hash(object): + digest_size: int + block_size: int + oid: str + + def __init__(self, data: Optional[Buffer] = ...) -> None: ... + def update(self, data: Buffer) -> None: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def copy(self) -> MD4Hash: ... + def new(self, data: Optional[Buffer] = ...) -> MD4Hash: ... + +def new(data: Optional[Buffer] = ...) -> MD4Hash: ... +digest_size: int +block_size: int diff --git a/frozen_deps/Cryptodome/Hash/MD5.py b/frozen_deps/Cryptodome/Hash/MD5.py new file mode 100644 index 0000000..8f573a9 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/MD5.py @@ -0,0 +1,184 @@ +# -*- 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 Cryptodome.Util.py3compat import * + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +_raw_md5_lib = load_pycryptodome_raw_lib("Cryptodome.Hash._MD5", + """ + #define MD5_DIGEST_SIZE 16 + + int MD5_init(void **shaState); + int MD5_destroy(void *shaState); + int MD5_update(void *hs, + const uint8_t *buf, + size_t len); + int MD5_digest(const void *shaState, + uint8_t digest[MD5_DIGEST_SIZE]); + int MD5_copy(const void *src, void *dst); + + int MD5_pbkdf2_hmac_assist(const void *inner, + const void *outer, + const uint8_t first_digest[MD5_DIGEST_SIZE], + uint8_t final_digest[MD5_DIGEST_SIZE], + size_t iterations); + """) + +class MD5Hash(object): + """A MD5 hash object. + Do not instantiate directly. + Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + + :ivar block_size: the size in bytes of the internal message block, + input to the compression function + :vartype block_size: integer + + :ivar digest_size: the size in bytes of the resulting hash + :vartype digest_size: integer + """ + + # The size of the resulting hash in bytes. + digest_size = 16 + # The internal block size of the hash algorithm in bytes. + block_size = 64 + # ASN.1 Object ID + oid = "1.2.840.113549.2.5" + + def __init__(self, data=None): + state = VoidPointer() + result = _raw_md5_lib.MD5_init(state.address_of()) + if result: + raise ValueError("Error %d while instantiating MD5" + % result) + self._state = SmartPointer(state.get(), + _raw_md5_lib.MD5_destroy) + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + result = _raw_md5_lib.MD5_update(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while instantiating MD5" + % result) + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + bfr = create_string_buffer(self.digest_size) + result = _raw_md5_lib.MD5_digest(self._state.get(), + bfr) + if result: + raise ValueError("Error %d while instantiating MD5" + % result) + + return get_raw_buffer(bfr) + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in self.digest()]) + + 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 + """ + + clone = MD5Hash() + result = _raw_md5_lib.MD5_copy(self._state.get(), + clone._state.get()) + if result: + raise ValueError("Error %d while copying MD5" % result) + return clone + + def new(self, data=None): + """Create a fresh SHA-1 hash object.""" + + return MD5Hash(data) + + +def new(data=None): + """Create a new hash object. + + :parameter data: + Optional. The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`MD5Hash.update`. + :type data: byte string/byte array/memoryview + + :Return: A :class:`MD5Hash` hash object + """ + return MD5Hash().new(data) + +# The size of the resulting hash in bytes. +digest_size = 16 + +# The internal block size of the hash algorithm in bytes. +block_size = 64 + + +def _pbkdf2_hmac_assist(inner, outer, first_digest, iterations): + """Compute the expensive inner loop in PBKDF-HMAC.""" + + assert len(first_digest) == digest_size + assert iterations > 0 + + bfr = create_string_buffer(digest_size); + result = _raw_md5_lib.MD5_pbkdf2_hmac_assist( + inner._state.get(), + outer._state.get(), + first_digest, + bfr, + c_size_t(iterations)) + + if result: + raise ValueError("Error %d with PBKDF2-HMAC assis for MD5" % result) + + return get_raw_buffer(bfr) diff --git a/frozen_deps/Cryptodome/Hash/MD5.pyi b/frozen_deps/Cryptodome/Hash/MD5.pyi new file mode 100644 index 0000000..d819556 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/MD5.pyi @@ -0,0 +1,19 @@ +from typing import Union + +Buffer = Union[bytes, bytearray, memoryview] + +class MD5Hash(object): + digest_size: int + block_size: int + oid: str + + def __init__(self, data: Buffer = ...) -> None: ... + def update(self, data: Buffer) -> None: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def copy(self) -> MD5Hash: ... + def new(self, data: Buffer = ...) -> MD5Hash: ... + +def new(data: Buffer = ...) -> MD5Hash: ... +digest_size: int +block_size: int diff --git a/frozen_deps/Cryptodome/Hash/Poly1305.py b/frozen_deps/Cryptodome/Hash/Poly1305.py new file mode 100644 index 0000000..c03f522 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/Poly1305.py @@ -0,0 +1,217 @@ +# -*- coding: utf-8 -*- +# +# Hash/Poly1305.py - Implements the Poly1305 MAC +# +# =================================================================== +# 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 unhexlify + +from Cryptodome.Util.py3compat import bord, tobytes, _copy_bytes + +from Cryptodome.Hash import BLAKE2s +from Cryptodome.Random import get_random_bytes +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + + +_raw_poly1305 = load_pycryptodome_raw_lib("Cryptodome.Hash._poly1305", + """ + int poly1305_init(void **state, + const uint8_t *r, + size_t r_len, + const uint8_t *s, + size_t s_len); + int poly1305_destroy(void *state); + int poly1305_update(void *state, + const uint8_t *in, + size_t len); + int poly1305_digest(const void *state, + uint8_t *digest, + size_t len); + """) + + +class Poly1305_MAC(object): + """An Poly1305 MAC object. + Do not instantiate directly. Use the :func:`new` function. + + :ivar digest_size: the size in bytes of the resulting MAC tag + :vartype digest_size: integer + """ + + digest_size = 16 + + def __init__(self, r, s, data): + + if len(r) != 16: + raise ValueError("Parameter r is not 16 bytes long") + if len(s) != 16: + raise ValueError("Parameter s is not 16 bytes long") + + self._mac_tag = None + + state = VoidPointer() + result = _raw_poly1305.poly1305_init(state.address_of(), + c_uint8_ptr(r), + c_size_t(len(r)), + c_uint8_ptr(s), + c_size_t(len(s)) + ) + if result: + raise ValueError("Error %d while instantiating Poly1305" % result) + self._state = SmartPointer(state.get(), + _raw_poly1305.poly1305_destroy) + if data: + self.update(data) + + def update(self, data): + """Authenticate the next chunk of message. + + Args: + data (byte string/byte array/memoryview): The next chunk of data + """ + + if self._mac_tag: + raise TypeError("You can only call 'digest' or 'hexdigest' on this object") + + result = _raw_poly1305.poly1305_update(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while hashing Poly1305 data" % result) + return self + + def copy(self): + raise NotImplementedError() + + def digest(self): + """Return the **binary** (non-printable) MAC tag of the message + authenticated so far. + + :return: The MAC tag digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + if self._mac_tag: + return self._mac_tag + + bfr = create_string_buffer(16) + result = _raw_poly1305.poly1305_digest(self._state.get(), + bfr, + c_size_t(len(bfr))) + if result: + raise ValueError("Error %d while creating Poly1305 digest" % result) + + self._mac_tag = get_raw_buffer(bfr) + return self._mac_tag + + def hexdigest(self): + """Return the **printable** MAC tag of the message authenticated so far. + + :return: The MAC tag, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) + for x in tuple(self.digest())]) + + def verify(self, mac_tag): + """Verify that a given **binary** MAC (computed by another party) + is valid. + + Args: + mac_tag (byte string/byte string/memoryview): the expected MAC of the message. + + Raises: + ValueError: if the MAC does not match. It means that the message + has been tampered with or that the MAC key is incorrect. + """ + + secret = get_random_bytes(16) + + mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=mac_tag) + mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=self.digest()) + + if mac1.digest() != mac2.digest(): + raise ValueError("MAC check failed") + + def hexverify(self, hex_mac_tag): + """Verify that a given **printable** MAC (computed by another party) + is valid. + + Args: + hex_mac_tag (string): the expected MAC of the message, + as a hexadecimal string. + + Raises: + ValueError: if the MAC does not match. It means that the message + has been tampered with or that the MAC key is incorrect. + """ + + self.verify(unhexlify(tobytes(hex_mac_tag))) + + + +def new(**kwargs): + """Create a new Poly1305 MAC object. + + Args: + key (bytes/bytearray/memoryview): + The 32-byte key for the Poly1305 object. + cipher (module from ``Cryptodome.Cipher``): + The cipher algorithm to use for deriving the Poly1305 + key pair *(r, s)*. + It can only be ``Cryptodome.Cipher.AES`` or ``Cryptodome.Cipher.ChaCha20``. + nonce (bytes/bytearray/memoryview): + Optional. The non-repeatable value to use for the MAC of this message. + It must be 16 bytes long for ``AES`` and 8 or 12 bytes for ``ChaCha20``. + If not passed, a random nonce is created; you will find it in the + ``nonce`` attribute of the new object. + data (bytes/bytearray/memoryview): + Optional. The very first chunk of the message to authenticate. + It is equivalent to an early call to ``update()``. + + Returns: + A :class:`Poly1305_MAC` object + """ + + cipher = kwargs.pop("cipher", None) + if not hasattr(cipher, '_derive_Poly1305_key_pair'): + raise ValueError("Parameter 'cipher' must be AES or ChaCha20") + + cipher_key = kwargs.pop("key", None) + if cipher_key is None: + raise TypeError("You must pass a parameter 'key'") + + nonce = kwargs.pop("nonce", None) + data = kwargs.pop("data", None) + + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + r, s, nonce = cipher._derive_Poly1305_key_pair(cipher_key, nonce) + + new_mac = Poly1305_MAC(r, s, data) + new_mac.nonce = _copy_bytes(None, None, nonce) # nonce may still be just a memoryview + return new_mac diff --git a/frozen_deps/Cryptodome/Hash/Poly1305.pyi b/frozen_deps/Cryptodome/Hash/Poly1305.pyi new file mode 100644 index 0000000..f97a14a --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/Poly1305.pyi @@ -0,0 +1,24 @@ +from types import ModuleType +from typing import Union + +Buffer = Union[bytes, bytearray, memoryview] + +class Poly1305_MAC(object): + block_size: int + digest_size: int + oid: str + + def __init__(self, + r : int, + s : int, + data : Buffer) -> None: ... + def update(self, data: Buffer) -> Poly1305_MAC: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def verify(self, mac_tag: Buffer) -> None: ... + def hexverify(self, hex_mac_tag: str) -> None: ... + +def new(key: Buffer, + cipher: ModuleType, + nonce: Buffer = ..., + data: Buffer = ...) -> Poly1305_MAC: ... diff --git a/frozen_deps/Cryptodome/Hash/RIPEMD.py b/frozen_deps/Cryptodome/Hash/RIPEMD.py new file mode 100644 index 0000000..35ad576 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/RIPEMD.py @@ -0,0 +1,26 @@ +# -*- 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. +# =================================================================== + +# This file exists for backward compatibility with old code that refers to +# Cryptodome.Hash.RIPEMD + +"""Deprecated alias for `Cryptodome.Hash.RIPEMD160`""" + +from Cryptodome.Hash.RIPEMD160 import new, block_size, digest_size diff --git a/frozen_deps/Cryptodome/Hash/RIPEMD.pyi b/frozen_deps/Cryptodome/Hash/RIPEMD.pyi new file mode 100644 index 0000000..cfb2252 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/RIPEMD.pyi @@ -0,0 +1,3 @@ +# This file exists for backward compatibility with old code that refers to +# Cryptodome.Hash.SHA + diff --git a/frozen_deps/Cryptodome/Hash/RIPEMD160.py b/frozen_deps/Cryptodome/Hash/RIPEMD160.py new file mode 100644 index 0000000..f959027 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/RIPEMD160.py @@ -0,0 +1,169 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Util.py3compat import bord + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +_raw_ripemd160_lib = load_pycryptodome_raw_lib( + "Cryptodome.Hash._RIPEMD160", + """ + int ripemd160_init(void **shaState); + int ripemd160_destroy(void *shaState); + int ripemd160_update(void *hs, + const uint8_t *buf, + size_t len); + int ripemd160_digest(const void *shaState, + uint8_t digest[20]); + int ripemd160_copy(const void *src, void *dst); + """) + + +class RIPEMD160Hash(object): + """A RIPEMD-160 hash object. + Do not instantiate directly. + Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + + :ivar block_size: the size in bytes of the internal message block, + input to the compression function + :vartype block_size: integer + + :ivar digest_size: the size in bytes of the resulting hash + :vartype digest_size: integer + """ + + # The size of the resulting hash in bytes. + digest_size = 20 + # The internal block size of the hash algorithm in bytes. + block_size = 64 + # ASN.1 Object ID + oid = "1.3.36.3.2.1" + + def __init__(self, data=None): + state = VoidPointer() + result = _raw_ripemd160_lib.ripemd160_init(state.address_of()) + if result: + raise ValueError("Error %d while instantiating RIPEMD160" + % result) + self._state = SmartPointer(state.get(), + _raw_ripemd160_lib.ripemd160_destroy) + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + result = _raw_ripemd160_lib.ripemd160_update(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while instantiating ripemd160" + % result) + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + bfr = create_string_buffer(self.digest_size) + result = _raw_ripemd160_lib.ripemd160_digest(self._state.get(), + bfr) + if result: + raise ValueError("Error %d while instantiating ripemd160" + % result) + + return get_raw_buffer(bfr) + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in self.digest()]) + + 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 + """ + + clone = RIPEMD160Hash() + result = _raw_ripemd160_lib.ripemd160_copy(self._state.get(), + clone._state.get()) + if result: + raise ValueError("Error %d while copying ripemd160" % result) + return clone + + def new(self, data=None): + """Create a fresh RIPEMD-160 hash object.""" + + return RIPEMD160Hash(data) + + +def new(data=None): + """Create a new hash object. + + :parameter data: + Optional. The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`RIPEMD160Hash.update`. + :type data: byte string/byte array/memoryview + + :Return: A :class:`RIPEMD160Hash` hash 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/frozen_deps/Cryptodome/Hash/RIPEMD160.pyi b/frozen_deps/Cryptodome/Hash/RIPEMD160.pyi new file mode 100644 index 0000000..b619473 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/RIPEMD160.pyi @@ -0,0 +1,19 @@ +from typing import Union + +Buffer = Union[bytes, bytearray, memoryview] + +class RIPEMD160Hash(object): + digest_size: int + block_size: int + oid: str + + def __init__(self, data: Buffer = ...) -> None: ... + def update(self, data: Buffer) -> None: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def copy(self) -> RIPEMD160Hash: ... + def new(self, data: Buffer = ...) -> RIPEMD160Hash: ... + +def new(data: Buffer = ...) -> RIPEMD160Hash: ... +digest_size: int +block_size: int diff --git a/frozen_deps/Cryptodome/Hash/SHA.py b/frozen_deps/Cryptodome/Hash/SHA.py new file mode 100644 index 0000000..95f8745 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA.py @@ -0,0 +1,24 @@ +# -*- 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. +# =================================================================== + +# This file exists for backward compatibility with old code that refers to +# Cryptodome.Hash.SHA + +from Cryptodome.Hash.SHA1 import __doc__, new, block_size, digest_size diff --git a/frozen_deps/Cryptodome/Hash/SHA.pyi b/frozen_deps/Cryptodome/Hash/SHA.pyi new file mode 100644 index 0000000..7d01a5f --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA.pyi @@ -0,0 +1,4 @@ +# This file exists for backward compatibility with old code that refers to +# Cryptodome.Hash.SHA + +from Cryptodome.Hash.SHA1 import __doc__, new, block_size, digest_size diff --git a/frozen_deps/Cryptodome/Hash/SHA1.py b/frozen_deps/Cryptodome/Hash/SHA1.py new file mode 100644 index 0000000..dea51bc --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA1.py @@ -0,0 +1,185 @@ +# -*- 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 Cryptodome.Util.py3compat import * + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +_raw_sha1_lib = load_pycryptodome_raw_lib("Cryptodome.Hash._SHA1", + """ + #define SHA1_DIGEST_SIZE 20 + + int SHA1_init(void **shaState); + int SHA1_destroy(void *shaState); + int SHA1_update(void *hs, + const uint8_t *buf, + size_t len); + int SHA1_digest(const void *shaState, + uint8_t digest[SHA1_DIGEST_SIZE]); + int SHA1_copy(const void *src, void *dst); + + int SHA1_pbkdf2_hmac_assist(const void *inner, + const void *outer, + const uint8_t first_digest[SHA1_DIGEST_SIZE], + uint8_t final_digest[SHA1_DIGEST_SIZE], + size_t iterations); + """) + +class SHA1Hash(object): + """A SHA-1 hash object. + Do not instantiate directly. + Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + + :ivar block_size: the size in bytes of the internal message block, + input to the compression function + :vartype block_size: integer + + :ivar digest_size: the size in bytes of the resulting hash + :vartype digest_size: integer + """ + + # The size of the resulting hash in bytes. + digest_size = 20 + # The internal block size of the hash algorithm in bytes. + block_size = 64 + # ASN.1 Object ID + oid = "1.3.14.3.2.26" + + def __init__(self, data=None): + state = VoidPointer() + result = _raw_sha1_lib.SHA1_init(state.address_of()) + if result: + raise ValueError("Error %d while instantiating SHA1" + % result) + self._state = SmartPointer(state.get(), + _raw_sha1_lib.SHA1_destroy) + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + result = _raw_sha1_lib.SHA1_update(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while instantiating SHA1" + % result) + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + bfr = create_string_buffer(self.digest_size) + result = _raw_sha1_lib.SHA1_digest(self._state.get(), + bfr) + if result: + raise ValueError("Error %d while instantiating SHA1" + % result) + + return get_raw_buffer(bfr) + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in self.digest()]) + + 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 + """ + + clone = SHA1Hash() + result = _raw_sha1_lib.SHA1_copy(self._state.get(), + clone._state.get()) + if result: + raise ValueError("Error %d while copying SHA1" % result) + return clone + + def new(self, data=None): + """Create a fresh SHA-1 hash object.""" + + return SHA1Hash(data) + + +def new(data=None): + """Create a new hash object. + + :parameter data: + Optional. The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`SHA1Hash.update`. + :type data: byte string/byte array/memoryview + + :Return: A :class:`SHA1Hash` hash 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 + + +def _pbkdf2_hmac_assist(inner, outer, first_digest, iterations): + """Compute the expensive inner loop in PBKDF-HMAC.""" + + assert len(first_digest) == digest_size + assert iterations > 0 + + bfr = create_string_buffer(digest_size); + result = _raw_sha1_lib.SHA1_pbkdf2_hmac_assist( + inner._state.get(), + outer._state.get(), + first_digest, + bfr, + c_size_t(iterations)) + + if result: + raise ValueError("Error %d with PBKDF2-HMAC assis for SHA1" % result) + + return get_raw_buffer(bfr) diff --git a/frozen_deps/Cryptodome/Hash/SHA1.pyi b/frozen_deps/Cryptodome/Hash/SHA1.pyi new file mode 100644 index 0000000..d6c8e25 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA1.pyi @@ -0,0 +1,19 @@ +from typing import Union, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +class SHA1Hash(object): + digest_size: int + block_size: int + oid: str + + def __init__(self, data: Optional[Buffer] = ...) -> None: ... + def update(self, data: Buffer) -> None: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def copy(self) -> SHA1Hash: ... + def new(self, data: Optional[Buffer] = ...) -> SHA1Hash: ... + +def new(data: Optional[Buffer] = ...) -> SHA1Hash: ... +digest_size: int +block_size: int diff --git a/frozen_deps/Cryptodome/Hash/SHA224.py b/frozen_deps/Cryptodome/Hash/SHA224.py new file mode 100644 index 0000000..fca7622 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA224.py @@ -0,0 +1,186 @@ +# -*- 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 Cryptodome.Util.py3compat import bord + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +_raw_sha224_lib = load_pycryptodome_raw_lib("Cryptodome.Hash._SHA224", + """ + int SHA224_init(void **shaState); + int SHA224_destroy(void *shaState); + int SHA224_update(void *hs, + const uint8_t *buf, + size_t len); + int SHA224_digest(const void *shaState, + uint8_t *digest, + size_t digest_size); + int SHA224_copy(const void *src, void *dst); + + int SHA224_pbkdf2_hmac_assist(const void *inner, + const void *outer, + const uint8_t *first_digest, + uint8_t *final_digest, + size_t iterations, + size_t digest_size); + """) + +class SHA224Hash(object): + """A SHA-224 hash object. + Do not instantiate directly. + Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + + :ivar block_size: the size in bytes of the internal message block, + input to the compression function + :vartype block_size: integer + + :ivar digest_size: the size in bytes of the resulting hash + :vartype digest_size: integer + """ + + # The size of the resulting hash in bytes. + digest_size = 28 + # The internal block size of the hash algorithm in bytes. + block_size = 64 + # ASN.1 Object ID + oid = '2.16.840.1.101.3.4.2.4' + + def __init__(self, data=None): + state = VoidPointer() + result = _raw_sha224_lib.SHA224_init(state.address_of()) + if result: + raise ValueError("Error %d while instantiating SHA224" + % result) + self._state = SmartPointer(state.get(), + _raw_sha224_lib.SHA224_destroy) + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + result = _raw_sha224_lib.SHA224_update(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while hashing data with SHA224" + % result) + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + bfr = create_string_buffer(self.digest_size) + result = _raw_sha224_lib.SHA224_digest(self._state.get(), + bfr, + c_size_t(self.digest_size)) + if result: + raise ValueError("Error %d while making SHA224 digest" + % result) + + return get_raw_buffer(bfr) + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in self.digest()]) + + 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 + """ + + clone = SHA224Hash() + result = _raw_sha224_lib.SHA224_copy(self._state.get(), + clone._state.get()) + if result: + raise ValueError("Error %d while copying SHA224" % result) + return clone + + def new(self, data=None): + """Create a fresh SHA-224 hash object.""" + + return SHA224Hash(data) + + +def new(data=None): + """Create a new hash object. + + :parameter data: + Optional. The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`SHA224Hash.update`. + :type data: byte string/byte array/memoryview + + :Return: A :class:`SHA224Hash` hash 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 + + +def _pbkdf2_hmac_assist(inner, outer, first_digest, iterations): + """Compute the expensive inner loop in PBKDF-HMAC.""" + + assert iterations > 0 + + bfr = create_string_buffer(len(first_digest)); + result = _raw_sha224_lib.SHA224_pbkdf2_hmac_assist( + inner._state.get(), + outer._state.get(), + first_digest, + bfr, + c_size_t(iterations), + c_size_t(len(first_digest))) + + if result: + raise ValueError("Error %d with PBKDF2-HMAC assist for SHA224" % result) + + return get_raw_buffer(bfr) diff --git a/frozen_deps/Cryptodome/Hash/SHA224.pyi b/frozen_deps/Cryptodome/Hash/SHA224.pyi new file mode 100644 index 0000000..613a7f9 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA224.pyi @@ -0,0 +1,19 @@ +from typing import Union, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +class SHA224Hash(object): + digest_size: int + block_size: int + oid: str + + def __init__(self, data: Optional[Buffer] = ...) -> None: ... + def update(self, data: Buffer) -> None: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def copy(self) -> SHA224Hash: ... + def new(self, data: Optional[Buffer] = ...) -> SHA224Hash: ... + +def new(data: Optional[Buffer] = ...) -> SHA224Hash: ... +digest_size: int +block_size: int diff --git a/frozen_deps/Cryptodome/Hash/SHA256.py b/frozen_deps/Cryptodome/Hash/SHA256.py new file mode 100644 index 0000000..c1a81b1 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA256.py @@ -0,0 +1,185 @@ +# -*- 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 Cryptodome.Util.py3compat import bord + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +_raw_sha256_lib = load_pycryptodome_raw_lib("Cryptodome.Hash._SHA256", + """ + int SHA256_init(void **shaState); + int SHA256_destroy(void *shaState); + int SHA256_update(void *hs, + const uint8_t *buf, + size_t len); + int SHA256_digest(const void *shaState, + uint8_t *digest, + size_t digest_size); + int SHA256_copy(const void *src, void *dst); + + int SHA256_pbkdf2_hmac_assist(const void *inner, + const void *outer, + const uint8_t *first_digest, + uint8_t *final_digest, + size_t iterations, + size_t digest_size); + """) + +class SHA256Hash(object): + """A SHA-256 hash object. + Do not instantiate directly. Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + + :ivar block_size: the size in bytes of the internal message block, + input to the compression function + :vartype block_size: integer + + :ivar digest_size: the size in bytes of the resulting hash + :vartype digest_size: integer + """ + + # The size of the resulting hash in bytes. + digest_size = 32 + # The internal block size of the hash algorithm in bytes. + block_size = 64 + # ASN.1 Object ID + oid = "2.16.840.1.101.3.4.2.1" + + def __init__(self, data=None): + state = VoidPointer() + result = _raw_sha256_lib.SHA256_init(state.address_of()) + if result: + raise ValueError("Error %d while instantiating SHA256" + % result) + self._state = SmartPointer(state.get(), + _raw_sha256_lib.SHA256_destroy) + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + result = _raw_sha256_lib.SHA256_update(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while hashing data with SHA256" + % result) + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + bfr = create_string_buffer(self.digest_size) + result = _raw_sha256_lib.SHA256_digest(self._state.get(), + bfr, + c_size_t(self.digest_size)) + if result: + raise ValueError("Error %d while making SHA256 digest" + % result) + + return get_raw_buffer(bfr) + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in self.digest()]) + + 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 + """ + + clone = SHA256Hash() + result = _raw_sha256_lib.SHA256_copy(self._state.get(), + clone._state.get()) + if result: + raise ValueError("Error %d while copying SHA256" % result) + return clone + + def new(self, data=None): + """Create a fresh SHA-256 hash object.""" + + return SHA256Hash(data) + +def new(data=None): + """Create a new hash object. + + :parameter data: + Optional. The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`SHA256Hash.update`. + :type data: byte string/byte array/memoryview + + :Return: A :class:`SHA256Hash` hash 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 + + +def _pbkdf2_hmac_assist(inner, outer, first_digest, iterations): + """Compute the expensive inner loop in PBKDF-HMAC.""" + + assert iterations > 0 + + bfr = create_string_buffer(len(first_digest)); + result = _raw_sha256_lib.SHA256_pbkdf2_hmac_assist( + inner._state.get(), + outer._state.get(), + first_digest, + bfr, + c_size_t(iterations), + c_size_t(len(first_digest))) + + if result: + raise ValueError("Error %d with PBKDF2-HMAC assist for SHA256" % result) + + return get_raw_buffer(bfr) diff --git a/frozen_deps/Cryptodome/Hash/SHA256.pyi b/frozen_deps/Cryptodome/Hash/SHA256.pyi new file mode 100644 index 0000000..cbf21bf --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA256.pyi @@ -0,0 +1,18 @@ +from typing import Union, Optional + + +class SHA256Hash(object): + digest_size: int + block_size: int + oid: str + def __init__(self, data: Optional[Union[bytes, bytearray, memoryview]]=None) -> None: ... + def update(self, data: Union[bytes, bytearray, memoryview]) -> None: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def copy(self) -> SHA256Hash: ... + def new(self, data: Optional[Union[bytes, bytearray, memoryview]]=None) -> SHA256Hash: ... + +def new(data: Optional[Union[bytes, bytearray, memoryview]]=None) -> SHA256Hash: ... + +digest_size: int +block_size: int diff --git a/frozen_deps/Cryptodome/Hash/SHA384.py b/frozen_deps/Cryptodome/Hash/SHA384.py new file mode 100644 index 0000000..711aa73 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA384.py @@ -0,0 +1,186 @@ +# -*- 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 Cryptodome.Util.py3compat import bord + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +_raw_sha384_lib = load_pycryptodome_raw_lib("Cryptodome.Hash._SHA384", + """ + int SHA384_init(void **shaState); + int SHA384_destroy(void *shaState); + int SHA384_update(void *hs, + const uint8_t *buf, + size_t len); + int SHA384_digest(const void *shaState, + uint8_t *digest, + size_t digest_size); + int SHA384_copy(const void *src, void *dst); + + int SHA384_pbkdf2_hmac_assist(const void *inner, + const void *outer, + const uint8_t *first_digest, + uint8_t *final_digest, + size_t iterations, + size_t digest_size); + """) + +class SHA384Hash(object): + """A SHA-384 hash object. + Do not instantiate directly. Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + + :ivar block_size: the size in bytes of the internal message block, + input to the compression function + :vartype block_size: integer + + :ivar digest_size: the size in bytes of the resulting hash + :vartype digest_size: integer + """ + + # The size of the resulting hash in bytes. + digest_size = 48 + # The internal block size of the hash algorithm in bytes. + block_size = 128 + # ASN.1 Object ID + oid = '2.16.840.1.101.3.4.2.2' + + def __init__(self, data=None): + state = VoidPointer() + result = _raw_sha384_lib.SHA384_init(state.address_of()) + if result: + raise ValueError("Error %d while instantiating SHA384" + % result) + self._state = SmartPointer(state.get(), + _raw_sha384_lib.SHA384_destroy) + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + result = _raw_sha384_lib.SHA384_update(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while hashing data with SHA384" + % result) + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + bfr = create_string_buffer(self.digest_size) + result = _raw_sha384_lib.SHA384_digest(self._state.get(), + bfr, + c_size_t(self.digest_size)) + if result: + raise ValueError("Error %d while making SHA384 digest" + % result) + + return get_raw_buffer(bfr) + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in self.digest()]) + + 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 + """ + + clone = SHA384Hash() + result = _raw_sha384_lib.SHA384_copy(self._state.get(), + clone._state.get()) + if result: + raise ValueError("Error %d while copying SHA384" % result) + return clone + + def new(self, data=None): + """Create a fresh SHA-384 hash object.""" + + return SHA384Hash(data) + + +def new(data=None): + """Create a new hash object. + + :parameter data: + Optional. The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`SHA384Hash.update`. + :type data: byte string/byte array/memoryview + + :Return: A :class:`SHA384Hash` hash 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 + + +def _pbkdf2_hmac_assist(inner, outer, first_digest, iterations): + """Compute the expensive inner loop in PBKDF-HMAC.""" + + assert iterations > 0 + + bfr = create_string_buffer(len(first_digest)); + result = _raw_sha384_lib.SHA384_pbkdf2_hmac_assist( + inner._state.get(), + outer._state.get(), + first_digest, + bfr, + c_size_t(iterations), + c_size_t(len(first_digest))) + + if result: + raise ValueError("Error %d with PBKDF2-HMAC assist for SHA384" % result) + + return get_raw_buffer(bfr) diff --git a/frozen_deps/Cryptodome/Hash/SHA384.pyi b/frozen_deps/Cryptodome/Hash/SHA384.pyi new file mode 100644 index 0000000..c2aab9e --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA384.pyi @@ -0,0 +1,19 @@ +from typing import Union, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +class SHA384Hash(object): + digest_size: int + block_size: int + oid: str + + def __init__(self, data: Optional[Buffer] = ...) -> None: ... + def update(self, data: Buffer) -> None: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def copy(self) -> SHA384Hash: ... + def new(self, data: Optional[Buffer] = ...) -> SHA384Hash: ... + +def new(data: Optional[Buffer] = ...) -> SHA384Hash: ... +digest_size: int +block_size: int diff --git a/frozen_deps/Cryptodome/Hash/SHA3_224.py b/frozen_deps/Cryptodome/Hash/SHA3_224.py new file mode 100644 index 0000000..3196bd6 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA3_224.py @@ -0,0 +1,147 @@ +# -*- 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 Cryptodome.Util.py3compat import bord + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +from Cryptodome.Hash.keccak import _raw_keccak_lib + +class SHA3_224_Hash(object): + """A SHA3-224 hash object. + Do not instantiate directly. + Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + + :ivar digest_size: the size in bytes of the resulting hash + :vartype digest_size: integer + """ + + # The size of the resulting hash in bytes. + digest_size = 28 + + # ASN.1 Object ID + oid = "2.16.840.1.101.3.4.2.7" + + def __init__(self, data, update_after_digest): + self._update_after_digest = update_after_digest + self._digest_done = False + + state = VoidPointer() + result = _raw_keccak_lib.keccak_init(state.address_of(), + c_size_t(self.digest_size * 2), + 0x06) + if result: + raise ValueError("Error %d while instantiating SHA-3/224" + % result) + self._state = SmartPointer(state.get(), + _raw_keccak_lib.keccak_destroy) + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + if self._digest_done and not self._update_after_digest: + raise TypeError("You can only call 'digest' or 'hexdigest' on this object") + + result = _raw_keccak_lib.keccak_absorb(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while updating SHA-3/224" + % result) + return self + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + self._digest_done = True + + bfr = create_string_buffer(self.digest_size) + result = _raw_keccak_lib.keccak_digest(self._state.get(), + bfr, + c_size_t(self.digest_size)) + if result: + raise ValueError("Error %d while instantiating SHA-3/224" + % result) + + self._digest_value = get_raw_buffer(bfr) + return self._digest_value + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in self.digest()]) + + def new(self): + """Create a fresh SHA3-224 hash object.""" + + return type(self)(None, self._update_after_digest) + + +def new(*args, **kwargs): + """Create a new hash object. + + Args: + data (byte string/byte array/memoryview): + The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`update`. + update_after_digest (boolean): + Whether :meth:`digest` can be followed by another :meth:`update` + (default: ``False``). + + :Return: A :class:`SHA3_224_Hash` hash object + """ + + data = kwargs.pop("data", None) + update_after_digest = kwargs.pop("update_after_digest", False) + if len(args) == 1: + if data: + raise ValueError("Initial data for hash specified twice") + data = args[0] + + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + return SHA3_224_Hash(data, update_after_digest) + +# The size of the resulting hash in bytes. +digest_size = SHA3_224_Hash.digest_size diff --git a/frozen_deps/Cryptodome/Hash/SHA3_224.pyi b/frozen_deps/Cryptodome/Hash/SHA3_224.pyi new file mode 100644 index 0000000..3437042 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA3_224.pyi @@ -0,0 +1,16 @@ +from typing import Union, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +class SHA3_224_Hash(object): + digest_size: int + oid: str + def __init__(self, data: Optional[Buffer], update_after_digest: bool) -> None: ... + def update(self, data: Buffer) -> SHA3_224_Hash: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def new(self) -> SHA3_224_Hash: ... + +def new(__data: Buffer = ..., update_after_digest: bool = ...) -> SHA3_224_Hash: ... + +digest_size: int diff --git a/frozen_deps/Cryptodome/Hash/SHA3_256.py b/frozen_deps/Cryptodome/Hash/SHA3_256.py new file mode 100644 index 0000000..89e3b42 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA3_256.py @@ -0,0 +1,147 @@ +# -*- 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 Cryptodome.Util.py3compat import bord + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +from Cryptodome.Hash.keccak import _raw_keccak_lib + +class SHA3_256_Hash(object): + """A SHA3-256 hash object. + Do not instantiate directly. + Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + + :ivar digest_size: the size in bytes of the resulting hash + :vartype digest_size: integer + """ + + # The size of the resulting hash in bytes. + digest_size = 32 + + # ASN.1 Object ID + oid = "2.16.840.1.101.3.4.2.8" + + def __init__(self, data, update_after_digest): + self._update_after_digest = update_after_digest + self._digest_done = False + + state = VoidPointer() + result = _raw_keccak_lib.keccak_init(state.address_of(), + c_size_t(self.digest_size * 2), + 0x06) + if result: + raise ValueError("Error %d while instantiating SHA-3/256" + % result) + self._state = SmartPointer(state.get(), + _raw_keccak_lib.keccak_destroy) + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + if self._digest_done and not self._update_after_digest: + raise TypeError("You can only call 'digest' or 'hexdigest' on this object") + + result = _raw_keccak_lib.keccak_absorb(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while updating SHA-3/256" + % result) + return self + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + self._digest_done = True + + bfr = create_string_buffer(self.digest_size) + result = _raw_keccak_lib.keccak_digest(self._state.get(), + bfr, + c_size_t(self.digest_size)) + if result: + raise ValueError("Error %d while instantiating SHA-3/256" + % result) + + self._digest_value = get_raw_buffer(bfr) + return self._digest_value + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in self.digest()]) + + def new(self): + """Create a fresh SHA3-256 hash object.""" + + return type(self)(None, self._update_after_digest) + + +def new(*args, **kwargs): + """Create a new hash object. + + Args: + data (byte string/byte array/memoryview): + The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`update`. + update_after_digest (boolean): + Whether :meth:`digest` can be followed by another :meth:`update` + (default: ``False``). + + :Return: A :class:`SHA3_256_Hash` hash object + """ + + data = kwargs.pop("data", None) + update_after_digest = kwargs.pop("update_after_digest", False) + if len(args) == 1: + if data: + raise ValueError("Initial data for hash specified twice") + data = args[0] + + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + return SHA3_256_Hash(data, update_after_digest) + +# The size of the resulting hash in bytes. +digest_size = SHA3_256_Hash.digest_size diff --git a/frozen_deps/Cryptodome/Hash/SHA3_256.pyi b/frozen_deps/Cryptodome/Hash/SHA3_256.pyi new file mode 100644 index 0000000..c1a07fa --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA3_256.pyi @@ -0,0 +1,16 @@ +from typing import Union, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +class SHA3_256_Hash(object): + digest_size: int + oid: str + def __init__(self, data: Optional[Buffer], update_after_digest: bool) -> None: ... + def update(self, data: Buffer) -> SHA3_256_Hash: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def new(self) -> SHA3_256_Hash: ... + +def new(__data: Buffer = ..., update_after_digest: bool = ...) -> SHA3_256_Hash: ... + +digest_size: int diff --git a/frozen_deps/Cryptodome/Hash/SHA3_384.py b/frozen_deps/Cryptodome/Hash/SHA3_384.py new file mode 100644 index 0000000..e6baf3f --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA3_384.py @@ -0,0 +1,147 @@ +# -*- 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 Cryptodome.Util.py3compat import bord + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +from Cryptodome.Hash.keccak import _raw_keccak_lib + +class SHA3_384_Hash(object): + """A SHA3-384 hash object. + Do not instantiate directly. + Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + + :ivar digest_size: the size in bytes of the resulting hash + :vartype digest_size: integer + """ + + # The size of the resulting hash in bytes. + digest_size = 48 + + # ASN.1 Object ID + oid = "2.16.840.1.101.3.4.2.9" + + def __init__(self, data, update_after_digest): + self._update_after_digest = update_after_digest + self._digest_done = False + + state = VoidPointer() + result = _raw_keccak_lib.keccak_init(state.address_of(), + c_size_t(self.digest_size * 2), + 0x06) + if result: + raise ValueError("Error %d while instantiating SHA-3/384" + % result) + self._state = SmartPointer(state.get(), + _raw_keccak_lib.keccak_destroy) + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + if self._digest_done and not self._update_after_digest: + raise TypeError("You can only call 'digest' or 'hexdigest' on this object") + + result = _raw_keccak_lib.keccak_absorb(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while updating SHA-3/384" + % result) + return self + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + self._digest_done = True + + bfr = create_string_buffer(self.digest_size) + result = _raw_keccak_lib.keccak_digest(self._state.get(), + bfr, + c_size_t(self.digest_size)) + if result: + raise ValueError("Error %d while instantiating SHA-3/384" + % result) + + self._digest_value = get_raw_buffer(bfr) + return self._digest_value + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in self.digest()]) + + def new(self): + """Create a fresh SHA3-384 hash object.""" + + return type(self)(None, self._update_after_digest) + + +def new(*args, **kwargs): + """Create a new hash object. + + Args: + data (byte string/byte array/memoryview): + The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`update`. + update_after_digest (boolean): + Whether :meth:`digest` can be followed by another :meth:`update` + (default: ``False``). + + :Return: A :class:`SHA3_384_Hash` hash object + """ + + data = kwargs.pop("data", None) + update_after_digest = kwargs.pop("update_after_digest", False) + if len(args) == 1: + if data: + raise ValueError("Initial data for hash specified twice") + data = args[0] + + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + return SHA3_384_Hash(data, update_after_digest) + +# The size of the resulting hash in bytes. +digest_size = SHA3_384_Hash.digest_size diff --git a/frozen_deps/Cryptodome/Hash/SHA3_384.pyi b/frozen_deps/Cryptodome/Hash/SHA3_384.pyi new file mode 100644 index 0000000..d029ab6 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA3_384.pyi @@ -0,0 +1,16 @@ +from typing import Union, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +class SHA3_384_Hash(object): + digest_size: int + oid: str + def __init__(self, data: Optional[Buffer], update_after_digest: bool) -> None: ... + def update(self, data: Buffer) -> SHA3_384_Hash: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def new(self) -> SHA3_384_Hash: ... + +def new(__data: Buffer = ..., update_after_digest: bool = ...) -> SHA3_384_Hash: ... + +digest_size: int diff --git a/frozen_deps/Cryptodome/Hash/SHA3_512.py b/frozen_deps/Cryptodome/Hash/SHA3_512.py new file mode 100644 index 0000000..676ce2f --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA3_512.py @@ -0,0 +1,148 @@ +# -*- 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 Cryptodome.Util.py3compat import bord + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +from Cryptodome.Hash.keccak import _raw_keccak_lib + +class SHA3_512_Hash(object): + """A SHA3-512 hash object. + Do not instantiate directly. + Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + + :ivar digest_size: the size in bytes of the resulting hash + :vartype digest_size: integer + """ + + # The size of the resulting hash in bytes. + digest_size = 64 + + # ASN.1 Object ID + oid = "2.16.840.1.101.3.4.2.10" + + def __init__(self, data, update_after_digest): + self._update_after_digest = update_after_digest + self._digest_done = False + + state = VoidPointer() + result = _raw_keccak_lib.keccak_init(state.address_of(), + c_size_t(self.digest_size * 2), + 0x06) + if result: + raise ValueError("Error %d while instantiating SHA-3/512" + % result) + self._state = SmartPointer(state.get(), + _raw_keccak_lib.keccak_destroy) + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + if self._digest_done and not self._update_after_digest: + raise TypeError("You can only call 'digest' or 'hexdigest' on this object") + + result = _raw_keccak_lib.keccak_absorb(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while updating SHA-3/512" + % result) + return self + + def digest(self): + + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + self._digest_done = True + + bfr = create_string_buffer(self.digest_size) + result = _raw_keccak_lib.keccak_digest(self._state.get(), + bfr, + c_size_t(self.digest_size)) + if result: + raise ValueError("Error %d while instantiating SHA-3/512" + % result) + + self._digest_value = get_raw_buffer(bfr) + return self._digest_value + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in self.digest()]) + + def new(self): + """Create a fresh SHA3-512 hash object.""" + + return type(self)(None, self._update_after_digest) + + +def new(*args, **kwargs): + """Create a new hash object. + + Args: + data (byte string/byte array/memoryview): + The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`update`. + update_after_digest (boolean): + Whether :meth:`digest` can be followed by another :meth:`update` + (default: ``False``). + + :Return: A :class:`SHA3_512_Hash` hash object + """ + + data = kwargs.pop("data", None) + update_after_digest = kwargs.pop("update_after_digest", False) + if len(args) == 1: + if data: + raise ValueError("Initial data for hash specified twice") + data = args[0] + + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + return SHA3_512_Hash(data, update_after_digest) + +# The size of the resulting hash in bytes. +digest_size = SHA3_512_Hash.digest_size diff --git a/frozen_deps/Cryptodome/Hash/SHA3_512.pyi b/frozen_deps/Cryptodome/Hash/SHA3_512.pyi new file mode 100644 index 0000000..2c5403b --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA3_512.pyi @@ -0,0 +1,16 @@ +from typing import Union, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +class SHA3_512_Hash(object): + digest_size: int + oid: str + def __init__(self, data: Optional[Buffer], update_after_digest: bool) -> None: ... + def update(self, data: Buffer) -> SHA3_512_Hash: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def new(self) -> SHA3_512_Hash: ... + +def new(__data: Buffer = ..., update_after_digest: bool = ...) -> SHA3_512_Hash: ... + +digest_size: int diff --git a/frozen_deps/Cryptodome/Hash/SHA512.py b/frozen_deps/Cryptodome/Hash/SHA512.py new file mode 100644 index 0000000..5066197 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA512.py @@ -0,0 +1,204 @@ +# -*- 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 Cryptodome.Util.py3compat import bord + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +_raw_sha512_lib = load_pycryptodome_raw_lib("Cryptodome.Hash._SHA512", + """ + int SHA512_init(void **shaState, + size_t digest_size); + int SHA512_destroy(void *shaState); + int SHA512_update(void *hs, + const uint8_t *buf, + size_t len); + int SHA512_digest(const void *shaState, + uint8_t *digest, + size_t digest_size); + int SHA512_copy(const void *src, void *dst); + + int SHA512_pbkdf2_hmac_assist(const void *inner, + const void *outer, + const uint8_t *first_digest, + uint8_t *final_digest, + size_t iterations, + size_t digest_size); + """) + +class SHA512Hash(object): + """A SHA-512 hash object (possibly in its truncated version SHA-512/224 or + SHA-512/256. + Do not instantiate directly. Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + + :ivar block_size: the size in bytes of the internal message block, + input to the compression function + :vartype block_size: integer + + :ivar digest_size: the size in bytes of the resulting hash + :vartype digest_size: integer + """ + + # The internal block size of the hash algorithm in bytes. + block_size = 128 + + def __init__(self, data, truncate): + self._truncate = truncate + + if truncate is None: + self.oid = "2.16.840.1.101.3.4.2.3" + self.digest_size = 64 + elif truncate == "224": + self.oid = "2.16.840.1.101.3.4.2.5" + self.digest_size = 28 + elif truncate == "256": + self.oid = "2.16.840.1.101.3.4.2.6" + self.digest_size = 32 + else: + raise ValueError("Incorrect truncation length. It must be '224' or '256'.") + + state = VoidPointer() + result = _raw_sha512_lib.SHA512_init(state.address_of(), + c_size_t(self.digest_size)) + if result: + raise ValueError("Error %d while instantiating SHA-512" + % result) + self._state = SmartPointer(state.get(), + _raw_sha512_lib.SHA512_destroy) + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + result = _raw_sha512_lib.SHA512_update(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while hashing data with SHA512" + % result) + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + bfr = create_string_buffer(self.digest_size) + result = _raw_sha512_lib.SHA512_digest(self._state.get(), + bfr, + c_size_t(self.digest_size)) + if result: + raise ValueError("Error %d while making SHA512 digest" + % result) + + return get_raw_buffer(bfr) + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in self.digest()]) + + 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 + """ + + clone = SHA512Hash(None, self._truncate) + result = _raw_sha512_lib.SHA512_copy(self._state.get(), + clone._state.get()) + if result: + raise ValueError("Error %d while copying SHA512" % result) + return clone + + def new(self, data=None): + """Create a fresh SHA-512 hash object.""" + + return SHA512Hash(data, self._truncate) + + +def new(data=None, truncate=None): + """Create a new hash object. + + Args: + data (bytes/bytearray/memoryview): + Optional. The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`SHA512Hash.update`. + truncate (string): + Optional. The desired length of the digest. It can be either "224" or + "256". If not present, the digest is 512 bits long. + Passing this parameter is **not** equivalent to simply truncating + the output digest. + + :Return: A :class:`SHA512Hash` hash object + """ + + return SHA512Hash(data, truncate) + + +# The size of the full SHA-512 hash in bytes. +digest_size = 64 + +# The internal block size of the hash algorithm in bytes. +block_size = 128 + + +def _pbkdf2_hmac_assist(inner, outer, first_digest, iterations): + """Compute the expensive inner loop in PBKDF-HMAC.""" + + assert iterations > 0 + + bfr = create_string_buffer(len(first_digest)); + result = _raw_sha512_lib.SHA512_pbkdf2_hmac_assist( + inner._state.get(), + outer._state.get(), + first_digest, + bfr, + c_size_t(iterations), + c_size_t(len(first_digest))) + + if result: + raise ValueError("Error %d with PBKDF2-HMAC assist for SHA512" % result) + + return get_raw_buffer(bfr) diff --git a/frozen_deps/Cryptodome/Hash/SHA512.pyi b/frozen_deps/Cryptodome/Hash/SHA512.pyi new file mode 100644 index 0000000..f219ee9 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHA512.pyi @@ -0,0 +1,22 @@ +from typing import Union, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +class SHA512Hash(object): + digest_size: int + block_size: int + oid: str + + def __init__(self, + data: Optional[Buffer], + truncate: Optional[str]) -> None: ... + def update(self, data: Buffer) -> None: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def copy(self) -> SHA512Hash: ... + def new(self, data: Optional[Buffer] = ...) -> SHA512Hash: ... + +def new(data: Optional[Buffer] = ..., + truncate: Optional[str] = ...) -> SHA512Hash: ... +digest_size: int +block_size: int diff --git a/frozen_deps/Cryptodome/Hash/SHAKE128.py b/frozen_deps/Cryptodome/Hash/SHAKE128.py new file mode 100644 index 0000000..be2b22e --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHAKE128.py @@ -0,0 +1,127 @@ +# =================================================================== +# +# Copyright (c) 2015, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Util.py3compat import bord + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +from Cryptodome.Hash.keccak import _raw_keccak_lib + +class SHAKE128_XOF(object): + """A SHAKE128 hash object. + Do not instantiate directly. + Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + """ + + # ASN.1 Object ID + oid = "2.16.840.1.101.3.4.2.11" + + def __init__(self, data=None): + state = VoidPointer() + result = _raw_keccak_lib.keccak_init(state.address_of(), + c_size_t(32), + 0x1F) + if result: + raise ValueError("Error %d while instantiating SHAKE128" + % result) + self._state = SmartPointer(state.get(), + _raw_keccak_lib.keccak_destroy) + self._is_squeezing = False + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + if self._is_squeezing: + raise TypeError("You cannot call 'update' after the first 'read'") + + result = _raw_keccak_lib.keccak_absorb(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while updating SHAKE128 state" + % result) + return self + + def read(self, length): + """ + Compute the next piece of XOF output. + + .. note:: + You cannot use :meth:`update` anymore after the first call to + :meth:`read`. + + Args: + length (integer): the amount of bytes this method must return + + :return: the next piece of XOF output (of the given length) + :rtype: byte string + """ + + self._is_squeezing = True + bfr = create_string_buffer(length) + result = _raw_keccak_lib.keccak_squeeze(self._state.get(), + bfr, + c_size_t(length)) + if result: + raise ValueError("Error %d while extracting from SHAKE128" + % result) + + return get_raw_buffer(bfr) + + def new(self, data=None): + return type(self)(data=data) + + +def new(data=None): + """Return a fresh instance of a SHAKE128 object. + + Args: + data (bytes/bytearray/memoryview): + The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`update`. + Optional. + + :Return: A :class:`SHAKE128_XOF` object + """ + + return SHAKE128_XOF(data=data) diff --git a/frozen_deps/Cryptodome/Hash/SHAKE128.pyi b/frozen_deps/Cryptodome/Hash/SHAKE128.pyi new file mode 100644 index 0000000..f618881 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHAKE128.pyi @@ -0,0 +1,13 @@ +from typing import Union, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +class SHAKE128_XOF(object): + oid: str + def __init__(self, + data: Optional[Buffer] = ...) -> None: ... + def update(self, data: Buffer) -> SHAKE128_XOF: ... + def read(self, length: int) -> bytes: ... + def new(self, data: Optional[Buffer] = ...) -> SHAKE128_XOF: ... + +def new(data: Optional[Buffer] = ...) -> SHAKE128_XOF: ... diff --git a/frozen_deps/Cryptodome/Hash/SHAKE256.py b/frozen_deps/Cryptodome/Hash/SHAKE256.py new file mode 100644 index 0000000..46040e1 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHAKE256.py @@ -0,0 +1,127 @@ +# =================================================================== +# +# Copyright (c) 2015, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Util.py3compat import bord + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +from Cryptodome.Hash.keccak import _raw_keccak_lib + +class SHAKE256_XOF(object): + """A SHAKE256 hash object. + Do not instantiate directly. + Use the :func:`new` function. + + :ivar oid: ASN.1 Object ID + :vartype oid: string + """ + + # ASN.1 Object ID + oid = "2.16.840.1.101.3.4.2.12" + + def __init__(self, data=None): + state = VoidPointer() + result = _raw_keccak_lib.keccak_init(state.address_of(), + c_size_t(64), + 0x1F) + if result: + raise ValueError("Error %d while instantiating SHAKE256" + % result) + self._state = SmartPointer(state.get(), + _raw_keccak_lib.keccak_destroy) + self._is_squeezing = False + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + if self._is_squeezing: + raise TypeError("You cannot call 'update' after the first 'read'") + + result = _raw_keccak_lib.keccak_absorb(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while updating SHAKE256 state" + % result) + return self + + def read(self, length): + """ + Compute the next piece of XOF output. + + .. note:: + You cannot use :meth:`update` anymore after the first call to + :meth:`read`. + + Args: + length (integer): the amount of bytes this method must return + + :return: the next piece of XOF output (of the given length) + :rtype: byte string + """ + + self._is_squeezing = True + bfr = create_string_buffer(length) + result = _raw_keccak_lib.keccak_squeeze(self._state.get(), + bfr, + c_size_t(length)) + if result: + raise ValueError("Error %d while extracting from SHAKE256" + % result) + + return get_raw_buffer(bfr) + + def new(self, data=None): + return type(self)(data=data) + + +def new(data=None): + """Return a fresh instance of a SHAKE256 object. + + Args: + data (bytes/bytearray/memoryview): + The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`update`. + Optional. + + :Return: A :class:`SHAKE256_XOF` object + """ + + return SHAKE256_XOF(data=data) diff --git a/frozen_deps/Cryptodome/Hash/SHAKE256.pyi b/frozen_deps/Cryptodome/Hash/SHAKE256.pyi new file mode 100644 index 0000000..029347a --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/SHAKE256.pyi @@ -0,0 +1,13 @@ +from typing import Union, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +class SHAKE256_XOF(object): + oid: str + def __init__(self, + data: Optional[Buffer] = ...) -> None: ... + def update(self, data: Buffer) -> SHAKE256_XOF: ... + def read(self, length: int) -> bytes: ... + def new(self, data: Optional[Buffer] = ...) -> SHAKE256_XOF: ... + +def new(data: Optional[Buffer] = ...) -> SHAKE256_XOF: ... diff --git a/frozen_deps/Cryptodome/Hash/_BLAKE2b.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Hash/_BLAKE2b.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..35ee701 Binary files /dev/null and b/frozen_deps/Cryptodome/Hash/_BLAKE2b.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/_BLAKE2s.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Hash/_BLAKE2s.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..7f391c9 Binary files /dev/null and b/frozen_deps/Cryptodome/Hash/_BLAKE2s.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/_MD2.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Hash/_MD2.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..8fffa21 Binary files /dev/null and b/frozen_deps/Cryptodome/Hash/_MD2.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/_MD4.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Hash/_MD4.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..12b4c06 Binary files /dev/null and b/frozen_deps/Cryptodome/Hash/_MD4.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/_MD5.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Hash/_MD5.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..6fb6942 Binary files /dev/null and b/frozen_deps/Cryptodome/Hash/_MD5.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/_RIPEMD160.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Hash/_RIPEMD160.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..2d8928d Binary files /dev/null and b/frozen_deps/Cryptodome/Hash/_RIPEMD160.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/_SHA1.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Hash/_SHA1.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..7324a29 Binary files /dev/null and b/frozen_deps/Cryptodome/Hash/_SHA1.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/_SHA224.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Hash/_SHA224.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..c60f2ae Binary files /dev/null and b/frozen_deps/Cryptodome/Hash/_SHA224.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/_SHA256.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Hash/_SHA256.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..0b8212d Binary files /dev/null and b/frozen_deps/Cryptodome/Hash/_SHA256.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/_SHA384.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Hash/_SHA384.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..b3ef7ab Binary files /dev/null and b/frozen_deps/Cryptodome/Hash/_SHA384.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/_SHA512.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Hash/_SHA512.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..424a00b Binary files /dev/null and b/frozen_deps/Cryptodome/Hash/_SHA512.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/__init__.py b/frozen_deps/Cryptodome/Hash/__init__.py new file mode 100644 index 0000000..719cd8d --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/__init__.py @@ -0,0 +1,22 @@ +# -*- 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. +# =================================================================== + +__all__ = ['HMAC', 'MD2', 'MD4', 'MD5', 'RIPEMD160', 'SHA1', + 'SHA224', 'SHA256', 'SHA384', 'SHA512', 'CMAC', 'Poly1305'] diff --git a/frozen_deps/Cryptodome/Hash/__init__.pyi b/frozen_deps/Cryptodome/Hash/__init__.pyi new file mode 100644 index 0000000..e69de29 diff --git a/frozen_deps/Cryptodome/Hash/_ghash_clmul.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Hash/_ghash_clmul.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..c4387d7 Binary files /dev/null and b/frozen_deps/Cryptodome/Hash/_ghash_clmul.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/_ghash_portable.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Hash/_ghash_portable.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..ed1479f Binary files /dev/null and b/frozen_deps/Cryptodome/Hash/_ghash_portable.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/_keccak.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Hash/_keccak.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..074d7c4 Binary files /dev/null and b/frozen_deps/Cryptodome/Hash/_keccak.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/_poly1305.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Hash/_poly1305.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..b9ae83f Binary files /dev/null and b/frozen_deps/Cryptodome/Hash/_poly1305.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Hash/keccak.py b/frozen_deps/Cryptodome/Hash/keccak.py new file mode 100644 index 0000000..9ae8ec5 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/keccak.py @@ -0,0 +1,173 @@ +# =================================================================== +# +# Copyright (c) 2015, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Util.py3compat import bord + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr) + +_raw_keccak_lib = load_pycryptodome_raw_lib("Cryptodome.Hash._keccak", + """ + int keccak_init(void **state, + size_t capacity_bytes, + uint8_t padding_byte); + int keccak_destroy(void *state); + int keccak_absorb(void *state, + const uint8_t *in, + size_t len); + int keccak_squeeze(const void *state, + uint8_t *out, + size_t len); + int keccak_digest(void *state, uint8_t *digest, size_t len); + """) + +class Keccak_Hash(object): + """A Keccak hash object. + Do not instantiate directly. + Use the :func:`new` function. + + :ivar digest_size: the size in bytes of the resulting hash + :vartype digest_size: integer + """ + + def __init__(self, data, digest_bytes, update_after_digest): + # The size of the resulting hash in bytes. + self.digest_size = digest_bytes + + self._update_after_digest = update_after_digest + self._digest_done = False + + state = VoidPointer() + result = _raw_keccak_lib.keccak_init(state.address_of(), + c_size_t(self.digest_size * 2), + 0x01) + if result: + raise ValueError("Error %d while instantiating keccak" % result) + self._state = SmartPointer(state.get(), + _raw_keccak_lib.keccak_destroy) + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + if self._digest_done and not self._update_after_digest: + raise TypeError("You can only call 'digest' or 'hexdigest' on this object") + + result = _raw_keccak_lib.keccak_absorb(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while updating keccak" % result) + return self + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Binary form. + :rtype: byte string + """ + + self._digest_done = True + bfr = create_string_buffer(self.digest_size) + result = _raw_keccak_lib.keccak_digest(self._state.get(), + bfr, + c_size_t(self.digest_size)) + if result: + raise ValueError("Error %d while squeezing keccak" % result) + + return get_raw_buffer(bfr) + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + :return: The hash digest, computed over the data processed so far. + Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in self.digest()]) + + def new(self, **kwargs): + """Create a fresh Keccak hash object.""" + + if "digest_bytes" not in kwargs and "digest_bits" not in kwargs: + kwargs["digest_bytes"] = self.digest_size + + return new(**kwargs) + + +def new(**kwargs): + """Create a new hash object. + + Args: + data (bytes/bytearray/memoryview): + The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`Keccak_Hash.update`. + digest_bytes (integer): + The size of the digest, in bytes (28, 32, 48, 64). + digest_bits (integer): + The size of the digest, in bits (224, 256, 384, 512). + update_after_digest (boolean): + Whether :meth:`Keccak.digest` can be followed by another + :meth:`Keccak.update` (default: ``False``). + + :Return: A :class:`Keccak_Hash` hash object + """ + + data = kwargs.pop("data", None) + update_after_digest = kwargs.pop("update_after_digest", False) + + digest_bytes = kwargs.pop("digest_bytes", None) + digest_bits = kwargs.pop("digest_bits", None) + if None not in (digest_bytes, digest_bits): + raise TypeError("Only one digest parameter must be provided") + if (None, None) == (digest_bytes, digest_bits): + raise TypeError("Digest size (bits, bytes) not provided") + if digest_bytes is not None: + if digest_bytes not in (28, 32, 48, 64): + raise ValueError("'digest_bytes' must be: 28, 32, 48 or 64") + else: + if digest_bits not in (224, 256, 384, 512): + raise ValueError("'digest_bytes' must be: 224, 256, 384 or 512") + digest_bytes = digest_bits // 8 + + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + return Keccak_Hash(data, digest_bytes, update_after_digest) diff --git a/frozen_deps/Cryptodome/Hash/keccak.pyi b/frozen_deps/Cryptodome/Hash/keccak.pyi new file mode 100644 index 0000000..844d256 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/keccak.pyi @@ -0,0 +1,23 @@ +from typing import Union, Any + +Buffer = Union[bytes, bytearray, memoryview] + +class Keccak_Hash(object): + digest_size: int + def __init__(self, + data: Buffer, + digest_bytes: int, + update_after_digest: bool) -> None: ... + def update(self, data: Buffer) -> Keccak_Hash: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def new(self, + data: Buffer = ..., + digest_bytes: int = ..., + digest_bits: int = ..., + update_after_digest: bool = ...) -> Keccak_Hash: ... + +def new(data: Buffer = ..., + digest_bytes: int = ..., + digest_bits: int = ..., + update_after_digest: bool = ...) -> Keccak_Hash: ... diff --git a/frozen_deps/Cryptodome/IO/PEM.py b/frozen_deps/Cryptodome/IO/PEM.py new file mode 100644 index 0000000..7655368 --- /dev/null +++ b/frozen_deps/Cryptodome/IO/PEM.py @@ -0,0 +1,189 @@ +# +# Util/PEM.py : Privacy Enhanced Mail utilities +# +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +__all__ = ['encode', 'decode'] + +import re +from binascii import a2b_base64, b2a_base64, hexlify, unhexlify + +from Cryptodome.Hash import MD5 +from Cryptodome.Util.Padding import pad, unpad +from Cryptodome.Cipher import DES, DES3, AES +from Cryptodome.Protocol.KDF import PBKDF1 +from Cryptodome.Random import get_random_bytes +from Cryptodome.Util.py3compat import tobytes, tostr + + +def encode(data, marker, passphrase=None, randfunc=None): + """Encode a piece of binary data into PEM format. + + Args: + data (byte string): + The piece of binary data to encode. + marker (string): + The marker for the PEM block (e.g. "PUBLIC KEY"). + Note that there is no official master list for all allowed markers. + Still, you can refer to the OpenSSL_ source code. + passphrase (byte string): + If given, the PEM block will be encrypted. The key is derived from + the passphrase. + randfunc (callable): + Random number generation function; it accepts an integer N and returns + a byte string of random data, N bytes long. If not given, a new one is + instantiated. + + Returns: + The PEM block, as a string. + + .. _OpenSSL: https://github.com/openssl/openssl/blob/master/include/openssl/pem.h + """ + + if randfunc is None: + randfunc = get_random_bytes + + out = "-----BEGIN %s-----\n" % marker + if passphrase: + # We only support 3DES for encryption + salt = randfunc(8) + key = PBKDF1(passphrase, salt, 16, 1, MD5) + key += PBKDF1(key + passphrase, salt, 8, 1, MD5) + objenc = DES3.new(key, DES3.MODE_CBC, salt) + out += "Proc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,%s\n\n" %\ + tostr(hexlify(salt).upper()) + # Encrypt with PKCS#7 padding + data = objenc.encrypt(pad(data, objenc.block_size)) + elif passphrase is not None: + raise ValueError("Empty password") + + # Each BASE64 line can take up to 64 characters (=48 bytes of data) + # b2a_base64 adds a new line character! + chunks = [tostr(b2a_base64(data[i:i + 48])) + for i in range(0, len(data), 48)] + out += "".join(chunks) + out += "-----END %s-----" % marker + return out + + +def _EVP_BytesToKey(data, salt, key_len): + d = [ b'' ] + m = (key_len + 15 ) // 16 + for _ in range(m): + nd = MD5.new(d[-1] + data + salt).digest() + d.append(nd) + return b"".join(d)[:key_len] + + +def decode(pem_data, passphrase=None): + """Decode a PEM block into binary. + + Args: + pem_data (string): + The PEM block. + passphrase (byte string): + If given and the PEM block is encrypted, + the key will be derived from the passphrase. + + Returns: + A tuple with the binary data, the marker string, and a boolean to + indicate if decryption was performed. + + Raises: + ValueError: if decoding fails, if the PEM file is encrypted and no passphrase has + been provided or if the passphrase is incorrect. + """ + + # Verify Pre-Encapsulation Boundary + r = re.compile(r"\s*-----BEGIN (.*)-----\s+") + m = r.match(pem_data) + if not m: + raise ValueError("Not a valid PEM pre boundary") + marker = m.group(1) + + # Verify Post-Encapsulation Boundary + r = re.compile(r"-----END (.*)-----\s*$") + m = r.search(pem_data) + if not m or m.group(1) != marker: + raise ValueError("Not a valid PEM post boundary") + + # Removes spaces and slit on lines + lines = pem_data.replace(" ", '').split() + + # Decrypts, if necessary + if lines[1].startswith('Proc-Type:4,ENCRYPTED'): + if not passphrase: + raise ValueError("PEM is encrypted, but no passphrase available") + DEK = lines[2].split(':') + if len(DEK) != 2 or DEK[0] != 'DEK-Info': + raise ValueError("PEM encryption format not supported.") + algo, salt = DEK[1].split(',') + salt = unhexlify(tobytes(salt)) + + padding = True + + if algo == "DES-CBC": + key = _EVP_BytesToKey(passphrase, salt, 8) + objdec = DES.new(key, DES.MODE_CBC, salt) + elif algo == "DES-EDE3-CBC": + key = _EVP_BytesToKey(passphrase, salt, 24) + objdec = DES3.new(key, DES3.MODE_CBC, salt) + elif algo == "AES-128-CBC": + key = _EVP_BytesToKey(passphrase, salt[:8], 16) + objdec = AES.new(key, AES.MODE_CBC, salt) + elif algo == "AES-192-CBC": + key = _EVP_BytesToKey(passphrase, salt[:8], 24) + objdec = AES.new(key, AES.MODE_CBC, salt) + elif algo == "AES-256-CBC": + key = _EVP_BytesToKey(passphrase, salt[:8], 32) + objdec = AES.new(key, AES.MODE_CBC, salt) + elif algo.lower() == "id-aes256-gcm": + key = _EVP_BytesToKey(passphrase, salt[:8], 32) + objdec = AES.new(key, AES.MODE_GCM, nonce=salt) + padding = False + else: + raise ValueError("Unsupport PEM encryption algorithm (%s)." % algo) + lines = lines[2:] + else: + objdec = None + + # Decode body + data = a2b_base64(''.join(lines[1:-1])) + enc_flag = False + if objdec: + if padding: + data = unpad(objdec.decrypt(data), objdec.block_size) + else: + # There is no tag, so we don't use decrypt_and_verify + data = objdec.decrypt(data) + enc_flag = True + + return (data, marker, enc_flag) diff --git a/frozen_deps/Cryptodome/IO/PEM.pyi b/frozen_deps/Cryptodome/IO/PEM.pyi new file mode 100644 index 0000000..2e324c4 --- /dev/null +++ b/frozen_deps/Cryptodome/IO/PEM.pyi @@ -0,0 +1,10 @@ +from typing import Tuple, Optional, Callable + +def encode(data: bytes, + marke: str, + passphrase: Optional[bytes] = ..., + randfunc: Optional[Callable[[int],bytes]] = ...) -> str: ... + + +def decode(pem_data: str, + passphrase: Optional[bytes] = ...) -> Tuple[bytes, str, bool]: ... diff --git a/frozen_deps/Cryptodome/IO/PKCS8.py b/frozen_deps/Cryptodome/IO/PKCS8.py new file mode 100644 index 0000000..7365476 --- /dev/null +++ b/frozen_deps/Cryptodome/IO/PKCS8.py @@ -0,0 +1,231 @@ +# +# PublicKey/PKCS8.py : PKCS#8 functions +# +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + + +from Cryptodome.Util.py3compat import * + +from Cryptodome.Util.asn1 import ( + DerNull, + DerSequence, + DerObjectId, + DerOctetString, + ) + +from Cryptodome.IO._PBES import PBES1, PBES2, PbesError + + +__all__ = ['wrap', 'unwrap'] + + +def wrap(private_key, key_oid, passphrase=None, protection=None, + prot_params=None, key_params=None, randfunc=None): + """Wrap a private key into a PKCS#8 blob (clear or encrypted). + + Args: + + private_key (byte string): + The private key encoded in binary form. The actual encoding is + algorithm specific. In most cases, it is DER. + + key_oid (string): + The object identifier (OID) of the private key to wrap. + It is a dotted string, like ``1.2.840.113549.1.1.1`` (for RSA keys). + + passphrase (bytes string or string): + The secret passphrase from which the wrapping key is derived. + Set it only if encryption is required. + + protection (string): + The identifier of the algorithm to use for securely wrapping the key. + The default value is ``PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC``. + + prot_params (dictionary): + Parameters for the protection algorithm. + + +------------------+-----------------------------------------------+ + | Key | Description | + +==================+===============================================+ + | iteration_count | The KDF algorithm is repeated several times to| + | | slow down brute force attacks on passwords | + | | (called *N* or CPU/memory cost in scrypt). | + | | The default value for PBKDF2 is 1000. | + | | The default value for scrypt is 16384. | + +------------------+-----------------------------------------------+ + | salt_size | Salt is used to thwart dictionary and rainbow | + | | attacks on passwords. The default value is 8 | + | | bytes. | + +------------------+-----------------------------------------------+ + | block_size | *(scrypt only)* Memory-cost (r). The default | + | | value is 8. | + +------------------+-----------------------------------------------+ + | parallelization | *(scrypt only)* CPU-cost (p). The default | + | | value is 1. | + +------------------+-----------------------------------------------+ + + key_params (DER object): + The algorithm parameters associated to the private key. + It is required for algorithms like DSA, but not for others like RSA. + + 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 RNG will be instantiated + from :mod:`Cryptodome.Random`. + + Return: + The PKCS#8-wrapped private key (possibly encrypted), as a byte string. + """ + + if key_params is None: + key_params = DerNull() + + # + # PrivateKeyInfo ::= SEQUENCE { + # version Version, + # privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, + # privateKey PrivateKey, + # attributes [0] IMPLICIT Attributes OPTIONAL + # } + # + pk_info = DerSequence([ + 0, + DerSequence([ + DerObjectId(key_oid), + key_params + ]), + DerOctetString(private_key) + ]) + pk_info_der = pk_info.encode() + + if passphrase is None: + return pk_info_der + + if not passphrase: + raise ValueError("Empty passphrase") + + # Encryption with PBES2 + passphrase = tobytes(passphrase) + if protection is None: + protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC' + return PBES2.encrypt(pk_info_der, passphrase, + protection, prot_params, randfunc) + + +def unwrap(p8_private_key, passphrase=None): + """Unwrap a private key from a PKCS#8 blob (clear or encrypted). + + Args: + p8_private_key (byte string): + The private key wrapped into a PKCS#8 blob, DER encoded. + passphrase (byte string or string): + The passphrase to use to decrypt the blob (if it is encrypted). + + Return: + A tuple containing + + #. the algorithm identifier of the wrapped key (OID, dotted string) + #. the private key (byte string, DER encoded) + #. the associated parameters (byte string, DER encoded) or ``None`` + + Raises: + ValueError : if decoding fails + """ + + if passphrase: + passphrase = tobytes(passphrase) + + found = False + try: + p8_private_key = PBES1.decrypt(p8_private_key, passphrase) + found = True + except PbesError as e: + error_str = "PBES1[%s]" % str(e) + except ValueError: + error_str = "PBES1[Invalid]" + + if not found: + try: + p8_private_key = PBES2.decrypt(p8_private_key, passphrase) + found = True + except PbesError as e: + error_str += ",PBES2[%s]" % str(e) + except ValueError: + error_str += ",PBES2[Invalid]" + + if not found: + raise ValueError("Error decoding PKCS#8 (%s)" % error_str) + + pk_info = DerSequence().decode(p8_private_key, nr_elements=(2, 3, 4)) + if len(pk_info) == 2 and not passphrase: + raise ValueError("Not a valid clear PKCS#8 structure " + "(maybe it is encrypted?)") + + # + # PrivateKeyInfo ::= SEQUENCE { + # version Version, + # privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, + # privateKey PrivateKey, + # attributes [0] IMPLICIT Attributes OPTIONAL + # } + # Version ::= INTEGER + if pk_info[0] != 0: + raise ValueError("Not a valid PrivateKeyInfo SEQUENCE") + + # PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier + # + # EncryptedPrivateKeyInfo ::= SEQUENCE { + # encryptionAlgorithm EncryptionAlgorithmIdentifier, + # encryptedData EncryptedData + # } + # EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier + + # AlgorithmIdentifier ::= SEQUENCE { + # algorithm OBJECT IDENTIFIER, + # parameters ANY DEFINED BY algorithm OPTIONAL + # } + + algo = DerSequence().decode(pk_info[1], nr_elements=(1, 2)) + algo_oid = DerObjectId().decode(algo[0]).value + if len(algo) == 1: + algo_params = None + else: + try: + DerNull().decode(algo[1]) + algo_params = None + except: + algo_params = algo[1] + + # EncryptedData ::= OCTET STRING + private_key = DerOctetString().decode(pk_info[2]).payload + + return (algo_oid, private_key, algo_params) diff --git a/frozen_deps/Cryptodome/IO/PKCS8.pyi b/frozen_deps/Cryptodome/IO/PKCS8.pyi new file mode 100644 index 0000000..135b638 --- /dev/null +++ b/frozen_deps/Cryptodome/IO/PKCS8.pyi @@ -0,0 +1,14 @@ +from typing import Dict, Tuple, Optional, Union, Callable + +from Cryptodome.Util.asn1 import DerObject + +def wrap(private_key: bytes, + key_oid: str, + passphrase: Union[bytes, str] = ..., + protection: str = ..., + prot_params: Dict = ..., + key_params: DerObject = ..., + randfunc: Optional[Callable[[int],str]] = ...) -> bytes: ... + + +def unwrap(p8_private_key: bytes, passphrase: Optional[Union[bytes, str]] = ...) -> Tuple[str, bytes, Optional[bytes]]: ... diff --git a/frozen_deps/Cryptodome/IO/_PBES.py b/frozen_deps/Cryptodome/IO/_PBES.py new file mode 100644 index 0000000..9ee5385 --- /dev/null +++ b/frozen_deps/Cryptodome/IO/_PBES.py @@ -0,0 +1,435 @@ +# +# PublicKey/_PBES.py : Password-Based Encryption functions +# +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome import Random +from Cryptodome.Util.asn1 import ( + DerSequence, DerOctetString, + DerObjectId, DerInteger, + ) + +from Cryptodome.Util.Padding import pad, unpad +from Cryptodome.Hash import MD5, SHA1, SHA224, SHA256, SHA384, SHA512 +from Cryptodome.Cipher import DES, ARC2, DES3, AES +from Cryptodome.Protocol.KDF import PBKDF1, PBKDF2, scrypt + +_OID_PBE_WITH_MD5_AND_DES_CBC = "1.2.840.113549.1.5.3" +_OID_PBE_WITH_MD5_AND_RC2_CBC = "1.2.840.113549.1.5.6" +_OID_PBE_WITH_SHA1_AND_DES_CBC = "1.2.840.113549.1.5.10" +_OID_PBE_WITH_SHA1_AND_RC2_CBC = "1.2.840.113549.1.5.11" + +_OID_PBES2 = "1.2.840.113549.1.5.13" + +_OID_PBKDF2 = "1.2.840.113549.1.5.12" +_OID_SCRYPT = "1.3.6.1.4.1.11591.4.11" + +_OID_HMAC_SHA1 = "1.2.840.113549.2.7" +_OID_HMAC_SHA224 = "1.2.840.113549.2.8" +_OID_HMAC_SHA256 = "1.2.840.113549.2.9" +_OID_HMAC_SHA384 = "1.2.840.113549.2.10" +_OID_HMAC_SHA512 = "1.2.840.113549.2.11" + +_OID_DES_EDE3_CBC = "1.2.840.113549.3.7" +_OID_AES128_CBC = "2.16.840.1.101.3.4.1.2" +_OID_AES192_CBC = "2.16.840.1.101.3.4.1.22" +_OID_AES256_CBC = "2.16.840.1.101.3.4.1.42" + + +class PbesError(ValueError): + pass + +# These are the ASN.1 definitions used by the PBES1/2 logic: +# +# EncryptedPrivateKeyInfo ::= SEQUENCE { +# encryptionAlgorithm EncryptionAlgorithmIdentifier, +# encryptedData EncryptedData +# } +# +# EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier +# +# EncryptedData ::= OCTET STRING +# +# AlgorithmIdentifier ::= SEQUENCE { +# algorithm OBJECT IDENTIFIER, +# parameters ANY DEFINED BY algorithm OPTIONAL +# } +# +# PBEParameter ::= SEQUENCE { +# salt OCTET STRING (SIZE(8)), +# iterationCount INTEGER +# } +# +# PBES2-params ::= SEQUENCE { +# keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, +# encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} +# } +# +# PBKDF2-params ::= SEQUENCE { +# salt CHOICE { +# specified OCTET STRING, +# otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}} +# }, +# iterationCount INTEGER (1..MAX), +# keyLength INTEGER (1..MAX) OPTIONAL, +# prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 +# } +# +# scrypt-params ::= SEQUENCE { +# salt OCTET STRING, +# costParameter INTEGER (1..MAX), +# blockSize INTEGER (1..MAX), +# parallelizationParameter INTEGER (1..MAX), +# keyLength INTEGER (1..MAX) OPTIONAL +# } + +class PBES1(object): + """Deprecated encryption scheme with password-based key derivation + (originally defined in PKCS#5 v1.5, but still present in `v2.0`__). + + .. __: http://www.ietf.org/rfc/rfc2898.txt + """ + + @staticmethod + def decrypt(data, passphrase): + """Decrypt a piece of data using a passphrase and *PBES1*. + + The algorithm to use is automatically detected. + + :Parameters: + data : byte string + The piece of data to decrypt. + passphrase : byte string + The passphrase to use for decrypting the data. + :Returns: + The decrypted data, as a binary string. + """ + + enc_private_key_info = DerSequence().decode(data) + encrypted_algorithm = DerSequence().decode(enc_private_key_info[0]) + encrypted_data = DerOctetString().decode(enc_private_key_info[1]).payload + + pbe_oid = DerObjectId().decode(encrypted_algorithm[0]).value + cipher_params = {} + if pbe_oid == _OID_PBE_WITH_MD5_AND_DES_CBC: + # PBE_MD5_DES_CBC + hashmod = MD5 + ciphermod = DES + elif pbe_oid == _OID_PBE_WITH_MD5_AND_RC2_CBC: + # PBE_MD5_RC2_CBC + hashmod = MD5 + ciphermod = ARC2 + cipher_params['effective_keylen'] = 64 + elif pbe_oid == _OID_PBE_WITH_SHA1_AND_DES_CBC: + # PBE_SHA1_DES_CBC + hashmod = SHA1 + ciphermod = DES + elif pbe_oid == _OID_PBE_WITH_SHA1_AND_RC2_CBC: + # PBE_SHA1_RC2_CBC + hashmod = SHA1 + ciphermod = ARC2 + cipher_params['effective_keylen'] = 64 + else: + raise PbesError("Unknown OID for PBES1") + + pbe_params = DerSequence().decode(encrypted_algorithm[1], nr_elements=2) + salt = DerOctetString().decode(pbe_params[0]).payload + iterations = pbe_params[1] + + key_iv = PBKDF1(passphrase, salt, 16, iterations, hashmod) + key, iv = key_iv[:8], key_iv[8:] + + cipher = ciphermod.new(key, ciphermod.MODE_CBC, iv, **cipher_params) + pt = cipher.decrypt(encrypted_data) + return unpad(pt, cipher.block_size) + + +class PBES2(object): + """Encryption scheme with password-based key derivation + (defined in `PKCS#5 v2.0`__). + + .. __: http://www.ietf.org/rfc/rfc2898.txt.""" + + @staticmethod + def encrypt(data, passphrase, protection, prot_params=None, randfunc=None): + """Encrypt a piece of data using a passphrase and *PBES2*. + + :Parameters: + data : byte string + The piece of data to encrypt. + passphrase : byte string + The passphrase to use for encrypting the data. + protection : string + The identifier of the encryption algorithm to use. + The default value is '``PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC``'. + prot_params : dictionary + Parameters of the protection algorithm. + + +------------------+-----------------------------------------------+ + | Key | Description | + +==================+===============================================+ + | iteration_count | The KDF algorithm is repeated several times to| + | | slow down brute force attacks on passwords | + | | (called *N* or CPU/memory cost in scrypt). | + | | | + | | The default value for PBKDF2 is 1 000. | + | | The default value for scrypt is 16 384. | + +------------------+-----------------------------------------------+ + | salt_size | Salt is used to thwart dictionary and rainbow | + | | attacks on passwords. The default value is 8 | + | | bytes. | + +------------------+-----------------------------------------------+ + | block_size | *(scrypt only)* Memory-cost (r). The default | + | | value is 8. | + +------------------+-----------------------------------------------+ + | parallelization | *(scrypt only)* CPU-cost (p). The default | + | | value is 1. | + +------------------+-----------------------------------------------+ + + + 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 RNG will be + instantiated from ``Cryptodome.Random``. + + :Returns: + The encrypted data, as a binary string. + """ + + if prot_params is None: + prot_params = {} + + if randfunc is None: + randfunc = Random.new().read + + if protection == 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC': + key_size = 24 + module = DES3 + cipher_mode = DES3.MODE_CBC + enc_oid = _OID_DES_EDE3_CBC + elif protection in ('PBKDF2WithHMAC-SHA1AndAES128-CBC', + 'scryptAndAES128-CBC'): + key_size = 16 + module = AES + cipher_mode = AES.MODE_CBC + enc_oid = _OID_AES128_CBC + elif protection in ('PBKDF2WithHMAC-SHA1AndAES192-CBC', + 'scryptAndAES192-CBC'): + key_size = 24 + module = AES + cipher_mode = AES.MODE_CBC + enc_oid = _OID_AES192_CBC + elif protection in ('PBKDF2WithHMAC-SHA1AndAES256-CBC', + 'scryptAndAES256-CBC'): + key_size = 32 + module = AES + cipher_mode = AES.MODE_CBC + enc_oid = _OID_AES256_CBC + else: + raise ValueError("Unknown PBES2 mode") + + # Get random data + iv = randfunc(module.block_size) + salt = randfunc(prot_params.get("salt_size", 8)) + + # Derive key from password + if protection.startswith('PBKDF2'): + count = prot_params.get("iteration_count", 1000) + key = PBKDF2(passphrase, salt, key_size, count) + kdf_info = DerSequence([ + DerObjectId(_OID_PBKDF2), # PBKDF2 + DerSequence([ + DerOctetString(salt), + DerInteger(count) + ]) + ]) + else: + # It must be scrypt + count = prot_params.get("iteration_count", 16384) + scrypt_r = prot_params.get('block_size', 8) + scrypt_p = prot_params.get('parallelization', 1) + key = scrypt(passphrase, salt, key_size, + count, scrypt_r, scrypt_p) + kdf_info = DerSequence([ + DerObjectId(_OID_SCRYPT), # scrypt + DerSequence([ + DerOctetString(salt), + DerInteger(count), + DerInteger(scrypt_r), + DerInteger(scrypt_p) + ]) + ]) + + # Create cipher and use it + cipher = module.new(key, cipher_mode, iv) + encrypted_data = cipher.encrypt(pad(data, cipher.block_size)) + enc_info = DerSequence([ + DerObjectId(enc_oid), + DerOctetString(iv) + ]) + + # Result + enc_private_key_info = DerSequence([ + # encryptionAlgorithm + DerSequence([ + DerObjectId(_OID_PBES2), + DerSequence([ + kdf_info, + enc_info + ]), + ]), + DerOctetString(encrypted_data) + ]) + return enc_private_key_info.encode() + + @staticmethod + def decrypt(data, passphrase): + """Decrypt a piece of data using a passphrase and *PBES2*. + + The algorithm to use is automatically detected. + + :Parameters: + data : byte string + The piece of data to decrypt. + passphrase : byte string + The passphrase to use for decrypting the data. + :Returns: + The decrypted data, as a binary string. + """ + + enc_private_key_info = DerSequence().decode(data, nr_elements=2) + enc_algo = DerSequence().decode(enc_private_key_info[0]) + encrypted_data = DerOctetString().decode(enc_private_key_info[1]).payload + + pbe_oid = DerObjectId().decode(enc_algo[0]).value + if pbe_oid != _OID_PBES2: + raise PbesError("Not a PBES2 object") + + pbes2_params = DerSequence().decode(enc_algo[1], nr_elements=2) + + ### Key Derivation Function selection + kdf_info = DerSequence().decode(pbes2_params[0], nr_elements=2) + kdf_oid = DerObjectId().decode(kdf_info[0]).value + + kdf_key_length = None + + # We only support PBKDF2 or scrypt + if kdf_oid == _OID_PBKDF2: + + pbkdf2_params = DerSequence().decode(kdf_info[1], nr_elements=(2, 3, 4)) + salt = DerOctetString().decode(pbkdf2_params[0]).payload + iteration_count = pbkdf2_params[1] + + left = len(pbkdf2_params) - 2 + idx = 2 + + if left > 0: + try: + kdf_key_length = pbkdf2_params[idx] - 0 + left -= 1 + idx += 1 + except TypeError: + pass + + # Default is HMAC-SHA1 + pbkdf2_prf_oid = "1.2.840.113549.2.7" + if left > 0: + pbkdf2_prf_algo_id = DerSequence().decode(pbkdf2_params[idx]) + pbkdf2_prf_oid = DerObjectId().decode(pbkdf2_prf_algo_id[0]).value + + elif kdf_oid == _OID_SCRYPT: + + scrypt_params = DerSequence().decode(kdf_info[1], nr_elements=(4, 5)) + salt = DerOctetString().decode(scrypt_params[0]).payload + iteration_count, scrypt_r, scrypt_p = [scrypt_params[x] + for x in (1, 2, 3)] + if len(scrypt_params) > 4: + kdf_key_length = scrypt_params[4] + else: + kdf_key_length = None + else: + raise PbesError("Unsupported PBES2 KDF") + + ### Cipher selection + enc_info = DerSequence().decode(pbes2_params[1]) + enc_oid = DerObjectId().decode(enc_info[0]).value + + if enc_oid == _OID_DES_EDE3_CBC: + # DES_EDE3_CBC + ciphermod = DES3 + key_size = 24 + elif enc_oid == _OID_AES128_CBC: + # AES128_CBC + ciphermod = AES + key_size = 16 + elif enc_oid == _OID_AES192_CBC: + # AES192_CBC + ciphermod = AES + key_size = 24 + elif enc_oid == _OID_AES256_CBC: + # AES256_CBC + ciphermod = AES + key_size = 32 + else: + raise PbesError("Unsupported PBES2 cipher") + + if kdf_key_length and kdf_key_length != key_size: + raise PbesError("Mismatch between PBES2 KDF parameters" + " and selected cipher") + + IV = DerOctetString().decode(enc_info[1]).payload + + # Create cipher + if kdf_oid == _OID_PBKDF2: + if pbkdf2_prf_oid == _OID_HMAC_SHA1: + hmac_hash_module = SHA1 + elif pbkdf2_prf_oid == _OID_HMAC_SHA224: + hmac_hash_module = SHA224 + elif pbkdf2_prf_oid == _OID_HMAC_SHA256: + hmac_hash_module = SHA256 + elif pbkdf2_prf_oid == _OID_HMAC_SHA384: + hmac_hash_module = SHA384 + elif pbkdf2_prf_oid == _OID_HMAC_SHA512: + hmac_hash_module = SHA512 + else: + raise PbesError("Unsupported HMAC %s" % pbkdf2_prf_oid) + + key = PBKDF2(passphrase, salt, key_size, iteration_count, + hmac_hash_module=hmac_hash_module) + else: + key = scrypt(passphrase, salt, key_size, iteration_count, + scrypt_r, scrypt_p) + cipher = ciphermod.new(key, ciphermod.MODE_CBC, IV) + + # Decrypt data + pt = cipher.decrypt(encrypted_data) + return unpad(pt, cipher.block_size) diff --git a/frozen_deps/Cryptodome/IO/_PBES.pyi b/frozen_deps/Cryptodome/IO/_PBES.pyi new file mode 100644 index 0000000..a8a34ce --- /dev/null +++ b/frozen_deps/Cryptodome/IO/_PBES.pyi @@ -0,0 +1,19 @@ +from typing import Dict, Optional, Callable + +class PbesError(ValueError): + ... + +class PBES1(object): + @staticmethod + def decrypt(data: bytes, passphrase: bytes) -> bytes: ... + +class PBES2(object): + @staticmethod + def encrypt(data: bytes, + passphrase: bytes, + protection: str, + prot_params: Optional[Dict] = ..., + randfunc: Optional[Callable[[int],bytes]] = ...) -> bytes: ... + + @staticmethod + def decrypt(data:bytes, passphrase: bytes) -> bytes: ... diff --git a/frozen_deps/Cryptodome/IO/__init__.py b/frozen_deps/Cryptodome/IO/__init__.py new file mode 100644 index 0000000..85a0d0b --- /dev/null +++ b/frozen_deps/Cryptodome/IO/__init__.py @@ -0,0 +1,31 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +__all__ = ['PEM', 'PKCS8'] diff --git a/frozen_deps/Cryptodome/Math/Numbers.py b/frozen_deps/Cryptodome/Math/Numbers.py new file mode 100644 index 0000000..c9ff848 --- /dev/null +++ b/frozen_deps/Cryptodome/Math/Numbers.py @@ -0,0 +1,42 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +__all__ = ["Integer"] + +try: + from Cryptodome.Math._IntegerGMP import IntegerGMP as Integer + from Cryptodome.Math._IntegerGMP import implementation as _implementation +except (ImportError, OSError, AttributeError): + try: + from Cryptodome.Math._IntegerCustom import IntegerCustom as Integer + from Cryptodome.Math._IntegerCustom import implementation as _implementation + except (ImportError, OSError): + from Cryptodome.Math._IntegerNative import IntegerNative as Integer + _implementation = {} diff --git a/frozen_deps/Cryptodome/Math/Numbers.pyi b/frozen_deps/Cryptodome/Math/Numbers.pyi new file mode 100644 index 0000000..2285a3b --- /dev/null +++ b/frozen_deps/Cryptodome/Math/Numbers.pyi @@ -0,0 +1,4 @@ +from Cryptodome.Math._IntegerBase import IntegerBase + +class Integer(IntegerBase): + pass diff --git a/frozen_deps/Cryptodome/Math/Primality.py b/frozen_deps/Cryptodome/Math/Primality.py new file mode 100644 index 0000000..08ea3ff --- /dev/null +++ b/frozen_deps/Cryptodome/Math/Primality.py @@ -0,0 +1,368 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +"""Functions to create and test prime numbers. + +:undocumented: __package__ +""" + +from Cryptodome import Random +from Cryptodome.Math.Numbers import Integer + +from Cryptodome.Util.py3compat import iter_range + +COMPOSITE = 0 +PROBABLY_PRIME = 1 + + +def miller_rabin_test(candidate, iterations, randfunc=None): + """Perform a Miller-Rabin primality test on an integer. + + The test is specified in Section C.3.1 of `FIPS PUB 186-4`__. + + :Parameters: + candidate : integer + The number to test for primality. + iterations : integer + The maximum number of iterations to perform before + declaring a candidate a probable prime. + randfunc : callable + An RNG function where bases are taken from. + + :Returns: + ``Primality.COMPOSITE`` or ``Primality.PROBABLY_PRIME``. + + .. __: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf + """ + + if not isinstance(candidate, Integer): + candidate = Integer(candidate) + + if candidate in (1, 2, 3, 5): + return PROBABLY_PRIME + + if candidate.is_even(): + return COMPOSITE + + one = Integer(1) + minus_one = Integer(candidate - 1) + + if randfunc is None: + randfunc = Random.new().read + + # Step 1 and 2 + m = Integer(minus_one) + a = 0 + while m.is_even(): + m >>= 1 + a += 1 + + # Skip step 3 + + # Step 4 + for i in iter_range(iterations): + + # Step 4.1-2 + base = 1 + while base in (one, minus_one): + base = Integer.random_range(min_inclusive=2, + max_inclusive=candidate - 2) + assert(2 <= base <= candidate - 2) + + # Step 4.3-4.4 + z = pow(base, m, candidate) + if z in (one, minus_one): + continue + + # Step 4.5 + for j in iter_range(1, a): + z = pow(z, 2, candidate) + if z == minus_one: + break + if z == one: + return COMPOSITE + else: + return COMPOSITE + + # Step 5 + return PROBABLY_PRIME + + +def lucas_test(candidate): + """Perform a Lucas primality test on an integer. + + The test is specified in Section C.3.3 of `FIPS PUB 186-4`__. + + :Parameters: + candidate : integer + The number to test for primality. + + :Returns: + ``Primality.COMPOSITE`` or ``Primality.PROBABLY_PRIME``. + + .. __: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf + """ + + if not isinstance(candidate, Integer): + candidate = Integer(candidate) + + # Step 1 + if candidate in (1, 2, 3, 5): + return PROBABLY_PRIME + if candidate.is_even() or candidate.is_perfect_square(): + return COMPOSITE + + # Step 2 + def alternate(): + value = 5 + while True: + yield value + if value > 0: + value += 2 + else: + value -= 2 + value = -value + + for D in alternate(): + if candidate in (D, -D): + continue + js = Integer.jacobi_symbol(D, candidate) + if js == 0: + return COMPOSITE + if js == -1: + break + # Found D. P=1 and Q=(1-D)/4 (note that Q is guaranteed to be an integer) + + # Step 3 + # This is \delta(n) = n - jacobi(D/n) + K = candidate + 1 + # Step 4 + r = K.size_in_bits() - 1 + # Step 5 + # U_1=1 and V_1=P + U_i = Integer(1) + V_i = Integer(1) + U_temp = Integer(0) + V_temp = Integer(0) + # Step 6 + for i in iter_range(r - 1, -1, -1): + # Square + # U_temp = U_i * V_i % candidate + U_temp.set(U_i) + U_temp *= V_i + U_temp %= candidate + # V_temp = (((V_i ** 2 + (U_i ** 2 * D)) * K) >> 1) % candidate + V_temp.set(U_i) + V_temp *= U_i + V_temp *= D + V_temp.multiply_accumulate(V_i, V_i) + if V_temp.is_odd(): + V_temp += candidate + V_temp >>= 1 + V_temp %= candidate + # Multiply + if K.get_bit(i): + # U_i = (((U_temp + V_temp) * K) >> 1) % candidate + U_i.set(U_temp) + U_i += V_temp + if U_i.is_odd(): + U_i += candidate + U_i >>= 1 + U_i %= candidate + # V_i = (((V_temp + U_temp * D) * K) >> 1) % candidate + V_i.set(V_temp) + V_i.multiply_accumulate(U_temp, D) + if V_i.is_odd(): + V_i += candidate + V_i >>= 1 + V_i %= candidate + else: + U_i.set(U_temp) + V_i.set(V_temp) + # Step 7 + if U_i == 0: + return PROBABLY_PRIME + return COMPOSITE + + +from Cryptodome.Util.number import sieve_base as _sieve_base_large +## The optimal number of small primes to use for the sieve +## is probably dependent on the platform and the candidate size +_sieve_base = set(_sieve_base_large[:100]) + + +def test_probable_prime(candidate, randfunc=None): + """Test if a number is prime. + + A number is qualified as prime if it passes a certain + number of Miller-Rabin tests (dependent on the size + of the number, but such that probability of a false + positive is less than 10^-30) and a single Lucas test. + + For instance, a 1024-bit candidate will need to pass + 4 Miller-Rabin tests. + + :Parameters: + candidate : integer + The number to test for primality. + randfunc : callable + The routine to draw random bytes from to select Miller-Rabin bases. + :Returns: + ``PROBABLE_PRIME`` if the number if prime with very high probability. + ``COMPOSITE`` if the number is a composite. + For efficiency reasons, ``COMPOSITE`` is also returned for small primes. + """ + + if randfunc is None: + randfunc = Random.new().read + + if not isinstance(candidate, Integer): + candidate = Integer(candidate) + + # First, check trial division by the smallest primes + if int(candidate) in _sieve_base: + return PROBABLY_PRIME + try: + map(candidate.fail_if_divisible_by, _sieve_base) + except ValueError: + return COMPOSITE + + # These are the number of Miller-Rabin iterations s.t. p(k, t) < 1E-30, + # with p(k, t) being the probability that a randomly chosen k-bit number + # is composite but still survives t MR iterations. + mr_ranges = ((220, 30), (280, 20), (390, 15), (512, 10), + (620, 7), (740, 6), (890, 5), (1200, 4), + (1700, 3), (3700, 2)) + + bit_size = candidate.size_in_bits() + try: + mr_iterations = list(filter(lambda x: bit_size < x[0], + mr_ranges))[0][1] + except IndexError: + mr_iterations = 1 + + if miller_rabin_test(candidate, mr_iterations, + randfunc=randfunc) == COMPOSITE: + return COMPOSITE + if lucas_test(candidate) == COMPOSITE: + return COMPOSITE + return PROBABLY_PRIME + + +def generate_probable_prime(**kwargs): + """Generate a random probable prime. + + The prime will not have any specific properties + (e.g. it will not be a *strong* prime). + + Random numbers are evaluated for primality until one + passes all tests, consisting of a certain number of + Miller-Rabin tests with random bases followed by + a single Lucas test. + + The number of Miller-Rabin iterations is chosen such that + the probability that the output number is a non-prime is + less than 1E-30 (roughly 2^{-100}). + + This approach is compliant to `FIPS PUB 186-4`__. + + :Keywords: + exact_bits : integer + The desired size in bits of the probable prime. + It must be at least 160. + randfunc : callable + An RNG function where candidate primes are taken from. + prime_filter : callable + A function that takes an Integer as parameter and returns + True if the number can be passed to further primality tests, + False if it should be immediately discarded. + + :Return: + A probable prime in the range 2^exact_bits > p > 2^(exact_bits-1). + + .. __: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf + """ + + exact_bits = kwargs.pop("exact_bits", None) + randfunc = kwargs.pop("randfunc", None) + prime_filter = kwargs.pop("prime_filter", lambda x: True) + if kwargs: + raise ValueError("Unknown parameters: " + kwargs.keys()) + + if exact_bits is None: + raise ValueError("Missing exact_bits parameter") + if exact_bits < 160: + raise ValueError("Prime number is not big enough.") + + if randfunc is None: + randfunc = Random.new().read + + result = COMPOSITE + while result == COMPOSITE: + candidate = Integer.random(exact_bits=exact_bits, + randfunc=randfunc) | 1 + if not prime_filter(candidate): + continue + result = test_probable_prime(candidate, randfunc) + return candidate + + +def generate_probable_safe_prime(**kwargs): + """Generate a random, probable safe prime. + + Note this operation is much slower than generating a simple prime. + + :Keywords: + exact_bits : integer + The desired size in bits of the probable safe prime. + randfunc : callable + An RNG function where candidate primes are taken from. + + :Return: + A probable safe prime in the range + 2^exact_bits > p > 2^(exact_bits-1). + """ + + exact_bits = kwargs.pop("exact_bits", None) + randfunc = kwargs.pop("randfunc", None) + if kwargs: + raise ValueError("Unknown parameters: " + kwargs.keys()) + + if randfunc is None: + randfunc = Random.new().read + + result = COMPOSITE + while result == COMPOSITE: + q = generate_probable_prime(exact_bits=exact_bits - 1, randfunc=randfunc) + candidate = q * 2 + 1 + if candidate.size_in_bits() != exact_bits: + continue + result = test_probable_prime(candidate, randfunc=randfunc) + return candidate diff --git a/frozen_deps/Cryptodome/Math/Primality.pyi b/frozen_deps/Cryptodome/Math/Primality.pyi new file mode 100644 index 0000000..7813483 --- /dev/null +++ b/frozen_deps/Cryptodome/Math/Primality.pyi @@ -0,0 +1,18 @@ +from typing import Callable, Optional, Union, Set + +PrimeResult = int + +COMPOSITE: PrimeResult +PROBABLY_PRIME: PrimeResult + +def miller_rabin_test(candidate: int, iterations: int, randfunc: Optional[Callable[[int],bytes]]=None) -> PrimeResult: ... +def lucas_test(candidate: int) -> PrimeResult: ... +_sieve_base: Set[int] +def test_probable_prime(candidate: int, randfunc: Optional[Callable[[int],bytes]]=None) -> PrimeResult: ... +def generate_probable_prime(*, + exact_bits: int = ..., + randfunc: Callable[[int],bytes] = ..., + prime_filter: Callable[[int],bool] = ...) -> int: ... +def generate_probable_safe_prime(*, + exact_bits: int = ..., + randfunc: Callable[[int],bytes] = ...) -> int: ... diff --git a/frozen_deps/Cryptodome/Math/_IntegerBase.py b/frozen_deps/Cryptodome/Math/_IntegerBase.py new file mode 100644 index 0000000..f8cf333 --- /dev/null +++ b/frozen_deps/Cryptodome/Math/_IntegerBase.py @@ -0,0 +1,392 @@ +# =================================================================== +# +# Copyright (c) 2018, Helder Eijs +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +import abc + +from Cryptodome.Util.py3compat import iter_range, bord, bchr, ABC + +from Cryptodome import Random + + +class IntegerBase(ABC): + + # Conversions + @abc.abstractmethod + def __int__(self): + pass + + @abc.abstractmethod + def __str__(self): + pass + + @abc.abstractmethod + def __repr__(self): + pass + + @abc.abstractmethod + def to_bytes(self, block_size=0): + pass + + @staticmethod + @abc.abstractmethod + def from_bytes(byte_string): + pass + + # Relations + @abc.abstractmethod + def __eq__(self, term): + pass + + @abc.abstractmethod + def __ne__(self, term): + pass + + @abc.abstractmethod + def __lt__(self, term): + pass + + @abc.abstractmethod + def __le__(self, term): + pass + + @abc.abstractmethod + def __gt__(self, term): + pass + + @abc.abstractmethod + def __ge__(self, term): + pass + + @abc.abstractmethod + def __nonzero__(self): + pass + __bool__ = __nonzero__ + + @abc.abstractmethod + def is_negative(self): + pass + + # Arithmetic operations + @abc.abstractmethod + def __add__(self, term): + pass + + @abc.abstractmethod + def __sub__(self, term): + pass + + @abc.abstractmethod + def __mul__(self, factor): + pass + + @abc.abstractmethod + def __floordiv__(self, divisor): + pass + + @abc.abstractmethod + def __mod__(self, divisor): + pass + + @abc.abstractmethod + def inplace_pow(self, exponent, modulus=None): + pass + + @abc.abstractmethod + def __pow__(self, exponent, modulus=None): + pass + + @abc.abstractmethod + def __abs__(self): + pass + + @abc.abstractmethod + def sqrt(self, modulus=None): + pass + + @abc.abstractmethod + def __iadd__(self, term): + pass + + @abc.abstractmethod + def __isub__(self, term): + pass + + @abc.abstractmethod + def __imul__(self, term): + pass + + @abc.abstractmethod + def __imod__(self, term): + pass + + # Boolean/bit operations + @abc.abstractmethod + def __and__(self, term): + pass + + @abc.abstractmethod + def __or__(self, term): + pass + + @abc.abstractmethod + def __rshift__(self, pos): + pass + + @abc.abstractmethod + def __irshift__(self, pos): + pass + + @abc.abstractmethod + def __lshift__(self, pos): + pass + + @abc.abstractmethod + def __ilshift__(self, pos): + pass + + @abc.abstractmethod + def get_bit(self, n): + pass + + # Extra + @abc.abstractmethod + def is_odd(self): + pass + + @abc.abstractmethod + def is_even(self): + pass + + @abc.abstractmethod + def size_in_bits(self): + pass + + @abc.abstractmethod + def size_in_bytes(self): + pass + + @abc.abstractmethod + def is_perfect_square(self): + pass + + @abc.abstractmethod + def fail_if_divisible_by(self, small_prime): + pass + + @abc.abstractmethod + def multiply_accumulate(self, a, b): + pass + + @abc.abstractmethod + def set(self, source): + pass + + @abc.abstractmethod + def inplace_inverse(self, modulus): + pass + + @abc.abstractmethod + def inverse(self, modulus): + pass + + @abc.abstractmethod + def gcd(self, term): + pass + + @abc.abstractmethod + def lcm(self, term): + pass + + @staticmethod + @abc.abstractmethod + def jacobi_symbol(a, n): + pass + + @staticmethod + def _tonelli_shanks(n, p): + """Tonelli-shanks algorithm for computing the square root + of n modulo a prime p. + + n must be in the range [0..p-1]. + p must be at least even. + + The return value r is the square root of modulo p. If non-zero, + another solution will also exist (p-r). + + Note we cannot assume that p is really a prime: if it's not, + we can either raise an exception or return the correct value. + """ + + # See https://rosettacode.org/wiki/Tonelli-Shanks_algorithm + + if n in (0, 1): + return n + + if p % 4 == 3: + root = pow(n, (p + 1) // 4, p) + if pow(root, 2, p) != n: + raise ValueError("Cannot compute square root") + return root + + s = 1 + q = (p - 1) // 2 + while not (q & 1): + s += 1 + q >>= 1 + + z = n.__class__(2) + while True: + euler = pow(z, (p - 1) // 2, p) + if euler == 1: + z += 1 + continue + if euler == p - 1: + break + # Most probably p is not a prime + raise ValueError("Cannot compute square root") + + m = s + c = pow(z, q, p) + t = pow(n, q, p) + r = pow(n, (q + 1) // 2, p) + + while t != 1: + for i in iter_range(0, m): + if pow(t, 2**i, p) == 1: + break + if i == m: + raise ValueError("Cannot compute square root of %d mod %d" % (n, p)) + b = pow(c, 2**(m - i - 1), p) + m = i + c = b**2 % p + t = (t * b**2) % p + r = (r * b) % p + + if pow(r, 2, p) != n: + raise ValueError("Cannot compute square root") + + return r + + @classmethod + def random(cls, **kwargs): + """Generate a random natural integer of a certain size. + + :Keywords: + exact_bits : positive integer + The length in bits of the resulting random Integer number. + The number is guaranteed to fulfil the relation: + + 2^bits > result >= 2^(bits - 1) + + max_bits : positive integer + The maximum length in bits of the resulting random Integer number. + The number is guaranteed to fulfil the relation: + + 2^bits > result >=0 + + randfunc : callable + A function that returns a random byte string. The length of the + byte string is passed as parameter. Optional. + If not provided (or ``None``), randomness is read from the system RNG. + + :Return: a Integer object + """ + + exact_bits = kwargs.pop("exact_bits", None) + max_bits = kwargs.pop("max_bits", None) + randfunc = kwargs.pop("randfunc", None) + + if randfunc is None: + randfunc = Random.new().read + + if exact_bits is None and max_bits is None: + raise ValueError("Either 'exact_bits' or 'max_bits' must be specified") + + if exact_bits is not None and max_bits is not None: + raise ValueError("'exact_bits' and 'max_bits' are mutually exclusive") + + bits = exact_bits or max_bits + bytes_needed = ((bits - 1) // 8) + 1 + significant_bits_msb = 8 - (bytes_needed * 8 - bits) + msb = bord(randfunc(1)[0]) + if exact_bits is not None: + msb |= 1 << (significant_bits_msb - 1) + msb &= (1 << significant_bits_msb) - 1 + + return cls.from_bytes(bchr(msb) + randfunc(bytes_needed - 1)) + + @classmethod + def random_range(cls, **kwargs): + """Generate a random integer within a given internal. + + :Keywords: + min_inclusive : integer + The lower end of the interval (inclusive). + max_inclusive : integer + The higher end of the interval (inclusive). + max_exclusive : integer + The higher end of the interval (exclusive). + randfunc : callable + A function that returns a random byte string. The length of the + byte string is passed as parameter. Optional. + If not provided (or ``None``), randomness is read from the system RNG. + :Returns: + An Integer randomly taken in the given interval. + """ + + min_inclusive = kwargs.pop("min_inclusive", None) + max_inclusive = kwargs.pop("max_inclusive", None) + max_exclusive = kwargs.pop("max_exclusive", None) + randfunc = kwargs.pop("randfunc", None) + + if kwargs: + raise ValueError("Unknown keywords: " + str(kwargs.keys)) + if None not in (max_inclusive, max_exclusive): + raise ValueError("max_inclusive and max_exclusive cannot be both" + " specified") + if max_exclusive is not None: + max_inclusive = max_exclusive - 1 + if None in (min_inclusive, max_inclusive): + raise ValueError("Missing keyword to identify the interval") + + if randfunc is None: + randfunc = Random.new().read + + norm_maximum = max_inclusive - min_inclusive + bits_needed = cls(norm_maximum).size_in_bits() + + norm_candidate = -1 + while not 0 <= norm_candidate <= norm_maximum: + norm_candidate = cls.random( + max_bits=bits_needed, + randfunc=randfunc + ) + return norm_candidate + min_inclusive + diff --git a/frozen_deps/Cryptodome/Math/_IntegerBase.pyi b/frozen_deps/Cryptodome/Math/_IntegerBase.pyi new file mode 100644 index 0000000..3f534db --- /dev/null +++ b/frozen_deps/Cryptodome/Math/_IntegerBase.pyi @@ -0,0 +1,61 @@ +from typing import Optional, Union, Callable + +RandFunc = Callable[[int],int] + +class IntegerBase: + + def __int__(self) -> int: ... + def __str__(self) -> str: ... + def __repr__(self) -> str: ... + def to_bytes(self, block_size: Optional[int]=0) -> bytes: ... + @staticmethod + def from_bytes(byte_string: bytes) -> IntegerBase: ... + def __eq__(self, term: object) -> bool: ... + def __ne__(self, term: object) -> bool: ... + def __lt__(self, term: Union[IntegerBase, int]) -> bool: ... + def __le__(self, term: Union[IntegerBase, int]) -> bool: ... + def __gt__(self, term: Union[IntegerBase, int]) -> bool: ... + def __ge__(self, term: Union[IntegerBase, int]) -> bool: ... + def __nonzero__(self) -> bool: ... + def is_negative(self) -> bool: ... + def __add__(self, term: Union[IntegerBase, int]) -> IntegerBase: ... + def __sub__(self, term: Union[IntegerBase, int]) -> IntegerBase: ... + def __mul__(self, term: Union[IntegerBase, int]) -> IntegerBase: ... + def __floordiv__(self, divisor: Union[IntegerBase, int]) -> IntegerBase: ... + def __mod__(self, divisor: Union[IntegerBase, int]) -> IntegerBase: ... + def inplace_pow(self, exponent: int, modulus: Optional[Union[IntegerBase, int]]=None) -> IntegerBase: ... + def __pow__(self, exponent: int, modulus: Optional[int]) -> IntegerBase: ... + def __abs__(self) -> IntegerBase: ... + def sqrt(self, modulus: Optional[int]) -> IntegerBase: ... + def __iadd__(self, term: Union[IntegerBase, int]) -> IntegerBase: ... + def __isub__(self, term: Union[IntegerBase, int]) -> IntegerBase: ... + def __imul__(self, term: Union[IntegerBase, int]) -> IntegerBase: ... + def __imod__(self, divisor: Union[IntegerBase, int]) -> IntegerBase: ... + def __and__(self, term: Union[IntegerBase, int]) -> IntegerBase: ... + def __or__(self, term: Union[IntegerBase, int]) -> IntegerBase: ... + def __rshift__(self, pos: Union[IntegerBase, int]) -> IntegerBase: ... + def __irshift__(self, pos: Union[IntegerBase, int]) -> IntegerBase: ... + def __lshift__(self, pos: Union[IntegerBase, int]) -> IntegerBase: ... + def __ilshift__(self, pos: Union[IntegerBase, int]) -> IntegerBase: ... + def get_bit(self, n: int) -> bool: ... + def is_odd(self) -> bool: ... + def is_even(self) -> bool: ... + def size_in_bits(self) -> int: ... + def size_in_bytes(self) -> int: ... + def is_perfect_square(self) -> bool: ... + def fail_if_divisible_by(self, small_prime: Union[IntegerBase, int]) -> None: ... + def multiply_accumulate(self, a: Union[IntegerBase, int], b: Union[IntegerBase, int]) -> IntegerBase: ... + def set(self, source: Union[IntegerBase, int]) -> IntegerBase: ... + def inplace_inverse(self, modulus: Union[IntegerBase, int]) -> IntegerBase: ... + def inverse(self, modulus: Union[IntegerBase, int]) -> IntegerBase: ... + def gcd(self, term: Union[IntegerBase, int]) -> IntegerBase: ... + def lcm(self, term: Union[IntegerBase, int]) -> IntegerBase: ... + @staticmethod + def jacobi_symbol(a: Union[IntegerBase, int], n: Union[IntegerBase, int]) -> IntegerBase: ... + @staticmethod + def _tonelli_shanks(n: Union[IntegerBase, int], p: Union[IntegerBase, int]) -> IntegerBase : ... + @classmethod + def random(cls, **kwargs: Union[int,RandFunc]) -> IntegerBase : ... + @classmethod + def random_range(cls, **kwargs: Union[int,RandFunc]) -> IntegerBase : ... + diff --git a/frozen_deps/Cryptodome/Math/_IntegerCustom.py b/frozen_deps/Cryptodome/Math/_IntegerCustom.py new file mode 100644 index 0000000..b626014 --- /dev/null +++ b/frozen_deps/Cryptodome/Math/_IntegerCustom.py @@ -0,0 +1,111 @@ +# =================================================================== +# +# Copyright (c) 2018, Helder Eijs +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from ._IntegerNative import IntegerNative + +from Cryptodome.Util.number import long_to_bytes, bytes_to_long + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + create_string_buffer, + get_raw_buffer, backend, + c_size_t, c_ulonglong) + + +from Cryptodome.Random.random import getrandbits + +c_defs = """ +int monty_pow(const uint8_t *base, + const uint8_t *exp, + const uint8_t *modulus, + uint8_t *out, + size_t len, + uint64_t seed); +""" + + +_raw_montgomery = load_pycryptodome_raw_lib("Cryptodome.Math._modexp", c_defs) +implementation = {"library": "custom", "api": backend} + + +class IntegerCustom(IntegerNative): + + @staticmethod + def from_bytes(byte_string): + return IntegerCustom(bytes_to_long(byte_string)) + + def inplace_pow(self, exponent, modulus=None): + exp_value = int(exponent) + if exp_value < 0: + raise ValueError("Exponent must not be negative") + + # No modular reduction + if modulus is None: + self._value = pow(self._value, exp_value) + return self + + # With modular reduction + mod_value = int(modulus) + if mod_value < 0: + raise ValueError("Modulus must be positive") + if mod_value == 0: + raise ZeroDivisionError("Modulus cannot be zero") + + # C extension only works with odd moduli + if (mod_value & 1) == 0: + self._value = pow(self._value, exp_value, mod_value) + return self + + # C extension only works with bases smaller than modulus + if self._value >= mod_value: + self._value %= mod_value + + max_len = len(long_to_bytes(max(self._value, exp_value, mod_value))) + + base_b = long_to_bytes(self._value, max_len) + exp_b = long_to_bytes(exp_value, max_len) + modulus_b = long_to_bytes(mod_value, max_len) + + out = create_string_buffer(max_len) + + error = _raw_montgomery.monty_pow( + out, + base_b, + exp_b, + modulus_b, + c_size_t(max_len), + c_ulonglong(getrandbits(64)) + ) + + if error: + raise ValueError("monty_pow failed with error: %d" % error) + + result = bytes_to_long(get_raw_buffer(out)) + self._value = result + return self diff --git a/frozen_deps/Cryptodome/Math/_IntegerCustom.pyi b/frozen_deps/Cryptodome/Math/_IntegerCustom.pyi new file mode 100644 index 0000000..2dd75c7 --- /dev/null +++ b/frozen_deps/Cryptodome/Math/_IntegerCustom.pyi @@ -0,0 +1,8 @@ +from typing import Any + +from ._IntegerNative import IntegerNative + +_raw_montgomery = Any + +class IntegerCustom(IntegerNative): + pass diff --git a/frozen_deps/Cryptodome/Math/_IntegerGMP.py b/frozen_deps/Cryptodome/Math/_IntegerGMP.py new file mode 100644 index 0000000..c860020 --- /dev/null +++ b/frozen_deps/Cryptodome/Math/_IntegerGMP.py @@ -0,0 +1,708 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +import sys + +from Cryptodome.Util.py3compat import tobytes, is_native_int + +from Cryptodome.Util._raw_api import (backend, load_lib, + get_raw_buffer, get_c_string, + null_pointer, create_string_buffer, + c_ulong, c_size_t) + +from ._IntegerBase import IntegerBase + +gmp_defs = """typedef unsigned long UNIX_ULONG; + typedef struct { int a; int b; void *c; } MPZ; + typedef MPZ mpz_t[1]; + typedef UNIX_ULONG mp_bitcnt_t; + void __gmpz_init (mpz_t x); + void __gmpz_init_set (mpz_t rop, const mpz_t op); + void __gmpz_init_set_ui (mpz_t rop, UNIX_ULONG op); + int __gmp_sscanf (const char *s, const char *fmt, ...); + void __gmpz_set (mpz_t rop, const mpz_t op); + int __gmp_snprintf (uint8_t *buf, size_t size, const char *fmt, ...); + void __gmpz_add (mpz_t rop, const mpz_t op1, const mpz_t op2); + void __gmpz_add_ui (mpz_t rop, const mpz_t op1, UNIX_ULONG op2); + void __gmpz_sub_ui (mpz_t rop, const mpz_t op1, UNIX_ULONG op2); + void __gmpz_addmul (mpz_t rop, const mpz_t op1, const mpz_t op2); + void __gmpz_addmul_ui (mpz_t rop, const mpz_t op1, UNIX_ULONG op2); + void __gmpz_submul_ui (mpz_t rop, const mpz_t op1, UNIX_ULONG op2); + void __gmpz_import (mpz_t rop, size_t count, int order, size_t size, + int endian, size_t nails, const void *op); + void * __gmpz_export (void *rop, size_t *countp, int order, + size_t size, + int endian, size_t nails, const mpz_t op); + size_t __gmpz_sizeinbase (const mpz_t op, int base); + void __gmpz_sub (mpz_t rop, const mpz_t op1, const mpz_t op2); + void __gmpz_mul (mpz_t rop, const mpz_t op1, const mpz_t op2); + void __gmpz_mul_ui (mpz_t rop, const mpz_t op1, UNIX_ULONG op2); + int __gmpz_cmp (const mpz_t op1, const mpz_t op2); + void __gmpz_powm (mpz_t rop, const mpz_t base, const mpz_t exp, const + mpz_t mod); + void __gmpz_powm_ui (mpz_t rop, const mpz_t base, UNIX_ULONG exp, + const mpz_t mod); + void __gmpz_pow_ui (mpz_t rop, const mpz_t base, UNIX_ULONG exp); + void __gmpz_sqrt(mpz_t rop, const mpz_t op); + void __gmpz_mod (mpz_t r, const mpz_t n, const mpz_t d); + void __gmpz_neg (mpz_t rop, const mpz_t op); + void __gmpz_abs (mpz_t rop, const mpz_t op); + void __gmpz_and (mpz_t rop, const mpz_t op1, const mpz_t op2); + void __gmpz_ior (mpz_t rop, const mpz_t op1, const mpz_t op2); + void __gmpz_clear (mpz_t x); + void __gmpz_tdiv_q_2exp (mpz_t q, const mpz_t n, mp_bitcnt_t b); + void __gmpz_fdiv_q (mpz_t q, const mpz_t n, const mpz_t d); + void __gmpz_mul_2exp (mpz_t rop, const mpz_t op1, mp_bitcnt_t op2); + int __gmpz_tstbit (const mpz_t op, mp_bitcnt_t bit_index); + int __gmpz_perfect_square_p (const mpz_t op); + int __gmpz_jacobi (const mpz_t a, const mpz_t b); + void __gmpz_gcd (mpz_t rop, const mpz_t op1, const mpz_t op2); + UNIX_ULONG __gmpz_gcd_ui (mpz_t rop, const mpz_t op1, + UNIX_ULONG op2); + void __gmpz_lcm (mpz_t rop, const mpz_t op1, const mpz_t op2); + int __gmpz_invert (mpz_t rop, const mpz_t op1, const mpz_t op2); + int __gmpz_divisible_p (const mpz_t n, const mpz_t d); + int __gmpz_divisible_ui_p (const mpz_t n, UNIX_ULONG d); + """ + +if sys.platform == "win32": + raise ImportError("Not using GMP on Windows") + +lib = load_lib("gmp", gmp_defs) +implementation = {"library": "gmp", "api": backend} + +if hasattr(lib, "__mpir_version"): + raise ImportError("MPIR library detected") + +# In order to create a function that returns a pointer to +# a new MPZ structure, we need to break the abstraction +# and know exactly what ffi backend we have +if implementation["api"] == "ctypes": + from ctypes import Structure, c_int, c_void_p, byref + + class _MPZ(Structure): + _fields_ = [('_mp_alloc', c_int), + ('_mp_size', c_int), + ('_mp_d', c_void_p)] + + def new_mpz(): + return byref(_MPZ()) + +else: + # We are using CFFI + from Cryptodome.Util._raw_api import ffi + + def new_mpz(): + return ffi.new("MPZ*") + + +# Lazy creation of GMP methods +class _GMP(object): + + def __getattr__(self, name): + if name.startswith("mpz_"): + func_name = "__gmpz_" + name[4:] + elif name.startswith("gmp_"): + func_name = "__gmp_" + name[4:] + else: + raise AttributeError("Attribute %s is invalid" % name) + func = getattr(lib, func_name) + setattr(self, name, func) + return func + + +_gmp = _GMP() + + +class IntegerGMP(IntegerBase): + """A fast, arbitrary precision integer""" + + _zero_mpz_p = new_mpz() + _gmp.mpz_init_set_ui(_zero_mpz_p, c_ulong(0)) + + def __init__(self, value): + """Initialize the integer to the given value.""" + + self._mpz_p = new_mpz() + self._initialized = False + + if isinstance(value, float): + raise ValueError("A floating point type is not a natural number") + + self._initialized = True + + if is_native_int(value): + _gmp.mpz_init(self._mpz_p) + result = _gmp.gmp_sscanf(tobytes(str(value)), b"%Zd", self._mpz_p) + if result != 1: + raise ValueError("Error converting '%d'" % value) + elif isinstance(value, IntegerGMP): + _gmp.mpz_init_set(self._mpz_p, value._mpz_p) + else: + raise NotImplementedError + + # Conversions + def __int__(self): + # buf will contain the integer encoded in decimal plus the trailing + # zero, and possibly the negative sign. + # dig10(x) < log10(x) + 1 = log2(x)/log2(10) + 1 < log2(x)/3 + 1 + buf_len = _gmp.mpz_sizeinbase(self._mpz_p, 2) // 3 + 3 + buf = create_string_buffer(buf_len) + + _gmp.gmp_snprintf(buf, c_size_t(buf_len), b"%Zd", self._mpz_p) + return int(get_c_string(buf)) + + def __str__(self): + return str(int(self)) + + def __repr__(self): + return "Integer(%s)" % str(self) + + # Only Python 2.x + def __hex__(self): + return hex(int(self)) + + # Only Python 3.x + def __index__(self): + return int(self) + + def to_bytes(self, block_size=0): + """Convert the number into a byte string. + + This method encodes the number in network order and prepends + as many zero bytes as required. It only works for non-negative + values. + + :Parameters: + block_size : integer + The exact size the output byte string must have. + If zero, the string has the minimal length. + :Returns: + A byte string. + :Raise ValueError: + If the value is negative or if ``block_size`` is + provided and the length of the byte string would exceed it. + """ + + if self < 0: + raise ValueError("Conversion only valid for non-negative numbers") + + buf_len = (_gmp.mpz_sizeinbase(self._mpz_p, 2) + 7) // 8 + if buf_len > block_size > 0: + raise ValueError("Number is too big to convert to byte string" + "of prescribed length") + buf = create_string_buffer(buf_len) + + _gmp.mpz_export( + buf, + null_pointer, # Ignore countp + 1, # Big endian + c_size_t(1), # Each word is 1 byte long + 0, # Endianess within a word - not relevant + c_size_t(0), # No nails + self._mpz_p) + + return b'\x00' * max(0, block_size - buf_len) + get_raw_buffer(buf) + + @staticmethod + def from_bytes(byte_string): + """Convert a byte string into a number. + + :Parameters: + byte_string : byte string + The input number, encoded in network order. + It can only be non-negative. + :Return: + The ``Integer`` object carrying the same value as the input. + """ + result = IntegerGMP(0) + _gmp.mpz_import( + result._mpz_p, + c_size_t(len(byte_string)), # Amount of words to read + 1, # Big endian + c_size_t(1), # Each word is 1 byte long + 0, # Endianess within a word - not relevant + c_size_t(0), # No nails + byte_string) + return result + + # Relations + def _apply_and_return(self, func, term): + if not isinstance(term, IntegerGMP): + term = IntegerGMP(term) + return func(self._mpz_p, term._mpz_p) + + def __eq__(self, term): + if not (isinstance(term, IntegerGMP) or is_native_int(term)): + return False + return self._apply_and_return(_gmp.mpz_cmp, term) == 0 + + def __ne__(self, term): + if not (isinstance(term, IntegerGMP) or is_native_int(term)): + return True + return self._apply_and_return(_gmp.mpz_cmp, term) != 0 + + def __lt__(self, term): + return self._apply_and_return(_gmp.mpz_cmp, term) < 0 + + def __le__(self, term): + return self._apply_and_return(_gmp.mpz_cmp, term) <= 0 + + def __gt__(self, term): + return self._apply_and_return(_gmp.mpz_cmp, term) > 0 + + def __ge__(self, term): + return self._apply_and_return(_gmp.mpz_cmp, term) >= 0 + + def __nonzero__(self): + return _gmp.mpz_cmp(self._mpz_p, self._zero_mpz_p) != 0 + __bool__ = __nonzero__ + + def is_negative(self): + return _gmp.mpz_cmp(self._mpz_p, self._zero_mpz_p) < 0 + + # Arithmetic operations + def __add__(self, term): + result = IntegerGMP(0) + if not isinstance(term, IntegerGMP): + try: + term = IntegerGMP(term) + except NotImplementedError: + return NotImplemented + _gmp.mpz_add(result._mpz_p, + self._mpz_p, + term._mpz_p) + return result + + def __sub__(self, term): + result = IntegerGMP(0) + if not isinstance(term, IntegerGMP): + try: + term = IntegerGMP(term) + except NotImplementedError: + return NotImplemented + _gmp.mpz_sub(result._mpz_p, + self._mpz_p, + term._mpz_p) + return result + + def __mul__(self, term): + result = IntegerGMP(0) + if not isinstance(term, IntegerGMP): + try: + term = IntegerGMP(term) + except NotImplementedError: + return NotImplemented + _gmp.mpz_mul(result._mpz_p, + self._mpz_p, + term._mpz_p) + return result + + def __floordiv__(self, divisor): + if not isinstance(divisor, IntegerGMP): + divisor = IntegerGMP(divisor) + if _gmp.mpz_cmp(divisor._mpz_p, + self._zero_mpz_p) == 0: + raise ZeroDivisionError("Division by zero") + result = IntegerGMP(0) + _gmp.mpz_fdiv_q(result._mpz_p, + self._mpz_p, + divisor._mpz_p) + return result + + def __mod__(self, divisor): + if not isinstance(divisor, IntegerGMP): + divisor = IntegerGMP(divisor) + comp = _gmp.mpz_cmp(divisor._mpz_p, + self._zero_mpz_p) + if comp == 0: + raise ZeroDivisionError("Division by zero") + if comp < 0: + raise ValueError("Modulus must be positive") + result = IntegerGMP(0) + _gmp.mpz_mod(result._mpz_p, + self._mpz_p, + divisor._mpz_p) + return result + + def inplace_pow(self, exponent, modulus=None): + + if modulus is None: + if exponent < 0: + raise ValueError("Exponent must not be negative") + + # Normal exponentiation + if exponent > 256: + raise ValueError("Exponent is too big") + _gmp.mpz_pow_ui(self._mpz_p, + self._mpz_p, # Base + c_ulong(int(exponent)) + ) + else: + # Modular exponentiation + if not isinstance(modulus, IntegerGMP): + modulus = IntegerGMP(modulus) + if not modulus: + raise ZeroDivisionError("Division by zero") + if modulus.is_negative(): + raise ValueError("Modulus must be positive") + if is_native_int(exponent): + if exponent < 0: + raise ValueError("Exponent must not be negative") + if exponent < 65536: + _gmp.mpz_powm_ui(self._mpz_p, + self._mpz_p, + c_ulong(exponent), + modulus._mpz_p) + return self + exponent = IntegerGMP(exponent) + elif exponent.is_negative(): + raise ValueError("Exponent must not be negative") + _gmp.mpz_powm(self._mpz_p, + self._mpz_p, + exponent._mpz_p, + modulus._mpz_p) + return self + + def __pow__(self, exponent, modulus=None): + result = IntegerGMP(self) + return result.inplace_pow(exponent, modulus) + + def __abs__(self): + result = IntegerGMP(0) + _gmp.mpz_abs(result._mpz_p, self._mpz_p) + return result + + def sqrt(self, modulus=None): + """Return the largest Integer that does not + exceed the square root""" + + if modulus is None: + if self < 0: + raise ValueError("Square root of negative value") + result = IntegerGMP(0) + _gmp.mpz_sqrt(result._mpz_p, + self._mpz_p) + else: + if modulus <= 0: + raise ValueError("Modulus must be positive") + modulus = int(modulus) + result = IntegerGMP(self._tonelli_shanks(int(self) % modulus, modulus)) + + return result + + def __iadd__(self, term): + if is_native_int(term): + if 0 <= term < 65536: + _gmp.mpz_add_ui(self._mpz_p, + self._mpz_p, + c_ulong(term)) + return self + if -65535 < term < 0: + _gmp.mpz_sub_ui(self._mpz_p, + self._mpz_p, + c_ulong(-term)) + return self + term = IntegerGMP(term) + _gmp.mpz_add(self._mpz_p, + self._mpz_p, + term._mpz_p) + return self + + def __isub__(self, term): + if is_native_int(term): + if 0 <= term < 65536: + _gmp.mpz_sub_ui(self._mpz_p, + self._mpz_p, + c_ulong(term)) + return self + if -65535 < term < 0: + _gmp.mpz_add_ui(self._mpz_p, + self._mpz_p, + c_ulong(-term)) + return self + term = IntegerGMP(term) + _gmp.mpz_sub(self._mpz_p, + self._mpz_p, + term._mpz_p) + return self + + def __imul__(self, term): + if is_native_int(term): + if 0 <= term < 65536: + _gmp.mpz_mul_ui(self._mpz_p, + self._mpz_p, + c_ulong(term)) + return self + if -65535 < term < 0: + _gmp.mpz_mul_ui(self._mpz_p, + self._mpz_p, + c_ulong(-term)) + _gmp.mpz_neg(self._mpz_p, self._mpz_p) + return self + term = IntegerGMP(term) + _gmp.mpz_mul(self._mpz_p, + self._mpz_p, + term._mpz_p) + return self + + def __imod__(self, divisor): + if not isinstance(divisor, IntegerGMP): + divisor = IntegerGMP(divisor) + comp = _gmp.mpz_cmp(divisor._mpz_p, + divisor._zero_mpz_p) + if comp == 0: + raise ZeroDivisionError("Division by zero") + if comp < 0: + raise ValueError("Modulus must be positive") + _gmp.mpz_mod(self._mpz_p, + self._mpz_p, + divisor._mpz_p) + return self + + # Boolean/bit operations + def __and__(self, term): + result = IntegerGMP(0) + if not isinstance(term, IntegerGMP): + term = IntegerGMP(term) + _gmp.mpz_and(result._mpz_p, + self._mpz_p, + term._mpz_p) + return result + + def __or__(self, term): + result = IntegerGMP(0) + if not isinstance(term, IntegerGMP): + term = IntegerGMP(term) + _gmp.mpz_ior(result._mpz_p, + self._mpz_p, + term._mpz_p) + return result + + def __rshift__(self, pos): + result = IntegerGMP(0) + if pos < 0: + raise ValueError("negative shift count") + if pos > 65536: + if self < 0: + return -1 + else: + return 0 + _gmp.mpz_tdiv_q_2exp(result._mpz_p, + self._mpz_p, + c_ulong(int(pos))) + return result + + def __irshift__(self, pos): + if pos < 0: + raise ValueError("negative shift count") + if pos > 65536: + if self < 0: + return -1 + else: + return 0 + _gmp.mpz_tdiv_q_2exp(self._mpz_p, + self._mpz_p, + c_ulong(int(pos))) + return self + + def __lshift__(self, pos): + result = IntegerGMP(0) + if not 0 <= pos < 65536: + raise ValueError("Incorrect shift count") + _gmp.mpz_mul_2exp(result._mpz_p, + self._mpz_p, + c_ulong(int(pos))) + return result + + def __ilshift__(self, pos): + if not 0 <= pos < 65536: + raise ValueError("Incorrect shift count") + _gmp.mpz_mul_2exp(self._mpz_p, + self._mpz_p, + c_ulong(int(pos))) + return self + + def get_bit(self, n): + """Return True if the n-th bit is set to 1. + Bit 0 is the least significant.""" + + if self < 0: + raise ValueError("no bit representation for negative values") + if n < 0: + raise ValueError("negative bit count") + if n > 65536: + return 0 + return bool(_gmp.mpz_tstbit(self._mpz_p, + c_ulong(int(n)))) + + # Extra + def is_odd(self): + return _gmp.mpz_tstbit(self._mpz_p, 0) == 1 + + def is_even(self): + return _gmp.mpz_tstbit(self._mpz_p, 0) == 0 + + def size_in_bits(self): + """Return the minimum number of bits that can encode the number.""" + + if self < 0: + raise ValueError("Conversion only valid for non-negative numbers") + return _gmp.mpz_sizeinbase(self._mpz_p, 2) + + def size_in_bytes(self): + """Return the minimum number of bytes that can encode the number.""" + return (self.size_in_bits() - 1) // 8 + 1 + + def is_perfect_square(self): + return _gmp.mpz_perfect_square_p(self._mpz_p) != 0 + + def fail_if_divisible_by(self, small_prime): + """Raise an exception if the small prime is a divisor.""" + + if is_native_int(small_prime): + if 0 < small_prime < 65536: + if _gmp.mpz_divisible_ui_p(self._mpz_p, + c_ulong(small_prime)): + raise ValueError("The value is composite") + return + small_prime = IntegerGMP(small_prime) + if _gmp.mpz_divisible_p(self._mpz_p, + small_prime._mpz_p): + raise ValueError("The value is composite") + + def multiply_accumulate(self, a, b): + """Increment the number by the product of a and b.""" + + if not isinstance(a, IntegerGMP): + a = IntegerGMP(a) + if is_native_int(b): + if 0 < b < 65536: + _gmp.mpz_addmul_ui(self._mpz_p, + a._mpz_p, + c_ulong(b)) + return self + if -65535 < b < 0: + _gmp.mpz_submul_ui(self._mpz_p, + a._mpz_p, + c_ulong(-b)) + return self + b = IntegerGMP(b) + _gmp.mpz_addmul(self._mpz_p, + a._mpz_p, + b._mpz_p) + return self + + def set(self, source): + """Set the Integer to have the given value""" + + if not isinstance(source, IntegerGMP): + source = IntegerGMP(source) + _gmp.mpz_set(self._mpz_p, + source._mpz_p) + return self + + def inplace_inverse(self, modulus): + """Compute the inverse of this number in the ring of + modulo integers. + + Raise an exception if no inverse exists. + """ + + if not isinstance(modulus, IntegerGMP): + modulus = IntegerGMP(modulus) + + comp = _gmp.mpz_cmp(modulus._mpz_p, + self._zero_mpz_p) + if comp == 0: + raise ZeroDivisionError("Modulus cannot be zero") + if comp < 0: + raise ValueError("Modulus must be positive") + + result = _gmp.mpz_invert(self._mpz_p, + self._mpz_p, + modulus._mpz_p) + if not result: + raise ValueError("No inverse value can be computed") + return self + + def inverse(self, modulus): + result = IntegerGMP(self) + result.inplace_inverse(modulus) + return result + + def gcd(self, term): + """Compute the greatest common denominator between this + number and another term.""" + + result = IntegerGMP(0) + if is_native_int(term): + if 0 < term < 65535: + _gmp.mpz_gcd_ui(result._mpz_p, + self._mpz_p, + c_ulong(term)) + return result + term = IntegerGMP(term) + _gmp.mpz_gcd(result._mpz_p, self._mpz_p, term._mpz_p) + return result + + def lcm(self, term): + """Compute the least common multiplier between this + number and another term.""" + + result = IntegerGMP(0) + if not isinstance(term, IntegerGMP): + term = IntegerGMP(term) + _gmp.mpz_lcm(result._mpz_p, self._mpz_p, term._mpz_p) + return result + + @staticmethod + def jacobi_symbol(a, n): + """Compute the Jacobi symbol""" + + if not isinstance(a, IntegerGMP): + a = IntegerGMP(a) + if not isinstance(n, IntegerGMP): + n = IntegerGMP(n) + if n <= 0 or n.is_even(): + raise ValueError("n must be positive even for the Jacobi symbol") + return _gmp.mpz_jacobi(a._mpz_p, n._mpz_p) + + # Clean-up + def __del__(self): + + try: + if self._mpz_p is not None: + if self._initialized: + _gmp.mpz_clear(self._mpz_p) + + self._mpz_p = None + except AttributeError: + pass diff --git a/frozen_deps/Cryptodome/Math/_IntegerGMP.pyi b/frozen_deps/Cryptodome/Math/_IntegerGMP.pyi new file mode 100644 index 0000000..2181b47 --- /dev/null +++ b/frozen_deps/Cryptodome/Math/_IntegerGMP.pyi @@ -0,0 +1,3 @@ +from ._IntegerBase import IntegerBase +class IntegerGMP(IntegerBase): + pass diff --git a/frozen_deps/Cryptodome/Math/_IntegerNative.py b/frozen_deps/Cryptodome/Math/_IntegerNative.py new file mode 100644 index 0000000..896107f --- /dev/null +++ b/frozen_deps/Cryptodome/Math/_IntegerNative.py @@ -0,0 +1,380 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from ._IntegerBase import IntegerBase + +from Cryptodome.Util.number import long_to_bytes, bytes_to_long + + +class IntegerNative(IntegerBase): + """A class to model a natural integer (including zero)""" + + def __init__(self, value): + if isinstance(value, float): + raise ValueError("A floating point type is not a natural number") + try: + self._value = value._value + except AttributeError: + self._value = value + + # Conversions + def __int__(self): + return self._value + + def __str__(self): + return str(int(self)) + + def __repr__(self): + return "Integer(%s)" % str(self) + + # Only Python 2.x + def __hex__(self): + return hex(self._value) + + # Only Python 3.x + def __index__(self): + return int(self._value) + + def to_bytes(self, block_size=0): + if self._value < 0: + raise ValueError("Conversion only valid for non-negative numbers") + result = long_to_bytes(self._value, block_size) + if len(result) > block_size > 0: + raise ValueError("Value too large to encode") + return result + + @classmethod + def from_bytes(cls, byte_string): + return cls(bytes_to_long(byte_string)) + + # Relations + def __eq__(self, term): + if term is None: + return False + return self._value == int(term) + + def __ne__(self, term): + return not self.__eq__(term) + + def __lt__(self, term): + return self._value < int(term) + + def __le__(self, term): + return self.__lt__(term) or self.__eq__(term) + + def __gt__(self, term): + return not self.__le__(term) + + def __ge__(self, term): + return not self.__lt__(term) + + def __nonzero__(self): + return self._value != 0 + __bool__ = __nonzero__ + + def is_negative(self): + return self._value < 0 + + # Arithmetic operations + def __add__(self, term): + try: + return self.__class__(self._value + int(term)) + except (ValueError, AttributeError, TypeError): + return NotImplemented + + def __sub__(self, term): + try: + return self.__class__(self._value - int(term)) + except (ValueError, AttributeError, TypeError): + return NotImplemented + + def __mul__(self, factor): + try: + return self.__class__(self._value * int(factor)) + except (ValueError, AttributeError, TypeError): + return NotImplemented + + def __floordiv__(self, divisor): + return self.__class__(self._value // int(divisor)) + + def __mod__(self, divisor): + divisor_value = int(divisor) + if divisor_value < 0: + raise ValueError("Modulus must be positive") + return self.__class__(self._value % divisor_value) + + def inplace_pow(self, exponent, modulus=None): + exp_value = int(exponent) + if exp_value < 0: + raise ValueError("Exponent must not be negative") + + if modulus is not None: + mod_value = int(modulus) + if mod_value < 0: + raise ValueError("Modulus must be positive") + if mod_value == 0: + raise ZeroDivisionError("Modulus cannot be zero") + else: + mod_value = None + self._value = pow(self._value, exp_value, mod_value) + return self + + def __pow__(self, exponent, modulus=None): + result = self.__class__(self) + return result.inplace_pow(exponent, modulus) + + def __abs__(self): + return abs(self._value) + + def sqrt(self, modulus=None): + + value = self._value + if modulus is None: + if value < 0: + raise ValueError("Square root of negative value") + # http://stackoverflow.com/questions/15390807/integer-square-root-in-python + + x = value + y = (x + 1) // 2 + while y < x: + x = y + y = (x + value // x) // 2 + result = x + else: + if modulus <= 0: + raise ValueError("Modulus must be positive") + result = self._tonelli_shanks(self % modulus, modulus) + + return self.__class__(result) + + def __iadd__(self, term): + self._value += int(term) + return self + + def __isub__(self, term): + self._value -= int(term) + return self + + def __imul__(self, term): + self._value *= int(term) + return self + + def __imod__(self, term): + modulus = int(term) + if modulus == 0: + raise ZeroDivisionError("Division by zero") + if modulus < 0: + raise ValueError("Modulus must be positive") + self._value %= modulus + return self + + # Boolean/bit operations + def __and__(self, term): + return self.__class__(self._value & int(term)) + + def __or__(self, term): + return self.__class__(self._value | int(term)) + + def __rshift__(self, pos): + try: + return self.__class__(self._value >> int(pos)) + except OverflowError: + if self._value >= 0: + return 0 + else: + return -1 + + def __irshift__(self, pos): + try: + self._value >>= int(pos) + except OverflowError: + if self._value >= 0: + return 0 + else: + return -1 + return self + + def __lshift__(self, pos): + try: + return self.__class__(self._value << int(pos)) + except OverflowError: + raise ValueError("Incorrect shift count") + + def __ilshift__(self, pos): + try: + self._value <<= int(pos) + except OverflowError: + raise ValueError("Incorrect shift count") + return self + + def get_bit(self, n): + if self._value < 0: + raise ValueError("no bit representation for negative values") + try: + try: + result = (self._value >> n._value) & 1 + if n._value < 0: + raise ValueError("negative bit count") + except AttributeError: + result = (self._value >> n) & 1 + if n < 0: + raise ValueError("negative bit count") + except OverflowError: + result = 0 + return result + + # Extra + def is_odd(self): + return (self._value & 1) == 1 + + def is_even(self): + return (self._value & 1) == 0 + + def size_in_bits(self): + + if self._value < 0: + raise ValueError("Conversion only valid for non-negative numbers") + + if self._value == 0: + return 1 + + bit_size = 0 + tmp = self._value + while tmp: + tmp >>= 1 + bit_size += 1 + + return bit_size + + def size_in_bytes(self): + return (self.size_in_bits() - 1) // 8 + 1 + + def is_perfect_square(self): + if self._value < 0: + return False + if self._value in (0, 1): + return True + + x = self._value // 2 + square_x = x ** 2 + + while square_x > self._value: + x = (square_x + self._value) // (2 * x) + square_x = x ** 2 + + return self._value == x ** 2 + + def fail_if_divisible_by(self, small_prime): + if (self._value % int(small_prime)) == 0: + raise ValueError("Value is composite") + + def multiply_accumulate(self, a, b): + self._value += int(a) * int(b) + return self + + def set(self, source): + self._value = int(source) + + def inplace_inverse(self, modulus): + modulus = int(modulus) + if modulus == 0: + raise ZeroDivisionError("Modulus cannot be zero") + if modulus < 0: + raise ValueError("Modulus cannot be negative") + r_p, r_n = self._value, modulus + s_p, s_n = 1, 0 + while r_n > 0: + q = r_p // r_n + r_p, r_n = r_n, r_p - q * r_n + s_p, s_n = s_n, s_p - q * s_n + if r_p != 1: + raise ValueError("No inverse value can be computed" + str(r_p)) + while s_p < 0: + s_p += modulus + self._value = s_p + return self + + def inverse(self, modulus): + result = self.__class__(self) + result.inplace_inverse(modulus) + return result + + def gcd(self, term): + r_p, r_n = abs(self._value), abs(int(term)) + while r_n > 0: + q = r_p // r_n + r_p, r_n = r_n, r_p - q * r_n + return self.__class__(r_p) + + def lcm(self, term): + term = int(term) + if self._value == 0 or term == 0: + return self.__class__(0) + return self.__class__(abs((self._value * term) // self.gcd(term)._value)) + + @staticmethod + def jacobi_symbol(a, n): + a = int(a) + n = int(n) + + if n <= 0: + raise ValueError("n must be a positive integer") + + if (n & 1) == 0: + raise ValueError("n must be even for the Jacobi symbol") + + # Step 1 + a = a % n + # Step 2 + if a == 1 or n == 1: + return 1 + # Step 3 + if a == 0: + return 0 + # Step 4 + e = 0 + a1 = a + while (a1 & 1) == 0: + a1 >>= 1 + e += 1 + # Step 5 + if (e & 1) == 0: + s = 1 + elif n % 8 in (1, 7): + s = 1 + else: + s = -1 + # Step 6 + if n % 4 == 3 and a1 % 4 == 3: + s = -s + # Step 7 + n1 = n % a1 + # Step 8 + return s * IntegerNative.jacobi_symbol(n1, a1) diff --git a/frozen_deps/Cryptodome/Math/_IntegerNative.pyi b/frozen_deps/Cryptodome/Math/_IntegerNative.pyi new file mode 100644 index 0000000..3f65a39 --- /dev/null +++ b/frozen_deps/Cryptodome/Math/_IntegerNative.pyi @@ -0,0 +1,3 @@ +from ._IntegerBase import IntegerBase +class IntegerNative(IntegerBase): + pass diff --git a/frozen_deps/Cryptodome/Math/__init__.py b/frozen_deps/Cryptodome/Math/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/frozen_deps/Cryptodome/Math/_modexp.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Math/_modexp.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..9b8cd0a Binary files /dev/null and b/frozen_deps/Cryptodome/Math/_modexp.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Protocol/KDF.py b/frozen_deps/Cryptodome/Protocol/KDF.py new file mode 100644 index 0000000..4baa276 --- /dev/null +++ b/frozen_deps/Cryptodome/Protocol/KDF.py @@ -0,0 +1,574 @@ +# coding=utf-8 +# +# KDF.py : a collection of Key Derivation Functions +# +# Part of the Python Cryptography Toolkit +# +# =================================================================== +# 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. +# =================================================================== + +import re +import struct +from functools import reduce + +from Cryptodome.Util.py3compat import (tobytes, bord, _copy_bytes, iter_range, + tostr, bchr, bstr) + +from Cryptodome.Hash import SHA1, SHA256, HMAC, CMAC, BLAKE2s +from Cryptodome.Util.strxor import strxor +from Cryptodome.Random import get_random_bytes +from Cryptodome.Util.number import size as bit_size, long_to_bytes, bytes_to_long + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, + create_string_buffer, + get_raw_buffer, c_size_t) + +_raw_salsa20_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._Salsa20", + """ + int Salsa20_8_core(const uint8_t *x, const uint8_t *y, + uint8_t *out); + """) + +_raw_scrypt_lib = load_pycryptodome_raw_lib("Cryptodome.Protocol._scrypt", + """ + typedef int (core_t)(const uint8_t [64], const uint8_t [64], uint8_t [64]); + int scryptROMix(const uint8_t *data_in, uint8_t *data_out, + size_t data_len, unsigned N, core_t *core); + """) + + +def PBKDF1(password, salt, dkLen, count=1000, hashAlgo=None): + """Derive one key from a password (or passphrase). + + This function performs key derivation according to an old version of + the PKCS#5 standard (v1.5) or `RFC2898 + `_. + + Args: + password (string): + The secret password to generate the key from. + salt (byte string): + An 8 byte 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. + dkLen (integer): + The length of the desired key. The default is 16 bytes, suitable for + instance for :mod:`Cryptodome.Cipher.AES`. + count (integer): + The number of iterations to carry out. The recommendation is 1000 or + more. + hashAlgo (module): + The hash algorithm to use, as a module or an object from the :mod:`Cryptodome.Hash` package. + The digest length must be no shorter than ``dkLen``. + The default algorithm is :mod:`Cryptodome.Hash.SHA1`. + + Return: + A byte string of length ``dkLen`` that can be used as key. + """ + + if not hashAlgo: + hashAlgo = SHA1 + password = tobytes(password) + pHash = hashAlgo.new(password+salt) + digest = pHash.digest_size + if dkLen > digest: + raise TypeError("Selected hash algorithm has a too short digest (%d bytes)." % digest) + if len(salt) != 8: + raise ValueError("Salt is not 8 bytes long (%d bytes instead)." % len(salt)) + for i in iter_range(count-1): + pHash = pHash.new(pHash.digest()) + return pHash.digest()[:dkLen] + + +def PBKDF2(password, salt, dkLen=16, count=1000, prf=None, hmac_hash_module=None): + """Derive one or more keys from a password (or passphrase). + + This function performs key derivation according to the PKCS#5 standard (v2.0). + + Args: + password (string or byte string): + The secret password to generate the key from. + salt (string or byte string): + A (byte) 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 use at least 16 bytes. + dkLen (integer): + The cumulative length of the keys to produce. + + Due to a flaw in the PBKDF2 design, you should not request more bytes + than the ``prf`` can output. For instance, ``dkLen`` should not exceed + 20 bytes in combination with ``HMAC-SHA1``. + count (integer): + The number of iterations to carry out. The higher the value, the slower + and the more secure the function becomes. + + You should find the maximum number of iterations that keeps the + key derivation still acceptable on the slowest hardware you must support. + + Although the default value is 1000, **it is recommended to use at least + 1000000 (1 million) iterations**. + prf (callable): + A pseudorandom function. It must be a function that returns a + pseudorandom byte string from two parameters: a secret and a salt. + The slower the algorithm, the more secure the derivation function. + If not specified, **HMAC-SHA1** is used. + hmac_hash_module (module): + A module from ``Cryptodome.Hash`` implementing a Merkle-Damgard cryptographic + hash, which PBKDF2 must use in combination with HMAC. + This parameter is mutually exclusive with ``prf``. + + Return: + A byte string of length ``dkLen`` that can be used as key material. + If you want multiple keys, just break up this string into segments of the desired length. + """ + + password = tobytes(password) + salt = tobytes(salt) + + if prf and hmac_hash_module: + raise ValueError("'prf' and 'hmac_hash_module' are mutually exlusive") + + if prf is None and hmac_hash_module is None: + hmac_hash_module = SHA1 + + if prf or not hasattr(hmac_hash_module, "_pbkdf2_hmac_assist"): + # Generic (and slow) implementation + + if prf is None: + prf = lambda p,s: HMAC.new(p, s, hmac_hash_module).digest() + + def link(s): + s[0], s[1] = s[1], prf(password, s[1]) + return s[0] + + key = b'' + i = 1 + while len(key) < dkLen: + s = [ prf(password, salt + struct.pack(">I", i)) ] * 2 + key += reduce(strxor, (link(s) for j in range(count)) ) + i += 1 + + else: + # Optimized implementation + key = b'' + i = 1 + while len(key)I", i)).digest() + key += base._pbkdf2_hmac_assist(first_digest, count) + i += 1 + + return key[:dkLen] + + +class _S2V(object): + """String-to-vector PRF as defined in `RFC5297`_. + + This class implements a pseudorandom function family + based on CMAC that takes as input a vector of strings. + + .. _RFC5297: http://tools.ietf.org/html/rfc5297 + """ + + def __init__(self, key, ciphermod, cipher_params=None): + """Initialize the S2V PRF. + + :Parameters: + key : byte string + A secret that can be used as key for CMACs + based on ciphers from ``ciphermod``. + ciphermod : module + A block cipher module from `Cryptodome.Cipher`. + cipher_params : dictionary + A set of extra parameters to use to create a cipher instance. + """ + + self._key = _copy_bytes(None, None, key) + self._ciphermod = ciphermod + self._last_string = self._cache = b'\x00' * ciphermod.block_size + + # Max number of update() call we can process + self._n_updates = ciphermod.block_size * 8 - 1 + + if cipher_params is None: + self._cipher_params = {} + else: + self._cipher_params = dict(cipher_params) + + @staticmethod + def new(key, ciphermod): + """Create a new S2V PRF. + + :Parameters: + key : byte string + A secret that can be used as key for CMACs + based on ciphers from ``ciphermod``. + ciphermod : module + A block cipher module from `Cryptodome.Cipher`. + """ + return _S2V(key, ciphermod) + + def _double(self, bs): + doubled = bytes_to_long(bs)<<1 + if bord(bs[0]) & 0x80: + doubled ^= 0x87 + return long_to_bytes(doubled, len(bs))[-len(bs):] + + def update(self, item): + """Pass the next component of the vector. + + The maximum number of components you can pass is equal to the block + length of the cipher (in bits) minus 1. + + :Parameters: + item : byte string + The next component of the vector. + :Raise TypeError: when the limit on the number of components has been reached. + """ + + if self._n_updates == 0: + raise TypeError("Too many components passed to S2V") + self._n_updates -= 1 + + mac = CMAC.new(self._key, + msg=self._last_string, + ciphermod=self._ciphermod, + cipher_params=self._cipher_params) + self._cache = strxor(self._double(self._cache), mac.digest()) + self._last_string = _copy_bytes(None, None, item) + + def derive(self): + """"Derive a secret from the vector of components. + + :Return: a byte string, as long as the block length of the cipher. + """ + + if len(self._last_string) >= 16: + # xorend + final = self._last_string[:-16] + strxor(self._last_string[-16:], self._cache) + else: + # zero-pad & xor + padded = (self._last_string + b'\x80' + b'\x00' * 15)[:16] + final = strxor(padded, self._double(self._cache)) + mac = CMAC.new(self._key, + msg=final, + ciphermod=self._ciphermod, + cipher_params=self._cipher_params) + return mac.digest() + + +def HKDF(master, key_len, salt, hashmod, num_keys=1, context=None): + """Derive one or more keys from a master secret using + the HMAC-based KDF defined in RFC5869_. + + Args: + master (byte string): + The unguessable value used by the KDF to generate the other keys. + It must be a high-entropy secret, though not necessarily uniform. + It must not be a password. + salt (byte string): + A non-secret, reusable value that strengthens the randomness + extraction step. + Ideally, it is as long as the digest size of the chosen hash. + If empty, a string of zeroes in used. + key_len (integer): + The length in bytes of every derived key. + hashmod (module): + A cryptographic hash algorithm from :mod:`Cryptodome.Hash`. + :mod:`Cryptodome.Hash.SHA512` is a good choice. + num_keys (integer): + The number of keys to derive. Every key is :data:`key_len` bytes long. + The maximum cumulative length of all keys is + 255 times the digest size. + context (byte string): + Optional identifier describing what the keys are used for. + + Return: + A byte string or a tuple of byte strings. + + .. _RFC5869: http://tools.ietf.org/html/rfc5869 + """ + + output_len = key_len * num_keys + if output_len > (255 * hashmod.digest_size): + raise ValueError("Too much secret data to derive") + if not salt: + salt = b'\x00' * hashmod.digest_size + if context is None: + context = b"" + + # Step 1: extract + hmac = HMAC.new(salt, master, digestmod=hashmod) + prk = hmac.digest() + + # Step 2: expand + t = [ b"" ] + n = 1 + tlen = 0 + while tlen < output_len: + hmac = HMAC.new(prk, t[-1] + context + struct.pack('B', n), digestmod=hashmod) + t.append(hmac.digest()) + tlen += hashmod.digest_size + n += 1 + derived_output = b"".join(t) + if num_keys == 1: + return derived_output[:key_len] + kol = [derived_output[idx:idx + key_len] + for idx in iter_range(0, output_len, key_len)] + return list(kol[:num_keys]) + + + +def scrypt(password, salt, key_len, N, r, p, num_keys=1): + """Derive one or more keys from a passphrase. + + Args: + password (string): + The secret pass phrase to generate the keys 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 16 bytes long. + key_len (integer): + The length in bytes of every derived key. + N (integer): + CPU/Memory cost parameter. It must be a power of 2 and less + than :math:`2^{32}`. + r (integer): + Block size parameter. + p (integer): + Parallelization parameter. + It must be no greater than :math:`(2^{32}-1)/(4r)`. + num_keys (integer): + The number of keys to derive. Every key is :data:`key_len` bytes long. + By default, only 1 key is generated. + The maximum cumulative length of all keys is :math:`(2^{32}-1)*32` + (that is, 128TB). + + A good choice of parameters *(N, r , p)* was suggested + by Colin Percival in his `presentation in 2009`__: + + - *( 2¹⁴, 8, 1 )* for interactive logins (≤100ms) + - *( 2²⁰, 8, 1 )* for file encryption (≤5s) + + Return: + A byte string or a tuple of byte strings. + + .. __: http://www.tarsnap.com/scrypt/scrypt-slides.pdf + """ + + if 2 ** (bit_size(N) - 1) != N: + raise ValueError("N must be a power of 2") + if N >= 2 ** 32: + raise ValueError("N is too big") + if p > ((2 ** 32 - 1) * 32) // (128 * r): + raise ValueError("p or r are too big") + + prf_hmac_sha256 = lambda p, s: HMAC.new(p, s, SHA256).digest() + + stage_1 = PBKDF2(password, salt, p * 128 * r, 1, prf=prf_hmac_sha256) + + scryptROMix = _raw_scrypt_lib.scryptROMix + core = _raw_salsa20_lib.Salsa20_8_core + + # Parallelize into p flows + data_out = [] + for flow in iter_range(p): + idx = flow * 128 * r + buffer_out = create_string_buffer(128 * r) + result = scryptROMix(stage_1[idx : idx + 128 * r], + buffer_out, + c_size_t(128 * r), + N, + core) + if result: + raise ValueError("Error %X while running scrypt" % result) + data_out += [ get_raw_buffer(buffer_out) ] + + dk = PBKDF2(password, + b"".join(data_out), + key_len * num_keys, 1, + prf=prf_hmac_sha256) + + if num_keys == 1: + return dk + + kol = [dk[idx:idx + key_len] + for idx in iter_range(0, key_len * num_keys, key_len)] + return kol + + +def _bcrypt_encode(data): + s = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" + + bits = [] + for c in data: + bits_c = bin(bord(c))[2:].zfill(8) + bits.append(bstr(bits_c)) + bits = b"".join(bits) + + bits6 = [ bits[idx:idx+6] for idx in range(0, len(bits), 6) ] + + result = [] + for g in bits6[:-1]: + idx = int(g, 2) + result.append(s[idx]) + + g = bits6[-1] + idx = int(g, 2) << (6 - len(g)) + result.append(s[idx]) + result = "".join(result) + + return tobytes(result) + + +def _bcrypt_decode(data): + s = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" + + bits = [] + for c in tostr(data): + idx = s.find(c) + bits6 = bin(idx)[2:].zfill(6) + bits.append(bits6) + bits = "".join(bits) + + modulo4 = len(data) % 4 + if modulo4 == 1: + raise ValueError("Incorrect length") + elif modulo4 == 2: + bits = bits[:-4] + elif modulo4 == 3: + bits = bits[:-2] + + bits8 = [ bits[idx:idx+8] for idx in range(0, len(bits), 8) ] + + result = [] + for g in bits8: + result.append(bchr(int(g, 2))) + result = b"".join(result) + + return result + + +def _bcrypt_hash(password, cost, salt, constant, invert): + from Cryptodome.Cipher import _EKSBlowfish + + if len(password) > 72: + raise ValueError("The password is too long. It must be 72 bytes at most.") + + if not (4 <= cost <= 31): + raise ValueError("bcrypt cost factor must be in the range 4..31") + + cipher = _EKSBlowfish.new(password, _EKSBlowfish.MODE_ECB, salt, cost, invert) + ctext = constant + for _ in range(64): + ctext = cipher.encrypt(ctext) + return ctext + + +def bcrypt(password, cost, salt=None): + """Hash a password into a key, using the OpenBSD bcrypt protocol. + + Args: + password (byte string or string): + The secret password or pass phrase. + It must be at most 72 bytes long. + It must not contain the zero byte. + Unicode strings will be encoded as UTF-8. + cost (integer): + The exponential factor that makes it slower to compute the hash. + It must be in the range 4 to 31. + A value of at least 12 is recommended. + salt (byte string): + Optional. Random byte string to thwarts dictionary and rainbow table + attacks. It must be 16 bytes long. + If not passed, a random value is generated. + + Return (byte string): + The bcrypt hash + + Raises: + ValueError: if password is longer than 72 bytes or if it contains the zero byte + + """ + + password = tobytes(password, "utf-8") + + if password.find(bchr(0)[0]) != -1: + raise ValueError("The password contains the zero byte") + + if len(password) < 72: + password += b"\x00" + + if salt is None: + salt = get_random_bytes(16) + if len(salt) != 16: + raise ValueError("bcrypt salt must be 16 bytes long") + + ctext = _bcrypt_hash(password, cost, salt, b"OrpheanBeholderScryDoubt", True) + + cost_enc = b"$" + bstr(str(cost).zfill(2)) + salt_enc = b"$" + _bcrypt_encode(salt) + hash_enc = _bcrypt_encode(ctext[:-1]) # only use 23 bytes, not 24 + return b"$2a" + cost_enc + salt_enc + hash_enc + + +def bcrypt_check(password, bcrypt_hash): + """Verify if the provided password matches the given bcrypt hash. + + Args: + password (byte string or string): + The secret password or pass phrase to test. + It must be at most 72 bytes long. + It must not contain the zero byte. + Unicode strings will be encoded as UTF-8. + bcrypt_hash (byte string, bytearray): + The reference bcrypt hash the password needs to be checked against. + + Raises: + ValueError: if the password does not match + """ + + bcrypt_hash = tobytes(bcrypt_hash) + + if len(bcrypt_hash) != 60: + raise ValueError("Incorrect length of the bcrypt hash: %d bytes instead of 60" % len(bcrypt_hash)) + + if bcrypt_hash[:4] != b'$2a$': + raise ValueError("Unsupported prefix") + + p = re.compile(br'\$2a\$([0-9][0-9])\$([A-Za-z0-9./]{22,22})([A-Za-z0-9./]{31,31})') + r = p.match(bcrypt_hash) + if not r: + raise ValueError("Incorrect bcrypt hash format") + + cost = int(r.group(1)) + if not (4 <= cost <= 31): + raise ValueError("Incorrect cost") + + salt = _bcrypt_decode(r.group(2)) + + bcrypt_hash2 = bcrypt(password, cost, salt) + + secret = get_random_bytes(16) + + mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=bcrypt_hash).digest() + mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=bcrypt_hash2).digest() + if mac1 != mac2: + raise ValueError("Incorrect bcrypt hash") diff --git a/frozen_deps/Cryptodome/Protocol/KDF.pyi b/frozen_deps/Cryptodome/Protocol/KDF.pyi new file mode 100644 index 0000000..fb004bf --- /dev/null +++ b/frozen_deps/Cryptodome/Protocol/KDF.pyi @@ -0,0 +1,24 @@ +from types import ModuleType +from typing import Optional, Callable, Tuple, Union, Dict, Any + +RNG = Callable[[int], bytes] + +def PBKDF1(password: str, salt: bytes, dkLen: int, count: Optional[int]=1000, hashAlgo: Optional[ModuleType]=None) -> bytes: ... +def PBKDF2(password: str, salt: bytes, dkLen: Optional[int]=16, count: Optional[int]=1000, prf: Optional[RNG]=None, hmac_hash_module: Optional[ModuleType]=None) -> bytes: ... + +class _S2V(object): + def __init__(self, key: bytes, ciphermod: ModuleType, cipher_params: Optional[Dict[Any, Any]]=None) -> None: ... + + @staticmethod + def new(key: bytes, ciphermod: ModuleType) -> None: ... + def update(self, item: bytes) -> None: ... + def derive(self) -> bytes: ... + +def HKDF(master: bytes, key_len: int, salt: bytes, hashmod: ModuleType, num_keys: Optional[int]=1, context: Optional[bytes]=None) -> Union[bytes, Tuple[bytes, ...]]: ... + +def scrypt(password: str, salt: str, key_len: int, N: int, r: int, p: int, num_keys: Optional[int]=1) -> Union[bytes, Tuple[bytes, ...]]: ... + +def _bcrypt_decode(data: bytes) -> bytes: ... +def _bcrypt_hash(password:bytes , cost: int, salt: bytes, constant:bytes, invert:bool) -> bytes: ... +def bcrypt(password: Union[bytes, str], cost: int, salt: Optional[bytes]=None) -> bytes: ... +def bcrypt_check(password: Union[bytes, str], bcrypt_hash: Union[bytes, bytearray, str]) -> None: ... diff --git a/frozen_deps/Cryptodome/Protocol/SecretSharing.py b/frozen_deps/Cryptodome/Protocol/SecretSharing.py new file mode 100644 index 0000000..6fdc9b4 --- /dev/null +++ b/frozen_deps/Cryptodome/Protocol/SecretSharing.py @@ -0,0 +1,278 @@ +# +# SecretSharing.py : distribute a secret amongst a group of participants +# +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Util.py3compat import is_native_int +from Cryptodome.Util import number +from Cryptodome.Util.number import long_to_bytes, bytes_to_long +from Cryptodome.Random import get_random_bytes as rng + + +def _mult_gf2(f1, f2): + """Multiply two polynomials in GF(2)""" + + # Ensure f2 is the smallest + if f2 > f1: + f1, f2 = f2, f1 + z = 0 + while f2: + if f2 & 1: + z ^= f1 + f1 <<= 1 + f2 >>= 1 + return z + + +def _div_gf2(a, b): + """ + Compute division of polynomials over GF(2). + Given a and b, it finds two polynomials q and r such that: + + a = b*q + r with deg(r)= d: + s = 1 << (deg(r) - d) + q ^= s + r ^= _mult_gf2(b, s) + return (q, r) + + +class _Element(object): + """Element of GF(2^128) field""" + + # The irreducible polynomial defining this field is 1+x+x^2+x^7+x^128 + irr_poly = 1 + 2 + 4 + 128 + 2 ** 128 + + def __init__(self, encoded_value): + """Initialize the element to a certain value. + + The value passed as parameter is internally encoded as + a 128-bit integer, where each bit represents a polynomial + coefficient. The LSB is the constant coefficient. + """ + + if is_native_int(encoded_value): + self._value = encoded_value + elif len(encoded_value) == 16: + self._value = bytes_to_long(encoded_value) + else: + raise ValueError("The encoded value must be an integer or a 16 byte string") + + def __eq__(self, other): + return self._value == other._value + + def __int__(self): + """Return the field element, encoded as a 128-bit integer.""" + return self._value + + def encode(self): + """Return the field element, encoded as a 16 byte string.""" + return long_to_bytes(self._value, 16) + + def __mul__(self, factor): + + f1 = self._value + f2 = factor._value + + # Make sure that f2 is the smallest, to speed up the loop + if f2 > f1: + f1, f2 = f2, f1 + + if self.irr_poly in (f1, f2): + return _Element(0) + + mask1 = 2 ** 128 + v, z = f1, 0 + while f2: + # if f2 ^ 1: z ^= v + mask2 = int(bin(f2 & 1)[2:] * 128, base=2) + z = (mask2 & (z ^ v)) | ((mask1 - mask2 - 1) & z) + v <<= 1 + # if v & mask1: v ^= self.irr_poly + mask3 = int(bin((v >> 128) & 1)[2:] * 128, base=2) + v = (mask3 & (v ^ self.irr_poly)) | ((mask1 - mask3 - 1) & v) + f2 >>= 1 + return _Element(z) + + def __add__(self, term): + return _Element(self._value ^ term._value) + + def inverse(self): + """Return the inverse of this element in GF(2^128).""" + + # We use the Extended GCD algorithm + # http://en.wikipedia.org/wiki/Polynomial_greatest_common_divisor + + if self._value == 0: + raise ValueError("Inversion of zero") + + r0, r1 = self._value, self.irr_poly + s0, s1 = 1, 0 + while r1 > 0: + q = _div_gf2(r0, r1)[0] + r0, r1 = r1, r0 ^ _mult_gf2(q, r1) + s0, s1 = s1, s0 ^ _mult_gf2(q, s1) + return _Element(s0) + + def __pow__(self, exponent): + result = _Element(self._value) + for _ in range(exponent - 1): + result = result * self + return result + + +class Shamir(object): + """Shamir's secret sharing scheme. + + A secret is split into ``n`` shares, and it is sufficient to collect + ``k`` of them to reconstruct the secret. + """ + + @staticmethod + def split(k, n, secret, ssss=False): + """Split a secret into ``n`` shares. + + The secret can be reconstructed later using just ``k`` shares + out of the original ``n``. + Each share must be kept confidential to the person it was + assigned to. + + Each share is associated to an index (starting from 1). + + Args: + k (integer): + The sufficient number of shares to reconstruct the secret (``k < n``). + n (integer): + The number of shares that this method will create. + secret (byte string): + A byte string of 16 bytes (e.g. the AES 128 key). + ssss (bool): + If ``True``, the shares can be used with the ``ssss`` utility. + Default: ``False``. + + Return (tuples): + ``n`` tuples. A tuple is meant for each participant and it contains two items: + + 1. the unique index (an integer) + 2. the share (a byte string, 16 bytes) + """ + + # + # We create a polynomial with random coefficients in GF(2^128): + # + # p(x) = \sum_{i=0}^{k-1} c_i * x^i + # + # c_0 is the encoded secret + # + + coeffs = [_Element(rng(16)) for i in range(k - 1)] + coeffs.append(_Element(secret)) + + # Each share is y_i = p(x_i) where x_i is the public index + # associated to each of the n users. + + def make_share(user, coeffs, ssss): + idx = _Element(user) + share = _Element(0) + for coeff in coeffs: + share = idx * share + coeff + if ssss: + share += _Element(user) ** len(coeffs) + return share.encode() + + return [(i, make_share(i, coeffs, ssss)) for i in range(1, n + 1)] + + @staticmethod + def combine(shares, ssss=False): + """Recombine a secret, if enough shares are presented. + + Args: + shares (tuples): + The *k* tuples, each containin the index (an integer) and + the share (a byte string, 16 bytes long) that were assigned to + a participant. + ssss (bool): + If ``True``, the shares were produced by the ``ssss`` utility. + Default: ``False``. + + Return: + The original secret, as a byte string (16 bytes long). + """ + + # + # Given k points (x,y), the interpolation polynomial of degree k-1 is: + # + # L(x) = \sum_{j=0}^{k-1} y_i * l_j(x) + # + # where: + # + # l_j(x) = \prod_{ \overset{0 \le m \le k-1}{m \ne j} } + # \frac{x - x_m}{x_j - x_m} + # + # However, in this case we are purely interested in the constant + # coefficient of L(x). + # + + k = len(shares) + + gf_shares = [] + for x in shares: + idx = _Element(x[0]) + value = _Element(x[1]) + if any(y[0] == idx for y in gf_shares): + raise ValueError("Duplicate share") + if ssss: + value += idx ** k + gf_shares.append((idx, value)) + + result = _Element(0) + for j in range(k): + x_j, y_j = gf_shares[j] + + numerator = _Element(1) + denominator = _Element(1) + + for m in range(k): + x_m = gf_shares[m][0] + if m != j: + numerator *= x_m + denominator *= x_j + x_m + result += y_j * numerator * denominator.inverse() + return result.encode() diff --git a/frozen_deps/Cryptodome/Protocol/SecretSharing.pyi b/frozen_deps/Cryptodome/Protocol/SecretSharing.pyi new file mode 100644 index 0000000..5952c99 --- /dev/null +++ b/frozen_deps/Cryptodome/Protocol/SecretSharing.pyi @@ -0,0 +1,22 @@ +from typing import Union, List, Tuple, Optional + +def _mult_gf2(f1: int, f2: int) -> int : ... +def _div_gf2(a: int, b: int) -> int : ... + +class _Element(object): + irr_poly: int + def __init__(self, encoded_value: Union[int, bytes]) -> None: ... + def __eq__(self, other) -> bool: ... + def __int__(self) -> int: ... + def encode(self) -> bytes: ... + def __mul__(self, factor: int) -> _Element: ... + def __add__(self, term: _Element) -> _Element: ... + def inverse(self) -> _Element: ... + def __pow__(self, exponent) -> _Element: ... + +class Shamir(object): + @staticmethod + def split(k: int, n: int, secret: bytes, ssss: Optional[bool]) -> List[Tuple[int, bytes]]: ... + @staticmethod + def combine(shares: List[Tuple[int, bytes]], ssss: Optional[bool]) -> bytes: ... + diff --git a/frozen_deps/Cryptodome/Protocol/__init__.py b/frozen_deps/Cryptodome/Protocol/__init__.py new file mode 100644 index 0000000..efdf034 --- /dev/null +++ b/frozen_deps/Cryptodome/Protocol/__init__.py @@ -0,0 +1,31 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +__all__ = ['KDF', 'SecretSharing'] diff --git a/frozen_deps/Cryptodome/Protocol/__init__.pyi b/frozen_deps/Cryptodome/Protocol/__init__.pyi new file mode 100644 index 0000000..377ed90 --- /dev/null +++ b/frozen_deps/Cryptodome/Protocol/__init__.pyi @@ -0,0 +1 @@ +__all__ = ['KDF.pyi', 'SecretSharing.pyi'] diff --git a/frozen_deps/Cryptodome/Protocol/_scrypt.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Protocol/_scrypt.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..dbc8ca2 Binary files /dev/null and b/frozen_deps/Cryptodome/Protocol/_scrypt.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/PublicKey/DSA.py b/frozen_deps/Cryptodome/PublicKey/DSA.py new file mode 100644 index 0000000..2aaf864 --- /dev/null +++ b/frozen_deps/Cryptodome/PublicKey/DSA.py @@ -0,0 +1,679 @@ +# -*- 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. +# =================================================================== + +__all__ = ['generate', 'construct', 'DsaKey', 'import_key' ] + +import binascii +import struct +import itertools + +from Cryptodome.Util.py3compat import bchr, bord, tobytes, tostr, iter_range + +from Cryptodome import Random +from Cryptodome.IO import PKCS8, PEM +from Cryptodome.Hash import SHA256 +from Cryptodome.Util.asn1 import ( + DerObject, DerSequence, + DerInteger, DerObjectId, + DerBitString, + ) + +from Cryptodome.Math.Numbers import Integer +from Cryptodome.Math.Primality import (test_probable_prime, COMPOSITE, + PROBABLY_PRIME) + +from Cryptodome.PublicKey import (_expand_subject_public_key_info, + _create_subject_public_key_info, + _extract_subject_public_key_info) + +# ; The following ASN.1 types are relevant for DSA +# +# SubjectPublicKeyInfo ::= SEQUENCE { +# algorithm AlgorithmIdentifier, +# subjectPublicKey BIT STRING +# } +# +# id-dsa ID ::= { iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 1 } +# +# ; See RFC3279 +# Dss-Parms ::= SEQUENCE { +# p INTEGER, +# q INTEGER, +# g INTEGER +# } +# +# DSAPublicKey ::= INTEGER +# +# DSSPrivatKey_OpenSSL ::= SEQUENCE +# version INTEGER, +# p INTEGER, +# q INTEGER, +# g INTEGER, +# y INTEGER, +# x INTEGER +# } +# + +class DsaKey(object): + r"""Class defining an actual DSA key. + Do not instantiate directly. + Use :func:`generate`, :func:`construct` or :func:`import_key` instead. + + :ivar p: DSA modulus + :vartype p: integer + + :ivar q: Order of the subgroup + :vartype q: integer + + :ivar g: Generator + :vartype g: integer + + :ivar y: Public key + :vartype y: integer + + :ivar x: Private key + :vartype x: integer + """ + + _keydata = ['y', 'g', 'p', 'q', 'x'] + + def __init__(self, key_dict): + input_set = set(key_dict.keys()) + public_set = set(('y' , 'g', 'p', 'q')) + if not public_set.issubset(input_set): + raise ValueError("Some DSA components are missing = %s" % + str(public_set - input_set)) + extra_set = input_set - public_set + if extra_set and extra_set != set(('x',)): + raise ValueError("Unknown DSA components = %s" % + str(extra_set - set(('x',)))) + self._key = dict(key_dict) + + def _sign(self, m, k): + if not self.has_private(): + raise TypeError("DSA public key cannot be used for signing") + if not (1 < k < self.q): + raise ValueError("k is not between 2 and q-1") + + x, q, p, g = [self._key[comp] for comp in ['x', 'q', 'p', 'g']] + + blind_factor = Integer.random_range(min_inclusive=1, + max_exclusive=q) + inv_blind_k = (blind_factor * k).inverse(q) + blind_x = x * blind_factor + + r = pow(g, k, p) % q # r = (g**k mod p) mod q + s = (inv_blind_k * (blind_factor * m + blind_x * r)) % q + return map(int, (r, s)) + + def _verify(self, m, sig): + r, s = sig + y, q, p, g = [self._key[comp] for comp in ['y', 'q', 'p', 'g']] + if not (0 < r < q) or not (0 < s < q): + return False + w = Integer(s).inverse(q) + u1 = (w * m) % q + u2 = (w * r) % q + v = (pow(g, u1, p) * pow(y, u2, p) % p) % q + return v == r + + def has_private(self): + """Whether this is a DSA private key""" + + return 'x' in self._key + + def can_encrypt(self): # legacy + return False + + def can_sign(self): # legacy + return True + + def publickey(self): + """A matching DSA public key. + + Returns: + a new :class:`DsaKey` object + """ + + public_components = dict((k, self._key[k]) for k in ('y', 'g', 'p', 'q')) + return DsaKey(public_components) + + def __eq__(self, other): + if bool(self.has_private()) != bool(other.has_private()): + return False + + result = True + for comp in self._keydata: + result = result and (getattr(self._key, comp, None) == + getattr(other._key, comp, None)) + return result + + def __ne__(self, other): + return not self.__eq__(other) + + def __getstate__(self): + # DSA key is not pickable + from pickle import PicklingError + raise PicklingError + + def domain(self): + """The DSA domain parameters. + + Returns + tuple : (p,q,g) + """ + + return [int(self._key[comp]) for comp in ('p', 'q', 'g')] + + def __repr__(self): + attrs = [] + for k in self._keydata: + if k == 'p': + bits = Integer(self.p).size_in_bits() + attrs.append("p(%d)" % (bits,)) + elif hasattr(self, 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 __getattr__(self, item): + try: + return int(self._key[item]) + except KeyError: + raise AttributeError(item) + + def export_key(self, format='PEM', pkcs8=None, passphrase=None, + protection=None, randfunc=None): + """Export this DSA key. + + Args: + format (string): + The encoding for the output: + + - *'PEM'* (default). ASCII as per `RFC1421`_/ `RFC1423`_. + - *'DER'*. Binary ASN.1 encoding. + - *'OpenSSH'*. ASCII one-liner as per `RFC4253`_. + Only suitable for public keys, not for private keys. + + passphrase (string): + *Private keys only*. The pass phrase to protect the output. + + pkcs8 (boolean): + *Private keys only*. If ``True`` (default), the key is encoded + with `PKCS#8`_. If ``False``, it is encoded in the custom + OpenSSL/OpenSSH container. + + protection (string): + *Only in combination with a pass phrase*. + The encryption scheme to use to protect the output. + + If :data:`pkcs8` takes value ``True``, this is the PKCS#8 + algorithm to use for deriving the secret and encrypting + the private DSA key. + For a complete list of algorithms, see :mod:`Cryptodome.IO.PKCS8`. + The default is *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC*. + + If :data:`pkcs8` is ``False``, the obsolete PEM encryption scheme is + used. It is based on MD5 for key derivation, and Triple DES for + encryption. Parameter :data:`protection` is then ignored. + + The combination ``format='DER'`` and ``pkcs8=False`` is not allowed + if a passphrase is present. + + randfunc (callable): + A function that returns random bytes. + By default it is :func:`Cryptodome.Random.get_random_bytes`. + + Returns: + byte string : the encoded key + + Raises: + ValueError : when the format is unknown or when you try to encrypt a private + key with *DER* format and OpenSSL/OpenSSH. + + .. warning:: + If you don't provide a pass phrase, the private key will be + exported in the clear! + + .. _RFC1421: http://www.ietf.org/rfc/rfc1421.txt + .. _RFC1423: http://www.ietf.org/rfc/rfc1423.txt + .. _RFC4253: http://www.ietf.org/rfc/rfc4253.txt + .. _`PKCS#8`: http://www.ietf.org/rfc/rfc5208.txt + """ + + if passphrase is not None: + passphrase = tobytes(passphrase) + + if randfunc is None: + randfunc = Random.get_random_bytes + + if format == 'OpenSSH': + tup1 = [self._key[x].to_bytes() for x in ('p', 'q', 'g', 'y')] + + def func(x): + if (bord(x[0]) & 0x80): + return bchr(0) + x + else: + return x + + tup2 = [func(x) for x in tup1] + keyparts = [b'ssh-dss'] + tup2 + keystring = b''.join( + [struct.pack(">I", len(kp)) + kp for kp in keyparts] + ) + return b'ssh-dss ' + binascii.b2a_base64(keystring)[:-1] + + # DER format is always used, even in case of PEM, which simply + # encodes it into BASE64. + params = DerSequence([self.p, self.q, self.g]) + if self.has_private(): + if pkcs8 is None: + pkcs8 = True + if pkcs8: + if not protection: + protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC' + private_key = DerInteger(self.x).encode() + binary_key = PKCS8.wrap( + private_key, oid, passphrase, + protection, key_params=params, + randfunc=randfunc + ) + if passphrase: + key_type = 'ENCRYPTED PRIVATE' + else: + key_type = 'PRIVATE' + passphrase = None + else: + if format != 'PEM' and passphrase: + raise ValueError("DSA private key cannot be encrypted") + ints = [0, self.p, self.q, self.g, self.y, self.x] + binary_key = DerSequence(ints).encode() + key_type = "DSA PRIVATE" + else: + if pkcs8: + raise ValueError("PKCS#8 is only meaningful for private keys") + + binary_key = _create_subject_public_key_info(oid, + DerInteger(self.y), params) + key_type = "PUBLIC" + + if format == 'DER': + return binary_key + if format == 'PEM': + pem_str = PEM.encode( + binary_key, key_type + " KEY", + passphrase, randfunc + ) + return tobytes(pem_str) + raise ValueError("Unknown key format '%s'. Cannot export the DSA key." % format) + + # Backward-compatibility + exportKey = export_key + + # Methods defined in PyCryptodome that we don't support anymore + + def sign(self, M, K): + raise NotImplementedError("Use module Cryptodome.Signature.DSS instead") + + def verify(self, M, signature): + raise NotImplementedError("Use module Cryptodome.Signature.DSS instead") + + def encrypt(self, plaintext, K): + raise NotImplementedError + + def decrypt(self, ciphertext): + raise NotImplementedError + + def blind(self, M, B): + raise NotImplementedError + + def unblind(self, M, B): + raise NotImplementedError + + def size(self): + raise NotImplementedError + + +def _generate_domain(L, randfunc): + """Generate a new set of DSA domain parameters""" + + N = { 1024:160, 2048:224, 3072:256 }.get(L) + if N is None: + raise ValueError("Invalid modulus length (%d)" % L) + + outlen = SHA256.digest_size * 8 + n = (L + outlen - 1) // outlen - 1 # ceil(L/outlen) -1 + b_ = L - 1 - (n * outlen) + + # Generate q (A.1.1.2) + q = Integer(4) + upper_bit = 1 << (N - 1) + while test_probable_prime(q, randfunc) != PROBABLY_PRIME: + seed = randfunc(64) + U = Integer.from_bytes(SHA256.new(seed).digest()) & (upper_bit - 1) + q = U | upper_bit | 1 + + assert(q.size_in_bits() == N) + + # Generate p (A.1.1.2) + offset = 1 + upper_bit = 1 << (L - 1) + while True: + V = [ SHA256.new(seed + Integer(offset + j).to_bytes()).digest() + for j in iter_range(n + 1) ] + V = [ Integer.from_bytes(v) for v in V ] + W = sum([V[i] * (1 << (i * outlen)) for i in iter_range(n)], + (V[n] & ((1 << b_) - 1)) * (1 << (n * outlen))) + + X = Integer(W + upper_bit) # 2^{L-1} < X < 2^{L} + assert(X.size_in_bits() == L) + + c = X % (q * 2) + p = X - (c - 1) # 2q divides (p-1) + if p.size_in_bits() == L and \ + test_probable_prime(p, randfunc) == PROBABLY_PRIME: + break + offset += n + 1 + + # Generate g (A.2.3, index=1) + e = (p - 1) // q + for count in itertools.count(1): + U = seed + b"ggen" + bchr(1) + Integer(count).to_bytes() + W = Integer.from_bytes(SHA256.new(U).digest()) + g = pow(W, e, p) + if g != 1: + break + + return (p, q, g, seed) + + +def generate(bits, randfunc=None, domain=None): + """Generate a new DSA key pair. + + The algorithm follows Appendix A.1/A.2 and B.1 of `FIPS 186-4`_, + respectively for domain generation and key pair generation. + + Args: + bits (integer): + Key length, or size (in bits) of the DSA modulus *p*. + It must be 1024, 2048 or 3072. + + randfunc (callable): + Random number generation function; it accepts a single integer N + and return a string of random data N bytes long. + If not specified, :func:`Cryptodome.Random.get_random_bytes` is used. + + domain (tuple): + The DSA domain parameters *p*, *q* and *g* as a list of 3 + integers. Size of *p* and *q* must comply to `FIPS 186-4`_. + If not specified, the parameters are created anew. + + Returns: + :class:`DsaKey` : a new DSA key object + + Raises: + ValueError : when **bits** is too little, too big, or not a multiple of 64. + + .. _FIPS 186-4: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf + """ + + if randfunc is None: + randfunc = Random.get_random_bytes + + if domain: + p, q, g = map(Integer, domain) + + ## Perform consistency check on domain parameters + # P and Q must be prime + fmt_error = test_probable_prime(p) == COMPOSITE + fmt_error = test_probable_prime(q) == COMPOSITE + # Verify Lagrange's theorem for sub-group + fmt_error |= ((p - 1) % q) != 0 + fmt_error |= g <= 1 or g >= p + fmt_error |= pow(g, q, p) != 1 + if fmt_error: + raise ValueError("Invalid DSA domain parameters") + else: + p, q, g, _ = _generate_domain(bits, randfunc) + + L = p.size_in_bits() + N = q.size_in_bits() + + if L != bits: + raise ValueError("Mismatch between size of modulus (%d)" + " and 'bits' parameter (%d)" % (L, bits)) + + if (L, N) not in [(1024, 160), (2048, 224), + (2048, 256), (3072, 256)]: + raise ValueError("Lengths of p and q (%d, %d) are not compatible" + "to FIPS 186-3" % (L, N)) + + if not 1 < g < p: + raise ValueError("Incorrent DSA generator") + + # B.1.1 + c = Integer.random(exact_bits=N + 64, randfunc=randfunc) + x = c % (q - 1) + 1 # 1 <= x <= q-1 + y = pow(g, x, p) + + key_dict = { 'y':y, 'g':g, 'p':p, 'q':q, 'x':x } + return DsaKey(key_dict) + + +def construct(tup, consistency_check=True): + """Construct a DSA key from a tuple of valid DSA components. + + Args: + 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. + + consistency_check (boolean): + If ``True``, the library will verify that the provided components + fulfil the main DSA properties. + + Raises: + ValueError: when the key being imported fails the most basic DSA validity checks. + + Returns: + :class:`DsaKey` : a DSA key object + """ + + key_dict = dict(zip(('y', 'g', 'p', 'q', 'x'), map(Integer, tup))) + key = DsaKey(key_dict) + + fmt_error = False + if consistency_check: + # P and Q must be prime + fmt_error = test_probable_prime(key.p) == COMPOSITE + fmt_error = test_probable_prime(key.q) == COMPOSITE + # Verify Lagrange's theorem for sub-group + fmt_error |= ((key.p - 1) % key.q) != 0 + fmt_error |= key.g <= 1 or key.g >= key.p + fmt_error |= pow(key.g, key.q, key.p) != 1 + # Public key + fmt_error |= key.y <= 0 or key.y >= key.p + if hasattr(key, 'x'): + fmt_error |= key.x <= 0 or key.x >= key.q + fmt_error |= pow(key.g, key.x, key.p) != key.y + + if fmt_error: + raise ValueError("Invalid DSA key components") + + return key + + +# Dss-Parms ::= SEQUENCE { +# p OCTET STRING, +# q OCTET STRING, +# g OCTET STRING +# } +# DSAPublicKey ::= INTEGER -- public key, y + +def _import_openssl_private(encoded, passphrase, params): + if params: + raise ValueError("DSA private key already comes with parameters") + der = DerSequence().decode(encoded, nr_elements=6, only_ints_expected=True) + if der[0] != 0: + raise ValueError("No version found") + tup = [der[comp] for comp in (4, 3, 1, 2, 5)] + return construct(tup) + + +def _import_subjectPublicKeyInfo(encoded, passphrase, params): + + algoid, encoded_key, emb_params = _expand_subject_public_key_info(encoded) + if algoid != oid: + raise ValueError("No DSA subjectPublicKeyInfo") + if params and emb_params: + raise ValueError("Too many DSA parameters") + + y = DerInteger().decode(encoded_key).value + p, q, g = list(DerSequence().decode(params or emb_params)) + tup = (y, g, p, q) + return construct(tup) + + +def _import_x509_cert(encoded, passphrase, params): + + sp_info = _extract_subject_public_key_info(encoded) + return _import_subjectPublicKeyInfo(sp_info, None, params) + + +def _import_pkcs8(encoded, passphrase, params): + if params: + raise ValueError("PKCS#8 already includes parameters") + k = PKCS8.unwrap(encoded, passphrase) + if k[0] != oid: + raise ValueError("No PKCS#8 encoded DSA key") + x = DerInteger().decode(k[1]).value + p, q, g = list(DerSequence().decode(k[2])) + tup = (pow(g, x, p), g, p, q, x) + return construct(tup) + + +def _import_key_der(key_data, passphrase, params): + """Import a DSA key (public or private half), encoded in DER form.""" + + decodings = (_import_openssl_private, + _import_subjectPublicKeyInfo, + _import_x509_cert, + _import_pkcs8) + + for decoding in decodings: + try: + return decoding(key_data, passphrase, params) + except ValueError: + pass + + raise ValueError("DSA key format is not supported") + + +def import_key(extern_key, passphrase=None): + """Import a DSA key. + + Args: + extern_key (string or byte string): + The DSA key to import. + + The following formats are supported for a DSA **public** key: + + - X.509 certificate (binary DER or PEM) + - X.509 ``subjectPublicKeyInfo`` (binary DER or PEM) + - OpenSSH (ASCII one-liner, see `RFC4253`_) + + The following formats are supported for a DSA **private** key: + + - `PKCS#8`_ ``PrivateKeyInfo`` or ``EncryptedPrivateKeyInfo`` + DER SEQUENCE (binary or PEM) + - OpenSSL/OpenSSH custom format (binary or PEM) + + For details about the PEM encoding, see `RFC1421`_/`RFC1423`_. + + passphrase (string): + In case of an encrypted private key, this is the pass phrase + from which the decryption key is derived. + + Encryption may be applied either at the `PKCS#8`_ or at the PEM level. + + Returns: + :class:`DsaKey` : a DSA key object + + Raises: + ValueError : 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 + .. _RFC4253: http://www.ietf.org/rfc/rfc4253.txt + .. _PKCS#8: http://www.ietf.org/rfc/rfc5208.txt + """ + + extern_key = tobytes(extern_key) + if passphrase is not None: + passphrase = tobytes(passphrase) + + if extern_key.startswith(b'-----'): + # This is probably a PEM encoded key + (der, marker, enc_flag) = PEM.decode(tostr(extern_key), passphrase) + if enc_flag: + passphrase = None + return _import_key_der(der, passphrase, None) + + if extern_key.startswith(b'ssh-dss '): + # This is probably a public OpenSSH key + keystring = binascii.a2b_base64(extern_key.split(b' ')[1]) + keyparts = [] + while len(keystring) > 4: + length = struct.unpack(">I", keystring[:4])[0] + keyparts.append(keystring[4:4 + length]) + keystring = keystring[4 + length:] + if keyparts[0] == b"ssh-dss": + tup = [Integer.from_bytes(keyparts[x]) for x in (4, 3, 1, 2)] + return construct(tup) + + if len(extern_key) > 0 and bord(extern_key[0]) == 0x30: + # This is probably a DER encoded key + return _import_key_der(extern_key, passphrase, None) + + raise ValueError("DSA key format is not supported") + + +# Backward compatibility +importKey = import_key + +#: `Object ID`_ for a DSA key. +#: +#: id-dsa ID ::= { iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 1 } +#: +#: .. _`Object ID`: http://www.alvestrand.no/objectid/1.2.840.10040.4.1.html +oid = "1.2.840.10040.4.1" diff --git a/frozen_deps/Cryptodome/PublicKey/DSA.pyi b/frozen_deps/Cryptodome/PublicKey/DSA.pyi new file mode 100644 index 0000000..9977a0f --- /dev/null +++ b/frozen_deps/Cryptodome/PublicKey/DSA.pyi @@ -0,0 +1,30 @@ +from typing import Dict, Tuple, Callable, Union, Optional + +__all__ = ['generate', 'construct', 'DsaKey', 'import_key' ] + +RNG = Callable[[int], bytes] + +class DsaKey(object): + def __init__(self, key_dict: Dict[str, int]) -> None: ... + def has_private(self) -> bool: ... + def can_encrypt(self) -> bool: ... # legacy + def can_sign(self) -> bool: ... # legacy + def publickey(self) -> DsaKey: ... + def __eq__(self, other: object) -> bool: ... + def __ne__(self, other: object) -> bool: ... + def __getstate__(self) -> None: ... + def domain(self) -> Tuple[int, int, int]: ... + def __repr__(self) -> str: ... + def __getattr__(self, item: str) -> int: ... + def export_key(self, format: Optional[str]="PEM", pkcs8: Optional[bool]=None, passphrase: Optional[str]=None, + protection: Optional[str]=None, randfunc: Optional[RNG]=None) -> bytes: ... + # Backward-compatibility + exportKey = export_key + +def generate(bits: int, randfunc: Optional[RNG]=None, domain: Optional[Tuple[int, int, int]]=None) -> DsaKey: ... +def construct(tup: Union[Tuple[int, int, int, int], Tuple[int, int, int, int, int]], consistency_check: Optional[bool]=True) -> DsaKey: ... +def import_key(extern_key: Union[str, bytes], passphrase: Optional[str]=None) -> DsaKey: ... +# Backward compatibility +importKey = import_key + +oid: str diff --git a/frozen_deps/Cryptodome/PublicKey/ECC.py b/frozen_deps/Cryptodome/PublicKey/ECC.py new file mode 100644 index 0000000..e83664b --- /dev/null +++ b/frozen_deps/Cryptodome/PublicKey/ECC.py @@ -0,0 +1,1184 @@ +# =================================================================== +# +# Copyright (c) 2015, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from __future__ import print_function + +import re +import sys +import struct +import binascii +from collections import namedtuple + +from Cryptodome.Util.py3compat import bord, tobytes, tostr, bchr, is_string +from Cryptodome.Util.number import bytes_to_long, long_to_bytes + +from Cryptodome.Math.Numbers import Integer +from Cryptodome.Util.asn1 import (DerObjectId, DerOctetString, DerSequence, + DerBitString) + +from Cryptodome.PublicKey import (_expand_subject_public_key_info, + _create_subject_public_key_info, + _extract_subject_public_key_info) + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer, + SmartPointer, c_size_t, c_uint8_ptr, + c_ulonglong) + +from Cryptodome.Random import get_random_bytes +from Cryptodome.Random.random import getrandbits + + +_ec_lib = load_pycryptodome_raw_lib("Cryptodome.PublicKey._ec_ws", """ +typedef void EcContext; +typedef void EcPoint; +int ec_ws_new_context(EcContext **pec_ctx, + const uint8_t *modulus, + const uint8_t *b, + const uint8_t *order, + size_t len, + uint64_t seed); +void ec_free_context(EcContext *ec_ctx); +int ec_ws_new_point(EcPoint **pecp, + const uint8_t *x, + const uint8_t *y, + size_t len, + const EcContext *ec_ctx); +void ec_free_point(EcPoint *ecp); +int ec_ws_get_xy(uint8_t *x, + uint8_t *y, + size_t len, + const EcPoint *ecp); +int ec_ws_double(EcPoint *p); +int ec_ws_add(EcPoint *ecpa, EcPoint *ecpb); +int ec_ws_scalar(EcPoint *ecp, + const uint8_t *k, + size_t len, + uint64_t seed); +int ec_ws_clone(EcPoint **pecp2, const EcPoint *ecp); +int ec_ws_copy(EcPoint *ecp1, const EcPoint *ecp2); +int ec_ws_cmp(const EcPoint *ecp1, const EcPoint *ecp2); +int ec_ws_neg(EcPoint *p); +int ec_ws_normalize(EcPoint *ecp); +int ec_ws_is_pai(EcPoint *ecp); +""") + +_Curve = namedtuple("_Curve", "p b order Gx Gy G modulus_bits oid context desc openssh") +_curves = {} + + +p256_names = ["p256", "NIST P-256", "P-256", "prime256v1", "secp256r1", + "nistp256"] + + +def init_p256(): + p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff + b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b + order = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 + Gx = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296 + Gy = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5 + + p256_modulus = long_to_bytes(p, 32) + p256_b = long_to_bytes(b, 32) + p256_order = long_to_bytes(order, 32) + + ec_p256_context = VoidPointer() + result = _ec_lib.ec_ws_new_context(ec_p256_context.address_of(), + c_uint8_ptr(p256_modulus), + c_uint8_ptr(p256_b), + c_uint8_ptr(p256_order), + c_size_t(len(p256_modulus)), + c_ulonglong(getrandbits(64)) + ) + if result: + raise ImportError("Error %d initializing P-256 context" % result) + + context = SmartPointer(ec_p256_context.get(), _ec_lib.ec_free_context) + p256 = _Curve(Integer(p), + Integer(b), + Integer(order), + Integer(Gx), + Integer(Gy), + None, + 256, + "1.2.840.10045.3.1.7", # ANSI X9.62 + context, + "NIST P-256", + "ecdsa-sha2-nistp256") + global p256_names + _curves.update(dict.fromkeys(p256_names, p256)) + + +init_p256() +del init_p256 + + +p384_names = ["p384", "NIST P-384", "P-384", "prime384v1", "secp384r1", + "nistp384"] + + +def init_p384(): + p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff + b = 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef + order = 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973 + Gx = 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760aB7 + Gy = 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5F + + p384_modulus = long_to_bytes(p, 48) + p384_b = long_to_bytes(b, 48) + p384_order = long_to_bytes(order, 48) + + ec_p384_context = VoidPointer() + result = _ec_lib.ec_ws_new_context(ec_p384_context.address_of(), + c_uint8_ptr(p384_modulus), + c_uint8_ptr(p384_b), + c_uint8_ptr(p384_order), + c_size_t(len(p384_modulus)), + c_ulonglong(getrandbits(64)) + ) + if result: + raise ImportError("Error %d initializing P-384 context" % result) + + context = SmartPointer(ec_p384_context.get(), _ec_lib.ec_free_context) + p384 = _Curve(Integer(p), + Integer(b), + Integer(order), + Integer(Gx), + Integer(Gy), + None, + 384, + "1.3.132.0.34", # SEC 2 + context, + "NIST P-384", + "ecdsa-sha2-nistp384") + global p384_names + _curves.update(dict.fromkeys(p384_names, p384)) + + +init_p384() +del init_p384 + + +p521_names = ["p521", "NIST P-521", "P-521", "prime521v1", "secp521r1", + "nistp521"] + + +def init_p521(): + p = 0x000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + b = 0x00000051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00 + order = 0x000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409 + Gx = 0x000000c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66 + Gy = 0x0000011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650 + + p521_modulus = long_to_bytes(p, 66) + p521_b = long_to_bytes(b, 66) + p521_order = long_to_bytes(order, 66) + + ec_p521_context = VoidPointer() + result = _ec_lib.ec_ws_new_context(ec_p521_context.address_of(), + c_uint8_ptr(p521_modulus), + c_uint8_ptr(p521_b), + c_uint8_ptr(p521_order), + c_size_t(len(p521_modulus)), + c_ulonglong(getrandbits(64)) + ) + if result: + raise ImportError("Error %d initializing P-521 context" % result) + + context = SmartPointer(ec_p521_context.get(), _ec_lib.ec_free_context) + p521 = _Curve(Integer(p), + Integer(b), + Integer(order), + Integer(Gx), + Integer(Gy), + None, + 521, + "1.3.132.0.35", # SEC 2 + context, + "NIST P-521", + "ecdsa-sha2-nistp521") + global p521_names + _curves.update(dict.fromkeys(p521_names, p521)) + + +init_p521() +del init_p521 + + +class UnsupportedEccFeature(ValueError): + pass + + +class EccPoint(object): + """A class to abstract a point over an Elliptic Curve. + + The class support special methods for: + + * Adding two points: ``R = S + T`` + * In-place addition: ``S += T`` + * Negating a point: ``R = -T`` + * Comparing two points: ``if S == T: ...`` + * Multiplying a point by a scalar: ``R = S*k`` + * In-place multiplication by a scalar: ``T *= k`` + + :ivar x: The affine X-coordinate of the ECC point + :vartype x: integer + + :ivar y: The affine Y-coordinate of the ECC point + :vartype y: integer + + :ivar xy: The tuple with X- and Y- coordinates + """ + + def __init__(self, x, y, curve="p256"): + + try: + self._curve = _curves[curve] + except KeyError: + raise ValueError("Unknown curve name %s" % str(curve)) + self._curve_name = curve + + modulus_bytes = self.size_in_bytes() + context = self._curve.context + + xb = long_to_bytes(x, modulus_bytes) + yb = long_to_bytes(y, modulus_bytes) + if len(xb) != modulus_bytes or len(yb) != modulus_bytes: + raise ValueError("Incorrect coordinate length") + + self._point = VoidPointer() + result = _ec_lib.ec_ws_new_point(self._point.address_of(), + c_uint8_ptr(xb), + c_uint8_ptr(yb), + c_size_t(modulus_bytes), + context.get()) + if result: + if result == 15: + raise ValueError("The EC point does not belong to the curve") + raise ValueError("Error %d while instantiating an EC point" % result) + + # Ensure that object disposal of this Python object will (eventually) + # free the memory allocated by the raw library for the EC point + self._point = SmartPointer(self._point.get(), + _ec_lib.ec_free_point) + + def set(self, point): + self._point = VoidPointer() + result = _ec_lib.ec_ws_clone(self._point.address_of(), + point._point.get()) + if result: + raise ValueError("Error %d while cloning an EC point" % result) + + self._point = SmartPointer(self._point.get(), + _ec_lib.ec_free_point) + return self + + def __eq__(self, point): + return 0 == _ec_lib.ec_ws_cmp(self._point.get(), point._point.get()) + + def __neg__(self): + np = self.copy() + result = _ec_lib.ec_ws_neg(np._point.get()) + if result: + raise ValueError("Error %d while inverting an EC point" % result) + return np + + def copy(self): + """Return a copy of this point.""" + x, y = self.xy + np = EccPoint(x, y, self._curve_name) + return np + + def is_point_at_infinity(self): + """``True`` if this is the point-at-infinity.""" + return self.xy == (0, 0) + + def point_at_infinity(self): + """Return the point-at-infinity for the curve this point is on.""" + return EccPoint(0, 0, self._curve_name) + + @property + def x(self): + return self.xy[0] + + @property + def y(self): + return self.xy[1] + + @property + def xy(self): + modulus_bytes = self.size_in_bytes() + xb = bytearray(modulus_bytes) + yb = bytearray(modulus_bytes) + result = _ec_lib.ec_ws_get_xy(c_uint8_ptr(xb), + c_uint8_ptr(yb), + c_size_t(modulus_bytes), + self._point.get()) + if result: + raise ValueError("Error %d while encoding an EC point" % result) + + return (Integer(bytes_to_long(xb)), Integer(bytes_to_long(yb))) + + def size_in_bytes(self): + """Size of each coordinate, in bytes.""" + return (self.size_in_bits() + 7) // 8 + + def size_in_bits(self): + """Size of each coordinate, in bits.""" + return self._curve.modulus_bits + + def double(self): + """Double this point (in-place operation). + + :Return: + :class:`EccPoint` : this same object (to enable chaining) + """ + + result = _ec_lib.ec_ws_double(self._point.get()) + if result: + raise ValueError("Error %d while doubling an EC point" % result) + return self + + def __iadd__(self, point): + """Add a second point to this one""" + + result = _ec_lib.ec_ws_add(self._point.get(), point._point.get()) + if result: + if result == 16: + raise ValueError("EC points are not on the same curve") + raise ValueError("Error %d while adding two EC points" % result) + return self + + def __add__(self, point): + """Return a new point, the addition of this one and another""" + + np = self.copy() + np += point + return np + + def __imul__(self, scalar): + """Multiply this point by a scalar""" + + if scalar < 0: + raise ValueError("Scalar multiplication is only defined for non-negative integers") + sb = long_to_bytes(scalar) + result = _ec_lib.ec_ws_scalar(self._point.get(), + c_uint8_ptr(sb), + c_size_t(len(sb)), + c_ulonglong(getrandbits(64))) + if result: + raise ValueError("Error %d during scalar multiplication" % result) + return self + + def __mul__(self, scalar): + """Return a new point, the scalar product of this one""" + + np = self.copy() + np *= scalar + return np + + def __rmul__(self, left_hand): + return self.__mul__(left_hand) + + +# Last piece of initialization +p256_G = EccPoint(_curves['p256'].Gx, _curves['p256'].Gy, "p256") +p256 = _curves['p256']._replace(G=p256_G) +_curves.update(dict.fromkeys(p256_names, p256)) +del p256_G, p256, p256_names + +p384_G = EccPoint(_curves['p384'].Gx, _curves['p384'].Gy, "p384") +p384 = _curves['p384']._replace(G=p384_G) +_curves.update(dict.fromkeys(p384_names, p384)) +del p384_G, p384, p384_names + +p521_G = EccPoint(_curves['p521'].Gx, _curves['p521'].Gy, "p521") +p521 = _curves['p521']._replace(G=p521_G) +_curves.update(dict.fromkeys(p521_names, p521)) +del p521_G, p521, p521_names + + +class EccKey(object): + r"""Class defining an ECC key. + Do not instantiate directly. + Use :func:`generate`, :func:`construct` or :func:`import_key` instead. + + :ivar curve: The name of the ECC as defined in :numref:`curve_names`. + :vartype curve: string + + :ivar pointQ: an ECC point representating the public component + :vartype pointQ: :class:`EccPoint` + + :ivar d: A scalar representating the private component + :vartype d: integer + """ + + def __init__(self, **kwargs): + """Create a new ECC key + + Keywords: + curve : string + It must be *"p256"*, *"P-256"*, *"prime256v1"* or *"secp256r1"*. + d : integer + Only for a private key. It must be in the range ``[1..order-1]``. + point : EccPoint + Mandatory for a public key. If provided for a private key, + the implementation will NOT check whether it matches ``d``. + """ + + kwargs_ = dict(kwargs) + curve_name = kwargs_.pop("curve", None) + self._d = kwargs_.pop("d", None) + self._point = kwargs_.pop("point", None) + if kwargs_: + raise TypeError("Unknown parameters: " + str(kwargs_)) + + if curve_name not in _curves: + raise ValueError("Unsupported curve (%s)", curve_name) + self._curve = _curves[curve_name] + + if self._d is None: + if self._point is None: + raise ValueError("Either private or public ECC component must be specified, not both") + else: + self._d = Integer(self._d) + if not 1 <= self._d < self._curve.order: + raise ValueError("Invalid ECC private component") + + self.curve = self._curve.desc + + def __eq__(self, other): + if other.has_private() != self.has_private(): + return False + + return other.pointQ == self.pointQ + + def __repr__(self): + if self.has_private(): + extra = ", d=%d" % int(self._d) + else: + extra = "" + x, y = self.pointQ.xy + return "EccKey(curve='%s', point_x=%d, point_y=%d%s)" % (self._curve.desc, x, y, extra) + + def has_private(self): + """``True`` if this key can be used for making signatures or decrypting data.""" + + return self._d is not None + + def _sign(self, z, k): + assert 0 < k < self._curve.order + + order = self._curve.order + blind = Integer.random_range(min_inclusive=1, + max_exclusive=order) + + blind_d = self._d * blind + inv_blind_k = (blind * k).inverse(order) + + r = (self._curve.G * k).x % order + s = inv_blind_k * (blind * z + blind_d * r) % order + return (r, s) + + def _verify(self, z, rs): + order = self._curve.order + sinv = rs[1].inverse(order) + point1 = self._curve.G * ((sinv * z) % order) + point2 = self.pointQ * ((sinv * rs[0]) % order) + return (point1 + point2).x == rs[0] + + @property + def d(self): + if not self.has_private(): + raise ValueError("This is not a private ECC key") + return self._d + + @property + def pointQ(self): + if self._point is None: + self._point = self._curve.G * self._d + return self._point + + def public_key(self): + """A matching ECC public key. + + Returns: + a new :class:`EccKey` object + """ + + return EccKey(curve=self._curve.desc, point=self.pointQ) + + def _export_subjectPublicKeyInfo(self, compress): + + # See 2.2 in RFC5480 and 2.3.3 in SEC1 + # The first byte is: + # - 0x02: compressed, only X-coordinate, Y-coordinate is even + # - 0x03: compressed, only X-coordinate, Y-coordinate is odd + # - 0x04: uncompressed, X-coordinate is followed by Y-coordinate + # + # PAI is in theory encoded as 0x00. + + modulus_bytes = self.pointQ.size_in_bytes() + + if compress: + first_byte = 2 + self.pointQ.y.is_odd() + public_key = (bchr(first_byte) + + self.pointQ.x.to_bytes(modulus_bytes)) + else: + public_key = (b'\x04' + + self.pointQ.x.to_bytes(modulus_bytes) + + self.pointQ.y.to_bytes(modulus_bytes)) + + unrestricted_oid = "1.2.840.10045.2.1" + return _create_subject_public_key_info(unrestricted_oid, + public_key, + DerObjectId(self._curve.oid)) + + def _export_private_der(self, include_ec_params=True): + + assert self.has_private() + + # ECPrivateKey ::= SEQUENCE { + # version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + # privateKey OCTET STRING, + # parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + # publicKey [1] BIT STRING OPTIONAL + # } + + # Public key - uncompressed form + modulus_bytes = self.pointQ.size_in_bytes() + public_key = (b'\x04' + + self.pointQ.x.to_bytes(modulus_bytes) + + self.pointQ.y.to_bytes(modulus_bytes)) + + seq = [1, + DerOctetString(self.d.to_bytes(modulus_bytes)), + DerObjectId(self._curve.oid, explicit=0), + DerBitString(public_key, explicit=1)] + + if not include_ec_params: + del seq[2] + + return DerSequence(seq).encode() + + def _export_pkcs8(self, **kwargs): + from Cryptodome.IO import PKCS8 + + if kwargs.get('passphrase', None) is not None and 'protection' not in kwargs: + raise ValueError("At least the 'protection' parameter should be present") + + unrestricted_oid = "1.2.840.10045.2.1" + private_key = self._export_private_der(include_ec_params=False) + result = PKCS8.wrap(private_key, + unrestricted_oid, + key_params=DerObjectId(self._curve.oid), + **kwargs) + return result + + def _export_public_pem(self, compress): + from Cryptodome.IO import PEM + + encoded_der = self._export_subjectPublicKeyInfo(compress) + return PEM.encode(encoded_der, "PUBLIC KEY") + + def _export_private_pem(self, passphrase, **kwargs): + from Cryptodome.IO import PEM + + encoded_der = self._export_private_der() + return PEM.encode(encoded_der, "EC PRIVATE KEY", passphrase, **kwargs) + + def _export_private_clear_pkcs8_in_clear_pem(self): + from Cryptodome.IO import PEM + + encoded_der = self._export_pkcs8() + return PEM.encode(encoded_der, "PRIVATE KEY") + + def _export_private_encrypted_pkcs8_in_clear_pem(self, passphrase, **kwargs): + from Cryptodome.IO import PEM + + assert passphrase + if 'protection' not in kwargs: + raise ValueError("At least the 'protection' parameter should be present") + encoded_der = self._export_pkcs8(passphrase=passphrase, **kwargs) + return PEM.encode(encoded_der, "ENCRYPTED PRIVATE KEY") + + def _export_openssh(self, compress): + if self.has_private(): + raise ValueError("Cannot export OpenSSH private keys") + + desc = self._curve.openssh + modulus_bytes = self.pointQ.size_in_bytes() + + if compress: + first_byte = 2 + self.pointQ.y.is_odd() + public_key = (bchr(first_byte) + + self.pointQ.x.to_bytes(modulus_bytes)) + else: + public_key = (b'\x04' + + self.pointQ.x.to_bytes(modulus_bytes) + + self.pointQ.y.to_bytes(modulus_bytes)) + + middle = desc.split("-")[2] + comps = (tobytes(desc), tobytes(middle), public_key) + blob = b"".join([struct.pack(">I", len(x)) + x for x in comps]) + return desc + " " + tostr(binascii.b2a_base64(blob)) + + def export_key(self, **kwargs): + """Export this ECC key. + + Args: + format (string): + The format to use for encoding the key: + + - ``'DER'``. The key will be encoded in ASN.1 DER format (binary). + For a public key, the ASN.1 ``subjectPublicKeyInfo`` structure + defined in `RFC5480`_ will be used. + For a private key, the ASN.1 ``ECPrivateKey`` structure defined + in `RFC5915`_ is used instead (possibly within a PKCS#8 envelope, + see the ``use_pkcs8`` flag below). + - ``'PEM'``. The key will be encoded in a PEM_ envelope (ASCII). + - ``'OpenSSH'``. The key will be encoded in the OpenSSH_ format + (ASCII, public keys only). + + passphrase (byte string or string): + The passphrase to use for protecting the private key. + + use_pkcs8 (boolean): + Only relevant for private keys. + + If ``True`` (default and recommended), the `PKCS#8`_ representation + will be used. + + If ``False``, the much weaker `PEM encryption`_ mechanism will be used. + + protection (string): + When a private key is exported with password-protection + and PKCS#8 (both ``DER`` and ``PEM`` formats), this parameter MUST be + present and be a valid algorithm supported by :mod:`Cryptodome.IO.PKCS8`. + It is recommended to use ``PBKDF2WithHMAC-SHA1AndAES128-CBC``. + + compress (boolean): + If ``True``, a more compact representation of the public key + with the X-coordinate only is used. + + If ``False`` (default), the full public key will be exported. + + .. warning:: + If you don't provide a passphrase, the private key will be + exported in the clear! + + .. note:: + When exporting a private key with password-protection and `PKCS#8`_ + (both ``DER`` and ``PEM`` formats), any extra parameters + to ``export_key()`` will be passed to :mod:`Cryptodome.IO.PKCS8`. + + .. _PEM: http://www.ietf.org/rfc/rfc1421.txt + .. _`PEM encryption`: http://www.ietf.org/rfc/rfc1423.txt + .. _`PKCS#8`: http://www.ietf.org/rfc/rfc5208.txt + .. _OpenSSH: http://www.openssh.com/txt/rfc5656.txt + .. _RFC5480: https://tools.ietf.org/html/rfc5480 + .. _RFC5915: http://www.ietf.org/rfc/rfc5915.txt + + Returns: + A multi-line string (for PEM and OpenSSH) or bytes (for DER) with the encoded key. + """ + + args = kwargs.copy() + ext_format = args.pop("format") + if ext_format not in ("PEM", "DER", "OpenSSH"): + raise ValueError("Unknown format '%s'" % ext_format) + + compress = args.pop("compress", False) + + if self.has_private(): + passphrase = args.pop("passphrase", None) + if is_string(passphrase): + passphrase = tobytes(passphrase) + if not passphrase: + raise ValueError("Empty passphrase") + use_pkcs8 = args.pop("use_pkcs8", True) + if ext_format == "PEM": + if use_pkcs8: + if passphrase: + return self._export_private_encrypted_pkcs8_in_clear_pem(passphrase, **args) + else: + return self._export_private_clear_pkcs8_in_clear_pem() + else: + return self._export_private_pem(passphrase, **args) + elif ext_format == "DER": + # DER + if passphrase and not use_pkcs8: + raise ValueError("Private keys can only be encrpyted with DER using PKCS#8") + if use_pkcs8: + return self._export_pkcs8(passphrase=passphrase, **args) + else: + return self._export_private_der() + else: + raise ValueError("Private keys cannot be exported in OpenSSH format") + else: # Public key + if args: + raise ValueError("Unexpected parameters: '%s'" % args) + if ext_format == "PEM": + return self._export_public_pem(compress) + elif ext_format == "DER": + return self._export_subjectPublicKeyInfo(compress) + else: + return self._export_openssh(compress) + + +def generate(**kwargs): + """Generate a new private key on the given curve. + + Args: + + curve (string): + Mandatory. It must be a curve name defined in :numref:`curve_names`. + + randfunc (callable): + Optional. The RNG to read randomness from. + If ``None``, :func:`Cryptodome.Random.get_random_bytes` is used. + """ + + curve_name = kwargs.pop("curve") + curve = _curves[curve_name] + randfunc = kwargs.pop("randfunc", get_random_bytes) + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + d = Integer.random_range(min_inclusive=1, + max_exclusive=curve.order, + randfunc=randfunc) + + return EccKey(curve=curve_name, d=d) + + +def construct(**kwargs): + """Build a new ECC key (private or public) starting + from some base components. + + Args: + + curve (string): + Mandatory. It must be a curve name defined in :numref:`curve_names`. + + d (integer): + Only for a private key. It must be in the range ``[1..order-1]``. + + point_x (integer): + Mandatory for a public key. X coordinate (affine) of the ECC point. + + point_y (integer): + Mandatory for a public key. Y coordinate (affine) of the ECC point. + + Returns: + :class:`EccKey` : a new ECC key object + """ + + curve_name = kwargs["curve"] + curve = _curves[curve_name] + point_x = kwargs.pop("point_x", None) + point_y = kwargs.pop("point_y", None) + + if "point" in kwargs: + raise TypeError("Unknown keyword: point") + + if None not in (point_x, point_y): + # ValueError is raised if the point is not on the curve + kwargs["point"] = EccPoint(point_x, point_y, curve_name) + + # Validate that the private key matches the public one + d = kwargs.get("d", None) + if d is not None and "point" in kwargs: + pub_key = curve.G * d + if pub_key.xy != (point_x, point_y): + raise ValueError("Private and public ECC keys do not match") + + return EccKey(**kwargs) + + +def _import_public_der(curve_oid, ec_point): + """Convert an encoded EC point into an EccKey object + + curve_name: string with the OID of the curve + ec_point: byte string with the EC point (not DER encoded) + + """ + + for curve_name, curve in _curves.items(): + if curve.oid == curve_oid: + break + else: + raise UnsupportedEccFeature("Unsupported ECC curve (OID: %s)" % curve_oid) + + # See 2.2 in RFC5480 and 2.3.3 in SEC1 + # The first byte is: + # - 0x02: compressed, only X-coordinate, Y-coordinate is even + # - 0x03: compressed, only X-coordinate, Y-coordinate is odd + # - 0x04: uncompressed, X-coordinate is followed by Y-coordinate + # + # PAI is in theory encoded as 0x00. + + modulus_bytes = curve.p.size_in_bytes() + point_type = bord(ec_point[0]) + + # Uncompressed point + if point_type == 0x04: + if len(ec_point) != (1 + 2 * modulus_bytes): + raise ValueError("Incorrect EC point length") + x = Integer.from_bytes(ec_point[1:modulus_bytes+1]) + y = Integer.from_bytes(ec_point[modulus_bytes+1:]) + # Compressed point + elif point_type in (0x02, 0x3): + if len(ec_point) != (1 + modulus_bytes): + raise ValueError("Incorrect EC point length") + x = Integer.from_bytes(ec_point[1:]) + y = (x**3 - x*3 + curve.b).sqrt(curve.p) # Short Weierstrass + if point_type == 0x02 and y.is_odd(): + y = curve.p - y + if point_type == 0x03 and y.is_even(): + y = curve.p - y + else: + raise ValueError("Incorrect EC point encoding") + + return construct(curve=curve_name, point_x=x, point_y=y) + + +def _import_subjectPublicKeyInfo(encoded, *kwargs): + """Convert a subjectPublicKeyInfo into an EccKey object""" + + # See RFC5480 + + # Parse the generic subjectPublicKeyInfo structure + oid, ec_point, params = _expand_subject_public_key_info(encoded) + + # ec_point must be an encoded OCTET STRING + # params is encoded ECParameters + + # We accept id-ecPublicKey, id-ecDH, id-ecMQV without making any + # distiction for now. + + # Restrictions can be captured in the key usage certificate + # extension + unrestricted_oid = "1.2.840.10045.2.1" + ecdh_oid = "1.3.132.1.12" + ecmqv_oid = "1.3.132.1.13" + + if oid not in (unrestricted_oid, ecdh_oid, ecmqv_oid): + raise UnsupportedEccFeature("Unsupported ECC purpose (OID: %s)" % oid) + + # Parameters are mandatory for all three types + if not params: + raise ValueError("Missing ECC parameters") + + # ECParameters ::= CHOICE { + # namedCurve OBJECT IDENTIFIER + # -- implicitCurve NULL + # -- specifiedCurve SpecifiedECDomain + # } + # + # implicitCurve and specifiedCurve are not supported (as per RFC) + curve_oid = DerObjectId().decode(params).value + + return _import_public_der(curve_oid, ec_point) + + +def _import_private_der(encoded, passphrase, curve_oid=None): + + # See RFC5915 https://tools.ietf.org/html/rfc5915 + # + # ECPrivateKey ::= SEQUENCE { + # version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + # privateKey OCTET STRING, + # parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + # publicKey [1] BIT STRING OPTIONAL + # } + + private_key = DerSequence().decode(encoded, nr_elements=(3, 4)) + if private_key[0] != 1: + raise ValueError("Incorrect ECC private key version") + + try: + parameters = DerObjectId(explicit=0).decode(private_key[2]).value + if curve_oid is not None and parameters != curve_oid: + raise ValueError("Curve mismatch") + curve_oid = parameters + except ValueError: + pass + + if curve_oid is None: + raise ValueError("No curve found") + + for curve_name, curve in _curves.items(): + if curve.oid == curve_oid: + break + else: + raise UnsupportedEccFeature("Unsupported ECC curve (OID: %s)" % curve_oid) + + scalar_bytes = DerOctetString().decode(private_key[1]).payload + modulus_bytes = curve.p.size_in_bytes() + if len(scalar_bytes) != modulus_bytes: + raise ValueError("Private key is too small") + d = Integer.from_bytes(scalar_bytes) + + # Decode public key (if any) + if len(private_key) == 4: + public_key_enc = DerBitString(explicit=1).decode(private_key[3]).value + public_key = _import_public_der(curve_oid, public_key_enc) + point_x = public_key.pointQ.x + point_y = public_key.pointQ.y + else: + point_x = point_y = None + + return construct(curve=curve_name, d=d, point_x=point_x, point_y=point_y) + + +def _import_pkcs8(encoded, passphrase): + from Cryptodome.IO import PKCS8 + + # From RFC5915, Section 1: + # + # Distributing an EC private key with PKCS#8 [RFC5208] involves including: + # a) id-ecPublicKey, id-ecDH, or id-ecMQV (from [RFC5480]) with the + # namedCurve as the parameters in the privateKeyAlgorithm field; and + # b) ECPrivateKey in the PrivateKey field, which is an OCTET STRING. + + algo_oid, private_key, params = PKCS8.unwrap(encoded, passphrase) + + # We accept id-ecPublicKey, id-ecDH, id-ecMQV without making any + # distiction for now. + unrestricted_oid = "1.2.840.10045.2.1" + ecdh_oid = "1.3.132.1.12" + ecmqv_oid = "1.3.132.1.13" + + if algo_oid not in (unrestricted_oid, ecdh_oid, ecmqv_oid): + raise UnsupportedEccFeature("Unsupported ECC purpose (OID: %s)" % algo_oid) + + curve_oid = DerObjectId().decode(params).value + + return _import_private_der(private_key, passphrase, curve_oid) + + +def _import_x509_cert(encoded, *kwargs): + + sp_info = _extract_subject_public_key_info(encoded) + return _import_subjectPublicKeyInfo(sp_info) + + +def _import_der(encoded, passphrase): + + try: + return _import_subjectPublicKeyInfo(encoded, passphrase) + except UnsupportedEccFeature as err: + raise err + except (ValueError, TypeError, IndexError): + pass + + try: + return _import_x509_cert(encoded, passphrase) + except UnsupportedEccFeature as err: + raise err + except (ValueError, TypeError, IndexError): + pass + + try: + return _import_private_der(encoded, passphrase) + except UnsupportedEccFeature as err: + raise err + except (ValueError, TypeError, IndexError): + pass + + try: + return _import_pkcs8(encoded, passphrase) + except UnsupportedEccFeature as err: + raise err + except (ValueError, TypeError, IndexError): + pass + + raise ValueError("Not an ECC DER key") + + +def _import_openssh_public(encoded): + keystring = binascii.a2b_base64(encoded.split(b' ')[1]) + + keyparts = [] + while len(keystring) > 4: + lk = struct.unpack(">I", keystring[:4])[0] + keyparts.append(keystring[4:4 + lk]) + keystring = keystring[4 + lk:] + + for curve_name, curve in _curves.items(): + middle = tobytes(curve.openssh.split("-")[2]) + if keyparts[1] == middle: + break + else: + raise ValueError("Unsupported ECC curve") + + return _import_public_der(curve.oid, keyparts[2]) + + +def _import_openssh_private_ecc(data, password): + + from ._openssh import (import_openssh_private_generic, + read_bytes, read_string, check_padding) + + ssh_name, decrypted = import_openssh_private_generic(data, password) + + name, decrypted = read_string(decrypted) + if name not in _curves: + raise UnsupportedEccFeature("Unsupported ECC curve %s" % name) + curve = _curves[name] + modulus_bytes = (curve.modulus_bits + 7) // 8 + + public_key, decrypted = read_bytes(decrypted) + + if bord(public_key[0]) != 4: + raise ValueError("Only uncompressed OpenSSH EC keys are supported") + if len(public_key) != 2 * modulus_bytes + 1: + raise ValueError("Incorrect public key length") + + point_x = Integer.from_bytes(public_key[1:1+modulus_bytes]) + point_y = Integer.from_bytes(public_key[1+modulus_bytes:]) + point = EccPoint(point_x, point_y, curve=name) + + private_key, decrypted = read_bytes(decrypted) + d = Integer.from_bytes(private_key) + + _, padded = read_string(decrypted) # Comment + check_padding(padded) + + return EccKey(curve=name, d=d, point=point) + + +def import_key(encoded, passphrase=None): + """Import an ECC key (public or private). + + Args: + encoded (bytes or multi-line string): + The ECC key to import. + + An ECC **public** key can be: + + - An X.509 certificate, binary (DER) or ASCII (PEM) + - An X.509 ``subjectPublicKeyInfo``, binary (DER) or ASCII (PEM) + - An OpenSSH line (e.g. the content of ``~/.ssh/id_ecdsa``, ASCII) + + An ECC **private** key can be: + + - In binary format (DER, see section 3 of `RFC5915`_ or `PKCS#8`_) + - In ASCII format (PEM or `OpenSSH 6.5+`_) + + Private keys can be in the clear or password-protected. + + For details about the PEM encoding, see `RFC1421`_/`RFC1423`_. + + passphrase (byte string): + The passphrase to use for decrypting a private key. + Encryption may be applied protected at the PEM level or at the PKCS#8 level. + This parameter is ignored if the key in input is not encrypted. + + Returns: + :class:`EccKey` : a new ECC key object + + Raises: + ValueError: 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 + .. _RFC5915: http://www.ietf.org/rfc/rfc5915.txt + .. _`PKCS#8`: http://www.ietf.org/rfc/rfc5208.txt + .. _`OpenSSH 6.5+`: https://flak.tedunangst.com/post/new-openssh-key-format-and-bcrypt-pbkdf + """ + + from Cryptodome.IO import PEM + + encoded = tobytes(encoded) + if passphrase is not None: + passphrase = tobytes(passphrase) + + # PEM + if encoded.startswith(b'-----BEGIN OPENSSH PRIVATE KEY'): + text_encoded = tostr(encoded) + openssh_encoded, marker, enc_flag = PEM.decode(text_encoded, passphrase) + result = _import_openssh_private_ecc(openssh_encoded, passphrase) + return result + + elif encoded.startswith(b'-----'): + + text_encoded = tostr(encoded) + + # Remove any EC PARAMETERS section + # Ignore its content because the curve type must be already given in the key + if sys.version_info[:2] != (2, 6): + ecparams_start = "-----BEGIN EC PARAMETERS-----" + ecparams_end = "-----END EC PARAMETERS-----" + text_encoded = re.sub(ecparams_start + ".*?" + ecparams_end, "", + text_encoded, + flags=re.DOTALL) + + der_encoded, marker, enc_flag = PEM.decode(text_encoded, passphrase) + if enc_flag: + passphrase = None + try: + result = _import_der(der_encoded, passphrase) + except UnsupportedEccFeature as uef: + raise uef + except ValueError: + raise ValueError("Invalid DER encoding inside the PEM file") + return result + + # OpenSSH + if encoded.startswith(b'ecdsa-sha2-'): + return _import_openssh_public(encoded) + + # DER + if len(encoded) > 0 and bord(encoded[0]) == 0x30: + return _import_der(encoded, passphrase) + + raise ValueError("ECC key format is not supported") + + +if __name__ == "__main__": + + import time + + d = 0xc51e4753afdec1e6b6c6a5b992f43f8dd0c7a8933072708b6522468b2ffb06fd + + point = _curves['p256'].G.copy() + count = 3000 + + start = time.time() + for x in range(count): + pointX = point * d + print("(P-256 G)", (time.time() - start) / count * 1000, "ms") + + start = time.time() + for x in range(count): + pointX = pointX * d + print("(P-256 arbitrary point)", (time.time() - start) / count * 1000, "ms") diff --git a/frozen_deps/Cryptodome/PublicKey/ECC.pyi b/frozen_deps/Cryptodome/PublicKey/ECC.pyi new file mode 100644 index 0000000..b38b337 --- /dev/null +++ b/frozen_deps/Cryptodome/PublicKey/ECC.pyi @@ -0,0 +1,62 @@ +from typing import Union, Callable, Optional, NamedTuple, List, Tuple, Dict, NamedTuple, Any + +from Cryptodome.Math.Numbers import Integer + +RNG = Callable[[int], bytes] + +class UnsupportedEccFeature(ValueError): ... +class EccPoint(object): + def __init__(self, x: Union[int, Integer], y: Union[int, Integer], curve: Optional[str] = ...) -> None: ... + def set(self, point: EccPoint) -> EccPoint: ... + def __eq__(self, point: object) -> bool: ... + def __neg__(self) -> EccPoint: ... + def copy(self) -> EccPoint: ... + def is_point_at_infinity(self) -> bool: ... + def point_at_infinity(self) -> EccPoint: ... + @property + def x(self) -> int: ... + @property + def y(self) -> int: ... + @property + def xy(self) -> Tuple[int, int]: ... + def size_in_bytes(self) -> int: ... + def size_in_bits(self) -> int: ... + def double(self) -> EccPoint: ... + def __iadd__(self, point: EccPoint) -> EccPoint: ... + def __add__(self, point: EccPoint) -> EccPoint: ... + def __imul__(self, scalar: int) -> EccPoint: ... + def __mul__(self, scalar: int) -> EccPoint: ... + +class EccKey(object): + curve: str + def __init__(self, *, curve: str = ..., d: int = ..., point: EccPoint = ...) -> None: ... + def __eq__(self, other: object) -> bool: ... + def __repr__(self) -> str: ... + def has_private(self) -> bool: ... + @property + def d(self) -> int: ... + @property + def pointQ(self) -> EccPoint: ... + def public_key(self) -> EccKey: ... + def export_key(self, **kwargs: Union[str, bytes, bool]) -> str: ... + + +_Curve = NamedTuple("_Curve", [('p', Integer), + ('order', Integer), + ('b', Integer), + ('Gx', Integer), + ('Gy', Integer), + ('G', EccPoint), + ('modulus_bits', int), + ('oid', str), + ('context', Any), + ('desc', str), + ('openssh', str), + ]) + +_curves : Dict[str, _Curve] + + +def generate(**kwargs: Union[str, RNG]) -> EccKey: ... +def construct(**kwargs: Union[str, int]) -> EccKey: ... +def import_key(encoded: Union[bytes, str], passphrase: Optional[str]=None) -> EccKey: ... diff --git a/frozen_deps/Cryptodome/PublicKey/ElGamal.py b/frozen_deps/Cryptodome/PublicKey/ElGamal.py new file mode 100644 index 0000000..95c219e --- /dev/null +++ b/frozen_deps/Cryptodome/PublicKey/ElGamal.py @@ -0,0 +1,286 @@ +# +# 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. +# =================================================================== + +__all__ = ['generate', 'construct', 'ElGamalKey'] + +from Cryptodome import Random +from Cryptodome.Math.Primality import ( generate_probable_safe_prime, + test_probable_prime, COMPOSITE ) +from Cryptodome.Math.Numbers import Integer + +# Generate an ElGamal key with N bits +def generate(bits, randfunc): + """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). + + Args: + bits (int): + Key length, or size (in bits) of the modulus *p*. + The recommended value is 2048. + randfunc (callable): + Random number generation function; it should accept + a single integer *N* and return a string of random + *N* random bytes. + + Return: + an :class:`ElGamalKey` object + """ + + obj=ElGamalKey() + + # Generate a safe prime p + # See Algorithm 4.86 in Handbook of Applied Cryptography + obj.p = generate_probable_safe_prime(exact_bits=bits, randfunc=randfunc) + q = (obj.p - 1) >> 1 + + # Generate generator g + while 1: + # Choose a square residue; it will generate a cyclic group of order q. + obj.g = pow(Integer.random_range(min_inclusive=2, + max_exclusive=obj.p, + randfunc=randfunc), 2, obj.p) + + # We must avoid g=2 because of Bleichenbacher's attack described + # in "Generating ElGamal signatures without knowning the secret key", + # 1996 + if obj.g in (1, 2): + continue + + # Discard g if it divides p-1 because of the attack described + # in Note 11.67 (iii) in HAC + if (obj.p - 1) % obj.g == 0: + continue + + # g^{-1} must not divide p-1 because of Khadir's attack + # described in "Conditions of the generator for forging ElGamal + # signature", 2011 + ginv = obj.g.inverse(obj.p) + if (obj.p - 1) % ginv == 0: + continue + + # Found + break + + # Generate private key x + obj.x = Integer.random_range(min_inclusive=2, + max_exclusive=obj.p-1, + randfunc=randfunc) + # Generate public key y + obj.y = pow(obj.g, obj.x, obj.p) + return obj + +def construct(tup): + r"""Construct an ElGamal key from a tuple of valid ElGamal components. + + The modulus *p* must be a prime. + The following conditions must apply: + + .. math:: + + \begin{align} + &1 < g < p-1 \\ + &g^{p-1} = 1 \text{ mod } 1 \\ + &1 < x < p-1 \\ + &g^x = y \text{ mod } p + \end{align} + + Args: + tup (tuple): + A tuple with either 3 or 4 integers, + in the following order: + + 1. Modulus (*p*). + 2. Generator (*g*). + 3. Public key (*y*). + 4. Private key (*x*). Optional. + + Raises: + ValueError: when the key being imported fails the most basic ElGamal validity checks. + + Returns: + an :class:`ElGamalKey` object + """ + + obj=ElGamalKey() + 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, Integer(tup[i])) + + fmt_error = test_probable_prime(obj.p) == COMPOSITE + fmt_error |= obj.g<=1 or obj.g>=obj.p + fmt_error |= pow(obj.g, obj.p-1, obj.p)!=1 + fmt_error |= obj.y<1 or obj.y>=obj.p + if len(tup)==4: + fmt_error |= obj.x<=1 or obj.x>=obj.p + fmt_error |= pow(obj.g, obj.x, obj.p)!=obj.y + + if fmt_error: + raise ValueError("Invalid ElGamal key components") + + return obj + +class ElGamalKey(object): + r"""Class defining an ElGamal key. + Do not instantiate directly. + Use :func:`generate` or :func:`construct` instead. + + :ivar p: Modulus + :vartype d: integer + + :ivar g: Generator + :vartype e: integer + + :ivar y: Public key component + :vartype y: integer + + :ivar x: Private key component + :vartype x: integer + """ + + #: 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 __init__(self, randfunc=None): + if randfunc is None: + randfunc = Random.new().read + self._randfunc = randfunc + + def _encrypt(self, M, K): + a=pow(self.g, K, self.p) + b=( pow(self.y, K, self.p)*M ) % self.p + return [int(a), int(b)] + + def _decrypt(self, M): + if (not hasattr(self, 'x')): + raise TypeError('Private key not available in this object') + r = Integer.random_range(min_inclusive=2, + max_exclusive=self.p-1, + randfunc=self._randfunc) + a_blind = (pow(self.g, r, self.p) * M[0]) % self.p + ax=pow(a_blind, self.x, self.p) + plaintext_blind = (ax.inverse(self.p) * M[1] ) % self.p + plaintext = (plaintext_blind * pow(self.y, r, self.p)) % self.p + return int(plaintext) + + def _sign(self, M, K): + if (not hasattr(self, 'x')): + raise TypeError('Private key not available in this object') + p1=self.p-1 + K = Integer(K) + if (K.gcd(p1)!=1): + raise ValueError('Bad K value: GCD(K,p-1)!=1') + a=pow(self.g, K, self.p) + t=(Integer(M)-self.x*a) % p1 + while t<0: t=t+p1 + b=(t*K.inverse(p1)) % p1 + return [int(a), int(b)] + + def _verify(self, M, sig): + sig = [Integer(x) for x in 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 has_private(self): + """Whether this is an ElGamal private key""" + + if hasattr(self, 'x'): + return 1 + else: + return 0 + + def can_encrypt(self): + return True + + def can_sign(self): + return True + + def publickey(self): + """A matching ElGamal public key. + + Returns: + a new :class:`ElGamalKey` object + """ + return construct((self.p, self.g, self.y)) + + def __eq__(self, other): + if bool(self.has_private()) != bool(other.has_private()): + return False + + result = True + for comp in self._keydata: + result = result and (getattr(self.key, comp, None) == + getattr(other.key, comp, None)) + return result + + def __ne__(self, other): + return not self.__eq__(other) + + def __getstate__(self): + # ElGamal key is not pickable + from pickle import PicklingError + raise PicklingError + + # Methods defined in PyCryptodome that we don't support anymore + + def sign(self, M, K): + raise NotImplementedError + + def verify(self, M, signature): + raise NotImplementedError + + def encrypt(self, plaintext, K): + raise NotImplementedError + + def decrypt(self, ciphertext): + raise NotImplementedError + + def blind(self, M, B): + raise NotImplementedError + + def unblind(self, M, B): + raise NotImplementedError + + def size(self): + raise NotImplementedError diff --git a/frozen_deps/Cryptodome/PublicKey/ElGamal.pyi b/frozen_deps/Cryptodome/PublicKey/ElGamal.pyi new file mode 100644 index 0000000..9048531 --- /dev/null +++ b/frozen_deps/Cryptodome/PublicKey/ElGamal.pyi @@ -0,0 +1,18 @@ +from typing import Callable, Union, Tuple, Optional + +__all__ = ['generate', 'construct', 'ElGamalKey'] + +RNG = Callable[[int], bytes] + +def generate(bits: int, randfunc: RNG) -> ElGamalKey: ... +def construct(tup: Union[Tuple[int, int, int], Tuple[int, int, int, int]]) -> ElGamalKey: ... + +class ElGamalKey(object): + def __init__(self, randfunc: Optional[RNG]=None) -> None: ... + def has_private(self) -> bool: ... + def can_encrypt(self) -> bool: ... + def can_sign(self) -> bool: ... + def publickey(self) -> ElGamalKey: ... + def __eq__(self, other: object) -> bool: ... + def __ne__(self, other: object) -> bool: ... + def __getstate__(self) -> None: ... diff --git a/frozen_deps/Cryptodome/PublicKey/RSA.py b/frozen_deps/Cryptodome/PublicKey/RSA.py new file mode 100644 index 0000000..27331ca --- /dev/null +++ b/frozen_deps/Cryptodome/PublicKey/RSA.py @@ -0,0 +1,796 @@ +# -*- coding: utf-8 -*- +# =================================================================== +# +# Copyright (c) 2016, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +__all__ = ['generate', 'construct', 'import_key', + 'RsaKey', 'oid'] + +import binascii +import struct + +from Cryptodome import Random +from Cryptodome.Util.py3compat import tobytes, bord, tostr +from Cryptodome.Util.asn1 import DerSequence + +from Cryptodome.Math.Numbers import Integer +from Cryptodome.Math.Primality import (test_probable_prime, + generate_probable_prime, COMPOSITE) + +from Cryptodome.PublicKey import (_expand_subject_public_key_info, + _create_subject_public_key_info, + _extract_subject_public_key_info) + + +class RsaKey(object): + r"""Class defining an actual RSA key. + Do not instantiate directly. + Use :func:`generate`, :func:`construct` or :func:`import_key` instead. + + :ivar n: RSA modulus + :vartype n: integer + + :ivar e: RSA public exponent + :vartype e: integer + + :ivar d: RSA private exponent + :vartype d: integer + + :ivar p: First factor of the RSA modulus + :vartype p: integer + + :ivar q: Second factor of the RSA modulus + :vartype q: integer + + :ivar u: Chinese remainder component (:math:`p^{-1} \text{mod } q`) + :vartype q: integer + """ + + def __init__(self, **kwargs): + """Build an RSA key. + + :Keywords: + n : integer + The modulus. + e : integer + The public exponent. + d : integer + The private exponent. Only required for private keys. + p : integer + The first factor of the modulus. Only required for private keys. + q : integer + The second factor of the modulus. Only required for private keys. + u : integer + The CRT coefficient (inverse of p modulo q). Only required for + private keys. + """ + + input_set = set(kwargs.keys()) + public_set = set(('n', 'e')) + private_set = public_set | set(('p', 'q', 'd', 'u')) + if input_set not in (private_set, public_set): + raise ValueError("Some RSA components are missing") + for component, value in kwargs.items(): + setattr(self, "_" + component, value) + if input_set == private_set: + self._dp = self._d % (self._p - 1) # = (e⁻¹) mod (p-1) + self._dq = self._d % (self._q - 1) # = (e⁻¹) mod (q-1) + + @property + def n(self): + return int(self._n) + + @property + def e(self): + return int(self._e) + + @property + def d(self): + if not self.has_private(): + raise AttributeError("No private exponent available for public keys") + return int(self._d) + + @property + def p(self): + if not self.has_private(): + raise AttributeError("No CRT component 'p' available for public keys") + return int(self._p) + + @property + def q(self): + if not self.has_private(): + raise AttributeError("No CRT component 'q' available for public keys") + return int(self._q) + + @property + def u(self): + if not self.has_private(): + raise AttributeError("No CRT component 'u' available for public keys") + return int(self._u) + + def size_in_bits(self): + """Size of the RSA modulus in bits""" + return self._n.size_in_bits() + + def size_in_bytes(self): + """The minimal amount of bytes that can hold the RSA modulus""" + return (self._n.size_in_bits() - 1) // 8 + 1 + + def _encrypt(self, plaintext): + if not 0 <= plaintext < self._n: + raise ValueError("Plaintext too large") + return int(pow(Integer(plaintext), self._e, self._n)) + + def _decrypt(self, ciphertext): + if not 0 <= ciphertext < self._n: + raise ValueError("Ciphertext too large") + if not self.has_private(): + raise TypeError("This is not a private key") + + # Blinded RSA decryption (to prevent timing attacks): + # Step 1: Generate random secret blinding factor r, + # such that 0 < r < n-1 + r = Integer.random_range(min_inclusive=1, max_exclusive=self._n) + # Step 2: Compute c' = c * r**e mod n + cp = Integer(ciphertext) * pow(r, self._e, self._n) % self._n + # Step 3: Compute m' = c'**d mod n (normal RSA decryption) + m1 = pow(cp, self._dp, self._p) + m2 = pow(cp, self._dq, self._q) + h = ((m2 - m1) * self._u) % self._q + mp = h * self._p + m1 + # Step 4: Compute m = m**(r-1) mod n + result = (r.inverse(self._n) * mp) % self._n + # Verify no faults occurred + if ciphertext != pow(result, self._e, self._n): + raise ValueError("Fault detected in RSA decryption") + return result + + def has_private(self): + """Whether this is an RSA private key""" + + return hasattr(self, "_d") + + def can_encrypt(self): # legacy + return True + + def can_sign(self): # legacy + return True + + def publickey(self): + """A matching RSA public key. + + Returns: + a new :class:`RsaKey` object + """ + return RsaKey(n=self._n, e=self._e) + + def __eq__(self, other): + if self.has_private() != other.has_private(): + return False + if self.n != other.n or self.e != other.e: + return False + if not self.has_private(): + return True + return (self.d == other.d) + + def __ne__(self, other): + return not (self == other) + + def __getstate__(self): + # RSA key is not pickable + from pickle import PicklingError + raise PicklingError + + def __repr__(self): + if self.has_private(): + extra = ", d=%d, p=%d, q=%d, u=%d" % (int(self._d), int(self._p), + int(self._q), int(self._u)) + else: + extra = "" + return "RsaKey(n=%d, e=%d%s)" % (int(self._n), int(self._e), extra) + + def __str__(self): + if self.has_private(): + key_type = "Private" + else: + key_type = "Public" + return "%s RSA key at 0x%X" % (key_type, id(self)) + + def export_key(self, format='PEM', passphrase=None, pkcs=1, + protection=None, randfunc=None): + """Export this RSA key. + + Args: + format (string): + The format to use for wrapping the key: + + - *'PEM'*. (*Default*) Text encoding, done according to `RFC1421`_/`RFC1423`_. + - *'DER'*. Binary encoding. + - *'OpenSSH'*. Textual encoding, done according to OpenSSH specification. + Only suitable for public keys (not private keys). + + passphrase (string): + (*For private keys only*) The pass phrase used for protecting the output. + + pkcs (integer): + (*For private keys only*) The ASN.1 structure to use for + serializing the key. Note that even in case of PEM + encoding, there is an inner ASN.1 DER structure. + + With ``pkcs=1`` (*default*), the private key is encoded in a + simple `PKCS#1`_ structure (``RSAPrivateKey``). + + With ``pkcs=8``, the private key is encoded in a `PKCS#8`_ structure + (``PrivateKeyInfo``). + + .. note:: + This parameter is ignored for a public key. + For DER and PEM, an ASN.1 DER ``SubjectPublicKeyInfo`` + structure is always used. + + protection (string): + (*For private keys only*) + The encryption scheme to use for protecting the private key. + + If ``None`` (default), the behavior depends on :attr:`format`: + + - For *'DER'*, the *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC* + scheme is used. The following operations are performed: + + 1. A 16 byte Triple DES key is derived from the passphrase + using :func:`Cryptodome.Protocol.KDF.PBKDF2` with 8 bytes salt, + and 1 000 iterations of :mod:`Cryptodome.Hash.HMAC`. + 2. The private key is encrypted using CBC. + 3. The encrypted key is encoded according to PKCS#8. + + - For *'PEM'*, the obsolete PEM encryption scheme is used. + It is based on MD5 for key derivation, and Triple DES for encryption. + + Specifying a value for :attr:`protection` is only meaningful for PKCS#8 + (that is, ``pkcs=8``) and only if a pass phrase is present too. + + The supported schemes for PKCS#8 are listed in the + :mod:`Cryptodome.IO.PKCS8` module (see :attr:`wrap_algo` parameter). + + randfunc (callable): + A function that provides random bytes. Only used for PEM encoding. + The default is :func:`Cryptodome.Random.get_random_bytes`. + + Returns: + byte string: the encoded key + + Raises: + ValueError:when the format is unknown or when you try to encrypt a private + key with *DER* format and PKCS#1. + + .. warning:: + If you don't provide a pass phrase, the private key will be + exported in the clear! + + .. _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 randfunc is None: + randfunc = Random.get_random_bytes + + if format == 'OpenSSH': + e_bytes, n_bytes = [x.to_bytes() for x in (self._e, self._n)] + if bord(e_bytes[0]) & 0x80: + e_bytes = b'\x00' + e_bytes + if bord(n_bytes[0]) & 0x80: + n_bytes = b'\x00' + n_bytes + keyparts = [b'ssh-rsa', e_bytes, n_bytes] + keystring = b''.join([struct.pack(">I", len(kp)) + kp for kp in keyparts]) + return b'ssh-rsa ' + binascii.b2a_base64(keystring)[:-1] + + # DER format is always used, even in case of PEM, which simply + # encodes it into BASE64. + if self.has_private(): + binary_key = DerSequence([0, + self.n, + self.e, + self.d, + self.p, + self.q, + self.d % (self.p-1), + self.d % (self.q-1), + Integer(self.q).inverse(self.p) + ]).encode() + if pkcs == 1: + key_type = 'RSA PRIVATE KEY' + if format == 'DER' and passphrase: + raise ValueError("PKCS#1 private key cannot be encrypted") + else: # PKCS#8 + from Cryptodome.IO import PKCS8 + + if format == 'PEM' and protection is None: + key_type = 'PRIVATE KEY' + binary_key = PKCS8.wrap(binary_key, oid, None) + else: + key_type = 'ENCRYPTED PRIVATE KEY' + if not protection: + protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC' + binary_key = PKCS8.wrap(binary_key, oid, + passphrase, protection) + passphrase = None + else: + key_type = "PUBLIC KEY" + binary_key = _create_subject_public_key_info(oid, + DerSequence([self.n, + self.e]) + ) + + if format == 'DER': + return binary_key + if format == 'PEM': + from Cryptodome.IO import PEM + + pem_str = PEM.encode(binary_key, key_type, passphrase, randfunc) + return tobytes(pem_str) + + raise ValueError("Unknown key format '%s'. Cannot export the RSA key." % format) + + # Backward compatibility + exportKey = export_key + + # Methods defined in PyCryptodome that we don't support anymore + def sign(self, M, K): + raise NotImplementedError("Use module Cryptodome.Signature.pkcs1_15 instead") + + def verify(self, M, signature): + raise NotImplementedError("Use module Cryptodome.Signature.pkcs1_15 instead") + + def encrypt(self, plaintext, K): + raise NotImplementedError("Use module Cryptodome.Cipher.PKCS1_OAEP instead") + + def decrypt(self, ciphertext): + raise NotImplementedError("Use module Cryptodome.Cipher.PKCS1_OAEP instead") + + def blind(self, M, B): + raise NotImplementedError + + def unblind(self, M, B): + raise NotImplementedError + + def size(self): + raise NotImplementedError + + +def generate(bits, randfunc=None, e=65537): + """Create a new RSA key pair. + + The algorithm closely follows NIST `FIPS 186-4`_ in its + sections B.3.1 and B.3.3. The modulus is the product of + two non-strong probable primes. + Each prime passes a suitable number of Miller-Rabin tests + with random bases and a single Lucas test. + + Args: + bits (integer): + Key length, or size (in bits) of the RSA modulus. + It must be at least 1024, but **2048 is recommended.** + The FIPS standard only defines 1024, 2048 and 3072. + randfunc (callable): + Function that returns random bytes. + The default is :func:`Cryptodome.Random.get_random_bytes`. + e (integer): + 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 FIPS standard requires the public exponent to be + at least 65537 (the default). + + Returns: an RSA key object (:class:`RsaKey`, with private key). + + .. _FIPS 186-4: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf + """ + + if bits < 1024: + raise ValueError("RSA modulus length must be >= 1024") + if e % 2 == 0 or e < 3: + raise ValueError("RSA public exponent must be a positive, odd integer larger than 2.") + + if randfunc is None: + randfunc = Random.get_random_bytes + + d = n = Integer(1) + e = Integer(e) + + while n.size_in_bits() != bits and d < (1 << (bits // 2)): + # Generate the prime factors of n: p and q. + # By construciton, their product is always + # 2^{bits-1} < p*q < 2^bits. + size_q = bits // 2 + size_p = bits - size_q + + min_p = min_q = (Integer(1) << (2 * size_q - 1)).sqrt() + if size_q != size_p: + min_p = (Integer(1) << (2 * size_p - 1)).sqrt() + + def filter_p(candidate): + return candidate > min_p and (candidate - 1).gcd(e) == 1 + + p = generate_probable_prime(exact_bits=size_p, + randfunc=randfunc, + prime_filter=filter_p) + + min_distance = Integer(1) << (bits // 2 - 100) + + def filter_q(candidate): + return (candidate > min_q and + (candidate - 1).gcd(e) == 1 and + abs(candidate - p) > min_distance) + + q = generate_probable_prime(exact_bits=size_q, + randfunc=randfunc, + prime_filter=filter_q) + + n = p * q + lcm = (p - 1).lcm(q - 1) + d = e.inverse(lcm) + + if p > q: + p, q = q, p + + u = p.inverse(q) + + return RsaKey(n=n, e=e, d=d, p=p, q=q, u=u) + + +def construct(rsa_components, consistency_check=True): + r"""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: + + .. math:: + + \begin{align} + p*q &= n \\ + e*d &\equiv 1 ( \text{mod lcm} [(p-1)(q-1)]) \\ + p*u &\equiv 1 ( \text{mod } q) + \end{align} + + Args: + rsa_components (tuple): + A tuple of 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, but the other factor *q* must also be present. + 5. Second factor of *n* (*q*). Optional. + 6. CRT coefficient *q*, that is :math:`p^{-1} \text{mod }q`. Optional. + + consistency_check (boolean): + If ``True``, the library will verify that the provided components + fulfil the main RSA properties. + + Raises: + ValueError: when the key being imported fails the most basic RSA validity checks. + + Returns: An RSA key object (:class:`RsaKey`). + """ + + class InputComps(object): + pass + + input_comps = InputComps() + for (comp, value) in zip(('n', 'e', 'd', 'p', 'q', 'u'), rsa_components): + setattr(input_comps, comp, Integer(value)) + + n = input_comps.n + e = input_comps.e + if not hasattr(input_comps, 'd'): + key = RsaKey(n=n, e=e) + else: + d = input_comps.d + if hasattr(input_comps, 'q'): + p = input_comps.p + q = input_comps.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 //= 2 + # 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 = False + a = Integer(2) + while not spotted and a < 100: + k = Integer(t) + # Cycle through all values a^{t*2^i}=a^k + while k < ktot: + cand = pow(a, k, n) + # Check if a^k is a non-trivial root of unity (mod n) + if cand != 1 and cand != (n - 1) and pow(cand, 2, n) == 1: + # We have found a number such that (cand-1)(cand+1)=0 (mod n). + # Either of the terms divides n. + p = Integer(n).gcd(cand + 1) + spotted = True + break + k *= 2 + # This value was not any good... let's try another! + a += 2 + if not spotted: + raise ValueError("Unable to compute factors p and q from exponent d.") + # Found ! + assert ((n % p) == 0) + q = n // p + + if hasattr(input_comps, 'u'): + u = input_comps.u + else: + u = p.inverse(q) + + # Build key object + key = RsaKey(n=n, e=e, d=d, p=p, q=q, u=u) + + # Verify consistency of the key + if consistency_check: + + # Modulus and public exponent must be coprime + if e <= 1 or e >= n: + raise ValueError("Invalid RSA public exponent") + if Integer(n).gcd(e) != 1: + raise ValueError("RSA public exponent is not coprime to modulus") + + # For RSA, modulus must be odd + if not n & 1: + raise ValueError("RSA modulus is not odd") + + if key.has_private(): + # Modulus and private exponent must be coprime + if d <= 1 or d >= n: + raise ValueError("Invalid RSA private exponent") + if Integer(n).gcd(d) != 1: + raise ValueError("RSA private exponent is not coprime to modulus") + # Modulus must be product of 2 primes + if p * q != n: + raise ValueError("RSA factors do not match modulus") + if test_probable_prime(p) == COMPOSITE: + raise ValueError("RSA factor p is composite") + if test_probable_prime(q) == COMPOSITE: + raise ValueError("RSA factor q is composite") + # See Carmichael theorem + phi = (p - 1) * (q - 1) + lcm = phi // (p - 1).gcd(q - 1) + if (e * d % int(lcm)) != 1: + raise ValueError("Invalid RSA condition") + if hasattr(key, 'u'): + # CRT coefficient + if u <= 1 or u >= q: + raise ValueError("Invalid RSA component u") + if (p * u % q) != 1: + raise ValueError("Invalid RSA component u with p") + + return key + + +def _import_pkcs1_private(encoded, *kwargs): + # RSAPrivateKey ::= SEQUENCE { + # version Version, + # modulus INTEGER, -- n + # publicExponent INTEGER, -- e + # privateExponent INTEGER, -- d + # prime1 INTEGER, -- p + # prime2 INTEGER, -- q + # exponent1 INTEGER, -- d mod (p-1) + # exponent2 INTEGER, -- d mod (q-1) + # coefficient INTEGER -- (inverse of q) mod p + # } + # + # Version ::= INTEGER + der = DerSequence().decode(encoded, nr_elements=9, only_ints_expected=True) + if der[0] != 0: + raise ValueError("No PKCS#1 encoding of an RSA private key") + return construct(der[1:6] + [Integer(der[4]).inverse(der[5])]) + + +def _import_pkcs1_public(encoded, *kwargs): + # RSAPublicKey ::= SEQUENCE { + # modulus INTEGER, -- n + # publicExponent INTEGER -- e + # } + der = DerSequence().decode(encoded, nr_elements=2, only_ints_expected=True) + return construct(der) + + +def _import_subjectPublicKeyInfo(encoded, *kwargs): + + algoid, encoded_key, params = _expand_subject_public_key_info(encoded) + if algoid != oid or params is not None: + raise ValueError("No RSA subjectPublicKeyInfo") + return _import_pkcs1_public(encoded_key) + + +def _import_x509_cert(encoded, *kwargs): + + sp_info = _extract_subject_public_key_info(encoded) + return _import_subjectPublicKeyInfo(sp_info) + + +def _import_pkcs8(encoded, passphrase): + from Cryptodome.IO import PKCS8 + + k = PKCS8.unwrap(encoded, passphrase) + if k[0] != oid: + raise ValueError("No PKCS#8 encoded RSA key") + return _import_keyDER(k[1], passphrase) + + +def _import_keyDER(extern_key, passphrase): + """Import an RSA key (public or private half), encoded in DER form.""" + + decodings = (_import_pkcs1_private, + _import_pkcs1_public, + _import_subjectPublicKeyInfo, + _import_x509_cert, + _import_pkcs8) + + for decoding in decodings: + try: + return decoding(extern_key, passphrase) + except ValueError: + pass + + raise ValueError("RSA key format is not supported") + + +def _import_openssh_private_rsa(data, password): + + from ._openssh import (import_openssh_private_generic, + read_bytes, read_string, check_padding) + + ssh_name, decrypted = import_openssh_private_generic(data, password) + + if ssh_name != "ssh-rsa": + raise ValueError("This SSH key is not RSA") + + n, decrypted = read_bytes(decrypted) + e, decrypted = read_bytes(decrypted) + d, decrypted = read_bytes(decrypted) + iqmp, decrypted = read_bytes(decrypted) + p, decrypted = read_bytes(decrypted) + q, decrypted = read_bytes(decrypted) + + _, padded = read_string(decrypted) # Comment + check_padding(padded) + + build = [Integer.from_bytes(x) for x in (n, e, d, q, p, iqmp)] + return construct(build) + + +def import_key(extern_key, passphrase=None): + """Import an RSA key (public or private). + + Args: + extern_key (string or byte string): + The RSA key to import. + + The following formats are supported for an RSA **public key**: + + - X.509 certificate (binary or PEM format) + - X.509 ``subjectPublicKeyInfo`` DER SEQUENCE (binary or PEM + encoding) + - `PKCS#1`_ ``RSAPublicKey`` DER SEQUENCE (binary or PEM encoding) + - An OpenSSH line (e.g. the content of ``~/.ssh/id_ecdsa``, ASCII) + + The following formats are supported for an RSA **private key**: + + - PKCS#1 ``RSAPrivateKey`` DER SEQUENCE (binary or PEM encoding) + - `PKCS#8`_ ``PrivateKeyInfo`` or ``EncryptedPrivateKeyInfo`` + DER SEQUENCE (binary or PEM encoding) + - OpenSSH (text format, introduced in `OpenSSH 6.5`_) + + For details about the PEM encoding, see `RFC1421`_/`RFC1423`_. + + passphrase (string or byte string): + For private keys only, the pass phrase that encrypts the key. + + Returns: An RSA key object (:class:`RsaKey`). + + Raises: + 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 + .. _`OpenSSH 6.5`: https://flak.tedunangst.com/post/new-openssh-key-format-and-bcrypt-pbkdf + """ + + from Cryptodome.IO import PEM + + extern_key = tobytes(extern_key) + if passphrase is not None: + passphrase = tobytes(passphrase) + + if extern_key.startswith(b'-----BEGIN OPENSSH PRIVATE KEY'): + text_encoded = tostr(extern_key) + openssh_encoded, marker, enc_flag = PEM.decode(text_encoded, passphrase) + result = _import_openssh_private_rsa(openssh_encoded, passphrase) + return result + + if extern_key.startswith(b'-----'): + # This is probably a PEM encoded key. + (der, marker, enc_flag) = PEM.decode(tostr(extern_key), passphrase) + if enc_flag: + passphrase = None + return _import_keyDER(der, passphrase) + + if extern_key.startswith(b'ssh-rsa '): + # This is probably an OpenSSH key + keystring = binascii.a2b_base64(extern_key.split(b' ')[1]) + keyparts = [] + while len(keystring) > 4: + length = struct.unpack(">I", keystring[:4])[0] + keyparts.append(keystring[4:4 + length]) + keystring = keystring[4 + length:] + e = Integer.from_bytes(keyparts[1]) + n = Integer.from_bytes(keyparts[2]) + return construct([n, e]) + + if len(extern_key) > 0 and bord(extern_key[0]) == 0x30: + # This is probably a DER encoded key + return _import_keyDER(extern_key, passphrase) + + raise ValueError("RSA key format is not supported") + + +# Backward compatibility +importKey = import_key + +#: `Object ID`_ for the RSA encryption algorithm. This OID often indicates +#: a generic RSA key, even when such key will be actually used for digital +#: signatures. +#: +#: .. _`Object ID`: http://www.alvestrand.no/objectid/1.2.840.113549.1.1.1.html +oid = "1.2.840.113549.1.1.1" diff --git a/frozen_deps/Cryptodome/PublicKey/RSA.pyi b/frozen_deps/Cryptodome/PublicKey/RSA.pyi new file mode 100644 index 0000000..e4d0369 --- /dev/null +++ b/frozen_deps/Cryptodome/PublicKey/RSA.pyi @@ -0,0 +1,50 @@ +from typing import Callable, Union, Tuple, Optional + +__all__ = ['generate', 'construct', 'import_key', + 'RsaKey', 'oid'] + +RNG = Callable[[int], bytes] + +class RsaKey(object): + def __init__(self, **kwargs: int) -> None: ... + @property + def n(self) -> int: ... + @property + def e(self) -> int: ... + @property + def d(self) -> int: ... + @property + def p(self) -> int: ... + @property + def q(self) -> int: ... + @property + def u(self) -> int: ... + def size_in_bits(self) -> int: ... + def size_in_bytes(self) -> int: ... + def has_private(self) -> bool: ... + def can_encrypt(self) -> bool: ... # legacy + def can_sign(self) -> bool:... # legacy + def publickey(self) -> RsaKey: ... + def __eq__(self, other: object) -> bool: ... + def __ne__(self, other: object) -> bool: ... + def __getstate__(self) -> None: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... + def export_key(self, format: Optional[str]="PEM", passphrase: Optional[str]=None, pkcs: Optional[int]=1, + protection: Optional[str]=None, randfunc: Optional[RNG]=None) -> bytes: ... + + # Backward compatibility + exportKey = export_key + +def generate(bits: int, randfunc: Optional[RNG]=None, e: Optional[int]=65537) -> RsaKey: ... +def construct(rsa_components: Union[Tuple[int, int], # n, e + Tuple[int, int, int], # n, e, d + Tuple[int, int, int, int, int], # n, e, d, p, q + Tuple[int, int, int, int, int, int]], # n, e, d, p, q, crt_q + consistency_check: Optional[bool]=True) -> RsaKey: ... +def import_key(extern_key: Union[str, bytes], passphrase: Optional[str]=None) -> RsaKey: ... + +# Backward compatibility +importKey = import_key + +oid: str diff --git a/frozen_deps/Cryptodome/PublicKey/__init__.py b/frozen_deps/Cryptodome/PublicKey/__init__.py new file mode 100644 index 0000000..4d019bf --- /dev/null +++ b/frozen_deps/Cryptodome/PublicKey/__init__.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. +# =================================================================== + +from Cryptodome.Util.asn1 import (DerSequence, DerInteger, DerBitString, + DerObjectId, DerNull) + + +def _expand_subject_public_key_info(encoded): + """Parse a SubjectPublicKeyInfo structure. + + It returns a triple with: + * OID (string) + * encoded public key (bytes) + * Algorithm parameters (bytes or None) + """ + + # + # SubjectPublicKeyInfo ::= SEQUENCE { + # algorithm AlgorithmIdentifier, + # subjectPublicKey BIT STRING + # } + # + # AlgorithmIdentifier ::= SEQUENCE { + # algorithm OBJECT IDENTIFIER, + # parameters ANY DEFINED BY algorithm OPTIONAL + # } + # + + spki = DerSequence().decode(encoded, nr_elements=2) + algo = DerSequence().decode(spki[0], nr_elements=(1,2)) + algo_oid = DerObjectId().decode(algo[0]) + spk = DerBitString().decode(spki[1]).value + + if len(algo) == 1: + algo_params = None + else: + try: + DerNull().decode(algo[1]) + algo_params = None + except: + algo_params = algo[1] + + return algo_oid.value, spk, algo_params + + +def _create_subject_public_key_info(algo_oid, secret_key, params=None): + + if params is None: + params = DerNull() + + spki = DerSequence([ + DerSequence([ + DerObjectId(algo_oid), + params]), + DerBitString(secret_key) + ]) + return spki.encode() + + +def _extract_subject_public_key_info(x509_certificate): + """Extract subjectPublicKeyInfo from a DER X.509 certificate.""" + + certificate = DerSequence().decode(x509_certificate, nr_elements=3) + tbs_certificate = DerSequence().decode(certificate[0], + nr_elements=range(6, 11)) + + index = 5 + try: + tbs_certificate[0] + 1 + # Version not present + version = 1 + except TypeError: + version = DerInteger(explicit=0).decode(tbs_certificate[0]).value + if version not in (2, 3): + raise ValueError("Incorrect X.509 certificate version") + index = 6 + + return tbs_certificate[index] diff --git a/frozen_deps/Cryptodome/PublicKey/__init__.pyi b/frozen_deps/Cryptodome/PublicKey/__init__.pyi new file mode 100644 index 0000000..e69de29 diff --git a/frozen_deps/Cryptodome/PublicKey/_ec_ws.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/PublicKey/_ec_ws.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..fba01e8 Binary files /dev/null and b/frozen_deps/Cryptodome/PublicKey/_ec_ws.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/PublicKey/_openssh.py b/frozen_deps/Cryptodome/PublicKey/_openssh.py new file mode 100644 index 0000000..53b16df --- /dev/null +++ b/frozen_deps/Cryptodome/PublicKey/_openssh.py @@ -0,0 +1,135 @@ +# =================================================================== +# +# Copyright (c) 2019, Helder Eijs +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +import struct + +from Cryptodome.Cipher import AES +from Cryptodome.Hash import SHA512 +from Cryptodome.Protocol.KDF import _bcrypt_hash +from Cryptodome.Util.strxor import strxor +from Cryptodome.Util.py3compat import tostr, bchr, bord + + +def read_int4(data): + if len(data) < 4: + raise ValueError("Insufficient data") + value = struct.unpack(">I", data[:4])[0] + return value, data[4:] + + +def read_bytes(data): + size, data = read_int4(data) + if len(data) < size: + raise ValueError("Insufficient data (V)") + return data[:size], data[size:] + + +def read_string(data): + s, d = read_bytes(data) + return tostr(s), d + + +def check_padding(pad): + for v, x in enumerate(pad): + if bord(x) != ((v + 1) & 0xFF): + raise ValueError("Incorrect padding") + + +def import_openssh_private_generic(data, password): + # https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.key?annotate=HEAD + # https://github.com/openssh/openssh-portable/blob/master/sshkey.c + # https://coolaj86.com/articles/the-openssh-private-key-format/ + # https://coolaj86.com/articles/the-ssh-public-key-format/ + + if not data.startswith(b'openssh-key-v1\x00'): + raise ValueError("Incorrect magic value") + data = data[15:] + + ciphername, data = read_string(data) + kdfname, data = read_string(data) + kdfoptions, data = read_bytes(data) + number_of_keys, data = read_int4(data) + + if number_of_keys != 1: + raise ValueError("We only handle 1 key at a time") + + _, data = read_string(data) # Public key + encrypted, data = read_bytes(data) + if data: + raise ValueError("Too much data") + + if len(encrypted) % 8 != 0: + raise ValueError("Incorrect payload length") + + # Decrypt if necessary + if ciphername == 'none': + decrypted = encrypted + else: + if (ciphername, kdfname) != ('aes256-ctr', 'bcrypt'): + raise ValueError("Unsupported encryption scheme %s/%s" % (ciphername, kdfname)) + + salt, kdfoptions = read_bytes(kdfoptions) + iterations, kdfoptions = read_int4(kdfoptions) + + if len(salt) != 16: + raise ValueError("Incorrect salt length") + if kdfoptions: + raise ValueError("Too much data in kdfoptions") + + pwd_sha512 = SHA512.new(password).digest() + # We need 32+16 = 48 bytes, therefore 2 bcrypt outputs are sufficient + stripes = [] + constant = b"OxychromaticBlowfishSwatDynamite" + for count in range(1, 3): + salt_sha512 = SHA512.new(salt + struct.pack(">I", count)).digest() + out_le = _bcrypt_hash(pwd_sha512, 6, salt_sha512, constant, False) + out = struct.pack("IIIIIIII", out_le)) + acc = bytearray(out) + for _ in range(1, iterations): + out_le = _bcrypt_hash(pwd_sha512, 6, SHA512.new(out).digest(), constant, False) + out = struct.pack("IIIIIIII", out_le)) + strxor(acc, out, output=acc) + stripes.append(acc[:24]) + + result = b"".join([bchr(a)+bchr(b) for (a, b) in zip(*stripes)]) + + cipher = AES.new(result[:32], + AES.MODE_CTR, + nonce=b"", + initial_value=result[32:32+16]) + decrypted = cipher.decrypt(encrypted) + + checkint1, decrypted = read_int4(decrypted) + checkint2, decrypted = read_int4(decrypted) + if checkint1 != checkint2: + raise ValueError("Incorrect checksum") + ssh_name, decrypted = read_string(decrypted) + + return ssh_name, decrypted diff --git a/frozen_deps/Cryptodome/PublicKey/_openssh.pyi b/frozen_deps/Cryptodome/PublicKey/_openssh.pyi new file mode 100644 index 0000000..15f3677 --- /dev/null +++ b/frozen_deps/Cryptodome/PublicKey/_openssh.pyi @@ -0,0 +1,7 @@ +from typing import Tuple + +def read_int4(data: bytes) -> Tuple[int, bytes]: ... +def read_bytes(data: bytes) -> Tuple[bytes, bytes]: ... +def read_string(data: bytes) -> Tuple[str, bytes]: ... +def check_padding(pad: bytes) -> None: ... +def import_openssh_private_generic(data: bytes, password: bytes) -> Tuple[str, bytes]: ... diff --git a/frozen_deps/Cryptodome/Random/__init__.py b/frozen_deps/Cryptodome/Random/__init__.py new file mode 100644 index 0000000..fd18d86 --- /dev/null +++ b/frozen_deps/Cryptodome/Random/__init__.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# +# Random/__init__.py : PyCryptodome random number generation +# +# =================================================================== +# 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. +# =================================================================== + +__all__ = ['new', 'get_random_bytes'] + +from os import urandom + +class _UrandomRNG(object): + + def read(self, n): + """Return a random byte string of the desired size.""" + return urandom(n) + + def flush(self): + """Method provided for backward compatibility only.""" + pass + + def reinit(self): + """Method provided for backward compatibility only.""" + pass + + def close(self): + """Method provided for backward compatibility only.""" + pass + + +def new(*args, **kwargs): + """Return a file-like object that outputs cryptographically random bytes.""" + return _UrandomRNG() + + +def atfork(): + pass + + +#: Function that returns a random byte string of the desired size. +get_random_bytes = urandom + diff --git a/frozen_deps/Cryptodome/Random/__init__.pyi b/frozen_deps/Cryptodome/Random/__init__.pyi new file mode 100644 index 0000000..ddc5b9b --- /dev/null +++ b/frozen_deps/Cryptodome/Random/__init__.pyi @@ -0,0 +1,19 @@ +from typing import Any + +__all__ = ['new', 'get_random_bytes'] + +from os import urandom + +class _UrandomRNG(object): + + def read(self, n: int) -> bytes:... + def flush(self) -> None: ... + def reinit(self) -> None: ... + def close(self) -> None: ... + +def new(*args: Any, **kwargs: Any) -> _UrandomRNG: ... + +def atfork() -> None: ... + +get_random_bytes = urandom + diff --git a/frozen_deps/Cryptodome/Random/random.py b/frozen_deps/Cryptodome/Random/random.py new file mode 100644 index 0000000..da30795 --- /dev/null +++ b/frozen_deps/Cryptodome/Random/random.py @@ -0,0 +1,138 @@ +# -*- 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. +# =================================================================== + +__all__ = ['StrongRandom', 'getrandbits', 'randrange', 'randint', 'choice', 'shuffle', 'sample'] + +from Cryptodome import Random + +from Cryptodome.Util.py3compat import is_native_int + +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 an integer with k random bits.""" + + if self._randfunc is None: + self._randfunc = Random.new().read + mask = (1 << 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 is_native_int(start) or not is_native_int(stop) or not + is_native_int(step)): + 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 is_native_int(a) or not is_native_int(b): + 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.""" + # Fisher-Yates shuffle. O(n) + # See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + # Working backwards from the end of the array, we choose a random item + # from the remaining items until all items have been chosen. + for i in range(len(x)-1, 0, -1): # iterate from len(x)-1 downto 1 + j = self.randrange(0, i+1) # choose random j such that 0 <= j <= i + x[i], x[j] = x[j], x[i] # exchange x[i] and x[j] + + 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 range(k): + r = None + while r is None or r in selected: + 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 Cryptodome.Util.number import ceil_div, bytes_to_long, long_to_bytes, size + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/frozen_deps/Cryptodome/Random/random.pyi b/frozen_deps/Cryptodome/Random/random.pyi new file mode 100644 index 0000000..f873c4a --- /dev/null +++ b/frozen_deps/Cryptodome/Random/random.pyi @@ -0,0 +1,20 @@ +from typing import Callable, Tuple, Union, Sequence, Any, Optional + +__all__ = ['StrongRandom', 'getrandbits', 'randrange', 'randint', 'choice', 'shuffle', 'sample'] + +class StrongRandom(object): + def __init__(self, rng: Optional[Any]=None, randfunc: Optional[Callable]=None) -> None: ... # TODO What is rng? + def getrandbits(self, k: int) -> int: ... + def randrange(self, start: int, stop: int = ..., step: int = ...) -> int: ... + def randint(self, a: int, b: int) -> int: ... + def choice(self, seq: Sequence) -> object: ... + def shuffle(self, x: Sequence) -> None: ... + def sample(self, population: Sequence, k: int) -> list: ... + +_r = StrongRandom() +getrandbits = _r.getrandbits +randrange = _r.randrange +randint = _r.randint +choice = _r.choice +shuffle = _r.shuffle +sample = _r.sample diff --git a/frozen_deps/Cryptodome/Signature/DSS.py b/frozen_deps/Cryptodome/Signature/DSS.py new file mode 100644 index 0000000..3dcbeb4 --- /dev/null +++ b/frozen_deps/Cryptodome/Signature/DSS.py @@ -0,0 +1,413 @@ +# +# Signature/DSS.py : DSS.py +# +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +__all__ = ['new'] + + +from Cryptodome.Util.asn1 import DerSequence +from Cryptodome.Util.number import long_to_bytes +from Cryptodome.Math.Numbers import Integer + +from Cryptodome.Hash import HMAC +from Cryptodome.PublicKey.ECC import EccKey + + +class DssSigScheme(object): + """A (EC)DSA signature object. + Do not instantiate directly. + Use :func:`Cryptodome.Signature.DSS.new`. + """ + + def __init__(self, key, encoding, order): + """Create a new Digital Signature Standard (DSS) object. + + Do not instantiate this object directly, + use `Cryptodome.Signature.DSS.new` instead. + """ + + self._key = key + self._encoding = encoding + self._order = order + + self._order_bits = self._order.size_in_bits() + self._order_bytes = (self._order_bits - 1) // 8 + 1 + + def can_sign(self): + """Return ``True`` if this signature object can be used + for signing messages.""" + + return self._key.has_private() + + def _compute_nonce(self, msg_hash): + raise NotImplementedError("To be provided by subclasses") + + def _valid_hash(self, msg_hash): + raise NotImplementedError("To be provided by subclasses") + + def sign(self, msg_hash): + """Produce the DSA/ECDSA signature of a message. + + :parameter msg_hash: + The hash that was carried out over the message. + The object belongs to the :mod:`Cryptodome.Hash` package. + + Under mode *'fips-186-3'*, the hash must be a FIPS + approved secure hash (SHA-1 or a member of the SHA-2 family), + of cryptographic strength appropriate for the DSA key. + For instance, a 3072/256 DSA key can only be used + in combination with SHA-512. + :type msg_hash: hash object + + :return: The signature as a *byte string* + :raise ValueError: if the hash algorithm is incompatible to the (EC)DSA key + :raise TypeError: if the (EC)DSA key has no private half + """ + + if not self._valid_hash(msg_hash): + raise ValueError("Hash is not sufficiently strong") + + # Generate the nonce k (critical!) + nonce = self._compute_nonce(msg_hash) + + # Perform signature using the raw API + z = Integer.from_bytes(msg_hash.digest()[:self._order_bytes]) + sig_pair = self._key._sign(z, nonce) + + # Encode the signature into a single byte string + if self._encoding == 'binary': + output = b"".join([long_to_bytes(x, self._order_bytes) + for x in sig_pair]) + else: + # Dss-sig ::= SEQUENCE { + # r INTEGER, + # s INTEGER + # } + # Ecdsa-Sig-Value ::= SEQUENCE { + # r INTEGER, + # s INTEGER + # } + output = DerSequence(sig_pair).encode() + + return output + + def verify(self, msg_hash, signature): + """Check if a certain (EC)DSA signature is authentic. + + :parameter msg_hash: + The hash that was carried out over the message. + This is an object belonging to the :mod:`Cryptodome.Hash` module. + + Under mode *'fips-186-3'*, the hash must be a FIPS + approved secure hash (SHA-1 or a member of the SHA-2 family), + of cryptographic strength appropriate for the DSA key. + For instance, a 3072/256 DSA key can only be used in + combination with SHA-512. + :type msg_hash: hash object + + :parameter signature: + The signature that needs to be validated + :type signature: byte string + + :raise ValueError: if the signature is not authentic + """ + + if not self._valid_hash(msg_hash): + raise ValueError("Hash is not sufficiently strong") + + if self._encoding == 'binary': + if len(signature) != (2 * self._order_bytes): + raise ValueError("The signature is not authentic (length)") + r_prime, s_prime = [Integer.from_bytes(x) + for x in (signature[:self._order_bytes], + signature[self._order_bytes:])] + else: + try: + der_seq = DerSequence().decode(signature, strict=True) + except (ValueError, IndexError): + raise ValueError("The signature is not authentic (DER)") + if len(der_seq) != 2 or not der_seq.hasOnlyInts(): + raise ValueError("The signature is not authentic (DER content)") + r_prime, s_prime = Integer(der_seq[0]), Integer(der_seq[1]) + + if not (0 < r_prime < self._order) or not (0 < s_prime < self._order): + raise ValueError("The signature is not authentic (d)") + + z = Integer.from_bytes(msg_hash.digest()[:self._order_bytes]) + result = self._key._verify(z, (r_prime, s_prime)) + if not result: + raise ValueError("The signature is not authentic") + # Make PyCryptodome code to fail + return False + + +class DeterministicDsaSigScheme(DssSigScheme): + # Also applicable to ECDSA + + def __init__(self, key, encoding, order, private_key): + super(DeterministicDsaSigScheme, self).__init__(key, encoding, order) + self._private_key = private_key + + def _bits2int(self, bstr): + """See 2.3.2 in RFC6979""" + + result = Integer.from_bytes(bstr) + q_len = self._order.size_in_bits() + b_len = len(bstr) * 8 + if b_len > q_len: + # Only keep leftmost q_len bits + result >>= (b_len - q_len) + return result + + def _int2octets(self, int_mod_q): + """See 2.3.3 in RFC6979""" + + assert 0 < int_mod_q < self._order + return long_to_bytes(int_mod_q, self._order_bytes) + + def _bits2octets(self, bstr): + """See 2.3.4 in RFC6979""" + + z1 = self._bits2int(bstr) + if z1 < self._order: + z2 = z1 + else: + z2 = z1 - self._order + return self._int2octets(z2) + + def _compute_nonce(self, mhash): + """Generate k in a deterministic way""" + + # See section 3.2 in RFC6979.txt + # Step a + h1 = mhash.digest() + # Step b + mask_v = b'\x01' * mhash.digest_size + # Step c + nonce_k = b'\x00' * mhash.digest_size + + for int_oct in (b'\x00', b'\x01'): + # Step d/f + nonce_k = HMAC.new(nonce_k, + mask_v + int_oct + + self._int2octets(self._private_key) + + self._bits2octets(h1), mhash).digest() + # Step e/g + mask_v = HMAC.new(nonce_k, mask_v, mhash).digest() + + nonce = -1 + while not (0 < nonce < self._order): + # Step h.C (second part) + if nonce != -1: + nonce_k = HMAC.new(nonce_k, mask_v + b'\x00', + mhash).digest() + mask_v = HMAC.new(nonce_k, mask_v, mhash).digest() + + # Step h.A + mask_t = b"" + + # Step h.B + while len(mask_t) < self._order_bytes: + mask_v = HMAC.new(nonce_k, mask_v, mhash).digest() + mask_t += mask_v + + # Step h.C (first part) + nonce = self._bits2int(mask_t) + return nonce + + def _valid_hash(self, msg_hash): + return True + + +class FipsDsaSigScheme(DssSigScheme): + + #: List of L (bit length of p) and N (bit length of q) combinations + #: that are allowed by FIPS 186-3. The security level is provided in + #: Table 2 of FIPS 800-57 (rev3). + _fips_186_3_L_N = ( + (1024, 160), # 80 bits (SHA-1 or stronger) + (2048, 224), # 112 bits (SHA-224 or stronger) + (2048, 256), # 128 bits (SHA-256 or stronger) + (3072, 256) # 256 bits (SHA-512) + ) + + def __init__(self, key, encoding, order, randfunc): + super(FipsDsaSigScheme, self).__init__(key, encoding, order) + self._randfunc = randfunc + + L = Integer(key.p).size_in_bits() + if (L, self._order_bits) not in self._fips_186_3_L_N: + error = ("L/N (%d, %d) is not compliant to FIPS 186-3" + % (L, self._order_bits)) + raise ValueError(error) + + def _compute_nonce(self, msg_hash): + # hash is not used + return Integer.random_range(min_inclusive=1, + max_exclusive=self._order, + randfunc=self._randfunc) + + def _valid_hash(self, msg_hash): + """Verify that SHA-1, SHA-2 or SHA-3 are used""" + return (msg_hash.oid == "1.3.14.3.2.26" or + msg_hash.oid.startswith("2.16.840.1.101.3.4.2.")) + + +class FipsEcDsaSigScheme(DssSigScheme): + + def __init__(self, key, encoding, order, randfunc): + super(FipsEcDsaSigScheme, self).__init__(key, encoding, order) + self._randfunc = randfunc + + def _compute_nonce(self, msg_hash): + return Integer.random_range(min_inclusive=1, + max_exclusive=self._key._curve.order, + randfunc=self._randfunc) + + def _valid_hash(self, msg_hash): + """Verify that SHA-[23] (256|384|512) bits are used to + match the security of P-256 (128 bits), P-384 (192 bits) + or P-521 (256 bits)""" + + modulus_bits = self._key.pointQ.size_in_bits() + + sha256 = ( "2.16.840.1.101.3.4.2.1", "2.16.840.1.101.3.4.2.8" ) + sha384 = ( "2.16.840.1.101.3.4.2.2", "2.16.840.1.101.3.4.2.9" ) + sha512 = ( "2.16.840.1.101.3.4.2.3", "2.16.840.1.101.3.4.2.10") + + if msg_hash.oid in sha256: + return modulus_bits <= 256 + elif msg_hash.oid in sha384: + return modulus_bits <= 384 + else: + return msg_hash.oid in sha512 + + +def new(key, mode, encoding='binary', randfunc=None): + """Create a signature object :class:`DSS_SigScheme` that + can perform (EC)DSA signature or verification. + + .. note:: + Refer to `NIST SP 800 Part 1 Rev 4`_ (or newer release) for an + overview of the recommended key lengths. + + :parameter key: + The key to use for computing the signature (*private* keys only) + or verifying one: it must be either + :class:`Cryptodome.PublicKey.DSA` or :class:`Cryptodome.PublicKey.ECC`. + + For DSA keys, let ``L`` and ``N`` be the bit lengths of the modulus ``p`` + and of ``q``: the pair ``(L,N)`` must appear in the following list, + in compliance to section 4.2 of `FIPS 186-4`_: + + - (1024, 160) *legacy only; do not create new signatures with this* + - (2048, 224) *deprecated; do not create new signatures with this* + - (2048, 256) + - (3072, 256) + + For ECC, only keys over P-256, P384, and P-521 are accepted. + :type key: + a key object + + :parameter mode: + The parameter can take these values: + + - *'fips-186-3'*. The signature generation is randomized and carried out + according to `FIPS 186-3`_: the nonce ``k`` is taken from the RNG. + - *'deterministic-rfc6979'*. The signature generation is not + randomized. See RFC6979_. + :type mode: + string + + :parameter encoding: + How the signature is encoded. This value determines the output of + :meth:`sign` and the input to :meth:`verify`. + + The following values are accepted: + + - *'binary'* (default), the signature is the raw concatenation + of ``r`` and ``s``. It is defined in the IEEE P.1363 standard. + + For DSA, the size in bytes of the signature is ``N/4`` bytes + (e.g. 64 for ``N=256``). + + For ECDSA, the signature is always twice the length of a point + coordinate (e.g. 64 bytes for P-256). + + - *'der'*, the signature is a ASN.1 DER SEQUENCE + with two INTEGERs (``r`` and ``s``). It is defined in RFC3279_. + The size of the signature is variable. + :type encoding: string + + :parameter randfunc: + A function that returns random *byte strings*, of a given length. + If omitted, the internal RNG is used. + Only applicable for the *'fips-186-3'* mode. + :type randfunc: callable + + .. _FIPS 186-3: http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf + .. _FIPS 186-4: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf + .. _NIST SP 800 Part 1 Rev 4: http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r4.pdf + .. _RFC6979: http://tools.ietf.org/html/rfc6979 + .. _RFC3279: https://tools.ietf.org/html/rfc3279#section-2.2.2 + """ + + # The goal of the 'mode' parameter is to avoid to + # have the current version of the standard as default. + # + # Over time, such version will be superseded by (for instance) + # FIPS 186-4 and it will be odd to have -3 as default. + + if encoding not in ('binary', 'der'): + raise ValueError("Unknown encoding '%s'" % encoding) + + if isinstance(key, EccKey): + order = key._curve.order + private_key_attr = 'd' + else: + order = Integer(key.q) + private_key_attr = 'x' + + if key.has_private(): + private_key = getattr(key, private_key_attr) + else: + private_key = None + + if mode == 'deterministic-rfc6979': + return DeterministicDsaSigScheme(key, encoding, order, private_key) + elif mode == 'fips-186-3': + if isinstance(key, EccKey): + return FipsEcDsaSigScheme(key, encoding, order, randfunc) + else: + return FipsDsaSigScheme(key, encoding, order, randfunc) + else: + raise ValueError("Unknown DSS mode '%s'" % mode) diff --git a/frozen_deps/Cryptodome/Signature/DSS.pyi b/frozen_deps/Cryptodome/Signature/DSS.pyi new file mode 100644 index 0000000..52ecc8f --- /dev/null +++ b/frozen_deps/Cryptodome/Signature/DSS.pyi @@ -0,0 +1,27 @@ +from typing import Union, Optional, Callable +from typing_extensions import Protocol + +from Cryptodome.PublicKey.DSA import DsaKey +from Cryptodome.PublicKey.ECC import EccKey + +class Hash(Protocol): + def digest(self) -> bytes: ... + +__all__ = ['new'] + +class DssSigScheme: + def __init__(self, key: Union[DsaKey, EccKey], encoding: str, order: int) -> None: ... + def can_sign(self) -> bool: ... + def sign(self, msg_hash: Hash) -> bytes: ... + def verify(self, msg_hash: Hash, signature: bytes) -> bool: ... + +class DeterministicDsaSigScheme(DssSigScheme): + def __init__(self, key, encoding, order, private_key) -> None: ... + +class FipsDsaSigScheme(DssSigScheme): + def __init__(self, key: DsaKey, encoding: str, order: int, randfunc: Callable) -> None: ... + +class FipsEcDsaSigScheme(DssSigScheme): + def __init__(self, key: EccKey, encoding: str, order: int, randfunc: Callable) -> None: ... + +def new(key: Union[DsaKey, EccKey], mode: str, encoding: Optional[str]='binary', randfunc: Optional[Callable]=None) -> Union[DeterministicDsaSigScheme, FipsDsaSigScheme, FipsEcDsaSigScheme]: ... diff --git a/frozen_deps/Cryptodome/Signature/PKCS1_PSS.py b/frozen_deps/Cryptodome/Signature/PKCS1_PSS.py new file mode 100644 index 0000000..1e7e5b5 --- /dev/null +++ b/frozen_deps/Cryptodome/Signature/PKCS1_PSS.py @@ -0,0 +1,55 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +""" +Legacy module for PKCS#1 PSS signatures. + +:undocumented: __package__ +""" + +import types + +from Cryptodome.Signature import pss + + +def _pycrypto_verify(self, hash_object, signature): + try: + self._verify(hash_object, signature) + except (ValueError, TypeError): + return False + return True + + +def new(rsa_key, mgfunc=None, saltLen=None, randfunc=None): + pkcs1 = pss.new(rsa_key, mask_func=mgfunc, + salt_bytes=saltLen, rand_func=randfunc) + pkcs1._verify = pkcs1.verify + pkcs1.verify = types.MethodType(_pycrypto_verify, pkcs1) + return pkcs1 diff --git a/frozen_deps/Cryptodome/Signature/PKCS1_PSS.pyi b/frozen_deps/Cryptodome/Signature/PKCS1_PSS.pyi new file mode 100644 index 0000000..7ed68e6 --- /dev/null +++ b/frozen_deps/Cryptodome/Signature/PKCS1_PSS.pyi @@ -0,0 +1,7 @@ +from typing import Optional, Callable + +from Cryptodome.PublicKey.RSA import RsaKey +from Cryptodome.Signature.pss import PSS_SigScheme + + +def new(rsa_key: RsaKey, mgfunc: Optional[Callable]=None, saltLen: Optional[int]=None, randfunc: Optional[Callable]=None) -> PSS_SigScheme: ... diff --git a/frozen_deps/Cryptodome/Signature/PKCS1_v1_5.py b/frozen_deps/Cryptodome/Signature/PKCS1_v1_5.py new file mode 100644 index 0000000..d560663 --- /dev/null +++ b/frozen_deps/Cryptodome/Signature/PKCS1_v1_5.py @@ -0,0 +1,53 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +""" +Legacy module for PKCS#1 v1.5 signatures. + +:undocumented: __package__ +""" + +import types + +from Cryptodome.Signature import pkcs1_15 + +def _pycrypto_verify(self, hash_object, signature): + try: + self._verify(hash_object, signature) + except (ValueError, TypeError): + return False + return True + +def new(rsa_key): + pkcs1 = pkcs1_15.new(rsa_key) + pkcs1._verify = pkcs1.verify + pkcs1.verify = types.MethodType(_pycrypto_verify, pkcs1) + return pkcs1 + diff --git a/frozen_deps/Cryptodome/Signature/PKCS1_v1_5.pyi b/frozen_deps/Cryptodome/Signature/PKCS1_v1_5.pyi new file mode 100644 index 0000000..5851e5b --- /dev/null +++ b/frozen_deps/Cryptodome/Signature/PKCS1_v1_5.pyi @@ -0,0 +1,6 @@ +from Cryptodome.PublicKey.RSA import RsaKey + +from Cryptodome.Signature.pkcs1_15 import PKCS115_SigScheme + + +def new(rsa_key: RsaKey) -> PKCS115_SigScheme: ... \ No newline at end of file diff --git a/frozen_deps/Cryptodome/Signature/__init__.py b/frozen_deps/Cryptodome/Signature/__init__.py new file mode 100644 index 0000000..da028a5 --- /dev/null +++ b/frozen_deps/Cryptodome/Signature/__init__.py @@ -0,0 +1,36 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +"""Digital signature protocols + +A collection of standardized protocols to carry out digital signatures. +""" + +__all__ = ['PKCS1_v1_5', 'PKCS1_PSS', 'DSS', 'pkcs1_15', 'pss'] diff --git a/frozen_deps/Cryptodome/Signature/pkcs1_15.py b/frozen_deps/Cryptodome/Signature/pkcs1_15.py new file mode 100644 index 0000000..f572f85 --- /dev/null +++ b/frozen_deps/Cryptodome/Signature/pkcs1_15.py @@ -0,0 +1,222 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +import Cryptodome.Util.number +from Cryptodome.Util.number import ceil_div, bytes_to_long, long_to_bytes +from Cryptodome.Util.asn1 import DerSequence, DerNull, DerOctetString, DerObjectId + +class PKCS115_SigScheme: + """A signature object for ``RSASSA-PKCS1-v1_5``. + Do not instantiate directly. + Use :func:`Cryptodome.Signature.pkcs1_15.new`. + """ + + def __init__(self, rsa_key): + """Initialize this PKCS#1 v1.5 signature scheme object. + + :Parameters: + rsa_key : an RSA key object + Creation of signatures is only possible if this is a *private* + RSA key. Verification of signatures is always possible. + """ + self._key = rsa_key + + def can_sign(self): + """Return ``True`` if this object can be used to sign messages.""" + return self._key.has_private() + + def sign(self, msg_hash): + """Create the PKCS#1 v1.5 signature of a message. + + This function is also called ``RSASSA-PKCS1-V1_5-SIGN`` and + it is specified in + `section 8.2.1 of RFC8017 `_. + + :parameter msg_hash: + This is an object from the :mod:`Cryptodome.Hash` package. + It has been used to digest the message to sign. + :type msg_hash: hash object + + :return: the signature encoded as a *byte string*. + :raise ValueError: if the RSA key is not long enough for the given hash algorithm. + :raise TypeError: if the RSA key has no private half. + """ + + # See 8.2.1 in RFC3447 + modBits = Cryptodome.Util.number.size(self._key.n) + k = ceil_div(modBits,8) # Convert from bits to bytes + + # Step 1 + em = _EMSA_PKCS1_V1_5_ENCODE(msg_hash, k) + # Step 2a (OS2IP) + em_int = bytes_to_long(em) + # Step 2b (RSASP1) + m_int = self._key._decrypt(em_int) + # Step 2c (I2OSP) + signature = long_to_bytes(m_int, k) + return signature + + def verify(self, msg_hash, signature): + """Check if the PKCS#1 v1.5 signature over a message is valid. + + This function is also called ``RSASSA-PKCS1-V1_5-VERIFY`` and + it is specified in + `section 8.2.2 of RFC8037 `_. + + :parameter msg_hash: + The hash that was carried out over the message. This is an object + belonging to the :mod:`Cryptodome.Hash` module. + :type parameter: hash object + + :parameter signature: + The signature that needs to be validated. + :type signature: byte string + + :raise ValueError: if the signature is not valid. + """ + + # See 8.2.2 in RFC3447 + modBits = Cryptodome.Util.number.size(self._key.n) + k = ceil_div(modBits, 8) # Convert from bits to bytes + + # Step 1 + if len(signature) != k: + raise ValueError("Invalid signature") + # Step 2a (O2SIP) + signature_int = bytes_to_long(signature) + # Step 2b (RSAVP1) + em_int = self._key._encrypt(signature_int) + # Step 2c (I2OSP) + em1 = long_to_bytes(em_int, k) + # Step 3 + try: + possible_em1 = [ _EMSA_PKCS1_V1_5_ENCODE(msg_hash, k, True) ] + # MD2/4/5 hashes always require NULL params in AlgorithmIdentifier. + # For all others, it is optional. + try: + algorithm_is_md = msg_hash.oid.startswith('1.2.840.113549.2.') + except AttributeError: + algorithm_is_md = False + if not algorithm_is_md: # MD2/MD4/MD5 + possible_em1.append(_EMSA_PKCS1_V1_5_ENCODE(msg_hash, k, False)) + except ValueError: + raise ValueError("Invalid signature") + # 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). + # + if em1 not in possible_em1: + raise ValueError("Invalid signature") + pass + + +def _EMSA_PKCS1_V1_5_ENCODE(msg_hash, emLen, with_hash_parameters=True): + """ + 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: + msg_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. + with_hash_parameters : bool + If True (default), include NULL parameters for the hash + algorithm in the ``digestAlgorithm`` SEQUENCE. + + :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. + + :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 } + # } + # + # Appendix B.1 also says that for SHA-1/-2 algorithms, the parameters + # should be omitted. They may be present, but when they are, they shall + # have NULL value. + + digestAlgo = DerSequence([ DerObjectId(msg_hash.oid).encode() ]) + + if with_hash_parameters: + digestAlgo.append(DerNull().encode()) + + digest = DerOctetString(msg_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 emLen bytes: ... + +class PKCS115_SigScheme: + def __init__(self, rsa_key: RsaKey) -> None: ... + def can_sign(self) -> bool: ... + def sign(self, msg_hash: Hash) -> bytes: ... + def verify(self, msg_hash: Hash, signature: bytes) -> None: ... + +def _EMSA_PKCS1_V1_5_ENCODE(msg_hash: Hash, emLen: int, with_hash_parameters: Optional[bool]=True) -> bytes: ... + +def new(rsa_key: RsaKey) -> PKCS115_SigScheme: ... diff --git a/frozen_deps/Cryptodome/Signature/pss.py b/frozen_deps/Cryptodome/Signature/pss.py new file mode 100644 index 0000000..0b05ed2 --- /dev/null +++ b/frozen_deps/Cryptodome/Signature/pss.py @@ -0,0 +1,386 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Util.py3compat import bchr, bord, iter_range +import Cryptodome.Util.number +from Cryptodome.Util.number import (ceil_div, + long_to_bytes, + bytes_to_long + ) +from Cryptodome.Util.strxor import strxor +from Cryptodome import Random + + +class PSS_SigScheme: + """A signature object for ``RSASSA-PSS``. + Do not instantiate directly. + Use :func:`Cryptodome.Signature.pss.new`. + """ + + def __init__(self, key, mgfunc, saltLen, randfunc): + """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 : integer + Length of the salt, in bytes. + randfunc : callable + A function that returns random bytes. + """ + + self._key = key + self._saltLen = saltLen + self._mgfunc = mgfunc + self._randfunc = randfunc + + def can_sign(self): + """Return ``True`` if this object can be used to sign messages.""" + return self._key.has_private() + + def sign(self, msg_hash): + """Create the PKCS#1 PSS signature of a message. + + This function is also called ``RSASSA-PSS-SIGN`` and + it is specified in + `section 8.1.1 of RFC8017 `_. + + :parameter msg_hash: + This is an object from the :mod:`Cryptodome.Hash` package. + It has been used to digest the message to sign. + :type msg_hash: hash object + + :return: the signature encoded as a *byte string*. + :raise ValueError: if the RSA key is not long enough for the given hash algorithm. + :raise TypeError: if the RSA key has no private half. + """ + + # Set defaults for salt length and mask generation function + if self._saltLen is None: + sLen = msg_hash.digest_size + else: + sLen = self._saltLen + + if self._mgfunc is None: + mgf = lambda x, y: MGF1(x, y, msg_hash) + else: + mgf = self._mgfunc + + modBits = Cryptodome.Util.number.size(self._key.n) + + # See 8.1.1 in RFC3447 + k = ceil_div(modBits, 8) # k is length in bytes of the modulus + # Step 1 + em = _EMSA_PSS_ENCODE(msg_hash, modBits-1, self._randfunc, mgf, sLen) + # Step 2a (OS2IP) + em_int = bytes_to_long(em) + # Step 2b (RSASP1) + m_int = self._key._decrypt(em_int) + # Step 2c (I2OSP) + signature = long_to_bytes(m_int, k) + return signature + + def verify(self, msg_hash, signature): + """Check if the PKCS#1 PSS signature over a message is valid. + + This function is also called ``RSASSA-PSS-VERIFY`` and + it is specified in + `section 8.1.2 of RFC8037 `_. + + :parameter msg_hash: + The hash that was carried out over the message. This is an object + belonging to the :mod:`Cryptodome.Hash` module. + :type parameter: hash object + + :parameter signature: + The signature that needs to be validated. + :type signature: bytes + + :raise ValueError: if the signature is not valid. + """ + + # Set defaults for salt length and mask generation function + if self._saltLen is None: + sLen = msg_hash.digest_size + else: + sLen = self._saltLen + if self._mgfunc: + mgf = self._mgfunc + else: + mgf = lambda x, y: MGF1(x, y, msg_hash) + + modBits = Cryptodome.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(signature) != k: + raise ValueError("Incorrect signature") + # Step 2a (O2SIP) + signature_int = bytes_to_long(signature) + # Step 2b (RSAVP1) + em_int = self._key._encrypt(signature_int) + # Step 2c (I2OSP) + emLen = ceil_div(modBits - 1, 8) + em = long_to_bytes(em_int, emLen) + # Step 3/4 + _EMSA_PSS_VERIFY(msg_hash, em, modBits-1, mgf, sLen) + + +def MGF1(mgfSeed, maskLen, hash_gen): + """Mask Generation Function, described in `B.2.1 of RFC8017 + `_. + + :param mfgSeed: + seed from which the mask is generated + :type mfgSeed: byte string + + :param maskLen: + intended length in bytes of the mask + :type maskLen: integer + + :param hash_gen: + A module or a hash object from :mod:`Cryptodome.Hash` + :type hash_object: + + :return: the mask, as a *byte string* + """ + + T = b"" + for counter in iter_range(ceil_div(maskLen, hash_gen.digest_size)): + c = long_to_bytes(counter, 4) + hobj = hash_gen.new() + hobj.update(mgfSeed + c) + T = T + hobj.digest() + assert(len(T) >= maskLen) + return T[:maskLen] + + +def _EMSA_PSS_ENCODE(mhash, emBits, randFunc, mgf, sLen): + r""" + 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 iter_range(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 = randFunc(sLen) + # Step 5 + m_prime = bchr(0)*8 + mhash.digest() + salt + # Step 6 + h = mhash.new() + h.update(m_prime) + # Step 7 + ps = bchr(0)*(emLen-sLen-mhash.digest_size-2) + # Step 8 + db = ps + bchr(1) + 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. + + :Raise ValueError: + When the encoding is inconsistent, or the digest or salt lengths + are too big. + """ + + emLen = ceil_div(emBits, 8) + + # Bitmask of digits that fill up + lmask = 0 + for i in iter_range(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("Incorrect signature") + # Step 4 + if ord(em[-1:]) != 0xBC: + raise ValueError("Incorrect signature") + # Step 5 + maskedDB = em[:emLen-mhash.digest_size-1] + h = em[emLen-mhash.digest_size-1:-1] + # Step 6 + if lmask & bord(em[0]): + raise ValueError("Incorrect signature") + # 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(0)*(emLen-mhash.digest_size-sLen-2) + bchr(1)): + raise ValueError("Incorrect signature") + # Step 11 + if sLen > 0: + salt = db[-sLen:] + else: + salt = b"" + # Step 12 + m_prime = bchr(0)*8 + mhash.digest() + salt + # Step 13 + hobj = mhash.new() + hobj.update(m_prime) + hp = hobj.digest() + # Step 14 + if h != hp: + raise ValueError("Incorrect signature") + + +def new(rsa_key, **kwargs): + """Create an object for making or verifying PKCS#1 PSS signatures. + + :parameter rsa_key: + The RSA key to use for signing or verifying the message. + This is a :class:`Cryptodome.PublicKey.RSA` object. + Signing is only possible when ``rsa_key`` is a **private** RSA key. + :type rsa_key: RSA object + + :Keyword Arguments: + + * *mask_func* (``callable``) -- + A function that returns the mask (as `bytes`). + It must accept two parameters: a seed (as `bytes`) + and the length of the data to return. + + If not specified, it will be the function :func:`MGF1` defined in + `RFC8017 `_ and + combined with the same hash algorithm applied to the + message to sign or verify. + + If you want to use a different function, for instance still :func:`MGF1` + but together with another hash, you can do:: + + from Cryptodome.Hash import SHA256 + from Cryptodome.Signature.pss import MGF1 + mgf = lambda x, y: MGF1(x, y, SHA256) + + * *salt_bytes* (``integer``) -- + Length of the salt, in bytes. + It is a value between 0 and ``emLen - hLen - 2``, where ``emLen`` + is the size of the RSA modulus and ``hLen`` is the size of the digest + applied to the message to sign or verify. + + The salt is generated internally, you don't need to provide it. + + If not specified, the salt length will be ``hLen``. + If it is zero, the signature scheme becomes deterministic. + + Note that in some implementations such as OpenSSL the default + salt length is ``emLen - hLen - 2`` (even though it is not more + secure than ``hLen``). + + * *rand_func* (``callable``) -- + A function that returns random ``bytes``, of the desired length. + The default is :func:`Cryptodome.Random.get_random_bytes`. + + :return: a :class:`PSS_SigScheme` signature object + """ + + mask_func = kwargs.pop("mask_func", None) + salt_len = kwargs.pop("salt_bytes", None) + rand_func = kwargs.pop("rand_func", None) + if rand_func is None: + rand_func = Random.get_random_bytes + if kwargs: + raise ValueError("Unknown keywords: " + str(kwargs.keys())) + return PSS_SigScheme(rsa_key, mask_func, salt_len, rand_func) diff --git a/frozen_deps/Cryptodome/Signature/pss.pyi b/frozen_deps/Cryptodome/Signature/pss.pyi new file mode 100644 index 0000000..9ca19ea --- /dev/null +++ b/frozen_deps/Cryptodome/Signature/pss.pyi @@ -0,0 +1,30 @@ +from typing import Union, Callable, Optional +from typing_extensions import Protocol + +from Cryptodome.PublicKey.RSA import RsaKey + + +class Hash(Protocol): + def digest(self) -> bytes: ... + def update(self, bytes) -> None: ... + + +class HashModule(Protocol): + @staticmethod + def new(data: Optional[bytes]) -> Hash: ... + + +MaskFunction = Callable[[bytes, int, Union[Hash, HashModule]], bytes] +RndFunction = Callable[[int], bytes] + +class PSS_SigScheme: + def __init__(self, key: RsaKey, mgfunc: RndFunction, saltLen: int, randfunc: RndFunction) -> None: ... + def can_sign(self) -> bool: ... + def sign(self, msg_hash: Hash) -> bytes: ... + def verify(self, msg_hash: Hash, signature: bytes) -> None: ... + + +MGF1 : MaskFunction +def _EMSA_PSS_ENCODE(mhash: Hash, emBits: int, randFunc: RndFunction, mgf:MaskFunction, sLen: int) -> str: ... +def _EMSA_PSS_VERIFY(mhash: Hash, em: str, emBits: int, mgf: MaskFunction, sLen: int) -> None: ... +def new(rsa_key: RsaKey, **kwargs: Union[MaskFunction, RndFunction, int]) -> PSS_SigScheme: ... diff --git a/frozen_deps/Cryptodome/Util/Counter.py b/frozen_deps/Cryptodome/Util/Counter.py new file mode 100644 index 0000000..423f91f --- /dev/null +++ b/frozen_deps/Cryptodome/Util/Counter.py @@ -0,0 +1,70 @@ +# -*- coding: ascii -*- +# +# Util/Counter.py : Fast counter for use with CTR-mode ciphers +# +# 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. +# =================================================================== + +def new(nbits, prefix=b"", suffix=b"", initial_value=1, little_endian=False, allow_wraparound=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 1 at each call. + + Args: + nbits (integer): + Length of the desired counter value, 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): + This parameter is ignored. + Returns: + An object that can be passed with the :data:`counter` parameter to a CTR mode + cipher. + + It must hold that *len(prefix) + nbits//8 + len(suffix)* matches the + block size of the underlying block cipher. + """ + + if (nbits % 8) != 0: + raise ValueError("'nbits' must be a multiple of 8") + + # Ignore wraparound + return {"counter_len": nbits // 8, + "prefix": prefix, + "suffix": suffix, + "initial_value": initial_value, + "little_endian": little_endian + } diff --git a/frozen_deps/Cryptodome/Util/Counter.pyi b/frozen_deps/Cryptodome/Util/Counter.pyi new file mode 100644 index 0000000..fa2ffdd --- /dev/null +++ b/frozen_deps/Cryptodome/Util/Counter.pyi @@ -0,0 +1,5 @@ +from typing import Optional, Union, Dict + +def new(nbits: int, prefix: Optional[bytes]=..., suffix: Optional[bytes]=..., initial_value: Optional[int]=1, + little_endian: Optional[bool]=False, allow_wraparound: Optional[bool]=False) -> \ + Dict[str, Union[int, bytes, bool]]: ... diff --git a/frozen_deps/Cryptodome/Util/Padding.py b/frozen_deps/Cryptodome/Util/Padding.py new file mode 100644 index 0000000..1c353d1 --- /dev/null +++ b/frozen_deps/Cryptodome/Util/Padding.py @@ -0,0 +1,106 @@ +# +# Util/Padding.py : Functions to manage padding +# +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +__all__ = [ 'pad', 'unpad' ] + +from Cryptodome.Util.py3compat import * + + +def pad(data_to_pad, block_size, style='pkcs7'): + """Apply standard padding. + + Args: + data_to_pad (byte string): + The data that needs to be padded. + block_size (integer): + The block boundary to use for padding. The output length is guaranteed + to be a multiple of :data:`block_size`. + style (string): + Padding algorithm. It can be *'pkcs7'* (default), *'iso7816'* or *'x923'*. + + Return: + byte string : the original data with the appropriate padding added at the end. + """ + + padding_len = block_size-len(data_to_pad)%block_size + if style == 'pkcs7': + padding = bchr(padding_len)*padding_len + elif style == 'x923': + padding = bchr(0)*(padding_len-1) + bchr(padding_len) + elif style == 'iso7816': + padding = bchr(128) + bchr(0)*(padding_len-1) + else: + raise ValueError("Unknown padding style") + return data_to_pad + padding + + +def unpad(padded_data, block_size, style='pkcs7'): + """Remove standard padding. + + Args: + padded_data (byte string): + A piece of data with padding that needs to be stripped. + block_size (integer): + The block boundary to use for padding. The input length + must be a multiple of :data:`block_size`. + style (string): + Padding algorithm. It can be *'pkcs7'* (default), *'iso7816'* or *'x923'*. + Return: + byte string : data without padding. + Raises: + ValueError: if the padding is incorrect. + """ + + pdata_len = len(padded_data) + if pdata_len % block_size: + raise ValueError("Input data is not padded") + if style in ('pkcs7', 'x923'): + padding_len = bord(padded_data[-1]) + if padding_len<1 or padding_len>min(block_size, pdata_len): + raise ValueError("Padding is incorrect.") + if style == 'pkcs7': + if padded_data[-padding_len:]!=bchr(padding_len)*padding_len: + raise ValueError("PKCS#7 padding is incorrect.") + else: + if padded_data[-padding_len:-1]!=bchr(0)*(padding_len-1): + raise ValueError("ANSI X.923 padding is incorrect.") + elif style == 'iso7816': + padding_len = pdata_len - padded_data.rfind(bchr(128)) + if padding_len<1 or padding_len>min(block_size, pdata_len): + raise ValueError("Padding is incorrect.") + if padding_len>1 and padded_data[1-padding_len:]!=bchr(0)*(padding_len-1): + raise ValueError("ISO 7816-4 padding is incorrect.") + else: + raise ValueError("Unknown padding style") + return padded_data[:-padding_len] + diff --git a/frozen_deps/Cryptodome/Util/Padding.pyi b/frozen_deps/Cryptodome/Util/Padding.pyi new file mode 100644 index 0000000..4d8d30d --- /dev/null +++ b/frozen_deps/Cryptodome/Util/Padding.pyi @@ -0,0 +1,6 @@ +from typing import Optional + +__all__ = [ 'pad', 'unpad' ] + +def pad(data_to_pad: bytes, block_size: int, style: Optional[str]='pkcs7') -> bytes: ... +def unpad(padded_data: bytes, block_size: int, style: Optional[str]='pkcs7') -> bytes: ... \ No newline at end of file diff --git a/frozen_deps/Cryptodome/Util/RFC1751.py b/frozen_deps/Cryptodome/Util/RFC1751.py new file mode 100644 index 0000000..10859c3 --- /dev/null +++ b/frozen_deps/Cryptodome/Util/RFC1751.py @@ -0,0 +1,386 @@ +# 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. +# =================================================================== + +from __future__ import print_function + +import binascii + +from Cryptodome.Util.py3compat import bord, bchr + +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.""" + + result = 0 + for y in key[start:start+length]: + result = result * 2 + ord(y) - 48 + return result + + +def key_to_english(key): + """Transform an arbitrary key into a string containing English words. + + Example:: + + >>> from Cryptodome.Util.RFC1751 import key_to_english + >>> key_to_english(b'66666666') + 'RAM LOIS GOAD CREW CARE HIT' + + Args: + key (byte string): + The key to convert. Its length must be a multiple of 8. + Return: + A string of English words. + """ + + if len(key) % 8 != 0: + raise ValueError('The length of the key 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.strip() + + +def english_to_key(s): + """Transform a string into a corresponding key. + + Example:: + + >>> from Cryptodome.Util.RFC1751 import english_to_key + >>> english_to_key('RAM LOIS GOAD CREW CARE HIT') + b'66666666' + + Args: + s (string): the string with the words separated by whitespace; + the number of words must be a multiple of 6. + Return: + A byte string. + """ + + 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 = b'' + for y in char: + subkey = subkey + bchr(y) + + # 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" ] diff --git a/frozen_deps/Cryptodome/Util/RFC1751.pyi b/frozen_deps/Cryptodome/Util/RFC1751.pyi new file mode 100644 index 0000000..6ad07ff --- /dev/null +++ b/frozen_deps/Cryptodome/Util/RFC1751.pyi @@ -0,0 +1,7 @@ +from typing import Dict, List + +binary: Dict[int, str] +wordlist: List[str] + +def key_to_english(key: bytes) -> str: ... +def english_to_key(s: str) -> bytes: ... diff --git a/frozen_deps/Cryptodome/Util/__init__.py b/frozen_deps/Cryptodome/Util/__init__.py new file mode 100644 index 0000000..1862b82 --- /dev/null +++ b/frozen_deps/Cryptodome/Util/__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. +# =================================================================== + +"""Miscellaneous modules + +Contains useful modules that don't belong into any of the +other Cryptodome.* subpackages. + +======================== ============================================= +Module Description +======================== ============================================= +`Cryptodome.Util.number` Number-theoretic functions (primality testing, etc.) +`Cryptodome.Util.Counter` Fast counter functions for CTR cipher modes. +`Cryptodome.Util.RFC1751` Converts between 128-bit keys and human-readable + strings of words. +`Cryptodome.Util.asn1` Minimal support for ASN.1 DER encoding +`Cryptodome.Util.Padding` Set of functions for adding and removing padding. +======================== ============================================= + +:undocumented: _galois, _number_new, cpuid, py3compat, _raw_api +""" + +__all__ = ['RFC1751', 'number', 'strxor', 'asn1', 'Counter', 'Padding'] + diff --git a/frozen_deps/Cryptodome/Util/_cpu_features.py b/frozen_deps/Cryptodome/Util/_cpu_features.py new file mode 100644 index 0000000..4794a02 --- /dev/null +++ b/frozen_deps/Cryptodome/Util/_cpu_features.py @@ -0,0 +1,46 @@ +# =================================================================== +# +# Copyright (c) 2018, Helder Eijs +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Util._raw_api import load_pycryptodome_raw_lib + + +_raw_cpuid_lib = load_pycryptodome_raw_lib("Cryptodome.Util._cpuid_c", + """ + int have_aes_ni(void); + int have_clmul(void); + """) + + +def have_aes_ni(): + return _raw_cpuid_lib.have_aes_ni() + + +def have_clmul(): + return _raw_cpuid_lib.have_clmul() diff --git a/frozen_deps/Cryptodome/Util/_cpu_features.pyi b/frozen_deps/Cryptodome/Util/_cpu_features.pyi new file mode 100644 index 0000000..10e669e --- /dev/null +++ b/frozen_deps/Cryptodome/Util/_cpu_features.pyi @@ -0,0 +1,2 @@ +def have_aes_ni() -> int: ... +def have_clmul() -> int: ... diff --git a/frozen_deps/Cryptodome/Util/_cpuid_c.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Util/_cpuid_c.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..a555959 Binary files /dev/null and b/frozen_deps/Cryptodome/Util/_cpuid_c.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Util/_file_system.py b/frozen_deps/Cryptodome/Util/_file_system.py new file mode 100644 index 0000000..282f0dc --- /dev/null +++ b/frozen_deps/Cryptodome/Util/_file_system.py @@ -0,0 +1,54 @@ +# =================================================================== +# +# Copyright (c) 2016, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +import os + + +def pycryptodome_filename(dir_comps, filename): + """Return the complete file name for the module + + dir_comps : list of string + The list of directory names in the PyCryptodome package. + The first element must be "Cryptodome". + + filename : string + The filename (inclusing extension) in the target directory. + """ + + if dir_comps[0] != "Cryptodome": + raise ValueError("Only available for modules under 'Cryptodome'") + + dir_comps = list(dir_comps[1:]) + [filename] + + util_lib, _ = os.path.split(os.path.abspath(__file__)) + root_lib = os.path.join(util_lib, "..") + + return os.path.join(root_lib, *dir_comps) + diff --git a/frozen_deps/Cryptodome/Util/_file_system.pyi b/frozen_deps/Cryptodome/Util/_file_system.pyi new file mode 100644 index 0000000..d54a126 --- /dev/null +++ b/frozen_deps/Cryptodome/Util/_file_system.pyi @@ -0,0 +1,4 @@ +from typing import List + + +def pycryptodome_filename(dir_comps: List[str], filename: str) -> str: ... \ No newline at end of file diff --git a/frozen_deps/Cryptodome/Util/_raw_api.py b/frozen_deps/Cryptodome/Util/_raw_api.py new file mode 100644 index 0000000..9423738 --- /dev/null +++ b/frozen_deps/Cryptodome/Util/_raw_api.py @@ -0,0 +1,327 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +import abc +import sys +from Cryptodome.Util.py3compat import byte_string +from Cryptodome.Util._file_system import pycryptodome_filename + +# +# List of file suffixes for Python extensions +# +if sys.version_info[0] < 3: + + import imp + extension_suffixes = [] + for ext, mod, typ in imp.get_suffixes(): + if typ == imp.C_EXTENSION: + extension_suffixes.append(ext) + +else: + + from importlib import machinery + extension_suffixes = machinery.EXTENSION_SUFFIXES + +# Which types with buffer interface we support (apart from byte strings) +if sys.version_info[0] == 2 and sys.version_info[1] < 7: + _buffer_type = (bytearray) +else: + _buffer_type = (bytearray, memoryview) + + +class _VoidPointer(object): + @abc.abstractmethod + def get(self): + """Return the memory location we point to""" + return + + @abc.abstractmethod + def address_of(self): + """Return a raw pointer to this pointer""" + return + + +try: + if sys.version_info[0] == 2 and sys.version_info[1] < 7: + raise ImportError("CFFI is only supported with Python 2.7+") + + # Starting from v2.18, pycparser (used by cffi for in-line ABI mode) + # stops working correctly when PYOPTIMIZE==2 or the parameter -OO is + # passed. In that case, we fall back to ctypes. + # Note that PyPy ships with an old version of pycparser so we can keep + # using cffi there. + # See https://github.com/Legrandin/pycryptodome/issues/228 + if '__pypy__' not in sys.builtin_module_names and sys.flags.optimize == 2: + raise ImportError("CFFI with optimize=2 fails due to pycparser bug.") + + from cffi import FFI + + ffi = FFI() + null_pointer = ffi.NULL + uint8_t_type = ffi.typeof(ffi.new("const uint8_t*")) + + _Array = ffi.new("uint8_t[1]").__class__.__bases__ + + def load_lib(name, cdecl): + """Load a shared library and return a handle to it. + + @name, either an absolute path or the name of a library + in the system search path. + + @cdecl, the C function declarations. + """ + + lib = ffi.dlopen(name) + ffi.cdef(cdecl) + return lib + + def c_ulong(x): + """Convert a Python integer to unsigned long""" + return x + + c_ulonglong = c_ulong + c_uint = c_ulong + + def c_size_t(x): + """Convert a Python integer to size_t""" + return x + + def create_string_buffer(init_or_size, size=None): + """Allocate the given amount of bytes (initially set to 0)""" + + if isinstance(init_or_size, bytes): + size = max(len(init_or_size) + 1, size) + result = ffi.new("uint8_t[]", size) + result[:] = init_or_size + else: + if size: + raise ValueError("Size must be specified once only") + result = ffi.new("uint8_t[]", init_or_size) + return result + + def get_c_string(c_string): + """Convert a C string into a Python byte sequence""" + return ffi.string(c_string) + + def get_raw_buffer(buf): + """Convert a C buffer into a Python byte sequence""" + return ffi.buffer(buf)[:] + + def c_uint8_ptr(data): + if isinstance(data, _buffer_type): + # This only works for cffi >= 1.7 + return ffi.cast(uint8_t_type, ffi.from_buffer(data)) + elif byte_string(data) or isinstance(data, _Array): + return data + else: + raise TypeError("Object type %s cannot be passed to C code" % type(data)) + + class VoidPointer_cffi(_VoidPointer): + """Model a newly allocated pointer to void""" + + def __init__(self): + self._pp = ffi.new("void *[1]") + + def get(self): + return self._pp[0] + + def address_of(self): + return self._pp + + def VoidPointer(): + return VoidPointer_cffi() + + backend = "cffi" + +except ImportError: + + import ctypes + from ctypes import (CDLL, c_void_p, byref, c_ulong, c_ulonglong, c_size_t, + create_string_buffer, c_ubyte, c_uint) + from ctypes.util import find_library + from ctypes import Array as _Array + + null_pointer = None + cached_architecture = [] + + def load_lib(name, cdecl): + if not cached_architecture: + # platform.architecture() creates a subprocess, so caching the + # result makes successive imports faster. + import platform + cached_architecture[:] = platform.architecture() + bits, linkage = cached_architecture + if "." not in name and not linkage.startswith("Win"): + full_name = find_library(name) + if full_name is None: + raise OSError("Cannot load library '%s'" % name) + name = full_name + return CDLL(name) + + def get_c_string(c_string): + return c_string.value + + def get_raw_buffer(buf): + return buf.raw + + # ---- Get raw pointer --- + + if sys.version_info[0] == 2 and sys.version_info[1] == 6: + # ctypes in 2.6 does not define c_ssize_t. Replacing it + # with c_size_t keeps the structure correctely laid out + _c_ssize_t = c_size_t + else: + _c_ssize_t = ctypes.c_ssize_t + + _PyBUF_SIMPLE = 0 + _PyObject_GetBuffer = ctypes.pythonapi.PyObject_GetBuffer + _PyBuffer_Release = ctypes.pythonapi.PyBuffer_Release + _py_object = ctypes.py_object + _c_ssize_p = ctypes.POINTER(_c_ssize_t) + + # See Include/object.h for CPython + # and https://github.com/pallets/click/blob/master/click/_winconsole.py + class _Py_buffer(ctypes.Structure): + _fields_ = [ + ('buf', c_void_p), + ('obj', ctypes.py_object), + ('len', _c_ssize_t), + ('itemsize', _c_ssize_t), + ('readonly', ctypes.c_int), + ('ndim', ctypes.c_int), + ('format', ctypes.c_char_p), + ('shape', _c_ssize_p), + ('strides', _c_ssize_p), + ('suboffsets', _c_ssize_p), + ('internal', c_void_p) + ] + + # Extra field for CPython 2.6/2.7 + if sys.version_info[0] == 2: + _fields_.insert(-1, ('smalltable', _c_ssize_t * 2)) + + def c_uint8_ptr(data): + if byte_string(data) or isinstance(data, _Array): + return data + elif isinstance(data, _buffer_type): + obj = _py_object(data) + buf = _Py_buffer() + _PyObject_GetBuffer(obj, byref(buf), _PyBUF_SIMPLE) + try: + buffer_type = c_ubyte * buf.len + return buffer_type.from_address(buf.buf) + finally: + _PyBuffer_Release(byref(buf)) + else: + raise TypeError("Object type %s cannot be passed to C code" % type(data)) + + # --- + + class VoidPointer_ctypes(_VoidPointer): + """Model a newly allocated pointer to void""" + + def __init__(self): + self._p = c_void_p() + + def get(self): + return self._p + + def address_of(self): + return byref(self._p) + + def VoidPointer(): + return VoidPointer_ctypes() + + backend = "ctypes" + del ctypes + + +class SmartPointer(object): + """Class to hold a non-managed piece of memory""" + + def __init__(self, raw_pointer, destructor): + self._raw_pointer = raw_pointer + self._destructor = destructor + + def get(self): + return self._raw_pointer + + def release(self): + rp, self._raw_pointer = self._raw_pointer, None + return rp + + def __del__(self): + try: + if self._raw_pointer is not None: + self._destructor(self._raw_pointer) + self._raw_pointer = None + except AttributeError: + pass + + +def load_pycryptodome_raw_lib(name, cdecl): + """Load a shared library and return a handle to it. + + @name, the name of the library expressed as a PyCryptodome module, + for instance Cryptodome.Cipher._raw_cbc. + + @cdecl, the C function declarations. + """ + + split = name.split(".") + dir_comps, basename = split[:-1], split[-1] + attempts = [] + for ext in extension_suffixes: + try: + filename = basename + ext + return load_lib(pycryptodome_filename(dir_comps, filename), + cdecl) + except OSError as exp: + attempts.append("Trying '%s': %s" % (filename, str(exp))) + raise OSError("Cannot load native module '%s': %s" % (name, ", ".join(attempts))) + + +if sys.version_info[:2] != (2, 6): + + def is_buffer(x): + """Return True if object x supports the buffer interface""" + return isinstance(x, (bytes, bytearray, memoryview)) + + def is_writeable_buffer(x): + return (isinstance(x, bytearray) or + (isinstance(x, memoryview) and not x.readonly)) + +else: + + def is_buffer(x): + return isinstance(x, (bytes, bytearray)) + + def is_writeable_buffer(x): + return isinstance(x, bytearray) diff --git a/frozen_deps/Cryptodome/Util/_raw_api.pyi b/frozen_deps/Cryptodome/Util/_raw_api.pyi new file mode 100644 index 0000000..2bc5301 --- /dev/null +++ b/frozen_deps/Cryptodome/Util/_raw_api.pyi @@ -0,0 +1,27 @@ +from typing import Any, Optional, Union + +def load_lib(name: str, cdecl: str) -> Any : ... +def c_ulong(x: int ) -> Any : ... +def c_ulonglong(x: int ) -> Any : ... +def c_size_t(x: int) -> Any : ... +def create_string_buffer(init_or_size: Union[bytes,int], size: Optional[int]) -> Any : ... +def get_c_string(c_string: Any) -> bytes : ... +def get_raw_buffer(buf: Any) -> bytes : ... +def c_uint8_ptr(data: Union[bytes, memoryview, bytearray]) -> Any : ... + +class VoidPointer(object): + def get(self) -> Any : ... + def address_of(self) -> Any : ... + +class SmartPointer(object): + def __init__(self, raw_pointer: Any, destructor: Any) -> None : ... + def get(self) -> Any : ... + def release(self) -> Any : ... + +backend : str +null_pointer : Any +ffi: Any + +def load_pycryptodome_raw_lib(name: str, cdecl: str) -> Any : ... +def is_buffer(x: Any) -> bool : ... +def is_writeable_buffer(x: Any) -> bool : ... diff --git a/frozen_deps/Cryptodome/Util/_strxor.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Util/_strxor.cpython-38-x86_64-linux-gnu.so new file mode 100755 index 0000000..ea7566c Binary files /dev/null and b/frozen_deps/Cryptodome/Util/_strxor.cpython-38-x86_64-linux-gnu.so differ diff --git a/frozen_deps/Cryptodome/Util/asn1.py b/frozen_deps/Cryptodome/Util/asn1.py new file mode 100644 index 0000000..18e080c --- /dev/null +++ b/frozen_deps/Cryptodome/Util/asn1.py @@ -0,0 +1,940 @@ +# -*- 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. +# =================================================================== + +import struct + +from Cryptodome.Util.py3compat import byte_string, b, bchr, bord + +from Cryptodome.Util.number import long_to_bytes, bytes_to_long + +__all__ = ['DerObject', 'DerInteger', 'DerOctetString', 'DerNull', + 'DerSequence', 'DerObjectId', 'DerBitString', 'DerSetOf'] + + +def _is_number(x, only_non_negative=False): + test = 0 + try: + test = x + test + except TypeError: + return False + return not only_non_negative or x >= 0 + + +class BytesIO_EOF(object): + """This class differs from BytesIO in that a ValueError exception is + raised whenever EOF is reached.""" + + def __init__(self, initial_bytes): + self._buffer = initial_bytes + self._index = 0 + self._bookmark = None + + def set_bookmark(self): + self._bookmark = self._index + + def data_since_bookmark(self): + assert self._bookmark is not None + return self._buffer[self._bookmark:self._index] + + def remaining_data(self): + return len(self._buffer) - self._index + + def read(self, length): + new_index = self._index + length + if new_index > len(self._buffer): + raise ValueError("Not enough data for DER decoding: expected %d bytes and found %d" % (new_index, len(self._buffer))) + + result = self._buffer[self._index:new_index] + self._index = new_index + return result + + def read_byte(self): + return bord(self.read(1)[0]) + + +class DerObject(object): + """Base class for defining a single DER object. + + This class should never be directly instantiated. + """ + + def __init__(self, asn1Id=None, payload=b'', implicit=None, + constructed=False, explicit=None): + """Initialize the DER object according to a specific ASN.1 type. + + :Parameters: + asn1Id : integer + The universal DER tag number for this object + (e.g. 0x10 for a SEQUENCE). + If None, the tag is not known yet. + + payload : byte string + The initial payload of the object (that it, + the content octets). + If not specified, the payload is empty. + + implicit : integer + The IMPLICIT tag number to use for the encoded object. + It overrides the universal tag *asn1Id*. + + constructed : bool + True when the ASN.1 type is *constructed*. + False when it is *primitive*. + + explicit : integer + The EXPLICIT tag number to use for the encoded object. + """ + + if asn1Id is None: + # The tag octet will be read in with ``decode`` + self._tag_octet = None + return + asn1Id = self._convertTag(asn1Id) + + self.payload = payload + + # In a BER/DER identifier octet: + # * bits 4-0 contain the tag value + # * bit 5 is set if the type is 'constructed' + # and unset if 'primitive' + # * bits 7-6 depend on the encoding class + # + # Class | Bit 7, Bit 6 + # ---------------------------------- + # universal | 0 0 + # application | 0 1 + # context-spec | 1 0 (default for IMPLICIT/EXPLICIT) + # private | 1 1 + # + if None not in (explicit, implicit): + raise ValueError("Explicit and implicit tags are" + " mutually exclusive") + + if implicit is not None: + self._tag_octet = 0x80 | 0x20 * constructed | self._convertTag(implicit) + return + + if explicit is not None: + self._tag_octet = 0xA0 | self._convertTag(explicit) + self._inner_tag_octet = 0x20 * constructed | asn1Id + return + + self._tag_octet = 0x20 * constructed | asn1Id + + def _convertTag(self, tag): + """Check if *tag* is a real DER tag. + Convert it from a character to number if necessary. + """ + if not _is_number(tag): + if len(tag) == 1: + tag = bord(tag[0]) + # Ensure that tag is a low tag + if not (_is_number(tag) and 0 <= tag < 0x1F): + raise ValueError("Wrong DER tag") + return tag + + @staticmethod + def _definite_form(length): + """Build length octets according to BER/DER + definite form. + """ + if length > 127: + encoding = long_to_bytes(length) + return bchr(len(encoding) + 128) + encoding + return bchr(length) + + def encode(self): + """Return this DER element, fully encoded as a binary byte string.""" + + # Concatenate identifier octets, length octets, + # and contents octets + + output_payload = self.payload + + # In case of an EXTERNAL tag, first encode the inner + # element. + if hasattr(self, "_inner_tag_octet"): + output_payload = (bchr(self._inner_tag_octet) + + self._definite_form(len(self.payload)) + + self.payload) + + return (bchr(self._tag_octet) + + self._definite_form(len(output_payload)) + + output_payload) + + def _decodeLen(self, s): + """Decode DER length octets from a file.""" + + length = s.read_byte() + + if length > 127: + encoded_length = s.read(length & 0x7F) + if bord(encoded_length[0]) == 0: + raise ValueError("Invalid DER: length has leading zero") + length = bytes_to_long(encoded_length) + if length <= 127: + raise ValueError("Invalid DER: length in long form but smaller than 128") + + return length + + def decode(self, der_encoded, strict=False): + """Decode a complete DER element, and re-initializes this + object with it. + + Args: + der_encoded (byte string): A complete DER element. + + Raises: + ValueError: in case of parsing errors. + """ + + if not byte_string(der_encoded): + raise ValueError("Input is not a byte string") + + s = BytesIO_EOF(der_encoded) + self._decodeFromStream(s, strict) + + # There shouldn't be other bytes left + if s.remaining_data() > 0: + raise ValueError("Unexpected extra data after the DER structure") + + return self + + def _decodeFromStream(self, s, strict): + """Decode a complete DER element from a file.""" + + idOctet = s.read_byte() + if self._tag_octet is not None: + if idOctet != self._tag_octet: + raise ValueError("Unexpected DER tag") + else: + self._tag_octet = idOctet + length = self._decodeLen(s) + self.payload = s.read(length) + + # In case of an EXTERNAL tag, further decode the inner + # element. + if hasattr(self, "_inner_tag_octet"): + p = BytesIO_EOF(self.payload) + inner_octet = p.read_byte() + if inner_octet != self._inner_tag_octet: + raise ValueError("Unexpected internal DER tag") + length = self._decodeLen(p) + self.payload = p.read(length) + + # There shouldn't be other bytes left + if p.remaining_data() > 0: + raise ValueError("Unexpected extra data after the DER structure") + + +class DerInteger(DerObject): + """Class to model a DER INTEGER. + + An example of encoding is:: + + >>> from Cryptodome.Util.asn1 import DerInteger + >>> from binascii import hexlify, unhexlify + >>> int_der = DerInteger(9) + >>> print hexlify(int_der.encode()) + + which will show ``020109``, the DER encoding of 9. + + And for decoding:: + + >>> s = unhexlify(b'020109') + >>> try: + >>> int_der = DerInteger() + >>> int_der.decode(s) + >>> print int_der.value + >>> except ValueError: + >>> print "Not a valid DER INTEGER" + + the output will be ``9``. + + :ivar value: The integer value + :vartype value: integer + """ + + def __init__(self, value=0, implicit=None, explicit=None): + """Initialize the DER object as an INTEGER. + + :Parameters: + value : integer + The value of the integer. + + implicit : integer + The IMPLICIT tag to use for the encoded object. + It overrides the universal tag for INTEGER (2). + """ + + DerObject.__init__(self, 0x02, b'', implicit, + False, explicit) + self.value = value # The integer value + + def encode(self): + """Return the DER INTEGER, fully encoded as a + binary string.""" + + number = self.value + self.payload = b'' + while True: + self.payload = bchr(int(number & 255)) + self.payload + if 128 <= number <= 255: + self.payload = bchr(0x00) + self.payload + if -128 <= number <= 255: + break + number >>= 8 + return DerObject.encode(self) + + def decode(self, der_encoded, strict=False): + """Decode a complete DER INTEGER DER, and re-initializes this + object with it. + + Args: + der_encoded (byte string): A complete INTEGER DER element. + + Raises: + ValueError: in case of parsing errors. + """ + + return DerObject.decode(self, der_encoded, strict=strict) + + def _decodeFromStream(self, s, strict): + """Decode a complete DER INTEGER from a file.""" + + # Fill up self.payload + DerObject._decodeFromStream(self, s, strict) + + if strict: + if len(self.payload) == 0: + raise ValueError("Invalid encoding for DER INTEGER: empty payload") + if len(self.payload) >= 2 and struct.unpack('>H', self.payload[:2])[0] < 0x80: + raise ValueError("Invalid encoding for DER INTEGER: leading zero") + + # Derive self.value from self.payload + self.value = 0 + bits = 1 + for i in self.payload: + self.value *= 256 + self.value += bord(i) + bits <<= 8 + if self.payload and bord(self.payload[0]) & 0x80: + self.value -= bits + + +class DerSequence(DerObject): + """Class to model a DER SEQUENCE. + + This object behaves like a dynamic Python sequence. + + Sub-elements that are INTEGERs behave like Python integers. + + Any other sub-element is a binary string encoded as a complete DER + sub-element (TLV). + + An example of encoding is: + + >>> from Cryptodome.Util.asn1 import DerSequence, DerInteger + >>> from binascii import hexlify, unhexlify + >>> obj_der = unhexlify('070102') + >>> seq_der = DerSequence([4]) + >>> seq_der.append(9) + >>> seq_der.append(obj_der.encode()) + >>> print hexlify(seq_der.encode()) + + which will show ``3009020104020109070102``, the DER encoding of the + sequence containing ``4``, ``9``, and the object with payload ``02``. + + For decoding: + + >>> s = unhexlify(b'3009020104020109070102') + >>> try: + >>> seq_der = DerSequence() + >>> seq_der.decode(s) + >>> print len(seq_der) + >>> print seq_der[0] + >>> print seq_der[:] + >>> except ValueError: + >>> print "Not a valid DER SEQUENCE" + + the output will be:: + + 3 + 4 + [4, 9, b'\x07\x01\x02'] + + """ + + def __init__(self, startSeq=None, implicit=None): + """Initialize the DER object as a SEQUENCE. + + :Parameters: + startSeq : Python sequence + A sequence whose element are either integers or + other DER objects. + + implicit : integer + The IMPLICIT tag to use for the encoded object. + It overrides the universal tag for SEQUENCE (16). + """ + + DerObject.__init__(self, 0x10, b'', implicit, True) + if startSeq is 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 __iadd__(self, item): + self._seq.append(item) + return self + + def append(self, item): + self._seq.append(item) + return self + + def hasInts(self, only_non_negative=True): + """Return the number of items in this sequence that are + integers. + + Args: + only_non_negative (boolean): + If ``True``, negative integers are not counted in. + """ + + items = [x for x in self._seq if _is_number(x, only_non_negative)] + return len(items) + + def hasOnlyInts(self, only_non_negative=True): + """Return ``True`` if all items in this sequence are integers + or non-negative integers. + + This function returns False is the sequence is empty, + or at least one member is not an integer. + + Args: + only_non_negative (boolean): + If ``True``, the presence of negative integers + causes the method to return ``False``.""" + return self._seq and self.hasInts(only_non_negative) == len(self._seq) + + def encode(self): + """Return this DER SEQUENCE, fully encoded as a + binary string. + + Raises: + ValueError: if some elements in the sequence are neither integers + nor byte strings. + """ + self.payload = b'' + for item in self._seq: + if byte_string(item): + self.payload += item + elif _is_number(item): + self.payload += DerInteger(item).encode() + else: + self.payload += item.encode() + return DerObject.encode(self) + + def decode(self, der_encoded, strict=False, nr_elements=None, only_ints_expected=False): + """Decode a complete DER SEQUENCE, and re-initializes this + object with it. + + Args: + der_encoded (byte string): + A complete SEQUENCE DER element. + nr_elements (None or integer or list of integers): + The number of members the SEQUENCE can have + only_ints_expected (boolean): + Whether the SEQUENCE is expected to contain only integers. + strict (boolean): + Whether decoding must check for strict DER compliancy. + + Raises: + ValueError: in case of parsing errors. + + DER INTEGERs are decoded into Python integers. Any other DER + element is not decoded. Its validity is not checked. + """ + + self._nr_elements = nr_elements + result = DerObject.decode(self, der_encoded, strict=strict) + + if only_ints_expected and not self.hasOnlyInts(): + raise ValueError("Some members are not INTEGERs") + + return result + + def _decodeFromStream(self, s, strict): + """Decode a complete DER SEQUENCE from a file.""" + + self._seq = [] + + # Fill up self.payload + DerObject._decodeFromStream(self, s, strict) + + # Add one item at a time to self.seq, by scanning self.payload + p = BytesIO_EOF(self.payload) + while p.remaining_data() > 0: + p.set_bookmark() + + der = DerObject() + der._decodeFromStream(p, strict) + + # Parse INTEGERs differently + if der._tag_octet != 0x02: + self._seq.append(p.data_since_bookmark()) + else: + derInt = DerInteger() + #import pdb; pdb.set_trace() + data = p.data_since_bookmark() + derInt.decode(data, strict=strict) + self._seq.append(derInt.value) + + ok = True + if self._nr_elements is not None: + try: + ok = len(self._seq) in self._nr_elements + except TypeError: + ok = len(self._seq) == self._nr_elements + + if not ok: + raise ValueError("Unexpected number of members (%d)" + " in the sequence" % len(self._seq)) + + +class DerOctetString(DerObject): + """Class to model a DER OCTET STRING. + + An example of encoding is: + + >>> from Cryptodome.Util.asn1 import DerOctetString + >>> from binascii import hexlify, unhexlify + >>> os_der = DerOctetString(b'\\xaa') + >>> os_der.payload += b'\\xbb' + >>> print hexlify(os_der.encode()) + + which will show ``0402aabb``, the DER encoding for the byte string + ``b'\\xAA\\xBB'``. + + For decoding: + + >>> s = unhexlify(b'0402aabb') + >>> try: + >>> os_der = DerOctetString() + >>> os_der.decode(s) + >>> print hexlify(os_der.payload) + >>> except ValueError: + >>> print "Not a valid DER OCTET STRING" + + the output will be ``aabb``. + + :ivar payload: The content of the string + :vartype payload: byte string + """ + + def __init__(self, value=b'', implicit=None): + """Initialize the DER object as an OCTET STRING. + + :Parameters: + value : byte string + The initial payload of the object. + If not specified, the payload is empty. + + implicit : integer + The IMPLICIT tag to use for the encoded object. + It overrides the universal tag for OCTET STRING (4). + """ + DerObject.__init__(self, 0x04, value, implicit, False) + + +class DerNull(DerObject): + """Class to model a DER NULL element.""" + + def __init__(self): + """Initialize the DER object as a NULL.""" + + DerObject.__init__(self, 0x05, b'', None, False) + + +class DerObjectId(DerObject): + """Class to model a DER OBJECT ID. + + An example of encoding is: + + >>> from Cryptodome.Util.asn1 import DerObjectId + >>> from binascii import hexlify, unhexlify + >>> oid_der = DerObjectId("1.2") + >>> oid_der.value += ".840.113549.1.1.1" + >>> print hexlify(oid_der.encode()) + + which will show ``06092a864886f70d010101``, the DER encoding for the + RSA Object Identifier ``1.2.840.113549.1.1.1``. + + For decoding: + + >>> s = unhexlify(b'06092a864886f70d010101') + >>> try: + >>> oid_der = DerObjectId() + >>> oid_der.decode(s) + >>> print oid_der.value + >>> except ValueError: + >>> print "Not a valid DER OBJECT ID" + + the output will be ``1.2.840.113549.1.1.1``. + + :ivar value: The Object ID (OID), a dot separated list of integers + :vartype value: string + """ + + def __init__(self, value='', implicit=None, explicit=None): + """Initialize the DER object as an OBJECT ID. + + :Parameters: + value : string + The initial Object Identifier (e.g. "1.2.0.0.6.2"). + implicit : integer + The IMPLICIT tag to use for the encoded object. + It overrides the universal tag for OBJECT ID (6). + explicit : integer + The EXPLICIT tag to use for the encoded object. + """ + DerObject.__init__(self, 0x06, b'', implicit, False, explicit) + self.value = value + + def encode(self): + """Return the DER OBJECT ID, fully encoded as a + binary string.""" + + comps = [int(x) for x in self.value.split(".")] + if len(comps) < 2: + raise ValueError("Not a valid Object Identifier string") + self.payload = bchr(40*comps[0]+comps[1]) + for v in comps[2:]: + if v == 0: + enc = [0] + else: + enc = [] + while v: + enc.insert(0, (v & 0x7F) | 0x80) + v >>= 7 + enc[-1] &= 0x7F + self.payload += b''.join([bchr(x) for x in enc]) + return DerObject.encode(self) + + def decode(self, der_encoded, strict=False): + """Decode a complete DER OBJECT ID, and re-initializes this + object with it. + + Args: + der_encoded (byte string): + A complete DER OBJECT ID. + strict (boolean): + Whether decoding must check for strict DER compliancy. + + Raises: + ValueError: in case of parsing errors. + """ + + return DerObject.decode(self, der_encoded, strict) + + def _decodeFromStream(self, s, strict): + """Decode a complete DER OBJECT ID from a file.""" + + # Fill up self.payload + DerObject._decodeFromStream(self, s, strict) + + # Derive self.value from self.payload + p = BytesIO_EOF(self.payload) + comps = [str(x) for x in divmod(p.read_byte(), 40)] + v = 0 + while p.remaining_data(): + c = p.read_byte() + v = v*128 + (c & 0x7F) + if not (c & 0x80): + comps.append(str(v)) + v = 0 + self.value = '.'.join(comps) + + +class DerBitString(DerObject): + """Class to model a DER BIT STRING. + + An example of encoding is: + + >>> from Cryptodome.Util.asn1 import DerBitString + >>> from binascii import hexlify, unhexlify + >>> bs_der = DerBitString(b'\\xaa') + >>> bs_der.value += b'\\xbb' + >>> print hexlify(bs_der.encode()) + + which will show ``040300aabb``, the DER encoding for the bit string + ``b'\\xAA\\xBB'``. + + For decoding: + + >>> s = unhexlify(b'040300aabb') + >>> try: + >>> bs_der = DerBitString() + >>> bs_der.decode(s) + >>> print hexlify(bs_der.value) + >>> except ValueError: + >>> print "Not a valid DER BIT STRING" + + the output will be ``aabb``. + + :ivar value: The content of the string + :vartype value: byte string + """ + + def __init__(self, value=b'', implicit=None, explicit=None): + """Initialize the DER object as a BIT STRING. + + :Parameters: + value : byte string or DER object + The initial, packed bit string. + If not specified, the bit string is empty. + implicit : integer + The IMPLICIT tag to use for the encoded object. + It overrides the universal tag for OCTET STRING (3). + explicit : integer + The EXPLICIT tag to use for the encoded object. + """ + DerObject.__init__(self, 0x03, b'', implicit, False, explicit) + + # The bitstring value (packed) + if isinstance(value, DerObject): + self.value = value.encode() + else: + self.value = value + + def encode(self): + """Return the DER BIT STRING, fully encoded as a + binary string.""" + + # Add padding count byte + self.payload = b'\x00' + self.value + return DerObject.encode(self) + + def decode(self, der_encoded, strict=False): + """Decode a complete DER BIT STRING, and re-initializes this + object with it. + + Args: + der_encoded (byte string): a complete DER BIT STRING. + strict (boolean): + Whether decoding must check for strict DER compliancy. + + Raises: + ValueError: in case of parsing errors. + """ + + return DerObject.decode(self, der_encoded, strict) + + def _decodeFromStream(self, s, strict): + """Decode a complete DER BIT STRING DER from a file.""" + + # Fill-up self.payload + DerObject._decodeFromStream(self, s, strict) + + if self.payload and bord(self.payload[0]) != 0: + raise ValueError("Not a valid BIT STRING") + + # Fill-up self.value + self.value = b'' + # Remove padding count byte + if self.payload: + self.value = self.payload[1:] + + +class DerSetOf(DerObject): + """Class to model a DER SET OF. + + An example of encoding is: + + >>> from Cryptodome.Util.asn1 import DerBitString + >>> from binascii import hexlify, unhexlify + >>> so_der = DerSetOf([4,5]) + >>> so_der.add(6) + >>> print hexlify(so_der.encode()) + + which will show ``3109020104020105020106``, the DER encoding + of a SET OF with items 4,5, and 6. + + For decoding: + + >>> s = unhexlify(b'3109020104020105020106') + >>> try: + >>> so_der = DerSetOf() + >>> so_der.decode(s) + >>> print [x for x in so_der] + >>> except ValueError: + >>> print "Not a valid DER SET OF" + + the output will be ``[4, 5, 6]``. + """ + + def __init__(self, startSet=None, implicit=None): + """Initialize the DER object as a SET OF. + + :Parameters: + startSet : container + The initial set of integers or DER encoded objects. + implicit : integer + The IMPLICIT tag to use for the encoded object. + It overrides the universal tag for SET OF (17). + """ + DerObject.__init__(self, 0x11, b'', implicit, True) + self._seq = [] + + # All elements must be of the same type (and therefore have the + # same leading octet) + self._elemOctet = None + + if startSet: + for e in startSet: + self.add(e) + + def __getitem__(self, n): + return self._seq[n] + + def __iter__(self): + return iter(self._seq) + + def __len__(self): + return len(self._seq) + + def add(self, elem): + """Add an element to the set. + + Args: + elem (byte string or integer): + An element of the same type of objects already in the set. + It can be an integer or a DER encoded object. + """ + + if _is_number(elem): + eo = 0x02 + elif isinstance(elem, DerObject): + eo = self._tag_octet + else: + eo = bord(elem[0]) + + if self._elemOctet != eo: + if self._elemOctet is not None: + raise ValueError("New element does not belong to the set") + self._elemOctet = eo + + if elem not in self._seq: + self._seq.append(elem) + + def decode(self, der_encoded, strict=False): + """Decode a complete SET OF DER element, and re-initializes this + object with it. + + DER INTEGERs are decoded into Python integers. Any other DER + element is left undecoded; its validity is not checked. + + Args: + der_encoded (byte string): a complete DER BIT SET OF. + strict (boolean): + Whether decoding must check for strict DER compliancy. + + Raises: + ValueError: in case of parsing errors. + """ + + return DerObject.decode(self, der_encoded, strict) + + def _decodeFromStream(self, s, strict): + """Decode a complete DER SET OF from a file.""" + + self._seq = [] + + # Fill up self.payload + DerObject._decodeFromStream(self, s, strict) + + # Add one item at a time to self.seq, by scanning self.payload + p = BytesIO_EOF(self.payload) + setIdOctet = -1 + while p.remaining_data() > 0: + p.set_bookmark() + + der = DerObject() + der._decodeFromStream(p, strict) + + # Verify that all members are of the same type + if setIdOctet < 0: + setIdOctet = der._tag_octet + else: + if setIdOctet != der._tag_octet: + raise ValueError("Not all elements are of the same DER type") + + # Parse INTEGERs differently + if setIdOctet != 0x02: + self._seq.append(p.data_since_bookmark()) + else: + derInt = DerInteger() + derInt.decode(p.data_since_bookmark(), strict) + self._seq.append(derInt.value) + # end + + def encode(self): + """Return this SET OF DER element, fully encoded as a + binary string. + """ + + # Elements in the set must be ordered in lexicographic order + ordered = [] + for item in self._seq: + if _is_number(item): + bys = DerInteger(item).encode() + elif isinstance(item, DerObject): + bys = item.encode() + else: + bys = item + ordered.append(bys) + ordered.sort() + self.payload = b''.join(ordered) + return DerObject.encode(self) diff --git a/frozen_deps/Cryptodome/Util/asn1.pyi b/frozen_deps/Cryptodome/Util/asn1.pyi new file mode 100644 index 0000000..dac023b --- /dev/null +++ b/frozen_deps/Cryptodome/Util/asn1.pyi @@ -0,0 +1,74 @@ +from typing import Optional, Sequence, Union, Set, Iterable + +__all__ = ['DerObject', 'DerInteger', 'DerOctetString', 'DerNull', + 'DerSequence', 'DerObjectId', 'DerBitString', 'DerSetOf'] + +# TODO: Make the encoded DerObjects their own type, so that DerSequence and +# DerSetOf can check their contents better + +class BytesIO_EOF: + def __init__(self, initial_bytes: bytes) -> None: ... + def set_bookmark(self) -> None: ... + def data_since_bookmark(self) -> bytes: ... + def remaining_data(self) -> int: ... + def read(self, length: int) -> bytes: ... + def read_byte(self) -> bytes: ... + +class DerObject: + payload: bytes + def __init__(self, asn1Id: Optional[int]=None, payload: Optional[bytes]=..., implicit: Optional[int]=None, + constructed: Optional[bool]=False, explicit: Optional[int]=None) -> None: ... + def encode(self) -> bytes: ... + def decode(self, der_encoded: bytes, strict: Optional[bool]=False) -> DerObject: ... + +class DerInteger(DerObject): + value: int + def __init__(self, value: Optional[int]= 0, implicit: Optional[int]=None, explicit: Optional[int]=None) -> None: ... + def encode(self) -> bytes: ... + def decode(self, der_encoded: bytes, strict: Optional[bool]=False) -> DerInteger: ... + +class DerSequence(DerObject): + def __init__(self, startSeq: Optional[Sequence[Union[int, DerInteger, DerObject]]]=None, implicit: Optional[int]=None) -> None: ... + def __delitem__(self, n: int) -> None: ... + def __getitem__(self, n: int) -> None: ... + def __setitem__(self, key: int, value: DerObject) -> None: ... + def __setslice__(self, i: int, j: int, sequence: Sequence) -> None: ... + def __delslice__(self, i: int, j: int) -> None: ... + def __getslice__(self, i: int, j: int) -> DerSequence: ... + def __len__(self) -> int: ... + def __iadd__(self, item: DerObject) -> DerSequence: ... + def append(self, item: DerObject) -> DerSequence: ... + def hasInts(self, only_non_negative: Optional[bool]=True) -> int: ... + def hasOnlyInts(self, only_non_negative: Optional[bool]=True) -> bool: ... + def encode(self) -> bytes: ... + def decode(self, der_encoded: bytes, strict: Optional[bool]=False, nr_elements: Optional[int]=None, only_ints_expected: Optional[bool]=False) -> DerSequence: ... + +class DerOctetString(DerObject): + payload: bytes + def __init__(self, value: Optional[bytes]=..., implicit: Optional[int]=None) -> None: ... + +class DerNull(DerObject): + def __init__(self) -> None: ... + +class DerObjectId(DerObject): + value: str + def __init__(self, value: Optional[str]=..., implicit: Optional[int]=None, explicit: Optional[int]=None) -> None: ... + def encode(self) -> bytes: ... + def decode(self, der_encoded: bytes, strict: Optional[bool]=False) -> DerObjectId: ... + +class DerBitString(DerObject): + value: bytes + def __init__(self, value: Optional[bytes]=..., implicit: Optional[int]=None, explicit: Optional[int]=None) -> None: ... + def encode(self) -> bytes: ... + def decode(self, der_encoded: bytes, strict: Optional[bool]=False) -> DerBitString: ... + +DerSetElement = Union[bytes, int] + +class DerSetOf(DerObject): + def __init__(self, startSet: Optional[Set[DerSetElement]]=None, implicit: Optional[int]=None) -> None: ... + def __getitem__(self, n: int) -> DerSetElement: ... + def __iter__(self) -> Iterable: ... + def __len__(self) -> int: ... + def add(self, elem: DerSetElement) -> None: ... + def decode(self, der_encoded: bytes, strict: Optional[bool]=False) -> DerObject: ... + def encode(self) -> bytes: ... diff --git a/frozen_deps/Cryptodome/Util/number.py b/frozen_deps/Cryptodome/Util/number.py new file mode 100644 index 0000000..0367fdc --- /dev/null +++ b/frozen_deps/Cryptodome/Util/number.py @@ -0,0 +1,1469 @@ +# +# 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. +# =================================================================== +# + +import math +import sys +import struct +from Cryptodome import Random +from Cryptodome.Util.py3compat import _memoryview, iter_range + +# Backward compatibility +_fastmath = None + + +def ceil_div(n, d): + """Return ceil(n/d), that is, the smallest integer r such that r*d >= n""" + + if d == 0: + raise ZeroDivisionError() + if (n < 0) or (d < 0): + raise ValueError("Non positive values") + r, q = divmod(n, d) + if (n != 0) and (q != 0): + r += 1 + return r + + +def size (N): + """Returns the size of the number N in bits.""" + + if N < 0: + raise ValueError("Size in bits only avialable for non-negative numbers") + + bits = 0 + while N >> bits: + bits += 1 + return bits + + +def getRandomInteger(N, randfunc=None): + """Return a random number at most N bits long. + + If :data:`randfunc` is omitted, then :meth:`Random.get_random_bytes` is used. + + .. deprecated:: 3.0 + This function is for internal use only and may be renamed or removed in + the future. Use :func:`Cryptodome.Random.random.getrandbits` instead. + """ + + if randfunc is None: + randfunc = Random.get_random_bytes + + S = randfunc(N>>3) + odd_bits = N % 8 + if odd_bits != 0: + rand_bits = ord(randfunc(1)) >> (8-odd_bits) + S = struct.pack('B', rand_bits) + S + value = bytes_to_long(S) + return value + +def getRandomRange(a, b, randfunc=None): + """Return a random number *n* so that *a <= n < b*. + + If :data:`randfunc` is omitted, then :meth:`Random.get_random_bytes` is used. + + .. deprecated:: 3.0 + This function is for internal use only and may be renamed or removed in + the future. Use :func:`Cryptodome.Random.random.randrange` instead. + """ + + 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): + """Return a random number with exactly N-bits, + i.e. a random number between 2**(N-1) and (2**N)-1. + + If :data:`randfunc` is omitted, then :meth:`Random.get_random_bytes` is used. + + .. deprecated:: 3.0 + This function is for internal use only and may be renamed or removed in + the future. + """ + + value = getRandomInteger (N-1, randfunc) + value |= 2 ** (N-1) # Ensure high bit is set + assert size(value) >= N + return value + +def GCD(x,y): + """Greatest Common Denominator of :data:`x` and :data:`y`. + """ + + x = abs(x) ; y = abs(y) + while x > 0: + x, y = y % x, x + return y + +def inverse(u, v): + """The inverse of :data:`u` *mod* :data:`v`.""" + + u3, v3 = u, v + u1, v1 = 1, 0 + while v3 > 0: + q = u3 // v3 + 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): + """Return a random N-bit prime number. + + If randfunc is omitted, then :meth:`Random.get_random_bytes` is used. + """ + if randfunc is None: + randfunc = Random.get_random_bytes + + 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 definitely composite. + Returns 1 when n is probably prime. + Returns 2 when n is definitely 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 iter_range (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 iter_range(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): + r""" + 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. + + Args: + N (integer): the exact length of the strong prime. + It must be a multiple of 128 and > 512. + e (integer): if provided, the returned prime (minus 1) + will be coprime to *e* and thus suitable for RSA where + *e* is the public exponent. + false_positive_prob (float): + The statistical probability for the result not to be actually a + prime. It defaults to 10\ :sup:`-6`. + Note that the real probability of a false-positive is far less. This is + just the mathematically provable limit. + randfunc (callable): + A function that takes a parameter *N* and that returns + a random byte string of such length. + If omitted, :func:`Cryptodome.Random.get_random_bytes` is used. + Return: + The new strong prime. + + .. deprecated:: 3.0 + This function is for internal use only and may be renamed or removed in + the future. + """ + + # 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 + + if randfunc is None: + randfunc = Random.get_random_bytes + + # 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 = (14142135623730950489 * (2 ** (511 + 128*x))) // 10000000000000000000 + upper_bound = (1 << (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 iter_range((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, (X-1) // 2) != 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 >= 1 << 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): + r"""Test if a number *N* is a prime. + + Args: + false_positive_prob (float): + The statistical probability for the result not to be actually a + prime. It defaults to 10\ :sup:`-6`. + Note that the real probability of a false-positive is far less. + This is just the mathematically provable limit. + randfunc (callable): + A function that takes a parameter *N* and that returns + a random byte string of such length. + If omitted, :func:`Cryptodome.Random.get_random_bytes` is used. + + Return: + `True` is the input is indeed prime. + """ + + if randfunc is None: + randfunc = Random.get_random_bytes + + 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): + """Convert an integer to a byte string. + + In Python 3.2+, use the native method instead:: + + >>> n.to_bytes(blocksize, 'big') + + For instance:: + + >>> n = 80 + >>> n.to_bytes(2, 'big') + b'\x00P' + + If the optional :data:`blocksize` is provided and greater than zero, + the byte string is padded with binary zeros (on the front) so that + the total length of the output is a multiple of blocksize. + + If :data:`blocksize` is zero or not provided, the byte string will + be of minimal length. + """ + # after much testing, this algorithm was deemed to be the fastest + s = b'' + n = int(n) + pack = struct.pack + while n > 0: + s = pack('>I', n & 0xffffffff) + s + n = n >> 32 + # strip off leading zeros + for i in range(len(s)): + if s[i] != b'\x00'[0]: + break + else: + # only happens when n == 0 + s = b'\x00' + 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'\x00' + s + return s + +def bytes_to_long(s): + """Convert a byte string to a long integer (big endian). + + In Python 3.2+, use the native method instead:: + + >>> int.from_bytes(s, 'big') + + For instance:: + + >>> int.from_bytes(b'\x00P', 'big') + 80 + + This is (essentially) the inverse of :func:`long_to_bytes`. + """ + acc = 0 + + unpack = struct.unpack + + # Up to Python 2.7.4, struct.unpack can't work with bytearrays nor + # memoryviews + if sys.version_info[0:3] < (2, 7, 4): + if isinstance(s, bytearray): + s = bytes(s) + elif isinstance(s, _memoryview): + s = s.tobytes() + + length = len(s) + if length % 4: + extra = (4 - length % 4) + s = b'\x00' * 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) + + +# 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/frozen_deps/Cryptodome/Util/number.pyi b/frozen_deps/Cryptodome/Util/number.pyi new file mode 100644 index 0000000..f8680bf --- /dev/null +++ b/frozen_deps/Cryptodome/Util/number.pyi @@ -0,0 +1,19 @@ +from typing import List, Optional, Callable + + +def ceil_div(n: int, d: int) -> int: ... +def size (N: int) -> int: ... +def getRandomInteger(N: int, randfunc: Optional[Callable]=None) -> int: ... +def getRandomRange(a: int, b: int, randfunc: Optional[Callable]=None) -> int: ... +def getRandomNBitInteger(N: int, randfunc: Optional[Callable]=None) -> int: ... +def GCD(x: int,y: int) -> int: ... +def inverse(u: int, v: int) -> int: ... +def getPrime(N: int, randfunc: Optional[Callable]=None) -> int: ... +def getStrongPrime(N: int, e: Optional[int]=0, false_positive_prob: Optional[float]=1e-6, randfunc: Optional[Callable]=None) -> int: ... +def isPrime(N: int, false_positive_prob: Optional[float]=1e-6, randfunc: Optional[Callable]=None) -> bool: ... +def long_to_bytes(n: int, blocksize: Optional[int]=0) -> bytes: ... +def bytes_to_long(s: bytes) -> int: ... +def long2str(n: int, blocksize: Optional[int]=0) -> bytes: ... +def str2long(s: bytes) -> int: ... + +sieve_base: List[int] diff --git a/frozen_deps/Cryptodome/Util/py3compat.py b/frozen_deps/Cryptodome/Util/py3compat.py new file mode 100644 index 0000000..40ef752 --- /dev/null +++ b/frozen_deps/Cryptodome/Util/py3compat.py @@ -0,0 +1,164 @@ +# -*- coding: utf-8 -*- +# +# Util/py3compat.py : Compatibility code for handling Py3k / Python 2.x +# +# Written in 2010 by Thorsten Behrens +# +# =================================================================== +# 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 handling string/bytes changes from Python 2.x to Py3k + +In Python 2.x, strings (of type ''str'') contain binary data, including encoded +Unicode text (e.g. UTF-8). The separate type ''unicode'' holds Unicode text. +Unicode literals are specified via the u'...' prefix. Indexing or slicing +either type always produces a string of the same type as the original. +Data read from a file is always of '''str'' type. + +In Python 3.x, strings (type ''str'') may only contain Unicode text. The u'...' +prefix and the ''unicode'' type are now redundant. A new type (called +''bytes'') has to be used for binary data (including any particular +''encoding'' of a string). The b'...' prefix allows one to specify a binary +literal. Indexing or slicing a string produces another string. Slicing a byte +string produces another byte string, but the indexing operation produces an +integer. Data read from a file is of '''str'' type if the file was opened in +text mode, or of ''bytes'' type otherwise. + +Since PyCryptodome aims at supporting both Python 2.x and 3.x, the following helper +functions are used to keep the rest of the library as independent as possible +from the actual Python version. + +In general, the code should always deal with binary strings, and use integers +instead of 1-byte character strings. + +b(s) + Take a text string literal (with no prefix or with u'...' prefix) and + make a byte string. +bchr(c) + Take an integer and make a 1-character byte string. +bord(c) + Take the result of indexing on a byte string and make an integer. +tobytes(s) + Take a text string, a byte string, or a sequence of character taken from + a byte string and make a byte string. +""" + +import sys +import abc + + +if sys.version_info[0] == 2: + def b(s): + return s + def bchr(s): + return chr(s) + def bstr(s): + return str(s) + def bord(s): + return ord(s) + def tobytes(s, encoding="latin-1"): + if isinstance(s, unicode): + return s.encode(encoding) + elif isinstance(s, str): + return s + elif isinstance(s, bytearray): + return bytes(s) + else: + return ''.join(s) + def tostr(bs): + return bs + def byte_string(s): + return isinstance(s, str) + + # In Pyton 2.x, StringIO is a stand-alone module + from StringIO import StringIO as BytesIO + + from sys import maxint + + if sys.version_info[1] < 7: + import types + _memoryview = types.NoneType + else: + _memoryview = memoryview + + iter_range = xrange + + def is_native_int(x): + return isinstance(x, (int, long)) + + def is_string(x): + return isinstance(x, basestring) + + ABC = abc.ABCMeta('ABC', (object,), {'__slots__': ()}) + +else: + def b(s): + return s.encode("latin-1") # utf-8 would cause some side-effects we don't want + def bchr(s): + return bytes([s]) + def bstr(s): + if isinstance(s,str): + return bytes(s,"latin-1") + else: + return bytes(s) + def bord(s): + return s + def tobytes(s, encoding="latin-1"): + if isinstance(s, bytes): + return s + elif isinstance(s, bytearray): + return bytes(s) + elif isinstance(s,str): + return s.encode(encoding) + else: + return bytes([s]) + def tostr(bs): + return bs.decode("latin-1") + def byte_string(s): + return isinstance(s, bytes) + + # In Python 3.x, StringIO is a sub-module of io + from io import BytesIO + from sys import maxsize as maxint + + _memoryview = memoryview + + iter_range = range + + def is_native_int(x): + return isinstance(x, int) + + def is_string(x): + return isinstance(x, str) + + from abc import ABC + + +def _copy_bytes(start, end, seq): + """Return an immutable copy of a sequence (byte string, byte array, memoryview) + in a certain interval [start:seq]""" + + if isinstance(seq, _memoryview): + return seq[start:end].tobytes() + elif isinstance(seq, bytearray): + return bytes(seq[start:end]) + else: + return seq[start:end] + +del sys +del abc diff --git a/frozen_deps/Cryptodome/Util/py3compat.pyi b/frozen_deps/Cryptodome/Util/py3compat.pyi new file mode 100644 index 0000000..3297dc0 --- /dev/null +++ b/frozen_deps/Cryptodome/Util/py3compat.pyi @@ -0,0 +1,35 @@ +from typing import Union, Any, Optional, IO + +Buffer = Union[bytes, bytearray, memoryview] + +import sys + +def b(s: str) -> bytes: ... +def bchr(s: int) -> bytes: ... +def bord(s: bytes) -> int: ... +def tobytes(s: Union[bytes, str]) -> bytes: ... +def tostr(b: bytes) -> str: ... +def bytestring(x: Any) -> bool: ... + +def is_native_int(s: Any) -> bool: ... +def is_string(x: Any) -> bool: ... + +def BytesIO(b: bytes) -> IO[bytes]: ... + +if sys.version_info[0] == 2: + from sys import maxint + iter_range = xrange + + if sys.version_info[1] < 7: + import types + _memoryview = types.NoneType + else: + _memoryview = memoryview + +else: + from sys import maxsize as maxint + iter_range = range + + _memoryview = memoryview + +def _copy_bytes(start: Optional[int], end: Optional[int], seq: Buffer) -> bytes: ... diff --git a/frozen_deps/Cryptodome/Util/strxor.py b/frozen_deps/Cryptodome/Util/strxor.py new file mode 100644 index 0000000..91fb4c9 --- /dev/null +++ b/frozen_deps/Cryptodome/Util/strxor.py @@ -0,0 +1,137 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, c_size_t, + create_string_buffer, get_raw_buffer, + c_uint8_ptr, is_writeable_buffer) + +_raw_strxor = load_pycryptodome_raw_lib("Cryptodome.Util._strxor", + """ + void strxor(const uint8_t *in1, + const uint8_t *in2, + uint8_t *out, size_t len); + void strxor_c(const uint8_t *in, + uint8_t c, + uint8_t *out, + size_t len); + """) + + +def strxor(term1, term2, output=None): + """XOR two byte strings. + + Args: + term1 (bytes/bytearray/memoryview): + The first term of the XOR operation. + term2 (bytes/bytearray/memoryview): + The second term of the XOR operation. + output (bytearray/memoryview): + The location where the result must be written to. + If ``None``, the result is returned. + :Return: + If ``output`` is ``None``, a new ``bytes`` string with the result. + Otherwise ``None``. + """ + + if len(term1) != len(term2): + raise ValueError("Only byte strings of equal length can be xored") + + if output is None: + result = create_string_buffer(len(term1)) + else: + # Note: output may overlap with either input + result = output + + if not is_writeable_buffer(output): + raise TypeError("output must be a bytearray or a writeable memoryview") + + if len(term1) != len(output): + raise ValueError("output must have the same length as the input" + " (%d bytes)" % len(term1)) + + _raw_strxor.strxor(c_uint8_ptr(term1), + c_uint8_ptr(term2), + c_uint8_ptr(result), + c_size_t(len(term1))) + + if output is None: + return get_raw_buffer(result) + else: + return None + + +def strxor_c(term, c, output=None): + """XOR a byte string with a repeated sequence of characters. + + Args: + term(bytes/bytearray/memoryview): + The first term of the XOR operation. + c (bytes): + The byte that makes up the second term of the XOR operation. + output (None or bytearray/memoryview): + If not ``None``, the location where the result is stored into. + + Return: + If ``output`` is ``None``, a new ``bytes`` string with the result. + Otherwise ``None``. + """ + + if not 0 <= c < 256: + raise ValueError("c must be in range(256)") + + if output is None: + result = create_string_buffer(len(term)) + else: + # Note: output may overlap with either input + result = output + + if not is_writeable_buffer(output): + raise TypeError("output must be a bytearray or a writeable memoryview") + + if len(term) != len(output): + raise ValueError("output must have the same length as the input" + " (%d bytes)" % len(term)) + + _raw_strxor.strxor_c(c_uint8_ptr(term), + c, + c_uint8_ptr(result), + c_size_t(len(term)) + ) + + if output is None: + return get_raw_buffer(result) + else: + return None + + +def _strxor_direct(term1, term2, result): + """Very fast XOR - check conditions!""" + _raw_strxor.strxor(term1, term2, result, c_size_t(len(term1))) + diff --git a/frozen_deps/Cryptodome/Util/strxor.pyi b/frozen_deps/Cryptodome/Util/strxor.pyi new file mode 100644 index 0000000..ca896f3 --- /dev/null +++ b/frozen_deps/Cryptodome/Util/strxor.pyi @@ -0,0 +1,6 @@ +from typing import Union, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +def strxor(term1: bytes, term2: bytes, output: Optional[Buffer]=...) -> bytes: ... +def strxor_c(term: bytes, c: int, output: Optional[Buffer]=...) -> bytes: ... diff --git a/frozen_deps/Cryptodome/__init__.py b/frozen_deps/Cryptodome/__init__.py new file mode 100644 index 0000000..bb08e39 --- /dev/null +++ b/frozen_deps/Cryptodome/__init__.py @@ -0,0 +1,6 @@ +__all__ = ['Cipher', 'Hash', 'Protocol', 'PublicKey', 'Util', 'Signature', + 'IO', 'Math'] + +version_info = (3, 9, '9') + +__version__ = ".".join([str(x) for x in version_info]) diff --git a/frozen_deps/Cryptodome/__init__.pyi b/frozen_deps/Cryptodome/__init__.pyi new file mode 100644 index 0000000..bc73446 --- /dev/null +++ b/frozen_deps/Cryptodome/__init__.pyi @@ -0,0 +1,4 @@ +from typing import Tuple, Union + +version_info : Tuple[int, int, Union[int, str]] +__version__ : str diff --git a/frozen_deps/Cryptodome/py.typed b/frozen_deps/Cryptodome/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/frozen_deps/bin/keytree.py b/frozen_deps/bin/keytree.py index 1f4bedb..0b09eaf 100755 --- a/frozen_deps/bin/keytree.py +++ b/frozen_deps/bin/keytree.py @@ -223,12 +223,12 @@ def load_from_keystore(filename): key = hashlib.pbkdf2_hmac( 'sha256', sha256(passwd + salt), salt, 200000) - obj = AES.new(key, + a = AES.new(key, mode=AES.MODE_GCM, nonce=iv) if tag != sha256(passwd + sha256(passwd + salt)): raise KeytreeError("incorrect keystore password") - return obj.decrypt(ciphertext[:-16]).decode('utf-8') + return a.decrypt(ciphertext[:-16]).decode('utf-8') except KeytreeError as e: raise e except: @@ -237,9 +237,43 @@ def load_from_keystore(filename): raise KeytreeError("failed to open file") +def cb58encode(raw): + checksum = sha256(raw)[-4:] + return b58encode(raw + checksum) + + +def save_to_keystore(filename, words): + try: + with open(filename, "w") as f: + #try: + passwd = getpass('Enter the password for the keystore (utf-8): ').encode('utf-8') + iv = os.urandom(12) + salt = os.urandom(16) + pass_hash = sha256(passwd + sha256(passwd + salt)) + key = hashlib.pbkdf2_hmac( + 'sha256', + sha256(passwd + salt), salt, 200000) + a = AES.new(key, + mode=AES.MODE_GCM, + nonce=iv).update(salt) + (c, t) = a.encrypt_with_digest(words) + ciphertext = c + t + json.dump({ + 'keys': [ + {'key': cb58encode(ciphertext), 'iv': cb58encode(iv)}], + 'salt': cb58encode(salt), + 'pass_hash': cb58encode(pass_hash) + }, f) + #except: + # raise KeytreeError("invalid or corrupted keystore file") + except FileNotFoundError: + raise KeytreeError("failed to open file") + + if __name__ == '__main__': parser = argparse.ArgumentParser(description='Derive BIP32 key pairs from BIP39 mnemonic') - parser.add_argument('--from-avax-keystore', type=str, default=None, help='load mnemonic from an AVAX keystore file') + parser.add_argument('--load-keystore', type=str, default=None, help='load mnemonic from a keystore file (AVAX Wallet compatible)') + parser.add_argument('--save-keystore', type=str, default=None, help='save mnemonic to a keystore file (AVAX Wallet compatible)') parser.add_argument('--show-private', action='store_true', default=False, help='also show private keys and the mnemonic') parser.add_argument('--custom-words', action='store_true', default=False, help='use an arbitrary word combination as mnemonic') parser.add_argument('--account-path', default="44'/9000'/0'/0", help="path prefix for key deriving (e.g. \"0/1'/2\")") @@ -258,8 +292,8 @@ if __name__ == '__main__': mgen = mnemonic.Mnemonic(args.lang) words = mgen.generate(256) else: - if args.from_avax_keystore: - words = load_from_keystore(args.from_avax_keystore) + if args.load_keystore: + words = load_from_keystore(args.load_keystore) else: words = getpass('Enter the mnemonic: ').strip() if not args.custom_words: @@ -285,6 +319,8 @@ if __name__ == '__main__': print("{}.addr(AVAX) X-{}".format(i, bech32.bech32_encode(args.hrp, bech32.convertbits(ripemd160(sha256(cpub)), 8, 5)))) print("{}.addr(BTC) {}".format(i, get_btc_addr(pub))) print("{}.addr(ETH) {}".format(i, get_eth_addr(pub))) + if args.save_keystore: + save_to_keystore(args.save_keystore, words) except KeytreeError as e: sys.stderr.write("error: {}\n".format(str(e))) sys.exit(1) diff --git a/frozen_deps/keytree.py-0.2.dist-info/METADATA b/frozen_deps/keytree.py-0.2.dist-info/METADATA index ced8872..30904eb 100644 --- a/frozen_deps/keytree.py-0.2.dist-info/METADATA +++ b/frozen_deps/keytree.py-0.2.dist-info/METADATA @@ -10,7 +10,7 @@ Platform: UNKNOWN Requires-Dist: ecdsa Requires-Dist: base58 Requires-Dist: pysha3 -Requires-Dist: pycrypto +Requires-Dist: pycryptodomex Requires-Dist: mnemonic UNKNOWN diff --git a/frozen_deps/keytree.py-0.2.dist-info/RECORD b/frozen_deps/keytree.py-0.2.dist-info/RECORD index 6d5e4e7..5f7d2f8 100644 --- a/frozen_deps/keytree.py-0.2.dist-info/RECORD +++ b/frozen_deps/keytree.py-0.2.dist-info/RECORD @@ -1,9 +1,9 @@ ../../bin/__pycache__/keytree.cpython-38.pyc,, -../../bin/keytree.py,sha256=3ZAMRh7CeqEydctLUTqBLfcgiVZlDfmcsDfUWcxLYjw,10394 +../../bin/keytree.py,sha256=XCCc0ThEVf1BRHtz8LefMmWyhGBp9G8LkxzY51JDkj0,11850 __pycache__/bech32.cpython-38.pyc,, bech32.py,sha256=QZdU7nY1UUzeYfV-5ASwhe3PA3YVVnClyGGrtgJIjsE,4376 keytree.py-0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -keytree.py-0.2.dist-info/METADATA,sha256=mbeKpm8oSaMl3-pBpqeonURUlfmadsd0gw7rt8ZVm1w,363 +keytree.py-0.2.dist-info/METADATA,sha256=bnRg0Bju4Uk768UXWAJ2TAlKIkRFgPP92ClhF1Z2o2w,368 keytree.py-0.2.dist-info/RECORD,, keytree.py-0.2.dist-info/WHEEL,sha256=g4nMs7d-Xl9-xC9XovUrsDHGXt-FT0E17Yqo92DEfvY,92 keytree.py-0.2.dist-info/direct_url.json,sha256=6seyiOxGCRXsnt6lrEcpcJtZGEXuBr-KHa0idXAuZDA,71 diff --git a/frozen_deps/pycrypto-2.6.1.dist-info/INSTALLER b/frozen_deps/pycrypto-2.6.1.dist-info/INSTALLER deleted file mode 100644 index a1b589e..0000000 --- a/frozen_deps/pycrypto-2.6.1.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/frozen_deps/pycrypto-2.6.1.dist-info/METADATA b/frozen_deps/pycrypto-2.6.1.dist-info/METADATA deleted file mode 100644 index 3f5b6a7..0000000 --- a/frozen_deps/pycrypto-2.6.1.dist-info/METADATA +++ /dev/null @@ -1,22 +0,0 @@ -Metadata-Version: 2.1 -Name: pycrypto -Version: 2.6.1 -Summary: Cryptographic modules for Python. -Home-page: http://www.pycrypto.org/ -Author: Dwayne C. Litzenberger -Author-email: dlitz@dlitz.net -License: UNKNOWN -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: License :: Public Domain -Classifier: Intended Audience :: Developers -Classifier: Operating System :: Unix -Classifier: Operating System :: Microsoft :: Windows -Classifier: Operating System :: MacOS :: MacOS X -Classifier: Topic :: Security :: Cryptography -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 3 - -UNKNOWN - - diff --git a/frozen_deps/pycrypto-2.6.1.dist-info/RECORD b/frozen_deps/pycrypto-2.6.1.dist-info/RECORD deleted file mode 100644 index bcad46d..0000000 --- a/frozen_deps/pycrypto-2.6.1.dist-info/RECORD +++ /dev/null @@ -1,261 +0,0 @@ -Crypto/Cipher/AES.py,sha256=zdQXQvWD37SMh6Pz71Ir_nmzv7cZ7RQjCd6Tp2gE0fY,4218 -Crypto/Cipher/ARC2.py,sha256=3lRMA8tW0jBEbyXC-f_4x88MkzudgmRPZlzGpZ8032M,4916 -Crypto/Cipher/ARC4.py,sha256=HLlyx41Ao7nLwHZ5Z-vqiBPqB0udK9EcmyBnBABYWP4,4265 -Crypto/Cipher/Blowfish.py,sha256=xGVzqqoeDegd6KFyUalrTZ81jZDUbJtE2-zf8nidO2k,4459 -Crypto/Cipher/CAST.py,sha256=G9B9pHPD5A_2f_8laeMU9HtYEWu6iPrzP8kU2pNDr8E,4497 -Crypto/Cipher/DES.py,sha256=BtD_kaaAtHd4eqYUD1R12TJ5tLSlgww6kgJpkiMOcDQ,4403 -Crypto/Cipher/DES3.py,sha256=RxWw3mcYZ6YkVYGGjffQHZWqqOQTv_43s-73SyYko_w,5130 -Crypto/Cipher/PKCS1_OAEP.py,sha256=CEDbzB7NG9LJ5cUPSWkVlUIaIHtHiitGip1z2VDIXIM,9337 -Crypto/Cipher/PKCS1_v1_5.py,sha256=QefUewQFdMeqyzyNtPJWsbm12kidQuoiwMJt2JIGYZc,9109 -Crypto/Cipher/XOR.py,sha256=_tqnB-fVPSeL4UTbD58QNFCikvXACAI_yNYyUZ0veDs,2736 -Crypto/Cipher/_AES.cpython-38-x86_64-linux-gnu.so,sha256=qajgcGRe6FxLNsqyjmC0kvAM-AP5Leg5x-pJ7Ff3YDg,43640 -Crypto/Cipher/_ARC2.cpython-38-x86_64-linux-gnu.so,sha256=Ms1i0EgMSg1u0l0PqooApjfXBXrPdBa4BNvC5JtpXrQ,26904 -Crypto/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so,sha256=Z8XpYrkIBzeb3bC8G2rVetIbXT-YBEPH0bYACLrL6Nc,18064 -Crypto/Cipher/_Blowfish.cpython-38-x86_64-linux-gnu.so,sha256=_Kj6oU_kwvtnXoZPvtQ6bbvgqan7jtWWDpChUQSu8-A,35368 -Crypto/Cipher/_CAST.cpython-38-x86_64-linux-gnu.so,sha256=74aSGGReYsFWAYaxdzvQvFGArb3ByJUp9fYFOsutwi0,35320 -Crypto/Cipher/_DES.cpython-38-x86_64-linux-gnu.so,sha256=nAbiA_48cuQD5rPQkyIflgckbONIUPlOF5BqLL55CnU,68560 -Crypto/Cipher/_DES3.cpython-38-x86_64-linux-gnu.so,sha256=B5Z5TAcZldhS_Rx0_NvlXpyC697IGYIOgyybb9GjFco,68560 -Crypto/Cipher/_XOR.cpython-38-x86_64-linux-gnu.so,sha256=6yZ52WaICl8oqjJoED3V34JxwnX44C_INVBLjluPqpA,18096 -Crypto/Cipher/__init__.py,sha256=XljqRT7D0kyJEpntdMQbA8n68gWwLQedxzc1T8VygYU,3440 -Crypto/Cipher/__pycache__/AES.cpython-38.pyc,, -Crypto/Cipher/__pycache__/ARC2.cpython-38.pyc,, -Crypto/Cipher/__pycache__/ARC4.cpython-38.pyc,, -Crypto/Cipher/__pycache__/Blowfish.cpython-38.pyc,, -Crypto/Cipher/__pycache__/CAST.cpython-38.pyc,, -Crypto/Cipher/__pycache__/DES.cpython-38.pyc,, -Crypto/Cipher/__pycache__/DES3.cpython-38.pyc,, -Crypto/Cipher/__pycache__/PKCS1_OAEP.cpython-38.pyc,, -Crypto/Cipher/__pycache__/PKCS1_v1_5.cpython-38.pyc,, -Crypto/Cipher/__pycache__/XOR.cpython-38.pyc,, -Crypto/Cipher/__pycache__/__init__.cpython-38.pyc,, -Crypto/Cipher/__pycache__/blockalgo.cpython-38.pyc,, -Crypto/Cipher/blockalgo.py,sha256=iTMWpnhMhwMD1SqyDduyB9B-ueLAKGLiW-oD2Vt-xms,12596 -Crypto/Hash/HMAC.py,sha256=2lpshwFp5OGeymb3D-zirgjDOg6QIdTvWnJAmnJ8xk0,7309 -Crypto/Hash/MD2.py,sha256=AVkf-DC5TPJysc6qXBNfSTWgz-RVIKP8adbOUZBS914,2734 -Crypto/Hash/MD4.py,sha256=4LNMbJUmXeB7Dg24FrtzyZaYpBhHKD3qBsFzsENFAQE,2716 -Crypto/Hash/MD5.py,sha256=tpnoyAq7YDeCfJVMXc2U6rm4R0pCMjLzAF2lMEmDG24,2863 -Crypto/Hash/RIPEMD.py,sha256=VGl2ej_XG3PPByfduL8KNy2g_W45SYukmE4Ww5jUhyg,3005 -Crypto/Hash/SHA.py,sha256=IgvTUNC1j1Y-ITKyKhbZBLSaZGHSFTY_nVEUThXVvbg,2841 -Crypto/Hash/SHA224.py,sha256=HNBj-5K5W9o6hwROHKtan6TzRPM72jGNIxEEKEF0r8o,2851 -Crypto/Hash/SHA256.py,sha256=zUuyPbvEM519lyc9yG1yF9J_WD9QaQCa1wzfDWPwcNw,2852 -Crypto/Hash/SHA384.py,sha256=W7QZ-jYyCA1_vL2IeMQyhtXdCnuuk9KNEwEmwjzHoW8,2853 -Crypto/Hash/SHA512.py,sha256=_5Bk0r-48hJuNMezQYuWemlbGGPW2v4OqHVTYUmMvCg,2850 -Crypto/Hash/_MD2.cpython-38-x86_64-linux-gnu.so,sha256=-YIEL7BIqS1buS_x2LYTYZup3ANqy5PX5Yz37frUyLM,18464 -Crypto/Hash/_MD4.cpython-38-x86_64-linux-gnu.so,sha256=zbK4osbY37dLzSNUPKN6AgxQSZ6YtuVgyGIGuWVj334,18552 -Crypto/Hash/_RIPEMD160.cpython-38-x86_64-linux-gnu.so,sha256=wtjyzmtTp_rYQBvJFviVfZpsAvlk6D-4t_zkKIXUWvI,22888 -Crypto/Hash/_SHA224.cpython-38-x86_64-linux-gnu.so,sha256=4LvpSq7MmkNpZsMf7speKCxgUh_b10plytYXflrBt7Y,18496 -Crypto/Hash/_SHA256.cpython-38-x86_64-linux-gnu.so,sha256=Xa5v4RySkT_tHytuUBm9A5NK90108oebNDxnzePepuk,18496 -Crypto/Hash/_SHA384.cpython-38-x86_64-linux-gnu.so,sha256=URhwdl1hoK0euL23vtoj3N9Jw2Gem3kVqN20nXAbCdU,22592 -Crypto/Hash/_SHA512.cpython-38-x86_64-linux-gnu.so,sha256=uA5QGreT8Ufq54CkniZdr5ayeBhBzTe5BHlyxI0BPY4,22592 -Crypto/Hash/__init__.py,sha256=QtJ_3oI1ELyZ1gm8Gqhli_1xT4CQCECWLaq094HonN4,2432 -Crypto/Hash/__pycache__/HMAC.cpython-38.pyc,, -Crypto/Hash/__pycache__/MD2.cpython-38.pyc,, -Crypto/Hash/__pycache__/MD4.cpython-38.pyc,, -Crypto/Hash/__pycache__/MD5.cpython-38.pyc,, -Crypto/Hash/__pycache__/RIPEMD.cpython-38.pyc,, -Crypto/Hash/__pycache__/SHA.cpython-38.pyc,, -Crypto/Hash/__pycache__/SHA224.cpython-38.pyc,, -Crypto/Hash/__pycache__/SHA256.cpython-38.pyc,, -Crypto/Hash/__pycache__/SHA384.cpython-38.pyc,, -Crypto/Hash/__pycache__/SHA512.cpython-38.pyc,, -Crypto/Hash/__pycache__/__init__.cpython-38.pyc,, -Crypto/Hash/__pycache__/hashalgo.cpython-38.pyc,, -Crypto/Hash/hashalgo.py,sha256=uNOiQseIAw-NXKIwjAomwA3ZdjLHBnzES0GD3Xh6hu8,3984 -Crypto/Protocol/AllOrNothing.py,sha256=szBTydYgyxmPbGbHXv-uthp5rO4XA0N0rgKRGF3FmvM,11959 -Crypto/Protocol/Chaffing.py,sha256=hkUbn2R4nKjQlMEy9CgJ4a4qvuqxjMCz9quqHrYBuJU,10280 -Crypto/Protocol/KDF.py,sha256=98bWbmx1ctD65OHxTNhxqX2dE58TIAXl5p2PCkEPaFo,5069 -Crypto/Protocol/__init__.py,sha256=nIuNk6tS9Xm4HsOhkQPIyG_VMCgT2MwGsZja2sjXrtg,1573 -Crypto/Protocol/__pycache__/AllOrNothing.cpython-38.pyc,, -Crypto/Protocol/__pycache__/Chaffing.cpython-38.pyc,, -Crypto/Protocol/__pycache__/KDF.cpython-38.pyc,, -Crypto/Protocol/__pycache__/__init__.cpython-38.pyc,, -Crypto/PublicKey/DSA.py,sha256=jXpxkko8IrvH_YfGGEl3idVVpfTbllAjkpliz635Iok,13689 -Crypto/PublicKey/ElGamal.py,sha256=HVZfYJylzakvAJ83W0VxVyyVoUP-eGl5Z6_WM5kYaog,13212 -Crypto/PublicKey/RSA.py,sha256=6DeyV2z4H5wChNI622FyT0M3czDgPX0tUlQrIFzimII,29893 -Crypto/PublicKey/_DSA.py,sha256=m-dMnmKqkw4uOXSNTwf7braa_-eoWuRDcmjPWKQcOVI,3470 -Crypto/PublicKey/_RSA.py,sha256=dFMnO1k9N1rijktx2OFCJv5xzd_oYVepVSWNRv0fkmQ,2760 -Crypto/PublicKey/__init__.py,sha256=dTFZbenEp98vElmrk9vuT2X9IqL3jHHKtq4pITpJZTU,1876 -Crypto/PublicKey/__pycache__/DSA.cpython-38.pyc,, -Crypto/PublicKey/__pycache__/ElGamal.cpython-38.pyc,, -Crypto/PublicKey/__pycache__/RSA.cpython-38.pyc,, -Crypto/PublicKey/__pycache__/_DSA.cpython-38.pyc,, -Crypto/PublicKey/__pycache__/_RSA.cpython-38.pyc,, -Crypto/PublicKey/__pycache__/__init__.cpython-38.pyc,, -Crypto/PublicKey/__pycache__/_slowmath.cpython-38.pyc,, -Crypto/PublicKey/__pycache__/pubkey.cpython-38.pyc,, -Crypto/PublicKey/_fastmath.cpython-38-x86_64-linux-gnu.so,sha256=wVmNfdPPprXNgY8Db86ZywNBsLIGDjaKCuWmE56Sy-s,78864 -Crypto/PublicKey/_slowmath.py,sha256=bZTi0MEViDieJfhsEnKRatt86yZ7V-MToW3viDDT3c4,6409 -Crypto/PublicKey/pubkey.py,sha256=swCmQTk5oHjODolNoO78znO1vlb044LgT2EcvKWEXW4,8088 -Crypto/Random/Fortuna/FortunaAccumulator.py,sha256=LJ9Npmoq9uPyCLjEAw0cceitozqKLPHsIHfHsjGc4LA,6788 -Crypto/Random/Fortuna/FortunaGenerator.py,sha256=GfaMASoqHTeCPW9lPJ2cuIe4z245H9XrykNMS-BvFJU,5270 -Crypto/Random/Fortuna/SHAd256.py,sha256=BNLUDG0QSNqlBpmorD8Qv583LTinuAgpAi2HgThsaag,3098 -Crypto/Random/Fortuna/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -Crypto/Random/Fortuna/__pycache__/FortunaAccumulator.cpython-38.pyc,, -Crypto/Random/Fortuna/__pycache__/FortunaGenerator.cpython-38.pyc,, -Crypto/Random/Fortuna/__pycache__/SHAd256.cpython-38.pyc,, -Crypto/Random/Fortuna/__pycache__/__init__.cpython-38.pyc,, -Crypto/Random/OSRNG/__init__.py,sha256=6Q_9uzT3pk7G_Wk97D8Ze_JlFvSG2owPxJkyd24xP5E,1542 -Crypto/Random/OSRNG/__pycache__/__init__.cpython-38.pyc,, -Crypto/Random/OSRNG/__pycache__/fallback.cpython-38.pyc,, -Crypto/Random/OSRNG/__pycache__/posix.cpython-38.pyc,, -Crypto/Random/OSRNG/__pycache__/rng_base.cpython-38.pyc,, -Crypto/Random/OSRNG/fallback.py,sha256=MH99pYPRTmw7m8KorK2xeSwO7xrkLFor76RMNhY5KQg,1521 -Crypto/Random/OSRNG/posix.py,sha256=eTOTZJX9ZrCVc9Wz5Zw_Q7yaCe4iIeaq7O2P7jLv5pM,2838 -Crypto/Random/OSRNG/rng_base.py,sha256=GVjP55P4VRBk7oO_FKTjAGrc83O2NuYuOWVlG9C0EmQ,2867 -Crypto/Random/_UserFriendlyRNG.py,sha256=-K-jbkaPjn7reXc6gplEnYGq5A9lDmf1NiCXipdgK2w,7621 -Crypto/Random/__init__.py,sha256=L6NbHyEB2epH7WRsz3M6_LF9z7_eOnJjDOFH4opFzkg,1669 -Crypto/Random/__pycache__/_UserFriendlyRNG.cpython-38.pyc,, -Crypto/Random/__pycache__/__init__.cpython-38.pyc,, -Crypto/Random/__pycache__/random.cpython-38.pyc,, -Crypto/Random/random.py,sha256=eurKE-iEuqRp3vu39Gpiux67zfl5CJ8OGvnrTd8nWb4,5235 -Crypto/SelfTest/Cipher/__init__.py,sha256=QCrjmEJc9HvASt_x1TFxGvuWXJ0YTLKsVsLTG-V3E4E,2401 -Crypto/SelfTest/Cipher/__pycache__/__init__.cpython-38.pyc,, -Crypto/SelfTest/Cipher/__pycache__/common.cpython-38.pyc,, -Crypto/SelfTest/Cipher/__pycache__/test_AES.cpython-38.pyc,, -Crypto/SelfTest/Cipher/__pycache__/test_ARC2.cpython-38.pyc,, -Crypto/SelfTest/Cipher/__pycache__/test_ARC4.cpython-38.pyc,, -Crypto/SelfTest/Cipher/__pycache__/test_Blowfish.cpython-38.pyc,, -Crypto/SelfTest/Cipher/__pycache__/test_CAST.cpython-38.pyc,, -Crypto/SelfTest/Cipher/__pycache__/test_DES.cpython-38.pyc,, -Crypto/SelfTest/Cipher/__pycache__/test_DES3.cpython-38.pyc,, -Crypto/SelfTest/Cipher/__pycache__/test_XOR.cpython-38.pyc,, -Crypto/SelfTest/Cipher/__pycache__/test_pkcs1_15.cpython-38.pyc,, -Crypto/SelfTest/Cipher/__pycache__/test_pkcs1_oaep.cpython-38.pyc,, -Crypto/SelfTest/Cipher/common.py,sha256=YrMmMD1WSore4F24DC_vxJKvAHpBJLHce-g4NXYzIDY,16568 -Crypto/SelfTest/Cipher/test_AES.py,sha256=nvJaazjoV6kOcXHAWfNjb326Ikb5wZitMaRPwWeth1U,79977 -Crypto/SelfTest/Cipher/test_ARC2.py,sha256=UDWMnNHxGfoaSViVbcPGXs3NomsW2zxKAt2xcFxjIw4,4947 -Crypto/SelfTest/Cipher/test_ARC4.py,sha256=-iqIeQ6i9nR2M_YaME3QEuAFxhhUpelNlg3aCsiftgE,3547 -Crypto/SelfTest/Cipher/test_Blowfish.py,sha256=DLT3g75NF_eeaVaueRCQ2n4_XxJYd16rBouRsS7FIzU,5833 -Crypto/SelfTest/Cipher/test_CAST.py,sha256=YY6x3LJdrJbJgazEJxaHoOxlzfMzdCND8mUJZIZoDRs,1978 -Crypto/SelfTest/Cipher/test_DES.py,sha256=cG4o_9ckWsJvhSZiXU9I6jLBqdxaHBS2V73JlDt9bn4,15011 -Crypto/SelfTest/Cipher/test_DES3.py,sha256=dtR_aOZwlvUgppqFLemz0A6bfyUtiY09k0Sr-bQwhW0,15560 -Crypto/SelfTest/Cipher/test_XOR.py,sha256=Eq6eDUqae8ju8olSN5m9arIt4X6vbqCFmC-ev3htjHM,2539 -Crypto/SelfTest/Cipher/test_pkcs1_15.py,sha256=oLEYASebuOK3ruYz91ZThY8t07Sh04zoiuCfJ9K-UY0,7342 -Crypto/SelfTest/Cipher/test_pkcs1_oaep.py,sha256=uDgrJmzoJqIXeizzJDqKW2w0K8RGSp6NtE2aSIB5XSQ,17253 -Crypto/SelfTest/Hash/__init__.py,sha256=PwY0AUVBF3JZL0jyzajD_i5R7K6HatO5fLNuCqnSbHk,2518 -Crypto/SelfTest/Hash/__pycache__/__init__.cpython-38.pyc,, -Crypto/SelfTest/Hash/__pycache__/common.cpython-38.pyc,, -Crypto/SelfTest/Hash/__pycache__/test_HMAC.cpython-38.pyc,, -Crypto/SelfTest/Hash/__pycache__/test_MD2.cpython-38.pyc,, -Crypto/SelfTest/Hash/__pycache__/test_MD4.cpython-38.pyc,, -Crypto/SelfTest/Hash/__pycache__/test_MD5.cpython-38.pyc,, -Crypto/SelfTest/Hash/__pycache__/test_RIPEMD.cpython-38.pyc,, -Crypto/SelfTest/Hash/__pycache__/test_SHA.cpython-38.pyc,, -Crypto/SelfTest/Hash/__pycache__/test_SHA224.cpython-38.pyc,, -Crypto/SelfTest/Hash/__pycache__/test_SHA256.cpython-38.pyc,, -Crypto/SelfTest/Hash/__pycache__/test_SHA384.cpython-38.pyc,, -Crypto/SelfTest/Hash/__pycache__/test_SHA512.cpython-38.pyc,, -Crypto/SelfTest/Hash/common.py,sha256=0z6RQTvJ_hs-2nL-4NvWgW1TKib6urQjrlDb1tipYtU,7076 -Crypto/SelfTest/Hash/test_HMAC.py,sha256=An7fj5tVxCPoAkFWpTkteliVOTxEJ6wbxQCOLoCE-90,8199 -Crypto/SelfTest/Hash/test_MD2.py,sha256=SU0Bh-hD1BUwbZ1wmK6yOFIx2wkqdjIOW5k8HANxDQA,2369 -Crypto/SelfTest/Hash/test_MD4.py,sha256=xsr0oHX-vFlF6s4u0zK7VuyUBytbiFker7HwREZiCEw,2369 -Crypto/SelfTest/Hash/test_MD5.py,sha256=bd8-oLvo4Zbjk5VI-LiO1NWutLHGCQz8c2pdVm0PuEA,2369 -Crypto/SelfTest/Hash/test_RIPEMD.py,sha256=1uTfKvlGFSin5Zwkb5-EpDN9Hqju5RhBJE1mNzY8qGo,2686 -Crypto/SelfTest/Hash/test_SHA.py,sha256=OPYddyrd0jZwj7iDvEeLHwOcY39mLgg4DxEwOBI4LZo,2312 -Crypto/SelfTest/Hash/test_SHA224.py,sha256=pJv-BVv1U6SbVXuq4qurueae9Gv6ExwjlfhgF_nv8pA,2582 -Crypto/SelfTest/Hash/test_SHA256.py,sha256=lvDWuTKYIqVi07XsWiczsuETvw_MOGJmKT9ASatwpAc,3662 -Crypto/SelfTest/Hash/test_SHA384.py,sha256=nRNxUd0ji_iGhZeelFTS1BtC_7yKbO49oVW2GlKvM7I,2763 -Crypto/SelfTest/Hash/test_SHA512.py,sha256=teZzqGj9pJ1fY2XmMtgJiZRvcvngAourOH6Ka_nL2Hc,2850 -Crypto/SelfTest/Protocol/__init__.py,sha256=n0jyxv7F-g4upKbUa-17TvOvDDNNgR9FAsZPT2pRkf8,1751 -Crypto/SelfTest/Protocol/__pycache__/__init__.cpython-38.pyc,, -Crypto/SelfTest/Protocol/__pycache__/test_AllOrNothing.cpython-38.pyc,, -Crypto/SelfTest/Protocol/__pycache__/test_KDF.cpython-38.pyc,, -Crypto/SelfTest/Protocol/__pycache__/test_chaffing.cpython-38.pyc,, -Crypto/SelfTest/Protocol/__pycache__/test_rfc1751.cpython-38.pyc,, -Crypto/SelfTest/Protocol/test_AllOrNothing.py,sha256=9ZTaJ2VE1OqF_RxjKZLo_Geoqg_-26Z_N5hrPk_Dpwc,3024 -Crypto/SelfTest/Protocol/test_KDF.py,sha256=SAIrJVGiqZ5WWWi7xm90tqMBzTySWT4nA16ERp7VkgY,3827 -Crypto/SelfTest/Protocol/test_chaffing.py,sha256=CdumC2qHo_DSlv0NlgMX2Rh_n_IKiL1xxBLJYlQiWu8,2972 -Crypto/SelfTest/Protocol/test_rfc1751.py,sha256=LR3M9XLk_sxOyapPq32PEf93SUMwErFwwzlHNKhUazg,2208 -Crypto/SelfTest/PublicKey/__init__.py,sha256=LwAO13YrBCiPBG8n2EMD4pTH3JBvCJU5xEbWrkcFw5o,1842 -Crypto/SelfTest/PublicKey/__pycache__/__init__.cpython-38.pyc,, -Crypto/SelfTest/PublicKey/__pycache__/test_DSA.cpython-38.pyc,, -Crypto/SelfTest/PublicKey/__pycache__/test_ElGamal.cpython-38.pyc,, -Crypto/SelfTest/PublicKey/__pycache__/test_RSA.cpython-38.pyc,, -Crypto/SelfTest/PublicKey/__pycache__/test_importKey.cpython-38.pyc,, -Crypto/SelfTest/PublicKey/test_DSA.py,sha256=bD0J8xd60_K0-V4AEpMGS5gxNpE-43KRDJWLhEKZNyg,9861 -Crypto/SelfTest/PublicKey/test_ElGamal.py,sha256=JrUGohyq8mtTfYFo6aBrPpliybGZ1sO3R9aHjr_j3qM,8511 -Crypto/SelfTest/PublicKey/test_RSA.py,sha256=uHLl_bNVYuWtvgG8vZiySj-s5hKb7BgbcfmzyQGVLRo,16563 -Crypto/SelfTest/PublicKey/test_importKey.py,sha256=yG4mHgEVlUBkYnsLkqw8MKPRzXLJ6i-oIy2A57k1NTw,14907 -Crypto/SelfTest/Random/Fortuna/__init__.py,sha256=0jEzcC4VxLRAnSroCV-xkteVlO9sW8c_2-nldKelw5g,1825 -Crypto/SelfTest/Random/Fortuna/__pycache__/__init__.cpython-38.pyc,, -Crypto/SelfTest/Random/Fortuna/__pycache__/test_FortunaAccumulator.cpython-38.pyc,, -Crypto/SelfTest/Random/Fortuna/__pycache__/test_FortunaGenerator.cpython-38.pyc,, -Crypto/SelfTest/Random/Fortuna/__pycache__/test_SHAd256.cpython-38.pyc,, -Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.py,sha256=I0d-g7-rAKwJqMD4jMHo-DNLvv7j0_PPJU3z9Rci0xE,8655 -Crypto/SelfTest/Random/Fortuna/test_FortunaGenerator.py,sha256=aVxRxI7009xM0IjUt2gmF6ZiZJuZpWAXZELeYZWAezM,3506 -Crypto/SelfTest/Random/Fortuna/test_SHAd256.py,sha256=hCo1zmP1VE90tw1Xa5zNDhz42KY6Zf1A6yEMlIQR5R0,2419 -Crypto/SelfTest/Random/OSRNG/__init__.py,sha256=GHy35y5OsEdAve1otasx-d1P6UnAI9AcWM3pslNHIQQ,2082 -Crypto/SelfTest/Random/OSRNG/__pycache__/__init__.cpython-38.pyc,, -Crypto/SelfTest/Random/OSRNG/__pycache__/test_fallback.cpython-38.pyc,, -Crypto/SelfTest/Random/OSRNG/__pycache__/test_generic.cpython-38.pyc,, -Crypto/SelfTest/Random/OSRNG/__pycache__/test_nt.cpython-38.pyc,, -Crypto/SelfTest/Random/OSRNG/__pycache__/test_posix.cpython-38.pyc,, -Crypto/SelfTest/Random/OSRNG/__pycache__/test_winrandom.cpython-38.pyc,, -Crypto/SelfTest/Random/OSRNG/test_fallback.py,sha256=pReymeE8atbWeOiqmLu3M66K07ZyWaUhnTfMT1YI5kQ,1795 -Crypto/SelfTest/Random/OSRNG/test_generic.py,sha256=86QgZM4AcC_HMpXuyuvwOw2olhE4i--8dKDjXRA5_V8,1746 -Crypto/SelfTest/Random/OSRNG/test_nt.py,sha256=qpxL-Er7veLxAFHtgeqVVlpu7aGbKF3Wdt0xayfnYBQ,1764 -Crypto/SelfTest/Random/OSRNG/test_posix.py,sha256=5f52SxQg1dAPjcOPY0Gltlg5HpJkQqHKLJ9zlG3JKlY,1777 -Crypto/SelfTest/Random/OSRNG/test_winrandom.py,sha256=84h5E-vE6UBA55tBqk9m3q30jBXQzXswGE_RPEne5Vo,1777 -Crypto/SelfTest/Random/__init__.py,sha256=2lrY6di7ijeWWM9w4GX-XEepRuSY28aorzVz1X4K2_U,1973 -Crypto/SelfTest/Random/__pycache__/__init__.cpython-38.pyc,, -Crypto/SelfTest/Random/__pycache__/test__UserFriendlyRNG.cpython-38.pyc,, -Crypto/SelfTest/Random/__pycache__/test_random.cpython-38.pyc,, -Crypto/SelfTest/Random/__pycache__/test_rpoolcompat.cpython-38.pyc,, -Crypto/SelfTest/Random/test__UserFriendlyRNG.py,sha256=AIuP_vWn3skmVA9dxhfgYOLtMeVvdMPADcMFfTn2Lmo,5672 -Crypto/SelfTest/Random/test_random.py,sha256=BTA8EJQ2Q7DGyzoocXDOuPikskSM1xKkoEnAZsp50Ok,7129 -Crypto/SelfTest/Random/test_rpoolcompat.py,sha256=py3o_QmgRvX6tcvEp7Je6XnEBcVO_pOi-GXvgZmN85w,2030 -Crypto/SelfTest/Signature/__init__.py,sha256=FMHyPlOIGj67IkoPFun0UHpnc_1koKhfuQfw-mxhn44,1528 -Crypto/SelfTest/Signature/__pycache__/__init__.cpython-38.pyc,, -Crypto/SelfTest/Signature/__pycache__/test_pkcs1_15.cpython-38.pyc,, -Crypto/SelfTest/Signature/__pycache__/test_pkcs1_pss.cpython-38.pyc,, -Crypto/SelfTest/Signature/test_pkcs1_15.py,sha256=_b-Mab4CdXRIALdB8cWGqFLqgILZAUScEtfiWViuGb8,9471 -Crypto/SelfTest/Signature/test_pkcs1_pss.py,sha256=4CFckbL8OvCNYQgyB8RLueT6yDT6OTqSD53yOQtc4B4,20565 -Crypto/SelfTest/Util/__init__.py,sha256=TdCWQ_hp0YSq6Dna6rsrYz-VJpBKBcEG9LzqKev-v9Y,1743 -Crypto/SelfTest/Util/__pycache__/__init__.cpython-38.pyc,, -Crypto/SelfTest/Util/__pycache__/test_Counter.cpython-38.pyc,, -Crypto/SelfTest/Util/__pycache__/test_asn1.cpython-38.pyc,, -Crypto/SelfTest/Util/__pycache__/test_number.cpython-38.pyc,, -Crypto/SelfTest/Util/__pycache__/test_winrandom.cpython-38.pyc,, -Crypto/SelfTest/Util/test_Counter.py,sha256=WWliRgH8RVIIag6BpG0bSYjH4YL_0azSrEiRt-qgmT4,7087 -Crypto/SelfTest/Util/test_asn1.py,sha256=qRyogItInITbzbAftBJ9Mos1ZSbKjOUSRNfJP_4fVSk,10187 -Crypto/SelfTest/Util/test_number.py,sha256=BTet6CfyOh-3zIBAS8W-O1W4dpIzP6XvxdC9IExjhng,12862 -Crypto/SelfTest/Util/test_winrandom.py,sha256=HvBPZAjbk_1rQiq5ySHCPZQ46OFrXFo8EsCSZSWK40I,1772 -Crypto/SelfTest/__init__.py,sha256=M1NKM4hO2MmSQbI8KTagsloskp0OHJVlUEOTTaYPisQ,3412 -Crypto/SelfTest/__pycache__/__init__.cpython-38.pyc,, -Crypto/SelfTest/__pycache__/st_common.cpython-38.pyc,, -Crypto/SelfTest/st_common.py,sha256=qi1uOlmw06U32DD9tWGYZF9A3oA7PJfxWVbx4d8MxrE,2142 -Crypto/Signature/PKCS1_PSS.py,sha256=t6DUy5bgUp6guNII6rmRJRgxOFZa6Vd_foIfiRsA88U,12189 -Crypto/Signature/PKCS1_v1_5.py,sha256=4zF1UXx46uN43K7jRajJZFU8IprxYG4ualoGhES0dy8,8637 -Crypto/Signature/__init__.py,sha256=edI2zDF9wZnt2tGUMl-5QYwsHdspZTXsCot2ewsvyl0,1202 -Crypto/Signature/__pycache__/PKCS1_PSS.cpython-38.pyc,, -Crypto/Signature/__pycache__/PKCS1_v1_5.cpython-38.pyc,, -Crypto/Signature/__pycache__/__init__.cpython-38.pyc,, -Crypto/Util/Counter.py,sha256=wjed6nTp3jmEWXfmYPpUCSjsPDoa6WmiUlvSXhSQvMw,5156 -Crypto/Util/RFC1751.py,sha256=pm9iilAnohlNOVFwowxXCbkWKUSFticbzxQlzdBGDvk,21208 -Crypto/Util/__init__.py,sha256=RygfvkDs72Jet2S2jN7zwtkWOSVTHsSVJ6RVBvp4ugs,1507 -Crypto/Util/__pycache__/Counter.cpython-38.pyc,, -Crypto/Util/__pycache__/RFC1751.cpython-38.pyc,, -Crypto/Util/__pycache__/__init__.cpython-38.pyc,, -Crypto/Util/__pycache__/_number_new.cpython-38.pyc,, -Crypto/Util/__pycache__/asn1.cpython-38.pyc,, -Crypto/Util/__pycache__/number.cpython-38.pyc,, -Crypto/Util/__pycache__/py3compat.cpython-38.pyc,, -Crypto/Util/__pycache__/randpool.cpython-38.pyc,, -Crypto/Util/__pycache__/winrandom.cpython-38.pyc,, -Crypto/Util/_counter.cpython-38-x86_64-linux-gnu.so,sha256=-8wyPt4xwYdGeHnfTmzYJqjesu5UHvvZTdlEaa0QNzU,22856 -Crypto/Util/_number_new.py,sha256=DMlYTwTLefBEAMX139gjP9uDdvyamloCC0kc2oaNQYg,3976 -Crypto/Util/asn1.py,sha256=2eg7T1XMaNDo340pAq9BuO9Hp_1mYf5cWgkfFW97bGQ,12733 -Crypto/Util/number.py,sha256=P_MYzcU9oVwwJAjCQ_AAYmqPsTZrWf-G2j5TiHkdCts,95469 -Crypto/Util/py3compat.py,sha256=e-a4R1jOOvsNeb5CHqNPUhEKa-Qa0Ozwhyu4iwcbDFE,3908 -Crypto/Util/randpool.py,sha256=8qSQTg_aPf6RUHlCNZJQXQ5LZClvydNWaFqEDaG-FEE,2768 -Crypto/Util/strxor.cpython-38-x86_64-linux-gnu.so,sha256=xfCPtgkJehM3uVE4aEViOVeRF0jl4K42PgEI1iJ64ts,16784 -Crypto/Util/winrandom.py,sha256=IhpE9uIOdNmWXmjzSICrTKEVoP0XOxasaTi4m2afB5I,1196 -Crypto/__init__.py,sha256=Bi_KjWxdfCyFeRx_abV-wr3o89SsH7c9fEwx0oLgjiA,1992 -Crypto/__pycache__/__init__.cpython-38.pyc,, -Crypto/__pycache__/pct_warnings.cpython-38.pyc,, -Crypto/pct_warnings.py,sha256=Uc2DAGSs6rZGMssd2SNkLzpF-h0CwwH288Alv3SzCeM,2295 -pycrypto-2.6.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pycrypto-2.6.1.dist-info/METADATA,sha256=1l-9AVgkccANEeeXZ29e95C1BWovYM_VeUb1T4Lat0g,656 -pycrypto-2.6.1.dist-info/RECORD,, -pycrypto-2.6.1.dist-info/WHEEL,sha256=TpFVeXF_cAlV118WSIPWtjqW7nPvzoOw-49FmS3fDKQ,103 -pycrypto-2.6.1.dist-info/top_level.txt,sha256=-W2wTtkxc1QnPUPRqBZ0bMwrhD8xRD13HIobFX-wDOs,7 diff --git a/frozen_deps/pycrypto-2.6.1.dist-info/WHEEL b/frozen_deps/pycrypto-2.6.1.dist-info/WHEEL deleted file mode 100644 index d193dea..0000000 --- a/frozen_deps/pycrypto-2.6.1.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.34.2) -Root-Is-Purelib: false -Tag: cp38-cp38-linux_x86_64 - diff --git a/frozen_deps/pycrypto-2.6.1.dist-info/top_level.txt b/frozen_deps/pycrypto-2.6.1.dist-info/top_level.txt deleted file mode 100644 index e6645e7..0000000 --- a/frozen_deps/pycrypto-2.6.1.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -Crypto diff --git a/frozen_deps/pycryptodomex-3.9.9.dist-info/AUTHORS.rst b/frozen_deps/pycryptodomex-3.9.9.dist-info/AUTHORS.rst new file mode 100644 index 0000000..bdafc82 --- /dev/null +++ b/frozen_deps/pycryptodomex-3.9.9.dist-info/AUTHORS.rst @@ -0,0 +1,49 @@ +Simon Arneaud +Nevins Bartolomeo +Thorsten E. Behrens +Tim Berners-Lee +Frédéric Bertolus +Ian Bicking +Joris Bontje +Antoon Bosselaers +Andrea Bottoni +Jean-Paul Calderone +Sergey Chernov +Geremy Condra +Jan Dittberner +Andrew Eland +Philippe Frycia +Peter Gutmann +Hirendra Hindocha +Nikhil Jhingan +Sebastian Kayser +Ryan Kelly +Andrew M. Kuchling +Piers Lauder +Legrandin +M.-A. Lemburg +Wim Lewis +Darsey C. Litzenberger +Richard Mitchell +Mark Moraes +Lim Chee Siang +Bryan Olson +Wallace Owen +Colin Plumb +Robey Pointer +Lorenz Quack +Sebastian Ramacher +Jeethu Rao +James P. Rutledge +Matt Schreiner +Peter Simmons +Janne Snabb +Tom St. Denis +Anders Sundman +Paul Swartz +Fabrizio Tarizzo +Kevin M. Turner +Barry A. Warsaw +Eric Young +Hannes van Niekerk +Stefan Seering diff --git a/frozen_deps/pycryptodomex-3.9.9.dist-info/INSTALLER b/frozen_deps/pycryptodomex-3.9.9.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/frozen_deps/pycryptodomex-3.9.9.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/frozen_deps/pycryptodomex-3.9.9.dist-info/LICENSE.rst b/frozen_deps/pycryptodomex-3.9.9.dist-info/LICENSE.rst new file mode 100644 index 0000000..23f8f33 --- /dev/null +++ b/frozen_deps/pycryptodomex-3.9.9.dist-info/LICENSE.rst @@ -0,0 +1,274 @@ +The source code in PyCryptodome is partially in the public domain +and partially released under the BSD 2-Clause license. + +In either case, there are minimal if no restrictions on the redistribution, +modification and usage of the software. + +Public domain +============= + +All code originating from PyCrypto is free and unencumbered software +released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +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 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. + +For more information, please refer to + +BSD license +=========== + +All direct contributions to PyCryptodome are released under the following +license. The copyright of each piece belongs to the respective author. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +OCB license +=========== + +The OCB cipher mode is patented in the US under patent numbers 7,949,129 and +8,321,675. The directory Doc/ocb contains three free licenses for implementors +and users. As a general statement, OCB can be freely used for software not meant +for military purposes. Contact your attorney for further information. + +Apache 2.0 license (Wycheproof) +=============================== + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/frozen_deps/pycryptodomex-3.9.9.dist-info/METADATA b/frozen_deps/pycryptodomex-3.9.9.dist-info/METADATA new file mode 100644 index 0000000..c519e01 --- /dev/null +++ b/frozen_deps/pycryptodomex-3.9.9.dist-info/METADATA @@ -0,0 +1,84 @@ +Metadata-Version: 2.1 +Name: pycryptodomex +Version: 3.9.9 +Summary: Cryptographic library for Python +Home-page: https://www.pycryptodome.org +Author: Helder Eijs +Author-email: helderijs@gmail.com +License: BSD, Public Domain, Apache +Project-URL: Source, https://github.com/Legrandin/pycryptodome/ +Platform: Posix; MacOS X; Windows +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: BSD License +Classifier: License :: OSI Approved :: Apache Software License +Classifier: License :: Public Domain +Classifier: Intended Audience :: Developers +Classifier: Operating System :: Unix +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Topic :: Security :: Cryptography +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Requires-Python: >=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* + + +PyCryptodome +============ + +PyCryptodome is a self-contained Python package of low-level +cryptographic primitives. + +It supports Python 2.6 and 2.7, Python 3.4 and newer, and PyPy. + +You can install it with:: + + pip install pycryptodomex + +All modules are installed under the ``Cryptodome`` package. + +Check the pycryptodome_ project for the equivalent library that +works under the ``Crypto`` package. + +PyCryptodome is a fork of PyCrypto. It brings several enhancements +with respect to the last official version of PyCrypto (2.6.1), +for instance: + +* Authenticated encryption modes (GCM, CCM, EAX, SIV, OCB) +* Accelerated AES on Intel platforms via AES-NI +* First class support for PyPy +* Elliptic curves cryptography (NIST P-256, P-384 and P-521 curves only) +* Better and more compact API (`nonce` and `iv` attributes for ciphers, + automatic generation of random nonces and IVs, simplified CTR cipher mode, + and more) +* SHA-3 (including SHAKE XOFs) and BLAKE2 hash algorithms +* Salsa20 and ChaCha20 stream ciphers +* scrypt and HKDF +* Deterministic (EC)DSA +* Password-protected PKCS#8 key containers +* Shamir's Secret Sharing scheme +* Random numbers get sourced directly from the OS (and not from a CSPRNG in userspace) +* Simplified install process, including better support for Windows +* Cleaner RSA and DSA key generation (largely based on FIPS 186-4) +* Major clean ups and simplification of the code base + +PyCryptodome is not a wrapper to a separate C library like *OpenSSL*. +To the largest possible extent, algorithms are implemented in pure Python. +Only the pieces that are extremely critical to performance (e.g. block ciphers) +are implemented as C extensions. + +For more information, see the `homepage`_. + +All the code can be downloaded from `GitHub`_. + +.. _pycryptodome: https://pypi.python.org/pypi/pycryptodome +.. _`homepage`: http://www.pycryptodome.org +.. _GitHub: https://github.com/Legrandin/pycryptodome + + diff --git a/frozen_deps/pycryptodomex-3.9.9.dist-info/RECORD b/frozen_deps/pycryptodomex-3.9.9.dist-info/RECORD new file mode 100644 index 0000000..6cea692 --- /dev/null +++ b/frozen_deps/pycryptodomex-3.9.9.dist-info/RECORD @@ -0,0 +1,794 @@ +Cryptodome/Cipher/AES.py,sha256=fbD_h8DbAF4NsFKrbhKz5sMFnqKYUza0XqT4k9f1SpE,9569 +Cryptodome/Cipher/AES.pyi,sha256=3ahEn43wmFv37xdmnlibzjWOmRAgSSeiFToFMIoLVUk,1387 +Cryptodome/Cipher/ARC2.py,sha256=NwO42KWBpuTXS5Thx0gsDRmxyrvfiudx7PKed1KR0CI,7026 +Cryptodome/Cipher/ARC2.pyi,sha256=zgMfUY35w1AuEi0apkFuHo_NQOfzsCxuZ9gN1s3oAhg,982 +Cryptodome/Cipher/ARC4.py,sha256=x_8L_KA_pDkoeIOSCQZyVPwhD3na4-xShkPkeNRka58,5168 +Cryptodome/Cipher/ARC4.pyi,sha256=sMw73yZHeonmGx9BhiyA7__4PQJocU04SMRcDjnyJ2Y,431 +Cryptodome/Cipher/Blowfish.py,sha256=K5hF6nb2r8FsHhgLX2irdyUMqg4PCwrAgu68NNhU1ag,5976 +Cryptodome/Cipher/Blowfish.pyi,sha256=kDooazMxY1973SMtPuhNJ9f68PS4cNWynyYa7CoWC48,1018 +Cryptodome/Cipher/CAST.py,sha256=3XDjtVBsia2kPvducB19_FEc3zM7hSK8JKKmK-b8cvU,6087 +Cryptodome/Cipher/CAST.pyi,sha256=XgVk9wOv_V77LbQmm24O2R-PDss8JiHfw11karavKCI,983 +Cryptodome/Cipher/ChaCha20.py,sha256=u7YX0kO9MBwV7Ibt_Dbyz_pHq-TG5POxoRnNOGy9ZPs,10754 +Cryptodome/Cipher/ChaCha20.pyi,sha256=_l1xhtOyBmYEHP7Ftmk8EQZpKegX9p3N5tckC_PPve0,762 +Cryptodome/Cipher/ChaCha20_Poly1305.py,sha256=W0tOmBkoNzfwtwgPG9Tw0dUm3sZ8IVhnehTbAc2jRt4,11561 +Cryptodome/Cipher/ChaCha20_Poly1305.pyi,sha256=h1U5ixODzM9NwLpX9oaIJdeQ0ubYeDeY9m6ur05dKCc,1068 +Cryptodome/Cipher/DES.py,sha256=ebgHOqNGjCYlIoFh3W5KXY17aQnvckjhQC9TPEKqPuY,5963 +Cryptodome/Cipher/DES.pyi,sha256=thNZATxZ0Q-vOh_V7QVZu6J_ESvr9mcA67WlQV_nP1A,963 +Cryptodome/Cipher/DES3.py,sha256=qmIagOLhMGG221sC7BAH9xe5lnxk2iyilbeYoC3it4c,6941 +Cryptodome/Cipher/DES3.pyi,sha256=arv4Uhv7lSgAL36B_Vx5DL-s_18Kc9_TejNxftMp4H4,1033 +Cryptodome/Cipher/PKCS1_OAEP.py,sha256=GtxJWWSmK5PCIc1xFZDkMucGmPrioWBRB3M3T_VeVDY,8880 +Cryptodome/Cipher/PKCS1_OAEP.pyi,sha256=XRZ5_0v8w2LUYD04Gz3Ekey9PxYBZJnUl-0rVv2q_gY,1183 +Cryptodome/Cipher/PKCS1_v1_5.py,sha256=IeTKcgsUJSYzct2EzvL0cPg4d2F7SjUMGjTQ4HjxnUc,7979 +Cryptodome/Cipher/PKCS1_v1_5.pyi,sha256=XzzxTLrPfBUqROLd-hhDua4w6YrzI7xjLmHrQN__Xck,571 +Cryptodome/Cipher/Salsa20.py,sha256=SuzaYhBc_Q7voODDmQ2rCzILndPpmF1n6qitDMmk7no,6369 +Cryptodome/Cipher/Salsa20.pyi,sha256=4vjq_HN8NK7U9VdaaHIgs17-fyW8SRPDZaHy3jKVkto,744 +Cryptodome/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so,sha256=bFvUKemyW2bXoEsC2HdV35dgQgtR8S7m6eLRNhAXSi4,14354 +Cryptodome/Cipher/_EKSBlowfish.py,sha256=fi6TEeN0bXcznFkyLzsaoLxNmu9iPT-Tmp3CLvJsE0A,5217 +Cryptodome/Cipher/_EKSBlowfish.pyi,sha256=6JhAXsSVbJMYlcudpNwSNEDB9X5NjhfRGPzZvcOc_As,270 +Cryptodome/Cipher/_Salsa20.cpython-38-x86_64-linux-gnu.so,sha256=LyVUPFhUIQoJx0QaXx0FkwZC0nmZGILsrE3uoTXsIw0,21734 +Cryptodome/Cipher/__init__.py,sha256=Cdau3A_ZsmqOFM8yK4Q2C_hFeV2xjd9_fU812_ferXM,2888 +Cryptodome/Cipher/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +Cryptodome/Cipher/__pycache__/AES.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/ARC2.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/ARC4.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/Blowfish.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/CAST.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/ChaCha20.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/ChaCha20_Poly1305.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/DES.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/DES3.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/PKCS1_OAEP.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/PKCS1_v1_5.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/Salsa20.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/_EKSBlowfish.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/_mode_cbc.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/_mode_ccm.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/_mode_cfb.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/_mode_ctr.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/_mode_eax.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/_mode_ecb.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/_mode_gcm.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/_mode_ocb.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/_mode_ofb.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/_mode_openpgp.cpython-38.pyc,, +Cryptodome/Cipher/__pycache__/_mode_siv.cpython-38.pyc,, +Cryptodome/Cipher/_chacha20.cpython-38-x86_64-linux-gnu.so,sha256=xCnihlEf-dEc4-Zq5sOpUBcuHEcYfhw58nJLvkt_n_o,25741 +Cryptodome/Cipher/_mode_cbc.py,sha256=cDaa-zgNIbosLHJhwsDtt7YOTE-jzRUi4ODfj95SBsM,10971 +Cryptodome/Cipher/_mode_cbc.pyi,sha256=qH5pEQNuefabeRV-Xz-6AA953MFd_Z20zGeBTwa6t0s,691 +Cryptodome/Cipher/_mode_ccm.py,sha256=zqq91jARvmdPXs58u0uCP-D8ctzsg65Lf8nW9VQYezs,24476 +Cryptodome/Cipher/_mode_ccm.pyi,sha256=ZSs4SOlivIG_JUxknDjQKs4ZYGmkwAO7K2DKcbz_14M,1600 +Cryptodome/Cipher/_mode_cfb.py,sha256=lfIeHxJmyqmBWk84d4z9030OooTSBX1gfaVIaRqIPyE,10821 +Cryptodome/Cipher/_mode_cfb.pyi,sha256=PM0slBBfWdA4Ec0JjM-OJheiZkCFPWAADvLsvKpDRCY,731 +Cryptodome/Cipher/_mode_ctr.py,sha256=PFiqbWjboWaeLv0M0GnE4o8_vv6h7Aedv5cNq51VNlU,15920 +Cryptodome/Cipher/_mode_ctr.pyi,sha256=UcZ1zOZlVnTSlka9R1yFo7kaDhreiLKCe7AU05AcAuI,804 +Cryptodome/Cipher/_mode_eax.py,sha256=XXOc-GKbZ2hRagr5I5FihKWaGh8hXP1Si2kY3D85-ls,14543 +Cryptodome/Cipher/_mode_eax.pyi,sha256=VHPtTdA-2btCvRE-4npRtGCrApg7rBNWpHSZV1po8J0,1545 +Cryptodome/Cipher/_mode_ecb.py,sha256=h81F3mNQc08dVr__iP3_41ixeul00OsDw9mCI_Bh7I8,8222 +Cryptodome/Cipher/_mode_ecb.pyi,sha256=PgzUPsVY2DRM72wM-h74vCiceNF_yeaBxOA6bt_ZfmA,596 +Cryptodome/Cipher/_mode_gcm.py,sha256=oAOWTQ1qynOv7BfuueXokEF1TghERzKOXEgHKMj50wg,21402 +Cryptodome/Cipher/_mode_gcm.pyi,sha256=5t72QHQS0gDq6wtzYfaVqTxmjBzpUvsQvDaP2DqNvLE,1541 +Cryptodome/Cipher/_mode_ocb.py,sha256=QeHiPunUGWKt4iG8A50xgWV9b3C7qW0uwJPRcta5bC8,19838 +Cryptodome/Cipher/_mode_ocb.pyi,sha256=SXMUa1s1dY-272lktxSOtyOoqLdtPvfNkRXqmXjBE4o,1231 +Cryptodome/Cipher/_mode_ofb.py,sha256=sXdbumASGN-K7ps89z7c-knnMnnYtuO97X7y-VYZvyA,10301 +Cryptodome/Cipher/_mode_ofb.pyi,sha256=mPIZ2e_X-URk-8LBNiZyacfcS3Ei1vgT8YlhyI-0C8k,695 +Cryptodome/Cipher/_mode_openpgp.py,sha256=whIc90qioqxMiL2RCys5-XwfDntDneVYJx4Br6X3zD4,7061 +Cryptodome/Cipher/_mode_openpgp.pyi,sha256=FoLrFqnvxJf0F_npHOgPURfUyGSt6DxyIp2ikoXi-CI,556 +Cryptodome/Cipher/_mode_siv.py,sha256=nRqGJBjqxmKikUpVBLgMN3TGwg2f3boCNtUtGcn9uEU,14094 +Cryptodome/Cipher/_mode_siv.pyi,sha256=syb3kXnyuhoQV6FXvozIjudWCQBCadOb1I2BuV-6Ai0,1261 +Cryptodome/Cipher/_raw_aes.cpython-38-x86_64-linux-gnu.so,sha256=XItknsf2UUYW6JTafj9EiURNPq87iPbpU7MZsxstgvM,54112 +Cryptodome/Cipher/_raw_aesni.cpython-38-x86_64-linux-gnu.so,sha256=9SThqIhzfGdPQ_KGthp7Zf6_HwJ37LKk69bXn1miAlI,52331 +Cryptodome/Cipher/_raw_arc2.cpython-38-x86_64-linux-gnu.so,sha256=P_bLzcdq-ErD_QIP554zqCsKh5T4j6tag0Nr8B-9TOQ,18917 +Cryptodome/Cipher/_raw_blowfish.cpython-38-x86_64-linux-gnu.so,sha256=qpJcyzPSThz-wLRFqvzllniT56b7srYSSJVXFpVpxI8,26938 +Cryptodome/Cipher/_raw_cast.cpython-38-x86_64-linux-gnu.so,sha256=GKXmI8Brnf70GZO4Ewcsfaod5W7C4lGOomlHD8AxoD0,44422 +Cryptodome/Cipher/_raw_cbc.cpython-38-x86_64-linux-gnu.so,sha256=djug00p4Co5fTF90S4DloDEmnOHx94K0aFE57DCb1n0,17215 +Cryptodome/Cipher/_raw_cfb.cpython-38-x86_64-linux-gnu.so,sha256=IH-UyapBP38NwDAGVlG7zU1aVaYG05NFGRp_8z9ZYCQ,22696 +Cryptodome/Cipher/_raw_ctr.cpython-38-x86_64-linux-gnu.so,sha256=MBDwyhkt0HsQFCGnyb-aD5y_YRn78gY02Eik1Dite44,23249 +Cryptodome/Cipher/_raw_des.cpython-38-x86_64-linux-gnu.so,sha256=8RP468xPFfr5eTZHWvuAuft4MIk-BGQ61u4h82b6nZw,62525 +Cryptodome/Cipher/_raw_des3.cpython-38-x86_64-linux-gnu.so,sha256=gVRpZJLUtQJ2FZypbVn-v4vFi6JLT1nQsiERbLT4xK0,63370 +Cryptodome/Cipher/_raw_ecb.cpython-38-x86_64-linux-gnu.so,sha256=DWruIGvT5Yibn7gNdmoCf05Ug03nRkmtSZI5WlG2MRE,10893 +Cryptodome/Cipher/_raw_eksblowfish.cpython-38-x86_64-linux-gnu.so,sha256=0P3HCyU6I1CQoQpqIH37qOVpTzvzAIkglPiM7SpDHyc,58926 +Cryptodome/Cipher/_raw_ocb.cpython-38-x86_64-linux-gnu.so,sha256=SGNBSgyJzNmKRDzt_qxUvQxxwAPRpRTS_HRjqZLv1_8,30281 +Cryptodome/Cipher/_raw_ofb.cpython-38-x86_64-linux-gnu.so,sha256=YjayUPJO7GrvYEn_zHCyA87uDH4hlIvr8XwLX8qiqbE,14743 +Cryptodome/Hash/BLAKE2b.py,sha256=WEV8u2cm18T_j9BwjCDPaSJ6AappqpwO1u7mHG6Sgnk,9440 +Cryptodome/Hash/BLAKE2b.pyi,sha256=9FsubGLHkCf6aPA5xZGVSop8WY4yLCWi3Vq53cGiSNo,877 +Cryptodome/Hash/BLAKE2s.py,sha256=uBxYbWDZleCmsOvSEmVRXPywTS2TM-qq3oyN4FJp68c,9446 +Cryptodome/Hash/BLAKE2s.pyi,sha256=9jsL4jLQq5_Mb8WM99LPurH1D-FL-gLAeZyBf8QiWt0,739 +Cryptodome/Hash/CMAC.py,sha256=06Hyo7r7XAgklKXWp7tttTiZFqKRTGINigxkEgWh6WY,10448 +Cryptodome/Hash/CMAC.pyi,sha256=8gybenApjooarPbVIWZohcOruj0tMyZuW5gJvrK_Vag,797 +Cryptodome/Hash/HMAC.py,sha256=pp450gCQNmw4vUfrQAJyDZ_h1ovwd-8wLvoyqd9t5hU,7062 +Cryptodome/Hash/HMAC.pyi,sha256=fAyHBEf5Ee6LoiYYTZ9PZpmIRvitU6OriKGfjFUM_4c,624 +Cryptodome/Hash/MD2.py,sha256=mfucNRXYIj8iOXGKEXGN4TIwyHHhIglb2ScSowyg5tc,6123 +Cryptodome/Hash/MD2.pyi,sha256=wa7GSYUpzL27so4YgiJEZo0dO201KyHK87Q20Pvm-bM,492 +Cryptodome/Hash/MD4.py,sha256=FSGY7k8rYayR6PE0hNpICRTa1uNiISVxixIpaC28zzg,6598 +Cryptodome/Hash/MD4.pyi,sha256=7ZtZQEgJCwIswneb0NBov_uL0_Toglh9EPMnLVFGqwo,532 +Cryptodome/Hash/MD5.py,sha256=Cd5wtZ4OBW-O7tvebvObsay_jI6tRtoUfIfkbE0aqMQ,6630 +Cryptodome/Hash/MD5.pyi,sha256=c4MCJHvYTi2YL4hmqEu9ivbSvkBJdR-S2ldUqEpzK8s,492 +Cryptodome/Hash/Poly1305.py,sha256=xESe_sBaJg7jBJE88_S3jWU0uIu8l18NaQjmol_uIeA,8106 +Cryptodome/Hash/Poly1305.pyi,sha256=TSGottirLPIRyivSjZucQB7aPaYfhrUkn8oot6OrmmU,665 +Cryptodome/Hash/RIPEMD.py,sha256=0oRaGuKcTUVTfBZXZm5NZLQAvyPbAhjBpgzN5Kf2a6g,1211 +Cryptodome/Hash/RIPEMD.pyi,sha256=-DzZk9OtiAZE-E2_PCyFz4pHQ3RouoLlUo3Neabf3Sc,98 +Cryptodome/Hash/RIPEMD160.py,sha256=GYDiBSw_D7SCOPA80i3l3mjZsPvmmhZSVVENKwkUs_k,6410 +Cryptodome/Hash/RIPEMD160.pyi,sha256=RQ9yXxjH1BSaU3mwhsCn9-67C0a_Bcv3MDdafQCiuPs,516 +Cryptodome/Hash/SHA.py,sha256=1-O3GFKbm1ht2jV7M9pdKu6GpACsCSnARPHllFcFTAo,1156 +Cryptodome/Hash/SHA.pyi,sha256=RJHp4vuV_19StgE4qxlnIfDltgFjx-L9q6H0tjh-Rk0,169 +Cryptodome/Hash/SHA1.py,sha256=oyz9PdGgaVa90S6O1NPhe7OPq7AvDbJIsH6pICDpTN4,6702 +Cryptodome/Hash/SHA1.pyi,sha256=vNtB_b4MytJq8Io1xufdOO6VL-nMBcCnDPIgJQuNPCM,536 +Cryptodome/Hash/SHA224.py,sha256=RQ3ECOkVJsnh2a5fCPL7Aienpi22lcpsuRNUypkWfBs,6913 +Cryptodome/Hash/SHA224.pyi,sha256=8RsbyIwIfO8Fc_fpWw1MnFw04Z4n-qL0G01qCQZwvx8,544 +Cryptodome/Hash/SHA256.py,sha256=2fhVNPGKrifj49B0ExaxrMCubtDTcQiHarrzN0JPVUA,6909 +Cryptodome/Hash/SHA256.pyi,sha256=zndNEjv6DZOWaOpuoUKsA2hTi2J7-oJFgOQ10sSRnXE,612 +Cryptodome/Hash/SHA384.py,sha256=aDu5NdDbICyrSt2sj0N4fIWwGurEu08WYB5mMiqfW7g,6911 +Cryptodome/Hash/SHA384.pyi,sha256=KIWbD-lBbd7lvWgFquIqUAMaisovey0HV0Nmmq-pvOY,544 +Cryptodome/Hash/SHA3_224.py,sha256=eoXfnjBCNjCD8nNxE8-S4vR7XJZBY11Xf6Lk__fNzU8,5302 +Cryptodome/Hash/SHA3_224.pyi,sha256=Dv2Xk6o9Sm1kcUMeo8sbuuP32HqQhEo_dV9p8yAyc0k,504 +Cryptodome/Hash/SHA3_256.py,sha256=z9IiiZvVV_J3Fpbl8c7-mjDMB_q-5Hrdx1tZpNxLy4A,5302 +Cryptodome/Hash/SHA3_256.pyi,sha256=MLvrZYxvRJ0l9TiGq2axjs66_13px5XlUx_lugQTVxM,504 +Cryptodome/Hash/SHA3_384.py,sha256=dGiHZHjbeU-Ul7zjQnpGfQebLWjixnVAtK_kPMNxIFY,5302 +Cryptodome/Hash/SHA3_384.pyi,sha256=pciFn3aMYw23Y3MZhAbf-cqXuyHIlI27qAmDo-6VtJY,504 +Cryptodome/Hash/SHA3_512.py,sha256=etHVIzMn11RfjalnGPGHqE3G_7iXxwffrh3Gh7ja5fo,5304 +Cryptodome/Hash/SHA3_512.pyi,sha256=HxxfMXlsnZ42ZQ_2YxWZU7aBdGhDPEtAT4EIF77kRzU,504 +Cryptodome/Hash/SHA512.py,sha256=rmSnd1Rka2NCImO0e-suLbzAF9EEXrY1ipnnS8RlG-Q,7732 +Cryptodome/Hash/SHA512.pyi,sha256=VfMzHx-0U4efCyZCrgs_aOz17W8t0ZHL_3uR8zaYzCU,622 +Cryptodome/Hash/SHAKE128.py,sha256=wNVbtzVBie6jczEfjiGjtRflEPEeYWji8CgHK5oak5c,4656 +Cryptodome/Hash/SHAKE128.pyi,sha256=wLhV8lh8YYWzi7PkhAB3_JQn_hOZNvkiZYg-JjiPpfs,437 +Cryptodome/Hash/SHAKE256.py,sha256=dBCwFGVqbythJH6Zy7tGVgtZKo5WCXFP9LVZICEvHjg,4656 +Cryptodome/Hash/SHAKE256.pyi,sha256=9Uq_FaeYwDx_6dLv331Wv1snnGxA2UhFcUdELHkwU9U,437 +Cryptodome/Hash/_BLAKE2b.cpython-38-x86_64-linux-gnu.so,sha256=TszE3R0aDpiryAo6AYj6sOyeUCuOV1O_qoWGSxUIOW8,20015 +Cryptodome/Hash/_BLAKE2s.cpython-38-x86_64-linux-gnu.so,sha256=5IuREhBw3LMMax7ws8i3xNwUf9hRhiviNgYsqu1JMFY,20807 +Cryptodome/Hash/_MD2.cpython-38-x86_64-linux-gnu.so,sha256=6JKEXGjwn3jffmux4Syh3LY1gY1vjCF-pa2OE8dHyJE,16919 +Cryptodome/Hash/_MD4.cpython-38-x86_64-linux-gnu.so,sha256=J-t1w8Jf51EpWYC7DUJk22uBCVgdVl1yFgTntYg9Piw,19072 +Cryptodome/Hash/_MD5.cpython-38-x86_64-linux-gnu.so,sha256=-wohxwVJRlUgJoJgtrJdRs0DCtjT67AYObjbtcRjhqc,25434 +Cryptodome/Hash/_RIPEMD160.cpython-38-x86_64-linux-gnu.so,sha256=Xa2c7tVD_7Qn-Zqx5RoWhad9uXkwvtQDFkzGCQNt6cs,27226 +Cryptodome/Hash/_SHA1.cpython-38-x86_64-linux-gnu.so,sha256=xTMo-GOZ7R3XAGVtwYHh3eInH66rJE0erLkToaI24uY,84273 +Cryptodome/Hash/_SHA224.cpython-38-x86_64-linux-gnu.so,sha256=QrWYibmzohwXUyqhfrb7Eb62f0oMXEKAV7NCO-s7uUc,35822 +Cryptodome/Hash/_SHA256.cpython-38-x86_64-linux-gnu.so,sha256=GZg9EMGcEzxNzFddlDMUKih4zZJ8nEwpnWo4gfOk2io,35806 +Cryptodome/Hash/_SHA384.cpython-38-x86_64-linux-gnu.so,sha256=uAbYxVoN7kiMPGtm89lzSomGqeexJ1Vt91JaJCpMUWU,41869 +Cryptodome/Hash/_SHA512.cpython-38-x86_64-linux-gnu.so,sha256=ED19YH2nMlNTNGT5DyWRW1fD3R0ItQMY3qRDEckqtGM,41967 +Cryptodome/Hash/__init__.py,sha256=jxsjQHZzCkphA6DkKfV200k5U6ipBEXf2YI__PQua7s,1119 +Cryptodome/Hash/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +Cryptodome/Hash/__pycache__/BLAKE2b.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/BLAKE2s.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/CMAC.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/HMAC.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/MD2.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/MD4.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/MD5.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/Poly1305.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/RIPEMD.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/RIPEMD160.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/SHA.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/SHA1.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/SHA224.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/SHA256.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/SHA384.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/SHA3_224.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/SHA3_256.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/SHA3_384.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/SHA3_512.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/SHA512.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/SHAKE128.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/SHAKE256.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/Hash/__pycache__/keccak.cpython-38.pyc,, +Cryptodome/Hash/_ghash_clmul.cpython-38-x86_64-linux-gnu.so,sha256=jlP-qmQqsu7X0ujoJgm6Jrr7Fm56k4gx3f7I6QMmB00,34203 +Cryptodome/Hash/_ghash_portable.cpython-38-x86_64-linux-gnu.so,sha256=GOThQjY5Ahc4_kVcRAXMWzFKMf1uiKkbqbj_6DZ2dzs,18711 +Cryptodome/Hash/_keccak.cpython-38-x86_64-linux-gnu.so,sha256=F9ha1YMuXWPL9-HEhfyOOuGY6GOkoIyjHSxIh37h9Ig,26749 +Cryptodome/Hash/_poly1305.cpython-38-x86_64-linux-gnu.so,sha256=M0HF762RLGF4PmslwV16dqAp2p8jhLAnhEKg3F7qF0w,25921 +Cryptodome/Hash/keccak.py,sha256=a6uqDYaAveDMk73ZAK4q2D1GkzHyEmnOgE91Fi5BnsA,7118 +Cryptodome/Hash/keccak.pyi,sha256=pXAZaNfayZCXMxB7IDFr2F8Hi06_hwFB3GXjNzY7sBM,741 +Cryptodome/IO/PEM.py,sha256=TPPdUiCHLEauwRAIZ1Y0uxtIGzz5Vz5eF5EZsP3dGRc,6972 +Cryptodome/IO/PEM.pyi,sha256=a1G07RQtZvEtXHlybxdDcoTPM3nqMbdONNjzcz5HGtE,303 +Cryptodome/IO/PKCS8.py,sha256=z-WihBqgcebhhkkK6jcuXE3-4i34RCXJlqefF3qaOg0,8711 +Cryptodome/IO/PKCS8.pyi,sha256=VxlDc05DEKa1DJ6lGPMbyuFC8XHTjm-pvviw90phLpU,474 +Cryptodome/IO/_PBES.py,sha256=ZAoljR3_saaEGvNmv1Zjkcp-Up925t6lH0GHbPAzZP4,16352 +Cryptodome/IO/_PBES.pyi,sha256=QWJLbYh7ywy2wlRWnbUQG_hqlv6zfobF5o6FKh7reWA,489 +Cryptodome/IO/__init__.py,sha256=QUvnoDWlmuOGEjxXh_uXHMoSmoPi_nSeh-Et7MSofeg,1540 +Cryptodome/IO/__pycache__/PEM.cpython-38.pyc,, +Cryptodome/IO/__pycache__/PKCS8.cpython-38.pyc,, +Cryptodome/IO/__pycache__/_PBES.cpython-38.pyc,, +Cryptodome/IO/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/Math/Numbers.py,sha256=2fQR0NxDh4r8rxGGrIahadGXQ5ssQb2nNPuhC1O9S0Q,2042 +Cryptodome/Math/Numbers.pyi,sha256=DBEdhel2f5i097pHa5ZTccxyGf0rKfhXtJP4GiNbP_Q,88 +Cryptodome/Math/Primality.py,sha256=dElcPU2SbxTu3E5IGj_S18W4tEXMkI0AJNEz8Xd8f54,11352 +Cryptodome/Math/Primality.pyi,sha256=iXAY0gUmciIS_FvH5VJwhQfK-0tDmaH2vcDLHHFyxIE,823 +Cryptodome/Math/_IntegerBase.py,sha256=4fofn-eRAi5h_RTX4w44_fh-S_r36GISV2nbLtjUJ5w,10486 +Cryptodome/Math/_IntegerBase.pyi,sha256=8robOel28h7YCFIOEWhW-DtJE1GLzdowmDkWyUaWQR8,3417 +Cryptodome/Math/_IntegerCustom.py,sha256=viV3iZBDGkLLqsfBgY0ebmaAyXjTRdEKaMc5fi_J6x8,4016 +Cryptodome/Math/_IntegerCustom.pyi,sha256=s9UZigBEgUvHS4IOdt8jXhsZ33O9j19p7lieob1R-EY,135 +Cryptodome/Math/_IntegerGMP.py,sha256=kWG3VAWTzO1lJO0cpS5rk0Vb3ldplAHNpF3yu4ry69c,25317 +Cryptodome/Math/_IntegerGMP.pyi,sha256=UcJOGMYT1d-G0PjbC5ByShFl5oyorFR8h38fFt0uY9s,78 +Cryptodome/Math/_IntegerNative.py,sha256=j-v3xELayy7C0lOgOlDR4hyUDHc0TzUIguUBh1tJDn8,11076 +Cryptodome/Math/_IntegerNative.pyi,sha256=pZaN1xXnB8u7VfrMgp6jqi_jCaJ4x4t0Ecs7qZ_2x-4,81 +Cryptodome/Math/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +Cryptodome/Math/__pycache__/Numbers.cpython-38.pyc,, +Cryptodome/Math/__pycache__/Primality.cpython-38.pyc,, +Cryptodome/Math/__pycache__/_IntegerBase.cpython-38.pyc,, +Cryptodome/Math/__pycache__/_IntegerCustom.cpython-38.pyc,, +Cryptodome/Math/__pycache__/_IntegerGMP.cpython-38.pyc,, +Cryptodome/Math/__pycache__/_IntegerNative.cpython-38.pyc,, +Cryptodome/Math/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/Math/_modexp.cpython-38-x86_64-linux-gnu.so,sha256=UjtwotV2UVN7d8J1re7ErZ75kvBvA1RFffcroyjmjJM,207274 +Cryptodome/Protocol/KDF.py,sha256=nmwDb1qTj5fHNSWZdLVwl_CyjlbOjM6rUDSl8wNLcUM,19897 +Cryptodome/Protocol/KDF.pyi,sha256=OfuAajDDJIDIny-zMuGsfhqCLZr4x8bZnV5Tonbg00E,1383 +Cryptodome/Protocol/SecretSharing.py,sha256=ZNw_YhVs4TYrJ7075g6WwaiiCJRRmy0fpT_LoEMV3Ww,8794 +Cryptodome/Protocol/SecretSharing.pyi,sha256=-lErV2RvaNPuOA0z4c44WmNSu9irCw_DDb7wPgCS2BY,798 +Cryptodome/Protocol/__init__.py,sha256=eXlh5nJVd6NoXfUjJ-mNGgm5oE8r6MYDBOIHXWdzTPw,1548 +Cryptodome/Protocol/__init__.pyi,sha256=RNdrwMgjt9b9LmckdRkaYYC4PCzNV-1Hi2T3B2MHgds,43 +Cryptodome/Protocol/__pycache__/KDF.cpython-38.pyc,, +Cryptodome/Protocol/__pycache__/SecretSharing.cpython-38.pyc,, +Cryptodome/Protocol/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/Protocol/_scrypt.cpython-38-x86_64-linux-gnu.so,sha256=RAIsDgb0Bgzraim44UGmPeISIJH4VWDCEinZbDAfDg8,16510 +Cryptodome/PublicKey/DSA.py,sha256=r3Vo6fyCWAngyfI8hWsrOms9Srj_lvzIfoHcdlwFMCM,22363 +Cryptodome/PublicKey/DSA.pyi,sha256=Q4s-ZAx5xV8ue2lxfVhOtQQzYuawu3qhDz0O5ThoLdM,1353 +Cryptodome/PublicKey/ECC.py,sha256=62eaTeNl_6VcHjwyaA28vcjmWM-WEKMnFdq-3GOr8Lk,42053 +Cryptodome/PublicKey/ECC.pyi,sha256=KhDMYrqTioBcZa0FWeMdJelJWmN47M2KWfS7y78ILVw,2358 +Cryptodome/PublicKey/ElGamal.py,sha256=qe1JXZRLCnMQO8u892VZA80u92IBXnTq-rV0CcvMKa8,8631 +Cryptodome/PublicKey/ElGamal.pyi,sha256=-s3ty0v_o-8Rq8_nrYh32Vo6ihr8OaSWdc_H7_CVGCo,674 +Cryptodome/PublicKey/RSA.py,sha256=jn4L8zDEPRB1haBoVKikrgUb9cOl5Dg2fU2gYiGx7J0,28834 +Cryptodome/PublicKey/RSA.pyi,sha256=53HgZFdczCzVYl8hVQLay9RA0KqcVBGtyKG0u2r5S-8,1837 +Cryptodome/PublicKey/__init__.py,sha256=2yP0pjkXKBr0C0QA5xS8Jxd9nHz9VT5uoNIS59KC4Kw,3123 +Cryptodome/PublicKey/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +Cryptodome/PublicKey/__pycache__/DSA.cpython-38.pyc,, +Cryptodome/PublicKey/__pycache__/ECC.cpython-38.pyc,, +Cryptodome/PublicKey/__pycache__/ElGamal.cpython-38.pyc,, +Cryptodome/PublicKey/__pycache__/RSA.cpython-38.pyc,, +Cryptodome/PublicKey/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/PublicKey/__pycache__/_openssh.cpython-38.pyc,, +Cryptodome/PublicKey/_ec_ws.cpython-38-x86_64-linux-gnu.so,sha256=FAVYikDHr6gC6vLsL4BE-v0mI0olLJ9GbxYXyB3APZ0,1000375 +Cryptodome/PublicKey/_openssh.py,sha256=t8Z8fOJDh64ZXmqpSCqlds-OKb2C5FncQmqCstfGImM,5146 +Cryptodome/PublicKey/_openssh.pyi,sha256=ywCy9UDu2_AQI60ChWxGxyqHiZoYwMKC3TVXJn_ZVIM,324 +Cryptodome/Random/__init__.py,sha256=EJnd9lTXo5ZFvmgrAzv2wHX8b87SNPO3sDGB3UofVe0,1813 +Cryptodome/Random/__init__.pyi,sha256=ieifhoMB2veKusRRBZWQp6igPri5027VrqfddO5b-WU,367 +Cryptodome/Random/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/Random/__pycache__/random.cpython-38.pyc,, +Cryptodome/Random/random.py,sha256=aWcD7vA4eWrRmjIkho-YGxbrVC3anFTzHa_N_7Sds64,5246 +Cryptodome/Random/random.pyi,sha256=Lgo1h6wtyUDhEuroDRyt-eYvPFEgQOo0fxfAE68S2cM,807 +Cryptodome/SelfTest/Cipher/__init__.py,sha256=nI0MW4-BVQHwCwYqgWxa7MhL9OxYmwYSIJcp5qe_n9Y,3708 +Cryptodome/SelfTest/Cipher/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/common.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_AES.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_ARC2.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_ARC4.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_Blowfish.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_CAST.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_CBC.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_CCM.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_CFB.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_CTR.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_ChaCha20.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_ChaCha20_Poly1305.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_DES.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_DES3.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_EAX.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_GCM.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_OCB.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_OFB.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_OpenPGP.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_SIV.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_Salsa20.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_pkcs1_15.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/__pycache__/test_pkcs1_oaep.cpython-38.pyc,, +Cryptodome/SelfTest/Cipher/common.py,sha256=HpeH9ouK2m5kcrfcb0vRSw2q1LehsuicQfGuT1jnclg,17016 +Cryptodome/SelfTest/Cipher/test_AES.py,sha256=PpAFYq6sGbzd-tFNi--37LLD-hI_A6KCw4J5DB5nlDo,71827 +Cryptodome/SelfTest/Cipher/test_ARC2.py,sha256=gOXQEu0PBG3vD7D_sT7y0AqfrXfAA4U-qsbArNOujBI,6550 +Cryptodome/SelfTest/Cipher/test_ARC4.py,sha256=5YgyIIhAn1_Ca5q3Sh2Cx1yLsQhrZK6t0aQdAVtdCdo,24749 +Cryptodome/SelfTest/Cipher/test_Blowfish.py,sha256=fC6tYqaKzCuo7gIqyenNsoxvS-hSyC8FAkqUIadrv_w,7318 +Cryptodome/SelfTest/Cipher/test_CAST.py,sha256=WjrbmsHybravO0qPALVVyBRskQTlRiemhsh-ud5MvxU,3367 +Cryptodome/SelfTest/Cipher/test_CBC.py,sha256=dr5yzeU-HaLlTFVaJeRjm59uZuJYjdQqFvFAPoWNSDg,20419 +Cryptodome/SelfTest/Cipher/test_CCM.py,sha256=FB0ElwRqrWNUlOmeNup21HC2MVCxRObrRzG_8UJ2WVw,38039 +Cryptodome/SelfTest/Cipher/test_CFB.py,sha256=WNkgDVTR1BacaVPnVDscddLFkfAUENfABdR6enu4CtM,16162 +Cryptodome/SelfTest/Cipher/test_CTR.py,sha256=X2d0y1ZktQd29BxgEmeiC86OIUGgVrl_41dOuxJyHX0,21402 +Cryptodome/SelfTest/Cipher/test_ChaCha20.py,sha256=0Aj4tJWSxW8Lbn5EbXk9PyNbTDB9zIOK4_a4k0-NBYQ,20017 +Cryptodome/SelfTest/Cipher/test_ChaCha20_Poly1305.py,sha256=pKisgjpYWUB6GE-Vj9U_wdWzNGArBIYTF0fXwvKhKXQ,31070 +Cryptodome/SelfTest/Cipher/test_DES.py,sha256=5nGk-NGJg4iap191mOJgiNpLgjZ38Qwq_5oktYz58cs,16027 +Cryptodome/SelfTest/Cipher/test_DES3.py,sha256=DnPIMMsAf2N-yl0j7JILr1GGvJNzAi3A4Qsi3P-3HE4,6724 +Cryptodome/SelfTest/Cipher/test_EAX.py,sha256=b-qiqzx_wpBUDaQ1cgybM5V_Eoh_dJte3TMn4-uFTpc,29491 +Cryptodome/SelfTest/Cipher/test_GCM.py,sha256=p-4TGNvjhCY2EZl1HrVpxU5X0o3cE4BYJP02u3x5-MM,38246 +Cryptodome/SelfTest/Cipher/test_OCB.py,sha256=-lvM3XRSouW29b1m3bhhno4TgKI9TUI2DKxBbfd1dCA,28406 +Cryptodome/SelfTest/Cipher/test_OFB.py,sha256=bKcBCLL39YIz8xr0YEGySWWJxxzQ6pgmRLZv2FxCxUo,9327 +Cryptodome/SelfTest/Cipher/test_OpenPGP.py,sha256=Q4rOCU0axh_z7U4MSUGda39nujktPlBUaqVVfE5kMhs,8497 +Cryptodome/SelfTest/Cipher/test_SIV.py,sha256=h_SPw8YaOZOQ4Bw7BCRms9K7qbfY5byDzLbisDLNtbA,21125 +Cryptodome/SelfTest/Cipher/test_Salsa20.py,sha256=1AuzeYLpnYhuzdqqbdkUguIpZlT7kbbpParNYF220QY,16767 +Cryptodome/SelfTest/Cipher/test_pkcs1_15.py,sha256=s_t7dHvCIKc-QobF8CJHZcRsb1Q4qRUslxEkih19ZVA,10594 +Cryptodome/SelfTest/Cipher/test_pkcs1_oaep.py,sha256=s8-2D2puFnmmUcbRkcXro8h1CE4cAhYO_8_rYjChwV0,22998 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCGFSbox128.rsp,sha256=jU0y_RjZc7Rae4Ra71JZdnuZjOVYRxAp1IGe4aYSabY,2787 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCGFSbox192.rsp,sha256=fjvAZvU59Szb-jHISNXS2eJwyxCNSfUUZtuj4EBBL3k,2609 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCGFSbox256.rsp,sha256=V9hpYePiv0Idf-261mYVpmHGtDFVA10iyd8R-x4dKpc,2367 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCKeySbox128.rsp,sha256=dbpmQvcgZvrPzNBCOxGnqCQuEKuKvLOZWP8ECuNw-V4,7990 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCKeySbox192.rsp,sha256=lr4vtlL_4gVhySVIlxg01kVY351NpTNfhutiXPLENYI,9874 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCKeySbox256.rsp,sha256=JELpUAjt036FZn87hQAiV4bwz3rXlHjR2ZStkB9sM4k,7154 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCMCT128.rsp,sha256=jk8YVL-7jYSPWGHPshIQTfYb1tEUKXiSYArqP7ovJ2Q,37376 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCMCT192.rsp,sha256=LTXLqH_ODWAW53y2Xe_bdALPxDjTOhMtyvAlvtN-9Gs,40576 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCMCT256.rsp,sha256=I7H3lzMhXUSCCp6MTV8y2GKwnyHkCng7DglNkVeVmL0,43776 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCMMT128.rsp,sha256=hgKmNyD7pJJbFBOF9ZC-8z4Q0qYcLJPX8wsLgIzLJ74,9654 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCMMT192.rsp,sha256=kxK_gWyWXZMpsixh-Nfz5zTpwORBDEvDdHh_Wys7bBI,9974 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCMMT256.rsp,sha256=vfQ3mslBnS4ejLIFaGEapETh8rTvfTuUOK-kNqlwBLc,10294 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCVarKey128.rsp,sha256=CG8rZuSGmdaCofMPCRv-RBlW8CymmSNf49_s_HBsr9E,47849 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCVarKey192.rsp,sha256=IK1mvGNLPgnAyNACs3RsXPItkRb4RKcm9ZYQPZkzn1M,77929 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCVarKey256.rsp,sha256=3AyzgBafQ6g8Sv-G7rFG1YYafgJHkIEG-Lb9N5Aul_g,112105 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCVarTxt128.rsp,sha256=NuIPk6FOKn_HyvD0eKbMUEMelNXn203qZkLFhDx4fd0,47849 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCVarTxt192.rsp,sha256=myc4SHgTQ_R0NslkNNBvxIemJm8ycws1mt0fvoPOX3M,51945 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CBCVarTxt256.rsp,sha256=E8WwhsZMgW5D_8ZXtgLP5qcjG-qCl-vJqWsJMtNR8VU,56041 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128GFSbox128.rsp,sha256=PetBa4V9l8tZucoVdmnTcG2yxGmXV5zggGAs6BjyJrM,2790 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128GFSbox192.rsp,sha256=4pLczu5j53_ZEJN3QbGtb9s1BPckiwM-B4Xy9FEmmfc,2612 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128GFSbox256.rsp,sha256=2U8vwvdS2yN5UPGAxKcHq7jHwFymgHfCGbNNyg5nshE,2370 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128KeySbox128.rsp,sha256=o87VaOGVb2A0vBEzf8wxTcgBKdJ7qyv5aTNDJrdbgSk,7993 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128KeySbox192.rsp,sha256=aOrrWPE21kdquhb2-NF7BV__wJh2VfWXyZ2yEoezwGI,9877 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128KeySbox256.rsp,sha256=PM1Kl9FkTLqkBPAXKuk_0hjbi-ktnL21YZ6UZJ4oaKQ,7157 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128MCT128.rsp,sha256=qssStFCa3Xi9-x0RB3Y4hQUXqw1vAwXnH-cc8vuQonI,37379 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128MCT192.rsp,sha256=uvFr2372lGeK9DD4S1ulwwqAXusEkc3Aok7Zbu6-WME,40579 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128MCT256.rsp,sha256=ptLz5OsPykXQx_j4_BxRX1OWRxKbRsdfvGFG0hi6uBo,43779 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128MMT128.rsp,sha256=QysTd7nANa2-aYZZtjeSnvqjfkmsiBasoMN1FqmsRQw,9657 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128MMT192.rsp,sha256=SCubxxY-Xz2uJCsD_N3Gm4PcH0f_Gfrj74Opar0mIJU,9977 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128MMT256.rsp,sha256=C2AkiXUSrDlMAxFKkaPxdDBQH0Codt4YDWAI4To_H34,10297 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128VarKey128.rsp,sha256=lMpe6dc1E2S1BTK1CSJubsXCNUcylc1Juyj0CjZX0v8,47852 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128VarKey192.rsp,sha256=JRwBrwNDy5npksDoi1UwjnL40vGWEeJG7cezM7Ep50w,77932 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128VarKey256.rsp,sha256=rfwz1yvXvU4DN2ZxNkPFE5wajQcREZbO76mvOo_GLsQ,112108 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128VarTxt128.rsp,sha256=UFUNsGaH5PAijmRJ3wli320O0u4smpQMvxKLaTr-aU4,47852 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128VarTxt192.rsp,sha256=a52sEs1Sn_A1CMD16vC-mHDAw_CD2dZcGJolAcFC46U,51948 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB128VarTxt256.rsp,sha256=_FRB9oN5Q-KyVVbNMsnLionMBYFVfx7CX_rSb9Lmg5o,56044 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8GFSbox128.rsp,sha256=hMQY14LzloH3lWaW5Wa_w_xrPmYC_4-mkt5zbjlSyY0,1948 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8GFSbox192.rsp,sha256=PINYd4KRk623-kA7c13ekEWrxbrhidZOTNQVWCZSw9M,1890 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8GFSbox256.rsp,sha256=VUbW4eab0v3SNO5BRdNcd6bGXxaZ4thkxOfq6S7Dw-U,1768 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8KeySbox128.rsp,sha256=lXccJkglpMet2HdG_hVxPHUA5T9ye7w3RNtXbROqz2Y,5471 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8KeySbox192.rsp,sha256=dde2y-QM22fXMMdRL6A8DIofghIZihRBxmC2w3HZMy0,6995 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8KeySbox256.rsp,sha256=41SLZ_y0h0qdyzfHWhYSkzu2e7SDes8nTzHvpvkdd40,5235 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8MCT128.rsp,sha256=D3yf9MGKx78BNoN4GkNnHFwco6enBlY_G0wf07FEPxc,25377 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8MCT192.rsp,sha256=MQumbDtwDZOOVY66sOODkLjiygHMwRF5iwDC1_7RpdM,28577 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8MCT256.rsp,sha256=DxHJ-AmB8z--Ly3Kt_inweIwUVECXWgBXvujaIbD5kY,31777 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8MMT128.rsp,sha256=lP20fsuv0fqhnbdWG-YiHiDp8tNPjdVuIRc3wiE20nE,3055 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8MMT192.rsp,sha256=sBqsFN3TMkQO7Zbl7I_n8sloD52zxeLgiq5zYH4Oyy8,3375 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8MMT256.rsp,sha256=4NOc6LASPWEnD-50boVm5MomaWhYTYbQhzLCPybGddo,3695 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8VarKey128.rsp,sha256=mvHAmSr092Z32a3kveZlNruin3zWe2tIQpqqfWTeXPI,32490 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8VarKey192.rsp,sha256=01L3kHeD-LqSfE--mpFjnGGkeenqOSas8s-I82Vfpw8,54890 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8VarKey256.rsp,sha256=6Aooiamd3pB-ZUOmrBcsCbaXwR7BI-i9QCM5tWY9r40,81386 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8VarTxt128.rsp,sha256=jrHzMizQegT39uay0-m_U_fCYRp2SXSNNb162zb4m9w,32490 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8VarTxt192.rsp,sha256=D3mN2TULDZ9UWIB5GfZo27SlYSUCCpN1pSCOpf9gQvA,36586 +Cryptodome/SelfTest/Cipher/test_vectors/AES/CFB8VarTxt256.rsp,sha256=PMX7Tm87AiMU17lrRB5SBlgUkfCQMurFhZ8U1gXd_DM,40682 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBGFSbox128.rsp,sha256=NqmhVuhGhk3KiDpdoLHj2aStP0mrQ8ltYMAWPf09V7w,2787 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBGFSbox192.rsp,sha256=i8YFQ_bSRpAARg3o0cypWgXVNg4LJQEpaT-MueuBi80,2609 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBGFSbox256.rsp,sha256=QQvrbGgDg13HR6sG9Y4NYJG9Fno1GiDhksD7WsbEnGI,2367 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBKeySbox128.rsp,sha256=zYZzoBHZJywm8-PXGkdh0M92lt69q1Xlez6pT36jXyM,7990 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBKeySbox192.rsp,sha256=LpaZlABRpjAHBI6Wb5FrgtYQCgYiqQJ5pA5LgoS6sv8,9874 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBKeySbox256.rsp,sha256=sJzuWVShDIACWoUw9ZKIfuPG4bBl9dqvZ0_nWV5Ykvg,7154 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBMCT128.rsp,sha256=AW0pmMOE2FdpcJOY0OUT6AluNbIJmY4ymqsTryRBj_E,37376 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBMCT192.rsp,sha256=hff1UxqKGO1wIP9SQ2g6OCWsoBdnivefOw0SrKkX-q4,40576 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBMCT256.rsp,sha256=8ixrgFsp_27dSKskpR0Omy9FE6nQw9Q3ZiwJwadbK_s,43776 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBMMT128.rsp,sha256=aEps11PAOdDX_p5pzR8IrK4oLaGal6NVHYTvimGheV0,9654 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBMMT192.rsp,sha256=UN9R1JN8LPSgp7m-YVbnwrxw5u6wu9_n39T5vQmleMY,9974 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBMMT256.rsp,sha256=ULROQmjB5MnVIhWgp2mY8hNbTzxZsw10EtMDPncNq40,10294 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBVarKey128.rsp,sha256=-wNByOr7EMG_6ZXa3usWmI7DE6SxaYhCJiZHQhrrMQY,47849 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBVarKey192.rsp,sha256=aAE8BEABWnKPgbvs2OtQCb5UAOLVoC3X8gDfZd4mw20,77929 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBVarKey256.rsp,sha256=2Pzwktz9Ff5i7lNCvHqjmD1pYDUCCjpsGoOBDfbhUeQ,112105 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBVarTxt128.rsp,sha256=Jowo6O7I1UKWPGQUBL6lPKOVbSQecaTv4eFJoihGrmA,47849 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBVarTxt192.rsp,sha256=DjaxbJUulI8uZ9Aw_N-f5OZijPScGK-1A62TbI19eag,51945 +Cryptodome/SelfTest/Cipher/test_vectors/AES/OFBVarTxt256.rsp,sha256=bupYeO4v-gv_bLKAgIV4CN6_J4odWn11xE7boL8Qjtc,56041 +Cryptodome/SelfTest/Cipher/test_vectors/AES/README.txt,sha256=60TZ8t3yT6VSsa8Em-WuA3U8b4YZxo5ZacUyGq6G890,360 +Cryptodome/SelfTest/Cipher/test_vectors/AES/gcmDecrypt128.rsp,sha256=DR-Y0Mnhdu3h8-hUhN0T3pLDQ2ypffN47DSB4EwZpzI,2748606 +Cryptodome/SelfTest/Cipher/test_vectors/AES/gcmEncryptExtIV128.rsp,sha256=MBViNvdosNgeWKPlvTvXnOKUz57wugqEz3uGnInr2f0,2930939 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/README.txt,sha256=hDeBnqtd185cf-MlzMsAUHtTQMTQA3AWXlRwieQu_NE,195 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCBCMMT2.rsp,sha256=w9zaXFSlBUkSgOd9EIv-uJjZMd5Kq4CCh1Mw39Ef5SI,6492 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCBCMMT3.rsp,sha256=01k6aw7y1P3YU1O1tMGJxfzU_hQTSv-cu-ZFLwUoO0I,6492 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCBCinvperm.rsp,sha256=_zs_hHhOHk8R0jqalJfZv5W9YLR0JZwouXlUNVb4D70,15890 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCBCpermop.rsp,sha256=Jo3PnThZZS_EbimNgAhLZ_885v2CYFgUSKrLzInKvpc,8020 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCBCsubtab.rsp,sha256=5900Cila5IOo5VpUDtrB8RDRtOIPWsrroTAGsc4oULM,4819 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCBCvarkey.rsp,sha256=2lA8JmREU52Vp9X5pJWQa6rLCMzGYnUDi5VG6Yr5CYA,13915 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCBCvartext.rsp,sha256=6qE0bIigNfJslrVQDGWZV7YkXBG3-hwOgjsuIhzyQrc,15900 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCFB64MMT2.rsp,sha256=TpBVhZUmX2C4sRoCDROvQDuQv5gVOk0aFxm1pp6bfA4,6494 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCFB64MMT3.rsp,sha256=mMwx1bCOtw0AcJrsYxrhmBycW4B3VaHvfgPGHrnpHKs,6494 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCFB64invperm.rsp,sha256=BVMb18Mm1Hin3tgHjnxrfPSb4P4Y2mvfh2B9V5Zy9Xc,15892 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCFB64permop.rsp,sha256=6ZwOKZ5Ej8ErjfZEnWOBT19WgTx5Uyq6j0bi1Qr6Vu8,8022 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCFB64subtab.rsp,sha256=RPLhWK13522rsiUgBnbgCk57_yDSEbqtXY1QZy8SRQA,4821 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCFB64varkey.rsp,sha256=whxavgBPUbeGwSAlDqy1wWgELMtQs9PQE0LUzFzcBsY,13917 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCFB64vartext.rsp,sha256=DCRrqKJ3cE7sPTd5Nov00szLB3UsZvhhIIlYyXClhjM,15902 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCFB8MMT2.rsp,sha256=BtKIJNMPMQiuTRUb2GVrFYPfeMkFvGUkpzfQcj9hmKo,3413 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCFB8MMT3.rsp,sha256=iR2pfe1o2D6uXaWhYIyI104EiwMoSh_xQvlACak2jdc,3413 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCFB8invperm.rsp,sha256=y1BhaDajhJK6sgi_WoCpivnunEcQz3s_YP6S0cx5cYY,12307 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCFB8permop.rsp,sha256=UunDHgTlkgu5SX-_rbwru7Cb14r71p_52mGgk1eA4Yg,6229 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCFB8subtab.rsp,sha256=Pz9gt4Yg56ZhpJaNdWIXm0rrEuFgRDVJE3BSRXRXB4I,3756 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCFB8varkey.rsp,sha256=OUnAab1XVxlUkcHR0hpZM4WzF4aLnkbPorYPs3LeLlk,10780 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TCFB8vartext.rsp,sha256=4qzDlfCrKSgqizeSaWSSCbdMXu7wWupnWYI2J9Zy0JM,12317 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TECBMMT2.rsp,sha256=iD7ZSuiJkln6dzwrs9CmSXt6nd-rkVK1dOQ7Yvuq-jM,6032 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TECBMMT3.rsp,sha256=4jD9aPnKbr9QvC6bBzzznaFXknd2ryXoUG2UyAXxVz4,6032 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TOFBMMT2.rsp,sha256=90ejMmcQJAAva5oDHZfVFtV8PfJwcCAJ-VZvrvdVP4M,6492 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TOFBMMT3.rsp,sha256=0C3349hXpEGwP8fryw8jAzo2yxlxHUloeMyALrFyxEg,6492 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TOFBinvperm.rsp,sha256=jhBskIqunOstw3z9ECnLPjY3le5CV3GkbsZimghIFik,15890 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TOFBpermop.rsp,sha256=9kwCTwvwrMICoK13_yYU9l8mJk_5N5_91bqMFm56aws,8020 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TOFBsubtab.rsp,sha256=sVfYcy66WOKFcT4vfy_ykavEt8fFP-5TzUNdR0gs5sY,4819 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TOFBvarkey.rsp,sha256=HmcozNR9lqGmiNcyI9QqAI3GasIQfkuWK6LmE52A2Ak,13915 +Cryptodome/SelfTest/Cipher/test_vectors/TDES/TOFBvartext.rsp,sha256=kkrk9qQzO-tzAH0YYR4QtyGQAfyiu_JQ8vIv0-KcvBg,15900 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/aead_aes_siv_cmac_test.json,sha256=pUC3FoitW8wK8OntE4DlwN7iquDH9BLRRf5uBta3kGI,405682 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/aes_ccm_test.json,sha256=zus5i_I7cLNlM2essEx__Ae4NrtPlJ3Wo3AwfTJbpQA,236978 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/aes_eax_test.json,sha256=iYDZEI3B_4j0OXdyfii49rIDQeaWpq-HKBC6J5WND_4,84816 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/aes_gcm_test.json,sha256=xj96NNX0m-Uvjy9aXEd1C0GK8wQmWGn3fNS6y44dL1E,133455 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/aes_siv_cmac_test.json,sha256=weGSoUbwEUmiIjpWUHs6y2XT0rVgxZFcGcxGwLKh4v0,177708 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/chacha20_poly1305_test.json,sha256=S17zmflWIUIn2lScioTZ0JdTjACj0THeV0ithQgQWuw,196184 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_2048_sha1_mgf1sha1_test.json,sha256=k3KUn7gP3nLejBN_1jsVYlXKn-o2iQQzQ-pZZBFVkLo,35337 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_2048_sha224_mgf1sha1_test.json,sha256=DB8sKJtW7C6MixB6xl-LGZqUTxGRBYyOFNUAAezkvp4,27669 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_2048_sha224_mgf1sha224_test.json,sha256=gomskn7LU4tbT0n6z3CqDNgIuGrv_k31OzJcN3gG_e4,32722 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_2048_sha256_mgf1sha1_test.json,sha256=qn09ZvlxI2FtRB1j6nkjht9PGLV3AuRyVrp9S9fMzbc,27647 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_2048_sha256_mgf1sha256_test.json,sha256=BjZddqcYpQxuI1WDknKJIDrt8MRt-WUf4l2QqSbf7rU,36411 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_2048_sha384_mgf1sha1_test.json,sha256=ou0E0xKYvocIgueLOXXGVJqvJm5WRsVoFjVJGE9UoDU,27583 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_2048_sha384_mgf1sha384_test.json,sha256=ssgZNn8L633XaGD8mBL1lkk7HgZrMNKoY2VkHoUM5Zc,31284 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_2048_sha512_mgf1sha1_test.json,sha256=pCZoGS3QUPDbRjs5-evo_Yp95r-RJBlZoA_Et8E8IKc,27517 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_2048_sha512_mgf1sha512_test.json,sha256=rof_1bNM5JD2FFAISphMxFD6upRpDo6MZnBNQmKI8y0,29546 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_3072_sha256_mgf1sha1_test.json,sha256=gd8cnYuJlqQP18DopU4aMaOOtp_MQslrdjBtkstmTr0,38507 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_3072_sha256_mgf1sha256_test.json,sha256=zY8aRXZ7ZiyDsuizeprFoRMN2Pmp9FrJzrtqH2vvtwo,49871 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_3072_sha512_mgf1sha1_test.json,sha256=2eh490VoYTgj0dtpM9aFIVrNvtH59sxDonPiQ3SZ60s,37409 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_3072_sha512_mgf1sha512_test.json,sha256=KEr7XjVuzjRdG1qfVjBWVGEdUhY2mg9zD6jf9Q8VPyw,40890 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_4096_sha256_mgf1sha1_test.json,sha256=WNIxqjFQnECM-q0FqGBHMU8UqXffYunrgDtWF3z1Yd8,48665 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_4096_sha256_mgf1sha256_test.json,sha256=W5PFMgMBr7LrftEMF41eUXtk5gOWYTaPdzy0r1y4McQ,63366 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_4096_sha512_mgf1sha1_test.json,sha256=-iuHeAw8VvKt0LGqa6dS16KVvOlbZIftcaKqpkDx1TI,47299 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_4096_sha512_mgf1sha512_test.json,sha256=MgaDMR-MzZxxcCpTuHkJNprvGsQV-gUOzVTDstNREy0,57400 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_oaep_misc_test.json,sha256=jMh3_BLOIzzV1QZUbWxe4mNwVkmHF302u6wJki3SITk,1262220 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_pkcs1_2048_test.json,sha256=UoeSkKnXl60751hJ_G7856k8YhkfMHNH2EAx5eFQsF0,292951 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_pkcs1_3072_test.json,sha256=2DTy-Osluiq2MqrzmAHqxACQ5HK1a2BMQGpXW2ZdP88,423258 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/rsa_pkcs1_4096_test.json,sha256=ZIMdsdGrwxFehQuFZCCKp40l3uZKH5WcvXUstDuxku0,551672 +Cryptodome/SelfTest/Cipher/test_vectors/wycheproof/xchacha20_poly1305_test.json,sha256=F4Kso6XhhcUv1Xa5aGfoEeJKV79II0u59xN0K1MDlOk,181687 +Cryptodome/SelfTest/Hash/__init__.py,sha256=um4TKfVp-bYbGRIbSdPzy2Tal_tEmREk0NiJkCTRwz4,3533 +Cryptodome/SelfTest/Hash/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/common.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_BLAKE2.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_CMAC.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_HMAC.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_MD2.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_MD4.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_MD5.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_Poly1305.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_RIPEMD160.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_SHA1.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_SHA224.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_SHA256.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_SHA384.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_SHA3_224.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_SHA3_256.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_SHA3_384.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_SHA3_512.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_SHA512.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_SHAKE.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/__pycache__/test_keccak.cpython-38.pyc,, +Cryptodome/SelfTest/Hash/common.py,sha256=C2jFAjRERl6uCNr12bwRTTighWDRpNiyAbXVfc-iSl8,9964 +Cryptodome/SelfTest/Hash/test_BLAKE2.py,sha256=vpPxSXeaZGIo6iprJCASNjuz4pW8epk1gK3C0ygjgwA,14953 +Cryptodome/SelfTest/Hash/test_CMAC.py,sha256=tj7t9augqONo539ZaxxXuNGMShgPMSs3ZNDj4RJBGHs,13946 +Cryptodome/SelfTest/Hash/test_HMAC.py,sha256=S-oBHJeQ4M8xdSfuq1IjYQB3BVqADGwC4aXpoFAGBc8,13568 +Cryptodome/SelfTest/Hash/test_MD2.py,sha256=ElKzN0tL3U-0TeLVP0e7I8txskHXSA8Ys63aYjLW_BM,2336 +Cryptodome/SelfTest/Hash/test_MD4.py,sha256=9SFHZcbB3M2AhjYtK-Y9w0tWE_cdmeo2QrHvl3f9S4U,2359 +Cryptodome/SelfTest/Hash/test_MD5.py,sha256=Bj6C548u8dz0d-pGxg7JZlezPWuXfD_TBnj7QOJGtxw,3300 +Cryptodome/SelfTest/Hash/test_Poly1305.py,sha256=2_ZTIuatKcaI0ATBGQm0DicKnXMTUqdu1nC7g6rNg10,18406 +Cryptodome/SelfTest/Hash/test_RIPEMD160.py,sha256=V1q7YGF0xKe0DeXZhAmtc4hIbbDKhEpjkNfPsNkB-qE,2675 +Cryptodome/SelfTest/Hash/test_SHA1.py,sha256=CrQWc1iCeKmVauPe5KqrBS4kt2qE2Ocwf365BOThGPM,2960 +Cryptodome/SelfTest/Hash/test_SHA224.py,sha256=Dz7sRLuh-AJZXarIZ7Lza4ZUy9tNNT5pUSsAm5Q6Ax0,2541 +Cryptodome/SelfTest/Hash/test_SHA256.py,sha256=pmV4r5WojFZmtVWAIFAl1uO55GO7wMWXCdE_I2e87J0,3637 +Cryptodome/SelfTest/Hash/test_SHA384.py,sha256=6_hL7uoZdQYAEoC0gT2mYuZQuCELHe9ebxcFhQZd4BM,2722 +Cryptodome/SelfTest/Hash/test_SHA3_224.py,sha256=S3PBL2Jqiby-Fmrj8SfU9OHoIL6ggCkWT8wbBJ69kBo,2874 +Cryptodome/SelfTest/Hash/test_SHA3_256.py,sha256=gQIzg3vguubWE2m3Dg0GiKXrWU_0aEQUvYjO5HE_LjE,2875 +Cryptodome/SelfTest/Hash/test_SHA3_384.py,sha256=iKXhYtyaa85GiNJ5y0C97JSWy2JLAR88bwZEgt-jttY,2874 +Cryptodome/SelfTest/Hash/test_SHA3_512.py,sha256=Z05p5vkxaJFoaxuPtZuFJTZxMyqRfzIFPE3z9SuBZmY,2875 +Cryptodome/SelfTest/Hash/test_SHA512.py,sha256=dGVeICdKxE_4mmpgewgEjnqzxDU0_ZYr5qt4LKMIO9c,5302 +Cryptodome/SelfTest/Hash/test_SHAKE.py,sha256=e5J4G8UNR-h5_ucZL_iqr1GlyWUY0ILyvOgqmYiGz-0,4786 +Cryptodome/SelfTest/Hash/test_keccak.py,sha256=ZdxMKcZf5zTOjcguA2HBnreYFZYWUwKBlsvPqyw6v1E,9160 +Cryptodome/SelfTest/Hash/test_vectors/BLAKE2b/blake2b-test.txt,sha256=6DYRIlZ96-rzmjXAmmoGiEIsAQqnQpIWnJqbDM26AkY,135750 +Cryptodome/SelfTest/Hash/test_vectors/BLAKE2b/tv1.txt,sha256=_fgZKswUlDW4iyAtEb4h0XcjY0edq6M0CyfEE1g0ncQ,4741 +Cryptodome/SelfTest/Hash/test_vectors/BLAKE2b/tv2.txt,sha256=hejftkYHZ5waIFHWX_OacTNfVyfdIwWhuzF0lL1KKps,9060 +Cryptodome/SelfTest/Hash/test_vectors/BLAKE2s/blake2s-test.txt,sha256=nH7O_rr67tH8etckN_qAoRu6BTAi0Oa8EIvyNaVMijs,102983 +Cryptodome/SelfTest/Hash/test_vectors/BLAKE2s/tv1.txt,sha256=sO6d-SWvAMOwzjMuLNZR8K2eb7QLIzOBk6L7omqcg9k,1413 +Cryptodome/SelfTest/Hash/test_vectors/BLAKE2s/tv2.txt,sha256=v6M_7bwZO3a7V4KXowFt93wWHudF1M5A1_2BWHz4OcI,2564 +Cryptodome/SelfTest/Hash/test_vectors/SHA1/SHA1ShortMsg.rsp,sha256=vgmR3cU3KTLVWASxFxPJFA0QQ170sxagdz41Bu7HnNo,8735 +Cryptodome/SelfTest/Hash/test_vectors/SHA2/SHA512ShortMsg.rsp,sha256=5To2wDYJ5aPjzEtuEXpJnbeGTCPsglxs7JlQOkX0B2Q,36800 +Cryptodome/SelfTest/Hash/test_vectors/SHA2/SHA512_224ShortMsg.rsp,sha256=mxH7Jf8I2McI4JiiLQE8XTjAaNHjmOtXPSBVwFO__nU,27536 +Cryptodome/SelfTest/Hash/test_vectors/SHA2/SHA512_256ShortMsg.rsp,sha256=2NUAi3P5DLkqj41NmvdFgJzu9Hr0y-su4kXMaxU_UiM,28568 +Cryptodome/SelfTest/Hash/test_vectors/SHA3/ShortMsgKAT_SHA3-224.txt,sha256=1eLWO-0-QY5KJRsFVYuMsZxZJUqid5fQdoYf62TK0UU,86195 +Cryptodome/SelfTest/Hash/test_vectors/SHA3/ShortMsgKAT_SHA3-256.txt,sha256=RvFAFF5Dz74xTtmOI-6rlwdLm9g3q6ToCZCSdTwWjgA,88243 +Cryptodome/SelfTest/Hash/test_vectors/SHA3/ShortMsgKAT_SHA3-384.txt,sha256=iyqT-Rq0yO5R6eYMQnnlEynzNYvT1fMjEb1TetruOZw,96434 +Cryptodome/SelfTest/Hash/test_vectors/SHA3/ShortMsgKAT_SHA3-512.txt,sha256=pImzhhuDKlqdHvspZxdke4Ovym8Cgfdw-5gQtni4BTI,104627 +Cryptodome/SelfTest/Hash/test_vectors/SHA3/ShortMsgKAT_SHAKE128.txt,sha256=-GOrJL52VikLqOrNLo_dW6vAuoikrIwv_M8yE-cC20c,333928 +Cryptodome/SelfTest/Hash/test_vectors/SHA3/ShortMsgKAT_SHAKE256.txt,sha256=wRVs94lIiWRqphXKojGwqWxi_BjtbNOToZwvLuT0C_4,333928 +Cryptodome/SelfTest/Hash/test_vectors/keccak/ExtremelyLongMsgKAT_224.txt,sha256=Z8BU0nZzRihAAARK2JV-gbZKBkeEPF1meRld4oOyJLU,316 +Cryptodome/SelfTest/Hash/test_vectors/keccak/ExtremelyLongMsgKAT_256.txt,sha256=wDRraKgIR_Bb--u3qjgRDI_4JuDYY3k8CERjWlfXcO0,324 +Cryptodome/SelfTest/Hash/test_vectors/keccak/ExtremelyLongMsgKAT_384.txt,sha256=J1aO_Asi6jHQkLvNqqQX0ct3IjlGSi_X2dKi886PhJw,356 +Cryptodome/SelfTest/Hash/test_vectors/keccak/ExtremelyLongMsgKAT_512.txt,sha256=xCXigswYKQjijTOnSo6YfMKbWNu-p_RnR0-WKdR2zy0,388 +Cryptodome/SelfTest/Hash/test_vectors/keccak/LongMsgKAT_224.txt,sha256=ORAzRQYztzHLW1kiQcKViaDpOFDmxRWlVH55E57axYo,300741 +Cryptodome/SelfTest/Hash/test_vectors/keccak/LongMsgKAT_256.txt,sha256=0GA-RoRMyaobz-mZsxR0FAYaGJax0yDeCMo7AidY6JA,301261 +Cryptodome/SelfTest/Hash/test_vectors/keccak/LongMsgKAT_384.txt,sha256=lcfkQiEcCvCDWCAPxrLtAjVIVtqftH9iUohS38DMlDQ,303341 +Cryptodome/SelfTest/Hash/test_vectors/keccak/LongMsgKAT_512.txt,sha256=Z9a9BYUTLD92OdA2FR15LhIcqStLBnAAZSeJqf6dggo,305421 +Cryptodome/SelfTest/Hash/test_vectors/keccak/ShortMsgKAT_224.txt,sha256=4GBcFh1vLSJXYo7p-TRHHnHvp43NgyPgXjV69KZolzA,85946 +Cryptodome/SelfTest/Hash/test_vectors/keccak/ShortMsgKAT_256.txt,sha256=qo_vZ44ayILxErUnmTwnKwOBndsWRgk9ER9GDh2r2nY,87994 +Cryptodome/SelfTest/Hash/test_vectors/keccak/ShortMsgKAT_384.txt,sha256=TmfukzxIOlEHEFfahvDDuOtrebZhSaGUcNggUv8_ywY,96186 +Cryptodome/SelfTest/Hash/test_vectors/keccak/ShortMsgKAT_512.txt,sha256=3-33JR9udHo5AELPPPFLu12Y4ltAjxkSa6HPgn3s0yI,104378 +Cryptodome/SelfTest/Hash/test_vectors/keccak/readme.txt,sha256=K1q35vq7h6S1aGqUPr8EcZKoJEjtaBgQlaQtya3v-6U,83 +Cryptodome/SelfTest/Hash/test_vectors/wycheproof/aes_cmac_test.json,sha256=4GQcX-EVpdpSANFyweVfnrUS0_qOhnwUFNZQFlBPQzk,90510 +Cryptodome/SelfTest/IO/__init__.py,sha256=62l-NkQk9WPrRYoDAbtWKMOc9LT5yAE6ENws7t7-uzU,2002 +Cryptodome/SelfTest/IO/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/SelfTest/IO/__pycache__/test_PBES.cpython-38.pyc,, +Cryptodome/SelfTest/IO/__pycache__/test_PKCS8.cpython-38.pyc,, +Cryptodome/SelfTest/IO/test_PBES.py,sha256=sCOtJYeUCsSYM1NRYpweWzlUgrrc8W4vSHLIdi2s_aE,3469 +Cryptodome/SelfTest/IO/test_PKCS8.py,sha256=RC8LDc5b-7056ZWgoJNMPxaRgN4J8UyzgvQNE7LfoU8,17574 +Cryptodome/SelfTest/Math/__init__.py,sha256=EkOt_fJnPR9-LS36rE0xm0j1nlj-I0Y9CPnQk1KO29E,2113 +Cryptodome/SelfTest/Math/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/SelfTest/Math/__pycache__/test_Numbers.cpython-38.pyc,, +Cryptodome/SelfTest/Math/__pycache__/test_Primality.cpython-38.pyc,, +Cryptodome/SelfTest/Math/__pycache__/test_modexp.cpython-38.pyc,, +Cryptodome/SelfTest/Math/test_Numbers.py,sha256=AwPV2PIK_R51JgX5GxpYUVOxp2eZ1uzhcxvFPpzN3V8,29839 +Cryptodome/SelfTest/Math/test_Primality.py,sha256=0V_gzcBWyk1SFYEBcsEgYVaPfw3-UZtcWl0etV_bgvA,4901 +Cryptodome/SelfTest/Math/test_modexp.py,sha256=rsoK86G8jDUNPiVg5uu3c3S6XVN4wz9dl_ty0oajcwI,8135 +Cryptodome/SelfTest/Protocol/__init__.py,sha256=M2Sh9OvDVzEqup__hYYipuAqXvBwEHSooPPz4meBCyo,1763 +Cryptodome/SelfTest/Protocol/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/SelfTest/Protocol/__pycache__/test_KDF.cpython-38.pyc,, +Cryptodome/SelfTest/Protocol/__pycache__/test_SecretSharing.cpython-38.pyc,, +Cryptodome/SelfTest/Protocol/__pycache__/test_rfc1751.cpython-38.pyc,, +Cryptodome/SelfTest/Protocol/test_KDF.py,sha256=qIDtlD4nJOHL0Rlg-2rAIw-PhBaR3Q96Vbn3kxzq0XI,34529 +Cryptodome/SelfTest/Protocol/test_SecretSharing.py,sha256=B64noTracARMA3qGIUmIuk5Ob-NYyIldndNK-KJVmkg,9701 +Cryptodome/SelfTest/Protocol/test_rfc1751.py,sha256=6QuxUUE-NP8_1tQNj9Macjtc540zk4j85Z7G1Nyy2cI,2220 +Cryptodome/SelfTest/Protocol/test_vectors/wycheproof/hkdf_sha1_test.json,sha256=O9w7X1BkMKkFTU_6LHA-NO1uMTMLKr0IgRSO4SlWCP0,80132 +Cryptodome/SelfTest/Protocol/test_vectors/wycheproof/hkdf_sha256_test.json,sha256=i0ExHY0YXUgtQ6TH9svR3lNezQ0ZHU_mhU_hpj0mf7Q,98622 +Cryptodome/SelfTest/Protocol/test_vectors/wycheproof/hkdf_sha384_test.json,sha256=iCNFhGsEfB3wwhKfOnKjzhBpfry4CaZIlAmg8maC9DA,122104 +Cryptodome/SelfTest/Protocol/test_vectors/wycheproof/hkdf_sha512_test.json,sha256=UzoAknq9V9ZtOoCB48e0C4VoQh4_yXesEH555P8ee-s,147385 +Cryptodome/SelfTest/PublicKey/__init__.py,sha256=aRQ22RfDcpSeNEKu98hfxITqQMIoSOCGwCG1XTQuzVo,2203 +Cryptodome/SelfTest/PublicKey/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/SelfTest/PublicKey/__pycache__/test_DSA.cpython-38.pyc,, +Cryptodome/SelfTest/PublicKey/__pycache__/test_ECC.cpython-38.pyc,, +Cryptodome/SelfTest/PublicKey/__pycache__/test_ElGamal.cpython-38.pyc,, +Cryptodome/SelfTest/PublicKey/__pycache__/test_RSA.cpython-38.pyc,, +Cryptodome/SelfTest/PublicKey/__pycache__/test_import_DSA.cpython-38.pyc,, +Cryptodome/SelfTest/PublicKey/__pycache__/test_import_ECC.cpython-38.pyc,, +Cryptodome/SelfTest/PublicKey/__pycache__/test_import_RSA.cpython-38.pyc,, +Cryptodome/SelfTest/PublicKey/test_DSA.py,sha256=8V1xuY9LWsMLxFJUfbf0SkJYuy0F1mRIprozyn3kdXU,9552 +Cryptodome/SelfTest/PublicKey/test_ECC.py,sha256=aWwLootkojYrRI6cwttSD1SSYnCEGZ2QiG2uSmp8BX4,31788 +Cryptodome/SelfTest/PublicKey/test_ElGamal.py,sha256=FhcxH3ngmtbPezyLLS2g1JXUb6RreGTVfK6a8RT5y4Q,8671 +Cryptodome/SelfTest/PublicKey/test_RSA.py,sha256=_MlvOivZxIzWVARdyMYx6AKpbZnSYQ_0DfnGBlzNw3Q,12220 +Cryptodome/SelfTest/PublicKey/test_import_DSA.py,sha256=V20ehAYhf5WAcm5mBxurN9YM3Z58vAfTY-irdzE7A_Y,25492 +Cryptodome/SelfTest/PublicKey/test_import_ECC.py,sha256=0fbH06J9fkz1AErgv0uS7dUGSROOjSnxNWmpvyj5_Qg,50208 +Cryptodome/SelfTest/PublicKey/test_import_RSA.py,sha256=cWheO9zbXvoCrHsCticFCqHOmkqmuCyZQWwk2FHrq_c,23778 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256.txt,sha256=wYvstytkYlYw41vRkecS-zFU5jRFvqjck1_FslBiU9s,630 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private.der,sha256=7qlKORodBckn-NEiXjjhvdK33oj615HsiX2lCdn_HHY,121 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private.pem,sha256=yjB0KGJw7cK59wOGC9vav00Hua7O-4y4KmR-ZvfTIFo,227 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_ecparams.pem,sha256=UoWial9kzXR5-vqH-DiiStF9LQuR7HaWVEza1zO6oGM,302 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_enc_aes128.pem,sha256=0wkiqVsPBEzM0xudk3HJ41WKhYIp1XYb5EMid3HIhjk,314 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_enc_aes192.pem,sha256=TJKSWl5XvJu7ir-bBj_YNhqw1zrT2tJpQ0tacLnPswA,314 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_enc_aes256.pem,sha256=yMEDYmgWlztJujMOF9rMS9Iha34GBXyuXYpYgLWxx0k,314 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_enc_aes256_gcm.pem,sha256=GotcdRDvbl91HvWlW1z009iuUYTTSpGy4HrmVJ_sDCk,300 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_enc_des3.pem,sha256=XOwp6KnEADXw239Va5r9ugVpJOWoaZQTQ-iE99Gpyh4,299 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_openssh.pem,sha256=aCxAUluUngRkqklTjXMJ1U-R06vyTtgvAY9HJiyiBM0,525 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_openssh_old.pem,sha256=U2LOqXeFl_KpuBjteuFMVINwpkhySBQHreMsIsmAe8U,241 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_openssh_pwd.pem,sha256=faDeroEuwg_Ix_5F5NPjrcIgL1JsuVTO8ElkT09GgL4,578 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_openssh_pwd_old.pem,sha256=DKlWKgTzq5QEpu7OfnASW2P1CMpsTrHYLFMMzP__SMU,241 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_p8.der,sha256=8Lia3f3O81Fur193lkEPfMuqxxJIRO2UqjqWo_HDHF4,179 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_p8.pem,sha256=XoGTYG5LrjouLTIkIT4eFOxt5N1VH7AYbhBA2aZbzKE,318 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_p8_clear.der,sha256=cnmbIowIW8z6EJ2Nn4eg6jygbK5Fx-TPjIsr9RX50i4,138 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_p8_clear.pem,sha256=aQZgvErmx6ZyJ4UtYRukA17Gc4eQO7uaiDsCwBqPF08,241 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_public.der,sha256=fGv8W3UpJMMXYmJ2nPRrmjSPNnyOcE-fI1dgGsA1qWo,91 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_public.pem,sha256=18VbHNZHsikjlu35teZZB5_x_Vimb7NlLu3xTwIMs4U,178 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_public_compressed.der,sha256=wUxc_rRUKSbVuW9Xmr2y-9j6fZoWUyp-f3kMEFnScVU,59 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_public_compressed.pem,sha256=AQ9fW0iXXwb_gAfEgsZOFbv8_F9rHkrO5FWkG6WL5-4,134 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_public_openssh.txt,sha256=lez_62x3FxIN6LUS6NdwuGRn4yZZ0VqVWJIdsyC7jKY,161 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_x509.der,sha256=FbcHrhY7Q7BO0nt-AoCVMWqPPLebvNB7dPNUyBFVHtI,401 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_x509.pem,sha256=zTGkUwOeqJpxZz2LcsluZ3A_0f_wHrMPzR7DF3lJ7bw,599 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384.txt,sha256=30cv9scTYhSDTQE7gNXeihp7QVFW3azbBPfSqdIeLBI,848 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_private.der,sha256=gdF5yQdMI2w9N1Rz2OZl1kXAS3VjdvvO4eRBNEwci88,167 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_private.pem,sha256=lW4F-gHG8plnrEjwXODlNBDR06244E2FqdNW6RrKZ0k,288 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_private_enc_aes128.pem,sha256=m8h8zR8UR_shztyeCLv2ERdn-Pj0RZPI_lDnA84EzNU,379 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_private_enc_aes192.pem,sha256=jjDKqZ71CAeoEf9qdFUrm5qMdL9SLBBUSA77aHCdsqY,379 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_private_enc_aes256.pem,sha256=Okuv8VAz-TjM1INmOx-sfZIAaNYENrkViLhU6Tub5BM,379 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_private_enc_aes256_gcm.pem,sha256=q7oNkCM9-0ZVdmXMT-I_ubd9BAeUf7FAWw7ax45nUbA,361 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_private_enc_des3.pem,sha256=zvzq_un0MjYOriaiI2unsjiZyODYLajkEZhKl1M-fIg,352 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_private_openssh.pem,sha256=YaQ4jzZ_Qk680cHo4D7pSgOuGKL-x1ehVrmNuaP8VpA,634 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_private_openssh_old.pem,sha256=xtuVGnb35W5TviTFR-VX4UAm27jPw_qaAKT2zGRdN50,306 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_private_openssh_pwd.pem,sha256=VJGw10-QUR3K012qM5S0xulsxqHMAnLO9kjyZ9AUyAs,687 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_private_openssh_pwd_old.pem,sha256=HA9CtaFCz82uqaJWF4PbMra_WmBWeGhs_oOUPE4I46k,306 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_private_p8.der,sha256=v-ba89TMhcrwYb99FwTTSGRjPvHEY_YtAD_uHN9NXfY,288 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_private_p8.pem,sha256=28va4dDY6o0BQweiABnLzVd2XJHP6Sh1keljdA4vSMI,464 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_private_p8_clear.der,sha256=iQNdOt70TwEAa8JjslZfU14t9QMuJw4WI4xp9bO1boM,185 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_private_p8_clear.pem,sha256=p9k9kyrlXEdWLTgX77lC-EsRjRyJ_attoLxP_7u9ABo,306 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_public.der,sha256=P_Xu10VVbabmws1UYBe36AAb0r67KopkCpVXrdAZWBk,120 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_public.pem,sha256=DLmI4hGdlkQt8msGAWK8PIGeSwljpsaRPcap48ljUPE,215 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_public_compressed.der,sha256=40gth3gsa-MDzpE3oBbzNUeGT6w2xUHnGJr6MFHPPp0,72 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_public_compressed.pem,sha256=KAd0DNF4lw7LCTEHG-eQ5AlQx61yfbISZ15OoWlImxI,150 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_public_openssh.txt,sha256=lwxYgs4nmrAh3MzAwGXVnpzbGMUuIVtlGUQA6w1kd4g,205 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_x509.der,sha256=ianAVbMC_RUc_qkW56ZveHWNON9UkCtxHzRAKNTgU3Y,465 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p384_x509.pem,sha256=IoS2VsH6MzJFrqkaE7dUNx9zpPZilSOKqwWWTzwd1ss,684 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521.txt,sha256=csPtEBUyVqueAivVBMENIQK6dIW5EeVzOuMm74eEbuw,1102 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_private.der,sha256=EgT4zXHC_nUdlpMQPtVNVL6Kd85-UNlFvWpXj3ZKLsU,223 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_private.pem,sha256=SzMianLiLMvdM_uoKpuoolMEr149xfjxZs1BMzNk3E4,365 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_private_enc_aes128.pem,sha256=6Q7QjmOg9HtGgvzbr1Ir8y_s-X0VJiItGIojnGk_188,444 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_private_enc_aes192.pem,sha256=Usoy3FRZ621Ba_On0UR8iuS8a1dBIliXoNViFedOn5M,444 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_private_enc_aes256.pem,sha256=V7aiqI6niQFt33j0fRuSjLULlAebLtrzqkStBm-tynI,444 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_private_enc_aes256_gcm.pem,sha256=p5exiD4JHHDtK0jVlajI0N73pBwVVVmg03O2caZDb-M,438 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_private_enc_des3.pem,sha256=9ct7Q2bQ4Wqw-S_BCu6TPpRmLoVxuAA5Ui3vNRrcX54,429 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_private_openssh.pem,sha256=kBOZ_mWsjGkvuY76LoeXCW08zpd6e-vzL-PC2A1kRE8,756 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_private_openssh_old.pem,sha256=fo2rw0koPqjatPBspOclEYuVLVko-wLgmxTsEqoNJjY,384 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_private_openssh_pwd.pem,sha256=kVA6BoPYrlOqW1scj0tddmMaeKfn-MT7unIpZClsSIM,801 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_private_openssh_pwd_old.pem,sha256=uZCxZEF1324xbh8FsyeC-e5xWTuh2JI9THSMYta3nNc,384 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_private_p8.der,sha256=uBLXLGBOnJHNhsnfxi3_LBzEQt7zZ7dvA8W10XNFBsU,353 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_private_p8.pem,sha256=IMvxQdmrlUhfItAyms1un1MBUETxXOELdpb7wqg58RM,554 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_private_p8_clear.der,sha256=bhoyjpfdqhn8txQ02eOmK1uBoz7Y2FTj3qFYvf9er6g,241 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_private_p8_clear.pem,sha256=GvWW9t8Ux6z1-Uu7O6hWAgxdI5vgU2eVsDNcyyS_b18,384 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_public.der,sha256=n8k_4lc8DlJD1jqFzj9QFbIU2uMyJTuZt08BOjEQHaU,158 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_public.pem,sha256=cd0AukbHFnj_d1habRRQaZxss3QEgzs6pkYvFFgMh2A,268 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_public_compressed.der,sha256=35DQpuatGV2E92otSp8JcI4yszBg2A3q3a1TiVoDHzE,90 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_public_compressed.pem,sha256=LYsdWOfaBZtP9eYvu4hktp5HhmuuiGATJPOYQYNmVqw,174 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_public_openssh.txt,sha256=NUTubHKJmFuqIhBPwTy9PSOMoWI511Q_bUUOallD5jY,253 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_x509.der,sha256=T8JHzhTzXC74Bzy2t9JCfpXMi3FgC_RvhqZNK2S47vU,539 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/ecc_p521_x509.pem,sha256=il319QczAtkua27nPwS5gQnwuhPDuVc4U8z8_F5HHgQ,786 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/gen_ecc_p256.sh,sha256=jvhcZKBm51b1N-zcTLjsiquVBtdrQuLHm6c6JagsDCA,2651 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/gen_ecc_p384.sh,sha256=tOY_BeLz7D55rRohOnASfpKU5VISAI_slDKmNuQCxr8,2540 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/gen_ecc_p521.sh,sha256=pr2bzhpJtOMHa9HCIToMctduu9bzKwFhr06kFd9aeIk,2540 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/openssl_version.txt,sha256=TpgzscIqzY_FLk6WH0y1H0klab_iJn2U120v1loK4Gg,31 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/openssl_version_p384.txt,sha256=NEWRNBfUbq4TNQkZuuSOQAp6VeGmnrbIoo-lC-Qe0-M,27 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/openssl_version_p521.txt,sha256=NEWRNBfUbq4TNQkZuuSOQAp6VeGmnrbIoo-lC-Qe0-M,27 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/point-at-infinity.org-P256.txt,sha256=YCL_d9GA0wp_B4jH63gFgglZz97QDipQb3JAGyGk1iQ,9993 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/point-at-infinity.org-P384.txt,sha256=LH3JZPf82mX9kZfLCurwN6KFxAJKe0c7dn_wTkmznTc,14455 +Cryptodome/SelfTest/PublicKey/test_vectors/ECC/point-at-infinity.org-P521.txt,sha256=uXgYPT7uZU4VSE8D4of-9MbgFWVWyTLWekpPwryKWho,19421 +Cryptodome/SelfTest/PublicKey/test_vectors/RSA/gen_rsa_2048.sh,sha256=kKh8bTqhBmvzCO-rek3THD8SfhibZXb-5MKAkua6-_0,659 +Cryptodome/SelfTest/PublicKey/test_vectors/RSA/openssl_version.txt,sha256=g4a696SFxOtAl9Ta6wEQ7Gk7S2xAOYDW_2owds4QRG0,33 +Cryptodome/SelfTest/PublicKey/test_vectors/RSA/rsa2048_private.pem,sha256=p-GqC-XtacpQsChpxqB0UuDzGJz25zDVGc1XLD9QZlw,1675 +Cryptodome/SelfTest/PublicKey/test_vectors/RSA/rsa2048_private_openssh.pem,sha256=SscubX5Q_zu193_200rKEEMcDsA8UUNMFl2qwpZD79c,1843 +Cryptodome/SelfTest/PublicKey/test_vectors/RSA/rsa2048_private_openssh_old.pem,sha256=z7hNYzNlTHBBD1TgzIeRT1jL6Mz9WFNNbnB1HjihX2s,1704 +Cryptodome/SelfTest/PublicKey/test_vectors/RSA/rsa2048_private_openssh_pwd.pem,sha256=d2AQnmOPVvU_FiCA9nPo3QA7TQnRIkCrVKiiBP7Zuy4,1896 +Cryptodome/SelfTest/PublicKey/test_vectors/RSA/rsa2048_private_openssh_pwd_old.pem,sha256=akUEWlzHkLQySLriut7c1Lz7_A8Uv6GmID2a_nSrvgA,1708 +Cryptodome/SelfTest/PublicKey/test_vectors/RSA/rsa2048_public_openssh.txt,sha256=Wk5hyMlp7Cb_TAglAhmPEVFejSPMY97cTz9voxhgp4E,381 +Cryptodome/SelfTest/Random/__init__.py,sha256=vWmKA--IXzOIszf150wbGq1-OTAVBTI3sqInjutIBWk,1546 +Cryptodome/SelfTest/Random/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/SelfTest/Random/__pycache__/test_random.cpython-38.pyc,, +Cryptodome/SelfTest/Random/test_random.py,sha256=VtbtEXdP_6EaxZ_hRL3rP-HrBVBEqb_ANN7l8HfoRFM,7014 +Cryptodome/SelfTest/Signature/__init__.py,sha256=C-5wFBkGOqSmy5j1ljP2EAHsTPmz4Cp3klsrUgTaUVI,1564 +Cryptodome/SelfTest/Signature/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/SelfTest/Signature/__pycache__/test_dss.cpython-38.pyc,, +Cryptodome/SelfTest/Signature/__pycache__/test_pkcs1_15.cpython-38.pyc,, +Cryptodome/SelfTest/Signature/__pycache__/test_pss.cpython-38.pyc,, +Cryptodome/SelfTest/Signature/test_dss.py,sha256=pNFOUpR_XNTRW6YYbevhL47JH-YKuMT4Tn2-osJtKy0,48521 +Cryptodome/SelfTest/Signature/test_pkcs1_15.py,sha256=rDFun7A_XUMiqksw6iTm7HJap-1Z1wGINiwhoSRT9CI,13961 +Cryptodome/SelfTest/Signature/test_pss.py,sha256=cniIFFvnRk7JvAIfyZHagK8emuGXMklwHYKnd5ye_AM,15834 +Cryptodome/SelfTest/Signature/test_vectors/DSA/FIPS_186_3_SigGen.txt,sha256=CgbUHJa42LSFuKhzyHqIOrOhjfty1UEbqG6mZzgwG4w,332997 +Cryptodome/SelfTest/Signature/test_vectors/DSA/FIPS_186_3_SigVer.rsp,sha256=XAzACaPYLKYnuy3k9eKMEaLLYv599wDS-P4_WPc-sFM,320900 +Cryptodome/SelfTest/Signature/test_vectors/ECDSA/README.txt,sha256=-9a-bk38fNGDOL5A0MuvoMv_-DGDyXv-Hy_hi9lPVdU,233 +Cryptodome/SelfTest/Signature/test_vectors/ECDSA/SigGen.txt,sha256=fmR9CA0A0OBmTk0VXO3dLF6JuWpfYnTiR0GbKJ46u8c,73092 +Cryptodome/SelfTest/Signature/test_vectors/ECDSA/SigVer.rsp,sha256=2mRCPlaCZaEKtHnQaNT4UyV4y4Ugp2ym431pVWlO5Qs,59083 +Cryptodome/SelfTest/Signature/test_vectors/PKCS1-PSS/SigGenPSS_186-2.txt,sha256=rcKJqoIznZ4T1n7CWiQF1IdS--TtECXiJTvu9cuIlEY,241521 +Cryptodome/SelfTest/Signature/test_vectors/PKCS1-PSS/SigGenPSS_186-3.txt,sha256=Rt5_L8y1-JUW5ktb2xxP1FagnJzGgN1k4HVuYv9QAOw,84721 +Cryptodome/SelfTest/Signature/test_vectors/PKCS1-PSS/SigVerPSS_186-3.rsp,sha256=eMQgBgTucJ1k6lMI9E9r5JNWyaaYjDdojMugWQz4O_o,618655 +Cryptodome/SelfTest/Signature/test_vectors/PKCS1-v1.5/SigGen15_186-2.txt,sha256=O-UB5gD4svYkt_DtBDsPNeF-7KhkRF-DUwHhv3IAloc,228502 +Cryptodome/SelfTest/Signature/test_vectors/PKCS1-v1.5/SigGen15_186-3.txt,sha256=GcSbj8cQLMEkduIVhUzSKPH4wNMW8Oot9sGD8Wfpcko,78424 +Cryptodome/SelfTest/Signature/test_vectors/PKCS1-v1.5/SigVer15_186-3.rsp,sha256=b2A4FDStYP85DmeRO00HLufCVkvVdjaW7xspnh2WezM,248174 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/dsa_test.json,sha256=dY9VnMaPZ0VYhzjyXXu4DUa5OyN1HM8HXZFIata5Kj8,361835 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp224r1_sha224_p1363_test.json,sha256=NUzTUOvq8KUgnhgblXylo_xC0prDUrBJnvHT2COMDhY,126917 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp224r1_sha224_test.json,sha256=h0ZfND_VTKlrULr6fsqhWi1NOwSkCZQYLOY1k5kuo3Q,182708 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp224r1_sha256_p1363_test.json,sha256=frm9Q9JD6btb9aYrfeSrqu1JisTmOcsNMR67oRZUPjg,136148 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp224r1_sha256_test.json,sha256=fllUI96pdYYPSmtNnf5wengqklQcNl1Fv5tmYgGajRA,191745 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp224r1_sha3_224_test.json,sha256=rYp3SAmNMqI5Oiek4o2JradM7YsCN3sgJTm3Q2191OU,192369 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp224r1_sha3_256_test.json,sha256=DSwWgANVGnI6l3tTT_f6IX7ld1x6TWQq1QLvmkn_AmA,195342 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp224r1_sha3_512_test.json,sha256=rUn9FPrUbfFRa9Rti9mAeT1WH8TCjXvQ-SkN6ymx6_Y,216893 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp224r1_sha512_p1363_test.json,sha256=m-6HhNQBAO0oP7Hvu5qOm7y0_RhwpiavN4H7SPJKZ94,158057 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp224r1_sha512_test.json,sha256=srxXDnc8w0HyPC1cFGYEum5u9WlaFilCM2969gFRf1w,215238 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp256r1_sha256_p1363_test.json,sha256=eEd59aM1Yyrmq1aojPZKLgyRixx_tJ0-nxc_sl_Q8JQ,169360 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp256r1_sha256_test.json,sha256=Yvg1kKnp4mpdc1n4Y-1BKqzSnt3ySPgXWbCcPEiT9O0,209501 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp256r1_sha3_256_test.json,sha256=tQCOWU-wS8pwztc_QQB2vK1IXmflAvR91WGplVKfcto,212335 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp256r1_sha3_512_test.json,sha256=GO0BLh57BNYJK3ZcuiPjAynKzBLek5z9SP1EacmOkIU,235525 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp256r1_sha512_p1363_test.json,sha256=LTH5hr5Eqciwd64TdLiL9OfUTk0_YEVFyYWiCQw-4AE,192688 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp256r1_sha512_test.json,sha256=TbH2DT14pKwLQdnqdc3LJkRaf2EcdkECPZX0qtUMHqM,233815 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp384r1_sha384_p1363_test.json,sha256=fLjtA_INZ1ZC4JIwbnbTLZYvmvVN7cHn6c_sbX7-1qY,202354 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp384r1_sha384_test.json,sha256=QPdf0K6THBEM9aSkl35s6kDkh3-SIomshoX6bEtwxXI,248834 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp384r1_sha3_384_test.json,sha256=WwCSeAmsmAnJtYpRdxpT1M4GMn9SabbgiRIkSVij7AY,252441 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp384r1_sha3_512_test.json,sha256=llhW4ydRgaY_Uq663LDVieLPOz6EN-d_vqKJq1VuPj4,266529 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp384r1_sha512_p1363_test.json,sha256=ZTO1O-Z_eTEfXMXX_gZ8tyr1qHUUIxKb-8mOHOmHffs,217518 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp384r1_sha512_test.json,sha256=ycWfQpYvSTBG6B3Q3-cVoKG1rUblxAc3ric7QxZrBbs,264814 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp521r1_sha3_512_test.json,sha256=zvNdmzSSuNUmf_ZusWRljRxJspgiN_IThYGVdmzqJhE,316628 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp521r1_sha512_p1363_test.json,sha256=nivx2a4HuAwfaERUwBuTZDREIve8uGstu0wN5ZZoBCc,265577 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_secp521r1_sha512_test.json,sha256=gLytODmZ8DmUJTrTGbg0WuvG1wGm3uq-wwZhzNpmEAM,315478 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_test.json,sha256=1XbwmavbVPefYmWJhS7x1byueiJ5DAzTmo2eQhlG-7I,1333478 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/ecdsa_webcrypto_test.json,sha256=Qa7kaY0Xohqsixuy-ezkDSLG8yGL8L98Hubfj9DGOs0,385262 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_pss_2048_sha1_mgf1_20_test.json,sha256=bD0sOop9DKD2OIBaJOBTqN9piTU_1lqk-pBpXvAW6BU,63308 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_pss_2048_sha256_mgf1_0_test.json,sha256=ZZGPT7_oIvbgwLFKM1iFfKJefD6C9-VnuP8fgEga9Bw,72789 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_pss_2048_sha256_mgf1_32_test.json,sha256=hR7EkUvCMwshuYQW1lChpfQJdgwCsJTiEAHK1DyjV3c,74923 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_pss_2048_sha512_256_mgf1_28_test.json,sha256=LQ8ufxpctrj2VHOZ2I7TBWuNpTpzW3r9YOsPcaCGfQk,37903 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_pss_2048_sha512_256_mgf1_32_test.json,sha256=2RkYwmvFpuP1XIWTR5fKshYJyif7TObvzYxlpWQLXO8,37191 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_pss_3072_sha256_mgf1_32_test.json,sha256=xkx8gcULOEd0N9SfcehBSUQBKDOrv2Q-dDmc3MQ2NKk,101979 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_pss_4096_sha256_mgf1_32_test.json,sha256=8omUot7aJDuhggbUHYGF0qCR7DNRLjvIwnSAGXqCVEM,129037 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_pss_4096_sha512_mgf1_32_test.json,sha256=uOksGZcx2x4A_DPnnE0DXmI166rNshpY8oWfmlPcWgs,211443 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_pss_misc_test.json,sha256=d2w-C4-V2t7yCDW92y_UMEtbSdTJ3QGOLqPQs4Jxifw,463761 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_sig_gen_misc_test.json,sha256=Q1OTIr166OUg4uAMbRGsXP3_Ty9wQ8weOhZgsS0GuvQ,372540 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_2048_sha224_test.json,sha256=1ANoEKJ6Mc94iKCS-cqNqnhx79ZsHCy9a8pWV8Popsk,175874 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_2048_sha256_test.json,sha256=BHjrlYexXC5nCb_wGGNT5VBRYcKhU9bUuEzauElpBGU,181387 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_2048_sha384_test.json,sha256=bt4DMVo3j7HgRFE5l7m03aVv68UZJm6g39kmgh-Etr4,184281 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_2048_sha3_224_test.json,sha256=AdsypMqO6_GRil0LRBG7zuWJD80EEVjA3mY-9Or_Ako,181604 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_2048_sha3_256_test.json,sha256=hQ4Fs6ZQzL55QtPQmJUYAXrBP7bSukas9rL482hflOA,180890 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_2048_sha3_384_test.json,sha256=FSXUlpTnygKfQbhyKog1iSebDjG6zFxav9HInKYheHw,181604 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_2048_sha3_512_test.json,sha256=Znlqjz8DFWdsjZv40HBxn_juSuIjsoossTYYQsPiuWw,181604 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_2048_sha512_224_test.json,sha256=kC_TABoVqLd1Jo8wxqd-4NTJVCQYWRQpBTJ3_1_8jYk,183800 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_2048_sha512_256_test.json,sha256=tYXtc6895ZxNzy_uvxnRdWCOHC6pk2Jy39vi533DZjc,183086 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_2048_sha512_test.json,sha256=WsNGI8iC3jx2AqGoGzS4MEM9QDJ_Ky-bhgmrowrUuJ8,178542 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_3072_sha256_test.json,sha256=INZNK4hxDkjguICmNnPOUCkToSMFjeWWq9moA6GZ1CA,240992 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_3072_sha384_test.json,sha256=AoHmTwjmNhhJmfkGNWNXnlxPhnWP1lWs5ccMRb1llMM,236965 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_3072_sha3_256_test.json,sha256=fRdlVlSs_r1BDqFl3B7yQvCKGQTBwWeDaWV1B-k3PgE,245066 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_3072_sha3_384_test.json,sha256=RWjb1l5WR1hVKuqZ09BuLuBnpWhFcmhnXVr-r7Iipww,246036 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_3072_sha3_512_test.json,sha256=15-WDZpI2meYFNnFeRpSaAtuxapszz8MkfR8eskTu5E,246036 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_3072_sha512_256_test.json,sha256=p9euedS_ywKSYRD0T80klmDpyt52vvsZzRXwDaTPioA,248030 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_3072_sha512_test.json,sha256=695qzX0M3a9enz0Botw3LejEcMQKQ2CMATBcuY0JzUY,241950 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_4096_sha384_test.json,sha256=FvvLp8tnOeoeFjd91W8sBOMbI75sHj5fkH_DT2Q1eGA,299010 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_4096_sha512_256_test.json,sha256=dRHPuI8avsTKUBRAp8ej2VszXamupiMqYi_TzDec1no,312976 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_4096_sha512_test.json,sha256=dwFh4ADPbnVs-1T-PnHahFfIBTitecFHT-aAzlk1k4E,299010 +Cryptodome/SelfTest/Signature/test_vectors/wycheproof/rsa_signature_test.json,sha256=j_yzdGf4xK7M0bxP_iF3n6-p-cY7FKUJV76pttMADl0,353455 +Cryptodome/SelfTest/Util/__init__.py,sha256=0Ov0gHqo91NR0f639IzQMU-UX1pxOm90PI-uUaOJlro,2021 +Cryptodome/SelfTest/Util/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/SelfTest/Util/__pycache__/test_Counter.cpython-38.pyc,, +Cryptodome/SelfTest/Util/__pycache__/test_Padding.cpython-38.pyc,, +Cryptodome/SelfTest/Util/__pycache__/test_asn1.cpython-38.pyc,, +Cryptodome/SelfTest/Util/__pycache__/test_number.cpython-38.pyc,, +Cryptodome/SelfTest/Util/__pycache__/test_rfc1751.cpython-38.pyc,, +Cryptodome/SelfTest/Util/__pycache__/test_strxor.cpython-38.pyc,, +Cryptodome/SelfTest/Util/test_Counter.py,sha256=ApOFXU5UI7v6Fyud6x9DOxxzknMs5mRhdiPxrEayeKE,2214 +Cryptodome/SelfTest/Util/test_Padding.py,sha256=YS6QCpAg4wO1f_uF1yjRCfljxLV9exTjxzZJEzdJvQk,5642 +Cryptodome/SelfTest/Util/test_asn1.py,sha256=H8bZeUqd3I8y1eWhR_XgOTLfCTvhgIqyu6HxCb7JjM8,29439 +Cryptodome/SelfTest/Util/test_number.py,sha256=E4AuphgplCJEVK8NWQzhCQgOtUZXQDnLCKyxUCKQjm0,6440 +Cryptodome/SelfTest/Util/test_rfc1751.py,sha256=iRu-xLLslb_ktNOPkKs4TAWPljrxDMksFnSqo25q9dA,1121 +Cryptodome/SelfTest/Util/test_strxor.py,sha256=CMOooo3QahU0wx3n-gNdmpqio5FanEUOosse0XfS_jo,10618 +Cryptodome/SelfTest/__init__.py,sha256=bsbo1dGYE-girZ4Mc7JeMbsgKWQ-WccHPAlLAzd3028,3686 +Cryptodome/SelfTest/__main__.py,sha256=aQAx7W62ztb2utGTClg3Qgb8iD9zSCnThhil_cIdL84,1506 +Cryptodome/SelfTest/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/SelfTest/__pycache__/__main__.cpython-38.pyc,, +Cryptodome/SelfTest/__pycache__/loader.cpython-38.pyc,, +Cryptodome/SelfTest/__pycache__/st_common.cpython-38.pyc,, +Cryptodome/SelfTest/loader.py,sha256=xO6_2DEpt-7RH6CD1YEWv8AjKjTxQsalKWLLb0ALbws,4101 +Cryptodome/SelfTest/st_common.py,sha256=XsoFHmR_gylMxGhRJrQHfarNnIT_Mu8t9oAebRPReck,1949 +Cryptodome/Signature/DSS.py,sha256=GG7RirihwrofE8dzjMDcbQfOVkit4MXobaB_55qP09A,15333 +Cryptodome/Signature/DSS.pyi,sha256=zay6LNZ3NIlu42Q63ICT3mZEcz_aVG1rXLOkJ2tfasc,1102 +Cryptodome/Signature/PKCS1_PSS.py,sha256=o3Ky9DF9iI-wpGHDi5vZs7spzFSlANYIkqgqu0zCkAo,2103 +Cryptodome/Signature/PKCS1_PSS.pyi,sha256=fzw5vQvHchfJHvlHEr24CMTY2Gw8_pqsz76jNmMUBlc,280 +Cryptodome/Signature/PKCS1_v1_5.py,sha256=aEzzt1ccFM71pJfG6drwzGZeTI-ntM4-LLxBPyaFXLA,1993 +Cryptodome/Signature/PKCS1_v1_5.pyi,sha256=eqweCPvqayn2xiO9Aqv4Bc38GKOLcca6PazT9T87ufE,157 +Cryptodome/Signature/__init__.py,sha256=Y7O7plqZibJUIIyRDTPHxUKYBNvl4botFXvjEUA0y0A,1686 +Cryptodome/Signature/__pycache__/DSS.cpython-38.pyc,, +Cryptodome/Signature/__pycache__/PKCS1_PSS.cpython-38.pyc,, +Cryptodome/Signature/__pycache__/PKCS1_v1_5.cpython-38.pyc,, +Cryptodome/Signature/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/Signature/__pycache__/pkcs1_15.cpython-38.pyc,, +Cryptodome/Signature/__pycache__/pss.cpython-38.pyc,, +Cryptodome/Signature/pkcs1_15.py,sha256=C0tGVrnMF3caVBJArhpEYZ0dsQ2RD8taIIzv50j85gg,8749 +Cryptodome/Signature/pkcs1_15.pyi,sha256=k8o74VVp_Zw11VmbhLBxPiU6CzzTm7NbaNwGeWeNn9A,568 +Cryptodome/Signature/pss.py,sha256=1443VYy8pEuvB7t8sWJ9p--pGHnRz2yqChKx3EowkXI,13494 +Cryptodome/Signature/pss.pyi,sha256=O_6YOe-iR4rHIzNnm6vCzcwxVNPGRgfAXhhzp1N9jPE,1044 +Cryptodome/Util/Counter.py,sha256=IWid224Wy-kmQ1UxqRsutwiTDzJq-ajxQGx0rx-_M3E,2811 +Cryptodome/Util/Counter.pyi,sha256=2JrTHJYq263XosQSC_NIP0TufUsTlG7WUr-lRqjJCuA,290 +Cryptodome/Util/Padding.py,sha256=KMwvlHUL6zRNA_XMa_SXwbm7RBIND_3sK155NeSocI8,4229 +Cryptodome/Util/Padding.pyi,sha256=47R3H2kE66PtKO82eT_Vc5eCSgNe4qOFgqOIPRdlp9c,238 +Cryptodome/Util/RFC1751.py,sha256=zHC63Jx-PqZQ2ebcYGUhaG62vfkFSklQc8MZmapE7SY,21204 +Cryptodome/Util/RFC1751.pyi,sha256=B42LvsE6G786rNEsrhta_BANazgrpb0WoSBPqKyjt5g,159 +Cryptodome/Util/__init__.py,sha256=fsZWRqGXZR2gmM0jxuiogKW3WwzlzKuTRRWYiwtOOd0,1951 +Cryptodome/Util/__pycache__/Counter.cpython-38.pyc,, +Cryptodome/Util/__pycache__/Padding.cpython-38.pyc,, +Cryptodome/Util/__pycache__/RFC1751.cpython-38.pyc,, +Cryptodome/Util/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/Util/__pycache__/_cpu_features.cpython-38.pyc,, +Cryptodome/Util/__pycache__/_file_system.cpython-38.pyc,, +Cryptodome/Util/__pycache__/_raw_api.cpython-38.pyc,, +Cryptodome/Util/__pycache__/asn1.cpython-38.pyc,, +Cryptodome/Util/__pycache__/number.cpython-38.pyc,, +Cryptodome/Util/__pycache__/py3compat.cpython-38.pyc,, +Cryptodome/Util/__pycache__/strxor.cpython-38.pyc,, +Cryptodome/Util/_cpu_features.py,sha256=f_JiluwzxhmltMbptIQ8qA03YUdgSNBr3RwcyX9z-xc,1997 +Cryptodome/Util/_cpu_features.pyi,sha256=3wKXZ0Z8llc2uxADvbhz3dHV6YLyRrDujOsabXlffCQ,59 +Cryptodome/Util/_cpuid_c.cpython-38-x86_64-linux-gnu.so,sha256=0XsY-HTCy_DusKyRTYtS92e6dfrvqiKb17YhkONXQwM,10899 +Cryptodome/Util/_file_system.py,sha256=m7HsPgKuKRsTQjgov6Vg02dn7Xsa52xhCLmqLjPIoZg,2183 +Cryptodome/Util/_file_system.pyi,sha256=5QruEWPE4urPtlCT5Eg8tBQyhV9ffBfZIAjmMo727dM,100 +Cryptodome/Util/_raw_api.py,sha256=_Uzt_wQ1_lm5GnENEF_s2Zya-LOCfG-UCA26ELB0DLg,10461 +Cryptodome/Util/_raw_api.pyi,sha256=Ohc2rr6RS-nhs6T5AL1YyQtaqsx6BVrJa092CiwAvNM,906 +Cryptodome/Util/_strxor.cpython-38-x86_64-linux-gnu.so,sha256=lvjppxLIMiolJvn5lp_CIYEloWiyFmDzeg-4v08mxcE,13213 +Cryptodome/Util/asn1.py,sha256=uOFoioOtH5ko3E59qR_zHHsVE2I9ZEDHPg6cMmIJanc,31772 +Cryptodome/Util/asn1.pyi,sha256=xR4oQKBf4SXiz0IQ_K0lw427jvvgX9SiEXejIu9fdV8,3579 +Cryptodome/Util/number.py,sha256=xwH1LGqkVsg0fufxrbWlX88pVPxbE11FvO3L4Oc3zhs,94868 +Cryptodome/Util/number.pyi,sha256=ixX1BS8EvvuPXN1_8aosdYHKmtXGB9NlRNVI9T9MAA8,975 +Cryptodome/Util/py3compat.py,sha256=PrPeqRZP9glhLCzrj-G_8BFmTui7EOO3bwA1y1bBgmw,5246 +Cryptodome/Util/py3compat.pyi,sha256=GeZXPUe7HqATRZ9ijsDRt3sVXEioOvi_T8dzLrUMBN4,824 +Cryptodome/Util/strxor.py,sha256=SEcBSWY8xqSAPBmPA2TdTjFJnqTs9A4WoxVX4VyNv2Y,5126 +Cryptodome/Util/strxor.pyi,sha256=OuBvuuK_ezq3eaHY10J89xpER9IQ9wcYzFI7j1tpll0,243 +Cryptodome/__init__.py,sha256=oIHjFUCVTvgyuhVOuPLSQ29PXjOgb4XN7UiRdTs8GbU,184 +Cryptodome/__init__.pyi,sha256=e5Ea45Jy2RdOr6bmLF9jiS2Bw65WnYTD1NMLJlbGAaw,99 +Cryptodome/__pycache__/__init__.cpython-38.pyc,, +Cryptodome/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pycryptodomex-3.9.9.dist-info/AUTHORS.rst,sha256=4AeRvMPhQSqwZcXaicX3Uv6MzyU98gNxUNcQsE6XiNg,735 +pycryptodomex-3.9.9.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pycryptodomex-3.9.9.dist-info/LICENSE.rst,sha256=0a8_qy74zFO2x_SL3rF4rIdLBPr0ugFZqWthCfHTk-I,14685 +pycryptodomex-3.9.9.dist-info/METADATA,sha256=P7sdFrKssGKWsJR1a92GfdG4CNCtXFB3XFUPR2KWAWA,3188 +pycryptodomex-3.9.9.dist-info/RECORD,, +pycryptodomex-3.9.9.dist-info/WHEEL,sha256=lmsU4pfb_60LHFgAOwGQv63gTX7Ny9agYdFe9vUdh58,108 +pycryptodomex-3.9.9.dist-info/top_level.txt,sha256=eHU9ase6in1ZSBEtTDpl7fwIPION42nbqZ1uFTyccxs,11 diff --git a/frozen_deps/pycryptodomex-3.9.9.dist-info/WHEEL b/frozen_deps/pycryptodomex-3.9.9.dist-info/WHEEL new file mode 100644 index 0000000..460075a --- /dev/null +++ b/frozen_deps/pycryptodomex-3.9.9.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.35.1) +Root-Is-Purelib: false +Tag: cp38-cp38-manylinux1_x86_64 + diff --git a/frozen_deps/pycryptodomex-3.9.9.dist-info/top_level.txt b/frozen_deps/pycryptodomex-3.9.9.dist-info/top_level.txt new file mode 100644 index 0000000..9cbd375 --- /dev/null +++ b/frozen_deps/pycryptodomex-3.9.9.dist-info/top_level.txt @@ -0,0 +1 @@ +Cryptodome diff --git a/keytree.py b/keytree.py index 44e922b..6a04677 100755 --- a/keytree.py +++ b/keytree.py @@ -223,12 +223,12 @@ def load_from_keystore(filename): key = hashlib.pbkdf2_hmac( 'sha256', sha256(passwd + salt), salt, 200000) - obj = AES.new(key, + a = AES.new(key, mode=AES.MODE_GCM, - nonce=iv) + nonce=iv).update(salt) if tag != sha256(passwd + sha256(passwd + salt)): raise KeytreeError("incorrect keystore password") - return obj.decrypt(ciphertext[:-16]).decode('utf-8') + return a.decrypt_and_verify(ciphertext[:-16], ciphertext[-16:]).decode('utf-8') except KeytreeError as e: raise e except: @@ -237,9 +237,41 @@ def load_from_keystore(filename): raise KeytreeError("failed to open file") +def cb58encode(raw): + checksum = sha256(raw)[-4:] + return b58encode(raw + checksum).decode('utf-8') + + +def save_to_keystore(filename, words): + try: + with open(filename, "w") as f: + passwd = getpass('Enter the password for the keystore (utf-8): ').encode('utf-8') + iv = os.urandom(12) + salt = os.urandom(16) + pass_hash = sha256(passwd + sha256(passwd + salt)) + key = hashlib.pbkdf2_hmac( + 'sha256', + sha256(passwd + salt), salt, 200000) + a = AES.new(key, + mode=AES.MODE_GCM, + nonce=iv).update(salt) + (c, t) = a.encrypt_and_digest(words.encode('utf-8')) + ciphertext = c + t + json.dump({ + 'version': "5.0", + 'keys': [ + {'key': cb58encode(ciphertext), 'iv': cb58encode(iv)}], + 'salt': cb58encode(salt), + 'pass_hash': cb58encode(pass_hash) + }, f) + except FileNotFoundError: + raise KeytreeError("failed while saving") + + if __name__ == '__main__': parser = argparse.ArgumentParser(description='Derive BIP32 key pairs from BIP39 mnemonic') - parser.add_argument('--from-avax-keystore', type=str, default=None, help='load mnemonic from an AVAX keystore file') + parser.add_argument('--load-keystore', type=str, default=None, help='load mnemonic from a keystore file (AVAX Wallet compatible)') + parser.add_argument('--save-keystore', type=str, default=None, help='save mnemonic to a keystore file (AVAX Wallet compatible)') parser.add_argument('--show-private', action='store_true', default=False, help='also show private keys and the mnemonic') parser.add_argument('--custom-words', action='store_true', default=False, help='use an arbitrary word combination as mnemonic') parser.add_argument('--account-path', default="44'/9000'/0'/0", help="path prefix for key deriving (e.g. \"0/1'/2\")") @@ -258,8 +290,8 @@ if __name__ == '__main__': mgen = mnemonic.Mnemonic(args.lang) words = mgen.generate(256) else: - if args.from_avax_keystore: - words = load_from_keystore(args.from_avax_keystore) + if args.load_keystore: + words = load_from_keystore(args.load_keystore) else: words = getpass('Enter the mnemonic: ').strip() if not args.custom_words: @@ -285,6 +317,8 @@ if __name__ == '__main__': print("{}.addr(AVAX) X-{}".format(i, bech32.bech32_encode(args.hrp, bech32.convertbits(ripemd160(sha256(cpub)), 8, 5)))) print("{}.addr(BTC) {}".format(i, get_btc_addr(pub))) print("{}.addr(ETH) {}".format(i, get_eth_addr(pub))) + if args.save_keystore: + save_to_keystore(args.save_keystore, words) except KeytreeError as e: sys.stderr.write("error: {}\n".format(str(e))) sys.exit(1) diff --git a/setup.py b/setup.py index 352641a..116053b 100644 --- a/setup.py +++ b/setup.py @@ -9,4 +9,4 @@ setup(name='keytree.py', license='MIT', scripts=['keytree.py'], py_modules=['bech32'], - install_requires=['ecdsa', 'base58', 'pysha3', 'pycrypto', 'mnemonic']) + install_requires=['ecdsa', 'base58', 'pysha3', 'pycryptodomex', 'mnemonic']) -- cgit v1.2.3-70-g09d2