Move test vectors in a separate package

This commit is contained in:
Helder Eijs 2021-01-02 00:52:11 +01:00
parent 6ccdb9a200
commit eda4f65718
363 changed files with 1198 additions and 1021 deletions

View file

@ -60,8 +60,13 @@ jobs:
if: matrix.os == 'windows-latest' && matrix.python-version == '2.7' if: matrix.os == 'windows-latest' && matrix.python-version == '2.7'
run: choco install vcpython27 run: choco install vcpython27
- name: Install dependencies
run: |
pip install pycryptodome-test-vectors
- name: Test - name: Test
run: python -bb setup.py test run: |
python -bb setup.py test
mypy: mypy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -73,7 +78,7 @@ jobs:
python-version: 3.9 python-version: 3.9
- name: Install dependencies - name: Install dependencies
run: | run: |
pip install mypy pip install mypy pycryptodome-test-vectors
- name: Test - name: Test
run: | run: |
mypy lib/ mypy lib/

View file

@ -12,7 +12,8 @@ PyCryptodome can be used as:
In this case, all modules are installed under the ``Crypto`` package. In this case, all modules are installed under the ``Crypto`` package.
You can test everything is right with:: You can test everything is right with::
python -m Crypto.SelfTest pip install pycryptodome-test-vectors
python -m Crypto.SelfTest
One must avoid having both PyCrypto and PyCryptodome installed One must avoid having both PyCrypto and PyCryptodome installed
at the same time, as they will interfere with each other. at the same time, as they will interfere with each other.
@ -27,6 +28,7 @@ PyCryptodome can be used as:
You can test everything is right with:: You can test everything is right with::
pip install pycryptodome-test-vectors
python -m Cryptodome.SelfTest python -m Cryptodome.SelfTest
In this case, all modules are installed under the ``Cryptodome`` package. In this case, all modules are installed under the ``Cryptodome`` package.
@ -47,18 +49,21 @@ For Python 2.x::
$ sudo apt-get install build-essential python-dev $ sudo apt-get install build-essential python-dev
$ pip install pycryptodomex $ pip install pycryptodomex
$ pip install pycryptodome-test-vectors
$ python -m Cryptodome.SelfTest $ python -m Cryptodome.SelfTest
For Python 3.x:: For Python 3.x::
$ sudo apt-get install build-essential python3-dev $ sudo apt-get install build-essential python3-dev
$ pip install pycryptodomex $ pip install pycryptodomex
$ pip install pycryptodome-test-vectors
$ python3 -m Cryptodome.SelfTest $ python3 -m Cryptodome.SelfTest
For PyPy:: For PyPy::
$ sudo apt-get install build-essential pypy-dev $ sudo apt-get install build-essential pypy-dev
$ pip install pycryptodomex $ pip install pycryptodomex
$ pip install pycryptodome-test-vectors
$ pypy -m Cryptodome.SelfTest $ pypy -m Cryptodome.SelfTest
Compiling in Linux Fedora Compiling in Linux Fedora
@ -72,18 +77,21 @@ For Python 2.x::
$ sudo yum install gcc gmp python-devel $ sudo yum install gcc gmp python-devel
$ pip install pycryptodomex $ pip install pycryptodomex
$ pip install pycryptodome-test-vectors
$ python -m Cryptodome.SelfTest $ python -m Cryptodome.SelfTest
For Python 3.x:: For Python 3.x::
$ sudo yum install gcc gmp python3-devel $ sudo yum install gcc gmp python3-devel
$ pip install pycryptodomex $ pip install pycryptodomex
$ pip install pycryptodome-test-vectors
$ python3 -m Cryptodome.SelfTest $ python3 -m Cryptodome.SelfTest
For PyPy:: For PyPy::
$ sudo yum install gcc gmp pypy-devel $ sudo yum install gcc gmp pypy-devel
$ pip install pycryptodomex $ pip install pycryptodomex
$ pip install pycryptodome-test-vectors
$ pypy -m Cryptodome.SelfTest $ pypy -m Cryptodome.SelfTest
@ -134,6 +142,7 @@ components freely made available by Microsoft.
#. To make sure everything work fine, run the test suite:: #. To make sure everything work fine, run the test suite::
> pip install pycryptodome-test-vectors
> python -m Cryptodome.SelfTest > python -m Cryptodome.SelfTest
Windows (from sources, Python 3.3 and 3.4) Windows (from sources, Python 3.3 and 3.4)
@ -183,6 +192,7 @@ components freely made available by Microsoft.
#. To make sure everything work fine, run the test suite:: #. To make sure everything work fine, run the test suite::
> pip install pycryptodome-test-vectors
> python -m Cryptodome.SelfTest > python -m Cryptodome.SelfTest
Windows (from sources, Python 3.5 and newer) Windows (from sources, Python 3.5 and newer)
@ -206,6 +216,7 @@ components freely made available by Microsoft.
#. To make sure everything work fine, run the test suite:: #. To make sure everything work fine, run the test suite::
> pip install pycryptodome-test-vectors
> python -m Cryptodome.SelfTest > python -m Cryptodome.SelfTest
Documentation Documentation

View file

@ -67,208 +67,3 @@ The OCB cipher mode is patented in the US under patent numbers 7,949,129 and
8,321,675. The directory Doc/ocb contains three free licenses for implementors 8,321,675. The directory Doc/ocb contains three free licenses for implementors
and users. As a general statement, OCB can be freely used for software not meant and users. As a general statement, OCB can be freely used for software not meant
for military purposes. Contact your attorney for further information. for military purposes. Contact your attorney for further information.
Apache 2.0 license (Wycheproof)
===============================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -31,12 +31,13 @@
import unittest import unittest
from binascii import unhexlify from binascii import unhexlify
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.Util.py3compat import tobytes, is_string from Crypto.Util.py3compat import tobytes, is_string
from Crypto.Cipher import AES, DES3, DES from Crypto.Cipher import AES, DES3, DES
from Crypto.Hash import SHAKE128 from Crypto.Hash import SHAKE128
def get_tag_random(tag, length): def get_tag_random(tag, length):
return SHAKE128.new(data=tobytes(tag)).read(length) return SHAKE128.new(data=tobytes(tag)).read(length)
@ -311,11 +312,13 @@ class CbcTests(BlockChainingTests):
class NistBlockChainingVectors(unittest.TestCase): class NistBlockChainingVectors(unittest.TestCase):
def _do_kat_aes_test(self, file_name): def _do_kat_aes_test(self, file_name):
test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "AES"),
file_name, test_vectors = load_test_vectors(("Cipher", "AES"),
"AES KAT", file_name,
{ "count" : lambda x: int(x) } ) "AES CBC KAT",
assert(test_vectors) { "count" : lambda x: int(x) } )
if test_vectors is None:
return
direction = None direction = None
for tv in test_vectors: for tv in test_vectors:
@ -337,11 +340,13 @@ class NistBlockChainingVectors(unittest.TestCase):
# See Section 6.4.2 in AESAVS # See Section 6.4.2 in AESAVS
def _do_mct_aes_test(self, file_name): def _do_mct_aes_test(self, file_name):
test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "AES"),
file_name, test_vectors = load_test_vectors(("Cipher", "AES"),
"AES Montecarlo", file_name,
{ "count" : lambda x: int(x) } ) "AES CBC Montecarlo",
assert(test_vectors) { "count" : lambda x: int(x) } )
if test_vectors is None:
return
direction = None direction = None
for tv in test_vectors: for tv in test_vectors:
@ -370,11 +375,13 @@ class NistBlockChainingVectors(unittest.TestCase):
assert False assert False
def _do_tdes_test(self, file_name): def _do_tdes_test(self, file_name):
test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "TDES"),
file_name, test_vectors = load_test_vectors(("Cipher", "TDES"),
"TDES CBC KAT", file_name,
{ "count" : lambda x: int(x) } ) "TDES CBC KAT",
assert(test_vectors) { "count" : lambda x: int(x) } )
if test_vectors is None:
return
direction = None direction = None
for tv in test_vectors: for tv in test_vectors:

View file

@ -28,18 +28,18 @@
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
# =================================================================== # ===================================================================
import json
import unittest import unittest
from binascii import unhexlify from binascii import unhexlify
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.SelfTest.loader import load_test_vectors_wycheproof
from Crypto.Util.py3compat import tobytes, bchr from Crypto.Util.py3compat import tobytes, bchr
from Crypto.Cipher import AES from Crypto.Cipher import AES
from Crypto.Hash import SHAKE128 from Crypto.Hash import SHAKE128
from Crypto.Util._file_system import pycryptodome_filename
from Crypto.Util.strxor import strxor from Crypto.Util.strxor import strxor
def get_tag_random(tag, length): def get_tag_random(tag, length):
return SHAKE128.new(data=tobytes(tag)).read(length) return SHAKE128.new(data=tobytes(tag)).read(length)
@ -371,7 +371,7 @@ class CcmTests(unittest.TestCase):
pt_test = cipher4.decrypt_and_verify(memoryview(ct_test), memoryview(tag_test)) pt_test = cipher4.decrypt_and_verify(memoryview(ct_test), memoryview(tag_test))
self.assertEqual(self.data_128, pt_test) self.assertEqual(self.data_128, pt_test)
def test_output_param(self): def test_output_param(self):
pt = b'5' * 16 pt = b'5' * 16
@ -384,25 +384,25 @@ class CcmTests(unittest.TestCase):
res = cipher.encrypt(pt, output=output) res = cipher.encrypt(pt, output=output)
self.assertEqual(ct, output) self.assertEqual(ct, output)
self.assertEqual(res, None) self.assertEqual(res, None)
cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96)
res = cipher.decrypt(ct, output=output) res = cipher.decrypt(ct, output=output)
self.assertEqual(pt, output) self.assertEqual(pt, output)
self.assertEqual(res, None) self.assertEqual(res, None)
cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96)
res, tag_out = cipher.encrypt_and_digest(pt, output=output) res, tag_out = cipher.encrypt_and_digest(pt, output=output)
self.assertEqual(ct, output) self.assertEqual(ct, output)
self.assertEqual(res, None) self.assertEqual(res, None)
self.assertEqual(tag, tag_out) self.assertEqual(tag, tag_out)
cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96)
res = cipher.decrypt_and_verify(ct, tag, output=output) res = cipher.decrypt_and_verify(ct, tag, output=output)
self.assertEqual(pt, output) self.assertEqual(pt, output)
self.assertEqual(res, None) self.assertEqual(res, None)
def test_output_param_memoryview(self): def test_output_param_memoryview(self):
pt = b'5' * 16 pt = b'5' * 16
cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96)
ct = cipher.encrypt(pt) ct = cipher.encrypt(pt)
@ -411,7 +411,7 @@ class CcmTests(unittest.TestCase):
cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96)
cipher.encrypt(pt, output=output) cipher.encrypt(pt, output=output)
self.assertEqual(ct, output) self.assertEqual(ct, output)
cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96)
cipher.decrypt(ct, output=output) cipher.decrypt(ct, output=output)
self.assertEqual(pt, output) self.assertEqual(pt, output)
@ -424,7 +424,7 @@ class CcmTests(unittest.TestCase):
cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96)
self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*16) self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*16)
cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96)
self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*16) self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*16)
@ -830,27 +830,14 @@ class TestVectorsWycheproof(unittest.TestCase):
self._id = "None" self._id = "None"
def setUp(self): def setUp(self):
comps = "Crypto.SelfTest.Cipher.test_vectors.wycheproof".split(".")
with open(pycryptodome_filename(comps, "aes_ccm_test.json"), "rt") as file_in:
tv_tree = json.load(file_in)
class TestVector(object): def filter_tag(group):
pass return group['tagSize'] // 8
self.tv = []
for group in tv_tree['testGroups']: self.tv = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
tag_size = group['tagSize'] // 8 "aes_ccm_test.json",
for test in group['tests']: "Wycheproof AES CCM",
tv = TestVector() group_tag={'tag_size': filter_tag})
tv.tag_size = tag_size
tv.id = test['tcId']
tv.comment = test['comment']
for attr in 'key', 'iv', 'aad', 'msg', 'ct', 'tag':
setattr(tv, attr, unhexlify(test[attr]))
tv.valid = test['result'] != "invalid"
tv.warning = test['result'] == "acceptable"
self.tv.append(tv)
def shortDescription(self): def shortDescription(self):
return self._id return self._id
@ -865,7 +852,7 @@ class TestVectorsWycheproof(unittest.TestCase):
try: try:
cipher = AES.new(tv.key, AES.MODE_CCM, tv.iv, mac_len=tv.tag_size, cipher = AES.new(tv.key, AES.MODE_CCM, tv.iv, mac_len=tv.tag_size,
**self._extra_params) **self._extra_params)
except ValueError as e: except ValueError as e:
if len(tv.iv) not in range(7, 13 + 1, 2) and "Length of parameter 'nonce'" in str(e): if len(tv.iv) not in range(7, 13 + 1, 2) and "Length of parameter 'nonce'" in str(e):
assert not tv.valid assert not tv.valid
@ -887,7 +874,7 @@ class TestVectorsWycheproof(unittest.TestCase):
try: try:
cipher = AES.new(tv.key, AES.MODE_CCM, tv.iv, mac_len=tv.tag_size, cipher = AES.new(tv.key, AES.MODE_CCM, tv.iv, mac_len=tv.tag_size,
**self._extra_params) **self._extra_params)
except ValueError as e: except ValueError as e:
if len(tv.iv) not in range(7, 13 + 1, 2) and "Length of parameter 'nonce'" in str(e): if len(tv.iv) not in range(7, 13 + 1, 2) and "Length of parameter 'nonce'" in str(e):
assert not tv.valid assert not tv.valid
@ -912,7 +899,7 @@ class TestVectorsWycheproof(unittest.TestCase):
if len(tv.iv) not in range(7, 13 + 1, 2) or len(tv.ct) == 0: if len(tv.iv) not in range(7, 13 + 1, 2) or len(tv.ct) == 0:
return return
cipher = AES.new(tv.key, AES.MODE_CCM, tv.iv, mac_len=tv.tag_size, cipher = AES.new(tv.key, AES.MODE_CCM, tv.iv, mac_len=tv.tag_size,
**self._extra_params) **self._extra_params)
cipher.update(tv.aad) cipher.update(tv.aad)
ct_corrupt = strxor(tv.ct, b"\x00" * (len(tv.ct) - 1) + b"\x01") ct_corrupt = strxor(tv.ct, b"\x00" * (len(tv.ct) - 1) + b"\x01")
self.assertRaises(ValueError, cipher.decrypt_and_verify, ct_corrupt, tv.tag) self.assertRaises(ValueError, cipher.decrypt_and_verify, ct_corrupt, tv.tag)
@ -932,11 +919,12 @@ def get_tests(config={}):
tests += list_test_cases(CcmTests) tests += list_test_cases(CcmTests)
tests += list_test_cases(CcmFSMTests) tests += list_test_cases(CcmFSMTests)
tests += [TestVectors()] tests += [TestVectors()]
tests += [ TestVectorsWycheproof(wycheproof_warnings) ] tests += [TestVectorsWycheproof(wycheproof_warnings)]
return tests return tests
if __name__ == '__main__': if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests()) def suite():
unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite') unittest.main(defaultTest='suite')

View file

@ -31,18 +31,19 @@
import unittest import unittest
from binascii import unhexlify from binascii import unhexlify
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.Util.py3compat import tobytes, is_string from Crypto.Util.py3compat import tobytes, is_string
from Crypto.Cipher import AES, DES3, DES from Crypto.Cipher import AES, DES3, DES
from Crypto.Hash import SHAKE128 from Crypto.Hash import SHAKE128
from Crypto.SelfTest.Cipher.test_CBC import BlockChainingTests
def get_tag_random(tag, length): def get_tag_random(tag, length):
return SHAKE128.new(data=tobytes(tag)).read(length) return SHAKE128.new(data=tobytes(tag)).read(length)
from Crypto.SelfTest.Cipher.test_CBC import BlockChainingTests
class CfbTests(BlockChainingTests): class CfbTests(BlockChainingTests):
aes_mode = AES.MODE_CFB aes_mode = AES.MODE_CFB
@ -101,11 +102,13 @@ class CfbTests(BlockChainingTests):
class NistCfbVectors(unittest.TestCase): class NistCfbVectors(unittest.TestCase):
def _do_kat_aes_test(self, file_name, segment_size): def _do_kat_aes_test(self, file_name, segment_size):
test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "AES"),
file_name, test_vectors = load_test_vectors(("Cipher", "AES"),
"AES CFB%d KAT" % segment_size, file_name,
{ "count" : lambda x: int(x) } ) "AES CFB%d KAT" % segment_size,
assert(test_vectors) { "count" : lambda x: int(x) } )
if test_vectors is None:
return
direction = None direction = None
for tv in test_vectors: for tv in test_vectors:
@ -127,11 +130,14 @@ class NistCfbVectors(unittest.TestCase):
# See Section 6.4.5 in AESAVS # See Section 6.4.5 in AESAVS
def _do_mct_aes_test(self, file_name, segment_size): def _do_mct_aes_test(self, file_name, segment_size):
test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "AES"),
file_name, test_vectors = load_test_vectors(("Cipher", "AES"),
"AES CFB%d Montecarlo" % segment_size, file_name,
{ "count" : lambda x: int(x) } ) "AES CFB%d Montecarlo" % segment_size,
assert(test_vectors) { "count" : lambda x: int(x) } )
if test_vectors is None:
return
assert(segment_size in (8, 128)) assert(segment_size in (8, 128))
direction = None direction = None
@ -175,11 +181,13 @@ class NistCfbVectors(unittest.TestCase):
assert False assert False
def _do_tdes_test(self, file_name, segment_size): def _do_tdes_test(self, file_name, segment_size):
test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "TDES"),
file_name, test_vectors = load_test_vectors(("Cipher", "TDES"),
"AES CFB%d KAT" % segment_size, file_name,
{ "count" : lambda x: int(x) } ) "TDES CFB%d KAT" % segment_size,
assert(test_vectors) { "count" : lambda x: int(x) } )
if test_vectors is None:
return
direction = None direction = None
for tv in test_vectors: for tv in test_vectors:

View file

@ -28,11 +28,11 @@
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
# =================================================================== # ===================================================================
import json
import unittest import unittest
from binascii import unhexlify from binascii import unhexlify
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.SelfTest.loader import load_test_vectors_wycheproof
from Crypto.Util.py3compat import tobytes from Crypto.Util.py3compat import tobytes
from Crypto.Cipher import ChaCha20_Poly1305 from Crypto.Cipher import ChaCha20_Poly1305
from Crypto.Hash import SHAKE128 from Crypto.Hash import SHAKE128
@ -625,29 +625,18 @@ class TestVectorsWycheproof(unittest.TestCase):
self._id = "None" self._id = "None"
def load_tests(self, filename): def load_tests(self, filename):
comps = "Crypto.SelfTest.Cipher.test_vectors.wycheproof".split(".")
with open(pycryptodome_filename(comps, filename), "rt") as file_in:
tv_tree = json.load(file_in)
class TestVector(object): def filter_tag(group):
pass return group['tagSize'] // 8
result = []
for group in tv_tree['testGroups']: def filter_algo(root):
tag_size = group['tagSize'] // 8 return root['algorithm']
for test in group['tests']:
tv = TestVector()
tv.tag_size = tag_size
tv.id = test['tcId'] result = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
tv.comment = test['comment'] filename,
for attr in 'key', 'iv', 'aad', 'msg', 'ct', 'tag': "Wycheproof ChaCha20-Poly1305",
setattr(tv, attr, unhexlify(test[attr])) root_tag={'algo': filter_algo},
tv.valid = test['result'] != "invalid" group_tag={'tag_size': filter_tag})
tv.warning = test['result'] == "acceptable"
tv.algo = tv_tree['algorithm']
result.append(tv)
return result return result
def setUp(self): def setUp(self):
@ -665,7 +654,7 @@ class TestVectorsWycheproof(unittest.TestCase):
def test_encrypt(self, tv): def test_encrypt(self, tv):
self._id = "Wycheproof Encrypt %s Test #%s" % (tv.algo, tv.id) self._id = "Wycheproof Encrypt %s Test #%s" % (tv.algo, tv.id)
try: try:
cipher = ChaCha20_Poly1305.new(key=tv.key, nonce=tv.iv) cipher = ChaCha20_Poly1305.new(key=tv.key, nonce=tv.iv)
except ValueError as e: except ValueError as e:
@ -681,7 +670,7 @@ class TestVectorsWycheproof(unittest.TestCase):
def test_decrypt(self, tv): def test_decrypt(self, tv):
self._id = "Wycheproof Decrypt %s Test #%s" % (tv.algo, tv.id) self._id = "Wycheproof Decrypt %s Test #%s" % (tv.algo, tv.id)
try: try:
cipher = ChaCha20_Poly1305.new(key=tv.key, nonce=tv.iv) cipher = ChaCha20_Poly1305.new(key=tv.key, nonce=tv.iv)
except ValueError as e: except ValueError as e:
@ -732,7 +721,7 @@ class TestOutput(unittest.TestCase):
res = cipher.encrypt(pt, output=output) res = cipher.encrypt(pt, output=output)
self.assertEqual(ct, output) self.assertEqual(ct, output)
self.assertEqual(res, None) self.assertEqual(res, None)
cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce) cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
res = cipher.decrypt(ct, output=output) res = cipher.decrypt(ct, output=output)
self.assertEqual(pt, output) self.assertEqual(pt, output)
@ -742,22 +731,22 @@ class TestOutput(unittest.TestCase):
cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce) cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
cipher.encrypt(pt, output=output) cipher.encrypt(pt, output=output)
self.assertEqual(ct, output) self.assertEqual(ct, output)
cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce) cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
cipher.decrypt(ct, output=output) cipher.decrypt(ct, output=output)
self.assertEqual(pt, output) self.assertEqual(pt, output)
cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce) cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*16) self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*16)
cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce) cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*16) self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*16)
shorter_output = bytearray(7) shorter_output = bytearray(7)
cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce) cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
self.assertRaises(ValueError, cipher.encrypt, pt, output=shorter_output) self.assertRaises(ValueError, cipher.encrypt, pt, output=shorter_output)
cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce) cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
self.assertRaises(ValueError, cipher.decrypt, ct, output=shorter_output) self.assertRaises(ValueError, cipher.decrypt, ct, output=shorter_output)

View file

@ -31,7 +31,7 @@ from Crypto.Cipher import DES3
from Crypto.Util.strxor import strxor_c from Crypto.Util.strxor import strxor_c
from Crypto.Util.py3compat import bchr, tostr from Crypto.Util.py3compat import bchr, tostr
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
# This is a list of (plaintext, ciphertext, key, description) tuples. # This is a list of (plaintext, ciphertext, key, description) tuples.
@ -56,11 +56,13 @@ test_data = [
nist_tdes_mmt_files = ("TECBMMT2.rsp", "TECBMMT3.rsp") nist_tdes_mmt_files = ("TECBMMT2.rsp", "TECBMMT3.rsp")
for tdes_file in nist_tdes_mmt_files: for tdes_file in nist_tdes_mmt_files:
test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "TDES"),
tdes_file, test_vectors = load_test_vectors(
"TDES ECB (%s)" % tdes_file, ("Cipher", "TDES"),
{ "count" : lambda x: int(x) } ) tdes_file,
assert(test_vectors) "TDES ECB (%s)" % tdes_file,
{"count": lambda x: int(x)}) or []
for index, tv in enumerate(test_vectors): for index, tv in enumerate(test_vectors):
# The test vector file contains some directive lines # The test vector file contains some directive lines
@ -107,7 +109,7 @@ class CheckParity(unittest.TestCase):
# K1 == K2 (with different parity) # K1 == K2 (with different parity)
self.assertRaises(ValueError, DES3.adjust_key_parity, self.assertRaises(ValueError, DES3.adjust_key_parity,
sub_key1 + strxor_c(sub_key1, 1) + sub_key2) sub_key1 + strxor_c(sub_key1, 1) + sub_key2)
class DegenerateToDESTest(unittest.TestCase): class DegenerateToDESTest(unittest.TestCase):
@ -128,7 +130,7 @@ class DegenerateToDESTest(unittest.TestCase):
# K1 == K2 == K3 # K1 == K2 == K3
self.assertRaises(ValueError, DES3.new, self.assertRaises(ValueError, DES3.new,
sub_key1 *3, sub_key1 * 3,
DES3.MODE_ECB) DES3.MODE_ECB)
# K2 == K3 (parity is ignored) # K2 == K3 (parity is ignored)
@ -151,7 +153,7 @@ class TestOutput(unittest.TestCase):
res = cipher.encrypt(pt, output=output) res = cipher.encrypt(pt, output=output)
self.assertEqual(ct, output) self.assertEqual(ct, output)
self.assertEqual(res, None) self.assertEqual(res, None)
res = cipher.decrypt(ct, output=output) res = cipher.decrypt(ct, output=output)
self.assertEqual(pt, output) self.assertEqual(pt, output)
self.assertEqual(res, None) self.assertEqual(res, None)
@ -159,7 +161,7 @@ class TestOutput(unittest.TestCase):
output = memoryview(bytearray(16)) output = memoryview(bytearray(16))
cipher.encrypt(pt, output=output) cipher.encrypt(pt, output=output)
self.assertEqual(ct, output) self.assertEqual(ct, output)
cipher.decrypt(ct, output=output) cipher.decrypt(ct, output=output)
self.assertEqual(pt, output) self.assertEqual(pt, output)
@ -184,7 +186,10 @@ def get_tests(config={}):
if __name__ == '__main__': if __name__ == '__main__':
import unittest import unittest
suite = lambda: unittest.TestSuite(get_tests())
def suite():
unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite') unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab: # vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -28,16 +28,15 @@
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
# =================================================================== # ===================================================================
import json
import unittest import unittest
from binascii import unhexlify from binascii import unhexlify
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.SelfTest.loader import load_test_vectors_wycheproof
from Crypto.Util.py3compat import tobytes, bchr from Crypto.Util.py3compat import tobytes, bchr
from Crypto.Cipher import AES, DES3 from Crypto.Cipher import AES, DES3
from Crypto.Hash import SHAKE128 from Crypto.Hash import SHAKE128
from Crypto.Util._file_system import pycryptodome_filename
from Crypto.Util.strxor import strxor from Crypto.Util.strxor import strxor
@ -342,25 +341,25 @@ class EaxTests(unittest.TestCase):
res = cipher.encrypt(pt, output=output) res = cipher.encrypt(pt, output=output)
self.assertEqual(ct, output) self.assertEqual(ct, output)
self.assertEqual(res, None) self.assertEqual(res, None)
cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96)
res = cipher.decrypt(ct, output=output) res = cipher.decrypt(ct, output=output)
self.assertEqual(pt, output) self.assertEqual(pt, output)
self.assertEqual(res, None) self.assertEqual(res, None)
cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96)
res, tag_out = cipher.encrypt_and_digest(pt, output=output) res, tag_out = cipher.encrypt_and_digest(pt, output=output)
self.assertEqual(ct, output) self.assertEqual(ct, output)
self.assertEqual(res, None) self.assertEqual(res, None)
self.assertEqual(tag, tag_out) self.assertEqual(tag, tag_out)
cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96)
res = cipher.decrypt_and_verify(ct, tag, output=output) res = cipher.decrypt_and_verify(ct, tag, output=output)
self.assertEqual(pt, output) self.assertEqual(pt, output)
self.assertEqual(res, None) self.assertEqual(res, None)
def test_output_param_memoryview(self): def test_output_param_memoryview(self):
pt = b'5' * 16 pt = b'5' * 16
cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96)
ct = cipher.encrypt(pt) ct = cipher.encrypt(pt)
@ -369,7 +368,7 @@ class EaxTests(unittest.TestCase):
cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96)
cipher.encrypt(pt, output=output) cipher.encrypt(pt, output=output)
self.assertEqual(ct, output) self.assertEqual(ct, output)
cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96)
cipher.decrypt(ct, output=output) cipher.decrypt(ct, output=output)
self.assertEqual(pt, output) self.assertEqual(pt, output)
@ -382,7 +381,7 @@ class EaxTests(unittest.TestCase):
cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96)
self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*16) self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*16)
cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=self.nonce_96)
self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*16) self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*16)
@ -653,27 +652,14 @@ class TestVectorsWycheproof(unittest.TestCase):
self._id = "None" self._id = "None"
def setUp(self): def setUp(self):
comps = "Crypto.SelfTest.Cipher.test_vectors.wycheproof".split(".")
with open(pycryptodome_filename(comps, "aes_eax_test.json"), "rt") as file_in:
tv_tree = json.load(file_in)
class TestVector(object): def filter_tag(group):
pass return group['tagSize'] // 8
self.tv = []
for group in tv_tree['testGroups']: self.tv = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
tag_size = group['tagSize'] // 8 "aes_eax_test.json",
for test in group['tests']: "Wycheproof EAX",
tv = TestVector() group_tag={'tag_size': filter_tag})
tv.tag_size = tag_size
tv.id = test['tcId']
tv.comment = test['comment']
for attr in 'key', 'iv', 'aad', 'msg', 'ct', 'tag':
setattr(tv, attr, unhexlify(test[attr]))
tv.valid = test['result'] != "invalid"
tv.warning = test['result'] == "acceptable"
self.tv.append(tv)
def shortDescription(self): def shortDescription(self):
return self._id return self._id
@ -685,7 +671,7 @@ class TestVectorsWycheproof(unittest.TestCase):
def test_encrypt(self, tv): def test_encrypt(self, tv):
self._id = "Wycheproof Encrypt EAX Test #" + str(tv.id) self._id = "Wycheproof Encrypt EAX Test #" + str(tv.id)
try: try:
cipher = AES.new(tv.key, AES.MODE_EAX, tv.iv, mac_len=tv.tag_size) cipher = AES.new(tv.key, AES.MODE_EAX, tv.iv, mac_len=tv.tag_size)
except ValueError as e: except ValueError as e:
@ -701,7 +687,7 @@ class TestVectorsWycheproof(unittest.TestCase):
def test_decrypt(self, tv): def test_decrypt(self, tv):
self._id = "Wycheproof Decrypt EAX Test #" + str(tv.id) self._id = "Wycheproof Decrypt EAX Test #" + str(tv.id)
try: try:
cipher = AES.new(tv.key, AES.MODE_EAX, tv.iv, mac_len=tv.tag_size) cipher = AES.new(tv.key, AES.MODE_EAX, tv.iv, mac_len=tv.tag_size)
except ValueError as e: except ValueError as e:

View file

@ -30,18 +30,16 @@
from __future__ import print_function from __future__ import print_function
import json
import unittest import unittest
from binascii import unhexlify from binascii import unhexlify
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors, load_test_vectors_wycheproof
from Crypto.Util.py3compat import tobytes, bchr from Crypto.Util.py3compat import tobytes, bchr
from Crypto.Cipher import AES from Crypto.Cipher import AES
from Crypto.Hash import SHAKE128, SHA256 from Crypto.Hash import SHAKE128, SHA256
from Crypto.Util._file_system import pycryptodome_filename
from Crypto.Util.strxor import strxor from Crypto.Util.strxor import strxor
@ -306,7 +304,7 @@ class GcmTests(unittest.TestCase):
pt_test = cipher4.decrypt_and_verify(memoryview(ct_test), memoryview(tag_test)) pt_test = cipher4.decrypt_and_verify(memoryview(ct_test), memoryview(tag_test))
self.assertEqual(self.data_128, pt_test) self.assertEqual(self.data_128, pt_test)
def test_output_param(self): def test_output_param(self):
pt = b'5' * 16 pt = b'5' * 16
@ -319,25 +317,25 @@ class GcmTests(unittest.TestCase):
res = cipher.encrypt(pt, output=output) res = cipher.encrypt(pt, output=output)
self.assertEqual(ct, output) self.assertEqual(ct, output)
self.assertEqual(res, None) self.assertEqual(res, None)
cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96)
res = cipher.decrypt(ct, output=output) res = cipher.decrypt(ct, output=output)
self.assertEqual(pt, output) self.assertEqual(pt, output)
self.assertEqual(res, None) self.assertEqual(res, None)
cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96)
res, tag_out = cipher.encrypt_and_digest(pt, output=output) res, tag_out = cipher.encrypt_and_digest(pt, output=output)
self.assertEqual(ct, output) self.assertEqual(ct, output)
self.assertEqual(res, None) self.assertEqual(res, None)
self.assertEqual(tag, tag_out) self.assertEqual(tag, tag_out)
cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96)
res = cipher.decrypt_and_verify(ct, tag, output=output) res = cipher.decrypt_and_verify(ct, tag, output=output)
self.assertEqual(pt, output) self.assertEqual(pt, output)
self.assertEqual(res, None) self.assertEqual(res, None)
def test_output_param_memoryview(self): def test_output_param_memoryview(self):
pt = b'5' * 16 pt = b'5' * 16
cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96)
ct = cipher.encrypt(pt) ct = cipher.encrypt(pt)
@ -346,7 +344,7 @@ class GcmTests(unittest.TestCase):
cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96)
cipher.encrypt(pt, output=output) cipher.encrypt(pt, output=output)
self.assertEqual(ct, output) self.assertEqual(ct, output)
cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96)
cipher.decrypt(ct, output=output) cipher.decrypt(ct, output=output)
self.assertEqual(pt, output) self.assertEqual(pt, output)
@ -359,7 +357,7 @@ class GcmTests(unittest.TestCase):
cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96)
self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*16) self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*16)
cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96) cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96)
self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*16) self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*16)
@ -561,7 +559,7 @@ class TestVectors(unittest.TestCase):
'feedfacedeadbeeffeedfacedeadbeefabaddad2', 'feedfacedeadbeeffeedfacedeadbeefabaddad2',
'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' + 'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' +
'1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39',
'42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e' + '42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e' +
'21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091', '21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091',
'5bc94fbc3221a5db94fae95ae7121a47', '5bc94fbc3221a5db94fae95ae7121a47',
'feffe9928665731c6d6a8f9467308308', 'feffe9928665731c6d6a8f9467308308',
@ -586,7 +584,7 @@ class TestVectors(unittest.TestCase):
'619cc5aefffe0bfa462af43c1699d050', '619cc5aefffe0bfa462af43c1699d050',
'feffe9928665731c6d6a8f9467308308', 'feffe9928665731c6d6a8f9467308308',
'9313225df88406e555909c5aff5269aa' + '9313225df88406e555909c5aff5269aa' +
'6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b5254'+ '6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b5254' +
'16aedbf5a0de6a57a637b39b' '16aedbf5a0de6a57a637b39b'
), ),
( (
@ -701,7 +699,7 @@ class TestVectors(unittest.TestCase):
'a44a8266ee1c8eb0c8b5d4cf5ae9f19a', 'a44a8266ee1c8eb0c8b5d4cf5ae9f19a',
'feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308', 'feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308',
'9313225df88406e555909c5aff5269aa' + '9313225df88406e555909c5aff5269aa' +
'6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b5254'+ '6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b5254' +
'16aedbf5a0de6a57a637b39b' '16aedbf5a0de6a57a637b39b'
) )
] ]
@ -767,13 +765,13 @@ class TestVectorsGueronKrasnov(unittest.TestCase):
self.assertEqual(digest, digest2) self.assertEqual(digest, digest2)
class NISTTestVectorsGCM(unittest.TestCase): class NISTTestVectorsGCM(unittest.TestCase):
def __init__(self, a): def __init__(self, a):
self.use_clmul = True self.use_clmul = True
unittest.TestCase.__init__(self, a) unittest.TestCase.__init__(self, a)
class NISTTestVectorsGCM_no_clmul(unittest.TestCase): class NISTTestVectorsGCM_no_clmul(unittest.TestCase):
def __init__(self, a): def __init__(self, a):
@ -781,17 +779,17 @@ class NISTTestVectorsGCM_no_clmul(unittest.TestCase):
unittest.TestCase.__init__(self, a) unittest.TestCase.__init__(self, a)
test_vectors_nist = load_tests( test_vectors_nist = load_test_vectors(
("Crypto", "SelfTest", "Cipher", "test_vectors", "AES"), ("Cipher", "AES"),
"gcmDecrypt128.rsp", "gcmDecrypt128.rsp",
"GCM decrypt", "GCM decrypt",
{ "count" : lambda x: int(x) }) {"count": lambda x: int(x)}) or []
test_vectors_nist += load_tests( test_vectors_nist += load_test_vectors(
("Crypto", "SelfTest", "Cipher", "test_vectors", "AES"), ("Cipher", "AES"),
"gcmEncryptExtIV128.rsp", "gcmEncryptExtIV128.rsp",
"GCM encrypt", "GCM encrypt",
{ "count" : lambda x: int(x) }) {"count": lambda x: int(x)}) or []
for idx, tv in enumerate(test_vectors_nist): for idx, tv in enumerate(test_vectors_nist):
@ -801,16 +799,16 @@ for idx, tv in enumerate(test_vectors_nist):
def single_test(self, tv=tv): def single_test(self, tv=tv):
self.description = tv.desc self.description = tv.desc
cipher = AES.new(tv.key, AES.MODE_GCM, nonce=tv.iv, cipher = AES.new(tv.key, AES.MODE_GCM, nonce=tv.iv,
mac_len=len(tv.tag), use_clmul=self.use_clmul) mac_len=len(tv.tag), use_clmul=self.use_clmul)
cipher.update(tv.aad) cipher.update(tv.aad)
if "FAIL" in tv.others: if "FAIL" in tv.others:
self.assertRaises(ValueError, cipher.decrypt_and_verify, self.assertRaises(ValueError, cipher.decrypt_and_verify,
tv.ct, tv.tag) tv.ct, tv.tag)
else: else:
pt = cipher.decrypt_and_verify(tv.ct, tv.tag) pt = cipher.decrypt_and_verify(tv.ct, tv.tag)
self.assertEqual(pt, tv.pt) self.assertEqual(pt, tv.pt)
setattr(NISTTestVectorsGCM, "test_%d" % idx, single_test) setattr(NISTTestVectorsGCM, "test_%d" % idx, single_test)
setattr(NISTTestVectorsGCM_no_clmul, "test_%d" % idx, single_test) setattr(NISTTestVectorsGCM_no_clmul, "test_%d" % idx, single_test)
@ -825,27 +823,14 @@ class TestVectorsWycheproof(unittest.TestCase):
self._id = "None" self._id = "None"
def setUp(self): def setUp(self):
comps = "Crypto.SelfTest.Cipher.test_vectors.wycheproof".split(".")
with open(pycryptodome_filename(comps, "aes_gcm_test.json"), "rt") as file_in:
tv_tree = json.load(file_in)
class TestVector(object): def filter_tag(group):
pass return group['tagSize'] // 8
self.tv = []
for group in tv_tree['testGroups']: self.tv = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
tag_size = group['tagSize'] // 8 "aes_gcm_test.json",
for test in group['tests']: "Wycheproof GCM",
tv = TestVector() group_tag={'tag_size': filter_tag})
tv.tag_size = tag_size
tv.id = test['tcId']
tv.comment = test['comment']
for attr in 'key', 'iv', 'aad', 'msg', 'ct', 'tag':
setattr(tv, attr, unhexlify(test[attr]))
tv.valid = test['result'] != "invalid"
tv.warning = test['result'] == "acceptable"
self.tv.append(tv)
def shortDescription(self): def shortDescription(self):
return self._id return self._id
@ -860,7 +845,7 @@ class TestVectorsWycheproof(unittest.TestCase):
try: try:
cipher = AES.new(tv.key, AES.MODE_GCM, tv.iv, mac_len=tv.tag_size, cipher = AES.new(tv.key, AES.MODE_GCM, tv.iv, mac_len=tv.tag_size,
**self._extra_params) **self._extra_params)
except ValueError as e: except ValueError as e:
if len(tv.iv) == 0 and "Nonce cannot be empty" in str(e): if len(tv.iv) == 0 and "Nonce cannot be empty" in str(e):
return return
@ -878,7 +863,7 @@ class TestVectorsWycheproof(unittest.TestCase):
try: try:
cipher = AES.new(tv.key, AES.MODE_GCM, tv.iv, mac_len=tv.tag_size, cipher = AES.new(tv.key, AES.MODE_GCM, tv.iv, mac_len=tv.tag_size,
**self._extra_params) **self._extra_params)
except ValueError as e: except ValueError as e:
if len(tv.iv) == 0 and "Nonce cannot be empty" in str(e): if len(tv.iv) == 0 and "Nonce cannot be empty" in str(e):
return return
@ -899,7 +884,7 @@ class TestVectorsWycheproof(unittest.TestCase):
if len(tv.iv) == 0 or len(tv.ct) < 1: if len(tv.iv) == 0 or len(tv.ct) < 1:
return return
cipher = AES.new(tv.key, AES.MODE_GCM, tv.iv, mac_len=tv.tag_size, cipher = AES.new(tv.key, AES.MODE_GCM, tv.iv, mac_len=tv.tag_size,
**self._extra_params) **self._extra_params)
cipher.update(tv.aad) cipher.update(tv.aad)
ct_corrupt = strxor(tv.ct, b"\x00" * (len(tv.ct) - 1) + b"\x01") ct_corrupt = strxor(tv.ct, b"\x00" * (len(tv.ct) - 1) + b"\x01")
self.assertRaises(ValueError, cipher.decrypt_and_verify, ct_corrupt, tv.tag) self.assertRaises(ValueError, cipher.decrypt_and_verify, ct_corrupt, tv.tag)
@ -941,16 +926,16 @@ def get_tests(config={}):
tests = [] tests = []
tests += list_test_cases(GcmTests) tests += list_test_cases(GcmTests)
tests += list_test_cases(GcmFSMTests) tests += list_test_cases(GcmFSMTests)
tests += [ TestVectors() ] tests += [TestVectors()]
tests += [ TestVectorsWycheproof(wycheproof_warnings) ] tests += [TestVectorsWycheproof(wycheproof_warnings)]
tests += list_test_cases(TestVectorsGueronKrasnov) tests += list_test_cases(TestVectorsGueronKrasnov)
tests += [ TestVariableLength() ] tests += [TestVariableLength()]
if config.get('slow_tests'): if config.get('slow_tests'):
tests += list_test_cases(NISTTestVectorsGCM) tests += list_test_cases(NISTTestVectorsGCM)
if _cpu_features.have_clmul(): if _cpu_features.have_clmul():
tests += [ TestVectorsWycheproof(wycheproof_warnings, use_clmul=False) ] tests += [TestVectorsWycheproof(wycheproof_warnings, use_clmul=False)]
tests += [ TestVariableLength(use_clmul = False) ] tests += [TestVariableLength(use_clmul=False)]
if config.get('slow_tests'): if config.get('slow_tests'):
tests += list_test_cases(NISTTestVectorsGCM_no_clmul) tests += list_test_cases(NISTTestVectorsGCM_no_clmul)
else: else:
@ -960,5 +945,6 @@ def get_tests(config={}):
if __name__ == '__main__': if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests()) def suite():
unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite') unittest.main(defaultTest='suite')

View file

@ -35,6 +35,7 @@ from Crypto.SelfTest.st_common import list_test_cases
from Crypto.Util.py3compat import tobytes from Crypto.Util.py3compat import tobytes
from Crypto.Cipher import AES, DES3, DES from Crypto.Cipher import AES, DES3, DES
from Crypto.Hash import SHAKE128 from Crypto.Hash import SHAKE128
from Crypto.SelfTest.loader import load_test_vectors_wycheproof
def get_tag_random(tag, length): def get_tag_random(tag, length):
return SHAKE128.new(data=tobytes(tag)).read(length) return SHAKE128.new(data=tobytes(tag)).read(length)

View file

@ -33,11 +33,12 @@ import unittest
from binascii import unhexlify from binascii import unhexlify
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.SelfTest.loader import load_test_vectors_wycheproof
from Crypto.Util.py3compat import tobytes, bchr from Crypto.Util.py3compat import tobytes, bchr
from Crypto.Cipher import AES from Crypto.Cipher import AES
from Crypto.Hash import SHAKE128 from Crypto.Hash import SHAKE128
from Crypto.Util._file_system import pycryptodome_filename
from Crypto.Util.strxor import strxor from Crypto.Util.strxor import strxor
@ -150,7 +151,7 @@ class SivTests(unittest.TestCase):
cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96) cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96)
cipher.hexverify(mac_hex) cipher.hexverify(mac_hex)
def test_bytearray(self): def test_bytearray(self):
# Encrypt # Encrypt
@ -158,7 +159,7 @@ class SivTests(unittest.TestCase):
nonce = bytearray(self.nonce_96) nonce = bytearray(self.nonce_96)
data = bytearray(self.data_128) data = bytearray(self.data_128)
header = bytearray(self.data_128) header = bytearray(self.data_128)
cipher1 = AES.new(self.key_256, cipher1 = AES.new(self.key_256,
AES.MODE_SIV, AES.MODE_SIV,
nonce=self.nonce_96) nonce=self.nonce_96)
@ -184,7 +185,7 @@ class SivTests(unittest.TestCase):
header = bytearray(self.data_128) header = bytearray(self.data_128)
ct_ba = bytearray(ct) ct_ba = bytearray(ct)
tag_ba = bytearray(tag) tag_ba = bytearray(tag)
cipher3 = AES.new(key, cipher3 = AES.new(key,
AES.MODE_SIV, AES.MODE_SIV,
nonce=nonce) nonce=nonce)
@ -195,7 +196,7 @@ class SivTests(unittest.TestCase):
pt_test = cipher3.decrypt_and_verify(ct_ba, tag_ba) pt_test = cipher3.decrypt_and_verify(ct_ba, tag_ba)
self.assertEqual(self.data_128, pt_test) self.assertEqual(self.data_128, pt_test)
def test_memoryview(self): def test_memoryview(self):
# Encrypt # Encrypt
@ -203,7 +204,7 @@ class SivTests(unittest.TestCase):
nonce = memoryview(bytearray(self.nonce_96)) nonce = memoryview(bytearray(self.nonce_96))
data = memoryview(bytearray(self.data_128)) data = memoryview(bytearray(self.data_128))
header = memoryview(bytearray(self.data_128)) header = memoryview(bytearray(self.data_128))
cipher1 = AES.new(self.key_256, cipher1 = AES.new(self.key_256,
AES.MODE_SIV, AES.MODE_SIV,
nonce=self.nonce_96) nonce=self.nonce_96)
@ -229,7 +230,7 @@ class SivTests(unittest.TestCase):
header = memoryview(bytearray(self.data_128)) header = memoryview(bytearray(self.data_128))
ct_ba = memoryview(bytearray(ct)) ct_ba = memoryview(bytearray(ct))
tag_ba = memoryview(bytearray(tag)) tag_ba = memoryview(bytearray(tag))
cipher3 = AES.new(key, cipher3 = AES.new(key,
AES.MODE_SIV, AES.MODE_SIV,
nonce=nonce) nonce=nonce)
@ -240,7 +241,7 @@ class SivTests(unittest.TestCase):
pt_test = cipher3.decrypt_and_verify(ct_ba, tag_ba) pt_test = cipher3.decrypt_and_verify(ct_ba, tag_ba)
self.assertEqual(self.data_128, pt_test) self.assertEqual(self.data_128, pt_test)
def test_output_param(self): def test_output_param(self):
pt = b'5' * 16 pt = b'5' * 16
@ -253,14 +254,14 @@ class SivTests(unittest.TestCase):
self.assertEqual(ct, output) self.assertEqual(ct, output)
self.assertEqual(res, None) self.assertEqual(res, None)
self.assertEqual(tag, tag_out) self.assertEqual(tag, tag_out)
cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96) cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96)
res = cipher.decrypt_and_verify(ct, tag, output=output) res = cipher.decrypt_and_verify(ct, tag, output=output)
self.assertEqual(pt, output) self.assertEqual(pt, output)
self.assertEqual(res, None) self.assertEqual(res, None)
def test_output_param_memoryview(self): def test_output_param_memoryview(self):
pt = b'5' * 16 pt = b'5' * 16
cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96) cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96)
ct, tag = cipher.encrypt_and_digest(pt) ct, tag = cipher.encrypt_and_digest(pt)
@ -269,7 +270,7 @@ class SivTests(unittest.TestCase):
cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96) cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96)
cipher.encrypt_and_digest(pt, output=output) cipher.encrypt_and_digest(pt, output=output)
self.assertEqual(ct, output) self.assertEqual(ct, output)
cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96) cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96)
cipher.decrypt_and_verify(ct, tag, output=output) cipher.decrypt_and_verify(ct, tag, output=output)
self.assertEqual(pt, output) self.assertEqual(pt, output)
@ -282,7 +283,7 @@ class SivTests(unittest.TestCase):
cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96) cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96)
self.assertRaises(TypeError, cipher.encrypt_and_digest, pt, output=b'0'*16) self.assertRaises(TypeError, cipher.encrypt_and_digest, pt, output=b'0'*16)
cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96) cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96)
self.assertRaises(TypeError, cipher.decrypt_and_verify, ct, tag, output=b'0'*16) self.assertRaises(TypeError, cipher.decrypt_and_verify, ct, tag, output=b'0'*16)
@ -298,7 +299,7 @@ class SivFSMTests(unittest.TestCase):
key_256 = get_tag_random("key_256", 32) key_256 = get_tag_random("key_256", 32)
nonce_96 = get_tag_random("nonce_96", 12) nonce_96 = get_tag_random("nonce_96", 12)
data_128 = get_tag_random("data_128", 16) data_128 = get_tag_random("data_128", 16)
def test_invalid_init_encrypt(self): def test_invalid_init_encrypt(self):
# Path INIT->ENCRYPT fails # Path INIT->ENCRYPT fails
cipher = AES.new(self.key_256, AES.MODE_SIV, cipher = AES.new(self.key_256, AES.MODE_SIV,
@ -453,23 +454,9 @@ class TestVectorsWycheproof(unittest.TestCase):
self._id = "None" self._id = "None"
def setUp(self): def setUp(self):
comps = "Crypto.SelfTest.Cipher.test_vectors.wycheproof".split(".") self.tv = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
with open(pycryptodome_filename(comps, "aes_siv_cmac_test.json"), "rt") as file_in: "aes_siv_cmac_test.json",
tv_tree = json.load(file_in) "Wycheproof AES SIV")
class TestVector(object):
pass
self.tv = []
for group in tv_tree['testGroups']:
for test in group['tests']:
tv = TestVector()
tv.id = test['tcId']
for attr in 'key', 'aad', 'msg', 'ct':
setattr(tv, attr, unhexlify(test[attr]))
tv.valid = test['result'] != "invalid"
self.tv.append(tv)
def shortDescription(self): def shortDescription(self):
return self._id return self._id
@ -510,23 +497,9 @@ class TestVectorsWycheproof2(unittest.TestCase):
self._id = "None" self._id = "None"
def setUp(self): def setUp(self):
comps = "Crypto.SelfTest.Cipher.test_vectors.wycheproof".split(".") self.tv = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
with open(pycryptodome_filename(comps, "aead_aes_siv_cmac_test.json"), "rt") as file_in: "aead_aes_siv_cmac_test.json",
tv_tree = json.load(file_in) "Wycheproof AEAD SIV")
class TestVector(object):
pass
self.tv = []
for group in tv_tree['testGroups']:
for test in group['tests']:
tv = TestVector()
tv.id = test['tcId']
for attr in 'key', 'iv', 'aad', 'msg', 'ct', 'tag':
setattr(tv, attr, unhexlify(test[attr]))
tv.valid = test['result'] != "invalid"
self.tv.append(tv)
def shortDescription(self): def shortDescription(self):
return self._id return self._id

View file

@ -32,7 +32,8 @@ from Crypto import Random
from Crypto.Cipher import PKCS1_v1_5 as PKCS from Crypto.Cipher import PKCS1_v1_5 as PKCS
from Crypto.Util.py3compat import b from Crypto.Util.py3compat import b
from Crypto.Util.number import bytes_to_long, long_to_bytes from Crypto.Util.number import bytes_to_long, long_to_bytes
from Crypto.Util._file_system import pycryptodome_filename from Crypto.SelfTest.loader import load_test_vectors_wycheproof
def rws(t): def rws(t):
"""Remove white spaces, tabs, and new lines from a string""" """Remove white spaces, tabs, and new lines from a string"""
@ -187,31 +188,15 @@ class TestVectorsWycheproof(unittest.TestCase):
self._id = "None" self._id = "None"
def load_tests(self, filename): def load_tests(self, filename):
comps = "Crypto.SelfTest.Cipher.test_vectors.wycheproof".split(".")
with open(pycryptodome_filename(comps, filename), "rt") as file_in:
tv_tree = json.load(file_in)
class TestVector(object): def filter_rsa(group):
pass return RSA.import_key(group['privateKeyPem'])
result = []
for group in tv_tree['testGroups']: result = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
filename,
rsa_key = RSA.import_key(group['privateKeyPem']) "Wycheproof PKCS#1v1.5 (%s)" % filename,
group_tag={'rsa_key': filter_rsa}
for test in group['tests']: )
tv = TestVector()
tv.rsa_key = rsa_key
tv.id = test['tcId']
tv.comment = test['comment']
for attr in 'msg', 'ct':
setattr(tv, attr, unhexlify(test[attr]))
tv.valid = test['result'] != "invalid"
tv.warning = test['result'] == "acceptable"
result.append(tv)
return result return result
def setUp(self): def setUp(self):

View file

