mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-21 14:34:49 +01:00
Fuzz test for Ellswift ECDH
Co-authored-by: Pieter Wuille <bitcoin-dev@wuille.net>
This commit is contained in:
parent
c3ac9f5cf4
commit
2e5a8a437c
2 changed files with 69 additions and 0 deletions
10
src/pubkey.h
10
src/pubkey.h
|
@ -311,6 +311,16 @@ public:
|
|||
static constexpr size_t size() { return SIZE; }
|
||||
auto begin() const { return m_pubkey.cbegin(); }
|
||||
auto end() const { return m_pubkey.cend(); }
|
||||
|
||||
bool friend operator==(const EllSwiftPubKey& a, const EllSwiftPubKey& b)
|
||||
{
|
||||
return a.m_pubkey == b.m_pubkey;
|
||||
}
|
||||
|
||||
bool friend operator!=(const EllSwiftPubKey& a, const EllSwiftPubKey& b)
|
||||
{
|
||||
return a.m_pubkey != b.m_pubkey;
|
||||
}
|
||||
};
|
||||
|
||||
struct CExtPubKey {
|
||||
|
|
|
@ -22,8 +22,10 @@
|
|||
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <numeric>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -324,3 +326,60 @@ FUZZ_TARGET_INIT(ellswift_roundtrip, initialize_key)
|
|||
|
||||
assert(key.VerifyPubKey(decoded_pubkey));
|
||||
}
|
||||
|
||||
FUZZ_TARGET_INIT(bip324_ecdh, initialize_key)
|
||||
{
|
||||
FuzzedDataProvider fdp{buffer.data(), buffer.size()};
|
||||
|
||||
// We generate private key, k1.
|
||||
auto rnd32 = fdp.ConsumeBytes<uint8_t>(32);
|
||||
rnd32.resize(32);
|
||||
CKey k1;
|
||||
k1.Set(rnd32.begin(), rnd32.end(), true);
|
||||
if (!k1.IsValid()) return;
|
||||
|
||||
// They generate private key, k2.
|
||||
rnd32 = fdp.ConsumeBytes<uint8_t>(32);
|
||||
rnd32.resize(32);
|
||||
CKey k2;
|
||||
k2.Set(rnd32.begin(), rnd32.end(), true);
|
||||
if (!k2.IsValid()) return;
|
||||
|
||||
// We construct an ellswift encoding for our key, k1_ellswift.
|
||||
auto ent32_1 = fdp.ConsumeBytes<std::byte>(32);
|
||||
ent32_1.resize(32);
|
||||
auto k1_ellswift = k1.EllSwiftCreate(ent32_1);
|
||||
|
||||
// They construct an ellswift encoding for their key, k2_ellswift.
|
||||
auto ent32_2 = fdp.ConsumeBytes<std::byte>(32);
|
||||
ent32_2.resize(32);
|
||||
auto k2_ellswift = k2.EllSwiftCreate(ent32_2);
|
||||
|
||||
// They construct another (possibly distinct) ellswift encoding for their key, k2_ellswift_bad.
|
||||
auto ent32_2_bad = fdp.ConsumeBytes<std::byte>(32);
|
||||
ent32_2_bad.resize(32);
|
||||
auto k2_ellswift_bad = k2.EllSwiftCreate(ent32_2_bad);
|
||||
assert((ent32_2_bad == ent32_2) == (k2_ellswift_bad == k2_ellswift));
|
||||
|
||||
// Determine who is who.
|
||||
bool initiating = fdp.ConsumeBool();
|
||||
|
||||
// We compute our shared secret using our key and their public key.
|
||||
auto ecdh_secret_1 = k1.ComputeBIP324ECDHSecret(k2_ellswift, k1_ellswift, initiating);
|
||||
// They compute their shared secret using their key and our public key.
|
||||
auto ecdh_secret_2 = k2.ComputeBIP324ECDHSecret(k1_ellswift, k2_ellswift, !initiating);
|
||||
// Those must match, as everyone is behaving correctly.
|
||||
assert(ecdh_secret_1 == ecdh_secret_2);
|
||||
|
||||
if (k1_ellswift != k2_ellswift) {
|
||||
// Unless the two keys are exactly identical, acting as the wrong party breaks things.
|
||||
auto ecdh_secret_bad = k1.ComputeBIP324ECDHSecret(k2_ellswift, k1_ellswift, !initiating);
|
||||
assert(ecdh_secret_bad != ecdh_secret_1);
|
||||
}
|
||||
|
||||
if (k2_ellswift_bad != k2_ellswift) {
|
||||
// Unless both encodings created by them are identical, using the second one breaks things.
|
||||
auto ecdh_secret_bad = k1.ComputeBIP324ECDHSecret(k2_ellswift_bad, k1_ellswift, initiating);
|
||||
assert(ecdh_secret_bad != ecdh_secret_1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue