aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeterminant <[email protected]>2020-11-17 18:47:40 -0500
committerDeterminant <[email protected]>2020-11-17 18:47:40 -0500
commit3bef51eec2299403467e621ae660cef3f9256ac8 (patch)
tree9b72aaa95fb6dffacd8b20164699870a32ab6825
parent92b8b8e9628cac41d37226416107adc76b10e01b (diff)
update frozen deps
-rw-r--r--README.rst11
-rw-r--r--freezed_deps/ecdsa-0.15.dist-info/RECORD52
-rw-r--r--freezed_deps/ecdsa/__init__.py25
-rw-r--r--freezed_deps/ecdsa/curves.py128
-rw-r--r--freezed_deps/ecdsa/ecdsa.py446
-rw-r--r--freezed_deps/ecdsa/ellipticcurve.py780
-rw-r--r--freezed_deps/ecdsa/numbertheory.py600
-rw-r--r--freezed_deps/ecdsa/test_ecdsa.py448
-rw-r--r--frozen_deps/Crypto/Cipher/AES.py115
-rw-r--r--frozen_deps/Crypto/Cipher/ARC2.py130
-rw-r--r--frozen_deps/Crypto/Cipher/ARC4.py120
-rw-r--r--frozen_deps/Crypto/Cipher/Blowfish.py121
-rw-r--r--frozen_deps/Crypto/Cipher/CAST.py123
-rw-r--r--frozen_deps/Crypto/Cipher/DES.py118
-rw-r--r--frozen_deps/Crypto/Cipher/DES3.py133
-rw-r--r--frozen_deps/Crypto/Cipher/PKCS1_OAEP.py255
-rw-r--r--frozen_deps/Crypto/Cipher/PKCS1_v1_5.py226
-rw-r--r--frozen_deps/Crypto/Cipher/XOR.py86
-rwxr-xr-xfrozen_deps/Crypto/Cipher/_AES.cpython-38-x86_64-linux-gnu.sobin0 -> 43640 bytes
-rwxr-xr-xfrozen_deps/Crypto/Cipher/_ARC2.cpython-38-x86_64-linux-gnu.sobin0 -> 26904 bytes
-rwxr-xr-xfrozen_deps/Crypto/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.sobin0 -> 18064 bytes
-rwxr-xr-xfrozen_deps/Crypto/Cipher/_Blowfish.cpython-38-x86_64-linux-gnu.sobin0 -> 35368 bytes
-rwxr-xr-xfrozen_deps/Crypto/Cipher/_CAST.cpython-38-x86_64-linux-gnu.sobin0 -> 35320 bytes
-rwxr-xr-xfrozen_deps/Crypto/Cipher/_DES.cpython-38-x86_64-linux-gnu.sobin0 -> 68560 bytes
-rwxr-xr-xfrozen_deps/Crypto/Cipher/_DES3.cpython-38-x86_64-linux-gnu.sobin0 -> 68560 bytes
-rwxr-xr-xfrozen_deps/Crypto/Cipher/_XOR.cpython-38-x86_64-linux-gnu.sobin0 -> 18096 bytes
-rw-r--r--frozen_deps/Crypto/Cipher/__init__.py83
-rw-r--r--frozen_deps/Crypto/Cipher/blockalgo.py296
-rw-r--r--frozen_deps/Crypto/Hash/HMAC.py212
-rw-r--r--frozen_deps/Crypto/Hash/MD2.py91
-rw-r--r--frozen_deps/Crypto/Hash/MD4.py91
-rw-r--r--frozen_deps/Crypto/Hash/MD5.py97
-rw-r--r--frozen_deps/Crypto/Hash/RIPEMD.py94
-rw-r--r--frozen_deps/Crypto/Hash/SHA.py98
-rw-r--r--frozen_deps/Crypto/Hash/SHA224.py95
-rw-r--r--frozen_deps/Crypto/Hash/SHA256.py95
-rw-r--r--frozen_deps/Crypto/Hash/SHA384.py96
-rw-r--r--frozen_deps/Crypto/Hash/SHA512.py95
-rwxr-xr-xfrozen_deps/Crypto/Hash/_MD2.cpython-38-x86_64-linux-gnu.sobin0 -> 18464 bytes
-rwxr-xr-xfrozen_deps/Crypto/Hash/_MD4.cpython-38-x86_64-linux-gnu.sobin0 -> 18552 bytes
-rwxr-xr-xfrozen_deps/Crypto/Hash/_RIPEMD160.cpython-38-x86_64-linux-gnu.sobin0 -> 22888 bytes
-rwxr-xr-xfrozen_deps/Crypto/Hash/_SHA224.cpython-38-x86_64-linux-gnu.sobin0 -> 18496 bytes
-rwxr-xr-xfrozen_deps/Crypto/Hash/_SHA256.cpython-38-x86_64-linux-gnu.sobin0 -> 18496 bytes
-rwxr-xr-xfrozen_deps/Crypto/Hash/_SHA384.cpython-38-x86_64-linux-gnu.sobin0 -> 22592 bytes
-rwxr-xr-xfrozen_deps/Crypto/Hash/_SHA512.cpython-38-x86_64-linux-gnu.sobin0 -> 22592 bytes
-rw-r--r--frozen_deps/Crypto/Hash/__init__.py56
-rw-r--r--frozen_deps/Crypto/Hash/hashalgo.py116
-rw-r--r--frozen_deps/Crypto/Protocol/AllOrNothing.py320
-rw-r--r--frozen_deps/Crypto/Protocol/Chaffing.py245
-rw-r--r--frozen_deps/Crypto/Protocol/KDF.py123
-rw-r--r--frozen_deps/Crypto/Protocol/__init__.py41
-rw-r--r--frozen_deps/Crypto/PublicKey/DSA.py379
-rw-r--r--frozen_deps/Crypto/PublicKey/ElGamal.py373
-rw-r--r--frozen_deps/Crypto/PublicKey/RSA.py719
-rw-r--r--frozen_deps/Crypto/PublicKey/_DSA.py115
-rw-r--r--frozen_deps/Crypto/PublicKey/_RSA.py81
-rw-r--r--frozen_deps/Crypto/PublicKey/__init__.py41
-rwxr-xr-xfrozen_deps/Crypto/PublicKey/_fastmath.cpython-38-x86_64-linux-gnu.sobin0 -> 78864 bytes
-rw-r--r--frozen_deps/Crypto/PublicKey/_slowmath.py187
-rw-r--r--frozen_deps/Crypto/PublicKey/pubkey.py240
-rw-r--r--frozen_deps/Crypto/Random/Fortuna/FortunaAccumulator.py171
-rw-r--r--frozen_deps/Crypto/Random/Fortuna/FortunaGenerator.py132
-rw-r--r--frozen_deps/Crypto/Random/Fortuna/SHAd256.py98
-rw-r--r--frozen_deps/Crypto/Random/Fortuna/__init__.py0
-rw-r--r--frozen_deps/Crypto/Random/OSRNG/__init__.py40
-rw-r--r--frozen_deps/Crypto/Random/OSRNG/fallback.py46
-rw-r--r--frozen_deps/Crypto/Random/OSRNG/posix.py86
-rw-r--r--frozen_deps/Crypto/Random/OSRNG/rng_base.py88
-rw-r--r--frozen_deps/Crypto/Random/_UserFriendlyRNG.py230
-rw-r--r--frozen_deps/Crypto/Random/__init__.py43
-rw-r--r--frozen_deps/Crypto/Random/random.py142
-rw-r--r--frozen_deps/Crypto/Signature/PKCS1_PSS.py355
-rw-r--r--frozen_deps/Crypto/Signature/PKCS1_v1_5.py236
-rw-r--r--frozen_deps/Crypto/Signature/__init__.py31
-rw-r--r--frozen_deps/Crypto/Util/Counter.py127
-rw-r--r--frozen_deps/Crypto/Util/RFC1751.py365
-rw-r--r--frozen_deps/Crypto/Util/__init__.py37
-rwxr-xr-xfrozen_deps/Crypto/Util/_counter.cpython-38-x86_64-linux-gnu.sobin0 -> 22856 bytes
-rw-r--r--frozen_deps/Crypto/Util/_number_new.py119
-rw-r--r--frozen_deps/Crypto/Util/asn1.py286
-rw-r--r--frozen_deps/Crypto/Util/number.py1456
-rw-r--r--frozen_deps/Crypto/Util/py3compat.py107
-rw-r--r--frozen_deps/Crypto/Util/randpool.py82
-rwxr-xr-xfrozen_deps/Crypto/Util/strxor.cpython-38-x86_64-linux-gnu.sobin0 -> 16784 bytes
-rw-r--r--frozen_deps/Crypto/Util/winrandom.py28
-rw-r--r--frozen_deps/Crypto/__init__.py51
-rw-r--r--frozen_deps/Crypto/pct_warnings.py60
-rwxr-xr-xfrozen_deps/_pysha3.cpython-38-x86_64-linux-gnu.so (renamed from freezed_deps/_pysha3.cpython-38-x86_64-linux-gnu.so)bin517664 -> 517664 bytes
-rw-r--r--frozen_deps/base58-2.0.1.dist-info/COPYING (renamed from freezed_deps/base58-2.0.1.dist-info/COPYING)0
-rw-r--r--frozen_deps/base58-2.0.1.dist-info/INSTALLER (renamed from freezed_deps/base58-2.0.1.dist-info/INSTALLER)0
-rw-r--r--frozen_deps/base58-2.0.1.dist-info/METADATA (renamed from freezed_deps/base58-2.0.1.dist-info/METADATA)0
-rw-r--r--frozen_deps/base58-2.0.1.dist-info/RECORD (renamed from freezed_deps/base58-2.0.1.dist-info/RECORD)0
-rw-r--r--frozen_deps/base58-2.0.1.dist-info/WHEEL (renamed from freezed_deps/base58-2.0.1.dist-info/WHEEL)0
-rw-r--r--frozen_deps/base58-2.0.1.dist-info/entry_points.txt (renamed from freezed_deps/base58-2.0.1.dist-info/entry_points.txt)0
-rw-r--r--frozen_deps/base58-2.0.1.dist-info/top_level.txt (renamed from freezed_deps/base58-2.0.1.dist-info/top_level.txt)0
-rw-r--r--frozen_deps/base58/__init__.py (renamed from freezed_deps/base58/__init__.py)0
-rw-r--r--frozen_deps/base58/__main__.py (renamed from freezed_deps/base58/__main__.py)0
-rw-r--r--frozen_deps/base58/py.typed (renamed from freezed_deps/base58/py.typed)0
-rw-r--r--frozen_deps/bech32.py (renamed from freezed_deps/bech32.py)0
-rwxr-xr-xfrozen_deps/bin/base58 (renamed from freezed_deps/bin/base58)0
-rwxr-xr-xfrozen_deps/bin/keytree.py (renamed from freezed_deps/bin/keytree.py)130
-rw-r--r--frozen_deps/ecdsa-0.16.1.dist-info/INSTALLER (renamed from freezed_deps/ecdsa-0.15.dist-info/INSTALLER)0
-rw-r--r--frozen_deps/ecdsa-0.16.1.dist-info/LICENSE (renamed from freezed_deps/ecdsa-0.15.dist-info/LICENSE)0
-rw-r--r--frozen_deps/ecdsa-0.16.1.dist-info/METADATA (renamed from freezed_deps/ecdsa-0.15.dist-info/METADATA)3
-rw-r--r--frozen_deps/ecdsa-0.16.1.dist-info/RECORD52
-rw-r--r--frozen_deps/ecdsa-0.16.1.dist-info/WHEEL (renamed from freezed_deps/ecdsa-0.15.dist-info/WHEEL)0
-rw-r--r--frozen_deps/ecdsa-0.16.1.dist-info/top_level.txt (renamed from freezed_deps/ecdsa-0.15.dist-info/top_level.txt)0
-rw-r--r--frozen_deps/ecdsa/__init__.py76
-rw-r--r--frozen_deps/ecdsa/_compat.py (renamed from freezed_deps/ecdsa/_compat.py)23
-rw-r--r--frozen_deps/ecdsa/_rwlock.py (renamed from freezed_deps/ecdsa/_rwlock.py)1
-rw-r--r--frozen_deps/ecdsa/_version.py (renamed from freezed_deps/ecdsa/_version.py)6
-rw-r--r--frozen_deps/ecdsa/curves.py194
-rw-r--r--frozen_deps/ecdsa/der.py (renamed from freezed_deps/ecdsa/der.py)125
-rw-r--r--frozen_deps/ecdsa/ecdh.py (renamed from freezed_deps/ecdsa/ecdh.py)59
-rw-r--r--frozen_deps/ecdsa/ecdsa.py754
-rw-r--r--frozen_deps/ecdsa/ellipticcurve.py847
-rw-r--r--frozen_deps/ecdsa/keys.py (renamed from freezed_deps/ecdsa/keys.py)558
-rw-r--r--frozen_deps/ecdsa/numbertheory.py810
-rw-r--r--frozen_deps/ecdsa/rfc6979.py (renamed from freezed_deps/ecdsa/rfc6979.py)35
-rw-r--r--frozen_deps/ecdsa/test_der.py (renamed from freezed_deps/ecdsa/test_der.py)201
-rw-r--r--frozen_deps/ecdsa/test_ecdh.py (renamed from freezed_deps/ecdsa/test_ecdh.py)96
-rw-r--r--frozen_deps/ecdsa/test_ecdsa.py538
-rw-r--r--frozen_deps/ecdsa/test_ellipticcurve.py (renamed from freezed_deps/ecdsa/test_ellipticcurve.py)106
-rw-r--r--frozen_deps/ecdsa/test_jacobi.py (renamed from freezed_deps/ecdsa/test_jacobi.py)171
-rw-r--r--frozen_deps/ecdsa/test_keys.py (renamed from freezed_deps/ecdsa/test_keys.py)225
-rw-r--r--frozen_deps/ecdsa/test_malformed_sigs.py (renamed from freezed_deps/ecdsa/test_malformed_sigs.py)164
-rw-r--r--frozen_deps/ecdsa/test_numbertheory.py (renamed from freezed_deps/ecdsa/test_numbertheory.py)207
-rw-r--r--frozen_deps/ecdsa/test_pyecdsa.py (renamed from freezed_deps/ecdsa/test_pyecdsa.py)1412
-rw-r--r--frozen_deps/ecdsa/test_rw_lock.py (renamed from freezed_deps/ecdsa/test_rw_lock.py)40
-rw-r--r--frozen_deps/ecdsa/util.py (renamed from freezed_deps/ecdsa/util.py)86
-rw-r--r--frozen_deps/keytree.py-0.2.dist-info/INSTALLER (renamed from freezed_deps/keytree.py-0.2.dist-info/INSTALLER)0
-rw-r--r--frozen_deps/keytree.py-0.2.dist-info/METADATA (renamed from freezed_deps/keytree.py-0.2.dist-info/METADATA)1
-rw-r--r--frozen_deps/keytree.py-0.2.dist-info/RECORD (renamed from freezed_deps/keytree.py-0.2.dist-info/RECORD)4
-rw-r--r--frozen_deps/keytree.py-0.2.dist-info/WHEEL (renamed from freezed_deps/keytree.py-0.2.dist-info/WHEEL)0
-rw-r--r--frozen_deps/keytree.py-0.2.dist-info/direct_url.json (renamed from freezed_deps/keytree.py-0.2.dist-info/direct_url.json)0
-rw-r--r--frozen_deps/keytree.py-0.2.dist-info/top_level.txt (renamed from freezed_deps/keytree.py-0.2.dist-info/top_level.txt)0
-rw-r--r--frozen_deps/mnemonic-0.19.dist-info/AUTHORS (renamed from freezed_deps/mnemonic-0.19.dist-info/AUTHORS)0
-rw-r--r--frozen_deps/mnemonic-0.19.dist-info/INSTALLER (renamed from freezed_deps/mnemonic-0.19.dist-info/INSTALLER)0
-rw-r--r--frozen_deps/mnemonic-0.19.dist-info/LICENSE (renamed from freezed_deps/mnemonic-0.19.dist-info/LICENSE)0
-rw-r--r--frozen_deps/mnemonic-0.19.dist-info/METADATA (renamed from freezed_deps/mnemonic-0.19.dist-info/METADATA)0
-rw-r--r--frozen_deps/mnemonic-0.19.dist-info/RECORD (renamed from freezed_deps/mnemonic-0.19.dist-info/RECORD)0
-rw-r--r--frozen_deps/mnemonic-0.19.dist-info/WHEEL (renamed from freezed_deps/mnemonic-0.19.dist-info/WHEEL)0
-rw-r--r--frozen_deps/mnemonic-0.19.dist-info/top_level.txt (renamed from freezed_deps/mnemonic-0.19.dist-info/top_level.txt)0
-rw-r--r--frozen_deps/mnemonic/__init__.py (renamed from freezed_deps/mnemonic/__init__.py)0
-rw-r--r--frozen_deps/mnemonic/mnemonic.py (renamed from freezed_deps/mnemonic/mnemonic.py)0
-rw-r--r--frozen_deps/mnemonic/wordlist/chinese_simplified.txt (renamed from freezed_deps/mnemonic/wordlist/chinese_simplified.txt)0
-rw-r--r--frozen_deps/mnemonic/wordlist/chinese_traditional.txt (renamed from freezed_deps/mnemonic/wordlist/chinese_traditional.txt)0
-rw-r--r--frozen_deps/mnemonic/wordlist/english.txt (renamed from freezed_deps/mnemonic/wordlist/english.txt)0
-rw-r--r--frozen_deps/mnemonic/wordlist/french.txt (renamed from freezed_deps/mnemonic/wordlist/french.txt)0
-rw-r--r--frozen_deps/mnemonic/wordlist/italian.txt (renamed from freezed_deps/mnemonic/wordlist/italian.txt)0
-rw-r--r--frozen_deps/mnemonic/wordlist/japanese.txt (renamed from freezed_deps/mnemonic/wordlist/japanese.txt)0
-rw-r--r--frozen_deps/mnemonic/wordlist/korean.txt (renamed from freezed_deps/mnemonic/wordlist/korean.txt)0
-rw-r--r--frozen_deps/mnemonic/wordlist/spanish.txt (renamed from freezed_deps/mnemonic/wordlist/spanish.txt)0
-rw-r--r--frozen_deps/pycrypto-2.6.1.dist-info/INSTALLER (renamed from freezed_deps/pysha3-1.0.2.dist-info/INSTALLER)0
-rw-r--r--frozen_deps/pycrypto-2.6.1.dist-info/METADATA22
-rw-r--r--frozen_deps/pycrypto-2.6.1.dist-info/RECORD261
-rw-r--r--frozen_deps/pycrypto-2.6.1.dist-info/WHEEL (renamed from freezed_deps/pysha3-1.0.2.dist-info/WHEEL)0
-rw-r--r--frozen_deps/pycrypto-2.6.1.dist-info/top_level.txt1
-rw-r--r--frozen_deps/pysha3-1.0.2.dist-info/INSTALLER (renamed from freezed_deps/six-1.15.0.dist-info/INSTALLER)0
-rw-r--r--frozen_deps/pysha3-1.0.2.dist-info/LICENSE (renamed from freezed_deps/pysha3-1.0.2.dist-info/LICENSE)0
-rw-r--r--frozen_deps/pysha3-1.0.2.dist-info/METADATA (renamed from freezed_deps/pysha3-1.0.2.dist-info/METADATA)0
-rw-r--r--frozen_deps/pysha3-1.0.2.dist-info/RECORD (renamed from freezed_deps/pysha3-1.0.2.dist-info/RECORD)0
-rw-r--r--frozen_deps/pysha3-1.0.2.dist-info/WHEEL5
-rw-r--r--frozen_deps/pysha3-1.0.2.dist-info/top_level.txt (renamed from freezed_deps/pysha3-1.0.2.dist-info/top_level.txt)0
-rw-r--r--frozen_deps/sha3.py (renamed from freezed_deps/sha3.py)0
-rw-r--r--frozen_deps/six-1.15.0.dist-info/INSTALLER1
-rw-r--r--frozen_deps/six-1.15.0.dist-info/LICENSE (renamed from freezed_deps/six-1.15.0.dist-info/LICENSE)0
-rw-r--r--frozen_deps/six-1.15.0.dist-info/METADATA (renamed from freezed_deps/six-1.15.0.dist-info/METADATA)0
-rw-r--r--frozen_deps/six-1.15.0.dist-info/RECORD (renamed from freezed_deps/six-1.15.0.dist-info/RECORD)0
-rw-r--r--frozen_deps/six-1.15.0.dist-info/WHEEL (renamed from freezed_deps/six-1.15.0.dist-info/WHEEL)0
-rw-r--r--frozen_deps/six-1.15.0.dist-info/top_level.txt (renamed from freezed_deps/six-1.15.0.dist-info/top_level.txt)0
-rw-r--r--frozen_deps/six.py (renamed from freezed_deps/six.py)0
-rwxr-xr-xkeytree.py2
173 files changed, 16333 insertions, 3695 deletions
diff --git a/README.rst b/README.rst
index 8f981f9..ecfd3d5 100644
--- a/README.rst
+++ b/README.rst
@@ -3,14 +3,15 @@ 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``
-- Caveat: the above instructions use a freezed, 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.
- You can also load the mnemonic from an existing JSON keystore file (generated
by the official AVAX Wallet): ``./keytree.py --from-avax-keystore``.
-- To see all private keys and the mnemonic word, use ``--show-private`` (only
+- 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.
diff --git a/freezed_deps/ecdsa-0.15.dist-info/RECORD b/freezed_deps/ecdsa-0.15.dist-info/RECORD
deleted file mode 100644
index 0411a4f..0000000
--- a/freezed_deps/ecdsa-0.15.dist-info/RECORD
+++ /dev/null
@@ -1,52 +0,0 @@
-ecdsa-0.15.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
-ecdsa-0.15.dist-info/LICENSE,sha256=PsqYRXc9LluMydjBGdNF8ApIBuS9Zg1KPWzfnA6di7I,1147
-ecdsa-0.15.dist-info/METADATA,sha256=Vipd5pI4sqqaWMjmDzRNRkZCQaq1YDHOHkAJPlI92tw,24899
-ecdsa-0.15.dist-info/RECORD,,
-ecdsa-0.15.dist-info/WHEEL,sha256=8zNYZbwQSXoB9IfXOjPfeNwvAsALAjffgk27FqvCWbo,110
-ecdsa-0.15.dist-info/top_level.txt,sha256=7ovPHfAPyTou19f8gOSbHm6B9dGjTibWolcCB7Zjovs,6
-ecdsa/__init__.py,sha256=3wbqSX9mkjn_sjkbx2vU-MJbKg0uz8DYLAZE5Jk4iyc,1219
-ecdsa/__pycache__/__init__.cpython-38.pyc,,
-ecdsa/__pycache__/_compat.cpython-38.pyc,,
-ecdsa/__pycache__/_rwlock.cpython-38.pyc,,
-ecdsa/__pycache__/_version.cpython-38.pyc,,
-ecdsa/__pycache__/curves.cpython-38.pyc,,
-ecdsa/__pycache__/der.cpython-38.pyc,,
-ecdsa/__pycache__/ecdh.cpython-38.pyc,,
-ecdsa/__pycache__/ecdsa.cpython-38.pyc,,
-ecdsa/__pycache__/ellipticcurve.cpython-38.pyc,,
-ecdsa/__pycache__/keys.cpython-38.pyc,,
-ecdsa/__pycache__/numbertheory.cpython-38.pyc,,
-ecdsa/__pycache__/rfc6979.cpython-38.pyc,,
-ecdsa/__pycache__/test_der.cpython-38.pyc,,
-ecdsa/__pycache__/test_ecdh.cpython-38.pyc,,
-ecdsa/__pycache__/test_ecdsa.cpython-38.pyc,,
-ecdsa/__pycache__/test_ellipticcurve.cpython-38.pyc,,
-ecdsa/__pycache__/test_jacobi.cpython-38.pyc,,
-ecdsa/__pycache__/test_keys.cpython-38.pyc,,
-ecdsa/__pycache__/test_malformed_sigs.cpython-38.pyc,,
-ecdsa/__pycache__/test_numbertheory.cpython-38.pyc,,
-ecdsa/__pycache__/test_pyecdsa.cpython-38.pyc,,
-ecdsa/__pycache__/test_rw_lock.cpython-38.pyc,,
-ecdsa/__pycache__/util.cpython-38.pyc,,
-ecdsa/_compat.py,sha256=qmUf5lfl20-p8JleM4etlhplAEN37gbBqadBxXboomo,1108
-ecdsa/_rwlock.py,sha256=UVXDDwWF115oQroaHUtQo88uhhIoMLPIKfDQq3i7ETc,2848
-ecdsa/_version.py,sha256=J5ustrqphtIgbQXJKWGzATMRfq4koBTZ2UYvZuesnRw,496
-ecdsa/curves.py,sha256=Snq0JL6lydJunmSHeeycWvUQJ8Sj5N1tavcw6ZlZ4ik,4278
-ecdsa/der.py,sha256=rfV-KrVw10YAA2EWkVA4vZgbdeEhgsXaXfDd3S5qpp8,13864
-ecdsa/ecdh.py,sha256=qsUDPGMF9-tiqLaA9xUfhNBoUQ49gtMMFrc_O1YO_BQ,10459
-ecdsa/ecdsa.py,sha256=MB7v-2hUV982oOk-OzmKLtq-GXIPjNNK-Yd_dM4VcqU,17546
-ecdsa/ellipticcurve.py,sha256=wa3Om5WkW-HszXlBzyKdGaFfbQDsLABDCSXfrBzSMx0,24278
-ecdsa/keys.py,sha256=jeDeK5-G4C5jYebV0_sQGavRUQp5grNY7CV9eOH7o7I,52990
-ecdsa/numbertheory.py,sha256=FQiMnzY92Qi-Tt2z1czVd5MvaqqXzRgwlChZwPhwxEQ,15427
-ecdsa/rfc6979.py,sha256=7MR1nf19ZBD-EDgztlJ1SfSwLjlx3ePPb9BBFW7aEHo,2701
-ecdsa/test_der.py,sha256=XGZwUhZORvAZKEiWTLDDKlF_4JBplbUmTwkfdN-KGXU,12609
-ecdsa/test_ecdh.py,sha256=VlkuPt7fqwGh1nWwLVA-10Pguu5PYqWVaEOTDO7qlGM,13472
-ecdsa/test_ecdsa.py,sha256=zGC5L5vqc8nWNOKf0KOaUu3rJuLvpICioQ8tSypEjxs,18334
-ecdsa/test_ellipticcurve.py,sha256=odDCqwJm_sQgDFja9xSklpVskpXG5ebJ4xpBONU0duQ,6160
-ecdsa/test_jacobi.py,sha256=iGtWSMLpJ8HmJlrJkU7aiC5d50I8ahHKXFWfd0o_YP4,10778
-ecdsa/test_keys.py,sha256=NcnvEHsHJ0W-5T1F7M2RS9MzdR26ELlTv2LfAgMqEaU,12701
-ecdsa/test_malformed_sigs.py,sha256=6ow1rb-A-lbFD-TZjcl6a8VV9bwV2aL5Z0kwYJ4SJfk,10170
-ecdsa/test_numbertheory.py,sha256=KwC75hI2NfVPctlYki4JIUT8hUUcoK0x1AjcXDZQrow,9004
-ecdsa/test_pyecdsa.py,sha256=FqGtHsqwOpWz3Ne0Cmgib508pcEGv1b31eEBo-PQ5bE,64737
-ecdsa/test_rw_lock.py,sha256=5Gu_H73gU8Pb1_86X3AzkLMTYOtE4qdAwDOzBsEVbjk,6899
-ecdsa/util.py,sha256=CO6Jj3kUL28fIM3KnsevxYQJ1TCAAYDgCSacDAbSMu0,14007
diff --git a/freezed_deps/ecdsa/__init__.py b/freezed_deps/ecdsa/__init__.py
deleted file mode 100644
index eef5fe3..0000000
--- a/freezed_deps/ecdsa/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-from .keys import SigningKey, VerifyingKey, BadSignatureError, BadDigestError,\
- MalformedPointError
-from .curves import NIST192p, NIST224p, NIST256p, NIST384p, NIST521p,\
- SECP256k1, BRAINPOOLP160r1, BRAINPOOLP192r1, BRAINPOOLP224r1,\
- BRAINPOOLP256r1, BRAINPOOLP320r1, BRAINPOOLP384r1, BRAINPOOLP512r1
-from .ecdh import ECDH, NoKeyError, NoCurveError, InvalidCurveError, \
- InvalidSharedSecretError
-from .der import UnexpectedDER
-
-# This code comes from http://github.com/warner/python-ecdsa
-from ._version import get_versions
-__version__ = get_versions()['version']
-del get_versions
-
-__all__ = ["curves", "der", "ecdsa", "ellipticcurve", "keys", "numbertheory",
- "test_pyecdsa", "util", "six"]
-
-_hush_pyflakes = [SigningKey, VerifyingKey, BadSignatureError, BadDigestError,
- MalformedPointError, UnexpectedDER, InvalidCurveError,
- NoKeyError, InvalidSharedSecretError, ECDH, NoCurveError,
- NIST192p, NIST224p, NIST256p, NIST384p, NIST521p, SECP256k1,
- BRAINPOOLP160r1, BRAINPOOLP192r1, BRAINPOOLP224r1,
- BRAINPOOLP256r1, BRAINPOOLP320r1, BRAINPOOLP384r1,
- BRAINPOOLP512r1]
-del _hush_pyflakes
diff --git a/freezed_deps/ecdsa/curves.py b/freezed_deps/ecdsa/curves.py
deleted file mode 100644
index 173a2cd..0000000
--- a/freezed_deps/ecdsa/curves.py
+++ /dev/null
@@ -1,128 +0,0 @@
-from __future__ import division
-
-from . import der, ecdsa
-from .util import orderlen
-
-
-# orderlen was defined in this module previously, so keep it in __all__,
-# will need to mark it as deprecated later
-__all__ = ["UnknownCurveError", "orderlen", "Curve", "NIST192p",
- "NIST224p", "NIST256p", "NIST384p", "NIST521p", "curves",
- "find_curve", "SECP256k1", "BRAINPOOLP160r1", "BRAINPOOLP192r1",
- "BRAINPOOLP224r1", "BRAINPOOLP256r1", "BRAINPOOLP320r1",
- "BRAINPOOLP384r1", "BRAINPOOLP512r1"]
-
-
-class UnknownCurveError(Exception):
- pass
-
-
-class Curve:
- def __init__(self, name, curve, generator, oid, openssl_name=None):
- self.name = name
- self.openssl_name = openssl_name # maybe None
- self.curve = curve
- self.generator = generator
- self.order = generator.order()
- self.baselen = orderlen(self.order)
- self.verifying_key_length = 2*self.baselen
- self.signature_length = 2*self.baselen
- self.oid = oid
- self.encoded_oid = der.encode_oid(*oid)
-
- def __repr__(self):
- return self.name
-
-
-# the NIST curves
-NIST192p = Curve("NIST192p", ecdsa.curve_192,
- ecdsa.generator_192,
- (1, 2, 840, 10045, 3, 1, 1), "prime192v1")
-
-
-NIST224p = Curve("NIST224p", ecdsa.curve_224,
- ecdsa.generator_224,
- (1, 3, 132, 0, 33), "secp224r1")
-
-
-NIST256p = Curve("NIST256p", ecdsa.curve_256,
- ecdsa.generator_256,
- (1, 2, 840, 10045, 3, 1, 7), "prime256v1")
-
-
-NIST384p = Curve("NIST384p", ecdsa.curve_384,
- ecdsa.generator_384,
- (1, 3, 132, 0, 34), "secp384r1")
-
-
-NIST521p = Curve("NIST521p", ecdsa.curve_521,
- ecdsa.generator_521,
- (1, 3, 132, 0, 35), "secp521r1")
-
-
-SECP256k1 = Curve("SECP256k1", ecdsa.curve_secp256k1,
- ecdsa.generator_secp256k1,
- (1, 3, 132, 0, 10), "secp256k1")
-
-
-BRAINPOOLP160r1 = Curve("BRAINPOOLP160r1",
- ecdsa.curve_brainpoolp160r1,
- ecdsa.generator_brainpoolp160r1,
- (1, 3, 36, 3, 3, 2, 8, 1, 1, 1),
- "brainpoolP160r1")
-
-
-BRAINPOOLP192r1 = Curve("BRAINPOOLP192r1",
- ecdsa.curve_brainpoolp192r1,
- ecdsa.generator_brainpoolp192r1,
- (1, 3, 36, 3, 3, 2, 8, 1, 1, 3),
- "brainpoolP192r1")
-
-
-BRAINPOOLP224r1 = Curve("BRAINPOOLP224r1",
- ecdsa.curve_brainpoolp224r1,
- ecdsa.generator_brainpoolp224r1,
- (1, 3, 36, 3, 3, 2, 8, 1, 1, 5),
- "brainpoolP224r1")
-
-
-BRAINPOOLP256r1 = Curve("BRAINPOOLP256r1",
- ecdsa.curve_brainpoolp256r1,
- ecdsa.generator_brainpoolp256r1,
- (1, 3, 36, 3, 3, 2, 8, 1, 1, 7),
- "brainpoolP256r1")
-
-
-BRAINPOOLP320r1 = Curve("BRAINPOOLP320r1",
- ecdsa.curve_brainpoolp320r1,
- ecdsa.generator_brainpoolp320r1,
- (1, 3, 36, 3, 3, 2, 8, 1, 1, 9),
- "brainpoolP320r1")
-
-
-BRAINPOOLP384r1 = Curve("BRAINPOOLP384r1",
- ecdsa.curve_brainpoolp384r1,
- ecdsa.generator_brainpoolp384r1,
- (1, 3, 36, 3, 3, 2, 8, 1, 1, 11),
- "brainpoolP384r1")
-
-
-BRAINPOOLP512r1 = Curve("BRAINPOOLP512r1",
- ecdsa.curve_brainpoolp512r1,
- ecdsa.generator_brainpoolp512r1,
- (1, 3, 36, 3, 3, 2, 8, 1, 1, 13),
- "brainpoolP512r1")
-
-
-curves = [NIST192p, NIST224p, NIST256p, NIST384p, NIST521p, SECP256k1,
- BRAINPOOLP160r1, BRAINPOOLP192r1, BRAINPOOLP224r1, BRAINPOOLP256r1,
- BRAINPOOLP320r1, BRAINPOOLP384r1, BRAINPOOLP512r1]
-
-
-def find_curve(oid_curve):
- for c in curves:
- if c.oid == oid_curve:
- return c
- raise UnknownCurveError("I don't know about the curve with oid %s."
- "I only know about these: %s" %
- (oid_curve, [c.name for c in curves]))
diff --git a/freezed_deps/ecdsa/ecdsa.py b/freezed_deps/ecdsa/ecdsa.py
deleted file mode 100644
index 4e9bab0..0000000
--- a/freezed_deps/ecdsa/ecdsa.py
+++ /dev/null
@@ -1,446 +0,0 @@
-#! /usr/bin/env python
-
-"""
-Implementation of Elliptic-Curve Digital Signatures.
-
-Classes and methods for elliptic-curve signatures:
-private keys, public keys, signatures,
-NIST prime-modulus curves with modulus lengths of
-192, 224, 256, 384, and 521 bits.
-
-Example:
-
- # (In real-life applications, you would probably want to
- # protect against defects in SystemRandom.)
- from random import SystemRandom
- randrange = SystemRandom().randrange
-
- # Generate a public/private key pair using the NIST Curve P-192:
-
- g = generator_192
- n = g.order()
- secret = randrange( 1, n )
- pubkey = Public_key( g, g * secret )
- privkey = Private_key( pubkey, secret )
-
- # Signing a hash value:
-
- hash = randrange( 1, n )
- signature = privkey.sign( hash, randrange( 1, n ) )
-
- # Verifying a signature for a hash value:
-
- if pubkey.verifies( hash, signature ):
- print_("Demo verification succeeded.")
- else:
- print_("*** Demo verification failed.")
-
- # Verification fails if the hash value is modified:
-
- if pubkey.verifies( hash-1, signature ):
- print_("**** Demo verification failed to reject tampered hash.")
- else:
- print_("Demo verification correctly rejected tampered hash.")
-
-Version of 2009.05.16.
-
-Revision history:
- 2005.12.31 - Initial version.
- 2008.11.25 - Substantial revisions introducing new classes.
- 2009.05.16 - Warn against using random.randrange in real applications.
- 2009.05.17 - Use random.SystemRandom by default.
-
-Written in 2005 by Peter Pearson and placed in the public domain.
-"""
-
-from six import int2byte, b
-from . import ellipticcurve
-from . import numbertheory
-from .util import bit_length
-
-
-class RSZeroError(RuntimeError):
- pass
-
-
-class InvalidPointError(RuntimeError):
- pass
-
-
-class Signature(object):
- """ECDSA signature.
- """
- def __init__(self, r, s):
- self.r = r
- self.s = s
-
- def recover_public_keys(self, hash, generator):
- """Returns two public keys for which the signature is valid
- hash is signed hash
- generator is the used generator of the signature
- """
- curve = generator.curve()
- n = generator.order()
- r = self.r
- s = self.s
- e = hash
- x = r
-
- # Compute the curve point with x as x-coordinate
- alpha = (pow(x, 3, curve.p()) + (curve.a() * x) + curve.b()) % curve.p()
- beta = numbertheory.square_root_mod_prime(alpha, curve.p())
- y = beta if beta % 2 == 0 else curve.p() - beta
-
- # Compute the public key
- R1 = ellipticcurve.PointJacobi(curve, x, y, 1, n)
- Q1 = numbertheory.inverse_mod(r, n) * (s * R1 + (-e % n) * generator)
- Pk1 = Public_key(generator, Q1)
-
- # And the second solution
- R2 = ellipticcurve.PointJacobi(curve, x, -y, 1, n)
- Q2 = numbertheory.inverse_mod(r, n) * (s * R2 + (-e % n) * generator)
- Pk2 = Public_key(generator, Q2)
-
- return [Pk1, Pk2]
-
-
-class Public_key(object):
- """Public key for ECDSA.
- """
-
- def __init__(self, generator, point, verify=True):
- """
- Low level ECDSA public key object.
-
- :param generator: the Point that generates the group (the base point)
- :param point: the Point that defines the public key
- :param bool verify: if True check if point is valid point on curve
-
- :raises InvalidPointError: if the point parameters are invalid or
- point does not lie on the curve
- """
-
- self.curve = generator.curve()
- self.generator = generator
- self.point = point
- n = generator.order()
- p = self.curve.p()
- if not (0 <= point.x() < p) or not (0 <= point.y() < p):
- raise InvalidPointError("The public point has x or y out of range.")
- if verify and not self.curve.contains_point(point.x(), point.y()):
- raise InvalidPointError("Point does not lie on the curve")
- if not n:
- raise InvalidPointError("Generator point must have order.")
- # for curve parameters with base point with cofactor 1, all points
- # that are on the curve are scalar multiples of the base point, so
- # verifying that is not necessary. See Section 3.2.2.1 of SEC 1 v2
- if verify and self.curve.cofactor() != 1 and \
- not n * point == ellipticcurve.INFINITY:
- raise InvalidPointError("Generator point order is bad.")
-
- def __eq__(self, other):
- if isinstance(other, Public_key):
- """Return True if the points are identical, False otherwise."""
- return self.curve == other.curve \
- and self.point == other.point
- return NotImplemented
-
- def verifies(self, hash, signature):
- """Verify that signature is a valid signature of hash.
- Return True if the signature is valid.
- """
-
- # From X9.62 J.3.1.
-
- G = self.generator
- n = G.order()
- r = signature.r
- s = signature.s
- if r < 1 or r > n - 1:
- return False
- if s < 1 or s > n - 1:
- return False
- c = numbertheory.inverse_mod(s, n)
- u1 = (hash * c) % n
- u2 = (r * c) % n
- if hasattr(G, "mul_add"):
- xy = G.mul_add(u1, self.point, u2)
- else:
- xy = u1 * G + u2 * self.point
- v = xy.x() % n
- return v == r
-
-
-class Private_key(object):
- """Private key for ECDSA.
- """
-
- def __init__(self, public_key, secret_multiplier):
- """public_key is of class Public_key;
- secret_multiplier is a large integer.
- """
-
- self.public_key = public_key
- self.secret_multiplier = secret_multiplier
-
- def __eq__(self, other):
- if isinstance(other, Private_key):
- """Return True if the points are identical, False otherwise."""
- return self.public_key == other.public_key \
- and self.secret_multiplier == other.secret_multiplier
- return NotImplemented
-
- def sign(self, hash, random_k):
- """Return a signature for the provided hash, using the provided
- random nonce. It is absolutely vital that random_k be an unpredictable
- number in the range [1, self.public_key.point.order()-1]. If
- an attacker can guess random_k, he can compute our private key from a
- single signature. Also, if an attacker knows a few high-order
- bits (or a few low-order bits) of random_k, he can compute our private
- key from many signatures. The generation of nonces with adequate
- cryptographic strength is very difficult and far beyond the scope
- of this comment.
-
- May raise RuntimeError, in which case retrying with a new
- random value k is in order.
- """
-
- G = self.public_key.generator
- n = G.order()
- k = random_k % n
- # Fix the bit-length of the random nonce,
- # so that it doesn't leak via timing.
- # This does not change that ks = k mod n
- ks = k + n
- kt = ks + n
- if bit_length(ks) == bit_length(n):
- p1 = kt * G
- else:
- p1 = ks * G
- r = p1.x() % n
- if r == 0:
- raise RSZeroError("amazingly unlucky random number r")
- s = (numbertheory.inverse_mod(k, n)
- * (hash + (self.secret_multiplier * r) % n)) % n
- if s == 0:
- raise RSZeroError("amazingly unlucky random number s")
- return Signature(r, s)
-
-
-def int_to_string(x):
- """Convert integer x into a string of bytes, as per X9.62."""
- assert x >= 0
- if x == 0:
- return b('\0')
- result = []
- while x:
- ordinal = x & 0xFF
- result.append(int2byte(ordinal))
- x >>= 8
-
- result.reverse()
- return b('').join(result)
-
-
-def string_to_int(s):
- """Convert a string of bytes into an integer, as per X9.62."""
- result = 0
- for c in s:
- if not isinstance(c, int):
- c = ord(c)
- result = 256 * result + c
- return result
-
-
-def digest_integer(m):
- """Convert an integer into a string of bytes, compute
- its SHA-1 hash, and convert the result to an integer."""
- #
- # I don't expect this function to be used much. I wrote
- # it in order to be able to duplicate the examples
- # in ECDSAVS.
- #
- from hashlib import sha1
- return string_to_int(sha1(int_to_string(m)).digest())
-
-
-def point_is_valid(generator, x, y):
- """Is (x,y) a valid public key based on the specified generator?"""
-
- # These are the tests specified in X9.62.
-
- n = generator.order()
- curve = generator.curve()
- p = curve.p()
- if not (0 <= x < p) or not (0 <= y < p):
- return False
- if not curve.contains_point(x, y):
- return False
- if curve.cofactor() != 1 and \
- not n * ellipticcurve.PointJacobi(curve, x, y, 1)\
- == ellipticcurve.INFINITY:
- return False
- return True
-
-
-# NIST Curve P-192:
-_p = 6277101735386680763835789423207666416083908700390324961279
-_r = 6277101735386680763835789423176059013767194773182842284081
-# s = 0x3045ae6fc8422f64ed579528d38120eae12196d5L
-# c = 0x3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65L
-_b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1
-_Gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012
-_Gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811
-
-curve_192 = ellipticcurve.CurveFp(_p, -3, _b, 1)
-generator_192 = ellipticcurve.PointJacobi(
- curve_192, _Gx, _Gy, 1, _r, generator=True)
-
-
-# NIST Curve P-224:
-_p = 26959946667150639794667015087019630673557916260026308143510066298881
-_r = 26959946667150639794667015087019625940457807714424391721682722368061
-# s = 0xbd71344799d5c7fcdc45b59fa3b9ab8f6a948bc5L
-# c = 0x5b056c7e11dd68f40469ee7f3c7a7d74f7d121116506d031218291fbL
-_b = 0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4
-_Gx = 0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21
-_Gy = 0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34
-
-curve_224 = ellipticcurve.CurveFp(_p, -3, _b, 1)
-generator_224 = ellipticcurve.PointJacobi(
- curve_224, _Gx, _Gy, 1, _r, generator=True)
-
-# NIST Curve P-256:
-_p = 115792089210356248762697446949407573530086143415290314195533631308867097853951
-_r = 115792089210356248762697446949407573529996955224135760342422259061068512044369
-# s = 0xc49d360886e704936a6678e1139d26b7819f7e90L
-# c = 0x7efba1662985be9403cb055c75d4f7e0ce8d84a9c5114abcaf3177680104fa0dL
-_b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b
-_Gx = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296
-_Gy = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5
-
-curve_256 = ellipticcurve.CurveFp(_p, -3, _b, 1)
-generator_256 = ellipticcurve.PointJacobi(
- curve_256, _Gx, _Gy, 1, _r, generator=True)
-
-# NIST Curve P-384:
-_p = 39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319
-_r = 39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643
-# s = 0xa335926aa319a27a1d00896a6773a4827acdac73L
-# c = 0x79d1e655f868f02fff48dcdee14151ddb80643c1406d0ca10dfe6fc52009540a495e8042ea5f744f6e184667cc722483L
-_b = 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef
-_Gx = 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7
-_Gy = 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f
-
-curve_384 = ellipticcurve.CurveFp(_p, -3, _b, 1)
-generator_384 = ellipticcurve.PointJacobi(
- curve_384, _Gx, _Gy, 1, _r, generator=True)
-
-# NIST Curve P-521:
-_p = 6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151
-_r = 6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449
-# s = 0xd09e8800291cb85396cc6717393284aaa0da64baL
-# c = 0x0b48bfa5f420a34949539d2bdfc264eeeeb077688e44fbf0ad8f6d0edb37bd6b533281000518e19f1b9ffbe0fe9ed8a3c2200b8f875e523868c70c1e5bf55bad637L
-_b = 0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00
-_Gx = 0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66
-_Gy = 0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650
-
-curve_521 = ellipticcurve.CurveFp(_p, -3, _b, 1)
-generator_521 = ellipticcurve.PointJacobi(
- curve_521, _Gx, _Gy, 1, _r, generator=True)
-
-# Certicom secp256-k1
-_a = 0x0000000000000000000000000000000000000000000000000000000000000000
-_b = 0x0000000000000000000000000000000000000000000000000000000000000007
-_p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
-_Gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
-_Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
-_r = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
-
-curve_secp256k1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
-generator_secp256k1 = ellipticcurve.PointJacobi(
- curve_secp256k1, _Gx, _Gy, 1, _r, generator=True)
-
-# Brainpool P-160-r1
-_a = 0x340E7BE2A280EB74E2BE61BADA745D97E8F7C300
-_b = 0x1E589A8595423412134FAA2DBDEC95C8D8675E58
-_p = 0xE95E4A5F737059DC60DFC7AD95B3D8139515620F
-_Gx = 0xBED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3
-_Gy = 0x1667CB477A1A8EC338F94741669C976316DA6321
-_q = 0xE95E4A5F737059DC60DF5991D45029409E60FC09
-
-curve_brainpoolp160r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
-generator_brainpoolp160r1 = ellipticcurve.PointJacobi(
- curve_brainpoolp160r1, _Gx, _Gy, 1, _q, generator=True)
-
-# Brainpool P-192-r1
-_a = 0x6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF
-_b = 0x469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9
-_p = 0xC302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297
-_Gx = 0xC0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6
-_Gy = 0x14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F
-_q = 0xC302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1
-
-curve_brainpoolp192r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
-generator_brainpoolp192r1 = ellipticcurve.PointJacobi(
- curve_brainpoolp192r1, _Gx, _Gy, 1, _q, generator=True)
-
-# Brainpool P-224-r1
-_a = 0x68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43
-_b = 0x2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B
-_p = 0xD7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF
-_Gx = 0x0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D
-_Gy = 0x58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD
-_q = 0xD7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F
-
-curve_brainpoolp224r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
-generator_brainpoolp224r1 = ellipticcurve.PointJacobi(
- curve_brainpoolp224r1, _Gx, _Gy, 1, _q, generator=True)
-
-# Brainpool P-256-r1
-_a = 0x7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9
-_b = 0x26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6
-_p = 0xA9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377
-_Gx = 0x8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262
-_Gy = 0x547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997
-_q = 0xA9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7
-
-curve_brainpoolp256r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
-generator_brainpoolp256r1 = ellipticcurve.PointJacobi(
- curve_brainpoolp256r1, _Gx, _Gy, 1, _q, generator=True)
-
-# Brainpool P-320-r1
-_a = 0x3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4
-_b = 0x520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6
-_p = 0xD35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27
-_Gx = 0x43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611
-_Gy = 0x14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1
-_q = 0xD35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311
-
-curve_brainpoolp320r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
-generator_brainpoolp320r1 = ellipticcurve.PointJacobi(
- curve_brainpoolp320r1, _Gx, _Gy, 1, _q, generator=True)
-
-# Brainpool P-384-r1
-_a = 0x7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826
-_b = 0x04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11
-_p = 0x8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53
-_Gx = 0x1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E
-_Gy = 0x8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315
-_q = 0x8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565
-
-curve_brainpoolp384r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
-generator_brainpoolp384r1 = ellipticcurve.PointJacobi(
- curve_brainpoolp384r1, _Gx, _Gy, 1, _q, generator=True)
-
-# Brainpool P-512-r1
-_a = 0x7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA
-_b = 0x3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723
-_p = 0xAADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3
-_Gx = 0x81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822
-_Gy = 0x7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892
-_q = 0xAADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069
-
-curve_brainpoolp512r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
-generator_brainpoolp512r1 = ellipticcurve.PointJacobi(
- curve_brainpoolp512r1, _Gx, _Gy, 1, _q, generator=True)
diff --git a/freezed_deps/ecdsa/ellipticcurve.py b/freezed_deps/ecdsa/ellipticcurve.py
deleted file mode 100644
index 3420454..0000000
--- a/freezed_deps/ecdsa/ellipticcurve.py
+++ /dev/null
@@ -1,780 +0,0 @@
-#! /usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-# Implementation of elliptic curves, for cryptographic applications.
-#
-# This module doesn't provide any way to choose a random elliptic
-# curve, nor to verify that an elliptic curve was chosen randomly,
-# because one can simply use NIST's standard curves.
-#
-# Notes from X9.62-1998 (draft):
-# Nomenclature:
-# - Q is a public key.
-# The "Elliptic Curve Domain Parameters" include:
-# - q is the "field size", which in our case equals p.
-# - p is a big prime.
-# - G is a point of prime order (5.1.1.1).
-# - n is the order of G (5.1.1.1).
-# Public-key validation (5.2.2):
-# - Verify that Q is not the point at infinity.
-# - Verify that X_Q and Y_Q are in [0,p-1].
-# - Verify that Q is on the curve.
-# - Verify that nQ is the point at infinity.
-# Signature generation (5.3):
-# - Pick random k from [1,n-1].
-# Signature checking (5.4.2):
-# - Verify that r and s are in [1,n-1].
-#
-# Version of 2008.11.25.
-#
-# Revision history:
-# 2005.12.31 - Initial version.
-# 2008.11.25 - Change CurveFp.is_on to contains_point.
-#
-# Written in 2005 by Peter Pearson and placed in the public domain.
-
-from __future__ import division
-
-try:
- from gmpy2 import mpz
- GMPY = True
-except ImportError:
- try:
- from gmpy import mpz
- GMPY = True
- except ImportError:
- GMPY = False
-
-
-from six import python_2_unicode_compatible
-from . import numbertheory
-from ._rwlock import RWLock
-
-
-@python_2_unicode_compatible
-class CurveFp(object):
- """Elliptic Curve over the field of integers modulo a prime."""
-
- if GMPY:
- def __init__(self, p, a, b, h=None):
- """
- The curve of points satisfying y^2 = x^3 + a*x + b (mod p).
-
- h is an integer that is the cofactor of the elliptic curve domain
- parameters; it is the number of points satisfying the elliptic curve
- equation divided by the order of the base point. It is used for selection
- of efficient algorithm for public point verification.
- """
- self.__p = mpz(p)
- self.__a = mpz(a)
- self.__b = mpz(b)
- # h is not used in calculations and it can be None, so don't use
- # gmpy with it
- self.__h = h
- else:
- def __init__(self, p, a, b, h=None):
- """
- The curve of points satisfying y^2 = x^3 + a*x + b (mod p).
-
- h is an integer that is the cofactor of the elliptic curve domain
- parameters; it is the number of points satisfying the elliptic curve
- equation divided by the order of the base point. It is used for selection
- of efficient algorithm for public point verification.
- """
- self.__p = p
- self.__a = a
- self.__b = b
- self.__h = h
-
- def __eq__(self, other):
- if isinstance(other, CurveFp):
- """Return True if the curves are identical, False otherwise."""
- return self.__p == other.__p \
- and self.__a == other.__a \
- and self.__b == other.__b
- return NotImplemented
-
- def __hash__(self):
- return hash((self.__p, self.__a, self.__b))
-
- def p(self):
- return self.__p
-
- def a(self):
- return self.__a
-
- def b(self):
- return self.__b
-
- def cofactor(self):
- return self.__h
-
- def contains_point(self, x, y):
- """Is the point (x,y) on this curve?"""
- return (y * y - ((x * x + self.__a) * x + self.__b)) % self.__p == 0
-
- def __str__(self):
- return "CurveFp(p=%d, a=%d, b=%d, h=%d)" % (
- self.__p, self.__a, self.__b, self.__h)
-
-
-class PointJacobi(object):
- """
- Point on an elliptic curve. Uses Jacobi coordinates.
-
- In Jacobian coordinates, there are three parameters, X, Y and Z.
- They correspond to affine parameters 'x' and 'y' like so:
-
- x = X / Z²
- y = Y / Z³
- """
- def __init__(self, curve, x, y, z, order=None, generator=False):
- """
- Initialise a point that uses Jacobi representation internally.
-
- :param CurveFp curve: curve on which the point resides
- :param int x: the X parameter of Jacobi representation (equal to x when
- converting from affine coordinates
- :param int y: the Y parameter of Jacobi representation (equal to y when
- converting from affine coordinates
- :param int z: the Z parameter of Jacobi representation (equal to 1 when
- converting from affine coordinates
- :param int order: the point order, must be non zero when using
- generator=True
- :param bool generator: the point provided is a curve generator, as
- such, it will be commonly used with scalar multiplication. This will
- cause to precompute multiplication table for it
- """
- self.__curve = curve
- # since it's generally better (faster) to use scaled points vs unscaled
- # ones, use writer-biased RWLock for locking:
- self._scale_lock = RWLock()
- if GMPY:
- self.__x = mpz(x)
- self.__y = mpz(y)
- self.__z = mpz(z)
- self.__order = order and mpz(order)
- else:
- self.__x = x
- self.__y = y
- self.__z = z
- self.__order = order
- self.__precompute = []
- if generator:
- assert order
- i = 1
- order *= 2
- doubler = PointJacobi(curve, x, y, z, order)
- order *= 2
- self.__precompute.append((doubler.x(), doubler.y()))
-
- while i < order:
- i *= 2
- doubler = doubler.double().scale()
- self.__precompute.append((doubler.x(), doubler.y()))
-
- def __eq__(self, other):
- """Compare two points with each-other."""
- try:
- self._scale_lock.reader_acquire()
- if other is INFINITY:
- return not self.__y or not self.__z
- x1, y1, z1 = self.__x, self.__y, self.__z
- finally:
- self._scale_lock.reader_release()
- if isinstance(other, Point):
- x2, y2, z2 = other.x(), other.y(), 1
- elif isinstance(other, PointJacobi):
- try:
- other._scale_lock.reader_acquire()
- x2, y2, z2 = other.__x, other.__y, other.__z
- finally:
- other._scale_lock.reader_release()
- else:
- return NotImplemented
- if self.__curve != other.curve():
- return False
- p = self.__curve.p()
-
- zz1 = z1 * z1 % p
- zz2 = z2 * z2 % p
-
- # compare the fractions by bringing them to the same denominator
- # depend on short-circuit to save 4 multiplications in case of inequality
- return (x1 * zz2 - x2 * zz1) % p == 0 and \
- (y1 * zz2 * z2 - y2 * zz1 * z1) % p == 0
-
- def order(self):
- """Return the order of the point.
-
- None if it is undefined.
- """
- return self.__order
-
- def curve(self):
- """Return curve over which the point is defined."""
- return self.__curve
-
- def x(self):
- """
- Return affine x coordinate.
-
- This method should be used only when the 'y' coordinate is not needed.
- It's computationally more efficient to use `to_affine()` and then
- call x() and y() on the returned instance. Or call `scale()`
- and then x() and y() on the returned instance.
- """
- try:
- self._scale_lock.reader_acquire()
- if self.__z == 1:
- return self.__x
- x = self.__x
- z = self.__z
- finally:
- self._scale_lock.reader_release()
- p = self.__curve.p()
- z = numbertheory.inverse_mod(z, p)
- return x * z**2 % p
-
- def y(self):
- """
- Return affine y coordinate.
-
- This method should be used only when the 'x' coordinate is not needed.
- It's computationally more efficient to use `to_affine()` and then
- call x() and y() on the returned instance. Or call `scale()`
- and then x() and y() on the returned instance.
- """
- try:
- self._scale_lock.reader_acquire()
- if self.__z == 1:
- return self.__y
- y = self.__y
- z = self.__z
- finally:
- self._scale_lock.reader_release()
- p = self.__curve.p()
- z = numbertheory.inverse_mod(z, p)
- return y * z**3 % p
-
- def scale(self):
- """
- Return point scaled so that z == 1.
-
- Modifies point in place, returns self.
- """
- try:
- self._scale_lock.reader_acquire()
- if self.__z == 1:
- return self
- finally:
- self._scale_lock.reader_release()
-
- try:
- self._scale_lock.writer_acquire()
- # scaling already scaled point is safe (as inverse of 1 is 1) and
- # quick so we don't need to optimise for the unlikely event when
- # two threads hit the lock at the same time
- p = self.__curve.p()
- z_inv = numbertheory.inverse_mod(self.__z, p)
- zz_inv = z_inv * z_inv % p
- self.__x = self.__x * zz_inv % p
- self.__y = self.__y * zz_inv * z_inv % p
- # we are setting the z last so that the check above will return true
- # only after all values were already updated
- self.__z = 1
- finally:
- self._scale_lock.writer_release()
- return self
-
- def to_affine(self):
- """Return point in affine form."""
- if not self.__y or not self.__z:
- return INFINITY
- self.scale()
- # after point is scaled, it's immutable, so no need to perform locking
- return Point(self.__curve, self.__x,
- self.__y, self.__order)
-
- @staticmethod
- def from_affine(point, generator=False):
- """Create from an affine point.
-
- :param bool generator: set to True to make the point to precalculate
- multiplication table - useful for public point when verifying many
- signatures (around 100 or so) or for generator points of a curve.
- """
- return PointJacobi(point.curve(), point.x(), point.y(), 1,
- point.order(), generator)
-
- # plese note that all the methods that use the equations from hyperelliptic
- # are formatted in a way to maximise performance.
- # Things that make code faster: multiplying instead of taking to the power
- # (`xx = x * x; xxxx = xx * xx % p` is faster than `xxxx = x**4 % p` and
- # `pow(x, 4, p)`),
- # multiple assignments at the same time (`x1, x2 = self.x1, self.x2` is
- # faster than `x1 = self.x1; x2 = self.x2`),
- # similarly, sometimes the `% p` is skipped if it makes the calculation
- # faster and the result of calculation is later reduced modulo `p`
-
- def _double_with_z_1(self, X1, Y1, p, a):
- """Add a point to itself with z == 1."""
- # after:
- # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-mdbl-2007-bl
- XX, YY = X1 * X1 % p, Y1 * Y1 % p
- if not YY:
- return 0, 0, 1
- YYYY = YY * YY % p
- S = 2 * ((X1 + YY)**2 - XX - YYYY) % p
- M = 3 * XX + a
- T = (M * M - 2 * S) % p
- # X3 = T
- Y3 = (M * (S - T) - 8 * YYYY) % p
- Z3 = 2 * Y1 % p
- return T, Y3, Z3
-
- def _double(self, X1, Y1, Z1, p, a):
- """Add a point to itself, arbitrary z."""
- if Z1 == 1:
- return self._double_with_z_1(X1, Y1, p, a)
- if not Z1:
- return 0, 0, 1
- # after:
- # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl
- XX, YY = X1 * X1 % p, Y1 * Y1 % p
- if not YY:
- return 0, 0, 1
- YYYY = YY * YY % p
- ZZ = Z1 * Z1 % p
- S = 2 * ((X1 + YY)**2 - XX - YYYY) % p
- M = (3 * XX + a * ZZ * ZZ) % p
- T = (M * M - 2 * S) % p
- # X3 = T
- Y3 = (M * (S - T) - 8 * YYYY) % p
- Z3 = ((Y1 + Z1)**2 - YY - ZZ) % p
-
- return T, Y3, Z3
-
- def double(self):
- """Add a point to itself."""
- if not self.__y:
- return INFINITY
-
- p, a = self.__curve.p(), self.__curve.a()
-
- try:
- self._scale_lock.reader_acquire()
- X1, Y1, Z1 = self.__x, self.__y, self.__z
- finally:
- self._scale_lock.reader_release()
-
- X3, Y3, Z3 = self._double(X1, Y1, Z1, p, a)
-
- if not Y3 or not Z3:
- return INFINITY
- return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
-
- def _add_with_z_1(self, X1, Y1, X2, Y2, p):
- """add points when both Z1 and Z2 equal 1"""
- # after:
- # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-mmadd-2007-bl
- H = X2 - X1
- HH = H * H
- I = 4 * HH % p
- J = H * I
- r = 2 * (Y2 - Y1)
- if not H and not r:
- return self._double_with_z_1(X1, Y1, p, self.__curve.a())
- V = X1 * I
- X3 = (r**2 - J - 2 * V) % p
- Y3 = (r * (V - X3) - 2 * Y1 * J) % p
- Z3 = 2 * H % p
- return X3, Y3, Z3
-
- def _add_with_z_eq(self, X1, Y1, Z1, X2, Y2, p):
- """add points when Z1 == Z2"""
- # after:
- # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-zadd-2007-m
- A = (X2 - X1)**2 % p
- B = X1 * A % p
- C = X2 * A
- D = (Y2 - Y1)**2 % p
- if not A and not D:
- return self._double(X1, Y1, Z1, p, self.__curve.a())
- X3 = (D - B - C) % p
- Y3 = ((Y2 - Y1) * (B - X3) - Y1 * (C - B)) % p
- Z3 = Z1 * (X2 - X1) % p
- return X3, Y3, Z3
-
- def _add_with_z2_1(self, X1, Y1, Z1, X2, Y2, p):
- """add points when Z2 == 1"""
- # after:
- # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-madd-2007-bl
- Z1Z1 = Z1 * Z1 % p
- U2, S2 = X2 * Z1Z1 % p, Y2 * Z1 * Z1Z1 % p
- H = (U2 - X1) % p
- HH = H * H % p
- I = 4 * HH % p
- J = H * I
- r = 2 * (S2 - Y1) % p
- if not r and not H:
- return self._double_with_z_1(X2, Y2, p, self.__curve.a())
- V = X1 * I
- X3 = (r * r - J - 2 * V) % p
- Y3 = (r * (V - X3) - 2 * Y1 * J) % p
- Z3 = ((Z1 + H)**2 - Z1Z1 - HH) % p
- return X3, Y3, Z3
-
- def _add_with_z_ne(self, X1, Y1, Z1, X2, Y2, Z2, p):
- """add points with arbitrary z"""
- # after:
- # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-add-2007-bl
- Z1Z1 = Z1 * Z1 % p
- Z2Z2 = Z2 * Z2 % p
- U1 = X1 * Z2Z2 % p
- U2 = X2 * Z1Z1 % p
- S1 = Y1 * Z2 * Z2Z2 % p
- S2 = Y2 * Z1 * Z1Z1 % p
- H = U2 - U1
- I = 4 * H * H % p
- J = H * I % p
- r = 2 * (S2 - S1) % p
- if not H and not r:
- return self._double(X1, Y1, Z1, p, self.__curve.a())
- V = U1 * I
- X3 = (r * r - J - 2 * V) % p
- Y3 = (r * (V - X3) - 2 * S1 * J) % p
- Z3 = ((Z1 + Z2)**2 - Z1Z1 - Z2Z2) * H % p
-
- return X3, Y3, Z3
-
- def __radd__(self, other):
- """Add other to self."""
- return self + other
-
- def _add(self, X1, Y1, Z1, X2, Y2, Z2, p):
- """add two points, select fastest method."""
- if not Y1 or not Z1:
- return X2, Y2, Z2
- if not Y2 or not Z2:
- return X1, Y1, Z1
- if Z1 == Z2:
- if Z1 == 1:
- return self._add_with_z_1(X1, Y1, X2, Y2, p)
- return self._add_with_z_eq(X1, Y1, Z1, X2, Y2, p)
- if Z1 == 1:
- return self._add_with_z2_1(X2, Y2, Z2, X1, Y1, p)
- if Z2 == 1:
- return self._add_with_z2_1(X1, Y1, Z1, X2, Y2, p)
- return self._add_with_z_ne(X1, Y1, Z1, X2, Y2, Z2, p)
-
- def __add__(self, other):
- """Add two points on elliptic curve."""
- if self == INFINITY:
- return other
- if other == INFINITY:
- return self
- if isinstance(other, Point):
- other = PointJacobi.from_affine(other)
- if self.__curve != other.__curve:
- raise ValueError("The other point is on different curve")
-
- p = self.__curve.p()
- try:
- self._scale_lock.reader_acquire()
- X1, Y1, Z1 = self.__x, self.__y, self.__z
- finally:
- self._scale_lock.reader_release()
- try:
- other._scale_lock.reader_acquire()
- X2, Y2, Z2 = other.__x, other.__y, other.__z
- finally:
- other._scale_lock.reader_release()
- X3, Y3, Z3 = self._add(X1, Y1, Z1, X2, Y2, Z2, p)
-
- if not Y3 or not Z3:
- return INFINITY
- return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
-
- def __rmul__(self, other):
- """Multiply point by an integer."""
- return self * other
-
- def _mul_precompute(self, other):
- """Multiply point by integer with precomputation table."""
- X3, Y3, Z3, p = 0, 0, 1, self.__curve.p()
- _add = self._add
- for X2, Y2 in self.__precompute:
- if other % 2:
- if other % 4 >= 2:
- other = (other + 1)//2
- X3, Y3, Z3 = _add(X3, Y3, Z3, X2, -Y2, 1, p)
- else:
- other = (other - 1)//2
- X3, Y3, Z3 = _add(X3, Y3, Z3, X2, Y2, 1, p)
- else:
- other //= 2
-
- if not Y3 or not Z3:
- return INFINITY
- return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
-
- @staticmethod
- def _naf(mult):
- """Calculate non-adjacent form of number."""
- ret = []
- while mult:
- if mult % 2:
- nd = mult % 4
- if nd >= 2:
- nd = nd - 4
- ret += [nd]
- mult -= nd
- else:
- ret += [0]
- mult //= 2
- return ret
-
- def __mul__(self, other):
- """Multiply point by an integer."""
- if not self.__y or not other:
- return INFINITY
- if other == 1:
- return self
- if self.__order:
- # order*2 as a protection for Minerva
- other = other % (self.__order*2)
- if self.__precompute:
- return self._mul_precompute(other)
-
- self = self.scale()
- # once scaled, point is immutable, not need to lock
- X2, Y2 = self.__x, self.__y
- X3, Y3, Z3 = 0, 0, 1
- p, a = self.__curve.p(), self.__curve.a()
- _double = self._double
- _add = self._add
- # since adding points when at least one of them is scaled
- # is quicker, reverse the NAF order
- for i in reversed(self._naf(other)):
- X3, Y3, Z3 = _double(X3, Y3, Z3, p, a)
- if i < 0:
- X3, Y3, Z3 = _add(X3, Y3, Z3, X2, -Y2, 1, p)
- elif i > 0:
- X3, Y3, Z3 = _add(X3, Y3, Z3, X2, Y2, 1, p)
-
- if not Y3 or not Z3:
- return INFINITY
-
- return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
-
- @staticmethod
- def _leftmost_bit(x):
- """Return integer with the same magnitude as x but hamming weight of 1"""
- assert x > 0
- result = 1
- while result <= x:
- result = 2 * result
- return result // 2
-
- def mul_add(self, self_mul, other, other_mul):
- """
- Do two multiplications at the same time, add results.
-
- calculates self*self_mul + other*other_mul
- """
- if other is INFINITY or other_mul == 0:
- return self * self_mul
- if self_mul == 0:
- return other * other_mul
- if not isinstance(other, PointJacobi):
- other = PointJacobi.from_affine(other)
- # when the points have precomputed answers, then multiplying them alone
- # is faster (as it uses NAF)
- if self.__precompute and other.__precompute:
- return self * self_mul + other * other_mul
-
- if self.__order:
- self_mul = self_mul % self.__order
- other_mul = other_mul % self.__order
-
- i = self._leftmost_bit(max(self_mul, other_mul))*2
- X3, Y3, Z3 = 0, 0, 1
- p, a = self.__curve.p(), self.__curve.a()
- self = self.scale()
- # after scaling, point is immutable, no need for locking
- X1, Y1 = self.__x, self.__y
- other = other.scale()
- X2, Y2 = other.__x, other.__y
- both = (self + other).scale()
- X4, Y4 = both.__x, both.__y
- _double = self._double
- _add = self._add
- while i > 1:
- X3, Y3, Z3 = _double(X3, Y3, Z3, p, a)
- i = i // 2
-
- if self_mul & i and other_mul & i:
- X3, Y3, Z3 = _add(X3, Y3, Z3, X4, Y4, 1, p)
- elif self_mul & i:
- X3, Y3, Z3 = _add(X3, Y3, Z3, X1, Y1, 1, p)
- elif other_mul & i:
- X3, Y3, Z3 = _add(X3, Y3, Z3, X2, Y2, 1, p)
-
- if not Y3 or not Z3:
- return INFINITY
-
- return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
-
- def __neg__(self):
- """Return negated point."""
- try:
- self._scale_lock.reader_acquire()
- return PointJacobi(self.__curve, self.__x, -self.__y, self.__z,
- self.__order)
- finally:
- self._scale_lock.reader_release()
-
-
-class Point(object):
- """A point on an elliptic curve. Altering x and y is forbidding,
- but they can be read by the x() and y() methods."""
- def __init__(self, curve, x, y, order=None):
- """curve, x, y, order; order (optional) is the order of this point."""
- self.__curve = curve
- if GMPY:
- self.__x = x and mpz(x)
- self.__y = y and mpz(y)
- self.__order = order and mpz(order)
- else:
- self.__x = x
- self.__y = y
- self.__order = order
- # self.curve is allowed to be None only for INFINITY:
- if self.__curve:
- assert self.__curve.contains_point(x, y)
- # for curves with cofactor 1, all points that are on the curve are scalar
- # multiples of the base point, so performing multiplication is not
- # necessary to verify that. See Section 3.2.2.1 of SEC 1 v2
- if curve and curve.cofactor() != 1 and order:
- assert self * order == INFINITY
-
- def __eq__(self, other):
- """Return True if the points are identical, False otherwise."""
- if isinstance(other, Point):
- return self.__curve == other.__curve \
- and self.__x == other.__x \
- and self.__y == other.__y
- return NotImplemented
-
- def __neg__(self):
- return Point(self.__curve, self.__x, self.__curve.p() - self.__y)
-
- def __add__(self, other):
- """Add one point to another point."""
-
- # X9.62 B.3:
-
- if not isinstance(other, Point):
- return NotImplemented
- if other == INFINITY:
- return self
- if self == INFINITY:
- return other
- assert self.__curve == other.__curve
- if self.__x == other.__x:
- if (self.__y + other.__y) % self.__curve.p() == 0:
- return INFINITY
- else:
- return self.double()
-
- p = self.__curve.p()
-
- l = ((other.__y - self.__y) * \
- numbertheory.inverse_mod(other.__x - self.__x, p)) % p
-
- x3 = (l * l - self.__x - other.__x) % p
- y3 = (l * (self.__x - x3) - self.__y) % p
-
- return Point(self.__curve, x3, y3)
-
- def __mul__(self, other):
- """Multiply a point by an integer."""
-
- def leftmost_bit(x):
- assert x > 0
- result = 1
- while result <= x:
- result = 2 * result
- return result // 2
-
- e = other
- if e == 0 or (self.__order and e % self.__order == 0):
- return INFINITY
- if self == INFINITY:
- return INFINITY
- if e < 0:
- return (-self) * (-e)
-
- # From X9.62 D.3.2:
-
- e3 = 3 * e
- negative_self = Point(self.__curve, self.__x, -self.__y, self.__order)
- i = leftmost_bit(e3) // 2
- result = self
- # print_("Multiplying %s by %d (e3 = %d):" % (self, other, e3))
- while i > 1:
- result = result.double()
- if (e3 & i) != 0 and (e & i) == 0:
- result = result + self
- if (e3 & i) == 0 and (e & i) != 0:
- result = result + negative_self
- # print_(". . . i = %d, result = %s" % ( i, result ))
- i = i // 2
-
- return result
-
- def __rmul__(self, other):
- """Multiply a point by an integer."""
-
- return self * other
-
- def __str__(self):
- if self == INFINITY:
- return "infinity"
- return "(%d,%d)" % (self.__x, self.__y)
-
- def double(self):
- """Return a new point that is twice the old."""
-
- if self == INFINITY:
- return INFINITY
-
- # X9.62 B.3:
-
- p = self.__curve.p()
- a = self.__curve.a()
-
- l = ((3 * self.__x * self.__x + a) * \
- numbertheory.inverse_mod(2 * self.__y, p)) % p
-
- x3 = (l * l - 2 * self.__x) % p
- y3 = (l * (self.__x - x3) - self.__y) % p
-
- return Point(self.__curve, x3, y3)
-
- def x(self):
- return self.__x
-
- def y(self):
- return self.__y
-
- def curve(self):
- return self.__curve
-
- def order(self):
- return self.__order
-
-
-# This one point is the Point At Infinity for all purposes:
-INFINITY = Point(None, None, None)
diff --git a/freezed_deps/ecdsa/numbertheory.py b/freezed_deps/ecdsa/numbertheory.py
deleted file mode 100644
index b300440..0000000
--- a/freezed_deps/ecdsa/numbertheory.py
+++ /dev/null
@@ -1,600 +0,0 @@
-#! /usr/bin/env python
-#
-# Provide some simple capabilities from number theory.
-#
-# Version of 2008.11.14.
-#
-# Written in 2005 and 2006 by Peter Pearson and placed in the public domain.
-# Revision history:
-# 2008.11.14: Use pow(base, exponent, modulus) for modular_exp.
-# Make gcd and lcm accept arbitrarly many arguments.
-
-from __future__ import division
-
-from six import integer_types, PY3
-from six.moves import reduce
-try:
- xrange
-except NameError:
- xrange = range
-try:
- from gmpy2 import powmod
- GMPY2 = True
- GMPY = False
-except ImportError:
- GMPY2 = False
- try:
- from gmpy import mpz
- GMPY = True
- except ImportError:
- GMPY = False
-
-import math
-import warnings
-
-
-class Error(Exception):
- """Base class for exceptions in this module."""
- pass
-
-
-class SquareRootError(Error):
- pass
-
-
-class NegativeExponentError(Error):
- pass
-
-
-def modular_exp(base, exponent, modulus): # pragma: no cover
- """Raise base to exponent, reducing by modulus"""
- # deprecated in 0.14
- warnings.warn("Function is unused in library code. If you use this code, "
- "change to pow() builtin.", DeprecationWarning)
- if exponent < 0:
- raise NegativeExponentError("Negative exponents (%d) not allowed"
- % exponent)
- return pow(base, exponent, modulus)
-
-
-def polynomial_reduce_mod(poly, polymod, p):
- """Reduce poly by polymod, integer arithmetic modulo p.
-
- Polynomials are represented as lists of coefficients
- of increasing powers of x."""
-
- # This module has been tested only by extensive use
- # in calculating modular square roots.
-
- # Just to make this easy, require a monic polynomial:
- assert polymod[-1] == 1
-
- assert len(polymod) > 1
-
- while len(poly) >= len(polymod):
- if poly[-1] != 0:
- for i in xrange(2, len(polymod) + 1):
- poly[-i] = (poly[-i] - poly[-1] * polymod[-i]) % p
- poly = poly[0:-1]
-
- return poly
-
-
-def polynomial_multiply_mod(m1, m2, polymod, p):
- """Polynomial multiplication modulo a polynomial over ints mod p.
-
- Polynomials are represented as lists of coefficients
- of increasing powers of x."""
-
- # This is just a seat-of-the-pants implementation.
-
- # This module has been tested only by extensive use
- # in calculating modular square roots.
-
- # Initialize the product to zero:
-
- prod = (len(m1) + len(m2) - 1) * [0]
-
- # Add together all the cross-terms:
-
- for i in xrange(len(m1)):
- for j in xrange(len(m2)):
- prod[i + j] = (prod[i + j] + m1[i] * m2[j]) % p
-
- return polynomial_reduce_mod(prod, polymod, p)
-
-
-def polynomial_exp_mod(base, exponent, polymod, p):
- """Polynomial exponentiation modulo a polynomial over ints mod p.
-
- Polynomials are represented as lists of coefficients
- of increasing powers of x."""
-
- # Based on the Handbook of Applied Cryptography, algorithm 2.227.
-
- # This module has been tested only by extensive use
- # in calculating modular square roots.
-
- assert exponent < p
-
- if exponent == 0:
- return [1]
-
- G = base
- k = exponent
- if k % 2 == 1:
- s = G
- else:
- s = [1]
-
- while k > 1:
- k = k // 2
- G = polynomial_multiply_mod(G, G, polymod, p)
- if k % 2 == 1:
- s = polynomial_multiply_mod(G, s, polymod, p)
-
- return s
-
-
-def jacobi(a, n):
- """Jacobi symbol"""
-
- # Based on the Handbook of Applied Cryptography (HAC), algorithm 2.149.
-
- # This function has been tested by comparison with a small
- # table printed in HAC, and by extensive use in calculating
- # modular square roots.
-
- assert n >= 3
- assert n % 2 == 1
- a = a % n
- if a == 0:
- return 0
- if a == 1:
- return 1
- a1, e = a, 0
- while a1 % 2 == 0:
- a1, e = a1 // 2, e + 1
- if e % 2 == 0 or n % 8 == 1 or n % 8 == 7:
- s = 1
- else:
- s = -1
- if a1 == 1:
- return s
- if n % 4 == 3 and a1 % 4 == 3:
- s = -s
- return s * jacobi(n % a1, a1)
-
-
-def square_root_mod_prime(a, p):
- """Modular square root of a, mod p, p prime."""
-
- # Based on the Handbook of Applied Cryptography, algorithms 3.34 to 3.39.
-
- # This module has been tested for all values in [0,p-1] for
- # every prime p from 3 to 1229.
-
- assert 0 <= a < p
- assert 1 < p
-
- if a == 0:
- return 0
- if p == 2:
- return a
-
- jac = jacobi(a, p)
- if jac == -1:
- raise SquareRootError("%d has no square root modulo %d" \
- % (a, p))
-
- if p % 4 == 3:
- return pow(a, (p + 1) // 4, p)
-
- if p % 8 == 5:
- d = pow(a, (p - 1) // 4, p)
- if d == 1:
- return pow(a, (p + 3) // 8, p)
- if d == p - 1:
- return (2 * a * pow(4 * a, (p - 5) // 8, p)) % p
- raise RuntimeError("Shouldn't get here.")
-
- if PY3:
- range_top = p
- else:
- # xrange on python2 can take integers representable as C long only
- range_top = min(0x7fffffff, p)
- for b in xrange(2, range_top):
- if jacobi(b * b - 4 * a, p) == -1:
- f = (a, -b, 1)
- ff = polynomial_exp_mod((0, 1), (p + 1) // 2, f, p)
- assert ff[1] == 0
- return ff[0]
- raise RuntimeError("No b found.")
-
-
-if GMPY2:
- def inverse_mod(a, m):
- """Inverse of a mod m."""
- if a == 0:
- return 0
- return powmod(a, -1, m)
-elif GMPY:
- def inverse_mod(a, m):
- """Inverse of a mod m."""
- # while libgmp likely does support inverses modulo, it is accessible
- # only using the native `pow()` function, and `pow()` sanity checks
- # the parameters before passing them on to underlying implementation
- # on Python2
- if a == 0:
- return 0
- a = mpz(a)
- m = mpz(m)
-
- lm, hm = mpz(1), mpz(0)
- low, high = a % m, m
- while low > 1:
- r = high // low
- lm, low, hm, high = hm - lm * r, high - low * r, lm, low
-
- return lm % m
-else:
- def inverse_mod(a, m):
- """Inverse of a mod m."""
-
- if a == 0:
- return 0
-
- lm, hm = 1, 0
- low, high = a % m, m
- while low > 1:
- r = high // low
- lm, low, hm, high = hm - lm * r, high - low * r, lm, low
-
- return lm % m
-
-
-try:
- gcd2 = math.gcd
-except AttributeError:
- def gcd2(a, b):
- """Greatest common divisor using Euclid's algorithm."""
- while a:
- a, b = b % a, a
- return b
-
-
-def gcd(*a):
- """Greatest common divisor.
-
- Usage: gcd([ 2, 4, 6 ])
- or: gcd(2, 4, 6)
- """
-
- if len(a) > 1:
- return reduce(gcd2, a)
- if hasattr(a[0], "__iter__"):
- return reduce(gcd2, a[0])
- return a[0]
-
-
-def lcm2(a, b):
- """Least common multiple of two integers."""
-
- return (a * b) // gcd(a, b)
-
-
-def lcm(*a):
- """Least common multiple.
-
- Usage: lcm([ 3, 4, 5 ])
- or: lcm(3, 4, 5)
- """
-
- if len(a) > 1:
- return reduce(lcm2, a)
- if hasattr(a[0], "__iter__"):
- return reduce(lcm2, a[0])
- return a[0]
-
-
-def factorization(n):
- """Decompose n into a list of (prime,exponent) pairs."""
-
- assert isinstance(n, integer_types)
-
- if n < 2:
- return []
-
- result = []
- d = 2
-
- # Test the small primes:
-
- for d in smallprimes:
- if d > n:
- break
- q, r = divmod(n, d)
- if r == 0:
- count = 1
- while d <= n:
- n = q
- q, r = divmod(n, d)
- if r != 0:
- break
- count = count + 1
- result.append((d, count))
-
- # If n is still greater than the last of our small primes,
- # it may require further work:
-
- if n > smallprimes[-1]:
- if is_prime(n): # If what's left is prime, it's easy:
- result.append((n, 1))
- else: # Ugh. Search stupidly for a divisor:
- d = smallprimes[-1]
- while 1:
- d = d + 2 # Try the next divisor.
- q, r = divmod(n, d)
- if q < d: # n < d*d means we're done, n = 1 or prime.
- break
- if r == 0: # d divides n. How many times?
- count = 1
- n = q
- while d <= n: # As long as d might still divide n,
- q, r = divmod(n, d) # see if it does.
- if r != 0:
- break
- n = q # It does. Reduce n, increase count.
- count = count + 1
- result.append((d, count))
- if n > 1:
- result.append((n, 1))
-
- return result
-
-
-def phi(n): # pragma: no cover
- """Return the Euler totient function of n."""
- # deprecated in 0.14
- warnings.warn("Function is unused by library code. If you use this code, "
- "please open an issue in "
- "https://github.com/warner/python-ecdsa",
- DeprecationWarning)
-
- assert isinstance(n, integer_types)
-
- if n < 3:
- return 1
-
- result = 1
- ff = factorization(n)
- for f in ff:
- e = f[1]
- if e > 1:
- result = result * f[0] ** (e - 1) * (f[0] - 1)
- else:
- result = result * (f[0] - 1)
- return result
-
-
-def carmichael(n): # pragma: no cover
- """Return Carmichael function of n.
-
- Carmichael(n) is the smallest integer x such that
- m**x = 1 mod n for all m relatively prime to n.
- """
- # deprecated in 0.14
- warnings.warn("Function is unused by library code. If you use this code, "
- "please open an issue in "
- "https://github.com/warner/python-ecdsa",
- DeprecationWarning)
-
- return carmichael_of_factorized(factorization(n))
-
-
-def carmichael_of_factorized(f_list): # pragma: no cover
- """Return the Carmichael function of a number that is
- represented as a list of (prime,exponent) pairs.
- """
- # deprecated in 0.14
- warnings.warn("Function is unused by library code. If you use this code, "
- "please open an issue in "
- "https://github.com/warner/python-ecdsa",
- DeprecationWarning)
-
- if len(f_list) < 1:
- return 1
-
- result = carmichael_of_ppower(f_list[0])
- for i in xrange(1, len(f_list)):
- result = lcm(result, carmichael_of_ppower(f_list[i]))
-
- return result
-
-
-def carmichael_of_ppower(pp): # pragma: no cover
- """Carmichael function of the given power of the given prime.
- """
- # deprecated in 0.14
- warnings.warn("Function is unused by library code. If you use this code, "
- "please open an issue in "
- "https://github.com/warner/python-ecdsa",
- DeprecationWarning)
-
- p, a = pp
- if p == 2 and a > 2:
- return 2**(a - 2)
- else:
- return (p - 1) * p**(a - 1)
-
-
-def order_mod(x, m): # pragma: no cover
- """Return the order of x in the multiplicative group mod m.
- """
- # deprecated in 0.14
- warnings.warn("Function is unused by library code. If you use this code, "
- "please open an issue in "
- "https://github.com/warner/python-ecdsa",
- DeprecationWarning)
-
- # Warning: this implementation is not very clever, and will
- # take a long time if m is very large.
-
- if m <= 1:
- return 0
-
- assert gcd(x, m) == 1
-
- z = x
- result = 1
- while z != 1:
- z = (z * x) % m
- result = result + 1
- return result
-
-
-def largest_factor_relatively_prime(a, b): # pragma: no cover
- """Return the largest factor of a relatively prime to b.
- """
- # deprecated in 0.14
- warnings.warn("Function is unused by library code. If you use this code, "
- "please open an issue in "
- "https://github.com/warner/python-ecdsa",
- DeprecationWarning)
-
- while 1:
- d = gcd(a, b)
- if d <= 1:
- break
- b = d
- while 1:
- q, r = divmod(a, d)
- if r > 0:
- break
- a = q
- return a
-
-
-def kinda_order_mod(x, m): # pragma: no cover
- """Return the order of x in the multiplicative group mod m',
- where m' is the largest factor of m relatively prime to x.
- """
- # deprecated in 0.14
- warnings.warn("Function is unused by library code. If you use this code, "
- "please open an issue in "
- "https://github.com/warner/python-ecdsa",
- DeprecationWarning)
-
- return order_mod(x, largest_factor_relatively_prime(m, x))
-
-
-def is_prime(n):
- """Return True if x is prime, False otherwise.
-
- We use the Miller-Rabin test, as given in Menezes et al. p. 138.
- This test is not exact: there are composite values n for which
- it returns True.
-
- In testing the odd numbers from 10000001 to 19999999,
- about 66 composites got past the first test,
- 5 got past the second test, and none got past the third.
- Since factors of 2, 3, 5, 7, and 11 were detected during
- preliminary screening, the number of numbers tested by
- Miller-Rabin was (19999999 - 10000001)*(2/3)*(4/5)*(6/7)
- = 4.57 million.
- """
-
- # (This is used to study the risk of false positives:)
- global miller_rabin_test_count
-
- miller_rabin_test_count = 0
-
- if n <= smallprimes[-1]:
- if n in smallprimes:
- return True
- else:
- return False
-
- if gcd(n, 2 * 3 * 5 * 7 * 11) != 1:
- return False
-
- # Choose a number of iterations sufficient to reduce the
- # probability of accepting a composite below 2**-80
- # (from Menezes et al. Table 4.4):
-
- t = 40
- n_bits = 1 + int(math.log(n, 2))
- for k, tt in ((100, 27),
- (150, 18),
- (200, 15),
- (250, 12),
- (300, 9),
- (350, 8),
- (400, 7),
- (450, 6),
- (550, 5),
- (650, 4),
- (850, 3),
- (1300, 2),
- ):
- if n_bits < k:
- break
- t = tt
-
- # Run the test t times:
-
- s = 0
- r = n - 1
- while (r % 2) == 0:
- s = s + 1
- r = r // 2
- for i in xrange(t):
- a = smallprimes[i]
- y = pow(a, r, n)
- if y != 1 and y != n - 1:
- j = 1
- while j <= s - 1 and y != n - 1:
- y = pow(y, 2, n)
- if y == 1:
- miller_rabin_test_count = i + 1
- return False
- j = j + 1
- if y != n - 1:
- miller_rabin_test_count = i + 1
- return False
- return True
-
-
-def next_prime(starting_value):
- "Return the smallest prime larger than the starting value."
-
- if starting_value < 2:
- return 2
- result = (starting_value + 1) | 1
- while not is_prime(result):
- result = result + 2
- return result
-
-
-smallprimes = [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]
-
-miller_rabin_test_count = 0
diff --git a/freezed_deps/ecdsa/test_ecdsa.py b/freezed_deps/ecdsa/test_ecdsa.py
deleted file mode 100644
index 71c6891..0000000
--- a/freezed_deps/ecdsa/test_ecdsa.py
+++ /dev/null
@@ -1,448 +0,0 @@
-from __future__ import print_function
-import sys
-import hypothesis.strategies as st
-from hypothesis import given, settings, note, example
-try:
- import unittest2 as unittest
-except ImportError:
- import unittest
-import pytest
-from .ecdsa import Private_key, Public_key, Signature, \
- generator_192, digest_integer, ellipticcurve, point_is_valid, \
- generator_224, generator_256, generator_384, generator_521, \
- generator_secp256k1
-
-
-HYP_SETTINGS = {}
-# old hypothesis doesn't have the "deadline" setting
-if sys.version_info > (2, 7): # pragma: no branch
- # SEC521p is slow, allow long execution for it
- HYP_SETTINGS["deadline"] = 5000
-
-
-class TestP192FromX9_62(unittest.TestCase):
- """Check test vectors from X9.62"""
- @classmethod
- def setUpClass(cls):
- cls.d = 651056770906015076056810763456358567190100156695615665659
- cls.Q = cls.d * generator_192
- cls.k = 6140507067065001063065065565667405560006161556565665656654
- cls.R = cls.k * generator_192
-
- cls.msg = 968236873715988614170569073515315707566766479517
- cls.pubk = Public_key(generator_192, generator_192 * cls.d)
- cls.privk = Private_key(cls.pubk, cls.d)
- cls.sig = cls.privk.sign(cls.msg, cls.k)
-
- def test_point_multiplication(self):
- assert self.Q.x() == 0x62B12D60690CDCF330BABAB6E69763B471F994DD702D16A5
-
- def test_point_multiplication_2(self):
- assert self.R.x() == 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD
- assert self.R.y() == 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835
-
- def test_mult_and_addition(self):
- u1 = 2563697409189434185194736134579731015366492496392189760599
- u2 = 6266643813348617967186477710235785849136406323338782220568
- temp = u1 * generator_192 + u2 * self.Q
- assert temp.x() == 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD
- assert temp.y() == 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835
-
- def test_signature(self):
- r, s = self.sig.r, self.sig.s
- assert r == 3342403536405981729393488334694600415596881826869351677613
- assert s == 5735822328888155254683894997897571951568553642892029982342
-
- def test_verification(self):
- assert self.pubk.verifies(self.msg, self.sig)
-
- def test_rejection(self):
- assert not self.pubk.verifies(self.msg - 1, self.sig)
-
-
-class TestPublicKey(unittest.TestCase):
-
- def test_equality_public_keys(self):
- gen = generator_192
- x = 0xc58d61f88d905293bcd4cd0080bcb1b7f811f2ffa41979f6
- y = 0x8804dc7a7c4c7f8b5d437f5156f3312ca7d6de8a0e11867f
- point = ellipticcurve.Point(gen.curve(), x, y)
- pub_key1 = Public_key(gen, point)
- pub_key2 = Public_key(gen, point)
- self.assertEqual(pub_key1, pub_key2)
-
- def test_inequality_public_key(self):
- gen = generator_192
- x1 = 0xc58d61f88d905293bcd4cd0080bcb1b7f811f2ffa41979f6
- y1 = 0x8804dc7a7c4c7f8b5d437f5156f3312ca7d6de8a0e11867f
- point1 = ellipticcurve.Point(gen.curve(), x1, y1)
-
- x2 = 0x6a223d00bd22c52833409a163e057e5b5da1def2a197dd15
- y2 = 0x7b482604199367f1f303f9ef627f922f97023e90eae08abf
- point2 = ellipticcurve.Point(gen.curve(), x2, y2)
-
- pub_key1 = Public_key(gen, point1)
- pub_key2 = Public_key(gen, point2)
- self.assertNotEqual(pub_key1, pub_key2)
-
- def test_inequality_public_key_not_implemented(self):
- gen = generator_192
- x = 0xc58d61f88d905293bcd4cd0080bcb1b7f811f2ffa41979f6
- y = 0x8804dc7a7c4c7f8b5d437f5156f3312ca7d6de8a0e11867f
- point = ellipticcurve.Point(gen.curve(), x, y)
- pub_key = Public_key(gen, point)
- self.assertNotEqual(pub_key, None)
-
-
-class TestPrivateKey(unittest.TestCase):
-
- @classmethod
- def setUpClass(cls):
- gen = generator_192
- x = 0xc58d61f88d905293bcd4cd0080bcb1b7f811f2ffa41979f6
- y = 0x8804dc7a7c4c7f8b5d437f5156f3312ca7d6de8a0e11867f
- point = ellipticcurve.Point(gen.curve(), x, y)
- cls.pub_key = Public_key(gen, point)
-
- def test_equality_private_keys(self):
- pr_key1 = Private_key(self.pub_key, 100)
- pr_key2 = Private_key(self.pub_key, 100)
- self.assertEqual(pr_key1, pr_key2)
-
- def test_inequality_private_keys(self):
- pr_key1 = Private_key(self.pub_key, 100)
- pr_key2 = Private_key(self.pub_key, 200)
- self.assertNotEqual(pr_key1, pr_key2)
-
- def test_inequality_private_keys_not_implemented(self):
- pr_key = Private_key(self.pub_key, 100)
- self.assertNotEqual(pr_key, None)
-
-
-# Testing point validity, as per ECDSAVS.pdf B.2.2:
-P192_POINTS = [
- (generator_192,
- 0xcd6d0f029a023e9aaca429615b8f577abee685d8257cc83a,
- 0x00019c410987680e9fb6c0b6ecc01d9a2647c8bae27721bacdfc,
- False),
-
- (generator_192,
- 0x00017f2fce203639e9eaf9fb50b81fc32776b30e3b02af16c73b,
- 0x95da95c5e72dd48e229d4748d4eee658a9a54111b23b2adb,
- False),
-
- (generator_192,
- 0x4f77f8bc7fccbadd5760f4938746d5f253ee2168c1cf2792,
- 0x000147156ff824d131629739817edb197717c41aab5c2a70f0f6,
- False),
-
- (generator_192,
- 0xc58d61f88d905293bcd4cd0080bcb1b7f811f2ffa41979f6,
- 0x8804dc7a7c4c7f8b5d437f5156f3312ca7d6de8a0e11867f,
- True),
-
- (generator_192,
- 0xcdf56c1aa3d8afc53c521adf3ffb96734a6a630a4a5b5a70,
- 0x97c1c44a5fb229007b5ec5d25f7413d170068ffd023caa4e,
- True),
-
- (generator_192,
- 0x89009c0dc361c81e99280c8e91df578df88cdf4b0cdedced,
- 0x27be44a529b7513e727251f128b34262a0fd4d8ec82377b9,
- True),
-
- (generator_192,
- 0x6a223d00bd22c52833409a163e057e5b5da1def2a197dd15,
- 0x7b482604199367f1f303f9ef627f922f97023e90eae08abf,
- True),
-
- (generator_192,
- 0x6dccbde75c0948c98dab32ea0bc59fe125cf0fb1a3798eda,
- 0x0001171a3e0fa60cf3096f4e116b556198de430e1fbd330c8835,
- False),
-
- (generator_192,
- 0xd266b39e1f491fc4acbbbc7d098430931cfa66d55015af12,
- 0x193782eb909e391a3148b7764e6b234aa94e48d30a16dbb2,
- False),
-
- (generator_192,
- 0x9d6ddbcd439baa0c6b80a654091680e462a7d1d3f1ffeb43,
- 0x6ad8efc4d133ccf167c44eb4691c80abffb9f82b932b8caa,
- False),
-
- (generator_192,
- 0x146479d944e6bda87e5b35818aa666a4c998a71f4e95edbc,
- 0xa86d6fe62bc8fbd88139693f842635f687f132255858e7f6,
- False),
-
- (generator_192,
- 0xe594d4a598046f3598243f50fd2c7bd7d380edb055802253,
- 0x509014c0c4d6b536e3ca750ec09066af39b4c8616a53a923,
- False)]
-
-
[email protected]("generator,x,y,expected", P192_POINTS)
-def test_point_validity(generator, x, y, expected):
- """
- `generator` defines the curve; is `(x, y)` a point on
- this curve? `expected` is True if the right answer is Yes.
- """
- assert point_is_valid(generator, x, y) == expected
-
-
-# Trying signature-verification tests from ECDSAVS.pdf B.2.4:
-CURVE_192_KATS = [
- (generator_192,
- int("0x84ce72aa8699df436059f052ac51b6398d2511e49631bcb7e71f89c499b9ee"
- "425dfbc13a5f6d408471b054f2655617cbbaf7937b7c80cd8865cf02c8487d30"
- "d2b0fbd8b2c4e102e16d828374bbc47b93852f212d5043c3ea720f086178ff79"
- "8cc4f63f787b9c2e419efa033e7644ea7936f54462dc21a6c4580725f7f0e7d1"
- "58", 16),
- 0xd9dbfb332aa8e5ff091e8ce535857c37c73f6250ffb2e7ac,
- 0x282102e364feded3ad15ddf968f88d8321aa268dd483ebc4,
- 0x64dca58a20787c488d11d6dd96313f1b766f2d8efe122916,
- 0x1ecba28141e84ab4ecad92f56720e2cc83eb3d22dec72479,
- True),
-
- (generator_192,
- int("0x94bb5bacd5f8ea765810024db87f4224ad71362a3c28284b2b9f39fab86db1"
- "2e8beb94aae899768229be8fdb6c4f12f28912bb604703a79ccff769c1607f5a"
- "91450f30ba0460d359d9126cbd6296be6d9c4bb96c0ee74cbb44197c207f6db3"
- "26ab6f5a659113a9034e54be7b041ced9dcf6458d7fb9cbfb2744d999f7dfd63"
- "f4", 16),
- 0x3e53ef8d3112af3285c0e74842090712cd324832d4277ae7,
- 0xcc75f8952d30aec2cbb719fc6aa9934590b5d0ff5a83adb7,
- 0x8285261607283ba18f335026130bab31840dcfd9c3e555af,
- 0x356d89e1b04541afc9704a45e9c535ce4a50929e33d7e06c,
- True),
-
- (generator_192,
- int("0xf6227a8eeb34afed1621dcc89a91d72ea212cb2f476839d9b4243c66877911"
- "b37b4ad6f4448792a7bbba76c63bdd63414b6facab7dc71c3396a73bd7ee14cd"
- "d41a659c61c99b779cecf07bc51ab391aa3252386242b9853ea7da67fd768d30"
- "3f1b9b513d401565b6f1eb722dfdb96b519fe4f9bd5de67ae131e64b40e78c42"
- "dd", 16),
- 0x16335dbe95f8e8254a4e04575d736befb258b8657f773cb7,
- 0x421b13379c59bc9dce38a1099ca79bbd06d647c7f6242336,
- 0x4141bd5d64ea36c5b0bd21ef28c02da216ed9d04522b1e91,
- 0x159a6aa852bcc579e821b7bb0994c0861fb08280c38daa09,
- False),
-
- (generator_192,
- int("0x16b5f93afd0d02246f662761ed8e0dd9504681ed02a253006eb36736b56309"
- "7ba39f81c8e1bce7a16c1339e345efabbc6baa3efb0612948ae51103382a8ee8"
- "bc448e3ef71e9f6f7a9676694831d7f5dd0db5446f179bcb737d4a526367a447"
- "bfe2c857521c7f40b6d7d7e01a180d92431fb0bbd29c04a0c420a57b3ed26ccd"
- "8a", 16),
- 0xfd14cdf1607f5efb7b1793037b15bdf4baa6f7c16341ab0b,
- 0x83fa0795cc6c4795b9016dac928fd6bac32f3229a96312c4,
- 0x8dfdb832951e0167c5d762a473c0416c5c15bc1195667dc1,
- 0x1720288a2dc13fa1ec78f763f8fe2ff7354a7e6fdde44520,
- False),
-
- (generator_192,
- int("0x08a2024b61b79d260e3bb43ef15659aec89e5b560199bc82cf7c65c77d3919"
- "2e03b9a895d766655105edd9188242b91fbde4167f7862d4ddd61e5d4ab55196"
- "683d4f13ceb90d87aea6e07eb50a874e33086c4a7cb0273a8e1c4408f4b846bc"
- "eae1ebaac1b2b2ea851a9b09de322efe34cebe601653efd6ddc876ce8c2f2072"
- "fb", 16),
- 0x674f941dc1a1f8b763c9334d726172d527b90ca324db8828,
- 0x65adfa32e8b236cb33a3e84cf59bfb9417ae7e8ede57a7ff,
- 0x9508b9fdd7daf0d8126f9e2bc5a35e4c6d800b5b804d7796,
- 0x36f2bf6b21b987c77b53bb801b3435a577e3d493744bfab0,
- False),
-
- (generator_192,
- int("0x1843aba74b0789d4ac6b0b8923848023a644a7b70afa23b1191829bbe4397c"
- "e15b629bf21a8838298653ed0c19222b95fa4f7390d1b4c844d96e645537e0aa"
- "e98afb5c0ac3bd0e4c37f8daaff25556c64e98c319c52687c904c4de7240a1cc"
- "55cd9756b7edaef184e6e23b385726e9ffcba8001b8f574987c1a3fedaaa83ca"
- "6d", 16),
- 0x10ecca1aad7220b56a62008b35170bfd5e35885c4014a19f,
- 0x04eb61984c6c12ade3bc47f3c629ece7aa0a033b9948d686,
- 0x82bfa4e82c0dfe9274169b86694e76ce993fd83b5c60f325,
- 0xa97685676c59a65dbde002fe9d613431fb183e8006d05633,
- False),
-
- (generator_192,
- int("0x5a478f4084ddd1a7fea038aa9732a822106385797d02311aeef4d0264f824f"
- "698df7a48cfb6b578cf3da416bc0799425bb491be5b5ecc37995b85b03420a98"
- "f2c4dc5c31a69a379e9e322fbe706bbcaf0f77175e05cbb4fa162e0da82010a2"
- "78461e3e974d137bc746d1880d6eb02aa95216014b37480d84b87f717bb13f76"
- "e1", 16),
- 0x6636653cb5b894ca65c448277b29da3ad101c4c2300f7c04,
- 0xfdf1cbb3fc3fd6a4f890b59e554544175fa77dbdbeb656c1,
- 0xeac2ddecddfb79931a9c3d49c08de0645c783a24cb365e1c,
- 0x3549fee3cfa7e5f93bc47d92d8ba100e881a2a93c22f8d50,
- False),
-
- (generator_192,
- int("0xc598774259a058fa65212ac57eaa4f52240e629ef4c310722088292d1d4af6"
- "c39b49ce06ba77e4247b20637174d0bd67c9723feb57b5ead232b47ea452d5d7"
- "a089f17c00b8b6767e434a5e16c231ba0efa718a340bf41d67ea2d295812ff1b"
- "9277daacb8bc27b50ea5e6443bcf95ef4e9f5468fe78485236313d53d1c68f6b"
- "a2", 16),
- 0xa82bd718d01d354001148cd5f69b9ebf38ff6f21898f8aaa,
- 0xe67ceede07fc2ebfafd62462a51e4b6c6b3d5b537b7caf3e,
- 0x4d292486c620c3de20856e57d3bb72fcde4a73ad26376955,
- 0xa85289591a6081d5728825520e62ff1c64f94235c04c7f95,
- False),
-
- (generator_192,
- int("0xca98ed9db081a07b7557f24ced6c7b9891269a95d2026747add9e9eb80638a"
- "961cf9c71a1b9f2c29744180bd4c3d3db60f2243c5c0b7cc8a8d40a3f9a7fc91"
- "0250f2187136ee6413ffc67f1a25e1c4c204fa9635312252ac0e0481d89b6d53"
- "808f0c496ba87631803f6c572c1f61fa049737fdacce4adff757afed4f05beb6"
- "58", 16),
- 0x7d3b016b57758b160c4fca73d48df07ae3b6b30225126c2f,
- 0x4af3790d9775742bde46f8da876711be1b65244b2b39e7ec,
- 0x95f778f5f656511a5ab49a5d69ddd0929563c29cbc3a9e62,
- 0x75c87fc358c251b4c83d2dd979faad496b539f9f2ee7a289,
- False),
-
- (generator_192,
- int("0x31dd9a54c8338bea06b87eca813d555ad1850fac9742ef0bbe40dad400e102"
- "88acc9c11ea7dac79eb16378ebea9490e09536099f1b993e2653cd50240014c9"
- "0a9c987f64545abc6a536b9bd2435eb5e911fdfde2f13be96ea36ad38df4ae9e"
- "a387b29cced599af777338af2794820c9cce43b51d2112380a35802ab7e396c9"
- "7a", 16),
- 0x9362f28c4ef96453d8a2f849f21e881cd7566887da8beb4a,
- 0xe64d26d8d74c48a024ae85d982ee74cd16046f4ee5333905,
- 0xf3923476a296c88287e8de914b0b324ad5a963319a4fe73b,
- 0xf0baeed7624ed00d15244d8ba2aede085517dbdec8ac65f5,
- True),
-
- (generator_192,
- int("0xb2b94e4432267c92f9fdb9dc6040c95ffa477652761290d3c7de312283f645"
- "0d89cc4aabe748554dfb6056b2d8e99c7aeaad9cdddebdee9dbc099839562d90"
- "64e68e7bb5f3a6bba0749ca9a538181fc785553a4000785d73cc207922f63e8c"
- "e1112768cb1de7b673aed83a1e4a74592f1268d8e2a4e9e63d414b5d442bd045"
- "6d", 16),
- 0xcc6fc032a846aaac25533eb033522824f94e670fa997ecef,
- 0xe25463ef77a029eccda8b294fd63dd694e38d223d30862f1,
- 0x066b1d07f3a40e679b620eda7f550842a35c18b80c5ebe06,
- 0xa0b0fb201e8f2df65e2c4508ef303bdc90d934016f16b2dc,
- False),
-
- (generator_192,
- int("0x4366fcadf10d30d086911de30143da6f579527036937007b337f7282460eae"
- "5678b15cccda853193ea5fc4bc0a6b9d7a31128f27e1214988592827520b214e"
- "ed5052f7775b750b0c6b15f145453ba3fee24a085d65287e10509eb5d5f602c4"
- "40341376b95c24e5c4727d4b859bfe1483d20538acdd92c7997fa9c614f0f839"
- "d7", 16),
- 0x955c908fe900a996f7e2089bee2f6376830f76a19135e753,
- 0xba0c42a91d3847de4a592a46dc3fdaf45a7cc709b90de520,
- 0x1f58ad77fc04c782815a1405b0925e72095d906cbf52a668,
- 0xf2e93758b3af75edf784f05a6761c9b9a6043c66b845b599,
- False),
-
- (generator_192,
- int("0x543f8af57d750e33aa8565e0cae92bfa7a1ff78833093421c2942cadf99866"
- "70a5ff3244c02a8225e790fbf30ea84c74720abf99cfd10d02d34377c3d3b412"
- "69bea763384f372bb786b5846f58932defa68023136cd571863b304886e95e52"
- "e7877f445b9364b3f06f3c28da12707673fecb4b8071de06b6e0a3c87da160ce"
- "f3", 16),
- 0x31f7fa05576d78a949b24812d4383107a9a45bb5fccdd835,
- 0x8dc0eb65994a90f02b5e19bd18b32d61150746c09107e76b,
- 0xbe26d59e4e883dde7c286614a767b31e49ad88789d3a78ff,
- 0x8762ca831c1ce42df77893c9b03119428e7a9b819b619068,
- False),
-
- (generator_192,
- int("0xd2e8454143ce281e609a9d748014dcebb9d0bc53adb02443a6aac2ffe6cb009f"
- "387c346ecb051791404f79e902ee333ad65e5c8cb38dc0d1d39a8dc90add502357"
- "2720e5b94b190d43dd0d7873397504c0c7aef2727e628eb6a74411f2e400c65670"
- "716cb4a815dc91cbbfeb7cfe8c929e93184c938af2c078584da045e8f8d1", 16),
- 0x66aa8edbbdb5cf8e28ceb51b5bda891cae2df84819fe25c0,
- 0x0c6bc2f69030a7ce58d4a00e3b3349844784a13b8936f8da,
- 0xa4661e69b1734f4a71b788410a464b71e7ffe42334484f23,
- 0x738421cf5e049159d69c57a915143e226cac8355e149afe9,
- False),
-
- (generator_192,
- int("0x6660717144040f3e2f95a4e25b08a7079c702a8b29babad5a19a87654bc5c5af"
- "a261512a11b998a4fb36b5d8fe8bd942792ff0324b108120de86d63f65855e5461"
- "184fc96a0a8ffd2ce6d5dfb0230cbbdd98f8543e361b3205f5da3d500fdc8bac6d"
- "b377d75ebef3cb8f4d1ff738071ad0938917889250b41dd1d98896ca06fb", 16),
- 0xbcfacf45139b6f5f690a4c35a5fffa498794136a2353fc77,
- 0x6f4a6c906316a6afc6d98fe1f0399d056f128fe0270b0f22,
- 0x9db679a3dafe48f7ccad122933acfe9da0970b71c94c21c1,
- 0x984c2db99827576c0a41a5da41e07d8cc768bc82f18c9da9,
- False)
- ]
-
-
[email protected]("gen,msg,qx,qy,r,s,expected", CURVE_192_KATS)
-def test_signature_validity(gen, msg, qx, qy, r, s, expected):
- """
- `msg` = message, `qx` and `qy` represent the base point on
- elliptic curve of `gen`, `r` and `s` are the signature, and
- `expected` is True iff the signature is expected to be valid."""
- pubk = Public_key(gen,
- ellipticcurve.Point(gen.curve(), qx, qy))
- assert expected == pubk.verifies(digest_integer(msg), Signature(r, s))
-
-
[email protected]("gen,msg,qx,qy,r,s,expected",
- [x for x in CURVE_192_KATS if x[6]])
-def test_pk_recovery(gen, msg, r, s, qx, qy, expected):
- del expected
- sign = Signature(r, s)
- pks = sign.recover_public_keys(digest_integer(msg), gen)
-
- assert pks
-
- # Test if the signature is valid for all found public keys
- for pk in pks:
- q = pk.point
- test_signature_validity(gen, msg, q.x(), q.y(), r, s, True)
-
- # Test if the original public key is in the set of found keys
- original_q = ellipticcurve.Point(gen.curve(), qx, qy)
- points = [pk.point for pk in pks]
- assert original_q in points
-
-
-def st_random_gen_key_msg_nonce(draw):
- """Hypothesis strategy for test_sig_verify()."""
- name_gen = {
- "generator_192": generator_192,
- "generator_224": generator_224,
- "generator_256": generator_256,
- "generator_secp256k1": generator_secp256k1,
- "generator_384": generator_384,
- "generator_521": generator_521}
- name = draw(st.sampled_from(sorted(name_gen.keys())))
- note("Generator used: {0}".format(name))
- generator = name_gen[name]
- order = int(generator.order())
-
- key = draw(st.integers(min_value=1, max_value=order))
- msg = draw(st.integers(min_value=1, max_value=order))
- nonce = draw(st.integers(min_value=1, max_value=order+1) |
- st.integers(min_value=order>>1, max_value=order))
- return generator, key, msg, nonce
-
-
-SIG_VER_SETTINGS = dict(HYP_SETTINGS)
-SIG_VER_SETTINGS["max_examples"] = 10
-@settings(**SIG_VER_SETTINGS)
-@example((generator_224, 4, 1, 1))
-@given(st_random_gen_key_msg_nonce())
-def test_sig_verify(args):
- """
- Check if signing and verification works for arbitrary messages and
- that signatures for other messages are rejected.
- """
- generator, sec_mult, msg, nonce = args
-
- pubkey = Public_key(generator, generator * sec_mult)
- privkey = Private_key(pubkey, sec_mult)
-
- signature = privkey.sign(msg, nonce)
-
- assert pubkey.verifies(msg, signature)
-
- assert not pubkey.verifies(msg - 1, signature)
diff --git a/frozen_deps/Crypto/Cipher/AES.py b/frozen_deps/Crypto/Cipher/AES.py
new file mode 100644
index 0000000..14f68d8
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/AES.py
@@ -0,0 +1,115 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/AES.py : AES
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""AES symmetric cipher
+
+AES `(Advanced Encryption Standard)`__ is a symmetric block cipher standardized
+by NIST_ . It has a fixed data block size of 16 bytes.
+Its keys can be 128, 192, or 256 bits long.
+
+AES is very fast and secure, and it is the de facto standard for symmetric
+encryption.
+
+As an example, encryption can be done as follows:
+
+ >>> from Crypto.Cipher import AES
+ >>> from Crypto import Random
+ >>>
+ >>> key = b'Sixteen byte key'
+ >>> iv = Random.new().read(AES.block_size)
+ >>> cipher = AES.new(key, AES.MODE_CFB, iv)
+ >>> msg = iv + cipher.encrypt(b'Attack at dawn')
+
+.. __: http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
+.. _NIST: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
+
+:undocumented: __revision__, __package__
+"""
+
+__revision__ = "$Id$"
+
+from Crypto.Cipher import blockalgo
+from Crypto.Cipher import _AES
+
+class AESCipher (blockalgo.BlockAlgo):
+ """AES cipher object"""
+
+ def __init__(self, key, *args, **kwargs):
+ """Initialize an AES cipher object
+
+ See also `new()` at the module level."""
+ blockalgo.BlockAlgo.__init__(self, _AES, key, *args, **kwargs)
+
+def new(key, *args, **kwargs):
+ """Create a new AES cipher
+
+ :Parameters:
+ key : byte string
+ The secret key to use in the symmetric cipher.
+ It must be 16 (*AES-128*), 24 (*AES-192*), or 32 (*AES-256*) bytes long.
+ :Keywords:
+ mode : a *MODE_** constant
+ The chaining mode to use for encryption or decryption.
+ Default is `MODE_ECB`.
+ IV : byte string
+ The initialization vector to use for encryption or decryption.
+
+ It is ignored for `MODE_ECB` and `MODE_CTR`.
+
+ For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption
+ and `block_size` +2 bytes for decryption (in the latter case, it is
+ actually the *encrypted* IV which was prefixed to the ciphertext).
+ It is mandatory.
+
+ For all other modes, it must be `block_size` bytes longs. It is optional and
+ when not present it will be given a default value of all zeroes.
+ counter : callable
+ (*Only* `MODE_CTR`). A stateful function that returns the next
+ *counter block*, which is a byte string of `block_size` bytes.
+ For better performance, use `Crypto.Util.Counter`.
+ segment_size : integer
+ (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext
+ are segmented in.
+ It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8.
+
+ :Return: an `AESCipher` object
+ """
+ return AESCipher(key, *args, **kwargs)
+
+#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`.
+MODE_ECB = 1
+#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`.
+MODE_CBC = 2
+#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`.
+MODE_CFB = 3
+#: This mode should not be used.
+MODE_PGP = 4
+#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`.
+MODE_OFB = 5
+#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`.
+MODE_CTR = 6
+#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`.
+MODE_OPENPGP = 7
+#: Size of a data block (in bytes)
+block_size = 16
+#: Size of a key (in bytes)
+key_size = ( 16, 24, 32 )
+
diff --git a/frozen_deps/Crypto/Cipher/ARC2.py b/frozen_deps/Crypto/Cipher/ARC2.py
new file mode 100644
index 0000000..b5234e6
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/ARC2.py
@@ -0,0 +1,130 @@
+# -*- 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
new file mode 100644
index 0000000..d83f75b
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/ARC4.py
@@ -0,0 +1,120 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/ARC4.py : ARC4
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""ARC4 symmetric cipher
+
+ARC4_ (Alleged RC4) is an implementation of RC4 (Rivest's Cipher version 4),
+a symmetric stream cipher designed by Ron Rivest in 1987.
+
+The cipher started as a proprietary design, that was reverse engineered and
+anonymously posted on Usenet in 1994. The company that owns RC4 (RSA Data
+Inc.) never confirmed the correctness of the leaked algorithm.
+
+Unlike RC2, the company has never published the full specification of RC4,
+of whom it still holds the trademark.
+
+ARC4 keys can vary in length from 40 to 2048 bits.
+
+One problem of ARC4 is that it does not take a nonce or an IV. If it is required
+to encrypt multiple messages with the same long-term key, a distinct
+independent nonce must be created for each message, and a short-term key must
+be derived from the combination of the long-term key and the nonce.
+Due to the weak key scheduling algorithm of RC2, the combination must be carried
+out with a complex function (e.g. a cryptographic hash) and not by simply
+concatenating key and nonce.
+
+New designs should not use ARC4. A good alternative is AES
+(`Crypto.Cipher.AES`) in any of the modes that turn it into a stream cipher (OFB, CFB, or CTR).
+
+As an example, encryption can be done as follows:
+
+ >>> from Crypto.Cipher import ARC4
+ >>> from Crypto.Hash import SHA
+ >>> from Crypto import Random
+ >>>
+ >>> key = b'Very long and confidential key'
+ >>> nonce = Random.new().read(16)
+ >>> tempkey = SHA.new(key+nonce).digest()
+ >>> cipher = ARC4.new(tempkey)
+ >>> msg = nonce + cipher.encrypt(b'Open the pod bay doors, HAL')
+
+.. _ARC4: http://en.wikipedia.org/wiki/RC4
+
+:undocumented: __revision__, __package__
+"""
+
+__revision__ = "$Id$"
+
+from Crypto.Cipher import _ARC4
+
+class ARC4Cipher:
+ """ARC4 cipher object"""
+
+
+ def __init__(self, key, *args, **kwargs):
+ """Initialize an ARC4 cipher object
+
+ See also `new()` at the module level."""
+
+ self._cipher = _ARC4.new(key, *args, **kwargs)
+ self.block_size = self._cipher.block_size
+ self.key_size = self._cipher.key_size
+
+ def encrypt(self, plaintext):
+ """Encrypt a piece of data.
+
+ :Parameters:
+ plaintext : byte string
+ The piece of data to encrypt. It can be of any size.
+ :Return: the encrypted data (byte string, as long as the
+ plaintext).
+ """
+ return self._cipher.encrypt(plaintext)
+
+ def decrypt(self, ciphertext):
+ """Decrypt a piece of data.
+
+ :Parameters:
+ ciphertext : byte string
+ The piece of data to decrypt. It can be of any size.
+ :Return: the decrypted data (byte string, as long as the
+ ciphertext).
+ """
+ return self._cipher.decrypt(ciphertext)
+
+def new(key, *args, **kwargs):
+ """Create a new ARC4 cipher
+
+ :Parameters:
+ key : byte string
+ The secret key to use in the symmetric cipher.
+ It can have any length, with a minimum of 40 bytes.
+ Its cryptograpic strength is always capped to 2048 bits (256 bytes).
+
+ :Return: an `ARC4Cipher` object
+ """
+ return ARC4Cipher(key, *args, **kwargs)
+
+#: Size of a data block (in bytes)
+block_size = 1
+#: Size of a key (in bytes)
+key_size = range(1,256+1)
+
diff --git a/frozen_deps/Crypto/Cipher/Blowfish.py b/frozen_deps/Crypto/Cipher/Blowfish.py
new file mode 100644
index 0000000..8c81d96
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/Blowfish.py
@@ -0,0 +1,121 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/Blowfish.py : Blowfish
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""Blowfish symmetric cipher
+
+Blowfish_ is a symmetric block cipher designed by Bruce Schneier.
+
+It has a fixed data block size of 8 bytes and its keys can vary in length
+from 32 to 448 bits (4 to 56 bytes).
+
+Blowfish is deemed secure and it is fast. However, its keys should be chosen
+to be big enough to withstand a brute force attack (e.g. at least 16 bytes).
+
+As an example, encryption can be done as follows:
+
+ >>> from Crypto.Cipher import Blowfish
+ >>> from Crypto import Random
+ >>> from struct import pack
+ >>>
+ >>> bs = Blowfish.block_size
+ >>> key = b'An arbitrarily long key'
+ >>> iv = Random.new().read(bs)
+ >>> cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv)
+ >>> plaintext = b'docendo discimus '
+ >>> plen = bs - divmod(len(plaintext),bs)[1]
+ >>> padding = [plen]*plen
+ >>> padding = pack('b'*plen, *padding)
+ >>> msg = iv + cipher.encrypt(plaintext + padding)
+
+.. _Blowfish: http://www.schneier.com/blowfish.html
+
+:undocumented: __revision__, __package__
+"""
+
+__revision__ = "$Id$"
+
+from Crypto.Cipher import blockalgo
+from Crypto.Cipher import _Blowfish
+
+class BlowfishCipher (blockalgo.BlockAlgo):
+ """Blowfish cipher object"""
+
+ def __init__(self, key, *args, **kwargs):
+ """Initialize a Blowfish cipher object
+
+ See also `new()` at the module level."""
+ blockalgo.BlockAlgo.__init__(self, _Blowfish, key, *args, **kwargs)
+
+def new(key, *args, **kwargs):
+ """Create a new Blowfish cipher
+
+ :Parameters:
+ key : byte string
+ The secret key to use in the symmetric cipher.
+ Its length can vary from 4 to 56 bytes.
+ :Keywords:
+ mode : a *MODE_** constant
+ The chaining mode to use for encryption or decryption.
+ Default is `MODE_ECB`.
+ IV : byte string
+ The initialization vector to use for encryption or decryption.
+
+ It is ignored for `MODE_ECB` and `MODE_CTR`.
+
+ For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption
+ and `block_size` +2 bytes for decryption (in the latter case, it is
+ actually the *encrypted* IV which was prefixed to the ciphertext).
+ It is mandatory.
+
+ For all other modes, it must be `block_size` bytes longs. It is optional and
+ when not present it will be given a default value of all zeroes.
+ counter : callable
+ (*Only* `MODE_CTR`). A stateful function that returns the next
+ *counter block*, which is a byte string of `block_size` bytes.
+ For better performance, use `Crypto.Util.Counter`.
+ segment_size : integer
+ (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext
+ are segmented in.
+ It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8.
+
+ :Return: a `BlowfishCipher` object
+ """
+ return BlowfishCipher(key, *args, **kwargs)
+
+#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`.
+MODE_ECB = 1
+#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`.
+MODE_CBC = 2
+#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`.
+MODE_CFB = 3
+#: This mode should not be used.
+MODE_PGP = 4
+#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`.
+MODE_OFB = 5
+#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`.
+MODE_CTR = 6
+#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`.
+MODE_OPENPGP = 7
+#: Size of a data block (in bytes)
+block_size = 8
+#: Size of a key (in bytes)
+key_size = range(4,56+1)
+
diff --git a/frozen_deps/Crypto/Cipher/CAST.py b/frozen_deps/Crypto/Cipher/CAST.py
new file mode 100644
index 0000000..89543b2
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/CAST.py
@@ -0,0 +1,123 @@
+# -*- 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
new file mode 100644
index 0000000..2fae42f
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/DES.py
@@ -0,0 +1,118 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/DES.py : DES
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""DES symmetric cipher
+
+DES `(Data Encryption Standard)`__ is a symmetric block cipher standardized
+by NIST_ . It has a fixed data block size of 8 bytes.
+Its keys are 64 bits long, even though 8 bits were used for integrity (now they
+are ignored) and do not contribute to securty.
+
+DES is cryptographically secure, but its key length is too short by nowadays
+standards and it could be brute forced with some effort.
+
+DES should not be used for new designs. Use `AES`.
+
+As an example, encryption can be done as follows:
+
+ >>> from Crypto.Cipher import DES3
+ >>> from Crypto import Random
+ >>>
+ >>> key = b'Sixteen byte key'
+ >>> iv = Random.new().read(DES3.block_size)
+ >>> cipher = DES3.new(key, DES3.MODE_OFB, iv)
+ >>> plaintext = b'sona si latine loqueris '
+ >>> msg = iv + cipher.encrypt(plaintext)
+
+.. __: http://en.wikipedia.org/wiki/Data_Encryption_Standard
+.. _NIST: http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
+
+:undocumented: __revision__, __package__
+"""
+
+__revision__ = "$Id$"
+
+from Crypto.Cipher import blockalgo
+from Crypto.Cipher import _DES
+
+class DESCipher(blockalgo.BlockAlgo):
+ """DES cipher object"""
+
+ def __init__(self, key, *args, **kwargs):
+ """Initialize a DES cipher object
+
+ See also `new()` at the module level."""
+ blockalgo.BlockAlgo.__init__(self, _DES, key, *args, **kwargs)
+
+def new(key, *args, **kwargs):
+ """Create a new DES cipher
+
+ :Parameters:
+ key : byte string
+ The secret key to use in the symmetric cipher.
+ It must be 8 byte long. The parity bits will be ignored.
+ :Keywords:
+ mode : a *MODE_** constant
+ The chaining mode to use for encryption or decryption.
+ Default is `MODE_ECB`.
+ IV : byte string
+ The initialization vector to use for encryption or decryption.
+
+ It is ignored for `MODE_ECB` and `MODE_CTR`.
+
+ For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption
+ and `block_size` +2 bytes for decryption (in the latter case, it is
+ actually the *encrypted* IV which was prefixed to the ciphertext).
+ It is mandatory.
+
+ For all other modes, it must be `block_size` bytes longs. It is optional and
+ when not present it will be given a default value of all zeroes.
+ counter : callable
+ (*Only* `MODE_CTR`). A stateful function that returns the next
+ *counter block*, which is a byte string of `block_size` bytes.
+ For better performance, use `Crypto.Util.Counter`.
+ segment_size : integer
+ (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext
+ are segmented in.
+ It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8.
+
+ :Return: an `DESCipher` object
+ """
+ return DESCipher(key, *args, **kwargs)
+
+#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`.
+MODE_ECB = 1
+#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`.
+MODE_CBC = 2
+#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`.
+MODE_CFB = 3
+#: This mode should not be used.
+MODE_PGP = 4
+#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`.
+MODE_OFB = 5
+#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`.
+MODE_CTR = 6
+#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`.
+MODE_OPENPGP = 7
+#: Size of a data block (in bytes)
+block_size = 8
+#: Size of a key (in bytes)
+key_size = 8
diff --git a/frozen_deps/Crypto/Cipher/DES3.py b/frozen_deps/Crypto/Cipher/DES3.py
new file mode 100644
index 0000000..7fedac8
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/DES3.py
@@ -0,0 +1,133 @@
+# -*- 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
new file mode 100644
index 0000000..2738ce3
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/PKCS1_OAEP.py
@@ -0,0 +1,255 @@
+# -*- 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<hLen+2:
+ 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 3a
+ lHash = self._hashObj.new(self._label).digest()
+ # Step 3b
+ y = em[0]
+ # y must be 0, but we MUST NOT check it here in order not to
+ # allow attacks like Manger's (http://dl.acm.org/citation.cfm?id=704143)
+ maskedSeed = em[1:hLen+1]
+ maskedDB = em[hLen+1:]
+ # Step 3c
+ seedMask = self._mgf(maskedDB, hLen)
+ # Step 3d
+ seed = strxor(maskedSeed, seedMask)
+ # Step 3e
+ dbMask = self._mgf(seed, k-hLen-1)
+ # Step 3f
+ db = strxor(maskedDB, dbMask)
+ # Step 3g
+ valid = 1
+ one = db[hLen:].find(bchr(0x01))
+ lHash1 = db[:hLen]
+ if lHash1!=lHash:
+ valid = 0
+ if one<0:
+ valid = 0
+ if bord(y)!=0:
+ valid = 0
+ if not valid:
+ raise ValueError("Incorrect decryption.")
+ # Step 4
+ return db[hLen+one+1:]
+
+def new(key, hashAlgo=None, mgfunc=None, label=b('')):
+ """Return a cipher object `PKCS1OAEP_Cipher` that can be used to perform PKCS#1 OAEP 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.
+ 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.
+ """
+ return PKCS1OAEP_Cipher(key, hashAlgo, mgfunc, label)
+
diff --git a/frozen_deps/Crypto/Cipher/PKCS1_v1_5.py b/frozen_deps/Crypto/Cipher/PKCS1_v1_5.py
new file mode 100644
index 0000000..3602cb0
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/PKCS1_v1_5.py
@@ -0,0 +1,226 @@
+# -*- 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.
+# ===================================================================
+
+"""RSA encryption protocol according to PKCS#1 v1.5
+
+See RFC3447__ or the `original RSA Labs specification`__ .
+
+This scheme is more properly called ``RSAES-PKCS1-v1_5``.
+
+**If you are designing a new protocol, consider using the more robust PKCS#1 OAEP.**
+
+As an example, a sender may encrypt a message in this way:
+
+ >>> 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
new file mode 100644
index 0000000..46b8464
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/XOR.py
@@ -0,0 +1,86 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/XOR.py : XOR
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""XOR toy cipher
+
+XOR is one the simplest stream ciphers. Encryption and decryption are
+performed by XOR-ing data with a keystream made by contatenating
+the key.
+
+Do not use it for real applications!
+
+:undocumented: __revision__, __package__
+"""
+
+__revision__ = "$Id$"
+
+from Crypto.Cipher import _XOR
+
+class XORCipher:
+ """XOR cipher object"""
+
+ def __init__(self, key, *args, **kwargs):
+ """Initialize a XOR cipher object
+
+ See also `new()` at the module level."""
+ self._cipher = _XOR.new(key, *args, **kwargs)
+ self.block_size = self._cipher.block_size
+ self.key_size = self._cipher.key_size
+
+ def encrypt(self, plaintext):
+ """Encrypt a piece of data.
+
+ :Parameters:
+ plaintext : byte string
+ The piece of data to encrypt. It can be of any size.
+ :Return: the encrypted data (byte string, as long as the
+ plaintext).
+ """
+ return self._cipher.encrypt(plaintext)
+
+ def decrypt(self, ciphertext):
+ """Decrypt a piece of data.
+
+ :Parameters:
+ ciphertext : byte string
+ The piece of data to decrypt. It can be of any size.
+ :Return: the decrypted data (byte string, as long as the
+ ciphertext).
+ """
+ return self._cipher.decrypt(ciphertext)
+
+def new(key, *args, **kwargs):
+ """Create a new XOR cipher
+
+ :Parameters:
+ key : byte string
+ The secret key to use in the symmetric cipher.
+ Its length may vary from 1 to 32 bytes.
+
+ :Return: an `XORCipher` object
+ """
+ return XORCipher(key, *args, **kwargs)
+
+#: Size of a data block (in bytes)
+block_size = 1
+#: Size of a key (in bytes)
+key_size = 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
new file mode 100755
index 0000000..e9ffeb9
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/_AES.cpython-38-x86_64-linux-gnu.so
Binary files 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
new file mode 100755
index 0000000..b325488
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/_ARC2.cpython-38-x86_64-linux-gnu.so
Binary files 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
new file mode 100755
index 0000000..982a28d
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so
Binary files 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
new file mode 100755
index 0000000..2648636
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/_Blowfish.cpython-38-x86_64-linux-gnu.so
Binary files 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
new file mode 100755
index 0000000..439731a
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/_CAST.cpython-38-x86_64-linux-gnu.so
Binary files 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
new file mode 100755
index 0000000..e025c0d
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/_DES.cpython-38-x86_64-linux-gnu.so
Binary files 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
new file mode 100755
index 0000000..faef3f9
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/_DES3.cpython-38-x86_64-linux-gnu.so
Binary files 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
new file mode 100755
index 0000000..43f0560
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/_XOR.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Crypto/Cipher/__init__.py b/frozen_deps/Crypto/Cipher/__init__.py
new file mode 100644
index 0000000..7afed2d
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/__init__.py
@@ -0,0 +1,83 @@
+# -*- 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
new file mode 100644
index 0000000..dd183dc
--- /dev/null
+++ b/frozen_deps/Crypto/Cipher/blockalgo.py
@@ -0,0 +1,296 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/blockalgo.py
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""Module with definitions common to all block ciphers."""
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+ from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+#: *Electronic Code Book (ECB)*.
+#: This is the simplest encryption mode. Each of the plaintext blocks
+#: is directly encrypted into a ciphertext block, independently of
+#: any other block. This mode exposes frequency of symbols
+#: in your plaintext. Other modes (e.g. *CBC*) should be used instead.
+#:
+#: See `NIST SP800-38A`_ , Section 6.1 .
+#:
+#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+MODE_ECB = 1
+
+#: *Cipher-Block Chaining (CBC)*. Each of the ciphertext blocks depends
+#: on the current and all previous plaintext blocks. An Initialization Vector
+#: (*IV*) is required.
+#:
+#: The *IV* is a data block to be transmitted to the receiver.
+#: The *IV* can be made public, but it must be authenticated by the receiver and
+#: it should be picked randomly.
+#:
+#: See `NIST SP800-38A`_ , Section 6.2 .
+#:
+#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+MODE_CBC = 2
+
+#: *Cipher FeedBack (CFB)*. This mode is similar to CBC, but it transforms
+#: the underlying block cipher into a stream cipher. Plaintext and ciphertext
+#: are processed in *segments* of **s** bits. The mode is therefore sometimes
+#: labelled **s**-bit CFB. An Initialization Vector (*IV*) is required.
+#:
+#: When encrypting, each ciphertext segment contributes to the encryption of
+#: the next plaintext segment.
+#:
+#: This *IV* is a data block to be transmitted to the receiver.
+#: The *IV* can be made public, but it should be picked randomly.
+#: Reusing the same *IV* for encryptions done with the same key lead to
+#: catastrophic cryptographic failures.
+#:
+#: See `NIST SP800-38A`_ , Section 6.3 .
+#:
+#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+MODE_CFB = 3
+
+#: This mode should not be used.
+MODE_PGP = 4
+
+#: *Output FeedBack (OFB)*. This mode is very similar to CBC, but it
+#: transforms the underlying block cipher into a stream cipher.
+#: The keystream is the iterated block encryption of an Initialization Vector (*IV*).
+#:
+#: The *IV* is a data block to be transmitted to the receiver.
+#: The *IV* can be made public, but it should be picked randomly.
+#:
+#: Reusing the same *IV* for encryptions done with the same key lead to
+#: catastrophic cryptograhic failures.
+#:
+#: See `NIST SP800-38A`_ , Section 6.4 .
+#:
+#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+MODE_OFB = 5
+
+#: *CounTeR (CTR)*. This mode is very similar to ECB, in that
+#: encryption of one block is done independently of all other blocks.
+#: Unlike ECB, the block *position* contributes to the encryption and no
+#: information leaks about symbol frequency.
+#:
+#: Each message block is associated to a *counter* which must be unique
+#: across all messages that get encrypted with the same key (not just within
+#: the same message). The counter is as big as the block size.
+#:
+#: Counters can be generated in several ways. The most straightword one is
+#: to choose an *initial counter block* (which can be made public, similarly
+#: to the *IV* for the other modes) and increment its lowest **m** bits by
+#: one (modulo *2^m*) for each block. In most cases, **m** is chosen to be half
+#: the block size.
+#:
+#: Reusing the same *initial counter block* for encryptions done with the same
+#: key lead to catastrophic cryptograhic failures.
+#:
+#: See `NIST SP800-38A`_ , Section 6.5 (for the mode) and Appendix B (for how
+#: to manage the *initial counter block*).
+#:
+#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+MODE_CTR = 6
+
+#: OpenPGP. This mode is a variant of CFB, and it is only used in PGP and OpenPGP_ applications.
+#: An Initialization Vector (*IV*) is required.
+#:
+#: Unlike CFB, the IV is not transmitted to the receiver. Instead, the *encrypted* IV is.
+#: The IV is a random data block. Two of its bytes are duplicated to act as a checksum
+#: for the correctness of the key. The encrypted IV is therefore 2 bytes longer than
+#: the clean IV.
+#:
+#: .. _OpenPGP: http://tools.ietf.org/html/rfc4880
+MODE_OPENPGP = 7
+
+def _getParameter(name, index, args, kwargs, default=None):
+ """Find a parameter in tuple and dictionary arguments a function receives"""
+ param = kwargs.get(name)
+ if len(args)>index:
+ if param:
+ raise ValueError("Parameter '%s' is specified twice" % name)
+ param = args[index]
+ return param or default
+
+class BlockAlgo:
+ """Class modelling an abstract block cipher."""
+
+ def __init__(self, factory, key, *args, **kwargs):
+ self.mode = _getParameter('mode', 0, args, kwargs, default=MODE_ECB)
+ self.block_size = factory.block_size
+
+ if self.mode != MODE_OPENPGP:
+ self._cipher = factory.new(key, *args, **kwargs)
+ self.IV = self._cipher.IV
+ else:
+ # OPENPGP mode. For details, see 13.9 in RCC4880.
+ #
+ # A few members are specifically created for this mode:
+ # - _encrypted_iv, set in this constructor
+ # - _done_first_block, set to True after the first encryption
+ # - _done_last_block, set to True after a partial block is processed
+
+ self._done_first_block = False
+ self._done_last_block = False
+ self.IV = _getParameter('iv', 1, args, kwargs)
+ if not self.IV:
+ raise ValueError("MODE_OPENPGP requires an IV")
+
+ # Instantiate a temporary cipher to process the IV
+ IV_cipher = factory.new(key, MODE_CFB,
+ b('\x00')*self.block_size, # IV for CFB
+ segment_size=self.block_size*8)
+
+ # The cipher will be used for...
+ if len(self.IV) == self.block_size:
+ # ... encryption
+ self._encrypted_IV = IV_cipher.encrypt(
+ self.IV + self.IV[-2:] + # Plaintext
+ b('\x00')*(self.block_size-2) # Padding
+ )[:self.block_size+2]
+ elif len(self.IV) == self.block_size+2:
+ # ... decryption
+ self._encrypted_IV = self.IV
+ self.IV = IV_cipher.decrypt(self.IV + # Ciphertext
+ b('\x00')*(self.block_size-2) # Padding
+ )[:self.block_size+2]
+ if self.IV[-2:] != self.IV[-4:-2]:
+ raise ValueError("Failed integrity check for OPENPGP IV")
+ self.IV = self.IV[:-2]
+ else:
+ raise ValueError("Length of IV must be %d or %d bytes for MODE_OPENPGP"
+ % (self.block_size, self.block_size+2))
+
+ # Instantiate the cipher for the real PGP data
+ self._cipher = factory.new(key, MODE_CFB,
+ self._encrypted_IV[-self.block_size:],
+ segment_size=self.block_size*8)
+
+ def encrypt(self, plaintext):
+ """Encrypt data with the key and the parameters set at initialization.
+
+ The cipher object is stateful; encryption of a long block
+ of data can be broken up in two or more calls to `encrypt()`.
+ That is, the statement:
+
+ >>> c.encrypt(a) + c.encrypt(b)
+
+ is always equivalent to:
+
+ >>> c.encrypt(a+b)
+
+ That also means that you cannot reuse an object for encrypting
+ or decrypting other data with the same key.
+
+ This function does not perform any padding.
+
+ - For `MODE_ECB`, `MODE_CBC`, and `MODE_OFB`, *plaintext* length
+ (in bytes) must be a multiple of *block_size*.
+
+ - For `MODE_CFB`, *plaintext* length (in bytes) must be a multiple
+ of *segment_size*/8.
+
+ - For `MODE_CTR`, *plaintext* can be of any length.
+
+ - For `MODE_OPENPGP`, *plaintext* must be a multiple of *block_size*,
+ unless it is the last chunk of the message.
+
+ :Parameters:
+ plaintext : byte string
+ The piece of data to encrypt.
+ :Return:
+ the encrypted data, as a byte string. It is as long as
+ *plaintext* with one exception: when encrypting the first message
+ chunk with `MODE_OPENPGP`, the encypted IV is prepended to the
+ returned ciphertext.
+ """
+
+ if self.mode == MODE_OPENPGP:
+ padding_length = (self.block_size - len(plaintext) % self.block_size) % self.block_size
+ if padding_length>0:
+ # CFB mode requires ciphertext to have length multiple of block size,
+ # but PGP mode allows the last block to be shorter
+ if self._done_last_block:
+ raise ValueError("Only the last chunk is allowed to have length not multiple of %d bytes",
+ self.block_size)
+ self._done_last_block = True
+ padded = plaintext + b('\x00')*padding_length
+ res = self._cipher.encrypt(padded)[:len(plaintext)]
+ else:
+ res = self._cipher.encrypt(plaintext)
+ if not self._done_first_block:
+ res = self._encrypted_IV + res
+ self._done_first_block = True
+ return res
+
+ return self._cipher.encrypt(plaintext)
+
+ def decrypt(self, ciphertext):
+ """Decrypt data with the key and the parameters set at initialization.
+
+ The cipher object is stateful; decryption of a long block
+ of data can be broken up in two or more calls to `decrypt()`.
+ That is, the statement:
+
+ >>> c.decrypt(a) + c.decrypt(b)
+
+ is always equivalent to:
+
+ >>> c.decrypt(a+b)
+
+ That also means that you cannot reuse an object for encrypting
+ or decrypting other data with the same key.
+
+ This function does not perform any padding.
+
+ - For `MODE_ECB`, `MODE_CBC`, and `MODE_OFB`, *ciphertext* length
+ (in bytes) must be a multiple of *block_size*.
+
+ - For `MODE_CFB`, *ciphertext* length (in bytes) must be a multiple
+ of *segment_size*/8.
+
+ - For `MODE_CTR`, *ciphertext* can be of any length.
+
+ - For `MODE_OPENPGP`, *plaintext* must be a multiple of *block_size*,
+ unless it is the last chunk of the message.
+
+ :Parameters:
+ ciphertext : byte string
+ The piece of data to decrypt.
+ :Return: the decrypted data (byte string, as long as *ciphertext*).
+ """
+ if self.mode == MODE_OPENPGP:
+ padding_length = (self.block_size - len(ciphertext) % self.block_size) % self.block_size
+ if padding_length>0:
+ # CFB mode requires ciphertext to have length multiple of block size,
+ # but PGP mode allows the last block to be shorter
+ if self._done_last_block:
+ raise ValueError("Only the last chunk is allowed to have length not multiple of %d bytes",
+ self.block_size)
+ self._done_last_block = True
+ padded = ciphertext + b('\x00')*padding_length
+ res = self._cipher.decrypt(padded)[:len(ciphertext)]
+ else:
+ res = self._cipher.decrypt(ciphertext)
+ return res
+
+ return self._cipher.decrypt(ciphertext)
+
diff --git a/frozen_deps/Crypto/Hash/HMAC.py b/frozen_deps/Crypto/Hash/HMAC.py
new file mode 100644
index 0000000..324f534
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/HMAC.py
@@ -0,0 +1,212 @@
+# HMAC.py - Implements the HMAC algorithm as described by RFC 2104.
+#
+# ===================================================================
+# Portions Copyright (c) 2001, 2002, 2003 Python Software Foundation;
+# All Rights Reserved
+#
+# This file contains code from the Python 2.2 hmac.py module (the
+# "Original Code"), with modifications made after it was incorporated
+# into PyCrypto (the "Modifications").
+#
+# To the best of our knowledge, the Python Software Foundation is the
+# copyright holder of the Original Code, and has licensed it under the
+# Python 2.2 license. See the file LEGAL/copy/LICENSE.python-2.2 for
+# details.
+#
+# The Modifications to this file are dedicated to the public domain.
+# To the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever. No rights are
+# reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+
+"""HMAC (Hash-based Message Authentication Code) algorithm
+
+HMAC is a MAC defined in RFC2104_ and FIPS-198_ and constructed using
+a cryptograpic hash algorithm.
+It is usually named *HMAC-X*, where *X* is the hash algorithm; for
+instance *HMAC-SHA1* or *HMAC-MD5*.
+
+The strength of an HMAC depends on:
+
+ - the strength of the hash algorithm
+ - the length and entropy of the secret key
+
+An example of possible usage is the following:
+
+ >>> from Crypto.Hash import HMAC
+ >>>
+ >>> secret = b'Swordfish'
+ >>> h = HMAC.new(secret)
+ >>> h.update(b'Hello')
+ >>> print h.hexdigest()
+
+.. _RFC2104: http://www.ietf.org/rfc/rfc2104.txt
+.. _FIPS-198: http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf
+"""
+
+# This is just a copy of the Python 2.2 HMAC module, modified to work when
+# used on versions of Python before 2.2.
+
+__revision__ = "$Id$"
+
+__all__ = ['new', 'digest_size', 'HMAC' ]
+
+from Crypto.Util.strxor import strxor_c
+from Crypto.Util.py3compat import *
+
+#: The size of the authentication tag produced by the MAC.
+#: It matches the digest size on the underlying
+#: hashing module used.
+digest_size = None
+
+class HMAC:
+ """Class that implements HMAC"""
+
+ #: The size of the authentication tag produced by the MAC.
+ #: It matches the digest size on the underlying
+ #: hashing module used.
+ digest_size = None
+
+ def __init__(self, key, msg = None, digestmod = None):
+ """Create a new HMAC object.
+
+ :Parameters:
+ key : byte string
+ secret key for the MAC object.
+ It must be long enough to match the expected security level of the
+ MAC. However, there is no benefit in using keys longer than the
+ `digest_size` of the underlying hash algorithm.
+ msg : byte string
+ The very first chunk of the message to authenticate.
+ It is equivalent to an early call to `update()`. Optional.
+ :Parameter digestmod:
+ The hash algorithm the HMAC is based on.
+ Default is `Crypto.Hash.MD5`.
+ :Type digestmod:
+ A hash module or object instantiated from `Crypto.Hash`
+ """
+ if digestmod is None:
+ 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
new file mode 100644
index 0000000..dac959e
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/MD2.py
@@ -0,0 +1,91 @@
+# -*- 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
new file mode 100644
index 0000000..e28a201
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/MD4.py
@@ -0,0 +1,91 @@
+# -*- 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
new file mode 100644
index 0000000..18e9e7b
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/MD5.py
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""MD5 cryptographic hash algorithm.
+
+MD5 is specified in RFC1321_ and produces the 128 bit digest of a message.
+
+ >>> from Crypto.Hash import MD5
+ >>>
+ >>> h = MD5.new()
+ >>> h.update(b'Hello')
+ >>> print h.hexdigest()
+
+MD5 stand for Message Digest version 5, and it was invented by Rivest in 1991.
+
+This algorithm is insecure. Do not use it for new designs.
+
+.. _RFC1321: http://tools.ietf.org/html/rfc1321
+"""
+
+_revision__ = "$Id$"
+
+__all__ = ['new', 'digest_size', 'MD5Hash' ]
+
+from Crypto.Util.py3compat import *
+from Crypto.Hash.hashalgo import HashAlgo
+
+try:
+ # The md5 module is deprecated in Python 2.6, so use hashlib when possible.
+ import hashlib
+ hashFactory = hashlib.md5
+
+except ImportError:
+ import md5
+ hashFactory = md5
+
+class MD5Hash(HashAlgo):
+ """Class that implements an MD5 hash
+
+ :undocumented: block_size
+ """
+
+ #: ASN.1 Object identifier (OID)::
+ #:
+ #: id-md5 OBJECT IDENTIFIER ::= {
+ #: iso(1) member-body(2) us(840) rsadsi(113549)
+ #: digestAlgorithm(2) 5
+ #: }
+ #:
+ #: This value uniquely identifies the MD5 algorithm.
+ oid = b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05')
+
+ digest_size = 16
+ block_size = 64
+
+ def __init__(self, data=None):
+ HashAlgo.__init__(self, hashFactory, data)
+
+ def new(self, data=None):
+ return MD5Hash(data)
+
+def new(data=None):
+ """Return a fresh instance of the hash object.
+
+ :Parameters:
+ data : byte string
+ The very first chunk of the message to hash.
+ It is equivalent to an early call to `MD5Hash.update()`.
+ Optional.
+
+ :Return: A `MD5Hash` object
+ """
+ return MD5Hash().new(data)
+
+#: The size of the resulting hash in bytes.
+digest_size = MD5Hash.digest_size
+
+#: The internal block size of the hash algorithm in bytes.
+block_size = MD5Hash.block_size
+
diff --git a/frozen_deps/Crypto/Hash/RIPEMD.py b/frozen_deps/Crypto/Hash/RIPEMD.py
new file mode 100644
index 0000000..33099cb
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/RIPEMD.py
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""RIPEMD-160 cryptographic hash algorithm.
+
+RIPEMD-160_ produces the 160 bit digest of a message.
+
+ >>> from Crypto.Hash import RIPEMD
+ >>>
+ >>> h = RIPEMD.new()
+ >>> h.update(b'Hello')
+ >>> print h.hexdigest()
+
+RIPEMD-160 stands for RACE Integrity Primitives Evaluation Message Digest
+with a 160 bit digest. It was invented by Dobbertin, Bosselaers, and Preneel.
+
+This algorithm is considered secure, although it has not been scrutinized as
+extensively as SHA-1. Moreover, it provides an informal security level of just
+80bits.
+
+.. _RIPEMD-160: http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
+"""
+
+_revision__ = "$Id$"
+
+__all__ = ['new', 'digest_size', 'RIPEMD160Hash' ]
+
+from Crypto.Util.py3compat import *
+from Crypto.Hash.hashalgo import HashAlgo
+
+import Crypto.Hash._RIPEMD160 as _RIPEMD160
+hashFactory = _RIPEMD160
+
+class RIPEMD160Hash(HashAlgo):
+ """Class that implements a RIPMD-160 hash
+
+ :undocumented: block_size
+ """
+
+ #: ASN.1 Object identifier (OID)::
+ #:
+ #: id-ripemd160 OBJECT IDENTIFIER ::= {
+ #: iso(1) identified-organization(3) teletrust(36)
+ #: algorithm(3) hashAlgorithm(2) ripemd160(1)
+ #: }
+ #:
+ #: This value uniquely identifies the RIPMD-160 algorithm.
+ oid = b("\x06\x05\x2b\x24\x03\x02\x01")
+
+ digest_size = 20
+ block_size = 64
+
+ def __init__(self, data=None):
+ HashAlgo.__init__(self, hashFactory, data)
+
+ def new(self, data=None):
+ return RIPEMD160Hash(data)
+
+def new(data=None):
+ """Return a fresh instance of the hash object.
+
+ :Parameters:
+ data : byte string
+ The very first chunk of the message to hash.
+ It is equivalent to an early call to `RIPEMD160Hash.update()`.
+ Optional.
+
+ :Return: A `RIPEMD160Hash` object
+ """
+ return RIPEMD160Hash().new(data)
+
+#: The size of the resulting hash in bytes.
+digest_size = RIPEMD160Hash.digest_size
+
+#: The internal block size of the hash algorithm in bytes.
+block_size = RIPEMD160Hash.block_size
+
diff --git a/frozen_deps/Crypto/Hash/SHA.py b/frozen_deps/Crypto/Hash/SHA.py
new file mode 100644
index 0000000..0bc5917
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/SHA.py
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""SHA-1 cryptographic hash algorithm.
+
+SHA-1_ produces the 160 bit digest of a message.
+
+ >>> from Crypto.Hash import SHA
+ >>>
+ >>> h = SHA.new()
+ >>> h.update(b'Hello')
+ >>> print h.hexdigest()
+
+*SHA* stands for Secure Hash Algorithm.
+
+This algorithm is not considered secure. Do not use it for new designs.
+
+.. _SHA-1: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+"""
+
+_revision__ = "$Id$"
+
+__all__ = ['new', 'digest_size', 'SHA1Hash' ]
+
+from Crypto.Util.py3compat import *
+from Crypto.Hash.hashalgo import HashAlgo
+
+try:
+ # The sha module is deprecated in Python 2.6, so use hashlib when possible.
+ import hashlib
+ hashFactory = hashlib.sha1
+
+except ImportError:
+ import sha
+ hashFactory = sha
+
+class SHA1Hash(HashAlgo):
+ """Class that implements a SHA-1 hash
+
+ :undocumented: block_size
+ """
+
+ #: ASN.1 Object identifier (OID)::
+ #:
+ #: id-sha1 OBJECT IDENTIFIER ::= {
+ #: iso(1) identified-organization(3) oiw(14) secsig(3)
+ #: algorithms(2) 26
+ #: }
+ #:
+ #: This value uniquely identifies the SHA-1 algorithm.
+ oid = b('\x06\x05\x2b\x0e\x03\x02\x1a')
+
+ digest_size = 20
+ block_size = 64
+
+ def __init__(self, data=None):
+ HashAlgo.__init__(self, hashFactory, data)
+
+ def new(self, data=None):
+ return SHA1Hash(data)
+
+def new(data=None):
+ """Return a fresh instance of the hash object.
+
+ :Parameters:
+ data : byte string
+ The very first chunk of the message to hash.
+ It is equivalent to an early call to `SHA1Hash.update()`.
+ Optional.
+
+ :Return: A `SHA1Hash` object
+ """
+ return SHA1Hash().new(data)
+
+#: The size of the resulting hash in bytes.
+digest_size = SHA1Hash.digest_size
+
+#: The internal block size of the hash algorithm in bytes.
+block_size = SHA1Hash.block_size
+
+
diff --git a/frozen_deps/Crypto/Hash/SHA224.py b/frozen_deps/Crypto/Hash/SHA224.py
new file mode 100644
index 0000000..959b56d
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/SHA224.py
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""SHA-224 cryptographic hash algorithm.
+
+SHA-224 belongs to the SHA-2_ family of cryptographic hashes.
+It produces the 224 bit digest of a message.
+
+ >>> from Crypto.Hash import SHA224
+ >>>
+ >>> h = SHA224.new()
+ >>> h.update(b'Hello')
+ >>> print h.hexdigest()
+
+*SHA* stands for Secure Hash Algorithm.
+
+.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+"""
+
+_revision__ = "$Id$"
+
+__all__ = ['new', 'digest_size', 'SHA224Hash' ]
+
+from Crypto.Util.py3compat import *
+from Crypto.Hash.hashalgo import HashAlgo
+
+try:
+ import hashlib
+ hashFactory = hashlib.sha224
+
+except ImportError:
+ from Crypto.Hash import _SHA224
+ hashFactory = _SHA224
+
+class SHA224Hash(HashAlgo):
+ """Class that implements a SHA-224 hash
+
+ :undocumented: block_size
+ """
+
+ #: ASN.1 Object identifier (OID)::
+ #:
+ #: id-sha224 OBJECT IDENTIFIER ::= {
+ #: joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3)
+ #: nistalgorithm(4) hashalgs(2) 4
+ #: }
+ #:
+ #: This value uniquely identifies the SHA-224 algorithm.
+ oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04')
+
+ digest_size = 28
+ block_size = 64
+
+ def __init__(self, data=None):
+ HashAlgo.__init__(self, hashFactory, data)
+
+ def new(self, data=None):
+ return SHA224Hash(data)
+
+def new(data=None):
+ """Return a fresh instance of the hash object.
+
+ :Parameters:
+ data : byte string
+ The very first chunk of the message to hash.
+ It is equivalent to an early call to `SHA224Hash.update()`.
+ Optional.
+
+ :Return: A `SHA224Hash` object
+ """
+ return SHA224Hash().new(data)
+
+#: The size of the resulting hash in bytes.
+digest_size = SHA224Hash.digest_size
+
+#: The internal block size of the hash algorithm in bytes.
+block_size = SHA224Hash.block_size
+
diff --git a/frozen_deps/Crypto/Hash/SHA256.py b/frozen_deps/Crypto/Hash/SHA256.py
new file mode 100644
index 0000000..b0a99b3
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/SHA256.py
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""SHA-256 cryptographic hash algorithm.
+
+SHA-256 belongs to the SHA-2_ family of cryptographic hashes.
+It produces the 256 bit digest of a message.
+
+ >>> from Crypto.Hash import SHA256
+ >>>
+ >>> h = SHA256.new()
+ >>> h.update(b'Hello')
+ >>> print h.hexdigest()
+
+*SHA* stands for Secure Hash Algorithm.
+
+.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+"""
+
+_revision__ = "$Id$"
+
+__all__ = ['new', 'digest_size', 'SHA256Hash' ]
+
+from Crypto.Util.py3compat import *
+from Crypto.Hash.hashalgo import HashAlgo
+
+try:
+ import hashlib
+ hashFactory = hashlib.sha256
+
+except ImportError:
+ from Crypto.Hash import _SHA256
+ hashFactory = _SHA256
+
+class SHA256Hash(HashAlgo):
+ """Class that implements a SHA-256 hash
+
+ :undocumented: block_size
+ """
+
+ #: ASN.1 Object identifier (OID)::
+ #:
+ #: id-sha256 OBJECT IDENTIFIER ::= {
+ #: joint-iso-itu-t(2) country(16) us(840) organization(1)
+ #: gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1
+ #: }
+ #:
+ #: This value uniquely identifies the SHA-256 algorithm.
+ oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01')
+
+ digest_size = 32
+ block_size = 64
+
+ def __init__(self, data=None):
+ HashAlgo.__init__(self, hashFactory, data)
+
+ def new(self, data=None):
+ return SHA256Hash(data)
+
+def new(data=None):
+ """Return a fresh instance of the hash object.
+
+ :Parameters:
+ data : byte string
+ The very first chunk of the message to hash.
+ It is equivalent to an early call to `SHA256Hash.update()`.
+ Optional.
+
+ :Return: A `SHA256Hash` object
+ """
+ return SHA256Hash().new(data)
+
+#: The size of the resulting hash in bytes.
+digest_size = SHA256Hash.digest_size
+
+#: The internal block size of the hash algorithm in bytes.
+block_size = SHA256Hash.block_size
+
diff --git a/frozen_deps/Crypto/Hash/SHA384.py b/frozen_deps/Crypto/Hash/SHA384.py
new file mode 100644
index 0000000..3490b02
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/SHA384.py
@@ -0,0 +1,96 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""SHA-384 cryptographic hash algorithm.
+
+SHA-384 belongs to the SHA-2_ family of cryptographic hashes.
+It produces the 384 bit digest of a message.
+
+ >>> from Crypto.Hash import SHA384
+ >>>
+ >>> h = SHA384.new()
+ >>> h.update(b'Hello')
+ >>> print h.hexdigest()
+
+*SHA* stands for Secure Hash Algorithm.
+
+.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+"""
+
+_revision__ = "$Id$"
+
+__all__ = ['new', 'digest_size', 'SHA384Hash' ]
+
+from Crypto.Util.py3compat import *
+from Crypto.Hash.hashalgo import HashAlgo
+
+try:
+ import hashlib
+ hashFactory = hashlib.sha384
+
+except ImportError:
+ from Crypto.Hash import _SHA384
+ hashFactory = _SHA384
+
+class SHA384Hash(HashAlgo):
+ """Class that implements a SHA-384 hash
+
+ :undocumented: block_size
+ """
+
+ #: ASN.1 Object identifier (OID)::
+ #:
+ #: id-sha384 OBJECT IDENTIFIER ::= {
+ #: joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3)
+ #: nistalgorithm(4) hashalgs(2) 2
+ #: }
+ #:
+ #: This value uniquely identifies the SHA-384 algorithm.
+ oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02')
+
+ digest_size = 48
+ block_size = 128
+
+ def __init__(self, data=None):
+ HashAlgo.__init__(self, hashFactory, data)
+
+ def new(self, data=None):
+ return SHA384Hash(data)
+
+def new(data=None):
+ """Return a fresh instance of the hash object.
+
+ :Parameters:
+ data : byte string
+ The very first chunk of the message to hash.
+ It is equivalent to an early call to `SHA384Hash.update()`.
+ Optional.
+
+ :Return: A `SHA384Hash` object
+ """
+ return SHA384Hash().new(data)
+
+#: The size of the resulting hash in bytes.
+digest_size = SHA384Hash.digest_size
+
+#: The internal block size of the hash algorithm in bytes.
+block_size = SHA384Hash.block_size
+
+
diff --git a/frozen_deps/Crypto/Hash/SHA512.py b/frozen_deps/Crypto/Hash/SHA512.py
new file mode 100644
index 0000000..d57548d
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/SHA512.py
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""SHA-512 cryptographic hash algorithm.
+
+SHA-512 belongs to the SHA-2_ family of cryptographic hashes.
+It produces the 512 bit digest of a message.
+
+ >>> from Crypto.Hash import SHA512
+ >>>
+ >>> h = SHA512.new()
+ >>> h.update(b'Hello')
+ >>> print h.hexdigest()
+
+*SHA* stands for Secure Hash Algorithm.
+
+.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+"""
+
+_revision__ = "$Id$"
+
+__all__ = ['new', 'digest_size', 'SHA512Hash' ]
+
+from Crypto.Util.py3compat import *
+from Crypto.Hash.hashalgo import HashAlgo
+
+try:
+ import hashlib
+ hashFactory = hashlib.sha512
+
+except ImportError:
+ from Crypto.Hash import _SHA512
+ hashFactory = _SHA512
+
+class SHA512Hash(HashAlgo):
+ """Class that implements a SHA-512 hash
+
+ :undocumented: block_size
+ """
+
+ #: ASN.1 Object identifier (OID)::
+ #:
+ #: id-sha512 OBJECT IDENTIFIER ::= {
+ #: joint-iso-itu-t(2)
+ #: country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3
+ #: }
+ #:
+ #: This value uniquely identifies the SHA-512 algorithm.
+ oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03')
+
+ digest_size = 64
+ block_size = 128
+
+ def __init__(self, data=None):
+ HashAlgo.__init__(self, hashFactory, data)
+
+ def new(self, data=None):
+ return SHA512Hash(data)
+
+def new(data=None):
+ """Return a fresh instance of the hash object.
+
+ :Parameters:
+ data : byte string
+ The very first chunk of the message to hash.
+ It is equivalent to an early call to `SHA512Hash.update()`.
+ Optional.
+
+ :Return: A `SHA512Hash` object
+ """
+ return SHA512Hash().new(data)
+
+#: The size of the resulting hash in bytes.
+digest_size = SHA512Hash.digest_size
+
+#: The internal block size of the hash algorithm in bytes.
+block_size = SHA512Hash.block_size
+
diff --git a/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
new file mode 100755
index 0000000..6fbfc79
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/_MD2.cpython-38-x86_64-linux-gnu.so
Binary files 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
new file mode 100755
index 0000000..286f3ec
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/_MD4.cpython-38-x86_64-linux-gnu.so
Binary files 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
new file mode 100755
index 0000000..a66d804
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/_RIPEMD160.cpython-38-x86_64-linux-gnu.so
Binary files 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
new file mode 100755
index 0000000..eac6cae
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/_SHA224.cpython-38-x86_64-linux-gnu.so
Binary files 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
new file mode 100755
index 0000000..0155f47
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/_SHA256.cpython-38-x86_64-linux-gnu.so
Binary files 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
new file mode 100755
index 0000000..3d1049b
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/_SHA384.cpython-38-x86_64-linux-gnu.so
Binary files 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
new file mode 100755
index 0000000..e3c5c5c
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/_SHA512.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Crypto/Hash/__init__.py b/frozen_deps/Crypto/Hash/__init__.py
new file mode 100644
index 0000000..4582c66
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/__init__.py
@@ -0,0 +1,56 @@
+# -*- 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
new file mode 100644
index 0000000..b38b3a6
--- /dev/null
+++ b/frozen_deps/Crypto/Hash/hashalgo.py
@@ -0,0 +1,116 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+from binascii import hexlify
+
+class HashAlgo:
+ """A generic class for an abstract cryptographic hash algorithm.
+
+ :undocumented: block_size
+ """
+
+ #: The size of the resulting hash in bytes.
+ digest_size = None
+ #: The internal block size of the hash algorithm in bytes.
+ block_size = None
+
+ def __init__(self, hashFactory, data=None):
+ """Initialize the hash object.
+
+ :Parameters:
+ hashFactory : callable
+ An object that will generate the actual hash implementation.
+ *hashFactory* must have a *new()* method, or must be directly
+ callable.
+ data : byte string
+ The very first chunk of the message to hash.
+ It is equivalent to an early call to `update()`.
+ """
+ if hasattr(hashFactory, 'new'):
+ self._hash = hashFactory.new()
+ else:
+ self._hash = hashFactory()
+ if data:
+ self.update(data)
+
+ def update(self, data):
+ """Continue hashing of a message by consuming the next chunk of data.
+
+ Repeated calls are equivalent to a single call with the concatenation
+ of all the arguments. In other words:
+
+ >>> m.update(a); m.update(b)
+
+ is equivalent to:
+
+ >>> m.update(a+b)
+
+ :Parameters:
+ data : byte string
+ The next chunk of the message being hashed.
+ """
+ return self._hash.update(data)
+
+ def digest(self):
+ """Return the **binary** (non-printable) digest of the message that has been hashed so far.
+
+ This method does not change the state of the hash object.
+ You can continue updating the object after calling this function.
+
+ :Return: A byte string of `digest_size` bytes. It may contain non-ASCII
+ characters, including null bytes.
+ """
+ return self._hash.digest()
+
+ def hexdigest(self):
+ """Return the **printable** digest of the message that has been hashed so far.
+
+ This method does not change the state of the hash object.
+
+ :Return: A string of 2* `digest_size` characters. It contains only
+ hexadecimal ASCII digits.
+ """
+ return self._hash.hexdigest()
+
+ def copy(self):
+ """Return a copy ("clone") of the hash object.
+
+ The copy will have the same internal state as the original hash
+ object.
+ This can be used to efficiently compute the digests of strings that
+ share a common initial substring.
+
+ :Return: A hash object of the same type
+ """
+ return self._hash.copy()
+
+ def new(self, data=None):
+ """Return a fresh instance of the hash object.
+
+ Unlike the `copy` method, the internal state of the object is empty.
+
+ :Parameters:
+ data : byte string
+ The next chunk of the message being hashed.
+
+ :Return: A hash object of the same type
+ """
+ pass
+
diff --git a/frozen_deps/Crypto/Protocol/AllOrNothing.py b/frozen_deps/Crypto/Protocol/AllOrNothing.py
new file mode 100644
index 0000000..dd20536
--- /dev/null
+++ b/frozen_deps/Crypto/Protocol/AllOrNothing.py
@@ -0,0 +1,320 @@
+#
+# 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
new file mode 100644
index 0000000..bbfcbda
--- /dev/null
+++ b/frozen_deps/Crypto/Protocol/Chaffing.py
@@ -0,0 +1,245 @@
+#
+# Chaffing.py : chaffing & winnowing support
+#
+# Part of the Python Cryptography Toolkit
+#
+# Written by Andrew M. Kuchling, Barry A. Warsaw, and others
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+#
+"""This file implements the chaffing algorithm.
+
+Winnowing and chaffing is a technique for enhancing privacy without requiring
+strong encryption. In short, the technique takes a set of authenticated
+message blocks (the wheat) and adds a number of chaff blocks which have
+randomly chosen data and MAC fields. This means that to an adversary, the
+chaff blocks look as valid as the wheat blocks, and so the authentication
+would have to be performed on every block. By tailoring the number of chaff
+blocks added to the message, the sender can make breaking the message
+computationally infeasible. There are many other interesting properties of
+the winnow/chaff technique.
+
+For example, say Alice is sending a message to Bob. She packetizes the
+message and performs an all-or-nothing transformation on the packets. Then
+she authenticates each packet with a message authentication code (MAC). The
+MAC is a hash of the data packet, and there is a secret key which she must
+share with Bob (key distribution is an exercise left to the reader). She then
+adds a serial number to each packet, and sends the packets to Bob.
+
+Bob receives the packets, and using the shared secret authentication key,
+authenticates the MACs for each packet. Those packets that have bad MACs are
+simply discarded. The remainder are sorted by serial number, and passed
+through the reverse all-or-nothing transform. The transform means that an
+eavesdropper (say Eve) must acquire all the packets before any of the data can
+be read. If even one packet is missing, the data is useless.
+
+There's one twist: by adding chaff packets, Alice and Bob can make Eve's job
+much harder, since Eve now has to break the shared secret key, or try every
+combination of wheat and chaff packet to read any of the message. The cool
+thing is that Bob doesn't need to add any additional code; the chaff packets
+are already filtered out because their MACs don't match (in all likelihood --
+since the data and MACs for the chaff packets are randomly chosen it is
+possible, but very unlikely that a chaff MAC will match the chaff data). And
+Alice need not even be the party adding the chaff! She could be completely
+unaware that a third party, say Charles, is adding chaff packets to her
+messages as they are transmitted.
+
+For more information on winnowing and chaffing see this paper:
+
+Ronald L. Rivest, "Chaffing and Winnowing: Confidentiality without Encryption"
+http://theory.lcs.mit.edu/~rivest/chaffing.txt
+
+"""
+
+__revision__ = "$Id$"
+
+from Crypto.Util.number import bytes_to_long
+
+class Chaff:
+ """Class implementing the chaff adding algorithm.
+
+ Methods for subclasses:
+
+ _randnum(size):
+ Returns a randomly generated number with a byte-length equal
+ to size. Subclasses can use this to implement better random
+ data and MAC generating algorithms. The default algorithm is
+ probably not very cryptographically secure. It is most
+ important that the chaff data does not contain any patterns
+ that can be used to discern it from wheat data without running
+ the MAC.
+
+ """
+
+ def __init__(self, factor=1.0, blocksper=1):
+ """Chaff(factor:float, blocksper:int)
+
+ factor is the number of message blocks to add chaff to,
+ expressed as a percentage between 0.0 and 1.0. blocksper is
+ the number of chaff blocks to include for each block being
+ chaffed. Thus the defaults add one chaff block to every
+ message block. By changing the defaults, you can adjust how
+ computationally difficult it could be for an adversary to
+ brute-force crack the message. The difficulty is expressed
+ as:
+
+ pow(blocksper, int(factor * number-of-blocks))
+
+ For ease of implementation, when factor < 1.0, only the first
+ int(factor*number-of-blocks) message blocks are chaffed.
+ """
+
+ if not (0.0<=factor<=1.0):
+ raise ValueError("'factor' must be between 0.0 and 1.0")
+ if blocksper < 0:
+ raise ValueError("'blocksper' must be zero or more")
+
+ self.__factor = factor
+ self.__blocksper = blocksper
+
+
+ def chaff(self, blocks):
+ """chaff( [(serial-number:int, data:string, MAC:string)] )
+ : [(int, string, string)]
+
+ Add chaff to message blocks. blocks is a list of 3-tuples of the
+ form (serial-number, data, MAC).
+
+ Chaff is created by choosing a random number of the same
+ byte-length as data, and another random number of the same
+ byte-length as MAC. The message block's serial number is
+ placed on the chaff block and all the packet's chaff blocks
+ are randomly interspersed with the single wheat block. This
+ method then returns a list of 3-tuples of the same form.
+ Chaffed blocks will contain multiple instances of 3-tuples
+ with the same serial number, but the only way to figure out
+ which blocks are wheat and which are chaff is to perform the
+ MAC hash and compare values.
+ """
+
+ chaffedblocks = []
+
+ # count is the number of blocks to add chaff to. blocksper is the
+ # number of chaff blocks to add per message block that is being
+ # chaffed.
+ count = len(blocks) * self.__factor
+ blocksper = 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
new file mode 100644
index 0000000..af4e2a6
--- /dev/null
+++ b/frozen_deps/Crypto/Protocol/KDF.py
@@ -0,0 +1,123 @@
+#
+# 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)<dkLen:
+ U = previousU = prf(password,salt+struct.pack(">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
new file mode 100644
index 0000000..cacc685
--- /dev/null
+++ b/frozen_deps/Crypto/Protocol/__init__.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Cryptographic protocols
+
+Implements various cryptographic protocols. (Don't expect to find
+network protocols here.)
+
+Crypto.Protocol.AllOrNothing
+ Transforms a message into a set of message blocks, such that the blocks
+ can be recombined to get the message back.
+
+Crypto.Protocol.Chaffing
+ Takes a set of authenticated message blocks (the wheat) and adds a number
+ of randomly generated blocks (the chaff).
+
+Crypto.Protocol.KDF
+ A collection of standard key derivation functions.
+
+:undocumented: __revision__
+"""
+
+__all__ = ['AllOrNothing', 'Chaffing', 'KDF']
+__revision__ = "$Id$"
diff --git a/frozen_deps/Crypto/PublicKey/DSA.py b/frozen_deps/Crypto/PublicKey/DSA.py
new file mode 100644
index 0000000..648f4b2
--- /dev/null
+++ b/frozen_deps/Crypto/PublicKey/DSA.py
@@ -0,0 +1,379 @@
+# -*- coding: utf-8 -*-
+#
+# PublicKey/DSA.py : DSA signature primitive
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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<x<q-1*) as private key, and its public
+key (*y* where *y=g^x mod p*) is distributed.
+
+In 2012, a sufficient size is deemed to be 2048 bits for *p* and 256 bits for *q*.
+For more information, see the most recent ECRYPT_ report.
+
+DSA is reasonably secure for new designs.
+
+The algorithm can only be used for authentication (digital signature).
+DSA cannot be used for confidentiality (encryption).
+
+The values *(p,q,g)* are called *domain parameters*;
+they are not sensitive but must be shared by both parties (the signer and the verifier).
+Different signers can share the same domain parameters with no security
+concerns.
+
+The DSA signature is twice as big as the size of *q* (64 bytes if *q* is 256 bit
+long).
+
+This module provides facilities for generating new DSA keys and for constructing
+them from known components. DSA keys allows you to perform basic signing and
+verification.
+
+ >>> 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
new file mode 100644
index 0000000..99af71c
--- /dev/null
+++ b/frozen_deps/Crypto/PublicKey/ElGamal.py
@@ -0,0 +1,373 @@
+#
+# ElGamal.py : ElGamal encryption/decryption and signatures
+#
+# Part of the Python Cryptography Toolkit
+#
+# Originally written by: A.M. Kuchling
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""ElGamal public-key algorithm (randomized encryption and signature).
+
+Signature algorithm
+-------------------
+The security of the ElGamal signature scheme is based (like DSA) on the discrete
+logarithm problem (DLP_). Given a cyclic group, a generator *g*,
+and an element *h*, it is hard to find an integer *x* such that *g^x = h*.
+
+The group is the largest multiplicative sub-group of the integers modulo *p*,
+with *p* prime.
+The signer holds a value *x* (*0<x<p-1*) as private key, and its public
+key (*y* where *y=g^x mod p*) is distributed.
+
+The ElGamal signature is twice as big as *p*.
+
+Encryption algorithm
+--------------------
+The security of the ElGamal encryption scheme is based on the computational
+Diffie-Hellman problem (CDH_). Given a cyclic group, a generator *g*,
+and two integers *a* and *b*, it is difficult to find
+the element *g^{ab}* when only *g^a* and *g^b* are known, and not *a* and *b*.
+
+As before, the group is the largest multiplicative sub-group of the integers
+modulo *p*, with *p* prime.
+The receiver holds a value *a* (*0<a<p-1*) as private key, and its public key
+(*b* where *b*=g^a*) is given to the sender.
+
+The ElGamal ciphertext is twice as big as *p*.
+
+Domain parameters
+-----------------
+For both signature and encryption schemes, the values *(p,g)* are called
+*domain parameters*.
+They are not sensitive but must be distributed to all parties (senders and
+receivers).
+Different signers can share the same domain parameters, as can
+different recipients of encrypted messages.
+
+Security
+--------
+Both DLP and CDH problem are believed to be difficult, and they have been proved
+such (and therefore secure) for more than 30 years.
+
+The cryptographic strength is linked to the magnitude of *p*.
+In 2012, a sufficient size for *p* is deemed to be 2048 bits.
+For more information, see the most recent ECRYPT_ report.
+
+Even though ElGamal algorithms are in theory reasonably secure for new designs,
+in practice there are no real good reasons for using them.
+The signature is four times larger than the equivalent DSA, and the ciphertext
+is two times larger than the equivalent RSA.
+
+Functionality
+-------------
+This module provides facilities for generating new ElGamal keys and for constructing
+them from known components. ElGamal keys allows you to perform basic signing,
+verification, encryption, and decryption.
+
+ >>> 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
new file mode 100644
index 0000000..debe39e
--- /dev/null
+++ b/frozen_deps/Crypto/PublicKey/RSA.py
@@ -0,0 +1,719 @@
+# -*- coding: utf-8 -*-
+#
+# PublicKey/RSA.py : RSA public key primitive
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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
new file mode 100644
index 0000000..1787ced
--- /dev/null
+++ b/frozen_deps/Crypto/PublicKey/_DSA.py
@@ -0,0 +1,115 @@
+
+#
+# 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 1<h<p-1 and g>1:
+ 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
new file mode 100644
index 0000000..601ab7c
--- /dev/null
+++ b/frozen_deps/Crypto/PublicKey/_RSA.py
@@ -0,0 +1,81 @@
+#
+# 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
new file mode 100644
index 0000000..503809f
--- /dev/null
+++ b/frozen_deps/Crypto/PublicKey/__init__.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Public-key encryption and signature algorithms.
+
+Public-key encryption uses two different keys, one for encryption and
+one for decryption. The encryption key can be made public, and the
+decryption key is kept private. Many public-key algorithms can also
+be used to sign messages, and some can *only* be used for signatures.
+
+======================== =============================================
+Module Description
+======================== =============================================
+Crypto.PublicKey.DSA Digital Signature Algorithm (Signature only)
+Crypto.PublicKey.ElGamal (Signing and encryption)
+Crypto.PublicKey.RSA (Signing, encryption, and blinding)
+======================== =============================================
+
+:undocumented: _DSA, _RSA, _fastmath, _slowmath, pubkey
+"""
+
+__all__ = ['RSA', 'DSA', 'ElGamal']
+__revision__ = "$Id$"
+
diff --git a/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
new file mode 100755
index 0000000..f0fe708
--- /dev/null
+++ b/frozen_deps/Crypto/PublicKey/_fastmath.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Crypto/PublicKey/_slowmath.py b/frozen_deps/Crypto/PublicKey/_slowmath.py
new file mode 100644
index 0000000..c87bdd2
--- /dev/null
+++ b/frozen_deps/Crypto/PublicKey/_slowmath.py
@@ -0,0 +1,187 @@
+# -*- coding: utf-8 -*-
+#
+# PubKey/RSA/_slowmath.py : Pure Python implementation of the RSA portions of _fastmath
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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<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.
+ obj.p = GCD(cand+1,n)
+ spotted = 1
+ break
+ k = k*2
+ # This value was not any good... let's try another!
+ a = a+2
+ if not spotted:
+ raise ValueError("Unable to compute factors p and q from exponent d.")
+ # Found !
+ assert ((n % obj.p)==0)
+ obj.q = divmod(n,obj.p)[0]
+ if u is not None:
+ obj.u = u
+ else:
+ obj.u = inverse(obj.p, obj.q)
+ return obj
+
+class _DSAKey(object):
+ def size(self):
+ """Return the maximum number of bits that can be encrypted"""
+ return size(self.p) - 1
+
+ def has_private(self):
+ return hasattr(self, 'x')
+
+ def _sign(self, m, k): # alias for _decrypt
+ # SECURITY TODO - We _should_ be computing SHA1(m), but we don't because that's the API.
+ if not self.has_private():
+ raise TypeError("No private key")
+ if not (1 < k < self.q):
+ raise ValueError("k is not between 2 and q-1")
+ inv_k = inverse(k, self.q) # Compute k**-1 mod q
+ r = pow(self.g, k, self.p) % self.q # r = (g**k mod p) mod q
+ s = (inv_k * (m + self.x * r)) % self.q
+ return (r, s)
+
+ def _verify(self, m, r, s):
+ # SECURITY TODO - We _should_ be computing SHA1(m), but we don't because that's the API.
+ if not (0 < r < self.q) or not (0 < s < self.q):
+ return False
+ w = inverse(s, self.q)
+ u1 = (m*w) % self.q
+ u2 = (r*w) % self.q
+ v = (pow(self.g, u1, self.p) * pow(self.y, u2, self.p) % self.p) % self.q
+ return v == r
+
+def dsa_construct(y, g, p, q, x=None):
+ assert isinstance(y, int)
+ assert isinstance(g, int)
+ assert isinstance(p, int)
+ assert isinstance(q, int)
+ assert isinstance(x, (int, type(None)))
+ obj = _DSAKey()
+ obj.y = y
+ obj.g = g
+ obj.p = p
+ obj.q = q
+ if x is not None: obj.x = x
+ return obj
+
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
+
diff --git a/frozen_deps/Crypto/PublicKey/pubkey.py b/frozen_deps/Crypto/PublicKey/pubkey.py
new file mode 100644
index 0000000..e46b076
--- /dev/null
+++ b/frozen_deps/Crypto/PublicKey/pubkey.py
@@ -0,0 +1,240 @@
+#
+# pubkey.py : Internal functions for public key operations
+#
+# Part of the Python Cryptography Toolkit
+#
+# Written by Andrew Kuchling, Paul Swartz, and others
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+#
+
+__revision__ = "$Id$"
+
+import types, warnings
+from Crypto.Util.number import *
+
+# Basic public key class
+class pubkey:
+ """An abstract class for a public key object.
+
+ :undocumented: __getstate__, __setstate__, __eq__, __ne__, validate
+ """
+ def __init__(self):
+ pass
+
+ def __getstate__(self):
+ """To keep key objects platform-independent, the key data is
+ converted to standard Python long integers before being
+ written out. It will then be reconverted as necessary on
+ restoration."""
+ d=self.__dict__
+ for key in self.keydata:
+ if key in d: d[key]=int(d[key])
+ return d
+
+ def __setstate__(self, d):
+ """On unpickling a key object, the key data is converted to the big
+number representation being used, whether that is Python long
+integers, MPZ objects, or whatever."""
+ for key in self.keydata:
+ if key in d: self.__dict__[key]=bignum(d[key])
+
+ def encrypt(self, plaintext, K):
+ """Encrypt a piece of data.
+
+ :Parameter plaintext: The piece of data to encrypt.
+ :Type plaintext: byte string or long
+
+ :Parameter K: A random parameter required by some algorithms
+ :Type K: byte string or long
+
+ :Return: A tuple with two items. Each item is of the same type as the
+ plaintext (string or long).
+ """
+ wasString=0
+ if isinstance(plaintext, bytes):
+ plaintext=bytes_to_long(plaintext) ; wasString=1
+ if isinstance(K, bytes):
+ K=bytes_to_long(K)
+ ciphertext=self._encrypt(plaintext, K)
+ if wasString: return tuple(map(long_to_bytes, ciphertext))
+ else: return ciphertext
+
+ def decrypt(self, ciphertext):
+ """Decrypt a piece of data.
+
+ :Parameter ciphertext: The piece of data to decrypt.
+ :Type ciphertext: byte string, long or a 2-item tuple as returned by `encrypt`
+
+ :Return: A byte string if ciphertext was a byte string or a tuple
+ of byte strings. A long otherwise.
+ """
+ wasString=0
+ if not isinstance(ciphertext, tuple):
+ ciphertext=(ciphertext,)
+ if isinstance(ciphertext[0], bytes):
+ ciphertext=tuple(map(bytes_to_long, ciphertext)) ; wasString=1
+ plaintext=self._decrypt(ciphertext)
+ if wasString: return long_to_bytes(plaintext)
+ else: return plaintext
+
+ def sign(self, M, K):
+ """Sign a piece of data.
+
+ :Parameter M: The piece of data to encrypt.
+ :Type M: byte string or long
+
+ :Parameter K: A random parameter required by some algorithms
+ :Type K: byte string or long
+
+ :Return: A tuple with two items.
+ """
+ if (not self.has_private()):
+ raise TypeError('Private key not available in this object')
+ if isinstance(M, bytes): M=bytes_to_long(M)
+ if isinstance(K, bytes): K=bytes_to_long(K)
+ return self._sign(M, K)
+
+ def verify (self, M, signature):
+ """Verify the validity of a signature.
+
+ :Parameter M: The expected message.
+ :Type M: byte string or long
+
+ :Parameter signature: The signature to verify.
+ :Type signature: tuple with two items, as return by `sign`
+
+ :Return: True if the signature is correct, False otherwise.
+ """
+ if isinstance(M, bytes): M=bytes_to_long(M)
+ return self._verify(M, signature)
+
+ # alias to compensate for the old validate() name
+ def validate (self, M, signature):
+ warnings.warn("validate() method name is obsolete; use verify()",
+ DeprecationWarning)
+
+ def blind(self, M, B):
+ """Blind a message to prevent certain side-channel attacks.
+
+ :Parameter M: The message to blind.
+ :Type M: byte string or long
+
+ :Parameter B: Blinding factor.
+ :Type B: byte string or long
+
+ :Return: A byte string if M was so. A long otherwise.
+ """
+ wasString=0
+ if isinstance(M, bytes):
+ M=bytes_to_long(M) ; wasString=1
+ if isinstance(B, bytes): B=bytes_to_long(B)
+ blindedmessage=self._blind(M, B)
+ if wasString: return long_to_bytes(blindedmessage)
+ else: return blindedmessage
+
+ def unblind(self, M, B):
+ """Unblind a message after cryptographic processing.
+
+ :Parameter M: The encoded message to unblind.
+ :Type M: byte string or long
+
+ :Parameter B: Blinding factor.
+ :Type B: byte string or long
+ """
+ wasString=0
+ if isinstance(M, bytes):
+ M=bytes_to_long(M) ; wasString=1
+ if isinstance(B, bytes): B=bytes_to_long(B)
+ unblindedmessage=self._unblind(M, B)
+ if wasString: return long_to_bytes(unblindedmessage)
+ else: return unblindedmessage
+
+
+ # The following methods will usually be left alone, except for
+ # signature-only algorithms. They both return Boolean values
+ # recording whether this key's algorithm can sign and encrypt.
+ def can_sign (self):
+ """Tell if the algorithm can deal with cryptographic signatures.
+
+ This property concerns the *algorithm*, not the key itself.
+ It may happen that this particular key object hasn't got
+ the private information required to generate a signature.
+
+ :Return: boolean
+ """
+ return 1
+
+ def can_encrypt (self):
+ """Tell if the algorithm can deal with data encryption.
+
+ This property concerns the *algorithm*, not the key itself.
+ It may happen that this particular key object hasn't got
+ the private information required to decrypt data.
+
+ :Return: boolean
+ """
+ return 1
+
+ def can_blind (self):
+ """Tell if the algorithm can deal with data blinding.
+
+ This property concerns the *algorithm*, not the key itself.
+ It may happen that this particular key object hasn't got
+ the private information required carry out blinding.
+
+ :Return: boolean
+ """
+ return 0
+
+ # The following methods will certainly be overridden by
+ # subclasses.
+
+ def size (self):
+ """Tell the maximum number of bits that can be handled by this key.
+
+ :Return: int
+ """
+ return 0
+
+ def has_private (self):
+ """Tell if the key object contains private components.
+
+ :Return: bool
+ """
+ return 0
+
+ def publickey (self):
+ """Construct a new key carrying only the public information.
+
+ :Return: A new `pubkey` object.
+ """
+ return self
+
+ def __eq__ (self, other):
+ """__eq__(other): 0, 1
+ Compare us to other for equality.
+ """
+ return self.__getstate__() == other.__getstate__()
+
+ def __ne__ (self, other):
+ """__ne__(other): 0, 1
+ Compare us to other for inequality.
+ """
+ return not self.__eq__(other)
diff --git a/frozen_deps/Crypto/Random/Fortuna/FortunaAccumulator.py b/frozen_deps/Crypto/Random/Fortuna/FortunaAccumulator.py
new file mode 100644
index 0000000..5c6beb0
--- /dev/null
+++ b/frozen_deps/Crypto/Random/Fortuna/FortunaAccumulator.py
@@ -0,0 +1,171 @@
+# -*- coding: ascii -*-
+#
+# FortunaAccumulator.py : Fortuna's internal accumulator
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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
new file mode 100644
index 0000000..489c81e
--- /dev/null
+++ b/frozen_deps/Crypto/Random/Fortuna/FortunaGenerator.py
@@ -0,0 +1,132 @@
+# -*- coding: ascii -*-
+#
+# FortunaGenerator.py : Fortuna's internal PRNG
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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
new file mode 100644
index 0000000..2e135c9
--- /dev/null
+++ b/frozen_deps/Crypto/Random/Fortuna/SHAd256.py
@@ -0,0 +1,98 @@
+# -*- coding: ascii -*-
+#
+# Random/Fortuna/SHAd256.py : SHA_d-256 hash function implementation
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/frozen_deps/Crypto/Random/Fortuna/__init__.py
diff --git a/frozen_deps/Crypto/Random/OSRNG/__init__.py b/frozen_deps/Crypto/Random/OSRNG/__init__.py
new file mode 100644
index 0000000..2fbbecb
--- /dev/null
+++ b/frozen_deps/Crypto/Random/OSRNG/__init__.py
@@ -0,0 +1,40 @@
+#
+# Random/OSRNG/__init__.py : Platform-independent OS RNG API
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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
new file mode 100644
index 0000000..6d4130d
--- /dev/null
+++ b/frozen_deps/Crypto/Random/OSRNG/fallback.py
@@ -0,0 +1,46 @@
+#
+# Random/OSRNG/fallback.py : Fallback entropy source for systems with os.urandom
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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 = "<os.urandom>"
+
+ 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
new file mode 100644
index 0000000..ceea7b7
--- /dev/null
+++ b/frozen_deps/Crypto/Random/OSRNG/posix.py
@@ -0,0 +1,86 @@
+#
+# Random/OSRNG/posix.py : OS entropy source for POSIX systems
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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
new file mode 100644
index 0000000..546f2e9
--- /dev/null
+++ b/frozen_deps/Crypto/Random/OSRNG/rng_base.py
@@ -0,0 +1,88 @@
+#
+# Random/OSRNG/rng_base.py : Base class for OSRNG
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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
new file mode 100644
index 0000000..937c17d
--- /dev/null
+++ b/frozen_deps/Crypto/Random/_UserFriendlyRNG.py
@@ -0,0 +1,230 @@
+# -*- coding: utf-8 -*-
+#
+# Random/_UserFriendlyRNG.py : A user-friendly random number generator
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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
new file mode 100644
index 0000000..659ffee
--- /dev/null
+++ b/frozen_deps/Crypto/Random/__init__.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+#
+# Random/__init__.py : PyCrypto random number generation
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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
new file mode 100644
index 0000000..cd9a221
--- /dev/null
+++ b/frozen_deps/Crypto/Random/random.py
@@ -0,0 +1,142 @@
+# -*- coding: utf-8 -*-
+#
+# Random/random.py : Strong alternative for the standard 'random' module
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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
new file mode 100644
index 0000000..319851e
--- /dev/null
+++ b/frozen_deps/Crypto/Signature/PKCS1_PSS.py
@@ -0,0 +1,355 @@
+# -*- coding: utf-8 -*-
+#
+# Signature/PKCS1_PSS.py : PKCS#1 PPS
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""RSA digital signature protocol with appendix according to PKCS#1 PSS.
+
+See RFC3447__ or the `original RSA Labs specification`__.
+
+This scheme is more properly called ``RSASSA-PSS``.
+
+For example, a sender may authenticate a message using SHA-1 and PSS like
+this:
+
+ >>> from Crypto.Signature import PKCS1_PSS
+ >>> from Crypto.Hash import SHA
+ >>> from Crypto.PublicKey import RSA
+ >>> from Crypto import Random
+ >>>
+ >>> message = 'To be signed'
+ >>> key = RSA.importKey(open('privkey.der').read())
+ >>> h = SHA.new()
+ >>> h.update(message)
+ >>> signer = PKCS1_PSS.new(key)
+ >>> signature = PKCS1_PSS.sign(key)
+
+At the receiver side, verification can be done like using the public part of
+the RSA key:
+
+ >>> key = RSA.importKey(open('pubkey.der').read())
+ >>> h = SHA.new()
+ >>> h.update(message)
+ >>> verifier = PKCS1_PSS.new(key)
+ >>> if verifier.verify(h, signature):
+ >>> print "The signature is authentic."
+ >>> else:
+ >>> print "The signature is not authentic."
+
+:undocumented: __revision__, __package__
+
+.. __: http://www.ietf.org/rfc/rfc3447.txt
+.. __: http://www.rsa.com/rsalabs/node.asp?id=2125
+"""
+
+# Allow nested scopes in Python 2.1
+# See http://oreilly.com/pub/a/python/2001/04/19/pythonnews.html
+
+
+__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
new file mode 100644
index 0000000..73ac251
--- /dev/null
+++ b/frozen_deps/Crypto/Signature/PKCS1_v1_5.py
@@ -0,0 +1,236 @@
+# -*- coding: utf-8 -*-
+#
+# Signature/PKCS1-v1_5.py : PKCS#1 v1.5
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""
+RSA digital signature protocol according to PKCS#1 v1.5
+
+See RFC3447__ or the `original RSA Labs specification`__.
+
+This scheme is more properly called ``RSASSA-PKCS1-v1_5``.
+
+For example, a sender may authenticate a message using SHA-1 like
+this:
+
+ >>> from Crypto.Signature import PKCS1_v1_5
+ >>> from Crypto.Hash import SHA
+ >>> from Crypto.PublicKey import RSA
+ >>>
+ >>> message = 'To be signed'
+ >>> key = RSA.importKey(open('privkey.der').read())
+ >>> h = SHA.new(message)
+ >>> signer = PKCS1_v1_5.new(key)
+ >>> signature = signer.sign(h)
+
+At the receiver side, verification can be done using the public part of
+the RSA key:
+
+ >>> key = RSA.importKey(open('pubkey.der').read())
+ >>> h = SHA.new(message)
+ >>> verifier = PKCS1_v1_5.new(key)
+ >>> if verifier.verify(h, signature):
+ >>> print "The signature is authentic."
+ >>> else:
+ >>> print "The signature is not authentic."
+
+:undocumented: __revision__, __package__
+
+.. __: http://www.ietf.org/rfc/rfc3447.txt
+.. __: http://www.rsa.com/rsalabs/node.asp?id=2125
+"""
+
+__revision__ = "$Id$"
+__all__ = [ 'new', 'PKCS115_SigScheme' ]
+
+import Crypto.Util.number
+from Crypto.Util.number import ceil_div
+from Crypto.Util.asn1 import DerSequence, DerNull, DerOctetString
+from Crypto.Util.py3compat import *
+
+class PKCS115_SigScheme:
+ """This signature scheme can perform PKCS#1 v1.5 RSA signature or verification."""
+
+ def __init__(self, key):
+ """Initialize this PKCS#1 v1.5 signature scheme object.
+
+ :Parameters:
+ key : an RSA key object
+ If a private half is given, both signature and verification are possible.
+ If a public half is given, only verification is possible.
+ """
+ self._key = key
+
+ def can_sign(self):
+ """Return True if this cipher object can be used for signing messages."""
+ return self._key.has_private()
+
+ def sign(self, mhash):
+ """Produce the PKCS#1 v1.5 signature of a message.
+
+ This function is named ``RSASSA-PKCS1-V1_5-SIGN``, and is specified in
+ section 8.2.1 of RFC3447.
+
+ :Parameters:
+ mhash : hash object
+ The hash that was carried out over the message. This is an object
+ belonging to the `Crypto.Hash` module.
+
+ :Return: The signature encoded as a string.
+ :Raise ValueError:
+ If the RSA key length is not sufficiently long to deal with the given
+ hash algorithm.
+ :Raise TypeError:
+ If the RSA key has no private half.
+ """
+ # TODO: Verify the key is RSA
+
+ # See 8.2.1 in RFC3447
+ modBits = Crypto.Util.number.size(self._key.n)
+ k = ceil_div(modBits,8) # Convert from bits to bytes
+
+ # Step 1
+ em = EMSA_PKCS1_V1_5_ENCODE(mhash, k)
+ # Step 2a (OS2IP) and 2b (RSASP1)
+ m = self._key.decrypt(em)
+ # Step 2c (I2OSP)
+ S = bchr(0x00)*(k-len(m)) + m
+ return S
+
+ def verify(self, mhash, S):
+ """Verify that a certain PKCS#1 v1.5 signature is authentic.
+
+ This function checks if the party holding the private half of the key
+ really signed the message.
+
+ This function is named ``RSASSA-PKCS1-V1_5-VERIFY``, and is specified in
+ section 8.2.2 of RFC3447.
+
+ :Parameters:
+ mhash : hash object
+ The hash that was carried out over the message. This is an object
+ belonging to the `Crypto.Hash` module.
+ S : string
+ The signature that needs to be validated.
+
+ :Return: True if verification is correct. False otherwise.
+ """
+ # TODO: Verify the key is RSA
+
+ # See 8.2.2 in RFC3447
+ modBits = Crypto.Util.number.size(self._key.n)
+ k = ceil_div(modBits,8) # Convert from bits to bytes
+
+ # Step 1
+ if len(S) != k:
+ return 0
+ # Step 2a (O2SIP) and 2b (RSAVP1)
+ # Note that signature must be smaller than the module
+ # but RSA.py won't complain about it.
+ # TODO: Fix RSA object; don't do it here.
+ m = self._key.encrypt(S, 0)[0]
+ # Step 2c (I2OSP)
+ em1 = bchr(0x00)*(k-len(m)) + m
+ # Step 3
+ try:
+ em2 = EMSA_PKCS1_V1_5_ENCODE(mhash, k)
+ except ValueError:
+ return 0
+ # Step 4
+ # By comparing the full encodings (as opposed to checking each
+ # of its components one at a time) we avoid attacks to the padding
+ # scheme like Bleichenbacher's (see http://www.mail-archive.com/[email protected]/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<len(digestInfo)+11:
+ raise ValueError("Selected hash algorith has a too long digest (%d bytes)." % len(digest))
+ PS = bchr(0xFF) * (emLen - len(digestInfo) - 3)
+ return b("\x00\x01") + PS + bchr(0x00) + digestInfo
+
+def new(key):
+ """Return a signature scheme object `PKCS115_SigScheme` that
+ can be used to perform PKCS#1 v1.5 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.
+
+ """
+ return PKCS115_SigScheme(key)
+
diff --git a/frozen_deps/Crypto/Signature/__init__.py b/frozen_deps/Crypto/Signature/__init__.py
new file mode 100644
index 0000000..ed523b4
--- /dev/null
+++ b/frozen_deps/Crypto/Signature/__init__.py
@@ -0,0 +1,31 @@
+# -*- 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.
+# ===================================================================
+
+"""Digital signature protocols
+
+A collection of standardized protocols to carry out digital signatures.
+
+:undocumented: __revision__, __package__
+"""
+
+__all__ = [ 'PKCS1_v1_5', 'PKCS1_PSS' ]
+__revision__ = "$Id$"
+
+
diff --git a/frozen_deps/Crypto/Util/Counter.py b/frozen_deps/Crypto/Util/Counter.py
new file mode 100644
index 0000000..f0460e5
--- /dev/null
+++ b/frozen_deps/Crypto/Util/Counter.py
@@ -0,0 +1,127 @@
+# -*- coding: ascii -*-
+#
+# Util/Counter.py : Fast counter for use with CTR-mode ciphers
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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
new file mode 100644
index 0000000..1c10c4a
--- /dev/null
+++ b/frozen_deps/Crypto/Util/RFC1751.py
@@ -0,0 +1,365 @@
+# 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
new file mode 100644
index 0000000..a3bef8a
--- /dev/null
+++ b/frozen_deps/Crypto/Util/__init__.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Miscellaneous modules
+
+Contains useful modules that don't belong into any of the
+other Crypto.* subpackages.
+
+Crypto.Util.number Number-theoretic functions (primality testing, etc.)
+Crypto.Util.randpool Random number generation
+Crypto.Util.RFC1751 Converts between 128-bit keys and human-readable
+ strings of words.
+Crypto.Util.asn1 Minimal support for ASN.1 DER encoding
+
+"""
+
+__all__ = ['randpool', 'RFC1751', 'number', 'strxor', 'asn1' ]
+
+__revision__ = "$Id$"
+
diff --git a/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
new file mode 100755
index 0000000..77cd132
--- /dev/null
+++ b/frozen_deps/Crypto/Util/_counter.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Crypto/Util/_number_new.py b/frozen_deps/Crypto/Util/_number_new.py
new file mode 100644
index 0000000..5f29176
--- /dev/null
+++ b/frozen_deps/Crypto/Util/_number_new.py
@@ -0,0 +1,119 @@
+# -*- coding: ascii -*-
+#
+# Util/_number_new.py : utility functions
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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
new file mode 100644
index 0000000..9a97d97
--- /dev/null
+++ b/frozen_deps/Crypto/Util/asn1.py
@@ -0,0 +1,286 @@
+# -*- coding: ascii -*-
+#
+# Util/asn1.py : Minimal support for ASN.1 DER binary encoding.
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+from Crypto.Util.number import long_to_bytes, bytes_to_long
+import sys
+from Crypto.Util.py3compat import *
+
+__all__ = [ 'DerObject', 'DerInteger', 'DerOctetString', 'DerNull', 'DerSequence', 'DerObjectId' ]
+
+class DerObject:
+ """Base class for defining a single DER object.
+
+ Instantiate this class ONLY when you have to decode a DER element.
+ """
+
+ # Known TAG types
+ typeTags = { 'SEQUENCE': 0x30, 'BIT STRING': 0x03, 'INTEGER': 0x02,
+ 'OCTET STRING': 0x04, 'NULL': 0x05, 'OBJECT IDENTIFIER': 0x06 }
+
+ def __init__(self, ASN1Type=None, payload=b('')):
+ """Initialize the DER object according to a specific type.
+
+ The ASN.1 type is either specified as the ASN.1 string (e.g.
+ 'SEQUENCE'), directly with its numerical tag or with no tag
+ at all (None)."""
+ if isInt(ASN1Type) or ASN1Type is None:
+ self.typeTag = ASN1Type
+ else:
+ if len(ASN1Type)==1:
+ self.typeTag = ord(ASN1Type)
+ else:
+ self.typeTag = self.typeTags.get(ASN1Type)
+ self.payload = payload
+
+ def isType(self, ASN1Type):
+ return self.typeTags[ASN1Type]==self.typeTag
+
+ def _lengthOctets(self, payloadLen):
+ """Return a byte string that encodes the given payload length (in
+ bytes) in a format suitable for a DER length tag (L).
+ """
+ if payloadLen>127:
+ encoding = long_to_bytes(payloadLen)
+ return bchr(len(encoding)+128) + encoding
+ return bchr(payloadLen)
+
+ def encode(self):
+ """Return a complete DER element, fully encoded as a TLV."""
+ return bchr(self.typeTag) + self._lengthOctets(len(self.payload)) + self.payload
+
+ def _decodeLen(self, idx, der):
+ """Given a (part of a) DER element, and an index to the first byte of
+ a DER length tag (L), return a tuple with the payload size,
+ and the index of the first byte of the such payload (V).
+
+ Raises a ValueError exception if the DER length is invalid.
+ Raises an IndexError exception if the DER element is too short.
+ """
+ length = bord(der[idx])
+ if length<=127:
+ return (length,idx+1)
+ payloadLength = bytes_to_long(der[idx+1:idx+1+(length & 0x7F)])
+ if payloadLength<=127:
+ raise ValueError("Not a DER length tag.")
+ return (payloadLength, idx+1+(length & 0x7F))
+
+ def decode(self, derEle, noLeftOvers=0):
+ """Decode a complete DER element, and re-initializes this
+ object with it.
+
+ @param derEle A complete DER element. It must start with a DER T
+ tag.
+ @param noLeftOvers Indicate whether it is acceptable to complete the
+ parsing of the DER element and find that not all
+ bytes in derEle have been used.
+ @return Index of the first unused byte in the given DER element.
+
+ Raises a ValueError exception in case of parsing errors.
+ Raises an IndexError exception if the DER element is too short.
+ """
+ try:
+ self.typeTag = bord(derEle[0])
+ if (self.typeTag & 0x1F)==0x1F:
+ raise ValueError("Unsupported DER tag")
+ (length,idx) = self._decodeLen(1, derEle)
+ if noLeftOvers and len(derEle) != (idx+length):
+ raise ValueError("Not a DER structure")
+ self.payload = derEle[idx:idx+length]
+ except IndexError:
+ raise ValueError("Not a valid DER SEQUENCE.")
+ return idx+length
+
+class DerInteger(DerObject):
+ def __init__(self, value = 0):
+ """Class to model an INTEGER DER element.
+
+ Limitation: only non-negative values are supported.
+ """
+ DerObject.__init__(self, 'INTEGER')
+ self.value = value
+
+ def encode(self):
+ """Return a complete INTEGER DER element, fully encoded as a TLV."""
+ self.payload = long_to_bytes(self.value)
+ if bord(self.payload[0])>127:
+ self.payload = bchr(0x00) + self.payload
+ return DerObject.encode(self)
+
+ def decode(self, derEle, noLeftOvers=0):
+ """Decode a complete INTEGER DER element, and re-initializes this
+ object with it.
+
+ @param derEle A complete INTEGER DER element. It must start with a DER
+ INTEGER tag.
+ @param noLeftOvers Indicate whether it is acceptable to complete the
+ parsing of the DER element and find that not all
+ bytes in derEle have been used.
+ @return Index of the first unused byte in the given DER element.
+
+ Raises a ValueError exception if the DER element is not a
+ valid non-negative INTEGER.
+ Raises an IndexError exception if the DER element is too short.
+ """
+ tlvLength = DerObject.decode(self, derEle, noLeftOvers)
+ if self.typeTag!=self.typeTags['INTEGER']:
+ raise ValueError ("Not a DER INTEGER.")
+ if bord(self.payload[0])>127:
+ raise ValueError ("Negative INTEGER.")
+ self.value = bytes_to_long(self.payload)
+ return tlvLength
+
+class DerSequence(DerObject):
+ """Class to model a SEQUENCE DER element.
+
+ This object behave like a dynamic Python sequence.
+ Sub-elements that are INTEGERs, look like Python integers.
+ Any other sub-element is a binary string encoded as the complete DER
+ sub-element (TLV).
+ """
+
+ def __init__(self, startSeq=None):
+ """Initialize the SEQUENCE DER object. Always empty
+ initially."""
+ DerObject.__init__(self, 'SEQUENCE')
+ if startSeq==None:
+ self._seq = []
+ else:
+ self._seq = startSeq
+
+ ## A few methods to make it behave like a python sequence
+
+ def __delitem__(self, n):
+ del self._seq[n]
+ def __getitem__(self, n):
+ return self._seq[n]
+ def __setitem__(self, key, value):
+ self._seq[key] = value
+ def __setslice__(self,i,j,sequence):
+ self._seq[i:j] = sequence
+ def __delslice__(self,i,j):
+ del self._seq[i:j]
+ def __getslice__(self, i, j):
+ return self._seq[max(0, i):max(0, j)]
+ def __len__(self):
+ return len(self._seq)
+ def append(self, item):
+ return self._seq.append(item)
+
+ def hasInts(self):
+ """Return the number of items in this sequence that are numbers."""
+ return len(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<len(self.payload):
+ typeTag = bord(self.payload[idx])
+ if typeTag==self.typeTags['INTEGER']:
+ newInteger = DerInteger()
+ idx += newInteger.decode(self.payload[idx:])
+ self._seq.append(newInteger.value)
+ else:
+ itemLen,itemIdx = self._decodeLen(idx+1,self.payload)
+ self._seq.append(self.payload[idx:itemIdx+itemLen])
+ idx = itemIdx + itemLen
+ except IndexError:
+ raise ValueError("Not a valid DER SEQUENCE.")
+ return tlvLength
+
+class DerOctetString(DerObject):
+ def __init__(self, value = b('')):
+ DerObject.__init__(self, 'OCTET STRING')
+ self.payload = value
+
+ def decode(self, derEle, noLeftOvers=0):
+ p = DerObject.decode(derEle, noLeftOvers)
+ if not self.isType("OCTET STRING"):
+ raise ValueError("Not a valid OCTET STRING.")
+ return p
+
+class DerNull(DerObject):
+ def __init__(self):
+ DerObject.__init__(self, 'NULL')
+
+class DerObjectId(DerObject):
+ def __init__(self):
+ DerObject.__init__(self, 'OBJECT IDENTIFIER')
+
+ def decode(self, derEle, noLeftOvers=0):
+ p = DerObject.decode(derEle, noLeftOvers)
+ if not self.isType("OBJECT IDENTIFIER"):
+ raise ValueError("Not a valid OBJECT IDENTIFIER.")
+ return p
+
+def isInt(x):
+ test = 0
+ try:
+ test += x
+ except TypeError:
+ return 0
+ return 1
+
diff --git a/frozen_deps/Crypto/Util/number.py b/frozen_deps/Crypto/Util/number.py
new file mode 100644
index 0000000..0e1baa0
--- /dev/null
+++ b/frozen_deps/Crypto/Util/number.py
@@ -0,0 +1,1456 @@
+#
+# number.py : Number-theoretic functions
+#
+# Part of the Python Cryptography Toolkit
+#
+# Written by Andrew M. Kuchling, Barry A. Warsaw, and others
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+#
+
+__revision__ = "$Id$"
+
+from Crypto.pct_warnings import GetRandomNumber_DeprecationWarning, PowmInsecureWarning
+from warnings import warn as _warn
+import math
+import sys
+from Crypto.Util.py3compat import *
+
+bignum = int
+try:
+ from Crypto.PublicKey import _fastmath
+except ImportError:
+ # For production, we are going to let import issues due to gmp/mpir shared
+ # libraries not loading slide silently and use slowmath. If you'd rather
+ # see an exception raised if _fastmath exists but cannot be imported,
+ # uncomment the below
+ #
+ # from distutils.sysconfig import get_config_var
+ # import inspect, os
+ # _fm_path = os.path.normpath(os.path.dirname(os.path.abspath(
+ # inspect.getfile(inspect.currentframe())))
+ # +"/../../PublicKey/_fastmath"+get_config_var("SO"))
+ # if os.path.exists(_fm_path):
+ # raise ImportError("While the _fastmath module exists, importing "+
+ # "it failed. This may point to the gmp or mpir shared library "+
+ # "not being in the path. _fastmath was found at "+_fm_path)
+ _fastmath = None
+
+# You need libgmp v5 or later to get mpz_powm_sec. Warn if it's not available.
+if _fastmath is not None and not _fastmath.HAVE_DECL_MPZ_POWM_SEC:
+ _warn("Not using mpz_powm_sec. You should rebuild using libgmp >= 5 to avoid timing attack vulnerability.", PowmInsecureWarning)
+
+# New functions
+from ._number_new import *
+
+# Commented out and replaced with faster versions below
+## def long2str(n):
+## s=''
+## while n>0:
+## s=chr(n & 255)+s
+## n=n>>8
+## return s
+
+## import types
+## def str2long(s):
+## if type(s)!=types.StringType: return s # Integers will be left alone
+## return reduce(lambda x,y : x*256+ord(y), s, 0L)
+
+def size (N):
+ """size(N:long) : int
+ Returns the size of the number N in bits.
+ """
+ bits = 0
+ while N >> bits:
+ bits += 1
+ return bits
+
+def getRandomNumber(N, randfunc=None):
+ """Deprecated. Use getRandomInteger or getRandomNBitInteger instead."""
+ warnings.warn("Crypto.Util.number.getRandomNumber has confusing semantics"+
+ "and has been deprecated. Use getRandomInteger or getRandomNBitInteger instead.",
+ GetRandomNumber_DeprecationWarning)
+ return getRandomNBitInteger(N, randfunc)
+
+def getRandomInteger(N, randfunc=None):
+ """getRandomInteger(N:int, randfunc:callable):long
+ Return a random number with at most N bits.
+
+ If randfunc is omitted, then Random.new().read is used.
+
+ This function is for internal use only and may be renamed or removed in
+ the future.
+ """
+ if randfunc is None:
+ _import_Random()
+ randfunc = Random.new().read
+
+ S = randfunc(N>>3)
+ odd_bits = N % 8
+ if odd_bits != 0:
+ char = ord(randfunc(1)) >> (8-odd_bits)
+ S = bchr(char) + S
+ value = bytes_to_long(S)
+ return value
+
+def getRandomRange(a, b, randfunc=None):
+ """getRandomRange(a:int, b:int, randfunc:callable):long
+ Return a random number n so that a <= n < b.
+
+ If randfunc is omitted, then Random.new().read is used.
+
+ This function is for internal use only and may be renamed or removed in
+ the future.
+ """
+ range_ = b - a - 1
+ bits = size(range_)
+ value = getRandomInteger(bits, randfunc)
+ while value > range_:
+ value = getRandomInteger(bits, randfunc)
+ return a + value
+
+def getRandomNBitInteger(N, randfunc=None):
+ """getRandomInteger(N:int, randfunc:callable):long
+ Return a random number with exactly N-bits, i.e. a random number
+ between 2**(N-1) and (2**N)-1.
+
+ If randfunc is omitted, then Random.new().read is used.
+
+ This function is for internal use only and may be renamed or removed in
+ the future.
+ """
+ value = getRandomInteger (N-1, randfunc)
+ value |= 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
new file mode 100644
index 0000000..f8367c9
--- /dev/null
+++ b/frozen_deps/Crypto/Util/py3compat.py
@@ -0,0 +1,107 @@
+# -*- 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
new file mode 100644
index 0000000..8b5a0b7
--- /dev/null
+++ b/frozen_deps/Crypto/Util/randpool.py
@@ -0,0 +1,82 @@
+#
+# 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
new file mode 100755
index 0000000..8358023
--- /dev/null
+++ b/frozen_deps/Crypto/Util/strxor.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Crypto/Util/winrandom.py b/frozen_deps/Crypto/Util/winrandom.py
new file mode 100644
index 0000000..0242815
--- /dev/null
+++ b/frozen_deps/Crypto/Util/winrandom.py
@@ -0,0 +1,28 @@
+#
+# Util/winrandom.py : Stub for Crypto.Random.OSRNG.winrandom
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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
new file mode 100644
index 0000000..c27402e
--- /dev/null
+++ b/frozen_deps/Crypto/__init__.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain. To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Python Cryptography Toolkit
+
+A collection of cryptographic modules implementing various algorithms
+and protocols.
+
+Subpackages:
+
+Crypto.Cipher
+ Secret-key (AES, DES, ARC4) and public-key encryption (RSA PKCS#1) algorithms
+Crypto.Hash
+ Hashing algorithms (MD5, SHA, HMAC)
+Crypto.Protocol
+ Cryptographic protocols (Chaffing, all-or-nothing transform, key derivation
+ functions). This package does not contain any network protocols.
+Crypto.PublicKey
+ Public-key encryption and signature algorithms (RSA, DSA)
+Crypto.Signature
+ Public-key signature algorithms (RSA PKCS#1)
+Crypto.Util
+ Various useful modules and functions (long-to-string conversion, random number
+ generation, number theoretic functions)
+"""
+
+__all__ = ['Cipher', 'Hash', 'Protocol', 'PublicKey', 'Util', 'Signature']
+
+__version__ = '2.6.1' # See also below and setup.py
+__revision__ = "$Id$"
+
+# New software should look at this instead of at __version__ above.
+version_info = (2, 6, 1, 'final', 0) # See also above and setup.py
+
diff --git a/frozen_deps/Crypto/pct_warnings.py b/frozen_deps/Crypto/pct_warnings.py
new file mode 100644
index 0000000..9b4361e
--- /dev/null
+++ b/frozen_deps/Crypto/pct_warnings.py
@@ -0,0 +1,60 @@
+# -*- coding: ascii -*-
+#
+# pct_warnings.py : PyCrypto warnings file
+#
+# Written in 2008 by Dwayne C. Litzenberger <[email protected]>
+#
+# ===================================================================
+# 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/freezed_deps/_pysha3.cpython-38-x86_64-linux-gnu.so b/frozen_deps/_pysha3.cpython-38-x86_64-linux-gnu.so
index 0d09638..0d09638 100755
--- a/freezed_deps/_pysha3.cpython-38-x86_64-linux-gnu.so
+++ b/frozen_deps/_pysha3.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/freezed_deps/base58-2.0.1.dist-info/COPYING b/frozen_deps/base58-2.0.1.dist-info/COPYING
index 342bd62..342bd62 100644
--- a/freezed_deps/base58-2.0.1.dist-info/COPYING
+++ b/frozen_deps/base58-2.0.1.dist-info/COPYING
diff --git a/freezed_deps/base58-2.0.1.dist-info/INSTALLER b/frozen_deps/base58-2.0.1.dist-info/INSTALLER
index a1b589e..a1b589e 100644
--- a/freezed_deps/base58-2.0.1.dist-info/INSTALLER
+++ b/frozen_deps/base58-2.0.1.dist-info/INSTALLER
diff --git a/freezed_deps/base58-2.0.1.dist-info/METADATA b/frozen_deps/base58-2.0.1.dist-info/METADATA
index 22a37ad..22a37ad 100644
--- a/freezed_deps/base58-2.0.1.dist-info/METADATA
+++ b/frozen_deps/base58-2.0.1.dist-info/METADATA
diff --git a/freezed_deps/base58-2.0.1.dist-info/RECORD b/frozen_deps/base58-2.0.1.dist-info/RECORD
index d20c1c2..d20c1c2 100644
--- a/freezed_deps/base58-2.0.1.dist-info/RECORD
+++ b/frozen_deps/base58-2.0.1.dist-info/RECORD
diff --git a/freezed_deps/base58-2.0.1.dist-info/WHEEL b/frozen_deps/base58-2.0.1.dist-info/WHEEL
index 3b5c403..3b5c403 100644
--- a/freezed_deps/base58-2.0.1.dist-info/WHEEL
+++ b/frozen_deps/base58-2.0.1.dist-info/WHEEL
diff --git a/freezed_deps/base58-2.0.1.dist-info/entry_points.txt b/frozen_deps/base58-2.0.1.dist-info/entry_points.txt
index dc6d6a2..dc6d6a2 100644
--- a/freezed_deps/base58-2.0.1.dist-info/entry_points.txt
+++ b/frozen_deps/base58-2.0.1.dist-info/entry_points.txt
diff --git a/freezed_deps/base58-2.0.1.dist-info/top_level.txt b/frozen_deps/base58-2.0.1.dist-info/top_level.txt
index b4c9d71..b4c9d71 100644
--- a/freezed_deps/base58-2.0.1.dist-info/top_level.txt
+++ b/frozen_deps/base58-2.0.1.dist-info/top_level.txt
diff --git a/freezed_deps/base58/__init__.py b/frozen_deps/base58/__init__.py
index ff2fa18..ff2fa18 100644
--- a/freezed_deps/base58/__init__.py
+++ b/frozen_deps/base58/__init__.py
diff --git a/freezed_deps/base58/__main__.py b/frozen_deps/base58/__main__.py
index b76fdad..b76fdad 100644
--- a/freezed_deps/base58/__main__.py
+++ b/frozen_deps/base58/__main__.py
diff --git a/freezed_deps/base58/py.typed b/frozen_deps/base58/py.typed
index e5aff4f..e5aff4f 100644
--- a/freezed_deps/base58/py.typed
+++ b/frozen_deps/base58/py.typed
diff --git a/freezed_deps/bech32.py b/frozen_deps/bech32.py
index d450080..d450080 100644
--- a/freezed_deps/bech32.py
+++ b/frozen_deps/bech32.py
diff --git a/freezed_deps/bin/base58 b/frozen_deps/bin/base58
index 1e291f0..1e291f0 100755
--- a/freezed_deps/bin/base58
+++ b/frozen_deps/bin/base58
diff --git a/freezed_deps/bin/keytree.py b/frozen_deps/bin/keytree.py
index 41650c5..1f4bedb 100755
--- a/freezed_deps/bin/keytree.py
+++ b/frozen_deps/bin/keytree.py
@@ -30,24 +30,32 @@
# Use at your own risk.
#
# Example:
-# python ./keytree.py
+# python3 ./keytree.py
+import os
import sys
+if sys.version_info[1] < 7:
+ sys.write("Python should be >= 3.7")
+ sys.exit(1)
+basedir = os.path.dirname(os.path.abspath(__file__))
+sys.path.insert(0, basedir + "/frozen_deps")
+
+import re
import argparse
import hashlib
import hmac
import unicodedata
-import bech32
+import json
from getpass import getpass
+
+import bech32
+import mnemonic
from ecdsa import SigningKey, VerifyingKey, SECP256k1
from ecdsa.ecdsa import generator_secp256k1
from ecdsa.ellipticcurve import INFINITY
-from base58 import b58encode
+from base58 import b58encode, b58decode
from sha3 import keccak_256
-import re
-import mnemonic
-
-err = sys.stderr
+from Crypto.Cipher import AES
def sha256(data):
@@ -62,7 +70,11 @@ def ripemd160(data):
return h.digest()
-class BIP32Error(Exception):
+class KeytreeError(Exception):
+ pass
+
+
+class BIP32Error(KeytreeError):
pass
@@ -142,6 +154,8 @@ def ckd_prv(k_par, c_par, i):
return k_i, c_i
class BIP32:
+ path_error = BIP32Error("unsupported BIP32 path format")
+
def __init__(self, seed, key="Bitcoin seed"):
I = hmac.digest(b"Bitcoin seed", seed, 'sha512')
I_L, I_R = I[:32], I[32:]
@@ -157,7 +171,7 @@ class BIP32:
c = self.c
for r in tokens[1:]:
if not rformat.match(r):
- raise BIP32Error("unsupported path format")
+ raise self.path_error
if r[-1] == "'":
i = iH(int(r[:-1]))
else:
@@ -169,7 +183,7 @@ class BIP32:
c = self.c
for r in tokens[1:]:
if not rformat.match(r):
- raise BIP32Error("unsupported path format")
+ raise self.path_error
if r[-1] == "'":
i = iH(int(r[:-1]))
else:
@@ -177,7 +191,7 @@ class BIP32:
K, c = ckd_pub(K, c, i)
return VerifyingKey.from_public_point(K, curve=SECP256k1)
else:
- raise BIP32Error("unsupported path format")
+ raise self.path_error
def get_eth_addr(pk):
pub_key = pk.to_string()
@@ -196,43 +210,81 @@ def get_btc_addr(pk):
h += checksum
return b58encode(h).decode("utf-8")
+def load_from_keystore(filename):
+ try:
+ with open(filename, "r") as f:
+ try:
+ parsed = json.load(f)
+ ciphertext = b58decode(parsed['keys'][0]['key'])[:-4]
+ iv = b58decode(parsed['keys'][0]['iv'])[:-4]
+ salt = b58decode(parsed['salt'])[:-4]
+ tag = b58decode(parsed['pass_hash'])[:-4]
+ passwd = getpass('Enter the password to unlock keystore: ').encode('utf-8')
+ key = hashlib.pbkdf2_hmac(
+ 'sha256',
+ sha256(passwd + salt), salt, 200000)
+ obj = 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')
+ except KeytreeError as e:
+ raise e
+ 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('--show-private', action='store_true', default=False, help='also show private keys')
+ parser.add_argument('--from-avax-keystore', type=str, default=None, help='load mnemonic from an AVAX keystore file')
+ 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')
+ parser.add_argument('--account-path', default="44'/9000'/0'/0", help="path prefix for key deriving (e.g. \"0/1'/2\")")
parser.add_argument('--gen-mnemonic', action='store_true', default=False, help='generate a mnemonic (instead of taking an input)')
parser.add_argument('--lang', type=str, default="english", help='language for mnemonic words')
parser.add_argument('--start-idx', type=int, default=0, help='the start index for keys')
parser.add_argument('--end-idx', type=int, default=1, help='the end index for keys (exclusive)')
+ parser.add_argument('--hrp', type=str, default="avax", help='HRP (Human Readable Prefix, defined by Bech32)')
args = parser.parse_args()
- if args.gen_mnemonic:
- mgen = mnemonic.Mnemonic(args.lang)
- words = mgen.generate(256)
- print("KEEP THIS PRIVATE: {}".format(words))
- else:
- words = getpass('Enter the mnemonic: ')
- if not args.custom_words:
- mchecker = mnemonic.Mnemonic(args.lang)
- if not mchecker.check(words):
- err.write("Invalid mnemonic\n")
- sys.exit(1)
-
- seed = hashlib.pbkdf2_hmac('sha512', unicodedata.normalize('NFKD', words).encode("utf-8"), b"mnemonic", 2048)
- gen = BIP32(seed)
- if args.start_idx < 0 or args.end_idx < 0:
+ try:
+ try:
+ if args.gen_mnemonic:
+ mgen = mnemonic.Mnemonic(args.lang)
+ words = mgen.generate(256)
+ else:
+ if args.from_avax_keystore:
+ words = load_from_keystore(args.from_avax_keystore)
+ else:
+ words = getpass('Enter the mnemonic: ').strip()
+ if not args.custom_words:
+ mchecker = mnemonic.Mnemonic(args.lang)
+ if not mchecker.check(words):
+ raise KeytreeError("invalid mnemonic")
+ except FileNotFoundError:
+ raise KeytreeError("invalid language")
+ if args.show_private or args.gen_mnemonic:
+ print("KEEP THIS PRIVATE: {}".format(words))
+ seed = hashlib.pbkdf2_hmac('sha512', unicodedata.normalize('NFKD', words).encode("utf-8"), b"mnemonic", 2048)
+ gen = BIP32(seed)
+ if args.start_idx < 0 or args.end_idx < 0:
+ raise KeytreeError("invalid start/end index")
+ for i in range(args.start_idx, args.end_idx):
+ path = "m/{}/{}".format(args.account_path, i)
+ priv = gen.derive(path)
+ pub = priv.get_verifying_key()
+ cpub = pub.to_string(encoding="compressed")
+ if args.show_private:
+ print("{}.priv(raw) {}".format(i, priv.to_string().hex()))
+ print("{}.priv(BTC) {}".format(i, get_privkey_btc(priv)))
+ 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)))
+ except KeytreeError as e:
+ sys.stderr.write("error: {}\n".format(str(e)))
sys.exit(1)
- for i in range(args.start_idx, args.end_idx):
- path = "m/{}/{}".format(args.account_path, i)
- priv = gen.derive(path)
- pub = priv.get_verifying_key()
- cpub = pub.to_string(encoding="compressed")
- if args.show_private:
- print("{}.priv(raw) {}".format(i, priv.to_string().hex()))
- print("{}.priv(BTC) {}".format(i, get_privkey_btc(priv)))
- print("{}.addr(AVAX) X-{}".format(i, bech32.bech32_encode('avax', 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)))
diff --git a/freezed_deps/ecdsa-0.15.dist-info/INSTALLER b/frozen_deps/ecdsa-0.16.1.dist-info/INSTALLER
index a1b589e..a1b589e 100644
--- a/freezed_deps/ecdsa-0.15.dist-info/INSTALLER
+++ b/frozen_deps/ecdsa-0.16.1.dist-info/INSTALLER
diff --git a/freezed_deps/ecdsa-0.15.dist-info/LICENSE b/frozen_deps/ecdsa-0.16.1.dist-info/LICENSE
index 474479a..474479a 100644
--- a/freezed_deps/ecdsa-0.15.dist-info/LICENSE
+++ b/frozen_deps/ecdsa-0.16.1.dist-info/LICENSE
diff --git a/freezed_deps/ecdsa-0.15.dist-info/METADATA b/frozen_deps/ecdsa-0.16.1.dist-info/METADATA
index 6e8a2ef..983a64a 100644
--- a/freezed_deps/ecdsa-0.15.dist-info/METADATA
+++ b/frozen_deps/ecdsa-0.16.1.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: ecdsa
-Version: 0.15
+Version: 0.16.1
Summary: ECDSA cryptographic signature library (pure python)
Home-page: http://github.com/warner/python-ecdsa
Author: Brian Warner
@@ -32,6 +32,7 @@ Requires-Dist: gmpy2 ; extra == 'gmpy2'
[![Coverage Status](https://coveralls.io/repos/warner/python-ecdsa/badge.svg)](https://coveralls.io/r/warner/python-ecdsa)
[![condition coverage](https://img.shields.io/badge/condition%20coverage-81%25-yellow)](https://travis-ci.org/warner/python-ecdsa/jobs/626479178#L776)
[![Latest Version](https://img.shields.io/pypi/v/ecdsa.svg?style=flat)](https://pypi.python.org/pypi/ecdsa/)
+![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg?style=flat)
This is an easy-to-use implementation of ECDSA cryptography (Elliptic Curve
diff --git a/frozen_deps/ecdsa-0.16.1.dist-info/RECORD b/frozen_deps/ecdsa-0.16.1.dist-info/RECORD
new file mode 100644
index 0000000..4382e84
--- /dev/null
+++ b/frozen_deps/ecdsa-0.16.1.dist-info/RECORD
@@ -0,0 +1,52 @@
+ecdsa-0.16.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+ecdsa-0.16.1.dist-info/LICENSE,sha256=PsqYRXc9LluMydjBGdNF8ApIBuS9Zg1KPWzfnA6di7I,1147
+ecdsa-0.16.1.dist-info/METADATA,sha256=cwaWRd_w5Q-Y4wENZxW14D0cpK13fE3AP56XLw-tF50,24993
+ecdsa-0.16.1.dist-info/RECORD,,
+ecdsa-0.16.1.dist-info/WHEEL,sha256=8zNYZbwQSXoB9IfXOjPfeNwvAsALAjffgk27FqvCWbo,110
+ecdsa-0.16.1.dist-info/top_level.txt,sha256=7ovPHfAPyTou19f8gOSbHm6B9dGjTibWolcCB7Zjovs,6
+ecdsa/__init__.py,sha256=u-_1cu1I_GIwJ0DRYY7LNvkB4pvodv1kHztsAsCX3eA,1325
+ecdsa/__pycache__/__init__.cpython-38.pyc,,
+ecdsa/__pycache__/_compat.cpython-38.pyc,,
+ecdsa/__pycache__/_rwlock.cpython-38.pyc,,
+ecdsa/__pycache__/_version.cpython-38.pyc,,
+ecdsa/__pycache__/curves.cpython-38.pyc,,
+ecdsa/__pycache__/der.cpython-38.pyc,,
+ecdsa/__pycache__/ecdh.cpython-38.pyc,,
+ecdsa/__pycache__/ecdsa.cpython-38.pyc,,
+ecdsa/__pycache__/ellipticcurve.cpython-38.pyc,,
+ecdsa/__pycache__/keys.cpython-38.pyc,,
+ecdsa/__pycache__/numbertheory.cpython-38.pyc,,
+ecdsa/__pycache__/rfc6979.cpython-38.pyc,,
+ecdsa/__pycache__/test_der.cpython-38.pyc,,
+ecdsa/__pycache__/test_ecdh.cpython-38.pyc,,
+ecdsa/__pycache__/test_ecdsa.cpython-38.pyc,,
+ecdsa/__pycache__/test_ellipticcurve.cpython-38.pyc,,
+ecdsa/__pycache__/test_jacobi.cpython-38.pyc,,
+ecdsa/__pycache__/test_keys.cpython-38.pyc,,
+ecdsa/__pycache__/test_malformed_sigs.cpython-38.pyc,,
+ecdsa/__pycache__/test_numbertheory.cpython-38.pyc,,
+ecdsa/__pycache__/test_pyecdsa.cpython-38.pyc,,
+ecdsa/__pycache__/test_rw_lock.cpython-38.pyc,,
+ecdsa/__pycache__/util.cpython-38.pyc,,
+ecdsa/_compat.py,sha256=j_BnKmVOkjucCQbCuLaFsxHSiEUqj_co5sSAPLLWSsk,1659
+ecdsa/_rwlock.py,sha256=CAwHp2V65ksI8B1UqY7EccK9LaUToiv6pDLVzm44eag,2849
+ecdsa/_version.py,sha256=Qncu2Mr06Q_KO_8jvc8zi5RZ4XgaxiWI17VDRqKMrfw,498
+ecdsa/curves.py,sha256=rlAVrS6hwZ6sNnTswdRMJBlC-mryxXYo7zZIEQjYOPE,3735
+ecdsa/der.py,sha256=l528iLGUwqcNokzDkk-2qO3-6_nzL908OfB0GhUhbZ8,14092
+ecdsa/ecdh.py,sha256=K7T-XoiP-Y_bsGcnulcXFsr_7P5LCK2O4wbM-WkopDQ,10631
+ecdsa/ecdsa.py,sha256=5xD8X3qD9By3aZdxVoPOyx_FFDRNVrRUhxtw5j70g0g,21232
+ecdsa/ellipticcurve.py,sha256=l11lgxjqTe2ocyOed9M19FKZR7kNAB3dUfUvjJLAcsk,27437
+ecdsa/keys.py,sha256=1-YQm967hqvOsnF9o7Tw0eHyo21YHkZYzcKOckebfGI,59502
+ecdsa/numbertheory.py,sha256=yLx-P5-esRFT63gDSvKBfoiwOfSyVfjXyFcGF9_SFbM,16764
+ecdsa/rfc6979.py,sha256=x6dCO2l3QlPLHE-w3c456rqthhSBP03dCnTfSweBgBU,2725
+ecdsa/test_der.py,sha256=jifDHof2nEDs2phCEYMOJ-h6oCEuqS-pz8x65rrmm8U,12653
+ecdsa/test_ecdh.py,sha256=PxwESmg9_ckt1N9yXA88yN_0bERwkXDojSP9Oppfub8,13510
+ecdsa/test_ecdsa.py,sha256=csODW8xYt_LhjEvHiWteehEU2UxBLodvkQk21aMNCzs,19696
+ecdsa/test_ellipticcurve.py,sha256=todhFIkd2pyRCqfa7S92o69uOM7DfFp1tkD7LFa2Edw,6112
+ecdsa/test_jacobi.py,sha256=Ie3NocTE1i69oHxfnmnmvwqXJIlQpzVAFAG1rJq3YFU,12178
+ecdsa/test_keys.py,sha256=lT05J0Cu7C0HLu8cicBKBGRzmkuQBIECHQEzBmXYDzQ,14157
+ecdsa/test_malformed_sigs.py,sha256=Sr4RdBG4WWpOdJBME8f4v82uvbqJ_2cKyccL9crsi58,10300
+ecdsa/test_numbertheory.py,sha256=VqEme1ND9gbh2aMKsXXnZXcI4fpSvfkglM1O8DQpxR8,8815
+ecdsa/test_pyecdsa.py,sha256=61c5ASQ9pHKIYg73JWiIZdlCz4wqmkvCqmPJKVBNzn4,73402
+ecdsa/test_rw_lock.py,sha256=pkSoLder1YdsyRPSam8topCvdMytQjV3q-sCqrjx4nE,6959
+ecdsa/util.py,sha256=lHkBmYk4wuUETSUj4V23ssCjL385zCDxFr24jptXxI8,14557
diff --git a/freezed_deps/ecdsa-0.15.dist-info/WHEEL b/frozen_deps/ecdsa-0.16.1.dist-info/WHEEL
index 8b701e9..8b701e9 100644
--- a/freezed_deps/ecdsa-0.15.dist-info/WHEEL
+++ b/frozen_deps/ecdsa-0.16.1.dist-info/WHEEL
diff --git a/freezed_deps/ecdsa-0.15.dist-info/top_level.txt b/frozen_deps/ecdsa-0.16.1.dist-info/top_level.txt
index aa5efdb..aa5efdb 100644
--- a/freezed_deps/ecdsa-0.15.dist-info/top_level.txt
+++ b/frozen_deps/ecdsa-0.16.1.dist-info/top_level.txt
diff --git a/frozen_deps/ecdsa/__init__.py b/frozen_deps/ecdsa/__init__.py
new file mode 100644
index 0000000..4ae0a11
--- /dev/null
+++ b/frozen_deps/ecdsa/__init__.py
@@ -0,0 +1,76 @@
+from .keys import (
+ SigningKey,
+ VerifyingKey,
+ BadSignatureError,
+ BadDigestError,
+ MalformedPointError,
+)
+from .curves import (
+ NIST192p,
+ NIST224p,
+ NIST256p,
+ NIST384p,
+ NIST521p,
+ SECP256k1,
+ BRAINPOOLP160r1,
+ BRAINPOOLP192r1,
+ BRAINPOOLP224r1,
+ BRAINPOOLP256r1,
+ BRAINPOOLP320r1,
+ BRAINPOOLP384r1,
+ BRAINPOOLP512r1,
+)
+from .ecdh import (
+ ECDH,
+ NoKeyError,
+ NoCurveError,
+ InvalidCurveError,
+ InvalidSharedSecretError,
+)
+from .der import UnexpectedDER
+
+# This code comes from http://github.com/warner/python-ecdsa
+from ._version import get_versions
+
+__version__ = get_versions()["version"]
+del get_versions
+
+__all__ = [
+ "curves",
+ "der",
+ "ecdsa",
+ "ellipticcurve",
+ "keys",
+ "numbertheory",
+ "test_pyecdsa",
+ "util",
+ "six",
+]
+
+_hush_pyflakes = [
+ SigningKey,
+ VerifyingKey,
+ BadSignatureError,
+ BadDigestError,
+ MalformedPointError,
+ UnexpectedDER,
+ InvalidCurveError,
+ NoKeyError,
+ InvalidSharedSecretError,
+ ECDH,
+ NoCurveError,
+ NIST192p,
+ NIST224p,
+ NIST256p,
+ NIST384p,
+ NIST521p,
+ SECP256k1,
+ BRAINPOOLP160r1,
+ BRAINPOOLP192r1,
+ BRAINPOOLP224r1,
+ BRAINPOOLP256r1,
+ BRAINPOOLP320r1,
+ BRAINPOOLP384r1,
+ BRAINPOOLP512r1,
+]
+del _hush_pyflakes
diff --git a/freezed_deps/ecdsa/_compat.py b/frozen_deps/ecdsa/_compat.py
index 965d8c4..720360b 100644
--- a/freezed_deps/ecdsa/_compat.py
+++ b/frozen_deps/ecdsa/_compat.py
@@ -2,6 +2,7 @@
Common functions for providing cross-python version compatibility.
"""
import sys
+import re
from six import integer_types
@@ -14,6 +15,7 @@ def str_idx_as_int(string, index):
if sys.version_info < (3, 0):
+
def normalise_bytes(buffer_object):
"""Cast the input into array of bytes."""
# flake8 runs on py3 where `buffer` indeed doesn't exist...
@@ -22,6 +24,19 @@ if sys.version_info < (3, 0):
def hmac_compat(ret):
return ret
+ if sys.version_info < (2, 7) or sys.version_info < (2, 7, 4):
+
+ def remove_whitespace(text):
+ """Removes all whitespace from passed in string"""
+ return re.sub(r"\s+", "", text)
+
+ else:
+
+ def remove_whitespace(text):
+ """Removes all whitespace from passed in string"""
+ return re.sub(r"\s+", "", text, flags=re.UNICODE)
+
+
else:
if sys.version_info < (3, 4):
# on python 3.3 hmac.hmac.update() accepts only bytes, on newer
@@ -30,10 +45,16 @@ else:
if not isinstance(data, bytes):
return bytes(data)
return data
+
else:
+
def hmac_compat(data):
return data
def normalise_bytes(buffer_object):
"""Cast the input into array of bytes."""
- return memoryview(buffer_object).cast('B')
+ return memoryview(buffer_object).cast("B")
+
+ def remove_whitespace(text):
+ """Removes all whitespace from passed in string"""
+ return re.sub(r"\s+", "", text, flags=re.UNICODE)
diff --git a/freezed_deps/ecdsa/_rwlock.py b/frozen_deps/ecdsa/_rwlock.py
index e4ef78d..010e498 100644
--- a/freezed_deps/ecdsa/_rwlock.py
+++ b/frozen_deps/ecdsa/_rwlock.py
@@ -66,6 +66,7 @@ class RWLock:
class _LightSwitch:
"""An auxiliary "light switch"-like object. The first thread turns on the
"switch", the last one turns it off (see [1, sec. 4.2.2] for details)."""
+
def __init__(self):
self.__counter = 0
self.__mutex = threading.Lock()
diff --git a/freezed_deps/ecdsa/_version.py b/frozen_deps/ecdsa/_version.py
index 038d62a..9a3e5fa 100644
--- a/freezed_deps/ecdsa/_version.py
+++ b/frozen_deps/ecdsa/_version.py
@@ -8,11 +8,11 @@ import json
version_json = '''
{
- "date": "2020-01-02T17:05:04+0100",
+ "date": "2020-11-12T20:12:49+0100",
"dirty": false,
"error": null,
- "full-revisionid": "93b04ba3ddb7c2716e07761393a179c061718c34",
- "version": "0.15"
+ "full-revisionid": "9d5a727c766773b8367f6dd0a49bbda21c18dbe7",
+ "version": "0.16.1"
}
''' # END VERSION_JSON
diff --git a/frozen_deps/ecdsa/curves.py b/frozen_deps/ecdsa/curves.py
new file mode 100644
index 0000000..9a10380
--- /dev/null
+++ b/frozen_deps/ecdsa/curves.py
@@ -0,0 +1,194 @@
+from __future__ import division
+
+from . import der, ecdsa
+from .util import orderlen
+
+
+# orderlen was defined in this module previously, so keep it in __all__,
+# will need to mark it as deprecated later
+__all__ = [
+ "UnknownCurveError",
+ "orderlen",
+ "Curve",
+ "NIST192p",
+ "NIST224p",
+ "NIST256p",
+ "NIST384p",
+ "NIST521p",
+ "curves",
+ "find_curve",
+ "SECP256k1",
+ "BRAINPOOLP160r1",
+ "BRAINPOOLP192r1",
+ "BRAINPOOLP224r1",
+ "BRAINPOOLP256r1",
+ "BRAINPOOLP320r1",
+ "BRAINPOOLP384r1",
+ "BRAINPOOLP512r1",
+]
+
+
+class UnknownCurveError(Exception):
+ pass
+
+
+class Curve:
+ def __init__(self, name, curve, generator, oid, openssl_name=None):
+ self.name = name
+ self.openssl_name = openssl_name # maybe None
+ self.curve = curve
+ self.generator = generator
+ self.order = generator.order()
+ self.baselen = orderlen(self.order)
+ self.verifying_key_length = 2 * self.baselen
+ self.signature_length = 2 * self.baselen
+ self.oid = oid
+ self.encoded_oid = der.encode_oid(*oid)
+
+ def __repr__(self):
+ return self.name
+
+
+# the NIST curves
+NIST192p = Curve(
+ "NIST192p",
+ ecdsa.curve_192,
+ ecdsa.generator_192,
+ (1, 2, 840, 10045, 3, 1, 1),
+ "prime192v1",
+)
+
+
+NIST224p = Curve(
+ "NIST224p",
+ ecdsa.curve_224,
+ ecdsa.generator_224,
+ (1, 3, 132, 0, 33),
+ "secp224r1",
+)
+
+
+NIST256p = Curve(
+ "NIST256p",
+ ecdsa.curve_256,
+ ecdsa.generator_256,
+ (1, 2, 840, 10045, 3, 1, 7),
+ "prime256v1",
+)
+
+
+NIST384p = Curve(
+ "NIST384p",
+ ecdsa.curve_384,
+ ecdsa.generator_384,
+ (1, 3, 132, 0, 34),
+ "secp384r1",
+)
+
+
+NIST521p = Curve(
+ "NIST521p",
+ ecdsa.curve_521,
+ ecdsa.generator_521,
+ (1, 3, 132, 0, 35),
+ "secp521r1",
+)
+
+
+SECP256k1 = Curve(
+ "SECP256k1",
+ ecdsa.curve_secp256k1,
+ ecdsa.generator_secp256k1,
+ (1, 3, 132, 0, 10),
+ "secp256k1",
+)
+
+
+BRAINPOOLP160r1 = Curve(
+ "BRAINPOOLP160r1",
+ ecdsa.curve_brainpoolp160r1,
+ ecdsa.generator_brainpoolp160r1,
+ (1, 3, 36, 3, 3, 2, 8, 1, 1, 1),
+ "brainpoolP160r1",
+)
+
+
+BRAINPOOLP192r1 = Curve(
+ "BRAINPOOLP192r1",
+ ecdsa.curve_brainpoolp192r1,
+ ecdsa.generator_brainpoolp192r1,
+ (1, 3, 36, 3, 3, 2, 8, 1, 1, 3),
+ "brainpoolP192r1",
+)
+
+
+BRAINPOOLP224r1 = Curve(
+ "BRAINPOOLP224r1",
+ ecdsa.curve_brainpoolp224r1,
+ ecdsa.generator_brainpoolp224r1,
+ (1, 3, 36, 3, 3, 2, 8, 1, 1, 5),
+ "brainpoolP224r1",
+)
+
+
+BRAINPOOLP256r1 = Curve(
+ "BRAINPOOLP256r1",
+ ecdsa.curve_brainpoolp256r1,
+ ecdsa.generator_brainpoolp256r1,
+ (1, 3, 36, 3, 3, 2, 8, 1, 1, 7),
+ "brainpoolP256r1",
+)
+
+
+BRAINPOOLP320r1 = Curve(
+ "BRAINPOOLP320r1",
+ ecdsa.curve_brainpoolp320r1,
+ ecdsa.generator_brainpoolp320r1,
+ (1, 3, 36, 3, 3, 2, 8, 1, 1, 9),
+ "brainpoolP320r1",
+)
+
+
+BRAINPOOLP384r1 = Curve(
+ "BRAINPOOLP384r1",
+ ecdsa.curve_brainpoolp384r1,
+ ecdsa.generator_brainpoolp384r1,
+ (1, 3, 36, 3, 3, 2, 8, 1, 1, 11),
+ "brainpoolP384r1",
+)
+
+
+BRAINPOOLP512r1 = Curve(
+ "BRAINPOOLP512r1",
+ ecdsa.curve_brainpoolp512r1,
+ ecdsa.generator_brainpoolp512r1,
+ (1, 3, 36, 3, 3, 2, 8, 1, 1, 13),
+ "brainpoolP512r1",
+)
+
+
+curves = [
+ NIST192p,
+ NIST224p,
+ NIST256p,
+ NIST384p,
+ NIST521p,
+ SECP256k1,
+ BRAINPOOLP160r1,
+ BRAINPOOLP192r1,
+ BRAINPOOLP224r1,
+ BRAINPOOLP256r1,
+ BRAINPOOLP320r1,
+ BRAINPOOLP384r1,
+ BRAINPOOLP512r1,
+]
+
+
+def find_curve(oid_curve):
+ for c in curves:
+ if c.oid == oid_curve:
+ return c
+ raise UnknownCurveError(
+ "I don't know about the curve with oid %s."
+ "I only know about these: %s" % (oid_curve, [c.name for c in curves])
+ )
diff --git a/freezed_deps/ecdsa/der.py b/frozen_deps/ecdsa/der.py
index ad75b37..8c1de9b 100644
--- a/freezed_deps/ecdsa/der.py
+++ b/frozen_deps/ecdsa/der.py
@@ -13,7 +13,7 @@ class UnexpectedDER(Exception):
def encode_constructed(tag, value):
- return int2byte(0xa0+tag) + encode_length(len(value)) + value
+ return int2byte(0xA0 + tag) + encode_length(len(value)) + value
def encode_integer(r):
@@ -23,13 +23,13 @@ def encode_integer(r):
h = b("0") + h
s = binascii.unhexlify(h)
num = str_idx_as_int(s, 0)
- if num <= 0x7f:
+ if num <= 0x7F:
return b("\x02") + encode_length(len(s)) + s
else:
# DER integers are two's complement, so if the first byte is
# 0x80-0xff then we need an extra 0x00 byte to prevent it from
# looking negative.
- return b("\x02") + encode_length(len(s)+1) + b("\x00") + s
+ return b("\x02") + encode_length(len(s) + 1) + b("\x00") + s
# sentry object to check if an argument was specified (used to detect
@@ -73,12 +73,13 @@ def encode_bitstring(s, unused=_sentry):
:return: `s` encoded using DER
:rtype: bytes
"""
- encoded_unused = b''
+ encoded_unused = b""
len_extra = 0
if unused is _sentry:
- warnings.warn("Legacy call convention used, unused= needs to be "
- "specified",
- DeprecationWarning)
+ warnings.warn(
+ "Legacy call convention used, unused= needs to be specified",
+ DeprecationWarning,
+ )
elif unused is not None:
if not 0 <= unused <= 7:
raise ValueError("unused must be integer between 0 and 7")
@@ -99,36 +100,45 @@ def encode_octet_string(s):
def encode_oid(first, second, *pieces):
assert 0 <= first < 2 and 0 <= second <= 39 or first == 2 and 0 <= second
- body = b''.join(chain([encode_number(40*first+second)],
- (encode_number(p) for p in pieces)))
- return b'\x06' + encode_length(len(body)) + body
+ body = b"".join(
+ chain(
+ [encode_number(40 * first + second)],
+ (encode_number(p) for p in pieces),
+ )
+ )
+ return b"\x06" + encode_length(len(body)) + body
def encode_sequence(*encoded_pieces):
total_len = sum([len(p) for p in encoded_pieces])
- return b('\x30') + encode_length(total_len) + b('').join(encoded_pieces)
+ return b("\x30") + encode_length(total_len) + b("").join(encoded_pieces)
def encode_number(n):
b128_digits = []
while n:
- b128_digits.insert(0, (n & 0x7f) | 0x80)
+ b128_digits.insert(0, (n & 0x7F) | 0x80)
n = n >> 7
if not b128_digits:
b128_digits.append(0)
- b128_digits[-1] &= 0x7f
- return b('').join([int2byte(d) for d in b128_digits])
+ b128_digits[-1] &= 0x7F
+ return b("").join([int2byte(d) for d in b128_digits])
+
+
+def is_sequence(string):
+ return string and string[:1] == b"\x30"
def remove_constructed(string):
s0 = str_idx_as_int(string, 0)
- if (s0 & 0xe0) != 0xa0:
- raise UnexpectedDER("wanted type 'constructed tag' (0xa0-0xbf), "
- "got 0x%02x" % s0)
- tag = s0 & 0x1f
+ if (s0 & 0xE0) != 0xA0:
+ raise UnexpectedDER(
+ "wanted type 'constructed tag' (0xa0-0xbf), got 0x%02x" % s0
+ )
+ tag = s0 & 0x1F
length, llen = read_length(string[1:])
- body = string[1+llen:1+llen+length]
- rest = string[1+llen+length:]
+ body = string[1 + llen : 1 + llen + length]
+ rest = string[1 + llen + length :]
return tag, body, rest
@@ -141,8 +151,8 @@ def remove_sequence(string):
length, lengthlength = read_length(string[1:])
if length > len(string) - 1 - lengthlength:
raise UnexpectedDER("Length longer than the provided buffer")
- endseq = 1+lengthlength+length
- return string[1+lengthlength:endseq], string[endseq:]
+ endseq = 1 + lengthlength + length
+ return string[1 + lengthlength : endseq], string[endseq:]
def remove_octet_string(string):
@@ -150,26 +160,28 @@ def remove_octet_string(string):
n = str_idx_as_int(string, 0)
raise UnexpectedDER("wanted type 'octetstring' (0x04), got 0x%02x" % n)
length, llen = read_length(string[1:])
- body = string[1+llen:1+llen+length]
- rest = string[1+llen+length:]
+ body = string[1 + llen : 1 + llen + length]
+ rest = string[1 + llen + length :]
return body, rest
def remove_object(string):
if not string:
raise UnexpectedDER(
- "Empty string does not encode an object identifier")
+ "Empty string does not encode an object identifier"
+ )
if string[:1] != b"\x06":
n = str_idx_as_int(string, 0)
raise UnexpectedDER("wanted type 'object' (0x06), got 0x%02x" % n)
length, lengthlength = read_length(string[1:])
- body = string[1+lengthlength:1+lengthlength+length]
- rest = string[1+lengthlength+length:]
+ body = string[1 + lengthlength : 1 + lengthlength + length]
+ rest = string[1 + lengthlength + length :]
if not body:
raise UnexpectedDER("Empty object identifier")
if len(body) != length:
raise UnexpectedDER(
- "Length of object identifier longer than the provided buffer")
+ "Length of object identifier longer than the provided buffer"
+ )
numbers = []
while body:
n, ll = read_number(body)
@@ -188,8 +200,9 @@ def remove_object(string):
def remove_integer(string):
if not string:
- raise UnexpectedDER("Empty string is an invalid encoding of an "
- "integer")
+ raise UnexpectedDER(
+ "Empty string is an invalid encoding of an integer"
+ )
if string[:1] != b"\x02":
n = str_idx_as_int(string, 0)
raise UnexpectedDER("wanted type 'integer' (0x02), got 0x%02x" % n)
@@ -198,8 +211,8 @@ def remove_integer(string):
raise UnexpectedDER("Length longer than provided buffer")
if length == 0:
raise UnexpectedDER("0-byte long encoding of integer")
- numberbytes = string[1+llen:1+llen+length]
- rest = string[1+llen+length:]
+ numberbytes = string[1 + llen : 1 + llen + length]
+ rest = string[1 + llen + length :]
msb = str_idx_as_int(numberbytes, 0)
if not msb < 0x80:
raise UnexpectedDER("Negative integers are not supported")
@@ -209,8 +222,10 @@ def remove_integer(string):
# considered a negative number otherwise
smsb = str_idx_as_int(numberbytes, 1)
if smsb < 0x80:
- raise UnexpectedDER("Invalid encoding of integer, unnecessary "
- "zero padding bytes")
+ raise UnexpectedDER(
+ "Invalid encoding of integer, unnecessary "
+ "zero padding bytes"
+ )
return int(binascii.hexlify(numberbytes), 16), rest
@@ -226,7 +241,7 @@ def read_number(string):
raise UnexpectedDER("ran out of length bytes")
number = number << 7
d = str_idx_as_int(string, llen)
- number += (d & 0x7f)
+ number += d & 0x7F
llen += 1
if not d & 0x80:
break
@@ -251,19 +266,19 @@ def read_length(string):
num = str_idx_as_int(string, 0)
if not (num & 0x80):
# short form
- return (num & 0x7f), 1
+ return (num & 0x7F), 1
# else long-form: b0&0x7f is number of additional base256 length bytes,
# big-endian
- llen = num & 0x7f
+ llen = num & 0x7F
if not llen:
raise UnexpectedDER("Invalid length encoding, length of length is 0")
- if llen > len(string)-1:
+ if llen > len(string) - 1:
raise UnexpectedDER("Length of length longer than provided buffer")
# verify that the encoding is minimal possible (DER requirement)
msb = str_idx_as_int(string, 1)
if not msb or llen == 1 and msb < 0x80:
raise UnexpectedDER("Not minimal encoding of length")
- return int(binascii.hexlify(string[1:1+llen]), 16), 1+llen
+ return int(binascii.hexlify(string[1 : 1 + llen]), 16), 1 + llen
def remove_bitstring(string, expect_unused=_sentry):
@@ -308,17 +323,19 @@ def remove_bitstring(string, expect_unused=_sentry):
if not string:
raise UnexpectedDER("Empty string does not encode a bitstring")
if expect_unused is _sentry:
- warnings.warn("Legacy call convention used, expect_unused= needs to be"
- " specified",
- DeprecationWarning)
+ warnings.warn(
+ "Legacy call convention used, expect_unused= needs to be"
+ " specified",
+ DeprecationWarning,
+ )
num = str_idx_as_int(string, 0)
if string[:1] != b"\x03":
raise UnexpectedDER("wanted bitstring (0x03), got 0x%02x" % num)
length, llen = read_length(string[1:])
if not length:
raise UnexpectedDER("Invalid length of bit string, can't be 0")
- body = string[1+llen:1+llen+length]
- rest = string[1+llen+length:]
+ body = string[1 + llen : 1 + llen + length]
+ rest = string[1 + llen + length :]
if expect_unused is not _sentry:
unused = str_idx_as_int(body, 0)
if not 0 <= unused <= 7:
@@ -337,6 +354,7 @@ def remove_bitstring(string, expect_unused=_sentry):
body = (body, unused)
return body, rest
+
# SEQUENCE([1, STRING(secexp), cont[0], OBJECT(curvename), cont[1], BINTSTRING)
@@ -348,8 +366,8 @@ def remove_bitstring(string, expect_unused=_sentry):
# ansi-X9-62 signatures(4) }
# ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
# id-ecSigType 1 }
-## so 1,2,840,10045,4,1
-## so 0x42, .. ..
+# so 1,2,840,10045,4,1
+# so 0x42, .. ..
# Ecdsa-Sig-Value ::= SEQUENCE {
# r INTEGER,
@@ -366,19 +384,26 @@ def remove_bitstring(string, expect_unused=_sentry):
# secp384r1 OBJECT IDENTIFIER ::= {
# iso(1) identified-organization(3) certicom(132) curve(0) 34 }
+
def unpem(pem):
if isinstance(pem, text_type):
pem = pem.encode()
- d = b("").join([l.strip() for l in pem.split(b("\n"))
- if l and not l.startswith(b("-----"))])
+ d = b("").join(
+ [
+ l.strip()
+ for l in pem.split(b("\n"))
+ if l and not l.startswith(b("-----"))
+ ]
+ )
return base64.b64decode(d)
def topem(der, name):
b64 = base64.b64encode(der)
lines = [("-----BEGIN %s-----\n" % name).encode()]
- lines.extend([b64[start:start+64]+b("\n")
- for start in range(0, len(b64), 64)])
+ lines.extend(
+ [b64[start : start + 64] + b("\n") for start in range(0, len(b64), 64)]
+ )
lines.append(("-----END %s-----\n" % name).encode())
return b("").join(lines)
diff --git a/freezed_deps/ecdsa/ecdh.py b/frozen_deps/ecdsa/ecdh.py
index 88848f5..9173279 100644
--- a/freezed_deps/ecdsa/ecdh.py
+++ b/frozen_deps/ecdsa/ecdh.py
@@ -7,8 +7,13 @@ from .ellipticcurve import INFINITY
from .keys import SigningKey, VerifyingKey
-__all__ = ["ECDH", "NoKeyError", "NoCurveError", "InvalidCurveError",
- "InvalidSharedSecretError"]
+__all__ = [
+ "ECDH",
+ "NoKeyError",
+ "NoCurveError",
+ "InvalidCurveError",
+ "InvalidSharedSecretError",
+]
class NoKeyError(Exception):
@@ -24,7 +29,9 @@ class NoCurveError(Exception):
class InvalidCurveError(Exception):
- """ECDH. Raised in case the public and private keys use different curves."""
+ """
+ ECDH. Raised in case the public and private keys use different curves.
+ """
pass
@@ -41,7 +48,7 @@ class ECDH(object):
Allows two parties, each having an elliptic-curve public-private key
pair, to establish a shared secret over an insecure channel
- """""
+ """
def __init__(self, curve=None, private_key=None, public_key=None):
"""
@@ -58,7 +65,7 @@ class ECDH(object):
:type private_key: SigningKey
:param public_key: `their` public key for ECDH
:type public_key: VerifyingKey
- """
+ """
self.curve = curve
self.private_key = None
self.public_key = None
@@ -70,19 +77,26 @@ class ECDH(object):
def _get_shared_secret(self, remote_public_key):
if not self.private_key:
raise NoKeyError(
- "Private key needs to be set to create shared secret")
+ "Private key needs to be set to create shared secret"
+ )
if not self.public_key:
raise NoKeyError(
- "Public key needs to be set to create shared secret")
- if not (self.private_key.curve == self.curve == remote_public_key.curve):
+ "Public key needs to be set to create shared secret"
+ )
+ if not (
+ self.private_key.curve == self.curve == remote_public_key.curve
+ ):
raise InvalidCurveError(
- "Curves for public key and private key is not equal.")
+ "Curves for public key and private key is not equal."
+ )
# shared secret = PUBKEYtheirs * PRIVATEKEYours
- result = remote_public_key.pubkey.point * self.private_key.privkey.secret_multiplier
+ result = (
+ remote_public_key.pubkey.point
+ * self.private_key.privkey.secret_multiplier
+ )
if result == INFINITY:
- raise InvalidSharedSecretError(
- "Invalid shared secret (INFINITY).")
+ raise InvalidSharedSecretError("Invalid shared secret (INFINITY).")
return result.x()
@@ -149,7 +163,8 @@ class ECDH(object):
if not self.curve:
raise NoCurveError("Curve must be set prior to key load.")
return self.load_private_key(
- SigningKey.from_string(private_key, curve=self.curve))
+ SigningKey.from_string(private_key, curve=self.curve)
+ )
def load_private_key_der(self, private_key_der):
"""
@@ -161,7 +176,8 @@ class ECDH(object):
Note, the only DER format supported is the RFC5915
Look at keys.py:SigningKey.from_der()
- :param private_key_der: string with the DER encoding of private ECDSA key
+ :param private_key_der: string with the DER encoding of private ECDSA
+ key
:type private_key_der: string
:raises InvalidCurveError: private_key curve not the same as self.curve
@@ -233,7 +249,8 @@ class ECDH(object):
:type public_key_str: :term:`bytes-like object`
"""
return self.load_received_public_key(
- VerifyingKey.from_string(public_key_str, self.curve))
+ VerifyingKey.from_string(public_key_str, self.curve)
+ )
def load_received_public_key_der(self, public_key_der):
"""
@@ -250,7 +267,9 @@ class ECDH(object):
:raises InvalidCurveError: public_key curve not the same as self.curve
"""
- return self.load_received_public_key(VerifyingKey.from_der(public_key_der))
+ return self.load_received_public_key(
+ VerifyingKey.from_der(public_key_der)
+ )
def load_received_public_key_pem(self, public_key_pem):
"""
@@ -267,7 +286,9 @@ class ECDH(object):
:raises InvalidCurveError: public_key curve not the same as self.curve
"""
- return self.load_received_public_key(VerifyingKey.from_pem(public_key_pem))
+ return self.load_received_public_key(
+ VerifyingKey.from_pem(public_key_pem)
+ )
def generate_sharedsecret_bytes(self):
"""
@@ -283,8 +304,8 @@ class ECDH(object):
:rtype: byte string
"""
return number_to_string(
- self.generate_sharedsecret(),
- self.private_key.curve.order)
+ self.generate_sharedsecret(), self.private_key.curve.order
+ )
def generate_sharedsecret(self):
"""
diff --git a/frozen_deps/ecdsa/ecdsa.py b/frozen_deps/ecdsa/ecdsa.py
new file mode 100644
index 0000000..d785a45
--- /dev/null
+++ b/frozen_deps/ecdsa/ecdsa.py
@@ -0,0 +1,754 @@
+#! /usr/bin/env python
+
+"""
+Implementation of Elliptic-Curve Digital Signatures.
+
+Classes and methods for elliptic-curve signatures:
+private keys, public keys, signatures,
+NIST prime-modulus curves with modulus lengths of
+192, 224, 256, 384, and 521 bits.
+
+Example:
+
+ # (In real-life applications, you would probably want to
+ # protect against defects in SystemRandom.)
+ from random import SystemRandom
+ randrange = SystemRandom().randrange
+
+ # Generate a public/private key pair using the NIST Curve P-192:
+
+ g = generator_192
+ n = g.order()
+ secret = randrange( 1, n )
+ pubkey = Public_key( g, g * secret )
+ privkey = Private_key( pubkey, secret )
+
+ # Signing a hash value:
+
+ hash = randrange( 1, n )
+ signature = privkey.sign( hash, randrange( 1, n ) )
+
+ # Verifying a signature for a hash value:
+
+ if pubkey.verifies( hash, signature ):
+ print_("Demo verification succeeded.")
+ else:
+ print_("*** Demo verification failed.")
+
+ # Verification fails if the hash value is modified:
+
+ if pubkey.verifies( hash-1, signature ):
+ print_("**** Demo verification failed to reject tampered hash.")
+ else:
+ print_("Demo verification correctly rejected tampered hash.")
+
+Version of 2009.05.16.
+
+Revision history:
+ 2005.12.31 - Initial version.
+ 2008.11.25 - Substantial revisions introducing new classes.
+ 2009.05.16 - Warn against using random.randrange in real applications.
+ 2009.05.17 - Use random.SystemRandom by default.
+
+Written in 2005 by Peter Pearson and placed in the public domain.
+"""
+
+from six import int2byte, b
+from . import ellipticcurve
+from . import numbertheory
+from .util import bit_length
+from ._compat import remove_whitespace
+
+
+class RSZeroError(RuntimeError):
+ pass
+
+
+class InvalidPointError(RuntimeError):
+ pass
+
+
+class Signature(object):
+ """ECDSA signature."""
+
+ def __init__(self, r, s):
+ self.r = r
+ self.s = s
+
+ def recover_public_keys(self, hash, generator):
+ """Returns two public keys for which the signature is valid
+ hash is signed hash
+ generator is the used generator of the signature
+ """
+ curve = generator.curve()
+ n = generator.order()
+ r = self.r
+ s = self.s
+ e = hash
+ x = r
+
+ # Compute the curve point with x as x-coordinate
+ alpha = (
+ pow(x, 3, curve.p()) + (curve.a() * x) + curve.b()
+ ) % curve.p()
+ beta = numbertheory.square_root_mod_prime(alpha, curve.p())
+ y = beta if beta % 2 == 0 else curve.p() - beta
+
+ # Compute the public key
+ R1 = ellipticcurve.PointJacobi(curve, x, y, 1, n)
+ Q1 = numbertheory.inverse_mod(r, n) * (s * R1 + (-e % n) * generator)
+ Pk1 = Public_key(generator, Q1)
+
+ # And the second solution
+ R2 = ellipticcurve.PointJacobi(curve, x, -y, 1, n)
+ Q2 = numbertheory.inverse_mod(r, n) * (s * R2 + (-e % n) * generator)
+ Pk2 = Public_key(generator, Q2)
+
+ return [Pk1, Pk2]
+
+
+class Public_key(object):
+ """Public key for ECDSA."""
+
+ def __init__(self, generator, point, verify=True):
+ """Low level ECDSA public key object.
+
+ :param generator: the Point that generates the group (the base point)
+ :param point: the Point that defines the public key
+ :param bool verify: if True check if point is valid point on curve
+
+ :raises InvalidPointError: if the point parameters are invalid or
+ point does not lie on the curve
+ """
+
+ self.curve = generator.curve()
+ self.generator = generator
+ self.point = point
+ n = generator.order()
+ p = self.curve.p()
+ if not (0 <= point.x() < p) or not (0 <= point.y() < p):
+ raise InvalidPointError(
+ "The public point has x or y out of range."
+ )
+ if verify and not self.curve.contains_point(point.x(), point.y()):
+ raise InvalidPointError("Point does not lie on the curve")
+ if not n:
+ raise InvalidPointError("Generator point must have order.")
+ # for curve parameters with base point with cofactor 1, all points
+ # that are on the curve are scalar multiples of the base point, so
+ # verifying that is not necessary. See Section 3.2.2.1 of SEC 1 v2
+ if (
+ verify
+ and self.curve.cofactor() != 1
+ and not n * point == ellipticcurve.INFINITY
+ ):
+ raise InvalidPointError("Generator point order is bad.")
+
+ def __eq__(self, other):
+ if isinstance(other, Public_key):
+ """Return True if the points are identical, False otherwise."""
+ return self.curve == other.curve and self.point == other.point
+ return NotImplemented
+
+ def verifies(self, hash, signature):
+ """Verify that signature is a valid signature of hash.
+ Return True if the signature is valid.
+ """
+
+ # From X9.62 J.3.1.
+
+ G = self.generator
+ n = G.order()
+ r = signature.r
+ s = signature.s
+ if r < 1 or r > n - 1:
+ return False
+ if s < 1 or s > n - 1:
+ return False
+ c = numbertheory.inverse_mod(s, n)
+ u1 = (hash * c) % n
+ u2 = (r * c) % n
+ if hasattr(G, "mul_add"):
+ xy = G.mul_add(u1, self.point, u2)
+ else:
+ xy = u1 * G + u2 * self.point
+ v = xy.x() % n
+ return v == r
+
+
+class Private_key(object):
+ """Private key for ECDSA."""
+
+ def __init__(self, public_key, secret_multiplier):
+ """public_key is of class Public_key;
+ secret_multiplier is a large integer.
+ """
+
+ self.public_key = public_key
+ self.secret_multiplier = secret_multiplier
+
+ def __eq__(self, other):
+ if isinstance(other, Private_key):
+ """Return True if the points are identical, False otherwise."""
+ return (
+ self.public_key == other.public_key
+ and self.secret_multiplier == other.secret_multiplier
+ )
+ return NotImplemented
+
+ def sign(self, hash, random_k):
+ """Return a signature for the provided hash, using the provided
+ random nonce. It is absolutely vital that random_k be an unpredictable
+ number in the range [1, self.public_key.point.order()-1]. If
+ an attacker can guess random_k, he can compute our private key from a
+ single signature. Also, if an attacker knows a few high-order
+ bits (or a few low-order bits) of random_k, he can compute our private
+ key from many signatures. The generation of nonces with adequate
+ cryptographic strength is very difficult and far beyond the scope
+ of this comment.
+
+ May raise RuntimeError, in which case retrying with a new
+ random value k is in order.
+ """
+
+ G = self.public_key.generator
+ n = G.order()
+ k = random_k % n
+ # Fix the bit-length of the random nonce,
+ # so that it doesn't leak via timing.
+ # This does not change that ks = k mod n
+ ks = k + n
+ kt = ks + n
+ if bit_length(ks) == bit_length(n):
+ p1 = kt * G
+ else:
+ p1 = ks * G
+ r = p1.x() % n
+ if r == 0:
+ raise RSZeroError("amazingly unlucky random number r")
+ s = (
+ numbertheory.inverse_mod(k, n)
+ * (hash + (self.secret_multiplier * r) % n)
+ ) % n
+ if s == 0:
+ raise RSZeroError("amazingly unlucky random number s")
+ return Signature(r, s)
+
+
+def int_to_string(x):
+ """Convert integer x into a string of bytes, as per X9.62."""
+ assert x >= 0
+ if x == 0:
+ return b("\0")
+ result = []
+ while x:
+ ordinal = x & 0xFF
+ result.append(int2byte(ordinal))
+ x >>= 8
+
+ result.reverse()
+ return b("").join(result)
+
+
+def string_to_int(s):
+ """Convert a string of bytes into an integer, as per X9.62."""
+ result = 0
+ for c in s:
+ if not isinstance(c, int):
+ c = ord(c)
+ result = 256 * result + c
+ return result
+
+
+def digest_integer(m):
+ """Convert an integer into a string of bytes, compute
+ its SHA-1 hash, and convert the result to an integer."""
+ #
+ # I don't expect this function to be used much. I wrote
+ # it in order to be able to duplicate the examples
+ # in ECDSAVS.
+ #
+ from hashlib import sha1
+
+ return string_to_int(sha1(int_to_string(m)).digest())
+
+
+def point_is_valid(generator, x, y):
+ """Is (x,y) a valid public key based on the specified generator?"""
+
+ # These are the tests specified in X9.62.
+
+ n = generator.order()
+ curve = generator.curve()
+ p = curve.p()
+ if not (0 <= x < p) or not (0 <= y < p):
+ return False
+ if not curve.contains_point(x, y):
+ return False
+ if (
+ curve.cofactor() != 1
+ and not n * ellipticcurve.PointJacobi(curve, x, y, 1)
+ == ellipticcurve.INFINITY
+ ):
+ return False
+ return True
+
+
+# NIST Curve P-192:
+_p = 6277101735386680763835789423207666416083908700390324961279
+_r = 6277101735386680763835789423176059013767194773182842284081
+# s = 0x3045ae6fc8422f64ed579528d38120eae12196d5L
+# c = 0x3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65L
+_b = int(
+ remove_whitespace(
+ """
+ 64210519 E59C80E7 0FA7E9AB 72243049 FEB8DEEC C146B9B1"""
+ ),
+ 16,
+)
+_Gx = int(
+ remove_whitespace(
+ """
+ 188DA80E B03090F6 7CBF20EB 43A18800 F4FF0AFD 82FF1012"""
+ ),
+ 16,
+)
+_Gy = int(
+ remove_whitespace(
+ """
+ 07192B95 FFC8DA78 631011ED 6B24CDD5 73F977A1 1E794811"""
+ ),
+ 16,
+)
+
+curve_192 = ellipticcurve.CurveFp(_p, -3, _b, 1)
+generator_192 = ellipticcurve.PointJacobi(
+ curve_192, _Gx, _Gy, 1, _r, generator=True
+)
+
+
+# NIST Curve P-224:
+_p = int(
+ remove_whitespace(
+ """
+ 2695994666715063979466701508701963067355791626002630814351
+ 0066298881"""
+ )
+)
+_r = int(
+ remove_whitespace(
+ """
+ 2695994666715063979466701508701962594045780771442439172168
+ 2722368061"""
+ )
+)
+# s = 0xbd71344799d5c7fcdc45b59fa3b9ab8f6a948bc5L
+# c = 0x5b056c7e11dd68f40469ee7f3c7a7d74f7d121116506d031218291fbL
+_b = int(
+ remove_whitespace(
+ """
+ B4050A85 0C04B3AB F5413256 5044B0B7 D7BFD8BA 270B3943
+ 2355FFB4"""
+ ),
+ 16,
+)
+_Gx = int(
+ remove_whitespace(
+ """
+ B70E0CBD 6BB4BF7F 321390B9 4A03C1D3 56C21122 343280D6
+ 115C1D21"""
+ ),
+ 16,
+)
+_Gy = int(
+ remove_whitespace(
+ """
+ BD376388 B5F723FB 4C22DFE6 CD4375A0 5A074764 44D58199
+ 85007E34"""
+ ),
+ 16,
+)
+
+curve_224 = ellipticcurve.CurveFp(_p, -3, _b, 1)
+generator_224 = ellipticcurve.PointJacobi(
+ curve_224, _Gx, _Gy, 1, _r, generator=True
+)
+
+# NIST Curve P-256:
+_p = int(
+ remove_whitespace(
+ """
+ 1157920892103562487626974469494075735300861434152903141955
+ 33631308867097853951"""
+ )
+)
+_r = int(
+ remove_whitespace(
+ """
+ 115792089210356248762697446949407573529996955224135760342
+ 422259061068512044369"""
+ )
+)
+# s = 0xc49d360886e704936a6678e1139d26b7819f7e90L
+# c = 0x7efba1662985be9403cb055c75d4f7e0ce8d84a9c5114abcaf3177680104fa0dL
+_b = int(
+ remove_whitespace(
+ """
+ 5AC635D8 AA3A93E7 B3EBBD55 769886BC 651D06B0 CC53B0F6
+ 3BCE3C3E 27D2604B"""
+ ),
+ 16,
+)
+_Gx = int(
+ remove_whitespace(
+ """
+ 6B17D1F2 E12C4247 F8BCE6E5 63A440F2 77037D81 2DEB33A0
+ F4A13945 D898C296"""
+ ),
+ 16,
+)
+_Gy = int(
+ remove_whitespace(
+ """
+ 4FE342E2 FE1A7F9B 8EE7EB4A 7C0F9E16 2BCE3357 6B315ECE
+ CBB64068 37BF51F5"""
+ ),
+ 16,
+)
+
+curve_256 = ellipticcurve.CurveFp(_p, -3, _b, 1)
+generator_256 = ellipticcurve.PointJacobi(
+ curve_256, _Gx, _Gy, 1, _r, generator=True
+)
+
+# NIST Curve P-384:
+_p = int(
+ remove_whitespace(
+ """
+ 3940200619639447921227904010014361380507973927046544666794
+ 8293404245721771496870329047266088258938001861606973112319"""
+ )
+)
+_r = int(
+ remove_whitespace(
+ """
+ 3940200619639447921227904010014361380507973927046544666794
+ 6905279627659399113263569398956308152294913554433653942643"""
+ )
+)
+# s = 0xa335926aa319a27a1d00896a6773a4827acdac73L
+# c = int(remove_whitespace(
+# """
+# 79d1e655 f868f02f ff48dcde e14151dd b80643c1 406d0ca1
+# 0dfe6fc5 2009540a 495e8042 ea5f744f 6e184667 cc722483"""
+# ), 16)
+_b = int(
+ remove_whitespace(
+ """
+ B3312FA7 E23EE7E4 988E056B E3F82D19 181D9C6E FE814112
+ 0314088F 5013875A C656398D 8A2ED19D 2A85C8ED D3EC2AEF"""
+ ),
+ 16,
+)
+_Gx = int(
+ remove_whitespace(
+ """
+ AA87CA22 BE8B0537 8EB1C71E F320AD74 6E1D3B62 8BA79B98
+ 59F741E0 82542A38 5502F25D BF55296C 3A545E38 72760AB7"""
+ ),
+ 16,
+)
+_Gy = int(
+ remove_whitespace(
+ """
+ 3617DE4A 96262C6F 5D9E98BF 9292DC29 F8F41DBD 289A147C
+ E9DA3113 B5F0B8C0 0A60B1CE 1D7E819D 7A431D7C 90EA0E5F"""
+ ),
+ 16,
+)
+
+curve_384 = ellipticcurve.CurveFp(_p, -3, _b, 1)
+generator_384 = ellipticcurve.PointJacobi(
+ curve_384, _Gx, _Gy, 1, _r, generator=True
+)
+
+# NIST Curve P-521:
+_p = int(
+ "686479766013060971498190079908139321726943530014330540939"
+ "446345918554318339765605212255964066145455497729631139148"
+ "0858037121987999716643812574028291115057151"
+)
+_r = int(
+ "686479766013060971498190079908139321726943530014330540939"
+ "446345918554318339765539424505774633321719753296399637136"
+ "3321113864768612440380340372808892707005449"
+)
+# s = 0xd09e8800291cb85396cc6717393284aaa0da64baL
+# c = int(remove_whitespace(
+# """
+# 0b4 8bfa5f42 0a349495 39d2bdfc 264eeeeb 077688e4
+# 4fbf0ad8 f6d0edb3 7bd6b533 28100051 8e19f1b9 ffbe0fe9
+# ed8a3c22 00b8f875 e523868c 70c1e5bf 55bad637"""
+# ), 16)
+_b = int(
+ remove_whitespace(
+ """
+ 051 953EB961 8E1C9A1F 929A21A0 B68540EE A2DA725B
+ 99B315F3 B8B48991 8EF109E1 56193951 EC7E937B 1652C0BD
+ 3BB1BF07 3573DF88 3D2C34F1 EF451FD4 6B503F00"""
+ ),
+ 16,
+)
+_Gx = int(
+ remove_whitespace(
+ """
+ C6 858E06B7 0404E9CD 9E3ECB66 2395B442 9C648139
+ 053FB521 F828AF60 6B4D3DBA A14B5E77 EFE75928 FE1DC127
+ A2FFA8DE 3348B3C1 856A429B F97E7E31 C2E5BD66"""
+ ),
+ 16,
+)
+_Gy = int(
+ remove_whitespace(
+ """
+ 118 39296A78 9A3BC004 5C8A5FB4 2C7D1BD9 98F54449
+ 579B4468 17AFBD17 273E662C 97EE7299 5EF42640 C550B901
+ 3FAD0761 353C7086 A272C240 88BE9476 9FD16650"""
+ ),
+ 16,
+)
+
+curve_521 = ellipticcurve.CurveFp(_p, -3, _b, 1)
+generator_521 = ellipticcurve.PointJacobi(
+ curve_521, _Gx, _Gy, 1, _r, generator=True
+)
+
+# Certicom secp256-k1
+_a = 0x0000000000000000000000000000000000000000000000000000000000000000
+_b = 0x0000000000000000000000000000000000000000000000000000000000000007
+_p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
+_Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
+_Gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
+_r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
+
+curve_secp256k1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
+generator_secp256k1 = ellipticcurve.PointJacobi(
+ curve_secp256k1, _Gx, _Gy, 1, _r, generator=True
+)
+
+# Brainpool P-160-r1
+_a = 0x340E7BE2A280EB74E2BE61BADA745D97E8F7C300
+_b = 0x1E589A8595423412134FAA2DBDEC95C8D8675E58
+_p = 0xE95E4A5F737059DC60DFC7AD95B3D8139515620F
+_Gx = 0xBED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3
+_Gy = 0x1667CB477A1A8EC338F94741669C976316DA6321
+_q = 0xE95E4A5F737059DC60DF5991D45029409E60FC09
+
+curve_brainpoolp160r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
+generator_brainpoolp160r1 = ellipticcurve.PointJacobi(
+ curve_brainpoolp160r1, _Gx, _Gy, 1, _q, generator=True
+)
+
+# Brainpool P-192-r1
+_a = 0x6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF
+_b = 0x469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9
+_p = 0xC302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297
+_Gx = 0xC0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6
+_Gy = 0x14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F
+_q = 0xC302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1
+
+curve_brainpoolp192r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
+generator_brainpoolp192r1 = ellipticcurve.PointJacobi(
+ curve_brainpoolp192r1, _Gx, _Gy, 1, _q, generator=True
+)
+
+# Brainpool P-224-r1
+_a = 0x68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43
+_b = 0x2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B
+_p = 0xD7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF
+_Gx = 0x0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D
+_Gy = 0x58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD
+_q = 0xD7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F
+
+curve_brainpoolp224r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
+generator_brainpoolp224r1 = ellipticcurve.PointJacobi(
+ curve_brainpoolp224r1, _Gx, _Gy, 1, _q, generator=True
+)
+
+# Brainpool P-256-r1
+_a = 0x7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9
+_b = 0x26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6
+_p = 0xA9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377
+_Gx = 0x8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262
+_Gy = 0x547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997
+_q = 0xA9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7
+
+curve_brainpoolp256r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
+generator_brainpoolp256r1 = ellipticcurve.PointJacobi(
+ curve_brainpoolp256r1, _Gx, _Gy, 1, _q, generator=True
+)
+
+# Brainpool P-320-r1
+_a = int(
+ remove_whitespace(
+ """
+ 3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9
+ F492F375A97D860EB4"""
+ ),
+ 16,
+)
+_b = int(
+ remove_whitespace(
+ """
+ 520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539
+ 816F5EB4AC8FB1F1A6"""
+ ),
+ 16,
+)
+_p = int(
+ remove_whitespace(
+ """
+ D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC
+ 28FCD412B1F1B32E27"""
+ ),
+ 16,
+)
+_Gx = int(
+ remove_whitespace(
+ """
+ 43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599
+ C710AF8D0D39E20611"""
+ ),
+ 16,
+)
+_Gy = int(
+ remove_whitespace(
+ """
+ 14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6A
+ C7D35245D1692E8EE1"""
+ ),
+ 16,
+)
+_q = int(
+ remove_whitespace(
+ """
+ D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658
+ E98691555B44C59311"""
+ ),
+ 16,
+)
+
+curve_brainpoolp320r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
+generator_brainpoolp320r1 = ellipticcurve.PointJacobi(
+ curve_brainpoolp320r1, _Gx, _Gy, 1, _q, generator=True
+)
+
+# Brainpool P-384-r1
+_a = int(
+ remove_whitespace(
+ """
+ 7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F9
+ 0F8AA5814A503AD4EB04A8C7DD22CE2826"""
+ ),
+ 16,
+)
+_b = int(
+ remove_whitespace(
+ """
+ 04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62
+ D57CB4390295DBC9943AB78696FA504C11"""
+ ),
+ 16,
+)
+_p = int(
+ remove_whitespace(
+ """
+ 8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB711
+ 23ACD3A729901D1A71874700133107EC53"""
+ ),
+ 16,
+)
+_Gx = int(
+ remove_whitespace(
+ """
+ 1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10
+ E8E826E03436D646AAEF87B2E247D4AF1E"""
+ ),
+ 16,
+)
+_Gy = int(
+ remove_whitespace(
+ """
+ 8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF991292
+ 80E4646217791811142820341263C5315"""
+ ),
+ 16,
+)
+_q = int(
+ remove_whitespace(
+ """
+ 8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425
+ A7CF3AB6AF6B7FC3103B883202E9046565"""
+ ),
+ 16,
+)
+
+curve_brainpoolp384r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
+generator_brainpoolp384r1 = ellipticcurve.PointJacobi(
+ curve_brainpoolp384r1, _Gx, _Gy, 1, _q, generator=True
+)
+
+# Brainpool P-512-r1
+_a = int(
+ remove_whitespace(
+ """
+ 7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863
+ BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA"""
+ ),
+ 16,
+)
+_b = int(
+ remove_whitespace(
+ """
+ 3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117
+ A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723"""
+ ),
+ 16,
+)
+_p = int(
+ remove_whitespace(
+ """
+ AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308
+ 717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3"""
+ ),
+ 16,
+)
+_Gx = int(
+ remove_whitespace(
+ """
+ 81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D009
+ 8EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822"""
+ ),
+ 16,
+)
+_Gy = int(
+ remove_whitespace(
+ """
+ 7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F81
+ 11B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892"""
+ ),
+ 16,
+)
+_q = int(
+ remove_whitespace(
+ """
+ AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308
+ 70553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069"""
+ ),
+ 16,
+)
+
+curve_brainpoolp512r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
+generator_brainpoolp512r1 = ellipticcurve.PointJacobi(
+ curve_brainpoolp512r1, _Gx, _Gy, 1, _q, generator=True
+)
diff --git a/frozen_deps/ecdsa/ellipticcurve.py b/frozen_deps/ecdsa/ellipticcurve.py
new file mode 100644
index 0000000..25565df
--- /dev/null
+++ b/frozen_deps/ecdsa/ellipticcurve.py
@@ -0,0 +1,847 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Implementation of elliptic curves, for cryptographic applications.
+#
+# This module doesn't provide any way to choose a random elliptic
+# curve, nor to verify that an elliptic curve was chosen randomly,
+# because one can simply use NIST's standard curves.
+#
+# Notes from X9.62-1998 (draft):
+# Nomenclature:
+# - Q is a public key.
+# The "Elliptic Curve Domain Parameters" include:
+# - q is the "field size", which in our case equals p.
+# - p is a big prime.
+# - G is a point of prime order (5.1.1.1).
+# - n is the order of G (5.1.1.1).
+# Public-key validation (5.2.2):
+# - Verify that Q is not the point at infinity.
+# - Verify that X_Q and Y_Q are in [0,p-1].
+# - Verify that Q is on the curve.
+# - Verify that nQ is the point at infinity.
+# Signature generation (5.3):
+# - Pick random k from [1,n-1].
+# Signature checking (5.4.2):
+# - Verify that r and s are in [1,n-1].
+#
+# Version of 2008.11.25.
+#
+# Revision history:
+# 2005.12.31 - Initial version.
+# 2008.11.25 - Change CurveFp.is_on to contains_point.
+#
+# Written in 2005 by Peter Pearson and placed in the public domain.
+
+from __future__ import division
+
+try:
+ from gmpy2 import mpz
+
+ GMPY = True
+except ImportError:
+ try:
+ from gmpy import mpz
+
+ GMPY = True
+ except ImportError:
+ GMPY = False
+
+
+from six import python_2_unicode_compatible
+from . import numbertheory
+from ._rwlock import RWLock
+
+
+@python_2_unicode_compatible
+class CurveFp(object):
+ """Elliptic Curve over the field of integers modulo a prime."""
+
+ if GMPY:
+
+ def __init__(self, p, a, b, h=None):
+ """
+ The curve of points satisfying y^2 = x^3 + a*x + b (mod p).
+
+ h is an integer that is the cofactor of the elliptic curve domain
+ parameters; it is the number of points satisfying the elliptic
+ curve equation divided by the order of the base point. It is used
+ for selection of efficient algorithm for public point verification.
+ """
+ self.__p = mpz(p)
+ self.__a = mpz(a)
+ self.__b = mpz(b)
+ # h is not used in calculations and it can be None, so don't use
+ # gmpy with it
+ self.__h = h
+
+ else:
+
+ def __init__(self, p, a, b, h=None):
+ """
+ The curve of points satisfying y^2 = x^3 + a*x + b (mod p).
+
+ h is an integer that is the cofactor of the elliptic curve domain
+ parameters; it is the number of points satisfying the elliptic
+ curve equation divided by the order of the base point. It is used
+ for selection of efficient algorithm for public point verification.
+ """
+ self.__p = p
+ self.__a = a
+ self.__b = b
+ self.__h = h
+
+ def __eq__(self, other):
+ if isinstance(other, CurveFp):
+ """Return True if the curves are identical, False otherwise."""
+ return (
+ self.__p == other.__p
+ and self.__a == other.__a
+ and self.__b == other.__b
+ )
+ return NotImplemented
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __hash__(self):
+ return hash((self.__p, self.__a, self.__b))
+
+ def p(self):
+ return self.__p
+
+ def a(self):
+ return self.__a
+
+ def b(self):
+ return self.__b
+
+ def cofactor(self):
+ return self.__h
+
+ def contains_point(self, x, y):
+ """Is the point (x,y) on this curve?"""
+ return (y * y - ((x * x + self.__a) * x + self.__b)) % self.__p == 0
+
+ def __str__(self):
+ return "CurveFp(p=%d, a=%d, b=%d, h=%d)" % (
+ self.__p,
+ self.__a,
+ self.__b,
+ self.__h,
+ )
+
+
+class PointJacobi(object):
+ """
+ Point on an elliptic curve. Uses Jacobi coordinates.
+
+ In Jacobian coordinates, there are three parameters, X, Y and Z.
+ They correspond to affine parameters 'x' and 'y' like so:
+
+ x = X / Z²
+ y = Y / Z³
+ """
+
+ def __init__(self, curve, x, y, z, order=None, generator=False):
+ """
+ Initialise a point that uses Jacobi representation internally.
+
+ :param CurveFp curve: curve on which the point resides
+ :param int x: the X parameter of Jacobi representation (equal to x when
+ converting from affine coordinates
+ :param int y: the Y parameter of Jacobi representation (equal to y when
+ converting from affine coordinates
+ :param int z: the Z parameter of Jacobi representation (equal to 1 when
+ converting from affine coordinates
+ :param int order: the point order, must be non zero when using
+ generator=True
+ :param bool generator: the point provided is a curve generator, as
+ such, it will be commonly used with scalar multiplication. This will
+ cause to precompute multiplication table for it
+ """
+ self.__curve = curve
+ # since it's generally better (faster) to use scaled points vs unscaled
+ # ones, use writer-biased RWLock for locking:
+ self._update_lock = RWLock()
+ if GMPY:
+ self.__x = mpz(x)
+ self.__y = mpz(y)
+ self.__z = mpz(z)
+ self.__order = order and mpz(order)
+ else:
+ self.__x = x
+ self.__y = y
+ self.__z = z
+ self.__order = order
+ self.__generator = generator
+ self.__precompute = []
+
+ def _maybe_precompute(self):
+ if self.__generator:
+ # since we lack promotion of read-locks to write-locks, we do a
+ # "acquire-read-lock, check, acquire-write-lock plus recheck" cycle
+ try:
+ self._update_lock.reader_acquire()
+ if self.__precompute:
+ return
+ finally:
+ self._update_lock.reader_release()
+
+ try:
+ self._update_lock.writer_acquire()
+ if self.__precompute:
+ return
+ order = self.__order
+ assert order
+ i = 1
+ order *= 2
+ doubler = PointJacobi(
+ self.__curve, self.__x, self.__y, self.__z, order
+ )
+ order *= 2
+ self.__precompute.append((doubler.x(), doubler.y()))
+
+ while i < order:
+ i *= 2
+ doubler = doubler.double().scale()
+ self.__precompute.append((doubler.x(), doubler.y()))
+
+ finally:
+ self._update_lock.writer_release()
+
+ def __getstate__(self):
+ try:
+ self._update_lock.reader_acquire()
+ state = self.__dict__.copy()
+ finally:
+ self._update_lock.reader_release()
+ del state["_update_lock"]
+ return state
+
+ def __setstate__(self, state):
+ self.__dict__.update(state)
+ self._update_lock = RWLock()
+
+ def __eq__(self, other):
+ """Compare two points with each-other."""
+ try:
+ self._update_lock.reader_acquire()
+ if other is INFINITY:
+ return not self.__y or not self.__z
+ x1, y1, z1 = self.__x, self.__y, self.__z
+ finally:
+ self._update_lock.reader_release()
+ if isinstance(other, Point):
+ x2, y2, z2 = other.x(), other.y(), 1
+ elif isinstance(other, PointJacobi):
+ try:
+ other._update_lock.reader_acquire()
+ x2, y2, z2 = other.__x, other.__y, other.__z
+ finally:
+ other._update_lock.reader_release()
+ else:
+ return NotImplemented
+ if self.__curve != other.curve():
+ return False
+ p = self.__curve.p()
+
+ zz1 = z1 * z1 % p
+ zz2 = z2 * z2 % p
+
+ # compare the fractions by bringing them to the same denominator
+ # depend on short-circuit to save 4 multiplications in case of
+ # inequality
+ return (x1 * zz2 - x2 * zz1) % p == 0 and (
+ y1 * zz2 * z2 - y2 * zz1 * z1
+ ) % p == 0
+
+ def order(self):
+ """Return the order of the point.
+
+ None if it is undefined.
+ """
+ return self.__order
+
+ def curve(self):
+ """Return curve over which the point is defined."""
+ return self.__curve
+
+ def x(self):
+ """
+ Return affine x coordinate.
+
+ This method should be used only when the 'y' coordinate is not needed.
+ It's computationally more efficient to use `to_affine()` and then
+ call x() and y() on the returned instance. Or call `scale()`
+ and then x() and y() on the returned instance.
+ """
+ try:
+ self._update_lock.reader_acquire()
+ if self.__z == 1:
+ return self.__x
+ x = self.__x
+ z = self.__z
+ finally:
+ self._update_lock.reader_release()
+ p = self.__curve.p()
+ z = numbertheory.inverse_mod(z, p)
+ return x * z ** 2 % p
+
+ def y(self):
+ """
+ Return affine y coordinate.
+
+ This method should be used only when the 'x' coordinate is not needed.
+ It's computationally more efficient to use `to_affine()` and then
+ call x() and y() on the returned instance. Or call `scale()`
+ and then x() and y() on the returned instance.
+ """
+ try:
+ self._update_lock.reader_acquire()
+ if self.__z == 1:
+ return self.__y
+ y = self.__y
+ z = self.__z
+ finally:
+ self._update_lock.reader_release()
+ p = self.__curve.p()
+ z = numbertheory.inverse_mod(z, p)
+ return y * z ** 3 % p
+
+ def scale(self):
+ """
+ Return point scaled so that z == 1.
+
+ Modifies point in place, returns self.
+ """
+ try:
+ self._update_lock.reader_acquire()
+ if self.__z == 1:
+ return self
+ finally:
+ self._update_lock.reader_release()
+
+ try:
+ self._update_lock.writer_acquire()
+ # scaling already scaled point is safe (as inverse of 1 is 1) and
+ # quick so we don't need to optimise for the unlikely event when
+ # two threads hit the lock at the same time
+ p = self.__curve.p()
+ z_inv = numbertheory.inverse_mod(self.__z, p)
+ zz_inv = z_inv * z_inv % p
+ self.__x = self.__x * zz_inv % p
+ self.__y = self.__y * zz_inv * z_inv % p
+ # we are setting the z last so that the check above will return
+ # true only after all values were already updated
+ self.__z = 1
+ finally:
+ self._update_lock.writer_release()
+ return self
+
+ def to_affine(self):
+ """Return point in affine form."""
+ if not self.__y or not self.__z:
+ return INFINITY
+ self.scale()
+ # after point is scaled, it's immutable, so no need to perform locking
+ return Point(self.__curve, self.__x, self.__y, self.__order)
+
+ @staticmethod
+ def from_affine(point, generator=False):
+ """Create from an affine point.
+
+ :param bool generator: set to True to make the point to precalculate
+ multiplication table - useful for public point when verifying many
+ signatures (around 100 or so) or for generator points of a curve.
+ """
+ return PointJacobi(
+ point.curve(), point.x(), point.y(), 1, point.order(), generator
+ )
+
+ # plese note that all the methods that use the equations from hyperelliptic
+ # are formatted in a way to maximise performance.
+ # Things that make code faster: multiplying instead of taking to the power
+ # (`xx = x * x; xxxx = xx * xx % p` is faster than `xxxx = x**4 % p` and
+ # `pow(x, 4, p)`),
+ # multiple assignments at the same time (`x1, x2 = self.x1, self.x2` is
+ # faster than `x1 = self.x1; x2 = self.x2`),
+ # similarly, sometimes the `% p` is skipped if it makes the calculation
+ # faster and the result of calculation is later reduced modulo `p`
+
+ def _double_with_z_1(self, X1, Y1, p, a):
+ """Add a point to itself with z == 1."""
+ # after:
+ # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-mdbl-2007-bl
+ XX, YY = X1 * X1 % p, Y1 * Y1 % p
+ if not YY:
+ return 0, 0, 1
+ YYYY = YY * YY % p
+ S = 2 * ((X1 + YY) ** 2 - XX - YYYY) % p
+ M = 3 * XX + a
+ T = (M * M - 2 * S) % p
+ # X3 = T
+ Y3 = (M * (S - T) - 8 * YYYY) % p
+ Z3 = 2 * Y1 % p
+ return T, Y3, Z3
+
+ def _double(self, X1, Y1, Z1, p, a):
+ """Add a point to itself, arbitrary z."""
+ if Z1 == 1:
+ return self._double_with_z_1(X1, Y1, p, a)
+ if not Z1:
+ return 0, 0, 1
+ # after:
+ # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl
+ XX, YY = X1 * X1 % p, Y1 * Y1 % p
+ if not YY:
+ return 0, 0, 1
+ YYYY = YY * YY % p
+ ZZ = Z1 * Z1 % p
+ S = 2 * ((X1 + YY) ** 2 - XX - YYYY) % p
+ M = (3 * XX + a * ZZ * ZZ) % p
+ T = (M * M - 2 * S) % p
+ # X3 = T
+ Y3 = (M * (S - T) - 8 * YYYY) % p
+ Z3 = ((Y1 + Z1) ** 2 - YY - ZZ) % p
+
+ return T, Y3, Z3
+
+ def double(self):
+ """Add a point to itself."""
+ if not self.__y:
+ return INFINITY
+
+ p, a = self.__curve.p(), self.__curve.a()
+
+ try:
+ self._update_lock.reader_acquire()
+ X1, Y1, Z1 = self.__x, self.__y, self.__z
+ finally:
+ self._update_lock.reader_release()
+
+ X3, Y3, Z3 = self._double(X1, Y1, Z1, p, a)
+
+ if not Y3 or not Z3:
+ return INFINITY
+ return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
+
+ def _add_with_z_1(self, X1, Y1, X2, Y2, p):
+ """add points when both Z1 and Z2 equal 1"""
+ # after:
+ # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-mmadd-2007-bl
+ H = X2 - X1
+ HH = H * H
+ I = 4 * HH % p
+ J = H * I
+ r = 2 * (Y2 - Y1)
+ if not H and not r:
+ return self._double_with_z_1(X1, Y1, p, self.__curve.a())
+ V = X1 * I
+ X3 = (r ** 2 - J - 2 * V) % p
+ Y3 = (r * (V - X3) - 2 * Y1 * J) % p
+ Z3 = 2 * H % p
+ return X3, Y3, Z3
+
+ def _add_with_z_eq(self, X1, Y1, Z1, X2, Y2, p):
+ """add points when Z1 == Z2"""
+ # after:
+ # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-zadd-2007-m
+ A = (X2 - X1) ** 2 % p
+ B = X1 * A % p
+ C = X2 * A
+ D = (Y2 - Y1) ** 2 % p
+ if not A and not D:
+ return self._double(X1, Y1, Z1, p, self.__curve.a())
+ X3 = (D - B - C) % p
+ Y3 = ((Y2 - Y1) * (B - X3) - Y1 * (C - B)) % p
+ Z3 = Z1 * (X2 - X1) % p
+ return X3, Y3, Z3
+
+ def _add_with_z2_1(self, X1, Y1, Z1, X2, Y2, p):
+ """add points when Z2 == 1"""
+ # after:
+ # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-madd-2007-bl
+ Z1Z1 = Z1 * Z1 % p
+ U2, S2 = X2 * Z1Z1 % p, Y2 * Z1 * Z1Z1 % p
+ H = (U2 - X1) % p
+ HH = H * H % p
+ I = 4 * HH % p
+ J = H * I
+ r = 2 * (S2 - Y1) % p
+ if not r and not H:
+ return self._double_with_z_1(X2, Y2, p, self.__curve.a())
+ V = X1 * I
+ X3 = (r * r - J - 2 * V) % p
+ Y3 = (r * (V - X3) - 2 * Y1 * J) % p
+ Z3 = ((Z1 + H) ** 2 - Z1Z1 - HH) % p
+ return X3, Y3, Z3
+
+ def _add_with_z_ne(self, X1, Y1, Z1, X2, Y2, Z2, p):
+ """add points with arbitrary z"""
+ # after:
+ # http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-add-2007-bl
+ Z1Z1 = Z1 * Z1 % p
+ Z2Z2 = Z2 * Z2 % p
+ U1 = X1 * Z2Z2 % p
+ U2 = X2 * Z1Z1 % p
+ S1 = Y1 * Z2 * Z2Z2 % p
+ S2 = Y2 * Z1 * Z1Z1 % p
+ H = U2 - U1
+ I = 4 * H * H % p
+ J = H * I % p
+ r = 2 * (S2 - S1) % p
+ if not H and not r:
+ return self._double(X1, Y1, Z1, p, self.__curve.a())
+ V = U1 * I
+ X3 = (r * r - J - 2 * V) % p
+ Y3 = (r * (V - X3) - 2 * S1 * J) % p
+ Z3 = ((Z1 + Z2) ** 2 - Z1Z1 - Z2Z2) * H % p
+
+ return X3, Y3, Z3
+
+ def __radd__(self, other):
+ """Add other to self."""
+ return self + other
+
+ def _add(self, X1, Y1, Z1, X2, Y2, Z2, p):
+ """add two points, select fastest method."""
+ if not Y1 or not Z1:
+ return X2, Y2, Z2
+ if not Y2 or not Z2:
+ return X1, Y1, Z1
+ if Z1 == Z2:
+ if Z1 == 1:
+ return self._add_with_z_1(X1, Y1, X2, Y2, p)
+ return self._add_with_z_eq(X1, Y1, Z1, X2, Y2, p)
+ if Z1 == 1:
+ return self._add_with_z2_1(X2, Y2, Z2, X1, Y1, p)
+ if Z2 == 1:
+ return self._add_with_z2_1(X1, Y1, Z1, X2, Y2, p)
+ return self._add_with_z_ne(X1, Y1, Z1, X2, Y2, Z2, p)
+
+ def __add__(self, other):
+ """Add two points on elliptic curve."""
+ if self == INFINITY:
+ return other
+ if other == INFINITY:
+ return self
+ if isinstance(other, Point):
+ other = PointJacobi.from_affine(other)
+ if self.__curve != other.__curve:
+ raise ValueError("The other point is on different curve")
+
+ p = self.__curve.p()
+ try:
+ self._update_lock.reader_acquire()
+ X1, Y1, Z1 = self.__x, self.__y, self.__z
+ finally:
+ self._update_lock.reader_release()
+ try:
+ other._update_lock.reader_acquire()
+ X2, Y2, Z2 = other.__x, other.__y, other.__z
+ finally:
+ other._update_lock.reader_release()
+ X3, Y3, Z3 = self._add(X1, Y1, Z1, X2, Y2, Z2, p)
+
+ if not Y3 or not Z3:
+ return INFINITY
+ return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
+
+ def __rmul__(self, other):
+ """Multiply point by an integer."""
+ return self * other
+
+ def _mul_precompute(self, other):
+ """Multiply point by integer with precomputation table."""
+ X3, Y3, Z3, p = 0, 0, 1, self.__curve.p()
+ _add = self._add
+ for X2, Y2 in self.__precompute:
+ if other % 2:
+ if other % 4 >= 2:
+ other = (other + 1) // 2
+ X3, Y3, Z3 = _add(X3, Y3, Z3, X2, -Y2, 1, p)
+ else:
+ other = (other - 1) // 2
+ X3, Y3, Z3 = _add(X3, Y3, Z3, X2, Y2, 1, p)
+ else:
+ other //= 2
+
+ if not Y3 or not Z3:
+ return INFINITY
+ return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
+
+ @staticmethod
+ def _naf(mult):
+ """Calculate non-adjacent form of number."""
+ ret = []
+ while mult:
+ if mult % 2:
+ nd = mult % 4
+ if nd >= 2:
+ nd = nd - 4
+ ret += [nd]
+ mult -= nd
+ else:
+ ret += [0]
+ mult //= 2
+ return ret
+
+ def __mul__(self, other):
+ """Multiply point by an integer."""
+ if not self.__y or not other:
+ return INFINITY
+ if other == 1:
+ return self
+ if self.__order:
+ # order*2 as a protection for Minerva
+ other = other % (self.__order * 2)
+ self._maybe_precompute()
+ if self.__precompute:
+ return self._mul_precompute(other)
+
+ self = self.scale()
+ # once scaled, point is immutable, not need to lock
+ X2, Y2 = self.__x, self.__y
+ X3, Y3, Z3 = 0, 0, 1
+ p, a = self.__curve.p(), self.__curve.a()
+ _double = self._double
+ _add = self._add
+ # since adding points when at least one of them is scaled
+ # is quicker, reverse the NAF order
+ for i in reversed(self._naf(other)):
+ X3, Y3, Z3 = _double(X3, Y3, Z3, p, a)
+ if i < 0:
+ X3, Y3, Z3 = _add(X3, Y3, Z3, X2, -Y2, 1, p)
+ elif i > 0:
+ X3, Y3, Z3 = _add(X3, Y3, Z3, X2, Y2, 1, p)
+
+ if not Y3 or not Z3:
+ return INFINITY
+
+ return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
+
+ @staticmethod
+ def _leftmost_bit(x):
+ """Return integer with the same magnitude as x but only one bit set"""
+ assert x > 0
+ result = 1
+ while result <= x:
+ result = 2 * result
+ return result // 2
+
+ def mul_add(self, self_mul, other, other_mul):
+ """
+ Do two multiplications at the same time, add results.
+
+ calculates self*self_mul + other*other_mul
+ """
+ if other is INFINITY or other_mul == 0:
+ return self * self_mul
+ if self_mul == 0:
+ return other * other_mul
+ if not isinstance(other, PointJacobi):
+ other = PointJacobi.from_affine(other)
+ # when the points have precomputed answers, then multiplying them alone
+ # is faster (as it uses NAF)
+ self._maybe_precompute()
+ other._maybe_precompute()
+ if self.__precompute and other.__precompute:
+ return self * self_mul + other * other_mul
+
+ if self.__order:
+ self_mul = self_mul % self.__order
+ other_mul = other_mul % self.__order
+
+ i = self._leftmost_bit(max(self_mul, other_mul)) * 2
+ X3, Y3, Z3 = 0, 0, 1
+ p, a = self.__curve.p(), self.__curve.a()
+ self = self.scale()
+ # after scaling, point is immutable, no need for locking
+ X1, Y1 = self.__x, self.__y
+ other = other.scale()
+ X2, Y2 = other.__x, other.__y
+ both = self + other
+ if both is INFINITY:
+ X4, Y4 = 0, 0
+ else:
+ both.scale()
+ X4, Y4 = both.__x, both.__y
+ _double = self._double
+ _add = self._add
+ while i > 1:
+ X3, Y3, Z3 = _double(X3, Y3, Z3, p, a)
+ i = i // 2
+
+ if self_mul & i and other_mul & i:
+ X3, Y3, Z3 = _add(X3, Y3, Z3, X4, Y4, 1, p)
+ elif self_mul & i:
+ X3, Y3, Z3 = _add(X3, Y3, Z3, X1, Y1, 1, p)
+ elif other_mul & i:
+ X3, Y3, Z3 = _add(X3, Y3, Z3, X2, Y2, 1, p)
+
+ if not Y3 or not Z3:
+ return INFINITY
+
+ return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
+
+ def __neg__(self):
+ """Return negated point."""
+ try:
+ self._update_lock.reader_acquire()
+ return PointJacobi(
+ self.__curve, self.__x, -self.__y, self.__z, self.__order
+ )
+ finally:
+ self._update_lock.reader_release()
+
+
+class Point(object):
+ """A point on an elliptic curve. Altering x and y is forbidding,
+ but they can be read by the x() and y() methods."""
+
+ def __init__(self, curve, x, y, order=None):
+ """curve, x, y, order; order (optional) is the order of this point."""
+ self.__curve = curve
+ if GMPY:
+ self.__x = x and mpz(x)
+ self.__y = y and mpz(y)
+ self.__order = order and mpz(order)
+ else:
+ self.__x = x
+ self.__y = y
+ self.__order = order
+ # self.curve is allowed to be None only for INFINITY:
+ if self.__curve:
+ assert self.__curve.contains_point(x, y)
+ # for curves with cofactor 1, all points that are on the curve are
+ # scalar multiples of the base point, so performing multiplication is
+ # not necessary to verify that. See Section 3.2.2.1 of SEC 1 v2
+ if curve and curve.cofactor() != 1 and order:
+ assert self * order == INFINITY
+
+ def __eq__(self, other):
+ """Return True if the points are identical, False otherwise."""
+ if isinstance(other, Point):
+ return (
+ self.__curve == other.__curve
+ and self.__x == other.__x
+ and self.__y == other.__y
+ )
+ return NotImplemented
+
+ def __neg__(self):
+ return Point(self.__curve, self.__x, self.__curve.p() - self.__y)
+
+ def __add__(self, other):
+ """Add one point to another point."""
+
+ # X9.62 B.3:
+
+ if not isinstance(other, Point):
+ return NotImplemented
+ if other == INFINITY:
+ return self
+ if self == INFINITY:
+ return other
+ assert self.__curve == other.__curve
+ if self.__x == other.__x:
+ if (self.__y + other.__y) % self.__curve.p() == 0:
+ return INFINITY
+ else:
+ return self.double()
+
+ p = self.__curve.p()
+
+ l = (
+ (other.__y - self.__y)
+ * numbertheory.inverse_mod(other.__x - self.__x, p)
+ ) % p
+
+ x3 = (l * l - self.__x - other.__x) % p
+ y3 = (l * (self.__x - x3) - self.__y) % p
+
+ return Point(self.__curve, x3, y3)
+
+ def __mul__(self, other):
+ """Multiply a point by an integer."""
+
+ def leftmost_bit(x):
+ assert x > 0
+ result = 1
+ while result <= x:
+ result = 2 * result
+ return result // 2
+
+ e = other
+ if e == 0 or (self.__order and e % self.__order == 0):
+ return INFINITY
+ if self == INFINITY:
+ return INFINITY
+ if e < 0:
+ return (-self) * (-e)
+
+ # From X9.62 D.3.2:
+
+ e3 = 3 * e
+ negative_self = Point(self.__curve, self.__x, -self.__y, self.__order)
+ i = leftmost_bit(e3) // 2
+ result = self
+ # print_("Multiplying %s by %d (e3 = %d):" % (self, other, e3))
+ while i > 1:
+ result = result.double()
+ if (e3 & i) != 0 and (e & i) == 0:
+ result = result + self
+ if (e3 & i) == 0 and (e & i) != 0:
+ result = result + negative_self
+ # print_(". . . i = %d, result = %s" % ( i, result ))
+ i = i // 2
+
+ return result
+
+ def __rmul__(self, other):
+ """Multiply a point by an integer."""
+
+ return self * other
+
+ def __str__(self):
+ if self == INFINITY:
+ return "infinity"
+ return "(%d,%d)" % (self.__x, self.__y)
+
+ def double(self):
+ """Return a new point that is twice the old."""
+
+ if self == INFINITY:
+ return INFINITY
+
+ # X9.62 B.3:
+
+ p = self.__curve.p()
+ a = self.__curve.a()
+
+ l = (
+ (3 * self.__x * self.__x + a)
+ * numbertheory.inverse_mod(2 * self.__y, p)
+ ) % p
+
+ x3 = (l * l - 2 * self.__x) % p
+ y3 = (l * (self.__x - x3) - self.__y) % p
+
+ return Point(self.__curve, x3, y3)
+
+ def x(self):
+ return self.__x
+
+ def y(self):
+ return self.__y
+
+ def curve(self):
+ return self.__curve
+
+ def order(self):
+ return self.__order
+
+
+# This one point is the Point At Infinity for all purposes:
+INFINITY = Point(None, None, None)
diff --git a/freezed_deps/ecdsa/keys.py b/frozen_deps/ecdsa/keys.py
index 172fdf5..a6fc13f 100644
--- a/freezed_deps/ecdsa/keys.py
+++ b/frozen_deps/ecdsa/keys.py
@@ -68,7 +68,7 @@ Primary classes for performing signing and verification operations.
import binascii
from hashlib import sha1
-from six import PY3, b
+from six import PY2, b
from . import ecdsa
from . import der
from . import rfc6979
@@ -77,13 +77,24 @@ from .curves import NIST192p, find_curve
from .numbertheory import square_root_mod_prime, SquareRootError
from .ecdsa import RSZeroError
from .util import string_to_number, number_to_string, randrange
-from .util import sigencode_string, sigdecode_string
-from .util import oid_ecPublicKey, encoded_oid_ecPublicKey, MalformedSignature
+from .util import sigencode_string, sigdecode_string, bit_length
+from .util import (
+ oid_ecPublicKey,
+ encoded_oid_ecPublicKey,
+ oid_ecDH,
+ oid_ecMQV,
+ MalformedSignature,
+)
from ._compat import normalise_bytes
-__all__ = ["BadSignatureError", "BadDigestError", "VerifyingKey", "SigningKey",
- "MalformedPointError"]
+__all__ = [
+ "BadSignatureError",
+ "BadDigestError",
+ "VerifyingKey",
+ "SigningKey",
+ "MalformedPointError",
+]
class BadSignatureError(Exception):
@@ -129,8 +140,9 @@ class VerifyingKey(object):
def __init__(self, _error__please_use_generate=None):
"""Unsupported, please use one of the classmethods to initialise."""
if not _error__please_use_generate:
- raise TypeError("Please use VerifyingKey.generate() to "
- "construct me")
+ raise TypeError(
+ "Please use VerifyingKey.generate() to construct me"
+ )
self.curve = None
self.default_hashfunc = None
self.pubkey = None
@@ -138,18 +150,19 @@ class VerifyingKey(object):
def __repr__(self):
pub_key = self.to_string("compressed")
return "VerifyingKey.from_string({0!r}, {1!r}, {2})".format(
- pub_key, self.curve, self.default_hashfunc().name)
+ pub_key, self.curve, self.default_hashfunc().name
+ )
def __eq__(self, other):
"""Return True if the points are identical, False otherwise."""
if isinstance(other, VerifyingKey):
- return self.curve == other.curve \
- and self.pubkey == other.pubkey
+ return self.curve == other.curve and self.pubkey == other.pubkey
return NotImplemented
@classmethod
- def from_public_point(cls, point, curve=NIST192p, hashfunc=sha1,
- validate_point=True):
+ def from_public_point(
+ cls, point, curve=NIST192p, hashfunc=sha1, validate_point=True
+ ):
"""
Initialise the object from a Point object.
@@ -180,16 +193,41 @@ class VerifyingKey(object):
self.curve = curve
self.default_hashfunc = hashfunc
try:
- self.pubkey = ecdsa.Public_key(curve.generator, point,
- validate_point)
+ self.pubkey = ecdsa.Public_key(
+ curve.generator, point, validate_point
+ )
except ecdsa.InvalidPointError:
raise MalformedPointError("Point does not lie on the curve")
self.pubkey.order = curve.order
return self
- def precompute(self):
+ def precompute(self, lazy=False):
+ """
+ Precompute multiplication tables for faster signature verification.
+
+ Calling this method will cause the library to precompute the
+ scalar multiplication tables, used in signature verification.
+ While it's an expensive operation (comparable to performing
+ as many signatures as the bit size of the curve, i.e. 256 for NIST256p)
+ it speeds up verification 2 times. You should call this method
+ if you expect to verify hundreds of signatures (or more) using the same
+ VerifyingKey object.
+
+ Note: You should call this method only once, this method generates a
+ new precomputation table every time it's called.
+
+ :param bool lazy: whether to calculate the precomputation table now
+ (if set to False) or if it should be delayed to the time of first
+ use (when set to True)
+ """
self.pubkey.point = ellipticcurve.PointJacobi.from_affine(
- self.pubkey.point, True)
+ self.pubkey.point, True
+ )
+ # as precomputation in now delayed to the time of first use of the
+ # point and we were asked specifically to precompute now, make
+ # sure the precomputation is performed now to preserve the behaviour
+ if not lazy:
+ self.pubkey.point * 2
@staticmethod
def _from_raw_encoding(string, curve):
@@ -202,8 +240,8 @@ class VerifyingKey(object):
order = curve.order
# real assert, from_string() should not call us with different length
assert len(string) == curve.verifying_key_length
- xs = string[:curve.baselen]
- ys = string[curve.baselen:]
+ xs = string[: curve.baselen]
+ ys = string[curve.baselen :]
if len(xs) != curve.baselen:
raise MalformedPointError("Unexpected length of encoded x")
if len(ys) != curve.baselen:
@@ -216,10 +254,10 @@ class VerifyingKey(object):
@staticmethod
def _from_compressed(string, curve):
"""Decode public point from compressed encoding."""
- if string[:1] not in (b('\x02'), b('\x03')):
+ if string[:1] not in (b("\x02"), b("\x03")):
raise MalformedPointError("Malformed compressed point encoding")
- is_even = string[:1] == b('\x02')
+ is_even = string[:1] == b("\x02")
x = string_to_number(string[1:])
order = curve.order
p = curve.curve.p()
@@ -228,7 +266,8 @@ class VerifyingKey(object):
beta = square_root_mod_prime(alpha, p)
except SquareRootError as e:
raise MalformedPointError(
- "Encoding does not correspond to a point on curve", e)
+ "Encoding does not correspond to a point on curve", e
+ )
if is_even == bool(beta & 1):
y = p - beta
else:
@@ -239,22 +278,26 @@ class VerifyingKey(object):
def _from_hybrid(cls, string, curve, validate_point):
"""Decode public point from hybrid encoding."""
# real assert, from_string() should not call us with different types
- assert string[:1] in (b('\x06'), b('\x07'))
+ assert string[:1] in (b("\x06"), b("\x07"))
# primarily use the uncompressed as it's easiest to handle
point = cls._from_raw_encoding(string[1:], curve)
# but validate if it's self-consistent if we're asked to do that
- if validate_point \
- and (point.y() & 1 and string[:1] != b('\x07')
- or (not point.y() & 1) and string[:1] != b('\x06')):
+ if validate_point and (
+ point.y() & 1
+ and string[:1] != b("\x07")
+ or (not point.y() & 1)
+ and string[:1] != b("\x06")
+ ):
raise MalformedPointError("Inconsistent hybrid point encoding")
return point
@classmethod
- def from_string(cls, string, curve=NIST192p, hashfunc=sha1,
- validate_point=True):
+ def from_string(
+ cls, string, curve=NIST192p, hashfunc=sha1, validate_point=True
+ ):
"""
Initialise the object from byte encoding of public key.
@@ -288,22 +331,23 @@ class VerifyingKey(object):
if sig_len == curve.verifying_key_length:
point = cls._from_raw_encoding(string, curve)
elif sig_len == curve.verifying_key_length + 1:
- if string[:1] in (b('\x06'), b('\x07')):
+ if string[:1] in (b("\x06"), b("\x07")):
point = cls._from_hybrid(string, curve, validate_point)
- elif string[:1] == b('\x04'):
+ elif string[:1] == b("\x04"):
point = cls._from_raw_encoding(string[1:], curve)
else:
raise MalformedPointError(
- "Invalid X9.62 encoding of the public point")
+ "Invalid X9.62 encoding of the public point"
+ )
elif sig_len == curve.baselen + 1:
point = cls._from_compressed(string, curve)
else:
raise MalformedPointError(
"Length of string does not match lengths of "
"any of the supported encodings of {0} "
- "curve.".format(curve.name))
- return cls.from_public_point(point, curve, hashfunc,
- validate_point)
+ "curve.".format(curve.name)
+ )
+ return cls.from_public_point(point, curve, hashfunc, validate_point)
@classmethod
def from_pem(cls, string, hashfunc=sha1):
@@ -360,31 +404,39 @@ class VerifyingKey(object):
# [[oid_ecPublicKey,oid_curve], point_str_bitstring]
s1, empty = der.remove_sequence(string)
if empty != b"":
- raise der.UnexpectedDER("trailing junk after DER pubkey: %s" %
- binascii.hexlify(empty))
+ raise der.UnexpectedDER(
+ "trailing junk after DER pubkey: %s" % binascii.hexlify(empty)
+ )
s2, point_str_bitstring = der.remove_sequence(s1)
# s2 = oid_ecPublicKey,oid_curve
oid_pk, rest = der.remove_object(s2)
oid_curve, empty = der.remove_object(rest)
if empty != b"":
- raise der.UnexpectedDER("trailing junk after DER pubkey objects: %s" %
- binascii.hexlify(empty))
+ raise der.UnexpectedDER(
+ "trailing junk after DER pubkey objects: %s"
+ % binascii.hexlify(empty)
+ )
if not oid_pk == oid_ecPublicKey:
- raise der.UnexpectedDER("Unexpected object identifier in DER "
- "encoding: {0!r}".format(oid_pk))
+ raise der.UnexpectedDER(
+ "Unexpected object identifier in DER "
+ "encoding: {0!r}".format(oid_pk)
+ )
curve = find_curve(oid_curve)
point_str, empty = der.remove_bitstring(point_str_bitstring, 0)
if empty != b"":
- raise der.UnexpectedDER("trailing junk after pubkey pointstring: %s" %
- binascii.hexlify(empty))
+ raise der.UnexpectedDER(
+ "trailing junk after pubkey pointstring: %s"
+ % binascii.hexlify(empty)
+ )
# raw encoding of point is invalid in DER files
if len(point_str) == curve.verifying_key_length:
raise der.UnexpectedDER("Malformed encoding of public point")
return cls.from_string(point_str, curve, hashfunc=hashfunc)
@classmethod
- def from_public_key_recovery(cls, signature, data, curve, hashfunc=sha1,
- sigdecode=sigdecode_string):
+ def from_public_key_recovery(
+ cls, signature, data, curve, hashfunc=sha1, sigdecode=sigdecode_string
+ ):
"""
Return keys that can be used as verifiers of the provided signature.
@@ -414,13 +466,18 @@ class VerifyingKey(object):
data = normalise_bytes(data)
digest = hashfunc(data).digest()
return cls.from_public_key_recovery_with_digest(
- signature, digest, curve, hashfunc=hashfunc,
- sigdecode=sigdecode)
+ signature, digest, curve, hashfunc=hashfunc, sigdecode=sigdecode
+ )
@classmethod
def from_public_key_recovery_with_digest(
- cls, signature, digest, curve,
- hashfunc=sha1, sigdecode=sigdecode_string):
+ cls,
+ signature,
+ digest,
+ curve,
+ hashfunc=sha1,
+ sigdecode=sigdecode_string,
+ ):
"""
Return keys that can be used as verifiers of the provided signature.
@@ -457,8 +514,9 @@ class VerifyingKey(object):
pks = sig.recover_public_keys(digest_as_number, generator)
# Transforms the ecdsa.Public_key object into a VerifyingKey
- verifying_keys = [cls.from_public_point(pk.point, curve, hashfunc)
- for pk in pks]
+ verifying_keys = [
+ cls.from_public_point(pk.point, curve, hashfunc) for pk in pks
+ ]
return verifying_keys
def _raw_encode(self):
@@ -473,17 +531,17 @@ class VerifyingKey(object):
order = self.pubkey.order
x_str = number_to_string(self.pubkey.point.x(), order)
if self.pubkey.point.y() & 1:
- return b('\x03') + x_str
+ return b("\x03") + x_str
else:
- return b('\x02') + x_str
+ return b("\x02") + x_str
def _hybrid_encode(self):
"""Encode the public point into the hybrid form."""
raw_enc = self._raw_encode()
if self.pubkey.point.y() & 1:
- return b('\x07') + raw_enc
+ return b("\x07") + raw_enc
else:
- return b('\x06') + raw_enc
+ return b("\x06") + raw_enc
def to_string(self, encoding="raw"):
"""
@@ -509,7 +567,7 @@ class VerifyingKey(object):
if encoding == "raw":
return self._raw_encode()
elif encoding == "uncompressed":
- return b('\x04') + self._raw_encode()
+ return b("\x04") + self._raw_encode()
elif encoding == "hybrid":
return self._hybrid_encode()
else:
@@ -531,7 +589,10 @@ class VerifyingKey(object):
implementations, it is as big as "uncompressed".
:return: portable encoding of the public key
- :rtype: str
+ :rtype: bytes
+
+ .. warning:: The PEM is encoded to US-ASCII, it needs to be
+ re-encoded if the system is incompatible (e.g. uses UTF-16)
"""
return der.topem(self.to_der(point_encoding), "PUBLIC KEY")
@@ -554,14 +615,23 @@ class VerifyingKey(object):
if point_encoding == "raw":
raise ValueError("raw point_encoding not allowed in DER")
point_str = self.to_string(point_encoding)
- return der.encode_sequence(der.encode_sequence(encoded_oid_ecPublicKey,
- self.curve.encoded_oid),
- # 0 is the number of unused bits in the
- # bit string
- der.encode_bitstring(point_str, 0))
-
- def verify(self, signature, data, hashfunc=None,
- sigdecode=sigdecode_string):
+ return der.encode_sequence(
+ der.encode_sequence(
+ encoded_oid_ecPublicKey, self.curve.encoded_oid
+ ),
+ # 0 is the number of unused bits in the
+ # bit string
+ der.encode_bitstring(point_str, 0),
+ )
+
+ def verify(
+ self,
+ signature,
+ data,
+ hashfunc=None,
+ sigdecode=sigdecode_string,
+ allow_truncate=True,
+ ):
"""
Verify a signature made over provided data.
@@ -587,6 +657,11 @@ class VerifyingKey(object):
second one. See :func:`ecdsa.util.sigdecode_string` and
:func:`ecdsa.util.sigdecode_der` for examples.
:type sigdecode: callable
+ :param bool allow_truncate: if True, the provided digest can have
+ bigger bit-size than the order of the curve, the extra bits (at
+ the end of the digest) will be truncated. Use it when verifying
+ SHA-384 output using NIST256p or in similar situations. Defaults to
+ True.
:raises BadSignatureError: if the signature is invalid or malformed
@@ -599,10 +674,15 @@ class VerifyingKey(object):
hashfunc = hashfunc or self.default_hashfunc
digest = hashfunc(data).digest()
- return self.verify_digest(signature, digest, sigdecode, True)
-
- def verify_digest(self, signature, digest, sigdecode=sigdecode_string,
- allow_truncate=False):
+ return self.verify_digest(signature, digest, sigdecode, allow_truncate)
+
+ def verify_digest(
+ self,
+ signature,
+ digest,
+ sigdecode=sigdecode_string,
+ allow_truncate=False,
+ ):
"""
Verify a signature made over provided hash value.
@@ -637,13 +717,28 @@ class VerifyingKey(object):
# signature doesn't have to be a bytes-like-object so don't normalise
# it, the decoders will do that
digest = normalise_bytes(digest)
- if allow_truncate:
- digest = digest[:self.curve.baselen]
- if len(digest) > self.curve.baselen:
- raise BadDigestError("this curve (%s) is too short "
- "for your digest (%d)" % (self.curve.name,
- 8 * len(digest)))
+ if not allow_truncate and len(digest) > self.curve.baselen:
+ raise BadDigestError(
+ "this curve (%s) is too short "
+ "for your digest (%d)" % (self.curve.name, 8 * len(digest))
+ )
number = string_to_number(digest)
+ if allow_truncate:
+ max_length = bit_length(self.curve.order)
+ # we don't use bit_length(number) as that truncates leading zeros
+ length = len(digest) * 8
+
+ # See NIST FIPS 186-4:
+ #
+ # When the length of the output of the hash function is greater
+ # than N (i.e., the bit length of q), then the leftmost N bits of
+ # the hash function output block shall be used in any calculation
+ # using the hash function output during the generation or
+ # verification of a digital signature.
+ #
+ # as such, we need to shift-out the low-order bits:
+ number >>= max(0, length - max_length)
+
try:
r, s = sigdecode(signature, self.pubkey.order)
except (der.UnexpectedDER, MalformedSignature) as e:
@@ -681,9 +776,11 @@ class SigningKey(object):
def __eq__(self, other):
"""Return True if the points are identical, False otherwise."""
if isinstance(other, SigningKey):
- return self.curve == other.curve \
- and self.verifying_key == other.verifying_key \
+ return (
+ self.curve == other.curve
+ and self.verifying_key == other.verifying_key
and self.privkey == other.privkey
+ )
return NotImplemented
@classmethod
@@ -741,13 +838,15 @@ class SigningKey(object):
n = curve.order
if not 1 <= secexp < n:
raise MalformedPointError(
- "Invalid value for secexp, expected integer between 1 and {0}"
- .format(n))
+ "Invalid value for secexp, expected integer "
+ "between 1 and {0}".format(n)
+ )
pubkey_point = curve.generator * secexp
if hasattr(pubkey_point, "scale"):
pubkey_point = pubkey_point.scale()
- self.verifying_key = VerifyingKey.from_public_point(pubkey_point, curve,
- hashfunc, False)
+ self.verifying_key = VerifyingKey.from_public_point(
+ pubkey_point, curve, hashfunc, False
+ )
pubkey = self.verifying_key.pubkey
self.privkey = ecdsa.Private_key(pubkey, secexp)
self.privkey.order = n
@@ -782,8 +881,9 @@ class SigningKey(object):
string = normalise_bytes(string)
if len(string) != curve.baselen:
raise MalformedPointError(
- "Invalid length of private key, received {0}, expected {1}"
- .format(len(string), curve.baselen))
+ "Invalid length of private key, received {0}, "
+ "expected {1}".format(len(string), curve.baselen)
+ )
secexp = string_to_number(string)
return cls.from_secret_exponent(secexp, curve, hashfunc)
@@ -792,16 +892,13 @@ class SigningKey(object):
"""
Initialise from key stored in :term:`PEM` format.
- Note, the only PEM format supported is the un-encrypted RFC5915
- (the sslay format) supported by OpenSSL, the more common PKCS#8 format
- is NOT supported (see:
- https://github.com/warner/python-ecdsa/issues/113 )
-
- ``openssl ec -in pkcs8.pem -out sslay.pem`` can be used to
- convert PKCS#8 file to this legacy format.
+ The PEM formats supported are the un-encrypted RFC5915
+ (the ssleay format) supported by OpenSSL, and the more common
+ un-encrypted RFC5958 (the PKCS #8 format).
The legacy format files have the header with the string
``BEGIN EC PRIVATE KEY``.
+ PKCS#8 files have the header ``BEGIN PRIVATE KEY``.
Encrypted files (ones that include the string
``Proc-Type: 4,ENCRYPTED``
right after the PEM header) are not supported.
@@ -818,31 +915,32 @@ class SigningKey(object):
key failed
:raises UnexpectedDER: if the encoding of the PEM file is incorrect
- :return: Initialised VerifyingKey object
- :rtype: VerifyingKey
+ :return: Initialised SigningKey object
+ :rtype: SigningKey
"""
- # the privkey pem may have multiple sections, commonly it also has
- # "EC PARAMETERS", we need just "EC PRIVATE KEY".
- if PY3 and isinstance(string, str):
+ if not PY2 and isinstance(string, str):
string = string.encode()
- privkey_pem = string[string.index(b("-----BEGIN EC PRIVATE KEY-----")):]
- return cls.from_der(der.unpem(privkey_pem), hashfunc)
+
+ # The privkey pem may have multiple sections, commonly it also has
+ # "EC PARAMETERS", we need just "EC PRIVATE KEY". PKCS#8 should not
+ # have the "EC PARAMETERS" section; it's just "PRIVATE KEY".
+ private_key_index = string.find(b"-----BEGIN EC PRIVATE KEY-----")
+ if private_key_index == -1:
+ private_key_index = string.index(b"-----BEGIN PRIVATE KEY-----")
+
+ return cls.from_der(der.unpem(string[private_key_index:]), hashfunc)
@classmethod
def from_der(cls, string, hashfunc=sha1):
"""
Initialise from key stored in :term:`DER` format.
- Note, the only DER format supported is the RFC5915
- (the sslay format) supported by OpenSSL, the more common PKCS#8 format
- is NOT supported (see:
- https://github.com/warner/python-ecdsa/issues/113 )
-
- ``openssl ec -in pkcs8.pem -outform der -out sslay.der`` can be
- used to convert PKCS#8 file to this legacy format.
+ The DER formats supported are the un-encrypted RFC5915
+ (the ssleay format) supported by OpenSSL, and the more common
+ un-encrypted RFC5958 (the PKCS #8 format).
- The encoding of the ASN.1 object in those files follows following
- syntax specified in RFC5915::
+ Both formats contain an ASN.1 object following the syntax specified
+ in RFC5915::
ECPrivateKey ::= SEQUENCE {
version INTEGER { ecPrivkeyVer1(1) }} (ecPrivkeyVer1),
@@ -851,14 +949,30 @@ class SigningKey(object):
publicKey [1] BIT STRING OPTIONAL
}
+ `publicKey` field is ignored completely (errors, if any, in it will
+ be undetected).
+
The only format supported for the `parameters` field is the named
curve method. Explicit encoding of curve parameters is not supported.
+ In the legacy ssleay format, this implementation requires the optional
+ `parameters` field to get the curve name. In PKCS #8 format, the curve
+ is part of the PrivateKeyAlgorithmIdentifier.
+
+ The PKCS #8 format includes an ECPrivateKey object as the `privateKey`
+ field within a larger structure:
+
+ OneAsymmetricKey ::= SEQUENCE {
+ version Version,
+ privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
+ privateKey PrivateKey,
+ attributes [0] Attributes OPTIONAL,
+ ...,
+ [[2: publicKey [1] PublicKey OPTIONAL ]],
+ ...
+ }
- While `parameters` field is defined as optional, this implementation
- requires its presence for correct parsing of the keys.
-
- `publicKey` field is ignored completely (errors, if any, in it will
- be undetected).
+ The `attributes` and `publicKey` fields are completely ignored; errors
+ in them will not be detected.
:param string: binary string with DER-encoded private ECDSA key
:type string: bytes like object
@@ -869,28 +983,83 @@ class SigningKey(object):
key failed
:raises UnexpectedDER: if the encoding of the DER file is incorrect
- :return: Initialised VerifyingKey object
- :rtype: VerifyingKey
+ :return: Initialised SigningKey object
+ :rtype: SigningKey
"""
- string = normalise_bytes(string)
- s, empty = der.remove_sequence(string)
+ s = normalise_bytes(string)
+ curve = None
+
+ s, empty = der.remove_sequence(s)
if empty != b(""):
- raise der.UnexpectedDER("trailing junk after DER privkey: %s" %
- binascii.hexlify(empty))
- one, s = der.remove_integer(s)
- if one != 1:
- raise der.UnexpectedDER("expected '1' at start of DER privkey,"
- " got %d" % one)
+ raise der.UnexpectedDER(
+ "trailing junk after DER privkey: %s" % binascii.hexlify(empty)
+ )
+
+ version, s = der.remove_integer(s)
+
+ # At this point, PKCS #8 has a sequence containing the algorithm
+ # identifier and the curve identifier. The ssleay format instead has
+ # an octet string containing the key data, so this is how we can
+ # distinguish the two formats.
+ if der.is_sequence(s):
+ if version not in (0, 1):
+ raise der.UnexpectedDER(
+ "expected version '0' or '1' at start of privkey, got %d"
+ % version
+ )
+
+ sequence, s = der.remove_sequence(s)
+ algorithm_oid, algorithm_identifier = der.remove_object(sequence)
+ curve_oid, empty = der.remove_object(algorithm_identifier)
+ curve = find_curve(curve_oid)
+
+ if algorithm_oid not in (oid_ecPublicKey, oid_ecDH, oid_ecMQV):
+ raise der.UnexpectedDER(
+ "unexpected algorithm identifier '%s'" % (algorithm_oid,)
+ )
+ if empty != b"":
+ raise der.UnexpectedDER(
+ "unexpected data after algorithm identifier: %s"
+ % binascii.hexlify(empty)
+ )
+
+ # Up next is an octet string containing an ECPrivateKey. Ignore
+ # the optional "attributes" and "publicKey" fields that come after.
+ s, _ = der.remove_octet_string(s)
+
+ # Unpack the ECPrivateKey to get to the key data octet string,
+ # and rejoin the ssleay parsing path.
+ s, empty = der.remove_sequence(s)
+ if empty != b(""):
+ raise der.UnexpectedDER(
+ "trailing junk after DER privkey: %s"
+ % binascii.hexlify(empty)
+ )
+
+ version, s = der.remove_integer(s)
+
+ # The version of the ECPrivateKey must be 1.
+ if version != 1:
+ raise der.UnexpectedDER(
+ "expected version '1' at start of DER privkey, got %d"
+ % version
+ )
+
privkey_str, s = der.remove_octet_string(s)
- tag, curve_oid_str, s = der.remove_constructed(s)
- if tag != 0:
- raise der.UnexpectedDER("expected tag 0 in DER privkey,"
- " got %d" % tag)
- curve_oid, empty = der.remove_object(curve_oid_str)
- if empty != b(""):
- raise der.UnexpectedDER("trailing junk after DER privkey "
- "curve_oid: %s" % binascii.hexlify(empty))
- curve = find_curve(curve_oid)
+
+ if not curve:
+ tag, curve_oid_str, s = der.remove_constructed(s)
+ if tag != 0:
+ raise der.UnexpectedDER(
+ "expected tag 0 in DER privkey, got %d" % tag
+ )
+ curve_oid, empty = der.remove_object(curve_oid_str)
+ if empty != b(""):
+ raise der.UnexpectedDER(
+ "trailing junk after DER privkey "
+ "curve_oid: %s" % binascii.hexlify(empty)
+ )
+ curve = find_curve(curve_oid)
# we don't actually care about the following fields
#
@@ -901,11 +1070,14 @@ class SigningKey(object):
# pubkey_str = der.remove_bitstring(pubkey_bitstring, 0)
# if empty != "":
# raise der.UnexpectedDER("trailing junk after DER privkey "
- # "pubkeystr: %s" % binascii.hexlify(empty))
+ # "pubkeystr: %s"
+ # % binascii.hexlify(empty))
# our from_string method likes fixed-length privkey strings
if len(privkey_str) < curve.baselen:
- privkey_str = b("\x00") * (curve.baselen - len(privkey_str)) + privkey_str
+ privkey_str = (
+ b("\x00") * (curve.baselen - len(privkey_str)) + privkey_str
+ )
return cls.from_string(privkey_str, curve, hashfunc)
def to_string(self):
@@ -923,7 +1095,7 @@ class SigningKey(object):
s = number_to_string(secexp, self.privkey.order)
return s
- def to_pem(self, point_encoding="uncompressed"):
+ def to_pem(self, point_encoding="uncompressed", format="ssleay"):
"""
Convert the private key to the :term:`PEM` format.
@@ -932,17 +1104,24 @@ class SigningKey(object):
Only the named curve format is supported.
The public key will be included in generated string.
- The PEM header will specify ``BEGIN EC PRIVATE KEY``
+ The PEM header will specify ``BEGIN EC PRIVATE KEY`` or
+ ``BEGIN PRIVATE KEY``, depending on the desired format.
:param str point_encoding: format to use for encoding public point
+ :param str format: either ``ssleay`` (default) or ``pkcs8``
:return: PEM encoded private key
- :rtype: str
+ :rtype: bytes
+
+ .. warning:: The PEM is encoded to US-ASCII, it needs to be
+ re-encoded if the system is incompatible (e.g. uses UTF-16)
"""
# TODO: "BEGIN ECPARAMETERS"
- return der.topem(self.to_der(point_encoding), "EC PRIVATE KEY")
+ assert format in ("ssleay", "pkcs8")
+ header = "EC PRIVATE KEY" if format == "ssleay" else "PRIVATE KEY"
+ return der.topem(self.to_der(point_encoding, format), header)
- def to_der(self, point_encoding="uncompressed"):
+ def to_der(self, point_encoding="uncompressed", format="ssleay"):
"""
Convert the private key to the :term:`DER` format.
@@ -952,6 +1131,7 @@ class SigningKey(object):
The public key will be included in the generated string.
:param str point_encoding: format to use for encoding public point
+ :param str format: either ``ssleay`` (default) or ``pkcs8``
:return: DER encoded private key
:rtype: bytes
@@ -960,14 +1140,29 @@ class SigningKey(object):
# cont[1],bitstring])
if point_encoding == "raw":
raise ValueError("raw encoding not allowed in DER")
+ assert format in ("ssleay", "pkcs8")
encoded_vk = self.get_verifying_key().to_string(point_encoding)
# the 0 in encode_bitstring specifies the number of unused bits
# in the `encoded_vk` string
- return der.encode_sequence(
+ ec_private_key = der.encode_sequence(
der.encode_integer(1),
der.encode_octet_string(self.to_string()),
der.encode_constructed(0, self.curve.encoded_oid),
- der.encode_constructed(1, der.encode_bitstring(encoded_vk, 0)))
+ der.encode_constructed(1, der.encode_bitstring(encoded_vk, 0)),
+ )
+
+ if format == "ssleay":
+ return ec_private_key
+ else:
+ return der.encode_sequence(
+ # version = 1 means the public key is not present in the
+ # top-level structure.
+ der.encode_integer(1),
+ der.encode_sequence(
+ der.encode_oid(*oid_ecPublicKey), self.curve.encoded_oid
+ ),
+ der.encode_octet_string(ec_private_key),
+ )
def get_verifying_key(self):
"""
@@ -981,9 +1176,13 @@ class SigningKey(object):
"""
return self.verifying_key
- def sign_deterministic(self, data, hashfunc=None,
- sigencode=sigencode_string,
- extra_entropy=b''):
+ def sign_deterministic(
+ self,
+ data,
+ hashfunc=None,
+ sigencode=sigencode_string,
+ extra_entropy=b"",
+ ):
"""
Create signature over data using the deterministic RFC6679 algorithm.
@@ -1020,12 +1219,21 @@ class SigningKey(object):
digest = hashfunc(data).digest()
return self.sign_digest_deterministic(
- digest, hashfunc=hashfunc, sigencode=sigencode,
- extra_entropy=extra_entropy, allow_truncate=True)
-
- def sign_digest_deterministic(self, digest, hashfunc=None,
- sigencode=sigencode_string,
- extra_entropy=b'', allow_truncate=False):
+ digest,
+ hashfunc=hashfunc,
+ sigencode=sigencode,
+ extra_entropy=extra_entropy,
+ allow_truncate=True,
+ )
+
+ def sign_digest_deterministic(
+ self,
+ digest,
+ hashfunc=None,
+ sigencode=sigencode_string,
+ extra_entropy=b"",
+ allow_truncate=False,
+ ):
"""
Create signature for digest using the deterministic RFC6679 algorithm.
@@ -1073,21 +1281,35 @@ class SigningKey(object):
retry_gen = 0
while True:
k = rfc6979.generate_k(
- self.curve.generator.order(), secexp, hashfunc, digest,
- retry_gen=retry_gen, extra_entropy=extra_entropy)
+ self.curve.generator.order(),
+ secexp,
+ hashfunc,
+ digest,
+ retry_gen=retry_gen,
+ extra_entropy=extra_entropy,
+ )
try:
- r, s, order = self.sign_digest(digest,
- sigencode=simple_r_s,
- k=k,
- allow_truncate=allow_truncate)
+ r, s, order = self.sign_digest(
+ digest,
+ sigencode=simple_r_s,
+ k=k,
+ allow_truncate=allow_truncate,
+ )
break
except RSZeroError:
retry_gen += 1
return sigencode(r, s, order)
- def sign(self, data, entropy=None, hashfunc=None,
- sigencode=sigencode_string, k=None):
+ def sign(
+ self,
+ data,
+ entropy=None,
+ hashfunc=None,
+ sigencode=sigencode_string,
+ k=None,
+ allow_truncate=True,
+ ):
"""
Create signature over data using the probabilistic ECDSA algorithm.
@@ -1123,6 +1345,11 @@ class SigningKey(object):
:param int k: a pre-selected nonce for calculating the signature.
In typical use cases, it should be set to None (the default) to
allow its generation from an entropy source.
+ :param bool allow_truncate: if True, the provided digest can have
+ bigger bit-size than the order of the curve, the extra bits (at
+ the end of the digest) will be truncated. Use it when signing
+ SHA-384 output using NIST256p or in similar situations. True by
+ default.
:raises RSZeroError: in the unlikely event when "r" parameter or
"s" parameter is equal 0 as that would leak the key. Calee should
@@ -1134,10 +1361,16 @@ class SigningKey(object):
hashfunc = hashfunc or self.default_hashfunc
data = normalise_bytes(data)
h = hashfunc(data).digest()
- return self.sign_digest(h, entropy, sigencode, k, allow_truncate=True)
-
- def sign_digest(self, digest, entropy=None, sigencode=sigencode_string,
- k=None, allow_truncate=False):
+ return self.sign_digest(h, entropy, sigencode, k, allow_truncate)
+
+ def sign_digest(
+ self,
+ digest,
+ entropy=None,
+ sigencode=sigencode_string,
+ k=None,
+ allow_truncate=False,
+ ):
"""
Create signature over digest using the probabilistic ECDSA algorithm.
@@ -1177,11 +1410,12 @@ class SigningKey(object):
"""
digest = normalise_bytes(digest)
if allow_truncate:
- digest = digest[:self.curve.baselen]
+ digest = digest[: self.curve.baselen]
if len(digest) > self.curve.baselen:
- raise BadDigestError("this curve (%s) is too short "
- "for your digest (%d)" % (self.curve.name,
- 8 * len(digest)))
+ raise BadDigestError(
+ "this curve (%s) is too short "
+ "for your digest (%d)" % (self.curve.name, 8 * len(digest))
+ )
number = string_to_number(digest)
r, s = self.sign_number(number, entropy, k)
return sigencode(r, s, self.privkey.order)
diff --git a/frozen_deps/ecdsa/numbertheory.py b/frozen_deps/ecdsa/numbertheory.py
new file mode 100644
index 0000000..e5cc888
--- /dev/null
+++ b/frozen_deps/ecdsa/numbertheory.py
@@ -0,0 +1,810 @@
+#! /usr/bin/env python
+#
+# Provide some simple capabilities from number theory.
+#
+# Version of 2008.11.14.
+#
+# Written in 2005 and 2006 by Peter Pearson and placed in the public domain.
+# Revision history:
+# 2008.11.14: Use pow(base, exponent, modulus) for modular_exp.
+# Make gcd and lcm accept arbitrarly many arguments.
+
+from __future__ import division
+
+from six import integer_types, PY2
+from six.moves import reduce
+
+try:
+ xrange
+except NameError:
+ xrange = range
+try:
+ from gmpy2 import powmod
+
+ GMPY2 = True
+ GMPY = False
+except ImportError:
+ GMPY2 = False
+ try:
+ from gmpy import mpz
+
+ GMPY = True
+ except ImportError:
+ GMPY = False
+
+import math
+import warnings
+
+
+class Error(Exception):
+ """Base class for exceptions in this module."""
+
+ pass
+
+
+class SquareRootError(Error):
+ pass
+
+
+class NegativeExponentError(Error):
+ pass
+
+
+def modular_exp(base, exponent, modulus): # pragma: no cover
+ """Raise base to exponent, reducing by modulus"""
+ # deprecated in 0.14
+ warnings.warn(
+ "Function is unused in library code. If you use this code, "
+ "change to pow() builtin.",
+ DeprecationWarning,
+ )
+ if exponent < 0:
+ raise NegativeExponentError(
+ "Negative exponents (%d) not allowed" % exponent
+ )
+ return pow(base, exponent, modulus)
+
+
+def polynomial_reduce_mod(poly, polymod, p):
+ """Reduce poly by polymod, integer arithmetic modulo p.
+
+ Polynomials are represented as lists of coefficients
+ of increasing powers of x."""
+
+ # This module has been tested only by extensive use
+ # in calculating modular square roots.
+
+ # Just to make this easy, require a monic polynomial:
+ assert polymod[-1] == 1
+
+ assert len(polymod) > 1
+
+ while len(poly) >= len(polymod):
+ if poly[-1] != 0:
+ for i in xrange(2, len(polymod) + 1):
+ poly[-i] = (poly[-i] - poly[-1] * polymod[-i]) % p
+ poly = poly[0:-1]
+
+ return poly
+
+
+def polynomial_multiply_mod(m1, m2, polymod, p):
+ """Polynomial multiplication modulo a polynomial over ints mod p.
+
+ Polynomials are represented as lists of coefficients
+ of increasing powers of x."""
+
+ # This is just a seat-of-the-pants implementation.
+
+ # This module has been tested only by extensive use
+ # in calculating modular square roots.
+
+ # Initialize the product to zero:
+
+ prod = (len(m1) + len(m2) - 1) * [0]
+
+ # Add together all the cross-terms:
+
+ for i in xrange(len(m1)):
+ for j in xrange(len(m2)):
+ prod[i + j] = (prod[i + j] + m1[i] * m2[j]) % p
+
+ return polynomial_reduce_mod(prod, polymod, p)
+
+
+def polynomial_exp_mod(base, exponent, polymod, p):
+ """Polynomial exponentiation modulo a polynomial over ints mod p.
+
+ Polynomials are represented as lists of coefficients
+ of increasing powers of x."""
+
+ # Based on the Handbook of Applied Cryptography, algorithm 2.227.
+
+ # This module has been tested only by extensive use
+ # in calculating modular square roots.
+
+ assert exponent < p
+
+ if exponent == 0:
+ return [1]
+
+ G = base
+ k = exponent
+ if k % 2 == 1:
+ s = G
+ else:
+ s = [1]
+
+ while k > 1:
+ k = k // 2
+ G = polynomial_multiply_mod(G, G, polymod, p)
+ if k % 2 == 1:
+ s = polynomial_multiply_mod(G, s, polymod, p)
+
+ return s
+
+
+def jacobi(a, n):
+ """Jacobi symbol"""
+
+ # Based on the Handbook of Applied Cryptography (HAC), algorithm 2.149.
+
+ # This function has been tested by comparison with a small
+ # table printed in HAC, and by extensive use in calculating
+ # modular square roots.
+
+ assert n >= 3
+ assert n % 2 == 1
+ a = a % n
+ if a == 0:
+ return 0
+ if a == 1:
+ return 1
+ a1, e = a, 0
+ while a1 % 2 == 0:
+ a1, e = a1 // 2, e + 1
+ if e % 2 == 0 or n % 8 == 1 or n % 8 == 7:
+ s = 1
+ else:
+ s = -1
+ if a1 == 1:
+ return s
+ if n % 4 == 3 and a1 % 4 == 3:
+ s = -s
+ return s * jacobi(n % a1, a1)
+
+
+def square_root_mod_prime(a, p):
+ """Modular square root of a, mod p, p prime."""
+
+ # Based on the Handbook of Applied Cryptography, algorithms 3.34 to 3.39.
+
+ # This module has been tested for all values in [0,p-1] for
+ # every prime p from 3 to 1229.
+
+ assert 0 <= a < p
+ assert 1 < p
+
+ if a == 0:
+ return 0
+ if p == 2:
+ return a
+
+ jac = jacobi(a, p)
+ if jac == -1:
+ raise SquareRootError("%d has no square root modulo %d" % (a, p))
+
+ if p % 4 == 3:
+ return pow(a, (p + 1) // 4, p)
+
+ if p % 8 == 5:
+ d = pow(a, (p - 1) // 4, p)
+ if d == 1:
+ return pow(a, (p + 3) // 8, p)
+ if d == p - 1:
+ return (2 * a * pow(4 * a, (p - 5) // 8, p)) % p
+ raise RuntimeError("Shouldn't get here.")
+
+ if PY2:
+ # xrange on python2 can take integers representable as C long only
+ range_top = min(0x7FFFFFFF, p)
+ else:
+ range_top = p
+ for b in xrange(2, range_top):
+ if jacobi(b * b - 4 * a, p) == -1:
+ f = (a, -b, 1)
+ ff = polynomial_exp_mod((0, 1), (p + 1) // 2, f, p)
+ assert ff[1] == 0
+ return ff[0]
+ raise RuntimeError("No b found.")
+
+
+if GMPY2:
+
+ def inverse_mod(a, m):
+ """Inverse of a mod m."""
+ if a == 0:
+ return 0
+ return powmod(a, -1, m)
+
+
+elif GMPY:
+
+ def inverse_mod(a, m):
+ """Inverse of a mod m."""
+ # while libgmp likely does support inverses modulo, it is accessible
+ # only using the native `pow()` function, and `pow()` sanity checks
+ # the parameters before passing them on to underlying implementation
+ # on Python2
+ if a == 0:
+ return 0
+ a = mpz(a)
+ m = mpz(m)
+
+ lm, hm = mpz(1), mpz(0)
+ low, high = a % m, m
+ while low > 1:
+ r = high // low
+ lm, low, hm, high = hm - lm * r, high - low * r, lm, low
+
+ return lm % m
+
+
+else:
+
+ def inverse_mod(a, m):
+ """Inverse of a mod m."""
+
+ if a == 0:
+ return 0
+
+ lm, hm = 1, 0
+ low, high = a % m, m
+ while low > 1:
+ r = high // low
+ lm, low, hm, high = hm - lm * r, high - low * r, lm, low
+
+ return lm % m
+
+
+try:
+ gcd2 = math.gcd
+except AttributeError:
+
+ def gcd2(a, b):
+ """Greatest common divisor using Euclid's algorithm."""
+ while a:
+ a, b = b % a, a
+ return b
+
+
+def gcd(*a):
+ """Greatest common divisor.
+
+ Usage: gcd([ 2, 4, 6 ])
+ or: gcd(2, 4, 6)
+ """
+
+ if len(a) > 1:
+ return reduce(gcd2, a)
+ if hasattr(a[0], "__iter__"):
+ return reduce(gcd2, a[0])
+ return a[0]
+
+
+def lcm2(a, b):
+ """Least common multiple of two integers."""
+
+ return (a * b) // gcd(a, b)
+
+
+def lcm(*a):
+ """Least common multiple.
+
+ Usage: lcm([ 3, 4, 5 ])
+ or: lcm(3, 4, 5)
+ """
+
+ if len(a) > 1:
+ return reduce(lcm2, a)
+ if hasattr(a[0], "__iter__"):
+ return reduce(lcm2, a[0])
+ return a[0]
+
+
+def factorization(n):
+ """Decompose n into a list of (prime,exponent) pairs."""
+
+ assert isinstance(n, integer_types)
+
+ if n < 2:
+ return []
+
+ result = []
+ d = 2
+
+ # Test the small primes:
+
+ for d in smallprimes:
+ if d > n:
+ break
+ q, r = divmod(n, d)
+ if r == 0:
+ count = 1
+ while d <= n:
+ n = q
+ q, r = divmod(n, d)
+ if r != 0:
+ break
+ count = count + 1
+ result.append((d, count))
+
+ # If n is still greater than the last of our small primes,
+ # it may require further work:
+
+ if n > smallprimes[-1]:
+ if is_prime(n): # If what's left is prime, it's easy:
+ result.append((n, 1))
+ else: # Ugh. Search stupidly for a divisor:
+ d = smallprimes[-1]
+ while 1:
+ d = d + 2 # Try the next divisor.
+ q, r = divmod(n, d)
+ if q < d: # n < d*d means we're done, n = 1 or prime.
+ break
+ if r == 0: # d divides n. How many times?
+ count = 1
+ n = q
+ while d <= n: # As long as d might still divide n,
+ q, r = divmod(n, d) # see if it does.
+ if r != 0:
+ break
+ n = q # It does. Reduce n, increase count.
+ count = count + 1
+ result.append((d, count))
+ if n > 1:
+ result.append((n, 1))
+
+ return result
+
+
+def phi(n): # pragma: no cover
+ """Return the Euler totient function of n."""
+ # deprecated in 0.14
+ warnings.warn(
+ "Function is unused by library code. If you use this code, "
+ "please open an issue in "
+ "https://github.com/warner/python-ecdsa",
+ DeprecationWarning,
+ )
+
+ assert isinstance(n, integer_types)
+
+ if n < 3:
+ return 1
+
+ result = 1
+ ff = factorization(n)
+ for f in ff:
+ e = f[1]
+ if e > 1:
+ result = result * f[0] ** (e - 1) * (f[0] - 1)
+ else:
+ result = result * (f[0] - 1)
+ return result
+
+
+def carmichael(n): # pragma: no cover
+ """Return Carmichael function of n.
+
+ Carmichael(n) is the smallest integer x such that
+ m**x = 1 mod n for all m relatively prime to n.
+ """
+ # deprecated in 0.14
+ warnings.warn(
+ "Function is unused by library code. If you use this code, "
+ "please open an issue in "
+ "https://github.com/warner/python-ecdsa",
+ DeprecationWarning,
+ )
+
+ return carmichael_of_factorized(factorization(n))
+
+
+def carmichael_of_factorized(f_list): # pragma: no cover
+ """Return the Carmichael function of a number that is
+ represented as a list of (prime,exponent) pairs.
+ """
+ # deprecated in 0.14
+ warnings.warn(
+ "Function is unused by library code. If you use this code, "
+ "please open an issue in "
+ "https://github.com/warner/python-ecdsa",
+ DeprecationWarning,
+ )
+
+ if len(f_list) < 1:
+ return 1
+
+ result = carmichael_of_ppower(f_list[0])
+ for i in xrange(1, len(f_list)):
+ result = lcm(result, carmichael_of_ppower(f_list[i]))
+
+ return result
+
+
+def carmichael_of_ppower(pp): # pragma: no cover
+ """Carmichael function of the given power of the given prime."""
+ # deprecated in 0.14
+ warnings.warn(
+ "Function is unused by library code. If you use this code, "
+ "please open an issue in "
+ "https://github.com/warner/python-ecdsa",
+ DeprecationWarning,
+ )
+
+ p, a = pp
+ if p == 2 and a > 2:
+ return 2 ** (a - 2)
+ else:
+ return (p - 1) * p ** (a - 1)
+
+
+def order_mod(x, m): # pragma: no cover
+ """Return the order of x in the multiplicative group mod m."""
+ # deprecated in 0.14
+ warnings.warn(
+ "Function is unused by library code. If you use this code, "
+ "please open an issue in "
+ "https://github.com/warner/python-ecdsa",
+ DeprecationWarning,
+ )
+
+ # Warning: this implementation is not very clever, and will
+ # take a long time if m is very large.
+
+ if m <= 1:
+ return 0
+
+ assert gcd(x, m) == 1
+
+ z = x
+ result = 1
+ while z != 1:
+ z = (z * x) % m
+ result = result + 1
+ return result
+
+
+def largest_factor_relatively_prime(a, b): # pragma: no cover
+ """Return the largest factor of a relatively prime to b."""
+ # deprecated in 0.14
+ warnings.warn(
+ "Function is unused by library code. If you use this code, "
+ "please open an issue in "
+ "https://github.com/warner/python-ecdsa",
+ DeprecationWarning,
+ )
+
+ while 1:
+ d = gcd(a, b)
+ if d <= 1:
+ break
+ b = d
+ while 1:
+ q, r = divmod(a, d)
+ if r > 0:
+ break
+ a = q
+ return a
+
+
+def kinda_order_mod(x, m): # pragma: no cover
+ """Return the order of x in the multiplicative group mod m',
+ where m' is the largest factor of m relatively prime to x.
+ """
+ # deprecated in 0.14
+ warnings.warn(
+ "Function is unused by library code. If you use this code, "
+ "please open an issue in "
+ "https://github.com/warner/python-ecdsa",
+ DeprecationWarning,
+ )
+
+ return order_mod(x, largest_factor_relatively_prime(m, x))
+
+
+def is_prime(n):
+ """Return True if x is prime, False otherwise.
+
+ We use the Miller-Rabin test, as given in Menezes et al. p. 138.
+ This test is not exact: there are composite values n for which
+ it returns True.
+
+ In testing the odd numbers from 10000001 to 19999999,
+ about 66 composites got past the first test,
+ 5 got past the second test, and none got past the third.
+ Since factors of 2, 3, 5, 7, and 11 were detected during
+ preliminary screening, the number of numbers tested by
+ Miller-Rabin was (19999999 - 10000001)*(2/3)*(4/5)*(6/7)
+ = 4.57 million.
+ """
+
+ # (This is used to study the risk of false positives:)
+ global miller_rabin_test_count
+
+ miller_rabin_test_count = 0
+
+ if n <= smallprimes[-1]:
+ if n in smallprimes:
+ return True
+ else:
+ return False
+
+ if gcd(n, 2 * 3 * 5 * 7 * 11) != 1:
+ return False
+
+ # Choose a number of iterations sufficient to reduce the
+ # probability of accepting a composite below 2**-80
+ # (from Menezes et al. Table 4.4):
+
+ t = 40
+ n_bits = 1 + int(math.log(n, 2))
+ for k, tt in (
+ (100, 27),
+ (150, 18),
+ (200, 15),
+ (250, 12),
+ (300, 9),
+ (350, 8),
+ (400, 7),
+ (450, 6),
+ (550, 5),
+ (650, 4),
+ (850, 3),
+ (1300, 2),
+ ):
+ if n_bits < k:
+ break
+ t = tt
+
+ # Run the test t times:
+
+ s = 0
+ r = n - 1
+ while (r % 2) == 0:
+ s = s + 1
+ r = r // 2
+ for i in xrange(t):
+ a = smallprimes[i]
+ y = pow(a, r, n)
+ if y != 1 and y != n - 1:
+ j = 1
+ while j <= s - 1 and y != n - 1:
+ y = pow(y, 2, n)
+ if y == 1:
+ miller_rabin_test_count = i + 1
+ return False
+ j = j + 1
+ if y != n - 1:
+ miller_rabin_test_count = i + 1
+ return False
+ return True
+
+
+def next_prime(starting_value):
+ """Return the smallest prime larger than the starting value."""
+
+ if starting_value < 2:
+ return 2
+ result = (starting_value + 1) | 1
+ while not is_prime(result):
+ result = result + 2
+ return result
+
+
+smallprimes = [
+ 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,
+]
+
+miller_rabin_test_count = 0
diff --git a/freezed_deps/ecdsa/rfc6979.py b/frozen_deps/ecdsa/rfc6979.py
index a489381..1e577c0 100644
--- a/freezed_deps/ecdsa/rfc6979.py
+++ b/frozen_deps/ecdsa/rfc6979.py
@@ -1,4 +1,4 @@
-'''
+"""
RFC 6979:
Deterministic Usage of the Digital Signature Algorithm (DSA) and
Elliptic Curve Digital Signature Algorithm (ECDSA)
@@ -7,7 +7,7 @@ RFC 6979:
Many thanks to Coda Hale for his implementation in Go language:
https://github.com/codahale/rfc6979
-'''
+"""
import hmac
from binascii import hexlify
@@ -40,34 +40,37 @@ def bits2octets(data, order):
# https://tools.ietf.org/html/rfc6979#section-3.2
-def generate_k(order, secexp, hash_func, data, retry_gen=0, extra_entropy=b''):
- '''
+def generate_k(order, secexp, hash_func, data, retry_gen=0, extra_entropy=b""):
+ """
order - order of the DSA generator used in the signature
secexp - secure exponent (private key) in numeric form
- hash_func - reference to the same hash function used for generating hash
+ hash_func - reference to the same hash function used for generating
+ hash
data - hash in binary form of the signing data
retry_gen - int - how many good 'k' values to skip before returning
extra_entropy - extra added data in binary form as per section-3.6 of
rfc6979
- '''
+ """
qlen = bit_length(order)
holen = hash_func().digest_size
- rolen = (qlen + 7) / 8
- bx = (hmac_compat(number_to_string(secexp, order)),
- hmac_compat(bits2octets(data, order)),
- hmac_compat(extra_entropy))
+ rolen = (qlen + 7) // 8
+ bx = (
+ hmac_compat(number_to_string(secexp, order)),
+ hmac_compat(bits2octets(data, order)),
+ hmac_compat(extra_entropy),
+ )
# Step B
- v = b'\x01' * holen
+ v = b"\x01" * holen
# Step C
- k = b'\x00' * holen
+ k = b"\x00" * holen
# Step D
k = hmac.new(k, digestmod=hash_func)
- k.update(v + b'\x00')
+ k.update(v + b"\x00")
for i in bx:
k.update(i)
k = k.digest()
@@ -77,7 +80,7 @@ def generate_k(order, secexp, hash_func, data, retry_gen=0, extra_entropy=b''):
# Step F
k = hmac.new(k, digestmod=hash_func)
- k.update(v + b'\x01')
+ k.update(v + b"\x01")
for i in bx:
k.update(i)
k = k.digest()
@@ -88,7 +91,7 @@ def generate_k(order, secexp, hash_func, data, retry_gen=0, extra_entropy=b''):
# Step H
while True:
# Step H1
- t = b''
+ t = b""
# Step H2
while len(t) < rolen:
@@ -103,5 +106,5 @@ def generate_k(order, secexp, hash_func, data, retry_gen=0, extra_entropy=b''):
return secret
retry_gen -= 1
- k = hmac.new(k, v + b'\x00', hash_func).digest()
+ k = hmac.new(k, v + b"\x00", hash_func).digest()
v = hmac.new(k, v, hash_func).digest()
diff --git a/freezed_deps/ecdsa/test_der.py b/frozen_deps/ecdsa/test_der.py
index e6cd593..746d927 100644
--- a/freezed_deps/ecdsa/test_der.py
+++ b/frozen_deps/ecdsa/test_der.py
@@ -1,8 +1,8 @@
-
# compatibility with Python 2.6, for that we need unittest2 package,
# which is not available on 3.3 or 3.4
import warnings
from binascii import hexlify
+
try:
import unittest2 as unittest
except ImportError:
@@ -13,8 +13,15 @@ from hypothesis import given, example
import pytest
from ._compat import str_idx_as_int
from .curves import NIST256p, NIST224p
-from .der import remove_integer, UnexpectedDER, read_length, encode_bitstring,\
- remove_bitstring, remove_object, encode_oid
+from .der import (
+ remove_integer,
+ UnexpectedDER,
+ read_length,
+ encode_bitstring,
+ remove_bitstring,
+ remove_object,
+ encode_oid,
+)
class TestRemoveInteger(unittest.TestCase):
@@ -22,44 +29,44 @@ class TestRemoveInteger(unittest.TestCase):
# interpreted as negative, check if those errors are detected
def test_non_minimal_encoding(self):
with self.assertRaises(UnexpectedDER):
- remove_integer(b('\x02\x02\x00\x01'))
+ remove_integer(b("\x02\x02\x00\x01"))
def test_negative_with_high_bit_set(self):
with self.assertRaises(UnexpectedDER):
- remove_integer(b('\x02\x01\x80'))
+ remove_integer(b("\x02\x01\x80"))
def test_minimal_with_high_bit_set(self):
- val, rem = remove_integer(b('\x02\x02\x00\x80'))
+ val, rem = remove_integer(b("\x02\x02\x00\x80"))
self.assertEqual(val, 0x80)
self.assertFalse(rem)
def test_two_zero_bytes_with_high_bit_set(self):
with self.assertRaises(UnexpectedDER):
- remove_integer(b('\x02\x03\x00\x00\xff'))
+ remove_integer(b("\x02\x03\x00\x00\xff"))
def test_zero_length_integer(self):
with self.assertRaises(UnexpectedDER):
- remove_integer(b('\x02\x00'))
+ remove_integer(b("\x02\x00"))
def test_empty_string(self):
with self.assertRaises(UnexpectedDER):
- remove_integer(b(''))
+ remove_integer(b(""))
def test_encoding_of_zero(self):
- val, rem = remove_integer(b('\x02\x01\x00'))
+ val, rem = remove_integer(b("\x02\x01\x00"))
self.assertEqual(val, 0)
self.assertFalse(rem)
def test_encoding_of_127(self):
- val, rem = remove_integer(b('\x02\x01\x7f'))
+ val, rem = remove_integer(b("\x02\x01\x7f"))
self.assertEqual(val, 127)
self.assertFalse(rem)
def test_encoding_of_128(self):
- val, rem = remove_integer(b('\x02\x02\x00\x80'))
+ val, rem = remove_integer(b("\x02\x02\x00\x80"))
self.assertEqual(val, 128)
self.assertFalse(rem)
@@ -70,37 +77,37 @@ class TestReadLength(unittest.TestCase):
# form and lengths above that encoded with minimal number of bytes
# necessary
def test_zero_length(self):
- self.assertEqual((0, 1), read_length(b('\x00')))
+ self.assertEqual((0, 1), read_length(b("\x00")))
def test_two_byte_zero_length(self):
with self.assertRaises(UnexpectedDER):
- read_length(b('\x81\x00'))
+ read_length(b("\x81\x00"))
def test_two_byte_small_length(self):
with self.assertRaises(UnexpectedDER):
- read_length(b('\x81\x7f'))
+ read_length(b("\x81\x7f"))
def test_long_form_with_zero_length(self):
with self.assertRaises(UnexpectedDER):
- read_length(b('\x80'))
+ read_length(b("\x80"))
def test_smallest_two_byte_length(self):
- self.assertEqual((128, 2), read_length(b('\x81\x80')))
+ self.assertEqual((128, 2), read_length(b("\x81\x80")))
def test_zero_padded_length(self):
with self.assertRaises(UnexpectedDER):
- read_length(b('\x82\x00\x80'))
+ read_length(b("\x82\x00\x80"))
def test_two_three_byte_length(self):
- self.assertEqual((256, 3), read_length(b'\x82\x01\x00'))
+ self.assertEqual((256, 3), read_length(b"\x82\x01\x00"))
def test_empty_string(self):
with self.assertRaises(UnexpectedDER):
- read_length(b(''))
+ read_length(b(""))
def test_length_overflow(self):
with self.assertRaises(UnexpectedDER):
- read_length(b('\x83\x01\x00'))
+ read_length(b("\x83\x01\x00"))
class TestEncodeBitstring(unittest.TestCase):
@@ -109,143 +116,145 @@ class TestEncodeBitstring(unittest.TestCase):
def test_old_call_convention(self):
"""This is the old way to use the function."""
- warnings.simplefilter('always')
+ warnings.simplefilter("always")
with pytest.warns(DeprecationWarning) as warns:
- der = encode_bitstring(b'\x00\xff')
+ der = encode_bitstring(b"\x00\xff")
self.assertEqual(len(warns), 1)
- self.assertIn("unused= needs to be specified",
- warns[0].message.args[0])
+ self.assertIn(
+ "unused= needs to be specified", warns[0].message.args[0]
+ )
- self.assertEqual(der, b'\x03\x02\x00\xff')
+ self.assertEqual(der, b"\x03\x02\x00\xff")
def test_new_call_convention(self):
"""This is how it should be called now."""
- warnings.simplefilter('always')
+ warnings.simplefilter("always")
with pytest.warns(None) as warns:
- der = encode_bitstring(b'\xff', 0)
+ der = encode_bitstring(b"\xff", 0)
# verify that new call convention doesn't raise Warnings
self.assertEqual(len(warns), 0)
- self.assertEqual(der, b'\x03\x02\x00\xff')
+ self.assertEqual(der, b"\x03\x02\x00\xff")
def test_implicit_unused_bits(self):
"""
Writing bit string with already included the number of unused bits.
"""
- warnings.simplefilter('always')
+ warnings.simplefilter("always")
with pytest.warns(None) as warns:
- der = encode_bitstring(b'\x00\xff', None)
+ der = encode_bitstring(b"\x00\xff", None)
# verify that new call convention doesn't raise Warnings
self.assertEqual(len(warns), 0)
- self.assertEqual(der, b'\x03\x02\x00\xff')
+ self.assertEqual(der, b"\x03\x02\x00\xff")
def test_explicit_unused_bits(self):
- der = encode_bitstring(b'\xff\xf0', 4)
+ der = encode_bitstring(b"\xff\xf0", 4)
- self.assertEqual(der, b'\x03\x03\x04\xff\xf0')
+ self.assertEqual(der, b"\x03\x03\x04\xff\xf0")
def test_empty_string(self):
- self.assertEqual(encode_bitstring(b'', 0), b'\x03\x01\x00')
+ self.assertEqual(encode_bitstring(b"", 0), b"\x03\x01\x00")
def test_invalid_unused_count(self):
with self.assertRaises(ValueError):
- encode_bitstring(b'\xff\x00', 8)
+ encode_bitstring(b"\xff\x00", 8)
def test_invalid_unused_with_empty_string(self):
with self.assertRaises(ValueError):
- encode_bitstring(b'', 1)
+ encode_bitstring(b"", 1)
def test_non_zero_padding_bits(self):
with self.assertRaises(ValueError):
- encode_bitstring(b'\xff', 2)
+ encode_bitstring(b"\xff", 2)
class TestRemoveBitstring(unittest.TestCase):
def test_old_call_convention(self):
"""This is the old way to call the function."""
- warnings.simplefilter('always')
+ warnings.simplefilter("always")
with pytest.warns(DeprecationWarning) as warns:
- bits, rest = remove_bitstring(b'\x03\x02\x00\xff')
+ bits, rest = remove_bitstring(b"\x03\x02\x00\xff")
self.assertEqual(len(warns), 1)
- self.assertIn("expect_unused= needs to be specified",
- warns[0].message.args[0])
+ self.assertIn(
+ "expect_unused= needs to be specified", warns[0].message.args[0]
+ )
- self.assertEqual(bits, b'\x00\xff')
- self.assertEqual(rest, b'')
+ self.assertEqual(bits, b"\x00\xff")
+ self.assertEqual(rest, b"")
def test_new_call_convention(self):
- warnings.simplefilter('always')
+ warnings.simplefilter("always")
with pytest.warns(None) as warns:
- bits, rest = remove_bitstring(b'\x03\x02\x00\xff', 0)
+ bits, rest = remove_bitstring(b"\x03\x02\x00\xff", 0)
self.assertEqual(len(warns), 0)
- self.assertEqual(bits, b'\xff')
- self.assertEqual(rest, b'')
+ self.assertEqual(bits, b"\xff")
+ self.assertEqual(rest, b"")
def test_implicit_unexpected_unused(self):
- warnings.simplefilter('always')
+ warnings.simplefilter("always")
with pytest.warns(None) as warns:
- bits, rest = remove_bitstring(b'\x03\x02\x00\xff', None)
+ bits, rest = remove_bitstring(b"\x03\x02\x00\xff", None)
self.assertEqual(len(warns), 0)
- self.assertEqual(bits, (b'\xff', 0))
- self.assertEqual(rest, b'')
+ self.assertEqual(bits, (b"\xff", 0))
+ self.assertEqual(rest, b"")
def test_with_padding(self):
- ret, rest = remove_bitstring(b'\x03\x02\x04\xf0', None)
+ ret, rest = remove_bitstring(b"\x03\x02\x04\xf0", None)
- self.assertEqual(ret, (b'\xf0', 4))
- self.assertEqual(rest, b'')
+ self.assertEqual(ret, (b"\xf0", 4))
+ self.assertEqual(rest, b"")
def test_not_a_bitstring(self):
with self.assertRaises(UnexpectedDER):
- remove_bitstring(b'\x02\x02\x00\xff', None)
+ remove_bitstring(b"\x02\x02\x00\xff", None)
def test_empty_encoding(self):
with self.assertRaises(UnexpectedDER):
- remove_bitstring(b'\x03\x00', None)
+ remove_bitstring(b"\x03\x00", None)
def test_empty_string(self):
with self.assertRaises(UnexpectedDER):
- remove_bitstring(b'', None)
+ remove_bitstring(b"", None)
def test_no_length(self):
with self.assertRaises(UnexpectedDER):
- remove_bitstring(b'\x03', None)
+ remove_bitstring(b"\x03", None)
def test_unexpected_number_of_unused_bits(self):
with self.assertRaises(UnexpectedDER):
- remove_bitstring(b'\x03\x02\x00\xff', 1)
+ remove_bitstring(b"\x03\x02\x00\xff", 1)
def test_invalid_encoding_of_unused_bits(self):
with self.assertRaises(UnexpectedDER):
- remove_bitstring(b'\x03\x03\x08\xff\x00', None)
+ remove_bitstring(b"\x03\x03\x08\xff\x00", None)
def test_invalid_encoding_of_empty_string(self):
with self.assertRaises(UnexpectedDER):
- remove_bitstring(b'\x03\x01\x01', None)
+ remove_bitstring(b"\x03\x01\x01", None)
def test_invalid_padding_bits(self):
with self.assertRaises(UnexpectedDER):
- remove_bitstring(b'\x03\x02\x01\xff', None)
+ remove_bitstring(b"\x03\x02\x01\xff", None)
class TestStrIdxAsInt(unittest.TestCase):
def test_str(self):
- self.assertEqual(115, str_idx_as_int('str', 0))
+ self.assertEqual(115, str_idx_as_int("str", 0))
def test_bytes(self):
- self.assertEqual(115, str_idx_as_int(b'str', 0))
+ self.assertEqual(115, str_idx_as_int(b"str", 0))
def test_bytearray(self):
- self.assertEqual(115, str_idx_as_int(bytearray(b'str'), 0))
+ self.assertEqual(115, str_idx_as_int(bytearray(b"str"), 0))
class TestEncodeOid(unittest.TestCase):
@@ -257,21 +266,22 @@ class TestEncodeOid(unittest.TestCase):
self.assertEqual(hexlify(NIST224p.encoded_oid), b("06052b81040021"))
def test_nist256p_oid(self):
- self.assertEqual(hexlify(NIST256p.encoded_oid),
- b"06082a8648ce3d030107")
+ self.assertEqual(
+ hexlify(NIST256p.encoded_oid), b"06082a8648ce3d030107"
+ )
def test_large_second_subid(self):
# from X.690, section 8.19.5
oid = encode_oid(2, 999, 3)
- self.assertEqual(oid, b'\x06\x03\x88\x37\x03')
+ self.assertEqual(oid, b"\x06\x03\x88\x37\x03")
def test_with_two_subids(self):
oid = encode_oid(2, 999)
- self.assertEqual(oid, b'\x06\x02\x88\x37')
+ self.assertEqual(oid, b"\x06\x02\x88\x37")
def test_zero_zero(self):
oid = encode_oid(0, 0)
- self.assertEqual(oid, b'\x06\x01\x00')
+ self.assertEqual(oid, b"\x06\x01\x00")
def test_with_wrong_types(self):
with self.assertRaises((TypeError, AssertionError)):
@@ -283,7 +293,7 @@ class TestEncodeOid(unittest.TestCase):
def test_small_first_max_second(self):
oid = encode_oid(1, 39)
- self.assertEqual(oid, b'\x06\x01\x4f')
+ self.assertEqual(oid, b"\x06\x01\x4f")
def test_with_invalid_first(self):
with self.assertRaises(AssertionError):
@@ -297,69 +307,69 @@ class TestRemoveObject(unittest.TestCase):
def test_pub_key_oid(self):
oid, rest = remove_object(self.oid_ecPublicKey)
- self.assertEqual(rest, b'')
+ self.assertEqual(rest, b"")
self.assertEqual(oid, (1, 2, 840, 10045, 2, 1))
def test_with_extra_bytes(self):
- oid, rest = remove_object(self.oid_ecPublicKey + b'more')
- self.assertEqual(rest, b'more')
+ oid, rest = remove_object(self.oid_ecPublicKey + b"more")
+ self.assertEqual(rest, b"more")
self.assertEqual(oid, (1, 2, 840, 10045, 2, 1))
def test_with_large_second_subid(self):
# from X.690, section 8.19.5
- oid, rest = remove_object(b'\x06\x03\x88\x37\x03')
- self.assertEqual(rest, b'')
+ oid, rest = remove_object(b"\x06\x03\x88\x37\x03")
+ self.assertEqual(rest, b"")
self.assertEqual(oid, (2, 999, 3))
def test_with_padded_first_subid(self):
with self.assertRaises(UnexpectedDER):
- remove_object(b'\x06\x02\x80\x00')
+ remove_object(b"\x06\x02\x80\x00")
def test_with_padded_second_subid(self):
with self.assertRaises(UnexpectedDER):
- remove_object(b'\x06\x04\x88\x37\x80\x01')
+ remove_object(b"\x06\x04\x88\x37\x80\x01")
def test_with_missing_last_byte_of_multi_byte(self):
with self.assertRaises(UnexpectedDER):
- remove_object(b'\x06\x03\x88\x37\x83')
+ remove_object(b"\x06\x03\x88\x37\x83")
def test_with_two_subids(self):
- oid, rest = remove_object(b'\x06\x02\x88\x37')
- self.assertEqual(rest, b'')
+ oid, rest = remove_object(b"\x06\x02\x88\x37")
+ self.assertEqual(rest, b"")
self.assertEqual(oid, (2, 999))
def test_zero_zero(self):
- oid, rest = remove_object(b'\x06\x01\x00')
- self.assertEqual(rest, b'')
+ oid, rest = remove_object(b"\x06\x01\x00")
+ self.assertEqual(rest, b"")
self.assertEqual(oid, (0, 0))
def test_empty_string(self):
with self.assertRaises(UnexpectedDER):
- remove_object(b'')
+ remove_object(b"")
def test_missing_length(self):
with self.assertRaises(UnexpectedDER):
- remove_object(b'\x06')
+ remove_object(b"\x06")
def test_empty_oid(self):
with self.assertRaises(UnexpectedDER):
- remove_object(b'\x06\x00')
+ remove_object(b"\x06\x00")
def test_empty_oid_overflow(self):
with self.assertRaises(UnexpectedDER):
- remove_object(b'\x06\x01')
+ remove_object(b"\x06\x01")
def test_with_wrong_type(self):
with self.assertRaises(UnexpectedDER):
- remove_object(b'\x04\x02\x88\x37')
+ remove_object(b"\x04\x02\x88\x37")
def test_with_too_long_length(self):
with self.assertRaises(UnexpectedDER):
- remove_object(b'\x06\x03\x88\x37')
+ remove_object(b"\x06\x03\x88\x37")
@st.composite
-def st_oid(draw, max_value=2**512, max_size=50):
+def st_oid(draw, max_value=2 ** 512, max_size=50):
"""
Hypothesis strategy that returns valid OBJECT IDENTIFIERs as tuples
@@ -371,8 +381,11 @@ def st_oid(draw, max_value=2**512, max_size=50):
second = draw(st.integers(min_value=0, max_value=39))
else:
second = draw(st.integers(min_value=0, max_value=max_value))
- rest = draw(st.lists(st.integers(min_value=0, max_value=max_value),
- max_size=max_size))
+ rest = draw(
+ st.lists(
+ st.integers(min_value=0, max_value=max_value), max_size=max_size
+ )
+ )
return (first, second) + tuple(rest)
@@ -380,5 +393,5 @@ def st_oid(draw, max_value=2**512, max_size=50):
def test_oids(ids):
encoded_oid = encode_oid(*ids)
decoded_oid, rest = remove_object(encoded_oid)
- assert rest == b''
+ assert rest == b""
assert decoded_oid == ids
diff --git a/freezed_deps/ecdsa/test_ecdh.py b/frozen_deps/ecdsa/test_ecdh.py
index 74c8bba..caf6835 100644
--- a/freezed_deps/ecdsa/test_ecdh.py
+++ b/frozen_deps/ecdsa/test_ecdh.py
@@ -1,4 +1,3 @@
-
import os
import shutil
import subprocess
@@ -7,12 +6,13 @@ from binascii import hexlify, unhexlify
from .curves import NIST192p, NIST224p, NIST256p, NIST384p, NIST521p
from .curves import curves
-from .ecdh import ECDH, InvalidCurveError, \
- InvalidSharedSecretError, NoKeyError
+from .ecdh import ECDH, InvalidCurveError, InvalidSharedSecretError, NoKeyError
from .keys import SigningKey, VerifyingKey
[email protected]("vcurve", curves, ids=[curve.name for curve in curves])
+ "vcurve", curves, ids=[curve.name for curve in curves]
+)
def test_ecdh_each(vcurve):
ecdh1 = ECDH(curve=vcurve)
ecdh2 = ECDH(curve=vcurve)
@@ -64,7 +64,9 @@ def test_ecdh_invalid_shared_secret_curve():
ecdh1 = ECDH(curve=NIST256p)
ecdh1.generate_private_key()
- ecdh1.load_received_public_key(SigningKey.generate(NIST256p).get_verifying_key())
+ ecdh1.load_received_public_key(
+ SigningKey.generate(NIST256p).get_verifying_key()
+ )
ecdh1.private_key.privkey.secret_multiplier = ecdh1.private_key.curve.order
@@ -84,7 +86,7 @@ def test_ecdh_invalid_shared_secret_curve():
"42ea6dd9969dd2a61fea1aac7f8e98edcc896c6e55857cc0"
"dfbe5d7c61fac88b11811bde328e8a0d12bf01a9d204b523",
"803d8ab2e5b6e6fca715737c3a82f7ce3c783124f6d51cd0",
- id="NIST192p-1"
+ id="NIST192p-1",
),
pytest.param(
NIST192p,
@@ -92,7 +94,7 @@ def test_ecdh_invalid_shared_secret_curve():
"deb5712fa027ac8d2f22c455ccb73a91e17b6512b5e030e7"
"7e2690a02cc9b28708431a29fb54b87b1f0c14e011ac2125",
"c208847568b98835d7312cef1f97f7aa298283152313c29d",
- id="NIST192p-2"
+ id="NIST192p-2",
),
pytest.param(
NIST192p,
@@ -100,7 +102,7 @@ def test_ecdh_invalid_shared_secret_curve():
"4edaa8efc5a0f40f843663ec5815e7762dddc008e663c20f"
"0a9f8dc67a3e60ef6d64b522185d03df1fc0adfd42478279",
"87229107047a3b611920d6e3b2c0c89bea4f49412260b8dd",
- id="NIST192p-3"
+ id="NIST192p-3",
),
pytest.param(
NIST192p,
@@ -108,7 +110,7 @@ def test_ecdh_invalid_shared_secret_curve():
"8887c276edeed3e9e866b46d58d895c73fbd80b63e382e88"
"04c5097ba6645e16206cfb70f7052655947dd44a17f1f9d5",
"eec0bed8fc55e1feddc82158fd6dc0d48a4d796aaf47d46c",
- id="NIST192p-4"
+ id="NIST192p-4",
),
pytest.param(
NIST192p,
@@ -116,7 +118,7 @@ def test_ecdh_invalid_shared_secret_curve():
"0d045f30254adc1fcefa8a5b1f31bf4e739dd327cd18d594"
"542c314e41427c08278a08ce8d7305f3b5b849c72d8aff73",
"716e743b1b37a2cd8479f0a3d5a74c10ba2599be18d7e2f4",
- id="NIST192p-5"
+ id="NIST192p-5",
),
pytest.param(
NIST192p,
@@ -124,7 +126,7 @@ def test_ecdh_invalid_shared_secret_curve():
"fb35ca20d2e96665c51b98e8f6eb3d79113508d8bccd4516"
"368eec0d5bfb847721df6aaff0e5d48c444f74bf9cd8a5a7",
"f67053b934459985a315cb017bf0302891798d45d0e19508",
- id="NIST192p-6"
+ id="NIST192p-6",
),
pytest.param(
NIST224p,
@@ -132,7 +134,7 @@ def test_ecdh_invalid_shared_secret_curve():
"af33cd0629bc7e996320a3f40368f74de8704fa37b8fab69abaae280"
"882092ccbba7930f419a8a4f9bb16978bbc3838729992559a6f2e2d7",
"7d96f9a3bd3c05cf5cc37feb8b9d5209d5c2597464dec3e9983743e8",
- id="NIST224p"
+ id="NIST224p",
),
pytest.param(
NIST256p,
@@ -140,7 +142,7 @@ def test_ecdh_invalid_shared_secret_curve():
"700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287"
"db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac",
"46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b",
- id="NIST256p-1"
+ id="NIST256p-1",
),
pytest.param(
NIST256p,
@@ -148,7 +150,7 @@ def test_ecdh_invalid_shared_secret_curve():
"809f04289c64348c01515eb03d5ce7ac1a8cb9498f5caa50197e58d43a86a7ae"
"b29d84e811197f25eba8f5194092cb6ff440e26d4421011372461f579271cda3",
"057d636096cb80b67a8c038c890e887d1adfa4195e9b3ce241c8a778c59cda67",
- id="NIST256p-2"
+ id="NIST256p-2",
),
pytest.param(
NIST256p,
@@ -156,7 +158,7 @@ def test_ecdh_invalid_shared_secret_curve():
"a2339c12d4a03c33546de533268b4ad667debf458b464d77443636440ee7fec3"
"ef48a3ab26e20220bcda2c1851076839dae88eae962869a497bf73cb66faf536",
"2d457b78b4614132477618a5b077965ec90730a8c81a1c75d6d4ec68005d67ec",
- id="NIST256p-3"
+ id="NIST256p-3",
),
pytest.param(
NIST256p,
@@ -164,7 +166,7 @@ def test_ecdh_invalid_shared_secret_curve():
"df3989b9fa55495719b3cf46dccd28b5153f7808191dd518eff0c3cff2b705ed"
"422294ff46003429d739a33206c8752552c8ba54a270defc06e221e0feaf6ac4",
"96441259534b80f6aee3d287a6bb17b5094dd4277d9e294f8fe73e48bf2a0024",
- id="NIST256p-4"
+ id="NIST256p-4",
),
pytest.param(
NIST256p,
@@ -172,7 +174,7 @@ def test_ecdh_invalid_shared_secret_curve():
"41192d2813e79561e6a1d6f53c8bc1a433a199c835e141b05a74a97b0faeb922"
"1af98cc45e98a7e041b01cf35f462b7562281351c8ebf3ffa02e33a0722a1328",
"19d44c8d63e8e8dd12c22a87b8cd4ece27acdde04dbf47f7f27537a6999a8e62",
- id="NIST256p-5"
+ id="NIST256p-5",
),
pytest.param(
NIST256p,
@@ -180,7 +182,7 @@ def test_ecdh_invalid_shared_secret_curve():
"33e82092a0f1fb38f5649d5867fba28b503172b7035574bf8e5b7100a3052792"
"f2cf6b601e0a05945e335550bf648d782f46186c772c0f20d3cd0d6b8ca14b2f",
"664e45d5bba4ac931cd65d52017e4be9b19a515f669bea4703542a2c525cd3d3",
- id="NIST256p-6"
+ id="NIST256p-6",
),
pytest.param(
NIST384p,
@@ -192,7 +194,7 @@ def test_ecdh_invalid_shared_secret_curve():
"1efedf243451915ed0905a32b060992b468c64766fc8437a",
"5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f4"
"0ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1",
- id="NIST384p"
+ id="NIST384p",
),
pytest.param(
NIST521p,
@@ -204,11 +206,11 @@ def test_ecdh_invalid_shared_secret_curve():
"bde99e0f6716939e632bc8986fa18dccd443a348b6c3e522497955a4f3c302f676",
"005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc5e1fdf90930d5e1366"
"72d72cc770742d1711c3c3a4c334a0ad9759436a4d3c5bf6e74b9578fac148c831",
- id="NIST521p"
+ id="NIST521p",
),
],
)
-def test_ecdh_NIST(curve,privatekey,pubkey,secret):
+def test_ecdh_NIST(curve, privatekey, pubkey, secret):
ecdh = ECDH(curve=curve)
ecdh.load_private_key_bytes(unhexlify(privatekey))
ecdh.load_received_public_key_bytes(unhexlify(pubkey))
@@ -223,19 +225,23 @@ pem_local_private_key = (
"MF8CAQEEGF7IQgvW75JSqULpiQQ8op9WH6Uldw6xxaAKBggqhkjOPQMBAaE0AzIA\n"
"BLiBd9CE7xf15FY5QIAoNg+fWbSk1yZOYtoGUdzkejWkxbRc9RWTQjqLVXucIJnz\n"
"bA==\n"
- "-----END EC PRIVATE KEY-----\n")
+ "-----END EC PRIVATE KEY-----\n"
+)
der_local_private_key = (
"305f02010104185ec8420bd6ef9252a942e989043ca29f561fa525770eb1c5a00a06082a864"
"8ce3d030101a13403320004b88177d084ef17f5e45639408028360f9f59b4a4d7264e62da06"
- "51dce47a35a4c5b45cf51593423a8b557b9c2099f36c")
+ "51dce47a35a4c5b45cf51593423a8b557b9c2099f36c"
+)
pem_remote_public_key = (
"-----BEGIN PUBLIC KEY-----\n"
"MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEuIF30ITvF/XkVjlAgCg2D59ZtKTX\n"
"Jk5i2gZR3OR6NaTFtFz1FZNCOotVe5wgmfNs\n"
- "-----END PUBLIC KEY-----\n")
+ "-----END PUBLIC KEY-----\n"
+)
der_remote_public_key = (
"3049301306072a8648ce3d020106082a8648ce3d03010103320004b88177d084ef17f5e4563"
- "9408028360f9f59b4a4d7264e62da0651dce47a35a4c5b45cf51593423a8b557b9c2099f36c")
+ "9408028360f9f59b4a4d7264e62da0651dce47a35a4c5b45cf51593423a8b557b9c2099f36c"
+)
gshared_secret = "8f457e34982478d1c34b9cd2d0c15911b72dd60d869e2cea"
@@ -266,23 +272,29 @@ class RunOpenSslError(Exception):
def run_openssl(cmd):
OPENSSL = "openssl"
- p = subprocess.Popen([OPENSSL] + cmd.split(),
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
+ p = subprocess.Popen(
+ [OPENSSL] + cmd.split(),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ )
stdout, ignored = p.communicate()
if p.returncode != 0:
raise RunOpenSslError(
- "cmd '%s %s' failed: rc=%s, stdout/err was %s" %
- (OPENSSL, cmd, p.returncode, stdout))
+ "cmd '%s %s' failed: rc=%s, stdout/err was %s"
+ % (OPENSSL, cmd, p.returncode, stdout)
+ )
return stdout.decode()
-OPENSSL_SUPPORTED_CURVES = set(c.split(':')[0].strip() for c in
- run_openssl("ecparam -list_curves")
- .split('\n'))
+OPENSSL_SUPPORTED_CURVES = set(
+ c.split(":")[0].strip()
+ for c in run_openssl("ecparam -list_curves").split("\n")
+)
[email protected]("vcurve", curves, ids=[curve.name for curve in curves])
+ "vcurve", curves, ids=[curve.name for curve in curves]
+)
def test_ecdh_with_openssl(vcurve):
assert vcurve.openssl_name
@@ -302,8 +314,12 @@ def test_ecdh_with_openssl(vcurve):
if os.path.isdir("t"):
shutil.rmtree("t")
os.mkdir("t")
- run_openssl("ecparam -name %s -genkey -out t/privkey1.pem" % vcurve.openssl_name)
- run_openssl("ecparam -name %s -genkey -out t/privkey2.pem" % vcurve.openssl_name)
+ run_openssl(
+ "ecparam -name %s -genkey -out t/privkey1.pem" % vcurve.openssl_name
+ )
+ run_openssl(
+ "ecparam -name %s -genkey -out t/privkey2.pem" % vcurve.openssl_name
+ )
run_openssl("ec -in t/privkey1.pem -pubout -out t/pubkey1.pem")
ecdh1 = ECDH(curve=vcurve)
@@ -331,8 +347,12 @@ def test_ecdh_with_openssl(vcurve):
assert secret1 == secret2
try:
- run_openssl("pkeyutl -derive -inkey t/privkey1.pem -peerkey t/pubkey2.pem -out t/secret1")
- run_openssl("pkeyutl -derive -inkey t/privkey2.pem -peerkey t/pubkey1.pem -out t/secret2")
+ run_openssl(
+ "pkeyutl -derive -inkey t/privkey1.pem -peerkey t/pubkey2.pem -out t/secret1"
+ )
+ run_openssl(
+ "pkeyutl -derive -inkey t/privkey2.pem -peerkey t/pubkey1.pem -out t/secret2"
+ )
except RunOpenSslError:
pytest.skip("system openssl does not support `pkeyutl -derive`")
return
diff --git a/frozen_deps/ecdsa/test_ecdsa.py b/frozen_deps/ecdsa/test_ecdsa.py
new file mode 100644
index 0000000..e656b88
--- /dev/null
+++ b/frozen_deps/ecdsa/test_ecdsa.py
@@ -0,0 +1,538 @@
+from __future__ import print_function
+import sys
+import hypothesis.strategies as st
+from hypothesis import given, settings, note, example
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+import pytest
+from .ecdsa import (
+ Private_key,
+ Public_key,
+ Signature,
+ generator_192,
+ digest_integer,
+ ellipticcurve,
+ point_is_valid,
+ generator_224,
+ generator_256,
+ generator_384,
+ generator_521,
+ generator_secp256k1,
+)
+
+
+HYP_SETTINGS = {}
+# old hypothesis doesn't have the "deadline" setting
+if sys.version_info > (2, 7): # pragma: no branch
+ # SEC521p is slow, allow long execution for it
+ HYP_SETTINGS["deadline"] = 5000
+
+
+class TestP192FromX9_62(unittest.TestCase):
+ """Check test vectors from X9.62"""
+
+ @classmethod
+ def setUpClass(cls):
+ cls.d = 651056770906015076056810763456358567190100156695615665659
+ cls.Q = cls.d * generator_192
+ cls.k = 6140507067065001063065065565667405560006161556565665656654
+ cls.R = cls.k * generator_192
+
+ cls.msg = 968236873715988614170569073515315707566766479517
+ cls.pubk = Public_key(generator_192, generator_192 * cls.d)
+ cls.privk = Private_key(cls.pubk, cls.d)
+ cls.sig = cls.privk.sign(cls.msg, cls.k)
+
+ def test_point_multiplication(self):
+ assert self.Q.x() == 0x62B12D60690CDCF330BABAB6E69763B471F994DD702D16A5
+
+ def test_point_multiplication_2(self):
+ assert self.R.x() == 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD
+ assert self.R.y() == 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835
+
+ def test_mult_and_addition(self):
+ u1 = 2563697409189434185194736134579731015366492496392189760599
+ u2 = 6266643813348617967186477710235785849136406323338782220568
+ temp = u1 * generator_192 + u2 * self.Q
+ assert temp.x() == 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD
+ assert temp.y() == 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835
+
+ def test_signature(self):
+ r, s = self.sig.r, self.sig.s
+ assert r == 3342403536405981729393488334694600415596881826869351677613
+ assert s == 5735822328888155254683894997897571951568553642892029982342
+
+ def test_verification(self):
+ assert self.pubk.verifies(self.msg, self.sig)
+
+ def test_rejection(self):
+ assert not self.pubk.verifies(self.msg - 1, self.sig)
+
+
+class TestPublicKey(unittest.TestCase):
+ def test_equality_public_keys(self):
+ gen = generator_192
+ x = 0xC58D61F88D905293BCD4CD0080BCB1B7F811F2FFA41979F6
+ y = 0x8804DC7A7C4C7F8B5D437F5156F3312CA7D6DE8A0E11867F
+ point = ellipticcurve.Point(gen.curve(), x, y)
+ pub_key1 = Public_key(gen, point)
+ pub_key2 = Public_key(gen, point)
+ self.assertEqual(pub_key1, pub_key2)
+
+ def test_inequality_public_key(self):
+ gen = generator_192
+ x1 = 0xC58D61F88D905293BCD4CD0080BCB1B7F811F2FFA41979F6
+ y1 = 0x8804DC7A7C4C7F8B5D437F5156F3312CA7D6DE8A0E11867F
+ point1 = ellipticcurve.Point(gen.curve(), x1, y1)
+
+ x2 = 0x6A223D00BD22C52833409A163E057E5B5DA1DEF2A197DD15
+ y2 = 0x7B482604199367F1F303F9EF627F922F97023E90EAE08ABF
+ point2 = ellipticcurve.Point(gen.curve(), x2, y2)
+
+ pub_key1 = Public_key(gen, point1)
+ pub_key2 = Public_key(gen, point2)
+ self.assertNotEqual(pub_key1, pub_key2)
+
+ def test_inequality_public_key_not_implemented(self):
+ gen = generator_192
+ x = 0xC58D61F88D905293BCD4CD0080BCB1B7F811F2FFA41979F6
+ y = 0x8804DC7A7C4C7F8B5D437F5156F3312CA7D6DE8A0E11867F
+ point = ellipticcurve.Point(gen.curve(), x, y)
+ pub_key = Public_key(gen, point)
+ self.assertNotEqual(pub_key, None)
+
+
+class TestPrivateKey(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ gen = generator_192
+ x = 0xC58D61F88D905293BCD4CD0080BCB1B7F811F2FFA41979F6
+ y = 0x8804DC7A7C4C7F8B5D437F5156F3312CA7D6DE8A0E11867F
+ point = ellipticcurve.Point(gen.curve(), x, y)
+ cls.pub_key = Public_key(gen, point)
+
+ def test_equality_private_keys(self):
+ pr_key1 = Private_key(self.pub_key, 100)
+ pr_key2 = Private_key(self.pub_key, 100)
+ self.assertEqual(pr_key1, pr_key2)
+
+ def test_inequality_private_keys(self):
+ pr_key1 = Private_key(self.pub_key, 100)
+ pr_key2 = Private_key(self.pub_key, 200)
+ self.assertNotEqual(pr_key1, pr_key2)
+
+ def test_inequality_private_keys_not_implemented(self):
+ pr_key = Private_key(self.pub_key, 100)
+ self.assertNotEqual(pr_key, None)
+
+
+# Testing point validity, as per ECDSAVS.pdf B.2.2:
+P192_POINTS = [
+ (
+ generator_192,
+ 0xCD6D0F029A023E9AACA429615B8F577ABEE685D8257CC83A,
+ 0x00019C410987680E9FB6C0B6ECC01D9A2647C8BAE27721BACDFC,
+ False,
+ ),
+ (
+ generator_192,
+ 0x00017F2FCE203639E9EAF9FB50B81FC32776B30E3B02AF16C73B,
+ 0x95DA95C5E72DD48E229D4748D4EEE658A9A54111B23B2ADB,
+ False,
+ ),
+ (
+ generator_192,
+ 0x4F77F8BC7FCCBADD5760F4938746D5F253EE2168C1CF2792,
+ 0x000147156FF824D131629739817EDB197717C41AAB5C2A70F0F6,
+ False,
+ ),
+ (
+ generator_192,
+ 0xC58D61F88D905293BCD4CD0080BCB1B7F811F2FFA41979F6,
+ 0x8804DC7A7C4C7F8B5D437F5156F3312CA7D6DE8A0E11867F,
+ True,
+ ),
+ (
+ generator_192,
+ 0xCDF56C1AA3D8AFC53C521ADF3FFB96734A6A630A4A5B5A70,
+ 0x97C1C44A5FB229007B5EC5D25F7413D170068FFD023CAA4E,
+ True,
+ ),
+ (
+ generator_192,
+ 0x89009C0DC361C81E99280C8E91DF578DF88CDF4B0CDEDCED,
+ 0x27BE44A529B7513E727251F128B34262A0FD4D8EC82377B9,
+ True,
+ ),
+ (
+ generator_192,
+ 0x6A223D00BD22C52833409A163E057E5B5DA1DEF2A197DD15,
+ 0x7B482604199367F1F303F9EF627F922F97023E90EAE08ABF,
+ True,
+ ),
+ (
+ generator_192,
+ 0x6DCCBDE75C0948C98DAB32EA0BC59FE125CF0FB1A3798EDA,
+ 0x0001171A3E0FA60CF3096F4E116B556198DE430E1FBD330C8835,
+ False,
+ ),
+ (
+ generator_192,
+ 0xD266B39E1F491FC4ACBBBC7D098430931CFA66D55015AF12,
+ 0x193782EB909E391A3148B7764E6B234AA94E48D30A16DBB2,
+ False,
+ ),
+ (
+ generator_192,
+ 0x9D6DDBCD439BAA0C6B80A654091680E462A7D1D3F1FFEB43,
+ 0x6AD8EFC4D133CCF167C44EB4691C80ABFFB9F82B932B8CAA,
+ False,
+ ),
+ (
+ generator_192,
+ 0x146479D944E6BDA87E5B35818AA666A4C998A71F4E95EDBC,
+ 0xA86D6FE62BC8FBD88139693F842635F687F132255858E7F6,
+ False,
+ ),
+ (
+ generator_192,
+ 0xE594D4A598046F3598243F50FD2C7BD7D380EDB055802253,
+ 0x509014C0C4D6B536E3CA750EC09066AF39B4C8616A53A923,
+ False,
+ ),
+]
+
+
[email protected]("generator,x,y,expected", P192_POINTS)
+def test_point_validity(generator, x, y, expected):
+ """
+ `generator` defines the curve; is `(x, y)` a point on
+ this curve? `expected` is True if the right answer is Yes.
+ """
+ assert point_is_valid(generator, x, y) == expected
+
+
+# Trying signature-verification tests from ECDSAVS.pdf B.2.4:
+CURVE_192_KATS = [
+ (
+ generator_192,
+ int(
+ "0x84ce72aa8699df436059f052ac51b6398d2511e49631bcb7e71f89c499b9ee"
+ "425dfbc13a5f6d408471b054f2655617cbbaf7937b7c80cd8865cf02c8487d30"
+ "d2b0fbd8b2c4e102e16d828374bbc47b93852f212d5043c3ea720f086178ff79"
+ "8cc4f63f787b9c2e419efa033e7644ea7936f54462dc21a6c4580725f7f0e7d1"
+ "58",
+ 16,
+ ),
+ 0xD9DBFB332AA8E5FF091E8CE535857C37C73F6250FFB2E7AC,
+ 0x282102E364FEDED3AD15DDF968F88D8321AA268DD483EBC4,
+ 0x64DCA58A20787C488D11D6DD96313F1B766F2D8EFE122916,
+ 0x1ECBA28141E84AB4ECAD92F56720E2CC83EB3D22DEC72479,
+ True,
+ ),
+ (
+ generator_192,
+ int(
+ "0x94bb5bacd5f8ea765810024db87f4224ad71362a3c28284b2b9f39fab86db1"
+ "2e8beb94aae899768229be8fdb6c4f12f28912bb604703a79ccff769c1607f5a"
+ "91450f30ba0460d359d9126cbd6296be6d9c4bb96c0ee74cbb44197c207f6db3"
+ "26ab6f5a659113a9034e54be7b041ced9dcf6458d7fb9cbfb2744d999f7dfd63"
+ "f4",
+ 16,
+ ),
+ 0x3E53EF8D3112AF3285C0E74842090712CD324832D4277AE7,
+ 0xCC75F8952D30AEC2CBB719FC6AA9934590B5D0FF5A83ADB7,
+ 0x8285261607283BA18F335026130BAB31840DCFD9C3E555AF,
+ 0x356D89E1B04541AFC9704A45E9C535CE4A50929E33D7E06C,
+ True,
+ ),
+ (
+ generator_192,
+ int(
+ "0xf6227a8eeb34afed1621dcc89a91d72ea212cb2f476839d9b4243c66877911"
+ "b37b4ad6f4448792a7bbba76c63bdd63414b6facab7dc71c3396a73bd7ee14cd"
+ "d41a659c61c99b779cecf07bc51ab391aa3252386242b9853ea7da67fd768d30"
+ "3f1b9b513d401565b6f1eb722dfdb96b519fe4f9bd5de67ae131e64b40e78c42"
+ "dd",
+ 16,
+ ),
+ 0x16335DBE95F8E8254A4E04575D736BEFB258B8657F773CB7,
+ 0x421B13379C59BC9DCE38A1099CA79BBD06D647C7F6242336,
+ 0x4141BD5D64EA36C5B0BD21EF28C02DA216ED9D04522B1E91,
+ 0x159A6AA852BCC579E821B7BB0994C0861FB08280C38DAA09,
+ False,
+ ),
+ (
+ generator_192,
+ int(
+ "0x16b5f93afd0d02246f662761ed8e0dd9504681ed02a253006eb36736b56309"
+ "7ba39f81c8e1bce7a16c1339e345efabbc6baa3efb0612948ae51103382a8ee8"
+ "bc448e3ef71e9f6f7a9676694831d7f5dd0db5446f179bcb737d4a526367a447"
+ "bfe2c857521c7f40b6d7d7e01a180d92431fb0bbd29c04a0c420a57b3ed26ccd"
+ "8a",
+ 16,
+ ),
+ 0xFD14CDF1607F5EFB7B1793037B15BDF4BAA6F7C16341AB0B,
+ 0x83FA0795CC6C4795B9016DAC928FD6BAC32F3229A96312C4,
+ 0x8DFDB832951E0167C5D762A473C0416C5C15BC1195667DC1,
+ 0x1720288A2DC13FA1EC78F763F8FE2FF7354A7E6FDDE44520,
+ False,
+ ),
+ (
+ generator_192,
+ int(
+ "0x08a2024b61b79d260e3bb43ef15659aec89e5b560199bc82cf7c65c77d3919"
+ "2e03b9a895d766655105edd9188242b91fbde4167f7862d4ddd61e5d4ab55196"
+ "683d4f13ceb90d87aea6e07eb50a874e33086c4a7cb0273a8e1c4408f4b846bc"
+ "eae1ebaac1b2b2ea851a9b09de322efe34cebe601653efd6ddc876ce8c2f2072"
+ "fb",
+ 16,
+ ),
+ 0x674F941DC1A1F8B763C9334D726172D527B90CA324DB8828,
+ 0x65ADFA32E8B236CB33A3E84CF59BFB9417AE7E8EDE57A7FF,
+ 0x9508B9FDD7DAF0D8126F9E2BC5A35E4C6D800B5B804D7796,
+ 0x36F2BF6B21B987C77B53BB801B3435A577E3D493744BFAB0,
+ False,
+ ),
+ (
+ generator_192,
+ int(
+ "0x1843aba74b0789d4ac6b0b8923848023a644a7b70afa23b1191829bbe4397c"
+ "e15b629bf21a8838298653ed0c19222b95fa4f7390d1b4c844d96e645537e0aa"
+ "e98afb5c0ac3bd0e4c37f8daaff25556c64e98c319c52687c904c4de7240a1cc"
+ "55cd9756b7edaef184e6e23b385726e9ffcba8001b8f574987c1a3fedaaa83ca"
+ "6d",
+ 16,
+ ),
+ 0x10ECCA1AAD7220B56A62008B35170BFD5E35885C4014A19F,
+ 0x04EB61984C6C12ADE3BC47F3C629ECE7AA0A033B9948D686,
+ 0x82BFA4E82C0DFE9274169B86694E76CE993FD83B5C60F325,
+ 0xA97685676C59A65DBDE002FE9D613431FB183E8006D05633,
+ False,
+ ),
+ (
+ generator_192,
+ int(
+ "0x5a478f4084ddd1a7fea038aa9732a822106385797d02311aeef4d0264f824f"
+ "698df7a48cfb6b578cf3da416bc0799425bb491be5b5ecc37995b85b03420a98"
+ "f2c4dc5c31a69a379e9e322fbe706bbcaf0f77175e05cbb4fa162e0da82010a2"
+ "78461e3e974d137bc746d1880d6eb02aa95216014b37480d84b87f717bb13f76"
+ "e1",
+ 16,
+ ),
+ 0x6636653CB5B894CA65C448277B29DA3AD101C4C2300F7C04,
+ 0xFDF1CBB3FC3FD6A4F890B59E554544175FA77DBDBEB656C1,
+ 0xEAC2DDECDDFB79931A9C3D49C08DE0645C783A24CB365E1C,
+ 0x3549FEE3CFA7E5F93BC47D92D8BA100E881A2A93C22F8D50,
+ False,
+ ),
+ (
+ generator_192,
+ int(
+ "0xc598774259a058fa65212ac57eaa4f52240e629ef4c310722088292d1d4af6"
+ "c39b49ce06ba77e4247b20637174d0bd67c9723feb57b5ead232b47ea452d5d7"
+ "a089f17c00b8b6767e434a5e16c231ba0efa718a340bf41d67ea2d295812ff1b"
+ "9277daacb8bc27b50ea5e6443bcf95ef4e9f5468fe78485236313d53d1c68f6b"
+ "a2",
+ 16,
+ ),
+ 0xA82BD718D01D354001148CD5F69B9EBF38FF6F21898F8AAA,
+ 0xE67CEEDE07FC2EBFAFD62462A51E4B6C6B3D5B537B7CAF3E,
+ 0x4D292486C620C3DE20856E57D3BB72FCDE4A73AD26376955,
+ 0xA85289591A6081D5728825520E62FF1C64F94235C04C7F95,
+ False,
+ ),
+ (
+ generator_192,
+ int(
+ "0xca98ed9db081a07b7557f24ced6c7b9891269a95d2026747add9e9eb80638a"
+ "961cf9c71a1b9f2c29744180bd4c3d3db60f2243c5c0b7cc8a8d40a3f9a7fc91"
+ "0250f2187136ee6413ffc67f1a25e1c4c204fa9635312252ac0e0481d89b6d53"
+ "808f0c496ba87631803f6c572c1f61fa049737fdacce4adff757afed4f05beb6"
+ "58",
+ 16,
+ ),
+ 0x7D3B016B57758B160C4FCA73D48DF07AE3B6B30225126C2F,
+ 0x4AF3790D9775742BDE46F8DA876711BE1B65244B2B39E7EC,
+ 0x95F778F5F656511A5AB49A5D69DDD0929563C29CBC3A9E62,
+ 0x75C87FC358C251B4C83D2DD979FAAD496B539F9F2EE7A289,
+ False,
+ ),
+ (
+ generator_192,
+ int(
+ "0x31dd9a54c8338bea06b87eca813d555ad1850fac9742ef0bbe40dad400e102"
+ "88acc9c11ea7dac79eb16378ebea9490e09536099f1b993e2653cd50240014c9"
+ "0a9c987f64545abc6a536b9bd2435eb5e911fdfde2f13be96ea36ad38df4ae9e"
+ "a387b29cced599af777338af2794820c9cce43b51d2112380a35802ab7e396c9"
+ "7a",
+ 16,
+ ),
+ 0x9362F28C4EF96453D8A2F849F21E881CD7566887DA8BEB4A,
+ 0xE64D26D8D74C48A024AE85D982EE74CD16046F4EE5333905,
+ 0xF3923476A296C88287E8DE914B0B324AD5A963319A4FE73B,
+ 0xF0BAEED7624ED00D15244D8BA2AEDE085517DBDEC8AC65F5,
+ True,
+ ),
+ (
+ generator_192,
+ int(
+ "0xb2b94e4432267c92f9fdb9dc6040c95ffa477652761290d3c7de312283f645"
+ "0d89cc4aabe748554dfb6056b2d8e99c7aeaad9cdddebdee9dbc099839562d90"
+ "64e68e7bb5f3a6bba0749ca9a538181fc785553a4000785d73cc207922f63e8c"
+ "e1112768cb1de7b673aed83a1e4a74592f1268d8e2a4e9e63d414b5d442bd045"
+ "6d",
+ 16,
+ ),
+ 0xCC6FC032A846AAAC25533EB033522824F94E670FA997ECEF,
+ 0xE25463EF77A029ECCDA8B294FD63DD694E38D223D30862F1,
+ 0x066B1D07F3A40E679B620EDA7F550842A35C18B80C5EBE06,
+ 0xA0B0FB201E8F2DF65E2C4508EF303BDC90D934016F16B2DC,
+ False,
+ ),
+ (
+ generator_192,
+ int(
+ "0x4366fcadf10d30d086911de30143da6f579527036937007b337f7282460eae"
+ "5678b15cccda853193ea5fc4bc0a6b9d7a31128f27e1214988592827520b214e"
+ "ed5052f7775b750b0c6b15f145453ba3fee24a085d65287e10509eb5d5f602c4"
+ "40341376b95c24e5c4727d4b859bfe1483d20538acdd92c7997fa9c614f0f839"
+ "d7",
+ 16,
+ ),
+ 0x955C908FE900A996F7E2089BEE2F6376830F76A19135E753,
+ 0xBA0C42A91D3847DE4A592A46DC3FDAF45A7CC709B90DE520,
+ 0x1F58AD77FC04C782815A1405B0925E72095D906CBF52A668,
+ 0xF2E93758B3AF75EDF784F05A6761C9B9A6043C66B845B599,
+ False,
+ ),
+ (
+ generator_192,
+ int(
+ "0x543f8af57d750e33aa8565e0cae92bfa7a1ff78833093421c2942cadf99866"
+ "70a5ff3244c02a8225e790fbf30ea84c74720abf99cfd10d02d34377c3d3b412"
+ "69bea763384f372bb786b5846f58932defa68023136cd571863b304886e95e52"
+ "e7877f445b9364b3f06f3c28da12707673fecb4b8071de06b6e0a3c87da160ce"
+ "f3",
+ 16,
+ ),
+ 0x31F7FA05576D78A949B24812D4383107A9A45BB5FCCDD835,
+ 0x8DC0EB65994A90F02B5E19BD18B32D61150746C09107E76B,
+ 0xBE26D59E4E883DDE7C286614A767B31E49AD88789D3A78FF,
+ 0x8762CA831C1CE42DF77893C9B03119428E7A9B819B619068,
+ False,
+ ),
+ (
+ generator_192,
+ int(
+ "0xd2e8454143ce281e609a9d748014dcebb9d0bc53adb02443a6aac2ffe6cb009f"
+ "387c346ecb051791404f79e902ee333ad65e5c8cb38dc0d1d39a8dc90add502357"
+ "2720e5b94b190d43dd0d7873397504c0c7aef2727e628eb6a74411f2e400c65670"
+ "716cb4a815dc91cbbfeb7cfe8c929e93184c938af2c078584da045e8f8d1",
+ 16,
+ ),
+ 0x66AA8EDBBDB5CF8E28CEB51B5BDA891CAE2DF84819FE25C0,
+ 0x0C6BC2F69030A7CE58D4A00E3B3349844784A13B8936F8DA,
+ 0xA4661E69B1734F4A71B788410A464B71E7FFE42334484F23,
+ 0x738421CF5E049159D69C57A915143E226CAC8355E149AFE9,
+ False,
+ ),
+ (
+ generator_192,
+ int(
+ "0x6660717144040f3e2f95a4e25b08a7079c702a8b29babad5a19a87654bc5c5af"
+ "a261512a11b998a4fb36b5d8fe8bd942792ff0324b108120de86d63f65855e5461"
+ "184fc96a0a8ffd2ce6d5dfb0230cbbdd98f8543e361b3205f5da3d500fdc8bac6d"
+ "b377d75ebef3cb8f4d1ff738071ad0938917889250b41dd1d98896ca06fb",
+ 16,
+ ),
+ 0xBCFACF45139B6F5F690A4C35A5FFFA498794136A2353FC77,
+ 0x6F4A6C906316A6AFC6D98FE1F0399D056F128FE0270B0F22,
+ 0x9DB679A3DAFE48F7CCAD122933ACFE9DA0970B71C94C21C1,
+ 0x984C2DB99827576C0A41A5DA41E07D8CC768BC82F18C9DA9,
+ False,
+ ),
+]
+
+
[email protected]("gen,msg,qx,qy,r,s,expected", CURVE_192_KATS)
+def test_signature_validity(gen, msg, qx, qy, r, s, expected):
+ """
+ `msg` = message, `qx` and `qy` represent the base point on
+ elliptic curve of `gen`, `r` and `s` are the signature, and
+ `expected` is True iff the signature is expected to be valid."""
+ pubk = Public_key(gen, ellipticcurve.Point(gen.curve(), qx, qy))
+ assert expected == pubk.verifies(digest_integer(msg), Signature(r, s))
+
+
+ "gen,msg,qx,qy,r,s,expected", [x for x in CURVE_192_KATS if x[6]]
+)
+def test_pk_recovery(gen, msg, r, s, qx, qy, expected):
+ del expected
+ sign = Signature(r, s)
+ pks = sign.recover_public_keys(digest_integer(msg), gen)
+
+ assert pks
+
+ # Test if the signature is valid for all found public keys
+ for pk in pks:
+ q = pk.point
+ test_signature_validity(gen, msg, q.x(), q.y(), r, s, True)
+
+ # Test if the original public key is in the set of found keys
+ original_q = ellipticcurve.Point(gen.curve(), qx, qy)
+ points = [pk.point for pk in pks]
+ assert original_q in points
+
+
+def st_random_gen_key_msg_nonce(draw):
+ """Hypothesis strategy for test_sig_verify()."""
+ name_gen = {
+ "generator_192": generator_192,
+ "generator_224": generator_224,
+ "generator_256": generator_256,
+ "generator_secp256k1": generator_secp256k1,
+ "generator_384": generator_384,
+ "generator_521": generator_521,
+ }
+ name = draw(st.sampled_from(sorted(name_gen.keys())))
+ note("Generator used: {0}".format(name))
+ generator = name_gen[name]
+ order = int(generator.order())
+
+ key = draw(st.integers(min_value=1, max_value=order))
+ msg = draw(st.integers(min_value=1, max_value=order))
+ nonce = draw(
+ st.integers(min_value=1, max_value=order + 1)
+ | st.integers(min_value=order >> 1, max_value=order)
+ )
+ return generator, key, msg, nonce
+
+
+SIG_VER_SETTINGS = dict(HYP_SETTINGS)
+SIG_VER_SETTINGS["max_examples"] = 10
+
+
+@settings(**SIG_VER_SETTINGS)
+@example((generator_224, 4, 1, 1))
+@given(st_random_gen_key_msg_nonce())
+def test_sig_verify(args):
+ """
+ Check if signing and verification works for arbitrary messages and
+ that signatures for other messages are rejected.
+ """
+ generator, sec_mult, msg, nonce = args
+
+ pubkey = Public_key(generator, generator * sec_mult)
+ privkey = Private_key(pubkey, sec_mult)
+
+ signature = privkey.sign(msg, nonce)
+
+ assert pubkey.verifies(msg, signature)
+
+ assert not pubkey.verifies(msg - 1, signature)
diff --git a/freezed_deps/ecdsa/test_ellipticcurve.py b/frozen_deps/ecdsa/test_ellipticcurve.py
index 924134c..def53b2 100644
--- a/freezed_deps/ecdsa/test_ellipticcurve.py
+++ b/frozen_deps/ecdsa/test_ellipticcurve.py
@@ -1,24 +1,27 @@
import pytest
from six import print_
+
try:
import unittest2 as unittest
except ImportError:
import unittest
from hypothesis import given, settings
import hypothesis.strategies as st
+
try:
from hypothesis import HealthCheck
- HC_PRESENT=True
+
+ HC_PRESENT = True
except ImportError: # pragma: no cover
- HC_PRESENT=False
+ HC_PRESENT = False
from .numbertheory import inverse_mod
from .ellipticcurve import CurveFp, INFINITY, Point
-HYP_SETTINGS={}
+HYP_SETTINGS = {}
if HC_PRESENT: # pragma: no branch
- HYP_SETTINGS['suppress_health_check']=[HealthCheck.too_slow]
- HYP_SETTINGS['deadline'] = 5000
+ HYP_SETTINGS["suppress_health_check"] = [HealthCheck.too_slow]
+ HYP_SETTINGS["deadline"] = 5000
# NIST Curve P-192:
@@ -26,9 +29,9 @@ p = 6277101735386680763835789423207666416083908700390324961279
r = 6277101735386680763835789423176059013767194773182842284081
# s = 0x3045ae6fc8422f64ed579528d38120eae12196d5
# c = 0x3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65
-b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1
-Gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012
-Gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811
+b = 0x64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1
+Gx = 0x188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012
+Gy = 0x07192B95FFC8DA78631011ED6B24CDD573F977A11E794811
c192 = CurveFp(p, -3, b)
p192 = Point(c192, Gx, Gy, r)
@@ -37,19 +40,19 @@ c_23 = CurveFp(23, 1, 1)
g_23 = Point(c_23, 13, 7, 7)
-HYP_SLOW_SETTINGS=dict(HYP_SETTINGS)
-HYP_SLOW_SETTINGS["max_examples"]=10
+HYP_SLOW_SETTINGS = dict(HYP_SETTINGS)
+HYP_SLOW_SETTINGS["max_examples"] = 10
@settings(**HYP_SLOW_SETTINGS)
-@given(st.integers(min_value=1, max_value=r+1))
+@given(st.integers(min_value=1, max_value=r + 1))
def test_p192_mult_tests(multiple):
inv_m = inverse_mod(multiple, r)
p1 = p192 * multiple
assert p1 * inv_m == p192
-
-
+
+
def add_n_times(point, n):
ret = INFINITY
i = 0
@@ -57,26 +60,26 @@ def add_n_times(point, n):
yield ret
ret = ret + point
i += 1
-
+
# From X9.62 I.1 (p. 96):
@pytest.mark.parametrize(
"p, m, check",
[(g_23, n, exp) for n, exp in enumerate(add_n_times(g_23, 8))],
- ids=["g_23 test with mult {0}".format(i) for i in range(9)])
+ ids=["g_23 test with mult {0}".format(i) for i in range(9)],
+)
def test_add_and_mult_equivalence(p, m, check):
assert p * m == check
-
-class TestCurve(unittest.TestCase):
+class TestCurve(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.c_23 = CurveFp(23, 1, 1)
-
+
def test_equality_curves(self):
self.assertEqual(self.c_23, CurveFp(23, 1, 1))
-
+
def test_inequality_curves(self):
c192 = CurveFp(p, -3, b)
self.assertNotEqual(self.c_23, c192)
@@ -97,92 +100,101 @@ class TestCurve(unittest.TestCase):
class TestPoint(unittest.TestCase):
-
@classmethod
def setUpClass(cls):
cls.c_23 = CurveFp(23, 1, 1)
cls.g_23 = Point(cls.c_23, 13, 7, 7)
-
+
p = 6277101735386680763835789423207666416083908700390324961279
r = 6277101735386680763835789423176059013767194773182842284081
# s = 0x3045ae6fc8422f64ed579528d38120eae12196d5
# c = 0x3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65
- b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1
- Gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012
- Gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811
-
+ b = 0x64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1
+ Gx = 0x188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012
+ Gy = 0x07192B95FFC8DA78631011ED6B24CDD573F977A11E794811
+
cls.c192 = CurveFp(p, -3, b)
- cls.p192 = Point(cls.c192, Gx, Gy, r)
-
+ cls.p192 = Point(cls.c192, Gx, Gy, r)
+
def test_p192(self):
# Checking against some sample computations presented
# in X9.62:
d = 651056770906015076056810763456358567190100156695615665659
Q = d * self.p192
- self.assertEqual(Q.x(), 0x62B12D60690CDCF330BABAB6E69763B471F994DD702D16A5)
+ self.assertEqual(
+ Q.x(), 0x62B12D60690CDCF330BABAB6E69763B471F994DD702D16A5
+ )
k = 6140507067065001063065065565667405560006161556565665656654
R = k * self.p192
- self.assertEqual(R.x(), 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD)
- self.assertEqual(R.y(), 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835)
+ self.assertEqual(
+ R.x(), 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD
+ )
+ self.assertEqual(
+ R.y(), 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835
+ )
u1 = 2563697409189434185194736134579731015366492496392189760599
u2 = 6266643813348617967186477710235785849136406323338782220568
temp = u1 * self.p192 + u2 * Q
- self.assertEqual(temp.x(), 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD)
- self.assertEqual(temp.y(), 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835)
-
+ self.assertEqual(
+ temp.x(), 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD
+ )
+ self.assertEqual(
+ temp.y(), 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835
+ )
+
def test_double_infinity(self):
p1 = INFINITY
p3 = p1.double()
self.assertEqual(p1, p3)
self.assertEqual(p3.x(), p1.x())
- self.assertEqual(p3.y(), p3.y())
-
+ self.assertEqual(p3.y(), p3.y())
+
def test_double(self):
x1, y1, x3, y3 = (3, 10, 7, 12)
-
+
p1 = Point(self.c_23, x1, y1)
p3 = p1.double()
self.assertEqual(p3.x(), x3)
self.assertEqual(p3.y(), y3)
-
+
def test_multiply(self):
x1, y1, m, x3, y3 = (3, 10, 2, 7, 12)
p1 = Point(self.c_23, x1, y1)
p3 = p1 * m
self.assertEqual(p3.x(), x3)
self.assertEqual(p3.y(), y3)
-
+
# Trivial tests from X9.62 B.3:
def test_add(self):
"""We expect that on curve c, (x1,y1) + (x2, y2 ) = (x3, y3)."""
-
+
x1, y1, x2, y2, x3, y3 = (3, 10, 9, 7, 17, 20)
p1 = Point(self.c_23, x1, y1)
p2 = Point(self.c_23, x2, y2)
p3 = p1 + p2
self.assertEqual(p3.x(), x3)
self.assertEqual(p3.y(), y3)
-
+
def test_add_as_double(self):
"""We expect that on curve c, (x1,y1) + (x2, y2 ) = (x3, y3)."""
-
- x1, y1, x2, y2, x3, y3 = (3, 10, 3, 10, 7, 12)
+
+ x1, y1, x2, y2, x3, y3 = (3, 10, 3, 10, 7, 12)
p1 = Point(self.c_23, x1, y1)
p2 = Point(self.c_23, x2, y2)
p3 = p1 + p2
self.assertEqual(p3.x(), x3)
self.assertEqual(p3.y(), y3)
-
+
def test_equality_points(self):
self.assertEqual(self.g_23, Point(self.c_23, 13, 7, 7))
-
+
def test_inequality_points(self):
c = CurveFp(100, -3, 100)
p = Point(c, 100, 100, 100)
self.assertNotEqual(self.g_23, p)
-
- def test_inaquality_points_diff_types(self):
- c = CurveFp(100, -3, 100)
+
+ def test_inequality_points_diff_types(self):
+ c = CurveFp(100, -3, 100)
self.assertNotEqual(self.g_23, c)
diff --git a/freezed_deps/ecdsa/test_jacobi.py b/frozen_deps/ecdsa/test_jacobi.py
index 35e5242..43ed6c1 100644
--- a/freezed_deps/ecdsa/test_jacobi.py
+++ b/frozen_deps/ecdsa/test_jacobi.py
@@ -1,3 +1,4 @@
+import pickle
try:
import unittest2 as unittest
@@ -7,10 +8,17 @@ except ImportError:
import hypothesis.strategies as st
from hypothesis import given, assume, settings, example
-from .ellipticcurve import Point, PointJacobi, INFINITY
-from .ecdsa import generator_256, curve_256, generator_224
+from .ellipticcurve import CurveFp, Point, PointJacobi, INFINITY
+from .ecdsa import (
+ generator_256,
+ curve_256,
+ generator_224,
+ generator_brainpoolp160r1,
+ curve_brainpoolp160r1,
+)
from .numbertheory import inverse_mod
+
class TestJacobi(unittest.TestCase):
def test___init__(self):
curve = object()
@@ -179,9 +187,13 @@ class TestJacobi(unittest.TestCase):
self.assertEqual(dbl, mlpl)
@settings(max_examples=10)
- @given(st.integers(min_value=0, max_value=int(generator_256.order())))
+ @given(
+ st.integers(
+ min_value=0, max_value=int(generator_brainpoolp160r1.order())
+ )
+ )
def test_multiplications(self, mul):
- pj = PointJacobi.from_affine(generator_256)
+ pj = PointJacobi.from_affine(generator_brainpoolp160r1)
pw = pj.to_affine() * mul
pj = pj * mul
@@ -190,12 +202,16 @@ class TestJacobi(unittest.TestCase):
self.assertEqual(pj, pw)
@settings(max_examples=10)
- @given(st.integers(min_value=0, max_value=int(generator_256.order())))
+ @given(
+ st.integers(
+ min_value=0, max_value=int(generator_brainpoolp160r1.order())
+ )
+ )
@example(0)
- @example(int(generator_256.order()))
+ @example(int(generator_brainpoolp160r1.order()))
def test_precompute(self, mul):
- precomp = PointJacobi.from_affine(generator_256, True)
- pj = PointJacobi.from_affine(generator_256)
+ precomp = PointJacobi.from_affine(generator_brainpoolp160r1, True)
+ pj = PointJacobi.from_affine(generator_brainpoolp160r1)
a = precomp * mul
b = pj * mul
@@ -203,11 +219,17 @@ class TestJacobi(unittest.TestCase):
self.assertEqual(a, b)
@settings(max_examples=10)
- @given(st.integers(min_value=1, max_value=int(generator_256.order())),
- st.integers(min_value=1, max_value=int(generator_256.order())))
+ @given(
+ st.integers(
+ min_value=1, max_value=int(generator_brainpoolp160r1.order())
+ ),
+ st.integers(
+ min_value=1, max_value=int(generator_brainpoolp160r1.order())
+ ),
+ )
@example(3, 3)
def test_add_scaled_points(self, a_mul, b_mul):
- j_g = PointJacobi.from_affine(generator_256)
+ j_g = PointJacobi.from_affine(generator_brainpoolp160r1)
a = PointJacobi.from_affine(j_g * a_mul)
b = PointJacobi.from_affine(j_g * b_mul)
@@ -216,70 +238,106 @@ class TestJacobi(unittest.TestCase):
self.assertEqual(c, j_g * (a_mul + b_mul))
@settings(max_examples=10)
- @given(st.integers(min_value=1, max_value=int(generator_256.order())),
- st.integers(min_value=1, max_value=int(generator_256.order())),
- st.integers(min_value=1, max_value=int(curve_256.p()-1)))
+ @given(
+ st.integers(
+ min_value=1, max_value=int(generator_brainpoolp160r1.order())
+ ),
+ st.integers(
+ min_value=1, max_value=int(generator_brainpoolp160r1.order())
+ ),
+ st.integers(min_value=1, max_value=int(curve_brainpoolp160r1.p() - 1)),
+ )
def test_add_one_scaled_point(self, a_mul, b_mul, new_z):
- j_g = PointJacobi.from_affine(generator_256)
+ j_g = PointJacobi.from_affine(generator_brainpoolp160r1)
a = PointJacobi.from_affine(j_g * a_mul)
b = PointJacobi.from_affine(j_g * b_mul)
- p = curve_256.p()
+ p = curve_brainpoolp160r1.p()
assume(inverse_mod(new_z, p))
new_zz = new_z * new_z % p
b = PointJacobi(
- curve_256, b.x() * new_zz % p, b.y() * new_zz * new_z % p, new_z)
+ curve_brainpoolp160r1,
+ b.x() * new_zz % p,
+ b.y() * new_zz * new_z % p,
+ new_z,
+ )
c = a + b
self.assertEqual(c, j_g * (a_mul + b_mul))
@settings(max_examples=10)
- @given(st.integers(min_value=1, max_value=int(generator_256.order())),
- st.integers(min_value=1, max_value=int(generator_256.order())),
- st.integers(min_value=1, max_value=int(curve_256.p()-1)))
+ @given(
+ st.integers(
+ min_value=1, max_value=int(generator_brainpoolp160r1.order())
+ ),
+ st.integers(
+ min_value=1, max_value=int(generator_brainpoolp160r1.order())
+ ),
+ st.integers(min_value=1, max_value=int(curve_brainpoolp160r1.p() - 1)),
+ )
@example(1, 1, 1)
@example(3, 3, 3)
- @example(2, int(generator_256.order()-2), 1)
- @example(2, int(generator_256.order()-2), 3)
+ @example(2, int(generator_brainpoolp160r1.order() - 2), 1)
+ @example(2, int(generator_brainpoolp160r1.order() - 2), 3)
def test_add_same_scale_points(self, a_mul, b_mul, new_z):
- j_g = PointJacobi.from_affine(generator_256)
+ j_g = PointJacobi.from_affine(generator_brainpoolp160r1)
a = PointJacobi.from_affine(j_g * a_mul)
b = PointJacobi.from_affine(j_g * b_mul)
- p = curve_256.p()
+ p = curve_brainpoolp160r1.p()
assume(inverse_mod(new_z, p))
new_zz = new_z * new_z % p
a = PointJacobi(
- curve_256, a.x() * new_zz % p, a.y() * new_zz * new_z % p, new_z)
+ curve_brainpoolp160r1,
+ a.x() * new_zz % p,
+ a.y() * new_zz * new_z % p,
+ new_z,
+ )
b = PointJacobi(
- curve_256, b.x() * new_zz % p, b.y() * new_zz * new_z % p, new_z)
+ curve_brainpoolp160r1,
+ b.x() * new_zz % p,
+ b.y() * new_zz * new_z % p,
+ new_z,
+ )
c = a + b
self.assertEqual(c, j_g * (a_mul + b_mul))
@settings(max_examples=14)
- @given(st.integers(min_value=1, max_value=int(generator_256.order())),
- st.integers(min_value=1, max_value=int(generator_256.order())),
- st.lists(st.integers(min_value=1, max_value=int(curve_256.p()-1)),
- min_size=2, max_size=2, unique=True))
+ @given(
+ st.integers(
+ min_value=1, max_value=int(generator_brainpoolp160r1.order())
+ ),
+ st.integers(
+ min_value=1, max_value=int(generator_brainpoolp160r1.order())
+ ),
+ st.lists(
+ st.integers(
+ min_value=1, max_value=int(curve_brainpoolp160r1.p() - 1)
+ ),
+ min_size=2,
+ max_size=2,
+ unique=True,
+ ),
+ )
@example(2, 2, [2, 1])
@example(2, 2, [2, 3])
- @example(2, int(generator_256.order()-2), [2, 3])
- @example(2, int(generator_256.order()-2), [2, 1])
+ @example(2, int(generator_brainpoolp160r1.order() - 2), [2, 3])
+ @example(2, int(generator_brainpoolp160r1.order() - 2), [2, 1])
def test_add_different_scale_points(self, a_mul, b_mul, new_z):
- j_g = PointJacobi.from_affine(generator_256)
+ j_g = PointJacobi.from_affine(generator_brainpoolp160r1)
a = PointJacobi.from_affine(j_g * a_mul)
b = PointJacobi.from_affine(j_g * b_mul)
- p = curve_256.p()
+ p = curve_brainpoolp160r1.p()
assume(inverse_mod(new_z[0], p))
assume(inverse_mod(new_z[1], p))
@@ -288,15 +346,17 @@ class TestJacobi(unittest.TestCase):
new_zz1 = new_z[1] * new_z[1] % p
a = PointJacobi(
- curve_256,
+ curve_brainpoolp160r1,
a.x() * new_zz0 % p,
a.y() * new_zz0 * new_z[0] % p,
- new_z[0])
+ new_z[0],
+ )
b = PointJacobi(
- curve_256,
+ curve_brainpoolp160r1,
b.x() * new_zz1 % p,
b.y() * new_zz1 * new_z[1] % p,
- new_z[1])
+ new_z[1],
+ )
c = a + b
@@ -330,10 +390,12 @@ class TestJacobi(unittest.TestCase):
b = PointJacobi.from_affine(j_g * 255, True)
self.assertEqual(j_g * 256, j_g + b)
- self.assertEqual(j_g * (0xff00 + 255 * 0xf0f0),
- j_g * 0xff00 + b * 0xf0f0)
- self.assertEqual(j_g * (0xff00 + 255 * 0xf0f0),
- j_g.mul_add(0xff00, b, 0xf0f0))
+ self.assertEqual(
+ j_g * (0xFF00 + 255 * 0xF0F0), j_g * 0xFF00 + b * 0xF0F0
+ )
+ self.assertEqual(
+ j_g * (0xFF00 + 255 * 0xF0F0), j_g.mul_add(0xFF00, b, 0xF0F0)
+ )
def test_mul_add_to_mul(self):
j_g = PointJacobi.from_affine(generator_256)
@@ -347,10 +409,10 @@ class TestJacobi(unittest.TestCase):
j_g = PointJacobi.from_affine(generator_256)
w_a = generator_256 * 255
- w_b = generator_256 * (0xa8*0xf0)
- j_b = j_g * 0xa8
+ w_b = generator_256 * (0xA8 * 0xF0)
+ j_b = j_g * 0xA8
- ret = j_g.mul_add(255, j_b, 0xf0)
+ ret = j_g.mul_add(255, j_b, 0xF0)
self.assertEqual(ret.to_affine(), w_a + w_b)
@@ -359,7 +421,18 @@ class TestJacobi(unittest.TestCase):
b = PointJacobi.from_affine(j_g * 255)
self.assertEqual(j_g * 256, j_g + b)
- self.assertEqual(j_g * (0xff00 + 255 * 0xf0f0),
- j_g * 0xff00 + b * 0xf0f0)
- self.assertEqual(j_g * (0xff00 + 255 * 0xf0f0),
- j_g.mul_add(0xff00, b, 0xf0f0))
+ self.assertEqual(
+ j_g * (0xFF00 + 255 * 0xF0F0), j_g * 0xFF00 + b * 0xF0F0
+ )
+ self.assertEqual(
+ j_g * (0xFF00 + 255 * 0xF0F0), j_g.mul_add(0xFF00, b, 0xF0F0)
+ )
+
+ def test_equality(self):
+ pj1 = PointJacobi(curve=CurveFp(23, 1, 1, 1), x=2, y=3, z=1, order=1)
+ pj2 = PointJacobi(curve=CurveFp(23, 1, 1, 1), x=2, y=3, z=1, order=1)
+ self.assertEqual(pj1, pj2)
+
+ def test_pickle(self):
+ pj = PointJacobi(curve=CurveFp(23, 1, 1, 1), x=2, y=3, z=1, order=1)
+ self.assertEqual(pickle.loads(pickle.dumps(pj)), pj)
diff --git a/freezed_deps/ecdsa/test_keys.py b/frozen_deps/ecdsa/test_keys.py
index 56e1284..406a5bf 100644
--- a/freezed_deps/ecdsa/test_keys.py
+++ b/frozen_deps/ecdsa/test_keys.py
@@ -16,8 +16,15 @@ import hashlib
from .keys import VerifyingKey, SigningKey
from .der import unpem
-from .util import sigencode_string, sigencode_der, sigencode_strings, \
- sigdecode_string, sigdecode_der, sigdecode_strings
+from .util import (
+ sigencode_string,
+ sigencode_der,
+ sigencode_strings,
+ sigdecode_string,
+ sigdecode_der,
+ sigdecode_strings,
+)
+from .curves import NIST256p
class TestVerifyingKeyFromString(unittest.TestCase):
@@ -28,9 +35,11 @@ class TestVerifyingKeyFromString(unittest.TestCase):
@classmethod
def setUpClass(cls):
- cls.key_bytes = (b'\x04L\xa2\x95\xdb\xc7Z\xd7\x1f\x93\nz\xcf\x97\xcf'
- b'\xd7\xc2\xd9o\xfe8}X!\xae\xd4\xfah\xfa^\rpI\xba\xd1'
- b'Y\xfb\x92xa\xebo+\x9cG\xfav\xca')
+ cls.key_bytes = (
+ b"\x04L\xa2\x95\xdb\xc7Z\xd7\x1f\x93\nz\xcf\x97\xcf"
+ b"\xd7\xc2\xd9o\xfe8}X!\xae\xd4\xfah\xfa^\rpI\xba\xd1"
+ b"Y\xfb\x92xa\xebo+\x9cG\xfav\xca"
+ )
cls.vk = VerifyingKey.from_string(cls.key_bytes)
def test_bytes(self):
@@ -38,10 +47,12 @@ class TestVerifyingKeyFromString(unittest.TestCase):
self.assertIsInstance(self.vk, VerifyingKey)
self.assertEqual(
self.vk.pubkey.point.x(),
- 105419898848891948935835657980914000059957975659675736097)
+ 105419898848891948935835657980914000059957975659675736097,
+ )
self.assertEqual(
self.vk.pubkey.point.y(),
- 4286866841217412202667522375431381222214611213481632495306)
+ 4286866841217412202667522375431381222214611213481632495306,
+ )
def test_bytes_memoryview(self):
vk = VerifyingKey.from_string(buffer(self.key_bytes))
@@ -59,46 +70,46 @@ class TestVerifyingKeyFromString(unittest.TestCase):
self.assertEqual(self.vk.to_string(), vk.to_string())
def test_array_array_of_bytes(self):
- arr = array.array('B', self.key_bytes)
+ arr = array.array("B", self.key_bytes)
vk = VerifyingKey.from_string(arr)
self.assertEqual(self.vk.to_string(), vk.to_string())
def test_array_array_of_bytes_memoryview(self):
- arr = array.array('B', self.key_bytes)
+ arr = array.array("B", self.key_bytes)
vk = VerifyingKey.from_string(buffer(arr))
self.assertEqual(self.vk.to_string(), vk.to_string())
def test_array_array_of_ints(self):
- arr = array.array('I', self.key_bytes)
+ arr = array.array("I", self.key_bytes)
vk = VerifyingKey.from_string(arr)
self.assertEqual(self.vk.to_string(), vk.to_string())
def test_array_array_of_ints_memoryview(self):
- arr = array.array('I', self.key_bytes)
+ arr = array.array("I", self.key_bytes)
vk = VerifyingKey.from_string(buffer(arr))
self.assertEqual(self.vk.to_string(), vk.to_string())
def test_bytes_uncompressed(self):
- vk = VerifyingKey.from_string(b'\x04' + self.key_bytes)
+ vk = VerifyingKey.from_string(b"\x04" + self.key_bytes)
self.assertEqual(self.vk.to_string(), vk.to_string())
def test_bytearray_uncompressed(self):
- vk = VerifyingKey.from_string(bytearray(b'\x04' + self.key_bytes))
+ vk = VerifyingKey.from_string(bytearray(b"\x04" + self.key_bytes))
self.assertEqual(self.vk.to_string(), vk.to_string())
def test_bytes_compressed(self):
- vk = VerifyingKey.from_string(b'\x02' + self.key_bytes[:24])
+ vk = VerifyingKey.from_string(b"\x02" + self.key_bytes[:24])
self.assertEqual(self.vk.to_string(), vk.to_string())
def test_bytearray_compressed(self):
- vk = VerifyingKey.from_string(bytearray(b'\x02' + self.key_bytes[:24]))
+ vk = VerifyingKey.from_string(bytearray(b"\x02" + self.key_bytes[:24]))
self.assertEqual(self.vk.to_string(), vk.to_string())
@@ -108,6 +119,7 @@ class TestVerifyingKeyFromDer(unittest.TestCase):
Verify that ecdsa.keys.VerifyingKey.from_der() can be used with
bytes-like objects.
"""
+
@classmethod
def setUpClass(cls):
prv_key_str = (
@@ -115,12 +127,14 @@ class TestVerifyingKeyFromDer(unittest.TestCase):
"MF8CAQEEGF7IQgvW75JSqULpiQQ8op9WH6Uldw6xxaAKBggqhkjOPQMBAaE0AzIA\n"
"BLiBd9CE7xf15FY5QIAoNg+fWbSk1yZOYtoGUdzkejWkxbRc9RWTQjqLVXucIJnz\n"
"bA==\n"
- "-----END EC PRIVATE KEY-----\n")
+ "-----END EC PRIVATE KEY-----\n"
+ )
key_str = (
"-----BEGIN PUBLIC KEY-----\n"
"MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEuIF30ITvF/XkVjlAgCg2D59ZtKTX\n"
"Jk5i2gZR3OR6NaTFtFz1FZNCOotVe5wgmfNs\n"
- "-----END PUBLIC KEY-----\n")
+ "-----END PUBLIC KEY-----\n"
+ )
cls.key_pem = key_str
cls.key_bytes = unpem(key_str)
@@ -167,13 +181,13 @@ class TestVerifyingKeyFromDer(unittest.TestCase):
self.assertEqual(self.vk.to_string(), vk.to_string())
def test_array_array_of_bytes(self):
- arr = array.array('B', self.key_bytes)
+ arr = array.array("B", self.key_bytes)
vk = VerifyingKey.from_der(arr)
self.assertEqual(self.vk.to_string(), vk.to_string())
def test_array_array_of_bytes_memoryview(self):
- arr = array.array('B', self.key_bytes)
+ arr = array.array("B", self.key_bytes)
vk = VerifyingKey.from_der(buffer(arr))
self.assertEqual(self.vk.to_string(), vk.to_string())
@@ -193,6 +207,7 @@ class TestSigningKey(unittest.TestCase):
Verify that ecdsa.keys.SigningKey.from_der() can be used with
bytes-like objects.
"""
+
@classmethod
def setUpClass(cls):
prv_key_str = (
@@ -200,43 +215,87 @@ class TestSigningKey(unittest.TestCase):
"MF8CAQEEGF7IQgvW75JSqULpiQQ8op9WH6Uldw6xxaAKBggqhkjOPQMBAaE0AzIA\n"
"BLiBd9CE7xf15FY5QIAoNg+fWbSk1yZOYtoGUdzkejWkxbRc9RWTQjqLVXucIJnz\n"
"bA==\n"
- "-----END EC PRIVATE KEY-----\n")
- cls.sk1 = SigningKey.from_pem(prv_key_str)
-
+ "-----END EC PRIVATE KEY-----\n"
+ )
+ cls.sk1 = SigningKey.from_pem(prv_key_str)
+
+ prv_key_str = (
+ "-----BEGIN PRIVATE KEY-----\n"
+ "MG8CAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQEEVTBTAgEBBBheyEIL1u+SUqlC6YkE\n"
+ "PKKfVh+lJXcOscWhNAMyAAS4gXfQhO8X9eRWOUCAKDYPn1m0pNcmTmLaBlHc5Ho1\n"
+ "pMW0XPUVk0I6i1V7nCCZ82w=\n"
+ "-----END PRIVATE KEY-----\n"
+ )
+ cls.sk1_pkcs8 = SigningKey.from_pem(prv_key_str)
+
prv_key_str = (
"-----BEGIN EC PRIVATE KEY-----\n"
"MHcCAQEEIKlL2EAm5NPPZuXwxRf4nXMk0A80y6UUbiQ17be/qFhRoAoGCCqGSM49\n"
"AwEHoUQDQgAE4H3iRbG4TSrsSRb/gusPQB/4YcN8Poqzgjau4kfxBPyZimeRfuY/\n"
"9g/wMmPuhGl4BUve51DsnKJFRr8psk0ieA==\n"
- "-----END EC PRIVATE KEY-----\n")
- cls.sk2 = SigningKey.from_pem(prv_key_str)
-
- def test_equality_on_signing_keys(self):
- sk = SigningKey.from_secret_exponent(self.sk1.privkey.secret_multiplier, self.sk1.curve)
+ "-----END EC PRIVATE KEY-----\n"
+ )
+ cls.sk2 = SigningKey.from_pem(prv_key_str)
+
+ def test_equality_on_signing_keys(self):
+ sk = SigningKey.from_secret_exponent(
+ self.sk1.privkey.secret_multiplier, self.sk1.curve
+ )
self.assertEqual(self.sk1, sk)
-
+ self.assertEqual(self.sk1_pkcs8, sk)
+
+ def test_verify_with_precompute(self):
+ sig = self.sk1.sign(b"message")
+
+ vk = self.sk1.verifying_key
+
+ vk.precompute()
+
+ self.assertTrue(vk.verify(sig, b"message"))
+
+ def test_compare_verifying_key_with_precompute(self):
+ vk1 = self.sk1.verifying_key
+ vk1.precompute()
+
+ vk2 = self.sk1_pkcs8.verifying_key
+
+ self.assertEqual(vk1, vk2)
+
+ def test_verify_with_lazy_precompute(self):
+ sig = self.sk2.sign(b"other message")
+
+ vk = self.sk2.verifying_key
+
+ vk.precompute(lazy=True)
+
+ self.assertTrue(vk.verify(sig, b"other message"))
+
def test_inequality_on_signing_keys(self):
self.assertNotEqual(self.sk1, self.sk2)
-
+
def test_inequality_on_signing_keys_not_implemented(self):
self.assertNotEqual(self.sk1, None)
+
# test VerifyingKey.verify()
prv_key_str = (
"-----BEGIN EC PRIVATE KEY-----\n"
"MF8CAQEEGF7IQgvW75JSqULpiQQ8op9WH6Uldw6xxaAKBggqhkjOPQMBAaE0AzIA\n"
"BLiBd9CE7xf15FY5QIAoNg+fWbSk1yZOYtoGUdzkejWkxbRc9RWTQjqLVXucIJnz\n"
"bA==\n"
- "-----END EC PRIVATE KEY-----\n")
+ "-----END EC PRIVATE KEY-----\n"
+)
key_bytes = unpem(prv_key_str)
assert isinstance(key_bytes, bytes)
sk = SigningKey.from_der(key_bytes)
vk = sk.verifying_key
-data = (b"some string for signing"
- b"contents don't really matter"
- b"but do include also some crazy values: "
- b"\x00\x01\t\r\n\x00\x00\x00\xff\xf0")
+data = (
+ b"some string for signing"
+ b"contents don't really matter"
+ b"but do include also some crazy values: "
+ b"\x00\x01\t\r\n\x00\x00\x00\xff\xf0"
+)
assert len(data) % 4 == 0
sha1 = hashlib.sha1()
sha1.update(data)
@@ -255,11 +314,11 @@ for modifier, fun in [
("bytes memoryview", lambda x: buffer(x)),
("bytearray", lambda x: bytearray(x)),
("bytearray memoryview", lambda x: buffer(bytearray(x))),
- ("array.array of bytes", lambda x: array.array('B', x)),
- ("array.array of bytes memoryview", lambda x: buffer(array.array('B', x))),
- ("array.array of ints", lambda x: array.array('I', x)),
- ("array.array of ints memoryview", lambda x: buffer(array.array('I', x)))
- ]:
+ ("array.array of bytes", lambda x: array.array("B", x)),
+ ("array.array of bytes memoryview", lambda x: buffer(array.array("B", x))),
+ ("array.array of ints", lambda x: array.array("I", x)),
+ ("array.array of ints memoryview", lambda x: buffer(array.array("I", x))),
+]:
if "ints" in modifier:
conv = lambda x: x
else:
@@ -267,47 +326,60 @@ for modifier, fun in [
for sig_format, signature, decoder, mod_apply in [
("raw", sig_raw, sigdecode_string, lambda x: conv(x)),
("der", sig_der, sigdecode_der, lambda x: conv(x)),
- ("strings", sig_strings, sigdecode_strings, lambda x:
- tuple(conv(i) for i in x))
- ]:
+ (
+ "strings",
+ sig_strings,
+ sigdecode_strings,
+ lambda x: tuple(conv(i) for i in x),
+ ),
+ ]:
for method_name, vrf_mthd, vrf_data in [
("verify", vk.verify, data),
- ("verify_digest", vk.verify_digest, data_hash)
- ]:
- verifiers.append(pytest.param(
- signature, decoder, mod_apply, fun, vrf_mthd, vrf_data,
- id="{2}-{0}-{1}".format(modifier, sig_format, method_name)))
+ ("verify_digest", vk.verify_digest, data_hash),
+ ]:
+ verifiers.append(
+ pytest.param(
+ signature,
+ decoder,
+ mod_apply,
+ fun,
+ vrf_mthd,
+ vrf_data,
+ id="{2}-{0}-{1}".format(modifier, sig_format, method_name),
+ )
+ )
+
@pytest.mark.parametrize(
- "signature,decoder,mod_apply,fun,vrf_mthd,vrf_data",
- verifiers)
+ "signature,decoder,mod_apply,fun,vrf_mthd,vrf_data", verifiers
+)
def test_VerifyingKey_verify(
- signature, decoder, mod_apply, fun, vrf_mthd, vrf_data):
+ signature, decoder, mod_apply, fun, vrf_mthd, vrf_data
+):
sig = mod_apply(signature)
assert vrf_mthd(sig, fun(vrf_data), sigdecode=decoder)
# test SigningKey.from_string()
-prv_key_bytes = (b'^\xc8B\x0b\xd6\xef\x92R\xa9B\xe9\x89\x04<\xa2'
- b'\x9fV\x1f\xa5%w\x0e\xb1\xc5')
+prv_key_bytes = (
+ b"^\xc8B\x0b\xd6\xef\x92R\xa9B\xe9\x89\x04<\xa2"
+ b"\x9fV\x1f\xa5%w\x0e\xb1\xc5"
+)
assert len(prv_key_bytes) == 24
converters = []
for modifier, convert in [
- ("bytes", lambda x: x),
- ("bytes memoryview", buffer),
- ("bytearray", bytearray),
- ("bytearray memoryview", lambda x: buffer(bytearray(x))),
- ("array.array of bytes", lambda x: array.array('B', x)),
- ("array.array of bytes memoryview",
- lambda x: buffer(array.array('B', x))),
- ("array.array of ints", lambda x: array.array('I', x)),
- ("array.array of ints memoryview",
- lambda x: buffer(array.array('I', x)))
- ]:
- converters.append(pytest.param(
- convert,
- id=modifier))
+ ("bytes", lambda x: x),
+ ("bytes memoryview", buffer),
+ ("bytearray", bytearray),
+ ("bytearray memoryview", lambda x: buffer(bytearray(x))),
+ ("array.array of bytes", lambda x: array.array("B", x)),
+ ("array.array of bytes memoryview", lambda x: buffer(array.array("B", x))),
+ ("array.array of ints", lambda x: array.array("I", x)),
+ ("array.array of ints memoryview", lambda x: buffer(array.array("I", x))),
+]:
+ converters.append(pytest.param(convert, id=modifier))
+
@pytest.mark.parametrize("convert", converters)
def test_SigningKey_from_string(convert):
@@ -323,7 +395,8 @@ prv_key_str = (
"MF8CAQEEGF7IQgvW75JSqULpiQQ8op9WH6Uldw6xxaAKBggqhkjOPQMBAaE0AzIA\n"
"BLiBd9CE7xf15FY5QIAoNg+fWbSk1yZOYtoGUdzkejWkxbRc9RWTQjqLVXucIJnz\n"
"bA==\n"
- "-----END EC PRIVATE KEY-----\n")
+ "-----END EC PRIVATE KEY-----\n"
+)
key_bytes = unpem(prv_key_str)
assert isinstance(key_bytes, bytes)
@@ -338,13 +411,14 @@ def test_SigningKey_from_der(convert):
# test SigningKey.sign_deterministic()
-extra_entropy=b'\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11'
+extra_entropy = b"\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11"
+
@pytest.mark.parametrize("convert", converters)
def test_SigningKey_sign_deterministic(convert):
sig = sk.sign_deterministic(
- convert(data),
- extra_entropy=convert(extra_entropy))
+ convert(data), extra_entropy=convert(extra_entropy)
+ )
vk.verify(sig, data)
@@ -353,8 +427,8 @@ def test_SigningKey_sign_deterministic(convert):
@pytest.mark.parametrize("convert", converters)
def test_SigningKey_sign_digest_deterministic(convert):
sig = sk.sign_digest_deterministic(
- convert(data_hash),
- extra_entropy=convert(extra_entropy))
+ convert(data_hash), extra_entropy=convert(extra_entropy)
+ )
vk.verify(sig, data)
@@ -371,3 +445,10 @@ def test_SigningKey_sign_digest(convert):
sig = sk.sign_digest(convert(data_hash))
vk.verify(sig, data)
+
+
+def test_SigningKey_with_unlikely_value():
+ sk = SigningKey.from_secret_exponent(NIST256p.order - 1, curve=NIST256p)
+ vk = sk.verifying_key
+ sig = sk.sign(b"hello")
+ assert vk.verify(sig, b"hello")
diff --git a/freezed_deps/ecdsa/test_malformed_sigs.py b/frozen_deps/ecdsa/test_malformed_sigs.py
index c1dca44..4895cea 100644
--- a/freezed_deps/ecdsa/test_malformed_sigs.py
+++ b/frozen_deps/ecdsa/test_malformed_sigs.py
@@ -1,11 +1,18 @@
from __future__ import with_statement, division
import hashlib
+
try:
from hashlib import algorithms_available
except ImportError: # pragma: no cover
algorithms_available = [
- "md5", "sha1", "sha224", "sha256", "sha384", "sha512"]
+ "md5",
+ "sha1",
+ "sha224",
+ "sha256",
+ "sha384",
+ "sha512",
+ ]
from functools import partial
import pytest
import sys
@@ -18,16 +25,23 @@ from .keys import BadSignatureError
from .util import sigencode_der, sigencode_string
from .util import sigdecode_der, sigdecode_string
from .curves import curves, NIST256p
-from .der import encode_integer, encode_bitstring, encode_octet_string, \
- encode_oid, encode_sequence, encode_constructed
+from .der import (
+ encode_integer,
+ encode_bitstring,
+ encode_octet_string,
+ encode_oid,
+ encode_sequence,
+ encode_constructed,
+)
example_data = b"some data to sign"
"""Since the data is hashed for processing, really any string will do."""
-hash_and_size = [(name, hashlib.new(name).digest_size)
- for name in algorithms_available]
+hash_and_size = [
+ (name, hashlib.new(name).digest_size) for name in algorithms_available
+]
"""Pairs of hash names and their output sizes.
Needed for pairing with curves as we don't support hashes
bigger than order sizes of curves."""
@@ -39,26 +53,33 @@ keys_and_sigs = []
# for hypothesis strategy shrinking we want smallest curves and hashes first
for curve in sorted(curves, key=lambda x: x.baselen):
- for hash_alg in [name for name, size in
- sorted(hash_and_size, key=lambda x: x[1])
- if 0 < size <= curve.baselen]:
+ for hash_alg in [
+ name
+ for name, size in sorted(hash_and_size, key=lambda x: x[1])
+ if 0 < size <= curve.baselen
+ ]:
sk = SigningKey.generate(
- curve,
- hashfunc=partial(hashlib.new, hash_alg))
+ curve, hashfunc=partial(hashlib.new, hash_alg)
+ )
keys_and_sigs.append(
- ("{0} {1}".format(curve, hash_alg),
- sk.verifying_key,
- sk.sign(example_data, sigencode=sigencode_der)))
+ (
+ "{0} {1}".format(curve, hash_alg),
+ sk.verifying_key,
+ sk.sign(example_data, sigencode=sigencode_der),
+ )
+ )
# first make sure that the signatures can be verified
@pytest.mark.parametrize(
"verifying_key,signature",
- [pytest.param(vk, sig, id=name) for name, vk, sig in keys_and_sigs])
+ [pytest.param(vk, sig, id=name) for name, vk, sig in keys_and_sigs],
+)
def test_signatures(verifying_key, signature):
- assert verifying_key.verify(signature, example_data,
- sigdecode=sigdecode_der)
+ assert verifying_key.verify(
+ signature, example_data, sigdecode=sigdecode_der
+ )
@st.composite
@@ -73,9 +94,9 @@ def st_fuzzed_sig(draw, keys_and_sigs):
sig = bytearray(old_sig)
# decide which bytes should be removed
- to_remove = draw(st.lists(
- st.integers(min_value=0, max_value=len(sig)-1),
- unique=True))
+ to_remove = draw(
+ st.lists(st.integers(min_value=0, max_value=len(sig) - 1), unique=True)
+ )
to_remove.sort()
for i in reversed(to_remove):
del sig[i]
@@ -83,9 +104,12 @@ def st_fuzzed_sig(draw, keys_and_sigs):
# decide which bytes of the original signature should be changed
if sig: # pragma: no branch
- xors = draw(st.dictionaries(
- st.integers(min_value=0, max_value=len(sig)-1),
- st.integers(min_value=1, max_value=255)))
+ xors = draw(
+ st.dictionaries(
+ st.integers(min_value=0, max_value=len(sig) - 1),
+ st.integers(min_value=1, max_value=255),
+ )
+ )
for i, val in xors.items():
sig[i] ^= val
note("xors: {0}".format(xors))
@@ -96,8 +120,9 @@ def st_fuzzed_sig(draw, keys_and_sigs):
insert_data = draw(st.binary(max_size=256))
sig = sig[:insert_pos] + insert_data + sig[insert_pos:]
- note("Inserted at position {0} bytes: {1!r}"
- .format(insert_pos, insert_data))
+ note(
+ "Inserted at position {0} bytes: {1!r}".format(insert_pos, insert_data)
+ )
sig = bytes(sig)
# make sure that there was performed at least one mutation on the data
@@ -112,11 +137,14 @@ params = {}
# not supported in hypothesis 2.0.0
if sys.version_info >= (2, 7): # pragma: no branch
from hypothesis import HealthCheck
+
# deadline=5s because NIST521p are slow to verify
params["deadline"] = 5000
- params["suppress_health_check"] = [HealthCheck.data_too_large,
- HealthCheck.filter_too_much,
- HealthCheck.too_slow]
+ params["suppress_health_check"] = [
+ HealthCheck.data_too_large,
+ HealthCheck.filter_too_much,
+ HealthCheck.too_slow,
+ ]
slow_params = dict(params)
slow_params["max_examples"] = 10
@@ -151,10 +179,14 @@ def st_random_der_ecdsa_sig_value(draw):
# verifying that it doesn't accept them, so meh.
# Test all numbers around the ones that can show up (around order)
# way smaller and slightly bigger
- r = draw(st.integers(min_value=0, max_value=order << 4) |
- st.integers(min_value=order >> 2, max_value=order+1))
- s = draw(st.integers(min_value=0, max_value=order << 4) |
- st.integers(min_value=order >> 2, max_value=order+1))
+ r = draw(
+ st.integers(min_value=0, max_value=order << 4)
+ | st.integers(min_value=order >> 2, max_value=order + 1)
+ )
+ s = draw(
+ st.integers(min_value=0, max_value=order << 4)
+ | st.integers(min_value=order >> 2, max_value=order + 1)
+ )
sig = encode_sequence(encode_integer(r), encode_integer(s))
@@ -195,7 +227,7 @@ def st_der_bit_string(draw, *args, **kwargs):
if data:
unused = draw(st.integers(min_value=0, max_value=7))
data = bytearray(data)
- data[-1] &= - (2**unused)
+ data[-1] &= -(2 ** unused)
data = bytes(data)
else:
unused = 0
@@ -214,7 +246,7 @@ def st_der_null():
"""
Hypothesis strategy that returns DER NULL object.
"""
- return st.just(b'\x05\x00')
+ return st.just(b"\x05\x00")
@st.composite
@@ -226,9 +258,10 @@ def st_der_oid(draw):
if first < 2:
second = draw(st.integers(min_value=0, max_value=39))
else:
- second = draw(st.integers(min_value=0, max_value=2**512))
- rest = draw(st.lists(st.integers(min_value=0, max_value=2**512),
- max_size=50))
+ second = draw(st.integers(min_value=0, max_value=2 ** 512))
+ rest = draw(
+ st.lists(st.integers(min_value=0, max_value=2 ** 512), max_size=50)
+ )
return encode_oid(first, second, *rest)
@@ -241,20 +274,26 @@ def st_der():
encoding of any of the above.
"""
return st.recursive(
- st.just(b'') | st_der_integer(max_value=2**4096) |
- st_der_bit_string(max_size=1024**2) |
- st_der_octet_string(max_size=1024**2) | st_der_null() | st_der_oid(),
- lambda children:
- st.builds(lambda x: encode_octet_string(x), st.one_of(children)) |
- st.builds(lambda x: encode_bitstring(x, 0), st.one_of(children)) |
- st.builds(lambda x: encode_sequence(*x),
- st.lists(children, max_size=200)) |
- st.builds(lambda tag, x:
- encode_constructed(tag, x),
- st.integers(min_value=0, max_value=0x3f),
- st.one_of(children)),
- max_leaves=40
+ st.just(b"")
+ | st_der_integer(max_value=2 ** 4096)
+ | st_der_bit_string(max_size=1024 ** 2)
+ | st_der_octet_string(max_size=1024 ** 2)
+ | st_der_null()
+ | st_der_oid(),
+ lambda children: st.builds(
+ lambda x: encode_octet_string(x), st.one_of(children)
)
+ | st.builds(lambda x: encode_bitstring(x, 0), st.one_of(children))
+ | st.builds(
+ lambda x: encode_sequence(*x), st.lists(children, max_size=200)
+ )
+ | st.builds(
+ lambda tag, x: encode_constructed(tag, x),
+ st.integers(min_value=0, max_value=0x3F),
+ st.one_of(children),
+ ),
+ max_leaves=40,
+ )
@settings(**params)
@@ -268,16 +307,15 @@ def test_random_der_as_signature(params, der):
@settings(**params)
-@given(st.sampled_from(keys_and_sigs), st.binary(max_size=1024**2))
-@example(
- keys_and_sigs[0],
- encode_sequence(encode_integer(0), encode_integer(0)))
+@given(st.sampled_from(keys_and_sigs), st.binary(max_size=1024 ** 2))
@example(
- keys_and_sigs[0],
- encode_sequence(encode_integer(1), encode_integer(1)) + b'\x00')
+ keys_and_sigs[0], encode_sequence(encode_integer(0), encode_integer(0))
+)
@example(
keys_and_sigs[0],
- encode_sequence(*[encode_integer(1)] * 3))
+ encode_sequence(encode_integer(1), encode_integer(1)) + b"\x00",
+)
+@example(keys_and_sigs[0], encode_sequence(*[encode_integer(1)] * 3))
def test_random_bytes_as_signature(params, der):
"""Check if random bytes are rejected as signature"""
name, verifying_key, _ = params
@@ -287,10 +325,16 @@ def test_random_bytes_as_signature(params, der):
keys_and_string_sigs = [
- (name, verifying_key,
- sigencode_string(*sigdecode_der(sig, verifying_key.curve.order),
- order=verifying_key.curve.order))
- for name, verifying_key, sig in keys_and_sigs]
+ (
+ name,
+ verifying_key,
+ sigencode_string(
+ *sigdecode_der(sig, verifying_key.curve.order),
+ order=verifying_key.curve.order
+ ),
+ )
+ for name, verifying_key, sig in keys_and_sigs
+]
"""
Name of the curve+hash combination, VerifyingKey and signature as a
byte string.
diff --git a/freezed_deps/ecdsa/test_numbertheory.py b/frozen_deps/ecdsa/test_numbertheory.py
index 4cec4fd..4912c57 100644
--- a/freezed_deps/ecdsa/test_numbertheory.py
+++ b/frozen_deps/ecdsa/test_numbertheory.py
@@ -2,6 +2,7 @@ import operator
from six import print_
from functools import reduce
import operator
+
try:
import unittest2 as unittest
except ImportError:
@@ -9,49 +10,59 @@ except ImportError:
import hypothesis.strategies as st
import pytest
from hypothesis import given, settings, example
+
try:
from hypothesis import HealthCheck
- HC_PRESENT=True
+
+ HC_PRESENT = True
except ImportError: # pragma: no cover
- HC_PRESENT=False
-from .numbertheory import (SquareRootError, factorization, gcd, lcm,
- jacobi, inverse_mod,
- is_prime, next_prime, smallprimes,
- square_root_mod_prime)
-
-
-BIGPRIMES = (999671,
- 999683,
- 999721,
- 999727,
- 999749,
- 999763,
- 999769,
- 999773,
- 999809,
- 999853,
- 999863,
- 999883,
- 999907,
- 999917,
- 999931,
- 999953,
- 999959,
- 999961,
- 999979,
- 999983)
+ HC_PRESENT = False
+from .numbertheory import (
+ SquareRootError,
+ factorization,
+ gcd,
+ lcm,
+ jacobi,
+ inverse_mod,
+ is_prime,
+ next_prime,
+ smallprimes,
+ square_root_mod_prime,
+)
+
+
+BIGPRIMES = (
+ 999671,
+ 999683,
+ 999721,
+ 999727,
+ 999749,
+ 999763,
+ 999769,
+ 999773,
+ 999809,
+ 999853,
+ 999863,
+ 999883,
+ 999907,
+ 999917,
+ 999931,
+ 999953,
+ 999959,
+ 999961,
+ 999979,
+ 999983,
+)
@pytest.mark.parametrize(
- "prime, next_p",
- [(p, q) for p, q in zip(BIGPRIMES[:-1], BIGPRIMES[1:])])
+ "prime, next_p", [(p, q) for p, q in zip(BIGPRIMES[:-1], BIGPRIMES[1:])]
+)
def test_next_prime(prime, next_p):
assert next_prime(prime) == next_p
- "val",
- [-1, 0, 1])
[email protected]("val", [-1, 0, 1])
def test_next_prime_with_nums_less_2(val):
assert next_prime(val) == 2
@@ -77,9 +88,12 @@ def test_square_root_mod_prime_for_small_primes(prime):
def st_two_nums_rel_prime(draw):
# 521-bit is the biggest curve we operate on, use 1024 for a bit
# of breathing space
- mod = draw(st.integers(min_value=2, max_value=2**1024))
- num = draw(st.integers(min_value=1, max_value=mod-1)
- .filter(lambda x: gcd(x, mod) == 1))
+ mod = draw(st.integers(min_value=2, max_value=2 ** 1024))
+ num = draw(
+ st.integers(min_value=1, max_value=mod - 1).filter(
+ lambda x: gcd(x, mod) == 1
+ )
+ )
return num, mod
@@ -87,15 +101,16 @@ def st_two_nums_rel_prime(draw):
def st_primes(draw, *args, **kwargs):
if "min_value" not in kwargs: # pragma: no branch
kwargs["min_value"] = 1
- prime = draw(st.sampled_from(smallprimes) |
- st.integers(*args, **kwargs)
- .filter(is_prime))
+ prime = draw(
+ st.sampled_from(smallprimes)
+ | st.integers(*args, **kwargs).filter(is_prime)
+ )
return prime
@st.composite
def st_num_square_prime(draw):
- prime = draw(st_primes(max_value=2**1024))
+ prime = draw(st_primes(max_value=2 ** 1024))
num = draw(st.integers(min_value=0, max_value=1 + prime // 2))
sq = num * num % prime
return sq, prime
@@ -106,21 +121,27 @@ def st_comp_with_com_fac(draw):
"""
Strategy that returns lists of numbers, all having a common factor.
"""
- primes = draw(st.lists(st_primes(max_value=2**512), min_size=1,
- max_size=10))
+ primes = draw(
+ st.lists(st_primes(max_value=2 ** 512), min_size=1, max_size=10)
+ )
# select random prime(s) that will make the common factor of composites
- com_fac_primes = draw(st.lists(st.sampled_from(primes),
- min_size=1, max_size=20))
+ com_fac_primes = draw(
+ st.lists(st.sampled_from(primes), min_size=1, max_size=20)
+ )
com_fac = reduce(operator.mul, com_fac_primes, 1)
# select at most 20 lists (returned numbers),
# each having at most 30 primes (factors) including none (then the number
# will be 1)
comp_primes = draw(
- st.integers(min_value=1, max_value=20).
- flatmap(lambda n: st.lists(st.lists(st.sampled_from(primes),
- max_size=30),
- min_size=1, max_size=n)))
+ st.integers(min_value=1, max_value=20).flatmap(
+ lambda n: st.lists(
+ st.lists(st.sampled_from(primes), max_size=30),
+ min_size=1,
+ max_size=n,
+ )
+ )
+ )
return [reduce(operator.mul, nums, 1) * com_fac for nums in comp_primes]
@@ -130,13 +151,21 @@ def st_comp_no_com_fac(draw):
"""
Strategy that returns lists of numbers that don't have a common factor.
"""
- primes = draw(st.lists(st_primes(max_value=2**512),
- min_size=2, max_size=10, unique=True))
+ primes = draw(
+ st.lists(
+ st_primes(max_value=2 ** 512), min_size=2, max_size=10, unique=True
+ )
+ )
# first select the primes that will create the uncommon factor
# between returned numbers
- uncom_fac_primes = draw(st.lists(
- st.sampled_from(primes),
- min_size=1, max_size=len(primes)-1, unique=True))
+ uncom_fac_primes = draw(
+ st.lists(
+ st.sampled_from(primes),
+ min_size=1,
+ max_size=len(primes) - 1,
+ unique=True,
+ )
+ )
uncom_fac = reduce(operator.mul, uncom_fac_primes, 1)
# then build composites from leftover primes
@@ -148,10 +177,14 @@ def st_comp_no_com_fac(draw):
# select at most 20 lists, each having at most 30 primes
# selected from the leftover_primes list
number_primes = draw(
- st.integers(min_value=1, max_value=20).
- flatmap(lambda n: st.lists(st.lists(st.sampled_from(leftover_primes),
- max_size=30),
- min_size=1, max_size=n)))
+ st.integers(min_value=1, max_value=20).flatmap(
+ lambda n: st.lists(
+ st.lists(st.sampled_from(leftover_primes), max_size=30),
+ min_size=1,
+ max_size=n,
+ )
+ )
+ )
numbers = [reduce(operator.mul, nums, 1) for nums in number_primes]
@@ -162,13 +195,15 @@ def st_comp_no_com_fac(draw):
HYP_SETTINGS = {}
if HC_PRESENT: # pragma: no branch
- HYP_SETTINGS['suppress_health_check']=[HealthCheck.filter_too_much,
- HealthCheck.too_slow]
+ HYP_SETTINGS["suppress_health_check"] = [
+ HealthCheck.filter_too_much,
+ HealthCheck.too_slow,
+ ]
# the factorization() sometimes takes a long time to finish
- HYP_SETTINGS['deadline'] = 5000
+ HYP_SETTINGS["deadline"] = 5000
-HYP_SLOW_SETTINGS=dict(HYP_SETTINGS)
+HYP_SLOW_SETTINGS = dict(HYP_SETTINGS)
HYP_SLOW_SETTINGS["max_examples"] = 10
@@ -178,10 +213,12 @@ class TestNumbertheory(unittest.TestCase):
assert gcd([3 * 5 * 7, 3 * 5 * 11, 3 * 5 * 13]) == 3 * 5
assert gcd(3) == 3
- @unittest.skipUnless(HC_PRESENT,
- "Hypothesis 2.0.0 can't be made tolerant of hard to "
- "meet requirements (like `is_prime()`), the test "
- "case times-out on it")
+ @unittest.skipUnless(
+ HC_PRESENT,
+ "Hypothesis 2.0.0 can't be made tolerant of hard to "
+ "meet requirements (like `is_prime()`), the test "
+ "case times-out on it",
+ )
@settings(**HYP_SLOW_SETTINGS)
@given(st_comp_with_com_fac())
def test_gcd_with_com_factor(self, numbers):
@@ -190,18 +227,25 @@ class TestNumbertheory(unittest.TestCase):
for i in numbers:
assert i % n == 0
- @unittest.skipUnless(HC_PRESENT,
- "Hypothesis 2.0.0 can't be made tolerant of hard to "
- "meet requirements (like `is_prime()`), the test "
- "case times-out on it")
+ @unittest.skipUnless(
+ HC_PRESENT,
+ "Hypothesis 2.0.0 can't be made tolerant of hard to "
+ "meet requirements (like `is_prime()`), the test "
+ "case times-out on it",
+ )
@settings(**HYP_SLOW_SETTINGS)
@given(st_comp_no_com_fac())
def test_gcd_with_uncom_factor(self, numbers):
n = gcd(numbers)
assert n == 1
- @given(st.lists(st.integers(min_value=1, max_value=2**8192),
- min_size=1, max_size=20))
+ @given(
+ st.lists(
+ st.integers(min_value=1, max_value=2 ** 8192),
+ min_size=1,
+ max_size=20,
+ )
+ )
def test_gcd_with_random_numbers(self, numbers):
n = gcd(numbers)
for i in numbers:
@@ -213,17 +257,24 @@ class TestNumbertheory(unittest.TestCase):
assert lcm([3, 5 * 3, 7 * 3]) == 3 * 5 * 7
assert lcm(3) == 3
- @given(st.lists(st.integers(min_value=1, max_value=2**8192),
- min_size=1, max_size=20))
+ @given(
+ st.lists(
+ st.integers(min_value=1, max_value=2 ** 8192),
+ min_size=1,
+ max_size=20,
+ )
+ )
def test_lcm_with_random_numbers(self, numbers):
n = lcm(numbers)
for i in numbers:
assert n % i == 0
- @unittest.skipUnless(HC_PRESENT,
- "Hypothesis 2.0.0 can't be made tolerant of hard to "
- "meet requirements (like `is_prime()`), the test "
- "case times-out on it")
+ @unittest.skipUnless(
+ HC_PRESENT,
+ "Hypothesis 2.0.0 can't be made tolerant of hard to "
+ "meet requirements (like `is_prime()`), the test "
+ "case times-out on it",
+ )
@settings(**HYP_SETTINGS)
@given(st_num_square_prime())
def test_square_root_mod_prime(self, vals):
@@ -233,7 +284,7 @@ class TestNumbertheory(unittest.TestCase):
assert calc * calc % prime == square
@settings(**HYP_SETTINGS)
- @given(st.integers(min_value=1, max_value=10**12))
+ @given(st.integers(min_value=1, max_value=10 ** 12))
@example(265399 * 1526929)
@example(373297 ** 2 * 553991)
def test_factorization(self, num):
diff --git a/freezed_deps/ecdsa/test_pyecdsa.py b/frozen_deps/ecdsa/test_pyecdsa.py
index d83eb01..65b6716 100644
--- a/freezed_deps/ecdsa/test_pyecdsa.py
+++ b/frozen_deps/ecdsa/test_pyecdsa.py
@@ -23,15 +23,30 @@ from .keys import BadSignatureError, MalformedPointError, BadDigestError
from . import util
from .util import sigencode_der, sigencode_strings
from .util import sigdecode_der, sigdecode_strings
-from .util import number_to_string, encoded_oid_ecPublicKey, \
- MalformedSignature
+from .util import number_to_string, encoded_oid_ecPublicKey, MalformedSignature
from .curves import Curve, UnknownCurveError
-from .curves import NIST192p, NIST224p, NIST256p, NIST384p, NIST521p, \
- SECP256k1, BRAINPOOLP160r1, BRAINPOOLP192r1, BRAINPOOLP224r1, \
- BRAINPOOLP256r1, BRAINPOOLP320r1, BRAINPOOLP384r1, BRAINPOOLP512r1, \
- curves
-from .ecdsa import curve_brainpoolp224r1, curve_brainpoolp256r1, \
- curve_brainpoolp384r1, curve_brainpoolp512r1
+from .curves import (
+ NIST192p,
+ NIST224p,
+ NIST256p,
+ NIST384p,
+ NIST521p,
+ SECP256k1,
+ BRAINPOOLP160r1,
+ BRAINPOOLP192r1,
+ BRAINPOOLP224r1,
+ BRAINPOOLP256r1,
+ BRAINPOOLP320r1,
+ BRAINPOOLP384r1,
+ BRAINPOOLP512r1,
+ curves,
+)
+from .ecdsa import (
+ curve_brainpoolp224r1,
+ curve_brainpoolp256r1,
+ curve_brainpoolp384r1,
+ curve_brainpoolp512r1,
+)
from .ellipticcurve import Point
from . import der
from . import rfc6979
@@ -44,13 +59,17 @@ class SubprocessError(Exception):
def run_openssl(cmd):
OPENSSL = "openssl"
- p = subprocess.Popen([OPENSSL] + cmd.split(),
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
+ p = subprocess.Popen(
+ [OPENSSL] + cmd.split(),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ )
stdout, ignored = p.communicate()
if p.returncode != 0:
- raise SubprocessError("cmd '%s %s' failed: rc=%s, stdout/err was %s" %
- (OPENSSL, cmd, p.returncode, stdout))
+ raise SubprocessError(
+ "cmd '%s %s' failed: rc=%s, stdout/err was %s"
+ % (OPENSSL, cmd, p.returncode, stdout)
+ )
return stdout.decode()
@@ -76,7 +95,8 @@ class ECDSA(unittest.TestCase):
pub = priv.get_verifying_key()
k = rfc6979.generate_k(
- SECP256k1.generator.order(), secexp, sha256, sha256(data).digest())
+ SECP256k1.generator.order(), secexp, sha256, sha256(data).digest()
+ )
sig1 = priv.sign(data, k=k)
self.assertTrue(pub.verify(sig1, data))
@@ -102,18 +122,27 @@ class ECDSA(unittest.TestCase):
self.assertEqual(len(pub.to_string()), default.verifying_key_length)
sig = priv.sign(b("data"))
self.assertEqual(len(sig), default.signature_length)
- for curve in (NIST192p, NIST224p, NIST256p, NIST384p, NIST521p,
- BRAINPOOLP160r1, BRAINPOOLP192r1, BRAINPOOLP224r1,
- BRAINPOOLP256r1, BRAINPOOLP320r1, BRAINPOOLP384r1,
- BRAINPOOLP512r1):
+ for curve in (
+ NIST192p,
+ NIST224p,
+ NIST256p,
+ NIST384p,
+ NIST521p,
+ BRAINPOOLP160r1,
+ BRAINPOOLP192r1,
+ BRAINPOOLP224r1,
+ BRAINPOOLP256r1,
+ BRAINPOOLP320r1,
+ BRAINPOOLP384r1,
+ BRAINPOOLP512r1,
+ ):
start = time.time()
priv = SigningKey.generate(curve=curve)
pub1 = priv.get_verifying_key()
keygen_time = time.time() - start
pub2 = VerifyingKey.from_string(pub1.to_string(), curve)
self.assertEqual(pub1.to_string(), pub2.to_string())
- self.assertEqual(len(pub1.to_string()),
- curve.verifying_key_length)
+ self.assertEqual(len(pub1.to_string()), curve.verifying_key_length)
start = time.time()
sig = priv.sign(b("data"))
sign_time = time.time() - start
@@ -127,8 +156,9 @@ class ECDSA(unittest.TestCase):
self.assertEqual(secexp1, secexp2)
priv1 = SigningKey.from_secret_exponent(secexp1, curve)
priv2 = SigningKey.from_secret_exponent(secexp2, curve)
- self.assertEqual(hexlify(priv1.to_string()),
- hexlify(priv2.to_string()))
+ self.assertEqual(
+ hexlify(priv1.to_string()), hexlify(priv2.to_string())
+ )
self.assertEqual(priv1.to_pem(), priv2.to_pem())
pub1 = priv1.get_verifying_key()
pub2 = priv2.get_verifying_key()
@@ -139,8 +169,7 @@ class ECDSA(unittest.TestCase):
self.assertTrue(pub2.verify(sig1, data))
self.assertTrue(pub1.verify(sig2, data))
self.assertTrue(pub2.verify(sig2, data))
- self.assertEqual(hexlify(pub1.to_string()),
- hexlify(pub2.to_string()))
+ self.assertEqual(hexlify(pub1.to_string()), hexlify(pub2.to_string()))
def test_nonrandom(self):
s = b("all the entropy in the entire world, compressed into one line")
@@ -151,8 +180,10 @@ class ECDSA(unittest.TestCase):
# we control the entropy source, these two keys should be identical:
priv1 = SigningKey.generate(entropy=not_much_entropy)
priv2 = SigningKey.generate(entropy=not_much_entropy)
- self.assertEqual(hexlify(priv1.get_verifying_key().to_string()),
- hexlify(priv2.get_verifying_key().to_string()))
+ self.assertEqual(
+ hexlify(priv1.get_verifying_key().to_string()),
+ hexlify(priv2.get_verifying_key().to_string()),
+ )
# likewise, signatures should be identical. Obviously you'd never
# want to do this with keys you care about, because the secrecy of
# the private key depends upon using different random numbers for
@@ -162,10 +193,13 @@ class ECDSA(unittest.TestCase):
self.assertEqual(hexlify(sig1), hexlify(sig2))
def assertTruePrivkeysEqual(self, priv1, priv2):
- self.assertEqual(priv1.privkey.secret_multiplier,
- priv2.privkey.secret_multiplier)
- self.assertEqual(priv1.privkey.public_key.generator,
- priv2.privkey.public_key.generator)
+ self.assertEqual(
+ priv1.privkey.secret_multiplier, priv2.privkey.secret_multiplier
+ )
+ self.assertEqual(
+ priv1.privkey.public_key.generator,
+ priv2.privkey.public_key.generator,
+ )
def test_privkey_creation(self):
s = b("all the entropy in the entire world, compressed into one line")
@@ -267,15 +301,18 @@ class ECDSA(unittest.TestCase):
pub2 = VerifyingKey.from_der(pub1_der)
self.assertTruePubkeysEqual(pub1, pub2)
- self.assertRaises(der.UnexpectedDER,
- VerifyingKey.from_der, pub1_der + b("junk"))
+ self.assertRaises(
+ der.UnexpectedDER, VerifyingKey.from_der, pub1_der + b("junk")
+ )
badpub = VerifyingKey.from_der(pub1_der)
class FakeGenerator:
def order(self):
return 123456789
- badcurve = Curve("unknown", None, FakeGenerator(), (1, 2, 3, 4, 5, 6), None)
+ badcurve = Curve(
+ "unknown", None, FakeGenerator(), (1, 2, 3, 4, 5, 6), None
+ )
badpub.curve = badcurve
badder = badpub.to_der()
self.assertRaises(UnknownCurveError, VerifyingKey.from_der, badder)
@@ -283,7 +320,9 @@ class ECDSA(unittest.TestCase):
pem = pub1.to_pem()
self.assertEqual(type(pem), binary_type)
self.assertTrue(pem.startswith(b("-----BEGIN PUBLIC KEY-----")), pem)
- self.assertTrue(pem.strip().endswith(b("-----END PUBLIC KEY-----")), pem)
+ self.assertTrue(
+ pem.strip().endswith(b("-----END PUBLIC KEY-----")), pem
+ )
pub2 = VerifyingKey.from_pem(pem)
self.assertTruePubkeysEqual(pub1, pub2)
@@ -316,10 +355,11 @@ class ECDSA(unittest.TestCase):
def test_vk_from_der_garbage_after_curve_oid(self):
type_oid_der = encoded_oid_ecPublicKey
- curve_oid_der = der.encode_oid(*(1, 2, 840, 10045, 3, 1, 1)) + \
- b('garbage')
+ curve_oid_der = der.encode_oid(*(1, 2, 840, 10045, 3, 1, 1)) + b(
+ "garbage"
+ )
enc_type_der = der.encode_sequence(type_oid_der, curve_oid_der)
- point_der = der.encode_bitstring(b'\x00\xff', None)
+ point_der = der.encode_bitstring(b"\x00\xff", None)
to_decode = der.encode_sequence(enc_type_der, point_der)
with self.assertRaises(der.UnexpectedDER):
@@ -329,7 +369,7 @@ class ECDSA(unittest.TestCase):
type_oid_der = der.encode_oid(*(1, 2, 3))
curve_oid_der = der.encode_oid(*(1, 2, 840, 10045, 3, 1, 1))
enc_type_der = der.encode_sequence(type_oid_der, curve_oid_der)
- point_der = der.encode_bitstring(b'\x00\xff', None)
+ point_der = der.encode_bitstring(b"\x00\xff", None)
to_decode = der.encode_sequence(enc_type_der, point_der)
with self.assertRaises(der.UnexpectedDER):
@@ -339,7 +379,7 @@ class ECDSA(unittest.TestCase):
type_oid_der = encoded_oid_ecPublicKey
curve_oid_der = der.encode_oid(*(1, 2, 840, 10045, 3, 1, 1))
enc_type_der = der.encode_sequence(type_oid_der, curve_oid_der)
- point_der = der.encode_bitstring(b'\x00\xff', None) + b('garbage')
+ point_der = der.encode_bitstring(b"\x00\xff", None) + b("garbage")
to_decode = der.encode_sequence(enc_type_der, point_der)
with self.assertRaises(der.UnexpectedDER):
@@ -349,7 +389,7 @@ class ECDSA(unittest.TestCase):
type_oid_der = encoded_oid_ecPublicKey
curve_oid_der = der.encode_oid(*(1, 2, 840, 10045, 3, 1, 1))
enc_type_der = der.encode_sequence(type_oid_der, curve_oid_der)
- point_der = der.encode_bitstring(b'\x08\xff', None)
+ point_der = der.encode_bitstring(b"\x08\xff", None)
to_decode = der.encode_sequence(enc_type_der, point_der)
with self.assertRaises(der.UnexpectedDER):
@@ -359,7 +399,7 @@ class ECDSA(unittest.TestCase):
type_oid_der = encoded_oid_ecPublicKey
curve_oid_der = der.encode_oid(*(1, 2, 840, 10045, 3, 1, 1))
enc_type_der = der.encode_sequence(type_oid_der, curve_oid_der)
- point_der = der.encode_bitstring(b'\xff'*64, 0)
+ point_der = der.encode_bitstring(b"\xff" * 64, 0)
to_decode = der.encode_sequence(enc_type_der, point_der)
with self.assertRaises(MalformedPointError):
@@ -369,7 +409,7 @@ class ECDSA(unittest.TestCase):
type_oid_der = encoded_oid_ecPublicKey
curve_oid_der = der.encode_oid(*(1, 2, 840, 10045, 3, 1, 1))
enc_type_der = der.encode_sequence(type_oid_der, curve_oid_der)
- point_der = der.encode_bitstring(b'\xff'*48, 0)
+ point_der = der.encode_bitstring(b"\xff" * 48, 0)
to_decode = der.encode_sequence(enc_type_der, point_der)
with self.assertRaises(der.UnexpectedDER):
@@ -400,22 +440,22 @@ class ECDSA(unittest.TestCase):
def test_sig_decode_strings_with_invalid_count(self):
with self.assertRaises(MalformedSignature):
- sigdecode_strings([b('one'), b('two'), b('three')], 0xff)
+ sigdecode_strings([b("one"), b("two"), b("three")], 0xFF)
def test_sig_decode_strings_with_wrong_r_len(self):
with self.assertRaises(MalformedSignature):
- sigdecode_strings([b('one'), b('two')], 0xff)
+ sigdecode_strings([b("one"), b("two")], 0xFF)
def test_sig_decode_strings_with_wrong_s_len(self):
with self.assertRaises(MalformedSignature):
- sigdecode_strings([b('\xa0'), b('\xb0\xff')], 0xff)
+ sigdecode_strings([b("\xa0"), b("\xb0\xff")], 0xFF)
def test_verify_with_too_long_input(self):
sk = SigningKey.generate()
vk = sk.verifying_key
with self.assertRaises(BadDigestError):
- vk.verify_digest(None, b('\x00') * 128)
+ vk.verify_digest(None, b("\x00") * 128)
def test_sk_from_secret_exponent_with_wrong_sec_exponent(self):
with self.assertRaises(MalformedPointError):
@@ -423,11 +463,11 @@ class ECDSA(unittest.TestCase):
def test_sk_from_string_with_wrong_len_string(self):
with self.assertRaises(MalformedPointError):
- SigningKey.from_string(b('\x01'))
+ SigningKey.from_string(b("\x01"))
def test_sk_from_der_with_junk_after_sequence(self):
ver_der = der.encode_integer(1)
- to_decode = der.encode_sequence(ver_der) + b('garbage')
+ to_decode = der.encode_sequence(ver_der) + b("garbage")
with self.assertRaises(der.UnexpectedDER):
SigningKey.from_der(to_decode)
@@ -441,59 +481,137 @@ class ECDSA(unittest.TestCase):
def test_sk_from_der_invalid_const_tag(self):
ver_der = der.encode_integer(1)
- privkey_der = der.encode_octet_string(b('\x00\xff'))
+ privkey_der = der.encode_octet_string(b("\x00\xff"))
curve_oid_der = der.encode_oid(*(1, 2, 3))
const_der = der.encode_constructed(1, curve_oid_der)
- to_decode = der.encode_sequence(ver_der, privkey_der, const_der,
- curve_oid_der)
+ to_decode = der.encode_sequence(
+ ver_der, privkey_der, const_der, curve_oid_der
+ )
with self.assertRaises(der.UnexpectedDER):
SigningKey.from_der(to_decode)
def test_sk_from_der_garbage_after_privkey_oid(self):
ver_der = der.encode_integer(1)
- privkey_der = der.encode_octet_string(b('\x00\xff'))
- curve_oid_der = der.encode_oid(*(1, 2, 3)) + b('garbage')
+ privkey_der = der.encode_octet_string(b("\x00\xff"))
+ curve_oid_der = der.encode_oid(*(1, 2, 3)) + b("garbage")
const_der = der.encode_constructed(0, curve_oid_der)
- to_decode = der.encode_sequence(ver_der, privkey_der, const_der,
- curve_oid_der)
+ to_decode = der.encode_sequence(
+ ver_der, privkey_der, const_der, curve_oid_der
+ )
with self.assertRaises(der.UnexpectedDER):
SigningKey.from_der(to_decode)
def test_sk_from_der_with_short_privkey(self):
ver_der = der.encode_integer(1)
- privkey_der = der.encode_octet_string(b('\x00\xff'))
+ privkey_der = der.encode_octet_string(b("\x00\xff"))
curve_oid_der = der.encode_oid(*(1, 2, 840, 10045, 3, 1, 1))
const_der = der.encode_constructed(0, curve_oid_der)
- to_decode = der.encode_sequence(ver_der, privkey_der, const_der,
- curve_oid_der)
+ to_decode = der.encode_sequence(
+ ver_der, privkey_der, const_der, curve_oid_der
+ )
sk = SigningKey.from_der(to_decode)
self.assertEqual(sk.privkey.secret_multiplier, 255)
+ def test_sk_from_p8_der_with_wrong_version(self):
+ ver_der = der.encode_integer(2)
+ algorithm_der = der.encode_sequence(
+ der.encode_oid(1, 2, 840, 10045, 2, 1),
+ der.encode_oid(1, 2, 840, 10045, 3, 1, 1),
+ )
+ privkey_der = der.encode_octet_string(
+ der.encode_sequence(
+ der.encode_integer(1), der.encode_octet_string(b"\x00\xff")
+ )
+ )
+ to_decode = der.encode_sequence(ver_der, algorithm_der, privkey_der)
+
+ with self.assertRaises(der.UnexpectedDER):
+ SigningKey.from_der(to_decode)
+
+ def test_sk_from_p8_der_with_wrong_algorithm(self):
+ ver_der = der.encode_integer(1)
+ algorithm_der = der.encode_sequence(
+ der.encode_oid(1, 2, 3), der.encode_oid(1, 2, 840, 10045, 3, 1, 1)
+ )
+ privkey_der = der.encode_octet_string(
+ der.encode_sequence(
+ der.encode_integer(1), der.encode_octet_string(b"\x00\xff")
+ )
+ )
+ to_decode = der.encode_sequence(ver_der, algorithm_der, privkey_der)
+
+ with self.assertRaises(der.UnexpectedDER):
+ SigningKey.from_der(to_decode)
+
+ def test_sk_from_p8_der_with_trailing_junk_after_algorithm(self):
+ ver_der = der.encode_integer(1)
+ algorithm_der = der.encode_sequence(
+ der.encode_oid(1, 2, 840, 10045, 2, 1),
+ der.encode_oid(1, 2, 840, 10045, 3, 1, 1),
+ der.encode_octet_string(b"junk"),
+ )
+ privkey_der = der.encode_octet_string(
+ der.encode_sequence(
+ der.encode_integer(1), der.encode_octet_string(b"\x00\xff")
+ )
+ )
+ to_decode = der.encode_sequence(ver_der, algorithm_der, privkey_der)
+
+ with self.assertRaises(der.UnexpectedDER):
+ SigningKey.from_der(to_decode)
+
+ def test_sk_from_p8_der_with_trailing_junk_after_key(self):
+ ver_der = der.encode_integer(1)
+ algorithm_der = der.encode_sequence(
+ der.encode_oid(1, 2, 840, 10045, 2, 1),
+ der.encode_oid(1, 2, 840, 10045, 3, 1, 1),
+ )
+ privkey_der = der.encode_octet_string(
+ der.encode_sequence(
+ der.encode_integer(1), der.encode_octet_string(b"\x00\xff")
+ )
+ + der.encode_integer(999)
+ )
+ to_decode = der.encode_sequence(
+ ver_der,
+ algorithm_der,
+ privkey_der,
+ der.encode_octet_string(b"junk"),
+ )
+
+ with self.assertRaises(der.UnexpectedDER):
+ SigningKey.from_der(to_decode)
+
def test_sign_with_too_long_hash(self):
sk = SigningKey.from_secret_exponent(12)
with self.assertRaises(BadDigestError):
- sk.sign_digest(b('\xff') * 64)
+ sk.sign_digest(b("\xff") * 64)
def test_hashfunc(self):
sk = SigningKey.generate(curve=NIST256p, hashfunc=sha256)
data = b("security level is 128 bits")
sig = sk.sign(data)
- vk = VerifyingKey.from_string(sk.get_verifying_key().to_string(),
- curve=NIST256p, hashfunc=sha256)
+ vk = VerifyingKey.from_string(
+ sk.get_verifying_key().to_string(), curve=NIST256p, hashfunc=sha256
+ )
self.assertTrue(vk.verify(sig, data))
sk2 = SigningKey.generate(curve=NIST256p)
sig2 = sk2.sign(data, hashfunc=sha256)
- vk2 = VerifyingKey.from_string(sk2.get_verifying_key().to_string(),
- curve=NIST256p, hashfunc=sha256)
+ vk2 = VerifyingKey.from_string(
+ sk2.get_verifying_key().to_string(),
+ curve=NIST256p,
+ hashfunc=sha256,
+ )
self.assertTrue(vk2.verify(sig2, data))
- vk3 = VerifyingKey.from_string(sk.get_verifying_key().to_string(),
- curve=NIST256p)
+ vk3 = VerifyingKey.from_string(
+ sk.get_verifying_key().to_string(), curve=NIST256p
+ )
self.assertTrue(vk3.verify(sig, data, hashfunc=sha256))
def test_public_key_recovery(self):
@@ -508,7 +626,9 @@ class ECDSA(unittest.TestCase):
signature = sk.sign(data)
# Recover verifying keys
- recovered_vks = VerifyingKey.from_public_key_recovery(signature, data, curve)
+ recovered_vks = VerifyingKey.from_public_key_recovery(
+ signature, data, curve
+ )
# Test if each pk is valid
for recovered_vk in recovered_vks:
@@ -517,11 +637,15 @@ class ECDSA(unittest.TestCase):
# Test if properties are equal
self.assertEqual(vk.curve, recovered_vk.curve)
- self.assertEqual(vk.default_hashfunc, recovered_vk.default_hashfunc)
+ self.assertEqual(
+ vk.default_hashfunc, recovered_vk.default_hashfunc
+ )
# Test if original vk is the list of recovered keys
self.assertTrue(
- vk.pubkey.point in [recovered_vk.pubkey.point for recovered_vk in recovered_vks])
+ vk.pubkey.point
+ in [recovered_vk.pubkey.point for recovered_vk in recovered_vks]
+ )
def test_public_key_recovery_with_custom_hash(self):
# Create keys
@@ -535,9 +659,9 @@ class ECDSA(unittest.TestCase):
signature = sk.sign(data)
# Recover verifying keys
- recovered_vks = VerifyingKey.\
- from_public_key_recovery(signature, data, curve,
- hashfunc=sha256)
+ recovered_vks = VerifyingKey.from_public_key_recovery(
+ signature, data, curve, hashfunc=sha256
+ )
# Test if each pk is valid
for recovered_vk in recovered_vks:
@@ -549,84 +673,98 @@ class ECDSA(unittest.TestCase):
self.assertEqual(sha256, recovered_vk.default_hashfunc)
# Test if original vk is the list of recovered keys
- self.assertTrue(vk.pubkey.point in
- [recovered_vk.pubkey.point for recovered_vk in recovered_vks])
+ self.assertTrue(
+ vk.pubkey.point
+ in [recovered_vk.pubkey.point for recovered_vk in recovered_vks]
+ )
def test_encoding(self):
sk = SigningKey.from_secret_exponent(123456789)
vk = sk.verifying_key
- exp = b('\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3'
- '\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4'
- 'z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*')
+ exp = b(
+ "\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3"
+ "\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4"
+ "z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*"
+ )
self.assertEqual(vk.to_string(), exp)
- self.assertEqual(vk.to_string('raw'), exp)
- self.assertEqual(vk.to_string('uncompressed'), b('\x04') + exp)
- self.assertEqual(vk.to_string('compressed'), b('\x02') + exp[:24])
- self.assertEqual(vk.to_string('hybrid'), b('\x06') + exp)
+ self.assertEqual(vk.to_string("raw"), exp)
+ self.assertEqual(vk.to_string("uncompressed"), b("\x04") + exp)
+ self.assertEqual(vk.to_string("compressed"), b("\x02") + exp[:24])
+ self.assertEqual(vk.to_string("hybrid"), b("\x06") + exp)
def test_decoding(self):
sk = SigningKey.from_secret_exponent(123456789)
vk = sk.verifying_key
- enc = b('\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3'
- '\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4'
- 'z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*')
+ enc = b(
+ "\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3"
+ "\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4"
+ "z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*"
+ )
from_raw = VerifyingKey.from_string(enc)
self.assertEqual(from_raw.pubkey.point, vk.pubkey.point)
- from_uncompressed = VerifyingKey.from_string(b('\x04') + enc)
+ from_uncompressed = VerifyingKey.from_string(b("\x04") + enc)
self.assertEqual(from_uncompressed.pubkey.point, vk.pubkey.point)
- from_compressed = VerifyingKey.from_string(b('\x02') + enc[:24])
+ from_compressed = VerifyingKey.from_string(b("\x02") + enc[:24])
self.assertEqual(from_compressed.pubkey.point, vk.pubkey.point)
- from_uncompressed = VerifyingKey.from_string(b('\x06') + enc)
+ from_uncompressed = VerifyingKey.from_string(b("\x06") + enc)
self.assertEqual(from_uncompressed.pubkey.point, vk.pubkey.point)
def test_decoding_with_malformed_uncompressed(self):
- enc = b('\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3'
- '\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4'
- 'z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*')
+ enc = b(
+ "\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3"
+ "\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4"
+ "z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*"
+ )
with self.assertRaises(MalformedPointError):
- VerifyingKey.from_string(b('\x02') + enc)
+ VerifyingKey.from_string(b("\x02") + enc)
def test_decoding_with_malformed_compressed(self):
- enc = b('\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3'
- '\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4'
- 'z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*')
+ enc = b(
+ "\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3"
+ "\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4"
+ "z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*"
+ )
with self.assertRaises(MalformedPointError):
- VerifyingKey.from_string(b('\x01') + enc[:24])
+ VerifyingKey.from_string(b("\x01") + enc[:24])
def test_decoding_with_inconsistent_hybrid(self):
- enc = b('\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3'
- '\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4'
- 'z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*')
+ enc = b(
+ "\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3"
+ "\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4"
+ "z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*"
+ )
with self.assertRaises(MalformedPointError):
- VerifyingKey.from_string(b('\x07') + enc)
+ VerifyingKey.from_string(b("\x07") + enc)
def test_decoding_with_point_not_on_curve(self):
- enc = b('\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3'
- '\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4'
- 'z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*')
+ enc = b(
+ "\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3"
+ "\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4"
+ "z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*"
+ )
with self.assertRaises(MalformedPointError):
- VerifyingKey.from_string(enc[:47] + b('\x00'))
+ VerifyingKey.from_string(enc[:47] + b("\x00"))
def test_decoding_with_point_at_infinity(self):
# decoding it is unsupported, as it's not necessary to encode it
with self.assertRaises(MalformedPointError):
- VerifyingKey.from_string(b('\x00'))
+ VerifyingKey.from_string(b("\x00"))
def test_not_lying_on_curve(self):
- enc = number_to_string(NIST192p.curve.p(), NIST192p.curve.p()+1)
+ enc = number_to_string(NIST192p.curve.p(), NIST192p.curve.p() + 1)
with self.assertRaises(MalformedPointError):
- VerifyingKey.from_string(b('\x02') + enc)
+ VerifyingKey.from_string(b("\x02") + enc)
def test_from_string_with_invalid_curve_too_short_ver_key_len(self):
# both verifying_key_length and baselen are calculated internally
@@ -637,7 +775,7 @@ class ECDSA(unittest.TestCase):
curve.baselen = 32
with self.assertRaises(MalformedPointError):
- VerifyingKey.from_string(b('\x00')*16, curve)
+ VerifyingKey.from_string(b("\x00") * 16, curve)
def test_from_string_with_invalid_curve_too_long_ver_key_len(self):
# both verifying_key_length and baselen are calculated internally
@@ -648,18 +786,19 @@ class ECDSA(unittest.TestCase):
curve.baselen = 16
with self.assertRaises(MalformedPointError):
- VerifyingKey.from_string(b('\x00')*16, curve)
+ VerifyingKey.from_string(b("\x00") * 16, curve)
[email protected]("val,even",
- [(i, j) for i in range(256) for j in [True, False]])
+ "val,even", [(i, j) for i in range(256) for j in [True, False]]
+)
def test_VerifyingKey_decode_with_small_values(val, even):
enc = number_to_string(val, NIST192p.order)
if even:
- enc = b('\x02') + enc
+ enc = b("\x02") + enc
else:
- enc = b('\x03') + enc
+ enc = b("\x03") + enc
# small values can both be actual valid public keys and not, verify that
# only expected exceptions are raised if they are not
@@ -673,8 +812,9 @@ def test_VerifyingKey_decode_with_small_values(val, even):
params = []
for curve in curves:
for enc in ["raw", "uncompressed", "compressed", "hybrid"]:
- params.append(pytest.param(curve, enc, id="{0}-{1}".format(
- curve.name, enc)))
+ params.append(
+ pytest.param(curve, enc, id="{0}-{1}".format(curve.name, enc))
+ )
@pytest.mark.parametrize("curve,encoding", params)
@@ -706,9 +846,10 @@ class OpenSSL(unittest.TestCase):
# openssl ec -in privkey.pem -pubout -out pubkey.pem
# openssl ec -in privkey.pem -pubout -outform DER -out pubkey.der
- OPENSSL_SUPPORTED_CURVES = set(c.split(':')[0].strip() for c in
- run_openssl("ecparam -list_curves")
- .split('\n'))
+ OPENSSL_SUPPORTED_CURVES = set(
+ c.split(":")[0].strip()
+ for c in run_openssl("ecparam -list_curves").split("\n")
+ )
def get_openssl_messagedigest_arg(self, hash_name):
v = run_openssl("version")
@@ -724,83 +865,115 @@ class OpenSSL(unittest.TestCase):
# vk: 3:OpenSSL->python 4:python->OpenSSL
# sig: 5:OpenSSL->python 6:python->OpenSSL
- @pytest.mark.skipif("prime192v1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support prime192v1")
+ @pytest.mark.skipif(
+ "prime192v1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support prime192v1",
+ )
def test_from_openssl_nist192p(self):
return self.do_test_from_openssl(NIST192p)
- @pytest.mark.skipif("prime192v1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support prime192v1")
+ @pytest.mark.skipif(
+ "prime192v1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support prime192v1",
+ )
def test_from_openssl_nist192p_sha256(self):
return self.do_test_from_openssl(NIST192p, "SHA256")
- @pytest.mark.skipif("secp224r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support secp224r1")
+ @pytest.mark.skipif(
+ "secp224r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support secp224r1",
+ )
def test_from_openssl_nist224p(self):
return self.do_test_from_openssl(NIST224p)
- @pytest.mark.skipif("prime256v1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support prime256v1")
+ @pytest.mark.skipif(
+ "prime256v1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support prime256v1",
+ )
def test_from_openssl_nist256p(self):
return self.do_test_from_openssl(NIST256p)
- @pytest.mark.skipif("prime256v1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support prime256v1")
+ @pytest.mark.skipif(
+ "prime256v1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support prime256v1",
+ )
def test_from_openssl_nist256p_sha384(self):
return self.do_test_from_openssl(NIST256p, "SHA384")
- @pytest.mark.skipif("prime256v1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support prime256v1")
+ @pytest.mark.skipif(
+ "prime256v1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support prime256v1",
+ )
def test_from_openssl_nist256p_sha512(self):
return self.do_test_from_openssl(NIST256p, "SHA512")
- @pytest.mark.skipif("secp384r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support secp384r1")
+ @pytest.mark.skipif(
+ "secp384r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support secp384r1",
+ )
def test_from_openssl_nist384p(self):
return self.do_test_from_openssl(NIST384p)
- @pytest.mark.skipif("secp521r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support secp521r1")
+ @pytest.mark.skipif(
+ "secp521r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support secp521r1",
+ )
def test_from_openssl_nist521p(self):
return self.do_test_from_openssl(NIST521p)
- @pytest.mark.skipif("secp256k1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support secp256k1")
+ @pytest.mark.skipif(
+ "secp256k1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support secp256k1",
+ )
def test_from_openssl_secp256k1(self):
return self.do_test_from_openssl(SECP256k1)
- @pytest.mark.skipif("brainpoolP160r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support brainpoolP160r1")
+ @pytest.mark.skipif(
+ "brainpoolP160r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support brainpoolP160r1",
+ )
def test_from_openssl_brainpoolp160r1(self):
return self.do_test_from_openssl(BRAINPOOLP160r1)
- @pytest.mark.skipif("brainpoolP192r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support brainpoolP192r1")
+ @pytest.mark.skipif(
+ "brainpoolP192r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support brainpoolP192r1",
+ )
def test_from_openssl_brainpoolp192r1(self):
return self.do_test_from_openssl(BRAINPOOLP192r1)
- @pytest.mark.skipif("brainpoolP224r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support brainpoolP224r1")
+ @pytest.mark.skipif(
+ "brainpoolP224r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support brainpoolP224r1",
+ )
def test_from_openssl_brainpoolp224r1(self):
return self.do_test_from_openssl(BRAINPOOLP224r1)
- @pytest.mark.skipif("brainpoolP256r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support brainpoolP256r1")
+ @pytest.mark.skipif(
+ "brainpoolP256r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support brainpoolP256r1",
+ )
def test_from_openssl_brainpoolp256r1(self):
return self.do_test_from_openssl(BRAINPOOLP256r1)
- @pytest.mark.skipif("brainpoolP320r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support brainpoolP320r1")
+ @pytest.mark.skipif(
+ "brainpoolP320r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support brainpoolP320r1",
+ )
def test_from_openssl_brainpoolp320r1(self):
return self.do_test_from_openssl(BRAINPOOLP320r1)
- @pytest.mark.skipif("brainpoolP384r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support brainpoolP384r1")
+ @pytest.mark.skipif(
+ "brainpoolP384r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support brainpoolP384r1",
+ )
def test_from_openssl_brainpoolp384r1(self):
return self.do_test_from_openssl(BRAINPOOLP384r1)
- @pytest.mark.skipif("brainpoolP512r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support brainpoolP512r1")
+ @pytest.mark.skipif(
+ "brainpoolP512r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support brainpoolP512r1",
+ )
def test_from_openssl_brainpoolp512r1(self):
return self.do_test_from_openssl(BRAINPOOLP512r1)
@@ -817,106 +990,154 @@ class OpenSSL(unittest.TestCase):
run_openssl("ec -in t/privkey.pem -pubout -out t/pubkey.pem")
data = b("data")
with open("t/data.txt", "wb") as e:
- e.write(data)
- run_openssl("dgst %s -sign t/privkey.pem -out t/data.sig t/data.txt" % mdarg)
- run_openssl("dgst %s -verify t/pubkey.pem -signature t/data.sig t/data.txt" % mdarg)
+ e.write(data)
+ run_openssl(
+ "dgst %s -sign t/privkey.pem -out t/data.sig t/data.txt" % mdarg
+ )
+ run_openssl(
+ "dgst %s -verify t/pubkey.pem -signature t/data.sig t/data.txt"
+ % mdarg
+ )
with open("t/pubkey.pem", "rb") as e:
- pubkey_pem = e.read()
+ pubkey_pem = e.read()
vk = VerifyingKey.from_pem(pubkey_pem) # 3
with open("t/data.sig", "rb") as e:
- sig_der = e.read()
- self.assertTrue(vk.verify(sig_der, data, # 5
- hashfunc=partial(hashlib.new, hash_name),
- sigdecode=sigdecode_der))
+ sig_der = e.read()
+ self.assertTrue(
+ vk.verify(
+ sig_der,
+ data, # 5
+ hashfunc=partial(hashlib.new, hash_name),
+ sigdecode=sigdecode_der,
+ )
+ )
with open("t/privkey.pem") as e:
- fp = e.read()
+ fp = e.read()
sk = SigningKey.from_pem(fp) # 1
- sig = sk.sign(
- data,
- hashfunc=partial(hashlib.new, hash_name),
- )
- self.assertTrue(vk.verify(sig,
- data,
- hashfunc=partial(hashlib.new, hash_name)))
-
- @pytest.mark.skipif("prime192v1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support prime192v1")
+ sig = sk.sign(data, hashfunc=partial(hashlib.new, hash_name))
+ self.assertTrue(
+ vk.verify(sig, data, hashfunc=partial(hashlib.new, hash_name))
+ )
+
+ run_openssl(
+ "pkcs8 -topk8 -nocrypt "
+ "-in t/privkey.pem -outform pem -out t/privkey-p8.pem"
+ )
+ with open("t/privkey-p8.pem", "rb") as e:
+ privkey_p8_pem = e.read()
+ sk_from_p8 = SigningKey.from_pem(privkey_p8_pem)
+ self.assertEqual(sk, sk_from_p8)
+
+ @pytest.mark.skipif(
+ "prime192v1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support prime192v1",
+ )
def test_to_openssl_nist192p(self):
self.do_test_to_openssl(NIST192p)
- @pytest.mark.skipif("prime192v1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support prime192v1")
+ @pytest.mark.skipif(
+ "prime192v1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support prime192v1",
+ )
def test_to_openssl_nist192p_sha256(self):
self.do_test_to_openssl(NIST192p, "SHA256")
- @pytest.mark.skipif("secp224r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support secp224r1")
+ @pytest.mark.skipif(
+ "secp224r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support secp224r1",
+ )
def test_to_openssl_nist224p(self):
self.do_test_to_openssl(NIST224p)
- @pytest.mark.skipif("prime256v1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support prime256v1")
+ @pytest.mark.skipif(
+ "prime256v1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support prime256v1",
+ )
def test_to_openssl_nist256p(self):
self.do_test_to_openssl(NIST256p)
- @pytest.mark.skipif("prime256v1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support prime256v1")
+ @pytest.mark.skipif(
+ "prime256v1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support prime256v1",
+ )
def test_to_openssl_nist256p_sha384(self):
self.do_test_to_openssl(NIST256p, "SHA384")
- @pytest.mark.skipif("prime256v1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support prime256v1")
+ @pytest.mark.skipif(
+ "prime256v1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support prime256v1",
+ )
def test_to_openssl_nist256p_sha512(self):
self.do_test_to_openssl(NIST256p, "SHA512")
- @pytest.mark.skipif("secp384r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support secp384r1")
+ @pytest.mark.skipif(
+ "secp384r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support secp384r1",
+ )
def test_to_openssl_nist384p(self):
self.do_test_to_openssl(NIST384p)
- @pytest.mark.skipif("secp521r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support secp521r1")
+ @pytest.mark.skipif(
+ "secp521r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support secp521r1",
+ )
def test_to_openssl_nist521p(self):
self.do_test_to_openssl(NIST521p)
- @pytest.mark.skipif("secp256k1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support secp256k1")
+ @pytest.mark.skipif(
+ "secp256k1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support secp256k1",
+ )
def test_to_openssl_secp256k1(self):
self.do_test_to_openssl(SECP256k1)
- @pytest.mark.skipif("brainpoolP160r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support brainpoolP160r1")
+ @pytest.mark.skipif(
+ "brainpoolP160r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support brainpoolP160r1",
+ )
def test_to_openssl_brainpoolp160r1(self):
self.do_test_to_openssl(BRAINPOOLP160r1)
- @pytest.mark.skipif("brainpoolP192r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support brainpoolP192r1")
+ @pytest.mark.skipif(
+ "brainpoolP192r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support brainpoolP192r1",
+ )
def test_to_openssl_brainpoolp192r1(self):
self.do_test_to_openssl(BRAINPOOLP192r1)
- @pytest.mark.skipif("brainpoolP224r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support brainpoolP224r1")
+ @pytest.mark.skipif(
+ "brainpoolP224r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support brainpoolP224r1",
+ )
def test_to_openssl_brainpoolp224r1(self):
self.do_test_to_openssl(BRAINPOOLP224r1)
- @pytest.mark.skipif("brainpoolP256r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support brainpoolP256r1")
+ @pytest.mark.skipif(
+ "brainpoolP256r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support brainpoolP256r1",
+ )
def test_to_openssl_brainpoolp256r1(self):
self.do_test_to_openssl(BRAINPOOLP256r1)
- @pytest.mark.skipif("brainpoolP320r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support brainpoolP320r1")
+ @pytest.mark.skipif(
+ "brainpoolP320r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support brainpoolP320r1",
+ )
def test_to_openssl_brainpoolp320r1(self):
self.do_test_to_openssl(BRAINPOOLP320r1)
- @pytest.mark.skipif("brainpoolP384r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support brainpoolP384r1")
+ @pytest.mark.skipif(
+ "brainpoolP384r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support brainpoolP384r1",
+ )
def test_to_openssl_brainpoolp384r1(self):
self.do_test_to_openssl(BRAINPOOLP384r1)
- @pytest.mark.skipif("brainpoolP512r1" not in OPENSSL_SUPPORTED_CURVES,
- reason="system openssl does not support brainpoolP512r1")
+ @pytest.mark.skipif(
+ "brainpoolP512r1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support brainpoolP512r1",
+ )
def test_to_openssl_brainpoolp512r1(self):
self.do_test_to_openssl(BRAINPOOLP512r1)
@@ -933,27 +1154,99 @@ class OpenSSL(unittest.TestCase):
vk = sk.get_verifying_key()
data = b("data")
with open("t/pubkey.der", "wb") as e:
- e.write(vk.to_der()) # 4
+ e.write(vk.to_der()) # 4
with open("t/pubkey.pem", "wb") as e:
- e.write(vk.to_pem()) # 4
- sig_der = sk.sign(data, hashfunc=partial(hashlib.new, hash_name),
- sigencode=sigencode_der)
+ e.write(vk.to_pem()) # 4
+ sig_der = sk.sign(
+ data,
+ hashfunc=partial(hashlib.new, hash_name),
+ sigencode=sigencode_der,
+ )
with open("t/data.sig", "wb") as e:
- e.write(sig_der) # 6
+ e.write(sig_der) # 6
with open("t/data.txt", "wb") as e:
- e.write(data)
+ e.write(data)
with open("t/baddata.txt", "wb") as e:
- e.write(data + b("corrupt"))
-
- self.assertRaises(SubprocessError, run_openssl,
- "dgst %s -verify t/pubkey.der -keyform DER -signature t/data.sig t/baddata.txt" % mdarg)
- run_openssl("dgst %s -verify t/pubkey.der -keyform DER -signature t/data.sig t/data.txt" % mdarg)
+ e.write(data + b("corrupt"))
+
+ self.assertRaises(
+ SubprocessError,
+ run_openssl,
+ "dgst %s -verify t/pubkey.der -keyform DER -signature t/data.sig t/baddata.txt"
+ % mdarg,
+ )
+ run_openssl(
+ "dgst %s -verify t/pubkey.der -keyform DER -signature t/data.sig t/data.txt"
+ % mdarg
+ )
with open("t/privkey.pem", "wb") as e:
- e.write(sk.to_pem()) # 2
- run_openssl("dgst %s -sign t/privkey.pem -out t/data.sig2 t/data.txt" % mdarg)
- run_openssl("dgst %s -verify t/pubkey.pem -signature t/data.sig2 t/data.txt" % mdarg)
+ e.write(sk.to_pem()) # 2
+ run_openssl(
+ "dgst %s -sign t/privkey.pem -out t/data.sig2 t/data.txt" % mdarg
+ )
+ run_openssl(
+ "dgst %s -verify t/pubkey.pem -signature t/data.sig2 t/data.txt"
+ % mdarg
+ )
+
+ with open("t/privkey-p8.pem", "wb") as e:
+ e.write(sk.to_pem(format="pkcs8"))
+ run_openssl(
+ "dgst %s -sign t/privkey-p8.pem -out t/data.sig3 t/data.txt"
+ % mdarg
+ )
+ run_openssl(
+ "dgst %s -verify t/pubkey.pem -signature t/data.sig3 t/data.txt"
+ % mdarg
+ )
+
+
+class TooSmallCurve(unittest.TestCase):
+ OPENSSL_SUPPORTED_CURVES = set(
+ c.split(":")[0].strip()
+ for c in run_openssl("ecparam -list_curves").split("\n")
+ )
+
+ @pytest.mark.skipif(
+ "prime192v1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support prime192v1",
+ )
+ def test_sign_too_small_curve_dont_allow_truncate_raises(self):
+ sk = SigningKey.generate(curve=NIST192p)
+ vk = sk.get_verifying_key()
+ data = b("data")
+ with self.assertRaises(BadDigestError):
+ sk.sign(
+ data,
+ hashfunc=partial(hashlib.new, "SHA256"),
+ sigencode=sigencode_der,
+ allow_truncate=False,
+ )
+
+ @pytest.mark.skipif(
+ "prime192v1" not in OPENSSL_SUPPORTED_CURVES,
+ reason="system openssl does not support prime192v1",
+ )
+ def test_verify_too_small_curve_dont_allow_truncate_raises(self):
+ sk = SigningKey.generate(curve=NIST192p)
+ vk = sk.get_verifying_key()
+ data = b("data")
+ sig_der = sk.sign(
+ data,
+ hashfunc=partial(hashlib.new, "SHA256"),
+ sigencode=sigencode_der,
+ allow_truncate=True,
+ )
+ with self.assertRaises(BadDigestError):
+ vk.verify(
+ sig_der,
+ data,
+ hashfunc=partial(hashlib.new, "SHA256"),
+ sigdecode=sigdecode_der,
+ allow_truncate=False,
+ )
class DER(unittest.TestCase):
@@ -966,14 +1259,17 @@ class DER(unittest.TestCase):
# self.assertEqual(der.encode_integer(-1), b("\x02\x01\xff"))
def s(n):
- return der.remove_integer(der.encode_integer(n) + b("junk"))
+ return der.remove_integer(der.encode_integer(n) + b("junk"))
+
self.assertEqual(s(0), (0, b("junk")))
self.assertEqual(s(1), (1, b("junk")))
self.assertEqual(s(127), (127, b("junk")))
self.assertEqual(s(128), (128, b("junk")))
self.assertEqual(s(256), (256, b("junk")))
- self.assertEqual(s(1234567890123456789012345678901234567890),
- (1234567890123456789012345678901234567890, b("junk")))
+ self.assertEqual(
+ s(1234567890123456789012345678901234567890),
+ (1234567890123456789012345678901234567890, b("junk")),
+ )
def test_number(self):
self.assertEqual(der.encode_number(0), b("\x00"))
@@ -1022,28 +1318,41 @@ class Util(unittest.TestCase):
tta = util.randrange_from_seed__trytryagain
for i in range(1000):
seed = "seed-%d" % i
- for order in (2**8 - 2, 2**8 - 1, 2**8, 2**8 + 1, 2**8 + 2,
- 2**16 - 1, 2**16 + 1):
+ for order in (
+ 2 ** 8 - 2,
+ 2 ** 8 - 1,
+ 2 ** 8,
+ 2 ** 8 + 1,
+ 2 ** 8 + 2,
+ 2 ** 16 - 1,
+ 2 ** 16 + 1,
+ ):
n = tta(seed, order)
self.assertTrue(1 <= n < order, (1, n, order))
# this trytryagain *does* provide long-term stability
- self.assertEqual(("%x" % (tta("seed", NIST224p.order))).encode(),
- b("6fa59d73bf0446ae8743cf748fc5ac11d5585a90356417e97155c3bc"))
+ self.assertEqual(
+ ("%x" % (tta("seed", NIST224p.order))).encode(),
+ b("6fa59d73bf0446ae8743cf748fc5ac11d5585a90356417e97155c3bc"),
+ )
- @given(st.integers(min_value=0, max_value=10**200))
+ @given(st.integers(min_value=0, max_value=10 ** 200))
def test_randrange(self, i):
# util.randrange does not provide long-term stability: we might
# change the algorithm in the future.
entropy = util.PRNG("seed-%d" % i)
- for order in (2**8 - 2, 2**8 - 1, 2**8,
- 2**16 - 1, 2**16 + 1,
- ):
+ for order in (
+ 2 ** 8 - 2,
+ 2 ** 8 - 1,
+ 2 ** 8,
+ 2 ** 16 - 1,
+ 2 ** 16 + 1,
+ ):
# that oddball 2**16+1 takes half our runtime
n = util.randrange(order, entropy=entropy)
self.assertTrue(1 <= n < order, (1, n, order))
def OFF_test_prove_uniformity(self): # pragma: no cover
- order = 2**8 - 2
+ order = 2 ** 8 - 2
counts = dict([(i, 0) for i in range(1, order)])
assert 0 not in counts
assert order not in counts
@@ -1064,22 +1373,33 @@ class RFC6979(unittest.TestCase):
self.assertEqual(expected, actual)
def test_SECP256k1(self):
- '''RFC doesn't contain test vectors for SECP256k1 used in bitcoin.
- This vector has been computed by Golang reference implementation instead.'''
+ """RFC doesn't contain test vectors for SECP256k1 used in bitcoin.
+ This vector has been computed by Golang reference implementation instead."""
self._do(
generator=SECP256k1.generator,
secexp=int("9d0219792467d7d37b4d43298a7d0c05", 16),
hsh=sha256(b("sample")).digest(),
hash_func=sha256,
- expected=int("8fa1f95d514760e498f28957b824ee6ec39ed64826ff4fecc2b5739ec45b91cd", 16))
+ expected=int(
+ "8fa1f95d514760e498f28957b824ee6ec39ed64826ff4fecc2b5739ec45b91cd",
+ 16,
+ ),
+ )
def test_SECP256k1_2(self):
self._do(
generator=SECP256k1.generator,
- secexp=int("cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50", 16),
+ secexp=int(
+ "cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50",
+ 16,
+ ),
hsh=sha256(b("sample")).digest(),
hash_func=sha256,
- expected=int("2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3", 16))
+ expected=int(
+ "2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3",
+ 16,
+ ),
+ )
def test_SECP256k1_3(self):
self._do(
@@ -1087,15 +1407,21 @@ class RFC6979(unittest.TestCase):
secexp=0x1,
hsh=sha256(b("Satoshi Nakamoto")).digest(),
hash_func=sha256,
- expected=0x8F8A276C19F4149656B280621E358CCE24F5F52542772691EE69063B74F15D15)
+ expected=0x8F8A276C19F4149656B280621E358CCE24F5F52542772691EE69063B74F15D15,
+ )
def test_SECP256k1_4(self):
self._do(
generator=SECP256k1.generator,
secexp=0x1,
- hsh=sha256(b("All those moments will be lost in time, like tears in rain. Time to die...")).digest(),
+ hsh=sha256(
+ b(
+ "All those moments will be lost in time, like tears in rain. Time to die..."
+ )
+ ).digest(),
hash_func=sha256,
- expected=0x38AA22D72376B4DBC472E06C3BA403EE0A394DA63FC58D88686C611ABA98D6B3)
+ expected=0x38AA22D72376B4DBC472E06C3BA403EE0A394DA63FC58D88686C611ABA98D6B3,
+ )
def test_SECP256k1_5(self):
self._do(
@@ -1103,24 +1429,36 @@ class RFC6979(unittest.TestCase):
secexp=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140,
hsh=sha256(b("Satoshi Nakamoto")).digest(),
hash_func=sha256,
- expected=0x33A19B60E25FB6F4435AF53A3D42D493644827367E6453928554F43E49AA6F90)
+ expected=0x33A19B60E25FB6F4435AF53A3D42D493644827367E6453928554F43E49AA6F90,
+ )
def test_SECP256k1_6(self):
self._do(
generator=SECP256k1.generator,
- secexp=0xf8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181,
+ secexp=0xF8B8AF8CE3C7CCA5E300D33939540C10D45CE001B8F252BFBC57BA0342904181,
hsh=sha256(b("Alan Turing")).digest(),
hash_func=sha256,
- expected=0x525A82B70E67874398067543FD84C83D30C175FDC45FDEEE082FE13B1D7CFDF1)
+ expected=0x525A82B70E67874398067543FD84C83D30C175FDC45FDEEE082FE13B1D7CFDF1,
+ )
def test_1(self):
# Basic example of the RFC, it also tests 'try-try-again' from Step H of rfc6979
self._do(
- generator=Point(None, 0, 0, int("4000000000000000000020108A2E0CC0D99F8A5EF", 16)),
+ generator=Point(
+ None,
+ 0,
+ 0,
+ int("4000000000000000000020108A2E0CC0D99F8A5EF", 16),
+ ),
secexp=int("09A4D6792295A7F730FC3F2B49CBC0F62E862272F", 16),
- hsh=unhexlify(b("AF2BDBE1AA9B6EC1E2ADE1D694F41FC71A831D0268E9891562113D8A62ADD1BF")),
+ hsh=unhexlify(
+ b(
+ "AF2BDBE1AA9B6EC1E2ADE1D694F41FC71A831D0268E9891562113D8A62ADD1BF"
+ )
+ ),
hash_func=sha256,
- expected=int("23AF4074C90A02B3FE61D286D5C87F425E6BDD81B", 16))
+ expected=int("23AF4074C90A02B3FE61D286D5C87F425E6BDD81B", 16),
+ )
def test_2(self):
self._do(
@@ -1128,7 +1466,10 @@ class RFC6979(unittest.TestCase):
secexp=int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16),
hsh=sha1(b("sample")).digest(),
hash_func=sha1,
- expected=int("37D7CA00D2C7B0E5E412AC03BD44BA837FDD5B28CD3B0021", 16))
+ expected=int(
+ "37D7CA00D2C7B0E5E412AC03BD44BA837FDD5B28CD3B0021", 16
+ ),
+ )
def test_3(self):
self._do(
@@ -1136,7 +1477,10 @@ class RFC6979(unittest.TestCase):
secexp=int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16),
hsh=sha256(b("sample")).digest(),
hash_func=sha256,
- expected=int("32B1B6D7D42A05CB449065727A84804FB1A3E34D8F261496", 16))
+ expected=int(
+ "32B1B6D7D42A05CB449065727A84804FB1A3E34D8F261496", 16
+ ),
+ )
def test_4(self):
self._do(
@@ -1144,7 +1488,10 @@ class RFC6979(unittest.TestCase):
secexp=int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16),
hsh=sha512(b("sample")).digest(),
hash_func=sha512,
- expected=int("A2AC7AB055E4F20692D49209544C203A7D1F2C0BFBC75DB1", 16))
+ expected=int(
+ "A2AC7AB055E4F20692D49209544C203A7D1F2C0BFBC75DB1", 16
+ ),
+ )
def test_5(self):
self._do(
@@ -1152,7 +1499,10 @@ class RFC6979(unittest.TestCase):
secexp=int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16),
hsh=sha1(b("test")).digest(),
hash_func=sha1,
- expected=int("D9CF9C3D3297D3260773A1DA7418DB5537AB8DD93DE7FA25", 16))
+ expected=int(
+ "D9CF9C3D3297D3260773A1DA7418DB5537AB8DD93DE7FA25", 16
+ ),
+ )
def test_6(self):
self._do(
@@ -1160,7 +1510,10 @@ class RFC6979(unittest.TestCase):
secexp=int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16),
hsh=sha256(b("test")).digest(),
hash_func=sha256,
- expected=int("5C4CE89CF56D9E7C77C8585339B006B97B5F0680B4306C6C", 16))
+ expected=int(
+ "5C4CE89CF56D9E7C77C8585339B006B97B5F0680B4306C6C", 16
+ ),
+ )
def test_7(self):
self._do(
@@ -1168,31 +1521,55 @@ class RFC6979(unittest.TestCase):
secexp=int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16),
hsh=sha512(b("test")).digest(),
hash_func=sha512,
- expected=int("0758753A5254759C7CFBAD2E2D9B0792EEE44136C9480527", 16))
+ expected=int(
+ "0758753A5254759C7CFBAD2E2D9B0792EEE44136C9480527", 16
+ ),
+ )
def test_8(self):
self._do(
generator=NIST521p.generator,
- secexp=int("0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538", 16),
+ secexp=int(
+ "0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538",
+ 16,
+ ),
hsh=sha1(b("sample")).digest(),
hash_func=sha1,
- expected=int("089C071B419E1C2820962321787258469511958E80582E95D8378E0C2CCDB3CB42BEDE42F50E3FA3C71F5A76724281D31D9C89F0F91FC1BE4918DB1C03A5838D0F9", 16))
+ expected=int(
+ "089C071B419E1C2820962321787258469511958E80582E95D8378E0C2CCDB3CB42BEDE42F50E3FA3C71F5A76724281D31D9C89F0F91FC1BE4918DB1C03A5838D0F9",
+ 16,
+ ),
+ )
def test_9(self):
self._do(
generator=NIST521p.generator,
- secexp=int("0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538", 16),
+ secexp=int(
+ "0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538",
+ 16,
+ ),
hsh=sha256(b("sample")).digest(),
hash_func=sha256,
- expected=int("0EDF38AFCAAECAB4383358B34D67C9F2216C8382AAEA44A3DAD5FDC9C32575761793FEF24EB0FC276DFC4F6E3EC476752F043CF01415387470BCBD8678ED2C7E1A0", 16))
+ expected=int(
+ "0EDF38AFCAAECAB4383358B34D67C9F2216C8382AAEA44A3DAD5FDC9C32575761793FEF24EB0FC276DFC4F6E3EC476752F043CF01415387470BCBD8678ED2C7E1A0",
+ 16,
+ ),
+ )
def test_10(self):
self._do(
generator=NIST521p.generator,
- secexp=int("0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538", 16),
+ secexp=int(
+ "0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538",
+ 16,
+ ),
hsh=sha512(b("test")).digest(),
hash_func=sha512,
- expected=int("16200813020EC986863BEDFC1B121F605C1215645018AEA1A7B215A564DE9EB1B38A67AA1128B80CE391C4FB71187654AAA3431027BFC7F395766CA988C964DC56D", 16))
+ expected=int(
+ "16200813020EC986863BEDFC1B121F605C1215645018AEA1A7B215A564DE9EB1B38A67AA1128B80CE391C4FB71187654AAA3431027BFC7F395766CA988C964DC56D",
+ 16,
+ ),
+ )
class ECDH(unittest.TestCase):
@@ -1202,10 +1579,12 @@ class ECDH(unittest.TestCase):
Z = dA * qB
self.assertEqual(Point(curve, x_qA, y_qA), qA)
self.assertEqual(Point(curve, x_qB, y_qB), qB)
- self.assertTrue((dA * qB) ==
- (dA * dB * generator) ==
- (dB * dA * generator) ==
- (dB * qA))
+ self.assertTrue(
+ (dA * qB)
+ == (dA * dB * generator)
+ == (dB * dA * generator)
+ == (dB * qA)
+ )
self.assertEqual(Point(curve, x_Z, y_Z), Z)
@@ -1216,93 +1595,177 @@ class RFC6932(ECDH):
self._do(
curve=curve_brainpoolp224r1,
generator=BRAINPOOLP224r1.generator,
- dA=int("7C4B7A2C8A4BAD1FBB7D79CC0955DB7C6A4660CA64CC4778159B495E",
- 16),
- x_qA=int("B104A67A6F6E85E14EC1825E1539E8ECDBBF584922367DD88C6BDCF2",
- 16),
- y_qA=int("46D782E7FDB5F60CD8404301AC5949C58EDB26BC68BA07695B750A94",
- 16),
- dB=int("63976D4AAE6CD0F6DD18DEFEF55D96569D0507C03E74D6486FFA28FB",
- 16),
- x_qB=int("2A97089A9296147B71B21A4B574E1278245B536F14D8C2B9D07A874E",
- 16),
- y_qB=int("9B900D7C77A709A797276B8CA1BA61BB95B546FC29F862E44D59D25B",
- 16),
- x_Z=int("312DFD98783F9FB77B9704945A73BEB6DCCBE3B65D0F967DCAB574EB",
- 16),
- y_Z=int("6F800811D64114B1C48C621AB3357CF93F496E4238696A2A012B3C98",
- 16))
+ dA=int(
+ "7C4B7A2C8A4BAD1FBB7D79CC0955DB7C6A4660CA64CC4778159B495E", 16
+ ),
+ x_qA=int(
+ "B104A67A6F6E85E14EC1825E1539E8ECDBBF584922367DD88C6BDCF2", 16
+ ),
+ y_qA=int(
+ "46D782E7FDB5F60CD8404301AC5949C58EDB26BC68BA07695B750A94", 16
+ ),
+ dB=int(
+ "63976D4AAE6CD0F6DD18DEFEF55D96569D0507C03E74D6486FFA28FB", 16
+ ),
+ x_qB=int(
+ "2A97089A9296147B71B21A4B574E1278245B536F14D8C2B9D07A874E", 16
+ ),
+ y_qB=int(
+ "9B900D7C77A709A797276B8CA1BA61BB95B546FC29F862E44D59D25B", 16
+ ),
+ x_Z=int(
+ "312DFD98783F9FB77B9704945A73BEB6DCCBE3B65D0F967DCAB574EB", 16
+ ),
+ y_Z=int(
+ "6F800811D64114B1C48C621AB3357CF93F496E4238696A2A012B3C98", 16
+ ),
+ )
def test_brainpoolP256r1(self):
self._do(
curve=curve_brainpoolp256r1,
generator=BRAINPOOLP256r1.generator,
- dA=int("041EB8B1E2BC681BCE8E39963B2E9FC415B05283313DD1A8BCC055F11AE"
- "49699", 16),
- x_qA=int("78028496B5ECAAB3C8B6C12E45DB1E02C9E4D26B4113BC4F015F60C5C"
- "CC0D206", 16),
- y_qA=int("A2AE1762A3831C1D20F03F8D1E3C0C39AFE6F09B4D44BBE80CD100987"
- "B05F92B", 16),
- dB=int("06F5240EACDB9837BC96D48274C8AA834B6C87BA9CC3EEDD81F99A16B8D"
- "804D3", 16),
- x_qB=int("8E07E219BA588916C5B06AA30A2F464C2F2ACFC1610A3BE2FB240B635"
- "341F0DB", 16),
- y_qB=int("148EA1D7D1E7E54B9555B6C9AC90629C18B63BEE5D7AA6949EBBF47B2"
- "4FDE40D", 16),
- x_Z=int("05E940915549E9F6A4A75693716E37466ABA79B4BF2919877A16DD2CC2"
- "E23708", 16),
- y_Z=int("6BC23B6702BC5A019438CEEA107DAAD8B94232FFBBC350F3B137628FE6"
- "FD134C", 16))
+ dA=int(
+ "041EB8B1E2BC681BCE8E39963B2E9FC415B05283313DD1A8BCC055F11AE"
+ "49699",
+ 16,
+ ),
+ x_qA=int(
+ "78028496B5ECAAB3C8B6C12E45DB1E02C9E4D26B4113BC4F015F60C5C"
+ "CC0D206",
+ 16,
+ ),
+ y_qA=int(
+ "A2AE1762A3831C1D20F03F8D1E3C0C39AFE6F09B4D44BBE80CD100987"
+ "B05F92B",
+ 16,
+ ),
+ dB=int(
+ "06F5240EACDB9837BC96D48274C8AA834B6C87BA9CC3EEDD81F99A16B8D"
+ "804D3",
+ 16,
+ ),
+ x_qB=int(
+ "8E07E219BA588916C5B06AA30A2F464C2F2ACFC1610A3BE2FB240B635"
+ "341F0DB",
+ 16,
+ ),
+ y_qB=int(
+ "148EA1D7D1E7E54B9555B6C9AC90629C18B63BEE5D7AA6949EBBF47B2"
+ "4FDE40D",
+ 16,
+ ),
+ x_Z=int(
+ "05E940915549E9F6A4A75693716E37466ABA79B4BF2919877A16DD2CC2"
+ "E23708",
+ 16,
+ ),
+ y_Z=int(
+ "6BC23B6702BC5A019438CEEA107DAAD8B94232FFBBC350F3B137628FE6"
+ "FD134C",
+ 16,
+ ),
+ )
def test_brainpoolP384r1(self):
self._do(
curve=curve_brainpoolp384r1,
generator=BRAINPOOLP384r1.generator,
- dA=int("014EC0755B78594BA47FB0A56F6173045B4331E74BA1A6F47322E70D79D"
- "828D97E095884CA72B73FDABD5910DF0FA76A", 16),
- x_qA=int("45CB26E4384DAF6FB776885307B9A38B7AD1B5C692E0C32F012533277"
- "8F3B8D3F50CA358099B30DEB5EE69A95C058B4E", 16),
- y_qA=int("8173A1C54AFFA7E781D0E1E1D12C0DC2B74F4DF58E4A4E3AF7026C5D3"
- "2DC530A2CD89C859BB4B4B768497F49AB8CC859", 16),
- dB=int("6B461CB79BD0EA519A87D6828815D8CE7CD9B3CAA0B5A8262CBCD550A01"
- "5C90095B976F3529957506E1224A861711D54", 16),
- x_qB=int("01BF92A92EE4BE8DED1A911125C209B03F99E3161CFCC986DC7711383"
- "FC30AF9CE28CA3386D59E2C8D72CE1E7B4666E8", 16),
- y_qB=int("3289C4A3A4FEE035E39BDB885D509D224A142FF9FBCC5CFE5CCBB3026"
- "8EE47487ED8044858D31D848F7A95C635A347AC", 16),
- x_Z=int("04CC4FF3DCCCB07AF24E0ACC529955B36D7C807772B92FCBE48F3AFE9A"
- "2F370A1F98D3FA73FD0C0747C632E12F1423EC", 16),
- y_Z=int("7F465F90BD69AFB8F828A214EB9716D66ABC59F17AF7C75EE7F1DE22AB"
- "5D05085F5A01A9382D05BF72D96698FE3FF64E", 16))
+ dA=int(
+ "014EC0755B78594BA47FB0A56F6173045B4331E74BA1A6F47322E70D79D"
+ "828D97E095884CA72B73FDABD5910DF0FA76A",
+ 16,
+ ),
+ x_qA=int(
+ "45CB26E4384DAF6FB776885307B9A38B7AD1B5C692E0C32F012533277"
+ "8F3B8D3F50CA358099B30DEB5EE69A95C058B4E",
+ 16,
+ ),
+ y_qA=int(
+ "8173A1C54AFFA7E781D0E1E1D12C0DC2B74F4DF58E4A4E3AF7026C5D3"
+ "2DC530A2CD89C859BB4B4B768497F49AB8CC859",
+ 16,
+ ),
+ dB=int(
+ "6B461CB79BD0EA519A87D6828815D8CE7CD9B3CAA0B5A8262CBCD550A01"
+ "5C90095B976F3529957506E1224A861711D54",
+ 16,
+ ),
+ x_qB=int(
+ "01BF92A92EE4BE8DED1A911125C209B03F99E3161CFCC986DC7711383"
+ "FC30AF9CE28CA3386D59E2C8D72CE1E7B4666E8",
+ 16,
+ ),
+ y_qB=int(
+ "3289C4A3A4FEE035E39BDB885D509D224A142FF9FBCC5CFE5CCBB3026"
+ "8EE47487ED8044858D31D848F7A95C635A347AC",
+ 16,
+ ),
+ x_Z=int(
+ "04CC4FF3DCCCB07AF24E0ACC529955B36D7C807772B92FCBE48F3AFE9A"
+ "2F370A1F98D3FA73FD0C0747C632E12F1423EC",
+ 16,
+ ),
+ y_Z=int(
+ "7F465F90BD69AFB8F828A214EB9716D66ABC59F17AF7C75EE7F1DE22AB"
+ "5D05085F5A01A9382D05BF72D96698FE3FF64E",
+ 16,
+ ),
+ )
def test_brainpoolP512r1(self):
self._do(
curve=curve_brainpoolp512r1,
generator=BRAINPOOLP512r1.generator,
- dA=int("636B6BE0482A6C1C41AA7AE7B245E983392DB94CECEA2660A379CFE1595"
- "59E357581825391175FC195D28BAC0CF03A7841A383B95C262B98378287"
- "4CCE6FE333", 16),
- x_qA=int("0562E68B9AF7CBFD5565C6B16883B777FF11C199161ECC427A39D17EC"
- "2166499389571D6A994977C56AD8252658BA8A1B72AE42F4FB7532151"
- "AFC3EF0971CCDA", 16),
- y_qA=int("A7CA2D8191E21776A89860AFBC1F582FAA308D551C1DC6133AF9F9C3C"
- "AD59998D70079548140B90B1F311AFB378AA81F51B275B2BE6B7DEE97"
- "8EFC7343EA642E", 16),
- dB=int("0AF4E7F6D52EDD52907BB8DBAB3992A0BB696EC10DF11892FF205B66D38"
- "1ECE72314E6A6EA079CEA06961DBA5AE6422EF2E9EE803A1F236FB96A17"
- "99B86E5C8B", 16),
- x_qB=int("5A7954E32663DFF11AE24712D87419F26B708AC2B92877D6BFEE2BFC4"
- "3714D89BBDB6D24D807BBD3AEB7F0C325F862E8BADE4F74636B97EAAC"
- "E739E11720D323", 16),
- y_qB=int("96D14621A9283A1BED84DE8DD64836B2C0758B11441179DC0C54C0D49"
- "A47C03807D171DD544B72CAAEF7B7CE01C7753E2CAD1A861ECA55A719"
- "54EE1BA35E04BE", 16),
- x_Z=int("1EE8321A4BBF93B9CF8921AB209850EC9B7066D1984EF08C2BB7232362"
- "08AC8F1A483E79461A00E0D5F6921CE9D360502F85C812BEDEE23AC5B2"
- "10E5811B191E", 16),
- y_Z=int("2632095B7B936174B41FD2FAF369B1D18DCADEED7E410A7E251F083109"
- "7C50D02CFED02607B6A2D5ADB4C0006008562208631875B58B54ECDA5A"
- "4F9FE9EAABA6", 16))
+ dA=int(
+ "636B6BE0482A6C1C41AA7AE7B245E983392DB94CECEA2660A379CFE1595"
+ "59E357581825391175FC195D28BAC0CF03A7841A383B95C262B98378287"
+ "4CCE6FE333",
+ 16,
+ ),
+ x_qA=int(
+ "0562E68B9AF7CBFD5565C6B16883B777FF11C199161ECC427A39D17EC"
+ "2166499389571D6A994977C56AD8252658BA8A1B72AE42F4FB7532151"
+ "AFC3EF0971CCDA",
+ 16,
+ ),
+ y_qA=int(
+ "A7CA2D8191E21776A89860AFBC1F582FAA308D551C1DC6133AF9F9C3C"
+ "AD59998D70079548140B90B1F311AFB378AA81F51B275B2BE6B7DEE97"
+ "8EFC7343EA642E",
+ 16,
+ ),
+ dB=int(
+ "0AF4E7F6D52EDD52907BB8DBAB3992A0BB696EC10DF11892FF205B66D38"
+ "1ECE72314E6A6EA079CEA06961DBA5AE6422EF2E9EE803A1F236FB96A17"
+ "99B86E5C8B",
+ 16,
+ ),
+ x_qB=int(
+ "5A7954E32663DFF11AE24712D87419F26B708AC2B92877D6BFEE2BFC4"
+ "3714D89BBDB6D24D807BBD3AEB7F0C325F862E8BADE4F74636B97EAAC"
+ "E739E11720D323",
+ 16,
+ ),
+ y_qB=int(
+ "96D14621A9283A1BED84DE8DD64836B2C0758B11441179DC0C54C0D49"
+ "A47C03807D171DD544B72CAAEF7B7CE01C7753E2CAD1A861ECA55A719"
+ "54EE1BA35E04BE",
+ 16,
+ ),
+ x_Z=int(
+ "1EE8321A4BBF93B9CF8921AB209850EC9B7066D1984EF08C2BB7232362"
+ "08AC8F1A483E79461A00E0D5F6921CE9D360502F85C812BEDEE23AC5B2"
+ "10E5811B191E",
+ 16,
+ ),
+ y_Z=int(
+ "2632095B7B936174B41FD2FAF369B1D18DCADEED7E410A7E251F083109"
+ "7C50D02CFED02607B6A2D5ADB4C0006008562208631875B58B54ECDA5A"
+ "4F9FE9EAABA6",
+ 16,
+ ),
+ )
class RFC7027(ECDH):
@@ -1312,128 +1775,209 @@ class RFC7027(ECDH):
self._do(
curve=curve_brainpoolp256r1,
generator=BRAINPOOLP256r1.generator,
- dA=int("81DB1EE100150FF2EA338D708271BE38300CB54241D79950F77B0630398"
- "04F1D", 16),
- x_qA=int("44106E913F92BC02A1705D9953A8414DB95E1AAA49E81D9E85F929A8E"
- "3100BE5", 16),
- y_qA=int("8AB4846F11CACCB73CE49CBDD120F5A900A69FD32C272223F789EF10E"
- "B089BDC", 16),
- dB=int("55E40BC41E37E3E2AD25C3C6654511FFA8474A91A0032087593852D3E7D"
- "76BD3", 16),
- x_qB=int("8D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F"
- "1B39F7B", 16),
- y_qB=int("990C57520812BE512641E47034832106BC7D3E8DD0E4C7F1136D70065"
- "47CEC6A", 16),
- x_Z=int("89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A"
- "18BF2B", 16),
- y_Z=int("49C27868F4ECA2179BFD7D59B1E3BF34C1DBDE61AE12931648F43E5963"
- "2504DE", 16))
+ dA=int(
+ "81DB1EE100150FF2EA338D708271BE38300CB54241D79950F77B0630398"
+ "04F1D",
+ 16,
+ ),
+ x_qA=int(
+ "44106E913F92BC02A1705D9953A8414DB95E1AAA49E81D9E85F929A8E"
+ "3100BE5",
+ 16,
+ ),
+ y_qA=int(
+ "8AB4846F11CACCB73CE49CBDD120F5A900A69FD32C272223F789EF10E"
+ "B089BDC",
+ 16,
+ ),
+ dB=int(
+ "55E40BC41E37E3E2AD25C3C6654511FFA8474A91A0032087593852D3E7D"
+ "76BD3",
+ 16,
+ ),
+ x_qB=int(
+ "8D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F"
+ "1B39F7B",
+ 16,
+ ),
+ y_qB=int(
+ "990C57520812BE512641E47034832106BC7D3E8DD0E4C7F1136D70065"
+ "47CEC6A",
+ 16,
+ ),
+ x_Z=int(
+ "89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A"
+ "18BF2B",
+ 16,
+ ),
+ y_Z=int(
+ "49C27868F4ECA2179BFD7D59B1E3BF34C1DBDE61AE12931648F43E5963"
+ "2504DE",
+ 16,
+ ),
+ )
def test_brainpoolP384r1(self):
self._do(
curve=curve_brainpoolp384r1,
generator=BRAINPOOLP384r1.generator,
- dA=int("1E20F5E048A5886F1F157C74E91BDE2B98C8B52D58E5003D57053FC4B0B"
- "D65D6F15EB5D1EE1610DF870795143627D042", 16),
- x_qA=int("68B665DD91C195800650CDD363C625F4E742E8134667B767B1B476793"
- "588F885AB698C852D4A6E77A252D6380FCAF068", 16),
- y_qA=int("55BC91A39C9EC01DEE36017B7D673A931236D2F1F5C83942D049E3FA2"
- "0607493E0D038FF2FD30C2AB67D15C85F7FAA59", 16),
- dB=int("032640BC6003C59260F7250C3DB58CE647F98E1260ACCE4ACDA3DD869F7"
- "4E01F8BA5E0324309DB6A9831497ABAC96670", 16),
- x_qB=int("4D44326F269A597A5B58BBA565DA5556ED7FD9A8A9EB76C25F46DB69D"
- "19DC8CE6AD18E404B15738B2086DF37E71D1EB4", 16),
- y_qB=int("62D692136DE56CBE93BF5FA3188EF58BC8A3A0EC6C1E151A21038A42E"
- "9185329B5B275903D192F8D4E1F32FE9CC78C48", 16),
- x_Z=int("0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBC"
- "E239BBADF6403715C35D4FB2A5444F575D4F42", 16),
- y_Z=int("0DF213417EBE4D8E40A5F76F66C56470C489A3478D146DECF6DF0D94BA"
- "E9E598157290F8756066975F1DB34B2324B7BD", 16))
+ dA=int(
+ "1E20F5E048A5886F1F157C74E91BDE2B98C8B52D58E5003D57053FC4B0B"
+ "D65D6F15EB5D1EE1610DF870795143627D042",
+ 16,
+ ),
+ x_qA=int(
+ "68B665DD91C195800650CDD363C625F4E742E8134667B767B1B476793"
+ "588F885AB698C852D4A6E77A252D6380FCAF068",
+ 16,
+ ),
+ y_qA=int(
+ "55BC91A39C9EC01DEE36017B7D673A931236D2F1F5C83942D049E3FA2"
+ "0607493E0D038FF2FD30C2AB67D15C85F7FAA59",
+ 16,
+ ),
+ dB=int(
+ "032640BC6003C59260F7250C3DB58CE647F98E1260ACCE4ACDA3DD869F7"
+ "4E01F8BA5E0324309DB6A9831497ABAC96670",
+ 16,
+ ),
+ x_qB=int(
+ "4D44326F269A597A5B58BBA565DA5556ED7FD9A8A9EB76C25F46DB69D"
+ "19DC8CE6AD18E404B15738B2086DF37E71D1EB4",
+ 16,
+ ),
+ y_qB=int(
+ "62D692136DE56CBE93BF5FA3188EF58BC8A3A0EC6C1E151A21038A42E"
+ "9185329B5B275903D192F8D4E1F32FE9CC78C48",
+ 16,
+ ),
+ x_Z=int(
+ "0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBC"
+ "E239BBADF6403715C35D4FB2A5444F575D4F42",
+ 16,
+ ),
+ y_Z=int(
+ "0DF213417EBE4D8E40A5F76F66C56470C489A3478D146DECF6DF0D94BA"
+ "E9E598157290F8756066975F1DB34B2324B7BD",
+ 16,
+ ),
+ )
def test_brainpoolP512r1(self):
self._do(
curve=curve_brainpoolp512r1,
generator=BRAINPOOLP512r1.generator,
- dA=int("16302FF0DBBB5A8D733DAB7141C1B45ACBC8715939677F6A56850A38BD8"
- "7BD59B09E80279609FF333EB9D4C061231FB26F92EEB04982A5F1D1764C"
- "AD57665422", 16),
- x_qA=int("0A420517E406AAC0ACDCE90FCD71487718D3B953EFD7FBEC5F7F27E28"
- "C6149999397E91E029E06457DB2D3E640668B392C2A7E737A7F0BF044"
- "36D11640FD09FD", 16),
- y_qA=int("72E6882E8DB28AAD36237CD25D580DB23783961C8DC52DFA2EC138AD4"
- "72A0FCEF3887CF62B623B2A87DE5C588301EA3E5FC269B373B60724F5"
- "E82A6AD147FDE7", 16),
- dB=int("230E18E1BCC88A362FA54E4EA3902009292F7F8033624FD471B5D8ACE49"
- "D12CFABBC19963DAB8E2F1EBA00BFFB29E4D72D13F2224562F405CB8050"
- "3666B25429", 16),
- x_qB=int("9D45F66DE5D67E2E6DB6E93A59CE0BB48106097FF78A081DE781CDB31"
- "FCE8CCBAAEA8DD4320C4119F1E9CD437A2EAB3731FA9668AB268D871D"
- "EDA55A5473199F", 16),
- y_qB=int("2FDC313095BCDD5FB3A91636F07A959C8E86B5636A1E930E8396049CB"
- "481961D365CC11453A06C719835475B12CB52FC3C383BCE35E27EF194"
- "512B71876285FA", 16),
- x_Z=int("A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226"
- "244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1"
- "454B21C4CD1F", 16),
- y_Z=int("7DB71C3DEF63212841C463E881BDCF055523BD368240E6C3143BD8DEF8"
- "B3B3223B95E0F53082FF5E412F4222537A43DF1C6D25729DDB51620A83"
- "2BE6A26680A2", 16))
+ dA=int(
+ "16302FF0DBBB5A8D733DAB7141C1B45ACBC8715939677F6A56850A38BD8"
+ "7BD59B09E80279609FF333EB9D4C061231FB26F92EEB04982A5F1D1764C"
+ "AD57665422",
+ 16,
+ ),
+ x_qA=int(
+ "0A420517E406AAC0ACDCE90FCD71487718D3B953EFD7FBEC5F7F27E28"
+ "C6149999397E91E029E06457DB2D3E640668B392C2A7E737A7F0BF044"
+ "36D11640FD09FD",
+ 16,
+ ),
+ y_qA=int(
+ "72E6882E8DB28AAD36237CD25D580DB23783961C8DC52DFA2EC138AD4"
+ "72A0FCEF3887CF62B623B2A87DE5C588301EA3E5FC269B373B60724F5"
+ "E82A6AD147FDE7",
+ 16,
+ ),
+ dB=int(
+ "230E18E1BCC88A362FA54E4EA3902009292F7F8033624FD471B5D8ACE49"
+ "D12CFABBC19963DAB8E2F1EBA00BFFB29E4D72D13F2224562F405CB8050"
+ "3666B25429",
+ 16,
+ ),
+ x_qB=int(
+ "9D45F66DE5D67E2E6DB6E93A59CE0BB48106097FF78A081DE781CDB31"
+ "FCE8CCBAAEA8DD4320C4119F1E9CD437A2EAB3731FA9668AB268D871D"
+ "EDA55A5473199F",
+ 16,
+ ),
+ y_qB=int(
+ "2FDC313095BCDD5FB3A91636F07A959C8E86B5636A1E930E8396049CB"
+ "481961D365CC11453A06C719835475B12CB52FC3C383BCE35E27EF194"
+ "512B71876285FA",
+ 16,
+ ),
+ x_Z=int(
+ "A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226"
+ "244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1"
+ "454B21C4CD1F",
+ 16,
+ ),
+ y_Z=int(
+ "7DB71C3DEF63212841C463E881BDCF055523BD368240E6C3143BD8DEF8"
+ "B3B3223B95E0F53082FF5E412F4222537A43DF1C6D25729DDB51620A83"
+ "2BE6A26680A2",
+ 16,
+ ),
+ )
# https://tools.ietf.org/html/rfc4754#page-5
[email protected]("w, gwx, gwy, k, msg, md, r, s, curve",
- [pytest.param(
- "DC51D3866A15BACDE33D96F992FCA99DA7E6EF0934E7097559C27F1614C88A7F",
- "2442A5CC0ECD015FA3CA31DC8E2BBC70BF42D60CBCA20085E0822CB04235E970",
- "6FC98BD7E50211A4A27102FA3549DF79EBCB4BF246B80945CDDFE7D509BBFD7D",
- "9E56F509196784D963D1C0A401510EE7ADA3DCC5DEE04B154BF61AF1D5A6DECE",
- b"abc",
- sha256,
- "CB28E0999B9C7715FD0A80D8E47A77079716CBBF917DD72E97566EA1C066957C",
- "86FA3BB4E26CAD5BF90B7F81899256CE7594BB1EA0C89212748BFF3B3D5B0315",
- NIST256p,
- id="ECDSA-256"),
- pytest.param(
- "0BEB646634BA87735D77AE4809A0EBEA865535DE4C1E1DCB692E84708E81A5AF"
- "62E528C38B2A81B35309668D73524D9F",
- "96281BF8DD5E0525CA049C048D345D3082968D10FEDF5C5ACA0C64E6465A97EA"
- "5CE10C9DFEC21797415710721F437922",
- "447688BA94708EB6E2E4D59F6AB6D7EDFF9301D249FE49C33096655F5D502FAD"
- "3D383B91C5E7EDAA2B714CC99D5743CA",
- "B4B74E44D71A13D568003D7489908D564C7761E229C58CBFA18950096EB7463B"
- "854D7FA992F934D927376285E63414FA",
- b'abc',
- sha384,
- "FB017B914E29149432D8BAC29A514640B46F53DDAB2C69948084E2930F1C8F7E"
- "08E07C9C63F2D21A07DCB56A6AF56EB3",
- "B263A1305E057F984D38726A1B46874109F417BCA112674C528262A40A629AF1"
- "CBB9F516CE0FA7D2FF630863A00E8B9F",
- NIST384p,
- id="ECDSA-384"),
- pytest.param(
- "0065FDA3409451DCAB0A0EAD45495112A3D813C17BFD34BDF8C1209D7DF58491"
- "20597779060A7FF9D704ADF78B570FFAD6F062E95C7E0C5D5481C5B153B48B37"
- "5FA1",
- "0151518F1AF0F563517EDD5485190DF95A4BF57B5CBA4CF2A9A3F6474725A35F"
- "7AFE0A6DDEB8BEDBCD6A197E592D40188901CECD650699C9B5E456AEA5ADD190"
- "52A8",
- "006F3B142EA1BFFF7E2837AD44C9E4FF6D2D34C73184BBAD90026DD5E6E85317"
- "D9DF45CAD7803C6C20035B2F3FF63AFF4E1BA64D1C077577DA3F4286C58F0AEA"
- "E643",
- "00C1C2B305419F5A41344D7E4359933D734096F556197A9B244342B8B62F46F9"
- "373778F9DE6B6497B1EF825FF24F42F9B4A4BD7382CFC3378A540B1B7F0C1B95"
- "6C2F",
- b'abc',
- sha512,
- "0154FD3836AF92D0DCA57DD5341D3053988534FDE8318FC6AAAAB68E2E6F4339"
- "B19F2F281A7E0B22C269D93CF8794A9278880ED7DBB8D9362CAEACEE54432055"
- "2251",
- "017705A7030290D1CEB605A9A1BB03FF9CDD521E87A696EC926C8C10C8362DF4"
- "975367101F67D1CF9BCCBF2F3D239534FA509E70AAC851AE01AAC68D62F86647"
- "2660",
- NIST521p,
- id="ECDSA-521")
- ])
+ "w, gwx, gwy, k, msg, md, r, s, curve",
+ [
+ pytest.param(
+ "DC51D3866A15BACDE33D96F992FCA99DA7E6EF0934E7097559C27F1614C88A7F",
+ "2442A5CC0ECD015FA3CA31DC8E2BBC70BF42D60CBCA20085E0822CB04235E970",
+ "6FC98BD7E50211A4A27102FA3549DF79EBCB4BF246B80945CDDFE7D509BBFD7D",
+ "9E56F509196784D963D1C0A401510EE7ADA3DCC5DEE04B154BF61AF1D5A6DECE",
+ b"abc",
+ sha256,
+ "CB28E0999B9C7715FD0A80D8E47A77079716CBBF917DD72E97566EA1C066957C",
+ "86FA3BB4E26CAD5BF90B7F81899256CE7594BB1EA0C89212748BFF3B3D5B0315",
+ NIST256p,
+ id="ECDSA-256",
+ ),
+ pytest.param(
+ "0BEB646634BA87735D77AE4809A0EBEA865535DE4C1E1DCB692E84708E81A5AF"
+ "62E528C38B2A81B35309668D73524D9F",
+ "96281BF8DD5E0525CA049C048D345D3082968D10FEDF5C5ACA0C64E6465A97EA"
+ "5CE10C9DFEC21797415710721F437922",
+ "447688BA94708EB6E2E4D59F6AB6D7EDFF9301D249FE49C33096655F5D502FAD"
+ "3D383B91C5E7EDAA2B714CC99D5743CA",
+ "B4B74E44D71A13D568003D7489908D564C7761E229C58CBFA18950096EB7463B"
+ "854D7FA992F934D927376285E63414FA",
+ b"abc",
+ sha384,
+ "FB017B914E29149432D8BAC29A514640B46F53DDAB2C69948084E2930F1C8F7E"
+ "08E07C9C63F2D21A07DCB56A6AF56EB3",
+ "B263A1305E057F984D38726A1B46874109F417BCA112674C528262A40A629AF1"
+ "CBB9F516CE0FA7D2FF630863A00E8B9F",
+ NIST384p,
+ id="ECDSA-384",
+ ),
+ pytest.param(
+ "0065FDA3409451DCAB0A0EAD45495112A3D813C17BFD34BDF8C1209D7DF58491"
+ "20597779060A7FF9D704ADF78B570FFAD6F062E95C7E0C5D5481C5B153B48B37"
+ "5FA1",
+ "0151518F1AF0F563517EDD5485190DF95A4BF57B5CBA4CF2A9A3F6474725A35F"
+ "7AFE0A6DDEB8BEDBCD6A197E592D40188901CECD650699C9B5E456AEA5ADD190"
+ "52A8",
+ "006F3B142EA1BFFF7E2837AD44C9E4FF6D2D34C73184BBAD90026DD5E6E85317"
+ "D9DF45CAD7803C6C20035B2F3FF63AFF4E1BA64D1C077577DA3F4286C58F0AEA"
+ "E643",
+ "00C1C2B305419F5A41344D7E4359933D734096F556197A9B244342B8B62F46F9"
+ "373778F9DE6B6497B1EF825FF24F42F9B4A4BD7382CFC3378A540B1B7F0C1B95"
+ "6C2F",
+ b"abc",
+ sha512,
+ "0154FD3836AF92D0DCA57DD5341D3053988534FDE8318FC6AAAAB68E2E6F4339"
+ "B19F2F281A7E0B22C269D93CF8794A9278880ED7DBB8D9362CAEACEE54432055"
+ "2251",
+ "017705A7030290D1CEB605A9A1BB03FF9CDD521E87A696EC926C8C10C8362DF4"
+ "975367101F67D1CF9BCCBF2F3D239534FA509E70AAC851AE01AAC68D62F86647"
+ "2660",
+ NIST521p,
+ id="ECDSA-521",
+ ),
+ ],
+)
def test_RFC4754_vectors(w, gwx, gwy, k, msg, md, r, s, curve):
sk = SigningKey.from_string(unhexlify(w), curve)
vk = VerifyingKey.from_string(unhexlify(gwx + gwy), curve)
diff --git a/freezed_deps/ecdsa/test_rw_lock.py b/frozen_deps/ecdsa/test_rw_lock.py
index de11d15..d360482 100644
--- a/freezed_deps/ecdsa/test_rw_lock.py
+++ b/frozen_deps/ecdsa/test_rw_lock.py
@@ -10,7 +10,9 @@ from ._rwlock import RWLock
class Writer(threading.Thread):
- def __init__(self, buffer_, rw_lock, init_sleep_time, sleep_time, to_write):
+ def __init__(
+ self, buffer_, rw_lock, init_sleep_time, sleep_time, to_write
+ ):
"""
@param buffer_: common buffer_ shared by the readers and writers
@type buffer_: list
@@ -87,16 +89,16 @@ class RWLockTestCase(unittest.TestCase):
self.__start_and_join_threads(threads)
## The third reader should enter after the second one but it should
- ## exit before the second one exits
- ## (i.e. the readers should be in the critical section
+ ## exit before the second one exits
+ ## (i.e. the readers should be in the critical section
## at the same time)
self.assertEqual([], threads[0].buffer_read)
self.assertEqual([1], threads[2].buffer_read)
self.assertEqual([1], threads[3].buffer_read)
- self.assert_(threads[1].exit_time <= threads[2].entry_time)
- self.assert_(threads[2].entry_time <= threads[3].entry_time)
- self.assert_(threads[3].exit_time < threads[2].exit_time)
+ self.assertTrue(threads[1].exit_time <= threads[2].entry_time)
+ self.assertTrue(threads[2].entry_time <= threads[3].entry_time)
+ self.assertTrue(threads[3].exit_time < threads[2].exit_time)
def test_writers_exclusive_access(self):
(buffer_, rw_lock, threads) = self.__init_variables()
@@ -110,8 +112,8 @@ class RWLockTestCase(unittest.TestCase):
## The second writer should wait for the first one to exit
self.assertEqual([1, 2], threads[2].buffer_read)
- self.assert_(threads[0].exit_time <= threads[1].entry_time)
- self.assert_(threads[1].exit_time <= threads[2].exit_time)
+ self.assertTrue(threads[0].exit_time <= threads[1].entry_time)
+ self.assertTrue(threads[1].exit_time <= threads[2].exit_time)
def test_writer_priority(self):
(buffer_, rw_lock, threads) = self.__init_variables()
@@ -129,10 +131,10 @@ class RWLockTestCase(unittest.TestCase):
self.assertEqual([1], threads[1].buffer_read)
self.assertEqual([1, 2], threads[3].buffer_read)
self.assertEqual([1, 2], threads[4].buffer_read)
- self.assert_(threads[0].exit_time < threads[1].entry_time)
- self.assert_(threads[1].exit_time <= threads[2].entry_time)
- self.assert_(threads[2].exit_time <= threads[3].entry_time)
- self.assert_(threads[2].exit_time <= threads[4].entry_time)
+ self.assertTrue(threads[0].exit_time < threads[1].entry_time)
+ self.assertTrue(threads[1].exit_time <= threads[2].entry_time)
+ self.assertTrue(threads[2].exit_time <= threads[3].entry_time)
+ self.assertTrue(threads[2].exit_time <= threads[4].entry_time)
def test_many_writers_priority(self):
(buffer_, rw_lock, threads) = self.__init_variables()
@@ -152,13 +154,13 @@ class RWLockTestCase(unittest.TestCase):
self.assertEqual([1], threads[1].buffer_read)
self.assertEqual([1, 2, 3], threads[3].buffer_read)
self.assertEqual([1, 2, 3], threads[4].buffer_read)
- self.assert_(threads[0].exit_time < threads[1].entry_time)
- self.assert_(threads[1].exit_time <= threads[2].entry_time)
- self.assert_(threads[1].exit_time <= threads[5].entry_time)
- self.assert_(threads[2].exit_time <= threads[3].entry_time)
- self.assert_(threads[2].exit_time <= threads[4].entry_time)
- self.assert_(threads[5].exit_time <= threads[3].entry_time)
- self.assert_(threads[5].exit_time <= threads[4].entry_time)
+ self.assertTrue(threads[0].exit_time < threads[1].entry_time)
+ self.assertTrue(threads[1].exit_time <= threads[2].entry_time)
+ self.assertTrue(threads[1].exit_time <= threads[5].entry_time)
+ self.assertTrue(threads[2].exit_time <= threads[3].entry_time)
+ self.assertTrue(threads[2].exit_time <= threads[4].entry_time)
+ self.assertTrue(threads[5].exit_time <= threads[3].entry_time)
+ self.assertTrue(threads[5].exit_time <= threads[4].entry_time)
@staticmethod
def __init_variables():
diff --git a/freezed_deps/ecdsa/util.py b/frozen_deps/ecdsa/util.py
index 5f1c750..e77d61c 100644
--- a/freezed_deps/ecdsa/util.py
+++ b/frozen_deps/ecdsa/util.py
@@ -5,7 +5,7 @@ import math
import binascii
import sys
from hashlib import sha256
-from six import PY3, int2byte, b, next
+from six import PY2, int2byte, b, next
from . import der
from ._compat import normalise_bytes
@@ -17,27 +17,50 @@ from ._compat import normalise_bytes
oid_ecPublicKey = (1, 2, 840, 10045, 2, 1)
encoded_oid_ecPublicKey = der.encode_oid(*oid_ecPublicKey)
-if sys.version > '3':
+# RFC5480:
+# The ECDH algorithm uses the following object identifier:
+# id-ecDH OBJECT IDENTIFIER ::= {
+# iso(1) identified-organization(3) certicom(132) schemes(1)
+# ecdh(12) }
+
+oid_ecDH = (1, 3, 132, 1, 12)
+
+# RFC5480:
+# The ECMQV algorithm uses the following object identifier:
+# id-ecMQV OBJECT IDENTIFIER ::= {
+# iso(1) identified-organization(3) certicom(132) schemes(1)
+# ecmqv(13) }
+
+oid_ecMQV = (1, 3, 132, 1, 13)
+
+if sys.version_info >= (3,):
+
def entropy_to_bits(ent_256):
"""Convert a bytestring to string of 0's and 1's"""
- return bin(int.from_bytes(ent_256, 'big'))[2:].zfill(len(ent_256)*8)
+ return bin(int.from_bytes(ent_256, "big"))[2:].zfill(len(ent_256) * 8)
+
+
else:
+
def entropy_to_bits(ent_256):
"""Convert a bytestring to string of 0's and 1's"""
- return ''.join(bin(ord(x))[2:].zfill(8) for x in ent_256)
+ return "".join(bin(ord(x))[2:].zfill(8) for x in ent_256)
-if sys.version < '2.7':
+if sys.version_info < (2, 7):
# Can't add a method to a built-in type so we are stuck with this
def bit_length(x):
return len(bin(x)) - 2
+
+
else:
+
def bit_length(x):
return x.bit_length() or 1
def orderlen(order):
- return (1+len("%x" % order))//2 # bytes
+ return (1 + len("%x" % order)) // 2 # bytes
def randrange(order, entropy=None):
@@ -54,8 +77,8 @@ def randrange(order, entropy=None):
assert order > 1
if entropy is None:
entropy = os.urandom
- upper_2 = bit_length(order-2)
- upper_256 = upper_2//8 + 1
+ upper_2 = bit_length(order - 2)
+ upper_256 = upper_2 // 8 + 1
while True: # I don't think this needs a counter with bit-wise randrange
ent_256 = entropy(upper_256)
ent_2 = entropy_to_bits(ent_256)
@@ -76,15 +99,17 @@ class PRNG:
def __call__(self, numbytes):
a = [next(self.generator) for i in range(numbytes)]
- if PY3:
- return bytes(a)
- else:
+ if PY2:
return "".join(a)
+ else:
+ return bytes(a)
def block_generator(self, seed):
counter = 0
while True:
- for byte in sha256(("prng-%d-%s" % (counter, seed)).encode()).digest():
+ for byte in sha256(
+ ("prng-%d-%s" % (counter, seed)).encode()
+ ).digest():
yield byte
counter += 1
@@ -124,6 +149,7 @@ def bits_and_bytes(order):
# secexp = ecdsa.util.randrange_from_seed__trytryagain(sed, curve.order)
# sk = SigningKey.from_secret_exponent(secexp, curve)
+
def randrange_from_seed__truncate_bytes(seed, order, hashmod=sha256):
# hash the seed, then turn the digest into a number in [1,order), but
# don't worry about trying to uniformly fill the range. This will lose,
@@ -201,6 +227,7 @@ def string_to_number_fixedlen(string, order):
# sigdecode= argument to VK.verify(), and control how the signature is packed
# or unpacked.
+
def sigencode_strings(r, s, order):
r_str = number_to_string(r, order)
s_str = number_to_string(s, order)
@@ -254,8 +281,9 @@ def sigencode_der(r, s, order):
# canonical versions of sigencode methods
-# these enforce low S values, by negating the value (modulo the order) if above order/2
-# see CECKey::Sign() https://github.com/bitcoin/bitcoin/blob/master/src/key.cpp#L214
+# these enforce low S values, by negating the value (modulo the order) if
+# above order/2 see CECKey::Sign()
+# https://github.com/bitcoin/bitcoin/blob/master/src/key.cpp#L214
def sigencode_strings_canonize(r, s, order):
if s > order / 2:
s = order - s
@@ -313,8 +341,8 @@ def sigdecode_string(signature, order):
if not len(signature) == 2 * l:
raise MalformedSignature(
"Invalid length of signature, expected {0} bytes long, "
- "provided string is {1} bytes long"
- .format(2 * l, len(signature)))
+ "provided string is {1} bytes long".format(2 * l, len(signature))
+ )
r = string_to_number_fixedlen(signature[:l], order)
s = string_to_number_fixedlen(signature[l:], order)
return r, s
@@ -341,8 +369,10 @@ def sigdecode_strings(rs_strings, order):
"""
if not len(rs_strings) == 2:
raise MalformedSignature(
- "Invalid number of strings provided: {0}, expected 2"
- .format(len(rs_strings)))
+ "Invalid number of strings provided: {0}, expected 2".format(
+ len(rs_strings)
+ )
+ )
(r_str, s_str) = rs_strings
r_str = normalise_bytes(r_str)
s_str = normalise_bytes(s_str)
@@ -350,13 +380,15 @@ def sigdecode_strings(rs_strings, order):
if not len(r_str) == l:
raise MalformedSignature(
"Invalid length of first string ('r' parameter), "
- "expected {0} bytes long, provided string is {1} bytes long"
- .format(l, len(r_str)))
+ "expected {0} bytes long, provided string is {1} "
+ "bytes long".format(l, len(r_str))
+ )
if not len(s_str) == l:
raise MalformedSignature(
"Invalid length of second string ('s' parameter), "
- "expected {0} bytes long, provided string is {1} bytes long"
- .format(l, len(s_str)))
+ "expected {0} bytes long, provided string is {1} "
+ "bytes long".format(l, len(s_str))
+ )
r = string_to_number_fixedlen(r_str, order)
s = string_to_number_fixedlen(s_str, order)
return r, s
@@ -391,11 +423,13 @@ def sigdecode_der(sig_der, order):
# return der.encode_sequence(der.encode_integer(r), der.encode_integer(s))
rs_strings, empty = der.remove_sequence(sig_der)
if empty != b"":
- raise der.UnexpectedDER("trailing junk after DER sig: %s" %
- binascii.hexlify(empty))
+ raise der.UnexpectedDER(
+ "trailing junk after DER sig: %s" % binascii.hexlify(empty)
+ )
r, rest = der.remove_integer(rs_strings)
s, empty = der.remove_integer(rest)
if empty != b"":
- raise der.UnexpectedDER("trailing junk after DER numbers: %s" %
- binascii.hexlify(empty))
+ raise der.UnexpectedDER(
+ "trailing junk after DER numbers: %s" % binascii.hexlify(empty)
+ )
return r, s
diff --git a/freezed_deps/keytree.py-0.2.dist-info/INSTALLER b/frozen_deps/keytree.py-0.2.dist-info/INSTALLER
index a1b589e..a1b589e 100644
--- a/freezed_deps/keytree.py-0.2.dist-info/INSTALLER
+++ b/frozen_deps/keytree.py-0.2.dist-info/INSTALLER
diff --git a/freezed_deps/keytree.py-0.2.dist-info/METADATA b/frozen_deps/keytree.py-0.2.dist-info/METADATA
index 39653b5..ced8872 100644
--- a/freezed_deps/keytree.py-0.2.dist-info/METADATA
+++ b/frozen_deps/keytree.py-0.2.dist-info/METADATA
@@ -10,6 +10,7 @@ Platform: UNKNOWN
Requires-Dist: ecdsa
Requires-Dist: base58
Requires-Dist: pysha3
+Requires-Dist: pycrypto
Requires-Dist: mnemonic
UNKNOWN
diff --git a/freezed_deps/keytree.py-0.2.dist-info/RECORD b/frozen_deps/keytree.py-0.2.dist-info/RECORD
index fb29847..6d5e4e7 100644
--- a/freezed_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=4wc6C66L6SP8SAoIviOIlKSHwhZICpZ-RzyD9dv6oRA,8097
+../../bin/keytree.py,sha256=3ZAMRh7CeqEydctLUTqBLfcgiVZlDfmcsDfUWcxLYjw,10394
__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=0uY8qpORqGzU6yUUZS0Td2tknlN7tKi-ncL_wPe0FA4,339
+keytree.py-0.2.dist-info/METADATA,sha256=mbeKpm8oSaMl3-pBpqeonURUlfmadsd0gw7rt8ZVm1w,363
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/freezed_deps/keytree.py-0.2.dist-info/WHEEL b/frozen_deps/keytree.py-0.2.dist-info/WHEEL
index b552003..b552003 100644
--- a/freezed_deps/keytree.py-0.2.dist-info/WHEEL
+++ b/frozen_deps/keytree.py-0.2.dist-info/WHEEL
diff --git a/freezed_deps/keytree.py-0.2.dist-info/direct_url.json b/frozen_deps/keytree.py-0.2.dist-info/direct_url.json
index 650a846..650a846 100644
--- a/freezed_deps/keytree.py-0.2.dist-info/direct_url.json
+++ b/frozen_deps/keytree.py-0.2.dist-info/direct_url.json
diff --git a/freezed_deps/keytree.py-0.2.dist-info/top_level.txt b/frozen_deps/keytree.py-0.2.dist-info/top_level.txt
index e5e2a6a..e5e2a6a 100644
--- a/freezed_deps/keytree.py-0.2.dist-info/top_level.txt
+++ b/frozen_deps/keytree.py-0.2.dist-info/top_level.txt
diff --git a/freezed_deps/mnemonic-0.19.dist-info/AUTHORS b/frozen_deps/mnemonic-0.19.dist-info/AUTHORS
index 34ed344..34ed344 100644
--- a/freezed_deps/mnemonic-0.19.dist-info/AUTHORS
+++ b/frozen_deps/mnemonic-0.19.dist-info/AUTHORS
diff --git a/freezed_deps/mnemonic-0.19.dist-info/INSTALLER b/frozen_deps/mnemonic-0.19.dist-info/INSTALLER
index a1b589e..a1b589e 100644
--- a/freezed_deps/mnemonic-0.19.dist-info/INSTALLER
+++ b/frozen_deps/mnemonic-0.19.dist-info/INSTALLER
diff --git a/freezed_deps/mnemonic-0.19.dist-info/LICENSE b/frozen_deps/mnemonic-0.19.dist-info/LICENSE
index b135744..b135744 100644
--- a/freezed_deps/mnemonic-0.19.dist-info/LICENSE
+++ b/frozen_deps/mnemonic-0.19.dist-info/LICENSE
diff --git a/freezed_deps/mnemonic-0.19.dist-info/METADATA b/frozen_deps/mnemonic-0.19.dist-info/METADATA
index ccd2d7e..ccd2d7e 100644
--- a/freezed_deps/mnemonic-0.19.dist-info/METADATA
+++ b/frozen_deps/mnemonic-0.19.dist-info/METADATA
diff --git a/freezed_deps/mnemonic-0.19.dist-info/RECORD b/frozen_deps/mnemonic-0.19.dist-info/RECORD
index dea0329..dea0329 100644
--- a/freezed_deps/mnemonic-0.19.dist-info/RECORD
+++ b/frozen_deps/mnemonic-0.19.dist-info/RECORD
diff --git a/freezed_deps/mnemonic-0.19.dist-info/WHEEL b/frozen_deps/mnemonic-0.19.dist-info/WHEEL
index c8240f0..c8240f0 100644
--- a/freezed_deps/mnemonic-0.19.dist-info/WHEEL
+++ b/frozen_deps/mnemonic-0.19.dist-info/WHEEL
diff --git a/freezed_deps/mnemonic-0.19.dist-info/top_level.txt b/frozen_deps/mnemonic-0.19.dist-info/top_level.txt
index 9015942..9015942 100644
--- a/freezed_deps/mnemonic-0.19.dist-info/top_level.txt
+++ b/frozen_deps/mnemonic-0.19.dist-info/top_level.txt
diff --git a/freezed_deps/mnemonic/__init__.py b/frozen_deps/mnemonic/__init__.py
index 47e293d..47e293d 100644
--- a/freezed_deps/mnemonic/__init__.py
+++ b/frozen_deps/mnemonic/__init__.py
diff --git a/freezed_deps/mnemonic/mnemonic.py b/frozen_deps/mnemonic/mnemonic.py
index 935620a..935620a 100644
--- a/freezed_deps/mnemonic/mnemonic.py
+++ b/frozen_deps/mnemonic/mnemonic.py
diff --git a/freezed_deps/mnemonic/wordlist/chinese_simplified.txt b/frozen_deps/mnemonic/wordlist/chinese_simplified.txt
index b90f1ed..b90f1ed 100644
--- a/freezed_deps/mnemonic/wordlist/chinese_simplified.txt
+++ b/frozen_deps/mnemonic/wordlist/chinese_simplified.txt
diff --git a/freezed_deps/mnemonic/wordlist/chinese_traditional.txt b/frozen_deps/mnemonic/wordlist/chinese_traditional.txt
index 9b02047..9b02047 100644
--- a/freezed_deps/mnemonic/wordlist/chinese_traditional.txt
+++ b/frozen_deps/mnemonic/wordlist/chinese_traditional.txt
diff --git a/freezed_deps/mnemonic/wordlist/english.txt b/frozen_deps/mnemonic/wordlist/english.txt
index 942040e..942040e 100644
--- a/freezed_deps/mnemonic/wordlist/english.txt
+++ b/frozen_deps/mnemonic/wordlist/english.txt
diff --git a/freezed_deps/mnemonic/wordlist/french.txt b/frozen_deps/mnemonic/wordlist/french.txt
index 8600949..8600949 100644
--- a/freezed_deps/mnemonic/wordlist/french.txt
+++ b/frozen_deps/mnemonic/wordlist/french.txt
diff --git a/freezed_deps/mnemonic/wordlist/italian.txt b/frozen_deps/mnemonic/wordlist/italian.txt
index c47370f..c47370f 100644
--- a/freezed_deps/mnemonic/wordlist/italian.txt
+++ b/frozen_deps/mnemonic/wordlist/italian.txt
diff --git a/freezed_deps/mnemonic/wordlist/japanese.txt b/frozen_deps/mnemonic/wordlist/japanese.txt
index fb8501a..fb8501a 100644
--- a/freezed_deps/mnemonic/wordlist/japanese.txt
+++ b/frozen_deps/mnemonic/wordlist/japanese.txt
diff --git a/freezed_deps/mnemonic/wordlist/korean.txt b/frozen_deps/mnemonic/wordlist/korean.txt
index 1acebf7..1acebf7 100644
--- a/freezed_deps/mnemonic/wordlist/korean.txt
+++ b/frozen_deps/mnemonic/wordlist/korean.txt
diff --git a/freezed_deps/mnemonic/wordlist/spanish.txt b/frozen_deps/mnemonic/wordlist/spanish.txt
index fdbc23c..fdbc23c 100644
--- a/freezed_deps/mnemonic/wordlist/spanish.txt
+++ b/frozen_deps/mnemonic/wordlist/spanish.txt
diff --git a/freezed_deps/pysha3-1.0.2.dist-info/INSTALLER b/frozen_deps/pycrypto-2.6.1.dist-info/INSTALLER
index a1b589e..a1b589e 100644
--- a/freezed_deps/pysha3-1.0.2.dist-info/INSTALLER
+++ b/frozen_deps/pycrypto-2.6.1.dist-info/INSTALLER
diff --git a/frozen_deps/pycrypto-2.6.1.dist-info/METADATA b/frozen_deps/pycrypto-2.6.1.dist-info/METADATA
new file mode 100644
index 0000000..3f5b6a7
--- /dev/null
+++ b/frozen_deps/pycrypto-2.6.1.dist-info/METADATA
@@ -0,0 +1,22 @@
+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: [email protected]
+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
new file mode 100644
index 0000000..bcad46d
--- /dev/null
+++ b/frozen_deps/pycrypto-2.6.1.dist-info/RECORD
@@ -0,0 +1,261 @@
+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/freezed_deps/pysha3-1.0.2.dist-info/WHEEL b/frozen_deps/pycrypto-2.6.1.dist-info/WHEEL
index d193dea..d193dea 100644
--- a/freezed_deps/pysha3-1.0.2.dist-info/WHEEL
+++ b/frozen_deps/pycrypto-2.6.1.dist-info/WHEEL
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
new file mode 100644
index 0000000..e6645e7
--- /dev/null
+++ b/frozen_deps/pycrypto-2.6.1.dist-info/top_level.txt
@@ -0,0 +1 @@
+Crypto
diff --git a/freezed_deps/six-1.15.0.dist-info/INSTALLER b/frozen_deps/pysha3-1.0.2.dist-info/INSTALLER
index a1b589e..a1b589e 100644
--- a/freezed_deps/six-1.15.0.dist-info/INSTALLER
+++ b/frozen_deps/pysha3-1.0.2.dist-info/INSTALLER
diff --git a/freezed_deps/pysha3-1.0.2.dist-info/LICENSE b/frozen_deps/pysha3-1.0.2.dist-info/LICENSE
index 311690c..311690c 100644
--- a/freezed_deps/pysha3-1.0.2.dist-info/LICENSE
+++ b/frozen_deps/pysha3-1.0.2.dist-info/LICENSE
diff --git a/freezed_deps/pysha3-1.0.2.dist-info/METADATA b/frozen_deps/pysha3-1.0.2.dist-info/METADATA
index 5e11ab7..5e11ab7 100644
--- a/freezed_deps/pysha3-1.0.2.dist-info/METADATA
+++ b/frozen_deps/pysha3-1.0.2.dist-info/METADATA
diff --git a/freezed_deps/pysha3-1.0.2.dist-info/RECORD b/frozen_deps/pysha3-1.0.2.dist-info/RECORD
index 17ecd37..17ecd37 100644
--- a/freezed_deps/pysha3-1.0.2.dist-info/RECORD
+++ b/frozen_deps/pysha3-1.0.2.dist-info/RECORD
diff --git a/frozen_deps/pysha3-1.0.2.dist-info/WHEEL b/frozen_deps/pysha3-1.0.2.dist-info/WHEEL
new file mode 100644
index 0000000..d193dea
--- /dev/null
+++ b/frozen_deps/pysha3-1.0.2.dist-info/WHEEL
@@ -0,0 +1,5 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.34.2)
+Root-Is-Purelib: false
+Tag: cp38-cp38-linux_x86_64
+
diff --git a/freezed_deps/pysha3-1.0.2.dist-info/top_level.txt b/frozen_deps/pysha3-1.0.2.dist-info/top_level.txt
index a9e88ad..a9e88ad 100644
--- a/freezed_deps/pysha3-1.0.2.dist-info/top_level.txt
+++ b/frozen_deps/pysha3-1.0.2.dist-info/top_level.txt
diff --git a/freezed_deps/sha3.py b/frozen_deps/sha3.py
index 5657f66..5657f66 100644
--- a/freezed_deps/sha3.py
+++ b/frozen_deps/sha3.py
diff --git a/frozen_deps/six-1.15.0.dist-info/INSTALLER b/frozen_deps/six-1.15.0.dist-info/INSTALLER
new file mode 100644
index 0000000..a1b589e
--- /dev/null
+++ b/frozen_deps/six-1.15.0.dist-info/INSTALLER
@@ -0,0 +1 @@
+pip
diff --git a/freezed_deps/six-1.15.0.dist-info/LICENSE b/frozen_deps/six-1.15.0.dist-info/LICENSE
index de66331..de66331 100644
--- a/freezed_deps/six-1.15.0.dist-info/LICENSE
+++ b/frozen_deps/six-1.15.0.dist-info/LICENSE
diff --git a/freezed_deps/six-1.15.0.dist-info/METADATA b/frozen_deps/six-1.15.0.dist-info/METADATA
index 869bf25..869bf25 100644
--- a/freezed_deps/six-1.15.0.dist-info/METADATA
+++ b/frozen_deps/six-1.15.0.dist-info/METADATA
diff --git a/freezed_deps/six-1.15.0.dist-info/RECORD b/frozen_deps/six-1.15.0.dist-info/RECORD
index 80bf846..80bf846 100644
--- a/freezed_deps/six-1.15.0.dist-info/RECORD
+++ b/frozen_deps/six-1.15.0.dist-info/RECORD
diff --git a/freezed_deps/six-1.15.0.dist-info/WHEEL b/frozen_deps/six-1.15.0.dist-info/WHEEL
index ef99c6c..ef99c6c 100644
--- a/freezed_deps/six-1.15.0.dist-info/WHEEL
+++ b/frozen_deps/six-1.15.0.dist-info/WHEEL
diff --git a/freezed_deps/six-1.15.0.dist-info/top_level.txt b/frozen_deps/six-1.15.0.dist-info/top_level.txt
index ffe2fce..ffe2fce 100644
--- a/freezed_deps/six-1.15.0.dist-info/top_level.txt
+++ b/frozen_deps/six-1.15.0.dist-info/top_level.txt
diff --git a/freezed_deps/six.py b/frozen_deps/six.py
index 83f6978..83f6978 100644
--- a/freezed_deps/six.py
+++ b/frozen_deps/six.py
diff --git a/keytree.py b/keytree.py
index 46bea6f..44e922b 100755
--- a/keytree.py
+++ b/keytree.py
@@ -38,7 +38,7 @@ if sys.version_info[1] < 7:
sys.write("Python should be >= 3.7")
sys.exit(1)
basedir = os.path.dirname(os.path.abspath(__file__))
-sys.path.insert(0, basedir + "/freezed_deps")
+sys.path.insert(0, basedir + "/frozen_deps")
import re
import argparse