diff --git a/src/common/sv2_noise.cpp b/src/common/sv2_noise.cpp index 5a4905dc2122ce..532aa3cc14e0ec 100644 --- a/src/common/sv2_noise.cpp +++ b/src/common/sv2_noise.cpp @@ -140,7 +140,7 @@ void Sv2SymmetricState::MixHash(const Span input) m_hash_output = (HashWriter{} << m_hash_output << input).GetSHA256(); } -void Sv2SymmetricState::MixKey(const Span input_key_material) +void Sv2SymmetricState::MixKey(const Span input_key_material) { uint8_t out0[KEY_SIZE], out1[KEY_SIZE]; @@ -161,11 +161,11 @@ void Sv2SymmetricState::LogChainingKey() LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Chaining key: %s\n", GetChainingKey()); } -void Sv2SymmetricState::HKDF2(const Span input_key_material, uint8_t out0[KEY_SIZE], uint8_t out1[KEY_SIZE]) +void Sv2SymmetricState::HKDF2(const Span input_key_material, uint8_t out0[KEY_SIZE], uint8_t out1[KEY_SIZE]) { uint8_t tmp_key[KEY_SIZE]; CHMAC_SHA256 tmp_mac(m_chaining_key, KEY_SIZE); - tmp_mac.Write(input_key_material.begin(), input_key_material.size()); + tmp_mac.Write(UCharCast(input_key_material.data()), input_key_material.size()); tmp_mac.Finalize(tmp_key); CHMAC_SHA256 out0_mac(tmp_key, KEY_SIZE); @@ -204,7 +204,7 @@ std::array Sv2SymmetricState::Split() { uint8_t send_key[KEY_SIZE], recv_key[KEY_SIZE]; - std::vector empty; + std::vector empty; HKDF2(empty, send_key, recv_key); std::array result; @@ -219,28 +219,25 @@ uint256 Sv2SymmetricState::GetHashOutput() return m_hash_output; } -void Sv2HandshakeState::GenerateEphemeralKey(CKey& key) noexcept +void Sv2HandshakeState::GenerateEphemeralKey() noexcept { - Assume(!key.size()); - key.MakeNewKey(true); - Assume(XOnlyPubKey(key.GetPubKey()).IsFullyValid()); + Assume(!m_ephemeral_key.size()); + m_ephemeral_key.MakeNewKey(true); + m_our_ephemeral_ellswift_pk = m_ephemeral_key.EllSwiftCreate(MakeByteSpan(GetRandHash())); }; void Sv2HandshakeState::WriteMsgEphemeralPK(Span msg) { - if (msg.size() < KEY_SIZE) { - throw std::runtime_error(strprintf("Invalid message size: %d bytes < %d", msg.size(), KEY_SIZE)); + if (msg.size() < ELLSWIFT_KEY_SIZE) { + throw std::runtime_error(strprintf("Invalid message size: %d bytes < %d", msg.size(), ELLSWIFT_KEY_SIZE)); } - GenerateEphemeralKey(m_ephemeral_key); + GenerateEphemeralKey(); LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Write our ephemeral key\n"); + std::copy(m_our_ephemeral_ellswift_pk.begin(), m_our_ephemeral_ellswift_pk.end(), msg.begin()); - auto ephemeral_pk = XOnlyPubKey(m_ephemeral_key.GetPubKey()); - std::transform(ephemeral_pk.begin(), ephemeral_pk.end(), msg.begin(), - [](unsigned char b) { return static_cast(b); }); - - m_symmetric_state.MixHash(Span(msg.begin(), KEY_SIZE)); + m_symmetric_state.MixHash(Span(msg.begin(), ELLSWIFT_KEY_SIZE)); LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Mix hash: %s\n", HexStr(m_symmetric_state.GetHashOutput())); std::vector empty; @@ -248,14 +245,11 @@ void Sv2HandshakeState::WriteMsgEphemeralPK(Span msg) } void Sv2HandshakeState::ReadMsgEphemeralPK(Span msg) { - LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Write their ephemeral key\n"); - auto ucharSpan = UCharSpanCast(msg); - m_remote_ephemeral_key = XOnlyPubKey(Span(&ucharSpan[0], KEY_SIZE)); + LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Read their ephemeral key\n"); + Assume(msg.size() == ELLSWIFT_KEY_SIZE); + m_remote_ephemeral_ellswift_pk = EllSwiftPubKey(msg); - if (!m_remote_ephemeral_key.IsFullyValid()) { - throw std::runtime_error("Sv2HandshakeState::ReadMsgEphemeralPK(): Received invalid remote ephemeral key"); - } - m_symmetric_state.MixHash(Span(&msg[0], KEY_SIZE)); + m_symmetric_state.MixHash(Span(&msg[0], ELLSWIFT_KEY_SIZE)); LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Mix hash: %s\n", HexStr(m_symmetric_state.GetHashOutput())); std::vector empty; @@ -266,50 +260,43 @@ void Sv2HandshakeState::WriteMsgES(Span msg) { ssize_t bytes_written = 0; - Assume(m_remote_ephemeral_key.IsFullyValid()); - - GenerateEphemeralKey(m_ephemeral_key); + GenerateEphemeralKey(); // Send our ephemeral pk. LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Write our ephemeral key\n"); - auto ephemeral_pk = XOnlyPubKey(m_ephemeral_key.GetPubKey()); - Assume(ephemeral_pk.IsFullyValid()); - std::transform(ephemeral_pk.begin(), ephemeral_pk.end(), msg.begin(), - [](unsigned char b) { return static_cast(b); }); + std::copy(m_our_ephemeral_ellswift_pk.begin(), m_our_ephemeral_ellswift_pk.end(), msg.begin()); - m_symmetric_state.MixHash(Span(msg.begin(), KEY_SIZE)); - bytes_written += KEY_SIZE; + m_symmetric_state.MixHash(Span(msg.begin(), ELLSWIFT_KEY_SIZE)); + bytes_written += ELLSWIFT_KEY_SIZE; LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Mix hash: %s\n", HexStr(m_symmetric_state.GetHashOutput())); LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Perform ECDH with the remote ephemeral key\n"); - uint8_t ecdh_output[ECDH_OUTPUT_SIZE] = {}; - if (!m_ephemeral_key.ECDH(m_remote_ephemeral_key, ecdh_output)) { - throw std::runtime_error("Failed to perform ECDH on the remote ephemeral key using our ephemeral key"); - } + ECDHSecret ecdh_secret{m_ephemeral_key.ComputeBIP324ECDHSecret(m_remote_ephemeral_ellswift_pk, + m_our_ephemeral_ellswift_pk, + /*initiating=*/false)}; + LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Mix key with ECDH result: ephemeral ours -- remote ephemeral\n"); - m_symmetric_state.MixKey(Span(ecdh_output)); + m_symmetric_state.MixKey(ecdh_secret); m_symmetric_state.LogChainingKey(); // Send our static pk. LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Encrypt and write our static key\n"); - auto static_pk = XOnlyPubKey(m_static_key.GetPubKey()); - Assume(static_pk.IsFullyValid()); - std::transform(static_pk.begin(), static_pk.end(), msg.begin() + KEY_SIZE, - [](unsigned char b) { return static_cast(b); }); - m_symmetric_state.EncryptAndHash(Span(msg.begin() + KEY_SIZE, KEY_SIZE + POLY1305_TAGLEN)); - bytes_written += KEY_SIZE + POLY1305_TAGLEN; + std::copy(m_our_static_ellswift_pk.begin(), m_our_static_ellswift_pk.end(), msg.begin() + ELLSWIFT_KEY_SIZE); + + m_symmetric_state.EncryptAndHash(Span(msg.begin() + ELLSWIFT_KEY_SIZE, ELLSWIFT_KEY_SIZE + POLY1305_TAGLEN)); + bytes_written += ELLSWIFT_KEY_SIZE + POLY1305_TAGLEN; LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Mix hash: %s\n", HexStr(m_symmetric_state.GetHashOutput())); LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Perform ECDH between our static and remote ephemeral key\n"); - uint8_t ecdh_output_remote[ECDH_OUTPUT_SIZE]; - if (!m_static_key.ECDH(m_remote_ephemeral_key, ecdh_output_remote)) { - throw std::runtime_error("Failed to perform ECDH on the remote ephemeral key using our static key"); - } - LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "ECDH result: %s\n", HexStr(ecdh_output_remote)); + ECDHSecret ecdh_static_secret{m_static_key.ComputeBIP324ECDHSecret(m_remote_ephemeral_ellswift_pk, + m_our_static_ellswift_pk, + /*initiating=*/false)}; + LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "ECDH result: %s\n", HexStr(ecdh_static_secret)); + LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Mix key with ECDH result: static ours -- remote ephemeral\n"); - m_symmetric_state.MixKey(Span(ecdh_output_remote)); + m_symmetric_state.MixKey(ecdh_static_secret); m_symmetric_state.LogChainingKey(); // Serialize our digital signature noise message and encrypt. @@ -337,48 +324,41 @@ bool Sv2HandshakeState::ReadMsgES(Span msg) // Read the remote ephmeral key from the msg and decrypt. LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Read remote ephemeral key\n"); - auto remote_ephemeral_key_span = UCharSpanCast(Span(msg.begin(), KEY_SIZE)); - m_remote_ephemeral_key = XOnlyPubKey(remote_ephemeral_key_span); - if (!m_remote_ephemeral_key.IsFullyValid()) { - throw std::runtime_error("Sv2HandshakeState::ReadMsgES(): Received invalid remote ephemeral key"); - } - bytes_read += KEY_SIZE; + auto remote_ephemeral_key_span = Span(msg.begin(), ELLSWIFT_KEY_SIZE); + m_remote_ephemeral_ellswift_pk = EllSwiftPubKey(remote_ephemeral_key_span); + bytes_read += ELLSWIFT_KEY_SIZE; - m_symmetric_state.MixHash(Span(msg.begin(), KEY_SIZE)); + m_symmetric_state.MixHash(Span(msg.begin(), ELLSWIFT_KEY_SIZE)); LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Mix hash: %s\n", HexStr(m_symmetric_state.GetHashOutput())); LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Perform ECDH with the remote ephemeral key\n"); - uint8_t ecdh_output[ECDH_OUTPUT_SIZE]; - m_ephemeral_key.ECDH(m_remote_ephemeral_key, ecdh_output); + ECDHSecret ecdh_secret{m_ephemeral_key.ComputeBIP324ECDHSecret(m_remote_ephemeral_ellswift_pk, + m_our_ephemeral_ellswift_pk, + /*initiating=*/true)}; LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Mix key with ECDH result: ephemeral ours -- remote ephemeral\n"); - m_symmetric_state.MixKey(Span(ecdh_output)); + m_symmetric_state.MixKey(ecdh_secret); m_symmetric_state.LogChainingKey(); LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Decrypt remote static key\n"); - bool res = m_symmetric_state.DecryptAndHash(Span(msg.begin() + KEY_SIZE, KEY_SIZE + POLY1305_TAGLEN)); + bool res = m_symmetric_state.DecryptAndHash(Span(msg.begin() + ELLSWIFT_KEY_SIZE, ELLSWIFT_KEY_SIZE + POLY1305_TAGLEN)); if (!res) return false; - bytes_read += KEY_SIZE + POLY1305_TAGLEN; + bytes_read += ELLSWIFT_KEY_SIZE + POLY1305_TAGLEN; LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Mix hash: %s\n", HexStr(m_symmetric_state.GetHashOutput())); // Load remote static key from the decryted msg - auto remote_static_key_span = UCharSpanCast(Span(msg.begin() + KEY_SIZE, KEY_SIZE)); - m_remote_static_key = XOnlyPubKey(remote_static_key_span); - - LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Check if remote static key is valid\n"); - if (!m_remote_static_key.IsFullyValid()) { - throw std::runtime_error("Sv2HandshakeState::ReadMsgES(): Received invalid remote static key"); - } + auto remote_static_key_span = Span(msg.begin() + ELLSWIFT_KEY_SIZE, ELLSWIFT_KEY_SIZE); + m_remote_static_ellswift_pk = EllSwiftPubKey(remote_static_key_span); LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Perform ECDH on the remote static key\n"); - uint8_t ecdh_output_remote[ECDH_OUTPUT_SIZE]; - if (!m_ephemeral_key.ECDH(m_remote_static_key, ecdh_output_remote)) { - throw std::runtime_error("Failed to perform ECDH on the remote static key using our ephemeral key"); - } - LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "ECDH result: %s\n", HexStr(ecdh_output_remote)); + ECDHSecret ecdh_static_secret{m_ephemeral_key.ComputeBIP324ECDHSecret(m_remote_static_ellswift_pk, + m_our_ephemeral_ellswift_pk, + /*initiating=*/true)}; + LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "ECDH result: %s\n", HexStr(ecdh_static_secret)); + LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Mix key with ECDH result: ephemeral ours -- remote static\n"); - m_symmetric_state.MixKey(Span(ecdh_output_remote)); + m_symmetric_state.MixKey(ecdh_static_secret); m_symmetric_state.LogChainingKey(); @@ -392,7 +372,7 @@ bool Sv2HandshakeState::ReadMsgES(Span msg) DataStream ss_cert(cert_span); Sv2SignatureNoiseMessage cert; ss_cert >> cert; - cert.m_static_key = m_remote_static_key; + cert.m_static_key = XOnlyPubKey(m_remote_static_ellswift_pk.Decode()); Assume(m_authority_pubkey); if (!cert.Validate(m_authority_pubkey.value())) { LogPrintLevel(BCLog::SV2, BCLog::Level::Error, "Invalid certificate: %s\n", HexStr(cert_span)); diff --git a/src/common/sv2_noise.h b/src/common/sv2_noise.h index bb308e284a7639..e7247f496bff9e 100644 --- a/src/common/sv2_noise.h +++ b/src/common/sv2_noise.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -21,23 +22,24 @@ static constexpr size_t POLY1305_TAGLEN{16}; static constexpr size_t KEY_SIZE = 32; +static constexpr size_t ELLSWIFT_KEY_SIZE = 64; static constexpr size_t ECDH_OUTPUT_SIZE = 32; /** Section 3: All Noise messages are less than or equal to 65535 bytes in length. */ static constexpr size_t NOISE_MAX_CHUNK_SIZE = 65535; /** Sv2 spec 4.5.2 */ static constexpr size_t SIGNATURE_NOISE_MESSAGE_SIZE = 2 + 4 + 4 + 64; -static constexpr size_t INITIATOR_EXPECTED_HANDSHAKE_MESSAGE_LENGTH = KEY_SIZE + KEY_SIZE + +static constexpr size_t INITIATOR_EXPECTED_HANDSHAKE_MESSAGE_LENGTH = ELLSWIFT_KEY_SIZE + ELLSWIFT_KEY_SIZE + POLY1305_TAGLEN + SIGNATURE_NOISE_MESSAGE_SIZE + POLY1305_TAGLEN; -// Sha256 hash of the ascii encoding - "Noise_NX_secp256k1_ChaChaPoly_SHA256". +// Sha256 hash of the ascii encoding - "Noise_NX_EllSwiftXonly_ChaChaPoly_SHA256". // This is the first step required when setting up the chaining key. const std::vector PROTOCOL_NAME_HASH = { - 168, 246, 65, 106, 218, 197, 235, 205, 62, 183, 118, 131, 234, 247, 6, 174, 180, 164, 162, 125, - 30, 121, 156, 182, 95, 117, 218, 138, 122, 135, 4, 65, -}; + 27, 97, 156, 90, 248, 120, 254, 68, 34, 119, 45, 129, 209, 41, 152, 82, + 26,137, 97, 115, 62, 44, 177, 60, 145, 24, 250, 214, 68, 188, 1, 128}; -// The double hash of protocol name "Noise_NX_secp256k1_ChaChaPoly_SHA256". -static std::vector PROTOCOL_NAME_DOUBLE_HASH = {132, 175, 109, 74, 47, 106, 167, 237, 124, 169, 128, 188, 123, 69, 19, 92, 215, 4, 100, 205, 0, 191, 211, 210, 38, 190, 247, 183, 20, 200, 116, 58}; +// The double hash of protocol name "Noise_NX_EllSwiftXonly_ChaChaPoly_SHA256". +static std::vector PROTOCOL_NAME_DOUBLE_HASH = {60, 102, 112, 143, 69, 248, 185, 34, 53, 193, 3, 46, 250, 104, 70, 171, + 139, 103, 55, 191, 199, 9, 77, 179, 99, 170, 7, 240, 219, 36, 226, 71}; /** Simple certificate for the static key signed by the authority key. * See 4.5.2 and 4.5.3 of the Stratum v2 spec. @@ -57,6 +59,7 @@ class Sv2SignatureNoiseMessage Sv2SignatureNoiseMessage() = default; Sv2SignatureNoiseMessage(uint16_t version, uint32_t valid_from, uint32_t valid_to, const XOnlyPubKey& static_key, const CKey& authority_key); + /* The certificate serializes pubkeys in x-only format, not EllSwift. */ XOnlyPubKey m_static_key = {}; [[ nodiscard ]] bool Validate(XOnlyPubKey authority_key); @@ -141,7 +144,7 @@ class Sv2SymmetricState } void MixHash(const Span input); - void MixKey(const Span input_key_material); + void MixKey(const Span input_key_material); void EncryptAndHash(Span data); [[ nodiscard ]] bool DecryptAndHash(Span data); std::array Split(); @@ -157,7 +160,7 @@ class Sv2SymmetricState uint256 m_hash_output = uint256(PROTOCOL_NAME_DOUBLE_HASH); Sv2CipherState m_cipher_state; - void HKDF2(const Span input_key_material, uint8_t out0[KEY_SIZE], uint8_t out1[KEY_SIZE]); + void HKDF2(const Span input_key_material, uint8_t out0[KEY_SIZE], uint8_t out1[KEY_SIZE]); }; /* @@ -179,7 +182,9 @@ class Sv2HandshakeState Sv2HandshakeState(CKey&& static_key, XOnlyPubKey&& authority_pubkey): m_static_key{static_key}, - m_authority_pubkey{authority_pubkey} {}; + m_authority_pubkey{authority_pubkey} { + m_our_static_ellswift_pk = static_key.EllSwiftCreate(MakeByteSpan(GetRandHash())); + }; /* * If we are the responder, the certificate must be set @@ -187,7 +192,9 @@ class Sv2HandshakeState Sv2HandshakeState(CKey&& static_key, Sv2SignatureNoiseMessage&& certificate): m_static_key{static_key}, - m_certificate{certificate} {}; + m_certificate{certificate} { + m_our_static_ellswift_pk = static_key.EllSwiftCreate(MakeByteSpan(GetRandHash())); + }; /** Handshake step 1 for initiator: -> e */ void WriteMsgEphemeralPK(Span msg); @@ -209,19 +216,24 @@ class Sv2HandshakeState private: /** Our static key (s) */ CKey m_static_key; + /** EllSwift encoded static key, for optimized ECDH */ + EllSwiftPubKey m_our_static_ellswift_pk; /** Our ephemeral key (e) */ CKey m_ephemeral_key; + /** EllSwift encoded ephemeral key, for optimized ECDH */ + EllSwiftPubKey m_our_ephemeral_ellswift_pk; /** Remote static key (rs) */ - XOnlyPubKey m_remote_static_key; + EllSwiftPubKey m_remote_static_ellswift_pk; /** Remote ephemeral key (re) */ - XOnlyPubKey m_remote_ephemeral_key; + EllSwiftPubKey m_remote_ephemeral_ellswift_pk; Sv2SymmetricState m_symmetric_state; /** Certificate signed by m_authority_pubkey. */ std::optional m_certificate; /** Authority public key. */ std::optional m_authority_pubkey; - void GenerateEphemeralKey(CKey& key) noexcept; + /** Generate ephemeral key, sets set m_ephemeral_key and m_our_ephemeral_ellswift_pk */ + void GenerateEphemeralKey() noexcept; }; /** diff --git a/src/common/sv2_transport.cpp b/src/common/sv2_transport.cpp index b6809fdfaa2d10..97c5b628318d0b 100644 --- a/src/common/sv2_transport.cpp +++ b/src/common/sv2_transport.cpp @@ -90,7 +90,7 @@ void Sv2Transport::StartSendingHandshake() noexcept Assume(m_send_state == SendState::HANDSHAKE_STEP_1); Assume(m_send_buffer.empty()); - m_send_buffer.resize(KEY_SIZE); + m_send_buffer.resize(ELLSWIFT_KEY_SIZE); m_cipher.GetHandshakeState().WriteMsgEphemeralPK(MakeWritableByteSpan(m_send_buffer)); m_send_state = SendState::HANDSHAKE_STEP_2; @@ -231,7 +231,7 @@ bool Sv2Transport::ReceivedBytes(Span& msg_bytes) noexcept if (m_recv_buffer.size() + std::min(msg_bytes.size(), max_read) > m_recv_buffer.capacity()) { switch (m_recv_state) { case RecvState::HANDSHAKE_STEP_1: - m_recv_buffer.reserve(KEY_SIZE); + m_recv_buffer.reserve(ELLSWIFT_KEY_SIZE); break; case RecvState::HANDSHAKE_STEP_2: m_recv_buffer.reserve(INITIATOR_EXPECTED_HANDSHAKE_MESSAGE_LENGTH); @@ -290,9 +290,9 @@ bool Sv2Transport::ProcessReceivedEphemeralKeyBytes() noexcept AssertLockHeld(m_recv_mutex); AssertLockNotHeld(m_send_mutex); Assume(m_recv_state == RecvState::HANDSHAKE_STEP_1); - Assume(m_recv_buffer.size() <= KEY_SIZE); + Assume(m_recv_buffer.size() <= ELLSWIFT_KEY_SIZE); - if (m_recv_buffer.size() == KEY_SIZE) { + if (m_recv_buffer.size() == ELLSWIFT_KEY_SIZE) { // Other side's key has been fully received, and can now be Diffie-Hellman // combined with our key. This is act 1 of the Noise Protocol handshake. // TODO handle failure @@ -344,8 +344,8 @@ size_t Sv2Transport::GetMaxBytesToProcess() noexcept switch (m_recv_state) { case RecvState::HANDSHAKE_STEP_1: // In this state, we only allow the 32-byte key into the receive buffer. - Assume(m_recv_buffer.size() <= KEY_SIZE); - return KEY_SIZE - m_recv_buffer.size(); + Assume(m_recv_buffer.size() <= ELLSWIFT_KEY_SIZE); + return ELLSWIFT_KEY_SIZE - m_recv_buffer.size(); case RecvState::HANDSHAKE_STEP_2: // In this state, we only allow the handshake reply into the receive buffer. Assume(m_recv_buffer.size() <= INITIATOR_EXPECTED_HANDSHAKE_MESSAGE_LENGTH); diff --git a/src/pubkey.h b/src/pubkey.h index 2b655c3f73b572..5b0ca53bfa2370 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -313,7 +313,7 @@ struct EllSwiftPubKey /** Construct a new ellswift public key from a given serialization. */ EllSwiftPubKey(Span ellswift) noexcept; - /** Decode to normal compressed CPubKey (for debugging purposes). */ + /** Decode to normal compressed CPubKey. */ CPubKey Decode() const; // Read-only access for serialization. diff --git a/src/test/sv2_noise_tests.cpp b/src/test/sv2_noise_tests.cpp index 41b1eddd467246..ad612c4dd85536 100644 --- a/src/test/sv2_noise_tests.cpp +++ b/src/test/sv2_noise_tests.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -13,33 +14,19 @@ BOOST_AUTO_TEST_CASE(MixKey_test) Sv2SymmetricState r_ss; BOOST_CHECK_EQUAL(r_ss.GetChainingKey(), i_ss.GetChainingKey()); - CKey initiator_key; - initiator_key.MakeNewKey(true); - while (!initiator_key.HasEvenY()) { - initiator_key.MakeNewKey(true); - } - BOOST_CHECK(initiator_key.HasEvenY()); - auto initiator_pk = XOnlyPubKey(initiator_key.GetPubKey()); + CKey initiator_key{GenerateRandomKey()}; + auto initiator_pk = initiator_key.EllSwiftCreate(MakeByteSpan(GetRandHash())); - CKey responder_key; - responder_key.MakeNewKey(true); - while (!responder_key.HasEvenY()) { - responder_key.MakeNewKey(true); - } - BOOST_CHECK(responder_key.HasEvenY()); - auto responder_pk = XOnlyPubKey(responder_key.GetPubKey()); + CKey responder_key{GenerateRandomKey()}; + auto responder_pk = responder_key.EllSwiftCreate(MakeByteSpan(GetRandHash())); - unsigned char ecdh_output_1[32]; - initiator_key.ECDH(responder_pk, ecdh_output_1); - - - unsigned char ecdh_output_2[32]; - responder_key.ECDH(initiator_pk, ecdh_output_2); + auto ecdh_output_1 = initiator_key.ComputeBIP324ECDHSecret(responder_pk, initiator_pk, true); + auto ecdh_output_2 = responder_key.ComputeBIP324ECDHSecret(initiator_pk, responder_pk, false); BOOST_CHECK(std::memcmp(&ecdh_output_1[0], &ecdh_output_2[0], 32) == 0); - i_ss.MixKey(Span(ecdh_output_1)); - r_ss.MixKey(Span(ecdh_output_2)); + i_ss.MixKey(ecdh_output_1); + r_ss.MixKey(ecdh_output_2); BOOST_CHECK_EQUAL(r_ss.GetChainingKey(), i_ss.GetChainingKey()); } @@ -133,12 +120,11 @@ BOOST_AUTO_TEST_CASE(handshake_and_transport_test) // Handshake Act 1: e -> std::vector transport_buffer; - transport_buffer.resize(KEY_SIZE); + transport_buffer.resize(ELLSWIFT_KEY_SIZE); Span transport_span{MakeWritableByteSpan(transport_buffer)}; // Alice generates her ephemeral public key and write it into the buffer: alice_handshake->WriteMsgEphemeralPK(transport_span); - XOnlyPubKey alice_pubkey(Span(&transport_buffer[0], XOnlyPubKey::size())); - BOOST_CHECK(alice_pubkey.IsFullyValid()); + EllSwiftPubKey alice_pubkey(transport_span); // Bob reads the ephemeral key bob_handshake->ReadMsgEphemeralPK(transport_span); diff --git a/src/test/sv2_transport_tests.cpp b/src/test/sv2_transport_tests.cpp index 46c73d833b6fd4..0370d87f875018 100644 --- a/src/test/sv2_transport_tests.cpp +++ b/src/test/sv2_transport_tests.cpp @@ -183,12 +183,12 @@ class Sv2TransportTester */ void ProcessHandshake1() { if (m_test_initiator) { - BOOST_REQUIRE(m_received.size() == KEY_SIZE); + BOOST_REQUIRE(m_received.size() == ELLSWIFT_KEY_SIZE); m_peer_cipher->GetHandshakeState().ReadMsgEphemeralPK(MakeWritableByteSpan(m_received)); m_received.clear(); } else { BOOST_REQUIRE(m_to_send.empty()); - m_to_send.resize(KEY_SIZE); + m_to_send.resize(ELLSWIFT_KEY_SIZE); m_peer_cipher->GetHandshakeState().WriteMsgEphemeralPK(MakeWritableByteSpan(m_to_send)); }