SevenZipWriterOptions gains Password and EncryptHeader (#1472). With a
password, each folder is written as 7zAES -> LZMA/LZMA2 in the same
layout 7-Zip uses: AES is coder 0 and reads the packed stream, the
codec is coder 1 and reads AES's output. AES properties match 7-Zip's
defaults (NumCyclesPower 19, no salt, random 16-byte IV per folder), so
the key is derived once per archive. EncryptHeader runs the header
through the same chain; an encrypted header is always LZMA-compressed.
Empty files have no stream and stay unencrypted, as in 7-Zip.
- SevenZipAesKey: the 7zAES KDF, moved unchanged from AesDecoderStream
so the encoder and decoder share it.
- AesEncoderStream: AES-256-CBC, zero-fills the last block on Finish.
- SevenZipAesEncryption: per-archive key and per-folder IV/properties.
- EncryptHeader without a password, or an empty password, throws
ArgumentException.
Uses only Aes (CBC) and SHA256, available on every target framework and
Native AOT safe. Verified with 7-Zip 26.05 (7z t, 7z x, 7z l -slt) and
WinRAR for LZMA and LZMA2, with and without header encryption.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7-Zip writes 7zAES as the first coder of an encrypted folder, in front
of the codec. SevenZipFilePart.GetCompression() looked at the first
coder only, so CompressionType threw InvalidFormatException for every
entry of a 7-Zip-made encrypted archive. Skip the AES filter and report
the first real coder.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7-Zip writes 7zAES as the first coder of an encrypted folder, in front
of the codec. SevenZipFilePart.GetCompression() looked at the first
coder only, so CompressionType threw InvalidFormatException for every
entry of a 7-Zip-made encrypted archive. Skip the AES filter and report
the first real coder.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reuse keyed HMAC state and digest buffers on modern .NET targets while preserving RAR5's three PBKDF2 snapshots. Add independent derivation checks and an allocation regression test.
Profiling on macOS ARM64 with .NET 10 reduced allocations by 99.96%, but showed slower throughput; Alpine-specific timing remains unverified. Full .NET 10 test suite passes.
Use a ValueTask read core and memory-based compressed-input refills on modern targets, replace per-block Huffman output arrays with scalar parameters, and decode directly into array-backed caller memory with a pooled fallback.
Preserve generated sync array-read semantics and clear codec output references after reads. Add slice, fallback, cancellation, failure, tree-validation, and read-ahead coverage; document staged ZIP profiles.
Validation: 2,989 .NET 10 tests passed; all library targets, net48 tests, and performance project compile; formatting checks pass.
Replace historical profiling rounds with a self-contained report for the origin/master merge comparison, including allocation results, timing variability, validation, and reproduction artifacts.