TT Lab
Blog

한국어 English 日本語 中文

Get started
Blog

Blog

Model Weight Encryption and Protection: Rethinking the Cost of Encryption at Rest and Defining Protection Boundaries

Status: Draft (2026-10-07). Encryption/decryption speed, integrity checks, and the path of placing decrypted weights into a memory volume to boot a vLLM server (0.6B model) are values measured directly by the author. Confidential computing could not be tested directly due to a lack of hardware, so paper and vendor documentation descriptions were reviewed and cited. Loading large models and multiple GPUs was not measured (unmeasured). Writing Rule: Measured data is the default, and unmeasured items are marked as 「Unmeasured」.

Table of Contents

1. Define the Question First: What Are We Protecting Weights From?

The phrase "encrypting the model" is meaningless unless threats are defined. Weights are exposed through multiple paths, and encryption only protects against some of them.

Threat Example Encryption at Rest Additional Requirements
Leakage from storage, backups, and image registries Bucket permission errors, lost backup tapes, image layer leakage Blocked(if keys are stored separately) Store keys separately from storage
Eavesdropping in transit Between nodes and storage Blocked by TLS; encryption at rest serves as defense-in-depth mTLS
File tampering and swapping (supply chain) Replacing with malicious weights, reordering Detected by authenticated encryption (GCM)(Checked in Section 4) Signatures and provenance verification
Memory dump of a running server Node root, malicious pod on the same node, debugger Not blocked(Decrypted weights reside in memory) Access control, confidential computing
Functional replication via serving API Training a imitation model by collecting outputs through mass queries Irrelevant Rate limiting, anomaly detection, contracts
Parameter extraction via serving API Reconstructing actual parameters of the final layer from APIs exposing logits and log probabilities (Carlini et al., ICML 2024) Irrelevant Limit exposed fields (prohibit combinations of logprobs and logit bias)

This article measures the costs and effects of the first and third rows (encryption at rest and integrity) and explains why the fourth row remains unblocked.

2. Methodology

Item Value
Target The larger of the two safetensors pieces of Qwen3-1.7B (3.44GB)
Cipher AES-256-GCM (cryptography library), 12-byte random nonce per 64MiB chunk, 16-byte tag
Additional Authenticated Data (AAD) Chunk number (8 bytes). Used to detect chunk reordering attacks
Storage format Per chunk: (length 4 bytes, nonce 12 bytes, ciphertext, tag 16 bytes)
Environment Container (CPU limit 6 cores, temporary disk), computations use CPU only
Measurement File encryption/decryption throughput (including disk write/read), pure computational throughput in memory (repeating 64MiB buffer without disk)

3. Cost: How Much Slower and Larger Does It Get?

Item Value
Plaintext file read (close to upper bound due to page cache) 2.15 GB/s
Encryption, file to file 0.56 GB/s (identical for 1 and 4 threads)
Decryption, file to memory 1 thread 0.78, 2 threads 0.92, 4 threads 0.95 GB/s
Pure computation, AES-256-GCM encryption 1 thread 1.81, 2 threads 2.10, 4 threads 2.21 GB/s
Pure computation, AES-256-GCM decryption 1 thread 1.77, 2 threads 2.10, 4 threads 2.20 GB/s
File size increase 3.441GB became 3.441GB (32 bytes per 64MiB chunk, approx. 0.00005%)

Additional Time Added to Cold Starts

Applying a decryption throughput of approx. 0.9 GB/s directly, the additional time by model size is as follows (calculated based on file path values from this test).

Model Size Additional Decryption Time (0.9 GB/s) If at Pure Computation Speed (2 GB/s)
3.4GB (1.7B bf16) Approx. 3.8 sec Approx. 1.7 sec
7GB (12B 4-bit) Approx. 7.8 sec Approx. 3.5 sec
140GB (70B bf16) Approx. 156 sec Approx. 70 sec

