1package com.peachpasswords.vault23import org.junit.Assert.assertEquals4import org.junit.Assert.assertTrue5import org.junit.Test6789101112131415161718192021222324class CrossPlatformRecoveryWordsTest {2526 private val vectorRootKey =27 "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"2829 private val vectorWords = listOf(30 "abandon", "math", "mimic", "master", "filter", "design",31 "carbon", "crystal", "rookie", "group", "knife", "young",32 )3334 @Test fun word_list_is_the_canonical_2048_with_no_duplicates() {35 assertEquals(2048, WORD_LIST.size)36 assertEquals(2048, WORD_LIST.toSet().size)37 assertEquals("abandon", WORD_LIST.first())38 assertEquals("ability", WORD_LIST[1])39 assertEquals("zoo", WORD_LIST.last())40 }4142 @Test fun words_match_the_browser_for_the_shared_vector() {43 assertEquals(vectorWords, rootKeyToWords(hexToRootKey(vectorRootKey)))44 }4546 @Test fun every_reachable_index_round_trips() {47 48 49 for (index in 0 until 2048) {50 assertEquals(51 "index $index does not round-trip",52 index,53 WORD_LIST.indexOf(WORD_LIST[index]),54 )55 }56 }5758 @Test fun random_root_keys_always_round_trip() {59 val rng = java.util.Random(20260726)60 repeat(20_000) {61 val key = ByteArray(32).also(rng::nextBytes)62 val material = wordsToRootKeyMaterial(rootKeyToWords(key))63 assertTrue(material.copyOfRange(0, 16).contentEquals(key.copyOfRange(0, 16)))64 }65 }6667 @Test fun the_shared_vector_decodes_to_its_root_key_entropy() {68 val expected = hexToRootKey(vectorRootKey).copyOfRange(0, 16)69 assertTrue(70 wordsToRootKeyMaterial(vectorWords).copyOfRange(0, 16).contentEquals(expected),71 )72 }73}