Console.WriteLine("\nECDH SHARED SECRET USING P-256:"); // Ref: CAVS 14.1 ECC CDH Primitive (SP800 - 56A Section 5.7.1.2) // Test Information for "testecccdh" ecccdhtestvectors.zip // [P-256] Ecc.CurveName curve = Ecc.CurveName.P_256; // Our private key is dUIT: string ourPrivateKeyHex = "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534"; // Their public key as hex is "04" || QCAVSx || QCAVSy string theirPublicKeyHex = "04" + "700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287" + "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac"; // Correct expected result string zzOK = "46FC62106420FF012E54A434FBDD2D25CCC5852060561E68040DD7778997BD7B"; string ourPrivateKey = Ecc.ReadKeyByCurve(ourPrivateKeyHex, curve); Console.WriteLine("Curve = {0}", Ecc.QueryKey(ourPrivateKey, "curveName")); Console.WriteLine("Our private key has {0} bits", Ecc.QueryKey(ourPrivateKey, "keyBits")); string theirPublicKey = Ecc.ReadKeyByCurve(theirPublicKeyHex, curve); Console.WriteLine("Their public key has {0} bits", Ecc.QueryKey(theirPublicKey, "keyBits")); // Compute shared secret byte[] zz = Ecc.DHSharedSecret(ourPrivateKey, theirPublicKey); Console.WriteLine("ZZ={0}", Cnv.ToHex(zz)); Debug.Assert(Cnv.ToHex(zz) == zzOK, "Ecc.DHSharedSecret failed");
For similar code using VBA/VB6 see the example in ECC_DHSharedSecret and the (shorter) example below. This shorter example uses the new VBA/VB6 wrapper functions introduced v20.0.1.
Debug.Print "Testing ECC_DHSharedSecret ..." Dim strOurPriKeyHex As String Dim strTheirPubKeyHex As String Dim strOurPrivateKey As String Dim strTheirPublicKey As String Dim strCurveName As String Dim strCorrectHex As String Dim lpZZ() As Byte ' Ref: CAVS 14.1 ECC CDH Primitive (SP800 - 56A Section 5.7.1.2) ' Test Information for "testecccdh" ecccdhtestvectors.zip '[P-256] strCurveName = "P-256" ' Our private key is dUIT: strOurPriKeyHex = "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534" ' Their public key as hex is "04" || QCAVSx || QCAVSy strTheirPubKeyHex = "04" & "700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287" _ + "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac" ' Correct result is ZIUT strCorrectHex = "46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b" Debug.Print "Test for curve " & strCurveName & " ..." ' Read in keys to internal key strings ' Our private key... strOurPrivateKey = eccReadKeyByCurve(strOurPriKeyHex, strCurveName, 0) Debug.Assert Len(strOurPrivateKey) > 0 ' Check the key we read in Debug.Print "Our private key has " & ECC_QueryKey("", 0, strOurPrivateKey, "keyBits", 0) & " bits" ' Their public key... strTheirPublicKey = eccReadKeyByCurve(strTheirPubKeyHex, strCurveName, 0) Debug.Assert Len(strTheirPublicKey) > 0 ' Check the key we read in Debug.Print "Their public key has " & ECC_QueryKey("", 0, strTheirPublicKey, "keyBits", 0) & " bits" ' Compute shared secret lpZZ = eccDHSharedSecret(strOurPrivateKey, strTheirPublicKey, 0) Debug.Assert cnvBytesLen(lpZZ) > 0 Debug.Print "ZZ=" & cnvHexStrFromBytes(lpZZ) ' Check the result Debug.Print "OK=" & strCorrectHex Debug.Assert UCase(cnvHexStrFromBytes(lpZZ)) = UCase(strCorrectHex)
Console.WriteLine("\nECDH SHARED SECRET USING X25519:"); // Ref: RFC7748 Section 6.1 // https://tools.ietf.org/html/rfc7748#section-6.1 /* Test vector: Alice's private key, a: 77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a Alice's public key, X25519(a, 9): 8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a Bob's private key, b: 5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb Bob's public key, X25519(b, 9): de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f Their shared secret, K: 4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742 */ Ecc.CurveName curve = Ecc.CurveName.X25519; string alicePrivateKeyHex = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"; string alicePublicKeyHex = "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"; string bobPrivateKeyHex = "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb"; string bobPublicKeyHex = "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f"; // Correct expected result string zzOK = "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"; // 1. Alice's private + Bob's public // NB we *must* specify whether X25519 keys are public or private string ourPrivateKey = Ecc.ReadKeyByCurve(alicePrivateKeyHex, curve, Ecc.KeyType.PrivateKey); Console.WriteLine("Curve = {0}", Ecc.QueryKey(ourPrivateKey, "curveName")); Console.WriteLine("Our private key has {0} bits", Ecc.QueryKey(ourPrivateKey, "keyBits")); string theirPublicKey = Ecc.ReadKeyByCurve(bobPublicKeyHex, curve, Ecc.KeyType.PublicKey); Console.WriteLine("Their public key has {0} bits", Ecc.QueryKey(theirPublicKey, "keyBits")); // Compute shared secret byte[] zz1 = Ecc.DHSharedSecret(ourPrivateKey, theirPublicKey); Console.WriteLine("ZZ={0}", Cnv.ToHex(zz1)); Debug.Assert(Cnv.ToHex(zz1).ToLower() == zzOK, "Ecc.DHSharedSecret failed"); // 2. Bob's private + Alice's public ourPrivateKey = Ecc.ReadKeyByCurve(bobPrivateKeyHex, curve, Ecc.KeyType.PrivateKey); theirPublicKey = Ecc.ReadKeyByCurve(alicePublicKeyHex, curve, Ecc.KeyType.PublicKey); // Compute shared secret byte[] zz2 = Ecc.DHSharedSecret(ourPrivateKey, theirPublicKey); Console.WriteLine("ZZ={0}", Cnv.ToHex(zz2)); Debug.Assert(Cnv.ToHex(zz2).ToLower() == zzOK, "Ecc.DHSharedSecret failed");
' Ref: RFC7748 Section 6.1 ' https://tools.ietf.org/html/rfc7748#section-6.1 ' ' Test vector: ' Alice's private key, a: ' 77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a ' Alice's public key, X25519(a, 9): ' 8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a ' Bob's private key, b: ' 5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb ' Bob's public key, X25519(b, 9): ' de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f ' Their shared secret, K: ' 4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742 ' NB uses functions in basCrPKIWrappers.bas, available in v20.0.1 Dim curveName As String Dim alicePrivateKeyHex As String Dim alicePublicKeyHex As String Dim bobPrivateKeyHex As String Dim bobPublicKeyHex As String Dim zzOK As String Dim ourPrivateKey As String Dim theirPublicKey As String Dim zz1() As Byte Dim zz2() As Byte curveName = "X25519" alicePrivateKeyHex = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a" alicePublicKeyHex = "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a" bobPrivateKeyHex = "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb" bobPublicKeyHex = "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f" ' Correct expected result zzOK = "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742" ' 1. Alice's private + Bob's public ' NB we *must* specify whether X25519 keys are public or private ourPrivateKey = eccReadKeyByCurve(alicePrivateKeyHex, curveName, PKI_ECC_PRIVATE_KEY) Debug.Assert Len(ourPrivateKey) > 0 Debug.Print "Our private key has " & ECC_QueryKey("", 0, ourPrivateKey, "keyBits", 0) & " bits" theirPublicKey = eccReadKeyByCurve(bobPublicKeyHex, curveName, PKI_ECC_PUBLIC_KEY) Debug.Assert Len(theirPublicKey) > 0 Debug.Print "Their public key has " & ECC_QueryKey("", 0, theirPublicKey, "keyBits", 0) & " bits" ' Compute shared secret zz1 = eccDHSharedSecret(ourPrivateKey, theirPublicKey, 0) Debug.Print "ZZ=" & cnvHexStrFromBytes(zz1) Debug.Assert StrComp(cnvHexStrFromBytes(zz1), zzOK, vbTextCompare) = 0
To contact us or comment on this page, please send us a message.
This page last updated 10 September 2025