1package com.peachpasswords.codex23import org.junit.Assert.assertArrayEquals4import org.junit.Assert.assertEquals5import org.junit.Assert.assertTrue6import org.junit.Test7import kotlin.random.Random89class CodexCodecTest {1011 @Test fun rs_recovers_dropped_shards() {12 val data = 613 val parity = computeParityShards(data) 14 val size = 4015 val rng = Random(7)16 val original = Array(data) { ByteArray(size) { rng.nextInt().toByte() } }17 val shards = Array(data + parity) { i -> if (i < data) original[i].copyOf() else ByteArray(size) }18 ReedSolomon.encode(shards, data, parity)1920 21 val present = BooleanArray(data + parity) { true }22 shards[1] = ByteArray(0); present[1] = false23 shards[4] = ByteArray(0); present[4] = false24 ReedSolomon.reconstruct(shards, data, parity, present)2526 for (i in 0 until data) assertArrayEquals("shard $i", original[i], shards[i])27 }2829 @Test fun gf_mul_div_are_inverse() {30 for (a in 1..255) for (b in 1..255) {31 assertEquals(a, Galois.div(Galois.mul(a, b), b))32 }33 }3435 @Test fun full_codec_round_trip() {36 val payload = CodexPayload(37 version = 2, verifyCode = "PX-AB12-CD34",38 vaultBlob = "x".repeat(5000), timestamp = 111, entryCount = 7,39 vaultFingerprint = "DEADBEEF".repeat(4), generatedAt = 222,40 )41 val bytes = CodexCodec.json.encodeToString(CodexPayload.serializer(), payload).toByteArray()42 val compressed = CodexCodec.deflate(bytes)43 assertArrayEquals(bytes, CodexCodec.inflate(compressed))4445 val (envelopes, layout) = CodexCodec.encodeToEnvelopes(compressed, payload.verifyCode)46 assertTrue(envelopes.all { CodexCodec.verifyChunkIntegrity(it) })47 assertEquals(layout.dataChunks + layout.parityChunks, envelopes.size)4849 50 val parity = layout.parityChunks / layout.stripeCount51 val survivors = envelopes.toMutableList()52 repeat(parity) { survivors.removeAt(0) } 53 val recovered = CodexCodec.reconstructCompressed(survivors)54 val parsed = CodexCodec.json.decodeFromString(CodexPayload.serializer(), String(CodexCodec.inflate(recovered)))55 assertEquals(payload, parsed)56 }5758 @Test fun corrupted_chunk_fails_integrity() {59 val (envelopes, _) = CodexCodec.encodeToEnvelopes(CodexCodec.deflate("hello world".toByteArray()), "PX-0000-0000")60 val tampered = envelopes.first().copy(d = CodexCodec.base64Url("tampered".toByteArray()))61 assertTrue(!CodexCodec.verifyChunkIntegrity(tampered))62 }63}