@ -20,11 +20,10 @@
# SOFTWARE. # SOFTWARE.
# =================================================================== # ===================================================================
import json
import unittest import unittest
from binascii import unhexlify
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex from Crypto.SelfTest.st_common import list_test_cases, a2b_hex
from Crypto.SelfTest.loader import load_test_vectors_wycheproof
from Crypto.PublicKey import RSA from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP as PKCS from Crypto.Cipher import PKCS1_OAEP as PKCS
@ -33,21 +32,23 @@ from Crypto import Random
from Crypto.Signature.pss import MGF1 from Crypto.Signature.pss import MGF1
from Crypto.Util.py3compat import b, bchr from Crypto.Util.py3compat import b, bchr
from Crypto.Util._file_system import pycryptodome_filename
def rws(t): def rws(t):
"""Remove white spaces, tabs, and new lines from a string""" """Remove white spaces, tabs, and new lines from a string"""
for c in ['\n', '\t', ' ']: for c in ['\n', '\t', ' ']:
t = t.replace(c,'') t = t.replace(c, '')
return t return t
def t2b(t): def t2b(t):
"""Convert a text string with bytes in hex form to a byte string""" """Convert a text string with bytes in hex form to a byte string"""
clean = rws(t) clean = rws(t)
if len(clean)%2 == 1: if len(clean) % 2 == 1:
raise ValueError("Even number of characters expected") raise ValueError("Even number of characters expected")
return a2b_hex(clean) return a2b_hex(clean)
class PKCS1_OAEP_Tests(unittest.TestCase): class PKCS1_OAEP_Tests(unittest.TestCase):
def setUp(self): def setUp(self):
@ -267,98 +268,106 @@ class PKCS1_OAEP_Tests(unittest.TestCase):
) )
def testEncrypt1(self): def testEncrypt1(self):
# Verify encryption using all test vectors # Verify encryption using all test vectors
for test in self._testData: for test in self._testData:
# Build the key # Build the key
comps = [ int(rws(test[0][x]),16) for x in ('n','e') ] comps = [int(rws(test[0][x]), 16) for x in ('n', 'e')]
key = RSA.construct(comps) key = RSA.construct(comps)
# RNG that takes its random numbers from a pool given
# at initialization # RNG that takes its random numbers from a pool given
class randGen: # at initialization
def __init__(self, data): class randGen:
self.data = data
self.idx = 0 def __init__(self, data):
def __call__(self, N): self.data = data
r = self.data[self.idx:N] self.idx = 0
self.idx += N
return r def __call__(self, N):
# The real test r = self.data[self.idx:N]
cipher = PKCS.new(key, test[4], randfunc=randGen(t2b(test[3]))) self.idx += N
ct = cipher.encrypt(t2b(test[1])) return r
self.assertEqual(ct, t2b(test[2]))
# The real test
cipher = PKCS.new(key, test[4], randfunc=randGen(t2b(test[3])))
ct = cipher.encrypt(t2b(test[1]))
self.assertEqual(ct, t2b(test[2]))
def testEncrypt2(self): def testEncrypt2(self):
# Verify that encryption fails if plaintext is too long # Verify that encryption fails if plaintext is too long
pt = '\x00'*(128-2*20-2+1) pt = '\x00'*(128-2*20-2+1)
cipher = PKCS.new(self.key1024) cipher = PKCS.new(self.key1024)
self.assertRaises(ValueError, cipher.encrypt, pt) self.assertRaises(ValueError, cipher.encrypt, pt)
def testDecrypt1(self): def testDecrypt1(self):
# Verify decryption using all test vectors # Verify decryption using all test vectors
for test in self._testData: for test in self._testData:
# Build the key # Build the key
comps = [ int(rws(test[0][x]),16) for x in ('n','e','d') ] comps = [int(rws(test[0][x]),16) for x in ('n', 'e', 'd')]
key = RSA.construct(comps) key = RSA.construct(comps)
# The real test # The real test
cipher = PKCS.new(key, test[4]) cipher = PKCS.new(key, test[4])
pt = cipher.decrypt(t2b(test[2])) pt = cipher.decrypt(t2b(test[2]))
self.assertEqual(pt, t2b(test[1])) self.assertEqual(pt, t2b(test[1]))
def testDecrypt2(self): def testDecrypt2(self):
# Simplest possible negative tests # Simplest possible negative tests
for ct_size in (127,128,129): for ct_size in (127, 128, 129):
cipher = PKCS.new(self.key1024) cipher = PKCS.new(self.key1024)
self.assertRaises(ValueError, cipher.decrypt, bchr(0x00)*ct_size) self.assertRaises(ValueError, cipher.decrypt, bchr(0x00)*ct_size)
def testEncryptDecrypt1(self): def testEncryptDecrypt1(self):
# Encrypt/Decrypt messages of length [0..128-2*20-2] # Encrypt/Decrypt messages of length [0..128-2*20-2]
for pt_len in range(0,128-2*20-2): for pt_len in range(0, 128-2*20-2):
pt = self.rng(pt_len) pt = self.rng(pt_len)
cipher = PKCS.new(self.key1024) cipher = PKCS.new(self.key1024)
ct = cipher.encrypt(pt) ct = cipher.encrypt(pt)
pt2 = cipher.decrypt(ct) pt2 = cipher.decrypt(ct)
self.assertEqual(pt,pt2) self.assertEqual(pt, pt2)
def testEncryptDecrypt2(self): def testEncryptDecrypt2(self):
# Helper function to monitor what's requested from RNG # Helper function to monitor what's requested from RNG
global asked
def localRng(N):
global asked global asked
def localRng(N): asked += N
global asked return self.rng(N)
asked += N
return self.rng(N) # Verify that OAEP is friendly to all hashes
# Verify that OAEP is friendly to all hashes for hashmod in (MD2, MD5, SHA1, SHA256, RIPEMD160):
for hashmod in (MD2,MD5,SHA1,SHA256,RIPEMD160): # Verify that encrypt() asks for as many random bytes
# Verify that encrypt() asks for as many random bytes # as the hash output size
# as the hash output size asked = 0
asked = 0 pt = self.rng(40)
pt = self.rng(40) cipher = PKCS.new(self.key1024, hashmod, randfunc=localRng)
cipher = PKCS.new(self.key1024, hashmod, randfunc=localRng) ct = cipher.encrypt(pt)
ct = cipher.encrypt(pt) self.assertEqual(cipher.decrypt(ct), pt)
self.assertEqual(cipher.decrypt(ct), pt) self.assertEqual(asked, hashmod.digest_size)
self.assertEqual(asked, hashmod.digest_size)
def testEncryptDecrypt3(self): def testEncryptDecrypt3(self):
# Verify that OAEP supports labels # Verify that OAEP supports labels
pt = self.rng(35) pt = self.rng(35)
xlabel = self.rng(22) xlabel = self.rng(22)
cipher = PKCS.new(self.key1024, label=xlabel) cipher = PKCS.new(self.key1024, label=xlabel)
ct = cipher.encrypt(pt) ct = cipher.encrypt(pt)
self.assertEqual(cipher.decrypt(ct), pt) self.assertEqual(cipher.decrypt(ct), pt)
def testEncryptDecrypt4(self): def testEncryptDecrypt4(self):
# Verify that encrypt() uses the custom MGF # Verify that encrypt() uses the custom MGF
global mgfcalls
# Helper function to monitor what's requested from MGF
def newMGF(seed, maskLen):
global mgfcalls global mgfcalls
# Helper function to monitor what's requested from MGF mgfcalls += 1
def newMGF(seed,maskLen): return b'\x00' * maskLen
global mgfcalls
mgfcalls += 1 mgfcalls = 0
return bchr(0x00)*maskLen pt = self.rng(32)
mgfcalls = 0 cipher = PKCS.new(self.key1024, mgfunc=newMGF)
pt = self.rng(32) ct = cipher.encrypt(pt)
cipher = PKCS.new(self.key1024, mgfunc=newMGF) self.assertEqual(mgfcalls, 2)
ct = cipher.encrypt(pt) self.assertEqual(cipher.decrypt(ct), pt)
self.assertEqual(mgfcalls, 2)
self.assertEqual(cipher.decrypt(ct), pt)
def testByteArray(self): def testByteArray(self):
pt = b("XER") pt = b("XER")
@ -384,59 +393,49 @@ class TestVectorsWycheproof(unittest.TestCase):
self._id = "None" self._id = "None"
def load_tests(self, filename): def load_tests(self, filename):
comps = "Crypto.SelfTest.Cipher.test_vectors.wycheproof".split(".")
with open(pycryptodome_filename(comps, filename), "rt") as file_in:
tv_tree = json.load(file_in)
class TestVector(object): def filter_rsa(group):
pass return RSA.import_key(group['privateKeyPem'])
result = []
for group in tv_tree['testGroups']: def filter_sha(group):
rsa_key = RSA.import_key(group['privateKeyPem'])
if group['sha'] == "SHA-1": if group['sha'] == "SHA-1":
hash_mod = SHA1 return SHA1
elif group['sha'] == "SHA-224": elif group['sha'] == "SHA-224":
hash_mod = SHA224 return SHA224
elif group['sha'] == "SHA-256": elif group['sha'] == "SHA-256":
hash_mod = SHA256 return SHA256
elif group['sha'] == "SHA-384": elif group['sha'] == "SHA-384":
hash_mod = SHA384 return SHA384
elif group['sha'] == "SHA-512": elif group['sha'] == "SHA-512":
hash_mod = SHA512 return SHA512
else: else:
raise ValueError("Unknown sha " + group['sha']) raise ValueError("Unknown sha " + group['sha'])
def filter_mgf(group):
if group['mgfSha'] == "SHA-1": if group['mgfSha'] == "SHA-1":
mgf = lambda x,y: MGF1(x, y, SHA1) return lambda x, y: MGF1(x, y, SHA1)
elif group['mgfSha'] == "SHA-224": elif group['mgfSha'] == "SHA-224":
mgf = lambda x,y: MGF1(x, y, SHA224) return lambda x, y: MGF1(x, y, SHA224)
elif group['mgfSha'] == "SHA-256": elif group['mgfSha'] == "SHA-256":
mgf = lambda x,y: MGF1(x, y, SHA256) return lambda x, y: MGF1(x, y, SHA256)
elif group['mgfSha'] == "SHA-384": elif group['mgfSha'] == "SHA-384":
mgf = lambda x,y: MGF1(x, y, SHA384) return lambda x, y: MGF1(x, y, SHA384)
elif group['mgfSha'] == "SHA-512": elif group['mgfSha'] == "SHA-512":
mgf = lambda x,y: MGF1(x, y, SHA512) return lambda x, y: MGF1(x, y, SHA512)
else: else:
raise ValueError("Unknown mgf/sha " + group['mgfSha']) raise ValueError("Unknown mgf/sha " + group['mgfSha'])
for test in group['tests']:
tv = TestVector()
tv.rsa_key = rsa_key def filter_algo(group):
tv.hash_mod = hash_mod return "%s with MGF1/%s" % (group['sha'], group['mgfSha'])
tv.mgf = mgf
tv.algo = "%s with MGF1/%s" % (group['sha'], group['mgfSha'])
tv.id = test['tcId'] result = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
tv.comment = test['comment'] filename,
for attr in 'msg', 'ct', 'label': "Wycheproof PKCS#1 OAEP (%s)" % filename,
setattr(tv, attr, unhexlify(test[attr])) group_tag={'rsa_key': filter_rsa,
tv.valid = test['result'] != "invalid" 'hash_mod': filter_sha,
tv.warning = test['result'] == "acceptable" 'mgf': filter_mgf,
'algo': filter_algo}
result.append(tv) )
return result return result
def setUp(self): def setUp(self):
@ -462,7 +461,6 @@ class TestVectorsWycheproof(unittest.TestCase):
self.tv.extend(self.load_tests("rsa_oaep_4096_sha512_mgf1sha512_test.json")) self.tv.extend(self.load_tests("rsa_oaep_4096_sha512_mgf1sha512_test.json"))
self.tv.extend(self.load_tests("rsa_oaep_misc_test.json")) self.tv.extend(self.load_tests("rsa_oaep_misc_test.json"))
def shortDescription(self): def shortDescription(self):
return self._id return self._id
@ -499,8 +497,10 @@ def get_tests(config={}):
tests += [TestVectorsWycheproof(wycheproof_warnings, skip_slow_tests)] tests += [TestVectorsWycheproof(wycheproof_warnings, skip_slow_tests)]
return tests return tests
if __name__ == '__main__': if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests()) def suite():
unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite') unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab: # vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -263,7 +263,7 @@ def make_hash_tests(module, module_name, test_data, digest_size, oid=None,
name = "%s #%d: %s" % (module_name, i+1, description) name = "%s #%d: %s" % (module_name, i+1, description)
tests.append(HashSelfTest(module, name, expected, input, extra_params)) tests.append(HashSelfTest(module, name, expected, input, extra_params))
name = "%s #%d: digest_size" % (module_name, i+1) name = "%s #%d: digest_size" % (module_name, len(test_data) + 1)
tests.append(HashDigestSizeSelfTest(module, name, digest_size, extra_params)) tests.append(HashDigestSizeSelfTest(module, name, digest_size, extra_params))
if oid is not None: if oid is not None:

View file

@ -28,13 +28,14 @@
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
# =================================================================== # ===================================================================
import os
import re import re
import unittest import unittest
import warnings
from binascii import unhexlify, hexlify from binascii import unhexlify, hexlify
from Crypto.Util.py3compat import tobytes from Crypto.Util.py3compat import tobytes
from Crypto.Util.strxor import strxor_c from Crypto.Util.strxor import strxor_c
from Crypto.Util._file_system import pycryptodome_filename
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.Hash import BLAKE2b, BLAKE2s from Crypto.Hash import BLAKE2b, BLAKE2s
@ -112,7 +113,7 @@ class Blake2Test(unittest.TestCase):
self.failUnless(isinstance(digest, type(b"digest"))) self.failUnless(isinstance(digest, type(b"digest")))
def test_update_after_digest(self): def test_update_after_digest(self):
msg=b"rrrrttt" msg = b"rrrrttt"
# Normally, update() cannot be done after digest() # Normally, update() cannot be done after digest()
h = self.BLAKE2.new(digest_bits=256, data=msg[:4]) h = self.BLAKE2.new(digest_bits=256, data=msg[:4])
@ -262,14 +263,9 @@ class Blake2sTest(Blake2Test):
class Blake2OfficialTestVector(unittest.TestCase): class Blake2OfficialTestVector(unittest.TestCase):
def setUp(self): def _load_tests(self, test_vector_file):
test_vector_file = pycryptodome_filename(
("Crypto", "SelfTest", "Hash", "test_vectors", self.name),
self.name.lower() + "-test.txt")
expected = "in" expected = "in"
self.test_vectors = [] test_vectors = []
with open(test_vector_file, "rt") as test_vector_fd: with open(test_vector_file, "rt") as test_vector_fd:
for line_number, line in enumerate(test_vector_fd): for line_number, line in enumerate(test_vector_fd):
@ -294,7 +290,26 @@ class Blake2OfficialTestVector(unittest.TestCase):
else: else:
result = bin_value result = bin_value
expected = "in" expected = "in"
self.test_vectors.append((input_data, key, result)) test_vectors.append((input_data, key, result))
return test_vectors
def setUp(self):
dir_comps = ("Hash", self.name)
file_name = self.name.lower() + "-test.txt"
self.description = "%s tests" % self.name
try:
import pycryptodome_test_vectors # type: ignore
except ImportError:
warnings.warn("Warning: skipping extended tests for %s" % self.name,
UserWarning)
self.test_vectors = []
return
init_dir = os.path.dirname(pycryptodome_test_vectors.__file__)
full_file_name = os.path.join(init_dir, *dir_comps, file_name)
self.test_vectors = self._load_tests(full_file_name)
def runTest(self): def runTest(self):
for (input_data, key, result) in self.test_vectors: for (input_data, key, result) in self.test_vectors:
@ -323,12 +338,8 @@ class Blake2sOfficialTestVector(Blake2OfficialTestVector):
class Blake2TestVector1(unittest.TestCase): class Blake2TestVector1(unittest.TestCase):
def setUp(self): def _load_tests(self, test_vector_file):
test_vector_file = pycryptodome_filename( test_vectors = []
("Crypto", "SelfTest", "Hash", "test_vectors", self.name),
"tv1.txt")
self.test_vectors = []
with open(test_vector_file, "rt") as test_vector_fd: with open(test_vector_file, "rt") as test_vector_fd:
for line_number, line in enumerate(test_vector_fd): for line_number, line in enumerate(test_vector_fd):
if line.strip() == "" or line.startswith("#"): if line.strip() == "" or line.startswith("#"):
@ -338,7 +349,25 @@ class Blake2TestVector1(unittest.TestCase):
raise ValueError("Incorrect test vector format (line %d)" raise ValueError("Incorrect test vector format (line %d)"
% line_number) % line_number)
self.test_vectors.append(unhexlify(tobytes(res.group(1)))) test_vectors.append(unhexlify(tobytes(res.group(1))))
return test_vectors
def setUp(self):
dir_comps = ("Hash", self.name)
file_name = "tv1.txt"
self.description = "%s tests" % self.name
try:
import pycryptodome_test_vectors
except ImportError:
warnings.warn("Warning: skipping extended tests for %s" % self.name,
UserWarning)
self.test_vectors = []
return
init_dir = os.path.dirname(pycryptodome_test_vectors.__file__)
full_file_name = os.path.join(init_dir, *dir_comps, file_name)
self.test_vectors = self._load_tests(full_file_name)
def runTest(self): def runTest(self):
@ -368,12 +397,8 @@ class Blake2sTestVector1(Blake2TestVector1):
class Blake2TestVector2(unittest.TestCase): class Blake2TestVector2(unittest.TestCase):
def setUp(self): def _load_tests(self, test_vector_file):
test_vector_file = pycryptodome_filename( test_vectors = []
("Crypto", "SelfTest", "Hash", "test_vectors", self.name),
"tv2.txt")
self.test_vectors = []
with open(test_vector_file, "rt") as test_vector_fd: with open(test_vector_file, "rt") as test_vector_fd:
for line_number, line in enumerate(test_vector_fd): for line_number, line in enumerate(test_vector_fd):
if line.strip() == "" or line.startswith("#"): if line.strip() == "" or line.startswith("#"):
@ -382,10 +407,27 @@ class Blake2TestVector2(unittest.TestCase):
if not res: if not res:
raise ValueError("Incorrect test vector format (line %d)" raise ValueError("Incorrect test vector format (line %d)"
% line_number) % line_number)
key_size = int(res.group(1)) key_size = int(res.group(1))
result = unhexlify(tobytes(res.group(2))) result = unhexlify(tobytes(res.group(2)))
self.test_vectors.append((key_size, result)) test_vectors.append((key_size, result))
return test_vectors
def setUp(self):
dir_comps = ("Hash", self.name)
file_name = "tv2.txt"
self.description = "%s tests" % self.name
try:
import pycryptodome_test_vectors # type: ignore
except ImportError:
warnings.warn("Warning: skipping extended tests for %s" % self.name,
UserWarning)
self.test_vectors = []
return
init_dir = os.path.dirname(pycryptodome_test_vectors.__file__)
full_file_name = os.path.join(init_dir, *dir_comps, file_name)
self.test_vectors = self._load_tests(full_file_name)
def runTest(self): def runTest(self):
@ -435,5 +477,6 @@ def get_tests(config={}):
if __name__ == '__main__': if __name__ == '__main__':
import unittest import unittest
suite = lambda: unittest.TestSuite(get_tests()) def suite():
return unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite') unittest.main(defaultTest='suite')

