Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/ellipticcurve/privateKey.py: 45%
43 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1from .math import Math
2from .utils.integer import RandomInteger
3from .utils.pem import getPemContent, createPem
4from .utils.binary import hexFromByteString, byteStringFromHex, intFromHex, base64FromByteString, byteStringFromBase64
5from .utils.der import hexFromInt, parse, encodeConstructed, DerFieldType, encodePrimitive
6from .curve import secp256k1, getByOid
7from .publicKey import PublicKey
10class PrivateKey:
12 def __init__(self, curve=secp256k1, secret=None):
13 self.curve = curve
14 self.secret = secret or RandomInteger.between(1, curve.N - 1)
16 def publicKey(self):
17 curve = self.curve
18 publicPoint = Math.multiply(
19 p=curve.G,
20 n=self.secret,
21 N=curve.N,
22 A=curve.A,
23 P=curve.P,
24 )
25 return PublicKey(point=publicPoint, curve=curve)
27 def toString(self):
28 return hexFromInt(self.secret)
30 def toDer(self):
31 publicKeyString = self.publicKey().toString(encoded=True)
32 hexadecimal = encodeConstructed(
33 encodePrimitive(DerFieldType.integer, 1),
34 encodePrimitive(DerFieldType.octetString, hexFromInt(self.secret)),
35 encodePrimitive(DerFieldType.oidContainer, encodePrimitive(DerFieldType.object, self.curve.oid)),
36 encodePrimitive(DerFieldType.publicKeyPointContainer, encodePrimitive(DerFieldType.bitString, publicKeyString))
37 )
38 return byteStringFromHex(hexadecimal)
40 def toPem(self):
41 der = self.toDer()
42 return createPem(content=base64FromByteString(der), template=_pemTemplate)
44 @classmethod
45 def fromPem(cls, string):
46 privateKeyPem = getPemContent(pem=string, template=_pemTemplate)
47 return cls.fromDer(byteStringFromBase64(privateKeyPem))
49 @classmethod
50 def fromDer(cls, string):
51 hexadecimal = hexFromByteString(string)
52 privateKeyFlag, secretHex, curveData, publicKeyString = parse(hexadecimal)[0]
53 if privateKeyFlag != 1:
54 raise Exception("Private keys should start with a '1' flag, but a '{flag}' was found instead".format(
55 flag=privateKeyFlag
56 ))
57 curve = getByOid(curveData[0])
58 privateKey = cls.fromString(string=secretHex, curve=curve)
59 if privateKey.publicKey().toString(encoded=True) != publicKeyString[0]:
60 raise Exception("The public key described inside the private key file doesn't match the actual public key of the pair")
61 return privateKey
63 @classmethod
64 def fromString(cls, string, curve=secp256k1):
65 return PrivateKey(secret=intFromHex(string), curve=curve)
68_pemTemplate = """
69-----BEGIN EC PRIVATE KEY-----
70{content}
71-----END EC PRIVATE KEY-----
72"""