slight update
This commit is contained in:
63
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/__init__.py
vendored
Normal file
63
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/__init__.py
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/__init__.py: Self-test for public key crypto
|
||||
#
|
||||
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
"""Self-test for public-key crypto"""
|
||||
|
||||
import unittest
|
||||
from Crypto.SelfTest.PublicKey import (test_DSA, test_RSA,
|
||||
test_ECC_NIST,
|
||||
test_ECC_Ed25519,
|
||||
test_ECC_Curve25519,
|
||||
test_ECC_Ed448,
|
||||
test_ECC_Curve448,
|
||||
test_import_DSA, test_import_RSA,
|
||||
test_import_ECC, test_ElGamal,
|
||||
test_import_Curve25519,
|
||||
test_import_Curve448)
|
||||
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += test_DSA.get_tests(config=config)
|
||||
tests += test_RSA.get_tests(config=config)
|
||||
tests += test_ECC_NIST.get_tests(config=config)
|
||||
tests += test_ECC_Ed25519.get_tests(config=config)
|
||||
tests += test_ECC_Curve25519.get_tests(config=config)
|
||||
tests += test_ECC_Ed448.get_tests(config=config)
|
||||
tests += test_ECC_Curve448.get_tests(config=config)
|
||||
|
||||
tests += test_import_DSA.get_tests(config=config)
|
||||
tests += test_import_RSA.get_tests(config=config)
|
||||
tests += test_import_ECC.get_tests(config=config)
|
||||
tests += test_import_Curve25519.get_tests(config=config)
|
||||
tests += test_import_Curve448.get_tests(config=config)
|
||||
|
||||
tests += test_ElGamal.get_tests(config=config)
|
||||
return tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
def suite():
|
||||
return unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
BIN
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/__pycache__/__init__.cpython-312.pyc
vendored
Normal file
BIN
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/__pycache__/__init__.cpython-312.pyc
vendored
Normal file
Binary file not shown.
BIN
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/__pycache__/test_DSA.cpython-312.pyc
vendored
Normal file
BIN
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/__pycache__/test_DSA.cpython-312.pyc
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/__pycache__/test_ECC_NIST.cpython-312.pyc
vendored
Normal file
BIN
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/__pycache__/test_ECC_NIST.cpython-312.pyc
vendored
Normal file
Binary file not shown.
BIN
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/__pycache__/test_ElGamal.cpython-312.pyc
vendored
Normal file
BIN
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/__pycache__/test_ElGamal.cpython-312.pyc
vendored
Normal file
Binary file not shown.
BIN
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/__pycache__/test_RSA.cpython-312.pyc
vendored
Normal file
BIN
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/__pycache__/test_RSA.cpython-312.pyc
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
247
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_DSA.py
vendored
Normal file
247
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_DSA.py
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_DSA.py: Self-test for the DSA primitive
|
||||
#
|
||||
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
"""Self-test suite for Crypto.PublicKey.DSA"""
|
||||
|
||||
import os
|
||||
from Crypto.Util.py3compat import *
|
||||
|
||||
import unittest
|
||||
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
|
||||
|
||||
def _sws(s):
|
||||
"""Remove whitespace from a text or byte string"""
|
||||
if isinstance(s,str):
|
||||
return "".join(s.split())
|
||||
else:
|
||||
return b("").join(s.split())
|
||||
|
||||
class DSATest(unittest.TestCase):
|
||||
# Test vector from "Appendix 5. Example of the DSA" of
|
||||
# "Digital Signature Standard (DSS)",
|
||||
# U.S. Department of Commerce/National Institute of Standards and Technology
|
||||
# FIPS 186-2 (+Change Notice), 2000 January 27.
|
||||
# http://csrc.nist.gov/publications/fips/fips186-2/fips186-2-change1.pdf
|
||||
|
||||
y = _sws("""19131871 d75b1612 a819f29d 78d1b0d7 346f7aa7 7bb62a85
|
||||
9bfd6c56 75da9d21 2d3a36ef 1672ef66 0b8c7c25 5cc0ec74
|
||||
858fba33 f44c0669 9630a76b 030ee333""")
|
||||
|
||||
g = _sws("""626d0278 39ea0a13 413163a5 5b4cb500 299d5522 956cefcb
|
||||
3bff10f3 99ce2c2e 71cb9de5 fa24babf 58e5b795 21925c9c
|
||||
c42e9f6f 464b088c c572af53 e6d78802""")
|
||||
|
||||
p = _sws("""8df2a494 492276aa 3d25759b b06869cb eac0d83a fb8d0cf7
|
||||
cbb8324f 0d7882e5 d0762fc5 b7210eaf c2e9adac 32ab7aac
|
||||
49693dfb f83724c2 ec0736ee 31c80291""")
|
||||
|
||||
q = _sws("""c773218c 737ec8ee 993b4f2d ed30f48e dace915f""")
|
||||
|
||||
x = _sws("""2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614""")
|
||||
|
||||
k = _sws("""358dad57 1462710f 50e254cf 1a376b2b deaadfbf""")
|
||||
k_inverse = _sws("""0d516729 8202e49b 4116ac10 4fc3f415 ae52f917""")
|
||||
m = b2a_hex(b("abc"))
|
||||
m_hash = _sws("""a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d""")
|
||||
r = _sws("""8bac1ab6 6410435c b7181f95 b16ab97c 92b341c0""")
|
||||
s = _sws("""41e2345f 1f56df24 58f426d1 55b4ba2d b6dcd8c8""")
|
||||
|
||||
def setUp(self):
|
||||
global DSA, Random, bytes_to_long, size
|
||||
from Crypto.PublicKey import DSA
|
||||
from Crypto import Random
|
||||
from Crypto.Util.number import bytes_to_long, inverse, size
|
||||
|
||||
self.dsa = DSA
|
||||
|
||||
def test_generate_1arg(self):
|
||||
"""DSA (default implementation) generated key (1 argument)"""
|
||||
dsaObj = self.dsa.generate(1024)
|
||||
self._check_private_key(dsaObj)
|
||||
pub = dsaObj.public_key()
|
||||
self._check_public_key(pub)
|
||||
|
||||
def test_generate_2arg(self):
|
||||
"""DSA (default implementation) generated key (2 arguments)"""
|
||||
dsaObj = self.dsa.generate(1024, Random.new().read)
|
||||
self._check_private_key(dsaObj)
|
||||
pub = dsaObj.public_key()
|
||||
self._check_public_key(pub)
|
||||
|
||||
def test_construct_4tuple(self):
|
||||
"""DSA (default implementation) constructed key (4-tuple)"""
|
||||
(y, g, p, q) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q)]
|
||||
dsaObj = self.dsa.construct((y, g, p, q))
|
||||
self._test_verification(dsaObj)
|
||||
|
||||
def test_construct_5tuple(self):
|
||||
"""DSA (default implementation) constructed key (5-tuple)"""
|
||||
(y, g, p, q, x) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q, self.x)]
|
||||
dsaObj = self.dsa.construct((y, g, p, q, x))
|
||||
self._test_signing(dsaObj)
|
||||
self._test_verification(dsaObj)
|
||||
|
||||
def test_construct_bad_key4(self):
|
||||
(y, g, p, q) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q)]
|
||||
tup = (y, g, p+1, q)
|
||||
self.assertRaises(ValueError, self.dsa.construct, tup)
|
||||
|
||||
tup = (y, g, p, q+1)
|
||||
self.assertRaises(ValueError, self.dsa.construct, tup)
|
||||
|
||||
tup = (y, 1, p, q)
|
||||
self.assertRaises(ValueError, self.dsa.construct, tup)
|
||||
|
||||
def test_construct_bad_key5(self):
|
||||
(y, g, p, q, x) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q, self.x)]
|
||||
tup = (y, g, p, q, x+1)
|
||||
self.assertRaises(ValueError, self.dsa.construct, tup)
|
||||
|
||||
tup = (y, g, p, q, q+10)
|
||||
self.assertRaises(ValueError, self.dsa.construct, tup)
|
||||
|
||||
def _check_private_key(self, dsaObj):
|
||||
# Check capabilities
|
||||
self.assertEqual(1, dsaObj.has_private())
|
||||
self.assertEqual(1, dsaObj.can_sign())
|
||||
self.assertEqual(0, dsaObj.can_encrypt())
|
||||
|
||||
# Sanity check key data
|
||||
self.assertEqual(1, dsaObj.p > dsaObj.q) # p > q
|
||||
self.assertEqual(160, size(dsaObj.q)) # size(q) == 160 bits
|
||||
self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q) # q is a divisor of p-1
|
||||
self.assertEqual(dsaObj.y, pow(dsaObj.g, dsaObj.x, dsaObj.p)) # y == g**x mod p
|
||||
self.assertEqual(1, 0 < dsaObj.x < dsaObj.q) # 0 < x < q
|
||||
|
||||
def _check_public_key(self, dsaObj):
|
||||
k = bytes_to_long(a2b_hex(self.k))
|
||||
m_hash = bytes_to_long(a2b_hex(self.m_hash))
|
||||
|
||||
# Check capabilities
|
||||
self.assertEqual(0, dsaObj.has_private())
|
||||
self.assertEqual(1, dsaObj.can_sign())
|
||||
self.assertEqual(0, dsaObj.can_encrypt())
|
||||
|
||||
# Check that private parameters are all missing
|
||||
self.assertEqual(0, hasattr(dsaObj, 'x'))
|
||||
|
||||
# Sanity check key data
|
||||
self.assertEqual(1, dsaObj.p > dsaObj.q) # p > q
|
||||
self.assertEqual(160, size(dsaObj.q)) # size(q) == 160 bits
|
||||
self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q) # q is a divisor of p-1
|
||||
|
||||
# Public-only key objects should raise an error when .sign() is called
|
||||
self.assertRaises(TypeError, dsaObj._sign, m_hash, k)
|
||||
|
||||
# Check __eq__ and __ne__
|
||||
self.assertEqual(dsaObj.public_key() == dsaObj.public_key(),True) # assert_
|
||||
self.assertEqual(dsaObj.public_key() != dsaObj.public_key(),False) # assertFalse
|
||||
|
||||
self.assertEqual(dsaObj.public_key(), dsaObj.publickey())
|
||||
|
||||
def _test_signing(self, dsaObj):
|
||||
k = bytes_to_long(a2b_hex(self.k))
|
||||
m_hash = bytes_to_long(a2b_hex(self.m_hash))
|
||||
r = bytes_to_long(a2b_hex(self.r))
|
||||
s = bytes_to_long(a2b_hex(self.s))
|
||||
(r_out, s_out) = dsaObj._sign(m_hash, k)
|
||||
self.assertEqual((r, s), (r_out, s_out))
|
||||
|
||||
def _test_verification(self, dsaObj):
|
||||
m_hash = bytes_to_long(a2b_hex(self.m_hash))
|
||||
r = bytes_to_long(a2b_hex(self.r))
|
||||
s = bytes_to_long(a2b_hex(self.s))
|
||||
self.assertTrue(dsaObj._verify(m_hash, (r, s)))
|
||||
self.assertFalse(dsaObj._verify(m_hash + 1, (r, s)))
|
||||
|
||||
def test_repr(self):
|
||||
(y, g, p, q) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q)]
|
||||
dsaObj = self.dsa.construct((y, g, p, q))
|
||||
repr(dsaObj)
|
||||
|
||||
|
||||
class DSADomainTest(unittest.TestCase):
|
||||
|
||||
def test_domain1(self):
|
||||
"""Verify we can generate new keys in a given domain"""
|
||||
dsa_key_1 = DSA.generate(1024)
|
||||
domain_params = dsa_key_1.domain()
|
||||
|
||||
dsa_key_2 = DSA.generate(1024, domain=domain_params)
|
||||
self.assertEqual(dsa_key_1.p, dsa_key_2.p)
|
||||
self.assertEqual(dsa_key_1.q, dsa_key_2.q)
|
||||
self.assertEqual(dsa_key_1.g, dsa_key_2.g)
|
||||
|
||||
self.assertEqual(dsa_key_1.domain(), dsa_key_2.domain())
|
||||
|
||||
def _get_weak_domain(self):
|
||||
|
||||
from Crypto.Math.Numbers import Integer
|
||||
from Crypto.Math import Primality
|
||||
|
||||
p = Integer(4)
|
||||
while p.size_in_bits() != 1024 or Primality.test_probable_prime(p) != Primality.PROBABLY_PRIME:
|
||||
q1 = Integer.random(exact_bits=80)
|
||||
q2 = Integer.random(exact_bits=80)
|
||||
q = q1 * q2
|
||||
z = Integer.random(exact_bits=1024-160)
|
||||
p = z * q + 1
|
||||
|
||||
h = Integer(2)
|
||||
g = 1
|
||||
while g == 1:
|
||||
g = pow(h, z, p)
|
||||
h += 1
|
||||
|
||||
return (p, q, g)
|
||||
|
||||
|
||||
def test_generate_error_weak_domain(self):
|
||||
"""Verify that domain parameters with composite q are rejected"""
|
||||
|
||||
domain_params = self._get_weak_domain()
|
||||
self.assertRaises(ValueError, DSA.generate, 1024, domain=domain_params)
|
||||
|
||||
|
||||
def test_construct_error_weak_domain(self):
|
||||
"""Verify that domain parameters with composite q are rejected"""
|
||||
|
||||
from Crypto.Math.Numbers import Integer
|
||||
|
||||
p, q, g = self._get_weak_domain()
|
||||
y = pow(g, 89, p)
|
||||
self.assertRaises(ValueError, DSA.construct, (y, g, p, q))
|
||||
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(DSATest)
|
||||
tests += list_test_cases(DSADomainTest)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
# vim:set ts=4 sw=4 sts=4 expandtab:
|
283
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ECC_Curve25519.py
vendored
Normal file
283
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ECC_Curve25519.py
vendored
Normal file
@ -0,0 +1,283 @@
|
||||
# ===================================================================
|
||||
#
|
||||
# Copyright (c) 2024, Helder Eijs <helderijs@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# ===================================================================
|
||||
|
||||
import unittest
|
||||
from binascii import unhexlify
|
||||
|
||||
from Crypto.SelfTest.st_common import list_test_cases
|
||||
from Crypto.Math.Numbers import Integer
|
||||
from Crypto.Hash import SHAKE128
|
||||
|
||||
from Crypto.PublicKey import ECC
|
||||
from Crypto.PublicKey.ECC import EccKey, EccXPoint, _curves
|
||||
|
||||
# Test vectors for scalar multiplication using point with X=9 as base
|
||||
# generated with nickovs' Python-only code https://gist.github.com/nickovs/cc3c22d15f239a2640c185035c06f8a3
|
||||
# The order is 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed
|
||||
# Each tuple is (exponent, X-coordinate)
|
||||
scalar_base9_test = [
|
||||
(1, 9),
|
||||
(2, 0x20d342d51873f1b7d9750c687d1571148f3f5ced1e350b5c5cae469cdd684efb),
|
||||
(3, 0x1c12bc1a6d57abe645534d91c21bba64f8824e67621c0859c00a03affb713c12),
|
||||
(4, 0x79ce98b7e0689d7de7d1d074a15b315ffe1805dfcd5d2a230fee85e4550013ef),
|
||||
(6, 0x26954ccdc99ebf34f8f1dde5e6bb080685fec73640494c28f9fe0bfa8c794531),
|
||||
(9, 0x192b929197d07748db44600da41bab7499b1c2e6e2f87c6f0e337980668164ba),
|
||||
(129, 0x7332096a738900085e721103fce2cbf13aee50fef0788ea0d669008eb09ceab7),
|
||||
(255, 0x1534582fc2b1cea45e8cb776547e209da4fd54a9e473b50c5b8c6b0ae023a9b3),
|
||||
(256, 0x4300017536976a742ec8747f7505cd6bc80e610d669acab1a1eed36f680d98e8),
|
||||
(257, 0x6c410611cb484c9016adfb884d37a0e682e075daca1d46f45bb7a4afed10b125),
|
||||
(0x10101, 0xa679e9d7e043bf76c03362576e2c88abe9093c5d4f6b4a202c64a8397467cf),
|
||||
(0xAA55CC, 0x2cc02f84c067e3586f4278326689be163e606d69ccae505bb09488e11f295887),
|
||||
(0x1B29A0E579E0A000567, 0x50c38a72d7bfd7864c8b9083fa123e8d359068e6b491a019a885036e073f6604),
|
||||
(0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed + 1, 9),
|
||||
]
|
||||
|
||||
|
||||
class TestEccPoint_Curve25519(unittest.TestCase):
|
||||
|
||||
v1 = 0x09fa78b39b00a72930bcd8039be789a0997830bb99f79aeeb93493715390b4e8
|
||||
v2 = 0x15210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493
|
||||
|
||||
def test_init(self):
|
||||
EccXPoint(9, "curve25519")
|
||||
EccXPoint(2**255 - 19 + 5, "curve25519")
|
||||
|
||||
def test_curve_attribute(self):
|
||||
point = EccXPoint(9, "curve25519")
|
||||
self.assertEqual(point.curve, "Curve25519")
|
||||
|
||||
def test_init_fail(self):
|
||||
self.assertRaises(ValueError, EccXPoint, 3*(2**255 - 19), "curve25519")
|
||||
self.assertRaises(ValueError, EccXPoint, 9, "curve25518")
|
||||
|
||||
def test_equal_set(self):
|
||||
point1 = EccXPoint(self.v1, "curve25519")
|
||||
point2 = EccXPoint(self.v2, "curve25519")
|
||||
|
||||
self.assertEqual(point1, point1)
|
||||
self.assertNotEqual(point1, point2)
|
||||
|
||||
point2.set(point1)
|
||||
self.assertEqual(point1.x, point2.x)
|
||||
|
||||
def test_copy(self):
|
||||
point1 = EccXPoint(self.v1, "curve25519")
|
||||
point2 = point1.copy()
|
||||
self.assertEqual(point1.x, point2.x)
|
||||
|
||||
def test_pai(self):
|
||||
point1 = EccXPoint(self.v1, "curve25519")
|
||||
pai = point1.point_at_infinity()
|
||||
self.assertTrue(pai.point_at_infinity())
|
||||
|
||||
point2 = EccXPoint(None, "curve25519")
|
||||
self.assertTrue(point2.point_at_infinity())
|
||||
|
||||
def test_scalar_multiply(self):
|
||||
base = EccXPoint(9, "curve25519")
|
||||
|
||||
pointH = 0 * base
|
||||
self.assertTrue(pointH.point_at_infinity())
|
||||
|
||||
pointH = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed * base
|
||||
self.assertTrue(pointH.point_at_infinity())
|
||||
|
||||
pointH = base * 1
|
||||
self.assertEqual(pointH.x, 9)
|
||||
|
||||
for d, result in scalar_base9_test:
|
||||
pointH = d * base
|
||||
self.assertEqual(pointH.x, result)
|
||||
|
||||
def test_sizes(self):
|
||||
point = EccXPoint(9, "curve25519")
|
||||
self.assertEqual(point.size_in_bits(), 255)
|
||||
self.assertEqual(point.size_in_bytes(), 32)
|
||||
|
||||
|
||||
class TestEccKey_Curve25519(unittest.TestCase):
|
||||
|
||||
def test_private_key(self):
|
||||
# RFC7748 Section 6.1 - Alice
|
||||
alice_priv = unhexlify("77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a")
|
||||
alice_pub = unhexlify("8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a")
|
||||
alice_pub_x = Integer.from_bytes(alice_pub, byteorder='little')
|
||||
|
||||
key = EccKey(curve="Curve25519", seed=alice_priv)
|
||||
self.assertEqual(key.seed, alice_priv)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.pointQ.x, alice_pub_x)
|
||||
|
||||
# RFC7748 Section 6.1 - Bob
|
||||
bob_priv = unhexlify("5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb")
|
||||
bob_pub = unhexlify("de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f")
|
||||
bob_pub_x = Integer.from_bytes(bob_pub, byteorder='little')
|
||||
|
||||
key = EccKey(curve="Curve25519", seed=bob_priv)
|
||||
self.assertEqual(key.seed, bob_priv)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.pointQ.x, bob_pub_x)
|
||||
|
||||
# Other names
|
||||
key = EccKey(curve="curve25519", seed=alice_priv)
|
||||
|
||||
# Must not accept d parameter
|
||||
self.assertRaises(ValueError, EccKey, curve="curve25519", d=1)
|
||||
|
||||
def test_public_key(self):
|
||||
point = EccXPoint(_curves['curve25519'].Gx,
|
||||
curve='curve25519')
|
||||
key = EccKey(curve="curve25519", point=point)
|
||||
self.assertFalse(key.has_private())
|
||||
self.assertEqual(key.pointQ, point)
|
||||
|
||||
def test_public_key_derived(self):
|
||||
priv_key = EccKey(curve="curve25519", seed=b'H'*32)
|
||||
pub_key = priv_key.public_key()
|
||||
self.assertFalse(pub_key.has_private())
|
||||
self.assertEqual(priv_key.pointQ, pub_key.pointQ)
|
||||
|
||||
def test_invalid_seed(self):
|
||||
self.assertRaises(ValueError, lambda: EccKey(curve="curve25519", seed=b'H' * 31))
|
||||
|
||||
def test_equality(self):
|
||||
private_key = ECC.construct(seed=b'H'*32, curve="Curve25519")
|
||||
private_key2 = ECC.construct(seed=b'H'*32, curve="curve25519")
|
||||
private_key3 = ECC.construct(seed=b'C'*32, curve="Curve25519")
|
||||
|
||||
public_key = private_key.public_key()
|
||||
public_key2 = private_key2.public_key()
|
||||
public_key3 = private_key3.public_key()
|
||||
|
||||
self.assertEqual(private_key, private_key2)
|
||||
self.assertNotEqual(private_key, private_key3)
|
||||
|
||||
self.assertEqual(public_key, public_key2)
|
||||
self.assertNotEqual(public_key, public_key3)
|
||||
|
||||
self.assertNotEqual(public_key, private_key)
|
||||
|
||||
def test_name_consistency(self):
|
||||
key = ECC.generate(curve='curve25519')
|
||||
self.assertIn("curve='Curve25519'", repr(key))
|
||||
self.assertEqual(key.curve, 'Curve25519')
|
||||
self.assertEqual(key.public_key().curve, 'Curve25519')
|
||||
|
||||
|
||||
class TestEccModule_Curve25519(unittest.TestCase):
|
||||
|
||||
def test_generate(self):
|
||||
key = ECC.generate(curve="Curve25519")
|
||||
self.assertTrue(key.has_private())
|
||||
point = EccXPoint(_curves['Curve25519'].Gx, curve="Curve25519") * key.d
|
||||
self.assertEqual(key.pointQ, point)
|
||||
|
||||
# Always random
|
||||
key2 = ECC.generate(curve="Curve25519")
|
||||
self.assertNotEqual(key, key2)
|
||||
|
||||
# Other names
|
||||
ECC.generate(curve="curve25519")
|
||||
|
||||
# Random source
|
||||
key1 = ECC.generate(curve="Curve25519", randfunc=SHAKE128.new().read)
|
||||
key2 = ECC.generate(curve="Curve25519", randfunc=SHAKE128.new().read)
|
||||
self.assertEqual(key1, key2)
|
||||
|
||||
def test_construct(self):
|
||||
seed = unhexlify("77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a")
|
||||
point_hex = unhexlify("8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a")
|
||||
Px = Integer.from_bytes(point_hex, byteorder='little')
|
||||
point = EccXPoint(Px, curve="Curve25519")
|
||||
|
||||
# Private key only
|
||||
key = ECC.construct(curve="Curve25519", seed=seed)
|
||||
self.assertEqual(key.pointQ, point)
|
||||
self.assertTrue(key.has_private())
|
||||
|
||||
# Public key only
|
||||
key = ECC.construct(curve="Curve25519", point_x=Px)
|
||||
self.assertEqual(key.pointQ, point)
|
||||
self.assertFalse(key.has_private())
|
||||
|
||||
# Private and public key
|
||||
key = ECC.construct(curve="Curve25519", seed=seed, point_x=Px)
|
||||
self.assertEqual(key.pointQ, point)
|
||||
self.assertTrue(key.has_private())
|
||||
|
||||
# Other names
|
||||
key = ECC.construct(curve="curve25519", seed=seed)
|
||||
|
||||
def test_negative_construct(self):
|
||||
coordG = dict(point_x=_curves['curve25519'].Gx)
|
||||
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve25519", d=2, **coordG)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve25519", seed=b'H'*31)
|
||||
|
||||
# Verify you cannot construct weak keys (small-order points)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve25519",
|
||||
point_x=0)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve25519",
|
||||
point_x=1)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve25519",
|
||||
point_x=325606250916557431795983626356110631294008115727848805560023387167927233504)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve25519",
|
||||
point_x=39382357235489614581723060781553021112529911719440698176882885853963445705823)
|
||||
p = 2**255 - 19
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve25519",
|
||||
point_x=p-1)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve25519",
|
||||
point_x=p)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve25519",
|
||||
point_x=p+1)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve25519",
|
||||
point_x=p+325606250916557431795983626356110631294008115727848805560023387167927233504)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve25519",
|
||||
point_x=p+39382357235489614581723060781553021112529911719440698176882885853963445705823)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve25519",
|
||||
point_x=p*2-1)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve25519",
|
||||
point_x=p*2)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve25519",
|
||||
point_x=p*2+1)
|
||||
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(TestEccPoint_Curve25519)
|
||||
tests += list_test_cases(TestEccKey_Curve25519)
|
||||
tests += list_test_cases(TestEccModule_Curve25519)
|
||||
return tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
def suite():
|
||||
return unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
246
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ECC_Curve448.py
vendored
Normal file
246
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ECC_Curve448.py
vendored
Normal file
@ -0,0 +1,246 @@
|
||||
# This file is licensed under the BSD 2-Clause License.
|
||||
# See https://opensource.org/licenses/BSD-2-Clause for details.
|
||||
|
||||
import unittest
|
||||
from binascii import unhexlify
|
||||
|
||||
from Crypto.SelfTest.st_common import list_test_cases
|
||||
from Crypto.Math.Numbers import Integer
|
||||
from Crypto.Hash import SHAKE128
|
||||
|
||||
from Crypto.PublicKey import ECC
|
||||
from Crypto.PublicKey.ECC import EccKey, EccXPoint, _curves
|
||||
|
||||
CURVE448_P = 2**448 - 2**224 - 1
|
||||
CURVE448_ORDER = 2**446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d
|
||||
|
||||
# Test vectors for scalar multiplication using point with X=5 as base
|
||||
# Each tuple is (exponent, X-coordinate)
|
||||
scalar_base5_test = [
|
||||
(1, 5),
|
||||
(2, 0x6391322257cae3d49aef4665d8bd5cccac9abefb511e83d75f3c766616266fc1bf3747f1da00ed7125e8f0255a1208087d32a4bc1c743cb6),
|
||||
(3, 0x1fbe4b3584cab86170c14b9325840b8a2429b61fb93c42492c002a2807a4e7ea63138ea59bf95652ce9a7d13d0321c7511e3314d0553f34c),
|
||||
(4, 0x93b44a7b78726ba8d0b048bd7144074f8bdad24ef9d0a6c8264f6c00b135ffcea11545e80d18364acc8ebfbcc45358e0da5fd5e5146e2b1),
|
||||
(6, 0x693d165f453bd62871e5e53845f33e9e5b18b24d79c1f9102608aa7ba6f18ac24864012171d64c90b698f5ce5631cd02cee4e4336b1ad88c),
|
||||
(9, 0xb970d576e7d9aa427dbf7cb9b7dd65170721d04ee060c9ea8d499dc361d4cfde1ceb19068eae853bac8f5d92827bdbf3d94c22de2fb42dae),
|
||||
(129, 0x9fbdb50a1450438fe656aa32aa1bb2548d077d5c3a5d327689093a2996a4f94eacd1fb4f90315edb2afe41908a759f0d6db83fa791df80db),
|
||||
(255, 0x31bc3e9385dfd12e1238927061eb0c911466da394e459bf058ba3b08260a258a3c392b0f85ddbd23828657137b88577a85b83774139fab9e),
|
||||
(256, 0x735c7f30e6872e5e4215c0147c8a112d697f668c9bd0f92f5f1e4e6badc128a0b654e697cd4bae2144d54e726b54c1fa63a09b00dd3c17f),
|
||||
(257, 0x95c1b0ce01286dc047aeb5922a5e62b3effb5b9296273a5004eb456f592728dd494a6fb5996a2ea7011ae6423874a48c2927bfa62d8ce8b0),
|
||||
(0x10101, 0x113bb172c9dc52ab45bd665dd9751ed44e33b8596f943c6cb2f8dd329160ece802960b3eb0d2c21ef3a3ac12c20fccbc2a271fc2f061c1b2),
|
||||
(0xAA55CC, 0xcf42585d2e0b1e45c0bfd601c91af4b137d7faf139fc761178c7ded432417c307ee1759af2deec6a14dbaf6b868eb13a6039fbdde4b61898),
|
||||
(0x1B29A0E579E0A000567, 0x7bd9ec9775a664f4d860d82d6be60895113a7c36f92db25583dbba5dc17f09c136ec27e14857bfd6a705311327030aa657dd036325fad330),
|
||||
(CURVE448_ORDER + 1, 5),
|
||||
]
|
||||
|
||||
|
||||
class TestEccPoint_Curve448(unittest.TestCase):
|
||||
|
||||
v1 = 0x09fa78b39b00a72930bcd8039be789a0997830bb99f79aeeb93493715390b4e8
|
||||
v2 = 0x15210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493
|
||||
|
||||
def test_init(self):
|
||||
EccXPoint(5, "curve448")
|
||||
EccXPoint(CURVE448_P - 5, "curve448")
|
||||
|
||||
def test_curve_attribute(self):
|
||||
point = EccXPoint(5, "curve448")
|
||||
self.assertEqual(point.curve, "Curve448")
|
||||
|
||||
def test_init_fail(self):
|
||||
self.assertRaises(ValueError, EccXPoint, 3*CURVE448_P, "curve448")
|
||||
self.assertRaises(ValueError, EccXPoint, 3, "curve449")
|
||||
|
||||
def test_equal_set(self):
|
||||
point1 = EccXPoint(self.v1, "curve448")
|
||||
point2 = EccXPoint(self.v2, "curve448")
|
||||
|
||||
self.assertEqual(point1, point1)
|
||||
self.assertNotEqual(point1, point2)
|
||||
|
||||
point2.set(point1)
|
||||
self.assertEqual(point1.x, point2.x)
|
||||
|
||||
def test_copy(self):
|
||||
point1 = EccXPoint(self.v1, "curve448")
|
||||
point2 = point1.copy()
|
||||
self.assertEqual(point1.x, point2.x)
|
||||
|
||||
def test_pai(self):
|
||||
point1 = EccXPoint(self.v1, "curve448")
|
||||
pai = point1.point_at_infinity()
|
||||
self.assertTrue(pai.point_at_infinity())
|
||||
|
||||
point2 = EccXPoint(None, "curve448")
|
||||
self.assertTrue(point2.point_at_infinity())
|
||||
|
||||
def test_scalar_multiply(self):
|
||||
base = EccXPoint(5, "curve448")
|
||||
|
||||
pointH = 0 * base
|
||||
self.assertTrue(pointH.point_at_infinity())
|
||||
|
||||
pointH = CURVE448_ORDER * base
|
||||
self.assertTrue(pointH.point_at_infinity())
|
||||
|
||||
pointH = base * 1
|
||||
self.assertEqual(pointH.x, 5)
|
||||
|
||||
for d, result in scalar_base5_test:
|
||||
pointH = d * base
|
||||
self.assertEqual(pointH.x, result)
|
||||
|
||||
def test_sizes(self):
|
||||
point = EccXPoint(5, "curve448")
|
||||
self.assertEqual(point.size_in_bits(), 448)
|
||||
self.assertEqual(point.size_in_bytes(), 56)
|
||||
|
||||
|
||||
class TestEccKey_Curve448(unittest.TestCase):
|
||||
|
||||
def test_private_key(self):
|
||||
# RFC7748 Section 6.2 - Alice
|
||||
alice_priv = unhexlify("9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28dd9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b")
|
||||
alice_pub = unhexlify("9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0")
|
||||
alice_pub_x = Integer.from_bytes(alice_pub, byteorder='little')
|
||||
|
||||
key = EccKey(curve="Curve448", seed=alice_priv)
|
||||
self.assertEqual(key.seed, alice_priv)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.pointQ.x, alice_pub_x)
|
||||
|
||||
# RFC7748 Section 6.2 - Bob
|
||||
bob_priv = unhexlify("1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d")
|
||||
bob_pub = unhexlify("3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b43027d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609")
|
||||
bob_pub_x = Integer.from_bytes(bob_pub, byteorder='little')
|
||||
|
||||
key = EccKey(curve="Curve448", seed=bob_priv)
|
||||
self.assertEqual(key.seed, bob_priv)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.pointQ.x, bob_pub_x)
|
||||
|
||||
# Other names
|
||||
key = EccKey(curve="curve448", seed=alice_priv)
|
||||
|
||||
# Must not accept d parameter
|
||||
self.assertRaises(ValueError, EccKey, curve="curve448", d=1)
|
||||
|
||||
def test_public_key(self):
|
||||
point = EccXPoint(_curves['curve448'].Gx,
|
||||
curve='curve448')
|
||||
key = EccKey(curve="curve448", point=point)
|
||||
self.assertFalse(key.has_private())
|
||||
self.assertEqual(key.pointQ, point)
|
||||
|
||||
def test_public_key_derived(self):
|
||||
priv_key = EccKey(curve="curve448", seed=b'H'*56)
|
||||
pub_key = priv_key.public_key()
|
||||
self.assertFalse(pub_key.has_private())
|
||||
self.assertEqual(priv_key.pointQ, pub_key.pointQ)
|
||||
|
||||
def test_invalid_seed(self):
|
||||
self.assertRaises(ValueError, lambda: EccKey(curve="curve448",
|
||||
seed=b'H' * 55))
|
||||
|
||||
def test_equality(self):
|
||||
private_key = ECC.construct(seed=b'H'*56, curve="Curve448")
|
||||
private_key2 = ECC.construct(seed=b'H'*56, curve="curve448")
|
||||
private_key3 = ECC.construct(seed=b'C'*56, curve="Curve448")
|
||||
|
||||
public_key = private_key.public_key()
|
||||
public_key2 = private_key2.public_key()
|
||||
public_key3 = private_key3.public_key()
|
||||
|
||||
self.assertEqual(private_key, private_key2)
|
||||
self.assertNotEqual(private_key, private_key3)
|
||||
|
||||
self.assertEqual(public_key, public_key2)
|
||||
self.assertNotEqual(public_key, public_key3)
|
||||
|
||||
self.assertNotEqual(public_key, private_key)
|
||||
|
||||
def test_name_consistency(self):
|
||||
key = ECC.generate(curve='curve448')
|
||||
self.assertIn("curve='Curve448'", repr(key))
|
||||
self.assertEqual(key.curve, 'Curve448')
|
||||
self.assertEqual(key.public_key().curve, 'Curve448')
|
||||
|
||||
|
||||
class TestEccModule_Curve448(unittest.TestCase):
|
||||
|
||||
def test_generate(self):
|
||||
key = ECC.generate(curve="Curve448")
|
||||
self.assertTrue(key.has_private())
|
||||
point = EccXPoint(_curves['Curve448'].Gx, curve="Curve448") * key.d
|
||||
self.assertEqual(key.pointQ, point)
|
||||
|
||||
# Always random
|
||||
key2 = ECC.generate(curve="Curve448")
|
||||
self.assertNotEqual(key, key2)
|
||||
|
||||
# Other names
|
||||
ECC.generate(curve="curve448")
|
||||
|
||||
# Random source
|
||||
key1 = ECC.generate(curve="Curve448", randfunc=SHAKE128.new().read)
|
||||
key2 = ECC.generate(curve="Curve448", randfunc=SHAKE128.new().read)
|
||||
self.assertEqual(key1, key2)
|
||||
|
||||
def test_construct(self):
|
||||
seed = unhexlify("9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28dd9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b")
|
||||
point_hex = unhexlify("9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0")
|
||||
Px = Integer.from_bytes(point_hex, byteorder='little')
|
||||
point = EccXPoint(Px, curve="Curve448")
|
||||
|
||||
# Private key only
|
||||
key = ECC.construct(curve="Curve448", seed=seed)
|
||||
self.assertEqual(key.pointQ, point)
|
||||
self.assertTrue(key.has_private())
|
||||
|
||||
# Public key only
|
||||
key = ECC.construct(curve="Curve448", point_x=Px)
|
||||
self.assertEqual(key.pointQ, point)
|
||||
self.assertFalse(key.has_private())
|
||||
|
||||
# Private and public key
|
||||
key = ECC.construct(curve="Curve448", seed=seed, point_x=Px)
|
||||
self.assertEqual(key.pointQ, point)
|
||||
self.assertTrue(key.has_private())
|
||||
|
||||
# Other names
|
||||
key = ECC.construct(curve="curve448", seed=seed)
|
||||
|
||||
def test_negative_construct(self):
|
||||
coordG = dict(point_x=_curves['curve448'].Gx)
|
||||
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve448",
|
||||
d=2, **coordG)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve448",
|
||||
seed=b'H'*55)
|
||||
|
||||
# Verify you cannot construct weak keys (small-order points)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve448",
|
||||
point_x=0)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve448",
|
||||
point_x=1)
|
||||
p = 2**448 - 2**224 - 1
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve448",
|
||||
point_x=p-1)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve448",
|
||||
point_x=p)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Curve448",
|
||||
point_x=p+1)
|
||||
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(TestEccPoint_Curve448)
|
||||
tests += list_test_cases(TestEccKey_Curve448)
|
||||
tests += list_test_cases(TestEccModule_Curve448)
|
||||
return tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
def suite():
|
||||
return unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
341
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ECC_Ed25519.py
vendored
Normal file
341
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ECC_Ed25519.py
vendored
Normal file
@ -0,0 +1,341 @@
|
||||
# ===================================================================
|
||||
#
|
||||
# Copyright (c) 2022, Legrandin <helderijs@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# ===================================================================
|
||||
|
||||
import unittest
|
||||
from binascii import unhexlify
|
||||
|
||||
from Crypto.SelfTest.st_common import list_test_cases
|
||||
from Crypto.SelfTest.loader import load_test_vectors
|
||||
|
||||
from Crypto.PublicKey import ECC
|
||||
from Crypto.PublicKey.ECC import EccPoint, _curves, EccKey
|
||||
|
||||
from Crypto.Math.Numbers import Integer
|
||||
|
||||
from Crypto.Hash import SHAKE128
|
||||
|
||||
|
||||
class TestEccPoint_Ed25519(unittest.TestCase):
|
||||
|
||||
Gxy = {"x": 15112221349535400772501151409588531511454012693041857206046113283949847762202,
|
||||
"y": 46316835694926478169428394003475163141307993866256225615783033603165251855960}
|
||||
|
||||
G2xy = {"x": 24727413235106541002554574571675588834622768167397638456726423682521233608206,
|
||||
"y": 15549675580280190176352668710449542251549572066445060580507079593062643049417}
|
||||
|
||||
G3xy = {"x": 46896733464454938657123544595386787789046198280132665686241321779790909858396,
|
||||
"y": 8324843778533443976490377120369201138301417226297555316741202210403726505172}
|
||||
|
||||
pointG = EccPoint(Gxy['x'], Gxy['y'], curve="ed25519")
|
||||
pointG2 = EccPoint(G2xy['x'], G2xy['y'], curve="ed25519")
|
||||
pointG3 = EccPoint(G3xy['x'], G3xy['y'], curve="ed25519")
|
||||
|
||||
def test_curve_attribute(self):
|
||||
self.assertEqual(self.pointG.curve, "Ed25519")
|
||||
|
||||
def test_init_xy(self):
|
||||
EccPoint(self.Gxy['x'], self.Gxy['y'], curve="Ed25519")
|
||||
|
||||
# Neutral point
|
||||
pai = EccPoint(0, 1, curve="Ed25519")
|
||||
self.assertEqual(pai.x, 0)
|
||||
self.assertEqual(pai.y, 1)
|
||||
self.assertEqual(pai.xy, (0, 1))
|
||||
|
||||
# G
|
||||
bp = self.pointG.copy()
|
||||
self.assertEqual(bp.x, 15112221349535400772501151409588531511454012693041857206046113283949847762202)
|
||||
self.assertEqual(bp.y, 46316835694926478169428394003475163141307993866256225615783033603165251855960)
|
||||
self.assertEqual(bp.xy, (bp.x, bp.y))
|
||||
|
||||
# 2G
|
||||
bp2 = self.pointG2.copy()
|
||||
self.assertEqual(bp2.x, 24727413235106541002554574571675588834622768167397638456726423682521233608206)
|
||||
self.assertEqual(bp2.y, 15549675580280190176352668710449542251549572066445060580507079593062643049417)
|
||||
self.assertEqual(bp2.xy, (bp2.x, bp2.y))
|
||||
|
||||
# 5G
|
||||
EccPoint(x=33467004535436536005251147249499675200073690106659565782908757308821616914995,
|
||||
y=43097193783671926753355113395909008640284023746042808659097434958891230611693,
|
||||
curve="Ed25519")
|
||||
|
||||
# Catch if point is not on the curve
|
||||
self.assertRaises(ValueError, EccPoint, 34, 35, curve="Ed25519")
|
||||
|
||||
def test_set(self):
|
||||
pointW = EccPoint(0, 1, curve="Ed25519")
|
||||
pointW.set(self.pointG)
|
||||
self.assertEqual(pointW.x, self.pointG.x)
|
||||
self.assertEqual(pointW.y, self.pointG.y)
|
||||
|
||||
def test_copy(self):
|
||||
pointW = self.pointG.copy()
|
||||
self.assertEqual(pointW.x, self.pointG.x)
|
||||
self.assertEqual(pointW.y, self.pointG.y)
|
||||
|
||||
def test_equal(self):
|
||||
pointH = self.pointG.copy()
|
||||
pointI = self.pointG2.copy()
|
||||
self.assertEqual(self.pointG, pointH)
|
||||
self.assertNotEqual(self.pointG, pointI)
|
||||
|
||||
def test_pai(self):
|
||||
pai = EccPoint(0, 1, curve="Ed25519")
|
||||
self.assertTrue(pai.is_point_at_infinity())
|
||||
self.assertEqual(pai, pai.point_at_infinity())
|
||||
|
||||
def test_negate(self):
|
||||
negG = -self.pointG
|
||||
G100 = self.pointG * 100
|
||||
sum_zero = G100 + negG * 100
|
||||
self.assertTrue(sum_zero.is_point_at_infinity())
|
||||
|
||||
sum_99 = G100 + negG
|
||||
expected = self.pointG * 99
|
||||
self.assertEqual(sum_99, expected)
|
||||
|
||||
def test_addition(self):
|
||||
self.assertEqual(self.pointG + self.pointG2, self.pointG3)
|
||||
self.assertEqual(self.pointG2 + self.pointG, self.pointG3)
|
||||
self.assertEqual(self.pointG2 + self.pointG.point_at_infinity(), self.pointG2)
|
||||
self.assertEqual(self.pointG.point_at_infinity() + self.pointG2, self.pointG2)
|
||||
|
||||
G5 = self.pointG2 + self.pointG3
|
||||
self.assertEqual(G5.x, 33467004535436536005251147249499675200073690106659565782908757308821616914995)
|
||||
self.assertEqual(G5.y, 43097193783671926753355113395909008640284023746042808659097434958891230611693)
|
||||
|
||||
def test_inplace_addition(self):
|
||||
pointH = self.pointG.copy()
|
||||
pointH += self.pointG
|
||||
self.assertEqual(pointH, self.pointG2)
|
||||
pointH += self.pointG
|
||||
self.assertEqual(pointH, self.pointG3)
|
||||
pointH += self.pointG.point_at_infinity()
|
||||
self.assertEqual(pointH, self.pointG3)
|
||||
|
||||
def test_doubling(self):
|
||||
pointH = self.pointG.copy()
|
||||
pointH.double()
|
||||
self.assertEqual(pointH.x, self.pointG2.x)
|
||||
self.assertEqual(pointH.y, self.pointG2.y)
|
||||
|
||||
# 2*0
|
||||
pai = self.pointG.point_at_infinity()
|
||||
pointR = pai.copy()
|
||||
pointR.double()
|
||||
self.assertEqual(pointR, pai)
|
||||
|
||||
def test_scalar_multiply(self):
|
||||
d = 0
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, 0)
|
||||
self.assertEqual(pointH.y, 1)
|
||||
|
||||
d = 1
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, self.pointG.x)
|
||||
self.assertEqual(pointH.y, self.pointG.y)
|
||||
|
||||
d = 2
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, self.pointG2.x)
|
||||
self.assertEqual(pointH.y, self.pointG2.y)
|
||||
|
||||
d = 3
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, self.pointG3.x)
|
||||
self.assertEqual(pointH.y, self.pointG3.y)
|
||||
|
||||
d = 4
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, 14582954232372986451776170844943001818709880559417862259286374126315108956272)
|
||||
self.assertEqual(pointH.y, 32483318716863467900234833297694612235682047836132991208333042722294373421359)
|
||||
|
||||
d = 5
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, 33467004535436536005251147249499675200073690106659565782908757308821616914995)
|
||||
self.assertEqual(pointH.y, 43097193783671926753355113395909008640284023746042808659097434958891230611693)
|
||||
|
||||
d = 10
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, 43500613248243327786121022071801015118933854441360174117148262713429272820047)
|
||||
self.assertEqual(pointH.y, 45005105423099817237495816771148012388779685712352441364231470781391834741548)
|
||||
|
||||
d = 20
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, 46694936775300686710656303283485882876784402425210400817529601134760286812591)
|
||||
self.assertEqual(pointH.y, 8786390172762935853260670851718824721296437982862763585171334833968259029560)
|
||||
|
||||
d = 255
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, 36843863416400016952258312492144504209624961884991522125275155377549541182230)
|
||||
self.assertEqual(pointH.y, 22327030283879720808995671630924669697661065034121040761798775626517750047180)
|
||||
|
||||
d = 256
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, 42740085206947573681423002599456489563927820004573071834350074001818321593686)
|
||||
self.assertEqual(pointH.y, 6935684722522267618220753829624209639984359598320562595061366101608187623111)
|
||||
|
||||
def test_sizes(self):
|
||||
self.assertEqual(self.pointG.size_in_bits(), 255)
|
||||
self.assertEqual(self.pointG.size_in_bytes(), 32)
|
||||
|
||||
|
||||
class TestEccKey_Ed25519(unittest.TestCase):
|
||||
|
||||
def test_private_key(self):
|
||||
seed = unhexlify("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60")
|
||||
Px = 38815646466658113194383306759739515082307681141926459231621296960732224964046
|
||||
Py = 11903303657706407974989296177215005343713679411332034699907763981919547054807
|
||||
|
||||
key = EccKey(curve="Ed25519", seed=seed)
|
||||
self.assertEqual(key.seed, seed)
|
||||
self.assertEqual(key.d, 36144925721603087658594284515452164870581325872720374094707712194495455132720)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.pointQ.x, Px)
|
||||
self.assertEqual(key.pointQ.y, Py)
|
||||
|
||||
point = EccPoint(Px, Py, "ed25519")
|
||||
key = EccKey(curve="Ed25519", seed=seed, point=point)
|
||||
self.assertEqual(key.d, 36144925721603087658594284515452164870581325872720374094707712194495455132720)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.pointQ, point)
|
||||
|
||||
# Other names
|
||||
key = EccKey(curve="ed25519", seed=seed)
|
||||
|
||||
# Must not accept d parameter
|
||||
self.assertRaises(ValueError, EccKey, curve="ed25519", d=1)
|
||||
|
||||
def test_public_key(self):
|
||||
point = EccPoint(_curves['ed25519'].Gx, _curves['ed25519'].Gy, curve='ed25519')
|
||||
key = EccKey(curve="ed25519", point=point)
|
||||
self.assertFalse(key.has_private())
|
||||
self.assertEqual(key.pointQ, point)
|
||||
|
||||
def test_public_key_derived(self):
|
||||
priv_key = EccKey(curve="ed25519", seed=b'H'*32)
|
||||
pub_key = priv_key.public_key()
|
||||
self.assertFalse(pub_key.has_private())
|
||||
self.assertEqual(priv_key.pointQ, pub_key.pointQ)
|
||||
|
||||
def test_invalid_seed(self):
|
||||
self.assertRaises(ValueError, lambda: EccKey(curve="ed25519", seed=b'H' * 31))
|
||||
|
||||
def test_equality(self):
|
||||
private_key = ECC.construct(seed=b'H'*32, curve="Ed25519")
|
||||
private_key2 = ECC.construct(seed=b'H'*32, curve="ed25519")
|
||||
private_key3 = ECC.construct(seed=b'C'*32, curve="Ed25519")
|
||||
|
||||
public_key = private_key.public_key()
|
||||
public_key2 = private_key2.public_key()
|
||||
public_key3 = private_key3.public_key()
|
||||
|
||||
self.assertEqual(private_key, private_key2)
|
||||
self.assertNotEqual(private_key, private_key3)
|
||||
|
||||
self.assertEqual(public_key, public_key2)
|
||||
self.assertNotEqual(public_key, public_key3)
|
||||
|
||||
self.assertNotEqual(public_key, private_key)
|
||||
|
||||
def test_name_consistency(self):
|
||||
key = ECC.generate(curve='ed25519')
|
||||
self.assertIn("curve='Ed25519'", repr(key))
|
||||
self.assertEqual(key.curve, 'Ed25519')
|
||||
self.assertEqual(key.public_key().curve, 'Ed25519')
|
||||
|
||||
|
||||
class TestEccModule_Ed25519(unittest.TestCase):
|
||||
|
||||
def test_generate(self):
|
||||
key = ECC.generate(curve="Ed25519")
|
||||
self.assertTrue(key.has_private())
|
||||
point = EccPoint(_curves['Ed25519'].Gx, _curves['Ed25519'].Gy, curve="Ed25519") * key.d
|
||||
self.assertEqual(key.pointQ, point)
|
||||
|
||||
# Always random
|
||||
key2 = ECC.generate(curve="Ed25519")
|
||||
self.assertNotEqual(key, key2)
|
||||
|
||||
# Other names
|
||||
ECC.generate(curve="Ed25519")
|
||||
|
||||
# Random source
|
||||
key1 = ECC.generate(curve="Ed25519", randfunc=SHAKE128.new().read)
|
||||
key2 = ECC.generate(curve="Ed25519", randfunc=SHAKE128.new().read)
|
||||
self.assertEqual(key1, key2)
|
||||
|
||||
def test_construct(self):
|
||||
seed = unhexlify("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60")
|
||||
Px = 38815646466658113194383306759739515082307681141926459231621296960732224964046
|
||||
Py = 11903303657706407974989296177215005343713679411332034699907763981919547054807
|
||||
d = 36144925721603087658594284515452164870581325872720374094707712194495455132720
|
||||
point = EccPoint(Px, Py, curve="Ed25519")
|
||||
|
||||
# Private key only
|
||||
key = ECC.construct(curve="Ed25519", seed=seed)
|
||||
self.assertEqual(key.pointQ, point)
|
||||
self.assertTrue(key.has_private())
|
||||
|
||||
# Public key only
|
||||
key = ECC.construct(curve="Ed25519", point_x=Px, point_y=Py)
|
||||
self.assertEqual(key.pointQ, point)
|
||||
self.assertFalse(key.has_private())
|
||||
|
||||
# Private and public key
|
||||
key = ECC.construct(curve="Ed25519", seed=seed, point_x=Px, point_y=Py)
|
||||
self.assertEqual(key.pointQ, point)
|
||||
self.assertTrue(key.has_private())
|
||||
|
||||
# Other names
|
||||
key = ECC.construct(curve="ed25519", seed=seed)
|
||||
|
||||
def test_negative_construct(self):
|
||||
coord = dict(point_x=10, point_y=4)
|
||||
coordG = dict(point_x=_curves['ed25519'].Gx, point_y=_curves['ed25519'].Gy)
|
||||
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Ed25519", **coord)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Ed25519", d=2, **coordG)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Ed25519", seed=b'H'*31)
|
||||
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(TestEccPoint_Ed25519)
|
||||
tests += list_test_cases(TestEccKey_Ed25519)
|
||||
tests += list_test_cases(TestEccModule_Ed25519)
|
||||
return tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
def suite():
|
||||
return unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
336
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ECC_Ed448.py
vendored
Normal file
336
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ECC_Ed448.py
vendored
Normal file
@ -0,0 +1,336 @@
|
||||
# ===================================================================
|
||||
#
|
||||
# Copyright (c) 2022, Legrandin <helderijs@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# ===================================================================
|
||||
|
||||
import unittest
|
||||
from binascii import unhexlify
|
||||
|
||||
from Crypto.SelfTest.st_common import list_test_cases
|
||||
from Crypto.SelfTest.loader import load_test_vectors
|
||||
|
||||
from Crypto.PublicKey import ECC
|
||||
from Crypto.PublicKey.ECC import EccPoint, _curves, EccKey
|
||||
|
||||
from Crypto.Math.Numbers import Integer
|
||||
|
||||
from Crypto.Hash import SHAKE128
|
||||
|
||||
|
||||
class TestEccPoint_Ed448(unittest.TestCase):
|
||||
|
||||
Gxy = {"x": 0x4f1970c66bed0ded221d15a622bf36da9e146570470f1767ea6de324a3d3a46412ae1af72ab66511433b80e18b00938e2626a82bc70cc05e,
|
||||
"y": 0x693f46716eb6bc248876203756c9c7624bea73736ca3984087789c1e05a0c2d73ad3ff1ce67c39c4fdbd132c4ed7c8ad9808795bf230fa14}
|
||||
|
||||
G2xy = {"x": 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa955555555555555555555555555555555555555555555555555555555,
|
||||
"y": 0xae05e9634ad7048db359d6205086c2b0036ed7a035884dd7b7e36d728ad8c4b80d6565833a2a3098bbbcb2bed1cda06bdaeafbcdea9386ed}
|
||||
|
||||
G3xy = {"x": 0x865886b9108af6455bd64316cb6943332241b8b8cda82c7e2ba077a4a3fcfe8daa9cbf7f6271fd6e862b769465da8575728173286ff2f8f,
|
||||
"y": 0xe005a8dbd5125cf706cbda7ad43aa6449a4a8d952356c3b9fce43c82ec4e1d58bb3a331bdb6767f0bffa9a68fed02dafb822ac13588ed6fc}
|
||||
|
||||
pointG = EccPoint(Gxy['x'], Gxy['y'], curve="ed448")
|
||||
pointG2 = EccPoint(G2xy['x'], G2xy['y'], curve="ed448")
|
||||
pointG3 = EccPoint(G3xy['x'], G3xy['y'], curve="ed448")
|
||||
|
||||
def test_curve_attribute(self):
|
||||
self.assertEqual(self.pointG.curve, "Ed448")
|
||||
|
||||
def test_init_xy(self):
|
||||
EccPoint(self.Gxy['x'], self.Gxy['y'], curve="Ed448")
|
||||
|
||||
# Neutral point
|
||||
pai = EccPoint(0, 1, curve="Ed448")
|
||||
self.assertEqual(pai.x, 0)
|
||||
self.assertEqual(pai.y, 1)
|
||||
self.assertEqual(pai.xy, (0, 1))
|
||||
|
||||
# G
|
||||
bp = self.pointG.copy()
|
||||
self.assertEqual(bp.x, 0x4f1970c66bed0ded221d15a622bf36da9e146570470f1767ea6de324a3d3a46412ae1af72ab66511433b80e18b00938e2626a82bc70cc05e)
|
||||
self.assertEqual(bp.y, 0x693f46716eb6bc248876203756c9c7624bea73736ca3984087789c1e05a0c2d73ad3ff1ce67c39c4fdbd132c4ed7c8ad9808795bf230fa14)
|
||||
self.assertEqual(bp.xy, (bp.x, bp.y))
|
||||
|
||||
# 2G
|
||||
bp2 = self.pointG2.copy()
|
||||
self.assertEqual(bp2.x, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa955555555555555555555555555555555555555555555555555555555)
|
||||
self.assertEqual(bp2.y, 0xae05e9634ad7048db359d6205086c2b0036ed7a035884dd7b7e36d728ad8c4b80d6565833a2a3098bbbcb2bed1cda06bdaeafbcdea9386ed)
|
||||
self.assertEqual(bp2.xy, (bp2.x, bp2.y))
|
||||
|
||||
# 5G
|
||||
EccPoint(x=0x7a9f9335a48dcb0e2ba7601eedb50def80cbcf728562ada756d761e8958812808bc0d57a920c3c96f07b2d8cefc6f950d0a99d1092030034,
|
||||
y=0xadfd751a2517edd3b9109ce4fd580ade260ca1823ab18fced86551f7b698017127d7a4ee59d2b33c58405512881f225443b4731472f435eb,
|
||||
curve="Ed448")
|
||||
|
||||
# Catch if point is not on the curve
|
||||
self.assertRaises(ValueError, EccPoint, 34, 35, curve="Ed448")
|
||||
|
||||
def test_set(self):
|
||||
pointW = EccPoint(0, 1, curve="Ed448")
|
||||
pointW.set(self.pointG)
|
||||
self.assertEqual(pointW.x, self.pointG.x)
|
||||
self.assertEqual(pointW.y, self.pointG.y)
|
||||
|
||||
def test_copy(self):
|
||||
pointW = self.pointG.copy()
|
||||
self.assertEqual(pointW.x, self.pointG.x)
|
||||
self.assertEqual(pointW.y, self.pointG.y)
|
||||
|
||||
def test_equal(self):
|
||||
pointH = self.pointG.copy()
|
||||
pointI = self.pointG2.copy()
|
||||
self.assertEqual(self.pointG, pointH)
|
||||
self.assertNotEqual(self.pointG, pointI)
|
||||
|
||||
def test_pai(self):
|
||||
pai = EccPoint(0, 1, curve="Ed448")
|
||||
self.assertTrue(pai.is_point_at_infinity())
|
||||
self.assertEqual(pai, pai.point_at_infinity())
|
||||
|
||||
def test_negate(self):
|
||||
negG = -self.pointG
|
||||
sum = self.pointG + negG
|
||||
self.assertTrue(sum.is_point_at_infinity())
|
||||
|
||||
def test_addition(self):
|
||||
self.assertEqual(self.pointG + self.pointG2, self.pointG3)
|
||||
self.assertEqual(self.pointG2 + self.pointG, self.pointG3)
|
||||
self.assertEqual(self.pointG2 + self.pointG.point_at_infinity(), self.pointG2)
|
||||
self.assertEqual(self.pointG.point_at_infinity() + self.pointG2, self.pointG2)
|
||||
|
||||
G5 = self.pointG2 + self.pointG3
|
||||
self.assertEqual(G5.x, 0x7a9f9335a48dcb0e2ba7601eedb50def80cbcf728562ada756d761e8958812808bc0d57a920c3c96f07b2d8cefc6f950d0a99d1092030034)
|
||||
self.assertEqual(G5.y, 0xadfd751a2517edd3b9109ce4fd580ade260ca1823ab18fced86551f7b698017127d7a4ee59d2b33c58405512881f225443b4731472f435eb)
|
||||
|
||||
def test_inplace_addition(self):
|
||||
pointH = self.pointG.copy()
|
||||
pointH += self.pointG
|
||||
self.assertEqual(pointH, self.pointG2)
|
||||
pointH += self.pointG
|
||||
self.assertEqual(pointH, self.pointG3)
|
||||
pointH += self.pointG.point_at_infinity()
|
||||
self.assertEqual(pointH, self.pointG3)
|
||||
|
||||
def test_doubling(self):
|
||||
pointH = self.pointG.copy()
|
||||
pointH.double()
|
||||
self.assertEqual(pointH.x, self.pointG2.x)
|
||||
self.assertEqual(pointH.y, self.pointG2.y)
|
||||
|
||||
# 2*0
|
||||
pai = self.pointG.point_at_infinity()
|
||||
pointR = pai.copy()
|
||||
pointR.double()
|
||||
self.assertEqual(pointR, pai)
|
||||
|
||||
def test_scalar_multiply(self):
|
||||
d = 0
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, 0)
|
||||
self.assertEqual(pointH.y, 1)
|
||||
|
||||
d = 1
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, self.pointG.x)
|
||||
self.assertEqual(pointH.y, self.pointG.y)
|
||||
|
||||
d = 2
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, self.pointG2.x)
|
||||
self.assertEqual(pointH.y, self.pointG2.y)
|
||||
|
||||
d = 3
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, self.pointG3.x)
|
||||
self.assertEqual(pointH.y, self.pointG3.y)
|
||||
|
||||
d = 4
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, 0x49dcbc5c6c0cce2c1419a17226f929ea255a09cf4e0891c693fda4be70c74cc301b7bdf1515dd8ba21aee1798949e120e2ce42ac48ba7f30)
|
||||
self.assertEqual(pointH.y, 0xd49077e4accde527164b33a5de021b979cb7c02f0457d845c90dc3227b8a5bc1c0d8f97ea1ca9472b5d444285d0d4f5b32e236f86de51839)
|
||||
|
||||
d = 5
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, 0x7a9f9335a48dcb0e2ba7601eedb50def80cbcf728562ada756d761e8958812808bc0d57a920c3c96f07b2d8cefc6f950d0a99d1092030034)
|
||||
self.assertEqual(pointH.y, 0xadfd751a2517edd3b9109ce4fd580ade260ca1823ab18fced86551f7b698017127d7a4ee59d2b33c58405512881f225443b4731472f435eb)
|
||||
|
||||
d = 10
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, 0x77486f9d19f6411cdd35d30d1c3235f71936452c787e5c034134d3e8172278aca61622bc805761ce3dab65118a0122d73b403165d0ed303d)
|
||||
self.assertEqual(pointH.y, 0x4d2fea0b026be11024f1f0fe7e94e618e8ac17381ada1d1bf7ee293a68ff5d0bf93c1997dc1aabdc0c7e6381428d85b6b1954a89e4cddf67)
|
||||
|
||||
d = 20
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, 0x3c236422354600fe6763defcc1503737e4ed89e262d0de3ec1e552020f2a56fe3b9e1e012d021072598c3c2821e18268bb8fb8339c0d1216)
|
||||
self.assertEqual(pointH.y, 0xb555b9721f630ccb05fc466de4c74d3d2781e69eca88e1b040844f04cab39fd946f91c688fa42402bb38fb9c3e61231017020b219b4396e1)
|
||||
|
||||
d = 255
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, 0xbeb7f8388b05cd9c1aa2e3c0dcf31e2b563659361826225390e7748654f627d5c36cbe627e9019936b56d15d4dad7c337c09bac64ff4197f)
|
||||
self.assertEqual(pointH.y, 0x1e37312b2dd4e9440c43c6e7725fc4fa3d11e582d4863f1d018e28f50c0efdb1f53f9b01ada7c87fa162b1f0d72401015d57613d25f1ad53)
|
||||
|
||||
d = 256
|
||||
pointH = d * self.pointG
|
||||
self.assertEqual(pointH.x, 0xf19c34feb56730e3e2be761ac0a2a2b24853b281dda019fc35a5ab58e3696beb39609ae756b0d20fb7ccf0d79aaf5f3bca2e4fdb25bfac1c)
|
||||
self.assertEqual(pointH.y, 0x3beb69cc9111bffcaddc61d363ce6fe5dd44da4aadce78f52e92e985d5442344ced72c4611ed0daac9f4f5661eab73d7a12d25ce8a30241e)
|
||||
|
||||
def test_sizes(self):
|
||||
self.assertEqual(self.pointG.size_in_bits(), 448)
|
||||
self.assertEqual(self.pointG.size_in_bytes(), 56)
|
||||
|
||||
|
||||
class TestEccKey_Ed448(unittest.TestCase):
|
||||
|
||||
def test_private_key(self):
|
||||
seed = unhexlify("4adf5d37ac6785e83e99a924f92676d366a78690af59c92b6bdf14f9cdbcf26fdad478109607583d633b60078d61d51d81b7509c5433b0d4c9")
|
||||
Px = 0x72a01eea003a35f9ac44231dc4aae2a382f351d80bf32508175b0855edcf389aa2bbf308dd961ce361a6e7c2091bc78957f6ebcf3002a617
|
||||
Py = 0x9e0d08d84586e9aeefecacb41d049b831f1a3ee0c3eada63e34557b30702b50ab59fb372feff7c30b8cbb7dd51afbe88444ec56238722ec1
|
||||
|
||||
key = EccKey(curve="Ed448", seed=seed)
|
||||
self.assertEqual(key.seed, seed)
|
||||
self.assertEqual(key.d, 0xb07cf179604f83433186e5178760c759c15125ee54ff6f8dcde46e872b709ac82ed0bd0a4e036d774034dcb18a9fb11894657a1485895f80)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.pointQ.x, Px)
|
||||
self.assertEqual(key.pointQ.y, Py)
|
||||
|
||||
point = EccPoint(Px, Py, "ed448")
|
||||
key = EccKey(curve="Ed448", seed=seed, point=point)
|
||||
self.assertEqual(key.d, 0xb07cf179604f83433186e5178760c759c15125ee54ff6f8dcde46e872b709ac82ed0bd0a4e036d774034dcb18a9fb11894657a1485895f80)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.pointQ, point)
|
||||
|
||||
# Other names
|
||||
key = EccKey(curve="ed448", seed=seed)
|
||||
|
||||
# Must not accept d parameter
|
||||
self.assertRaises(ValueError, EccKey, curve="ed448", d=1)
|
||||
|
||||
def test_public_key(self):
|
||||
point = EccPoint(_curves['ed448'].Gx, _curves['ed448'].Gy, curve='ed448')
|
||||
key = EccKey(curve="ed448", point=point)
|
||||
self.assertFalse(key.has_private())
|
||||
self.assertEqual(key.pointQ, point)
|
||||
|
||||
def test_public_key_derived(self):
|
||||
priv_key = EccKey(curve="ed448", seed=b'H'*57)
|
||||
pub_key = priv_key.public_key()
|
||||
self.assertFalse(pub_key.has_private())
|
||||
self.assertEqual(priv_key.pointQ, pub_key.pointQ)
|
||||
|
||||
def test_invalid_seed(self):
|
||||
self.assertRaises(ValueError, lambda: EccKey(curve="ed448", seed=b'H' * 56))
|
||||
|
||||
def test_equality(self):
|
||||
private_key = ECC.construct(seed=b'H'*57, curve="Ed448")
|
||||
private_key2 = ECC.construct(seed=b'H'*57, curve="ed448")
|
||||
private_key3 = ECC.construct(seed=b'C'*57, curve="Ed448")
|
||||
|
||||
public_key = private_key.public_key()
|
||||
public_key2 = private_key2.public_key()
|
||||
public_key3 = private_key3.public_key()
|
||||
|
||||
self.assertEqual(private_key, private_key2)
|
||||
self.assertNotEqual(private_key, private_key3)
|
||||
|
||||
self.assertEqual(public_key, public_key2)
|
||||
self.assertNotEqual(public_key, public_key3)
|
||||
|
||||
self.assertNotEqual(public_key, private_key)
|
||||
|
||||
def test_name_consistency(self):
|
||||
key = ECC.generate(curve='ed448')
|
||||
self.assertIn("curve='Ed448'", repr(key))
|
||||
self.assertEqual(key.curve, 'Ed448')
|
||||
self.assertEqual(key.public_key().curve, 'Ed448')
|
||||
|
||||
|
||||
class TestEccModule_Ed448(unittest.TestCase):
|
||||
|
||||
def test_generate(self):
|
||||
key = ECC.generate(curve="Ed448")
|
||||
self.assertTrue(key.has_private())
|
||||
point = EccPoint(_curves['Ed448'].Gx, _curves['Ed448'].Gy, curve="Ed448") * key.d
|
||||
self.assertEqual(key.pointQ, point)
|
||||
|
||||
# Always random
|
||||
key2 = ECC.generate(curve="Ed448")
|
||||
self.assertNotEqual(key, key2)
|
||||
|
||||
# Other names
|
||||
ECC.generate(curve="Ed448")
|
||||
|
||||
# Random source
|
||||
key1 = ECC.generate(curve="Ed448", randfunc=SHAKE128.new().read)
|
||||
key2 = ECC.generate(curve="Ed448", randfunc=SHAKE128.new().read)
|
||||
self.assertEqual(key1, key2)
|
||||
|
||||
def test_construct(self):
|
||||
seed = unhexlify("4adf5d37ac6785e83e99a924f92676d366a78690af59c92b6bdf14f9cdbcf26fdad478109607583d633b60078d61d51d81b7509c5433b0d4c9")
|
||||
Px = 0x72a01eea003a35f9ac44231dc4aae2a382f351d80bf32508175b0855edcf389aa2bbf308dd961ce361a6e7c2091bc78957f6ebcf3002a617
|
||||
Py = 0x9e0d08d84586e9aeefecacb41d049b831f1a3ee0c3eada63e34557b30702b50ab59fb372feff7c30b8cbb7dd51afbe88444ec56238722ec1
|
||||
d = 0xb07cf179604f83433186e5178760c759c15125ee54ff6f8dcde46e872b709ac82ed0bd0a4e036d774034dcb18a9fb11894657a1485895f80
|
||||
point = EccPoint(Px, Py, curve="Ed448")
|
||||
|
||||
# Private key only
|
||||
key = ECC.construct(curve="Ed448", seed=seed)
|
||||
self.assertEqual(key.pointQ, point)
|
||||
self.assertTrue(key.has_private())
|
||||
|
||||
# Public key only
|
||||
key = ECC.construct(curve="Ed448", point_x=Px, point_y=Py)
|
||||
self.assertEqual(key.pointQ, point)
|
||||
self.assertFalse(key.has_private())
|
||||
|
||||
# Private and public key
|
||||
key = ECC.construct(curve="Ed448", seed=seed, point_x=Px, point_y=Py)
|
||||
self.assertEqual(key.pointQ, point)
|
||||
self.assertTrue(key.has_private())
|
||||
|
||||
# Other names
|
||||
key = ECC.construct(curve="ed448", seed=seed)
|
||||
|
||||
def test_negative_construct(self):
|
||||
coord = dict(point_x=10, point_y=4)
|
||||
coordG = dict(point_x=_curves['ed448'].Gx, point_y=_curves['ed448'].Gy)
|
||||
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Ed448", **coord)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Ed448", d=2, **coordG)
|
||||
self.assertRaises(ValueError, ECC.construct, curve="Ed448", seed=b'H'*58)
|
||||
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(TestEccPoint_Ed448)
|
||||
tests += list_test_cases(TestEccKey_Ed448)
|
||||
tests += list_test_cases(TestEccModule_Ed448)
|
||||
return tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
def suite():
|
||||
return unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
1440
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ECC_NIST.py
vendored
Normal file
1440
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ECC_NIST.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
217
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ElGamal.py
vendored
Normal file
217
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ElGamal.py
vendored
Normal file
@ -0,0 +1,217 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_ElGamal.py: Self-test for the ElGamal primitive
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
"""Self-test suite for Crypto.PublicKey.ElGamal"""
|
||||
|
||||
__revision__ = "$Id$"
|
||||
|
||||
import unittest
|
||||
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
|
||||
from Crypto import Random
|
||||
from Crypto.PublicKey import ElGamal
|
||||
from Crypto.Util.number import bytes_to_long
|
||||
from Crypto.Util.py3compat import *
|
||||
|
||||
class ElGamalTest(unittest.TestCase):
|
||||
|
||||
#
|
||||
# Test vectors
|
||||
#
|
||||
# There seem to be no real ElGamal test vectors available in the
|
||||
# public domain. The following test vectors have been generated
|
||||
# with libgcrypt 1.5.0.
|
||||
#
|
||||
# Encryption
|
||||
tve=[
|
||||
{
|
||||
# 256 bits
|
||||
'p' :'BA4CAEAAED8CBE952AFD2126C63EB3B345D65C2A0A73D2A3AD4138B6D09BD933',
|
||||
'g' :'05',
|
||||
'y' :'60D063600ECED7C7C55146020E7A31C4476E9793BEAED420FEC9E77604CAE4EF',
|
||||
'x' :'1D391BA2EE3C37FE1BA175A69B2C73A11238AD77675932',
|
||||
'k' :'F5893C5BAB4131264066F57AB3D8AD89E391A0B68A68A1',
|
||||
'pt' :'48656C6C6F207468657265',
|
||||
'ct1':'32BFD5F487966CEA9E9356715788C491EC515E4ED48B58F0F00971E93AAA5EC7',
|
||||
'ct2':'7BE8FBFF317C93E82FCEF9BD515284BA506603FEA25D01C0CB874A31F315EE68'
|
||||
},
|
||||
|
||||
{
|
||||
# 512 bits
|
||||
'p' :'F1B18AE9F7B4E08FDA9A04832F4E919D89462FD31BF12F92791A93519F75076D6CE3942689CDFF2F344CAFF0F82D01864F69F3AECF566C774CBACF728B81A227',
|
||||
'g' :'07',
|
||||
'y' :'688628C676E4F05D630E1BE39D0066178CA7AA83836B645DE5ADD359B4825A12B02EF4252E4E6FA9BEC1DB0BE90F6D7C8629CABB6E531F472B2664868156E20C',
|
||||
'x' :'14E60B1BDFD33436C0DA8A22FDC14A2CCDBBED0627CE68',
|
||||
'k' :'38DBF14E1F319BDA9BAB33EEEADCAF6B2EA5250577ACE7',
|
||||
'pt' :'48656C6C6F207468657265',
|
||||
'ct1':'290F8530C2CC312EC46178724F196F308AD4C523CEABB001FACB0506BFED676083FE0F27AC688B5C749AB3CB8A80CD6F7094DBA421FB19442F5A413E06A9772B',
|
||||
'ct2':'1D69AAAD1DC50493FB1B8E8721D621D683F3BF1321BE21BC4A43E11B40C9D4D9C80DE3AAC2AB60D31782B16B61112E68220889D53C4C3136EE6F6CE61F8A23A0'
|
||||
}
|
||||
]
|
||||
|
||||
# Signature
|
||||
tvs=[
|
||||
{
|
||||
# 256 bits
|
||||
'p' :'D2F3C41EA66530838A704A48FFAC9334F4701ECE3A97CEE4C69DD01AE7129DD7',
|
||||
'g' :'05',
|
||||
'y' :'C3F9417DC0DAFEA6A05C1D2333B7A95E63B3F4F28CC962254B3256984D1012E7',
|
||||
'x' :'165E4A39BE44D5A2D8B1332D416BC559616F536BC735BB',
|
||||
'k' :'C7F0C794A7EAD726E25A47FF8928013680E73C51DD3D7D99BFDA8F492585928F',
|
||||
'h' :'48656C6C6F207468657265',
|
||||
'sig1':'35CA98133779E2073EF31165AFCDEB764DD54E96ADE851715495F9C635E1E7C2',
|
||||
'sig2':'0135B88B1151279FE5D8078D4FC685EE81177EE9802AB123A73925FC1CB059A7',
|
||||
},
|
||||
{
|
||||
# 512 bits
|
||||
'p' :'E24CF3A4B8A6AF749DCA6D714282FE4AABEEE44A53BB6ED15FBE32B5D3C3EF9CC4124A2ECA331F3C1C1B667ACA3766825217E7B5F9856648D95F05330C6A19CF',
|
||||
'g' :'0B',
|
||||
'y' :'2AD3A1049CA5D4ED207B2431C79A8719BB4073D4A94E450EA6CEE8A760EB07ADB67C0D52C275EE85D7B52789061EE45F2F37D9B2AE522A51C28329766BFE68AC',
|
||||
'x' :'16CBB4F46D9ECCF24FF9F7E63CAA3BD8936341555062AB',
|
||||
'k' :'8A3D89A4E429FD2476D7D717251FB79BF900FFE77444E6BB8299DC3F84D0DD57ABAB50732AE158EA52F5B9E7D8813E81FD9F79470AE22F8F1CF9AEC820A78C69',
|
||||
'h' :'48656C6C6F207468657265',
|
||||
'sig1':'BE001AABAFFF976EC9016198FBFEA14CBEF96B000CCC0063D3324016F9E91FE80D8F9325812ED24DDB2B4D4CF4430B169880B3CE88313B53255BD4EC0378586F',
|
||||
'sig2':'5E266F3F837BA204E3BBB6DBECC0611429D96F8C7CE8F4EFDF9D4CB681C2A954468A357BF4242CEC7418B51DFC081BCD21299EF5B5A0DDEF3A139A1817503DDE',
|
||||
}
|
||||
]
|
||||
|
||||
def test_generate_180(self):
|
||||
self._test_random_key(180)
|
||||
|
||||
def test_encryption(self):
|
||||
for tv in self.tve:
|
||||
d = self.convert_tv(tv, True)
|
||||
key = ElGamal.construct(d['key'])
|
||||
ct = key._encrypt(d['pt'], d['k'])
|
||||
self.assertEqual(ct[0], d['ct1'])
|
||||
self.assertEqual(ct[1], d['ct2'])
|
||||
|
||||
def test_decryption(self):
|
||||
for tv in self.tve:
|
||||
d = self.convert_tv(tv, True)
|
||||
key = ElGamal.construct(d['key'])
|
||||
pt = key._decrypt((d['ct1'], d['ct2']))
|
||||
self.assertEqual(pt, d['pt'])
|
||||
|
||||
def test_signing(self):
|
||||
for tv in self.tvs:
|
||||
d = self.convert_tv(tv, True)
|
||||
key = ElGamal.construct(d['key'])
|
||||
sig1, sig2 = key._sign(d['h'], d['k'])
|
||||
self.assertEqual(sig1, d['sig1'])
|
||||
self.assertEqual(sig2, d['sig2'])
|
||||
|
||||
def test_verification(self):
|
||||
for tv in self.tvs:
|
||||
d = self.convert_tv(tv, True)
|
||||
key = ElGamal.construct(d['key'])
|
||||
# Positive test
|
||||
res = key._verify( d['h'], (d['sig1'],d['sig2']) )
|
||||
self.assertTrue(res)
|
||||
# Negative test
|
||||
res = key._verify( d['h'], (d['sig1']+1,d['sig2']) )
|
||||
self.assertFalse(res)
|
||||
|
||||
def test_bad_key3(self):
|
||||
tup = tup0 = list(self.convert_tv(self.tvs[0], 1)['key'])[:3]
|
||||
tup[0] += 1 # p += 1 (not prime)
|
||||
self.assertRaises(ValueError, ElGamal.construct, tup)
|
||||
|
||||
tup = tup0
|
||||
tup[1] = 1 # g = 1
|
||||
self.assertRaises(ValueError, ElGamal.construct, tup)
|
||||
|
||||
tup = tup0
|
||||
tup[2] = tup[0]*2 # y = 2*p
|
||||
self.assertRaises(ValueError, ElGamal.construct, tup)
|
||||
|
||||
def test_bad_key4(self):
|
||||
tup = tup0 = list(self.convert_tv(self.tvs[0], 1)['key'])
|
||||
tup[3] += 1 # x += 1
|
||||
self.assertRaises(ValueError, ElGamal.construct, tup)
|
||||
|
||||
def convert_tv(self, tv, as_longs=0):
|
||||
"""Convert a test vector from textual form (hexadecimal ascii
|
||||
to either integers or byte strings."""
|
||||
key_comps = 'p','g','y','x'
|
||||
tv2 = {}
|
||||
for c in tv.keys():
|
||||
tv2[c] = a2b_hex(tv[c])
|
||||
if as_longs or c in key_comps or c in ('sig1','sig2'):
|
||||
tv2[c] = bytes_to_long(tv2[c])
|
||||
tv2['key']=[]
|
||||
for c in key_comps:
|
||||
tv2['key'] += [tv2[c]]
|
||||
del tv2[c]
|
||||
return tv2
|
||||
|
||||
def _test_random_key(self, bits):
|
||||
elgObj = ElGamal.generate(bits, Random.new().read)
|
||||
self._check_private_key(elgObj)
|
||||
self._exercise_primitive(elgObj)
|
||||
pub = elgObj.publickey()
|
||||
self._check_public_key(pub)
|
||||
self._exercise_public_primitive(elgObj)
|
||||
|
||||
def _check_private_key(self, elgObj):
|
||||
|
||||
# Check capabilities
|
||||
self.assertTrue(elgObj.has_private())
|
||||
|
||||
# Sanity check key data
|
||||
self.assertTrue(1<elgObj.g<(elgObj.p-1))
|
||||
self.assertEqual(pow(elgObj.g, elgObj.p-1, elgObj.p), 1)
|
||||
self.assertTrue(1<elgObj.x<(elgObj.p-1))
|
||||
self.assertEqual(pow(elgObj.g, elgObj.x, elgObj.p), elgObj.y)
|
||||
|
||||
def _check_public_key(self, elgObj):
|
||||
|
||||
# Check capabilities
|
||||
self.assertFalse(elgObj.has_private())
|
||||
|
||||
# Sanity check key data
|
||||
self.assertTrue(1<elgObj.g<(elgObj.p-1))
|
||||
self.assertEqual(pow(elgObj.g, elgObj.p-1, elgObj.p), 1)
|
||||
|
||||
def _exercise_primitive(self, elgObj):
|
||||
# Test encryption/decryption
|
||||
plaintext = 127218
|
||||
ciphertext = elgObj._encrypt(plaintext, 123456789)
|
||||
plaintextP = elgObj._decrypt(ciphertext)
|
||||
self.assertEqual(plaintext, plaintextP)
|
||||
|
||||
# Test signature/verification
|
||||
signature = elgObj._sign(plaintext, 987654321)
|
||||
elgObj._verify(plaintext, signature)
|
||||
|
||||
def _exercise_public_primitive(self, elgObj):
|
||||
plaintext = 92987276
|
||||
ciphertext = elgObj._encrypt(plaintext, 123456789)
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(ElGamalTest)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
324
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_RSA.py
vendored
Normal file
324
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_RSA.py
vendored
Normal file
@ -0,0 +1,324 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_RSA.py: Self-test for the RSA primitive
|
||||
#
|
||||
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
"""Self-test suite for Crypto.PublicKey.RSA"""
|
||||
|
||||
__revision__ = "$Id$"
|
||||
|
||||
import os
|
||||
import pickle
|
||||
from pickle import PicklingError
|
||||
from Crypto.Util.py3compat import *
|
||||
|
||||
import unittest
|
||||
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
|
||||
|
||||
class RSATest(unittest.TestCase):
|
||||
# Test vectors from "RSA-OAEP and RSA-PSS test vectors (.zip file)"
|
||||
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
|
||||
# See RSADSI's PKCS#1 page at
|
||||
# http://www.rsa.com/rsalabs/node.asp?id=2125
|
||||
|
||||
# from oaep-int.txt
|
||||
|
||||
# TODO: PyCrypto treats the message as starting *after* the leading "00"
|
||||
# TODO: That behaviour should probably be changed in the future.
|
||||
plaintext = """
|
||||
eb 7a 19 ac e9 e3 00 63 50 e3 29 50 4b 45 e2
|
||||
ca 82 31 0b 26 dc d8 7d 5c 68 f1 ee a8 f5 52 67
|
||||
c3 1b 2e 8b b4 25 1f 84 d7 e0 b2 c0 46 26 f5 af
|
||||
f9 3e dc fb 25 c9 c2 b3 ff 8a e1 0e 83 9a 2d db
|
||||
4c dc fe 4f f4 77 28 b4 a1 b7 c1 36 2b aa d2 9a
|
||||
b4 8d 28 69 d5 02 41 21 43 58 11 59 1b e3 92 f9
|
||||
82 fb 3e 87 d0 95 ae b4 04 48 db 97 2f 3a c1 4f
|
||||
7b c2 75 19 52 81 ce 32 d2 f1 b7 6d 4d 35 3e 2d
|
||||
"""
|
||||
|
||||
ciphertext = """
|
||||
12 53 e0 4d c0 a5 39 7b b4 4a 7a b8 7e 9b f2 a0
|
||||
39 a3 3d 1e 99 6f c8 2a 94 cc d3 00 74 c9 5d f7
|
||||
63 72 20 17 06 9e 52 68 da 5d 1c 0b 4f 87 2c f6
|
||||
53 c1 1d f8 23 14 a6 79 68 df ea e2 8d ef 04 bb
|
||||
6d 84 b1 c3 1d 65 4a 19 70 e5 78 3b d6 eb 96 a0
|
||||
24 c2 ca 2f 4a 90 fe 9f 2e f5 c9 c1 40 e5 bb 48
|
||||
da 95 36 ad 87 00 c8 4f c9 13 0a de a7 4e 55 8d
|
||||
51 a7 4d df 85 d8 b5 0d e9 68 38 d6 06 3e 09 55
|
||||
"""
|
||||
|
||||
modulus = """
|
||||
bb f8 2f 09 06 82 ce 9c 23 38 ac 2b 9d a8 71 f7
|
||||
36 8d 07 ee d4 10 43 a4 40 d6 b6 f0 74 54 f5 1f
|
||||
b8 df ba af 03 5c 02 ab 61 ea 48 ce eb 6f cd 48
|
||||
76 ed 52 0d 60 e1 ec 46 19 71 9d 8a 5b 8b 80 7f
|
||||
af b8 e0 a3 df c7 37 72 3e e6 b4 b7 d9 3a 25 84
|
||||
ee 6a 64 9d 06 09 53 74 88 34 b2 45 45 98 39 4e
|
||||
e0 aa b1 2d 7b 61 a5 1f 52 7a 9a 41 f6 c1 68 7f
|
||||
e2 53 72 98 ca 2a 8f 59 46 f8 e5 fd 09 1d bd cb
|
||||
"""
|
||||
|
||||
e = 0x11 # public exponent
|
||||
|
||||
prime_factor = """
|
||||
c9 7f b1 f0 27 f4 53 f6 34 12 33 ea aa d1 d9 35
|
||||
3f 6c 42 d0 88 66 b1 d0 5a 0f 20 35 02 8b 9d 86
|
||||
98 40 b4 16 66 b4 2e 92 ea 0d a3 b4 32 04 b5 cf
|
||||
ce 33 52 52 4d 04 16 a5 a4 41 e7 00 af 46 15 03
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
global RSA, Random, bytes_to_long
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto import Random
|
||||
from Crypto.Util.number import bytes_to_long, inverse
|
||||
self.n = bytes_to_long(a2b_hex(self.modulus))
|
||||
self.p = bytes_to_long(a2b_hex(self.prime_factor))
|
||||
|
||||
# Compute q, d, and u from n, e, and p
|
||||
self.q = self.n // self.p
|
||||
self.d = inverse(self.e, (self.p-1)*(self.q-1))
|
||||
self.u = inverse(self.p, self.q) # u = e**-1 (mod q)
|
||||
|
||||
self.rsa = RSA
|
||||
|
||||
def test_generate_1arg(self):
|
||||
"""RSA (default implementation) generated key (1 argument)"""
|
||||
rsaObj = self.rsa.generate(1024)
|
||||
self._check_private_key(rsaObj)
|
||||
self._exercise_primitive(rsaObj)
|
||||
pub = rsaObj.public_key()
|
||||
self._check_public_key(pub)
|
||||
self._exercise_public_primitive(rsaObj)
|
||||
|
||||
def test_generate_2arg(self):
|
||||
"""RSA (default implementation) generated key (2 arguments)"""
|
||||
rsaObj = self.rsa.generate(1024, Random.new().read)
|
||||
self._check_private_key(rsaObj)
|
||||
self._exercise_primitive(rsaObj)
|
||||
pub = rsaObj.public_key()
|
||||
self._check_public_key(pub)
|
||||
self._exercise_public_primitive(rsaObj)
|
||||
|
||||
def test_generate_3args(self):
|
||||
rsaObj = self.rsa.generate(1024, Random.new().read,e=65537)
|
||||
self._check_private_key(rsaObj)
|
||||
self._exercise_primitive(rsaObj)
|
||||
pub = rsaObj.public_key()
|
||||
self._check_public_key(pub)
|
||||
self._exercise_public_primitive(rsaObj)
|
||||
self.assertEqual(65537,rsaObj.e)
|
||||
|
||||
def test_construct_2tuple(self):
|
||||
"""RSA (default implementation) constructed key (2-tuple)"""
|
||||
pub = self.rsa.construct((self.n, self.e))
|
||||
self._check_public_key(pub)
|
||||
self._check_encryption(pub)
|
||||
|
||||
def test_construct_3tuple(self):
|
||||
"""RSA (default implementation) constructed key (3-tuple)"""
|
||||
rsaObj = self.rsa.construct((self.n, self.e, self.d))
|
||||
self._check_encryption(rsaObj)
|
||||
self._check_decryption(rsaObj)
|
||||
|
||||
def test_construct_4tuple(self):
|
||||
"""RSA (default implementation) constructed key (4-tuple)"""
|
||||
rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p))
|
||||
self._check_encryption(rsaObj)
|
||||
self._check_decryption(rsaObj)
|
||||
|
||||
def test_construct_5tuple(self):
|
||||
"""RSA (default implementation) constructed key (5-tuple)"""
|
||||
rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q))
|
||||
self._check_private_key(rsaObj)
|
||||
self._check_encryption(rsaObj)
|
||||
self._check_decryption(rsaObj)
|
||||
|
||||
def test_construct_6tuple(self):
|
||||
"""RSA (default implementation) constructed key (6-tuple)"""
|
||||
rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q, self.u))
|
||||
self._check_private_key(rsaObj)
|
||||
self._check_encryption(rsaObj)
|
||||
self._check_decryption(rsaObj)
|
||||
|
||||
def test_construct_bad_key2(self):
|
||||
tup = (self.n, 1)
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
# An even modulus is wrong
|
||||
tup = (self.n+1, self.e)
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
def test_construct_bad_key3(self):
|
||||
tup = (self.n, self.e, self.d+1)
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
def test_construct_bad_key5(self):
|
||||
tup = (self.n, self.e, self.d, self.p, self.p)
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
tup = (self.p*self.p, self.e, self.p, self.p)
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
tup = (self.p*self.p, 3, self.p, self.q)
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
def test_construct_bad_key6(self):
|
||||
tup = (self.n, self.e, self.d, self.p, self.q, 10)
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
from Crypto.Util.number import inverse
|
||||
tup = (self.n, self.e, self.d, self.p, self.q, inverse(self.q, self.p))
|
||||
self.assertRaises(ValueError, self.rsa.construct, tup)
|
||||
|
||||
def test_factoring(self):
|
||||
rsaObj = self.rsa.construct([self.n, self.e, self.d])
|
||||
self.assertTrue(rsaObj.p==self.p or rsaObj.p==self.q)
|
||||
self.assertTrue(rsaObj.q==self.p or rsaObj.q==self.q)
|
||||
self.assertTrue(rsaObj.q*rsaObj.p == self.n)
|
||||
|
||||
self.assertRaises(ValueError, self.rsa.construct, [self.n, self.e, self.n-1])
|
||||
|
||||
def test_repr(self):
|
||||
rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q))
|
||||
repr(rsaObj)
|
||||
|
||||
def test_serialization(self):
|
||||
"""RSA keys are unpickable"""
|
||||
|
||||
rsa_key = self.rsa.generate(1024)
|
||||
self.assertRaises(PicklingError, pickle.dumps, rsa_key)
|
||||
|
||||
def test_raw_rsa_boundary(self):
|
||||
# The argument of every RSA raw operation (encrypt/decrypt) must be
|
||||
# non-negative and no larger than the modulus
|
||||
rsa_obj = self.rsa.generate(1024)
|
||||
|
||||
self.assertRaises(ValueError, rsa_obj._decrypt, rsa_obj.n)
|
||||
self.assertRaises(ValueError, rsa_obj._decrypt_to_bytes, rsa_obj.n)
|
||||
self.assertRaises(ValueError, rsa_obj._encrypt, rsa_obj.n)
|
||||
|
||||
self.assertRaises(ValueError, rsa_obj._decrypt, -1)
|
||||
self.assertRaises(ValueError, rsa_obj._decrypt_to_bytes, -1)
|
||||
self.assertRaises(ValueError, rsa_obj._encrypt, -1)
|
||||
|
||||
def test_size(self):
|
||||
pub = self.rsa.construct((self.n, self.e))
|
||||
self.assertEqual(pub.size_in_bits(), 1024)
|
||||
self.assertEqual(pub.size_in_bytes(), 128)
|
||||
|
||||
def _check_private_key(self, rsaObj):
|
||||
from Crypto.Math.Numbers import Integer
|
||||
|
||||
# Check capabilities
|
||||
self.assertEqual(1, rsaObj.has_private())
|
||||
|
||||
# Sanity check key data
|
||||
self.assertEqual(rsaObj.n, rsaObj.p * rsaObj.q) # n = pq
|
||||
lcm = int(Integer(rsaObj.p-1).lcm(rsaObj.q-1))
|
||||
self.assertEqual(1, rsaObj.d * rsaObj.e % lcm) # ed = 1 (mod LCM(p-1, q-1))
|
||||
self.assertEqual(1, rsaObj.p * rsaObj.u % rsaObj.q) # pu = 1 (mod q)
|
||||
self.assertEqual(1, rsaObj.p > 1) # p > 1
|
||||
self.assertEqual(1, rsaObj.q > 1) # q > 1
|
||||
self.assertEqual(1, rsaObj.e > 1) # e > 1
|
||||
self.assertEqual(1, rsaObj.d > 1) # d > 1
|
||||
|
||||
self.assertEqual(rsaObj.u, rsaObj.invp)
|
||||
self.assertEqual(1, rsaObj.q * rsaObj.invq % rsaObj.p)
|
||||
|
||||
def _check_public_key(self, rsaObj):
|
||||
ciphertext = a2b_hex(self.ciphertext)
|
||||
|
||||
# Check capabilities
|
||||
self.assertEqual(0, rsaObj.has_private())
|
||||
|
||||
# Check rsaObj.[ne] -> rsaObj.[ne] mapping
|
||||
self.assertEqual(rsaObj.n, rsaObj.n)
|
||||
self.assertEqual(rsaObj.e, rsaObj.e)
|
||||
|
||||
# Check that private parameters are all missing
|
||||
self.assertEqual(0, hasattr(rsaObj, 'd'))
|
||||
self.assertEqual(0, hasattr(rsaObj, 'p'))
|
||||
self.assertEqual(0, hasattr(rsaObj, 'q'))
|
||||
self.assertEqual(0, hasattr(rsaObj, 'u'))
|
||||
|
||||
# Sanity check key data
|
||||
self.assertEqual(1, rsaObj.e > 1) # e > 1
|
||||
|
||||
# Public keys should not be able to sign or decrypt
|
||||
self.assertRaises(TypeError, rsaObj._decrypt,
|
||||
bytes_to_long(ciphertext))
|
||||
self.assertRaises(TypeError, rsaObj._decrypt_to_bytes,
|
||||
bytes_to_long(ciphertext))
|
||||
|
||||
# Check __eq__ and __ne__
|
||||
self.assertEqual(rsaObj.public_key() == rsaObj.public_key(),True) # assert_
|
||||
self.assertEqual(rsaObj.public_key() != rsaObj.public_key(),False) # assertFalse
|
||||
|
||||
self.assertEqual(rsaObj.publickey(), rsaObj.public_key())
|
||||
|
||||
def _exercise_primitive(self, rsaObj):
|
||||
# Since we're using a randomly-generated key, we can't check the test
|
||||
# vector, but we can make sure encryption and decryption are inverse
|
||||
# operations.
|
||||
ciphertext = bytes_to_long(a2b_hex(self.ciphertext))
|
||||
|
||||
# Test decryption
|
||||
plaintext = rsaObj._decrypt(ciphertext)
|
||||
|
||||
# Test encryption (2 arguments)
|
||||
new_ciphertext2 = rsaObj._encrypt(plaintext)
|
||||
self.assertEqual(ciphertext, new_ciphertext2)
|
||||
|
||||
def _exercise_public_primitive(self, rsaObj):
|
||||
plaintext = a2b_hex(self.plaintext)
|
||||
|
||||
# Test encryption (2 arguments)
|
||||
new_ciphertext2 = rsaObj._encrypt(bytes_to_long(plaintext))
|
||||
|
||||
def _check_encryption(self, rsaObj):
|
||||
plaintext = a2b_hex(self.plaintext)
|
||||
ciphertext = a2b_hex(self.ciphertext)
|
||||
|
||||
# Test encryption
|
||||
new_ciphertext2 = rsaObj._encrypt(bytes_to_long(plaintext))
|
||||
self.assertEqual(bytes_to_long(ciphertext), new_ciphertext2)
|
||||
|
||||
def _check_decryption(self, rsaObj):
|
||||
plaintext = bytes_to_long(a2b_hex(self.plaintext))
|
||||
ciphertext = bytes_to_long(a2b_hex(self.ciphertext))
|
||||
|
||||
# Test plain decryption
|
||||
new_plaintext = rsaObj._decrypt(ciphertext)
|
||||
self.assertEqual(plaintext, new_plaintext)
|
||||
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(RSATest)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
# vim:set ts=4 sw=4 sts=4 expandtab:
|
385
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_import_Curve25519.py
vendored
Normal file
385
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_import_Curve25519.py
vendored
Normal file
@ -0,0 +1,385 @@
|
||||
# ===================================================================
|
||||
#
|
||||
# Copyright (c) 2024, Helder Eijs <helderijs@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# ===================================================================
|
||||
|
||||
import os
|
||||
import errno
|
||||
import warnings
|
||||
import unittest
|
||||
from binascii import unhexlify
|
||||
from unittest import SkipTest
|
||||
|
||||
from Crypto.SelfTest.st_common import list_test_cases
|
||||
from Crypto.Util.py3compat import tostr, FileNotFoundError
|
||||
from Crypto.Util.asn1 import DerSequence, DerBitString
|
||||
from Crypto.Hash import SHAKE128
|
||||
|
||||
from Crypto.PublicKey import ECC
|
||||
|
||||
try:
|
||||
import pycryptodome_test_vectors # type: ignore
|
||||
test_vectors_available = True
|
||||
except ImportError:
|
||||
test_vectors_available = False
|
||||
|
||||
|
||||
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(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 SkipTest("Missing %s" % file_name)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def compact(lines):
|
||||
ext = b"".join(lines)
|
||||
return unhexlify(tostr(ext).replace(" ", "").replace(":", ""))
|
||||
|
||||
|
||||
def create_ref_keys_x25519():
|
||||
key_lines = load_file("ecc_x25519.txt").splitlines()
|
||||
seed = compact(key_lines[5:8])
|
||||
key = ECC.construct(curve="Curve25519", seed=seed)
|
||||
return (key, key.public_key())
|
||||
|
||||
|
||||
def get_fixed_prng():
|
||||
return SHAKE128.new().update(b"SEED").read
|
||||
|
||||
|
||||
def extract_bitstring_from_spki(data):
|
||||
seq = DerSequence()
|
||||
seq.decode(data)
|
||||
bs = DerBitString()
|
||||
bs.decode(seq[1])
|
||||
return bs.value
|
||||
|
||||
|
||||
class TestImport(unittest.TestCase):
|
||||
|
||||
def test_empty(self):
|
||||
self.assertRaises(ValueError, ECC.import_key, b"")
|
||||
|
||||
def test_mismatch(self):
|
||||
# Private key with X448 Object ID but X25519 key
|
||||
mismatch_hex = "302e020100300506032b656f042204207009906b64ec727d5cb5c23007bf0425b3fd79014c6cd62ca3dddfcf0f278f79"
|
||||
mismatch = unhexlify(mismatch_hex)
|
||||
self.assertRaises(ValueError, ECC.import_key, mismatch)
|
||||
|
||||
|
||||
class TestImport_Curve25519(unittest.TestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TestImport_Curve25519, self).__init__(*args, **kwargs)
|
||||
self.ref_private, self.ref_public = create_ref_keys_x25519()
|
||||
|
||||
def test_import_public_der(self):
|
||||
key_file = load_file("ecc_x25519_public.der")
|
||||
|
||||
key = ECC._import_subjectPublicKeyInfo(key_file)
|
||||
self.assertEqual(self.ref_public, key)
|
||||
|
||||
key = ECC._import_der(key_file, None)
|
||||
self.assertEqual(self.ref_public, key)
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(self.ref_public, key)
|
||||
|
||||
def test_import_pkcs8_der(self):
|
||||
key_file = load_file("ecc_x25519_private.der")
|
||||
|
||||
key = ECC._import_der(key_file, None)
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
def test_import_private_pkcs8_encrypted_1(self):
|
||||
key_file = load_file("ecc_x25519_private_p8.der")
|
||||
|
||||
key = ECC._import_der(key_file, "secret")
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
key = ECC.import_key(key_file, "secret")
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
def test_import_private_pkcs8_encrypted_2(self):
|
||||
key_file = load_file("ecc_x25519_private_p8.pem")
|
||||
|
||||
key = ECC.import_key(key_file, "secret")
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
def test_import_private_pkcs8_encrypted_3(self):
|
||||
key_file = load_file("ecc_x25519_private_p8_2.der")
|
||||
|
||||
key = ECC._import_der(key_file, "secret")
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
key = ECC.import_key(key_file, "secret")
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
def test_import_x509_der(self):
|
||||
key_file = load_file("ecc_x25519_x509.der")
|
||||
|
||||
key = ECC._import_der(key_file, None)
|
||||
self.assertEqual(self.ref_public, key)
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(self.ref_public, key)
|
||||
|
||||
def test_import_public_pem(self):
|
||||
key_file = load_file("ecc_x25519_public.pem")
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(self.ref_public, key)
|
||||
|
||||
def test_import_private_pem(self):
|
||||
key_file = load_file("ecc_x25519_private.pem")
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
def test_import_private_pem_encrypted(self):
|
||||
for algo in "des3", "aes128", "aes192", "aes256":
|
||||
key_file = load_file("ecc_x25519_private_enc_%s.pem" % algo)
|
||||
|
||||
key = ECC.import_key(key_file, "secret")
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
key = ECC.import_key(tostr(key_file), b"secret")
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
def test_import_x509_pem(self):
|
||||
key_file = load_file("ecc_x25519_x509.pem")
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(self.ref_public, key)
|
||||
|
||||
|
||||
class TestExport_Curve25519(unittest.TestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TestExport_Curve25519, self).__init__(*args, **kwargs)
|
||||
self.ref_private, self.ref_public = create_ref_keys_x25519()
|
||||
|
||||
def test_export_public_der(self):
|
||||
key_file = load_file("ecc_x25519_public.der")
|
||||
|
||||
encoded = self.ref_public._export_subjectPublicKeyInfo(True)
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
encoded = self.ref_public.export_key(format="DER")
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
encoded = self.ref_public.export_key(format="DER", compress=False)
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
def test_export_private_pkcs8_clear(self):
|
||||
key_file = load_file("ecc_x25519_private.der")
|
||||
|
||||
encoded = self.ref_private._export_pkcs8()
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = self.ref_private.export_key(format="DER")
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
self.assertRaises(ValueError, self.ref_private.export_key,
|
||||
format="DER", use_pkcs8=False)
|
||||
|
||||
def test_export_private_pkcs8_encrypted(self):
|
||||
encoded = self.ref_private._export_pkcs8(passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
|
||||
# This should prove that the output is password-protected
|
||||
self.assertRaises(ValueError, ECC._import_pkcs8, encoded, None)
|
||||
|
||||
decoded = ECC._import_pkcs8(encoded, "secret")
|
||||
self.assertEqual(self.ref_private, decoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = self.ref_private.export_key(format="DER",
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
decoded = ECC.import_key(encoded, "secret")
|
||||
self.assertEqual(self.ref_private, decoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = self.ref_private.export_key(format="DER",
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA256AndAES128-CBC",
|
||||
prot_params={'iteration_count': 123})
|
||||
decoded = ECC.import_key(encoded, "secret")
|
||||
self.assertEqual(self.ref_private, decoded)
|
||||
|
||||
def test_export_public_pem(self):
|
||||
key_file_ref = load_file("ecc_x25519_public.pem", "rt").strip()
|
||||
key_file = self.ref_public.export_key(format="PEM").strip()
|
||||
self.assertEqual(key_file_ref, key_file)
|
||||
|
||||
def test_export_private_pem_clear(self):
|
||||
key_file = load_file("ecc_x25519_private.pem", "rt").strip()
|
||||
encoded = self.ref_private.export_key(format="PEM").strip()
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
def test_export_private_pem_encrypted(self):
|
||||
encoded = self.ref_private.export_key(format="PEM",
|
||||
passphrase=b"secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
|
||||
# This should prove that the output is password-protected
|
||||
self.assertRaises(ValueError, ECC.import_key, encoded)
|
||||
|
||||
assert "ENCRYPTED PRIVATE KEY" in encoded
|
||||
|
||||
decoded = ECC.import_key(encoded, "secret")
|
||||
self.assertEqual(self.ref_private, decoded)
|
||||
|
||||
def test_export_raw(self):
|
||||
encoded = self.ref_public.export_key(format='raw')
|
||||
self.assertEqual(len(encoded), 32)
|
||||
self.assertEqual(encoded, unhexlify(b'ff7561ef60c9c8a757f6d6372ec14142c9be208d0e719136d8d3c715dfcf7e15'))
|
||||
|
||||
def test_prng(self):
|
||||
# Test that password-protected containers use the provided PRNG
|
||||
encoded1 = self.ref_private.export_key(format="PEM",
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC",
|
||||
randfunc=get_fixed_prng())
|
||||
encoded2 = self.ref_private.export_key(format="PEM",
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC",
|
||||
randfunc=get_fixed_prng())
|
||||
self.assertEqual(encoded1, encoded2)
|
||||
|
||||
def test_byte_or_string_passphrase(self):
|
||||
encoded1 = self.ref_private.export_key(format="PEM",
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC",
|
||||
randfunc=get_fixed_prng())
|
||||
encoded2 = self.ref_private.export_key(format="PEM",
|
||||
passphrase=b"secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC",
|
||||
randfunc=get_fixed_prng())
|
||||
self.assertEqual(encoded1, encoded2)
|
||||
|
||||
def test_error_params1(self):
|
||||
# Unknown format
|
||||
self.assertRaises(ValueError, self.ref_private.export_key, format="XXX")
|
||||
|
||||
# Missing 'protection' parameter when PKCS#8 is used
|
||||
self.assertRaises(ValueError,
|
||||
self.ref_private.export_key,
|
||||
format="PEM",
|
||||
passphrase="secret")
|
||||
|
||||
# Empty password
|
||||
self.assertRaises(ValueError,
|
||||
self.ref_private.export_key,
|
||||
format="PEM",
|
||||
passphrase="",
|
||||
use_pkcs8=False)
|
||||
self.assertRaises(ValueError,
|
||||
self.ref_private.export_key,
|
||||
format="PEM",
|
||||
passphrase="",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
|
||||
# No private keys with OpenSSH
|
||||
self.assertRaises(ValueError,
|
||||
self.ref_private.export_key,
|
||||
format="OpenSSH",
|
||||
passphrase="secret")
|
||||
|
||||
|
||||
class TestImport_Curve25519_Weak(unittest.TestCase):
|
||||
|
||||
def test_weak_pem(self):
|
||||
|
||||
p = 2**255 - 19
|
||||
weak_x = (0,
|
||||
1,
|
||||
325606250916557431795983626356110631294008115727848805560023387167927233504,
|
||||
39382357235489614581723060781553021112529911719440698176882885853963445705823,
|
||||
p - 1,
|
||||
p,
|
||||
p + 1,
|
||||
p + 325606250916557431795983626356110631294008115727848805560023387167927233504,
|
||||
p + 39382357235489614581723060781553021112529911719440698176882885853963445705823,
|
||||
p * 2 - 1,
|
||||
p * 2,
|
||||
p * 2 + 1)
|
||||
|
||||
for x in weak_x:
|
||||
low_order_point = ECC.EccXPoint(x, "curve25519")
|
||||
weak_key = ECC.EccKey(point=low_order_point, curve="curve25519")
|
||||
encoded = weak_key.export_key(format="PEM")
|
||||
|
||||
self.assertRaises(ValueError,
|
||||
ECC.import_key,
|
||||
encoded)
|
||||
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
try:
|
||||
tests += list_test_cases(TestImport)
|
||||
tests += list_test_cases(TestImport_Curve25519)
|
||||
tests += list_test_cases(TestExport_Curve25519)
|
||||
tests += list_test_cases(TestImport_Curve25519_Weak)
|
||||
except SkipTest:
|
||||
pass
|
||||
return tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
def suit():
|
||||
return unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
351
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_import_Curve448.py
vendored
Normal file
351
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_import_Curve448.py
vendored
Normal file
@ -0,0 +1,351 @@
|
||||
# This file is licensed under the BSD 2-Clause License.
|
||||
# See https://opensource.org/licenses/BSD-2-Clause for details.
|
||||
|
||||
import os
|
||||
import errno
|
||||
import warnings
|
||||
import unittest
|
||||
from binascii import unhexlify
|
||||
from unittest import SkipTest
|
||||
|
||||
from Crypto.SelfTest.st_common import list_test_cases
|
||||
from Crypto.Util.py3compat import tostr, FileNotFoundError
|
||||
from Crypto.Util.asn1 import DerSequence, DerBitString
|
||||
from Crypto.Hash import SHAKE128
|
||||
|
||||
from Crypto.PublicKey import ECC
|
||||
|
||||
try:
|
||||
import pycryptodome_test_vectors # type: ignore
|
||||
test_vectors_available = True
|
||||
except ImportError:
|
||||
test_vectors_available = False
|
||||
|
||||
|
||||
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(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 SkipTest("Missing %s" % file_name)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def compact(lines):
|
||||
ext = b"".join(lines)
|
||||
return unhexlify(tostr(ext).replace(" ", "").replace(":", ""))
|
||||
|
||||
|
||||
def create_ref_keys_x448():
|
||||
key_lines = load_file("ecc_x448.txt").splitlines()
|
||||
seed = compact(key_lines[6:10])
|
||||
key = ECC.construct(curve="Curve448", seed=seed)
|
||||
return (key, key.public_key())
|
||||
|
||||
|
||||
def get_fixed_prng():
|
||||
return SHAKE128.new().update(b"SEED").read
|
||||
|
||||
|
||||
def extract_bitstring_from_spki(data):
|
||||
seq = DerSequence()
|
||||
seq.decode(data)
|
||||
bs = DerBitString()
|
||||
bs.decode(seq[1])
|
||||
return bs.value
|
||||
|
||||
|
||||
class TestImport(unittest.TestCase):
|
||||
|
||||
def test_empty(self):
|
||||
self.assertRaises(ValueError, ECC.import_key, b"")
|
||||
|
||||
def test_mismatch(self):
|
||||
# Private key with X448 Object ID but X448 key
|
||||
mismatch_hex = "302e020100300506032b656f042204207009906b64ec727d5cb5c23007bf0425b3fd79014c6cd62ca3dddfcf0f278f79"
|
||||
mismatch = unhexlify(mismatch_hex)
|
||||
self.assertRaises(ValueError, ECC.import_key, mismatch)
|
||||
|
||||
|
||||
class TestImport_Curve448(unittest.TestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TestImport_Curve448, self).__init__(*args, **kwargs)
|
||||
self.ref_private, self.ref_public = create_ref_keys_x448()
|
||||
|
||||
def test_import_public_der(self):
|
||||
key_file = load_file("ecc_x448_public.der")
|
||||
|
||||
key = ECC._import_subjectPublicKeyInfo(key_file)
|
||||
self.assertEqual(self.ref_public, key)
|
||||
|
||||
key = ECC._import_der(key_file, None)
|
||||
self.assertEqual(self.ref_public, key)
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(self.ref_public, key)
|
||||
|
||||
def test_import_pkcs8_der(self):
|
||||
key_file = load_file("ecc_x448_private.der")
|
||||
|
||||
key = ECC._import_der(key_file, None)
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
def test_import_private_pkcs8_encrypted_1(self):
|
||||
key_file = load_file("ecc_x448_private_p8.der")
|
||||
|
||||
key = ECC._import_der(key_file, "secret")
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
key = ECC.import_key(key_file, "secret")
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
def test_import_private_pkcs8_encrypted_2(self):
|
||||
key_file = load_file("ecc_x448_private_p8.pem")
|
||||
|
||||
key = ECC.import_key(key_file, "secret")
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
def test_import_private_pkcs8_encrypted_3(self):
|
||||
key_file = load_file("ecc_x448_private_p8_2.der")
|
||||
|
||||
key = ECC._import_der(key_file, "secret")
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
key = ECC.import_key(key_file, "secret")
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
def test_import_x509_der(self):
|
||||
key_file = load_file("ecc_x448_x509.der")
|
||||
|
||||
key = ECC._import_der(key_file, None)
|
||||
self.assertEqual(self.ref_public, key)
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(self.ref_public, key)
|
||||
|
||||
def test_import_public_pem(self):
|
||||
key_file = load_file("ecc_x448_public.pem")
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(self.ref_public, key)
|
||||
|
||||
def test_import_private_pem(self):
|
||||
key_file = load_file("ecc_x448_private.pem")
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
def test_import_private_pem_encrypted(self):
|
||||
for algo in "des3", "aes128", "aes192", "aes256":
|
||||
key_file = load_file("ecc_x448_private_enc_%s.pem" % algo)
|
||||
|
||||
key = ECC.import_key(key_file, "secret")
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
key = ECC.import_key(tostr(key_file), b"secret")
|
||||
self.assertEqual(self.ref_private, key)
|
||||
|
||||
def test_import_x509_pem(self):
|
||||
key_file = load_file("ecc_x448_x509.pem")
|
||||
|
||||
key = ECC.import_key(key_file)
|
||||
self.assertEqual(self.ref_public, key)
|
||||
|
||||
|
||||
class TestExport_Curve448(unittest.TestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TestExport_Curve448, self).__init__(*args, **kwargs)
|
||||
self.ref_private, self.ref_public = create_ref_keys_x448()
|
||||
|
||||
def test_export_public_der(self):
|
||||
key_file = load_file("ecc_x448_public.der")
|
||||
|
||||
encoded = self.ref_public._export_subjectPublicKeyInfo(True)
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
encoded = self.ref_public.export_key(format="DER")
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
encoded = self.ref_public.export_key(format="DER", compress=False)
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
def test_export_private_pkcs8_clear(self):
|
||||
key_file = load_file("ecc_x448_private.der")
|
||||
|
||||
encoded = self.ref_private._export_pkcs8()
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = self.ref_private.export_key(format="DER")
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
self.assertRaises(ValueError, self.ref_private.export_key,
|
||||
format="DER", use_pkcs8=False)
|
||||
|
||||
def test_export_private_pkcs8_encrypted(self):
|
||||
encoded = self.ref_private._export_pkcs8(passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
|
||||
# This should prove that the output is password-protected
|
||||
self.assertRaises(ValueError, ECC._import_pkcs8, encoded, None)
|
||||
|
||||
decoded = ECC._import_pkcs8(encoded, "secret")
|
||||
self.assertEqual(self.ref_private, decoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = self.ref_private.export_key(format="DER",
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
decoded = ECC.import_key(encoded, "secret")
|
||||
self.assertEqual(self.ref_private, decoded)
|
||||
|
||||
# ---
|
||||
|
||||
encoded = self.ref_private.export_key(format="DER",
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA256AndAES128-CBC",
|
||||
prot_params={'iteration_count': 123})
|
||||
decoded = ECC.import_key(encoded, "secret")
|
||||
self.assertEqual(self.ref_private, decoded)
|
||||
|
||||
def test_export_public_pem(self):
|
||||
key_file_ref = load_file("ecc_x448_public.pem", "rt").strip()
|
||||
key_file = self.ref_public.export_key(format="PEM").strip()
|
||||
self.assertEqual(key_file_ref, key_file)
|
||||
|
||||
def test_export_private_pem_clear(self):
|
||||
key_file = load_file("ecc_x448_private.pem", "rt").strip()
|
||||
encoded = self.ref_private.export_key(format="PEM").strip()
|
||||
self.assertEqual(key_file, encoded)
|
||||
|
||||
def test_export_private_pem_encrypted(self):
|
||||
encoded = self.ref_private.export_key(format="PEM",
|
||||
passphrase=b"secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
|
||||
# This should prove that the output is password-protected
|
||||
self.assertRaises(ValueError, ECC.import_key, encoded)
|
||||
|
||||
assert "ENCRYPTED PRIVATE KEY" in encoded
|
||||
|
||||
decoded = ECC.import_key(encoded, "secret")
|
||||
self.assertEqual(self.ref_private, decoded)
|
||||
|
||||
def test_export_raw(self):
|
||||
encoded = self.ref_public.export_key(format='raw')
|
||||
self.assertEqual(len(encoded), 56)
|
||||
self.assertEqual(encoded, unhexlify(b'e2abae24ab8f65b01969e61f84fee615b525f413a90e3d727f71d0ffe60fb1d0a1a0285f2a7fd88789206e0aa4f3e9fcb9e4ba5d644e691e'))
|
||||
|
||||
def test_prng(self):
|
||||
# Test that password-protected containers use the provided PRNG
|
||||
encoded1 = self.ref_private.export_key(format="PEM",
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC",
|
||||
randfunc=get_fixed_prng())
|
||||
encoded2 = self.ref_private.export_key(format="PEM",
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC",
|
||||
randfunc=get_fixed_prng())
|
||||
self.assertEqual(encoded1, encoded2)
|
||||
|
||||
def test_byte_or_string_passphrase(self):
|
||||
encoded1 = self.ref_private.export_key(format="PEM",
|
||||
passphrase="secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC",
|
||||
randfunc=get_fixed_prng())
|
||||
encoded2 = self.ref_private.export_key(format="PEM",
|
||||
passphrase=b"secret",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC",
|
||||
randfunc=get_fixed_prng())
|
||||
self.assertEqual(encoded1, encoded2)
|
||||
|
||||
def test_error_params1(self):
|
||||
# Unknown format
|
||||
self.assertRaises(ValueError, self.ref_private.export_key, format="XXX")
|
||||
|
||||
# Missing 'protection' parameter when PKCS#8 is used
|
||||
self.assertRaises(ValueError,
|
||||
self.ref_private.export_key,
|
||||
format="PEM",
|
||||
passphrase="secret")
|
||||
|
||||
# Empty password
|
||||
self.assertRaises(ValueError,
|
||||
self.ref_private.export_key,
|
||||
format="PEM",
|
||||
passphrase="",
|
||||
use_pkcs8=False)
|
||||
self.assertRaises(ValueError,
|
||||
self.ref_private.export_key,
|
||||
format="PEM",
|
||||
passphrase="",
|
||||
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
|
||||
|
||||
# No private keys with OpenSSH
|
||||
self.assertRaises(ValueError,
|
||||
self.ref_private.export_key,
|
||||
format="OpenSSH",
|
||||
passphrase="secret")
|
||||
|
||||
|
||||
class TestImport_Curve448_Weak(unittest.TestCase):
|
||||
|
||||
def test_weak_pem(self):
|
||||
|
||||
p = 2**448 - 2**224 - 1
|
||||
weak_x = (0,
|
||||
1,
|
||||
p - 1,
|
||||
p,
|
||||
p + 1)
|
||||
|
||||
for x in weak_x:
|
||||
low_order_point = ECC.EccXPoint(x, "curve448")
|
||||
weak_key = ECC.EccKey(point=low_order_point, curve="curve448")
|
||||
encoded = weak_key.export_key(format="PEM")
|
||||
|
||||
self.assertRaises(ValueError,
|
||||
ECC.import_key,
|
||||
encoded)
|
||||
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
try:
|
||||
tests += list_test_cases(TestImport)
|
||||
tests += list_test_cases(TestImport_Curve448)
|
||||
tests += list_test_cases(TestExport_Curve448)
|
||||
tests += list_test_cases(TestImport_Curve448_Weak)
|
||||
except SkipTest:
|
||||
pass
|
||||
return tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
def suit():
|
||||
return unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
554
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_import_DSA.py
vendored
Normal file
554
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_import_DSA.py
vendored
Normal file
@ -0,0 +1,554 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_import_DSA.py: Self-test for importing DSA keys
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
import unittest
|
||||
import re
|
||||
|
||||
from Crypto.PublicKey import DSA
|
||||
from Crypto.SelfTest.st_common import *
|
||||
from Crypto.Util.py3compat import *
|
||||
|
||||
from binascii import unhexlify
|
||||
|
||||
class ImportKeyTests(unittest.TestCase):
|
||||
|
||||
y = 92137165128186062214622779787483327510946462589285775188003362705875131352591574106484271700740858696583623951844732128165434284507709057439633739849986759064015013893156866539696757799934634945787496920169462601722830899660681779448742875054459716726855443681559131362852474817534616736104831095601710736729
|
||||
p = 162452170958135306109773853318304545923250830605675936228618290525164105310663722368377131295055868997377338797580997938253236213714988311430600065853662861806894003694743806769284131194035848116051021923956699231855223389086646903420682639786976554552864568460372266462812137447840653688476258666833303658691
|
||||
q = 988791743931120302950649732173330531512663554851
|
||||
g = 85583152299197514738065570254868711517748965097380456700369348466136657764813442044039878840094809620913085570225318356734366886985903212775602770761953571967834823306046501307810937486758039063386311593890777319935391363872375452381836756832784184928202587843258855704771836753434368484556809100537243908232
|
||||
x = 540873410045082450874416847965843801027716145253
|
||||
|
||||
def setUp(self):
|
||||
|
||||
# It is easier to write test vectors in text form,
|
||||
# and convert them to byte strigs dynamically here
|
||||
for mname, mvalue in ImportKeyTests.__dict__.items():
|
||||
if mname[:4] in ('der_', 'pem_', 'ssh_'):
|
||||
if mname[:4] == 'der_':
|
||||
mvalue = unhexlify(tobytes(mvalue))
|
||||
mvalue = tobytes(mvalue)
|
||||
setattr(self, mname, mvalue)
|
||||
|
||||
# 1. SubjectPublicKeyInfo
|
||||
der_public=\
|
||||
'308201b73082012b06072a8648ce3804013082011e02818100e756ee1717f4b6'+\
|
||||
'794c7c214724a19763742c45572b4b3f8ff3b44f3be9f44ce039a2757695ec91'+\
|
||||
'5697da74ef914fcd1b05660e2419c761d639f45d2d79b802dbd23e7ab8b81b47'+\
|
||||
'9a380e1f30932584ba2a0b955032342ebc83cb5ca906e7b0d7cd6fe656cecb4c'+\
|
||||
'8b5a77123a8c6750a481e3b06057aff6aa6eba620b832d60c3021500ad32f48c'+\
|
||||
'd3ae0c45a198a61fa4b5e20320763b2302818079dfdc3d614fe635fceb7eaeae'+\
|
||||
'3718dc2efefb45282993ac6749dc83c223d8c1887296316b3b0b54466cf444f3'+\
|
||||
'4b82e3554d0b90a778faaf1306f025dae6a3e36c7f93dd5bac4052b92370040a'+\
|
||||
'ca70b8d5820599711900efbc961812c355dd9beffe0981da85c5548074b41c56'+\
|
||||
'ae43fd300d89262e4efd89943f99a651b03888038185000281810083352a69a1'+\
|
||||
'32f34843d2a0eb995bff4e2f083a73f0049d2c91ea2f0ce43d144abda48199e4'+\
|
||||
'b003c570a8af83303d45105f606c5c48d925a40ed9c2630c2fa4cdbf838539de'+\
|
||||
'b9a29f919085f2046369f627ca84b2cb1e2c7940564b670f963ab1164d4e2ca2'+\
|
||||
'bf6ffd39f12f548928bf4d2d1b5e6980b4f1be4c92a91986fba559'
|
||||
|
||||
def testImportKey1(self):
|
||||
key_obj = DSA.importKey(self.der_public)
|
||||
self.assertFalse(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
|
||||
def testExportKey1(self):
|
||||
tup = (self.y, self.g, self.p, self.q)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.export_key('DER')
|
||||
self.assertEqual(self.der_public, encoded)
|
||||
|
||||
# 2.
|
||||
pem_public="""\
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBtzCCASsGByqGSM44BAEwggEeAoGBAOdW7hcX9LZ5THwhRyShl2N0LEVXK0s/
|
||||
j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4uBtH
|
||||
mjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47BgV6/2
|
||||
qm66YguDLWDDAhUArTL0jNOuDEWhmKYfpLXiAyB2OyMCgYB539w9YU/mNfzrfq6u
|
||||
NxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG8CXa
|
||||
5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0tBxW
|
||||
rkP9MA2JJi5O/YmUP5mmUbA4iAOBhQACgYEAgzUqaaEy80hD0qDrmVv/Ti8IOnPw
|
||||
BJ0skeovDOQ9FEq9pIGZ5LADxXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTne
|
||||
uaKfkZCF8gRjafYnyoSyyx4seUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmA
|
||||
tPG+TJKpGYb7pVk=
|
||||
-----END PUBLIC KEY-----"""
|
||||
|
||||
def testImportKey2(self):
|
||||
for pem in (self.pem_public, tostr(self.pem_public)):
|
||||
key_obj = DSA.importKey(pem)
|
||||
self.assertFalse(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
|
||||
def testExportKey2(self):
|
||||
tup = (self.y, self.g, self.p, self.q)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.export_key('PEM')
|
||||
self.assertEqual(self.pem_public, encoded)
|
||||
|
||||
# 3. OpenSSL/OpenSSH format
|
||||
der_private=\
|
||||
'308201bb02010002818100e756ee1717f4b6794c7c214724a19763742c45572b'+\
|
||||
'4b3f8ff3b44f3be9f44ce039a2757695ec915697da74ef914fcd1b05660e2419'+\
|
||||
'c761d639f45d2d79b802dbd23e7ab8b81b479a380e1f30932584ba2a0b955032'+\
|
||||
'342ebc83cb5ca906e7b0d7cd6fe656cecb4c8b5a77123a8c6750a481e3b06057'+\
|
||||
'aff6aa6eba620b832d60c3021500ad32f48cd3ae0c45a198a61fa4b5e2032076'+\
|
||||
'3b2302818079dfdc3d614fe635fceb7eaeae3718dc2efefb45282993ac6749dc'+\
|
||||
'83c223d8c1887296316b3b0b54466cf444f34b82e3554d0b90a778faaf1306f0'+\
|
||||
'25dae6a3e36c7f93dd5bac4052b92370040aca70b8d5820599711900efbc9618'+\
|
||||
'12c355dd9beffe0981da85c5548074b41c56ae43fd300d89262e4efd89943f99'+\
|
||||
'a651b038880281810083352a69a132f34843d2a0eb995bff4e2f083a73f0049d'+\
|
||||
'2c91ea2f0ce43d144abda48199e4b003c570a8af83303d45105f606c5c48d925'+\
|
||||
'a40ed9c2630c2fa4cdbf838539deb9a29f919085f2046369f627ca84b2cb1e2c'+\
|
||||
'7940564b670f963ab1164d4e2ca2bf6ffd39f12f548928bf4d2d1b5e6980b4f1'+\
|
||||
'be4c92a91986fba55902145ebd9a3f0b82069d98420986b314215025756065'
|
||||
|
||||
def testImportKey3(self):
|
||||
key_obj = DSA.importKey(self.der_private)
|
||||
self.assertTrue(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
self.assertEqual(self.x, key_obj.x)
|
||||
|
||||
def testExportKey3(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.export_key('DER', pkcs8=False)
|
||||
self.assertEqual(self.der_private, encoded)
|
||||
|
||||
# 4.
|
||||
pem_private="""\
|
||||
-----BEGIN DSA PRIVATE KEY-----
|
||||
MIIBuwIBAAKBgQDnVu4XF/S2eUx8IUckoZdjdCxFVytLP4/ztE876fRM4DmidXaV
|
||||
7JFWl9p075FPzRsFZg4kGcdh1jn0XS15uALb0j56uLgbR5o4Dh8wkyWEuioLlVAy
|
||||
NC68g8tcqQbnsNfNb+ZWzstMi1p3EjqMZ1CkgeOwYFev9qpuumILgy1gwwIVAK0y
|
||||
9IzTrgxFoZimH6S14gMgdjsjAoGAed/cPWFP5jX8636urjcY3C7++0UoKZOsZ0nc
|
||||
g8Ij2MGIcpYxazsLVEZs9ETzS4LjVU0LkKd4+q8TBvAl2uaj42x/k91brEBSuSNw
|
||||
BArKcLjVggWZcRkA77yWGBLDVd2b7/4JgdqFxVSAdLQcVq5D/TANiSYuTv2JlD+Z
|
||||
plGwOIgCgYEAgzUqaaEy80hD0qDrmVv/Ti8IOnPwBJ0skeovDOQ9FEq9pIGZ5LAD
|
||||
xXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTneuaKfkZCF8gRjafYnyoSyyx4s
|
||||
eUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmAtPG+TJKpGYb7pVkCFF69mj8L
|
||||
ggadmEIJhrMUIVAldWBl
|
||||
-----END DSA PRIVATE KEY-----"""
|
||||
|
||||
def testImportKey4(self):
|
||||
for pem in (self.pem_private, tostr(self.pem_private)):
|
||||
key_obj = DSA.importKey(pem)
|
||||
self.assertTrue(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
self.assertEqual(self.x, key_obj.x)
|
||||
|
||||
def testExportKey4(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.export_key('PEM', pkcs8=False)
|
||||
self.assertEqual(self.pem_private, encoded)
|
||||
|
||||
# 5. PKCS8 (unencrypted)
|
||||
der_pkcs8=\
|
||||
'3082014a0201003082012b06072a8648ce3804013082011e02818100e756ee17'+\
|
||||
'17f4b6794c7c214724a19763742c45572b4b3f8ff3b44f3be9f44ce039a27576'+\
|
||||
'95ec915697da74ef914fcd1b05660e2419c761d639f45d2d79b802dbd23e7ab8'+\
|
||||
'b81b479a380e1f30932584ba2a0b955032342ebc83cb5ca906e7b0d7cd6fe656'+\
|
||||
'cecb4c8b5a77123a8c6750a481e3b06057aff6aa6eba620b832d60c3021500ad'+\
|
||||
'32f48cd3ae0c45a198a61fa4b5e20320763b2302818079dfdc3d614fe635fceb'+\
|
||||
'7eaeae3718dc2efefb45282993ac6749dc83c223d8c1887296316b3b0b54466c'+\
|
||||
'f444f34b82e3554d0b90a778faaf1306f025dae6a3e36c7f93dd5bac4052b923'+\
|
||||
'70040aca70b8d5820599711900efbc961812c355dd9beffe0981da85c5548074'+\
|
||||
'b41c56ae43fd300d89262e4efd89943f99a651b03888041602145ebd9a3f0b82'+\
|
||||
'069d98420986b314215025756065'
|
||||
|
||||
def testImportKey5(self):
|
||||
key_obj = DSA.importKey(self.der_pkcs8)
|
||||
self.assertTrue(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
self.assertEqual(self.x, key_obj.x)
|
||||
|
||||
def testExportKey5(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.export_key('DER')
|
||||
self.assertEqual(self.der_pkcs8, encoded)
|
||||
encoded = key.export_key('DER', pkcs8=True)
|
||||
self.assertEqual(self.der_pkcs8, encoded)
|
||||
|
||||
# 6.
|
||||
pem_pkcs8="""\
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBAOdW7hcX9LZ5THwhRyShl2N0LEVX
|
||||
K0s/j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4
|
||||
uBtHmjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47Bg
|
||||
V6/2qm66YguDLWDDAhUArTL0jNOuDEWhmKYfpLXiAyB2OyMCgYB539w9YU/mNfzr
|
||||
fq6uNxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG
|
||||
8CXa5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0
|
||||
tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAQWAhRevZo/C4IGnZhCCYazFCFQJXVgZQ==
|
||||
-----END PRIVATE KEY-----"""
|
||||
|
||||
def testImportKey6(self):
|
||||
for pem in (self.pem_pkcs8, tostr(self.pem_pkcs8)):
|
||||
key_obj = DSA.importKey(pem)
|
||||
self.assertTrue(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
self.assertEqual(self.x, key_obj.x)
|
||||
|
||||
def testExportKey6(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.export_key('PEM')
|
||||
self.assertEqual(self.pem_pkcs8, encoded)
|
||||
encoded = key.export_key('PEM', pkcs8=True)
|
||||
self.assertEqual(self.pem_pkcs8, encoded)
|
||||
|
||||
# 7. OpenSSH/RFC4253
|
||||
ssh_pub="""ssh-dss AAAAB3NzaC1kc3MAAACBAOdW7hcX9LZ5THwhRyShl2N0LEVXK0s/j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4uBtHmjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47BgV6/2qm66YguDLWDDAAAAFQCtMvSM064MRaGYph+kteIDIHY7IwAAAIB539w9YU/mNfzrfq6uNxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG8CXa5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAAAAIEAgzUqaaEy80hD0qDrmVv/Ti8IOnPwBJ0skeovDOQ9FEq9pIGZ5LADxXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTneuaKfkZCF8gRjafYnyoSyyx4seUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmAtPG+TJKpGYb7pVk="""
|
||||
|
||||
def testImportKey7(self):
|
||||
for ssh in (self.ssh_pub, tostr(self.ssh_pub)):
|
||||
key_obj = DSA.importKey(ssh)
|
||||
self.assertFalse(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
|
||||
def testExportKey7(self):
|
||||
tup = (self.y, self.g, self.p, self.q)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.export_key('OpenSSH')
|
||||
self.assertEqual(self.ssh_pub, encoded)
|
||||
|
||||
# 8. Encrypted OpenSSL/OpenSSH
|
||||
pem_private_encrypted="""\
|
||||
-----BEGIN DSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-128-CBC,70B6908939D65E9F2EB999E8729788CE
|
||||
|
||||
4V6GHRDpCrdZ8MBjbyp5AlGUrjvr2Pn2e2zVxy5RBt4FBj9/pa0ae0nnyUPMLSUU
|
||||
kKyOR0topRYTVRLElm4qVrb5uNZ3hRwfbklr+pSrB7O9eHz9V5sfOQxyODS07JxK
|
||||
k1OdOs70/ouMXLF9EWfAZOmWUccZKHNblUwg1p1UrZIz5jXw4dUE/zqhvXh6d+iC
|
||||
ADsICaBCjCrRQJKDp50h3+ndQjkYBKVH+pj8TiQ79U7lAvdp3+iMghQN6YXs9mdI
|
||||
gFpWw/f97oWM4GHZFqHJ+VSMNFjBiFhAvYV587d7Lk4dhD8sCfbxj42PnfRgUItc
|
||||
nnPqHxmhMQozBWzYM4mQuo3XbF2WlsNFbOzFVyGhw1Bx1s91qvXBVWJh2ozrW0s6
|
||||
HYDV7ZkcTml/4kjA/d+mve6LZ8kuuR1qCiZx6rkffhh1gDN/1Xz3HVvIy/dQ+h9s
|
||||
5zp7PwUoWbhqp3WCOr156P6gR8qo7OlT6wMh33FSXK/mxikHK136fV2shwTKQVII
|
||||
rJBvXpj8nACUmi7scKuTWGeUoXa+dwTZVVe+b+L2U1ZM7+h/neTJiXn7u99PFUwu
|
||||
xVJtxaV37m3aXxtCsPnbBg==
|
||||
-----END DSA PRIVATE KEY-----"""
|
||||
|
||||
def testImportKey8(self):
|
||||
for pem in (self.pem_private_encrypted, tostr(self.pem_private_encrypted)):
|
||||
key_obj = DSA.importKey(pem, "PWDTEST")
|
||||
self.assertTrue(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
self.assertEqual(self.x, key_obj.x)
|
||||
|
||||
def testExportKey8(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = DSA.construct(tup)
|
||||
encoded = key.export_key('PEM', pkcs8=False, passphrase="PWDTEST")
|
||||
key = DSA.importKey(encoded, "PWDTEST")
|
||||
self.assertEqual(self.y, key.y)
|
||||
self.assertEqual(self.p, key.p)
|
||||
self.assertEqual(self.q, key.q)
|
||||
self.assertEqual(self.g, key.g)
|
||||
self.assertEqual(self.x, key.x)
|
||||
|
||||
# 9. Encrypted PKCS8
|
||||
# pbeWithMD5AndDES-CBC
|
||||
pem_pkcs8_encrypted="""\
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBcTAbBgkqhkiG9w0BBQMwDgQI0GC3BJ/jSw8CAggABIIBUHc1cXZpExIE9tC7
|
||||
7ryiW+5ihtF2Ekurq3e408GYSAu5smJjN2bvQXmzRFBz8W38K8eMf1sbWroZ4+zn
|
||||
kZSbb9nSm5kAa8lR2+oF2k+WRswMR/PTC3f/D9STO2X0QxdrzKgIHEcSGSHp5jTx
|
||||
aVvbkCDHo9vhBTl6S3ogZ48As/MEro76+9igUwJ1jNhIQZPJ7e20QH5qDpQFFJN4
|
||||
CKl2ENSEuwGiqBszItFy4dqH0g63ZGZV/xt9wSO9Rd7SK/EbA/dklOxBa5Y/VItM
|
||||
gnIhs9XDMoGYyn6F023EicNJm6g/bVQk81BTTma4tm+12TKGdYm+QkeZvCOMZylr
|
||||
Wv67cKwO3cAXt5C3QXMDgYR64XvuaT5h7C0igMp2afSXJlnbHEbFxQVJlv83T4FM
|
||||
eZ4k+NQDbEL8GiHmFxzDWQAuPPZKJWEEEV2p/To+WOh+kSDHQw==
|
||||
-----END ENCRYPTED PRIVATE KEY-----"""
|
||||
|
||||
def testImportKey9(self):
|
||||
for pem in (self.pem_pkcs8_encrypted, tostr(self.pem_pkcs8_encrypted)):
|
||||
key_obj = DSA.importKey(pem, "PWDTEST")
|
||||
self.assertTrue(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
self.assertEqual(self.x, key_obj.x)
|
||||
|
||||
# 10. Encrypted PKCS8
|
||||
# pkcs5PBES2 /
|
||||
# pkcs5PBKDF2 (rounds=1000, salt=D725BF1B6B8239F4) /
|
||||
# des-EDE3-CBC (iv=27A1C66C42AFEECE)
|
||||
#
|
||||
der_pkcs8_encrypted=\
|
||||
'30820196304006092a864886f70d01050d3033301b06092a864886f70d01050c'+\
|
||||
'300e0408d725bf1b6b8239f4020203e8301406082a864886f70d0307040827a1'+\
|
||||
'c66c42afeece048201505cacfde7bf8edabb3e0d387950dc872662ea7e9b1ed4'+\
|
||||
'400d2e7e6186284b64668d8d0328c33a9d9397e6f03df7cb68268b0a06b4e22f'+\
|
||||
'7d132821449ecf998a8b696dbc6dd2b19e66d7eb2edfeb4153c1771d49702395'+\
|
||||
'4f36072868b5fcccf93413a5ac4b2eb47d4b3f681c6bd67ae363ed776f45ae47'+\
|
||||
'174a00098a7c930a50f820b227ddf50f9742d8e950d02586ff2dac0e3c372248'+\
|
||||
'e5f9b6a7a02f4004f20c87913e0f7b52bccc209b95d478256a890b31d4c9adec'+\
|
||||
'21a4d157a179a93a3dad06f94f3ce486b46dfa7fc15fd852dd7680bbb2f17478'+\
|
||||
'7e71bd8dbaf81eca7518d76c1d26256e95424864ba45ca5d47d7c5a421be02fa'+\
|
||||
'b94ab01e18593f66cf9094eb5c94b9ecf3aa08b854a195cf87612fbe5e96c426'+\
|
||||
'2b0d573e52dc71ba3f5e468c601e816c49b7d32c698b22175e89aaef0c443770'+\
|
||||
'5ef2f88a116d99d8e2869a4fd09a771b84b49e4ccb79aadcb1c9'
|
||||
|
||||
def testImportKey10(self):
|
||||
key_obj = DSA.importKey(self.der_pkcs8_encrypted, "PWDTEST")
|
||||
self.assertTrue(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
self.assertEqual(self.x, key_obj.x)
|
||||
|
||||
def testExportKey10(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = DSA.construct(tup)
|
||||
randfunc = BytesIO(unhexlify(b("27A1C66C42AFEECE") + b("D725BF1B6B8239F4"))).read
|
||||
encoded = key.export_key('DER', pkcs8=True, passphrase="PWDTEST", randfunc=randfunc)
|
||||
self.assertEqual(self.der_pkcs8_encrypted, encoded)
|
||||
|
||||
# ----
|
||||
|
||||
def testImportError1(self):
|
||||
self.assertRaises(ValueError, DSA.importKey, self.der_pkcs8_encrypted, "wrongpwd")
|
||||
|
||||
def testExportError2(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = DSA.construct(tup)
|
||||
self.assertRaises(ValueError, key.export_key, 'DER', pkcs8=False, passphrase="PWDTEST")
|
||||
|
||||
def test_import_key(self):
|
||||
"""Verify importKey is an alias to import_key"""
|
||||
|
||||
key_obj = DSA.import_key(self.der_public)
|
||||
self.assertFalse(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.y)
|
||||
self.assertEqual(self.p, key_obj.p)
|
||||
self.assertEqual(self.q, key_obj.q)
|
||||
self.assertEqual(self.g, key_obj.g)
|
||||
|
||||
def test_exportKey(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = DSA.construct(tup)
|
||||
self.assertEqual(key.exportKey(), key.export_key())
|
||||
|
||||
|
||||
def test_import_empty(self):
|
||||
self.assertRaises(ValueError, DSA.import_key, b'')
|
||||
|
||||
|
||||
class ImportKeyFromX509Cert(unittest.TestCase):
|
||||
|
||||
def test_x509v1(self):
|
||||
|
||||
# Sample V1 certificate with a 1024 bit DSA key
|
||||
x509_v1_cert = """
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDUjCCArsCAQIwDQYJKoZIhvcNAQEFBQAwfjENMAsGA1UEChMEQWNtZTELMAkG
|
||||
A1UECxMCUkQxHDAaBgkqhkiG9w0BCQEWDXNwYW1AYWNtZS5vcmcxEzARBgNVBAcT
|
||||
Ck1ldHJvcG9saXMxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYDVQQGEwJVUzENMAsG
|
||||
A1UEAxMEdGVzdDAeFw0xNDA3MTEyMDM4NDNaFw0xNzA0MDYyMDM4NDNaME0xCzAJ
|
||||
BgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazENMAsGA1UEChMEQWNtZTELMAkG
|
||||
A1UECxMCUkQxDzANBgNVBAMTBnBvbGFuZDCCAbYwggErBgcqhkjOOAQBMIIBHgKB
|
||||
gQDOrN4Ox4+t3T6wKeHfhzArhcrNEFMQ4Ss+4PIKyimDy9Bn64WPkL1B/9dvYIga
|
||||
23GLu6tVJmXo6EdJnVOHEMhr99EeOwuDWWeP7Awq7RSlKEejokr4BEzMTW/tExSD
|
||||
cO6/GI7xzh0eTH+VTTPDfyrJMYCkh0rJAfCP+5xrmPNetwIVALtXYOV1yoRrzJ2Q
|
||||
M5uEjidH6GiZAoGAfUqA1SAm5g5U68SILMVX9l5rq0OpB0waBMpJQ31/R/yXNDqo
|
||||
c3gGWZTOJFU4IzwNpGhrGNADUByz/lc1SAOAdEJIr0JVrhbGewQjB4pWqoLGbBKz
|
||||
RoavTNDc/zD7SYa12evWDHADwvlXoeQg+lWop1zS8OqaDC7aLGKpWN3/m8kDgYQA
|
||||
AoGAKoirPAfcp1rbbl4y2FFAIktfW8f4+T7d2iKSg73aiVfujhNOt1Zz1lfC0NI2
|
||||
eonLWO3tAM4XGKf1TLjb5UXngGn40okPsaA81YE6ZIKm20ywjlOY3QkAEdMaLVY3
|
||||
9PJvM8RGB9m7pLKxyHfGMfF40MVN4222zKeGp7xhM0CNiCUwDQYJKoZIhvcNAQEF
|
||||
BQADgYEAfbNZfpYa2KlALEM1FZnwvQDvJHntHz8LdeJ4WM7CXDlKi67wY2HKM30w
|
||||
s2xej75imkVOFd1kF2d0A8sjfriXLVIt1Hwq9ANZomhu4Edx0xpH8tqdh/bDtnM2
|
||||
TmduZNY9OWkb07h0CtWD6Zt8fhRllVsSSrlWd/2or7FXNC5weFQ=
|
||||
-----END CERTIFICATE-----
|
||||
""".strip()
|
||||
|
||||
# DSA public key as dumped by openssl
|
||||
y_str = """
|
||||
2a:88:ab:3c:07:dc:a7:5a:db:6e:5e:32:d8:51:40:
|
||||
22:4b:5f:5b:c7:f8:f9:3e:dd:da:22:92:83:bd:da:
|
||||
89:57:ee:8e:13:4e:b7:56:73:d6:57:c2:d0:d2:36:
|
||||
7a:89:cb:58:ed:ed:00:ce:17:18:a7:f5:4c:b8:db:
|
||||
e5:45:e7:80:69:f8:d2:89:0f:b1:a0:3c:d5:81:3a:
|
||||
64:82:a6:db:4c:b0:8e:53:98:dd:09:00:11:d3:1a:
|
||||
2d:56:37:f4:f2:6f:33:c4:46:07:d9:bb:a4:b2:b1:
|
||||
c8:77:c6:31:f1:78:d0:c5:4d:e3:6d:b6:cc:a7:86:
|
||||
a7:bc:61:33:40:8d:88:25
|
||||
"""
|
||||
p_str = """
|
||||
00:ce:ac:de:0e:c7:8f:ad:dd:3e:b0:29:e1:df:87:
|
||||
30:2b:85:ca:cd:10:53:10:e1:2b:3e:e0:f2:0a:ca:
|
||||
29:83:cb:d0:67:eb:85:8f:90:bd:41:ff:d7:6f:60:
|
||||
88:1a:db:71:8b:bb:ab:55:26:65:e8:e8:47:49:9d:
|
||||
53:87:10:c8:6b:f7:d1:1e:3b:0b:83:59:67:8f:ec:
|
||||
0c:2a:ed:14:a5:28:47:a3:a2:4a:f8:04:4c:cc:4d:
|
||||
6f:ed:13:14:83:70:ee:bf:18:8e:f1:ce:1d:1e:4c:
|
||||
7f:95:4d:33:c3:7f:2a:c9:31:80:a4:87:4a:c9:01:
|
||||
f0:8f:fb:9c:6b:98:f3:5e:b7
|
||||
"""
|
||||
q_str = """
|
||||
00:bb:57:60:e5:75:ca:84:6b:cc:9d:90:33:9b:84:
|
||||
8e:27:47:e8:68:99
|
||||
"""
|
||||
g_str = """
|
||||
7d:4a:80:d5:20:26:e6:0e:54:eb:c4:88:2c:c5:57:
|
||||
f6:5e:6b:ab:43:a9:07:4c:1a:04:ca:49:43:7d:7f:
|
||||
47:fc:97:34:3a:a8:73:78:06:59:94:ce:24:55:38:
|
||||
23:3c:0d:a4:68:6b:18:d0:03:50:1c:b3:fe:57:35:
|
||||
48:03:80:74:42:48:af:42:55:ae:16:c6:7b:04:23:
|
||||
07:8a:56:aa:82:c6:6c:12:b3:46:86:af:4c:d0:dc:
|
||||
ff:30:fb:49:86:b5:d9:eb:d6:0c:70:03:c2:f9:57:
|
||||
a1:e4:20:fa:55:a8:a7:5c:d2:f0:ea:9a:0c:2e:da:
|
||||
2c:62:a9:58:dd:ff:9b:c9
|
||||
"""
|
||||
|
||||
key = DSA.importKey(x509_v1_cert)
|
||||
for comp_name in ('y', 'p', 'q', 'g'):
|
||||
comp_str = locals()[comp_name + "_str"]
|
||||
comp = int(re.sub("[^0-9a-f]", "", comp_str), 16)
|
||||
self.assertEqual(getattr(key, comp_name), comp)
|
||||
self.assertFalse(key.has_private())
|
||||
|
||||
def test_x509v3(self):
|
||||
|
||||
# Sample V3 certificate with a 1024 bit DSA key
|
||||
x509_v3_cert = """
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFhjCCA26gAwIBAgIBAzANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJVUzEL
|
||||
MAkGA1UECAwCTUQxEjAQBgNVBAcMCUJhbHRpbW9yZTEQMA4GA1UEAwwHVGVzdCBD
|
||||
QTEfMB0GCSqGSIb3DQEJARYQdGVzdEBleGFtcGxlLmNvbTAeFw0xNDA3MTMyMDUz
|
||||
MjBaFw0xNzA0MDgyMDUzMjBaMEAxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNRDES
|
||||
MBAGA1UEBwwJQmFsdGltb3JlMRAwDgYDVQQDDAdhdXN0cmlhMIIBtjCCASsGByqG
|
||||
SM44BAEwggEeAoGBALfd8gyEpVPA0ZI69Kp3nyJcu5N0ZZ3K1K9hleQLNqKEcZOh
|
||||
7a/C2J1TPdmHTLJ0rAwBZ1nWxnARSgRphziGDFspKCYQwYcSMz8KoFgvXbXpuchy
|
||||
oFACiQ2LqZnc5MakuLQtLcQciSYGYj3zmZdYMoa904F1aDWr+DxQI6DVC3/bAhUA
|
||||
hqXMCJ6fQK3G2O9S3/CC/yVZXCsCgYBRXROl3R2khX7l10LQjDEgo3B1IzjXU/jP
|
||||
McMBl6XO+nBJXxr/scbq8Ajiv7LTnGpSjgryHtvfj887kfvo8QbSS3kp3vq5uSqI
|
||||
ui7E7r3jguWaLj616AG1HWOctXJUjqsiabZwsp2h09gHTzmHEXBOmiARu8xFxKAH
|
||||
xsuo7onAbwOBhAACgYBylWjWSnKHE8mHx1A5m/0GQx6xnhWIe3+MJAnEhRGxA2J4
|
||||
SCsfWU0OwglIQToh1z5uUU9oDi9cYgNPBevOFRnDhc2yaJY6VAYnI+D+6J5IU6Yd
|
||||
0iaG/iSc4sV4bFr0axcPpse3SN0XaQxiKeSFBfFnoMqL+dd9Gb3QPZSllBcVD6OB
|
||||
1TCB0jAdBgNVHQ4EFgQUx5wN0Puotv388M9Tp/fsPbZpzAUwHwYDVR0jBBgwFoAU
|
||||
a0hkif3RMaraiWtsOOZZlLu9wJwwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwSgYD
|
||||
VR0RBEMwQYILZXhhbXBsZS5jb22CD3d3dy5leGFtcGxlLmNvbYIQbWFpbC5leGFt
|
||||
cGxlLmNvbYIPZnRwLmV4YW1wbGUuY29tMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM
|
||||
IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAgEAyWf1TiJI
|
||||
aNEIA9o/PG8/JiGASTS2/HBVTJbkq03k6NkJVk/GxC1DPziTUJ+CdWlHWcAi1EOW
|
||||
Ach3QxNDRrVfCOfCMDgElIO1094/reJgdFYG00LRi8QkRJuxANV7YS4tLudhyHJC
|
||||
kR2lhdMNmEuzWK+s2y+5cLrdm7qdvdENQCcV67uvGPx4sc+EaE7x13SczKjWBtbo
|
||||
QCs6JTOW+EkPRl4Zo27K4OIZ43/J+GxvwU9QUVH3wPVdbbLNw+QeTFBYMTEcxyc4
|
||||
kv50HPBFaithziXBFyvdIs19FjkFzu0Uz/e0zb1+vMzQlJMD94HVOrMnIj5Sb2cL
|
||||
KKdYXS4uhxFJmdV091Xur5JkYYwEzuaGav7J3zOzYutrIGTgDluLCvA+VQkRcTsy
|
||||
jZ065SkY/v+38QHp+cmm8WRluupJTs8wYzVp6Fu0iFaaK7ztFmaZmHpiPIfDFjva
|
||||
aCIgzzT5NweJd/b71A2SyzHXJ14zBXsr1PMylMp2TpHIidhuuNuQL6I0HaollB4M
|
||||
Z3FsVBMhVDw4Z76qnFPr8mZE2tar33hSlJI/3pS/bBiukuBk8U7VB0X8OqaUnP3C
|
||||
7b2Z4G8GtqDVcKGMzkvMjT4n9rKd/Le+qHSsQOGO9W/0LB7UDAZSwUsfAPnoBgdS
|
||||
5t9tIomLCOstByXi+gGZue1TcdCa3Ph4kO0=
|
||||
-----END CERTIFICATE-----
|
||||
""".strip()
|
||||
|
||||
# DSA public key as dumped by openssl
|
||||
y_str = """
|
||||
72:95:68:d6:4a:72:87:13:c9:87:c7:50:39:9b:fd:
|
||||
06:43:1e:b1:9e:15:88:7b:7f:8c:24:09:c4:85:11:
|
||||
b1:03:62:78:48:2b:1f:59:4d:0e:c2:09:48:41:3a:
|
||||
21:d7:3e:6e:51:4f:68:0e:2f:5c:62:03:4f:05:eb:
|
||||
ce:15:19:c3:85:cd:b2:68:96:3a:54:06:27:23:e0:
|
||||
fe:e8:9e:48:53:a6:1d:d2:26:86:fe:24:9c:e2:c5:
|
||||
78:6c:5a:f4:6b:17:0f:a6:c7:b7:48:dd:17:69:0c:
|
||||
62:29:e4:85:05:f1:67:a0:ca:8b:f9:d7:7d:19:bd:
|
||||
d0:3d:94:a5:94:17:15:0f
|
||||
"""
|
||||
p_str = """
|
||||
00:b7:dd:f2:0c:84:a5:53:c0:d1:92:3a:f4:aa:77:
|
||||
9f:22:5c:bb:93:74:65:9d:ca:d4:af:61:95:e4:0b:
|
||||
36:a2:84:71:93:a1:ed:af:c2:d8:9d:53:3d:d9:87:
|
||||
4c:b2:74:ac:0c:01:67:59:d6:c6:70:11:4a:04:69:
|
||||
87:38:86:0c:5b:29:28:26:10:c1:87:12:33:3f:0a:
|
||||
a0:58:2f:5d:b5:e9:b9:c8:72:a0:50:02:89:0d:8b:
|
||||
a9:99:dc:e4:c6:a4:b8:b4:2d:2d:c4:1c:89:26:06:
|
||||
62:3d:f3:99:97:58:32:86:bd:d3:81:75:68:35:ab:
|
||||
f8:3c:50:23:a0:d5:0b:7f:db
|
||||
"""
|
||||
q_str = """
|
||||
00:86:a5:cc:08:9e:9f:40:ad:c6:d8:ef:52:df:f0:
|
||||
82:ff:25:59:5c:2b
|
||||
"""
|
||||
g_str = """
|
||||
51:5d:13:a5:dd:1d:a4:85:7e:e5:d7:42:d0:8c:31:
|
||||
20:a3:70:75:23:38:d7:53:f8:cf:31:c3:01:97:a5:
|
||||
ce:fa:70:49:5f:1a:ff:b1:c6:ea:f0:08:e2:bf:b2:
|
||||
d3:9c:6a:52:8e:0a:f2:1e:db:df:8f:cf:3b:91:fb:
|
||||
e8:f1:06:d2:4b:79:29:de:fa:b9:b9:2a:88:ba:2e:
|
||||
c4:ee:bd:e3:82:e5:9a:2e:3e:b5:e8:01:b5:1d:63:
|
||||
9c:b5:72:54:8e:ab:22:69:b6:70:b2:9d:a1:d3:d8:
|
||||
07:4f:39:87:11:70:4e:9a:20:11:bb:cc:45:c4:a0:
|
||||
07:c6:cb:a8:ee:89:c0:6f
|
||||
"""
|
||||
|
||||
key = DSA.importKey(x509_v3_cert)
|
||||
for comp_name in ('y', 'p', 'q', 'g'):
|
||||
comp_str = locals()[comp_name + "_str"]
|
||||
comp = int(re.sub("[^0-9a-f]", "", comp_str), 16)
|
||||
self.assertEqual(getattr(key, comp_name), comp)
|
||||
self.assertFalse(key.has_private())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(ImportKeyTests)
|
||||
tests += list_test_cases(ImportKeyFromX509Cert)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
2782
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_import_ECC.py
vendored
Normal file
2782
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_import_ECC.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
636
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_import_RSA.py
vendored
Normal file
636
env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_import_RSA.py
vendored
Normal file
@ -0,0 +1,636 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_importKey.py: Self-test for importing RSA keys
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
import os
|
||||
import re
|
||||
import errno
|
||||
import warnings
|
||||
import unittest
|
||||
from unittest import SkipTest
|
||||
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.SelfTest.st_common import a2b_hex, list_test_cases
|
||||
from Crypto.IO import PEM
|
||||
from Crypto.Util.py3compat import b, tostr, FileNotFoundError
|
||||
from Crypto.Util.number import inverse
|
||||
from Crypto.Util import asn1
|
||||
|
||||
try:
|
||||
import pycryptodome_test_vectors # type: ignore
|
||||
test_vectors_available = True
|
||||
except ImportError:
|
||||
test_vectors_available = False
|
||||
|
||||
|
||||
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(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("Skipping tests for RSA based on %s" % file_name,
|
||||
UserWarning,
|
||||
stacklevel=2)
|
||||
|
||||
if results is None:
|
||||
raise SkipTest("Missing %s" % file_name)
|
||||
|
||||
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)
|
||||
pem += b('').join(chunks)
|
||||
pem += b('-----END %s KEY-----' % text)
|
||||
return pem
|
||||
|
||||
|
||||
class ImportKeyTests(unittest.TestCase):
|
||||
# 512-bit RSA key generated with openssl
|
||||
rsaKeyPEM = u'''-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+TLr7UkvEtFrRhDDKMtuII
|
||||
q19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQJACUSDEp8RTe32ftq8IwG8
|
||||
Wojl5mAd1wFiIOrZ/Uv8b963WJOJiuQcVN29vxU5+My9GPZ7RA3hrDBEAoHUDPrI
|
||||
OQIhAPIPLz4dphiD9imAkivY31Rc5AfHJiQRA7XixTcjEkojAiEAyh/pJHks/Mlr
|
||||
+rdPNEpotBjfV4M4BkgGAA/ipcmaAjcCIQCHvhwwKVBLzzTscT2HeUdEeBMoiXXK
|
||||
JACAr3sJQJGxIQIgarRp+m1WSKV1MciwMaTOnbU7wxFs9DP1pva76lYBzgUCIQC9
|
||||
n0CnZCJ6IZYqSt0H5N7+Q+2Ro64nuwV/OSQfM6sBwQ==
|
||||
-----END RSA PRIVATE KEY-----'''
|
||||
|
||||
# As above, but this is actually an unencrypted PKCS#8 key
|
||||
rsaKeyPEM8 = u'''-----BEGIN PRIVATE KEY-----
|
||||
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvx4nkAqgiyNRGlwS
|
||||
ga5tkzEsPv6RP5MuvtSS8S0WtGEMMoy24girX0WsvilQgzKY8xIsGfeEkt7fQPDj
|
||||
wZAzhQIDAQABAkAJRIMSnxFN7fZ+2rwjAbxaiOXmYB3XAWIg6tn9S/xv3rdYk4mK
|
||||
5BxU3b2/FTn4zL0Y9ntEDeGsMEQCgdQM+sg5AiEA8g8vPh2mGIP2KYCSK9jfVFzk
|
||||
B8cmJBEDteLFNyMSSiMCIQDKH+kkeSz8yWv6t080Smi0GN9XgzgGSAYAD+KlyZoC
|
||||
NwIhAIe+HDApUEvPNOxxPYd5R0R4EyiJdcokAICvewlAkbEhAiBqtGn6bVZIpXUx
|
||||
yLAxpM6dtTvDEWz0M/Wm9rvqVgHOBQIhAL2fQKdkInohlipK3Qfk3v5D7ZGjrie7
|
||||
BX85JB8zqwHB
|
||||
-----END PRIVATE KEY-----'''
|
||||
|
||||
# The same RSA private key as in rsaKeyPEM, but now encrypted
|
||||
rsaKeyEncryptedPEM = (
|
||||
|
||||
# PEM encryption
|
||||
# With DES and passphrase 'test'
|
||||
('test', u'''-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-CBC,AF8F9A40BD2FA2FC
|
||||
|
||||
Ckl9ex1kaVEWhYC2QBmfaF+YPiR4NFkRXA7nj3dcnuFEzBnY5XULupqQpQI3qbfA
|
||||
u8GYS7+b3toWWiHZivHbAAUBPDIZG9hKDyB9Sq2VMARGsX1yW1zhNvZLIiVJzUHs
|
||||
C6NxQ1IJWOXzTew/xM2I26kPwHIvadq+/VaT8gLQdjdH0jOiVNaevjWnLgrn1mLP
|
||||
BCNRMdcexozWtAFNNqSzfW58MJL2OdMi21ED184EFytIc1BlB+FZiGZduwKGuaKy
|
||||
9bMbdb/1PSvsSzPsqW7KSSrTw6MgJAFJg6lzIYvR5F4poTVBxwBX3+EyEmShiaNY
|
||||
IRX3TgQI0IjrVuLmvlZKbGWP18FXj7I7k9tSsNOOzllTTdq3ny5vgM3A+ynfAaxp
|
||||
dysKznQ6P+IoqML1WxAID4aGRMWka+uArOJ148Rbj9s=
|
||||
-----END RSA PRIVATE KEY-----'''),
|
||||
|
||||
# PKCS8 encryption
|
||||
('winter', u'''-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBpjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIeZIsbW3O+JcCAggA
|
||||
MBQGCCqGSIb3DQMHBAgSM2p0D8FilgSCAWBhFyP2tiGKVpGj3mO8qIBzinU60ApR
|
||||
3unvP+N6j7LVgnV2lFGaXbJ6a1PbQXe+2D6DUyBLo8EMXrKKVLqOMGkFMHc0UaV6
|
||||
R6MmrsRDrbOqdpTuVRW+NVd5J9kQQh4xnfU/QrcPPt7vpJvSf4GzG0n666Ki50OV
|
||||
M/feuVlIiyGXY6UWdVDpcOV72cq02eNUs/1JWdh2uEBvA9fCL0c07RnMrdT+CbJQ
|
||||
NjJ7f8ULtp7xvR9O3Al/yJ4Wv3i4VxF1f3MCXzhlUD4I0ONlr0kJWgeQ80q/cWhw
|
||||
ntvgJwnCn2XR1h6LA8Wp+0ghDTsL2NhJpWd78zClGhyU4r3hqu1XDjoXa7YCXCix
|
||||
jCV15+ViDJzlNCwg+W6lRg18sSLkCT7alviIE0U5tHc6UPbbHwT5QqAxAABaP+nZ
|
||||
CGqJGyiwBzrKebjgSm/KRd4C91XqcsysyH2kKPfT51MLAoD4xelOURBP
|
||||
-----END ENCRYPTED PRIVATE KEY-----'''
|
||||
),
|
||||
)
|
||||
|
||||
rsaPublicKeyPEM = u'''-----BEGIN PUBLIC KEY-----
|
||||
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+T
|
||||
Lr7UkvEtFrRhDDKMtuIIq19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQ==
|
||||
-----END PUBLIC KEY-----'''
|
||||
|
||||
# Obtained using 'ssh-keygen -i -m PKCS8 -f rsaPublicKeyPEM'
|
||||
rsaPublicKeyOpenSSH = b('''ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAQQC/HieQCqCLI1EaXBKBrm2TMSw+/pE/ky6+1JLxLRa0YQwyjLbiCKtfRay+KVCDMpjzEiwZ94SS3t9A8OPBkDOF comment\n''')
|
||||
|
||||
# The private key, in PKCS#1 format encoded with DER
|
||||
rsaKeyDER = a2b_hex(
|
||||
'''3082013b020100024100bf1e27900aa08b23511a5c1281ae6d93312c3efe
|
||||
913f932ebed492f12d16b4610c328cb6e208ab5f45acbe2950833298f312
|
||||
2c19f78492dedf40f0e3c190338502030100010240094483129f114dedf6
|
||||
7edabc2301bc5a88e5e6601dd7016220ead9fd4bfc6fdeb75893898ae41c
|
||||
54ddbdbf1539f8ccbd18f67b440de1ac30440281d40cfac839022100f20f
|
||||
2f3e1da61883f62980922bd8df545ce407c726241103b5e2c53723124a23
|
||||
022100ca1fe924792cfcc96bfab74f344a68b418df578338064806000fe2
|
||||
a5c99a023702210087be1c3029504bcf34ec713d877947447813288975ca
|
||||
240080af7b094091b12102206ab469fa6d5648a57531c8b031a4ce9db53b
|
||||
c3116cf433f5a6f6bbea5601ce05022100bd9f40a764227a21962a4add07
|
||||
e4defe43ed91a3ae27bb057f39241f33ab01c1
|
||||
'''.replace(" ",""))
|
||||
|
||||
# The private key, in unencrypted PKCS#8 format encoded with DER
|
||||
rsaKeyDER8 = a2b_hex(
|
||||
'''30820155020100300d06092a864886f70d01010105000482013f3082013
|
||||
b020100024100bf1e27900aa08b23511a5c1281ae6d93312c3efe913f932
|
||||
ebed492f12d16b4610c328cb6e208ab5f45acbe2950833298f3122c19f78
|
||||
492dedf40f0e3c190338502030100010240094483129f114dedf67edabc2
|
||||
301bc5a88e5e6601dd7016220ead9fd4bfc6fdeb75893898ae41c54ddbdb
|
||||
f1539f8ccbd18f67b440de1ac30440281d40cfac839022100f20f2f3e1da
|
||||
61883f62980922bd8df545ce407c726241103b5e2c53723124a23022100c
|
||||
a1fe924792cfcc96bfab74f344a68b418df578338064806000fe2a5c99a0
|
||||
23702210087be1c3029504bcf34ec713d877947447813288975ca240080a
|
||||
f7b094091b12102206ab469fa6d5648a57531c8b031a4ce9db53bc3116cf
|
||||
433f5a6f6bbea5601ce05022100bd9f40a764227a21962a4add07e4defe4
|
||||
3ed91a3ae27bb057f39241f33ab01c1
|
||||
'''.replace(" ",""))
|
||||
|
||||
rsaPublicKeyDER = a2b_hex(
|
||||
'''305c300d06092a864886f70d0101010500034b003048024100bf1e27900a
|
||||
a08b23511a5c1281ae6d93312c3efe913f932ebed492f12d16b4610c328c
|
||||
b6e208ab5f45acbe2950833298f3122c19f78492dedf40f0e3c190338502
|
||||
03010001
|
||||
'''.replace(" ",""))
|
||||
|
||||
n = int('BF 1E 27 90 0A A0 8B 23 51 1A 5C 12 81 AE 6D 93 31 2C 3E FE 91 3F 93 2E BE D4 92 F1 2D 16 B4 61 0C 32 8C B6 E2 08 AB 5F 45 AC BE 29 50 83 32 98 F3 12 2C 19 F7 84 92 DE DF 40 F0 E3 C1 90 33 85'.replace(" ",""),16)
|
||||
e = 65537
|
||||
d = int('09 44 83 12 9F 11 4D ED F6 7E DA BC 23 01 BC 5A 88 E5 E6 60 1D D7 01 62 20 EA D9 FD 4B FC 6F DE B7 58 93 89 8A E4 1C 54 DD BD BF 15 39 F8 CC BD 18 F6 7B 44 0D E1 AC 30 44 02 81 D4 0C FA C8 39'.replace(" ",""),16)
|
||||
p = int('00 F2 0F 2F 3E 1D A6 18 83 F6 29 80 92 2B D8 DF 54 5C E4 07 C7 26 24 11 03 B5 E2 C5 37 23 12 4A 23'.replace(" ",""),16)
|
||||
q = int('00 CA 1F E9 24 79 2C FC C9 6B FA B7 4F 34 4A 68 B4 18 DF 57 83 38 06 48 06 00 0F E2 A5 C9 9A 02 37'.replace(" ",""),16)
|
||||
|
||||
# This is q^{-1} mod p). fastmath and slowmath use pInv (p^{-1}
|
||||
# mod q) instead!
|
||||
qInv = int('00 BD 9F 40 A7 64 22 7A 21 96 2A 4A DD 07 E4 DE FE 43 ED 91 A3 AE 27 BB 05 7F 39 24 1F 33 AB 01 C1'.replace(" ",""),16)
|
||||
pInv = inverse(p,q)
|
||||
|
||||
def testImportKey1(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE"""
|
||||
key = RSA.importKey(self.rsaKeyDER)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey2(self):
|
||||
"""Verify import of SubjectPublicKeyInfo DER SEQUENCE"""
|
||||
key = RSA.importKey(self.rsaPublicKeyDER)
|
||||
self.assertFalse(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey3unicode(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as unicode"""
|
||||
key = RSA.importKey(self.rsaKeyPEM)
|
||||
self.assertEqual(key.has_private(),True) # assert_
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey3bytes(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as byte string"""
|
||||
key = RSA.importKey(b(self.rsaKeyPEM))
|
||||
self.assertEqual(key.has_private(),True) # assert_
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey4unicode(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as unicode"""
|
||||
key = RSA.importKey(self.rsaPublicKeyPEM)
|
||||
self.assertEqual(key.has_private(),False) # assertFalse
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey4bytes(self):
|
||||
"""Verify import of SubjectPublicKeyInfo DER SEQUENCE, encoded with PEM as byte string"""
|
||||
key = RSA.importKey(b(self.rsaPublicKeyPEM))
|
||||
self.assertEqual(key.has_private(),False) # assertFalse
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey5(self):
|
||||
"""Verifies that the imported key is still a valid RSA pair"""
|
||||
key = RSA.importKey(self.rsaKeyPEM)
|
||||
idem = key._encrypt(key._decrypt(89))
|
||||
self.assertEqual(idem, 89)
|
||||
|
||||
def testImportKey6(self):
|
||||
"""Verifies that the imported key is still a valid RSA pair"""
|
||||
key = RSA.importKey(self.rsaKeyDER)
|
||||
idem = key._encrypt(key._decrypt(65))
|
||||
self.assertEqual(idem, 65)
|
||||
|
||||
def testImportKey7(self):
|
||||
"""Verify import of OpenSSH public key"""
|
||||
key = RSA.importKey(self.rsaPublicKeyOpenSSH)
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey8(self):
|
||||
"""Verify import of encrypted PrivateKeyInfo DER SEQUENCE"""
|
||||
for t in self.rsaKeyEncryptedPEM:
|
||||
key = RSA.importKey(t[1], t[0])
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey9(self):
|
||||
"""Verify import of unencrypted PrivateKeyInfo DER SEQUENCE"""
|
||||
key = RSA.importKey(self.rsaKeyDER8)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey10(self):
|
||||
"""Verify import of unencrypted PrivateKeyInfo DER SEQUENCE, encoded with PEM"""
|
||||
key = RSA.importKey(self.rsaKeyPEM8)
|
||||
self.assertTrue(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey11(self):
|
||||
"""Verify import of RSAPublicKey DER SEQUENCE"""
|
||||
der = asn1.DerSequence([17, 3]).encode()
|
||||
key = RSA.importKey(der)
|
||||
self.assertEqual(key.n, 17)
|
||||
self.assertEqual(key.e, 3)
|
||||
|
||||
def testImportKey12(self):
|
||||
"""Verify import of RSAPublicKey DER SEQUENCE, encoded with PEM"""
|
||||
der = asn1.DerSequence([17, 3]).encode()
|
||||
pem = der2pem(der)
|
||||
key = RSA.importKey(pem)
|
||||
self.assertEqual(key.n, 17)
|
||||
self.assertEqual(key.e, 3)
|
||||
|
||||
def test_import_key_windows_cr_lf(self):
|
||||
pem_cr_lf = "\r\n".join(self.rsaKeyPEM.splitlines())
|
||||
key = RSA.importKey(pem_cr_lf)
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def test_import_empty(self):
|
||||
self.assertRaises(ValueError, RSA.import_key, b"")
|
||||
|
||||
###
|
||||
def testExportKey1(self):
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
derKey = key.export_key("DER")
|
||||
self.assertEqual(derKey, self.rsaKeyDER)
|
||||
|
||||
def testExportKey2(self):
|
||||
key = RSA.construct([self.n, self.e])
|
||||
derKey = key.export_key("DER")
|
||||
self.assertEqual(derKey, self.rsaPublicKeyDER)
|
||||
|
||||
def testExportKey3(self):
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
pemKey = key.export_key("PEM")
|
||||
self.assertEqual(pemKey, b(self.rsaKeyPEM))
|
||||
|
||||
def testExportKey4(self):
|
||||
key = RSA.construct([self.n, self.e])
|
||||
pemKey = key.export_key("PEM")
|
||||
self.assertEqual(pemKey, b(self.rsaPublicKeyPEM))
|
||||
|
||||
def testExportKey5(self):
|
||||
key = RSA.construct([self.n, self.e])
|
||||
openssh_1 = key.export_key("OpenSSH").split()
|
||||
openssh_2 = self.rsaPublicKeyOpenSSH.split()
|
||||
self.assertEqual(openssh_1[0], openssh_2[0])
|
||||
self.assertEqual(openssh_1[1], openssh_2[1])
|
||||
|
||||
def testExportKey7(self):
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
derKey = key.export_key("DER", pkcs=8)
|
||||
self.assertEqual(derKey, self.rsaKeyDER8)
|
||||
|
||||
def testExportKey8(self):
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
pemKey = key.export_key("PEM", pkcs=8)
|
||||
self.assertEqual(pemKey, b(self.rsaKeyPEM8))
|
||||
|
||||
def testExportKey9(self):
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
self.assertRaises(ValueError, key.export_key, "invalid-format")
|
||||
|
||||
def testExportKey10(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# PEM envelope, PKCS#1, old PEM encryption
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.export_key('PEM', 'test')
|
||||
self.assertTrue(tostr(outkey).find('4,ENCRYPTED')!=-1)
|
||||
self.assertTrue(tostr(outkey).find('BEGIN RSA PRIVATE KEY')!=-1)
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def testExportKey11(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# PEM envelope, PKCS#1, old PEM encryption
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.export_key('PEM', 'test', pkcs=1)
|
||||
self.assertTrue(tostr(outkey).find('4,ENCRYPTED')!=-1)
|
||||
self.assertTrue(tostr(outkey).find('BEGIN RSA PRIVATE KEY')!=-1)
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def testExportKey12(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# PEM envelope, PKCS#8, old PEM encryption
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.export_key('PEM', 'test', pkcs=8)
|
||||
self.assertTrue(tostr(outkey).find('4,ENCRYPTED')!=-1)
|
||||
self.assertTrue(tostr(outkey).find('BEGIN PRIVATE KEY')!=-1)
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def testExportKey13(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# PEM envelope, PKCS#8, PKCS#8 encryption
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.export_key('PEM', 'test', pkcs=8,
|
||||
protection='PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC')
|
||||
self.assertTrue(tostr(outkey).find('4,ENCRYPTED')==-1)
|
||||
self.assertTrue(tostr(outkey).find('BEGIN ENCRYPTED PRIVATE KEY')!=-1)
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def testExportKey14(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# DER envelope, PKCS#8, PKCS#8 encryption
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.export_key('DER', 'test', pkcs=8)
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def testExportKey15(self):
|
||||
# Verify that that error an condition is detected when trying to
|
||||
# use a password with DER encoding and PKCS#1.
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
self.assertRaises(ValueError, key.export_key, 'DER', 'test', 1)
|
||||
|
||||
def testExportKey16(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# PEM envelope, PKCS#8, PKCS#8 encryption with parameters
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.export_key('PEM', 'test', pkcs=8,
|
||||
protection='PBKDF2WithHMAC-SHA512AndAES256-CBC',
|
||||
prot_params={'iteration_count':123}
|
||||
)
|
||||
self.assertTrue(tostr(outkey).find('4,ENCRYPTED')==-1)
|
||||
self.assertTrue(tostr(outkey).find('BEGIN ENCRYPTED PRIVATE KEY')!=-1)
|
||||
|
||||
# Verify the iteration count
|
||||
der = PEM.decode(tostr(outkey))[0]
|
||||
seq1 = asn1.DerSequence().decode(der)
|
||||
seq2 = asn1.DerSequence().decode(seq1[0])
|
||||
seq3 = asn1.DerSequence().decode(seq2[1])
|
||||
seq4 = asn1.DerSequence().decode(seq3[0])
|
||||
seq5 = asn1.DerSequence().decode(seq4[1])
|
||||
self.assertEqual(seq5[1], 123)
|
||||
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def test_import_key(self):
|
||||
"""Verify that import_key is an alias to importKey"""
|
||||
key = RSA.import_key(self.rsaPublicKeyDER)
|
||||
self.assertFalse(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def test_import_key_ba_mv(self):
|
||||
"""Verify that import_key can be used on bytearrays and memoryviews"""
|
||||
key = RSA.import_key(bytearray(self.rsaPublicKeyDER))
|
||||
key = RSA.import_key(memoryview(self.rsaPublicKeyDER))
|
||||
|
||||
def test_exportKey(self):
|
||||
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
self.assertEqual(key.export_key(), key.exportKey())
|
||||
|
||||
|
||||
class ImportKeyFromX509Cert(unittest.TestCase):
|
||||
|
||||
def test_x509v1(self):
|
||||
|
||||
# Sample V1 certificate with a 1024 bit RSA key
|
||||
x509_v1_cert = """
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICOjCCAaMCAQEwDQYJKoZIhvcNAQEEBQAwfjENMAsGA1UEChMEQWNtZTELMAkG
|
||||
A1UECxMCUkQxHDAaBgkqhkiG9w0BCQEWDXNwYW1AYWNtZS5vcmcxEzARBgNVBAcT
|
||||
Ck1ldHJvcG9saXMxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYDVQQGEwJVUzENMAsG
|
||||
A1UEAxMEdGVzdDAeFw0xNDA3MTExOTU3MjRaFw0xNzA0MDYxOTU3MjRaME0xCzAJ
|
||||
BgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazENMAsGA1UEChMEQWNtZTELMAkG
|
||||
A1UECxMCUkQxDzANBgNVBAMTBmxhdHZpYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
|
||||
gYkCgYEAyG+kytdRj3TFbRmHDYp3TXugVQ81chew0qeOxZWOz80IjtWpgdOaCvKW
|
||||
NCuc8wUR9BWrEQW+39SaRMLiQfQtyFSQZijc3nsEBu/Lo4uWZ0W/FHDRVSvkJA/V
|
||||
Ex5NL5ikI+wbUeCV5KajGNDalZ8F1pk32+CBs8h1xNx5DyxuEHUCAwEAATANBgkq
|
||||
hkiG9w0BAQQFAAOBgQCVQF9Y//Q4Psy+umEM38pIlbZ2hxC5xNz/MbVPwuCkNcGn
|
||||
KYNpQJP+JyVTsPpO8RLZsAQDzRueMI3S7fbbwTzAflN0z19wvblvu93xkaBytVok
|
||||
9VBAH28olVhy9b1MMeg2WOt5sUEQaFNPnwwsyiY9+HsRpvpRnPSQF+kyYVsshQ==
|
||||
-----END CERTIFICATE-----
|
||||
""".strip()
|
||||
|
||||
# RSA public key as dumped by openssl
|
||||
exponent = 65537
|
||||
modulus_str = """
|
||||
00:c8:6f:a4:ca:d7:51:8f:74:c5:6d:19:87:0d:8a:
|
||||
77:4d:7b:a0:55:0f:35:72:17:b0:d2:a7:8e:c5:95:
|
||||
8e:cf:cd:08:8e:d5:a9:81:d3:9a:0a:f2:96:34:2b:
|
||||
9c:f3:05:11:f4:15:ab:11:05:be:df:d4:9a:44:c2:
|
||||
e2:41:f4:2d:c8:54:90:66:28:dc:de:7b:04:06:ef:
|
||||
cb:a3:8b:96:67:45:bf:14:70:d1:55:2b:e4:24:0f:
|
||||
d5:13:1e:4d:2f:98:a4:23:ec:1b:51:e0:95:e4:a6:
|
||||
a3:18:d0:da:95:9f:05:d6:99:37:db:e0:81:b3:c8:
|
||||
75:c4:dc:79:0f:2c:6e:10:75
|
||||
"""
|
||||
modulus = int(re.sub("[^0-9a-f]","", modulus_str), 16)
|
||||
|
||||
key = RSA.importKey(x509_v1_cert)
|
||||
self.assertEqual(key.e, exponent)
|
||||
self.assertEqual(key.n, modulus)
|
||||
self.assertFalse(key.has_private())
|
||||
|
||||
def test_x509v3(self):
|
||||
|
||||
# Sample V3 certificate with a 1024 bit RSA key
|
||||
x509_v3_cert = """
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEcjCCAlqgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJVUzEL
|
||||
MAkGA1UECAwCTUQxEjAQBgNVBAcMCUJhbHRpbW9yZTEQMA4GA1UEAwwHVGVzdCBD
|
||||
QTEfMB0GCSqGSIb3DQEJARYQdGVzdEBleGFtcGxlLmNvbTAeFw0xNDA3MTIwOTM1
|
||||
MTJaFw0xNzA0MDcwOTM1MTJaMEQxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNRDES
|
||||
MBAGA1UEBwwJQmFsdGltb3JlMRQwEgYDVQQDDAtUZXN0IFNlcnZlcjCBnzANBgkq
|
||||
hkiG9w0BAQEFAAOBjQAwgYkCgYEA/S7GJV2OcFdyNMQ4K75KrYFtMEn3VnEFdPHa
|
||||
jyS37XlMxSh0oS4GeTGVUCJInl5Cpsv8WQdh03FfeOdvzp5IZ46OcjeOPiWnmjgl
|
||||
2G5j7e2bDH7RSchGV+OD6Fb1Agvuu2/9iy8fdf3rPQ/7eAddzKUrzwacVbnW+tg2
|
||||
QtSXKRcCAwEAAaOB1TCB0jAdBgNVHQ4EFgQU/WwCX7FfWMIPDFfJ+I8a2COG+l8w
|
||||
HwYDVR0jBBgwFoAUa0hkif3RMaraiWtsOOZZlLu9wJwwCQYDVR0TBAIwADALBgNV
|
||||
HQ8EBAMCBeAwSgYDVR0RBEMwQYILZXhhbXBsZS5jb22CD3d3dy5leGFtcGxlLmNv
|
||||
bYIQbWFpbC5leGFtcGxlLmNvbYIPZnRwLmV4YW1wbGUuY29tMCwGCWCGSAGG+EIB
|
||||
DQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsF
|
||||
AAOCAgEAvO6xfdsGbnoK4My3eJthodTAjMjPwFVY133LH04QLcCv54TxKhtUg1fi
|
||||
PgdjVe1HpTytPBfXy2bSZbXAN0abZCtw1rYrnn7o1g2pN8iypVq3zVn0iMTzQzxs
|
||||
zEPO3bpR/UhNSf90PmCsS5rqZpAAnXSaAy1ClwHWk/0eG2pYkhE1m1ABVMN2lsAW
|
||||
e9WxGk6IFqaI9O37NYQwmEypMs4DC+ECJEvbPFiqi3n0gbXCZJJ6omDA5xJldaYK
|
||||
Oa7KR3s/qjBsu9UAiWpLBuFoSTHIF2aeRKRFmUdmzwo43eVPep65pY6eQ4AdL2RF
|
||||
rqEuINbGlzI5oQyYhu71IwB+iPZXaZZPlwjLgOsuad/p2hOgDb5WxUi8FnDPursQ
|
||||
ujfpIpmrOP/zpvvQWnwePI3lI+5n41kTBSbefXEdv6rXpHk3QRzB90uPxnXPdxSC
|
||||
16ASA8bQT5an/1AgoE3k9CrcD2K0EmgaX0YI0HUhkyzbkg34EhpWJ6vvRUbRiNRo
|
||||
9cIbt/ya9Y9u0Ja8GLXv6dwX0l0IdJMkL8KifXUFAVCujp1FBrr/gdmwQn8itANy
|
||||
+qbnWSxmOvtaY0zcaFAcONuHva0h51/WqXOMO1eb8PhR4HIIYU8p1oBwQp7dSni8
|
||||
THDi1F+GG5PsymMDj5cWK42f+QzjVw5PrVmFqqrrEoMlx8DWh5Y=
|
||||
-----END CERTIFICATE-----
|
||||
""".strip()
|
||||
|
||||
# RSA public key as dumped by openssl
|
||||
exponent = 65537
|
||||
modulus_str = """
|
||||
00:fd:2e:c6:25:5d:8e:70:57:72:34:c4:38:2b:be:
|
||||
4a:ad:81:6d:30:49:f7:56:71:05:74:f1:da:8f:24:
|
||||
b7:ed:79:4c:c5:28:74:a1:2e:06:79:31:95:50:22:
|
||||
48:9e:5e:42:a6:cb:fc:59:07:61:d3:71:5f:78:e7:
|
||||
6f:ce:9e:48:67:8e:8e:72:37:8e:3e:25:a7:9a:38:
|
||||
25:d8:6e:63:ed:ed:9b:0c:7e:d1:49:c8:46:57:e3:
|
||||
83:e8:56:f5:02:0b:ee:bb:6f:fd:8b:2f:1f:75:fd:
|
||||
eb:3d:0f:fb:78:07:5d:cc:a5:2b:cf:06:9c:55:b9:
|
||||
d6:fa:d8:36:42:d4:97:29:17
|
||||
"""
|
||||
modulus = int(re.sub("[^0-9a-f]","", modulus_str), 16)
|
||||
|
||||
key = RSA.importKey(x509_v3_cert)
|
||||
self.assertEqual(key.e, exponent)
|
||||
self.assertEqual(key.n, modulus)
|
||||
self.assertFalse(key.has_private())
|
||||
|
||||
|
||||
class TestImport_2048(unittest.TestCase):
|
||||
|
||||
def test_import_pss(self):
|
||||
pub_key_file = load_file("rsa2048_pss_public.pem")
|
||||
pub_key = RSA.import_key(pub_key_file)
|
||||
|
||||
priv_key_file = load_file("rsa2048_pss_private.pem")
|
||||
priv_key = RSA.import_key(priv_key_file)
|
||||
|
||||
self.assertEqual(pub_key.n, priv_key.n)
|
||||
|
||||
def test_import_openssh_public(self):
|
||||
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)
|
||||
|
||||
def test_import_openssh_private_clear(self):
|
||||
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)
|
||||
|
||||
self.assertEqual(key, key_old)
|
||||
|
||||
def test_import_openssh_private_password(self):
|
||||
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)
|
||||
|
||||
def test_import_pkcs8_private(self):
|
||||
key_file_ref = load_file("rsa2048_private.pem")
|
||||
key_file = load_file("rsa2048_private_p8.der")
|
||||
|
||||
# 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)
|
||||
key = RSA.import_key(key_file, b'secret')
|
||||
self.assertEqual(key_ref, key)
|
||||
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(ImportKeyTests)
|
||||
tests += list_test_cases(ImportKeyFromX509Cert)
|
||||
tests += list_test_cases(TestImport_2048)
|
||||
return tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
def suite():
|
||||
return unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
Reference in New Issue
Block a user