View file

@ -43,10 +43,10 @@ from Crypto.Hash import CMAC
from Crypto.Cipher import AES, DES3 from Crypto.Cipher import AES, DES3
from Crypto.Hash import SHAKE128 from Crypto.Hash import SHAKE128
from Crypto.Util._file_system import pycryptodome_filename
from Crypto.Util.strxor import strxor from Crypto.Util.strxor import strxor
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.SelfTest.loader import load_test_vectors_wycheproof
# This is a list of (key, data, result, description, module) tuples. # This is a list of (key, data, result, description, module) tuples.
test_data = [ test_data = [
@ -366,27 +366,14 @@ class TestVectorsWycheproof(unittest.TestCase):
self._id = "None" self._id = "None"
def setUp(self): def setUp(self):
comps = "Crypto.SelfTest.Hash.test_vectors.wycheproof".split(".")
with open(pycryptodome_filename(comps, "aes_cmac_test.json"), "rt") as file_in:
tv_tree = json.load(file_in)
class TestVector(object): def filter_tag(group):
pass return group['tagSize'] // 8
self.tv = []
for group in tv_tree['testGroups']: self.tv = load_test_vectors_wycheproof(("Hash", "wycheproof"),
tag_size = group['tagSize'] // 8 "aes_cmac_test.json",
for test in group['tests']: "Wycheproof CMAC",
tv = TestVector() group_tag={'tag_size': filter_tag})
tv.tag_size = tag_size
tv.id = test['tcId']
tv.comment = test['comment']
for attr in 'key', 'msg', 'tag':
setattr(tv, attr, unhexlify(test[attr]))
tv.valid = test['result'] != "invalid"
tv.warning = test['result'] == "acceptable"
self.tv.append(tv)
def shortDescription(self): def shortDescription(self):
return self._id return self._id
@ -398,7 +385,7 @@ class TestVectorsWycheproof(unittest.TestCase):
def test_create_mac(self, tv): def test_create_mac(self, tv):
self._id = "Wycheproof MAC creation Test #" + str(tv.id) self._id = "Wycheproof MAC creation Test #" + str(tv.id)
try: try:
tag = CMAC.new(tv.key, tv.msg, ciphermod=AES, mac_len=tv.tag_size).digest() tag = CMAC.new(tv.key, tv.msg, ciphermod=AES, mac_len=tv.tag_size).digest()
except ValueError as e: except ValueError as e:
@ -411,7 +398,7 @@ class TestVectorsWycheproof(unittest.TestCase):
def test_verify_mac(self, tv): def test_verify_mac(self, tv):
self._id = "Wycheproof MAC verification Test #" + str(tv.id) self._id = "Wycheproof MAC verification Test #" + str(tv.id)
try: try:
mac = CMAC.new(tv.key, tv.msg, ciphermod=AES, mac_len=tv.tag_size) mac = CMAC.new(tv.key, tv.msg, ciphermod=AES, mac_len=tv.tag_size)
except ValueError as e: except ValueError as e:
@ -437,7 +424,7 @@ def get_tests(config={}):
global test_data global test_data
import types import types
from .common import make_mac_tests from .common import make_mac_tests
wycheproof_warnings = config.get('wycheproof_warnings') wycheproof_warnings = config.get('wycheproof_warnings')
# Add new() parameters to the back of each test vector # Add new() parameters to the back of each test vector

View file

@ -26,7 +26,7 @@
from binascii import hexlify from binascii import hexlify
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors
# Test vectors from various sources # Test vectors from various sources
# This is a list of (expected_result, input[, description]) tuples. # This is a list of (expected_result, input[, description]) tuples.
@ -55,10 +55,10 @@ def get_tests(config={}):
tests = [] tests = []
test_vectors = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA1"), test_vectors = load_test_vectors(("Hash", "SHA1"),
"SHA1ShortMsg.rsp", "SHA1ShortMsg.rsp",
"KAT SHA-1", "KAT SHA-1",
{ "len" : lambda x: int(x) } ) { "len" : lambda x: int(x) } ) or []
test_data = test_data_various[:] test_data = test_data_various[:]
for tv in test_vectors: for tv in test_vectors:

View file

@ -25,7 +25,7 @@
import unittest import unittest
from binascii import hexlify from binascii import hexlify
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.Hash import SHA3_224 as SHA3 from Crypto.Hash import SHA3_224 as SHA3
from Crypto.Util.py3compat import b from Crypto.Util.py3compat import b
@ -56,10 +56,10 @@ def get_tests(config={}):
tests = [] tests = []
test_vectors = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA3"), test_vectors = load_test_vectors(("Hash", "SHA3"),
"ShortMsgKAT_SHA3-224.txt", "ShortMsgKAT_SHA3-224.txt",
"KAT SHA-3 224", "KAT SHA-3 224",
{ "len" : lambda x: int(x) } ) { "len" : lambda x: int(x) } ) or []
test_data = [] test_data = []
for tv in test_vectors: for tv in test_vectors:

View file

@ -25,7 +25,7 @@
import unittest import unittest
from binascii import hexlify from binascii import hexlify
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.Hash import SHA3_256 as SHA3 from Crypto.Hash import SHA3_256 as SHA3
from Crypto.Util.py3compat import b from Crypto.Util.py3compat import b
@ -56,10 +56,10 @@ def get_tests(config={}):
tests = [] tests = []
test_vectors = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA3"), test_vectors = load_test_vectors(("Hash", "SHA3"),
"ShortMsgKAT_SHA3-256.txt", "ShortMsgKAT_SHA3-256.txt",
"KAT SHA-3 256", "KAT SHA-3 256",
{ "len" : lambda x: int(x) } ) { "len" : lambda x: int(x) } ) or []
test_data = [] test_data = []
for tv in test_vectors: for tv in test_vectors:

View file

@ -25,7 +25,7 @@
import unittest import unittest
from binascii import hexlify from binascii import hexlify
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.Hash import SHA3_384 as SHA3 from Crypto.Hash import SHA3_384 as SHA3
from Crypto.Util.py3compat import b from Crypto.Util.py3compat import b
@ -56,10 +56,10 @@ def get_tests(config={}):
tests = [] tests = []
test_vectors = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA3"), test_vectors = load_test_vectors(("Hash", "SHA3"),
"ShortMsgKAT_SHA3-384.txt", "ShortMsgKAT_SHA3-384.txt",
"KAT SHA-3 384", "KAT SHA-3 384",
{ "len" : lambda x: int(x) } ) { "len" : lambda x: int(x) } ) or []
test_data = [] test_data = []
for tv in test_vectors: for tv in test_vectors:

View file

@ -25,7 +25,7 @@
import unittest import unittest
from binascii import hexlify from binascii import hexlify
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.Hash import SHA3_512 as SHA3 from Crypto.Hash import SHA3_512 as SHA3
from Crypto.Util.py3compat import b from Crypto.Util.py3compat import b
@ -56,10 +56,10 @@ def get_tests(config={}):
tests = [] tests = []
test_vectors = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA3"), test_vectors = load_test_vectors(("Hash", "SHA3"),
"ShortMsgKAT_SHA3-512.txt", "ShortMsgKAT_SHA3-512.txt",
"KAT SHA-3 512", "KAT SHA-3 512",
{ "len" : lambda x: int(x) } ) { "len" : lambda x: int(x) } ) or []
test_data = [] test_data = []
for tv in test_vectors: for tv in test_vectors:

View file

@ -28,7 +28,7 @@ from binascii import hexlify
from Crypto.Hash import SHA512 from Crypto.Hash import SHA512
from .common import make_hash_tests from .common import make_hash_tests
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors
# Test vectors from various sources # Test vectors from various sources
# This is a list of (expected_result, input[, description]) tuples. # This is a list of (expected_result, input[, description]) tuples.
@ -52,10 +52,10 @@ test_data_512_other = [
def get_tests_SHA512(): def get_tests_SHA512():
test_vectors = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA2"), test_vectors = load_test_vectors(("Hash", "SHA2"),
"SHA512ShortMsg.rsp", "SHA512ShortMsg.rsp",
"KAT SHA-512", "KAT SHA-512",
{ "len" : lambda x: int(x) } ) {"len": lambda x: int(x)}) or []
test_data = test_data_512_other[:] test_data = test_data_512_other[:]
for tv in test_vectors: for tv in test_vectors:
@ -76,10 +76,10 @@ def get_tests_SHA512():
def get_tests_SHA512_224(): def get_tests_SHA512_224():
test_vectors = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA2"), test_vectors = load_test_vectors(("Hash", "SHA2"),
"SHA512_224ShortMsg.rsp", "SHA512_224ShortMsg.rsp",
"KAT SHA-512/224", "KAT SHA-512/224",
{ "len" : lambda x: int(x) } ) {"len": lambda x: int(x)}) or []
test_data = [] test_data = []
for tv in test_vectors: for tv in test_vectors:
@ -101,10 +101,10 @@ def get_tests_SHA512_224():
def get_tests_SHA512_256(): def get_tests_SHA512_256():
test_vectors = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA2"), test_vectors = load_test_vectors(("Hash", "SHA2"),
"SHA512_256ShortMsg.rsp", "SHA512_256ShortMsg.rsp",
"KAT SHA-512/256", "KAT SHA-512/256",
{ "len" : lambda x: int(x) } ) {"len": lambda x: int(x)}) or []
test_data = [] test_data = []
for tv in test_vectors: for tv in test_vectors:

View file

@ -33,7 +33,7 @@
import unittest import unittest
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.Hash import SHAKE128, SHAKE256 from Crypto.Hash import SHAKE128, SHAKE256
@ -91,10 +91,10 @@ class SHAKEVectors(unittest.TestCase):
pass pass
test_vectors_128 = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA3"), test_vectors_128 = load_test_vectors(("Hash", "SHA3"),
"ShortMsgKAT_SHAKE128.txt", "ShortMsgKAT_SHAKE128.txt",
"Short Messages KAT SHAKE128", "Short Messages KAT SHAKE128",
{ "len" : lambda x: int(x) } ) { "len" : lambda x: int(x) } ) or []
for idx, tv in enumerate(test_vectors_128): for idx, tv in enumerate(test_vectors_128):
if tv.len == 0: if tv.len == 0:
@ -110,10 +110,10 @@ for idx, tv in enumerate(test_vectors_128):
setattr(SHAKEVectors, "test_128_%d" % idx, new_test) setattr(SHAKEVectors, "test_128_%d" % idx, new_test)
test_vectors_256 = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA3"), test_vectors_256 = load_test_vectors(("Hash", "SHA3"),
"ShortMsgKAT_SHAKE256.txt", "ShortMsgKAT_SHAKE256.txt",
"Short Messages KAT SHAKE256", "Short Messages KAT SHAKE256",
{ "len" : lambda x: int(x) } ) { "len" : lambda x: int(x) } ) or []
for idx, tv in enumerate(test_vectors_256): for idx, tv in enumerate(test_vectors_256):
if tv.len == 0: if tv.len == 0:

View file

@ -33,7 +33,7 @@
import unittest import unittest
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.Hash import keccak from Crypto.Hash import keccak
@ -141,15 +141,15 @@ class KeccakVectors(unittest.TestCase):
# TODO: add ExtremelyLong tests # TODO: add ExtremelyLong tests
test_vectors_224 = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "keccak"), test_vectors_224 = load_test_vectors(("Hash", "keccak"),
"ShortMsgKAT_224.txt", "ShortMsgKAT_224.txt",
"Short Messages KAT 224", "Short Messages KAT 224",
{ "len" : lambda x: int(x) } ) {"len": lambda x: int(x)}) or []
test_vectors_224 += load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "keccak"), test_vectors_224 += load_test_vectors(("Hash", "keccak"),
"LongMsgKAT_224.txt", "LongMsgKAT_224.txt",
"Long Messages KAT 224", "Long Messages KAT 224",
{ "len" : lambda x: int(x) } ) {"len": lambda x: int(x)}) or []
for idx, tv in enumerate(test_vectors_224): for idx, tv in enumerate(test_vectors_224):
if tv.len == 0: if tv.len == 0:
@ -165,15 +165,15 @@ for idx, tv in enumerate(test_vectors_224):
# --- # ---
test_vectors_256 = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "keccak"), test_vectors_256 = load_test_vectors(("Hash", "keccak"),
"ShortMsgKAT_256.txt", "ShortMsgKAT_256.txt",
"Short Messages KAT 256", "Short Messages KAT 256",
{ "len" : lambda x: int(x) } ) { "len" : lambda x: int(x) } ) or []
test_vectors_256 += load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "keccak"), test_vectors_256 += load_test_vectors(("Hash", "keccak"),
"LongMsgKAT_256.txt", "LongMsgKAT_256.txt",
"Long Messages KAT 256", "Long Messages KAT 256",
{ "len" : lambda x: int(x) } ) { "len" : lambda x: int(x) } ) or []
for idx, tv in enumerate(test_vectors_256): for idx, tv in enumerate(test_vectors_256):
if tv.len == 0: if tv.len == 0:
@ -190,15 +190,15 @@ for idx, tv in enumerate(test_vectors_256):
# --- # ---
test_vectors_384 = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "keccak"), test_vectors_384 = load_test_vectors(("Hash", "keccak"),
"ShortMsgKAT_384.txt", "ShortMsgKAT_384.txt",
"Short Messages KAT 384", "Short Messages KAT 384",
{ "len" : lambda x: int(x) } ) {"len": lambda x: int(x)}) or []
test_vectors_384 += load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "keccak"), test_vectors_384 += load_test_vectors(("Hash", "keccak"),
"LongMsgKAT_384.txt", "LongMsgKAT_384.txt",
"Long Messages KAT 384", "Long Messages KAT 384",
{ "len" : lambda x: int(x) } ) {"len": lambda x: int(x)}) or []
for idx, tv in enumerate(test_vectors_384): for idx, tv in enumerate(test_vectors_384):
if tv.len == 0: if tv.len == 0:
@ -214,15 +214,15 @@ for idx, tv in enumerate(test_vectors_384):
# --- # ---
test_vectors_512 = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "keccak"), test_vectors_512 = load_test_vectors(("Hash", "keccak"),
"ShortMsgKAT_512.txt", "ShortMsgKAT_512.txt",
"Short Messages KAT 512", "Short Messages KAT 512",
{ "len" : lambda x: int(x) } ) {"len": lambda x: int(x)}) or []
test_vectors_512 += load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "keccak"), test_vectors_512 += load_test_vectors(("Hash", "keccak"),
"LongMsgKAT_512.txt", "LongMsgKAT_512.txt",
"Long Messages KAT 512", "Long Messages KAT 512",
{ "len" : lambda x: int(x) } ) {"len": lambda x: int(x)}) or []
for idx, tv in enumerate(test_vectors_512): for idx, tv in enumerate(test_vectors_512):
if tv.len == 0: if tv.len == 0:

View file

@ -20,13 +20,13 @@
# SOFTWARE. # SOFTWARE.
# =================================================================== # ===================================================================
import json
import unittest import unittest
from binascii import unhexlify from binascii import unhexlify
from Crypto.Util.py3compat import * from Crypto.Util.py3compat import b, bchr
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.SelfTest.loader import load_test_vectors_wycheproof
from Crypto.Hash import SHA1, HMAC, SHA256, MD5, SHA224, SHA384, SHA512 from Crypto.Hash import SHA1, HMAC, SHA256, MD5, SHA224, SHA384, SHA512
from Crypto.Cipher import AES, DES3 from Crypto.Cipher import AES, DES3
@ -34,7 +34,6 @@ from Crypto.Protocol.KDF import (PBKDF1, PBKDF2, _S2V, HKDF, scrypt,
bcrypt, bcrypt_check) bcrypt, bcrypt_check)
from Crypto.Protocol.KDF import _bcrypt_decode from Crypto.Protocol.KDF import _bcrypt_decode
from Crypto.Util._file_system import pycryptodome_filename
def t2b(t): def t2b(t):
@ -59,7 +58,7 @@ class PBKDF1_Tests(unittest.TestCase):
# Item #4: expected result (encoded in hex) # Item #4: expected result (encoded in hex)
_testData = ( _testData = (
# From http://www.di-mgt.com.au/cryptoKDFs.html#examplespbkdf # From http://www.di-mgt.com.au/cryptoKDFs.html#examplespbkdf
("password","78578E5A5D63CB06",16,1000,"DC19847E05C64D2FAF10EBFB4A3D2A20"), ("password", "78578E5A5D63CB06", 16, 1000, "DC19847E05C64D2FAF10EBFB4A3D2A20"),
) )
def test1(self): def test1(self):
@ -67,6 +66,7 @@ class PBKDF1_Tests(unittest.TestCase):
res = PBKDF1(v[0], t2b(v[1]), v[2], v[3], SHA1) res = PBKDF1(v[0], t2b(v[1]), v[2], v[3], SHA1)
self.assertEqual(res, t2b(v[4])) self.assertEqual(res, t2b(v[4]))
class PBKDF2_Tests(unittest.TestCase): class PBKDF2_Tests(unittest.TestCase):
# List of tuples with test data. # List of tuples with test data.
@ -462,7 +462,7 @@ class bcrypt_Tests(unittest.TestCase):
bcrypt_check("pwd", ref) bcrypt_check("pwd", ref)
bref = bytearray(ref) bref = bytearray(ref)
bcrypt_check("pwd", bref) bcrypt_check("pwd", bref)
wrong = ref[:-1] + bchr(bref[-1] ^ 0x01) wrong = ref[:-1] + bchr(bref[-1] ^ 0x01)
self.assertRaises(ValueError, bcrypt_check, "pwd", wrong) self.assertRaises(ValueError, bcrypt_check, "pwd", wrong)
@ -650,42 +650,29 @@ class TestVectorsHKDFWycheproof(unittest.TestCase):
self._id = "None" self._id = "None"
def add_tests(self, filename): def add_tests(self, filename):
comps = "Crypto.SelfTest.Protocol.test_vectors.wycheproof".split(".")
with open(pycryptodome_filename(comps, filename), "rt") as file_in:
tv_tree = json.load(file_in)
algo_name = tv_tree['algorithm'] def filter_algo(root):
if algo_name == "HKDF-SHA-1": algo_name = root['algorithm']
hash_module = SHA1 if algo_name == "HKDF-SHA-1":
elif algo_name == "HKDF-SHA-256": return SHA1
hash_module = SHA256 elif algo_name == "HKDF-SHA-256":
elif algo_name == "HKDF-SHA-384": return SHA256
hash_module = SHA384 elif algo_name == "HKDF-SHA-384":
elif algo_name == "HKDF-SHA-512": return SHA384
hash_module = SHA512 elif algo_name == "HKDF-SHA-512":
else: return SHA512
raise ValueError("Unknown algorithm " + algo_name) else:
raise ValueError("Unknown algorithm " + algo_name)
for group in tv_tree['testGroups']: def filter_size(unit):
return int(unit['size'])
from collections import namedtuple result = load_test_vectors_wycheproof(("Protocol", "wycheproof"),
TestVector = namedtuple('TestVector', 'id comment ikm salt info size okm hash_module valid warning filename') filename,
"Wycheproof HMAC (%s)" % filename,
for test in group['tests']: root_tag={'hash_module': filter_algo},
tv = TestVector( unit_tag={'size': filter_size})
test['tcId'], return result
test['comment'],
unhexlify(test['ikm']),
unhexlify(test['salt']),
unhexlify(test['info']),
int(test['size']),
unhexlify(test['okm']),
hash_module,
test['result'] != "invalid",
test['result'] == "acceptable",
filename
)
self.tv.append(tv)
def setUp(self): def setUp(self):
self.tv = [] self.tv = []
@ -733,7 +720,7 @@ def get_tests(config={}):
tests += list_test_cases(PBKDF2_Tests) tests += list_test_cases(PBKDF2_Tests)
tests += list_test_cases(S2V_Tests) tests += list_test_cases(S2V_Tests)
tests += list_test_cases(HKDF_Tests) tests += list_test_cases(HKDF_Tests)
tests += [ TestVectorsHKDFWycheproof(wycheproof_warnings) ] tests += [TestVectorsHKDFWycheproof(wycheproof_warnings)]
tests += list_test_cases(scrypt_Tests) tests += list_test_cases(scrypt_Tests)
tests += list_test_cases(bcrypt_Tests) tests += list_test_cases(bcrypt_Tests)

View file

@ -31,7 +31,7 @@
import unittest import unittest
import time import time
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors
from Crypto.PublicKey import ECC from Crypto.PublicKey import ECC
from Crypto.PublicKey.ECC import EccPoint, _curves, EccKey from Crypto.PublicKey.ECC import EccPoint, _curves, EccKey
@ -479,13 +479,12 @@ class TestEccPoint_PAI_P256(unittest.TestCase):
pointG = EccPoint(curve.Gx, curve.Gy, "p256") pointG = EccPoint(curve.Gx, curve.Gy, "p256")
tv_pai = load_tests(("Crypto", "SelfTest", "PublicKey", "test_vectors", "ECC"), tv_pai = load_test_vectors(("PublicKey", "ECC"),
"point-at-infinity.org-P256.txt", "point-at-infinity.org-P256.txt",
"P-256 tests from point-at-infinity.org", "P-256 tests from point-at-infinity.org",
{ "k" : lambda k: int(k), {"k": lambda k: int(k),
"x" : lambda x: int(x, 16), "x": lambda x: int(x, 16),
"y" : lambda y: int(y, 16)} ) "y": lambda y: int(y, 16)}) or []
assert(tv_pai)
for tv in tv_pai: for tv in tv_pai:
def new_test(self, scalar=tv.k, x=tv.x, y=tv.y): def new_test(self, scalar=tv.k, x=tv.x, y=tv.y):
result = self.pointG * scalar result = self.pointG * scalar
@ -501,13 +500,12 @@ class TestEccPoint_PAI_P384(unittest.TestCase):
pointG = EccPoint(curve.Gx, curve.Gy, "p384") pointG = EccPoint(curve.Gx, curve.Gy, "p384")
tv_pai = load_tests(("Crypto", "SelfTest", "PublicKey", "test_vectors", "ECC"), tv_pai = load_test_vectors(("PublicKey", "ECC"),
"point-at-infinity.org-P384.txt", "point-at-infinity.org-P384.txt",
"P-384 tests from point-at-infinity.org", "P-384 tests from point-at-infinity.org",
{ "k" : lambda k: int(k), {"k" : lambda k: int(k),
"x" : lambda x: int(x, 16), "x" : lambda x: int(x, 16),
"y" : lambda y: int(y, 16)} ) "y" : lambda y: int(y, 16)}) or []
assert(tv_pai)
for tv in tv_pai: for tv in tv_pai:
def new_test(self, scalar=tv.k, x=tv.x, y=tv.y): def new_test(self, scalar=tv.k, x=tv.x, y=tv.y):
result = self.pointG * scalar result = self.pointG * scalar
@ -523,13 +521,12 @@ class TestEccPoint_PAI_P521(unittest.TestCase):
pointG = EccPoint(curve.Gx, curve.Gy, "p521") pointG = EccPoint(curve.Gx, curve.Gy, "p521")
tv_pai = load_tests(("Crypto", "SelfTest", "PublicKey", "test_vectors", "ECC"), tv_pai = load_test_vectors(("PublicKey", "ECC"),
"point-at-infinity.org-P521.txt", "point-at-infinity.org-P521.txt",
"P-521 tests from point-at-infinity.org", "P-521 tests from point-at-infinity.org",
{ "k" : lambda k: int(k), {"k": lambda k: int(k),
"x" : lambda x: int(x, 16), "x": lambda x: int(x, 16),
"y" : lambda y: int(y, 16)} ) "y": lambda y: int(y, 16)}) or []
assert(tv_pai)
for tv in tv_pai: for tv in tv_pai:
def new_test(self, scalar=tv.k, x=tv.x, y=tv.y): def new_test(self, scalar=tv.k, x=tv.x, y=tv.y):
result = self.pointG * scalar result = self.pointG * scalar

View file

