0f3f0e36bc4a
replace the word list that duplicated abandon at index 1 with the browser's canonical 2048, so the same vault stops printing different recovery words on each platform, and decode old phrases through a legacy fallback (v2.4.13)
- time
- 2026-07-26 14:22 UTC · 3 months ago
- machine
- koh2
- agent
- claude-opus-5
- session
- recovery word divergence
- parent
- 8d5c5d9501a7
↓ peach-android-0f3f0e36.tar.gzatlas at this save
files changed6 files
VERSION+1 −1app/build.gradle+2 −2app/src/main/java/com/peachpasswords/vault/RecoveryWordList.kt+534 −2049app/src/main/java/com/peachpasswords/vault/RecoveryWords.kt+30 −22app/src/test/java/com/peachpasswords/vault/CrossPlatformRecoveryWordsTest.kt+87 −0app/src/test/java/com/peachpasswords/vault/RecoveryEscrowTest.kt+9 −2app/build.gradle+2 −2
@@ -16,8 +16,8 @@1616 applicationId "com.peachpasswords"1717 minSdk 261818 targetSdk 3519- versionCode 24001220- versionName "2.4.12"19+ versionCode 24001320+ versionName "2.4.13"2121 2222 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"2323 vectorDrawables {app/src/main/java/com/peachpasswords/vault/RecoveryWordList.kt+534 −2049
@@ -1,2053 +1,538 @@11 package com.peachpasswords.vault22 3-val WORD_LIST: List<String> = listOf(4- "abandon",5- "abandon",6- "ability",7- "able",8- "about",9- "above",10- "absent",11- "absorb",12- "abstract",13- "absurd",14- "abuse",15- "access",16- "accident",17- "account",18- "accuse",19- "achieve",20- "acid",21- "acoustic",22- "acquire",23- "across",24- "act",25- "action",26- "actor",27- "actress",28- "actual",29- "adapt",30- "add",31- "addict",32- "address",33- "adjust",34- "admit",35- "adult",36- "advance",37- "advice",38- "aerobic",39- "affair",40- "afford",41- "afraid",42- "again",43- "age",44- "agent",45- "agree",46- "ahead",47- "aim",48- "air",49- "airport",50- "aisle",51- "alarm",52- "album",53- "alcohol",54- "alert",55- "alien",56- "all",57- "alley",58- "allow",59- "almost",60- "alone",61- "alpha",62- "already",63- "also",64- "alter",65- "always",66- "amateur",67- "amazing",68- "among",69- "amount",70- "amused",71- "analyst",72- "anchor",73- "ancient",74- "anger",75- "angle",76- "angry",77- "animal",78- "ankle",79- "announce",80- "annual",81- "another",82- "answer",83- "antenna",84- "antique",85- "anxiety",86- "any",87- "apart",88- "apology",89- "appear",90- "apple",91- "approve",92- "april",93- "arch",94- "arctic",95- "area",96- "arena",97- "argue",98- "arm",99- "armed",100- "armor",101- "army",102- "around",103- "arrange",104- "arrest",105- "arrive",106- "arrow",107- "art",108- "artefact",109- "artist",110- "artwork",111- "ask",112- "aspect",113- "assault",114- "asset",115- "assist",116- "assume",117- "asthma",118- "athlete",119- "atom",120- "attack",121- "attend",122- "attitude",123- "attract",124- "auction",125- "audit",126- "august",127- "aunt",128- "author",129- "auto",130- "autumn",131- "average",132- "avocado",133- "avoid",134- "awake",135- "aware",136- "away",137- "awesome",138- "awful",139- "awkward",140- "axis",141- "baby",142- "bachelor",143- "bacon",144- "badge",145- "bag",146- "balance",147- "balcony",148- "ball",149- "bamboo",150- "banana",151- "banner",152- "bar",153- "barely",154- "bargain",155- "barrel",156- "base",157- "basic",158- "basket",159- "battle",160- "beach",161- "bean",162- "beauty",163- "because",164- "become",165- "beef",166- "before",167- "begin",168- "behave",169- "behind",170- "believe",171- "below",172- "belt",173- "bench",174- "benefit",175- "best",176- "betray",177- "better",178- "between",179- "beyond",180- "bicycle",181- "bid",182- "bike",183- "bind",184- "biology",185- "bird",186- "birth",187- "bitter",188- "black",189- "blade",190- "blame",191- "blanket",192- "blast",193- "bleak",194- "bless",195- "blind",196- "blood",197- "blossom",198- "blouse",199- "blue",200- "blur",201- "blush",202- "board",203- "boat",204- "body",205- "boil",206- "bomb",207- "bone",208- "bonus",209- "book",210- "boost",211- "border",212- "boring",213- "borrow",214- "boss",215- "bottom",216- "bounce",217- "box",218- "boy",219- "bracket",220- "brain",221- "brand",222- "brass",223- "brave",224- "bread",225- "breeze",226- "brick",227- "bridge",228- "brief",229- "bright",230- "bring",231- "brisk",232- "broccoli",233- "broken",234- "bronze",235- "broom",236- "brother",237- "brown",238- "brush",239- "bubble",240- "buddy",241- "budget",242- "buffalo",243- "build",244- "bulb",245- "bulk",246- "bullet",247- "bundle",248- "bunker",249- "burden",250- "burger",251- "burst",252- "bus",253- "business",254- "busy",255- "butter",256- "buyer",257- "buzz",258- "cabbage",259- "cabin",260- "cable",261- "cactus",262- "cage",263- "cake",264- "call",265- "calm",266- "camera",267- "camp",268- "can",269- "canal",270- "cancel",271- "candy",272- "cannon",273- "canoe",274- "canvas",275- "canyon",276- "capable",277- "capital",278- "captain",279- "car",280- "carbon",281- "card",282- "cargo",283- "carpet",284- "carry",285- "cart",286- "case",287- "cash",288- "casino",289- "castle",290- "casual",291- "cat",292- "catalog",293- "catch",294- "category",295- "cattle",296- "caught",297- "cause",298- "caution",299- "cave",300- "ceiling",301- "celery",302- "cement",303- "census",304- "century",305- "cereal",306- "certain",307- "chair",308- "chalk",309- "champion",310- "change",311- "chaos",312- "chapter",313- "charge",314- "chase",315- "chat",316- "cheap",317- "check",318- "cheese",319- "chef",320- "cherry",321- "chest",322- "chicken",323- "chief",324- "child",325- "chimney",326- "choice",327- "choose",328- "chronic",329- "chuckle",330- "chunk",331- "churn",332- "cigar",333- "cinnamon",334- "circle",335- "citizen",336- "city",337- "civil",338- "claim",339- "clap",340- "clarify",341- "claw",342- "clay",343- "clean",344- "clerk",345- "clever",346- "click",347- "client",348- "cliff",349- "climb",350- "clinic",351- "clip",352- "clock",353- "clog",354- "close",355- "cloth",356- "cloud",357- "clown",358- "club",359- "clump",360- "cluster",361- "clutch",362- "coach",363- "coast",364- "coconut",365- "code",366- "coffee",367- "coil",368- "coin",369- "collect",370- "color",371- "column",372- "combine",373- "come",374- "comfort",375- "comic",376- "common",377- "company",378- "concert",379- "conduct",380- "confirm",381- "congress",382- "connect",383- "consider",384- "control",385- "convince",386- "cook",387- "cool",388- "copper",389- "copy",390- "coral",391- "core",392- "corn",393- "correct",394- "cost",395- "cotton",396- "couch",397- "country",398- "couple",399- "course",400- "cousin",401- "cover",402- "coyote",403- "crack",404- "cradle",405- "craft",406- "cram",407- "crane",408- "crash",409- "crater",410- "crawl",411- "crazy",412- "cream",413- "credit",414- "creek",415- "crew",416- "cricket",417- "crime",418- "crisp",419- "critic",420- "crop",421- "cross",422- "crouch",423- "crowd",424- "crucial",425- "cruel",426- "cruise",427- "crumble",428- "crunch",429- "crush",430- "cry",431- "crystal",432- "cube",433- "culture",434- "cup",435- "cupboard",436- "curious",437- "current",438- "curtain",439- "curve",440- "cushion",441- "custom",442- "cute",443- "cycle",444- "dad",445- "damage",446- "damp",447- "dance",448- "danger",449- "daring",450- "dash",451- "daughter",452- "dawn",453- "day",454- "deal",455- "debate",456- "debris",457- "decade",458- "december",459- "decide",460- "decline",461- "decorate",462- "decrease",463- "deer",464- "defense",465- "define",466- "defy",467- "degree",468- "delay",469- "deliver",470- "demand",471- "demise",472- "denial",473- "dentist",474- "deny",475- "depart",476- "depend",477- "deposit",478- "depth",479- "deputy",480- "derive",481- "describe",482- "desert",483- "design",484- "desk",485- "despair",486- "destroy",487- "detail",488- "detect",489- "develop",490- "device",491- "devote",492- "diagram",493- "dial",494- "diamond",495- "diary",496- "dice",497- "diesel",498- "diet",499- "differ",500- "digital",501- "dignity",502- "dilemma",503- "dinner",504- "dinosaur",505- "direct",506- "dirt",507- "disagree",508- "discover",509- "disease",510- "dish",511- "dismiss",512- "disorder",513- "display",514- "distance",515- "divert",516- "divide",517- "divorce",518- "dizzy",519- "doctor",520- "document",521- "dog",522- "doll",523- "dolphin",524- "domain",525- "donate",526- "donkey",527- "donor",528- "door",529- "dose",530- "double",531- "dove",532- "draft",533- "dragon",534- "drama",535- "drastic",536- "draw",537- "dream",538- "dress",539- "drift",540- "drill",541- "drink",542- "drip",543- "drive",544- "drop",545- "drum",546- "dry",547- "duck",548- "dumb",549- "dune",550- "during",551- "dust",552- "dutch",553- "duty",554- "dwarf",555- "dynamic",556- "eager",557- "eagle",558- "early",559- "earn",560- "earth",561- "easily",562- "east",563- "easy",564- "echo",565- "ecology",566- "economy",567- "edge",568- "edit",569- "educate",570- "effort",571- "egg",572- "eight",573- "either",574- "elbow",575- "elder",576- "electric",577- "elegant",578- "element",579- "elephant",580- "elevator",581- "elite",582- "else",583- "embark",584- "embody",585- "embrace",586- "emerge",587- "emotion",588- "employ",589- "empower",590- "empty",591- "enable",592- "enact",593- "end",594- "endless",595- "endorse",596- "enemy",597- "energy",598- "enforce",599- "engage",600- "engine",601- "enhance",602- "enjoy",603- "enlist",604- "enough",605- "enrich",606- "enroll",607- "ensure",608- "enter",609- "entire",610- "entry",611- "envelope",612- "episode",613- "equal",614- "equip",615- "era",616- "erase",617- "erode",618- "erosion",619- "error",620- "erupt",621- "escape",622- "essay",623- "essence",624- "estate",625- "eternal",626- "ethics",627- "evidence",628- "evil",629- "evoke",630- "evolve",631- "exact",632- "example",633- "excess",634- "exchange",635- "excite",636- "exclude",637- "excuse",638- "execute",639- "exercise",640- "exhaust",641- "exhibit",642- "exile",643- "exist",644- "exit",645- "exotic",646- "expand",647- "expect",648- "expire",649- "explain",650- "expose",651- "express",652- "extend",653- "extra",654- "eye",655- "eyebrow",656- "fabric",657- "face",658- "faculty",659- "fade",660- "faint",661- "faith",662- "fall",663- "false",664- "fame",665- "family",666- "famous",667- "fan",668- "fancy",669- "fantasy",670- "farm",671- "fashion",672- "fat",673- "fatal",674- "father",675- "fatigue",676- "fault",677- "favorite",678- "feature",679- "february",680- "federal",681- "fee",682- "feed",683- "feel",684- "female",685- "fence",686- "festival",687- "fetch",688- "fever",689- "few",690- "fiber",691- "fiction",692- "field",693- "figure",694- "file",695- "film",696- "filter",697- "final",698- "find",699- "fine",700- "finger",701- "finish",702- "fire",703- "firm",704- "first",705- "fiscal",706- "fish",707- "fit",708- "fitness",709- "fix",710- "flag",711- "flame",712- "flash",713- "flat",714- "flavor",715- "flee",716- "flight",717- "flip",718- "float",719- "flock",720- "floor",721- "flower",722- "fluid",723- "flush",724- "fly",725- "foam",726- "focus",727- "fog",728- "foil",729- "fold",730- "follow",731- "food",732- "foot",733- "force",734- "forest",735- "forget",736- "fork",737- "fortune",738- "forum",739- "forward",740- "fossil",741- "foster",742- "found",743- "fox",744- "fragile",745- "frame",746- "frequent",747- "fresh",748- "friend",749- "fringe",750- "frog",751- "front",752- "frost",753- "frown",754- "frozen",755- "fruit",756- "fuel",757- "fun",758- "funny",759- "furnace",760- "fury",761- "future",762- "gadget",763- "gain",764- "galaxy",765- "gallery",766- "game",767- "gap",768- "garage",769- "garbage",770- "garden",771- "garlic",772- "garment",773- "gas",774- "gasp",775- "gate",776- "gather",777- "gauge",778- "gaze",779- "general",780- "genius",781- "genre",782- "gentle",783- "genuine",784- "gesture",785- "ghost",786- "giant",787- "gift",788- "giggle",789- "ginger",790- "giraffe",791- "girl",792- "give",793- "glad",794- "glance",795- "glare",796- "glass",797- "glide",798- "glimpse",799- "globe",800- "gloom",801- "glory",802- "glove",803- "glow",804- "glue",805- "goat",806- "goddess",807- "gold",808- "good",809- "goose",810- "gorilla",811- "gospel",812- "gossip",813- "govern",814- "gown",815- "grab",816- "grace",817- "grain",818- "grant",819- "grape",820- "grass",821- "gravity",822- "great",823- "green",824- "grid",825- "grief",826- "grit",827- "grocery",828- "group",829- "grow",830- "grunt",831- "guard",832- "guess",833- "guide",834- "guilt",835- "guitar",836- "gun",837- "gym",838- "habit",839- "hair",840- "half",841- "hammer",842- "hamster",843- "hand",844- "happy",845- "harbor",846- "hard",847- "harsh",848- "harvest",849- "hat",850- "have",851- "hawk",852- "hazard",853- "head",854- "health",855- "heart",856- "heavy",857- "hedgehog",858- "height",859- "hello",860- "helmet",861- "help",862- "hen",863- "hero",864- "hidden",865- "high",866- "hill",867- "hint",868- "hip",869- "hire",870- "history",871- "hobby",872- "hockey",873- "hold",874- "hole",875- "holiday",876- "hollow",877- "home",878- "honey",879- "hood",880- "hope",881- "horn",882- "horror",883- "horse",884- "hospital",885- "host",886- "hotel",887- "hour",888- "hover",889- "hub",890- "huge",891- "human",892- "humble",893- "humor",894- "hundred",895- "hungry",896- "hunt",897- "hurdle",898- "hurry",899- "hurt",900- "husband",901- "hybrid",902- "ice",903- "icon",904- "idea",905- "identify",906- "idle",907- "ignore",908- "ill",909- "illegal",910- "illness",911- "image",912- "imitate",913- "immense",914- "immune",915- "impact",916- "impose",917- "improve",918- "impulse",919- "inch",920- "include",921- "income",922- "increase",923- "index",924- "indicate",925- "indoor",926- "industry",927- "infant",928- "inflict",929- "inform",930- "inhale",931- "inherit",932- "initial",933- "inject",934- "injury",935- "inmate",936- "inner",937- "innocent",938- "input",939- "inquiry",940- "insane",941- "insect",942- "inside",943- "inspire",944- "install",945- "intact",946- "interest",947- "into",948- "invest",949- "invite",950- "involve",951- "iron",952- "island",953- "isolate",954- "issue",955- "item",956- "ivory",957- "jacket",958- "jaguar",959- "jar",960- "jazz",961- "jealous",962- "jeans",963- "jelly",964- "jewel",965- "job",966- "join",967- "joke",968- "journey",969- "joy",970- "judge",971- "juice",972- "jump",973- "jungle",974- "junior",975- "junk",976- "just",977- "kangaroo",978- "keen",979- "keep",980- "ketchup",981- "key",982- "kick",983- "kid",984- "kidney",985- "kind",986- "kingdom",987- "kiss",988- "kit",989- "kitchen",990- "kite",991- "kitten",992- "kiwi",993- "knee",994- "knife",995- "knock",996- "know",997- "lab",998- "label",999- "labor",1000- "ladder",1001- "lady",1002- "lake",1003- "lamp",1004- "language",1005- "laptop",1006- "large",1007- "later",1008- "latin",1009- "laugh",1010- "laundry",1011- "lava",1012- "law",1013- "lawn",1014- "lawsuit",1015- "layer",1016- "lazy",1017- "leader",1018- "leaf",1019- "learn",1020- "leave",1021- "lecture",1022- "left",1023- "leg",1024- "legal",1025- "legend",1026- "leisure",1027- "lemon",1028- "lend",1029- "length",1030- "lens",1031- "leopard",1032- "lesson",1033- "letter",1034- "level",1035- "liar",1036- "liberty",1037- "library",1038- "license",1039- "life",1040- "lift",1041- "light",1042- "like",1043- "limb",1044- "limit",1045- "link",1046- "lion",1047- "liquid",1048- "list",1049- "little",1050- "live",1051- "lizard",1052- "load",1053- "loan",1054- "lobster",1055- "local",1056- "lock",1057- "logic",1058- "lonely",1059- "long",1060- "loop",1061- "lottery",1062- "loud",1063- "lounge",1064- "love",1065- "loyal",1066- "lucky",1067- "luggage",1068- "lumber",1069- "lunar",1070- "lunch",1071- "luxury",1072- "lyrics",1073- "machine",1074- "mad",1075- "magic",1076- "magnet",1077- "maid",1078- "mail",1079- "main",1080- "major",1081- "make",1082- "mammal",1083- "man",1084- "manage",1085- "mandate",1086- "mango",1087- "mansion",1088- "manual",1089- "maple",1090- "marble",1091- "march",1092- "margin",1093- "marine",1094- "market",1095- "marriage",1096- "mask",1097- "mass",1098- "master",1099- "match",1100- "material",1101- "math",1102- "matrix",1103- "matter",1104- "maximum",1105- "maze",1106- "meadow",1107- "mean",1108- "measure",1109- "meat",1110- "mechanic",1111- "medal",1112- "media",1113- "melody",1114- "melt",1115- "member",1116- "memory",1117- "mention",1118- "menu",1119- "mercy",1120- "merge",1121- "merit",1122- "merry",1123- "mesh",1124- "message",1125- "metal",1126- "method",1127- "middle",1128- "midnight",1129- "milk",1130- "million",1131- "mimic",1132- "mind",1133- "minimum",1134- "minor",1135- "minute",1136- "miracle",1137- "mirror",1138- "misery",1139- "miss",1140- "mistake",1141- "mix",1142- "mixed",1143- "mixture",1144- "mobile",1145- "model",1146- "modify",1147- "mom",1148- "moment",1149- "monitor",1150- "monkey",1151- "monster",1152- "month",1153- "moon",1154- "moral",1155- "more",1156- "morning",1157- "mosquito",1158- "mother",1159- "motion",1160- "motor",1161- "mountain",1162- "mouse",1163- "move",1164- "movie",1165- "much",1166- "muffin",1167- "mule",1168- "multiply",1169- "muscle",1170- "museum",1171- "mushroom",1172- "music",1173- "must",1174- "mutual",1175- "myself",1176- "mystery",1177- "myth",1178- "naive",1179- "name",1180- "napkin",1181- "narrow",1182- "nasty",1183- "nation",1184- "nature",1185- "near",1186- "neck",1187- "need",1188- "negative",1189- "neglect",1190- "neither",1191- "nephew",1192- "nerve",1193- "nest",1194- "net",1195- "network",1196- "neutral",1197- "never",1198- "news",1199- "next",1200- "nice",1201- "night",1202- "noble",1203- "noise",1204- "nominee",1205- "noodle",1206- "normal",1207- "north",1208- "nose",1209- "notable",1210- "note",1211- "nothing",1212- "notice",1213- "novel",1214- "now",1215- "nuclear",1216- "number",1217- "nurse",1218- "nut",1219- "oak",1220- "obey",1221- "object",1222- "oblige",1223- "obscure",1224- "observe",1225- "obtain",1226- "obvious",1227- "occur",1228- "ocean",1229- "october",1230- "odor",1231- "off",1232- "offer",1233- "office",1234- "often",1235- "oil",1236- "okay",1237- "old",1238- "olive",1239- "olympic",1240- "omit",1241- "once",1242- "one",1243- "onion",1244- "online",1245- "only",1246- "open",1247- "opera",1248- "opinion",1249- "oppose",1250- "option",1251- "orange",1252- "orbit",1253- "orchard",1254- "order",1255- "ordinary",1256- "organ",1257- "orient",1258- "original",1259- "orphan",1260- "ostrich",1261- "other",1262- "outdoor",1263- "outer",1264- "output",1265- "outside",1266- "oval",1267- "oven",1268- "over",1269- "own",1270- "owner",1271- "oxygen",1272- "oyster",1273- "ozone",1274- "pact",1275- "paddle",1276- "page",1277- "pair",1278- "palace",1279- "palm",1280- "panda",1281- "panel",1282- "panic",1283- "panther",1284- "paper",1285- "parade",1286- "parent",1287- "park",1288- "parrot",1289- "party",1290- "pass",1291- "patch",1292- "path",1293- "patient",1294- "patrol",1295- "pattern",1296- "pause",1297- "pave",1298- "payment",1299- "peace",1300- "peanut",1301- "pear",1302- "peasant",1303- "pelican",1304- "pen",1305- "penalty",1306- "pencil",1307- "people",1308- "pepper",1309- "perfect",1310- "permit",1311- "person",1312- "pet",1313- "phone",1314- "photo",1315- "phrase",1316- "physical",1317- "piano",1318- "picnic",1319- "picture",1320- "piece",1321- "pig",1322- "pigeon",1323- "pill",1324- "pilot",1325- "pink",1326- "pioneer",1327- "pipe",1328- "pistol",1329- "pitch",1330- "pizza",1331- "place",1332- "planet",1333- "plastic",1334- "plate",1335- "play",1336- "please",1337- "pledge",1338- "pluck",1339- "plug",1340- "plunge",1341- "poem",1342- "poet",1343- "point",1344- "polar",1345- "pole",1346- "police",1347- "pond",1348- "pony",1349- "pool",1350- "popular",1351- "portion",1352- "position",1353- "possible",1354- "post",1355- "potato",1356- "pottery",1357- "poverty",1358- "powder",1359- "power",1360- "practice",1361- "praise",1362- "predict",1363- "prefer",1364- "prepare",1365- "present",1366- "pretty",1367- "prevent",1368- "price",1369- "pride",1370- "primary",1371- "print",1372- "priority",1373- "prison",1374- "private",1375- "prize",1376- "problem",1377- "process",1378- "produce",1379- "profit",1380- "program",1381- "project",1382- "promote",1383- "proof",1384- "property",1385- "prosper",1386- "protect",1387- "proud",1388- "provide",1389- "public",1390- "pudding",1391- "pull",1392- "pulp",1393- "pulse",1394- "pumpkin",1395- "punch",1396- "pupil",1397- "puppy",1398- "purchase",1399- "purity",1400- "purpose",1401- "purse",1402- "push",1403- "put",1404- "puzzle",1405- "pyramid",1406- "quality",1407- "quantum",1408- "quarter",1409- "question",1410- "quick",1411- "quit",1412- "quiz",1413- "quote",1414- "rabbit",1415- "raccoon",1416- "race",1417- "rack",1418- "radar",1419- "radio",1420- "rail",1421- "rain",1422- "raise",1423- "rally",1424- "ramp",1425- "ranch",1426- "random",1427- "range",1428- "rapid",1429- "rare",1430- "rate",1431- "rather",1432- "raven",1433- "raw",1434- "razor",1435- "ready",1436- "real",1437- "reason",1438- "rebel",1439- "rebuild",1440- "recall",1441- "receive",1442- "recipe",1443- "record",1444- "recycle",1445- "reduce",1446- "reflect",1447- "reform",1448- "refuse",1449- "region",1450- "regret",1451- "regular",1452- "reject",1453- "relax",1454- "release",1455- "relief",1456- "rely",1457- "remain",1458- "remember",1459- "remind",1460- "remove",1461- "render",1462- "renew",1463- "rent",1464- "reopen",1465- "repair",1466- "repeat",1467- "replace",1468- "report",1469- "require",1470- "rescue",1471- "resemble",1472- "resist",1473- "resource",1474- "response",1475- "result",1476- "retire",1477- "retreat",1478- "return",1479- "reunion",1480- "reveal",1481- "review",1482- "reward",1483- "rhythm",1484- "rib",1485- "ribbon",1486- "rice",1487- "rich",1488- "ride",1489- "ridge",1490- "rifle",1491- "right",1492- "rigid",1493- "ring",1494- "riot",1495- "ripple",1496- "risk",1497- "ritual",1498- "rival",1499- "river",1500- "road",1501- "roast",1502- "robot",1503- "robust",1504- "rocket",1505- "romance",1506- "roof",1507- "rookie",1508- "room",1509- "rose",1510- "rotate",1511- "rough",1512- "round",1513- "route",1514- "royal",1515- "rubber",1516- "rude",1517- "rug",1518- "rule",1519- "run",1520- "runway",1521- "rural",1522- "sad",1523- "saddle",1524- "sadness",1525- "safe",1526- "sail",1527- "salad",1528- "salmon",1529- "salon",1530- "salt",1531- "salute",1532- "same",1533- "sample",1534- "sand",1535- "satisfy",1536- "satoshi",1537- "sauce",1538- "sausage",1539- "save",1540- "say",1541- "scale",1542- "scan",1543- "scare",1544- "scatter",1545- "scene",1546- "scheme",1547- "school",1548- "science",1549- "scissors",1550- "scorpion",1551- "scout",1552- "scrap",1553- "screen",1554- "script",1555- "scrub",1556- "sea",1557- "search",1558- "season",1559- "seat",1560- "second",1561- "secret",1562- "section",1563- "security",1564- "seed",1565- "seek",1566- "segment",1567- "select",1568- "sell",1569- "seminar",1570- "senior",1571- "sense",1572- "sentence",1573- "series",1574- "service",1575- "session",1576- "settle",1577- "setup",1578- "seven",1579- "shadow",1580- "shaft",1581- "shallow",1582- "share",1583- "shed",1584- "shell",1585- "sheriff",1586- "shield",1587- "shift",1588- "shine",1589- "ship",1590- "shiver",1591- "shock",1592- "shoe",1593- "shoot",1594- "shop",1595- "short",1596- "shoulder",1597- "shove",1598- "shrimp",1599- "shrug",1600- "shuffle",1601- "shy",1602- "sibling",1603- "sick",1604- "side",1605- "siege",1606- "sight",1607- "sign",1608- "silent",1609- "silk",1610- "silly",1611- "silver",1612- "similar",1613- "simple",1614- "since",1615- "sing",1616- "siren",1617- "sister",1618- "situate",1619- "six",1620- "size",1621- "skate",1622- "sketch",1623- "ski",1624- "skill",1625- "skin",1626- "skirt",1627- "skull",1628- "slab",1629- "slam",1630- "sleep",1631- "slender",1632- "slice",1633- "slide",1634- "slight",1635- "slim",1636- "slogan",1637- "slot",1638- "slow",1639- "slush",1640- "small",1641- "smart",1642- "smile",1643- "smoke",1644- "smooth",1645- "snack",1646- "snake",1647- "snap",1648- "sniff",1649- "snow",1650- "soap",1651- "soccer",1652- "social",1653- "sock",1654- "soda",1655- "soft",1656- "solar",1657- "soldier",1658- "solid",1659- "solution",1660- "solve",1661- "someone",1662- "song",1663- "soon",1664- "sorry",1665- "sort",1666- "soul",1667- "sound",1668- "soup",1669- "source",1670- "south",1671- "space",1672- "spare",1673- "spatial",1674- "spawn",1675- "speak",1676- "special",1677- "speed",1678- "spell",1679- "spend",1680- "sphere",1681- "spice",1682- "spider",1683- "spike",1684- "spin",1685- "spirit",1686- "split",1687- "spoil",1688- "sponsor",1689- "spoon",1690- "sport",1691- "spot",1692- "spray",1693- "spread",1694- "spring",1695- "spy",1696- "square",1697- "squeeze",1698- "squirrel",1699- "stable",1700- "stadium",1701- "staff",1702- "stage",1703- "stairs",1704- "stamp",1705- "stand",1706- "start",1707- "state",1708- "stay",1709- "steak",1710- "steel",1711- "stem",1712- "step",1713- "stereo",1714- "stick",1715- "still",1716- "sting",1717- "stock",1718- "stomach",1719- "stone",1720- "stool",1721- "story",1722- "stove",1723- "strategy",1724- "street",1725- "strike",1726- "strong",1727- "struggle",1728- "student",1729- "stuff",1730- "stumble",1731- "style",1732- "subject",1733- "submit",1734- "subway",1735- "success",1736- "such",1737- "sudden",1738- "suffer",1739- "sugar",1740- "suggest",1741- "suit",1742- "summer",1743- "sun",1744- "sunny",1745- "sunset",1746- "super",1747- "supply",1748- "supreme",1749- "sure",1750- "surface",1751- "surge",1752- "surprise",1753- "surround",1754- "survey",1755- "suspect",1756- "sustain",1757- "swallow",1758- "swamp",1759- "swap",1760- "swarm",1761- "swear",1762- "sweet",1763- "swift",1764- "swim",1765- "swing",1766- "switch",1767- "sword",1768- "symbol",1769- "symptom",1770- "syrup",1771- "system",1772- "table",1773- "tackle",1774- "tag",1775- "tail",1776- "talent",1777- "talk",1778- "tank",1779- "tape",1780- "target",1781- "task",1782- "taste",1783- "tattoo",1784- "taxi",1785- "teach",1786- "team",1787- "tell",1788- "ten",1789- "tenant",1790- "tennis",1791- "tent",1792- "term",1793- "test",1794- "text",1795- "thank",1796- "that",1797- "theme",1798- "then",1799- "theory",1800- "there",1801- "they",1802- "thing",1803- "this",1804- "thought",1805- "three",1806- "thrive",1807- "throw",1808- "thumb",1809- "thunder",1810- "ticket",1811- "tide",1812- "tiger",1813- "tilt",1814- "timber",1815- "time",1816- "tiny",1817- "tip",1818- "tired",1819- "tissue",1820- "title",1821- "toast",1822- "tobacco",1823- "today",1824- "toddler",1825- "toe",1826- "together",1827- "toilet",1828- "token",1829- "tomato",1830- "tomorrow",1831- "tone",1832- "tongue",1833- "tonight",1834- "tool",1835- "tooth",1836- "top",1837- "topic",1838- "topple",1839- "torch",1840- "tornado",1841- "tortoise",1842- "toss",1843- "total",1844- "tourist",1845- "toward",1846- "tower",1847- "town",1848- "toy",1849- "track",1850- "trade",1851- "traffic",1852- "tragic",1853- "train",1854- "transfer",1855- "trap",1856- "trash",1857- "travel",1858- "tray",1859- "treat",1860- "tree",1861- "trend",1862- "trial",1863- "tribe",1864- "trick",1865- "trigger",1866- "trim",1867- "trip",1868- "trophy",1869- "trouble",1870- "truck",1871- "true",1872- "truly",1873- "trumpet",1874- "trust",1875- "truth",1876- "try",1877- "tube",1878- "tuition",1879- "tumble",1880- "tuna",1881- "tunnel",1882- "turkey",1883- "turn",1884- "turtle",1885- "twelve",1886- "twenty",1887- "twice",1888- "twin",1889- "twist",1890- "two",1891- "type",1892- "typical",1893- "ugly",1894- "umbrella",1895- "unable",1896- "unaware",1897- "uncle",1898- "uncover",1899- "under",1900- "undo",1901- "unfair",1902- "unfold",1903- "unhappy",1904- "uniform",1905- "unique",1906- "unit",1907- "universe",1908- "unknown",1909- "unlock",1910- "until",1911- "unusual",1912- "unveil",1913- "update",1914- "upgrade",1915- "uphold",1916- "upon",1917- "upper",1918- "upset",1919- "urban",1920- "urge",1921- "usage",1922- "use",1923- "used",1924- "useful",1925- "useless",1926- "usual",1927- "utility",1928- "vacant",1929- "vacuum",1930- "vague",1931- "valid",1932- "valley",1933- "valve",1934- "van",1935- "vanish",1936- "vapor",1937- "various",1938- "vast",1939- "vault",1940- "vehicle",1941- "velvet",1942- "vendor",1943- "venture",1944- "venue",1945- "verb",1946- "verify",1947- "version",1948- "very",1949- "vessel",1950- "veteran",1951- "viable",1952- "vibrant",1953- "vicious",1954- "victory",1955- "video",1956- "view",1957- "village",1958- "vintage",1959- "violin",1960- "virtual",1961- "virus",1962- "visa",1963- "visit",1964- "visual",1965- "vital",1966- "vivid",1967- "vocal",1968- "voice",1969- "void",1970- "volcano",1971- "volume",1972- "vote",1973- "voyage",1974- "wage",1975- "wagon",1976- "wait",1977- "walk",1978- "wall",1979- "walnut",1980- "want",1981- "warfare",1982- "warm",1983- "warrior",1984- "wash",1985- "wasp",1986- "waste",1987- "water",1988- "wave",1989- "way",1990- "wealth",1991- "weapon",1992- "wear",1993- "weasel",1994- "weather",1995- "web",1996- "wedding",1997- "weekend",1998- "weird",1999- "welcome",2000- "west",2001- "wet",2002- "whale",2003- "what",2004- "wheat",2005- "wheel",2006- "when",2007- "where",2008- "whip",2009- "whisper",2010- "wide",2011- "width",2012- "wife",2013- "wild",2014- "will",2015- "win",2016- "window",2017- "wine",2018- "wing",2019- "wink",2020- "winner",2021- "winter",2022- "wire",2023- "wisdom",2024- "wise",2025- "wish",2026- "witness",2027- "wolf",2028- "woman",2029- "wonder",2030- "wood",2031- "wool",2032- "word",2033- "work",2034- "world",2035- "worry",2036- "worth",2037- "wrap",2038- "wreck",2039- "wrestle",2040- "wrist",2041- "write",2042- "wrong",2043- "yard",2044- "year",2045- "yellow",2046- "you",2047- "young",2048- "youth",2049- "zebra",2050- "zero",2051- "zone",3+/**4+ * Recovery word list — byte-identical to the browser's5+ * `src/shared/recovery-word-list.ts`: the canonical 2048-word BIP39 English6+ * list, 0-indexed, no duplicates.7+ *8+ * This MUST stay identical to the browser's list. Words are only a human9+ * readable encoding of the root key's first 16 bytes, so any divergence in10+ * ordering means the same vault prints different words on each platform and a11+ * phrase written down on one device restores nothing on the other.12+ * `CrossPlatformRecoveryWordsTest` pins that with a shared vector.13+ */14+val WORD_LIST: List<String> = listOf(15+ "abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract",16+ "absurd", "abuse", "access", "accident", "account", "accuse", "achieve", "acid",17+ "acoustic", "acquire", "across", "act", "action", "actor", "actress", "actual",18+ "adapt", "add", "addict", "address", "adjust", "admit", "adult", "advance",19+ "advice", "aerobic", "affair", "afford", "afraid", "again", "age", "agent",20+ "agree", "ahead", "aim", "air", "airport", "aisle", "alarm", "album",21+ "alcohol", "alert", "alien", "all", "alley", "allow", "almost", "alone",22+ "alpha", "already", "also", "alter", "always", "amateur", "amazing", "among",23+ "amount", "amused", "analyst", "anchor", "ancient", "anger", "angle", "angry",24+ "animal", "ankle", "announce", "annual", "another", "answer", "antenna", "antique",25+ "anxiety", "any", "apart", "apology", "appear", "apple", "approve", "april",26+ "arch", "arctic", "area", "arena", "argue", "arm", "armed", "armor",27+ "army", "around", "arrange", "arrest", "arrive", "arrow", "art", "artefact",28+ "artist", "artwork", "ask", "aspect", "assault", "asset", "assist", "assume",29+ "asthma", "athlete", "atom", "attack", "attend", "attitude", "attract", "auction",30+ "audit", "august", "aunt", "author", "auto", "autumn", "average", "avocado",31+ "avoid", "awake", "aware", "away", "awesome", "awful", "awkward", "axis",32+ "baby", "bachelor", "bacon", "badge", "bag", "balance", "balcony", "ball",33+ "bamboo", "banana", "banner", "bar", "barely", "bargain", "barrel", "base",34+ "basic", "basket", "battle", "beach", "bean", "beauty", "because", "become",35+ "beef", "before", "begin", "behave", "behind", "believe", "below", "belt",36+ "bench", "benefit", "best", "betray", "better", "between", "beyond", "bicycle",37+ "bid", "bike", "bind", "biology", "bird", "birth", "bitter", "black",38+ "blade", "blame", "blanket", "blast", "bleak", "bless", "blind", "blood",39+ "blossom", "blouse", "blue", "blur", "blush", "board", "boat", "body",40+ "boil", "bomb", "bone", "bonus", "book", "boost", "border", "boring",41+ "borrow", "boss", "bottom", "bounce", "box", "boy", "bracket", "brain",42+ "brand", "brass", "brave", "bread", "breeze", "brick", "bridge", "brief",43+ "bright", "bring", "brisk", "broccoli", "broken", "bronze", "broom", "brother",44+ "brown", "brush", "bubble", "buddy", "budget", "buffalo", "build", "bulb",45+ "bulk", "bullet", "bundle", "bunker", "burden", "burger", "burst", "bus",46+ "business", "busy", "butter", "buyer", "buzz", "cabbage", "cabin", "cable",47+ "cactus", "cage", "cake", "call", "calm", "camera", "camp", "can",48+ "canal", "cancel", "candy", "cannon", "canoe", "canvas", "canyon", "capable",49+ "capital", "captain", "car", "carbon", "card", "cargo", "carpet", "carry",50+ "cart", "case", "cash", "casino", "castle", "casual", "cat", "catalog",51+ "catch", "category", "cattle", "caught", "cause", "caution", "cave", "ceiling",52+ "celery", "cement", "census", "century", "cereal", "certain", "chair", "chalk",53+ "champion", "change", "chaos", "chapter", "charge", "chase", "chat", "cheap",54+ "check", "cheese", "chef", "cherry", "chest", "chicken", "chief", "child",55+ "chimney", "choice", "choose", "chronic", "chuckle", "chunk", "churn", "cigar",56+ "cinnamon", "circle", "citizen", "city", "civil", "claim", "clap", "clarify",57+ "claw", "clay", "clean", "clerk", "clever", "click", "client", "cliff",58+ "climb", "clinic", "clip", "clock", "clog", "close", "cloth", "cloud",59+ "clown", "club", "clump", "cluster", "clutch", "coach", "coast", "coconut",60+ "code", "coffee", "coil", "coin", "collect", "color", "column", "combine",61+ "come", "comfort", "comic", "common", "company", "concert", "conduct", "confirm",62+ "congress", "connect", "consider", "control", "convince", "cook", "cool", "copper",63+ "copy", "coral", "core", "corn", "correct", "cost", "cotton", "couch",64+ "country", "couple", "course", "cousin", "cover", "coyote", "crack", "cradle",65+ "craft", "cram", "crane", "crash", "crater", "crawl", "crazy", "cream",66+ "credit", "creek", "crew", "cricket", "crime", "crisp", "critic", "crop",67+ "cross", "crouch", "crowd", "crucial", "cruel", "cruise", "crumble", "crunch",68+ "crush", "cry", "crystal", "cube", "culture", "cup", "cupboard", "curious",69+ "current", "curtain", "curve", "cushion", "custom", "cute", "cycle", "dad",70+ "damage", "damp", "dance", "danger", "daring", "dash", "daughter", "dawn",71+ "day", "deal", "debate", "debris", "decade", "december", "decide", "decline",72+ "decorate", "decrease", "deer", "defense", "define", "defy", "degree", "delay",73+ "deliver", "demand", "demise", "denial", "dentist", "deny", "depart", "depend",74+ "deposit", "depth", "deputy", "derive", "describe", "desert", "design", "desk",75+ "despair", "destroy", "detail", "detect", "develop", "device", "devote", "diagram",76+ "dial", "diamond", "diary", "dice", "diesel", "diet", "differ", "digital",77+ "dignity", "dilemma", "dinner", "dinosaur", "direct", "dirt", "disagree", "discover",78+ "disease", "dish", "dismiss", "disorder", "display", "distance", "divert", "divide",79+ "divorce", "dizzy", "doctor", "document", "dog", "doll", "dolphin", "domain",80+ "donate", "donkey", "donor", "door", "dose", "double", "dove", "draft",81+ "dragon", "drama", "drastic", "draw", "dream", "dress", "drift", "drill",82+ "drink", "drip", "drive", "drop", "drum", "dry", "duck", "dumb",83+ "dune", "during", "dust", "dutch", "duty", "dwarf", "dynamic", "eager",84+ "eagle", "early", "earn", "earth", "easily", "east", "easy", "echo",85+ "ecology", "economy", "edge", "edit", "educate", "effort", "egg", "eight",86+ "either", "elbow", "elder", "electric", "elegant", "element", "elephant", "elevator",87+ "elite", "else", "embark", "embody", "embrace", "emerge", "emotion", "employ",88+ "empower", "empty", "enable", "enact", "end", "endless", "endorse", "enemy",89+ "energy", "enforce", "engage", "engine", "enhance", "enjoy", "enlist", "enough",90+ "enrich", "enroll", "ensure", "enter", "entire", "entry", "envelope", "episode",91+ "equal", "equip", "era", "erase", "erode", "erosion", "error", "erupt",92+ "escape", "essay", "essence", "estate", "eternal", "ethics", "evidence", "evil",93+ "evoke", "evolve", "exact", "example", "excess", "exchange", "excite", "exclude",94+ "excuse", "execute", "exercise", "exhaust", "exhibit", "exile", "exist", "exit",95+ "exotic", "expand", "expect", "expire", "explain", "expose", "express", "extend",96+ "extra", "eye", "eyebrow", "fabric", "face", "faculty", "fade", "faint",97+ "faith", "fall", "false", "fame", "family", "famous", "fan", "fancy",98+ "fantasy", "farm", "fashion", "fat", "fatal", "father", "fatigue", "fault",99+ "favorite", "feature", "february", "federal", "fee", "feed", "feel", "female",100+ "fence", "festival", "fetch", "fever", "few", "fiber", "fiction", "field",101+ "figure", "file", "film", "filter", "final", "find", "fine", "finger",102+ "finish", "fire", "firm", "first", "fiscal", "fish", "fit", "fitness",103+ "fix", "flag", "flame", "flash", "flat", "flavor", "flee", "flight",104+ "flip", "float", "flock", "floor", "flower", "fluid", "flush", "fly",105+ "foam", "focus", "fog", "foil", "fold", "follow", "food", "foot",106+ "force", "forest", "forget", "fork", "fortune", "forum", "forward", "fossil",107+ "foster", "found", "fox", "fragile", "frame", "frequent", "fresh", "friend",108+ "fringe", "frog", "front", "frost", "frown", "frozen", "fruit", "fuel",109+ "fun", "funny", "furnace", "fury", "future", "gadget", "gain", "galaxy",110+ "gallery", "game", "gap", "garage", "garbage", "garden", "garlic", "garment",111+ "gas", "gasp", "gate", "gather", "gauge", "gaze", "general", "genius",112+ "genre", "gentle", "genuine", "gesture", "ghost", "giant", "gift", "giggle",113+ "ginger", "giraffe", "girl", "give", "glad", "glance", "glare", "glass",114+ "glide", "glimpse", "globe", "gloom", "glory", "glove", "glow", "glue",115+ "goat", "goddess", "gold", "good", "goose", "gorilla", "gospel", "gossip",116+ "govern", "gown", "grab", "grace", "grain", "grant", "grape", "grass",117+ "gravity", "great", "green", "grid", "grief", "grit", "grocery", "group",118+ "grow", "grunt", "guard", "guess", "guide", "guilt", "guitar", "gun",119+ "gym", "habit", "hair", "half", "hammer", "hamster", "hand", "happy",120+ "harbor", "hard", "harsh", "harvest", "hat", "have", "hawk", "hazard",121+ "head", "health", "heart", "heavy", "hedgehog", "height", "hello", "helmet",122+ "help", "hen", "hero", "hidden", "high", "hill", "hint", "hip",123+ "hire", "history", "hobby", "hockey", "hold", "hole", "holiday", "hollow",124+ "home", "honey", "hood", "hope", "horn", "horror", "horse", "hospital",125+ "host", "hotel", "hour", "hover", "hub", "huge", "human", "humble",126+ "humor", "hundred", "hungry", "hunt", "hurdle", "hurry", "hurt", "husband",127+ "hybrid", "ice", "icon", "idea", "identify", "idle", "ignore", "ill",128+ "illegal", "illness", "image", "imitate", "immense", "immune", "impact", "impose",129+ "improve", "impulse", "inch", "include", "income", "increase", "index", "indicate",130+ "indoor", "industry", "infant", "inflict", "inform", "inhale", "inherit", "initial",131+ "inject", "injury", "inmate", "inner", "innocent", "input", "inquiry", "insane",132+ "insect", "inside", "inspire", "install", "intact", "interest", "into", "invest",133+ "invite", "involve", "iron", "island", "isolate", "issue", "item", "ivory",134+ "jacket", "jaguar", "jar", "jazz", "jealous", "jeans", "jelly", "jewel",135+ "job", "join", "joke", "journey", "joy", "judge", "juice", "jump",136+ "jungle", "junior", "junk", "just", "kangaroo", "keen", "keep", "ketchup",137+ "key", "kick", "kid", "kidney", "kind", "kingdom", "kiss", "kit",138+ "kitchen", "kite", "kitten", "kiwi", "knee", "knife", "knock", "know",139+ "lab", "label", "labor", "ladder", "lady", "lake", "lamp", "language",140+ "laptop", "large", "later", "latin", "laugh", "laundry", "lava", "law",141+ "lawn", "lawsuit", "layer", "lazy", "leader", "leaf", "learn", "leave",142+ "lecture", "left", "leg", "legal", "legend", "leisure", "lemon", "lend",143+ "length", "lens", "leopard", "lesson", "letter", "level", "liar", "liberty",144+ "library", "license", "life", "lift", "light", "like", "limb", "limit",145+ "link", "lion", "liquid", "list", "little", "live", "lizard", "load",146+ "loan", "lobster", "local", "lock", "logic", "lonely", "long", "loop",147+ "lottery", "loud", "lounge", "love", "loyal", "lucky", "luggage", "lumber",148+ "lunar", "lunch", "luxury", "lyrics", "machine", "mad", "magic", "magnet",149+ "maid", "mail", "main", "major", "make", "mammal", "man", "manage",150+ "mandate", "mango", "mansion", "manual", "maple", "marble", "march", "margin",151+ "marine", "market", "marriage", "mask", "mass", "master", "match", "material",152+ "math", "matrix", "matter", "maximum", "maze", "meadow", "mean", "measure",153+ "meat", "mechanic", "medal", "media", "melody", "melt", "member", "memory",154+ "mention", "menu", "mercy", "merge", "merit", "merry", "mesh", "message",155+ "metal", "method", "middle", "midnight", "milk", "million", "mimic", "mind",156+ "minimum", "minor", "minute", "miracle", "mirror", "misery", "miss", "mistake",157+ "mix", "mixed", "mixture", "mobile", "model", "modify", "mom", "moment",158+ "monitor", "monkey", "monster", "month", "moon", "moral", "more", "morning",159+ "mosquito", "mother", "motion", "motor", "mountain", "mouse", "move", "movie",160+ "much", "muffin", "mule", "multiply", "muscle", "museum", "mushroom", "music",161+ "must", "mutual", "myself", "mystery", "myth", "naive", "name", "napkin",162+ "narrow", "nasty", "nation", "nature", "near", "neck", "need", "negative",163+ "neglect", "neither", "nephew", "nerve", "nest", "net", "network", "neutral",164+ "never", "news", "next", "nice", "night", "noble", "noise", "nominee",165+ "noodle", "normal", "north", "nose", "notable", "note", "nothing", "notice",166+ "novel", "now", "nuclear", "number", "nurse", "nut", "oak", "obey",167+ "object", "oblige", "obscure", "observe", "obtain", "obvious", "occur", "ocean",168+ "october", "odor", "off", "offer", "office", "often", "oil", "okay",169+ "old", "olive", "olympic", "omit", "once", "one", "onion", "online",170+ "only", "open", "opera", "opinion", "oppose", "option", "orange", "orbit",171+ "orchard", "order", "ordinary", "organ", "orient", "original", "orphan", "ostrich",172+ "other", "outdoor", "outer", "output", "outside", "oval", "oven", "over",173+ "own", "owner", "oxygen", "oyster", "ozone", "pact", "paddle", "page",174+ "pair", "palace", "palm", "panda", "panel", "panic", "panther", "paper",175+ "parade", "parent", "park", "parrot", "party", "pass", "patch", "path",176+ "patient", "patrol", "pattern", "pause", "pave", "payment", "peace", "peanut",177+ "pear", "peasant", "pelican", "pen", "penalty", "pencil", "people", "pepper",178+ "perfect", "permit", "person", "pet", "phone", "photo", "phrase", "physical",179+ "piano", "picnic", "picture", "piece", "pig", "pigeon", "pill", "pilot",180+ "pink", "pioneer", "pipe", "pistol", "pitch", "pizza", "place", "planet",181+ "plastic", "plate", "play", "please", "pledge", "pluck", "plug", "plunge",182+ "poem", "poet", "point", "polar", "pole", "police", "pond", "pony",183+ "pool", "popular", "portion", "position", "possible", "post", "potato", "pottery",184+ "poverty", "powder", "power", "practice", "praise", "predict", "prefer", "prepare",185+ "present", "pretty", "prevent", "price", "pride", "primary", "print", "priority",186+ "prison", "private", "prize", "problem", "process", "produce", "profit", "program",187+ "project", "promote", "proof", "property", "prosper", "protect", "proud", "provide",188+ "public", "pudding", "pull", "pulp", "pulse", "pumpkin", "punch", "pupil",189+ "puppy", "purchase", "purity", "purpose", "purse", "push", "put", "puzzle",190+ "pyramid", "quality", "quantum", "quarter", "question", "quick", "quit", "quiz",191+ "quote", "rabbit", "raccoon", "race", "rack", "radar", "radio", "rail",192+ "rain", "raise", "rally", "ramp", "ranch", "random", "range", "rapid",193+ "rare", "rate", "rather", "raven", "raw", "razor", "ready", "real",194+ "reason", "rebel", "rebuild", "recall", "receive", "recipe", "record", "recycle",195+ "reduce", "reflect", "reform", "refuse", "region", "regret", "regular", "reject",196+ "relax", "release", "relief", "rely", "remain", "remember", "remind", "remove",197+ "render", "renew", "rent", "reopen", "repair", "repeat", "replace", "report",198+ "require", "rescue", "resemble", "resist", "resource", "response", "result", "retire",199+ "retreat", "return", "reunion", "reveal", "review", "reward", "rhythm", "rib",200+ "ribbon", "rice", "rich", "ride", "ridge", "rifle", "right", "rigid",201+ "ring", "riot", "ripple", "risk", "ritual", "rival", "river", "road",202+ "roast", "robot", "robust", "rocket", "romance", "roof", "rookie", "room",203+ "rose", "rotate", "rough", "round", "route", "royal", "rubber", "rude",204+ "rug", "rule", "run", "runway", "rural", "sad", "saddle", "sadness",205+ "safe", "sail", "salad", "salmon", "salon", "salt", "salute", "same",206+ "sample", "sand", "satisfy", "satoshi", "sauce", "sausage", "save", "say",207+ "scale", "scan", "scare", "scatter", "scene", "scheme", "school", "science",208+ "scissors", "scorpion", "scout", "scrap", "screen", "script", "scrub", "sea",209+ "search", "season", "seat", "second", "secret", "section", "security", "seed",210+ "seek", "segment", "select", "sell", "seminar", "senior", "sense", "sentence",211+ "series", "service", "session", "settle", "setup", "seven", "shadow", "shaft",212+ "shallow", "share", "shed", "shell", "sheriff", "shield", "shift", "shine",213+ "ship", "shiver", "shock", "shoe", "shoot", "shop", "short", "shoulder",214+ "shove", "shrimp", "shrug", "shuffle", "shy", "sibling", "sick", "side",215+ "siege", "sight", "sign", "silent", "silk", "silly", "silver", "similar",216+ "simple", "since", "sing", "siren", "sister", "situate", "six", "size",217+ "skate", "sketch", "ski", "skill", "skin", "skirt", "skull", "slab",218+ "slam", "sleep", "slender", "slice", "slide", "slight", "slim", "slogan",219+ "slot", "slow", "slush", "small", "smart", "smile", "smoke", "smooth",220+ "snack", "snake", "snap", "sniff", "snow", "soap", "soccer", "social",221+ "sock", "soda", "soft", "solar", "soldier", "solid", "solution", "solve",222+ "someone", "song", "soon", "sorry", "sort", "soul", "sound", "soup",223+ "source", "south", "space", "spare", "spatial", "spawn", "speak", "special",224+ "speed", "spell", "spend", "sphere", "spice", "spider", "spike", "spin",225+ "spirit", "split", "spoil", "sponsor", "spoon", "sport", "spot", "spray",226+ "spread", "spring", "spy", "square", "squeeze", "squirrel", "stable", "stadium",227+ "staff", "stage", "stairs", "stamp", "stand", "start", "state", "stay",228+ "steak", "steel", "stem", "step", "stereo", "stick", "still", "sting",229+ "stock", "stomach", "stone", "stool", "story", "stove", "strategy", "street",230+ "strike", "strong", "struggle", "student", "stuff", "stumble", "style", "subject",231+ "submit", "subway", "success", "such", "sudden", "suffer", "sugar", "suggest",232+ "suit", "summer", "sun", "sunny", "sunset", "super", "supply", "supreme",233+ "sure", "surface", "surge", "surprise", "surround", "survey", "suspect", "sustain",234+ "swallow", "swamp", "swap", "swarm", "swear", "sweet", "swift", "swim",235+ "swing", "switch", "sword", "symbol", "symptom", "syrup", "system", "table",236+ "tackle", "tag", "tail", "talent", "talk", "tank", "tape", "target",237+ "task", "taste", "tattoo", "taxi", "teach", "team", "tell", "ten",238+ "tenant", "tennis", "tent", "term", "test", "text", "thank", "that",239+ "theme", "then", "theory", "there", "they", "thing", "this", "thought",240+ "three", "thrive", "throw", "thumb", "thunder", "ticket", "tide", "tiger",241+ "tilt", "timber", "time", "tiny", "tip", "tired", "tissue", "title",242+ "toast", "tobacco", "today", "toddler", "toe", "together", "toilet", "token",243+ "tomato", "tomorrow", "tone", "tongue", "tonight", "tool", "tooth", "top",244+ "topic", "topple", "torch", "tornado", "tortoise", "toss", "total", "tourist",245+ "toward", "tower", "town", "toy", "track", "trade", "traffic", "tragic",246+ "train", "transfer", "trap", "trash", "travel", "tray", "treat", "tree",247+ "trend", "trial", "tribe", "trick", "trigger", "trim", "trip", "trophy",248+ "trouble", "truck", "true", "truly", "trumpet", "trust", "truth", "try",249+ "tube", "tuition", "tumble", "tuna", "tunnel", "turkey", "turn", "turtle",250+ "twelve", "twenty", "twice", "twin", "twist", "two", "type", "typical",251+ "ugly", "umbrella", "unable", "unaware", "uncle", "uncover", "under", "undo",252+ "unfair", "unfold", "unhappy", "uniform", "unique", "unit", "universe", "unknown",253+ "unlock", "until", "unusual", "unveil", "update", "upgrade", "uphold", "upon",254+ "upper", "upset", "urban", "urge", "usage", "use", "used", "useful",255+ "useless", "usual", "utility", "vacant", "vacuum", "vague", "valid", "valley",256+ "valve", "van", "vanish", "vapor", "various", "vast", "vault", "vehicle",257+ "velvet", "vendor", "venture", "venue", "verb", "verify", "version", "very",258+ "vessel", "veteran", "viable", "vibrant", "vicious", "victory", "video", "view",259+ "village", "vintage", "violin", "virtual", "virus", "visa", "visit", "visual",260+ "vital", "vivid", "vocal", "voice", "void", "volcano", "volume", "vote",261+ "voyage", "wage", "wagon", "wait", "walk", "wall", "walnut", "want",262+ "warfare", "warm", "warrior", "wash", "wasp", "waste", "water", "wave",263+ "way", "wealth", "weapon", "wear", "weasel", "weather", "web", "wedding",264+ "weekend", "weird", "welcome", "west", "wet", "whale", "what", "wheat",265+ "wheel", "when", "where", "whip", "whisper", "wide", "width", "wife",266+ "wild", "will", "win", "window", "wine", "wing", "wink", "winner",267+ "winter", "wire", "wisdom", "wise", "wish", "witness", "wolf", "woman",268+ "wonder", "wood", "wool", "word", "work", "world", "worry", "worth",269+ "wrap", "wreck", "wrestle", "wrist", "write", "wrong", "yard", "year",270+ "yellow", "you", "young", "youth", "zebra", "zero", "zone", "zoo",271+)272+273+/**274+ * The list shipped up to v2.4.12, which carried a duplicate "abandon" at index275+ * 1 and so was the canonical list shifted by one from index 1 onward. Phrases276+ * written down from those builds decode only under this ordering, so277+ * [wordsToRootKeyMaterial] falls back to it. Never used for display or for new278+ * vaults — decode only, and it will be removed once no such phrase can remain.279+ */280+val LEGACY_WORD_LIST: List<String> = listOf(281+ "abandon", "abandon", "ability", "able", "about", "above", "absent", "absorb",282+ "abstract", "absurd", "abuse", "access", "accident", "account", "accuse", "achieve",283+ "acid", "acoustic", "acquire", "across", "act", "action", "actor", "actress",284+ "actual", "adapt", "add", "addict", "address", "adjust", "admit", "adult",285+ "advance", "advice", "aerobic", "affair", "afford", "afraid", "again", "age",286+ "agent", "agree", "ahead", "aim", "air", "airport", "aisle", "alarm",287+ "album", "alcohol", "alert", "alien", "all", "alley", "allow", "almost",288+ "alone", "alpha", "already", "also", "alter", "always", "amateur", "amazing",289+ "among", "amount", "amused", "analyst", "anchor", "ancient", "anger", "angle",290+ "angry", "animal", "ankle", "announce", "annual", "another", "answer", "antenna",291+ "antique", "anxiety", "any", "apart", "apology", "appear", "apple", "approve",292+ "april", "arch", "arctic", "area", "arena", "argue", "arm", "armed",293+ "armor", "army", "around", "arrange", "arrest", "arrive", "arrow", "art",294+ "artefact", "artist", "artwork", "ask", "aspect", "assault", "asset", "assist",295+ "assume", "asthma", "athlete", "atom", "attack", "attend", "attitude", "attract",296+ "auction", "audit", "august", "aunt", "author", "auto", "autumn", "average",297+ "avocado", "avoid", "awake", "aware", "away", "awesome", "awful", "awkward",298+ "axis", "baby", "bachelor", "bacon", "badge", "bag", "balance", "balcony",299+ "ball", "bamboo", "banana", "banner", "bar", "barely", "bargain", "barrel",300+ "base", "basic", "basket", "battle", "beach", "bean", "beauty", "because",301+ "become", "beef", "before", "begin", "behave", "behind", "believe", "below",302+ "belt", "bench", "benefit", "best", "betray", "better", "between", "beyond",303+ "bicycle", "bid", "bike", "bind", "biology", "bird", "birth", "bitter",304+ "black", "blade", "blame", "blanket", "blast", "bleak", "bless", "blind",305+ "blood", "blossom", "blouse", "blue", "blur", "blush", "board", "boat",306+ "body", "boil", "bomb", "bone", "bonus", "book", "boost", "border",307+ "boring", "borrow", "boss", "bottom", "bounce", "box", "boy", "bracket",308+ "brain", "brand", "brass", "brave", "bread", "breeze", "brick", "bridge",309+ "brief", "bright", "bring", "brisk", "broccoli", "broken", "bronze", "broom",310+ "brother", "brown", "brush", "bubble", "buddy", "budget", "buffalo", "build",311+ "bulb", "bulk", "bullet", "bundle", "bunker", "burden", "burger", "burst",312+ "bus", "business", "busy", "butter", "buyer", "buzz", "cabbage", "cabin",313+ "cable", "cactus", "cage", "cake", "call", "calm", "camera", "camp",314+ "can", "canal", "cancel", "candy", "cannon", "canoe", "canvas", "canyon",315+ "capable", "capital", "captain", "car", "carbon", "card", "cargo", "carpet",316+ "carry", "cart", "case", "cash", "casino", "castle", "casual", "cat",317+ "catalog", "catch", "category", "cattle", "caught", "cause", "caution", "cave",318+ "ceiling", "celery", "cement", "census", "century", "cereal", "certain", "chair",319+ "chalk", "champion", "change", "chaos", "chapter", "charge", "chase", "chat",320+ "cheap", "check", "cheese", "chef", "cherry", "chest", "chicken", "chief",321+ "child", "chimney", "choice", "choose", "chronic", "chuckle", "chunk", "churn",322+ "cigar", "cinnamon", "circle", "citizen", "city", "civil", "claim", "clap",323+ "clarify", "claw", "clay", "clean", "clerk", "clever", "click", "client",324+ "cliff", "climb", "clinic", "clip", "clock", "clog", "close", "cloth",325+ "cloud", "clown", "club", "clump", "cluster", "clutch", "coach", "coast",326+ "coconut", "code", "coffee", "coil", "coin", "collect", "color", "column",327+ "combine", "come", "comfort", "comic", "common", "company", "concert", "conduct",328+ "confirm", "congress", "connect", "consider", "control", "convince", "cook", "cool",329+ "copper", "copy", "coral", "core", "corn", "correct", "cost", "cotton",330+ "couch", "country", "couple", "course", "cousin", "cover", "coyote", "crack",331+ "cradle", "craft", "cram", "crane", "crash", "crater", "crawl", "crazy",332+ "cream", "credit", "creek", "crew", "cricket", "crime", "crisp", "critic",333+ "crop", "cross", "crouch", "crowd", "crucial", "cruel", "cruise", "crumble",334+ "crunch", "crush", "cry", "crystal", "cube", "culture", "cup", "cupboard",335+ "curious", "current", "curtain", "curve", "cushion", "custom", "cute", "cycle",336+ "dad", "damage", "damp", "dance", "danger", "daring", "dash", "daughter",337+ "dawn", "day", "deal", "debate", "debris", "decade", "december", "decide",338+ "decline", "decorate", "decrease", "deer", "defense", "define", "defy", "degree",339+ "delay", "deliver", "demand", "demise", "denial", "dentist", "deny", "depart",340+ "depend", "deposit", "depth", "deputy", "derive", "describe", "desert", "design",341+ "desk", "despair", "destroy", "detail", "detect", "develop", "device", "devote",342+ "diagram", "dial", "diamond", "diary", "dice", "diesel", "diet", "differ",343+ "digital", "dignity", "dilemma", "dinner", "dinosaur", "direct", "dirt", "disagree",344+ "discover", "disease", "dish", "dismiss", "disorder", "display", "distance", "divert",345+ "divide", "divorce", "dizzy", "doctor", "document", "dog", "doll", "dolphin",346+ "domain", "donate", "donkey", "donor", "door", "dose", "double", "dove",347+ "draft", "dragon", "drama", "drastic", "draw", "dream", "dress", "drift",348+ "drill", "drink", "drip", "drive", "drop", "drum", "dry", "duck",349+ "dumb", "dune", "during", "dust", "dutch", "duty", "dwarf", "dynamic",350+ "eager", "eagle", "early", "earn", "earth", "easily", "east", "easy",351+ "echo", "ecology", "economy", "edge", "edit", "educate", "effort", "egg",352+ "eight", "either", "elbow", "elder", "electric", "elegant", "element", "elephant",353+ "elevator", "elite", "else", "embark", "embody", "embrace", "emerge", "emotion",354+ "employ", "empower", "empty", "enable", "enact", "end", "endless", "endorse",355+ "enemy", "energy", "enforce", "engage", "engine", "enhance", "enjoy", "enlist",356+ "enough", "enrich", "enroll", "ensure", "enter", "entire", "entry", "envelope",357+ "episode", "equal", "equip", "era", "erase", "erode", "erosion", "error",358+ "erupt", "escape", "essay", "essence", "estate", "eternal", "ethics", "evidence",359+ "evil", "evoke", "evolve", "exact", "example", "excess", "exchange", "excite",360+ "exclude", "excuse", "execute", "exercise", "exhaust", "exhibit", "exile", "exist",361+ "exit", "exotic", "expand", "expect", "expire", "explain", "expose", "express",362+ "extend", "extra", "eye", "eyebrow", "fabric", "face", "faculty", "fade",363+ "faint", "faith", "fall", "false", "fame", "family", "famous", "fan",364+ "fancy", "fantasy", "farm", "fashion", "fat", "fatal", "father", "fatigue",365+ "fault", "favorite", "feature", "february", "federal", "fee", "feed", "feel",366+ "female", "fence", "festival", "fetch", "fever", "few", "fiber", "fiction",367+ "field", "figure", "file", "film", "filter", "final", "find", "fine",368+ "finger", "finish", "fire", "firm", "first", "fiscal", "fish", "fit",369+ "fitness", "fix", "flag", "flame", "flash", "flat", "flavor", "flee",370+ "flight", "flip", "float", "flock", "floor", "flower", "fluid", "flush",371+ "fly", "foam", "focus", "fog", "foil", "fold", "follow", "food",372+ "foot", "force", "forest", "forget", "fork", "fortune", "forum", "forward",373+ "fossil", "foster", "found", "fox", "fragile", "frame", "frequent", "fresh",374+ "friend", "fringe", "frog", "front", "frost", "frown", "frozen", "fruit",375+ "fuel", "fun", "funny", "furnace", "fury", "future", "gadget", "gain",376+ "galaxy", "gallery", "game", "gap", "garage", "garbage", "garden", "garlic",377+ "garment", "gas", "gasp", "gate", "gather", "gauge", "gaze", "general",378+ "genius", "genre", "gentle", "genuine", "gesture", "ghost", "giant", "gift",379+ "giggle", "ginger", "giraffe", "girl", "give", "glad", "glance", "glare",380+ "glass", "glide", "glimpse", "globe", "gloom", "glory", "glove", "glow",381+ "glue", "goat", "goddess", "gold", "good", "goose", "gorilla", "gospel",382+ "gossip", "govern", "gown", "grab", "grace", "grain", "grant", "grape",383+ "grass", "gravity", "great", "green", "grid", "grief", "grit", "grocery",384+ "group", "grow", "grunt", "guard", "guess", "guide", "guilt", "guitar",385+ "gun", "gym", "habit", "hair", "half", "hammer", "hamster", "hand",386+ "happy", "harbor", "hard", "harsh", "harvest", "hat", "have", "hawk",387+ "hazard", "head", "health", "heart", "heavy", "hedgehog", "height", "hello",388+ "helmet", "help", "hen", "hero", "hidden", "high", "hill", "hint",389+ "hip", "hire", "history", "hobby", "hockey", "hold", "hole", "holiday",390+ "hollow", "home", "honey", "hood", "hope", "horn", "horror", "horse",391+ "hospital", "host", "hotel", "hour", "hover", "hub", "huge", "human",392+ "humble", "humor", "hundred", "hungry", "hunt", "hurdle", "hurry", "hurt",393+ "husband", "hybrid", "ice", "icon", "idea", "identify", "idle", "ignore",394+ "ill", "illegal", "illness", "image", "imitate", "immense", "immune", "impact",395+ "impose", "improve", "impulse", "inch", "include", "income", "increase", "index",396+ "indicate", "indoor", "industry", "infant", "inflict", "inform", "inhale", "inherit",397+ "initial", "inject", "injury", "inmate", "inner", "innocent", "input", "inquiry",398+ "insane", "insect", "inside", "inspire", "install", "intact", "interest", "into",399+ "invest", "invite", "involve", "iron", "island", "isolate", "issue", "item",400+ "ivory", "jacket", "jaguar", "jar", "jazz", "jealous", "jeans", "jelly",401+ "jewel", "job", "join", "joke", "journey", "joy", "judge", "juice",402+ "jump", "jungle", "junior", "junk", "just", "kangaroo", "keen", "keep",403+ "ketchup", "key", "kick", "kid", "kidney", "kind", "kingdom", "kiss",404+ "kit", "kitchen", "kite", "kitten", "kiwi", "knee", "knife", "knock",405+ "know", "lab", "label", "labor", "ladder", "lady", "lake", "lamp",406+ "language", "laptop", "large", "later", "latin", "laugh", "laundry", "lava",407+ "law", "lawn", "lawsuit", "layer", "lazy", "leader", "leaf", "learn",408+ "leave", "lecture", "left", "leg", "legal", "legend", "leisure", "lemon",409+ "lend", "length", "lens", "leopard", "lesson", "letter", "level", "liar",410+ "liberty", "library", "license", "life", "lift", "light", "like", "limb",411+ "limit", "link", "lion", "liquid", "list", "little", "live", "lizard",412+ "load", "loan", "lobster", "local", "lock", "logic", "lonely", "long",413+ "loop", "lottery", "loud", "lounge", "love", "loyal", "lucky", "luggage",414+ "lumber", "lunar", "lunch", "luxury", "lyrics", "machine", "mad", "magic",415+ "magnet", "maid", "mail", "main", "major", "make", "mammal", "man",416+ "manage", "mandate", "mango", "mansion", "manual", "maple", "marble", "march",417+ "margin", "marine", "market", "marriage", "mask", "mass", "master", "match",418+ "material", "math", "matrix", "matter", "maximum", "maze", "meadow", "mean",419+ "measure", "meat", "mechanic", "medal", "media", "melody", "melt", "member",420+ "memory", "mention", "menu", "mercy", "merge", "merit", "merry", "mesh",421+ "message", "metal", "method", "middle", "midnight", "milk", "million", "mimic",422+ "mind", "minimum", "minor", "minute", "miracle", "mirror", "misery", "miss",423+ "mistake", "mix", "mixed", "mixture", "mobile", "model", "modify", "mom",424+ "moment", "monitor", "monkey", "monster", "month", "moon", "moral", "more",425+ "morning", "mosquito", "mother", "motion", "motor", "mountain", "mouse", "move",426+ "movie", "much", "muffin", "mule", "multiply", "muscle", "museum", "mushroom",427+ "music", "must", "mutual", "myself", "mystery", "myth", "naive", "name",428+ "napkin", "narrow", "nasty", "nation", "nature", "near", "neck", "need",429+ "negative", "neglect", "neither", "nephew", "nerve", "nest", "net", "network",430+ "neutral", "never", "news", "next", "nice", "night", "noble", "noise",431+ "nominee", "noodle", "normal", "north", "nose", "notable", "note", "nothing",432+ "notice", "novel", "now", "nuclear", "number", "nurse", "nut", "oak",433+ "obey", "object", "oblige", "obscure", "observe", "obtain", "obvious", "occur",434+ "ocean", "october", "odor", "off", "offer", "office", "often", "oil",435+ "okay", "old", "olive", "olympic", "omit", "once", "one", "onion",436+ "online", "only", "open", "opera", "opinion", "oppose", "option", "orange",437+ "orbit", "orchard", "order", "ordinary", "organ", "orient", "original", "orphan",438+ "ostrich", "other", "outdoor", "outer", "output", "outside", "oval", "oven",439+ "over", "own", "owner", "oxygen", "oyster", "ozone", "pact", "paddle",440+ "page", "pair", "palace", "palm", "panda", "panel", "panic", "panther",441+ "paper", "parade", "parent", "park", "parrot", "party", "pass", "patch",442+ "path", "patient", "patrol", "pattern", "pause", "pave", "payment", "peace",443+ "peanut", "pear", "peasant", "pelican", "pen", "penalty", "pencil", "people",444+ "pepper", "perfect", "permit", "person", "pet", "phone", "photo", "phrase",445+ "physical", "piano", "picnic", "picture", "piece", "pig", "pigeon", "pill",446+ "pilot", "pink", "pioneer", "pipe", "pistol", "pitch", "pizza", "place",447+ "planet", "plastic", "plate", "play", "please", "pledge", "pluck", "plug",448+ "plunge", "poem", "poet", "point", "polar", "pole", "police", "pond",449+ "pony", "pool", "popular", "portion", "position", "possible", "post", "potato",450+ "pottery", "poverty", "powder", "power", "practice", "praise", "predict", "prefer",451+ "prepare", "present", "pretty", "prevent", "price", "pride", "primary", "print",452+ "priority", "prison", "private", "prize", "problem", "process", "produce", "profit",453+ "program", "project", "promote", "proof", "property", "prosper", "protect", "proud",454+ "provide", "public", "pudding", "pull", "pulp", "pulse", "pumpkin", "punch",455+ "pupil", "puppy", "purchase", "purity", "purpose", "purse", "push", "put",456+ "puzzle", "pyramid", "quality", "quantum", "quarter", "question", "quick", "quit",457+ "quiz", "quote", "rabbit", "raccoon", "race", "rack", "radar", "radio",458+ "rail", "rain", "raise", "rally", "ramp", "ranch", "random", "range",459+ "rapid", "rare", "rate", "rather", "raven", "raw", "razor", "ready",460+ "real", "reason", "rebel", "rebuild", "recall", "receive", "recipe", "record",461+ "recycle", "reduce", "reflect", "reform", "refuse", "region", "regret", "regular",462+ "reject", "relax", "release", "relief", "rely", "remain", "remember", "remind",463+ "remove", "render", "renew", "rent", "reopen", "repair", "repeat", "replace",464+ "report", "require", "rescue", "resemble", "resist", "resource", "response", "result",465+ "retire", "retreat", "return", "reunion", "reveal", "review", "reward", "rhythm",466+ "rib", "ribbon", "rice", "rich", "ride", "ridge", "rifle", "right",467+ "rigid", "ring", "riot", "ripple", "risk", "ritual", "rival", "river",468+ "road", "roast", "robot", "robust", "rocket", "romance", "roof", "rookie",469+ "room", "rose", "rotate", "rough", "round", "route", "royal", "rubber",470+ "rude", "rug", "rule", "run", "runway", "rural", "sad", "saddle",471+ "sadness", "safe", "sail", "salad", "salmon", "salon", "salt", "salute",472+ "same", "sample", "sand", "satisfy", "satoshi", "sauce", "sausage", "save",473+ "say", "scale", "scan", "scare", "scatter", "scene", "scheme", "school",474+ "science", "scissors", "scorpion", "scout", "scrap", "screen", "script", "scrub",475+ "sea", "search", "season", "seat", "second", "secret", "section", "security",476+ "seed", "seek", "segment", "select", "sell", "seminar", "senior", "sense",477+ "sentence", "series", "service", "session", "settle", "setup", "seven", "shadow",478+ "shaft", "shallow", "share", "shed", "shell", "sheriff", "shield", "shift",479+ "shine", "ship", "shiver", "shock", "shoe", "shoot", "shop", "short",480+ "shoulder", "shove", "shrimp", "shrug", "shuffle", "shy", "sibling", "sick",481+ "side", "siege", "sight", "sign", "silent", "silk", "silly", "silver",482+ "similar", "simple", "since", "sing", "siren", "sister", "situate", "six",483+ "size", "skate", "sketch", "ski", "skill", "skin", "skirt", "skull",484+ "slab", "slam", "sleep", "slender", "slice", "slide", "slight", "slim",485+ "slogan", "slot", "slow", "slush", "small", "smart", "smile", "smoke",486+ "smooth", "snack", "snake", "snap", "sniff", "snow", "soap", "soccer",487+ "social", "sock", "soda", "soft", "solar", "soldier", "solid", "solution",488+ "solve", "someone", "song", "soon", "sorry", "sort", "soul", "sound",489+ "soup", "source", "south", "space", "spare", "spatial", "spawn", "speak",490+ "special", "speed", "spell", "spend", "sphere", "spice", "spider", "spike",491+ "spin", "spirit", "split", "spoil", "sponsor", "spoon", "sport", "spot",492+ "spray", "spread", "spring", "spy", "square", "squeeze", "squirrel", "stable",493+ "stadium", "staff", "stage", "stairs", "stamp", "stand", "start", "state",494+ "stay", "steak", "steel", "stem", "step", "stereo", "stick", "still",495+ "sting", "stock", "stomach", "stone", "stool", "story", "stove", "strategy",496+ "street", "strike", "strong", "struggle", "student", "stuff", "stumble", "style",497+ "subject", "submit", "subway", "success", "such", "sudden", "suffer", "sugar",498+ "suggest", "suit", "summer", "sun", "sunny", "sunset", "super", "supply",499+ "supreme", "sure", "surface", "surge", "surprise", "surround", "survey", "suspect",500+ "sustain", "swallow", "swamp", "swap", "swarm", "swear", "sweet", "swift",501+ "swim", "swing", "switch", "sword", "symbol", "symptom", "syrup", "system",502+ "table", "tackle", "tag", "tail", "talent", "talk", "tank", "tape",503+ "target", "task", "taste", "tattoo", "taxi", "teach", "team", "tell",504+ "ten", "tenant", "tennis", "tent", "term", "test", "text", "thank",505+ "that", "theme", "then", "theory", "there", "they", "thing", "this",506+ "thought", "three", "thrive", "throw", "thumb", "thunder", "ticket", "tide",507+ "tiger", "tilt", "timber", "time", "tiny", "tip", "tired", "tissue",508+ "title", "toast", "tobacco", "today", "toddler", "toe", "together", "toilet",509+ "token", "tomato", "tomorrow", "tone", "tongue", "tonight", "tool", "tooth",510+ "top", "topic", "topple", "torch", "tornado", "tortoise", "toss", "total",511+ "tourist", "toward", "tower", "town", "toy", "track", "trade", "traffic",512+ "tragic", "train", "transfer", "trap", "trash", "travel", "tray", "treat",513+ "tree", "trend", "trial", "tribe", "trick", "trigger", "trim", "trip",514+ "trophy", "trouble", "truck", "true", "truly", "trumpet", "trust", "truth",515+ "try", "tube", "tuition", "tumble", "tuna", "tunnel", "turkey", "turn",516+ "turtle", "twelve", "twenty", "twice", "twin", "twist", "two", "type",517+ "typical", "ugly", "umbrella", "unable", "unaware", "uncle", "uncover", "under",518+ "undo", "unfair", "unfold", "unhappy", "uniform", "unique", "unit", "universe",519+ "unknown", "unlock", "until", "unusual", "unveil", "update", "upgrade", "uphold",520+ "upon", "upper", "upset", "urban", "urge", "usage", "use", "used",521+ "useful", "useless", "usual", "utility", "vacant", "vacuum", "vague", "valid",522+ "valley", "valve", "van", "vanish", "vapor", "various", "vast", "vault",523+ "vehicle", "velvet", "vendor", "venture", "venue", "verb", "verify", "version",524+ "very", "vessel", "veteran", "viable", "vibrant", "vicious", "victory", "video",525+ "view", "village", "vintage", "violin", "virtual", "virus", "visa", "visit",526+ "visual", "vital", "vivid", "vocal", "voice", "void", "volcano", "volume",527+ "vote", "voyage", "wage", "wagon", "wait", "walk", "wall", "walnut",528+ "want", "warfare", "warm", "warrior", "wash", "wasp", "waste", "water",529+ "wave", "way", "wealth", "weapon", "wear", "weasel", "weather", "web",530+ "wedding", "weekend", "weird", "welcome", "west", "wet", "whale", "what",531+ "wheat", "wheel", "when", "where", "whip", "whisper", "wide", "width",532+ "wife", "wild", "will", "win", "window", "wine", "wing", "wink",533+ "winner", "winter", "wire", "wisdom", "wise", "wish", "witness", "wolf",534+ "woman", "wonder", "wood", "wool", "word", "work", "world", "worry",535+ "worth", "wrap", "wreck", "wrestle", "wrist", "write", "wrong", "yard",536+ "year", "yellow", "you", "young", "youth", "zebra", "zero", "zone",2052537 "zoo",2053538 )app/src/main/java/com/peachpasswords/vault/RecoveryWords.kt+30 −22
@@ -35,13 +35,30 @@3535 return words3636 }3737 38-fun wordsToRootKeyMaterial(words: List<String>): ByteArray {38+/**39+ * Decode a phrase to its 16 bytes of word material.40+ *41+ * Tries the canonical list first, then [LEGACY_WORD_LIST] so a phrase written42+ * down from a build that shipped the duplicated-"abandon" ordering still43+ * recovers. Both orderings are checksum-verified, and the escrow this material44+ * unwraps is authenticated, so a phrase that decodes under the wrong ordering45+ * cannot silently yield the wrong vault.46+ */47+fun wordsToRootKeyMaterial(words: List<String>): ByteArray =48+ runCatching { decodeWith(words, WORD_LIST) }49+ .recoverCatching { canonicalFailure ->50+ runCatching { decodeWith(words, LEGACY_WORD_LIST) }51+ .getOrElse { throw canonicalFailure }52+ }53+ .getOrThrow()54+55+private fun decodeWith(words: List<String>, list: List<String>): ByteArray {3956 require(words.size == TOTAL_WORDS) { "exactly $TOTAL_WORDS words required" }4057 4158 val indices = IntArray(words.size)4259 for (i in words.indices) {4360 val word = words[i].trim().lowercase()44- val index = WORD_LIST.indexOf(word)61+ val index = list.indexOf(word)4562 require(index >= 0) { "unknown word at position ${i + 1}: \"${words[i]}\"" }4663 indices[i] = index4764 }@@ -67,29 +84,20 @@6784 }6885 6986 /**70- * Generate a random 32-byte root key whose recovery words round-trip cleanly.87+ * Generate a random 32-byte root key and prove its words round-trip.7188 *72- * WORD_LIST carries "abandon" at both index 0 and 1 (a byte-identical parity copy73- * of the browser list), so `wordsToRootKeyMaterial` — which reconstructs entropy74- * via `indexOf` — cannot invert any phrase that `rootKeyToWords` emitted from75- * index 1; it throws on the checksum. The browser's `createVault` (`vault.ts:947`)76- * does NOT retry and therefore throws for those ~0.6% of root keys (a latent77- * reference bug). We deviate deliberately and safely: regenerate until the words78- * round-trip, yielding a strict, fully cross-compatible SUBSET of root keys. Any79- * vault created this way is recoverable by the browser too.89+ * The retry loop this used to carry existed only because the shipped word list90+ * duplicated "abandon" at index 1, which made ~0.6% of keys undecodable. The91+ * list is now the canonical 2048, so every key round-trips; the check stays as92+ * an assertion because shipping a key whose words cannot be typed back is the93+ * one failure this code must never allow.8094 */81-fun generateRecoverableRootKey(maxAttempts: Int = 64): ByteArray {82- val rng = java.security.SecureRandom()83- repeat(maxAttempts) {84- val candidate = ByteArray(32).also(rng::nextBytes)85- val words = rootKeyToWords(candidate)86- val roundTrips = runCatching { wordsToRootKeyMaterial(words) }.isSuccess87- if (roundTrips) return candidate88- candidate.fill(0)95+fun generateRecoverableRootKey(): ByteArray {96+ val candidate = ByteArray(32).also(java.security.SecureRandom()::nextBytes)97+ check(runCatching { wordsToRootKeyMaterial(rootKeyToWords(candidate)) }.isSuccess) {98+ "generated a root key whose recovery words do not round-trip"8999 }90- // Astronomically unlikely (P(fail)^64 with P(fail)≈0.006). Surface rather than91- // ship a root key whose displayed words cannot be entered back.92- throw IllegalStateException("could not generate a round-tripping root key")100+ return candidate93101 }94102 95103 /** Lowercase, unseparated hex of [bytes] — the exact ASCII the browser wraps in the escrow. */app/src/test/java/com/peachpasswords/vault/CrossPlatformRecoveryWordsTest.kt+87 −0
@@ -0,0 +1,87 @@1+package com.peachpasswords.vault2+3+import org.junit.Assert.assertEquals4+import org.junit.Assert.assertNotEquals5+import org.junit.Assert.assertTrue6+import org.junit.Test7+8+/**9+ * Recovery words are only a human-readable encoding of the root key's first 1610+ * bytes, so the two platforms MUST agree on the word list byte for byte. They11+ * did not: Android shipped a list with "abandon" duplicated at index 1, making12+ * it the canonical list shifted by one from index 1 on. The same vault printed13+ * different words on each platform, so a phrase written down on the phone14+ * restored nothing in the extension.15+ *16+ * The vector below is computed from the browser's canonical list17+ * (`src/shared/recovery-word-list.ts`) and is pinned identically in18+ * `src/background/recovery-words.test.ts`.19+ */20+class CrossPlatformRecoveryWordsTest {21+22+ private val vectorRootKey =23+ "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"24+25+ private val vectorWords = listOf(26+ "abandon", "math", "mimic", "master", "filter", "design",27+ "carbon", "crystal", "rookie", "group", "knife", "young",28+ )29+30+ @Test fun word_list_is_the_canonical_2048_with_no_duplicates() {31+ assertEquals(2048, WORD_LIST.size)32+ assertEquals(2048, WORD_LIST.toSet().size)33+ assertEquals("abandon", WORD_LIST.first())34+ assertEquals("ability", WORD_LIST[1])35+ assertEquals("zoo", WORD_LIST.last())36+ }37+38+ @Test fun words_match_the_browser_for_the_shared_vector() {39+ assertEquals(vectorWords, rootKeyToWords(hexToRootKey(vectorRootKey)))40+ }41+42+ @Test fun every_reachable_index_round_trips() {43+ // The old list failed exactly here: index 1 encoded to "abandon" and44+ // decoded back to 0. An 11-bit index reaches 0..2047, so all of it must.45+ for (index in 0 until 2048) {46+ assertEquals(47+ "index $index does not round-trip",48+ index,49+ WORD_LIST.indexOf(WORD_LIST[index]),50+ )51+ }52+ }53+54+ @Test fun random_root_keys_always_round_trip() {55+ val rng = java.util.Random(20260726)56+ repeat(20_000) {57+ val key = ByteArray(32).also(rng::nextBytes)58+ val material = wordsToRootKeyMaterial(rootKeyToWords(key))59+ assertTrue(material.copyOfRange(0, 16).contentEquals(key.copyOfRange(0, 16)))60+ }61+ }62+63+ @Test fun a_phrase_written_under_the_legacy_ordering_still_recovers() {64+ // What an affected phone displayed for the same root key. It must keep65+ // working: someone has this on paper.66+ val legacyWords = LEGACY_WORD_LIST.let { legacy ->67+ val key = hexToRootKey(vectorRootKey)68+ val canonical = rootKeyToWords(key)69+ // Same indices, rendered through the legacy ordering: the extra70+ // "abandon" at index 1 means legacy[i] is canonical[i - 1].71+ canonical.map { legacy[WORD_LIST.indexOf(it)] }72+ }73+ assertNotEquals(vectorWords, legacyWords)74+75+ val expected = hexToRootKey(vectorRootKey).copyOfRange(0, 16)76+ assertTrue(77+ wordsToRootKeyMaterial(legacyWords).copyOfRange(0, 16).contentEquals(expected),78+ )79+ }80+81+ @Test fun canonical_phrases_are_not_misread_as_legacy() {82+ val expected = hexToRootKey(vectorRootKey).copyOfRange(0, 16)83+ assertTrue(84+ wordsToRootKeyMaterial(vectorWords).copyOfRange(0, 16).contentEquals(expected),85+ )86+ }87+}app/src/test/java/com/peachpasswords/vault/RecoveryEscrowTest.kt+9 −2
@@ -136,9 +136,16 @@136136 // root key on both platforms.137137 @Test fun kat_matches_browser_algorithm() {138138 val rootKeyHex = "bfb2d5731a470e1b1a0ae9521f501ac5edad8b4ce8e064b76da4cb3cdf00b937"139+ // Corrected in v2.4.13. These were previously this platform's own140+ // output under a word list that duplicated "abandon" at index 1, so the141+ // vector was one position off the browser at every index >= 1 — this142+ // test asserted browser parity while pinning the divergence. Recomputed143+ // against the browser's canonical list; the material/HKDF/ciphertext144+ // vectors below are unchanged because they key off the root key bytes,145+ // not the word ordering.139146 val expectedWords = listOf(140- "sauce", "notable", "frequent", "crucial", "ignore", "aspect",141- "gym", "fringe", "faint", "whip", "alley", "merge",147+ "sausage", "note", "fresh", "cruel", "ill", "assault",148+ "habit", "frog", "faith", "whisper", "allow", "merit",142149 )143150 val wordMaterialHex = "bfb2d5731a470e1b1a0ae9521f501ac500000000000000000000000000000000"144151 val recoveryKeyHex = "06880fb677e5b1cd1a65de6340a605681a55c86268885d644117401a9effd990"