From 5ce650382352c1503f40abf08129ada69402af55 Mon Sep 17 00:00:00 2001 From: bitflash-coin Date: Tue, 4 Aug 2026 06:34:32 -0700 Subject: public commit --- src/btfaddr.h | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/btfaddr.h (limited to 'src/btfaddr.h') diff --git a/src/btfaddr.h b/src/btfaddr.h new file mode 100644 index 0000000..1addf8f --- /dev/null +++ b/src/btfaddr.h @@ -0,0 +1,72 @@ +// Copyright (c) 2026 Bitflash developers +// Distributed under the MIT/X11 software license. +// +// Bitflash hidden services -- self-certifying `.btf` addresses (a Tor `.onion` +// analogue, ported from the Itzal design). An address IS the service's public +// key: base32(pubkey[32] || checksum[2]).btf, derived from the owner's +// secp256k1 x-only key, so it cannot be forged (no CA, no DNS). Resolving it +// means proving a descriptor is signed by exactly this key. +// +// This is the ADDRESS + DESCRIPTOR layer. Reachability (rendezvous over the +// embedded Nostr relays so the origin IP is never exposed) builds on top. + +#ifndef BITFLASH_BTFADDR_H +#define BITFLASH_BTFADDR_H + +#include +#include +#include + +namespace btf +{ + +// Pseudo-TLD, resolved inside the Bitflash client, never by real DNS. +extern const char* TLD; // ".btf" + +// RFC 4648 base32, lowercase, no padding (case-insensitive hostname label). +std::string Base32Encode(const unsigned char* data, size_t n); +bool Base32Decode(const std::string& s, std::vector& out); + +// Derive the `.btf` address for a 32-byte x-only public key. +std::string Address(const unsigned char pubkey[32]); + +// True if a hostname is a `.btf` address (case-insensitive, optional trailing dot). +bool IsBtf(const std::string& host); + +// Parse a `.btf` address back to its 32-byte public key, verifying the checksum. +// Returns false if the label isn't valid base32, is too short, or checksum fails. +bool ParseAddress(const std::string& addr, unsigned char pubkeyOut[32]); + + +// ---- Service descriptor (published later on Nostr) ------------------------- +// +// A descriptor tells a client how to REACH a service after resolving its +// address: "service is reachable via , encrypt end-to-end +// to my x25519 key ". It is signed by the service key and self-certifying: +// the client requires the signature to verify under the exact pubkey the +// address decodes to, so nobody can publish a descriptor for an address they +// don't own (no hijacking, even via a malicious relay). + +struct Descriptor +{ + unsigned char pubkey[32]; + std::string enc; // service x25519 public key (hex) for the E2E channel + std::string meeting_node; // rendezvous node the service is registered at + uint64_t created; +}; + +// Sign a descriptor. `ctx` is a secp256k1_context* (passed as void* to keep this +// header free of secp headers); `seckey` is the 32-byte service secret key. +// Returns the descriptor JSON as a string, or "" on failure. +std::string SignDescriptor(void* ctx, const unsigned char seckey[32], + const std::string& enc, const std::string& meeting_node, + uint64_t created); + +// Verify a descriptor is validly signed by `expect_pubkey` (the key the resolved +// `.btf` address encodes). Returns true and fills `out` on success. +bool VerifyDescriptor(void* ctx, const std::string& jsonStr, + const unsigned char expect_pubkey[32], Descriptor& out); + +} // namespace btf + +#endif -- cgit v1.2.3