@ -28,21 +28,54 @@
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
# =================================================================== # ===================================================================
import os
import errno
import warnings
import unittest import unittest
from binascii import unhexlify from binascii import unhexlify
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.Util._file_system import pycryptodome_filename
from Crypto.Util.py3compat import bord, tostr from Crypto.Util.py3compat import bord, tostr
from Crypto.Util.number import bytes_to_long from Crypto.Util.number import bytes_to_long
from Crypto.Hash import SHAKE128 from Crypto.Hash import SHAKE128
from Crypto.PublicKey import ECC from Crypto.PublicKey import ECC
def load_file(filename, mode="rb"): try:
comps = [ "Crypto", "SelfTest", "PublicKey", "test_vectors", "ECC" ] import pycryptodome_test_vectors # type: ignore
with open(pycryptodome_filename(comps, filename), mode) as fd: test_vectors_available = True
return fd.read() except ImportError:
test_vectors_available = False
class MissingTestVectorException(ValueError):
pass
def load_file(file_name, mode="rb"):
results = None
try:
if not test_vectors_available:
raise FileNotFoundError(errno.ENOENT,
os.strerror(errno.ENOENT),
file_name)
dir_comps = ("PublicKey", "ECC")
init_dir = os.path.dirname(pycryptodome_test_vectors.__file__)
full_file_name = os.path.join(init_dir, *dir_comps, file_name)
with open(full_file_name, mode) as file_in:
results = file_in.read()
except FileNotFoundError:
warnings.warn("Warning: skipping extended tests for ECC",
UserWarning,
stacklevel=2)
if results is None:
raise MissingTestVectorException("Missing %s" % file_name)
return results
def compact(lines): def compact(lines):
@ -86,13 +119,11 @@ def create_ref_keys_p521():
return (ECC.construct(curve="P-521", d=private_key_d), return (ECC.construct(curve="P-521", d=private_key_d),
ECC.construct(curve="P-521", point_x=public_key_x, point_y=public_key_y)) ECC.construct(curve="P-521", point_x=public_key_x, point_y=public_key_y))
# Create reference key pair # Create reference key pair
# ref_private, ref_public = create_ref_keys_p521() # ref_private, ref_public = create_ref_keys_p521()
def get_fixed_prng(): def get_fixed_prng():
return SHAKE128.new().update(b"SEED").read return SHAKE128.new().update(b"SEED").read
class TestImport(unittest.TestCase): class TestImport(unittest.TestCase):
@ -103,7 +134,9 @@ class TestImport(unittest.TestCase):
class TestImport_P256(unittest.TestCase): class TestImport_P256(unittest.TestCase):
ref_private, ref_public = create_ref_keys_p256() def __init__(self, *args, **kwargs):
super(TestImport_P256, self).__init__(*args, **kwargs)
self.ref_private, self.ref_public = create_ref_keys_p256()
def test_import_public_der(self): def test_import_public_der(self):
key_file = load_file("ecc_p256_public.der") key_file = load_file("ecc_p256_public.der")
@ -229,7 +262,9 @@ class TestImport_P256(unittest.TestCase):
class TestImport_P384(unittest.TestCase): class TestImport_P384(unittest.TestCase):
ref_private, ref_public = create_ref_keys_p384() def __init__(self, *args, **kwargs):
super(TestImport_P384, self).__init__(*args, **kwargs)
self.ref_private, self.ref_public = create_ref_keys_p384()
def test_import_public_der(self): def test_import_public_der(self):
key_file = load_file("ecc_p384_public.der") key_file = load_file("ecc_p384_public.der")
@ -350,7 +385,9 @@ class TestImport_P384(unittest.TestCase):
class TestImport_P521(unittest.TestCase): class TestImport_P521(unittest.TestCase):
ref_private, ref_public = create_ref_keys_p521() def __init__(self, *args, **kwargs):
super(TestImport_P521, self).__init__(*args, **kwargs)
self.ref_private, self.ref_public = create_ref_keys_p521()
def test_import_public_der(self): def test_import_public_der(self):
key_file = load_file("ecc_p521_public.der") key_file = load_file("ecc_p521_public.der")
@ -471,7 +508,9 @@ class TestImport_P521(unittest.TestCase):
class TestExport_P256(unittest.TestCase): class TestExport_P256(unittest.TestCase):
ref_private, ref_public = create_ref_keys_p256() def __init__(self, *args, **kwargs):
super(TestExport_P256, self).__init__(*args, **kwargs)
self.ref_private, self.ref_public = create_ref_keys_p256()
def test_export_public_der_uncompressed(self): def test_export_public_der_uncompressed(self):
key_file = load_file("ecc_p256_public.der") key_file = load_file("ecc_p256_public.der")
@ -517,7 +556,7 @@ class TestExport_P256(unittest.TestCase):
def test_export_private_pkcs8_encrypted(self): def test_export_private_pkcs8_encrypted(self):
encoded = self.ref_private._export_pkcs8(passphrase="secret", encoded = self.ref_private._export_pkcs8(passphrase="secret",
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
# This should prove that the output is password-protected # This should prove that the output is password-protected
self.assertRaises(ValueError, ECC._import_pkcs8, encoded, None) self.assertRaises(ValueError, ECC._import_pkcs8, encoded, None)
@ -528,8 +567,8 @@ class TestExport_P256(unittest.TestCase):
# --- # ---
encoded = self.ref_private.export_key(format="DER", encoded = self.ref_private.export_key(format="DER",
passphrase="secret", passphrase="secret",
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
decoded = ECC.import_key(encoded, "secret") decoded = ECC.import_key(encoded, "secret")
self.assertEqual(self.ref_private, decoded) self.assertEqual(self.ref_private, decoded)
@ -749,7 +788,9 @@ gVnJp9EBND/tHQ==
class TestExport_P384(unittest.TestCase): class TestExport_P384(unittest.TestCase):
ref_private, ref_public = create_ref_keys_p384() def __init__(self, *args, **kwargs):
super(TestExport_P384, self).__init__(*args, **kwargs)
self.ref_private, self.ref_public = create_ref_keys_p384()
def test_export_public_der_uncompressed(self): def test_export_public_der_uncompressed(self):
key_file = load_file("ecc_p384_public.der") key_file = load_file("ecc_p384_public.der")
@ -1016,7 +1057,9 @@ YC46ZRsnKNayw3wATdPjgja7L/DSII3nZK0G6KOOVwJBznT/e+zudUJYhZKaBLRx
class TestExport_P521(unittest.TestCase): class TestExport_P521(unittest.TestCase):
ref_private, ref_public = create_ref_keys_p521() def __init__(self, *args, **kwargs):
super(TestExport_P521, self).__init__(*args, **kwargs)
self.ref_private, self.ref_public = create_ref_keys_p521()
def test_export_public_der_uncompressed(self): def test_export_public_der_uncompressed(self):
key_file = load_file("ecc_p521_public.der") key_file = load_file("ecc_p521_public.der")
@ -1286,14 +1329,18 @@ vv6oYkMIIi7r5oQWAiQDrR2mlrrFDL9V7GH/r8SWQw==
def get_tests(config={}): def get_tests(config={}):
tests = [] tests = []
tests += list_test_cases(TestImport) tests += list_test_cases(TestImport)
tests += list_test_cases(TestImport_P256) try:
tests += list_test_cases(TestImport_P384) tests += list_test_cases(TestImport_P256)
tests += list_test_cases(TestImport_P521) tests += list_test_cases(TestImport_P384)
tests += list_test_cases(TestExport_P256) tests += list_test_cases(TestImport_P521)
tests += list_test_cases(TestExport_P384) tests += list_test_cases(TestExport_P256)
tests += list_test_cases(TestExport_P521) tests += list_test_cases(TestExport_P384)
tests += list_test_cases(TestExport_P521)
except MissingTestVectorException:
pass
return tests return tests
if __name__ == '__main__': if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests()) suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite') unittest.main(defaultTest='suite')

View file

@ -20,32 +20,57 @@
# SOFTWARE. # SOFTWARE.
# =================================================================== # ===================================================================
import unittest import os
import re import re
import errno
import warnings
import unittest
from Crypto.PublicKey import RSA from Crypto.PublicKey import RSA
from Crypto.SelfTest.st_common import * from Crypto.SelfTest.st_common import a2b_hex, list_test_cases
from Crypto.Util.py3compat import * from Crypto.Util.py3compat import b, tostr
from Crypto.Util.number import inverse from Crypto.Util.number import inverse
from Crypto.Util import asn1 from Crypto.Util import asn1
from Crypto.Util._file_system import pycryptodome_filename try:
import pycryptodome_test_vectors # type: ignore
test_vectors_available = True
except ImportError:
test_vectors_available = False
def load_file(filename, mode="rb"): def load_file(file_name, mode="rb"):
comps = [ "Crypto", "SelfTest", "PublicKey", "test_vectors", "RSA" ] results = None
with open(pycryptodome_filename(comps, filename), mode) as fd:
return fd.read() try:
if not test_vectors_available:
raise FileNotFoundError(errno.ENOENT,
os.strerror(errno.ENOENT),
file_name)
dir_comps = ("PublicKey", "RSA")
init_dir = os.path.dirname(pycryptodome_test_vectors.__file__)
full_file_name = os.path.join(init_dir, *dir_comps, file_name)
with open(full_file_name, mode) as file_in:
results = file_in.read()
except FileNotFoundError:
warnings.warn("Warning: skipping extended tests for RSA",
UserWarning,
stacklevel=2)
return results
def der2pem(der, text='PUBLIC'): def der2pem(der, text='PUBLIC'):
import binascii import binascii
chunks = [ binascii.b2a_base64(der[i:i+48]) for i in range(0, len(der), 48) ] chunks = [binascii.b2a_base64(der[i:i+48]) for i in range(0, len(der), 48)]
pem = b('-----BEGIN %s KEY-----\n' % text) pem = b('-----BEGIN %s KEY-----\n' % text)
pem += b('').join(chunks) pem += b('').join(chunks)
pem += b('-----END %s KEY-----' % text) pem += b('-----END %s KEY-----' % text)
return pem return pem
class ImportKeyTests(unittest.TestCase): class ImportKeyTests(unittest.TestCase):
# 512-bit RSA key generated with openssl # 512-bit RSA key generated with openssl
rsaKeyPEM = u'''-----BEGIN RSA PRIVATE KEY----- rsaKeyPEM = u'''-----BEGIN RSA PRIVATE KEY-----
@ -71,7 +96,7 @@ BX85JB8zqwHB
-----END PRIVATE KEY-----''' -----END PRIVATE KEY-----'''
# The same RSA private key as in rsaKeyPEM, but now encrypted # The same RSA private key as in rsaKeyPEM, but now encrypted
rsaKeyEncryptedPEM=( rsaKeyEncryptedPEM = (
# PEM encryption # PEM encryption
# With DES and passphrase 'test' # With DES and passphrase 'test'
@ -507,6 +532,10 @@ class TestImport_2048(unittest.TestCase):
key_file_ref = load_file("rsa2048_private.pem") key_file_ref = load_file("rsa2048_private.pem")
key_file = load_file("rsa2048_public_openssh.txt") key_file = load_file("rsa2048_public_openssh.txt")
# Skip test if test vectors are not installed
if None in (key_file_ref, key_file):
return
key_ref = RSA.import_key(key_file_ref).public_key() key_ref = RSA.import_key(key_file_ref).public_key()
key = RSA.import_key(key_file) key = RSA.import_key(key_file)
self.assertEqual(key_ref, key) self.assertEqual(key_ref, key)
@ -515,6 +544,10 @@ class TestImport_2048(unittest.TestCase):
key_file = load_file("rsa2048_private_openssh.pem") key_file = load_file("rsa2048_private_openssh.pem")
key_file_old = load_file("rsa2048_private_openssh_old.pem") key_file_old = load_file("rsa2048_private_openssh_old.pem")
# Skip test if test vectors are not installed
if None in (key_file_old, key_file):
return
key = RSA.import_key(key_file) key = RSA.import_key(key_file)
key_old = RSA.import_key(key_file_old) key_old = RSA.import_key(key_file_old)
@ -524,6 +557,10 @@ class TestImport_2048(unittest.TestCase):
key_file = load_file("rsa2048_private_openssh_pwd.pem") key_file = load_file("rsa2048_private_openssh_pwd.pem")
key_file_old = load_file("rsa2048_private_openssh_pwd_old.pem") key_file_old = load_file("rsa2048_private_openssh_pwd_old.pem")
# Skip test if test vectors are not installed
if None in (key_file_old, key_file):
return
key = RSA.import_key(key_file, b"password") key = RSA.import_key(key_file, b"password")
key_old = RSA.import_key(key_file_old) key_old = RSA.import_key(key_file_old)
self.assertEqual(key, key_old) self.assertEqual(key, key_old)

View file

@ -32,7 +32,6 @@
# =================================================================== # ===================================================================
import re import re
import json
import unittest import unittest
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
@ -43,12 +42,9 @@ from Crypto.Hash import (SHA1, SHA224, SHA256, SHA384, SHA512, SHA3_256,
from Crypto.Signature import DSS from Crypto.Signature import DSS
from Crypto.PublicKey import DSA, ECC from Crypto.PublicKey import DSA, ECC
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors, load_test_vectors_wycheproof
from Crypto.Util.number import bytes_to_long, long_to_bytes from Crypto.Util.number import bytes_to_long, long_to_bytes
from Crypto.Util._file_system import pycryptodome_filename
from Crypto.Util.strxor import strxor
def t2b(hexstring): def t2b(hexstring):
ws = hexstring.replace(" ", "").replace("\n", "") ws = hexstring.replace(" ", "").replace("\n", "")
@ -147,13 +143,15 @@ class FIPS_DSA_Tests(unittest.TestCase):
signer = DSS.new(self.key_pub, 'fips-186-3') signer = DSS.new(self.key_pub, 'fips-186-3')
self.failIf(signer.can_sign()) self.failIf(signer.can_sign())
class FIPS_DSA_Tests_KAT(unittest.TestCase): class FIPS_DSA_Tests_KAT(unittest.TestCase):
pass pass
test_vectors_verify = load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "DSA"),
"FIPS_186_3_SigVer.rsp", test_vectors_verify = load_test_vectors(("Signature", "DSA"),
"Signature Verification 186-3", "FIPS_186_3_SigVer.rsp",
{'result' : lambda x: x}) "Signature Verification 186-3",
{'result': lambda x: x}) or []
for idx, tv in enumerate(test_vectors_verify): for idx, tv in enumerate(test_vectors_verify):
@ -171,9 +169,9 @@ for idx, tv in enumerate(test_vectors_verify):
continue continue
hash_obj = hash_module.new(tv.msg) hash_obj = hash_module.new(tv.msg)
comps = [bytes_to_long(x) for x in (tv.y, generator, modulus, suborder)] comps = [bytes_to_long(x) for x in (tv.y, generator, modulus, suborder)]
key = DSA.construct(comps, False) # type: ignore key = DSA.construct(comps, False) # type: ignore
verifier = DSS.new(key, 'fips-186-3') verifier = DSS.new(key, 'fips-186-3')
def positive_test(self, verifier=verifier, hash_obj=hash_obj, signature=tv.r+tv.s): def positive_test(self, verifier=verifier, hash_obj=hash_obj, signature=tv.r+tv.s):
@ -188,10 +186,10 @@ for idx, tv in enumerate(test_vectors_verify):
setattr(FIPS_DSA_Tests_KAT, "test_verify_negative_%d" % idx, negative_test) setattr(FIPS_DSA_Tests_KAT, "test_verify_negative_%d" % idx, negative_test)
test_vectors_sign = load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "DSA"), test_vectors_sign = load_test_vectors(("Signature", "DSA"),
"FIPS_186_3_SigGen.txt", "FIPS_186_3_SigGen.txt",
"Signature Creation 186-3", "Signature Creation 186-3",
{}) {}) or []
for idx, tv in enumerate(test_vectors_sign): for idx, tv in enumerate(test_vectors_sign):
@ -285,13 +283,13 @@ class FIPS_ECDSA_Tests_KAT(unittest.TestCase):
pass pass
test_vectors_verify = load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "ECDSA"), test_vectors_verify = load_test_vectors(("Signature", "ECDSA"),
"SigVer.rsp", "SigVer.rsp",
"ECDSA Signature Verification 186-3", "ECDSA Signature Verification 186-3",
{'result': lambda x: x, {'result': lambda x: x,
'qx': lambda x: int(x, 16), 'qx': lambda x: int(x, 16),
'qy': lambda x: int(x, 16), 'qy': lambda x: int(x, 16),
}) }) or []
for idx, tv in enumerate(test_vectors_verify): for idx, tv in enumerate(test_vectors_verify):
@ -319,10 +317,10 @@ for idx, tv in enumerate(test_vectors_verify):
setattr(FIPS_ECDSA_Tests_KAT, "test_verify_negative_%d" % idx, negative_test) setattr(FIPS_ECDSA_Tests_KAT, "test_verify_negative_%d" % idx, negative_test)
test_vectors_sign = load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "ECDSA"), test_vectors_sign = load_test_vectors(("Signature", "ECDSA"),
"SigGen.txt", "SigGen.txt",
"ECDSA Signature Verification 186-3", "ECDSA Signature Verification 186-3",
{'d': lambda x: int(x, 16)}) {'d': lambda x: int(x, 16)}) or []
for idx, tv in enumerate(test_vectors_sign): for idx, tv in enumerate(test_vectors_sign):
@ -576,7 +574,7 @@ class Det_DSA_Tests(unittest.TestCase):
TestKey = namedtuple('TestKey', 'p q g x y') TestKey = namedtuple('TestKey', 'p q g x y')
new_keys = {} new_keys = {}
for k in self.keys: for k in self.keys:
tk = TestKey(*[ t2l(y) for y in k[:-1] ]) tk = TestKey(*[t2l(y) for y in k[:-1]])
new_keys[k[-1]] = tk new_keys[k[-1]] = tk
self.keys = new_keys self.keys = new_keys
@ -900,26 +898,46 @@ class Det_ECDSA_Tests(unittest.TestCase):
def test_data_rfc6979_p256(self): def test_data_rfc6979_p256(self):
signer = DSS.new(self.key_priv_p256, 'deterministic-rfc6979') signer = DSS.new(self.key_priv_p256, 'deterministic-rfc6979')
for message, k, r, s, module in self.signatures_p256: for message, k, r, s, module in self.signatures_p256:
hash_obj = module.new(message) hash_obj = module.new(message)
result = signer.sign(hash_obj) result = signer.sign(hash_obj)
self.assertEqual(r + s, result) self.assertEqual(r + s, result)
def test_data_rfc6979_p384(self): def test_data_rfc6979_p384(self):
signer = DSS.new(self.key_priv_p384, 'deterministic-rfc6979') signer = DSS.new(self.key_priv_p384, 'deterministic-rfc6979')
for message, k, r, s, module in self.signatures_p384: for message, k, r, s, module in self.signatures_p384:
hash_obj = module.new(message) hash_obj = module.new(message)
result = signer.sign(hash_obj) result = signer.sign(hash_obj)
self.assertEqual(r + s, result) self.assertEqual(r + s, result)
def test_data_rfc6979_p521(self): def test_data_rfc6979_p521(self):
signer = DSS.new(self.key_priv_p521, 'deterministic-rfc6979') signer = DSS.new(self.key_priv_p521, 'deterministic-rfc6979')
for message, k, r, s, module in self.signatures_p521: for message, k, r, s, module in self.signatures_p521:
hash_obj = module.new(message) hash_obj = module.new(message)
result = signer.sign(hash_obj) result = signer.sign(hash_obj)
self.assertEqual(r + s, result) self.assertEqual(r + s, result)
def get_hash_module(hash_name):
if hash_name == "SHA-512":
hash_module = SHA512
elif hash_name == "SHA-512/224":
hash_module = SHA512.new(truncate="224")
elif hash_name == "SHA-512/256":
hash_module = SHA512.new(truncate="256")
elif hash_name == "SHA-384":
hash_module = SHA384
elif hash_name == "SHA-256":
hash_module = SHA256
elif hash_name == "SHA-224":
hash_module = SHA224
elif hash_name == "SHA-1":
hash_module = SHA1
else:
raise ValueError("Unknown hash algorithm: " + hash_name)
return hash_module
class TestVectorsDSAWycheproof(unittest.TestCase): class TestVectorsDSAWycheproof(unittest.TestCase):
def __init__(self, wycheproof_warnings, slow_tests): def __init__(self, wycheproof_warnings, slow_tests):
@ -927,42 +945,29 @@ class TestVectorsDSAWycheproof(unittest.TestCase):
self._wycheproof_warnings = wycheproof_warnings self._wycheproof_warnings = wycheproof_warnings
self._slow_tests = slow_tests self._slow_tests = slow_tests
self._id = "None" self._id = "None"
def setUp(self):
comps = "Crypto.SelfTest.Signature.test_vectors.wycheproof".split(".")
with open(pycryptodome_filename(comps, "dsa_test.json"), "rt") as file_in:
tv_tree = json.load(file_in)
self.tv = [] self.tv = []
for group in tv_tree['testGroups']: def setUp(self):
key = DSA.import_key(group['keyPem'])
hash_name = group['sha']
if hash_name == "SHA-256":
hash_module = SHA256
elif hash_name == "SHA-224":
hash_module = SHA224
elif hash_name == "SHA-1":
hash_module = SHA1
else:
assert False
assert group['type'] == "DsaVerify"
from collections import namedtuple
TestVector = namedtuple('TestVector', 'id comment msg sig key hash_module valid warning')
for test in group['tests']: def filter_dsa(group):
tv = TestVector( return DSA.import_key(group['keyPem'])
test['tcId'],
test['comment'], def filter_sha(group):
unhexlify(test['msg']), return get_hash_module(group['sha'])
unhexlify(test['sig']),
key, def filter_type(group):
hash_module, sig_type = group['type']
test['result'] != "invalid", if sig_type != 'DsaVerify':
test['result'] == "acceptable" raise ValueError("Unknown signature type " + sig_type)
) return sig_type
self.tv.append(tv)
result = load_test_vectors_wycheproof(("Signature", "wycheproof"),
"dsa_test.json",
"Wycheproof DSA signature",
group_tag={'key': filter_dsa,
'hash_module': filter_sha,
'sig_type': filter_type})
self.tv += result
def shortDescription(self): def shortDescription(self):
return self._id return self._id
@ -974,7 +979,7 @@ class TestVectorsDSAWycheproof(unittest.TestCase):
def test_verify(self, tv): def test_verify(self, tv):
self._id = "Wycheproof DSA Test #" + str(tv.id) self._id = "Wycheproof DSA Test #" + str(tv.id)
hashed_msg = tv.hash_module.new(tv.msg) hashed_msg = tv.hash_module.new(tv.msg)
signer = DSS.new(tv.key, 'fips-186-3', encoding='der') signer = DSS.new(tv.key, 'fips-186-3', encoding='der')
try: try:
@ -1001,62 +1006,39 @@ class TestVectorsECDSAWycheproof(unittest.TestCase):
self._id = "None" self._id = "None"
def add_tests(self, filename): def add_tests(self, filename):
comps = "Crypto.SelfTest.Signature.test_vectors.wycheproof".split(".")
with open(pycryptodome_filename(comps, filename), "rt") as file_in:
tv_tree = json.load(file_in)
for group in tv_tree['testGroups']: def filter_ecc(group):
# These are the only curves we accept to skip
try: if group['key']['curve'] in ('secp224r1', 'secp224k1', 'secp256k1',
key = ECC.import_key(group['keyPem']) 'brainpoolP224r1', 'brainpoolP224t1',
except ValueError: 'brainpoolP256r1', 'brainpoolP256t1',
continue 'brainpoolP320r1', 'brainpoolP320t1',
'brainpoolP384r1', 'brainpoolP384t1',
hash_name = group['sha'] 'brainpoolP512r1', 'brainpoolP512t1',
if hash_name == "SHA-512": ):
hash_module = SHA512 return None
elif hash_name == "SHA3-512": return ECC.import_key(group['keyPem'])
hash_module = SHA3_512
elif hash_name == "SHA-384":
hash_module = SHA384
elif hash_name == "SHA3-384":
hash_module = SHA3_384
elif hash_name == "SHA-256":
hash_module = SHA256
elif hash_name == "SHA3-256":
hash_module = SHA3_256
elif hash_name == "SHA-224":
hash_module = SHA224
elif hash_name == "SHA-1":
hash_module = SHA1
else:
raise ValueError("Unknown hash type " + hash_name)
def filter_sha(group):
return get_hash_module(group['sha'])
def filter_encoding(group):
encoding_name = group['type'] encoding_name = group['type']
if encoding_name == "EcdsaVerify": if encoding_name == "EcdsaVerify":
encoding = "der" return "der"
elif encoding_name == "EcdsaP1363Verify": elif encoding_name == "EcdsaP1363Verify":
encoding = "binary" return "binary"
else: else:
raise ValueError("Unknown signature type " + encoding_name) raise ValueError("Unknown signature type " + encoding_name)
from collections import namedtuple result = load_test_vectors_wycheproof(("Signature", "wycheproof"),
TestVector = namedtuple('TestVector', 'id comment msg encoding sig key hash_module valid warning filename') filename,
"Wycheproof ECDSA signature (%s)" % filename,
for test in group['tests']: group_tag={'key': filter_ecc,
tv = TestVector( 'hash_module': filter_sha,
test['tcId'], 'encoding': filter_encoding,
test['comment'], })
unhexlify(test['msg']), self.tv += result
encoding,
unhexlify(test['sig']),
key,
hash_module,
test['result'] != "invalid",
test['result'] == "acceptable",
filename
)
self.tv.append(tv)
def setUp(self): def setUp(self):
self.tv = [] self.tv = []
@ -1101,6 +1083,10 @@ class TestVectorsECDSAWycheproof(unittest.TestCase):
def test_verify(self, tv): def test_verify(self, tv):
self._id = "Wycheproof ECDSA Test #%d (%s, %s)" % (tv.id, tv.comment, tv.filename) self._id = "Wycheproof ECDSA Test #%d (%s, %s)" % (tv.id, tv.comment, tv.filename)
# Skip tests with unsupported curves
if tv.key is None:
return
hashed_msg = tv.hash_module.new(tv.msg) hashed_msg = tv.hash_module.new(tv.msg)
signer = DSS.new(tv.key, 'fips-186-3', encoding=tv.encoding) signer = DSS.new(tv.key, 'fips-186-3', encoding=tv.encoding)
try: try:
@ -1134,12 +1120,13 @@ def get_tests(config={}):
tests += list_test_cases(FIPS_DSA_Tests_KAT) tests += list_test_cases(FIPS_DSA_Tests_KAT)
tests += list_test_cases(FIPS_ECDSA_Tests_KAT) tests += list_test_cases(FIPS_ECDSA_Tests_KAT)
tests += [ TestVectorsDSAWycheproof(wycheproof_warnings, slow_tests) ] tests += [TestVectorsDSAWycheproof(wycheproof_warnings, slow_tests)]
tests += [ TestVectorsECDSAWycheproof(wycheproof_warnings, slow_tests) ] tests += [TestVectorsECDSAWycheproof(wycheproof_warnings, slow_tests)]
return tests return tests
if __name__ == '__main__': if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests()) def suite():
return unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite') unittest.main(defaultTest='suite')

View file

