Updated DB_Helper by adding firebase methods.

This commit is contained in:
Batuhan Berk Başoğlu 2020-10-05 16:53:40 -04:00
parent 485cc3bbba
commit c82121d036
1810 changed files with 537281 additions and 1 deletions

View file

@ -0,0 +1,54 @@
# -*- 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"""
__revision__ = "$Id$"
import os
def get_tests(config={}):
tests = []
from Crypto.SelfTest.PublicKey import test_DSA; tests += test_DSA.get_tests(config=config)
from Crypto.SelfTest.PublicKey import test_RSA; tests += test_RSA.get_tests(config=config)
from Crypto.SelfTest.PublicKey import test_ECC; tests += test_ECC.get_tests(config=config)
from Crypto.SelfTest.PublicKey import test_import_DSA
tests +=test_import_DSA.get_tests(config=config)
from Crypto.SelfTest.PublicKey import test_import_RSA
tests += test_import_RSA.get_tests(config=config)
from Crypto.SelfTest.PublicKey import test_import_ECC
tests += test_import_ECC.get_tests(config=config)
from Crypto.SelfTest.PublicKey import test_ElGamal; tests += test_ElGamal.get_tests(config=config)
return tests
if __name__ == '__main__':
import unittest
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,240 @@
# -*- 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.publickey()
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.publickey()
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.publickey() == dsaObj.publickey(),True) # assert_
self.assertEqual(dsaObj.publickey() != dsaObj.publickey(),False) # failIf
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)))
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:

View file