140GB is an extrapolated calculation and was not directly measured. Since 70B models are typically split across multiple GPUs, parallelizing decryption per GPU distributes the time (parallel tests splitting processes are in "CPU Supplemental Tests" below). Compared to server preparation time in Article 14 (35-55 seconds for reboot, of which weight loading accounts to 4-6 seconds), a few seconds of decryption is a noticeable ratio for smaller models, but gets buried in model download and loading times for large models.

4. Integrity: Detecting Tampering and Swapping

GCM checks for tampering using tags alongside encryption (NIST SP 800-38D). Two tests were conducted directly.

Attempt Result
Flipping 1 byte in a ciphertext chunk InvalidTag Decryption rejected
Placing chunk 1 into chunk 0's position (chunk swapping) InvalidTag Decryption rejected (because chunk numbers were included in AAD)
SHA-256 of successful decryption result Matches original

Ciphertext is Indistinguishable from Plaintext

Byte entropy of the first 1MiB (including headers) was 6.34 bits/byte for plaintext (safetensors, bf16 weights) and 8.00 bits/byte for ciphertext. While weight files retain statistical structures that can provide clues via compression or pattern analysis, ciphertext is equivalent to randomness. Since encrypted files cannot be compressed either, compression must be done before encryption .

How Much Does It Increase When Inserted into the Serving Engine Loading Path?

We placed decrypted weights into a memory volume (/dev/shm) and booted a vLLM server along that path. The model is Qwen3-0.6B (safetensors 1.50GB) configured with a single 8GB-class GPU, 64MiB chunks, and chunk numbers and total chunk counts included in AAD. Server preparation time spans from launching the server process to receiving a health check response, and decryption time is not included in this value.

Category Measured Value
Encryption (1.50GB) 2.43 sec, 0.62 GB/s
Decryption 3 times (to memory volume) 2.02, 2.10, 2.18 sec (0.69-0.75 GB/s). Total invocation including Python startup and imports is 2.3-2.4 sec
Server preparation from plaintext directory 68.0 sec (first boot), 29.4 sec, 28.3 sec
Server preparation from decryption path 49.4 sec (first boot), 28.3 sec, 27.3 sec
Tampering (1 byte flipped in ciphertext) Aborted at decryption stage with InvalidTag . Weight file was not created (only config files copied) and server start stage was not reached

The interpretation is as follows:

CPU Supplement Test: Disabling Acceleration, Parallelization

The remaining questions from the test above were re-measured using only the CPU (ephemeral pod, one node of a 22-core server CPU, cryptography 50.0.2, 64MiB chunk, memory-only). Since another workload was running concurrently on this node, the absolute values for the same test fluctuated by about 40% (decryption for a single process came out to 1.20 GB/s, and one of the thread tests was 2.00 GB/s). Therefore, only the ratios are meaningful.

Test Result
Default (using AES-NI, PCLMULQDQ) Decryption 2.01 GB/s, Encryption 2.08 GB/s (single-threaded)
OPENSSL_ia32cap=~0x200000000000000 With AES-NI disabled 0.47 GB/s (approx. 4.3x slower)
Both AES-NI and PCLMULQDQ disabled 0.29 GB/s (approx. 6.9x slower)
Decryption with 1, 2, 4, 8 threads (single process) 2.00, 2.52, 2.41, 2.44 GB/s
Decryption with 1, 2, 4, 8 processes 1.20, 2.30, 4.24, 6.07 GB/s (1.9, 3.5, 5.1x compared to 1)

5. What Cannot Be Prevented: Weights Are Plaintext During Execution

For the server to use the model, it must load the decrypted weights into memory (including GPU memory). From that moment on, root on the node or a compromised process on the same node can read the memory. Standard GPUs do not encrypt memory, so this threat cannot be prevented solely by encryption-at-rest.

An NVIDIA tech blog (2023-05-31) explains that H100 GPUs provide confidential computing features that work alongside CPU trusted execution environments (AMD SEV-SNP, Intel TDX). This article could not directly test this feature (lack of datacenter GPUs). A blog post from the same company on 2023-08-03 describes the protection method as follows: the CPU TEE encrypts the virtual machine's memory, the GPU is isolated in hardware, and data between the CPU and GPU passes through an encrypted bounce buffer. On the other hand, it states that HBM on the GPU package is considered secure against casual physical attack tools and is therefore not encrypted. Thus, calling confidential computing "GPU memory encryption" is inaccurate; what it blocks is plaintext exposure on the host side and access by the host administrator. The same post also states that the bandwidth between the CPU and GPU is capped by CPU encryption performance at around 4 GB/s, and in this article's path of loading weights at startup, this value may dictate the loading time (vendor description, directly unmeasured). How to securely deliver keys (releasing keys after attestation) is also a separate design issue.

Therefore, practical layers are stacked as follows:

  1. Storage Side: Encrypt weights and keep keys in a KMS or secret management tool. Bucket permission errors do not immediately lead to leaks.
  2. Loading Side: Receive keys and decrypt at startup. If you use a memory-based volume (emptyDir of medium: Memory) so that decrypted plaintexts are not left on disk, plaintexts will not remain on the node disk. Since this volume consumes RAM equal to the model size, it must be calculated by including it in the node memory and pod memory limits (calculated, not directly tested).
  3. Execution Side: Node access control (SSH, debug pods prohibited), pod security settings, and confidential computing nodes if necessary.
  4. Output Side: Rate limiting and abnormal query detection. You can build a surrogate model by collecting outputs even without stealing weights.

6. Where to Store the Keys

7. Potential Interview Questions

External References

Claims that could not be measured directly or where direct measurement was insufficient were verified using the materials below. "Abstract only" means only the abstract, not the main text, was read.

Claim Material Verified Content
Nonce and call count limits NIST SP 800-38D (2007) Sections 8.2.2, 8.3 Random field of 96 bits or more, total authenticated encryption calls for the same key of 2 to the 32nd power or less. As of 2026, revision is underway, but the valid document is the 2007 edition.
Protection scope of confidential computing NVIDIA Technical Blog (2023-08-03) HBM is not encrypted; protected by CPU TEE, isolation, and encrypted bounce buffers. Between CPU and GPU is approx. 4 GB/s (vendor description).
Inference overhead of H100 confidential computing Zhu et al., arXiv 2409.03992 (Confidential Computing on NVIDIA Hopper GPUs: A Performance Benchmark Study) Less than 7% for most general queries, nearly 0 for large models and long sequences. 70B loaded onto a single card with 4-bit quantization.
Other measurements on the same topic Chrapek et al., arXiv 2509.18886 (abstract only) / Ibarra et al., arXiv 2505.16501 (abstract only) Throughput drop of 4-8% (Llama2 7B-70B) / In configurations swapping models, the non-confidential side has 45-70% higher throughput. Attributes the difference to encryption and decryption costs when loading models onto the GPU.
Parameter extraction via API Carlini et al., ICML 2024 (arXiv 2403.06634) Reconstruction of the final layer from APIs exposing log probabilities and logit bias. The actual countermeasure was limiting exposed fields rather than rate limiting.
Function cloning via API Tramèr et al., USENIX Security 2016 (arXiv 1609.02943, abstract only) Extraction is sometimes possible even when confidence scores are hidden.
Exfiltration when the inference server is compromised Rinberg et al., arXiv 2511.02620 (abstract only) Formalizes the threat of exfiltrating hidden weights within normal responses and proposes verification-based detection.

There are also materials that could not be accessed. RAND's model weight protection report (2024) could not be opened because access to the original text was blocked, so figures regarding the frequency of leak incidents are not included in this article.

Unverified Items

References

Verified Versions and Dates

As of October 7, 2026. cryptography Libraries (AESGCM), Python 3.12 inside the container, Qwen3-1.7B safetensors (speed test), and Qwen3-0.6B (server loading path test, vLLM 0.31.0).

Sign in to like

Comments

No comments yet.

Sign in to leave a comment