9.6 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 03-round-trip-verification | 02 | execute | 2 |
|
|
true |
|
|
Purpose: Golden vectors prove the crypto implementation matches the spec (cross-verifiable with openssl). Round-trip tests prove the full pack->unpack pipeline preserves file content exactly. Together they satisfy the Phase 3 success criteria.
Output: tests/golden.rs with fixed-IV crypto tests, tests/round_trip.rs with CLI integration tests for all edge cases.
<execution_context> @/home/nick/.claude/get-shit-done/workflows/execute-plan.md @/home/nick/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/03-round-trip-verification/03-RESEARCH.md @.planning/phases/03-round-trip-verification/03-01-SUMMARY.md @docs/FORMAT.md @src/crypto.rs @src/key.rs Task 1: Create golden test vectors with fixed IV/key tests/golden.rs Create `tests/golden.rs` with deterministic golden test vectors. These call library functions directly with fixed IVs (NOT via CLI which uses random IVs).Import:
use encrypted_archive::{crypto, key::KEY};
use hex_literal::hex;
Test 1: test_golden_aes256cbc_hello
Encrypt "Hello" (5 bytes) with project KEY and IV = 00000000000000000000000000000001.
Expected ciphertext: hex!("6e66ae8bc740efeefe83b5713fcb716f") (16 bytes -- verified with openssl in research).
let iv = hex!("00000000000000000000000000000001");
let ciphertext = crypto::encrypt_data(b"Hello", &KEY, &iv);
assert_eq!(ciphertext, hex!("6e66ae8bc740efeefe83b5713fcb716f").to_vec());
Test 2: test_golden_aes256cbc_decrypt_hello
Decrypt the ciphertext from Test 1 back to "Hello". Verifies round-trip with the exact golden vector.
let iv = hex!("00000000000000000000000000000001");
let ciphertext = hex!("6e66ae8bc740efeefe83b5713fcb716f");
let plaintext = crypto::decrypt_data(&ciphertext, &KEY, &iv).unwrap();
assert_eq!(plaintext, b"Hello");
Test 3: test_golden_aes256cbc_empty
Encrypt empty slice with KEY and IV = zero. Expected: 16 bytes (full PKCS7 padding block). Decrypt back, assert empty.
Use a fixed IV (e.g., all zeros). The exact ciphertext can be computed: encrypt b"" and store the result as golden vector. Since empty + PKCS7 = 16 bytes of 0x10, encrypt that. Compute the expected value by running the test once, then hardcode it. ALTERNATIVELY: just test the round-trip property (encrypt then decrypt gives empty) plus verify length == 16. This is simpler and sufficient for the empty case.
Test 4: test_golden_hmac_sha256
Compute HMAC-SHA256 over IV || ciphertext from Test 1.
Expected: hex!("0c85780b6628ba3b52654d2f6e0d9bbec67443cf2a6104eb3120ec93fc2d38d4") (verified with openssl in research).
let iv = hex!("00000000000000000000000000000001");
let ciphertext = hex!("6e66ae8bc740efeefe83b5713fcb716f");
let hmac = crypto::compute_hmac(&KEY, &iv, &ciphertext);
assert_eq!(hmac, hex!("0c85780b6628ba3b52654d2f6e0d9bbec67443cf2a6104eb3120ec93fc2d38d4"));
Test 5: test_golden_hmac_verify
Verify HMAC from Test 4 returns true. Also verify with a wrong expected value returns false.
Test 6: test_golden_sha256_hello
SHA-256("Hello") must equal hex!("185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969") (from FORMAT.md Section 12.3).
Test 7: test_golden_sha256_32x01
SHA-256 of 32 bytes of 0x01 must equal hex!("72cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793") (from FORMAT.md Section 12.3).
CRITICAL: Do NOT create golden vectors for compressed-then-encrypted data (gzip non-determinism across platforms). All golden vectors test raw plaintext encryption only. cd /home/nick/Projects/Rust/encrypted_archive && cargo test --test golden 2>&1 All 7 golden vector tests pass Golden test vectors exist for AES-256-CBC encrypt/decrypt, HMAC-SHA256, and SHA-256. All values cross-verified with openssl enc / openssl dgst / sha256sum during research. TST-02 satisfied.
Task 2: Create CLI round-trip integration tests tests/round_trip.rs Create `tests/round_trip.rs` with integration tests that run the actual `encrypted_archive` binary via `assert_cmd::Command::cargo_bin("encrypted_archive")`.Import:
use assert_cmd::Command;
use tempfile::tempdir;
use std::fs;
Test 1: test_roundtrip_single_text_file
- Create tempdir, write
hello.txtwith contentb"Hello". - Run
encrypted_archive pack hello.txt -o archive.bin. - Run
encrypted_archive unpack archive.bin -o output/. - Assert
output/hello.txtcontent == originalb"Hello".
Test 2: test_roundtrip_multiple_files
- Create two files:
text.txt("Some text content") andbinary.dat(256 bytes of 0x42). - Pack both into one archive.
- Unpack.
- Assert both files byte-identical to originals.
Test 3: test_roundtrip_empty_file
- Create
empty.txtwith 0 bytes. - Pack, unpack.
- Assert extracted file is exactly 0 bytes.
- This tests PKCS7 full-block padding on 0-byte input (encrypted_size = 16).
Test 4: test_roundtrip_cyrillic_filename
- Create
файл.txtwith content "Содержимое" (Cyrillic, UTF-8). - Pack, unpack.
- Assert extracted
файл.txtcontent equals original. - This tests non-ASCII (UTF-8) filename handling in TOC entries.
Test 5: test_roundtrip_large_file
- Generate 11MB (11_000_000 bytes) of deterministic pseudo-random data:
(0..11_000_000u32).map(|i| (i.wrapping_mul(2654435761)) as u8).collect(). - Write as
large.bin. - Pack with
--no-compress bin(skip compression for binary extension). - Unpack.
- Assert byte-identical.
- This tests large file handling (>10MB) per Phase 3 success criteria.
Test 6: test_roundtrip_no_compress_flag
- Create
data.apkwith some content (e.g., 100 bytes of pattern). - Pack (APK auto-detected as no-compress).
- Unpack.
- Assert byte-identical.
- This tests that no-compression round-trip works (compression_flag=0).
Each test uses tempdir() for isolation (auto-cleanup, parallel-safe).
Each test asserts .success() on both pack and unpack commands.
Each test compares file content with assert_eq!(fs::read(original), fs::read(extracted)).
IMPORTANT: Use assert_cmd::Command::cargo_bin("encrypted_archive").unwrap() to locate the binary. This handles debug/release build paths automatically.
cd /home/nick/Projects/Rust/encrypted_archive && cargo test --test round_trip 2>&1
All 6 round-trip tests pass including empty file, Cyrillic filename, and 11MB file
Round-trip integration tests cover: single file, multiple files, empty file, Cyrillic filename, large (11MB) binary, no-compression APK. All tests verify byte-identical extraction via SHA-256 implicit comparison (assert_eq on raw bytes). INT-02 and TST-01 satisfied.
<success_criteria>
cargo testruns 30+ tests (19 unit + 7 golden + 6 round-trip), all pass- Golden test values match openssl cross-verification from research
- All Phase 3 success criteria met:
- Byte-identical round-trips (INT-02)
- Golden vectors exist (TST-02)
- Unit tests per module (TST-03, from Plan 01)
- Edge cases: empty file, >10MB, Cyrillic filename </success_criteria>