Table of Contents

👉 Try the demo: https://github.com/LM-Kit/lm-kit-net-samples/tree/main/console_net/local-inference/encrypted-models/encrypted_model_loading

Encrypted Model Loading for C# .NET Applications


🎯 Purpose of the Demo

Encrypts a plaintext GGUF file into an LM-Kit AES-256-CTR encrypted container and loads it directly with LM.LoadEncrypted(). Tensor bytes are decrypted on the fly as the native runtime requests them, so the loader never holds the full file in memory.

👥 Who Should Use This Demo

  • Anyone shipping a model file inside a commercial product where the model weights are intellectual property.
  • Teams that distribute fine-tuned models to customers and want to protect those weights.
  • Regulated environments where model files must be encrypted at rest.

🚀 What Problem It Solves

A plaintext GGUF on disk is a free download for anyone with file system access. With EncryptedGguf.Encrypt() and LM.LoadEncrypted(), you ship a .lmke container that requires the runtime password to deserialise. The encryption is streaming: encryption and load both work on a few MB of metadata plus one tensor at a time, no full-file copy.

💻 Demo Application Overview

A console app that:

  1. Picks (or downloads) a small plaintext GGUF model.
  2. Encrypts it into a sibling .lmke file via EncryptedGguf.Encrypt(src, dst, GgufEncryptionScheme.AesCtr256, password).
  3. Loads the encrypted container with LM.LoadEncrypted(path, scheme, password, loadingProgress).
  4. Runs an interactive chat loop on top of the loaded model.

✨ Key Features

  • LMKit.Cryptography.EncryptedGguf.Encrypt(srcPath, dstPath, scheme, password).
  • LMKit.Model.LM.LoadEncrypted(path, scheme, password, loadingProgress).
  • GgufEncryptionScheme.AesCtr256 -> AES-256 in counter mode, suitable for random tensor access.
  • Streaming I/O: peak RAM stays in the tens of MB even for multi-GB models.

⚙️ Getting Started

Run:

cd lm-kit-net-samples/console_net/local-inference/encrypted-models/encrypted_model_loading
dotnet run

The first run encrypts the chosen plaintext model and caches the result; subsequent runs reuse the cached .lmke file.

🚀 Extend the Demo

  • Move the password out of process memory using a hardware-backed keystore (DPAPI on Windows, Keychain on macOS).
  • Distribute the .lmke file alongside an obfuscated key-derivation routine so the password is never stored verbatim.

📚 Additional Resources

Share