@ -36,7 +36,7 @@ from Crypto.Util.py3compat import bchr
from Crypto.Util.number import bytes_to_long from Crypto.Util.number import bytes_to_long
from Crypto.Util.strxor import strxor from Crypto.Util.strxor import strxor
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors, load_test_vectors_wycheproof
from Crypto.Hash import (SHA1, SHA224, SHA256, SHA384, SHA512, SHA3_384, from Crypto.Hash import (SHA1, SHA224, SHA256, SHA384, SHA512, SHA3_384,
SHA3_224, SHA3_256, SHA3_512) SHA3_224, SHA3_256, SHA3_512)
@ -67,12 +67,12 @@ class FIPS_PKCS1_Verify_Tests_KAT(unittest.TestCase):
pass pass
test_vectors_verify = load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "PKCS1-v1.5"), test_vectors_verify = load_test_vectors(("Signature", "PKCS1-v1.5"),
"SigVer15_186-3.rsp", "SigVer15_186-3.rsp",
"Signature Verification 186-3", "Signature Verification 186-3",
{ 'shaalg' : lambda x: x, {'shaalg': lambda x: x,
'd' : lambda x: int(x), 'd': lambda x: int(x),
'result' : lambda x: x }) 'result': lambda x: x}) or []
for count, tv in enumerate(test_vectors_verify): for count, tv in enumerate(test_vectors_verify):
@ -114,15 +114,15 @@ class FIPS_PKCS1_Sign_Tests_KAT(unittest.TestCase):
pass pass
test_vectors_sign = load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "PKCS1-v1.5"), test_vectors_sign = load_test_vectors(("Signature", "PKCS1-v1.5"),
"SigGen15_186-2.txt", "SigGen15_186-2.txt",
"Signature Generation 186-2", "Signature Generation 186-2",
{ 'shaalg' : lambda x: x }) {'shaalg': lambda x: x}) or []
test_vectors_sign += load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "PKCS1-v1.5"), test_vectors_sign += load_test_vectors(("Signature", "PKCS1-v1.5"),
"SigGen15_186-3.txt", "SigGen15_186-3.txt",
"Signature Generation 186-3", "Signature Generation 186-3",
{ 'shaalg' : lambda x: x }) {'shaalg': lambda x: x}) or []
for count, tv in enumerate(test_vectors_sign): for count, tv in enumerate(test_vectors_sign):
if isinstance(tv, str): if isinstance(tv, str):
@ -254,59 +254,49 @@ class TestVectorsWycheproof(unittest.TestCase):
self.add_tests("rsa_signature_test.json") self.add_tests("rsa_signature_test.json")
def add_tests(self, filename): def add_tests(self, filename):
comps = "Crypto.SelfTest.Signature.test_vectors.wycheproof".split(".")
with open(pycryptodome_filename(comps, filename), "rt") as file_in:
tv_tree = json.load(file_in)
class TestVector(object): def filter_rsa(group):
pass return RSA.import_key(group['keyPem'])
self.tv = []
for group in tv_tree['testGroups']:
key = RSA.import_key(group['keyPem'])
def filter_sha(group):
hash_name = group['sha'] hash_name = group['sha']
if hash_name == "SHA-512": if hash_name == "SHA-512":
hash_module = SHA512 return SHA512
elif hash_name == "SHA-512/224": elif hash_name == "SHA-512/224":
hash_module = SHA512.new(truncate="224") return SHA512.new(truncate="224")
elif hash_name == "SHA-512/256": elif hash_name == "SHA-512/256":
hash_module = SHA512.new(truncate="256") return SHA512.new(truncate="256")
elif hash_name == "SHA3-512": elif hash_name == "SHA3-512":
hash_module = SHA3_512 return SHA3_512
elif hash_name == "SHA-384": elif hash_name == "SHA-384":
hash_module = SHA384 return SHA384
elif hash_name == "SHA3-384": elif hash_name == "SHA3-384":
hash_module = SHA3_384 return SHA3_384
elif hash_name == "SHA-256": elif hash_name == "SHA-256":
hash_module = SHA256 return SHA256
elif hash_name == "SHA3-256": elif hash_name == "SHA3-256":
hash_module = SHA3_256 return SHA3_256
elif hash_name == "SHA-224": elif hash_name == "SHA-224":
hash_module = SHA224 return SHA224
elif hash_name == "SHA3-224": elif hash_name == "SHA3-224":
hash_module = SHA3_224 return SHA3_224
elif hash_name == "SHA-1": elif hash_name == "SHA-1":
hash_module = SHA1 return SHA1
else: else:
raise ValueError("Unknown hash algorithm: " + hash_name) raise ValueError("Unknown hash algorithm: " + hash_name)
def filter_type(group):
type_name = group['type'] type_name = group['type']
if type_name not in ("RsassaPkcs1Verify", "RsassaPkcs1Generate"): if type_name not in ("RsassaPkcs1Verify", "RsassaPkcs1Generate"):
raise ValueError("Unknown type name " + type_name) raise ValueError("Unknown type name " + type_name)
for test in group['tests']: result = load_test_vectors_wycheproof(("Signature", "wycheproof"),
tv = TestVector() filename,
"Wycheproof PKCS#1v1.5 signature (%s)" % filename,
tv.id = test['tcId'] group_tag={'rsa_key': filter_rsa,
tv.comment = test['comment'] 'hash_mod': filter_sha,
for attr in 'msg', 'sig': 'type': filter_type})
setattr(tv, attr, unhexlify(test[attr])) return result
tv.key = key
tv.hash_module = hash_module
tv.valid = test['result'] != "invalid"
tv.warning = test['result'] == "acceptable"
self.tv.append(tv)
def shortDescription(self): def shortDescription(self):
return self._id return self._id
@ -318,7 +308,7 @@ class TestVectorsWycheproof(unittest.TestCase):
def test_verify(self, tv): def test_verify(self, tv):
self._id = "Wycheproof RSA PKCS$#1 Test #" + str(tv.id) self._id = "Wycheproof RSA PKCS$#1 Test #" + str(tv.id)
hashed_msg = tv.hash_module.new(tv.msg) hashed_msg = tv.hash_module.new(tv.msg)
signer = pkcs1_15.new(tv.key) signer = pkcs1_15.new(tv.key)
try: try:

View file

@ -28,15 +28,13 @@
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
# =================================================================== # ===================================================================
import json
import unittest import unittest
from binascii import unhexlify
from Crypto.Util.py3compat import b, bchr from Crypto.Util.py3compat import b, bchr
from Crypto.Util.number import bytes_to_long from Crypto.Util.number import bytes_to_long
from Crypto.Util.strxor import strxor from Crypto.Util.strxor import strxor
from Crypto.SelfTest.st_common import list_test_cases from Crypto.SelfTest.st_common import list_test_cases
from Crypto.SelfTest.loader import load_tests from Crypto.SelfTest.loader import load_test_vectors, load_test_vectors_wycheproof
from Crypto.Hash import SHA1, SHA224, SHA256, SHA384, SHA512 from Crypto.Hash import SHA1, SHA224, SHA256, SHA384, SHA512
from Crypto.PublicKey import RSA from Crypto.PublicKey import RSA
@ -45,8 +43,6 @@ from Crypto.Signature import PKCS1_PSS
from Crypto.Signature.pss import MGF1 from Crypto.Signature.pss import MGF1
from Crypto.Util._file_system import pycryptodome_filename
def load_hash_by_name(hash_name): def load_hash_by_name(hash_name):
return __import__("Crypto.Hash." + hash_name, globals(), locals(), ["new"]) return __import__("Crypto.Hash." + hash_name, globals(), locals(), ["new"])
@ -118,11 +114,11 @@ class FIPS_PKCS1_Verify_Tests_KAT(unittest.TestCase):
pass pass
test_vectors_verify = load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "PKCS1-PSS"), test_vectors_verify = load_test_vectors(("Signature", "PKCS1-PSS"),
"SigVerPSS_186-3.rsp", "SigVerPSS_186-3.rsp",
"Signature Verification 186-3", "Signature Verification 186-3",
{ 'shaalg' : lambda x: x, {'shaalg': lambda x: x,
'result' : lambda x: x }) 'result': lambda x: x}) or []
for count, tv in enumerate(test_vectors_verify): for count, tv in enumerate(test_vectors_verify):
@ -136,7 +132,7 @@ for count, tv in enumerate(test_vectors_verify):
hash_module = load_hash_by_name(tv.shaalg.upper()) hash_module = load_hash_by_name(tv.shaalg.upper())
hash_obj = hash_module.new(tv.msg) hash_obj = hash_module.new(tv.msg)
public_key = RSA.construct([bytes_to_long(x) for x in (modulus, tv.e)]) # type: ignore public_key = RSA.construct([bytes_to_long(x) for x in (modulus, tv.e)]) # type: ignore
if tv.saltval != b("\x00"): if tv.saltval != b("\x00"):
prng = PRNG(tv.saltval) prng = PRNG(tv.saltval)
verifier = pss.new(public_key, salt_bytes=len(tv.saltval), rand_func=prng) verifier = pss.new(public_key, salt_bytes=len(tv.saltval), rand_func=prng)
@ -170,15 +166,15 @@ class FIPS_PKCS1_Sign_Tests_KAT(unittest.TestCase):
pass pass
test_vectors_sign = load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "PKCS1-PSS"), test_vectors_sign = load_test_vectors(("Signature", "PKCS1-PSS"),
"SigGenPSS_186-2.txt", "SigGenPSS_186-2.txt",
"Signature Generation 186-2", "Signature Generation 186-2",
{ 'shaalg' : lambda x: x }) {'shaalg': lambda x: x}) or []
test_vectors_sign += load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "PKCS1-PSS"), test_vectors_sign += load_test_vectors(("Signature", "PKCS1-PSS"),
"SigGenPSS_186-3.txt", "SigGenPSS_186-3.txt",
"Signature Generation 186-3", "Signature Generation 186-3",
{ 'shaalg' : lambda x: x }) {'shaalg': lambda x: x}) or []
for count, tv in enumerate(test_vectors_sign): for count, tv in enumerate(test_vectors_sign):
if isinstance(tv, str): if isinstance(tv, str):
@ -187,7 +183,7 @@ for count, tv in enumerate(test_vectors_sign):
modulus = tv.n modulus = tv.n
continue continue
if hasattr(tv, "e"): if hasattr(tv, "e"):
private_key = RSA.construct([bytes_to_long(x) for x in (modulus, tv.e, tv.d)]) # type: ignore private_key = RSA.construct([bytes_to_long(x) for x in (modulus, tv.e, tv.d)]) # type: ignore
continue continue
hash_module = load_hash_by_name(tv.shaalg.upper()) hash_module = load_hash_by_name(tv.shaalg.upper())
@ -280,41 +276,41 @@ class TestVectorsPSSWycheproof(unittest.TestCase):
self._id = "None" self._id = "None"
def add_tests(self, filename): def add_tests(self, filename):
comps = "Crypto.SelfTest.Signature.test_vectors.wycheproof".split(".")
with open(pycryptodome_filename(comps, filename), "rt") as file_in:
tv_tree = json.load(file_in)
for group in tv_tree['testGroups']: def filter_rsa(group):
return RSA.import_key(group['keyPem'])
key = RSA.import_key(group['keyPem']) def filter_sha(group):
hash_module = get_hash_module(group['sha']) return get_hash_module(group['sha'])
sLen = group['sLen']
assert group['type'] == "RsassaPssVerify" def filter_type(group):
assert group['mgf'] == "MGF1" type_name = group['type']
if type_name not in ("RsassaPssVerify", ):
raise ValueError("Unknown type name " + type_name)
mgf1_hash = get_hash_module(group['mgfSha']) def filter_slen(group):
return group['sLen']
def filter_mgf(group):
mgf = group['mgf']
if mgf not in ("MGF1", ):
raise ValueError("Unknown MGF " + mgf)
mgf1_hash = get_hash_module(group['mgfSha'])
def mgf(x, y, mh=mgf1_hash): def mgf(x, y, mh=mgf1_hash):
return MGF1(x, y, mh) return MGF1(x, y, mh)
from collections import namedtuple return mgf
TestVector = namedtuple('TestVector', 'id comment msg sig key mgf sLen hash_module valid warning')
for test in group['tests']: result = load_test_vectors_wycheproof(("Signature", "wycheproof"),
tv = TestVector( filename,
test['tcId'], "Wycheproof PSS signature (%s)" % filename,
test['comment'], group_tag={'key': filter_rsa,
unhexlify(test['msg']), 'hash_module': filter_sha,
unhexlify(test['sig']), 'sLen': filter_slen,
key, 'mgf': filter_mgf,
mgf, 'type': filter_type})
sLen, return result
hash_module,
test['result'] != "invalid",
test['result'] == "acceptable"
)
self.tv.append(tv)
def setUp(self): def setUp(self):
self.tv = [] self.tv = []
@ -370,10 +366,12 @@ def get_tests(config={}):
tests += list_test_cases(FIPS_PKCS1_Verify_Tests_KAT) tests += list_test_cases(FIPS_PKCS1_Verify_Tests_KAT)
tests += list_test_cases(FIPS_PKCS1_Sign_Tests_KAT) tests += list_test_cases(FIPS_PKCS1_Sign_Tests_KAT)
tests += [ TestVectorsPSSWycheproof(wycheproof_warnings) ] tests += [TestVectorsPSSWycheproof(wycheproof_warnings)]
return tests return tests
if __name__ == '__main__': if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests()) def suite():
return unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite') unittest.main(defaultTest='suite')

View file

@ -28,11 +28,19 @@
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
# =================================================================== # ===================================================================
import os
import re import re
import sys import json
import errno
import binascii import binascii
import warnings
from binascii import unhexlify
from Crypto.Util._file_system import pycryptodome_filename try:
import pycryptodome_test_vectors # type: ignore
test_vectors_available = True
except ImportError:
test_vectors_available = False
def _load_tests(dir_comps, file_in, description, conversions): def _load_tests(dir_comps, file_in, description, conversions):
@ -103,17 +111,94 @@ def _load_tests(dir_comps, file_in, description, conversions):
# This line is ignored # This line is ignored
return results return results
def load_tests(dir_comps, file_name, description, conversions):
def load_test_vectors(dir_comps, file_name, description, conversions):
"""Load and parse a test vector file """Load and parse a test vector file
This function returnis a list of objects, one per group of adjacent This function returns a list of objects, one per group of adjacent
KV lines or for a single line in the form "[.*]". KV lines or for a single line in the form "[.*]".
For a group of lines, the object has one attribute per line. For a group of lines, the object has one attribute per line.
""" """
description = "%s test (%s)" % (description, file_name)
with open(pycryptodome_filename(dir_comps, file_name)) as file_in: results = None
results = _load_tests(dir_comps, file_in, description, conversions)
try:
if not test_vectors_available:
raise FileNotFoundError(errno.ENOENT,
os.strerror(errno.ENOENT),
file_name)
description = "%s test (%s)" % (description, file_name)
init_dir = os.path.dirname(pycryptodome_test_vectors.__file__)
full_file_name = os.path.join(init_dir, *dir_comps, file_name)
with open(full_file_name) as file_in:
results = _load_tests(dir_comps, file_in, description, conversions)
except FileNotFoundError:
warnings.warn("Warning: skipping extended tests for " + description,
UserWarning,
stacklevel=2)
return results return results
def load_test_vectors_wycheproof(dir_comps, file_name, description,
root_tag={}, group_tag={}, unit_tag={}):
result = []
try:
if not test_vectors_available:
raise FileNotFoundError(errno.ENOENT,
os.strerror(errno.ENOENT),
file_name)
init_dir = os.path.dirname(pycryptodome_test_vectors.__file__)
full_file_name = os.path.join(init_dir, *dir_comps, file_name)
with open(full_file_name) as file_in:
tv_tree = json.load(file_in)
except FileNotFoundError:
warnings.warn("Warning: skipping extended tests for " + description,
UserWarning,
stacklevel=2)
return result
class TestVector(object):
pass
common_root = {}
for k, v in root_tag.items():
common_root[k] = v(tv_tree)
for group in tv_tree['testGroups']:
common_group = {}
for k, v in group_tag.items():
common_group[k] = v(group)
for test in group['tests']:
tv = TestVector()
for k, v in common_root.items():
setattr(tv, k, v)
for k, v in common_group.items():
setattr(tv, k, v)
tv.id = test['tcId']
tv.comment = test['comment']
for attr in 'key', 'iv', 'aad', 'msg', 'ct', 'tag', 'label', 'ikm', 'salt', 'info', 'okm', 'sig':
if attr in test:
setattr(tv, attr, unhexlify(test[attr]))
tv.filename = file_name
for k, v in unit_tag.items():
setattr(tv, k, v(test))
tv.valid = test['result'] != "invalid"
tv.warning = test['result'] == "acceptable"
result.append(tv)
return result

View file

@ -40,6 +40,7 @@ from Crypto.Math.Numbers import Integer
from Crypto.Hash import HMAC from Crypto.Hash import HMAC
from Crypto.PublicKey.ECC import EccKey from Crypto.PublicKey.ECC import EccKey
from Crypto.PublicKey.DSA import DsaKey
class DssSigScheme(object): class DssSigScheme(object):
@ -393,9 +394,11 @@ def new(key, mode, encoding='binary', randfunc=None):
if isinstance(key, EccKey): if isinstance(key, EccKey):
order = key._curve.order order = key._curve.order
private_key_attr = 'd' private_key_attr = 'd'
else: elif isinstance(key, DsaKey):
order = Integer(key.q) order = Integer(key.q)
private_key_attr = 'x' private_key_attr = 'x'
else:
raise ValueError("Unsupported key type " + str(type(key)))
if key.has_private(): if key.has_private():
private_key = getattr(key, private_key_attr) private_key = getattr(key, private_key_attr)

View file

@ -271,34 +271,6 @@ package_data = {
"Crypto.Signature" : [ "*.pyi" ], "Crypto.Signature" : [ "*.pyi" ],
"Crypto.IO" : [ "*.pyi" ], "Crypto.IO" : [ "*.pyi" ],
"Crypto.Util" : [ "*.pyi" ], "Crypto.Util" : [ "*.pyi" ],
"Crypto.SelfTest.Cipher" : [
"test_vectors/AES/*.*",
"test_vectors/TDES/*.*",
"test_vectors/wycheproof/*.*",
],
"Crypto.SelfTest.Hash" : [
"test_vectors/SHA1/*.*",
"test_vectors/SHA2/*.*",
"test_vectors/SHA3/*.*",
"test_vectors/keccak/*.*",
"test_vectors/BLAKE2s/*.*",
"test_vectors/BLAKE2b/*.*",
"test_vectors/wycheproof/*.*",
],
"Crypto.SelfTest.Signature" : [
"test_vectors/DSA/*.*",
"test_vectors/ECDSA/*.*",
"test_vectors/PKCS1-v1.5/*.*",
"test_vectors/PKCS1-PSS/*.*",
"test_vectors/wycheproof/*.*",
],
"Crypto.SelfTest.PublicKey" : [
"test_vectors/ECC/*.*",
"test_vectors/RSA/*.*",
],
"Crypto.SelfTest.Protocol" : [
"test_vectors/wycheproof/*.*",
],
} }
ext_modules = [ ext_modules = [
@ -494,7 +466,7 @@ setup(
'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.9',
], ],
license="BSD, Public Domain, Apache", license="BSD, Public Domain",
packages=packages, packages=packages,
package_dir={"": "lib"}, package_dir={"": "lib"},
package_data=package_data, package_data=package_data,

231
test_vectors/LICENSE.rst Normal file
View file

@ -0,0 +1,231 @@
BSD license
===========
All direct contributions to PyCryptodome are released under the following
license. The copyright of each piece belongs to the respective author.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Apache 2.0 license (Wycheproof)
===============================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

4
test_vectors/MANIFEST.in Normal file
View file

@ -0,0 +1,4 @@
include MANIFEST.in
include setup.py
graft pycryptodome_test_vectors
global-exclude __pycache__ *.pyc

Some files were not shown because too many files have changed in this diff Show more