20inline constexpr std::size_t
kSha1Size = 20;
26using Sha256Digest = std::array<std::uint8_t, kSha256Size>;
29template <std::
size_t N>
35 explicit FixedHexString(std::span<const std::uint8_t, N> bytes)
noexcept {
36 static constexpr char kDigits[] =
"0123456789abcdef";
37 for (std::size_t i = 0; i < N; ++i) {
38 data_[2 * i] = kDigits[bytes[i] >> 4];
39 data_[2 * i + 1] = kDigits[bytes[i] & 0x0F];
44 std::string_view
view() const noexcept {
return {data_.data(),
kCapacity}; }
45 const char*
c_str() const noexcept {
return data_.data(); }
47 operator std::string_view() const noexcept {
52 std::array<char, kCapacity + 1> data_{};
55using HexSha256 = FixedHexString<kSha256Size>;
56using HexSha384 = FixedHexString<kSha384Size>;
62 std::string_view data,
63 std::span<std::uint8_t, kSha256Size> out)
noexcept;
81 void sign(std::string_view data, std::span<std::uint8_t, kSha256Size> out)
const noexcept;
85 static constexpr std::size_t
kCtxBytes = 128;
88 alignas(16) std::array<std::uint8_t, kCtxBytes> inner_{};
89 alignas(16) std::array<std::uint8_t, kCtxBytes> outer_{};
92bool sha1(std::string_view data, std::span<std::uint8_t, kSha1Size> out)
noexcept;
93bool sha256(std::string_view data, std::span<std::uint8_t, kSha256Size> out)
noexcept;
100 return ((n + 2) / 3) * 4;
103 return (n / 4) * 3 + 2;
108std::size_t
base64_encode(std::span<const std::uint8_t> in, std::span<char> out)
noexcept;
115 return (n * 4 + 2) / 3;
117std::size_t
base64url_encode(std::span<const std::uint8_t> in, std::span<char> out)
noexcept;
124std::size_t
base64_decode(std::string_view in, std::span<std::uint8_t> out)
noexcept;
153 [[nodiscard]]
bool valid() const noexcept {
return pkey_ !=
nullptr; }
154 [[nodiscard]]
bool has_private() const noexcept {
return pkey_ !=
nullptr && private_; }
157 bool sign(std::string_view data,
158 std::span<std::uint8_t, kEd25519SignatureSize> out)
const noexcept;
160 std::size_t
sign_base64(std::string_view data, std::span<char> out)
const noexcept;
161 [[nodiscard]] std::string
sign_base64(std::string_view data)
const;
162 [[nodiscard]]
bool verify(std::string_view data,
163 std::span<const std::uint8_t> signature)
const noexcept;
166 std::string_view signature)
const noexcept;
171 void* pkey_ =
nullptr;
172 bool private_ =
false;
197 [[nodiscard]]
bool valid() const noexcept {
return pkey_ !=
nullptr; }
198 [[nodiscard]]
bool has_private() const noexcept {
return pkey_ !=
nullptr && private_; }
201 bool sign(std::string_view data, std::span<std::uint8_t, kEs256SignatureSize> out)
const noexcept;
202 [[nodiscard]]
bool verify(std::string_view data,
203 std::span<const std::uint8_t> signature)
const noexcept;
208 void* pkey_ =
nullptr;
209 bool private_ =
false;
Definition crypto.hpp:183
std::string public_pem() const
"\--\---BEGIN PUBLIC KEY\--\---" PEM of the key (empty when invalid).
static EcdsaP256Key from_private_pem(std::string_view pem)
SEC 1 "EC PRIVATE KEY" or PKCS#8 "PRIVATE KEY" PEM. Not valid() unless it is a P-256 key.
bool verify(std::string_view data, std::span< const std::uint8_t > signature) const noexcept
EcdsaP256Key & operator=(EcdsaP256Key &&o) noexcept
bool has_private() const noexcept
Definition crypto.hpp:200
EcdsaP256Key() noexcept=default
bool sign(std::string_view data, std::span< std::uint8_t, kEs256SignatureSize > out) const noexcept
r || s of SHA-256(data); false without a private key.
static EcdsaP256Key from_public_pem(std::string_view pem)
SubjectPublicKeyInfo "PUBLIC KEY" PEM.
bool valid() const noexcept
Definition crypto.hpp:199
A parsed Ed25519 key (private, or public only for verification). Move-only.
Definition crypto.hpp:141
Ed25519Key() noexcept=default
std::string public_pem() const
"\--\---BEGIN PUBLIC KEY\--\---" PEM of the key (empty when invalid).
static Ed25519Key from_private_pem(std::string_view pem)
PKCS#8 "PRIVATE KEY" PEM. Not valid() if the PEM is not an Ed25519 private key.
bool verify_base64(std::string_view data, std::string_view signature) const noexcept
Verifies a base64 signature (Binance's signature parameter).
bool sign(std::string_view data, std::span< std::uint8_t, kEd25519SignatureSize > out) const noexcept
Writes the 64-byte signature; false without a private key.
static Ed25519Key from_public_pem(std::string_view pem)
SubjectPublicKeyInfo "PUBLIC KEY" PEM (what Binance asks for when registering the key).
bool valid() const noexcept
Definition crypto.hpp:155
bool has_private() const noexcept
Definition crypto.hpp:156
bool verify(std::string_view data, std::span< const std::uint8_t > signature) const noexcept
std::size_t sign_base64(std::string_view data, std::span< char > out) const noexcept
Base64 signature into out (>= kEd25519Base64Size); returns bytes written, 0 on failure.
Ed25519Key(Ed25519Key &&o) noexcept
Definition crypto.hpp:145
Ed25519Key & operator=(Ed25519Key &&o) noexcept
Fixed-capacity, NUL-terminated hex string (no heap). size() excludes the terminator.
Definition crypto.hpp:32
std::string_view view() const noexcept
Definition crypto.hpp:46
static constexpr std::size_t kCapacity
Definition crypto.hpp:34
constexpr std::size_t size() const noexcept
Definition crypto.hpp:48
const char * c_str() const noexcept
Definition crypto.hpp:47
constexpr FixedHexString() noexcept
Definition crypto.hpp:36
HMAC-SHA256 with the key schedule precomputed (see the header comment).
Definition crypto.hpp:78
HmacSha256Key() noexcept
Definition crypto.hpp:80
void sign(std::string_view data, std::span< std::uint8_t, kSha256Size > out) const noexcept
HexSha256 sign_hex(std::string_view data) const noexcept
static constexpr std::size_t kCtxBytes
Opaque storage for one OpenSSL SHA256_CTX (112 bytes; checked in crypto.cpp).
Definition crypto.hpp:87
Definition reactor.hpp:37
bool random_bytes(std::span< std::uint8_t > out) noexcept
CSPRNG (RAND_bytes). Returns false if the RNG is unavailable.
bool sha1(std::string_view data, std::span< std::uint8_t, kSha1Size > out) noexcept
bool sha256(std::string_view data, std::span< std::uint8_t, kSha256Size > out) noexcept
constexpr std::size_t kSha256Size
Definition crypto.hpp:23
constexpr std::size_t kEd25519Base64Size
base64_encoded_size(64)
Definition crypto.hpp:138
constexpr std::size_t kSha1Size
Definition crypto.hpp:22
constexpr std::size_t base64_max_decoded_size(std::size_t n) noexcept
Definition crypto.hpp:104
HexSha512 sha512_hex(std::string_view data) noexcept
std::array< std::uint8_t, kSha1Size > Sha1Digest
Definition crypto.hpp:27
constexpr std::size_t kSha512Size
Definition crypto.hpp:25
constexpr std::size_t base64_encoded_size(std::size_t n) noexcept
RFC 4648 §4 base64 with '=' padding. base64_encoded_size(n) is the exact output size.
Definition crypto.hpp:101
std::size_t base64url_decode(std::string_view in, std::span< std::uint8_t > out) noexcept
Unpadded base64url; SIZE_MAX on malformed input or insufficient output space.
constexpr std::size_t base64url_encoded_size(std::size_t n) noexcept
RFC 4648 §5 base64url without padding, the encoding of JWS/JWT segments.
Definition crypto.hpp:116
constexpr std::size_t kEs256SignatureSize
ECDSA on P-256 with SHA-256 (JWS "ES256", RFC 7518 §3.4): the signature is r || s,...
Definition crypto.hpp:181
constexpr std::size_t kEd25519SignatureSize
Definition crypto.hpp:137
std::string ed25519_sign_base64(std::string_view private_key_pem, std::string_view data)
Ed25519 signature (base64) of data using a PEM-encoded PKCS#8 private key.
bool hmac_sha256(std::string_view key, std::string_view data, std::span< std::uint8_t, kSha256Size > out) noexcept
HMAC-SHA256(key, data).
std::size_t base64_encode(std::span< const std::uint8_t > in, std::span< char > out) noexcept
Writes into out (must be >= base64_encoded_size(in.size())); returns bytes written or 0 if the output...
HexSha512 hmac_sha512_hex(std::string_view key, std::string_view data) noexcept
HMAC-SHA512(key, data) as lowercase hex (Gate APIv4 signs REST requests and WebSocket logins with it)...
std::size_t base64url_encode(std::span< const std::uint8_t > in, std::span< char > out) noexcept
FixedHexString< kSha256Size > HexSha256
Definition crypto.hpp:57
std::size_t base64_decode(std::string_view in, std::span< std::uint8_t > out) noexcept
Decodes standard base64 (padding required, no whitespace).
HexSha256 hmac_sha256_hex(std::string_view key, std::string_view data) noexcept
constexpr std::size_t kSha384Size
Definition crypto.hpp:24
std::array< std::uint8_t, kSha256Size > Sha256Digest
Definition crypto.hpp:28
HexSha384 hmac_sha384_hex(std::string_view key, std::string_view data) noexcept
HMAC-SHA384(key, data) as lowercase hex (Gemini signs its requests and the WebSocket upgrade with it)...
FixedHexString< kSha384Size > HexSha384
Definition crypto.hpp:58