Generated reference › API — ICoreEssentials/Crypto
kind: generated#api#icoreessentials-crypto

API — ICoreEssentials/Crypto

The public contract of 8 header(s) under ICoreEssentials/Crypto — 8 class/struct definition(s), 45 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.

ICoreBase64.h#

ICoreEssentials/Crypto/ICoreBase64.h

ICoreBase64#

ICoreBase64.h:42 · class · 4 declaration(s)

ICoreBase64 -- RFC 4648 base64, both alphabets, decoded STRICTLY.

class ICoreBase64 {
public:
    // base64url, RFC 4648 §5 -- the JWT alphabet. Padding is optional on input
    // in the sense that its ABSENCE is normal; an actual '=' is rejected.
    static std::optional<ICoreByteArray> decodeUrl(std::string_view text);

    // Standard base64, RFC 4648 §4. Padding is required when the length calls
    // for it, because a standard-alphabet producer always writes it.
    static std::optional<ICoreByteArray> decode(std::string_view text);

    // Unpadded base64url. Round-trips through decodeUrl() for every input.
    static std::string encodeUrl(const ICoreByteArray& bytes);

    // Padded standard base64. Round-trips through decode().
    static std::string encode(const ICoreByteArray& bytes);

};

ICoreChecksum.h#

ICoreEssentials/Crypto/ICoreChecksum.h

ICoreChecksum -- CRC-32 and Adler-32.

Fast checksums that catch accidental corruption: a truncated download, a flipped bit on disk, a mangled record. They are NOT security -- anyone can forge a matching checksum on purpose. Use ICoreHash or ICoreHmac for that.

crc32() is the IEEE 802.3 CRC (reflected polynomial 0xEDB88320) that zlib, gzip, PNG and ZIP all use, so its values match theirs byte for byte: crc32("123456789") == 0xCBF43926. adler32() is zlib's Adler-32: adler32("Wikipedia") == 0x11E60398.

Both run incrementally in zlib's style: pass the previous result back in to continue over the next chunk. Start from the one-argument form (or from crc32Initial / adler32Initial):

ICoreChecksum#

ICoreChecksum.h:30 · class · 7 declaration(s)

Opened by row PS5.7 of the Platform SDK product plan.

class ICoreChecksum {
public:
    ICoreChecksum() = delete;

    static constexpr std::uint32_t crc32Initial   = 0;
    static constexpr std::uint32_t adler32Initial = 1;

    [[nodiscard]] static std::uint32_t crc32(const ICoreByteArray& data);
    [[nodiscard]] static std::uint32_t crc32(std::uint32_t previous, const ICoreByteArray& data);
    [[nodiscard]] static std::uint32_t crc32(std::uint32_t previous, const void* data, std::size_t size);

    [[nodiscard]] static std::uint32_t adler32(const ICoreByteArray& data);
    [[nodiscard]] static std::uint32_t adler32(std::uint32_t previous, const ICoreByteArray& data);
    [[nodiscard]] static std::uint32_t adler32(std::uint32_t previous, const void* data, std::size_t size);
};
};

ICoreHash.h#

ICoreEssentials/Crypto/ICoreHash.h

ICoreHash -- a content digest.

QT-FREE (phase 3). SHA-1 is implemented here, in 60 lines against RFC 3174, SHA-256 in about as many against FIPS 180-4, and <QCryptographicHash> is gone from this header and from the umbrella. The two share everything a Merkle-Damgard hash shares -- the 64-byte block, the 0x80 pad, the big-endian 64-bit bit length -- so the second algorithm cost a compression function and a constant table, not a second wrapper.

B2 is why this row was small. It narrowed the wrapper to ONE algorithm out of QCryptographicHash's fourteen and to a raw (pointer, length) addData, so phase 3 owed one hash function rather than a crypto library -- exactly the bargain ICoreStandardPaths struck when its narrowing turned a known-folders implementation into a PATH walk.

ICoreHash#

ICoreHash.h:98 · class · pImpl · 12 declaration(s)

