1package com.peachpasswords23import com.peachpasswords.sync.SASDerivation4import com.peachpasswords.sync.computeVaultId5import com.peachpasswords.sync.noiseNKHkdf2ForTest6import com.peachpasswords.sync.noiseNKInitHashForTest7import com.peachpasswords.vault.VaultCrypto8import org.junit.Assert.assertArrayEquals9import org.junit.Assert.assertEquals10import org.junit.Assert.assertFalse11import org.junit.Assert.assertNotEquals12import org.junit.Test13import java.text.Normalizer14151617181920212223class CrossPlatformKATTest {2425 private fun hex(b: ByteArray) = b.joinToString("") { "%02x".format(it) }2627 28 private val argonSalt = ByteArray(VaultCrypto.SALT_SIZE) { it.toByte() }2930 @Test fun argon2id_non_bmp_password_vector() {31 32 33 34 val key = VaultCrypto.deriveKey("test🔑", argonSalt)35 assertEquals("a519dd4e695d25c6cd69a2f89d51ddcabd952c979f5714ab29fb77f6d1ad3728", hex(key))36 }3738 @Test fun nfc_normalization_makes_composed_and_decomposed_match() {39 40 41 val nfd = Normalizer.normalize("café", Normalizer.Form.NFD)42 val nfc = Normalizer.normalize("café", Normalizer.Form.NFC)43 assertNotEquals(nfd, nfc)44 assertArrayEquals(VaultCrypto.deriveKey(nfd, argonSalt), VaultCrypto.deriveKey(nfc, argonSalt))45 }4647 @Test fun deriveKeyRaw_does_not_normalize() {48 val nfd = Normalizer.normalize("café", Normalizer.Form.NFD)49 val nfc = Normalizer.normalize("café", Normalizer.Form.NFC)50 assertFalse(51 VaultCrypto.deriveKeyRaw(nfd, argonSalt).contentEquals(VaultCrypto.deriveKeyRaw(nfc, argonSalt)),52 )53 }5455 @Test fun compute_vault_id_vector() {56 57 val masterKey = ByteArray(32) { it.toByte() }58 assertEquals("ae0ec54041c9ba3e20c0c2d33bdeb2552f3b9a3fb4be3286ec0ef0a61be2fc9c", computeVaultId(masterKey))59 }6061 @Test fun sas_derivation_vector() {62 63 val handshakeHash = byteArrayOf(0x12, 0x34, 0x56, 0x78) + ByteArray(28)64 assertEquals("67721216", SASDerivation.derive(handshakeHash))65 }6667 68 69 70 71 72 @Test fun noise_nk_init_hash_is_blake2s_vector() {73 assertEquals(74 "e01688d376ef280a27a8af5c559024a02017585b3763763e4f3c7118a979b09e",75 hex(noiseNKInitHashForTest()),76 )77 }7879 @Test fun noise_hkdf2_blake2s_vector() {80 81 val ck = ByteArray(32) { it.toByte() }82 val ikm = ByteArray(32) { (it + 32).toByte() }83 val (nk1, nk2) = noiseNKHkdf2ForTest(ck, ikm)84 assertEquals("6a96444e20e8d4c1cee974416acae1c10b3c92886010e54ed94dafb2c3b80ea0", hex(nk1))85 assertEquals("57af120b0de7acbe7907ec149c5ae870a2dbb74232b65777ba4123f1f7f888f5", hex(nk2))86 }87}