mirror of
https://github.com/Legrandin/pycryptodome.git
synced 2025-10-19 16:03:45 +00:00
Move test vectors in a separate package
This commit is contained in:
parent
6ccdb9a200
commit
eda4f65718
363 changed files with 1198 additions and 1021 deletions
9
.github/workflows/integration.yml
vendored
9
.github/workflows/integration.yml
vendored
|
@ -60,8 +60,13 @@ jobs:
|
|||
if: matrix.os == 'windows-latest' && matrix.python-version == '2.7'
|
||||
run: choco install vcpython27
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install pycryptodome-test-vectors
|
||||
|
||||
- name: Test
|
||||
run: python -bb setup.py test
|
||||
run: |
|
||||
python -bb setup.py test
|
||||
|
||||
mypy:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -73,7 +78,7 @@ jobs:
|
|||
python-version: 3.9
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install mypy
|
||||
pip install mypy pycryptodome-test-vectors
|
||||
- name: Test
|
||||
run: |
|
||||
mypy lib/
|
||||
|
|
13
INSTALL.rst
13
INSTALL.rst
|
@ -12,7 +12,8 @@ PyCryptodome can be used as:
|
|||
In this case, all modules are installed under the ``Crypto`` package.
|
||||
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
|
||||
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::
|
||||
|
||||
pip install pycryptodome-test-vectors
|
||||
python -m Cryptodome.SelfTest
|
||||
|
||||
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
|
||||
$ pip install pycryptodomex
|
||||
$ pip install pycryptodome-test-vectors
|
||||
$ python -m Cryptodome.SelfTest
|
||||
|
||||
For Python 3.x::
|
||||
|
||||
$ sudo apt-get install build-essential python3-dev
|
||||
$ pip install pycryptodomex
|
||||
$ pip install pycryptodome-test-vectors
|
||||
$ python3 -m Cryptodome.SelfTest
|
||||
|
||||
For PyPy::
|
||||
|
||||
$ sudo apt-get install build-essential pypy-dev
|
||||
$ pip install pycryptodomex
|
||||
$ pip install pycryptodome-test-vectors
|
||||
$ pypy -m Cryptodome.SelfTest
|
||||
|
||||
Compiling in Linux Fedora
|
||||
|
@ -72,18 +77,21 @@ For Python 2.x::
|
|||
|
||||
$ sudo yum install gcc gmp python-devel
|
||||
$ pip install pycryptodomex
|
||||
$ pip install pycryptodome-test-vectors
|
||||
$ python -m Cryptodome.SelfTest
|
||||
|
||||
For Python 3.x::
|
||||
|
||||
$ sudo yum install gcc gmp python3-devel
|
||||
$ pip install pycryptodomex
|
||||
$ pip install pycryptodome-test-vectors
|
||||
$ python3 -m Cryptodome.SelfTest
|
||||
|
||||
For PyPy::
|
||||
|
||||
$ sudo yum install gcc gmp pypy-devel
|
||||
$ pip install pycryptodomex
|
||||
$ pip install pycryptodome-test-vectors
|
||||
$ pypy -m Cryptodome.SelfTest
|
||||
|
||||
|
||||
|
@ -134,6 +142,7 @@ components freely made available by Microsoft.
|
|||
|
||||
#. To make sure everything work fine, run the test suite::
|
||||
|
||||
> pip install pycryptodome-test-vectors
|
||||
> python -m Cryptodome.SelfTest
|
||||
|
||||
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::
|
||||
|
||||
> pip install pycryptodome-test-vectors
|
||||
> python -m Cryptodome.SelfTest
|
||||
|
||||
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::
|
||||
|
||||
> pip install pycryptodome-test-vectors
|
||||
> python -m Cryptodome.SelfTest
|
||||
|
||||
Documentation
|
||||
|
|
205
LICENSE.rst
205
LICENSE.rst
|
@ -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
|
||||
and users. As a general statement, OCB can be freely used for software not meant
|
||||
for military purposes. Contact your attorney for further information.
|
||||
|
||||
Apache 2.0 license (Wycheproof)
|
||||
===============================
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
|
@ -31,12 +31,13 @@
|
|||
import unittest
|
||||
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.Util.py3compat import tobytes, is_string
|
||||
from Crypto.Cipher import AES, DES3, DES
|
||||
from Crypto.Hash import SHAKE128
|
||||
|
||||
|
||||
def get_tag_random(tag, length):
|
||||
return SHAKE128.new(data=tobytes(tag)).read(length)
|
||||
|
||||
|
@ -311,11 +312,13 @@ class CbcTests(BlockChainingTests):
|
|||
class NistBlockChainingVectors(unittest.TestCase):
|
||||
|
||||
def _do_kat_aes_test(self, file_name):
|
||||
test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "AES"),
|
||||
file_name,
|
||||
"AES KAT",
|
||||
{ "count" : lambda x: int(x) } )
|
||||
assert(test_vectors)
|
||||
|
||||
test_vectors = load_test_vectors(("Cipher", "AES"),
|
||||
file_name,
|
||||
"AES CBC KAT",
|
||||
{ "count" : lambda x: int(x) } )
|
||||
if test_vectors is None:
|
||||
return
|
||||
|
||||
direction = None
|
||||
for tv in test_vectors:
|
||||
|
@ -337,11 +340,13 @@ class NistBlockChainingVectors(unittest.TestCase):
|
|||
|
||||
# See Section 6.4.2 in AESAVS
|
||||
def _do_mct_aes_test(self, file_name):
|
||||
test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "AES"),
|
||||
file_name,
|
||||
"AES Montecarlo",
|
||||
{ "count" : lambda x: int(x) } )
|
||||
assert(test_vectors)
|
||||
|
||||
test_vectors = load_test_vectors(("Cipher", "AES"),
|
||||
file_name,
|
||||
"AES CBC Montecarlo",
|
||||
{ "count" : lambda x: int(x) } )
|
||||
if test_vectors is None:
|
||||
return
|
||||
|
||||
direction = None
|
||||
for tv in test_vectors:
|
||||
|
@ -370,11 +375,13 @@ class NistBlockChainingVectors(unittest.TestCase):
|
|||
assert False
|
||||
|
||||
def _do_tdes_test(self, file_name):
|
||||
test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "TDES"),
|
||||
file_name,
|
||||
"TDES CBC KAT",
|
||||
{ "count" : lambda x: int(x) } )
|
||||
assert(test_vectors)
|
||||
|
||||
test_vectors = load_test_vectors(("Cipher", "TDES"),
|
||||
file_name,
|
||||
"TDES CBC KAT",
|
||||
{ "count" : lambda x: int(x) } )
|
||||
if test_vectors is None:
|
||||
return
|
||||
|
||||
direction = None
|
||||
for tv in test_vectors:
|
||||
|
|
|
@ -28,18 +28,18 @@
|
|||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# ===================================================================
|
||||
|
||||
import json
|
||||
import unittest
|
||||
from binascii import unhexlify
|
||||
|
||||
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.Cipher import AES
|
||||
from Crypto.Hash import SHAKE128
|
||||
|
||||
from Crypto.Util._file_system import pycryptodome_filename
|
||||
from Crypto.Util.strxor import strxor
|
||||
|
||||
|
||||
def get_tag_random(tag, length):
|
||||
return SHAKE128.new(data=tobytes(tag)).read(length)
|
||||
|
||||
|
@ -830,27 +830,14 @@ class TestVectorsWycheproof(unittest.TestCase):
|
|||
self._id = "None"
|
||||
|
||||
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):
|
||||
pass
|
||||
self.tv = []
|
||||
def filter_tag(group):
|
||||
return group['tagSize'] // 8
|
||||
|
||||
for group in tv_tree['testGroups']:
|
||||
tag_size = group['tagSize'] // 8
|
||||
for test in group['tests']:
|
||||
tv = TestVector()
|
||||
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)
|
||||
self.tv = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
|
||||
"aes_ccm_test.json",
|
||||
"Wycheproof AES CCM",
|
||||
group_tag={'tag_size': filter_tag})
|
||||
|
||||
def shortDescription(self):
|
||||
return self._id
|
||||
|
@ -865,7 +852,7 @@ class TestVectorsWycheproof(unittest.TestCase):
|
|||
|
||||
try:
|
||||
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:
|
||||
if len(tv.iv) not in range(7, 13 + 1, 2) and "Length of parameter 'nonce'" in str(e):
|
||||
assert not tv.valid
|
||||
|
@ -887,7 +874,7 @@ class TestVectorsWycheproof(unittest.TestCase):
|
|||
|
||||
try:
|
||||
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:
|
||||
if len(tv.iv) not in range(7, 13 + 1, 2) and "Length of parameter 'nonce'" in str(e):
|
||||
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:
|
||||
return
|
||||
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)
|
||||
ct_corrupt = strxor(tv.ct, b"\x00" * (len(tv.ct) - 1) + b"\x01")
|
||||
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(CcmFSMTests)
|
||||
tests += [TestVectors()]
|
||||
tests += [ TestVectorsWycheproof(wycheproof_warnings) ]
|
||||
tests += [TestVectorsWycheproof(wycheproof_warnings)]
|
||||
|
||||
return tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
def suite():
|
||||
unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
|
|
@ -31,18 +31,19 @@
|
|||
import unittest
|
||||
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.Util.py3compat import tobytes, is_string
|
||||
from Crypto.Cipher import AES, DES3, DES
|
||||
from Crypto.Hash import SHAKE128
|
||||
|
||||
from Crypto.SelfTest.Cipher.test_CBC import BlockChainingTests
|
||||
|
||||
|
||||
def get_tag_random(tag, length):
|
||||
return SHAKE128.new(data=tobytes(tag)).read(length)
|
||||
|
||||
|
||||
from Crypto.SelfTest.Cipher.test_CBC import BlockChainingTests
|
||||
|
||||
class CfbTests(BlockChainingTests):
|
||||
|
||||
aes_mode = AES.MODE_CFB
|
||||
|
@ -101,11 +102,13 @@ class CfbTests(BlockChainingTests):
|
|||
class NistCfbVectors(unittest.TestCase):
|
||||
|
||||
def _do_kat_aes_test(self, file_name, segment_size):
|
||||
test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "AES"),
|
||||
file_name,
|
||||
"AES CFB%d KAT" % segment_size,
|
||||
{ "count" : lambda x: int(x) } )
|
||||
assert(test_vectors)
|
||||
|
||||
test_vectors = load_test_vectors(("Cipher", "AES"),
|
||||
file_name,
|
||||
"AES CFB%d KAT" % segment_size,
|
||||
{ "count" : lambda x: int(x) } )
|
||||
if test_vectors is None:
|
||||
return
|
||||
|
||||
direction = None
|
||||
for tv in test_vectors:
|
||||
|
@ -127,11 +130,14 @@ class NistCfbVectors(unittest.TestCase):
|
|||
|
||||
# See Section 6.4.5 in AESAVS
|
||||
def _do_mct_aes_test(self, file_name, segment_size):
|
||||
test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "AES"),
|
||||
file_name,
|
||||
"AES CFB%d Montecarlo" % segment_size,
|
||||
{ "count" : lambda x: int(x) } )
|
||||
assert(test_vectors)
|
||||
|
||||
test_vectors = load_test_vectors(("Cipher", "AES"),
|
||||
file_name,
|
||||
"AES CFB%d Montecarlo" % segment_size,
|
||||
{ "count" : lambda x: int(x) } )
|
||||
if test_vectors is None:
|
||||
return
|
||||
|
||||
assert(segment_size in (8, 128))
|
||||
|
||||
direction = None
|
||||
|
@ -175,11 +181,13 @@ class NistCfbVectors(unittest.TestCase):
|
|||
assert False
|
||||
|
||||
def _do_tdes_test(self, file_name, segment_size):
|
||||
test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "TDES"),
|
||||
file_name,
|
||||
"AES CFB%d KAT" % segment_size,
|
||||
{ "count" : lambda x: int(x) } )
|
||||
assert(test_vectors)
|
||||
|
||||
test_vectors = load_test_vectors(("Cipher", "TDES"),
|
||||
file_name,
|
||||
"TDES CFB%d KAT" % segment_size,
|
||||
{ "count" : lambda x: int(x) } )
|
||||
if test_vectors is None:
|
||||
return
|
||||
|
||||
direction = None
|
||||
for tv in test_vectors:
|
||||
|
|
|
@ -28,11 +28,11 @@
|
|||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# ===================================================================
|
||||
|
||||
import json
|
||||
import unittest
|
||||
from binascii import unhexlify
|
||||
|
||||
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.Cipher import ChaCha20_Poly1305
|
||||
from Crypto.Hash import SHAKE128
|
||||
|
@ -625,29 +625,18 @@ class TestVectorsWycheproof(unittest.TestCase):
|
|||
self._id = "None"
|
||||
|
||||
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):
|
||||
pass
|
||||
result = []
|
||||
def filter_tag(group):
|
||||
return group['tagSize'] // 8
|
||||
|
||||
for group in tv_tree['testGroups']:
|
||||
tag_size = group['tagSize'] // 8
|
||||
for test in group['tests']:
|
||||
tv = TestVector()
|
||||
tv.tag_size = tag_size
|
||||
def filter_algo(root):
|
||||
return root['algorithm']
|
||||
|
||||
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"
|
||||
tv.algo = tv_tree['algorithm']
|
||||
|
||||
result.append(tv)
|
||||
result = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
|
||||
filename,
|
||||
"Wycheproof ChaCha20-Poly1305",
|
||||
root_tag={'algo': filter_algo},
|
||||
group_tag={'tag_size': filter_tag})
|
||||
return result
|
||||
|
||||
def setUp(self):
|
||||
|
|
|
@ -31,7 +31,7 @@ from Crypto.Cipher import DES3
|
|||
|
||||
from Crypto.Util.strxor import strxor_c
|
||||
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
|
||||
|
||||
# This is a list of (plaintext, ciphertext, key, description) tuples.
|
||||
|
@ -56,11 +56,13 @@ test_data = [
|
|||
nist_tdes_mmt_files = ("TECBMMT2.rsp", "TECBMMT3.rsp")
|
||||
|
||||
for tdes_file in nist_tdes_mmt_files:
|
||||
test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "TDES"),
|
||||
tdes_file,
|
||||
"TDES ECB (%s)" % tdes_file,
|
||||
{ "count" : lambda x: int(x) } )
|
||||
assert(test_vectors)
|
||||
|
||||
test_vectors = load_test_vectors(
|
||||
("Cipher", "TDES"),
|
||||
tdes_file,
|
||||
"TDES ECB (%s)" % tdes_file,
|
||||
{"count": lambda x: int(x)}) or []
|
||||
|
||||
for index, tv in enumerate(test_vectors):
|
||||
|
||||
# The test vector file contains some directive lines
|
||||
|
@ -107,7 +109,7 @@ class CheckParity(unittest.TestCase):
|
|||
|
||||
# K1 == K2 (with different 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):
|
||||
|
@ -128,7 +130,7 @@ class DegenerateToDESTest(unittest.TestCase):
|
|||
|
||||
# K1 == K2 == K3
|
||||
self.assertRaises(ValueError, DES3.new,
|
||||
sub_key1 *3,
|
||||
sub_key1 * 3,
|
||||
DES3.MODE_ECB)
|
||||
|
||||
# K2 == K3 (parity is ignored)
|
||||
|
@ -184,7 +186,10 @@ def get_tests(config={}):
|
|||
|
||||
if __name__ == '__main__':
|
||||
import unittest
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
|
||||
def suite():
|
||||
unittest.TestSuite(get_tests())
|
||||
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
# vim:set ts=4 sw=4 sts=4 expandtab:
|
||||
|
|
|
@ -28,16 +28,15 @@
|
|||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# ===================================================================
|
||||
|
||||
import json
|
||||
import unittest
|
||||
from binascii import unhexlify
|
||||
|
||||
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.Cipher import AES, DES3
|
||||
from Crypto.Hash import SHAKE128
|
||||
|
||||
from Crypto.Util._file_system import pycryptodome_filename
|
||||
from Crypto.Util.strxor import strxor
|
||||
|
||||
|
||||
|
@ -653,27 +652,14 @@ class TestVectorsWycheproof(unittest.TestCase):
|
|||
self._id = "None"
|
||||
|
||||
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):
|
||||
pass
|
||||
self.tv = []
|
||||
def filter_tag(group):
|
||||
return group['tagSize'] // 8
|
||||
|
||||
for group in tv_tree['testGroups']:
|
||||
tag_size = group['tagSize'] // 8
|
||||
for test in group['tests']:
|
||||
tv = TestVector()
|
||||
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)
|
||||
self.tv = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
|
||||
"aes_eax_test.json",
|
||||
"Wycheproof EAX",
|
||||
group_tag={'tag_size': filter_tag})
|
||||
|
||||
def shortDescription(self):
|
||||
return self._id
|
||||
|
|
|
@ -30,18 +30,16 @@
|
|||
|
||||
from __future__ import print_function
|
||||
|
||||
import json
|
||||
import unittest
|
||||
from binascii import unhexlify
|
||||
|
||||
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.Cipher import AES
|
||||
from Crypto.Hash import SHAKE128, SHA256
|
||||
|
||||
from Crypto.Util._file_system import pycryptodome_filename
|
||||
from Crypto.Util.strxor import strxor
|
||||
|
||||
|
||||
|
@ -561,7 +559,7 @@ class TestVectors(unittest.TestCase):
|
|||
'feedfacedeadbeeffeedfacedeadbeefabaddad2',
|
||||
'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' +
|
||||
'1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39',
|
||||
'42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e' +
|
||||
'42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e' +
|
||||
'21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091',
|
||||
'5bc94fbc3221a5db94fae95ae7121a47',
|
||||
'feffe9928665731c6d6a8f9467308308',
|
||||
|
@ -586,7 +584,7 @@ class TestVectors(unittest.TestCase):
|
|||
'619cc5aefffe0bfa462af43c1699d050',
|
||||
'feffe9928665731c6d6a8f9467308308',
|
||||
'9313225df88406e555909c5aff5269aa' +
|
||||
'6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b5254'+
|
||||
'6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b5254' +
|
||||
'16aedbf5a0de6a57a637b39b'
|
||||
),
|
||||
(
|
||||
|
@ -701,7 +699,7 @@ class TestVectors(unittest.TestCase):
|
|||
'a44a8266ee1c8eb0c8b5d4cf5ae9f19a',
|
||||
'feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308',
|
||||
'9313225df88406e555909c5aff5269aa' +
|
||||
'6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b5254'+
|
||||
'6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b5254' +
|
||||
'16aedbf5a0de6a57a637b39b'
|
||||
)
|
||||
]
|
||||
|
@ -767,13 +765,13 @@ class TestVectorsGueronKrasnov(unittest.TestCase):
|
|||
self.assertEqual(digest, digest2)
|
||||
|
||||
|
||||
|
||||
class NISTTestVectorsGCM(unittest.TestCase):
|
||||
|
||||
def __init__(self, a):
|
||||
self.use_clmul = True
|
||||
unittest.TestCase.__init__(self, a)
|
||||
|
||||
|
||||
class NISTTestVectorsGCM_no_clmul(unittest.TestCase):
|
||||
|
||||
def __init__(self, a):
|
||||
|
@ -781,17 +779,17 @@ class NISTTestVectorsGCM_no_clmul(unittest.TestCase):
|
|||
unittest.TestCase.__init__(self, a)
|
||||
|
||||
|
||||
test_vectors_nist = load_tests(
|
||||
("Crypto", "SelfTest", "Cipher", "test_vectors", "AES"),
|
||||
test_vectors_nist = load_test_vectors(
|
||||
("Cipher", "AES"),
|
||||
"gcmDecrypt128.rsp",
|
||||
"GCM decrypt",
|
||||
{ "count" : lambda x: int(x) })
|
||||
{"count": lambda x: int(x)}) or []
|
||||
|
||||
test_vectors_nist += load_tests(
|
||||
("Crypto", "SelfTest", "Cipher", "test_vectors", "AES"),
|
||||
test_vectors_nist += load_test_vectors(
|
||||
("Cipher", "AES"),
|
||||
"gcmEncryptExtIV128.rsp",
|
||||
"GCM encrypt",
|
||||
{ "count" : lambda x: int(x) })
|
||||
{"count": lambda x: int(x)}) or []
|
||||
|
||||
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):
|
||||
|
||||
self.description = tv.desc
|
||||
cipher = AES.new(tv.key, AES.MODE_GCM, nonce=tv.iv,
|
||||
self.description = tv.desc
|
||||
cipher = AES.new(tv.key, AES.MODE_GCM, nonce=tv.iv,
|
||||
mac_len=len(tv.tag), use_clmul=self.use_clmul)
|
||||
cipher.update(tv.aad)
|
||||
if "FAIL" in tv.others:
|
||||
self.assertRaises(ValueError, cipher.decrypt_and_verify,
|
||||
cipher.update(tv.aad)
|
||||
if "FAIL" in tv.others:
|
||||
self.assertRaises(ValueError, cipher.decrypt_and_verify,
|
||||
tv.ct, tv.tag)
|
||||
else:
|
||||
pt = cipher.decrypt_and_verify(tv.ct, tv.tag)
|
||||
self.assertEqual(pt, tv.pt)
|
||||
else:
|
||||
pt = cipher.decrypt_and_verify(tv.ct, tv.tag)
|
||||
self.assertEqual(pt, tv.pt)
|
||||
|
||||
setattr(NISTTestVectorsGCM, "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"
|
||||
|
||||
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):
|
||||
pass
|
||||
self.tv = []
|
||||
def filter_tag(group):
|
||||
return group['tagSize'] // 8
|
||||
|
||||
for group in tv_tree['testGroups']:
|
||||
tag_size = group['tagSize'] // 8
|
||||
for test in group['tests']:
|
||||
tv = TestVector()
|
||||
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)
|
||||
self.tv = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
|
||||
"aes_gcm_test.json",
|
||||
"Wycheproof GCM",
|
||||
group_tag={'tag_size': filter_tag})
|
||||
|
||||
def shortDescription(self):
|
||||
return self._id
|
||||
|
@ -860,7 +845,7 @@ class TestVectorsWycheproof(unittest.TestCase):
|
|||
|
||||
try:
|
||||
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:
|
||||
if len(tv.iv) == 0 and "Nonce cannot be empty" in str(e):
|
||||
return
|
||||
|
@ -878,7 +863,7 @@ class TestVectorsWycheproof(unittest.TestCase):
|
|||
|
||||
try:
|
||||
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:
|
||||
if len(tv.iv) == 0 and "Nonce cannot be empty" in str(e):
|
||||
return
|
||||
|
@ -899,7 +884,7 @@ class TestVectorsWycheproof(unittest.TestCase):
|
|||
if len(tv.iv) == 0 or len(tv.ct) < 1:
|
||||
return
|
||||
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)
|
||||
ct_corrupt = strxor(tv.ct, b"\x00" * (len(tv.ct) - 1) + b"\x01")
|
||||
self.assertRaises(ValueError, cipher.decrypt_and_verify, ct_corrupt, tv.tag)
|
||||
|
@ -941,16 +926,16 @@ def get_tests(config={}):
|
|||
tests = []
|
||||
tests += list_test_cases(GcmTests)
|
||||
tests += list_test_cases(GcmFSMTests)
|
||||
tests += [ TestVectors() ]
|
||||
tests += [ TestVectorsWycheproof(wycheproof_warnings) ]
|
||||
tests += [TestVectors()]
|
||||
tests += [TestVectorsWycheproof(wycheproof_warnings)]
|
||||
tests += list_test_cases(TestVectorsGueronKrasnov)
|
||||
tests += [ TestVariableLength() ]
|
||||
tests += [TestVariableLength()]
|
||||
if config.get('slow_tests'):
|
||||
tests += list_test_cases(NISTTestVectorsGCM)
|
||||
|
||||
if _cpu_features.have_clmul():
|
||||
tests += [ TestVectorsWycheproof(wycheproof_warnings, use_clmul=False) ]
|
||||
tests += [ TestVariableLength(use_clmul = False) ]
|
||||
tests += [TestVectorsWycheproof(wycheproof_warnings, use_clmul=False)]
|
||||
tests += [TestVariableLength(use_clmul=False)]
|
||||
if config.get('slow_tests'):
|
||||
tests += list_test_cases(NISTTestVectorsGCM_no_clmul)
|
||||
else:
|
||||
|
@ -960,5 +945,6 @@ def get_tests(config={}):
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
def suite():
|
||||
unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
|
|
@ -35,6 +35,7 @@ from Crypto.SelfTest.st_common import list_test_cases
|
|||
from Crypto.Util.py3compat import tobytes
|
||||
from Crypto.Cipher import AES, DES3, DES
|
||||
from Crypto.Hash import SHAKE128
|
||||
from Crypto.SelfTest.loader import load_test_vectors_wycheproof
|
||||
|
||||
def get_tag_random(tag, length):
|
||||
return SHAKE128.new(data=tobytes(tag)).read(length)
|
||||
|
|
|
@ -33,11 +33,12 @@ import unittest
|
|||
from binascii import unhexlify
|
||||
|
||||
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.Cipher import AES
|
||||
from Crypto.Hash import SHAKE128
|
||||
|
||||
from Crypto.Util._file_system import pycryptodome_filename
|
||||
from Crypto.Util.strxor import strxor
|
||||
|
||||
|
||||
|
@ -453,23 +454,9 @@ class TestVectorsWycheproof(unittest.TestCase):
|
|||
self._id = "None"
|
||||
|
||||
def setUp(self):
|
||||
comps = "Crypto.SelfTest.Cipher.test_vectors.wycheproof".split(".")
|
||||
with open(pycryptodome_filename(comps, "aes_siv_cmac_test.json"), "rt") as file_in:
|
||||
tv_tree = json.load(file_in)
|
||||
|
||||
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)
|
||||
self.tv = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
|
||||
"aes_siv_cmac_test.json",
|
||||
"Wycheproof AES SIV")
|
||||
|
||||
def shortDescription(self):
|
||||
return self._id
|
||||
|
@ -510,23 +497,9 @@ class TestVectorsWycheproof2(unittest.TestCase):
|
|||
self._id = "None"
|
||||
|
||||
def setUp(self):
|
||||
comps = "Crypto.SelfTest.Cipher.test_vectors.wycheproof".split(".")
|
||||
with open(pycryptodome_filename(comps, "aead_aes_siv_cmac_test.json"), "rt") as file_in:
|
||||
tv_tree = json.load(file_in)
|
||||
|
||||
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)
|
||||
self.tv = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
|
||||
"aead_aes_siv_cmac_test.json",
|
||||
"Wycheproof AEAD SIV")
|
||||
|
||||
def shortDescription(self):
|
||||
return self._id
|
||||
|
|
|
@ -32,7 +32,8 @@ from Crypto import Random
|
|||
from Crypto.Cipher import PKCS1_v1_5 as PKCS
|
||||
from Crypto.Util.py3compat import b
|
||||
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):
|
||||
"""Remove white spaces, tabs, and new lines from a string"""
|
||||
|
@ -187,31 +188,15 @@ class TestVectorsWycheproof(unittest.TestCase):
|
|||
self._id = "None"
|
||||
|
||||
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):
|
||||
pass
|
||||
result = []
|
||||
def filter_rsa(group):
|
||||
return RSA.import_key(group['privateKeyPem'])
|
||||
|
||||
for group in tv_tree['testGroups']:
|
||||
|
||||
rsa_key = RSA.import_key(group['privateKeyPem'])
|
||||
|
||||
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)
|
||||
result = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
|
||||
filename,
|
||||
"Wycheproof PKCS#1v1.5 (%s)" % filename,
|
||||
group_tag={'rsa_key': filter_rsa}
|
||||
)
|
||||
return result
|
||||
|
||||
def setUp(self):
|
||||
|
|
|
@ -20,11 +20,10 @@
|
|||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
import json
|
||||
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.Cipher import PKCS1_OAEP as PKCS
|
||||
|
@ -33,21 +32,23 @@ from Crypto import Random
|
|||
from Crypto.Signature.pss import MGF1
|
||||
|
||||
from Crypto.Util.py3compat import b, bchr
|
||||
from Crypto.Util._file_system import pycryptodome_filename
|
||||
|
||||
|
||||
def rws(t):
|
||||
"""Remove white spaces, tabs, and new lines from a string"""
|
||||
for c in ['\n', '\t', ' ']:
|
||||
t = t.replace(c,'')
|
||||
t = t.replace(c, '')
|
||||
return t
|
||||
|
||||
|
||||
def t2b(t):
|
||||
"""Convert a text string with bytes in hex form to a byte string"""
|
||||
clean = rws(t)
|
||||
if len(clean)%2 == 1:
|
||||
if len(clean) % 2 == 1:
|
||||
raise ValueError("Even number of characters expected")
|
||||
return a2b_hex(clean)
|
||||
|
||||
|
||||
class PKCS1_OAEP_Tests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
@ -267,98 +268,106 @@ class PKCS1_OAEP_Tests(unittest.TestCase):
|
|||
)
|
||||
|
||||
def testEncrypt1(self):
|
||||
# Verify encryption using all test vectors
|
||||
for test in self._testData:
|
||||
# Build the key
|
||||
comps = [ int(rws(test[0][x]),16) for x in ('n','e') ]
|
||||
key = RSA.construct(comps)
|
||||
# RNG that takes its random numbers from a pool given
|
||||
# at initialization
|
||||
class randGen:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
self.idx = 0
|
||||
def __call__(self, N):
|
||||
r = self.data[self.idx:N]
|
||||
self.idx += N
|
||||
return r
|
||||
# The real test
|
||||
cipher = PKCS.new(key, test[4], randfunc=randGen(t2b(test[3])))
|
||||
ct = cipher.encrypt(t2b(test[1]))
|
||||
self.assertEqual(ct, t2b(test[2]))
|
||||
# Verify encryption using all test vectors
|
||||
for test in self._testData:
|
||||
# Build the key
|
||||
comps = [int(rws(test[0][x]), 16) for x in ('n', 'e')]
|
||||
key = RSA.construct(comps)
|
||||
|
||||
# RNG that takes its random numbers from a pool given
|
||||
# at initialization
|
||||
class randGen:
|
||||
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
self.idx = 0
|
||||
|
||||
def __call__(self, N):
|
||||
r = self.data[self.idx:N]
|
||||
self.idx += N
|
||||
return r
|
||||
|
||||
# The real test
|
||||
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):
|
||||
# Verify that encryption fails if plaintext is too long
|
||||
pt = '\x00'*(128-2*20-2+1)
|
||||
cipher = PKCS.new(self.key1024)
|
||||
self.assertRaises(ValueError, cipher.encrypt, pt)
|
||||
# Verify that encryption fails if plaintext is too long
|
||||
pt = '\x00'*(128-2*20-2+1)
|
||||
cipher = PKCS.new(self.key1024)
|
||||
self.assertRaises(ValueError, cipher.encrypt, pt)
|
||||
|
||||
def testDecrypt1(self):
|
||||
# Verify decryption using all test vectors
|
||||
for test in self._testData:
|
||||
# Build the key
|
||||
comps = [ int(rws(test[0][x]),16) for x in ('n','e','d') ]
|
||||
key = RSA.construct(comps)
|
||||
# The real test
|
||||
cipher = PKCS.new(key, test[4])
|
||||
pt = cipher.decrypt(t2b(test[2]))
|
||||
self.assertEqual(pt, t2b(test[1]))
|
||||
# Verify decryption using all test vectors
|
||||
for test in self._testData:
|
||||
# Build the key
|
||||
comps = [int(rws(test[0][x]),16) for x in ('n', 'e', 'd')]
|
||||
key = RSA.construct(comps)
|
||||
# The real test
|
||||
cipher = PKCS.new(key, test[4])
|
||||
pt = cipher.decrypt(t2b(test[2]))
|
||||
self.assertEqual(pt, t2b(test[1]))
|
||||
|
||||
def testDecrypt2(self):
|
||||
# Simplest possible negative tests
|
||||
for ct_size in (127,128,129):
|
||||
cipher = PKCS.new(self.key1024)
|
||||
self.assertRaises(ValueError, cipher.decrypt, bchr(0x00)*ct_size)
|
||||
# Simplest possible negative tests
|
||||
for ct_size in (127, 128, 129):
|
||||
cipher = PKCS.new(self.key1024)
|
||||
self.assertRaises(ValueError, cipher.decrypt, bchr(0x00)*ct_size)
|
||||
|
||||
def testEncryptDecrypt1(self):
|
||||
# Encrypt/Decrypt messages of length [0..128-2*20-2]
|
||||
for pt_len in range(0,128-2*20-2):
|
||||
pt = self.rng(pt_len)
|
||||
cipher = PKCS.new(self.key1024)
|
||||
ct = cipher.encrypt(pt)
|
||||
pt2 = cipher.decrypt(ct)
|
||||
self.assertEqual(pt,pt2)
|
||||
# Encrypt/Decrypt messages of length [0..128-2*20-2]
|
||||
for pt_len in range(0, 128-2*20-2):
|
||||
pt = self.rng(pt_len)
|
||||
cipher = PKCS.new(self.key1024)
|
||||
ct = cipher.encrypt(pt)
|
||||
pt2 = cipher.decrypt(ct)
|
||||
self.assertEqual(pt, pt2)
|
||||
|
||||
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
|
||||
def localRng(N):
|
||||
global asked
|
||||
asked += N
|
||||
return self.rng(N)
|
||||
# Verify that OAEP is friendly to all hashes
|
||||
for hashmod in (MD2,MD5,SHA1,SHA256,RIPEMD160):
|
||||
# Verify that encrypt() asks for as many random bytes
|
||||
# as the hash output size
|
||||
asked = 0
|
||||
pt = self.rng(40)
|
||||
cipher = PKCS.new(self.key1024, hashmod, randfunc=localRng)
|
||||
ct = cipher.encrypt(pt)
|
||||
self.assertEqual(cipher.decrypt(ct), pt)
|
||||
self.assertEqual(asked, hashmod.digest_size)
|
||||
asked += N
|
||||
return self.rng(N)
|
||||
|
||||
# Verify that OAEP is friendly to all hashes
|
||||
for hashmod in (MD2, MD5, SHA1, SHA256, RIPEMD160):
|
||||
# Verify that encrypt() asks for as many random bytes
|
||||
# as the hash output size
|
||||
asked = 0
|
||||
pt = self.rng(40)
|
||||
cipher = PKCS.new(self.key1024, hashmod, randfunc=localRng)
|
||||
ct = cipher.encrypt(pt)
|
||||
self.assertEqual(cipher.decrypt(ct), pt)
|
||||
self.assertEqual(asked, hashmod.digest_size)
|
||||
|
||||
def testEncryptDecrypt3(self):
|
||||
# Verify that OAEP supports labels
|
||||
pt = self.rng(35)
|
||||
xlabel = self.rng(22)
|
||||
cipher = PKCS.new(self.key1024, label=xlabel)
|
||||
ct = cipher.encrypt(pt)
|
||||
self.assertEqual(cipher.decrypt(ct), pt)
|
||||
# Verify that OAEP supports labels
|
||||
pt = self.rng(35)
|
||||
xlabel = self.rng(22)
|
||||
cipher = PKCS.new(self.key1024, label=xlabel)
|
||||
ct = cipher.encrypt(pt)
|
||||
self.assertEqual(cipher.decrypt(ct), pt)
|
||||
|
||||
def 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
|
||||
# Helper function to monitor what's requested from MGF
|
||||
def newMGF(seed,maskLen):
|
||||
global mgfcalls
|
||||
mgfcalls += 1
|
||||
return bchr(0x00)*maskLen
|
||||
mgfcalls = 0
|
||||
pt = self.rng(32)
|
||||
cipher = PKCS.new(self.key1024, mgfunc=newMGF)
|
||||
ct = cipher.encrypt(pt)
|
||||
self.assertEqual(mgfcalls, 2)
|
||||
self.assertEqual(cipher.decrypt(ct), pt)
|
||||
mgfcalls += 1
|
||||
return b'\x00' * maskLen
|
||||
|
||||
mgfcalls = 0
|
||||
pt = self.rng(32)
|
||||
cipher = PKCS.new(self.key1024, mgfunc=newMGF)
|
||||
ct = cipher.encrypt(pt)
|
||||
self.assertEqual(mgfcalls, 2)
|
||||
self.assertEqual(cipher.decrypt(ct), pt)
|
||||
|
||||
def testByteArray(self):
|
||||
pt = b("XER")
|
||||
|
@ -384,59 +393,49 @@ class TestVectorsWycheproof(unittest.TestCase):
|
|||
self._id = "None"
|
||||
|
||||
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):
|
||||
pass
|
||||
result = []
|
||||
def filter_rsa(group):
|
||||
return RSA.import_key(group['privateKeyPem'])
|
||||
|
||||
for group in tv_tree['testGroups']:
|
||||
|
||||
rsa_key = RSA.import_key(group['privateKeyPem'])
|
||||
def filter_sha(group):
|
||||
if group['sha'] == "SHA-1":
|
||||
hash_mod = SHA1
|
||||
return SHA1
|
||||
elif group['sha'] == "SHA-224":
|
||||
hash_mod = SHA224
|
||||
return SHA224
|
||||
elif group['sha'] == "SHA-256":
|
||||
hash_mod = SHA256
|
||||
return SHA256
|
||||
elif group['sha'] == "SHA-384":
|
||||
hash_mod = SHA384
|
||||
return SHA384
|
||||
elif group['sha'] == "SHA-512":
|
||||
hash_mod = SHA512
|
||||
return SHA512
|
||||
else:
|
||||
raise ValueError("Unknown sha " + group['sha'])
|
||||
|
||||
def filter_mgf(group):
|
||||
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":
|
||||
mgf = lambda x,y: MGF1(x, y, SHA224)
|
||||
return lambda x, y: MGF1(x, y, SHA224)
|
||||
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":
|
||||
mgf = lambda x,y: MGF1(x, y, SHA384)
|
||||
return lambda x, y: MGF1(x, y, SHA384)
|
||||
elif group['mgfSha'] == "SHA-512":
|
||||
mgf = lambda x,y: MGF1(x, y, SHA512)
|
||||
return lambda x, y: MGF1(x, y, SHA512)
|
||||
else:
|
||||
raise ValueError("Unknown mgf/sha " + group['mgfSha'])
|
||||
|
||||
for test in group['tests']:
|
||||
tv = TestVector()
|
||||
def filter_algo(group):
|
||||
return "%s with MGF1/%s" % (group['sha'], group['mgfSha'])
|
||||
|
||||
tv.rsa_key = rsa_key
|
||||
tv.hash_mod = hash_mod
|
||||
tv.mgf = mgf
|
||||
tv.algo = "%s with MGF1/%s" % (group['sha'], group['mgfSha'])
|
||||
|
||||
tv.id = test['tcId']
|
||||
tv.comment = test['comment']
|
||||
for attr in 'msg', 'ct', 'label':
|
||||
setattr(tv, attr, unhexlify(test[attr]))
|
||||
tv.valid = test['result'] != "invalid"
|
||||
tv.warning = test['result'] == "acceptable"
|
||||
|
||||
result.append(tv)
|
||||
result = load_test_vectors_wycheproof(("Cipher", "wycheproof"),
|
||||
filename,
|
||||
"Wycheproof PKCS#1 OAEP (%s)" % filename,
|
||||
group_tag={'rsa_key': filter_rsa,
|
||||
'hash_mod': filter_sha,
|
||||
'mgf': filter_mgf,
|
||||
'algo': filter_algo}
|
||||
)
|
||||
return result
|
||||
|
||||
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_misc_test.json"))
|
||||
|
||||
|
||||
def shortDescription(self):
|
||||
return self._id
|
||||
|
||||
|
@ -499,8 +497,10 @@ def get_tests(config={}):
|
|||
tests += [TestVectorsWycheproof(wycheproof_warnings, skip_slow_tests)]
|
||||
return tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
def suite():
|
||||
unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
# vim:set ts=4 sw=4 sts=4 expandtab:
|
||||
|
|
|
@ -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)
|
||||
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))
|
||||
|
||||
if oid is not None:
|
||||
|
|
|
@ -28,13 +28,14 @@
|
|||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# ===================================================================
|
||||
|
||||
import os
|
||||
import re
|
||||
import unittest
|
||||
import warnings
|
||||
from binascii import unhexlify, hexlify
|
||||
|
||||
from Crypto.Util.py3compat import tobytes
|
||||
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.Hash import BLAKE2b, BLAKE2s
|
||||
|
@ -112,7 +113,7 @@ class Blake2Test(unittest.TestCase):
|
|||
self.failUnless(isinstance(digest, type(b"digest")))
|
||||
|
||||
def test_update_after_digest(self):
|
||||
msg=b"rrrrttt"
|
||||
msg = b"rrrrttt"
|
||||
|
||||
# Normally, update() cannot be done after digest()
|
||||
h = self.BLAKE2.new(digest_bits=256, data=msg[:4])
|
||||
|
@ -262,14 +263,9 @@ class Blake2sTest(Blake2Test):
|
|||
|
||||
class Blake2OfficialTestVector(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
test_vector_file = pycryptodome_filename(
|
||||
("Crypto", "SelfTest", "Hash", "test_vectors", self.name),
|
||||
self.name.lower() + "-test.txt")
|
||||
|
||||
def _load_tests(self, test_vector_file):
|
||||
expected = "in"
|
||||
self.test_vectors = []
|
||||
test_vectors = []
|
||||
with open(test_vector_file, "rt") as test_vector_fd:
|
||||
for line_number, line in enumerate(test_vector_fd):
|
||||
|
||||
|
@ -294,7 +290,26 @@ class Blake2OfficialTestVector(unittest.TestCase):
|
|||
else:
|
||||
result = bin_value
|
||||
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):
|
||||
for (input_data, key, result) in self.test_vectors:
|
||||
|
@ -323,12 +338,8 @@ class Blake2sOfficialTestVector(Blake2OfficialTestVector):
|
|||
|
||||
class Blake2TestVector1(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
test_vector_file = pycryptodome_filename(
|
||||
("Crypto", "SelfTest", "Hash", "test_vectors", self.name),
|
||||
"tv1.txt")
|
||||
|
||||
self.test_vectors = []
|
||||
def _load_tests(self, test_vector_file):
|
||||
test_vectors = []
|
||||
with open(test_vector_file, "rt") as test_vector_fd:
|
||||
for line_number, line in enumerate(test_vector_fd):
|
||||
if line.strip() == "" or line.startswith("#"):
|
||||
|
@ -338,7 +349,25 @@ class Blake2TestVector1(unittest.TestCase):
|
|||
raise ValueError("Incorrect test vector format (line %d)"
|
||||
% 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):
|
||||
|
||||
|
@ -368,12 +397,8 @@ class Blake2sTestVector1(Blake2TestVector1):
|
|||
|
||||
class Blake2TestVector2(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
test_vector_file = pycryptodome_filename(
|
||||
("Crypto", "SelfTest", "Hash", "test_vectors", self.name),
|
||||
"tv2.txt")
|
||||
|
||||
self.test_vectors = []
|
||||
def _load_tests(self, test_vector_file):
|
||||
test_vectors = []
|
||||
with open(test_vector_file, "rt") as test_vector_fd:
|
||||
for line_number, line in enumerate(test_vector_fd):
|
||||
if line.strip() == "" or line.startswith("#"):
|
||||
|
@ -382,10 +407,27 @@ class Blake2TestVector2(unittest.TestCase):
|
|||
if not res:
|
||||
raise ValueError("Incorrect test vector format (line %d)"
|
||||
% line_number)
|
||||
|
||||
key_size = int(res.group(1))
|
||||
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):
|
||||
|
||||
|
@ -435,5 +477,6 @@ def get_tests(config={}):
|
|||
|
||||
if __name__ == '__main__':
|
||||
import unittest
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
def suite():
|
||||
return unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
|
|
@ -43,10 +43,10 @@ from Crypto.Hash import CMAC
|
|||
from Crypto.Cipher import AES, DES3
|
||||
from Crypto.Hash import SHAKE128
|
||||
|
||||
from Crypto.Util._file_system import pycryptodome_filename
|
||||
from Crypto.Util.strxor import strxor
|
||||
|
||||
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.
|
||||
test_data = [
|
||||
|
@ -366,27 +366,14 @@ class TestVectorsWycheproof(unittest.TestCase):
|
|||
self._id = "None"
|
||||
|
||||
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):
|
||||
pass
|
||||
self.tv = []
|
||||
def filter_tag(group):
|
||||
return group['tagSize'] // 8
|
||||
|
||||
for group in tv_tree['testGroups']:
|
||||
tag_size = group['tagSize'] // 8
|
||||
for test in group['tests']:
|
||||
tv = TestVector()
|
||||
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)
|
||||
self.tv = load_test_vectors_wycheproof(("Hash", "wycheproof"),
|
||||
"aes_cmac_test.json",
|
||||
"Wycheproof CMAC",
|
||||
group_tag={'tag_size': filter_tag})
|
||||
|
||||
def shortDescription(self):
|
||||
return self._id
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
from binascii import hexlify
|
||||
|
||||
from Crypto.SelfTest.loader import load_tests
|
||||
from Crypto.SelfTest.loader import load_test_vectors
|
||||
|
||||
# Test vectors from various sources
|
||||
# This is a list of (expected_result, input[, description]) tuples.
|
||||
|
@ -55,10 +55,10 @@ def get_tests(config={}):
|
|||
|
||||
tests = []
|
||||
|
||||
test_vectors = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA1"),
|
||||
test_vectors = load_test_vectors(("Hash", "SHA1"),
|
||||
"SHA1ShortMsg.rsp",
|
||||
"KAT SHA-1",
|
||||
{ "len" : lambda x: int(x) } )
|
||||
{ "len" : lambda x: int(x) } ) or []
|
||||
|
||||
test_data = test_data_various[:]
|
||||
for tv in test_vectors:
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
import unittest
|
||||
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.Hash import SHA3_224 as SHA3
|
||||
from Crypto.Util.py3compat import b
|
||||
|
@ -56,10 +56,10 @@ def get_tests(config={}):
|
|||
|
||||
tests = []
|
||||
|
||||
test_vectors = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA3"),
|
||||
test_vectors = load_test_vectors(("Hash", "SHA3"),
|
||||
"ShortMsgKAT_SHA3-224.txt",
|
||||
"KAT SHA-3 224",
|
||||
{ "len" : lambda x: int(x) } )
|
||||
{ "len" : lambda x: int(x) } ) or []
|
||||
|
||||
test_data = []
|
||||
for tv in test_vectors:
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
import unittest
|
||||
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.Hash import SHA3_256 as SHA3
|
||||
from Crypto.Util.py3compat import b
|
||||
|
@ -56,10 +56,10 @@ def get_tests(config={}):
|
|||
|
||||
tests = []
|
||||
|
||||
test_vectors = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA3"),
|
||||
test_vectors = load_test_vectors(("Hash", "SHA3"),
|
||||
"ShortMsgKAT_SHA3-256.txt",
|
||||
"KAT SHA-3 256",
|
||||
{ "len" : lambda x: int(x) } )
|
||||
{ "len" : lambda x: int(x) } ) or []
|
||||
|
||||
test_data = []
|
||||
for tv in test_vectors:
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
import unittest
|
||||
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.Hash import SHA3_384 as SHA3
|
||||
from Crypto.Util.py3compat import b
|
||||
|
@ -56,10 +56,10 @@ def get_tests(config={}):
|
|||
|
||||
tests = []
|
||||
|
||||
test_vectors = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA3"),
|
||||
test_vectors = load_test_vectors(("Hash", "SHA3"),
|
||||
"ShortMsgKAT_SHA3-384.txt",
|
||||
"KAT SHA-3 384",
|
||||
{ "len" : lambda x: int(x) } )
|
||||
{ "len" : lambda x: int(x) } ) or []
|
||||
|
||||
test_data = []
|
||||
for tv in test_vectors:
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
import unittest
|
||||
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.Hash import SHA3_512 as SHA3
|
||||
from Crypto.Util.py3compat import b
|
||||
|
@ -56,10 +56,10 @@ def get_tests(config={}):
|
|||
|
||||
tests = []
|
||||
|
||||
test_vectors = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA3"),
|
||||
test_vectors = load_test_vectors(("Hash", "SHA3"),
|
||||
"ShortMsgKAT_SHA3-512.txt",
|
||||
"KAT SHA-3 512",
|
||||
{ "len" : lambda x: int(x) } )
|
||||
{ "len" : lambda x: int(x) } ) or []
|
||||
|
||||
test_data = []
|
||||
for tv in test_vectors:
|
||||
|
|
|
@ -28,7 +28,7 @@ from binascii import hexlify
|
|||
|
||||
from Crypto.Hash import SHA512
|
||||
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
|
||||
# This is a list of (expected_result, input[, description]) tuples.
|
||||
|
@ -52,10 +52,10 @@ test_data_512_other = [
|
|||
|
||||
def get_tests_SHA512():
|
||||
|
||||
test_vectors = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA2"),
|
||||
test_vectors = load_test_vectors(("Hash", "SHA2"),
|
||||
"SHA512ShortMsg.rsp",
|
||||
"KAT SHA-512",
|
||||
{ "len" : lambda x: int(x) } )
|
||||
{"len": lambda x: int(x)}) or []
|
||||
|
||||
test_data = test_data_512_other[:]
|
||||
for tv in test_vectors:
|
||||
|
@ -76,10 +76,10 @@ def get_tests_SHA512():
|
|||
|
||||
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",
|
||||
"KAT SHA-512/224",
|
||||
{ "len" : lambda x: int(x) } )
|
||||
{"len": lambda x: int(x)}) or []
|
||||
|
||||
test_data = []
|
||||
for tv in test_vectors:
|
||||
|
@ -101,10 +101,10 @@ def get_tests_SHA512_224():
|
|||
|
||||
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",
|
||||
"KAT SHA-512/256",
|
||||
{ "len" : lambda x: int(x) } )
|
||||
{"len": lambda x: int(x)}) or []
|
||||
|
||||
test_data = []
|
||||
for tv in test_vectors:
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
import unittest
|
||||
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.Hash import SHAKE128, SHAKE256
|
||||
|
@ -91,10 +91,10 @@ class SHAKEVectors(unittest.TestCase):
|
|||
pass
|
||||
|
||||
|
||||
test_vectors_128 = load_tests(("Crypto", "SelfTest", "Hash", "test_vectors", "SHA3"),
|
||||
test_vectors_128 = load_test_vectors(("Hash", "SHA3"),
|
||||
"ShortMsgKAT_SHAKE128.txt",
|
||||
"Short Messages KAT SHAKE128",
|
||||
{ "len" : lambda x: int(x) } )
|
||||
{ "len" : lambda x: int(x) } ) or []
|
||||
|
||||
for idx, tv in enumerate(test_vectors_128):
|
||||
if tv.len == 0:
|
||||
|
@ -110,10 +110,10 @@ for idx, tv in enumerate(test_vectors_128):
|
|||
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",
|
||||
"Short Messages KAT SHAKE256",
|
||||
{ "len" : lambda x: int(x) } )
|
||||
{ "len" : lambda x: int(x) } ) or []
|
||||
|
||||
for idx, tv in enumerate(test_vectors_256):
|
||||
if tv.len == 0:
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
import unittest
|
||||
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.Hash import keccak
|
||||
|
@ -141,15 +141,15 @@ class KeccakVectors(unittest.TestCase):
|
|||
# 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",
|
||||
"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",
|
||||
"Long Messages KAT 224",
|
||||
{ "len" : lambda x: int(x) } )
|
||||
{"len": lambda x: int(x)}) or []
|
||||
|
||||
for idx, tv in enumerate(test_vectors_224):
|
||||
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",
|
||||
"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",
|
||||
"Long Messages KAT 256",
|
||||
{ "len" : lambda x: int(x) } )
|
||||
{ "len" : lambda x: int(x) } ) or []
|
||||
|
||||
for idx, tv in enumerate(test_vectors_256):
|
||||
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",
|
||||
"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",
|
||||
"Long Messages KAT 384",
|
||||
{ "len" : lambda x: int(x) } )
|
||||
{"len": lambda x: int(x)}) or []
|
||||
|
||||
for idx, tv in enumerate(test_vectors_384):
|
||||
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",
|
||||
"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",
|
||||
"Long Messages KAT 512",
|
||||
{ "len" : lambda x: int(x) } )
|
||||
{"len": lambda x: int(x)}) or []
|
||||
|
||||
for idx, tv in enumerate(test_vectors_512):
|
||||
if tv.len == 0:
|
||||
|
|
|
@ -20,13 +20,13 @@
|
|||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
import json
|
||||
import unittest
|
||||
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.loader import load_test_vectors_wycheproof
|
||||
from Crypto.Hash import SHA1, HMAC, SHA256, MD5, SHA224, SHA384, SHA512
|
||||
from Crypto.Cipher import AES, DES3
|
||||
|
||||
|
@ -34,7 +34,6 @@ from Crypto.Protocol.KDF import (PBKDF1, PBKDF2, _S2V, HKDF, scrypt,
|
|||
bcrypt, bcrypt_check)
|
||||
|
||||
from Crypto.Protocol.KDF import _bcrypt_decode
|
||||
from Crypto.Util._file_system import pycryptodome_filename
|
||||
|
||||
|
||||
def t2b(t):
|
||||
|
@ -59,7 +58,7 @@ class PBKDF1_Tests(unittest.TestCase):
|
|||
# Item #4: expected result (encoded in hex)
|
||||
_testData = (
|
||||
# From http://www.di-mgt.com.au/cryptoKDFs.html#examplespbkdf
|
||||
("password","78578E5A5D63CB06",16,1000,"DC19847E05C64D2FAF10EBFB4A3D2A20"),
|
||||
("password", "78578E5A5D63CB06", 16, 1000, "DC19847E05C64D2FAF10EBFB4A3D2A20"),
|
||||
)
|
||||
|
||||
def test1(self):
|
||||
|
@ -67,6 +66,7 @@ class PBKDF1_Tests(unittest.TestCase):
|
|||
res = PBKDF1(v[0], t2b(v[1]), v[2], v[3], SHA1)
|
||||
self.assertEqual(res, t2b(v[4]))
|
||||
|
||||
|
||||
class PBKDF2_Tests(unittest.TestCase):
|
||||
|
||||
# List of tuples with test data.
|
||||
|
@ -650,42 +650,29 @@ class TestVectorsHKDFWycheproof(unittest.TestCase):
|
|||
self._id = "None"
|
||||
|
||||
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']
|
||||
if algo_name == "HKDF-SHA-1":
|
||||
hash_module = SHA1
|
||||
elif algo_name == "HKDF-SHA-256":
|
||||
hash_module = SHA256
|
||||
elif algo_name == "HKDF-SHA-384":
|
||||
hash_module = SHA384
|
||||
elif algo_name == "HKDF-SHA-512":
|
||||
hash_module = SHA512
|
||||
else:
|
||||
raise ValueError("Unknown algorithm " + algo_name)
|
||||
def filter_algo(root):
|
||||
algo_name = root['algorithm']
|
||||
if algo_name == "HKDF-SHA-1":
|
||||
return SHA1
|
||||
elif algo_name == "HKDF-SHA-256":
|
||||
return SHA256
|
||||
elif algo_name == "HKDF-SHA-384":
|
||||
return SHA384
|
||||
elif algo_name == "HKDF-SHA-512":
|
||||
return SHA512
|
||||
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
|
||||
TestVector = namedtuple('TestVector', 'id comment ikm salt info size okm hash_module valid warning filename')
|
||||
|
||||
for test in group['tests']:
|
||||
tv = TestVector(
|
||||
test['tcId'],
|
||||
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)
|
||||
result = load_test_vectors_wycheproof(("Protocol", "wycheproof"),
|
||||
filename,
|
||||
"Wycheproof HMAC (%s)" % filename,
|
||||
root_tag={'hash_module': filter_algo},
|
||||
unit_tag={'size': filter_size})
|
||||
return result
|
||||
|
||||
def setUp(self):
|
||||
self.tv = []
|
||||
|
@ -733,7 +720,7 @@ def get_tests(config={}):
|
|||
tests += list_test_cases(PBKDF2_Tests)
|
||||
tests += list_test_cases(S2V_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(bcrypt_Tests)
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
import unittest
|
||||
import time
|
||||
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.ECC import EccPoint, _curves, EccKey
|
||||
|
@ -479,13 +479,12 @@ class TestEccPoint_PAI_P256(unittest.TestCase):
|
|||
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",
|
||||
"P-256 tests from point-at-infinity.org",
|
||||
{ "k" : lambda k: int(k),
|
||||
"x" : lambda x: int(x, 16),
|
||||
"y" : lambda y: int(y, 16)} )
|
||||
assert(tv_pai)
|
||||
{"k": lambda k: int(k),
|
||||
"x": lambda x: int(x, 16),
|
||||
"y": lambda y: int(y, 16)}) or []
|
||||
for tv in tv_pai:
|
||||
def new_test(self, scalar=tv.k, x=tv.x, y=tv.y):
|
||||
result = self.pointG * scalar
|
||||
|
@ -501,13 +500,12 @@ class TestEccPoint_PAI_P384(unittest.TestCase):
|
|||
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",
|
||||
"P-384 tests from point-at-infinity.org",
|
||||
{ "k" : lambda k: int(k),
|
||||
"x" : lambda x: int(x, 16),
|
||||
"y" : lambda y: int(y, 16)} )
|
||||
assert(tv_pai)
|
||||
{"k" : lambda k: int(k),
|
||||
"x" : lambda x: int(x, 16),
|
||||
"y" : lambda y: int(y, 16)}) or []
|
||||
for tv in tv_pai:
|
||||
def new_test(self, scalar=tv.k, x=tv.x, y=tv.y):
|
||||
result = self.pointG * scalar
|
||||
|
@ -523,13 +521,12 @@ class TestEccPoint_PAI_P521(unittest.TestCase):
|
|||
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",
|
||||
"P-521 tests from point-at-infinity.org",
|
||||
{ "k" : lambda k: int(k),
|
||||
"x" : lambda x: int(x, 16),
|
||||
"y" : lambda y: int(y, 16)} )
|
||||
assert(tv_pai)
|
||||
{"k": lambda k: int(k),
|
||||
"x": lambda x: int(x, 16),
|
||||
"y": lambda y: int(y, 16)}) or []
|
||||
for tv in tv_pai:
|
||||
def new_test(self, scalar=tv.k, x=tv.x, y=tv.y):
|
||||
result = self.pointG * scalar
|
||||
|
|
|
@ -28,21 +28,54 @@
|
|||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# ===================================================================
|
||||
|
||||
import os
|
||||
import errno
|
||||
import warnings
|
||||
import unittest
|
||||
from binascii import unhexlify
|
||||
|
||||
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.number import bytes_to_long
|
||||
from Crypto.Hash import SHAKE128
|
||||
|
||||
from Crypto.PublicKey import ECC
|
||||
|
||||
def load_file(filename, mode="rb"):
|
||||
comps = [ "Crypto", "SelfTest", "PublicKey", "test_vectors", "ECC" ]
|
||||
with open(pycryptodome_filename(comps, filename), mode) as fd:
|
||||
return fd.read()
|
||||
try:
|
||||
import pycryptodome_test_vectors # type: ignore
|
||||
test_vectors_available = True
|
||||
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):
|
||||
|
@ -86,13 +119,11 @@ def create_ref_keys_p521():
|
|||
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))
|
||||
|
||||
|
||||
# Create reference key pair
|
||||
# ref_private, ref_public = create_ref_keys_p521()
|
||||
|
||||
|
||||
def get_fixed_prng():
|
||||
return SHAKE128.new().update(b"SEED").read
|
||||
return SHAKE128.new().update(b"SEED").read
|
||||
|
||||
|
||||
class TestImport(unittest.TestCase):
|
||||
|
@ -103,7 +134,9 @@ class TestImport(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):
|
||||
key_file = load_file("ecc_p256_public.der")
|
||||
|
@ -229,7 +262,9 @@ class TestImport_P256(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):
|
||||
key_file = load_file("ecc_p384_public.der")
|
||||
|
@ -350,7 +385,9 @@ class TestImport_P384(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):
|
||||
key_file = load_file("ecc_p521_public.der")
|
||||
|
@ -471,7 +508,9 @@ class TestImport_P521(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):
|
||||
key_file = load_file("ecc_p256_public.der")
|
||||
|
@ -517,7 +556,7 @@ class TestExport_P256(unittest.TestCase):
|
|||
|
||||
def test_export_private_pkcs8_encrypted(self):
|
||||
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
|
||||
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",
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
decoded = ECC.import_key(encoded, "secret")
|
||||
self.assertEqual(self.ref_private, decoded)
|
||||
|
||||
|
@ -749,7 +788,9 @@ gVnJp9EBND/tHQ==
|
|||
|
||||
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):
|
||||
key_file = load_file("ecc_p384_public.der")
|
||||
|
@ -1016,7 +1057,9 @@ YC46ZRsnKNayw3wATdPjgja7L/DSII3nZK0G6KOOVwJBznT/e+zudUJYhZKaBLRx
|
|||
|
||||
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):
|
||||
key_file = load_file("ecc_p521_public.der")
|
||||
|
@ -1286,14 +1329,18 @@ vv6oYkMIIi7r5oQWAiQDrR2mlrrFDL9V7GH/r8SWQw==
|
|||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(TestImport)
|
||||
tests += list_test_cases(TestImport_P256)
|
||||
tests += list_test_cases(TestImport_P384)
|
||||
tests += list_test_cases(TestImport_P521)
|
||||
tests += list_test_cases(TestExport_P256)
|
||||
tests += list_test_cases(TestExport_P384)
|
||||
tests += list_test_cases(TestExport_P521)
|
||||
try:
|
||||
tests += list_test_cases(TestImport_P256)
|
||||
tests += list_test_cases(TestImport_P384)
|
||||
tests += list_test_cases(TestImport_P521)
|
||||
tests += list_test_cases(TestExport_P256)
|
||||
tests += list_test_cases(TestExport_P384)
|
||||
tests += list_test_cases(TestExport_P521)
|
||||
except MissingTestVectorException:
|
||||
pass
|
||||
return tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
|
|
@ -20,32 +20,57 @@
|
|||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
import unittest
|
||||
import os
|
||||
import re
|
||||
import errno
|
||||
import warnings
|
||||
import unittest
|
||||
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.SelfTest.st_common import *
|
||||
from Crypto.Util.py3compat import *
|
||||
from Crypto.SelfTest.st_common import a2b_hex, list_test_cases
|
||||
from Crypto.Util.py3compat import b, tostr
|
||||
from Crypto.Util.number import inverse
|
||||
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"):
|
||||
comps = [ "Crypto", "SelfTest", "PublicKey", "test_vectors", "RSA" ]
|
||||
with open(pycryptodome_filename(comps, filename), mode) as fd:
|
||||
return fd.read()
|
||||
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", "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'):
|
||||
import binascii
|
||||
chunks = [ binascii.b2a_base64(der[i:i+48]) for i in range(0, len(der), 48) ]
|
||||
pem = b('-----BEGIN %s KEY-----\n' % text)
|
||||
chunks = [binascii.b2a_base64(der[i:i+48]) for i in range(0, len(der), 48)]
|
||||
pem = b('-----BEGIN %s KEY-----\n' % text)
|
||||
pem += b('').join(chunks)
|
||||
pem += b('-----END %s KEY-----' % text)
|
||||
return pem
|
||||
|
||||
|
||||
class ImportKeyTests(unittest.TestCase):
|
||||
# 512-bit RSA key generated with openssl
|
||||
rsaKeyPEM = u'''-----BEGIN RSA PRIVATE KEY-----
|
||||
|
@ -71,7 +96,7 @@ BX85JB8zqwHB
|
|||
-----END PRIVATE KEY-----'''
|
||||
|
||||
# The same RSA private key as in rsaKeyPEM, but now encrypted
|
||||
rsaKeyEncryptedPEM=(
|
||||
rsaKeyEncryptedPEM = (
|
||||
|
||||
# PEM encryption
|
||||
# With DES and passphrase 'test'
|
||||
|
@ -507,6 +532,10 @@ class TestImport_2048(unittest.TestCase):
|
|||
key_file_ref = load_file("rsa2048_private.pem")
|
||||
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 = RSA.import_key(key_file)
|
||||
self.assertEqual(key_ref, key)
|
||||
|
@ -515,6 +544,10 @@ class TestImport_2048(unittest.TestCase):
|
|||
key_file = load_file("rsa2048_private_openssh.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_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_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_old = RSA.import_key(key_file_old)
|
||||
self.assertEqual(key, key_old)
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
# ===================================================================
|
||||
|
||||
import re
|
||||
import json
|
||||
import unittest
|
||||
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.PublicKey import DSA, ECC
|
||||
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._file_system import pycryptodome_filename
|
||||
from Crypto.Util.strxor import strxor
|
||||
|
||||
|
||||
def t2b(hexstring):
|
||||
ws = hexstring.replace(" ", "").replace("\n", "")
|
||||
|
@ -147,13 +143,15 @@ class FIPS_DSA_Tests(unittest.TestCase):
|
|||
signer = DSS.new(self.key_pub, 'fips-186-3')
|
||||
self.failIf(signer.can_sign())
|
||||
|
||||
|
||||
class FIPS_DSA_Tests_KAT(unittest.TestCase):
|
||||
pass
|
||||
|
||||
test_vectors_verify = load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "DSA"),
|
||||
"FIPS_186_3_SigVer.rsp",
|
||||
"Signature Verification 186-3",
|
||||
{'result' : lambda x: x})
|
||||
|
||||
test_vectors_verify = load_test_vectors(("Signature", "DSA"),
|
||||
"FIPS_186_3_SigVer.rsp",
|
||||
"Signature Verification 186-3",
|
||||
{'result': lambda x: x}) or []
|
||||
|
||||
for idx, tv in enumerate(test_vectors_verify):
|
||||
|
||||
|
@ -173,7 +171,7 @@ for idx, tv in enumerate(test_vectors_verify):
|
|||
hash_obj = hash_module.new(tv.msg)
|
||||
|
||||
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')
|
||||
|
||||
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)
|
||||
|
||||
|
||||
test_vectors_sign = load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "DSA"),
|
||||
"FIPS_186_3_SigGen.txt",
|
||||
"Signature Creation 186-3",
|
||||
{})
|
||||
test_vectors_sign = load_test_vectors(("Signature", "DSA"),
|
||||
"FIPS_186_3_SigGen.txt",
|
||||
"Signature Creation 186-3",
|
||||
{}) or []
|
||||
|
||||
for idx, tv in enumerate(test_vectors_sign):
|
||||
|
||||
|
@ -285,13 +283,13 @@ class FIPS_ECDSA_Tests_KAT(unittest.TestCase):
|
|||
pass
|
||||
|
||||
|
||||
test_vectors_verify = load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "ECDSA"),
|
||||
"SigVer.rsp",
|
||||
"ECDSA Signature Verification 186-3",
|
||||
{'result': lambda x: x,
|
||||
'qx': lambda x: int(x, 16),
|
||||
'qy': lambda x: int(x, 16),
|
||||
})
|
||||
test_vectors_verify = load_test_vectors(("Signature", "ECDSA"),
|
||||
"SigVer.rsp",
|
||||
"ECDSA Signature Verification 186-3",
|
||||
{'result': lambda x: x,
|
||||
'qx': lambda x: int(x, 16),
|
||||
'qy': lambda x: int(x, 16),
|
||||
}) or []
|
||||
|
||||
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)
|
||||
|
||||
|
||||
test_vectors_sign = load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "ECDSA"),
|
||||
"SigGen.txt",
|
||||
"ECDSA Signature Verification 186-3",
|
||||
{'d': lambda x: int(x, 16)})
|
||||
test_vectors_sign = load_test_vectors(("Signature", "ECDSA"),
|
||||
"SigGen.txt",
|
||||
"ECDSA Signature Verification 186-3",
|
||||
{'d': lambda x: int(x, 16)}) or []
|
||||
|
||||
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')
|
||||
new_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
|
||||
self.keys = new_keys
|
||||
|
||||
|
@ -900,26 +898,46 @@ class Det_ECDSA_Tests(unittest.TestCase):
|
|||
|
||||
def test_data_rfc6979_p256(self):
|
||||
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)
|
||||
result = signer.sign(hash_obj)
|
||||
self.assertEqual(r + s, result)
|
||||
|
||||
def test_data_rfc6979_p384(self):
|
||||
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)
|
||||
result = signer.sign(hash_obj)
|
||||
self.assertEqual(r + s, result)
|
||||
|
||||
def test_data_rfc6979_p521(self):
|
||||
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)
|
||||
result = signer.sign(hash_obj)
|
||||
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):
|
||||
|
||||
def __init__(self, wycheproof_warnings, slow_tests):
|
||||
|
@ -927,42 +945,29 @@ class TestVectorsDSAWycheproof(unittest.TestCase):
|
|||
self._wycheproof_warnings = wycheproof_warnings
|
||||
self._slow_tests = slow_tests
|
||||
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 = []
|
||||
|
||||
for group in tv_tree['testGroups']:
|
||||
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"
|
||||
def setUp(self):
|
||||
|
||||
from collections import namedtuple
|
||||
TestVector = namedtuple('TestVector', 'id comment msg sig key hash_module valid warning')
|
||||
def filter_dsa(group):
|
||||
return DSA.import_key(group['keyPem'])
|
||||
|
||||
for test in group['tests']:
|
||||
tv = TestVector(
|
||||
test['tcId'],
|
||||
test['comment'],
|
||||
unhexlify(test['msg']),
|
||||
unhexlify(test['sig']),
|
||||
key,
|
||||
hash_module,
|
||||
test['result'] != "invalid",
|
||||
test['result'] == "acceptable"
|
||||
)
|
||||
self.tv.append(tv)
|
||||
def filter_sha(group):
|
||||
return get_hash_module(group['sha'])
|
||||
|
||||
def filter_type(group):
|
||||
sig_type = group['type']
|
||||
if sig_type != 'DsaVerify':
|
||||
raise ValueError("Unknown signature type " + sig_type)
|
||||
return sig_type
|
||||
|
||||
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):
|
||||
return self._id
|
||||
|
@ -1001,62 +1006,39 @@ class TestVectorsECDSAWycheproof(unittest.TestCase):
|
|||
self._id = "None"
|
||||
|
||||
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
|
||||
if group['key']['curve'] in ('secp224r1', 'secp224k1', 'secp256k1',
|
||||
'brainpoolP224r1', 'brainpoolP224t1',
|
||||
'brainpoolP256r1', 'brainpoolP256t1',
|
||||
'brainpoolP320r1', 'brainpoolP320t1',
|
||||
'brainpoolP384r1', 'brainpoolP384t1',
|
||||
'brainpoolP512r1', 'brainpoolP512t1',
|
||||
):
|
||||
return None
|
||||
return ECC.import_key(group['keyPem'])
|
||||
|
||||
try:
|
||||
key = ECC.import_key(group['keyPem'])
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
hash_name = group['sha']
|
||||
if hash_name == "SHA-512":
|
||||
hash_module = SHA512
|
||||
elif hash_name == "SHA3-512":
|
||||
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']
|
||||
if encoding_name == "EcdsaVerify":
|
||||
encoding = "der"
|
||||
return "der"
|
||||
elif encoding_name == "EcdsaP1363Verify":
|
||||
encoding = "binary"
|
||||
return "binary"
|
||||
else:
|
||||
raise ValueError("Unknown signature type " + encoding_name)
|
||||
|
||||
from collections import namedtuple
|
||||
TestVector = namedtuple('TestVector', 'id comment msg encoding sig key hash_module valid warning filename')
|
||||
|
||||
for test in group['tests']:
|
||||
tv = TestVector(
|
||||
test['tcId'],
|
||||
test['comment'],
|
||||
unhexlify(test['msg']),
|
||||
encoding,
|
||||
unhexlify(test['sig']),
|
||||
key,
|
||||
hash_module,
|
||||
test['result'] != "invalid",
|
||||
test['result'] == "acceptable",
|
||||
filename
|
||||
)
|
||||
self.tv.append(tv)
|
||||
result = load_test_vectors_wycheproof(("Signature", "wycheproof"),
|
||||
filename,
|
||||
"Wycheproof ECDSA signature (%s)" % filename,
|
||||
group_tag={'key': filter_ecc,
|
||||
'hash_module': filter_sha,
|
||||
'encoding': filter_encoding,
|
||||
})
|
||||
self.tv += result
|
||||
|
||||
def setUp(self):
|
||||
self.tv = []
|
||||
|
@ -1101,6 +1083,10 @@ class TestVectorsECDSAWycheproof(unittest.TestCase):
|
|||
def test_verify(self, tv):
|
||||
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)
|
||||
signer = DSS.new(tv.key, 'fips-186-3', encoding=tv.encoding)
|
||||
try:
|
||||
|
@ -1134,12 +1120,13 @@ def get_tests(config={}):
|
|||
tests += list_test_cases(FIPS_DSA_Tests_KAT)
|
||||
tests += list_test_cases(FIPS_ECDSA_Tests_KAT)
|
||||
|
||||
tests += [ TestVectorsDSAWycheproof(wycheproof_warnings, slow_tests) ]
|
||||
tests += [ TestVectorsECDSAWycheproof(wycheproof_warnings, slow_tests) ]
|
||||
tests += [TestVectorsDSAWycheproof(wycheproof_warnings, slow_tests)]
|
||||
tests += [TestVectorsECDSAWycheproof(wycheproof_warnings, slow_tests)]
|
||||
|
||||
return tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
def suite():
|
||||
return unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
|
|
@ -36,7 +36,7 @@ from Crypto.Util.py3compat import bchr
|
|||
from Crypto.Util.number import bytes_to_long
|
||||
from Crypto.Util.strxor import strxor
|
||||
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,
|
||||
SHA3_224, SHA3_256, SHA3_512)
|
||||
|
@ -67,12 +67,12 @@ class FIPS_PKCS1_Verify_Tests_KAT(unittest.TestCase):
|
|||
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",
|
||||
"Signature Verification 186-3",
|
||||
{ 'shaalg' : lambda x: x,
|
||||
'd' : lambda x: int(x),
|
||||
'result' : lambda x: x })
|
||||
{'shaalg': lambda x: x,
|
||||
'd': lambda x: int(x),
|
||||
'result': lambda x: x}) or []
|
||||
|
||||
|
||||
for count, tv in enumerate(test_vectors_verify):
|
||||
|
@ -114,15 +114,15 @@ class FIPS_PKCS1_Sign_Tests_KAT(unittest.TestCase):
|
|||
pass
|
||||
|
||||
|
||||
test_vectors_sign = load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "PKCS1-v1.5"),
|
||||
"SigGen15_186-2.txt",
|
||||
"Signature Generation 186-2",
|
||||
{ 'shaalg' : lambda x: x })
|
||||
test_vectors_sign = load_test_vectors(("Signature", "PKCS1-v1.5"),
|
||||
"SigGen15_186-2.txt",
|
||||
"Signature Generation 186-2",
|
||||
{'shaalg': lambda x: x}) or []
|
||||
|
||||
test_vectors_sign += load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "PKCS1-v1.5"),
|
||||
"SigGen15_186-3.txt",
|
||||
"Signature Generation 186-3",
|
||||
{ 'shaalg' : lambda x: x })
|
||||
test_vectors_sign += load_test_vectors(("Signature", "PKCS1-v1.5"),
|
||||
"SigGen15_186-3.txt",
|
||||
"Signature Generation 186-3",
|
||||
{'shaalg': lambda x: x}) or []
|
||||
|
||||
for count, tv in enumerate(test_vectors_sign):
|
||||
if isinstance(tv, str):
|
||||
|
@ -254,59 +254,49 @@ class TestVectorsWycheproof(unittest.TestCase):
|
|||
self.add_tests("rsa_signature_test.json")
|
||||
|
||||
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):
|
||||
pass
|
||||
self.tv = []
|
||||
|
||||
for group in tv_tree['testGroups']:
|
||||
key = RSA.import_key(group['keyPem'])
|
||||
def filter_rsa(group):
|
||||
return RSA.import_key(group['keyPem'])
|
||||
|
||||
def filter_sha(group):
|
||||
hash_name = group['sha']
|
||||
if hash_name == "SHA-512":
|
||||
hash_module = SHA512
|
||||
return SHA512
|
||||
elif hash_name == "SHA-512/224":
|
||||
hash_module = SHA512.new(truncate="224")
|
||||
return SHA512.new(truncate="224")
|
||||
elif hash_name == "SHA-512/256":
|
||||
hash_module = SHA512.new(truncate="256")
|
||||
return SHA512.new(truncate="256")
|
||||
elif hash_name == "SHA3-512":
|
||||
hash_module = SHA3_512
|
||||
return SHA3_512
|
||||
elif hash_name == "SHA-384":
|
||||
hash_module = SHA384
|
||||
return SHA384
|
||||
elif hash_name == "SHA3-384":
|
||||
hash_module = SHA3_384
|
||||
return SHA3_384
|
||||
elif hash_name == "SHA-256":
|
||||
hash_module = SHA256
|
||||
return SHA256
|
||||
elif hash_name == "SHA3-256":
|
||||
hash_module = SHA3_256
|
||||
return SHA3_256
|
||||
elif hash_name == "SHA-224":
|
||||
hash_module = SHA224
|
||||
return SHA224
|
||||
elif hash_name == "SHA3-224":
|
||||
hash_module = SHA3_224
|
||||
return SHA3_224
|
||||
elif hash_name == "SHA-1":
|
||||
hash_module = SHA1
|
||||
return SHA1
|
||||
else:
|
||||
raise ValueError("Unknown hash algorithm: " + hash_name)
|
||||
|
||||
def filter_type(group):
|
||||
type_name = group['type']
|
||||
if type_name not in ("RsassaPkcs1Verify", "RsassaPkcs1Generate"):
|
||||
raise ValueError("Unknown type name " + type_name)
|
||||
|
||||
for test in group['tests']:
|
||||
tv = TestVector()
|
||||
|
||||
tv.id = test['tcId']
|
||||
tv.comment = test['comment']
|
||||
for attr in 'msg', 'sig':
|
||||
setattr(tv, attr, unhexlify(test[attr]))
|
||||
tv.key = key
|
||||
tv.hash_module = hash_module
|
||||
tv.valid = test['result'] != "invalid"
|
||||
tv.warning = test['result'] == "acceptable"
|
||||
self.tv.append(tv)
|
||||
result = load_test_vectors_wycheproof(("Signature", "wycheproof"),
|
||||
filename,
|
||||
"Wycheproof PKCS#1v1.5 signature (%s)" % filename,
|
||||
group_tag={'rsa_key': filter_rsa,
|
||||
'hash_mod': filter_sha,
|
||||
'type': filter_type})
|
||||
return result
|
||||
|
||||
def shortDescription(self):
|
||||
return self._id
|
||||
|
|
|
@ -28,15 +28,13 @@
|
|||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# ===================================================================
|
||||
|
||||
import json
|
||||
import unittest
|
||||
from binascii import unhexlify
|
||||
|
||||
from Crypto.Util.py3compat import b, bchr
|
||||
from Crypto.Util.number import bytes_to_long
|
||||
from Crypto.Util.strxor import strxor
|
||||
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.PublicKey import RSA
|
||||
|
@ -45,8 +43,6 @@ from Crypto.Signature import PKCS1_PSS
|
|||
|
||||
from Crypto.Signature.pss import MGF1
|
||||
|
||||
from Crypto.Util._file_system import pycryptodome_filename
|
||||
|
||||
|
||||
def load_hash_by_name(hash_name):
|
||||
return __import__("Crypto.Hash." + hash_name, globals(), locals(), ["new"])
|
||||
|
@ -118,11 +114,11 @@ class FIPS_PKCS1_Verify_Tests_KAT(unittest.TestCase):
|
|||
pass
|
||||
|
||||
|
||||
test_vectors_verify = load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "PKCS1-PSS"),
|
||||
"SigVerPSS_186-3.rsp",
|
||||
"Signature Verification 186-3",
|
||||
{ 'shaalg' : lambda x: x,
|
||||
'result' : lambda x: x })
|
||||
test_vectors_verify = load_test_vectors(("Signature", "PKCS1-PSS"),
|
||||
"SigVerPSS_186-3.rsp",
|
||||
"Signature Verification 186-3",
|
||||
{'shaalg': lambda x: x,
|
||||
'result': lambda x: x}) or []
|
||||
|
||||
|
||||
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_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"):
|
||||
prng = PRNG(tv.saltval)
|
||||
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
|
||||
|
||||
|
||||
test_vectors_sign = load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "PKCS1-PSS"),
|
||||
"SigGenPSS_186-2.txt",
|
||||
"Signature Generation 186-2",
|
||||
{ 'shaalg' : lambda x: x })
|
||||
test_vectors_sign = load_test_vectors(("Signature", "PKCS1-PSS"),
|
||||
"SigGenPSS_186-2.txt",
|
||||
"Signature Generation 186-2",
|
||||
{'shaalg': lambda x: x}) or []
|
||||
|
||||
test_vectors_sign += load_tests(("Crypto", "SelfTest", "Signature", "test_vectors", "PKCS1-PSS"),
|
||||
"SigGenPSS_186-3.txt",
|
||||
"Signature Generation 186-3",
|
||||
{ 'shaalg' : lambda x: x })
|
||||
test_vectors_sign += load_test_vectors(("Signature", "PKCS1-PSS"),
|
||||
"SigGenPSS_186-3.txt",
|
||||
"Signature Generation 186-3",
|
||||
{'shaalg': lambda x: x}) or []
|
||||
|
||||
for count, tv in enumerate(test_vectors_sign):
|
||||
if isinstance(tv, str):
|
||||
|
@ -187,7 +183,7 @@ for count, tv in enumerate(test_vectors_sign):
|
|||
modulus = tv.n
|
||||
continue
|
||||
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
|
||||
|
||||
hash_module = load_hash_by_name(tv.shaalg.upper())
|
||||
|
@ -280,41 +276,41 @@ class TestVectorsPSSWycheproof(unittest.TestCase):
|
|||
self._id = "None"
|
||||
|
||||
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'])
|
||||
hash_module = get_hash_module(group['sha'])
|
||||
sLen = group['sLen']
|
||||
def filter_sha(group):
|
||||
return get_hash_module(group['sha'])
|
||||
|
||||
assert group['type'] == "RsassaPssVerify"
|
||||
assert group['mgf'] == "MGF1"
|
||||
def filter_type(group):
|
||||
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):
|
||||
return MGF1(x, y, mh)
|
||||
|
||||
from collections import namedtuple
|
||||
TestVector = namedtuple('TestVector', 'id comment msg sig key mgf sLen hash_module valid warning')
|
||||
return mgf
|
||||
|
||||
for test in group['tests']:
|
||||
tv = TestVector(
|
||||
test['tcId'],
|
||||
test['comment'],
|
||||
unhexlify(test['msg']),
|
||||
unhexlify(test['sig']),
|
||||
key,
|
||||
mgf,
|
||||
sLen,
|
||||
hash_module,
|
||||
test['result'] != "invalid",
|
||||
test['result'] == "acceptable"
|
||||
)
|
||||
self.tv.append(tv)
|
||||
result = load_test_vectors_wycheproof(("Signature", "wycheproof"),
|
||||
filename,
|
||||
"Wycheproof PSS signature (%s)" % filename,
|
||||
group_tag={'key': filter_rsa,
|
||||
'hash_module': filter_sha,
|
||||
'sLen': filter_slen,
|
||||
'mgf': filter_mgf,
|
||||
'type': filter_type})
|
||||
return result
|
||||
|
||||
def setUp(self):
|
||||
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_Sign_Tests_KAT)
|
||||
|
||||
tests += [ TestVectorsPSSWycheproof(wycheproof_warnings) ]
|
||||
tests += [TestVectorsPSSWycheproof(wycheproof_warnings)]
|
||||
|
||||
return tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
def suite():
|
||||
return unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
|
|
@ -28,11 +28,19 @@
|
|||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# ===================================================================
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import json
|
||||
import errno
|
||||
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):
|
||||
|
@ -103,17 +111,94 @@ def _load_tests(dir_comps, file_in, description, conversions):
|
|||
# This line is ignored
|
||||
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
|
||||
|
||||
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 "[.*]".
|
||||
|
||||
For a group of lines, the object has one attribute per line.
|
||||
"""
|
||||
|
||||
description = "%s test (%s)" % (description, file_name)
|
||||
results = None
|
||||
|
||||
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)
|
||||
|
||||
with open(pycryptodome_filename(dir_comps, file_name)) as file_in:
|
||||
results = _load_tests(dir_comps, file_in, description, conversions)
|
||||
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
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ from Crypto.Math.Numbers import Integer
|
|||
|
||||
from Crypto.Hash import HMAC
|
||||
from Crypto.PublicKey.ECC import EccKey
|
||||
from Crypto.PublicKey.DSA import DsaKey
|
||||
|
||||
|
||||
class DssSigScheme(object):
|
||||
|
@ -393,9 +394,11 @@ def new(key, mode, encoding='binary', randfunc=None):
|
|||
if isinstance(key, EccKey):
|
||||
order = key._curve.order
|
||||
private_key_attr = 'd'
|
||||
else:
|
||||
elif isinstance(key, DsaKey):
|
||||
order = Integer(key.q)
|
||||
private_key_attr = 'x'
|
||||
else:
|
||||
raise ValueError("Unsupported key type " + str(type(key)))
|
||||
|
||||
if key.has_private():
|
||||
private_key = getattr(key, private_key_attr)
|
||||
|
|
30
setup.py
30
setup.py
|
@ -271,34 +271,6 @@ package_data = {
|
|||
"Crypto.Signature" : [ "*.pyi" ],
|
||||
"Crypto.IO" : [ "*.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 = [
|
||||
|
@ -494,7 +466,7 @@ setup(
|
|||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
],
|
||||
license="BSD, Public Domain, Apache",
|
||||
license="BSD, Public Domain",
|
||||
packages=packages,
|
||||
package_dir={"": "lib"},
|
||||
package_data=package_data,
|
||||
|
|
231
test_vectors/LICENSE.rst
Normal file
231
test_vectors/LICENSE.rst
Normal 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
4
test_vectors/MANIFEST.in
Normal 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
Loading…
Add table
Add a link
Reference in a new issue