class ICoreHash {
public:
    // Sha1 names saved images and Sha256 verifies a downloaded release; see the
    // header note -- no digest may change once it is shipped. Sha512 joined for
    // the platform SDK (PS5.3). The values are pinned because an enumerator is
    // compiled into a consumer as a number: append, never renumber.
    enum class Algorithm {
        Sha1   = 0,
        Sha256 = 1,
        Sha512 = 2
    };

    explicit ICoreHash(Algorithm algorithm);
    ~ICoreHash();

    // Copyable, as it always was -- a half-fed hash is a value, and copying one
    // to fork two different endings off it is meaningful. Written out because a
    // unique_ptr<Impl> member deletes the implicit copy.
    ICoreHash(const ICoreHash& other);
    ICoreHash& operator=(const ICoreHash& other);

    void addData(const void* data, std::size_t size);
    void addData(const ICoreByteArray& data);

    // const, and therefore NON-DESTRUCTIVE: the padding is applied to a copy of
    // the state, so asking twice gives the same answer and addData may continue
    // afterwards. QCryptographicHash::result() behaves the same way, and the
    // call site relies on it only to the extent that it asks once.
    [[nodiscard]] ICoreString resultHex() const;

    // The same digest as raw bytes (20, 32 or 64 of them), with the same
    // non-destructive semantics as resultHex().
    [[nodiscard]] ICoreByteArray result() const;

    [[nodiscard]] Algorithm algorithm() const noexcept;

    // One-shot: the digest of `data`.
    [[nodiscard]] static ICoreByteArray hash(Algorithm algorithm, const ICoreByteArray& data);

    // The digest length and the internal block length in bytes -- 20/64,
    // 32/64 and 64/128. HMAC needs the second.
    [[nodiscard]] static std::size_t digestBytes(Algorithm algorithm) noexcept;
    [[nodiscard]] static std::size_t blockBytes(Algorithm algorithm) noexcept;

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};

ICoreHmac.h#

ICoreEssentials/Crypto/ICoreHmac.h

ICoreHmac -- keyed message authentication (HMAC, RFC 2104).

An HMAC tag proves a message was produced by someone holding the key and was not altered since. It is what signs webhook payloads, API requests and session cookies. Any ICoreHash algorithm can drive it; use Sha256 or Sha512 for anything new.

ICoreByteArray tag = ICoreHmac::mac(ICoreHash::Algorithm::Sha256, key, body); bool genuine = ICoreHmac::verify(ICoreHash::Algorithm::Sha256, key, body, tag);

Always check a received tag with verify(), never with ==: verify() compares in constant time, so the time it takes says nothing about how many leading bytes matched. constantTimeEquals() is the same comparison for other secrets.

ICoreHmac#

ICoreHmac.h:32 · class · pImpl · 8 declaration(s)

Opened by row PS5.4 of the Platform SDK product plan.

class ICoreHmac {
public:
    ICoreHmac(ICoreHash::Algorithm algorithm, const ICoreByteArray& key);
    ~ICoreHmac();

    ICoreHmac(const ICoreHmac& other);
    ICoreHmac& operator=(const ICoreHmac& other);

    void addData(const void* data, std::size_t size);
    void addData(const ICoreByteArray& data);

    // The tag, ICoreHash::digestBytes(algorithm) long.
    [[nodiscard]] ICoreByteArray result() const;

    [[nodiscard]] static ICoreByteArray mac(ICoreHash::Algorithm algorithm,
                                            const ICoreByteArray& key,
                                            const ICoreByteArray& message);

    [[nodiscard]] static bool verify(ICoreHash::Algorithm algorithm,
                                     const ICoreByteArray& key,
                                     const ICoreByteArray& message,
                                     const ICoreByteArray& tag);

    // True when both arrays hold the same bytes. Takes time that depends only
    // on the lengths, never on where the first difference is.
    [[nodiscard]] static bool constantTimeEquals(const ICoreByteArray& a, const ICoreByteArray& b);

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};

ICorePasswordHash.h#

ICoreEssentials/Crypto/ICorePasswordHash.h

ICorePasswordHash -- storing passwords, and turning a password into a key.

hash() returns a self-describing string in the standard PHC format ("$argon2id$v=19$m=...,t=...,p=1$<salt>$<hash>"). It carries its own random salt and cost parameters, so it is the ONLY thing to store; verify() reads them back out. Never store a password, and never store a plain SHA digest of one -- a GPU tries billions of those a second.

The function is Argon2id, from the SDK's vendored libsodium. Each Strength is a (time, memory) cost pair:

Interactive ~64 MiB, a fraction of a second -- logins, unlock prompts Moderate ~256 MiB, about a second -- rarely-typed secrets Sensitive ~1 GiB, several seconds -- offline key derivation

ICorePasswordHash#

ICorePasswordHash.h:43 · class · 4 declaration(s)

Opened by row PS5.6 of the Platform SDK product plan.

class ICorePasswordHash {
public:
    ICorePasswordHash() = delete;

    enum class Strength {
        Interactive = 0,
        Moderate    = 1,
        Sensitive   = 2
    };

    static constexpr std::size_t SaltBytes = 16;

    // The PHC string, or std::nullopt when the system cannot provide the
    // memory the Strength needs.
    [[nodiscard]] static std::optional<std::string> hash(std::string_view password);
    [[nodiscard]] static std::optional<std::string> hash(std::string_view password,
                                                         Strength strength);

    // True only when `stored` is a well-formed Argon2id string and `password`
    // matches it. The comparison runs in constant time.
    [[nodiscard]] static bool verify(std::string_view stored, std::string_view password);

    // True when `stored` was not made with `strength`'s costs (or is not an
    // Argon2id string this class can read).
    [[nodiscard]] static bool needsRehash(std::string_view stored, Strength strength);

    // `keyBytes` (16 or more) bytes derived from the password. std::nullopt when
    // the salt is not SaltBytes long, keyBytes is under 16, or the memory is
    // unavailable.
    [[nodiscard]] static std::optional<ICoreByteArray> deriveKey(std::string_view password,
                                                                 const ICoreByteArray& salt,
                                                                 std::size_t keyBytes,
                                                                 Strength strength);
};
};

ICoreRandom.h#

ICoreEssentials/Crypto/ICoreRandom.h

ICoreRandom -- cryptographically secure random numbers.

Every value comes from the operating system's CSPRNG (getentropy / arc4random on Apple, getrandom on Linux and Android, BCryptGenRandom on Windows, crypto.getRandomValues in a browser), reached through the SDK's vendored libsodium. Use it for keys, nonces, salts, session tokens and identifiers -- anything an attacker must not be able to predict.

There is no seed and no generator object: the source is the system's, it is safe to call from any thread, and there is no state to share or leak. For a REPRODUCIBLE sequence (a simulation, a test fixture) use <random>'s engines instead; this class deliberately cannot be seeded.

uniform() has no modulo bias: every value below the bound is equally

ICoreRandom#

ICoreRandom.h:30 · class · 6 declaration(s)

Opened by row PS5.1 of the Platform SDK product plan.

class ICoreRandom {
public:
    ICoreRandom() = delete;

    // Fills `size` bytes at `buffer`. A zero size is a no-op.
    static void fill(void* buffer, std::size_t size);

    // `count` fresh random bytes.
    [[nodiscard]] static ICoreByteArray bytes(std::size_t count);

    // A value in [0, upperBound), uniformly distributed. upperBound 0 and 1
    // both return 0.
    [[nodiscard]] static std::uint32_t uniform(std::uint32_t upperBound);

    // 32 and 64 uniformly random bits.
    [[nodiscard]] static std::uint32_t next32();
    [[nodiscard]] static std::uint64_t next64();
};
};

ICoreSecretBox.h#

ICoreEssentials/Crypto/ICoreSecretBox.h

ICoreSecretBox -- authenticated symmetric encryption.

seal() encrypts AND authenticates a message under a 32-byte secret key; open() returns the original bytes only if the box is exactly what seal() produced under that key. A flipped bit, a truncated box, a different key or different associated data all make open() return std::nullopt -- never a partial or garbled plaintext.

The construction is XChaCha20-Poly1305 (IETF), from the SDK's vendored libsodium. Its 192-bit nonce is drawn at random for every seal(), so the same key may seal as many messages as you like without nonce bookkeeping.

