You can use the ECC.construct(**kwargs)
call to construct keys from the respective integers.
I've shown below how to do this for an uncompressed point in hex and then bytes rather than as a number though. An uncompressed point is not a number in itself. So I haven't included the 0x
in your question for these byte arrays.
The private key vector (usually denoted s
or d
, I prefer s
for secret) is a number, but generally it will be transmitted using bytes as well (if it is ever transmitted, usually it is kept in place).
from Crypto.PublicKey import ECC
# --- ECC public key from "flat" uncompressed EC point representation ---
# lets assume that the input is binary, rather than an integer
uncompressedPointHex = "04017655e42a892cc71bccedcb1cd421d03530e1d7edb52cef143c5562c4c6f0129fa5a37738013e64a1ff0e6cb7068815a13000eb162cb7a0214dfcf3c8fa101c"
uncompressedPoint = bytes.fromhex(uncompressedPointHex)
# check if the point is uncompressed rather than compressed
# for compressed points ask a separate *question*
off = 0
if (uncompressedPoint[off] != 0x04):
raise Exception("Not an uncompressed point")
off += 1
sizeBytes = (len(uncompressedPoint) - 1) // 2
xBin = uncompressedPoint[off:off + sizeBytes]
x = int.from_bytes(xBin, 'big', signed=False)
off += sizeBytes
yBin = uncompressedPoint[off:off + sizeBytes]
y = int.from_bytes(yBin, 'big', signed=False)
off += sizeBytes
if (off != len(uncompressedPoint)):
raise Exception("Invalid format of uncompressed point")
# if you already have integers, this is all you need
publicKey = ECC.construct(curve="secp256r1", point_x=x, point_y=y)
# obviously just for testing the result
print(publicKey)
# --- ECC private key from "flat" uncompressed EC point representation ---
# lets assume that the input is binary, rather than an integer
sHex = "63bd3b01c5ce749d87f5f7481232a93540acdb0f7b5c014ecd9cd32b041d6f33"
sBin = bytes.fromhex(sHex)
# very straightforward conversion, as S is just there
s = int.from_bytes(sBin, 'big', signed=False)
# if you already have integers, this is all you need
privateKey = ECC.construct(curve="secp256r1", d=s)
# obviously just for testing the result
print(privateKey)
outputs
EccKey(curve='NIST P-256',
point_x=661393602013979783798470650260404653019684003375182707210783968552030760978,
point_y=72210400889213969389982861398963807410315877398616325431902307461337204789276)
EccKey(curve='NIST P-256',
point_x=661393602013979783798470650260404653019684003375182707210783968552030760978,
point_y=72210400889213969389982861398963807410315877398616325431902307461337204789276,
d=45113313355812346734724097146216873116458888764597604491161664272788312911667)
...slightly formatted with whitespace to show that the second key is indeed the private key containing d.
The x
and y
values can be calculated from d
(point multiplication with the base point: d*G
), which is why the private key can contain them without having them specified during construction.
Note that I've used Python 3, maybe some Python dev is able to convert it to Python 2 and include the result in this answer. The idea / calls should be similar after all.
construct
can be used, in Cryptographyderive_private_key
andpublicKey
. – Cobra