slight update
This commit is contained in:
63
week05/easy/env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/__init__.py
vendored
Normal file
63
week05/easy/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')
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
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
week05/easy/env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_DSA.py
vendored
Normal file
247
week05/easy/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
week05/easy/env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ECC_Curve25519.py
vendored
Normal file
283
week05/easy/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
week05/easy/env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ECC_Curve448.py
vendored
Normal file
246
week05/easy/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
week05/easy/env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ECC_Ed25519.py
vendored
Normal file
341
week05/easy/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
week05/easy/env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ECC_Ed448.py
vendored
Normal file
336
week05/easy/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
week05/easy/env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ECC_NIST.py
vendored
Normal file
1440
week05/easy/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
week05/easy/env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_ElGamal.py
vendored
Normal file
217
week05/easy/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
week05/easy/env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_RSA.py
vendored
Normal file
324
week05/easy/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
week05/easy/env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_import_Curve25519.py
vendored
Normal file
385
week05/easy/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
week05/easy/env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_import_Curve448.py
vendored
Normal file
351
week05/easy/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
week05/easy/env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_import_DSA.py
vendored
Normal file
554
week05/easy/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
week05/easy/env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_import_ECC.py
vendored
Normal file
2782
week05/easy/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
week05/easy/env/lib/python3.12/site-packages/Crypto/SelfTest/PublicKey/test_import_RSA.py
vendored
Normal file
636
week05/easy/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