A box is laid out as nonce (24 bytes) || ciphertext || tag (16 bytes), so it is always plaintext.size() + Overhead bytes long. That layout is part

ICoreSecretBox#

ICoreSecretBox.h:38 · class · 2 declaration(s)

Opened by row PS5.5 of the Platform SDK product plan.

class ICoreSecretBox {
public:
    ICoreSecretBox() = delete;

    static constexpr std::size_t KeyBytes   = 32;
    static constexpr std::size_t NonceBytes = 24;
    static constexpr std::size_t TagBytes   = 16;
    static constexpr std::size_t Overhead   = NonceBytes + TagBytes;

    // A fresh random key.
    [[nodiscard]] static ICoreByteArray generateKey();

    // nonce || ciphertext || tag. std::nullopt only when the key is not
    // exactly KeyBytes long.
    [[nodiscard]] static std::optional<ICoreByteArray> seal(const ICoreByteArray& plaintext,
                                                            const ICoreByteArray& key);
    [[nodiscard]] static std::optional<ICoreByteArray> seal(const ICoreByteArray& plaintext,
                                                            const ICoreByteArray& key,
                                                            const ICoreByteArray& associatedData);

    // The plaintext, or std::nullopt when the box is malformed, was altered,
    // or was sealed under a different key or associated data.
    [[nodiscard]] static std::optional<ICoreByteArray> open(const ICoreByteArray& box,
                                                            const ICoreByteArray& key);
    [[nodiscard]] static std::optional<ICoreByteArray> open(const ICoreByteArray& box,
                                                            const ICoreByteArray& key,
                                                            const ICoreByteArray& associatedData);
};
};

ICoreSignatureVerifier.h#

ICoreEssentials/Crypto/ICoreSignatureVerifier.h

ICoreSignatureVerifier#

ICoreSignatureVerifier.h:73 · class · 2 declaration(s)

ICoreSignatureVerifier -- detached Ed25519 verification, and nothing else.

class ICoreSignatureVerifier {
public:
    // Ed25519, fixed by the algorithm. Asserted against libsodium's own
    // constants in the .cpp, so a libsodium upgrade that changed them would
    // fail to compile rather than fail to verify.
    static constexpr std::size_t PublicKeyBytes = 32;
    static constexpr std::size_t SignatureBytes = 64;

    enum class Outcome {
        Ok,                      // and ONLY this one means the signature is good
        BadSignature,            // well formed, and it is not the signature
        MalformedPublicKey,      // not PublicKeyBytes bytes
        MalformedSignature,      // not SignatureBytes bytes
        Unavailable              // libsodium would not initialise; never seen
    };

    // The primitive. `message` may be empty; `signature` and `publicKey` are
    // RAW BYTES, not text -- pass them through decodeKeyOrSignature() first if
    // they arrived as base64url or hex.
    [[nodiscard]] static Outcome verifyDetached(std::string_view message,
                                                std::string_view signature,
                                                std::string_view publicKey);

    // The same check, with the two textual encodings decoded first. A decode
    // failure is MalformedSignature / MalformedPublicKey -- it is never
    // reported as a bad signature, because "you pasted the key wrong" and
    // "this build is not ours" want different responses.
    [[nodiscard]] static Outcome verifyDetachedEncoded(std::string_view message,
                                                       std::string_view signatureText,
                                                       std::string_view publicKeyText);

    // base64url (unpadded) or lowercase/uppercase hex, disambiguated by length
    // against `expectedBytes`. std::nullopt for anything else -- including a
    // string that decodes fine but to the wrong length, which is the shape a
    // truncated copy-paste takes.
    [[nodiscard]] static std::optional<std::string> decodeKeyOrSignature(std::string_view text,
                                                                         std::size_t expectedBytes);

    // For a log line. Not a UI string -- a dialog writes its own, because
    // "the signature is not ours" needs more words than this.
    [[nodiscard]] static std::string_view describe(Outcome outcome);

    // Case coverage for the crypto suite (A7.1). Returns the failure count and
    // appends a sentence per failure.
    static int selfTest(std::vector<std::string>* failures);

};