CryptoSys PKI Pro Manual

ECC_ReadKeyByCurve

Reads an EC key from its hexadecimal (base16) representation.

VBA/VB6 Syntax

Public Declare Function ECC_ReadKeyByCurve Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strHexKey As String, ByVal strCurveName As String, ByVal nOptions As Long) As Long

nRet = ECC_ReadKeyByCurve(strOutput, Len(strOutput), strHexKey, strCurveName, nOptions)

C/C++ Syntax

long __stdcall ECC_ReadKeyByCurve(char *szOutput, long nOutChars, const char *szHexKey, const char *szCurveName, long nOptions);

Parameters

szOutput
[out] string of sufficient length to receive the output.
nOutChars
[in] specifying the maximum number of characters to be received.
szHexKey
[in] containing a hexadecimal (base16) representation of the key
szCurveName
[in] containing the name of the elliptic curve (see remarks)
nOptions
[in] For Safe Curves specify PKI_ECC_PRIVATE_KEY or PKI_ECC_PUBLIC_KEY to indicate that the key value represents a private or public key, respectively. Otherwise, nOptions is ignored.

Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string; otherwise it returns a nonzero error code.

VBA Wrapper Syntax

Public Function eccReadKeyByCurve (szHexKey As String, szCurveName As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Ecc.ReadKeyByCurve Method

C++ (STL) Equivalent

static std::string dipki::Ecc::ReadKeyByCurve (std::string hexKey, Curve curve, Publicity publicity=Publicity::PrivateKey)

Python Equivalent

static Ecc.read_key_by_curve(keyhex, curvename, ispublic=False)

Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer szOutput of the required length. Specify a zero nOutChars or an empty string for szOutput to find the required length. ANSI C users must add one to this value when allocating memory.

The output string is an ephemeral internal key string valid only for the current session. This internal key string can be used directly by functions such as ECC_DHSharedSecret or SIG_SignData. You can analyze the key string using ECC_QueryKey or save it in one of the supported key file formats using ECC_SaveKey or ECC_SaveEncKey. The input string is expected to be the hexadecimal (base16) representation of a private or public key.

NIST/SEC/Brainpool curves: A private key is represented by the hexadecimal encoding of its integer value encoded in octets as per section 3 of [RFC5915]. A public key is represented by the hexadecimal encoding of the octet string as defined in section 4.3.6 of [X9-63]; that is, 04||Px||Py. Only the uncompressed form of a public key (beginning "04") is supported due to patent issues. It is an error if the key value is out of range or not a valid point on the curve.

Safe curves: Both private and public keys are represented by the hexadecimal encoding of its integer value encoded as a byte array in little-endian form as per [RFC7748] and [RFC8032]. For Ed25519 and X25519, the input string szHexKey is always expected to be a hexadecimal representation of exactly 32 bytes. Set nOptions as PKI_ECC_PRIVATE_KEY (default 0) or PKI_ECC_PUBLIC_KEY to indicate whether the key value represents a private or public key, respectively. Any 32-byte key string will be accepted as input and any required bit masking (e.g. for an X25519 private key) will be applied before use.

Supported curve names for szCurveName are:

Curve nameAlternative namesRemarks
secp192r1P-192, P_192, prime192v1NIST
secp224r1P-224, P_224NIST
secp256r1P-256, P_256, prime256v1NIST
secp384r1P-384, P_384NIST
secp521r1P-521, P_521NIST
secp256k1 SEC/Bitcoin
Ed25519 Safe EdDSA curve [RFC8032]
Ed448 Safe EdDSA curve [RFC8032]
X25519 Safe ECDH curve [RFC7748]
X448 Safe ECDH curve [RFC7748]
brainpoolP256r1 [RFC5639]
brainpoolP384r1 [RFC5639]
brainpoolP512r1 [RFC5639]

Example (VBA core function)

Dim nRet As Long
Dim nChars As Long
Dim strIntKey As String
Dim strHexKey As String
Dim strCurveName As String
Dim strQuery As String
Dim strBuffer As String
Dim strBase58 As String
Dim abTemp() As Byte
Dim nBytes As Long
  
' 1. A NIST P-192 public key in X9.63 uncompressed format
strHexKey = _
 "0496C248BE456192FA1380CCF615D171452F41FF31B92BA733524FD77168DEA4425A3EA8FD79B98DC7AFE83C86DCC39A96"
strCurveName = "prime192v1"  ' A synonym for "P-192"
Debug.Print "KEYHEX: " & strHexKey
Debug.Print "CURVE: " & strCurveName
' Find required length of internal key string
nChars = ECC_ReadKeyByCurve("", 0, strHexKey, strCurveName, 0)
Debug.Print "ECC_ReadKeyByCurve returns " & nChars & " (expected +ve)"
' Dimension the string to receive output
strIntKey = String(nChars, " ")
' Read into internal key string
nChars = ECC_ReadKeyByCurve(strIntKey, Len(strIntKey), strHexKey, strCurveName, 0)
' Find the key size in bits
strQuery = "keyBits"
nRet = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')=" & nRet & " (expected +ve)"
' Is it a private or public key?
strQuery = "isPrivate"
nRet = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')=" & nRet & " (expected 0)"
Debug.Print

' 2. A Bitcoin private key in base58 form
strBase58 = "6ACCbmy9qwiFcuVgvxNNwMPfoghobzznWrLs3v7t3RmN"
Debug.Print "KEYB58: " & strBase58
strCurveName = "secp256k1"
' Convert to a hex string
nBytes = CNV_Base58ToBytes(0, 0, strBase58)
Debug.Assert (nBytes > 0)
ReDim abTemp(nBytes - 1)
nBytes = CNV_Base58ToBytes(abTemp(0), nBytes, strBase58)
strHexKey = cnvHexStrFromBytes(abTemp)
Debug.Print "KEYHEX: " & strHexKey
Debug.Print "CURVE: " & strCurveName
' Find required length of internal key string
nChars = ECC_ReadKeyByCurve("", 0, strHexKey, strCurveName, 0)
Debug.Print "ECC_ReadKeyByCurve returns " & nChars & " (expected +ve)"
' Dimension the string to receive output
strIntKey = String(nChars, " ")
' Read into internal key string
nChars = ECC_ReadKeyByCurve(strIntKey, Len(strIntKey), strHexKey, strCurveName, 0)
' Find the key size in bits
strQuery = "keyBits"
nRet = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')=" & nRet & " (expected +ve)"
' Is it a private or public key?
strQuery = "isPrivate"
nRet = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')=" & nRet & " (expected 1)"

' Extract the public key in hex form
strQuery = "publicKey"
nChars = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
strBuffer = String(nChars, " ")
nChars = ECC_QueryKey(strBuffer, Len(strBuffer), strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')="
If nChars > 0 Then Debug.Print "[" & Left(strBuffer, nChars) & "]"
KEYHEX: 0496C248BE456192FA1380CCF615D171452F41FF31B92BA733524FD77168DEA4425A3EA8FD79B98DC7AFE83C86DCC39A96
CURVE: prime192v1
ECC_ReadKeyByCurve returns 100 (expected +ve)
ECC_QueryKey('keyBits')=192 (expected +ve)
ECC_QueryKey('isPrivate')=0 (expected 0)

KEYB58: 6ACCbmy9qwiFcuVgvxNNwMPfoghobzznWrLs3v7t3RmN
KEYHEX: 4CA55366ADE9E9BC12319DFFC246F64EB7FA07755925B92CEFC92D740DBC51ED
CURVE: secp256k1
ECC_ReadKeyByCurve returns 196 (expected +ve)
ECC_QueryKey('keyBits')=256 (expected +ve)
ECC_QueryKey('isPrivate')=1 (expected 1)
ECC_QueryKey('publicKey')=
[04654bacc2fc7a3bde0f8eb95dc5aac9ba1df732255cf7f2eb7e1e8e6edbb1f4188ff3752ac4bdf1e3a31a488747745dddcbabd33a10c3b52d737c092851da13c0]

Example (VBA wrapper function)

Dim curveName As String
Dim alicePrivateKeyHex As String
Dim ourPrivateKey As String
Dim nChars As Long

curveName = "X25519"
alicePrivateKeyHex = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"

' The old long way...
nChars = ECC_ReadKeyByCurve(vbNullString, 0, alicePrivateKeyHex, curveName, PKI_ECC_PRIVATE_KEY)
Debug.Assert nChars > 0
ourPrivateKey = String(nChars, " ")
nChars = ECC_ReadKeyByCurve(ourPrivateKey, nChars, alicePrivateKeyHex, curveName, PKI_ECC_PRIVATE_KEY)

' The new short way with a wrapper function
ourPrivateKey = eccReadKeyByCurve(alicePrivateKeyHex, curveName, PKI_ECC_PRIVATE_KEY)
Debug.Assert Len(ourPrivateKey) > 0
Debug.Print "Key curve=" & eccQueryKey(ourPrivateKey, "curveName", 0) & " keyBits=" & eccQueryKey(ourPrivateKey, "keyBits", 0)
Dim strCurveName As String
Dim ourPrivateKey As String
Dim theirPublicKey As String
Dim lpZZ() As Byte

' Ref: RFC7748 Section 6.1
Const alicePrivateKeyHex As String = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"
Const alicePublicKeyHex As String = "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"
Const bobPrivateKeyHex As String = "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb"
Const bobPublicKeyHex As String = "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f"

strCurveName = "X25519"
' 1. Alice's private + Bob's public
ourPrivateKey = eccReadKeyByCurve(alicePrivateKeyHex, strCurveName, PKI_ECC_PRIVATE_KEY)
Debug.Print "Our key has " & eccQueryKey(ourPrivateKey, "keyBits") & " bits and is a " & _
    IIf(eccQueryKey(ourPrivateKey, "isPrivate") = "1", "Private", "Public") & " key"
theirPublicKey = eccReadKeyByCurve(bobPublicKeyHex, strCurveName, PKI_ECC_PUBLIC_KEY)
Debug.Print "Their key has " & eccQueryKey(theirPublicKey, "keyBits") & " bits and is a " & _
    IIf(eccQueryKey(theirPublicKey, "isPrivate") = "1", "Private", "Public") & " key"
' Compute shared secret
lpZZ = eccDHSharedSecret(ourPrivateKey, theirPublicKey)
Debug.Print "ZZ=" & cnvHexStrFromBytes(lpZZ)
Debug.Print "OK=4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"

' 2. Bob's private + Alice's public
ourPrivateKey = eccReadKeyByCurve(bobPrivateKeyHex, strCurveName, PKI_ECC_PRIVATE_KEY)
Debug.Print "Our key has " & eccQueryKey(ourPrivateKey, "keyBits") & " bits and is a " & _
    IIf(eccQueryKey(ourPrivateKey, "isPrivate") = "1", "Private", "Public") & " key"
theirPublicKey = eccReadKeyByCurve(alicePublicKeyHex, strCurveName, PKI_ECC_PUBLIC_KEY)
Debug.Print "Their key has " & eccQueryKey(theirPublicKey, "keyBits") & " bits and is a " & _
    IIf(eccQueryKey(theirPublicKey, "isPrivate") = "1", "Private", "Public") & " key"
' Compute shared secret
lpZZ = eccDHSharedSecret(ourPrivateKey, theirPublicKey)
Debug.Print "ZZ=" & cnvHexStrFromBytes(lpZZ)
Debug.Print "OK=4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"

See Also

ECC_QueryKey

[Contents] [Index]

[PREV: ECC_QueryKey...]   [Contents]   [Index]   
   [NEXT: ECC_ReadPrivateKey...]

Copyright © 2004-24 D.I. Management Services Pty Ltd. All rights reserved. Generated 2024-09-23T07:52:09Z.