Mnemonic for electrum

M committed Nov 27, 2020 at 11:52 UTC 9ad76376d9cf5f1b1a69467c9a286d4b32404aed
5 files changed +2322 -7
lib/bitcoin/bitcoin_mnemonic.dart new
+2297
@@ -0,0 +1,2297 @@
1 +import 'dart:convert';
2 +import 'dart:math';
3 +import 'dart:typed_data';
4 +import 'package:crypto/crypto.dart';
5 +import 'package:unorm_dart/unorm_dart.dart' as unorm;
6 +import 'package:cryptography/cryptography.dart' as cryptography;
7 +
8 +const segwit = '100';
9 +final wordlist = englishWordlist;
10 +
11 +Uint8List randomBytes(int length, {bool secure = false}) {
12 + assert(length > 0);
13 +
14 + final random = secure ? Random.secure() : Random();
15 + final ret = Uint8List(length);
16 +
17 + for (var i = 0; i < length; i++) {
18 + ret[i] = random.nextInt(256);
19 + }
20 +
21 + return ret;
22 +}
23 +
24 +double logBase(num x, num base) => log(x) / log(base);
25 +
26 +String mnemonicEncode(int i) {
27 + var _i = i;
28 + final n = wordlist.length;
29 + final words = <String>[];
30 +
31 + while (_i > 0) {
32 + final x = i % n;
33 + _i = (i / n).floor();
34 + words.add(wordlist[x]);
35 + }
36 +
37 + return words.join(' ');
38 +}
39 +
40 +int mnemonicDecode(String seed) {
41 + var i = 0;
42 + final n = wordlist.length;
43 + final words = seed.split(' ');
44 +
45 + while (words.length > 0) {
46 + final word = words.removeLast();
47 + final k = wordlist.indexOf(word);
48 + i = i * n + k;
49 + }
50 +
51 + return i;
52 +}
53 +
54 +bool isNewSeed(String seed, {String prefix = segwit}) {
55 + final hmacSha512 = Hmac(sha512, utf8.encode('Seed version'));
56 + final digest = hmacSha512.convert(utf8.encode(normalizeText(seed)));
57 + final hx = digest.toString();
58 + return hx.startsWith(prefix.toLowerCase());
59 +}
60 +
61 +void maskBytes(Uint8List bytes, int bits) {
62 + final skipCount = (bits / 8).floor();
63 + var lastByte = (1 << bits % 8) - 1;
64 +
65 + for (var i = bytes.length - 1 - skipCount; i >= 0; i--) {
66 + bytes[i] &= lastByte;
67 +
68 + if (lastByte > 0) {
69 + lastByte = 0;
70 + }
71 + }
72 +}
73 +
74 +String bufferToBin(Uint8List data) {
75 + final q1 = data.map((e) => e.toRadixString(2).padLeft(8, '0'));
76 + final q2 = q1.join('');
77 + return q2;
78 +}
79 +
80 +String encode(Uint8List data) {
81 + final dataBitLen = data.length * 8;
82 + final wordBitLen = logBase(wordlist.length, 2).ceil();
83 + final wordCount = (dataBitLen / wordBitLen).floor();
84 + maskBytes(data, wordCount * wordBitLen);
85 + final bin = bufferToBin(data);
86 + final binStr = bin.substring(bin.length - (wordCount * wordBitLen));
87 + final result = <Object>[];
88 +
89 + for (var i = 0; i < wordCount; i++) {
90 + final wordBin = binStr.substring(i * wordBitLen, (i + 1) * wordBitLen);
91 + result.add(wordlist[int.parse(wordBin, radix: 2)]);
92 + }
93 +
94 + return result.join(' ');
95 +}
96 +
97 +List<bool> prefixMatches(String source, List<String> prefixes) {
98 + final hmacSha512 = Hmac(sha512, utf8.encode('Seed version'));
99 + final digest = hmacSha512.convert(utf8.encode(normalizeText(source)));
100 + final hx = digest.toString();
101 +
102 + return prefixes.map((prefix) => hx.startsWith(prefix.toLowerCase())).toList();
103 +}
104 +
105 +String generateMnemonic({int strength = 132, String prefix = segwit}) {
106 + final wordBitlen = logBase(wordlist.length, 2).ceil();
107 + final wordCount = strength / wordBitlen;
108 + final byteCount = ((wordCount * wordBitlen).ceil() / 8).ceil();
109 + var result = '';
110 +
111 + do {
112 + final bytes = randomBytes(byteCount);
113 + maskBytes(bytes, strength);
114 + result = encode(bytes);
115 + } while (!prefixMatches(result, [prefix]).first);
116 +
117 + return result;
118 +}
119 +
120 +Uint8List mnemonicToSeedBytes(String mnemonic, {String prefix = segwit}) {
121 + final pbkdf2 = cryptography.Pbkdf2(
122 + macAlgorithm: cryptography.Hmac(cryptography.sha512),
123 + iterations: 2048,
124 + bits: 512);
125 + final text = normalizeText(mnemonic);
126 +
127 + return pbkdf2.deriveBitsSync(text.codeUnits,
128 + nonce: cryptography.Nonce('electrum'.codeUnits));
129 +}
130 +
131 +final COMBININGCODEPOINTS = combiningcodepoints();
132 +
133 +List<int> combiningcodepoints() {
134 + final source = '300:34e|350:36f|483:487|591:5bd|5bf|5c1|5c2|5c4|5c5|5c7|610:61a|64b:65f|670|' +
135 + '6d6:6dc|6df:6e4|6e7|6e8|6ea:6ed|711|730:74a|7eb:7f3|816:819|81b:823|825:827|' +
136 + '829:82d|859:85b|8d4:8e1|8e3:8ff|93c|94d|951:954|9bc|9cd|a3c|a4d|abc|acd|b3c|' +
137 + 'b4d|bcd|c4d|c55|c56|cbc|ccd|d4d|dca|e38:e3a|e48:e4b|eb8|eb9|ec8:ecb|f18|f19|' +
138 + 'f35|f37|f39|f71|f72|f74|f7a:f7d|f80|f82:f84|f86|f87|fc6|1037|1039|103a|108d|' +
139 + '135d:135f|1714|1734|17d2|17dd|18a9|1939:193b|1a17|1a18|1a60|1a75:1a7c|1a7f|' +
140 + '1ab0:1abd|1b34|1b44|1b6b:1b73|1baa|1bab|1be6|1bf2|1bf3|1c37|1cd0:1cd2|' +
141 + '1cd4:1ce0|1ce2:1ce8|1ced|1cf4|1cf8|1cf9|1dc0:1df5|1dfb:1dff|20d0:20dc|20e1|' +
142 + '20e5:20f0|2cef:2cf1|2d7f|2de0:2dff|302a:302f|3099|309a|a66f|a674:a67d|a69e|' +
143 + 'a69f|a6f0|a6f1|a806|a8c4|a8e0:a8f1|a92b:a92d|a953|a9b3|a9c0|aab0|aab2:aab4|' +
144 + 'aab7|aab8|aabe|aabf|aac1|aaf6|abed|fb1e|fe20:fe2f|101fd|102e0|10376:1037a|' +
145 + '10a0d|10a0f|10a38:10a3a|10a3f|10ae5|10ae6|11046|1107f|110b9|110ba|11100:11102|' +
146 + '11133|11134|11173|111c0|111ca|11235|11236|112e9|112ea|1133c|1134d|11366:1136c|' +
147 + '11370:11374|11442|11446|114c2|114c3|115bf|115c0|1163f|116b6|116b7|1172b|11c3f|' +
148 + '16af0:16af4|16b30:16b36|1bc9e|1d165:1d169|1d16d:1d172|1d17b:1d182|1d185:1d18b|' +
149 + '1d1aa:1d1ad|1d242:1d244|1e000:1e006|1e008:1e018|1e01b:1e021|1e023|1e024|' +
150 + '1e026:1e02a|1e8d0:1e8d6|1e944:1e94a';
151 +
152 + return source.split('|').map((e) {
153 + if (e.contains(':')) {
154 + return e.split(':').map((hex) => int.parse(hex, radix: 16));
155 + }
156 +
157 + return int.parse(e, radix: 16);
158 + }).fold(<int>[], (List<int> acc, element) {
159 + if (element is List) {
160 + for (var i = element[0] as int; i <= (element[1] as int); i++) {}
161 + } else if (element is int) {
162 + acc.add(element);
163 + }
164 +
165 + return acc;
166 + }).toList();
167 +}
168 +
169 +String removeCombiningCharacters(String source) {
170 + return source
171 + .split('')
172 + .where((char) => !COMBININGCODEPOINTS.contains(char.codeUnits.first))
173 + .join('');
174 +}
175 +
176 +bool isCJK(String char) {
177 + final n = char.codeUnitAt(0);
178 +
179 + for (var x in CJKINTERVALS) {
180 + final imin = x[0] as num;
181 + final imax = x[1] as num;
182 +
183 + if (n >= imin && n <= imax) return true;
184 + }
185 +
186 + return false;
187 +}
188 +
189 +String removeCJKSpaces(String source) {
190 + final splitted = source.split('');
191 + final filtered = <String>[];
192 +
193 + for (var i = 0; i < splitted.length; i++) {
194 + final char = splitted[i];
195 + final isSpace = char.trim() == '';
196 + final prevIsCJK = i != 0 && isCJK(splitted[i - 1]);
197 + final nextIsCJK = i != splitted.length - 1 && isCJK(splitted[i + 1]);
198 +
199 + if (!(isSpace && prevIsCJK && nextIsCJK)) {
200 + filtered.add(char);
201 + }
202 + }
203 +
204 + return filtered.join('');
205 +}
206 +
207 +String normalizeText(String source) {
208 + final res = removeCombiningCharacters(unorm.nfkd(source).toLowerCase())
209 + .trim()
210 + .split('/\s+/')
211 + .join(' ');
212 +
213 + return removeCJKSpaces(res);
214 +}
215 +
216 +const CJKINTERVALS = [
217 + [0x4e00, 0x9fff, 'CJK Unified Ideographs'],
218 + [0x3400, 0x4dbf, 'CJK Unified Ideographs Extension A'],
219 + [0x20000, 0x2a6df, 'CJK Unified Ideographs Extension B'],
220 + [0x2a700, 0x2b73f, 'CJK Unified Ideographs Extension C'],
221 + [0x2b740, 0x2b81f, 'CJK Unified Ideographs Extension D'],
222 + [0xf900, 0xfaff, 'CJK Compatibility Ideographs'],
223 + [0x2f800, 0x2fa1d, 'CJK Compatibility Ideographs Supplement'],
224 + [0x3190, 0x319f, 'Kanbun'],
225 + [0x2e80, 0x2eff, 'CJK Radicals Supplement'],
226 + [0x2f00, 0x2fdf, 'CJK Radicals'],
227 + [0x31c0, 0x31ef, 'CJK Strokes'],
228 + [0x2ff0, 0x2fff, 'Ideographic Description Characters'],
229 + [0xe0100, 0xe01ef, 'Variation Selectors Supplement'],
230 + [0x3100, 0x312f, 'Bopomofo'],
231 + [0x31a0, 0x31bf, 'Bopomofo Extended'],
232 + [0xff00, 0xffef, 'Halfwidth and Fullwidth Forms'],
233 + [0x3040, 0x309f, 'Hiragana'],
234 + [0x30a0, 0x30ff, 'Katakana'],
235 + [0x31f0, 0x31ff, 'Katakana Phonetic Extensions'],
236 + [0x1b000, 0x1b0ff, 'Kana Supplement'],
237 + [0xac00, 0xd7af, 'Hangul Syllables'],
238 + [0x1100, 0x11ff, 'Hangul Jamo'],
239 + [0xa960, 0xa97f, 'Hangul Jamo Extended A'],
240 + [0xd7b0, 0xd7ff, 'Hangul Jamo Extended B'],
241 + [0x3130, 0x318f, 'Hangul Compatibility Jamo'],
242 + [0xa4d0, 0xa4ff, 'Lisu'],
243 + [0x16f00, 0x16f9f, 'Miao'],
244 + [0xa000, 0xa48f, 'Yi Syllables'],
245 + [0xa490, 0xa4cf, 'Yi Radicals'],
246 +];
247 +
248 +final englishWordlist = <String>[
249 + 'abandon',
250 + 'ability',
251 + 'able',
252 + 'about',
253 + 'above',
254 + 'absent',
255 + 'absorb',
256 + 'abstract',
257 + 'absurd',
258 + 'abuse',
259 + 'access',
260 + 'accident',
261 + 'account',
262 + 'accuse',
263 + 'achieve',
264 + 'acid',
265 + 'acoustic',
266 + 'acquire',
267 + 'across',
268 + 'act',
269 + 'action',
270 + 'actor',
271 + 'actress',
272 + 'actual',
273 + 'adapt',
274 + 'add',
275 + 'addict',
276 + 'address',
277 + 'adjust',
278 + 'admit',
279 + 'adult',
280 + 'advance',
281 + 'advice',
282 + 'aerobic',
283 + 'affair',
284 + 'afford',
285 + 'afraid',
286 + 'again',
287 + 'age',
288 + 'agent',
289 + 'agree',
290 + 'ahead',
291 + 'aim',
292 + 'air',
293 + 'airport',
294 + 'aisle',
295 + 'alarm',
296 + 'album',
297 + 'alcohol',
298 + 'alert',
299 + 'alien',
300 + 'all',
301 + 'alley',
302 + 'allow',
303 + 'almost',
304 + 'alone',
305 + 'alpha',
306 + 'already',
307 + 'also',
308 + 'alter',
309 + 'always',
310 + 'amateur',
311 + 'amazing',
312 + 'among',
313 + 'amount',
314 + 'amused',
315 + 'analyst',
316 + 'anchor',
317 + 'ancient',
318 + 'anger',
319 + 'angle',
320 + 'angry',
321 + 'animal',
322 + 'ankle',
323 + 'announce',
324 + 'annual',
325 + 'another',
326 + 'answer',
327 + 'antenna',
328 + 'antique',
329 + 'anxiety',
330 + 'any',
331 + 'apart',
332 + 'apology',
333 + 'appear',
334 + 'apple',
335 + 'approve',
336 + 'april',
337 + 'arch',
338 + 'arctic',
339 + 'area',
340 + 'arena',
341 + 'argue',
342 + 'arm',
343 + 'armed',
344 + 'armor',
345 + 'army',
346 + 'around',
347 + 'arrange',
348 + 'arrest',
349 + 'arrive',
350 + 'arrow',
351 + 'art',
352 + 'artefact',
353 + 'artist',
354 + 'artwork',
355 + 'ask',
356 + 'aspect',
357 + 'assault',
358 + 'asset',
359 + 'assist',
360 + 'assume',
361 + 'asthma',
362 + 'athlete',
363 + 'atom',
364 + 'attack',
365 + 'attend',
366 + 'attitude',
367 + 'attract',
368 + 'auction',
369 + 'audit',
370 + 'august',
371 + 'aunt',
372 + 'author',
373 + 'auto',
374 + 'autumn',
375 + 'average',
376 + 'avocado',
377 + 'avoid',
378 + 'awake',
379 + 'aware',
380 + 'away',
381 + 'awesome',
382 + 'awful',
383 + 'awkward',
384 + 'axis',
385 + 'baby',
386 + 'bachelor',
387 + 'bacon',
388 + 'badge',
389 + 'bag',
390 + 'balance',
391 + 'balcony',
392 + 'ball',
393 + 'bamboo',
394 + 'banana',
395 + 'banner',
396 + 'bar',
397 + 'barely',
398 + 'bargain',
399 + 'barrel',
400 + 'base',
401 + 'basic',
402 + 'basket',
403 + 'battle',
404 + 'beach',
405 + 'bean',
406 + 'beauty',
407 + 'because',
408 + 'become',
409 + 'beef',
410 + 'before',
411 + 'begin',
412 + 'behave',
413 + 'behind',
414 + 'believe',
415 + 'below',
416 + 'belt',
417 + 'bench',
418 + 'benefit',
419 + 'best',
420 + 'betray',
421 + 'better',
422 + 'between',
423 + 'beyond',
424 + 'bicycle',
425 + 'bid',
426 + 'bike',
427 + 'bind',
428 + 'biology',
429 + 'bird',
430 + 'birth',
431 + 'bitter',
432 + 'black',
433 + 'blade',
434 + 'blame',
435 + 'blanket',
436 + 'blast',
437 + 'bleak',
438 + 'bless',
439 + 'blind',
440 + 'blood',
441 + 'blossom',
442 + 'blouse',
443 + 'blue',
444 + 'blur',
445 + 'blush',
446 + 'board',
447 + 'boat',
448 + 'body',
449 + 'boil',
450 + 'bomb',
451 + 'bone',
452 + 'bonus',
453 + 'book',
454 + 'boost',
455 + 'border',
456 + 'boring',
457 + 'borrow',
458 + 'boss',
459 + 'bottom',
460 + 'bounce',
461 + 'box',
462 + 'boy',
463 + 'bracket',
464 + 'brain',
465 + 'brand',
466 + 'brass',
467 + 'brave',
468 + 'bread',
469 + 'breeze',
470 + 'brick',
471 + 'bridge',
472 + 'brief',
473 + 'bright',
474 + 'bring',
475 + 'brisk',
476 + 'broccoli',
477 + 'broken',
478 + 'bronze',
479 + 'broom',
480 + 'brother',
481 + 'brown',
482 + 'brush',
483 + 'bubble',
484 + 'buddy',
485 + 'budget',
486 + 'buffalo',
487 + 'build',
488 + 'bulb',
489 + 'bulk',
490 + 'bullet',
491 + 'bundle',
492 + 'bunker',
493 + 'burden',
494 + 'burger',
495 + 'burst',
496 + 'bus',
497 + 'business',
498 + 'busy',
499 + 'butter',
500 + 'buyer',
501 + 'buzz',
502 + 'cabbage',
503 + 'cabin',
504 + 'cable',
505 + 'cactus',
506 + 'cage',
507 + 'cake',
508 + 'call',
509 + 'calm',
510 + 'camera',
511 + 'camp',
512 + 'can',
513 + 'canal',
514 + 'cancel',
515 + 'candy',
516 + 'cannon',
517 + 'canoe',
518 + 'canvas',
519 + 'canyon',
520 + 'capable',
521 + 'capital',
522 + 'captain',
523 + 'car',
524 + 'carbon',
525 + 'card',
526 + 'cargo',
527 + 'carpet',
528 + 'carry',
529 + 'cart',
530 + 'case',
531 + 'cash',
532 + 'casino',
533 + 'castle',
534 + 'casual',
535 + 'cat',
536 + 'catalog',
537 + 'catch',
538 + 'category',
539 + 'cattle',
540 + 'caught',
541 + 'cause',
542 + 'caution',
543 + 'cave',
544 + 'ceiling',
545 + 'celery',
546 + 'cement',
547 + 'census',
548 + 'century',
549 + 'cereal',
550 + 'certain',
551 + 'chair',
552 + 'chalk',
553 + 'champion',
554 + 'change',
555 + 'chaos',
556 + 'chapter',
557 + 'charge',
558 + 'chase',
559 + 'chat',
560 + 'cheap',
561 + 'check',
562 + 'cheese',
563 + 'chef',
564 + 'cherry',
565 + 'chest',
566 + 'chicken',
567 + 'chief',
568 + 'child',
569 + 'chimney',
570 + 'choice',
571 + 'choose',
572 + 'chronic',
573 + 'chuckle',
574 + 'chunk',
575 + 'churn',
576 + 'cigar',
577 + 'cinnamon',
578 + 'circle',
579 + 'citizen',
580 + 'city',
581 + 'civil',
582 + 'claim',
583 + 'clap',
584 + 'clarify',
585 + 'claw',
586 + 'clay',
587 + 'clean',
588 + 'clerk',
589 + 'clever',
590 + 'click',
591 + 'client',
592 + 'cliff',
593 + 'climb',
594 + 'clinic',
595 + 'clip',
596 + 'clock',
597 + 'clog',
598 + 'close',
599 + 'cloth',
600 + 'cloud',
601 + 'clown',
602 + 'club',
603 + 'clump',
604 + 'cluster',
605 + 'clutch',
606 + 'coach',
607 + 'coast',
608 + 'coconut',
609 + 'code',
610 + 'coffee',
611 + 'coil',
612 + 'coin',
613 + 'collect',
614 + 'color',
615 + 'column',
616 + 'combine',
617 + 'come',
618 + 'comfort',
619 + 'comic',
620 + 'common',
621 + 'company',
622 + 'concert',
623 + 'conduct',
624 + 'confirm',
625 + 'congress',
626 + 'connect',
627 + 'consider',
628 + 'control',
629 + 'convince',
630 + 'cook',
631 + 'cool',
632 + 'copper',
633 + 'copy',
634 + 'coral',
635 + 'core',
636 + 'corn',
637 + 'correct',
638 + 'cost',
639 + 'cotton',
640 + 'couch',
641 + 'country',
642 + 'couple',
643 + 'course',
644 + 'cousin',
645 + 'cover',
646 + 'coyote',
647 + 'crack',
648 + 'cradle',
649 + 'craft',
650 + 'cram',
651 + 'crane',
652 + 'crash',
653 + 'crater',
654 + 'crawl',
655 + 'crazy',
656 + 'cream',
657 + 'credit',
658 + 'creek',
659 + 'crew',
660 + 'cricket',
661 + 'crime',
662 + 'crisp',
663 + 'critic',
664 + 'crop',
665 + 'cross',
666 + 'crouch',
667 + 'crowd',
668 + 'crucial',
669 + 'cruel',
670 + 'cruise',
671 + 'crumble',
672 + 'crunch',
673 + 'crush',
674 + 'cry',
675 + 'crystal',
676 + 'cube',
677 + 'culture',
678 + 'cup',
679 + 'cupboard',
680 + 'curious',
681 + 'current',
682 + 'curtain',
683 + 'curve',
684 + 'cushion',
685 + 'custom',
686 + 'cute',
687 + 'cycle',
688 + 'dad',
689 + 'damage',
690 + 'damp',
691 + 'dance',
692 + 'danger',
693 + 'daring',
694 + 'dash',
695 + 'daughter',
696 + 'dawn',
697 + 'day',
698 + 'deal',
699 + 'debate',
700 + 'debris',
701 + 'decade',
702 + 'december',
703 + 'decide',
704 + 'decline',
705 + 'decorate',
706 + 'decrease',
707 + 'deer',
708 + 'defense',
709 + 'define',
710 + 'defy',
711 + 'degree',
712 + 'delay',
713 + 'deliver',
714 + 'demand',
715 + 'demise',
716 + 'denial',
717 + 'dentist',
718 + 'deny',
719 + 'depart',
720 + 'depend',
721 + 'deposit',
722 + 'depth',
723 + 'deputy',
724 + 'derive',
725 + 'describe',
726 + 'desert',
727 + 'design',
728 + 'desk',
729 + 'despair',
730 + 'destroy',
731 + 'detail',
732 + 'detect',
733 + 'develop',
734 + 'device',
735 + 'devote',
736 + 'diagram',
737 + 'dial',
738 + 'diamond',
739 + 'diary',
740 + 'dice',
741 + 'diesel',
742 + 'diet',
743 + 'differ',
744 + 'digital',
745 + 'dignity',
746 + 'dilemma',
747 + 'dinner',
748 + 'dinosaur',
749 + 'direct',
750 + 'dirt',
751 + 'disagree',
752 + 'discover',
753 + 'disease',
754 + 'dish',
755 + 'dismiss',
756 + 'disorder',
757 + 'display',
758 + 'distance',
759 + 'divert',
760 + 'divide',
761 + 'divorce',
762 + 'dizzy',
763 + 'doctor',
764 + 'document',
765 + 'dog',
766 + 'doll',
767 + 'dolphin',
768 + 'domain',
769 + 'donate',
770 + 'donkey',
771 + 'donor',
772 + 'door',
773 + 'dose',
774 + 'double',
775 + 'dove',
776 + 'draft',
777 + 'dragon',
778 + 'drama',
779 + 'drastic',
780 + 'draw',
781 + 'dream',
782 + 'dress',
783 + 'drift',
784 + 'drill',
785 + 'drink',
786 + 'drip',
787 + 'drive',
788 + 'drop',
789 + 'drum',
790 + 'dry',
791 + 'duck',
792 + 'dumb',
793 + 'dune',
794 + 'during',
795 + 'dust',
796 + 'dutch',
797 + 'duty',
798 + 'dwarf',
799 + 'dynamic',
800 + 'eager',
801 + 'eagle',
802 + 'early',
803 + 'earn',
804 + 'earth',
805 + 'easily',
806 + 'east',
807 + 'easy',
808 + 'echo',
809 + 'ecology',
810 + 'economy',
811 + 'edge',
812 + 'edit',
813 + 'educate',
814 + 'effort',
815 + 'egg',
816 + 'eight',
817 + 'either',
818 + 'elbow',
819 + 'elder',
820 + 'electric',
821 + 'elegant',
822 + 'element',
823 + 'elephant',
824 + 'elevator',
825 + 'elite',
826 + 'else',
827 + 'embark',
828 + 'embody',
829 + 'embrace',
830 + 'emerge',
831 + 'emotion',
832 + 'employ',
833 + 'empower',
834 + 'empty',
835 + 'enable',
836 + 'enact',
837 + 'end',
838 + 'endless',
839 + 'endorse',
840 + 'enemy',
841 + 'energy',
842 + 'enforce',
843 + 'engage',
844 + 'engine',
845 + 'enhance',
846 + 'enjoy',
847 + 'enlist',
848 + 'enough',
849 + 'enrich',
850 + 'enroll',
851 + 'ensure',
852 + 'enter',
853 + 'entire',
854 + 'entry',
855 + 'envelope',
856 + 'episode',
857 + 'equal',
858 + 'equip',
859 + 'era',
860 + 'erase',
861 + 'erode',
862 + 'erosion',
863 + 'error',
864 + 'erupt',
865 + 'escape',
866 + 'essay',
867 + 'essence',
868 + 'estate',
869 + 'eternal',
870 + 'ethics',
871 + 'evidence',
872 + 'evil',
873 + 'evoke',
874 + 'evolve',
875 + 'exact',
876 + 'example',
877 + 'excess',
878 + 'exchange',
879 + 'excite',
880 + 'exclude',
881 + 'excuse',
882 + 'execute',
883 + 'exercise',
884 + 'exhaust',
885 + 'exhibit',
886 + 'exile',
887 + 'exist',
888 + 'exit',
889 + 'exotic',
890 + 'expand',
891 + 'expect',
892 + 'expire',
893 + 'explain',
894 + 'expose',
895 + 'express',
896 + 'extend',
897 + 'extra',
898 + 'eye',
899 + 'eyebrow',
900 + 'fabric',
901 + 'face',
902 + 'faculty',
903 + 'fade',
904 + 'faint',
905 + 'faith',
906 + 'fall',
907 + 'false',
908 + 'fame',
909 + 'family',
910 + 'famous',
911 + 'fan',
912 + 'fancy',
913 + 'fantasy',
914 + 'farm',
915 + 'fashion',
916 + 'fat',
917 + 'fatal',
918 + 'father',
919 + 'fatigue',
920 + 'fault',
921 + 'favorite',
922 + 'feature',
923 + 'february',
924 + 'federal',
925 + 'fee',
926 + 'feed',
927 + 'feel',
928 + 'female',
929 + 'fence',
930 + 'festival',
931 + 'fetch',
932 + 'fever',
933 + 'few',
934 + 'fiber',
935 + 'fiction',
936 + 'field',
937 + 'figure',
938 + 'file',
939 + 'film',
940 + 'filter',
941 + 'final',
942 + 'find',
943 + 'fine',
944 + 'finger',
945 + 'finish',
946 + 'fire',
947 + 'firm',
948 + 'first',
949 + 'fiscal',
950 + 'fish',
951 + 'fit',
952 + 'fitness',
953 + 'fix',
954 + 'flag',
955 + 'flame',
956 + 'flash',
957 + 'flat',
958 + 'flavor',
959 + 'flee',
960 + 'flight',
961 + 'flip',
962 + 'float',
963 + 'flock',
964 + 'floor',
965 + 'flower',
966 + 'fluid',
967 + 'flush',
968 + 'fly',
969 + 'foam',
970 + 'focus',
971 + 'fog',
972 + 'foil',
973 + 'fold',
974 + 'follow',
975 + 'food',
976 + 'foot',
977 + 'force',
978 + 'forest',
979 + 'forget',
980 + 'fork',
981 + 'fortune',
982 + 'forum',
983 + 'forward',
984 + 'fossil',
985 + 'foster',
986 + 'found',
987 + 'fox',
988 + 'fragile',
989 + 'frame',
990 + 'frequent',
991 + 'fresh',
992 + 'friend',
993 + 'fringe',
994 + 'frog',
995 + 'front',
996 + 'frost',
997 + 'frown',
998 + 'frozen',
999 + 'fruit',
1000 + 'fuel',
1001 + 'fun',
1002 + 'funny',
1003 + 'furnace',
1004 + 'fury',
1005 + 'future',
1006 + 'gadget',
1007 + 'gain',
1008 + 'galaxy',
1009 + 'gallery',
1010 + 'game',
1011 + 'gap',
1012 + 'garage',
1013 + 'garbage',
1014 + 'garden',
1015 + 'garlic',
1016 + 'garment',
1017 + 'gas',
1018 + 'gasp',
1019 + 'gate',
1020 + 'gather',
1021 + 'gauge',
1022 + 'gaze',
1023 + 'general',
1024 + 'genius',
1025 + 'genre',
1026 + 'gentle',
1027 + 'genuine',
1028 + 'gesture',
1029 + 'ghost',
1030 + 'giant',
1031 + 'gift',
1032 + 'giggle',
1033 + 'ginger',
1034 + 'giraffe',
1035 + 'girl',
1036 + 'give',
1037 + 'glad',
1038 + 'glance',
1039 + 'glare',
1040 + 'glass',
1041 + 'glide',
1042 + 'glimpse',
1043 + 'globe',
1044 + 'gloom',
1045 + 'glory',
1046 + 'glove',
1047 + 'glow',
1048 + 'glue',
1049 + 'goat',
1050 + 'goddess',
1051 + 'gold',
1052 + 'good',
1053 + 'goose',
1054 + 'gorilla',
1055 + 'gospel',
1056 + 'gossip',
1057 + 'govern',
1058 + 'gown',
1059 + 'grab',
1060 + 'grace',
1061 + 'grain',
1062 + 'grant',
1063 + 'grape',
1064 + 'grass',
1065 + 'gravity',
1066 + 'great',
1067 + 'green',
1068 + 'grid',
1069 + 'grief',
1070 + 'grit',
1071 + 'grocery',
1072 + 'group',
1073 + 'grow',
1074 + 'grunt',
1075 + 'guard',
1076 + 'guess',
1077 + 'guide',
1078 + 'guilt',
1079 + 'guitar',
1080 + 'gun',
1081 + 'gym',
1082 + 'habit',
1083 + 'hair',
1084 + 'half',
1085 + 'hammer',
1086 + 'hamster',
1087 + 'hand',
1088 + 'happy',
1089 + 'harbor',
1090 + 'hard',
1091 + 'harsh',
1092 + 'harvest',
1093 + 'hat',
1094 + 'have',
1095 + 'hawk',
1096 + 'hazard',
1097 + 'head',
1098 + 'health',
1099 + 'heart',
1100 + 'heavy',
1101 + 'hedgehog',
1102 + 'height',
1103 + 'hello',
1104 + 'helmet',
1105 + 'help',
1106 + 'hen',
1107 + 'hero',
1108 + 'hidden',
1109 + 'high',
1110 + 'hill',
1111 + 'hint',
1112 + 'hip',
1113 + 'hire',
1114 + 'history',
1115 + 'hobby',
1116 + 'hockey',
1117 + 'hold',
1118 + 'hole',
1119 + 'holiday',
1120 + 'hollow',
1121 + 'home',
1122 + 'honey',
1123 + 'hood',
1124 + 'hope',
1125 + 'horn',
1126 + 'horror',
1127 + 'horse',
1128 + 'hospital',
1129 + 'host',
1130 + 'hotel',
1131 + 'hour',
1132 + 'hover',
1133 + 'hub',
1134 + 'huge',
1135 + 'human',
1136 + 'humble',
1137 + 'humor',
1138 + 'hundred',
1139 + 'hungry',
1140 + 'hunt',
1141 + 'hurdle',
1142 + 'hurry',
1143 + 'hurt',
1144 + 'husband',
1145 + 'hybrid',
1146 + 'ice',
1147 + 'icon',
1148 + 'idea',
1149 + 'identify',
1150 + 'idle',
1151 + 'ignore',
1152 + 'ill',
1153 + 'illegal',
1154 + 'illness',
1155 + 'image',
1156 + 'imitate',
1157 + 'immense',
1158 + 'immune',
1159 + 'impact',
1160 + 'impose',
1161 + 'improve',
1162 + 'impulse',
1163 + 'inch',
1164 + 'include',
1165 + 'income',
1166 + 'increase',
1167 + 'index',
1168 + 'indicate',
1169 + 'indoor',
1170 + 'industry',
1171 + 'infant',
1172 + 'inflict',
1173 + 'inform',
1174 + 'inhale',
1175 + 'inherit',
1176 + 'initial',
1177 + 'inject',
1178 + 'injury',
1179 + 'inmate',
1180 + 'inner',
1181 + 'innocent',
1182 + 'input',
1183 + 'inquiry',
1184 + 'insane',
1185 + 'insect',
1186 + 'inside',
1187 + 'inspire',
1188 + 'install',
1189 + 'intact',
1190 + 'interest',
1191 + 'into',
1192 + 'invest',
1193 + 'invite',
1194 + 'involve',
1195 + 'iron',
1196 + 'island',
1197 + 'isolate',
1198 + 'issue',
1199 + 'item',
1200 + 'ivory',
1201 + 'jacket',
1202 + 'jaguar',
1203 + 'jar',
1204 + 'jazz',
1205 + 'jealous',
1206 + 'jeans',
1207 + 'jelly',
1208 + 'jewel',
1209 + 'job',
1210 + 'join',
1211 + 'joke',
1212 + 'journey',
1213 + 'joy',
1214 + 'judge',
1215 + 'juice',
1216 + 'jump',
1217 + 'jungle',
1218 + 'junior',
1219 + 'junk',
1220 + 'just',
1221 + 'kangaroo',
1222 + 'keen',
1223 + 'keep',
1224 + 'ketchup',
1225 + 'key',
1226 + 'kick',
1227 + 'kid',
1228 + 'kidney',
1229 + 'kind',
1230 + 'kingdom',
1231 + 'kiss',
1232 + 'kit',
1233 + 'kitchen',
1234 + 'kite',
1235 + 'kitten',
1236 + 'kiwi',
1237 + 'knee',
1238 + 'knife',
1239 + 'knock',
1240 + 'know',
1241 + 'lab',
1242 + 'label',
1243 + 'labor',
1244 + 'ladder',
1245 + 'lady',
1246 + 'lake',
1247 + 'lamp',
1248 + 'language',
1249 + 'laptop',
1250 + 'large',
1251 + 'later',
1252 + 'latin',
1253 + 'laugh',
1254 + 'laundry',
1255 + 'lava',
1256 + 'law',
1257 + 'lawn',
1258 + 'lawsuit',
1259 + 'layer',
1260 + 'lazy',
1261 + 'leader',
1262 + 'leaf',
1263 + 'learn',
1264 + 'leave',
1265 + 'lecture',
1266 + 'left',
1267 + 'leg',
1268 + 'legal',
1269 + 'legend',
1270 + 'leisure',
1271 + 'lemon',
1272 + 'lend',
1273 + 'length',
1274 + 'lens',
1275 + 'leopard',
1276 + 'lesson',
1277 + 'letter',
1278 + 'level',
1279 + 'liar',
1280 + 'liberty',
1281 + 'library',
1282 + 'license',
1283 + 'life',
1284 + 'lift',
1285 + 'light',
1286 + 'like',
1287 + 'limb',
1288 + 'limit',
1289 + 'link',
1290 + 'lion',
1291 + 'liquid',
1292 + 'list',
1293 + 'little',
1294 + 'live',
1295 + 'lizard',
1296 + 'load',
1297 + 'loan',
1298 + 'lobster',
1299 + 'local',
1300 + 'lock',
1301 + 'logic',
1302 + 'lonely',
1303 + 'long',
1304 + 'loop',
1305 + 'lottery',
1306 + 'loud',
1307 + 'lounge',
1308 + 'love',
1309 + 'loyal',
1310 + 'lucky',
1311 + 'luggage',
1312 + 'lumber',
1313 + 'lunar',
1314 + 'lunch',
1315 + 'luxury',
1316 + 'lyrics',
1317 + 'machine',
1318 + 'mad',
1319 + 'magic',
1320 + 'magnet',
1321 + 'maid',
1322 + 'mail',
1323 + 'main',
1324 + 'major',
1325 + 'make',
1326 + 'mammal',
1327 + 'man',
1328 + 'manage',
1329 + 'mandate',
1330 + 'mango',
1331 + 'mansion',
1332 + 'manual',
1333 + 'maple',
1334 + 'marble',
1335 + 'march',
1336 + 'margin',
1337 + 'marine',
1338 + 'market',
1339 + 'marriage',
1340 + 'mask',
1341 + 'mass',
1342 + 'master',
1343 + 'match',
1344 + 'material',
1345 + 'math',
1346 + 'matrix',
1347 + 'matter',
1348 + 'maximum',
1349 + 'maze',
1350 + 'meadow',
1351 + 'mean',
1352 + 'measure',
1353 + 'meat',
1354 + 'mechanic',
1355 + 'medal',
1356 + 'media',
1357 + 'melody',
1358 + 'melt',
1359 + 'member',
1360 + 'memory',
1361 + 'mention',
1362 + 'menu',
1363 + 'mercy',
1364 + 'merge',
1365 + 'merit',
1366 + 'merry',
1367 + 'mesh',
1368 + 'message',
1369 + 'metal',
1370 + 'method',
1371 + 'middle',
1372 + 'midnight',
1373 + 'milk',
1374 + 'million',
1375 + 'mimic',
1376 + 'mind',
1377 + 'minimum',
1378 + 'minor',
1379 + 'minute',
1380 + 'miracle',
1381 + 'mirror',
1382 + 'misery',
1383 + 'miss',
1384 + 'mistake',
1385 + 'mix',
1386 + 'mixed',
1387 + 'mixture',
1388 + 'mobile',
1389 + 'model',
1390 + 'modify',
1391 + 'mom',
1392 + 'moment',
1393 + 'monitor',
1394 + 'monkey',
1395 + 'monster',
1396 + 'month',
1397 + 'moon',
1398 + 'moral',
1399 + 'more',
1400 + 'morning',
1401 + 'mosquito',
1402 + 'mother',
1403 + 'motion',
1404 + 'motor',
1405 + 'mountain',
1406 + 'mouse',
1407 + 'move',
1408 + 'movie',
1409 + 'much',
1410 + 'muffin',
1411 + 'mule',
1412 + 'multiply',
1413 + 'muscle',
1414 + 'museum',
1415 + 'mushroom',
1416 + 'music',
1417 + 'must',
1418 + 'mutual',
1419 + 'myself',
1420 + 'mystery',
1421 + 'myth',
1422 + 'naive',
1423 + 'name',
1424 + 'napkin',
1425 + 'narrow',
1426 + 'nasty',
1427 + 'nation',
1428 + 'nature',
1429 + 'near',
1430 + 'neck',
1431 + 'need',
1432 + 'negative',
1433 + 'neglect',
1434 + 'neither',
1435 + 'nephew',
1436 + 'nerve',
1437 + 'nest',
1438 + 'net',
1439 + 'network',
1440 + 'neutral',
1441 + 'never',
1442 + 'news',
1443 + 'next',
1444 + 'nice',
1445 + 'night',
1446 + 'noble',
1447 + 'noise',
1448 + 'nominee',
1449 + 'noodle',
1450 + 'normal',
1451 + 'north',
1452 + 'nose',
1453 + 'notable',
1454 + 'note',
1455 + 'nothing',
1456 + 'notice',
1457 + 'novel',
1458 + 'now',
1459 + 'nuclear',
1460 + 'number',
1461 + 'nurse',
1462 + 'nut',
1463 + 'oak',
1464 + 'obey',
1465 + 'object',
1466 + 'oblige',
1467 + 'obscure',
1468 + 'observe',
1469 + 'obtain',
1470 + 'obvious',
1471 + 'occur',
1472 + 'ocean',
1473 + 'october',
1474 + 'odor',
1475 + 'off',
1476 + 'offer',
1477 + 'office',
1478 + 'often',
1479 + 'oil',
1480 + 'okay',
1481 + 'old',
1482 + 'olive',
1483 + 'olympic',
1484 + 'omit',
1485 + 'once',
1486 + 'one',
1487 + 'onion',
1488 + 'online',
1489 + 'only',
1490 + 'open',
1491 + 'opera',
1492 + 'opinion',
1493 + 'oppose',
1494 + 'option',
1495 + 'orange',
1496 + 'orbit',
1497 + 'orchard',
1498 + 'order',
1499 + 'ordinary',
1500 + 'organ',
1501 + 'orient',
1502 + 'original',
1503 + 'orphan',
1504 + 'ostrich',
1505 + 'other',
1506 + 'outdoor',
1507 + 'outer',
1508 + 'output',
1509 + 'outside',
1510 + 'oval',
1511 + 'oven',
1512 + 'over',
1513 + 'own',
1514 + 'owner',
1515 + 'oxygen',
1516 + 'oyster',
1517 + 'ozone',
1518 + 'pact',
1519 + 'paddle',
1520 + 'page',
1521 + 'pair',
1522 + 'palace',
1523 + 'palm',
1524 + 'panda',
1525 + 'panel',
1526 + 'panic',
1527 + 'panther',
1528 + 'paper',
1529 + 'parade',
1530 + 'parent',
1531 + 'park',
1532 + 'parrot',
1533 + 'party',
1534 + 'pass',
1535 + 'patch',
1536 + 'path',
1537 + 'patient',
1538 + 'patrol',
1539 + 'pattern',
1540 + 'pause',
1541 + 'pave',
1542 + 'payment',
1543 + 'peace',
1544 + 'peanut',
1545 + 'pear',
1546 + 'peasant',
1547 + 'pelican',
1548 + 'pen',
1549 + 'penalty',
1550 + 'pencil',
1551 + 'people',
1552 + 'pepper',
1553 + 'perfect',
1554 + 'permit',
1555 + 'person',
1556 + 'pet',
1557 + 'phone',
1558 + 'photo',
1559 + 'phrase',
1560 + 'physical',
1561 + 'piano',
1562 + 'picnic',
1563 + 'picture',
1564 + 'piece',
1565 + 'pig',
1566 + 'pigeon',
1567 + 'pill',
1568 + 'pilot',
1569 + 'pink',
1570 + 'pioneer',
1571 + 'pipe',
1572 + 'pistol',
1573 + 'pitch',
1574 + 'pizza',
1575 + 'place',
1576 + 'planet',
1577 + 'plastic',
1578 + 'plate',
1579 + 'play',
1580 + 'please',
1581 + 'pledge',
1582 + 'pluck',
1583 + 'plug',
1584 + 'plunge',
1585 + 'poem',
1586 + 'poet',
1587 + 'point',
1588 + 'polar',
1589 + 'pole',
1590 + 'police',
1591 + 'pond',
1592 + 'pony',
1593 + 'pool',
1594 + 'popular',
1595 + 'portion',
1596 + 'position',
1597 + 'possible',
1598 + 'post',
1599 + 'potato',
1600 + 'pottery',
1601 + 'poverty',
1602 + 'powder',
1603 + 'power',
1604 + 'practice',
1605 + 'praise',
1606 + 'predict',
1607 + 'prefer',
1608 + 'prepare',
1609 + 'present',
1610 + 'pretty',
1611 + 'prevent',
1612 + 'price',
1613 + 'pride',
1614 + 'primary',
1615 + 'print',
1616 + 'priority',
1617 + 'prison',
1618 + 'private',
1619 + 'prize',
1620 + 'problem',
1621 + 'process',
1622 + 'produce',
1623 + 'profit',
1624 + 'program',
1625 + 'project',
1626 + 'promote',
1627 + 'proof',
1628 + 'property',
1629 + 'prosper',
1630 + 'protect',
1631 + 'proud',
1632 + 'provide',
1633 + 'public',
1634 + 'pudding',
1635 + 'pull',
1636 + 'pulp',
1637 + 'pulse',
1638 + 'pumpkin',
1639 + 'punch',
1640 + 'pupil',
1641 + 'puppy',
1642 + 'purchase',
1643 + 'purity',
1644 + 'purpose',
1645 + 'purse',
1646 + 'push',
1647 + 'put',
1648 + 'puzzle',
1649 + 'pyramid',
1650 + 'quality',
1651 + 'quantum',
1652 + 'quarter',
1653 + 'question',
1654 + 'quick',
1655 + 'quit',
1656 + 'quiz',
1657 + 'quote',
1658 + 'rabbit',
1659 + 'raccoon',
1660 + 'race',
1661 + 'rack',
1662 + 'radar',
1663 + 'radio',
1664 + 'rail',
1665 + 'rain',
1666 + 'raise',
1667 + 'rally',
1668 + 'ramp',
1669 + 'ranch',
1670 + 'random',
1671 + 'range',
1672 + 'rapid',
1673 + 'rare',
1674 + 'rate',
1675 + 'rather',
1676 + 'raven',
1677 + 'raw',
1678 + 'razor',
1679 + 'ready',
1680 + 'real',
1681 + 'reason',
1682 + 'rebel',
1683 + 'rebuild',
1684 + 'recall',
1685 + 'receive',
1686 + 'recipe',
1687 + 'record',
1688 + 'recycle',
1689 + 'reduce',
1690 + 'reflect',
1691 + 'reform',
1692 + 'refuse',
1693 + 'region',
1694 + 'regret',
1695 + 'regular',
1696 + 'reject',
1697 + 'relax',
1698 + 'release',
1699 + 'relief',
1700 + 'rely',
1701 + 'remain',
1702 + 'remember',
1703 + 'remind',
1704 + 'remove',
1705 + 'render',
1706 + 'renew',
1707 + 'rent',
1708 + 'reopen',
1709 + 'repair',
1710 + 'repeat',
1711 + 'replace',
1712 + 'report',
1713 + 'require',
1714 + 'rescue',
1715 + 'resemble',
1716 + 'resist',
1717 + 'resource',
1718 + 'response',
1719 + 'result',
1720 + 'retire',
1721 + 'retreat',
1722 + 'return',
1723 + 'reunion',
1724 + 'reveal',
1725 + 'review',
1726 + 'reward',
1727 + 'rhythm',
1728 + 'rib',
1729 + 'ribbon',
1730 + 'rice',
1731 + 'rich',
1732 + 'ride',
1733 + 'ridge',
1734 + 'rifle',
1735 + 'right',
1736 + 'rigid',
1737 + 'ring',
1738 + 'riot',
1739 + 'ripple',
1740 + 'risk',
1741 + 'ritual',
1742 + 'rival',
1743 + 'river',
1744 + 'road',
1745 + 'roast',
1746 + 'robot',
1747 + 'robust',
1748 + 'rocket',
1749 + 'romance',
1750 + 'roof',
1751 + 'rookie',
1752 + 'room',
1753 + 'rose',
1754 + 'rotate',
1755 + 'rough',
1756 + 'round',
1757 + 'route',
1758 + 'royal',
1759 + 'rubber',
1760 + 'rude',
1761 + 'rug',
1762 + 'rule',
1763 + 'run',
1764 + 'runway',
1765 + 'rural',
1766 + 'sad',
1767 + 'saddle',
1768 + 'sadness',
1769 + 'safe',
1770 + 'sail',
1771 + 'salad',
1772 + 'salmon',
1773 + 'salon',
1774 + 'salt',
1775 + 'salute',
1776 + 'same',
1777 + 'sample',
1778 + 'sand',
1779 + 'satisfy',
1780 + 'satoshi',
1781 + 'sauce',
1782 + 'sausage',
1783 + 'save',
1784 + 'say',
1785 + 'scale',
1786 + 'scan',
1787 + 'scare',
1788 + 'scatter',
1789 + 'scene',
1790 + 'scheme',
1791 + 'school',
1792 + 'science',
1793 + 'scissors',
1794 + 'scorpion',
1795 + 'scout',
1796 + 'scrap',
1797 + 'screen',
1798 + 'script',
1799 + 'scrub',
1800 + 'sea',
1801 + 'search',
1802 + 'season',
1803 + 'seat',
1804 + 'second',
1805 + 'secret',
1806 + 'section',
1807 + 'security',
1808 + 'seed',
1809 + 'seek',
1810 + 'segment',
1811 + 'select',
1812 + 'sell',
1813 + 'seminar',
1814 + 'senior',
1815 + 'sense',
1816 + 'sentence',
1817 + 'series',
1818 + 'service',
1819 + 'session',
1820 + 'settle',
1821 + 'setup',
1822 + 'seven',
1823 + 'shadow',
1824 + 'shaft',
1825 + 'shallow',
1826 + 'share',
1827 + 'shed',
1828 + 'shell',
1829 + 'sheriff',
1830 + 'shield',
1831 + 'shift',
1832 + 'shine',
1833 + 'ship',
1834 + 'shiver',
1835 + 'shock',
1836 + 'shoe',
1837 + 'shoot',
1838 + 'shop',
1839 + 'short',
1840 + 'shoulder',
1841 + 'shove',
1842 + 'shrimp',
1843 + 'shrug',
1844 + 'shuffle',
1845 + 'shy',
1846 + 'sibling',
1847 + 'sick',
1848 + 'side',
1849 + 'siege',
1850 + 'sight',
1851 + 'sign',
1852 + 'silent',
1853 + 'silk',
1854 + 'silly',
1855 + 'silver',
1856 + 'similar',
1857 + 'simple',
1858 + 'since',
1859 + 'sing',
1860 + 'siren',
1861 + 'sister',
1862 + 'situate',
1863 + 'six',
1864 + 'size',
1865 + 'skate',
1866 + 'sketch',
1867 + 'ski',
1868 + 'skill',
1869 + 'skin',
1870 + 'skirt',
1871 + 'skull',
1872 + 'slab',
1873 + 'slam',
1874 + 'sleep',
1875 + 'slender',
1876 + 'slice',
1877 + 'slide',
1878 + 'slight',
1879 + 'slim',
1880 + 'slogan',
1881 + 'slot',
1882 + 'slow',
1883 + 'slush',
1884 + 'small',
1885 + 'smart',
1886 + 'smile',
1887 + 'smoke',
1888 + 'smooth',
1889 + 'snack',
1890 + 'snake',
1891 + 'snap',
1892 + 'sniff',
1893 + 'snow',
1894 + 'soap',
1895 + 'soccer',
1896 + 'social',
1897 + 'sock',
1898 + 'soda',
1899 + 'soft',
1900 + 'solar',
1901 + 'soldier',
1902 + 'solid',
1903 + 'solution',
1904 + 'solve',
1905 + 'someone',
1906 + 'song',
1907 + 'soon',
1908 + 'sorry',
1909 + 'sort',
1910 + 'soul',
1911 + 'sound',
1912 + 'soup',
1913 + 'source',
1914 + 'south',
1915 + 'space',
1916 + 'spare',
1917 + 'spatial',
1918 + 'spawn',
1919 + 'speak',
1920 + 'special',
1921 + 'speed',
1922 + 'spell',
1923 + 'spend',
1924 + 'sphere',
1925 + 'spice',
1926 + 'spider',
1927 + 'spike',
1928 + 'spin',
1929 + 'spirit',
1930 + 'split',
1931 + 'spoil',
1932 + 'sponsor',
1933 + 'spoon',
1934 + 'sport',
1935 + 'spot',
1936 + 'spray',
1937 + 'spread',
1938 + 'spring',
1939 + 'spy',
1940 + 'square',
1941 + 'squeeze',
1942 + 'squirrel',
1943 + 'stable',
1944 + 'stadium',
1945 + 'staff',
1946 + 'stage',
1947 + 'stairs',
1948 + 'stamp',
1949 + 'stand',
1950 + 'start',
1951 + 'state',
1952 + 'stay',
1953 + 'steak',
1954 + 'steel',
1955 + 'stem',
1956 + 'step',
1957 + 'stereo',
1958 + 'stick',
1959 + 'still',
1960 + 'sting',
1961 + 'stock',
1962 + 'stomach',
1963 + 'stone',
1964 + 'stool',
1965 + 'story',
1966 + 'stove',
1967 + 'strategy',
1968 + 'street',
1969 + 'strike',
1970 + 'strong',
1971 + 'struggle',
1972 + 'student',
1973 + 'stuff',
1974 + 'stumble',
1975 + 'style',
1976 + 'subject',
1977 + 'submit',
1978 + 'subway',
1979 + 'success',
1980 + 'such',
1981 + 'sudden',
1982 + 'suffer',
1983 + 'sugar',
1984 + 'suggest',
1985 + 'suit',
1986 + 'summer',
1987 + 'sun',
1988 + 'sunny',
1989 + 'sunset',
1990 + 'super',
1991 + 'supply',
1992 + 'supreme',
1993 + 'sure',
1994 + 'surface',
1995 + 'surge',
1996 + 'surprise',
1997 + 'surround',
1998 + 'survey',
1999 + 'suspect',
2000 + 'sustain',
2001 + 'swallow',
2002 + 'swamp',
2003 + 'swap',
2004 + 'swarm',
2005 + 'swear',
2006 + 'sweet',
2007 + 'swift',
2008 + 'swim',
2009 + 'swing',
2010 + 'switch',
2011 + 'sword',
2012 + 'symbol',
2013 + 'symptom',
2014 + 'syrup',
2015 + 'system',
2016 + 'table',
2017 + 'tackle',
2018 + 'tag',
2019 + 'tail',
2020 + 'talent',
2021 + 'talk',
2022 + 'tank',
2023 + 'tape',
2024 + 'target',
2025 + 'task',
2026 + 'taste',
2027 + 'tattoo',
2028 + 'taxi',
2029 + 'teach',
2030 + 'team',
2031 + 'tell',
2032 + 'ten',
2033 + 'tenant',
2034 + 'tennis',
2035 + 'tent',
2036 + 'term',
2037 + 'test',
2038 + 'text',
2039 + 'thank',
2040 + 'that',
2041 + 'theme',
2042 + 'then',
2043 + 'theory',
2044 + 'there',
2045 + 'they',
2046 + 'thing',
2047 + 'this',
2048 + 'thought',
2049 + 'three',
2050 + 'thrive',
2051 + 'throw',
2052 + 'thumb',
2053 + 'thunder',
2054 + 'ticket',
2055 + 'tide',
2056 + 'tiger',
2057 + 'tilt',
2058 + 'timber',
2059 + 'time',
2060 + 'tiny',
2061 + 'tip',
2062 + 'tired',
2063 + 'tissue',
2064 + 'title',
2065 + 'toast',
2066 + 'tobacco',
2067 + 'today',
2068 + 'toddler',
2069 + 'toe',
2070 + 'together',
2071 + 'toilet',
2072 + 'token',
2073 + 'tomato',
2074 + 'tomorrow',
2075 + 'tone',
2076 + 'tongue',
2077 + 'tonight',
2078 + 'tool',
2079 + 'tooth',
2080 + 'top',
2081 + 'topic',
2082 + 'topple',
2083 + 'torch',
2084 + 'tornado',
2085 + 'tortoise',
2086 + 'toss',
2087 + 'total',
2088 + 'tourist',
2089 + 'toward',
2090 + 'tower',
2091 + 'town',
2092 + 'toy',
2093 + 'track',
2094 + 'trade',
2095 + 'traffic',
2096 + 'tragic',
2097 + 'train',
2098 + 'transfer',
2099 + 'trap',
2100 + 'trash',
2101 + 'travel',
2102 + 'tray',
2103 + 'treat',
2104 + 'tree',
2105 + 'trend',
2106 + 'trial',
2107 + 'tribe',
2108 + 'trick',
2109 + 'trigger',
2110 + 'trim',
2111 + 'trip',
2112 + 'trophy',
2113 + 'trouble',
2114 + 'truck',
2115 + 'true',
2116 + 'truly',
2117 + 'trumpet',
2118 + 'trust',
2119 + 'truth',
2120 + 'try',
2121 + 'tube',
2122 + 'tuition',
2123 + 'tumble',
2124 + 'tuna',
2125 + 'tunnel',
2126 + 'turkey',
2127 + 'turn',
2128 + 'turtle',
2129 + 'twelve',
2130 + 'twenty',
2131 + 'twice',
2132 + 'twin',
2133 + 'twist',
2134 + 'two',
2135 + 'type',
2136 + 'typical',
2137 + 'ugly',
2138 + 'umbrella',
2139 + 'unable',
2140 + 'unaware',
2141 + 'uncle',
2142 + 'uncover',
2143 + 'under',
2144 + 'undo',
2145 + 'unfair',
2146 + 'unfold',
2147 + 'unhappy',
2148 + 'uniform',
2149 + 'unique',
2150 + 'unit',
2151 + 'universe',
2152 + 'unknown',
2153 + 'unlock',
2154 + 'until',
2155 + 'unusual',
2156 + 'unveil',
2157 + 'update',
2158 + 'upgrade',
2159 + 'uphold',
2160 + 'upon',
2161 + 'upper',
2162 + 'upset',
2163 + 'urban',
2164 + 'urge',
2165 + 'usage',
2166 + 'use',
2167 + 'used',
2168 + 'useful',
2169 + 'useless',
2170 + 'usual',
2171 + 'utility',
2172 + 'vacant',
2173 + 'vacuum',
2174 + 'vague',
2175 + 'valid',
2176 + 'valley',
2177 + 'valve',
2178 + 'van',
2179 + 'vanish',
2180 + 'vapor',
2181 + 'various',
2182 + 'vast',
2183 + 'vault',
2184 + 'vehicle',
2185 + 'velvet',
2186 + 'vendor',
2187 + 'venture',
2188 + 'venue',
2189 + 'verb',
2190 + 'verify',
2191 + 'version',
2192 + 'very',
2193 + 'vessel',
2194 + 'veteran',
2195 + 'viable',
2196 + 'vibrant',
2197 + 'vicious',
2198 + 'victory',
2199 + 'video',
2200 + 'view',
2201 + 'village',
2202 + 'vintage',
2203 + 'violin',
2204 + 'virtual',
2205 + 'virus',
2206 + 'visa',
2207 + 'visit',
2208 + 'visual',
2209 + 'vital',
2210 + 'vivid',
2211 + 'vocal',
2212 + 'voice',
2213 + 'void',
2214 + 'volcano',
2215 + 'volume',
2216 + 'vote',
2217 + 'voyage',
2218 + 'wage',
2219 + 'wagon',
2220 + 'wait',
2221 + 'walk',
2222 + 'wall',
2223 + 'walnut',
2224 + 'want',
2225 + 'warfare',
2226 + 'warm',
2227 + 'warrior',
2228 + 'wash',
2229 + 'wasp',
2230 + 'waste',
2231 + 'water',
2232 + 'wave',
2233 + 'way',
2234 + 'wealth',
2235 + 'weapon',
2236 + 'wear',
2237 + 'weasel',
2238 + 'weather',
2239 + 'web',
2240 + 'wedding',
2241 + 'weekend',
2242 + 'weird',
2243 + 'welcome',
2244 + 'west',
2245 + 'wet',
2246 + 'whale',
2247 + 'what',
2248 + 'wheat',
2249 + 'wheel',
2250 + 'when',
2251 + 'where',
2252 + 'whip',
2253 + 'whisper',
2254 + 'wide',
2255 + 'width',
2256 + 'wife',
2257 + 'wild',
2258 + 'will',
2259 + 'win',
2260 + 'window',
2261 + 'wine',
2262 + 'wing',
2263 + 'wink',
2264 + 'winner',
2265 + 'winter',
2266 + 'wire',
2267 + 'wisdom',
2268 + 'wise',
2269 + 'wish',
2270 + 'witness',
2271 + 'wolf',
2272 + 'woman',
2273 + 'wonder',
2274 + 'wood',
2275 + 'wool',
2276 + 'word',
2277 + 'work',
2278 + 'world',
2279 + 'worry',
2280 + 'worth',
2281 + 'wrap',
2282 + 'wreck',
2283 + 'wrestle',
2284 + 'wrist',
2285 + 'write',
2286 + 'wrong',
2287 + 'yard',
2288 + 'year',
2289 + 'yellow',
2290 + 'you',
2291 + 'young',
2292 + 'youth',
2293 + 'zebra',
2294 + 'zero',
2295 + 'zone',
2296 + 'zoo'
2297 +];
lib/bitcoin/bitcoin_wallet.dart
+5 -4
@@ -1,7 +1,7 @@
1 import 'dart:async';
2 import 'dart:convert';
3 +import 'package:cake_wallet/bitcoin/bitcoin_mnemonic.dart';
4 import 'package:mobx/mobx.dart';
4 -import 'package:bip39/bip39.dart' as bip39;
5 import 'package:flutter/foundation.dart';
6 import 'package:rxdart/rxdart.dart';
7 import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
@@ -42,8 +42,9 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
42 BitcoinBalance initialBalance})
43 : balance =
44 initialBalance ?? BitcoinBalance(confirmed: 0, unconfirmed: 0),
45 - hd = bitcoin.HDWallet.fromSeed(bip39.mnemonicToSeed(mnemonic),
46 - network: bitcoin.bitcoin),
45 + hd = bitcoin.HDWallet.fromSeed(mnemonicToSeedBytes(mnemonic),
46 + network: bitcoin.bitcoin)
47 + .derivePath("m/0'/0"),
48 addresses = initialAddresses != null
49 ? ObservableList<BitcoinAddressRecord>.of(initialAddresses)
50 : ObservableList<BitcoinAddressRecord>(),
@@ -58,7 +59,7 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
59 {@required String password,
60 @required String name,
61 @required String dirPath,
61 - @required WalletInfo walletInfo,
62 + @required WalletInfo walletInfo,
63 String jsonSource}) {
64 final data = json.decode(jsonSource) as Map;
65 final mnemonic = data['mnemonic'] as String;
lib/bitcoin/bitcoin_wallet_service.dart
+2 -2
@@ -1,5 +1,5 @@
1 import 'dart:io';
2 -import 'package:bip39/bip39.dart' as bip39;
2 +import 'package:cake_wallet/bitcoin/bitcoin_mnemonic.dart';
3 import 'package:cake_wallet/bitcoin/file.dart';
4 import 'package:cake_wallet/bitcoin/bitcoin_wallet_creation_credentials.dart';
5 import 'package:cake_wallet/core/wallet_base.dart';
@@ -24,7 +24,7 @@ class BitcoinWalletService extends WalletService<
24 type: WalletType.bitcoin, name: credentials.name);
25 final wallet = BitcoinWalletBase.build(
26 dirPath: dirPath,
27 - mnemonic: bip39.generateMnemonic(),
27 + mnemonic: generateMnemonic(),
28 password: credentials.password,
29 name: credentials.name,
30 walletInfo: credentials.walletInfo);
pubspec.lock
+15 -1
@@ -247,12 +247,19 @@ packages:
247 source: hosted
248 version: "2.1.1"
249 crypto:
250 - dependency: transitive
250 + dependency: "direct main"
251 description:
252 name: crypto
253 url: "https://pub.dartlang.org"
254 source: hosted
255 version: "2.1.5"
256 + cryptography:
257 + dependency: "direct main"
258 + description:
259 + name: cryptography
260 + url: "https://pub.dartlang.org"
261 + source: hosted
262 + version: "1.4.1"
263 cupertino_icons:
264 dependency: "direct main"
265 description:
@@ -924,6 +931,13 @@ packages:
931 url: "https://pub.dartlang.org"
932 source: hosted
933 version: "1.3.0-nullsafety.3"
934 + unorm_dart:
935 + dependency: "direct main"
936 + description:
937 + name: unorm_dart
938 + url: "https://pub.dartlang.org"
939 + source: hosted
940 + version: "0.1.2"
941 url_launcher:
942 dependency: "direct main"
943 description:
pubspec.yaml
+3
@@ -60,6 +60,7 @@ dependencies:
60 # Use with the CupertinoIcons class for iOS style icons.
61 cupertino_icons: ^0.1.2
62 encrypt: ^4.0.0
63 + crypto: ^2.1.5
64 password: ^1.0.0
65 basic_utils: ^1.0.8
66 bitcoin_flutter: ^2.0.0
@@ -67,6 +68,8 @@ dependencies:
68 connectivity: ^0.4.9+2
69 keyboard_actions: ^3.3.0
70 flushbar: ^1.10.4
71 + unorm_dart: ^0.1.2
72 + cryptography: ^1.4.0
73
74 dev_dependencies:
75 flutter_test: