commit 9f28397cfe7ff808f6aaab5de4ada6616e74bf94 Author: philemon Date: Sat Nov 30 11:42:07 2013 +0400 new file: LICENSE new file: MANIFEST new file: mmgen-addrgen new file: mmgen-keygen new file: mmgen-passchg new file: mmgen-walletchk new file: mmgen-walletgen new file: mmgen/Opts.py new file: mmgen/__init__.py new file: mmgen/addr.py new file: mmgen/bitcoin.py new file: mmgen/config.py new file: mmgen/license.py new file: mmgen/mn_electrum.py new file: mmgen/mn_tirosh.py new file: mmgen/mnemonic.py new file: mmgen/utils.py new file: mmgen/walletgen.py new file: setup.py new file: tests/addr.py new file: tests/bitcoin.py new file: tests/mn_electrum.py new file: tests/mn_tirosh.py new file: tests/mnemonic.py new file: tests/test.py new file: tests/utils.py new file: tests/walletgen.py new file: wordlists/mn_wordlist.c new file: wordlists/mn_wordlist.py new file: wordlists/mn_wordlist.sort.py new file: wordlists/mnemonic.py new file: wordlists/mnemonic.sort.py diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 00000000..336746c6 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,18 @@ +# file GENERATED by distutils, do NOT edit +mmgen-addrgen +mmgen-keygen +mmgen-passchg +mmgen-walletchk +mmgen-walletgen +setup.py +mmgen/Opts.py +mmgen/__init__.py +mmgen/addr.py +mmgen/bitcoin.py +mmgen/config.py +mmgen/license.py +mmgen/mn_electrum.py +mmgen/mn_tirosh.py +mmgen/mnemonic.py +mmgen/utils.py +mmgen/walletgen.py diff --git a/mmgen-addrgen b/mmgen-addrgen new file mode 120000 index 00000000..cd93f1ad --- /dev/null +++ b/mmgen-addrgen @@ -0,0 +1 @@ +mmgen-keygen \ No newline at end of file diff --git a/mmgen-keygen b/mmgen-keygen new file mode 100755 index 00000000..59dec039 --- /dev/null +++ b/mmgen-keygen @@ -0,0 +1,175 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +mmgen-keygen: Generate addresses/secret keys from a mmgen deterministic + wallet for a range of addresses. + Call as 'btc-addrgen' for safe, reduced functionality + with no output of secret keys. +""" + +import sys + +from mmgen.Opts import * +from mmgen.config import * +from mmgen.license import * +from mmgen.utils import * +from mmgen.addr import * + +invoked_as = sys.argv[0].split("-")[-1] +gen_what = "addresses" if invoked_as == "addrgen" else "keys" + +if invoked_as == "keygen": + extra_help_data = ( + "\n-A, --no-addresses Print only secret keys, no addresses", + "\n-x, --b16 Print secret keys in hexadecimal too", + ".\nBy default, both addresses and secret keys are generated" + ) +else: extra_help_data = ("","","") + +help_data = { + 'prog_name': sys.argv[0].split("/")[-1], + 'desc': """Generate a range of {} from a {} wallet, mnemonic, + seed or password""".format(gen_what,proj_name), + 'usage':"[opts] [infile]
", + 'options': """ +-h, --help Print this help message{} +-d, --outdir d Specify an alternate directory 'd' for output +-e, --echo-passphrase Display passphrase or mnemonic on screen upon entry +-K, --no-keyconv Use internal libraries for address generation + instead of 'keyconv' +-l, --seed-len N Length of seed. Options: {} + (default: {}) +-p, --hash-preset p Use scrypt.hash() parameters from preset 'p' + when hashing password (default: '{}') +-P, --show-hash-presets Show information on available hash presets +-q, --quiet Suppress warnings; overwrite files without asking +-S, --stdout Print {W} to stdout +-v, --verbose Produce more verbose output{} + +-b, --from-brain l,p Generate {W} from a user-created password, + i.e. a "brainwallet", using seed length 'l' and + hash preset 'p' (comma-separated) +-m, --from-mnemonic Generate {W} from an electrum-like mnemonic +-s, --from-seed Generate {W} from a seed in .{S} format + +Address range may be a single number or a range in the form XXX-YYY{} + +If available, external 'keyconv' program will be used for address generation + +Data for the --from- options will be taken from if +is specified. Otherwise, the user will be prompted to enter the data. Note +that passphrase data in a file may be arranged in free-form fashion, using +any combination of spaces, tabs or newlines to separate words + +BRAINWALLET NOTE: + +As brainwallets require especially strong hashing to thwart dictionary +attacks, the brainwallet hash preset must be specified by the user, using +the 'p' parameter of the '--from-brain' option + +The '--from-brain' option also requires the user to specify a seed length +(the 'l' parameter) + +For a brainwallet passphrase to always generate the same keys and addresses, +the same 'l' and 'p' parameters to '--from-brain' must be used in all future +invocations with that passphrase +""".format( + extra_help_data[0], + ", ".join([str(i) for i in seed_lens]), + seed_len, + hash_preset, + extra_help_data[1], + extra_help_data[2], + W=gen_what, + S=seed_ext + ) +} + +so = "h","A","d:","e","K","l:","p:","P","q","S","v","x","b:","m","s" +lo = "help","no_addresses","outdir=","echo_passphrase","no_keyconv",\ + "seed_len=","hash_preset=","show_hash_presets","quiet","stdout",\ + "verbose","b16","from_brain=","from_mnemonic","from_seed" + +if invoked_as == "addrgen": + short_opts = so[0:1] + so[2:10] + so[11:] + long_opts = lo[0:1] + lo[2:10] + lo[11:] +else: + short_opts,long_opts = so,lo + +opts,cmd_args = process_opts(sys.argv,help_data,"".join(short_opts),long_opts) + +if 'show_hash_presets' in opts: show_hash_presets() + +# Sanity checking and processing of command-line arguments: + +opts['gen_what'] = gen_what + +set_if_unset_and_typeconvert(opts,( + ('hash_preset',hash_preset,'str'), + ('seed_len',seed_len,'int') +)) + +# Exits on invalid input +check_opts(opts,('hash_preset','seed_len','outdir','from_brain')) + +if debug: + print "Processed options: %s" % repr(opts) + print "Cmd args: %s" % repr(cmd_args) + +if len(cmd_args) == 1 and ( + 'from_mnemonic' in opts or + 'from_brain' in opts or + 'from_seed' in opts + ): infile,addr_range = "",cmd_args[0] +elif len(cmd_args) == 2: + infile,addr_range = cmd_args + check_infile(infile) +else: usage(help_data) + +start,end = parse_address_range(addr_range) + +if not 'quiet' in opts: do_license_msg(); msg("\n") + +# Interact with user: + +if invoked_as == "keygen" and not 'quiet' in opts: + confirm_or_exit(cmessages['unencrypted_secret_keys'], 'continue') + +# Generate data: + +if invoked_as == "addrgen": + opts['print_addresses_only'] = True +else: + if not 'no_addresses' in opts: opts['print_secret'] = True + +seed = get_seed(infile,opts) +seed_id = make_chksum_8(seed) +addr_data = generate_addrs(seed, start, end, opts) +addr_data_str = format_addr_data(addr_data, seed_id, opts) + +# Output data: +if 'stdout' in opts: + if invoked_as == "keygen" and not 'quiet' in opts: + confirm = True + else: confirm = False + write_to_stdout(addr_data_str,confirm) +elif not sys.stdout.isatty(): + write_to_stdout(addr_data_str,confirm=False) +else: + write_addr_data_to_file(seed, addr_data_str, start, end, opts) diff --git a/mmgen-passchg b/mmgen-passchg new file mode 100755 index 00000000..3b44fc3f --- /dev/null +++ b/mmgen-passchg @@ -0,0 +1,121 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +mmgen-passchg: Change a mmgen deterministic wallet's passphrase, label or + hash preset +""" + +import sys +import mmgen.Opts as Opts + +from mmgen.utils import * +from mmgen.config import * + +help_data = { + 'desc': """Change the passphrase, hash preset or label of a {} + deterministic wallet""".format(proj_name), + 'usage': "[opts] [filename]", + 'options': """ +-h, --help Print this help message +-d, --outdir d Specify an alternate directory 'd' for output +-k, --keep-old-passphrase Keep old passphrase (use when changing hash + strength or label only) +-L, --label Change the wallet's label +-p, --hash-preset p Change scrypt.hash() parameters to preset 'p' + (default: '{}') +-P, --show-hash-presets Show information on available hash presets +-v, --verbose Produce more verbose output + +NOTE: The key ID will change if either the passphrase or hash preset + are changed +""".format(hash_preset) +} + +short_opts = "hd:kL:p:Pv" +long_opts = "help","outdir=","keep_old_passphrase","label=","hash_preset=",\ + "show_hash_presets","verbose" + +opts,cmd_args = Opts.process_opts(sys.argv,help_data,short_opts,long_opts) + +if 'show_hash_presets' in opts: show_hash_presets() + +set_if_unset_and_typeconvert(opts,(('hash_preset',hash_preset,'str'),)) +check_opts(opts,('hash_preset','outdir','label')) + +if len(cmd_args) != 1: + msg("One input file must be specified") + sys.exit(2) +infile = cmd_args[0] + +# Old key: +label,metadata,hash_preset,salt,enc_seed = get_data_from_wallet(infile,opts) +seed_id,key_id = metadata[:2] +passwd = " ".join(get_words("","","Enter old passphrase: ",opts)) +key = make_key(passwd, salt, hash_preset) +seed = decrypt_seed(enc_seed, key, seed_id, key_id) + +changed = {} + +if 'label' in opts: + if opts['label'] != label: + msg("Label changed: '%s' -> '%s'" % (label, opts['label'])) + changed['label'] = True + else: + msg("Label is unchanged: '%s'" % (label)) +else: opts['label'] = label # Copy the old label + +if 'hash_preset' in opts: + if hash_preset != opts['hash_preset']: + msg("Hash preset has changed (%s -> %s)" % + (hash_preset, opts['hash_preset'])) + changed['preset'] = True + else: + msg("Hash preset is unchanged") +else: + opts['hash_preset'] = hash_preset + +if 'keep_old_passphrase' in opts: + msg("Keeping old passphrase by user request") +else: + new_passwd = get_first_passphrase_from_user( + "new passphrase", {'quiet': True }) + + if new_passwd == passwd: + msg("Passphrase is unchanged") + else: + msg("Passphrase has changed") + passwd = new_passwd + changed['passwd'] = True + +if 'preset' in changed or 'passwd' in changed: # Update key ID, salt + msg("Will update salt and key ID") + + from hashlib import sha256 + from Crypto import Random + + salt = sha256(salt + Random.new().read(128)).digest()[:salt_len] + key = make_key(passwd, salt, opts['hash_preset']) + new_key_id = make_chksum_8(key) + msg("Key ID changed: %s -> %s" % (key_id,new_key_id)) + key_id = new_key_id + enc_seed = encrypt_seed(seed, key, opts) +elif not 'label' in changed: + msg("Data unchanged. No file will be written") + sys.exit(2) + +write_wallet_to_file(seed, passwd, key_id, salt, enc_seed, opts) diff --git a/mmgen-walletchk b/mmgen-walletchk new file mode 100755 index 00000000..9986a526 --- /dev/null +++ b/mmgen-walletchk @@ -0,0 +1,75 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +mmgen-walletchk: Check integrity of a mmgen deterministic wallet, display + information about it and export seed and mnemonic data +""" + +import sys +import mmgen.Opts as Opts + +from mmgen.utils import * + +help_data = { + 'desc': """Check integrity of a %s deterministic wallet, display + its information and export seed and mnemonic data."""\ + % proj_name, + 'usage': "[opts] [filename]", + 'options': """ +-h, --help Print this help message +-e, --echo-passphrase Print passphrase to screen when typing it +-m, --export-mnemonic Export the wallet's mnemonic to file +-s, --export-seed Export the wallet's seed to file +-v, --verbose Produce more verbose output +""" +} + +short_opts = "hemsv" +long_opts = "help","echo_passphrase","export_mnemonic","export_seed","verbose" + +opts,cmd_args = Opts.process_opts(sys.argv,help_data,short_opts,long_opts) + +if len(cmd_args) != 1: + msg("One input file must be specified") + sys.exit(2) + +if 'export_mnemonic' in opts: + msg("Exporting mnemonic data to file by user request") +if 'export_seed' in opts: + msg("Exporting seed data to file by user request") + +seed = get_seed_from_wallet(cmd_args[0], opts) +msg("Wallet is OK") + +if 'export_mnemonic' in opts: + wl = get_default_wordlist() + + from mmgen.mnemonic import get_mnemonic_from_seed + p = True if debug else False + mn = get_mnemonic_from_seed(seed, wl, default_wl, print_info=p) + + write_mnemonic_to_file(mn, seed, opts) + + if debug: print "Mnemonic:\n%s" % " ".join(mn) + +if 'export_seed' in opts: + write_seed_to_file(seed, opts) + + if debug: + from mmgen.bitcoin import b58encode_pad + print "Seed: %s" % col4(b58encode_pad(seed)) diff --git a/mmgen-walletgen b/mmgen-walletgen new file mode 100755 index 00000000..3d5f0a6a --- /dev/null +++ b/mmgen-walletgen @@ -0,0 +1,168 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +mmgen-walletgen: Generate a mmgen deterministic wallet +""" + +import sys, os +from hashlib import sha256 + +from mmgen.Opts import * +from mmgen.license import * +from mmgen.config import * +from mmgen.walletgen import * +from mmgen.utils import * +prog_name = sys.argv[0].split("/")[-1] + +help_data = { + 'prog_name': prog_name, + 'desc': "Generate a {} deterministic wallet".format(proj_name), + 'usage': "[opts] [infile]", + 'options': """ +-h, --help Print this help message +-d, --outdir d Specify an alternate directory 'd' for output +-e, --echo-passphrase Print passphrase to screen when typing it +-l, --seed-len n Create seed of length 'n'. Options: {} + (default: {}) +-L, --label l Label to identify this wallet (32 chars max. + Allowed symbols: A-Z, a-z, 0-9, " ", "_", ".") +-p, --hash-preset p Use scrypt.hash() parameters from preset 'p' + (default: '{}') +-P, --show-hash-presets Show information on available hash presets +-q, --quiet Suppress warnings; overwrite files without asking +-u, --usr-randlen n Get 'n' characters of randomness from the user + (default: {}) + +-b, --from-brain l,p Generate wallet from a user-created passphrase, + i.e. a "brainwallet", using seed length 'l' and + hash preset 'p' (comma-separated) +-m, --from-mnemonic Generate wallet from an Electrum-like mnemonic +-s, --from-seed Generate wallet from a seed in .{S} format + +By default (i.e. when invoked without any of the '--from-' options), +{} generates a wallet based on a random seed. + +Data for the --from- options will be taken from if +is specified. Otherwise, the user will be prompted to enter the data. +Note that passphrase data may be input in free-form fashion, using any +combination of spaces or tabs (or newlines, in a file) between words. + +BRAINWALLET NOTE: + +As brainwallets require especially strong hashing to thwart dictionary +attacks, the brainwallet hash preset must be specified by the user, using +the 'p' parameter of the '--from-brain' option. This preset should be +stronger than the one used for hashing the seed (i.e. the default value or +the one specified in the '--hash-preset' option). + +The '--from-brain' option also requires the user to specify a seed length +(the 'l' parameter), which overrides both the default and any one given in +the '--seed-len' option. + +For a brainwallet passphrase to always generate the same keys and addresses, +the same 'l' and 'p' parameters to '--from-brain' must be used in all future +invocations with that passphrase. +""".format( + ", ".join([str(i) for i in seed_lens]), + seed_len, + hash_preset, + usr_randlen, + prog_name, + S=seed_ext, + ) +} + +short_opts = "hd:el:L:p:Pqu:b:ms" +long_opts = "help","outdir=","echo_passphrase","seed_len=","label=",\ + "hash_preset=","show_hash_presets","quiet","usr_randlen=",\ + "from_brain=","from_mnemonic","from_seed" + +opts,cmd_args = process_opts(sys.argv,help_data,short_opts,long_opts) + +if 'show_hash_presets' in opts: show_hash_presets() + +# Argument sanity checks and processing: + +set_if_unset_and_typeconvert(opts,( + ('usr_randlen',usr_randlen,'int'), + ('hash_preset',hash_preset,'str'), + ('seed_len',seed_len,'int') +)) + +# Exits on invalid input +check_opts(opts, + ('usr_randlen','hash_preset','seed_len','outdir','label','from_brain') +) + +if debug: + print "Processed options: %s" % repr(opts) + print "Cmd args: %s" % repr(cmd_args) + +if len(cmd_args) == 1 and ( + 'from_brain' in opts or + 'from_mnemonic' in opts or + 'from_seed' in opts): + infile = cmd_args[0] + check_infile(infile) +elif len(cmd_args) == 0: infile = "" +else: usage(help_data) + +# Begin execution + +if not 'quiet' in opts: do_license_msg() + +msg_r("Acquiring random data from your computer...") + +try: + from Crypto import Random + r = Random.new() + os_rand_data = (r.read(256),r.read(128)) +except: + msg("FAILED\nUnable to generate random numbers. Exiting") + sys.exit(2) + +msg("OK") + +if debug: display_os_random_data(os_rand_data) + +usr_keys,key_timings = get_random_data_from_user(opts) +msg("") + +if debug: display_user_random_data(usr_keys,key_timings) + +usr_rand_data = sha256(usr_keys).digest() + \ + sha256("".join(key_timings)).digest() + +s = get_seed(infile,opts,no_wallet=True) +if s: seed = s +else: + # Truncate random data for smaller seed lengths + seed = os_rand_data[0] + usr_rand_data + seed = sha256(seed).digest()[:opts['seed_len']/8] + +salt = os_rand_data[1] + usr_rand_data +salt = sha256(salt).digest()[:salt_len] + +passwd = get_first_passphrase_from_user( + "{} wallet passphrase".format(proj_name), opts) + +key = make_key(passwd, salt, opts['hash_preset']) + +enc_seed = encrypt_seed(seed, key, opts) + +write_wallet_to_file(seed,passwd,make_chksum_8(key),salt,enc_seed,opts) diff --git a/mmgen/Opts.py b/mmgen/Opts.py new file mode 100755 index 00000000..e3cad36c --- /dev/null +++ b/mmgen/Opts.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import sys, getopt +from mmgen.config import * + +def usage(hd): + print "USAGE: %s %s" % (hd['prog_name'], hd['usage']) + sys.exit(2) + +def print_help(progname,help_data): + pn_len = str(len(progname)+2) + print (" %-"+pn_len+"s %s") % (progname.upper()+":", help_data['desc']) + print (" %-"+pn_len+"s %s %s") % ("USAGE:", progname, help_data['usage']) + sep = "\n " + print " OPTIONS:"+sep+"%s" % sep.join(help_data['options'].strip().split("\n")) + + +def process_opts(argv,help_data,short_opts,long_opts): + + progname = argv[0].split("/")[-1] + + if debug: + print "Short opts: %s" % repr(short_opts) + print "Long opts: %s" % repr(long_opts) + + long_opts = [i.replace("_","-") for i in long_opts] + + try: cl_opts, args = getopt.getopt(argv[1:], short_opts, long_opts) + except getopt.GetoptError as err: + print str(err); sys.exit(2) + + opts,short_opts_l = {},[] + + for i in short_opts: + if i == ":": short_opts_l[-1] += i + else: short_opts_l += i + + for opt, arg in cl_opts: + if opt in ("-h","--help"): print_help(progname,help_data); sys.exit() + elif opt[:2] == "--" and opt[2:] in long_opts: + opts[opt[2:].replace("-","_")] = True + elif opt[:2] == "--" and opt[2:]+"=" in long_opts: + opts[opt[2:].replace("-","_")] = arg + elif opt[0] == "-" and opt[1] in short_opts_l: + opts[long_opts[short_opts_l.index(opt[1:])].replace("-","_")] = True + elif opt[0] == "-" and opt[1:]+":" in short_opts_l: + opts[long_opts[short_opts_l.index(opt[1:]+":")][:-1].replace("-","_")] = arg + else: assert False, "Invalid option" + + if debug: print "User-selected options: %s" % repr(opts) + + return opts,args diff --git a/mmgen/__init__.py b/mmgen/__init__.py new file mode 100755 index 00000000..a8f8becc --- /dev/null +++ b/mmgen/__init__.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +MMGen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +""" + +__all__ = [ + 'addr.py', + 'bitcoin.py', + 'config.py', + 'license.py', + 'mn_electrum.py', + 'mnemonic.py', + 'mn_tirosh.py', + 'Opts.py', + 'utils.py', + 'walletgen.py' +] + +__version__ = '.6.0' # See also below and setup.py + +# New software should look at this instead of at __version__ above. +version_info = (0, 6, 0) # See also above and setup.py diff --git a/mmgen/addr.py b/mmgen/addr.py new file mode 100755 index 00000000..e600b209 --- /dev/null +++ b/mmgen/addr.py @@ -0,0 +1,187 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +addr.py: Address generation/display routines for mmgen suite +""" + +import sys +from hashlib import sha256, sha512 +from binascii import hexlify, unhexlify + +from mmgen.bitcoin import numtowif + +def test_for_keyconv(): + """ + Test for the presence of 'keyconv' utility on system + """ + + keyconv_exec = "keyconv" + + from subprocess import Popen, PIPE + try: + p = Popen([keyconv_exec, '-h'], stdout=PIPE, stderr=PIPE) + except: + sys.stderr.write(""" +Executable '%s' unavailable. Falling back on (slow) internal ECDSA library. +Please install '%s' from the %s package on your system for much faster +address generation. + +""" % (keyconv_exec, keyconv_exec, "vanitygen")) + return False + else: + return True + + +def generate_addrs(seed, start, end, opts): + """ + generate_addresses(start, end, seed, opts) => None + + Generate a series of Bitcoin addresses from start to end based on a + seed, optionally outputting secret keys + + The 'keyconv' utility will be used for address generation if + installed. Otherwise an internal function is used + + Supported options: + print_secret, no_addresses, no_keyconv, gen_what + + Addresses are returned in a list of dictionaries with the following keys: + num, sec, wif, addr + """ + + if not 'no_addresses' in opts: + if 'no_keyconv' in opts or test_for_keyconv() == False: + sys.stderr.write("Using (slow) internal ECDSA library for address generation\n") + from mmgen.bitcoin import privnum2addr + keyconv = "" + else: + from subprocess import Popen, PIPE + keyconv = "keyconv" + + total_addrs = end - start + 1 + + addrlist = [] + + for i in range(1, end+1): + seed = sha512(seed).digest() # round /i/ + + if i < start: continue + + sys.stderr.write("\rGenerating %s: %s of %s" % + (opts['gen_what'], (i-start)+1, total_addrs)) + + # Secret key is double sha256 of seed hash round /i/ + sec = sha256(sha256(seed).digest()).hexdigest() + wif = numtowif(int(sec,16)) + + el = { 'num': i } + + if not 'print_addresses_only' in opts: + el['sec'] = sec + el['wif'] = wif + + if not 'no_addresses' in opts: + if keyconv: + p = Popen([keyconv, wif], stdout=PIPE) + addr = dict([j.split() for j in p.stdout.readlines()])['Address:'] + else: + addr = privnum2addr(int(sec,16)) + + el['addr'] = addr + + addrlist.append(el) + + sys.stderr.write("\rGenerated %s %s-%s%s\n" % + (opts['gen_what'], start, end, " "*9)) + + return addrlist + + +def format_addr_data(addrlist, seed_chksum, opts): + """ + print_addresses(addrs, opts) => None + + Print out the addresses and/or keys generated by generate_addresses() + + By default, prints addresses only + + Output can be customized with the following command line options: + print_secret + no_addresses + b16 + """ + + start = addrlist[0]['num'] + end = addrlist[-1]['num'] + + wif_msg = "" + if ('b16' in opts and 'print_secret' in opts) \ + or 'no_addresses' in opts: + wif_msg = " (wif)" + + fa = "%s%%-%ss %%-%ss %%s" % ( + " "*2, len(str(end)) + (0 if 'no_addresses' in opts else 1), + (5 if 'print_secret' in opts else 1) + len(wif_msg) + ) + + data = [] + data.append("%s {" % seed_chksum.upper()) + + for el in addrlist: + col1 = el['num'] + if 'no_addresses' in opts: + if 'b16' in opts: + data.append(fa % (col1, " (hex):", el['sec'])) + col1 = "" + data.append(fa % (col1, " (wif):", el['wif'])) + if 'b16' in opts: data.append("") + elif 'print_secret' in opts: + if 'b16' in opts: + data.append(fa % (col1, "sec (hex):", el['sec'])) + col1 = "" + data.append(fa % (col1, "sec"+wif_msg+":", el['wif'])) + data.append(fa % ("", "addr:", el['addr'])) + data.append("") + else: + data.append(fa % (col1, "", el['addr'])) + + if not data[-1]: data.pop() + data.append("}") + + return "\n".join(data) + "\n" + + +def write_addr_data_to_file(seed, data, start, end, opts): + + if 'print_addresses_only' in opts: ext = "addrs" + elif 'no_addresses' in opts: ext = "keys" + else: ext = "akeys" + + if 'b16' in opts: ext = ext.replace("keys","xkeys") + + from mmgen.utils import write_to_file, make_chksum_8, msg + addr_range = str(start) if start == end else "%s-%s" % (start,end) + outfile = "{}[{}].{}".format(make_chksum_8(seed),addr_range,ext) + if 'outdir' in opts: + outfile = "%s/%s" % (opts['outdir'], outfile) + +# print outfile; sys.exit(3) + write_to_file(outfile,data) + + dtype = "Address" if 'print_addresses_only' in opts else "Key" + msg("%s data saved to file '%s'" % (dtype,outfile)) diff --git a/mmgen/bitcoin.py b/mmgen/bitcoin.py new file mode 100755 index 00000000..30b11edc --- /dev/null +++ b/mmgen/bitcoin.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +bitcoin.py: Bitcoin address/key conversion functions +""" + +import ecdsa +from binascii import hexlify, unhexlify +from hashlib import sha256 +from hashlib import new as hashlib_new +import sys + +# From electrum: +# secp256k1, http://www.oid-info.com/get/1.3.132.0.10 +_p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL +_r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L +_b = 0x0000000000000000000000000000000000000000000000000000000000000007L +_a = 0x0000000000000000000000000000000000000000000000000000000000000000L +_Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L +_Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L +curve_secp256k1 = ecdsa.ellipticcurve.CurveFp( _p, _a, _b ) +generator_secp256k1 = ecdsa.ellipticcurve.Point( curve_secp256k1, _Gx, _Gy, _r ) +oid_secp256k1 = (1,3,132,0,10) +secp256k1 = ecdsa.curves.Curve("secp256k1", curve_secp256k1, generator_secp256k1, oid_secp256k1) + +b58a='123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' + +# +# From en.bitcoin.it: +# The Base58 encoding used is home made, and has some differences. +# Especially, leading zeroes are kept as single zeroes when conversion +# happens. +# +# Test: 5JbQQTs3cnoYN9vDYaGY6nhQ1DggVsY4FJNBUfEfpSQqrEp3srk +# +# The "zero address": +# 1111111111111111111114oLvT2 (use step2 = ("0" * 40) to generate) +# +def _pubhex2addr(pubhex): + step1 = sha256(unhexlify(pubhex)).digest() + step2 = hashlib_new('ripemd160',step1).hexdigest() + # See above: + extra_ones = (len(step2) - len(step2.lstrip("0"))) / 2 + step3 = sha256(unhexlify('00'+step2)).digest() + step4 = sha256(step3).hexdigest() + pubkey = int(step2 + step4[:8], 16) + return "1" + ("1" * extra_ones) + _numtob58(pubkey) + +def privnum2addr(numpriv): + pko = ecdsa.SigningKey.from_secret_exponent(numpriv,secp256k1) + pubkey = hexlify(pko.get_verifying_key().to_string()) + return _pubhex2addr('04'+pubkey) + +# Reworked code from here: + +def _numtob58(num): + b58conv,i = [],0 + while True: + n = num / (58**i); i += 1 + if not n: break + b58conv.append(b58a[n % 58]) + return ''.join(b58conv)[::-1] + +def _b58tonum(b58num): + for i in b58num: + if not i in b58a: + print "Invalid symbol in b58 number: '%s'" % i + sys.exit(9) + + b58deconv = [] + b58num_r = b58num[::-1] + for i in range(len(b58num)): + idx = b58a.index(b58num_r[i]) + b58deconv.append(idx * (58**i)) + return sum(b58deconv) + +def numtowif(numpriv): + step1 = '80'+hex(numpriv)[2:].rstrip('L').zfill(64) + step2 = sha256(unhexlify(step1)).digest() + step3 = sha256(step2).hexdigest() + key = step1 + step3[:8] + return _numtob58(int(key,16)) + + +# The following are mmgen internal (non-bitcoin) b58 functions +# +# Drop-in replacements for b64encode() and b64decode(): +# (well, not exactly: they yield numeric but not bytewise equivalence) + +def b58encode(s): + if s == "": return "" + num = int(hexlify(s),16) + return _numtob58(num) + +def b58decode(b58num): + if b58num == "": return "" + # Zap all spaces: + num = _b58tonum(b58num.translate(None,' \t\n\r')) + out = hex(num)[2:].rstrip('L') + return unhexlify("0" + out if len(out) % 2 else out) + +# These yield bytewise equivalence in our special cases: + +bin_lens = 16,24,32 +b58_lens = 22,33,44 + +def _b58_pad(s,a,b,pad,f,w): + try: + outlen = b[a.index(len(s))] + except: + print "_b58_pad() accepts only %s %s bytes long "\ + "(input was %s bytes)" % (w,",".join([str(i) for i in a]),len(s)) + sys.exit(9) + + out = f(s) + return "%s%s" % (pad * (outlen - len(out)), out) + +def b58encode_pad(s): + return _b58_pad(s, + a=bin_lens,b=b58_lens,pad="1",f=b58encode,w="binary strings") + +def b58decode_pad(s): + return _b58_pad(s, + a=b58_lens,b=bin_lens,pad='\0',f=b58decode,w="base 58 numbers") + + +################### FUNCTIONS UNUSED BY MMGEN: ################### + +# To check validity, recode with numtowif() +def wiftonum(wifpriv): + num = _b58tonum(wifpriv) + return (num % (1<<288)) >> 32 + +def wiftohex(wifpriv): + key = hex(_b58tonum(wifpriv))[2:].rstrip('L') + round1 = sha256(unhexlify(key[:66])).digest() + round2 = sha256(round1).hexdigest() + return key[2:66] if (key[:2] == '80' and key[66:] == round2[:8]) else False diff --git a/mmgen/config.py b/mmgen/config.py new file mode 100755 index 00000000..051d1799 --- /dev/null +++ b/mmgen/config.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +config.py: Constants and configuration options for the mmgen suite +""" +proj_name = "mmgen" +seed_ext = "mmseed" +default_wl = "electrum" +#default_wl = "tirosh" + +seed_lens = 128,192,256 +seed_len = 256 + +mnemonic_lens = [i / 32 * 3 for i in seed_lens] + +from os import getenv +debug = True if getenv("MMGEN_DEBUG") else False + +passwd_max_tries = 5 +max_randlen,min_randlen = 80,5 +usr_randlen = 20 +salt_len = 16 + +hash_preset = '3' +hash_presets = { +# Scrypt params: +# ID N p r + '1': [2**12, 8, 1], + '2': [2**13, 8, 4], + '3': [2**14, 8, 8], + '4': [2**15, 8, 12], + '5': [2**16, 8, 16], +} diff --git a/mmgen/license.py b/mmgen/license.py new file mode 100755 index 00000000..67285068 --- /dev/null +++ b/mmgen/license.py @@ -0,0 +1,649 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +license.py: Show the license +""" + +import sys +from mmgen.config import proj_name +from mmgen.utils import msg, msg_r + +gpl = { + 'warning': """ +{} Copyright (C) 2013 by philemon +This program comes with ABSOLUTELY NO WARRANTY. +This is free software, and you are welcome to +redistribute it under certain conditions. +""".format(proj_name), + 'prompt': """ +Press 'c' for conditions, 'w' for warranty info, +or ENTER to continue: +""", + 'conditions': """ + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. +""", + 'warranty': """ + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. +""" +} + +def do_license_msg(): + ls = "\n " + msg(" " + ls.join(gpl['warning'].strip().split("\n"))) + + try: + import os + os.system( + "stty -icanon min 1 time 0 -echo -echoe -echok -echonl -crterase noflsh" + ) + pager = os.environ['PAGER'] if 'PAGER' in os.environ else 'more' + + while True: + msg_r(ls + ls.join(gpl['prompt'].strip().split("\n")) + " ") + reply = sys.stdin.read(1) + if reply == 'c': + m = gpl['conditions'] + elif reply == 'w': + m = gpl['warranty'] + else: break + p = os.popen(pager, 'w') + p.write(m) + p.close() + except: + msg("\nInterrupted by user") + sys.exit(1) + finally: + os.system("stty sane") diff --git a/mmgen/mn_electrum.py b/mmgen/mn_electrum.py new file mode 100755 index 00000000..577c52f3 --- /dev/null +++ b/mmgen/mn_electrum.py @@ -0,0 +1,1657 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# electrum wordlist +# Electrum - lightweight Bitcoin client +# Copyright (C) 2011 thomasv@gitorious +# list of words from: +# http://en.wiktionary.org/wiki/Wiktionary:Frequency_lists/Contemporary_poetry + +# From mmgen: +# this is a sorted version of the wordlist. +# Original can be found here: +# https://github.com/spesmilo/electrum/blob/master/lib/mnemonic.py + +electrum_words = """ +able +about +above +abuse +accept +accident +ache +acid +across +act +action +actually +add +admire +admit +adore +advice +affection +afraid +after +afternoon +again +against +age +agony +agree +ahead +aim +air +alas +alive +allow +almost +alone +along +already +also +alter +although +always +amaze +among +ancient +angel +anger +angry +animal +annoy +another +answer +any +anymore +anyone +anything +anyway +anywhere +apart +apologize +appear +apple +appreciate +approach +army +around +arrive +arrow +art +ash +ashamed +aside +ask +asleep +attack +attempt +attention +aunt +autumn +avoid +await +awake +awaken +away +awe +awkward +baby +back +bag +balance +ball +bang +bank +bar +bare +barely +bathroom +battle +beam +beard +beaten +beautiful +beauty +became +become +bedroom +bee +been +before +beg +began +begin +begun +behind +belief +believe +belly +belong +bench +beneath +beside +best +better +between +beyond +bid +bird +birth +birthday +bit +bite +bitter +black +blade +blame +blank +blanket +bleed +blend +bless +blind +blink +bliss +block +blonde +blood +bloody +bloom +blossom +blow +blue +blur +blush +board +boat +body +bold +bomb +bond +bone +book +boom +born +both +bother +bottle +bottom +bought +bounce +bound +bowl +box +boyfriend +brain +branch +brand +brave +bread +break +breast +breath +breathe +breeze +bridge +bright +bring +broke +broken +brother +brown +bruise +brush +bubble +build +built +bullet +bump +burden +burn +burst +bury +bus +busy +butterfly +button +buy +cage +calm +came +candle +canvas +cap +capture +card +careful +carefully +caress +carry +carve +cast +catch +caught +cause +cease +ceiling +cell +center +certain +certainly +chain +chair +chance +change +character +charm +chase +cheap +cheat +check +cheek +cheer +cheese +chest +child +childhood +children +chill +chin +chocolate +choice +choke +choose +church +cigarette +circle +city +claim +class +claw +clay +clean +clear +clearly +click +climb +cling +clock +close +closet +clothes +cloud +clue +clutch +coat +coffee +cold +collapse +collect +college +color +comfort +commit +common +companion +company +compare +complain +complete +completely +concern +concrete +confidence +confuse +confusion +connect +connection +consider +constant +constantly +consume +content +continue +control +conversation +cookie +cool +core +corner +cost +couch +count +country +couple +courage +course +cousin +cover +coward +crack +crap +crash +crave +crawl +crazy +creak +cream +create +creation +creator +creature +creek +creep +crime +crimson +cross +crowd +cruel +crumble +crush +cry +crystal +cup +curl +curse +curtain +curve +cute +dad +daddy +daily +damn +dance +danger +dark +darkness +darling +dart +date +daughter +dawn +deadly +deal +dear +death +decay +decide +decision +deep +deeply +defeat +defense +define +delicate +delight +demand +demon +deny +depend +depress +depression +depth +descend +describe +desert +deserve +desire +desk +despair +desperate +desperately +despite +destination +destroy +determine +devil +dew +diamond +difference +different +dig +dim +dinner +direction +dirt +dirty +disappear +discover +disguise +dish +distance +distant +doctor +dog +doll +doom +door +dot +double +doubt +dove +down +drag +dragon +drama +draw +drawn +dread +dream +dreamer +dress +drift +drink +drive +driver +drop +drove +drug +drum +drunk +dry +duck +dude +due +dull +dumb +during +dust +dusty +dwell +each +eager +early +earth +easily +easy +eat +echo +edge +effort +egg +either +embarrass +embrace +emotion +emptiness +empty +end +endless +enemy +energy +engine +enjoy +enough +enter +entire +erase +escape +especially +essence +eternal +eternity +even +evening +eventually +ever +everybody +everyday +everyone +everything +everytime +everywhere +evil +exactly +example +except +excuse +exist +existence +expect +experience +explain +explode +explore +express +expression +eye +fact +fade +fail +faint +fairy +faith +false +familiar +family +fan +fantasy +fate +father +fault +favorite +fear +feast +feather +feed +feet +felicity +few +field +figure +fill +final +finally +find +finger +finish +fire +first +fish +fist +five +fix +flag +flame +flare +flash +flat +flesh +flicker +flight +flip +flirt +float +flood +floor +flow +flower +flutter +fly +focus +foe +fog +fold +follow +foot +football +footstep +force +forehead +forest +forever +forget +forgive +forgot +forgotten +form +former +forth +forward +fought +foul +fragile +frame +freak +free +freedom +freely +freeze +fresh +friend +friendship +fright +frighten +front +frost +frown +frozen +fruit +frustrate +fully +funny +fur +further +future +gain +game +garden +gas +gasp +gather +gay +gaze +generation +gentle +gently +ghost +giant +gift +giggle +girl +girlfriend +give +given +glad +glance +glare +glass +glide +glorious +glory +glove +glow +goal +god +gone +good +goodbye +goose +got +gotta +gotten +government +grab +grace +grade +grand +grandma +grant +grasp +grass +great +green +greet +grew +grey +grief +grin +grip +ground +group +grow +grown +guard +guess +guide +guilt +guilty +guitar +gun +guy +hair +half +hallway +hand +handle +hang +happen +happiness +happy +hardly +harm +harmony +harsh +hate +hatred +haunt +heal +health +heard +heart +heartbeat +heat +heaven +heavy +heel +held +hello +help +here +hero +hey +hidden +hide +high +hill +history +hit +hollow +holy +home +honest +honey +honor +hook +hop +hope +hopefully +horizon +horrible +horse +hospital +hour +house +however +howl +hug +huge +hum +human +hundred +hunger +hungry +hunt +hurl +hurry +hurt +husband +ice +idea +idiot +ignorance +ignore +illuminate +illusion +image +imagination +imagine +important +impossible +inch +indeed +inhale +ink +inner +innocence +innocent +insane +inside +instead +insult +interest +into +invisible +invite +iron +itself +jaw +jealous +jeans +job +jock +join +joke +journey +joy +judge +juice +jump +just +keep +kept +key +kick +kid +kill +king +kingdom +kiss +kitchen +knee +knife +knock +know +knowledge +known +lace +lady +laid +land +language +large +laugh +laughter +law +lazy +lead +leaf +leap +learn +least +leave +led +left +leg +less +lesson +letter +level +lick +lifeless +lift +lightning +like +limb +limit +line +linger +lip +liquid +listen +little +lonely +long +look +loose +lord +loser +loss +lot +loud +love +lovely +lucky +lunch +lung +lust +machine +made +magic +make +mama +manage +many +march +mark +marry +mask +mass +master +match +math +matter +maybe +mean +meant +measure +meet +melody +melt +memory +men +mend +mention +mercy +mere +mess +message +metal +middle +midnight +might +mighty +milk +million +mind +mine +minute +mirror +misery +mist +mistake +mix +moan +mock +mold +mom +moment +money +monkey +monster +month +moon +moonlight +moral +more +morning +mostly +mother +motion +mountain +mourn +mouth +movement +movie +much +mud +mumble +murder +muscle +muse +music +mutter +myself +mystery +nail +naked +name +nation +natural +nature +near +nearly +neck +need +needle +neighbor +neither +nerd +nerve +nervous +never +new +next +nice +night +nightmare +nine +nobody +nod +noise +normal +north +nose +note +nothing +notice +nowhere +numb +number +object +observe +obviously +ocean +odd +ode +off +offer +often +okay +once +only +open +opinion +opposite +orange +order +other +ourselves +out +outside +over +own +pack +page +painful +paint +pair +pale +palm +pants +paper +paradise +parent +park +party +pass +passion +past +path +pathetic +patience +patient +pattern +pause +pay +peace +peaceful +peach +peel +peer +pen +pencil +people +perfect +perfection +perfectly +perhaps +person +petal +phone +physical +picture +pie +piece +pierce +pig +pile +pillow +pink +pity +place +plain +plan +planet +plant +plastic +plate +play +please +pleasure +pocket +poem +poet +poetry +point +poison +ponder +pool +poor +pop +position +possess +possible +possibly +pound +pour +power +powerful +practice +praise +pray +prayer +precious +prefer +prepare +presence +present +press +pressure +pretend +pretty +price +pride +prince +princess +probably +problem +process +promise +protect +proud +prove +puff +pull +pulse +punch +pure +purple +purpose +push +put +puzzle +queen +question +quick +quickly +quiet +quietly +quit +quite +rabbit +radio +rainbow +raise +random +rant +rape +rare +rather +raw +reach +ready +real +reality +realize +really +reason +rebel +recall +receive +red +reflect +reflection +refuse +regret +relationship +relax +release +remain +remember +remind +remove +repeat +replace +reply +respect +respond +rest +retreat +return +reveal +revenge +rhyme +rhythm +rich +ring +rip +ripple +rise +river +road +roam +roar +rock +roll +root +rope +rose +rough +royal +rub +rude +ruin +rule +run +rush +sad +sadness +safe +said +sail +salt +salty +sanctuary +sane +sanity +sat +satisfy +save +savior +scale +scar +scary +scatter +scene +scent +school +score +scrape +scratch +scream +screen +screw +sea +search +season +second +secret +seek +seem +self +selfish +sense +sent +sentence +separate +serious +serve +settle +seven +several +shade +shadow +shall +shame +shape +sharp +shatter +sheep +sheet +shelter +shield +shift +shimmer +shine +shiny +ship +shirt +shiver +shock +shoe +shook +shoot +shore +should +shoulder +shout +shove +show +shower +shown +shut +shy +sick +sigh +sign +silence +silent +silently +silly +silver +simple +simply +since +single +sink +sister +situation +six +size +skill +skin +skip +sky +slam +slap +sleep +slept +slice +slide +slight +slightly +slowly +small +smart +smell +smile +smoke +smooth +snake +snap +sneak +snow +soak +soar +sob +social +society +soft +softly +soldier +some +somebody +someday +somehow +someone +something +sometimes +somewhere +son +song +soon +soothe +sorrow +sorry +sort +soul +sound +space +speak +special +speed +spell +spend +spider +spill +spin +spine +spiral +spirit +split +spoken +sport +spot +spread +spring +square +squeeze +stab +stage +stain +stair +stand +stare +start +state +stay +steady +steal +steel +step +stick +still +sting +stir +stock +stole +stolen +stomach +stone +stood +stop +storm +story +straight +strain +strange +stranger +stray +stream +street +strength +stress +stretch +strife +strike +string +strip +stroke +strong +struggle +stubborn +stuck +student +study +stuff +stumble +stun +stupid +style +subject +such +sudden +suddenly +suffer +suffocate +suicide +suit +summer +sunlight +sunset +support +suppose +sure +surely +surface +surprise +surround +survive +suspend +swallow +sway +swear +sweat +sweet +swell +swim +swing +swirl +sword +sympathy +table +taint +take +taken +talent +talk +tangle +tap +task +taste +taught +tea +teach +teacher +team +tease +teeth +tell +tender +terrible +terror +test +thank +them +themselves +then +there +thick +thigh +thing +think +third +thorn +those +thought +thousand +thread +threaten +three +threw +throat +throne +through +throughout +throw +thrown +thump +thunder +tickle +tide +tie +tight +tightly +time +tiny +tired +today +toe +together +tomorrow +tongue +tonight +too +tool +torment +torture +toss +total +touch +tough +toward +tower +town +trace +trade +trail +train +travel +treasure +treat +tree +tremble +trick +trickle +trip +trouble +truck +true +truly +trust +truth +try +tuck +tumble +tune +turn +twenty +twice +twirl +twist +two +type +ugly +unable +uncle +under +underneath +understand +universe +unknown +unless +unlike +unseen +upon +upset +use +useless +usually +utter +vain +valley +value +vast +veil +vein +velvet +verse +very +victim +view +violence +vision +visit +voice +void +volume +waist +wait +walk +wall +wander +want +war +warm +warmth +warn +warrior +wash +waste +watch +water +wave +weak +weakness +weapon +weary +weather +weave +week +weep +weight +weird +welcome +wet +whatever +wheel +whenever +whether +whisper +whistle +white +whole +wife +wild +win +window +winter +wipe +wise +wish +witch +within +wolf +woman +women +won +wonder +wonderful +wood +work +world +worry +worse +worship +worst +worth +worthless +wound +wow +wrap +wrinkle +wrist +write +written +wrong +wrote +yard +yeah +yearn +yell +yellow +yesterday +yet +young +yours +yourself +youth +""" diff --git a/mmgen/mn_tirosh.py b/mmgen/mn_tirosh.py new file mode 100755 index 00000000..0be13103 --- /dev/null +++ b/mmgen/mn_tirosh.py @@ -0,0 +1,1658 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Oren Tirosh wordlist +# Copyright (c) 2000 Oren Tirosh + +# From mmgen: this is a sorted version of the wordlist + +tirosh_words = """ +abraham +absent +absorb +academy +accent +acid +acrobat +action +active +actor +adam +address +adios +admiral +adrian +africa +agatha +agenda +agent +airline +airport +alabama +aladdin +alamo +alarm +alaska +albert +albino +album +alcohol +alert +alex +alfonso +alfred +algebra +alias +alibi +alice +alien +almanac +almond +aloha +alpha +alpine +amadeus +amanda +amazon +amber +ambient +amen +america +amigo +ammonia +analog +analyze +anatomy +andrea +andy +angel +animal +anita +annual +answer +antenna +antonio +anvil +apollo +appear +apple +april +apropos +arcade +archer +archive +arctic +arena +ariel +arizona +armada +armor +arnold +aroma +arrow +arsenal +arthur +artist +asia +aspect +aspirin +athena +athlete +atlanta +atlas +atomic +audio +august +aurora +austin +austria +avalon +avatar +avenue +average +axiom +axis +aztec +baboon +baby +bagel +baggage +bahama +baker +balance +bali +ballad +ballet +balloon +balsa +bambino +bamboo +banana +bandit +banjo +bank +barbara +barcode +baron +basic +basil +basket +battery +bazaar +bazooka +beach +beast +beatles +beauty +before +begin +belgium +benefit +benny +berlin +bermuda +bernard +betty +between +beyond +bicycle +bikini +billy +binary +bingo +biology +biscuit +bishop +bison +blast +bless +blitz +block +blonde +blue +bogart +bombay +bonanza +bonjour +bonus +book +border +boris +boston +bottle +boxer +brain +brandy +brave +bravo +brazil +bread +break +brenda +bridge +brigade +british +broken +bronze +brother +brown +bruce +bruno +brush +bucket +budget +buenos +buffalo +bundle +burger +burma +button +buzzer +byte +cabaret +cabinet +cable +cactus +cadet +caesar +cafe +cairo +cake +calypso +camel +camera +camilla +campus +canada +canal +canary +candid +candle +cannon +canoe +cantina +canvas +canyon +capital +capitan +capsule +caramel +caravan +carbon +career +cargo +carlo +carmen +carol +carpet +carrot +cartel +cartoon +casino +castle +castro +catalog +cave +caviar +cecilia +cello +celtic +cement +center +century +ceramic +chamber +chance +change +channel +chant +chaos +chapter +chariot +charlie +charm +charter +cheese +chef +chemist +cherry +chess +chicago +chicken +chief +child +china +choice +chris +chrome +cigar +cinema +cipher +circle +circus +citizen +citrus +city +civil +clara +clarion +clark +classic +claudia +clean +clever +client +cliff +climax +clinic +clock +clone +cloud +club +cobalt +cobra +cockpit +coconut +cola +collect +college +colombo +colony +color +combat +comedy +comet +command +common +compact +company +compare +compass +complex +comrade +conan +concept +concert +condor +conduct +congo +connect +consul +contact +content +context +contour +control +convert +cool +copper +copy +coral +corner +corona +correct +cosmos +costume +cotton +couple +courage +cover +cowboy +crack +craft +crash +crater +credit +cricket +crimson +critic +crown +crystal +cuba +cubic +culture +cupid +current +cycle +cyclone +dallas +dance +daniel +danube +darwin +data +david +deal +decade +decide +decimal +declare +degree +delete +deliver +delphi +delta +deluxe +demand +demo +denmark +denver +depend +derby +desert +design +desire +detail +detect +develop +dexter +diagram +dialog +diamond +diana +diego +diesel +diet +digital +dilemma +dinner +diploma +direct +disco +disney +dispute +distant +divide +doctor +dolby +dollar +domain +domingo +dominic +domino +donald +donor +door +double +dragon +drama +dream +drink +driver +druid +drum +dublin +duet +dynamic +dynasty +eagle +earth +east +easy +echo +eclipse +ecology +economy +eddie +edgar +edison +edition +editor +educate +edward +effect +ego +egypt +elastic +electra +elegant +element +elite +elvis +email +emerald +emotion +empire +empty +energy +engine +english +enigma +enjoy +enrico +episode +epoxy +equal +equator +eric +erosion +escape +escort +eternal +ethnic +europe +evening +event +everest +evident +evita +exact +example +except +exhibit +exile +exit +exodus +exotic +expand +explain +explore +export +express +extend +extra +extreme +fabric +factor +falcon +fame +family +famous +fantasy +farmer +fashion +fast +father +fax +felix +ferrari +fiber +fiction +fidel +field +fiesta +figure +film +filter +final +finance +finish +finland +fiona +fire +first +fish +flag +flame +flash +flex +flipper +float +flood +floor +florida +flower +fluid +flute +focus +folio +food +forbid +ford +forest +forever +forget +formal +format +formula +fortune +forum +forward +fossil +fractal +fragile +frame +france +frank +freddie +freedom +fresh +friday +friend +frog +front +frozen +fruit +fuel +fuji +future +gabriel +galaxy +galileo +gallery +gallop +game +gamma +garage +garbo +garcia +garden +garlic +gate +gemini +general +genesis +genetic +geneva +genius +gentle +george +germany +giant +gibson +gilbert +ginger +giraffe +gizmo +glass +global +gloria +goblin +gold +golf +gondola +gong +good +gopher +gordon +gorilla +gossip +grace +gram +grand +granite +graph +gravity +gray +greek +green +gregory +grid +griffin +grille +ground +group +guest +guide +guitar +guru +gustav +gyro +habitat +hair +halt +hamlet +hammer +hand +happy +harbor +harlem +harmony +harris +harvard +harvest +havana +hawaii +hazard +heart +heaven +heavy +helena +helium +hello +henry +herbert +herman +heroic +hexagon +hilton +hippie +history +hobby +holiday +honey +hope +horizon +horse +hostel +hotel +house +human +humor +hunter +husband +hydro +ibiza +iceberg +icon +idea +igloo +igor +image +imagine +imitate +immune +impact +import +inca +inch +index +india +indigo +infant +info +ingrid +initial +input +insect +inside +instant +invent +invest +invite +iris +iron +isabel +isotope +italian +ivan +ivory +jacket +jackson +jacob +jaguar +jamaica +james +janet +japan +jargon +jasmine +jason +java +jazz +jeep +jerome +jessica +jester +jet +jimmy +job +joel +john +join +joker +jordan +joseph +joshua +journal +judge +judo +juice +juliet +julius +july +jumbo +jump +june +jungle +junior +jupiter +justice +justin +kansas +karate +karl +karma +kayak +kermit +kevin +kilo +kimono +kinetic +king +kitchen +kiwi +koala +korea +labor +ladder +lady +lagoon +lake +laptop +laser +latin +laura +lava +lazarus +learn +lecture +left +legacy +legal +legend +lemon +leonid +lesson +letter +level +lexicon +liberal +libra +license +life +light +lima +limbo +limit +linda +linear +lion +liquid +list +liter +lithium +little +llama +lobby +lobster +local +locate +logic +logo +lola +london +lopez +lorenzo +lotus +love +loyal +lucas +lucky +lunar +lunch +machine +macro +madam +madonna +madrid +maestro +magenta +magic +magnet +magnum +mailbox +major +malta +mama +mambo +mammal +manager +mango +manila +manual +marble +marco +margo +marina +marion +market +mars +martin +marvin +mary +mask +master +match +matrix +maximum +maxwell +mayday +mayor +maze +meaning +media +medical +medusa +mega +melody +melon +member +memo +memphis +mental +mentor +menu +mercury +mercy +message +metal +meteor +meter +method +metro +mexico +miami +michael +micro +middle +miguel +mike +milan +mile +milk +miller +million +mimic +mimosa +mineral +minimum +minus +minute +miracle +mirage +miranda +mirror +mission +mister +mixer +mobile +model +modem +modern +modest +modular +moment +monaco +monarch +monday +money +monica +monitor +monkey +mono +monster +montana +moral +morgan +morning +morph +morris +moses +motel +mother +motif +motor +mouse +mozart +multi +museum +music +mustang +mystery +nadia +nancy +natasha +native +nato +natural +navy +nebula +nectar +needle +nelson +neon +nepal +neptune +nerve +network +neuron +neutral +nevada +never +news +newton +next +nice +nickel +night +nikita +nina +ninja +nirvana +nissan +nitro +nixon +nobel +nobody +noise +nominal +normal +north +norway +nothing +nova +novel +nuclear +null +number +numeric +nurse +nylon +oasis +oberon +object +observe +ocean +octavia +october +octopus +office +ohio +olga +oliver +olivia +olympic +omega +open +opera +opinion +optic +optimal +option +opus +orange +orbit +orca +orchid +order +oregano +organic +orient +origami +origin +orinoco +orion +orlando +oscar +othello +outside +oval +owner +oxford +oxygen +ozone +pablo +pacific +package +page +pagoda +paint +palace +palma +pamela +panama +pancake +panda +pandora +panel +panic +panther +papa +paper +paprika +parade +paradox +pardon +parent +paris +parker +parking +parody +parole +partner +passage +passive +pasta +pastel +patent +patient +patriot +patrol +patron +pattern +paul +peace +pearl +pedro +pegasus +pelican +pencil +penguin +people +pepper +percent +perfect +perform +perfume +period +permit +person +peru +phantom +philips +phoenix +phone +photo +phrase +piano +picasso +picnic +picture +pierre +pigment +pilgrim +pilot +pinball +pioneer +pirate +pixel +pizza +place +planet +plasma +plaster +plastic +plate +plato +plaza +plume +pluto +pocket +podium +poem +poetic +pogo +point +poker +polaris +police +polite +politic +polka +polo +polygon +poncho +pony +popcorn +popular +portal +postage +postal +potato +powder +prague +precise +prefix +prelude +premium +prepare +present +press +presto +pretend +pretty +price +prime +prince +printer +prism +private +prize +process +product +profile +profit +program +project +promise +promo +protect +protein +proton +provide +proxy +public +pulse +puma +pump +pupil +puzzle +pyramid +python +quality +quarter +quasi +quebec +queen +quest +quick +quiet +quiz +quota +rabbit +race +rachel +radar +radical +radio +radius +rainbow +raja +ralph +ramirez +random +ranger +rapid +ravioli +raymond +rebel +record +recycle +reflex +reform +regard +region +regular +relax +remark +remote +rent +repair +reply +report +reptile +reserve +respect +respond +result +resume +retro +reunion +reverse +reward +rhino +ribbon +ricardo +richard +rider +right +ringo +rio +risk +ritual +rival +river +riviera +road +robert +robin +robot +rocket +rodent +rodeo +roger +roman +romeo +rondo +roof +rose +round +rover +royal +rubber +ruby +rudolf +rufus +russian +sabine +sabrina +saddle +safari +saga +sahara +sailor +saint +salad +salami +salary +salmon +salon +salsa +salt +salute +samba +sample +samuel +sandra +santana +sardine +satire +saturn +savage +scale +scarlet +scholar +school +scoop +scorpio +scratch +screen +script +scroll +scuba +season +second +secret +section +sector +secure +segment +select +seminar +senator +senior +sensor +serial +serpent +service +shadow +shake +shallow +shampoo +shannon +sharon +sharp +shave +shelf +shelter +sheriff +sherman +shine +ship +shirt +shock +shoe +short +shrink +side +sierra +sigma +signal +silence +silicon +silk +silver +similar +simon +simple +sinatra +sincere +singer +single +siren +sister +size +ski +slalom +slang +sleep +slogan +slow +small +smart +smile +smoke +snake +snow +social +society +soda +sofia +solar +solid +solo +sonar +sonata +song +sonic +soprano +sound +source +south +soviet +spain +spark +sparta +special +speech +speed +spell +spend +sphere +spider +spiral +spirit +split +sponsor +spoon +sport +spray +spring +square +stadium +stage +stamp +stand +star +state +static +station +status +stella +stereo +stick +sting +stock +stone +stop +store +storm +story +strange +street +stretch +strong +stuart +student +studio +style +subject +subway +sugar +sulfur +sultan +summer +sunday +sunset +super +support +survive +susan +sushi +suzuki +sweden +sweet +swim +swing +switch +symbol +system +table +taboo +tactic +tahiti +talent +tango +tape +target +tarzan +taxi +teacher +telecom +telex +temple +tempo +tennis +texas +textile +theory +thermos +think +thomas +tibet +ticket +tictac +tiger +time +tina +titanic +toast +tobacco +today +toga +tokyo +tomato +tommy +tonight +topic +torch +tornado +toronto +torpedo +torso +total +totem +touch +tourist +tower +toyota +tractor +trade +traffic +transit +trapeze +travel +tribal +tribune +trick +trident +trilogy +trinity +tripod +triton +trivial +tropic +truck +trumpet +trust +tulip +tuna +tunnel +turbo +turtle +twin +twist +type +ultra +uncle +under +unicorn +uniform +union +unique +unit +update +uranium +urban +urgent +user +vacuum +valery +valid +value +vampire +vanilla +vatican +vega +velvet +vendor +venice +ventura +venus +verbal +verona +version +vertigo +veteran +vibrate +victor +video +vienna +viking +village +vincent +violet +violin +virgo +virtual +virus +visa +visible +vision +visitor +vista +visual +vital +vitamin +viva +vocal +vodka +voice +volcano +voltage +volume +voodoo +vortex +voyage +waiter +warning +watch +water +wave +weather +wedding +weekend +welcome +western +wheel +whiskey +william +window +winter +wisdom +wizard +wolf +wonder +world +xray +yankee +year +yellow +yes +yoga +yogurt +young +yoyo +zebra +zero +zigzag +zipper +zodiac +zoom +""" diff --git a/mmgen/mnemonic.py b/mmgen/mnemonic.py new file mode 100755 index 00000000..0e5b7f5d --- /dev/null +++ b/mmgen/mnemonic.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +mnemonic.py: Mnemomic routines for the mmgen suite +""" + +wl_checksums = { + "electrum": '5ca31424', + "tirosh": '1a5faeff' +} + +# These are the only base-1626 specific configs: +mn_base = 1626 +def mn_fill(mn): return len(mn) * 8 / 3 +def mn_len(hexnum): return len(hexnum) * 3 / 8 + +import sys + +from mmgen.utils import msg,make_chksum_8 +from mmgen.config import * + +# These universal base-conversion routines work for any base + +def baseNtohex(base,words,wordlist,fill=0): + deconv = \ + [wordlist.index(words[::-1][i])*(base**i) for i in range(len(words))] + return hex(sum(deconv))[2:].rstrip('L').zfill(fill) + +def hextobaseN(base,hexnum,wordlist,mn_len): + num = int(hexnum,16) + return [wordlist[num / (base**i) % base] for i in range(mn_len)][::-1] + +def get_seed_from_mnemonic(mn,wl): + + if len(mn) not in mnemonic_lens: + msg("Bad mnemonic (%i words). Allowed numbers of words: %s" % + (len(mn)," ".join([str(i) for i in mnemonic_lens]))) + sys.exit(2) + + for w in mn: + if w not in wl: + msg("Bad mnemonic: '%s' is not in the wordlist" % w) + sys.exit(2) + + from binascii import unhexlify + seed = unhexlify(baseNtohex(mn_base,mn,wl,mn_fill(mn))) + msg("Valid mnemomic for seed ID %s" % make_chksum_8(seed)) + + return seed + + +def get_mnemonic_from_seed(seed, wl, label, print_info=False): + + from binascii import hexlify + + if print_info: + msg("Wordlist: %s" % label.capitalize()) + msg("Seed length: %s bits" % (len(seed) * 8)) + msg("Seed: %s" % hexlify(seed)) + + hseed = hexlify(seed) + mn = hextobaseN(mn_base,hseed,wl,mn_len(hseed)) + + if print_info: + msg("mnemonic (%s words):\n%s" % (len(mn), " ".join(mn))) + + if int(baseNtohex(mn_base,mn,wl,mn_fill(mn)),16) != int(hexlify(seed),16): + msg("ERROR: seed recomputed from wordlist not the same as original seed!") + msg("Recomputed seed %s" % baseNtohex(mn_base,mn,wl,mn_fill(mn))) + sys.exit(3) + + return mn + + +def check_wordlist(wl_str,label): + + wl = wl_str.strip().split("\n") + + print "Wordlist: %s" % label.capitalize() + + from hashlib import sha256 + + print "Length: %i" % len(wl) + new_chksum = sha256(" ".join(wl)).hexdigest()[:8] + + if new_chksum != wl_checksums[label]: + print "ERROR: Checksum mismatch. Computed: %s, Saved: %s" % \ + (new_chksum,wl_checksums[label]) + sys.exit(3) + + print "Checksum: %s (matches)" % new_chksum + + if (sorted(wl) == wl): + print "List is sorted" + else: + print "ERROR: List is not sorted!" + sys.exit(3) diff --git a/mmgen/utils.py b/mmgen/utils.py new file mode 100755 index 00000000..6e927206 --- /dev/null +++ b/mmgen/utils.py @@ -0,0 +1,727 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +utils.py: Shared routines for the mmgen suite +""" + +import sys +from mmgen.config import * +from binascii import hexlify,unhexlify + +def msg(s): sys.stderr.write(s + "\n") +def msg_r(s): sys.stderr.write(s) + +def bail(): sys.exit(9) + +def _my_getpass(prompt): + + from getpass import getpass + # getpass prompts to stderr, so no trickery required as with raw_input() + try: pw = getpass(prompt) + except: + msg("\nInterrupted by user") + sys.exit(1) + + return pw + + +def _my_raw_input(prompt): + + msg_r(prompt) + try: pw = raw_input() + except: + msg("\nInterrupted by user") + sys.exit(1) + + return pw + + +def _get_hash_params(hash_preset): + if hash_preset in hash_presets: + return hash_presets[hash_preset] # N,p,r,buflen + else: + # Shouldn't be here + msg("%s: invalid 'hash_preset' value" % hash_preset) + sys.exit(3) + +def show_hash_presets(): + fs = " {:<7} {:<6} {:<3} {}" + msg("Available parameters for scrypt.hash():") + msg(fs.format("Preset","N","r","p")) + for i in sorted(hash_presets.keys()): + msg(fs.format("'%s'" % i, *hash_presets[i])) + msg("N = memory usage, p = iterations (rounds)") + sys.exit(0) + + +def check_opts(opts,keys): + + for key in keys: + if key not in opts: continue + + val = opts[key] + what = "parameter for '--%s' option" % key.replace("_","-") + + if key == 'outdir': + what = "output directory" + import re, os, stat + d = re.sub(r'/*$','', val) + opts[key] = d + + try: mode = os.stat(d).st_mode + except: + msg("Unable to stat requested %s '%s'. Aborting" % (what,d)) + sys.exit(1) + + if not stat.S_ISDIR(mode): + msg("Requested %s '%s' is not a directory. Aborting" %(what,d)) + sys.exit(1) + + if not os.access(d, os.W_OK|os.X_OK): + msg("Requested %s '%s' is unwritable by you. Aborting"%(what,d)) + sys.exit(1) + + elif key == 'label': + label = val.strip() + opts[key] = label + + if len(label) > 32: + msg("Label must be 32 characters or less") + sys.exit(1) + + from string import ascii_letters, digits + label_chrs = list(ascii_letters + digits) + [".", "_", " "] + for ch in list(label): + if ch not in label_chrs: + msg("'%s': illegal character in label" % ch) + sys.exit(1) + + elif key == 'from_brain': + try: + l,p = val.split(",") + except: + msg("'%s': invalid %s" % (val,what)) + sys.exit(1) + + try: + int(l) + except: + msg("'%s': invalid 'l' %s (not an integer)" % (l,what)) + sys.exit(1) + + if int(l) not in seed_lens: + msg("'%s': invalid 'l' %s. Options: %s" % + (l, what, ", ".join([str(i) for i in seed_lens]))) + sys.exit(1) + + if p not in hash_presets: + hps = ", ".join([i for i in sorted(hash_presets.keys())]) + msg("'%s': invalid 'p' %s. Options: %s" % (p, what, hps)) + sys.exit(1) + elif key == 'seed_len': + if val not in seed_lens: + msg("'%s': invalid %s. Options: %s" + % (val,what,", ".join([str(i) for i in seed_lens]))) + sys.exit(2) + elif key == 'hash_preset': + if val not in hash_presets: + msg("'%s': invalid %s. Options: %s" + % (val,what,", ".join(sorted(hash_presets.keys())))) + sys.exit(2) + elif key == 'usr_randlen': + if val > max_randlen or val < min_randlen: + msg("'%s': invalid %s (must be >= %s and <= %s)" + % (val,what,min_randlen,max_randlen)) + sys.exit(2) + + +cmessages = { + 'null': "", + 'unencrypted_secret_keys': """ +This program generates secret keys from your {} seed, outputting them in +UNENCRYPTED form. Generate only the key(s) you need and guard them carefully. +""".format(proj_name), + 'brain_warning': """ +############################## EXPERTS ONLY! ############################## + +A brainwallet will be secure only if you really know what you're doing and +have put much care into its creation. {} assumes no responsibility for +coins stolen as a result of a poorly crafted brainwallet passphrase. + +A key will be generated from your passphrase using the parameters requested +by you: seed length {}, hash preset '{}'. For brainwallets it's highly +recommended to use one of the higher-numbered presets + +Remember the seed length and hash preset parameters you've specified. To +generate the correct keys/addresses associated with this passphrase in the +future, you must continue using these same parameters +""" +} + +def confirm_or_exit(message, question): + + if message.strip(): msg(message.strip()) + msg("") + + conf_msg = "Type uppercase 'YES' to confirm: " + + if question[0].isupper(): + prompt = question + " " + conf_msg + else: + prompt = "Are you sure you want to %s?\n%s" % (question,conf_msg) + + if _my_raw_input(prompt).strip() != "YES": + msg("Program aborted by user") + sys.exit(2) + + msg("") + + +def set_if_unset_and_typeconvert(opts,item): + +# ('usr_randlen',usr_randlen,'int'), + for opt,var,dtype in item: + if dtype == 'int': f,s = int,"an integer" + elif dtype == 'str': f,s = str,"a string" + + if opt in opts: + val = opts[opt] + what = "invalid parameter for '--%s' option" % opt.replace("_","-") + try: + f(val) + except: + msg("'%s': %s (not %s)" % (val,what,s)) + sys.exit(1) + opts[opt] = f(val) + else: + opts[opt] = var + + +def make_chksum_8(s): + from hashlib import sha256 + return sha256(sha256(s).digest()).hexdigest()[:8].upper() + +def _make_chksum_6(s): + from hashlib import sha256 + return sha256(s).hexdigest()[:6] + + +def _get_from_brain_opt_params(opts): + l,p = opts['from_brain'].split(",") + return(int(l),p) + + +def check_infile(f): + + import os, stat + + try: mode = os.stat(f).st_mode + except: + msg("Unable to stat requested input file '%s'. Aborting" % f) + sys.exit(1) + + if not stat.S_ISREG(mode) or stat.S_ISLNK(mode): + msg("Requested input file '%s' is not a file. Aborting" % f) + sys.exit(1) + + if not os.access(f, os.R_OK): + msg("Requested input file '%s' is unreadable by you. Aborting" % f) + sys.exit(1) + + +def parse_address_range(arg): + + import re + m = re.match(r'^(\d+)(-(\d+))*$', arg) + + if m == None: + msg(arg + ": invalid argument for address range") + sys.exit(2) + + start,end = int(m.group(1)), int(m.group(3) or m.group(1)) + + if start < 1: + msg(args + ": First address must be >= 1") + sys.exit(2) + + if end < start: + msg(arg + ": Last address must be >= first address") + sys.exit(2) + + return start,end + + +def get_first_passphrase_from_user(what, opts): + """ + Prompt the user for a passphrase and return it + + Supported options: echo_passphrase + """ + + if not 'quiet' in opts: + msg(""" +Now you must choose a passphrase to encrypt the seed with. A key will be +generated from your passphrase using a hash preset of '%s'. Please note that +no strength checking of passphrases is performed. For an empty passphrase, +just hit ENTER twice. +""" % opts['hash_preset']) + + for i in range(passwd_max_tries): + if 'echo_passphrase' in opts: + return _my_raw_input("Enter %s: " % what) + else: + ret = _my_getpass("Enter %s: " % what) + if ret == _my_getpass("Repeat %s: " % what): + s = " (empty)" if not len(ret) else "" + msg("%ss match%s" % (what.capitalize(),s)) + return ret + else: + msg("%ss do not match" % what.capitalize()) + + msg("User failed to duplicate passphrase in " + str(passwd_max_tries) + " attempts") + sys.exit(2) + + +def _scrypt_hash_passphrase(passwd, salt, hash_preset, buflen=32): + + N,r,p = _get_hash_params(hash_preset) + + import scrypt + return scrypt.hash(passwd, salt, N, r, p, buflen=buflen) + + +def _get_seed_from_brain_passphrase(words,opts): + bp = " ".join(words) + if debug: print "Sanitized brain passphrase: %s" % bp + seed_len,hash_preset = _get_from_brain_opt_params(opts) + if debug: print "Brainwallet l = %s, p = %s" % (seed_len,hash_preset) + msg_r("Hashing brainwallet data. Please wait...") + # Use buflen arg to scrypt.hash() to get seed of desired length + seed = _scrypt_hash_passphrase(bp, "", hash_preset, buflen=seed_len/8) + msg("Done") + return seed + + +def encrypt_seed(seed, key, opts): + """ + Encrypt a seed for a {} deterministic wallet + """.format(proj_name) + + # 192-bit seed is 24 bytes -> not multiple of 16. Must use MODE_CTR + from Crypto.Cipher import AES + from Crypto.Util import Counter + + c = AES.new(key, AES.MODE_CTR,counter=Counter.new(128)) + enc_seed = c.encrypt(seed) + + msg_r("Performing a test decryption of the seed...") + + c = AES.new(key, AES.MODE_CTR,counter=Counter.new(128)) + dec_seed = c.decrypt(enc_seed) + + if dec_seed == seed: msg("done") + else: + msg("FAILED.\nDecrypted seed doesn't match original seed. Aborting.") + sys.exit(2) + + return enc_seed + + +def write_to_stdout(data, confirm=True): + if sys.stdout.isatty() and confirm: + confirm_or_exit("",'output secret keys to screen') + elif not sys.stdout.isatty(): + import os + of = os.readlink("/proc/%d/fd/1" % os.getpid()) + msg("Writing data to file '%s'" % of) + sys.stdout.write("\n" + data) + + +def get_default_wordlist(): + + wl_id = default_wl + if wl_id == "electrum": from mmgen.mn_electrum import electrum_words as wl + elif wl_id == "tirosh": from mmgen.mn_tirosh import tirosh_words as wl + return wl.strip().split("\n") + + +def write_to_file(outfile,data,confirm=False): + + if confirm: + from os import stat + try: + stat(outfile) + except: + pass + else: + confirm_or_exit("","File '%s' already exists\nOverwrite?" % outfile) + + try: + f = open(outfile,'w') + except: + msg("Failed to open file '%s' for writing" % outfile) + sys.exit(2) + + try: + f.write(data) + except: + msg("Failed to write to file '%s'" % outfile) + sys.exit(2) + + f.close + + +def write_seed_to_file(seed, opts): + + outfile = "%s.%s" % (make_chksum_8(seed).upper(),seed_ext) + if 'outdir' in opts: + outfile = "%s/%s" % (opts['outdir'], outfile) + + from mmgen.bitcoin import b58encode_pad + data = col4(b58encode_pad(seed)) + chk = _make_chksum_6(b58encode_pad(seed)) + + write_to_file(outfile, "%s %s\n" % (chk,data)) + + msg("%s data saved to file '%s'" % ("Seed",outfile)) + + +def write_mnemonic_to_file(mn, seed, opts): + + outfile = "%s.words" % make_chksum_8(seed).upper() + if 'outdir' in opts: + outfile = "%s/%s" % (opts['outdir'], outfile) + + write_to_file(outfile," ".join(mn) + "\n") + + msg("%s data saved to file '%s'" % ("Mnemonic",outfile)) + + +def _display_control_data(label,metadata,hash_preset,salt,enc_seed): + msg("WALLET DATA") + fs = " {:25} {}" + pw_empty = "yes" if metadata[3] == "E" else "no" + from mmgen.bitcoin import b58encode_pad + for i in ( + ("Label:", label), + ("Seed ID:", metadata[0]), + ("Key ID:", metadata[1]), + ("Seed length:", metadata[2]), + ("Scrypt hash params:", "Preset '%s' (%s)" % (hash_preset, + " ".join([str(i) for i in _get_hash_params(hash_preset)]))), + ("Passphrase is empty:", pw_empty), + ("Timestamp:", "%s UTC" % metadata[4]), + ("Salt:", b58encode_pad(salt)), + ("Encrypted seed:", b58encode_pad(enc_seed)) + ): msg(fs.format(*i)) + + +def col4(s): + nondiv = 1 if len(s) % 4 else 0 + return " ".join([s[4*i:4*i+4] for i in range(len(s)/4 + nondiv)]) + + +def write_wallet_to_file(seed, passwd, key_id, salt, enc_seed, opts): + + import time + tv = time.gmtime(time.time())[:6] + ts_hdr = "{:04d}{:02d}{:02d}_{:02d}{:02d}{:02d}".format(*tv) + + seed_id = make_chksum_8(seed) + seed_len = str(len(seed)*8) + pw_status = "NE" if len(passwd) else "E" + + hash_preset = opts['hash_preset'] + + outfile = "{}-{}[{},{}].dat".format(seed_id,key_id,seed_len,hash_preset) + if 'outdir' in opts: + outfile = "%s/%s" % (opts['outdir'], outfile) + + label = opts['label'] if 'label' in opts else "None" + + from mmgen.bitcoin import b58encode_pad + + sf = b58encode_pad(salt) + esf = b58encode_pad(enc_seed) + + metadata = seed_id.lower(),key_id.lower(),seed_len,pw_status,ts_hdr + + lines = ( + label, + "{} {} {} {} {}".format(*metadata), + "{}: {} {} {}".format(hash_preset,*_get_hash_params(hash_preset)), + "{} {}".format(_make_chksum_6(sf), col4(sf)), + "{} {}".format(_make_chksum_6(esf), col4(esf)) + ) + + chk = _make_chksum_6(" ".join(lines)) + + confirm = False if 'quiet' in opts else True + write_to_file(outfile, "\n".join((chk,)+lines)+"\n", confirm) + + msg("Wallet saved to file '%s'" % outfile) + if 'verbose' in opts: + _display_control_data(label,metadata,hash_preset,salt,enc_seed) + + +def compare_checksums(chksum1, desc1, chksum2, desc2): + + if chksum1.lower() == chksum2.lower(): + msg("OK (%s)" % chksum1.upper()) + return True + else: + msg("ERROR!\nComputed checksum %s (%s) doesn't match checksum %s (%s)" \ + % (desc1,chksum1,desc2,chksum2)) + return False + +def _is_hex(s): + try: int(s,16) + except: return False + else: return True + + +def check_mmseed_format(words): + + valid = False + what = "%s data" % seed_ext + chklen = len(words[0]) + + if len(words) < 3 or len(words) > 12: + msg("Invalid data length (%s) in %s" % (len(words),what)) + elif not _is_hex(words[0]): + msg("Invalid format of checksum '%s' in %s"%(words[0], what)) + elif chklen != 6: + msg("Incorrect length of checksum (%s) in %s" % (chklen,what)) + else: valid = True + + if valid == False: + msg("Invalid %s data" % seed_ext) + sys.exit(3) + + +def check_wallet_format(infile, lines, opts): + + def vmsg(s): + if 'verbose' in opts: msg(s) + + what = "wallet file '%s'" % infile + valid = False + chklen = len(lines[0]) + if len(lines) != 6: + vmsg("Invalid number of lines (%s) in %s" % (len(lines),what)) + elif chklen != 6: + vmsg("Incorrect length of Master checksum (%s) in %s" % (chklen,what)) + elif not _is_hex(lines[0]): + vmsg("Invalid format of Master checksum '%s' in %s"%(lines[0], what)) + else: valid = True + + if valid == False: + msg("Invalid %s" % what) + sys.exit(2) + + +def _check_chksum_6(chk,val,desc,infile): + comp_chk = _make_chksum_6(val) + if chk != comp_chk: + msg("%s checksum incorrect in file '%s'!" % (desc,infile)) + msg("Checksum: %s. Computed value: %s" % (chk,comp_chk)) + sys.exit(2) + elif debug: + msg("%s checksum passed: %s" % (desc.capitalize(),chk)) + + +#def bin_pad(bindata,length): +# return unhexlify(hexlify(bindata).zfill(length*2)) + +def get_data_from_wallet(infile,opts): + + msg("Getting {} wallet data from file: {}".format(proj_name,infile)) + + try: + f = open(infile, 'r') + except: + msg("Unable to open file '" + infile + "' for reading") + sys.exit(2) + + lines = [i.strip() for i in f.readlines()] + f.close() + + check_wallet_format(infile, lines, opts) + + label = lines[1] + + metadata = lines[2].split() + + for i in 0,1: metadata[i] = metadata[i].upper() + + hd = lines[3].split() + hash_preset = hd[0][:-1] + hash_params = [int(i) for i in hd[1:]] + + if hash_params != _get_hash_params(hash_preset): + msg("Hash parameters '%s' don't match hash preset '%s'" % + (" ".join(hash_params), hash_preset)) + sys.exit(9) + + res = {} + from mmgen.bitcoin import b58decode_pad + for i,key in (4,"salt"),(5,"enc_seed"): + l = lines[i].split() + val = "".join(l[1:]) + _check_chksum_6(l[0], val, key, infile) + res[key] = b58decode_pad(val) + + _check_chksum_6(lines[0], " ".join(lines[1:]), "Master", infile) + + return label,metadata,hash_preset,res['salt'],res['enc_seed'] + + +def _get_words_from_user(opts, prompt): + # split() also strips + if 'echo_passphrase' in opts: + return _my_raw_input(prompt).split() + else: + return _my_getpass(prompt).split() + + +def _get_words_from_file(infile,what): + msg("Getting %s data from file '%s'" % (what,infile)) + try: + f = open(infile, 'r') + except: + msg("Unable to open file '%s' for reading" % infile) + sys.exit(2) + lines = f.readlines() + f.close() + # split() also strips + return [w for l in lines for w in l.split()] + +def get_words(infile,what,prompt,opts): + if infile: + words = _get_words_from_file(infile,what) + else: + words = _get_words_from_user(opts,prompt) + if debug: print "Sanitized input: [%s]" % " ".join(words) + return words + + +def get_seed_from_seed_data(words): + + check_mmseed_format(words) + + stored_chk = words[0] + seed_b58 = "".join(words[1:]) + + chk = _make_chksum_6(seed_b58) + msg_r("Validating %s checksum..." % seed_ext) + + if compare_checksums(chk, "from seed", stored_chk, "from input"): + from mmgen.bitcoin import b58decode_pad + seed = b58decode_pad(seed_b58) + msg("%s data produces seed ID: %s" % (seed_ext,make_chksum_8(seed))) + return seed + else: + msg("Invalid checksum for {} seed".format(proj_name)) + sys.exit(9) + + +def get_seed_from_wallet(infile,opts, + prompt="Enter {} wallet passphrase: ".format(proj_name)): + + wdata = get_data_from_wallet(infile,opts) + label,metadata,hash_preset,salt,enc_seed = wdata + + if 'verbose' in opts: _display_control_data(*wdata) + + passwd = " ".join(get_words("","",prompt,opts)) + + key = make_key(passwd, salt, hash_preset) + + return decrypt_seed(enc_seed, key, metadata[0], metadata[1]) + + +def make_key(passwd, salt, hash_preset): + + msg_r("Hashing passphrase. Please wait...") + key = _scrypt_hash_passphrase(passwd, salt, hash_preset) + msg("done") + return key + + +def decrypt_seed(enc_seed, key, seed_id, key_id): + + msg_r("Checking key...") + chk = make_chksum_8(key) + if not compare_checksums(chk, "of key", key_id, "in header"): + msg("Passphrase incorrect?") + sys.exit(3) + + msg_r("Decrypting seed with key...") + + from Crypto.Cipher import AES + from Crypto.Util import Counter + + c = AES.new(key, AES.MODE_CTR,counter=Counter.new(128)) + dec_seed = c.decrypt(enc_seed) + + chk = make_chksum_8(dec_seed) + if compare_checksums(chk,"of decrypted seed",seed_id,"in header"): + msg("Passphrase is OK") + else: + if not debug: + msg_r("Checking key ID...") + chk = make_chksum_8(key) + if compare_checksums(chk, "of key", key_id, "in header"): + msg("Key ID is correct but decryption of seed failed") + else: + msg("Incorrect passphrase") + + sys.exit(3) + + if debug: msg("key: %s" % hexlify(key)) + + return dec_seed + + +def get_seed(infile,opts,no_wallet=False): + if 'from_mnemonic' in opts: + prompt = "Enter mnemonic: " + words = get_words(infile,"mnemonic",prompt,opts) + + wl = get_default_wordlist() + from mmgen.mnemonic import get_seed_from_mnemonic + return get_seed_from_mnemonic(words,wl) + elif 'from_brain' in opts: + msg("") + if 'quiet' not in opts: + confirm_or_exit( + cmessages['brain_warning'].format( + proj_name.capitalize(), + *_get_from_brain_opt_params(opts)), + "continue") + prompt = "Enter brainwallet passphrase: " + words = get_words(infile,"brainwallet",prompt,opts) + return _get_seed_from_brain_passphrase(words,opts) + elif 'from_seed' in opts: + prompt = "Enter seed in %s format: " % seed_ext + words = get_words(infile,"seed",prompt,opts) + return get_seed_from_seed_data(words) + elif no_wallet: + return False + else: + return get_seed_from_wallet(infile, opts) diff --git a/mmgen/walletgen.py b/mmgen/walletgen.py new file mode 100755 index 00000000..29a21ae8 --- /dev/null +++ b/mmgen/walletgen.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +walletgen.py: Routines used for seed generation and wallet creation +""" + +import sys +from mmgen.utils import msg, msg_r +from binascii import hexlify + +def get_random_data_from_user(opts): + + ulen = opts['usr_randlen'] + + if 'quiet' in opts: + msg("Enter %s random symbols" % ulen) + else: + msg(""" +We're going to be paranoid and not fully trust your OS's random number +generator. Please type %s symbols on your keyboard. Type slowly and choose +your symbols carefully for maximum randomness. Try to use both upper and +lowercase as well as punctuation and numerals. What you type will not be +displayed on the screen. +""" % ulen) + + prompt = "You may begin typing. %s symbols left: " + msg_r(prompt % ulen) + + import time + # time.clock() always returns zero, so we'll use time.time() + saved_time = time.time() + + user_rand_data,intervals = "",[] + + try: + import os + os.system( + "stty -icanon min 1 time 0 -echo -echoe -echok -echonl -crterase noflsh" + ) + for i in range(ulen): + user_rand_data += sys.stdin.read(1) + msg_r("\r" + prompt % (ulen - i - 1)) + now = time.time() + intervals.append(now - saved_time) + saved_time = now + if 'quiet' in opts: + msg_r("\r") + else: + msg_r("\rThank you. That's enough." + " "*15 + "\n\n") + time.sleep(0.5) + msg_r( + "User random data successfully acquired. Press ENTER to continue: ") + raw_input() + except: + msg("\nUser random input interrupted. Aborting") + sys.exit(1) + finally: + os.system("stty sane") + + return user_rand_data, ["{:.22f}".format(i) for i in intervals] + + +def display_os_random_data(os_rand_data): + print "Rand1: {}\nRand2: {}".format( + *[hexlify(i) for i in os_rand_data]) + + +def display_user_random_data(user_rand_data,intervals_fmt): + msg("\nUser random data: " + user_rand_data) + msg("Keystroke time intervals:") + for i in range(0,len(intervals_fmt),3): + msg(" " + " ".join(intervals_fmt[i:i+3])) diff --git a/setup.py b/setup.py new file mode 100755 index 00000000..1d57f1b4 --- /dev/null +++ b/setup.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +from distutils.core import setup + +setup( + name = 'mmgen', + version = '0.6', + author = 'Philemon', + author_email = 'mmgen-py@yandex.com', + url = 'http://www.python.org/sigs/distutils-sig/', + py_modules = [ + 'mmgen.addr', + 'mmgen.bitcoin', + 'mmgen.config', + 'mmgen.license', + 'mmgen.__init__', + 'mmgen.mn_electrum', + 'mmgen.mnemonic', + 'mmgen.mn_tirosh', + 'mmgen.Opts', + 'mmgen.utils', + 'mmgen.walletgen' + ], + data_files=[('/usr/local/bin', [ + 'mmgen-addrgen', + 'mmgen-keygen', + 'mmgen-passchg', + 'mmgen-walletchk', + 'mmgen-walletgen' + ])] + ) diff --git a/tests/addr.py b/tests/addr.py new file mode 100755 index 00000000..e706cbd1 --- /dev/null +++ b/tests/addr.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +addr.py: Test suite for mmgen.addr module +""" + +from mmgen.addr import * + +tests = "none", + +if (len(sys.argv) == 1): + print "Available tests: %s" % " ".join(tests) diff --git a/tests/bitcoin.py b/tests/bitcoin.py new file mode 100755 index 00000000..5f7c0fb8 --- /dev/null +++ b/tests/bitcoin.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +bitcoin.py: Test suite for mmgen.bitcoin module +""" + +from mmgen.bitcoin import * +from mmgen.utils import msg +from test import * + +import sys + +def b58_randenc(): + r = get_random(24) + r_enc = b58encode(r) + print "Data (hex): %s" % hexlify(r) + print "Base 58: %s" % r_enc + r_dec = b58decode(r_enc) + print "Decoded data: %s" % hexlify(r_dec) + if r_dec != r: + print "ERROR! Decoded data doesn't match original" + sys.exit(9) + +def keyconv_compare_randloop(loops, quiet=False): + try: + for i in range(1,int(loops)+1): + + + wif = numtowif_rand(quiet=True) + + if not quiet: sys.stderr.write("-- %s --\n" % i) + ret = keyconv_compare(wif,quiet) + if ret == False: sys.exit(9) + + if quiet: + sys.stderr.write("\riteration: %i " % i) + + if quiet: + sys.stderr.write("\r%s iterations completed\n" % i) + else: + print "%s iterations completed" % i + + except: + print "\nUser interrupt" + + +def keyconv_compare(wif,quiet=False): + do_msg = nomsg if quiet else msg + do_msg("WIF: %s" % wif) + from subprocess import Popen, PIPE + try: + p = Popen(["keyconv", wif], stdout=PIPE) + except: + print "Error with execution of keyconv" + sys.exit(3) + kc_addr = dict([j.split() for j in p.stdout.readlines()])['Address:'] + addr = privnum2addr(wiftonum(wif)) + do_msg("Address (mmgen): %s" % addr) + do_msg("Address (keyconv): %s" % kc_addr) + if (kc_addr != addr): + print "'keyconv' addr differs from internally-generated addr!" + print "WIF: %s" % wif + print "keyconv: %s" % kc_addr + print "internal: %s" % addr + return False + else: + return True + +def _do_hextowif(hex_in,quiet=False): + do_msg = nomsg if quiet else msg + do_msg("Input: %s" % hex_in) + wif = numtowif(int(hex_in,16)) + do_msg("WIF encoded: %s" % wif) + wif_dec = wiftohex(wif) + do_msg("WIF decoded: %s" % wif_dec) + if hex_in != wif_dec: + print "ERROR! Decoded data doesn't match original data" + sys.exit(9) + return wif + + +def hextowiftopubkey(hex_in,quiet=False): + if len(hex_in) != 64: + print "Input must be a hex number 64 bits in length (%s input)" \ + % len(hex_in) + sys.exit(2) + + wif = _do_hextowif(hex_in,quiet=quiet) + + keyconv_compare(wif) + + +def numtowif_rand(quiet=False): + r_hex = hexlify(get_random(32)) + + return _do_hextowif(r_hex,quiet) + + +def strtob58(s,quiet=False): + print "Input: %s" % s + s_enc = b58encode(s) + print "Encoded data: %s" % s_enc + s_dec = b58decode(s_enc) + print "Decoded data: %s" % s_dec + test_equality(s,s_dec,[""],quiet) + +def hextob58(s_in,f_enc=b58encode, f_dec=b58decode, quiet=False): + do_msg = nomsg if quiet else msg + do_msg("Input: %s" % s_in) + s_bin = unhexlify(s_in) + s_enc = f_enc(s_bin) + do_msg("Encoded data: %s" % s_enc) + s_dec = hexlify(f_dec(s_enc)) + do_msg("Recoded data: %s" % s_dec) + test_equality(s_in,s_dec,["0"],quiet) + +def b58tohex(s_in,f_dec=b58decode, f_enc=b58encode,quiet=False): + print "Input: %s" % s_in + s_dec = f_dec(s_in) + print "Decoded data: %s" % hexlify(s_dec) + s_enc = f_enc(s_dec) + print "Recoded data: %s" % s_enc + test_equality(s_in,s_enc,["1"],quiet) + +def hextob58_pad(s_in, quiet=False): + hextob58(s_in,f_enc=b58encode_pad, f_dec=b58decode_pad, quiet=quiet) + +def b58tohex_pad(s_in, quiet=False): + b58tohex(s_in,f_dec=b58decode_pad, f_enc=b58encode_pad, quiet=quiet) + +def hextob58_pad_randloop(loops, quiet=False): + try: + for i in range(1,int(loops)+1): + r = hexlify(get_random(32)) + hextob58(r,f_enc=b58encode_pad, f_dec=b58decode_pad, quiet=quiet) + if not quiet: print + if not i % 100 and quiet: + sys.stderr.write("\riteration: %i " % i) + + sys.stderr.write("\r%s iterations completed\n" % i) + except: + print "User interrupt" + +def test_wiftohex(s_in,f_dec=wiftohex,f_enc=numtowif): + print "Input: %s" % s_in + s_dec = f_dec(s_in) + print "Decoded data: %s" % s_dec + s_enc = f_enc(int(s_dec,16)) + print "Recoded data: %s" % s_enc + +def hextosha256(s_in): + print "Entered data: %s" % s_in + s_enc = sha256(unhexlify(s_in)).hexdigest() + print "Encoded data: %s" % s_enc + + +tests = { + "keyconv_compare": ['wif [str]','quiet [bool=False]'], + "keyconv_compare_randloop": ['iterations [int]','quiet [bool=False]'], + "b58_randenc": ['quiet [bool=False]'], + "strtob58": ['string [str]','quiet [bool=False]'], + "hextob58": ['hexnum [str]','quiet [bool=False]'], + "b58tohex": ['b58num [str]','quiet [bool=False]'], + "hextob58_pad": ['hexnum [str]','quiet [bool=False]'], + "b58tohex_pad": ['b58num [str]','quiet [bool=False]'], + "hextob58_pad_randloop": ['iterations [int]','quiet [bool=False]'], + "test_wiftohex": ['wif [str]', 'quiet [bool=False]'], + "numtowif_rand": ['quiet [bool=False]'], + "hextosha256": ['hexnum [str]','quiet [bool=False]'], + "hextowiftopubkey": ['hexnum [str]','quiet [bool=False]'], +} + + +args = process_test_args(sys.argv, tests) +eval(sys.argv[1])(*args) diff --git a/tests/mn_electrum.py b/tests/mn_electrum.py new file mode 100755 index 00000000..78b1cac2 --- /dev/null +++ b/tests/mn_electrum.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +mn_electrum.py: Test suite for mmgen.mn_electrum module +""" + +from mmgen.mn_electrum import * + +print electrum_words.strip() diff --git a/tests/mn_tirosh.py b/tests/mn_tirosh.py new file mode 100755 index 00000000..d5f20da4 --- /dev/null +++ b/tests/mn_tirosh.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +mn_tirosh.py: Test suite for mmgen.mn_tirosh module +""" + +from mmgen.mn_tirosh import * + +print tirosh_words.strip() diff --git a/tests/mnemonic.py b/tests/mnemonic.py new file mode 100755 index 00000000..f1b7391d --- /dev/null +++ b/tests/mnemonic.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +mnemonic.py: Test suite for mmgen.mnemonic module +""" + +from mmgen.mnemonic import * +from test import * + +import sys +from binascii import hexlify +from mmgen.mn_electrum import electrum_words as el +from mmgen.mn_tirosh import tirosh_words as tl + +def do_random_tests(n): + r = get_random(n) + em = get_mnemonic_from_seed(r,el.strip().split("\n"), + "electrum",print_info=False) + tm = get_mnemonic_from_seed(r,tl.strip().split("\n"), + "tirosh",print_info=False) + + print "Seed: %s (%s bits)" % (hexlify(r),len(r)*8) + print "Electrum: %s" % " ".join(em) + print "Tirosh: %s" % " ".join(tm) + + +def hextobaseN_test(num_in,base,wl,quiet=False): + do_msg = nomsg if quiet else msg + do_msg("Input: %s" % num_in) + num_enc = "".join(hextobaseN(base,num_in,wl,len(num_in)*2)) + do_msg("Encoded value: %s" % num_enc) + num_dec = baseNtohex(base,num_enc,wl) + do_msg("Decoded value: %s" % num_dec) + test_equality(num_in,num_dec,wl,quiet) + return num_enc,num_dec + + +def baseNtohex_test(num_in,base,wl,quiet=False): + do_msg = nomsg if quiet else msg + do_msg("Input: %s" % num_in) + num_enc = baseNtohex(base,list(num_in),wl) + do_msg("Encoded value: %s" % num_enc) + num_dec = "".join(hextobaseN(base,num_enc,wl,len(num_enc)*2)) + do_msg("Decoded value: %s" % num_dec) + test_equality(num_in,num_dec,wl,quiet) + return num_enc,num_dec + + +def random128(): do_random_tests(16) +def random192(): do_random_tests(24) +def random256(): do_random_tests(32) +def random512(): do_random_tests(64) +def electrum(): check_wordlist(el,"electrum") +def tirosh(): check_wordlist(tl,"tirosh") + +def base10tohex(num,quiet=False): + enc,dec = baseNtohex_test(num,10,"0123456789",quiet) + print "Decimal: %s" % num + print "Hex (encoded): %s" % enc + print "Decimal (recoded): %s" % dec.lstrip("0") + +def hextobase10(num,quiet=False): + enc,dec= hextobaseN_test(num,10,"0123456789",quiet) + print "Hex: %s" % num + print "Decimal (encoded): %s" % enc.lstrip("0") + print "Hex (recoded): %s" % dec + +def base8tohex(num,quiet=False): + enc,dec = baseNtohex_test(num,8,"01234567",quiet) + print "Octal: %s" % num + print "Hex (encoded): %s" % enc + print "Octal (recoded): %s" % "0" + dec.lstrip("0") + +def hextobase8(num,quiet=False): + enc,dec = hextobaseN_test(num,8,"01234567",quiet) + print "Hex: %s" % num + print "Octal: %s" % "0" + enc.lstrip("0") + print "Hex (recoded): %s" % dec + +tests = { + "random128": [], + "random192": [], + "random256": [], + "random512": [], + "electrum": [], + "tirosh": [], + "base10tohex": ['base10num [int]','quiet [bool=False]'], + "hextobase10": ['hexnum [str]', 'quiet [bool=False]'], + "base8tohex": ['base8num [int]', 'quiet [bool=False]'], + "hextobase8": ['hexnum [str]', 'quiet [bool=False]'], +} + +args = process_test_args(sys.argv, tests) +eval(sys.argv[1])(*args) diff --git a/tests/test.py b/tests/test.py new file mode 100755 index 00000000..747b0da5 --- /dev/null +++ b/tests/test.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +test.py: Shared routines for mmgen test suite +""" + +import sys +from mmgen.utils import msg + +def nomsg(s): pass + +def test_equality(num_in,num_out,wl,quiet=False): + + do_msg = nomsg if quiet else msg + + if num_in != num_out: + do_msg("WARNING! Recoded number doesn't match input stringwise!") + do_msg("Input: %s" % num_in) + do_msg("Output: %s" % num_out) + + i = num_in.lstrip(wl[0]) + o = num_out.lstrip(wl[0]) + + if i != o: + print "ERROR! Recoded number doesn't match input numerically!" + sys.exit(9) + + +def get_random(length): + from Crypto import Random + return Random.new().read(length) + +def process_test_args(argv, tests): + if (len(argv) == 1): + print "Usage: %s " % argv[0].split("/")[-1] + ls = "\n " + print "Available tests:%s%s" % (ls,ls.join(sorted(tests.keys()))) + sys.exit(1) + elif argv[1] not in tests: + print "'%s': no such test" % argv[1] + sys.exit(2) + else: + cargs = tests[argv[1]] + uargs = argv[2:] + if len(uargs) > len(cargs): + print "Too many arguments\nUsage: %s(%s)" % \ + (argv[1], ", ".join(cargs)) + sys.exit() + + for i in range(len(cargs)): + try: uarg = uargs[i] + except: uarg = None + + cname,ctype_arg = cargs[i].split() + c = ctype_arg[1:-1].split("=")[0:] + ctype,cdflt = c[0],c[1:] + + if uarg == None and not cdflt: + print "Usage: %s(%s)" % \ + (argv[1], ", ".join(cargs)) + sys.exit() + +# print "%-10s %-7s %s" % (uarg, cargs[i], carg) + + if uarg: + try: eval(ctype + "('" + uarg + "')") + except: + print "'%s' Invalid argument (%s required)" % (uarg, ctype) + sys.exit() + + return uargs diff --git a/tests/utils.py b/tests/utils.py new file mode 100755 index 00000000..6f590199 --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +utils.py: Test suite for mmgen.utils module +""" + +from mmgen.utils import * + +tests = "none", + +if (len(sys.argv) == 1): + print "Available tests: %s" % " ".join(tests) diff --git a/tests/walletgen.py b/tests/walletgen.py new file mode 100755 index 00000000..93345ce5 --- /dev/null +++ b/tests/walletgen.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python +# +# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution +# Copyright (C) 2013 by philemon +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +walletgen.py: Test suite for mmgen.walletgen module +""" + +from mmgen.walletgen import * + +tests = "none", + +if (len(sys.argv) == 1): + print "Available tests: %s" % " ".join(tests) diff --git a/wordlists/mn_wordlist.c b/wordlists/mn_wordlist.c new file mode 100644 index 00000000..cb9106cc --- /dev/null +++ b/wordlists/mn_wordlist.c @@ -0,0 +1,302 @@ +/* mn_wordlist.c + Copyright (c) 2000 Oren Tirosh + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include "mnemonic.h" + +const char *mn_wordlist_version = + " Wordlist ver 0.7"; + +const char *mn_words[MN_WORDS + 1] = { 0, + "academy", "acrobat", "active", "actor", "adam", "admiral", + "adrian", "africa", "agenda", "agent", "airline", "airport", + "aladdin", "alarm", "alaska", "albert", "albino", "album", + "alcohol", "alex", "algebra", "alibi", "alice", "alien", + "alpha", "alpine", "amadeus", "amanda", "amazon", "amber", + "america", "amigo", "analog", "anatomy", "angel", "animal", + "antenna", "antonio", "apollo", "april", "archive", "arctic", + "arizona", "arnold", "aroma", "arthur", "artist", "asia", + "aspect", "aspirin", "athena", "athlete", "atlas", "audio", + "august", "austria", "axiom", "aztec", "balance", "ballad", + "banana", "bandit", "banjo", "barcode", "baron", "basic", + "battery", "belgium", "berlin", "bermuda", "bernard", "bikini", + "binary", "bingo", "biology", "block", "blonde", "bonus", + "boris", "boston", "boxer", "brandy", "bravo", "brazil", + "bronze", "brown", "bruce", "bruno", "burger", "burma", + "cabinet", "cactus", "cafe", "cairo", "cake", "calypso", + "camel", "camera", "campus", "canada", "canal", "cannon", + "canoe", "cantina", "canvas", "canyon", "capital", "caramel", + "caravan", "carbon", "cargo", "carlo", "carol", "carpet", + "cartel", "casino", "castle", "castro", "catalog", "caviar", + "cecilia", "cement", "center", "century", "ceramic", "chamber", + "chance", "change", "chaos", "charlie", "charm", "charter", + "chef", "chemist", "cherry", "chess", "chicago", "chicken", + "chief", "china", "cigar", "cinema", "circus", "citizen", + "city", "clara", "classic", "claudia", "clean", "client", + "climax", "clinic", "clock", "club", "cobra", "coconut", + "cola", "collect", "colombo", "colony", "color", "combat", + "comedy", "comet", "command", "compact", "company", "complex", + "concept", "concert", "connect", "consul", "contact", "context", + "contour", "control", "convert", "copy", "corner", "corona", + "correct", "cosmos", "couple", "courage", "cowboy", "craft", + "crash", "credit", "cricket", "critic", "crown", "crystal", + "cuba", "culture", "dallas", "dance", "daniel", "david", + "decade", "decimal", "deliver", "delta", "deluxe", "demand", + "demo", "denmark", "derby", "design", "detect", "develop", + "diagram", "dialog", "diamond", "diana", "diego", "diesel", + "diet", "digital", "dilemma", "diploma", "direct", "disco", + "disney", "distant", "doctor", "dollar", "dominic", "domino", + "donald", "dragon", "drama", "dublin", "duet", "dynamic", + "east", "ecology", "economy", "edgar", "egypt", "elastic", + "elegant", "element", "elite", "elvis", "email", "energy", + "engine", "english", "episode", "equator", "escort", "ethnic", + "europe", "everest", "evident", "exact", "example", "exit", + "exotic", "export", "express", "extra", "fabric", "factor", + "falcon", "family", "fantasy", "fashion", "fiber", "fiction", + "fidel", "fiesta", "figure", "film", "filter", "final", + "finance", "finish", "finland", "flash", "florida", "flower", + "fluid", "flute", "focus", "ford", "forest", "formal", + "format", "formula", "fortune", "forum", "fragile", "france", + "frank", "friend", "frozen", "future", "gabriel", "galaxy", + "gallery", "gamma", "garage", "garden", "garlic", "gemini", + "general", "genetic", "genius", "germany", "global", "gloria", + "golf", "gondola", "gong", "good", "gordon", "gorilla", + "grand", "granite", "graph", "green", "group", "guide", + "guitar", "guru", "hand", "happy", "harbor", "harmony", + "harvard", "havana", "hawaii", "helena", "hello", "henry", + "hilton", "history", "horizon", "hotel", "human", "humor", + "icon", "idea", "igloo", "igor", "image", "impact", + "import", "index", "india", "indigo", "input", "insect", + "instant", "iris", "italian", "jacket", "jacob", "jaguar", + "janet", "japan", "jargon", "jazz", "jeep", "john", + "joker", "jordan", "jumbo", "june", "jungle", "junior", + "jupiter", "karate", "karma", "kayak", "kermit", "kilo", + "king", "koala", "korea", "labor", "lady", "lagoon", + "laptop", "laser", "latin", "lava", "lecture", "left", + "legal", "lemon", "level", "lexicon", "liberal", "libra", + "limbo", "limit", "linda", "linear", "lion", "liquid", + "liter", "little", "llama", "lobby", "lobster", "local", + "logic", "logo", "lola", "london", "lotus", "lucas", + "lunar", "machine", "macro", "madam", "madonna", "madrid", + "maestro", "magic", "magnet", "magnum", "major", "mama", + "mambo", "manager", "mango", "manila", "marco", "marina", + "market", "mars", "martin", "marvin", "master", "matrix", + "maximum", "media", "medical", "mega", "melody", "melon", + "memo", "mental", "mentor", "menu", "mercury", "message", + "metal", "meteor", "meter", "method", "metro", "mexico", + "miami", "micro", "million", "mineral", "minimum", "minus", + "minute", "miracle", "mirage", "miranda", "mister", "mixer", + "mobile", "model", "modem", "modern", "modular", "moment", + "monaco", "monica", "monitor", "mono", "monster", "montana", + "morgan", "motel", "motif", "motor", "mozart", "multi", + "museum", "music", "mustang", "natural", "neon", "nepal", + "neptune", "nerve", "neutral", "nevada", "news", "ninja", + "nirvana", "normal", "nova", "novel", "nuclear", "numeric", + "nylon", "oasis", "object", "observe", "ocean", "octopus", + "olivia", "olympic", "omega", "opera", "optic", "optimal", + "orange", "orbit", "organic", "orient", "origin", "orlando", + "oscar", "oxford", "oxygen", "ozone", "pablo", "pacific", + "pagoda", "palace", "pamela", "panama", "panda", "panel", + "panic", "paradox", "pardon", "paris", "parker", "parking", + "parody", "partner", "passage", "passive", "pasta", "pastel", + "patent", "patriot", "patrol", "patron", "pegasus", "pelican", + "penguin", "pepper", "percent", "perfect", "perfume", "period", + "permit", "person", "peru", "phone", "photo", "piano", + "picasso", "picnic", "picture", "pigment", "pilgrim", "pilot", + "pirate", "pixel", "pizza", "planet", "plasma", "plaster", + "plastic", "plaza", "pocket", "poem", "poetic", "poker", + "polaris", "police", "politic", "polo", "polygon", "pony", + "popcorn", "popular", "postage", "postal", "precise", "prefix", + "premium", "present", "price", "prince", "printer", "prism", + "private", "product", "profile", "program", "project", "protect", + "proton", "public", "pulse", "puma", "pyramid", "queen", + "radar", "radio", "random", "rapid", "rebel", "record", + "recycle", "reflex", "reform", "regard", "regular", "relax", + "report", "reptile", "reverse", "ricardo", "ringo", "ritual", + "robert", "robot", "rocket", "rodeo", "romeo", "royal", + "russian", "safari", "salad", "salami", "salmon", "salon", + "salute", "samba", "sandra", "santana", "sardine", "school", + "screen", "script", "second", "secret", "section", "segment", + "select", "seminar", "senator", "senior", "sensor", "serial", + "service", "sheriff", "shock", "sierra", "signal", "silicon", + "silver", "similar", "simon", "single", "siren", "slogan", + "social", "soda", "solar", "solid", "solo", "sonic", + "soviet", "special", "speed", "spiral", "spirit", "sport", + "static", "station", "status", "stereo", "stone", "stop", + "street", "strong", "student", "studio", "style", "subject", + "sultan", "super", "susan", "sushi", "suzuki", "switch", + "symbol", "system", "tactic", "tahiti", "talent", "tango", + "tarzan", "taxi", "telex", "tempo", "tennis", "texas", + "textile", "theory", "thermos", "tiger", "titanic", "tokyo", + "tomato", "topic", "tornado", "toronto", "torpedo", "total", + "totem", "tourist", "tractor", "traffic", "transit", "trapeze", + "travel", "tribal", "trick", "trident", "trilogy", "tripod", + "tropic", "trumpet", "tulip", "tuna", "turbo", "twist", + "ultra", "uniform", "union", "uranium", "vacuum", "valid", + "vampire", "vanilla", "vatican", "velvet", "ventura", "venus", + "vertigo", "veteran", "victor", "video", "vienna", "viking", + "village", "vincent", "violet", "violin", "virtual", "virus", + "visa", "vision", "visitor", "visual", "vitamin", "viva", + "vocal", "vodka", "volcano", "voltage", "volume", "voyage", + "water", "weekend", "welcome", "western", "window", "winter", + "wizard", "wolf", "world", "xray", "yankee", "yoga", + "yogurt", "yoyo", "zebra", "zero", "zigzag", "zipper", + "zodiac", "zoom", "abraham", "action", "address", "alabama", + "alfred", "almond", "ammonia", "analyze", "annual", "answer", + "apple", "arena", "armada", "arsenal", "atlanta", "atomic", + "avenue", "average", "bagel", "baker", "ballet", "bambino", + "bamboo", "barbara", "basket", "bazaar", "benefit", "bicycle", + "bishop", "blitz", "bonjour", "bottle", "bridge", "british", + "brother", "brush", "budget", "cabaret", "cadet", "candle", + "capitan", "capsule", "career", "cartoon", "channel", "chapter", + "cheese", "circle", "cobalt", "cockpit", "college", "compass", + "comrade", "condor", "crimson", "cyclone", "darwin", "declare", + "degree", "delete", "delphi", "denver", "desert", "divide", + "dolby", "domain", "domingo", "double", "drink", "driver", + "eagle", "earth", "echo", "eclipse", "editor", "educate", + "edward", "effect", "electra", "emerald", "emotion", "empire", + "empty", "escape", "eternal", "evening", "exhibit", "expand", + "explore", "extreme", "ferrari", "first", "flag", "folio", + "forget", "forward", "freedom", "fresh", "friday", "fuji", + "galileo", "garcia", "genesis", "gold", "gravity", "habitat", + "hamlet", "harlem", "helium", "holiday", "house", "hunter", + "ibiza", "iceberg", "imagine", "infant", "isotope", "jackson", + "jamaica", "jasmine", "java", "jessica", "judo", "kitchen", + "lazarus", "letter", "license", "lithium", "loyal", "lucky", + "magenta", "mailbox", "manual", "marble", "mary", "maxwell", + "mayor", "milk", "monarch", "monday", "money", "morning", + "mother", "mystery", "native", "nectar", "nelson", "network", + "next", "nikita", "nobel", "nobody", "nominal", "norway", + "nothing", "number", "october", "office", "oliver", "opinion", + "option", "order", "outside", "package", "pancake", "pandora", + "panther", "papa", "patient", "pattern", "pedro", "pencil", + "people", "phantom", "philips", "pioneer", "pluto", "podium", + "portal", "potato", "prize", "process", "protein", "proxy", + "pump", "pupil", "python", "quality", "quarter", "quiet", + "rabbit", "radical", "radius", "rainbow", "ralph", "ramirez", + "ravioli", "raymond", "respect", "respond", "result", "resume", + "retro", "richard", "right", "risk", "river", "roger", + "roman", "rondo", "sabrina", "salary", "salsa", "sample", + "samuel", "saturn", "savage", "scarlet", "scoop", "scorpio", + "scratch", "scroll", "sector", "serpent", "shadow", "shampoo", + "sharon", "sharp", "short", "shrink", "silence", "silk", + "simple", "slang", "smart", "smoke", "snake", "society", + "sonar", "sonata", "soprano", "source", "sparta", "sphere", + "spider", "sponsor", "spring", "acid", "adios", "agatha", + "alamo", "alert", "almanac", "aloha", "andrea", "anita", + "arcade", "aurora", "avalon", "baby", "baggage", "balloon", + "bank", "basil", "begin", "biscuit", "blue", "bombay", + "brain", "brenda", "brigade", "cable", "carmen", "cello", + "celtic", "chariot", "chrome", "citrus", "civil", "cloud", + "common", "compare", "cool", "copper", "coral", "crater", + "cubic", "cupid", "cycle", "depend", "door", "dream", + "dynasty", "edison", "edition", "enigma", "equal", "eric", + "event", "evita", "exodus", "extend", "famous", "farmer", + "food", "fossil", "frog", "fruit", "geneva", "gentle", + "george", "giant", "gilbert", "gossip", "gram", "greek", + "grille", "hammer", "harvest", "hazard", "heaven", "herbert", + "heroic", "hexagon", "husband", "immune", "inca", "inch", + "initial", "isabel", "ivory", "jason", "jerome", "joel", + "joshua", "journal", "judge", "juliet", "jump", "justice", + "kimono", "kinetic", "leonid", "lima", "maze", "medusa", + "member", "memphis", "michael", "miguel", "milan", "mile", + "miller", "mimic", "mimosa", "mission", "monkey", "moral", + "moses", "mouse", "nancy", "natasha", "nebula", "nickel", + "nina", "noise", "orchid", "oregano", "origami", "orinoco", + "orion", "othello", "paper", "paprika", "prelude", "prepare", + "pretend", "profit", "promise", "provide", "puzzle", "remote", + "repair", "reply", "rival", "riviera", "robin", "rose", + "rover", "rudolf", "saga", "sahara", "scholar", "shelter", + "ship", "shoe", "sigma", "sister", "sleep", "smile", + "spain", "spark", "split", "spray", "square", "stadium", + "star", "storm", "story", "strange", "stretch", "stuart", + "subway", "sugar", "sulfur", "summer", "survive", "sweet", + "swim", "table", "taboo", "target", "teacher", "telecom", + "temple", "tibet", "ticket", "tina", "today", "toga", + "tommy", "tower", "trivial", "tunnel", "turtle", "twin", + "uncle", "unicorn", "unique", "update", "valery", "vega", + "version", "voodoo", "warning", "william", "wonder", "year", + "yellow", "young", "absent", "absorb", "accent", "alfonso", + "alias", "ambient", "andy", "anvil", "appear", "apropos", + "archer", "ariel", "armor", "arrow", "austin", "avatar", + "axis", "baboon", "bahama", "bali", "balsa", "bazooka", + "beach", "beast", "beatles", "beauty", "before", "benny", + "betty", "between", "beyond", "billy", "bison", "blast", + "bless", "bogart", "bonanza", "book", "border", "brave", + "bread", "break", "broken", "bucket", "buenos", "buffalo", + "bundle", "button", "buzzer", "byte", "caesar", "camilla", + "canary", "candid", "carrot", "cave", "chant", "child", + "choice", "chris", "cipher", "clarion", "clark", "clever", + "cliff", "clone", "conan", "conduct", "congo", "content", + "costume", "cotton", "cover", "crack", "current", "danube", + "data", "decide", "desire", "detail", "dexter", "dinner", + "dispute", "donor", "druid", "drum", "easy", "eddie", + "enjoy", "enrico", "epoxy", "erosion", "except", "exile", + "explain", "fame", "fast", "father", "felix", "field", + "fiona", "fire", "fish", "flame", "flex", "flipper", + "float", "flood", "floor", "forbid", "forever", "fractal", + "frame", "freddie", "front", "fuel", "gallop", "game", + "garbo", "gate", "gibson", "ginger", "giraffe", "gizmo", + "glass", "goblin", "gopher", "grace", "gray", "gregory", + "grid", "griffin", "ground", "guest", "gustav", "gyro", + "hair", "halt", "harris", "heart", "heavy", "herman", + "hippie", "hobby", "honey", "hope", "horse", "hostel", + "hydro", "imitate", "info", "ingrid", "inside", "invent", + "invest", "invite", "iron", "ivan", "james", "jester", + "jimmy", "join", "joseph", "juice", "julius", "july", + "justin", "kansas", "karl", "kevin", "kiwi", "ladder", + "lake", "laura", "learn", "legacy", "legend", "lesson", + "life", "light", "list", "locate", "lopez", "lorenzo", + "love", "lunch", "malta", "mammal", "margo", "marion", + "mask", "match", "mayday", "meaning", "mercy", "middle", + "mike", "mirror", "modest", "morph", "morris", "nadia", + "nato", "navy", "needle", "neuron", "never", "newton", + "nice", "night", "nissan", "nitro", "nixon", "north", + "oberon", "octavia", "ohio", "olga", "open", "opus", + "orca", "oval", "owner", "page", "paint", "palma", + "parade", "parent", "parole", "paul", "peace", "pearl", + "perform", "phoenix", "phrase", "pierre", "pinball", "place", + "plate", "plato", "plume", "pogo", "point", "polite", + "polka", "poncho", "powder", "prague", "press", "presto", + "pretty", "prime", "promo", "quasi", "quest", "quick", + "quiz", "quota", "race", "rachel", "raja", "ranger", + "region", "remark", "rent", "reward", "rhino", "ribbon", + "rider", "road", "rodent", "round", "rubber", "ruby", + "rufus", "sabine", "saddle", "sailor", "saint", "salt", + "satire", "scale", "scuba", "season", "secure", "shake", + "shallow", "shannon", "shave", "shelf", "sherman", "shine", + "shirt", "side", "sinatra", "sincere", "size", "slalom", + "slow", "small", "snow", "sofia", "song", "sound", + "south", "speech", "spell", "spend", "spoon", "stage", + "stamp", "stand", "state", "stella", "stick", "sting", + "stock", "store", "sunday", "sunset", "support", "sweden", + "swing", "tape", "think", "thomas", "tictac", "time", + "toast", "tobacco", "tonight", "torch", "torso", "touch", + "toyota", "trade", "tribune", "trinity", "triton", "truck", + "trust", "type", "under", "unit", "urban", "urgent", + "user", "value", "vendor", "venice", "verona", "vibrate", + "virgo", "visible", "vista", "vital", "voice", "vortex", + "waiter", "watch", "wave", "weather", "wedding", "wheel", + "whiskey", "wisdom", "deal", "null", "nurse", "quebec", + "reserve", "reunion", "roof", "singer", "verbal", "amen", + "ego", "fax", "jet", "job", "rio", "ski", + "yes" +}; diff --git a/wordlists/mn_wordlist.py b/wordlists/mn_wordlist.py new file mode 100755 index 00000000..2f3d8100 --- /dev/null +++ b/wordlists/mn_wordlist.py @@ -0,0 +1,292 @@ +#!/usr/bin/python + +""" +mn_words.py: Mnemomic wordlist + +Copyright (c) 2000 Oren Tirosh + +Oren Tirosh is no longer maintaining the original version of this +project. + +Stephen Paul Weber likes it and is making it accessible on GitHub. +https://github.com/singpolyma/mnemonicode +""" + +mn_words = [ + "academy", "acrobat", "active", "actor", "adam", "admiral", + "adrian", "africa", "agenda", "agent", "airline", "airport", + "aladdin", "alarm", "alaska", "albert", "albino", "album", + "alcohol", "alex", "algebra", "alibi", "alice", "alien", + "alpha", "alpine", "amadeus", "amanda", "amazon", "amber", + "america", "amigo", "analog", "anatomy", "angel", "animal", + "antenna", "antonio", "apollo", "april", "archive", "arctic", + "arizona", "arnold", "aroma", "arthur", "artist", "asia", + "aspect", "aspirin", "athena", "athlete", "atlas", "audio", + "august", "austria", "axiom", "aztec", "balance", "ballad", + "banana", "bandit", "banjo", "barcode", "baron", "basic", + "battery", "belgium", "berlin", "bermuda", "bernard", "bikini", + "binary", "bingo", "biology", "block", "blonde", "bonus", + "boris", "boston", "boxer", "brandy", "bravo", "brazil", + "bronze", "brown", "bruce", "bruno", "burger", "burma", + "cabinet", "cactus", "cafe", "cairo", "cake", "calypso", + "camel", "camera", "campus", "canada", "canal", "cannon", + "canoe", "cantina", "canvas", "canyon", "capital", "caramel", + "caravan", "carbon", "cargo", "carlo", "carol", "carpet", + "cartel", "casino", "castle", "castro", "catalog", "caviar", + "cecilia", "cement", "center", "century", "ceramic", "chamber", + "chance", "change", "chaos", "charlie", "charm", "charter", + "chef", "chemist", "cherry", "chess", "chicago", "chicken", + "chief", "china", "cigar", "cinema", "circus", "citizen", + "city", "clara", "classic", "claudia", "clean", "client", + "climax", "clinic", "clock", "club", "cobra", "coconut", + "cola", "collect", "colombo", "colony", "color", "combat", + "comedy", "comet", "command", "compact", "company", "complex", + "concept", "concert", "connect", "consul", "contact", "context", + "contour", "control", "convert", "copy", "corner", "corona", + "correct", "cosmos", "couple", "courage", "cowboy", "craft", + "crash", "credit", "cricket", "critic", "crown", "crystal", + "cuba", "culture", "dallas", "dance", "daniel", "david", + "decade", "decimal", "deliver", "delta", "deluxe", "demand", + "demo", "denmark", "derby", "design", "detect", "develop", + "diagram", "dialog", "diamond", "diana", "diego", "diesel", + "diet", "digital", "dilemma", "diploma", "direct", "disco", + "disney", "distant", "doctor", "dollar", "dominic", "domino", + "donald", "dragon", "drama", "dublin", "duet", "dynamic", + "east", "ecology", "economy", "edgar", "egypt", "elastic", + "elegant", "element", "elite", "elvis", "email", "energy", + "engine", "english", "episode", "equator", "escort", "ethnic", + "europe", "everest", "evident", "exact", "example", "exit", + "exotic", "export", "express", "extra", "fabric", "factor", + "falcon", "family", "fantasy", "fashion", "fiber", "fiction", + "fidel", "fiesta", "figure", "film", "filter", "final", + "finance", "finish", "finland", "flash", "florida", "flower", + "fluid", "flute", "focus", "ford", "forest", "formal", + "format", "formula", "fortune", "forum", "fragile", "france", + "frank", "friend", "frozen", "future", "gabriel", "galaxy", + "gallery", "gamma", "garage", "garden", "garlic", "gemini", + "general", "genetic", "genius", "germany", "global", "gloria", + "golf", "gondola", "gong", "good", "gordon", "gorilla", + "grand", "granite", "graph", "green", "group", "guide", + "guitar", "guru", "hand", "happy", "harbor", "harmony", + "harvard", "havana", "hawaii", "helena", "hello", "henry", + "hilton", "history", "horizon", "hotel", "human", "humor", + "icon", "idea", "igloo", "igor", "image", "impact", + "import", "index", "india", "indigo", "input", "insect", + "instant", "iris", "italian", "jacket", "jacob", "jaguar", + "janet", "japan", "jargon", "jazz", "jeep", "john", + "joker", "jordan", "jumbo", "june", "jungle", "junior", + "jupiter", "karate", "karma", "kayak", "kermit", "kilo", + "king", "koala", "korea", "labor", "lady", "lagoon", + "laptop", "laser", "latin", "lava", "lecture", "left", + "legal", "lemon", "level", "lexicon", "liberal", "libra", + "limbo", "limit", "linda", "linear", "lion", "liquid", + "liter", "little", "llama", "lobby", "lobster", "local", + "logic", "logo", "lola", "london", "lotus", "lucas", + "lunar", "machine", "macro", "madam", "madonna", "madrid", + "maestro", "magic", "magnet", "magnum", "major", "mama", + "mambo", "manager", "mango", "manila", "marco", "marina", + "market", "mars", "martin", "marvin", "master", "matrix", + "maximum", "media", "medical", "mega", "melody", "melon", + "memo", "mental", "mentor", "menu", "mercury", "message", + "metal", "meteor", "meter", "method", "metro", "mexico", + "miami", "micro", "million", "mineral", "minimum", "minus", + "minute", "miracle", "mirage", "miranda", "mister", "mixer", + "mobile", "model", "modem", "modern", "modular", "moment", + "monaco", "monica", "monitor", "mono", "monster", "montana", + "morgan", "motel", "motif", "motor", "mozart", "multi", + "museum", "music", "mustang", "natural", "neon", "nepal", + "neptune", "nerve", "neutral", "nevada", "news", "ninja", + "nirvana", "normal", "nova", "novel", "nuclear", "numeric", + "nylon", "oasis", "object", "observe", "ocean", "octopus", + "olivia", "olympic", "omega", "opera", "optic", "optimal", + "orange", "orbit", "organic", "orient", "origin", "orlando", + "oscar", "oxford", "oxygen", "ozone", "pablo", "pacific", + "pagoda", "palace", "pamela", "panama", "panda", "panel", + "panic", "paradox", "pardon", "paris", "parker", "parking", + "parody", "partner", "passage", "passive", "pasta", "pastel", + "patent", "patriot", "patrol", "patron", "pegasus", "pelican", + "penguin", "pepper", "percent", "perfect", "perfume", "period", + "permit", "person", "peru", "phone", "photo", "piano", + "picasso", "picnic", "picture", "pigment", "pilgrim", "pilot", + "pirate", "pixel", "pizza", "planet", "plasma", "plaster", + "plastic", "plaza", "pocket", "poem", "poetic", "poker", + "polaris", "police", "politic", "polo", "polygon", "pony", + "popcorn", "popular", "postage", "postal", "precise", "prefix", + "premium", "present", "price", "prince", "printer", "prism", + "private", "product", "profile", "program", "project", "protect", + "proton", "public", "pulse", "puma", "pyramid", "queen", + "radar", "radio", "random", "rapid", "rebel", "record", + "recycle", "reflex", "reform", "regard", "regular", "relax", + "report", "reptile", "reverse", "ricardo", "ringo", "ritual", + "robert", "robot", "rocket", "rodeo", "romeo", "royal", + "russian", "safari", "salad", "salami", "salmon", "salon", + "salute", "samba", "sandra", "santana", "sardine", "school", + "screen", "script", "second", "secret", "section", "segment", + "select", "seminar", "senator", "senior", "sensor", "serial", + "service", "sheriff", "shock", "sierra", "signal", "silicon", + "silver", "similar", "simon", "single", "siren", "slogan", + "social", "soda", "solar", "solid", "solo", "sonic", + "soviet", "special", "speed", "spiral", "spirit", "sport", + "static", "station", "status", "stereo", "stone", "stop", + "street", "strong", "student", "studio", "style", "subject", + "sultan", "super", "susan", "sushi", "suzuki", "switch", + "symbol", "system", "tactic", "tahiti", "talent", "tango", + "tarzan", "taxi", "telex", "tempo", "tennis", "texas", + "textile", "theory", "thermos", "tiger", "titanic", "tokyo", + "tomato", "topic", "tornado", "toronto", "torpedo", "total", + "totem", "tourist", "tractor", "traffic", "transit", "trapeze", + "travel", "tribal", "trick", "trident", "trilogy", "tripod", + "tropic", "trumpet", "tulip", "tuna", "turbo", "twist", + "ultra", "uniform", "union", "uranium", "vacuum", "valid", + "vampire", "vanilla", "vatican", "velvet", "ventura", "venus", + "vertigo", "veteran", "victor", "video", "vienna", "viking", + "village", "vincent", "violet", "violin", "virtual", "virus", + "visa", "vision", "visitor", "visual", "vitamin", "viva", + "vocal", "vodka", "volcano", "voltage", "volume", "voyage", + "water", "weekend", "welcome", "western", "window", "winter", + "wizard", "wolf", "world", "xray", "yankee", "yoga", + "yogurt", "yoyo", "zebra", "zero", "zigzag", "zipper", + "zodiac", "zoom", "abraham", "action", "address", "alabama", + "alfred", "almond", "ammonia", "analyze", "annual", "answer", + "apple", "arena", "armada", "arsenal", "atlanta", "atomic", + "avenue", "average", "bagel", "baker", "ballet", "bambino", + "bamboo", "barbara", "basket", "bazaar", "benefit", "bicycle", + "bishop", "blitz", "bonjour", "bottle", "bridge", "british", + "brother", "brush", "budget", "cabaret", "cadet", "candle", + "capitan", "capsule", "career", "cartoon", "channel", "chapter", + "cheese", "circle", "cobalt", "cockpit", "college", "compass", + "comrade", "condor", "crimson", "cyclone", "darwin", "declare", + "degree", "delete", "delphi", "denver", "desert", "divide", + "dolby", "domain", "domingo", "double", "drink", "driver", + "eagle", "earth", "echo", "eclipse", "editor", "educate", + "edward", "effect", "electra", "emerald", "emotion", "empire", + "empty", "escape", "eternal", "evening", "exhibit", "expand", + "explore", "extreme", "ferrari", "first", "flag", "folio", + "forget", "forward", "freedom", "fresh", "friday", "fuji", + "galileo", "garcia", "genesis", "gold", "gravity", "habitat", + "hamlet", "harlem", "helium", "holiday", "house", "hunter", + "ibiza", "iceberg", "imagine", "infant", "isotope", "jackson", + "jamaica", "jasmine", "java", "jessica", "judo", "kitchen", + "lazarus", "letter", "license", "lithium", "loyal", "lucky", + "magenta", "mailbox", "manual", "marble", "mary", "maxwell", + "mayor", "milk", "monarch", "monday", "money", "morning", + "mother", "mystery", "native", "nectar", "nelson", "network", + "next", "nikita", "nobel", "nobody", "nominal", "norway", + "nothing", "number", "october", "office", "oliver", "opinion", + "option", "order", "outside", "package", "pancake", "pandora", + "panther", "papa", "patient", "pattern", "pedro", "pencil", + "people", "phantom", "philips", "pioneer", "pluto", "podium", + "portal", "potato", "prize", "process", "protein", "proxy", + "pump", "pupil", "python", "quality", "quarter", "quiet", + "rabbit", "radical", "radius", "rainbow", "ralph", "ramirez", + "ravioli", "raymond", "respect", "respond", "result", "resume", + "retro", "richard", "right", "risk", "river", "roger", + "roman", "rondo", "sabrina", "salary", "salsa", "sample", + "samuel", "saturn", "savage", "scarlet", "scoop", "scorpio", + "scratch", "scroll", "sector", "serpent", "shadow", "shampoo", + "sharon", "sharp", "short", "shrink", "silence", "silk", + "simple", "slang", "smart", "smoke", "snake", "society", + "sonar", "sonata", "soprano", "source", "sparta", "sphere", + "spider", "sponsor", "spring", "acid", "adios", "agatha", + "alamo", "alert", "almanac", "aloha", "andrea", "anita", + "arcade", "aurora", "avalon", "baby", "baggage", "balloon", + "bank", "basil", "begin", "biscuit", "blue", "bombay", + "brain", "brenda", "brigade", "cable", "carmen", "cello", + "celtic", "chariot", "chrome", "citrus", "civil", "cloud", + "common", "compare", "cool", "copper", "coral", "crater", + "cubic", "cupid", "cycle", "depend", "door", "dream", + "dynasty", "edison", "edition", "enigma", "equal", "eric", + "event", "evita", "exodus", "extend", "famous", "farmer", + "food", "fossil", "frog", "fruit", "geneva", "gentle", + "george", "giant", "gilbert", "gossip", "gram", "greek", + "grille", "hammer", "harvest", "hazard", "heaven", "herbert", + "heroic", "hexagon", "husband", "immune", "inca", "inch", + "initial", "isabel", "ivory", "jason", "jerome", "joel", + "joshua", "journal", "judge", "juliet", "jump", "justice", + "kimono", "kinetic", "leonid", "lima", "maze", "medusa", + "member", "memphis", "michael", "miguel", "milan", "mile", + "miller", "mimic", "mimosa", "mission", "monkey", "moral", + "moses", "mouse", "nancy", "natasha", "nebula", "nickel", + "nina", "noise", "orchid", "oregano", "origami", "orinoco", + "orion", "othello", "paper", "paprika", "prelude", "prepare", + "pretend", "profit", "promise", "provide", "puzzle", "remote", + "repair", "reply", "rival", "riviera", "robin", "rose", + "rover", "rudolf", "saga", "sahara", "scholar", "shelter", + "ship", "shoe", "sigma", "sister", "sleep", "smile", + "spain", "spark", "split", "spray", "square", "stadium", + "star", "storm", "story", "strange", "stretch", "stuart", + "subway", "sugar", "sulfur", "summer", "survive", "sweet", + "swim", "table", "taboo", "target", "teacher", "telecom", + "temple", "tibet", "ticket", "tina", "today", "toga", + "tommy", "tower", "trivial", "tunnel", "turtle", "twin", + "uncle", "unicorn", "unique", "update", "valery", "vega", + "version", "voodoo", "warning", "william", "wonder", "year", + "yellow", "young", "absent", "absorb", "accent", "alfonso", + "alias", "ambient", "andy", "anvil", "appear", "apropos", + "archer", "ariel", "armor", "arrow", "austin", "avatar", + "axis", "baboon", "bahama", "bali", "balsa", "bazooka", + "beach", "beast", "beatles", "beauty", "before", "benny", + "betty", "between", "beyond", "billy", "bison", "blast", + "bless", "bogart", "bonanza", "book", "border", "brave", + "bread", "break", "broken", "bucket", "buenos", "buffalo", + "bundle", "button", "buzzer", "byte", "caesar", "camilla", + "canary", "candid", "carrot", "cave", "chant", "child", + "choice", "chris", "cipher", "clarion", "clark", "clever", + "cliff", "clone", "conan", "conduct", "congo", "content", + "costume", "cotton", "cover", "crack", "current", "danube", + "data", "decide", "desire", "detail", "dexter", "dinner", + "dispute", "donor", "druid", "drum", "easy", "eddie", + "enjoy", "enrico", "epoxy", "erosion", "except", "exile", + "explain", "fame", "fast", "father", "felix", "field", + "fiona", "fire", "fish", "flame", "flex", "flipper", + "float", "flood", "floor", "forbid", "forever", "fractal", + "frame", "freddie", "front", "fuel", "gallop", "game", + "garbo", "gate", "gibson", "ginger", "giraffe", "gizmo", + "glass", "goblin", "gopher", "grace", "gray", "gregory", + "grid", "griffin", "ground", "guest", "gustav", "gyro", + "hair", "halt", "harris", "heart", "heavy", "herman", + "hippie", "hobby", "honey", "hope", "horse", "hostel", + "hydro", "imitate", "info", "ingrid", "inside", "invent", + "invest", "invite", "iron", "ivan", "james", "jester", + "jimmy", "join", "joseph", "juice", "julius", "july", + "justin", "kansas", "karl", "kevin", "kiwi", "ladder", + "lake", "laura", "learn", "legacy", "legend", "lesson", + "life", "light", "list", "locate", "lopez", "lorenzo", + "love", "lunch", "malta", "mammal", "margo", "marion", + "mask", "match", "mayday", "meaning", "mercy", "middle", + "mike", "mirror", "modest", "morph", "morris", "nadia", + "nato", "navy", "needle", "neuron", "never", "newton", + "nice", "night", "nissan", "nitro", "nixon", "north", + "oberon", "octavia", "ohio", "olga", "open", "opus", + "orca", "oval", "owner", "page", "paint", "palma", + "parade", "parent", "parole", "paul", "peace", "pearl", + "perform", "phoenix", "phrase", "pierre", "pinball", "place", + "plate", "plato", "plume", "pogo", "point", "polite", + "polka", "poncho", "powder", "prague", "press", "presto", + "pretty", "prime", "promo", "quasi", "quest", "quick", + "quiz", "quota", "race", "rachel", "raja", "ranger", + "region", "remark", "rent", "reward", "rhino", "ribbon", + "rider", "road", "rodent", "round", "rubber", "ruby", + "rufus", "sabine", "saddle", "sailor", "saint", "salt", + "satire", "scale", "scuba", "season", "secure", "shake", + "shallow", "shannon", "shave", "shelf", "sherman", "shine", + "shirt", "side", "sinatra", "sincere", "size", "slalom", + "slow", "small", "snow", "sofia", "song", "sound", + "south", "speech", "spell", "spend", "spoon", "stage", + "stamp", "stand", "state", "stella", "stick", "sting", + "stock", "store", "sunday", "sunset", "support", "sweden", + "swing", "tape", "think", "thomas", "tictac", "time", + "toast", "tobacco", "tonight", "torch", "torso", "touch", + "toyota", "trade", "tribune", "trinity", "triton", "truck", + "trust", "type", "under", "unit", "urban", "urgent", + "user", "value", "vendor", "venice", "verona", "vibrate", + "virgo", "visible", "vista", "vital", "voice", "vortex", + "waiter", "watch", "wave", "weather", "wedding", "wheel", + "whiskey", "wisdom", "deal", "null", "nurse", "quebec", + "reserve", "reunion", "roof", "singer", "verbal", "amen", + "ego", "fax", "jet", "job", "rio", "ski", + "yes" +] + +if __name__ == "__main__": + print "\n".join(mn_words) diff --git a/wordlists/mn_wordlist.sort.py b/wordlists/mn_wordlist.sort.py new file mode 100644 index 00000000..2ca3eae4 --- /dev/null +++ b/wordlists/mn_wordlist.sort.py @@ -0,0 +1,1642 @@ +#!/usr/bin/python + +# Oren Tirosh wordlist +# Copyright (c) 2000 Oren Tirosh + +# This is a sorted version of the wordlist + +oren_tirosh_wordlist = """ +abraham +absent +absorb +academy +accent +acid +acrobat +action +active +actor +adam +address +adios +admiral +adrian +africa +agatha +agenda +agent +airline +airport +alabama +aladdin +alamo +alarm +alaska +albert +albino +album +alcohol +alert +alex +alfonso +alfred +algebra +alias +alibi +alice +alien +almanac +almond +aloha +alpha +alpine +amadeus +amanda +amazon +amber +ambient +amen +america +amigo +ammonia +analog +analyze +anatomy +andrea +andy +angel +animal +anita +annual +answer +antenna +antonio +anvil +apollo +appear +apple +april +apropos +arcade +archer +archive +arctic +arena +ariel +arizona +armada +armor +arnold +aroma +arrow +arsenal +arthur +artist +asia +aspect +aspirin +athena +athlete +atlanta +atlas +atomic +audio +august +aurora +austin +austria +avalon +avatar +avenue +average +axiom +axis +aztec +baboon +baby +bagel +baggage +bahama +baker +balance +bali +ballad +ballet +balloon +balsa +bambino +bamboo +banana +bandit +banjo +bank +barbara +barcode +baron +basic +basil +basket +battery +bazaar +bazooka +beach +beast +beatles +beauty +before +begin +belgium +benefit +benny +berlin +bermuda +bernard +betty +between +beyond +bicycle +bikini +billy +binary +bingo +biology +biscuit +bishop +bison +blast +bless +blitz +block +blonde +blue +bogart +bombay +bonanza +bonjour +bonus +book +border +boris +boston +bottle +boxer +brain +brandy +brave +bravo +brazil +bread +break +brenda +bridge +brigade +british +broken +bronze +brother +brown +bruce +bruno +brush +bucket +budget +buenos +buffalo +bundle +burger +burma +button +buzzer +byte +cabaret +cabinet +cable +cactus +cadet +caesar +cafe +cairo +cake +calypso +camel +camera +camilla +campus +canada +canal +canary +candid +candle +cannon +canoe +cantina +canvas +canyon +capital +capitan +capsule +caramel +caravan +carbon +career +cargo +carlo +carmen +carol +carpet +carrot +cartel +cartoon +casino +castle +castro +catalog +cave +caviar +cecilia +cello +celtic +cement +center +century +ceramic +chamber +chance +change +channel +chant +chaos +chapter +chariot +charlie +charm +charter +cheese +chef +chemist +cherry +chess +chicago +chicken +chief +child +china +choice +chris +chrome +cigar +cinema +cipher +circle +circus +citizen +citrus +city +civil +clara +clarion +clark +classic +claudia +clean +clever +client +cliff +climax +clinic +clock +clone +cloud +club +cobalt +cobra +cockpit +coconut +cola +collect +college +colombo +colony +color +combat +comedy +comet +command +common +compact +company +compare +compass +complex +comrade +conan +concept +concert +condor +conduct +congo +connect +consul +contact +content +context +contour +control +convert +cool +copper +copy +coral +corner +corona +correct +cosmos +costume +cotton +couple +courage +cover +cowboy +crack +craft +crash +crater +credit +cricket +crimson +critic +crown +crystal +cuba +cubic +culture +cupid +current +cycle +cyclone +dallas +dance +daniel +danube +darwin +data +david +deal +decade +decide +decimal +declare +degree +delete +deliver +delphi +delta +deluxe +demand +demo +denmark +denver +depend +derby +desert +design +desire +detail +detect +develop +dexter +diagram +dialog +diamond +diana +diego +diesel +diet +digital +dilemma +dinner +diploma +direct +disco +disney +dispute +distant +divide +doctor +dolby +dollar +domain +domingo +dominic +domino +donald +donor +door +double +dragon +drama +dream +drink +driver +druid +drum +dublin +duet +dynamic +dynasty +eagle +earth +east +easy +echo +eclipse +ecology +economy +eddie +edgar +edison +edition +editor +educate +edward +effect +ego +egypt +elastic +electra +elegant +element +elite +elvis +email +emerald +emotion +empire +empty +energy +engine +english +enigma +enjoy +enrico +episode +epoxy +equal +equator +eric +erosion +escape +escort +eternal +ethnic +europe +evening +event +everest +evident +evita +exact +example +except +exhibit +exile +exit +exodus +exotic +expand +explain +explore +export +express +extend +extra +extreme +fabric +factor +falcon +fame +family +famous +fantasy +farmer +fashion +fast +father +fax +felix +ferrari +fiber +fiction +fidel +field +fiesta +figure +film +filter +final +finance +finish +finland +fiona +fire +first +fish +flag +flame +flash +flex +flipper +float +flood +floor +florida +flower +fluid +flute +focus +folio +food +forbid +ford +forest +forever +forget +formal +format +formula +fortune +forum +forward +fossil +fractal +fragile +frame +france +frank +freddie +freedom +fresh +friday +friend +frog +front +frozen +fruit +fuel +fuji +future +gabriel +galaxy +galileo +gallery +gallop +game +gamma +garage +garbo +garcia +garden +garlic +gate +gemini +general +genesis +genetic +geneva +genius +gentle +george +germany +giant +gibson +gilbert +ginger +giraffe +gizmo +glass +global +gloria +goblin +gold +golf +gondola +gong +good +gopher +gordon +gorilla +gossip +grace +gram +grand +granite +graph +gravity +gray +greek +green +gregory +grid +griffin +grille +ground +group +guest +guide +guitar +guru +gustav +gyro +habitat +hair +halt +hamlet +hammer +hand +happy +harbor +harlem +harmony +harris +harvard +harvest +havana +hawaii +hazard +heart +heaven +heavy +helena +helium +hello +henry +herbert +herman +heroic +hexagon +hilton +hippie +history +hobby +holiday +honey +hope +horizon +horse +hostel +hotel +house +human +humor +hunter +husband +hydro +ibiza +iceberg +icon +idea +igloo +igor +image +imagine +imitate +immune +impact +import +inca +inch +index +india +indigo +infant +info +ingrid +initial +input +insect +inside +instant +invent +invest +invite +iris +iron +isabel +isotope +italian +ivan +ivory +jacket +jackson +jacob +jaguar +jamaica +james +janet +japan +jargon +jasmine +jason +java +jazz +jeep +jerome +jessica +jester +jet +jimmy +job +joel +john +join +joker +jordan +joseph +joshua +journal +judge +judo +juice +juliet +julius +july +jumbo +jump +june +jungle +junior +jupiter +justice +justin +kansas +karate +karl +karma +kayak +kermit +kevin +kilo +kimono +kinetic +king +kitchen +kiwi +koala +korea +labor +ladder +lady +lagoon +lake +laptop +laser +latin +laura +lava +lazarus +learn +lecture +left +legacy +legal +legend +lemon +leonid +lesson +letter +level +lexicon +liberal +libra +license +life +light +lima +limbo +limit +linda +linear +lion +liquid +list +liter +lithium +little +llama +lobby +lobster +local +locate +logic +logo +lola +london +lopez +lorenzo +lotus +love +loyal +lucas +lucky +lunar +lunch +machine +macro +madam +madonna +madrid +maestro +magenta +magic +magnet +magnum +mailbox +major +malta +mama +mambo +mammal +manager +mango +manila +manual +marble +marco +margo +marina +marion +market +mars +martin +marvin +mary +mask +master +match +matrix +maximum +maxwell +mayday +mayor +maze +meaning +media +medical +medusa +mega +melody +melon +member +memo +memphis +mental +mentor +menu +mercury +mercy +message +metal +meteor +meter +method +metro +mexico +miami +michael +micro +middle +miguel +mike +milan +mile +milk +miller +million +mimic +mimosa +mineral +minimum +minus +minute +miracle +mirage +miranda +mirror +mission +mister +mixer +mobile +model +modem +modern +modest +modular +moment +monaco +monarch +monday +money +monica +monitor +monkey +mono +monster +montana +moral +morgan +morning +morph +morris +moses +motel +mother +motif +motor +mouse +mozart +multi +museum +music +mustang +mystery +nadia +nancy +natasha +native +nato +natural +navy +nebula +nectar +needle +nelson +neon +nepal +neptune +nerve +network +neuron +neutral +nevada +never +news +newton +next +nice +nickel +night +nikita +nina +ninja +nirvana +nissan +nitro +nixon +nobel +nobody +noise +nominal +normal +north +norway +nothing +nova +novel +nuclear +null +number +numeric +nurse +nylon +oasis +oberon +object +observe +ocean +octavia +october +octopus +office +ohio +olga +oliver +olivia +olympic +omega +open +opera +opinion +optic +optimal +option +opus +orange +orbit +orca +orchid +order +oregano +organic +orient +origami +origin +orinoco +orion +orlando +oscar +othello +outside +oval +owner +oxford +oxygen +ozone +pablo +pacific +package +page +pagoda +paint +palace +palma +pamela +panama +pancake +panda +pandora +panel +panic +panther +papa +paper +paprika +parade +paradox +pardon +parent +paris +parker +parking +parody +parole +partner +passage +passive +pasta +pastel +patent +patient +patriot +patrol +patron +pattern +paul +peace +pearl +pedro +pegasus +pelican +pencil +penguin +people +pepper +percent +perfect +perform +perfume +period +permit +person +peru +phantom +philips +phoenix +phone +photo +phrase +piano +picasso +picnic +picture +pierre +pigment +pilgrim +pilot +pinball +pioneer +pirate +pixel +pizza +place +planet +plasma +plaster +plastic +plate +plato +plaza +plume +pluto +pocket +podium +poem +poetic +pogo +point +poker +polaris +police +polite +politic +polka +polo +polygon +poncho +pony +popcorn +popular +portal +postage +postal +potato +powder +prague +precise +prefix +prelude +premium +prepare +present +press +presto +pretend +pretty +price +prime +prince +printer +prism +private +prize +process +product +profile +profit +program +project +promise +promo +protect +protein +proton +provide +proxy +public +pulse +puma +pump +pupil +puzzle +pyramid +python +quality +quarter +quasi +quebec +queen +quest +quick +quiet +quiz +quota +rabbit +race +rachel +radar +radical +radio +radius +rainbow +raja +ralph +ramirez +random +ranger +rapid +ravioli +raymond +rebel +record +recycle +reflex +reform +regard +region +regular +relax +remark +remote +rent +repair +reply +report +reptile +reserve +respect +respond +result +resume +retro +reunion +reverse +reward +rhino +ribbon +ricardo +richard +rider +right +ringo +rio +risk +ritual +rival +river +riviera +road +robert +robin +robot +rocket +rodent +rodeo +roger +roman +romeo +rondo +roof +rose +round +rover +royal +rubber +ruby +rudolf +rufus +russian +sabine +sabrina +saddle +safari +saga +sahara +sailor +saint +salad +salami +salary +salmon +salon +salsa +salt +salute +samba +sample +samuel +sandra +santana +sardine +satire +saturn +savage +scale +scarlet +scholar +school +scoop +scorpio +scratch +screen +script +scroll +scuba +season +second +secret +section +sector +secure +segment +select +seminar +senator +senior +sensor +serial +serpent +service +shadow +shake +shallow +shampoo +shannon +sharon +sharp +shave +shelf +shelter +sheriff +sherman +shine +ship +shirt +shock +shoe +short +shrink +side +sierra +sigma +signal +silence +silicon +silk +silver +similar +simon +simple +sinatra +sincere +singer +single +siren +sister +size +ski +slalom +slang +sleep +slogan +slow +small +smart +smile +smoke +snake +snow +social +society +soda +sofia +solar +solid +solo +sonar +sonata +song +sonic +soprano +sound +source +south +soviet +spain +spark +sparta +special +speech +speed +spell +spend +sphere +spider +spiral +spirit +split +sponsor +spoon +sport +spray +spring +square +stadium +stage +stamp +stand +star +state +static +station +status +stella +stereo +stick +sting +stock +stone +stop +store +storm +story +strange +street +stretch +strong +stuart +student +studio +style +subject +subway +sugar +sulfur +sultan +summer +sunday +sunset +super +support +survive +susan +sushi +suzuki +sweden +sweet +swim +swing +switch +symbol +system +table +taboo +tactic +tahiti +talent +tango +tape +target +tarzan +taxi +teacher +telecom +telex +temple +tempo +tennis +texas +textile +theory +thermos +think +thomas +tibet +ticket +tictac +tiger +time +tina +titanic +toast +tobacco +today +toga +tokyo +tomato +tommy +tonight +topic +torch +tornado +toronto +torpedo +torso +total +totem +touch +tourist +tower +toyota +tractor +trade +traffic +transit +trapeze +travel +tribal +tribune +trick +trident +trilogy +trinity +tripod +triton +trivial +tropic +truck +trumpet +trust +tulip +tuna +tunnel +turbo +turtle +twin +twist +type +ultra +uncle +under +unicorn +uniform +union +unique +unit +update +uranium +urban +urgent +user +vacuum +valery +valid +value +vampire +vanilla +vatican +vega +velvet +vendor +venice +ventura +venus +verbal +verona +version +vertigo +veteran +vibrate +victor +video +vienna +viking +village +vincent +violet +violin +virgo +virtual +virus +visa +visible +vision +visitor +vista +visual +vital +vitamin +viva +vocal +vodka +voice +volcano +voltage +volume +voodoo +vortex +voyage +waiter +warning +watch +water +wave +weather +wedding +weekend +welcome +western +wheel +whiskey +william +window +winter +wisdom +wizard +wolf +wonder +world +xray +yankee +year +yellow +yes +yoga +yogurt +young +yoyo +zebra +zero +zigzag +zipper +zodiac +zoom +""" diff --git a/wordlists/mnemonic.py b/wordlists/mnemonic.py new file mode 100755 index 00000000..83c91393 --- /dev/null +++ b/wordlists/mnemonic.py @@ -0,0 +1,1691 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2011 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + + +# list of words from http://en.wiktionary.org/wiki/Wiktionary:Frequency_lists/Contemporary_poetry + +words = [ +"like", +"just", +"love", +"know", +"never", +"want", +"time", +"out", +"there", +"make", +"look", +"eye", +"down", +"only", +"think", +"heart", +"back", +"then", +"into", +"about", +"more", +"away", +"still", +"them", +"take", +"thing", +"even", +"through", +"long", +"always", +"world", +"too", +"friend", +"tell", +"try", +"hand", +"thought", +"over", +"here", +"other", +"need", +"smile", +"again", +"much", +"cry", +"been", +"night", +"ever", +"little", +"said", +"end", +"some", +"those", +"around", +"mind", +"people", +"girl", +"leave", +"dream", +"left", +"turn", +"myself", +"give", +"nothing", +"really", +"off", +"before", +"something", +"find", +"walk", +"wish", +"good", +"once", +"place", +"ask", +"stop", +"keep", +"watch", +"seem", +"everything", +"wait", +"got", +"yet", +"made", +"remember", +"start", +"alone", +"run", +"hope", +"maybe", +"believe", +"body", +"hate", +"after", +"close", +"talk", +"stand", +"own", +"each", +"hurt", +"help", +"home", +"god", +"soul", +"new", +"many", +"two", +"inside", +"should", +"true", +"first", +"fear", +"mean", +"better", +"play", +"another", +"gone", +"change", +"use", +"wonder", +"someone", +"hair", +"cold", +"open", +"best", +"any", +"behind", +"happen", +"water", +"dark", +"laugh", +"stay", +"forever", +"name", +"work", +"show", +"sky", +"break", +"came", +"deep", +"door", +"put", +"black", +"together", +"upon", +"happy", +"such", +"great", +"white", +"matter", +"fill", +"past", +"please", +"burn", +"cause", +"enough", +"touch", +"moment", +"soon", +"voice", +"scream", +"anything", +"stare", +"sound", +"red", +"everyone", +"hide", +"kiss", +"truth", +"death", +"beautiful", +"mine", +"blood", +"broken", +"very", +"pass", +"next", +"forget", +"tree", +"wrong", +"air", +"mother", +"understand", +"lip", +"hit", +"wall", +"memory", +"sleep", +"free", +"high", +"realize", +"school", +"might", +"skin", +"sweet", +"perfect", +"blue", +"kill", +"breath", +"dance", +"against", +"fly", +"between", +"grow", +"strong", +"under", +"listen", +"bring", +"sometimes", +"speak", +"pull", +"person", +"become", +"family", +"begin", +"ground", +"real", +"small", +"father", +"sure", +"feet", +"rest", +"young", +"finally", +"land", +"across", +"today", +"different", +"guy", +"line", +"fire", +"reason", +"reach", +"second", +"slowly", +"write", +"eat", +"smell", +"mouth", +"step", +"learn", +"three", +"floor", +"promise", +"breathe", +"darkness", +"push", +"earth", +"guess", +"save", +"song", +"above", +"along", +"both", +"color", +"house", +"almost", +"sorry", +"anymore", +"brother", +"okay", +"dear", +"game", +"fade", +"already", +"apart", +"warm", +"beauty", +"heard", +"notice", +"question", +"shine", +"began", +"piece", +"whole", +"shadow", +"secret", +"street", +"within", +"finger", +"point", +"morning", +"whisper", +"child", +"moon", +"green", +"story", +"glass", +"kid", +"silence", +"since", +"soft", +"yourself", +"empty", +"shall", +"angel", +"answer", +"baby", +"bright", +"dad", +"path", +"worry", +"hour", +"drop", +"follow", +"power", +"war", +"half", +"flow", +"heaven", +"act", +"chance", +"fact", +"least", +"tired", +"children", +"near", +"quite", +"afraid", +"rise", +"sea", +"taste", +"window", +"cover", +"nice", +"trust", +"lot", +"sad", +"cool", +"force", +"peace", +"return", +"blind", +"easy", +"ready", +"roll", +"rose", +"drive", +"held", +"music", +"beneath", +"hang", +"mom", +"paint", +"emotion", +"quiet", +"clear", +"cloud", +"few", +"pretty", +"bird", +"outside", +"paper", +"picture", +"front", +"rock", +"simple", +"anyone", +"meant", +"reality", +"road", +"sense", +"waste", +"bit", +"leaf", +"thank", +"happiness", +"meet", +"men", +"smoke", +"truly", +"decide", +"self", +"age", +"book", +"form", +"alive", +"carry", +"escape", +"damn", +"instead", +"able", +"ice", +"minute", +"throw", +"catch", +"leg", +"ring", +"course", +"goodbye", +"lead", +"poem", +"sick", +"corner", +"desire", +"known", +"problem", +"remind", +"shoulder", +"suppose", +"toward", +"wave", +"drink", +"jump", +"woman", +"pretend", +"sister", +"week", +"human", +"joy", +"crack", +"grey", +"pray", +"surprise", +"dry", +"knee", +"less", +"search", +"bleed", +"caught", +"clean", +"embrace", +"future", +"king", +"son", +"sorrow", +"chest", +"hug", +"remain", +"sat", +"worth", +"blow", +"daddy", +"final", +"parent", +"tight", +"also", +"create", +"lonely", +"safe", +"cross", +"dress", +"evil", +"silent", +"bone", +"fate", +"perhaps", +"anger", +"class", +"scar", +"snow", +"tiny", +"tonight", +"continue", +"control", +"dog", +"edge", +"mirror", +"month", +"suddenly", +"comfort", +"given", +"loud", +"quickly", +"gaze", +"plan", +"rush", +"stone", +"town", +"battle", +"ignore", +"spirit", +"stood", +"stupid", +"yours", +"brown", +"build", +"dust", +"hey", +"kept", +"pay", +"phone", +"twist", +"although", +"ball", +"beyond", +"hidden", +"nose", +"taken", +"fail", +"float", +"pure", +"somehow", +"wash", +"wrap", +"angry", +"cheek", +"creature", +"forgotten", +"heat", +"rip", +"single", +"space", +"special", +"weak", +"whatever", +"yell", +"anyway", +"blame", +"job", +"choose", +"country", +"curse", +"drift", +"echo", +"figure", +"grew", +"laughter", +"neck", +"suffer", +"worse", +"yeah", +"disappear", +"foot", +"forward", +"knife", +"mess", +"somewhere", +"stomach", +"storm", +"beg", +"idea", +"lift", +"offer", +"breeze", +"field", +"five", +"often", +"simply", +"stuck", +"win", +"allow", +"confuse", +"enjoy", +"except", +"flower", +"seek", +"strength", +"calm", +"grin", +"gun", +"heavy", +"hill", +"large", +"ocean", +"shoe", +"sigh", +"straight", +"summer", +"tongue", +"accept", +"crazy", +"everyday", +"exist", +"grass", +"mistake", +"sent", +"shut", +"surround", +"table", +"ache", +"brain", +"destroy", +"heal", +"nature", +"shout", +"sign", +"stain", +"choice", +"doubt", +"glance", +"glow", +"mountain", +"queen", +"stranger", +"throat", +"tomorrow", +"city", +"either", +"fish", +"flame", +"rather", +"shape", +"spin", +"spread", +"ash", +"distance", +"finish", +"image", +"imagine", +"important", +"nobody", +"shatter", +"warmth", +"became", +"feed", +"flesh", +"funny", +"lust", +"shirt", +"trouble", +"yellow", +"attention", +"bare", +"bite", +"money", +"protect", +"amaze", +"appear", +"born", +"choke", +"completely", +"daughter", +"fresh", +"friendship", +"gentle", +"probably", +"six", +"deserve", +"expect", +"grab", +"middle", +"nightmare", +"river", +"thousand", +"weight", +"worst", +"wound", +"barely", +"bottle", +"cream", +"regret", +"relationship", +"stick", +"test", +"crush", +"endless", +"fault", +"itself", +"rule", +"spill", +"art", +"circle", +"join", +"kick", +"mask", +"master", +"passion", +"quick", +"raise", +"smooth", +"unless", +"wander", +"actually", +"broke", +"chair", +"deal", +"favorite", +"gift", +"note", +"number", +"sweat", +"box", +"chill", +"clothes", +"lady", +"mark", +"park", +"poor", +"sadness", +"tie", +"animal", +"belong", +"brush", +"consume", +"dawn", +"forest", +"innocent", +"pen", +"pride", +"stream", +"thick", +"clay", +"complete", +"count", +"draw", +"faith", +"press", +"silver", +"struggle", +"surface", +"taught", +"teach", +"wet", +"bless", +"chase", +"climb", +"enter", +"letter", +"melt", +"metal", +"movie", +"stretch", +"swing", +"vision", +"wife", +"beside", +"crash", +"forgot", +"guide", +"haunt", +"joke", +"knock", +"plant", +"pour", +"prove", +"reveal", +"steal", +"stuff", +"trip", +"wood", +"wrist", +"bother", +"bottom", +"crawl", +"crowd", +"fix", +"forgive", +"frown", +"grace", +"loose", +"lucky", +"party", +"release", +"surely", +"survive", +"teacher", +"gently", +"grip", +"speed", +"suicide", +"travel", +"treat", +"vein", +"written", +"cage", +"chain", +"conversation", +"date", +"enemy", +"however", +"interest", +"million", +"page", +"pink", +"proud", +"sway", +"themselves", +"winter", +"church", +"cruel", +"cup", +"demon", +"experience", +"freedom", +"pair", +"pop", +"purpose", +"respect", +"shoot", +"softly", +"state", +"strange", +"bar", +"birth", +"curl", +"dirt", +"excuse", +"lord", +"lovely", +"monster", +"order", +"pack", +"pants", +"pool", +"scene", +"seven", +"shame", +"slide", +"ugly", +"among", +"blade", +"blonde", +"closet", +"creek", +"deny", +"drug", +"eternity", +"gain", +"grade", +"handle", +"key", +"linger", +"pale", +"prepare", +"swallow", +"swim", +"tremble", +"wheel", +"won", +"cast", +"cigarette", +"claim", +"college", +"direction", +"dirty", +"gather", +"ghost", +"hundred", +"loss", +"lung", +"orange", +"present", +"swear", +"swirl", +"twice", +"wild", +"bitter", +"blanket", +"doctor", +"everywhere", +"flash", +"grown", +"knowledge", +"numb", +"pressure", +"radio", +"repeat", +"ruin", +"spend", +"unknown", +"buy", +"clock", +"devil", +"early", +"false", +"fantasy", +"pound", +"precious", +"refuse", +"sheet", +"teeth", +"welcome", +"add", +"ahead", +"block", +"bury", +"caress", +"content", +"depth", +"despite", +"distant", +"marry", +"purple", +"threw", +"whenever", +"bomb", +"dull", +"easily", +"grasp", +"hospital", +"innocence", +"normal", +"receive", +"reply", +"rhyme", +"shade", +"someday", +"sword", +"toe", +"visit", +"asleep", +"bought", +"center", +"consider", +"flat", +"hero", +"history", +"ink", +"insane", +"muscle", +"mystery", +"pocket", +"reflection", +"shove", +"silently", +"smart", +"soldier", +"spot", +"stress", +"train", +"type", +"view", +"whether", +"bus", +"energy", +"explain", +"holy", +"hunger", +"inch", +"magic", +"mix", +"noise", +"nowhere", +"prayer", +"presence", +"shock", +"snap", +"spider", +"study", +"thunder", +"trail", +"admit", +"agree", +"bag", +"bang", +"bound", +"butterfly", +"cute", +"exactly", +"explode", +"familiar", +"fold", +"further", +"pierce", +"reflect", +"scent", +"selfish", +"sharp", +"sink", +"spring", +"stumble", +"universe", +"weep", +"women", +"wonderful", +"action", +"ancient", +"attempt", +"avoid", +"birthday", +"branch", +"chocolate", +"core", +"depress", +"drunk", +"especially", +"focus", +"fruit", +"honest", +"match", +"palm", +"perfectly", +"pillow", +"pity", +"poison", +"roar", +"shift", +"slightly", +"thump", +"truck", +"tune", +"twenty", +"unable", +"wipe", +"wrote", +"coat", +"constant", +"dinner", +"drove", +"egg", +"eternal", +"flight", +"flood", +"frame", +"freak", +"gasp", +"glad", +"hollow", +"motion", +"peer", +"plastic", +"root", +"screen", +"season", +"sting", +"strike", +"team", +"unlike", +"victim", +"volume", +"warn", +"weird", +"attack", +"await", +"awake", +"built", +"charm", +"crave", +"despair", +"fought", +"grant", +"grief", +"horse", +"limit", +"message", +"ripple", +"sanity", +"scatter", +"serve", +"split", +"string", +"trick", +"annoy", +"blur", +"boat", +"brave", +"clearly", +"cling", +"connect", +"fist", +"forth", +"imagination", +"iron", +"jock", +"judge", +"lesson", +"milk", +"misery", +"nail", +"naked", +"ourselves", +"poet", +"possible", +"princess", +"sail", +"size", +"snake", +"society", +"stroke", +"torture", +"toss", +"trace", +"wise", +"bloom", +"bullet", +"cell", +"check", +"cost", +"darling", +"during", +"footstep", +"fragile", +"hallway", +"hardly", +"horizon", +"invisible", +"journey", +"midnight", +"mud", +"nod", +"pause", +"relax", +"shiver", +"sudden", +"value", +"youth", +"abuse", +"admire", +"blink", +"breast", +"bruise", +"constantly", +"couple", +"creep", +"curve", +"difference", +"dumb", +"emptiness", +"gotta", +"honor", +"plain", +"planet", +"recall", +"rub", +"ship", +"slam", +"soar", +"somebody", +"tightly", +"weather", +"adore", +"approach", +"bond", +"bread", +"burst", +"candle", +"coffee", +"cousin", +"crime", +"desert", +"flutter", +"frozen", +"grand", +"heel", +"hello", +"language", +"level", +"movement", +"pleasure", +"powerful", +"random", +"rhythm", +"settle", +"silly", +"slap", +"sort", +"spoken", +"steel", +"threaten", +"tumble", +"upset", +"aside", +"awkward", +"bee", +"blank", +"board", +"button", +"card", +"carefully", +"complain", +"crap", +"deeply", +"discover", +"drag", +"dread", +"effort", +"entire", +"fairy", +"giant", +"gotten", +"greet", +"illusion", +"jeans", +"leap", +"liquid", +"march", +"mend", +"nervous", +"nine", +"replace", +"rope", +"spine", +"stole", +"terror", +"accident", +"apple", +"balance", +"boom", +"childhood", +"collect", +"demand", +"depression", +"eventually", +"faint", +"glare", +"goal", +"group", +"honey", +"kitchen", +"laid", +"limb", +"machine", +"mere", +"mold", +"murder", +"nerve", +"painful", +"poetry", +"prince", +"rabbit", +"shelter", +"shore", +"shower", +"soothe", +"stair", +"steady", +"sunlight", +"tangle", +"tease", +"treasure", +"uncle", +"begun", +"bliss", +"canvas", +"cheer", +"claw", +"clutch", +"commit", +"crimson", +"crystal", +"delight", +"doll", +"existence", +"express", +"fog", +"football", +"gay", +"goose", +"guard", +"hatred", +"illuminate", +"mass", +"math", +"mourn", +"rich", +"rough", +"skip", +"stir", +"student", +"style", +"support", +"thorn", +"tough", +"yard", +"yearn", +"yesterday", +"advice", +"appreciate", +"autumn", +"bank", +"beam", +"bowl", +"capture", +"carve", +"collapse", +"confusion", +"creation", +"dove", +"feather", +"girlfriend", +"glory", +"government", +"harsh", +"hop", +"inner", +"loser", +"moonlight", +"neighbor", +"neither", +"peach", +"pig", +"praise", +"screw", +"shield", +"shimmer", +"sneak", +"stab", +"subject", +"throughout", +"thrown", +"tower", +"twirl", +"wow", +"army", +"arrive", +"bathroom", +"bump", +"cease", +"cookie", +"couch", +"courage", +"dim", +"guilt", +"howl", +"hum", +"husband", +"insult", +"led", +"lunch", +"mock", +"mostly", +"natural", +"nearly", +"needle", +"nerd", +"peaceful", +"perfection", +"pile", +"price", +"remove", +"roam", +"sanctuary", +"serious", +"shiny", +"shook", +"sob", +"stolen", +"tap", +"vain", +"void", +"warrior", +"wrinkle", +"affection", +"apologize", +"blossom", +"bounce", +"bridge", +"cheap", +"crumble", +"decision", +"descend", +"desperately", +"dig", +"dot", +"flip", +"frighten", +"heartbeat", +"huge", +"lazy", +"lick", +"odd", +"opinion", +"process", +"puzzle", +"quietly", +"retreat", +"score", +"sentence", +"separate", +"situation", +"skill", +"soak", +"square", +"stray", +"taint", +"task", +"tide", +"underneath", +"veil", +"whistle", +"anywhere", +"bedroom", +"bid", +"bloody", +"burden", +"careful", +"compare", +"concern", +"curtain", +"decay", +"defeat", +"describe", +"double", +"dreamer", +"driver", +"dwell", +"evening", +"flare", +"flicker", +"grandma", +"guitar", +"harm", +"horrible", +"hungry", +"indeed", +"lace", +"melody", +"monkey", +"nation", +"object", +"obviously", +"rainbow", +"salt", +"scratch", +"shown", +"shy", +"stage", +"stun", +"third", +"tickle", +"useless", +"weakness", +"worship", +"worthless", +"afternoon", +"beard", +"boyfriend", +"bubble", +"busy", +"certain", +"chin", +"concrete", +"desk", +"diamond", +"doom", +"drawn", +"due", +"felicity", +"freeze", +"frost", +"garden", +"glide", +"harmony", +"hopefully", +"hunt", +"jealous", +"lightning", +"mama", +"mercy", +"peel", +"physical", +"position", +"pulse", +"punch", +"quit", +"rant", +"respond", +"salty", +"sane", +"satisfy", +"savior", +"sheep", +"slept", +"social", +"sport", +"tuck", +"utter", +"valley", +"wolf", +"aim", +"alas", +"alter", +"arrow", +"awaken", +"beaten", +"belief", +"brand", +"ceiling", +"cheese", +"clue", +"confidence", +"connection", +"daily", +"disguise", +"eager", +"erase", +"essence", +"everytime", +"expression", +"fan", +"flag", +"flirt", +"foul", +"fur", +"giggle", +"glorious", +"ignorance", +"law", +"lifeless", +"measure", +"mighty", +"muse", +"north", +"opposite", +"paradise", +"patience", +"patient", +"pencil", +"petal", +"plate", +"ponder", +"possibly", +"practice", +"slice", +"spell", +"stock", +"strife", +"strip", +"suffocate", +"suit", +"tender", +"tool", +"trade", +"velvet", +"verse", +"waist", +"witch", +"aunt", +"bench", +"bold", +"cap", +"certainly", +"click", +"companion", +"creator", +"dart", +"delicate", +"determine", +"dish", +"dragon", +"drama", +"drum", +"dude", +"everybody", +"feast", +"forehead", +"former", +"fright", +"fully", +"gas", +"hook", +"hurl", +"invite", +"juice", +"manage", +"moral", +"possess", +"raw", +"rebel", +"royal", +"scale", +"scary", +"several", +"slight", +"stubborn", +"swell", +"talent", +"tea", +"terrible", +"thread", +"torment", +"trickle", +"usually", +"vast", +"violence", +"weave", +"acid", +"agony", +"ashamed", +"awe", +"belly", +"blend", +"blush", +"character", +"cheat", +"common", +"company", +"coward", +"creak", +"danger", +"deadly", +"defense", +"define", +"depend", +"desperate", +"destination", +"dew", +"duck", +"dusty", +"embarrass", +"engine", +"example", +"explore", +"foe", +"freely", +"frustrate", +"generation", +"glove", +"guilty", +"health", +"hurry", +"idiot", +"impossible", +"inhale", +"jaw", +"kingdom", +"mention", +"mist", +"moan", +"mumble", +"mutter", +"observe", +"ode", +"pathetic", +"pattern", +"pie", +"prefer", +"puff", +"rape", +"rare", +"revenge", +"rude", +"scrape", +"spiral", +"squeeze", +"strain", +"sunset", +"suspend", +"sympathy", +"thigh", +"throne", +"total", +"unseen", +"weapon", +"weary" +] + + + +n = 1626 + +# Note about US patent no 5892470: Here each word does not represent a given digit. +# Instead, the digit represented by a word is variable, it depends on the previous word. + +def mn_encode( message ): + out = [] + for i in range(len(message)/8): + word = message[8*i:8*i+8] + x = int(word, 16) + w1 = (x%n) + w2 = ((x/n) + w1)%n + w3 = ((x/n/n) + w2)%n + out += [ words[w1], words[w2], words[w3] ] + return out + +def mn_decode( wlist ): + out = '' + for i in range(len(wlist)/3): + word1, word2, word3 = wlist[3*i:3*i+3] + w1 = words.index(word1) + w2 = (words.index(word2))%n + w3 = (words.index(word3))%n + x = w1 +n*((w2-w1)%n) +n*n*((w3-w2)%n) + out += '%08x'%x + return out + +if __name__ == '__main__': + print "\n".join(words) + +# if __name__ == '__main__': +# import sys +# if len( sys.argv ) == 1: +# print 'I need arguments: a hex string to encode, or a list of words to decode' +# elif len( sys.argv ) == 2: +# print ' '.join(mn_encode(sys.argv[1])) +# else: +# print mn_decode(sys.argv[1:]) diff --git a/wordlists/mnemonic.sort.py b/wordlists/mnemonic.sort.py new file mode 100644 index 00000000..e1627af4 --- /dev/null +++ b/wordlists/mnemonic.sort.py @@ -0,0 +1,1638 @@ +#!/usr/bin/python + +# electrum wordlist +# Electrum - lightweight Bitcoin client +# Copyright (C) 2011 thomasv@gitorious +# list of words from: +# http://en.wiktionary.org/wiki/Wiktionary:Frequency_lists/Contemporary_poetry + +# This is a sorted version of the wordlist + +electrum_wordlist = """ +able +about +above +abuse +accept +accident +ache +acid +across +act +action +actually +add +admire +admit +adore +advice +affection +afraid +after +afternoon +again +against +age +agony +agree +ahead +aim +air +alas +alive +allow +almost +alone +along +already +also +alter +although +always +amaze +among +ancient +angel +anger +angry +animal +annoy +another +answer +any +anymore +anyone +anything +anyway +anywhere +apart +apologize +appear +apple +appreciate +approach +army +around +arrive +arrow +art +ash +ashamed +aside +ask +asleep +attack +attempt +attention +aunt +autumn +avoid +await +awake +awaken +away +awe +awkward +baby +back +bag +balance +ball +bang +bank +bar +bare +barely +bathroom +battle +beam +beard +beaten +beautiful +beauty +became +become +bedroom +bee +been +before +beg +began +begin +begun +behind +belief +believe +belly +belong +bench +beneath +beside +best +better +between +beyond +bid +bird +birth +birthday +bit +bite +bitter +black +blade +blame +blank +blanket +bleed +blend +bless +blind +blink +bliss +block +blonde +blood +bloody +bloom +blossom +blow +blue +blur +blush +board +boat +body +bold +bomb +bond +bone +book +boom +born +both +bother +bottle +bottom +bought +bounce +bound +bowl +box +boyfriend +brain +branch +brand +brave +bread +break +breast +breath +breathe +breeze +bridge +bright +bring +broke +broken +brother +brown +bruise +brush +bubble +build +built +bullet +bump +burden +burn +burst +bury +bus +busy +butterfly +button +buy +cage +calm +came +candle +canvas +cap +capture +card +careful +carefully +caress +carry +carve +cast +catch +caught +cause +cease +ceiling +cell +center +certain +certainly +chain +chair +chance +change +character +charm +chase +cheap +cheat +check +cheek +cheer +cheese +chest +child +childhood +children +chill +chin +chocolate +choice +choke +choose +church +cigarette +circle +city +claim +class +claw +clay +clean +clear +clearly +click +climb +cling +clock +close +closet +clothes +cloud +clue +clutch +coat +coffee +cold +collapse +collect +college +color +comfort +commit +common +companion +company +compare +complain +complete +completely +concern +concrete +confidence +confuse +confusion +connect +connection +consider +constant +constantly +consume +content +continue +control +conversation +cookie +cool +core +corner +cost +couch +count +country +couple +courage +course +cousin +cover +coward +crack +crap +crash +crave +crawl +crazy +creak +cream +create +creation +creator +creature +creek +creep +crime +crimson +cross +crowd +cruel +crumble +crush +cry +crystal +cup +curl +curse +curtain +curve +cute +dad +daddy +daily +damn +dance +danger +dark +darkness +darling +dart +date +daughter +dawn +deadly +deal +dear +death +decay +decide +decision +deep +deeply +defeat +defense +define +delicate +delight +demand +demon +deny +depend +depress +depression +depth +descend +describe +desert +deserve +desire +desk +despair +desperate +desperately +despite +destination +destroy +determine +devil +dew +diamond +difference +different +dig +dim +dinner +direction +dirt +dirty +disappear +discover +disguise +dish +distance +distant +doctor +dog +doll +doom +door +dot +double +doubt +dove +down +drag +dragon +drama +draw +drawn +dread +dream +dreamer +dress +drift +drink +drive +driver +drop +drove +drug +drum +drunk +dry +duck +dude +due +dull +dumb +during +dust +dusty +dwell +each +eager +early +earth +easily +easy +eat +echo +edge +effort +egg +either +embarrass +embrace +emotion +emptiness +empty +end +endless +enemy +energy +engine +enjoy +enough +enter +entire +erase +escape +especially +essence +eternal +eternity +even +evening +eventually +ever +everybody +everyday +everyone +everything +everytime +everywhere +evil +exactly +example +except +excuse +exist +existence +expect +experience +explain +explode +explore +express +expression +eye +fact +fade +fail +faint +fairy +faith +false +familiar +family +fan +fantasy +fate +father +fault +favorite +fear +feast +feather +feed +feet +felicity +few +field +figure +fill +final +finally +find +finger +finish +fire +first +fish +fist +five +fix +flag +flame +flare +flash +flat +flesh +flicker +flight +flip +flirt +float +flood +floor +flow +flower +flutter +fly +focus +foe +fog +fold +follow +foot +football +footstep +force +forehead +forest +forever +forget +forgive +forgot +forgotten +form +former +forth +forward +fought +foul +fragile +frame +freak +free +freedom +freely +freeze +fresh +friend +friendship +fright +frighten +front +frost +frown +frozen +fruit +frustrate +fully +funny +fur +further +future +gain +game +garden +gas +gasp +gather +gay +gaze +generation +gentle +gently +ghost +giant +gift +giggle +girl +girlfriend +give +given +glad +glance +glare +glass +glide +glorious +glory +glove +glow +goal +god +gone +good +goodbye +goose +got +gotta +gotten +government +grab +grace +grade +grand +grandma +grant +grasp +grass +great +green +greet +grew +grey +grief +grin +grip +ground +group +grow +grown +guard +guess +guide +guilt +guilty +guitar +gun +guy +hair +half +hallway +hand +handle +hang +happen +happiness +happy +hardly +harm +harmony +harsh +hate +hatred +haunt +heal +health +heard +heart +heartbeat +heat +heaven +heavy +heel +held +hello +help +here +hero +hey +hidden +hide +high +hill +history +hit +hollow +holy +home +honest +honey +honor +hook +hop +hope +hopefully +horizon +horrible +horse +hospital +hour +house +however +howl +hug +huge +hum +human +hundred +hunger +hungry +hunt +hurl +hurry +hurt +husband +ice +idea +idiot +ignorance +ignore +illuminate +illusion +image +imagination +imagine +important +impossible +inch +indeed +inhale +ink +inner +innocence +innocent +insane +inside +instead +insult +interest +into +invisible +invite +iron +itself +jaw +jealous +jeans +job +jock +join +joke +journey +joy +judge +juice +jump +just +keep +kept +key +kick +kid +kill +king +kingdom +kiss +kitchen +knee +knife +knock +know +knowledge +known +lace +lady +laid +land +language +large +laugh +laughter +law +lazy +lead +leaf +leap +learn +least +leave +led +left +leg +less +lesson +letter +level +lick +lifeless +lift +lightning +like +limb +limit +line +linger +lip +liquid +listen +little +lonely +long +look +loose +lord +loser +loss +lot +loud +love +lovely +lucky +lunch +lung +lust +machine +made +magic +make +mama +manage +many +march +mark +marry +mask +mass +master +match +math +matter +maybe +mean +meant +measure +meet +melody +melt +memory +men +mend +mention +mercy +mere +mess +message +metal +middle +midnight +might +mighty +milk +million +mind +mine +minute +mirror +misery +mist +mistake +mix +moan +mock +mold +mom +moment +money +monkey +monster +month +moon +moonlight +moral +more +morning +mostly +mother +motion +mountain +mourn +mouth +movement +movie +much +mud +mumble +murder +muscle +muse +music +mutter +myself +mystery +nail +naked +name +nation +natural +nature +near +nearly +neck +need +needle +neighbor +neither +nerd +nerve +nervous +never +new +next +nice +night +nightmare +nine +nobody +nod +noise +normal +north +nose +note +nothing +notice +nowhere +numb +number +object +observe +obviously +ocean +odd +ode +off +offer +often +okay +once +only +open +opinion +opposite +orange +order +other +ourselves +out +outside +over +own +pack +page +painful +paint +pair +pale +palm +pants +paper +paradise +parent +park +party +pass +passion +past +path +pathetic +patience +patient +pattern +pause +pay +peace +peaceful +peach +peel +peer +pen +pencil +people +perfect +perfection +perfectly +perhaps +person +petal +phone +physical +picture +pie +piece +pierce +pig +pile +pillow +pink +pity +place +plain +plan +planet +plant +plastic +plate +play +please +pleasure +pocket +poem +poet +poetry +point +poison +ponder +pool +poor +pop +position +possess +possible +possibly +pound +pour +power +powerful +practice +praise +pray +prayer +precious +prefer +prepare +presence +present +press +pressure +pretend +pretty +price +pride +prince +princess +probably +problem +process +promise +protect +proud +prove +puff +pull +pulse +punch +pure +purple +purpose +push +put +puzzle +queen +question +quick +quickly +quiet +quietly +quit +quite +rabbit +radio +rainbow +raise +random +rant +rape +rare +rather +raw +reach +ready +real +reality +realize +really +reason +rebel +recall +receive +red +reflect +reflection +refuse +regret +relationship +relax +release +remain +remember +remind +remove +repeat +replace +reply +respect +respond +rest +retreat +return +reveal +revenge +rhyme +rhythm +rich +ring +rip +ripple +rise +river +road +roam +roar +rock +roll +root +rope +rose +rough +royal +rub +rude +ruin +rule +run +rush +sad +sadness +safe +said +sail +salt +salty +sanctuary +sane +sanity +sat +satisfy +save +savior +scale +scar +scary +scatter +scene +scent +school +score +scrape +scratch +scream +screen +screw +sea +search +season +second +secret +seek +seem +self +selfish +sense +sent +sentence +separate +serious +serve +settle +seven +several +shade +shadow +shall +shame +shape +sharp +shatter +sheep +sheet +shelter +shield +shift +shimmer +shine +shiny +ship +shirt +shiver +shock +shoe +shook +shoot +shore +should +shoulder +shout +shove +show +shower +shown +shut +shy +sick +sigh +sign +silence +silent +silently +silly +silver +simple +simply +since +single +sink +sister +situation +six +size +skill +skin +skip +sky +slam +slap +sleep +slept +slice +slide +slight +slightly +slowly +small +smart +smell +smile +smoke +smooth +snake +snap +sneak +snow +soak +soar +sob +social +society +soft +softly +soldier +some +somebody +someday +somehow +someone +something +sometimes +somewhere +son +song +soon +soothe +sorrow +sorry +sort +soul +sound +space +speak +special +speed +spell +spend +spider +spill +spin +spine +spiral +spirit +split +spoken +sport +spot +spread +spring +square +squeeze +stab +stage +stain +stair +stand +stare +start +state +stay +steady +steal +steel +step +stick +still +sting +stir +stock +stole +stolen +stomach +stone +stood +stop +storm +story +straight +strain +strange +stranger +stray +stream +street +strength +stress +stretch +strife +strike +string +strip +stroke +strong +struggle +stubborn +stuck +student +study +stuff +stumble +stun +stupid +style +subject +such +sudden +suddenly +suffer +suffocate +suicide +suit +summer +sunlight +sunset +support +suppose +sure +surely +surface +surprise +surround +survive +suspend +swallow +sway +swear +sweat +sweet +swell +swim +swing +swirl +sword +sympathy +table +taint +take +taken +talent +talk +tangle +tap +task +taste +taught +tea +teach +teacher +team +tease +teeth +tell +tender +terrible +terror +test +thank +them +themselves +then +there +thick +thigh +thing +think +third +thorn +those +thought +thousand +thread +threaten +three +threw +throat +throne +through +throughout +throw +thrown +thump +thunder +tickle +tide +tie +tight +tightly +time +tiny +tired +today +toe +together +tomorrow +tongue +tonight +too +tool +torment +torture +toss +total +touch +tough +toward +tower +town +trace +trade +trail +train +travel +treasure +treat +tree +tremble +trick +trickle +trip +trouble +truck +true +truly +trust +truth +try +tuck +tumble +tune +turn +twenty +twice +twirl +twist +two +type +ugly +unable +uncle +under +underneath +understand +universe +unknown +unless +unlike +unseen +upon +upset +use +useless +usually +utter +vain +valley +value +vast +veil +vein +velvet +verse +very +victim +view +violence +vision +visit +voice +void +volume +waist +wait +walk +wall +wander +want +war +warm +warmth +warn +warrior +wash +waste +watch +water +wave +weak +weakness +weapon +weary +weather +weave +week +weep +weight +weird +welcome +wet +whatever +wheel +whenever +whether +whisper +whistle +white +whole +wife +wild +win +window +winter +wipe +wise +wish +witch +within +wolf +woman +women +won +wonder +wonderful +wood +work +world +worry +worse +worship +worst +worth +worthless +wound +wow +wrap +wrinkle +wrist +write +written +wrong +wrote +yard +yeah +yearn +yell +yellow +yesterday +yet +young +yours +yourself +youth +"""