@ -0,0 +1,284 @@
# ===================================================================
#
# Copyright (c) 2015, 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
import time
from Crypto.SelfTest.st_common import list_test_cases
from Crypto.SelfTest.loader import load_tests
from Crypto.PublicKey import ECC
from Crypto.PublicKey.ECC import EccPoint, _curve, EccKey
class TestEccPoint_NIST(unittest.TestCase):
"""Tests defined in section 4.3 of https://www.nsa.gov/ia/_files/nist-routines.pdf"""
pointS = EccPoint(
0xde2444bebc8d36e682edd27e0f271508617519b3221a8fa0b77cab3989da97c9,
0xc093ae7ff36e5380fc01a5aad1e66659702de80f53cec576b6350b243042a256)
pointT = EccPoint(
0x55a8b00f8da1d44e62f6b3b25316212e39540dc861c89575bb8cf92e35e0986b,
0x5421c3209c2d6c704835d82ac4c3dd90f61a8a52598b9e7ab656e9d8c8b24316)
def test_set(self):
pointW = EccPoint(0, 0)
pointW.set(self.pointS)
self.assertEqual(pointW, self.pointS)
def test_copy(self):
pointW = self.pointS.copy()
self.assertEqual(pointW, self.pointS)
pointW.set(self.pointT)
self.assertEqual(pointW, self.pointT)
self.assertNotEqual(self.pointS, self.pointT)
def test_addition(self):
pointRx = 0x72b13dd4354b6b81745195e98cc5ba6970349191ac476bd4553cf35a545a067e
pointRy = 0x8d585cbb2e1327d75241a8a122d7620dc33b13315aa5c9d46d013011744ac264
pointR = self.pointS + self.pointT
self.assertEqual(pointR.x, pointRx)
self.assertEqual(pointR.y, pointRy)
pai = EccPoint.point_at_infinity()
# S + 0
pointR = self.pointS + pai
self.assertEqual(pointR, self.pointS)
# 0 + S
pointR = pai + self.pointS
self.assertEqual(pointR, self.pointS)
# 0 + 0
pointR = pai + pai
self.assertEqual(pointR, pai)
def test_inplace_addition(self):
pointRx = 0x72b13dd4354b6b81745195e98cc5ba6970349191ac476bd4553cf35a545a067e
pointRy = 0x8d585cbb2e1327d75241a8a122d7620dc33b13315aa5c9d46d013011744ac264
pointR = self.pointS.copy()
pointR += self.pointT
self.assertEqual(pointR.x, pointRx)
self.assertEqual(pointR.y, pointRy)
pai = EccPoint.point_at_infinity()
# S + 0
pointR = self.pointS.copy()
pointR += pai
self.assertEqual(pointR, self.pointS)
# 0 + S
pointR = pai.copy()
pointR += self.pointS
self.assertEqual(pointR, self.pointS)
# 0 + 0
pointR = pai.copy()
pointR += pai
self.assertEqual(pointR, pai)
def test_doubling(self):
pointRx = 0x7669e6901606ee3ba1a8eef1e0024c33df6c22f3b17481b82a860ffcdb6127b0
pointRy = 0xfa878162187a54f6c39f6ee0072f33de389ef3eecd03023de10ca2c1db61d0c7
pointR = self.pointS.copy()
pointR.double()
self.assertEqual(pointR.x, pointRx)
self.assertEqual(pointR.y, pointRy)
# 2*0
pai = self.pointS.point_at_infinity()
pointR = pai.copy()
pointR.double()
self.assertEqual(pointR, pai)
# S + S
pointR = self.pointS.copy()
pointR += pointR
self.assertEqual(pointR.x, pointRx)
self.assertEqual(pointR.y, pointRy)
def test_scalar_multiply(self):
d = 0xc51e4753afdec1e6b6c6a5b992f43f8dd0c7a8933072708b6522468b2ffb06fd
pointRx = 0x51d08d5f2d4278882946d88d83c97d11e62becc3cfc18bedacc89ba34eeca03f
pointRy = 0x75ee68eb8bf626aa5b673ab51f6e744e06f8fcf8a6c0cf3035beca956a7b41d5
pointR = self.pointS * d
self.assertEqual(pointR.x, pointRx)
self.assertEqual(pointR.y, pointRy)
# 0*S
pai = self.pointS.point_at_infinity()
pointR = self.pointS * 0
self.assertEqual(pointR, pai)
# -1*S
self.assertRaises(ValueError, lambda: self.pointS * -1)
def test_joing_scalar_multiply(self):
d = 0xc51e4753afdec1e6b6c6a5b992f43f8dd0c7a8933072708b6522468b2ffb06fd
e = 0xd37f628ece72a462f0145cbefe3f0b355ee8332d37acdd83a358016aea029db7
pointRx = 0xd867b4679221009234939221b8046245efcf58413daacbeff857b8588341f6b8
pointRy = 0xf2504055c03cede12d22720dad69c745106b6607ec7e50dd35d54bd80f615275
pointR = self.pointS * d + self.pointT * e
self.assertEqual(pointR.x, pointRx)
self.assertEqual(pointR.y, pointRy)
class TestEccPoint_PAI(unittest.TestCase):
"""Test vectors from http://point-at-infinity.org/ecc/nisttv"""
pointG = EccPoint(_curve.Gx, _curve.Gy)
tv_pai = load_tests(("Crypto", "SelfTest", "PublicKey", "test_vectors", "ECC"),
"point-at-infinity.org-P256.txt",
"P-256 tests from point-at-infinity.org",
{ "k" : lambda k: int(k),
"x" : lambda x: int(x, 16),
"y" : lambda y: int(y, 16)} )
assert(tv_pai)
for tv in tv_pai:
def new_test(self, scalar=tv.k, x=tv.x, y=tv.y):
result = self.pointG * scalar
self.assertEqual(result.x, x)
self.assertEqual(result.y, y)
setattr(TestEccPoint_PAI, "test_%d" % tv.count, new_test)
class TestEccKey(unittest.TestCase):
def test_private_key(self):
key = EccKey(curve="P-256", d=1)
self.assertEqual(key.d, 1)
self.assertTrue(key.has_private())
self.assertEqual(key.pointQ.x, _curve.Gx)
self.assertEqual(key.pointQ.y, _curve.Gy)
point = EccPoint(_curve.Gx, _curve.Gy)
key = EccKey(curve="P-256", d=1, point=point)
self.assertEqual(key.d, 1)
self.assertTrue(key.has_private())
self.assertEqual(key.pointQ, point)
# Other names
key = EccKey(curve="secp256r1", d=1)
key = EccKey(curve="prime256v1", d=1)
def test_public_key(self):
point = EccPoint(_curve.Gx, _curve.Gy)
key = EccKey(curve="P-256", point=point)
self.assertFalse(key.has_private())
self.assertEqual(key.pointQ, point)
def test_public_key_derived(self):
priv_key = EccKey(curve="P-256", d=3)
pub_key = priv_key.public_key()
self.assertFalse(pub_key.has_private())
self.assertEqual(priv_key.pointQ, pub_key.pointQ)
def test_invalid_curve(self):
self.assertRaises(ValueError, lambda: EccKey(curve="P-257", d=1))
def test_invalid_d(self):
self.assertRaises(ValueError, lambda: EccKey(curve="P-256", d=0))
self.assertRaises(ValueError, lambda: EccKey(curve="P-256", d=_curve.order))
def test_equality(self):
private_key = ECC.construct(d=3, curve="P-256")
private_key2 = ECC.construct(d=3, curve="P-256")
private_key3 = ECC.construct(d=4, curve="P-256")
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)
class TestEccModule(unittest.TestCase):
def test_generate(self):
key = ECC.generate(curve="P-256")
self.assertTrue(key.has_private())
self.assertEqual(key.pointQ, EccPoint(_curve.Gx, _curve.Gy) * key.d)
# Other names
ECC.generate(curve="secp256r1")
ECC.generate(curve="prime256v1")
def test_construct(self):
key = ECC.construct(curve="P-256", d=1)
self.assertTrue(key.has_private())
self.assertEqual(key.pointQ, _curve.G)
key = ECC.construct(curve="P-256", point_x=_curve.Gx, point_y=_curve.Gy)
self.assertFalse(key.has_private())
self.assertEqual(key.pointQ, _curve.G)
# Other names
ECC.construct(curve="secp256r1", d=1)
ECC.construct(curve="prime256v1", d=1)
def test_negative_construct(self):
coord = dict(point_x=10, point_y=4)
coordG = dict(point_x=_curve.Gx, point_y=_curve.Gy)
self.assertRaises(ValueError, ECC.construct, curve="P-256", **coord)
self.assertRaises(ValueError, ECC.construct, curve="P-256", d=2, **coordG)
def get_tests(config={}):
tests = []
tests += list_test_cases(TestEccPoint_NIST)
tests += list_test_cases(TestEccPoint_PAI)
tests += list_test_cases(TestEccKey)
tests += list_test_cases(TestEccModule)
return tests
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')

View 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 list(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')

View file

@ -0,0 +1,315 @@
# -*- 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.publickey()
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.publickey()
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.publickey()
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 positive
# 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._encrypt, rsa_obj.n)
self.assertRaises(ValueError, rsa_obj._decrypt, 0)
self.assertRaises(ValueError, rsa_obj._encrypt, 0)
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
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))
# Check __eq__ and __ne__
self.assertEqual(rsaObj.publickey() == rsaObj.publickey(),True) # assert_
self.assertEqual(rsaObj.publickey() != rsaObj.publickey(),False) # failIf
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:

View file

