diff options
Diffstat (limited to 'src/js/jsbip39.js')
-rw-r--r-- | src/js/jsbip39.js | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/src/js/jsbip39.js b/src/js/jsbip39.js new file mode 100644 index 0000000..d0ac3ae --- /dev/null +++ b/src/js/jsbip39.js | |||
@@ -0,0 +1,386 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013 Pavol Rusnak | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
5 | * this software and associated documentation files (the "Software"), to deal in | ||
6 | * the Software without restriction, including without limitation the rights to | ||
7 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
8 | * of the Software, and to permit persons to whom the Software is furnished to do | ||
9 | * so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in all | ||
12 | * copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
18 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * Javascript port from python by Ian Coleman | ||
24 | * | ||
25 | * Includes code from asmCrypto | ||
26 | * https://github.com/tresorit/asmcrypto.js | ||
27 | */ | ||
28 | |||
29 | var Mnemonic = function(language) { | ||
30 | |||
31 | var PBKDF2_ROUNDS = 2048; | ||
32 | var RADIX = 2048; | ||
33 | |||
34 | var self = this; | ||
35 | var wordlist = []; | ||
36 | |||
37 | function init() { | ||
38 | wordlist = WORDLISTS[language]; | ||
39 | if (wordlist.length != RADIX) { | ||
40 | err = 'Wordlist should contain ' + RADIX + ' words, but it contains ' + wordlist.length + ' words.'; | ||
41 | throw err; | ||
42 | } | ||
43 | } | ||
44 | |||
45 | self.generate = function(strength) { | ||
46 | strength = strength || 128; | ||
47 | var r = strength % 32; | ||
48 | if (r > 0) { | ||
49 | throw 'Strength should be divisible by 32, but it is not (' + r + ').'; | ||
50 | } | ||
51 | var hasStrongCrypto = 'crypto' in window && window['crypto'] !== null; | ||
52 | if (!hasStrongCrypto) { | ||
53 | throw 'Mnemonic should be generated with strong randomness, but crypto.getRandomValues is unavailable'; | ||
54 | } | ||
55 | var buffer = new Uint8Array(strength / 8); | ||
56 | var data = crypto.getRandomValues(buffer); | ||
57 | return self.toMnemonic(data); | ||
58 | } | ||
59 | |||
60 | self.toMnemonic = function(data) { | ||
61 | if (data.length % 4 > 0) { | ||
62 | throw 'Data length in bits should be divisible by 32, but it is not (' + data.length + ' bytes = ' + data.length*8 + ' bits).' | ||
63 | } | ||
64 | |||
65 | //h = hashlib.sha256(data).hexdigest() | ||
66 | var uintArray = new Uint8Array(data); | ||
67 | var h = asmCrypto.SHA256.bytes(uintArray); | ||
68 | |||
69 | // b is a binary string, eg '00111010101100...' | ||
70 | //b = bin(int(binascii.hexlify(data), 16))[2:].zfill(len(data) * 8) + \ | ||
71 | // bin(int(h, 16))[2:].zfill(256)[:len(data) * 8 / 32] | ||
72 | // | ||
73 | // a = bin(int(binascii.hexlify(data), 16))[2:].zfill(len(data) * 8) | ||
74 | // c = bin(int(h, 16))[2:].zfill(256) | ||
75 | // d = c[:len(data) * 8 / 32] | ||
76 | var a = byteArrayToBinaryString(data); | ||
77 | var c = byteArrayToBinaryString(h); | ||
78 | var d = c.substring(0, data.length * 8 / 32); | ||
79 | // b = line1 + line2 | ||
80 | var b = a + d; | ||
81 | |||
82 | var result = []; | ||
83 | var blen = b.length / 11; | ||
84 | for (var i=0; i<blen; i++) { | ||
85 | var idx = parseInt(b.substring(i * 11, (i + 1) * 11), 2); | ||
86 | result.push(wordlist[idx]); | ||
87 | } | ||
88 | return result.join(' '); | ||
89 | } | ||
90 | |||
91 | self.check = function(mnemonic) { | ||
92 | var mnemonic = mnemonic.split(' ') | ||
93 | if (mnemonic.length % 3 > 0) { | ||
94 | return false | ||
95 | } | ||
96 | // idx = map(lambda x: bin(self.wordlist.index(x))[2:].zfill(11), mnemonic) | ||
97 | var idx = []; | ||
98 | for (var i=0; i<mnemonic.length; i++) { | ||
99 | var word = mnemonic[i]; | ||
100 | var wordIndex = wordlist.indexOf(word); | ||
101 | if (wordIndex == -1) { | ||
102 | return false; | ||
103 | } | ||
104 | var binaryIndex = zfill(wordIndex.toString(2), 11); | ||
105 | idx.push(binaryIndex); | ||
106 | } | ||
107 | var b = idx.join(''); | ||
108 | var l = b.length; | ||
109 | //d = b[:l / 33 * 32] | ||
110 | //h = b[-l / 33:] | ||
111 | var d = b.substring(0, l / 33 * 32); | ||
112 | var h = b.substring(l - l / 33, l); | ||
113 | //nd = binascii.unhexlify(hex(int(d, 2))[2:].rstrip('L').zfill(l / 33 * 8)) | ||
114 | //nh = bin(int(hashlib.sha256(nd).hexdigest(), 16))[2:].zfill(256)[:l / 33] | ||
115 | var nd = binaryStringToByteArray(d); | ||
116 | var ndHash = asmCrypto.SHA256.bytes(nd); | ||
117 | var ndBstr = zfill(byteArrayToBinaryString(ndHash), 256); | ||
118 | var nh = ndBstr.substring(0,l/33); | ||
119 | return h == nh; | ||
120 | } | ||
121 | |||
122 | self.toSeed = function(mnemonic, passphrase) { | ||
123 | passphrase = passphrase || ''; | ||
124 | mnemonic = normalizeString(mnemonic) | ||
125 | passphrase = normalizeString(passphrase) | ||
126 | passphrase = "mnemonic" + passphrase; | ||
127 | //return PBKDF2(mnemonic, 'mnemonic' + passphrase, iterations=PBKDF2_ROUNDS, macmodule=hmac, digestmodule=hashlib.sha512).read(64) | ||
128 | return asmCrypto.PBKDF2_HMAC_SHA512.hex(mnemonic, passphrase, PBKDF2_ROUNDS, 512/8); | ||
129 | } | ||
130 | |||
131 | function normalizeString(str) { | ||
132 | if (typeof str.normalize == "function") { | ||
133 | return str.normalize("NFKD"); | ||
134 | } | ||
135 | else { | ||
136 | // TODO find a library to do this | ||
137 | // Not supported on firefox mobile | ||
138 | console.warn("NFKD Normalization is unavailable"); | ||
139 | return str; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | function byteArrayToBinaryString(data) { | ||
144 | var bin = ""; | ||
145 | for (var i=0; i<data.length; i++) { | ||
146 | bin += zfill(data[i].toString(2), 8); | ||
147 | } | ||
148 | return bin; | ||
149 | } | ||
150 | |||
151 | function binaryStringToByteArray(str) { | ||
152 | var arrayLen = str.length / 8; | ||
153 | var array = new Uint8Array(arrayLen); | ||
154 | for (var i=0; i<arrayLen; i++) { | ||
155 | var valueStr = str.substring(0,8); | ||
156 | var value = parseInt(valueStr, 2); | ||
157 | array[i] = value; | ||
158 | str = str.slice(8); | ||
159 | } | ||
160 | return array; | ||
161 | } | ||
162 | |||
163 | // Pad a numeric string on the left with zero digits until the given width | ||
164 | // is reached. | ||
165 | // Note this differs to the python implementation because it does not | ||
166 | // handle numbers starting with a sign. | ||
167 | function zfill(source, length) { | ||
168 | source = source.toString(); | ||
169 | while (source.length < length) { | ||
170 | source = '0' + source; | ||
171 | } | ||
172 | return source; | ||
173 | } | ||
174 | |||
175 | init(); | ||
176 | |||
177 | } | ||
178 | |||
179 | WORDLISTS = { | ||
180 | "english": [ | ||
181 | "abandon","ability","able","about","above","absent","absorb","abstract","absurd","abuse", | ||
182 | "access","accident","account","accuse","achieve","acid","acoustic","acquire","across","act", | ||
183 | "action","actor","actress","actual","adapt","add","addict","address","adjust","admit", | ||
184 | "adult","advance","advice","aerobic","affair","afford","afraid","again","age","agent", | ||
185 | "agree","ahead","aim","air","airport","aisle","alarm","album","alcohol","alert", | ||
186 | "alien","all","alley","allow","almost","alone","alpha","already","also","alter", | ||
187 | "always","amateur","amazing","among","amount","amused","analyst","anchor","ancient","anger", | ||
188 | "angle","angry","animal","ankle","announce","annual","another","answer","antenna","antique", | ||
189 | "anxiety","any","apart","apology","appear","apple","approve","april","arch","arctic", | ||
190 | "area","arena","argue","arm","armed","armor","army","around","arrange","arrest", | ||
191 | "arrive","arrow","art","artefact","artist","artwork","ask","aspect","assault","asset", | ||
192 | "assist","assume","asthma","athlete","atom","attack","attend","attitude","attract","auction", | ||
193 | "audit","august","aunt","author","auto","autumn","average","avocado","avoid","awake", | ||
194 | "aware","away","awesome","awful","awkward","axis","baby","bachelor","bacon","badge", | ||
195 | "bag","balance","balcony","ball","bamboo","banana","banner","bar","barely","bargain", | ||
196 | "barrel","base","basic","basket","battle","beach","bean","beauty","because","become", | ||
197 | "beef","before","begin","behave","behind","believe","below","belt","bench","benefit", | ||
198 | "best","betray","better","between","beyond","bicycle","bid","bike","bind","biology", | ||
199 | "bird","birth","bitter","black","blade","blame","blanket","blast","bleak","bless", | ||
200 | "blind","blood","blossom","blouse","blue","blur","blush","board","boat","body", | ||
201 | "boil","bomb","bone","bonus","book","boost","border","boring","borrow","boss", | ||
202 | "bottom","bounce","box","boy","bracket","brain","brand","brass","brave","bread", | ||
203 | "breeze","brick","bridge","brief","bright","bring","brisk","broccoli","broken","bronze", | ||
204 | "broom","brother","brown","brush","bubble","buddy","budget","buffalo","build","bulb", | ||
205 | "bulk","bullet","bundle","bunker","burden","burger","burst","bus","business","busy", | ||
206 | "butter","buyer","buzz","cabbage","cabin","cable","cactus","cage","cake","call", | ||
207 | "calm","camera","camp","can","canal","cancel","candy","cannon","canoe","canvas", | ||
208 | "canyon","capable","capital","captain","car","carbon","card","cargo","carpet","carry", | ||
209 | "cart","case","cash","casino","castle","casual","cat","catalog","catch","category", | ||
210 | "cattle","caught","cause","caution","cave","ceiling","celery","cement","census","century", | ||
211 | "cereal","certain","chair","chalk","champion","change","chaos","chapter","charge","chase", | ||
212 | "chat","cheap","check","cheese","chef","cherry","chest","chicken","chief","child", | ||
213 | "chimney","choice","choose","chronic","chuckle","chunk","churn","cigar","cinnamon","circle", | ||
214 | "citizen","city","civil","claim","clap","clarify","claw","clay","clean","clerk", | ||
215 | "clever","click","client","cliff","climb","clinic","clip","clock","clog","close", | ||
216 | "cloth","cloud","clown","club","clump","cluster","clutch","coach","coast","coconut", | ||
217 | "code","coffee","coil","coin","collect","color","column","combine","come","comfort", | ||
218 | "comic","common","company","concert","conduct","confirm","congress","connect","consider","control", | ||
219 | "convince","cook","cool","copper","copy","coral","core","corn","correct","cost", | ||
220 | "cotton","couch","country","couple","course","cousin","cover","coyote","crack","cradle", | ||
221 | "craft","cram","crane","crash","crater","crawl","crazy","cream","credit","creek", | ||
222 | "crew","cricket","crime","crisp","critic","crop","cross","crouch","crowd","crucial", | ||
223 | "cruel","cruise","crumble","crunch","crush","cry","crystal","cube","culture","cup", | ||
224 | "cupboard","curious","current","curtain","curve","cushion","custom","cute","cycle","dad", | ||
225 | "damage","damp","dance","danger","daring","dash","daughter","dawn","day","deal", | ||
226 | "debate","debris","decade","december","decide","decline","decorate","decrease","deer","defense", | ||
227 | "define","defy","degree","delay","deliver","demand","demise","denial","dentist","deny", | ||
228 | "depart","depend","deposit","depth","deputy","derive","describe","desert","design","desk", | ||
229 | "despair","destroy","detail","detect","develop","device","devote","diagram","dial","diamond", | ||
230 | "diary","dice","diesel","diet","differ","digital","dignity","dilemma","dinner","dinosaur", | ||
231 | "direct","dirt","disagree","discover","disease","dish","dismiss","disorder","display","distance", | ||
232 | "divert","divide","divorce","dizzy","doctor","document","dog","doll","dolphin","domain", | ||
233 | "donate","donkey","donor","door","dose","double","dove","draft","dragon","drama", | ||
234 | "drastic","draw","dream","dress","drift","drill","drink","drip","drive","drop", | ||
235 | "drum","dry","duck","dumb","dune","during","dust","dutch","duty","dwarf", | ||
236 | "dynamic","eager","eagle","early","earn","earth","easily","east","easy","echo", | ||
237 | "ecology","economy","edge","edit","educate","effort","egg","eight","either","elbow", | ||
238 | "elder","electric","elegant","element","elephant","elevator","elite","else","embark","embody", | ||
239 | "embrace","emerge","emotion","employ","empower","empty","enable","enact","end","endless", | ||
240 | "endorse","enemy","energy","enforce","engage","engine","enhance","enjoy","enlist","enough", | ||
241 | "enrich","enroll","ensure","enter","entire","entry","envelope","episode","equal","equip", | ||
242 | "era","erase","erode","erosion","error","erupt","escape","essay","essence","estate", | ||
243 | "eternal","ethics","evidence","evil","evoke","evolve","exact","example","excess","exchange", | ||
244 | "excite","exclude","excuse","execute","exercise","exhaust","exhibit","exile","exist","exit", | ||
245 | "exotic","expand","expect","expire","explain","expose","express","extend","extra","eye", | ||
246 | "eyebrow","fabric","face","faculty","fade","faint","faith","fall","false","fame", | ||
247 | "family","famous","fan","fancy","fantasy","farm","fashion","fat","fatal","father", | ||
248 | "fatigue","fault","favorite","feature","february","federal","fee","feed","feel","female", | ||
249 | "fence","festival","fetch","fever","few","fiber","fiction","field","figure","file", | ||
250 | "film","filter","final","find","fine","finger","finish","fire","firm","first", | ||
251 | "fiscal","fish","fit","fitness","fix","flag","flame","flash","flat","flavor", | ||
252 | "flee","flight","flip","float","flock","floor","flower","fluid","flush","fly", | ||
253 | "foam","focus","fog","foil","fold","follow","food","foot","force","forest", | ||
254 | "forget","fork","fortune","forum","forward","fossil","foster","found","fox","fragile", | ||
255 | "frame","frequent","fresh","friend","fringe","frog","front","frost","frown","frozen", | ||
256 | "fruit","fuel","fun","funny","furnace","fury","future","gadget","gain","galaxy", | ||
257 | "gallery","game","gap","garage","garbage","garden","garlic","garment","gas","gasp", | ||
258 | "gate","gather","gauge","gaze","general","genius","genre","gentle","genuine","gesture", | ||
259 | "ghost","giant","gift","giggle","ginger","giraffe","girl","give","glad","glance", | ||
260 | "glare","glass","glide","glimpse","globe","gloom","glory","glove","glow","glue", | ||
261 | "goat","goddess","gold","good","goose","gorilla","gospel","gossip","govern","gown", | ||
262 | "grab","grace","grain","grant","grape","grass","gravity","great","green","grid", | ||
263 | "grief","grit","grocery","group","grow","grunt","guard","guess","guide","guilt", | ||
264 | "guitar","gun","gym","habit","hair","half","hammer","hamster","hand","happy", | ||
265 | "harbor","hard","harsh","harvest","hat","have","hawk","hazard","head","health", | ||
266 | "heart","heavy","hedgehog","height","hello","helmet","help","hen","hero","hidden", | ||
267 | "high","hill","hint","hip","hire","history","hobby","hockey","hold","hole", | ||
268 | "holiday","hollow","home","honey","hood","hope","horn","horror","horse","hospital", | ||
269 | "host","hotel","hour","hover","hub","huge","human","humble","humor","hundred", | ||
270 | "hungry","hunt","hurdle","hurry","hurt","husband","hybrid","ice","icon","idea", | ||
271 | "identify","idle","ignore","ill","illegal","illness","image","imitate","immense","immune", | ||
272 | "impact","impose","improve","impulse","inch","include","income","increase","index","indicate", | ||
273 | "indoor","industry","infant","inflict","inform","inhale","inherit","initial","inject","injury", | ||
274 | "inmate","inner","innocent","input","inquiry","insane","insect","inside","inspire","install", | ||
275 | "intact","interest","into","invest","invite","involve","iron","island","isolate","issue", | ||
276 | "item","ivory","jacket","jaguar","jar","jazz","jealous","jeans","jelly","jewel", | ||
277 | "job","join","joke","journey","joy","judge","juice","jump","jungle","junior", | ||
278 | "junk","just","kangaroo","keen","keep","ketchup","key","kick","kid","kidney", | ||
279 | "kind","kingdom","kiss","kit","kitchen","kite","kitten","kiwi","knee","knife", | ||
280 | "knock","know","lab","label","labor","ladder","lady","lake","lamp","language", | ||
281 | "laptop","large","later","latin","laugh","laundry","lava","law","lawn","lawsuit", | ||
282 | "layer","lazy","leader","leaf","learn","leave","lecture","left","leg","legal", | ||
283 | "legend","leisure","lemon","lend","length","lens","leopard","lesson","letter","level", | ||
284 | "liar","liberty","library","license","life","lift","light","like","limb","limit", | ||
285 | "link","lion","liquid","list","little","live","lizard","load","loan","lobster", | ||
286 | "local","lock","logic","lonely","long","loop","lottery","loud","lounge","love", | ||
287 | "loyal","lucky","luggage","lumber","lunar","lunch","luxury","lyrics","machine","mad", | ||
288 | "magic","magnet","maid","mail","main","major","make","mammal","man","manage", | ||
289 | "mandate","mango","mansion","manual","maple","marble","march","margin","marine","market", | ||
290 | "marriage","mask","mass","master","match","material","math","matrix","matter","maximum", | ||
291 | "maze","meadow","mean","measure","meat","mechanic","medal","media","melody","melt", | ||
292 | "member","memory","mention","menu","mercy","merge","merit","merry","mesh","message", | ||
293 | "metal","method","middle","midnight","milk","million","mimic","mind","minimum","minor", | ||
294 | "minute","miracle","mirror","misery","miss","mistake","mix","mixed","mixture","mobile", | ||
295 | "model","modify","mom","moment","monitor","monkey","monster","month","moon","moral", | ||
296 | "more","morning","mosquito","mother","motion","motor","mountain","mouse","move","movie", | ||
297 | "much","muffin","mule","multiply","muscle","museum","mushroom","music","must","mutual", | ||
298 | "myself","mystery","myth","naive","name","napkin","narrow","nasty","nation","nature", | ||
299 | "near","neck","need","negative","neglect","neither","nephew","nerve","nest","net", | ||
300 | "network","neutral","never","news","next","nice","night","noble","noise","nominee", | ||
301 | "noodle","normal","north","nose","notable","note","nothing","notice","novel","now", | ||
302 | "nuclear","number","nurse","nut","oak","obey","object","oblige","obscure","observe", | ||
303 | "obtain","obvious","occur","ocean","october","odor","off","offer","office","often", | ||
304 | "oil","okay","old","olive","olympic","omit","once","one","onion","online", | ||
305 | "only","open","opera","opinion","oppose","option","orange","orbit","orchard","order", | ||
306 | "ordinary","organ","orient","original","orphan","ostrich","other","outdoor","outer","output", | ||
307 | "outside","oval","oven","over","own","owner","oxygen","oyster","ozone","pact", | ||
308 | "paddle","page","pair","palace","palm","panda","panel","panic","panther","paper", | ||
309 | "parade","parent","park","parrot","party","pass","patch","path","patient","patrol", | ||
310 | "pattern","pause","pave","payment","peace","peanut","pear","peasant","pelican","pen", | ||
311 | "penalty","pencil","people","pepper","perfect","permit","person","pet","phone","photo", | ||
312 | "phrase","physical","piano","picnic","picture","piece","pig","pigeon","pill","pilot", | ||
313 | "pink","pioneer","pipe","pistol","pitch","pizza","place","planet","plastic","plate", | ||
314 | "play","please","pledge","pluck","plug","plunge","poem","poet","point","polar", | ||
315 | "pole","police","pond","pony","pool","popular","portion","position","possible","post", | ||
316 | "potato","pottery","poverty","powder","power","practice","praise","predict","prefer","prepare", | ||
317 | "present","pretty","prevent","price","pride","primary","print","priority","prison","private", | ||
318 | "prize","problem","process","produce","profit","program","project","promote","proof","property", | ||
319 | "prosper","protect","proud","provide","public","pudding","pull","pulp","pulse","pumpkin", | ||
320 | "punch","pupil","puppy","purchase","purity","purpose","purse","push","put","puzzle", | ||
321 | "pyramid","quality","quantum","quarter","question","quick","quit","quiz","quote","rabbit", | ||
322 | "raccoon","race","rack","radar","radio","rail","rain","raise","rally","ramp", | ||
323 | "ranch","random","range","rapid","rare","rate","rather","raven","raw","razor", | ||
324 | "ready","real","reason","rebel","rebuild","recall","receive","recipe","record","recycle", | ||
325 | "reduce","reflect","reform","refuse","region","regret","regular","reject","relax","release", | ||
326 | "relief","rely","remain","remember","remind","remove","render","renew","rent","reopen", | ||
327 | "repair","repeat","replace","report","require","rescue","resemble","resist","resource","response", | ||
328 | "result","retire","retreat","return","reunion","reveal","review","reward","rhythm","rib", | ||
329 | "ribbon","rice","rich","ride","ridge","rifle","right","rigid","ring","riot", | ||
330 | "ripple","risk","ritual","rival","river","road","roast","robot","robust","rocket", | ||
331 | "romance","roof","rookie","room","rose","rotate","rough","round","route","royal", | ||
332 | "rubber","rude","rug","rule","run","runway","rural","sad","saddle","sadness", | ||
333 | "safe","sail","salad","salmon","salon","salt","salute","same","sample","sand", | ||
334 | "satisfy","satoshi","sauce","sausage","save","say","scale","scan","scare","scatter", | ||
335 | "scene","scheme","school","science","scissors","scorpion","scout","scrap","screen","script", | ||
336 | "scrub","sea","search","season","seat","second","secret","section","security","seed", | ||
337 | "seek","segment","select","sell","seminar","senior","sense","sentence","series","service", | ||
338 | "session","settle","setup","seven","shadow","shaft","shallow","share","shed","shell", | ||
339 | "sheriff","shield","shift","shine","ship","shiver","shock","shoe","shoot","shop", | ||
340 | "short","shoulder","shove","shrimp","shrug","shuffle","shy","sibling","sick","side", | ||
341 | "siege","sight","sign","silent","silk","silly","silver","similar","simple","since", | ||
342 | "sing","siren","sister","situate","six","size","skate","sketch","ski","skill", | ||
343 | "skin","skirt","skull","slab","slam","sleep","slender","slice","slide","slight", | ||
344 | "slim","slogan","slot","slow","slush","small","smart","smile","smoke","smooth", | ||
345 | "snack","snake","snap","sniff","snow","soap","soccer","social","sock","soda", | ||
346 | "soft","solar","soldier","solid","solution","solve","someone","song","soon","sorry", | ||
347 | "sort","soul","sound","soup","source","south","space","spare","spatial","spawn", | ||
348 | "speak","special","speed","spell","spend","sphere","spice","spider","spike","spin", | ||
349 | "spirit","split","spoil","sponsor","spoon","sport","spot","spray","spread","spring", | ||
350 | "spy","square","squeeze","squirrel","stable","stadium","staff","stage","stairs","stamp", | ||
351 | "stand","start","state","stay","steak","steel","stem","step","stereo","stick", | ||
352 | "still","sting","stock","stomach","stone","stool","story","stove","strategy","street", | ||
353 | "strike","strong","struggle","student","stuff","stumble","style","subject","submit","subway", | ||
354 | "success","such","sudden","suffer","sugar","suggest","suit","summer","sun","sunny", | ||
355 | "sunset","super","supply","supreme","sure","surface","surge","surprise","surround","survey", | ||
356 | "suspect","sustain","swallow","swamp","swap","swarm","swear","sweet","swift","swim", | ||
357 | "swing","switch","sword","symbol","symptom","syrup","system","table","tackle","tag", | ||
358 | "tail","talent","talk","tank","tape","target","task","taste","tattoo","taxi", | ||
359 | "teach","team","tell","ten","tenant","tennis","tent","term","test","text", | ||
360 | "thank","that","theme","then","theory","there","they","thing","this","thought", | ||
361 | "three","thrive","throw","thumb","thunder","ticket","tide","tiger","tilt","timber", | ||
362 | "time","tiny","tip","tired","tissue","title","toast","tobacco","today","toddler", | ||
363 | "toe","together","toilet","token","tomato","tomorrow","tone","tongue","tonight","tool", | ||
364 | "tooth","top","topic","topple","torch","tornado","tortoise","toss","total","tourist", | ||
365 | "toward","tower","town","toy","track","trade","traffic","tragic","train","transfer", | ||
366 | "trap","trash","travel","tray","treat","tree","trend","trial","tribe","trick", | ||
367 | "trigger","trim","trip","trophy","trouble","truck","true","truly","trumpet","trust", | ||
368 | "truth","try","tube","tuition","tumble","tuna","tunnel","turkey","turn","turtle", | ||
369 | "twelve","twenty","twice","twin","twist","two","type","typical","ugly","umbrella", | ||
370 | "unable","unaware","uncle","uncover","under","undo","unfair","unfold","unhappy","uniform", | ||
371 | "unique","unit","universe","unknown","unlock","until","unusual","unveil","update","upgrade", | ||
372 | "uphold","upon","upper","upset","urban","urge","usage","use","used","useful", | ||
373 | "useless","usual","utility","vacant","vacuum","vague","valid","valley","valve","van", | ||
374 | "vanish","vapor","various","vast","vault","vehicle","velvet","vendor","venture","venue", | ||
375 | "verb","verify","version","very","vessel","veteran","viable","vibrant","vicious","victory", | ||
376 | "video","view","village","vintage","violin","virtual","virus","visa","visit","visual", | ||
377 | "vital","vivid","vocal","voice","void","volcano","volume","vote","voyage","wage", | ||
378 | "wagon","wait","walk","wall","walnut","want","warfare","warm","warrior","wash", | ||
379 | "wasp","waste","water","wave","way","wealth","weapon","wear","weasel","weather", | ||
380 | "web","wedding","weekend","weird","welcome","west","wet","whale","what","wheat", | ||
381 | "wheel","when","where","whip","whisper","wide","width","wife","wild","will", | ||
382 | "win","window","wine","wing","wink","winner","winter","wire","wisdom","wise", | ||
383 | "wish","witness","wolf","woman","wonder","wood","wool","word","work","world", | ||
384 | "worry","worth","wrap","wreck","wrestle","wrist","write","wrong","yard","year", | ||
385 | "yellow","you","young","youth","zebra","zero","zone","zoo"] | ||
386 | }; | ||