b4bbb429a17e

test: pin official cryptographic vectors (v2.4.1)

time
2026-07-26 06:34 UTC · 3 months ago
machine
koh2
parent
3c69d09c658f
5 files VERSION+1 −1app/build.gradle+2 −2app/src/main/jniLibs/arm64-v8a/libpeach_noise_core.sobinaryapp/src/main/jniLibs/x86_64/libpeach_noise_core.sobinaryapp/src/test/java/com/peachpasswords/vault/OfficialCryptoVectorsTest.kt+76 −0
VERSION+1 −1
@@ -1 +1 @@1-2.4.01+2.4.1

view file

app/build.gradle+2 −2
@@ -16,8 +16,8 @@1616         applicationId "com.peachpasswords"1717         minSdk 261818         targetSdk 3519-        versionCode 24000020-        versionName "2.4.0"19+        versionCode 24000120+        versionName "2.4.1"2121 2222         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"2323         vectorDrawables {

view file

app/src/main/jniLibs/arm64-v8a/libpeach_noise_core.sobinary

binary file, not shown

view file

app/src/main/jniLibs/x86_64/libpeach_noise_core.sobinary

binary file, not shown

view file

app/src/test/java/com/peachpasswords/vault/OfficialCryptoVectorsTest.kt+76 −0
@@ -0,0 +1,76 @@1+package com.peachpasswords.vault2+3+import org.bouncycastle.crypto.digests.Blake3Digest4+import org.bouncycastle.crypto.generators.Argon2BytesGenerator5+import org.bouncycastle.crypto.params.Argon2Parameters6+import org.junit.Assert.assertArrayEquals7+import org.junit.Assert.assertEquals8+import org.junit.Assert.assertThrows9+import org.junit.Test10+11+class OfficialCryptoVectorsTest {12+13+    @Test fun rfc_9106_argon2id_vector_matches_bouncy_castle() {14+        val parameters = Argon2Parameters.Builder(Argon2Parameters.ARGON2_id)15+            .withVersion(Argon2Parameters.ARGON2_VERSION_13)16+            .withMemoryAsKB(32)17+            .withIterations(3)18+            .withParallelism(4)19+            .withSalt(ByteArray(16) { 0x02 })20+            .withSecret(ByteArray(8) { 0x03 })21+            .withAdditional(ByteArray(12) { 0x04 })22+            .build()23+        val generator = Argon2BytesGenerator().apply { init(parameters) }24+        val output = ByteArray(32)25+        generator.generateBytes(ByteArray(32) { 0x01 }, output)26+27+        assertEquals(28+            "0d640df58d78766c08c037a34a8b53c9d01ef0452d75b65eb52520e96b01e659",29+            output.toHex(),30+        )31+    }32+33+    @Test fun production_argon2id_profile_matches_browser_hash_wasm() {34+        assertEquals(35+            "df187c8d241e8f3fd42810e1379660605aad1119dcb133d8ff916f87160d6a33",36+            VaultCrypto.deriveKey("testpassword", ByteArray(16) { 0xab.toByte() }).toHex(),37+        )38+    }39+40+    @Test fun nist_aes_256_gcm_cavp_vector_decrypts_and_rejects_bad_tag() {41+        val key = "4c8ebfe1444ec1b2d503c6986659af2c94fafe945f72c1e8486a5acfedb8a0f8".hexBytes()42+        val iv = "473360e0ad24889959858995".hexBytes()43+        val ciphertext = "d2c78110ac7e8f107c0df0570bd7c90c".hexBytes()44+        val tag = "c26a379b6d98ef2852ead8ce83a833a7".hexBytes()45+        val packed = iv + ciphertext + tag46+47+        assertEquals(48+            "7789b41cb3ee548814ca0b388c10b343",49+            VaultCrypto.decrypt(packed, key, ByteArray(0)).toHex(),50+        )51+52+        val tampered = packed.copyOf().also { it[it.lastIndex] = (it.last().toInt() xor 0x01).toByte() }53+        assertThrows(Throwable::class.java) {54+            VaultCrypto.decrypt(tampered, key, ByteArray(0))55+        }56+    }57+58+    @Test fun blake3_reference_vector_matches_bouncy_castle_across_chunk_boundary() {59+        val input = ByteArray(1024) { (it % 251).toByte() }60+        val digest = Blake3Digest(256)61+        digest.update(input, 0, input.size)62+        val output = ByteArray(32)63+        digest.doFinal(output, 0)64+65+        assertArrayEquals(66+            "42214739f095a406f3fc83deb889744ac00df831c10daa55189b5d121c855af7".hexBytes(),67+            output,68+        )69+    }70+71+    private fun String.hexBytes(): ByteArray =72+        chunked(2).map { it.toInt(16).toByte() }.toByteArray()73+74+    private fun ByteArray.toHex(): String =75+        joinToString("") { "%02x".format(it.toInt() and 0xff) }76+}

view file