@ -0,0 +1,545 @@
# -*- 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 list(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.exportKey('DER')
self.assertEqual(self.der_public, encoded)
# 2.
pem_public="""\
-----BEGIN DSA 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 DSA 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.exportKey('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.exportKey('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.exportKey('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.exportKey('DER')
self.assertEqual(self.der_pkcs8, encoded)
encoded = key.exportKey('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.exportKey('PEM')
self.assertEqual(self.pem_pkcs8, encoded)
encoded = key.exportKey('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.exportKey('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.exportKey('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.exportKey('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.exportKey, '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)
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')

View file

@ -0,0 +1,392 @@
# ===================================================================
#
# Copyright (c) 2015, 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 Crypto.SelfTest.st_common import list_test_cases
from Crypto.Util._file_system import pycryptodome_filename
from Crypto.Util.py3compat import b, unhexlify, bord, tostr
from Crypto.Util.number import bytes_to_long
from Crypto.Hash import SHAKE128
from Crypto.PublicKey import ECC
def load_file(filename, mode="rb"):
fd = open(pycryptodome_filename([
"Crypto",
"SelfTest",
"PublicKey",
"test_vectors",
"ECC",
], filename), mode)
return fd.read()
def compact(lines):
ext = b("").join(lines)
return unhexlify(tostr(ext).replace(" ", "").replace(":", ""))
def create_ref_keys():
key_lines = load_file("ecc_p256.txt").splitlines()
private_key_d = bytes_to_long(compact(key_lines[2:5]))
public_key_xy = compact(key_lines[6:11])
assert bord(public_key_xy[0]) == 4 # Uncompressed
public_key_x = bytes_to_long(public_key_xy[1:33])
public_key_y = bytes_to_long(public_key_xy[33:])
return (ECC.construct(curve="P-256", d=private_key_d),
ECC.construct(curve="P-256", point_x=public_key_x, point_y=public_key_y))
# Create reference key pair
ref_private, ref_public = create_ref_keys()
def get_fixed_prng():
return SHAKE128.new().update(b("SEED")).read
class TestImport(unittest.TestCase):
def test_import_public_der(self):
key_file = load_file("ecc_p256_public.der")
key = ECC._import_subjectPublicKeyInfo(key_file)
self.assertEqual(ref_public, key)
key = ECC._import_der(key_file, None)
self.assertEqual(ref_public, key)
key = ECC.import_key(key_file)
self.assertEqual(ref_public, key)
def test_import_private_der(self):
key_file = load_file("ecc_p256_private.der")
key = ECC._import_private_der(key_file, None)
self.assertEqual(ref_private, key)
key = ECC._import_der(key_file, None)
self.assertEqual(ref_private, key)
key = ECC.import_key(key_file)
self.assertEqual(ref_private, key)
def test_import_private_pkcs8_clear(self):
key_file = load_file("ecc_p256_private_p8_clear.der")
key = ECC._import_der(key_file, None)
self.assertEqual(ref_private, key)
key = ECC.import_key(key_file)
self.assertEqual(ref_private, key)
def test_import_private_pkcs8_in_pem_clear(self):
key_file = load_file("ecc_p256_private_p8_clear.pem")
key = ECC.import_key(key_file)
self.assertEqual(ref_private, key)
def test_import_private_pkcs8_encrypted_1(self):
key_file = load_file("ecc_p256_private_p8.der")
key = ECC._import_der(key_file, "secret")
self.assertEqual(ref_private, key)
key = ECC.import_key(key_file, "secret")
self.assertEqual(ref_private, key)
def test_import_private_pkcs8_encrypted_2(self):
key_file = load_file("ecc_p256_private_p8.pem")
key = ECC.import_key(key_file, "secret")
self.assertEqual(ref_private, key)
def test_import_x509_der(self):
key_file = load_file("ecc_p256_x509.der")
key = ECC._import_der(key_file, None)
self.assertEqual(ref_public, key)
key = ECC.import_key(key_file)
self.assertEqual(ref_public, key)
def test_import_public_pem(self):
key_file = load_file("ecc_p256_public.pem")
key = ECC.import_key(key_file)
self.assertEqual(ref_public, key)
def test_import_private_pem(self):
key_file = load_file("ecc_p256_private.pem")
key = ECC.import_key(key_file)
self.assertEqual(ref_private, key)
def test_import_private_pem_encrypted(self):
for algo in "des3", : # TODO: , "aes128", "aes192", "aes256_gcm":
key_file = load_file("ecc_p256_private_enc_%s.pem" % algo)
key = ECC.import_key(key_file, "secret")
self.assertEqual(ref_private, key)
key = ECC.import_key(tostr(key_file), b("secret"))
self.assertEqual(ref_private, key)
def test_import_x509_pem(self):
key_file = load_file("ecc_p256_x509.pem")
key = ECC.import_key(key_file)
self.assertEqual(ref_public, key)
def test_import_openssh(self):
key_file = load_file("ecc_p256_public_openssh.txt")
key = ECC._import_openssh(key_file)
self.assertEqual(ref_public, key)
key = ECC.import_key(key_file)
self.assertEqual(ref_public, key)
class TestExport(unittest.TestCase):
def test_export_public_der(self):
key_file = load_file("ecc_p256_public.der")
encoded = ref_public._export_subjectPublicKeyInfo()
self.assertEqual(key_file, encoded)
# ---
encoded = ref_public.export_key(format="DER")
self.assertEqual(key_file, encoded)
def test_export_private_der(self):
key_file = load_file("ecc_p256_private.der")
encoded = ref_private._export_private_der()
self.assertEqual(key_file, encoded)
# ---
encoded = ref_private.export_key(format="DER", use_pkcs8=False)
self.assertEqual(key_file, encoded)
def test_export_private_pkcs8_clear(self):
key_file = load_file("ecc_p256_private_p8_clear.der")
encoded = ref_private._export_pkcs8()
self.assertEqual(key_file, encoded)
# ---
encoded = ref_private.export_key(format="DER")
self.assertEqual(key_file, encoded)
def test_export_private_pkcs8_encrypted(self):
encoded = 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(ref_private, decoded)
# ---
encoded = ref_private.export_key(format="DER",
passphrase="secret",
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
decoded = ECC.import_key(encoded, "secret")
self.assertEqual(ref_private, decoded)
def test_export_public_pem(self):
key_file = load_file("ecc_p256_public.pem", "rt").strip()
encoded = ref_private._export_public_pem()
self.assertEqual(key_file, encoded)
# ---
encoded = ref_public.export_key(format="PEM")
self.assertEqual(key_file, encoded)
def test_export_private_pem_clear(self):
key_file = load_file("ecc_p256_private.pem", "rt").strip()
encoded = ref_private._export_private_pem(None)
self.assertEqual(key_file, encoded)
# ---
encoded = ref_private.export_key(format="PEM", use_pkcs8=False)
self.assertEqual(key_file, encoded)
def test_export_private_pem_encrypted(self):
encoded = ref_private._export_private_pem(passphrase=b("secret"))
# This should prove that the output is password-protected
self.assertRaises(ValueError, ECC.import_key, encoded)
assert "EC PRIVATE KEY" in encoded
decoded = ECC.import_key(encoded, "secret")
self.assertEqual(ref_private, decoded)
# ---
encoded = ref_private.export_key(format="PEM",
passphrase="secret",
use_pkcs8=False)
decoded = ECC.import_key(encoded, "secret")
self.assertEqual(ref_private, decoded)
def test_export_private_pkcs8_and_pem_1(self):
# PKCS8 inside PEM with both unencrypted
key_file = load_file("ecc_p256_private_p8_clear.pem", "rt").strip()
encoded = ref_private._export_private_clear_pkcs8_in_clear_pem()
self.assertEqual(key_file, encoded)
# ---
encoded = ref_private.export_key(format="PEM")
self.assertEqual(key_file, encoded)
def test_export_private_pkcs8_and_pem_2(self):
# PKCS8 inside PEM with PKCS8 encryption
encoded = ref_private._export_private_encrypted_pkcs8_in_clear_pem("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(ref_private, decoded)
# ---
encoded = ref_private.export_key(format="PEM",
passphrase="secret",
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
decoded = ECC.import_key(encoded, "secret")
self.assertEqual(ref_private, decoded)
def test_export_openssh(self):
key_file = load_file("ecc_p256_public_openssh.txt", "rt")
encoded = ref_public._export_openssh()
self.assertEqual(key_file, encoded)
# ---
encoded = ref_public.export_key(format="OpenSSH")
self.assertEqual(key_file, encoded)
def test_prng(self):
# Test that password-protected containers use the provided PRNG
encoded1 = ref_private.export_key(format="PEM",
passphrase="secret",
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC",
randfunc=get_fixed_prng())
encoded2 = ref_private.export_key(format="PEM",
passphrase="secret",
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC",
randfunc=get_fixed_prng())
self.assertEqual(encoded1, encoded2)
# ---
encoded1 = ref_private.export_key(format="PEM",
use_pkcs8=False,
passphrase="secret",
randfunc=get_fixed_prng())
encoded2 = ref_private.export_key(format="PEM",
use_pkcs8=False,
passphrase="secret",
randfunc=get_fixed_prng())
self.assertEqual(encoded1, encoded2)
def test_byte_or_string_passphrase(self):
encoded1 = ref_private.export_key(format="PEM",
use_pkcs8=False,
passphrase="secret",
randfunc=get_fixed_prng())
encoded2 = ref_private.export_key(format="PEM",
use_pkcs8=False,
passphrase=b("secret"),
randfunc=get_fixed_prng())
self.assertEqual(encoded1, encoded2)
def test_error_params1(self):
# Unknown format
self.assertRaises(ValueError, ref_private.export_key, format="XXX")
# Missing 'protection' parameter when PKCS#8 is used
ref_private.export_key(format="PEM", passphrase="secret",
use_pkcs8=False)
self.assertRaises(ValueError, ref_private.export_key, format="PEM",
passphrase="secret")
# DER format but no PKCS#8
self.assertRaises(ValueError, ref_private.export_key, format="DER",
passphrase="secret",
use_pkcs8=False,
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
# Incorrect parameters for public keys
self.assertRaises(ValueError, ref_public.export_key, format="DER",
use_pkcs8=False)
# Empty password
self.assertRaises(ValueError, ref_private.export_key, format="PEM",
passphrase="", use_pkcs8=False)
self.assertRaises(ValueError, ref_private.export_key, format="PEM",
passphrase="",
protection="PBKDF2WithHMAC-SHA1AndAES128-CBC")
# No private keys with OpenSSH
self.assertRaises(ValueError, ref_private.export_key, format="OpenSSH",
passphrase="secret")
def get_tests(config={}):
tests = []
tests += list_test_cases(TestImport)
tests += list_test_cases(TestExport)
return tests
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')

View file

@ -0,0 +1,501 @@
# -*- 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 unittest
import re
from Crypto.PublicKey import RSA
from Crypto.SelfTest.st_common import *
from Crypto.Util.py3compat import *
from Crypto.Util.number import inverse
from Crypto.Util import asn1
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 = '''-----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 = '''-----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', '''-----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', '''-----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 = '''-----BEGIN RSA PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+T
Lr7UkvEtFrRhDDKMtuIIq19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQ==
-----END RSA 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) # failIf
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) # failIf
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 testExportKey1(self):
key = RSA.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
derKey = key.exportKey("DER")
self.assertEqual(derKey, self.rsaKeyDER)
def testExportKey2(self):
key = RSA.construct([self.n, self.e])
derKey = key.exportKey("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.exportKey("PEM")
self.assertEqual(pemKey, b(self.rsaKeyPEM))
def testExportKey4(self):
key = RSA.construct([self.n, self.e])
pemKey = key.exportKey("PEM")
self.assertEqual(pemKey, b(self.rsaPublicKeyPEM))
def testExportKey5(self):
key = RSA.construct([self.n, self.e])
openssh_1 = key.exportKey("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.exportKey("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.exportKey("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.exportKey, "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.exportKey('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.exportKey('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.exportKey('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.exportKey('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.exportKey('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.exportKey, 'DER', 'test', 1)
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)
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())
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')
# vim:set ts=4 sw=4 sts=4 expandtab:

View file

@ -0,0 +1,18 @@
Private-Key: (256 bit)
priv:
5c:4e:43:20:ef:26:0f:91:ed:9f:c5:97:ae:e9:8c:
82:36:b6:0e:0c:ed:69:2c:c7:a0:57:d5:e4:57:98:
a0:52
pub:
04:a4:0a:d5:9a:20:50:eb:e9:24:79:bd:5f:b1:6b:
b2:e4:5b:64:65:eb:3c:b2:b1:ef:fe:42:3f:ab:e6:
cb:74:24:db:82:19:ef:0b:ab:80:ac:f2:6f:d7:05:
95:b6:1f:e4:76:0d:33:ee:d8:0d:d0:3d:2f:d0:df:
b2:7b:8c:e7:5c
ASN1 OID: prime256v1
NIST CURVE: P-256
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIFxOQyDvJg+R7Z/Fl67pjII2tg4M7Wksx6BX1eRXmKBSoAoGCCqGSM49
AwEHoUQDQgAEpArVmiBQ6+kkeb1fsWuy5FtkZes8srHv/kI/q+bLdCTbghnvC6uA
rPJv1wWVth/kdg0z7tgN0D0v0N+ye4znXA==
-----END EC PRIVATE KEY-----

View file

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIFxOQyDvJg+R7Z/Fl67pjII2tg4M7Wksx6BX1eRXmKBSoAoGCCqGSM49
AwEHoUQDQgAEpArVmiBQ6+kkeb1fsWuy5FtkZes8srHv/kI/q+bLdCTbghnvC6uA
rPJv1wWVth/kdg0z7tgN0D0v0N+ye4znXA==
-----END EC PRIVATE KEY-----

View file

@ -0,0 +1,8 @@
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,288614CF0887BAE11B8B660C3CA24139
7Jy/LNIYkloV8x1LVRjy59phEtKrli8ySiFDf6nIBtAmt/WLoZijmCMJ7VTXVXNq
lyruBM2t4At/0EFI3CSQKxFvsnHDwHL9WYEDPC+gQ/Xy8j2JU0IAM+BuasjHAgXw
tq0sJUnRh+xNiI2FotEBC8S194M+lp3RkBZwoBlk3w0=
-----END EC PRIVATE KEY-----

View file

@ -0,0 +1,8 @@
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-192-CBC,82AE4C810C9CF67736F256DEDFD6908E
gWOVzIDfiMQuIvOQ2m5BWQRWYL7DMb2Mbz4GO8ovBHMNOkMAdi0GhanI+dpQyjtw
V9zYBjbqtpMGzACusVYFxvkE9VOb1tj+QphG09Nv4/oUNXBdx1RDxrvntaB/Uskj
0zIDV/7D9esLIPTiBtwy62ZAc5Pxk88IG/Z2nGvJZMg=
-----END EC PRIVATE KEY-----

View file

@ -0,0 +1,8 @@
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: id-aes256-GCM,4071BCFFB5B7CE18CEBFE901
oh6vdMD9bkUvRwtaBkYz6MMWCtjE2GvIKx+diG8XxzakcFzVIqXlDXfEcVIs6Vis
LFofIdBHElQxRUTnCCkb21pmly6v0ZLDugwMWNz6ichaie1gXqi+JwjPe2Ju5aro
UNeOPqFlVkCeEvHxE3eR1vqlDBLar9VwtA==
-----END EC PRIVATE KEY-----

View file

@ -0,0 +1,8 @@
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,7E383189A0521324
GT+hvDACAQAq8mD20yQFuQo5Gfg3gPJbZSErmgtdMa5xRLzPEWFnP1yOfZFIgVhn
HKLNhgrfbNRh3Ij/DcC6gQ+/35Ts9r+4KLMP6qXuEEfQGTCRu0JQbbMCheN7iNM1
8ji47sMaVPJPLrBbD6bPcUl8Tfv0+Xiikvxia5NjqAE=
-----END EC PRIVATE KEY-----

View file

@ -0,0 +1,6 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIGwMBsGCSqGSIb3DQEFAzAOBAjtAa3UT6r2WAICCAAEgZA1MjDX/jkmLeNTlbCK
oDJPqo9OzHoZInlg4diuvId3uAPxyYnMuwTJvCSklOPXQLkgpYsYRF3YgNBuGAld
VQvWcbfwX1eQSqOx6FBCWJgXpWLhlI9qViRDYNQfyam8Xszq7tOdsOdJhSuA+YCt
5mBj57E8tUNLLR6P3lAUIM8WJBlxOWyR0EqdM5vcxYIzzTM=
-----END ENCRYPTED PRIVATE KEY-----

View file

@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgXE5DIO8mD5Htn8WX
rumMgja2DgztaSzHoFfV5FeYoFKhRANCAASkCtWaIFDr6SR5vV+xa7LkW2Rl6zyy
se/+Qj+r5st0JNuCGe8Lq4Cs8m/XBZW2H+R2DTPu2A3QPS/Q37J7jOdc
-----END PRIVATE KEY-----

View file

@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEpArVmiBQ6+kkeb1fsWuy5FtkZes8
srHv/kI/q+bLdCTbghnvC6uArPJv1wWVth/kdg0z7tgN0D0v0N+ye4znXA==
-----END PUBLIC KEY-----

View file

@ -0,0 +1 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKQK1ZogUOvpJHm9X7FrsuRbZGXrPLKx7/5CP6vmy3Qk24IZ7wurgKzyb9cFlbYf5HYNM+7YDdA9L9DfsnuM51w=

View file

@ -0,0 +1,11 @@
-----BEGIN CERTIFICATE-----
MIIBjTCCATOgAwIBAgIJAJtI7kH/tXlvMAoGCCqGSM49BAMCMCMxCzAJBgNVBAYT
AkdCMRQwEgYDVQQDDAtleGFtcGxlLmNvbTAeFw0xNjAxMzAwNjMyNTBaFw0xNzAx
MjkwNjMyNTBaMCMxCzAJBgNVBAYTAkdCMRQwEgYDVQQDDAtleGFtcGxlLmNvbTBZ
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABKQK1ZogUOvpJHm9X7FrsuRbZGXrPLKx
7/5CP6vmy3Qk24IZ7wurgKzyb9cFlbYf5HYNM+7YDdA9L9DfsnuM51yjUDBOMB0G
A1UdDgQWBBSv2v+sOg8Z+VTAJk5ob4nDRS1+jjAfBgNVHSMEGDAWgBSv2v+sOg8Z
+VTAJk5ob4nDRS1+jjAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCID3r
ARj3nfwBK4uE3BmlGKjaH5JR3e9iEac7BT93W6hOAiEAuNZxsvUpadoB4SqurLVg
lrdvw9wpYr8JTq7q2KUIQes=
-----END CERTIFICATE-----

View file

@ -0,0 +1,33 @@
#!/bin/sh
set -e
set -x
openssl version | tee openssl_version.txt
# Private key
openssl ecparam -name prime256v1 -genkey -noout -conv_form uncompressed -out ecc_p256_private.pem
openssl ec -in ecc_p256_private.pem -outform DER -out ecc_p256_private.der
openssl pkcs8 -in ecc_p256_private.der -inform DER -out ecc_p256_private_p8_clear.der -outform DER -nocrypt -topk8
openssl pkcs8 -in ecc_p256_private.der -inform DER -out ecc_p256_private_p8_clear.pem -outform PEM -nocrypt -topk8
openssl ec -in ecc_p256_private.pem -text -out ecc_p256.txt
# Encrypted private key
openssl pkcs8 -in ecc_p256_private.der -inform DER -passout 'pass:secret' -out ecc_p256_private_p8.der -outform DER -topk8
openssl pkcs8 -in ecc_p256_private.der -inform DER -passout 'pass:secret' -out ecc_p256_private_p8.pem -outform PEM -topk8
openssl ec -in ecc_p256_private.pem -des3 -out ecc_p256_private_enc_des3.pem -passout 'pass:secret' -outform PEM
openssl ec -in ecc_p256_private.pem -aes128 -out ecc_p256_private_enc_aes128.pem -passout 'pass:secret' -outform PEM
openssl ec -in ecc_p256_private.pem -aes192 -out ecc_p256_private_enc_aes192.pem -passout 'pass:secret' -outform PEM
openssl ec -in ecc_p256_private.pem -aes-256-gcm -out ecc_p256_private_enc_aes256_gcm.pem -passout 'pass:secret' -outform PEM
# Public key
openssl ec -in ecc_p256_private.pem -pubout -out ecc_p256_public.pem
openssl ec -pubin -in ecc_p256_public.pem -outform DER -out ecc_p256_public.der
# X.509 cert
openssl req -new -key ecc_p256_private.pem -days 365 -x509 -out ecc_p256_x509.pem -subj '/C=GB/CN=example.com'
openssl x509 -in ecc_p256_x509.pem -out ecc_p256_x509.der -outform DER
# OpenSSH
chmod 600 ecc_p256_private.pem
ssh-keygen -f ecc_p256_private.pem -y > ecc_p256_public_openssh.txt

View file

@ -0,0 +1 @@
OpenSSL 1.0.2e-fips 3 Dec 2015

View file

@ -0,0 +1,212 @@
#
# Test vectors for NIST P-256 curve found in http://point-at-infinity.org/ecc/nisttv
# on 1 Jan 2016.
#
k = 1
x = 6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296
y = 4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5
k = 2
x = 7CF27B188D034F7E8A52380304B51AC3C08969E277F21B35A60B48FC47669978
y = 07775510DB8ED040293D9AC69F7430DBBA7DADE63CE982299E04B79D227873D1
k = 3
x = 5ECBE4D1A6330A44C8F7EF951D4BF165E6C6B721EFADA985FB41661BC6E7FD6C
y = 8734640C4998FF7E374B06CE1A64A2ECD82AB036384FB83D9A79B127A27D5032
k = 4
x = E2534A3532D08FBBA02DDE659EE62BD0031FE2DB785596EF509302446B030852
y = E0F1575A4C633CC719DFEE5FDA862D764EFC96C3F30EE0055C42C23F184ED8C6
k = 5
x = 51590B7A515140D2D784C85608668FDFEF8C82FD1F5BE52421554A0DC3D033ED
y = E0C17DA8904A727D8AE1BF36BF8A79260D012F00D4D80888D1D0BB44FDA16DA4
k = 6
x = B01A172A76A4602C92D3242CB897DDE3024C740DEBB215B4C6B0AAE93C2291A9
y = E85C10743237DAD56FEC0E2DFBA703791C00F7701C7E16BDFD7C48538FC77FE2
k = 7
x = 8E533B6FA0BF7B4625BB30667C01FB607EF9F8B8A80FEF5B300628703187B2A3
y = 73EB1DBDE03318366D069F83A6F5900053C73633CB041B21C55E1A86C1F400B4
k = 8
x = 62D9779DBEE9B0534042742D3AB54CADC1D238980FCE97DBB4DD9DC1DB6FB393
y = AD5ACCBD91E9D8244FF15D771167CEE0A2ED51F6BBE76A78DA540A6A0F09957E
k = 9
x = EA68D7B6FEDF0B71878938D51D71F8729E0ACB8C2C6DF8B3D79E8A4B90949EE0
y = 2A2744C972C9FCE787014A964A8EA0C84D714FEAA4DE823FE85A224A4DD048FA
k = 10
x = CEF66D6B2A3A993E591214D1EA223FB545CA6C471C48306E4C36069404C5723F
y = 878662A229AAAE906E123CDD9D3B4C10590DED29FE751EEECA34BBAA44AF0773
k = 11
x = 3ED113B7883B4C590638379DB0C21CDA16742ED0255048BF433391D374BC21D1
y = 9099209ACCC4C8A224C843AFA4F4C68A090D04DA5E9889DAE2F8EEFCE82A3740
k = 12
x = 741DD5BDA817D95E4626537320E5D55179983028B2F82C99D500C5EE8624E3C4
y = 0770B46A9C385FDC567383554887B1548EEB912C35BA5CA71995FF22CD4481D3
k = 13
x = 177C837AE0AC495A61805DF2D85EE2FC792E284B65EAD58A98E15D9D46072C01
y = 63BB58CD4EBEA558A24091ADB40F4E7226EE14C3A1FB4DF39C43BBE2EFC7BFD8
k = 14
x = 54E77A001C3862B97A76647F4336DF3CF126ACBE7A069C5E5709277324D2920B
y = F599F1BB29F4317542121F8C05A2E7C37171EA77735090081BA7C82F60D0B375
k = 15
x = F0454DC6971ABAE7ADFB378999888265AE03AF92DE3A0EF163668C63E59B9D5F
y = B5B93EE3592E2D1F4E6594E51F9643E62A3B21CE75B5FA3F47E59CDE0D034F36
k = 16
x = 76A94D138A6B41858B821C629836315FCD28392EFF6CA038A5EB4787E1277C6E
y = A985FE61341F260E6CB0A1B5E11E87208599A0040FC78BAA0E9DDD724B8C5110
k = 17
x = 47776904C0F1CC3A9C0984B66F75301A5FA68678F0D64AF8BA1ABCE34738A73E
y = AA005EE6B5B957286231856577648E8381B2804428D5733F32F787FF71F1FCDC
k = 18
x = 1057E0AB5780F470DEFC9378D1C7C87437BB4C6F9EA55C63D936266DBD781FDA
y = F6F1645A15CBE5DC9FA9B7DFD96EE5A7DCC11B5C5EF4F1F78D83B3393C6A45A2
k = 19
x = CB6D2861102C0C25CE39B7C17108C507782C452257884895C1FC7B74AB03ED83
y = 58D7614B24D9EF515C35E7100D6D6CE4A496716E30FA3E03E39150752BCECDAA
k = 20
x = 83A01A9378395BAB9BCD6A0AD03CC56D56E6B19250465A94A234DC4C6B28DA9A
y = 76E49B6DE2F73234AE6A5EB9D612B75C9F2202BB6923F54FF8240AAA86F640B8
k = 112233445566778899
x = 339150844EC15234807FE862A86BE77977DBFB3AE3D96F4C22795513AEAAB82F
y = B1C14DDFDC8EC1B2583F51E85A5EB3A155840F2034730E9B5ADA38B674336A21
k = 112233445566778899112233445566778899
x = 1B7E046A076CC25E6D7FA5003F6729F665CC3241B5ADAB12B498CD32F2803264
y = BFEA79BE2B666B073DB69A2A241ADAB0738FE9D2DD28B5604EB8C8CF097C457B
k = 29852220098221261079183923314599206100666902414330245206392788703677545185283
x = 9EACE8F4B071E677C5350B02F2BB2B384AAE89D58AA72CA97A170572E0FB222F
y = 1BBDAEC2430B09B93F7CB08678636CE12EAAFD58390699B5FD2F6E1188FC2A78
k = 57896042899961394862005778464643882389978449576758748073725983489954366354431
x = 878F22CC6DB6048D2B767268F22FFAD8E56AB8E2DC615F7BD89F1E350500DD8D
y = 714A5D7BB901C9C5853400D12341A892EF45D87FC553786756C4F0C9391D763E
k = 1766845392945710151501889105729049882997660004824848915955419660366636031
x = 659A379625AB122F2512B8DADA02C6348D53B54452DFF67AC7ACE4E8856295CA
y = 49D81AB97B648464D0B4A288BD7818FAB41A16426E943527C4FED8736C53D0F6
k = 28948025760307534517734791687894775804466072615242963443097661355606862201087
x = CBCEAAA8A4DD44BBCE58E8DB7740A5510EC2CB7EA8DA8D8F036B3FB04CDA4DE4
y = 4BD7AA301A80D7F59FD983FEDBE59BB7B2863FE46494935E3745B360E32332FA
k = 113078210460870548944811695960290644973229224625838436424477095834645696384
x = F0C4A0576154FF3A33A3460D42EAED806E854DFA37125221D37935124BA462A4
y = 5B392FA964434D29EEC6C9DBC261CF116796864AA2FAADB984A2DF38D1AEF7A3
k = 12078056106883488161242983286051341125085761470677906721917479268909056
x = 5E6C8524B6369530B12C62D31EC53E0288173BD662BDF680B53A41ECBCAD00CC
y = 447FE742C2BFEF4D0DB14B5B83A2682309B5618E0064A94804E9282179FE089F
k = 57782969857385448082319957860328652998540760998293976083718804450708503920639
x = 03792E541BC209076A3D7920A915021ECD396A6EB5C3960024BE5575F3223484
y = FC774AE092403101563B712F68170312304F20C80B40C06282063DB25F268DE4
k = 57896017119460046759583662757090100341435943767777707906455551163257755533312
x = 2379FF85AB693CDF901D6CE6F2473F39C04A2FE3DCD842CE7AAB0E002095BCF8
y = F8B476530A634589D5129E46F322B02FBC610A703D80875EE70D7CE1877436A1
k = 452312848374287284681282171017647412726433684238464212999305864837160993279
x = C1E4072C529BF2F44DA769EFC934472848003B3AF2C0F5AA8F8DDBD53E12ED7C
y = 39A6EE77812BB37E8079CD01ED649D3830FCA46F718C1D3993E4A591824ABCDB
k = 904571339174065134293634407946054000774746055866917729876676367558469746684
x = 34DFBC09404C21E250A9B40FA8772897AC63A094877DB65862B61BD1507B34F3
y = CF6F8A876C6F99CEAEC87148F18C7E1E0DA6E165FFC8ED82ABB65955215F77D3
k = 115792089210356248762697446949407573529996955224135760342422259061068512044349
x = 83A01A9378395BAB9BCD6A0AD03CC56D56E6B19250465A94A234DC4C6B28DA9A
y = 891B64911D08CDCC5195A14629ED48A360DDFD4596DC0AB007DBF5557909BF47
k = 115792089210356248762697446949407573529996955224135760342422259061068512044350
x = CB6D2861102C0C25CE39B7C17108C507782C452257884895C1FC7B74AB03ED83
y = A7289EB3DB2610AFA3CA18EFF292931B5B698E92CF05C1FC1C6EAF8AD4313255
k = 115792089210356248762697446949407573529996955224135760342422259061068512044351
x = 1057E0AB5780F470DEFC9378D1C7C87437BB4C6F9EA55C63D936266DBD781FDA
y = 090E9BA4EA341A246056482026911A58233EE4A4A10B0E08727C4CC6C395BA5D
k = 115792089210356248762697446949407573529996955224135760342422259061068512044352
x = 47776904C0F1CC3A9C0984B66F75301A5FA68678F0D64AF8BA1ABCE34738A73E
y = 55FFA1184A46A8D89DCE7A9A889B717C7E4D7FBCD72A8CC0CD0878008E0E0323
k = 115792089210356248762697446949407573529996955224135760342422259061068512044353
x = 76A94D138A6B41858B821C629836315FCD28392EFF6CA038A5EB4787E1277C6E
y = 567A019DCBE0D9F2934F5E4A1EE178DF7A665FFCF0387455F162228DB473AEEF
k = 115792089210356248762697446949407573529996955224135760342422259061068512044354
x = F0454DC6971ABAE7ADFB378999888265AE03AF92DE3A0EF163668C63E59B9D5F
y = 4A46C11BA6D1D2E1B19A6B1AE069BC19D5C4DE328A4A05C0B81A6321F2FCB0C9
k = 115792089210356248762697446949407573529996955224135760342422259061068512044355
x = 54E77A001C3862B97A76647F4336DF3CF126ACBE7A069C5E5709277324D2920B
y = 0A660E43D60BCE8BBDEDE073FA5D183C8E8E15898CAF6FF7E45837D09F2F4C8A
k = 115792089210356248762697446949407573529996955224135760342422259061068512044356
x = 177C837AE0AC495A61805DF2D85EE2FC792E284B65EAD58A98E15D9D46072C01
y = 9C44A731B1415AA85DBF6E524BF0B18DD911EB3D5E04B20C63BC441D10384027
k = 115792089210356248762697446949407573529996955224135760342422259061068512044357
x = 741DD5BDA817D95E4626537320E5D55179983028B2F82C99D500C5EE8624E3C4
y = F88F4B9463C7A024A98C7CAAB7784EAB71146ED4CA45A358E66A00DD32BB7E2C
k = 115792089210356248762697446949407573529996955224135760342422259061068512044358
x = 3ED113B7883B4C590638379DB0C21CDA16742ED0255048BF433391D374BC21D1
y = 6F66DF64333B375EDB37BC505B0B3975F6F2FB26A16776251D07110317D5C8BF
k = 115792089210356248762697446949407573529996955224135760342422259061068512044359
x = CEF66D6B2A3A993E591214D1EA223FB545CA6C471C48306E4C36069404C5723F
y = 78799D5CD655517091EDC32262C4B3EFA6F212D7018AE11135CB4455BB50F88C
k = 115792089210356248762697446949407573529996955224135760342422259061068512044360
x = EA68D7B6FEDF0B71878938D51D71F8729E0ACB8C2C6DF8B3D79E8A4B90949EE0
y = D5D8BB358D36031978FEB569B5715F37B28EB0165B217DC017A5DDB5B22FB705
k = 115792089210356248762697446949407573529996955224135760342422259061068512044361
x = 62D9779DBEE9B0534042742D3AB54CADC1D238980FCE97DBB4DD9DC1DB6FB393
y = 52A533416E1627DCB00EA288EE98311F5D12AE0A4418958725ABF595F0F66A81
k = 115792089210356248762697446949407573529996955224135760342422259061068512044362
x = 8E533B6FA0BF7B4625BB30667C01FB607EF9F8B8A80FEF5B300628703187B2A3
y = 8C14E2411FCCE7CA92F9607C590A6FFFAC38C9CD34FBE4DE3AA1E5793E0BFF4B
k = 115792089210356248762697446949407573529996955224135760342422259061068512044363
x = B01A172A76A4602C92D3242CB897DDE3024C740DEBB215B4C6B0AAE93C2291A9
y = 17A3EF8ACDC8252B9013F1D20458FC86E3FF0890E381E9420283B7AC7038801D
k = 115792089210356248762697446949407573529996955224135760342422259061068512044364
x = 51590B7A515140D2D784C85608668FDFEF8C82FD1F5BE52421554A0DC3D033ED
y = 1F3E82566FB58D83751E40C9407586D9F2FED1002B27F7772E2F44BB025E925B
k = 115792089210356248762697446949407573529996955224135760342422259061068512044365
x = E2534A3532D08FBBA02DDE659EE62BD0031FE2DB785596EF509302446B030852
y = 1F0EA8A4B39CC339E62011A02579D289B103693D0CF11FFAA3BD3DC0E7B12739
k = 115792089210356248762697446949407573529996955224135760342422259061068512044366
x = 5ECBE4D1A6330A44C8F7EF951D4BF165E6C6B721EFADA985FB41661BC6E7FD6C
y = 78CB9BF2B6670082C8B4F931E59B5D1327D54FCAC7B047C265864ED85D82AFCD
k = 115792089210356248762697446949407573529996955224135760342422259061068512044367
x = 7CF27B188D034F7E8A52380304B51AC3C08969E277F21B35A60B48FC47669978
y = F888AAEE24712FC0D6C26539608BCF244582521AC3167DD661FB4862DD878C2E
k = 115792089210356248762697446949407573529996955224135760342422259061068512044368
x = 6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296
y = B01CBD1C01E58065711814B583F061E9D431CCA994CEA1313449BF97C840AE0A