PenguinConverters.CandyStore.xml

<?xml version="1.0"?>
<doc>
    <assembly>
        <name>PenguinConverters.CandyStore</name>
    </assembly>
    <members>
        <member name="T:PenguinConverters.CandyStore.AesGcmCrypto">
             <summary>
             AES-256-GCM authenticated encryption primitives.
             
             Security properties:
             - 256-bit key (32 bytes) for AES-256
             - 96-bit nonce (12 bytes) - optimal for GCM mode per NIST SP 800-38D
             - 128-bit authentication tag (16 bytes) - maximum integrity protection
             - Unique random nonce per encryption operation
             </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.AesGcmCrypto.NONCE_SIZE_BYTES">
            <summary>
            Nonce size: 96 bits (12 bytes) - optimal for GCM mode.
            </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.AesGcmCrypto.TAG_SIZE_BYTES">
            <summary>
            Authentication tag size: 128 bits (16 bytes) - maximum GCM integrity.
            </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.AesGcmCrypto.KEY_SIZE_BYTES">
            <summary>
            Key size: 256 bits (32 bytes) for AES-256.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.AesGcmCrypto.Encrypt(System.Byte[],System.Byte[])">
            <summary>
            Encrypts plaintext using AES-256-GCM.
            Output format: nonce (12 bytes) + ciphertext + tag (16 bytes)
            </summary>
            <param name="key">AES-256 key (must be 32 bytes)</param>
            <param name="plaintext">Data to encrypt</param>
            <returns>Encrypted data: nonce + ciphertext + tag</returns>
            <exception cref="T:System.ArgumentException">If key is not 32 bytes</exception>
        </member>
        <member name="M:PenguinConverters.CandyStore.AesGcmCrypto.Decrypt(System.Byte[],System.Byte[])">
            <summary>
            Decrypts ciphertext using AES-256-GCM.
            Input format: nonce (12 bytes) + ciphertext + tag (16 bytes)
            </summary>
            <param name="key">AES-256 key (must be 32 bytes)</param>
            <param name="encryptedData">Encrypted data: nonce + ciphertext + tag</param>
            <returns>Decrypted plaintext</returns>
            <exception cref="T:System.ArgumentException">If key is not 32 bytes or data is invalid</exception>
            <exception cref="T:System.Security.Cryptography.CryptographicException">If authentication fails</exception>
        </member>
        <member name="M:PenguinConverters.CandyStore.AesGcmCrypto.GenerateKey">
            <summary>
            Generates a cryptographically secure random AES-256 key.
            </summary>
            <returns>32-byte random key</returns>
        </member>
        <member name="M:PenguinConverters.CandyStore.AesGcmCrypto.ClearKey(System.Byte[])">
            <summary>
            Securely clears a key from memory.
            </summary>
            <param name="key">The key to clear</param>
        </member>
        <member name="M:PenguinConverters.CandyStore.AesGcmCrypto.ValidateKey(System.Byte[])">
            <summary>
            Validates that the provided key is non-null and the correct size for AES-256.
            </summary>
            <param name="key">The key to validate.</param>
        </member>
        <member name="T:PenguinConverters.CandyStore.CandyExtensions">
            <summary>
            Object custom method extensions
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.CandyExtensions.Apply``1(``0,System.Action{``0})">
            <summary>
            Apply inline changes over initialized object
            </summary>
            <typeparam name="T"></typeparam>
            <param name="obj"></param>
            <param name="action"></param>
            <returns></returns>
        </member>
        <member name="M:PenguinConverters.CandyStore.CandyExtensions.SecureStringAction(System.Security.SecureString,System.Action{System.String},System.Text.Encoding)">
            <summary>
            Performs secure operation on SecureString
            </summary>
            <param name="secureString"></param>
            <param name="StringAction"></param>
            <param name="encoding"></param>
        </member>
        <member name="M:PenguinConverters.CandyStore.CandyExtensions.SecureStringAction(System.Security.SecureString,System.Action{System.Byte[]},System.Text.Encoding)">
            <summary>
            Performs secure operation on SecureString byte representation without creating a managed string.
            </summary>
            <param name="secureString"></param>
            <param name="ByteArrayAction"></param>
            <param name="encoding"></param>
        </member>
        <member name="M:PenguinConverters.CandyStore.CandyExtensions.ToSecureString(System.String)">
            <summary>
            Converts String to SecureString
            </summary>
            <param name="value">String value</param>
            <returns>SecureString value</returns>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeyraEngine">
             <summary>
             Gateway to the Rust <c>keyra_ffi</c> engine. This build is <b>Rust-only</b>: the managed
             crypto/IO chokepoints (<c>AesGcmCrypto</c>, keystore load, secret/folder IO, vault-key
             derivation, git, hosting) are thin facades over the native engine, with <b>no .NET fallback</b>.
             
             The engine is therefore a hard dependency. Each top-level entry point (WPF, CLI, PowerShell)
             calls <see cref="M:PenguinConverters.CandyStore.KeyraEngine.RequireNativeEngine"/> at startup to fail fast with a clear message if the
             cdylib is missing, rather than run on a path that no longer exists. The cdylib ships in the
             installer beside the managed assemblies (and is copied into <c>dotnet publish</c> output for
             local runs); a missing engine means a broken install or a dev build where
             <c>cargo build -p keyra-ffi --release</c> has not been run.
             </summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeyraEngine.NativeEngineAvailable">
            <summary>Whether the native Rust engine (<c>keyra_ffi</c>) is present and loadable.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraEngine.RequireNativeEngine">
            <summary>
            Asserts the native Rust engine is present, throwing a clear, actionable error if not.
            Called at startup by every entry point: this build runs on the Rust engine with no
            managed fallback, so a missing engine must fail loudly rather than degrade silently.
            </summary>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeyraFountainDecoder">
             <summary>
             Reassembles a share from scanned fountain-coded QR frames (the animated multi-QR path for
             payloads too large for a single QR — see <see cref="M:PenguinConverters.CandyStore.KeyraNativeCrypto.FountainEncode(System.String,System.Int32)"/>).
             Feed every scanned text to <see cref="M:PenguinConverters.CandyStore.KeyraFountainDecoder.Ingest(System.String)"/> until it reports
             <see cref="F:PenguinConverters.CandyStore.FountainIngestState.Complete"/>, then take the reconstructed plain-armored share
             from <see cref="M:PenguinConverters.CandyStore.KeyraFountainDecoder.Armored"/>. Frames arrive in any order and dropped frames are tolerated —
             the decoder completes as soon as it has decoded <i>enough</i> of them.
             
             The native decoder locks onto the stream of the first valid frame; frames of another stream
             report <see cref="F:PenguinConverters.CandyStore.FountainIngestState.StreamMismatch"/> and text without the fountain markers
             (a plain armored share, an unrelated QR) reports <see cref="F:PenguinConverters.CandyStore.FountainIngestState.NotAFrame"/>
             so the caller can route it to the normal import path. The reassembled payload lives only
             inside the Rust decoder (zeroized on dispose) until <see cref="M:PenguinConverters.CandyStore.KeyraFountainDecoder.Armored"/> is called.
             </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraFountainDecoder.#ctor">
            <summary>Creates an empty decoder; it locks onto the first valid frame it ingests.</summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeyraFountainDecoder.IsComplete">
            <summary>Whether the stream has fully reassembled (a prior ingest reported Complete).</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraFountainDecoder.Ingest(System.String)">
            <summary>
            Feeds one scanned QR text. Corrupt frames (fountain markers present but undecodable
            content) throw; every routing outcome is returned as a <see cref="T:PenguinConverters.CandyStore.FountainIngestResult"/>.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraFountainDecoder.Armored">
            <summary>
            The reassembled share as a <b>plain-armored</b> string — the same <c>KEYRA:…:ARYEK</c>
            form the single-QR path emits, directly consumable by the existing import pipelines.
            Throws while the stream is not complete.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraFountainDecoder.Dispose">
            <inheritdoc/>
        </member>
        <member name="T:PenguinConverters.CandyStore.FountainIngestState">
            <summary>Routing outcome of one <see cref="M:PenguinConverters.CandyStore.KeyraFountainDecoder.Ingest(System.String)"/> call (mirrors the native states).</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.FountainIngestState.Accepted">
            <summary>A new frame was absorbed; the stream is not complete yet.</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.FountainIngestState.Duplicate">
            <summary>The frame was already absorbed (the animation looped); nothing changed.</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.FountainIngestState.Complete">
            <summary>The stream is complete — fetch the share via <see cref="M:PenguinConverters.CandyStore.KeyraFountainDecoder.Armored"/>.</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.FountainIngestState.NotAFrame">
            <summary>Not a fountain frame — route the text to the normal armor import path.</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.FountainIngestState.StreamMismatch">
            <summary>The frame belongs to a different stream than the one the decoder locked onto.</summary>
        </member>
        <member name="T:PenguinConverters.CandyStore.FountainIngestResult">
            <summary>
            One ingest outcome: the routing <see cref="P:PenguinConverters.CandyStore.FountainIngestResult.State"/> and the unique-frame progress
            (<see cref="P:PenguinConverters.CandyStore.FountainIngestResult.Received"/> of <see cref="P:PenguinConverters.CandyStore.FountainIngestResult.Needed"/>, the UI numerator/denominator; both 0 while
            no stream is locked).
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.FountainIngestResult.#ctor(PenguinConverters.CandyStore.FountainIngestState,System.Int32,System.Int32)">
            <summary>
            One ingest outcome: the routing <see cref="P:PenguinConverters.CandyStore.FountainIngestResult.State"/> and the unique-frame progress
            (<see cref="P:PenguinConverters.CandyStore.FountainIngestResult.Received"/> of <see cref="P:PenguinConverters.CandyStore.FountainIngestResult.Needed"/>, the UI numerator/denominator; both 0 while
            no stream is locked).
            </summary>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeyraKdbxOpenStatus">
            <summary>
            Outcome of <see cref="M:PenguinConverters.CandyStore.KeyraKdbxDatabase.TryOpen(System.String,System.Byte[],System.Byte[],PenguinConverters.CandyStore.KeyraKdbxDatabase@)"/>. Consumers map these to localized
            messages; no engine error text crosses the boundary.
            </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraKdbxOpenStatus.Success">
            <summary>The database was opened and decrypted.</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraKdbxOpenStatus.FileUnreadable">
            <summary>The file could not be read.</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraKdbxOpenStatus.InvalidKey">
            <summary>The master password (or key file) failed verification.</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraKdbxOpenStatus.InvalidFormat">
            <summary>The file is not a supported KeePass database or is corrupt.</summary>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeyraKdbxDatabase">
            <summary>
            A KeePass <c>.kdbx</c> database opened and decrypted by the Rust engine
            (<c>keyra-import</c>, issue #76). The decrypted database lives engine-side behind an
            opaque handle; managed code sees a metadata manifest (JSON, no secret values) and fetches
            individual field/attachment values as Rust-owned <see cref="T:PenguinConverters.CandyStore.KeyraSecureBuffer"/>s, so
            secret values never sit on the managed heap unless a consumer explicitly exports them.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraKdbxDatabase.TryOpen(System.String,System.Byte[],System.Byte[],PenguinConverters.CandyStore.KeyraKdbxDatabase@)">
            <summary>
            Opens and decrypts a <c>.kdbx</c> file. The caller owns <paramref name="passwordUtf8"/>
            and should zero it after the call; it is only read for the duration of the open.
            </summary>
            <param name="path">Path to the .kdbx file.</param>
            <param name="passwordUtf8">Master password, UTF-8 encoded.</param>
            <param name="keyFile">Raw key-file bytes, or null when no key file is used.</param>
            <param name="database">The opened database on <see cref="F:PenguinConverters.CandyStore.KeyraKdbxOpenStatus.Success"/>.</param>
            <returns>The open outcome.</returns>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraKdbxDatabase.GetManifestJson">
            <summary>
            Returns the database metadata as camelCase JSON:
            <c>{groups:[{path,name}],entries:[{index,title,path,created?,expires?,fields,binaries}]}</c>.
            Contains no secret values.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraKdbxDatabase.TryReadField(System.Int32,System.String,PenguinConverters.CandyStore.KeyraSecureBuffer@)">
            <summary>
            Reads one string field of an entry into a Rust-owned buffer (UTF-8 content).
            </summary>
            <param name="entryIndex">The entry's manifest index.</param>
            <param name="fieldName">The field name as listed in the manifest.</param>
            <param name="value">The field value; the caller must dispose it.</param>
            <returns>False when the entry index or field name is unknown.</returns>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraKdbxDatabase.TryReadBinary(System.Int32,System.String,PenguinConverters.CandyStore.KeyraSecureBuffer@)">
            <summary>
            Reads one binary attachment of an entry into a Rust-owned buffer.
            </summary>
            <param name="entryIndex">The entry's manifest index.</param>
            <param name="attachmentName">The attachment name as listed in the manifest.</param>
            <param name="value">The attachment bytes; the caller must dispose it.</param>
            <returns>False when the entry index or attachment name is unknown.</returns>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraKdbxDatabase.Dispose">
            <inheritdoc/>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeyraNativeCrypto">
             <summary>
             Managed façade over the Rust <c>keyra-ffi</c> crypto engine (P/Invoke).
             
             Phase 1 (coexist): this is exercised by parity tests to prove byte-for-byte equivalence
             with the .NET implementation in the real .NET runtime. It is NOT on any production path
             yet. Byte-in/byte-out; the native side owns and zeroizes its own intermediates. DPAPI-NG
             is intentionally absent — it stays in the Windows-only key-storage provider.
             </summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeyraNativeCrypto.IsAvailable">
            <summary>True if the native <c>keyra-ffi</c> library is present and loadable.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.AbiVersion">
            <summary>The C-ABI version exported by the native library.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.Sha256(System.Byte[])">
            <summary>SHA-256 of <paramref name="data"/> (32 bytes).</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.HmacSha256(System.Byte[],System.Byte[])">
            <summary>HMAC-SHA256(<paramref name="key"/>, <paramref name="message"/>) (32 bytes).</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.Pbkdf2Sha256(System.Byte[],System.Byte[],System.Int32,System.Int32)">
            <summary>PBKDF2-HMAC-SHA256 deriving <paramref name="outputLength"/> bytes.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.AesGcmEncrypt(System.Byte[],System.Byte[])">
            <summary>AES-256-GCM encrypt with a fresh random nonce. Output: nonce(12)‖ciphertext‖tag(16).</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.AesGcmDecrypt(System.Byte[],System.Byte[])">
            <summary>AES-256-GCM decrypt of nonce(12)‖ciphertext‖tag(16).</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.AesGcmDecryptToBuffer(System.Byte[],System.Byte[])">
            <summary>
            AES-256-GCM decrypt of <c>nonce(12) || ciphertext || tag(16)</c> into a Rust-owned
            <see cref="T:PenguinConverters.CandyStore.KeyraSecureBuffer"/> — the key-per-call entry (the DPAPI-NG provider's path;
            its key is managed by design, the plaintext still never touches the managed heap).
            </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorShapeCount">
            <summary>
            Number of decorative shapes the native renderer supports (mirrors Rust <c>armor::SHAPES</c>).
            Valid shape indices for <see cref="M:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorFormat(System.String,PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorKind,System.Int32,System.Char)"/> are <c>0 .. ArmorShapeCount-1</c>.
            </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorShapePlain">
            <summary>Shape sentinel for <see cref="M:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorFormat(System.String,PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorKind,System.Int32,System.Char)"/> / <see cref="M:PenguinConverters.CandyStore.KeyraNativeCrypto.SecretTransferBuild(System.String,PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorKind,System.Int32,System.Char)"/>: plain, unshaped markers.</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorShapeRandom">
            <summary>Shape sentinel for <see cref="M:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorFormat(System.String,PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorKind,System.Int32,System.Char)"/> / <see cref="M:PenguinConverters.CandyStore.KeyraNativeCrypto.SecretTransferBuild(System.String,PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorKind,System.Int32,System.Char)"/>: a random decorative shape.</summary>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorKind">
            <summary>Marker kind for share armor: secret (double colon) or vault/key (single colon).</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorKind.Secret">
            <summary>Secret data — <c>KEYRA::</c> … <c>::ARYEK</c>.</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorKind.Vault">
            <summary>Vault/key data — <c>KEYRA:</c> … <c>:ARYEK</c>.</summary>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorUnwrapResult">
            <summary>The result of unwrapping an armored string: the recovered Base64 payload and its kind.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorUnwrapResult.#ctor(PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorKind,System.String)">
            <summary>The result of unwrapping an armored string: the recovered Base64 payload and its kind.</summary>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorTransferResult">
            <summary>The result of parsing a secret-transfer share: the canonical <c>SecretTransferData</c> JSON and its kind.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorTransferResult.#ctor(PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorKind,System.String)">
            <summary>The result of parsing a secret-transfer share: the canonical <c>SecretTransferData</c> JSON and its kind.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.ManifestNormalize(System.String)">
            <summary>
            Formats an already-Base64 <paramref name="payload"/> into a decorative share-armor string using the
            <paramref name="kind"/> markers. <paramref name="shape"/> selects the decorative shape; pass a negative
            value for the (currently deterministic) random shape. <paramref name="spacer"/> is the character that
            fills the shape's holes — the default space matches the WPF renderer, the Android renderer passes
            <c>'.'</c>; both import identically because the parser strips whitespace and <c>'.'</c>. A Base64
            spacer is rejected. Payloads above the large-data threshold render as plain armor. Byte-identical to
            the Rust <c>keyra-core::armor</c> renderer across every client.
            </summary>
            <summary>
            Normalizes <c>.keyra</c> manifest JSON (<c>vault.json</c>) through the engine's typed
            model — the one manifest reader/writer every head binds to (issue #87). Output is
            canonical: PascalCase declaration order, nulls written, unmodeled fields preserved
            after the modeled ones, datetimes passed through as source text. The golden fixture in
            <c>contracts/golden/</c> pins the output byte-identical to what
            <c>Core.Export.VaultManifest</c> serialization produces for the same content.
            </summary>
            <param name="manifestJson">The manifest document text.</param>
            <returns>The canonical manifest text.</returns>
            <exception cref="T:System.Security.Cryptography.CryptographicException">
            The input is not a manifest-shaped JSON object.
            </exception>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.SecretTransferBuild(System.String,PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorKind,System.Int32,System.Char)">
            <summary>
            Builds a secret-transfer share string from a <c>SecretTransferData</c> JSON object
            (<paramref name="dtoJson"/> — any field ordering / date formatting the caller's serializer emits is
            accepted). The DTO is re-serialized <b>canonically in Rust</b>, so the wire bytes are identical
            regardless of which head produced the share; the result is Base64-encoded and wrapped in the
            <paramref name="kind"/> markers. <paramref name="shape"/> (negative = random) and
            <paramref name="spacer"/> control the decorative render. Throws on invalid DTO JSON.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.SecretTransferParse(System.String)">
            <summary>
            Parses a secret-transfer share string (<paramref name="share"/>; plain or shaped, space- or
            <c>'.'</c>-holed) into the <b>canonical</b> <c>SecretTransferData</c> JSON, alongside the detected
            <see cref="T:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorKind"/>. Rust is the single parser of this wire format. Returns <c>null</c> when the
            text carries no Keyra marker.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorUnwrap(System.String)">
            <summary>
            Parses an armored (plain or shaped) string, recovering the Base64 payload and detecting its
            <see cref="T:PenguinConverters.CandyStore.KeyraNativeCrypto.ArmorKind"/>. Returns <c>null</c> when no Keyra marker is present.
            </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraNativeCrypto.MaxSingleQrChars">
            <summary>
            Largest armored share (in characters) still shown as a <b>single static</b> QR; anything
            longer animates via <see cref="M:PenguinConverters.CandyStore.KeyraNativeCrypto.FountainEncode(System.String,System.Int32)"/>. A readability ceiling, deliberately far
            below the QR format's hard capacity — a near-capacity code "fits" but is unscannable at
            screen size (issue #47). Mirrors Rust <c>fountain::MAX_SINGLE_QR_CHARS</c>.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.FountainEncode(System.String,System.Int32)">
            <summary>
            Splits a <b>plain-armored</b> share string into fountain-coded QR frame strings
            (<c>KEYRA:QR:…:ARYEK</c>) for an animated multi-QR display — the path for payloads too
            large for a single QR code. The display loops the frames; a scanner
            (<see cref="T:PenguinConverters.CandyStore.KeyraFountainDecoder"/>) reassembles the share from any sufficient subset,
            so a dropped frame never stalls the transfer. Frame generation is deterministic — the
            same share yields byte-identical frames on every head. <paramref name="maxFrameChars"/>
            caps each frame's text length (<c>0</c> = the canonical default). Throws when the input
            is not armored Base64 or the frame budget is too small.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.KeystoreGenerateKey">
            <summary>Generates a random 256-bit AES key.</summary>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeyraNativeCrypto.ProtectedKeyResult">
            <summary>
            A key protected with a password: the raw ciphertext plus the parameters the caller MUST
            record beside it. Storing the ciphertext without the salt and recipe makes the key
            unrecoverable - they belong together in the key entry's provider block
            (see <c>docs/storage-format.md</c>).
            </summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeyraNativeCrypto.ProtectedKeyResult.Ciphertext">
            <summary>Raw <c>AES-256-GCM(KEK, key)</c> - no envelope, no magic, no header.</summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeyraNativeCrypto.ProtectedKeyResult.Salt">
            <summary>The random Site-B salt this key was derived with.</summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeyraNativeCrypto.ProtectedKeyResult.KdfRecipeJson">
            <summary>The Site-B recipe, as executed, ready to record verbatim.</summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeyraNativeCrypto.ProtectedKeyResult.ProviderTypeId">
            <summary>The provider that produced it (the built-in portable scheme).</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.KeystoreProtectPassword(System.Byte[],System.Byte[])">
            <summary>
            Protects a 32-byte key with a password (UTF-8 bytes) via the engine's portable password
            scheme (Argon2id KEK + AES-256-GCM). This is the only AES-GCM/password key-protection
            path in the product. The caller records the returned salt and recipe alongside the
            ciphertext; nothing is embedded in the bytes.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.KeystoreUnprotectPassword(System.Byte[],System.Byte[],System.Byte[],System.String)">
            <summary>
            Recovers a key from raw <paramref name="ciphertext"/> using the password plus the
            <paramref name="salt"/> and <paramref name="kdfRecipeJson"/> recorded with it. The recipe
            is validated against the engine's hard bounds before it executes, so a recipe demanding
            weak or extravagant parameters is refused rather than obeyed.
            </summary>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeyraNativeCrypto.KeyContainer">
            <summary>
            The container a key is stored in, as folded into its verification hash: a vault's
            <c>vaultId</c>, or one of <see cref="T:PenguinConverters.CandyStore.KeyraNativeCrypto.KeyContainer"/>'s constants. See
            <see cref="M:PenguinConverters.CandyStore.KeyraNativeCrypto.VerificationHash(System.Byte[],System.String)"/>.
            </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraNativeCrypto.KeyContainer.MASTER_KEY">
            <summary>The repository's master-key store.</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraNativeCrypto.KeyContainer.PORTABLE">
            <summary>
            A portable package that belongs to no container yet. Such a key is re-protected when
            it is adopted into one, which restamps its hash for that container.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.VerificationHash(System.Byte[],System.String)">
            <summary>
            Raw 32-byte verification hash <c>SHA256(key || "KeyraVerification.v2" || context)</c>.
            </summary>
            <remarks>
            <paramref name="context"/> names the container the key is stored in. Binding the two
            means a key file moved between containers fails verification instead of opening whatever
            it was dropped into; the hash covered the key alone before, which made that move
            invisible. A key adopted into a container is re-protected there, so it is stamped for
            where it actually lives rather than where it came from.
            </remarks>
            <param name="aesKey">The raw key.</param>
            <param name="context">The container the key is stored in.</param>
            <returns>The 32-byte hash.</returns>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.KeystoreVerify(System.Byte[],System.Byte[],System.String)">
            <summary>
            Constant-time verify of a key against a stored raw verification hash, for
            <paramref name="context"/>. A key checked against the wrong container does not match.
            </summary>
            <param name="aesKey">The raw key.</param>
            <param name="expectedHash">The stored hash.</param>
            <param name="context">The container the key is stored in.</param>
            <returns>True when the key matches.</returns>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.MixKeyWithEntropy(System.Byte[],System.Byte[])">
            <summary>Mixes a key with additional (image) entropy → 32-byte key.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.KeystoreLoadKey(System.Byte[],System.Byte[],System.String)">
            <summary>
            Recovers the 32-byte AES key from a <c>.key</c> metadata JSON document (UTF-8 bytes)
            using <paramref name="passwordUtf8"/>: parses KeyMetadata, Base64-decodes + unprotects
            the blob, and verifies the stored hash. Throws on bad password / corrupt / mismatch.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.HkdfSha256(System.Byte[],System.Byte[],System.Byte[],System.Int32)">
            <summary>HKDF-SHA256 (e.g. YubiKey response → key derivation).</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.RecipeExecute(System.Byte[],System.Collections.Generic.IReadOnlyList{System.String},System.Collections.Generic.IReadOnlyList{System.Byte[]})">
            <summary>
            Executes a Site-A KDF recipe (UTF-8 JSON, as produced by the Core <c>KdfRecipe</c>) over
            named byte inputs → the 32-byte vault key, via the single Rust interpreter. Secret input
            values (passwords, UTF-16LE) are passed as raw bytes and the flattened copy is zeroized
            after the call — never marshalled through a managed string; input names are non-secret.
            </summary>
            <param name="recipeJsonUtf8">The recipe as UTF-8 JSON bytes.</param>
            <param name="inputNames">Input names in the same order as <paramref name="inputValues"/>.</param>
            <param name="inputValues">Input value byte-runs (secret-capable), one per name.</param>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.SanitizeName(System.Byte[])">
            <summary>Sanitizes a name for filesystem use (UTF-8 in, UTF-8 string out).</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.ValidateSecretJson(System.Byte[])">
            <summary>Whether the Rust engine can deserialize a secret JSON document (UTF-8 bytes).</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.ValidateFolderJson(System.Byte[])">
            <summary>Whether the Rust engine can deserialize a <c>folder.json</c> document (UTF-8 bytes).</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.SecretStoreSaveSecret(System.String,System.String)">
            <summary>
            Saves a secret into <paramref name="secretsDir"/>: Rust parses the .NET <c>Secret</c> JSON,
            chooses a collision-safe file name from its identifier, and writes the on-disk bytes.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.SecretStoreLoadSecrets(System.String)">
            <summary>
            Loads every secret in <paramref name="secretsDir"/> as a JSON array (UTF-8) of the .NET
            <c>Secret</c> shape. A missing directory yields <c>[]</c>; unparseable files are skipped.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.SecretStoreListFolders(System.String)">
            <summary>
            Lists the immediate child folders of <paramref name="foldersDir"/> as a JSON array (UTF-8)
            of absolute path strings, sorted. A missing directory yields <c>[]</c>.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.SecretStoreReadFolderFields(System.String)">
            <summary>
            Leniently reads the <c>Identifier</c> + <c>Properties</c> fields from <c>folder.json</c> in
            <paramref name="folderDir"/>, returning <c>{"identifier":&lt;string|null&gt;,"properties":{..}}</c>
            (UTF-8). A missing/malformed file yields <c>{"identifier":null,"properties":{}}</c>.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.SecretStoreDeleteSecret(System.String,System.String)">
            <summary>
            Deletes the secret with <paramref name="identifier"/> from <paramref name="secretsDir"/>.
            Returns whether a file was removed.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.SecretStoreSaveFolder(System.String,System.String)">
            <summary>
            Writes <c>folder.json</c> into <paramref name="folderDir"/> (and ensures its
            <c>secrets/</c> subdirectory exists): Rust parses the metadata JSON and writes the bytes.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.GitInit(System.String)">
            <summary>Initializes a git repository in <paramref name="dir"/> (mirrors GitFeature.Initialize).</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.GitRenameBranch(System.String,System.String)">
            <summary>Force-renames the current branch to <paramref name="branch"/> (git branch -M).</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.GitSetOrAddRemote(System.String,System.String,System.String)">
            <summary>Sets (or adds) <paramref name="remote"/> to <paramref name="url"/> in <paramref name="dir"/>.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.GitClone(System.String,System.String,System.String)">
            <summary>
            Clones <paramref name="url"/> into <paramref name="target"/> (mirrors GitFeature.Clone),
            authenticating with <paramref name="token"/> via the inline credential helper when set.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.GitSync(System.String,System.String,System.String,System.String,System.String,System.String,System.Boolean,System.String)">
            <summary>
            Pull → commit → push for <paramref name="dir"/> (mirrors GitFeature.Sync). Returns whether
            a push ran. Authenticates with <paramref name="token"/> via the inline credential helper.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.GitStage(System.String)">
            <summary>Stages all changes in <paramref name="dir"/> (git add -A; mirrors GitFeature.Stage).</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.GitCommit(System.String,System.String,System.String,System.String)">
            <summary>
            Stages then commits <paramref name="dir"/> with <paramref name="message"/> (mirrors
            GitFeature.Commit); a clean tree is a no-op. The author identity may be empty.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.GitPush(System.String,System.String,System.String,System.Boolean,System.String)">
            <summary>
            Pushes the current branch of <paramref name="dir"/> (mirrors GitFeature.Push): renames the
            branch to <paramref name="branch"/> if mismatched and sets upstream on first push.
            Authenticates with <paramref name="token"/> via the inline credential helper when set.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.GitPull(System.String,System.String,System.String,System.Boolean,System.String)">
            <summary>
            Pulls (fetch + rebase) into <paramref name="dir"/> (mirrors GitFeature.Pull); tolerates an
            empty/new remote. Authenticates with <paramref name="token"/> via the inline credential
            helper when set.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.GitLastError">
            <summary>Retrieves the last git error message recorded by the native engine on this thread.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.ThrowIfGitError(System.Int32,System.String)">
            <summary>Throws a descriptive exception on a non-OK git status, surfacing the git error text.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.HostingBuildCreateRequest(System.String)">
            <summary>
            Builds a create-repository HTTP request from a JSON spec
            (<c>{provider,token,baseUrl?,name,description?,isPrivate,organization?,initializeWithReadme}</c>).
            Returns JSON: <c>{"request":{method,url,headers:[{name,value}],body}}</c> on success, or
            <c>{"error":"..."}</c> when the provider rejects the options. The caller performs the HTTP.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.HostingParseCreateResponse(System.String,System.Int32,System.String)">
            <summary>
            Parses a create-repository HTTP response into a result JSON
            (<c>{success,errorMessage,repositoryUrl,cloneUrl,sshUrl}</c>). <paramref name="provider"/>
            is <c>"github"</c> or <c>"gitlab"</c>.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.HostingGitlabBuildNamespaceRequest(System.String)">
            <summary>
            Builds the GitLab namespace-resolution request from a JSON spec
            (<c>{token,baseUrl?,namespacePath}</c>). Returns <c>{"request":{...}}</c> for the caller to send.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.HostingGitlabParseNamespace(System.Int32,System.String)">
            <summary>
            Parses a GitLab namespace-resolution response into <c>{"namespaceId":&lt;number|null&gt;}</c>.
            </summary>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeyraNativeCrypto.JsonReturningCall">
            <summary>Delegate for an FFI call that writes a variable-length result via the buffer-grow contract.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraNativeCrypto.CallJsonReturning(PenguinConverters.CandyStore.KeyraNativeCrypto.JsonReturningCall,System.String)">
            <summary>Invokes a buffer-grow FFI call (probe for size, then read) and returns the UTF-8 result.</summary>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeyraPasswordGenerator">
             <summary>
             The engine's password generator (issue #73).
             
             <para>
             There is one of these for the whole product, and that is the point. A generator is easy to
             write and easy to write badly - the usual mistake is reducing a random byte modulo the
             alphabet size, which favours the first <c>256 % length</c> characters and silently spends
             the entropy the caller thought it was buying by choosing a length. Keeping generation in the
             engine means no head can reintroduce that by writing its own, and the alphabet cannot drift
             between the CLI and the desktop heads.
             </para>
             
             <para>
             The generated password lives in a <see cref="T:PenguinConverters.CandyStore.KeyraSecureBuffer"/> - native memory the GC
             never moves, zeroized on disposal. It reaches the managed heap only if a caller explicitly
             asks it to.
             </para>
             </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraPasswordGenerator.Lowercase">
            <summary>Lower-case letters.</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraPasswordGenerator.Uppercase">
            <summary>Upper-case letters.</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraPasswordGenerator.Digits">
            <summary>Decimal digits.</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraPasswordGenerator.Symbols">
            <summary>Punctuation.</summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraPasswordGenerator.AllClasses">
            <summary>
            Every character class - the default, and the 88-character alphabet the CLI generator has
            always used.
            </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeyraPasswordGenerator.MaxLength">
            <summary>The longest password the engine will generate.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraPasswordGenerator.Generate(System.Int32,System.UInt32,System.Byte[])">
             <summary>
             Generates a password as a native, zeroizing buffer holding UTF-8 bytes.
             
             <para>
             Every character is ASCII, so <see cref="P:PenguinConverters.CandyStore.KeyraSecureBuffer.Length"/> is the password's
             character count as well as its byte count.
             </para>
             </summary>
             <param name="length">How many characters to generate.</param>
             <param name="classes">Character classes to draw from; defaults to all of them.</param>
             <param name="additionalEntropy">
             Optional entropy to fold into the draw — in practice the repository's stored first-run
             entropy (issue #210). Null or empty simply means there is none, and the engine draws
             straight from the OS random source. It is <b>mixed, never substituted</b>: the engine
             keeps an unconditional CSPRNG floor, so these bytes can only add to the result's
             unpredictability, and two calls with identical entropy still return different passwords.
             The caller owns the buffer and should zero it afterwards.
             </param>
             <returns>The password. The caller disposes it.</returns>
             <exception cref="T:System.ArgumentOutOfRangeException">The length is not between 1 and <see cref="F:PenguinConverters.CandyStore.KeyraPasswordGenerator.MaxLength"/>.</exception>
             <exception cref="T:System.ArgumentException">No character class was selected.</exception>
             <exception cref="T:System.Security.Cryptography.CryptographicException">The engine could not generate it.</exception>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraPasswordGenerator.GenerateSecureString(System.Int32,System.UInt32,System.Byte[])">
             <summary>
             Generates a password directly into a read-only <see cref="T:System.Security.SecureString"/>, for the
             callers whose next step needs one.
             
             <para>
             The characters are copied one at a time out of native memory, so the password is never a
             managed <c>string</c> at any point. The native buffer is disposed - and so zeroized -
             before this returns.
             </para>
             </summary>
             <param name="length">How many characters to generate.</param>
             <param name="classes">Character classes to draw from; defaults to all of them.</param>
             <param name="additionalEntropy">Optional entropy to fold in; see <see cref="M:PenguinConverters.CandyStore.KeyraPasswordGenerator.Generate(System.Int32,System.UInt32,System.Byte[])"/>.</param>
             <returns>The password. The caller disposes it.</returns>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeyraSecretCipher">
             <summary>
             Managed handle over a Rust <c>keyra-engine</c> value cipher (an opaque pointer) — the .NET face
             of the provider-agnostic <c>SecretCipher</c> capability. The master key lives only inside Rust
             and is zeroized on <see cref="M:PenguinConverters.CandyStore.KeyraSecretCipher.Dispose"/> — it never lands on the managed heap. The built-in
             cipher is AES-256-GCM; secret values are <c>Base64(AES-GCM(master_key, plaintext))</c>,
             byte-identical to the .NET AES-GCM key.
             
             This is the consumption primitive the cipher decoupling (unhooking consumers from
             <c>IKey</c>) is built on. See <c>docs/cipher-architecture.md</c>.
             </summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeyraSecretCipher.KeyId">
            <summary>Key identifier — a reference for display/sharing, never the key material.</summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeyraSecretCipher.Algorithm">
            <summary>Algorithm identifier of the built-in cipher.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraSecretCipher.OpenAesGcmFromKeyJson(System.Byte[],System.Byte[],System.String,System.String)">
            <summary>
            Opens an AES-GCM cipher by recovering the master key from <c>.key</c> metadata JSON +
            auth-derived <paramref name="passwordUtf8"/> — the key is recovered inside Rust and never
            lands on the managed heap (AES-GCM / password-protected keys).
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraSecretCipher.OpenAesGcmFromMasterKey(System.Byte[],System.String)">
            <summary>
            Opens an AES-GCM cipher over an already-recovered 32-byte master key (e.g. a DPAPI-NG key
            unwrapped in .NET). The caller should zeroize its copy after this call.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraSecretCipher.Encrypt(System.Byte[])">
            <summary>Encrypts <paramref name="plaintext"/> with the cipher → Base64 ciphertext string.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraSecretCipher.Decrypt(System.String)">
            <summary>Decrypts a Base64 ciphertext string with the cipher → plaintext bytes.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraSecretCipher.DecryptToBuffer(System.String)">
            <summary>
            Decrypts a Base64 ciphertext string into a Rust-owned <see cref="T:PenguinConverters.CandyStore.KeyraSecureBuffer"/> —
            the plaintext never crosses to the managed heap.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraSecretCipher.ExportAesGcm(System.Byte[],System.String)">
            <summary>
            Re-protects this AES-GCM cipher's key with <paramref name="passwordUtf8"/> into a portable
            <c>.key</c> blob (for export/sharing). The raw key stays inside Rust — only the protected
            blob + verification hash cross the boundary.
            </summary>
            <returns>The Base64 <c>protectedBlob</c> and <c>keyVerificationHash</c>.</returns>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraSecretCipher.Dispose">
            <inheritdoc/>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeyraSecureBuffer">
             <summary>
             A Rust-owned plaintext allocation (issue #74). The decrypted bytes live only in native
             memory — never moved by the GC, so no compaction can strand stale copies — and are zeroized
             inside Rust on <see cref="M:PenguinConverters.CandyStore.KeyraSecureBuffer.Dispose"/>. Managed code reads them in place through
             <see cref="P:PenguinConverters.CandyStore.KeyraSecureBuffer.ByteSpan"/>/<see cref="P:PenguinConverters.CandyStore.KeyraSecureBuffer.CharSpan"/>; the bytes reach the managed heap only on an
             explicit <see cref="M:PenguinConverters.CandyStore.KeyraSecureBuffer.ToArray"/>, whose copy the caller owns and must zero.
             
             Spans are valid only while the buffer is undisposed; do not store them.
             </summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeyraSecureBuffer.Length">
            <summary>Length in bytes.</summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeyraSecureBuffer.ByteSpan">
            <summary>A read-only view over the native bytes (UTF-8 for text buffers).</summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeyraSecureBuffer.CharSpan">
            <summary>
            A read-only char view over the native bytes. Valid only for buffers produced by
            <see cref="M:PenguinConverters.CandyStore.KeyraSecureBuffer.ToUtf16"/> (UTF-16LE content).
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraSecureBuffer.ToUtf16">
            <summary>
            Re-encodes this UTF-8 buffer as a new UTF-16 buffer (for <see cref="P:PenguinConverters.CandyStore.KeyraSecureBuffer.CharSpan"/> /
            managed <c>char</c> consumers). The conversion happens inside Rust; this buffer is
            untouched and both must be disposed.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraSecureBuffer.FromBytes(System.Byte[])">
            <summary>
            Creates a buffer by copying <paramref name="data"/> into Rust — the fallback for ciphers
            whose crypto runs managed. The caller should zero its source copy after this call.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraSecureBuffer.ToArray">
            <summary>
            Copies the contents to a new managed array — an explicit export; the caller is
            responsible for zeroing the returned array.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraSecureBuffer.Dispose">
            <inheritdoc/>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeyraVaultSession">
             <summary>
             Managed handle over a Rust <c>keyra-engine</c> vault session (an opaque pointer). The master
             key lives only inside Rust and is zeroized on <see cref="M:PenguinConverters.CandyStore.KeyraVaultSession.Lock"/>/<see cref="M:PenguinConverters.CandyStore.KeyraVaultSession.Dispose"/> —
             it never lands on the managed heap.
             
             Phase F: this is the bridge the consumer cutover will use. It is not yet on a production
             path. Inert/throws only when the native <c>keyra-ffi</c> library is present (Open fails
             otherwise, like the other native wrappers).
             </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraVaultSession.Open(System.String,System.String)">
            <summary>Opens a (locked) vault session for <paramref name="vaultId"/> under <paramref name="root"/>.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraVaultSession.UnlockWithPassword(System.String,System.String,System.Byte[],System.String)">
            <summary>Unlocks from a <c>.key</c> file using the auth-derived password (UTF-8 bytes) — AES-GCM vaults.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraVaultSession.UnlockWithKeyJson(System.Byte[],System.Byte[],System.String)">
            <summary>
            Unlocks by recovering the master key from <c>.key</c> metadata JSON (the portable/on-disk
            key file content) using the auth-derived <paramref name="passwordUtf8"/> — AES-GCM /
            password-protected keys. The key is recovered inside Rust and never lands on the managed
            heap. DPAPI-NG keys cannot be recovered this way; unwrap them in .NET and use
            <see cref="M:PenguinConverters.CandyStore.KeyraVaultSession.UnlockWithMasterKey(System.Byte[])"/>.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraVaultSession.UnlockWithMasterKey(System.Byte[])">
            <summary>Unlocks with an already-recovered 32-byte master key (e.g. a DPAPI-NG vault unwrapped in .NET).</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraVaultSession.Lock">
            <summary>Locks the session, zeroizing the master key in Rust.</summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeyraVaultSession.IsUnlocked">
            <summary>Whether the session is currently unlocked.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraVaultSession.Encrypt(System.Byte[])">
            <summary>Encrypts <paramref name="plaintext"/> with the session key → Base64 ciphertext string.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraVaultSession.Decrypt(System.String)">
            <summary>Decrypts a Base64 ciphertext string with the session key → plaintext bytes.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraVaultSession.DecryptToBuffer(System.String)">
            <summary>
            Decrypts a Base64 ciphertext string into a Rust-owned <see cref="T:PenguinConverters.CandyStore.KeyraSecureBuffer"/> —
            the plaintext never crosses to the managed heap.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeyraVaultSession.Dispose">
            <inheritdoc/>
        </member>
        <member name="T:PenguinConverters.CandyStore.KeystrokeEntropyCollector">
            <summary>
            Collects cryptographic entropy from keystroke characters and their precise timing — a thin
            facade over the Rust engine's entropy collector (<c>keyra-crypto::entropy</c>). The engine
            owns the pool: every recorded event is timestamped natively at call time, key-code and
            modifier metadata is folded in as application-supplied entropy, and generation always mixes
            fresh OS randomness, so keystroke input can only add entropy on top of the CSPRNG, never
            replace it. The pool lives in Rust and is zeroized on dispose; only the display text is
            kept managed. Thread-safe for concurrent access.
            </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeystrokeEntropyCollector.ENTROPY_SIZE_BYTES">
            <summary>
            Size of the generated entropy in bytes (256-bit).
            </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeystrokeEntropyCollector._handle">
            <summary>
            Handle to the engine's entropy collector, which owns the accumulating pool.
            </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeystrokeEntropyCollector._textBuilder">
            <summary>
            Builder for the collected text (optional, for display purposes).
            </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeystrokeEntropyCollector._keystrokeCount">
            <summary>
            Number of keystrokes recorded.
            </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeystrokeEntropyCollector._lock">
            <summary>
            Lock object for thread-safe access.
            </summary>
        </member>
        <member name="F:PenguinConverters.CandyStore.KeystrokeEntropyCollector._disposed">
            <summary>
            Whether the collector has been disposed.
            </summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeystrokeEntropyCollector.KeystrokeCount">
            <summary>
            Gets the number of keystrokes recorded.
            </summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeystrokeEntropyCollector.CollectedText">
            <summary>
            Gets the collected text (if tracking is enabled).
            </summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeystrokeEntropyCollector.MinimumKeystrokes">
            <summary>
            Gets or sets the minimum keystrokes required for adequate entropy.
            Default is 20.
            </summary>
        </member>
        <member name="P:PenguinConverters.CandyStore.KeystrokeEntropyCollector.HasSufficientEntropy">
            <summary>
            Gets whether sufficient entropy has been collected.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeystrokeEntropyCollector.#ctor">
            <summary>
            Creates a new KeystrokeEntropyCollector over a freshly seeded engine pool.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeystrokeEntropyCollector.RecordKeystroke(System.Char)">
            <summary>
            Records a keystroke; the engine timestamps it with high-resolution timing.
            </summary>
            <param name="character">The character pressed</param>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeystrokeEntropyCollector.RecordKeystroke(System.Char,System.Int32,System.Int32)">
            <summary>
            Records a keystroke with additional key metadata (for CLI with ConsoleKeyInfo).
            The key code and modifier state are folded into the pool as application-supplied entropy.
            </summary>
            <param name="character">The character pressed</param>
            <param name="keyCode">The virtual key code</param>
            <param name="modifiers">Modifier keys state</param>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeystrokeEntropyCollector.AddApplicationEntropy(System.Byte[])">
            <summary>
            Folds application-supplied bytes into the engine's pool. Unlike
            <see cref="M:PenguinConverters.CandyStore.KeystrokeEntropyCollector.RecordKeystroke(System.Char)"/> this carries no interaction timing — it is for
            entropy the host already holds, such as the first-run image entropy a repository keeps
            for its master key.
            <para>
            Mixing in, never substituting: <see cref="M:PenguinConverters.CandyStore.KeystrokeEntropyCollector.GenerateEntropy"/> hashes the pool together
            with fresh timestamps and 32 bytes of OS randomness, so what is added here can raise the
            unpredictability of the output but can never lower it below that CSPRNG floor. Passing
            the same bytes twice therefore does not make the collector deterministic.
            </para>
            </summary>
            <param name="data">The bytes to fold in. Empty is a no-op; the caller owns and should
            zero the buffer when it holds anything sensitive.</param>
            <exception cref="T:System.ArgumentNullException"><paramref name="data"/> is null.</exception>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeystrokeEntropyCollector.RecordBackspace">
            <summary>
            Records a backspace (removes last character from text but keeps timing entropy).
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeystrokeEntropyCollector.GenerateEntropy">
            <summary>
            Generates a 256-bit (32-byte) entropy value: the engine hashes its pool together with
            fresh timestamps and 32 bytes of OS randomness. Non-destructive — successive calls
            yield independent values.
            </summary>
            <returns>32-byte entropy array</returns>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeystrokeEntropyCollector.Reset">
            <summary>
            Resets the collector to initial state; the engine wipes and reseeds its pool.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeystrokeEntropyCollector.Dispose">
            <summary>
            Disposes the collector; the engine zeroizes the collected pool.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeystrokeEntropyCollector.ThrowIfDisposed">
            <summary>
            Throws ObjectDisposedException if disposed.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.KeystrokeEntropyCollector.ThrowIfError(System.Int32,System.String)">
            <summary>
            Throws CryptographicException for a non-OK engine status.
            </summary>
        </member>
        <member name="T:PenguinConverters.CandyStore.Native.KeyraFfiNative">
            <summary>
            Raw P/Invoke declarations for the Rust <c>keyra-ffi</c> cdylib (the single C-ABI
            boundary). All interop lives here. Functions return an <see cref="T:System.Int32"/> status
            (0 = OK, negative = error); variable-length results use a caller buffer plus
            <c>out_written</c>. See <c>docs/interop.md</c>.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.Native.KeyraFfiNative.Register">
            <summary>
            Registers a resolver so the cdylib is found next to the assembly, under
            <c>runtimes/&lt;rid&gt;/native/</c>, or at <c>KEYRA_FFI_PATH</c> — falling back to
            the default OS search. Runs once when the assembly loads.
            </summary>
        </member>
        <member name="T:PenguinConverters.CandyStore.Native.KeyraVaultSessionHandle">
            <summary>
            A <see cref="!:SafeHandle"/> over a Rust <c>keyra-engine</c> vault-session pointer. Using a
            SafeHandle (instead of a raw <see cref="T:System.IntPtr"/> + finalizer) makes the P/Invoke marshaller
            ref-count and keep the handle alive across each native call, closing the premature-finalization
            and cross-thread use-after-free windows, and it releases the session (zeroizing the master key
            in Rust) deterministically on dispose or via its own critical finalizer.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.Native.KeyraVaultSessionHandle.#ctor">
            <summary>Parameterless ctor required for <c>out</c> marshalling; owns the handle.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.Native.KeyraVaultSessionHandle.ReleaseHandle">
            <inheritdoc/>
        </member>
        <member name="T:PenguinConverters.CandyStore.Native.KeyraSecretCipherHandle">
            <summary>
            A <see cref="!:SafeHandle"/> over a Rust <c>keyra-engine</c> value-cipher pointer. See
            <see cref="T:PenguinConverters.CandyStore.Native.KeyraVaultSessionHandle"/> for the rationale.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.Native.KeyraSecretCipherHandle.#ctor">
            <summary>Parameterless ctor required for <c>out</c> marshalling; owns the handle.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.Native.KeyraSecretCipherHandle.ReleaseHandle">
            <inheritdoc/>
        </member>
        <member name="T:PenguinConverters.CandyStore.Native.KeyraSecureBufHandle">
            <summary>
            A <see cref="!:SafeHandle"/> over a Rust-owned plaintext buffer (<c>keyra-ffi SecureBuf</c>).
            The decrypted bytes live only in native memory — never moved by the GC — and are zeroized
            inside Rust when the handle is released. See <see cref="T:PenguinConverters.CandyStore.Native.KeyraVaultSessionHandle"/> for the
            SafeHandle rationale.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.Native.KeyraSecureBufHandle.#ctor">
            <summary>Parameterless ctor required for <c>out</c> marshalling; owns the handle.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.Native.KeyraSecureBufHandle.ReleaseHandle">
            <inheritdoc/>
        </member>
        <member name="T:PenguinConverters.CandyStore.Native.KeyraFountainDecoderHandle">
            <summary>
            A <see cref="!:SafeHandle"/> over a Rust <c>keyra-core</c> fountain-decoder pointer (the
            animated multi-QR reassembler). See <see cref="T:PenguinConverters.CandyStore.Native.KeyraVaultSessionHandle"/> for the rationale;
            releasing zeroizes any reassembled share payload held inside the native decoder.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.Native.KeyraFountainDecoderHandle.#ctor">
            <summary>Parameterless ctor required for <c>out</c> marshalling; owns the handle.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.Native.KeyraFountainDecoderHandle.ReleaseHandle">
            <inheritdoc/>
        </member>
        <member name="T:PenguinConverters.CandyStore.Native.KeyraKdbxImportHandle">
            <summary>
            A <see cref="!:SafeHandle"/> over a Rust <c>keyra-import</c> opened-kdbx pointer (the
            decrypted KeePass database held engine-side, issue #76). See
            <see cref="T:PenguinConverters.CandyStore.Native.KeyraVaultSessionHandle"/> for the rationale; releasing drops the decrypted
            database inside Rust (protected values are zeroized by their containers).
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.Native.KeyraKdbxImportHandle.#ctor">
            <summary>Parameterless ctor required for <c>out</c> marshalling; owns the handle.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.Native.KeyraKdbxImportHandle.ReleaseHandle">
            <inheritdoc/>
        </member>
        <member name="T:PenguinConverters.CandyStore.Native.KeyraEntropyCollectorHandle">
            <summary>
            A <see cref="!:SafeHandle"/> over a Rust <c>keyra-crypto</c> entropy-collector pointer (the
            first-run interaction-entropy pool). See <see cref="T:PenguinConverters.CandyStore.Native.KeyraVaultSessionHandle"/> for the
            rationale; releasing zeroizes the collected pool inside the native collector.
            </summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.Native.KeyraEntropyCollectorHandle.#ctor">
            <summary>Parameterless ctor required for <c>out</c> marshalling; owns the handle.</summary>
        </member>
        <member name="M:PenguinConverters.CandyStore.Native.KeyraEntropyCollectorHandle.ReleaseHandle">
            <inheritdoc/>
        </member>
    </members>
</doc>