From fcdea621bfc714e3bdc58b60706e2c6612c88c10 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sun, 25 Oct 2015 13:42:49 -0700 Subject: [PATCH 001/287] first commit --- LICENSE.md | 206 ++++++++++++++++++++++++++++++++++++++++++++++ priv_key.go | 77 +++++++++++++++++ pub_key.go | 91 ++++++++++++++++++++ signature.go | 34 ++++++++ signature_test.go | 68 +++++++++++++++ 5 files changed, 476 insertions(+) create mode 100644 LICENSE.md create mode 100644 priv_key.go create mode 100644 pub_key.go create mode 100644 signature.go create mode 100644 signature_test.go diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 000000000..25db84e64 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,206 @@ +Tendermint Go-Crypto +Copyright (C) 2015 Tendermint + +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 . + +//-------------------------------------------------------------------------------- + +GNU GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright © 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 diff --git a/priv_key.go b/priv_key.go new file mode 100644 index 000000000..9a5c66163 --- /dev/null +++ b/priv_key.go @@ -0,0 +1,77 @@ +package account + +import ( + "github.com/tendermint/ed25519" + "github.com/tendermint/ed25519/extra25519" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" +) + +// PrivKey is part of PrivAccount and state.PrivValidator. +type PrivKey interface { + Sign(msg []byte) Signature + PubKey() PubKey +} + +// Types of PrivKey implementations +const ( + PrivKeyTypeEd25519 = byte(0x01) +) + +// for wire.readReflect +var _ = wire.RegisterInterface( + struct{ PrivKey }{}, + wire.ConcreteType{PrivKeyEd25519{}, PrivKeyTypeEd25519}, +) + +//------------------------------------- + +// Implements PrivKey +type PrivKeyEd25519 [64]byte + +func (key PrivKeyEd25519) Sign(msg []byte) Signature { + privKeyBytes := [64]byte(key) + signatureBytes := ed25519.Sign(&privKeyBytes, msg) + return SignatureEd25519(*signatureBytes) +} + +func (privKey PrivKeyEd25519) PubKey() PubKey { + privKeyBytes := [64]byte(privKey) + return PubKeyEd25519(*ed25519.MakePublicKey(&privKeyBytes)) +} + +func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte { + keyCurve25519 := new([32]byte) + privKeyBytes := [64]byte(privKey) + extra25519.PrivateKeyToCurve25519(keyCurve25519, &privKeyBytes) + return keyCurve25519 +} + +func (privKey PrivKeyEd25519) String() string { + return Fmt("PrivKeyEd25519{*****}") +} + +// Deterministically generates new priv-key bytes from key. +func (key PrivKeyEd25519) Generate(index int) PrivKeyEd25519 { + newBytes := wire.BinarySha256(struct { + PrivKey [64]byte + Index int + }{key, index}) + var newKey [64]byte + copy(newKey[:], newBytes) + return PrivKeyEd25519(newKey) +} + +func GenPrivKeyEd25519() PrivKeyEd25519 { + privKeyBytes := new([64]byte) + copy(privKeyBytes[:32], CRandBytes(32)) + ed25519.MakePublicKey(privKeyBytes) + return PrivKeyEd25519(*privKeyBytes) +} + +func GenPrivKeyEd25519FromSecret(secret string) PrivKeyEd25519 { + privKey32 := wire.BinarySha256(secret) // Not Ripemd160 because we want 32 bytes. + privKeyBytes := new([64]byte) + copy(privKeyBytes[:32], privKey32) + return PrivKeyEd25519(*privKeyBytes) +} diff --git a/pub_key.go b/pub_key.go new file mode 100644 index 000000000..0e7d8fa0d --- /dev/null +++ b/pub_key.go @@ -0,0 +1,91 @@ + +package account + +import ( + "bytes" + + "github.com/tendermint/ed25519" + "github.com/tendermint/ed25519/extra25519" + "golang.org/x/crypto/ripemd160" + "github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" +) + +// PubKey is part of Account and Validator. +type PubKey interface { + Address() []byte + VerifyBytes(msg []byte, sig Signature) bool +} + +// Types of PubKey implementations +const ( + PubKeyTypeEd25519 = byte(0x01) +) + +// for wire.readReflect +var _ = wire.RegisterInterface( + struct{ PubKey }{}, + wire.ConcreteType{PubKeyEd25519{}, PubKeyTypeEd25519}, +) + +//------------------------------------- + +// Implements PubKey +type PubKeyEd25519 [32]byte + +// TODO: Slicing the array gives us length prefixing but loses the type byte. +// Revisit if we add more pubkey types. +// For now, we artificially append the type byte in front to give us backwards +// compatibility for when the pubkey wasn't fixed length array +func (pubKey PubKeyEd25519) Address() []byte { + w, n, err := new(bytes.Buffer), new(int64), new(error) + wire.WriteBinary(pubKey[:], w, n, err) + if *err != nil { + PanicCrisis(*err) + } + // append type byte + encodedPubkey := append([]byte{1}, w.Bytes()...) + hasher := ripemd160.New() + hasher.Write(encodedPubkey) // does not error + return hasher.Sum(nil) +} + +// TODO: Consider returning a reason for failure, or logging a runtime type mismatch. +func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool { + sig, ok := sig_.(SignatureEd25519) + if !ok { + return false + } + pubKeyBytes := [32]byte(pubKey) + sigBytes := [64]byte(sig) + return ed25519.Verify(&pubKeyBytes, msg, &sigBytes) +} + +// For use with golang/crypto/nacl/box +// If error, returns nil. +func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte { + keyCurve25519, pubKeyBytes := new([32]byte), [32]byte(pubKey) + ok := extra25519.PublicKeyToCurve25519(keyCurve25519, &pubKeyBytes) + if !ok { + return nil + } + return keyCurve25519 +} + +func (pubKey PubKeyEd25519) String() string { + return Fmt("PubKeyEd25519{%X}", pubKey[:]) +} + +// Must return the full bytes in hex. +// Used for map keying, etc. +func (pubKey PubKeyEd25519) KeyString() string { + return Fmt("%X", pubKey[:]) +} + +func (pubKey PubKeyEd25519) Equals(other PubKey) bool { + if otherEd, ok := other.(PubKeyEd25519); ok { + return bytes.Equal(pubKey[:], otherEd[:]) + } else { + return false + } +} diff --git a/signature.go b/signature.go new file mode 100644 index 000000000..1224c5c99 --- /dev/null +++ b/signature.go @@ -0,0 +1,34 @@ +package account + +import ( + "fmt" + + "github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" +) + +// Signature is a part of Txs and consensus Votes. +type Signature interface { + IsZero() bool + String() string +} + +// Types of Signature implementations +const ( + SignatureTypeEd25519 = byte(0x01) +) + +// for wire.readReflect +var _ = wire.RegisterInterface( + struct{ Signature }{}, + wire.ConcreteType{SignatureEd25519{}, SignatureTypeEd25519}, +) + +//------------------------------------- + +// Implements Signature +type SignatureEd25519 [64]byte + +func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 } + +func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } diff --git a/signature_test.go b/signature_test.go new file mode 100644 index 000000000..8e603f97b --- /dev/null +++ b/signature_test.go @@ -0,0 +1,68 @@ +package account + +import ( + "bytes" + "testing" + + "github.com/tendermint/ed25519" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" +) + +func TestSignAndValidate(t *testing.T) { + + privKey := GenPrivKeyEd25519() + pubKey := privKey.PubKey() + + msg := CRandBytes(128) + sig := privKey.Sign(msg) + t.Logf("msg: %X, sig: %X", msg, sig) + + // Test the signature + if !pubKey.VerifyBytes(msg, sig) { + t.Errorf("Account message signature verification failed") + } + + // Mutate the signature, just one bit. + sigEd := sig.(SignatureEd25519) + sigEd[0] ^= byte(0x01) + sig = Signature(sigEd) + + if pubKey.VerifyBytes(msg, sig) { + t.Errorf("Account message signature verification should have failed but passed instead") + } +} + +func TestBinaryDecode(t *testing.T) { + + privKey := GenPrivKeyEd25519() + pubKey := privKey.PubKey() + + msg := CRandBytes(128) + sig := privKey.Sign(msg) + t.Logf("msg: %X, sig: %X", msg, sig) + + buf, n, err := new(bytes.Buffer), new(int64), new(error) + wire.WriteBinary(sig, buf, n, err) + if *err != nil { + t.Fatalf("Failed to write Signature: %v", err) + } + + if len(buf.Bytes()) != ed25519.SignatureSize+1 { + // 1 byte TypeByte, 64 bytes signature bytes + t.Fatalf("Unexpected signature write size: %v", len(buf.Bytes())) + } + if buf.Bytes()[0] != SignatureTypeEd25519 { + t.Fatalf("Unexpected signature type byte") + } + + sig2, ok := wire.ReadBinary(SignatureEd25519{}, buf, n, err).(SignatureEd25519) + if !ok || *err != nil { + t.Fatalf("Failed to read Signature: %v", err) + } + + // Test the signature + if !pubKey.VerifyBytes(msg, sig2) { + t.Errorf("Account message signature verification failed") + } +} From 31a456c8d403333639cf0b1d02e73037d4212cc4 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sun, 25 Oct 2015 13:45:13 -0700 Subject: [PATCH 002/287] update package name --- priv_key.go | 2 +- pub_key.go | 7 +++---- signature.go | 4 ++-- signature_test.go | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/priv_key.go b/priv_key.go index 9a5c66163..f548172e4 100644 --- a/priv_key.go +++ b/priv_key.go @@ -1,4 +1,4 @@ -package account +package crypto import ( "github.com/tendermint/ed25519" diff --git a/pub_key.go b/pub_key.go index 0e7d8fa0d..6eeb4a86e 100644 --- a/pub_key.go +++ b/pub_key.go @@ -1,14 +1,13 @@ - -package account +package crypto import ( "bytes" "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" - "golang.org/x/crypto/ripemd160" - "github.com/tendermint/go-wire" . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" + "golang.org/x/crypto/ripemd160" ) // PubKey is part of Account and Validator. diff --git a/signature.go b/signature.go index 1224c5c99..959258091 100644 --- a/signature.go +++ b/signature.go @@ -1,10 +1,10 @@ -package account +package crypto import ( "fmt" - "github.com/tendermint/go-wire" . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) // Signature is a part of Txs and consensus Votes. diff --git a/signature_test.go b/signature_test.go index 8e603f97b..1dbc58096 100644 --- a/signature_test.go +++ b/signature_test.go @@ -1,4 +1,4 @@ -package account +package crypto import ( "bytes" From 32b3a27a9a7a4c3c94c406cc10fc7749e639bdd3 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Tue, 10 Nov 2015 11:53:35 -0800 Subject: [PATCH 003/287] Conform to new go-wire 1.0 --- pub_key.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pub_key.go b/pub_key.go index 6eeb4a86e..47eba9ed6 100644 --- a/pub_key.go +++ b/pub_key.go @@ -37,7 +37,7 @@ type PubKeyEd25519 [32]byte // For now, we artificially append the type byte in front to give us backwards // compatibility for when the pubkey wasn't fixed length array func (pubKey PubKeyEd25519) Address() []byte { - w, n, err := new(bytes.Buffer), new(int64), new(error) + w, n, err := new(bytes.Buffer), new(int), new(error) wire.WriteBinary(pubKey[:], w, n, err) if *err != nil { PanicCrisis(*err) From ea56ed5ea24c2d6928be62d9921ff99643dfe8db Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Wed, 23 Dec 2015 14:17:27 -0800 Subject: [PATCH 004/287] Change license to Apache2.0 --- LICENSE | 193 +++++++++++++++++++++++++++++++++++++++++++++++++ LICENSE.md | 206 ----------------------------------------------------- 2 files changed, 193 insertions(+), 206 deletions(-) create mode 100644 LICENSE delete mode 100644 LICENSE.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..3beb77b13 --- /dev/null +++ b/LICENSE @@ -0,0 +1,193 @@ +Tendermint Go-Crypto +Copyright (C) 2015 Tendermint + + + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index 25db84e64..000000000 --- a/LICENSE.md +++ /dev/null @@ -1,206 +0,0 @@ -Tendermint Go-Crypto -Copyright (C) 2015 Tendermint - -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 . - -//-------------------------------------------------------------------------------- - -GNU GENERAL PUBLIC LICENSE - -Version 3, 29 June 2007 - -Copyright © 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 From 1fb7234ff5138df3df93678dd62cc4bc892b2f06 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 16 Jan 2016 13:49:16 -0500 Subject: [PATCH 005/287] fix test --- signature_test.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/signature_test.go b/signature_test.go index 1dbc58096..6a803b697 100644 --- a/signature_test.go +++ b/signature_test.go @@ -42,8 +42,8 @@ func TestBinaryDecode(t *testing.T) { sig := privKey.Sign(msg) t.Logf("msg: %X, sig: %X", msg, sig) - buf, n, err := new(bytes.Buffer), new(int64), new(error) - wire.WriteBinary(sig, buf, n, err) + buf, n, err := new(bytes.Buffer), new(int), new(error) + wire.WriteBinary(struct{ Signature }{sig}, buf, n, err) if *err != nil { t.Fatalf("Failed to write Signature: %v", err) } @@ -56,13 +56,14 @@ func TestBinaryDecode(t *testing.T) { t.Fatalf("Unexpected signature type byte") } - sig2, ok := wire.ReadBinary(SignatureEd25519{}, buf, n, err).(SignatureEd25519) - if !ok || *err != nil { + sigStruct := struct{ Signature }{} + sig2 := wire.ReadBinary(sigStruct, buf, 0, n, err) + if *err != nil { t.Fatalf("Failed to read Signature: %v", err) } // Test the signature - if !pubKey.VerifyBytes(msg, sig2) { + if !pubKey.VerifyBytes(msg, sig2.(struct{ Signature }).Signature.(SignatureEd25519)) { t.Errorf("Account message signature verification failed") } } From 372191dd5fc888ac21629be55fddd4fa22db06d7 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Mon, 8 Feb 2016 00:50:52 -0800 Subject: [PATCH 006/287] KeyString() in PubKey; Fix tests --- pub_key.go | 1 + signature_test.go | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pub_key.go b/pub_key.go index 47eba9ed6..c5d3cadc2 100644 --- a/pub_key.go +++ b/pub_key.go @@ -13,6 +13,7 @@ import ( // PubKey is part of Account and Validator. type PubKey interface { Address() []byte + KeyString() string VerifyBytes(msg []byte, sig Signature) bool } diff --git a/signature_test.go b/signature_test.go index 1dbc58096..b7eec577f 100644 --- a/signature_test.go +++ b/signature_test.go @@ -42,7 +42,7 @@ func TestBinaryDecode(t *testing.T) { sig := privKey.Sign(msg) t.Logf("msg: %X, sig: %X", msg, sig) - buf, n, err := new(bytes.Buffer), new(int64), new(error) + buf, n, err := new(bytes.Buffer), new(int), new(error) wire.WriteBinary(sig, buf, n, err) if *err != nil { t.Fatalf("Failed to write Signature: %v", err) @@ -56,7 +56,7 @@ func TestBinaryDecode(t *testing.T) { t.Fatalf("Unexpected signature type byte") } - sig2, ok := wire.ReadBinary(SignatureEd25519{}, buf, n, err).(SignatureEd25519) + sig2, ok := wire.ReadBinary(SignatureEd25519{}, buf, 0, n, err).(SignatureEd25519) if !ok || *err != nil { t.Fatalf("Failed to read Signature: %v", err) } From 76ba23e4c0c627b8c66d1f97b6a18dc77f4f0297 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Mon, 8 Feb 2016 02:18:06 -0800 Subject: [PATCH 007/287] Fix bug in GenPrivKeyEd25519FromSecret --- priv_key.go | 1 + 1 file changed, 1 insertion(+) diff --git a/priv_key.go b/priv_key.go index f548172e4..5e93fbe11 100644 --- a/priv_key.go +++ b/priv_key.go @@ -73,5 +73,6 @@ func GenPrivKeyEd25519FromSecret(secret string) PrivKeyEd25519 { privKey32 := wire.BinarySha256(secret) // Not Ripemd160 because we want 32 bytes. privKeyBytes := new([64]byte) copy(privKeyBytes[:32], privKey32) + ed25519.MakePublicKey(privKeyBytes) return PrivKeyEd25519(*privKeyBytes) } From 264d2a3eef760ab171f253b738b7d5dad5cde1b9 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sun, 13 Mar 2016 09:40:15 -0700 Subject: [PATCH 008/287] Add seed-able cryptographic random. --- hash.go | 18 +++++++++ pub_key.go | 1 + random.go | 100 ++++++++++++++++++++++++++++++++++++++++++++++ signature_test.go | 1 - 4 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 hash.go create mode 100644 random.go diff --git a/hash.go b/hash.go new file mode 100644 index 000000000..165b1e153 --- /dev/null +++ b/hash.go @@ -0,0 +1,18 @@ +package crypto + +import ( + "crypto/sha256" + "golang.org/x/crypto/ripemd160" +) + +func Sha256(bytes []byte) []byte { + hasher := sha256.New() + hasher.Write(bytes) + return hasher.Sum(nil) +} + +func Ripemd160(bytes []byte) []byte { + hasher := ripemd160.New() + hasher.Write(bytes) + return hasher.Sum(nil) +} diff --git a/pub_key.go b/pub_key.go index c5d3cadc2..4cfe815ce 100644 --- a/pub_key.go +++ b/pub_key.go @@ -15,6 +15,7 @@ type PubKey interface { Address() []byte KeyString() string VerifyBytes(msg []byte, sig Signature) bool + Equals(PubKey) bool } // Types of PubKey implementations diff --git a/random.go b/random.go new file mode 100644 index 000000000..803386843 --- /dev/null +++ b/random.go @@ -0,0 +1,100 @@ +package crypto + +import ( + "crypto/aes" + "crypto/cipher" + crand "crypto/rand" + "encoding/hex" + "io" + "sync" + + . "github.com/tendermint/go-common" +) + +var gRandInfo *randInfo + +func init() { + gRandInfo = &randInfo{} + gRandInfo.AddSeed(randBytes(32)) // Init +} + +// Add additional bytes of randomness, e.g. from hardware, user-input, etc. +// It is OK to call it multiple times. It does not deminish security. +func Seed(seedBytes []byte) { + gRandInfo.AddSeed(seedBytes) +} + +// This only uses the OS's randomness +func randBytes(numBytes int) []byte { + b := make([]byte, numBytes) + _, err := crand.Read(b) + if err != nil { + PanicCrisis(err) + } + return b +} + +// This uses the OS and the Seed(s). +func CRandBytes(numBytes int) []byte { + b := make([]byte, numBytes) + _, err := gRandInfo.Read(b) + if err != nil { + PanicCrisis(err) + } + return b +} + +// RandHex(24) gives 96 bits of randomness, strong enough for most purposes. +func CRandHex(numDigits int) string { + return hex.EncodeToString(CRandBytes(numDigits / 2)) +} + +// Returns a crand.Reader mixed with user-supplied entropy +func CReader() io.Reader { + return gRandInfo +} + +//-------------------------------------------------------------------------------- + +type randInfo struct { + mtx sync.Mutex + seedBytes [32]byte + cipherAES256 cipher.Block + streamAES256 cipher.Stream + reader io.Reader +} + +// You can call this as many times as you'd like. +// XXX TODO review +func (ri *randInfo) AddSeed(seedBytes []byte) { + ri.mtx.Lock() + defer ri.mtx.Unlock() + // Make new ri.seedBytes + hashBytes := Sha256(seedBytes) + hashBytes32 := [32]byte{} + copy(hashBytes32[:], hashBytes) + ri.seedBytes = xorBytes32(ri.seedBytes, hashBytes32) + // Create new cipher.Block + var err error + ri.cipherAES256, err = aes.NewCipher(ri.seedBytes[:]) + if err != nil { + PanicSanity("Error creating AES256 cipher: " + err.Error()) + } + // Create new stream + ri.streamAES256 = cipher.NewCTR(ri.cipherAES256, randBytes(aes.BlockSize)) + // Create new reader + ri.reader = &cipher.StreamReader{S: ri.streamAES256, R: crand.Reader} +} + +func (ri *randInfo) Read(b []byte) (n int, err error) { + ri.mtx.Lock() + defer ri.mtx.Unlock() + return ri.reader.Read(b) +} + +func xorBytes32(bytesA [32]byte, bytesB [32]byte) (res [32]byte) { + for i, b := range bytesA { + res[i] = b ^ bytesB[i] + } + return res +} diff --git a/signature_test.go b/signature_test.go index 6a803b697..e4e72e48d 100644 --- a/signature_test.go +++ b/signature_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/tendermint/ed25519" - . "github.com/tendermint/go-common" "github.com/tendermint/go-wire" ) From f59fe0c8e0b45a2f7aca9ed3e4f18427a3493766 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sun, 13 Mar 2016 10:14:24 -0700 Subject: [PATCH 009/287] s/Seed/MixEntropy/g --- random.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/random.go b/random.go index 803386843..edadeaab6 100644 --- a/random.go +++ b/random.go @@ -15,13 +15,13 @@ var gRandInfo *randInfo func init() { gRandInfo = &randInfo{} - gRandInfo.AddSeed(randBytes(32)) // Init + gRandInfo.MixEntropy(randBytes(32)) // Init } -// Add additional bytes of randomness, e.g. from hardware, user-input, etc. -// It is OK to call it multiple times. It does not deminish security. -func Seed(seedBytes []byte) { - gRandInfo.AddSeed(seedBytes) +// Mix additional bytes of randomness, e.g. from hardware, user-input, etc. +// It is OK to call it multiple times. It does not diminish security. +func MixEntropy(seedBytes []byte) { + gRandInfo.MixEntropy(seedBytes) } // This only uses the OS's randomness @@ -66,7 +66,7 @@ type randInfo struct { // You can call this as many times as you'd like. // XXX TODO review -func (ri *randInfo) AddSeed(seedBytes []byte) { +func (ri *randInfo) MixEntropy(seedBytes []byte) { ri.mtx.Lock() defer ri.mtx.Unlock() // Make new ri.seedBytes From 181aa56c8711c9dc40eb7d2f2b259b0d1ed5240e Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sun, 13 Mar 2016 12:55:02 -0700 Subject: [PATCH 010/287] Added symmetric encrypt/decrypt methods --- encrypt.go | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ encrypt_test.go | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 encrypt.go create mode 100644 encrypt_test.go diff --git a/encrypt.go b/encrypt.go new file mode 100644 index 000000000..36bddd44c --- /dev/null +++ b/encrypt.go @@ -0,0 +1,51 @@ +package crypto + +import ( + "errors" + + . "github.com/tendermint/go-common" + "golang.org/x/crypto/nacl/secretbox" +) + +const nonceLen = 24 +const secretLen = 32 + +// secret must be 32 bytes long. Use something like Sha256(Bcrypt(passphrase)) +// The ciphertext is (secretbox.Overhead + 24) bytes longer than the plaintext. +// NOTE: call crypto.MixEntropy() first. +func EncryptSymmetric(plaintext []byte, secret []byte) (ciphertext []byte) { + if len(secret) != secretLen { + PanicSanity(Fmt("Secret must be 32 bytes long, got len %v", len(secret))) + } + nonce := CRandBytes(nonceLen) + nonceArr := [nonceLen]byte{} + copy(nonceArr[:], nonce) + secretArr := [secretLen]byte{} + copy(secretArr[:], secret) + ciphertext = make([]byte, nonceLen+secretbox.Overhead+len(plaintext)) + copy(ciphertext, nonce) + secretbox.Seal(ciphertext[nonceLen:nonceLen], plaintext, &nonceArr, &secretArr) + return ciphertext +} + +// secret must be 32 bytes long. Use something like Sha256(Bcrypt(passphrase)) +// The ciphertext is (secretbox.Overhead + 24) bytes longer than the plaintext. +func DecryptSymmetric(ciphertext []byte, secret []byte) (plaintext []byte, err error) { + if len(secret) != secretLen { + PanicSanity(Fmt("Secret must be 32 bytes long, got len %v", len(secret))) + } + if len(ciphertext) <= secretbox.Overhead+nonceLen { + return nil, errors.New("Ciphertext is too short") + } + nonce := ciphertext[:nonceLen] + nonceArr := [nonceLen]byte{} + copy(nonceArr[:], nonce) + secretArr := [secretLen]byte{} + copy(secretArr[:], secret) + plaintext = make([]byte, len(ciphertext)-nonceLen-secretbox.Overhead) + _, ok := secretbox.Open(plaintext[:0], ciphertext[nonceLen:], &nonceArr, &secretArr) + if !ok { + return nil, errors.New("Ciphertext decryption failed") + } + return plaintext, nil +} diff --git a/encrypt_test.go b/encrypt_test.go new file mode 100644 index 000000000..f05c812b6 --- /dev/null +++ b/encrypt_test.go @@ -0,0 +1,51 @@ +package crypto + +import ( + "bytes" + "golang.org/x/crypto/bcrypt" + "testing" +) + +func TestSimple(t *testing.T) { + + MixEntropy([]byte("someentropy")) + + plaintext := []byte("sometext") + secret := []byte("somesecretoflengththirtytwo===32") + ciphertext := EncryptSymmetric(plaintext, secret) + + plaintext2, err := DecryptSymmetric(ciphertext, secret) + if err != nil { + t.Error(err) + } + + if !bytes.Equal(plaintext, plaintext2) { + t.Errorf("Decrypted plaintext was %X, expected %X", plaintext2, plaintext) + } + +} + +func TestSimpleWithKDF(t *testing.T) { + + MixEntropy([]byte("someentropy")) + + plaintext := []byte("sometext") + secretPass := []byte("somesecret") + secret, err := bcrypt.GenerateFromPassword(secretPass, 12) + if err != nil { + t.Error(err) + } + secret = Sha256(secret) + + ciphertext := EncryptSymmetric(plaintext, secret) + + plaintext2, err := DecryptSymmetric(ciphertext, secret) + if err != nil { + t.Error(err) + } + + if !bytes.Equal(plaintext, plaintext2) { + t.Errorf("Decrypted plaintext was %X, expected %X", plaintext2, plaintext) + } + +} From 185547efc1fe6e03fe22fcc2c00d001df8832071 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sun, 13 Mar 2016 14:00:27 -0700 Subject: [PATCH 011/287] Add ascii armor support --- armor.go | 39 ++++++++++++++++++++++++++++ armor_test.go | 25 ++++++++++++++++++ encrypt.go => symmetric.go | 0 encrypt_test.go => symmetric_test.go | 3 ++- 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 armor.go create mode 100644 armor_test.go rename encrypt.go => symmetric.go (100%) rename encrypt_test.go => symmetric_test.go (99%) diff --git a/armor.go b/armor.go new file mode 100644 index 000000000..9343284e1 --- /dev/null +++ b/armor.go @@ -0,0 +1,39 @@ +package crypto + +import ( + "bytes" + "io/ioutil" + + . "github.com/tendermint/go-common" + "golang.org/x/crypto/openpgp/armor" +) + +func EncodeArmor(blockType string, headers map[string]string, data []byte) string { + buf := new(bytes.Buffer) + w, err := armor.Encode(buf, blockType, headers) + if err != nil { + PanicSanity("Error encoding ascii armor: " + err.Error()) + } + _, err = w.Write(data) + if err != nil { + PanicSanity("Error encoding ascii armor: " + err.Error()) + } + err = w.Close() + if err != nil { + PanicSanity("Error encoding ascii armor: " + err.Error()) + } + return string(buf.Bytes()) +} + +func DecodeArmor(armorStr string) (blockType string, headers map[string]string, data []byte, err error) { + buf := bytes.NewBufferString(armorStr) + block, err := armor.Decode(buf) + if err != nil { + return "", nil, nil, err + } + data, err = ioutil.ReadAll(block.Body) + if err != nil { + return "", nil, nil, err + } + return block.Type, block.Header, data, nil +} diff --git a/armor_test.go b/armor_test.go new file mode 100644 index 000000000..3de37d7bc --- /dev/null +++ b/armor_test.go @@ -0,0 +1,25 @@ +package crypto + +import ( + "bytes" + "testing" +) + +func TestSimpleArmor(t *testing.T) { + blockType := "MINT TEST" + data := []byte("somedata") + armorStr := EncodeArmor(blockType, nil, data) + t.Log("Got armor: ", armorStr) + + // Decode armorStr and test for equivalence. + blockType2, _, data2, err := DecodeArmor(armorStr) + if err != nil { + t.Error(err) + } + if blockType != blockType2 { + t.Errorf("Expected block type %v but got %v", blockType, blockType2) + } + if !bytes.Equal(data, data2) { + t.Errorf("Expected data %X but got %X", data2, data) + } +} diff --git a/encrypt.go b/symmetric.go similarity index 100% rename from encrypt.go rename to symmetric.go diff --git a/encrypt_test.go b/symmetric_test.go similarity index 99% rename from encrypt_test.go rename to symmetric_test.go index f05c812b6..c8134742d 100644 --- a/encrypt_test.go +++ b/symmetric_test.go @@ -2,8 +2,9 @@ package crypto import ( "bytes" - "golang.org/x/crypto/bcrypt" "testing" + + "golang.org/x/crypto/bcrypt" ) func TestSimple(t *testing.T) { From 9a95e7b7a559340495c049a756804981b68a70a2 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Tue, 15 Mar 2016 11:11:54 -0700 Subject: [PATCH 012/287] Added Bytes() and *FromBytes() --- priv_key.go | 16 ++++++++++++++-- pub_key.go | 24 ++++++++++++------------ 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/priv_key.go b/priv_key.go index 5e93fbe11..e9b43caa0 100644 --- a/priv_key.go +++ b/priv_key.go @@ -9,6 +9,7 @@ import ( // PrivKey is part of PrivAccount and state.PrivValidator. type PrivKey interface { + Bytes() []byte Sign(msg []byte) Signature PubKey() PubKey } @@ -24,11 +25,20 @@ var _ = wire.RegisterInterface( wire.ConcreteType{PrivKeyEd25519{}, PrivKeyTypeEd25519}, ) +func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { + err = wire.ReadBinaryBytes(privKeyBytes, &privKey) + return +} + //------------------------------------- // Implements PrivKey type PrivKeyEd25519 [64]byte +func (privKey PrivKeyEd25519) Bytes() []byte { + return wire.BinaryBytes(struct{ PrivKey }{privKey}) +} + func (key PrivKeyEd25519) Sign(msg []byte) Signature { privKeyBytes := [64]byte(key) signatureBytes := ed25519.Sign(&privKeyBytes, msg) @@ -69,8 +79,10 @@ func GenPrivKeyEd25519() PrivKeyEd25519 { return PrivKeyEd25519(*privKeyBytes) } -func GenPrivKeyEd25519FromSecret(secret string) PrivKeyEd25519 { - privKey32 := wire.BinarySha256(secret) // Not Ripemd160 because we want 32 bytes. +// NOTE: secret should be the output of a KDF like bcrypt, +// if it's derived from user input. +func GenPrivKeyEd25519FromSecret(secret []byte) PrivKeyEd25519 { + privKey32 := Sha256(secret) // Not Ripemd160 because we want 32 bytes. privKeyBytes := new([64]byte) copy(privKeyBytes[:32], privKey32) ed25519.MakePublicKey(privKeyBytes) diff --git a/pub_key.go b/pub_key.go index 4cfe815ce..b9500741e 100644 --- a/pub_key.go +++ b/pub_key.go @@ -13,6 +13,7 @@ import ( // PubKey is part of Account and Validator. type PubKey interface { Address() []byte + Bytes() []byte KeyString() string VerifyBytes(msg []byte, sig Signature) bool Equals(PubKey) bool @@ -29,28 +30,27 @@ var _ = wire.RegisterInterface( wire.ConcreteType{PubKeyEd25519{}, PubKeyTypeEd25519}, ) +func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { + err = wire.ReadBinaryBytes(pubKeyBytes, &pubKey) + return +} + //------------------------------------- // Implements PubKey type PubKeyEd25519 [32]byte -// TODO: Slicing the array gives us length prefixing but loses the type byte. -// Revisit if we add more pubkey types. -// For now, we artificially append the type byte in front to give us backwards -// compatibility for when the pubkey wasn't fixed length array func (pubKey PubKeyEd25519) Address() []byte { - w, n, err := new(bytes.Buffer), new(int), new(error) - wire.WriteBinary(pubKey[:], w, n, err) - if *err != nil { - PanicCrisis(*err) - } - // append type byte - encodedPubkey := append([]byte{1}, w.Bytes()...) + pubKeyBytes := pubKey.Bytes() hasher := ripemd160.New() - hasher.Write(encodedPubkey) // does not error + hasher.Write(pubKeyBytes) // does not error return hasher.Sum(nil) } +func (pubKey PubKeyEd25519) Bytes() []byte { + return wire.BinaryBytes(struct{ PubKey }{pubKey}) +} + // TODO: Consider returning a reason for failure, or logging a runtime type mismatch. func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool { sig, ok := sig_.(SignatureEd25519) From 8152c18c355bb17e38292d9473e71d7998a72a43 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Tue, 15 Mar 2016 15:58:43 -0700 Subject: [PATCH 013/287] Revert Address() scheme change --- pub_key.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pub_key.go b/pub_key.go index b9500741e..6da13077f 100644 --- a/pub_key.go +++ b/pub_key.go @@ -41,9 +41,15 @@ func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { type PubKeyEd25519 [32]byte func (pubKey PubKeyEd25519) Address() []byte { - pubKeyBytes := pubKey.Bytes() + w, n, err := new(bytes.Buffer), new(int), new(error) + wire.WriteBinary(pubKey[:], w, n, err) + if *err != nil { + PanicCrisis(*err) + } + // append type byte + encodedPubkey := append([]byte{1}, w.Bytes()...) hasher := ripemd160.New() - hasher.Write(pubKeyBytes) // does not error + hasher.Write(encodedPubkey) // does not error return hasher.Sum(nil) } From eddde7f46aa3a02191c829149f83c09048c874cb Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Thu, 17 Mar 2016 20:37:30 -0700 Subject: [PATCH 014/287] Added customized bcrypt --- bcrypt/base64.go | 35 ++++++ bcrypt/bcrypt.go | 292 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 327 insertions(+) create mode 100644 bcrypt/base64.go create mode 100644 bcrypt/bcrypt.go diff --git a/bcrypt/base64.go b/bcrypt/base64.go new file mode 100644 index 000000000..fc3116090 --- /dev/null +++ b/bcrypt/base64.go @@ -0,0 +1,35 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bcrypt + +import "encoding/base64" + +const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" + +var bcEncoding = base64.NewEncoding(alphabet) + +func base64Encode(src []byte) []byte { + n := bcEncoding.EncodedLen(len(src)) + dst := make([]byte, n) + bcEncoding.Encode(dst, src) + for dst[n-1] == '=' { + n-- + } + return dst[:n] +} + +func base64Decode(src []byte) ([]byte, error) { + numOfEquals := 4 - (len(src) % 4) + for i := 0; i < numOfEquals; i++ { + src = append(src, '=') + } + + dst := make([]byte, bcEncoding.DecodedLen(len(src))) + n, err := bcEncoding.Decode(dst, src) + if err != nil { + return nil, err + } + return dst[:n], nil +} diff --git a/bcrypt/bcrypt.go b/bcrypt/bcrypt.go new file mode 100644 index 000000000..a6b4a2cf6 --- /dev/null +++ b/bcrypt/bcrypt.go @@ -0,0 +1,292 @@ +package bcrypt + +// MODIFIED BY TENDERMINT TO EXPOSE NONCE +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package bcrypt implements Provos and Mazières's bcrypt adaptive hashing +// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf + +// The code is a port of Provos and Mazières's C implementation. +import ( + "crypto/subtle" + "errors" + "fmt" + "strconv" + + "golang.org/x/crypto/blowfish" +) + +const ( + MinCost int = 4 // the minimum allowable cost as passed in to GenerateFromPassword + MaxCost int = 31 // the maximum allowable cost as passed in to GenerateFromPassword + DefaultCost int = 10 // the cost that will actually be set if a cost below MinCost is passed into GenerateFromPassword +) + +// The error returned from CompareHashAndPassword when a password and hash do +// not match. +var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password") + +// The error returned from CompareHashAndPassword when a hash is too short to +// be a bcrypt hash. +var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password") + +// The error returned from CompareHashAndPassword when a hash was created with +// a bcrypt algorithm newer than this implementation. +type HashVersionTooNewError byte + +func (hv HashVersionTooNewError) Error() string { + return fmt.Sprintf("crypto/bcrypt: bcrypt algorithm version '%c' requested is newer than current version '%c'", byte(hv), majorVersion) +} + +// The error returned from CompareHashAndPassword when a hash starts with something other than '$' +type InvalidHashPrefixError byte + +func (ih InvalidHashPrefixError) Error() string { + return fmt.Sprintf("crypto/bcrypt: bcrypt hashes must start with '$', but hashedSecret started with '%c'", byte(ih)) +} + +type InvalidCostError int + +func (ic InvalidCostError) Error() string { + return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost)) +} + +const ( + majorVersion = '2' + minorVersion = 'a' + maxSaltSize = 16 + maxCryptedHashSize = 23 + encodedSaltSize = 22 + encodedHashSize = 31 + minHashSize = 59 +) + +// magicCipherData is an IV for the 64 Blowfish encryption calls in +// bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes. +var magicCipherData = []byte{ + 0x4f, 0x72, 0x70, 0x68, + 0x65, 0x61, 0x6e, 0x42, + 0x65, 0x68, 0x6f, 0x6c, + 0x64, 0x65, 0x72, 0x53, + 0x63, 0x72, 0x79, 0x44, + 0x6f, 0x75, 0x62, 0x74, +} + +type hashed struct { + hash []byte + salt []byte + cost int // allowed range is MinCost to MaxCost + major byte + minor byte +} + +// GenerateFromPassword returns the bcrypt hash of the password at the given +// cost. If the cost given is less than MinCost, the cost will be set to +// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package, +// to compare the returned hashed password with its cleartext version. +func GenerateFromPassword(salt []byte, password []byte, cost int) ([]byte, error) { + if len(salt) != maxSaltSize { + return nil, fmt.Errorf("Salt len must be %v", maxSaltSize) + } + p, err := newFromPassword(salt, password, cost) + if err != nil { + return nil, err + } + return p.Hash(), nil +} + +// CompareHashAndPassword compares a bcrypt hashed password with its possible +// plaintext equivalent. Returns nil on success, or an error on failure. +func CompareHashAndPassword(hashedPassword, password []byte) error { + p, err := newFromHash(hashedPassword) + if err != nil { + return err + } + + otherHash, err := bcrypt(password, p.cost, p.salt) + if err != nil { + return err + } + + otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor} + if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 { + return nil + } + + return ErrMismatchedHashAndPassword +} + +// Cost returns the hashing cost used to create the given hashed +// password. When, in the future, the hashing cost of a password system needs +// to be increased in order to adjust for greater computational power, this +// function allows one to establish which passwords need to be updated. +func Cost(hashedPassword []byte) (int, error) { + p, err := newFromHash(hashedPassword) + if err != nil { + return 0, err + } + return p.cost, nil +} + +func newFromPassword(salt []byte, password []byte, cost int) (*hashed, error) { + if cost < MinCost { + cost = DefaultCost + } + p := new(hashed) + p.major = majorVersion + p.minor = minorVersion + + err := checkCost(cost) + if err != nil { + return nil, err + } + p.cost = cost + + p.salt = base64Encode(salt) + hash, err := bcrypt(password, p.cost, p.salt) + if err != nil { + return nil, err + } + p.hash = hash + return p, err +} + +func newFromHash(hashedSecret []byte) (*hashed, error) { + if len(hashedSecret) < minHashSize { + return nil, ErrHashTooShort + } + p := new(hashed) + n, err := p.decodeVersion(hashedSecret) + if err != nil { + return nil, err + } + hashedSecret = hashedSecret[n:] + n, err = p.decodeCost(hashedSecret) + if err != nil { + return nil, err + } + hashedSecret = hashedSecret[n:] + + // The "+2" is here because we'll have to append at most 2 '=' to the salt + // when base64 decoding it in expensiveBlowfishSetup(). + p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2) + copy(p.salt, hashedSecret[:encodedSaltSize]) + + hashedSecret = hashedSecret[encodedSaltSize:] + p.hash = make([]byte, len(hashedSecret)) + copy(p.hash, hashedSecret) + + return p, nil +} + +func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) { + cipherData := make([]byte, len(magicCipherData)) + copy(cipherData, magicCipherData) + + c, err := expensiveBlowfishSetup(password, uint32(cost), salt) + if err != nil { + return nil, err + } + + for i := 0; i < 24; i += 8 { + for j := 0; j < 64; j++ { + c.Encrypt(cipherData[i:i+8], cipherData[i:i+8]) + } + } + + // Bug compatibility with C bcrypt implementations. We only encode 23 of + // the 24 bytes encrypted. + hsh := base64Encode(cipherData[:maxCryptedHashSize]) + return hsh, nil +} + +func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) { + + csalt, err := base64Decode(salt) + if err != nil { + return nil, err + } + + // Bug compatibility with C bcrypt implementations. They use the trailing + // NULL in the key string during expansion. + ckey := append(key, 0) + + c, err := blowfish.NewSaltedCipher(ckey, csalt) + if err != nil { + return nil, err + } + + var i, rounds uint64 + rounds = 1 << cost + for i = 0; i < rounds; i++ { + blowfish.ExpandKey(ckey, c) + blowfish.ExpandKey(csalt, c) + } + + return c, nil +} + +func (p *hashed) Hash() []byte { + arr := make([]byte, 60) + arr[0] = '$' + arr[1] = p.major + n := 2 + if p.minor != 0 { + arr[2] = p.minor + n = 3 + } + arr[n] = '$' + n += 1 + copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost))) + n += 2 + arr[n] = '$' + n += 1 + copy(arr[n:], p.salt) + n += encodedSaltSize + copy(arr[n:], p.hash) + n += encodedHashSize + return arr[:n] +} + +func (p *hashed) decodeVersion(sbytes []byte) (int, error) { + if sbytes[0] != '$' { + return -1, InvalidHashPrefixError(sbytes[0]) + } + if sbytes[1] > majorVersion { + return -1, HashVersionTooNewError(sbytes[1]) + } + p.major = sbytes[1] + n := 3 + if sbytes[2] != '$' { + p.minor = sbytes[2] + n++ + } + return n, nil +} + +// sbytes should begin where decodeVersion left off. +func (p *hashed) decodeCost(sbytes []byte) (int, error) { + cost, err := strconv.Atoi(string(sbytes[0:2])) + if err != nil { + return -1, err + } + err = checkCost(cost) + if err != nil { + return -1, err + } + p.cost = cost + return 3, nil +} + +func (p *hashed) String() string { + return fmt.Sprintf("&{hash: %#v, salt: %#v, cost: %d, major: %c, minor: %c}", string(p.hash), p.salt, p.cost, p.major, p.minor) +} + +func checkCost(cost int) error { + if cost < MinCost || cost > MaxCost { + return InvalidCostError(cost) + } + return nil +} From 3f0d9b3f29f30e5d0cbc2cef04fa45e5a606c622 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Tue, 22 Mar 2016 15:21:18 -0700 Subject: [PATCH 015/287] Signature bytes --- signature.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/signature.go b/signature.go index 959258091..8eafab7cf 100644 --- a/signature.go +++ b/signature.go @@ -9,6 +9,7 @@ import ( // Signature is a part of Txs and consensus Votes. type Signature interface { + Bytes() []byte IsZero() bool String() string } @@ -29,6 +30,10 @@ var _ = wire.RegisterInterface( // Implements Signature type SignatureEd25519 [64]byte +func (sig SignatureEd25519) Bytes() []byte { + return wire.BinaryBytes(struct{ Signature }{sig}) +} + func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 } func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } From 8b34fd2e51ab2b5c368b81e4aa82f7bd2a0b5381 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Tue, 19 Apr 2016 01:02:31 -0700 Subject: [PATCH 016/287] Add secp256k1 support --- priv_key.go | 73 +++++++++++++++++++++++++++++++++++++++++++---- pub_key.go | 64 +++++++++++++++++++++++++++++++++++++++-- signature.go | 17 ++++++++++- signature_test.go | 59 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 202 insertions(+), 11 deletions(-) diff --git a/priv_key.go b/priv_key.go index e9b43caa0..2806e24f7 100644 --- a/priv_key.go +++ b/priv_key.go @@ -1,6 +1,7 @@ package crypto import ( + secp256k1 "github.com/btcsuite/btcd/btcec" "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" . "github.com/tendermint/go-common" @@ -16,13 +17,15 @@ type PrivKey interface { // Types of PrivKey implementations const ( - PrivKeyTypeEd25519 = byte(0x01) + PrivKeyTypeEd25519 = byte(0x01) + PrivKeyTypeSecp256k1 = byte(0x02) ) // for wire.readReflect var _ = wire.RegisterInterface( struct{ PrivKey }{}, wire.ConcreteType{PrivKeyEd25519{}, PrivKeyTypeEd25519}, + wire.ConcreteType{PrivKeySecp256k1{}, PrivKeyTypeSecp256k1}, ) func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { @@ -39,8 +42,8 @@ func (privKey PrivKeyEd25519) Bytes() []byte { return wire.BinaryBytes(struct{ PrivKey }{privKey}) } -func (key PrivKeyEd25519) Sign(msg []byte) Signature { - privKeyBytes := [64]byte(key) +func (privKey PrivKeyEd25519) Sign(msg []byte) Signature { + privKeyBytes := [64]byte(privKey) signatureBytes := ed25519.Sign(&privKeyBytes, msg) return SignatureEd25519(*signatureBytes) } @@ -62,11 +65,11 @@ func (privKey PrivKeyEd25519) String() string { } // Deterministically generates new priv-key bytes from key. -func (key PrivKeyEd25519) Generate(index int) PrivKeyEd25519 { +func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519 { newBytes := wire.BinarySha256(struct { PrivKey [64]byte Index int - }{key, index}) + }{privKey, index}) var newKey [64]byte copy(newKey[:], newBytes) return PrivKeyEd25519(newKey) @@ -88,3 +91,63 @@ func GenPrivKeyEd25519FromSecret(secret []byte) PrivKeyEd25519 { ed25519.MakePublicKey(privKeyBytes) return PrivKeyEd25519(*privKeyBytes) } + +//------------------------------------- + +// Implements PrivKey +type PrivKeySecp256k1 [32]byte + +func (privKey PrivKeySecp256k1) Bytes() []byte { + return wire.BinaryBytes(struct{ PrivKey }{privKey}) +} + +func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature { + priv__, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) + sig__, err := priv__.Sign(Sha256(msg)) + if err != nil { + PanicSanity(err) + } + return SignatureSecp256k1(sig__.Serialize()) +} + +func (privKey PrivKeySecp256k1) PubKey() PubKey { + _, pub__ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) + pub := [65]byte{} + copy(pub[:], pub__.SerializeUncompressed()) + return PubKeySecp256k1(pub) +} + +func (privKey PrivKeySecp256k1) String() string { + return Fmt("PrivKeySecp256k1{*****}") +} + +/* +// Deterministically generates new priv-key bytes from key. +func (key PrivKeySecp256k1) Generate(index int) PrivKeySecp256k1 { + newBytes := wire.BinarySha256(struct { + PrivKey [64]byte + Index int + }{key, index}) + var newKey [64]byte + copy(newKey[:], newBytes) + return PrivKeySecp256k1(newKey) +} +*/ + +func GenPrivKeySecp256k1() PrivKeySecp256k1 { + privKeyBytes := [32]byte{} + copy(privKeyBytes[:], CRandBytes(32)) + priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKeyBytes[:]) + copy(privKeyBytes[:], priv.Serialize()) + return PrivKeySecp256k1(privKeyBytes) +} + +// NOTE: secret should be the output of a KDF like bcrypt, +// if it's derived from user input. +func GenPrivKeySecp256k1FromSecret(secret []byte) PrivKeySecp256k1 { + privKey32 := Sha256(secret) // Not Ripemd160 because we want 32 bytes. + priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey32) + privKeyBytes := [32]byte{} + copy(privKeyBytes[:], priv.Serialize()) + return PrivKeySecp256k1(privKeyBytes) +} diff --git a/pub_key.go b/pub_key.go index 6da13077f..1162a1ef3 100644 --- a/pub_key.go +++ b/pub_key.go @@ -3,6 +3,7 @@ package crypto import ( "bytes" + secp256k1 "github.com/btcsuite/btcd/btcec" "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" . "github.com/tendermint/go-common" @@ -21,13 +22,15 @@ type PubKey interface { // Types of PubKey implementations const ( - PubKeyTypeEd25519 = byte(0x01) + PubKeyTypeEd25519 = byte(0x01) + PubKeyTypeSecp256k1 = byte(0x02) ) // for wire.readReflect var _ = wire.RegisterInterface( struct{ PubKey }{}, wire.ConcreteType{PubKeyEd25519{}, PubKeyTypeEd25519}, + wire.ConcreteType{PubKeySecp256k1{}, PubKeyTypeSecp256k1}, ) func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { @@ -47,7 +50,7 @@ func (pubKey PubKeyEd25519) Address() []byte { PanicCrisis(*err) } // append type byte - encodedPubkey := append([]byte{1}, w.Bytes()...) + encodedPubkey := append([]byte{PubKeyTypeEd25519}, w.Bytes()...) hasher := ripemd160.New() hasher.Write(encodedPubkey) // does not error return hasher.Sum(nil) @@ -57,7 +60,6 @@ func (pubKey PubKeyEd25519) Bytes() []byte { return wire.BinaryBytes(struct{ PubKey }{pubKey}) } -// TODO: Consider returning a reason for failure, or logging a runtime type mismatch. func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool { sig, ok := sig_.(SignatureEd25519) if !ok { @@ -96,3 +98,59 @@ func (pubKey PubKeyEd25519) Equals(other PubKey) bool { return false } } + +//------------------------------------- + +// Implements PubKey +type PubKeySecp256k1 [65]byte + +func (pubKey PubKeySecp256k1) Address() []byte { + w, n, err := new(bytes.Buffer), new(int), new(error) + wire.WriteBinary(pubKey[:], w, n, err) + if *err != nil { + PanicCrisis(*err) + } + // append type byte + encodedPubkey := append([]byte{PubKeyTypeSecp256k1}, w.Bytes()...) + hasher := ripemd160.New() + hasher.Write(encodedPubkey) // does not error + return hasher.Sum(nil) +} + +func (pubKey PubKeySecp256k1) Bytes() []byte { + return wire.BinaryBytes(struct{ PubKey }{pubKey}) +} + +func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool { + pub__, err := secp256k1.ParsePubKey(pubKey[:], secp256k1.S256()) + if err != nil { + return false + } + sig, ok := sig_.(SignatureSecp256k1) + if !ok { + return false + } + sig__, err := secp256k1.ParseDERSignature(sig[:], secp256k1.S256()) + if err != nil { + return false + } + return sig__.Verify(Sha256(msg), pub__) +} + +func (pubKey PubKeySecp256k1) String() string { + return Fmt("PubKeySecp256k1{%X}", pubKey[:]) +} + +// Must return the full bytes in hex. +// Used for map keying, etc. +func (pubKey PubKeySecp256k1) KeyString() string { + return Fmt("%X", pubKey[:]) +} + +func (pubKey PubKeySecp256k1) Equals(other PubKey) bool { + if otherEd, ok := other.(PubKeySecp256k1); ok { + return bytes.Equal(pubKey[:], otherEd[:]) + } else { + return false + } +} diff --git a/signature.go b/signature.go index 8eafab7cf..e4921ccf7 100644 --- a/signature.go +++ b/signature.go @@ -16,13 +16,15 @@ type Signature interface { // Types of Signature implementations const ( - SignatureTypeEd25519 = byte(0x01) + SignatureTypeEd25519 = byte(0x01) + SignatureTypeSecp256k1 = byte(0x02) ) // for wire.readReflect var _ = wire.RegisterInterface( struct{ Signature }{}, wire.ConcreteType{SignatureEd25519{}, SignatureTypeEd25519}, + wire.ConcreteType{SignatureSecp256k1{}, SignatureTypeSecp256k1}, ) //------------------------------------- @@ -37,3 +39,16 @@ func (sig SignatureEd25519) Bytes() []byte { func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 } func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } + +//------------------------------------- + +// Implements Signature +type SignatureSecp256k1 []byte + +func (sig SignatureSecp256k1) Bytes() []byte { + return wire.BinaryBytes(struct{ Signature }{sig}) +} + +func (sig SignatureSecp256k1) IsZero() bool { return len(sig) == 0 } + +func (sig SignatureSecp256k1) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } diff --git a/signature_test.go b/signature_test.go index e4e72e48d..88c490f39 100644 --- a/signature_test.go +++ b/signature_test.go @@ -8,7 +8,7 @@ import ( "github.com/tendermint/go-wire" ) -func TestSignAndValidate(t *testing.T) { +func TestSignAndValidateEd25519(t *testing.T) { privKey := GenPrivKeyEd25519() pubKey := privKey.PubKey() @@ -32,7 +32,31 @@ func TestSignAndValidate(t *testing.T) { } } -func TestBinaryDecode(t *testing.T) { +func TestSignAndValidateSecp256k1(t *testing.T) { + + privKey := GenPrivKeySecp256k1() + pubKey := privKey.PubKey() + + msg := CRandBytes(128) + sig := privKey.Sign(msg) + t.Logf("msg: %X, sig: %X", msg, sig) + + // Test the signature + if !pubKey.VerifyBytes(msg, sig) { + t.Errorf("Account message signature verification failed") + } + + // Mutate the signature, just one bit. + sigEd := sig.(SignatureSecp256k1) + sigEd[0] ^= byte(0x01) + sig = Signature(sigEd) + + if pubKey.VerifyBytes(msg, sig) { + t.Errorf("Account message signature verification should have failed but passed instead") + } +} + +func TestBinaryDecodeEd25519(t *testing.T) { privKey := GenPrivKeyEd25519() pubKey := privKey.PubKey() @@ -66,3 +90,34 @@ func TestBinaryDecode(t *testing.T) { t.Errorf("Account message signature verification failed") } } + +func TestBinaryDecodeSecp256k1(t *testing.T) { + + privKey := GenPrivKeySecp256k1() + pubKey := privKey.PubKey() + + msg := CRandBytes(128) + sig := privKey.Sign(msg) + t.Logf("msg: %X, sig: %X", msg, sig) + + buf, n, err := new(bytes.Buffer), new(int), new(error) + wire.WriteBinary(struct{ Signature }{sig}, buf, n, err) + if *err != nil { + t.Fatalf("Failed to write Signature: %v", err) + } + + if buf.Bytes()[0] != SignatureTypeSecp256k1 { + t.Fatalf("Unexpected signature type byte") + } + + sigStruct := struct{ Signature }{} + sig2 := wire.ReadBinary(sigStruct, buf, 0, n, err) + if *err != nil { + t.Fatalf("Failed to read Signature: %v", err) + } + + // Test the signature + if !pubKey.VerifyBytes(msg, sig2.(struct{ Signature }).Signature.(SignatureSecp256k1)) { + t.Errorf("Account message signature verification failed") + } +} From d57d5ff3c925149e62f3a3c3f6ecaf4c8250d678 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Tue, 19 Apr 2016 01:26:40 -0700 Subject: [PATCH 017/287] PrivKey.Equals --- priv_key.go | 19 +++++++++++++++++++ pub_key.go | 4 ++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/priv_key.go b/priv_key.go index 2806e24f7..42f932ba1 100644 --- a/priv_key.go +++ b/priv_key.go @@ -1,6 +1,8 @@ package crypto import ( + "bytes" + secp256k1 "github.com/btcsuite/btcd/btcec" "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" @@ -13,6 +15,7 @@ type PrivKey interface { Bytes() []byte Sign(msg []byte) Signature PubKey() PubKey + Equals(PrivKey) bool } // Types of PrivKey implementations @@ -53,6 +56,14 @@ func (privKey PrivKeyEd25519) PubKey() PubKey { return PubKeyEd25519(*ed25519.MakePublicKey(&privKeyBytes)) } +func (privKey PrivKeyEd25519) Equals(other PrivKey) bool { + if otherEd, ok := other.(PrivKeyEd25519); ok { + return bytes.Equal(privKey[:], otherEd[:]) + } else { + return false + } +} + func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte { keyCurve25519 := new([32]byte) privKeyBytes := [64]byte(privKey) @@ -117,6 +128,14 @@ func (privKey PrivKeySecp256k1) PubKey() PubKey { return PubKeySecp256k1(pub) } +func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool { + if otherSecp, ok := other.(PrivKeySecp256k1); ok { + return bytes.Equal(privKey[:], otherSecp[:]) + } else { + return false + } +} + func (privKey PrivKeySecp256k1) String() string { return Fmt("PrivKeySecp256k1{*****}") } diff --git a/pub_key.go b/pub_key.go index 1162a1ef3..de56c8122 100644 --- a/pub_key.go +++ b/pub_key.go @@ -148,8 +148,8 @@ func (pubKey PubKeySecp256k1) KeyString() string { } func (pubKey PubKeySecp256k1) Equals(other PubKey) bool { - if otherEd, ok := other.(PubKeySecp256k1); ok { - return bytes.Equal(pubKey[:], otherEd[:]) + if otherSecp, ok := other.(PubKeySecp256k1); ok { + return bytes.Equal(pubKey[:], otherSecp[:]) } else { return false } From c121163635a0a36ddfa242c737e13dbab5edb587 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Tue, 19 Apr 2016 08:49:41 -0700 Subject: [PATCH 018/287] ReadSignature* --- signature.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/signature.go b/signature.go index e4921ccf7..40f269f34 100644 --- a/signature.go +++ b/signature.go @@ -40,6 +40,15 @@ func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 } func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } +func ReadSignatureEd25519(bz []byte) (SignatureEd25519, error) { + sig := struct{ Signature }{} + err := wire.ReadBinaryBytes(bz, &sig) + if err != nil { + return SignatureEd25519{}, err + } + return sig.Signature.(SignatureEd25519), nil +} + //------------------------------------- // Implements Signature @@ -52,3 +61,12 @@ func (sig SignatureSecp256k1) Bytes() []byte { func (sig SignatureSecp256k1) IsZero() bool { return len(sig) == 0 } func (sig SignatureSecp256k1) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } + +func ReadSignatureSecp256k1(bz []byte) (SignatureSecp256k1, error) { + sig := struct{ Signature }{} + err := wire.ReadBinaryBytes(bz, &sig) + if err != nil { + return nil, err + } + return sig.Signature.(SignatureSecp256k1), nil +} From 7e767e95485d0907a694057103ebc018660a6573 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Wed, 20 Apr 2016 08:46:07 -0700 Subject: [PATCH 019/287] Secp256k1 pubkeys are 64 bytes. Strip btcec prefix byte --- priv_key.go | 4 ++-- pub_key.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/priv_key.go b/priv_key.go index 42f932ba1..8b7dc117f 100644 --- a/priv_key.go +++ b/priv_key.go @@ -123,8 +123,8 @@ func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature { func (privKey PrivKeySecp256k1) PubKey() PubKey { _, pub__ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) - pub := [65]byte{} - copy(pub[:], pub__.SerializeUncompressed()) + pub := [64]byte{} + copy(pub[:], pub__.SerializeUncompressed()[1:]) return PubKeySecp256k1(pub) } diff --git a/pub_key.go b/pub_key.go index de56c8122..a3a259795 100644 --- a/pub_key.go +++ b/pub_key.go @@ -102,7 +102,7 @@ func (pubKey PubKeyEd25519) Equals(other PubKey) bool { //------------------------------------- // Implements PubKey -type PubKeySecp256k1 [65]byte +type PubKeySecp256k1 [64]byte func (pubKey PubKeySecp256k1) Address() []byte { w, n, err := new(bytes.Buffer), new(int), new(error) @@ -122,7 +122,7 @@ func (pubKey PubKeySecp256k1) Bytes() []byte { } func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool { - pub__, err := secp256k1.ParsePubKey(pubKey[:], secp256k1.S256()) + pub__, err := secp256k1.ParsePubKey(append([]byte{0x04}, pubKey[:]...), secp256k1.S256()) if err != nil { return false } From 41cfb7b677f4e16cdfd22b6ce0946c89919fbc7b Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Thu, 21 Apr 2016 18:05:15 -0700 Subject: [PATCH 020/287] Remove ReadSignature* methods --- signature.go | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/signature.go b/signature.go index 40f269f34..bb4a2e327 100644 --- a/signature.go +++ b/signature.go @@ -27,6 +27,11 @@ var _ = wire.RegisterInterface( wire.ConcreteType{SignatureSecp256k1{}, SignatureTypeSecp256k1}, ) +func SignatureFromBytes(sigBytes []byte) (sig Signature, err error) { + err = wire.ReadBinaryBytes(sigBytes, &sig) + return +} + //------------------------------------- // Implements Signature @@ -40,15 +45,6 @@ func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 } func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } -func ReadSignatureEd25519(bz []byte) (SignatureEd25519, error) { - sig := struct{ Signature }{} - err := wire.ReadBinaryBytes(bz, &sig) - if err != nil { - return SignatureEd25519{}, err - } - return sig.Signature.(SignatureEd25519), nil -} - //------------------------------------- // Implements Signature @@ -61,12 +57,3 @@ func (sig SignatureSecp256k1) Bytes() []byte { func (sig SignatureSecp256k1) IsZero() bool { return len(sig) == 0 } func (sig SignatureSecp256k1) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } - -func ReadSignatureSecp256k1(bz []byte) (SignatureSecp256k1, error) { - sig := struct{ Signature }{} - err := wire.ReadBinaryBytes(bz, &sig) - if err != nil { - return nil, err - } - return sig.Signature.(SignatureSecp256k1), nil -} From 4b11d62bdb324027ea01554e5767b71174680ba0 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sun, 24 Jul 2016 13:21:57 -0700 Subject: [PATCH 021/287] Add Signature.Equals --- signature.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/signature.go b/signature.go index bb4a2e327..b0049da8d 100644 --- a/signature.go +++ b/signature.go @@ -1,6 +1,7 @@ package crypto import ( + "bytes" "fmt" . "github.com/tendermint/go-common" @@ -12,6 +13,7 @@ type Signature interface { Bytes() []byte IsZero() bool String() string + Equals(Signature) bool } // Types of Signature implementations @@ -45,6 +47,14 @@ func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 } func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } +func (sig SignatureEd25519) Equals(other Signature) bool { + if otherEd, ok := other.(SignatureEd25519); ok { + return bytes.Equal(sig[:], otherEd[:]) + } else { + return false + } +} + //------------------------------------- // Implements Signature @@ -57,3 +67,11 @@ func (sig SignatureSecp256k1) Bytes() []byte { func (sig SignatureSecp256k1) IsZero() bool { return len(sig) == 0 } func (sig SignatureSecp256k1) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } + +func (sig SignatureSecp256k1) Equals(other Signature) bool { + if otherEd, ok := other.(SignatureSecp256k1); ok { + return bytes.Equal(sig[:], otherEd[:]) + } else { + return false + } +} From e6d35ee6416f0e234ae39ce01aab5922b7ff3b5d Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 22 Feb 2017 23:15:10 +0100 Subject: [PATCH 022/287] Add structs for go-data support --- Makefile | 9 +++++++++ priv_key.go | 56 ++++++++++++++++++++++++++++++++++++++++++++++------ pub_key.go | 56 ++++++++++++++++++++++++++++++++++++++++++++++------ signature.go | 47 ++++++++++++++++++++++++++++++++++++------- 4 files changed, 149 insertions(+), 19 deletions(-) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..0cd05448a --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +.PHONY: docs +REPO:=github.com/tendermint/go-crypto + +docs: + @go get github.com/davecheney/godoc2md + godoc2md $(REPO) > README.md + +test: + go test ./... diff --git a/priv_key.go b/priv_key.go index 8b7dc117f..ac4760c7c 100644 --- a/priv_key.go +++ b/priv_key.go @@ -7,6 +7,7 @@ import ( "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" . "github.com/tendermint/go-common" + data "github.com/tendermint/go-data" "github.com/tendermint/go-wire" ) @@ -22,14 +23,35 @@ type PrivKey interface { const ( PrivKeyTypeEd25519 = byte(0x01) PrivKeyTypeSecp256k1 = byte(0x02) + PrivKeyNameEd25519 = "ed25519" + PrivKeyNameSecp256k1 = "secp256k1" ) -// for wire.readReflect -var _ = wire.RegisterInterface( - struct{ PrivKey }{}, - wire.ConcreteType{PrivKeyEd25519{}, PrivKeyTypeEd25519}, - wire.ConcreteType{PrivKeySecp256k1{}, PrivKeyTypeSecp256k1}, -) +var privKeyMapper data.Mapper + +// register both private key types with go-data (and thus go-wire) +func init() { + privKeyMapper = data.NewMapper(PrivKeyS{}). + RegisterInterface(PrivKeyEd25519{}, PrivKeyNameEd25519, PrivKeyTypeEd25519). + RegisterInterface(PrivKeySecp256k1{}, PrivKeyNameSecp256k1, PrivKeyTypeSecp256k1) +} + +// PrivKeyS add json serialization to PrivKey +type PrivKeyS struct { + PrivKey +} + +func (p PrivKeyS) MarshalJSON() ([]byte, error) { + return privKeyMapper.ToJSON(p.PrivKey) +} + +func (p *PrivKeyS) UnmarshalJSON(data []byte) (err error) { + parsed, err := privKeyMapper.FromJSON(data) + if err == nil { + p.PrivKey = parsed.(PrivKey) + } + return +} func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { err = wire.ReadBinaryBytes(privKeyBytes, &privKey) @@ -64,6 +86,17 @@ func (privKey PrivKeyEd25519) Equals(other PrivKey) bool { } } +func (p PrivKeyEd25519) MarshalJSON() ([]byte, error) { + return data.Encoder.Marshal(p[:]) +} + +func (p *PrivKeyEd25519) UnmarshalJSON(enc []byte) error { + var ref []byte + err := data.Encoder.Unmarshal(&ref, enc) + copy(p[:], ref) + return err +} + func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte { keyCurve25519 := new([32]byte) privKeyBytes := [64]byte(privKey) @@ -136,6 +169,17 @@ func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool { } } +func (p PrivKeySecp256k1) MarshalJSON() ([]byte, error) { + return data.Encoder.Marshal(p[:]) +} + +func (p *PrivKeySecp256k1) UnmarshalJSON(enc []byte) error { + var ref []byte + err := data.Encoder.Unmarshal(&ref, enc) + copy(p[:], ref) + return err +} + func (privKey PrivKeySecp256k1) String() string { return Fmt("PrivKeySecp256k1{*****}") } diff --git a/pub_key.go b/pub_key.go index a3a259795..54d1173eb 100644 --- a/pub_key.go +++ b/pub_key.go @@ -7,6 +7,7 @@ import ( "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" . "github.com/tendermint/go-common" + data "github.com/tendermint/go-data" "github.com/tendermint/go-wire" "golang.org/x/crypto/ripemd160" ) @@ -24,14 +25,35 @@ type PubKey interface { const ( PubKeyTypeEd25519 = byte(0x01) PubKeyTypeSecp256k1 = byte(0x02) + PubKeyNameEd25519 = "ed25519" + PubKeyNameSecp256k1 = "secp256k1" ) -// for wire.readReflect -var _ = wire.RegisterInterface( - struct{ PubKey }{}, - wire.ConcreteType{PubKeyEd25519{}, PubKeyTypeEd25519}, - wire.ConcreteType{PubKeySecp256k1{}, PubKeyTypeSecp256k1}, -) +var pubKeyMapper data.Mapper + +// register both public key types with go-data (and thus go-wire) +func init() { + pubKeyMapper = data.NewMapper(PubKeyS{}). + RegisterInterface(PubKeyEd25519{}, PubKeyNameEd25519, PubKeyTypeEd25519). + RegisterInterface(PubKeySecp256k1{}, PubKeyNameSecp256k1, PubKeyTypeSecp256k1) +} + +// PubKeyS add json serialization to PubKey +type PubKeyS struct { + PubKey +} + +func (p PubKeyS) MarshalJSON() ([]byte, error) { + return pubKeyMapper.ToJSON(p.PubKey) +} + +func (p *PubKeyS) UnmarshalJSON(data []byte) (err error) { + parsed, err := pubKeyMapper.FromJSON(data) + if err == nil { + p.PubKey = parsed.(PubKey) + } + return +} func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { err = wire.ReadBinaryBytes(pubKeyBytes, &pubKey) @@ -70,6 +92,17 @@ func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool { return ed25519.Verify(&pubKeyBytes, msg, &sigBytes) } +func (p PubKeyEd25519) MarshalJSON() ([]byte, error) { + return data.Encoder.Marshal(p[:]) +} + +func (p *PubKeyEd25519) UnmarshalJSON(enc []byte) error { + var ref []byte + err := data.Encoder.Unmarshal(&ref, enc) + copy(p[:], ref) + return err +} + // For use with golang/crypto/nacl/box // If error, returns nil. func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte { @@ -137,6 +170,17 @@ func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool { return sig__.Verify(Sha256(msg), pub__) } +func (p PubKeySecp256k1) MarshalJSON() ([]byte, error) { + return data.Encoder.Marshal(p[:]) +} + +func (p *PubKeySecp256k1) UnmarshalJSON(enc []byte) error { + var ref []byte + err := data.Encoder.Unmarshal(&ref, enc) + copy(p[:], ref) + return err +} + func (pubKey PubKeySecp256k1) String() string { return Fmt("PubKeySecp256k1{%X}", pubKey[:]) } diff --git a/signature.go b/signature.go index b0049da8d..3960088bd 100644 --- a/signature.go +++ b/signature.go @@ -5,6 +5,7 @@ import ( "fmt" . "github.com/tendermint/go-common" + data "github.com/tendermint/go-data" "github.com/tendermint/go-wire" ) @@ -20,14 +21,35 @@ type Signature interface { const ( SignatureTypeEd25519 = byte(0x01) SignatureTypeSecp256k1 = byte(0x02) + SignatureNameEd25519 = "ed25519" + SignatureNameSecp256k1 = "secp256k1" ) -// for wire.readReflect -var _ = wire.RegisterInterface( - struct{ Signature }{}, - wire.ConcreteType{SignatureEd25519{}, SignatureTypeEd25519}, - wire.ConcreteType{SignatureSecp256k1{}, SignatureTypeSecp256k1}, -) +var sigMapper data.Mapper + +// register both public key types with go-data (and thus go-wire) +func init() { + sigMapper = data.NewMapper(SignatureS{}). + RegisterInterface(SignatureEd25519{}, SignatureNameEd25519, SignatureTypeEd25519). + RegisterInterface(SignatureSecp256k1{}, SignatureNameSecp256k1, SignatureTypeSecp256k1) +} + +// SignatureS add json serialization to Signature +type SignatureS struct { + Signature +} + +func (p SignatureS) MarshalJSON() ([]byte, error) { + return sigMapper.ToJSON(p.Signature) +} + +func (p *SignatureS) UnmarshalJSON(data []byte) (err error) { + parsed, err := sigMapper.FromJSON(data) + if err == nil { + p.Signature = parsed.(Signature) + } + return +} func SignatureFromBytes(sigBytes []byte) (sig Signature, err error) { err = wire.ReadBinaryBytes(sigBytes, &sig) @@ -55,10 +77,21 @@ func (sig SignatureEd25519) Equals(other Signature) bool { } } +func (p SignatureEd25519) MarshalJSON() ([]byte, error) { + return data.Encoder.Marshal(p[:]) +} + +func (p *SignatureEd25519) UnmarshalJSON(enc []byte) error { + var ref []byte + err := data.Encoder.Unmarshal(&ref, enc) + copy(p[:], ref) + return err +} + //------------------------------------- // Implements Signature -type SignatureSecp256k1 []byte +type SignatureSecp256k1 data.Bytes func (sig SignatureSecp256k1) Bytes() []byte { return wire.BinaryBytes(struct{ Signature }{sig}) From 1bc1947e3f94e628778a38d36256bce8a66a6779 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 22 Feb 2017 23:43:26 +0100 Subject: [PATCH 023/287] First tests of go-data encoding --- pub_key.go | 17 +++++-- signature.go | 9 +++- signature_test.go | 121 ++++++++++++++++++++++------------------------ 3 files changed, 80 insertions(+), 67 deletions(-) diff --git a/pub_key.go b/pub_key.go index 54d1173eb..0c7f4663e 100644 --- a/pub_key.go +++ b/pub_key.go @@ -83,6 +83,11 @@ func (pubKey PubKeyEd25519) Bytes() []byte { } func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool { + // unwrap if needed + if wrap, ok := sig_.(SignatureS); ok { + sig_ = wrap.Signature + } + // make sure we use the same algorithm to sign sig, ok := sig_.(SignatureEd25519) if !ok { return false @@ -155,14 +160,20 @@ func (pubKey PubKeySecp256k1) Bytes() []byte { } func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool { - pub__, err := secp256k1.ParsePubKey(append([]byte{0x04}, pubKey[:]...), secp256k1.S256()) - if err != nil { - return false + // unwrap if needed + if wrap, ok := sig_.(SignatureS); ok { + sig_ = wrap.Signature } + // and assert same algorithm to sign and verify sig, ok := sig_.(SignatureSecp256k1) if !ok { return false } + + pub__, err := secp256k1.ParsePubKey(append([]byte{0x04}, pubKey[:]...), secp256k1.S256()) + if err != nil { + return false + } sig__, err := secp256k1.ParseDERSignature(sig[:], secp256k1.S256()) if err != nil { return false diff --git a/signature.go b/signature.go index 3960088bd..fcef20a43 100644 --- a/signature.go +++ b/signature.go @@ -91,7 +91,7 @@ func (p *SignatureEd25519) UnmarshalJSON(enc []byte) error { //------------------------------------- // Implements Signature -type SignatureSecp256k1 data.Bytes +type SignatureSecp256k1 []byte func (sig SignatureSecp256k1) Bytes() []byte { return wire.BinaryBytes(struct{ Signature }{sig}) @@ -108,3 +108,10 @@ func (sig SignatureSecp256k1) Equals(other Signature) bool { return false } } +func (p SignatureSecp256k1) MarshalJSON() ([]byte, error) { + return data.Encoder.Marshal(p) +} + +func (p *SignatureSecp256k1) UnmarshalJSON(enc []byte) error { + return data.Encoder.Unmarshal((*[]byte)(p), enc) +} diff --git a/signature_test.go b/signature_test.go index 88c490f39..ac631eac5 100644 --- a/signature_test.go +++ b/signature_test.go @@ -1,11 +1,14 @@ package crypto import ( - "bytes" + "fmt" + "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/tendermint/ed25519" - "github.com/tendermint/go-wire" + data "github.com/tendermint/go-data" ) func TestSignAndValidateEd25519(t *testing.T) { @@ -56,68 +59,60 @@ func TestSignAndValidateSecp256k1(t *testing.T) { } } -func TestBinaryDecodeEd25519(t *testing.T) { - - privKey := GenPrivKeyEd25519() - pubKey := privKey.PubKey() - - msg := CRandBytes(128) - sig := privKey.Sign(msg) - t.Logf("msg: %X, sig: %X", msg, sig) - - buf, n, err := new(bytes.Buffer), new(int), new(error) - wire.WriteBinary(struct{ Signature }{sig}, buf, n, err) - if *err != nil { - t.Fatalf("Failed to write Signature: %v", err) - } - - if len(buf.Bytes()) != ed25519.SignatureSize+1 { - // 1 byte TypeByte, 64 bytes signature bytes - t.Fatalf("Unexpected signature write size: %v", len(buf.Bytes())) - } - if buf.Bytes()[0] != SignatureTypeEd25519 { - t.Fatalf("Unexpected signature type byte") - } - - sigStruct := struct{ Signature }{} - sig2 := wire.ReadBinary(sigStruct, buf, 0, n, err) - if *err != nil { - t.Fatalf("Failed to read Signature: %v", err) - } - - // Test the signature - if !pubKey.VerifyBytes(msg, sig2.(struct{ Signature }).Signature.(SignatureEd25519)) { - t.Errorf("Account message signature verification failed") +func TestSignatureEncodings(t *testing.T) { + cases := []struct { + privKey PrivKeyS + sigSize int + sigType byte + sigName string + }{ + { + privKey: PrivKeyS{GenPrivKeyEd25519()}, + sigSize: ed25519.SignatureSize, + sigType: SignatureTypeEd25519, + sigName: SignatureNameEd25519, + }, + { + privKey: PrivKeyS{GenPrivKeySecp256k1()}, + sigSize: 0, // unknown + sigType: SignatureTypeSecp256k1, + sigName: SignatureNameSecp256k1, + }, } -} - -func TestBinaryDecodeSecp256k1(t *testing.T) { - - privKey := GenPrivKeySecp256k1() - pubKey := privKey.PubKey() - - msg := CRandBytes(128) - sig := privKey.Sign(msg) - t.Logf("msg: %X, sig: %X", msg, sig) - buf, n, err := new(bytes.Buffer), new(int), new(error) - wire.WriteBinary(struct{ Signature }{sig}, buf, n, err) - if *err != nil { - t.Fatalf("Failed to write Signature: %v", err) - } - - if buf.Bytes()[0] != SignatureTypeSecp256k1 { - t.Fatalf("Unexpected signature type byte") - } - - sigStruct := struct{ Signature }{} - sig2 := wire.ReadBinary(sigStruct, buf, 0, n, err) - if *err != nil { - t.Fatalf("Failed to read Signature: %v", err) - } - - // Test the signature - if !pubKey.VerifyBytes(msg, sig2.(struct{ Signature }).Signature.(SignatureSecp256k1)) { - t.Errorf("Account message signature verification failed") + for _, tc := range cases { + // note we embed them from the beginning.... + pubKey := PubKeyS{tc.privKey.PubKey()} + + msg := CRandBytes(128) + sig := SignatureS{tc.privKey.Sign(msg)} + + // store as wire + bin, err := data.ToWire(sig) + require.Nil(t, err, "%+v", err) + if tc.sigSize != 0 { + assert.Equal(t, tc.sigSize+1, len(bin)) + } + assert.Equal(t, tc.sigType, bin[0]) + + // and back + sig2 := SignatureS{} + err = data.FromWire(bin, &sig2) + require.Nil(t, err, "%+v", err) + assert.EqualValues(t, sig, sig2) + assert.True(t, pubKey.VerifyBytes(msg, sig2)) + + // store as json + js, err := data.ToJSON(sig) + require.Nil(t, err, "%+v", err) + assert.True(t, strings.Contains(string(js), tc.sigName)) + fmt.Println(string(js)) + + // and back + sig3 := SignatureS{} + err = data.FromJSON(js, &sig3) + require.Nil(t, err, "%+v", err) + assert.EqualValues(t, sig, sig3) + assert.True(t, pubKey.VerifyBytes(msg, sig3)) } } From 6c2bf8c24bcccbe4093b5cfb7fbe54427a527027 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 23 Feb 2017 13:20:30 +0100 Subject: [PATCH 024/287] Clean up test cases -> testify --- armor_test.go | 17 ++++++----------- signature_test.go | 27 +++++++++------------------ symmetric_test.go | 24 +++++++----------------- 3 files changed, 22 insertions(+), 46 deletions(-) diff --git a/armor_test.go b/armor_test.go index 3de37d7bc..5eae87c00 100644 --- a/armor_test.go +++ b/armor_test.go @@ -1,25 +1,20 @@ package crypto import ( - "bytes" "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSimpleArmor(t *testing.T) { blockType := "MINT TEST" data := []byte("somedata") armorStr := EncodeArmor(blockType, nil, data) - t.Log("Got armor: ", armorStr) // Decode armorStr and test for equivalence. blockType2, _, data2, err := DecodeArmor(armorStr) - if err != nil { - t.Error(err) - } - if blockType != blockType2 { - t.Errorf("Expected block type %v but got %v", blockType, blockType2) - } - if !bytes.Equal(data, data2) { - t.Errorf("Expected data %X but got %X", data2, data) - } + require.Nil(t, err, "%+v", err) + assert.Equal(t, blockType, blockType2) + assert.Equal(t, data, data2) } diff --git a/signature_test.go b/signature_test.go index ac631eac5..e0e30b780 100644 --- a/signature_test.go +++ b/signature_test.go @@ -1,7 +1,6 @@ package crypto import ( - "fmt" "strings" "testing" @@ -18,45 +17,33 @@ func TestSignAndValidateEd25519(t *testing.T) { msg := CRandBytes(128) sig := privKey.Sign(msg) - t.Logf("msg: %X, sig: %X", msg, sig) // Test the signature - if !pubKey.VerifyBytes(msg, sig) { - t.Errorf("Account message signature verification failed") - } + assert.True(t, pubKey.VerifyBytes(msg, sig)) // Mutate the signature, just one bit. sigEd := sig.(SignatureEd25519) sigEd[0] ^= byte(0x01) sig = Signature(sigEd) - if pubKey.VerifyBytes(msg, sig) { - t.Errorf("Account message signature verification should have failed but passed instead") - } + assert.False(t, pubKey.VerifyBytes(msg, sig)) } func TestSignAndValidateSecp256k1(t *testing.T) { - privKey := GenPrivKeySecp256k1() pubKey := privKey.PubKey() msg := CRandBytes(128) sig := privKey.Sign(msg) - t.Logf("msg: %X, sig: %X", msg, sig) - // Test the signature - if !pubKey.VerifyBytes(msg, sig) { - t.Errorf("Account message signature verification failed") - } + assert.True(t, pubKey.VerifyBytes(msg, sig)) // Mutate the signature, just one bit. sigEd := sig.(SignatureSecp256k1) sigEd[0] ^= byte(0x01) sig = Signature(sigEd) - if pubKey.VerifyBytes(msg, sig) { - t.Errorf("Account message signature verification should have failed but passed instead") - } + assert.False(t, pubKey.VerifyBytes(msg, sig)) } func TestSignatureEncodings(t *testing.T) { @@ -106,7 +93,6 @@ func TestSignatureEncodings(t *testing.T) { js, err := data.ToJSON(sig) require.Nil(t, err, "%+v", err) assert.True(t, strings.Contains(string(js), tc.sigName)) - fmt.Println(string(js)) // and back sig3 := SignatureS{} @@ -114,5 +100,10 @@ func TestSignatureEncodings(t *testing.T) { require.Nil(t, err, "%+v", err) assert.EqualValues(t, sig, sig3) assert.True(t, pubKey.VerifyBytes(msg, sig3)) + + // and make sure we can textify it + text, err := data.ToText(sig) + require.Nil(t, err, "%+v", err) + assert.True(t, strings.HasPrefix(text, tc.sigName)) } } diff --git a/symmetric_test.go b/symmetric_test.go index c8134742d..d92bff1aa 100644 --- a/symmetric_test.go +++ b/symmetric_test.go @@ -1,9 +1,11 @@ package crypto import ( - "bytes" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/crypto/bcrypt" ) @@ -14,16 +16,10 @@ func TestSimple(t *testing.T) { plaintext := []byte("sometext") secret := []byte("somesecretoflengththirtytwo===32") ciphertext := EncryptSymmetric(plaintext, secret) - plaintext2, err := DecryptSymmetric(ciphertext, secret) - if err != nil { - t.Error(err) - } - - if !bytes.Equal(plaintext, plaintext2) { - t.Errorf("Decrypted plaintext was %X, expected %X", plaintext2, plaintext) - } + require.Nil(t, err, "%+v", err) + assert.Equal(t, plaintext, plaintext2) } func TestSimpleWithKDF(t *testing.T) { @@ -39,14 +35,8 @@ func TestSimpleWithKDF(t *testing.T) { secret = Sha256(secret) ciphertext := EncryptSymmetric(plaintext, secret) - plaintext2, err := DecryptSymmetric(ciphertext, secret) - if err != nil { - t.Error(err) - } - - if !bytes.Equal(plaintext, plaintext2) { - t.Errorf("Decrypted plaintext was %X, expected %X", plaintext2, plaintext) - } + require.Nil(t, err, "%+v", err) + assert.Equal(t, plaintext, plaintext2) } From cbe35e07d1a40dde7245ef926bd47090bba914f7 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 23 Feb 2017 14:56:25 +0100 Subject: [PATCH 025/287] Add more tests for de/en-coding public and private keys --- encode_test.go | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 encode_test.go diff --git a/encode_test.go b/encode_test.go new file mode 100644 index 000000000..224f413c1 --- /dev/null +++ b/encode_test.go @@ -0,0 +1,88 @@ +package crypto + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + data "github.com/tendermint/go-data" +) + +type byter interface { + Bytes() []byte +} + +// go to wire encoding and back +func checkWire(t *testing.T, in byter, reader interface{}, typ byte) { + // test to and from binary + bin, err := data.ToWire(in) + require.Nil(t, err, "%+v", err) + assert.Equal(t, typ, bin[0]) + // make sure this is compatible with current (Bytes()) encoding + assert.Equal(t, in.Bytes(), bin) + + err = data.FromWire(bin, reader) + require.Nil(t, err, "%+v", err) +} + +// go to json encoding and back +func checkJSON(t *testing.T, in interface{}, reader interface{}, typ string) { + // test to and from binary + js, err := data.ToJSON(in) + require.Nil(t, err, "%+v", err) + styp := `"` + typ + `"` + assert.True(t, strings.Contains(string(js), styp)) + + err = data.FromJSON(js, reader) + require.Nil(t, err, "%+v", err) + + // also check text format + text, err := data.ToText(in) + require.Nil(t, err, "%+v", err) + parts := strings.Split(text, ":") + require.Equal(t, 2, len(parts)) + // make sure the first part is the typ string + assert.Equal(t, typ, parts[0]) + // and the data is also present in the json + assert.True(t, strings.Contains(string(js), parts[1])) +} + +func TestKeyEncodings(t *testing.T) { + cases := []struct { + privKey PrivKeyS + keyType byte + keyName string + }{ + { + privKey: PrivKeyS{GenPrivKeyEd25519()}, + keyType: PrivKeyTypeEd25519, + keyName: PrivKeyNameEd25519, + }, + { + privKey: PrivKeyS{GenPrivKeySecp256k1()}, + keyType: PrivKeyTypeSecp256k1, + keyName: PrivKeyNameSecp256k1, + }, + } + + for _, tc := range cases { + // check (de/en)codings of private key + priv2 := PrivKeyS{} + checkWire(t, tc.privKey, &priv2, tc.keyType) + assert.EqualValues(t, tc.privKey, priv2) + priv3 := PrivKeyS{} + checkJSON(t, tc.privKey, &priv3, tc.keyName) + assert.EqualValues(t, tc.privKey, priv3) + + // check (de/en)codings of public key + pubKey := PubKeyS{tc.privKey.PubKey()} + pub2 := PubKeyS{} + checkWire(t, pubKey, &pub2, tc.keyType) + assert.EqualValues(t, pubKey, pub2) + pub3 := PubKeyS{} + checkJSON(t, pubKey, &pub3, tc.keyName) + assert.EqualValues(t, pubKey, pub3) + } + +} From b6a2c5949f7ea1d064cbb9dc638eb0a3dca9af34 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 23 Feb 2017 15:35:04 +0100 Subject: [PATCH 026/287] Add helper methods for nil checks in structs --- priv_key.go | 4 ++++ pub_key.go | 4 ++++ signature.go | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/priv_key.go b/priv_key.go index ac4760c7c..60a82636d 100644 --- a/priv_key.go +++ b/priv_key.go @@ -53,6 +53,10 @@ func (p *PrivKeyS) UnmarshalJSON(data []byte) (err error) { return } +func (p PrivKeyS) Empty() bool { + return p.PrivKey == nil +} + func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { err = wire.ReadBinaryBytes(privKeyBytes, &privKey) return diff --git a/pub_key.go b/pub_key.go index 0c7f4663e..e5fe5209a 100644 --- a/pub_key.go +++ b/pub_key.go @@ -55,6 +55,10 @@ func (p *PubKeyS) UnmarshalJSON(data []byte) (err error) { return } +func (p PubKeyS) Empty() bool { + return p.PubKey == nil +} + func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { err = wire.ReadBinaryBytes(pubKeyBytes, &pubKey) return diff --git a/signature.go b/signature.go index fcef20a43..376a535d6 100644 --- a/signature.go +++ b/signature.go @@ -51,6 +51,10 @@ func (p *SignatureS) UnmarshalJSON(data []byte) (err error) { return } +func (p SignatureS) Empty() bool { + return p.Signature == nil +} + func SignatureFromBytes(sigBytes []byte) (sig Signature, err error) { err = wire.ReadBinaryBytes(sigBytes, &sig) return From 8c9b889ccfe1f891ce8ab36c843f15794ce8f30f Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 23 Feb 2017 18:11:20 +0100 Subject: [PATCH 027/287] Support json encode/decode for nil values in S structs --- encode_test.go | 24 ++++++++++++++++++++++++ priv_key.go | 2 +- pub_key.go | 2 +- signature.go | 2 +- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/encode_test.go b/encode_test.go index 224f413c1..8f2eebbaa 100644 --- a/encode_test.go +++ b/encode_test.go @@ -84,5 +84,29 @@ func TestKeyEncodings(t *testing.T) { checkJSON(t, pubKey, &pub3, tc.keyName) assert.EqualValues(t, pubKey, pub3) } +} + +func toFromJSON(t *testing.T, in interface{}, recvr interface{}) { + js, err := data.ToJSON(in) + require.Nil(t, err, "%+v", err) + err = data.FromJSON(js, recvr) + require.Nil(t, err, "%+v", err) +} + +func TestNilEncodings(t *testing.T) { + // make sure sigs are okay with nil + a, b := SignatureS{}, SignatureS{} + toFromJSON(t, a, &b) + assert.EqualValues(t, a, b) + + // make sure sigs are okay with nil + c, d := PubKeyS{}, PubKeyS{} + toFromJSON(t, c, &d) + assert.EqualValues(t, c, d) + + // make sure sigs are okay with nil + e, f := PrivKeyS{}, PrivKeyS{} + toFromJSON(t, e, &f) + assert.EqualValues(t, e, f) } diff --git a/priv_key.go b/priv_key.go index 60a82636d..81edfb3f6 100644 --- a/priv_key.go +++ b/priv_key.go @@ -47,7 +47,7 @@ func (p PrivKeyS) MarshalJSON() ([]byte, error) { func (p *PrivKeyS) UnmarshalJSON(data []byte) (err error) { parsed, err := privKeyMapper.FromJSON(data) - if err == nil { + if err == nil && parsed != nil { p.PrivKey = parsed.(PrivKey) } return diff --git a/pub_key.go b/pub_key.go index e5fe5209a..77ce74a97 100644 --- a/pub_key.go +++ b/pub_key.go @@ -49,7 +49,7 @@ func (p PubKeyS) MarshalJSON() ([]byte, error) { func (p *PubKeyS) UnmarshalJSON(data []byte) (err error) { parsed, err := pubKeyMapper.FromJSON(data) - if err == nil { + if err == nil && parsed != nil { p.PubKey = parsed.(PubKey) } return diff --git a/signature.go b/signature.go index 376a535d6..076358879 100644 --- a/signature.go +++ b/signature.go @@ -45,7 +45,7 @@ func (p SignatureS) MarshalJSON() ([]byte, error) { func (p *SignatureS) UnmarshalJSON(data []byte) (err error) { parsed, err := sigMapper.FromJSON(data) - if err == nil { + if err == nil && parsed != nil { p.Signature = parsed.(Signature) } return From 0e92dd5bb557c6530e906e414893f05dda66cf80 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Fri, 24 Feb 2017 00:31:43 +0100 Subject: [PATCH 028/287] One name, type byte per algorithm --- encode_test.go | 8 ++++---- priv_key.go | 14 +++++++------- pub_key.go | 16 ++++------------ signature.go | 12 ++---------- signature_test.go | 8 ++++---- 5 files changed, 21 insertions(+), 37 deletions(-) diff --git a/encode_test.go b/encode_test.go index 8f2eebbaa..977cc64cf 100644 --- a/encode_test.go +++ b/encode_test.go @@ -56,13 +56,13 @@ func TestKeyEncodings(t *testing.T) { }{ { privKey: PrivKeyS{GenPrivKeyEd25519()}, - keyType: PrivKeyTypeEd25519, - keyName: PrivKeyNameEd25519, + keyType: TypeEd25519, + keyName: NameEd25519, }, { privKey: PrivKeyS{GenPrivKeySecp256k1()}, - keyType: PrivKeyTypeSecp256k1, - keyName: PrivKeyNameSecp256k1, + keyType: TypeSecp256k1, + keyName: NameSecp256k1, }, } diff --git a/priv_key.go b/priv_key.go index 81edfb3f6..54fa36a3a 100644 --- a/priv_key.go +++ b/priv_key.go @@ -19,12 +19,12 @@ type PrivKey interface { Equals(PrivKey) bool } -// Types of PrivKey implementations +// Types of implementations const ( - PrivKeyTypeEd25519 = byte(0x01) - PrivKeyTypeSecp256k1 = byte(0x02) - PrivKeyNameEd25519 = "ed25519" - PrivKeyNameSecp256k1 = "secp256k1" + TypeEd25519 = byte(0x01) + TypeSecp256k1 = byte(0x02) + NameEd25519 = "ed25519" + NameSecp256k1 = "secp256k1" ) var privKeyMapper data.Mapper @@ -32,8 +32,8 @@ var privKeyMapper data.Mapper // register both private key types with go-data (and thus go-wire) func init() { privKeyMapper = data.NewMapper(PrivKeyS{}). - RegisterInterface(PrivKeyEd25519{}, PrivKeyNameEd25519, PrivKeyTypeEd25519). - RegisterInterface(PrivKeySecp256k1{}, PrivKeyNameSecp256k1, PrivKeyTypeSecp256k1) + RegisterInterface(PrivKeyEd25519{}, NameEd25519, TypeEd25519). + RegisterInterface(PrivKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) } // PrivKeyS add json serialization to PrivKey diff --git a/pub_key.go b/pub_key.go index 77ce74a97..9067a0363 100644 --- a/pub_key.go +++ b/pub_key.go @@ -21,21 +21,13 @@ type PubKey interface { Equals(PubKey) bool } -// Types of PubKey implementations -const ( - PubKeyTypeEd25519 = byte(0x01) - PubKeyTypeSecp256k1 = byte(0x02) - PubKeyNameEd25519 = "ed25519" - PubKeyNameSecp256k1 = "secp256k1" -) - var pubKeyMapper data.Mapper // register both public key types with go-data (and thus go-wire) func init() { pubKeyMapper = data.NewMapper(PubKeyS{}). - RegisterInterface(PubKeyEd25519{}, PubKeyNameEd25519, PubKeyTypeEd25519). - RegisterInterface(PubKeySecp256k1{}, PubKeyNameSecp256k1, PubKeyTypeSecp256k1) + RegisterInterface(PubKeyEd25519{}, NameEd25519, TypeEd25519). + RegisterInterface(PubKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) } // PubKeyS add json serialization to PubKey @@ -76,7 +68,7 @@ func (pubKey PubKeyEd25519) Address() []byte { PanicCrisis(*err) } // append type byte - encodedPubkey := append([]byte{PubKeyTypeEd25519}, w.Bytes()...) + encodedPubkey := append([]byte{TypeEd25519}, w.Bytes()...) hasher := ripemd160.New() hasher.Write(encodedPubkey) // does not error return hasher.Sum(nil) @@ -153,7 +145,7 @@ func (pubKey PubKeySecp256k1) Address() []byte { PanicCrisis(*err) } // append type byte - encodedPubkey := append([]byte{PubKeyTypeSecp256k1}, w.Bytes()...) + encodedPubkey := append([]byte{TypeSecp256k1}, w.Bytes()...) hasher := ripemd160.New() hasher.Write(encodedPubkey) // does not error return hasher.Sum(nil) diff --git a/signature.go b/signature.go index 076358879..b5fc36bf3 100644 --- a/signature.go +++ b/signature.go @@ -17,21 +17,13 @@ type Signature interface { Equals(Signature) bool } -// Types of Signature implementations -const ( - SignatureTypeEd25519 = byte(0x01) - SignatureTypeSecp256k1 = byte(0x02) - SignatureNameEd25519 = "ed25519" - SignatureNameSecp256k1 = "secp256k1" -) - var sigMapper data.Mapper // register both public key types with go-data (and thus go-wire) func init() { sigMapper = data.NewMapper(SignatureS{}). - RegisterInterface(SignatureEd25519{}, SignatureNameEd25519, SignatureTypeEd25519). - RegisterInterface(SignatureSecp256k1{}, SignatureNameSecp256k1, SignatureTypeSecp256k1) + RegisterInterface(SignatureEd25519{}, NameEd25519, TypeEd25519). + RegisterInterface(SignatureSecp256k1{}, NameSecp256k1, TypeSecp256k1) } // SignatureS add json serialization to Signature diff --git a/signature_test.go b/signature_test.go index e0e30b780..f6c8c37be 100644 --- a/signature_test.go +++ b/signature_test.go @@ -56,14 +56,14 @@ func TestSignatureEncodings(t *testing.T) { { privKey: PrivKeyS{GenPrivKeyEd25519()}, sigSize: ed25519.SignatureSize, - sigType: SignatureTypeEd25519, - sigName: SignatureNameEd25519, + sigType: TypeEd25519, + sigName: NameEd25519, }, { privKey: PrivKeyS{GenPrivKeySecp256k1()}, sigSize: 0, // unknown - sigType: SignatureTypeSecp256k1, - sigName: SignatureNameSecp256k1, + sigType: TypeSecp256k1, + sigName: NameSecp256k1, }, } From f80957ad3c78170a166180eb05f7ea9c674835a5 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Feb 2017 16:30:15 +0100 Subject: [PATCH 029/287] Basic cobra/viper cli framework --- LICENSE | 202 +++++++++++++++++++++++++++++++++++++++++++++++ cmd/keys/main.go | 21 +++++ cmd/list.go | 49 ++++++++++++ cmd/new.go | 49 ++++++++++++ cmd/root.go | 84 ++++++++++++++++++++ cmd/serve.go | 50 ++++++++++++ cmd/update.go | 39 +++++++++ keys.yaml | 2 + 8 files changed, 496 insertions(+) create mode 100644 LICENSE create mode 100644 cmd/keys/main.go create mode 100644 cmd/list.go create mode 100644 cmd/new.go create mode 100644 cmd/root.go create mode 100644 cmd/serve.go create mode 100644 cmd/update.go create mode 100644 keys.yaml diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/cmd/keys/main.go b/cmd/keys/main.go new file mode 100644 index 000000000..8c880ea03 --- /dev/null +++ b/cmd/keys/main.go @@ -0,0 +1,21 @@ +// Copyright © 2017 Ethan Frey +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import "github.com/tendermint/go-keys/cmd" + +func main() { + cmd.Execute() +} diff --git a/cmd/list.go b/cmd/list.go new file mode 100644 index 000000000..e2c8a7631 --- /dev/null +++ b/cmd/list.go @@ -0,0 +1,49 @@ +// Copyright © 2017 Ethan Frey +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +// listCmd represents the list command +var listCmd = &cobra.Command{ + Use: "list", + Short: "List all keys", + Long: `Return a list of all public keys stored by this key manager +along with their associated name and address.`, + Run: func(cmd *cobra.Command, args []string) { + // TODO: Work your own magic here + fmt.Println("list called") + fmt.Println(viper.Get("format")) + }, +} + +func init() { + RootCmd.AddCommand(listCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // listCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + listCmd.Flags().StringP("format", "f", "text", "Format to display (text|json)") +} diff --git a/cmd/new.go b/cmd/new.go new file mode 100644 index 000000000..40462e686 --- /dev/null +++ b/cmd/new.go @@ -0,0 +1,49 @@ +// Copyright © 2017 Ethan Frey +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +// newCmd represents the new command +var newCmd = &cobra.Command{ + Use: "new", + Short: "Create a new public/private key pair", + Long: `Add a public/private key pair to the key store. +The password muts be entered in the terminal and not +passed as a command line argument for security.`, + Run: func(cmd *cobra.Command, args []string) { + // TODO: Work your own magic here + fmt.Println("new called") + }, +} + +func init() { + RootCmd.AddCommand(newCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // newCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + // newCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + +} diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 000000000..896b7c666 --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,84 @@ +// Copyright © 2017 Ethan Frey +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "fmt" + "os" + "strings" + + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +var ( + rootDir string +) + +// RootCmd represents the base command when called without any subcommands +var RootCmd = &cobra.Command{ + Use: "keys", + Short: "Key manager for tendermint clients", + Long: `Keys allows you to manage your local keystore for tendermint. + +These keys may be in any format supported by go-crypto and can be +used by light-clients, full nodes, or any other application that +needs to sign with a private key.`, + PersistentPreRunE: bindFlags, + // Uncomment the following line if your bare application + // has an action associated with it: + // Run: func(cmd *cobra.Command, args []string) { }, +} + +// Execute adds all child commands to the root command sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + if err := RootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(-1) + } +} + +func init() { + cobra.OnInitialize(initEnv) + RootCmd.PersistentFlags().StringP("root", "r", os.ExpandEnv("$HOME/.tlc"), "root directory for config and data (default is $HOME/.tlc)") +} + +// initEnv sets to use ENV variables if set. +func initEnv() { + // env variables with TM prefix (eg. TM_ROOT) + viper.SetEnvPrefix("TM") + viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + viper.AutomaticEnv() +} + +func bindFlags(cmd *cobra.Command, args []string) error { + // cmd.Flags() includes flags from this command and all persistent flags from the parent + if err := viper.BindPFlags(cmd.Flags()); err != nil { + return err + } + + // rootDir is command line flag, env variable, or default $HOME/.tlc + rootDir = viper.GetString("root") + viper.SetConfigName("keys") // name of config file (without extension) + viper.AddConfigPath(rootDir) // search root directory + + // If a config file is found, read it in. + if err := viper.ReadInConfig(); err == nil { + fmt.Println("Using config file:", viper.ConfigFileUsed()) + } + + return nil +} diff --git a/cmd/serve.go b/cmd/serve.go new file mode 100644 index 000000000..06e923c7b --- /dev/null +++ b/cmd/serve.go @@ -0,0 +1,50 @@ +// Copyright © 2017 Ethan Frey +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +// serveCmd represents the serve command +var serveCmd = &cobra.Command{ + Use: "serve", + Short: "Run the key manager as an http server", + Long: `Launch an http server with a rest api to manage the +private keys much more in depth than the cli can perform. +In particular, this will allow you to sign transactions with +the private keys in the store.`, + Run: func(cmd *cobra.Command, args []string) { + // TODO: Work your own magic here + fmt.Println("serve called") + }, +} + +func init() { + RootCmd.AddCommand(serveCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // serveCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + // serveCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + +} diff --git a/cmd/update.go b/cmd/update.go new file mode 100644 index 000000000..c36bcf25a --- /dev/null +++ b/cmd/update.go @@ -0,0 +1,39 @@ +// Copyright © 2017 Ethan Frey +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +// updateCmd represents the update command +var updateCmd = &cobra.Command{ + Use: "update", + Short: "Change the password for a private key", + Long: `Change the password for a private key.`, + Run: func(cmd *cobra.Command, args []string) { + // TODO: Work your own magic here + fmt.Println(viper.Get("name")) + fmt.Println("update called") + }, +} + +func init() { + RootCmd.AddCommand(updateCmd) + updateCmd.Flags().StringP("name", "n", "", "Name of key to update") +} diff --git a/keys.yaml b/keys.yaml new file mode 100644 index 000000000..3aec88a7b --- /dev/null +++ b/keys.yaml @@ -0,0 +1,2 @@ +format: super +name: george From d979bfc49ea930134ddedba28eb087716f5c25f8 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Feb 2017 16:56:17 +0100 Subject: [PATCH 030/287] Add flag validation --- cmd/root.go | 21 ++++++++++++++++----- keys.yaml | 1 - 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 896b7c666..05fffd489 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -19,12 +19,14 @@ import ( "os" "strings" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" ) var ( rootDir string + format string ) // RootCmd represents the base command when called without any subcommands @@ -37,9 +39,6 @@ These keys may be in any format supported by go-crypto and can be used by light-clients, full nodes, or any other application that needs to sign with a private key.`, PersistentPreRunE: bindFlags, - // Uncomment the following line if your bare application - // has an action associated with it: - // Run: func(cmd *cobra.Command, args []string) { }, } // Execute adds all child commands to the root command sets flags appropriately. @@ -53,7 +52,8 @@ func Execute() { func init() { cobra.OnInitialize(initEnv) - RootCmd.PersistentFlags().StringP("root", "r", os.ExpandEnv("$HOME/.tlc"), "root directory for config and data (default is $HOME/.tlc)") + RootCmd.PersistentFlags().StringP("root", "r", os.ExpandEnv("$HOME/.tlc"), "root directory for config and data (default is TM_ROOT or $HOME/.tlc)") + RootCmd.PersistentFlags().StringP("format", "f", "text", "Output format (text|json)") } // initEnv sets to use ENV variables if set. @@ -80,5 +80,16 @@ func bindFlags(cmd *cobra.Command, args []string) error { fmt.Println("Using config file:", viper.ConfigFileUsed()) } - return nil + return validateFlags(cmd) +} + +// validateFlags asserts all RootCmd flags are valid +func validateFlags(cmd *cobra.Command) error { + format = viper.GetString("format") + switch format { + case "text", "json": + return nil + default: + return errors.Errorf("Unsupported format: %s", format) + } } diff --git a/keys.yaml b/keys.yaml index 3aec88a7b..812adb72a 100644 --- a/keys.yaml +++ b/keys.yaml @@ -1,2 +1 @@ -format: super name: george From 78bb9f9cd8ac4dacbb28efe1db37566f88e75209 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Feb 2017 18:07:59 +0100 Subject: [PATCH 031/287] Import keystore logic from light-client --- Makefile | 2 + cryptostore/docs.go | 25 ++++ cryptostore/enc_storage.go | 47 ++++++ cryptostore/encoder.go | 54 +++++++ cryptostore/encoder_test.go | 59 ++++++++ cryptostore/generator.go | 30 ++++ cryptostore/holder.go | 120 +++++++++++++++ cryptostore/holder_test.go | 241 +++++++++++++++++++++++++++++++ cryptostore/storage_test.go | 41 ++++++ keys.toml | 1 + keys.yaml | 1 - storage.go | 10 ++ storage/filestorage/main.go | 171 ++++++++++++++++++++++ storage/filestorage/main_test.go | 95 ++++++++++++ storage/memstorage/main.go | 70 +++++++++ storage/memstorage/main_test.go | 67 +++++++++ transactions.go | 61 ++++++++ 17 files changed, 1094 insertions(+), 1 deletion(-) create mode 100644 Makefile create mode 100644 cryptostore/docs.go create mode 100644 cryptostore/enc_storage.go create mode 100644 cryptostore/encoder.go create mode 100644 cryptostore/encoder_test.go create mode 100644 cryptostore/generator.go create mode 100644 cryptostore/holder.go create mode 100644 cryptostore/holder_test.go create mode 100644 cryptostore/storage_test.go create mode 100644 keys.toml delete mode 100644 keys.yaml create mode 100644 storage.go create mode 100644 storage/filestorage/main.go create mode 100644 storage/filestorage/main_test.go create mode 100644 storage/memstorage/main.go create mode 100644 storage/memstorage/main_test.go create mode 100644 transactions.go diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..7a1f90fd4 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +test: + go test ./... diff --git a/cryptostore/docs.go b/cryptostore/docs.go new file mode 100644 index 000000000..5c66fba2d --- /dev/null +++ b/cryptostore/docs.go @@ -0,0 +1,25 @@ +/* +package cryptostore maintains everything needed for doing public-key signing and +key management in software, based on the go-crypto library from tendermint. + +It is flexible, and allows the user to provide a key generation algorithm +(currently Ed25519 or Secp256k1), an encoder to passphrase-encrypt our keys +when storing them (currently SecretBox from NaCl), and a method to persist +the keys (currently FileStorage like ssh, or MemStorage for tests). +It should be relatively simple to write your own implementation of these +interfaces to match your specific security requirements. + +Note that the private keys are never exposed outside the package, and the +interface of Manager could be implemented by an HSM in the future for +enhanced security. It would require a completely different implementation +however. + +This Manager aims to implement Signer and KeyManager interfaces, along +with some extensions to allow importing/exporting keys and updating the +passphrase. + +Encoder and Generator implementations are currently in this package, +keys.Storage implementations exist as subpackages of +keys/storage +*/ +package cryptostore diff --git a/cryptostore/enc_storage.go b/cryptostore/enc_storage.go new file mode 100644 index 000000000..0a935075f --- /dev/null +++ b/cryptostore/enc_storage.go @@ -0,0 +1,47 @@ +package cryptostore + +import ( + crypto "github.com/tendermint/go-crypto" + keys "github.com/tendermint/go-keys" +) + +// encryptedStorage needs passphrase to get private keys +type encryptedStorage struct { + coder Encoder + store keys.Storage +} + +func (es encryptedStorage) Put(name, pass string, key crypto.PrivKey) error { + secret, err := es.coder.Encrypt(key, pass) + if err != nil { + return err + } + + ki := info(name, key) + return es.store.Put(name, secret, ki) +} + +func (es encryptedStorage) Get(name, pass string) (crypto.PrivKey, keys.KeyInfo, error) { + secret, info, err := es.store.Get(name) + if err != nil { + return nil, info, err + } + key, err := es.coder.Decrypt(secret, pass) + return key, info, err +} + +func (es encryptedStorage) List() ([]keys.KeyInfo, error) { + return es.store.List() +} + +func (es encryptedStorage) Delete(name string) error { + return es.store.Delete(name) +} + +// info hardcodes the encoding of keys +func info(name string, key crypto.PrivKey) keys.KeyInfo { + return keys.KeyInfo{ + Name: name, + PubKey: crypto.PubKeyS{key.PubKey()}, + } +} diff --git a/cryptostore/encoder.go b/cryptostore/encoder.go new file mode 100644 index 000000000..03bc1e4e8 --- /dev/null +++ b/cryptostore/encoder.go @@ -0,0 +1,54 @@ +package cryptostore + +import ( + "github.com/pkg/errors" + crypto "github.com/tendermint/go-crypto" +) + +var ( + // SecretBox uses the algorithm from NaCL to store secrets securely + SecretBox Encoder = secretbox{} + // Noop doesn't do any encryption, should only be used in test code + Noop Encoder = noop{} +) + +// Encoder is used to encrypt any key with a passphrase for storage. +// +// This should use a well-designed symetric encryption algorithm +type Encoder interface { + Encrypt(key crypto.PrivKey, pass string) ([]byte, error) + Decrypt(data []byte, pass string) (crypto.PrivKey, error) +} + +func secret(passphrase string) []byte { + // TODO: Sha256(Bcrypt(passphrase)) + return crypto.Sha256([]byte(passphrase)) +} + +type secretbox struct{} + +func (e secretbox) Encrypt(key crypto.PrivKey, pass string) ([]byte, error) { + s := secret(pass) + cipher := crypto.EncryptSymmetric(key.Bytes(), s) + return cipher, nil +} + +func (e secretbox) Decrypt(data []byte, pass string) (crypto.PrivKey, error) { + s := secret(pass) + private, err := crypto.DecryptSymmetric(data, s) + if err != nil { + return nil, errors.Wrap(err, "Invalid Passphrase") + } + key, err := crypto.PrivKeyFromBytes(private) + return key, errors.Wrap(err, "Invalid Passphrase") +} + +type noop struct{} + +func (n noop) Encrypt(key crypto.PrivKey, pass string) ([]byte, error) { + return key.Bytes(), nil +} + +func (n noop) Decrypt(data []byte, pass string) (crypto.PrivKey, error) { + return crypto.PrivKeyFromBytes(data) +} diff --git a/cryptostore/encoder_test.go b/cryptostore/encoder_test.go new file mode 100644 index 000000000..8b72509ed --- /dev/null +++ b/cryptostore/encoder_test.go @@ -0,0 +1,59 @@ +package cryptostore_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tendermint/go-keys/cryptostore" +) + +func TestNoopEncoder(t *testing.T) { + assert, require := assert.New(t), require.New(t) + noop := cryptostore.Noop + + key := cryptostore.GenEd25519.Generate() + key2 := cryptostore.GenSecp256k1.Generate() + + b, err := noop.Encrypt(key, "encode") + require.Nil(err) + assert.NotEmpty(b) + + b2, err := noop.Encrypt(key2, "encode") + require.Nil(err) + assert.NotEmpty(b2) + assert.NotEqual(b, b2) + + // note the decode with a different password works - not secure! + pk, err := noop.Decrypt(b, "decode") + require.Nil(err) + require.NotNil(pk) + assert.Equal(key, pk) + + pk2, err := noop.Decrypt(b2, "kggugougp") + require.Nil(err) + require.NotNil(pk2) + assert.Equal(key2, pk2) +} + +func TestSecretBox(t *testing.T) { + assert, require := assert.New(t), require.New(t) + enc := cryptostore.SecretBox + + key := cryptostore.GenEd25519.Generate() + pass := "some-special-secret" + + b, err := enc.Encrypt(key, pass) + require.Nil(err) + assert.NotEmpty(b) + + // decoding with a different pass is an error + pk, err := enc.Decrypt(b, "decode") + require.NotNil(err) + require.Nil(pk) + + // but decoding with the same passphrase gets us our key + pk, err = enc.Decrypt(b, pass) + require.Nil(err) + assert.Equal(key, pk) +} diff --git a/cryptostore/generator.go b/cryptostore/generator.go new file mode 100644 index 000000000..c6661fb34 --- /dev/null +++ b/cryptostore/generator.go @@ -0,0 +1,30 @@ +package cryptostore + +import crypto "github.com/tendermint/go-crypto" + +var ( + // GenEd25519 produces Ed25519 private keys + GenEd25519 Generator = GenFunc(genEd25519) + // GenSecp256k1 produces Secp256k1 private keys + GenSecp256k1 Generator = GenFunc(genSecp256) +) + +// Generator determines the type of private key the keystore creates +type Generator interface { + Generate() crypto.PrivKey +} + +// GenFunc is a helper to transform a function into a Generator +type GenFunc func() crypto.PrivKey + +func (f GenFunc) Generate() crypto.PrivKey { + return f() +} + +func genEd25519() crypto.PrivKey { + return crypto.GenPrivKeyEd25519() +} + +func genSecp256() crypto.PrivKey { + return crypto.GenPrivKeySecp256k1() +} diff --git a/cryptostore/holder.go b/cryptostore/holder.go new file mode 100644 index 000000000..4beb64160 --- /dev/null +++ b/cryptostore/holder.go @@ -0,0 +1,120 @@ +package cryptostore + +import keys "github.com/tendermint/go-keys" + +// Manager combines encyption and storage implementation to provide +// a full-featured key manager +type Manager struct { + gen Generator + es encryptedStorage +} + +func New(gen Generator, coder Encoder, store keys.Storage) Manager { + return Manager{ + gen: gen, + es: encryptedStorage{ + coder: coder, + store: store, + }, + } +} + +// exists just to make sure we fulfill the Signer interface +func (s Manager) assertSigner() keys.Signer { + return s +} + +// exists just to make sure we fulfill the KeyManager interface +func (s Manager) assertKeyManager() keys.KeyManager { + return s +} + +// Create adds a new key to the storage engine, returning error if +// another key already stored under this name +func (s Manager) Create(name, passphrase string) error { + key := s.gen.Generate() + return s.es.Put(name, passphrase, key) +} + +// List loads the keys from the storage and enforces alphabetical order +func (s Manager) List() (keys.KeyInfos, error) { + k, err := s.es.List() + res := keys.KeyInfos(k) + res.Sort() + return res, err +} + +// Get returns the public information about one key +func (s Manager) Get(name string) (keys.KeyInfo, error) { + _, info, err := s.es.store.Get(name) + return info, err +} + +// Sign will modify the Signable in order to attach a valid signature with +// this public key +// +// If no key for this name, or the passphrase doesn't match, returns an error +func (s Manager) Sign(name, passphrase string, tx keys.Signable) error { + key, _, err := s.es.Get(name, passphrase) + if err != nil { + return err + } + sig := key.Sign(tx.SignBytes()) + pubkey := key.PubKey() + return tx.Sign(pubkey, sig) +} + +// Export decodes the private key with the current password, encodes +// it with a secure one-time password and generates a sequence that can be +// Imported by another Manager +// +// This is designed to copy from one device to another, or provide backups +// during version updates. +func (s Manager) Export(name, oldpass, transferpass string) ([]byte, error) { + key, _, err := s.es.Get(name, oldpass) + if err != nil { + return nil, err + } + + res, err := s.es.coder.Encrypt(key, transferpass) + return res, err +} + +// Import accepts bytes generated by Export along with the same transferpass +// If they are valid, it stores the password under the given name with the +// new passphrase. +func (s Manager) Import(name, newpass, transferpass string, data []byte) error { + key, err := s.es.coder.Decrypt(data, transferpass) + if err != nil { + return err + } + + return s.es.Put(name, newpass, key) +} + +// Delete removes key forever, but we must present the +// proper passphrase before deleting it (for security) +func (s Manager) Delete(name, passphrase string) error { + // verify we have the proper password before deleting + _, _, err := s.es.Get(name, passphrase) + if err != nil { + return err + } + return s.es.Delete(name) +} + +// Update changes the passphrase with which a already stored key is encoded. +// +// oldpass must be the current passphrase used for encoding, newpass will be +// the only valid passphrase from this time forward +func (s Manager) Update(name, oldpass, newpass string) error { + key, _, err := s.es.Get(name, oldpass) + if err != nil { + return err + } + + // we must delete first, as Putting over an existing name returns an error + s.Delete(name, oldpass) + + return s.es.Put(name, newpass, key) +} diff --git a/cryptostore/holder_test.go b/cryptostore/holder_test.go new file mode 100644 index 000000000..fb5ef854f --- /dev/null +++ b/cryptostore/holder_test.go @@ -0,0 +1,241 @@ +package cryptostore_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tendermint/go-keys/cryptostore" + "github.com/tendermint/go-keys/storage/memstorage" +) + +// TestKeyManagement makes sure we can manipulate these keys well +func TestKeyManagement(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + // make the storage with reasonable defaults + cstore := cryptostore.New( + cryptostore.GenSecp256k1, + cryptostore.SecretBox, + memstorage.New(), + ) + + n1, n2, n3 := "personal", "business", "other" + p1, p2 := "1234", "really-secure!@#$" + + // Check empty state + l, err := cstore.List() + require.Nil(err) + assert.Empty(l) + + // create some keys + _, err = cstore.Get(n1) + assert.NotNil(err) + err = cstore.Create(n1, p1) + require.Nil(err) + err = cstore.Create(n2, p2) + require.Nil(err) + + // we can get these keys + i2, err := cstore.Get(n2) + assert.Nil(err) + _, err = cstore.Get(n3) + assert.NotNil(err) + + // list shows them in order + keys, err := cstore.List() + require.Nil(err) + require.Equal(2, len(keys)) + // note these are in alphabetical order + assert.Equal(n2, keys[0].Name) + assert.Equal(n1, keys[1].Name) + assert.Equal(i2.PubKey, keys[0].PubKey) + + // deleting a key removes it + err = cstore.Delete("bad name", "foo") + require.NotNil(err) + err = cstore.Delete(n1, p1) + require.Nil(err) + keys, err = cstore.List() + require.Nil(err) + assert.Equal(1, len(keys)) + _, err = cstore.Get(n1) + assert.NotNil(err) + + // make sure that it only signs with the right password + // tx := mock.NewSig([]byte("mytransactiondata")) + // err = cstore.Sign(n2, p1, tx) + // assert.NotNil(err) + // err = cstore.Sign(n2, p2, tx) + // assert.Nil(err, "%+v", err) + // sigs, err := tx.Signers() + // assert.Nil(err, "%+v", err) + // if assert.Equal(1, len(sigs)) { + // assert.Equal(i2.PubKey, sigs[0]) + // } +} + +// TestSignVerify does some detailed checks on how we sign and validate +// signatures +// func TestSignVerify(t *testing.T) { +// assert, require := assert.New(t), require.New(t) + +// // make the storage with reasonable defaults +// cstore := cryptostore.New( +// cryptostore.GenSecp256k1, +// cryptostore.SecretBox, +// memstorage.New(), +// ) + +// n1, n2 := "some dude", "a dudette" +// p1, p2 := "1234", "foobar" + +// // create two users and get their info +// err := cstore.Create(n1, p1) +// require.Nil(err) +// i1, err := cstore.Get(n1) +// require.Nil(err) + +// err = cstore.Create(n2, p2) +// require.Nil(err) +// i2, err := cstore.Get(n2) +// require.Nil(err) + +// // let's try to sign some messages +// d1 := []byte("my first message") +// d2 := []byte("some other important info!") + +// // try signing both data with both keys... +// s11, err := cstore.Signature(n1, p1, d1) +// require.Nil(err) +// s12, err := cstore.Signature(n1, p1, d2) +// require.Nil(err) +// s21, err := cstore.Signature(n2, p2, d1) +// require.Nil(err) +// s22, err := cstore.Signature(n2, p2, d2) +// require.Nil(err) + +// // let's try to validate and make sure it only works when everything is proper +// keys := [][]byte{i1.PubKey, i2.PubKey} +// data := [][]byte{d1, d2} +// sigs := [][]byte{s11, s12, s21, s22} + +// // loop over keys and data +// for k := 0; k < 2; k++ { +// for d := 0; d < 2; d++ { +// // make sure only the proper sig works +// good := 2*k + d +// for s := 0; s < 4; s++ { +// err = cstore.Verify(data[d], sigs[s], keys[k]) +// if s == good { +// assert.Nil(err, "%+v", err) +// } else { +// assert.NotNil(err) +// } +// } +// } +// } +// } + +func assertPassword(assert *assert.Assertions, cstore cryptostore.Manager, name, pass, badpass string) { + err := cstore.Update(name, badpass, pass) + assert.NotNil(err) + err = cstore.Update(name, pass, pass) + assert.Nil(err, "%+v", err) +} + +// TestAdvancedKeyManagement verifies update, import, export functionality +func TestAdvancedKeyManagement(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + // make the storage with reasonable defaults + cstore := cryptostore.New( + cryptostore.GenSecp256k1, + cryptostore.SecretBox, + memstorage.New(), + ) + + n1, n2 := "old-name", "new name" + p1, p2, p3, pt := "1234", "foobar", "ding booms!", "really-secure!@#$" + + // make sure key works with initial password + err := cstore.Create(n1, p1) + require.Nil(err, "%+v", err) + assertPassword(assert, cstore, n1, p1, p2) + + // update password requires the existing password + err = cstore.Update(n1, "jkkgkg", p2) + assert.NotNil(err) + assertPassword(assert, cstore, n1, p1, p2) + + // then it changes the password when correct + err = cstore.Update(n1, p1, p2) + assert.Nil(err) + // p2 is now the proper one! + assertPassword(assert, cstore, n1, p2, p1) + + // exporting requires the proper name and passphrase + _, err = cstore.Export(n2, p2, pt) + assert.NotNil(err) + _, err = cstore.Export(n1, p1, pt) + assert.NotNil(err) + exported, err := cstore.Export(n1, p2, pt) + require.Nil(err, "%+v", err) + + // import fails on bad transfer pass + err = cstore.Import(n2, p3, p2, exported) + assert.NotNil(err) + // import cannot overwrite existing keys + err = cstore.Import(n1, p3, pt, exported) + assert.NotNil(err) + // we can now import under another name + err = cstore.Import(n2, p3, pt, exported) + require.Nil(err, "%+v", err) + + // make sure both passwords are now properly set (not to the transfer pass) + assertPassword(assert, cstore, n1, p2, pt) + assertPassword(assert, cstore, n2, p3, pt) +} + +// func ExampleStore() { +// // Select the encryption and storage for your cryptostore +// cstore := cryptostore.New( +// cryptostore.GenEd25519, +// cryptostore.SecretBox, +// // Note: use filestorage.New(dir) for real data +// memstorage.New(), +// ) + +// // Add keys and see they return in alphabetical order +// cstore.Create("Bob", "friend") +// cstore.Create("Alice", "secret") +// cstore.Create("Carl", "mitm") +// info, _ := cstore.List() +// for _, i := range info { +// fmt.Println(i.Name) +// } + +// // We need to use passphrase to generate a signature +// tx := mock.NewSig([]byte("deadbeef")) +// err := cstore.Sign("Bob", "friend", tx) +// if err != nil { +// fmt.Println("don't accept real passphrase") +// } + +// // and we can validate the signature with publically available info +// binfo, _ := cstore.Get("Bob") +// sigs, err := tx.Signers() +// if err != nil { +// fmt.Println("badly signed") +// } else if bytes.Equal(sigs[0].Bytes(), binfo.PubKey.Bytes()) { +// fmt.Println("signed by Bob") +// } else { +// fmt.Println("signed by someone else") +// } + +// // Output: +// // Alice +// // Bob +// // Carl +// // signed by Bob +// } diff --git a/cryptostore/storage_test.go b/cryptostore/storage_test.go new file mode 100644 index 000000000..6c6ea5e2c --- /dev/null +++ b/cryptostore/storage_test.go @@ -0,0 +1,41 @@ +package cryptostore + +import ( + "testing" + + "github.com/stretchr/testify/assert" + keys "github.com/tendermint/go-keys" +) + +func TestSortKeys(t *testing.T) { + assert := assert.New(t) + + gen := GenEd25519.Generate + assert.NotEqual(gen(), gen()) + + // alphabetical order is n3, n1, n2 + n1, n2, n3 := "john", "mike", "alice" + infos := keys.KeyInfos{ + info(n1, gen()), + info(n2, gen()), + info(n3, gen()), + } + + // make sure they are initialized unsorted + assert.Equal(n1, infos[0].Name) + assert.Equal(n2, infos[1].Name) + assert.Equal(n3, infos[2].Name) + + // now they are sorted + infos.Sort() + assert.Equal(n3, infos[0].Name) + assert.Equal(n1, infos[1].Name) + assert.Equal(n2, infos[2].Name) + + // make sure info put some real data there... + assert.NotEmpty(infos[0].PubKey) + assert.NotEmpty(infos[0].PubKey.Address()) + assert.NotEmpty(infos[1].PubKey) + assert.NotEmpty(infos[1].PubKey.Address()) + assert.NotEqual(infos[0].PubKey, infos[1].PubKey) +} diff --git a/keys.toml b/keys.toml new file mode 100644 index 000000000..41f4d5286 --- /dev/null +++ b/keys.toml @@ -0,0 +1 @@ +format = "text" diff --git a/keys.yaml b/keys.yaml deleted file mode 100644 index 812adb72a..000000000 --- a/keys.yaml +++ /dev/null @@ -1 +0,0 @@ -name: george diff --git a/storage.go b/storage.go new file mode 100644 index 000000000..519ce1aa8 --- /dev/null +++ b/storage.go @@ -0,0 +1,10 @@ +package keys + +// Storage has many implementation, based on security and sharing requirements +// like disk-backed, mem-backed, vault, db, etc. +type Storage interface { + Put(name string, key []byte, info KeyInfo) error + Get(name string) ([]byte, KeyInfo, error) + List() ([]KeyInfo, error) + Delete(name string) error +} diff --git a/storage/filestorage/main.go b/storage/filestorage/main.go new file mode 100644 index 000000000..554a36540 --- /dev/null +++ b/storage/filestorage/main.go @@ -0,0 +1,171 @@ +/* +package filestorage provides a secure on-disk storage of private keys and +metadata. Security is enforced by file and directory permissions, much +like standard ssh key storage. +*/ +package filestorage + +import ( + "fmt" + "io/ioutil" + "os" + "path" + "strings" + + "github.com/pkg/errors" + crypto "github.com/tendermint/go-crypto" + keys "github.com/tendermint/go-keys" +) + +const ( + BlockType = "Tendermint Light Client" + PrivExt = "tlc" + PubExt = "pub" + keyPerm = os.FileMode(0600) + pubPerm = os.FileMode(0644) + dirPerm = os.FileMode(0700) +) + +type FileStore struct { + keyDir string +} + +// New creates an instance of file-based key storage with tight permissions +// +// dir should be an absolute path of a directory owner by this user. It will +// be created if it doesn't exist already. +func New(dir string) FileStore { + err := os.Mkdir(dir, dirPerm) + if err != nil && !os.IsExist(err) { + panic(err) + } + return FileStore{dir} +} + +// assertStorage just makes sure we implement the proper Storage interface +func (s FileStore) assertStorage() keys.Storage { + return s +} + +// Put creates two files, one with the public info as json, the other +// with the (encoded) private key as gpg ascii-armor style +func (s FileStore) Put(name string, key []byte, info keys.KeyInfo) error { + pub, priv := s.nameToPaths(name) + + // write public info + err := writeInfo(pub, info) + if err != nil { + return err + } + + // write private info + return write(priv, name, key) +} + +// Get loads the keyinfo and (encoded) private key from the directory +// It uses `name` to generate the filename, and returns an error if the +// files don't exist or are in the incorrect format +func (s FileStore) Get(name string) ([]byte, keys.KeyInfo, error) { + pub, priv := s.nameToPaths(name) + + info, err := readInfo(pub) + if err != nil { + return nil, info, err + } + + key, _, err := read(priv) + return key, info, err +} + +// List parses the key directory for public info and returns a list of +// KeyInfo for all keys located in this directory. +func (s FileStore) List() ([]keys.KeyInfo, error) { + dir, err := os.Open(s.keyDir) + if err != nil { + return nil, errors.Wrap(err, "List Keys") + } + names, err := dir.Readdirnames(0) + if err != nil { + return nil, errors.Wrap(err, "List Keys") + } + + // filter names for .pub ending and load them one by one + // half the files is a good guess for pre-allocating the slice + infos := make([]keys.KeyInfo, 0, len(names)/2) + for _, name := range names { + if strings.HasSuffix(name, PubExt) { + p := path.Join(s.keyDir, name) + info, err := readInfo(p) + if err != nil { + return nil, err + } + infos = append(infos, info) + } + } + + return infos, nil +} + +// Delete permanently removes the public and private info for the named key +// The calling function should provide some security checks first. +func (s FileStore) Delete(name string) error { + pub, priv := s.nameToPaths(name) + err := os.Remove(priv) + if err != nil { + return errors.Wrap(err, "Deleting Private Key") + } + err = os.Remove(pub) + return errors.Wrap(err, "Deleting Public Key") +} + +func (s FileStore) nameToPaths(name string) (pub, priv string) { + privName := fmt.Sprintf("%s.%s", name, PrivExt) + pubName := fmt.Sprintf("%s.%s", name, PubExt) + return path.Join(s.keyDir, pubName), path.Join(s.keyDir, privName) +} + +func writeInfo(path string, info keys.KeyInfo) error { + return write(path, info.Name, info.PubKey.Bytes()) +} + +func readInfo(path string) (info keys.KeyInfo, err error) { + var data []byte + data, info.Name, err = read(path) + if err != nil { + return + } + pk, err := crypto.PubKeyFromBytes(data) + info.PubKey = crypto.PubKeyS{pk} + return +} + +func read(path string) ([]byte, string, error) { + f, err := os.Open(path) + if err != nil { + return nil, "", errors.Wrap(err, "Reading data") + } + d, err := ioutil.ReadAll(f) + if err != nil { + return nil, "", errors.Wrap(err, "Reading data") + } + block, headers, key, err := crypto.DecodeArmor(string(d)) + if err != nil { + return nil, "", errors.Wrap(err, "Invalid Armor") + } + if block != BlockType { + return nil, "", errors.Errorf("Unknown key type: %s", block) + } + return key, headers["name"], nil +} + +func write(path, name string, key []byte) error { + f, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, keyPerm) + if err != nil { + return errors.Wrap(err, "Writing data") + } + defer f.Close() + headers := map[string]string{"name": name} + text := crypto.EncodeArmor(BlockType, headers, key) + _, err = f.WriteString(text) + return errors.Wrap(err, "Writing data") +} diff --git a/storage/filestorage/main_test.go b/storage/filestorage/main_test.go new file mode 100644 index 000000000..f81ba7198 --- /dev/null +++ b/storage/filestorage/main_test.go @@ -0,0 +1,95 @@ +package filestorage + +import ( + "io/ioutil" + "os" + "path" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + crypto "github.com/tendermint/go-crypto" + keys "github.com/tendermint/go-keys" +) + +func TestBasicCRUD(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + dir, err := ioutil.TempDir("", "filestorage-test") + assert.Nil(err) + defer os.RemoveAll(dir) + store := New(dir) + + name := "bar" + key := []byte("secret-key-here") + pubkey := crypto.GenPrivKeyEd25519().PubKey() + info := keys.KeyInfo{ + Name: name, + PubKey: crypto.PubKeyS{pubkey}, + } + + // No data: Get and Delete return nothing + _, _, err = store.Get(name) + assert.NotNil(err) + err = store.Delete(name) + assert.NotNil(err) + // List returns empty list + l, err := store.List() + assert.Nil(err) + assert.Empty(l) + + // Putting the key in the store must work + err = store.Put(name, key, info) + assert.Nil(err) + // But a second time is a failure + err = store.Put(name, key, info) + assert.NotNil(err) + + // Now, we can get and list properly + k, i, err := store.Get(name) + require.Nil(err, "%+v", err) + assert.Equal(key, k) + assert.Equal(info, i) + l, err = store.List() + require.Nil(err, "%+v", err) + assert.Equal(1, len(l)) + assert.Equal(info, l[0]) + + // querying a non-existent key fails + _, _, err = store.Get("badname") + assert.NotNil(err) + + // We can only delete once + err = store.Delete(name) + assert.Nil(err) + err = store.Delete(name) + assert.NotNil(err) + + // and then Get and List don't work + _, _, err = store.Get(name) + assert.NotNil(err) + // List returns empty list + l, err = store.List() + assert.Nil(err) + assert.Empty(l) +} + +func TestDirectoryHandling(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + // prepare a temp dir and make sure it is not there + newDir := path.Join(os.TempDir(), "file-test-dir") + _, err := os.Open(newDir) + assert.True(os.IsNotExist(err)) + + // create a new storage, and verify it creates the directory with good permissions + New(newDir) + defer os.RemoveAll(newDir) + d, err := os.Open(newDir) + require.Nil(err) + defer d.Close() + + stat, err := d.Stat() + require.Nil(err) + assert.Equal(dirPerm, stat.Mode()&os.ModePerm) +} diff --git a/storage/memstorage/main.go b/storage/memstorage/main.go new file mode 100644 index 000000000..e6573eb9f --- /dev/null +++ b/storage/memstorage/main.go @@ -0,0 +1,70 @@ +/* +package memstorage provides a simple in-memory key store designed for +use in test cases, particularly to isolate them from the filesystem, +concurrency, and cleanup issues. +*/ +package memstorage + +import ( + "github.com/pkg/errors" + keys "github.com/tendermint/go-keys" +) + +type data struct { + info keys.KeyInfo + key []byte +} + +type MemStore map[string]data + +// New creates an instance of file-based key storage with tight permissions +func New() MemStore { + return MemStore{} +} + +// assertStorage just makes sure we implement the Storage interface +func (s MemStore) assertStorage() keys.Storage { + return s +} + +// Put adds the given key, returns an error if it another key +// is already stored under this name +func (s MemStore) Put(name string, key []byte, info keys.KeyInfo) error { + if _, ok := s[name]; ok { + return errors.Errorf("Key named '%s' already exists", name) + } + s[name] = data{info, key} + return nil +} + +// Get returns the key stored under the name, or returns an error if not present +func (s MemStore) Get(name string) ([]byte, keys.KeyInfo, error) { + var err error + d, ok := s[name] + if !ok { + err = errors.Errorf("Key named '%s' doesn't exist", name) + } + return d.key, d.info, err +} + +// List returns the public info of all keys in the MemStore in unsorted order +func (s MemStore) List() ([]keys.KeyInfo, error) { + res := make([]keys.KeyInfo, len(s)) + i := 0 + for _, d := range s { + res[i] = d.info + i++ + } + return res, nil +} + +// Delete removes the named key from the MemStore, raising an error if it +// wasn't present yet. +func (s MemStore) Delete(name string) error { + _, ok := s[name] + if !ok { + return errors.Errorf("Key named '%s' doesn't exist", name) + } + delete(s, name) + return nil +} diff --git a/storage/memstorage/main_test.go b/storage/memstorage/main_test.go new file mode 100644 index 000000000..01c015a15 --- /dev/null +++ b/storage/memstorage/main_test.go @@ -0,0 +1,67 @@ +package memstorage + +import ( + "testing" + + "github.com/stretchr/testify/assert" + crypto "github.com/tendermint/go-crypto" + keys "github.com/tendermint/go-keys" +) + +func TestBasicCRUD(t *testing.T) { + assert := assert.New(t) + store := New() + + name := "foo" + key := []byte("secret-key-here") + pubkey := crypto.GenPrivKeyEd25519().PubKey() + info := keys.KeyInfo{ + Name: name, + PubKey: crypto.PubKeyS{pubkey}, + } + + // No data: Get and Delete return nothing + _, _, err := store.Get(name) + assert.NotNil(err) + err = store.Delete(name) + assert.NotNil(err) + // List returns empty list + l, err := store.List() + assert.Nil(err) + assert.Empty(l) + + // Putting the key in the store must work + err = store.Put(name, key, info) + assert.Nil(err) + // But a second time is a failure + err = store.Put(name, key, info) + assert.NotNil(err) + + // Now, we can get and list properly + k, i, err := store.Get(name) + assert.Nil(err) + assert.Equal(key, k) + assert.Equal(info, i) + l, err = store.List() + assert.Nil(err) + assert.Equal(1, len(l)) + assert.Equal(info, l[0]) + + // querying a non-existent key fails + _, _, err = store.Get("badname") + assert.NotNil(err) + + // We can only delete once + err = store.Delete(name) + assert.Nil(err) + err = store.Delete(name) + assert.NotNil(err) + + // and then Get and List don't work + _, _, err = store.Get(name) + assert.NotNil(err) + // List returns empty list + l, err = store.List() + assert.Nil(err) + assert.Empty(l) +} diff --git a/transactions.go b/transactions.go new file mode 100644 index 000000000..f22719f7e --- /dev/null +++ b/transactions.go @@ -0,0 +1,61 @@ +package keys + +import ( + "sort" + + crypto "github.com/tendermint/go-crypto" +) + +// KeyInfo is the public information about a key +type KeyInfo struct { + Name string + PubKey crypto.PubKeyS +} + +// KeyInfos is a wrapper to allows alphabetical sorting of the keys +type KeyInfos []KeyInfo + +func (k KeyInfos) Len() int { return len(k) } +func (k KeyInfos) Less(i, j int) bool { return k[i].Name < k[j].Name } +func (k KeyInfos) Swap(i, j int) { k[i], k[j] = k[j], k[i] } +func (k KeyInfos) Sort() { + if k != nil { + sort.Sort(k) + } +} + +// Signable represents any transaction we wish to send to tendermint core +// These methods allow us to sign arbitrary Tx with the KeyStore +type Signable interface { + // SignBytes is the immutable data, which needs to be signed + SignBytes() []byte + + // Sign will add a signature and pubkey. + // + // Depending on the Signable, one may be able to call this multiple times for multisig + // Returns error if called with invalid data or too many times + Sign(pubkey crypto.PubKey, sig crypto.Signature) error + + // Signers will return the public key(s) that signed if the signature + // is valid, or an error if there is any issue with the signature, + // including if there are no signatures + Signers() ([]crypto.PubKey, error) + + // TxBytes returns the transaction data as well as all signatures + // It should return an error if Sign was never called + TxBytes() ([]byte, error) +} + +// Signer allows one to use a keystore to sign transactions +type Signer interface { + Sign(name, passphrase string, tx Signable) error +} + +// KeyManager allows simple CRUD on a keystore, as an aid to signing +type KeyManager interface { + Create(name, passphrase string) error + List() (KeyInfos, error) + Get(name string) (KeyInfo, error) + Update(name, oldpass, newpass string) error + Delete(name, passphrase string) error +} From 506ff7d85a09b03b2dc726d7a4b466e325c55ec2 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Feb 2017 18:52:52 +0100 Subject: [PATCH 032/287] Expose new and list via cli --- Makefile | 3 ++ cmd/list.go | 21 ++++-------- cmd/new.go | 42 +++++++++++++++++------- cmd/root.go | 33 +++++++++++++++---- cmd/utils.go | 56 ++++++++++++++++++++++++++++++++ cryptostore/enc_storage.go | 8 ++--- cryptostore/holder.go | 16 ++++----- cryptostore/holder_test.go | 7 ++-- cryptostore/storage_test.go | 2 +- keys.toml | 3 +- storage.go | 6 ++-- storage/filestorage/main.go | 16 ++++----- storage/filestorage/main_test.go | 2 +- storage/memstorage/main.go | 10 +++--- storage/memstorage/main_test.go | 2 +- transactions.go | 26 +++++++-------- 16 files changed, 173 insertions(+), 80 deletions(-) create mode 100644 cmd/utils.go diff --git a/Makefile b/Makefile index 7a1f90fd4..b15317b25 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,5 @@ test: go test ./... + +install: + go install ./cmd/keys diff --git a/cmd/list.go b/cmd/list.go index e2c8a7631..44fefb8d6 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -18,7 +18,6 @@ import ( "fmt" "github.com/spf13/cobra" - "github.com/spf13/viper" ) // listCmd represents the list command @@ -28,22 +27,16 @@ var listCmd = &cobra.Command{ Long: `Return a list of all public keys stored by this key manager along with their associated name and address.`, Run: func(cmd *cobra.Command, args []string) { - // TODO: Work your own magic here - fmt.Println("list called") - fmt.Println(viper.Get("format")) + infos, err := manager.List() + if err != nil { + fmt.Println(err.Error()) + return + } + + printInfos(infos) }, } func init() { RootCmd.AddCommand(listCmd) - - // Here you will define your flags and configuration settings. - - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // listCmd.PersistentFlags().String("foo", "", "A help for foo") - - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: - listCmd.Flags().StringP("format", "f", "text", "Format to display (text|json)") } diff --git a/cmd/new.go b/cmd/new.go index 40462e686..38d9762f9 100644 --- a/cmd/new.go +++ b/cmd/new.go @@ -22,28 +22,46 @@ import ( // newCmd represents the new command var newCmd = &cobra.Command{ - Use: "new", + Use: "new ", Short: "Create a new public/private key pair", Long: `Add a public/private key pair to the key store. The password muts be entered in the terminal and not passed as a command line argument for security.`, - Run: func(cmd *cobra.Command, args []string) { - // TODO: Work your own magic here - fmt.Println("new called") - }, + Run: newPassword, } func init() { RootCmd.AddCommand(newCmd) +} - // Here you will define your flags and configuration settings. +func newPassword(cmd *cobra.Command, args []string) { + if len(args) != 1 || len(args[0]) == 0 { + fmt.Print("You must provide a name for the key") + return + } + name := args[0] - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // newCmd.PersistentFlags().String("foo", "", "A help for foo") + // TODO: own function??? + pass, err := getPassword("Enter a passphrase:") + if err != nil { + fmt.Println(err.Error()) + return + } + pass2, err := getPassword("Repeat the passphrase:") + if err != nil { + fmt.Println(err.Error()) + return + } + if pass != pass2 { + fmt.Println("Passphrases don't match") + return + } - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: - // newCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + info, err := manager.Create(name, pass) + if err != nil { + fmt.Println(err.Error()) + return + } + printInfo(info) } diff --git a/cmd/root.go b/cmd/root.go index 05fffd489..9d7ae9a9e 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -17,16 +17,22 @@ package cmd import ( "fmt" "os" + "path/filepath" "strings" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" + keys "github.com/tendermint/go-keys" + "github.com/tendermint/go-keys/cryptostore" + "github.com/tendermint/go-keys/storage/filestorage" ) var ( rootDir string - format string + output string + keyDir string + manager keys.Manager ) // RootCmd represents the base command when called without any subcommands @@ -53,7 +59,8 @@ func Execute() { func init() { cobra.OnInitialize(initEnv) RootCmd.PersistentFlags().StringP("root", "r", os.ExpandEnv("$HOME/.tlc"), "root directory for config and data (default is TM_ROOT or $HOME/.tlc)") - RootCmd.PersistentFlags().StringP("format", "f", "text", "Output format (text|json)") + RootCmd.PersistentFlags().StringP("output", "o", "text", "Output format (text|json)") + RootCmd.PersistentFlags().StringP("keydir", "", "keys", "Directory to store private keys (subdir of root)") } // initEnv sets to use ENV variables if set. @@ -85,11 +92,25 @@ func bindFlags(cmd *cobra.Command, args []string) error { // validateFlags asserts all RootCmd flags are valid func validateFlags(cmd *cobra.Command) error { - format = viper.GetString("format") - switch format { + // validate output format + output = viper.GetString("output") + switch output { case "text", "json": - return nil default: - return errors.Errorf("Unsupported format: %s", format) + return errors.Errorf("Unsupported output format: %s", output) } + + // store the keys directory + keyDir = viper.GetString("keydir") + if !filepath.IsAbs(keyDir) { + keyDir = filepath.Join(rootDir, keyDir) + } + // and construct the key manager + manager = cryptostore.New( + cryptostore.GenEd25519, // TODO - cli switch??? + cryptostore.SecretBox, + filestorage.New(keyDir), + ) + + return nil } diff --git a/cmd/utils.go b/cmd/utils.go new file mode 100644 index 000000000..bd067f9ca --- /dev/null +++ b/cmd/utils.go @@ -0,0 +1,56 @@ +package cmd + +import ( + "fmt" + + "github.com/bgentry/speakeasy" + "github.com/pkg/errors" + data "github.com/tendermint/go-data" + keys "github.com/tendermint/go-keys" +) + +const PassLength = 10 + +func getPassword(prompt string) (string, error) { + pass, err := speakeasy.Ask(prompt) + if err != nil { + return "", err + } + if len(pass) < PassLength { + return "", errors.Errorf("Password must be at least %d characters", PassLength) + } + return pass, nil +} + +func printInfo(info keys.Info) { + switch output { + case "text": + key, err := data.ToText(info.PubKey) + if err != nil { + panic(err) // really shouldn't happen... + } + fmt.Printf("%s\t%s\n", info.Name, key) + case "json": + json, err := data.ToJSON(info) + if err != nil { + panic(err) // really shouldn't happen... + } + fmt.Println(string(json)) + } +} + +func printInfos(infos keys.Infos) { + switch output { + case "text": + fmt.Println("All keys:") + for _, i := range infos { + printInfo(i) + } + case "json": + json, err := data.ToJSON(infos) + if err != nil { + panic(err) // really shouldn't happen... + } + fmt.Println(string(json)) + } +} diff --git a/cryptostore/enc_storage.go b/cryptostore/enc_storage.go index 0a935075f..759ca90e9 100644 --- a/cryptostore/enc_storage.go +++ b/cryptostore/enc_storage.go @@ -21,7 +21,7 @@ func (es encryptedStorage) Put(name, pass string, key crypto.PrivKey) error { return es.store.Put(name, secret, ki) } -func (es encryptedStorage) Get(name, pass string) (crypto.PrivKey, keys.KeyInfo, error) { +func (es encryptedStorage) Get(name, pass string) (crypto.PrivKey, keys.Info, error) { secret, info, err := es.store.Get(name) if err != nil { return nil, info, err @@ -30,7 +30,7 @@ func (es encryptedStorage) Get(name, pass string) (crypto.PrivKey, keys.KeyInfo, return key, info, err } -func (es encryptedStorage) List() ([]keys.KeyInfo, error) { +func (es encryptedStorage) List() (keys.Infos, error) { return es.store.List() } @@ -39,8 +39,8 @@ func (es encryptedStorage) Delete(name string) error { } // info hardcodes the encoding of keys -func info(name string, key crypto.PrivKey) keys.KeyInfo { - return keys.KeyInfo{ +func info(name string, key crypto.PrivKey) keys.Info { + return keys.Info{ Name: name, PubKey: crypto.PubKeyS{key.PubKey()}, } diff --git a/cryptostore/holder.go b/cryptostore/holder.go index 4beb64160..29682a87d 100644 --- a/cryptostore/holder.go +++ b/cryptostore/holder.go @@ -24,28 +24,28 @@ func (s Manager) assertSigner() keys.Signer { return s } -// exists just to make sure we fulfill the KeyManager interface -func (s Manager) assertKeyManager() keys.KeyManager { +// exists just to make sure we fulfill the Manager interface +func (s Manager) assertKeyManager() keys.Manager { return s } // Create adds a new key to the storage engine, returning error if // another key already stored under this name -func (s Manager) Create(name, passphrase string) error { +func (s Manager) Create(name, passphrase string) (keys.Info, error) { key := s.gen.Generate() - return s.es.Put(name, passphrase, key) + err := s.es.Put(name, passphrase, key) + return info(name, key), err } // List loads the keys from the storage and enforces alphabetical order -func (s Manager) List() (keys.KeyInfos, error) { - k, err := s.es.List() - res := keys.KeyInfos(k) +func (s Manager) List() (keys.Infos, error) { + res, err := s.es.List() res.Sort() return res, err } // Get returns the public information about one key -func (s Manager) Get(name string) (keys.KeyInfo, error) { +func (s Manager) Get(name string) (keys.Info, error) { _, info, err := s.es.store.Get(name) return info, err } diff --git a/cryptostore/holder_test.go b/cryptostore/holder_test.go index fb5ef854f..116b92c4e 100644 --- a/cryptostore/holder_test.go +++ b/cryptostore/holder_test.go @@ -31,9 +31,10 @@ func TestKeyManagement(t *testing.T) { // create some keys _, err = cstore.Get(n1) assert.NotNil(err) - err = cstore.Create(n1, p1) + i, err := cstore.Create(n1, p1) + require.Equal(n1, i.Name) require.Nil(err) - err = cstore.Create(n2, p2) + _, err = cstore.Create(n2, p2) require.Nil(err) // we can get these keys @@ -159,7 +160,7 @@ func TestAdvancedKeyManagement(t *testing.T) { p1, p2, p3, pt := "1234", "foobar", "ding booms!", "really-secure!@#$" // make sure key works with initial password - err := cstore.Create(n1, p1) + _, err := cstore.Create(n1, p1) require.Nil(err, "%+v", err) assertPassword(assert, cstore, n1, p1, p2) diff --git a/cryptostore/storage_test.go b/cryptostore/storage_test.go index 6c6ea5e2c..78d107c11 100644 --- a/cryptostore/storage_test.go +++ b/cryptostore/storage_test.go @@ -15,7 +15,7 @@ func TestSortKeys(t *testing.T) { // alphabetical order is n3, n1, n2 n1, n2, n3 := "john", "mike", "alice" - infos := keys.KeyInfos{ + infos := keys.Infos{ info(n1, gen()), info(n2, gen()), info(n3, gen()), diff --git a/keys.toml b/keys.toml index 41f4d5286..f9eb95e1c 100644 --- a/keys.toml +++ b/keys.toml @@ -1 +1,2 @@ -format = "text" +output = "text" +keydir = ".mykeys" diff --git a/storage.go b/storage.go index 519ce1aa8..0c25eb8a5 100644 --- a/storage.go +++ b/storage.go @@ -3,8 +3,8 @@ package keys // Storage has many implementation, based on security and sharing requirements // like disk-backed, mem-backed, vault, db, etc. type Storage interface { - Put(name string, key []byte, info KeyInfo) error - Get(name string) ([]byte, KeyInfo, error) - List() ([]KeyInfo, error) + Put(name string, key []byte, info Info) error + Get(name string) ([]byte, Info, error) + List() (Infos, error) Delete(name string) error } diff --git a/storage/filestorage/main.go b/storage/filestorage/main.go index 554a36540..0396c9532 100644 --- a/storage/filestorage/main.go +++ b/storage/filestorage/main.go @@ -49,7 +49,7 @@ func (s FileStore) assertStorage() keys.Storage { // Put creates two files, one with the public info as json, the other // with the (encoded) private key as gpg ascii-armor style -func (s FileStore) Put(name string, key []byte, info keys.KeyInfo) error { +func (s FileStore) Put(name string, key []byte, info keys.Info) error { pub, priv := s.nameToPaths(name) // write public info @@ -62,10 +62,10 @@ func (s FileStore) Put(name string, key []byte, info keys.KeyInfo) error { return write(priv, name, key) } -// Get loads the keyinfo and (encoded) private key from the directory +// Get loads the info and (encoded) private key from the directory // It uses `name` to generate the filename, and returns an error if the // files don't exist or are in the incorrect format -func (s FileStore) Get(name string) ([]byte, keys.KeyInfo, error) { +func (s FileStore) Get(name string) ([]byte, keys.Info, error) { pub, priv := s.nameToPaths(name) info, err := readInfo(pub) @@ -78,8 +78,8 @@ func (s FileStore) Get(name string) ([]byte, keys.KeyInfo, error) { } // List parses the key directory for public info and returns a list of -// KeyInfo for all keys located in this directory. -func (s FileStore) List() ([]keys.KeyInfo, error) { +// Info for all keys located in this directory. +func (s FileStore) List() (keys.Infos, error) { dir, err := os.Open(s.keyDir) if err != nil { return nil, errors.Wrap(err, "List Keys") @@ -91,7 +91,7 @@ func (s FileStore) List() ([]keys.KeyInfo, error) { // filter names for .pub ending and load them one by one // half the files is a good guess for pre-allocating the slice - infos := make([]keys.KeyInfo, 0, len(names)/2) + infos := make([]keys.Info, 0, len(names)/2) for _, name := range names { if strings.HasSuffix(name, PubExt) { p := path.Join(s.keyDir, name) @@ -124,11 +124,11 @@ func (s FileStore) nameToPaths(name string) (pub, priv string) { return path.Join(s.keyDir, pubName), path.Join(s.keyDir, privName) } -func writeInfo(path string, info keys.KeyInfo) error { +func writeInfo(path string, info keys.Info) error { return write(path, info.Name, info.PubKey.Bytes()) } -func readInfo(path string) (info keys.KeyInfo, err error) { +func readInfo(path string) (info keys.Info, err error) { var data []byte data, info.Name, err = read(path) if err != nil { diff --git a/storage/filestorage/main_test.go b/storage/filestorage/main_test.go index f81ba7198..b27fecfb7 100644 --- a/storage/filestorage/main_test.go +++ b/storage/filestorage/main_test.go @@ -23,7 +23,7 @@ func TestBasicCRUD(t *testing.T) { name := "bar" key := []byte("secret-key-here") pubkey := crypto.GenPrivKeyEd25519().PubKey() - info := keys.KeyInfo{ + info := keys.Info{ Name: name, PubKey: crypto.PubKeyS{pubkey}, } diff --git a/storage/memstorage/main.go b/storage/memstorage/main.go index e6573eb9f..9f671e484 100644 --- a/storage/memstorage/main.go +++ b/storage/memstorage/main.go @@ -11,7 +11,7 @@ import ( ) type data struct { - info keys.KeyInfo + info keys.Info key []byte } @@ -29,7 +29,7 @@ func (s MemStore) assertStorage() keys.Storage { // Put adds the given key, returns an error if it another key // is already stored under this name -func (s MemStore) Put(name string, key []byte, info keys.KeyInfo) error { +func (s MemStore) Put(name string, key []byte, info keys.Info) error { if _, ok := s[name]; ok { return errors.Errorf("Key named '%s' already exists", name) } @@ -38,7 +38,7 @@ func (s MemStore) Put(name string, key []byte, info keys.KeyInfo) error { } // Get returns the key stored under the name, or returns an error if not present -func (s MemStore) Get(name string) ([]byte, keys.KeyInfo, error) { +func (s MemStore) Get(name string) ([]byte, keys.Info, error) { var err error d, ok := s[name] if !ok { @@ -48,8 +48,8 @@ func (s MemStore) Get(name string) ([]byte, keys.KeyInfo, error) { } // List returns the public info of all keys in the MemStore in unsorted order -func (s MemStore) List() ([]keys.KeyInfo, error) { - res := make([]keys.KeyInfo, len(s)) +func (s MemStore) List() (keys.Infos, error) { + res := make([]keys.Info, len(s)) i := 0 for _, d := range s { res[i] = d.info diff --git a/storage/memstorage/main_test.go b/storage/memstorage/main_test.go index 01c015a15..2863bffad 100644 --- a/storage/memstorage/main_test.go +++ b/storage/memstorage/main_test.go @@ -15,7 +15,7 @@ func TestBasicCRUD(t *testing.T) { name := "foo" key := []byte("secret-key-here") pubkey := crypto.GenPrivKeyEd25519().PubKey() - info := keys.KeyInfo{ + info := keys.Info{ Name: name, PubKey: crypto.PubKeyS{pubkey}, } diff --git a/transactions.go b/transactions.go index f22719f7e..13f38b41c 100644 --- a/transactions.go +++ b/transactions.go @@ -6,19 +6,19 @@ import ( crypto "github.com/tendermint/go-crypto" ) -// KeyInfo is the public information about a key -type KeyInfo struct { +// Info is the public information about a key +type Info struct { Name string PubKey crypto.PubKeyS } -// KeyInfos is a wrapper to allows alphabetical sorting of the keys -type KeyInfos []KeyInfo +// Infos is a wrapper to allows alphabetical sorting of the keys +type Infos []Info -func (k KeyInfos) Len() int { return len(k) } -func (k KeyInfos) Less(i, j int) bool { return k[i].Name < k[j].Name } -func (k KeyInfos) Swap(i, j int) { k[i], k[j] = k[j], k[i] } -func (k KeyInfos) Sort() { +func (k Infos) Len() int { return len(k) } +func (k Infos) Less(i, j int) bool { return k[i].Name < k[j].Name } +func (k Infos) Swap(i, j int) { k[i], k[j] = k[j], k[i] } +func (k Infos) Sort() { if k != nil { sort.Sort(k) } @@ -51,11 +51,11 @@ type Signer interface { Sign(name, passphrase string, tx Signable) error } -// KeyManager allows simple CRUD on a keystore, as an aid to signing -type KeyManager interface { - Create(name, passphrase string) error - List() (KeyInfos, error) - Get(name string) (KeyInfo, error) +// Manager allows simple CRUD on a keystore, as an aid to signing +type Manager interface { + Create(name, passphrase string) (Info, error) + List() (Infos, error) + Get(name string) (Info, error) Update(name, oldpass, newpass string) error Delete(name, passphrase string) error } From 9c427e95e224e8e375c586e5cbeafe17fa4a1ce6 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Feb 2017 19:02:24 +0100 Subject: [PATCH 033/287] Add update cli command, cleanup --- cmd/new.go | 14 ++------------ cmd/update.go | 34 +++++++++++++++++++++++++++------- cmd/utils.go | 16 ++++++++++++++++ 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/cmd/new.go b/cmd/new.go index 38d9762f9..03e8fd2ce 100644 --- a/cmd/new.go +++ b/cmd/new.go @@ -36,26 +36,16 @@ func init() { func newPassword(cmd *cobra.Command, args []string) { if len(args) != 1 || len(args[0]) == 0 { - fmt.Print("You must provide a name for the key") + fmt.Println("You must provide a name for the key") return } name := args[0] - // TODO: own function??? - pass, err := getPassword("Enter a passphrase:") + pass, err := getCheckPassword("Enter a passphrase:", "Repeat the passphrase:") if err != nil { fmt.Println(err.Error()) return } - pass2, err := getPassword("Repeat the passphrase:") - if err != nil { - fmt.Println(err.Error()) - return - } - if pass != pass2 { - fmt.Println("Passphrases don't match") - return - } info, err := manager.Create(name, pass) if err != nil { diff --git a/cmd/update.go b/cmd/update.go index c36bcf25a..9b5387cb9 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -18,7 +18,6 @@ import ( "fmt" "github.com/spf13/cobra" - "github.com/spf13/viper" ) // updateCmd represents the update command @@ -26,14 +25,35 @@ var updateCmd = &cobra.Command{ Use: "update", Short: "Change the password for a private key", Long: `Change the password for a private key.`, - Run: func(cmd *cobra.Command, args []string) { - // TODO: Work your own magic here - fmt.Println(viper.Get("name")) - fmt.Println("update called") - }, + Run: updatePassword, } func init() { RootCmd.AddCommand(updateCmd) - updateCmd.Flags().StringP("name", "n", "", "Name of key to update") +} + +func updatePassword(cmd *cobra.Command, args []string) { + if len(args) != 1 || len(args[0]) == 0 { + fmt.Println("You must provide a name for the key") + return + } + name := args[0] + + oldpass, err := getPassword("Enter the current passphrase:") + if err != nil { + fmt.Println(err.Error()) + return + } + newpass, err := getCheckPassword("Enter the new passphrase:", "Repeat the new passphrase:") + if err != nil { + fmt.Println(err.Error()) + return + } + + err = manager.Update(name, oldpass, newpass) + if err != nil { + fmt.Println(err.Error()) + } else { + fmt.Println("Password successfully updated!") + } } diff --git a/cmd/utils.go b/cmd/utils.go index bd067f9ca..9a62fe7e8 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -22,6 +22,22 @@ func getPassword(prompt string) (string, error) { return pass, nil } +func getCheckPassword(prompt, prompt2 string) (string, error) { + // TODO: own function??? + pass, err := getPassword(prompt) + if err != nil { + return "", err + } + pass2, err := getPassword(prompt2) + if err != nil { + return "", err + } + if pass != pass2 { + return "", errors.New("Passphrases don't match") + } + return pass, nil +} + func printInfo(info keys.Info) { switch output { case "text": From d5931c9ee39c1482492279cbdc242456bbbc5453 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Feb 2017 19:43:18 +0100 Subject: [PATCH 034/287] Set key algorithm on key creation --- .gitignore | 1 + cmd/README.md | 76 ++++++++++++++++++++++++++++++++++++++ cmd/new.go | 5 ++- cmd/root.go | 5 +-- cryptostore/generator.go | 16 +++++++- cryptostore/holder.go | 19 ++++++---- cryptostore/holder_test.go | 11 +++--- transactions.go | 2 +- 8 files changed, 117 insertions(+), 18 deletions(-) create mode 100644 .gitignore create mode 100644 cmd/README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..cfaef8179 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.mykeys diff --git a/cmd/README.md b/cmd/README.md new file mode 100644 index 000000000..97ea787c9 --- /dev/null +++ b/cmd/README.md @@ -0,0 +1,76 @@ +# Keys CLI + +This is as much an example how to expose cobra/viper, as for a cli itself +(I think this code is overkill for what go-keys needs). But please look at +the commands, and give feedback and changes. + +`RootCmd` calls some initialization functions (`cobra.OnInitialize` and `RootCmd.PersistentPreRunE`) which serve to connect environmental variables and cobra flags, as well as load the config file. It also validates the flags registered on root and creates the cryptomanager, which will be used by all subcommands. + +## Help info + +``` +# keys help +Keys allows you to manage your local keystore for tendermint. + +These keys may be in any format supported by go-crypto and can be +used by light-clients, full nodes, or any other application that +needs to sign with a private key. + +Usage: + keys [command] + +Available Commands: + list List all keys + new Create a new public/private key pair + serve Run the key manager as an http server + update Change the password for a private key + +Flags: + --keydir string Directory to store private keys (subdir of root) (default "keys") + -o, --output string Output format (text|json) (default "text") + -r, --root string root directory for config and data (default "/Users/ethan/.tlc") + +Use "keys [command] --help" for more information about a command.``` + +## Getting the config file + +The first step is to load in root, by checking the following in order: + +* -r, --root command line flag +* TM_ROOT environmental variable +* default ($HOME/.tlc evaluated at runtime) + +Once the `rootDir` is established, the script looks for a config file named `keys.{json,toml,yaml,hcl}` in that directory and parses it. These values will provide defaults for flags of the same name. + +## Getting/Setting variables + +When we want to get the value of a user-defined variable (eg. `output`), we can call `viper.GetString("output")`, which will do the following checks, until it finds a match: + +* Is `--output` command line flag present? +* Is `TM_OUTPUT` environmental variable set? +* Was a config file found and does it have an `output` variable? +* Is there a default set on the command line flag? + +If no variable is set and there was no default, we get back "". + +This setup allows us to have powerful command line flags, but use env variables or config files (local or 12-factor style) to avoid passing these arguments every time. + +## Nesting structures + +Sometimes we don't just need key-value pairs, but actually a multi-level config file, like + +``` +[mail] +from = "no-reply@example.com" +server = "mail.example.com" +port = 567 +password = "XXXXXX" +``` + +This CLI is too simple to warant such a structure, but I think eg. tendermint could benefit from such an approach. Here are some pointers: + +* [Accessing nested keys from config files](https://github.com/spf13/viper#accessing-nested-keys) +* [Overriding nested values with envvars](https://www.netlify.com/blog/2016/09/06/creating-a-microservice-boilerplate-in-go/#nested-config-values) - the mentioned outstanding PR is already merged into master! +* Overriding nested values with cli flags? (use `--log_config.level=info` ??) + +I'd love to see an example of this fully worked out in a more complex CLI. diff --git a/cmd/new.go b/cmd/new.go index 03e8fd2ce..5ac0d3b90 100644 --- a/cmd/new.go +++ b/cmd/new.go @@ -18,6 +18,7 @@ import ( "fmt" "github.com/spf13/cobra" + "github.com/spf13/viper" ) // newCmd represents the new command @@ -32,6 +33,7 @@ passed as a command line argument for security.`, func init() { RootCmd.AddCommand(newCmd) + newCmd.Flags().StringP("type", "t", "ed25519", "Type of key (ed25519|secp256k1") } func newPassword(cmd *cobra.Command, args []string) { @@ -40,6 +42,7 @@ func newPassword(cmd *cobra.Command, args []string) { return } name := args[0] + algo := viper.GetString("type") pass, err := getCheckPassword("Enter a passphrase:", "Repeat the passphrase:") if err != nil { @@ -47,7 +50,7 @@ func newPassword(cmd *cobra.Command, args []string) { return } - info, err := manager.Create(name, pass) + info, err := manager.Create(name, pass, algo) if err != nil { fmt.Println(err.Error()) return diff --git a/cmd/root.go b/cmd/root.go index 9d7ae9a9e..7f5122af2 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -58,9 +58,9 @@ func Execute() { func init() { cobra.OnInitialize(initEnv) - RootCmd.PersistentFlags().StringP("root", "r", os.ExpandEnv("$HOME/.tlc"), "root directory for config and data (default is TM_ROOT or $HOME/.tlc)") + RootCmd.PersistentFlags().StringP("root", "r", os.ExpandEnv("$HOME/.tlc"), "root directory for config and data") RootCmd.PersistentFlags().StringP("output", "o", "text", "Output format (text|json)") - RootCmd.PersistentFlags().StringP("keydir", "", "keys", "Directory to store private keys (subdir of root)") + RootCmd.PersistentFlags().String("keydir", "keys", "Directory to store private keys (subdir of root)") } // initEnv sets to use ENV variables if set. @@ -107,7 +107,6 @@ func validateFlags(cmd *cobra.Command) error { } // and construct the key manager manager = cryptostore.New( - cryptostore.GenEd25519, // TODO - cli switch??? cryptostore.SecretBox, filestorage.New(keyDir), ) diff --git a/cryptostore/generator.go b/cryptostore/generator.go index c6661fb34..cf877f20b 100644 --- a/cryptostore/generator.go +++ b/cryptostore/generator.go @@ -1,6 +1,9 @@ package cryptostore -import crypto "github.com/tendermint/go-crypto" +import ( + "github.com/pkg/errors" + crypto "github.com/tendermint/go-crypto" +) var ( // GenEd25519 produces Ed25519 private keys @@ -28,3 +31,14 @@ func genEd25519() crypto.PrivKey { func genSecp256() crypto.PrivKey { return crypto.GenPrivKeySecp256k1() } + +func getGenerator(algo string) (Generator, error) { + switch algo { + case crypto.NameEd25519: + return GenEd25519, nil + case crypto.NameSecp256k1: + return GenSecp256k1, nil + default: + return nil, errors.Errorf("Cannot generate keys for algorithm: %s", algo) + } +} diff --git a/cryptostore/holder.go b/cryptostore/holder.go index 29682a87d..549326614 100644 --- a/cryptostore/holder.go +++ b/cryptostore/holder.go @@ -5,13 +5,11 @@ import keys "github.com/tendermint/go-keys" // Manager combines encyption and storage implementation to provide // a full-featured key manager type Manager struct { - gen Generator - es encryptedStorage + es encryptedStorage } -func New(gen Generator, coder Encoder, store keys.Storage) Manager { +func New(coder Encoder, store keys.Storage) Manager { return Manager{ - gen: gen, es: encryptedStorage{ coder: coder, store: store, @@ -31,9 +29,16 @@ func (s Manager) assertKeyManager() keys.Manager { // Create adds a new key to the storage engine, returning error if // another key already stored under this name -func (s Manager) Create(name, passphrase string) (keys.Info, error) { - key := s.gen.Generate() - err := s.es.Put(name, passphrase, key) +// +// algo must be a supported go-crypto algorithm: +// +func (s Manager) Create(name, passphrase, algo string) (keys.Info, error) { + gen, err := getGenerator(algo) + if err != nil { + return keys.Info{}, err + } + key := gen.Generate() + err = s.es.Put(name, passphrase, key) return info(name, key), err } diff --git a/cryptostore/holder_test.go b/cryptostore/holder_test.go index 116b92c4e..860869c86 100644 --- a/cryptostore/holder_test.go +++ b/cryptostore/holder_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + crypto "github.com/tendermint/go-crypto" "github.com/tendermint/go-keys/cryptostore" "github.com/tendermint/go-keys/storage/memstorage" ) @@ -15,11 +16,11 @@ func TestKeyManagement(t *testing.T) { // make the storage with reasonable defaults cstore := cryptostore.New( - cryptostore.GenSecp256k1, cryptostore.SecretBox, memstorage.New(), ) + algo := crypto.NameEd25519 n1, n2, n3 := "personal", "business", "other" p1, p2 := "1234", "really-secure!@#$" @@ -31,10 +32,10 @@ func TestKeyManagement(t *testing.T) { // create some keys _, err = cstore.Get(n1) assert.NotNil(err) - i, err := cstore.Create(n1, p1) + i, err := cstore.Create(n1, p1, algo) require.Equal(n1, i.Name) require.Nil(err) - _, err = cstore.Create(n2, p2) + _, err = cstore.Create(n2, p2, algo) require.Nil(err) // we can get these keys @@ -151,16 +152,16 @@ func TestAdvancedKeyManagement(t *testing.T) { // make the storage with reasonable defaults cstore := cryptostore.New( - cryptostore.GenSecp256k1, cryptostore.SecretBox, memstorage.New(), ) + algo := crypto.NameSecp256k1 n1, n2 := "old-name", "new name" p1, p2, p3, pt := "1234", "foobar", "ding booms!", "really-secure!@#$" // make sure key works with initial password - _, err := cstore.Create(n1, p1) + _, err := cstore.Create(n1, p1, algo) require.Nil(err, "%+v", err) assertPassword(assert, cstore, n1, p1, p2) diff --git a/transactions.go b/transactions.go index 13f38b41c..3acb476cf 100644 --- a/transactions.go +++ b/transactions.go @@ -53,7 +53,7 @@ type Signer interface { // Manager allows simple CRUD on a keystore, as an aid to signing type Manager interface { - Create(name, passphrase string) (Info, error) + Create(name, passphrase, algo string) (Info, error) List() (Infos, error) Get(name string) (Info, error) Update(name, oldpass, newpass string) error From c59e2d7d13084fb4860fbe4b67db4bef4760e622 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Feb 2017 20:07:44 +0100 Subject: [PATCH 035/287] Expose address in keyinfo, add get command --- cmd/README.md | 7 ++++- cmd/get.go | 47 ++++++++++++++++++++++++++++++++ cmd/root.go | 3 +- cmd/update.go | 2 +- cmd/utils.go | 8 ++++-- cryptostore/enc_storage.go | 6 ++-- storage/filestorage/main.go | 4 +-- storage/filestorage/main_test.go | 6 ++-- storage/memstorage/main.go | 4 +-- storage/memstorage/main_test.go | 6 ++-- transactions.go | 13 +++++++-- 11 files changed, 89 insertions(+), 17 deletions(-) create mode 100644 cmd/get.go diff --git a/cmd/README.md b/cmd/README.md index 97ea787c9..72f202bf1 100644 --- a/cmd/README.md +++ b/cmd/README.md @@ -10,6 +10,7 @@ the commands, and give feedback and changes. ``` # keys help + Keys allows you to manage your local keystore for tendermint. These keys may be in any format supported by go-crypto and can be @@ -20,6 +21,7 @@ Usage: keys [command] Available Commands: + get Get details of one key list List all keys new Create a new public/private key pair serve Run the key manager as an http server @@ -30,7 +32,8 @@ Flags: -o, --output string Output format (text|json) (default "text") -r, --root string root directory for config and data (default "/Users/ethan/.tlc") -Use "keys [command] --help" for more information about a command.``` +Use "keys [command] --help" for more information about a command. +``` ## Getting the config file @@ -42,6 +45,8 @@ The first step is to load in root, by checking the following in order: Once the `rootDir` is established, the script looks for a config file named `keys.{json,toml,yaml,hcl}` in that directory and parses it. These values will provide defaults for flags of the same name. +There is an example config file for testing out locally, which writes keys to `./.mykeys`. You can + ## Getting/Setting variables When we want to get the value of a user-defined variable (eg. `output`), we can call `viper.GetString("output")`, which will do the following checks, until it finds a match: diff --git a/cmd/get.go b/cmd/get.go new file mode 100644 index 000000000..d945809f9 --- /dev/null +++ b/cmd/get.go @@ -0,0 +1,47 @@ +// Copyright © 2017 Ethan Frey +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +// getCmd represents the get command +var getCmd = &cobra.Command{ + Use: "get ", + Short: "Get details of one key", + Long: `Return public details of one local key.`, + Run: func(cmd *cobra.Command, args []string) { + if len(args) != 1 || len(args[0]) == 0 { + fmt.Println("You must provide a name for the key") + return + } + name := args[0] + + info, err := manager.Get(name) + if err != nil { + fmt.Println(err.Error()) + return + } + + printInfo(info) + }, +} + +func init() { + RootCmd.AddCommand(getCmd) +} diff --git a/cmd/root.go b/cmd/root.go index 7f5122af2..029c37f9d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -84,7 +84,8 @@ func bindFlags(cmd *cobra.Command, args []string) error { // If a config file is found, read it in. if err := viper.ReadInConfig(); err == nil { - fmt.Println("Using config file:", viper.ConfigFileUsed()) + // stderr, so if we redirect output to json file, this doesn't appear + fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) } return validateFlags(cmd) diff --git a/cmd/update.go b/cmd/update.go index 9b5387cb9..0340944be 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -22,7 +22,7 @@ import ( // updateCmd represents the update command var updateCmd = &cobra.Command{ - Use: "update", + Use: "update ", Short: "Change the password for a private key", Long: `Change the password for a private key.`, Run: updatePassword, diff --git a/cmd/utils.go b/cmd/utils.go index 9a62fe7e8..01f9801ae 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -41,11 +41,15 @@ func getCheckPassword(prompt, prompt2 string) (string, error) { func printInfo(info keys.Info) { switch output { case "text": - key, err := data.ToText(info.PubKey) + addr, err := data.ToText(info.Address) if err != nil { panic(err) // really shouldn't happen... } - fmt.Printf("%s\t%s\n", info.Name, key) + sep := "\t\t" + if len(info.Name) > 7 { + sep = "\t" + } + fmt.Printf("%s%s%s\n", info.Name, sep, addr) case "json": json, err := data.ToJSON(info) if err != nil { diff --git a/cryptostore/enc_storage.go b/cryptostore/enc_storage.go index 759ca90e9..9589f4cc1 100644 --- a/cryptostore/enc_storage.go +++ b/cryptostore/enc_storage.go @@ -40,8 +40,10 @@ func (es encryptedStorage) Delete(name string) error { // info hardcodes the encoding of keys func info(name string, key crypto.PrivKey) keys.Info { + pub := key.PubKey() return keys.Info{ - Name: name, - PubKey: crypto.PubKeyS{key.PubKey()}, + Name: name, + Address: pub.Address(), + PubKey: crypto.PubKeyS{pub}, } } diff --git a/storage/filestorage/main.go b/storage/filestorage/main.go index 0396c9532..4b7dbe525 100644 --- a/storage/filestorage/main.go +++ b/storage/filestorage/main.go @@ -74,7 +74,7 @@ func (s FileStore) Get(name string) ([]byte, keys.Info, error) { } key, _, err := read(priv) - return key, info, err + return key, info.Format(), err } // List parses the key directory for public info and returns a list of @@ -99,7 +99,7 @@ func (s FileStore) List() (keys.Infos, error) { if err != nil { return nil, err } - infos = append(infos, info) + infos = append(infos, info.Format()) } } diff --git a/storage/filestorage/main_test.go b/storage/filestorage/main_test.go index b27fecfb7..c9c55eb02 100644 --- a/storage/filestorage/main_test.go +++ b/storage/filestorage/main_test.go @@ -49,11 +49,13 @@ func TestBasicCRUD(t *testing.T) { k, i, err := store.Get(name) require.Nil(err, "%+v", err) assert.Equal(key, k) - assert.Equal(info, i) + assert.Equal(info.Name, i.Name) + assert.Equal(info.PubKey, i.PubKey) + assert.NotEmpty(i.Address) l, err = store.List() require.Nil(err, "%+v", err) assert.Equal(1, len(l)) - assert.Equal(info, l[0]) + assert.Equal(i, l[0]) // querying a non-existent key fails _, _, err = store.Get("badname") diff --git a/storage/memstorage/main.go b/storage/memstorage/main.go index 9f671e484..69c8d9b03 100644 --- a/storage/memstorage/main.go +++ b/storage/memstorage/main.go @@ -44,7 +44,7 @@ func (s MemStore) Get(name string) ([]byte, keys.Info, error) { if !ok { err = errors.Errorf("Key named '%s' doesn't exist", name) } - return d.key, d.info, err + return d.key, d.info.Format(), err } // List returns the public info of all keys in the MemStore in unsorted order @@ -52,7 +52,7 @@ func (s MemStore) List() (keys.Infos, error) { res := make([]keys.Info, len(s)) i := 0 for _, d := range s { - res[i] = d.info + res[i] = d.info.Format() i++ } return res, nil diff --git a/storage/memstorage/main_test.go b/storage/memstorage/main_test.go index 2863bffad..7605c8225 100644 --- a/storage/memstorage/main_test.go +++ b/storage/memstorage/main_test.go @@ -41,11 +41,13 @@ func TestBasicCRUD(t *testing.T) { k, i, err := store.Get(name) assert.Nil(err) assert.Equal(key, k) - assert.Equal(info, i) + assert.Equal(info.Name, i.Name) + assert.Equal(info.PubKey, i.PubKey) + assert.NotEmpty(i.Address) l, err = store.List() assert.Nil(err) assert.Equal(1, len(l)) - assert.Equal(info, l[0]) + assert.Equal(i, l[0]) // querying a non-existent key fails _, _, err = store.Get("badname") diff --git a/transactions.go b/transactions.go index 3acb476cf..91dc0e273 100644 --- a/transactions.go +++ b/transactions.go @@ -4,12 +4,21 @@ import ( "sort" crypto "github.com/tendermint/go-crypto" + data "github.com/tendermint/go-data" ) // Info is the public information about a key type Info struct { - Name string - PubKey crypto.PubKeyS + Name string `json:"name"` + Address data.Bytes `json:"address"` + PubKey crypto.PubKeyS `json:"pubkey"` +} + +func (i *Info) Format() Info { + if !i.PubKey.Empty() { + i.Address = i.PubKey.Address() + } + return *i } // Infos is a wrapper to allows alphabetical sorting of the keys From e1c717a04863a9ddf24251a9eaec14feaf7da37a Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Feb 2017 20:26:45 +0100 Subject: [PATCH 036/287] Add support for hex / base64 / btc (b58) encoding of binary data --- cmd/README.md | 36 ++++++++++++++++++++++++++++++++++++ cmd/root.go | 18 +++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/cmd/README.md b/cmd/README.md index 72f202bf1..8bf9ca73b 100644 --- a/cmd/README.md +++ b/cmd/README.md @@ -79,3 +79,39 @@ This CLI is too simple to warant such a structure, but I think eg. tendermint co * Overriding nested values with cli flags? (use `--log_config.level=info` ??) I'd love to see an example of this fully worked out in a more complex CLI. + +## Have your cake and eat it too + +It's easy to render data different ways. Some better for viewing, some better for importing to other programs. You can just add some global (persistent) flags to control the output formatting, and everyone gets what they want. + +``` +# keys list -e hex +All keys: +betty d0789984492b1674e276b590d56b7ae077f81adc +john b77f4720b220d1411a649b6c7f1151eb6b1c226a + +# keys list -e btc +All keys: +betty 3uTF4r29CbtnzsNHZoPSYsE4BDwH +john 3ZGp2Md35iw4XVtRvZDUaAEkCUZP + +# keys list -e b64 -o json +[ + { + "name": "betty", + "address": "0HiZhEkrFnTidrWQ1Wt64Hf4Gtw=", + "pubkey": { + "type": "secp256k1", + "data": "F83WvhT0KwttSoqQqd_0_r2ztUUaQix5EXdO8AZyREoV31Og780NW59HsqTAb2O4hZ-w-j0Z-4b2IjfdqqfhVQ==" + } + }, + { + "name": "john", + "address": "t39HILIg0UEaZJtsfxFR62scImo=", + "pubkey": { + "type": "ed25519", + "data": "t1LFmbg_8UTwj-n1wkqmnTp6NfaOivokEhlYySlGYCY=" + } + } +] +``` diff --git a/cmd/root.go b/cmd/root.go index 029c37f9d..41803fc65 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -23,6 +23,8 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" + data "github.com/tendermint/go-data" + "github.com/tendermint/go-data/base58" keys "github.com/tendermint/go-keys" "github.com/tendermint/go-keys/cryptostore" "github.com/tendermint/go-keys/storage/filestorage" @@ -59,8 +61,9 @@ func Execute() { func init() { cobra.OnInitialize(initEnv) RootCmd.PersistentFlags().StringP("root", "r", os.ExpandEnv("$HOME/.tlc"), "root directory for config and data") - RootCmd.PersistentFlags().StringP("output", "o", "text", "Output format (text|json)") RootCmd.PersistentFlags().String("keydir", "keys", "Directory to store private keys (subdir of root)") + RootCmd.PersistentFlags().StringP("output", "o", "text", "Output format (text|json)") + RootCmd.PersistentFlags().StringP("encoding", "e", "hex", "Binary encoding (hex|b64|btc)") } // initEnv sets to use ENV variables if set. @@ -101,6 +104,19 @@ func validateFlags(cmd *cobra.Command) error { return errors.Errorf("Unsupported output format: %s", output) } + // validate and set encoding + enc := viper.GetString("encoding") + switch enc { + case "hex": + data.Encoder = data.HexEncoder + case "b64": + data.Encoder = data.B64Encoder + case "btc": + data.Encoder = base58.BTCEncoder + default: + return errors.Errorf("Unsupported encoding: %s", enc) + } + // store the keys directory keyDir = viper.GetString("keydir") if !filepath.IsAbs(keyDir) { From 6ec2330eb8dbecb17495d2dc0565ace570adf457 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Feb 2017 21:09:35 +0100 Subject: [PATCH 037/287] Import keys server from light-client, with changes --- proxy/README.md | 65 +++++++++++++++ proxy/helpers.go | 58 ++++++++++++++ proxy/keys.go | 123 ++++++++++++++++++++++++++++ proxy/keys_test.go | 190 ++++++++++++++++++++++++++++++++++++++++++++ proxy/types/keys.go | 28 +++++++ proxy/valid.go | 12 +++ 6 files changed, 476 insertions(+) create mode 100644 proxy/README.md create mode 100644 proxy/helpers.go create mode 100644 proxy/keys.go create mode 100644 proxy/keys_test.go create mode 100644 proxy/types/keys.go create mode 100644 proxy/valid.go diff --git a/proxy/README.md b/proxy/README.md new file mode 100644 index 000000000..614110b7f --- /dev/null +++ b/proxy/README.md @@ -0,0 +1,65 @@ +# Proxy Server + +This package provides all the functionality for a local proxy http server, and ties together functionality from all the other packages to acheive this aim. Simply configure this server with your application-specific settings via a main script and you are good to go. + +This server should run on the client's machine, and can accept a trusted connection from localhost (via tcp or unix socket). It provides a simple json rest API and handles all the binary wrangling and cryptographic proofs under the hood. Thus, you can host a local webapp (via electron?) and connect to this proxy, perform simple queries and posts and behind the scenes take advantage of the *awesome power* of the tendermint blockchain. + +If you are writing native code, you can use this as well, or you can look for bindings to embed this functionality directly as a library in your codebase. +**(coming soon)** + +## API + +The API has various sections based on functionality. The major portions are key management, signing and posting transactions, and querying and proving data. + +### Key Management + +We expose a number of methods for safely managing your keychain. They are typically bound under `/keys`, but could be placed in another location by the app. + +* `POST /keys/` - provide a name and passphrase and create a brand new key +* `GET /keys/` - get a list of all available key names, along with their public key and address +* `GET /keys/{name}` - get public key and address for this named key + +Later expose: + +* `PUT /keys/{name}` - update the passphrase for the given key. requires you to correctly provide the current passphrase, as well as a new one. +* `DELETE /keys/{name}` - permanently delete this private key. requires you to correctly provide the current passphrase +* export and import functionality + +### Transactions + +You want to post your transaction. Great. Your application must provide logic to transform json into a `Signable` go struct. Then we handle the rest, signing it with a keypair of your choosing, posting it to tendermint core, and returning you confirmation when it was committed. + +* `POST /txs/` - provide name, passphrase and application-specific data to post to tendermint + + +### Proving Data + +We sent some money to our friend, now we want to check his balance. No, not just look at it, but really check it, verify all those cryptographic proofs that some node is not lying and it really, truly is in his account. + +Thankfully, we have the technology and can do all the checks in the proxy, it might just take a second or two for us to get all those block headers. + +However, this still just leaves us with a bunch of binary blobs from the server, so to make this whole process less painless, you should provide some application-specific logic to parse this binary data from the blockchain, so we can present it as json over the interface. + +* `GET /query/{path}/{data}` - will quickly query the data under the given (hex-encoded) key. `path` is `key` to query by merkle key, but your application could provide other prefixes, to differentiate by types (eg. `account`, `votes`, `escrow`). The returned data is parsed into json and displayed. +* `GET /proof/{key}` - will query for a merkle proof of the given key, download block headers, and verify all the signatures of that block. After it is done, it will present you some json and a stamp that it your data is really safe and sound. + +## Configuring + +When you instantiate a server, make sure to pass in application-specific info in order to properly. Like the following info: + +Possibly as command-line flags: + +* Where to store the private keys? (or find existing ones) +* Which type of key to generate? +* What is the URL of the tendermint RPC server? + * TODO: support multiple node URLs and round-robin +* What is the chain_id we wish to connect to? + +Extra code (plugin) you must write: + +* Logic to parse json -> `Signable` transaction +* Logic to parse binary values from merkle tree -> `struct`ured data to render + +TODO: + +* How to get the trusted validator set? diff --git a/proxy/helpers.go b/proxy/helpers.go new file mode 100644 index 000000000..ac314684b --- /dev/null +++ b/proxy/helpers.go @@ -0,0 +1,58 @@ +/* +package proxy provides http handlers to construct a proxy server +for key management, transaction signing, and query validation. + +Please read the README and godoc to see how to +configure the server for your application. +*/ +package proxy + +import ( + "encoding/json" + "io/ioutil" + "net/http" + + data "github.com/tendermint/go-data" + "github.com/tendermint/go-keys/proxy/types" + + "github.com/pkg/errors" +) + +func readRequest(r *http.Request, o interface{}) error { + defer r.Body.Close() + data, err := ioutil.ReadAll(r.Body) + if err != nil { + return errors.Wrap(err, "Read Request") + } + err = json.Unmarshal(data, o) + if err != nil { + return errors.Wrap(err, "Parse") + } + return validate(o) +} + +// most errors are bad input, so 406... do better.... +func writeError(w http.ResponseWriter, err error) { + // fmt.Printf("Error: %+v\n", err) + res := types.ErrorResponse{ + Code: 406, + Error: err.Error(), + } + writeCode(w, &res, 406) +} + +func writeCode(w http.ResponseWriter, o interface{}, code int) { + // two space indent to make it easier to read + data, err := data.ToJSON(o) + if err != nil { + writeError(w, err) + } else { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(code) + w.Write(data) + } +} + +func writeSuccess(w http.ResponseWriter, o interface{}) { + writeCode(w, o, 200) +} diff --git a/proxy/keys.go b/proxy/keys.go new file mode 100644 index 000000000..64b6819cd --- /dev/null +++ b/proxy/keys.go @@ -0,0 +1,123 @@ +package proxy + +import ( + "errors" + "net/http" + + "github.com/gorilla/mux" + keys "github.com/tendermint/go-keys" + "github.com/tendermint/go-keys/proxy/types" +) + +type KeyServer struct { + manager keys.Manager +} + +func NewKeyServer(manager keys.Manager) KeyServer { + return KeyServer{ + manager: manager, + } +} + +func (k KeyServer) GenerateKey(w http.ResponseWriter, r *http.Request) { + req := types.CreateKeyRequest{} + err := readRequest(r, &req) + if err != nil { + writeError(w, err) + return + } + + key, err := k.manager.Create(req.Name, req.Passphrase, req.Algo) + if err != nil { + writeError(w, err) + return + } + + writeSuccess(w, &key) +} + +func (k KeyServer) GetKey(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + name := vars["name"] + key, err := k.manager.Get(name) + if err != nil { + writeError(w, err) + return + } + writeSuccess(w, &key) +} + +func (k KeyServer) ListKeys(w http.ResponseWriter, r *http.Request) { + + keys, err := k.manager.List() + if err != nil { + writeError(w, err) + return + } + writeSuccess(w, keys) +} + +func (k KeyServer) UpdateKey(w http.ResponseWriter, r *http.Request) { + req := types.UpdateKeyRequest{} + err := readRequest(r, &req) + if err != nil { + writeError(w, err) + return + } + + vars := mux.Vars(r) + name := vars["name"] + if name != req.Name { + writeError(w, errors.New("path and json key names don't match")) + return + } + + err = k.manager.Update(req.Name, req.OldPass, req.NewPass) + if err != nil { + writeError(w, err) + return + } + + key, err := k.manager.Get(req.Name) + if err != nil { + writeError(w, err) + return + } + writeSuccess(w, &key) +} + +func (k KeyServer) DeleteKey(w http.ResponseWriter, r *http.Request) { + req := types.DeleteKeyRequest{} + err := readRequest(r, &req) + if err != nil { + writeError(w, err) + return + } + + vars := mux.Vars(r) + name := vars["name"] + if name != req.Name { + writeError(w, errors.New("path and json key names don't match")) + return + } + + err = k.manager.Delete(req.Name, req.Passphrase) + if err != nil { + writeError(w, err) + return + } + + // not really an error, but something generic + resp := types.ErrorResponse{ + Success: true, + } + writeSuccess(w, &resp) +} + +func (k KeyServer) Register(r *mux.Router) { + r.HandleFunc("/", k.GenerateKey).Methods("POST") + r.HandleFunc("/", k.ListKeys).Methods("GET") + r.HandleFunc("/{name}", k.GetKey).Methods("GET") + r.HandleFunc("/{name}", k.UpdateKey).Methods("POST", "PUT") + r.HandleFunc("/{name}", k.DeleteKey).Methods("DELETE") +} diff --git a/proxy/keys_test.go b/proxy/keys_test.go new file mode 100644 index 000000000..6eee94e39 --- /dev/null +++ b/proxy/keys_test.go @@ -0,0 +1,190 @@ +package proxy_test + +import ( + "bytes" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/gorilla/mux" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + keys "github.com/tendermint/go-keys" + "github.com/tendermint/go-keys/cryptostore" + "github.com/tendermint/go-keys/proxy" + "github.com/tendermint/go-keys/proxy/types" + "github.com/tendermint/go-keys/storage/memstorage" +) + +func TestKeyServer(t *testing.T) { + assert, require := assert.New(t), require.New(t) + r := setupServer() + + // let's abstract this out a bit.... + keys, code, err := listKeys(r) + require.Nil(err) + require.Equal(http.StatusOK, code) + assert.Equal(0, len(keys)) + + algo := "ed25519" + n1, n2 := "personal", "business" + p0, p1, p2 := "1234", "over10chars...", "really-secure!@#$" + + // this fails for validation + _, code, err = createKey(r, n1, p0, algo) + require.Nil(err, "%+v", err) + require.NotEqual(http.StatusOK, code) + + // new password better + key, code, err := createKey(r, n1, p1, algo) + require.Nil(err, "%+v", err) + require.Equal(http.StatusOK, code) + require.Equal(key.Name, n1) + + // the other one works + key2, code, err := createKey(r, n2, p2, algo) + require.Nil(err, "%+v", err) + require.Equal(http.StatusOK, code) + require.Equal(key2.Name, n2) + + // let's abstract this out a bit.... + keys, code, err = listKeys(r) + require.Nil(err) + require.Equal(http.StatusOK, code) + if assert.Equal(2, len(keys)) { + // in alphabetical order + assert.Equal(keys[0].Name, n2) + assert.Equal(keys[1].Name, n1) + } + + // get works + k, code, err := getKey(r, n1) + require.Nil(err, "%+v", err) + require.Equal(http.StatusOK, code) + assert.Equal(k.Name, n1) + assert.NotNil(k.Address) + assert.Equal(k.Address, key.Address) + + // delete with proper key + _, code, err = deleteKey(r, n1, p1) + require.Nil(err, "%+v", err) + require.Equal(http.StatusOK, code) + + // after delete, get and list different + _, code, err = getKey(r, n1) + require.Nil(err, "%+v", err) + require.NotEqual(http.StatusOK, code) + keys, code, err = listKeys(r) + require.Nil(err, "%+v", err) + require.Equal(http.StatusOK, code) + if assert.Equal(1, len(keys)) { + assert.Equal(keys[0].Name, n2) + } + +} + +func setupServer() http.Handler { + // make the storage with reasonable defaults + cstore := cryptostore.New( + cryptostore.SecretBox, + memstorage.New(), + ) + + // build your http server + ks := proxy.NewKeyServer(cstore) + r := mux.NewRouter() + sk := r.PathPrefix("/keys").Subrouter() + ks.Register(sk) + return r +} + +// return data, status code, and error +func listKeys(h http.Handler) (keys.Infos, int, error) { + rr := httptest.NewRecorder() + req, err := http.NewRequest("GET", "/keys/", nil) + if err != nil { + return nil, 0, err + } + + h.ServeHTTP(rr, req) + if http.StatusOK != rr.Code { + return nil, rr.Code, nil + } + + data := keys.Infos{} + err = json.Unmarshal(rr.Body.Bytes(), &data) + return data, rr.Code, err +} + +func getKey(h http.Handler, name string) (*keys.Info, int, error) { + rr := httptest.NewRecorder() + req, err := http.NewRequest("GET", "/keys/"+name, nil) + if err != nil { + return nil, 0, err + } + + h.ServeHTTP(rr, req) + if http.StatusOK != rr.Code { + return nil, rr.Code, nil + } + + data := keys.Info{} + err = json.Unmarshal(rr.Body.Bytes(), &data) + return &data, rr.Code, err +} + +func createKey(h http.Handler, name, passphrase, algo string) (*keys.Info, int, error) { + rr := httptest.NewRecorder() + post := types.CreateKeyRequest{ + Name: name, + Passphrase: passphrase, + Algo: algo, + } + var b bytes.Buffer + err := json.NewEncoder(&b).Encode(&post) + if err != nil { + return nil, 0, err + } + + req, err := http.NewRequest("POST", "/keys/", &b) + if err != nil { + return nil, 0, err + } + + h.ServeHTTP(rr, req) + if http.StatusOK != rr.Code { + return nil, rr.Code, nil + } + + data := keys.Info{} + err = json.Unmarshal(rr.Body.Bytes(), &data) + return &data, rr.Code, err +} + +func deleteKey(h http.Handler, name, passphrase string) (*types.ErrorResponse, int, error) { + rr := httptest.NewRecorder() + post := types.DeleteKeyRequest{ + Name: name, + Passphrase: passphrase, + } + var b bytes.Buffer + err := json.NewEncoder(&b).Encode(&post) + if err != nil { + return nil, 0, err + } + + req, err := http.NewRequest("DELETE", "/keys/"+name, &b) + if err != nil { + return nil, 0, err + } + + h.ServeHTTP(rr, req) + if http.StatusOK != rr.Code { + return nil, rr.Code, nil + } + + data := types.ErrorResponse{} + err = json.Unmarshal(rr.Body.Bytes(), &data) + return &data, rr.Code, err +} diff --git a/proxy/types/keys.go b/proxy/types/keys.go new file mode 100644 index 000000000..ffdc542f1 --- /dev/null +++ b/proxy/types/keys.go @@ -0,0 +1,28 @@ +package types + +// CreateKeyRequest is sent to create a new key +type CreateKeyRequest struct { + Name string `json:"name" validate:"required,min=4,printascii"` + Passphrase string `json:"passphrase" validate:"required,min=10"` + Algo string `json:"algo"` +} + +// DeleteKeyRequest to destroy a key permanently (careful!) +type DeleteKeyRequest struct { + Name string `json:"name" validate:"required,min=4,printascii"` + Passphrase string `json:"passphrase" validate:"required,min=10"` +} + +// UpdateKeyRequest is sent to update the passphrase for an existing key +type UpdateKeyRequest struct { + Name string `json:"name" validate:"required,min=4,printascii"` + OldPass string `json:"passphrase" validate:"required,min=10"` + NewPass string `json:"new_passphrase" validate:"required,min=10"` +} + +// ErrorResponse is returned for 4xx and 5xx errors +type ErrorResponse struct { + Success bool `json:"success"` + Error string `json:"error"` // error message if Success is false + Code int `json:"code"` // error code if Success is false +} diff --git a/proxy/valid.go b/proxy/valid.go new file mode 100644 index 000000000..31782cfca --- /dev/null +++ b/proxy/valid.go @@ -0,0 +1,12 @@ +package proxy + +import ( + "github.com/pkg/errors" + "gopkg.in/go-playground/validator.v9" +) + +var v = validator.New() + +func validate(req interface{}) error { + return errors.Wrap(v.Struct(req), "Validate") +} From 6389d208ccd68d5f921b005d60b00e3126882bec Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Feb 2017 21:33:27 +0100 Subject: [PATCH 038/287] Key server API integrated in CLI --- cmd/new.go | 2 +- cmd/serve.go | 78 +++++++++++++++++++++++++++++++++++++++------- proxy/keys.go | 8 +++-- proxy/keys_test.go | 2 +- 4 files changed, 75 insertions(+), 15 deletions(-) diff --git a/cmd/new.go b/cmd/new.go index 5ac0d3b90..27c7dce75 100644 --- a/cmd/new.go +++ b/cmd/new.go @@ -33,7 +33,7 @@ passed as a command line argument for security.`, func init() { RootCmd.AddCommand(newCmd) - newCmd.Flags().StringP("type", "t", "ed25519", "Type of key (ed25519|secp256k1") + newCmd.Flags().StringP("type", "t", "ed25519", "Type of key (ed25519|secp256k1)") } func newPassword(cmd *cobra.Command, args []string) { diff --git a/cmd/serve.go b/cmd/serve.go index 06e923c7b..1555c6480 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -16,8 +16,16 @@ package cmd import ( "fmt" + "net" + "net/http" + "os" + "github.com/gorilla/handlers" + "github.com/gorilla/mux" + "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/tendermint/go-keys/proxy" ) // serveCmd represents the serve command @@ -28,23 +36,71 @@ var serveCmd = &cobra.Command{ private keys much more in depth than the cli can perform. In particular, this will allow you to sign transactions with the private keys in the store.`, - Run: func(cmd *cobra.Command, args []string) { - // TODO: Work your own magic here - fmt.Println("serve called") - }, + RunE: server, } func init() { RootCmd.AddCommand(serveCmd) + serveCmd.Flags().IntP("port", "p", 8118, "TCP Port for listen for http server") + serveCmd.Flags().StringP("socket", "s", "", "UNIX socket for more secure http server") + serveCmd.Flags().StringP("type", "t", "ed25519", "Default key type (ed25519|secp256k1)") +} + +func server(cmd *cobra.Command, args []string) error { + var l net.Listener + var err error + socket := viper.GetString("socket") + if socket != "" { + l, err = createSocket(socket) + if err != nil { + return errors.Wrap(err, "Cannot create socket") + } + } else { + port := viper.GetInt("port") + l, err = net.Listen("tcp", fmt.Sprintf(":%d", port)) + if err != nil { + return errors.Errorf("Cannot listen on port %d", port) + } + } + + router := mux.NewRouter() + ks := proxy.NewKeyServer(manager, viper.GetString("type")) + ks.Register(router) + + // only set cors for tcp listener + var h http.Handler + if socket == "" { + allowedHeaders := handlers.AllowedHeaders([]string{"Content-Type"}) + h = handlers.CORS(allowedHeaders)(router) + } else { + h = router + } + + err = http.Serve(l, h) + fmt.Printf("Server Killed: %+v\n", err) + return nil +} - // Here you will define your flags and configuration settings. +// createSocket deletes existing socket if there, creates a new one, +// starts a server on the socket, and sets permissions to 0600 +func createSocket(socket string) (net.Listener, error) { + err := os.Remove(socket) + if err != nil && !os.IsNotExist(err) { + // only fail if it does exist and cannot be deleted + return nil, err + } - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // serveCmd.PersistentFlags().String("foo", "", "A help for foo") + l, err := net.Listen("unix", socket) + if err != nil { + return nil, err + } - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: - // serveCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + mode := os.FileMode(0700) | os.ModeSocket + err = os.Chmod(socket, mode) + if err != nil { + l.Close() + return nil, err + } + return l, nil } diff --git a/proxy/keys.go b/proxy/keys.go index 64b6819cd..0dde57074 100644 --- a/proxy/keys.go +++ b/proxy/keys.go @@ -11,16 +11,20 @@ import ( type KeyServer struct { manager keys.Manager + algo string } -func NewKeyServer(manager keys.Manager) KeyServer { +func NewKeyServer(manager keys.Manager, algo string) KeyServer { return KeyServer{ manager: manager, + algo: algo, } } func (k KeyServer) GenerateKey(w http.ResponseWriter, r *http.Request) { - req := types.CreateKeyRequest{} + req := types.CreateKeyRequest{ + Algo: k.algo, // default key type from cli + } err := readRequest(r, &req) if err != nil { writeError(w, err) diff --git a/proxy/keys_test.go b/proxy/keys_test.go index 6eee94e39..3a9c73717 100644 --- a/proxy/keys_test.go +++ b/proxy/keys_test.go @@ -92,7 +92,7 @@ func setupServer() http.Handler { ) // build your http server - ks := proxy.NewKeyServer(cstore) + ks := proxy.NewKeyServer(cstore, "ed25519") r := mux.NewRouter() sk := r.PathPrefix("/keys").Subrouter() ks.Register(sk) From 0c92c8516f530f7f58150073a03e7fc7639b1cfb Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Feb 2017 21:53:05 +0100 Subject: [PATCH 039/287] Rename proxy to server for clarity --- cmd/serve.go | 8 ++-- proxy/README.md | 65 --------------------------------- server/README.md | 13 +++++++ {proxy => server}/helpers.go | 6 +-- {proxy => server}/keys.go | 22 +++++------ {proxy => server}/keys_test.go | 8 ++-- {proxy => server}/types/keys.go | 0 {proxy => server}/valid.go | 2 +- 8 files changed, 36 insertions(+), 88 deletions(-) delete mode 100644 proxy/README.md create mode 100644 server/README.md rename {proxy => server}/helpers.go (90%) rename {proxy => server}/keys.go (77%) rename {proxy => server}/keys_test.go (96%) rename {proxy => server}/types/keys.go (100%) rename {proxy => server}/valid.go (92%) diff --git a/cmd/serve.go b/cmd/serve.go index 1555c6480..2717913fd 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -25,7 +25,7 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/tendermint/go-keys/proxy" + "github.com/tendermint/go-keys/server" ) // serveCmd represents the serve command @@ -36,7 +36,7 @@ var serveCmd = &cobra.Command{ private keys much more in depth than the cli can perform. In particular, this will allow you to sign transactions with the private keys in the store.`, - RunE: server, + RunE: serveHTTP, } func init() { @@ -46,7 +46,7 @@ func init() { serveCmd.Flags().StringP("type", "t", "ed25519", "Default key type (ed25519|secp256k1)") } -func server(cmd *cobra.Command, args []string) error { +func serveHTTP(cmd *cobra.Command, args []string) error { var l net.Listener var err error socket := viper.GetString("socket") @@ -64,7 +64,7 @@ func server(cmd *cobra.Command, args []string) error { } router := mux.NewRouter() - ks := proxy.NewKeyServer(manager, viper.GetString("type")) + ks := server.New(manager, viper.GetString("type")) ks.Register(router) // only set cors for tcp listener diff --git a/proxy/README.md b/proxy/README.md deleted file mode 100644 index 614110b7f..000000000 --- a/proxy/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# Proxy Server - -This package provides all the functionality for a local proxy http server, and ties together functionality from all the other packages to acheive this aim. Simply configure this server with your application-specific settings via a main script and you are good to go. - -This server should run on the client's machine, and can accept a trusted connection from localhost (via tcp or unix socket). It provides a simple json rest API and handles all the binary wrangling and cryptographic proofs under the hood. Thus, you can host a local webapp (via electron?) and connect to this proxy, perform simple queries and posts and behind the scenes take advantage of the *awesome power* of the tendermint blockchain. - -If you are writing native code, you can use this as well, or you can look for bindings to embed this functionality directly as a library in your codebase. -**(coming soon)** - -## API - -The API has various sections based on functionality. The major portions are key management, signing and posting transactions, and querying and proving data. - -### Key Management - -We expose a number of methods for safely managing your keychain. They are typically bound under `/keys`, but could be placed in another location by the app. - -* `POST /keys/` - provide a name and passphrase and create a brand new key -* `GET /keys/` - get a list of all available key names, along with their public key and address -* `GET /keys/{name}` - get public key and address for this named key - -Later expose: - -* `PUT /keys/{name}` - update the passphrase for the given key. requires you to correctly provide the current passphrase, as well as a new one. -* `DELETE /keys/{name}` - permanently delete this private key. requires you to correctly provide the current passphrase -* export and import functionality - -### Transactions - -You want to post your transaction. Great. Your application must provide logic to transform json into a `Signable` go struct. Then we handle the rest, signing it with a keypair of your choosing, posting it to tendermint core, and returning you confirmation when it was committed. - -* `POST /txs/` - provide name, passphrase and application-specific data to post to tendermint - - -### Proving Data - -We sent some money to our friend, now we want to check his balance. No, not just look at it, but really check it, verify all those cryptographic proofs that some node is not lying and it really, truly is in his account. - -Thankfully, we have the technology and can do all the checks in the proxy, it might just take a second or two for us to get all those block headers. - -However, this still just leaves us with a bunch of binary blobs from the server, so to make this whole process less painless, you should provide some application-specific logic to parse this binary data from the blockchain, so we can present it as json over the interface. - -* `GET /query/{path}/{data}` - will quickly query the data under the given (hex-encoded) key. `path` is `key` to query by merkle key, but your application could provide other prefixes, to differentiate by types (eg. `account`, `votes`, `escrow`). The returned data is parsed into json and displayed. -* `GET /proof/{key}` - will query for a merkle proof of the given key, download block headers, and verify all the signatures of that block. After it is done, it will present you some json and a stamp that it your data is really safe and sound. - -## Configuring - -When you instantiate a server, make sure to pass in application-specific info in order to properly. Like the following info: - -Possibly as command-line flags: - -* Where to store the private keys? (or find existing ones) -* Which type of key to generate? -* What is the URL of the tendermint RPC server? - * TODO: support multiple node URLs and round-robin -* What is the chain_id we wish to connect to? - -Extra code (plugin) you must write: - -* Logic to parse json -> `Signable` transaction -* Logic to parse binary values from merkle tree -> `struct`ured data to render - -TODO: - -* How to get the trusted validator set? diff --git a/server/README.md b/server/README.md new file mode 100644 index 000000000..032cf574e --- /dev/null +++ b/server/README.md @@ -0,0 +1,13 @@ +# Proxy Server + +This package provides all the functionality for a local http server, providing access to key management functionality (creating, listing, updating, and deleting keys). This is a nice building block for larger apps, and the HTTP handlers here can be embedded in a larger server that does nice things like signing transactions and posting them to a tendermint chain (which requires domain-knowledge of the transactions types and out of scope of this generic app). + +## Key Management + +We expose a number of methods for safely managing your keychain. If you are embedding this in a larger server, you will typically want to mount all these paths under `/keys`. + +* `POST /` - provide a name and passphrase and create a brand new key +* `GET /` - get a list of all available key names, along with their public key and address +* `GET /{name}` - get public key and address for this named key +* `PUT /{name}` - update the passphrase for the given key. requires you to correctly provide the current passphrase, as well as a new one. +* `DELETE /{name}` - permanently delete this private key. requires you to correctly provide the current passphrase diff --git a/proxy/helpers.go b/server/helpers.go similarity index 90% rename from proxy/helpers.go rename to server/helpers.go index ac314684b..111f158e7 100644 --- a/proxy/helpers.go +++ b/server/helpers.go @@ -1,11 +1,11 @@ /* -package proxy provides http handlers to construct a proxy server +package server provides http handlers to construct a server server for key management, transaction signing, and query validation. Please read the README and godoc to see how to configure the server for your application. */ -package proxy +package server import ( "encoding/json" @@ -13,7 +13,7 @@ import ( "net/http" data "github.com/tendermint/go-data" - "github.com/tendermint/go-keys/proxy/types" + "github.com/tendermint/go-keys/server/types" "github.com/pkg/errors" ) diff --git a/proxy/keys.go b/server/keys.go similarity index 77% rename from proxy/keys.go rename to server/keys.go index 0dde57074..78a382e5e 100644 --- a/proxy/keys.go +++ b/server/keys.go @@ -1,4 +1,4 @@ -package proxy +package server import ( "errors" @@ -6,22 +6,22 @@ import ( "github.com/gorilla/mux" keys "github.com/tendermint/go-keys" - "github.com/tendermint/go-keys/proxy/types" + "github.com/tendermint/go-keys/server/types" ) -type KeyServer struct { +type Keys struct { manager keys.Manager algo string } -func NewKeyServer(manager keys.Manager, algo string) KeyServer { - return KeyServer{ +func New(manager keys.Manager, algo string) Keys { + return Keys{ manager: manager, algo: algo, } } -func (k KeyServer) GenerateKey(w http.ResponseWriter, r *http.Request) { +func (k Keys) GenerateKey(w http.ResponseWriter, r *http.Request) { req := types.CreateKeyRequest{ Algo: k.algo, // default key type from cli } @@ -40,7 +40,7 @@ func (k KeyServer) GenerateKey(w http.ResponseWriter, r *http.Request) { writeSuccess(w, &key) } -func (k KeyServer) GetKey(w http.ResponseWriter, r *http.Request) { +func (k Keys) GetKey(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) name := vars["name"] key, err := k.manager.Get(name) @@ -51,7 +51,7 @@ func (k KeyServer) GetKey(w http.ResponseWriter, r *http.Request) { writeSuccess(w, &key) } -func (k KeyServer) ListKeys(w http.ResponseWriter, r *http.Request) { +func (k Keys) ListKeys(w http.ResponseWriter, r *http.Request) { keys, err := k.manager.List() if err != nil { @@ -61,7 +61,7 @@ func (k KeyServer) ListKeys(w http.ResponseWriter, r *http.Request) { writeSuccess(w, keys) } -func (k KeyServer) UpdateKey(w http.ResponseWriter, r *http.Request) { +func (k Keys) UpdateKey(w http.ResponseWriter, r *http.Request) { req := types.UpdateKeyRequest{} err := readRequest(r, &req) if err != nil { @@ -90,7 +90,7 @@ func (k KeyServer) UpdateKey(w http.ResponseWriter, r *http.Request) { writeSuccess(w, &key) } -func (k KeyServer) DeleteKey(w http.ResponseWriter, r *http.Request) { +func (k Keys) DeleteKey(w http.ResponseWriter, r *http.Request) { req := types.DeleteKeyRequest{} err := readRequest(r, &req) if err != nil { @@ -118,7 +118,7 @@ func (k KeyServer) DeleteKey(w http.ResponseWriter, r *http.Request) { writeSuccess(w, &resp) } -func (k KeyServer) Register(r *mux.Router) { +func (k Keys) Register(r *mux.Router) { r.HandleFunc("/", k.GenerateKey).Methods("POST") r.HandleFunc("/", k.ListKeys).Methods("GET") r.HandleFunc("/{name}", k.GetKey).Methods("GET") diff --git a/proxy/keys_test.go b/server/keys_test.go similarity index 96% rename from proxy/keys_test.go rename to server/keys_test.go index 3a9c73717..8333e8e53 100644 --- a/proxy/keys_test.go +++ b/server/keys_test.go @@ -1,4 +1,4 @@ -package proxy_test +package server_test import ( "bytes" @@ -12,8 +12,8 @@ import ( "github.com/stretchr/testify/require" keys "github.com/tendermint/go-keys" "github.com/tendermint/go-keys/cryptostore" - "github.com/tendermint/go-keys/proxy" - "github.com/tendermint/go-keys/proxy/types" + "github.com/tendermint/go-keys/server" + "github.com/tendermint/go-keys/server/types" "github.com/tendermint/go-keys/storage/memstorage" ) @@ -92,7 +92,7 @@ func setupServer() http.Handler { ) // build your http server - ks := proxy.NewKeyServer(cstore, "ed25519") + ks := server.New(cstore, "ed25519") r := mux.NewRouter() sk := r.PathPrefix("/keys").Subrouter() ks.Register(sk) diff --git a/proxy/types/keys.go b/server/types/keys.go similarity index 100% rename from proxy/types/keys.go rename to server/types/keys.go diff --git a/proxy/valid.go b/server/valid.go similarity index 92% rename from proxy/valid.go rename to server/valid.go index 31782cfca..50b51e21b 100644 --- a/proxy/valid.go +++ b/server/valid.go @@ -1,4 +1,4 @@ -package proxy +package server import ( "github.com/pkg/errors" From af7e3120888a199c22e94f6e9a1b1a3a0545c5ac Mon Sep 17 00:00:00 2001 From: "Paul W. Homer" Date: Thu, 2 Mar 2017 17:16:15 -0500 Subject: [PATCH 040/287] Added glide dependency handling --- .gitignore | 1 + Makefile | 19 ++++++++- glide.lock | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++ glide.yaml | 19 +++++++++ 4 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 glide.lock create mode 100644 glide.yaml diff --git a/.gitignore b/.gitignore index cfaef8179..2f1e043a8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .mykeys +vendor diff --git a/Makefile b/Makefile index b15317b25..63eb70787 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,22 @@ +GOTOOLS = \ + github.com/mitchellh/gox \ + github.com/Masterminds/glide + +.PHONEY: all test install get_vendor_deps ensure_tools + +all: install test + test: - go test ./... + go test `glide novendor` install: go install ./cmd/keys + +get_vendor_deps: ensure_tools + @rm -rf vendor/ + @echo "--> Running glide install" + @glide install + +ensure_tools: + go get $(GOTOOLS) + diff --git a/glide.lock b/glide.lock new file mode 100644 index 000000000..c74262a4e --- /dev/null +++ b/glide.lock @@ -0,0 +1,123 @@ +hash: 4a517b0f71ea6e3aadcf98286cde97c2f567e9e7999a4c7ec9ce6e5b6c21564a +updated: 2017-03-02T16:57:20.740518259-05:00 +imports: +- name: github.com/bgentry/speakeasy + version: 675b82c74c0ed12283ee81ba8a534c8982c07b85 +- name: github.com/btcsuite/btcd + version: d06c0bb181529331be8f8d9350288c420d9e60e4 + subpackages: + - btcec +- name: github.com/fsnotify/fsnotify + version: 7d7316ed6e1ed2de075aab8dfc76de5d158d66e1 +- name: github.com/go-playground/locales + version: 084b0226cf88d891a2bdeccac01d592af13a8f7b + subpackages: + - currency +- name: github.com/go-playground/universal-translator + version: b32fa301c9fe55953584134cb6853a13c87ec0a1 +- name: github.com/go-stack/stack + version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82 +- name: github.com/gorilla/context + version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42 +- name: github.com/gorilla/handlers + version: 13d73096a474cac93275c679c7b8a2dc17ddba82 +- name: github.com/gorilla/mux + version: 599cba5e7b6137d46ddf58fb1765f5d928e69604 +- name: github.com/hashicorp/hcl + version: 630949a3c5fa3c613328e1b8256052cbc2327c9b + subpackages: + - hcl/ast + - hcl/parser + - hcl/scanner + - hcl/strconv + - hcl/token + - json/parser + - json/scanner + - json/token +- name: github.com/inconshreveable/mousetrap + version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 +- name: github.com/magiconair/properties + version: b3b15ef068fd0b17ddf408a23669f20811d194d2 +- name: github.com/mattn/go-colorable + version: 5411d3eea5978e6cdc258b30de592b60df6aba96 +- name: github.com/mattn/go-isatty + version: 281032e84ae07510239465db46bf442aa44b953a +- name: github.com/mitchellh/mapstructure + version: db1efb556f84b25a0a13a04aad883943538ad2e0 +- name: github.com/pelletier/go-buffruneio + version: c37440a7cf42ac63b919c752ca73a85067e05992 +- name: github.com/pelletier/go-toml + version: 13d49d4606eb801b8f01ae542b4afc4c6ee3d84a +- name: github.com/pkg/errors + version: 248dadf4e9068a0b3e79f02ed0a610d935de5302 +- name: github.com/spf13/afero + version: 9be650865eab0c12963d8753212f4f9c66cdcf12 + subpackages: + - mem +- name: github.com/spf13/cast + version: f820543c3592e283e311a60d2a600a664e39f6f7 +- name: github.com/spf13/cobra + version: fcd0c5a1df88f5d6784cb4feead962c3f3d0b66c +- name: github.com/spf13/jwalterweatherman + version: fa7ca7e836cf3a8bb4ebf799f472c12d7e903d66 +- name: github.com/spf13/pflag + version: 9ff6c6923cfffbcd502984b8e0c80539a94968b7 +- name: github.com/spf13/viper + version: 7538d73b4eb9511d85a9f1dfef202eeb8ac260f4 +- name: github.com/tendermint/ed25519 + version: 1f52c6f8b8a5c7908aff4497c186af344b428925 + subpackages: + - edwards25519 + - extra25519 +- name: github.com/tendermint/go-common + version: 339e135776142939d82bc8e699db0bf391fd938d +- name: github.com/tendermint/go-crypto + version: 562b4cc9ef0d20217f6e95679f9e83cb7bc98b17 +- name: github.com/tendermint/go-data + version: 32271140e8fd5abdbb22e268d7a02421fa382f0b + subpackages: + - base58 +- name: github.com/tendermint/go-logger + version: cefb3a45c0bf3c493a04e9bcd9b1540528be59f2 +- name: github.com/tendermint/go-wire + version: 3216ec9d47bbdf8d4fc27d22169ea86a6688bc15 +- name: github.com/tendermint/log15 + version: ae0f3d6450da9eac7074b439c8e1c3cabf0d5ce6 + subpackages: + - term +- name: golang.org/x/crypto + version: 453249f01cfeb54c3d549ddb75ff152ca243f9d8 + subpackages: + - nacl/secretbox + - openpgp/armor + - openpgp/errors + - poly1305 + - ripemd160 + - salsa20/salsa +- name: golang.org/x/sys + version: e24f485414aeafb646f6fca458b0bf869c0880a1 + subpackages: + - unix +- name: golang.org/x/text + version: d680ca3ed853995402af43b866311167281bdc20 + subpackages: + - transform + - unicode/norm +- name: gopkg.in/go-playground/validator.v9 + version: 4bd19358521c53f09639f21e2a9d6883d6890f24 +- name: gopkg.in/yaml.v2 + version: a3f3340b5840cee44f372bddb5880fcbc419b46a +testImports: +- name: github.com/davecgh/go-spew + version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 + subpackages: + - spew +- name: github.com/pmezard/go-difflib + version: d8ed2627bdf02c080bf22230dbb337003b7aba2d + subpackages: + - difflib +- name: github.com/stretchr/testify + version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0 + subpackages: + - assert + - require diff --git a/glide.yaml b/glide.yaml new file mode 100644 index 000000000..39402fa8b --- /dev/null +++ b/glide.yaml @@ -0,0 +1,19 @@ +package: github.com/tendermint/go-keys +import: +- package: github.com/bgentry/speakeasy +- package: github.com/gorilla/handlers +- package: github.com/gorilla/mux +- package: github.com/pkg/errors +- package: github.com/spf13/cobra +- package: github.com/spf13/viper +- package: github.com/tendermint/go-crypto + version: develop +- package: github.com/tendermint/go-data + subpackages: + - base58 +- package: gopkg.in/go-playground/validator.v9 +testImport: +- package: github.com/stretchr/testify + subpackages: + - assert + - require From 76ace969256d2e3c2c89ddc8566489c9b8cb78bd Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 20 Mar 2017 09:55:07 +0100 Subject: [PATCH 041/287] Create nested directories as needed to store keys --- storage/filestorage/main.go | 4 ++-- storage/filestorage/main_test.go | 25 +++++++++++++++++-------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/storage/filestorage/main.go b/storage/filestorage/main.go index 4b7dbe525..737f0772c 100644 --- a/storage/filestorage/main.go +++ b/storage/filestorage/main.go @@ -35,8 +35,8 @@ type FileStore struct { // dir should be an absolute path of a directory owner by this user. It will // be created if it doesn't exist already. func New(dir string) FileStore { - err := os.Mkdir(dir, dirPerm) - if err != nil && !os.IsExist(err) { + err := os.MkdirAll(dir, dirPerm) + if err != nil { panic(err) } return FileStore{dir} diff --git a/storage/filestorage/main_test.go b/storage/filestorage/main_test.go index c9c55eb02..890898dcb 100644 --- a/storage/filestorage/main_test.go +++ b/storage/filestorage/main_test.go @@ -83,15 +83,24 @@ func TestDirectoryHandling(t *testing.T) { newDir := path.Join(os.TempDir(), "file-test-dir") _, err := os.Open(newDir) assert.True(os.IsNotExist(err)) + defer os.RemoveAll(newDir) + + // now, check with two levels deep.... + parentDir := path.Join(os.TempDir(), "missing-dir") + nestedDir := path.Join(parentDir, "lots", "of", "levels", "here") + _, err = os.Open(parentDir) + assert.True(os.IsNotExist(err)) + defer os.RemoveAll(parentDir) // create a new storage, and verify it creates the directory with good permissions - New(newDir) - defer os.RemoveAll(newDir) - d, err := os.Open(newDir) - require.Nil(err) - defer d.Close() + for _, dir := range []string{newDir, nestedDir, newDir} { + New(dir) + d, err := os.Open(dir) + require.Nil(err) + defer d.Close() - stat, err := d.Stat() - require.Nil(err) - assert.Equal(dirPerm, stat.Mode()&os.ModePerm) + stat, err := d.Stat() + require.Nil(err) + assert.Equal(dirPerm, stat.Mode()&os.ModePerm) + } } From 3a1313ab7d0868f9c410ab423909bdbc45ad4a7f Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 22 Mar 2017 01:18:56 -0400 Subject: [PATCH 042/287] secp256k1: use compressed pubkey, bitcoin-style address --- priv_key.go | 6 +++--- pub_key.go | 27 ++++++++++++++------------- pub_key_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 16 deletions(-) create mode 100644 pub_key_test.go diff --git a/priv_key.go b/priv_key.go index 54fa36a3a..f2d108ee5 100644 --- a/priv_key.go +++ b/priv_key.go @@ -160,9 +160,9 @@ func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature { func (privKey PrivKeySecp256k1) PubKey() PubKey { _, pub__ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) - pub := [64]byte{} - copy(pub[:], pub__.SerializeUncompressed()[1:]) - return PubKeySecp256k1(pub) + var pub PubKeySecp256k1 + copy(pub[:], pub__.SerializeCompressed()) + return pub } func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool { diff --git a/pub_key.go b/pub_key.go index 9067a0363..45a4db92c 100644 --- a/pub_key.go +++ b/pub_key.go @@ -2,6 +2,7 @@ package crypto import ( "bytes" + "crypto/sha256" secp256k1 "github.com/btcsuite/btcd/btcec" "github.com/tendermint/ed25519" @@ -135,20 +136,20 @@ func (pubKey PubKeyEd25519) Equals(other PubKey) bool { //------------------------------------- -// Implements PubKey -type PubKeySecp256k1 [64]byte +// Implements PubKey. +// Compressed pubkey (just the x-cord), +// prefixed with 0x02 or 0x03, depending on the y-cord. +type PubKeySecp256k1 [33]byte +// Implements Bitcoin style addresses: RIPEMD160(SHA256(pubkey)) func (pubKey PubKeySecp256k1) Address() []byte { - w, n, err := new(bytes.Buffer), new(int), new(error) - wire.WriteBinary(pubKey[:], w, n, err) - if *err != nil { - PanicCrisis(*err) - } - // append type byte - encodedPubkey := append([]byte{TypeSecp256k1}, w.Bytes()...) - hasher := ripemd160.New() - hasher.Write(encodedPubkey) // does not error - return hasher.Sum(nil) + hasherSHA256 := sha256.New() + hasherSHA256.Write(pubKey[:]) // does not error + sha := hasherSHA256.Sum(nil) + + hasherRIPEMD160 := ripemd160.New() + hasherRIPEMD160.Write(sha) // does not error + return hasherRIPEMD160.Sum(nil) } func (pubKey PubKeySecp256k1) Bytes() []byte { @@ -166,7 +167,7 @@ func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool { return false } - pub__, err := secp256k1.ParsePubKey(append([]byte{0x04}, pubKey[:]...), secp256k1.S256()) + pub__, err := secp256k1.ParsePubKey(pubKey[:], secp256k1.S256()) if err != nil { return false } diff --git a/pub_key_test.go b/pub_key_test.go new file mode 100644 index 000000000..0616f5546 --- /dev/null +++ b/pub_key_test.go @@ -0,0 +1,41 @@ +package crypto + +import ( + "encoding/hex" + "testing" + + "github.com/btcsuite/btcutil/base58" + "github.com/stretchr/testify/assert" +) + +type keyData struct { + priv string + pub string + addr string +} + +var secpDataTable = []keyData{ + { + priv: "a96e62ed3955e65be32703f12d87b6b5cf26039ecfa948dc5107a495418e5330", + pub: "02950e1cdfcb133d6024109fd489f734eeb4502418e538c28481f22bce276f248c", + addr: "1CKZ9Nx4zgds8tU7nJHotKSDr4a9bYJCa3", + }, +} + +func TestPubKeySecp256k1Address(t *testing.T) { + for _, d := range secpDataTable { + privB, _ := hex.DecodeString(d.priv) + pubB, _ := hex.DecodeString(d.pub) + addrB, _, _ := base58.CheckDecode(d.addr) + + var priv PrivKeySecp256k1 + copy(priv[:], privB) + + pubT := priv.PubKey().(PubKeySecp256k1) + pub := pubT[:] + addr := priv.PubKey().Address() + + assert.Equal(t, pub, pubB, "Expected pub keys to match") + assert.Equal(t, addr, addrB, "Expected addresses to match") + } +} From ce9c57fca8261934db9f3612bc31ca5d0bd4505d Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 22 Mar 2017 15:59:48 -0400 Subject: [PATCH 043/287] hd test --- hd/hd_test.go | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 hd/hd_test.go diff --git a/hd/hd_test.go b/hd/hd_test.go new file mode 100644 index 000000000..6bd49a8ac --- /dev/null +++ b/hd/hd_test.go @@ -0,0 +1,132 @@ +package crypto + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "io/ioutil" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/tyler-smith/go-bip39" + + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcutil/hdkeychain" + "github.com/tyler-smith/go-bip32" + + "github.com/tendermint/go-crypto" +) + +type addrData struct { + Mnemonic string + Seed string + Priv string + Pub string + Addr string +} + +// NOTE: atom fundraiser address +var hdPath string = "m/44'/118'/0'/0/0" +var hdToAddrTable []addrData + +/*{ + { + Mnemonic: "spawn essence sudden gown library fire chalk edge start museum glimpse sea", + Priv: "ab20a81c1b9002538e2269e1f1302d519901633d40408313211598899bc00fc6", + Pub: "03eb89fb1c4582eed592e09c31c4665d3956154ea66fd269933d3f036e879abfe6", + Addr: "f7d613738f0a665ec320306d14f5d62a850ff714", + }, +}*/ + +func init() { + + b, err := ioutil.ReadFile("test.json") + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + err = json.Unmarshal(b, &hdToAddrTable) + if err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func TestHDToAddr(t *testing.T) { + + for i, d := range hdToAddrTable { + privB, _ := hex.DecodeString(d.Priv) + pubB, _ := hex.DecodeString(d.Pub) + addrB, _ := hex.DecodeString(d.Addr) + seedB, _ := hex.DecodeString(d.Seed) + + seed := bip39.NewSeed(d.Mnemonic, "") + + fmt.Println(i, d.Mnemonic) + + priv, pub := tylerSmith(seed) + //priv, pub := btcsuite(seed) + + fmt.Printf("\t%X %X\n", seedB, seed) + fmt.Printf("\t%X %X\n", privB, priv) + fmt.Printf("\t%X %X\n", pubB, pub) + assert.Equal(t, priv, privB, "Expected priv keys to match") + assert.Equal(t, pub, pubB, "Expected pub keys to match") + + var pubT crypto.PubKeySecp256k1 + copy(pubT[:], pub) + addr := pubT.Address() + assert.Equal(t, addr, addrB, "Expected addresses to match") + + /* if i%10 == 0 { + fmt.Printf("ADDR %d: %s %X %X\n", i, d.Mnemonic, addr, addrB) + }*/ + } +} + +func ifExit(err error, n int) { + if err != nil { + fmt.Println(n, err) + os.Exit(1) + } +} + +func btcsuite(seed []byte) ([]byte, []byte) { + masterKey, _ := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams) + fh := hdkeychain.HardenedKeyStart + k, err := masterKey.Child(uint32(fh + 44)) + ifExit(err, 44) + k, err = k.Child(uint32(fh + 118)) + ifExit(err, 118) + k, err = k.Child(uint32(fh + 0)) + ifExit(err, 1) + k, err = k.Child(uint32(0)) + ifExit(err, 2) + k, err = k.Child(uint32(0)) + ifExit(err, 3) + ecpriv, err := k.ECPrivKey() + ifExit(err, 10) + ecpub, err := k.ECPubKey() + ifExit(err, 11) + + priv := ecpriv.Serialize() + pub := ecpub.SerializeCompressed() + return priv, pub +} + +// return priv and pub +func tylerSmith(seed []byte) ([]byte, []byte) { + masterKey, _ := bip32.NewMasterKey(seed) + fh := bip32.FirstHardenedChild + k, _ := masterKey.NewChildKey(fh + 44) + k, _ = k.NewChildKey(fh + 118) + k, _ = k.NewChildKey(fh + 0) + k, _ = k.NewChildKey(0) + k, _ = k.NewChildKey(0) + + priv := k.Key + pub := k.PublicKey().Key + return priv, pub +} From c6be97c71c1a67d962b38ba7a9c0d4ac7a3de969 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 22 Mar 2017 16:45:30 -0400 Subject: [PATCH 044/287] error testing the hd --- hd/hd_test.go | 62 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/hd/hd_test.go b/hd/hd_test.go index 6bd49a8ac..ac07c7ed6 100644 --- a/hd/hd_test.go +++ b/hd/hd_test.go @@ -1,6 +1,10 @@ package crypto import ( + "bytes" + "crypto/hmac" + "crypto/sha512" + "encoding/binary" "encoding/hex" "encoding/json" "fmt" @@ -13,6 +17,7 @@ import ( "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcutil/hdkeychain" + "github.com/mndrix/btcutil" "github.com/tyler-smith/go-bip32" "github.com/tendermint/go-crypto" @@ -67,12 +72,13 @@ func TestHDToAddr(t *testing.T) { fmt.Println(i, d.Mnemonic) priv, pub := tylerSmith(seed) - //priv, pub := btcsuite(seed) + // priv, pub := btcsuite(seed) fmt.Printf("\t%X %X\n", seedB, seed) fmt.Printf("\t%X %X\n", privB, priv) fmt.Printf("\t%X %X\n", pubB, pub) - assert.Equal(t, priv, privB, "Expected priv keys to match") + _, _ = priv, privB + // assert.Equal(t, priv, privB, "Expected priv keys to match") assert.Equal(t, pub, pubB, "Expected pub keys to match") var pubT crypto.PubKeySecp256k1 @@ -94,7 +100,23 @@ func ifExit(err error, n int) { } func btcsuite(seed []byte) ([]byte, []byte) { - masterKey, _ := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams) + fmt.Println("HD") + masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams) + if err != nil { + hmac := hmac.New(sha512.New, []byte("Bitcoin seed")) + hmac.Write([]byte(seed)) + intermediary := hmac.Sum(nil) + + curve := btcutil.Secp256k1() + curveParams := curve.Params() + + // Split it into our key and chain code + keyBytes := intermediary[:32] + fmt.Printf("\t%X\n", keyBytes) + fmt.Printf("\t%X\n", curveParams.N.Bytes()) + keyInt, _ := binary.ReadVarint(bytes.NewBuffer(keyBytes)) + fmt.Printf("\t%d\n", keyInt) + } fh := hdkeychain.HardenedKeyStart k, err := masterKey.Child(uint32(fh + 44)) ifExit(err, 44) @@ -118,13 +140,35 @@ func btcsuite(seed []byte) ([]byte, []byte) { // return priv and pub func tylerSmith(seed []byte) ([]byte, []byte) { - masterKey, _ := bip32.NewMasterKey(seed) + masterKey, err := bip32.NewMasterKey(seed) + if err != nil { + hmac := hmac.New(sha512.New, []byte("Bitcoin seed")) + hmac.Write([]byte(seed)) + intermediary := hmac.Sum(nil) + + curve := btcutil.Secp256k1() + curveParams := curve.Params() + + // Split it into our key and chain code + keyBytes := intermediary[:32] + fmt.Printf("\t%X\n", keyBytes) + fmt.Printf("\t%X\n", curveParams.N.Bytes()) + keyInt, _ := binary.ReadVarint(bytes.NewBuffer(keyBytes)) + fmt.Printf("\t%d\n", keyInt) + + } + ifExit(err, 0) fh := bip32.FirstHardenedChild - k, _ := masterKey.NewChildKey(fh + 44) - k, _ = k.NewChildKey(fh + 118) - k, _ = k.NewChildKey(fh + 0) - k, _ = k.NewChildKey(0) - k, _ = k.NewChildKey(0) + k, err := masterKey.NewChildKey(fh + 44) + ifExit(err, 44) + k, err = k.NewChildKey(fh + 118) + ifExit(err, 118) + k, err = k.NewChildKey(fh + 0) + ifExit(err, 1) + k, err = k.NewChildKey(0) + ifExit(err, 2) + k, err = k.NewChildKey(0) + ifExit(err, 3) priv := k.Key pub := k.PublicKey().Key From 6fddcdf2452aa43e1e35f5fa47c5525468c4af2d Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 22 Mar 2017 20:13:16 -0400 Subject: [PATCH 045/287] hd test: check masters too --- hd/hd_test.go | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/hd/hd_test.go b/hd/hd_test.go index ac07c7ed6..42d034717 100644 --- a/hd/hd_test.go +++ b/hd/hd_test.go @@ -25,6 +25,7 @@ import ( type addrData struct { Mnemonic string + Master string Seed string Priv string Pub string @@ -66,25 +67,30 @@ func TestHDToAddr(t *testing.T) { pubB, _ := hex.DecodeString(d.Pub) addrB, _ := hex.DecodeString(d.Addr) seedB, _ := hex.DecodeString(d.Seed) + masterB, _ := hex.DecodeString(d.Master) seed := bip39.NewSeed(d.Mnemonic, "") fmt.Println(i, d.Mnemonic) - priv, pub := tylerSmith(seed) - // priv, pub := btcsuite(seed) + //master, priv, pub := tylerSmith(seed) + master, priv, pub := btcsuite(seed) fmt.Printf("\t%X %X\n", seedB, seed) + fmt.Printf("\t%X %X\n", masterB, master) fmt.Printf("\t%X %X\n", privB, priv) fmt.Printf("\t%X %X\n", pubB, pub) _, _ = priv, privB + + assert.Equal(t, master, masterB, fmt.Sprintf("Expected masters to match for %d", i)) + // assert.Equal(t, priv, privB, "Expected priv keys to match") - assert.Equal(t, pub, pubB, "Expected pub keys to match") + assert.Equal(t, pub, pubB, fmt.Sprintf("Expected pub keys to match for %d", i)) var pubT crypto.PubKeySecp256k1 copy(pubT[:], pub) addr := pubT.Address() - assert.Equal(t, addr, addrB, "Expected addresses to match") + assert.Equal(t, addr, addrB, fmt.Sprintf("Expected addresses to match %d", i)) /* if i%10 == 0 { fmt.Printf("ADDR %d: %s %X %X\n", i, d.Mnemonic, addr, addrB) @@ -99,7 +105,7 @@ func ifExit(err error, n int) { } } -func btcsuite(seed []byte) ([]byte, []byte) { +func btcsuite(seed []byte) ([]byte, []byte, []byte) { fmt.Println("HD") masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams) if err != nil { @@ -135,11 +141,12 @@ func btcsuite(seed []byte) ([]byte, []byte) { priv := ecpriv.Serialize() pub := ecpub.SerializeCompressed() - return priv, pub + mkey, _ := masterKey.ECPrivKey() + return mkey.Serialize(), priv, pub } // return priv and pub -func tylerSmith(seed []byte) ([]byte, []byte) { +func tylerSmith(seed []byte) ([]byte, []byte, []byte) { masterKey, err := bip32.NewMasterKey(seed) if err != nil { hmac := hmac.New(sha512.New, []byte("Bitcoin seed")) @@ -172,5 +179,5 @@ func tylerSmith(seed []byte) ([]byte, []byte) { priv := k.Key pub := k.PublicKey().Key - return priv, pub + return masterKey.Key, priv, pub } From 398ac046da7e1b23551e6a0d4405d3a7653eafad Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 23 Mar 2017 20:31:47 +0100 Subject: [PATCH 046/287] Reorganize cobra cmd to enable better reuse --- cmd/common.go | 119 +++++++++++++++++++++++++++++++++++++++++++++++ cmd/get.go | 2 +- cmd/keys/main.go | 11 ++++- cmd/list.go | 2 +- cmd/new.go | 2 +- cmd/root.go | 95 ++++--------------------------------- cmd/serve.go | 2 +- cmd/update.go | 2 +- cmd/utils.go | 5 +- 9 files changed, 146 insertions(+), 94 deletions(-) create mode 100644 cmd/common.go diff --git a/cmd/common.go b/cmd/common.go new file mode 100644 index 000000000..56c9afbab --- /dev/null +++ b/cmd/common.go @@ -0,0 +1,119 @@ +package cmd + +import ( + "fmt" + "os" + "strings" + + "github.com/pkg/errors" + "github.com/spf13/cobra" + "github.com/spf13/viper" + data "github.com/tendermint/go-data" + "github.com/tendermint/go-data/base58" +) + +/******* + +TODO + +This file should move into go-common or the like as a basis for all cli tools. +It is here for experimentation of re-use between go-keys and light-client. + +*********/ + +const ( + RootFlag = "root" + OutputFlag = "output" +) + +func PrepareMainCmd(cmd *cobra.Command, envPrefix, defautRoot string) func() { + cobra.OnInitialize(func() { initEnv(envPrefix) }) + cmd.PersistentFlags().StringP(RootFlag, "r", defautRoot, "root directory for config and data") + cmd.PersistentFlags().StringP("encoding", "e", "hex", "Binary encoding (hex|b64|btc)") + cmd.PersistentFlags().StringP(OutputFlag, "o", "text", "Output format (text|json)") + cmd.PersistentPreRunE = multiE(bindFlags, setEncoding, validateOutput, cmd.PersistentPreRunE) + return func() { execute(cmd) } +} + +// initEnv sets to use ENV variables if set. +func initEnv(prefix string) { + // env variables with TM prefix (eg. TM_ROOT) + viper.SetEnvPrefix(prefix) + viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + viper.AutomaticEnv() +} + +// execute adds all child commands to the root command sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func execute(cmd *cobra.Command) { + if err := cmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(-1) + } +} + +type wrapE func(cmd *cobra.Command, args []string) error + +func multiE(fs ...wrapE) wrapE { + return func(cmd *cobra.Command, args []string) error { + for _, f := range fs { + if f != nil { + if err := f(cmd, args); err != nil { + return err + } + } + } + return nil + } +} + +func bindFlags(cmd *cobra.Command, args []string) error { + // cmd.Flags() includes flags from this command and all persistent flags from the parent + if err := viper.BindPFlags(cmd.Flags()); err != nil { + return err + } + + // rootDir is command line flag, env variable, or default $HOME/.tlc + rootDir := viper.GetString("root") + viper.SetConfigName("config") // name of config file (without extension) + viper.AddConfigPath(rootDir) // search root directory + + // If a config file is found, read it in. + if err := viper.ReadInConfig(); err == nil { + // stderr, so if we redirect output to json file, this doesn't appear + // fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) + } else if _, ok := err.(viper.ConfigFileNotFoundError); !ok { + // we ignore not found error, only parse error + // stderr, so if we redirect output to json file, this doesn't appear + fmt.Fprintf(os.Stderr, "%#v", err) + } + return nil +} + +// setEncoding reads the encoding flag +func setEncoding(cmd *cobra.Command, args []string) error { + // validate and set encoding + enc := viper.GetString("encoding") + switch enc { + case "hex": + data.Encoder = data.HexEncoder + case "b64": + data.Encoder = data.B64Encoder + case "btc": + data.Encoder = base58.BTCEncoder + default: + return errors.Errorf("Unsupported encoding: %s", enc) + } + return nil +} + +func validateOutput(cmd *cobra.Command, args []string) error { + // validate output format + output := viper.GetString(OutputFlag) + switch output { + case "text", "json": + default: + return errors.Errorf("Unsupported output format: %s", output) + } + return nil +} diff --git a/cmd/get.go b/cmd/get.go index d945809f9..10d528807 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -32,7 +32,7 @@ var getCmd = &cobra.Command{ } name := args[0] - info, err := manager.Get(name) + info, err := Manager.Get(name) if err != nil { fmt.Println(err.Error()) return diff --git a/cmd/keys/main.go b/cmd/keys/main.go index 8c880ea03..40bf31808 100644 --- a/cmd/keys/main.go +++ b/cmd/keys/main.go @@ -14,8 +14,15 @@ package main -import "github.com/tendermint/go-keys/cmd" +import ( + "os" + + "github.com/tendermint/go-keys/cmd" +) func main() { - cmd.Execute() + cmd.RootCmd.PersistentPreRunE = cmd.SetupKeys + cmd.PrepareMainCmd(cmd.RootCmd, "TM", os.ExpandEnv("$HOME/.tlc")) + cmd.RootCmd.Execute() + // exec() } diff --git a/cmd/list.go b/cmd/list.go index 44fefb8d6..bf4d14b68 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -27,7 +27,7 @@ var listCmd = &cobra.Command{ Long: `Return a list of all public keys stored by this key manager along with their associated name and address.`, Run: func(cmd *cobra.Command, args []string) { - infos, err := manager.List() + infos, err := Manager.List() if err != nil { fmt.Println(err.Error()) return diff --git a/cmd/new.go b/cmd/new.go index 27c7dce75..3564ddf90 100644 --- a/cmd/new.go +++ b/cmd/new.go @@ -50,7 +50,7 @@ func newPassword(cmd *cobra.Command, args []string) { return } - info, err := manager.Create(name, pass, algo) + info, err := Manager.Create(name, pass, algo) if err != nil { fmt.Println(err.Error()) return diff --git a/cmd/root.go b/cmd/root.go index 41803fc65..ffe5cc36b 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -15,26 +15,19 @@ package cmd import ( - "fmt" - "os" "path/filepath" - "strings" - "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" - data "github.com/tendermint/go-data" - "github.com/tendermint/go-data/base58" keys "github.com/tendermint/go-keys" "github.com/tendermint/go-keys/cryptostore" "github.com/tendermint/go-keys/storage/filestorage" ) +const KeySubdir = "keys" + var ( - rootDir string - output string - keyDir string - manager keys.Manager + Manager keys.Manager ) // RootCmd represents the base command when called without any subcommands @@ -46,87 +39,19 @@ var RootCmd = &cobra.Command{ These keys may be in any format supported by go-crypto and can be used by light-clients, full nodes, or any other application that needs to sign with a private key.`, - PersistentPreRunE: bindFlags, -} - -// Execute adds all child commands to the root command sets flags appropriately. -// This is called by main.main(). It only needs to happen once to the rootCmd. -func Execute() { - if err := RootCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(-1) - } -} - -func init() { - cobra.OnInitialize(initEnv) - RootCmd.PersistentFlags().StringP("root", "r", os.ExpandEnv("$HOME/.tlc"), "root directory for config and data") - RootCmd.PersistentFlags().String("keydir", "keys", "Directory to store private keys (subdir of root)") - RootCmd.PersistentFlags().StringP("output", "o", "text", "Output format (text|json)") - RootCmd.PersistentFlags().StringP("encoding", "e", "hex", "Binary encoding (hex|b64|btc)") -} - -// initEnv sets to use ENV variables if set. -func initEnv() { - // env variables with TM prefix (eg. TM_ROOT) - viper.SetEnvPrefix("TM") - viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) - viper.AutomaticEnv() } -func bindFlags(cmd *cobra.Command, args []string) error { - // cmd.Flags() includes flags from this command and all persistent flags from the parent - if err := viper.BindPFlags(cmd.Flags()); err != nil { - return err - } - - // rootDir is command line flag, env variable, or default $HOME/.tlc - rootDir = viper.GetString("root") - viper.SetConfigName("keys") // name of config file (without extension) - viper.AddConfigPath(rootDir) // search root directory - - // If a config file is found, read it in. - if err := viper.ReadInConfig(); err == nil { - // stderr, so if we redirect output to json file, this doesn't appear - fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) - } - - return validateFlags(cmd) -} - -// validateFlags asserts all RootCmd flags are valid -func validateFlags(cmd *cobra.Command) error { - // validate output format - output = viper.GetString("output") - switch output { - case "text", "json": - default: - return errors.Errorf("Unsupported output format: %s", output) - } - - // validate and set encoding - enc := viper.GetString("encoding") - switch enc { - case "hex": - data.Encoder = data.HexEncoder - case "b64": - data.Encoder = data.B64Encoder - case "btc": - data.Encoder = base58.BTCEncoder - default: - return errors.Errorf("Unsupported encoding: %s", enc) - } - +// SetupKeys must be registered in main() on the top level command +// here this is RootCmd, but if we embed keys in eg. light-client, +// that must be responsible for the update +func SetupKeys(cmd *cobra.Command, args []string) error { // store the keys directory - keyDir = viper.GetString("keydir") - if !filepath.IsAbs(keyDir) { - keyDir = filepath.Join(rootDir, keyDir) - } + rootDir := viper.GetString("root") + keyDir := filepath.Join(rootDir, KeySubdir) // and construct the key manager - manager = cryptostore.New( + Manager = cryptostore.New( cryptostore.SecretBox, filestorage.New(keyDir), ) - return nil } diff --git a/cmd/serve.go b/cmd/serve.go index 2717913fd..5268f0b92 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -64,7 +64,7 @@ func serveHTTP(cmd *cobra.Command, args []string) error { } router := mux.NewRouter() - ks := server.New(manager, viper.GetString("type")) + ks := server.New(Manager, viper.GetString("type")) ks.Register(router) // only set cors for tcp listener diff --git a/cmd/update.go b/cmd/update.go index 0340944be..63b6f84df 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -50,7 +50,7 @@ func updatePassword(cmd *cobra.Command, args []string) { return } - err = manager.Update(name, oldpass, newpass) + err = Manager.Update(name, oldpass, newpass) if err != nil { fmt.Println(err.Error()) } else { diff --git a/cmd/utils.go b/cmd/utils.go index 01f9801ae..31a3a8df3 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -5,6 +5,7 @@ import ( "github.com/bgentry/speakeasy" "github.com/pkg/errors" + "github.com/spf13/viper" data "github.com/tendermint/go-data" keys "github.com/tendermint/go-keys" ) @@ -39,7 +40,7 @@ func getCheckPassword(prompt, prompt2 string) (string, error) { } func printInfo(info keys.Info) { - switch output { + switch viper.Get(OutputFlag) { case "text": addr, err := data.ToText(info.Address) if err != nil { @@ -60,7 +61,7 @@ func printInfo(info keys.Info) { } func printInfos(infos keys.Infos) { - switch output { + switch viper.Get(OutputFlag) { case "text": fmt.Println("All keys:") for _, i := range infos { From 58e537a42de4de0c7719171123695c5d0ed7b97c Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Mar 2017 19:05:33 +0200 Subject: [PATCH 047/287] Refactor setting up the key manager from config --- cmd/common.go | 7 ++++--- cmd/get.go | 2 +- cmd/keys/main.go | 1 - cmd/list.go | 2 +- cmd/new.go | 2 +- cmd/root.go | 28 ++++++++++++++-------------- cmd/serve.go | 2 +- cmd/update.go | 2 +- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/cmd/common.go b/cmd/common.go index 56c9afbab..eb7a158ae 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -22,14 +22,15 @@ It is here for experimentation of re-use between go-keys and light-client. *********/ const ( - RootFlag = "root" - OutputFlag = "output" + RootFlag = "root" + OutputFlag = "output" + EncodingFlag = "encoding" ) func PrepareMainCmd(cmd *cobra.Command, envPrefix, defautRoot string) func() { cobra.OnInitialize(func() { initEnv(envPrefix) }) cmd.PersistentFlags().StringP(RootFlag, "r", defautRoot, "root directory for config and data") - cmd.PersistentFlags().StringP("encoding", "e", "hex", "Binary encoding (hex|b64|btc)") + cmd.PersistentFlags().StringP(EncodingFlag, "e", "hex", "Binary encoding (hex|b64|btc)") cmd.PersistentFlags().StringP(OutputFlag, "o", "text", "Output format (text|json)") cmd.PersistentPreRunE = multiE(bindFlags, setEncoding, validateOutput, cmd.PersistentPreRunE) return func() { execute(cmd) } diff --git a/cmd/get.go b/cmd/get.go index 10d528807..9b8718996 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -32,7 +32,7 @@ var getCmd = &cobra.Command{ } name := args[0] - info, err := Manager.Get(name) + info, err := GetKeyManager().Get(name) if err != nil { fmt.Println(err.Error()) return diff --git a/cmd/keys/main.go b/cmd/keys/main.go index 40bf31808..8b92b3f49 100644 --- a/cmd/keys/main.go +++ b/cmd/keys/main.go @@ -21,7 +21,6 @@ import ( ) func main() { - cmd.RootCmd.PersistentPreRunE = cmd.SetupKeys cmd.PrepareMainCmd(cmd.RootCmd, "TM", os.ExpandEnv("$HOME/.tlc")) cmd.RootCmd.Execute() // exec() diff --git a/cmd/list.go b/cmd/list.go index bf4d14b68..875520159 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -27,7 +27,7 @@ var listCmd = &cobra.Command{ Long: `Return a list of all public keys stored by this key manager along with their associated name and address.`, Run: func(cmd *cobra.Command, args []string) { - infos, err := Manager.List() + infos, err := GetKeyManager().List() if err != nil { fmt.Println(err.Error()) return diff --git a/cmd/new.go b/cmd/new.go index 3564ddf90..b59874bb0 100644 --- a/cmd/new.go +++ b/cmd/new.go @@ -50,7 +50,7 @@ func newPassword(cmd *cobra.Command, args []string) { return } - info, err := Manager.Create(name, pass, algo) + info, err := GetKeyManager().Create(name, pass, algo) if err != nil { fmt.Println(err.Error()) return diff --git a/cmd/root.go b/cmd/root.go index ffe5cc36b..64adf2b0b 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -27,7 +27,7 @@ import ( const KeySubdir = "keys" var ( - Manager keys.Manager + manager keys.Manager ) // RootCmd represents the base command when called without any subcommands @@ -41,17 +41,17 @@ used by light-clients, full nodes, or any other application that needs to sign with a private key.`, } -// SetupKeys must be registered in main() on the top level command -// here this is RootCmd, but if we embed keys in eg. light-client, -// that must be responsible for the update -func SetupKeys(cmd *cobra.Command, args []string) error { - // store the keys directory - rootDir := viper.GetString("root") - keyDir := filepath.Join(rootDir, KeySubdir) - // and construct the key manager - Manager = cryptostore.New( - cryptostore.SecretBox, - filestorage.New(keyDir), - ) - return nil +// GetKeyManager initializes a key manager based on the configuration +func GetKeyManager() keys.Manager { + if manager == nil { + // store the keys directory + rootDir := viper.GetString("root") + keyDir := filepath.Join(rootDir, KeySubdir) + // and construct the key manager + manager = cryptostore.New( + cryptostore.SecretBox, + filestorage.New(keyDir), + ) + } + return manager } diff --git a/cmd/serve.go b/cmd/serve.go index 5268f0b92..c3f7dbe39 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -64,7 +64,7 @@ func serveHTTP(cmd *cobra.Command, args []string) error { } router := mux.NewRouter() - ks := server.New(Manager, viper.GetString("type")) + ks := server.New(GetKeyManager(), viper.GetString("type")) ks.Register(router) // only set cors for tcp listener diff --git a/cmd/update.go b/cmd/update.go index 63b6f84df..3835242c5 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -50,7 +50,7 @@ func updatePassword(cmd *cobra.Command, args []string) { return } - err = Manager.Update(name, oldpass, newpass) + err = GetKeyManager().Update(name, oldpass, newpass) if err != nil { fmt.Println(err.Error()) } else { From ae55713864f0679dfa628b23654d462bb12a109a Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 29 Mar 2017 20:41:11 +0200 Subject: [PATCH 048/287] Move tx from light-client and add tests --- tx/docs.go | 10 ++++++ tx/multi.go | 67 +++++++++++++++++++++++++++++++++++++++++ tx/multi_test.go | 77 +++++++++++++++++++++++++++++++++++++++++++++++ tx/one.go | 58 +++++++++++++++++++++++++++++++++++ tx/one_test.go | 73 ++++++++++++++++++++++++++++++++++++++++++++ tx/reader.go | 76 ++++++++++++++++++++++++++++++++++++++++++++++ tx/reader_test.go | 70 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 431 insertions(+) create mode 100644 tx/docs.go create mode 100644 tx/multi.go create mode 100644 tx/multi_test.go create mode 100644 tx/one.go create mode 100644 tx/one_test.go create mode 100644 tx/reader.go create mode 100644 tx/reader_test.go diff --git a/tx/docs.go b/tx/docs.go new file mode 100644 index 000000000..6a5ea3ce3 --- /dev/null +++ b/tx/docs.go @@ -0,0 +1,10 @@ +/* +package tx contains generic Signable implementations that can be used +by your application or tests to handle authentication needs. + +It currently supports transaction data as opaque bytes and either single +or multiple private key signatures using straightforward algorithms. +It currently does not support N-of-M key share signing of other more +complex algorithms (although it would be great to add them) +*/ +package tx diff --git a/tx/multi.go b/tx/multi.go new file mode 100644 index 000000000..eac86b010 --- /dev/null +++ b/tx/multi.go @@ -0,0 +1,67 @@ +package tx + +import ( + "github.com/pkg/errors" + crypto "github.com/tendermint/go-crypto" + data "github.com/tendermint/go-data" +) + +// MultiSig lets us wrap arbitrary data with a go-crypto signature +// +// TODO: rethink how we want to integrate this with KeyStore so it makes +// more sense (particularly the verify method) +type MultiSig struct { + Data data.Bytes + Sigs []Signed +} + +type Signed struct { + Sig crypto.SignatureS + Pubkey crypto.PubKeyS +} + +var _ SigInner = &MultiSig{} + +func NewMulti(data []byte) Sig { + return Sig{&MultiSig{Data: data}} +} + +// SignBytes returns the original data passed into `NewSig` +func (s *MultiSig) SignBytes() []byte { + return s.Data +} + +// Sign will add a signature and pubkey. +// +// Depending on the Signable, one may be able to call this multiple times for multisig +// Returns error if called with invalid data or too many times +func (s *MultiSig) Sign(pubkey crypto.PubKey, sig crypto.Signature) error { + if pubkey == nil || sig == nil { + return errors.New("Signature or Key missing") + } + + // set the value once we are happy + x := Signed{crypto.SignatureS{sig}, crypto.PubKeyS{pubkey}} + s.Sigs = append(s.Sigs, x) + return nil +} + +// Signers will return the public key(s) that signed if the signature +// is valid, or an error if there is any issue with the signature, +// including if there are no signatures +func (s *MultiSig) Signers() ([]crypto.PubKey, error) { + if len(s.Sigs) == 0 { + return nil, errors.New("Never signed") + } + + keys := make([]crypto.PubKey, len(s.Sigs)) + for i := range s.Sigs { + ms := s.Sigs[i] + if !ms.Pubkey.VerifyBytes(s.Data, ms.Sig) { + return nil, errors.Errorf("Signature %d doesn't match (key: %X)", i, ms.Pubkey.Bytes()) + } + keys[i] = ms.Pubkey + } + + return keys, nil +} diff --git a/tx/multi_test.go b/tx/multi_test.go new file mode 100644 index 000000000..815b9e15a --- /dev/null +++ b/tx/multi_test.go @@ -0,0 +1,77 @@ +package tx + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + crypto "github.com/tendermint/go-crypto" + keys "github.com/tendermint/go-keys" + "github.com/tendermint/go-keys/cryptostore" + "github.com/tendermint/go-keys/storage/memstorage" +) + +func TestMultiSig(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + algo := crypto.NameEd25519 + cstore := cryptostore.New( + cryptostore.SecretBox, + memstorage.New(), + ) + n, p := "foo", "bar" + n2, p2 := "other", "thing" + + acct, err := cstore.Create(n, p, algo) + require.Nil(err, "%+v", err) + acct2, err := cstore.Create(n2, p2, algo) + require.Nil(err, "%+v", err) + + type signer struct { + key keys.Info + name, pass string + } + cases := []struct { + data string + signers []signer + }{ + {"one", []signer{{acct, n, p}}}, + {"two", []signer{{acct2, n2, p2}}}, + {"both", []signer{{acct, n, p}, {acct2, n2, p2}}}, + } + + for _, tc := range cases { + tx := NewMulti([]byte(tc.data)) + // unsigned version + _, err = tx.Signers() + assert.NotNil(err) + orig, err := tx.TxBytes() + require.Nil(err, "%+v", err) + data := tx.SignBytes() + assert.Equal(tc.data, string(data)) + + // sign it + for _, s := range tc.signers { + err = cstore.Sign(s.name, s.pass, tx) + require.Nil(err, "%+v", err) + } + + // make sure it is proper now + sigs, err := tx.Signers() + require.Nil(err, "%+v", err) + if assert.Equal(len(tc.signers), len(sigs)) { + for i := range sigs { + // This must be refactored... + assert.Equal(tc.signers[i].key.PubKey, sigs[i]) + } + } + // the tx bytes should change after this + after, err := tx.TxBytes() + require.Nil(err, "%+v", err) + assert.NotEqual(orig, after, "%X != %X", orig, after) + + // sign bytes are the same + data = tx.SignBytes() + assert.Equal(tc.data, string(data)) + } +} diff --git a/tx/one.go b/tx/one.go new file mode 100644 index 000000000..0ad61dd50 --- /dev/null +++ b/tx/one.go @@ -0,0 +1,58 @@ +package tx + +import ( + "github.com/pkg/errors" + crypto "github.com/tendermint/go-crypto" + data "github.com/tendermint/go-data" +) + +// OneSig lets us wrap arbitrary data with a go-crypto signature +// +// TODO: rethink how we want to integrate this with KeyStore so it makes +// more sense (particularly the verify method) +type OneSig struct { + Data data.Bytes + Signed +} + +var _ SigInner = &OneSig{} + +func New(data []byte) Sig { + return WrapSig(&OneSig{Data: data}) +} + +// SignBytes returns the original data passed into `NewSig` +func (s *OneSig) SignBytes() []byte { + return s.Data +} + +// Sign will add a signature and pubkey. +// +// Depending on the Signable, one may be able to call this multiple times for multisig +// Returns error if called with invalid data or too many times +func (s *OneSig) Sign(pubkey crypto.PubKey, sig crypto.Signature) error { + if pubkey == nil || sig == nil { + return errors.New("Signature or Key missing") + } + if !s.Sig.Empty() { + return errors.New("Transaction can only be signed once") + } + + // set the value once we are happy + s.Pubkey = crypto.PubKeyS{pubkey} + s.Sig = crypto.SignatureS{sig} + return nil +} + +// Signers will return the public key(s) that signed if the signature +// is valid, or an error if there is any issue with the signature, +// including if there are no signatures +func (s *OneSig) Signers() ([]crypto.PubKey, error) { + if s.Pubkey.Empty() || s.Sig.Empty() { + return nil, errors.New("Never signed") + } + if !s.Pubkey.VerifyBytes(s.Data, s.Sig) { + return nil, errors.New("Signature doesn't match") + } + return []crypto.PubKey{s.Pubkey}, nil +} diff --git a/tx/one_test.go b/tx/one_test.go new file mode 100644 index 000000000..71b8011ef --- /dev/null +++ b/tx/one_test.go @@ -0,0 +1,73 @@ +package tx + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + crypto "github.com/tendermint/go-crypto" + keys "github.com/tendermint/go-keys" + "github.com/tendermint/go-keys/cryptostore" + "github.com/tendermint/go-keys/storage/memstorage" +) + +func TestOneSig(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + algo := crypto.NameEd25519 + cstore := cryptostore.New( + cryptostore.SecretBox, + memstorage.New(), + ) + n, p := "foo", "bar" + n2, p2 := "other", "thing" + + acct, err := cstore.Create(n, p, algo) + require.Nil(err, "%+v", err) + acct2, err := cstore.Create(n2, p2, algo) + require.Nil(err, "%+v", err) + + cases := []struct { + data string + key keys.Info + name, pass string + }{ + {"first", acct, n, p}, + {"kehfkhefy8y", acct, n, p}, + {"second", acct2, n2, p2}, + } + + for _, tc := range cases { + tx := New([]byte(tc.data)) + // unsigned version + _, err = tx.Signers() + assert.NotNil(err) + orig, err := tx.TxBytes() + require.Nil(err, "%+v", err) + data := tx.SignBytes() + assert.Equal(tc.data, string(data)) + + // sign it + err = cstore.Sign(tc.name, tc.pass, tx) + require.Nil(err, "%+v", err) + // but not twice + err = cstore.Sign(tc.name, tc.pass, tx) + require.NotNil(err) + + // make sure it is proper now + sigs, err := tx.Signers() + require.Nil(err, "%+v", err) + if assert.Equal(1, len(sigs)) { + // This must be refactored... + assert.Equal(tc.key.PubKey, sigs[0]) + } + // the tx bytes should change after this + after, err := tx.TxBytes() + require.Nil(err, "%+v", err) + assert.NotEqual(orig, after, "%X != %X", orig, after) + + // sign bytes are the same + data = tx.SignBytes() + assert.Equal(tc.data, string(data)) + } +} diff --git a/tx/reader.go b/tx/reader.go new file mode 100644 index 000000000..7689693cb --- /dev/null +++ b/tx/reader.go @@ -0,0 +1,76 @@ +package tx + +import ( + crypto "github.com/tendermint/go-crypto" + data "github.com/tendermint/go-data" + keys "github.com/tendermint/go-keys" +) + +const ( + typeOneSig = byte(0x01) + typeMultiSig = byte(0x02) + nameOneSig = "sig" + nameMultiSig = "multi" +) + +var _ keys.Signable = Sig{} +var TxMapper data.Mapper + +func init() { + TxMapper = data.NewMapper(Sig{}). + RegisterInterface(&OneSig{}, nameOneSig, typeOneSig). + RegisterInterface(&MultiSig{}, nameMultiSig, typeMultiSig) +} + +/* +DO NOT USE this interface. + +It is public by necessity but should never be used directly +outside of this package. + +Only use Sig, never SigInner +*/ +type SigInner interface { + SignBytes() []byte + Sign(pubkey crypto.PubKey, sig crypto.Signature) error + Signers() ([]crypto.PubKey, error) +} + +// Sig is what is exported, and handles serialization +type Sig struct { + SigInner +} + +// TxBytes +func (s Sig) TxBytes() ([]byte, error) { + return data.ToWire(s) +} + +// WrapSig goes from concrete implementation to "interface" struct +func WrapSig(pk SigInner) Sig { + if wrap, ok := pk.(Sig); ok { + pk = wrap.Unwrap() + } + return Sig{pk} +} + +// Unwrap recovers the concrete interface safely (regardless of levels of embeds) +func (p Sig) Unwrap() SigInner { + pk := p.SigInner + for wrap, ok := pk.(Sig); ok; wrap, ok = pk.(Sig) { + pk = wrap.SigInner + } + return pk +} + +func (p Sig) MarshalJSON() ([]byte, error) { + return TxMapper.ToJSON(p.Unwrap()) +} + +func (p *Sig) UnmarshalJSON(data []byte) (err error) { + parsed, err := TxMapper.FromJSON(data) + if err == nil && parsed != nil { + p.SigInner = parsed.(SigInner) + } + return +} diff --git a/tx/reader_test.go b/tx/reader_test.go new file mode 100644 index 000000000..54b76af96 --- /dev/null +++ b/tx/reader_test.go @@ -0,0 +1,70 @@ +package tx + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + crypto "github.com/tendermint/go-crypto" + data "github.com/tendermint/go-data" + "github.com/tendermint/go-keys/cryptostore" + "github.com/tendermint/go-keys/storage/memstorage" +) + +func TestReader(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + algo := crypto.NameEd25519 + cstore := cryptostore.New( + cryptostore.SecretBox, + memstorage.New(), + ) + type sigs struct{ name, pass string } + u := sigs{"alice", "1234"} + u2 := sigs{"bob", "foobar"} + + _, err := cstore.Create(u.name, u.pass, algo) + require.Nil(err, "%+v", err) + _, err = cstore.Create(u2.name, u2.pass, algo) + require.Nil(err, "%+v", err) + + cases := []struct { + tx Sig + sigs []sigs + }{ + {New([]byte("first")), nil}, + {New([]byte("second")), []sigs{u}}, + {New([]byte("other")), []sigs{u2}}, + {NewMulti([]byte("m-first")), nil}, + {NewMulti([]byte("m-second")), []sigs{u}}, + {NewMulti([]byte("m-other")), []sigs{u, u2}}, + } + + for _, tc := range cases { + tx := tc.tx + + // make sure json serialization and loading works w/o sigs + var pre Sig + pjs, err := data.ToJSON(tx) + require.Nil(err, "%+v", err) + err = data.FromJSON(pjs, &pre) + require.Nil(err, "%+v", err) + assert.Equal(tx, pre) + + for _, s := range tc.sigs { + err = cstore.Sign(s.name, s.pass, tx) + require.Nil(err, "%+v", err) + } + + var post Sig + sjs, err := data.ToJSON(tx) + require.Nil(err, "%+v", err) + err = data.FromJSON(sjs, &post) + require.Nil(err, "%+v\n%s", err, string(sjs)) + assert.Equal(tx, post) + + if len(tc.sigs) > 0 { + assert.NotEqual(pjs, sjs, "%s\n ------ %s", string(pjs), string(sjs)) + } + } +} From e49fdf7be75cb8a1c25b65bf3304e9038af9aea5 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sat, 8 Apr 2017 17:07:02 -0700 Subject: [PATCH 049/287] Add HD functions --- .gitignore | 2 + README.md | 837 +++++++++++++++++++++++++++++++++++++++++++++ hd/address.go | 289 ++++++++++++++++ hd/address_test.go | 37 ++ hd/hd_test.go | 50 +-- hd/test.json | 1 + 6 files changed, 1194 insertions(+), 22 deletions(-) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 hd/address.go create mode 100644 hd/address_test.go create mode 100644 hd/test.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..381931381 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.swp +*.swo diff --git a/README.md b/README.md new file mode 100644 index 000000000..ada192080 --- /dev/null +++ b/README.md @@ -0,0 +1,837 @@ + + +# crypto +`import "github.com/tendermint/go-crypto"` + +* [Overview](#pkg-overview) +* [Index](#pkg-index) +* [Subdirectories](#pkg-subdirectories) + +## Overview + + + +## Index +* [Constants](#pkg-constants) +* [func CRandBytes(numBytes int) []byte](#CRandBytes) +* [func CRandHex(numDigits int) string](#CRandHex) +* [func CReader() io.Reader](#CReader) +* [func DecodeArmor(armorStr string) (blockType string, headers map[string]string, data []byte, err error)](#DecodeArmor) +* [func DecryptSymmetric(ciphertext []byte, secret []byte) (plaintext []byte, err error)](#DecryptSymmetric) +* [func EncodeArmor(blockType string, headers map[string]string, data []byte) string](#EncodeArmor) +* [func EncryptSymmetric(plaintext []byte, secret []byte) (ciphertext []byte)](#EncryptSymmetric) +* [func MixEntropy(seedBytes []byte)](#MixEntropy) +* [func Ripemd160(bytes []byte) []byte](#Ripemd160) +* [func Sha256(bytes []byte) []byte](#Sha256) +* [type PrivKey](#PrivKey) + * [func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error)](#PrivKeyFromBytes) +* [type PrivKeyEd25519](#PrivKeyEd25519) + * [func GenPrivKeyEd25519() PrivKeyEd25519](#GenPrivKeyEd25519) + * [func GenPrivKeyEd25519FromSecret(secret []byte) PrivKeyEd25519](#GenPrivKeyEd25519FromSecret) + * [func (privKey PrivKeyEd25519) Bytes() []byte](#PrivKeyEd25519.Bytes) + * [func (privKey PrivKeyEd25519) Equals(other PrivKey) bool](#PrivKeyEd25519.Equals) + * [func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519](#PrivKeyEd25519.Generate) + * [func (p PrivKeyEd25519) MarshalJSON() ([]byte, error)](#PrivKeyEd25519.MarshalJSON) + * [func (privKey PrivKeyEd25519) PubKey() PubKey](#PrivKeyEd25519.PubKey) + * [func (privKey PrivKeyEd25519) Sign(msg []byte) Signature](#PrivKeyEd25519.Sign) + * [func (privKey PrivKeyEd25519) String() string](#PrivKeyEd25519.String) + * [func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte](#PrivKeyEd25519.ToCurve25519) + * [func (p *PrivKeyEd25519) UnmarshalJSON(enc []byte) error](#PrivKeyEd25519.UnmarshalJSON) +* [type PrivKeyS](#PrivKeyS) + * [func (p PrivKeyS) Empty() bool](#PrivKeyS.Empty) + * [func (p PrivKeyS) MarshalJSON() ([]byte, error)](#PrivKeyS.MarshalJSON) + * [func (p *PrivKeyS) UnmarshalJSON(data []byte) (err error)](#PrivKeyS.UnmarshalJSON) +* [type PrivKeySecp256k1](#PrivKeySecp256k1) + * [func GenPrivKeySecp256k1() PrivKeySecp256k1](#GenPrivKeySecp256k1) + * [func GenPrivKeySecp256k1FromSecret(secret []byte) PrivKeySecp256k1](#GenPrivKeySecp256k1FromSecret) + * [func (privKey PrivKeySecp256k1) Bytes() []byte](#PrivKeySecp256k1.Bytes) + * [func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool](#PrivKeySecp256k1.Equals) + * [func (p PrivKeySecp256k1) MarshalJSON() ([]byte, error)](#PrivKeySecp256k1.MarshalJSON) + * [func (privKey PrivKeySecp256k1) PubKey() PubKey](#PrivKeySecp256k1.PubKey) + * [func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature](#PrivKeySecp256k1.Sign) + * [func (privKey PrivKeySecp256k1) String() string](#PrivKeySecp256k1.String) + * [func (p *PrivKeySecp256k1) UnmarshalJSON(enc []byte) error](#PrivKeySecp256k1.UnmarshalJSON) +* [type PubKey](#PubKey) + * [func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error)](#PubKeyFromBytes) +* [type PubKeyEd25519](#PubKeyEd25519) + * [func (pubKey PubKeyEd25519) Address() []byte](#PubKeyEd25519.Address) + * [func (pubKey PubKeyEd25519) Bytes() []byte](#PubKeyEd25519.Bytes) + * [func (pubKey PubKeyEd25519) Equals(other PubKey) bool](#PubKeyEd25519.Equals) + * [func (pubKey PubKeyEd25519) KeyString() string](#PubKeyEd25519.KeyString) + * [func (p PubKeyEd25519) MarshalJSON() ([]byte, error)](#PubKeyEd25519.MarshalJSON) + * [func (pubKey PubKeyEd25519) String() string](#PubKeyEd25519.String) + * [func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte](#PubKeyEd25519.ToCurve25519) + * [func (p *PubKeyEd25519) UnmarshalJSON(enc []byte) error](#PubKeyEd25519.UnmarshalJSON) + * [func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool](#PubKeyEd25519.VerifyBytes) +* [type PubKeyS](#PubKeyS) + * [func (p PubKeyS) Empty() bool](#PubKeyS.Empty) + * [func (p PubKeyS) MarshalJSON() ([]byte, error)](#PubKeyS.MarshalJSON) + * [func (p *PubKeyS) UnmarshalJSON(data []byte) (err error)](#PubKeyS.UnmarshalJSON) +* [type PubKeySecp256k1](#PubKeySecp256k1) + * [func (pubKey PubKeySecp256k1) Address() []byte](#PubKeySecp256k1.Address) + * [func (pubKey PubKeySecp256k1) Bytes() []byte](#PubKeySecp256k1.Bytes) + * [func (pubKey PubKeySecp256k1) Equals(other PubKey) bool](#PubKeySecp256k1.Equals) + * [func (pubKey PubKeySecp256k1) KeyString() string](#PubKeySecp256k1.KeyString) + * [func (p PubKeySecp256k1) MarshalJSON() ([]byte, error)](#PubKeySecp256k1.MarshalJSON) + * [func (pubKey PubKeySecp256k1) String() string](#PubKeySecp256k1.String) + * [func (p *PubKeySecp256k1) UnmarshalJSON(enc []byte) error](#PubKeySecp256k1.UnmarshalJSON) + * [func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool](#PubKeySecp256k1.VerifyBytes) +* [type Signature](#Signature) + * [func SignatureFromBytes(sigBytes []byte) (sig Signature, err error)](#SignatureFromBytes) +* [type SignatureEd25519](#SignatureEd25519) + * [func (sig SignatureEd25519) Bytes() []byte](#SignatureEd25519.Bytes) + * [func (sig SignatureEd25519) Equals(other Signature) bool](#SignatureEd25519.Equals) + * [func (sig SignatureEd25519) IsZero() bool](#SignatureEd25519.IsZero) + * [func (p SignatureEd25519) MarshalJSON() ([]byte, error)](#SignatureEd25519.MarshalJSON) + * [func (sig SignatureEd25519) String() string](#SignatureEd25519.String) + * [func (p *SignatureEd25519) UnmarshalJSON(enc []byte) error](#SignatureEd25519.UnmarshalJSON) +* [type SignatureS](#SignatureS) + * [func (p SignatureS) Empty() bool](#SignatureS.Empty) + * [func (p SignatureS) MarshalJSON() ([]byte, error)](#SignatureS.MarshalJSON) + * [func (p *SignatureS) UnmarshalJSON(data []byte) (err error)](#SignatureS.UnmarshalJSON) +* [type SignatureSecp256k1](#SignatureSecp256k1) + * [func (sig SignatureSecp256k1) Bytes() []byte](#SignatureSecp256k1.Bytes) + * [func (sig SignatureSecp256k1) Equals(other Signature) bool](#SignatureSecp256k1.Equals) + * [func (sig SignatureSecp256k1) IsZero() bool](#SignatureSecp256k1.IsZero) + * [func (p SignatureSecp256k1) MarshalJSON() ([]byte, error)](#SignatureSecp256k1.MarshalJSON) + * [func (sig SignatureSecp256k1) String() string](#SignatureSecp256k1.String) + * [func (p *SignatureSecp256k1) UnmarshalJSON(enc []byte) error](#SignatureSecp256k1.UnmarshalJSON) + + +#### Package files +[armor.go](/src/github.com/tendermint/go-crypto/armor.go) [hash.go](/src/github.com/tendermint/go-crypto/hash.go) [priv_key.go](/src/github.com/tendermint/go-crypto/priv_key.go) [pub_key.go](/src/github.com/tendermint/go-crypto/pub_key.go) [random.go](/src/github.com/tendermint/go-crypto/random.go) [signature.go](/src/github.com/tendermint/go-crypto/signature.go) [symmetric.go](/src/github.com/tendermint/go-crypto/symmetric.go) + + +## Constants +``` go +const ( + TypeEd25519 = byte(0x01) + TypeSecp256k1 = byte(0x02) + NameEd25519 = "ed25519" + NameSecp256k1 = "secp256k1" +) +``` +Types of implementations + + + + +## func [CRandBytes](/src/target/random.go?s=698:734#L28) +``` go +func CRandBytes(numBytes int) []byte +``` +This uses the OS and the Seed(s). + + + +## func [CRandHex](/src/target/random.go?s=924:959#L38) +``` go +func CRandHex(numDigits int) string +``` +RandHex(24) gives 96 bits of randomness, strong enough for most purposes. + + + +## func [CReader](/src/target/random.go?s=1078:1102#L43) +``` go +func CReader() io.Reader +``` +Returns a crand.Reader mixed with user-supplied entropy + + + +## func [DecodeArmor](/src/target/armor.go?s=596:699#L18) +``` go +func DecodeArmor(armorStr string) (blockType string, headers map[string]string, data []byte, err error) +``` + + +## func [DecryptSymmetric](/src/target/symmetric.go?s=1048:1133#L23) +``` go +func DecryptSymmetric(ciphertext []byte, secret []byte) (plaintext []byte, err error) +``` +secret must be 32 bytes long. Use something like Sha256(Bcrypt(passphrase)) +The ciphertext is (secretbox.Overhead + 24) bytes longer than the plaintext. + + + +## func [EncodeArmor](/src/target/armor.go?s=125:206#L1) +``` go +func EncodeArmor(blockType string, headers map[string]string, data []byte) string +``` + + +## func [EncryptSymmetric](/src/target/symmetric.go?s=356:430#L6) +``` go +func EncryptSymmetric(plaintext []byte, secret []byte) (ciphertext []byte) +``` +secret must be 32 bytes long. Use something like Sha256(Bcrypt(passphrase)) +The ciphertext is (secretbox.Overhead + 24) bytes longer than the plaintext. +NOTE: call crypto.MixEntropy() first. + + + +## func [MixEntropy](/src/target/random.go?s=407:440#L13) +``` go +func MixEntropy(seedBytes []byte) +``` +Mix additional bytes of randomness, e.g. from hardware, user-input, etc. +It is OK to call it multiple times. It does not diminish security. + + + +## func [Ripemd160](/src/target/hash.go?s=185:220#L4) +``` go +func Ripemd160(bytes []byte) []byte +``` + + +## func [Sha256](/src/target/hash.go?s=78:110#L1) +``` go +func Sha256(bytes []byte) []byte +``` + + + +## type [PrivKey](/src/target/priv_key.go?s=326:435#L5) +``` go +type PrivKey interface { + Bytes() []byte + Sign(msg []byte) Signature + PubKey() PubKey + Equals(PrivKey) bool +} +``` +PrivKey is part of PrivAccount and state.PrivValidator. + + + + + + + +### func [PrivKeyFromBytes](/src/target/priv_key.go?s=1302:1373#L50) +``` go +func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) +``` + + + + +## type [PrivKeyEd25519](/src/target/priv_key.go?s=1502:1530#L58) +``` go +type PrivKeyEd25519 [64]byte +``` +Implements PrivKey + + + + + + + +### func [GenPrivKeyEd25519](/src/target/priv_key.go?s=3003:3042#L116) +``` go +func GenPrivKeyEd25519() PrivKeyEd25519 +``` + +### func [GenPrivKeyEd25519FromSecret](/src/target/priv_key.go?s=3290:3352#L125) +``` go +func GenPrivKeyEd25519FromSecret(secret []byte) PrivKeyEd25519 +``` +NOTE: secret should be the output of a KDF like bcrypt, +if it's derived from user input. + + + + + +### func (PrivKeyEd25519) [Bytes](/src/target/priv_key.go?s=1532:1576#L60) +``` go +func (privKey PrivKeyEd25519) Bytes() []byte +``` + + + +### func (PrivKeyEd25519) [Equals](/src/target/priv_key.go?s=1973:2029#L75) +``` go +func (privKey PrivKeyEd25519) Equals(other PrivKey) bool +``` + + + +### func (PrivKeyEd25519) [Generate](/src/target/priv_key.go?s=2761:2825#L106) +``` go +func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519 +``` +Deterministically generates new priv-key bytes from key. + + + + +### func (PrivKeyEd25519) [MarshalJSON](/src/target/priv_key.go?s=2156:2209#L83) +``` go +func (p PrivKeyEd25519) MarshalJSON() ([]byte, error) +``` + + + +### func (PrivKeyEd25519) [PubKey](/src/target/priv_key.go?s=1826:1871#L70) +``` go +func (privKey PrivKeyEd25519) PubKey() PubKey +``` + + + +### func (PrivKeyEd25519) [Sign](/src/target/priv_key.go?s=1635:1691#L64) +``` go +func (privKey PrivKeyEd25519) Sign(msg []byte) Signature +``` + + + +### func (PrivKeyEd25519) [String](/src/target/priv_key.go?s=2613:2658#L101) +``` go +func (privKey PrivKeyEd25519) String() string +``` + + + +### func (PrivKeyEd25519) [ToCurve25519](/src/target/priv_key.go?s=2399:2453#L94) +``` go +func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte +``` + + + +### func (\*PrivKeyEd25519) [UnmarshalJSON](/src/target/priv_key.go?s=2250:2306#L87) +``` go +func (p *PrivKeyEd25519) UnmarshalJSON(enc []byte) error +``` + + + +## type [PrivKeyS](/src/target/priv_key.go?s=929:962#L30) +``` go +type PrivKeyS struct { + PrivKey +} +``` +PrivKeyS add json serialization to PrivKey + + + + + + + + + + +### func (PrivKeyS) [Empty](/src/target/priv_key.go?s=1241:1271#L46) +``` go +func (p PrivKeyS) Empty() bool +``` + + + +### func (PrivKeyS) [MarshalJSON](/src/target/priv_key.go?s=964:1011#L34) +``` go +func (p PrivKeyS) MarshalJSON() ([]byte, error) +``` + + + +### func (\*PrivKeyS) [UnmarshalJSON](/src/target/priv_key.go?s=1057:1114#L38) +``` go +func (p *PrivKeyS) UnmarshalJSON(data []byte) (err error) +``` + + + +## type [PrivKeySecp256k1](/src/target/priv_key.go?s=3635:3665#L136) +``` go +type PrivKeySecp256k1 [32]byte +``` +Implements PrivKey + + + + + + + +### func [GenPrivKeySecp256k1](/src/target/priv_key.go?s=5071:5114#L194) +``` go +func GenPrivKeySecp256k1() PrivKeySecp256k1 +``` + +### func [GenPrivKeySecp256k1FromSecret](/src/target/priv_key.go?s=5436:5502#L204) +``` go +func GenPrivKeySecp256k1FromSecret(secret []byte) PrivKeySecp256k1 +``` +NOTE: secret should be the output of a KDF like bcrypt, +if it's derived from user input. + + + + + +### func (PrivKeySecp256k1) [Bytes](/src/target/priv_key.go?s=3667:3713#L138) +``` go +func (privKey PrivKeySecp256k1) Bytes() []byte +``` + + + +### func (PrivKeySecp256k1) [Equals](/src/target/priv_key.go?s=4235:4293#L158) +``` go +func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool +``` + + + +### func (PrivKeySecp256k1) [MarshalJSON](/src/target/priv_key.go?s=4426:4481#L166) +``` go +func (p PrivKeySecp256k1) MarshalJSON() ([]byte, error) +``` + + + +### func (PrivKeySecp256k1) [PubKey](/src/target/priv_key.go?s=4032:4079#L151) +``` go +func (privKey PrivKeySecp256k1) PubKey() PubKey +``` + + + +### func (PrivKeySecp256k1) [Sign](/src/target/priv_key.go?s=3772:3830#L142) +``` go +func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature +``` + + + +### func (PrivKeySecp256k1) [String](/src/target/priv_key.go?s=4673:4720#L177) +``` go +func (privKey PrivKeySecp256k1) String() string +``` + + + +### func (\*PrivKeySecp256k1) [UnmarshalJSON](/src/target/priv_key.go?s=4522:4580#L170) +``` go +func (p *PrivKeySecp256k1) UnmarshalJSON(enc []byte) error +``` + + + +## type [PubKey](/src/target/pub_key.go?s=361:506#L7) +``` go +type PubKey interface { + Address() []byte + Bytes() []byte + KeyString() string + VerifyBytes(msg []byte, sig Signature) bool + Equals(PubKey) bool +} +``` +PubKey is part of Account and Validator. + + + + + + + +### func [PubKeyFromBytes](/src/target/pub_key.go?s=1203:1270#L45) +``` go +func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) +``` + + + + +## type [PubKeyEd25519](/src/target/pub_key.go?s=1396:1423#L53) +``` go +type PubKeyEd25519 [32]byte +``` +Implements PubKey + + + + + + + + + + +### func (PubKeyEd25519) [Address](/src/target/pub_key.go?s=1425:1469#L55) +``` go +func (pubKey PubKeyEd25519) Address() []byte +``` + + + +### func (PubKeyEd25519) [Bytes](/src/target/pub_key.go?s=1789:1831#L68) +``` go +func (pubKey PubKeyEd25519) Bytes() []byte +``` + + + +### func (PubKeyEd25519) [Equals](/src/target/pub_key.go?s=3064:3117#L119) +``` go +func (pubKey PubKeyEd25519) Equals(other PubKey) bool +``` + + + +### func (PubKeyEd25519) [KeyString](/src/target/pub_key.go?s=2983:3029#L115) +``` go +func (pubKey PubKeyEd25519) KeyString() string +``` +Must return the full bytes in hex. +Used for map keying, etc. + + + + +### func (PubKeyEd25519) [MarshalJSON](/src/target/pub_key.go?s=2279:2331#L87) +``` go +func (p PubKeyEd25519) MarshalJSON() ([]byte, error) +``` + + + +### func (PubKeyEd25519) [String](/src/target/pub_key.go?s=2823:2866#L109) +``` go +func (pubKey PubKeyEd25519) String() string +``` + + + +### func (PubKeyEd25519) [ToCurve25519](/src/target/pub_key.go?s=2585:2637#L100) +``` go +func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte +``` +For use with golang/crypto/nacl/box +If error, returns nil. + + + + +### func (\*PubKeyEd25519) [UnmarshalJSON](/src/target/pub_key.go?s=2372:2427#L91) +``` go +func (p *PubKeyEd25519) UnmarshalJSON(enc []byte) error +``` + + + +### func (PubKeyEd25519) [VerifyBytes](/src/target/pub_key.go?s=1888:1960#L72) +``` go +func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool +``` + + + +## type [PubKeyS](/src/target/pub_key.go?s=841:872#L25) +``` go +type PubKeyS struct { + PubKey +} +``` +PubKeyS add json serialization to PubKey + + + + + + + + + + +### func (PubKeyS) [Empty](/src/target/pub_key.go?s=1144:1173#L41) +``` go +func (p PubKeyS) Empty() bool +``` + + + +### func (PubKeyS) [MarshalJSON](/src/target/pub_key.go?s=874:920#L29) +``` go +func (p PubKeyS) MarshalJSON() ([]byte, error) +``` + + + +### func (\*PubKeyS) [UnmarshalJSON](/src/target/pub_key.go?s=964:1020#L33) +``` go +func (p *PubKeyS) UnmarshalJSON(data []byte) (err error) +``` + + + +## type [PubKeySecp256k1](/src/target/pub_key.go?s=3401:3430#L132) +``` go +type PubKeySecp256k1 [33]byte +``` +Implements PubKey. +Compressed pubkey (just the x-cord), +prefixed with 0x02 or 0x03, depending on the y-cord. + + + + + + + + + + +### func (PubKeySecp256k1) [Address](/src/target/pub_key.go?s=3497:3543#L135) +``` go +func (pubKey PubKeySecp256k1) Address() []byte +``` +Implements Bitcoin style addresses: RIPEMD160(SHA256(pubkey)) + + + + +### func (PubKeySecp256k1) [Bytes](/src/target/pub_key.go?s=3774:3818#L145) +``` go +func (pubKey PubKeySecp256k1) Bytes() []byte +``` + + + +### func (PubKeySecp256k1) [Equals](/src/target/pub_key.go?s=4897:4952#L192) +``` go +func (pubKey PubKeySecp256k1) Equals(other PubKey) bool +``` + + + +### func (PubKeySecp256k1) [KeyString](/src/target/pub_key.go?s=4814:4862#L188) +``` go +func (pubKey PubKeySecp256k1) KeyString() string +``` +Must return the full bytes in hex. +Used for map keying, etc. + + + + +### func (PubKeySecp256k1) [MarshalJSON](/src/target/pub_key.go?s=4405:4459#L171) +``` go +func (p PubKeySecp256k1) MarshalJSON() ([]byte, error) +``` + + + +### func (PubKeySecp256k1) [String](/src/target/pub_key.go?s=4650:4695#L182) +``` go +func (pubKey PubKeySecp256k1) String() string +``` + + + +### func (\*PubKeySecp256k1) [UnmarshalJSON](/src/target/pub_key.go?s=4500:4557#L175) +``` go +func (p *PubKeySecp256k1) UnmarshalJSON(enc []byte) error +``` + + + +### func (PubKeySecp256k1) [VerifyBytes](/src/target/pub_key.go?s=3875:3949#L149) +``` go +func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool +``` + + + +## type [Signature](/src/target/signature.go?s=204:304#L3) +``` go +type Signature interface { + Bytes() []byte + IsZero() bool + String() string + Equals(Signature) bool +} +``` +Signature is a part of Txs and consensus Votes. + + + + + + + +### func [SignatureFromBytes](/src/target/signature.go?s=1031:1098#L40) +``` go +func SignatureFromBytes(sigBytes []byte) (sig Signature, err error) +``` + + + + +## type [SignatureEd25519](/src/target/signature.go?s=1221:1251#L48) +``` go +type SignatureEd25519 [64]byte +``` +Implements Signature + + + + + + + + + + +### func (SignatureEd25519) [Bytes](/src/target/signature.go?s=1253:1295#L50) +``` go +func (sig SignatureEd25519) Bytes() []byte +``` + + + +### func (SignatureEd25519) [Equals](/src/target/signature.go?s=1520:1576#L58) +``` go +func (sig SignatureEd25519) Equals(other Signature) bool +``` + + + +### func (SignatureEd25519) [IsZero](/src/target/signature.go?s=1352:1393#L54) +``` go +func (sig SignatureEd25519) IsZero() bool +``` + + + +### func (SignatureEd25519) [MarshalJSON](/src/target/signature.go?s=1701:1756#L66) +``` go +func (p SignatureEd25519) MarshalJSON() ([]byte, error) +``` + + + +### func (SignatureEd25519) [String](/src/target/signature.go?s=1420:1463#L56) +``` go +func (sig SignatureEd25519) String() string +``` + + + +### func (\*SignatureEd25519) [UnmarshalJSON](/src/target/signature.go?s=1797:1855#L70) +``` go +func (p *SignatureEd25519) UnmarshalJSON(enc []byte) error +``` + + + +## type [SignatureS](/src/target/signature.go?s=648:685#L20) +``` go +type SignatureS struct { + Signature +} +``` +SignatureS add json serialization to Signature + + + + + + + + + + +### func (SignatureS) [Empty](/src/target/signature.go?s=966:998#L36) +``` go +func (p SignatureS) Empty() bool +``` + + + +### func (SignatureS) [MarshalJSON](/src/target/signature.go?s=687:736#L24) +``` go +func (p SignatureS) MarshalJSON() ([]byte, error) +``` + + + +### func (\*SignatureS) [UnmarshalJSON](/src/target/signature.go?s=780:839#L28) +``` go +func (p *SignatureS) UnmarshalJSON(data []byte) (err error) +``` + + + +## type [SignatureSecp256k1](/src/target/signature.go?s=2013:2043#L80) +``` go +type SignatureSecp256k1 []byte +``` +Implements Signature + + + + + + + + + + +### func (SignatureSecp256k1) [Bytes](/src/target/signature.go?s=2045:2089#L82) +``` go +func (sig SignatureSecp256k1) Bytes() []byte +``` + + + +### func (SignatureSecp256k1) [Equals](/src/target/signature.go?s=2318:2376#L90) +``` go +func (sig SignatureSecp256k1) Equals(other Signature) bool +``` + + + +### func (SignatureSecp256k1) [IsZero](/src/target/signature.go?s=2146:2189#L86) +``` go +func (sig SignatureSecp256k1) IsZero() bool +``` + + + +### func (SignatureSecp256k1) [MarshalJSON](/src/target/signature.go?s=2502:2559#L97) +``` go +func (p SignatureSecp256k1) MarshalJSON() ([]byte, error) +``` + + + +### func (SignatureSecp256k1) [String](/src/target/signature.go?s=2216:2261#L88) +``` go +func (sig SignatureSecp256k1) String() string +``` + + + +### func (\*SignatureSecp256k1) [UnmarshalJSON](/src/target/signature.go?s=2597:2657#L101) +``` go +func (p *SignatureSecp256k1) UnmarshalJSON(enc []byte) error +``` + + + + + + + +- - - +Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) diff --git a/hd/address.go b/hd/address.go new file mode 100644 index 000000000..afdeefbc4 --- /dev/null +++ b/hd/address.go @@ -0,0 +1,289 @@ +package hd + +import ( + "crypto/ecdsa" + "crypto/hmac" + "crypto/sha256" + "crypto/sha512" + "encoding/base64" + "encoding/binary" + "encoding/hex" + "errors" + "fmt" + "hash" + "log" + "math/big" + "strconv" + "strings" + + "github.com/btcsuite/btcd/btcec" + "github.com/btcsuite/btcutil/base58" + "github.com/tendermint/go-crypto" + "golang.org/x/crypto/ripemd160" +) + +const ( + // BIP32 chainpath prefix + CHAINPATH_PREFIX_DEPOSIT = 0 + CHAINPATH_PREFIX_CHANGE = 1 + CHAINPATH_PREFIX_SWEEP = 2 + CHAINPATH_PREFIX_SWEEP_DRY = 102 +) + +func ComputeAddress(coin string, pubKeyHex string, chainHex string, path string, index int32) string { + pubKeyBytes := DerivePublicKeyForPath( + HexDecode(pubKeyHex), + HexDecode(chainHex), + fmt.Sprintf("%v/%v", path, index), + ) + return AddrFromPubKeyBytes(coin, pubKeyBytes) +} + +func ComputePrivateKey(mprivHex string, chainHex string, path string, index int32) string { + privKeyBytes := DerivePrivateKeyForPath( + HexDecode(mprivHex), + HexDecode(chainHex), + fmt.Sprintf("%v/%v", path, index), + ) + return HexEncode(privKeyBytes) +} + +func ComputeAddressForPrivKey(coin string, privKey string) string { + pubKeyBytes := PubKeyBytesFromPrivKeyBytes(HexDecode(privKey), true) + return AddrFromPubKeyBytes(coin, pubKeyBytes) +} + +func SignMessage(privKey string, message string, compress bool) string { + prefixBytes := []byte("Bitcoin Signed Message:\n") + messageBytes := []byte(message) + bytes := []byte{} + bytes = append(bytes, byte(len(prefixBytes))) + bytes = append(bytes, prefixBytes...) + bytes = append(bytes, byte(len(messageBytes))) + bytes = append(bytes, messageBytes...) + privKeyBytes := HexDecode(privKey) + x, y := btcec.S256().ScalarBaseMult(privKeyBytes) + ecdsaPubKey := ecdsa.PublicKey{ + Curve: btcec.S256(), + X: x, + Y: y, + } + ecdsaPrivKey := &btcec.PrivateKey{ + PublicKey: ecdsaPubKey, + D: new(big.Int).SetBytes(privKeyBytes), + } + sigbytes, err := btcec.SignCompact(btcec.S256(), ecdsaPrivKey, crypto.Sha256(crypto.Sha256(bytes)), compress) + if err != nil { + panic(err) + } + return base64.StdEncoding.EncodeToString(sigbytes) +} + +// returns MPK, Chain, and master secret in hex. +func ComputeMastersFromSeed(seed string) (string, string, string, string) { + secret, chain := I64([]byte("Bitcoin seed"), []byte(seed)) + pubKeyBytes := PubKeyBytesFromPrivKeyBytes(secret, true) + return HexEncode(pubKeyBytes), HexEncode(secret), HexEncode(chain), HexEncode(secret) +} + +func ComputeWIF(coin string, privKey string, compress bool) string { + return WIFFromPrivKeyBytes(coin, HexDecode(privKey), compress) +} + +func ComputeTxId(rawTxHex string) string { + return HexEncode(ReverseBytes(CalcHash256(HexDecode(rawTxHex)))) +} + +// Private methods... + +func printKeyInfo(privKeyBytes []byte, pubKeyBytes []byte, chain []byte) { + if pubKeyBytes == nil { + pubKeyBytes = PubKeyBytesFromPrivKeyBytes(privKeyBytes, true) + } + addr := AddrFromPubKeyBytes("BTC", pubKeyBytes) + log.Println("\nprikey:\t%v\npubKeyBytes:\t%v\naddr:\t%v\nchain:\t%v", + HexEncode(privKeyBytes), + HexEncode(pubKeyBytes), + addr, + HexEncode(chain)) +} + +func DerivePrivateKeyForPath(privKeyBytes []byte, chain []byte, path string) []byte { + data := privKeyBytes + parts := strings.Split(path, "/") + for _, part := range parts { + prime := part[len(part)-1:] == "'" + // prime == private derivation. Otherwise public. + if prime { + part = part[:len(part)-1] + } + i, err := strconv.Atoi(part) + if err != nil { + panic(err) + } + if i < 0 { + panic(errors.New("index too large.")) + } + data, chain = DerivePrivateKey(data, chain, uint32(i), prime) + //printKeyInfo(data, nil, chain) + } + return data +} + +func DerivePublicKeyForPath(pubKeyBytes []byte, chain []byte, path string) []byte { + data := pubKeyBytes + parts := strings.Split(path, "/") + for _, part := range parts { + prime := part[len(part)-1:] == "'" + if prime { + panic(errors.New("cannot do a prime derivation from public key")) + } + i, err := strconv.Atoi(part) + if err != nil { + panic(err) + } + if i < 0 { + panic(errors.New("index too large.")) + } + data, chain = DerivePublicKey(data, chain, uint32(i)) + //printKeyInfo(nil, data, chain) + } + return data +} + +func DerivePrivateKey(privKeyBytes []byte, chain []byte, i uint32, prime bool) ([]byte, []byte) { + data := []byte{} + if prime { + i = i | 0x80000000 + data = append([]byte{byte(0)}, privKeyBytes...) + } else { + public := PubKeyBytesFromPrivKeyBytes(privKeyBytes, true) + data = public + } + data = append(data, uint32ToBytes(i)...) + data2, chain2 := I64(chain, data) + x := addScalars(privKeyBytes, data2) + return x, chain2 +} + +func DerivePublicKey(pubKeyBytes []byte, chain []byte, i uint32) ([]byte, []byte) { + data := []byte{} + data = append(data, pubKeyBytes...) + data = append(data, uint32ToBytes(i)...) + data2, chain2 := I64(chain, data) + data2p := PubKeyBytesFromPrivKeyBytes(data2, true) + return addPoints(pubKeyBytes, data2p), chain2 +} + +func addPoints(a []byte, b []byte) []byte { + ap, err := btcec.ParsePubKey(a, btcec.S256()) + if err != nil { + panic(err) + } + bp, err := btcec.ParsePubKey(b, btcec.S256()) + if err != nil { + panic(err) + } + sumX, sumY := btcec.S256().Add(ap.X, ap.Y, bp.X, bp.Y) + sum := (*btcec.PublicKey)(&btcec.PublicKey{ + Curve: btcec.S256(), + X: sumX, + Y: sumY, + }) + return sum.SerializeCompressed() +} + +func addScalars(a []byte, b []byte) []byte { + aInt := new(big.Int).SetBytes(a) + bInt := new(big.Int).SetBytes(b) + sInt := new(big.Int).Add(aInt, bInt) + x := sInt.Mod(sInt, btcec.S256().N).Bytes() + x2 := [32]byte{} + copy(x2[32-len(x):], x) + return x2[:] +} + +func uint32ToBytes(i uint32) []byte { + b := [4]byte{} + binary.BigEndian.PutUint32(b[:], i) + return b[:] +} + +func HexEncode(b []byte) string { + return hex.EncodeToString(b) +} + +func HexDecode(str string) []byte { + b, _ := hex.DecodeString(str) + return b +} + +func I64(key []byte, data []byte) ([]byte, []byte) { + mac := hmac.New(sha512.New, key) + mac.Write(data) + I := mac.Sum(nil) + return I[:32], I[32:] +} + +func AddrFromPubKeyBytes(coin string, pubKeyBytes []byte) string { + prefix := byte(0x00) // TODO Make const or configurable + h160 := CalcHash160(pubKeyBytes) + h160 = append([]byte{prefix}, h160...) + checksum := CalcHash256(h160) + b := append(h160, checksum[:4]...) + return base58.Encode(b) +} + +func WIFFromPrivKeyBytes(coin string, privKeyBytes []byte, compress bool) string { + prefix := byte(0x80) // TODO Make const or configurable + bytes := append([]byte{prefix}, privKeyBytes...) + if compress { + bytes = append(bytes, byte(1)) + } + checksum := CalcHash256(bytes) + bytes = append(bytes, checksum[:4]...) + return base58.Encode(bytes) +} + +func PubKeyBytesFromPrivKeyBytes(privKeyBytes []byte, compress bool) (pubKeyBytes []byte) { + x, y := btcec.S256().ScalarBaseMult(privKeyBytes) + pub := (*btcec.PublicKey)(&btcec.PublicKey{ + Curve: btcec.S256(), + X: x, + Y: y, + }) + + if compress { + return pub.SerializeCompressed() + } + return pub.SerializeUncompressed() +} + +// Calculate the hash of hasher over buf. +func CalcHash(buf []byte, hasher hash.Hash) []byte { + hasher.Write(buf) + return hasher.Sum(nil) +} + +// calculate hash160 which is ripemd160(sha256(data)) +func CalcHash160(buf []byte) []byte { + return CalcHash(CalcHash(buf, sha256.New()), ripemd160.New()) +} + +// calculate hash256 which is sha256(sha256(data)) +func CalcHash256(buf []byte) []byte { + return CalcHash(CalcHash(buf, sha256.New()), sha256.New()) +} + +// calculate sha512(data) +func CalcSha512(buf []byte) []byte { + return CalcHash(buf, sha512.New()) +} + +func ReverseBytes(buf []byte) []byte { + res := []byte{} + for i := len(buf) - 1; i >= 0; i-- { + res = append(res, buf[i]) + } + return res +} diff --git a/hd/address_test.go b/hd/address_test.go new file mode 100644 index 000000000..0554733f1 --- /dev/null +++ b/hd/address_test.go @@ -0,0 +1,37 @@ +package hd + +/* + +import ( + "encoding/hex" + "fmt" + "testing" +) + +func TestManual(t *testing.T) { + bytes, _ := hex.DecodeString("dfac699f1618c9be4df2befe94dc5f313946ebafa386756bd4926a1ecfd7cf2438426ede521d1ee6512391bc200b7910bcbea593e68d52b874c29bdc5a308ed1") + fmt.Println(bytes) + puk, prk, ch, se := ComputeMastersFromSeed(string(bytes)) + fmt.Println(puk, ch, se) + + pubBytes2 := DerivePublicKeyForPath( + HexDecode(puk), + HexDecode(ch), + //"44'/118'/0'/0/0", + "0/0", + ) + fmt.Printf("PUB2 %X\n", pubBytes2) + + privBytes := DerivePrivateKeyForPath( + HexDecode(prk), + HexDecode(ch), + //"44'/118'/0'/0/0", + //"0/0", + "44'/118'/0'/0/0", + ) + fmt.Printf("PRIV %X\n", privBytes) + pubBytes := PubKeyBytesFromPrivKeyBytes(privBytes, true) + fmt.Printf("PUB %X\n", pubBytes) +} + +*/ diff --git a/hd/hd_test.go b/hd/hd_test.go index 42d034717..e771f14b6 100644 --- a/hd/hd_test.go +++ b/hd/hd_test.go @@ -1,4 +1,4 @@ -package crypto +package hd import ( "bytes" @@ -36,15 +36,6 @@ type addrData struct { var hdPath string = "m/44'/118'/0'/0/0" var hdToAddrTable []addrData -/*{ - { - Mnemonic: "spawn essence sudden gown library fire chalk edge start museum glimpse sea", - Priv: "ab20a81c1b9002538e2269e1f1302d519901633d40408313211598899bc00fc6", - Pub: "03eb89fb1c4582eed592e09c31c4665d3956154ea66fd269933d3f036e879abfe6", - Addr: "f7d613738f0a665ec320306d14f5d62a850ff714", - }, -}*/ - func init() { b, err := ioutil.ReadFile("test.json") @@ -71,30 +62,30 @@ func TestHDToAddr(t *testing.T) { seed := bip39.NewSeed(d.Mnemonic, "") - fmt.Println(i, d.Mnemonic) + fmt.Println("================================") + fmt.Println("ROUND:", i, "MNEMONIC:", d.Mnemonic) - //master, priv, pub := tylerSmith(seed) - master, priv, pub := btcsuite(seed) + // master, priv, pub := tylerSmith(seed) + // master, priv, pub := btcsuite(seed) + master, priv, pub := gocrypto(seed) - fmt.Printf("\t%X %X\n", seedB, seed) - fmt.Printf("\t%X %X\n", masterB, master) - fmt.Printf("\t%X %X\n", privB, priv) - fmt.Printf("\t%X %X\n", pubB, pub) + fmt.Printf("\tNODEJS GOLANG\n") + fmt.Printf("SEED \t%X %X\n", seedB, seed) + fmt.Printf("MSTR \t%X %X\n", masterB, master) + fmt.Printf("PRIV \t%X %X\n", privB, priv) + fmt.Printf("PUB \t%X %X\n", pubB, pub) _, _ = priv, privB assert.Equal(t, master, masterB, fmt.Sprintf("Expected masters to match for %d", i)) - - // assert.Equal(t, priv, privB, "Expected priv keys to match") + assert.Equal(t, priv, privB, "Expected priv keys to match") assert.Equal(t, pub, pubB, fmt.Sprintf("Expected pub keys to match for %d", i)) var pubT crypto.PubKeySecp256k1 copy(pubT[:], pub) addr := pubT.Address() + fmt.Printf("ADDR \t%X %X\n", addrB, addr) assert.Equal(t, addr, addrB, fmt.Sprintf("Expected addresses to match %d", i)) - /* if i%10 == 0 { - fmt.Printf("ADDR %d: %s %X %X\n", i, d.Mnemonic, addr, addrB) - }*/ } } @@ -105,6 +96,21 @@ func ifExit(err error, n int) { } } +func gocrypto(seed []byte) ([]byte, []byte, []byte) { + + _, priv, ch, _ := ComputeMastersFromSeed(string(seed)) + + privBytes := DerivePrivateKeyForPath( + HexDecode(priv), + HexDecode(ch), + "44'/118'/0'/0/0", + ) + + pubBytes := PubKeyBytesFromPrivKeyBytes(privBytes, true) + + return HexDecode(priv), privBytes, pubBytes +} + func btcsuite(seed []byte) ([]byte, []byte, []byte) { fmt.Println("HD") masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams) diff --git a/hd/test.json b/hd/test.json new file mode 100644 index 000000000..fa9610999 --- /dev/null +++ b/hd/test.json @@ -0,0 +1 @@ +[{"mnemonic":"measure slogan connect luggage stereo federal stuff stomach stumble security end differ","master":"c177fa4bd21420b6ba2246e4f7a43fbe76545d1204174cae942ffbd79a434d11","seed":"c237f7aa198c5bd560ac8daf5b8421d03855171465b2999b07159671e9186461e7d75dba6c7264b963108431f8674ac8d095b7a22878fa0ab8b582e5d6ea1986","priv":"91bba8805845210665d7a9c5aff63ef69f7604fbeddb485706d31f04458f572c","pub":"0210ddc89abc90bbcbec8c63f5a4ebb016b58063b9d1a77854502042bdfcac5e51","addr":"72e7d6e9cfa899043a0783752a4876423f8effb8"},{"mnemonic":"car taste absurd genius miracle toy earth true glare mobile pig forest","master":"d7e07c472b05a2d668328c148ca07264afb4b53e078a2e1c106470b51c6ef81c","seed":"fda7006f5e9b8d1c02404df6d4e4497ff5c2edf29c801180a046dc54fca2e019554da6e3dd2c26073a7871c5ac529ad465ccf77ec3608727cc47ef88f998ae2b","priv":"1122ac929a0a3b2947ef99c33c20b657cf7342ea09be92869c363cfc52118200","pub":"03d0b431b56ae65aeb5a572654445b3fc968fa9d73995d3b21243cb07ed1ef0067","addr":"63eba204c249c795cd9dbdad58561db56b1d0c9b"},{"mnemonic":"trophy crop coffee oppose pelican help sense note bar faint hen aunt","master":"d1baaea05c34a4bbdc6791ada5aad77fdb0e626642cb884e48d25cd4ef6c9bed","seed":"1cdcfda64cb0e4f5806a48ff374e9f5f7d2939815e7adcce3abd898a7a9204eec4a5822997ca556ad797b4610c4ae6accddc29d80fd651a33d5ed911892479f1","priv":"c4bbb8f1ec60271c1e4f9e019ea45f82ca0ee3c42d8ac268f898fdbdfc28cf48","pub":"03abff20397222f9cae536d6b6776ba48c9b51898f7527dea918058f986fbfad15","addr":"fb6abc72817a9d2c6c1a2fe652434999661e1178"},{"mnemonic":"embrace office author among dream island social gift ask drill polar festival","master":"8d58a57b66a08bc0bd8dde7a718432a01f7aff03cbf999aeb3830d7a1c3d0d54","seed":"65b81faccab573d4a4272ab7c46e5fcc7db66eceeab6796d6dd70d8c54d6c95c3b73a637210a96a95df5ef736f51eec1dd3af4ccca53e98fb7f16d4e22dc3f52","priv":"dec3ffc51d5c9eadfb11e11dcc640f8cb294a21cfbb4a230f164693d57851b3b","pub":"03ef202a875683203e9d9643a2943cb40ff5a69b6efb3b0dedfc8ab1c6928261d1","addr":"db1a5fd30abfe666a049f5c6689a0e3db3ebec1e"},{"mnemonic":"aware gospel lemon tomorrow east wheel member forest walnut virus shallow stick","master":"24075bca853e0066909a6ff06ff02f196d4d641c00677704a6472810b0e3263e","seed":"1a4419cb19e2e7686fe68187aa55a2d4fab8d655c505c5666963d61bc9e92cfb990402d8527f9463b2deb3e86894055e3c6b31cf9995ca5bdf9959db755c9e90","priv":"853665c8f66682e50db33fe699ee72dae036422bee03e37093ed95c871ae8309","pub":"02a4e19e61decd6006bec54fa9c7ada7ee63ca6df12640e9fcf4214faafce791e6","addr":"155dac0e19dc24880b5aed827ebabb05bb563b23"},{"mnemonic":"perfect chief lend clock bracket guard extend medal slice vague cheese child","master":"b594e8d22e4864bdf75ddf29de16b7b207b2bbbdf29132b859f9c71c919ff669","seed":"631fc64164825a9769c4cd376cd736d4dd4191b7728e70b1e84b46322cb8bfb01b5b33cc6707d59bed09f6e7c82335541cd7dfc51ebedfcc2786713a9d141663","priv":"eab18ec583e155fd4ece4a14248bda80c75a6f209a1e4a9b1801e1a707b4356e","pub":"0247995311612868a8d1f6927f18ae5163a9d64a41d8f4015f9dcbbdace9277ed3","addr":"1f42f6538f64d844cef39b941986465076da3d54"},{"mnemonic":"edge early ten vicious piece begin observe ripple neutral farm volume accident","master":"1d6462662cd27419936c1f5b579eb7ebbafe84a6b1a58906c37fc0c2aa612d22","seed":"fb9588a1e3a2d9c26dcdb3cb010b8f868b29c493c95f7fe16761b2a666a8b96ca62997646e8d2cea1ff8ec3b85bd2311741ee327076515ad075623853279b57e","priv":"081847ec4f11a7d54ddd78c6f0fb3cdc32508e4956da14e0d728ddd3862124ce","pub":"03533c9f60afc94de73a0abb7d3e98906fa72cd2aebb202fdac32e2014452779d1","addr":"bcab563beb9ead1a87ab5adabc708502dc4081de"},{"mnemonic":"escape crystal wrist method cave retire wedding unable fringe inhale vibrant inform","master":"8b8597cd8ca42fe10236cc933bf0adda507132be6c41451d6ddda615b4032798","seed":"84582da23a6c4cf3d8f75be55db0d2710e10e31e9d6cee8288d827ed17d6585f19d81831aac12aff8d2724ace9c4220924e7d778eaebb3ff7ac4976b5ee25cc9","priv":"d011566a0c3996c99cf02ee41aa3f24c3328b5773ad0c9ea23f1bda1967a7e2c","pub":"03dcb9dd25915f827965c2d64e258eed1e4cf55f9fa3a9a8b5b411cbccffb11de0","addr":"54eea7e51aec6be8eca7a556c0ba5abfb702b34f"},{"mnemonic":"alter buddy rival question bachelor expose unique menu east sample also fence","master":"0eff009e6a00061a23a9b26f365cc00b0189825fe2eec0a3e78928fbd9f4dd7b","seed":"afa260446549711688b754edf33e313ceaece5502d0dbd8d82bc3c797151741620e403575ba6b54b0071e7122c8ae54893ccf29a43de209c67f7a8c296e47c84","priv":"39be182557862e0b7cf6440fb23568e54772edf734b4710ef571b37a6c27d16c","pub":"032c0d9bdbb97f2b7041734968eae96b3283573b9eefcd3ea1ce286c872bc8df4b","addr":"cbc2321a8e91ea81a56150689921b65a402b5c63"},{"mnemonic":"jar toward train panic unhappy control artefact horse deposit liar minimum pink","master":"009a99faadbdaa139f7ad2297367fdf92103c75194097133b51e0dd57629d06f","seed":"75b28bd52420c950aad1b4270fea0f8816c240e1bb16ad7f35a4bcc234e1c0bce4642422ea359dfae0332417c188a10e1b7efda4a9129809d98a179e8ef618dc","priv":"fbb6c27c23346fb30aa1aca0004f3adff649067efcbcdd58f9e8ed1be9167624","pub":"02463386f13659d68ca10edbecafab3294fddfb989b8012dd8a306c1e716ea73bc","addr":"9aef504159fcefcce23e49b64fe73d64b652751a"},{"mnemonic":"wise undo month ugly case garbage cannon torch sight burst flock enter","master":"e8533102aa8baa896888094c49fd096151adde972cbdd46429095b6081226d88","seed":"c64eab45997b8f27af96667bb8b3e3b1f13cd1cae3f33d357ef8996e958a24f78c6fff1dd21a7aad45a236d02e93722a74827e723415f4c3d2e28b5755ce74bf","priv":"7b28255abe4b5dfc46dd3e4a78aff23fd519ee20d0fccf77fa1f08dc87d4c2a8","pub":"03666213b09e6838c37edd56d858361cc7252aff15c86d9cbb7fd2ffaab2797eff","addr":"8de416131b81c2b4fb347c619e162e5b9d8e9171"},{"mnemonic":"fever hotel cup cover lake cream hello drastic scrap appear device skill","master":"c0c7ae8be6467f73da04bf31893fed60a7d2874a1b8b40cf6b947d3e0c072fd8","seed":"ba8ccb1d6df012c48cd0e97e126aca7192fc49ffe58fe554f2f96b85f7c8ee842e582a7967e053c4ea26f5ee0730dd7b78212b397f5ad89c0691c151c5b649b2","priv":"2d28bdd1c56e6f0c953b97ea571d7ee13f4b53557e9de79de436faee8b984944","pub":"02d4ef64e150ee986d14953bb42d7da5a26e184ae00d33c648e552ec31cc81df62","addr":"1919c6f2d0c93447d4fb8f10b8af4c57a06ad235"},{"mnemonic":"camp pizza test idea attend urban pond gym solution denial coach oppose","master":"e85ce81ff0663a945753449ea5a53a72e429a7badc3c681d7c13bb1b75a4d2ed","seed":"2bc62e90ae9d83635b316ef55f4ada1652dea512da332474598f53f93268ee1e18802ba19e75df651cfe931049ccc7aba7b96d43b62182e0e5b0e21a1cc2f489","priv":"bbd3109cd6edfc583ad1fca84b3c32def7d41e36f1994ac40eb5fd9f72211a47","pub":"032a3e6b6d55ede0c25b78a2bb860adea7ec8b3dbaf7340197ad2d0c07e1673a1f","addr":"4f9ba3935c15ff8ce14f0b09ef498e50693c4c90"},{"mnemonic":"solution buffalo armor capital enter cat banana manage caution loan people gauge","master":"1d894a5d9932bc19f91fa92f0d03f25136a77b4eb961ddd742b74c54edad9332","seed":"b833db5ff34a1bddbbee895d96518261025bbc6a9be596d58435468f1547ff378f504062aab7add0c69763708238d0ab42a90f6af0b790caa1569d1cc089b605","priv":"4e26066e7ff8936e63fb011173f70b0206c1b6ecaa519fb252185e18dbc19705","pub":"03fd00f281ba6065cdc8f6a8cf17cdb22b2ccad62eeb535708381004b2a260837f","addr":"e6247dacab881ff882e412630350eaa6de14817a"},{"mnemonic":"power answer mixture choose course crop decline border carpet absorb long artwork","master":"1d74c0120756009f821899f220d3a9e77291e0549241481b657ddb84af1b66f8","seed":"cd9ac735fee9bbcf45bd79b31196138b3ca002513bd1fb973eae4bffd0c5732611cd67006af3f79dd127ce21532947a0c1355cc774faee82f58cdbef6f8bd7fa","priv":"45f7df4a90d4ed0f58c47ab4839220f50689cb2a5663acd9cbb359d6a23e465e","pub":"02697233abb54eeef1f03a371b0da9a97e85ffe404707b5b7ee3f0e3d2e2f0768f","addr":"0f5addad3faaad7ebaf37c3d3f2576a0a1a5e533"},{"mnemonic":"patrol room turtle cinnamon remain tank butter hazard expose winner rough pull","master":"91eb616d5be757e91052fe74042515b828e2bb14f5666370d7ec37c45018abbd","seed":"7e3b9d910c4b16b06e813b2b003d9c0e8c76ec520702be210d9ec2ef2406e7f473f09f41fda56b6a657c2f1000130e11a88362209c6b4b47362e786b7880916c","priv":"ffc2a31bf0371a095cadbad2e0b5adc5669ceb6faad08da818c3c64e4af53b44","pub":"03b50efecc97cc7d7f101fdcae02662d49d118a63f03180889d8321019f245f6aa","addr":"0c43cd72c09dee746c3af1691b495a8c02286612"},{"mnemonic":"bulb neglect chalk congress cattle found balcony easy tube sick journey quick","master":"a7c632878e900903d4e0e6bc57291f1e64981d703e27b82c2da00dec800d5570","seed":"aaa765dce33f6b289d37fff2e409a540a29f3830a7baa0526eba3317d559ef59e8936e8285b6ea8a62753ec72616163e24963e49d795f38df210836ffc7d8807","priv":"f8b281b658e9a584087e16eab0179747db5c38193cada4fc85364a8f743bfec9","pub":"0384df6f5de3f50793f62eee838d30334501d6339998a25889688ba305998d15cf","addr":"cfe9adc1e454387351d4ef2dfd086101a0012863"},{"mnemonic":"arm asthma voyage mansion hurdle alley ensure team coffee palm spice general","master":"48e37cc4961ff1234938ca5ad6ed22f668b29017067c283ebf2d9642cfc2e57b","seed":"6bec879e82e5d243a6bbd5a0a5dcd21a6403d450f0f498975d5205da7154f62350cf0afa034f921cfedd4dd4dde0b6e3e9cc118b16b6682686211040b3b80b6c","priv":"b0b487d336dbb594947dab6717a5f140056d998f9e8428307491d12b3f9e3883","pub":"039db2ffbad67e7e824bfd0cd9fd8798647390b8c9a583807995a9b49e252279c3","addr":"1353002776f22c179aa208bbdddeab3c369c51be"},{"mnemonic":"spread curtain furnace trim funny usual age floor crunch blue urge pistol","master":"3c44072b545e2e955892ee4e6e5949b748d17d47d3ebeda85fb50a341bda7668","seed":"05376e4a1725d48191bebb1e03bdf76880d82b033f597182becbdcf78f167b260bb5cd6b79681f7ecd7ec75c241f90cb40b2d57d108bcc1b7766a63002af1960","priv":"58285cb1f39d00c6aa84a32a69e0e108ca80e33e75b7b4890e182a7e19485a36","pub":"02e4194b7eab20702d498ee7eb7cc98c3ac8d8b2fc63aa66bc81aad93bb1aa3b71","addr":"9b8ded654ae3336405f0bdf768d4293c462ed51d"},{"mnemonic":"century outdoor world grunt member stuff holiday intact property race mutual vehicle","master":"9b9fcc1fedcf63ae9fd216f9a7253f85cdec90f9b1fdca0c36b03169a5860ff6","seed":"e39f8455cceaf542d4062d998b8de4d7e153e594224ef7d7069abc38acf479fd2485f0821fd9af2116c58180f0069af32d10f0b7222eaef6622de83741824999","priv":"e7b4c942473ebc56868904e588bea3342f761528ca90f2add423e17615ef80cd","pub":"02059867db3a2ab4307a5ff502e9f89c45837927eb2f2b75fe55f0dcf25df9e1ee","addr":"714b9aa6afc10a40d702076990a451dc3ee4fa4b"},{"mnemonic":"world trade divert sad unable plug stereo autumn father ankle biology clown","master":"dae1a9e15469905d0d20172bbaa768be4ea4900594080499a56a69d1ae6d0557","seed":"50169fc286de6432685d85b4352908b079ab4fd11f1d8c6a82093093a9161650c2e10d8407f65f8cd1cf4d9d557590f21f5c717a761e7918ef8ca9b73f410120","priv":"4cd8309f36881d1afbfba66b9fcfa09f948d544db0baa3d81d3bd4d2067950b7","pub":"02a86d26c5b309f49017d4778b13be315cdd1d7c3baceeb61fb91c78bfafda4447","addr":"36e8463e55df56e01fd08b8fafa3ec1704ca5480"},{"mnemonic":"observe minute art scheme pear lava search dove cube entry orbit worth","master":"b7ad8e5b587bf747fae6c42423fc4cafecde0db7c9443d48afe10115d95f9b93","seed":"f3ac2022097390a9a0ae0e47d7746e6bce017d15d97ab74b1f99f70ed1c1e9b3534bdafb69e2aba1a7fa2ad787e9ac6b408f2259259ed4f744054504b05c2001","priv":"63797b9d76fe914825f90664c4a109501be006ce9049d561b9f6798d5e518c33","pub":"028b851a2e41625548564242b16e4bfe07cbf685e2df45dfdaefb4aee9fcd607c9","addr":"16d7f83a219857fe095aff5c31e30333e06b329c"},{"mnemonic":"sphere diamond electric milk furnace uniform tomorrow fatigue mercy isolate judge arena","master":"f88c8bbcf7deb1636c5d96003a2bab945a518278d9d58782cc9e7c9fba4facbf","seed":"5660e5ac88a5c43cf14cdae6929c3894ea5aa3bccf3307f85f1162880562ca352153fc1955b21e8533ce844e79583ab95df0c4199b9bac4520ca1c2821ab4f18","priv":"700fd3176db1c0988d7c35d5ef2cd109c7f52b583ae665011f5d476e5a7b3ff5","pub":"022efb00f6c83d296a12f787239fb7905b7f0c27e4fbb62ae62fe43a91cffa9bf7","addr":"7e4a94be643599be266227f349d4797fb7befb89"},{"mnemonic":"syrup unfair confirm hunt flee armor limb travel hint ski mother credit","master":"01aa87dd513611771cfeee1a39986b13fff29760f0d4c7cfde678e70fd053909","seed":"0e54e0db6ff149c9c572a14c3902fdddd567c8ec361ba3bcccb3a407e3e5c6767ec71eaae2c75aa1fcebaaa95e14920e803d824ae4ce64b13413734dd4526836","priv":"72258e31f535c698fc029b953da4c0a89448e5633cccf27e3e6680bb895dfb99","pub":"02b9e8b06d6ef0ae29f911d48c7facd2528a45f432efb4f2c1f1eeb6056380de2b","addr":"90500208588f51b84399e4ba62ffb653d513cd43"},{"mnemonic":"embrace travel lake capital dream shaft focus kind card hood enjoy memory","master":"04e38c8074b77f3ae174593b3c69cf2f55bcbdc02bde68079691e2d8f4e26e6b","seed":"f9d883ef73a830ccfea41726a150e50c9c51b9acda9e4d022c0b8852a57f6df5d8f26542ef1bfaf83eddbe276b8f16cb7ef151fc512dbe005e473a64a5b84250","priv":"3c1b914b34fb0e5866ef082def1cc4fa589ac0d7be5813621d22fffe68b0d4eb","pub":"0381cc19aa68c4ce5bb656a1ac6d1f93375ae096826f99b46548b69c4a9d07e30e","addr":"2b82395c3c65dfe0c8a82928bb3a53e745e29d26"},{"mnemonic":"rabbit choose combine yellow permit raw puppy interest spring work wall humble","master":"04d834acb4020196f894564e1fe631420ce9e801b27bfdcf221c3068aecf3eef","seed":"1089688a78e4c6e35761aee10a12600d9f48eca57d239eb4573b4ccf28925cf72561c2921b31bdc5b00a222c537ef8c37773cedc7742f61633f1adcf94dee039","priv":"132eb740a216f2e92c7c5f96605ae61824ebcc4fbecddfd17689a1452fa174c0","pub":"03ad014b5a58c19ea616716e555dc7f30c67b5fe06bf77cd91e179f8218ddf89fa","addr":"8e05459a88d149b8473c0411a175c0b070423e05"},{"mnemonic":"bracket what unlock tooth melody wire chapter verb grow direct spin rescue","master":"f64c4e7a30ad534ca260cd280f1e8a6055e63f546d57e61071d5c7937273b4e6","seed":"56ad6c16f5bcdad95f566e8628fcceec9f00cedde68816077e0b6db1c106fc3203052ad334a0fa4b232157ba09983087d853240495fd010ee416a38cd3158108","priv":"37f99cd9868a0e44bf26a0a3180cb13f7e4fc0e379cb035b30bff23dac6518fa","pub":"0218c1d6b479b4a8ed804f62c84397d0ba8405a1a266c5318130f0c8473a60412b","addr":"224d710168a45dea667015231a3b8f910ba91191"},{"mnemonic":"position nation recipe recipe friend defense friend engine that leave match finish","master":"15aef2c47f684437bf88e44e9e518a5c517f16e163efa24f1ed8414d5e975933","seed":"15df2473af5b7147abb3b7d17da3d9668901d37ccc86ff652c9ebc75b596e8f3939e77ba39194276a659bd86947a50fef8ba147058db007232a4648e8c642ca9","priv":"59eaffd27a11231bdb4b39137e6667fe2c3ed81e6ead13818e4cd966729d558e","pub":"03865fbd6db962067b2547f69afd7effe57fb3dd3342bf5255ea6d5456dfea0842","addr":"0a0c1411a031ffc35f95c214e9a580ba4eae6c02"},{"mnemonic":"sight broken hockey empower hair never bean beyond glue small coil barely","master":"b6847c7371864fa8e19e57718425d640a027593b535d779b815e003098294910","seed":"3ad83d292efb99c2fcec6c12433c5fab6d250ae5895e0da6f1db3103bc12d82527be2853711532331280d3defa5f8bfe58fd325d11621c9a10b5c7712b02821b","priv":"9c3f71613d8ca92267a45b562e39e7e12305473be0a6498b3d2b9fa4c65b743d","pub":"02f9461c5bbb2e8ab8281f1384b5f0d412abb970b82e43ef0f1c44b9476319d87b","addr":"501b211909a1647afffe57f1ab7754d4c48940b4"},{"mnemonic":"pause usual cigar festival vanish direct amateur bone orchard cloud fall fat","master":"acdcc1f311b27f850eade92937a5d7a3a9ea1513e2ab5d08fbacba42ea267c30","seed":"cf00b72b84afc0e4b0e2480c6ae55ec1c5ef8eaa0bfa531432b3e9578fdd4ed5199cd24ab22e1cade76f0b763d901becebe686770f3409a8aafd2ee89f111b00","priv":"f0412e04a062aa3cb70cd68fcd327446121c76c33bc440ff93f63e05cd1aeea8","pub":"033708eb3564ba835b779fbce8ad6d64501333c05d0fd798c92f926256464149a4","addr":"92a06b244988b778f0986502d8ffe1804f78d10f"},{"mnemonic":"caution unusual response boost dose jaguar nice exhaust chunk tobacco cable toward","master":"7c584d3382f394a4d07684df15e04c482ba0dd3c8223a97c92c091bc95d2021f","seed":"17e49b743fda3aafe81ad205605dc7012a2096cef2475b7b12e79e54b625de459de8661ebdfacef620c851a11a0237c781ad2a84e7e30abe42f63d8da460267c","priv":"9666bc12bd5dbf4eb4bc1a8acfa021ba8f862e5551d16dd97e8e49381259196a","pub":"0314e1d0b675c88061db3d87de6bf4728ce8ec170bafc754f4fd846341ddad619e","addr":"9b695fc1b1429ec5f697df05a1f4c850489830c6"},{"mnemonic":"dream walk typical enroll knife gallery kingdom dynamic extend course shove power","master":"a0bef19259cafacafdb4854e37f36b332066b5c571538e970a7057ca0d97db1a","seed":"7d2bc8f37a8215149b75577f9efd29e0ada9f5db469e9125883804162dc7b100373f020667c06bebbcc593452dada790237ba11ef638573210d2fe67c7e7f205","priv":"370caa36a7e3a5aead2d4abb58d57b90299b4a65484613e5f39b0b7d1733e1ca","pub":"03bfddfb81e4058e08f3ee57b06065194c252e2a31b074acbb15cc7c5f6487368e","addr":"6299fc81f05eb71fa12dc69b2ca4ddfb6514af29"},{"mnemonic":"apology benefit donkey van target neutral success hen easy capable smart stuff","master":"dd96dfa3d46e0bf70df538f0da3b94cdbd7c20e170c8875032285ed7f6654ba2","seed":"c3e6214d2db9684e4c7022311861a013853761ae9900ea823fc4bc6d70bcb8de98f100664f0a04d32e18cceeba41539f9237e89400cf94e0017fc66622a902a8","priv":"3add5757d65ed58816a2b90411d2019d206b56692205724d6e412a26da88abe9","pub":"033607f86548d8e432cc23c8c995749dbb0bc0731121b90b952465fadec31df521","addr":"e2073969ad58513da3df1225e5266e03c0917e46"},{"mnemonic":"sing eagle hello october action alien equip tongue riot pave oyster fit","master":"03f58c7803af441682b522de573e37b218fdaeef55d9637c1ff8c58e01e57564","seed":"7b9cca7d24f97bf461619b101ecd343455f9b00146fec997ddf3e1c569c615e010cdac3b6643a6e9f4ec45be954bfde0b0320e86b0e869c121ca0adca7d11b5a","priv":"21f52146c31e0a6ab9016b717f0435b36847d5b72d83183b3719890171599068","pub":"02f391dc750aa937a7b89dffc9543f72e73d6939fda1c0d74dcf99f27140656307","addr":"7719d5badc862468acdaae65afef4e1e2ba5fd08"},{"mnemonic":"proof symptom trap diary biology tail cement interest fruit tobacco soccer prosper","master":"a0e4189e097622681654ff2b346e79bbffb8e4e7be139567fba8b2c6aa427096","seed":"557153d485c01cf29622ee3a2e1fdad38c815a7cfe72eb18c85605a96c30e38b16ab37d9a2be07cbee7a211e911bdaf460d47a07d83f385fdae9217eb70487e0","priv":"57a2ee34ff6e6cc2dcc3fe3b907cb44fcce0251013877d46b04e24c9aa20ab73","pub":"026172d3d801fb6e855e2eb0f1171de15e6823bb13002b4e9b01a41cd430da7f69","addr":"a1a953df8d8ff38614bbed7ea9f704ef98a37435"},{"mnemonic":"wire gorilla pupil since trust open amateur evil chicken razor minute science","master":"bb549a48f5610f28b23bff00b8b0de2c93bf4e093400989632c98feb3f45967e","seed":"b05c272f522ec2c53dc26679e207f2c16b6506de02e8fb231175265445218fd8617222a374beadfe1999ed617d5a1f89e0a93c85bc022eff6468c4646f3ea381","priv":"2e96c265f6cafb5912bb2748ff4e0d4b9e960d0b4fbc92967a73591c6d7f54c6","pub":"030d6aa64cba047b2ee2c5af2d3893e17004e66762696e6375b09e32e3675daa21","addr":"e065248114f65902b5cc3aefcc1bbbec4d7ed597"},{"mnemonic":"deer meat share below retire when crash original boy wide leaf blade","master":"47f23c913c2e53d34f7c5d869fccfc07a9a5a7a2e2e811abf9781c69aebb4ec4","seed":"7f1a2f19bab3b121415adf5ffc709749b009fdb90df35b6f3b7d17d8eeeae0d41e0f37565c5320b90edb50076d712aaa5e606a88a44460cea67cb686f1886984","priv":"dcb974cc926c246144d1e6c1c5b3babeb4de3be7dd24ad40d6fbbbc592f384ee","pub":"038d6fa489c22c5a8d95d6931144de5d61748be81076b8cc2f6a0c928065f098c7","addr":"4c8a5b45086b2514f8094d3579b2d420b36f7af4"},{"mnemonic":"accident symbol token cotton enough false cereal verify item army pulse sell","master":"70b049648afff7bafb6ac1d8f5a2e2d78bea9fa93c2924f0cba70d4aee27dde6","seed":"d58819c9862ce8078a2b4db0a25434f03631bac4143590f1a245eed73d41f68f0ab089753064eb879b2edf1a56ccb83d0fa88721cbe2ce05f2c46c040dbfe14c","priv":"ffccb427730c5e0b70f535e6ed079888f64b56b8ff51a7f5be1f1312ab63567a","pub":"03e4300d0181f901e200b71f607729f6db5b422c1dccc6facd28f7c694975d2bcd","addr":"66cff13f2cef89b9313377ef24b4a1fbe2851a64"},{"mnemonic":"modify monster ridge bullet lazy sweet output acid shove hire warrior broken","master":"014daa371dd0446424b0b8cbeacbf8209c5136f184cb97346e82ed155b535b58","seed":"a5c1919d9fab0049de70600a275930979ad0da3a3da6333feccbb1aa41ce461ff1bfc5fe0fa6db126fcd96887dfdc2f531a522fbb90741aea5cf2c7dbde8d585","priv":"b66d283958f01a72683b8c7637dbe3910575fa853c7cdfc395904dc73723fff3","pub":"0298afdd5257542bc7918449a8e22a85c5c6bee8311ebf6c712da73232252ac3bf","addr":"22a6f55327b02536e91a046e9a8347c38be6f111"},{"mnemonic":"economy relief sort silly pizza trick urge harbor coffee flash fantasy sorry","master":"f1ad3c0e0551b62d80ac54f85aa89c9f241f0601397b1b4e12206a67479443c5","seed":"d3abce93f99595d45d0e9eb84aa18cf836f0d7eef60345b8eb2a9d4c87a8eccb7a0304907adca904503d8211dd31ba96e076a4b2eaa91ae575d4d1f7c815e670","priv":"4aab4cc83a2acee81a99bf7fe4fea79cebf133b1a7f0fa3f583912efd60a8525","pub":"03b241333aa683b8319975cd9ab2b046cb7731459e79a0ee9facfafa85bf0a31ea","addr":"9ff29de09deaa15e5050b5156754f9168ddd6df8"},{"mnemonic":"wage thumb correct coffee salute rice trade middle monkey height hint plunge","master":"22c4ec2703eaaf2de49e585a5ac5b7e17340a07523aa46e35503176a3a53fe28","seed":"b93e4f76a12d3cf66af70b58b30a66d5d648918be7d5db33fc3d573d6ca546f39490d3101dd686185e61f4334f4880f1e52d94919b358806812057aeda57bef9","priv":"d5e46c667c3e8c08bec8c7f7dfb1dcff3a628cb39f1eb6b8e117ccfa96551354","pub":"03219d1b8b9d5562e550d0fdd5cb6227988622d664bdc48fcad2c07dc78b82f1a7","addr":"d8f9a7f71ad4a92a07ea0c53a54395895fac7134"},{"mnemonic":"miracle penalty base jeans inhale state roof size tent chair life afraid","master":"82e0e8ce42e1a391f362bd19a0959529139153e6102eb5c947a64ba6b8699c36","seed":"d43f307257db97baf0e458c06b0f509e5534aea2bf8e2972eeef0a5408b9fd52a13df5b73adeccad68ef61017d63243dedcd167185e10402e7a7c03c88087527","priv":"8a82fb302c3b5cf10e119ff3ab01a036e002e9e2d49f0db0a40d5b6828291bc4","pub":"0233cb5096a11a4c79e54cea37e42139a1198a1385cf4e0d37c704352aa3551a13","addr":"e019149a5036bbaadf18788e3be72fa5292a2bed"},{"mnemonic":"stumble army virtual virtual plunge until pudding universe suspect palace bacon dream","master":"32da9154b165c960e927f0b01be8435f2b6ace7dcecda4416a449a50aaa56774","seed":"72bd5c92a8ab4478fa1dad0761118bd3d9a1ce6322c00f81b527701a74e0c4aeea63238017e64d4acaa92bc61af2c41a734d90567799ddfd15deecefba60988b","priv":"63c7d3a6da6149655588c4fab367f187f940101e99618de1d01963aac0dc639b","pub":"03df276b793ee770816ffd90ce2c45b6f24558bb90cedeb19f17264beb53344b29","addr":"03c20b0d41439a374a8a84ed7f139382b6b012f7"},{"mnemonic":"label script force inside outer pulse style nut meadow design receive panel","master":"bb084bcc5df57ad10abb3342888508e399cf723415d35f5440d0eaf808a56d1e","seed":"07029905fd6a538b5ba773384b0084bd11b5ede855a98189b8ca1b3b0457add4b365f98bdc75874ccaf85882c5f1aa59f0f9b77b5a823178cacbb4ff72d0969c","priv":"91eaffd2ddcb6d055c1ab3c7c87e313ba520c263312a6f3d267d41018d7cdec0","pub":"035bbb055ca818cf974da73d5d87d7cc447ff5b9dcbdd39552fb28c925c2077636","addr":"baa25da619099b41aebbbf1282dc6af9dc268664"},{"mnemonic":"nest decorate update alcohol system panel cool grape mind ivory ski dance","master":"64666caf25c290b5f46e27737e61124c34cd428b0d1a09e88ec47cd059765729","seed":"8db4806ada7b82f0811b24aca3b0e11d087cfc27e3e83b77e29c7d5695a126f577304e443f71b3de9239ca743acd05563c1f08f071eca5de4a9961fec463c372","priv":"eadb5c2704fe1eec4f121714b3a6d655d9eb985fae7d535c6543df13214bbfaa","pub":"022bcbc7676ad7693e97a587886293b6190edea96a339e225adaf3f3d6c493851f","addr":"5310b04cdfc366f6268deaaec22d7c628dc4b1f2"},{"mnemonic":"section supreme grit scan arrow flower rebel trend film sting govern museum","master":"29616b872561d14ef56f4761a29da1c5dc768092cf7eeb4ac28aad39e35ab274","seed":"4b8d6961db3f7b123dd71ba5fdc1b7809a19d84dcf25bd1b443b610cdbe44e5d5391aaaa4374ae9d6ca988b5898dadaf5fb79fcc09859851538842cec7acd36e","priv":"da2a60ed2f49ed3b6c1ff78698e3eedb2d9cbe9a707dd91e047f8a17db4f8e92","pub":"0304262df894cfd35a5330eed4008630b6527971f58075282290a070906c0d69a8","addr":"656996e8dc55902fc01bd95e93edb12e1e7dc440"},{"mnemonic":"vacant peanut senior skill helmet absorb turtle regular inmate hidden captain street","master":"7c329d40208ae70f5ecfe8b3a5930adfd09a2f618098e549c972036bea9fa4e1","seed":"b7fb706e9e43c671d401c374984ba22ab5465e15d8572eef3c3302a3fdc77ec8b5cbe7b2a8e42fca582a74fbefe6b755e442e6389592a0845aadf56975a4b212","priv":"29ea2c32ecc076c6e25dd9cc06b9736d730a8306a007df2410143153ec0d7402","pub":"020ee0b300f1714f378676bb533ed50b8336bd288180f4b55a338bb1ada82e0054","addr":"dfba016ba98cae2160c861d8e5117b5afb76a50b"},{"mnemonic":"setup asset fan host pride decide museum fashion disorder coconut school cause","master":"53bdc111a1d4208f6d04234dcdb764ca24c2f42d7dd1de46cb69dd00594f9c67","seed":"0039f1f4e2000001b1af4c47f72dc1f8347a6b7c0559a9625881eb6f7492c2e1fd186b778fe30540ec9dae03de4b8e4ad414ff5692490a547e1127ab03dfadc8","priv":"899611b8bfbc35a6bbf5cb80c193463849fa665aaad680d576f910bec97dc8f4","pub":"031a099725389ba4d2fbe5509cdeb5893a14a7d743a6f87be7af37701e99be18d1","addr":"5d12852d8132e60b6ed5707c4a589107c7c40c72"},{"mnemonic":"debris bus thought unhappy coconut sing sign piano exact favorite zoo title","master":"c2d02edb9583033a0db1b44443769d5c7b9d545aca03ce9d1db0c90c97e648b7","seed":"411ae07dd870bb2c367b72b5d131853088b501476fe0e09896004271dec37068722bd8952aede6c4ea32371361842f9507c5854f7e95b6e1685d8315c4a635fb","priv":"91047f9554ccc47f0c641022c8779e064ccbdf969827d374dc3419fd462c9ca6","pub":"02a6a4280980aa2a570d54d10c295a94acc7d22040a2299c79b9e72808274dd0e1","addr":"f1c8da3f0438f82da710f6e2604b5adc033cc0d0"},{"mnemonic":"stove romance diet season ramp mango swear behave rotate steak alter parent","master":"039f8ff7fd7e498c643ebecc5cd54018fbe4aceb34a92877746471c3d9446517","seed":"2df95585063422c193cafab822373fbcebb38780acb2349ba1e3d5b98f3a5c63f1631fad81649fd22a5acb3673c3c1cc4c93c6fac5e28bf9ce2c2d25a8215543","priv":"251fc43c061854edae6e1bfd0748770965d44ba5c0ba1cd9784aaa07a17ebed1","pub":"035b5a07e862224a2324a8bf3af20fd4dba7157baefaae03124b51274c4b50b48f","addr":"14f3a5e955fe78fdd87fa3b0eb3ef3195b7bad3b"},{"mnemonic":"cruel equip glow protect trade clever charge gadget valid inspire canal unable","master":"e47ebf7c8d4b5f5b80555c25c8fc89bdcfe7eec0d39b2c18adabfc81c90b676d","seed":"5eb48012a0412a9911b697a3b838605813f73a885a967be55432e73870d703f8db4649a59483b1ba26b739fc39af73e4f3f12d78648e78215c98c08428e5cf15","priv":"fa28e24225703620c1dafbcc09015b04b3839f8dbf170e454a8f6216c01f7800","pub":"027b56b3e5859e3df96d60366bd54a5024ec84efbba102ab1b4c85383f34b61d48","addr":"23890ab09f410c91db179e68ea1d942d25bc0c34"},{"mnemonic":"nest wool midnight tragic exit enemy knock oil tenant survey opera sense","master":"7074c03dfebcb8ed77af28e9b01b77d803c6f2ac88b61a17ae902797c82cbab7","seed":"c4740919291e1af1c7986906a374b081f0386c40601e4f832cdd3f5c4a453a0dfafa1aaa02b00d98f49803a16baa8cb64bcb186c4cf045eb803d8ffab66fd54b","priv":"1f0dbcbe498866989dc0e0b55e6f4b83b93ed2191df2db3ccaddb3f789e434f9","pub":"0396454c50b1a4ce149ed251ebfc6ab07f0d4c42ae84a80c90ca1b64112bb3ca57","addr":"8198e949ce71c8a950f39a8a691f2ec180106997"},{"mnemonic":"brush sustain penalty chalk palace slab learn decide agent private pigeon then","master":"3acf99c19afbfe290a99911c085a656eec61af6f976623c9b6d2d1500e7033dd","seed":"38ed979eea68a00495e0e4c045cfdd1cbe5aabefe628538c35a6debec1be144d41745cecb2003dd870dd87c4246b64e6fa4662173078ad7a4fe471bbc14ab9e9","priv":"1424627b12902bbb162cef56ce5609ac356e68e3ada9005bd92541d0d8766559","pub":"036155ad03bacc613c9fbfb87294091a9bdb7845e58231f4d585603153871a8c3a","addr":"1792e857fca4355189ade1f45066dad9c986e7d6"},{"mnemonic":"autumn sudden learn laundry erode claim exchange jelly jaguar vault deal humble","master":"1a616c74e30a912dad799fe8d65d6ffa77245f89e81a367310fc02d08be13522","seed":"976e55f1fbcebbd1e448edbe90d68d407d80bd5ae197082bcd7ae8e7a640f3246e0057c65271e9e403297b3725a895f15c502284ab342ce1416f40c892bd73aa","priv":"701e7206d44ca9269e1bca00dca53d7287d55fc39214ed4c7e8f7201a68d6792","pub":"031a31e47cc6d75f0652de6698757b8fb2ed1ac181697158f0bd50ec6e7abdcf65","addr":"a73ac9e548e47d6f1f3ec200593a6693297a9143"},{"mnemonic":"priority dinner offer glimpse sudden light work absurd unknown process gas tooth","master":"d969ece198e95be043e46dd8ecb45cd2e5bcc09d8e6b00bfd7aeb59eabcb0ce2","seed":"aa9cc6daf79e31c5e3ed594dd896b1ca39161add5e5a7dba0159f4a8fe262c51d742e66a19f28cf01f32a90fafe5195b0b359e87f5a5a60e31d883ebca08d433","priv":"81d13a5954925641ace6c24f38c68954d782b094002a689500f015a401d5c6cd","pub":"029b1e4dfd01689451ea069e8a193de0b506d87faae6eabd9edf5dc49633c0a03e","addr":"bb2704f3f0270cab3a5fc918b58561bc1505f718"},{"mnemonic":"glide sadness text grunt burst balance ask hair include refuse mom advice","master":"5a105765bef30fb458b9cdc3d6758479f003f96bdfc1d0c21ea1e4987f768ccf","seed":"0131a60482c920093bf7b7375a70bea607a2015bd0bc9deb04e99d214a0c3a4966b21c3bac01544f816a8f4c3583920758e70f8991506cea52c9450c1972a9b7","priv":"41505f80b9b0941d93341815a72fb32dea916912e3dc1b7b7c763fdfb5c541f8","pub":"039df863578cf71fd48dccaed45c21d1cf176c924bd5ed8ec5fd8dc1bd6fcd1a46","addr":"396984e26d5b3a4cc3cf4a5a868ac88776541564"},{"mnemonic":"jealous subject gap april eagle goose double door dynamic robust impose ordinary","master":"ceef22480f535024fa3fc2a7cea96559f4fe8133e45301807d3213ff7e49e0d4","seed":"52d4a03cd2da0a541450a4530565a5901953d1f3ea0ee9440748c1796a5b8ec8ff674a8cf3ee2fda215a720f0fed119ccaa97619f6fe76b736b6ff804c2dc299","priv":"308bee98e778b1037cfd69c0691b6cce81b1935c776a8473a1b3a49bef313305","pub":"02ff9d7bab97fa367a753ded100c11ca4bee7173c04ddb242fd928502a58149587","addr":"7bc8cb221d4de586491bee3016d9129a42fe0527"},{"mnemonic":"panther camp coconut patch blanket census able melody bid sketch protect illness","master":"aa867cfcb578d828df3a6cc4ed1496f3af72f94635ea82574bedf2d88f9fb0ae","seed":"1bf0752a4872e6a4bdbf9f15dcda591184c8e1c61910d958642b376086cb9db6902d7ec0997afa3a0872ae3fa4fa7751605a4b3a3ccb3e4fb5a6afe26e2aafad","priv":"ce6de5f65b6a0cc1e9c4f7751230aec5f2b5401686e7e42b81f1d8eb55f77303","pub":"03f6c0da8154df0baeb15a7bccdd79252c38901ce2dc59e6e08d2d292bf6668a71","addr":"38a888c98b1f68797a879b64e5907b909f81c386"},{"mnemonic":"great history exit include clean have vague stick victory else iron trim","master":"6fce540ed685440130d194a3e8af78417f9b73df783721ccf184807b3973e384","seed":"2459cdc80eda19acec0c704f020082b617952f652b109c268035607139ba2710dcb8dfaf546257f09f5a1b19dce62e83f603f561d2cc2fefacdac6fc902d311d","priv":"26d08c2b95d15b5e1313aa62cc275b10544f0aad3c2ca677426551d5a039a551","pub":"02d165d97ddc4cb451d52895521d7c0cc217d1a004b9a760aa3eee40edcba4ca37","addr":"7bccaf7fc14e648667e8d7001f7b0777bef7813a"},{"mnemonic":"pause you skirt bundle opinion soap wall doctor head method tent lava","master":"b97cd03b20895737ec084f536ba06f459831e6bf2eab51fc4097ca943014f29f","seed":"b661487c12002df5c65a204ef12698be70837ec522fa1bf17d789d0d0cd0be443a819e4c6a494ad8d66a8ebe25ddd833d6ef7d9dd80e3e5e276ab94e0d572e5e","priv":"6860cbc7b6017128bff9c6d48abb20200aea06a7e8c9168d46f51260dd7125a9","pub":"03d7666fd2ac98121523262fa6695c719d3ea6fbf8abac8266b7c8550a498a55fc","addr":"6a2c9c329b85c35721b69d2885cb8ffa3006ef1c"},{"mnemonic":"senior liquid release beauty echo castle honey limb junk carry clarify high","master":"b3dd9a9379270f2bee11afa64bd9e49e4d9f44fd997c383d651fce6b54e8a82f","seed":"4caef4408f37ba86781693fb979534b9c9534972c7b866f74318930f180a2a36875960ceab41e8725ee4e25f56d160455f7d372a7d08282ddb5d7c1d24f14daf","priv":"6d9ad9c1011761fedce7f7947b5325622ffb1cd6283eeb22cf5cfa3cbf214e69","pub":"03f173aac293bdfd7a98b5055feef56e70d07d3e0549bf278bcc7fef559c0a413a","addr":"93ef2c58e7de60d861c0dc994add27a914477d20"},{"mnemonic":"scrub pupil rural fat taxi area example spring doctor ripple obscure asthma","master":"bf805260160dc14eb96077258ac64d1f67979f7702c99c411fa075a3813ad57d","seed":"ece2913f94e791b8c5c37dff29cd19f9725bbb0a1d84e7c3958eca1b646858de1b3188c8dfade823903a4b4fd12b892bf55e570ed68286741dd02aa4ccb08820","priv":"d158bf7adfec3d4d7f941fd9ffccc1c089075fea66fca2039dc4e2b2a7d1a000","pub":"02d5c76872253c3890a8e1276ec4df0c874fcd46d1f7b84462893776b6d14fe972","addr":"a98c98b13f7cfe6fea7de31de3fbd325648a9357"},{"mnemonic":"first shallow crawl asset vocal special rural bomb random pair shock live","master":"a0f6894a4375e267aae6dc2d23843375250b44bdccbc63d1436a2f172214f928","seed":"7518a5b622fa57389790c2484ad833c95e5cf2caa12f71ffb0fad4c9fe044854ff1f7e97b188545679ea936816217d2a26204a0bde6eb7335328dd0c86814bcb","priv":"027d54b7a844be318ea4442113e4cecd464455e239c0726236e2cbbd4c559fe3","pub":"03f5c6a2e2a82d331268c789527b5ae6d3f36e3fdcb344fdfd7e200d5243b075a3","addr":"bd4e60a76b171fde2684d4c7690e8feb7ad06854"},{"mnemonic":"famous vital monitor opera strike coffee shield throw emotion enlist east smart","master":"f1a0708b891c80724310e95b29183394390ec56c3a6828bb4ec394a39726c256","seed":"61f06f35b43abe9256e635720f4e74c8e3796ed4222c8d914c3ceb0f26e48d9ff772040475acfefda1a907f24c369190b48f50feb2fbebd3a84c0c9d3850ff14","priv":"8c2d6f4673846749f8d2e2f9902f28f66d33625d0ba04a11477335390f908552","pub":"03f8139b274b297d1d669fa505ab797a7caea82e76c5d7a3341c71133fe3dae164","addr":"bc940ec509f5275207ae9b086be155154aefa3ad"},{"mnemonic":"flat cushion trend region glove humor below edit ticket west multiply black","master":"2e72ddd445cd917369177b7060dfc92883b4b56e301dd6b0c7049517c102ac22","seed":"85ca476c295a5b708beeb6af45aad1eb6bb691fab82fae7c6d4dca48723f7819551d04395581ff769554ddb94e0d065f4c710afa7674f0c3480c1c2c4299591b","priv":"a57387ddae40887dbb0f99e8c84c092ac1fb8e245ddf3c9909e189ca2b70d52d","pub":"02d19eb0bd72884a3d753121d0d4489215a369aaab5ad3bbecf47f2246c5ebe928","addr":"84141ec76f71f2bb4dcfc9f81fb5333b9cd1ea8e"},{"mnemonic":"domain produce address tunnel burst emerge divorce health frog rare cook series","master":"983fc11c91dcbfcb3c1869da88972b03f7cc51f54db49533c012238ba89ea234","seed":"9d7cf4d9d3c664b8e51db516449d3dac01d290d774cafa90326e0464290faaa6ed6b780f792e80955ee5e6d7aa8ce0efdec13c20ea0fd88e5e40367f6df818a5","priv":"b96264f6b7f9d01e386ae43893c2a6b8683162394bbfc8048dedd4ce129e52cf","pub":"02ac9b86bcb1d8c6991572ce5044b58560ddfcc25a26dc4c74b12271c263e9f1e0","addr":"345821fe95bca3c777328a7148106d46afad6861"},{"mnemonic":"dutch oyster switch layer rapid fat prefer bamboo stereo staff spin midnight","master":"47d4c05e953b7636bdaa099a136986544444911d1fa720575872370f2aaec934","seed":"f120c319991b7564a6bf0086d918b39aef44877b361883f58db6f95551a66bfffd1f9708140c07135d40d624ab78bae8969883a2239b4cb6de5270aa5eef59d9","priv":"968356e312506427072e2e628a136e6e0104e3b9f74d8a00f384da0d62e58a30","pub":"03efbe8d47bd3c1c6ed07bbb357e6ade29f46d70d204f4af19e5ccba2dbec7c811","addr":"27bbceb99a49bc927eb0d6434b41c873ecdbe782"},{"mnemonic":"green claw tiny bring meadow tone improve advance federal talent drop fruit","master":"f0d9b5313bed52a853a177c338cdfa1080fca511d1a3157e3aafac06a6a753e7","seed":"8acbd6c36b27634ea9017b1ff25913a3b6aee3ba578272ea70d753dd1390ee31e9b0a7685c76aae5bd0e3cefb34fe6d077a7aa0a1da2fe3a2b4d8592907f7c9b","priv":"633d8cb5c8aac8d9e8f3e540ffae0f9a2fe54ec4b9f95c4378927be49f785bb5","pub":"03479063239cddb13d026158bb3519ecb95590d0be4abe036668f3bd134ce8b0b4","addr":"5a6321ea26d9fe346e9af87801f30f823cae4e5f"},{"mnemonic":"model famous make lawn wrist busy food envelope town menu hint dove","master":"034f244b9742152cc762f84ab5fcd03ea6020e30d766d209240f4a1a4bbf4859","seed":"79c41d550c0fa03c15114feb0492e362030a17a72d2e3d05064d459ff8a5ae877c2d94243615ea0f41bb82030e0401ea6a51eebef49c520cdf9bd923f9427e12","priv":"3dc937a202f6c5f20a3d57c657f16269b84f52a4701da93bb1786ea0711335b5","pub":"03e26c7ba82177671230c877902563ed09283148d9f83f400006e11c735620d94b","addr":"b4faab756175074173121e758b65bf2663b792c4"},{"mnemonic":"leisure buddy divert feature soda reward moon doctor fence neutral bomb truly","master":"9e8c30422c780174c05f3a5c333e116be6d54acdcfa666db96e0bc3587fa457a","seed":"728465a73b67017cff82a9e1d5b3cc77276f286e491e9621c21317485b78766fe8828fd0f03016ec67a9e9a42c355804c875874206b60d474c09e49e1eaec89c","priv":"90c91a0f640add78f765fa475ba8267e5e3533b0175d29150138b659397b0a47","pub":"02c0b78775eaf3515a49cf8ee65dd95e8fea30340601229dcdf2d2dcb3d39b3839","addr":"0c300d4bc57ff741c4c634a063c24823a18b1ac9"},{"mnemonic":"excite cargo radar baby paddle century average nature tackle blue rhythm garbage","master":"6a4cd79ab70b5555d3815424bbb8c232351a14511aaa3708dc4449ea80fa7330","seed":"7356daf4bbcbf682469878ee2a8e7a35d659d8f19095059e7b59fe14d9893c054559bc2beba994c527e8417f86c3f57a69b3f42954aa9a4647c91155fcbe2488","priv":"ae2aca6963de88ac0a4e709c4f84f5ebbc2d1a18f55be9c036e97fd46200ef48","pub":"0304f4343dc04ad6ea1c528296ac17c9d47a42cfb744e311f206bb154abab6ff59","addr":"ed8d1537a6fcf980fd7297ba56f1638935ae0fc9"},{"mnemonic":"must trophy era antique goddess local green rhythm gift van target island","master":"52e55a55dbb99a2b170c489c99d50811c47be205294704a2d6e7f234b2a938c6","seed":"9797425288539f83d965bea50c769e5a681c7fd6860502bc7d7d953a36fe16d8f0af0e6441a92b421cca44ff0fdc17d6118801dd17814308af5f6f1436a2e28c","priv":"8eacce7419f6f8b94e426adcae21818ce6525f0ba624bafdae44f0838d36676b","pub":"0244ae10f79e38d499c76996fd6ace738b1fc3dfa60042775f200315cb1e827855","addr":"15b8bec456e7346a6446c9679afb13a7e4e82079"},{"mnemonic":"day include route train grow number traffic across acoustic render save gadget","master":"553843ecb6e4e0383bea60a245b7f34c46d8d505806f4d900c7344b2dd4e1787","seed":"abdb30b82471a0c81df74e7d8f9fc2315b7ed04580689d5ad91f8947cffa9375ef2b6c315b695e642f43d08edcda3712afcd48e86583b00bdf5085d2920ddfcb","priv":"ea826d758734cf1965b67fe0133a2b78aecf582aef9efa46c96c61cb512ba593","pub":"0304501989badca08ee05c3984c8e299e5ecfc91feea52daf24cca7f236684ca81","addr":"9bd24b970d41b73640a86beb27f3533d2bf35c82"},{"mnemonic":"safe favorite ticket bus picture tomato unaware lucky spy creek upgrade duty","master":"8be9a1fc81f80c427683964bc29c2eeb135a3ddda8bad041399e63053cc37fac","seed":"3b7f10be92522ba2544356227f415046ba8b2faae9c3dbef1563aee039d00afe8b476743cce4495c264ed01fc095fdd09e3c2159b9b91ae01f49e5610f3dc375","priv":"114c0269408ee0ad873b847793743f06dee7be10da15d0db533fa682a644a017","pub":"03876eec35fcf39732629c5b3ea22c2309a28549335b9f221001ceb0097ee8565d","addr":"fc82a1a044603663dc758d6987b8b699d56af1fc"},{"mnemonic":"slam jar adult liberty small adjust right sheriff cover below space fiction","master":"75e789f7c7da1a83a34d2a2a9b54d4af6403292156cc775be81ade0edec4d566","seed":"ce1684c7045cbd4ee4c6c23d52ad78dca82e426256dcdb3a5f5fd9c635e0dafff12612e981dbe983e1ec5d88d6bc3294b84f8705cfb553923e397da5044b896a","priv":"bae08dd84c10433159fb11a08f8e3df9fdc503e5cd543a4e9231e96468094a4a","pub":"02269218f35c468c3fead430880577410b580b9dd979d68c94f6531adba7dab809","addr":"5e44c323c10036262a3b02974a6d69f953d0e359"},{"mnemonic":"real acid movie gadget duty hole apple inner essence confirm laptop duty","master":"132081c3acbf9bcedb0a237fbd41c882232976e1bf5467c067892a80f5d30691","seed":"495b41f5b0f22b227458857db55d2787c126b832dfae01384ad0213eb28d79baaadd13a365e63cc7c250504c5f9a2fc5bf38e174769c33ddb629a012219a38e2","priv":"44b3ef5a4c7005846196bd9b7987308ba1bb7923687749509cfb733b3aebc95a","pub":"022803c31147ee31f5fbcfbdb2313c5ef39b80b505cc21275cc01e0527dc6ed6de","addr":"063cf369f1f4122821f7ba400ba1e8248535fd44"},{"mnemonic":"banner indicate tell thing elbow mechanic express stairs robust rival shadow matrix","master":"6e76cc6fe8099d9232c107ffb8959c3c6a24badc35579975ffdc29316ecb2b5e","seed":"f1224c30cb0141c0da3f5cb31632ef8cbd88896e5ce98a5290ab708f5c0c084043fb19a4e360c17e161a3e6122e8fb9d3991c9ed7129dd5ee26bbb2388e9b7f0","priv":"215dad8e633e3ebbacdca2ba68a9747ec69de4d5bf794748500768272445d516","pub":"0259f48c2e291b1d0b29890c10ca516ae8e186d06bec8dd2d966d0b336b9a68a8c","addr":"7863b183b3f98f4ed5ca402c3f1bce45a9d58aee"},{"mnemonic":"boat minute dutch sadness globe congress color sort feature boost regret gallery","master":"6be1882f4d3812eb5cc92b5ec4ae762b565596a01b1c4216f16337663d33f85f","seed":"dbcdc6e305e0330f5fcaf159763664a8decb12dc27003831213b93c241d886ce26175c726b6f899e8de4f2b15aea6af2be816eda613f00a3f8bb3ef3c162027f","priv":"e30847af4ca7d0bf9f76d2c15906c955de0d89ce994abf7696ebbe0880171675","pub":"02a6f99d68bb927000aa3cb6847e349fc7f0412a75869cecbbcbf223707b7fe8c7","addr":"eaa5c8da5482c10d473be2c62206eb82312f3ac6"},{"mnemonic":"icon echo become average ramp undo actress sea water struggle interest trash","master":"d07e7e040dc9b1ce70fa78ff50d10345880fcabac783c380ed43885532d79ab5","seed":"9498c9409da005532ea8fa71aa658c9b160c6630498514e52aec48589ab60207f2770e4cf0f47a04a2d46a878b3b2a2f0f58c478d708ec9dc8f54b51ed1f0506","priv":"33a881e07441283721c695c58caadeb68e5576a526ae465ef48812b98d66bd9a","pub":"03226330049e98e5513799ded19923809dbed40226e958f9c36218e8eeb5cf47dd","addr":"b02c8d95cbc1417b891ba5d5c912a6e3b8cb6748"},{"mnemonic":"scan book mean egg situate dash chair water surge major sugar shield","master":"a50dba88cae4daa6db49e8cdbe710a305429ed2e4ff43c0b87cb0b88956f8f02","seed":"ca8bf187bbde692601b88a74c124c967cdd17810a5b4db55254a22278add4880b8360a66b5d91c0ce1c105f78873994361d2169a3d39bac0807a6ab7cb6b894b","priv":"4ecb295b77c3b1296fc214e554e77fb47df10cbfb22b980ba6e9436a2d884ab5","pub":"02c302c47bb2ead02062861ddb4c876b797607ed2a775317c7ad258c97139767bd","addr":"6f6f55426f790072f9752fd182a68710c2b3e72f"},{"mnemonic":"hint sign broom plate brown beauty figure song stumble setup polar road","master":"e4721371d82355bc7be6836a7915a19917d2efb313eab36abca855fc00f4cc7a","seed":"7f654f0582ce0c83d46e01477fafaecdaa7321d095ba1468ecd9fd6c04c67471a2e32187c02178522d11d9b9160de10c6cfd74eef79d6c50d013044a5e6562ed","priv":"612986c34ddfc5e93d93337f68645bcfaa2bdd37c8a6beeb7d58cab6e54ce3b7","pub":"0309c0b133a0af4f468285b0399a3c3cdaaf8c2b29ef61a4f8ef19d526b23eae6e","addr":"dbd39ec36261d32e313a82b4745c47489de5e955"},{"mnemonic":"eager item digital loop loud drill script ethics crystal tornado pride cattle","master":"1ed90fe65b73b2b50464a59268cc2a7a9bac67f2fb167c5b4714dfcb354a24ba","seed":"2e5bce8308d9ee56a168da570cfbe30f0dfa341df84cbd7674f198b4e419d48c65e1ec2b8600a2e7608bd148291c54ba29e5e7ed0a39d4418eb212ac6d7811bd","priv":"ab27d9960f7821dce58d2271652b42f8ddab5edbc87a23ce3177a0454b775167","pub":"02e1ed58d8c50877a6133c16e793fb6608515accbeb46ba07cbd3972c274534066","addr":"54b513aaef1aba872f8f521bd3b86c885563cde9"},{"mnemonic":"asset toilet hazard chief boy over trap session abandon jump wheat group","master":"43ca7686bc87728e62a5406222efe3ff40d4364a7904f7307437d1b2b13ced43","seed":"e04b7a46a47cf1c4a9382aacf36a32da16724eb1ba82f65a3c66679d793d410d3952fd7bb0c735bf96a089521acf7ec4e1f41b179b09dd75645b7bdeeb539292","priv":"e7295badc4984f21bc64f9ba723a92799ebb18acd8315686b5040feb603f03e4","pub":"02cda17b0a54b09d9389a06259a44004a569a7d862a9397d33f9fb598fe374bccd","addr":"f69a0e9ead6daf22623a1235062510360f0dc7fe"},{"mnemonic":"flat eagle owner ladder enlist chair next good solar drum service escape","master":"2de24f772282ea286aa716777f39a9233b38a5a8018dcd730b74bca33c5bcbdf","seed":"d571b7aca82b969fff273b5d4e876188c5b1124684d3ab8056f69bd521b1d030b617d201313ee42068f48dac836443ed6e8725ae2369a955133cf74682e6090a","priv":"232c2f9a62655637fc64e4173855506ddb4d3530807f4dd441a137981d636c11","pub":"025996bfa0d3593c05503476f4c340ff2bc32290affa52a130f2038b72deba930a","addr":"ea8a8d16976a6d922be30695d49a670027cc065b"},{"mnemonic":"hamster such legal analyst despair robot tumble embody coin taxi liquid cart","master":"f78ba19a1149f8dd5ff019f40fe5efaf8e0c5f9df5ef2a1b32df2b9a0cdaed8e","seed":"9d863569bb0a87d17b02c10eef8aa06edbd9ed37ecff427001f2e43cd4f101def938da306ecac02bc5ee83b886857e43f6248eca72e65e67828f243c625de0bc","priv":"5a2a5c105c9393cbec8cbdd79022c23407c556a503ede10645d744f20ec9ebce","pub":"03a14ba5b2261911010d2b2a7602b37dee944891b1e49d075b6729e62627a252b8","addr":"73ff0ff918c11d261453041ee18b38194d3aa57d"},{"mnemonic":"gun monitor turkey humble private essence limit member bike person cook ahead","master":"c3d138412cb4861effe93888a20e5072f887b2b3d3feac310fc8f40bb523f98b","seed":"6c79ddee8365c1c293e6424cd0c4ad5fa00256e9f8377e5692c3c60c1550cd4e00d3f08aa61441609b3954c271404888677aa4f7e075d7e93ada2f452984133a","priv":"865fdc61a6559f4ef787eb57210c09bcfd82ba9aa87a13a09e62746470eff4b1","pub":"03777c19e60200e1fd48d07f17c58c29bf6440aecefe503421bb13cd347bcd3e6c","addr":"a77712c1f028f11782d2805950c79e11d2229002"},{"mnemonic":"bargain doll comic scan fancy soap fragile benefit private sword share milk","master":"b26f239a994fc404b1aeb31ffd7f0bbcb625c881585dc57247cea88ed890b042","seed":"928a043d2007258b4cea3a478dd6b1cb133ca290142366af0ac60086f880cdec35541f080c8cc1d8d76cae811b5138d9de189557b37dc6726ac1df11ccc9ef92","priv":"ad650db8c2457981a143a3cf400ef1eadb5790368965a5fb8f28e8e0dae1991c","pub":"027ce8003309913c6f99fc6a5eb2020400118e3e253f618a418816e772b5008a75","addr":"67996609609bda5dfb179da0fe5e6c7614ffa922"},{"mnemonic":"father accident gaze obvious visa deal plug narrow shrimp motor pigeon sheriff","master":"643240ce9abd6d36e330c0cf47343823c3a3d4b533f6887aaac16d737c8a1a4a","seed":"9ebd83a564ca724a559e57e896940ac08d28a71613e9b414170539b29a5187a2ee91e3fd4bf258256e26ec5c41af2a57fd8dfd30f054403599cf9b4f45af5839","priv":"adc7eba12216571143e05626980ef0644521269bbe8870545b7cab11838537a8","pub":"023b065c65ef208f46ff43bd1051b494f60b1a395543952e14a3d53a6d1f347e96","addr":"7a7b0429f9706215b02ec49c205ec4710705a68f"},{"mnemonic":"reflect slab donkey village mushroom style brown pen mother pipe raccoon mass","master":"bfc2912b21b64143fa0c5a924573da251a9ca151aafc79a9038b96e21551dee4","seed":"fc21dffbf43c67a07c5333e57d238f07d0e1b987bf4f0ec763f1abce471a2e0fb27e733d5098fbeb81ed9cb2d4093ebc9c565b196c9900f39faf4da5448a2b15","priv":"d34fe09f482ae273ca07b2623d5b13180db5d14693025b57aadd6c7c51e640ce","pub":"0329edd6f8ab6a57ade9179889b4f54306a45f89b0007cf9843755b3aaab725586","addr":"c69fbd3b6e36a75ac8583713c1e3207253ec53de"},{"mnemonic":"lunch process rice hazard word vault surprise useful fiber trouble pride mean","master":"12caee441e7ec1c4109c53e42c8cad66704ca395108237f68953b137072d1aeb","seed":"19033ccf459d27009a9072905bae12152c877115e145eb5469f20ac8d763570d2d0ef57cfa6a482da6a1f2c38e7dd43fb6260a4826b54c0f03f0501df94e4132","priv":"4a2616ff7d529e66e3fb200e7531b4a08911a338e6a80c80182a0b98803eb14f","pub":"03e996278cd3c0374adb59287c00a526fa8a409a53a2606fb230748cedbed12f14","addr":"0f96e89ff4109143a838165bfaa158dd64603fa8"},{"mnemonic":"boring unaware cram sun mistake rule view rubber gravity humble detect zone","master":"23b29bcf96e849e44c0e8848e86596eb41908018dccdb91b9fd81b35cfe24523","seed":"25d1e2d98bbe47da86d732e8975f5c2ecdf2e107b641c6e9a259a49014dc35dcbb83ded97117bde45b0e78379ab0b7785aa8e45e2a628442be1ccc9a98e78a5c","priv":"d2c91726674b440f3aa7f105c17848c1e63d123bdc6ddaf88ecf0e6db40b7d1e","pub":"0367113b62388057da87fe1c781210074e0200b872a7243e05a8c9f39ced994acd","addr":"264fa5eeac6f6b37e249f8ba03168cd17aa7e258"},{"mnemonic":"extra hobby pond foil below injury light brief struggle gun visual recall","master":"80cfd73c33f507495340ad9370aa922b436b84d3f584d7f65cf6173b367331c2","seed":"d965ec811bf471bbdeb7aeb4c0fc43d710cb47fa63806f29661bc1aef4873455c6a97f85e675f6da0e975ffabb1356d310daaad51da951de68927933937e85be","priv":"67654951ada1ef3a6e15b3941d0eebbd1bcecb831bb084dac0d70d610ecac13b","pub":"02a1ad9bcf4e359f15d3a447b61b9f18bf2dfd56c52c20f267ae13b04bd60b0d25","addr":"13fe548ac9d9ecfd28e5c5b5d0b865b89b36e8a3"},{"mnemonic":"copy thank warfare visa else rally shuffle gauge method favorite dirt mushroom","master":"f76da13cf3b11641e547c33aed72ab423b7dbfed236da81ff3759d4ba3ba3aa0","seed":"24e7ebdd3792e56171fc46aa5112514874b67fce474a0ea4399b6cab23ead2dd6bc5201826f9127bae7419504de04342357c90a34884015edf094e52a7080d0b","priv":"0bd271e0b2adf4aa3f1b0ea862eb4efe72958d40ef2153e784ede4ffed2d4b51","pub":"03b42c815258c481e1e994ce430135aca9e8546585e82927066067a7f3eacf0223","addr":"95ee4a4c887ab69a23000fa3bb062d1bdd96371d"},{"mnemonic":"rude wolf aim frozen bargain false remember circle axis arrive virus echo","master":"98d35496c8e4f142a6be9c704611257b0520a14b328203fcc0b6b9419a71e366","seed":"ca47d7e6f88717ebac85734beded4a18c6a46e6775cb64b7ea5aa167559f90bb5d8eb9254599df6e09999d8dddc1e487c657c95eab703f756199ddc3196a5962","priv":"9dbde9c5f35f2fdd7bb33208c733021a8ed055af962137c23e06e252cb999456","pub":"02ed94e8e6ff816a2b053b959b261e7d8f8809f58bae0cfb84459d885da88355f3","addr":"38a0dc2d9bdffd96930010699ba2f39fd244c3d7"},{"mnemonic":"deputy among shuffle online fence mouse clutch joy away bean hybrid void","master":"e13cc05ed1c7f3415610c4011f994446c9c9c65df5e1568af347d42b31e36d30","seed":"f3b73f8483fd0cf17bba1032397207d4b593f54140391a91df47c5b8960fe5918b0160a18a1a2da8f3acc6585fccc19911c613424c91b47afab4eef5f06bb569","priv":"d323538934f97f44d23c78be6a5f6005a882126475ba4a7c953b19bec7678142","pub":"02e6c50799013ab284a676715c3c575be75806a5676281144cafd4c17481ea053c","addr":"788f0092868345453e40b0f38d44f4ff4af0f2a8"},{"mnemonic":"panda rule subway ceiling awake decorate forum cluster place club surge lunch","master":"f0aa8e87884a3e3462bd3a230081a29739fc62fafca9aadd9353986d27de4509","seed":"7ad436a119093e3862065629b195087e0162f2060d6e2a1e653be2e894cc9c3c4ddc2bae40f447ef87c0f3b2232420fd938c155938b4ff5fedb3fc7bd26e9eb6","priv":"9db3eddb02be190b266cd3bc93f5e45d126577bfdfb1df60ea9f2f3bc21cd2ce","pub":"03c4e1511881edd8d598fa65bfb4f9dfd93dc1f2f4944c790c2abc650492ce0a20","addr":"c61ee0480e8379e854a631caec02572b91c2b23a"},{"mnemonic":"addict foster exclude debris moral uphold couple surge reopen blind trash real","master":"9c7714714335b5d3bc2057f206da041c5b0e74213413c2cb9c98f521d2890209","seed":"4905780290404b998ba3ea764cf22ff5ee689aa9d783a7f6ccf57c9d2b4b27e4312941a2e4328232b6e0d2e7729cf30978b094dfa6ea369b34b6da35ee2ef73a","priv":"4e5be9010cf1a4ec010712d82bb0d18d5b1b1cd3095a56cced0ce00f430e81e1","pub":"02a18e4eb8623e1f0fc37434d1e18531ebf5e2dc9bf93af3f831cc72389cb3ed83","addr":"7acf8d7f9f6fe56e21ad77cc6e41b3b49bb542dc"},{"mnemonic":"bracket dragon until token cotton giant enter lyrics apart supreme pupil fashion","master":"dc8282dcc0f6d147d01f8ac326a3017380d56e242fe415fd17c0b6ea92dfca0a","seed":"b1a0043eff67b480d9b3b2c0b6676dc17da38225428cec06ca7884060b830ae243d50b659cba06166b6e8eae8d9c9d67a38554f5feee3315e90859b544833dc6","priv":"7c19323897d7640d225bbcab428731abe01c7b6160557476fc0bf97799f6cbc7","pub":"03f1a65a290bf4a7ad8585680304d187f5aeb3e51d44c9941443450270c457edb7","addr":"72caa875e043f9f2d3712a87317cf12c34980ace"},{"mnemonic":"catch unfair toy shadow hobby tuition remain leaf put blanket fall diagram","master":"611504571157c7451ce639658fb04945cbcfde1b2e487f9cb97ad430ad3c3801","seed":"b1b9002dcfec6d7bf1d7068a45615abb4aa076ad65e34f15d3f4006ec82384c3bb7d737fe7680e58089281ce9305ffc178bd1a23e95087c2fed495a20316ddcc","priv":"3fabb4604bf9163d245a293a4b50a4f844277afb9b260100ecf406fdb24a6d9c","pub":"032568275e2158b5b88f191d77cfc23742157a4c03863da61ccba04a29d6a5fc43","addr":"061151483994a2a2f420b081148754d5807cfe96"},{"mnemonic":"divert spot love tragic vast error crucial print snow filter fantasy forward","master":"817b4fb465a25b5dd9921ff72634202f30b98ac3040cd5006ca5e18fa851f4f6","seed":"824e5275f61c11ca6db812ffadec349e61afa0313d4d299c911eaba5ddd38ccbfa39a42d323f43aa4999bf95b997958a6ed0522930bff6968dc9cca2adaaa204","priv":"43919dba40cfbbdc53b2f8c097b6c66a6a391c28d9478fcfe23f29daa4f80194","pub":"02c32a7eec00f33e70c83aa4281d312bfba257bbe920f349dd3b674decf43e3aab","addr":"fb3e6b782cd14938a296f8986daefcb9c1424232"},{"mnemonic":"marble start nest primary author steel video science wire sister tonight invite","master":"8d62341b89e0c045322c270870d8c438ab41ca077b96681b9288ce2b04160b8f","seed":"ff79b45850f134169e1d12bc2c95c5f48933815e3062296a93644c8e88ec70f2faac59c5e0e20b1fe8799989509190442356a67596657156dd7b1eaaeb976adc","priv":"75adc55e735bce443ba38fa066c269d20c986d18d31b9c67a6f41215dc6205e2","pub":"0262ad481271c2b42b162d09eb549bf2e09ff953d78cc3b58f9633f0a2f0a1cb32","addr":"289c5796cb64589fc90d10c269093d9525249ae4"},{"mnemonic":"mesh rose keen want voyage net brave bargain session creek shoulder glimpse","master":"d3230ab8890910c45a3bf9d9d21b8c24a6a1aca2b87467b42c75cdb9204e1f2f","seed":"d61ef67df124c9b43132bf496bb3b18220a28c7c540247a11e25c2dff3ab8b7d0dabbfcd8125f03496a8fc4f888d6b8f8df9828ca406a3864881029e95578c2b","priv":"92d844eea97086fb63381e19e56e3b494af47e7cad3257a5ef1b46e21c4cc4ed","pub":"03be77c3a96734aed00ac4a0a18151670a213a911f3a9d78cf6f4e1fc33b7d0aca","addr":"e3a1325741de4de93501261a3850b374423ec97f"},{"mnemonic":"host increase panel pact gorilla alter cause cook voice ugly crop that","master":"22daa7841a31b77e2d006277ba1afd48ad7f066b4cc2b778926b4d4b8931271a","seed":"c1b9b9f1d4097d76288576869071b7efedc756fbc81bc62965c462fb0ac49ede2fba8110e4afaee3d9e187933fc28783aecfc9ceeaf87f63e75f4bc1eefc1860","priv":"2aedb3ffca9d76ee5070f107bf5c0dcb583bef571b1f498baa8708495f8f466c","pub":"027c929945ff29b6a5df3d4ad096849a270ae3052aa1dc74b7a14d4288421e47fc","addr":"97944948d7d679a5c9658168f6b1ea9772c49ce5"},{"mnemonic":"shy garage devote private degree cradle special fee plastic lonely legal agree","master":"b2150fb985a296a6548cd57d30f25bdb2a51c7163e96207353ad064ed0eba53d","seed":"474ce9dae1748e7f1c4096dc603c17696ec21f329b508083ead0651fe00dbd404a1703a7a90f0bd2f66553af28224c6abb93563527a6413732ec636f234b472d","priv":"2c079aefe8f9d45940fa7ca547243a229ac8aead5570a310ff0ea50e9579416b","pub":"03368684efade7cbe5d1017c8cb099718ee9b7ef52e7ec384d507117d1716faf3a","addr":"e0a6539483dfd061a878096e5cd0efd475b9318e"},{"mnemonic":"marine local subway mixed width zone palm lake sort radar matrix pumpkin","master":"5b1142363291deddd7fda0bd7775c7f2b1bdab5959d17d87830d96c3d07c15f6","seed":"c49978eee2d39326d8950c89a69ce6cfd4d51dd84973bdadb5dc517bb60185bb4354b3c5fca5dd0d10a9d8793c205304d1569af0b739bb796cc3f604edfd8959","priv":"84f09a48e36698ca0fa65597368284089059688c2cca84c72a22510f37989c85","pub":"0262798b5fba21efde82c22dd36df8261745c8f7046704e239996c634302efe8ff","addr":"6d81cb6953042af66fc1fa7755f48f3c3b529495"},{"mnemonic":"morning vast nut patrol owner body between neither earth always trouble mechanic","master":"abe0226f5383b2e40ac23a3cb7b486521f7b7af6b1108f24941fcdeef71edd81","seed":"14189de5d7d30504ea20b94fcdfa6054f70ff63f4378cb3a6715126216b571075879cd9fa1c1694ee16c656d8f8a2020adeef01f56dc814cf341aca1ee9e8e33","priv":"8da48fadffb800299535e930330f1c2f9dfeb45772c58764451079696ab3275f","pub":"0283e5b3d662399b88cac949cd41d65e33dac46101c6be4ab6718d7b7d4c1c2df8","addr":"bece5507c72c79ddee993158241c20ffeb20596d"},{"mnemonic":"weasel emerge sight shell cook develop entry truth era radar panther prepare","master":"2233dae87c1e1a6a98e1df4a573f6139dcfe49db3f2fc663b44503ee267b0c95","seed":"787e8fd15da3e7723f91521e3fe4b501b070ff5bbfbcd2b4af147a6067d751d5d1d992716519ad71b59a41ce329eb282a94cbd15bdef52567c8279c327651bf2","priv":"ef6ec780a7823965a871595f4f0c2e2e7ab07409f39ed825b1efafea19f39440","pub":"03a545388da649a8800ff9fff4bb33f70d94000e4b1a767ceec92f5c3f7b880783","addr":"57222240ca41ace976ea1ac308bb027ea4c64d36"},{"mnemonic":"switch sea bomb symbol foster flag grain bicycle case crystal august crazy","master":"32694a657bac54bb8b77e7d0d84014e41adafde6023723aa5779645c7c798d65","seed":"2719e5e2d4ea727d045817bb8cff56c62360b3c1c66522ee74d1b3e5c8d6ebd98700887d532f9d1f17a64bf683622b44df8dca30ac1bae5e296422cbb7741790","priv":"47b1b2ec336e0257687c8837c9aefdca2f45394bace57de882d7eba6c61da49b","pub":"034ad373c9e20284f233959b09432c82b0e7b430eb625c9edd1d5371a7038baba4","addr":"0900f4003360d4641626e75f3fedd19874b11671"},{"mnemonic":"asthma make clump clap tongue away used shift fiction siege tooth purchase","master":"0f28a391e22257fcc97aa8c229209ad0734e9d0ec8ecd67a203582f2c0ce7289","seed":"006b61f87ea0d6f9f87b0410ebb5bb54c9b8af72d3dc6283152b6e66a299b8ae0650ae528dea7b6fe5c6cf1652bd1b2c67b7e1c9ba5ccdd4111589216bdd02d7","priv":"6ad416539a8a969ee72e48e1b20e9502b90078dce0b5a4245d7cf12d4857eb5d","pub":"0274de9f743f31744d6e7ecf30c74ef56201c71b2ab56d03eb849f2adec2e3dbfd","addr":"67e73523c5eab9e70230fb7a806793419d28df99"},{"mnemonic":"nephew kick predict rotate maximum giant fit love float kitten embark another","master":"dd3cc8f83542c0fab49c660198ab42f48681db60661015e15fe4da87840b371a","seed":"5795b7fa476bc8f7b07738d313716d991a7bc2fb303fcd7012dc54e411bf7111d9c9159c9b28d74d5614b1f3a738bcdd63666b6b14b896311df18609521695ef","priv":"d84c0f29a4b95296e349bdc8bc9283367f5f68155fe92192a74f8a08e3c6e38f","pub":"02bc5af041b0710cedf1cb8895da55349d68ef4677670e89ce5da29f43bb063027","addr":"ad020570cc250019ba70e84f13a0b0c388443c08"},{"mnemonic":"filter vendor slice outside win urge welcome behave valley merge gun talent","master":"e20ace834dc8b88a259a3c6f983a8065ec612205e25da42103e40e968d1bbf98","seed":"1cedd43d959db14714c7e6f2f2caac10f548115f54bf7fb10ff4f178bb410530d8ade24d2dd770f92ccb459ba2dcf433d064c9c24f0d59137a2f808421e189d6","priv":"ca111d268b05839d504787ab4173f2d53cc459ea69c4965bc267db40b3499f18","pub":"0316b77b50cc08af7251303e190a4a12a96ce586631188d5f2ead491825db0b27f","addr":"c691a61bf6a5626bfa6b11f79a36c89e5f7efdf9"},{"mnemonic":"salt vote cook live accident leave define home section loop fiction sport","master":"30f08d7392ec4b37ec8fe00847aaaecc975ad1c98d64625b6e83525fd363b89d","seed":"85abff82357508cc583ff2c4cdfda7867467cc6889fb46caba56624f8c14e6141231c6b26ddd373b9e3504d90ce8b01da123ee72ae5a4db46aebf4ac7b8dda44","priv":"297a3c7969c15e6a3b4325ec6b4c768128aeb99e81dd4aa3cdbbd488e124b73f","pub":"02191258d0ce26b1e6adb0b84d19317fba6818f06993a46df1829a61a682a93185","addr":"a1082e1177f32b0b369429050324ae1c06461e44"},{"mnemonic":"model today toward awful apple actress hard reject discover type must member","master":"58168653609c2e12f079d799a7a344292edb46cfb7cf69a85f8a608acc6e47b0","seed":"bf3a70e5a322c0fad6db542bd4ffee2ed3ff85073e6d3ae01ddb7cf30773250c294529d69dc31f86ef390f30907c6da925cac78d10091d9df0fc97a6e48d9860","priv":"0a7c2b48dd3ec606816404246a0e28c36790c3b2f398531ddb7f1b7aa7e7d624","pub":"03f12f02b0cd5d3146eb28fe6a57eafcb542ac30833b7153e1a9121c3817d0854a","addr":"06eaa20c1fb4487be17eed4bcc57d49f1eeba446"},{"mnemonic":"popular among unable purchase matter athlete fever acquire mom install glance where","master":"fedb71f6c870bf049aa1355f4858675ca0c9a6268be575844d2313365df45382","seed":"be3448251aef8d22e97fa58862ff534bbe7a854eb0f1d574ebb49c4197328783c9f7a1b51202e5a37bf5b2410e3b6e11322977898c75241ed4806d1972102457","priv":"3f27d257bf6a625ea3dd1cc4ca9787c29027c105bda25d3fb44df992baa4ea45","pub":"026abcb82486454ef9ef70f5991f76cb263684624b040f9c7b1265569e65087036","addr":"197ff1aedd06d9015acb4712a4a3ed76b420be68"},{"mnemonic":"kiwi rail hen destroy path mistake protect carpet occur jewel pizza lazy","master":"7690775869756887b1866a93233ce2188202d12a4f0e01501e381b8aa120fd2b","seed":"82e3b78430fbad5184c4c7bcb1873d922de0758894d770edcc7a487ad5c10dd381345aee23f7d996dc8fbd44ed171b3e6e9b6dc19ba5c093925991aff3b303be","priv":"b0af5290094803ecbd0076266db8a65837d363be36738f267df6a5c37ea87b26","pub":"03a4b20c1179246419b5b5cd861ed440f3856b616c4bd5a04e0f9d45de91e25daf","addr":"ba2734783c80b277d6196850cfdbb7f1d599fd3e"},{"mnemonic":"cannon hill absorb ozone play derive duty quick unknown divorce history march","master":"668302ce757bac9a084220ac55e22027595a5bbf777dd344351fcfe668e58ff8","seed":"9282bc012e007bb31f889b9b284ed8dd02bcfe5b14528ffa0e128fe0b3d2bc27d3ce5240d14d581b5a530f66ba3c7146d891595a215b8faca2a0093287155171","priv":"82f9994e259551b52e63de92d93f21222b01c9f371c8cb0e9af15a6ac93b3fa9","pub":"030c0ca2aa6353264f3683210199ee7ebc1c051dc657a47f8ed9e95d50ecca2840","addr":"285debf5e963ce3fbd66a5fbb0841cb8d0a67745"},{"mnemonic":"wild saddle spring meadow spray lobster enroll album coconut chat marble follow","master":"14f5a8838df5b6546b7179704bcd40d5a168393bf9a65d0d5b80658e750b9cc4","seed":"565ab133d78d7fe7e8763fd73fd89ce7a5eeabe6841e5cdebb9a86f867c63f1ac7f3e1ea44029409bd48befc187f762480c3555d62fe9ab653ec2f8523b55516","priv":"229e28ae8746b90e772aa80afbe866cc08b0f49e40d4b1a512be21ea728ee0a5","pub":"026f08a2daea40b6a076b79c26de11bb1a5f74b9d127e79e1310d5a40675d5da0c","addr":"b262603b81f2f0ea718ee4fbcc9c807cb0317e70"},{"mnemonic":"firm mystery spoon brown rely mutual isolate degree stay brick brown abstract","master":"ffae4ec244b67e40036dceb4241614869beecad4e84fe6e41645159d3d5edb23","seed":"4e88efeeda99c5136e145dc0fc827d1a8edc96839311ae7c13e80443b4f8e7a907040d9a38be8d789200314110a91404119e33797e4ff5fdc790404322a7479f","priv":"be1343cf39f3758c560e38fb2b949c86225aa5a32af5328af3f476c94186e1c1","pub":"0379e9a16c9624525c15070ee3730fa02a9b8dac0d1847263789ce4df4ad22b533","addr":"2defd48b2cf9556c1bf6fde9307b17bad70018ab"},{"mnemonic":"shell open sing action exact cream scatter slim right sausage victory case","master":"d0bd4329ae716aebd1dbc4b75a06a4e6103540eb1185de24e180af67174cfc61","seed":"e55f447b58f363276a8f67672f8a4cd6a3bb014b5cda555f8d94e701dc775c4092e313e1aa102f36c98edc9f1c76d863afcec6dada643667f8dc612c43cba71a","priv":"31818b15c3b42238821b8a127a33e90100c6599d6c2ea10797f111b5a741860d","pub":"03c749cbf61f0e5b3cf815c454804486f64dc15e73c53b8957f4a1b0c1b3f36942","addr":"586fd2221b5f4dd31469ce689ba34160ecb002e1"},{"mnemonic":"mistake eye absorb midnight box nose bronze joy body trim give purchase","master":"8a97dbdb939254072731791791f1cb5f86bd61bee1b1a7b1c0220362b73f9048","seed":"ff955704f42fc8451d66092b720eee4153c1edfad5ac3b96bc87d0e1ff27a1655eb4c1127aba45906799197e1a92dfbb040304cc5acbb228f20c828d0f28689a","priv":"81b5ed5d49563e225a164180c53a55ee86432ee9e59ff5c6b1ba2dfdee8ecc87","pub":"0214a81bb7326df6f884b465b655f497c20bc68d2ac499d931945a56a20b21bab3","addr":"e4d30cd4f5b383401bdd02a01bdf1e7003ff9e7b"},{"mnemonic":"stadium blouse more trend reopen sick test trash glass bounce brain total","master":"a47cb7d914af1a75ca7ff6bc0192725a7b4b4daf386a039e9aefd8679f8a9f66","seed":"2a9aaff54cc77a16b4ab472b006768beb7403cbd11cc78aea80e19765ba685abadc03dc27c6444960bcffca5e206dc28f5564fdd05292f68ed825bb06ed6fe5a","priv":"7125901a72c60386b41bb65e8bb4aff64334ba8f2e032d2c032869b3b3a648a8","pub":"03a74cd7b3d21dd8698c7cfa4c30d81a454a55ce294171f30aa70f564f4ed71751","addr":"4a8f9540cb406aa75b0d68c2eb40869a8c25da92"},{"mnemonic":"fetch use target promote later more increase logic oxygen provide original high","master":"f06c1e5b33b4d18d65ca7e0b7627c23ae19da34a6aa55ccc8509fbe9fa25de3d","seed":"8ca3dcf901cddd77ad4f6db2a2e3a48fc1a00a81b372fde0dc926c4006c8cf81862013008d9e119d811512b9f98a84c7c655b071d28c295a5dd565491b961d45","priv":"44bff7bd7e57b709b5adfc54ec47d084d80ab9549479f4707a27e06a06083f2b","pub":"028d649230f94064c7837760706a615e7a714cae79a7b2363d493f9d4300b9a2e2","addr":"23b883cc57bdf88831c021ad62b2ae475e09d365"},{"mnemonic":"boat cause tooth danger box anxiety luggage panther engage human army language","master":"2c0c2474241d615780d2a1f34c4cda2a98e138c7bdfd13c97b341ddb8f5e87e6","seed":"98246a445ad873a5e8ac532ad64643c7e4d0ecabe60c7683996d58afbeea843c61cb9518461270cd2786453ce2ef39cac5818cb1aee0f336da3112be523349e6","priv":"f94665aaee7b5a07c328d74e3f5a51bdc0896f899c739c284bb9d882636c9b67","pub":"039f75b5dd06095b39778b0b5126907ad39a9c034dd5fc5e33f53cc00ecbecd8d3","addr":"af2307aaf8e07bc2feb04eaece0063867e64c4e5"},{"mnemonic":"much youth team what empty door language travel attitude rose furnace all","master":"df555390632d0ff6d8e472ef734e8e3f8f83061d5ddbbb2034f9370310356e35","seed":"f450c859e941b9d5e84126dd4710bd0113adabda8f962d383f8ba54bcc53d0e6e1da264d1841547ebd7c1bdfb8c29089a57ce05b64093653aa57e0ba51b0084e","priv":"89705fd7c86cbe5c18758ab9d4dcb7b1b6df12979c77a61c128ec13672b4433b","pub":"027949604d41872f518c8fabd333f8f351f16d68cd7e79e341f1b8368fe1b79842","addr":"36d1cbb6eb2510e0e3c2e76c2400dacfd9eae736"},{"mnemonic":"hamster adjust rally crew clinic skull private oval vast object school liar","master":"face99969ad94de93d7979a246a8e69e85dc6249bfc71f58ab6d774449e4f18b","seed":"ecc06609969bc31a47adc214324b7f7d81d09e0e3cb32eaf6b7be548f74eac5a9397300f0ff5650bff02ca895db55241d49b7037a54cf70e3fa62a3edd7206c4","priv":"c1d424295f77f3eb9f3a71c3f800d9a5292a2df311456daa694f5f6e12a7abad","pub":"0334e88812c848228b83e80283f709bd9827e991db6076a22f7497a3e73b641ee3","addr":"5f1a48e1eab155c3a698b69f11c0db64a556140d"},{"mnemonic":"dove grab grow giraffe pulp lift judge pluck dignity theme cigar annual","master":"3bb034fc63ce92269589e21c4fe89e16081e7cb3a29ec91f5ffb30bc077d914c","seed":"6f44f1782162a9d78af64e243dfe4d44c1ac521dbc8a00977e5260b6ea5d7aba6c205bc51b6c56b5139274d8b07bb31a728702df2dc2efd8f4f07c09bbff19b2","priv":"c2d5188d3db0a2dd9853104e3978c27d490eec8c3601259c4a4bf6e0fc30260a","pub":"03f7de67b6490d9cfe61818b22380450d5b5c815767c4efd821f3962ef4d430b58","addr":"0b5513fa903ae028a8bc3153b5f50b2df555a77d"},{"mnemonic":"wire silver blouse theme lumber modify muscle among orphan genius diary crystal","master":"28064c9af3e4436ebc8e71b424d749bdc6599b56f7ef1ead765606b4920d81cf","seed":"2a132c76e5b88181c24491f83f72b215b7963972f98c3d165c3a452f88165b459bb6e3756a511f40f9de0d47df6a030e91484a2fecb1648b9f194199143ce49b","priv":"232ec9cf0fce12247cc6335c9c8d54418a7db5aae86365558646d9d69b64af02","pub":"033e30397518d760b53821e3c0b3b43b324853c919b77a855250abe95d3924741f","addr":"dc7c6c94e8f7823485edd555741cbf224087f137"},{"mnemonic":"pattern syrup now tired gentle accuse rib cruel cluster wagon sting situate","master":"39f3af4487b768e1f9c7b04b0f713d4c56a5250994850ea4b20ec010a0879028","seed":"387138abf6c255b137a365dec7b8141ada4fe9fc55d75af013270f2df78328048981e69487873ee8740da3548ba611cc90f5a9315efafff651ec41df50732068","priv":"7270c0bd092550db36c7f5787dc20d17fd98edcf34d3d662085af7dfe604c8ec","pub":"026d65397b9ec78af76ec8a6ca1270cd0caded21aebef86160d4ea446b3dcc2f6c","addr":"35566b676261d80bd15792cbb348b79da3b10f56"},{"mnemonic":"blind force awesome radar law patch warfare defy device exist chuckle because","master":"b5eb133b2b7cdeb1bf5e6d3210f6a26b79b544ecf911f6f8cd838c7a6383e0ab","seed":"8a4539eb40090aa2cee32979ca6e8a23c1dcff202c935319db667cef1d2d49cd2a71f9cc54bdacbbed179b20feab254b932bc3c900d24216c089ac4f5c2cbac5","priv":"45e109f71861222311afe9d12b8a2a26d6f3fd0484b97a96bce464bec83346a0","pub":"03fd6c933a364638f867e6fa329d5cbf35aa9701061743ce5f1f6f6daa7137b3c1","addr":"dc3b76c2afeb877b256d7a9375618d0ec526fd6a"},{"mnemonic":"chef flock stem illegal later shadow tragic story tongue also fade core","master":"b7e82f75da29acb35a7714d3bf3aea45196e1857b5597a25b8a7ef6b69e9271f","seed":"7d02c419d5370133b6a0d0bda76a70b784e530c9a0b389cf2f6eebaa07ccaf946859cf4a7b2076814909f71c9c84ce3c0e45ee8caca9a753d5c2240029ca8847","priv":"555a830f9fc1f99debe0fbefcf34df402655484e5054c3fbd6c6a127e3356675","pub":"0238bc6cfb2c3c335b1564fe159e478d700a95ecc34ef23b7af3d571da8d136214","addr":"d3e9edf902c8dc5fabd17c17db492b15bdc33ae4"},{"mnemonic":"paddle appear actress output peace maid foam share afraid quick into erosion","master":"a3eb9cf3115d6b2f3cbe4bcc4f06e879b837d3b8960853a955f1231b8f95318e","seed":"a6b3ea2da0b83408010911cc091f9bb6d296fb13c1607cabb850824591ee5f69d0a2d4576a4361f3b368d34469f53282a1f9adadab3f8ab12956efa6d323cd5b","priv":"a37a2cf232918206e68593863c195d4319548c85d113456a0531b160b1c4509f","pub":"02a129fb596143418f94ec7bb1272aa1fda227e606c99f86cde12e8e7dd9b06755","addr":"69cfe226958b42832adcf69c7c84b734459af9f2"},{"mnemonic":"they garment wave wolf rubber firm toast hidden grit puzzle march rebel","master":"9c20ee12718c0fea98422c9ae0fa861da154552ffeb9e9991443edf224557309","seed":"99880bead4bf15beec406d9e980b46db9cfccd80473fe36d3471a0be1cce8f13bab732ace2e3589b1edbc5900c6641e088dc7a972bf11541ad475d97a66bd61c","priv":"b38db625f8ee7badcd89d159fa867b7d30ae946f199141f63af8e36c59750150","pub":"03ba880b842c952123b8bdb306fb0ec8c3c39e6bae28f2241242858c5c9c8c574a","addr":"24b75369a914827ee1e2697d5f591a58cf3f7be5"},{"mnemonic":"virus stand margin found heavy gadget depart idle guess siren mandate sock","master":"b6489aba56cfbac38041a70c7442bd298928cc37706dd01481fae719a2cc1222","seed":"fe240f7a830cd984b4b07cd77ba9a4f6b25e753cd2c981231e1458ed6775969a6b032be398838d2b5a706563d575177812361fa7cd35798e9a260b5454f3cc53","priv":"801663a31b3fa9f6788c826388b6d7272c53b0c331843c3ad19ab8f97eafb1b9","pub":"03067a334f5db13f9918aca85c5465042a8e994b835d6491604ea7c6b5d8a4403c","addr":"10cbc824bf4e61e2eb4091c0b1afe0f24ffec681"},{"mnemonic":"logic drip eternal frozen equal defense pudding prosper destroy chase faculty position","master":"df13ceb0854b9a18c97c8c972bc42e85231d26c4cdc87dfd3b8870b8ae0bda01","seed":"df990ef85f0d21de059f96b7037b905062b9e098a5f401afe29ae379a60c611a45cdd93f98f4994f231e549f739478566e71e7793fa750e92630aaa661b30e99","priv":"0395a33ce515a68172c9d8a324fdcb81073cd903f092581beb8ca73e8fd3016b","pub":"025a43eb1e0914d6f3c9269123280ec49ad469058d623230885b1f5dbb5f8dbcfa","addr":"6fa784b66d9a3c27073fc463e5a306916bd64374"},{"mnemonic":"nephew august wise enjoy age comfort hurdle cross feel depend south current","master":"9c01203e9921c9cbc2a05aff4cb90757f3d2e615ee6c6ef2d79100b48a48214d","seed":"19b2972d829bab57e706d21f00356d24cbbce556251aec246c36cd7a5243898371c92ef562ab2619244ab5e4854b9f76f76e2886b35cbf591a154a2e915a8a11","priv":"29af8262b1361dad291ed3e682a77a6bb09378c6503037da5c236b5eee1ccc69","pub":"02bc9c65596cc3f49aadad747651387a44d922de3f8b68a9876fb55e50372f1fd0","addr":"c4e1dd670e6c2ffb3a964315b0f7a51b2116126c"},{"mnemonic":"elder badge muscle tunnel sunny ring kite glide post slot injury crime","master":"e5dd0863b56bb3058b0aa457e17bed226f7f8afbc09c7ebf3cde93ac5912d22d","seed":"cd12f2dd94caf3a76292863e9528acd822c915385d8b84a09326b498ad5f1a60a1750686204b2c51093a3a3003ea558bd490cec607837675d2561a0b6f666a81","priv":"0f8717c113f78a6aaf7d57a93d5e7ec3a0326c119f792e8d16dee61b485beb16","pub":"02be9b54e62d1d26d08c1a2126c813a3a3a1a8d399440471491534dba209b3b8db","addr":"dde70795b05c51858f513bb59e2e0aa9d0330aa1"},{"mnemonic":"lunch cereal approve swing poet fresh sphere spray tower scale clerk main","master":"3c7e4e9876b819aad6e94d6decb42f615923873a72a2ca8b6df3b8b0ee1c77b5","seed":"0f9fb7102299f4b02874a785f60009c616ffc1e74e4386e78ab3abe2124257c7aec23b8926883dfd343f7260bad204f1261bb76cf0233dae8785c5e3dc9b015a","priv":"17b7b6f6184325c77195a60bcb15358b318a53ec2990dd46d8f60d0bf7e2e245","pub":"03eddd35bf621d1a943edeae5f5a5242687ee7f99f14be22f694653e449b77c177","addr":"06e8ee97a22bb6b2d458bc408bee7384749ada83"},{"mnemonic":"night law title fitness critic soap runway patrol carry drift damp state","master":"f7cc66a4812f3a394f9d52a0d83777f22eaf8fef4575561e26b0c636c4beff55","seed":"99acca4b65136a2b94c935892e265d125a1e8ef834e52efdb7b2ad09d973806dc318c43b0805924f5b239b74e6e516615ebf42d0379baee78ab63a2a24d03bb3","priv":"14506c9564b199203e8222c7508dac642fc6f15c981a7ed0fd21658c18660f04","pub":"0205f6b2c6ac7c0785d7f0c9aa85258167a314bacafa71f478c2577b5f9a3f9dc9","addr":"b380fefd78145bbe311a87e314ddf3b33d9bb34b"},{"mnemonic":"predict either bean grace myth scout number used void clown route member","master":"c7cba4de1441602a0b8ea2e11a4d72d7a21cae827db034ed4e43cbb38e608a51","seed":"8e80bededc4b64dac814dcb6e8dc5ce3acfb6f59988f13e24106fa7b3205c72eca6a16ee44ab51a54ab0a07d1e7d855fc75e3bcdd5d652e10a8fe33f623b15a1","priv":"6577584c26c25b3d6b11a1f669030008793f3d173721acc811f2dfd470d9e136","pub":"02e7f1c5213aded8dc3a44b14874cd9098a41e5cf0a7c83b7b3e045b8707d1d306","addr":"17614a88c0e044659cb6f99334fd1d8a83390df6"},{"mnemonic":"actual between river curve keep sing hollow bread theme corn mad easily","master":"e5498c15a99ef460088da7513360cc0e8ed3de095027783154425011575afd70","seed":"55fdc52505724e42ec76e0871860226daee30280de52f3d0538b8cbcc426ecd2d44287b4f1f11c01889ef63a6012896311a81f202c41e70725f3dff333f357c0","priv":"05b5a9a68afd24c6970b1686297582b3cb806729a277a056853f8918a706b0df","pub":"021a01e00670749567cd09de2ed8d0a66f0a0cb00cebb969ec43dcc9d6718da372","addr":"fb0c39ecab019c2d259baeba4819d924f8b9d97c"},{"mnemonic":"route aunt shed razor invite board ignore tower penalty claw absent solar","master":"c0f943565964df86bc140e8a8099ccb23417e7b86bf3c9f4d8aabdf7271cc721","seed":"111f3c5d234f0c02921ba5b30149d1913956a6c37e93fafaddbb3bf437b6709599bd623ad6ca97610717db77802f9c591ba352e7b08f4a06a4b897b9ac25c8ab","priv":"bba974522cb69e90b6b10ddd32f3b313bf5dfc129628bd2f10ad84a742a22cf8","pub":"0341c52f99a97637d09d68695b7b28f0c99d3fc5218d297e7bd95b267d2d7cac6c","addr":"5b4e4a18db22862daf7c43ec209bcb61ee139904"},{"mnemonic":"roof select rather approve must trumpet during more outside off owner blanket","master":"840894a95b0850e37a7424cdf10f73361387fffd96783a988a5d0e27012cb2cd","seed":"9eb1782d3ddbca4be52803a2dfdc85ef8ed55bc9b939246b9220dd911360c7323908996bfdcebf51b87c31c55cf2109c4792cf54b60374bff8f2c46bdfb97973","priv":"2db028d5651025a18a06e2c9bf77282f4bf35a8f54788624ffaadcb0caf34474","pub":"031c85b1faa9a2c9b3ad80328c54eb24cf27837d1418dba04fce05565f91e3344e","addr":"a7e4da90a801adcb7b3d9b947e760966fb4aadd6"},{"mnemonic":"album ball volume coffee motion cattle album wing unusual tornado bread stairs","master":"8bdb565fdd586d6aa72a53ecf88e2c81d48552034401bed5d130c862f179d159","seed":"aa0aeb0065b4c8e008fc9b1363fd4b32c0405359dd99f3a27670874bee96e8f1d76fdc807bd903289fb66b33138b92902ecb0d2c1627ef39353eb973b21b0003","priv":"54288cb0b5530aacba3ae1b16945a783e76ffde7e7c523c0c1e1293f00b5adc7","pub":"036974570620961a4e32d0329c851cb1e4218566056249c534ae92d77aabb73438","addr":"d7e65a2d95bb5d705ee894e16e4b6e4aea4821ec"},{"mnemonic":"start staff chalk volume emotion liar route lady sample mind casual involve","master":"aa479da35fc7c15a84e37a118102c41bb62012d872e34fb4f1317b67f9d7c452","seed":"70a8a8b15f77356e12438aef9fc97e6e6279be885fdcb28968db25d5c7bd2a3685aae1ee882d49658414af583c4339fc97f75f70f5b6ab23d184768cf12472b5","priv":"e1f12833fe2e792a0d959de815678a79e1e86342c7a092faba765979fde1d93f","pub":"02f127e13853937be361e47873d965fb8a6d602426c89389ffb45ee712e86e8231","addr":"4fdff2b288741e9f96b6595136c780d979403e2c"},{"mnemonic":"canvas fashion mandate will phrase spend galaxy good advance dismiss inhale holiday","master":"71707593bfe88f2751e6b381282fd71177be82bdc7b930c89c3f30606e0fd356","seed":"c0367432ce6b26e2d0b279b008b1d7d55e89b50b3dc55244360eb611d3af8c4e2dc6ee92f38e5e32309d4ca3b0b5c9eb9f8ba5edff66650dd052ac01f65ffc7c","priv":"0d53e4411bf7c498836412991515876c671967b55704e2928d87f3559a922911","pub":"03bccf2d3a8927babc9cdb6ae16addef1734739941071149122e780c9afd83877e","addr":"e1f22608018d5a6ad02dcac24a9ff28e065ce2c1"},{"mnemonic":"area thumb debate bracket unhappy muffin liar cute subject resource oppose nice","master":"416206edbc49f77c17405abe51397e5d5b547d300d296334b9848e4a844f355e","seed":"a08e97cf029eef0c4bcb3b2dca43e64b7a358199ced33a114c390ea81bdeef23aa7a4d6255993367426d051a56106e485d78f9b4057b4c50dc242d95484b39ba","priv":"9379dd5b24819205a9c7cc6a30ca2a416e6008af93817087b16778e9fa022fba","pub":"03e0796e8edc870070f179c669ef8acac6ba5d745c954762e5738e6db4d73317b4","addr":"ba2f7b307d6c8ba32f9f39174616def7551c4dc5"},{"mnemonic":"ahead face gloom dutch simple battle either hour abandon slush episode view","master":"5c953db2136db4be64531ea6556d5b93f1731332727eafa12630307dbc65c587","seed":"31d751f855507457129f25ecfa2ab8a50db37da0fb13b62ea4e232fdb8c7093c236502da769a0b3474a9436351b87df03a69c70b1b96c61f1675b8fec00f8ab1","priv":"aed4993762d4e8e31a12b500f8beecc1a3e747c2ff290c4e70141de4ed12be8b","pub":"02c922d80cccb9faa955b2ea0a90d3f72a88d8dd203a51e0aafb36c38af1f4c880","addr":"cb41fed3b24d89ef058d25d7264b6113e0481ce6"},{"mnemonic":"van custom clump rug floor what joy live art weekend unfold frame","master":"ab89a9c945f11e8ba88683d2a13cab657a9c938bd9014f19cf552bfd1db49bae","seed":"fffc2e2b6c4e1ff826e0d68ef4a2660417278cfce527ca55e48c5d3286d78ab4d6ca874514d70164e9040641281478b8c3b078bee6447d78262cc0556b463c4c","priv":"cfea30906faf51cc15f5ea6fd96ed92a40dc4bf80737a20ba37280e63ff1ddc0","pub":"020bcb8f7581415d4fe27dc7d0dcb25e4e4883d1290284f9d3028a6d0d618daa0d","addr":"57563ee5328ec10f7af2d0c44b95e5084afca64e"},{"mnemonic":"icon series document grass dutch green blossom report violin beauty window luggage","master":"9a203cb69ec2d8d19660947de9dd0b46ccbb07c9fcccb63da50fd3383c5f31e0","seed":"4acb08487e8a407ea10685ffa35b1c040e4dbdcb7e18a25c94a459bc7a2224246a00b66b88e6bea84948ed07f818e6e1a8fd4ebd102339773e704ce048a359ea","priv":"64d25c6a43d0aae389e2bc5b8f7d260098d85dd6a8ce929e42597490e5240ef8","pub":"03602214319ab01e65bda4711f9d03be60da39e092472d50492397e8f38d90f8fc","addr":"21fed5aa21ab9fdad79aa757d1408c0921d08cf0"},{"mnemonic":"upon legal wear defy path object fold security stem face question hint","master":"efa4834167d9f43a0807a950687e79ccf9327ec707fa4324ce8bdb40ed65e692","seed":"da5371985f4c48954726882bb278971512f9e4ee681645fea98415bd3ed4c7b049bfed3a3105f4d064b61de443500f53b4996c1fd7d2835d6b3e5b52cf67df5f","priv":"963ebebc47e1bf6c8f8cb515d7044f2095f61a8f77ecc2c7d5f8d1900af3b41e","pub":"0267d73ad34ba786e92207f5485f8aed4c634bccefe1a6c6a018dd30a9969bf1b9","addr":"f7b39221ff5352c17537d201c7d8422ea4c2f256"},{"mnemonic":"adjust symbol absorb winter dilemma reflect private all eager naive bundle lucky","master":"f8469edc4fc1bc6f3b934bc6ff8658f03fe2bae4d9be0b2689caea9f23d708e2","seed":"cfcf7299ef520c324a79db53e24326523e1d2346f173ecdd2bfdb38462a83c290cf80260353ceac5089efdfd9c819c3f0f15ed653ac3c4719b0ee6f0481335de","priv":"44025bd2acfbc6710d64d8b71eeec4934e054ab201419fbd553f6427e33d5197","pub":"02bbe2326c3d6c372c22c3aaf8118742442d237830428824160c5e703c268e06bc","addr":"81986a5c30d253a2b2ad8cec56dfd56ee3435772"},{"mnemonic":"fringe betray observe subway nation dignity stem omit topic lyrics index cause","master":"b8656cb35da2ecaf6b5189d8d252a08a15495afbf756ad1365ed757bcb46945b","seed":"cf0cce225311bc1fae42b654561de73cd2720d5a2e280cf39a1391cda8937fba9e69bb5b73b31e929d39a5f58f9505351f752d7666aa81211f69945ad81feba2","priv":"d55bc330b3ab7d09b0da10c1640c6fdf10909e5c6318801c3e7f877654b8576f","pub":"0222c2696c6480e840a7ff5d106f025d87309a0754a3638fcec93a6c7b8ab1f48e","addr":"2bbcd167f45d4f265075a2aac85d0ab7582d435e"},{"mnemonic":"ski labor urge doctor repair purity winter pond virtual salon number supreme","master":"283171546741970d2804029ce72b5848cc479f32f719b4f28670b00729c9ebf4","seed":"4aff8616a56b882083dc3f586afe1128f17aaae7b0c751bd24109094144c0f7aba69dd63cc4490301a72ac950e6a9c71959fd387629429a65178d1d4c7850322","priv":"2a0f5db45dca9a199102d2b920615cf2cd2c3a1d06d3fe72d5a64291fecfa116","pub":"0294a39a5a6f878929b7c18b0df75c7f42318864d84eaaaa68891f075f51906231","addr":"5173ecedd00d5de79bacab582a5b3de6f0534765"},{"mnemonic":"surge move forum tongue female cart foam coffee hole screen short clever","master":"57dd827d6deb98495732fbf12e0098970959ecdf113d441bbe6bd5064abc07f2","seed":"606c47f8d6984ce47270900cadf4cf5df3461f9293beeeaddc537c2e4b1d3ee7456ec7165c51e267d3c02a8cbbb5a2478626e475483f121ca5856005d0cccac3","priv":"3895a34ceb1de14e7e863759517cad044901cc7c8323e8565bbba98f5f3719b0","pub":"03a30052a8169da7d2342be9b0e2788df3e5ba7b4e6fef048662427476d875f537","addr":"9d9d8be022457576a9bf8a6a48f760fe346f22e1"},{"mnemonic":"ladder now flat food giraffe myth tattoo client party address tip avocado","master":"9986ab1b096cc4a635c2f99e7b191ee4d786b090cb1e00bed2cf18d6ff919aff","seed":"2bdf711ea898c4d62fc1c30a4a55dcec4928186c9d118befa4afd8c52d14291b3254ed926b1b1bbbcfe5ae775f74da99fe2112c7e2c64013b8f3b9de5adc18b2","priv":"cd0cf663053d6ac0d9785c3a56ae190fb8d0da670d6529e2f4572c1388dc6d8b","pub":"02ea2969ffa84be7d76fa55f4a897ecc63ebd61858b7561d41e179a38c7dbf8b79","addr":"a640cc723fd1d903e60a9de68e0a009b5e215812"},{"mnemonic":"change velvet mobile copy column cabin mountain shoe hub collect gym armed","master":"f80e68b799c63dd914912454f68a3c6ee5e01530bc48c130f1a4cfe46fdf2265","seed":"1bf846591febdca13c576bcdadd352b4b8b2ab8e346ab7db8213120d5b2f7a8031144adfe06a47f1d200f69c46bf9dd6dfae8e2d8dc94089b4974275960964d5","priv":"370af5ea565ec8725dbb8f63e141b12480bf43d39c219d612ff28e2a5fef031f","pub":"024f70c3096eeaa522240b50c1ad7347f1df1e764a305b8e618489788bf15865d7","addr":"e5226a6737202e5ea8d44f84620317f65fcd4ffe"},{"mnemonic":"crystal impose connect thing cement grow gospel reopen hand frame child shuffle","master":"a8d5b74cb00dc99c4fefff90a2f203b7e73daec3c7edfc71723894db050771f1","seed":"4e7c12a432766826d61cd07bec71147cd4282b2777b8ada1d09be5b873b9c51fb90ff4f4ea75739254fe7124e24696f66313d75289dcfb64ba5f5c8988b27ff8","priv":"7bae6919d134d0f150972cb0d96b0cbb3002d0d3b70efb2f9b03541c3830ae21","pub":"02daefc7677b5d77ec5fd27cead44fb3bd2d089be2b2e9744c1dcdc2e7def701e4","addr":"dd3ece1b6e903523289949e7aff1de580a536746"},{"mnemonic":"seek rain danger defy olive pluck people trumpet wide pave still cactus","master":"9d45b99a256e90347877aa27845d7ce7a259a8b50f7039852c60c16c372202c4","seed":"9c3f7dcb4aada2a8c204bef9a28c039dddd431f3daf5e70feb240be712cbb3dee3e5b65ed1e681255e9bb53bf762d82b95dad1bdedb27d0e18801ef1c5edd7bd","priv":"f43ce1484840f98f862f7d9c835bb3987fbc0413cf9121233bc29e829c779d45","pub":"02d82770b2af7ebb2a5eec49138178dd7899783a1ae1ea43ec3b2a13d6acd90c4c","addr":"49c6feff9794634c9fa66c76150375637f52ccc2"},{"mnemonic":"cat bid just hat diagram mimic field engine light elder resource render","master":"bf8a65e5cde0094db2ec4a5d776acfc944b0b482343bbe167a4bcb0a3492a9dc","seed":"780befda0890785a11f947a7da4280b897ddac841fa65e7cfbb01b09a46af665c25dba88abf759bac86e02d25d90c41347cd872f8abaedb158743dca746e87c7","priv":"b3f9f0ea5881318a1e011283a4e845ef6fa8e1ec5110bcdbb02cd37c4321c0b8","pub":"0214709b38a99a173a8b030bf9392534ae50d157e9e247f83d271be86872846336","addr":"9a7dc12f808fc5e599e2c03f73147317e381822e"},{"mnemonic":"eye thing material display own coral ankle spell hurry empty pitch sadness","master":"1a7c1facdec5151ca8d52af1f507f45c6614d12836d2604421138339c81dee2e","seed":"9c741558ad4c72086738a34898567312930af3221d13b160a39467d966862405a7f9b0b8718207bff6e26929cd33c578457b0d43e2e6358d488016c6ed7754bc","priv":"960704fe746bbf00a1c8d6bada8e500f2a7155af9f8328b7e4da7fc89fe079cf","pub":"0217e48b2a7ca750baac93ffa241b6fd3cd2422989096e0ff5eaf89f23277efcdd","addr":"13c55c8720eb51b5638331330ca19291213fdcfd"},{"mnemonic":"attend analyst stage network secret matter tackle safe stumble rifle lemon minimum","master":"e23dd8723b90971d4e03e21655e597b5f8110f0388392eff572e88db7f644cad","seed":"cfde90f605bace06583d24be20b13f73b3fd0acc60fcd93c2cb7d4eb6fcf70c885da2da7b709ba036ba20c275d99dd3a6af434b00932addbbd7b51a10cb5ddf4","priv":"ee54ee95a349da703f6d192fec6f776db6141a0cfa80372be04ef8b12ab65f82","pub":"020850e7d1011e08d7fd3ce20083b6c2658dcbdfdc067c979bea22d86403da9992","addr":"d834b0d108165f814c2616c91e18ba8b76a0ce92"},{"mnemonic":"student list element dilemma air faint eternal beach approve virtual fold large","master":"0dbc34013e5fddd9a1fc2d3e67a2d6d7445bc31e8343b4bf1a9c4941a24a2691","seed":"61b310aaa1875695f855a341f64b849774e3746db36303ada42eb60bbc91bc0fa7199c10f853e1def5fbf0a9ff2c38dcd803866d5473808a5b6340d88260cf57","priv":"ece1069e2cec7f5d270c3504e0cd9d8806eeb7ce8ce48a138c92d93d68fc9b7b","pub":"037989ae45a6a1f0ffcf9f73f1910a91bdb1ec39101810f3916d29a70b92232949","addr":"10c79559de51b7b96a7e0aa97f567289c41df1b7"},{"mnemonic":"ordinary fade chapter cheese patch injury better toddler rare manual rug opera","master":"ef81a17192ebb6e980676cacc7c9ace6af5d449a3c976d4f9a8a541dcef9d7a9","seed":"5a277523f2cd468b96db9dc30f8dec2d006035e388ef5348bb327eecd108d9e2815b3575b0f6d0da7560fdee6244194eefedb25edafd6f53019a91063478dca4","priv":"86e5fbe3136bcb11f0ed6dd97e3fc30afc0590d38b637fb19589947bd33f26a1","pub":"032fc8cd996500910443186db8432f24eddd6e04e00aac15db80cb5fcd73b7ec5e","addr":"db0aaf4c44693b2b93a8901640b940104d4931c4"},{"mnemonic":"leg easy evil ceiling candy okay afford apology around duck access ostrich","master":"098f864a847ca737aa5866f14fa96e9e5a6958758b56bc205d5c45f77b2f6fa5","seed":"7e6d013d39c652c2d57ccbec782fd0b9da7610d3c716b1c5f374daabf44f0a21726cf39b503850a5fe7daac263cd12dafe5c81a38b47e59b254027ceb298b520","priv":"1b5e814a954729ec4d4d25e01b52e6a48fc3beec84e43153cf9e5b4d5e61b852","pub":"0207214c051cc66259f234100e278a89b7ca3185ecf264d596ac8a4d3baddea28f","addr":"45cc1c7df7fb67a482dde6285b4dff7087857970"},{"mnemonic":"episode suspect cinnamon recall shell search allow hedgehog web avoid hero expand","master":"ede0db7b34ead2b35bd378d62d1b202ec206a389e27ba6d70813e3f98544f7ea","seed":"186c47e08e2fa1151bdafa4c8d16c5f6d8e9a61600a7ed76257cd3b41338a6d158d34ab84448c34c871243e211fc5082d3a6e199749ecf5bcc3fd8341e2b7784","priv":"d19884813f89a780962d2bdb40f36debddb81d132baa29795022b9498f04de0b","pub":"035f028dd1b126d6ea1b8091ac9dee9a3f44589a166d84a88ee982bc040c67d1eb","addr":"77b6f1f39bd0c5c636763b855396d1fcc5109778"},{"mnemonic":"safe run differ offer valve sing stomach table update base pitch pyramid","master":"1f6e07713ac34f997bbbfa0148cf2cfded624ee8eb4c89a66e2a88af2becaa6c","seed":"9c07c30f9b29fccb62670c57b8bc2210851ae9c80a3aee48c03e6bd35357626ebc6af1226f236508624fffbb52a8cc56fd21d8d2ab72a893a931c4891a33bc09","priv":"94c75ada800b2f73bc43625d569caf9f59f3afab6c2a8f9b023abf169c1a50e7","pub":"03263f919a4f79646ba17e1521c15f30d62c545d59c12344d4ce7d7561f8dd8428","addr":"17a63a29abe177f8bd93648ae4283b175b83c841"},{"mnemonic":"bubble bracket panda fury turkey decide obvious nest carpet defense side destroy","master":"d429dd03c2aac3ad66e8ea577ff48889d6ee006906f0d74be45d935c11f95c4e","seed":"d665e949ccba3afe3d3e14c8328f9d2eed1b3838e97a12d137bb188b4480b31f5f8ff388c4ea3aae961e6e98ae40177bd7ae075fe09aabfbab8140da075e8702","priv":"651abfb657e1b400e230b0fa3de8c022fc6fe33c2a80e425b13a3485aca1bef2","pub":"039d2e95484a02e3be5176e31ad41d9d38fd616aa37bc2f3032594f99b1d4225b7","addr":"cdd7ea2dfee41bc45d88e147ca87f15cf0278778"},{"mnemonic":"magnet setup unhappy slide human frequent notice unfold use ticket raccoon worry","master":"6a50fb7353ff7e3eff6054bee3ed8a156e3f4d65d712ef024ebbd58c11b16223","seed":"15195988c4a41524602465915d8c66b71acb07f8681a81bfcc77f5e8ae0071da3d900792c6666ed7f42e5362d1b22ec5de2856019e1d98d34f3bd977e5d6e712","priv":"e2e5997cea44fa966ed05107ee5347fe245ed436396a54dbd7bb0dcd45b02a5d","pub":"0251022b3f87060b140337f8a192c3037fa423b86f761c8e8b9abe13fdc7e954de","addr":"fb33e8b4227a4e31ee6d062f14129d86c190b864"},{"mnemonic":"extend expect crunch wear narrow crater opera dumb poet tone crunch eyebrow","master":"3a18fd4a5605d4a691097909a8fad033a9eacf3a8a6abbffbea184cb43bc4054","seed":"37661f80614a95188f9bf047b8b78201ba0512421b3fdbdb079d36cff88be9fcc6b2ee25a98495eec605c23eca528535adb4381b524ead9327671006a34d81e2","priv":"66b6e15ade42ef203b614a0d4db859263aab55cf9d98ae2118cbae7a2a8ba190","pub":"0318a0e61048878782f581429fdb2acfb382c59ede2a9c9f96112fc0a4dce78702","addr":"d3cbc69596f7f398a77be321ab4b306cad08798e"},{"mnemonic":"genius genius letter space share rich lava tenant drastic today vivid attract","master":"b1cf44f330ef51b5bfc09c224b83f3f678381b54328d6e407368f34f6b96a7f0","seed":"adbba0a0b7e15f2e7a8f95b0cc9e3b212fd3db246c0dd0b2dc41fe740c2d045aad24b9113dadc5b72d7e53d6c681fd702ae46b6bac877303e1ef4f9b1daa2822","priv":"4bc6a6a787283d7110cf4dd8e5f41b5abfbb302a5bd627cdc78cc419bd77ecf2","pub":"02fd610c024bf89e83940d0a5142c1b716786ae7c02e8779de11b72d3474b27260","addr":"f31609b8ee21b0da14e6d7ebab364b57230a8cc5"},{"mnemonic":"shadow ramp scan elbow cinnamon intact flash bulk squirrel pill zero tail","master":"46e4cc1975a8a363b8834ef06ff7a413a6158244a769ef15a9fcfe8981a0a6de","seed":"a8e143c8945640084294cee0afa09fbe4607059c8497259afe64dadc11b18b2d0eea33617b28b0f80419fed842afcb83fd1ab72c163c65e798bd1668cda9ba43","priv":"914a656705241622201d5ec8893d0d2484de7f4546847b3b2b2bc5afff743547","pub":"02f44993307ba52f2a927c5e7f7aa0baa6036a1e396d1d8593be5fecfd330e8d70","addr":"f966ac61247fc88e7d8a8eeaa2e682a669f17e81"},{"mnemonic":"wire list water over regret much ketchup slim capable proud then bike","master":"161946d516fc549a577b76ca6361f97b95ec58ec3bd2486dcef7f0d9ac9de062","seed":"c9af9f1c0f7fdcd56a69faf1274e563dc8ab739fad639e2032b4c0de10081544112b54ffb36fa1f6dc6419a7c073e0f3b4f2fc1a9ed95e4ee7dd300ea15d48c5","priv":"9f7f59143beb62116a592e3884d34d28a845c557be670278877c34f3749e74dd","pub":"027ab6afbdf54f5e952ac1d254cab364ffd91d49838354b02415a97421f9b9bdff","addr":"3824d1afbe44568f2ff4762157046e8f9bb561be"},{"mnemonic":"elder stereo hurt upon process furnace treat tool hole return base protect","master":"331d45143f0f94ba73de22ff235fec62132559735071ef806fb696e36f113352","seed":"4967f2af0a49298099ac49d75a3d99b99edf1165e3507c9055a9cb39a69aa05f6c07c192984e86f6abec6ab9b7fe8e66d22451aed158a6664ecd59b48932d9d2","priv":"7d547ee935de522967f92d0114dd40bb5c25d4f5aa2a1f70ad291601b7d0eaf3","pub":"03caf4c539853b640bf55c9db886e9906888e05fad3e18668f6c6d529434a73f32","addr":"816e255b2ca6837ba06d35fb834c3c246563d638"},{"mnemonic":"faith ski shell chest left entry admit smooth since hire pipe firm","master":"65f1eb6d72553cefc6fa5202583bb6db0af228fc0f008af45a3301cfbd279e05","seed":"2b778002d9097d84bb24e0dc577059a08e0dc24b47d401a37ece9b43c45585d49ccf9fdc6dfd87dfa2c4a70a226b9879f0927b0f3bf33b8f25573c1b6da98679","priv":"249dd8ddb06d455e6883a7126084aeccba0193a8ca0eadc6f924c16922ad891c","pub":"0390281dd22e02560114169d73fd72ae58ac7a83681a8d985cbf25fb39b485ba1e","addr":"9fb024edfc6a4e72e4fee5a4387c7bf09583eb1e"},{"mnemonic":"junior bracket pigeon swamp morning kitchen friend bike question emerge month faculty","master":"7a3d1634588a1d344986c5bdb8e5aade22a0fe74b5d234bce3591edfbc2279e9","seed":"4429c5b3dbd4db57f6ce8cf79533a746db6c28e1494de3610f225eeb00d2a6fef327aa17d68c75ae552c9c76b0dec4e06c583d531e45d6ab1f7d5dbcc259ae29","priv":"20b7253a740bf61bdee294c67b31aae21f90a41b2bd31a02267a773af049f983","pub":"03531e337b7ed416851867015996fe06b19a82bab432137ac32c914503fdf7ef58","addr":"e225e41ab3e0798b3631d71e753179bcd9226ede"},{"mnemonic":"farm frog apple capital foam behind grid project vague rural ugly sail","master":"22f4185158d434b8084c21d62c2fe3e653f9f1c5e2d592d72188bc36e9194e57","seed":"b92f9f3c0d496fc264acc1c04a42bca773f34137c92bb0f8fae52009166f48ed36d81c15be9e8eee8fe5f1ea2e7e0311a2d2b683285730cd6657ff862947ec4f","priv":"696f26ebb007bf4615ffedcb8a08ebc1b92be88955fb34eb5f08210970d566a0","pub":"03bb83731e190bdf7777058603180bc89a85f4bdd68fab3ecbd5c8a43f0e9bdc93","addr":"9c9f3d7c144c33f06ab476c752227c12149d9217"},{"mnemonic":"spare twenty above tape monster topple brush excuse squirrel pigeon maple fun","master":"a1ee9e1be2cb0f318e9cfca44f99ce405115ff3336d1678d94904efdb71f65c6","seed":"e90734515d14ab1b96bccb6f823abf76f21d47b450841ed1fe9ab7bec8a0e673828d09ee61b6a3f9bac0dfca778287abd21d70d45c596cd606261bd4baacc98e","priv":"d8239cc87c27ee5b6aa13d55505a8b0b2785392d26b0945976b575867b3aa068","pub":"0314db00f6e43e36e5f9e6a30cb2bb595cf4abc4cf26ada7d3bc7502b0e6be8919","addr":"fa50a1e20f2f4e490359a011ae4277ec61ca2a61"},{"mnemonic":"token cruel spot firm initial trouble slogan arrive steak inner champion affair","master":"4fd49883fd0f3b32564fa038cb60f762bcf4e65d3e297649cda474a6de9e16c1","seed":"c8b7b6807f2cef122125ddccd237435abeb2370a33db98f34336a28763996b81c336e7405e782d61f6b391b0ab2792b3788e27e67cf467127a50a6b2603820ad","priv":"e57e8f46f2eabf828cd024b4c7935126c95661bcbaf58488ddf7954b1a4486d2","pub":"03d959dd4d72e64be96260d31018ff3b3cc626ea3b80af1d6c3f9f8ed6452f9da6","addr":"e03c8d22c2e4513ffebefa5ed6e89245d36c1741"},{"mnemonic":"gentle whale exist height dress develop beef lounge apple gadget foil sea","master":"ed29987b8768b2f2636556eb1db2a69d48e6969f8b5ed455e39d6239ef376537","seed":"f4a08df5d89dd733e9b73df8a8518a0f3b632debdea655ea75b8b5b6afcc7c52d8bc0a2cf1337226c2e065ca0d71b6854109e360da8037b9c2a01156b2ca2b86","priv":"656e7a54258d7e2f4c493ae80e28c4eb08452175635cf0cf5a9111bdb6f76695","pub":"02f5f6c66a11efe81e76e7a5d440b9ca1b0dd73429426f4a27f3493f5dc7140927","addr":"e01072fa64ebf18099a46ee3799bffb49b990972"},{"mnemonic":"warm offer tattoo home elegant sausage sister cancel rocket struggle insane theme","master":"a58d8e3b8c25c182f6ba0e9e61b8aab35c04d846d1e44ccf3b305bbc03d839f7","seed":"ae94ef9d748fc2b348be876474f261458e3653cdd3f10448af8ee2caab848195cb802050f7d5d098e737672e331f1e48ee0e14c5924665f0aba855b89544f1a0","priv":"4534e2a9248df1bf1882da1a11ac8401b2db9cd92e5c3698d4610d120e6ff882","pub":"0246a4a61fd11a856a818f3726163b7f2f5f41b95f5ec513554f7237d8c85c867c","addr":"dbcf36e66ca99566f38ab8fb86930494c28405fe"},{"mnemonic":"ill orbit raise deliver fat age remind throw stomach country duck neglect","master":"9899f940702cfb78dbb9fe8d743301e2de5129f943c8dcfc4215e937c59280d8","seed":"789537517312103fd88f70345425c402bf0c665c34baf7d3e24c2c969162afae078adf365a0bc732de7abecda4ef5b12e213f4027a9e0ae621dbb6a16532ecd5","priv":"cb4acbee9d41eff9ef210ca73ed0ac71f353464210fc29b30c863a0c23214653","pub":"032779afee4e50503db9c67efc858d521ad8454cd691febc52540c4cf96ca92231","addr":"bc60e5da2c9e96698f32bbd087bf1b3b599a94d5"},{"mnemonic":"fold concert earth alley broom render ranch worry motor virtual industry bullet","master":"3eaddb6d4a2a73a1f0d094957901b9a53f4b36ef00451c9157a3dc159b523cb7","seed":"479d7ca92dade2e47b3f410fa563624cb9a7419921c687e93aba27d82af323bf1d0f04d12faa018732a476fc626df000f705525706a5e5958afe59891f10e43a","priv":"d0e151f6b58c2f48d0311fb2800e66db4fbd9ec14c92f84654907c5018f81c98","pub":"0372820ca8fc7a193815e924dc1e7fd405afd0b03e39ed8cd01a33bdcd35f899c6","addr":"90b134c6bb272ff804b6117fc1d6f3dba538e3d8"},{"mnemonic":"grid street boss erosion spike bunker indicate erase path mixture inflict group","master":"c5063e2bcf9fea3164cc8bacdac300a35b0b1dccef63e1de233ab39356249b9d","seed":"2c98b2b7703e3cc2fbf089d78184f2cdfcabc7bf269ba3b57e7b033629fd149263063e3f08c0d7fd3a785ceeab1f9b2f7e383fd2dffd7d9e982e7342ec90ee64","priv":"b6082dee45243a3fcf3313715ee9a644bb95d550cf8f275a99930372bf265e59","pub":"0282b6a0a9dfbbe648db6afcb9596fed1c02b8d7264925c88ba7007cd5cecc10c1","addr":"e9e9b9eb2c9d88b080af25d6c5fbf425e86c8f9b"},{"mnemonic":"flock entire rent cricket shadow inhale organ pioneer pottery faculty west umbrella","master":"e1beb66b50360f8bf5253b40e1fae368fe8ce267dd992a951b06896ec8e44404","seed":"267dd95caf4834b42cc69941de4dbeb3b37321af83548c865efda2b3cf9eb983c8244dbe65af863f0c88d2e0bb530d7580a0641d23a2bb98c4b64ac4b38d84c9","priv":"b35f776a36af618b48658829c0a914f8ee193070fd9b88ab34f3b4c35197ea97","pub":"03e030c12765cdf97520be291bd25d0a34aefb295f7749904b9aaef1ece99cb3aa","addr":"5c842dfe540f09579539e1fa6e961f929a5b7b60"},{"mnemonic":"all hurt survey laundry follow earn car music online reopen boring monkey","master":"56a9ee4a3e11b98885540ffd3e639369e2124f9d9b7108894cdfcb154279921c","seed":"ad2252df70bfa330e6a7c48da592336d202ff2f91d1654d34e9139ab644d54a04f88f3664822aecf8565453b58ab77a6785e81ecd7156bd7d560ddbfecd8a287","priv":"4181c26d8062eb8cdd8464524bbd2d82b56f423ee8aff8fe49385ccf98130a4d","pub":"0336b154ca3bca67a440c55add8c0ec34bdda413d57e8488ec58402a61eb93f861","addr":"2de1dd6ffa17618df2f9361a427dfc9689d7df99"},{"mnemonic":"obvious spot fuel leaf company birth drill baby lucky oven since fringe","master":"c75aa6398d3568764b147d2a951f2a93a38ca76f3e380e0574f35a6a69d0967d","seed":"d2793c736f85dac48f03f67c39b2b943b297744268dfad708ce9eddb74c649515632a25468a3d444bd07a0b9c4c9d650ae8676737e8373edd1b0f672206d7b72","priv":"cc9cbdf4b34dfcafad90d774b31313b08c6861e6409d659ee77afb75a1ebfb86","pub":"0251043d6ed5e0325ed3d7cf2caa3db8eec2a63c4c5472421a37831e96fc5a2bb3","addr":"9f75fc6e07b3935e5e8f3a39fadba8252e10cb41"},{"mnemonic":"funny online improve knife crumble critic grain vessel wood inspire venture ostrich","master":"83a4036503ba3499d266352b5d7736d5a16519870f9cac08d4706bb3a57e5d7e","seed":"23ab1c440ecfdba702427c5024503232b28aca8de6cba59d7ee1e070e84a4ce15cfa84e06c84c9907fb6bdc9d73c94abff5ce5c4828da89631cf77a3b091cb7e","priv":"e7cff4b876f286e6a8181763e453faac2d92582b0f9caa41b5aad8235f79ee86","pub":"03f2a9ed2bcd20f9ab0b50a3ed8f7ecca7c172997cbc877a896dc9ac740ebe03ea","addr":"ef1badd2e02541f774b7ccfccf8f550a0da31f48"},{"mnemonic":"elevator scan glimpse immense shoe buyer punch tomato chuckle art catalog coach","master":"ce00293fa3230ba3fff5f53d163acb0a06bcebc77606c6c22166f29d4f84d290","seed":"e06c12a0d1f8bb93596839e0c3c566b5b59421226c1523cb54f86e93e391883486e86807472313115c366495a9973d34b2c7cefd919f0023bf2039e95f22ba72","priv":"94e11d645e24aa3653caecfa6cafb3404a6b107c076fa2fc03d3a2d3127c8e95","pub":"036ff6332fa0db2db68b6a74a68ba0eba2cdff43f896de3d4b3b0d26ad1017b608","addr":"82ea6dd1ca5f8bd08633e5b69cffd8dacbdc3993"},{"mnemonic":"emotion super skull trade tell drum lake scrap alley reopen true prosper","master":"8bd8b2834c0aae5a8a207a40ece04ebf9fec51892b8c75dc7e4dfb256fba3b6e","seed":"6d9fa2ef59c1cd981a97e8d3e788b8bfb9738ebb23561d2eb72fd3bf3741e90eaca1c4e821e711756ad8adfb3c5d355f55fa8f7a41ddf260a85288416228d257","priv":"5adc84e56a3d3e6b43e1d42d01f2c7ab1bc340cbf8ce99c30cd94323e1107d9a","pub":"029aecdc08e10d442234814770ddd891241afabbb088e7dfe41f6ee0edc30a7581","addr":"19ce22a905e023e40b9a090b750870bb4d220d4a"},{"mnemonic":"federal math bicycle copy diary bind clap dose clown fabric hover draft","master":"05e5ae86313b56b4083a77339441c22cac4d675f18089028b841e12d0be35480","seed":"bfc46d250c423dfd4f123a91d8c7d556d484f1b8091132cc6e288fffb4b786d721a87d93414f71fb87457ef7b4f17d65d751fa43d7d67523d95997e357141ce0","priv":"760e1221ff1a283d14bc3fef817244affa4787036a46d3009d53911bb873dd4d","pub":"03286bd104bff54d0d01837e72b47e1bb582c13c78311a73a08dcffdf5d5e6bb42","addr":"d03ae88abf654c466a93dc167be85b7d1d172e38"},{"mnemonic":"parrot poem unique trim auto april under pear brown flag critic ship","master":"438ae7958c45b13e2f2d275f52ef71e6ce20d00545051101fdb5be7e235d49d2","seed":"85ca4c5faa1bd0c0a3b74b8a9f5afcc0849be00a0d1e67222a7b70a9f6343c0c637843756750852dd6247d311ae14f581b642e5c3c4cfea3b689dd1c9d4dd18a","priv":"f725a96177c31ae08f065255578e34f58145b921267c2a2e26f09a3fe0d58e61","pub":"02fb792c0736e01eff225a1cfc6f56ccb8ce70fbbb9c050da326ee5475fde784df","addr":"d096954bbd94038190e6aa959ebb8e6d4c5cafc7"},{"mnemonic":"expand enough goose wrestle title hamster purpose illegal peace patch moon spin","master":"fcd43f2a177b9c6f19b22a5864b41a30e9e4ff29cffad7663a6d5e5574910a2e","seed":"0dcfb2c19f6b6b6560db73bcc164ff84e117fac8a11027b0c8c2caf5c97256961e019dc1ae14752af47abd7290cddcb8400084eb59b8ebe5fe1b148806c422ac","priv":"645c6babf5d7abdf9a111ce1ef7a860466b73c47d2afc83d5091265dec741fcf","pub":"039d7f9485265190c0986c0ea74c065beefaf0b8a567c2502c122139f4f7d0f834","addr":"9de7c6791416a501bc1b3dfa5940e4ede894bca3"},{"mnemonic":"property grow toilet hollow slogan pioneer gate fresh still notable happy peanut","master":"9e289e0abc03cfab28e00b885be5328d88886a24e71d88c120cfcf697e1573ff","seed":"3deae69499f305108ec27c7ac5e844140b59316a354d08a9571e671d5f71ed8a35e060b084deb4ac2f55c3968184f7b625246c5635e8ae85cb511ed87582a712","priv":"3765a9eaffda6c370a95ca1c2ecd178a5a7799034fed7d051a37f658e1db0fab","pub":"039bbdd61b3e1570f585fe38ef1ff516a4d1ea27c9d9a2b11775f9f462b5e1e764","addr":"c0a75bc9853ea8ff8070b22b5e6b22c57ca2e820"},{"mnemonic":"grape arena buddy shrug foot fiscal move transfer beach else alone city","master":"903560571ef0d4cc0fc20d79ff830f6cd360a1ff387bcd893b436b8d8cc4a4c4","seed":"6b232fcb4175b92836ad60e8cb9bdc82856d663558adad2fd001fb71db4eecc55d0a9b0cb62c938c8e699f0bd55f3e773080cb3804d74e4c7503420b2f0640e6","priv":"b693be937db9f0aafcf2b68b9c3ad8dff86d250f4d7c7ce0bee4fec7cc164035","pub":"034178d1a76406edcea9b3e501aa11161cdd14d6760769cbd0070862148192ed81","addr":"91379f6876f01696ede09b112da349125ae3db9f"},{"mnemonic":"spirit march luxury planet review rhythm mother food orphan inhale dinosaur ginger","master":"88b72d270aaad97e466b4c6cc2d5376e0bd9d5d4389bf1c5e5fe3cd60eda1cdc","seed":"ae53ffbf1695fe13e7590e3c0d225621f392ba5885387cc5ba1ddbdff13f83051293be338369236cd2cefb39682019b257a4766eef632cb2f805c226a611d5c4","priv":"8cd4d3c8a6a6a18eef4b30056d4c23908d100a30566ee7ed486f96831be8657f","pub":"030dbc527c5e03ce3a6ba9caf81c44f0dd0c0b0374617efa819a71319879027fef","addr":"345000ace68ff89bef2f2c197da7f50329c739a9"},{"mnemonic":"cause enact push shove account orchard grunt sausage mosquito deny relief sun","master":"d66d0216c675ef09072623aa75fd8a9df788af3cf26b16d38091ba5ec8cc8cb8","seed":"07d83a41e284788319bc0e5b9b7b1849485b2bdb8cf408843184f09b1dededf8ca56160aff2f6ed2e0559e0c005f5f0dab7b3e36500db5e45c55612091818f60","priv":"bcd7f078131f5644373c0e0ced2f33822c116df476cfab34c39dc9a8d5b9aec2","pub":"026c0d381a709b557135d33bd1760de196b604b5d720269ba4e8d749b7737da2e9","addr":"7e268fec12b43d71998eba89c8e0df3205c094d6"},{"mnemonic":"faint jelly paper blush cute hope project giraffe muffin strike pistol blood","master":"3e2eece9505cdbdd0e44e237a90a023837b45c6305c01802fa278d6690afe9bc","seed":"7ff4975b81e3165068c8b861a748013e93614bd56c4af844080373a3c60d0e763d5c934ed4d4941f195e97eaad4257eb55ef4842d43ae648ebadfb82421d5b7c","priv":"d2e9c0441d876bc0c189a109a564404e00e3a7540cb2f84095da70e38321adc2","pub":"02a49b4d38662800e8aadabc72fc7fd3ff080c9c9aef5cc3c3970d6411ca92d2f3","addr":"b0bfe3ee05d361865a65678fa612cc64ba633789"},{"mnemonic":"jazz ten exchange horn junior frog surface blur color pill bonus science","master":"037073838661b05747c80ed9a91ef9fc07db4f4b9a89c56a26a517d74615a83d","seed":"92333a0fcd8cc74457ded4de145027c19de4d04d4e791c0418092ff599869c5a0f7f585692c0de272362e6ef3a8d31fd793e83701f1aaf41a0355a818ec061d1","priv":"04cb6c660a8006068ae929e97db3b29cf55093f52bb7292d212774db7b6544a9","pub":"034a39172b568cbecfe119e7c751086392e0a6b8c5ffc755453596ed74a75bd1c0","addr":"bde2747790882434b15deea070cd36c696c73bbc"},{"mnemonic":"chair practice neglect hawk panic sponsor ritual bid sick fiction vendor defy","master":"1f908e1559b37dc8ffde2f89ca0dbba2202260f6a848461d75cdc8791f53a1f5","seed":"0fcf390d0c757b52a520a2fc8c30dc740b0c481adf1e17a6e8d445f355c3c266bad1671bcdba99fba9c69e473a294c5e3f6ac51027a1048987cd3dc7a52dd3e8","priv":"6444a8b09434528113de487508dc7e30cd184c3a9f52ce20b30c7b6f40d5a031","pub":"0344d47049e125a655b9dff7de696e72689ee478b8b4f13a0bcdc71df4737689d1","addr":"3ad17b540fa37171f21fb9d4cf6cc061008ce652"},{"mnemonic":"dilemma main solar balcony differ bring close popular couple educate hobby mule","master":"2a9a19b24310a9019114beb8d3222df214ff8eef4ce190e7017bae4e45861092","seed":"ed8bd81a4515d1c43c24d69aca3ceb065d0552b79ad01db75ad19c2af3cd23a6a213163f9db3743d3b2fab6bc166954b2285bead616d1a50f036bf144856e762","priv":"1c8c89946f2dee6c92348f5d82506ddd9065f83b2eb8f8d173cf9642b971a0c4","pub":"02855f225d510b6b0d64fa5abfc9639488358272957b9003b1bc697d474577c45b","addr":"df365a12508a519bdf095aa5979b93acf59681c4"},{"mnemonic":"sudden cattle enough output make code tonight matter reduce enjoy file prison","master":"ab474b0afda779ae957963eb8643db33d1f2d879a5ebc2a79b5d8f2f9946223f","seed":"f732b62445528f4d96e0c95b58c4459e8ab7528d47ec2a925e3f5515e1459c952abbfa40fa5cd7f8b7c2f059e3df2c2a5a3813b4c37e322c9f2c8f55e66ce3cc","priv":"5d5af8bd1921fe03619088250bd74a2a1f58bcac8158230c0cc0e7ad304790e8","pub":"03ce0673f40df25344d5f2d85a374d6d40b6ab5b8bddeb5f9e2adc9120e2242c17","addr":"a9f1d96cfeeeeb011efc76ac43d3d121a2e7195e"},{"mnemonic":"oblige broccoli transfer midnight display talk jazz wall fit harsh kick ahead","master":"b5e760adc086f5be87b58aeabc63d74d018aaf2f673205620685c4ec32776769","seed":"3fd39274348d2cf5ea5ab4239dfa66dc65b33a7f4975b25e334d26b67e32ccb4865599f9b4fddfe8cf8a2630cd5787ef0188371d1563c8b9880b33201bf259a4","priv":"5e9b5b2a5628a5a57510469db849aea45ee2989c929bb1fc06918736f115edf8","pub":"039e5e293c463f16d26fd845e92d4503e551013864e5682e1c28bc21072589baeb","addr":"a784eadc4951c1e92e63a83204473dd467f5d558"},{"mnemonic":"prosper must remove pulse wink rabbit shadow harbor equal twenty air muscle","master":"ad8244b4d4221944b73939b681b275f280e1a8d42fe6583f63740865dc6483bb","seed":"a3258a6176d098bc96dced14718524f05669cc6c9f3ba5680a56c8c80b83bf50f32345843aab72e13df9bd8727408ec114bdc0099902857ff1889bd94a3a1388","priv":"32fde5f62df796263bd40267e1d1573f73d86d2fc98076008a5ea46092f8d01b","pub":"03ac2d243cf6580c8c0bdfc091c8ef1afffca6aede2ba5375e149efd2db54c23f4","addr":"504cf87560e4ccf69ce6f81aa5b0b3af45ec2899"},{"mnemonic":"harbor focus scare envelope slow margin boss giraffe daughter mouse hazard step","master":"28831264a522026221c9739fd286152e1123809699955d06149f34a0157a667c","seed":"bdb6f459beb7d6627a96b920ea39dd34b38b21cf45bafe88b66823c5ff02babd02b40ce25a9ce7b4d04696294910a967858fca74b18a5cb46f8afe294ff8d56c","priv":"4834d0601e457f6903e3dc08b3168411c351ed97df34a0932ba19f7bcecafc4b","pub":"03ba2538c15c37b3e0969adeabb0e5e1d093170f7e352ce0696aeb9e5e36150295","addr":"a259af3663c6ed69b149c94f73dddf22e4c91442"},{"mnemonic":"elite magic excite apology sleep cable refuse carpet ethics fortune assault hazard","master":"384338593c8198935c4bd0ced828784a7a26797b5e68212f7b142d25c5e8bef3","seed":"4ad678a061c1fa3351872cc3451c1410f5506919afce9ed62e5dfb05e9be36471fb80a5a94312ab603ec397cdb8ccf9acf8ce405fe7b834c9b14eddc570d5411","priv":"d07f63e9ed19bf7c7f89a598727dabde42bbe0e4cbdfc0dd889f8b5c4998a023","pub":"03d5199768e4a175f47831e46382232c217d58e94aa99f5cfcf7e85887865d4da9","addr":"427a4855b7d2222cc2d54dccc2de0b225b09c315"},{"mnemonic":"awake robust situate increase salmon tell roof agent grunt wear license kitchen","master":"c30d435feb0cf93a3cebc4584e94e00ff40ee2950cb3053ef2f7832799bab885","seed":"b49401408240429ba30ebfb5d9afd6fb74e79971be6b9f76e3810b83ab1993958f2d9f9fb5b75dee68607a2510ad621968d384873d16b4a194c939ff1358a67b","priv":"def35e61e636973967024d7cf9ee2ab0c232348c70fa25b945d6d4a6f220b9ba","pub":"032255b26a5ab86ade14eb9acd3c97e774aebd710b00e81719d04d7dfaad37251f","addr":"aafe58c581f30d3a55de219c15724e2b26dd2c5b"},{"mnemonic":"host proud little want shoulder guess acoustic spin since slight myth detail","master":"200f4964bac08715f0dc5bc750261c71ab2c5e5b70c6e20bf748aed10c4e6ae2","seed":"3fd02e2249ce332bd4f4bd3d9c0ab61e169d0f0c011a826d072153001c6f093e7fddebc437bfd7b9dd60093686147e069c4ff3806124cfeb02501b807205c47f","priv":"005e6a885009202c44f2dfd911fbd495214b9c53d2305b52c6bd7c1a2efbbb17","pub":"03a99eeec3b673289bf785c9482ee94fd906f992dbc11b6e0624e0c98c6b9ddefc","addr":"57a1472c9d2e1d80bad1e84b1a88356d973cac1f"},{"mnemonic":"chimney organ announce town worth finger donate hint vehicle sniff defense famous","master":"8059f2264cbba67a9868b20e25cd6ea7d5ac2c77a86b5f36b9890560b8ac9d42","seed":"a2317e376ede3b6bfc464a993815e5b32c7e2d896b462a3f636cad9e3837f7b454cfd3ce17e221a5f46a8b38a8eca74f6f1508d376ac9ebdbd92d6603178e8f9","priv":"e8e7e337feed5b08f418d6757b0cebc3cd2e037fddf8ecb51b42c1f71d83bce1","pub":"033ccaccdda15edadbe824e3340c73e27303df9c1e40037d0108bb2dea87e84235","addr":"13ae50b4bb386c1c5360404f5f43a2dfd95e1967"},{"mnemonic":"wolf found absurd device rare desk average water excite ring chest version","master":"5dec910d707536db8776b138103e97ed8a34d75e89d79c3657320ad9bd064d6b","seed":"421737ab059b231f6bac2f012f4472ec7215f94a5c9f5cafeeb43bb03d8b936c39afe6a712530fad6a5e4bac736b7ca12e488b3c377faf58476e9e8fe4897829","priv":"17e9344eade9c62a67b5d72af06616bc455ae6f9aa03dd48432efa2a242356e7","pub":"03776634e0508958ca0a9cf4f15b038f544a4d2d0497674ac7a1deef315d80ba81","addr":"63fde94bb741395136727075993a876ea1e59336"},{"mnemonic":"disorder improve say diamond present elegant evoke latin lonely muffin main resist","master":"e8e118fdfad2b3eaaecb31ccdb8ef3ef04e904c543245766a7bbc365dbe37174","seed":"c32d703d39d06d3c61464db0345ffe546f020678149496ee357acb0e93f9575d39ed2309f46917f89a2a299f1704958806f65404ad80aacb295242a91c0f6a53","priv":"947651ee70f613036de219df6d42b78dd5d1504af999c5c2ac7cccc656f578ce","pub":"02e0ca79766b0cdbe0cca0c4d4647e9d82740a6db151f0ad56df0881a0799e56b5","addr":"dd0179f1d538a9c67a42ca0fbc262edd506842db"},{"mnemonic":"define lion input friend used deny obvious basic fantasy initial grit jaguar","master":"e749606fd4eed5b54a718207b0c44af3dc32dafdc192d6f26744fe02b1cee804","seed":"2f67dd5c538358009d036e68d2205254ef898826613d01617abfdc83deca452603008226dcf4569f3faa21a18ba72e3f22ba0beedfc89888701ea2005be93912","priv":"59321cf870be317e697723d132c9f52b20ab43a84efa0f53d3af3b2e1bb075f9","pub":"02e681a3823e20e1482ae8888dd3fd54bf8b9843c1e480d36e72f6ec8f9311ef7a","addr":"c13389a74d1657b472efdd2fecfe736872952513"},{"mnemonic":"caution unable glue tissue toast august decide leisure foster session position match","master":"a0ae79723ea7b60a8234be8bae9acd64bad5472f789c7b8854d95862ffc441dd","seed":"9e1e3a5e11633be7f211cf442cf66b9350f2f4d84829ebe6da491e7749f2a9e6a3656feb5edd3584b723a9c4edbe1f2f530d4360f55bb1d32abe8a82d7383204","priv":"b2a560b474971b2ed48e47c0a27858b70c4485256ec288849a97be5d5eae26c5","pub":"03fe1ac82b75d9ce75fec2839d343954429207d4ffd7ad0e037c2bfe50d7f8c68f","addr":"85bf34297752337da3c79c124508daeab88faa11"},{"mnemonic":"pull drive tired success sorry raise top ship visual filter tag upon","master":"e5b018ed831659613748160d29f704367c0933b09ee12a8582f36ebac586ae78","seed":"1bcc9ff7923777f97fbcc49e5653ce6a7397668eb7b08aad407c77b5f7ddcc62323d8a566c15b51dd6032a57be69054c1273dd50e2c0698e42595258cdd05e7c","priv":"1a859101a7582121828f09eb02de30f34f6e1cda405cb36fda0279b25e1ffda7","pub":"028e0aafb274dcd1f7f8154bb6f1a6ee6207f69d8d7720c96a0d73e2fb2277f92b","addr":"ef934026abefbf19a96bab8f59b9f048ba4c14a1"},{"mnemonic":"grant enroll monster verb voice bench when certain kingdom nuclear save stem","master":"e8221f0b15c9ec7cac1bf373219481d9952b907ee29914d4506d079ae99ec17d","seed":"158737e586b7d0515efcf931d780a88fe0dbf150133a9f605bfa9c4f0df1b7d1c4f56f9745fe76b51640d45735b91e2a6391e3a53f1200824d58ea8cd9bf25ee","priv":"cb61489db37dc70695fdfd54887dcb61f17ba29925d6267f10999ef088acc11c","pub":"0272502a28dfa3e7ebef4c97ee7ee9817756e84733c1030a94820db6d25c82fb97","addr":"d941f06898ddb082c3f8dcdac5a455ba88be2dab"},{"mnemonic":"shrimp forward swarm olive laundry team fashion run tiger atom guitar blush","master":"e726598bbe78396d7d21a334ad1ddfb95285f72e5c6f015f6d76d7b018a8486f","seed":"7f59fa24106d19a2fc887bfdbd01f1f0c2e037869cdeddc6543354a29952785a31146ae4de6d7ceec9ea95df088dda0f195d491d8be3a6ff63bd427532a1d979","priv":"1bcf9039d65d76bac2b14698585db46cefc7de88f2724118dbf1b0597bea6960","pub":"021b8a68d6c12165a3c11dd81c93edcae4437c983751e8c2a4dc509f2e3bd4d400","addr":"9be822a10983a2c398dd72cb43eab3dcc2ee30f6"},{"mnemonic":"object lava wise decorate donate panther chicken enforce hood donkey lock better","master":"f2e88ff11892f72f22627d7cc7048909ff7403a121a23ebd9744a9017a013adb","seed":"9b7eef532cce30af1499362b675c2b6c3e6333f672c102d41459152f380661115461b1dee3613ee5be55beed081d1655b70d941e819754de304beed5269c5fc9","priv":"e19e47c990399d9bb11760b2b00847fe8b85d7a73c5c4fd99414ac37822b5ed6","pub":"02d0840b212aa20d204c8946877da8d6307b50c890a463a123d7eeaf877811f998","addr":"b85c15ec5abcbbb0991c18fbc788af88ff36e66d"},{"mnemonic":"blade reward angle predict text salad auto drum alert grace valve dove","master":"935ad9d81bdf740c8cec1414d56cba9a807d0d47d39b0d9169027cfa38491fd0","seed":"7888677a5dbd757788a5fa116a954610d3234aed529b85cce2bbc34413db5b7fa4b25ae8d9f4bbe367ac55b0dca61724399f70e5404e346506ea2e5708269639","priv":"a6f5a6d090cfb99f935d72d79e77d00c7eaac00b9d23ac1a4aacd6289fdd4604","pub":"0308cd34578b15b3f459d9c0507830af364ed359f27c1135ec0dce2fb9d256b65a","addr":"f05e198f7feacf7a2fdb37f598137f27dfbfafa3"},{"mnemonic":"icon aunt fiscal day never reflect rapid scatter exist fit prosper what","master":"9bf8057a5a94ecd164969fa719a846494e7fb8f40d6571ff0f021940bdb5567e","seed":"0532364343a12a5b821d7cb9c88317dbf802d8b3f24359b49ff32d79882f89f489a4f1f63e4c52ef1ba92a3789e971d56f056b39cc9b0821b3570ececeee9c3f","priv":"0b204e7b6e74dbf35602dd6914458af9860593d672f3409ceb133e431b3f6cc2","pub":"03d5efdd40e97200646f202db82895e2bbe0c16f2cb29bff1622169787433ffa56","addr":"472be066059dfe1d34abb3564037b0149137ff75"},{"mnemonic":"mass wing office match couch tent tumble rug beach mass october already","master":"1b63074ed73326c5629aa6bb9863f1a3cc2369f50f05aa1281d6b208a787adc5","seed":"8e96902f01dbbb458201370b5524fda040322026f83c8f77bc2e91e843ce6b63581b979f71368038e81aa627e3a10897692c1a215fe27a446ac914f043ff8f75","priv":"bf5a466ca37a2c297ba1ee4ff4ff26d62ff44b98b02a5713fc4b2f7427ce9e99","pub":"02827ec005329241a597b6c7faa5e92a0624179425549777ff922482d2a1f48d04","addr":"67f3445c15a8f34a0a5d374acfabc072c3fdf74b"},{"mnemonic":"lottery skull bleak sand drum domain rice eight card frown world much","master":"8a09b9b68f5f87795c60d6dc08146a2780f410f44560f4519194eb1dc6ed26be","seed":"f2dc56a6fc9f382d54b3d92785724815c9b78866ad586448cd9ca06e59d713dc136f41425b16b28d45ce094d3f817aed13bda99e73659a77c06064a1fc123d07","priv":"09b6ccac9c9109ada552b0982202838b3c1e53a816748176c2a3f6c04681300d","pub":"028211fce683bfffa2067cca19d0e003e9e86a066b40db4e16756723cbb525c042","addr":"9853d04f14981533312e56c75a32f10e98d543f8"},{"mnemonic":"advance poet beach endless idle castle inherit jaguar wife grief frequent wide","master":"c16f77a5a5931add45a26fb906cbffd87c7e5ef3d146b83df93e5a3d5b9ca9ef","seed":"26b3842ad77946bb585a05ef148b8ebde2994c800d30224adc7dc1110a4605c02a6651d30709f5f8c0a532c6976504344887bff1503e6afb6cb8b1ae0f909f66","priv":"58a69857570ddabf8a5454e97655e1a833194b64ec4421befe3e0d9e45ffe97a","pub":"033a877e03d2b871bb879b53196da3ca45459485eb38eac76e938c62979d23a1de","addr":"0bf6320bffe291c8f1c0676ed864232cc84b4e57"},{"mnemonic":"stove tennis wait major grass network mountain before inhale glare bird moon","master":"b1bb7df0cf5b8143e91787646825f92d175664fe68751c114824d5a374850672","seed":"73f5867400033e088b346620983d128294338a0988a8b4282999a2a960a26caa12686db680247520196fa9a1e34901841d999b4fdad40aee63834dab615cdf43","priv":"37af5d2736154cfef5c59e974f1954e541683331de3555976a9e9efffb7c960f","pub":"032c5fdf3604c6ef170e65007bdb75ded577aae6652f099ee41d4ecfd1020cc065","addr":"7ef3d9bcee0b3e3d131fab4dd7f79d6dad548889"},{"mnemonic":"sting nut gasp like spread sponsor march behave zoo vanish noble dirt","master":"9f74f4075e987922ac30b7f5f43bada33f0dd385a4a30a1ff42718fd43f76c93","seed":"4d6e6b8a41454924355067b754e619b663ea585f305482febb6db99d26d62fd1a1a5441b7fa1d02de242f0dd35c965ed62fb0d9bc7a857ba257dec94ce462a9c","priv":"53afc4f00fe2a5003c77e92b4d0837d7c8fc54b4ec1e76e0434ef38aa3712850","pub":"020f710a1596997eb3a95815ef79efb5a7204d3bc5fcff171e067f4c6b3692f5e1","addr":"f41ded9fb4ec7cae1a9e8aaaec7de6309644a2c8"},{"mnemonic":"tent trumpet jungle into loop target myth analyst symbol ask december rural","master":"3a8fc48e8e08afe8b32bc8e9c25ada84feb1b84922ea10135a590927eed2b3be","seed":"7c9d5d2681c85e71d49392aeb0502fee5643e8a6ed60c4b84bcc202a5bada19a99dad7f88e365abb6cce65985117d642ca1ae4733a0863e1cd15fad4edd1e8e0","priv":"56b266ef3f1a45b33ea1465c15dc6ec5779289522c8b2b6588c8cf2c182d2fbe","pub":"0206b8e7a5350358fd35bbf173d9ce5b0ec91ee8c710837b9198b5d5ef327a11e6","addr":"fb059b5167a4fb3bb07c0b3b3516bd6fc84f66c5"},{"mnemonic":"juice barely airport rigid miracle afraid funny combine address guard omit idle","master":"787086d46e0777b03c3774933f35e4fe65b4ff069de5ca9b09cb84caff915ddb","seed":"ed6db1f257a45468761be9dd26ce88f78ed7ed1c488e4affb3a8f8ff8550602848ba2fa284c930cd387188ec4f057c6865964ca93bd181bda40e4059c4fc4d28","priv":"9d6f46f7c329d6e57b2ae84150c23c983bab43e7e6ad7190bc95dbeac977c617","pub":"03ec60e506de8acf2a518ce07e3394421450db339cdb6b91ca52924b1e1c3afe22","addr":"0a4359701fca7026cfb2d196df28e34337a34960"},{"mnemonic":"uniform enter number remove obey arrive print version cake alcohol swallow mistake","master":"047c71cb3066ee3fc151a4dd961a06595d63b393c54e77c756966fbca8a749bb","seed":"3db076729af5e872e92581e3c8d8812b60dbe4ed85a59f034fed43c9c4e0015fc4363643dc8ee5ade53ddf68af54b3d63d6bd79457eba414f45bb0c809e90af7","priv":"557c62286ae6440a2a0b17ea98dbb4992333093a054b59a37345a61de1b871b8","pub":"03ad3f7e2e2279b486c88e7e12d2a97a3860aa31a3854987853a1d73cde6aa734d","addr":"ff0a8d5fca9824e71cdf434cd868c12957fc61c9"},{"mnemonic":"split lecture predict rich inflict flush bike sound credit girl pudding ridge","master":"12fb50c5a687fa1552f07cc9b56d6f5ecb7b68376c3cdae621190494ea279f9e","seed":"29d6e5b0c2cbb22e6048158990f14be89c6c2416b36761c2f4d4de70a3dee2c7f9e86bf6dcfb07e99ac1d15f66f7393fc48b00195b0981f0699652a9f3f0c340","priv":"b02635341dd14b0b5e701222337dce09c3426a6f80370b06dabc31c417d9cd2b","pub":"0365f2fe5611808dd6fcaea62ad335d9b992d1b8f91333d6dc7b96c0b3ac97b209","addr":"ee3da08bcfb0e2fd4331e8b1ea3c0905c6c2f005"},{"mnemonic":"fiscal deer minor dwarf measure goat enrich emerge act view cancel shrug","master":"4cb7b43c2efcc7f6e6d84d5b47ca352ff8aa3c1c44fd8d2de7dc75b3fcb310b5","seed":"f48a89c3f2dc87ad41069c06d0b8751881c993c5895cb548b06974194cb410122d1268a9f962790ca461e875148cba07c216439df21bb37a06600456f5bba35a","priv":"b77f4a13edd7f5ae33725c340b1f8982fd02829ba2756d70f4086dc4a38a5d21","pub":"029844babe3ab249b969895b2b0c6d3cf7a79104721e96ea3b24784a4593fcb7e1","addr":"20a6d611a9ea918d6697d2e09900cf4fc9f676c5"},{"mnemonic":"expect speak gasp outside word glue fluid neutral casual train left mountain","master":"a774f13c1b5a22667ed1d3954ef64f9ddf3f841890b894660bb291745f8c5d23","seed":"7e8078aab4d3b5d121cb17213ee1a06fe4b0ec7d95dbfccab17cd0cae6917151197385c2f75dfecc7221ad518d5899384c22d2641a66250dc581096ff5326a6c","priv":"663b4bbe218e2f6efaa30e02460985ec708e76abd845ca365de83d2bcf547680","pub":"02b78aee27b6c719f89f3f21c55e8c34b9b83e94864c894188a7e39c348622e5c2","addr":"1c716ff8774a14f48623598e80fed3877d974bed"},{"mnemonic":"grace clinic host vehicle drastic april sibling response laptop escape creek neglect","master":"0f2dd943aef0644bf150f38baddc31c3c2a95b813c1fd893ef936f36c6972aec","seed":"e21b62815782f3954ef2be4e9551f7ba47d6f471b566d3b9db6a07d29b42c2edd10e500c7e701ba60963315f21afc2a4ea0d4c187fe4e08f775d3439279572b1","priv":"df825cb149c95352cf0bb17fb8b12cb686ca246c76f7bdfd8ae4633fa18ec30c","pub":"029bb63c2664225dab9c6a93294891127728b77e7d9a9a8e187531f5f154ad36ac","addr":"55266b5a04683c1d61e2cbcf4180d7087550c9f1"},{"mnemonic":"neither help draw cup grief hood swing task okay wasp angle sweet","master":"5a89607cd2cdd7717fc0918d92e661dc7960b5f92a7083482079468afae827db","seed":"8a1d0d7f2799cf70744d682e734352e2330494cc309b2bf785cfe799f004b67c936f3987f75954e18f4eb3adece8e2a3c57ae24b3c8f747884f473cfdb671112","priv":"30a055fcbb2c88fd87963e2ed60117cdf5a82979a7829238f5093f0c27fd7380","pub":"02181e5dacd8408db30a736957d7b19448d5925417e4d38d487391dcdfb8ac4dab","addr":"9ee3469dbceacd60c741f1530646f7550b94be6c"},{"mnemonic":"fall laugh virtual service grit left clip betray wise correct walnut online","master":"7c11681ada91e9349c1e062d0036a29290bcf0bc1564428f7080ee0b81fc5a0c","seed":"c2ab87d2eab816dd1b81ae4acea81e034f2a7cd2cf7103ad3985e739d696248dc0cbc6ff2864e598ae736b58c6ac4f3898f1ddb7eff76413fa1383a63f6c7716","priv":"13edbf55d44ea6951f3825d67c2486a96030bc58ba15d282df4061a0d644a2a0","pub":"0386590dcb32fd11ada507c55069b5607182a1db6ec02c810c79668a27d60411be","addr":"71bdce836bd62d85f5a53f9fcfe2310d40bacc56"},{"mnemonic":"hedgehog light govern fruit season cousin shy tumble maple promote feature lonely","master":"f4575fea61d7539101b4f89674218bf8fb206563cd07d729a834bd7cd8e3cc62","seed":"147de64775c5b285b09b2f846212750577cd9cf77bdc64f198da75003dfbda9c9dc742bf9ef1de8390641ddf9b03db8958cea480e5b4660236e29ef5d2d6a6a1","priv":"9ce717cacb307400d04739f7431fbf02cdaa3ae9035e00e8a31d03d6cf7e193d","pub":"031b6e5958fd3a5883f0cff00cd6dd14ac6cd4d92611e97c4cdd751d76323ffe0c","addr":"775cfbe90a93b73c27172b699506e4b40020a47d"},{"mnemonic":"normal tuna cry human world wonder suit tribe company pink weird unable","master":"834e035154ca70f5719e0df0dea3581a2ea19c4f9c4f7e1348810e0a47eaaf81","seed":"c1682262a9bb26399355c5a226abf198db50fd6891e48afd60094127db569a3306b5e556fc166907a4ef90c80069d9c0027b74532491ca54560f7a85ee1c2934","priv":"035c6aa4e2ae3ca2d2a356112809945b068a21a4c3a448819d8b29ce406423f1","pub":"02a18ee68f4c04f7c9698d484b9e87a672f05ecb87d127746b67f3caa820406285","addr":"b6f3c63322c96f7cd1bc13195acd2a9485b45232"},{"mnemonic":"school kitten swap accuse vivid spirit team verb border write boss barely","master":"b97687333b05ee2da13ce7c5d488aa076a1cd16c8b21f43e38eb0606fa3887cc","seed":"7a770e511a21a4712fbb40f9cfbab467a97e5165e89f70b27dfc8bf5a6a69fcd8658bb6527d0203e93ac549a89dad65068f06e8699cc9748e6448eb8faafa2fd","priv":"de3f7ccc0001822d6320b5ccf27dd38dfdea7ba8fb5c73afe8b6f71982b06eb1","pub":"029d4b9f7e55bc7fa1e84f403a19bcff9eb9a9afb873476b082374e19d3e7c6589","addr":"2cff960c82af319d91e2b1fed8171fe04d47a491"},{"mnemonic":"banner lecture vacuum metal clutch return maid furnace beef armor excuse mother","master":"e944b1515fcab7dd33ccb6c027535d3e4d5db2798809fa6e9317587a1a9f8a07","seed":"6089209e2ba24a756beb9a5946df522adc87d9d98dab2c528d5469bb35ca2da36662d661b0daf50695322dab3578a5bc3cdd918a7097c0a10bca063568abe8a1","priv":"c0b5d1c2ba77450237956cccc68a162c2e32c62e662a0bcbc7e27f2ffa24743a","pub":"02b52a9589c4a631aeee16e8ce808a2c20c63134407bddd7986a517ecd46f6f1c7","addr":"d79746b3b45903cdefbfc4146489ea550bf9361d"},{"mnemonic":"lottery uncover blood that bench peace raccoon define scale fault erupt bean","master":"faee8490c1b9b5e79da43146bf8697b1aac582410ceccf66d1fa54a8b4e8c1aa","seed":"cb558b5816b5a3ec5d63468859b71f9d2b5c4b7ad07bc00e5e4e3dfeceb12fce337cf1acd97af6f5b8d9277cda0197dbac16c9700fd41df33d9d470cdb35e545","priv":"1f77e09b423c423043b8c41b93060c9e795b6b0e05ef0fe75eae4a53abdac019","pub":"022a4a7f860dc1ecb21faa1f827907b01b87a552f8cb0a085af3a6a0758d922390","addr":"7566766fb425c0d00ad475dcdca95e94b17faae6"},{"mnemonic":"bounce someone uniform blush plastic edge bachelor tenant office report lounge brick","master":"8766a5c2858ac393f9e73c6d842184953eb0806304fdcbccc43916ba70ce8924","seed":"cb6a680c6044a9bd171e97e38f4933a86f94a643a398e54ed042cb7d2039e11287876ec24794a0a078398e14cf471ec6357d02c83009eacbc377cf77385834a0","priv":"a5f252e60b69ac73744b617924ea8158b93d4dbdc2cba19db4506b86d413f6cc","pub":"038d3945d243fd90ab18ce1353e36b3c07143dcce74ae9670fc8e0ee12a2fd01a8","addr":"b184c47600390fb017cf60d2b5c89c28f72d64b1"},{"mnemonic":"alley wide siren matrix cigar paddle spin fame receive cave student tree","master":"2cacce92a105ed6a199a6d881ad7a43a7faa74f967b4e8330a55b263102fbd8e","seed":"c67bddd95507e4a9f9153f7da3de4e5951c53750a5842f11192328994742669c32cc61ed14139ddb72365ec7065436583b360ce6e2aee5c196beaab9b10e9991","priv":"f6dc107f30701827bf1f83113ea3853017e384d6995205dc9fd23176e802ef4d","pub":"02c3dc3ea3727f6f351a12d3f5b3fa52beb25ddcb5ec397042aea4e646d9aee6af","addr":"5ef50803371d9c915ddeee096f7131461323c489"},{"mnemonic":"pipe brisk focus nurse rare arrow seek spike guess enough unlock transfer","master":"ad585f1ab0b6e5f8d224fee37b6c3d1fdab1e6c757ea93a9df059a36b3f96646","seed":"5b76d0f7fa0ed23b52ec73d65d109d7026f7cc4c207988c6a003a142f3e6201fb1770f8e662fa8cf4acfc0f23e0620bf2f7b139fa9d8d71e5a3c5b5c2ab75e68","priv":"dfd55ba52a10f26aad26e7532f6631986acb0247fadb1b86c45ff9537924e42c","pub":"036bfbb102ab379a9dea1cc63dba5944b22d48a941a0d1e534170cca9a53d3fb0e","addr":"af337ff42bf6280f7e518df5f4f064a84fe209fe"},{"mnemonic":"coast opinion view orbit knife december pepper elbow boss junior wreck escape","master":"4eecc11aef13009bdfc444037aa185585c147be182442a33459b5a07b61aa555","seed":"f543bbe5ed92b75d06089c2335fd22db68f41e499634760dafaa6661e23178e7d075b2f8aa3630aa528ed77d85737601d041278d182458ae28c04420ddc25b5d","priv":"0fee3e3e025dc742e5a95f41f2e2c84d94bc8cf068bdc67db76e0378c1ff01af","pub":"03e58501a3f5052e4b7b1a4bb264c5f5a61d60c542a761a015606ffbf97f63c10d","addr":"c51fc7f607bb0e1cdba35f503f3e397346148784"},{"mnemonic":"indoor dinner fantasy cup move solve pride dust cross note raw balcony","master":"6346159218b27d00feda5a8fd63349956636147e058d9eafd60bd94bcd18efce","seed":"1c39176421e5c49e7fb6257ae70dd7d1ec60b3e2a1a4523bc4aec59b040708f0e48099520c0ae4de467da994082c82e0db6f1445c159f625559adefa55c7ce8d","priv":"74d7f00b88798ba5190b71e59dcc4bd7f2cb11e93669d7ba0372f4155308b947","pub":"03a07ad498d80dc84ce120f5518a541b5310e50bcbf0c669455c8ce2a0eb13e253","addr":"277346e420f814e9bb1a8ab16b11af318bd78d4a"},{"mnemonic":"please neither sister wrap comfort omit stamp roast lunch steel night report","master":"1f0fb7b99b38b57321f40b4327cc38f7c41c5688a478e4be908353df70477fcc","seed":"6d383d1ab8febb2334354e9e5261d6d4797bee2e6b9242521d59d22f982525ca87141e713b32cd60b6aea587caca213d8e0524c1d55cb209a6d06f607d7b74d2","priv":"95236694952fae12a92d15ca17c54cdfbd234109aadf6c295bf664115cc35a27","pub":"02f29a1a01ba6702e3a441386986ab5ef7227532704cbcfa08f2339c5273fe5f7e","addr":"048f26f774131d92ca52228106fe61d12e7d28c1"},{"mnemonic":"lawsuit trip betray slam tornado polar demise appear east dose produce market","master":"8e659f66e4dcd50dc7ba617e17e4dc45c75fe957b656039a73f3583944b16ac1","seed":"d982fe48080c3bee97fe1ae2ffdc0c5ff2445817d28b30bccd6f89bee138ef1e9828b04fd99cd70512cc8d0e58010ecd7c4460c0b2614211e7ebd8acd27d2061","priv":"4d053df57043c403659a370f486e8ebfd60fa2804430a6b97d95ecfde846d63c","pub":"035001c721d157c1af6dfa4d1de23852ba2d9be1133f30628588c5d9ec890a7662","addr":"bbd41b5af33ef8bd075e93a01f5377d486ddc475"},{"mnemonic":"hen build sand sister borrow victory syrup scrap rack aerobic shoot pole","master":"a4f3bc4a89dd86f38c5908d229f58a57c11f4a3d6872a0fd448043a6a214f938","seed":"3823745cd7589411813362179d13b2d2e1cb65bad1d53f34d512c349215e3cd5bef97ed86faf0096d2cfd5dd75556bdcbac1ac385c9caa9f928a19cb926082e3","priv":"5c14903308d7a83b6570ad2cbcffa3953b458572a72c3d5148a79a494fd90cf5","pub":"03b18bbcb61fe68f733542afa7c4c02214c8980ae4212caf818a8febce1166aeb2","addr":"fd5a9ed68124fee88f30a8d7f19e65e5ee47e681"},{"mnemonic":"chest hard axis own found relax skull bus frown distance gauge angle","master":"6eda34ed25b73c45cc0465aed51577fd35c45ef7e8d8e137c621c5bd6a726888","seed":"fd71ceb91c1c0c2176d7c75ef17010fca12beafc5a54feb3408a69461e1cbf1ad0421da9f31532aeb1f32ee6503899eb0e20fac3756d5c1d9fb23fa2738605c3","priv":"7ee2eab961362c9fb48f0cec5f63d1bfb0b38e819ae3fc1a4a3c6fe6d4d35725","pub":"03131e751282bed411e12a03c7b2ae4ba4c8f81fe5e62f3d40bba09ed7ff099509","addr":"f8a2d049f67222d673df66844d4355ca77a34db5"},{"mnemonic":"large merry tray craft fat clip album company nation tent increase armor","master":"c442b107b26f9c853ef65260fe813449152c2fc93d28774824153cfb4d67e1c2","seed":"bcdce56a81179b6fb0224a34b26583b1d1dc1d24a06bdeae60eb578df673d4d9ab5d8d639c494fcc024a945284be11ff55dd88d2470bb3740b3046155818a7ba","priv":"f359be0bbc26a121997cf2b6678b41c08d6815a5903c184c7743464e287e8557","pub":"032641e977e838507e61d0e85b1a2ff16f0b8d8a351f7958ea615bc2a8723cf1d0","addr":"924690289cc78854d75ddbcb2b06b241404fea7a"},{"mnemonic":"carry pipe make glory famous word shoot artwork ostrich slice blossom episode","master":"f6ad202d1f7acfe41ce8f97c809d0f8ab9c7959866c5a435faa9d551e98d921d","seed":"5b956478a0cf11e9e0bebfd97b3ca56a6cfd8499843d21f95a2ed58db8abb7b06c672e713a556c35258fba0533721cdeb38313565c8edbaedb17dbc1c8396a6b","priv":"0bf855554127bbd03b3779577449c37dfb82ca4457adaa0edf26f1e5e5d7ee27","pub":"03452b2268005ebdce5fb467e4ee5376624cb0dab31704c4725796dc68561b6f92","addr":"ce486d831a5c2e1b95a254c13393e50bea0cea66"},{"mnemonic":"inject more grid coach cause inner ordinary crucial mouse access attitude upgrade","master":"6556ec1bca4ce356846f9ad603e8b2e9a1ced7e2f875bb6330bac32baba3e820","seed":"c5248835bc868983d65e6009b983ec48b262a0da70dc66ba76cb167b9618730ff79b9da8e2321731b55ff63b8cfc8a2b59aa435146b5d2a21b8608bc14808bcb","priv":"3b783218c59cd664b88380619db7a4bfb4b3343fbf38d0a576849c60cb4eae41","pub":"038f88cb7546e49c3dec3d356b0bc70be0716a1b146c641447326aa077d91d055b","addr":"09e570c6a4c7439d6272bfd611dfe723d2fb632b"},{"mnemonic":"viable material flock borrow pear cup barrel fire exclude vintage economy force","master":"ed54a092853793849e78e0c42ef95242414a2dfaffc92d6b7c25efa46715e23a","seed":"013530be872ace250a72aabb73add7e4cc4568da3aac9447c094c49663be2cb6bbdc1fded3bffd41109eb14cf1e8ee48aa65da60166962aff17451bc86dc9bf9","priv":"669218899eadcca8823c6c10476cd25fe546f918495590051f8d45debeae3cf4","pub":"03f54a4a58259314bea899e9f6126305d13afc7e8de6b346e95934358b524a5b4b","addr":"b38f1873c88ab12cb5c839ab1e70639538b331a5"},{"mnemonic":"injury expose attend toward air brain carry neither amazing symptom number name","master":"769158e4432add662ca03b558828568f25369b5fff971076f7a303b8c89bb3f6","seed":"827d52b757b28ecee8ddbc402de54ed6911dfdf19abd00739766f70fb688f47575da03177ce2610263013c2d22e3ca7556c5aa134f74b8faf61dcfba1a4d5ee9","priv":"2d276c19d260ba43e8de8e4b982bb21e16f52b5c8e231cfb6bf71901a9137c62","pub":"0310fe6ba12f805a118c9052ba2cd3218418217e1e48da3daa5887bed6b2fe9bbf","addr":"0ca37f96efe4af7507cf85213a2aecd7dddfb51b"},{"mnemonic":"seat other color road pulse melody error hire scene lamp best analyst","master":"c4e172dcd2a54bbfd30fdea8363eb10b9f0bbdd0d1ff3d33ad3eb01e820d417b","seed":"32d43e6b794040093d6348fc46a452a8733e49a66a06cc8ed2045359c881630531e282ddd70a4d630a3ee69821764b45ab949650d4276a925cad0c3121c31074","priv":"828b3cddb3d902d31386264f84bc54d3574325f56df7d4e8e06b2145d60a0de1","pub":"0275e251466e97a728d0ab4527e04031e315de4d03d9cee50b5b52210fb697a9a9","addr":"c0e6ac260e64b92beed9f4370cb006e2697dea6b"},{"mnemonic":"tonight nature salute state carpet sad zero heart limit skill vehicle elephant","master":"7f116fc76af767fab661d90b8ce20b51cf5d0727ece353410e06409d79ebaea3","seed":"226457053ec313b3368e877c76f9f8a2cd5a7dbde6cfe91de075974f42f994d195f056d20802fef8bef78cdd49c6383e95933eb2517cde2bf353872a13d87da7","priv":"1f069518222310563fa736833f06041805cc0a9ada1ab2b704e85ad91b980ef5","pub":"0221fd13bb9d0177d081c7cc6b9012b0494ccc42ed79ffdcb2409c252f42b66b9f","addr":"401f8cd411f3c5475482430cd0c480ed383e8455"},{"mnemonic":"window awesome survey swear neutral tackle essence elephant weird emerge gesture click","master":"ffb27c19b7d6241a29a08c54605f0408d7de2af078a3eabde97ba6e973b9c31a","seed":"29aaedc60b8cdaeb799707830413942cac78b57c0fa1a4cae0542411a81efeb36d7e48e222f90b6d42bcae97202772d687c226a13143a9541b0d7a3bf7dbe600","priv":"68ab3dca6b53b32bfe8a1b2d428332415b6278cd258fecd927f9d8b371075789","pub":"0234cb69b2f76362ff4ff138f81499d5c2e0a1912fa47098c0d826f98f1be4facb","addr":"54637f8b0f2dad74bb46e7745d1957bb8b16f4fd"},{"mnemonic":"island pact measure trigger frost flee tape napkin wide kick select sense","master":"013a5ecc8a93bac063e18e79f5654cf0881e8c39fa43c467a8aad833b6a7ea76","seed":"19cee1ab2babcd2cc5cb4bc34acb350deaf24b997d603814a5509374a2f60ba133f498a20a9066cba31b4903a6c9da661dd459343004f69b2dc78ded2dde67d5","priv":"16b0960d535046bc5b95e335cd0326d0b0a902a3c81f70490453f75154a05e8a","pub":"03e6198bef79e7bbe034d1786e47f00fd53aa3132318ed99fef38b6f46bbdd9109","addr":"199fb6c909420f711c3b452df497d03da191911c"},{"mnemonic":"before shed sweet will sunset rapid color tattoo winter foil spring orchard","master":"29289b59bf6ad91e0f9b24900803f57d08b45194782e76102f5377c142c17f65","seed":"7b721e94ae18b7666bf293bdb8eaffd70c6bbd2c2ddc582a0939100f1f131009752be6759491e0006cfc424f88efd97868132fa2e6bee0b05a520c881c632951","priv":"f6d7fbb1fa8957d132b1d43414b0664cbc25020055c35635a5ae005e86e40767","pub":"0368c1403ed0df7c1f9faa90fcd60937094cc975d1ab5bc7a9eb03bdfe764dcb7e","addr":"6657bcebfa3816af66b1a0a92f8269cd3f515fe3"},{"mnemonic":"view forget toss steel right echo life candy fine unhappy document pulp","master":"5c6355a65617952bc05b16623992e81daf07695ee5cd3d9bb2b8fa600ffb2576","seed":"20909264d02b6b88a472678b6d457850ce4f67a228a4f6ad7f45be104029ecb68f25075f30680416e0e43469452ad903a1e7b0486932d0dea4b1c5f56b21406f","priv":"4495c90b188f706dbe1106966e49745c49676e5c54f78176eac166629a4c0815","pub":"03b828ccb3f9f1766cf1d1c1c57e8e5c9c96936adbcac4a8ea47b0a7e3139c5771","addr":"4a382d15c13a06adbf075cd847ae9e80dbdf4ca3"},{"mnemonic":"fetch planet injury lecture myth goat drill sea reflect tattoo story rival","master":"3725eab28e9f4275bf2dd2dd5a94aa550688b8d111798185383a58088d6f8b56","seed":"0d42a4096e20202bcaa4d1939ce86cc6975092d2e6081c149b374f3dbd6cda81188c442e1cc7b67032fee9effda37e20da0d809f0d969977ad2c547e9a075224","priv":"7abbbf9aa4375ec489d3ad3ef6041e9e371f4582eec1ed753f9d7de3b4fcb57a","pub":"0371b9cf4994f36ac2b5117a2daf84d7c072f63e51d9f7c5e547548bc2ce51a16f","addr":"d59315e071460c09d108bfa31e05cf37545b19d6"},{"mnemonic":"close raw empty danger educate metal vendor coil observe response scene army","master":"da1ffa0441ba19153f0f98af4092dbe68eb5ffc9d82823710dde6654684e8fec","seed":"f8ea358ea3a369cf72266a1f30e10c445817766080ba50991a2b10ae1f23d1fd3681ffd4cf4a7ac47b39ee9b04ea246cbf5337eb33e0d6e7c1da921d153e2cfa","priv":"5e3f256a55dbfbf2750e56067779fbc05503bea90e1a999c17a0bc27801a0bbb","pub":"02329640a5fbee753825fc310c06f9761cedfefb880d6e3dfb67eecc68ee269813","addr":"904c7b3d1cd8303fc3c8b0e3b0fd60fcb54807b7"},{"mnemonic":"ship puppy grab also merit doctor fine east venue resist loyal radar","master":"f7e49c26a890aa8deb888da48d82935a69730bfa0af67783b39d209ca803de9c","seed":"dd5c5df895a6663cea37b5e7c58c268420e290e4f20d7e0b7c98defa35fde4d372f52215b52bb2745481b8c63aa08c2ba163dd89f2a9e51a3bc92199be8d57ef","priv":"19a311da10e6f11ea3c91231a7e5bd22097701bb56c0248014958e6df186e596","pub":"023acf91dfb359e537f9183080ccd67f65b1b9efe314f682deebcbf718454d6bd4","addr":"618fb20184dd651d18d2e039ac0fa43e53feff61"},{"mnemonic":"beef hen spring repeat define hurry slab midnight liar either arch original","master":"85a6a3be23cc74b32c40f1dbe431584f8767f4116a98ace1a08c934956e8582e","seed":"cbe260dd75a3f8e7b7b9588f0a1325dd88b839a5536e39facf324cbbee3ae951903e2c17370ef673c770ff2e0fc3f1975a26f45d27c681a143f0e60fac8d18c8","priv":"42c6ccd133fbb7d3bd8bde8309f8202eb155c46829aaa558226b6e53abdb203e","pub":"02d1bd732a69043343e72e22432f7bc309e25e96d49b087572f021996297abba75","addr":"9eab0f06ec4e0a8058e4fde3ebd5a1b2f5ab043d"},{"mnemonic":"lend total guess ski divide diesel tumble heavy slight expose clump park","master":"6ad684d3e30778a46d5af816c3deaeaa0af5c4fc04cd74045dd80947faba053c","seed":"d63dd68a0b8296a41ff8698494d9823d18b4700b0564318f022b1bca641a8fd622ca403b48fb835c848f053557cb91fe4290f37ea9edc4f2428226983802e1cb","priv":"9625f841a7384f3fb64c643ee715ab0c5693d60132c4c9838c7f41e1c9163e1f","pub":"035e82a39dd7b61ad9f79ae31b0694af43378fe1b5cd6fa824ad2427da0834e00f","addr":"b88aca334f2bfafdb66c2e338a7d3b6c8be8bdcb"},{"mnemonic":"toss hand crystal buffalo during more laundry fantasy give dizzy bench want","master":"075697aef6de8c5b0b418fb3faa6038442349ded65421ae1089517423120ffac","seed":"4226da530678cd25633e2f87951c6f8f5bb4e3dda3172494dbc03ea15795b22d1042ba8265d67cfeddbc205b800ba7b7b05ed231845ad54cb3224c7ad0f9d8fe","priv":"8db99c4eb921431ead557ec1fc62bd6a9bc34eabb3516345a46bfe8c6106be6c","pub":"029eee00e90a02beca7c3813af59feaec320d26b585e5620de11efdc09a06d2c5d","addr":"e9a4a29d0e7267016b03bd23d6cc78b9eb1681be"},{"mnemonic":"camera gate trick sphere oven sick promote apology reason fiction item meadow","master":"7af52d41d0e35f2cad60fa2fb6c13d046f8aa4e0be104251dee489edce66a229","seed":"16ce2107f57bc5feff86b9dc81c98838cfb7b6274e835d6e35a46525d5870fd84c74cb528f6e2b87b0cef21bc6931793f472e5430b9582f036630c3b7c66df87","priv":"5f428e529d340883faceda659fdb36193f3cedbe2307dc4b8bee55a6845b9068","pub":"02c71ec0f9fc74db1da6d2a4a9d6a7f24980fa17e656c1d7f43a845a17625b2445","addr":"31dd6642a6d913d82b06c3793ae678670ea9bef1"},{"mnemonic":"slim guilt leader segment actor sick debate enough what rate fork rebuild","master":"674b90a421dab99750e982cd3c693668c45d7a39377cb82e3887552f047eadf8","seed":"115114f315f7af942dea64857c5bfe6a22c80031e6b1dd0c19a42a28526c0b9995b0eb39bf8e78ce849559eebdfa3c269783987bd4fd926e776984396a3c604e","priv":"2fdb1afdc8248d6afc69e387a698ef467dc0473323203445bf1dd5aaf5789936","pub":"03dd070062a8c3e65333572beea40f434d6f1b68e528ffefdfa8dd3d8b4c5a729c","addr":"8938c102cfbb8030cf69c660b04fee696a902f96"},{"mnemonic":"kind prefer arrow industry arrive cherry pupil arena strong tuition wide grunt","master":"c4b509d9b1e60d97cb8b862b96a2dfbf960b0553f0625af7430abd3951c59b2a","seed":"85ce840ce0f6625294d32cbd5f68b3c2abc3151db02b5a84b1d78ebd7c05ab24bd49a519a340cd19bdce6aee845ce59b6b5d2efd7a2b1640c7919177bed27b4f","priv":"ba8628565338b55d2a79b21fb9e47da978611095abcef86f305a0e2988e8128d","pub":"02bbbb0be37e3975749a095a9dcc025bd57368eee362cb896540c0dbebba42f0b9","addr":"4d8e97ff30d95baeb64ced528ab999c72aa4cbe1"},{"mnemonic":"slight bronze prevent civil junk van female movie vibrant soon grain suggest","master":"4d07291eea03d51cf9a3790ab0a77ebef383f2cdf184b0ebd872fdce93b0b889","seed":"4f770292818429f588226c4df9bf6053024a42f11a2499f0c2c5ce56f25d16489a2e554b99105c70fa57657b8d8b724d1879fabdfeea8aa43421d19849a0fad0","priv":"bc6ab78b16b831178cd9f2722bb8afb27664d1967cde464af0b951c3aea935b6","pub":"02673643c7fd4c12f47007a27a56537d152d607225a6d561fd0e18d30064752e38","addr":"3cd7ea7b1daecd3efdd14826508409791d8ce865"},{"mnemonic":"chief drill utility gauge tired alien bid deliver tooth amused busy run","master":"dbf20f3b945820a74898fd73218ed84a61ccbbb28d815d26dea7a7e9a9b0b430","seed":"93d2bcfeea8a87f021002ffadc33b664810eb8ed60342c8dd74a937cee64877d5823c45a4d34dddfb7d4381addeeff63e80a191b92dd7f1b4f0dbf5c5e8006a4","priv":"c38542f0dd692e74e8635dd784fe14d8c70ba931c354d6ea08f1e0b9080d74dc","pub":"0225dfa0e7d37e8903213d8d4900a2e56107e7dd02c66cdb7f86e9d9c0a05a835f","addr":"a94ac8358eca1fdb0ab8ded1cd80b492dda39dd6"},{"mnemonic":"large endless art unusual tornado loan planet excuse dolphin million reduce chair","master":"8f029c13f62099a1d280224f9af2d9458014903b3df1eb65647507e4a5262012","seed":"03d076444f817fb054603f746350c40c0551c3d155ded436620451c4f53ad1254d0b52bb0592197becf9e1fa14bdc65d04c7ab9c5bba7737841d800cb4f7c869","priv":"1cf63efe6800cfee972815f1fd71c68224594557d7894fe8902f56b40163ecd1","pub":"03cab792d05c87c205acd8d78771692507eab35d8c7bf729e2d36551ee0c7aac67","addr":"9f27d874704a788d3e3c3f63f9f1a42c27b83c18"},{"mnemonic":"recycle wine system erosion train make sting talent beauty decide beach pigeon","master":"d702a0785f59e080e2ec13280ec397e3af1c60a36bbf2c92c252da896caa7371","seed":"ffd0dd43668393be9b0949bb5872279ebd606be9ad58f8611ece8dd8b408c0714d5435c771ec87d23b83952af75a6853d94fb0ae88a9b9c1b506e3c0887f3bd6","priv":"d27a5cc824bc9e78ed2c991b8ca86498ed48775aec94dc79332057f2a36536db","pub":"02f85cda3ef9d19e68c4a3778ad99fe008904aa9a80c4dfa8d07355ffc840249a2","addr":"da42d3051e6dc70d85b5fa901e1a4c55ee12a47c"},{"mnemonic":"solve snake loyal grape island deputy monkey art pet candy enhance truck","master":"e866de4a10e7067fc8f6462938f3ea5fa7c88c93e2f630ca81dd07361c646fa6","seed":"82483d5e61c9eb2b0c588b438e24cb0a24922abc6cf0571cf3680474f1eb31496e387ae1c017d5a817c88e48020c5cc1298cfbd78d7175be0a1ebdfbf94853f9","priv":"919e4b231311f40772a47f03948b136879c13f5f0797c939e703b7082d65e637","pub":"0227c29a984f46d5a99c08f31355c3471eea9d231ad414286a25fb91bd8a3a6f92","addr":"e1ef4d05f41df82d47c287ad0347197e8deee0d6"},{"mnemonic":"energy buzz square deliver jaguar chapter analyst chat rare over bottom river","master":"3074c2d8f092896e7a197abaf388828f95eccde75986fd280c9b098586e18396","seed":"70be3c734ae665956abefaa3f94101b5863086c14d8c17ab288a3586bb69aadea314ff47dd19a4dd4295ecdab627a34d9bd56231180b20156b65660082e70d35","priv":"47ed2e3406d068624039f71e17f949c4b7865f4c8d006d6b4a635176b700bf2e","pub":"03786b91b237ba9c1c209d8386ab1fef86e0c667cf2a9a3cb25fbe06927ba3214e","addr":"67ba9f0de66103c6d6f1b799564ec38d4eb9f708"},{"mnemonic":"document move actress food guilt fence govern adjust supreme upon stay sibling","master":"6d110c56993597b6bd473eae083493e1a17b4cb971999b078e4c74c2a675f0d7","seed":"e6a300fc434aca28cb75f2113a8f7788778f2b9398290f82f8e5d989bd002659a645c18057ba64807f0d4ae3c064e56a2947d5aaeb83ff3c593e942fdd0542a3","priv":"fbf0d5b6e019bf7aa6745c4d95c0f9a428d0dd57b7af9e71eb2e39a6628b8d86","pub":"03725d6b7196d57cf1d3b193f1a6661613d02912981225beddd4e1db8de60682bb","addr":"9aad1b39fb3cd3fdef63130bb1a7c8d12bdcd866"},{"mnemonic":"express birth sweet kit special board rose sound place chimney awkward injury","master":"c60b7e5a1c89797d3ba7ce33ba487182144b4203379c04e51ec7ef4ee621f0f5","seed":"48274a66272c61abcdb72d36f16b6ae8a1853d299d9514516374096b443368656ec28f59c9f78f6707d1d1fd78c4aee00e046cbd3df66ee7b143b60e262ce162","priv":"972cf1431308c25e45efc26b86a87c85ade411bf3fe1cb6e88143684910dee6b","pub":"0243447732d68ec3287f154750f1b27df3ade846a0d4cda8e5e5f62f3875de6b86","addr":"c199f50b3c111205cc2c7309c9239393bc2c1e57"},{"mnemonic":"future desk scorpion enlist confirm favorite ill expire evidence cushion rapid staff","master":"0f15c9b1f3210c53c5c408329c3c028211660eaac42f27749a4e8901ee17dff5","seed":"c2db1a2615fb9b849717825a326e5bc2ffb8941755a529cf27903c0c3be806b4261cc3ed7afa8748d87d1ccdd36372fa02f92316f1adc28a354feeda7a0edaf0","priv":"39de89d88ac3f8b23ec57f82c83f9bf12a32762c2df4a612ad647ac9ba287c93","pub":"031abd39702f34958e3366a4d438a7285bb9d5ad5b8a29071ddf77ccea7f9c4358","addr":"a7bd49b9e2804e22072b1f336578334c53b6755a"},{"mnemonic":"interest judge only feel scissors illness quiz goddess transfer person position this","master":"f60677c75a51c5c9e8ebc4fc1320dbbc82e00a42507af218a71812d6f981344c","seed":"6e431ec0f7627bceab5dedf9165968ebfb03ca749aa8d021725338ca8e0e8ab3b00cd0395a68ab955068046c63daea7ba57117ebf7c99b242df8e63d01bfa625","priv":"41af5034dc87e11bb1cca3cca70f80fa057a5839b711927d3fab85048ff8620e","pub":"0321c6b392ae7a49201d0a7c89fc3541bf1c0c1287c051c405cf32a246df97c231","addr":"a71580dfa7773d8a2ce44c7dbbf03d285b46e56f"},{"mnemonic":"foil remember sample infant bread year evoke laptop buzz chuckle voyage gentle","master":"88ba5191913e778f76cbc28850f221e96f380724d29646f7cfd4fb6da20171c8","seed":"64485dc0ccee0c0b13c0bc76e44f8c3a26070a6c08fec558519503ed85769ce3f858978cdcd630b9c017a290ae4a7bdbeb0f66fa5e3fdf3ea227187a165ca654","priv":"117e2b0842cf25a1ee21eb2f244a2c1fcf2a3a6946b3b830707f7c96057616a9","pub":"02b349892030c73203e3fbadf870e1c8325ad0ba1747738706734f7a66e9c66ba7","addr":"1f6488347a7155806da3103c9a82954072a1abb7"},{"mnemonic":"pony super panther surround glow lounge kidney increase actual tray bulb device","master":"54c50d2520ae7023ffdd39740b46d029ae9e31211349193fef33cdaf373030a2","seed":"3d11ec99f173c1864ca6638a27554549c3f619a86e0099e5957972722b2937f5db767d86f5fa0c6b3e0a81d75a9aac5786cbf01f2245b51c9202cd4b4ea88a99","priv":"81741675b625a14760a1ee9e108a9ec6be183c480df05878cb31b45e0d0babcf","pub":"02b0bbfc4e33a79bec82682552fb4c0506528d121ef67a7a42d2ee26bd0b1661ae","addr":"8ec9b249788a123e1301100da2db3db71c913a78"},{"mnemonic":"achieve sail manual vibrant unhappy ripple aisle fossil pledge wrong cherry trim","master":"ca9ac46762b80571c25c2a9a6690181896f86ab3f728b4e372552fc9cf1f7e7a","seed":"4c1cf0279c8a29b8077b5797b6592397112b65e75e91b829a0a9f26b94803a53a02069ef774e7cb5c3cbb0a8e074c69b9afc5a4136e04913403b70046759471a","priv":"09503bd2da16f128b857cfc635cd90064446130c2477004a3870a0c5b1f1febe","pub":"022b34a4abc0a4288805719d72f0b64c3118d924d09a4dad4f26d39ed056349e00","addr":"ef2b6bfbe737261b45e770b5eb42d1950c556282"},{"mnemonic":"injury love grit wait junk bridge myself sister hidden dilemma gas paper","master":"b4781c7979c0b72d0c50c9889432fe2a54d6f08a4101778f88176dc661bb02a1","seed":"03bd824d7f4487af26d236950a69eef9c878361038f0e8be44145e558779d4accd58a8c5550bf5ea86ad169e5258947512c4b72f94bdf60b9135c28a4c779541","priv":"68354a2599b3be8ec6dd827b35290d9dfc068c267f1d89dd57851b22d69c95ea","pub":"028af1d826d45a920dcfcca8d9f86dad10d7356b3027d4051dd4c46ddaf32dc623","addr":"1f356a55f3d3fa48e5d5b36fa31f738bc8f83de3"},{"mnemonic":"domain congress cake cradle express despair devote swing meadow piece border cross","master":"a3ebb93b7fb0fac2b02408c0491f66800c220c7d47190c3c97023f3d6db86555","seed":"15494e78dec34f3fb759000cb0584e42addd40f1794bf2932c6bcbbba20e40a381bb9bc1b8dfd3a231d8e249aa3d51a257590a93188fbf116eed9321195a2267","priv":"1f1ae70c46a36ba70674c7b17e6cf0b8e08bda0a17473d8ae69bc54311239821","pub":"03d7d916b054c003413ac84402e59b976e5515f48bbc30ff8cb6bca7f4ee92c03e","addr":"54d0f98b9dad14550c844bbfce8a4031dd677a1a"},{"mnemonic":"pistol news assist poverty squirrel machine aisle sausage harbor garage truck type","master":"581d692fafd753f080fb83318856ccbf059b74a3f26ba22d4b93916e2165aec6","seed":"49abafbfd7b0c65ccf2e22eff01c78245c764d8ba7bd468fe1baf62a156aaa0a6af143c624241ac753ff8432712ea58f1df9e75cd969f905bea80c15b5fd84bf","priv":"f1d7e572b03a08cdf0ce00908c701053a5804fe566168436b90efd1302bd7f1b","pub":"03882ef7180679169f638a7da20a2b522c948b1979802cf4df83fe1b62581e4d4b","addr":"40bbf61a5ea5b704d02ae13d032f3dff4e597ba3"},{"mnemonic":"field tree license quality chase certain hedgehog alarm melt elbow screen pigeon","master":"dc22c189c264812f22664d39ea1fa2f7d986b981d59f1df2ec6f8582d640e196","seed":"37ab0888876ccb32b9ab73f144ba2a352b31b27fcf6b7f8fcc5a2d4802e7099a199242cd5f7f2a3c3a7d86e8c1abd871ca35881a6a47f605d04a063b589fb0b7","priv":"f82f484f92d1719d3e6832d49bbd493d5f7191acbc07872b345385c32f2d38ff","pub":"0390c62a3315cd02fa64216cfbcc1788d537818eab5cf932a24f9eafe6f4031f48","addr":"8933e5a789211fe61396f29fbc55be6ac7031550"},{"mnemonic":"wish vintage fiction false gap bonus abandon cloth usage hurry toss slender","master":"27f3a0c1791709a32f8ac4fc1e9c71eb24c06e2fcdd8dc959940cc1c8655a5ee","seed":"36932e48e1712c3d03261d432a17e940f1f21d730a3f22d37c1834ca0591b71b438d684c926ebdd51e6431502b8efba8e9c32cf457e68b71079864dcd0d1886a","priv":"bc0037a14a0297d3dd969b365a6d8dde9c6397dd3c8aeba6d701dfb1bc8b24f8","pub":"035ec8335e2f6ef0fa2dc6be7f3271b1117545ab02cf1c8cced03f9cfaaef7c602","addr":"5f64f8eccae09dd614ff9f7224a20eaad60c23d5"},{"mnemonic":"fatal strong idle grief present photo aware various april april card village","master":"ae83fc216ef4c81e2d128d90e91cba0b475be472d95ba77c2ab9cecaa511e308","seed":"3901e5518ac7cf29a42b94de334dc641e1db3b97b44a30d69f3865c050fdac8339dece5f9ed96a17e669d51d59ce856db902e918497ea8523e5ba49fbd06f621","priv":"1bef5a9ab2f2ebb16d9d08b958317a37f252f3de91a70b2c8b5b5ddc0a187ab5","pub":"0250e5876c37987b4189513c7a5dacb31a308c563bd09d7557f2584a3c86bc9d5d","addr":"bb82bd68b31663a75d0d007646e8575934991f43"},{"mnemonic":"error monkey argue fluid afraid hand cactus sand misery close laugh comfort","master":"1b4ea203fb592e2dad7f40b6cd4c8ab53c6a0a7656cb674f9e22d6a0e4e84efc","seed":"3c0544c9b9c32165fcaf9445e49518f8d0a2dc6ad672a01a15183ce1e2188f6fac026cebec0ac4ca58906d5599d781c18b2cd77d32992be9cfb01441d396faab","priv":"e0d0b452b3e1f760762f1bdc692225e7b14277d8227d619bda49bcc608658bb2","pub":"02e7a7156cd53cc7c8b4840772854e25b8c6c532c520770883da9d574c86551c7c","addr":"696d7a61a2ab18eb503cd724f0dd316340f96c90"},{"mnemonic":"demise know punch page upgrade gun smooth fruit machine long nominee radio","master":"b36ae5062ebe21f31bebf7b2078ec651ec579494eb764bedda7169095b73fce8","seed":"0f71fa966c1a56c3e11c54798052789cb0f450761a0227336ac50dc8206f032133937511e93fffd54103132d822b8e717ef15fcd4e68f391a398f14cc795cd76","priv":"6b9a3d2e63d666909216a0420709f127318f809549df2e99869fa70956e41dda","pub":"02d72eca95feaccd5a78567311e882d7b5eb2914d1d844e639b03c4cfa036155ab","addr":"9465a8f3afcc348d661bc198cf8220e74faa5895"},{"mnemonic":"install lawsuit guilt myself arena enable unable thumb domain lift feel object","master":"c033a48b64aff8d6c7fcabfab52087c0f7b9a4228837a7a21d8156358e5eb529","seed":"8075fb6cd8bfcc08f1678c005e9d2d0bcac710a6a62cfea46a1ccbf81747362a0e6a25cea2fa958fd320205e0f95eb8a5884c6f39cc3ad17d58fe49e43feb513","priv":"24e83fd857d2a0ef62052625d84e6aa37e96b14f2c8dbe5294107b647b369a7c","pub":"02d95869834be368c5bc37a45153135a1c4f003be6a44bb9af89e55485118826b7","addr":"631e72e50070f34e23ddd155ca0670c8c8db49d8"},{"mnemonic":"antique insect develop sheriff erosion appear easy fog kind apology stamp noodle","master":"72baea3e04811ee7447249a1140ba62e56bf473d5298b610235ec3178b388692","seed":"e751bd7ff01706f38b8d3a28ef3b1565f20a8ad221d521176347e7791d2cbcb9cecfbc8b51c2e36c303be55df280273711d94c416dd74a7e7a18ae52520cf89e","priv":"0ec2ef082498bbbf0a0686fd232a3b4bec66d867cca50bd0cb0e3221bc9223ad","pub":"03952fb023bb76ea74a6b5b9c4a035b193553a8adc1c0774f7ce4976ee2e8c7fae","addr":"9d63d52c57fd76c7036b882ed40f4a6714164c27"},{"mnemonic":"become tell dentist play light illegal work animal library dragon now gallery","master":"895a420763a2dd6fb934ef8d83762051b00235a83f621f57377a0d63b71bd43e","seed":"05975302d82f413289a1679cf6a69feaf8be733d7fd10deafe1470a08ed5796bfec454adde87e825ea80ff05586c12f5d0de69478cf72238b3e73851f691a3ed","priv":"f94266abb2a93d963a2505da57d66c36d37ea3f871654a0e4221ec911a6b507b","pub":"0256fe9203bb64e250fb0e68a7cd3b0d3c90cfa8f8db06c74524c63ebd66098ea2","addr":"4f73259b06b65db4afde238bf4b42a801178d92d"},{"mnemonic":"average anchor total witness carpet myth life admit gesture inject sustain valid","master":"aa36181d7a04a32433e6f4b1e4830d3e0796ea00b8b03d466087911931c16abc","seed":"e2bf601f15b7edaa2176e6a0e734c72f99ea63086ac463ba2dc317dd70466753fd1334cd27e28c382c99179db6a5b00003124f93a7a93da3a0018838b3b04595","priv":"235e293ad68581b4e24a554704eab59caf513b60b8af6b15fa5d8cfe4265e44b","pub":"03b9e9b4b67e3bd6500e6b0c3f0d0f69a15d0824f236553f7fa12a58111e5aee7e","addr":"3733ba0b6386f7534c7714e9e2382675e0dff54e"},{"mnemonic":"liberty cradle play vague cute borrow around that tongue wave solution share","master":"87869b74fcb6e5d4b0b5c5d53679737f275396d63cfceb1133e49458c9c74613","seed":"c60ac4201963706912996e289e5b6d886693f7277875b46ea166f4506bfc3a2652ae2fe5b466bc171c7c7f09f2920b8ecc6d9c7d2e0ba1ca2cb10b528119cfa8","priv":"a8cf8fb93cdc5c13402976952ddf2ba5c2b37d5756861536df21d02eb7d2c593","pub":"03c12a9f6ffe4d7b01364f266b835be4eda6515d601bd39399f6577c53b1289e12","addr":"cf72bf854dfe493a6c742d6941a4f22fbdabae1a"},{"mnemonic":"hip dose artefact tumble keen favorite truly stand accuse spin opera wire","master":"94ade552d985f2e8625e18360914a5046ad14b6cc5fa6abb4ada333de8973595","seed":"c1d9d325396486e588972df5ed2a281a1cef82184a90c7ed7ff1334e35ae92a15cbaec6d27c47742a28dd458474980dabcbc651d6a2eadcb97dcca08f295359c","priv":"9d3f309f684c2c61a0f05fc88e27894cfec51b738058bdb246f1a9fc65937fbe","pub":"02c1da3c5abf3dc4b52336b362614a1a7a24853759f72fae971b43940500badf86","addr":"cb143b40309bc078f3db3e24009ab54ec4741b9f"},{"mnemonic":"history team sight sibling art over pulse network sausage garbage october slogan","master":"2eacb1cbf92401aa2996b19c77a2f110faa835203cc6baa1c98204ad1740963f","seed":"70b0ab283cce0e7735ec8d05bad6178bbe5a19b747ca1d5d3f5a29c83fb634b43c39f621b11210a7d89ec988b94588b9d8b8f2f4c2a9ccb687cb807e230403ea","priv":"986837f4c2853f751c51e09e514d2d40b36d3995e9561b451474cec6ce431a5b","pub":"035ed85029803a151586b8b3da3f7b2208b257738dc43fd1af08c6f76798e82609","addr":"931b1e70776f50c1186cecec2dc8fcc917974e00"},{"mnemonic":"labor area outside toddler street now same obvious demise mammal puppy boost","master":"720c9f77cdac069406469500511e891b35f1a5782ed330f31ad1dde4bbdfe7e7","seed":"ddce9ca2ae36975072a321de56c51a6ba88b53c226d66006b81d4572af6c8c39303a5a8d56b1626510ad730d578105ee84ac079538118f9cf8e56b43e9da71e3","priv":"8182fafb8ffddf9b157f5a072e57d778e766f7fe5b1bf58ff6cf6bcef46e1d32","pub":"03399e5ef2e4a978be70fe20b7d44201b5130894588033d89e1c0b891576a7eccd","addr":"15a638bbd12f6cce559e0f03312fec99d8f5126a"},{"mnemonic":"coil room slice arrive lady world turkey huge point gorilla course oyster","master":"bf665f511652b19a5ba1b0a51137aa72e392a7149c2df6af31a0244dcdee4475","seed":"2abc97e164bca2a5f45001574f9781dd837304f949c28c102c9de3d713d8cb0443a3be55a324817e53d78b50f0a939346ad414eff0b6307cfabea6023c2258b0","priv":"dd27b678563eac5bd7565e130f6856fecfefe3b1364ee0afdace0408b5ac09a3","pub":"03ff0c0d776d27564be0a465e29923384215370508961a1a7c25c261d09115f8dd","addr":"c4e5450d737defbb8f4d406650c93d79b1820043"},{"mnemonic":"diamond empty network apple radio divide ritual flip correct phrase kidney say","master":"f451294347b6c2035d9cc0c635b777af0d1fa756e1a72c2e41863a753776bf49","seed":"9108fc851316d1f63bf92d68e1db688328b7ae4c5ddec9248d8b5012709dd14dda42ebfef74e61085ae56c64a9125e3a47184320e53ca82684074ea0d359e6d1","priv":"db4465c5493f98c16b002401e28422b630bfcfddf32f8112c10ba71787490e44","pub":"0370a09ad6af977beadc07793db44c7bbb94cdc060a12ab36949bd36a3aca9c776","addr":"b9a0c2f7fe9d2f416596b71538982206c70a38b6"},{"mnemonic":"cruel music theme kid pattern weather become same arch foot host region","master":"82dc215e8155458ad1f3c61deccef305932839a6087250839c41afc36a043f62","seed":"0bf672820da35a6601782bae8a773f4dc6381fda5fa60a3ded12cec851225042769cd147c614f0ad34515996bc1f90675c431a5517c2b5fed80552b2bba59d7c","priv":"a63537932e88d10143726eabb410b3fcf0baaa550892ec17fcef874a2df8b70c","pub":"03b01ab00751243c746766568875b948e12eb1b88e85dbbcf2b538cd65544b57c5","addr":"137ffba20e834d732918f15a7e8537f014d2f3e3"},{"mnemonic":"pass avocado year kick ticket chair pelican finish lamp eight latin hero","master":"5f0d43392033f39e4488d6d9ecf9cfc7cf358fd718c1534c30c67aac21ec94fe","seed":"577d6f62d28192b753fd00bfd3f5af506d7b9d1608eb31cad9f8b08019011dbd20aec03ad7ee731f74811ad060249113b9d2a4aaec0f9d3317a4e72745876822","priv":"5600cbd7c571ddf6d0493f88ea45ac92e33fca9e6644165365cd59f91e68eb21","pub":"036f3194e13694cb0cfa7af94b8a60cd641159d60130fd114cb496f5b828fc2132","addr":"d3b8b4027a87f928323589e9f5a85330a349b821"},{"mnemonic":"deny improve give spin carbon lobster shell lava romance jacket village canal","master":"8b58d86d8564a0f23f0d38e08f50c68ca12a7c55956ca8f34cf790b7260dfb60","seed":"1d5a8348a7c66d8d7f6b5b99f844a7ca23bfbd4558497c1eb72f6679df2e0a03404e99e97f68a3c0a47d56e8fbc0d565f4c1bd0f7da014845038466c7bd8386e","priv":"eacfcd11a571bcdfd73a64a8c0b935fa343b21c0044f8e4d9d2d882c75db1733","pub":"037fda0cd490d64febaebdf19a0236a1f7a1bc6d523d065cdb2626ca122e9d50a1","addr":"9dfc787aebcbfa396a0ac4fe9b1513ceb1cda121"},{"mnemonic":"target tunnel liar bargain bounce lesson silk lake artefact coin coffee degree","master":"86437b39d0a0db7f5b0a27f627146b1ba6ee9c2cfd4fc12663ec3a2fd06d6495","seed":"fe9740cbcde2cc458420431b44c8158a35c172637b748b4051b79dd1ac1d100ba0cc60d4928160ce8eb6cdd5232152f9b90439fa2f4a3aa40f1f884d79f0e520","priv":"5e56256b91d4e255d9a64d5e3fe5fd0cfc2eb558b683f2289d773d09008a41db","pub":"0273026ac3c43ee59dd6d703efc5fac4d31e6b6585e27820bd8d91185dc399cb36","addr":"a0d89229e673a6f6962045c70faffbfefb0764fd"},{"mnemonic":"rail ripple tuition once odor barrel winter antique woman merry nut offer","master":"33ed9b3e5babe3904c48a79769a0d8a8285fcd9b7c1154316429382876726bad","seed":"595dd0a7f36a71e38b37baf88967b9960baacf11b249edf1afa2f2bdcf68a96e867644b712a78173609202b7d8b7cf2a3cc82014ea28bb955ddc46027dd10f7c","priv":"de65d8250e9eba67bcc69a2840187c2ea7c64f44766c1b7ac0b648afa0f297c6","pub":"031a160d7d3b13d9190c2a0a684161bd00d7a3fd6f472368f5cc4bf5ef3f84cede","addr":"a0469ba7da8af387308cea748507999662a7f76e"},{"mnemonic":"mix you afford area also raw water fabric mother industry mystery victory","master":"d458f52e08056473bdc1a73f5ba148da38f58a53be4f7d5d8e5d2974da6474ef","seed":"fcfefea963149047cc195afa589c8a81189eb27bc30d6bdbcadc5a74495400eb12d7fbd3cede6ab7e67c42e308dbcb4f74cf2ba1335b873c8bdbd13ff19dde6c","priv":"d5ef3fde07814e0967f9ec90b44a749a1c2f4bae73f76af2e10a0f73681e58bf","pub":"03388e81cbddfdbad87b95d800bec6e1869bbae59b2098b51e083e97272ef82fe6","addr":"3570a61894c36414a607cc787e0eafa997ed0506"},{"mnemonic":"find fade drip oblige either deputy noodle trial hand clown athlete chapter","master":"1131d43aafe4c9a2314a3c41116a0ccc68080cfcc525fca0acc53d5a2d4c80fe","seed":"207bd6fc9c91ebe2521cb131c261de75c71aa28935feb420a2e9603659826c326e996074bdc78b7075bec54f4268c828ee8a62aafe993cd7cf481665a2303e29","priv":"22ca0a4c09e5d6a96ff37eae29507b62715a643d3ac24389217e35f4bea4d9cb","pub":"02ca3c47a5367b7c9d83057333cd716b44a429d7034bda65761ee1dc503038d520","addr":"64be7f76e0669905f362892b53491230aa4c6834"},{"mnemonic":"anger level recycle lemon material pear robust decide they hammer coyote fade","master":"0efa37efdf167ca18fe15ceace835d75ae94027d7cf4186b4ac7bb5b91d54fcd","seed":"8838fceccf5c30285bfff02ec64ee34d7518c30b9cd722ab8a732d1ced8135fe1919af7e3afab63a55f1551d43d4222f1f62d0349ec185e4d45076b849de8972","priv":"16f41120d317d7387aad821cd0374d715a1ec1049057268b3ee090210a00a6b2","pub":"02b13c5607cfd0675ec1f33f82a09a9cfd88ea6a212a84f9528fba9857d012f5fb","addr":"4cf25877cd8e38cf5a37a9dac81a9222e8cb5461"},{"mnemonic":"fall run bread slight rhythm flock pipe employ fault side kitchen position","master":"89394aaca338752755e33fde878862096328720570957a7c105ddb90599dd87c","seed":"a2fe89e4a22f8ff5dc458ff49870dfdd7be85afb9fdced1165efc1a2bc93ed44e4d0ea1be438f347f8bf7c9812ad6aa31f07c8eb3b5ec7cd40e37540876b12bc","priv":"c0c189d49e3735f5eb9c7007e1e0a841127998d7c462deaba60912a55c9f0de5","pub":"02199a2f84eab6e63c60f7aeaa56b5799c6013df61e51fd2b9e2be56e4d6e5b121","addr":"085ecfb2737f0ffc78f1ce0a15868b24d09fbda1"},{"mnemonic":"judge soccer grace train conduct duty arrest output roast candy total vacuum","master":"a5fe2db0c41ad910231deb8112f6e10998895d48655cd77b142ad9846fe62458","seed":"4ce2ea9a4984030e65ab6eaf3ce543a450881597d8585c79a66d324606c00cdcb2c3cba4fc83160f0426dfc5a89cd27a9c9d05f94e3a04e3bb550bf698076b0f","priv":"b9eceef7003d3258ec2bca498b34d3181b38aa493f8b3b1237588873751539e3","pub":"02bb8de097658d0e711f875089062c135df56e33fe97e2c828da5a5023ba634765","addr":"963bbc3ce38f6bcf2e15a3c300e7eef5cf2b648c"},{"mnemonic":"lumber lawsuit animal member stool claim know frown knock hotel noodle pulse","master":"fee5ba9a343f60a5f0f38b80c3208908e2db6f03c8a37dec5cf55d833e913fad","seed":"e1fbac7d494d3e1def8d193a71872395f24b8d62bc052ef2aa6a09220451ed59b1f74a2bd02ddc0fcc0ab0f4ad65bc17462497c431f2689d6bb9490573ce022d","priv":"8dfa11b3935e4e660e246fa935b438bf9aa9b5efded0e62db64f61cd678e71b3","pub":"036dc946490687b821115c280ff113002a160325f212b2ebde71628ebd27e418eb","addr":"3e6e6935d3d9715f525fc9a43eb1e7465a1178ee"},{"mnemonic":"city drastic advice adult taxi build local olive unknown leisure bounce umbrella","master":"0aecf2bf80c660dc6e9a987d260fd4f38daf6a00979e2e6ff0769907c6cbe893","seed":"f66f4fc74817a4edceed1cbfce8986d1cb9c9f77b23f5b33032616879c452e64b5b598518aad9216ff0b210b38cae0a6d417b7200df3fd7f2c8cac9cde2fb946","priv":"c8bb1e0db0df18c9a4254cac791a309045d9fbe6daee301d431ad9dfbdbfec38","pub":"0376d3fa96698c82b0ca3d704e8754838a80f05d01c6cc99894640da9aad067d47","addr":"9532ab7fb7493cf19a9d2e61a808fba45dea3ca8"},{"mnemonic":"assist obscure army approve salt tourist program raccoon coral economy connect around","master":"27262a815e351c2e583835dbcbb7fce7c5f96d7b8deec45a6325d02b095135f8","seed":"72315d5e5ae5936c29173566fe17da012160290050475356063fc678a8a41530edba5dafdc2404c410c4b5cebe8dfdf5cd0f6fd855d94a08ba7e856c984b7371","priv":"2849c2468ce054e94252fa34a7e704e04042dee4bda5fd82d6b38e17d2451c20","pub":"03a278a4623f9f8d32bc8198c694e961868709bb5f425f6000413e6be33cfab059","addr":"4bb9c78ec04e00e84fd3310d101f3af4949351d0"},{"mnemonic":"limb nerve equip power pyramid nest sure kitchen lady burst pig void","master":"47e667f4fa090bc0f8df1db86c5c7f835d7e43b8151b6ae51ea12b917d4b23c5","seed":"ee38177c8d3f2c0076cc84887f8ec20b9b6a874d67a0eed6dddb889c1c7af30ee9031215b6739d7858a3ec35253f0136217f888c20621b217b8aec2a900bbb1b","priv":"153335c0a20adc5347c99b869b1f1b2a30eebd4e1c71082b8f16a4641c88df14","pub":"02a2f7b5767ee89ba4aed85a5c198b9b7e62118433b61bed2f85c843576428683e","addr":"50c74e9486961c8b0bdf5b2289f5484ebd6554d7"},{"mnemonic":"toast fame primary broccoli valley fit chase critic life absent crucial chest","master":"f4a62f84c5ea1fd074494763e0a541015341f6e96d965b884fee68c0ef5e4f33","seed":"27302ff242190977db86f09e9399621c82a5f953e57dbc3a01a6c38ce8b5da4a61b0e6d5bb79bce239e5fe59f3dd12f62cb634f9347afddd89680b592872d348","priv":"7ebfe174b48e60f3809ee65cae852fbdbdc292fdb934d2dcd101f9f9be11f769","pub":"03b2b6586fe30ab7d00dd7a4da4bdc74c8092284f9d7a3e78eb9f298dc26b3b856","addr":"bfa414a410c1cbe1566a050fccc48c99a9b3c973"},{"mnemonic":"live mistake embrace other bar tell promote derive assist deposit stable chuckle","master":"d8dace20cfcf215f4cee2e55c6b9b8f65225291d629cc8f7e456778cb2f5b5df","seed":"0a5c716e273df360383a4e29cf2e2df63f47012be5f0acfac32d37241bc5580096e1538491b5daa0cb4929807a26b4225afa988057cd195d8180f5beae9a7b35","priv":"15330ed9be835c3ab25357f437b5809dad522ed0c5e1e19dc78ecbace52def0b","pub":"03b6ee1d8c8a1fe25b6982ae76008d65b5a1ee20a3537898d5c3ce528f55544315","addr":"b0a03a30af7c4a79cf777c64a86d66251d0b5b07"},{"mnemonic":"orbit recycle wedding rhythm write come apology plug blur pave job rice","master":"fc498e657b1ba22254ab35dc64173d6f9c790501b8cddd18f1edd625964c8f57","seed":"af14771135c60a6cea8c4790a008ba09c890d826c8606c94c5cc50bc8eb36f06bc8eb374fa18a67d738adab33cd849bf1d8bf744a7b33197055c75e924f8b1e8","priv":"94442c669d73ed4cfce1b2a87c76696f3954ff4fd3a867232c5f878f2fec1737","pub":"03db45a44b5dcd8b34b4a5125e54811b800879a45593af61a28a83180f75817a1e","addr":"20505c7aefd22f78b05bc45cecfae800fa1575bb"},{"mnemonic":"oppose brush collect swim cup age gate forward spirit boat century annual","master":"c156132e600a1d3c359813d2d3fab0cf5ff13d8713569cb3da35ec78a424e193","seed":"8a1ce5772eeba927d2f237acb22b9e86ed2fafc89c18e33d1fa040274d1dbce37bb2e93e1ec8e2dfbd32cb299fc966e43567f11bc0022811e6d43becb43e2e1c","priv":"f2c9a5337186920bd738336ee616ace6f7c21b68e731c8cd84dc023c89198525","pub":"021a7131768f1e6f03b1177153f36815503e411c54a6c33ee6a20281fa8bfbb8c0","addr":"50e772de1a2e1028fc46d8958f96ee5802d477c5"},{"mnemonic":"genre seminar green olive grow close siren sadness farm promote bottom few","master":"ce632e9a0596520a05d8c096928811ded1f9a09b461d2924f9e4ffaeadfed8c2","seed":"dba3b4f2981a61525481c49e34db737274b80b86ebd2eb6cc64b05d8e321f871a97938e56abadb178688373b8c29a7c752d7c53a55d7e26d660ca948c8ea76cf","priv":"14e58e498bf7d472247df7024c6465db0c2f7b390a65dd05028b42576a3d7678","pub":"02ab7825f84bb603bddf4325c2afd8f7497bd1d22b412576e8155f1fb91fb9b777","addr":"a2e64380682dcd5ba6a4a5e7347389da76ab39d1"},{"mnemonic":"radio minute vivid clean cost gadget ritual front tilt other valve now","master":"c1fc2d9a7484bbbf513ce72d4280d4d6f01ee0359c59f29a2910d44bd06b41fc","seed":"8d4a332dca82af94bdc825c3ab49b970c5a2263e8a07e848841392f4274b44cbbc57908d6522369b32a584de1d8fc012f8f7f763421cc309678386f593e2f819","priv":"fdb87e0dd6892d1b7e29e59dd43d7cc5bd7825329e569d5dad839836d551381c","pub":"0274c7216f289b5ace0f684dbd8f9360679909aee0244f5f16b65ae33b1f0d9737","addr":"ed20a72a5800b88c62873ded8f5e31bf0ae08944"},{"mnemonic":"clay verb soccer near actress august like venture goat rug brief scrap","master":"d888a8d4f3c351b37b6bf708f47ffa1f0d56dfa35f039d4c8c6e49531043c4f4","seed":"470399a3fdf3f7f113b6996468b4cd22524b05290e7e91dcedb0f8cb6d2fdd39ded069f3faa72799ed18d0692301a64a214fec0cab41b3bae69d121d06dfb2af","priv":"971aa66792510f25849cdc1a7ccfd7aa8fd82a0f42df4a947ab675fd96db7022","pub":"03f7c82b2ab42b8e221f661ee3eeebe6231f5d98ada0133431715db7302814d448","addr":"2d306db9a75411f5ee640e2778daeeac539b1a52"},{"mnemonic":"rose team vapor oyster embark shell six object rescue village rug retreat","master":"471f619784e65272a58248f67516ec85a69dbff66719eb5bd17948c4e2e27c94","seed":"39dc2669bc21baa81e45013e856e8289b858778d3b5ab601a26115beebacc708236e742bc105fbba968e364745e34a0c9fda0799b79b859c02efab3c3a4c7204","priv":"581e1940af1601b7ffc624a6465519cd6959234d112353d3a6f2ce4ab3c75711","pub":"02ba88784648b8476c55f9cc4be65140c478b835d79fa596abde69038f9b5a2b2f","addr":"bea24bf839a66b47497014c0f29f98bbd506e9c0"},{"mnemonic":"blossom turn knee oblige digital mail phrase fly soldier unaware corn journey","master":"d7f58c53d2b777e2f1162bf97573c03446afc51dc758bfaad0468c0edec615e4","seed":"f13ee4c99a6c39751bc6922c9be96321c7704c36ae6537f13146b4eda938fb8b2900e44e901223b2906db6392617d4e156554da83644731ff6e56b0b3fef24a2","priv":"c4231def1f2510c02388455fd0d5a2ccc80aacf2faefafb3534544f1b75630d6","pub":"02f0e5922755d841b79fb76f0f129ed3d10175ed4c377d02403cbfcc1c9ffd9c64","addr":"8c664b57dfede7168c0bde20acd37674a1922dcd"},{"mnemonic":"crisp joy brain treat actual later nice ensure village bind powder merit","master":"01058624d066cd1e0527da16937d9ad9bee8b7aeb76c279ea53f5c5d7e56f6d8","seed":"389060cdd3a98f5625f373a0a536f70f84cd0cc6a7d5bd8ee20fb94a2aab9652bdf61af9cc532ebcf217fb7d860c30ac1ccef4fa46b0478971653a42a1879811","priv":"7c0389b4564ae01f4c14da09842984f9b9720fca2d09fceb0244623db5cc07fb","pub":"03420010f464371dd52a34cc193d55de94a3ffb3e746c5566bf8a8e6bef686efec","addr":"c9ad4a84c23c753544d4c3972b0c3d2d86ae397f"},{"mnemonic":"three scare horse film rice divert frost gather photo weird nuclear hamster","master":"b5107f515bd7ce629e85b64264b2c9ec80595816d9bd47f04eaa6971dd565d8c","seed":"ee242699f11339f305818f44a171f79b174f45c09f2322f53ddf3094e830fddbf4e418bc3ade62f03164d8435036514791b936ccbf5f405defd33bf68984ca01","priv":"99513bf817cf2726237c70a70cf6bf5e2ffae1494b433e1d77c8b9c59a3e47e0","pub":"02641d322b89339dd17528573b100647bb082e91d7cf24bfc897e90b20f270f791","addr":"d8545d2e2a4ab61af14c04d40fcda9ad39bcaa33"},{"mnemonic":"circle pond sing route tribe grace exile leisure health cluster prevent year","master":"5cdab97cd5aecd22d671964282f6971ba4be01267c90677091d6db6b5adee0c9","seed":"929117b95286a76aa839e45e768b9f5cd23be5bfa73f929ab835df15cc1c96c2c57cad593b7e396296c0223d38c38b03a4ede097bf3b188a11631537dc6223a5","priv":"35fafc87a67c7547f256f7bffc5b19395349e1665e01a89f228f44af8086b118","pub":"03fee2e799ed5232ca3a29238e0140cfbe5f1bc6ed2c1429c0914c4000ad59fb3e","addr":"2bf9cf4c3f34de93078928aa8c6192450a29af02"},{"mnemonic":"rebuild address giggle city tired dice sorry danger onion cry cheap sock","master":"83df9579ad9f629ea3a09976302888929c52527620ec7041fc9d4e36380fa953","seed":"7cd7ab5cd9f450b45515985a2af469765286510461f42d4ee5258608aedb40b7f60365b685a706d0e0d82f775da38f0171bc8be56543113805227c5f9526e7bf","priv":"a1613406d358b4c1db8439a3e69a4d7072dbf78e06c8a8b72c37425761f874ae","pub":"0395d2c96136983d906c50caabd2f61d1c1b19a227549f7bfeea2ee327c5cea276","addr":"b51131cafeb358b0f90101072a0bd70fe5226726"},{"mnemonic":"toward turtle false distance spider plate aim daughter team jar case option","master":"229e0c7738aff8a44fa62ad310f3cb18f6b94610c83faca246c428c26f47ca18","seed":"405cc161455171571df109c3baa2b3ae25a8ab9b3c7affe9b09b32a755ea443ee590f722f9d2f3c39e9e828a2f276f46a6f9b65b024a11c6d9ae76929210ad23","priv":"095f70fb24f7f97994339cf37a6afc4e95f1a421d9b076cd714453ba2dfd29c4","pub":"037fee3b9ddecb153acb32358781fb541283c3a61ce2f25366b199f970a87057e7","addr":"f3e1bdca0ac89c2f4036f07cad45f65ecc94bd61"},{"mnemonic":"mind mirror athlete assume piece surface raccoon struggle inject horn body engage","master":"75156c7a3676b6a756cf4eba160d44d94ecbc6ae06457ca714f4313367e8493b","seed":"c754f1684d8944deeaec89ae5977458ea9843b4bfa0997a7c1213633c6203a154b65f2109e4e2746735c85ffb7dce803bcc57b38cd617b43345c2b486ce44ebd","priv":"c03717d4cef8ebc0e4bd6d78ab5ff3d5975da9919fab3cef3249d329d488fe28","pub":"02638868a04c039201022036284a8916939b6432f4a469c132748955f7e6dc468d","addr":"d7906686be6e6b9e1dc032c9e89d30ca8768c698"},{"mnemonic":"armed lottery garment beef manage knee subway market enough end clever edge","master":"08432ba7a4152d14119d22b52f8913f2e221237f125f58e4df5e5c87da81a74e","seed":"7660fa9d42eaee32aaba664593f1271cb60e092a5758bf3353c03a448360ccd74ef45b01612aae2637aeb86f8d9380bb8ce6b9eef5e0739c85736cc50b612d51","priv":"4f9e5ef095a07a939d5f3296b211fd938ca90d21f52640da2272ab812947127f","pub":"034c3bdf7e1bea7d629e2b1f82371d1d7d04bbce016317bff603a0cc2682544a93","addr":"8ecb13c1076cb132990cbd0efeb072e58fd3d1bc"},{"mnemonic":"city chest trip critic advance sign push patient choose pride lucky cage","master":"5069d7379310d03e01f740871ddb8043daa108e523ee5c2aaca252d079b9b99e","seed":"5459d94456d6fec414efec5630285ec7e05293d92c8290a07b1070b5a7fecb8f7356beffc82790b50da2fbfb28921bbdc64ac0d94e1d565f6ead799c1c04e7e6","priv":"6d334f7f362d2dfb4e7af20f7fe30887e3c91186954a8252078f215ca22e4b07","pub":"03fdb94e64855c4c973fee4157d3949bb9b840ead95906a672c1d08390e3be4883","addr":"bfa8840559e159b5cf6e7831c4696238202171cc"},{"mnemonic":"fuel derive exit magnet shallow salute clown prevent inmate hurry conduct series","master":"0c721f303dc4ba98877e76b3c36d82a82639ff6c02318dfd4547943b39d7fb36","seed":"877d16863699cca3246681de6e1b9f2c4b59ad600341c0ce16dd8c95c1f5cb1964bdafccff0af5d29eddaf9bb564552499234eee8e493549d0f6d2cea0a71695","priv":"b4f009ace3092938c51c2d7557b52900941c6dc437306883a89a51e29af04900","pub":"024cc003cb7be1724456fd703edfb7e339285883088e97247d83cc64e8283f796f","addr":"b2bfd256adb5be91b637eefc2c20efed75659f8e"},{"mnemonic":"soul junior garlic chunk eyebrow betray heart sunny average coast help champion","master":"7c420ff72c69dbc9006c4969beb830d7fbbac17dfedebbb7d7852430f17490b3","seed":"34ec95dad85e66b55bd9bde227e68b86298e4bb51b3b3514ff774298ade39fd769eea0f2433392a09578da35738cdaa31a0d71cf043204083006cbccb9ada2a5","priv":"719c2fbf2db0df066f36fb31275ab75a3905c52b04335f97f778c540e103a7fe","pub":"022333046c912253a37832140cd42243733ccded5a7a13f20ffd6e59cdf19443f2","addr":"048677f2e035a21eb91d40555f0c9ff53f335660"},{"mnemonic":"private outer service journey dry exact thank ability wheel destroy blade scout","master":"6d87dbea0c85b9ce5e67831bfab7e5118ea85d7e9103140842ed4b7aa46c2b87","seed":"d0fdad93d2b727475db3da1a5cee5a4dd8c9a0794a6a73b5c3d6078541df7e7717aaf0053edf1d4a670dbddb96a6085bee0b7bf0c4428f09bae98a46c93e139c","priv":"aea666b18ff888190a0119fd38604a711a66d235bdfd514378e6a52efe4067da","pub":"0275d06c981e89fc560ea25164baf2c238b6fe33bb65e78952e6912b9cf991a65b","addr":"32aa41676d1ab5e54575d0d13f673c352f0f99b6"},{"mnemonic":"diesel suspect urban fatal total motion other opera taste shock prize lesson","master":"6760aa56bdd6d9a29615c425d934b788ccd70b80066c85caa2091e3861a5508b","seed":"bb3df25ef6c4ac87b93991710c0b927a24c47bfe467cc3d057ae3cc5867bff989d6e8df8b790b52661ad3d310730dc55ba8fdbbda118d3fdf75a21750f2f8089","priv":"399d6d98eb0cef3674ce7d155b426638ea4679fddc624cc582e13b7f2927a8f8","pub":"03e6082570bd65f91edcdac9564f3d71efe75a4bbdedc379774ca9879fc8a57cf6","addr":"d3a69b264f967565d19aa3be68b6a20ed054da40"},{"mnemonic":"tide rain throw pink treat sphere soft season network good left potato","master":"a2f3cb3671d233a245fbbdc8b769089035cf13a9312a78826972dbb99eb4e619","seed":"0fa23be9b8c9a11dd03a5d6c1677ef78526ff2ce3e12de5195d2e1b40f2df6b90515bbb6eacfffc2e9b82ff66426fa1e3a86b51e98a733d054c4b58b6b5e7025","priv":"34fd376b792658501ede9f9f2726a94f8763151e20a3325d05eaa7e6b92b19a6","pub":"02f2f3b3ca1654334091af786f28f9b64dd599f188902cc24f2890edb62f0f7527","addr":"1f06acf38751a45fc0734766e3c794547a31434b"},{"mnemonic":"hold forest select elevator skull warm crater help sing liquid foil burden","master":"20bdfc70225db1ad0d9a1f53a1558efe992ceb7001f181a0ab5a0394851dc81c","seed":"8839e0268e51734574d033b2ac42d3de449819e0e6a916b9f59380d15be767f5a491076bb4e9c2c586cf92d07812f7338400962d28a06c2218a3674bffaf586a","priv":"8c1f88886e7ee663a9df9ad3b31871cb864bcc1ecac7e19bff14344423581796","pub":"022dc59925b511f1420f897805f13b684d9e91731c88672121dc59308ab4fd7c12","addr":"3911febb503ec0cfe4bb41bb6e9fd1924a027aca"},{"mnemonic":"power orange shoulder stove sunset during jungle buffalo funny enough immune skill","master":"51384a8d4d886c1f0a7b4b1938d798c0463e44fb0ef05f6392d5f0c3c0c1813d","seed":"ef0f86555bc2d06fb8b676196c8d046aecc752a61a95d4783f8e90cd0a3117e08c11171214fa63a8e86a8280ef98cf4cf780eb384eb78ece725b94a261770268","priv":"e644ce7c5f3541acf3649d8a44423d277301e519147f50be97dadd4ae1d629ee","pub":"0312f8f9435994bd6156ef158a80b721e73dbca17671aaac7f7d67cc847bda7ed4","addr":"82167c6542716e9c1a072228a6159af1b02f8893"},{"mnemonic":"black evoke reform inmate similar wall machine deliver gift photo axis mean","master":"2cd652f239c8ee231e516843dc9bfed097ad33378563e2cc50e07a48cf0bd28c","seed":"02da5a82f2f4a6ac1a4a962d5450899e949e702f96eee80f364faa7751b50a55b438c6e4f4fac1b6e495b06fc55f63ab9ec1d288df3d62f6644bd59dacbcea1f","priv":"f6566def1b32c210a1369b859cd8815efcf5565a2e1334afb0663115acbb5724","pub":"033055d70eb1aaa92d91e04edae35bdcf2dcaf4bd80cb2f798f2be9bfb6a6fcf3e","addr":"dbed2e50e81e7b093ccadb9cb1ec9ad86837ba09"},{"mnemonic":"sea snow child feature gadget oven this lake post entry essay alpha","master":"0ca6e7a0b4fa4522ed7b8ae0834949bf8a35f7fcfe099c237513d7ba59d82562","seed":"94a9ae63647a2b63121725f961c7e56c7c6b6985a169c43ae41434c3155ccc8244ce10d6376fcc473d7663189d51049b035e5e232834b470a404f24e286e88b0","priv":"9b029add6a255727c4cb80b868975e95086487b3a463cb35870a74414fc6c14c","pub":"028a44cde34153397149442c970964c1647e214fc15dcb345c4025cdc26cdbd3a8","addr":"a23cebeb59b458c97abd67a3e32387bbc56545e3"},{"mnemonic":"couple regret airport shy symptom shrug mom sail insane culture detail shrug","master":"37711c29531e793d6a5e2b4931b3aa0240ccef541c9b8408c29bc5b68eded038","seed":"9c054a9047e66665412432f402f94e0dc5f87d7cbc1a32f6486cd928bc2a9a0aa898ab91fd3aabb962af985da396eae7a0d00fd739650bffaf070c9af44721ad","priv":"b9f1026e086eeeac648193494b398770b7226d46221cfd7281e5519e81fd8fa5","pub":"02de158ec50efb1b8567d63331fd7aa66aaa59ff26a621a59a52ad9341330b028f","addr":"aafa96d9be89b09030494856cf6275b8e9eb387e"},{"mnemonic":"mechanic sadness easy credit eyebrow sample health pyramid bargain actor power glad","master":"68c40248a8f7049062f18ada91f3f2166b37865895d4fdc8000268dfe263ef9f","seed":"d28287812cbbf2cb8509eff491ac456ed199dd2dfc8cd3c93e05b0541c154850f09f686a573994d41f163884708db205b37afb02752a8f0b2b9785c6eff504b3","priv":"250d326d0c232bdf26b6eb8e349ae5b49e30b0507fcce0be1be3bce55b0f7645","pub":"02d5713f20005136dcf9d8653dbfd75bedca3f42b2682ec9918b92394f2b685b13","addr":"409ab6606687cf83eb6c2388d6ebe296b4799967"},{"mnemonic":"mercy spell despair dirt board clerk about symbol supply provide rigid evoke","master":"37a0b9c11386b995b71a8c8a5e150ff76d238779b8148a2137e5d4666fe9fba2","seed":"9e3ec2ab97061086be1e02cae7a0a30493c019247411a7e7271c0c5f7f40bf027ad3230a1f113580365c82549ae23c024ad85a8601a30b6f78276744ec803a35","priv":"0385392be6a34bae1ff02570948ce1217fd11700ac753bbbbd47a1ece41ba38b","pub":"03218315e18c8a5128f74186223d32ece9c3987a0427db95ef51eee9acda922c03","addr":"725139ec60574c941c133ad2e09e793c1cd32cf3"},{"mnemonic":"emotion exile anchor charge silent nose family tube view lottery neither razor","master":"d8e841a6199f937fa9bab3c3905db51899d456f9caa5d85d9d930f9981ba6ddf","seed":"c8610e5fa0b9d9a83610c4458129802434d7045fe44917de29366c6d900f123e5414fda889e21284405c4c64fe745a36966ee86fd6f61d1dce6f809e0e63624f","priv":"b567d59ec087a81214968756017868e483e62326bd7239fddb27586745412349","pub":"03182c009fea42d30f31f24b6a5d251b70e72c1262d22f25418653cee5a226bd15","addr":"9f5d2ece004dd9ddd79b164c4b51361eceaf077b"},{"mnemonic":"orphan attract pair execute fresh interest artefact shaft sail advice vanish moment","master":"b58a705076e0c5aeade31776d78d319529bb76ce748aacb266dc910595dcddf3","seed":"a156c3c4b6241c4e99bb63dc221b13fa77219f2419f7c33a7a7752b5dd89d5be2178b6c2de2225292bdd0bbcf3b90bbccceb93ea65deacc866a5a3da4944ab1d","priv":"857564d0b2bfda18ecf561ea17dccd6d1bec2100e79b6adc8a74997b55f53126","pub":"03eddc58dac77538639745d167c174b907a448072ea4ef9b14563217716fb606fa","addr":"b3a656fa40d9a7f6471cf6dbb00fa0e2687df914"},{"mnemonic":"guilt awesome champion wasp execute purchase better mirror such prevent stay actual","master":"ffd1b0b635383f57d0086c1e6e4925d82a9cb9b310d0757afa8d941a13a1d61f","seed":"c36560913942649932b4aa8027520c46155135b50d66b0c6b33a7f63272b3d531946fe3aa0efd22c6e91d5e19cbed5183ac2bc7a18c219ee3e47dfaf35ef15dc","priv":"d5d35667bd3f54b40858f3cb4c6f09feb889f11d6da386935fe8b42e3a37f58d","pub":"039cffe0fa0a30d9ab9b1ca354ace89b5c9cd21d2653eb5a7a8c5b66c03912bc8e","addr":"1f2543b17460c4f7c2d53369fce6383771c0f7d8"},{"mnemonic":"pyramid soul ahead tongue observe void whale sense keen feed today abuse","master":"272cd80e4846e16f0449c68c8ed4c78071613b57660b85206f716203014c9231","seed":"2f342928932ee8e588bb75ca7cdcd7cc61f32eb317401047cca5b4133e963776ad86474999f9013be1f6cd947cfd9cf4add3be93e686d467223864851ea71751","priv":"d52cf3cfd4e6b6310bf47db08d27ebf0109582f78419d369c4c5da596f22bdb6","pub":"038f855f837abe423fcea3ce81efeccc49da313c71630cb08089956afb73e96e95","addr":"c888d0e5e1840b29f6d85a64cd9704221fd3046c"},{"mnemonic":"speak mother wage grid column movie pluck deal bulb stem okay own","master":"60b4e8cd422ac64986d88f4412e0c694d77d09d4469b06bbc8b4d9146ca5e412","seed":"ecddae7245f9ceb3b2eb324a78421ba99d3b39819bf394be90309cea21d6275ee32a068aef8078fe3514cde61a69e31ebe091669392b5c8a442451b895591ad8","priv":"4695ad7f839e5997df9747bb6d4ceffbad85f6bb26d01c328e6c6e8f6e68800d","pub":"038e3e274ef62db04582bdf01f4c443fdc5b590da7d2c0f5f1d1d55abb0752d440","addr":"359c60c1bfe3a11711423effbacf7d857d39437f"},{"mnemonic":"unveil toast planet basic limit bubble lawsuit grunt lonely favorite inherit write","master":"32bd1431071e17e039819b0f3d9d959c5b88813cf49ca69c90fd547a4fedccea","seed":"d036fc1412c23cd5406860b96814ad9f54359e103834f5d9d1e5f79d52b2e0a8432c4ae705d2fffa9d87d4946dbed2c847a4589542f8051cf6e37689617964c3","priv":"93fac9e5a9e35c2138568864525be7a43492e11f715c097879033aa4019cd723","pub":"03b0e30e8c5bedab8f9ff703df5c9440855b96594e19a367f3c1da13aff1f606ce","addr":"0e70b83293cbdc8b5e3cbec03cf2d0602f221bb8"},{"mnemonic":"cereal forum again rail lawsuit mandate above vacuum hour tiny rain mad","master":"1bfbb49078074dcdc191bb798d3c02462d736f786d7e91461000fd644aff7cf8","seed":"2aef95fae13809c1689d4b5a6598ad4e642ec6373dc6a10b6f348718360e3397eee9a2ea24acd344260d4002b2e7857e71daa1e7111f943ba036d4d94deaa339","priv":"75d0ffb17edca54a389371ddfbeed3a930ff3ca88ef166a67101b9091636d7a8","pub":"03c1ab2904a55bcbd56d1f1b2840a4b09f665576e980cdf2fcd45db21c007fdf82","addr":"cedaa1fd49e697c467d8ce47a2d67ffbfcfe1d56"},{"mnemonic":"infant glad torch shoulder benefit pledge social indicate present deer glare hope","master":"fa580a50eb13d1df4efe98cd3e86a1927e4e9b8262a279f2e782d298641a7378","seed":"a3e088fc36097fcbb0286a2103e2b8f8c1b3e0f6d8521c82c2c93fe06a8c1b97748143b02d9196f095ec1be5044aa0d89b39bb131c4488858e549879cca4c8f4","priv":"61c933db24e871ee66fcce148c2ecc3fc85def76b1e6f8ea784001941deffca3","pub":"021922866e34e3d7e28c1f5778c70e7b8742c2c9151ca5559039949f32ff0854b2","addr":"e550531be6f31c18a90bc6add24c02895e444794"},{"mnemonic":"laptop vapor rotate chief frame trap duck satoshi obvious pen oblige bubble","master":"239c6fca9e52e705ba0d2d9190a08748408d3a53ba0d19bd51fef426b56e1ac1","seed":"15a573343b11562370b53ccc9f11be74e183b1a341ee922cdfeb8c84a4dc914d23ed6a7f58ab451cf57d5f610c8ed9f16e2072a71ab8edd82414fb9d24cacc3c","priv":"ac37a60d2ff77750624fdc0d41531ebc6dfc1786f681dcdb436ec920f91a34b0","pub":"025dd6a2cf772db80dbbe6957ad1606603cd5b065177ec93263ab0194505c420eb","addr":"5693d8a59358cd00f21dd8786248538bdfd0edc6"},{"mnemonic":"walk raven camp kingdom defy nice hero copper velvet lock era south","master":"b4292f1b198481120f507ff13017c2756208cbc9652c555807472d872a58b9bb","seed":"6d2f085ea9e128fb3652d78d9e14e38eaf793ef1aa8b455798556482a5c2f3dd43933c26ab9fc38fc4943c82cb85c8c5b027534f005d45b740b31f63c683b87a","priv":"ad8fc7544b1b79028e05e96c9889004d9c5cdeddbcdaf05bead09b2075dadbba","pub":"0285d2a820245c70d9f3cfc930d6c4e467585f3c831cb7bcd46f58d637bc827729","addr":"4c7c3cb79dffd93e81882b609f7424431e55d4a3"},{"mnemonic":"impulse certain olympic advice entry initial bean glimpse begin flip cotton mechanic","master":"b092aa1b7fa22bacb8915bfbee4018484dfa4313c5779142e71e6d80e334dac1","seed":"9dbec0ace8784d915fe1bd3cc88b7c774fdc4791ace38856dc0500927aa02975feac3d82cb9771bd69d5b2f8c11c663e887b27292e3ecb36ff33ef5b3b3a804f","priv":"19497a3611ce0f1fb43aa5c55325099b6fb18811c99ec1d38c743c3338ddf5a4","pub":"03ca79e260e5a06bd3717cd969610c06580f65aa158e770eb418653a95a52cd0f4","addr":"f83b4129ec37643eee9f5d262cfe80087c5c5841"},{"mnemonic":"trip brass eyebrow plug sibling couple tuition tired warm spoon october finish","master":"ba1d19fb67d08931e7fc46b55c02651d374c7edc6df6a3b89fdf9e28670de4ef","seed":"736522d275c19137d354d8899542497b76b304e33c348e8f446970cd77aea927e2fc1d493b5f8dcdbe48c0a535722ba4223ef52925a57db21065f92779ba66a8","priv":"5d7ece46202706ddb8db591c4e125403f9aadb33c96f259105a0648ca1e2acfa","pub":"03791637ee34fa2e798c0cd98ea21cd17a4c02c429f05a9df5197b852fb643216a","addr":"e46722ace3466a38d3b5f66d5f94786d4576390a"},{"mnemonic":"suspect brick cloud coin tomato guilt inflict type lesson panel right still","master":"56a2d9f123ae22001633fda68b5b6f1fce4959ef19dac2c2a88ca5f774cb7d71","seed":"bc3b42627e5dfb76f1808f75e8cce883afff811821dd615262fa62c98c00cc0e0fd97b213f3b386ac00dc38de399e6e56b9216e34e4deabd15d23d70ff94cfd5","priv":"0d2c63fef727f339b9563c1f8bda5edc3755029ed45010e99bff74bf805f187e","pub":"02742f8b32ff1cf54225fd667425daf286705a0852e554e3294d057f5b41bb737d","addr":"4ac1a9bbd5d9d9597587bb809db80b69485d7e47"},{"mnemonic":"innocent interest smoke fortune smoke nothing clutch dust ladder clutch property glad","master":"ef88eb840ba3b3a072860d726b16c5309b9959381db68debc03d9516a7a7205f","seed":"33a6441e74f21794565c5e219b98416a17316a7b9335f8a0f5a5ae45608b315539c9938740266b663f8410e773dbf361f67550e185c0d42fdd4b406fec4cecea","priv":"5360d32f6dad727cc98c0c1b0dea7bf59f89aad2e5127050294adb9d7b116788","pub":"02bb5f40466fe161d106ccbae569709217ce1da9764078d27d3c8375752d7d1f87","addr":"fbdf59b3297e67600290d6bbffbbd39fb6f460a6"},{"mnemonic":"employ ladder boil blossom level pitch vapor gain permit manage coin supply","master":"c550d7336d80488c81ee8f2a8c3fde04784b8f3079d63add93b1b8800f796024","seed":"a80406c58b6958a30c0bb15f3b6f9efcf7e0c8cd0f01114a72f9c446130801c539028c964321ed9ba511831aeb00dba1be82eb28977319f727de1a9f44b1a7a5","priv":"9233c90da7ccf973268310430efa073e4e070cc5b9dfa29612bcc9541ca3417a","pub":"03c070cf8379e2461ab6158755f45d881ab8fa7de1501bcf0530a871abcef79947","addr":"fcb4e5a3f2c568e0d513d1ad97c7b806a96debce"},{"mnemonic":"winter absorb stamp enroll brush paper spawn slide salad special front update","master":"ee7f947acde43c8fc5761af3ca28fd0e87d0883043ea4401f0d692ea818d5573","seed":"0f1b5f166616c83c129d6b2e0d1cf706d46fb56e60698beb77f9eb105bc0726fa7159a4a492b6de462517d692bf26a310528379ce47b4325879772f46ea0d82b","priv":"31f98cc2cdb0cc6d88d91f21960136650d3e7bca690a569edf2ddd6095026e38","pub":"039ad4a48de652c30e015c424c2ef3083f234e5df78791f112eaaab2f74deb71d8","addr":"68306083576ce37fb1bc653ef33e46ade3af0c7d"},{"mnemonic":"focus usual earn deputy execute climb broom save robust coral piece shell","master":"148c7f123552e1be3f696b2f8b0df4885de067d43f9c1e5c671ae6a3ba4dd361","seed":"a4f311017ce37d0f1199253671b0f615ebb09f92648cd33590c2292d4bbe1eb45d6f1a94e71e1438c5cc25974efb3b8ccd03272ea0218f171b01c7fde17adefe","priv":"587f36966f566888d5684aa983d86c124b4657ae02e7d540939c5265ca50ae59","pub":"03cc82a5871dbe05fc52fa3308bbde84a7744780a4c6344910989437b37b59a0c5","addr":"6fcc01f30a9e9733ae95a049ff8b3ae0ea8c97c0"},{"mnemonic":"twin over wire boy dragon drift erode human shy minor panther library","master":"1488ced839d3116ec99c8d4fef9208224ce28d270e4d3242999e8c3d1bcc1719","seed":"099d13da6ce761e666e6df0199a79e95e83d0c911279aebf8037196af6c7070dd08867dea0da8d9148dde2d14ac55864a7dfd09464282d93037aeda70520d664","priv":"1c2871733b9b2fc6224400612807d75387c37b87b925caae6486b777b0dc1e53","pub":"03496d39cdb3d666703b041d5bbb69482537addb552335c7f26d29e09d5ab8500d","addr":"7b89136f5fa6320f53c25a260b4b75eb5bee5774"},{"mnemonic":"potato lecture exit color target shell more push day catch entry erode","master":"a44668b008915d6eb656347398a007187c18cfe766ea167a89e855a77b9b9c37","seed":"815db5e7fd253567cffc54d938a3fd307968b45e95407617c55201d661f2ed581e92f86a1391154e6421bcf04487da1d3c098382a3587e8c5679704407812fab","priv":"de5ca4846103dca9d947e7867ed764c9094d40ce189cd2366befcb557325616f","pub":"0342ebbb943a1f8100441035ea11cf76c17dde7b7298d160ed56e3dc8fcdc7a8a6","addr":"68f2cf5a8b290409689d5e08f99cf1b882582e06"},{"mnemonic":"grit flavor pass apart swallow quick payment view weasel decline travel hat","master":"3a2d8a4e041357a246be12beaade6b6c36fdab6dfbcae0f8230106a09c5157ab","seed":"a69ea95da4c681f004cd5fa6d357c39e50594b66c73a42a93672c13d6dfea0ff0d741bc1b406851c36680895a8137086f6de132d2aaa47af5d4872fe08818171","priv":"502b2d14765f2f80f6ee0c10b98333e498dc7d33a46424555f8429488d57de1f","pub":"02aea2e315932b900ac7e31d5b6b82e9966e45b098dfec8990e2efbf4457e581b1","addr":"c6f8426ba017b6ac4fd45a95341e760f158f0e41"},{"mnemonic":"machine insane tomorrow island assault follow verify spatial pizza major cannon inquiry","master":"be46461a96c733b1add1465d664d74b8e1a28fc1bf25746b9e9d44ddef81ac4d","seed":"2a5d713bf4b71dcb40d0526767f8466c87f04ff5b2fe38ac17d5a7418f099b25761917cddec77d369471bc22a1f26d2d7f6fcfb00b3dbb28f08279ee0ac85f1a","priv":"097be27be2a0c6960b436acd651792cff207d877695acebd02c088e6f3617b9e","pub":"029cde9790e6e1b55d54aacbfc6d13f09fd6b5b04976d0ba5e01cf25da0a2c3976","addr":"06ffc6a5742544cb3a66bf443ec0d8894e5822d1"},{"mnemonic":"plate grid latin above champion demise idea urban raw exotic day diet","master":"9daa2224bd8c15a22941090eac1262e88dd2faeb708ecc00f404c88723bf617b","seed":"e07adaff2724a1af34ea6f3ef3e583086fa835ca126f731875f97b366322aafaa8d39b72a22dbe70bce68d8539f1ac109e3af03db42317f3807e91c35748438b","priv":"423d528c82af34cddc13f8873534984302e072e0aabc9f29b10c70335bd72a3b","pub":"03241547e0145dfbac8bbd5daca05314e2fddcc22aadaa8b49952e461fccce7d17","addr":"2c1ea451fe2233aa3d2120f2b836d11cba72905e"},{"mnemonic":"august quality apology more ring armed hamster raw gentle inhale angle dune","master":"90478d31095fcbbaa751055f7d9fc70a75a8dd34ff825f1b4547103e3367ff9c","seed":"0b944522c472688010098bad62a38a173e0184f64710bfc370e8ffd7a3e2383d630202f52b7ab9b8d41948f534b2bdd0e2664ba76f2e460fc62e73fd1684ff16","priv":"e8228b2ba4ccd5a22bddb4e0a3eaebe6a156ffef061779d264b905c90797826b","pub":"039fe65040d933902f33749f3d43cb924c6df298a969b05760bc4c8fdfb27df444","addr":"b0370814a3a0390cb3874600ff1dd48481725ce0"},{"mnemonic":"argue april pattern jungle favorite shed silk adult file cover benefit neutral","master":"3d5f13e3264550f14ba0edb8b693e7ccb5e74789359a7cf9b7f819654542acd2","seed":"f5fa70f943ebf5b941574820d4b91a1ce706fc5f9849219b7e2e0f9fb410c4bf81494beeb390383e1371817a39f2cc7a9552452d973ea8a15ab42b881c7cbebe","priv":"d0d2a3c92a4b1914064826c1a9205ce8bcb076109ab2524a2818d2ecaab08420","pub":"02040f9ca1b771a4692ff543df77d2fa8fbdd9dc5817789b1ac491a9e0908638e7","addr":"0fa135a93523a80e03603c609953a2f5c7b799ca"},{"mnemonic":"oppose describe defense consider long lesson better kit capable taste feature reward","master":"07ef0cb309577396089c024c1b48dd278d0575aed88e63ac99a44d531fc919f8","seed":"c6ab42822e1fc062f5bfa6e5d7d4049a28be293748858bb2062f4b9a3c20cd30dd02e7e86dbaca2c77bd2e1d837247cad63f8009f9f9410a0365ef7bbe647727","priv":"3b82e67931a96b68e6752ce67c1f971e23c317f8829e2573672edf1d80c68836","pub":"0248ad30caf9f25bf49bafb519ebb3d381ee9c95a6da6502e1cfc88a4a1aea3b37","addr":"17fe8e8d5f6a4a10a2b7f0323cb6ba3bdba9fb93"},{"mnemonic":"blouse patient surface urban stand clarify old pipe where spatial cargo shell","master":"8ea8f4837a7a4a3bc100595fb6dde65f319e8928e61f7da3eea2309169b9dde0","seed":"a7ae3795447825e6d51da632bbba6f8d9f5e141e593d2a78e05f7e0914ed063d629f1f84d3427e7803fd1e317ca0359654bf918724705f523e2a896077c39603","priv":"6fad450edfab3300ffdd65133f2973fd0be3daaf7864e2f357598b63416a01d0","pub":"0211cb5c4316de9b5c08e8764027f9dfa0cae026cd9ff9773dcf524c06f76c08df","addr":"2a51a4f2ba38e779b20b7a4bfba78e8267b6d6a2"},{"mnemonic":"moral penalty ladder step panther divorce bus adult math various speed rural","master":"9641e82d742f458ff81d48d486e38cbb8919a56b2a317d822674ab9e4887ea6d","seed":"8b4c57108bbc2c753be29e0b19ab43b06c7c81e2dda243535f74c08222b23789d3aee754e23ae936df99c8728b04cde066b6e6e512b54fcc1dac28f0b0763074","priv":"043dd7b6ec9ac7f52f1af6f3ff95cd99371c251680c04b3c847da42242d152ce","pub":"025f7dd3fc53ceb3ff87c2bfeaabdeac1d5f1c9b8a897bf4a28ac33b95562e4f79","addr":"9a61f1c15e55009122d52a1c3917a8459fa29238"},{"mnemonic":"pony liberty split enact quick arch mammal velvet cart wait arrest burden","master":"e5fbd41b38aaa3aa643a66aba1c3e8a01709b15f5e1e30d639db03dc87151065","seed":"b6a41b697611cccb9e117b5ce798d47bb37ce1e07341cfe972905a4b66c4b7f8596cd0e6c21e0cdd221be33de8c0a5854c5f8618df36f28d95dd1dfb0f31ea1f","priv":"7e98676864a3649911657e32afe07f6ca86dcac164f4a25e48e33cb147ca4401","pub":"03d61b29c9f5775c6d8fddd6babb2b8e77b65fddcfc14b8c8f6db262285f2d1832","addr":"36c7ac440660d8a8642d669022d621ec1e877680"},{"mnemonic":"summer envelope tumble six bar crazy forget very canvas sign inquiry copy","master":"4c8765857e92661d69dd8f64031d43df4e1043c786f1ad7593d9d6cd7967b9eb","seed":"662aadea06a5198cb230ab83449dff0514b2addd644ff618647ca788cadae3872e19becd5e8de5719e3397783cda6ab0e1496e8a204d3ea8ad524ea93a1b71a2","priv":"a1d833122e4bbf53a23695915b9f398fc8681f72cb68644ac78f5b0ed0b0839a","pub":"03620a954c07b3e3060414ee499f68a904a8afe2f7f3ada8a9db2e039302a1ac0d","addr":"9758f18ede0279601ed2cbabdc5a87e0858c0f01"},{"mnemonic":"robot lift decade april style rapid thought modify tenant wild pottery cool","master":"d43dea8679ea3ac6440623974b253ec2355e97697557c8d62b5a79eefbac54a7","seed":"bc1a90f5410aa2fe22248c19110d3bba802378c5fdf2f3a2eb379c767b3d222fc2ed5d4638876d51fc9b44816c229673694b3f3e8052257f574ea50fd6d7a73b","priv":"fa29d04ce0480d48e6793e227e142330aca85e4e91ee9488396b1b2af13aa160","pub":"0342e19701eeb5ce20b17397457db9105c092d00db7250968ba38a551fb47d3491","addr":"c8ae52e691ce5b507a152f47970456570aa6635e"},{"mnemonic":"invite pool cross silent empty jazz change smooth appear snack cloud lawsuit","master":"0ab641828b6b935da8bfd58e4910c6c3fe8cff9d18548f86bdcf7d501875aab5","seed":"4aca0bb1ece15e686bb9f08a0796eee1830b9d926b0daec50aa9e280ea8eb522f546c1668cc2e2a8beab636eeeb992569a8a8b50e2082b5cb6bdf3195a2e8376","priv":"621bb83e46364ea7bb3a1942dd857213f49077ebfd735ef33095843e11866388","pub":"036a6b24125e8cbb887c0e9806e5feb6555f3ad4042460f1ed85e8a5738a02cd54","addr":"24f1dc90e9321c1faa33d3b2fe82665b402d4e47"},{"mnemonic":"current exit average case novel nuclear recall unaware decrease maple bind acquire","master":"a0a9d482c7bddfd3a8bedc54779098ccb0c54829e7949b52969a76f4a67f1ee4","seed":"35f2474be8f9068d91047c19ea9f1471aef87eb868804c5c205692944bdd1a3ac62ab71e052047961946d9c371da2039e89cfd77aef881d23774f10b24c3e16e","priv":"75684bde10654605f673ba3f704edbc2329997c9b15128b5640b6c4e3ca366af","pub":"038617759898bdb797d411a87d1e55024fde8a1a65c6bc0391a8deda099f6f7fb8","addr":"5785b3440fbc82cef8b1fb97c8f8e62a590b1842"},{"mnemonic":"tone engine property lion used spring enhance need choose grid deliver sister","master":"a0b23f0ebfd072c71a27b964ac5ac2a58fd31fbb1b22c044631fae01b27a425e","seed":"e47ac6612dade3bab1613b016b271eae20948c7934b08d8ba5ad0d14da1417b27512550287853c6c71efbf023b8026d015b063696d562850b991664ea8bc29fe","priv":"bd8279824526377e70a20ab1ea2731f815ac8975ec7ba5dca90d54859143f409","pub":"02dc15779fe271cc197da7035bb0886d2b44026292c137f6cfa8c98624665b383b","addr":"8271679fe371b6ecd1e989a2fb2d7c8d981006f4"},{"mnemonic":"nut solve indicate dolphin crush bike puzzle outer mask bring dutch city","master":"0aa08b93b1e497f4e54d6caaccc4769e921cbf9cc155a5b8877beafc43884c5e","seed":"c7c692ed2dba467ca28d1249f4d39a5c0405a54131245312d05597ef2aa31af3bc6791850693123f18cb1c350fd79c1705e53ffee10a501b82d0cb237d256579","priv":"8f9835b154157f65bed179b6008a352b7ef7d5ce8e21227a22c461294a7410c4","pub":"02da01e33c91da079a39cf256db26b1254e132b894abb9f07bf01118b5b6edf486","addr":"3ca1fa508b336a46f89231ad841a5a14d026f5c6"},{"mnemonic":"inmate snap bullet curtain used blast fatal one join owner route absurd","master":"e4003c062456105b608885d8928bbf183aeef12a48d6e3510dc7f183514a5195","seed":"0402d1974747f32f00e4cc90795f28d6e07a12cba21f31e22e0eb269ad1dc5fc0ad5d6ed1b5d5268dc50e31fe78b7145546de0cc1fe7afec7f5e3831863e21c3","priv":"8e55c05a82e8fcfafdba94b07dc54940cb247eebd1c689b51170f4ed10628a82","pub":"03637d8eb1c87329d9367ac73d1f65e482bd13b072d791f5fc6c08fdf262afdc8c","addr":"23d0d3d1abcb6ec683851d8c21a1ccf5941f18d4"},{"mnemonic":"useful panda fold short about copy hurdle vibrant kingdom draft suit cat","master":"9c99df0058969798ccdfef6b053f61af2b6422e4c691213f1f0a59f4792156b4","seed":"4fa3755fab5aee41e0771c00362701451ac578a9d7f8b139d9fdc043b33fe3566576a7942b904047978bf6a6360181187d9f20bb3475c495985e39ac7fcb8987","priv":"2b65da5f7070729879787dea803a4f50e2df1ae69c39263525bad0b5c994f86c","pub":"03a457cb29097644eb4a8eb1713fdea43d3992b2b88dfd41fbb417845e2d373ce5","addr":"901ed83b7220c552c69c43d661dd468ed94ac9c0"},{"mnemonic":"intact pluck author dish garden frozen speed grit bar narrow across loop","master":"548d4844add02811ea1b60ea7a6c337883e818ead83782a7b5a652ac038310c1","seed":"6b3b40cfaf38ae1ef9938c621264cd373b7e15d196bf9c69ed6efe3f7a7a13900b3c89eb915fbc99457347832ef1b816da26cbdaf8bc48c2b8a634fdd8be2346","priv":"eacaee29cf8bae543732278774ef2244e4da49dac3d88fe11fd7ff50875ffe8d","pub":"03d4d894053c398cb5dacd431a03c673a4f883781d951254fb398a24de018c6110","addr":"0b0840f26af38181ca7f65b7fdc0a3309c28fc4a"},{"mnemonic":"equip energy remove soft alter mammal valid van ordinary motor follow buyer","master":"6110f719e36e14190eb39d4ae66ab2b35bd5c3fd2969145fa3881650556c5384","seed":"74163bcc1522e148a87a95c78072359a600b364eeb558d052b722e5db26b6b317a36219edab7558cfdbdaa6d62c7b078c691fcdf2acc493139a75cbd26ea3bd6","priv":"fea286b716369fef22c1c5ea7da50ad612868d81c50f5efdcbc2891e21328a7a","pub":"0269bb65b5d86befde40cd916410790f9a959c2f3aa3beb5efea2eb358eb5047d1","addr":"9ea73e16006fd30dcdfe1ecbfd2792d5001ff8a6"},{"mnemonic":"limb boring random already marriage team useless polar impact equip rely sunset","master":"20c34a5ae5b9f78bf032d7841469e27002583c800d4aee849860d58213210c39","seed":"848bed01605f3574c16480514ca0cac72c21412fb6ec38833f97fb744e4a975fd06135c4761aad05d73280bf2e1c8297769e5cb69299bcd99e638e4dd542c52a","priv":"59f09a8926377ef066a13627f032d2e700795976230ff2e58806d046af0450c6","pub":"026e3e1e7ff239b39eb4a77477b32d492f99cf1f611558885afc7363f3173a8a28","addr":"61dffa0563d51aabb1e2e585bd444f99cad8d54b"},{"mnemonic":"vapor reflect friend jazz chronic supply awkward tongue venue finger island brass","master":"4dff50c5a87bb1f9d2c0392ee7eee59977bceda605a40c0a111ebb46587a0ab8","seed":"e6f70f78b981254b4e3061270fa96d262d2fccaf8dafd752db2d0fb54f943ca99f49eac07d279b5875432dd7c0450a7bbb776e8852e5a5a82886c65803ec1698","priv":"50273043958c3d7cab07f41dba28080c507f460ff920c6b5b135d1c64dc85469","pub":"03ef40a81e58c08d1bcde1116e9e748eacc38906cec057f2984fd4bc91081492ac","addr":"a8aba313467ada95795757ab9a6661395adbbd33"},{"mnemonic":"top base town abuse shiver symptom green thing vast eagle steak warfare","master":"7ae7456584c905376b6e6f6732b8890baf4d768e82dbde95110effd229dabf9b","seed":"f88b915dc5753ee33855b3adfd292bc56f04e8aaca117023209877ac8cda5df3218c969f1491bd0eceba11ac433016a05a9aa68d6bf3fa59b51a5cbb224c902e","priv":"ea68890e0209f3444eb78727cd3f13dca20c886e8bcd6d31689dbba04d000a30","pub":"02030607d8a2bd18f8af9b67f99db31585b7a879d6f08588aafbd18dd95d1cdb7f","addr":"fa202ccc3db92eb55d45cc79891bd4be395fe4f4"},{"mnemonic":"picnic seek ivory unusual text become room artefact rigid unhappy wall harbor","master":"05638878665f27362c8165adf4b73fcba3cedc983be2f0897a333378f53377cd","seed":"8af253d6d848e9737c8b7807d37558e5a1f09d3a14eaf5794c83c9d4f2021166aab7faacb967eee25714553003cbbe0c0eed9487d4499bca430e709f0b8d219a","priv":"1357da6886941f1c50a19bc3b32a174acccb21a0415dd5a736e5d679fe505f0c","pub":"0333d6d3cbce04e1ac26ffc7c2d4323110a038dc33ce293e95d2d34d11bc1d4efb","addr":"c5aca5f8318f75bc143edda3eb89821e751ce0e7"},{"mnemonic":"faith box profit long entry that alley stereo wife nurse tiny assume","master":"67457c024bde2135b9493124ed03d0f5f30a66530c958693f02e463982362395","seed":"4e22fc62d0a60e2de3ac33de2db8d4a884905ef84071b190f8d43f57040686eb3476fff7a90d19b1bec66d8a2e62532501ac7914585ee5272c352197ee0f0ead","priv":"ba198f97576c66c34196a36a04172bde332ea3c6777ba1af203b68aeae3e23d1","pub":"026aefd0f79219acbe5377bb3578a38f71174dcc9f77fa4d1dde3f3aff35ad2f10","addr":"44c4ffa77990259e15f2b9dc59223c5807c85f54"},{"mnemonic":"brother bar food vessel shine object tape acid opinion brand indicate local","master":"23338d7c853f4e76208d97bf0c47db2dc317cd4501cf00c037e60461eb373353","seed":"e32c6c54ca4fef48630e4dd7927634ff1d21c60fc488e6f1b87755d3e79f4845a3d9f86ddfcf185136150b52dc2f721b04f2d61913d63461956764487fec24bc","priv":"3d410ce752789e05c5e02ba5e95c2765f77208c90cf32f289306204f82d6eb77","pub":"02a795076f39164eacecc80ce04d63e5336edb32d183c06dd81f50e330b6102c11","addr":"b2c8079676ea7d98e10b24d9a09e3d4519d32d74"},{"mnemonic":"broom together virus run require inside output spray day hour cruel witness","master":"3ec636201f4b0a0fc7226003f1744766875a0f8a76e19d69c6c352d86c672cb1","seed":"51bbd8710577f0a2eedac3e341727d975b0e79e2a0777766d43b0cad8b66e302d1dfeda04a6a5ae0683db18955692aebc554c4bcaffb5f9be9f4db079a550f78","priv":"9063c803e2075922b916efc668be57b734212ca8ffeaca221b587912426af4b7","pub":"02b66afbfc48ab4d97a0965e7c96582d2c4cdcae965f8aef72ec98f59b31d5eb7f","addr":"b18bf07d9f82f070da34d8a4e58fd6cc4125d51e"},{"mnemonic":"crash knee output divide essence fiber benefit pig recycle patient strategy already","master":"eb84eae9a804895edbc89020995755aca54a04a4e7b59adb96b2ad0a8b465a7d","seed":"4aab7e57401b6f2dd6502dec26ef36e36d712ce328b5190d73b9055a118c5ead12dd5f18829affbb488a71f18cec672093d58452bba1ec3775739c1169901e67","priv":"0d0ebcf8cd5c075d9b8a2d2e404d44701fc1a5dabfc5b3cb50cae523f3c4c149","pub":"0296e9cf1cfe73a4114a1afae2f05a6a92da168113764431fa57c25afe32258d8e","addr":"8aadd8961827385dfdda784993f8f135a6678a47"},{"mnemonic":"shock assist horror regular voyage gadget cook pipe hair boost release stamp","master":"74b514c25d4fa22f3ac95aae2e58824da6ea181962c52944256a8b80cf86e980","seed":"0a13bbed1d4d3d6128d1eb0bcc0595a4c72701c7e9b79ee6110a104e10e20656dbbaf2993a7a06381e9ac424c3db6b0e98be6d5c2817433660256becf295c70a","priv":"75da3f78a45cfc4e9318d5dcaaf6595002ed037605ca196282dcfc18c5e6eef2","pub":"037187c0d2d573d9c28cebed9214ac37fe20c55ac56ba565fbbf7dd79c4eeea519","addr":"4b79f08bc7daf43ea00b5ad88b7642c31fdbdb17"},{"mnemonic":"monitor artwork plug dream sniff sketch oblige prefer dentist rice degree trip","master":"e8211a763f0b7f2f0085047ec1687f9c37910d27d8580696ae843872a7cae0d9","seed":"0a48851384b8dd7f8c99bfdaee23b143479e589bcced7ea423f6fc5bee68bd5e5c45834e3f2a7a1fcb928781e37e2b3078d683c15dbcbb5032ca31d3425dadf1","priv":"8fc0e10b570558eac1349ca8ef4f47b2f6d3f148a07b94bb2f1040dcb9bf21d2","pub":"0341374d25e701d963aaef0316ca0b4f4c15283f6b8b6932d954cdb7d7af4d7bd7","addr":"9a4cc3bcd48d6998280db5cfe856f7ed85d6b4df"},{"mnemonic":"bus deputy eye shell isolate judge nominee later gift mouse leave square","master":"cf814d6a08c10f4f771f670120b52cb26b6265a5510c5035d5bab583bb7f314d","seed":"9974e3131ea54805d6e9cc124ffedf80b0ebf935cd0908c4d8d7a3b777220155c056f12a7cf3c0c6e58b7adef792215cd471c080e9f11ab6cd4776ad86df9544","priv":"ef857601132267606922590b016b10faf2405f7ff92e3d8dd73ee6843f0b3707","pub":"0317f408e6be956b15a8e9706287e6bed905a008e8d4705b6c9b6e7f478bbc57e6","addr":"70cbfc88189721a264c3d21bd01f2eeee8a245bc"},{"mnemonic":"toe present claw afford agent render direct december model skirt tape soon","master":"88f5eca5b3519ed612f9f7b15ced098565559b85db98cc57979dde0ed818bde9","seed":"d776e445d7541e997584381b5d2eb066b99644275814961daf748a76a84898c21942f23837851d387f0fb6557a0f693d98e4d23214ed34630bd74fa808b36668","priv":"6252b6cd338753e5cb6745e7ce92bb661fdd373e56796722d1766def72b93ab6","pub":"03dc54c14b80e91502c400d6a97562975ae0f967ee0a7cc5618ac0330855ebc688","addr":"afdf4a2de468ee8b2d47de70d52ad9a3239b3f42"},{"mnemonic":"save rich wage off orchard unfold call frown idea jungle boat oxygen","master":"dfff9a17815e298cd92e9a2c5d4ccce14d3df12af9b9c69c4aac7bd297639ec3","seed":"7d25dec6c87f92e685124b901b0ad423ca3554c31db8583d205ec4beb3f42c4a14777ff4fccf830f5641ff4c376c772a8a1273060d58c22b95a51f9daa812a2b","priv":"5e962f6e9e6e9ed76b0f3e3174ec9639996027fb2bec3fb47faed79e66c4fd6a","pub":"020b08249515846a566c2c9616894ddd6c2239c58077ccb2f2e7ec5a8a140ef293","addr":"dbcecdea56d7e5da2a6c96c1f36242e87416f221"},{"mnemonic":"claw ketchup mistake lesson drill crunch unaware captain perfect spell endless manage","master":"bc0c9ff880973352267788cd2e1882dbdf5613a8460414df0e570a099321bcbe","seed":"4b9cc68aaff0b0ad24c531e990f9a9b7d7076dda27cc2f21e8e75bce8f65f2daf1ce6228130bd2c8900fc677313ed4cce1c47eecf24fea0c119f70ad6d3d79c2","priv":"e36db8076b37e0d3785c550e47ccc91462388c8249d160df13391ff06f40a30c","pub":"03895e970001fb0b3566d8abcb1a3df46725daf591e6cf981c1f06a81eb202692d","addr":"6548f7cd7b619dcc8685e59456ecddb223c0bc45"},{"mnemonic":"canvas black between chunk wolf resist again joke club moral fix spawn","master":"374f2b9727601f87f72b70014fc10a38c5fea6cedb36246103e0fde2d356f7ab","seed":"217881b165a67d70c9ed44d81a1100cc829f00a0b3782d8ccd8429806b883eea17f900ed32927a7c8fb8df34d75d5264cb5704208d3dc336444c199b9cd4bd1d","priv":"7e6c83d4d58e7a55e9882e6160238c6fffebeaa89e86dc9785fb1626fd22e8e8","pub":"02795b9337e8dbaebd288d1f0d833d51a4969b0ff995ace05c329fb6d20ad82425","addr":"7618cb9305c15c8ba122949bc298b3d6daa43ef1"},{"mnemonic":"dismiss rubber stadium badge enable exercise collect globe another survey own hope","master":"9da347a5c2a00a44e9bd39e50d80c106a9f885f8c84f5c4d90a0a75dfa5d5508","seed":"7038ff726fcba91488e5fec28d436e7a2e7c462b06747769f79b785aac64164eba1ea5c125e6196b9430139d9e21af8cfe10b51a09577ed510453487cc1f39f2","priv":"86b04f6848114854a1b207b44d9475c216e63a9b051c44bdb7be3eea9d24988d","pub":"02c6e822bfe6255d841eae33f62987f9cbeca84eb8dd1dd02b2daf9c7de7f36371","addr":"bd2a4f087a519a3469cbdaed704221385a07acab"},{"mnemonic":"dignity tired drift feature file salmon vivid wife faith title direct toy","master":"ee03e61a429a846453557f202766fcdd8a3b408c00f3430f7b3a1c9bd88a7d11","seed":"baaeb3a06b419a7a9c49a99e712c11e87a7a4bb34b26700b1d57e95177dc9b6b2d590878111e14f6050e73e5c72239a1562062d1b8e4c8ce9ac158aac282c2ad","priv":"d1dc95b42024dd0c10e8b5f0aed5e5f7c9ad0d56636da91bfa910d6af2124969","pub":"02e1f4ba20c8383bf512073e335400e1a1b1a103cce9450864b9087203dbc0e027","addr":"3de51323a7d40ab752f2b0cda1c17d51cc477369"},{"mnemonic":"legal sword liquid clarify utility depend romance cement trash whisper endless parent","master":"7c61e0c0e85873e8bdf532ec5906b8be283a002114b8dd4b8d0154054b6f40b2","seed":"21ca62d84191c141f6b9890627d6d216d5373ee0819e7c618e4027e70395c2a4ea5702aeee5b844a99eee4fedb85bce72f7d5f57c3d670308e1fa484108c4862","priv":"d6ad713c9dc2cff3e55243729c56485fa34ce8a75c4e011f40762ee000dfdcf4","pub":"026c7a44022f2892f2b2b091bc1488e547b8b52c82c2a780dd6603f40261930d3b","addr":"c6c4dcf4763d9908a46ddde925afd86bbffd4719"},{"mnemonic":"tragic inform salon lamp tree deliver sugar robot torch collect choose nurse","master":"77e88aef57f8be3507ce43c1e47dfb86ce0fded4a6d9a5ed6a2c6711a0a83216","seed":"6670f6815a2865591e6f9ff5c1cb775eed9fd45d53d1ff3f65937425c6bb79403862a398b28c7aca032fdfb14f96b238174cf6353776321631bfe338029ac148","priv":"7907a31525b26f89eace8cc0b988a08f8feff4914dd8f692e24199c4134c6fa9","pub":"031af666b3e8d5da1684fe5d585b8638fe46cff1b1fa01bfde3b2b8e2ef2aa3a58","addr":"792001d0cd191121043ef1434855b85b583ecb09"},{"mnemonic":"common oxygen toward security mixture swim elite issue suit welcome ripple online","master":"f4b85ed364ae42dd7453f56df2731c194a203cc06a8bbf71a2498424d7687631","seed":"9f2217e5ef1a8691aa51e914411a5ef5bf70727cfc7d0a932e1a9f7d298a657db8f2f6eeabe881e8f4f4580a2bf1834ae888cf7b3bd32820448007769b310724","priv":"2f98bb40d987f7e50966b15d2bfc89befc72bb6934aaaa2293dbd9bb33923268","pub":"03b89c51d6a32cdc56e334997a0bbd57deb010778d62024f5012ced0ae184e2464","addr":"2ecc6f88d71e3b1344a7fdbbbbe4fa60b5e539eb"},{"mnemonic":"kite warrior idea engine trouble swing route main like burden divide drive","master":"8317ec95801550a748f5215d6e83cb12424635d5b2f6635a78a4a0311cacc56c","seed":"f406f2ef34c3a4bb64622dfc4496a0b6183f1b7c1f58bd28d3ad863ccaffe171bd6164044ff5e940650a6bef6c290279b41d80336cbd9592c1a3b326314d44f9","priv":"4fc699bea9f32362f74b1cb6e445b1a8f3df81dbf1d5333dabcc84305c355e9a","pub":"02f8b8958f9edce19f8c5a50371dd079ec4b4ad6f6a9746451d4024ccd266829c2","addr":"8fc3062dd0b1063eecaccb75e14faf5b06cbb939"},{"mnemonic":"toast health connect merry resemble slim address pioneer crop orphan keep dune","master":"07ff519f3c3fd08b9de16a26197914867d4e42b67222c9ce863ac6b176bb5909","seed":"5e80b7b4b8b388522fc283784f368f5f7875ff7b412af6c3e526ec1426ad4164e0f4921494ff28a258787beade935d472cbad9f48386c2d7e16f8ca76fce769a","priv":"1158d4b986fa7e05db824694ce3379b63f473161c965a39ca997a8e3f3e7664e","pub":"02a3a7b75a8532df2afd58bd2dd434603c21a0aa4081f8ef9798db401372e32bbd","addr":"24c8f405da27ad41be7b0c62db63f80226fd6b58"},{"mnemonic":"cube shaft clever hard fuel review enhance short nose again banana profit","master":"30f3fe7efee7a0c7eea064bdb63f509182f0dba45780dcbebc5f3374d1b878f1","seed":"93774eb188a6ef898e534aaf67c2ec9aba02f716eabc0d193bd5a035ed8e0eebb2e82fd3ae30bcc24c44d697d46296e5d307060420350a4294f3cb639a48e6e3","priv":"857bcd096012a98022b2d30cb926757f0afa9465058c103b70fc931554f2d360","pub":"02ccbe787178d64d347a4f146facea95d2d01cf353ba04cf7cf7325fba6fad3824","addr":"d3dc220b0c09ac018fffe2cfffb220410af0c0b1"},{"mnemonic":"weather surface use rotate entire foil female carbon once kit seek athlete","master":"68614cd2df975347ef5c7efce4e416821a1f1916ac54ba994f6d69f8f2860576","seed":"478f798d52999208d3c8c0feffa78c6d56406d59800a701c996b8c8a9b193494aef1881e2d1f8aee0a5973b722fc3bb3ba007187a377a64b13a81d0560cb090c","priv":"6671cf2b354b61f6410500e26cbc94afe78392d3feecefbecd6e60c6b1a33a31","pub":"032afb4d170e89e8c89c544ebb404678bc6470d26bf68dfaa1c034edaa85a9bb5d","addr":"2bf3d54106897da2427b1c4c85de761e4546564e"},{"mnemonic":"car rubber ocean miracle vault brave goat eager dolphin various infant receive","master":"fa86484b17c9b62008647587f406f4daa107c6b95e708487778865c76a31e330","seed":"ff824d733d160e50a156021b256e4663f9ebebea1530358d70c205da5e7703d64ca4f3d941043787a68fdade5143d993376b1ddc9fd6037a13520e8cfedb790f","priv":"bad6b6ee0a3aa898466552b2e5df05bccd7d0861e3368f206d8cbfd2ec8e47ad","pub":"02ae2706cc6a96f31da9cd46d544ab142a26ebc6259e5e807065fccc251b26c603","addr":"a6ddada02b29a165a86a8bf4a01e783640e5638f"},{"mnemonic":"segment nothing burden boss obvious find kiss join science dinner clip wrong","master":"64a4c932d3cf62f9bcfe86c3b709ead38ada505e944322b93e14022c3ed26e18","seed":"71966dfe2434f4dcb2cd1bec9090ebd20bbeac2ed54dd8d081a548ce7eb57f1b17cee242581cc893292ff9ae4e5526bf9e11034688299753a6d0bab024ae9126","priv":"44ddd6571ce3582ae17ca9c74ed41811a760c7059dfa7ee88f9ef76960e30328","pub":"0288341429320e6e7cc35df266cf3929e93e843e911f8ae0ebb2634132de1a6f49","addr":"4f32c063b84f9895d4411ece5ba0c9d2e94631ed"},{"mnemonic":"cake volume physical initial phrase false pear poverty bonus steak rebel ketchup","master":"8200ce644e28680726ffeaa7d949e23feef136634b58d504e34cf8b2bbaea439","seed":"8f6577cfd936a64de1c2be553f66b8e5991e2cf30c42181c0f7eb527105c19221268e3268aa243f740733748dea3c0ac16320305c401aef7cd0986f3dc6ed978","priv":"ae37947a92ab4e9ab9b4e24b5f26f710725ecf848f0412b583b8701dce4b7730","pub":"02ba33804bdd8733fb5ae1ce1758ca55c8bd9e15245d646e8f737da2d61758ebf2","addr":"1f3833c0eefb3d46c693b0476470d97abf02a792"},{"mnemonic":"outer meadow velvet fetch claim forget token fee gadget alert post pelican","master":"a991420cafd20f348c847780fcc2128888771f4771cc6ea137099616c617b1e7","seed":"35cd93e8d9c4651799471d4cdf2a2fbf083088b93f1c1bce6ba4394ab6239d05c0bfbf8d7f8976be68042e1c8267dfa7ab3008c967f8d1ae0793190c77077fa0","priv":"e4fb166f29590fb4a5c5484729f038a62aba50fef189f1e3769fa290e1800790","pub":"02e123798016f5eb1f79f633588051def8b59c27fd3973a7f2012db1a8fa508ad1","addr":"45a62d3353b39439d002c307c8789ac70adb69ba"},{"mnemonic":"flip expect rule wrap cousin fade example ugly crowd monitor cattle cable","master":"d5c2521cf1c8f3dbbf955477a993552cf7f6f0ce452bb789806daa0a4dcf192a","seed":"b08a8f7dde39c9680c07ec31ffe80377ea915de328fd38b81525e4f694ef0ceb630e7ccc19bd28a03b7061b194f2b7758f802945a7e556d526f25bf2b4d5fb90","priv":"21a41b9d3ca21569e3b8638188633a7be8e9b54397964a65bfeabc3425d5e4bb","pub":"03cacee92e7116a6012c2b3002fe67d00dd062e937393895703e010d5ada98b4cd","addr":"b3a4f2cdb4cdcb64f1434f3f1e4c20bb8b952116"},{"mnemonic":"alone absent senior wisdom sheriff siege harvest coast van skull want quick","master":"74109213fcb3350c4ebe081116bc7570d00bf49cc7cbb90cf3b09f5d532a3d97","seed":"7d111179778ce63cc39879ae303814acc25afca8eff930d3ddfdc640d7b3d8c1140429a75c6db52db96564aba0bf0c8d9e4cf78fcfd703c1d219c09a70d8569b","priv":"96c3356e90906a9b3c523a3ba61d66ec63d9bad5ccd23edf923e3c5e4c995774","pub":"021736b932aa1eb90716bd8bcf3cffaae73392a37ec114b34628367f8ecf1b35b7","addr":"e8951735e9840492e0589a885968f12b044067de"},{"mnemonic":"fall any bamboo energy ripple flag rich arctic argue decline auto pottery","master":"4b3fa55e01aec7bc6d41a890d8aae2d69e617bab49f8529beb38aaf835d15a69","seed":"aea9842051221d0eced61932fd18a5f3e1ed8479159c40d16e886699a0f923807b91df0763a5d9869fe9a159ae0453f8d651302a186bea4ffc120c2902012d3e","priv":"ca5c56fd1b4e7e7bf623032e17a186e20b22fdd49a4d29d9bed5edff206bf26f","pub":"03a8fd0ffee636d66a64cdcc6032214efd1c069491085053808d03c1ae83b9fe96","addr":"ced9d32eea230544e0f8095b39b0a4e18b59937f"},{"mnemonic":"over exhibit wait carpet pencil record post duck gossip vocal all wife","master":"6fbad4c20428a892a365ee50dc66f8eca7773dbc5ecc34f85619fbf1a73822b7","seed":"f998a57ed4eab4d8425d4a71bb1fa451d7a79c8dcad33e18f90d6a4506f93b2adffbf3eb887adda7669c0108e444548a3566306264a76dd4b0955af27cb9dfda","priv":"bdfaebff9d0fc673539d8be5e59907647d0050a9241dcc4aa24c5c26eda0fa60","pub":"02d32a22a05926844a6b0f2f677520bda4c54e6b2c9269ac91127b626159a9dde9","addr":"60862548d4e283f62ff8aeabec3f25891808a439"},{"mnemonic":"spell illness engine habit bike able chimney spoil know nice tunnel weekend","master":"ac366b29da09441f12742ab837cab2a4636e1b50f11680c4e1adb7d337dfd8da","seed":"59e69d46ac9f2a9edd9b1909b1e5ad4b9fd2b401d48e95eb43a0f4f2bec0e6c60bd2a263e58bec77dac6f6ba45db1345cf9d74593c6e0b5ebe3fdc7c5f24014b","priv":"05d077b8eb1163a1fe2e5eb3729ffc7c1327435d4ac48db86c6db5238d5af45a","pub":"0364973fff68be7b91de7858fb35869decac0273ccadd7ccb45b057ad7d7e9baa7","addr":"c59c857a493b2b81957f4769dd9b7b5a934acfc4"},{"mnemonic":"thunder fabric basket stumble file sudden effort congress process essay excuse practice","master":"6c3de9715b71139a3a352a1d0b272aa0152402db4b8429c32654755430623ec5","seed":"eb8d579bad88d416336e6ed882bd8a57474cc5ba30d4a20e426c29a78bcb27255f6a6cb50b6430fcf905111f9b9fe4e3d4920d563887dbba69ec74856ce4b79e","priv":"a38f2fdb79ac8a1d64f613dfb3cad99c9f06554cb05f39b6f60c52eb7ad888d4","pub":"03d548248b4afab15ed5e91699d6e13fc4401d6779ce97b3bbc833c690302d0049","addr":"fd60d97532ce397f4ae9accfa99ac5ed9f5a77d7"},{"mnemonic":"twenty fan benefit benefit life orange crystal matter index drip mobile matter","master":"08a9533038e137f0149a965d12c1c90d7f6846107dd626027164146406c86fc1","seed":"d3f6d9f156c814e0f77fb7e9aba06ac2c9c3ee171b2d0759e2d91fb5d383f862aee8b7dff8c62cf61286d8f7f374ce3aeae7ab36d551f802523dbeb80673e0f3","priv":"08bd659717169756d9d66e79aa2b51d2b539f5c453ac8abadcfce3d29df49e7a","pub":"02e3885a7d4343012cc76314876fe67729e434202a28525bf69ce27a9167a46385","addr":"f3181c18f63bd74c4ddb37a4c32d0985e0af010f"},{"mnemonic":"scissors foil oven finish exercise typical catch dentist lens dolphin flag warfare","master":"9db47325d363c87e509aa52701131ad236317ea04515f4e24ba4f87cf99b2327","seed":"0246e8cd14b6b8f01d35aac9c09f8e526bf9f05393c5e1e77ddec53477275dbef74add79ebeeca7d081e58272f4a1bf1fa8621894a8165dbc681b967d84ed10a","priv":"6e7e4b51346f8d1997d81f63dbb7fc7bf4f022bb3b5ccda9e5d84c4a5c97849c","pub":"029edfb5c989c002795c283f445ef4d673101736c25617500f8fe655e043ab55ed","addr":"2a98038648503b442fd77f4d05a338da2062cc69"},{"mnemonic":"monitor vehicle bench chaos stable cereal acquire shock image purchase sadness hundred","master":"bf5d7680d5ad260a89229451e6ebcf3c45988a83df6740fff9b557eb3afec827","seed":"5bec19e9219360a8de56fa85d593f5330ddb158205d25d00d8a2307f6b420f11916311e104dcadacb638f5434e98efc8551d768586a0d8d9baf2ceb0759ffa98","priv":"470256a6d68f8de27b0aba26684cea4c075f384bcdf8a68bf5418dee37f08dbf","pub":"03a1193ff722ba3b4bf7d257aca5c184fc776540fb139dd9a404d3743d31030971","addr":"5b4796167bc701e5182f16e2119d7e9d491881fb"},{"mnemonic":"never dentist blame parent sell income parent bullet eternal random seven urge","master":"665961de4995f001085ce2f1058422bfe5ba0132cfc5725f0c5c9d827020663c","seed":"79a95f522e50cb551c7fa70d54c0aafa5b794512be4e91de2fe1a2e9c17d76bd55087621a606107f3fb19486f15dffec5947cf16405304914f511dc43844ce97","priv":"88db51c0d63c95730fad0c616e4d4fde5a631dc3d315fc74db688ea1a7ceb5b5","pub":"020ebca88011035818999fdf69ccbf691d93cbb6bda65c68c0f2ca10757d23abe2","addr":"9de8cf2beaffcd389ea6dcd264444aae075a1590"},{"mnemonic":"noble shallow label region age proof remind panda useful session poverty open","master":"a8e1a3cf36520d5ae852890951b03cef3902f9ca168cf53c4ec6289dd802ad8f","seed":"0cf4cdddf1605c5c895c1b81fd523ee83239d42feb4a130105c2d5d1fa371e00cf34030cf02ef51aa53596253e264da2c3ec220b97885202dd73a7b5824b982d","priv":"5ddfdf68cf41919145c9c8624c245ce9d6d8c380f5d0153b6155e92b253b1b22","pub":"037943f2b34206bfcfc1fe236c77f6e844d98cef04671431a12883e23846e8e7a7","addr":"559839fa53e5b7408f3dbd00ae5e80f56042417e"},{"mnemonic":"hope inherit quantum text sadness dizzy glimpse cheap expand legend kiss once","master":"c307e0a3f22db3e59a7b28b931c1ba0daa0a8e8d743660c48b6babb4b9563702","seed":"6fa72118b297f2bcefab29f19ad4b701791f72cad287681e2af3e92595ec6b9f7a15b08771917d1754053d1e74aa1a254fc3d6e27deb78b7b55f35a5154964e0","priv":"1a6b9948bf4b717756a11e43847be38ae87b0f42d718dcfbded3bca1a8852aa8","pub":"02dc42929ebaebe447d089cc702bd8e29457a2619047a1d7c80cc4f2639a82246d","addr":"bdd0fc12beaef99e0ee5b07c9c2f41bd90163bf6"},{"mnemonic":"smile odor upgrade deer mistake bomb friend ability then segment orient nerve","master":"17c87ed5d20e5089408ac7fa68024124053d46bfe32fc04ba06801c45b6e19e7","seed":"f620d852a56ab0eb7d55d271034b767eded17ed740ada7f8330fe6d9affd8d88e44489de06d6d3f7b84b294a847334ea051ca63f0be4742667ccffc79031b5d7","priv":"8f90608bd45f866e9fad2a6a316fed6bb6342815ed79c967c3eb1be727ab8aee","pub":"03b6b746569b0ce4b97c3035634a2b30a519ec23a78402137c7ec395d35c4eedeb","addr":"179277829c7cabca8286a52ce3cb591ab22fc72d"},{"mnemonic":"black ghost quit birth dial helmet custom brain diamond rally local season","master":"8a6f8c836e3e83ba6ed94a9de24e1133d4b04fc436827d810c23ee1ec9406fa4","seed":"6488a47cd4123eddce9bd31a0982eb0ce8208ed5e331081dc18256dc8b5a1718807bfa267ae6a75bf1601b99c784542c3d981a9350f7f268d2666af3bb8e3680","priv":"1e7100a43845319b4bad268d111eb3746f09c9a005e023c45fd1da984d37e49f","pub":"035ed8c0324e4956ef2fd2b5141260cb6dbc0943708b0f83c0bca0e7297a27daa4","addr":"d2d9e9b6ea946a61082fe98d9b0a808f5f0879e7"},{"mnemonic":"advice uncle change position drastic leopard praise rack match toward paper faculty","master":"9583a2771931234cdf27fc8a96d06766d4c76b4bd25247596639dd21da4c95f2","seed":"8fa5760f5f2d36734e05cedd78260e9ec7f837bf5b7edeeaa8f4f3ecab9a1f82ca557fa8d75d7d779e47a29eb7c974264d98d12fe7af6a22a87a70bf0031cecf","priv":"3a69d90701054f78204f1d3c959f128dbfaecf4ff0cf6c29fe5ada13c96186eb","pub":"038241211180ec347d2459f2c22c01b50fcafd8ec1ebb51b4ba648fe291bd71104","addr":"f9c6730eeb7a00027b3deb720d6c541bc6b0aa89"},{"mnemonic":"carry enter invite orphan file grain pact glance ahead grace action mistake","master":"b6b8bb3d43f27c84f1e3fb1ea462c9a88d8544b18b22d9b9c13379954a3546bb","seed":"a0078d2fa9187ecae2b8ad3d4121e2567695c1cf26bcd441536ce95a6e04b4feb41c1ceacb86ae9ea26db4eeeefaac7e0477eab711b22d5390be3eb3daaf97b3","priv":"7503c22dd0cad622d4337dbd7e0bea66a2e8b52427cbda01a9c5959ebe8b5a73","pub":"032c577bb5610ae703c54444865932db4edef3b8c84f88c71a25731a85515eb69b","addr":"f268151a05642b378f8738ec00b2e486e60e284e"},{"mnemonic":"taxi betray parent equip margin snack spell agent talk possible portion lunar","master":"5bba6a340254e9803fb2889beb84d4bc63454beaba3f10cb992d5823b23472cd","seed":"a8b970f56b960fb9888f03013542e90b547f7d60aa91218105808e595a561ed37c13f259692d3dea5d324d0c4142b30e39cdc2e60697ddb5f52a5459469fb31d","priv":"ae63f7802417743bb8bca410ec64380a407373900e0af51e6acd65ec9d54a0f4","pub":"027410f719925fc55875ccb78092d5e6c31b8543e115ff39bdfb9a26f97fca8859","addr":"da9b8ea1879e13bb49e7b9d179e5b56cf6de6537"},{"mnemonic":"sheriff marble regret shrug shoot tornado coast that obscure sense duck noise","master":"e97a0a9cfbcc28b909f7a5a617af10289965c6901fb06af76a6fada22e41876c","seed":"7a231c5b3b91408a19de9571bcd820f17451562063ad2daa85a1164a952aeaf8d6a3c703909a76aa1e1a2818f8fc36d8dee3c87184b59d6340201402384fb7d3","priv":"d3fbcac181c592367cc527d8f09b54e1a31d3b2c3fb5c1cf4f2ea897c483f5a7","pub":"02b3e3765ad7c3c020c6a166b0113b87279e66a53859ccbb9d214181e2be30ca01","addr":"517212232acd318b376fcface8544506a8f76c18"},{"mnemonic":"connect drum once first trip dust trigger duty situate burger toilet half","master":"073fb31a2785afedaea95e67ac7a3219f2f910aa01b054022a5185c5ac99c35d","seed":"fe3d1ba2740ca127dfc5bc22ab6fdbcc930b957185a0b16b1919e4fd5e637c053b3d356b12152cda6d07f7088f16195319075d0b3533e5082b45f1bbdb7d5a74","priv":"6a19f33e357328d40aeaab5323764bf9e12df8b476100baee9d398a0fdbe3970","pub":"03f639ddf3dae4ec84bdbda49149d2fc3461b2309d043c89eea46bd99762b54a0d","addr":"c8a8a454a5aad713670e936b63c519c843874b3f"},{"mnemonic":"shock later journey twelve any ripple soup climb globe impact poem auto","master":"382a7bfaaf7df9ac5cf8ad1f574bcfdb98e185847a92cc36d272b74a14228259","seed":"aa3bbf8521133a0fba514e54147daa2c6fe294b1af8bee3a6fe46ecd480983d72635520db97bc3631d9bdd55787b07e45d81b052522fb7330f4e0f6aa24fca8c","priv":"dabfdd6c702d104e4c17dfea719ed870c783dfbcc66e8987bccee888658bff76","pub":"02efcce52d6c7ae70900d892e1b24ed5af6012c38c15864f2d15067457a2c55f2d","addr":"fb3af390f0137dcf7d98e2630021061d0fbc9e06"},{"mnemonic":"news book language depend fine fabric idle curious depend plate fold sustain","master":"4c28a9f9d854290f4655fde6a91500dacb684417d8dcaa69435e1ab4b8f04e3c","seed":"2839463d79148eacc1d367f9ed0a2ab8ad939643f439c276bb47f0fbdb4cfe8795001ea2e5c24a6a6da9d35cc6759c37e50ce49f34498ea61a74dd11b14a6421","priv":"d6ec69e742e0146c9811de01cfcb07b3de56594fd4e374722ccf81dd143e9a12","pub":"020f5c54b785c5ca65547b2ba32138a47b8b5b462b304e0cd3ef981b407ee73b87","addr":"2850f467f64992626b23e03d366f34f4e6760807"},{"mnemonic":"equal energy inquiry frequent aim wide exotic tail vintage toy marble spice","master":"0fae6d570fbeb343eaad5bcd272d8554fe27a9cde389685263ca1020e65d4a1c","seed":"62aa467a7dd73249fcad8432d188e64a1d0f1591c66912f906eed133ca0c1e99eb068dbcc8ec37947cc846b1ad4f439821324c61bbb385fd91b2e440d6a86e41","priv":"1a254e7f18b0836975e187a72d0cf1d1b69225067167f44dad6aaed6065e60ea","pub":"02ce2f7840d3f69580538517852dfcb2932285caaab4d11adb98ccf335430fa50c","addr":"53117f2a5d41d6e727db2975c9dabb1d28708d19"},{"mnemonic":"recipe prize resource define enact basic glimpse chalk box prison approve fossil","master":"ee8a619974bcf5cfa95af842bb003ce4f5236abac96eacd51ec8f797bed520a8","seed":"b2d4c119da7c72c24542998b036b2e1c501b0fb990154d1b5abba4c5ab9233c4caf1a427948faa62aa862002f43d115f2e4d715b8c9ea3eb662b2514ea06390e","priv":"0d896d53aeb3f2fbe634ed280225bdbfd10116e18651b3c801a3cbebb0f75ed8","pub":"0320fd7d4c9c548c28d08e587f45836902f14c7380cfc9f8119e0b6e36089369d6","addr":"949025151f752888794030aa47854ff5ee407e09"},{"mnemonic":"hunt carbon lady smile luxury old empower pretty memory gentle public pottery","master":"e9542dc3733e40f7c1e5f540e241dde57a09f76d28e889f69dba48d63f0b6445","seed":"ee0dcfd61e0fe95e1e0428f29c78076f302cc5a55db61c13f9e6d84811bb0d57ba3dc109d4d98fc30c1d2e5b25bab1c646623fbb00e5b3719e4bfc58005fcea9","priv":"e846c35be2eb1e3781e8078d8433a9816d8f8701131e69873290689940617de9","pub":"03aed0cae3a1054d184c820d9dcd5118630febfc450d4972b4963e56de2b1005ca","addr":"af41527e26ef2ed7e1692f2897fc48bbf792c8e6"},{"mnemonic":"captain disagree filter crane chef cousin one cherry able scout tip magic","master":"bf4a3d4839793f7d502e24a4ef4e99bb39fb2aaebc53149eb004ffaca0256af7","seed":"3fbd2b4e5c614a29cfe82ff906e94be976849cfffc6831d67fc47bf2dea68ca06fea30de70ea546adebad96d3fa106950545350e0925425f22a0ba1a0abfa3d7","priv":"046eff73ff79adecbc208e64dd7bfdca16c4593a1780261377ee48e44ea06d57","pub":"0374f44a020872df00e0101f61fb61e76038f6fa8a7d50a89757db14b2c95b76f1","addr":"130a585f378df286341fa93925eb5d630adda295"},{"mnemonic":"inform measure recipe evoke make recall volcano girl obtain flash soap prison","master":"3bcbc5c191d8f5fd59988894fb749ec333a07e909b3c22108500fe08cf7edb53","seed":"cedd1141a4c9a1e349435e247349994c909811dee5770ba3642768518cdebbe7d7e5ab0776af835bcee0913fa1bb4b72205e9d38b637196a624f031238bd2bf6","priv":"9c070a30d5ad6301d73ece1e6e71790327c6922521f93d6e8b7c69391a12d37c","pub":"036ebf4e4d5349613dd3c7375703a1025896ec4377a9635e9ddea2a2dc1e7bef22","addr":"74a413291b799fc2866fc7c7ed2d2becee9f15be"},{"mnemonic":"carpet poem piece silent boost trim famous coin fish rule leader oil","master":"ab7b210126590431eb1c09ead09bef99b689a429cd86be65681debd5deeb1ef4","seed":"133b317aa1f56e79697425b4c94aa52d5b7a95c3fa5ab6d437bb1b310bae6baafdc91ebd812c76b721fb45835f3ef0f61730320a8ca6e7cc18291b84af5ed68c","priv":"1863a0b1d15847102e3198549a59921488a67002e38af1cce7ab2c0e055eb498","pub":"03dfd8ee8642ccb78642d0e373ce9b15ce9384d12b36086d2c64601ae8d18325d5","addr":"b70aef2f2dd6e42f909a5840a6cc7e08fffff26a"},{"mnemonic":"liar hold orphan include gravity nothing erosion offer average now ability purity","master":"71b19fdcc0d8e082eea3d92a5e6d36512273095251da9177b7cbd0bc2e5843d9","seed":"e58ade95c1063890ab5296e5d8a07e20ac80a159afeb88c74dcc6bfa8fcff6c85a2f19af8404d3e457492c560e4f04becb6446e290ec1a376564be64ce1c7ec4","priv":"2bdde1157be2917e98549af370aedc6a98fc5d6df99db71650ef29407512912f","pub":"020a188651de8022da9d74bd298d324c54c88e35268eca0907a5f6366f9ceb3287","addr":"9c4c3c19a81d424ffd69bd29802ff155f52e219a"},{"mnemonic":"crisp security increase topple put engine wheel apology north tent front minimum","master":"77288b3b65bd31029a3791d357521172af895f1085c1996668a1a689f4473a93","seed":"af74884da27f1ce251a75244ac945052c4df5fbb59e3b12eaea5e28c8fc26b8ec95bdccbdf5481eba4b74680e642e5e7ab2b0f6a4d0eb41db3c08c01162520ca","priv":"4d1df90eb70f94aede9dc63cd951a30730364379bf9a0f339d59d5970095eb65","pub":"023f2f6cf79a65e2d25fbff8c422ff519603c2e400c5d3b6523a6db06b969c071e","addr":"42bc49b12a7eaf46695fb1ed32db0d32e8e661b9"},{"mnemonic":"switch shy kid child occur salt cage local top blade cheese width","master":"5755daab29ff030dc4b255171f77523530a659fdd70bb5fddb69d150d4e7e1f3","seed":"dab58ef3ea14f3041588a5411f22cd426ead10057616df799cf53907536819056a21faced7e56aacd120181734640821c082daa86fa8ea4b39ddc40b5bc02aad","priv":"e5c1ebc0e3428c9ca42dfe809495dcf7ce2abf2b149664031b5f5a9d5d2f8b4c","pub":"03fc64577364f254c6f919e1a9262740987217fa2c66ea490ee6d3dca1787114f5","addr":"1b83078e35972e3ce3b1bb062b3924665a6e5c5d"},{"mnemonic":"rival notable exhaust climb disorder enemy desk owner again twelve mystery devote","master":"5daf52423aaf7b7ac4d8ff4bad65d81f7e3b15021222d3d9ec788a2d35d074aa","seed":"709afe1cde759d12cdf4fc3a68793b35490cf0261397754a62dd5d40fe528424e8deef620f89337dbab01bf57cf241a6664bb3696bd76c886c57a405170a7b74","priv":"b171a7ea63d6e1b8aeffbb63ce5179edc656e17eaf85609ab0d2680e35a3d64b","pub":"02cffc5dff2f9896d995c9f9b6d11c1cab3e0d40a25dfb9da5aa010b703c80be0d","addr":"cc673e6d2578bda7d7054d2d53b841c26e15dec4"},{"mnemonic":"defy prison walk thrive enforce match turtle venture margin quote must cute","master":"9d747975a6889f2bab69fecae39db2a10df1545ae418596d97152de0e7cce077","seed":"183b5f3d963036b0e22eca9717769422bc515977c0a7fab66d716318de12d41a01f5ce101bb47ce44501f0908f8c1255f8c3078fd2c2084aac32624c20647806","priv":"a871082f9cd061e39987c76e516a7086f82eedc06a20081161e13dcada541f61","pub":"02726bfeeefc2d5ef521c3800ebc7700e11aba3cec88f8be5c9cf3275f4ab254ab","addr":"6d793f4478d2e4980a140b724cc8012b44097446"},{"mnemonic":"lyrics goose draw review manage recall snow lucky mirror swear fish rhythm","master":"b69e9a8960d5cf2b8f457e6a037654bcc72ec1d26e4753ad34512a877cc329af","seed":"47054d3ca54f6038ae500dd6a7f8b5fa3265e87b384c16a4e68560f56dc9f7945d599d6a71b2020618c9f7bab46bc6817062751f19b46c2e05eab7831fda1cb8","priv":"5c0efe877506f2f46bf345c71c8dc31239f9e23a543193d5ac894faf0aea9ddb","pub":"022b90c4806ce022e81c706555ba3cf9597861a3d7e28b9aef6bdf36211eba916f","addr":"a3ebb9a579f22150fd9b7cf62a5f52369fce28f1"},{"mnemonic":"coach silk assist potato gesture hire bullet piece document outdoor husband panda","master":"541e3f3e4e4e9803da42f2264efdce5b9338d410b16b0e7b66611e5dec5bf896","seed":"4368a638c45b7ba4d2f1953eac650631f1a1e3c23c72b545dafe466fcda597a0b97dc3302072e50a298989f94ea255290d3963ada9e42e064ae300173531f273","priv":"b9462f51e3c20b3d805b54adc6b27c669ba07d5a5c97edb0a8cc6199d772097f","pub":"02dc7826d790d013e76765b03447d2dc92a945268e42611c51080b7ae207906bcd","addr":"e59101c16f77cdba771eaac3ecf416232f6dd1cd"},{"mnemonic":"wet problem raven barrel explain long call civil pact swear luxury expire","master":"1e2704a2365215a83dda9aefb1093e095c0c06623f060c2741e8bcb8480c4165","seed":"fd81b59cb8a4abf789c2fd55e2d9366051f8f64f54a3e08d117d344b633f2ffd63c1a6bce7a4bcbb01261b6e41f6330ac5d0b151c36649ad59c0cca7e4b3a820","priv":"bf9f0440cd63148ea0771d0f892efd3cc0638330c428a50436fd048aeedd7ee3","pub":"03d807ec07f4f6eb00f9e3ec69dadafb3201cdca3e878367ce4245af65b8e4490a","addr":"e43aabb2d20275ff60d591dae8d83b938a0138c7"},{"mnemonic":"unique mobile gospel cost genius symbol online rack round canyon front again","master":"ff441298736365bf07856cae35a9dfc2612a9d015592d5326980225c4d4e4e21","seed":"e05899b5a5a94c860cca584b6065284e961625486b1ce1c80340721fe4f89fac7afb7b665464de68b5c5813e48896210a90d44eaf013ec4fa90ace43e3153d3e","priv":"45513cc23e8ad7f7b5932988637cd6aa85f19a481cdd20c220f0407afc69c688","pub":"036080589a5268143509bba4c4f26ae8a3ad7b12ef7295c9ef416cff53b66b39a7","addr":"68456ee838f224959e5c29649f41eed02b56c3a3"},{"mnemonic":"street bleak prison artefact pupil armed blouse pipe eye brother man aim","master":"6e0891146585834da8d83d0e221c88d53770f3c56f68429565d011ac697238aa","seed":"8af79a74ad501d308be613981a1a25342791288f14f05b7cf3b81131ba2146ea63e01ccfd150c4d2bfc42d64adc899158383d82f3bed0eb772851fdab4f901c7","priv":"86c09e2544c86b883e8de233ee297fa704c39bba463e5a8742c4fefc9ebc109c","pub":"03d8cd38cd2311a0360c84cecc58787fa3916c6c2adb5b2baf12a880549a572f7a","addr":"68c1770edaf76cabcf93c6d94f4510162fd36924"},{"mnemonic":"love wear kidney math magnet share mango also dial fabric near destroy","master":"e500e6d3a103eb11414e5ebc9e27eb96456c48e9567155c6250aeb83920df860","seed":"704e740c6f437a9e8b7e8d7e2321ce81d9132c9a6df7a45fdda99cc66a09c9d73350305aceabc0fcbb589bf44911917be71e9f399c401f86246d0aebd4b467f3","priv":"07c906988f937dc841918a7c3092f5df0cc0a6ce4487631774cf3f703e9c2713","pub":"02d131982bdf285fe3a37370ae0175438094cfe3d6fda273bf24320008fbdeb5cd","addr":"df31d832d2d23502cd0198c5947e8297e6f73eff"},{"mnemonic":"nominee connect useless dutch double vehicle rocket exist mango floor educate absurd","master":"0a66acfa6ac891a588255bef6fb1a845f2756ff0a7dee8d2ff33a19a7b22f18f","seed":"4c4e362fbf0dee5928b21652552815edf27a4ba5a11a09dfd83f3b53a44cdcb6acff4c39b16d2cb9ea3250af3743baddbf6ce90ce1e492fc6bb53f79d646a4ea","priv":"e81668360f562929af7e40c5970bc685ef5aaa7d390c1bbe005b028460c79ff9","pub":"020a16c5a1098493bf1f7242de71bed03779c4eab8f35a1c6859035111514284d7","addr":"c8a841f39aced64bbdebf2f8f834ee02ca33a8a1"},{"mnemonic":"sweet leopard loyal problem pupil perfect power flock thumb wage person secret","master":"6fb555e482a1987c2c0f129ffc040fab9c4eeaa3c23a3370db7b4a5ebfd2cdd1","seed":"b20837f8580aebb15a7a4b035639bc04e27bf33e1f600069ba1378a5dfdeff3e95545e6828f339dfc30eaa449c78b046c21fd99b24d819c735e050f6992f898e","priv":"9d06cb0fa2cd01675e038897a14e6b7719ae84ca6002ed6620a557877ec373ee","pub":"03f49f50e673851d74da1fe24aaaeb75c2cedd25116c003fb4a810025192c3186c","addr":"7f61e30a20df85042cfcda5163867bea46b98702"},{"mnemonic":"slender tilt tell faint dumb seminar cycle tongue bundle case swamp author","master":"444b57e7f846dadf73a0bf77fe918e8716454416501c84a48bd78dacfa87b885","seed":"4345b114d1f3a78c5582ec5469430a8cde3a1a866e64b3c3606b84f62ff48bbff48826cee928374a01aac080b79269f89751a11aa086fc1fcfe74cf05674ee04","priv":"7c6d51ee5199457807c66f22e8d9b7a703a4e61a84cc791efc3cdf5f7038d28a","pub":"028b09c16923224208b6ea2ed777a2e4aa2bca5674eb8f0021e9bfc4e9d3fa0a69","addr":"2486b9fb36e8849e09b147749e445fb515591197"},{"mnemonic":"alone oak satoshi diary artefact virus muffin quarter identify car whisper topic","master":"b4c37472c7fec6dc3f3452d4aaa7c306cb65ff940052b0aed224c12104296648","seed":"4dca6ca310d5028c4cff946edda516d55c7de81309109e6e3586927a8fc2c4095215ce471774df2795f04fa01cc2cc528c44a5968320ede4016d68c24e4bbacd","priv":"fde405fb9a8f0e98feed3f4e996b3fb90193800c571a89a2c681c0fb4917afc0","pub":"034bbb553a8525daf361bf0c831c756a56ec476c0c9a52b0c74dd9eef35177a776","addr":"c890e1e83daa169e0295ff2844edc5ca2a7ff346"},{"mnemonic":"noodle hour inquiry know sort review oxygen observe exotic script mimic march","master":"3be52af1a8430ba7c4610dd4bb1ad67d978d40ff7530d712cb5728bc961edd3c","seed":"e803e685c85a1a0a4a382d1358f5fecdb8821564545d8573f3708a01f0f0bc1da54544ca2338cb988e7d6239d18c32bedd38e1cb9bdf1bbb6dc8cbb323055510","priv":"defabd99910867339a4af3a425caaffad76ccd47a43b05a13ad86f3d23887b03","pub":"02609b9ff36c966dff6399576fec7efa83cf0fdb66bade72334ce2ba69161768b7","addr":"abef04d453ccc6d443cd60d6f964d008eb5f08e4"},{"mnemonic":"crumble loan economy dragon vague library slush ticket flip mixed accuse switch","master":"f085484747a4bf869f38da6e6f56b9ed2be60b137536a2333f2c6818d76fcc68","seed":"b0ed9b4d75a17a53b33a73223fb158d79999548d13919599ae7eb71cfe2fcfc06cedc8f94cdcdfb05ea043069c426d2b78e2f67260644109c42a6d9b3f7d5134","priv":"a64c537c561fc49e504e870eb3608e69afdb2cee4c6f177c63fd1ce170a67192","pub":"034f7f99f2699604d3f9869dacf1e6ddb387bce4e0d13fce3f4aa85713c7976048","addr":"4b51a7f925c0e1b428b1ec75dafcb0e4d9852620"},{"mnemonic":"rifle swing confirm response name void scan shoulder lake oxygen uncle south","master":"3560f172b5c2ad665da648cf0809604522eeff5fbb2b1e0ec50e7197bf711dac","seed":"85386f49048f371171ac3ed2bb4f358b7e22ae406a7f2c9b3f494f2f7eade96f2b6f96fe48bff1754894b8b2586013393f0b9f0365c6996cd251e668ee90071b","priv":"c79860b8ae43fa4dfc570b2d20549b457ebc6e18d38865ec9cb1ba571409bf12","pub":"0253d92439ae131722981eb16924b26fe01421e4222152cfd0505744278f963dec","addr":"ace153f8d13e8cee51a2c08fba9f445f50e818c2"},{"mnemonic":"air floor random smile mechanic exile run auction avoid truck expect old","master":"a7cf0d4043dccdf5cdc835419f5bf2665c8c10e7affeaa2d8cb42e3787bcec00","seed":"e4d315f6daa11eeaea17d513f8d6df6ff2dc13dbd2e09158af03f847ee6cdcac2d6b88906ae62e84355d9a0c0956ed465b3f8081837d45eb01cf785223404306","priv":"5f1f737625360db311accae8b8ceca9d4f2aecf15d6e4b91db4c407bf75345bd","pub":"02f467c86cba2d8d6fa258d16e9b4543006b81c61bd357a2b1d79b9010fa30437a","addr":"458f265c275940d726dd9714413a56efb7f8c4e9"},{"mnemonic":"assist right street define hurry section tide museum faculty glance power aunt","master":"49eeea0b9687360576a3f93cb31eaf0edd3521d2cfcfaa37434d6d51a2f3b5f6","seed":"9371c5276808cbae376bf529372c88e6c5c6178a9b469ef25a7558ad68fd6200a8fcfb2c117b7d99e9c7db907bdb8c69632e7ec058f2b8a4ea16518fed9dab82","priv":"936dff8ec25f22522bec8ddf52535a4320327697a581e9304e62240e5d2f4922","pub":"029c518dc7e8261f2a64104ac846ca90439959f4467e69dddc7c902dfd41fc2177","addr":"5a6600220c96af511e6c89dd9c8c80f1a1b0a893"},{"mnemonic":"glare earth tuition dish elevator mom remind arctic enlist excuse vacuum little","master":"a251df0c9b6925fa78489dc803a34839d90aa10dd35216360fef92173e0bea80","seed":"4a543a76deb55a8df2a58d0fdca3ef32e3f3ca74be97789cf004d1b69608763f8d311c6cccfa76bb6c7b04ff8d7ce20ee064d78ce4e2c05d894053e8a5309349","priv":"0aba88dc12cda2d2f267dbd19ebf0eb390483c7384895b6b7669ba821b73953e","pub":"033ca852e0b43e2ed4c7258c43bcc5be47e621bbe6e0bd570176940aa9b371adce","addr":"983a92fccb0350a8371cb5d5effae7125615316b"},{"mnemonic":"tornado group bring crack need pigeon scene quarter affair purse three mule","master":"b4d54df22150e28595aa5e1f6717ec764ffd8d2cc6338e264dbbb46e9155dbc3","seed":"85c281d21f25c14304aeb5402e717b52bcc0e5dbeaf2d155e11913717c545baf79d4d965670d7645bf093ff79f4793d136d794616905c2e24a8c72ba1af44ba8","priv":"c45a9afa0dcbfabbec916a9fba6bbd9cabc1a65b4ae3358e29943dee9d19ef9f","pub":"0272882ee11e688d04b89252ca1000456fa743b5931ae03e1d29934f79980baa41","addr":"860b69d255bf12d5f725e286203f91bdbdd29bfc"},{"mnemonic":"toddler bamboo tornado season total battle urban mule oval steel field case","master":"af9ea8f11f6fa83dbbd4ef32dedeb88070b3fa9fd98d27e1d9b43e66da7d3df7","seed":"4b95b55884e008f340660a6c9ed4f2b23f45a5e45535fb263e880ad8842e845a62e66720b75d94fad7f47fb494bd32ee70b7a339de5b07bb13c7f0533e8cec57","priv":"643eb65f5c87407a18be41f6c660d4d1ae610c9305833c570d785006b92ae354","pub":"03d1c423839d02f40abf0632a36f9739c6ba59622ea56e1085d2ed54504762b43b","addr":"05625426a47e8c11f27fc55a53121bf748c2d05b"},{"mnemonic":"meat endorse bike truth avoid measure injury polar rely water rocket zero","master":"23b56abfa50026840bf19105ea9a02569d1881e2cc447a582b08a6bf6304a33b","seed":"d8de461e4f04d4657de6b5adf8730bdbb85fd175326671886017c09d8081ddb7dac0b8262fb01f2dde477b3e2bd97653a700d373fa29ec7db2161dcbe418627d","priv":"f409c92079cbcbd9f96b2bf0d84f86d495bd8e6bb4859fff2d62c29558a551c1","pub":"0247908ec215a561a41e2da6ce05e0ad08158bffbef9fdf7bae729592e4d17b45f","addr":"e4cb61da62a6176483f967aad232c0fe89a9f16b"},{"mnemonic":"few transfer upon helmet property draw strategy talent awful goose index lesson","master":"c0e538e1e0b819660c63ff668869a81595107458fdad44459f6ec22b251d46e0","seed":"fad56235bc5f3a7dfa666c85e5782871e7c202bc4363da62fe3771d71b36a9a1502d550d668db69264daedefd7375862b891d4193cf958b6d8af9b39a9fb0e3f","priv":"51c8264448b81467c2c86c003765322f7c763e0854903230a4ff3557fb7afc31","pub":"03bd00d092d311add8fbf191abccf181bb5fbf83e26d6e29fb6f4d70055ad5e7fd","addr":"270429d79b582d835fff0b15b0eb21ba1c98b2fb"},{"mnemonic":"can warm add shell obscure ability mushroom discover destroy useless split blush","master":"611e2b107ee76d6f7b415776c7b0c6f03859366c342a56618850c6e3cdcf46c5","seed":"c9f4b2663f8abc8c8872842c41fe06b5911b412fdaa875ba59366d7a18734aa795092d220793867ed43afd1d79882ffefde417ca68c9ed61a9f52437d7e45a53","priv":"af975acc3008d742a37bd6917f4a5c6e9a5e0fcacdf1e74ec489e675905dd9c5","pub":"021152804b2ac5099446aa5e8cf1fff850cab08e225922e3865ae5b280a230ddf0","addr":"d4baf915a1108fabeaee47ba0b03cb241a12e1bb"},{"mnemonic":"critic length shine mimic gorilla rebuild bike security price differ spice average","master":"418d3fa386032d0a22a3b4553ec662d52ca416af47d0963e288a1bd08ad50d20","seed":"c44a2f7e56ffc9850454a03c40be79555c340b8bb2a7559a664a8e295fb34fe1a38074101b431038c207baa219181046805a67977022d61bff2270c1e27b80b9","priv":"117d57d4f3dd6db8a718e025f4fe5009949139f2a41aebd682ab49f96ed152dc","pub":"034af1a0205014cf22dcf328aa9308e255355dfff65a7185aeb180061aeece5084","addr":"f7af8cdd0592983c065c322efc64bf7c25769e2a"},{"mnemonic":"vast resist ticket hedgehog around fatigue rocket rack carry run protect icon","master":"c434c6e478fbf7edaf97e2c90c38369de3033a98696b1ffc793aa349849c629a","seed":"720f1afc198446db8a107105c7398d3bba7675fe0d01de12f933e2eef7d12effea0e9d93099e0256b9e494607bf45d855fefd68543d9beb4b92f3d7779a8616e","priv":"497b2409c651a41ed36e58e977611292bd665e273847d4d413291c386d0d65c4","pub":"03ba0869f55efde74895a6905dd149bfe140fb2ee4e3eb19c959195d93adaed2f7","addr":"2242ceef764c76680a768594f804e218154ae3e0"},{"mnemonic":"neither bunker use enrich liquid borrow time feed mixed clock submit scorpion","master":"a9c4646a10078a9ca6b218b7da25745a76cd7dd9e38d803d8e840863c9b97449","seed":"22cc85d4e408d0a751b854f16e00fd16b018fc26f95aa7d82323084ebd7d7bf3fc2370c1a5e38f88584e8a17977f17987d75e447f704603c2d71b3ccf806afd0","priv":"9801ad0243910e04b7322f493540801628da575ab5eb18a5e0b20b0ffa498e5f","pub":"02c3f726202db7040a250647799f5791d4013b38da6053e44f502d0c8a064124f7","addr":"fb0ef77563764b393003c137da2dd1ee21d92904"},{"mnemonic":"letter violin disagree arch crumble amount car inherit wasp vintage disease orchard","master":"a24fad07da3e4a04fecb2674abf8b4260ae5dd71f003622bbc4a00292dec3cf2","seed":"890b94a33cb176c697b9ca49281c053f88a8e8bb6f52af5f0fab57ce621145ea59624fd9f17bc4d7ff820bd2998cd1d4a2dcf8f89738c150aabe7af5f87a6b1a","priv":"499b6d6e741483ddccb35f917752e51970c5999900b48e18b2d1edb85927b7e6","pub":"03354167051ad5a01e056f7bb655de9af430fb0b3756e1cbbe6dd0cca65d43ff18","addr":"efbe8995bfb51a94b21826bb93937616c5807d94"},{"mnemonic":"elephant shoe quality dutch pepper math between lemon wood below strong grace","master":"7890fde1f36829461985465e7a7ba26ef80bc9908e5cd849517a999f04b02ef9","seed":"077fbcc3c57bca394c393e9852c3b837ab555cfcc5dd0097c058136bf088fea569d18fe0d447a8bbe53b5f22961de7c5cd0000274930db60ef18f049aaba4741","priv":"0af39cbaff322b7b7298b2605fc762bcfa69ff84a50dbb121502ed1e8db963ca","pub":"0221dd6d3d3c597b982093f5ddc4b8403b3d16d0e084aef37db3526f050c9b66d7","addr":"81ee7b181a5d1902b6aaf42ad0225edfbf669498"},{"mnemonic":"powder marine skate good skull correct catalog parade car length fold clown","master":"dca44cfd6a67d213ff365e5dd6bfab6fe63ffbc999c9d38e48b9c8d32d32f914","seed":"91dda0ed96be1b82432b76bb7dac1e80ed0a1c5413096d4a22437081834cc29f6355dc3e79d7ee00cb6bbe50a83fdd3b652259937beccdf11b844ff023269e76","priv":"25ef3009323160687cc6651338320311894b8260596834e6cd05c1b921c7254d","pub":"024b805e8c768c8914ad8c55d8e1898490b9c71fa68ef43d07f3db496f03db11e7","addr":"57c28bc9cb2f4fea177c34e581c95832256090eb"},{"mnemonic":"client wagon legal favorite donor tag describe object camp network tornado immense","master":"4b916d7a10502f4e2ecf295d826a3248fe9bc45a13f1332a46586833b2f1dc05","seed":"e2726352ef940a7cfccbe95172c1fb07c8c25ddfd7ebf5ed532f27abfd33e81041e816e34aff02530525596654111ab3186fd71bf65dd3dddcbc6efa7944c347","priv":"131de6e55bf3b614153557b35c839f0c869cb10d62b8c34c15fa2cf7c32bf97e","pub":"026a3afcb9ce79972ef910d6272613580b199f90a00035ecca637b09397f0624bc","addr":"b2ac8314ecf16da855c5d7b9ae3aa12854ae4a05"},{"mnemonic":"someone tip green vague sudden element beach people route lawn vehicle female","master":"2f7b9ecb854a851e308e944e6a8b39811a286e718b4ebb9a36e8c8570cfa7890","seed":"7653cad23c600649423fd68b0c7d002feb0327551521059362b3914a63f6ca6adcb1409f7f7f1b01f5c489237b25d0dd9b0aa121a60b1af33cccf739d05e32b8","priv":"4b3d50735f027be5ce5a85a739227b4e86590765e34b3608338497fe318cdfc8","pub":"03b47e6036447632c8ee3d2d1e3b177b51ea73bddd30893818c81059cfd3ec6c5e","addr":"10d976ebd58061a7c6ebe2ccbfc85adc617db2ee"},{"mnemonic":"version borrow decade family away zebra one course paper promote man gravity","master":"ca2995d4590ccdfa716b0f27a3e5e93d084df7039116b06ce5b4c5f2bdb18ef1","seed":"97a3f0fd0c7150526375d5cd1ea192dc0f04ed096e5c4895e0a15a6d491b206b59d52800c2c31ac6b512664788ac79663135f450b5198f358dcfdf1e9cc26e12","priv":"cbf04fb7c5c97ab9980cf82625a612919a85e72c0524cd49c0a237c25940b563","pub":"031f04b34f157a07b6bf50fd54ff972b8441a72d6a5d4fe1e54a1867d07fb61cac","addr":"57488105d27e808a39fdd571c895dd06264d3357"},{"mnemonic":"truck zebra tobacco hair monkey pool label produce leader hope misery cost","master":"b42e61efff413779403a9d5ddfad5230412788de3c0c7da4b020c73a72a77569","seed":"1b9c99349d6388e5f7dcbb8d5b87951a614ae7f803b69b30783035ed016cbcab3c42714246d05039bc6121dba51fbb722c13d2f6ca0cda79a0d816bf7e568cb0","priv":"52dad4ba927ba056a1f0a07515f044c3c9dc712c2019879029ee0b37c7f51b64","pub":"020e6af559d2e1115d8ab76e908e3ae778451dfca6250b996c42d4f3044f0f1a27","addr":"1a3e87568d2f20d4480c153cdd82af21382fdf9b"},{"mnemonic":"dizzy capable mutual cage uncover frozen exhibit awake teach grocery juice reveal","master":"54d15b84b003dd74581cc49909d3bd7ad07e00e745f4113aba6facfdb305aa2e","seed":"c4ae35b24c55af14bf590df97843ce1c9bbb324b845f9d2a08f0ead0d0292f6092e261711aae504feeae862bedd7558a092271455d89a5d1629be8ca43710e84","priv":"d5d476790ed6e46ce12e1573a9fedddada0413d5750d1d18e408c125e43c7923","pub":"02f3b58f6cf3533f3731e5ccc6cf094815d52467e39151d517b9f6a425f8743601","addr":"249ffe5709370cbe54520c162a4a7c8db2b28bba"},{"mnemonic":"menu damage flee oven blame vanish olympic scale pretty valid toy write","master":"91c79127f19318ce4594f4f1045f0f2efc8ecb6a3ee9177ea2cbfcc890a781b8","seed":"fc4b72ba3587fc4b35637186959e3f02460262bbb330c3b18e561faf4cb2ea29ae9f92f011d9d78231746dfae33f57d75ed85f96680a6a3f309a3f81cf59831a","priv":"cc7b3e962031f93079b4d6a9152a85bf927ddd2fdb9f84465220e2cc3ccf9ab7","pub":"03eb09eb7f21c9e411e3660fb49907bc9a23e04bbe75151ec732e066e4e0487118","addr":"20bbafa15fe38bfda08c18ed7a65c52daad01614"},{"mnemonic":"remember hamster power document detail pave inspire tongue rookie monkey board tourist","master":"dd1970c96e30be347b4ec8fe789b4cfc29ee073162d4a2e5dbe5c78c80944af2","seed":"561682af8f69fc045f09d43db4f71a3c7706615ac142078d6aaea287bff00b0bc3213537dd50b783d7f5293b4c2d2a1f6f9bfcd5fdf17f19cb10ecc05f854b1e","priv":"79c341d4178a7a8e1fd364d8a847d97b06ee94d9906a269499fafa63730d04bf","pub":"020540cda9e4957f9480aaedcb38379f2ba60648ae487b741c629a45a5b34870a3","addr":"cef7f07d4ae1da5fe3cdbb37d95bed5bbe53e838"},{"mnemonic":"endorse rescue traffic vapor chef movie symbol scene slide eagle youth tide","master":"8e54dbce9b2fba91209dcbbf6bd272d524762ba3ef2ed05297b01f440e6ed597","seed":"2a0ff0a70d82f948b866090a4e77ddc360a2f52b6abded17f13dd66e79e845bccd2c55ada4d4ed3dfb33d5d10700628bee551ea775c7f3342f6d7a0c3005194f","priv":"c58ed547be839e99eefae49479b3b6345fd7c6ddf390104a544b79f5f677016c","pub":"02d795bd4c26b14dd2aa3c04633f5e0ef787533b3ada72e7c83bffdfd4cbdbbc5e","addr":"ee25d8e4187f6a6214662cc4872b7f7cf7204c45"},{"mnemonic":"humble glove resemble slide rib focus naive false snow north strong attitude","master":"e8b826c5d90453d1af3082a0d5f6a625207bef96bf7e168ddc4091d7f865d51e","seed":"b9bc139c6e97339489cab328b3a362546cc19d0cc060e5c5b969206024aff86f1579d230b4b8b3983b33cba32a58d6dbab5f078704f0efc65d6476062c1d41bf","priv":"4085b496b9a18f4ee5a1d79974be1b1729f51d3c63ce347420d08833d2c793a2","pub":"0251ff80d2e90a37efec614d9fe65b6192179941b772a9468440a2380845996846","addr":"4fc115087277fd7dfcea23e089f5a3a6d7e3bcbd"},{"mnemonic":"fiscal truly seat deal crash train labor trigger kangaroo angry today minimum","master":"1770627ca13a66d0fcfdb474a3eef708abbf9d23d211970395308dd6758bf8e7","seed":"a19680de56046e31637ce714778881f1ec6bc08abe9357804062cb881838c2f8387b52f714377b89b6faa07c4e5b6294324081b7dc521190cd43f75f91029c22","priv":"131dc8ce3551842aebd863eb61e07e6d2de40d548dcd28ab0ed6380e469b5d92","pub":"039ac0eeaf7600231c75fc72dac0b2f58418e1f187aefb3491934120b4fc779d18","addr":"fce14c8cded6d2711301a780a58297c68761dd52"},{"mnemonic":"good dust code sell element tilt host valley climb genre asthma bench","master":"106ae0e9582e9db67ff88c1098d3ef651efeef30d44ff60de30bc0c447217ff6","seed":"1b307d8ffce13f7944bfeee6d6b97de257cd31608ef9059bcbe2cef8bdfded91722fcbf325788d48a5072b9f915670d345211006102e5535f7e2a1dd86bfdfd2","priv":"a78bb63f0cf56b81e228b801cfab1706afb073bc2deb8ce1c8c56f2ab564f1a7","pub":"03fb2144ca5e9dc753c2aa46f94806b35f201d942286571a44bbbb879d2e9e3adf","addr":"5d68a2c8fd5486ba93dc18cfb6a04698250a424e"},{"mnemonic":"buzz prevent cover list flock meat that slab crumble melt prison treat","master":"d620abf2e72b47f061594137194e41c33bd6789799d67b712179c5c9e0dccf4f","seed":"331fe2ce10eb19e2ea13c0ff7abac9b49d43de8d937963e8498da172a46e0c4dcf3e9d276d1e4c7dff5926609936f253e59c814bd4c061429cf1408c45d6e5a4","priv":"8e3b30ec2427f34c463f83a500842d4fb73575e261022720276b3fdeeb20f075","pub":"039ed714c28facded3af8fbd8497b17818cee93d26732aa7258ea61c6f8cf542d6","addr":"74b44edf7f993c72dfa53fbcbcc836c99578769f"},{"mnemonic":"domain tone insane visa much reason tip truck travel head finish grow","master":"3b00a9417e07cbca1d0b80b108cce99089c726e49c267b2e5a2a1d3965c7c99d","seed":"3e2c842cb5d267a2ca3fda4c20d674d048873ca2cfe89e02558a0b585475796979e4bef6e835b17593c53a75f5a4b37dacad0977a6b6fd6589d26502db47a048","priv":"cba9d951fdead64920a36afac46d82241c6084b46681902ad37eed1928135db3","pub":"0321db6f62dd27416d94cc22ebd3abe7ccb66d5e5f57641f79de3d9a1c49f8d0e7","addr":"17d65bc69345ab94e3817738981ea5f9289b81a8"},{"mnemonic":"bone earth country lemon great ridge glue neutral vibrant age doctor income","master":"ddaa76dc4405bdd779045a0b113133f51af43c14ac12281260ea2281a21d4704","seed":"c7edb1f4572aaf510b4b79f18cb68a7464d20babe170b3bcebfa7902f2df2a47d404baf1489922bbe2edb46a2a8ab798a99cb5dfc162b315e4e0a83ddcc5614f","priv":"cae3b56916c64b7303c038294cb1a9c15719e3cb8ac0cb2476e5688b6bbdbf50","pub":"03c9565910b4120ab6a62c275ca0127b717116e773f57eb93d1852ba3d0f2b431c","addr":"81b61de28566c226e0153b1e3afd53697c6591e4"},{"mnemonic":"rotate agree figure style cereal best corn box corn actress toy deposit","master":"ddb3592dc43e595f968e906c72be97c03beb78325f00969311f167e7748bfaec","seed":"cebd7cfb74b2ac03a29e6f4d3dba84d6b47730b478d0ec92f90c9a0ca575d17c581e1f3959b4e0ef5d5f51d43a0fa186ea54420cccc8c2fec8a25f36af549e6f","priv":"b3a7e3147640f66d7be8028a23dceeade18f23bead07774fa5d176014627dbec","pub":"020e2c9e9484acdf5f8a574e9fe912cbf6bf9198579107a48b976da5e4dca2ca0f","addr":"eba352793c5a7ed663a5eb33ef9c44ceb0388677"},{"mnemonic":"kit age click judge decade enable trash noble first grit crop decline","master":"bb39f1d6570a42b31a6b1093d6c1d3d469df3d565ceb2064863e50c540cfd986","seed":"9c8471f0ada1f4e4c4b863811b36036e72818432b8e441ef8234ea29446d2978195da3d63aea71aa5d1a7c4e71e131a90e2db598bc4ca2bad1dfccebeacf963e","priv":"83a532c37858e36cbbb325481e7be10beb2166ddb16b7ea19328e8dd712ac178","pub":"0215f7cac31b44b05f1fac2742ed8a0d6353fbecd06a3abe7946e2dad1feb089c2","addr":"a10254f23fb959df76231ea3061cdde854aee99c"},{"mnemonic":"jeans broom faith border sign decline choose black depend camp nest song","master":"01dc6326bc635da075e100217be8553c30be5c3ee66bd4cb8dc0768777b5826e","seed":"5e7d44489c45338978dcb69035addb83625389d15a5a2284ac888682e7499e8b07aca6ccba965201512ecf7da5a5ef6e22d561583e15f4507eb79ca60e525da4","priv":"07e07f2a2d9eaae6ec9ea7f676124dd14e2f29e43095cc8574b67fe5a8de1fc1","pub":"0295a431168b265c62a8885186b7719298c5791a0d73cb5b6e55cdd7200b5dda38","addr":"9328f2fcffe4db6cc6c8c2a5b0e7f78cac1854d5"},{"mnemonic":"narrow federal feature ignore damp sun brave cram blood crash glory cargo","master":"7e5ad0d0325b2bfc0ac8a2d32b13d758b308fad36c5aa4c497ee3fad4c999fa0","seed":"e680df5400ad6c1f8b097a39a4ce9d9c3c48ea4c21b71795fa499ed641137b50b58f78603bcb2bddae78ff5f96079d48fadd175050ff95784092bc93557d0c13","priv":"eb443a6e96330c1d3c2213e9e345b4cd0e4b2562d6bf13bdf9366f0974d0a98a","pub":"02843de6f3e02767908c2692c091df22867fa783f858a39aa7f6dc786ad5b5d2d0","addr":"5a53f850027b3f303ade321198c74d108e24f699"},{"mnemonic":"fringe fault blind lock wreck one kite ozone system come spring amazing","master":"dc2916fd303a02d0d7ce5d5e0ca55b8c504063c3b54d006f0926a89c52e413c9","seed":"ce52cb29528f78b85c003f5bee65b2d3145ba93963fc4ebc023183618cede1c0add4fbeda85df76e8887004fa526769752808977726bfcc838fe9fcbf4019df0","priv":"5b6302f3548c8a8ca594bf67bbfd44ca98ca84b2df134b0d1edf4b28ccac4340","pub":"03846f7ead64dacb85b25d5279681074dfb9a8c363fc48acc6565c6e142380ae3b","addr":"b32324b0f48ace5119e6d6616b9e613438d92184"},{"mnemonic":"rapid donkey deliver soccer between antique pipe youth science angle erupt leave","master":"3ba5a3b9f7badb433f4235e89359801dbc87b6948e74a61e8555b11dd2f6b491","seed":"eae34a8427228c93f754a3a5ead6241684af42b34047f98b12cb7339f3b7390ca9ebd4373a89ef512e75126de78cb72501d2deb575d356d6ba9d64a8d50951a7","priv":"61a6843aba8ade001ff479a2b768008ff5ef996a5a8576956328815755008c06","pub":"020bb75350f98f845d5ae99ad8720b025d7176c00b6a92a9ea7ac14818a7ae6a73","addr":"2cfb35c09a2a5a458519e036d21555571b88fde1"},{"mnemonic":"juice riot brand example type sign crucial warm bread describe rain slab","master":"9de3651516a0c991dac2dcfa0f95265a6100b6ca605a0d577bc9221151306b18","seed":"5ad029a5964c27c295502b40fba611bafb9b9e626cc8f8df5a98394060d16e53ce41ea46421a615c5a3b5b61c20138466dad1a0b9541d57e8ccf7813ef6d9327","priv":"a54d64cedd5e3b3cfddb182a513a13bfa1cd64627db1fcf5c91f398330010741","pub":"03840dfc1f9d210a632dd38f45fec096c9dad11de2a8523adcc79f4f520faab8a4","addr":"1151a84a341b5b24b687abd2083e7fd150ae937c"},{"mnemonic":"air ill huge miss empty force indoor inside young ball wear blind","master":"76dd3f042a76e88b7d63422086fe0b5242a80775c92ba4dc31b31333c6cf367a","seed":"0df5fefa4beba8bcbdc1e6d4b906c91ca66c14261b543280b31be5e1a37b7a91baf9f34e17143a3e3451d3da18534996a4edcfadeec0971b5b7db225d6056fc5","priv":"90ad41d7cdd253fb10da90c1eb6f9c75120553db484c6e1e2d61aa4ca679d5a3","pub":"0229419c442507c123f161277de5a9beb43fd91556f6cbbf194e26bcf4bcbbd4a3","addr":"68ca6d2e8330de386a3dff8acc4f9be6aed6facd"},{"mnemonic":"electric grape tomato average idea shrug slim certain caught know rather poem","master":"4770c9846aaef6f78e326f3aa72fe236564251b0187e3d8cf2dc95187fe348ce","seed":"d054638cfeac9ab3a2150a49d6854c9fad983e7fc91ccba17d6bc210c976b20336c33fb5f8eaa6e54bd6480487491a1f8150d074b29ece6164c2c99c5427d7c1","priv":"0bbedbc6807a1c2b81f7c1f8b9a8380e27d19a0905eb505630156639d0ea4097","pub":"02be715af6a8583fcbc51f4cfed7e78d93313d7fdd047b198abcdb6d0d2271bca8","addr":"0535e0d51a9f99ed22fbb713b2812e4f2fbc680f"},{"mnemonic":"boat tourist proof point giant horse error trash abandon transfer poet legal","master":"5c366956c526671c4e6f9011872b24d76adcd95de54187d81e3c7c2edc749023","seed":"7455f7f31ee2c7729f7a05b4223bb2b335a0ba5b8ca1ee3f632e04e752294a1f0081e94cbb6763391132562a8f8323b0b05cf00961a2d9a4993ef5ff69d52e2d","priv":"ea1f442448650bf1445c5aa13107210280293e9cbe1b1e432327339db7b68624","pub":"03a80a35d7d599be28524a427dc9b3fb593bd12c7cbef3982bc67523ae6c202455","addr":"c12318aa7559ef40d3b56856a2cfcf89d5f5def8"},{"mnemonic":"number oval section onion aspect surprise romance paddle oval reveal business pudding","master":"2b2fb49728bef8d8301af63af35716b2375071a75b1e2e8d4162afe068e6a7b4","seed":"384e57c3ddb0691d55be1d667dac88873719ba4260fb3d26c263d75d8f5cd12b444255daba423821916bd188df5007ad31c6388b0730de258f543c23fcf74923","priv":"26c77883d1bd7a257d55ff87b562a41408544fb727dd98a7aac093b4a70f75a2","pub":"020ee3bed4cfcfcd28ff8d41c96a1b7851ea3ec4f81fee00ef8ed05def21d37e51","addr":"e8447d8d97950c9a15d3d181a3cb00b0541941b4"},{"mnemonic":"shell lunar fragile unveil dinosaur napkin mountain fresh annual jealous check jump","master":"0bc353301fc1edfb08d3ac53efcfcd96699ffae3174bdc83876df3f9a5fb1a90","seed":"4c8a46510fff2ac0d666176cf77fdde3f2dcfee550260e43bef7f9e6127ad807ed335fccbeb49426aefa8c0f1268e5f602124c2487653160f575cad5ad68a571","priv":"2e783a6c7e1e74645f99752d342aa3b6de689af33c5a80e3abf28f7e1ac0c6e4","pub":"03fead7454b48e2bb68c8fbeb1c807dd4a7d05c6c4c9153d4c516b05967ec56853","addr":"0ff9f27bd866673fb10bf741a221cc8cb4a4f95c"},{"mnemonic":"sniff rule decorate expand siege boat people choose resource topple produce coconut","master":"03c9712b2dc0ed358c17478acf1b3b9c8ea9106c01f0e52056856ed212d4b9d2","seed":"a689100267375fcea1ea18ca798c803fbb6e4b9d82f9f4fc96b3a0873f41b7553589c605b021b4dd4a2db9d3dc5b239053ea5a48ed227fd6db264299fc8d0e96","priv":"8eb04249c00506425b0e414b131ee80dbd8db4f5a873be04a0b1d293203544dc","pub":"031e448ffa6e72016fbcdaa4c2790c8e57145ff051de1d99b69cac4df1f8ccfd0e","addr":"edff4f402b7525e5707a9ebb5b13b2bd03d12ee8"},{"mnemonic":"crumble coach clock opinion net churn cinnamon seminar slot upgrade always nose","master":"8af370254a2887d6d8d00364fc824b6565ef750d3b19fca98078281b040f9244","seed":"1c6241635fcbabb70bdd30d827f602169ddd82e36333aa50a7f7f2de4bbc9a581d6f7718cc94c0d63779f38363a8c45042b76b89610f9b3c2e785de234ba5818","priv":"23dc380f4557ecb1cb779d128309012c409c544c906865b06244e49be877db3d","pub":"03261b2261da80af3a33ca8252aeb21edc608b337761a6aa8160721dc202e65b29","addr":"fe0cb66348437ea5dbf8ca79de9db63f0ff51528"},{"mnemonic":"mind fat sort buddy gap glimpse hunt ready library invite mammal repair","master":"01979edaa3aacf38e619e05cd78ac50eb2729d6ca2d8ca5b476677d30a4414f1","seed":"7fe831aaaacfd5895fd3746b45c0cff02d52923fc3ef55842fdabd02de07bb6bbd07dab7f1db1318f97fdb6141e5ab0142d7d06ae92c020d2be760e08f99661c","priv":"10d3729902b4a8c26b88c84ddfd6201048250294f18a2ff0ab4248a5b4085992","pub":"026cc54074748e623153f3bd4b735d0c7df21cd21fc59cac3ba43292cf0ec3230e","addr":"0b7932471403f4769cfaafe834488587349525e0"},{"mnemonic":"area switch resource vibrant prepare write genius danger extra alcohol section company","master":"dc841ed2cf4ceadffcc8f8f6fbc50dc3385e2b438ba5f985f33dc5c68190c69b","seed":"cc2ee2baa8b309ef7e76fbc14a343a2435d6ce0f7da46d1f9a84782c77e84fd7cc40c503db71f75380cd7e2236c9dd0579b528d84b7deb89b0d4a4926c66a360","priv":"b2fb735d798aec932964121a2a00cfee6184f03bc0d7885a84507ffb1a8f97c7","pub":"024cd279a8812efb672200639f718ef89d9996a6bcd6ae9d50c1548da744bdee7a","addr":"4c56a50381b8edb7e02124e205e170979879ac05"},{"mnemonic":"twenty shift viable behind victory napkin cry gasp own dance primary glow","master":"4519e4b46f8279cefb8b261568638b514f8591a60617fd9ef4c0f03c193b345b","seed":"393b214e7d24adf4912b8b6dab2c779c2896816b1f001d80a702a7dd2c44b5a1efbc85e2554e2586eac150a1a2bf1fe12e08735dbab0ca65a746259bf953846a","priv":"a187f775899244b9a57da9a173614ef2992ce1bd2ad6333eea6e796f04ca446e","pub":"02735247ce372948d922ef85da71f424580a46fcb453cc889411722f8984f301e1","addr":"c055c01a09dfa7b360a99d784d05e715dfb1eb37"},{"mnemonic":"jump end chest decline act capital text puppy empty input possible goose","master":"5e8250d4fb78cdfa191efa589fccb98d2a635d091df8352a0aab57fa13be007d","seed":"fe6e62ac192f7f101fca767a1a24421acda2c23d1c232ccc19221eaae7697d9eb0cdf7350272d93ca37d7e10b3deb739ff0b05ee723a4acc754bb6994d2a5b78","priv":"f400703afc057875c9dd11e046fa53c0edee27c78e2905425a74139f3329c1be","pub":"02c98ed539a5905393750276488e60d851163ea5dbccd25e6fbeccf119b22f88e3","addr":"81473d441525a6374665b98ff30f75b43157b29f"},{"mnemonic":"spend course nephew spot nothing girl wink flight wine hotel harsh better","master":"6d62643bea35847c1ec3b6a7273c42a24832d28092402c2dab4df1004df249cb","seed":"5cca26006b3c22da1622ffd07f0478988c9c97c5f128f78b89fe6b89314ad8c37627f02eb630f376574a38c243a3069c5a34dc59a709d5264f42cb1f80740adb","priv":"dce7ae54553f89302b0aa63a500cee7472a4a33967aa8a1ee18e16aa0e78d2af","pub":"036052be2df30dd8ad7bbc35055a4e60bf520fe962d9c7158d1c5e2b45c4c4f841","addr":"1ac0320f22683aa7d67416e24bf59098933a7e4d"},{"mnemonic":"coast grass horn front broccoli artefact also history screen bleak thunder example","master":"c49a459ec914359418504d3d471fde7fb1a82257347a4bd95997df53da47b2ee","seed":"2f528e97791aad4a82a7af1a68007871a2b4917fa238d69137fb93f64ef1f7af2dc036079ec220b8be11365d62ca11be66e83ba0d829671a55a319c441f6c8c9","priv":"06fea4c71f85b7b161ec6edf5ea0b90cb95a410fda9fee0a603fa350f289ef43","pub":"022756af9a6df41e36de4300027a8a6a6a8f6bc7c2b31252153f3d915299a8129e","addr":"6203a9699c5d1b6bb64d1dae86cc741896792266"},{"mnemonic":"shield liberty wash park absurd inherit suit resist garlic cycle ecology mass","master":"a35a147cfb59e738ea4eaf9e6bcf1102c7d4c15e3e59458aaac528a0635d5316","seed":"fdf1adaddf7f8bec833c3054d079be7a240f98fbf08d051892a02c4b1e1392ffabf84422606d7ef333f99773bb8d51f01175c568a94f5317cf8b225991d7a528","priv":"581e1227a6f32dd51a3bf36e7c4f1504b00a528312f3025f3f7fbecb37b88b7c","pub":"03c0e2eb1d83e266c1c25cabbc6a9d46b0d955f70ee83b78ef0348e44fd6e8162e","addr":"18573866de437d48c044002b20fc5b886cd1dff0"},{"mnemonic":"spider cake process model elder electric mosquito rather choice insect crunch pizza","master":"1c95e3db98b4194020be93e3d4791b9aaa2c7eb1c83b02d7f3bdb07183f4c3fa","seed":"d25f0954443b2c18507a0c71923aaa31857d03187b08a649156ab634c20f29a444ae505cc80515e30feb69c05cd4e133f38b18659ae6189ea27b442705b9089b","priv":"5b9cff23b6a19a67864ec0973e3004da548b5b97400f9fdf2dde3db2469b776c","pub":"03829d931e59a87c6ffb4f8d512374ae7981ccf2c08a30acd787b77c628b727d8f","addr":"aa95e7e0c4fc203ea639873f05503a2d5e98b70e"},{"mnemonic":"include yellow off random knife video person monitor height virtual oven derive","master":"92cc90784cb9a58deb578aafd5b6bddf5195bac720c1b27ad575bddb1fe19487","seed":"7e090c19e128ee76d95f7334361fe7eef356bec53a06902c6c5bde0cfbbc7a7adc540eab3fbaf7d1e4c6ef38f4c29054767c115e6160e6825868a91297e2d5d9","priv":"076608b84151c535a295ccafdd1301e8eb82f779fb4aacad5bc2a1f0a699364e","pub":"03581ea3f2b7ec38ad8ad9717b22cf43192a637eb4d4db0b051f2085ccb43d9e5e","addr":"a68d0470048127c2234f1ce4a70f9f04c72c4dc6"},{"mnemonic":"chuckle hybrid seed portion dress move settle pool erupt segment annual demand","master":"fbad7924603e902337c9f58086a9334562d6f3866c798dece4c1761af9914d3c","seed":"ed3ee02d4b90299b11fbdf6fc7698613aca89749352bb2ecdbd5cf0e0436e0ef702a615ad041bd97bddd4e892582ed9037028002e2bd5c58ae7730c47a44e20f","priv":"77c0167a4fbcf6dc7105af046e2978eddf6366e945d8456c28e13c8f3ae4de57","pub":"039a672d56a39e6aa1bf2d51aa0c3525692117ef33a92ff903dc9611f86550b96b","addr":"d4fcea5b95282e1286e412122701e9bf49bab344"},{"mnemonic":"portion upper maid dash where control nuclear post run manual mushroom bleak","master":"66c9b9ac9c75057c18fa94eeb0f75cc73b90c08eaa3aecb1a83577062be3f6fb","seed":"06d6d3e53986a879befffbf87dcfd6b7570321a071e22092e1c88de34bd44d7ec72c76323fa0a7ca040a7ed90ccd686d13ea027ebb06f8c66154a838de229f2e","priv":"f5141661ead9339621deb48ffa15c4569cb2da05467de78a2eb631a327f5a68c","pub":"029a18777158d04ba09a941ac8ae89366a50dc8253319b71647fc1c6e93dab01c2","addr":"f1fa2abc32e5e9aaa843cb07c37dcd549b76485e"},{"mnemonic":"fatal lend tortoise urge topic sweet spend antenna stock nothing doll face","master":"2d03a7cd457dc67949321ed16a2893792e5210cd4bc0f5ac86af83897094507f","seed":"f48146154da92dab72fc0fbe1f6c7524178301502d72ae7c404b67f8b7e102306bc03f339424b011eb22d15977a0f12ad0b25e7adef5661d65b06dd0b5184dcf","priv":"d5908635bebc92518047b79599b90b1048fc2bf2d3eb36a2bfa5a894927675e2","pub":"02309e322a1c103c44ed7195044842250cd757b061430c55bf1fc8f7f10d660bb6","addr":"946728094cdfcc601a6a496ef5dcafd3de9a6488"},{"mnemonic":"blame margin glass dinner worth right require unknown wine settle make aware","master":"7297101c31d8168aee1fcb025bf1ebcd747ca6d5ba19d2bd28514fe3b0e0be18","seed":"e97413449360a70d3d202dc63ca0670a98aafecbec1de44d8c11f1ae90099bca926813685a429d4cefb6f0e29e207732f29e962aef7b6ae82ea3cf2d7617acd0","priv":"b144f77a520ba1ecd94b1fed5f362cc1fdd7ba9bdc355e9d520c2f39c0a20f7a","pub":"021c6773d45e549503e3bd6983655510a46a873e793c6cdc989356f657f3e5bf20","addr":"f259947fedfbb0ac039a44936e901f3622b9323b"},{"mnemonic":"gate make bird oak brave hole elevator tuna gauge type school disease","master":"1c1407749a31dca67aff767e4b78eca5351ab6792dca8aaa3b31a766147207bc","seed":"e079a04be32619bb57910662e11a006f27b02743e4440136ba02d7915502d0fe1590667a555fa76313452747a1384596950affa367c4a3e6f5b179e750018a7a","priv":"4319abffdaef48761ea2bcac50eaf80551baa1404b27b48fa379172f2fe8e1f4","pub":"0229358636cc2b80f63c7256eeb51b9e0bd3e1df0cb5e69ce87f15d71e16fa4a8a","addr":"d0134881f0c1f11cf9938920472f3d37e9365565"},{"mnemonic":"crumble danger tell frozen define mixture sadness strategy village mass junior kiwi","master":"0dc426f3c99fc31a73cd91f5c261fad7b70e2a7738e6312325686c95dd9df2b2","seed":"773955324075bed8d11f971096456a8557f8cf76750e48fa4423bf5e604943b5ad17788fda1afb47f03cbe208c79c8b6c38105538d6028b1ff4359e7f5a122e7","priv":"86f1207640ee12c8175e9b34cdc6fbdf2c200be9e03697fa82f8cf43dd8a6cc6","pub":"022ff8d5a67f1235242e9e143736bb950d391bfebc29173cdee50fd6826ca895f5","addr":"49fb80faca4a0537aab1d0b7ce5674d4490ff8b7"},{"mnemonic":"reflect mass fall habit mountain winner logic box cook between drift donor","master":"350db5a525a544ff7d82978817ce35f33ebb6c148b9ff6a9bdbd357a16373e97","seed":"4511bc8cd2b64472dbd108250e8d0efd825e763790bdbd44f4ab700c5038ab129e417ee574716e1b895cd660c72f9bc4f1a6a2846e7b09c635db2a51c22356c1","priv":"f2e5782037ff1ae1678ca2baebce674b973aec58caf7aa1aff830b372a6d6436","pub":"035d54ecb4a48285dc13346fe46cadd907e443c03e91339363b81c3d1988b09a38","addr":"6e8114f26eb00d95ea09ddc7d4d5cc104bd3ec41"},{"mnemonic":"enrich corn rose chest can figure canoe used pattern margin usage increase","master":"d38a5d82ce728c441f707cbced8d7b08d896ef9f37d0b563476d5500ca0008ef","seed":"ea926f98f2efb3af7bcc514969bdae01680e237424554b732cb37257e0b9f0ca1303af09dad82b0c967ce189ac8173901937ff42d0163310e5fcadfac1710c56","priv":"880b645884e27fd9205d82ad44c18fbfef02f205455ef818fd3beec79ab08e5c","pub":"0229eb380ec659c8964ca2d19196eb59804855b0d4226fbfc48f2373466380e1ad","addr":"ba2ea36646e0806378faea7ae0d1a691d91b54e4"},{"mnemonic":"coffee labor involve dragon upgrade route south guitar uncover enable soup sustain","master":"0dd39ec2f51c819042ad3fed701d1f982f599383049b38ca36da842bf5d3663e","seed":"f81aca2d700fedcc07990f1b9ecbaf194c0df5dbfd240437c06728bebf0022aac77b8b44f7863b13613b4bc5752f0f19e2a21617e5e0578e53f9198c2ae853cc","priv":"12c7b8c875fa9d0117b53e2e539584c9c524fe1519414a13062edb33eb712408","pub":"029b8bea854aa1d99e6564e5f4c9627a95d1fbda000a59ad3049baba92a474a5ee","addr":"eea20101f17d14b6bef65b393a49b9c558f5b87f"},{"mnemonic":"dash clutch smoke chapter lobster quote fat negative desert labor rent basket","master":"a6dae26374b6e165be90ae4f1759fff4dc4da104493a21c4e062d42a50ce1b48","seed":"2c4d251fa5b3a634ddafccb16393730cbdf1a1f20b44ddfa0a25ba2e5b6a48e8338e5e5a8a0b65bafe30ae629126789264c98a4b02ba96da5eb3b15fe5a296a0","priv":"5f7246020bfb4ab5146674df950ccadb3b014cb8956e4bcc3b575f710b4cc4f5","pub":"03f2712cae90744dfdec3a37990221e86063620b7298778ef4cbac6f438764acaa","addr":"7d8dbcba23c0e04ae21d250c585f511ebb825ff1"},{"mnemonic":"toddler juice raise depth club rebel weird portion void minimum game typical","master":"d56bc0aa70e0e583c13ea0edd4df5dd6f3b02a9a0434b0614f5fd9c2ec029b58","seed":"373286db33542c525710b01bb881158a7a1c723512596414370f1547edc08a11738d855569109b2249f927839c53361c8e0c8c468a62421c998b97fee5dab6e6","priv":"3db2ff05ae17ae227e78096b9803281f9332857f555dec941153805377f38520","pub":"031a9ef5c0a80f32c99f8c3af49b8fc51b3902ed13832ffcbd0f9527e057c0d56f","addr":"e5b70525b5b3c325b9a2a044ef05452ea0dd6821"},{"mnemonic":"legal lizard easily dream push business village network bread solve predict surprise","master":"4495fed7ff0239ac3a3ce75f1ec1e81fd3c8f7ac2c3a2a9d94f0f82a31042796","seed":"a709e3741759029624f534c66e8d8e56bb03fd8df960fa4776daee1c61810b96c495bbc3dcff634ebf140dcec9f7da9151e09856ee16ba5106cd7c1088032ebb","priv":"5e3e0925e33311aacc94b1d29f359f449d443cbe618e0a689d0c40cab692af21","pub":"03e2b6a2f99cf742f7c1fd356a6948df231a75fafb3cc471f9ca4ad00ddfad8c2f","addr":"c0980871c3f7b15830fa514167c90999279d496f"},{"mnemonic":"draw boat debris humble cactus method duck ask author soul busy assist","master":"8bbae4af997d4735d14c988cba637bc041b4b0907c5c53ecccc1456b43ea79b3","seed":"f05a91da4ef94c81e0bdd30ed6d9cd09cbff7013c693d6e8261bf2eb3cec9568fd3934551344ca8c768bdfdc44fd1b30a082bffa2c1611654320948883785e05","priv":"659c3413372935b99cc972629253f37305d258459c1a92b7fa81883ceb6dbb54","pub":"025a5af583aa8bf4459c72c9665cac772cad9fd49518b9080f635a4de283542588","addr":"36d01ca7b9f3c37ccd529033c15b1c089b877d8d"},{"mnemonic":"between equal crush suggest spoon material poverty diagram forget click company call","master":"3f2d83ceff7b98467d9cb2523820f55d22abd1700651f4b71ad6856c029ada7f","seed":"34e2764bed365dc73de440475c23b18cd69750977a4197a2efe374ef552a9c56eadd6ccad970c422730cd51e5ab4e051e4c86ef4db2284256186fdfa0ba92434","priv":"62febeb0325ae75eb0c71c4a3ae889a4a274f4ccc361cf0829743d5add3b084f","pub":"026e528216c24173250fb71c73019ac45e6171dd4f9d8fd97b0933fa964b966ac8","addr":"22aeb188b3a21507a27b35d860b583d9d844cb91"},{"mnemonic":"cram palace round input disorder armed wool cram over abuse order grow","master":"5c040bed4bfa8520ccdeaae710403b3ee7b77e069536bd87babd93c09177f9c8","seed":"df3911a2a01087b8826327ae368abf4dfac62258a1a7a91cd4ac64067d926b3ab89deda5a0e5539d8c0071d14815e2aebbb913e2e506c6574ad973f950049d91","priv":"87a97c3f977b1ce0b9dea5f2ca8671ab6830f9dd4b3da8195e603b7549f529cf","pub":"029722cdb8ceb0be8456ce4dcb24a4fafb1028ebb4d35b4af757bf22e8539de367","addr":"eff0f2517523745b0b404f688dc048fee89815de"},{"mnemonic":"donate view volume faculty anxiety degree brother cheap film eternal hurry debris","master":"762647d305701dbcce0a5bb079077eb514ad72981fc8489c6cdbd71991d24179","seed":"566c1fbaf6ce9a0c7352e903069b332aafb438ff086eaeccd1207b6fb8a9f0a0a4279307fa987a905ece60a04a52a59b3db45ec15892ba76b2308cf9db8e36ac","priv":"c0092fbde92e9ad29a52c825b8187f40fc5e4ca7a586f4b5b4a8805f0554a0b7","pub":"0340718652a6d3d2b791e79fa91e96f60eef740d10e3db8c8b206457f31b1a0aee","addr":"315ac67c85646a6ff00192c6752301f11e19e409"},{"mnemonic":"pattern much pilot choose prosper spot shaft camera unknown target wing movie","master":"1d04a744f4e0ca2b180f5f20ed34bfc800d0c874d232b5eee1018142fa612b15","seed":"2e1bed0a31e13e8f13a85a35ec1531a93ef433c96338f3e6533dd13d5bdae15bacdbeb954f9613fd4dfb6a941357fbcb5908520096502ab4f6edbf0c93e6f559","priv":"ec42f7fcebafba29c6d692ba732e8060d7050d7c57ef67c0c9d8ea152494a804","pub":"0295575d1d162b7599175bbb5b213ec3e79d6b632f5e50b6ba84e6a2ca15d70939","addr":"ddaffeebad79dfb4df2e2e35d9b6928900d38179"},{"mnemonic":"cruel tooth rescue step entry shock uncle crash possible inform inmate such","master":"f02e38437185794196a7822f0e4badce8644354fcb5d03e337ecee7ca0241df6","seed":"6dc6d27c01e91879638ef2281c904f2b3b0df18b0231c16f1518b63b39ce53c59335cb858b692f50decbe6fce2617434c927cc09d428a98820563438cda13c50","priv":"339120a922594b577d1f64af46c9dddbe0239a1ebe0187569c4302c035df4996","pub":"023e91521223a9a95c1df315c36ae543e606f426e1dc0b4938b374af5fa4967fff","addr":"c5711e1ffa2cca8f18b9be910c4c31330b8d60d6"},{"mnemonic":"evil height seek edge session require obscure begin skin outer foster able","master":"71495c08143478276d1107b9a496ca0befb1663524e46ae824b65e979b14b22a","seed":"2d209c72dd757b948bae9ac1d69014bda27b76dc890be357f542d994ee79329ea51114a1f721d17751152a1bbdd5c5e836771902ec6113c716fa016e30309a31","priv":"862d6335c9d39a65655c3fb644d71f9e4a902f085741ea4df75cd36afb94b0f5","pub":"03004f2c4133b0ffd92bdb3fef5eedd75bf04b6e7e18c0dea3204989476ad3762c","addr":"5d422b55f2091fa9e350655b2e550d209489318c"},{"mnemonic":"gravity sustain speed quit clock cage cupboard radar injury unlock sheriff alone","master":"44e4470967f781784b98f1e33d8fdd16568d1d43b1de044541a8e0821715060e","seed":"6c58333728b07bcf95ec884cb2ccdae5ec12dd67c3442044f7680a87c47da325429bb280727efbd848ee7f8c5fcdd433da0e9de39b21acb66938427ef6ac47df","priv":"37a9522e106495f859db94f5b6efd4e98d49e352b4e82cb3fd6ccf03bbec4b90","pub":"024b03123748ed0b4fdd8f6a351d1ab6a7167396fdd583aafc15233f5e79e3134e","addr":"62994a9de9dc8b9c9269287b63d847e90f519d59"},{"mnemonic":"fetch uncover sibling unfair brass explain sorry wheat talk web news exotic","master":"1ef8d0946b982a3233328040bb94e8e8cd0d5fc24b345f55535a8e7a92c22b67","seed":"f5b3db4d9c5686aff4eef0b0eee3cf88c4ffecde0e9b1c6772d9071fa433d5ccc9173f2f9e95114b27a37a1d91869227f8cb46b3ba26323e237bdc7a2365761e","priv":"cbb0527d80293daa1ccbf26c5e8f117123a63c0adf772bb80700e2334690ae61","pub":"0271bce67767a922d141970501f7341e7ef0f5d877df908c0c06e66000b94810da","addr":"368f8cd8319772499a4f2f109d440c2e1ea55038"},{"mnemonic":"follow actor noise creek afraid normal exchange universe swap draft cake forward","master":"7a443b3ca6069d981559e8cb1db37aded7d3e25d06f2f5ad35867c2086ae4cbd","seed":"3189fb459fb30288ea67a8cb2a46eecd8854db40b7f5b828254997301dae372d05b3eef58b0c670b510abe11ef7fa506b74a4280be94ebc55dc891776599fa3f","priv":"17ea39b63689ae32dbddaa2bae52e8fbd79d725a6a2ec0b56c432a90a1036bbf","pub":"02c3460e957acd5e228400055e9e1b22fc5fba87b16212382ec78b6131d05060b3","addr":"4e981e57f9e23760cadf381d28eb56d225f8b785"},{"mnemonic":"pulp fire pulp salmon finish question aim unusual casino super label soul","master":"3041f6724fc8fd54913ceac5487cf0b2a1c95e1d2cc65272f99d1d0918d73c20","seed":"424b5c69d42e95405b4d78c60f8c4541fdfe0600214623631154e144cd2ffcb3d6996fdf8838a07947a6b08d9792e6e883820399429d2427eaf4ca3cf2311e89","priv":"19026cc4be5629f8580b7cc5f01e36cea0cdb35a933d9871324b53eb9e4d62cb","pub":"0355a17ad503b793fd459e58e7cd85e13724e155ad487d9bbca7e49f939a89d514","addr":"e26908acb2f197f61f0036aef79f9c2b8e67cbd7"},{"mnemonic":"draft clap afraid census image debate pizza display sweet square today floor","master":"146c029ef74c9c9d00538cb03e70ffded59641ff8cd695e44abcbd71dca0aea0","seed":"a000df2590dc0b74a6b1bdc868079ff3172fcb9f758f7f61e9963aa49bb9ef1715985f3b88b0d1b22fbe5d30b2fa0dc489c19ab2fa42c5e62734585b6b35f212","priv":"4e39817ee6a106cd3b58666b9bd419c246caacd755c302c5440f7ff8b59a3e20","pub":"03532d53d02bdc71b0ffab4f5dd3222bdd8b49117ea8c10eed11882a21d604c72f","addr":"4ca53567a3b12f8bdc8cd66b1338c3760cd9def6"},{"mnemonic":"virtual search upset mushroom bundle vicious soul fine decade reflect basic nurse","master":"1e7e15314e1cac1584fc5d6fc5609db315a3a63c1baa96afa57475c7e05b77c7","seed":"183399406bee3c1b8c11ec94a8528e0c26a7c22926f286e320461809f84976cf31900b436022acf4635066c55bb793659254c75d4f18d692a07e20026d409986","priv":"8a07be43ff390d981394dfb29638f2464bded05d5daeb3bb54a93ee949f2da36","pub":"0336378e1b67b1588c6d5e279fc3fe58115cc24dee0cabb5f728acecc8ac6be8cc","addr":"e12910be135809fb5a6314212975564422d98445"},{"mnemonic":"venture wrong wheat oyster buzz cluster abandon rescue alter frequent way scheme","master":"15d4683cb037b61ab1fc64adbff7bea44f515683352cdc3b7e8c6d97700d66c1","seed":"0ea9eba247cce6f936ca4958c64cd6f8f19c3f68914018ad61ef9042a4fcea4058f32017ecd0f672cc8ace9af4d06b59bf2064983fb4615edf912f73343a734c","priv":"47006c978ed707415ac9da1eba861546e6a6150170db9699b585648dda4c863c","pub":"02dc09d31bdae4560008e82db56cd81fe95b6a6dbb87020117a98ea071753659d6","addr":"4a5c5ff9661ef26136b09a8e6af9d6aae0188e2b"},{"mnemonic":"consider sorry keep source session simple solar acoustic crater model hurdle champion","master":"2c3331a974819d6f38071aa2c790c42ad7e97111f5092b00f972859867cfbc5a","seed":"e4f33149ee0eda7a52f5f64d1c8ea945058b2f3b2cd0a0d8a85fdfaa2aa0b559bec8bdcbdb5703dcf2ac54ba7066f4d6c95b03140680b1f1d30a6305e4cd0b7f","priv":"3030acea65637e530cc39df608f467b4df6a47aba4e241c7579a608d8d53f12f","pub":"0340b77aae056f3e3e7e7bcd670c05a3c8975efed4e7efa0c0932a48031a242778","addr":"5dce4e49e053ec6443fdc36f11f1f9f233644cb4"},{"mnemonic":"salmon allow rebel eyebrow siren remind mango round task ritual exist course","master":"7393e3b637917023a724ff52b1f651f39da8a0d860bf20cb810eb635ca348eff","seed":"657dd9b458793c826944ce50c00f6cb97877543ed7dd6b113cafaa7971704a8ca5896fdb5118aa09c52cfd6b28bced9446a86258cf432339549e31b3abe0e279","priv":"46c0e6f6d527a46ca2b44d0d6892dc6c816bc0f1240b10ab2ec9f33050e35666","pub":"02cc668b114070164065c79990db45a64e4bcc5052ab0ca65a68f0dd3c107e6937","addr":"0da2a43e892435f79c2af7d62cc823adfce0355d"},{"mnemonic":"camera casino cigar harvest prepare satoshi close ill suffer chest parent urban","master":"1f6eeefc59b6600a739364a6606ac2c3a151b4234f1edb6efb97da193865402a","seed":"44388f05937f5cb3b47893b75aaac78ae919e4aba29f0a6934ef15d6c7d1df6e5afe36743320856181b5f0a8bc02e731ca83fec8dd501c9c845a1f0325d74a20","priv":"e6492972ca82c2cd62006bafe541c0ad5c6bbb01257600e8168702de496f3e37","pub":"0219ea8444509e7894ca706edc46a522244acdd643bb09d3856db3d9fb1c9821f2","addr":"593e42b50fa2f4491c831039dc1b4489333531c8"},{"mnemonic":"staff myth increase tornado student scare awesome fever promote vault write head","master":"5ce65c1772d4ee171fc0e843ee7b6124868d25c2cee48eddc73e92b805ea2239","seed":"88c5df5805a91765a045019ad39767a4aae836e8c0f53542c661934c3791f94b9d35cb9b1fdc865deaa6f749e583176ef9f114774fb0b59c0637d1e66dd6694c","priv":"066f7c65cb33bac2ef5229764c316ed587710752d456881dab54bae2b1ae55f5","pub":"0263f5acf96f7e6c02dcf040fa765db8fef8ff317400344cc92fa3f5d58f19755a","addr":"fc00f9a09aa3316fb67dba9e08c66d8569f055e9"},{"mnemonic":"during smooth snow please surprise winter measure weapon bench possible write night","master":"0af6eee6b3acb361f5743fec61f7377ca5db5e90a303484e7f877ade8da1e0ab","seed":"104ab4eb787b2da19876c47e1372bef860de1535ed30deec9887075d8f2c56213647f0e8d6b472b23f5ab6dcdc1f97cc32ed2842a0745589c196883967f2fbc4","priv":"0eab899fad8229fc681fb7c86d8102d4074c68e6503c644790125bee07669d76","pub":"02d13bfe147b234f2a81e3e2ae0e630f6be4bd56fe44dbf59b2336c689024b771a","addr":"86a7e52857c14411ec4bbb6c850822b7bfc8b7bb"},{"mnemonic":"equip clarify march rhythm supply attract dress sell clean galaxy index river","master":"aaa85635e77e16d5393f4ff5c73b5556b36ddea446f41c5cc3fd4cf6da2f324b","seed":"519f319e5c87b49923ef60a172b731c50da1da2eca2dc130ec732beaed5dcf161c2c4c98ec20b539259862456a7ab2c5f63d7789da98dbcf01ed23a3be7c00a7","priv":"b42830645c0a8c5fb59994bb7588e8fa80b6a3b95ec223d459a6652a9f3bd641","pub":"030b9ba15ca8ae95d10eeabb8b203b6253c0d08489c02dbe255221c42b16ecd043","addr":"5ac5bec20480d7b9007c9bd184d064ab6b1c9c75"},{"mnemonic":"session hint oppose damage illness metal combine bomb cargo unaware gun artwork","master":"d6322887157ca3852f75204cb3eb60ff3eec39450913387b03ac973f5ff09ab5","seed":"09900b51d5c10504fe63272bebdec8c2fde49190039916839b106af4b7340595cd5ce7a6be9866df28d0a40618b23d09a6f04bb963b05ff1b7e272bd0f0beced","priv":"3f012cc4faabdba2abbb64b9313d0a574b8b31c1d22f403f1d344d87ba3246c6","pub":"03b4a66483e09364f2fe2d905fe5d0d897ca32752df20ddbed0206e383bbd68810","addr":"0bc20be767a401a01d697c5afbf331fd7b3f4acb"},{"mnemonic":"gate credit cage whale razor come opera net speed dinosaur fold witness","master":"8e48eb7d42fbc6c30601ab45da446ae6c0ac2e9b709ac428fe1f98b5c8adcd28","seed":"be8b77e358eefcb5610dae1b36380d25983f1aa458c208e75a9117b507fed28975787d4531cf87edf366c29798a4a6d8b44d6dbd090da8eefbf6d97477b64ae7","priv":"24ef322d8877b9f5f352f8063498527685de6b7d056ca7776dfb1ee34c0696fa","pub":"03389070a550617f89cf46c1df8269a154bd4811ea7d519445ac1e7e3e3f9ecbf9","addr":"45d1a0a5f79d849577106135f7065782e972ade8"},{"mnemonic":"belt girl tribe accident machine library verb link host wire hurt elbow","master":"d604893e69b68ec73d7abee4d15303863ae766b867400eb6cc0c771e8eaa4a16","seed":"ed3677dc17838f9720d5c574a6c70e80c185a5df1faebf07c63bd64a3cbb43818f7337469d48142df4e6d0254fa73e8a8105c6306568bd8e3a1fffd2c9d85885","priv":"cc6d78f6b72176d96a3425cab46866499fc57a8de3a49d5b30030378982911b2","pub":"02926ca73be56e04b363daa330ad51514595250d48d8983ddf29f74749c1a81797","addr":"00cc426c8061740249ff1219b322f104f548449c"},{"mnemonic":"kitten monster sugar game word lion census purpose defy rich either distance","master":"d697b6319c74c77415f784aaa6b341a84ec08eaac0a3bbe094d5cef9be94f673","seed":"f6bcaac87b81723ee589e635ff4e5a5606cd28113eab6846f1e7d5bcad758c1af1c8c77c111ba1cb502f33418f1436220a0a080ee81c5dfd012be5dfb0bec360","priv":"cdc283846e3c5be0b327e48a83fc72d85521bf51321697f281333b6eb7fa83cf","pub":"03711ad3d292efc08729a820344bdd1efb9cd87b083d0ffd65b49f998d1808e520","addr":"71f678f7808db66273dcaf51fe4875fb4c47c80f"},{"mnemonic":"fury tackle glory welcome gauge rely spice profit east science nominee expose","master":"b04bb080a9192b41dd7ee5f9bbfca1396970ba10c54faa1b7a511950b2ac85f0","seed":"5c6ecf5aec8669d62d5db9e39a5c94167bdb21e9380f8efbfc967420a71e0be1d72553a2b84bac9b8fedcbfaca522b82b7b80b531615b9658379c236cc4bc5bc","priv":"05fd2f8cd2ea1cd0ddfe2acd25e498ebd81b902d51935ad3a094a2f2c9c62ca0","pub":"02c4730d47f1976f2a6412681ae6cceb97b899c4fc514b67b9070bf236e906bdde","addr":"bf3e06c5713080e1eb287d2eadf49de120aae6a6"},{"mnemonic":"young chaos must mom ginger hard symptom ethics father rain join time","master":"d9e68439465f5375de6e132498239c9d0f67f7caf16cede036da3fd1c3905522","seed":"4101de8d7cb1dc3176ac0781e94594a37b894ebccdb9d934bac104d7b22bf68d863fae68df1734ab10302025e53357b33ceec095e59505a1461aa751ca77e5b6","priv":"e8512f2fdfbf6bc1e125323de28f9f35931ab760bfbb2a736f750e3bf116bba1","pub":"032f51ba96193a6e24dffa85d748ed2b86e3677112b22da1d6dd5e2d98f987f0c5","addr":"7adb4deb8d4ee9aeca2dcc4dfcd5d1dffd3a2cf6"},{"mnemonic":"dash ridge ten when erode certain game rural canal race surface envelope","master":"fa20b9bbbaf883069a6a282b30870bbb02c8aeed3c611dd3c931bc217326c210","seed":"276e9b97f203454480976e1d86d4abca6072d05e4bd5b1eb972fba03cd6698afb7212e5fd77ff84bb8e68d45c641063550bc8ca208c00604f609a5770fd69b15","priv":"1d2ddfd078682c4d3950ec841b8555fb37981313d0ef69a7bff16c110171f71e","pub":"03f0d1613f82a900455d6834f6a02e037e3d6d7fbe08b1f3a278b2a5958bd13490","addr":"b190466866cfab3ed499547c88af1372f84ab61a"},{"mnemonic":"spend echo addict brave reason tell valve emotion gaze seminar entire game","master":"3d139abc58b8022d8fb2f0c622531874064a80fb4ad795b024226420f30f8ff5","seed":"d9d04d4207827877636a1a077468d2396dcba6ecd3398cdda7d4c15c1365518a5131fa12caef14a2b23702957b282903dfd96df19419e4ecdccf7c38487a0c9d","priv":"cd5f726ece1eb6653950ae42c9fecb053274b692ce6a58a5f630716fc9cc172b","pub":"03e79f46caaa31bca56700d91cb366428839fb09d027d13001ae723461e8575bb9","addr":"35c04d25b3205e9cdb5283b94f328792466ecbd8"},{"mnemonic":"moon argue laugh point unhappy long bridge water naive suffer curve duty","master":"72c22a1d7ffb152045afab5ab7831efd0910c0a4796b20fe9b741e2a06a0562b","seed":"c77d143d6a040b08fdd3a085c9fa097508137cd801e480752dfc55f776179dddf01199050893ca833af63f6595fd60b4d14944e31cdea626ee30777b681ebb66","priv":"af0e3a2476271d7a31943b44dbe9affb5c04690c2f9e1a559674f028a8cdb9ee","pub":"038beb9938f2f7bd600f8b0b48d85ddb9a09054534ccab4e5a3cfc36523dfbdf74","addr":"a7799a4603c1cad8209f6de4cff709ffb5ad240d"},{"mnemonic":"ceiling mother twice mask pelican glue such giggle session absent sauce copy","master":"1ab59e2748679caf59d4646f51b8cd7cf27c9e62160bce71a2da081d57e90a53","seed":"f46d771930a5a1f69674aa4459b0120ffc52f961d7f05a4f0629e580e3027e9112b81c582a74f92a63a0235d275be17a3ea24e8f3d86d2f460142cc3c075f352","priv":"2dbe6c2f1f3389a29271ed7ddb5d5b6aeb44cd3d762b9c5949f981f130c096d6","pub":"03da1b7e3745edb58ea53dda791d7dabd4945343d471f41b706ef2159f4895b234","addr":"14a8aeb393e7a99b53cc3661717b6a550f4ca30e"},{"mnemonic":"siege welcome clarify bread decline educate off snap canal north glance flash","master":"fd57e9d99aae7bddc7bf2218267db21683280d1c1fcbf1d0713d35c872dab359","seed":"d1771068274d476b8e3953ae1dbbac392157fe72dc01d9c1cb66936f26b07fe9de52c257f1f8a89ad5677a786a32b231bd4415a7fd6dc18ebc70d53c16d91f9d","priv":"8d0c094475b505e3c32bba7ad6817460ac20c5e75e4d5d0899d96fb2dbd8f43d","pub":"02bb4a1051ab8df516ba2b5bf42a99dc1a153127312a81f93b16121d2c60dbba1d","addr":"43b7281f4f0495f6ffcc129e1fe90cf772cdbb00"},{"mnemonic":"total wood brief sail top stomach phone silk soon flag beauty equip","master":"2d3e2c155708e47a76ee013fd8bd3d62b17b467fda08869fa5b474cd622c7e87","seed":"98cb2c832f8a2e59601b5dd85c1321251fa576f5e8b9ac250d18e45dfea7a492c80918d864f32d1fe0f3dc24fa1b8eec3cda8bfc526d4826e94a7ac352edc705","priv":"5de85e11fa81b39f6cbd36182259fa33ecbdcf309e2256a1ce91500a1c28fe91","pub":"02dc14302285378aa1783d6395e45b37aeec4456845bb90dd2436a15c601abf050","addr":"bfac65e04a1d9f0905e0d0cf87ba1531bb49bbf2"},{"mnemonic":"junior side human tomato army twin tired mammal sing evoke tape fall","master":"0a491a1d250b31b44ecf38584c65a733e785d65082d693847ebff6f7b749aadd","seed":"65c7faabd749b66f9f16b234142acf734fdeb1fe7c9170355471c008a3224c40c5c2b77aaf516f91fcf17e73f2905f021354561e56ccf08a9eedbe51ce8e8fc2","priv":"40dc50171a806155da73f7c5cab57f7db270e225c33eaf0665c0067e1d2f7743","pub":"037325819201f9eea88ab9e6856d2e60f02c41d3a07c09fb7161c42e05b9db824a","addr":"9acab1c1329b243a5959cf716dc5f29ff1a9bf33"},{"mnemonic":"fitness wire sun minimum novel scare response ten profit breeze equal wealth","master":"0292d1ccab93ad054ee3ff95f3fde715cbfb9b896894b56193003861f4403763","seed":"ab34f068d14286ef45af4f3339ac19d8704d84a3f4af2c00092f431f919252487759c7aa09511271336b3a40f446087e7a63d1cd5603244124fb746160ffe872","priv":"39ef24672e90e29f268369bdab5aaf09786efd7360b535bb4846035b12d1aa27","pub":"03db46d9a6c338affda7db18355bf17ddeb8519a59e193bfaeab4fa522b4124288","addr":"c3cad6c638d4f7d0a75dbbf9fb2d170f79f1cbf5"},{"mnemonic":"quit present half acoustic uphold buyer measure matrix uniform black play vacant","master":"6f8c86f53dab7d379e621daa00a25f6123d43ef2452ee6b7c20e43dff1379409","seed":"bee800b88e86d04b9e755c63669dd4d324c0640e1c121427cd08d1bff6897fe622320644844fd06bc16fd9bd7b981e473cca7cadebf7f50ebe3f917c0721b988","priv":"6070835567461840e0b216338b4a08313cbc3d8e805cd694f379fa0112975523","pub":"0296271e75096d7bfb7393b449318613c522774e7b2d4e0eed6161e80a9376bb91","addr":"3885ad9e25c274d8e461f4b685ec921aeea25b80"},{"mnemonic":"endless blade swallow bird faculty group rookie betray crucial amused gesture pupil","master":"f62cc9bd1a5d26309ff51867edac4548f63e30630afce94a59d94d77f6df34ee","seed":"f4100b5b36d63b0a87ffc828277c8eb2f0055d2ef500b402572d30cc23418960b831c84566153155d33eeb8ce65ac191882810a1281e87c7748bfb592103582d","priv":"14125462458c4e981d9dd963e67965ee70eaf50af376daefbd7f89a3d0cafffe","pub":"03b64c625b503104cb0f9e8de837c741c4952140348cc5d7d1ff379e35ae37df6c","addr":"64d529a1cc4a11c305c8ccbe24217f52be17a69e"},{"mnemonic":"evil lend heart deposit index prosper mammal vendor expose sun arrow school","master":"d3402de3b79b24291822c2737da8e7d760267adcbcff5af52fa7c33ecf199acf","seed":"5062aebf0c68ec4ae51b8f9bebe4cdca4a07989ed9a96888205a84d749ca90f8d9f2c992862f7fdb4bfc3fb2c590431c5fec415abd9a2d4ad04f7504b90a9081","priv":"ff7fa17496fad3c29afa98d427186cd43fa9aee71e2a81d2640fec87ebca2ffa","pub":"037eb47194d9fb1e61a65e399d06bc7044d02097a0e5939581fa9b15346eea38ea","addr":"8e9b1eef983e035d41aa63ec276454a075c52db7"},{"mnemonic":"various cruel sunny human sponsor seminar stumble romance hire cabin blast rich","master":"25f93ffcc752c263058f195fa4b2f80c46aaa057b399de9241c0fa8cc2d3ec8d","seed":"89ee6d4b8a328ec819556eb043c769007e332ec4ae0309c6b6f82ed70b725e9ac8d64cf1309ce0ebb0053ba515f6e42d1273ac4d0d1b9008b9375844a9e1ed24","priv":"4aa30facb3367721c7e39c3052e7221f0a926a00d00898699c483cbeff39e407","pub":"0312c6e2800eb33da7459a510d02e0fc5c91778c115c535eb429c2c5797675e2a4","addr":"9178f5d44bc450a7a1fc5746d17440670fa0eda8"},{"mnemonic":"kitten rabbit warrior replace dolphin banana aerobic arena elbow leisure slogan panel","master":"28b0f611c4fa230cb47936546853fb9f0e13bd6a4417b5bdfba9c85eb80313a5","seed":"88a78a4f882820e729d42557ec5db0984aad2aa40f535ea33416b0b89d25511fe4b6e37cefd23acf1ab65eed77b0c6ed2e453a2c7e8d509311cd802eb267200f","priv":"3af577c50bf57b6f44686af34c65b683c305496d1799c7c0d9febf9dacecade8","pub":"025901819b5c97d505616f3d1b5be0923564d5aa627885851bbef7b4efbac4f95f","addr":"9898d22edfe40425e714b877a5edf2d9ab5d7172"},{"mnemonic":"shy abstract heavy silly excite response figure math travel use cram dress","master":"558875deb7ade8202aa21350c8a98aa64d383c4b8dc6315a5bc149823398c8f4","seed":"256d310717830704992b0767827ce796310b3f561f5faa152b97c6bd9ca1bd10505049005da5026e64377dfc9b9a23b8f71b2dd8e4ae0644055a04b650a721b0","priv":"80c1b4808495fc23f7fba2bf9ff39a4b084371807c61ffa6f6b60cc863bc8fa8","pub":"02268631554db3ae0b7ac58b2437556d91aee4c2ff2eaac5e4a3fd6ca6d96eb960","addr":"e1b0517748e58df2cde812d45c251492008ae499"},{"mnemonic":"tag aisle unit arrow neck knee border plug order decrease corn hint","master":"67412592e636701931c0b0723451ee325db3b1b7d63938c83ab9b4aa5630be4a","seed":"590e676b0362db643cdac3687e67274fc7f67a2f3a6f274da3e8629893b1f474fc608eb2928fa2be01b9760807055ba11a7ca4b52a28b2f66e05bef7f09845f2","priv":"1cd36df351f7dd9b4746bee1d59c42f12b21ce84b9979e39b3b810ba95d13e56","pub":"0217468adf9b7f74d88b312883787e6baadeacf6436986573371bf19c359ce047c","addr":"a719fcec68779b1f0f92460e511739e3bc704be5"},{"mnemonic":"urge order bomb glance dream diamond cute quit napkin swarm oil taxi","master":"e7c99156c46a51a308bb59a9be9cec9d45a55a8f10908f2294b4a35734c24cdf","seed":"a31e29edd9da883053ab020e2058d482cf2a63b39a7d99f47a5972820820d5558f24bd4d86470f1b8f6d1707c059e2353c65ee69e0e2924376f84f36e77571e0","priv":"e204a5c8377829edb3a8866e028294d6fa34c6dcd76d10cbd857afe41f9f6852","pub":"03de7949f7a90aa8f21731e2979b684c6424537283dd15881f31541f14a0837042","addr":"fa9f6d11bf1fe75282dc336ac24f790086794ca7"},{"mnemonic":"drink combine way human stamp code chaos honey decline reopen candy stumble","master":"902a5423ff40734c67ef9ef008e63a232d1c0e30a8b8b75d911a5e5c31be5725","seed":"c5ee4ef92fab9bdfab9e859bd603a9b293509ae3b99427a3db2b3eccbeca2b2d717ff5d5ce010db0cafcf261e6addc949bc3c0187a121e303a0246125ffc249a","priv":"59e235dd2d86967f6690fe2171eee062c5e786ea6a0060069fab9dcdea5bdeb7","pub":"039c4adb01d0bffdd50a34a458ee58e19ed81d3f22f740af2414594e42447c9de8","addr":"3ae7c41fe8a65e527a850a44a5124597f5e43f6a"},{"mnemonic":"will confirm boy glare draft hospital grit marriage hen radio coach cram","master":"cd54fa9f850f2e90ead19946218c1c03ba1491d1273f6e2e59816e50ad80137c","seed":"1ac5cdf381522c28ff90b993d3a3612e0f91c08b89b11c83315ed78b7d89e7a342621344ed75a7bb1d996487da8b60ffaa75ba3ef504814636471fa017f76b06","priv":"c63babfa6c2e301910bb8cb846259aa0062e25ac8523dee9449354e9f44ab49f","pub":"0272029d11d7a1998e79230a4e82aceadfbe29925639f6ca6dffd237b7c12a6867","addr":"eba6a2907bdcd422c68a04093fc5127ef2945cc8"},{"mnemonic":"sister mouse nose morning remain bike wreck reject flee depend foam oil","master":"480c68e256ac710a18ff386a76b2a3ca50ab4214a23d2e162fd473f40e48ef88","seed":"267c7df08090f9d95d26c130af19c37adeffeb28644cb449a39fdc2038a5a87341fc9fb78a91c9d19b8a4843146e79e57cae43b9d1d65042cdbdc8f97c22f02b","priv":"d6d76df9474b038eb47c93ce8bdee2163ed5906475bfe0d40b31bc19a501a2a8","pub":"02a70a232ec5b59daa30873a4c11a65848d6d90b5775e488b87d8829a368fcd2e5","addr":"dfdf9f283fb3e21240437a994ccf124089782718"},{"mnemonic":"mule parent ritual earn swallow visit jelly give sun family scatter lend","master":"946aee32749e7c2527a9d7066df275f6a58b4d979778f565e87db434a4d82ec0","seed":"919d5d8ecbf7c9ee555aec51c4079aa8a97ba7c6207be27a119b307ecf5433e0e44856f21808b1a7c65ccd7efff25eaccb445cdd3d45c682aaea9d8358fd398b","priv":"1ff4a74557f15dc78cbe8c3fe3b760c23c19c2ffa12e6fcb0c452fac97a8c1c7","pub":"02b880cd243da4622fd4084c0779a34c117cac73c193de6691cfb9783c23a13751","addr":"5157180c3b43d1127614fcee3c772b45f438a73c"},{"mnemonic":"modify puppy army pull trust icon suit submit fade game near machine","master":"5b3dd4912f293341f8e62b55d25a7f01debaafa1a8ae6d7d9e34afce8d534c7b","seed":"e73259b5532099bfdcf2196ba80baa86886343ed2a5a7dc081128e5d94232b52d3914a8fb9ee17fcbbdd0d2199b2febc3ee1fb430729a376f8106439d45718e5","priv":"5a502a6484aa0eb1f7d963d950574d1cc348f3f64b1064f0d6ae8526293b9f89","pub":"0279d6b5231ca7729c450b055d51f350ef370544b83d10e80501ff5063961ec425","addr":"54a6fb03ba980c6efeb0e4e6eefa8d5c06f68dcb"},{"mnemonic":"beauty fetch title weird machine section remove better kind unfold candy risk","master":"b9c854671b0922cd1c27f876e2bb2748e74d7e5c56f71b7bb24e0f121c312c51","seed":"223ad6102e7f9e49ae732fd584519ebb6c139fd5cba630b78d2e5872be280c5c68eb6ed3b5b09fedfde8cbf6dcc1624f3380ae464f1d30c2abcd8d8ff5157e32","priv":"9c0c7cb874257ee95038077d5fb1be111685c5a54c7eae74da353fc2d476766f","pub":"02be94467d1120e497f16254d1840c431ef8254eb6a0b1f8b6e63b9f482ae37981","addr":"1c3965d6dce5a86ed7e176420079ebd2f475871d"},{"mnemonic":"broccoli ring road spell bubble slush cable column boil wisdom glide again","master":"dfe7a6221acf8d8f8b29530792efa9ac33b94e352f64ed3244062651596b0b1b","seed":"518f8503f16e8e5810486d1ea5b70951fe6f17427cec5e7f68584d7c7f101d6670ca755f81501146f3969f1869faf5efc6aa639ce47cf1d337367ff2d5336358","priv":"b7c6e7af8ffb55f9282d13c51736270a9b488191d8e9a4999a2735d5dc27ae5b","pub":"02ad6e0ed23179b9a12019db3afda6555fb3e088f2cb91eaf53db823bb284e7681","addr":"cc65b77303a5d3d42de2ef404a05ffd8b0fb73aa"},{"mnemonic":"settle jar tag talent bridge onion jazz vote certain job high lounge","master":"fd3df0c73c84b19831fb4fef9b6e8dc4eec01c845c38276f369ae73805cd5bbc","seed":"6944f80e097b237b7eb501d2d6d735c644c7d9fe0de4a1d12665b27a1567d3d619d41a9a469622c57f2e7998af4f8784dc1bf30b715b6c867d61902103ffefff","priv":"93d91fee61fa1f6704da23dbd1ee4b5513399d1d7ad52c3a632d5e3ad5884895","pub":"0331248b1a2b3ac8919c5654220fd21a10d2f700b2bca6a16d94ab25cbf60631e6","addr":"8219e185c9dc66aa8ecef927a93e884494251762"},{"mnemonic":"say unhappy visit follow rocket bind capable lunar age erupt depart leisure","master":"bb776f6f57d90a587b76509d6788c1afc54b7a35a06ace60d7d627605e462d9f","seed":"e20ebb6b86a37149a20e0f07a637de61af6d37f76d9bd84c210c8c06f92d23e167acd0098be525e943e2c4e7378903f8b4572190ba1c6b37ed40fc023b355e93","priv":"0bb90cdd4f552b15991e6e9c1546d78b4445af65e60d6cc850b7d4f64a6406d5","pub":"0342b5a2ce673cbf8610f049dba20a0c7d92091b7df857951aca402e56acda8a8b","addr":"1af59207b0004314be04dd208cc2154e06476ed4"},{"mnemonic":"next broccoli cluster someone just you crouch monitor crack tribe slim cloth","master":"87d2484fa935339252c8b0db3b4604f42e12a48ea00d22abccfc8a4ae9afd60d","seed":"abe12329f69d107732e3a3eb4ca9bd693b1ad465a042530031d0cf79e4d32a42185677250418809d0cf7fe7e47e0deeb76c321a8b82060666d36f8a79d68d2b1","priv":"9fe6b21141e8035d253dd8fb9e6009ef14f1680f58629dc880b50fec649bc00e","pub":"03af8824d512a243566015275cc2a8af24fae7acc538fc292806c2c95688797e9b","addr":"02f4e6e52415b7e25431c0af1f43f7dce05b08b7"},{"mnemonic":"scorpion artist craft enough whale maze copy ring search sugar rhythm few","master":"8700b2c3bc7b441f6600850cdfa90caa3fa8e4aa6c3091d9850c42644187c053","seed":"cecd5fef8caf60fdbab007cdcfa920867c0057d0c65b55ee569577427914e0e3227ab8cea26f50c1596fcf79a88a521721257f43dd84ef1d81e2ae4a8b73ebae","priv":"8dbc85572bf9b0f91c5e4f1516f3056c6a3608fd78e6b37e7dad0a0a5e4f6c2b","pub":"02947910def2d55c81ae2fc03727c62440713b0cfbaa854f3c7e9cc5b8f245a2fa","addr":"a77f593385c2e978d99f0a6a3d06e427f01f1c7a"},{"mnemonic":"improve help region hamster then raven eyebrow account sleep cliff copy pull","master":"e479782ba4b1b4f605fe2e892c6449a91a03aa8438668e22df211275a5644c92","seed":"bd788f3b47b98d37521fb5d51e35d42489fb83e21dc4f0fcf55dde6c2e1b561b63ef22f51cff2c190ef8b18cfab7af33df8e83d14d066c6b114404ba809869c5","priv":"a2deecc348654217762f8e5a422b3ab8aeb07738a75c49de9a1aea6ec767f4a6","pub":"025ee0f9bd4bfb85e42f918e91294fd9023831385e73ed06aabbbb7234d1707def","addr":"b80dcc0683ebdefb2a30398b0ba1478de6742050"},{"mnemonic":"bronze fix prison velvet sponsor woman vessel crunch forward sunset similar wedding","master":"608887c856e38875ce02b2bb7e6899698cd395db9ca1e19ebdaa0dea5dbdc1c9","seed":"66a0fc313ac72cc89a85bd4144b69061ca1e65f7d1968824f0cffe10b10380278428af5b6a114d6ce2a88e3626dfae38133acb02096d0b6ba7b9761a8c4a0eac","priv":"47de7838c74b2b1ceb138fdf96d455deaf8fc2550246a479ff98aa706b1d0211","pub":"02202887af1c72f72abe2754b6022a163b2abe5ee9f288126dfd1756067b03b5d7","addr":"8756dc9521ce9ad5e22d2612657e552ced185071"},{"mnemonic":"fame answer typical zoo key rail state chest snap stove urge collect","master":"377482e11aac4f724c3a1f94c8abef488f1807e3ad1a92821d7dc3f6377a2c3d","seed":"ffb372372dce3d525e923ba290828f0b5d12f65b241d5e3c36d431c1e1b3ef737f666abffc9d7e60aac3645a8f385262f2295b05c42a4c2f8bcbc3aba9edf5a7","priv":"bad40853765d64cdc729c94aa5e114fae54ee014517dc5231be8321bf7d93266","pub":"025d64a940c5b4dabfe233b552e43239b69dba164eac66b48a36f4e06915539575","addr":"f67fd1e04384628a47a01b88c399b30df8e5b226"},{"mnemonic":"expand machine nice damage roast slam example resemble tonight enforce salon benefit","master":"2e9614bf212cb179d91a224f1cc36fd4dc0a5be13eb5ef3ec614cd3f5db5be18","seed":"97c59f53a69f280fcf28110dd05e7510fad1d00e26d30847bd1dda99324ea2efa8550e5504f2f2648fef7f9c03ec58b2666b94269b3b5bbef1577f17af22ad1a","priv":"bf9962586c0636a20519a0eac17870ed0fd09862d4ebb563b3f445a179873551","pub":"027eb40d841c1028b75f21d593300ef57c3defdc258d17511ab086988240619261","addr":"d107cca0ed49d72efdde4b9369855d188f37a65c"},{"mnemonic":"debris scatter erosion dad quantum almost zone off bless tuition garden phone","master":"706940b567f1ab966a5f2db1d3e5eb832cb827a89c5bf2d17e9f3628ac6f88ba","seed":"b5caeb5e19c5c3e1e7a1074c3e4f366431d57f5ee5208aad341020fd33b2be38c2a228201949b6812513b28523cd82594a2db67177bbee6472bc5528a0fc01eb","priv":"671bab5dd3060bc813898cbc63828aacf50819c35981793fa9dcbe26c3427dc4","pub":"0283689f70b17659b51e2a5f345ae95e3a23fcc69941a5a842e992167dd958ab7f","addr":"aabde1e66f358e648444fa2a10be7404f1d6094d"},{"mnemonic":"expand fence want silk inhale web seed slide pitch fever online puppy","master":"2f3f69643bf40d05ff4be223ad7f05f0942166b629b6bddfe022df650b52a235","seed":"025608f609aa5f6662cea4323e4a4fdb4115f68d8cfd903886fbd561bf9bea74ec1e0c5d871ba46a1821efc769b2447c6b8d8f242fa0dfec8546c814f97cd120","priv":"26b51c99c8bbd84af26776dfb9a244114a66929f24fb782f195267fa7b35bf89","pub":"028d38aafd513f554facaf66eca4907f01ca8c48807898b6e142b609e93c3521cd","addr":"f5d92901099f9516401d963a0693f4d173cc2138"},{"mnemonic":"pudding mean volcano leader grain general because hockey mask solve frozen canoe","master":"a7a2aa088f904b0c44d1a307a17be86554cd9862f47b08f58205a7f73f93a011","seed":"d4e9852e81f9162b8fd6d1ce152e96a52b70d59289cbb8382cdb7bcbea5e5c5b6649aa6a2d138343092886474816c8e9c9f8c198d77986d2d6f7e1476f1499a1","priv":"31535d53290a02faa05f04894d6381b6edddcb7a374b19f8940d4581f9582cbd","pub":"03f89337767bf64bdbbca6a53184c126fca28f7613f2668a77119f62124f52a0b4","addr":"bd54d3175097fc470fefd66c7e5e63e7aa28cb70"},{"mnemonic":"make protect hungry coach tail female capable swamp alley one nerve nothing","master":"f171811d3c1b278279379244f480bdc165f5b645521749b2bf7b5bccb91e64a6","seed":"f8ebb80407da43b794542cca52f76b053175290dbc00751dfcb4539101bcf34369f76f686642c46728aef4b93f91f5ed2896b2a102aa3cd45e54591fcd0dd919","priv":"ea4ce4340c0eb740a33fec8198c22ec0064d72dcd74f85405f6d7efd1b1d0538","pub":"03e06202e127c7996f8367bcd0b28f779207cf222ec3d5d4190abae78fee5ed57f","addr":"54ef6f20caf4216e10a99ed446c842e3e9d90ed8"},{"mnemonic":"royal behave retreat force stable law cabbage home episode valid similar amused","master":"b2d8324833e37ae4f1a9a70dc33d070223b6313fe60e31a0c240b03f644ab78d","seed":"2448c418181d981fa42c83da24dab9d73b6a89dc0f86f624992ec9a982ab04e84989ff541364f4a289969d458364eabb08d51249c55ea16c29c6b65b5b95d7c7","priv":"473b6c4e1192b52fda7e64be4c34ee0197604c0e4c918d2a61e98f35fbd3f9e0","pub":"023bdc3332835493ed0258dad839d90c8503cd7a2a7097893170c6498dfaa2d534","addr":"d77a39d95f6204755a78c3b996c7bd84d1dc6a42"},{"mnemonic":"major dentist hurt task dinner exhibit soccer disease bullet knife hair nest","master":"9202dd767a3b88e0162803d54fb1e251ae14be8337829efc06770dc83aefa0b6","seed":"4c2d56edca18105e69c59b683d76034ad69006170a595c5648c84237ef0568862d5f95873334769be9937b83c5c96881569f232dec873e3947bdeca6831b1952","priv":"4db6777136a67a8279bfca36d0531a93bdc9e6eac4496fc20acbf78268e35d69","pub":"02d35a568677e4be8cfa051c190e54af69f8124daf5f39a288bd7a0baf1b1b4b13","addr":"6b8223d76a499b98d5bed2b146768569eaa7ab64"},{"mnemonic":"ketchup urban occur rain cheese bean need august autumn clarify kite chuckle","master":"8aa0b8b32ccae13b15ea9c808fe3b1185026c52a9f3b39546b355aab66d7f9a3","seed":"c910c33e6e009667a3d64ef0d10ce9738ff80aef32326d27b8f82bee0abf523e2940fc9ac6dcc27d10ed602fb60a99409688142fc18a9fab36fdadb6d76f1693","priv":"4541e2bafa8a4b3fcd1c9b49f646b3950292e0e18c2f1accda6d53197aca0d02","pub":"0336ad51e9c8d24af44291449aa86d4cb798181b2bdc9a2a6ae6a7c857a5d72c4e","addr":"9a37a2e3c1b6763a580a3b2aea95cf237bddbc68"},{"mnemonic":"shift anger harbor behave icon boring zebra sketch kid human nature learn","master":"139db45e5f8cbe86f23952b1558df3924dc55126119abcab216158285a645f61","seed":"1cea92117d8c90c554ae3ff517be704caa5c0d16369f68eb061154d59fb42ab9a6ea7ddcc62325df2c63ba0349e73a50c291edc1ceb0184012b71f2f5892a4c2","priv":"638fc2fa201498e1d76356acb3f4c5b42984c2c4b8619b0138426183daffb725","pub":"02272782c09fd51800d483c408ade4509c5cb83573293b873663a8492c1bf6711a","addr":"020ca2c2be203a95c0f7eade606d9c27bb572835"},{"mnemonic":"chat grain wisdom yellow rough swap notice range collect maple actor genre","master":"57363529ed9e9ae59ed408390581f344a7b974d130b23fc1da952983604e2cc1","seed":"d4b51a786cceb10f907941092f90be911c3ae2eca9924dade05aec85218baadc6b8137e86f4723b7500189529bc1da0b4cc95d1a8553cada6beceb71b12acaae","priv":"6245ecb65a10ed313dfc02843ac8e848a17aa37f6c3aa64007ff0b54b591e37f","pub":"032c33f1bc81371f8e599fa64736879a9fab286469e271d2fcff6f97b1b4829e46","addr":"4e076a5900d2016f08628257ae798a102c007e94"},{"mnemonic":"feed good spring pulse avocado smile surface conduct copper chaos dizzy describe","master":"003488e5bb876fb831b5ced5126e5c85ff6f98203dce52820acb139e31859ad0","seed":"e71271c88e445005f5bab28a4ed6c9d46f41adc6b646870c4097252e6f01d51ff9720d2960c61b9839cf29b559232b086ee5694252bd1fd73d601a27d78f8787","priv":"7702987362194e4b70c66b9d0d330a383e2710cdf863e5bb472c31815b6d9fef","pub":"02b790b42543e16b9c30a23baa39da3ed1d48402e51920187eaaa6796767ebe49b","addr":"778d3554fd4323ae321b6fdd0d907d28a4f0a886"},{"mnemonic":"brick wool tired another milk slight owner year electric later because response","master":"473c6a0dade946ed832babc01cac18b33ed7ea2303a362dfe6671202448a1f2c","seed":"ef22617d9f1ed62a89eb986d9addcb33c98d3da5e205c4cdca8c9b99f6267e0122d86be0b5f60c46d8c9f4c569c3ebade2376b04901bf8bfee5de83f6f818a21","priv":"7df1f72c7a5cf60268e760c29246e6e43f8168ab56b9c83d23df9923a3e51380","pub":"03de70b3833b9be36c88018dc6296feed7ae17d995af5b6942a67bd39689129498","addr":"27f48112f2be720f42706681bf2e97de964a009b"},{"mnemonic":"poem rifle october destroy castle scrub yellow brown soon this share radio","master":"bd39615405d3b2c25d023095975e07405228878f004b48be0a32fba278394020","seed":"578f2a69d418ed6bbe4a7639c6094396821dff23d1c26ef1a5452e91164e142fdcea44d63ec2eaa8d491f7b3757147f371ddb624fe10d6f7bae502e062671100","priv":"7cb45a918ecb28afef642f002cb9627381e1986ad90cbbe54aebb118724f1417","pub":"02ad197d4780b28d57ca50799d59fcc6956b2bdb24c8e2c2a221d5cf65007d2536","addr":"09c81b6b7dc3d57d239ca18573720e063144916a"},{"mnemonic":"hedgehog october thunder frown game aware reflect art favorite elite urge pluck","master":"0f2082a1d92a2d2ebdd605f33eb470568c7d82d0edf73e2be8a766d060dd61ad","seed":"9ecc3fc4516a37cafa09405c306bf19f53b085088a1d1cb0c54bacab3f21d4edf4adcabfa616137753a427c2269d3b3334a952cc5f4531980034433e4bbeeb9b","priv":"d3e3e9ee84d32091f08d7fed384fe3ec0465ec460f90a2749c69883dde03ec65","pub":"03b5af12849876b7c9c0e64833ea79c5b58f4450e4d67a99a90b3c9ab4ec3c8155","addr":"c5a46d31f9e363e348dc4ce803d44a676ce811de"},{"mnemonic":"goddess wear mail poverty exist pole advice blouse famous inform wrist pelican","master":"8c09d67d7e8691a66d2271093d7f74f5eb37729df23bf98525874b6d600158b5","seed":"093b6596b4986195e484e2d8977c8bdc20529c58527d9181c4d4e993495bba922fad305d8d4f13d9b5ba20c5e375dde147fda5aea8accf634d522e488d163c88","priv":"b028bdd6652a16380c61134fcbb095d372e63a117421fbedc46754266edaf916","pub":"03bb1f45e672d983a8856631fa8193422820747e3f8706e55d761d94bf091d7d6b","addr":"528f7468425b08f67e90058778cfb1efc46182ee"},{"mnemonic":"increase debate symbol swap raccoon crucial noble benefit kingdom prosper proud medal","master":"eb8bfa1409b9b28fb7c826f884d7eebaa6203e7bccecbe133e55df59db2ab8f7","seed":"5521921a26a36b06e62a681e2accb9a1577b6342085e9c9498f5693ce6b79fae98b9addd2da01df263445b5e45d2b4db45621517f96b86cd43b0ed00f7797fe6","priv":"e1927e2b0769daec6f1e7af012f1a14d82d52b89bc83a2fb9d007be1a51be4bc","pub":"02d41fc73e6624af22813b072d72a1d31fd628a66ae61e5d191c374be419c4a586","addr":"cc942c7413a8ea0db73c6cd3e2bd4c5e46ceb395"},{"mnemonic":"upset dutch damage thing maple ramp marine leave audit ugly walnut cricket","master":"012beaf52cd1e042c96753770315d25444e18cc63446a4207d57c2287d6ae028","seed":"dccb359dc9c2c2000e0fc23e100ad2ffcaaa0ea9bc1cf036b14c9c1f1542a4f9747097994ec5dc4071ea6863c01b2a5bfd6f747faea05dae4c3fa03eb2716b14","priv":"391710f6f67f54bb50abc86e349b889d0163a4c91dd1727dd3a6ae0912defc72","pub":"02bdbcdee705f81a4764a8e62de4bf6cd26f748be843fa36acad975980c5ab1b58","addr":"888ac8af30c1372d6c243363f6a8d97d3874eb31"},{"mnemonic":"truck stairs excite range van electric alarm sing provide mesh jazz cloth","master":"ef39accf9d3261de50dc985194a30b1cea9a861e2e48bcb47b8ba4542f855259","seed":"088e1bc0f701ada0c35c77f0d17ac9cdc3fee9747410407a1748b2c7e72bb37f2a9382e1108bcbaac1fa2db5aba2bf34574f47fe46450aaffa7712e5fefdd40b","priv":"e2e2d2973b52c1da6098e31018dd238b02ecc1d22236e631ff9d3009572ab1e7","pub":"03bd54aaf28542c6d155ebd24c032dde7341005e69a5ef67c3de5138b546d9f462","addr":"246b883c299597436993fcc8b22d9154db9d8f1b"},{"mnemonic":"admit penalty clarify isolate decrease draw virtual rhythm trim brief vocal box","master":"4df1d8bb85983df8abb7af56086dd76becdde81861462889c5a0809a470125cd","seed":"4340047ec19d4f318596cbe510ec11f233193b72214487cf3e8dd90c11f1466004810ba433261962b9c412b22c98655b06421b3bfe73ecfb1bd95aae30142cef","priv":"965f07d8304bab4719f071d1e3b656165a70eb31fb57d5cbc27e03780416d304","pub":"02e3a67f5d360f10b1786406cd2f1dab2abbf606fa014502ac9a7bb56616597776","addr":"90c64758c772184848b10adb3f841f14c86096da"},{"mnemonic":"citizen fire fetch luxury tumble analyst pitch van sketch measure effort danger","master":"e3469c68ff7e9f4e68af468ae8be59df246ae039ab8ecbfafc9677d6fa0b3d5e","seed":"bcd37194bce09d9704926235b5c83323ca7a71ca1b3b257c5436267a1e14b7b37fb44ad7fae1b818189240e9006cbd920b36aeb204ac00f98faf9e1b1c2b7034","priv":"d3f4ebbfa161b543e250ef0b52c027e49548d5a36a8bcbd8cecfddf0f1ecf92d","pub":"038f2c2418d2a68827be4807f06bc9c59ca291b34ee5284e860abdeff90197d40a","addr":"a44c929bb81a0dffc76e8659a44f85873578c005"},{"mnemonic":"claw stage toy keep crisp memory donor surround bullet ball innocent faint","master":"1025d24a465ea26b933c44575b283057daa066d0f5f0e12c9411ebaaec29d26d","seed":"effa6fca939b041aeb89550f138159090189a0ab3c96fb9151bd3ef69d29b457946695331804e437353d134f0d069b28092f122f35e74eda8a2d643c3d1a0f31","priv":"a81c4bc682ef7609d7ea9bd370703eef25006557166b9e04e589083bd7cd65c9","pub":"03b4d5e3abb4a6eff0409b20d8a1a88088e591a6ac3e6e25fb66f172303f55e590","addr":"09e4b6c1a32ed0e0b671e0f241708806a46fcd71"},{"mnemonic":"rigid neither track gesture effort venue vital bike spend unlock special swallow","master":"33fb6294ade198c457bb6d318b2eae4d2757977af36b988e042f1c3bb42afb7b","seed":"58b191573da33c6a4d94b8589fb32f8c5af326f5f40ced92973c352295e71d7a07251c8b42355b0360fe3ee2cc42b3217fedb914ebc61faae8a0f8cfe579fa98","priv":"db272ba1dc7e8aef500e29a4acf750dcc6fd92e4ee2f2e4235e7f82034a1857a","pub":"039d506e2c16bffda4127fc073a6e1b43b2c0ec68cd6d86bcffe0f0c4663b5033d","addr":"5485fe5a806040bf059c1e0d90822b49d14a51f2"},{"mnemonic":"sun ankle door drift sustain task home retreat light say wash pretty","master":"b0a3d174b40c1f2a723e3a62f878c1d4d19673c632a19fbea460d4d0c35d14a1","seed":"63e84de6c5f71a4b9dd5fe8998f00d0f8d0f2bf6da159d82bc8fe30475d0e909a939d7498936ac183e8220acdf104aa5dd0f721e65eb06e99baa27e81314a2b2","priv":"7e2d6c88823a8effdb5266c8fe605968ce231150169e0174e140643780bbbfa8","pub":"0280cf1699ed3cd91a57b8520c1173c8e8ff036cf759d4e076df031115c67e62f7","addr":"c31630d1643d32f652d89791c5de3a4b671773a8"},{"mnemonic":"ball symptom nephew dwarf mango crowd radio shift degree envelope science job","master":"449cdf41d10e6dc749aa52839a9c23a74c41cc7be85bd76f7ef0ea8347a76db1","seed":"303c978ed8b692e5e334bd1dfd0ece8615af24457129e7127e2ddc69f783628cc48d0d31ab522ffb6e70761dafb755f5878b45579911d52157c37c1b14b900f5","priv":"f6d3c4eaf86ce6c5c8d640edd4a67ff7dc852b6fcf36918f2b9e36df710b2049","pub":"03b3e239dc04042dc6c83a8ee1973917cacbe375786c73aae74a6b46cddba54773","addr":"f0eabf6d01285343afba4b7005268ed3af052d90"},{"mnemonic":"cactus trend empower board street stick animal replace media unveil recall proud","master":"17b6f0a996810ab534ac366a8890f7618f372ce0168b00655740f9698cb8595e","seed":"6ecace1a5b927d3058a08f1a59bb8943d214ce5e48e3627be8995814640782de30243f5a552e5600a3e1c62b3a46edb558434ac56bd105e4fe23aef8a1c0e4f5","priv":"69bbc1e6bf17262180141a0b00e6c410c3ae5b10b69b20d6321aa3893250cd6b","pub":"03bdb7edf4aa8f5e6bcc5bfd6a898671b0fd687bdfd9f8101f4ca840a183ffb226","addr":"c5fbfa7d4e0356d88cbb5e5bf47a67e877c1b1a6"},{"mnemonic":"source note bundle laptop pistol business only dust bright govern illegal melt","master":"9e7f939a19be0a48a3d9a740d8082b968fbd41065b1f5d425cd20d73d327097a","seed":"22b6512400907bd050684ea2ef220c4bcfd35d59de2c4c5dc3527436c417b68cec186640ea1be40dd00ff27b13884cfe7146c84ee3d568b8f74272f0edd91574","priv":"3f378db3f2004722591ed742f0d802e6c4eb51f357c1d77180a777d083b2ce35","pub":"034c05a98ebddfc54812ccfb797a99f3cc09e525759b7f40746513d58ce8577177","addr":"d920c5b1bd40b6a0c3835e5d32a8c8d5897a18ee"},{"mnemonic":"pride mobile flock dash second emerge seminar theme lift motor pave grant","master":"786638e9248b3b0ed4196533a1a437e1db7c2a83908c71823e9a8cf720b71975","seed":"59bf3e8f03faf407d8427e9b53093cb3708192de0c979c2e0a572a905af89d5ac43c2d1c2480cad58c63e3dcab5b5679a4bc12a4341cc618836d15f27c2ca623","priv":"f7ca55ff74a0f55f08cd8efc515ecc69d9cc6bf2ca389a3116f906d641de1f2b","pub":"03f538159091c45fadcfe4ada5d2a1a3827206bb4fcb756b9573ddd381b39621fc","addr":"14a320df092aafa1fd0a5207b6408daf532072c5"},{"mnemonic":"obvious man chaos alarm symbol novel accident label engine noodle inject empty","master":"df206751043497e26c74fde7e068376bdc0771e3e06a1e8bf17209bb9e1880b5","seed":"2178b8972916ccef4040e2c50cc9dc039a6ef7f799f2287d8d16aae3edb6ec0a20bcc4798299d2569cf6183d7aedcb426dbfca1971aaa31dc4c202f40c906a55","priv":"ab864f86be6e1970df2fa336835986e60fb7040a2edf05a196eed2ea9ff42627","pub":"02c8db2bfc3c7377ba3ec38f9aa7bb1be7d70ed6b15d76d3d5980f983552ef6fdb","addr":"c595c4572aa4b833719c935db03afefc56c0edc2"},{"mnemonic":"client increase remember size asthma source evil venture column truly risk clerk","master":"a0f072fd237c6f30dfa920940d04657e19ebe30e3fee5b0ad8e63cfbb6256d86","seed":"0ecdd247615ecba50ea404632b4f8e2a6babe067cf7d395b038935bcab013f0581c69f2d07ad330cb6c7660feafe8b21af062b474dba193f1121a65f83b71b99","priv":"4b54d2f02c43241d7a45efacbd48616f6293629fc0b539487865dbef626c6789","pub":"0336182aab2751a5399b14e0ac2a856143cc679405fa55141606ec3b2a09c3b1dc","addr":"48d6d2441e609507ca554f8f79e4340f257565b6"},{"mnemonic":"latin scrub oval capable drink common hundred ghost candy avocado stool dial","master":"3c8762364ca16a70f174584f1f276df1c432e0b315e08cffb0d5874760e8c587","seed":"40991c77f0fe52213ce2ccf4844ee6587b3595aee4e79f34cb00ccd0813f78f0955ab8e40a5f369522f7ae3ba0290db31fa1b224baa6ec5a91b57da8ad2b479c","priv":"5242eb4e71fc9715ce4ebf1ce08fd81d362fec9dad2be045ee0d6687e1662df3","pub":"02344bbc8ab1313883fee563a175cf98ba192e8570963fb7c99bd0dbf6368fb656","addr":"3db9be587f22ebc28ae33b4cfa2c86124f450440"},{"mnemonic":"envelope van become minimum electric inflict denial thrive congress visa jelly play","master":"e94c4ca894e31aa091dfb2ef9d7733fbc67f1dd45e5db389a037816e4ae9ebef","seed":"01a5a19c5f75ec7ebc2cf0d96b7665c4c79efa0cd0b7dd5e21c2cf8954f5dc5b1d23daae831a6e18e5157c200a603fb2ffc87a068d1dbfae1d4443eee76a1f53","priv":"7ed896005729b7de5c6c56a19d37f5352ad6329e948c256f11eeefbe8c0c7dd3","pub":"02025c5b38b96fa00b506cb0360cadcfade6aebc6eddddb71dd6efad382b0f6b3f","addr":"1b7ef9f1184a0da787b1231a0f44eaf4035c3ab7"},{"mnemonic":"grocery embody emotion wisdom picnic modify opera lounge impose junk scare ocean","master":"8091cf08fd5f50de4ef91fbd4b9eaaafe8f1c17624fec94cd47de656ce0444ab","seed":"ced20dfaf3a902a7b71ae459781e5013d215567a617a2300b49dac4d3473e624885ba0ca8df6f13c91dfaa9829aaf06c4ffa9ea22f6f17826a1629a597519507","priv":"f0ace0c797c7f3a93bf1f9ae64dae516fad77d18b11c0e32b5d0781d7a231f02","pub":"023c38bcace9489242f81a74168475ec29531c58523f476bd068195d18044f80ce","addr":"859850c7548250084438b5829b4255ebf5fdbe6f"},{"mnemonic":"oil inch eight notice okay gravity dynamic trend neglect bag earth predict","master":"b235b5a4e01f0e64d68b063f09a878c8b0785b84c5106431f4bf9250874e9d38","seed":"96096619deaf5792701545255d539f120ebc2ab8c23ee72de058874b6413e51774b7c2b61be1b1197784fb63fa7e509374449d4c812e7c8f8bccc711c73ba703","priv":"7d05f98b2cfedcb506c68d426b298b3450445a1ac89a3407f4ccef1ddff8def2","pub":"02274745f11a0de371600f1ab8b5ddfab91372f044ceda14c968b7e5bd953dad37","addr":"098fced832e9cc1c962630fdd2dbfe262728f018"},{"mnemonic":"oyster ceiling cupboard quit today neutral repair genius pretty gospel dress rent","master":"e669becb784c8ef38698f778cd27cf0b55ebebb5828531b65330d51ea2b1acc4","seed":"af8030276cfdf70d129e66467a09321eccd9505f662865a4776e1f5a05ba1ff6614b37b54583333e3ce931c9d44378f636efddf5189284f5fa566d8db01801b8","priv":"c0ddfbada817464834555e46ed3eb3d50c1023454f42826463e71754b9e6051d","pub":"039f5c467338b3cf8ac16e6677c8242a67caf89f1201f0f22d99ca1e7beb9f1a32","addr":"53ff0701507c25f97dd1e6721b218184dea2e3d7"},{"mnemonic":"utility angle dynamic fire canal current level trash chase praise witness mix","master":"54ef0de540f88777efd1f3c37929789620eff87bbf98e61f9b2e0783d75450cd","seed":"8701d5ac962b68ab8c34092b44210cb9c11c2332515815223537fcab99909b44a0394436074e60285c7b306917c1165a2f281bca911798b23832723abaf18971","priv":"bb5602644b1af5bfa019f2f81ed0d2475c1492661e55c8e65d8d5e94ddb33e52","pub":"0314f5e5d817f2235e3a6fdc0e86f231825165777c69314de63bd88738e7e7ab46","addr":"6d596a5fa6b1818895ee6fac51915a489da283a0"},{"mnemonic":"cabbage sauce filter identify potato coil bicycle river observe candy maid monster","master":"4e834379e58e480e0cde698f9f8e47b3b6e698b4c1325a995504980e43689706","seed":"a441b8fed73bf3bf06a27aaac9355a79d645f0c7d5d47ec216a8d42d6edf97e6a00dc48de9d9ad9d52279ef26f34990581caaba9d15342935ffe857c10456382","priv":"40e878ef025dc6424f2822e38c7a906b3bc39940e8db21262e6bb99ef3de98a2","pub":"030e41c103c49d2e54e5ba6e40b1dbf04245dca7da0738ce9048d0391da872365c","addr":"9d4e8dd66b5e16369be39000c11b03fd5054e0f8"},{"mnemonic":"method surge demand ginger pigeon chunk because wisdom stadium salad excite stool","master":"b8f4a0a87e42871e927b2d5775fd212dbf911351c525b92f5742ba15650aba63","seed":"3844f4bc75163d8dc39c53cdd0e9ff31182a87ad2d630286897b35b39a14afc5e5ecd3be988c9754ef31f14452290ff04c84faddfd195a3eaea076e48bde47c5","priv":"db0bbe779583c012d78f9b60d6648b72d699c2e6b5e9eb90d293852553649a91","pub":"02bb40395d5649363ec19874f2fdc122bddd8748234c1c1ccb37e38468c6e9da4b","addr":"bf52f59b2e4f01f23b32f502acddf96bda564682"},{"mnemonic":"stuff extra hair depth angry jar drastic jazz diet olympic choose legal","master":"5e09c2cd0aa6504c4a2e8bea31e0dcb7f0b82f040567b681271493e35ca910ec","seed":"ce48715916de04f9c4f9a84e4ca25900ca0292de3a7217a42497c0bab2253693ee8b5425c40ffb2700a65a772e98989a2adf4329a93596a4d6695f6c7f236e64","priv":"7f06d4f3cac1e4b2a7e0951a55f78ba85aa6e6b03872dbc0c930086b8e8e25c4","pub":"02b4ba9df766e58ae8a5164b4be48159901f421b8e8f396593b66dd3a715f268c6","addr":"fb2f7eb9e28187a7b68b02b7f55b5dd46fe9ff49"},{"mnemonic":"leader now arrow loan eternal prosper myself lift limit capital aim twist","master":"8a4e78bbca5c37b40feccb9bf053a24ffd6d0809fc2b89440d467bc903c03244","seed":"25f1e8641b6095446cb3d7f94bdd7d81d92d78ef808b18c48050985564543efcb99f28b94e2e935d31d973a848666b95bd183e05860bd0950cdf0ee8d7e04da7","priv":"a2fdc724702230d79b0c564c34fc4e68e8a10c336ca053278cb3be419313e07e","pub":"02e2206433e526fd4fff47b58ef262eb558e79870c0aad14290d40e912ecde8213","addr":"3389c22a794df27093c11dc80b6096dc3ed0d175"},{"mnemonic":"increase month viable teach spice pause safe mouse allow sound access grace","master":"919d9b6fd918d7f223acf91ea5abd831a1a3568d60fd2e43f0d97e000ec77f47","seed":"f4cec05a2bf6a00a7079213c03c36d765e49914166f497d6e38a522b1cb43fe24260008dbbad00a10d998f7963dc8dc09fd539570f157c9bcff8248987d38626","priv":"f145657458462f994a4e972cbd42ef4de683da47b5b6f95b14ea417b39e702ab","pub":"0289419eb27318299a51fce4f0e65827d0426d72543fa2f05d0c5f21bef86effbe","addr":"cbe298ebb714dd583e7c4d541ec9b38c56710226"},{"mnemonic":"move catch empty dilemma only online ginger rapid enough turtle flee retire","master":"39d365c85d0ae4f31811c665217b718bdb90a4f2d328587bdf430ff622d019e9","seed":"402b62437898f76f87f3e080c3f33f1c6b8ebbb848efd467ee4ae5d3303768c57a15fb1cb03a6befe486b0c02733c5c892ed9878ea7713cefc58b7a616d7b286","priv":"7e54e61877b8413d06251167b239c1a6213ed23e79c1ec8da7408e23928d47a7","pub":"03d25f230b5d12ba142046fa80c23e51198987254bf7f7f8a009b712783d9311aa","addr":"173f71a2ef94e964185c474eb310a363241c4621"},{"mnemonic":"audit energy setup mimic dilemma amateur evoke tornado machine artefact shed artwork","master":"40bd9cc381e632be6f25b822bb13bc7cb5c9697b09d7ec725aa21e13cd3eeff3","seed":"721de71ee0b84620bff8de317edf7c4ddadcc2dfbf19f3cbbbf61bf26157fa07c46119cd2f8387d67fb0cfbb98f62a3e711053a308496a0ccddb944ce517d90b","priv":"825587d79a33405a3c7cbb8a25e89cf1b3975de3763e1928e02c3f4d0cc8d44e","pub":"036ea297692c5bbd85ac06ca8ca238bad6db83d1acdd02fc012325a1369df4447d","addr":"5e45e1683f7c34754771340ecd629014297b72ba"},{"mnemonic":"vast noodle pumpkin sugar time iron screen begin among orphan glimpse deal","master":"cdd2cba6ca23c96a7967d3f3f5739009f2fca93bda0a36b85bf7a1cbe0d8af8b","seed":"6288319e4e2c7471be7088e9b50db78741c1da423892da1bfa289bbc62d4a014a6d9b7cce396cc3471531342a61d92345a3b043224dd271ba46cd716a0952af4","priv":"1a746edca60363f3bb4118e316ac549be3161be28c4151c9fb9cd63728abede8","pub":"03cfc321906acb176564624dbf1855f00188f563b14f07075b1d5c7e4dc25b4419","addr":"5007b4c128af77e8dfcdd85a925044438def1159"},{"mnemonic":"evidence element stereo crunch romance trigger ten ceiling cigar wire first frame","master":"9aa2f09eb1b6094ab52e39873444f04cc682e60305e9fd4f485af27d7c6e85b8","seed":"9adc22bf0cd328df0f54c6da7f5e43e9abb4e9a607aa02c312de24c12d9a18f38945da0188834e149aaa5798c8594fbaa9109d47363deb53e17553f2edfcdd2c","priv":"281e729635633787eb40b08d43d806a5e2ce178abe659b37c91c6c073e720448","pub":"039e0c68668af7289a7ab4c7f9b24347f10d38eca095e991207cd9ee55bf61f0b3","addr":"49b25bd31b9fed1ca7e2c32d663bd414d6c3705c"},{"mnemonic":"labor capable alpha robust suit trial media bottom pig hundred verb hotel","master":"b3e4d6c6bd059bc9548d33f6ce0aa6674160ce38bb231fe354950aab11651403","seed":"e1470e44481471f4c947976fdd4fc9119619571cbcc90d0d419f4a8c4e1102f84246da2c2fd0c02bccb34a23708cb6bfc25b23972c03fb6a70f5018ecc5dd2dd","priv":"9a9501487f7f9844ba521b3ef949b12b30046e927bbd8054c831434a4309131f","pub":"02b25d30e144102b7500d57f3c501093f4dc8708afa3ee2c9d772d5672802bb9fc","addr":"49bc8135a631475412f0b4bb0db7d437ef226243"},{"mnemonic":"resource pencil other subway knee small shield excite forget such annual opera","master":"955fe71377d76742d6bd94d49457e6cb768e57517ed010648edc058f65d6ccd5","seed":"28a7a3080633dd2485cd88b9c1ffe92889eda9d33be7fab5b8aae3448170282decf20587d613cf06f0d3a7da6acaeaf5c9918616b4d22f8f23bb6a17c67bbde8","priv":"ddc57bfd0d27c98a1d088272ab481407ba95f8556f5603245466f4f2d83c3168","pub":"03065ce8033103d6fb42bb382a59053797beb33214c9d16f2b4ec3634cddf857c3","addr":"b0ca9d5f91fa03b1350a40e4ffa84e99167e4115"},{"mnemonic":"dinner tone antique away vivid lesson frame floor rent field monkey race","master":"21cde220eeac2883dbddcc6927f73423af840e675eca3a6cc82bde4a5cfdfa39","seed":"16c220be97967c5fa8ff2176a9e0d748e0aad37c8ad32e590c5a35ba08247e2176369a3561c5eb0cc4ebc9a3d65bd132e31c2640968eea822ae76c6c34d17373","priv":"13366b2855dee63a394c4ba89378a35b75ee07853c78765dd1c5c8927e52d4a6","pub":"03cea336f71a793319bbb298bb3c546046e69b6abdec405302739345047cde8355","addr":"251a5f4b01da75091e938d782ab116e0e4ac37e0"},{"mnemonic":"peanut potato artist define merry brass nose brief dinosaur planet year blame","master":"87c46a1f19cc7d1e59887f445dab57aa835bf116db621e9df97c5f3090517e7a","seed":"f8b6aa2a59e9384933e0a88c76c5fa889ad82238ee7173a41a57638bbc82e51e7d89c97bf3cd2f6031e65edbeafdcad5760cc6d37a527eb0372b03281e7806ad","priv":"a7e43f8b98838fcc06ba6257cc64086fd1b6d0eef12eddf9910181bc6c0ff204","pub":"02db3f433577482b62d057404b61d9d10f25df66b0742c2a3471d2e80380355cda","addr":"571a2abcef5e4f690174e2d81d9ca035742e17af"},{"mnemonic":"orbit have attract dove horn liquid social maximum penalty slight mind mountain","master":"5da625838972cb1684ff4e45326b14bc1d73164f82527934fdf8b7a03b9891c2","seed":"abd2d4cdfc5b8330f58b7757efd4fece7854e461e22c71be5aadd735c144a954594fd8da84df6b8db3ea14c5db03a6952f093346ae94b6495a8635e72e4a38a1","priv":"cfb3afed34d7e53d459cad8623401f0d6071d77f70a96c75baa511179ca59cb3","pub":"02e9e07cdc8d57e321593919431bbb6c0761910d00e4a242ecd85d0b99e9ad3f36","addr":"78099b6cef2d14ad8f3ba7db73bdc9538e382464"},{"mnemonic":"squirrel motion glue best prevent fault goose evolve shoot decrease panic very","master":"2fc7364fc6537a38839ddc9dd41e0e58b2e972072e92ab8ec9fda67360f2a042","seed":"78718bcb53ba532316fc641cbe2027fdf4ea649563b36ae94a95415b5923397585b4d10b1026cfc8a00069cdc02c7ea8c1ebe04364bd68066195c748331104b4","priv":"7d9073ba21f72f91ca39d1f13c05108dc75b56d3b09bd08b7b8843137fba91b2","pub":"027827c957ea1c98f76a076bcb75ab8faf534dbed44beb234ebe9f60086fcee393","addr":"10440fcf67f5b2b6f4e81a0b6fe267941b437811"},{"mnemonic":"pudding tooth market kiss exhaust donor tattoo olympic uncle child bean nominee","master":"34f62b6ae3c01c03d64e0041bd50a9cf7027fbbc0b0fa7d13d08908422f72520","seed":"4f02768404f6da2b7654bef1e4d35a42386bcdbf167d09212194e20a93070030eb0a471945248a36a8d062e80130008cc16a001ecc3c05a27db0aab0f04c6411","priv":"1601556ec13ac16d4b38ee73080065756ef276473e7649c713ea1ce69367c087","pub":"03382cbb99d17b144dec0eaacaa33d1cd2041bd30cb658fb97ef2654e24addbaa4","addr":"e2bdf4c0101d49df4d8aa0782c4a1fc354fdbfaa"},{"mnemonic":"earn shock finish ritual segment post then note dizzy diesel jelly horn","master":"309b4a016a064d4bbbbc220c0fb0727114b0b83b600db73aeb4347a04ce52873","seed":"bee7d3de1274abc8fc05afc839de0b14166b86f1ea0a1f2a6b6484f40654aaa7cc4574a14996812974b905da6eed437576eb7f8fea704afdaca3b146b761f0b8","priv":"a269a409951e783c280a5d8afb0bc232f303618b4d83328ee1196cf86f2d8f04","pub":"03b79d6727f3d6a0c289f2efac4938caa94ee57a36a3ac70e3f8e5f85f7e4f52e3","addr":"8ed4fb10d7b8d66f4244e83d7e6cc89fc75460e3"},{"mnemonic":"venture bitter tongue learn whip palm race pioneer satoshi wait hub genre","master":"e01f7f5ad0a782b56a034b68230df72cc8440f6e4cad89ea0bb9b81a71b430bc","seed":"b6da5129dcad44188c654c9c50ea640543b66c0c98edb29099770eb6d89ff197f5e9fbb7725ada5b3b0191a9cea89ebd8f35698d5ffadcf3ec43f6b92795c1c3","priv":"e3ca3c8028c514ecacde54c73338ef5fc78e0ab05ed8260d4a70553c68390bfd","pub":"03913989f1771a015b6594b60de23017fb31b96a740507873cee53770684fdd5a6","addr":"db8e914a36120702031b4498a27d6bcb8c64da8b"},{"mnemonic":"opera wear actual virus pause topple leave video garden guard obey item","master":"8fa7f1c161b47e625e351c775c662eef0d5cf9d9c229a780ce0adee5fb045ccf","seed":"be4f43f613da6e02ae174310181afc71462ec108601eab58d369f452c4133d14bcbdd05462676d872b7aabae01e7e6e22ad38261ce70a2f107ff9f42ace4411e","priv":"506a98b80534c824f67233bd1840ea968886a57ab500fc0521da20fa4f24fce5","pub":"030a5a585b4db663ea11944e5be0bbb630b6b1f436989c8e7128784f7f59676370","addr":"5ad5c8981762b720bf74b376205f69a91c6f3cfb"},{"mnemonic":"captain tray course secret betray bag disagree boring umbrella liquid door memory","master":"b7974cd18de7e9e6abe2280e567fc51efaf3e80986c98901ae2ab7378eefa08c","seed":"3a3c2b0e7b237e37e7c92c12960ae5b8856a8a5795386d243c6d9eb7dae1b98170489c47b197a794e8f9ed0c323bbd722ca052f76d3cf1ac04db5f7ef6bf5b26","priv":"a13d741052c66e487ee376cd392096d9e56db28d64001cdd807427678b765016","pub":"02fac937135a8b0593c50d06a7b113c372d8c9d02a338673e3e07f267725536417","addr":"e5d9166b331f86253444f3198f707a495055b768"},{"mnemonic":"dizzy guard goddess trouble absorb pupil stove mirror nose couch diamond must","master":"d3bdf420266d0c5824a621cd631ba014a8ea614b85c628cf64bc3a77cd3be3da","seed":"485d06d18708ced0c344c4025d93cc194f7c63e2aaa1d19970a96db8dbd7e2f802d39d319338b0a92faffc2af408f69f1522481fbefdcbd3842ede957c663b0a","priv":"abebb4b15d2d9e3a3dac2afd4423d5da2b2260da49bc45d44d014e8d740ba064","pub":"02e39342b82a9b4bd73b165ea9b309e20b0cf9c8d5ee93756cf82ebad0b00e0cda","addr":"19f6fda807d1a0f99fb730923277d4f36601e2d5"},{"mnemonic":"rescue drink absorb brief unhappy rocket subject receive green echo marriage cactus","master":"a6ce8546f2cb2a62c573b3bb5b1e7437f70a44b7cddd7171a41d2c4c3dccd641","seed":"0605b45920c5894d2d351c091c7c31af1b6f0d77576f73716ac96dd7a22dddbf42155aa19bbc3c2cef3c757ff25c3e7998d0ca536b696a498c9a206bc53e8ee0","priv":"00a6e55ef1853ba31f2b7e76acc7e04649a1a2037a9bc33c74cf82261e956ceb","pub":"03de1a877576f6e77bc06a53e7b2c56afe7b58c460341b74c469e344d2b87f2e62","addr":"a4014c9bd6c662a6d4b20cbfc0524e125a5963a2"},{"mnemonic":"destroy naive mother audit tackle coral crater sponsor viable clump bomb bargain","master":"c0cc3cb63a702200dd06ba3355314b332385c3a0e1ba73bf428243278825a6e5","seed":"fdb9a430d0fce5ee93e6b0ec23506f65e76cae8be1f773605af71687d2f9fc14a9a1bbbb769a5c38f654398024159b48de392cc4a88e29030f4b7699a3ed6824","priv":"8b73cf6e42c216a7978f63a28abf839d0e2174cb10ac2abef6870c9a8b938462","pub":"033257c04174083656be1bee39ddf01b34aaceb538ee86c7df35a9ea4b3a3c282e","addr":"5ced7fca93a8e097cf58cffaf7c89141cc00697c"},{"mnemonic":"paddle image cash sadness barely sport employ slab keen riot solution switch","master":"be10364b52d5cdc0b8eb51215301e8468c82498f0d7b2de44013d382c0441e80","seed":"138194b9dbb5c35fc66755736c385e12ea8783c3208d85c58bc140a5edbbd709779d4b42a2c56b94d82b5edbb9de212f2eb315edeb20a5725f3c24a39ca50f51","priv":"06b0b15085f8af9cb90eb081a7b73d4f8b781467926c2dae68a0d300f2d62a71","pub":"0286afa72dc5ce3416e8996392d0cbd63a0f9b9d60701561d3596a1c9d5fa18499","addr":"bbda492cb736571a6bd62d8f5d8836b0e0c761c9"},{"mnemonic":"gossip choice orbit insane honey hobby split exchange uncle wash tower lyrics","master":"7b39b437bb8d0b66c3989df6debf35846dac9fb69d2f570c4738afe92a57d708","seed":"d0897a14b1958fa31a898e38fc95b6dbb2a9a5019175bf8e503149f9d1ee4958edce3f1f570c3e015b797b475f5eee882ce54f68c7f64e310571e0fc6296da62","priv":"816f5cd94acd51821291561d6aa30951d89221027418ca697aa2b621f733b2ac","pub":"03d4081dc8446919e4a949c323b4c8d6b76282325cc7f35c18791a57200577f082","addr":"fc5a9ef94fc8de5ba7407669ce04d8190864252f"},{"mnemonic":"ceiling shed aim oven emerge year sock achieve ask melt endless lecture","master":"ff1480b11529ec8240e79bd9e35275e1805a3e117a60f9b6b22f66715b4258e7","seed":"1aa288b6bac68936d8d2a89396f5be1659a12fc91a9d7edfbb45446de8bb39327044b6ed7451e820317882f162560fcbb134449e85d517a7f0eace2da2cec272","priv":"216833b820c607646ae504dfa7fe28b364741509047b89eeff48545fee07c11f","pub":"03b3c3ce98ff9d2340849c220a5127d8ebe2bfd320c9db41e94f57b4e067eccf0c","addr":"78e3043b376112452a22ce49f6647a0b1d20180d"},{"mnemonic":"deer defy door jungle sauce summer sea globe crane abstract minimum diet","master":"f7440871bbff95cea261708c1cd06220a5aadae4a86c00f53b6f510a50e8ad56","seed":"a1868d8a30b498e1d397838821bf762c5f448d3d8fb68bf12cb0e2e26cc69f95be698efb101e76ad6ab84447c0c2b2170fb2b201315f5e5023bed35490f43986","priv":"b64d5f61a5503b366e7296a5b060e42d5db420e4bb8c4d0248c07ac25d2a0b60","pub":"02f4e32b1b8f2ed1b75ea26def62a6e69c7cce521788bdc182663ccabe4c1da4e1","addr":"32a90701856a1d942f58f41f6cbad21a64494658"},{"mnemonic":"position course virtual distance fashion oval slice round rely key spawn shy","master":"255409af8fb802395b9433c062310fda250cf8f9df7d79bd16381a7ec7b4d27d","seed":"1dcf6512b003b07fc299098ad2b8d4ab3eb1be11cb8949636ff2dd0baa0081ba78a9fc117ac65666c0854387ce0adbb903b482b85a20b9e591f0ff156a59d30c","priv":"a9157f3dc6ce3889c4d8dd4d2434f0e080090e4a0c0c75cf58bc03b41ea507a8","pub":"021b68e6fc74dbc45d326f9d2c7efe9c718e7c3c1a084e92c1f384c273b2d41513","addr":"21101638d066b561f8c43f6e9061f3959e3f89ef"},{"mnemonic":"model absorb cart athlete helmet next hen indoor involve ladder engine tone","master":"4221074ff1f662276f167017a5d43611b1d6e666c0c5592a35c81d2f5389c93f","seed":"dc9672d8e648fb4da6a5de519d08fb677c0d583a988701f2ac57e1fff273c3c832d31c036fa36d33b029fe0e92e8bbae350c6b96eaec463588f1ee04209add53","priv":"c4662a26101f0dd36e56ab0528a3861547015022b9e8a30ffde845d6207ae8c8","pub":"0285c5ad35fd9063e8cea4d034628244e790261977eb0225d4da90c5a2d11ac25c","addr":"8fc4bfc728a5e5fe2423b8c380aed1f2fcf4d2c4"},{"mnemonic":"armor happy become inner fossil exhaust upon under offer sheriff coach huge","master":"154c74bbf5601f7fd35c183e77ba32c03eadb2fea62563d2221199cc694a5fe2","seed":"db7910b6fb6f406f146f857b5c116033356cda61099165a7b1f782b2201878f9a4104efa15c2bad266db1802f9d15719fdb9953eaf3e245f0aaf9f5b0ff8d296","priv":"ee1d3af46fafe868bc1a89394c068dfe05cfcf7578c10bd57750511276e829db","pub":"03db053e44816be4562be9df13d8ee1853c1336aff0d13cc516b0681521d96a9af","addr":"fa65a0099684906c758eecf10f7a2b6dda7c5767"},{"mnemonic":"long output ketchup question hurt drama bamboo globe manual chest luxury abuse","master":"b180100cbc124ed4a9812ab4ff3c632bd7df77209598d4b26af9d31fdb8bbc28","seed":"61b7b436746323085cda66fb4c0e21079e849bc4d2bcc67cbcfacc97008abeb7ee57c2ce751e5c63fdb676f0cfec68442277d4a0e5db1ecf82236bb2f2c9380c","priv":"1ed983d1024d453e2dfbed2278c3c8ea3abda96836db2462da4738f20ba1d772","pub":"02f9d9ceb9a27e4626d09331f645d40464c99975ab0b7344be3f6cece6cc0de8c9","addr":"d092b8b49065f0698b483e416f4b1b032b416dab"},{"mnemonic":"ecology over output enact system curious want oil denial ivory hamster approve","master":"f304cd809c371db0fc37fca212810e75134773494e5c1d20cd22753399ee6433","seed":"6693bbddb7e758825bc3c2096108aecca0414cd1b523460a14c8dd80c15b27f5f37cf4589e710a39fe663392874a6b17892fbf473da8d00d86af17aa19ab0cb4","priv":"8b13913b6f590abf399aafa87fec44961218fe45ece0f9ee8b22810839c46e5a","pub":"034738f122cf61a102148156d40aeb129bc4c54fc55c5b85462917f4013d7e3024","addr":"1657b328a5f1ddef43968178fd8034c685e9e312"},{"mnemonic":"uncover climb join country march border rack ridge track true master useful","master":"b1f2471d8e6e712e20343f06220f847caef645d9cd9972ed17684b3a44b25de9","seed":"431e56eae671e0f1ae12aeba623fd4ed4c7d3ed102588d3b39b3c0e20c104aa24a435b9ca504799214f95b7639e208dfae17fd866b2f58c0d916cd744b7e5424","priv":"1b0e22bfd60db8880827761411390dec4799efba98348052400deec1838b04d4","pub":"03c6d27aa4dae3b3e5754cb3bf8c4638576f113876cea4da0d915964cdff0cf7c8","addr":"0056ae65805ceceb8c17c3c1246c5f70dde2be6c"},{"mnemonic":"rally cool artwork leopard skate battle shine text ritual rookie sun way","master":"72c5b3c5022b033d71c7abea54feea3d3b37dbeadeea5db4c8847a7cd0e20d3e","seed":"d7fdcb354a8946fc3449107361e4bb3bfc569c0d3617b450484e5a7fcfd5c690cde3a511415e08be23672789d090a3c679a06be36a2a20204172e1d61433268b","priv":"dd57130e658e43c9adde730ca57aa6d43d31efc3697a752075a7cb491a7ff390","pub":"03b7cd7259877064b403af9a65ebce47f210141356a67efee77ce456d46d948db3","addr":"a8db1e5ce299462e4943d0eb05c146591fcc3297"},{"mnemonic":"room vapor anchor forum stage corn credit jelly level cat detail auction","master":"fd531ed5d65637f6031aa02ce031cdb366bc8a07b00fce1104675d1a653e7995","seed":"f42ae529e339d9b204165f2b5556c1637395d9598cf5a59717d048d7d5abf831e60abdd457f3432ed2ced4c13a5a73625f716f235d51bd7892cc16c294925cd4","priv":"c2342924a2792e7c4bb8523045faaac7a669fdd00b2621bd38077f58a32bb0f6","pub":"02df2b027f4597da0a2e8f46932929044dbefbcd5c5ee38c2147dc1ea061dbcf8c","addr":"642b32cbc358915bcb802eb30690951710f597bb"},{"mnemonic":"have offer number egg canvas uphold memory snow know orchard cause wife","master":"8ff4d3e7e6ff972e24682d1f1116c7b83bb94ca8cffed1db9ddb4adf89e2bcb1","seed":"14cc60691b49b9036c0bb64ed24da69478e01deb36184f58049d694ccaabc41d95b1e6734d9d06e7009c394d54d80fbd65cde6ea49165879dc306c0125b44681","priv":"c57093fcc3c593fec4002a9040d90485016346a9f4f7d896a105ac268face5ae","pub":"0252fef0dc82142ec121c4b01275b254d6a78b4600f417dd0f09639fd94a23c0af","addr":"af5cea50c72de4e54216fdcb9334a5f5a8a0393a"},{"mnemonic":"garden nature witness stable over move among pledge woman cotton worry behind","master":"48d57d0dc1abbb7142aad3371d68c41ebf078970c5fdd4bfd7294fb6f8d32b45","seed":"bdca43aa42eb2a34dccfa4fd48202cdc386454683850a12e7eb7eaf9998ebcf57a01a6fb1a6b9cd8aaf2910b160038fa6adb42daaa914c7628e27f912687e52a","priv":"63dfb6b77a4286875868db4877a3d0f3f0ae8c2766b9c5d9225f48071421d832","pub":"031e57ffbf90b85823505710bfe5be2200f1d880171e8480494b50a04462b98795","addr":"a7619c6704a7341472229bb7ace1709b88ddf175"},{"mnemonic":"pizza sting refuse olive final hungry kiss abuse nature junior opera tired","master":"397240e78b72dea36dd17ea2ef3a15f18f8fe64c9e31a30687d2fb013e1ac6ab","seed":"1dfb236c6bbfdaa74b02300a0da7b2d57a2fc2f736a5144186cc89b6f20a23d74ae59338fc04367a27e976e41f1d1bfd4232a3f386cbf74220c9d0c6fc5c7077","priv":"ae5a8c5bfb71adfb89055f61e82a6ef5258f6bae9056313c360ea454bc30c052","pub":"02756acc7cd398fda3d485f6aaa15e7e4e558be8725d9766119e570b2b64486372","addr":"c4c6e359acc30099a524b67223da51dfb6557de3"},{"mnemonic":"deer easily marine thrive author despair puzzle super agent life rebuild soup","master":"7efbef221b4d50acacbd20a10c1197727e9fbef29bf2418f51141fb8a5368618","seed":"2ad829ff702c19a138945f61d1449c32d6b16ebdfa34350dd434bca3899b6eec3f66a3dc8de7243539f7d6d07f85689a66b0e9f6481a4767a5630c2c693c3ec5","priv":"b6321fb4900455eb1986073f5f705d088e795d26ec53c09b6eedadf439fdcb6d","pub":"02e9c7d430122627396412df161a58813327f436bdaba34f3e855263044e1fcc77","addr":"47f0fa963518339112a65e54948c5df8c23daa72"},{"mnemonic":"gate calm appear symbol make can alone wonder cherry couch loan firm","master":"9a727a9574790f29c890079fc9e83b0bfeab84d9e79ae6b273ea8266f4a754e8","seed":"f37c4b52afedefc86a24bf4edadf6a2f151aa9d503fdb3da440d53134fb040f7ed60c29407e4b74a0714f5fde8d650b93d71da52568d0e9b2056412092125c76","priv":"41e13797f2f7c41a44db247f9da73e8d7893c2be4a689fe558145f2bbb88feec","pub":"0242c6981834d9c7a14b96c39c6f902ab0a076e4a7ed29fd7ea559aeba3727da4c","addr":"dad747d0295dfdf151b6267e701f8d889770b4ca"},{"mnemonic":"opinion spare hurt three insane sick place sphere ugly sad mobile icon","master":"e6b6704a86504c2552e7db9928c6333372fa5630983e5a9aff32b0ecf56c8fc8","seed":"bbf2fa3760c82ac61467265053828c9cac4bdfd8aa43ff860ce50a094bdc448468fc6d0e6c53368e42b95aabe4f0098f9af46018595badb4f8cbac787d5c00a5","priv":"496c6fc85e550d78a931b51e6807dbfe843599401dae033db98e308430939d34","pub":"037ed7cca0717526969db9101c62cfa151cf97544ae66408317fd798d705a30138","addr":"a1fc3fc66094cabe3f7edf5b630003a524bdcff7"},{"mnemonic":"include relax onion depend animal stock essence basket local result rocket panic","master":"5830b22230ba22060e22bc4ee3323c8b1e02e5f53caeaf90759f4e846720b3e2","seed":"8fc74e989ab5b4ae04472887a59bf89b501e1813e687cd27a06bbef858c9a63b35531864b177d27841abe4999a7b1901d95303a395f5614a176667abe8aefab4","priv":"99a7444212b0176324718171a318f74fa5721fa46ed18b3677934408b30218b2","pub":"0213e7320395ca9eae0bd4f550f7f5f65a801066c12d95c3f9b443556011b13944","addr":"a4087ec7d05b08362bab9c8fd9406ab3bd88354c"},{"mnemonic":"cushion hover joke lottery gym muscle drop scare purpose share food strike","master":"dcc4792ae42c425fe278db48211f6bf54551f9dc58268282a5a61cd620832d4b","seed":"0bb05d59704318da60a1697d09562a05e4133fbb8f5a4750f378f65a5f0d6b9c0fc668dfe08673d6b10bfc4557250759c9f70aff9df1a5418821756f4017dcd4","priv":"741dcf7d371948cb17723b1b58759d8a0520a341a29d581abd12274014e945cf","pub":"022dd390a8c2d4a826ba8e725f54f5ba65438c97519537701001bd7a68eaef91ff","addr":"931f12464c90ac2bb3b25fc00f13c56ba1c49679"},{"mnemonic":"point action veteran fragile outdoor vote timber cattle cube deer fade razor","master":"ed95f0d3557ecabcc04fa2160560dde68517d4fe7ebf88584d0993a1a861c6ed","seed":"886bd48b9c9e337480538f1119148ac4f0a8d00cc3ba17a34cd7076bfbe85ba2a1a8f410ca44f210d9cbf6751c10bf15b6f52a725979e613f4294813bdf173b8","priv":"c489a82eeab534dac53396b71dfcccdd6880bd441b89386baf9700589d92f169","pub":"03e2e7deb2c03412bb42d4b32cae6591e4e0db745681900436999ee51ef422cd35","addr":"f9f93bbebed5d2859f83fefb58bbfa5f93032837"},{"mnemonic":"ozone pulse whisper cry ordinary benefit enrich cry name bargain muffin case","master":"ddea83ac1fba7d6c79dd073d29c913a767315bbae6c3648617b7fee73a04595f","seed":"ee93e7ea1bfe194ffdf6b0f70c2d5b5759c223620c01647fabdd1e2a94575a61b211b301cd6d4e979761febf15336c9bd1301406e338c9f6c0b8b938863c1cb8","priv":"d344fa49eee22f5cabe1362f36a026bba1b0419c126da13c6cf335759a962d36","pub":"028bb9fefe8418dbf0fca6857526f286d9db3321d12c6a88ffe8e2bab7004b4a29","addr":"b9bbd7d328f0947669fd1c81cf8a842a721206c6"},{"mnemonic":"huge afraid venue bid visit decade hurry put swarm couch gadget book","master":"8755848478c71a1c3345cc855a10962382a6c27e6c639c4a4ed245bf32bbb2d8","seed":"b04392d13e629b759aec3c28ac4cd7eb0b7b846f1e241eb79f862d6c30e79f3a5cf5ed26abcad0dce95ed6d639e8088c169e49bc20df609b5555b0bc3f3e5e6f","priv":"f3ab0ed871c3feb01ee18fd374568aa378651815b6903a2b42eb43dd70edb9d3","pub":"022d2a9a829f992b3d16f9374b6a6946649630bf553c8eb11208a68acd03ec3c7e","addr":"c61f53c2b19de0ef11583048fd19404473065bdf"},{"mnemonic":"update ring situate blade term enough evoke balance absorb pupil wealth era","master":"fc22f89a860ffe871a7a45557fda9f38369f99103e02a2a97066517190d10e0e","seed":"d18f179ae9c4767501a8238182d3fef3f24fa3259d41a07b601179f67fdebb6b47a78ddbb056170c0bddd3e5f5a884a3d4046964c0f4ffbf7b37c3e6debeddbb","priv":"32a6d9270cc30fb5bb11411313af52a3359249c1b5b38b753a83ebf516a1d21c","pub":"03a579f47d1d57202e02e7f445d68d6915a3304b256cc37c5d474e699405deb613","addr":"8501c773ed9240be9fb0f83ac2af1bda6511b1ad"},{"mnemonic":"horn coconut protect box cargo switch ghost among energy easy deposit fly","master":"df4a2a6d35731478a3dfdc0e1595486bcc245f83214a974b31bc20e2c0e637c8","seed":"454ec603e16c8c5c522192885768d941316f0736929046aacda1a93ad1a658e70c21a7e924974583d63567acf26ac15725b1148a75522c6bb26b37d9f92fec22","priv":"447e4c3e530ee519973a63c6ddc63b9e5a474761eae12e8c1fdc6d0cea806604","pub":"0359c72dce4c6c9edd2774af06545c8996e4832ae35cde19fab2f7dde55316de1d","addr":"5a49f88b1672cd9102caa80ce55454030cdaafd7"},{"mnemonic":"price envelope myself under helmet dove uncle below extend gadget limit mammal","master":"abe0fdd5148a6b93ff8b281d084e4bc92277848c964e3698a48e5d50d6503d54","seed":"f8c27b37871dd5aea7f7bf5fef1c561beae9d029b3fd937a961ad39fd09100993efe7b84699f7abadd49b81d16382e0677563d28daeeb08eecbdaed50b27eed2","priv":"8ac79807c2a1bac4cedddb4768fe92b7a51e0cdab5cb79758f5876511a9b09e1","pub":"023277dccb7b0e017b461bf483c2d3a63273e83f3acc4688733776ee3ac0f649ef","addr":"0ad65e63beb8258df8ab0f17ce28afe3bf19a96d"},{"mnemonic":"toy grain guide crisp error then group clock coin civil space paddle","master":"7c02340aafc6a15a7c6accc312960631cb3a92c4a7c6d98c43897a1c4c55e59d","seed":"a08642010ea9779615e7a55b973f014ae8bd492630f9fc134159501e53a12d402842899978c75f553cc78c061b59210ecdb20648a1187ea55d85b7ef1b206c6a","priv":"83ab8e2ebe208b1f32ece9530ddf03e0727d3313903ef13b2d09a3952dded8fc","pub":"028582791e93e6e6b4270353aac091a58922c0067fa440a645dbb4673858e9bf81","addr":"4f37f8c3b16183c245ff4a101bc290c3ea9eafa2"},{"mnemonic":"atom border bubble lift day soft rich rely gather ensure that arrive","master":"e6936ec3f9876ca2c44973ee13fc02a08739655b71a9880b0c7959f9c5c12286","seed":"00fcb87f619a1033adf5c9311bced58ebd5fe56a70b69f65b61228732337ac46cefc48b1e53ed5a6b0ef658b002fc162ce686529120a486230f3845250ca7f70","priv":"4e527b2fbf28914ffc78f84031c462f3b33ad8d2b62357ac816bc4c06c0767d4","pub":"02b77c89d89bc757872025a0933d39ee65f5ae037031359cc1e692dcda3a290c90","addr":"8c8ed73961a3055cbaf4ca0b5ab0b0f56bfbc32f"},{"mnemonic":"require panda tackle valid tenant treat boss oppose where thunder zone rude","master":"fa9c61113d7c7ad38850ebccbdc2301c451ad272d86a7b6ac7b384c4560fbba8","seed":"936d1b0d443630cdbe8c98731761ce80f980728cdb122b95753ca3549670dda6663bd93d03a5cf601edbeb0b835ba3e152f940706aab856682b9de0a772e219b","priv":"9ca97c10d757f03eec5165df506d1809850b1d8f9369a89b0bb118d1ddff91cf","pub":"0368a22ead8cf1ca5b0bd3b6b4a680d47de8342b47d7205f4ed41e85299d2f9260","addr":"f03eaec270d04d368df8a3a5408b9c010f283b8e"},{"mnemonic":"thing gorilla large fog mutual hair gorilla soft venue ahead neck remain","master":"4b3929a08e30aed05400a3a7fcb91fafa085de08402ab546258c10346a21c14b","seed":"af471c7488c0046d2eb29429369a14b2b3bd6de6e89036285dcc9a121389323bdedfd7072ef9bccfc1ea472bf8a9d3f938bce5ff58b303f9c0b24dfe8185d917","priv":"13d5e5fc0f6c184e4dad19c4537603b811186a3a5aaaf272762ee236bc826367","pub":"02ecb5330e932bc89bfaaa8682e044f6a1c64823887aab000b2409b467fa94da4d","addr":"c6d1e41d9fc95706c276d85b5d93d657d59c045b"},{"mnemonic":"ketchup blade myth tackle neck gossip obtain write script grace mountain glass","master":"3d2d55b2b706361eab66a2724609c1ae6e7bde50f3ca78dfa72be5e784798ac4","seed":"ca3ff2b26ce97cdf280654a05e388ba2ce5ff909e3bf253b35c66c4b9f8d630a81c6367537039ad09d05ad7fca337c479db1b34544c26331c5fb860eef84f953","priv":"968bf9c285110ba33def9cfc3f47c82ff8050b854568cee2ac509191885c4c7f","pub":"02d8719b0bf9e5296ff70bd88c8eea612b5161e80be5315a9cbd4ba84eff6dc788","addr":"868855cc81bfbc80fccbe3f1fd2d526db7cfe298"},{"mnemonic":"violin toy phrase advance banana timber viable half nuclear friend bundle injury","master":"494774c8eec7a45b2e54e69d4ca64766ada0b90ab1d2f6913690b7b43f489b52","seed":"d11d7a22d020dd5e4ce9a9c162637f47223a4162d5b1920d7ac83d99d73c40ee6b67fad2c534f8100d2529afbdaedf7d2a8cae2e921e8c6e02e3bb8d7417205c","priv":"57827aa1804ff699ea31602eca3ecdef41b722bc2d321187b48c5780962c0f73","pub":"037fd67f44683a2613f7b049a87f47cdc7710d0a834658091675497600d07b485b","addr":"6b13a26e1a545c77cedafc8592e55363742b55fa"},{"mnemonic":"forest unfold spy harsh pitch alter bottom album renew siren find bomb","master":"f19401a9aea13a1daaec39107b9b860d4159b8c66118bf13bca736937eed4e61","seed":"606f8fd5651b2b7cd9e5d9974ca44c8dbee170e6c60ca3d7a4764bd2a1a31ba79b60d0c32b40f2998a3fbe784edc40f93a917f726d2d0a3a07a3871358bc4f7e","priv":"40bee09d892253ebaaa28579840239123740d952da7bb782e66410998405c2f4","pub":"0310455b5a6e7c5d4d09a3ea71e2dc7aac95e8457e6db3bcd605010e6e8f96fa7b","addr":"5d40749e1f1e8aaf38b91c12907f561668f3c691"},{"mnemonic":"goddess isolate speak arrange tumble ivory give message palm wrist slide drill","master":"424c0dd576d73827d765d558616a5c5abc92ff548c82cd6e5a277a5a316e0245","seed":"36d58066ea3378f1851c1e762f36697248c2799dd98b19d74e69aee16e497e4014244f62f696f34dbca202f78f7b6e21585f91531bfb8c3576f910eaaa64b524","priv":"f0c0691851dc50e5ec0897cb29a8e05032b7d02afd774aad6904ff44088f2850","pub":"031bd47b8bd9a56d24874a1df5c15834ccd5bf553e7858e2cc1df2c045966d5ea6","addr":"eb4f13a437254adfcf46d5cf7fafd4b2a059a99b"},{"mnemonic":"penalty trigger panel ring menu toy behind forget tunnel various giant melody","master":"770d401afbd35db8afb7a1864b794ea5a59f2c65127457d4675128b039638e73","seed":"81256b9fb40b02feaf3228eb300d1b002f9a8c0ef03a2b0db187b265b09baa4fa28ae7992c1ffa893381e572331a5016e6fddcf3871d1d836e92ba94a44d92ab","priv":"380085bbd1a2e2f50eedff2c758fb63f981adfe46a25db54ce7f1d7a68b6b7a5","pub":"0367f233e57390fb166e45ad792a054ba908fdbebf11c20a3c199ddb134244b7d9","addr":"ca1e2a50753d833d16c10ac03551839734b5e3c7"},{"mnemonic":"usage real inform betray ridge call coin warm meadow gossip river predict","master":"8aa38fef2d5a72f6e97cc57244f0baf53b976ab7263373dceef0b46ea52651e7","seed":"9b806b194b9afe0f5f46b4b40c4658198445b53462b6aafb2b1e82e1c98fd29731d193681ee43f3d9d70547a5f512344809e02d15ae441916725da5e63cb3791","priv":"10835079af496655bc2dd80c40c0b10f18788fbb9350a7c3f2abfa3e00ccbb2d","pub":"02a3077b5796d8cab9a90186be1c1456d75b3076760f2720225bf4f38eae7c0e1b","addr":"f7deda6ddbba1cb091c8091d2e43c01408fe0d8a"},{"mnemonic":"mechanic share spawn limit panda quiz glance dinosaur gold skill initial replace","master":"0a84289f0c2aad1de0e750a0312a2a362f99b8f0c7a15b1e11dadab1df18593d","seed":"c45a8faf2b5af3ddf883837378d03bf6566c6369005df0c7995ecc9718e2e1482fd42d3411b58bb4a94a637c41f310a8faa0209117031ffe993c0f04b2878935","priv":"10bb410b31a37b51b19165dba5171d33e826e06f83b8c590a23b9b2c8bf11b45","pub":"0331188abce7c6fc99ddee0d7335e872b7cb2f48a7ba7dcbd9ef093c30fa16a5a6","addr":"d3bd3dd9d928d4bdeaeefedd058ccf7047fe82ef"},{"mnemonic":"velvet renew spread mercy volcano always snap column loyal possible ordinary sock","master":"a2fa675336bc532f8e1c253861eccca1909a195238dd202e45f2f38ff421e721","seed":"89c8378d8a7c2a2ef02bbcbd2da9e39f6ef138db1d02e32cfb492c09a132e726c69268f9743e464a8421fcc0d5a0bbdbd00dad61798736c673df81515330ac17","priv":"ed486dbbabe3def74d052685a75e65d25970d8d134724968941a6b8e94fa2352","pub":"03a06dfdfe1fcdbc8e9ae8d6c55ac974ef4075c8aa0a5783bc87f9d9c2d66fd5b2","addr":"00c4fc7760ae8f7986f35efc66d18401bd352978"},{"mnemonic":"secret weekend fatigue anxiety second ramp tribe employ quality yellow game choice","master":"0f326ef21360ac2929e4f8becc2e8320cb49970ed229f987f15b9f58ad383d96","seed":"a29c1dcb8899cd716ced74d2d81cbfbf81eb8b7ca7ae0214ba270be71e8f4a77d235a607079897f6ba6c5aef44da1005f3ba8195775a562e7d243b2428ea288d","priv":"db24d2fa242ff540009bc15ace40783c1535812bd0c79cb145187e4d648627b3","pub":"02ebf506214798f631572bf5f45321adf084d457de1425c929059bbbc328948c5f","addr":"27b810c5c8307a20b949b3945b82c0ef594bf192"},{"mnemonic":"crouch gentle hip then measure brand enroll camp vibrant lunar still action","master":"f10577e0eeb7b2385b797acad2bb4e4028bf1ae52cd59f0f53ccb6eda0727166","seed":"955eeb623726361c94806c10334bf9b1df08737c2b09fc3bca332d9f8008c5f357dc69e07251fa2cb1330c1099352e76ab445f824361533a8e30175cace06812","priv":"2e0602e9dafe830a4fe783c1b53f9c9b2f7dc0b69a52fe701f0bc6f88beac1ea","pub":"02ca1fad1e6ee189fb124863445fed2a9a923d7ec23348771d3789978d30a275c0","addr":"51cdfbd7d00e618d63a64bc662cacbc183fb2b9a"},{"mnemonic":"cluster slice enlist shift world satoshi mesh disease season ready can strong","master":"74d52d1a33a53a722c7319883ee0f47f2f76f39ff17e26b77ade53d45df83a5e","seed":"cf8c965548281a449796c37a12dfacdbf395e474b5336073985e5d7e794d80ad0ff5059a3df31381d9eade948dbbb898f4fb7ff697d2f398655573170b416329","priv":"5b8824e9f9a0cb0c0fc19f4d06921b32a76e1baf98c249dcf01c77bff2ae59af","pub":"0309e87c2c54481db5cb4f7802d2488872f07fe08dfc3a984b932246155dafb6c8","addr":"dd84fe8fef92aedb045bbf091b93c7abf4f34352"},{"mnemonic":"series element media flight next blur fox impact joke review token emerge","master":"1841af9c8f47747ac1819c178e62673e51e2957292ee608557fa38e2ece61d6c","seed":"02de6354734c96841c8fdff0806fc5a0237d621ac98acb7eabdcfc94e458bd2e7d71a9de2f5107e188e153946798775450aac5c62cc293adda42a03e0f50edb8","priv":"a118a4e3a22a82e48a4847a644c452794946169a39d8919c02f131dc177b4c8c","pub":"037b3f5d214185886313379351ac7e6ed054a7db85b9f5aab74e2bb78abb519a2f","addr":"f70fa3d5dc91e442851e6cbcc827fee336bf267d"},{"mnemonic":"engine surge protect goose warm bottom frozen menu royal fox escape sword","master":"9ed672fb3cc919f26c925be30c6dce07dc101af5baad5b6dc2264f5580819b3e","seed":"21bec398901ec8b5b4bcbae5aa2e261f96190a3e9350c03a0e23da3755a4d36ba0532ac17fb7a41266905e76f2d72e90b577e86bd6b8f7ab62a4b835292a94be","priv":"0c386e0854877e7a34bd8a9c9794f107ac2114e05130861f77353406fe9db555","pub":"03a3740fa2bf35d6248bbb7be20d6c264dc526f382f72696a6c1c28ecd2bf25944","addr":"d59ee54eca22ff7873b68b429be08245b836141d"},{"mnemonic":"dignity almost rebuild habit visit come carry deposit stone page soda room","master":"f4eedac55ceae98a3bb706c442d3ceea7caadde17ea5a2d0c81cefae9af754a0","seed":"5ec26bdfbc0d587473ceea390a99616a9c8c4a03527627983cfc9cca8f7779d1ef7c08abfa0969eab1da7c8128cfe536b6d2d5a07c99cd1afac0052e8a753d7f","priv":"4ecd8b9d596eda21b65ed39c8f53dc6ef2e19726d6eaec60da340095aaa3be91","pub":"0392dd87d441269c56e78939eaef320b6a9c0f0ddf5758e57663f9f268dffccb8b","addr":"eb71c884b8e3c1b215445ca2ab5d5b51a6bc0be5"},{"mnemonic":"input sound bacon tower fun evolve song pear various laugh code sausage","master":"b0cbb2481cc2a131867c6514b194146b937a6e46e497d6b4c329d6146433b13c","seed":"1276370b1081d2b48f45f8df73af1eddececf2076f8425fb0b593557392f3853e5298ab5a55f0e367a578932f8daf640d40d8465ffd33ab4bb6c41fc9a4ec9f4","priv":"c358f0d976f10618d3d0a600c0ae754fb2d0a2a97a385091436178ef4bfa332f","pub":"02b2e45327f09ab88143f72f6bcf5f4fdcab9101d55e015022a5f7b63bc13b1a6c","addr":"ea33c880b7f4cbb849c551f61ba630c4d9b97155"},{"mnemonic":"tool lens message country slim wide fresh front merit science argue cupboard","master":"17e462a6a8c9e854a6a7443f0f903749ab8967d8fb3a42af27ba3c2819d0c750","seed":"506cf27425374254890839b40a5a05218cb5e8d7c143523058f74d2f955c5cfdde30cf034589fb7846b9ba3194bfa9fc1eedbdf2b706b75c9b51719cf7bbc663","priv":"995d94dac98165acbec37aa586c52d9c7f0a65394027e3350338eeb69a801155","pub":"022f8ae9595f1f48654fb99985148c5c041dd4a1da396ed59cfdee3f09d7166e93","addr":"23f909e775cadd631b1b3c75df7027382b702167"},{"mnemonic":"beauty fury random thrive grab merit powder wreck affair bitter style girl","master":"2b5ebd0f07795968a7fe8ba12da106195f1fe540d417190ddaf4b11527e5f2be","seed":"c2df6f955aa168424697c97325016298ad6361c3a197ea9b446e790d0b2e877f03692a86dbba512e4afaaaa975484969c14cf0034cbc3f5571374ade85e6e714","priv":"ba6c8ef770c6258ddf7a395670a13cbf661deccc4edf5601e70bf44d1d40d63b","pub":"032f8907f58fa7592e6a8ac556f605a981b7cc80c94431e78bdd20ba086b22c2d0","addr":"9fc0563bf0185e0e99f266af339220588c655280"},{"mnemonic":"code aerobic tent hero install segment truck foot employ manual dice time","master":"bb99c30775706beb704fb7a7416c778c295b82d93c8919d521ee915468143401","seed":"bbf14d684a22d95920436c3133dcd0748dc6e3a133fc61cd78e9f1bc9aff37c473f0ced555265f961d4b7e70b6151c9c7aedfe6930e6a352d2da531275833a4e","priv":"6b766aad48cd0ac49d4ea1cb1bd9961d0c0d2f38f241c1b1ac2f1a8b1f7f86f7","pub":"038450b54d2d0dff23c557b3c66613605dff4df0afd3a5b22dc1c93711c9718d01","addr":"e50e364ca287feaaafc0a6b1cb1bc8f3f1410a02"},{"mnemonic":"media custom wolf spider bitter require blouse soldier barely pause upon inspire","master":"83ebfa6de22ec8362e519d5430a1479c2185bd44749be80f3f5381cc7051d125","seed":"ec99f944a7043eb3da146ecf22086de374cb1b55c64f436f9489b7f4f1e0ac6adb0f937080bb20405a4b225bad173729abf5517e92c3bb75aeebb516893d54b7","priv":"0771719a4060245c49152ce121c01ca8fefd04eb559a610a5a084a772741141d","pub":"03b17977e89ee44c699e018352461bb244a783c4e2187ed49fdea72a479969e745","addr":"493f3d15f460402da46eea1dbe4b767273eb15a8"},{"mnemonic":"build key hope learn place romance parrot ask spy whale input chimney","master":"d3734ac55147344c1aa411a2a161f42710308a5463ed2183b9cb561a8f1a92bf","seed":"5065c3b0a1b3273acb090c991269ff667513cf41e34a11cb802b8880591fb5f9e89ef614306261b0ae2148e5747649b6d5a375ada3749e75e084c3b28faaae4f","priv":"ed51941c62cb63e1e232dc903894fd4c8797d69f501f41f85e1763745ea7247a","pub":"038ddc7d19d6bee458f791b34d2acdbadbec78a228066a4bd5434ae538597689c3","addr":"ee83ae098ae348e6c5464eff4d177c04e97862c2"},{"mnemonic":"habit pill guard artist void crystal various owner shadow inspire plunge price","master":"c0a23d72eacc59b5a382bbe6b59d4541f5c65abf8840a16255a1610ac56df1f2","seed":"d7d1bc83db47fd6215a4e193f654c8246957f7f62b6f8b4766ce867ee58d69b01e749abebb2de94f607e2c442554047a65570c4ef1e764c56295a8326fefc232","priv":"f2cdd0461e210bbc69f810f796189167a71aef2fdd769487c772135924d35060","pub":"03a0ff432ff63da4b30ad757931bf41927c0311f632715aaffc41f1a39dad92208","addr":"a9fadf07acb53dc1003c0de03f40f73767cf84bc"},{"mnemonic":"miracle chest bind idle bachelor science catch scatter current argue fiction ethics","master":"fb1730aadf636789c12f30bebf66b5c9b7ec1138e126b9280491f61013e094b3","seed":"2139c6cd3f1788ca6f91147c60d14498295daebfcb65f0732d3c2d327a1ec8e01cfa011e840503f5c49c89e9092ac88e5d688d0fa945b604a851fe4f4b48e404","priv":"a4d77dc6678d78fab38419b72857914e5848c4daa7bc8e47e960a74708fc30c1","pub":"03b946212019343e657dd0821422044234507602641f389ce1698256054e6b194e","addr":"c67df9937478387372ada7cde57712ed05e6cfde"},{"mnemonic":"garden box bus under chat pen connect access police mom crunch elder","master":"c49d46b19d0078803cadb2a63572295a9cea729fb31112b48cdddc9311ce874a","seed":"fab44285c884dcb44b1adc9823cc021c0560a92bb9ebe23ddc25a08c68935e64733aa1f7b7a4ed30494d8f74cd8373a77e114884f74e6804696cf94a6b0012f1","priv":"79ea8bec554ff6ad0f20806224d7f0402a07fcac87db0b4f5a6cf84221cec17e","pub":"02492778ff035fab9ee383b424a90d694121df7cab7ca984aa8a665693c44cf726","addr":"2a899dd4387375c42068e42fb90793e5f689d413"},{"mnemonic":"morning street camp meadow moral chalk pluck winner light same grape drill","master":"e5a773479add64869e28f1d1a01fd6200de25fd53debfb000504a6231d2ab263","seed":"5e24f51f1676b996b470c01db9db032958f58e1d22bd7efb2bffc55baf73700d948c5f82eae0f6b82f0b9158141b173187ffbf4fc792e43af194c992884d41cb","priv":"4794fe7f9410adf7f567728f98daed1eeda0248d7d0607e57c4ec184bafd8504","pub":"026145b6582ac105e06921c3856db99ac7ff518621d984214cf34f5c155f0c8736","addr":"f263e7676644a577d7b535df98f7eb6d3f45fcbe"},{"mnemonic":"annual very slight slush tomorrow stage mother girl forget castle emotion move","master":"53725daf3dc76a16b54a2086106ea4eec394802f70741e2895a06655ffb4ad34","seed":"fc6f22026780d6255cc7a21746c7ff48fc773a350784471350837ca92d9131e9bccaf78ddc60a5bd8dfa9838755dca0c22e6efaaa757a5bc4b2ad341e4cf5d15","priv":"5296ceed1517058d022c8fa5c8e076851745b98465e0fbbc834a0aa872222bbb","pub":"028250ee9798cccbba647bf41f7b338ab4d15f7e5dedfea1857213e125fc8795f3","addr":"82e76dc9270c795c2316a618abe828dc2f09c1c8"},{"mnemonic":"novel swap prevent funny lyrics erode wool pilot kite junior alley inner","master":"dd900d54ceda698e6ade447839e3eb3f64cdaf8f006d41ee8e1a2f3b66b55754","seed":"8b6b71539ed5ce60bf33745f1172fe3de811affd5a494050c4672f2acda9b4af9aa57fece9b8981c94b1b9701eb27da0f67b8dd216418ddacfc5b84f0c835c03","priv":"4fa69bc81f76265d4df75bc208294244c5191ba7c8d6350bbbf4445e90b9b4ec","pub":"0281946e059cd4dbf81328a3b01ea285e106a390ec6a1b938327a26b85b3e2432f","addr":"12e1ca832d7826ea5c85db514ca80723f83a59ab"},{"mnemonic":"film erode thank mobile file ball inner wasp unhappy borrow polar mass","master":"61b10af9d2c25aac6bf1b1d4fb2e0899c86e40b5b3aab8a29986d241aaf6d414","seed":"f1be2b5ead5055a4446bf8d608c754f4b112f25780aefc7859e9697954910d827969b8ab2d78582ee6f91985c7f740e3d5d5ad08a7f3db9e265aa977d4ccac58","priv":"816f805d3076c855f114b1f8fbe1a1476fc02a71b7b800d6c5fb9d3b1094adf1","pub":"03f08001ebfdcac89f9d4d4cd52f8529b957a6e1ab500d541edfa086ffaf219054","addr":"ed2fc0f401d326f2ea61375272ab741d648b690e"},{"mnemonic":"aim owner direct pizza enhance range need raven divert marriage gap hair","master":"6ebc5c412f961584572008b5d531c275d45e403f3e3672c12457fcdedab52be6","seed":"b07c83efb4979dc2978756f0457d7a4574f5ca3c06c133f2b9cae206f12282c29b8fee9430b22a347aabca5fa91ba9a742901aa4ffbf2a1fd5a30b7a258e0566","priv":"16e205a55aa370cc54cd05ea3805858561f4213c315a4cc91450097d3bf75d45","pub":"0309613fee96c3c5bd9af994d9805aef90ec3b4da315a2e7731f6aa1c25c28fdc9","addr":"ae3778cc1c0df866034a0ba6fd3e4d9308ed4429"},{"mnemonic":"base effort water actor slush space three tuna walk people proof siege","master":"96ed3fbe9c3d5647a24b899dbb2c67d69a629fde37f4973c6032555a48de4706","seed":"1dfbfe4c352e01a0d72fcbb4cc82645a81e02946ffdebeb465d424f92719dcde887566f784be14784742eafec3925160e87c4861663ac1ff722b554e2b1cbd37","priv":"7abe37156bddcd043fba717f9be6ebe3f9894f6b814390d0556053be00566e84","pub":"035621b9ff867ef93278aa007087ebb30bf8a045ea4bde45d14969bef6054e806f","addr":"b8ac9814855c57ddf5d9dd367af8d74bd7740f67"},{"mnemonic":"violin naive wrap margin glare sustain suffer nasty whip loan tuition car","master":"df6afd71e01d947df8fac4730e6569a23002ddeb2ab53ddc23c35349cfd55fb6","seed":"ad8e656352e03c098c0ddd1a5d9556b92f013ef9853264189968677656f0b12d6afff540bb8b548671ec2ed60a5bd61204c463a80c10e5d44380db05fc9cc4d7","priv":"607de82b3e17947b94b43b0dfef04eebe28acd497e6d5b7773feb983c0067b6f","pub":"02dd39ee3d3456e77be05aead5a1d0b71b03237929a8f085760d2e1496c3914286","addr":"2063185bcca6c0602cefec61b752ca5cd47982af"},{"mnemonic":"rug pulse coconut equal coconut soon helmet trim peace fall please robust","master":"a47a965d564ace3708293df5216eeb7b963ef1c814805acf55f76a9f44372ef5","seed":"e099210b6d5259379dfab4cbddaa188fd5d61cc9bf9354f6546db1eec25eba33a34ff535fa3adf285e7460aac8d724dd5208d08207064ff6d2f794f34c514747","priv":"c8cc7b2a9f01d89708fbebd824fcaf1251fdbe0dd4953f43a9079947cddaa2e1","pub":"030361dd18f40d337500a32de0adcc92a2044481876e17562863dc32412c8b9fae","addr":"90165eae1989ce6ab3edbb2d8d35cf843138eed3"},{"mnemonic":"expire company bean basket weather apology lottery energy column used goose advance","master":"66e2f9149b1c2ac8f5f9b139a52567d1284f8484d9cf338b016c4d361dbeac5d","seed":"a4218fc8ca69a1661bd0cd9d9a458c996c48502cfbfd72b0b018f7432ef41c8431f70cde82e7bed983e49ae7c01bae7de6d7bcc590677e166456e5a6e4ccc137","priv":"d7377837e6f73b9093b13741c27c8b25a0a323aa7046483b3f13e9ebf4d436f0","pub":"0368018fbe6931afeda06980639c2f5b532245eade554f5c2ec73f3a532d056718","addr":"a41364a6daca7cc6536aceb4a32e657f3ad22a84"},{"mnemonic":"track essay chase camp denial ski worth retire expire amused paddle ivory","master":"d764799a1d97bd937a1b9dbf4a0f7cc91bcd06c6d7c1a1dd3d25e2dc8d63b0a9","seed":"e3e62475c7d13f79f2005f61abd2f674bbb1613587b3e694c70f24f6403f0299140b68567608420af5a7d540a3707eb1817fef98aacc3e861c17172e3a6eaf53","priv":"b2369fb324c5ef9e7e7313a87470984de6ada9dbef59def90c594c374cecce93","pub":"036ecd0c3e3312f15b3ad399ca5281546366e33368c00d7066bcc371919df9aa40","addr":"42a6d89451dbd00904633f43389133bf199a090d"},{"mnemonic":"mean hello inhale jungle brown cause curtain arch orphan spy aware deer","master":"a66b0528350e9aab8e3f7985a658d50bc31d3cc88d145817f77f889de8afcd3f","seed":"3e240baee99e3e3c0030af994981ee7c10311faabbdd685cb41b971b647aabda05df165b31954506c1dcbda0d15bc9dfb3837d8561e8b346439d059431552c00","priv":"f516389c1d667c77455bf3ea25789d8fe6cbc52c62fdb54849f857fcd35d7f88","pub":"03fc762324c6a0ad341118a95cae96d737eb0194e05272b92160ad3412482d6fb4","addr":"0ee6e446b5713f87b9a8384c3fe356e45a4d6e49"},{"mnemonic":"clog just stomach title gauge park couch coast fault demise march smoke","master":"f964ec3cea5791c86c3740626bd8316bf3373dc874af01e2ee844c0eab7b9ccd","seed":"8175672d9e9e2c8e9182f0d6520eb1b0ce82a17a56d51019acd5edb9eba0c9abe7ba77a895717eae9bd565ff0312c65209c250ea48965be46292a4cf7c1ec7bc","priv":"445d84baed03c168e29c5167e6257198fb2f7fd6893b4323e692bf3514364719","pub":"03b43255f28016c8961fd0cf5dc49e427105f290b7025b6138ec444491e80e9be3","addr":"633349488a087a2789bd2a99feb62554bb35a4d2"},{"mnemonic":"silent burden donkey napkin churn equip artwork lyrics wage enemy fade sunny","master":"754eecf77fe825d148dd76b15601f36ea3c1a23b1535ebbff1be9695fe293bb3","seed":"c61d6da1ddb2a00797ec94d1bfe43df5d012c75bbb916e0ce42672f043a979e8cbbc4187867ae36edeec02c5526eb540f1ea4b9778c2a0b534d0b0e9d8a42286","priv":"530591f5c65acab37d4a98df46cd6c8ac259dd019dfb9c97fc34b1c9269cb42a","pub":"030e423006cf8ee7ac079b31591ffcd73f6d63b8e26e765a4b9f3dbe1022b2af22","addr":"e4da6fc6965990f17c8c827af0b0c2a2d9d87867"},{"mnemonic":"quick toast trim image exit clinic then leopard slice recipe acoustic meat","master":"068b8703650bc546dfe41908b04a7cc430add80d2c247784d41b4241a321b339","seed":"73126b2fcde7ca4509ee115803d5bcb22162748ba465c71767e32d5b271ac53c63168d2a16032947c1dc87d5e78e5117c0171abb1bcb4912de0331d7a7d7b171","priv":"a9251969a43a62c2b25f10aa0ee4d621cc1d5aac612b6027fab2a505a5dfa0d1","pub":"035a135e39da761bac2346f7b896ee0d2cbceac71d9679a201bf2b75e00ed047f3","addr":"f7f4f03d57d3726337478e5216c680c4543ca9fb"},{"mnemonic":"innocent struggle abuse math try bright craft lucky excuse fly nation include","master":"631066b05d71d61539a24b7cb2aa659f1a8d0e3dc76c5ea28d4702b18546bd71","seed":"6ab66876fdb7658a98dcd39fbaadac319ca73e280cc471ae3954e6899997f35576a4b7a506ce3c2b447ccca6203092a2c47f1018ba6d75ff58c416a3ae693f57","priv":"4c6c4c01ea2511f4ec731546f35cb469d424fe6af5dbd8ef3f4d27b7013e014a","pub":"021d951f161be476c1795f1987deea93eed12181b8b1a251107d83efe2d96c3a01","addr":"eb09dac4658f82aa173e5388281877403b124b85"},{"mnemonic":"weather fine valley envelope convince cheese primary scheme invest rely science pitch","master":"ea23ee8d99adbc168bbc367b10cec018bcc7f15717b19fbd05de7ab502701ff7","seed":"0c485f94abbe0e9ee91dd661eb2c6670588c712d7790e9d6357eb7dcc1f2bced5d0c8db8dd0b7aea72a6a057ac97a12980d753ebba11c2fb627163e729a74a8c","priv":"272a773d44247e0d0579731593d568c31017567d6dc29ee9cb2324598d1d7a6e","pub":"0305d1ee431078056588a2d2e503c40d1ec6070e3b06a78b2deb04c6de9f4b00c2","addr":"bbb37db4d3d3f8cc16178fa777ac23200c05d78e"},{"mnemonic":"portion visual market hurry enroll stuff upper pistol tired question barely surround","master":"997415f4d0711a371b522baa2a003fb6485f4979e170492c3104a18e7fb90cde","seed":"51a7489d52481c5fd36a703c9e832550f10bdf24b06f9ff023bec374c5089de64e6d06d61ecd509fb44972a92094b4cbe1dc13fc1ce1fa6ba04b03ce803305ec","priv":"8c8acc19030ae9e9ede5111a41637a7f69e624be9f098660247cf0154579018f","pub":"02ae3bf3047431b9d799b99d56bead936c5459039b965a612673a70ab9209e87df","addr":"a2d63ec58cafd042ffac57128bf9ed704d9735b5"},{"mnemonic":"intact elder sign valid party enjoy trophy mix hood bachelor near sadness","master":"fd40da840f8bc5eb4fe8e83611c5ffc897dc315583daf95a9e255bb8441e8605","seed":"e9f3376502c9e4506568876341ab89527694bd9f0184650c3f30fed6fe8b8b8705860e0c63276f0d92db398bfc2cdb4b816d58dc48a5b8ce9325139c1b96d682","priv":"bcc54e226725e41f96f81587653d60b736a8da21af6b24d9306bd6b94d1959e5","pub":"023828cc58f153451683a39c3cef165e8f3a5499eefe018f945b63062fe05dc82e","addr":"cbb390ec8ede1eaee76a40100c1b551872eed89a"},{"mnemonic":"unknown order purpose spice master small inch isolate loop frown page nurse","master":"b8b282b74a246171e39a795778958bfed4fce9aa6040c3e9013b1afc712ccb40","seed":"403e11937a99ae4a4aa3ba4e0f682c158dab10cc5cdd3b79be276e5283b0f91fb7478b6b33e30841b356cedd2091417a1fa09925e40c1ed23a9cf54484883129","priv":"c22ff234c4bb00b72005e1e88909dbbfbba148c90305eb81de0671a5d28da59e","pub":"024bfbef04401d5a5938c64619a6c566011b3cde0c1418f2b62c3a921f3d3f14ba","addr":"f0fe3107cd932d601abf273b7547be623bce653e"},{"mnemonic":"angle blouse weapon upgrade enhance frost fine pear install method duck okay","master":"aad7d48511dac2782ad61a97e3ca94352ad24590f1ffca0e9efc3c6ee69297e6","seed":"8651c2d20d4af238121b528fa601c290efc255a569c8db892ca8f77d634fc02f7098efb7a9a45262c7e86d3d71cd92c7239fe4bb780e69ded7782c00b1ee0ca1","priv":"4b8f93833d5896f673ed59c0bd75a34917a61d521cb8b8bdb22814a0da0eef19","pub":"02e17e65c69b471a9fdb75515aadcbba673dac78c0f34df920aa46ad65623400eb","addr":"c404a9b79ebfa5ed9066e06aca8e091c488bb740"},{"mnemonic":"trust huge gauge culture garlic fluid type drop arch camera true claw","master":"b74303ffd6d878d1ed69a0e406741b51bc725887df08a1c8efac15a959b8d0c3","seed":"715486a3cf1e3db172fce32a23868a832fe7d5ac2844990fc14e951a9a357f16e2b5bdc669e415a40efc7ad14020991497496e980395639a68c6c7b037690cb9","priv":"2c0d6847313ed5c928480a302bf3fa0bd9918a5debc3ddff43cbb4c9e3f12802","pub":"02f79fa697f78fbc6b154d7b14a3b28dedb6b746b9de88c0e9982a54904ef124d7","addr":"c15d6b60ea16407697665acca000d5f792fdd3b3"},{"mnemonic":"shadow sister evoke wing radar what trust main improve moment flee erode","master":"cb1d183803a2de896f83834d19c3e1ef518c3fb6382dd68ab310696bd1d69b7f","seed":"444b9c8d29447c024f11e3c6c1618e767d908dbcf380125a062ce18a552f39fa108361fd18561406eea36e63415d286eabe5d5a5fbd23ae5bfa846a3e8bbaecf","priv":"dd1acc9e8972c3bf4363b3411ed96f41477724b4353e514b339baebbb03a65bd","pub":"028658232d2a075b2c68a519c47d2d74636fbdacb8bb31c9af70a967682816ca14","addr":"f8db02ece9c267f8f5b7de9c801432e694e22731"},{"mnemonic":"guess beauty gift repeat desert oblige pistol pottery lemon clutch discover dragon","master":"67ae574f5ec3766b3a0e1699dfc188f0ec78b51e69faaba76dbb08cd3a9e6382","seed":"395674e7b70cdf97f6072be527bd79a6fcbfffcb4322786f8d17611a3bf87947a87fd59146a59e7143a427c4065759ed6973a00f6aa522e6b13058382eb8b080","priv":"170df49f85c0a741bd5a6647d33410f944619de34e9ebbe7387fe8785b470960","pub":"03dbaec7aec40764a0365a6b2b00384c7966e9b2c97432273abbdfd089c519fa4b","addr":"af3c030ae37cd0ce5d3c41012b904738c7905887"},{"mnemonic":"fire duty baby kidney coyote arena bonus convince soft party blossom brave","master":"2054fc16a8c8b5955c76150c43fe447fe7a6d083b323eba70784687f94780a75","seed":"c16d9aa8d945a01871a46a92881c10ffafeebc0b1183e97812169d8f6e4f094e70f82576947917f3f6e551a9b9dec573478180053f6e0d71c5c48eeee95b54af","priv":"fe7f533210200354ea9c5c972cd0a4445fdd8a2e6e6e830cb541fc894e2e0ddb","pub":"02f9fa53e71e4a2a180d6daba5ae9806ed5e338aa680e2bac8fe25ff1a1a151d0f","addr":"2f028ee2adcec5023013e7a3756fe18c9a87b669"},{"mnemonic":"poverty inhale unfold strategy insane usage festival dizzy drop divert august head","master":"148e592f2c22b1db9d693e3777470b27ed0fcb2de1c0ec2d1f9f47421ff98cd9","seed":"412368afe4a71e2a37b1f87b7ce82f64dbef5579b16a6c189fa2ca29759e410b7c1e13a7b591711fb3d5bc8fdcb3292b3c828e52a2c1cd20aa55c830b8506a39","priv":"7e070b5f714cc7e0e031be68dd03e6b3e18673b5966d9c17616554df4e0f3288","pub":"037227c68b192bd6ed034570d5b5d532354dc47891acae0815d0acbd8d0346ac2a","addr":"439c830a56e6f8299c4d859c2cd5fd4a821e6dc7"},{"mnemonic":"gossip quarter proof require develop about olive boss fiction quarter rely build","master":"8b7580ddbbb3b766cd08088792cde2429c003b8b0fa5a9165747275685223a9e","seed":"a3c24f6f125702480e2d8856095a96f3e6d596678f15817414631ffa525472a01bceb58a0790e1df38dbcceefd73dd9b6bbc5bab841503daba8d73033494c254","priv":"5bb1bd6cee64ee4cc9b08f27b34dfd3da9ea263cd7fe7b4d3fc8a6a2db4e0ec2","pub":"03bcbabf0702cd56f459b8cde03db89d3c953faa3c108e90b75c65eca10485b5a4","addr":"c3ba63ce6c961c11bb3f7cfbe7667ef2c1ff19ad"},{"mnemonic":"dash small ensure soda crime wheat future style guide repair diet panda","master":"468770a80bd9e0190ae3a7a695da6a7bf30ac9bede3805c7d1dd4f6052e4d7c4","seed":"59eeaf79145cd625c266dce31faddd42eea93d15e64be3a430b9fbefdabc85cc3366115a07d819bb5ee026e118ddce46a2d906680b59917ff7adcb3314d6b077","priv":"99813e574552f35d2ae337f8754afb37d8387129c5e714461a0b72cdb30d0bd2","pub":"039e8088eabbbe966cfe54264bd1335697ca335eb55d56a89ae6a2af0bcbe2fd60","addr":"b3926244d741397940f6218c6db7a7c71cc012af"},{"mnemonic":"profit brush exist mobile diesel keep oval guitar cover maximum media file","master":"f402407479104621247ca60a34f75391ddffac32511b61e83324d85d873f0da8","seed":"6d538602ce7d97d7cb5469aede489a9a4f8af829d76712c13e7851d9e63077dcea3233ad51a7c311d367d4d982bf963c016c23fe39604cdc3d1dfe25baf1f515","priv":"cadfc276bea3a62afe66fbb5a4d117aaaca562b272aca37a0ddbd5f5a20c95da","pub":"036aaa723e425f879d4b2e731fda45dd95294608daf9d553a40f59fc4cdc37c996","addr":"0b6a4c2a542c624ee95719f53c99e3f6c6f7df19"},{"mnemonic":"oyster twin legend bubble bacon wisdom affair bar search just daring teach","master":"722c8eada15c60706ea1a9fa5aa6225142a623d6f5bd946589b22b3c9e69f56c","seed":"2f3967f0ef31b8d1bfe4b125678ab07328ada854f5bb589b5fd2c5479c3306eba54233f3386409e4b68f95be7f4b20c054f7930ab022f720979c847bbac99b80","priv":"73b2d8daa926db7e9072d4576dfbd511017e1ca7876bfb453112c8308ce70fef","pub":"030a96a78ec8dbcc9d62b9a8ce221b0f740358e75ed7ead277b56a2c56bd93a468","addr":"0ab19ff6566e8294c16e734306415bed696791d0"},{"mnemonic":"say poem daring wild toast force fall bread cup crane next patient","master":"89a87aafde53a9a8fea6b38549b6bfccfc950dacacda40f83b613a6322299164","seed":"b86bdd449d73412f10419a9534fc545a5f062d615ae197b6ce5143a1b00ac838b09e9db2cebd5cb556f469a4eaf883b8d9683b222f9b8843314134bd718b0887","priv":"60b1a4533e8afb1ac5eb5448db1540b859fd3650dd4e7c52b8b1a98ad3eac169","pub":"0255161266504a58a273b413e75fba8ae3c49046a3bf8334b2bf4a203f837ed383","addr":"2c390e3e85f391607962fff3ef9c3a7ca4ab5704"},{"mnemonic":"bone path relax awesome planet exercise road reflect life ability device frozen","master":"fd23233c87545130d43a46064fa11deef11d56a3cbb0a2e52be1aa21eed24f58","seed":"c72634cdc1fb47955eb7d9fd2391b3098d407bb5da35c0a88fcb38746c4d673ea113a96707828b18549271af8cd0f9be51f5caa9718ba31d783a3b26d450e7d4","priv":"d946ac6ec053521443b3d8d2dad6e947dd544b58912fa7b87b0b7b55f8570981","pub":"028b9c6677d3fce87d4b324ad336e486d382f7b56c2a1c8723d993d247ac1e1caa","addr":"6ed322bd71b762e44bf4554937122492e039380e"},{"mnemonic":"true solution afraid clip year symbol burst alcohol orbit village arrest balance","master":"3cdf923de0656e5340979c614d12ca869b97bcb476f8ddac3c10162cd23ceaa9","seed":"13c3eb909b83529db1d166eca7cad6b918e1f58c6be120aae8b7fd2a2c848d29550551ba3d710cb4d4a8597485e20535d6e65a941d206c69774cbdb04113ac17","priv":"1432f702f33b6c318f79d2655da268dfba6075126108cab3c8d88f4de2a6a0e1","pub":"03d100bcb7a2b81bd8e49af05a92c9a874f4aadcc836be590d63ffe8a08b63a0a7","addr":"3527160f146f542703309ee02b4ef783416fc9e6"},{"mnemonic":"family trumpet pact beef stand naive book escape ensure puppy envelope dune","master":"ecc1fb248992b1402eafb7d3120569255268dfa5ace3d04fad48b1917a42c3bb","seed":"f0f55ed35029e7f123dd153df36cfc9bc97c633b9b8752264bbbc2c33bb5932ffbd1d657bad87f8ffd7d4d9a9355226d2155fff92109adfe573ec67a18657f3c","priv":"8cd151b71c1f1424e2f53a35af5d427965f453572a211d8b4315894d370184b6","pub":"022ec5ca227ab19d758ac5941b9e7e7e13a06ee9a59c94d42dd6d013ee7c3d1cf8","addr":"93f08bbc6109187bcba87f2b6bf86e73eef60483"},{"mnemonic":"feel grocery tone drastic clap great pizza artist current true diary suit","master":"cf0614735905c88cc0f2236dbf71fc61accb6fcba39fabbac4ba1275a1ce6e9c","seed":"75bee915c2f3216cd023b878d06aa4d45241a49d10085b851303bacf82c36b392e01478359e59b54c77882948aae3026539d687298b85c3517f31ec0dd80e213","priv":"03e47eec1c8f7d3ddd3bf1997bdec4802a5b997e80a9a9fdaa8ed93f2641b146","pub":"024adba9bba7c596189ff4b057a2329740e03166cf6416612676d68a6df32c56ae","addr":"ee63795d783ab1a27ba8fa2a64665c6a563134f9"},{"mnemonic":"health across rare laptop broccoli verb course bacon offer hockey vendor venue","master":"a80307838f0014f827d55ec51e5384722d7a6a24703d757aabde32dca9f6dcd0","seed":"5fb4a16684f338f15b5fa6ea48975ababb129b3c01c726493abbfea837757fd27ff0a70bcbe2d08a7174fb7848169f7e22f483b8976adb0a4b2600657c9eb912","priv":"255717f5e26bd51d607b059c9a7ddd153d9bab0e832596df648fa671d8535d5b","pub":"03ca70b2fe6fd3def827767c0b26b25534bfe22ac74f77c0c4c05051154a08ea69","addr":"c4029c4186f3e762228f4d43b4d8fe19753b99b5"},{"mnemonic":"begin step squirrel window liar lock endless maze health galaxy swift scrap","master":"53ce62b273658f9ee3ef5b78a4e9d8b9a84f383053492d86825cd9d360763406","seed":"93d7f29ea325b084210dec914666f70ed46b83b7818d2dbd1614352134dcb021d539acfb2f4d916fa5ea48babd11d95f12eee97860c19db1bc2f369c6cc96b93","priv":"50455038499b153d77f388654037cdf614bb85ba5470d8937fb108a123241521","pub":"03f1f12d396494513c14a7508a9ad1dfeb1577af519a250b48798ff59f5efde3c4","addr":"5c46de48e642722b4325afe8446608a60e7ea89d"},{"mnemonic":"snack fall math great upon wing casual acid clown despair cage heavy","master":"c40433c68e968ff1081d3ffdd47249f1bb3cff2214f4e0f19227442f8e7be4ee","seed":"6962c13ba9d9b79b31480c117cd1613f6bb9dd6613e42b17b7434547694c96059026355a2c58b682ebccddc5f84f50c05b60b517e27eb693f1eeff24a038eb0a","priv":"972881fe79c997d86f11440cefc6c52a46a1b3b9953a255da6488e7ac278299d","pub":"0276ddb2041eef2c3b487a4afb36de7cc5ce5ee693461aff375131177dc4d28b40","addr":"17ed4db6f0bd80e929e048d526dc55a74ad58eae"},{"mnemonic":"vibrant valid carbon wish bicycle adult hobby lawsuit problem toast clever lock","master":"903e9b75fb472ad89da3b1bc74937415e877c1973910cb9ddbc85fbb465c18e1","seed":"b175935f86b62ceb93ed1bc1d2f3aee77a628aca7def8f6761df8b624a29d495a150b373d12a5cceec7d394aa91d0e68c5e2464a99820ac5add276d655be28d7","priv":"dd46bb3b1342a5a3c3844ef7fb4bcb247f9a81a48e20722faa1e03ba59808191","pub":"02bacfbf1b8b6d4a6e8a36b913d61831668cdd3dc74710c0ae0851b87c65789edc","addr":"e0520de38f2d2c2d3e461b1e2fd3076af5b9e927"},{"mnemonic":"obscure false outer neglect transfer other index debris bread crawl morning scout","master":"601edf66610cd4b9467bd73418a3dac8b937ef2d08c09ecbc89110443c3c8869","seed":"9d6168c1331c952ba5c2b19a0894bddbcd3d6a0960ccd5fe685db487ab8caab4109e2dda7c487d6161427895a9803ef3fa857fa2106e48083587032c6d30a217","priv":"2389d4e6527d9190a9ad8720debd487a00d47d6ad6228d643e1307aa727d1757","pub":"03bc72643c1c9a13f31de0a61815f950aae5e186328d07bfddf8e1dfe952fa8b49","addr":"add81ed8c06032c52445dea0db02a9f56b738742"},{"mnemonic":"minimum coast chronic damage page antique mechanic material worry alley nose tray","master":"d7f00c2baf2037008e9d1fbc1acee85127db59ce939491aa5cc19033f55f51f0","seed":"0ce817dd3a344f8dcce47336d3bff28da5cb9f5a71fd26e54c4229e9c0bf943077826d72c68e7570804b1992646641d79f8ac1b0fe157b7e12c70413d9625e22","priv":"76e0ffd8727768a428fef6d1e4186459d6b3664fec801ec542608c955dd8974c","pub":"02c0fb2dacc13de0d29fa26144d0974f90b97ed706c16ccdfac02eafbadf9e4e0e","addr":"e28e2564870c7fd74244b111e188dc82c27755da"},{"mnemonic":"evoke example emotion suggest apology uniform giant empower future surround pizza scout","master":"ae3bdaf7acb6660fd151ed30d5d299f82556bae13873f6cd9e65111d991b4d00","seed":"840044591bf305fed33beea796f2c5a8ef72a5005797762ceb8528e1c0343696c02012ef81a8e964548af3293454fc6e3329059e40a95e9225fa254fa901f3fd","priv":"2ae6395640b6827f7b3af5d2a4a0f0df46d4c6c5bf28528eb3a896d60c80e0f3","pub":"0378059ff10a1d3e0ba1876622e9d45a9b75f01216bf14737a68b48138920e7adf","addr":"c1333d4372eb2dea3311829c10c6d12f17437cb9"},{"mnemonic":"endless come happy cause skate short list laugh amount marine glad pear","master":"c1643f331f86b0cbf7297eca946e44d0d1a1b3e704b6dfce6d53d9e9c6eeecfc","seed":"f3901b079e9987dffb0378a76f099e39349cd6abb9c59c23ac3f1cf90b988e82b71bcb3466b7a2f9e04e0b5b27bc945a3b4b714e0272184cb64e9b4f8d6a638b","priv":"e80f64abaa7b55214d94b2bea74d25a45bd6385bb2447fc53adc4be4820edffa","pub":"036d7029b6f83bbbd1238bfe9a2b8ee654ebc1b2ea9d00494345783342705ef7ae","addr":"56fc7b9a42b8dcf74932b92934321f2568606240"},{"mnemonic":"boring math photo park connect wash captain drum kingdom replace exist beef","master":"4853a21045f669f43eddd0df88100e473320d2f76641ce5f9d010d654f4896c9","seed":"65e6412f40852556186217c0ffddd4291b77651f8568d97434f1ce3bafd4784642d9eda0c401f9ec57ffc80c161832afd43ab89080fecdb8d6a2570b27b2f0a1","priv":"67f6f9aed318eaecf6e80b3a89748900f3dad77502893e133024616c15418799","pub":"02b0f15eaa2f0b9c09a03280c9689aad73e3e60e6c971ada22b9352cf381d9a7ea","addr":"741b1795cdbffea0b144b22ead2d466413bc232e"},{"mnemonic":"true also hockey holiday increase humor main lonely invest modify penalty soft","master":"c1716c4c6563885c995c00990cedcf3c90734ec9cd0bcfa327b19349762d1bd1","seed":"e192cb10ec4d6813342e8ae74c60ecba75c8f9f23cd60a92c8abc44211fbabe82f4f11e30bf68bd447c8f0147be7ff9ee9b64cb8c44ac8697f2bd1ba886f8427","priv":"f72b0a757b8ceb4bb80b47704eefcb5e0448a9bcfb7385fa3b6492628c36f2a8","pub":"020584eefaf032c19e853bdaad1d1bb8cea4001b8d5bc919d888b1cd55f6e88b04","addr":"98ff8a4e963a8e8cb4a09e10a83cfb704abf92f7"},{"mnemonic":"inmate mistake detail main sugar find maximum crack soup tumble helmet caught","master":"9b6e9657a31f9baf6f303b2df638d84e549fc35e23f4cd7b8b96ba608c474657","seed":"fea14199acf507de04127191e47dc5d20d60ff473d5aa600ab697b7854a7351bddfc24d99057671273b62111990d5bb6f0088af026b38448609d3a4ac8f58b74","priv":"2800c0aa8490524c5add4d3a2def895d8d54e9608a05fd21a7bb5373f594999e","pub":"03d49899c17ac5c0a8c3720c1a9593950d2a8a591c8a8fc24812d198ec1931b5a9","addr":"e198b4a329be8be7f67e4c7d63bdeedf9ad5b45b"},{"mnemonic":"embody ocean catalog shrug valve extra potato subway casino father denial oven","master":"a24ea5416ed8d137670224056db9656e8c1a70f8e602bf6a49cd2f7e6968fc5a","seed":"447121225f8095e806b284e249c1625d925999fed396dcd7c36d9fbff5339659530fe2df0760a9d1d15dad32e1a4c1577c518bbb378272b305434d138e748831","priv":"548afb052cd083e9504a6d602614d085c7a20f37556030550d13619cc39241c8","pub":"0370f25b9cfe827ca110760fd13eea09082573b534411d1719a12fbc9867982e4b","addr":"e6abb5bdb479ce55759bbe1d0331db6046f1aabc"},{"mnemonic":"brisk present attend rib envelope keen mosquito athlete guess ginger budget interest","master":"8e34652bc5848d8fa141e06899c93928c5bcbfac5e1daa60c77af837d7771b96","seed":"4305389939cf757a57a7ecdcdfcc09f7699c315704a3d23243968932386f01dfc8666b7dcfee1d7ae26a747907c85a949843ffc91c9abf3f98007d394b1ba2ca","priv":"65e554264f67ab679321ab7fa516b5988e6049847de929d6e1949032adf1452a","pub":"0358503d0c6dc10689a3705838741f20b83bd5496c4befd2403f69760533f7b28a","addr":"80b6d095ea92c035fdd56adbc4d38f209de13000"},{"mnemonic":"never gravity problem draw arena very panic patient clutch trick calm topple","master":"a6cf02c1407405402557a745a96019f2516fd7ed03677871da922282358b23ab","seed":"ea44a019240e09c4c642351a7aa04625c309102032b9f77ecefb4d33c25f31179fc52c300b4a2e57603c08b5ecb77600bf9f4f9fbdb07cb0dc7e822f709ba7f6","priv":"38ac40ab37d588c0b7ed4a6f4adb378c9e1a6d8a3cb220853dd56abd7327df4b","pub":"039f5f8a5513c74284314c5c5775ed39c77ec9081b978a3b096af6670630046730","addr":"c6a7dfac1a85311dfb3a3c6191a6124ce8ba39dc"},{"mnemonic":"aerobic slush coffee volcano tip speak across evolve nothing deputy limb arrive","master":"d0b24358e5a1e4cb2fcfbb10d9b32330e02be92f3397e70c8a81b04f065958b8","seed":"927a69f86c0f796ef2a6f89698ebcc6c7d2df24672d1c597c10f2b3dac8123808b46cd63e726eb6f1699b0790f14da3a82d9da2cf0fdd32a9b936c1763db0522","priv":"1d736f96fb08caa2ee8c9d4c1506bbdf235cd3ce076a976f8a7be2bd621e5a23","pub":"03f6d508014c45fedbd92677a8dc94a72a7ada2c893d0e2d508c4c9be4fbc669e0","addr":"7ccbeb5e8927c714b3d4c1047e66757bea289bf9"},{"mnemonic":"aspect glue bronze steel idea trend win collect ceiling puppy gas flat","master":"6320f492fc27070bdd7b99436ebfdb25f462b588f50915e5c79578613b53e41a","seed":"e0c9803520833b770aa6febcf2a0aaaeaafa6d39400141908c6577d99ff4ff26062451a4f1b2ed4dd91eafa345f7efa1d565fa101cf0ded88188e9d07ce62e5f","priv":"f87d3a46e925d395a8c4539469e0474cfc0bbed8005b50d539a28c85e3a44a28","pub":"03343c7d2cf83e568ea0c9b92e766c6e021d4a95ccf169c2c9d085693490d66f0d","addr":"6dba7380eb165ea86e2b07e30c5fe1022e046da7"},{"mnemonic":"curve better narrow reopen vocal gossip fall tornado fossil scrap goddess direct","master":"3fed34f65702bb4cd41a309cf81ae4a8c13b569e1de5420103bea9cb264a0ff5","seed":"c3f0c08138f32640b3fa1e6d9fde51163aab66318a7709933339874fe8bad22e75f6c19004af5196fe84348a1f3eaa37add1b645a320acf8a1fda40fd788b428","priv":"c99eb1a2f56c8ccc3ee2d2bdd3d849b6a60e1e82200f72e55d236ef1b0a9fcc6","pub":"028c3c8e1902ee965f55211362b5277748a5da54b43f0807a216581e6d686158df","addr":"507e551fa72ce7e9da2b19f4258c2ae79793aa2c"},{"mnemonic":"insane screen heavy sphere turn drink direct exhibit turn pattern series pitch","master":"b060bffb238a046de32305be06a806093f62fd0d52d1ff5b44b70ad45f502996","seed":"0f75c0f282ec504aefabcc1cdfea3e4166b4f6d4782771a905683e26b05dd5603178cc3fde6fe4febba6542350b15a3c393927ef1e371ec450af6ae6f4ed5a5d","priv":"3f590738a71a45fb5f111181747b44e342212ad15350db1d3ca475b9ef4914f5","pub":"02e50487e89882de6fe3ff87c7b12542a8a6a8a8cd2b4a08be5071aab04b2d461b","addr":"66284b62f4b7f506c6aa0f935d034b00f35fe66d"},{"mnemonic":"answer mobile swim shrimp jewel smile security shy decade sign physical width","master":"64cb57bff4e190f89d2d7564be94cfd1efa0014ef403cedc6946eb52a4a78813","seed":"3f645e90cbdf7eb6aed9afb802fa22f1c0baf57a79c813fe21478a7f2d658dc83c3498c75b0ee4e01a02cb11609473782065c7656083d7986df7bcb320603691","priv":"12c7e6691ffe251287754234d7b98747f12183b5535be6c886f86268b28e9175","pub":"0375b4071b801b389cbc66de9443623ea5b86d310297369305d869e885e187a0c4","addr":"b6fee98515f241c4ac41fd1382a1d7211dff3af0"},{"mnemonic":"match car rice essence try reopen wrist party choice creek inner comic","master":"60b8c48a8c8cb2d68a92559d1ead30a2cac313df4f5a84f94d0b64a3d5569047","seed":"17a91ddd485e6becbb822434a723c5143a11aaedbe9275b36080f92303fb3ef4d934abc5d36bc51b35946a4a683f932373e4a3276feb0393c499a961b78fc18e","priv":"1d9e0692e0c3e8d06606423fd6fe3d336b893c13b38ae3339aa3d7635e2c0046","pub":"039de765de0080a12871f7a278fd27a21ff6052d864f36a01aab4895a3e20d13ef","addr":"6a1216c843cdbe2010e5f024e265b31aa01592bb"},{"mnemonic":"leopard garlic permit menu opinion kick clinic upper start vote truth okay","master":"9db65a69d3ee0bc07c5ee34244faa0f6e8008c51c5372ccad6b9d54497c27f94","seed":"f125a9285412d9aab52baf0045d628d41e870814cc1ee92746d0cd0fe955bd30e3f5519521c6c7d172d07d53f318cacfc5b9d4b0a4e508f9a1056526df594283","priv":"da4acc9d2c281a03f904b42962e021401602b65c815b9659bc4a344f6f35e934","pub":"02744a41865188a5b3a37032369fa4ef214dd2ad836a35dc738b501736806b6606","addr":"fd86381be60f3ed78fc53abf84a8652b3c84b7b8"},{"mnemonic":"vote divert tower history staff finish lyrics empty bless alien walnut hub","master":"10f25de189ec007f9caa97230456a55ae87a807178e8cf23e84f761ec7c69cb1","seed":"ec42f0f2043a01fa768a6c5e889bdc706747abae60609511755f21b7798b7e3c476d38d0b2894f2519f2fad6e279d77a04e1ffa864c9059697da274b32bf3b88","priv":"4073cbb35009f9e7ad4bb18a0c3c7178ece1b9e07c9df1d595f5142c51a92bb4","pub":"0340a0d2e43896e6cfc4d0a7ff49afb1ac28a5ba112af2882f86510865f84bb8ca","addr":"21e3b66a23dbeb25b3b0e2372e2fc7b64364ccee"},{"mnemonic":"debate between rent foster stove powder truth remain cancel pupil object romance","master":"aeb2d34623bef5822150858dfbc2c0c53986c363297e9c3fe1ea64613c6701c2","seed":"c95a64fd29b7b9f15d9077e6a67a8f754bfa55bb952ee35ab94ca001caaec42b45ea2ae7223fd10492dfb02604fbb87de28b4202c49f72be52b7c55db0c8edf3","priv":"aaa218916efc3fd6ad5b948ffa4a3239984b06592c3e7809df3bce89b7c50465","pub":"0221a21829f0dbd3043b9a7645c182e835cd14c95ce9931c1e17284b9172b77130","addr":"853104a703410c5faf86381d5d2adb4f3254abee"},{"mnemonic":"dismiss fire ghost eyebrow salt report pupil include case east blind filter","master":"636ab989611298c004b6ceca6cf887c25d44df49260a8f755cc159d74fa971a3","seed":"5ac06b4e40354a95bcf97270de3db0ac2c9bcd44d1a83c40e9f2557490cf794dc8ec43e71d3dcf3f13e6a7202d84b835c124405a2dc79119288ebfd6352a1d1c","priv":"ce591b790083433d60e3678d5ae488f6033c8327b494789f457a4a137a99bb33","pub":"02607f14149c2272136dfac3ba34476203424fb3eab4282fa6e81c0bce0357e81e","addr":"9b38671825a0fa55e15833ac583fdaf3fcce3800"},{"mnemonic":"awkward slot wrestle sudden core clutch again pepper private reveal shift baby","master":"868dc5c7376cb2ccca274744e97e1b6f8390c1f2fb669862cb624fda1e8d9408","seed":"065aa8d9dbe5769799f29e7a99e663a6e622f0463c6b8093486728d2ff2e8dfe2d9d30e357ac6416515f043b9c96267f3b0de08f3b88c6bbe9486c3c78cdc44e","priv":"e6d6be1b041e0d52d576fa52f4987cc2c8490d86a49184a231703ca0f3d1fc16","pub":"0375e417a16b94bbb1e8cc1789535fac4abb78b466d2a354045da76405ceb8c35f","addr":"280ab94c67d7bddc3ee6a83571a2941b06c83676"},{"mnemonic":"whip tired like merge crush bird venture verify grow fiction provide coffee","master":"1a1a931d51b74af1b4ba19a4ad97b2d5d8c79396cac5d7dd7883d83d79fa81ae","seed":"a03ee9671bd73e717e93830e97dce58b4b5786321989e9f446daf96a6f328d70f5d5dcc4c40d21b7dd4b27aa6809be2a3aece2f3c2469923b8e3d112c899e3c6","priv":"8bc19d1e811c334e4417013c3c85a2040cea8a3b61c18bec0c7520bab9dc082d","pub":"0224c968015439332e83d1737b7429c7bcece458a00a94cc83aff758c5386e3878","addr":"a069c8ae758f12a39e86b2858865d95e953afc67"},{"mnemonic":"prefer benefit sound knock exact pull clutch cabbage local burden small report","master":"9d8ac0f2bbe4caafc11f2cbd9e644e62ec5f54003701453e9c08ebb5b252aa10","seed":"a6d48540efcd54706017c3a5c47773a4dbade3044bf445f8e811b2b2a1a584230d070c296fec26c59deeef37a7487926783fc96fc593c270e90d7da08766ed38","priv":"bb6d7a3a4717541b7e33146b75789999b5d763d14f0962fc43ac30193e711b38","pub":"0288eee81a2e81977eb56b163ea601470d99b9024b5b99db2af88228842fc6d4db","addr":"62c96ec870a47a2cd540758e27fb19fedb11d9da"},{"mnemonic":"case choice castle monkey awkward kid submit layer bargain reward ahead type","master":"c3da04cb84f0f98ea8723f2b6d7e6a3c83b30e5ab8e0ef75bff51ca0b4a00707","seed":"c65366f8af99f805aad4f87c4f73c074d1c99e69fe65bd2bb0ac6a1062bf9595051133c32d5abf4910cda20b9e8a8cd76e22e692e31c02f9327eb703602a9ff6","priv":"71a0279874cd44a61fffb0e65d7fcfa0f4f7c24db912f18f587d6393f8fc1154","pub":"0265ace29b8dffee0f31e6bb3e42f91d90eceb13357e6d324ee2cbc41528ec1c4c","addr":"cd772b14963185ed989f1085142b2b0ae2e5f980"},{"mnemonic":"educate meadow confirm subject tube urge guess black friend later cement spirit","master":"28cd56e6a857ac35c617c4665c143583e0626dffdd7a5e0ea55ed75215bc45e4","seed":"bec29b984cb4df491eb1154fb2717662606fa63742febe91e10d19057c9134b4d4b8677ae23e006b450d6d485a67ae09a9c34fcf8cee5b22be821dab855cfba9","priv":"fc3c5da684c39ac6ae5a91a3b94f50680f6562187b5a138551d20149113d03f0","pub":"032eda5239cb98993519d44e7838c971f9bd8ef140da2fa4a95a70a2488f78f1ad","addr":"5a9adf7df64dd7f7e9e0d29b9fb90069e8230090"},{"mnemonic":"way butter chimney fantasy rebuild delay shoot toy ugly festival resemble promote","master":"599622e23b3db7ee9a6f8f95f5e39b2562170fbc4dc0d84b6869224b9304f134","seed":"a5e0489af660e70db67649c03622aa66b1a6c57d2593204cea859a146b1676893c94f4390740021a51a3a076b27239c7870db78ab7eea48da0a0177a10b8e16b","priv":"e16a619f8355c4cc276583b67fb2b2616d23d09557539fefbe915c6922e80ae4","pub":"021e6f57790a3250f24b6323cda9f648cd0b1907e5c7a81369d022748af8a9b0d1","addr":"9c7b9192469e256207f7758a906d0ab3c50e4fa2"},{"mnemonic":"sniff rely wine book guitar repeat civil elevator olympic wasp dumb often","master":"43a2904bc971e275f33f12109c2067877acb6b00cec32e3913725114b48bb2d1","seed":"cdb3853a0160f7ff9f3b6a9d10192c11ba3f74d45f4bdd4366c9153728105cee7e117de9e8b13be65d3a284fed6866ef4850898c9c2ac4821f55a9c6415f7e16","priv":"970e0aa6e521b0d938c41143fdd75983f5a315ab51fe0e2c79f5c37053e7dd70","pub":"0378b468aa83eb47cceddd2ec8eca4004a9e99ccca959ede92d9b03ce3e38d5099","addr":"9b285c714fbf2d0d9e39395b08d07e3eb87ed87d"},{"mnemonic":"salad print drop winner chicken despair bleak warm misery buyer clip glory","master":"77c5e3581d686b79e863b82f41e563fa5a487e11a782f609b4559ff5c52fa091","seed":"494e915c3897e9bbce29c8af192e7360865be489b38efb5f6484955a525d7120d7637921f7ce7cfe820fcc996c9d9d0edd76f8376a48549057267fc7193cd66e","priv":"a7e988c4a3e661ec230fb359e8f6f7b9593ef5bf33b9086c1460fabacd162600","pub":"02f91a2b6f0545a45ee7d50d6899de984dc0d29ebe6f75cdb3dd169c696daaa9ff","addr":"8bbb9c4b435d0f42ae033e2819a600ab49f3a21d"},{"mnemonic":"inside alone salt borrow fuel stereo toast hotel want arm happy marine","master":"0bbbbf5948912d5e7243baff26886acf316b6ce9f450ee0d60d262b568200400","seed":"afbec9326da69fa938e71403cac67aece539c5fe1156d34ec737531b6ca38b68e60529d589f887ae24899ed8ae53b9f8329f64d84fb62c95a7cfcad45e83f6c1","priv":"8e2532f0440ecb83316645940e29d0b522adc421fb9aa49a8016b6bb1ad34e16","pub":"030de4b35fe61c0fc2fb4fd295a9352e98c7080cc99a6f70d6f64229745c161be1","addr":"519f731ed0412ac24588381879f050bfa9b01591"},{"mnemonic":"cousin drip gap gift ozone omit road parent square lawn crucial color","master":"742d494238d59034ac2026b9a94ad7cf75df5e1b481de734c440a8507e2236a8","seed":"82a0149396a6cadb670d7286506e1a0fbdd771751b39562eee0531d1a2353d29229940395cfb0e00fa1a6d26c9d117039d2a1738ffc93b34161e29de73ee41ca","priv":"aa04e7953be44feea3ddf077d01644f5b4f1eb85fa89521dafe85c341896104d","pub":"02f0d80a4cef0f71606ef476aa04ccd34182bc12b0c45708b0aac49fc2781fdd35","addr":"4a2358c67e4faad28e0d50066a9da25912c1cc57"},{"mnemonic":"list power fresh cricket must expire globe noble park eternal tongue thought","master":"c5210503dee7e7530a84ebb0ca5ca9f15670dcf987e82d67ab2213ae76275b95","seed":"7e482fcbe082d1e9520fa44c8ad117f4d2fad839c8556ea3aa4096a7b940009021611938b4cd2cd82434f5ea37afb4dfdc3548af496f0afad91bfab3117b241b","priv":"c14825a7bf41e5daf44cd9917f33c682da9fce939bab16421bd7dca1e04644a9","pub":"029a20080d20312ead4612ee0e9cb5a2d641ab929865cfb19c3234c838e6f75c44","addr":"750b5d9c00adb243177506688d9bf4943a3ff666"},{"mnemonic":"bless goat worth boil street wing quality visit honey couple upon sheriff","master":"c66453fb857a3deb4ff276dafe0437ba6dcecdcfa67b095053a060f9d5e67c26","seed":"b29cfcf2aaa980c88ae8e0b151601e40ccd6dceda39b4ae324d6d906bdd3342db7ab0f20ae75c1f1b424bac7b679b252532b4d5990d36d91f7612120a5c22b25","priv":"dd96f23418a459bfe23f676db88839e63d1bce7ab58b76d28e494abb1da9616b","pub":"027f81c68bec50476477e5d5524919b7e40509818a16da7724c62de26f23fc2d65","addr":"8856e5d456716486cc794be572454bf41f013404"},{"mnemonic":"slogan outside park during produce key meadow cricket glow choose pass tree","master":"4d6772450ecb47b86c562d5accee0f78c09b182ffe324fe0078fd324474f94f8","seed":"a050602af53f0857804abe575f05a664c292abe43782589fbee0aafbb9654988b6a46ac26d93ba14166d9c6f887dcc1693c2aab5a782f4277c0f153e3572936d","priv":"92918d979c61e8c6a256548502714cdb0094ab6fbc364891bc094bdee708357c","pub":"03dddebad5131d93de5078fad3a380a717f2d2dcb65743f05a84dcf7f29a26f9c4","addr":"0c34fd5317283be4b9ae5a953f539028a5f201ba"},{"mnemonic":"coil burger alpha grow lyrics check page spirit sea mention course fame","master":"9b4a2e05f533427551d7e44ccef49057b2fa0ea57a5890480133a8cad67319fa","seed":"013af1c7f10ada279b632bcaf0211006d13e62165646ad3af69da3b60f044ce62e9bdc7c1c6758da037664f18f1a1189683db16fc2ed39192a7737154984f417","priv":"1a9a114d594bfc3e41c3f507114ef3b872b70563fba390dae992317f67fa0241","pub":"03c5ce908d87792e067ca19d4fdfc15e3abda1993f3ad1f1c8bc5168c58c3c4e93","addr":"cb513df0682dc11374466aea70d7cd9a45d4fd44"},{"mnemonic":"napkin mystery powder birth crowd fun disorder bike lucky core dance punch","master":"8fb55d8de947c13497a83c9631a4fe9b0b491cca2743a6a056214c1daf5cd87d","seed":"f8c5fa5fb7581ae597edbf214a2755ac2bdd58dda03927c21c983b545674de67d69e258a196ef36e3f3e319863a54b521ee1e23807df9f2432b5004b563c2509","priv":"3846cab8eaa4af163f79dc83e5968ce0a59b7cc2f6f725767f70fc1780c00599","pub":"0399eacd20a2a7426a0946fba205891d22fbc041d264372c6bc981c3e7200995ab","addr":"3fc8f92413e731f59ea2768ca40393a92aa8dbca"},{"mnemonic":"sock real audit mind page price rocket home economy glove water rubber","master":"205d5de977b27ef90aa092c70456b516aedb62bd164fac4e4ff638be56d9b9cc","seed":"129afead267c2a9556c3cd3618a29b659e98d651f52259acb1eb4ffbdd6e61d87ecc487123994fe4eec4f65808d9cab6228f8054f8ba68c59a6de8a1997bf420","priv":"94f20ab0cca31de6ed426a818e8cf11299b8112905d0bbdbed79de137337983c","pub":"02ebd561df3cbc137540c7b9bc0c919021d4c4765a9f602078b028e469dbae397a","addr":"0103fbf9c8f122fd4ac6635f9178154d66b619ad"},{"mnemonic":"option faculty depart orchard foam orient seminar detail castle warm pink pen","master":"90dc715ea43f91c4777eda4e9c1dfc9f909c2cc811b55575410d21c0a9fddf4d","seed":"94c306f3e3aa6e991b0f9a8d42af67d058bd2ef0ee233467ba0d23936bb0e982029a887e6b1f9bb9e537ace50e2235a9976dd79b03555cad90da5e73aa0516ea","priv":"ff6cdb1cd48968c64608ac08be92e28f9808fbaccda86c1f5fd6d905d49dcb5e","pub":"035162c7e9506539401c3a0c181643ca621f5abda005f6aa14792fbaf44b862edb","addr":"d724d1f5b4a987109f0c84cda0ed290d88e7c668"},{"mnemonic":"jacket goat equal source proof congress potato solution rival lend finish bulk","master":"cdef2991efb462f091fd3c4e092f8926a4f5e18d6013c5545224d3ecd8e61821","seed":"01e84e54b7faf2374a4b4bb4e56f07d8b13f0dbb0191c23fd41b4520c8123f26b526a463404ce264283c0f3d41c5927681b6fa388d9a91274fd693fa265fab69","priv":"feebee90172106d859d545187adc06732e188580754c96311d9acd825c1ec9f4","pub":"0305697df9f3fb6796d40145316d8f90ded12e8ca18a5956651ee96ab26e69001d","addr":"d0955fef013a29bc7666f1a4696eed57441e2633"},{"mnemonic":"canoe tiny raw account weasel fork still mechanic cricket address squirrel void","master":"9382c4fa09665993b8803f3cc92913c5564be40b63b1c19c81f8f9dd415ba83a","seed":"5c12270e9fa3ca2a008729b1d5fc1a8dfd52dcc6461969ae71d2f3fe04a7c59dae4faec17f84567afd7bab3c5934382ef3d8bc6dd6879fd3af22bbf30fa84486","priv":"9f1d4cffae3c7ce9fce5f987e1439167273c83b6b2dacf1a11ed66c6053c2091","pub":"030a2c97fc8aa57c7fcf7d21c29fbe00ca0866e58f64fa56a85cba811445e0ff78","addr":"48b6bf075dffc6f03e77c67b3f2f573cad8e28e9"},{"mnemonic":"topple recipe surround useless elephant fan gentle wall since street enough harvest","master":"353c700ba61c0b56bd7a3a65d29d53e17bf99abeec68fb79c747ab006592c331","seed":"9fcd29b6b00decb8c8e2a14d5695941854cb391bc25351d7030587a09f64e92bb409c4bb7429329504c19c7619212c731216fd5568dad8e2a1330fbe6efebc7f","priv":"c900c7134a5b92a2a0d3bb0c117c08dbd67f47f7562cf330d619aa3c64b7ab6e","pub":"03e60ac1d0a9ea441a821a780d894ccae6ffacc207ab39ff905122d435acb17a31","addr":"4202687424a7c883cb1dd96353e7dc4697f35f3d"},{"mnemonic":"any myself dizzy magnet hand drift garbage reopen fiber great stuff burger","master":"74aeb0c2e7a7655668238f6a090ce3657def8df96d7af744ddc52d4900451a6e","seed":"0e0a18cbadc5ab76ef4194f7eb069f266ae34c854933b3fa9603b4fa39dedcf219d73e3b283e08a067fc994d46bc59e1c42c18a6a5609111b8fa690edbcf5d01","priv":"f426009813fdcee2b4cd38966e6214f9559426705621ca8b862d2a4cacbbcd4b","pub":"03b75491e3a05b32aff6972e720bd694ef496f6a753ae309cabf4e9b5adc2fa6f9","addr":"5e8c4290a5ab9cb6af1addd261ef37ebd0e6bdf5"},{"mnemonic":"spirit draft dilemma cause main admit thank slide barely diary humble enroll","master":"cd538c907349401ba6605eb1ca7923df44a30a049d5cb9d5a42f0f66a5cc5f29","seed":"baab841c07bf90c8b1bb82c56e355fd6de5a2c93e86f0f804a897ff9c391712d2ec5281582ec15337aadf1f0e835a8c98c42e86a4869e0e1ec47c063fd19f04d","priv":"cacbe0003d96c8263f09f328663ab1b5c74cd6635504b778ebf2d7d30dbe524c","pub":"03e71d9a3ca15f3d481ceeccafe14e6ce1214cf854aa245bdbe28e2b27d2d40353","addr":"f4b073ca68bc00077027a2793e7d6a24dc4b9434"},{"mnemonic":"state subway clip baby novel broken stand soldier among fringe track wrap","master":"0fc4edec9e5891d61e74dd1ee6b52f9601010cbf2bb8949c1d38339ec428bc88","seed":"46ff0c2553e5494666b6de0fd8fe734a8bf523bf6953dbe8622c66c7e9645670624f85a3ef2e9d090e9b153cb5923460cc1975c481a5c2868e51cddd15a9ca35","priv":"4f92a517fe46051132e74178a69f94a2dcd9a1120a54e09188e7d243bc97db67","pub":"034c0b78b452dd0fe61464dd0a44facac7ba28f126fc2a60b82f82efb8cd153349","addr":"2da2b5a6ccff13b5281582aec90f4c9ef28293b2"},{"mnemonic":"nation shuffle siege easy birth motor also family infant siren upon warrior","master":"506af6e687482c47562e38ac6a41e46e2291d777fa0f7abe53ab698065f03f17","seed":"6a4cfce60d546e03f17f6d977ce6d9dec6f4cf8b6a85dfa3070a34ceaca022c5ca4c6f187f1c23d720078c41d540fd04c56bd5061efd027eafa9dd8e650e745a","priv":"b9354ed6da16a0cc9b4404d3226de88048b546f5a01375466aae09c53af3cbf6","pub":"034c3ef56d2471b16f17ecc3e1d8695e0b44057fc8ccf76625a271487781c735ef","addr":"41b9aff0432990ba791b76ebc13af27c634d4a51"},{"mnemonic":"snake manage joy opera creek dwarf wreck merge oval rule elite coin","master":"02a8c9db54ea6d54186726806f81935dcbf6b5fcb9e91d03ad618fbc9f9d3879","seed":"7d6db7e19c66ac1f54395a5a4f7d878e19c24e0cb720ab2a146e2502b4c6832efca2edc2d3f1351cdeefb53a53d66fe64455790fb687234381c017fcbf692265","priv":"76d273285aceb1d4686167749496ae591df991af93a8c29bd627747bb2dd811a","pub":"0208492167c3478e65f8a31f051961d2ac809faf7777dfa7296c54cc3639de71ff","addr":"b18dde1cccf8095ae14353ff4ea995b5beb01dc5"},{"mnemonic":"edge aspect sleep design jelly vapor car blame dad pizza own possible","master":"7d938db55ab464a9ca1e9bf65fb4de0e25addf0ee2e0faff2fcdccaf209de40e","seed":"2d2530b934297fdab1c193d6aa9b93eaa1ea353e776a8b89118b31273f93c2ae78d7b98f02ce1cdfb8465fec0a97b29b563764409813bb4b893a3683dc9d9bba","priv":"c183cb66c406d72e64eee84dcf330e61514028a82d56c56490c4aa09e26dd987","pub":"03e7b33c7123aea9ee99d349eec2603ec7c32c2863034fcb87df8399b73885c97a","addr":"2e8c251e27ee90d6b8f05fdb2c7c51f92b277f1b"},{"mnemonic":"cancel confirm rent key glow confirm indoor chaos flag curtain indoor float","master":"0b49f5cae01e50cc4c05bc466ad91d84ea13896d93d468f951666726de9ccf1a","seed":"aa4561254b44e01ec6b00048e4346754b6626000cfe8e566180a99cdf8739c0c76e16729ee4c73b055e7c59f5ad30abed0ecbc1499fed87ee75cf0cc89f9a087","priv":"7c4e98bcc55251dee796fe3960a8b842322c51da57fe5cbbccb997714392016b","pub":"02ffec93ac53e470bbdc2dfa89c2389a1db404ae6e57e2586b5e638e1397a85f00","addr":"c69d4ef8ebc35e8a418b00c7263295052191763c"},{"mnemonic":"become search judge nation inherit short history resist luxury moon garlic protect","master":"72a0a669e55a3058f1d20be19571673ad281e965667c6bb7afe83e3e89f0f30b","seed":"75518eca5861396c14bce066dadee8eb5f9a74e7099cde11cc9b0f1cb1fab1df87b5fbdfb675761868c81dc7dfc805bd2e425678b0a562447a6684160eaa6264","priv":"276b9a47745eb9266100e62f8ed8f8fa2ee3e42e36ef8e010109acbfb667c1ea","pub":"03a596424477e9bd2500b20cbd0290feb0d30b755562561c52973edf826bae3324","addr":"933df39b013756091a3455104d61244fd16085eb"},{"mnemonic":"profit execute broom clever wing noise crew purity steak assume april leaf","master":"bc7e3bda0564fd300d6f0033fd13d75f7bec7464ef692bc96f83e7ee9427c6ff","seed":"353344a63ebd9a6e78ded4cbf52a5f29a64cb7c1d90b001d764f5f4fa419f569181c07f8bcca22117c970f65d6f9c06b44e934ad21257e0f1bb500f8a26db987","priv":"9120e0b2f502a6b5b5804fb4eece7754ed92a59fe482a7a1b4190213dfb60457","pub":"025f809c0f6a054c4b875c7bce8791f23cc9daa6a85558d6cd48818f29d6b978aa","addr":"f25a6479cee5506bb53b4b06fb326a508ca77abf"},{"mnemonic":"menu library ten glass coral taxi prevent learn pelican garden magic busy","master":"7f4687dad9ba781a99edc31d78a2c68875f40afced8adc8a66d55efd3f68c169","seed":"607827fdd6fb239229b116e73be3993a6596a09cabfd19dfb9b03482d052568c5443f4572393b0e9d460a05832c5fc41e811311d9bb501c43ec75e234c61785d","priv":"5605ca7fee44c088165aa3474327c53dcc13ffc73d8b4787a8b0dcdcd7fdbf3d","pub":"024d754ca81f064cf6dae96fd1344cab8e917e46ec639f677eea33a21bb34462c9","addr":"663ae3370a5b68058dfb1b2efa62f4a2222b3a89"},{"mnemonic":"green useful pair bulk excuse mixed train talk genre inspire much eyebrow","master":"318169a8d80848ddaaff93bd0fc68b1282aa8f5e6f058044de6ff82c62446005","seed":"2095e4cf4ec5ea142d9300cf431e47c6ad401ab1693a6518d5cf7950d1d5d7e0c6feede5a29b3721924074ccb527cb962ddc5745b46b794dddb4ccfdf31ff1fc","priv":"e9c336d9e59b1f4c822899ec39d256174521097060db24f305e3d4c3b12c35c4","pub":"03f44d7d4269f3aa14466483d80ad483af1307387170f563222e843c554f215b00","addr":"359955417cbda69e538cc001d5aca0bc59a077f2"},{"mnemonic":"follow half desert universe canal guide pony two fuel nuclear pull tag","master":"1f3ffb60e2293ecf146f414b28ca6a81dc6768c34450f2907eeca2851ebd92b8","seed":"e692e2810049aeeb25672c3d07a411940a7a7308e9a2fed2a67210d14dbc1de2258edba62437cdef1f913cbc65cc8040bd52f601c2edc51cc7d4744dc1781147","priv":"3534e3fc0a973dc314ff3610ff02c07a1a9e5f2a2003f8ce754c691acf172565","pub":"03e7f0b65a215a8d78831f05f10db86874dd0d900059bcbd64d83d08b05d8a5f7a","addr":"dd74030f9d82c0c40d2798e731b7c5eec61a0213"},{"mnemonic":"enjoy chief later rebel avoid emotion kid reward find patrol leopard destroy","master":"0c8eadc9ddd4cfe9b2c1759ed1372c513bd5226c1aa4afea02c8273d226182c5","seed":"d522815571acf5953d4bf6894c9bb5274e876a5ecb13310dc3db73f2d55544174d744cbc7d63a6ea07c8b7bf8bdcbcfe161ac57dc0ee488ed9fbe0d21a070d95","priv":"92e9da2b0ffdfca29c83f64a685f6f512eb291b5b130c4c5c506bf713016859e","pub":"036161fd5b9ff9bafb22e61860d1d3130e007839939eb3f609352bc73376552d17","addr":"015b10da504e82eaa290f2f5057a2581db032f51"},{"mnemonic":"giggle medal hat isolate congress else guitar below chase federal absent photo","master":"eb8a28df4360243f9dac597fa92de914aae4133af8f3a18c2506f2fcdaf4945b","seed":"95e8d77d1709418b4ac0b8cbafa302e2019644eedfbe52233ba988b55f5451781583ecaa8b1be51ae18e17ee5bbb35d3826302701588555dfc8c851844161acc","priv":"35da7e9dd8200ed89f461c484e63ff3ab68a9b1cb162bbc3331394f4f2ab8793","pub":"02bb24e03a89e6a6a7d318effa8ab645c46e5dcc4f25c3e4d75308144b5d2a29c2","addr":"2c271833daadd196147eea05df28dc41314a27ff"},{"mnemonic":"use protect bag nut fault off absurd involve ramp cereal symptom biology","master":"0f5a77192d1a941ac59a41773ea7d6b4e87295f4f82fb0f43c5f12d605afd56f","seed":"7d74703c2442bef350254d3dce2303a8a56fe4c96e4ff80ed57756dd7b8266e566ea2cbc3abba9c724deb9c45fe4cbd6a8c8bcc4bcfea2665e5193b781aea933","priv":"18c64949d8fb6fd392fb4846c119eb71a6021cc1c22991706fb776e8843a381b","pub":"02b94512126ed2d6412873f61bf16592f02df176cdd4c29fcd70085fe3d03127f9","addr":"15e94aeca2bbd591e337d57152663e25bc094747"},{"mnemonic":"tool twist jaguar excite borrow social sustain normal echo fork alley hybrid","master":"d6c9dbbbe44afa97a5f6365066a11a8fff48793d4c6720ecc419bfbb81329202","seed":"164785fe64846a802a9c134d094447035eaaa6cef2eec9d5fea9aa74d333ab31433c7cfe4b712b6a3b04048d239101a8dae5cb4ed37699658725bc2186ffbe41","priv":"cc5c6aba1301195af2626001e3d19660043377c75e7990063aa45ebbd30ab266","pub":"02ed0554dd8861043aab2105d7dbc83809193c59952e829421f7b9b6e9e56d6f0e","addr":"7db5745b47c147e40ea9fa2cf54488974d0bbc4b"},{"mnemonic":"approve bright target voice relax control knife again special future anchor crystal","master":"332ed66acc5c24c6a19c450775329c946197872435d77b0ea594d4632adb04eb","seed":"da2c0f3433cdb37ff151465470bad3b227114c46ddb025542133b4c10d942bce6cd34726c85e638fa82c4295d8fe93959069d35253ee528fb1724be1d95447f1","priv":"41a2cdb57b5cf352256bf9c2b155016160c7eeeaaa5a3ab2f06cd1df3e4bd695","pub":"02e76d02ff3fc76c21a995add6962e08bddec4abe23994668770d6cfd02cb82f42","addr":"39dcdc76bbd5c2ad8821cc5df8e816c7293a82b3"},{"mnemonic":"like wet pig pause steak name tornado else limb february secret subject","master":"e7dea9fa8e88520065302d4227d84a3d4226aac4b7c04bc78dc7e68efed73002","seed":"3926c7749d953ea66414c369fbe3f26a7a3f442ca98a277dfb362eb74432cbee32e44a6174f1e3fd16aead63e798c894d88ef260747de219c1e8631d800c13c1","priv":"804cc7215bdd8073b9c7f8e1ea2648724ec3e2593f1c2213875b6e4022513ae7","pub":"02770a43f589045b52ee29065b2cbae37ff65a0ace98c88531b4cf88c94c3f977d","addr":"cf82c749e61e9961ab72a76cbd3f71e0c5a46221"},{"mnemonic":"memory core ice box board flee ivory apology acid warm sugar resist","master":"4ae1d18a2c3cdc0c4b383d20846866f1a2ecb799e7d2c5c125e81c30856a2bfd","seed":"5922aa04496cda9a17e2f474805f095fa2bb70cce0857dcf92acc7737af2978145cdad0aefcf201fcb5aa2666a136b2eeffddb5476d9d49c0cf0d76d14bb332b","priv":"fde667c98a06017967b9169dc380a7393797486d07bba6575629f0661465a67a","pub":"03f8e990fabeba27ea70082b69628f95e5b86cedc033578426995bc1358949466c","addr":"efcaf3eebd6ec30c44fef92eb59327758eee3334"},{"mnemonic":"vintage rocket today version chair avoid mean play decade sport frequent magnet","master":"d167f9af9105ff115790c4d31ca48e4ce5cb3b571b4596b8ee78be5a6290e3c8","seed":"af58c0eb0e62201b926ab4c04d67b942f6ff40147ccdccc02a3df295fe69ca661b2a23fd2cc0f9148c4e92165ca9725014ff0abe5cb7acaeb513cdda359dced1","priv":"33b248b4a292ff6f26455859924eeb646290cd54a2cf587c5527e2f432fcd6d4","pub":"039802bdb2bedaabe4201344c1e9276d1981f403151e2cf179e4cd13861a54d568","addr":"c9ed9bc2778a33e5712b90843f1b0f0252c5c3d6"},{"mnemonic":"crash lazy cruel match youth note deal rack gym robot work pioneer","master":"13a82f0a499ea45154151ad95d52c3f15d84436c21d734b5ea105c902f85559c","seed":"c10e386ea97bef67bd97e59c5da37442ffc968893fb80ade82097b87a76dec5ae128962a4d69737a31eba4f1606e030d4c85df6733dcbb03e209a4b7931660c2","priv":"eac145103c713225ce05ffb862cb921797f9f88d48628321162798117e37494d","pub":"0260d3fc9e0ef5e8c38e3de4da944d59cc575aa530dce9fe8d95fb8eb68d6a4bd6","addr":"07aa44afcad33d8abe6e83da72d6d556a3720924"},{"mnemonic":"distance desert squeeze eyebrow episode enough sorry gym still label mansion thunder","master":"0f686b29302ac0d5532794598b98cfba275e4fa3dd0bef15c0b0866bfa0c9c0c","seed":"9fb57b9bb255323d11b7479bc34dc706e42e6ae8bb3f3af212b0807ebc9fe56a90a36c92bd17eda435fd0ce87a0465cd10a371b44dfb2e1531c14c29cf8ba466","priv":"7a140972fd7e2499dab8e22a52b0cf79c33ef58d1c5df578e30515e627f044a7","pub":"02332ac4729e52ba3ff4344ca262726bb58595670057aa967451302bd19579e8e7","addr":"f7c0cab3704f9ba669e318d17e33b1b5a7b3ac3f"},{"mnemonic":"zebra useless blue insect radar century lumber clock daughter slight quote stadium","master":"1168c3de22b717bd3e840b4ac6334ea707764d25bbf7ac14cd5d63ab127fe2a5","seed":"df9f562a972569f8dde2ba35e53c97c536ca3bffbbdc990df8cdbca812747887904a4f983d661035de0b3a85677d0092edad32ef528c926bf31541ba63b8e019","priv":"282da5f2191001a4bdcdccbd0000317ce62b09c0a48626b4fc2b45da6d7873be","pub":"02790696da42d2b21cb031e9b77bf855e2f5a214f80cd05618181433eec02fefb7","addr":"68f483b9d998b9250d320c43278e423d0394e8cc"},{"mnemonic":"laptop pepper arrest tribe glad keep behind gravity ketchup scrub bottom parade","master":"06a978fb60c517a506d2d8fa17956f144d1a5d57c0c9567320d1b21b8e7871eb","seed":"38c05886932cf2bca3cb7732e92b4086ca0575db2deaa241a0c9295eb79d50765a4bd92a03b76255144f71bf6f197c4b5eb6e3de8dd6e6ddf6d15ad18c90de35","priv":"62c37a4349e0d4edeb293e50adfac737ce73e3e0370439c561d117bd4ef23f19","pub":"027d978c9355669fab1ac4db17cf12a103f7501ca2011e022110d5b4398810039a","addr":"6e0cc4997d42b970855685f8c9a196b97b2d5ace"},{"mnemonic":"alpha slogan usage lemon cancel cruise rice crazy laptop donate city fade","master":"e3bed02bc801909cdfb1c65b6648f4df19b8927199e3d0f069f6713b13f10123","seed":"9b73467192fc857c552d60dc0223e3c4b604cb1cd50adcb61c9aa723d245e3ad44cba7f99f0f24fddd0c78b1bea41a86e682c9c482b115d575b9e3aa27f5650b","priv":"7b8d2c22c398e4a046da94656232cc75cfd6fc0e0f8191b673414383901b724c","pub":"0279989cb1f22fc08f871d023632a379d038bd9fa902a6e46f8bf0a780637b4efa","addr":"a4d3a5579aecfd9790dafc6b4e89972933c46d1e"},{"mnemonic":"chief runway cloth craft depth firm task ready credit multiply program smart","master":"d5d076659b0e0bb061736956cef361aa1a6a0ad6a337a6ccbf4b76a40184f405","seed":"8e60f22168de4f2a6c9db805a6485379d2facd7c99dc36981d0e209746766233d5d5012b03f8556195737bd71b88fc54eaea0f68e4fae4afc19c133f2ca5fba8","priv":"adee70b6b1dfc264606e0b1c848f7b5deb46de4af91c5eea9eac962dd085bb3c","pub":"0226458b01eb1e4f0d7901841662b2046f17e0945230a3b1b2d8a65aaf5ebdbe8c","addr":"c9d9042f15ecfb29595ed4769b1c858d1f627468"},{"mnemonic":"invest glory debris naive pill detail sister cattle physical favorite squeeze rice","master":"2ffaac06321f9aa3783155de5197448783583c027d8aa9d9b787d2a07b7a4c2a","seed":"3016cd4934eca835d3246cd7c05ff35a0ca5e3e0c4b74bc70aa31582a6da334c0f7e91458bc049ba3469a8aa7f216d27d44ec8ca4cc5f376ea366a38106c7fab","priv":"cfa4b9f12156ae24e632f318be54072149006db7a4a611403afa97c978351900","pub":"029e3e54ae265087ab8066bbb7e935af291b3ef5120b00f44019d9dfccec8a4e9b","addr":"3de09d0c1ee046365da74449b6c98ce3205e20e7"},{"mnemonic":"private alcohol loyal depend force sand twist couch beach report miracle abuse","master":"8354e18ddc5b38a6e26f9cfefbfd4b27ce3f65c91174c88143d947104ba91faa","seed":"507df1232f5cddcbee60de019cdba03e9337896ae2fa0b26855d48c34a9a2cdd1e93f2b66e965cf7666bf7c7ad11f00b1ff764b675a5c3df8a1a17b253cb9e54","priv":"d486cc9a23d56e1dd8d865ba042aa5cb9f8ba06107988e1a0d999b14da3b667b","pub":"03b75ef54ae8faa3f3565fd6301ba7a70114ddd184eefc74e716fa2e3c2df6c2af","addr":"2c82b93644c227bc66fc06c922ec1566c3e11c9f"},{"mnemonic":"memory achieve vault hip prevent category cactus aware venue dutch raccoon fresh","master":"16bffabbf3a08959dc9c1780781133e6aa096cef9d9542606c52e8ca2ea0230b","seed":"a4824f3efa0c730e3669acb08b1cadc25f3f63943983bc4f4f1505cba5c85959ec16c2cab98008d10e22f3ed6239e3182bd9b603ae1536755d222fc60f91419e","priv":"7c2b66b79e2e99ef0f794147aa93d3da8e62ebab7ebaad7813b586ea5db28f9e","pub":"03298a67eb59a27d636c2aff41d73ec658c87b136ea53a534ace18fabb76486dd7","addr":"89d5007339cb57fdb72ec629027583b8f3aaa5da"},{"mnemonic":"alien floor comfort six demand helmet light actor distance success buddy burden","master":"36ed5350c3672be815eb365f61ef0d0d42870b178aa34fa5c5b7397cbb7ddcf9","seed":"ff46b78794944b4372affad3f096339f8d9c03631335d9eaf4e4fe68a8fd9d58a6d6f37ba31cc06bf57c5b66aaad6ba64ed28ae4188195227fa07bfa587f2f1e","priv":"3bb1328f115390ade3c08de4f9672ae96bc3d5b783bd9d26d7e4ec12d5818b8f","pub":"02b37bccbe6c7173937b3af482d4a92280b670d715e2619fb1fc906973bcdd4d7e","addr":"935788847e1517096b9f31ccc2ac48c2e5a738ec"},{"mnemonic":"soul upgrade rebel wash hour gain lady side own double immense merry","master":"039c6373307aad9366dbaf9bc17e70ec1b5fedbe382b9bddc55ff606baadc0ae","seed":"37f9cc349c21182a3b34c66ae099de84bdcf30ed20160c7251f43f831279834dccb95745207defbae856c0a38dda3d7bb251b97cd2150c155ec64c680c82ba73","priv":"377f589beeb549285eee37d34e5ca85f4e00af8483027afb655e47ae05d1089d","pub":"0266f715310d9fee40c5c95da1b6a9a9aa51648df99326e29399b10e9cbcc51f7e","addr":"89a2ac362b8804981ecb6043bbea65587c997f97"},{"mnemonic":"stove pyramid vintage defy belt high have leave comic brass online caught","master":"eb9be6fc059732dd9eff612f2e4ed7121093f07889b87e8c66e103b83724e1f1","seed":"2537a9ac9dfe5c31c0f40c69c9fbf6a8ea186d2cd6c6d2134aea2f3ec2f28f5339fe623ff593da08857ee84193c54e204049009f8c86ded026a4cdca633b2b9a","priv":"a8f4ea6ba49c421a7d310b83bec05902cf2f2629a3845e390261c3917af3a17f","pub":"038a6d8d8947723f80f65dee0ef8579dea5678b67bd258ca591d0ce5d2ec060bb6","addr":"38d61629cc3e3ce7a614825cefb125ddec897b59"},{"mnemonic":"uncle seat rate acid ketchup frame marble limit demand exile wealth dinner","master":"fb1b8ac2f5bb56231fc93615bd8e25720818819d3df4ffcaf63dba0e7e7a0815","seed":"8e0bad11dc7784f19715ab90e8846e84155680027997fa0314fe32efdb3c026ae2918740d362744dff754e75b1d54050f5f02237cc4e15aad165ba10cc7b046f","priv":"cd20e39179c66285edeb6df646de54f3510f166bc1821349d779fcc103f13839","pub":"031a9529a2b5da261bb540f43b860b540490262b10aa09d419dc3b96d2e9aacc75","addr":"d1b6e238bc4a7e63e0a15f034deaf1a5b5161928"},{"mnemonic":"human benefit idea stone hospital misery warfare door goose unhappy crowd stadium","master":"b8b5781ae12ea6db767cc01d644cc52179363b72a7b67ee8d7d20fe8ffe4f41f","seed":"fc3f6e420f688e8553a2cf8d3a6a7198c5523aa6e3b00b3e1e4bc352288f0390951bcf698bafc12334522e04979fbcfb36f12fa789a85dada9909304de559193","priv":"ca41478acdd4f0413a843cec85b2abff69aa53b4f900da10918810b89127faa9","pub":"026096644513086624a2ba26daf7da0e4f5c7455bf852336416737fb72dc1137fc","addr":"e57448e2edf9d63574db45ae06510a521bd80522"},{"mnemonic":"violin cave ask subway session gaze settle pledge decorate alley swing evidence","master":"4c099f1692bd7137bf8b50e51d2f6fef0236f88bacfc4c87f83fcdd43a3a1aa8","seed":"2c3cb4cd88a4de52badeb41b1e3e1d61daf61369d5badc36601c4baad611eec459a0a1edb4046cc21ff50f396688ba6bd37fedf24b17ae447b6f7ce4b0a7e81e","priv":"5f1d6278c5d244334eb10d71e4e642017c7d3d63076507b7efc9c63c8c7e5df6","pub":"02c26860be7973c41ef183ad6ffb901d07bac225b5fae444df8abdc605c7a1efa0","addr":"fa055b86c6a1da4666ea4345e9d98ea32198805b"},{"mnemonic":"dance hip come square bread reduce ask riot shift twenty scrub derive","master":"964f2b5fb6c3f11f33ee1bc9db915d820834cb1ddf9cd35c17effe93ab3e3e14","seed":"bd4b3ee7b0042661b560cf39f8a9f8fdb70bb75c7482b09b296cf660e2b6360b52263cc38a1c546d0f935f0a156a36089975a7fd5a65ddbc960e4b6418e1d337","priv":"6f9b31f5247941f3a0e3954b05f77d68c469aaf25f0755293b1fdb17bcba6478","pub":"03a3cffd72d5e6360090e4a0bfc8e1c691add6690614ee5fcc7867780d686259de","addr":"95ed911acfc3d1332ecd9c8b93a4372a27911cb2"},{"mnemonic":"excess route notice shadow post business cram kind ripple odor enhance future","master":"ab1d6e993bb9b533e854f15591af9e8a74bd29d000d5c8e77b98e3e34e96fcd9","seed":"4ab45c5fa427c0c81853c3b5c2754ab1f54873b0bba3710204fe40ac69c13d21ae011fe9c835566db313947749dba53496f84709b71f4dba08a7db209922ee4a","priv":"98e0136920ca7d3844e7fe1cff54db7229be2412de8de831b94235e8ddc2696f","pub":"03714b295b752de7f1cefd195578fa7257d5dd8b47a39e584fc4d2637a8f730d1c","addr":"9019db50e3ad4d56ece94e7d5067b27a33400a4e"},{"mnemonic":"flag maid oil survey first force grant equal brick dog where strike","master":"85c3230463b78c924cb57ca637b5af3f5910d962861ead4b16af5de1b4be274b","seed":"6203eede1ed8164b3ab32049def751b55d82ba6807d97b3eb094b4e6327ce732a54de31a9fc6178266a4fa7e6452b004d89875694ec13ad05475d7ad86ec3241","priv":"1aff198e964909f87d5b15c1693e5d191b9444109a7ea4bb58952752623e77f2","pub":"03921265a585b1ec932828f58cbaea6ae709c7f2af0691ba3f2f0636286119bcca","addr":"7f38e5412e9011a5ca91fdae448bb8b15a6bc4bc"},{"mnemonic":"jaguar panic thought mimic voyage able inch pole vacuum twist velvet pulse","master":"f7ded49975e280cc791687730225a70a89c79f5245ca72a7e538295aac1ac710","seed":"52f058e84e0809ac44c37485ce9da088c1617f05e92553a073378a0a0b3c9cc95aabb6d1dd2c99d084b03afb98024f9381d958f6ee5f516baef2db97c493009c","priv":"615bd1f706f7a88d9816200f4c3085ee2c748f9a42b25b444393f8cf2b46191c","pub":"02635816dcc956bbd8d9d2ebe94fb117ca20907a238c99245a9635287404d30e78","addr":"78105acfd135889bff6f0f70c92c38e0eaad72dd"},{"mnemonic":"pond stairs still avocado rapid peasant direct debris spice cupboard pledge budget","master":"6b5a25d678b4fb67cfa80ca3ab21cd6bd554e5434c4fd362ddb01cb46bdbaff1","seed":"69d5e57322a46cecbfe1f895c1b22e9bf17d418a06b73d49e3fc83012ca2649818bce2310f1b195c5b4873d31d6e797c5edecb8f30377f5e638ba1b4ce2f3823","priv":"9aea611859425145441b6455a0ee206327c2de06e2d26974197873f2ae9366fb","pub":"0236498052412d5c5dc3ef0d195a2a537359fc44246fd9c8fb39478caf29e668cf","addr":"faeac1dc66f281714303d637666c09606504a227"},{"mnemonic":"december cram web moral spell comic tag lawn since helmet moment act","master":"ee67281243cf2f77274bdc4b91a2ff1e660197bbca2fb42d5aee60e6f55ab4ba","seed":"8052120f630a33ce44aba16f1807236b1330ffa6170f985c630532fdd2713aef0e1d681699c4f67a9b9a72fb0432335c243828bea29489c92d1b01d016257ef0","priv":"a98bf3a99fff927ec2b0f208bd8a3a586ccc2571fc6333c57f2f1b7c22d2c8f8","pub":"02743cd05cb536e2384da4e0f110fa4f807abdba3e5e25e426e32fc4b5c65f761e","addr":"a1f0b4bba0be62c6b2497826612303892ed77b05"},{"mnemonic":"basket tool pink steak antenna process accuse brown walk pretty only check","master":"ce30c7daae3e0a5293ece548d66f07852003afcc80874474f5a94eac4a00c928","seed":"9572350a5a22b4c0f95fb2ce61c1f5e5846a3c2fd6e4cdfb2aba0d05e04e5b67f0fb394521b73836bcd4555cdda44acf0ab7ba43b475795868a6056295967822","priv":"edcff07e74dc83738075605d76a0c6923dc475ab122da2789b5a195a421c354d","pub":"02c03e024e6f53a1676dccd7850cbb2bc1f6a9a85b1da7cf0ecbf1c653a60dae1e","addr":"ac3c8907bc31fe66155a47a37306ff7b75905133"},{"mnemonic":"since equal mobile pond island before crew boat clean behave climb good","master":"1d1eca07fe5058a9dd7b26d1afbf2f4f71acf1420dc4ce9d2e3959734c442f36","seed":"4167279cfd447453ee7f46328bc40b4961f814229cd72762af278cf56a8efb18211420cdba43ccb06dfdb207716390df9205fa880cc647bb48455f437ec8e4da","priv":"60622d64880831974cf62d8f65be9e4d89e6579e6e0f1e5351a10b7574f3615a","pub":"03ba031ce6dd8976cfb72a2121165ea4bc0a8cdb14082504a05a917de09bccda29","addr":"50203affa88d87f3b104e237058807366f33c1f2"},{"mnemonic":"inspire immune poet penalty remind mule crawl drill rare fork track creek","master":"7c581d1907fb46fc46e6e9b81d83fbae02a75a2ee50a8d723e24700b530ce917","seed":"3822ac35fca2e3b5904e3284deb5c178b7c64ada6d7dd31347ea302e76ecb46d4bf926158016b76106ca61ae068fdc594808a56aae5e39da7893592310c33d2f","priv":"6f87d364a299b42c40a641d121a255228b62884d6f2d09068a384f7c6b515831","pub":"03f217a49a2068b2807a4f0500a08dbc7bcba6ffd60b0fe3e4f381a089b74506f5","addr":"c4a20e80863522069f8059e91bb1a162a7af7356"},{"mnemonic":"inquiry exile okay attend enroll author forget essence script conduct apology rather","master":"609da212416c631e8701b1fcfda5c412e0758270daa7bc796ac1492045a93a5c","seed":"4a75975cb2852f8dea2ef90535307e0a0063985a1c2347db1edc25bb96dffbd880ae88e8e5a21e91b6c26cdc98673effdf0ca84f416a45950cbb0ec74cb7fbed","priv":"c2e4db33ed61ed9f7a2b1452515b971a1bb20dce3b07efeb9437fe6ed481c9b8","pub":"03fb6407710ca5408d137faa85f2837879c4b0f4df59182a3d5f002e49c34c3bc3","addr":"c5217c9cd9af8ceff8235b2d127ef1cea8e94e35"},{"mnemonic":"entire diary route emerge moment only lounge situate expose hurry hip mosquito","master":"a919ae0bb832affae8e5269efc47936b6bf3e487740f8bbd2c286866a2224762","seed":"e97e0456756e343a7d56b1edf7468419f8b431c6c850299b382d3d957fff7c48f86114eb5640aee13d245c2a34d390850ec43c427bfec555d40a489397376340","priv":"eff22ef90183b533c5267d9c19f29f7a6fc2c44b45dcfd4b440181b977087585","pub":"030cb4259aefba8429f5e3ab0009e080674e887748e51ba2e0a055d2df3bc17589","addr":"d5db282d076f9d474651970abe5d2e3fece873ed"},{"mnemonic":"ginger glad purity aware siege tornado seek orbit sniff spawn process surround","master":"5498d52a17868a0fb5f1d2416277fa1a4220ac3a498f18f15e750d1140c57f86","seed":"3674479b527c4f27b578f0609f800de86a46591eccef6d40d3ac4436ac8c92ff12659e1e404af552f1058e9f17e90efc160903fd985f5b8069c66c9f6708abc0","priv":"5fcf38e09f4a3665256644715fd606ab60d9cd62f4c22962ec94b6fc5fccdfc2","pub":"03da1b1b03fde4241b05adc19515eda3ea96febdd5ea0e8f82dcc7cd98f1b74029","addr":"1186fc924724531d8ccc9f9ffd49701e62056c52"},{"mnemonic":"laundry reform post update crime page snack another boil pet cement primary","master":"3b1c3ee0d63328bab055d691bd29179ce5abb933759fcf83912adb41ff1bd9c9","seed":"60771d2e964301990d7ce6de87becd62e65852a4da9b819ce3fe28d72ab0e4619445d934172c1fc9361d2176f4ccc8d5b9175f4e933fd5e9681d8e8b177fadf6","priv":"755dcf792c67ba8a9d8b0694d21fbd33c51fb7aea67f05d2c8b0f38093ffa7ef","pub":"037118c561ac7773ab212b899b57f5527b77577a39a4f413232c8e7c6a33f9091a","addr":"bc2e19256932b58fdbbe5ad809e30a3ab2b2685a"},{"mnemonic":"pool bean dilemma foster reveal renew exist bar sick spot bulb trim","master":"4d1399a0181de627ea555f388952dd5d2c7a7b83e1a618fe8b07b03c1bed18e3","seed":"d788888f57bc052bf0d35abf7be1175152aa607b901d1040f4a28c8cef343f0fed2031e3bc9e1eff77eeef4e024234466a55f70150388824d6fa10051133a464","priv":"00b7f71d77cf0d4e13e51403c92aa66ba543e9cfaecd810049d17794a4c0ded9","pub":"02319a6d654cb42a231f7d021e2cb7c9ea7624c37d6ee32b218d5ef79a31eaeb46","addr":"f6d78ff49d6f12b82e24bdd77bebb536566a39eb"},{"mnemonic":"poem leaf scrub bag bomb palace discover pear rhythm treat negative system","master":"4bbecc45fde87cb80a4cad7a4b08068265eb8c12d4ed36d1c9a9a7e5e73c39ac","seed":"efb6bca601760ffb2b183bd4cd2e84a864eda3bb4b8b1369095d3df69fa7ead0b8bfdf5a097f37bb4b1ccc452cb8935baa165f7ab039342af64e9e50bfd51b36","priv":"c4988f397df2821ee196f98e62e4a1542e53ca1e46f966a4d13c4e3e389d8937","pub":"038c8e4571f8f411827ba778340beb7bbc29fb47af998a852da29b4f1583d5c600","addr":"67b94e1d532cd8e42e5a74cbf20f7d079f42055f"},{"mnemonic":"punch twin village ostrich frame goose dance history valid mountain volume high","master":"f9ba8580f4d53e34d9bfd3b6a2e17c5d8987c879945df9bd20407d3f8144b108","seed":"07d40cd18ec6abbc351aa23172dfa6582ed83d5bb24d5cd830d7cefd23d8a2ea6272efc6686606e61507d5a793b7fa06f83bf73504a072e32a002750f5f240d0","priv":"10222b81cc386d25eaf5037fb8fbfa9c401c1d192fb715397f6636dd94e9db3d","pub":"038b04836ce19b454a0af260bc1271ec73f1a0998d8659e9cffe38fa5e4d696a77","addr":"55bd4a574aaa1be2c02aa2eb40254f8cdda7a682"},{"mnemonic":"ready embrace photo find orange curious essay pulse frozen earn wild travel","master":"361e9e44283fe7d3bab83395ecb8373dff5d0a4d60274695637cb02955523741","seed":"ab50c5ab74b1ebae85811108c372651ca8d275e7c2b5d0fec9f261966395482f311a76dd297f2d2997c6c59247807506ed20f524a32dff90637956cb7868aaed","priv":"1ffdff9fd05b67d22f10076595e0025800a8d60f022f2bd99ceeba93681372f4","pub":"03b168906d5b255a896509c8ecaac4a8141d22ebe005e6dfb2892f6f12970dba2f","addr":"a7d30e12ff906b2ca0c6df3fc68274e7e30725e1"},{"mnemonic":"pass paper cable blanket meadow talk govern admit busy base hold broccoli","master":"db0e45010140df4a4514284d7ba78ac7a5771ee15820856afb1d15a4e3b0af7a","seed":"521ec955279d92fae9dd8dd43162ee216798f4a0276a2c98b29dec8dec9bb26f17e6a49ce999ec55e061379166f25116c01b8cb48ded23c3b3087dbafbfc5371","priv":"b5bf00005304278d5e4aa792de142a6cb46bd6283ab02222de50cc2f01009e09","pub":"03c188a8581f09d9eb14252f8d1f5cebf1de8189526992889115c6edb1cd180090","addr":"0f8fe4fac4fd85d649d7e19d1773897aa6e75f43"},{"mnemonic":"weekend infant spin powder hurdle pupil disorder always excess unhappy price decide","master":"b1bec76f3cb15f82e5c9c65aa23d0871ec06a590a3823285a412ec9a243b1c1e","seed":"5a8d16dbd0586561cc81273ee320c6c3d51bd90bdf08119ec81596fcab24335193b33fdd621800daefb49e038ee079184e569b941ef5d839987dc1e24f578039","priv":"90ffc2ec625f528045a432ddae8d20017c9b1a883ed22ed403783e10801077e4","pub":"027d4213cf485f4eaf3ea06c61057f92ae8fde8362c3b2f4b167639b74153db673","addr":"c9b1073f122b5ebd155d4904cbc32da4281bed6d"},{"mnemonic":"agent seven dry cheese rhythm raise junior sorry spoil tag opera bench","master":"8cd8ddb8ad3f12fa347780c4614e38198a51c00bc61ecb572616382d6f8388ed","seed":"ad6641ad541b411261101e5f76036fcddd8af62de1966a3b9a1122edd1e6057e38fb5e129c86427a68590c87cf9410fc14ec08dff184742a54461c205018f43a","priv":"f15efc08c8a578f7035a672fb51c2f6929e169e5ff37802ae8b50f1664c025a4","pub":"039926cc43000431dab0f0f4818fa024ddcec0ffe9c483f8ec294cc863f5133574","addr":"89846353e3a3becad919620dae0a2d22d0533559"},{"mnemonic":"floor sting insane slice pistol blush follow muffin acid coral aim make","master":"f65fa0d49225f5f373eed6d7d6f9f8f73f80840c6027c3871645679e51f2dc81","seed":"8782d6395c27d8b9a3b0fe29e44093e5150c9b82bfcb6344e6134e954c1240cb33fe8c9489b3ad3117f5c112f02f0eecb0e30efa36db18b27003df5e542face0","priv":"de11f15f7cfb0038dc07ea2007019c17747e5138cd83b37ad30621c9f41b1799","pub":"02b662800bbc56c144f6b39773bfb4d496c9f1442900b59641aa94c6b50a783fa0","addr":"70b1ee56807b9191f77b1d18ddfd181677e91654"},{"mnemonic":"canal today stadium spell accuse cream chuckle method unfair regret sibling old","master":"90c0af3882fac84793812f44eacb1d4cf13b56863c70ccfd6866bbde1195036e","seed":"c1b4ea5bc074259d2f25ad7338b423c5ccd2083b60f0ecce88f7c5d4cb39806f2da873c05cd52729ee07512cba3af26f21354a3769350d5bdd10868ff46d8e28","priv":"9ff9156b1f137d20b486ea125515fd7a2f057145fa8313203606ead961ebed84","pub":"0225998b8535e9f2e269e86caeca1ed90a86414d8c449011ea2fd9a488b7097528","addr":"40f33af234da7de748b02a01687a5e60429ee07d"},{"mnemonic":"object sure already seat attitude great winner session cool addict direct popular","master":"86a35c7ab59d48a897f6b4a78221c8acd0850010a063ceb912488352fa19048f","seed":"fae4348ff7c42cb1ff8542bd19721823917037d1cb017ffaf64547be8ad4b296212d6e952b2af66db8541c7e881136aa76e17e4fed926064bd5edad8f25e0dcf","priv":"2df0f9c67615ca9370f8ab957db6ad6cbcff1b5353f745dd24125ad36d7c77c3","pub":"0367582dda754c5345514b2618d0844e83f8fb49ca39a70d00537c70c86b6519b9","addr":"128a4f8786a46bb7815e59abbcd85bffb526e953"},{"mnemonic":"sudden more spawn have pig observe embody title collect junior sing bronze","master":"c71aeb48c73d6ecef04597f248dfef9ebaab37e9df625a483db1e883a972a36f","seed":"eb1dcdc3ecd77652223ccccacb85a255f350028a843bed72ff96d4e3de5566f667af1d5fd48aed32d2e580f625bd258cdcf6760d1089ee3f9653375bb1139f9c","priv":"455da9b7df9d00ce53973439b23a26a75463c9ce0bdd73eb16a39e019d7786ae","pub":"0327c673e375a95e13ab6a940c18a35874331db2c0abb283736890b0ed1a09b79e","addr":"d173a47de381e714e3873d1e0ac05ef526b0eeec"},{"mnemonic":"world gown final mind dinosaur stamp unaware apology foot flavor hockey bamboo","master":"040827137019c4a9d29c1d65849cbac940ca0dcdac2ba8def0421c990c90e2e2","seed":"48c5532c17475f0a4d63d76daefe7cf21681b32cbbf4ad8cbb62b6fa872411fd2b8821f8f2ea97cd9004fe4585e5ecfa27ee6c46caab89145c3b0b4b7ef5c073","priv":"d66195156c08032f912a71128635b25750335aab186aec63ec9a83e9b24c55a6","pub":"022d8790106436a60a3b74d10fb07e06cb48b2b13ebfb81a608039d80e9d7c1e64","addr":"fa08eb0d89958302d67d4de8b99fe0c53ddebae7"},{"mnemonic":"bag bridge trip improve blanket machine asset boat mask flash vicious pig","master":"21df138f80902d1ee79948ca3836ecc29a0f9093b06a240b29ac7c3aab89750a","seed":"99cead310304d8ef58b23fd2b9ce7fb71386111ffda2f609898bd59289862b6f464ba261855b1bdbfad8f7ea25e43adce10f7386cb6cbb744ee05772b883d176","priv":"c82490739f0d969706299c3ecd89e4f47d0247471ad2d3f7ebba531b8d6804d4","pub":"03dfb5455095553fe24c1474c5a5dc0fb69aba612b79568486345f73fe27d36205","addr":"020c6ac4996d1c91b2b2894c426dc8e32b083fb2"},{"mnemonic":"auction okay cousin sick accuse steel limb staff tube gold hero add","master":"5bc8d22635bf6ce1494c820527e26a94c57f6987d6cdf6d40825138c3283e6c2","seed":"c7df0872664b4b4b0a7deeb3c26545380bc61fa3734a20a82c96e73707ae975b76b12f31da65e863040b2215c34a4e9f525ef38e555757a9e8a42a20af2f78de","priv":"0bc4a9bd3b88ad78c34a309183da9a0efe4d8e27d098282e3bb248cb960e018e","pub":"0200d5e1fe0707ff11dca2c30a0ac83bfa40ebbb7e51197993c6910312fe91d75c","addr":"72ada6e822ffed23ac5ff5147a22537b984bfca3"},{"mnemonic":"trip below tourist offer burden hungry later grain quantum universe service group","master":"7990e7b10c0c6bc95f45933e8f5be1e758e7b7b2ee39b8caa00e8ca50cc66855","seed":"a96ab2ab3fa2bc2547cb20cdb3e39eab2ce9dedb053277c7802bc0bdc4ba9d08a3860b48325c662de187c935419211bb64ca07448988f903cde04eea9f0f6e68","priv":"6d922bc8eef11400f93de7ce47b55d3e862ffece29fa666ba05c778ffde8d91f","pub":"032567a2ff9a50d1c4e6cc525dfb96da1edefa91fc09c32ddac3ad446056f1ad7c","addr":"abaf696230fd241bfed2c76a0452456bb608c17f"},{"mnemonic":"bacon together open trust hood detail liberty bean spread awkward antique minor","master":"b96abff8fade8664e35d68c78f7609f1c8553a02b80c81857583df0134513370","seed":"772590bec2194f5b552ffdb2eaad756555b22e979ef0463222af6711c53d77623ad9c34abe48b7389e67b10e56aae448e9d064e4be58c5d45c4de16ad56599e1","priv":"532a98d8be2812f88057a91510a20ed4e7fdcad022162e3d3dc14a34104859ce","pub":"020020a4aa457c2944b3c333141e9dccf1c500bb277b846d85a77141f69332a315","addr":"3b5c6eb43438c07d8591e7c4aabe8d4540490bd7"},{"mnemonic":"bulb jewel comic drop copy wreck unit engage meadow hurry acid thrive","master":"c0755ca5e91d4ec8f6dc7b2582d65dc70786a3ea67cd40dd68462ce13535ed61","seed":"e808525cb5c66bf4080ace7b3ff7d6454d07723ec23fa16fc0b3a346d7fdbf71dfe5f383c13d68de5b5f04cae47503ff352ae340700bcb75f2ed6f0eac3b7c5a","priv":"4f592a1d10867d00b28197be6207977e13c9fc551449d05be284642c43597132","pub":"035ec6120eeb601d6b3b444e066252a4c917cefda62c49c0ecd6384c1ca4db826e","addr":"35f84051b0a02090acd509fc801b21864c45ce91"},{"mnemonic":"devote guitar planet kick now above act sponsor account blouse divide horror","master":"1d5329254a9cffc9de60eaedb1735bc8b25c77142a9ea2098e8227ad289b967b","seed":"462b9b3d13f1b1e9e802525e3bd5e22f97a31b352240c9457c1f6d5f194c6e7b7bc37a4fd2607a27adbb77dd837b9114606c8dfc54d78a1a4c8f703889a2e50f","priv":"d5a648822e5c20ee1c56ac5b08a54e561a392d540d3e964499a5a970362c3829","pub":"0381ee04ec2cd440ee26d5a37c3775047e0215b2919736e092c2aaa7152ae448fa","addr":"daf4d242b80955a2269006d530ff6826f718fca8"},{"mnemonic":"youth error panic brisk panel hobby mimic nasty address little original sense","master":"57a151782b47da723e7bc39b13200bb9ee0c3621e839e179a92f99ced03d15ac","seed":"600441626b7035ce2b4e1a90a872ae2279cda57d8f8f44ae3c99edfd0e23ed4afb3e1f4e9b01eb5cba5cafff6a650f2d586d1f0ad85254cc99caa47abab30b4f","priv":"08030c2dd269b5b60f12ee6bb27aad68d3490ef128ca704f390e283ab608203e","pub":"03a38f69571f6187ce334833b798fc0d32065fef197f5812e4c392de54fce4bab1","addr":"02bbd2f05a3c4979db5ac72246d7e620e3edb769"},{"mnemonic":"age excuse wall torch dove enter movie almost build shock blame object","master":"cb4958fe22c8250f41998f6e869eb6cff240550af2db41d0b92e9bb64041469f","seed":"bd585927d17cba54ff5b2b63f2a98267d197ef07caf6a82b3dadc45bc5348d99dc7dac59e45561e55c3513a62ad1942ae2763168562c74ed808f1a59b32a64e3","priv":"7923cba208f6bc84ba7eb134836b96b69bf1f75330caea0be218df31885cbfb1","pub":"0369f14dcd228c164170d5187c21d092b4238386e0c8231a132cbe41e4ba315df1","addr":"93a1e4c78f24c08c48572169fa949001049a6528"},{"mnemonic":"expand shine stairs delay calm soldier deny volume whisper island topple cross","master":"0467b91a321c4326fec8f39cecfbb2d273e628837044815cab899f8debb66376","seed":"0597787fa9ed69ce29f6bfaddfbda091c7b35b6dfec6bcec23957e6a547819c320504afb3ed7a7c5636e4496271d2681891ecafcb9a93ec71bb7b5d9dd06c710","priv":"ab2422cc32992afafc497d2aaf8e4ffb193aa02a5574b0be59cca80566ae8a91","pub":"02348311d8c7310491aaa1f3bfba7945844cff5573ac8b5788872f594e20746830","addr":"a1d27d518ffacde5dcc9a10ade764cff42399996"},{"mnemonic":"sense palace seek enhance hold exotic sense pyramid program fuel deliver heart","master":"715d3a14fdee63848d94f9269d97fa562301f6899487a5ccc9d987c8eccad3ed","seed":"e80766a81744ba87d4faa9199a2b6d1b829256aadfc46f3b647be1788cdf324f8a4ec4ef52af07bef0d60ee090d3c2f45ebad582eb326b688366ebd7390df61a","priv":"7cd5560b3928e4048efe644e39bcc1eaa9e8b783c0f3f0ef5904e030bb6d63bb","pub":"03c7759ec461940a6a3f90b4380286aff6307c2ff6acc234df44aff978fdd7430c","addr":"0d43f6bbde0c5687561d8f5d457bfa78581b407e"},{"mnemonic":"poverty defy mistake begin dizzy behind annual olympic glad behave coin rhythm","master":"eb342d1dc891e285f0d1822af5e00ce3472b869c73102f87c008f73099448ab8","seed":"710a0f8ebbefb347f83eaf54d2977cd64e1f90d4f8de33c8ff041f807d64e5444707432877ffb4697e2e554d1e5bec48ff7428d13ed83433c4200b7aa6bd7c22","priv":"6c36c88b1168a478325ad77e220a77f10a2c8933fd72a2babbc918cd683cb265","pub":"027934c90cc3c75daf4971ccfc56f672fbe33f86c852f648afaf260989961be283","addr":"d60c6edc1bb9b47b0f2baeddeba2723e61aae00a"},{"mnemonic":"artefact vanish security tooth rail claim drive black push ocean special uphold","master":"08d1f1528ad6dd4424ca11825ac1b47111969f21b0285b3bfca9a2e28aef095b","seed":"add463ba53586dcf678b32e6285d40dc5502f91c3dd1128351380f52a28d08b9ba747c28aa85164b342e95b44c1ee03ce9c0d9029979f346ab6d9dc3a614f7bc","priv":"e22dff0eb96c0599766b81a0399e62589bf6e734003e45bbea048ac37c8c9bda","pub":"029954b4e87d373729575ca9b1606c566108753e12080de2739f64ea0a9b881ed7","addr":"0c670a5b8b1fe0a5e43d7efe0a905f67c5ae47c9"},{"mnemonic":"supreme correct virtual guess funny grocery assume dash blush rubber wage chaos","master":"09eb5b5fab562805b57ed0f1a96e66d56b8e132d885f39cc5d76094a4e169d91","seed":"994fbf31e1213b7c113ba0b47563afe37de2acab7bd17ee071c04b1616c6cb50d853bcd5203a9a635fab9dcaa07f0d9d4168a7303fdb53ef41cf5ff15db83704","priv":"1b56d4fd8c5fc994f22d4c7fc856aa18814f269c0f43fe65b52c914a186ec265","pub":"03941aa1d30a3122695e69b6a7f8c94edf030255255a33d82484f90c491dc77f1b","addr":"ebb17b37332f0079728e9de0f2b40951a233a9ac"},{"mnemonic":"pyramid insane eternal man arrange earth predict panther atom fashion claw present","master":"25ad3023a8597a1960b1e6411d75a821d86000ccb3e92a66646017f56dfe65b8","seed":"56231905c46f23f005085a4618005b1851055dc3f639f6b1169189c9bedf1bec6efa219631c333f0cc488e06a0b5babbd781071b7327dd8667bba0467b6630cf","priv":"0a4413be4769217c1f03bddca1fa921ec7935b473e9f13ab78f2b377c08198b6","pub":"02f4e8d8f9f165017e917b9128160fcc8232e03a7d4905583e60a76d3e532bcccf","addr":"d7356ce66dd427267edffbc7d90b1499edb2fb61"},{"mnemonic":"enlist pelican teach loyal like false property ski salon kite thunder gossip","master":"4b0285f521bf09632466c22873be5543b1c228edfdeb25838a3100d72c9bab6b","seed":"9c0e2337f5f02183d2dccc181372e47f8d89c3ba580e144fd6bbcc4d852e49d4f3f093eb1e29e9c0a58f84c6339033b800af15f212b01e7c60f8b89c3525f180","priv":"63a88432a7998b7af6962bff643d46a1d8fd7d4076923eb4a0f76a3038a7f26e","pub":"0284e4cfc7f7513515d97a68efd241f25c47d0b88f57b5308e508141b27b9ef2eb","addr":"2ae41ce0a0a995d865357c09749d94564f91ad65"},{"mnemonic":"congress like unhappy run unusual citizen flush force welcome arena clean student","master":"478229d977380296130a0a3d61be2ed2f8423ee7021544c32372beedf9e8c955","seed":"ee65535652c8733c881553f9ee7b9312a5ffe999ab40e12fe5a7b54101bdf8bc078de75d8dbee815604ebe1fce0eaa7104114780e074d4907297d29c1eeebbbf","priv":"caf650347982b40bd75eaa1830cb5d0089bfc011156c927ddec0fd90b333f590","pub":"037d33ba4e7bafde02969dabfbfe3397bd6744f1552da1313ce129f49eae410396","addr":"a00609d65a4753b3888416518cbd4c25282f355d"},{"mnemonic":"science reject slim wife shove laptop pull hundred genuine method canoe globe","master":"c011d8e6c42749fe6f7d1aea4b04b0d6e618650b0253710c717ece6d31005d05","seed":"40209df29de5baf4dd6b82df091404ec2f1b61f47bfa5e9a23e6d030848d8bd958138192458d82dc60c6c46ec01bf77b5c447e7b2ed0dace4c668d08c86719e3","priv":"058091efb05990cc436342cc3ef6efb2d0f02fed6380370d60255d37a2844939","pub":"034048a3e9bc89ed545de8f2131437838e7fd9477a7c3fba98032e2305732cead0","addr":"dba1207953cdf07ef09213624b99ae24780e8051"},{"mnemonic":"hint where immense cactus sugar entire stool accuse suspect cinnamon pipe car","master":"620259cc620b3b806fec360f2e9b84c4c5b94f9ad34c53b40debd1181e2da675","seed":"3332bd304e7a5b1120a80ce1fb74c1e0554c2fc5d3c007fa58af862c4c2450d9a1fd12c90ca6be5dbf9b69131eac8804fbe0e45ff433bf4d2f634b527319458d","priv":"536ffb48ba8ba6872cd9065c0d76b511a522a7e3b38c84ae16bc3eda2ef49e6f","pub":"038d3d8f70aa9ea108a19076d0e90cdde8d302b709aca1129eaf9ec281672b8aba","addr":"0fcf72bdee5071ce4f241e3c908ab5b0b969a37c"},{"mnemonic":"load loan mail real squirrel gossip fluid wrong amazing own post exclude","master":"c1cfa046473eee67b03ab8be8519a26c8cc72c01324d6a7e6108f3993a76d937","seed":"0f20d1b5e5e93bdb2031411be4c5590f977ca1ccc4550d7c8d8211a62221e6a5c6f34f7f99edf1f785811703a3540bd2f3dcadb15947cd4181b6e80fa988996c","priv":"b0dd0c8d5a07124f574ed87b406f4d51a77491d78f05ff5e80569741c8f044b9","pub":"03c403433ad539d2bfc212628180632b8d860172c6ce4ad46a3e94ddb1657ae889","addr":"145995cd3905204ca68f23c3203d5fb6d6eb8fb7"},{"mnemonic":"attack zoo topic note remind direct inside budget section outside permit inform","master":"ffc2f55b2c123430dc29c09fb431b125b5a3f321ed0ab5f64b179fd3358b0e02","seed":"693b14c3a0b6c0854971fdb5edfe2b5e5d3d37e524a96186d15fb0ab23f6d250b250f5c23a44d28ef9b94210df582d85c17208ce468d09029039ac5dcbd1222a","priv":"76f689bf1d6faf5456946bca3b048cfdefe39b74eb3e0e9d85c2da386db80d26","pub":"021e00bf6a0a71e0a37a8ffac002c5d5cc6350fee3dae6fd197a18ec880309fef1","addr":"7249de82b9250af13b7c309d32688ff19e7ed001"},{"mnemonic":"practice hard harvest gift bracket panic weather crucial have play reveal athlete","master":"cbce18216889b4dd4d2887fc924e98ccb5aae1e9b5d7433c120c79ec3ecc0aea","seed":"02bb9503765066c4e711e1a78be25e7b49689e107f58a2acb252b1c16dbb259db566a06213848fab833a32e34ce565788d7af30f584c21a21f02ef30dd2878e8","priv":"e6e7cedca2c3b1306cb06addcd2a861d04bc383c1579ba9d044a5c752b1b38af","pub":"02b11ef0b566fd9f429f88385507d63575094bd21caf8d3653a8b829c394de0920","addr":"8c0edef9f59b632305c72112f160e9c3616e3ebf"},{"mnemonic":"frown mix normal orient tower hero attend occur blur ship ball motor","master":"87c9a61c0fe1e8760393b18cc556b8f6d1d4bef0355444aabda127b342865d67","seed":"8e35626433f0913c1799adec7b23de7cf6d0689822d3a2f8d1bfb6ab041c80db3e5703c96aa09ed0db4e4f72097cb652e6d01d065bb6ab86f19e498793fb44cc","priv":"47b7699713fc59ddd67a556639c3f1ec0783a3dc3424cdeae4335707a549181f","pub":"0281ee7c3669207a68e189aca625e1b6eaabc909ae611a6eb2072f51a6f26d545b","addr":"ddd6d8013e5c4f99900cb22184075afb7842acdc"},{"mnemonic":"beef apple unable rocket balcony tag tooth spin sunny innocent clinic dice","master":"6b08fb53a185b5da79434bff6de9b10c558fae63beaf5f487c36760da44cb28d","seed":"f06397170fc337caa0278b2324f05095d587887217f5f10b13b04e1286158e4fe6a15da54c7dca729744e268255f4d04530763580ac7d660b323a8e8fe163753","priv":"923e63fa8400088c1f464357746b9e95560c23a755427d792aaffbb73551fbd1","pub":"03046ea68a2e1930e531b00376a4254da2a1ff0ed278aa800af2fa17cac40021d4","addr":"3ed4b79d2755b7d95fe1626d26a2b674a927b3be"},{"mnemonic":"sadness frown tape chase swear cushion eight funny sight dad solar civil","master":"af805962cf1c7bd97d0e4e981d3157834a17d3dce23a426c299b128685f28bec","seed":"a6292e7e8f3a502c4eefa0cdc94fda1d528642e084f45b30840e2ae9e7be636bbf2d67156e3bd352d1bb0750fa4df04dc5b8b6479c7c98c116c05ad5fe2d4d83","priv":"0bc87cd2cbddab83294a804fca193a6bbcaa3a07583bb2dd35619f325b70b7e4","pub":"025811f4948be5336572285ce58c97da84e5a4b7c542180933a1f4b6200ee4ebe6","addr":"9c6867cf41071e1f7d84ace3d2802ee46a1c08ec"},{"mnemonic":"bulk topple anger gift matter soft dune hotel dutch guard cycle close","master":"816ece50d6fbbee470de36fbcf646a83d224dabf5ca206786202f59ee7be8831","seed":"4980fcc86c5112625b63300e007a26287fec1b2a9cac0e254a8f43c91d897c03a3663fee0b351fd877171ce708b3fa471ba67290d6ad32075f0f6be6d3f70ec6","priv":"51cb46ea5db7c500388df8310bc5c8db7bdfb7c797030aa8f4a262b53f82a904","pub":"034e93f88a8da10122de23e2b25eeaf19aa1df514293b1e8fbdae2ad9fc2782779","addr":"c81ba2724c2e99a7168bd74cc79e222dd845187c"},{"mnemonic":"account lobster inhale champion relief scrub poverty tornado romance build amount exile","master":"202f11a0730b769f90d0fa68b81e9fdd78be483e38a9a39c447e8315d8f9fba3","seed":"001ce5c310547070fc2169bf0cb7353b90e824c051ea9f285eca426cb7f2527cca995865b0466c86a0fb3e208dc1ded076d2b985c8557dc7a94af7c6631bdd93","priv":"d142d2616dfe9e3aa43634a94a05707a8f0fa58ae0186bb565ecb87c96f648a2","pub":"02ca5eb73da42320161564c42520ab1a4b5823805bdb4dcb44a4abd88a235c6b2b","addr":"4481e257f1cb7d8105823e54a1b8d0254745874b"},{"mnemonic":"defense knock simple usage cook shoulder alcohol muscle pigeon balance become sister","master":"26df035303f63f356b451e829e154cac27e3f0c1686679c784d405455adfe5a4","seed":"44955b360a1622c1a69d20315b5fbc982502903b45736acea4f146c2cf69632a99630195b1166be96e4c90449abe1cddfacb3be63ff2b7fed02846b0d9244022","priv":"b9dbdb8952ce34d5f575b8b012a5e3041521efb893004f45eef2c01eb4f5fad6","pub":"02e9a6d02ce5cc1c14421c3d6db53d16a048e0421128f1ecc1e3e41d7df9d4e609","addr":"4e78dfe3fc045b8f65760a337ba354e01851d82d"},{"mnemonic":"bonus surface unlock noodle genuine stumble juice purchase grass table call piano","master":"16474b5955a793884279a9936804299a953427a38d5bead30553ec709bf42c74","seed":"da8eae0d3aa27a6ef6637dd17d57fe98e75619837c3dac48b3b546152d5fb1dcc4c59a86f65e8716c82e3014ccde5779e6e33c2a2658c71424f4ff9ea6ca0065","priv":"c9bdbc26bc788147d12c4bc3b13ff3774a7aad1ac66ce45e742c7a96eafa2a5e","pub":"0398102ae1bffc71eaf086b652c9bb847dace83d0b3f87d91ddacfb1702762cbe0","addr":"f0ead6caf66523b7e655b4ffd26a8b35f0b09eb3"},{"mnemonic":"envelope scheme knife muscle museum town valley until quote interest film keep","master":"bc01f4cbe286c6ad87553e0ece0e142f49984c2676ed1fc5142abb75637d47af","seed":"89867eca31ccd75983b064d62a1b4061d1f64c1731e25e08c65259139590490827869749ec30e8218e593e2ecbd4303984dfdb7b15775a487ba0eba84953a940","priv":"b5c899498ecb94655e622f999bd7ef9a2c4d26c3f555ee6888e5b4e1abbce1e9","pub":"0316d5c61149c0f83944192a788b5b64b9e6b1ce49f2604db67e8e4f16416ae153","addr":"b2a48800c35e6592ebe5003a46883a00360e2b44"},{"mnemonic":"also genre defense valid point smile hybrid radar lesson sniff one recipe","master":"3cc6fb6c4ddaa98e3daa2e984189417c55c1bfec4089397855f809659f9316cc","seed":"e962b4cbed0c3d5232f75595e7aa3cb33f1b2e093bcf9a21a4f8c6dd9677aba42161fd8eafe38fd12ca0ce3cb58d4d26fb7d349b1a160bf7f6f6b6c56284ac6f","priv":"420f0121df8cbc367e966344fa28d913bd1c3a1032efe5a3627d94039281e98c","pub":"03a61034ea8ffde7a239db255e414008c8e913a1405a34d9a606108f1943a7fa86","addr":"5976e21c1f85766c535011aac79e8a5f8b0f08a6"},{"mnemonic":"flavor spy elevator parent theme become slender recipe media pudding suspect melt","master":"4ce14ced0d4121d342d2c514755ba73b17eda70cefb20efa5aea71ec27ee47d6","seed":"0040263c29e5d965556054dbe7a738ea35b46775bea5859bc2e5b3872c89574e4f18de3f6fa36df65f47b13417763dc8c020b498ed3e9f11f46f019815bcf9a2","priv":"d2a1436a12fc9e4f2acce77564b8ddd67c1107d525eb6128c1eda078d3d8d845","pub":"03246bd048416493a970d97130d54db7e263af82dff75cc9fd0cf1e061f5d3f8b1","addr":"7eecbc8b6082d62d5fe28846a8ddc20b16e6a9c2"},{"mnemonic":"path number useless federal birth such peanut rate swarm flee current grief","master":"01d57fdf15aae5c1d45349fcb7bda6ab271c15be88429ebd1122336b91937540","seed":"061d0906c096a3338ac0877a102b4bb3b375ec5b34809838dfb47b186051a0a66c98e0d4a4dfac2c02b86266c4574c141f7a7c9365a57449ade60e28aecdbca4","priv":"9eb30cd9489297f0c4793df375a4a497162c5b75c36feb0a979da41000cc842e","pub":"03e036866bb847db7570ce0e2459d009dd1a89eea3fea8c3ce4f1f47c4781e32f1","addr":"139b3c7e7cb476da573548067d0a29b5abc111db"},{"mnemonic":"observe layer grab few fiscal omit clinic manual climb cloud song million","master":"cdaa9864952fa51a5a10de9210ea9e0199875459304876fdce150f042a415583","seed":"fa2c9dc476532ac66ec8e219c69883cb9645129765b4698b7f2010cb4b86b2d25ebd45e6c582a9f886c5fba4cd4d7488e81d705e63508e67c1698b77b8e6a676","priv":"238ae189645958242ffc9b3b868d78bad1be7d1351573298aac47ee78a5dac41","pub":"02ba7dec8131970a8f4a837bc225fe1e8fe20ef90b6363c058946930fe6b8cf629","addr":"4aad44c69095bad1588eacbffcb5ec324dff7563"},{"mnemonic":"solid business era limit engine fringe recycle harbor organ like tiger avocado","master":"afb951280a835f1ed21d00d478a644451e254310701d8a8025f5c716a5843731","seed":"2692dff98bb318f1f583e4f5d87a453b9e1472781b38f3b6a19784f8fd3e9b156ac6a292f8ab56e1da0967e159438b87b73042cbaf3e9886ee2641e7e97dc821","priv":"4b4bb7fa92a26e738da657b31ae57c52f057540f1371066b2570fb247b2862dc","pub":"023ecdde05d734b6ac286c9b14e1577f691f114b6554d0f1b389fdc37e05af9a55","addr":"5402fb7a4751cb34b261a2a2be940d7bdd3608ff"},{"mnemonic":"convince thing assume midnight debate end best cause laugh sweet unusual present","master":"7cf2f1baf94a8487a364a742db15bef15d1d1a7583ea26dc575b0181357e31dc","seed":"1e267ef4dc1099a438a346c7ca4c546149d6a57dc4cc6623ee160677711144583245125cfdbe45629160f3da711fbc57171564c4cbc771b1fd2a21236751eea4","priv":"9eea5ab5b8b22018197fd3c9256cd21be7dc26a111c60bc3d853bd977a19c90c","pub":"03e17aadccfc20dc41e65f7256717c54f9eb3898fe335395f25a65d4a96cbd93c6","addr":"85d9c9992d5351d84d40790e65c29b52b929f7bd"},{"mnemonic":"property youth river offer mention cloth mention pride opera repeat hidden orphan","master":"7e0faa6a216e4ae162547f5c9639530abfd56ff2026b4f18219d1c82934ab2ff","seed":"dd9faf30c2ddece69bb5d937c9ee58172564ec51d760fbdfdebe4dd445f1819bd6cc21a2a4cb70fa94a0d941d994d3ff58331be94f57a16589cd7a93c19ff10c","priv":"fa343044822d07308bc523eaf778bf697302cf8b88a3431bb5a0a51974a43199","pub":"0383e1d8186c1b3d0c567c91966a5c7aee8a1492feba372be735f9a612c1910ed3","addr":"efb2221453dfd951ba456f1c5ac164d3faf08032"},{"mnemonic":"awake virus civil cash clump equal phone wet friend attitude ask act","master":"87a61b5729fc2e294da66541b79085aa3f67c03a3eec40559111e68fe5a80412","seed":"8fa5a84240149f39dd60a5477ac59586aa05d6809adffb8184e4154dad74c2ab9a446f296098c44fac8c839d3405e0a2c1edfc26ba3aad9665e6b6984d320fbd","priv":"726210437d3054875e785b12d1aa23a8cab85a0a809593cafa9c63c62e6e3c55","pub":"025494819085e1d08d8ee2d421e4ca873682c69446ec5a412d7c7a7520900397af","addr":"e26e023a2aa67a3bb5e5988be46ff266722c0153"},{"mnemonic":"snap control problem flip minute huge lady elbow plate fall cabin trouble","master":"931052717250728c04dc605a8cfcc6a49a4c520f9fc343607fce57f5ae7a9e66","seed":"f55dcbed51a9db2ddd39d1164a81049af71116896e79ced722a387e878d00633830ab8cbfe7ee8e16ee612e1e047fa3d3c2a0fe230adc6a84f0178fef6aedc61","priv":"72aedd9eca0a5f17b3c20866d6d1e98bf01a1b8b9225bfb1d93f93c594726ee0","pub":"03c07579c66433d1b676630a0ddd343167fe91419a14a7859092b6b7f81341dcc2","addr":"37b2d898f165d5cca507de65f103231ea5128788"},{"mnemonic":"wine foam depth wise faith parade tuition search demise skill boat survey","master":"5001f6ff67ae2a32088e0ad93a227206bd66f5ccc7be991a27b2809354050b03","seed":"d889ec2bfbc930c78f9a3fc356e0dcef9d636766af361c8492189df1779bf76f4890d738106132cc5202ee97b849c9928a8934fd0b40d610a38f514953e3b02b","priv":"c19f1ce95ac35938d19d41e45d7122e8faa102e219188d681559d4db3f6aa66e","pub":"02331368ed143ec22cb1af2794bea8dd5e5661b9c6b1407bfbbdf1c1a151250b7c","addr":"a70e3677cb94b449a400c870159dbfa448e137cb"},{"mnemonic":"picnic basic you priority gown town oppose penalty various half follow nut","master":"59f5a86a5f6cf3254607f5e9846c7725d7cda493ac9850042de3bc7e8902583a","seed":"85645734c0caad6d0f3be793f71f08f2b87cc92b515e75abf94a202941c45aa78f663b455c91b6d51de40284d9c26a5336d444346b408bc12d8690e541a43583","priv":"17efc82e851c2938c22527638f4f3ccc2ff16ab95c24429c583b6f68d79ac948","pub":"02e534acf511fc86761ccde5eed25d793831cca6069f09694467a3b7434cb3fc95","addr":"d75b0c916f2329006221b040901933b2bc309838"},{"mnemonic":"enroll shaft young ramp moon message echo piano advice time blame mandate","master":"02f99e44bafc4e61bc3afff77696bd72af71ef05c86dffb2bb3bc241dd60861b","seed":"6e1cccef229d10e15ac6f1d2b2a579146ce011411a6e807cd227f3215c32aa394428f9a11900fe21699ecfd09d5ae6e4e1a30f2778bbdc15fe30927e32e1fa5c","priv":"8300a73d51449f909e8d0dfd843aa4cbcc055259f7deb54f40bfcc41acbcbe2a","pub":"0251fabe51d7eaeb45a7c82ee6cdd100f338692d796e7f1effe6a705cfeb21cb71","addr":"ada0f17f1854fcec548021ce617ea90a05a2fc8e"},{"mnemonic":"remind lizard alert mercy badge sustain judge van spike obscure account twice","master":"50a01f4e2adc48491e54c26a8c30c38f451de1d2d8195661eb50f6e5ad6e68ec","seed":"1194a8c42df528afd1b1eb41b2721a9b05f9456b09d042f15884d136c1713788ed8a32dc2153f01b560ad904c93327855450bb93ca8db384cda230eaec68ecbe","priv":"b78c8076bc4378ef0ea80af91addee35557f0fb059c1b434c254ae6c76716ff4","pub":"0251109362a0885fa59ad162e24c8f55cf4895bde354cfdbac7278d69124f77022","addr":"6655b6a665acc146984fd188c3c260668fdeef65"},{"mnemonic":"chief report afraid nation silent tower defy display suspect dice switch finger","master":"472175c2f86fa94d913108eb3842ff03fad950e4c7714cab8ce0c46e8e674968","seed":"c3656bac565a87cf18a1cfd8d488905e4b18436f93d0cf1d61572741b6e0ddfa794ce94a8b05e7796a6c9757edfecc6212e8b0ffba1e71064f67c340829b36e4","priv":"f16f039577d1fd9d6bbc18dc26c03cb37ad303ee1b85468df3de138ad927d098","pub":"024fcbc106c0b515838ce4d32c50ca1ef6134c314668d98a3ee30bf27e18e2fad1","addr":"a88574f43c1bbc38c2db68fae3f73f4244973b3c"},{"mnemonic":"now renew same wolf host minor obvious tape install barrel retreat cash","master":"a75fa702bcff39de09bcdc8f55cd1110c396ffca982d7c48f6d3d2f98ae29938","seed":"6d62aa254ec89ab960c04b4f72b5fd9acc135ad79ce4c9b3fcf25e0caca06ccf05e63d2aa47630b6c7fd3dc274dea540ceb4808eea2032ec3373d8a77b336338","priv":"dd211f6c5037d095da723423be7c1ead08f09d44fe01ffc0b2c0b83cccba6ab8","pub":"02ee58e7d2d8abd00c101024aff3da181d54ab84165e0b5c02e9d53dc336f0d11f","addr":"d9c4235d8222253cf41236382326190cc8f3983c"},{"mnemonic":"bonus message butter logic disease coast transfer explain away swim taste draft","master":"ac79c0b183965a1d918ec19217ce40c6ac1d84e3d57c8d0dd7a0c6ded35f057e","seed":"3fd63c9c7e1745a0f2526a70de96f251f1f61db25e808e3a6ba500e1a1c8e0693b888837cb9ddc1e8d09acc296e908eddb9386b97859bacb10561d12e46056dc","priv":"842e49ff7bc56dc113d532e7d7b4fd4d721f4600af0e67088b6ebbd491dcd4fb","pub":"03176edc37f7b671f46248531479b45b2b6ec77edb92001b46c64c7b88e7e588be","addr":"8170b83efdeca9e923de156cb5da2e3110852c0c"},{"mnemonic":"quit culture vintage misery pilot cheap wealth buzz false donate edit lemon","master":"b2fb8551d9d84f229e26e7874d1ed77ae8066ae80e04abae48ea84f96ae448f2","seed":"2cad64c36d24dc0cb94a2b2dac3ceec1498860ef0faedb78f702efada34c350f6b7f7760b14efc177893797160a838ead20f5a890ab05c477ee70cfa0a5a6c8e","priv":"38d5623053b64b8df44950a9f305288e3af0c411238ae3a89ea45f28f8375c54","pub":"02963af6b3f4add138a3b45b5b8f01bae5e6ba0434d558bed64fff01c6750ac053","addr":"9aecc7332529b0982d8ec14350594438ff5562ac"},{"mnemonic":"paddle mountain rent siege length essence negative amazing soap pitch blame sorry","master":"f179f7a22dd44ee96dc443f7fdccadeef1afaf9deefc8819cf254a554a3332a5","seed":"b408f67dbcdb8089f6ef0b241f026f6cccf85753ae137888e80c47b3267f58902e791675cae2854f556b067915821516fa04e00bfec6cd8e474d29639972741b","priv":"1fd4e1444a9c49ab77235d823e24d70d18b5d37cf9feb550c1e0763c7f9980b2","pub":"02bde455cf78c59409eaa2d98a105b537c9aee34c53486a4247299af90be3cdf38","addr":"46269ed379006a40bd873c79a9526ef076260eeb"},{"mnemonic":"abuse office gather ginger member carbon trash detect mammal shield like wink","master":"bde4ba63249cf7e6ea92a5724ae2f34477e42a8303fbf5c100c85c3d3ab8fc6f","seed":"ca4615dceb4adac1b16195899d537faa0d6e66a243c30accbe4902d26e77004da08873b0899ba21e4233d048c2d171cc8f9e657971f2ba0dc87b843f782ac619","priv":"05d5ce699cfc49b676ee843c9f85e1510f27cd65a76ba4d46eb6db36fc033c47","pub":"03c465fdcfd7441ab8d34244970daacd29a30c0d972b92a961559906f736d4cfb0","addr":"e60e2b02b46ff358acaeba84fadce61d7361f482"},{"mnemonic":"rude depth finger strategy wagon cherry mixed assume sense aim diesel urban","master":"ac83ffb8b0b9bc49758a81e567d179fe060301062d332bb40e353b788bd986ce","seed":"368f7051cfe851c638722e3691048292a1f2a94a83f44ac9e7d6d5a882c822e75ed5116cb059f0a91550b8b2237d32b9a0bfe556217455044b3b44962f4f162c","priv":"4af19a58ee5ea6c6cbaed88cd83c13a57da1c8002b816c833fdda7388adf8662","pub":"021ba0422b1fab7261983106fcaa20a43d8629633c95948e42aee12777181c1efe","addr":"aaccb6d212ff003c8754147b89b0718a58c002c9"},{"mnemonic":"mountain bitter treat hour purity swim panda damp notable beyond rough spider","master":"e48be94ec031c9cc4361550d88facfffaffc67fc0fc5adf495aa18e17c431007","seed":"fce2cfd110d408ed37c75fd0a88fd7513a09a8dc577b38176150f7d2835959f8170438903a78a5d84b32923bbdec6d5069c532621df387c65bbc2a879fe162a7","priv":"dfe58c17756a93be86fd81d3c874bf4ff6c45cbfcf049bbdf999a8e798e448c4","pub":"020d3913b431030aba9c57920708c5648ecdba1fb0111ffcf44f91f67ae92bf176","addr":"1ed6bca6d4080f039a12e3b0e772052231818121"},{"mnemonic":"protect chalk chapter dream icon boost layer couch soccer tool taste congress","master":"c5d0b996ee26e80cd48849482caa435956d87476d3fc5087a900a7e666ef3bdb","seed":"e40c57922c038fbfeb1ea7dce70c0807a55a2c62f58f947d8f05cb66ea7b26131e8b2b81ba9add4185bb8fb72176922190ba2e15de9caf3b4749ad7840ff1acd","priv":"850e9d1840b28dcea6088c9a4837effa1254f48af181d63f660d18f5062964f4","pub":"037859452c974613068cb16147826addb72f11101db03017612d1eed3e5352d010","addr":"3b58443eca15b2061bd5d7b3240b93e012424579"},{"mnemonic":"rubber twelve wire exile shrug will alter violin crucial border drill pattern","master":"15c68b495a571a78a09687a86495141f94b2c015f4c51a9dfbdad96e68c6d871","seed":"ecb81c59dc0464e8ff470db36c567301543b2bd1bdeb94512db63bdfe6632d9c88c1aef02bbbe04176ac7a0789c9579431e732adfbf038c89aca077d14582a8d","priv":"00ec93d9115439212ee358244b5128b48a67645a4f5bf94fdcbff2c8e93cffa2","pub":"02e68bb8dcc584b4e54da27ca229a66d6a222dbce0e187a9330b1740713addb417","addr":"14f8f956d84c53acad6e5eb43e8fd7362d341363"},{"mnemonic":"loud ski diet extra rely melody space canvas humble rain park fossil","master":"1e09a38b1538e950b8ba8472c07b619334973f9075e41732851606645e318d51","seed":"a2d3ffc96f020904af3760c11e9a9e87e8824c1093b07c92a8e6d98c6aec16adaa8ce6995d5d6b58a04824a765d0232ff995183ac38a5cc2bac14f734ca8496c","priv":"18e45a61f9e6ec29019df10abca1878045553d9b924c859fe57621f212133edf","pub":"02a0053e91ce99b2c401fc40cc2892023b30c2db914403ea0da794bb77f69e93e3","addr":"bedc6716f1649fc2ae412516cb0a1d68ec2868e4"},{"mnemonic":"potato tackle almost kiss unveil spring smoke nature agent carbon swallow final","master":"5917e819604fceb3e7c11bfdf6b85809f509f89b3bad6ec7069e8e29258df791","seed":"76d3089d7214660adbbc748f9690b70f7787e9e028fb429086caba19c3b412f931b2768a843ddbdfbb6b6bfdc6349aa0fce1168d124a13d8eda61fe37b407f37","priv":"13c35356aea2324ac57e4c2d605c45020adcd4be336e097dde0b23059499e947","pub":"02e9c1615b710594269b4e86436bae98e4e9c00e7ca0405b89be47c02060705ae1","addr":"e9699c41d2da37635fe657c557f54f51d8e4a503"},{"mnemonic":"innocent cousin jungle elephant speak rent arrow maple danger menu misery breeze","master":"c2dd7273c7f703e2c66974dfd25a1e7091d83a7e6f8ef64954c8b61cfe4e84c5","seed":"32f96dc9661f448f82e2100afa787fa09afe19d90171a3e2d7b5a007316690198a3da22adeb22a2fdea43c3ee98a6ee2bd33baf1e84034d559e6019a30c2e87c","priv":"1e9f48b65f2c57f6af4797a41afba8b017de41ccf6be00bb2a6dad09a72df167","pub":"0268e685815391e6956df39750aa3e9ad8e4e558cba04ed4c136785e2bf82478db","addr":"3ecb6cf97afb26e1e0272df4fbad2e38be15287b"},{"mnemonic":"shoulder lock swamp goddess length trend tongue razor heart donate curious social","master":"c71c518c4d97855fbba7c0d7df9ea8f4e6211962ca9f5378b493c6c1d3b6afc4","seed":"e575bae2e1ee08815052f98f5c4bfb9873f171b0dedf4385e378348310c5c7f6d1cb021696e5913aac6b631ea1951bb977b3bcb548579458807cd565771945a9","priv":"2fea7aaea02fd5d5a5918ebd643bdab939edd18ef406ac5163714fd731e1157a","pub":"0363e2499272df247aa216ab8b274e146fe677bb18e706fc5377f8c921ff1c782a","addr":"de719e1abeaaf11712931d05ee39990e1331055c"},{"mnemonic":"bitter yellow post enable knee tag spend base blur gossip lucky lucky","master":"1af25d9330946339620183b1f1209c4d1ffc0aae754b82d71268400b934ea426","seed":"9e07914810a7e2d91a3ff6d4efb0686c14e59506dd9dd3c357dd5a30925a3f57c0a4983589ff113833abdb7d5cf7dbf79c08172888539126dc286848c1e49ab8","priv":"6e1ca5a3a31b7f805e412f0bcde7f82bb3fd984661a58c07b7967e327e664e47","pub":"03cc8ddeed92731c6b475a964c885865c5a11bf59ba24295d1e1117feb7f1f3e5f","addr":"8b516445842b755f23d0e671f10a5c0b1c2e48f5"},{"mnemonic":"forget organ violin inch panic sword report clean garage sauce math man","master":"29156bb726af212233cbc6c191e59a96d7ce44b6821538ea03053f36d51a919e","seed":"66c639ef4de2dec82b99ad4ab7bc73c0a4fa79d28d06ee393ccdbcc27ee375e9dae7672055dbf6d0d5ed67f2e99d4840614223d85aec64dd35607aa9b266d9da","priv":"f5e49029f7141b33f51703add1f4495e04715674fb62ad2d781f8c66269fd32c","pub":"034132d2bc71934628f435b93a9d161a3ce242e7d82dcda0a3a8c2f304e3057500","addr":"cb0a4d79fadb82d7b947889b26f8515db8fe46e6"},{"mnemonic":"under depend door lens retire faith scheme dolphin orange maid carry disease","master":"62ecf318e91f233b59acdb4000665338c8d61539b7b079716c85ceadcbd6300a","seed":"30ec1c26fb1dd7e41c5959ef7a3615e6d4e5bc21fd8af5efe1f8c0634e765f63462d7017d5a62c1e992bbb626ffcaed002208ac5f8867a97e454c1bf0bcad8ce","priv":"2babdc8642c9c9beeeafb728e948bc8531dd066679b85a9b58676c0b4247cd89","pub":"037f9e2241008d25844a96272632255802c7cd3866c5a83bffb3e2f724eb59d385","addr":"10eba132bdc71c162058500af51c53074ea1947f"},{"mnemonic":"swim topic sunny exist exhibit nurse ozone guitar trend page machine pitch","master":"5a30155bbaea42d54e9a27fa7587c712a19ad6c1c31052f68418f235b7bd5de9","seed":"673d936ed3502149d68172a22785c2aa2bbb3707d319fb692fdc6a4ace39ec3596fc406b60720ab5993af07227f42608b5a43e8e732c72d8ddfc82e680428925","priv":"e6759f20947caed563dad40d46206c67599d4d622502e46199fde1e17dc3d76e","pub":"02dd5474a52b623514948319697c646b519ac6e63581d27b01f0780af8af085e66","addr":"85fb1118593dd8c12acb0c2104438faba5dc236d"},{"mnemonic":"dragon square define chronic round romance scrub gaze powder visa please symbol","master":"1f1a35ac699063a47220536ddc3e988c055cee5e08303b867fdc16d5488861fe","seed":"dc2037120b143c919a3f0d71c6822f29b9b0ea098d286f8d4e40b3240bc9d19d4f45da3bdb983f49c304c083f534c7a26471296211845c13b49df97be61055a4","priv":"d99a6b75adef1455ff85fc94e8a4ad400a326662e01e9c0152c797b842c060e7","pub":"02eb2aa36f19bb90fca43f34316a18bb80053faeaa909cd6222128286af6c18bac","addr":"d24f7932d14e493a54a5384dcba3682e3d6c55be"},{"mnemonic":"first knife erode dice talk coconut act example sudden garment scene income","master":"1214f622b52ddf15c146c74bb0843b653117459901214a8a198a0eb59b4153ae","seed":"eebdecdd33e9ed6dd2e825c12a73e4325593aa14a7faecaea48d6764e6ee6d9d4140ed9e105247b2ccc0a1bda976fe7fc7ef8483c58f465cf393c4f833e86d94","priv":"ad3894b4f558a2e7fe5f0685e4ccd63f57aead98863617b081ac620cd25ffc4f","pub":"039de7903629baa0b6ef2cfa85dbdcb51af3fc9218b01bc57bb1f7eeba5267a858","addr":"fe6dde2516232383dc3382a75e86be3b82d2d8c9"},{"mnemonic":"danger expand toe talk course mask quit virtual reflect vital address artwork","master":"54c66d5d95de00c23ccdbe2defb6cfe78d809d55e457a0b35407ca74ed33eda0","seed":"060b5853c7f3bbd7bfc7b5d532f39b74137c2b6273a30682f768ad62800744e1c6a1db920d151d7e553553cd908b2878a31fc6c682caa05af62eace45a897b19","priv":"0ab2d63d607a2c56041fd953d9be60f5f7ff5e50f3c3a606dbf54bd799e64190","pub":"03f8b555aa7005be93d03e98b6f2a8870b9cd4ef654299be64b13b89ad839038b8","addr":"526ec814ef1712329c1cd43244e92d3c1d5aef91"},{"mnemonic":"custom flock clock grain absorb danger universe achieve decade habit phrase together","master":"ffc14bb5a243dc703a5afb1f904f8aa4f21790b470c9e05fc21cf872bdfce41c","seed":"71a82a4221bf48e1e97c8e144de80e80a9dc5808d579da185e75f6b88bb81038d88210c252921a2d72dd38c5bcb4edd442d2b481dc1d857965012d9249f77477","priv":"d9bab16080df04ffe43c57fa80c441a65b4e49a4425a0db06f52d6db77595d38","pub":"021f074f1e14552ea091e14e680814661b1a75148f8bd149fb8f6a13f6f5e7ffdc","addr":"d63213b298b92b726178855680001d79ece9271d"},{"mnemonic":"spare absurd book liar green humor alarm income sadness shoot radio indoor","master":"f9056445390a09170334e8a225d62719fb259a0c159685c29ec39e348b742510","seed":"a023662c39608142068683c030ad51321ecae6bf954b72465dfa8feb34f1e8ace0d46a072b855e33f7c5e8be70420a4f3baf7ec3ba370e975da88890d4cbb2fb","priv":"e5b8369724ab9aafb2bb44a1d3cceb2568fb0350b45f123a7cd0f26a27e70b2a","pub":"03b9196b842ae4db2b2409389a0747407baef8b19d502156a809ae02161cb0de38","addr":"658f62b688afb4773a0dc4c81925d7914dad5d22"},{"mnemonic":"anxiety salon have exclude build airport decrease unable measure reunion monkey private","master":"4f708611377bee900ca76817926b905bbca28bccced3ad0e211c7609c0562fef","seed":"cdabd5c6b9a64c302fdde1e7cc5e6ca15811e52e432e7019a81945264b3e52d89456171be0e24d4dffea0136a12a6204f2958c303f8c61af84f4b5ed135685cb","priv":"7086136c92846f7deeafe05dddd8461028edf62e947fda55b4f1ac584a78c5be","pub":"03227f8b0d42ee20d3c5cb4524686d19ed43bfa5595debe2ac4840eeeb92f3a411","addr":"6d11946752473bad3a3d593f85e97bb4664c2984"},{"mnemonic":"frog youth swear now annual mushroom stuff business excuse frost cause athlete","master":"0390c3c986b8d724d344395860504caf17a7a347d10aed2f4a0ae7ebc0e07f13","seed":"25b6bc7a888b35e1246bf8c7a289a79ba589cbd949047ba6690b47bbcb12d8c87a4d14d585fc0721217891396ce0b0f75852187a9fea4feacf320f9ae4eba3b5","priv":"ccd3755ba9b7638c2ad6815d34a03869650bc1c35b75c8e1a1cc9c2ad71d983e","pub":"0284806c57cb6013ca5ac1027a07784d05b23bfc4e6facaef108bc5af7ec20e026","addr":"d512ff91fe37ab6bfc605cf5470ff684d6dad743"},{"mnemonic":"bridge rate pen range tip web bunker magnet blue rocket dune evoke","master":"38d760387d07ffba1ebd6ef9fa9737eabb311bead38560cc464c7585b90d6915","seed":"953c78a493fa99014a542b2740b5eb2623f0fbaa765a5aa79e61a5344867dade60e05c4293df4076e218ad61c66b1112f54aaf7bdc6000b059b2c88558f582b9","priv":"d6d617aacf6ac20090788e43a7eeb58d1b44c36ecd4fbdc9ba287c8bc7f3b24c","pub":"03ee39cb612e75ef609467ed6250b602b90ee94b25ae43be9593d2cf34b3cdb938","addr":"dcfbe07630e2a9156f0787ad4e96de1bec09b3f9"},{"mnemonic":"volcano exact weapon couple logic cactus carpet raccoon state rigid ball tent","master":"8c60a1a859b5684bc6aa996738801f47adb8392ca3f92865b2f2b3a48c69425c","seed":"fc6ede285bb6e6fad778234a5f6c5bfdc23dffa2975667dda6c5470c70122f8aca9c63bd77c8811c43b4d4b2ab4ca55db7b4d457f393436ca1626ae6fbde03e2","priv":"74a1b74d0f11c8297f0d315f9556a96ec5e880bc59fecaa1283ec2a693cd9ef6","pub":"03f62cef4ff1147df7ca38cf1231c48632c4c4b2618e6c7d2bd001e10509f68f05","addr":"8b8e006c70eba973ef8945d89e33b6a5422e5742"},{"mnemonic":"match quote pet worry pizza stock flee tip kidney tomorrow giant ship","master":"02f8e676d2c4dec8e6a8430c22f8adeaf3b25054c8d22dded7e2bb6af5327a63","seed":"4d29deced03c572a5fddf55539a735228b59cbcfa80381a54c5a69dae73f56484318e511fcf46123dd8f390e2527de882252f3c0b69f49b9dc83c7059e876767","priv":"049f7fa5733f1c674a29721a025d410bf35891984608ce1eebc7ab48626ec3d0","pub":"026912ef70835b247c3fee238937842fefebdebf046b7f2afdd4f350152765fd26","addr":"4d221f1336ccedb6b2a9850a15bbd13c62ce0fd5"},{"mnemonic":"swap amateur unaware glove biology frown vintage dream prison bulk gauge bacon","master":"8c370390691fe152f7d6f5220704c9fe6b27009c1218a07d529768f40fac692f","seed":"5e3c155797cecf5509151218e30101e33da6058dad04f89dcbeaba0d1d2310482b278dc747298284bbf7e29a71cf4a869e0c2755f6144cd2a5f58fd581551b48","priv":"708a814272dd4efdf60665c491730ddb73d3d5eae3d74ba8ae632183ed014569","pub":"02e06b607086808b325b7629a95ba7b945e611c3062f967402f04966bf87111a23","addr":"d343acd452e5118b6e4c1a83cb08a521735f2a39"},{"mnemonic":"shallow chapter special riot dial sweet armed imitate rotate south cliff shoot","master":"bbd697f9078e47816c986596fd2af08818e0e84f3c2bf52ff52cf72974add88f","seed":"bd24f3a066e4a994bbd613d12f88268d16d2439f9331932a9b30da17c7fee4fbf5aba4f2f333103c6bc1d0bb600be1c86db54e323b6e9e9394b93eee35a65359","priv":"1ff3375c7c35230fdb97b8b8a2401a59278b383c355dfc1773024fe38acb4a42","pub":"02d3fa09d1e5929fa37218d16448800c9eec188e31614396648b65f3303bb3ce80","addr":"8c3027c978b9be60970e98790b073f62cd3615da"},{"mnemonic":"illegal hospital witness leader wagon appear trick mixture refuse kidney total lizard","master":"9fdb13cb834e01260d56ad2bb7c8db55b768bd0e76464d52dccb77ab806a1258","seed":"a96e21fc0177a251d86cb6ffa4057890112cafd32a7c270e782616b407cda51dcd914ba2bda90c80acebf8969825e8044ec77965e264e085ee6ce78fcc698f61","priv":"17804874b6872c2df6c5da2ae45830f752a159dd03ab0b2ef22c64018e91c14a","pub":"0221388d8dfb7416ae88426999f1e07d41aca9668b10262e995cce20448e315e54","addr":"4feb63cb3ca2d1f6b0add8ce1bb2db5661dbdeb1"},{"mnemonic":"unknown update couple lunch demise sick brisk market area kid service again","master":"26f5f1d04e6f20ae2a9cf5631a1fda6f119e3c14dfb35ff75ced5091ddd072ac","seed":"72e5f09a5c9e56832ae400cc69b98932067a81edc9c0bd0d97d385b0cd7b04f70e51f496054c7d28af2853064982c9625a4fe745ccfe8bf4d690ffe9368867c4","priv":"e59d9190fa1f4f5b37842807ec8c886c9850c7946520f6fc764c232222500f9f","pub":"03da97ef93bfdd16433aad5ae6cde252c062a9875063fa3b7ed2615077e4446c34","addr":"4302a5c24f1ef5cbcc1e286f498140769f3fd667"},{"mnemonic":"leg damp bulb final remain off lion fold run buyer help safe","master":"4b64059f74a801c81a66d7ab2e25597a3f3c97fffe760d5ca70a8857fcc5fa55","seed":"24141973b3a7aae69d48656fc4e535d1a2e094d9ae5d6325f54d6288827dd32602b128ef414240fd88c9a72f790f8fef560efc023a6695f133d8b46eed51cb1c","priv":"13e840acfed4b533303974eb1223a9d4fd400902041be3994101ca517aedeb6b","pub":"03ed7c577c28dd6936bff7eba4569d681abf5bd59fb97ba5d793a3f65ad54f8d21","addr":"3e404c844010458e56726cf7d0881a1c4047ffa0"},{"mnemonic":"observe budget library column blade soldier apart panda express frame version coast","master":"dfb6154ae9a50d8853f5fb0fac07d98cdbdf00fc4511f6f940490e48ec1858da","seed":"a16b567cc1e2c96ef202c9d49b9d14cb5ff14c7c514c8e2bfb214a9e6371fb6f4eff3dbee51e7de2e781dbd815d1e76af525d9766504208949475866abe29766","priv":"b16e831a50e39788755684d0b96f9e4f11b9e637d9e43c27cdd5242091c0a8ac","pub":"030ee1b1e2c7afccfe7f667ba52dcef130de06b35655deeb33291ce6118eb0a31a","addr":"c72adab4e3d6d5d8a9a72e36bd2614d0b4b6e78b"},{"mnemonic":"exit pulse poverty scrap relax umbrella rug clump cruise biology magnet area","master":"0d00e0698a0958ab8ac891db675471b3f7a998f4947115313bdbfb189a8d2308","seed":"a2831c38659377da9fcb2b76d62b76a7f23d59083f33f8c6778eabd804331d46f2f0f4e167b013e16b2b6ce066816641b2bcf47dce75522cd3d1e6d9fffdb28b","priv":"d0c7f92739b274899883175525b6443c265c288e0835233428b97f6f912263c4","pub":"03740d02a36387dc52d66d96357240ec0e185007bbb4457b3598d96680de6309ac","addr":"c4dcba01a757bdf253ed47a41a49c996657d7f16"},{"mnemonic":"impact random cancel imitate base purity devote panel vintage group pool twist","master":"ae715a39fbf43bf9d848024d3eb93d9ca4313c384374fbeb3508077a29017462","seed":"da887f0a16dbc3fed38134acb53466bf1c1d18d179c2f857573fd4a43b8e52b16e598306dc199fa2414700b350174ffcbf4508951c765680f4b3dc7255270efd","priv":"512494ad5290d4dbb69d9247e563188a8705dbeab8dc319db39743c319389535","pub":"03a4eb5469006a29621ea5321f35e8ed8d839a9be99be7efb9caf5e5389dc708e6","addr":"4ab6b8d6bdce81c88b093698870645e7a1f92370"},{"mnemonic":"egg usual identify trap involve winter card eternal subject unknown obscure scrub","master":"6b54ed0110635ad73c4439e189e594cadb02f22d84bdbc7b94027edef2658a83","seed":"f23aee9d83ccd474ac819ce7dc8a57cc57ce082f8032c242511ccd96a395ba8c769d07a7115d25b53cee1d12d6a703f1c0204ee152bedaec1b8c15d5d5b78edd","priv":"0f1f52768a3bc3ce2810109ad40da0126ca5527c494b226048382a9513e11be1","pub":"031d08dd21c95576d1a1a028ba2938537d1c604679fc6e59cd13ef08e62e566a4b","addr":"a0c1e6d5d63341a8707be1673a0dc34fc054a14d"},{"mnemonic":"crunch drive cereal switch sketch gym hint fortune install approve device gesture","master":"4b4f8682bfb429ef36e7ea355276981be015fb78b90c50c19665b6804f7954ef","seed":"6ca97b6725834344247fe5dd5fa0d2a20c31130d6b9c60047578181867650f8e734cafab2158f57b64a92c3f77672352dd71d9df03dd6d592a137cd19e67f3c5","priv":"fac29029531fdccaf85476aae13bb3c3c9f0083265fe6d5e6e612386f3be3ec5","pub":"03683e7d7472d8fe91cc67bea096aac18dd00ae858b8912ca9b172207b89639b80","addr":"aced36c9dad879576f5904d67f504e704726a21a"},{"mnemonic":"congress nurse found frog crane toy pact write manual version repair embark","master":"157ac37c0bbc0732a71858377479fe8bb236664322016fdfd62786ae716f9ef1","seed":"8f8269a5211027a2c6480e9a9d910c385c2e772e12cb756802931b169b602d0eb7da4c603b901f55d4f5c5cb67d7fded0b71f5f9120ee1ce08e74c3bee1f745d","priv":"ae12502606695e34c1a97dbf15b70e1637c4d537cdb0a21896cbdb17277181ab","pub":"031077cb5bd6bea01a470524322478cb5997c06fc77d7154c92f3b7273a36c739b","addr":"6ef29aad62d003f9927be9daea218167fe14822f"},{"mnemonic":"verify service fashion camera deposit expect snack memory proud opera flower casual","master":"7df339fc4837633a008a512dfd0ebe4f9a1236f048839025d33c574c4af0cc42","seed":"151551954b5b4719de472d6a96d5222c1eb688c476f190bc263d7370baebd0740e58f2c3fa00e3cb4615389bd306ed994d3da60808d1d08dd005c5292d3038d0","priv":"771fbf2a2c24130bb356f2490ca67799ea8be2d37b3f291323d5e9b079681cbc","pub":"02f6c6d95852798faa803021107d6a12d56bedcfbccb8110fee698b800931aa2dd","addr":"00b958acb44eb87590ec60f63bf352ec8248fecb"},{"mnemonic":"artist gaze ginger just pride royal strong absent wash figure adapt decide","master":"ddebae65962a513c384bd902b230fdb48f6315d6645a947d79b63c4d45cb6023","seed":"8f7914ef479cab13a658b773db99f56a3ebc267675e1a91a3b595c2f0616f2793cb862cf6038858d363576f994c28c630eaa54299480f168f05d7564261a2693","priv":"b416f93bfe3495ae2ea2dfcae8e587bf19650ee08194962b43ff97deb85c1bcd","pub":"03c12fd1c2e653e3990d15b59d64cd3c34f3f248fc2f1d52946fb218d3e94912cc","addr":"06c7ac564ab51a452c3fe76c0cab37541ae1b3ab"},{"mnemonic":"case mandate call napkin cash test ripple bounce page dilemma usage stay","master":"101248d364cc296423da1839cc3d0774ed090bd9e73f55f355963272129cc184","seed":"b5aa29ba3342da94663315038e9b6c2d61acde2e4cd7d08971d79576224d12af8478abe891de819771a6ddee37269a71b13c825f8ea056f7596d301b00a9c0c5","priv":"4b97318dbb30a0b86d6497a97f3138db00d268ac6165a0fb80f5b8e5d714e619","pub":"022487dbfb8e3061c3a342d75ceb25ad9a6acc6b8df0b224f3f521c8105a4036ab","addr":"984ecec7727a1f812b63b6a6899979b36bff2e9e"},{"mnemonic":"neither divorce grocery stadium narrow electric observe that six diagram hero toss","master":"59cb4dd0ccefad583b8c79c8dc1c5e1d1d77149cac9fb26674076287105a0936","seed":"9c5e31547f43116891fba52294c90c80a583c0375ed100d69e2b72e1453b591b1072ac402d24e011ffacfecd2c8fea1c2b1cf93a435996df42e1c8b19aaa3fb2","priv":"f490ea8e2e8011d7f9b9c57d9143606d470ff00bd51ca69a44c2107d7de7123a","pub":"03fe9d9451c9505075629309bca9b361edb59483e417f07a2759aad704143ad778","addr":"65b28d0f6e78c0743903e41e915de6231603eb5d"},{"mnemonic":"van lucky present hobby property front toy document report switch strong say","master":"5517d9a3e2996bdc9e317a447f0506c33dc20c3c36e6565dd8af76ac2a0158e0","seed":"779e44dd0d1401cdd9d84061044158fa4036d66192c5059bb7f33810e776de434e24518477bd4092a0c775bf7801887a72fd94f0d6bb46757ecc3764f8e17e93","priv":"bbb4c89a597315ac9524df42b17498d334d93b8d48f19188f5ed2327fc2800b5","pub":"022e2a217432ce25ef42196530550d177aff02cdf91332e4a86c8d1fc4f34b07e1","addr":"ad5ea6aa0d47a084f1d01c547165eb51d067871b"},{"mnemonic":"swing shell april silk tenant swim clown beyond under tool envelope private","master":"bee0c171d74d809a83d0a7f70ec1d8ef320efd80541127c9e3b2dca85e344ece","seed":"da69d4582287e64756d8bc49979952716991ebc878764f7c8f93649f5b721c35f5496e7e81f5f21cc987315f53a747911363a58790eade4c43c7c24911cf8b89","priv":"a6c35d6f727685419b4c3717f0dc31d33340536319963186c64f18932bb3d921","pub":"023465c95f48753fd4546f6be7b3c5959ac2de74445c2352e14d0c57b058ab0ae6","addr":"7959735517d011fc100b56f25b6115982d2299e3"},{"mnemonic":"carpet sketch depart tenant immense sock because caught close canoe insect crack","master":"ab35e8379ede1615b44bf8b1a8dbcc3ce88b6d6d0980cd63ea4f783340a1c372","seed":"379373dd202ad95fca8046f17a5f989268cbacd2697a02ee5efc2f022f9019580e7fc452c551d97c9aa2247c566313e454768e38d6585ad9561a09710a279ef2","priv":"a7165228a05945d4b01a1ad12911666504f8fea8c8819df414995bc1eaa9068f","pub":"025a7afe792c05bb3d94c7996bf5ce1fbb02bbf716593b2049f6e42a0328311f2b","addr":"1fe2d6a254c104cc38f1466355501890d370b30b"},{"mnemonic":"world sweet evolve club speed desk double verify gentle account youth column","master":"b2309b5c1e0a5c590859c5ec3bad4b94aaee3e2e7ef21080cfe0780617eff220","seed":"efa3dba671c0c4e35072d8958b4d7af280d8e20d3b6752b34a6b1e561d0f44bfa7829a5d540b52e02dc1b06735dfe18b2073a784aa307253dad71b9146024bda","priv":"a2a6288f9feff9b408fd6b056309dcde5cbc40489afb85413202443d7c283466","pub":"0307429d4171f929f79c8532cec5970c17d6f92ae014e14d99fb1f8fbc0637c9e5","addr":"1ae1b848027b0d1276a85ec2946bb7096755017a"},{"mnemonic":"patch cave blush omit calm habit autumn load focus tobacco barely switch","master":"972320ebeadc9ce9da0a447dd469c95bdcbbda09e6887f64dc9c6fcb8d6c91ac","seed":"dedd6610c32b2e5a3fb93de12f758d92041b0d1aee0bb2626dc0e6e8cebb8ecfdf87e25dcdc4f9646f2e37fcc071ff4137d914df7133a6e22fe8669ccfa7cbb7","priv":"17cfca7dd65152e0a3c77a2bf4a15b0a99b7e889dda49174acefc06d390bb255","pub":"0286d1e4ac0c7df1e1e6ebbe1b7aea5f0e0cef8ff3336a1c2f61c80d135a382234","addr":"b184ce8d18aa006e93ce901fbe879d3d8d6e6417"},{"mnemonic":"extend install wolf token genuine mother swift pencil scrub annual wealth hip","master":"4ef0a071d94253f9a60bffa7443918f43865f131a579ccf93d2ee16a518af2b8","seed":"f66926e6837305237316d7a69fbe18911f73a4f98278a2f6e6b1a8e06adfc1d189875ca401387b74c0198741619030187368c2a58e6b844aacd45fe89fcb6a93","priv":"f4c00a2ce7e9217e5e5e3f5398114cfde57f25833e920f14989e450645087bc1","pub":"02fb09ad3c161919060141c50b70c144cb991a553a57b25b2688e56ad163c3bcb1","addr":"556ed45bf7463ad502fc2fc07ac05fc073badbec"},{"mnemonic":"canal pink undo modify apart bachelor movie coach december exclude scale despair","master":"ebef42622df1bc744290f0c5d930aeefe2764dca7efba491b78ec958a5acc171","seed":"056347f396399c75761136da001671c6097fe21adcc920952db079afa5debb60d1c3612742d96af16de34a44c792da1ad995757e6a25e62953116d3016639c86","priv":"6a83065d2777eb4674e19f33a08b46c44753cce58902a41cdc3b8e3f0883050b","pub":"03a928c2c2aafeedb59d1588a86c42428b70171eed39b94f68f2097d9cdaa4c283","addr":"28053af43e4d7e35b32f9d174bd205206f94028a"},{"mnemonic":"brisk clip brass tunnel credit hip clock deputy dial hole song soda","master":"965fc6288cf02a8aa3081de292a513fd7b23fd010d373045e2a5cb37f38b2393","seed":"553cbc6a6599410913b6304461c1cc8b4a2c09c8bc1091c231d7167d27892ffb84b89c3c001ad40d4740d97224062c974ab01ea2dedfe1a3322f1a041964fb46","priv":"c9fe5b03317f7e7496f8824f24b782c09b5b801b3ba7a08d5bab508005f88aea","pub":"02ecf7641a4b3436c91ff3fe5b9f700cecf8cc3769945c665ff6129f6a60e77a7c","addr":"e578b715e9e84da6beac28486ed9492bea16435f"},{"mnemonic":"senior example flock banner pumpkin salt silk soda funny input puzzle ready","master":"7b0b3ad8cec24080ad6fcb9b1ba4b745820543666d362a188f4aafa52cddbfad","seed":"367a466ca4069c50df5571db657cf4394e843973e5801db4d7072c51453ce04b574b01e07ee8ef0836448f7fa220863e6cc7e6180618efaa3868e78b807b4b74","priv":"31f5e11528a372d7948cbdfb0519f974168d568128e441a5840a02c1ebc71f50","pub":"03b507120d46abde399656100fb664c736a2476a588f2c893d4be9a5f9acb0460a","addr":"941deb14e567c6d60446fe5767a0bb780be7fd0b"},{"mnemonic":"say leg next pelican brand topple blame plate snow month van cherry","master":"82a9d68ae21ace7c2e5d7d8ff58e4f0cc3c7e5db8031d4f83008d06088c477dc","seed":"69956cc226c79bca915b24c65112962205eeb161b79f66246b493d53eb7e1dc56f9dbe475d9650c0e72d7befc0b899f75f7bb3b3c100f7d6128b21cb4cd88396","priv":"cc512c35a0edcc0efc15ca9659bb536b3957420f00b32cd9e3a0d0e1cad5360a","pub":"03c4c82df36b093deca7eabe03ede5c5ed3639dd37ce8598ab8a6342b86142b07a","addr":"d0ae8f85e8c95b4906de99ed528331173f251e85"},{"mnemonic":"develop odor front thank mobile subject then cupboard human high crumble rabbit","master":"73704bde13f4867719c71fac5b37f16f30b69581a53e7f09118ed1368610b1c9","seed":"88f30341bc3ab214f1aaf379a8fbe498825029793d4ed2b50d12ef666fe45f06e39f68583c4cea8ca6a88e5ea62d8aacb499da4814fe346e020a78bc636a3cbb","priv":"53f91608a0b1825b05ae68992f97fbec8dd7adf877c085d1f30981d6f5262653","pub":"025f5e6339f5b651038512ddb5073eaf10c962f6e82bd2bd94c117cd4cf4de4fc6","addr":"d24cd460bc42f5222b18d5632d53163b648c982c"},{"mnemonic":"toward weasel copper blush mammal window weekend exhibit pizza element impulse valley","master":"3fba4e4716bc0b0f99f44a2bc7df34bdf60bbc5c1e2b76ff4295f21428465dd4","seed":"8051dd06bf13a9b79d82138ee3e5cd3e417c6d203ad0f6ceb81f38890d4c18b56d29c93ba76591c499c9cbcce1bdd205b26ab792d506d4903d90104a226422e2","priv":"0379555ca3e00311dc6949659afba1cf6019ab5690f14fe8368f0fd07b90a44d","pub":"032446f977ee3324c946b0d6409a4b7401becffbfcb868827e6639cb686bb2140f","addr":"87bf7d0cff36c282a9140657a4420f67b7b7433e"},{"mnemonic":"lift piece elevator remain horse virtual fragile dynamic whip lecture perfect fine","master":"bd16309fe9a58eb87ddf1b8338ad0ffe4b39706c4d568cfdf6f5ddb79064ecdf","seed":"8433dee7ff8aa73f785d23b09d8ce7f4e1e5cbcc7c20133d81f87c1d47b94f733631d5406c01f756ba7bbfbdca900eb2fa03f6b0a0bc1f06b9f3c3c9ea4d6d61","priv":"c4ce940b7e5cc0606f023daa3dd724d773e886d48af58c785fef7605b2524a16","pub":"03c89852febcb140ba3d5e9c95ba6ee843666ccaa69492ede61dec94e4e6f73949","addr":"3c04769875dca7cb3c6faddbf1960e1738118d7e"},{"mnemonic":"dash output lesson topic butter run ancient claw enlist approve chief observe","master":"8d37dc9da62db3dab7a0f209d8997dab75793704d6c18056f02b6768db414121","seed":"6ca57fc186a6eddbb0e8ac6dea4c1eb5d8361ca08d7b909a8e863284b38180cf8ddd2d9590f7611a5cb80bf1abcb679adde5646e69f62208557ab1a37e80394c","priv":"db5742d8734235964645a018fc4cead9402a113a60de0d7f55ab3816c9780e8e","pub":"03710b31603eef3e10abe51c57c62818ae65fc7f0aa4a91cba5f178a0cbdb313cb","addr":"742d17ad66f51524f28deadb3366859f14cf02ff"},{"mnemonic":"blouse maid inflict jungle yellow believe arrange cruise seat dust endless benefit","master":"d13daac6580c68186cb049fbb63c05bf2282919865c4018acd8446828dbf07fd","seed":"5b4132806e12b669813f1ab295ec58fc472fdb46769ea7181faf6e6b48f3cf4d8280e8ed5951306ed71b40d016afa3ecb71476a23f455ab6e41233ec2929ff0e","priv":"a8b701c1abda145e723d92fb246b692e44693704b52198ba33128267bba63155","pub":"032c532be31e8394d98571f3623372abafce8bdd0ef02c198544d0dc6a6fbc3cf4","addr":"4675d51ea6dddfd9b296532f3f2c101229cee094"},{"mnemonic":"only enlist indicate practice safe romance orient gallery cousin silk eager what","master":"2bee5e0de945af3aed16b2a06423d3447dc0c91af3ab8fb20b4fc0dfdd74bad6","seed":"92a6a62d9b145dfac6f66b7dbdc7bcd7b9ac10163541cb95e18e77742e3f2ce1773d74b0b290e40ecda2aff147bf81fa8997eb02668891a68912cf42cc666fc4","priv":"6a8e812a13716f00c5139220f1afc9a7ac584ed7553fbe8a13c50add54e5446c","pub":"0341a641547fc87d6a44abe879aef7b9f7c36e3491f221f667d10c568eee0fe99f","addr":"0fbd95b59a63b2a4238d6703ff49746a5950db8b"},{"mnemonic":"oppose fan kit prosper message pass fiction machine duty antenna planet ribbon","master":"6464d66007d3609d21971ad05877316fd8fc73a4b61d971676fcbdd32eec832f","seed":"36f65f329a478fc6cf1c9be171f9de9255affd1434ccc3420660a156b6cc0a85a10d5eb1547bdb5849325f5972b332afea7973449dee8a72db256479301337d4","priv":"94c741202799e22867b197c900c11e25855196e9e10e2f74f1939aefb7ddb233","pub":"020b86916271d84b2ea8f8b83ffded3b8f2bfbcb4ac17da7fd59c9ede27c00926a","addr":"d26eefcc75de9069e99c2e98699823b45effa9d9"},{"mnemonic":"acid summer coach step inform jewel secret tornado abuse kit shell guide","master":"4a10d5e6783e00d6f3453d8948dc5b39776de5690775aaa0a8429b2f11679ea0","seed":"46c698780417975feae4b6607e7728a00600e0e8e225d5d8f36ca076521238761c5b910759f70498e7dbda012d4325f3fe81011ca762c2eaa06649a18b79fc74","priv":"7d6a286693fdf1e51c26a64e5e5f8763b328934540b18001898537afa49e8b1c","pub":"0319013f6935be2eea7cdfe0544145708d24ffe9742a64b1a2d22f24bc5e380bf0","addr":"d53d22924ffcad0359a177345c32723e6260c7c4"},{"mnemonic":"general shed quick sea amused piece air infant jeans page eternal lens","master":"7b435a6cead581f339c1008061cadc687c40156312a8201c823158a6028cdb93","seed":"0843ac840c79c9c7dd85cadcea3496bc7a376592b07d233c35bdcfdd09725eff59f0ebc1d0cf255035ab5c7344adc3581dc543b134a5e70eca410b46596ee8c5","priv":"e61236f6e4557b45a6e39058b8606b7e3041de297cb0d39ad06c2e5414199d78","pub":"0241be261330b87c2388ab4077fbd4fab3a66e7d039d3ce4faad319c42b8e886e6","addr":"29777a50646b5f08eb7a428805a9778851d3116d"},{"mnemonic":"view hood trigger weapon dress roast load artefact dumb biology sadness receive","master":"a619455307c5edc87edfda01059cfdbb6c356e9f639b16b80b78e2421f1989c0","seed":"d89adefef230e418d7462194e5e1a817a0ade01435763ac5030ffe94fcf4b1f9d8a06090ff8a742d22d7a78e4a6392e35e8c318f5d0e495d0f8773ff126ab56c","priv":"1f9c2085c35b5fbf1a096174e7f11537b4f6d6327018dbf3b3311488865e5135","pub":"0208e02b8410833b43ab7674e25efd7081d6516aada029588f72a5478fa5c0aa20","addr":"cf4138b64094d8a9f58cb9068305a69ac50c4f0a"},{"mnemonic":"salon diary era brain chat panel design lawsuit behind practice please budget","master":"fce0a096c14774cc4bb44a4e9c65cf075a2ef5eebf96f08cb684455218f4dbe1","seed":"b154f70e78908ca26852b659a6f6252d83f3bbc4261cb1b9faa4ea80dbf1feb27958164163bf7ad82de0ff8b1af07c60f23b376910a24608c8af4b88aa0065ec","priv":"156d45c8db9bb83613334020e9b9486eafe16c1341aa05f4ed2095ff5a11dd66","pub":"0389bab1175f1cdd60a54828f8684c99c603d6b877597d1ab0349ce6a974fb9e68","addr":"f60cdc064ba139ed5ddcb6cfdf6c89ebdc378962"},{"mnemonic":"text horror panda eight mention victory wonder orange error few you illegal","master":"fd6c8375c6c3458be159f4c2fea8d25688163c7d306e17aa2dc32951eec2342d","seed":"ff314a8722d3291744c0ba07d569373771357795f72307366b0ee0c84b71ebd60a54d6f1c1c974bad1150e85415658f5d30fe76062d80468786fcc20ee8ee903","priv":"943fb32cbdd79c2e34ea72a9c31cddc3ebfb1a353808e471b77f54cd108f487c","pub":"02d17d74fcab59fac7d1cbea2838d5db3ecb1c24219b0b086ea1ea69559b8c2099","addr":"996916a8fe8dd544c1906a0afe4b48df43abb409"},{"mnemonic":"apart beach sibling debris chat hope toy happy bean same auction brother","master":"9eb93023f619ad35b6aba1051b791dbde9618bb74059632813b4e0f72b16c773","seed":"4fa270abbc1443fe7f593af42da0b40c17773eb7b9efc09c621b59424f84be65ed1ac755b88d71632a5a384c6dd679887c021dd91aa06fd9547f5c52bac8618f","priv":"3adc47b4297474a18744bf61f18e3030bbf58d68eccd4b0f9a207fc513edb851","pub":"037f6fe821009e2e043e66b167e7708d9534a543391b3ea17abf449f2807931462","addr":"6b9668671f23172dd08382e8db996dc9df687f80"},{"mnemonic":"tag bright bitter hedgehog stable level outside alter uncle hold have voice","master":"63157c3bb0a525d611de7539718f3b8de9f4f7a61bc9884d2f03ae0d30e7c5e7","seed":"e40b20a383e582f304c7feb315ae1bb405e9a5e12797706042d82918a19cada05fd28ca8615d929dfe7ea331d588ae3506cc3cae09f560bc13d544607e075ba9","priv":"8675ee046186c61b46576c02a8a7e5dea1d307667ceba7f6a56bca72fcd5452a","pub":"03654985961e5509210a31d1f54b15b37ff975717ef1f5ea7c2aafc76ced1b6326","addr":"972e9f2582e7ed35767b1b23ee73af4daeaf0b3e"},{"mnemonic":"wave fiction coral polar enough gauge whale magnet science second squirrel answer","master":"e2f288c51ea9bb3befc3245bc0739998db6199615869b4f27db9b613aa443549","seed":"2d9a178a3292c3f3987c35d44a3fdef2d849630ff49343bc5c3456a6701310c56cb0688d7a4bb7c3d58c40472d8a71121fb54f0108f6d682c648694f9ee85aa8","priv":"4a4d6db92c8cae67cb80b4f8fc7e63c94d3ce9ea67026c2544325c7c14c8318a","pub":"023cca73403af0fa0a0faba0545c21472996381917db6e481de9fc0de210dd4458","addr":"fdf8fbd1473714cc6dbac873822a7e0c7ffee153"},{"mnemonic":"process visa stuff pulse shop ability test aspect royal pipe protect fiscal","master":"742d13461d14c18707e2828f69b8deae3e13a9d6c90895993a788bf51f5f8eff","seed":"fc0ffaec77037a17923401aea05d7e37f09d2e7d35e9ad26a5dfa3de6e5da7c4b8c1d16e5ff6ca18570b069e1e8e49ef9ef475665e00cf189eef652e40d3553c","priv":"ef5da20d14c6d948536faf4ebfec5f11e430795986086371afb5a239befc3410","pub":"03a03b2dfd694a9d95ce1fd0f9c97f3db35c02aa001d26dc313c269f8a97bc1688","addr":"0d76c54b8af88721dcc4968dbe47607d7040d3cf"},{"mnemonic":"jar draft slab quarter during hawk grass monkey mandate prosper hour fortune","master":"98e2ccbe3470de355e090d69247d6506ee9bf82473d83fb98c20506543dc4fa7","seed":"e6bae0e46c8e66bbaedd465ed2669f9ca5b2bb68d829d237a1846763129932588a1aa4e69979a4eb3f73010d7c093b20a542efa2fddeaa00032abb847cc7bffd","priv":"9d1e402404867001cb24a3f501b676effb69865045e6ac2b0fcfdc34f9df494e","pub":"03f0bc42295a11b4ccf18b44659cb6d0e0eca3d2034c98f485f5ae43e07a82d90d","addr":"e1c21227bfe3c09188066ae189c7d499d855a600"},{"mnemonic":"camp vocal absent ostrich sleep version puzzle afraid execute clog eyebrow tissue","master":"fdabda4c563e3d7caec47b62f4f06ca53015f98b498676116e7b3df18a4b4412","seed":"b752500a4695f6cd66edb640021b2f590e85f4df2af298388f042cf7b665f0d6e643827bf705d3d1d9786e64bb5e184fb16e270ebffe0ce4ff7f37c285d28db0","priv":"32ade388afcf551e5b9195941ee3d290a39ab041dc9a2b748cc36c53cd43061e","pub":"0346e927eeb5549f8f38fa6280c0932947ef78f63b55410e872e0bf6988e64d03a","addr":"462344dcf5eb679f62d6470927d227365b208524"},{"mnemonic":"kite slogan all win burden staff actual oak cave bamboo advance uniform","master":"43888096d253b010da1f0369f75bc0d6a3b5f14dfbe5bccf7c8fe9bd78242205","seed":"b770074f2868e3aa42bfb76b444f782e4a109f2ed51677a79a69bda83dbdbff3a64b9ee163c57859f143a726d10aa73b223f0cdcdde6497fb95e0fc4a810f583","priv":"26533617dd8d7399f399d59f0f8a50c798668f04f44b52bf50728f20959c68e1","pub":"035ce21f82a71a8580d4bff49e520ab9815ac4d5b6cdcf6eaafefa4457dd9dea27","addr":"178918f829f9cd67d701c9a64b5bfba373a7c820"},{"mnemonic":"bind fire final soon dilemma analyst train ecology say drive slot bacon","master":"9aaeaa7f7a7deb8a976783f523695466b78117462804405e200ad1677e547125","seed":"155349996ca5a6fadb151c9ec425ca1e39df10509a8577f6e63096681c13b3980285777e515176feb7e4aba096b4d9d81a26b4d3477409432629a862669bef40","priv":"a890f151c33c87340a9021d3186c4df062822a3088fb7447bb419bbe5dbeb53f","pub":"0253d42cb2ab28f7fcdb2011e547dc88902e1e4d588e9261aff0869b118bcd4dc1","addr":"19b05c71780f27ec2e44ecab4c426108ea5a0f6c"},{"mnemonic":"image wool rug little visa embark poverty shop shield parent odor farm","master":"c68aae9896977ce21f5f547a4d0ea9995c9641c2a5f2cf89fd5a804485ec0e23","seed":"5c6885f90dfc1286f17b0079ed90dfc3974ce6b60d4193784b9668ec93725328ee5c0d027df1d551541a62fe2d87cc19cbdeed9a235a4510b738930dd3eb4eaf","priv":"d807cdd58fa84e4bda7fa998c8bbea12b7ecb5147c5edf841dcbce2c8663be43","pub":"0259b24a008d6ff4ce4d589e081ff100c28c3f8eb5440c8643257881f10da3658b","addr":"a20d7d609e6b2c855b9da18dea5f7ab3d091aee8"},{"mnemonic":"enrich soup all neither easily combine police ordinary review room keep swarm","master":"8265329602cac11df40567d54c8d4759bd9013c7a325c3d628b81640e95af3ce","seed":"3998bb700715a777bab05afae33a6e6553af17bf8c35eb67c7d4afcc38d6f35875c12f8602f381f797157102334f9c01c483f8fb41abb5f439ebefb76fe260c7","priv":"8956ffbb87e45ba0ac8f4142e179e6f934ca9b88d754fd5347c340a598878088","pub":"02af92f546047de11b15fb4a4c13c77ec6034248b84835f421826a44a68477fec6","addr":"7a6dbb8c88319d3076eb0b387dd2a9e4209b3229"},{"mnemonic":"tribe unfair track nephew erosion spike machine exist wine banner horn document","master":"c8e67f2accc6f9d543e1619dfda891664d349f11eae5617d32a9132c015b964a","seed":"ee1bddbc1eded07dbaf52feac014380400de9e006bbbb74f0c12095b381ba01a696ee3c3f62eaf4324e49b397755cef44667762ec46321f5762ef0e269dc9cc2","priv":"4caaf1ce46e2a6bf8e058fbf063da8683aaea07af831456522ae501d4d09d517","pub":"03df708621a45e5d5fa1108caebb51c513ed1616529aa6f89e3442a840aa37d73a","addr":"4d5e8ec1737a693fb2820994f4dd69291c5224d9"},{"mnemonic":"assume wet effort damp similar original salon aunt grant peasant fatal toast","master":"ea31d3203ecc33935024caac7c319223ff0f4b694cf011538521b318716cbdb3","seed":"11b227c8cf099bde463f72b505add695254eb9fc4714231e09e337f1499791ee2441bd5a148862265b6b5414d47f767398fa97a392a82a0c70648b4a52c1c2a7","priv":"f96a9c148945df0490611dfd06ca16f485a153e96857d746de0f2817cd2412c9","pub":"02b7b1c5e504b37104fd92465cdfda7261a60aad61b7b19b040d074fd07ec8ea39","addr":"036687e670428aab8b8057483c02ca0ea8dcc8eb"},{"mnemonic":"celery inspire ritual apart bring pause sugar monkey leaf tunnel minute alarm","master":"fd42c88307af74bce721f71af73cdc15eba0a186923fb9ff122d86597c1578ee","seed":"46042a350e5932c11cf735b60382d9a331a21f199cc484cdb9df4d8b9be0400c94d58ba1bc4d41826e605c625c7301bbc61e71f3da650d2928e83e07de6a9097","priv":"23c351e14d35d01f62da3cab73dacdc1c0ca052a76a41b58ae9d5c0a242e5fed","pub":"027ef3a78f366db4396cf1da6d124e31b254e90ad0c517267fb5a20a0f4034fc93","addr":"64a202ed14304b5f143d5d10a08167decc68fc53"},{"mnemonic":"text blanket lake damp doll guilt select torch midnight tumble toast dove","master":"c9653205120cceaf6cc768674a6389ee961403a4364e96220134acceed105299","seed":"79d5619f5dfeedd623bfdcd7d201f58ba55a2fbfd0424f32b9a220b4a39cd048e5cc82686e578b420cc35924e8fa31f1a4a29307dcedb35a4c69567da300b07f","priv":"7a7205d096a658f41be1d4d6b8a8644bf370c34a10a55f4a63ce1117d71715e6","pub":"029b2f32b98281d644232c4d603aaf89a98083edbc75b61f8aa5ad2c7ca910079d","addr":"ee416c1d1471a6d06b755fc92535f0bf1a2e3f4b"},{"mnemonic":"crime level shadow chronic rotate era reunion fossil boat shrug patient artefact","master":"fe8df8e3413387b50476e0ae97fe9f3851d5645f90b0bcf0b47b18d16387c057","seed":"0be8bda7509b72cc2d39c38609510fee439dc03600883e39f596cfc30cc2f48dbf14860ca33b7b7dd6f5f41f3d2fa71d20fe3995a698599605c5ea23b95917ce","priv":"4462e7a144223c97450b5d6728c6d017ed953490f7e762563993fa309152ddb0","pub":"0278a9fcb45bb02944c9cff032c013168943c6e0193c6ba6299af4397e8113a340","addr":"a925672e895976c8783d48180cedd09b2edd6108"},{"mnemonic":"chest flat tissue cousin defense ramp burst once rocket time super retreat","master":"7a8c847ca8357ab65fe99b5cca5d0b70bc8da05adc747c4c2f201fa1e22d753b","seed":"96003a7547f32ae6d8e5ce1bfbd5e580cc8c81d3eca4397e5e1453824b672a6d966d97fdd462ee8c0553d832c28c42fe61e78f01d056b2952a6589273ad57514","priv":"e4847fb09c9438d765da59b51c3dd825726ade929294007f9ccab300c100a2a6","pub":"032ebdaeaa817d8b8bd206839e18d17a85bc44ff4d7f0a5367c4f48098b511b43d","addr":"449402b089274c0b78b40e6f45e8297badfc1bc1"},{"mnemonic":"elegant dune all subject country diet flag universe gap ability hello torch","master":"fba87eced090b1d991c077467db81d22e2691f9b15ea2e8ccf03a51a556ee13e","seed":"1f1cd5b090411b96728a6959a4639e3b2bd68d4ea5c6ceb801a5849af109650237d2a6727ac80e7b317c625faa593d7a8caefae3ffbb55f110bd66672cf516e5","priv":"31cf4c4c7e75e35e16e01071e2db66a51758c8cc2b5df3377462046e4d87f3d2","pub":"03722bc559c95cdd7baf08a6965a47a7762fb974a854d290295bd853f6be0a83cb","addr":"b7f0dfb1c5136bd9bc267e9c7b33c047d6a1429e"},{"mnemonic":"give citizen chief eagle horse alien below flip vanish eye sniff bus","master":"c3dc631ea1b0226bfa3572fe9b95d72d08bd160cdd5fbc2fc96866adaa49a431","seed":"196d5c0aa7839623842c51f2e5593695ddb596bcd839c70af2940e8d00f31dd68b45876ae7aeefc6032e8b939b4feb8114ce9c403e4b83e28a49ea69a97360ca","priv":"9fbb966c19808bb2b7d07c420f4aa59f7a41cce08499c4da2bc216d857ce86d0","pub":"02650905aba484a16f7c1a2b1bcd0ed4f16f45d1770cce32ed127bc046d5f2c3e0","addr":"1441b38310ffb1135c2c48269746894accf627a0"},{"mnemonic":"gym term crawl benefit kite various pepper noble into slim try then","master":"e5826174e32bce315c7baa21ca97c613b4eb095d74651867671afd3848343668","seed":"198b6d6de96c726477cf8cdde784fc43a89dd46ee8fea27933ab8daf09826ad0d7bdaa0c50f8d5c574f6f2e6ef7adabd9c2382feaae061c9cb10a3ba22c5dcac","priv":"ec23afe15c13d5f0c86a47b18ca81761976442cd7c07975c88d6ad475771694f","pub":"0331ddb4db50ff58ac1709986111cbacada08344bab6210da4a2f23b0c3208e100","addr":"625e5b098af6c98677a9a2cba960e84c11dfcee1"},{"mnemonic":"pause web there legal eight plug wheat convince adapt radar rely inquiry","master":"b13d46f4a0c6ef2cac56cb9c522dc35b8d02f4ed4f09f524d206e9ea6e6e6082","seed":"5f34196fb26a7bf0a9063284f702d934c03eb2ac10f3dc230a999e9566d3561b9dc0a61d199e7d9642b06474c08f9e12e618ac5cc1d805ec9cb9489d460f377f","priv":"b410cd330abf2a25f36b24fcbf72f73e5c62786cb5c0c24fdbc3cdf6ceb892f6","pub":"03755fa255c3f111f778c270f991a5cc0fc24c0068d78355ce340258aa7a3b81ce","addr":"170438465b203b844f98cf54b49cdf17094afd80"},{"mnemonic":"thought morning dad seat payment ball club goat man urge forget remain","master":"af52a1f224909be5cd5e7be0b960a995c1d25652cc0c6791060b98e1aab4ca9e","seed":"1e9bd47b5411fcdb8145b9eb1e7092eb218774c85da6efa3756e9a55e5ddc2153eeb568139c638af44cfe6cdc2a570451ed68c801dc2ff726b45ed43e8fd0691","priv":"5e42b1c08965620e1e647e89fe87c9079060121f5a0b65a5ca8cc462fdd13b20","pub":"03a7ca8e9445a67a6884f58e0e79b1571b34b90dad6df4c0b8dfd103e500bcb20d","addr":"f44393294c3f1369012836ab432386f1af2cce44"},{"mnemonic":"twenty memory ten own runway grocery polar dog curious program gap country","master":"f08104e81f54a7bdb17ee647c06009667d4d1ac6efe286495bcf2327c229adcd","seed":"10d3111f871ce9bda4a790e148657f6dae8586d0d80379d40e56cbf180876ef7ea5f2a66f006a8a8a46c7de99a4e4f8f5fa4cd1a3756a38a71971298af917d21","priv":"db3cc8657599d42858ee1f1a7480e68ee8cfecc0fbcca01556c1fe5e8f3a0025","pub":"02add58efeceddf43db9f3d12b54dcc1f1369f152d427a7ad5e3c8de5de23a16e3","addr":"eb30fff2557ca87addcffc02d3a237fd28511799"},{"mnemonic":"elevator sock worry budget skull bitter faith taste skill physical mass heavy","master":"bb2b406a20bc8b38709251d1cabf4631428e2ac053154db69e2f1c6d236c4716","seed":"71fd4f050ec95c4147aed32ea34bc065e67635315b1077a0e9453d883b0a4519015ebd5de2ad0f2a628c20881567532f3b679541e23892eca14d5ebf4456a8b0","priv":"ae56d8b12dd0cc788ec4d5eed7153b108aad7606d2f3653ba5c61bae06dd1cf2","pub":"0347f3d0ed7552ac8d667036f4403911b7a98f71cc1730223e74fee4194d0aeebf","addr":"98198786f5e46f72ac47e88168ede1378404ee70"},{"mnemonic":"message power uncle glimpse repair coin wasp flower alpha claim federal tourist","master":"28f596f188bfd9a0f1ba2729260fc20ecc1c1b67a20bc8a4f7bc0e810a625ec5","seed":"5a23114eb877a016fcbc82146957d2b9880ac79582776fecad126fd6b5aa81343cdc69c46f29ad17e19411f0f4e78817338a9fd39a72efcbad31ab965f8782ea","priv":"1376caa21630e355fe38924afbacded452c9552eafbd5b60dbf090fedae3d793","pub":"02713f022ea80f4807af048cd254ed4dc5a1276c21e4a7436306f83731843a5402","addr":"8a1cdab91bb44b089a51f0a736e914a37cdf20e0"},{"mnemonic":"infant walk right wave helmet punch alone path since output fashion isolate","master":"0de852a741c097122fccfc397d9ec55223ec1a6ef395c1848097a45aa6a4f0c5","seed":"d1fbf777f64ac5ab0375876dab5e934794782c73e84dfcb19a291a6a083d6aa6d0d3de7e8c804a8c02875ea5fa54a06159538f98f9174bc6cf69ec94e3bc682c","priv":"0fa223b1f217baf7a296e483ded5e6ee97facd5841fb85c78b5ecc4db7681838","pub":"0276da67ef9f098a2ee3a3a18d4ca17705448694f895c6ffc97959fd6507e904cc","addr":"02aacee8fb5e56f4b39fcbf7253b7a1302b0d8d6"},{"mnemonic":"type squeeze vocal monkey baby scale behind knife cherry luggage struggle what","master":"1e156273aae1d8c0b58558726d2f19924b1d06659adbe3539134f58a8a1ff82a","seed":"333847666190d4b5c9535920c47a6f68c586aa3f587cb7349542c0a30950f7208b3467ed437cd815007b11a4326f20b34f45335ba64cf9bcf17ef71aa10b9b86","priv":"c307afbc58b3561c7d276502e1b81de8b01c196bbdc1ccbde5855e00707f58ca","pub":"031a16f0dfd054f5d97233ce07cf647ad598a84177baa82d2f89a7f23cd0f2a0d7","addr":"3b1d109cab9545dbbe82631dd4f903b43cd79bcd"},{"mnemonic":"elder shallow catch anchor slice hundred kangaroo stereo myth proud clarify open","master":"babfd17c1c9647175a7b2739eb700c3385be4948f97d1dcd50cd17fbd605d6d2","seed":"eeb063599bfcd2520f7f07b3eb885cb83953ef9931926db8d1e76b689954ca902c6edb785af6d579ffe89f9253f5864cf21d3f7373986a6c1259e4bd0bd16437","priv":"652f38771bbddf64d2040c1300c317c42739f50839b604cc8f34e050b4590a95","pub":"02608acfabfda5579dae5d9efd4a191925864aa656e55b039da9736a874d46b8cc","addr":"f14a9e2a34c1cd6b95fdd473ddd799429fc03def"},{"mnemonic":"screen slim squirrel fox stairs still close club day satisfy either sentence","master":"a0101753f4e05c8ab9bfb6224120ef9c1f99ebaebc31c5aae114f68387676f5a","seed":"c1ec85f49b1928ed7ac6dc781703a66ef39692ba39f5296d9da33f93fd68cd85b0eb57cfb6ea115ceba67df15e4d835d813e3bbeea0363ef513220b98768316e","priv":"91af59d9bb62c2a2f0bf1b5c8729f2be88cc82e141fa045e59748f2b156b9a03","pub":"03a76d83455b42964c021906265a4e006d2c81555c8591a641ac0c495cd0d05cdf","addr":"093ad2a9be7153222002d94eefadef04ca7ea811"},{"mnemonic":"insect deer physical dog aunt metal super soda antenna broken undo athlete","master":"d3a4a655aafd0dd18e196b2f4e57bd4b1d27fe521f9312104ab75ac92ad92e62","seed":"9975a73239f3e2543108bec6d75c5c9a24261c9b2ffd0e088f6bc8369804b70ce99ddbced3c4cc2e1cd955be824f5d881af09e5ed403d7da2a533c73d9d82df8","priv":"0a313ab091f7fda44e92ba2482b8fe1294646bc9d27865bfb34ccd702376328e","pub":"02ff6999ead46c520026b1faa27004851fe1b2295e5f8b79ee1e87b330c45216d5","addr":"e3ba9de7fc81b75eaf4c6ff126b434dfda0a5008"},{"mnemonic":"layer embody trade slice odor deny please small clerk device ceiling right","master":"2b39b4a5aa164609c2734c00c1029534c5d7f3bc6b94268758acb506bb139608","seed":"1bd10cd1d50db3dd8f9e76ecf39b846d3a2aa44be383868921b155c03ed3485d52236c49783f5334c60e473458be3b3f588b9ac3e814d144128d96fbc002393a","priv":"5953e09dbaa56a12eb5e69231835924c0e38d5c322a43c354152a0333f26756a","pub":"02254c4d6976965f7c6122efdd52f65ee9e25b87549789499b72bf5d7213829d04","addr":"603d5b893cc41223eff641fc1a374a3ce97138a7"},{"mnemonic":"token heavy lazy little dry glass riot hobby keen blur wise okay","master":"7d84cf25bd5f7dabbdb7beae83d1fd128390b3a0fbf2d56b44fd34a7e0d11539","seed":"8f144bce2e5c73f44e5dd62ef4695c6e3457ddc37f64d1552e5b46a771120ccac23cd592b27a135c3593f8f21eff22625ca7bae8581f4f8ed223e813f5d98a6d","priv":"37d2c3993b275606241307c7b2339e304180555df260f18f524abcc75abfb0f3","pub":"02aa996bf4d889c9b37aacbd07d8ac3ea69e535c065a4b4258844b10c2a08eab8d","addr":"4a3860dc280c75a00382f3d8f11cfa01fda90188"},{"mnemonic":"tray drink color across armor spawn vast skin debate huge surround play","master":"e0cb1eb09b82bcd37fa63260e49222cf13b0b07cc1568aeb8849b538bda65a1f","seed":"faab52fca3060d1903e861706b57ca50ca71befd2d5363031128235cbb80e53ec943362f2288fcd1c850e94cf4e7c38029dff1880dc3f8c8bd440b14ed15fd01","priv":"747aaf84f110aefb34026ca0492894ccb8e0d1b34c5b0f9a9027320289914b52","pub":"022d3e35a5f51a6be1d0aff686e66e2fe282e42a51044ddca65b8a7659b6386f3c","addr":"43057d3d99231163cca42fe248b9d350ad7ae146"},{"mnemonic":"ring act drill burden sunny someone riot spawn uncover sauce today jeans","master":"676a5a20f35054b4f7ceb22d38226df0b2fa192b6bbdce9a96fba2b51845322d","seed":"979a3caac9130fab128a59243447f5add05251ad385f0c0ecca60920cc954ec516479aaf4def728770606db840088242a8bd5c3758f1ecfa7d3f8d54beb5cd6e","priv":"0e3f2306a70147cb332877343ff260e18c37d807d1ada3db3545dc21cb7adf71","pub":"03374f7d18335d1677902e2fb7c7afb6c3646ab18bc76d12793b86e0097d2b79fe","addr":"4f65a8364edc65cc430f4916af41cbf339c34a4f"},{"mnemonic":"title reopen welcome pottery stand safe scrap little razor rate oval rabbit","master":"600c330dca29a426ecae0e5e6dfcb13e004efcfcab0fcecab676e42462caded3","seed":"7554d02d091605c47acf117773dfb96821e28c551c2c5e855803f79f7ec9b9e5a4a7273c605c2a53771e045bcada466d3b4a88d03a7fcc1644d990a8dcb21ff8","priv":"79621755dac86e6026853bcd0d4c032b48b7c5eabf81cbf8ca4e9d056fcec5a8","pub":"03f63693949fdc2b62cabc47059e8b1d9ba748800bf08a30001e19aee33627d189","addr":"ae0c6ad31b94b29d502a846e1e371356a96a4f2d"},{"mnemonic":"hat stereo gold maple advance wreck poet dawn excite midnight kind type","master":"661d8b63856089b6f3d6bb37558d4deba395c7ea7797d022db398c3224696316","seed":"b13cc53d42e9726cdd9fda4279a660d987dc3d302409a0ccc844731ae1b138495200bd1ddee3912124dbe826e62567a9b9fb57a33b638cbc4a56f8b55df3182f","priv":"548da8b9469029522189b9d4e30f6b58c75f234f18b99d4f4dffd027b6e022ed","pub":"032df4ae6e9e3ed444bc1fe3eba670f2d877de7e579309fe3e7a8ea3b5176999e1","addr":"f94c66a0851fbdb52cb7b6774c736cfe4f99edae"},{"mnemonic":"image wolf among domain where post bicycle perfect cloth october bonus plug","master":"1751c464935d8be5b1f43188a61f14d0f509cbe289d5e586f1c5057299c05d56","seed":"80bc37cd3dacb7020735655be8a001ea26bd8a5a74d950a5ba3f31603bd929531d6da39d06499927e5acaaef4845b3403e73e3bbc7a43434242dd2b432f17529","priv":"38db8c107323379d07ec59fa7b76ceb436a5430468562fbabdecf4bd0a06d58a","pub":"02c5e7d3d224db89285ff2f71c27a68b267f9fd799f05ee334084edd4b91d4071c","addr":"40551f9071d46824a15fba194d98425698145795"},{"mnemonic":"squirrel grit cross witness wagon defense marriage tonight absurd organ load sing","master":"d5739288f3d99e1759690e2d68e5ba543151cd58a0d55d0be52f0a4cfcdc2a3d","seed":"a3e09aa4755d4a4c48f4611a7a8c22040feca1694415b2a6976d2ce161102557f5e855d5195b0132c9e7f23e01b825465eaa10b19ed323647ea5beac8a635e75","priv":"055f00180e4bf6548ba7b525236f63444808c0052fabc4eb14cdad2debf499a7","pub":"03f9831a1213aedf436bdd9e898f1d571ed6a7858f0168d60afce7ac389dc27d86","addr":"8a1289c49f8d83275e4c2201c87ded060ab38a36"},{"mnemonic":"cloth diamond test stay also risk music unit beauty escape trip draw","master":"6d16a7ccf9577b8948afab2ac83cb12ea124e9cf86506e6d08f3fd685ba97a71","seed":"d67dbc3d1e00b7703a7a44b91ddb891d89128f59d2f298b2a48f464aaea9852b97fd3002569d9e4b8a1cebf0d7eef3b708a944b1cb745844fc01b71829bbb2ac","priv":"d52b78224b5e2b9d074b4141dba1956b33f66ec7e8e271a20786d04136d1755a","pub":"020fd792486b8d8777b9910bcb1c28c52fdbaf239e07885b94ebf85edca05f3609","addr":"f571651ea3de2e84b53da4af619b1c51acdf9c13"},{"mnemonic":"vanish slush budget question demise bargain inner push weasel clay project project","master":"11828853c3e89d3515ac8c838d2a5107079c93695c430e2d5383fff8a0a98de2","seed":"9f838e1b4140cefd6857ecda55690fdf36bf4bf0247833801a481130844a89d0483b05e9cd1042a855714f67298a3f9d8cc093e6bf9e86b4c7bf16223f4f89d8","priv":"2e5945a384de4ed1030a299e8dddd2c9ca20aff939641e3cdbb00f5619b186f0","pub":"03a52a0f153c92a5fcde0f004c4ab3166f040b6e7e609afee6c2d0e494c18e7a75","addr":"09e3386e3636e365d8bfd15e822b0cb50136b5ba"},{"mnemonic":"blind desk mobile debate orchard nerve crack tower little scrub twist fantasy","master":"4d677a558cc1d0911ccea1c14c817b8fea57668f9a81af43ed036a1bbbd8b6ba","seed":"eb67d96512b6136ce060c7b7800fe48a8fc2ebf50a6051f4be4255a5e974fa0443f0c5ce1efb0b0a87f227b0da5d740452313d86561a42262e5681864b529054","priv":"d54dea50a4dbc94530ed3c04771c6f4c71487cf3562e89b79684fd6ab7843846","pub":"032622eaf55666e30dc53d73a88517f24a08f6ad703f02db30e87368c5344cbb17","addr":"eaf15d884294d6b72b618c55206db3685e1b0532"},{"mnemonic":"thumb nurse there alcohol legal agent abandon sight pill street speed catalog","master":"1a041414d1258b30a589e61e6d8ba19a34ca2b2e8bca68962c0c9dad5863f5a4","seed":"1b539679974f7355ee02c9d6609640acdae476ea23bc7d5982604e20009bf3ec153f9ec82fcae5de92570d2bf94672047557a36b3ad3f3ec03b910038658b816","priv":"5ee3c0258920c32da893a0fa051593544fd3547c6e37123ef9d6edaea940dfc3","pub":"03e8714f4d3e9c3e342dae646deb62c31cf3a4bda119a820b0ff6810b8e3d85383","addr":"a3eeef1bfc965df2fe15abf7cbf19b381a458478"},{"mnemonic":"crew venture wall front gesture jaguar often arm fly scare lunar guide","master":"656a72d27ab1a5fb50e27fb598037dc2ebf60b1b9f0bf7612a8490c1efed6b39","seed":"1cd2a5e644dfe51e367da6784848ec64ab3c4965818dd3529f00efdc102388b02dedb2207052bfaabb32a4039f76594b006aec871dbe9856f2b71fe6f426d75b","priv":"67cc3ba8f7d83c6d08737e1b56dfe469c21500f20fac09e8bc096a091682ae73","pub":"03ca0d6eac7a2663451d29012c25bcf469d12c556f30a57a34fe6d66d27d506db4","addr":"5acc54542938330e6961c6ee770760c135ede717"},{"mnemonic":"survey never crew section reward cotton praise ketchup treat suit knock text","master":"7175659726fd0ffbbd37fd2c7e309589d32b271672ca5459b7e1daf5f2daa105","seed":"a5a37f251e3c745169bed474c8ae6599da847ea473da32b8ff922f2c710a3c31034dfc45dee514af90246bbb1317e21669ccaa0666d3c88c8f729fddfb95d240","priv":"fdd98704f53d7ad0e43ae71437626048fe23f71c24a67f31b9491b60c4db3c9e","pub":"026936de280e31c060bcbc777bf28ed1ccd0128be0c25f9d074378f72db1de0f4a","addr":"997434efd190bbf98541832fc48283ff736a067e"},{"mnemonic":"lonely physical plastic final cool beef cloth chaos dizzy enough whale farm","master":"79842f02a7d39d8f19373fb1ca3c73f1961c916628279a00c96a980cdeade871","seed":"f957d8197386bd4ed6c5000bbbd02f70d6b4b76953dc6a3e36f021d488cec54293198f64fe6d46c52041bd34efbceb1e6cce3184a42c8fd37903b924112ba2f6","priv":"d58df19dab225b29ea77bfbcda84c2f1982ccb6e1eb79011bde7adcc03b95050","pub":"024ed971b9763ad9aa8be27d9b75d9ff2f443594da5e3e0b7a598c71f6c2e0d759","addr":"f4d72185f769724b50be932caf960a1a3951ea84"},{"mnemonic":"can three trend breeze spatial puzzle stool cherry raccoon sauce bounce balcony","master":"e76d9d768fe3ead9a6c1b561649b292d8659a6778442f9451a8fdd52e35637d7","seed":"85aae0e7a3e2efd67741cb0d752a078b250deb53927bea3f384d72661889409389188f267d7be61629c6a85aa7dc5b2607a066f32ac39a2c5efc4720b4a72e7e","priv":"57a934f4fdbb619a40394cda13acd1fc61ed9f17e4b4fcbcac2248b5703eb71e","pub":"02004c3736772a2cb507231b7ab75bfc7c1d35ca9e49523f1076e7d0925acce8ce","addr":"859915a9f70f142a41b0d169e7ec342061fbebdf"},{"mnemonic":"gaze example quote much tourist pitch victory common lazy message random glad","master":"6fdb41e8f54d6f123c75856c1c13caccb01bbd7e84b1c3385fb5fdb885f72f09","seed":"bdb5196003c1d1d272367b12affaa4d0cb37fb3aeea88bde6992dfd3519af34e94729ebc9e8057b9e462c064292a7cac18eeb838ec0f71b082cfd66bece3c5e4","priv":"1f264f1e86de3b28ea8f4827dee679787e60e34e81271139a8e74870518bce27","pub":"035e75a0beff3188c9d5aea7a760b879413ef712d98354b702aedc3385d58c903d","addr":"67c21921fa2c47c5657ae2434c29f447511fbab2"},{"mnemonic":"taste panda wreck guard trend blush armor giant innocent palm trouble silly","master":"8f3c32829998fdb3355b3a88caf484eaf7d67122c991c2402d77eb3e5e4f8416","seed":"fcf9f308ac99d81e74329f60787fd311848a2e56384202c37c025bafeb7022e4b47ca24a680d07d073566c487f39c8c0dc4bf43569b73f30ba4a2c260ce98e28","priv":"463194496ba851f6455e8298a0d4c118341bb0183c73c2d7739ef2c5bee38e0e","pub":"034a87ade739d3da37c8f15928db9b064bd1d1af0c10ffbb9f2027f42061c9bdf2","addr":"b0afd62cbf962672d092732872a6ab2795c9132c"},{"mnemonic":"tragic enter actress believe nominee floor vehicle dinner bulb useful case bamboo","master":"66f8cb0425dd278236de1352e9b2e47fbb8662d1de9d31227c4f18873b6aaf4d","seed":"5f0f5113b93be9036f009972fc49d9fa444c0dc4f89ad2e5d590f33b2aee250194494bfff047f8c9cc0261208d0d842f4c8a320d68f852c0938b6dd472a9c819","priv":"3fcea63ea530b9539af1ea66f5ceca1acc508fcf21a0d5ac21a378af5aabfb37","pub":"0256ac4246f19dbd12af232b2fe00efd158624ea48728b3a647c8237b7b9c1fe56","addr":"13804f3f5f0ba3c8f769b2e3428962f4ae88e4b0"},{"mnemonic":"between grocery tool polar already roast cash budget fatigue museum obvious notable","master":"c13b5bb1840f804c9b1da51fdb788f9262fad64b4c576370ede2d9c4001de2fe","seed":"1e5a866e10ee3ed7e727f59673328eae03808cfdb1bd3c9f155a1ce8f7c9bee61fd8d68d6b995588c0264400780467313ba92a9c359edc48ca59dcfff62567c4","priv":"08d7d4fa44f89fddc836ea265b71e9985363cf4e9ba0cb5b1ef0bfcbd00e0aa4","pub":"03514e8e0c990a6a60b1138351255827c7c46e15c3bc25f55946276b5fc56d9068","addr":"0c759c31f5f142dac57e712c7a09c99a3a0875ba"},{"mnemonic":"combine unique pig mind pair area chase idea abstract grow into result","master":"e7d06819461fbfccd1e05b6d63507b179854fd75fe7fcce2cd04ad6eb89fd11d","seed":"a1863842b2a6d82dca20ece807c12c58f6c4d2d1fcfc2577baa368a3a45a7ccb0650009ab558bc8350b77f9a03f6155e8c35f76ebf9b30133dc732ef5abe69cb","priv":"a545f01810112491c613a35c829157cc6a3dbd30b4b51f1d1eaa53fefb61e09b","pub":"02008752e98ab20e0fc8c9859884f97423c2315f5f35d1d757907b0affda7da9de","addr":"353ac98ae22d3161ce81bed93d7a0d77abd9e11a"},{"mnemonic":"bonus voyage inject they glory wreck soldier anchor also job cattle random","master":"cc5593732d2681a1aed33672cfe74f24238443d1b118235550834e14bc720235","seed":"ae6175dae17f8ab7481092eac1ee7d4c08d9ffeb69850745a1507c63426aaee1ef3bc6ae7fad3152d9bcb58e77a14a9570a4c550078c963991b215db64a2e9eb","priv":"45118b84fd5c7802b71fead3d78e5953e1841ccb4d4cddc20aa154e9fbfcf467","pub":"02a0378a67714f50eb383b47f7ab67b32c2adc2b8376b12da9e656ef11da9172c7","addr":"aa4e5ff5d78486413eef80525d20fc0a46befd5c"},{"mnemonic":"axis grace advance retreat fence prison traffic shield visual evoke upper they","master":"b0f1e554c9c4c38355939ec8641548df255dc8260ee2beb02eea8436359731fe","seed":"42d47d86e0eba00ac90f92e464cb034b25e3e261618ccb7893524e6103b8ab8edac9262e7417ca55cec0e5b90f0405d6b43b920317597d8b67c34f909b308ad9","priv":"0e986b99de5e1403218a3d6e64eda2c6e980002fc9345795464c6e100c4d214f","pub":"028193d72358fde04b71d553794171a3f6800d2d20d1d4821c2d411d9dcab044f0","addr":"68ef0232b6199e173a31b522f73b8740807e7991"},{"mnemonic":"speed advice script dynamic company foam mimic conduct wasp soft stick insane","master":"b0f61b56e248b14dc116231490779949a829920a9caf582fe25df4459e65108d","seed":"7b8b72a1bff2551f2e704e68f364b8d578e24bd6c51fead9805c2c33bf463dd462c793f73b88ca6353e8385a5baeba2c91e4efd6ccc2b80351cfed9d9a6d7738","priv":"32e5a08edf79a3192b221f978e209fee7f7d64f83c28ff57f47ff5757b727b14","pub":"02fa4ba71ba618ce2f1508b0386ceb0e09e202722353d9724a597cd680130c53e3","addr":"713ae3fbba6df605c843147183dfbf3a3fdd86c4"},{"mnemonic":"punch fame nasty actual betray melt find wink cross hobby double there","master":"a7bb2a4a7cc93d7dc12efe29071329febba1c999c4e7766172d9e53fe29cb0c8","seed":"6876d29989880fd1bae26463cd01cb148c68ea842603822657d0bdc708a8987cd33453087febfeda2f3ea53f2fcd65ee1c5f89b0cfd8aefefee2c81ed32c91e0","priv":"731b30c783b7cfeb7458db1e0c0db2586216b6ba661f1adff761977c782d24ef","pub":"03ee75f400c95ecc4b852cd1ea2b434f5cbdd2f6eb8a881f0f24a3d1098a6ce778","addr":"96ce0c791931f867dc4fddd2f091a552f1e57d26"},{"mnemonic":"feed session repair glad envelope pepper faculty earn hour slender cost boat","master":"d8507e0bbacaa494dd65a38d82c02f00d168ec8bdff9991f78ed5fc13ba81d38","seed":"aa9ac398fd8c94bef20e9b9a94bdb81fcafaec2453efaa2929730145528495515d7632de9cf558313a35d50c0428a15f01efc831379a696f632705bba7394ce8","priv":"ef95d3d563a0e774c8d486adeb2d22f4fcf4cddd80cd2a05471b691c12cfe0fd","pub":"026b711c8ed8ea414276c9d7c7a92739a350cbf01372d41c2160c046e1459223be","addr":"72da6e869b7d435ff2507e658acb26e0a50e6303"},{"mnemonic":"person affair gesture cherry intact day wrestle crew okay express throw large","master":"84a10e3f12a6d24e76cd66e934116f9478d8b1bf912fc61c9e00058f7c489f6a","seed":"5dbd3c2fe715a4dd9ca5129df8fddac1f699429636a58bcc2379791af11dcd77bd9b84f3d62539bf5eb41eb8fc966304cf334cc46133b7e42104a18733514777","priv":"337a826c33caf41a74b465c6981986d629c13a71aeef4c0e7c2b78fc3dff613b","pub":"03edadf784d13c4e22b33b61222e20348cc68e245d8b143dde09d37963e9e01eef","addr":"916fd4d732155d78fd412b4cd78abb49bac56c19"},{"mnemonic":"nose talent woman drip regular endless bar resemble friend mean frog cage","master":"1beb38f144a90141600a34813e98ac3cca43009e23c542b3009f3e22988b9705","seed":"aa324508ec3951c30fa4b32ca7a4ea48773c572652076a2a7e6aadec3faee23c3388663002b086483f39a1b08fd50ff233ddefded05f583211686d0323dd4d64","priv":"67109cb296022e46fbd12569cbbaeecec1843479bc716f7ed07ff996561f8196","pub":"03239409138ec1b5a60e5d72f894e95d599be18978d9f43bf201c85bc20210b473","addr":"580cdfe5a38f37a644204cd1d4b0094dffb982d6"},{"mnemonic":"undo thrive relax ancient menu milk sand race bargain evidence steak tomorrow","master":"1db1b33c9f26783cf9743ec719022a1280c8257ba11b2b03f35455cdfeb10ddb","seed":"b9905331927ef09ae2dbf5bec382cf3f18bd9cc03bbd4d21e8f63cbde32cd22abf07bdea578a201558f2a1f09f2fec8e3c7557f731a57439f1e348bd7530d9f3","priv":"c91c34d1a5218ecbfb63990b636d8bcbf6d7ba4723b70c960597f1b4ffb2854b","pub":"03c7d4b726c2ef316d8e60f0941e2af09c0cc1a9967aed825c322b629f74ebbab0","addr":"cbc5acf5001cb4d88fe88404cf3d1a919b127aa5"},{"mnemonic":"relax owner update nice speak office assault pottery uphold clump since ball","master":"5540b4c874952470d93f8a94689bd58c03c8bff373c74890e70b63caf9b5fe48","seed":"c3e8c04ce0d472761c468cdc13d04cd8fee5333a806259657923aad79d9bab8333329353e69cd3fc67833a7041a2c49f3c2b0654a4d243415f3f2761a4f7fa29","priv":"882ea08c9157b6bbfd686007ad668de373f34dbeb08e5d983a447a12c9efad3e","pub":"022f8b50589f2413d294e33de8fcac751c4c6ae54b359ba428c4a1ae28cd2ff57f","addr":"6ec1ae2736cb2a9e1dae6b5d5c7d408347db2dce"},{"mnemonic":"immune find story sadness depend debris popular swallow egg gauge firm drop","master":"fa46f28a8f32770393d3a3fd934141823d48ae561d8952ef3ac87839867840c7","seed":"6b5234df2c1b9ecb85d8493849e66186f98a828287e133cffc210140d63bee412ec58ede1968c2999485ef80710a83a99e7ffe205c404c5bda7346369c16f6fa","priv":"77cc4d765ee74267ea50ce3637ff9916370802a4940bffc8f7b76aac869ef80d","pub":"037d1e64685d2229c9b49baf2245511b3dc26733e1275c36f60555e2eeee32aead","addr":"80d9e410145ca65c65f143804e7e13f0572693af"},{"mnemonic":"airport refuse lake shuffle borrow depend agree oven huge hen brand reward","master":"b21a47b26023f1ed1963f81a2ec424c88520055cb2d69c329c76e6a354cccf91","seed":"7ae802a81c37abaf146f9c7606409640c53a3502da921347dbc260fc4fa5a164ec458480038ac10a3dc2c5ec15c600e72e011392413e13b9daeea82c2e9ef611","priv":"748f3e6cb6caafe5a188d528557ec1c1e817f990394bea8a011e3cbf6d00a3ec","pub":"029f0f4e5bf957c569e9cbb814295acaa1bb8bbdd549844246f86656ab700cd35f","addr":"005b3c2696248d3e45b43c88e258b2dee69ae542"},{"mnemonic":"slim trap alone fetch people skate middle since yard frown during smile","master":"1db54486ad20e5fd82e7c5bcab652cd01632014d66ccf0f7d6c39bc0a337fd77","seed":"30c3948e518b8ca06625fd7a1318984997ff587aa865207b54d5c9c469386e66e06656fe020665501a1f0a07636a250ddf5c127d5bd9ec497052b9e4ff2dc37d","priv":"0ce3645a3f7a1ae02535852fbfee9c59609eeb226a975ae24c94b7a13acb4d85","pub":"03b3f40812780bd4f8a596c0131ced87b9b981e4950f5217f44de7f777b4d29b35","addr":"7777090b6e5ae18d4a146a0c9c17a1a34cde74da"},{"mnemonic":"vague melody fine buffalo spread nation reduce spirit humor fruit spin diary","master":"7a5951d167793eb5d42307c68a3997fec7c34d56562dcab752c2559b97507e3c","seed":"aeb4a2ee7a25712bb76b26c654f5a79b4e92c25689799de2a11283a668aabc3d967d111e2bd98691dc2b72adb66188888999e0ce03ab2bf1b18e8d5d7f8c528d","priv":"d2dd273a93786422dc68e61e67dc0c48402af5964f85d5d785476bbcc68e99c5","pub":"0347a23bf9c802d6d826367a34219ff155a720b068bb0cc4f9c679d350f35a978a","addr":"88679cd2c43e562c21738ba5ffc8bff82575bc6d"},{"mnemonic":"ahead glad fame hip era kite pyramid endless sponsor tissue winner kite","master":"eafe3d2af7a63b644668dfd23b7f0868a1d6527b630860f79838fc520896e64e","seed":"91f06eed5517fa2367c272a18362085775cc9d8f13b2358ab32d0c626abd87aefb8ffdd1f37712d4c39fb625ff4aa56cfe06a3054e162bb62fb03755a19f970a","priv":"c8d580087355904e691ad5292775989853e59ce1d41d224f97d2d4b96f8514d1","pub":"0342c4be0ea075609aa181fb83ffa189ec9744c2a7c54f7d3fa2273ba01ae127e8","addr":"ebd946e96a89c8932ec788d66f3fe8c482622831"},{"mnemonic":"clump earth diary ostrich section column practice rapid hotel mom client adjust","master":"c6be4ea8b2810f07731b7258f2a2cf4a4bd0722e43081957bd74ccb5955bed55","seed":"04c2178510fe5f7afe60cf8718bc5240da95cc2a79d28fb2bce756a2fb0995f25c5921addae1932dcc4b62ee68b330d3abfe190f212f809816ee7c6d5b816095","priv":"d2ecfc9fffd24c8299647fc2f23a16a2e5b35ec6092563ae731d4737159ce03d","pub":"027c615b33b69f5599cb800a85073582bb2180f20bedd1bb3e8384bada13ab8f92","addr":"df913518315ba257805f9ea9f78c859428d101d9"},{"mnemonic":"teach salt dinner dinner escape cheap gate major bind armor dash gallery","master":"954d52c8574645c888e4eea6ca661fd1ca4764ca9e4243bc75610571a24ec5ac","seed":"7c3753fb498e2a48af89e5a39153382eb9591eb8a5bb2cc5b8bf690bb6d1365162bccfbc9d5e3688f48352f1f8915c376dfacc3c3cad9315fa60cb303161ac77","priv":"c3a850ce632a7ab061e378596cb4c66a6880d41f6b09b0868d8c7e96bde490fe","pub":"02a615c68dd2bb66d3cc9d7e46a0fa00510542471a19b1d48fe05355acf38903b6","addr":"db50721f5b6e0907490990182793ae796756bc7b"},{"mnemonic":"cement casino erupt clever gasp benefit response invest diet banner month hill","master":"97c777e73bebf40d39c4efe8fb74db3cedcf2e1ebd366520515ee2823a9c4d28","seed":"9344a709e0d53322b928e3128d1bc707216eb0e1ebb137f74fbde6cd066f88b86088793a5794df8cfbd6efb12c843399e8ccb958446fa558573b013d33236436","priv":"96464373c492c388bc4a2c421ed0f5017fb426ac95e55f0f322703b28012cf90","pub":"03e71c89b2629c032b6c9a35b46d572dd0db3dde47bd5919bed8457885553148b1","addr":"493af641ce946561f6cb3116a135fe6e6b1b0f13"},{"mnemonic":"supreme news pyramid sheriff attract volume zone innocent hat grunt gorilla mango","master":"2ba0cd68329e2b19d5c24c1d3fca44513151fc4a634e52756290967989883b52","seed":"efbf7e16af697b4dd62a876f62f08698e29531c05018bb6da7ce441340b0278353d5d08a88cb93c4fd9bdb14fb85ab857ea3e8ef13b49dabb20beae2f13af3fa","priv":"15b89635f69b28cee0aa00d0609b99f1a1dd3c83e3bd57032987146cd47cebb8","pub":"021ae715a05c4849519acbe8dbf7ff4031d18f57de1bcf9cb1a06d50e5ebdbf661","addr":"e3087b309db8490b23629cbe4d113c1ea5bb525e"},{"mnemonic":"way chat van put negative minute tail dress spawn crunch beef moment","master":"e0dff85e10808c3ac560957a46f5f86abbfc62251c8fd4c61cb5e089a0841e7a","seed":"eb14b38f90886c1a1d47ac42205b564a649a0cf6edbd88cda1c488ee700aae8b735d7e947efc5711e2cc02b2254690ff4a69d149d2e13affd6d9a3915ac9dceb","priv":"7fb5464c8bc2e1583105d34c6850fb332a578fea35dff9528422c8b7f3156242","pub":"02745f0fbe0b23688e9691f9c4a088bf1342100fe3b9f7e405df79bddd57f8e6e1","addr":"66d90273421fadbab93fb9b05ea6e572f8af7050"},{"mnemonic":"tattoo strong tool weapon blue cricket kick holiday medal club stage reason","master":"bc82d196675dbad1c24d78f4e400a8956297c6113d4004356963ca88617597b3","seed":"9cf6193178f1a6391105c79cc6d3d2e2a4fe97f44738f8f716fb5b17a3eacd4061f9bb7f0411b08d77dc10b16b9599e45e8ffa55ff7f8e5c9274bab71bfe120f","priv":"5925547ee089b4638743f0fabe33f925780772a65b87b8315acf7f523d044482","pub":"03bba775f325b1ad28ec0adf66c8e15f90d70368fa021be5db199a5188c0621eb4","addr":"1f63ff4af01b5b5f33e60b82646a39917b6a7305"},{"mnemonic":"rug diagram spend zebra occur neglect choose relax face when spell stem","master":"d7932ffb8f6b751543caed7158318a05f4686646e636b5725b9b0419fb66912b","seed":"b73957a412d9e4c677edef4cb3a376c7355f78bba347a61f44c85f76b2c8a3d8ac2bd6c3b70643bf19b8487dcdce3055aaf86921e29e5e6f89700e0e2bf00546","priv":"c827dfe5f1880d9c462985b915ff78a1ab615ff0840f3f125f618cef25e14a5c","pub":"031bfd2158660168795f38f980951921f6fa1d522ad460ac5f93dfc4a2eac91f7d","addr":"b866f1e9b5b7b00fbb6076915a0a2931cba6e029"},{"mnemonic":"faith bless there mountain stand cannon sick abstract fiscal theory begin easy","master":"9af948584294b3951e6c664423a12fdfe29a31d41546b911f3fcdf664399aa48","seed":"17b6451f4b9765fdc3ed280fb5a6141b8003c8c9d8c73afce3192e15012fd18431850ebcaa07fa08da2c648f0f97f45e33ebdea6c99f2f23a9e244a297596499","priv":"e759b35d18e8b60726e882a11ea830e30ddff6752a19bec6983fdecf655726b0","pub":"03151da31179657f296184543a1360bcb92983a12788b268db0c20d895e6c449b1","addr":"54ec389ea177e1a4fe2f98cd83f27cce218b9081"},{"mnemonic":"combine fine crowd enter check mule toward damage fortune bless topple source","master":"b831b7a1b85edf1945c892dd332419e7f3a5125229cdfe1c73cc0e964abb4b5c","seed":"d9456b80f01787607d9c3adecdd6fa299132d748ae4fab843b3802c798ea1bc0395f9a1dc29e1badccc742f3c4fa081bdd7b6f9ca8980009b75c892438020b9f","priv":"d9d037b9baf0796d8a151935c172b1f775c1875b3811bcfd6c3f477e74c5c54e","pub":"03c720f00c921ab13307d3790f742f0a40436fad9d999087c267107ce50f8fe2b9","addr":"4b5a1c53f8442c375e9af35937ff0471155c0bee"},{"mnemonic":"shift nut floor scorpion property sun either total follow glide special apology","master":"1a4520e80df55ad59d95fca8dfab5f09753f6e26f7f38f654f32e4fa6f3ff963","seed":"a9df829ec832270d1ef0b0b04542e351ab9145baf086231fbe9636120c18c8d545ed138c37c0612d296c915340f982b1d83bd408301de79c08e4580ce0ce8fdd","priv":"27b1742305c3921c0cc041dc79d6e3c83112828f3fd49e18f31cb0b422bc1c80","pub":"032b322eedf502edf5e6c24ad80ad4bde37e04de012b9bf9c8caa41151a9ccf74f","addr":"2ce4a3aeb7e0fc52c31121651346959d1cfcc1be"}] From 49569ac244c6103e190f13d626d9ef2069f8f2d2 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sun, 19 Mar 2017 17:56:33 +0100 Subject: [PATCH 050/287] Wrap constructor to create xxxS structs and avoid recursion --- priv_key.go | 7 +++++++ pub_key.go | 7 +++++++ signature.go | 7 +++++++ signature_test.go | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/priv_key.go b/priv_key.go index f2d108ee5..7c2543abe 100644 --- a/priv_key.go +++ b/priv_key.go @@ -41,6 +41,13 @@ type PrivKeyS struct { PrivKey } +func WrapPrivKey(pk PrivKey) PrivKeyS { + for ppk, ok := pk.(PrivKeyS); ok; ppk, ok = pk.(PrivKeyS) { + pk = ppk.PrivKey + } + return PrivKeyS{pk} +} + func (p PrivKeyS) MarshalJSON() ([]byte, error) { return privKeyMapper.ToJSON(p.PrivKey) } diff --git a/pub_key.go b/pub_key.go index 45a4db92c..ad7a54005 100644 --- a/pub_key.go +++ b/pub_key.go @@ -36,6 +36,13 @@ type PubKeyS struct { PubKey } +func WrapPubKey(pk PubKey) PubKeyS { + for ppk, ok := pk.(PubKeyS); ok; ppk, ok = pk.(PubKeyS) { + pk = ppk.PubKey + } + return PubKeyS{pk} +} + func (p PubKeyS) MarshalJSON() ([]byte, error) { return pubKeyMapper.ToJSON(p.PubKey) } diff --git a/signature.go b/signature.go index b5fc36bf3..7a03dc6d3 100644 --- a/signature.go +++ b/signature.go @@ -31,6 +31,13 @@ type SignatureS struct { Signature } +func WrapSignature(sig Signature) SignatureS { + for ssig, ok := sig.(SignatureS); ok; ssig, ok = sig.(SignatureS) { + sig = ssig.Signature + } + return SignatureS{sig} +} + func (p SignatureS) MarshalJSON() ([]byte, error) { return sigMapper.ToJSON(p.Signature) } diff --git a/signature_test.go b/signature_test.go index f6c8c37be..f04262b77 100644 --- a/signature_test.go +++ b/signature_test.go @@ -107,3 +107,37 @@ func TestSignatureEncodings(t *testing.T) { assert.True(t, strings.HasPrefix(text, tc.sigName)) } } + +func TestWrapping(t *testing.T) { + assert := assert.New(t) + + // construct some basic constructs + msg := CRandBytes(128) + priv := GenPrivKeyEd25519() + pub := priv.PubKey() + sig := priv.Sign(msg) + + // do some wrapping + pubs := []PubKeyS{ + WrapPubKey(nil), + WrapPubKey(pub), + WrapPubKey(WrapPubKey(WrapPubKey(WrapPubKey(pub)))), + WrapPubKey(PubKeyS{PubKeyS{PubKeyS{pub}}}), + } + for _, p := range pubs { + _, ok := p.PubKey.(PubKeyS) + assert.False(ok) + } + + sigs := []SignatureS{ + WrapSignature(nil), + WrapSignature(sig), + WrapSignature(WrapSignature(WrapSignature(WrapSignature(sig)))), + WrapSignature(SignatureS{SignatureS{SignatureS{sig}}}), + } + for _, s := range sigs { + _, ok := s.Signature.(SignatureS) + assert.False(ok) + } + +} From 750b25c47a5782f5f2b773ed9e706cb82b3ccef4 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 21 Mar 2017 21:13:50 +0100 Subject: [PATCH 051/287] Update go-data, test embedding strategies --- embed_test.go | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++ priv_key.go | 4 +- pub_key.go | 4 +- signature.go | 4 +- 4 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 embed_test.go diff --git a/embed_test.go b/embed_test.go new file mode 100644 index 000000000..71852848e --- /dev/null +++ b/embed_test.go @@ -0,0 +1,126 @@ +package crypto_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + data "github.com/tendermint/go-data" +) + +type Foo struct { + Name string +} + +func (f Foo) Greet() string { + return "Foo: " + f.Name +} + +type Bar struct { + Age int +} + +func (b Bar) Greet() string { + return fmt.Sprintf("Bar #%d", b.Age) +} + +type PubNameInner interface { + Greet() string +} + +type privNameInner interface { + Greet() string +} + +type Greeter interface { + Greet() string +} + +var ( + pubNameMapper, privNameMapper data.Mapper +) + +// register both public key types with go-data (and thus go-wire) +func init() { + pubNameMapper = data.NewMapper(PubName{}). + RegisterImplementation(Foo{}, "foo", 1). + RegisterImplementation(Bar{}, "bar", 2) + privNameMapper = data.NewMapper(PrivName{}). + RegisterImplementation(Foo{}, "foo", 1). + RegisterImplementation(Bar{}, "bar", 2) +} + +type PubName struct { + PubNameInner +} + +func (p PubName) MarshalJSON() ([]byte, error) { + return pubNameMapper.ToJSON(p.PubNameInner) +} + +func (p *PubName) UnmarshalJSON(data []byte) error { + parsed, err := pubNameMapper.FromJSON(data) + if err == nil && parsed != nil { + p.PubNameInner = parsed.(PubNameInner) + } + return err +} + +type PrivName struct { + privNameInner +} + +func (p PrivName) MarshalJSON() ([]byte, error) { + return privNameMapper.ToJSON(p.privNameInner) +} + +func (p *PrivName) UnmarshalJSON(data []byte) error { + parsed, err := privNameMapper.FromJSON(data) + if err == nil && parsed != nil { + p.privNameInner = parsed.(privNameInner) + } + return err +} + +// TestEncodeDemo tries the various strategies to encode the objects +func TestEncodeDemo(t *testing.T) { + assert, require := assert.New(t), require.New(t) + // assert := assert.New(t) + // require := require.New(t) + + cases := []struct { + in, out Greeter + expected string + }{ + {PubName{Foo{"pub-foo"}}, &PubName{}, "Foo: pub-foo"}, + {PubName{Bar{7}}, &PubName{}, "Bar #7"}, + // Note these fail - if you can figure a solution here, I'll buy you a beer :) + // {PrivName{Foo{"priv-foo"}}, &PrivName{}, "Foo: priv-foo"}, + // {PrivName{Bar{9}}, &PrivName{}, "Bar #9"}, + } + + for i, tc := range cases { + // make sure it is proper to start + require.Equal(tc.expected, tc.in.Greet()) + fmt.Println(tc.expected) + + // now, try to encode as binary + b, err := data.ToWire(tc.in) + if assert.Nil(err, "%d: %#v", i, tc.in) { + err := data.FromWire(b, tc.out) + if assert.Nil(err) { + assert.Equal(tc.expected, tc.out.Greet()) + } + } + + // try to encode it as json + j, err := data.ToJSON(tc.in) + if assert.Nil(err, "%d: %#v", i, tc.in) { + err := data.FromJSON(j, tc.out) + if assert.Nil(err) { + assert.Equal(tc.expected, tc.out.Greet()) + } + } + } +} diff --git a/priv_key.go b/priv_key.go index 7c2543abe..3a9a5f69b 100644 --- a/priv_key.go +++ b/priv_key.go @@ -32,8 +32,8 @@ var privKeyMapper data.Mapper // register both private key types with go-data (and thus go-wire) func init() { privKeyMapper = data.NewMapper(PrivKeyS{}). - RegisterInterface(PrivKeyEd25519{}, NameEd25519, TypeEd25519). - RegisterInterface(PrivKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) + RegisterImplementation(PrivKeyEd25519{}, NameEd25519, TypeEd25519). + RegisterImplementation(PrivKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) } // PrivKeyS add json serialization to PrivKey diff --git a/pub_key.go b/pub_key.go index ad7a54005..a047edb2f 100644 --- a/pub_key.go +++ b/pub_key.go @@ -27,8 +27,8 @@ var pubKeyMapper data.Mapper // register both public key types with go-data (and thus go-wire) func init() { pubKeyMapper = data.NewMapper(PubKeyS{}). - RegisterInterface(PubKeyEd25519{}, NameEd25519, TypeEd25519). - RegisterInterface(PubKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) + RegisterImplementation(PubKeyEd25519{}, NameEd25519, TypeEd25519). + RegisterImplementation(PubKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) } // PubKeyS add json serialization to PubKey diff --git a/signature.go b/signature.go index 7a03dc6d3..bb9d82009 100644 --- a/signature.go +++ b/signature.go @@ -22,8 +22,8 @@ var sigMapper data.Mapper // register both public key types with go-data (and thus go-wire) func init() { sigMapper = data.NewMapper(SignatureS{}). - RegisterInterface(SignatureEd25519{}, NameEd25519, TypeEd25519). - RegisterInterface(SignatureSecp256k1{}, NameSecp256k1, TypeSecp256k1) + RegisterImplementation(SignatureEd25519{}, NameEd25519, TypeEd25519). + RegisterImplementation(SignatureSecp256k1{}, NameSecp256k1, TypeSecp256k1) } // SignatureS add json serialization to Signature From 66ecd7705fa16cb786cbcfc00513aa88b8251230 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 21 Mar 2017 21:44:24 +0100 Subject: [PATCH 052/287] Use new naming scheme PubKey{PubKeyInner} --- embed_test.go | 1 - encode_test.go | 22 ++++++++--------- priv_key.go | 57 +++++++++++++++++++++++++------------------ pub_key.go | 62 +++++++++++++++++++++++------------------------ pub_key_test.go | 2 +- signature.go | 49 ++++++++++++++++++++++--------------- signature_test.go | 38 ++++++++++++++--------------- 7 files changed, 124 insertions(+), 107 deletions(-) diff --git a/embed_test.go b/embed_test.go index 71852848e..77b821f03 100644 --- a/embed_test.go +++ b/embed_test.go @@ -103,7 +103,6 @@ func TestEncodeDemo(t *testing.T) { for i, tc := range cases { // make sure it is proper to start require.Equal(tc.expected, tc.in.Greet()) - fmt.Println(tc.expected) // now, try to encode as binary b, err := data.ToWire(tc.in) diff --git a/encode_test.go b/encode_test.go index 977cc64cf..667132a6f 100644 --- a/encode_test.go +++ b/encode_test.go @@ -50,17 +50,17 @@ func checkJSON(t *testing.T, in interface{}, reader interface{}, typ string) { func TestKeyEncodings(t *testing.T) { cases := []struct { - privKey PrivKeyS + privKey PrivKey keyType byte keyName string }{ { - privKey: PrivKeyS{GenPrivKeyEd25519()}, + privKey: WrapPrivKey(GenPrivKeyEd25519()), keyType: TypeEd25519, keyName: NameEd25519, }, { - privKey: PrivKeyS{GenPrivKeySecp256k1()}, + privKey: WrapPrivKey(GenPrivKeySecp256k1()), keyType: TypeSecp256k1, keyName: NameSecp256k1, }, @@ -68,19 +68,19 @@ func TestKeyEncodings(t *testing.T) { for _, tc := range cases { // check (de/en)codings of private key - priv2 := PrivKeyS{} + priv2 := PrivKey{} checkWire(t, tc.privKey, &priv2, tc.keyType) assert.EqualValues(t, tc.privKey, priv2) - priv3 := PrivKeyS{} + priv3 := PrivKey{} checkJSON(t, tc.privKey, &priv3, tc.keyName) assert.EqualValues(t, tc.privKey, priv3) // check (de/en)codings of public key - pubKey := PubKeyS{tc.privKey.PubKey()} - pub2 := PubKeyS{} + pubKey := tc.privKey.PubKey() + pub2 := PubKey{} checkWire(t, pubKey, &pub2, tc.keyType) assert.EqualValues(t, pubKey, pub2) - pub3 := PubKeyS{} + pub3 := PubKey{} checkJSON(t, pubKey, &pub3, tc.keyName) assert.EqualValues(t, pubKey, pub3) } @@ -95,17 +95,17 @@ func toFromJSON(t *testing.T, in interface{}, recvr interface{}) { func TestNilEncodings(t *testing.T) { // make sure sigs are okay with nil - a, b := SignatureS{}, SignatureS{} + a, b := Signature{}, Signature{} toFromJSON(t, a, &b) assert.EqualValues(t, a, b) // make sure sigs are okay with nil - c, d := PubKeyS{}, PubKeyS{} + c, d := PubKey{}, PubKey{} toFromJSON(t, c, &d) assert.EqualValues(t, c, d) // make sure sigs are okay with nil - e, f := PrivKeyS{}, PrivKeyS{} + e, f := PrivKey{}, PrivKey{} toFromJSON(t, e, &f) assert.EqualValues(t, e, f) diff --git a/priv_key.go b/priv_key.go index 3a9a5f69b..f00a762d8 100644 --- a/priv_key.go +++ b/priv_key.go @@ -11,8 +11,8 @@ import ( "github.com/tendermint/go-wire" ) -// PrivKey is part of PrivAccount and state.PrivValidator. -type PrivKey interface { +// PrivKeyInner is now the interface itself, use PrivKey in all code +type PrivKeyInner interface { Bytes() []byte Sign(msg []byte) Signature PubKey() PubKey @@ -31,37 +31,45 @@ var privKeyMapper data.Mapper // register both private key types with go-data (and thus go-wire) func init() { - privKeyMapper = data.NewMapper(PrivKeyS{}). + privKeyMapper = data.NewMapper(PrivKey{}). RegisterImplementation(PrivKeyEd25519{}, NameEd25519, TypeEd25519). RegisterImplementation(PrivKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) } -// PrivKeyS add json serialization to PrivKey -type PrivKeyS struct { - PrivKey +// PrivKey handles all encoding and exposes methods +type PrivKey struct { + PrivKeyInner } -func WrapPrivKey(pk PrivKey) PrivKeyS { - for ppk, ok := pk.(PrivKeyS); ok; ppk, ok = pk.(PrivKeyS) { - pk = ppk.PrivKey +func WrapPrivKey(pk PrivKeyInner) PrivKey { + if wrap, ok := pk.(PrivKey); ok { + pk = wrap.Unwrap() } - return PrivKeyS{pk} + return PrivKey{pk} } -func (p PrivKeyS) MarshalJSON() ([]byte, error) { - return privKeyMapper.ToJSON(p.PrivKey) +func (p PrivKey) Unwrap() PrivKeyInner { + pk := p.PrivKeyInner + for wrap, ok := pk.(PrivKey); ok; wrap, ok = pk.(PrivKey) { + pk = wrap.PrivKeyInner + } + return pk +} + +func (p PrivKey) MarshalJSON() ([]byte, error) { + return privKeyMapper.ToJSON(p.PrivKeyInner) } -func (p *PrivKeyS) UnmarshalJSON(data []byte) (err error) { +func (p *PrivKey) UnmarshalJSON(data []byte) (err error) { parsed, err := privKeyMapper.FromJSON(data) if err == nil && parsed != nil { - p.PrivKey = parsed.(PrivKey) + p.PrivKeyInner = parsed.(PrivKeyInner) } return } -func (p PrivKeyS) Empty() bool { - return p.PrivKey == nil +func (p PrivKey) Empty() bool { + return p.PrivKeyInner == nil } func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { @@ -75,22 +83,23 @@ func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { type PrivKeyEd25519 [64]byte func (privKey PrivKeyEd25519) Bytes() []byte { - return wire.BinaryBytes(struct{ PrivKey }{privKey}) + return wire.BinaryBytes(PrivKey{privKey}) } func (privKey PrivKeyEd25519) Sign(msg []byte) Signature { privKeyBytes := [64]byte(privKey) signatureBytes := ed25519.Sign(&privKeyBytes, msg) - return SignatureEd25519(*signatureBytes) + return WrapSignature(SignatureEd25519(*signatureBytes)) } func (privKey PrivKeyEd25519) PubKey() PubKey { privKeyBytes := [64]byte(privKey) - return PubKeyEd25519(*ed25519.MakePublicKey(&privKeyBytes)) + pubBytes := *ed25519.MakePublicKey(&privKeyBytes) + return WrapPubKey(PubKeyEd25519(pubBytes)) } func (privKey PrivKeyEd25519) Equals(other PrivKey) bool { - if otherEd, ok := other.(PrivKeyEd25519); ok { + if otherEd, ok := other.Unwrap().(PrivKeyEd25519); ok { return bytes.Equal(privKey[:], otherEd[:]) } else { return false @@ -153,7 +162,7 @@ func GenPrivKeyEd25519FromSecret(secret []byte) PrivKeyEd25519 { type PrivKeySecp256k1 [32]byte func (privKey PrivKeySecp256k1) Bytes() []byte { - return wire.BinaryBytes(struct{ PrivKey }{privKey}) + return wire.BinaryBytes(PrivKey{privKey}) } func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature { @@ -162,18 +171,18 @@ func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature { if err != nil { PanicSanity(err) } - return SignatureSecp256k1(sig__.Serialize()) + return WrapSignature(SignatureSecp256k1(sig__.Serialize())) } func (privKey PrivKeySecp256k1) PubKey() PubKey { _, pub__ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) var pub PubKeySecp256k1 copy(pub[:], pub__.SerializeCompressed()) - return pub + return WrapPubKey(pub) } func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool { - if otherSecp, ok := other.(PrivKeySecp256k1); ok { + if otherSecp, ok := other.Unwrap().(PrivKeySecp256k1); ok { return bytes.Equal(privKey[:], otherSecp[:]) } else { return false diff --git a/pub_key.go b/pub_key.go index a047edb2f..fa91b12f4 100644 --- a/pub_key.go +++ b/pub_key.go @@ -13,8 +13,8 @@ import ( "golang.org/x/crypto/ripemd160" ) -// PubKey is part of Account and Validator. -type PubKey interface { +// PubKeyInner is now the interface itself, use PubKey struct in all code +type PubKeyInner interface { Address() []byte Bytes() []byte KeyString() string @@ -26,37 +26,45 @@ var pubKeyMapper data.Mapper // register both public key types with go-data (and thus go-wire) func init() { - pubKeyMapper = data.NewMapper(PubKeyS{}). + pubKeyMapper = data.NewMapper(PubKey{}). RegisterImplementation(PubKeyEd25519{}, NameEd25519, TypeEd25519). RegisterImplementation(PubKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) } -// PubKeyS add json serialization to PubKey -type PubKeyS struct { - PubKey +// PubKey add json serialization to PubKeyInner +type PubKey struct { + PubKeyInner } -func WrapPubKey(pk PubKey) PubKeyS { - for ppk, ok := pk.(PubKeyS); ok; ppk, ok = pk.(PubKeyS) { - pk = ppk.PubKey +func WrapPubKey(pk PubKeyInner) PubKey { + if wrap, ok := pk.(PubKey); ok { + pk = wrap.Unwrap() } - return PubKeyS{pk} + return PubKey{pk} } -func (p PubKeyS) MarshalJSON() ([]byte, error) { - return pubKeyMapper.ToJSON(p.PubKey) +func (p PubKey) Unwrap() PubKeyInner { + pk := p.PubKeyInner + for wrap, ok := pk.(PubKey); ok; wrap, ok = pk.(PubKey) { + pk = wrap.PubKeyInner + } + return pk +} + +func (p PubKey) MarshalJSON() ([]byte, error) { + return pubKeyMapper.ToJSON(p.PubKeyInner) } -func (p *PubKeyS) UnmarshalJSON(data []byte) (err error) { +func (p *PubKey) UnmarshalJSON(data []byte) (err error) { parsed, err := pubKeyMapper.FromJSON(data) if err == nil && parsed != nil { - p.PubKey = parsed.(PubKey) + p.PubKeyInner = parsed.(PubKeyInner) } return } -func (p PubKeyS) Empty() bool { - return p.PubKey == nil +func (p PubKey) Empty() bool { + return p.PubKeyInner == nil } func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { @@ -66,7 +74,7 @@ func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { //------------------------------------- -// Implements PubKey +// Implements PubKeyInner type PubKeyEd25519 [32]byte func (pubKey PubKeyEd25519) Address() []byte { @@ -83,16 +91,12 @@ func (pubKey PubKeyEd25519) Address() []byte { } func (pubKey PubKeyEd25519) Bytes() []byte { - return wire.BinaryBytes(struct{ PubKey }{pubKey}) + return wire.BinaryBytes(PubKey{pubKey}) } func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool { - // unwrap if needed - if wrap, ok := sig_.(SignatureS); ok { - sig_ = wrap.Signature - } // make sure we use the same algorithm to sign - sig, ok := sig_.(SignatureEd25519) + sig, ok := sig_.Unwrap().(SignatureEd25519) if !ok { return false } @@ -134,7 +138,7 @@ func (pubKey PubKeyEd25519) KeyString() string { } func (pubKey PubKeyEd25519) Equals(other PubKey) bool { - if otherEd, ok := other.(PubKeyEd25519); ok { + if otherEd, ok := other.Unwrap().(PubKeyEd25519); ok { return bytes.Equal(pubKey[:], otherEd[:]) } else { return false @@ -160,16 +164,12 @@ func (pubKey PubKeySecp256k1) Address() []byte { } func (pubKey PubKeySecp256k1) Bytes() []byte { - return wire.BinaryBytes(struct{ PubKey }{pubKey}) + return wire.BinaryBytes(PubKey{pubKey}) } func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool { - // unwrap if needed - if wrap, ok := sig_.(SignatureS); ok { - sig_ = wrap.Signature - } // and assert same algorithm to sign and verify - sig, ok := sig_.(SignatureSecp256k1) + sig, ok := sig_.Unwrap().(SignatureSecp256k1) if !ok { return false } @@ -207,7 +207,7 @@ func (pubKey PubKeySecp256k1) KeyString() string { } func (pubKey PubKeySecp256k1) Equals(other PubKey) bool { - if otherSecp, ok := other.(PubKeySecp256k1); ok { + if otherSecp, ok := other.Unwrap().(PubKeySecp256k1); ok { return bytes.Equal(pubKey[:], otherSecp[:]) } else { return false diff --git a/pub_key_test.go b/pub_key_test.go index 0616f5546..31642233c 100644 --- a/pub_key_test.go +++ b/pub_key_test.go @@ -31,7 +31,7 @@ func TestPubKeySecp256k1Address(t *testing.T) { var priv PrivKeySecp256k1 copy(priv[:], privB) - pubT := priv.PubKey().(PubKeySecp256k1) + pubT := priv.PubKey().Unwrap().(PubKeySecp256k1) pub := pubT[:] addr := priv.PubKey().Address() diff --git a/signature.go b/signature.go index bb9d82009..e7b6b1745 100644 --- a/signature.go +++ b/signature.go @@ -9,8 +9,9 @@ import ( "github.com/tendermint/go-wire" ) -// Signature is a part of Txs and consensus Votes. -type Signature interface { +// SignatureInner is now the interface itself. +// Use Signature in all code +type SignatureInner interface { Bytes() []byte IsZero() bool String() string @@ -21,37 +22,45 @@ var sigMapper data.Mapper // register both public key types with go-data (and thus go-wire) func init() { - sigMapper = data.NewMapper(SignatureS{}). + sigMapper = data.NewMapper(Signature{}). RegisterImplementation(SignatureEd25519{}, NameEd25519, TypeEd25519). RegisterImplementation(SignatureSecp256k1{}, NameSecp256k1, TypeSecp256k1) } -// SignatureS add json serialization to Signature -type SignatureS struct { - Signature +// Signature add json serialization to Signature +type Signature struct { + SignatureInner } -func WrapSignature(sig Signature) SignatureS { - for ssig, ok := sig.(SignatureS); ok; ssig, ok = sig.(SignatureS) { - sig = ssig.Signature +func WrapSignature(pk SignatureInner) Signature { + if wrap, ok := pk.(Signature); ok { + pk = wrap.Unwrap() } - return SignatureS{sig} + return Signature{pk} } -func (p SignatureS) MarshalJSON() ([]byte, error) { - return sigMapper.ToJSON(p.Signature) +func (p Signature) Unwrap() SignatureInner { + pk := p.SignatureInner + for wrap, ok := pk.(Signature); ok; wrap, ok = pk.(Signature) { + pk = wrap.SignatureInner + } + return pk +} + +func (p Signature) MarshalJSON() ([]byte, error) { + return sigMapper.ToJSON(p.SignatureInner) } -func (p *SignatureS) UnmarshalJSON(data []byte) (err error) { +func (p *Signature) UnmarshalJSON(data []byte) (err error) { parsed, err := sigMapper.FromJSON(data) if err == nil && parsed != nil { - p.Signature = parsed.(Signature) + p.SignatureInner = parsed.(SignatureInner) } return } -func (p SignatureS) Empty() bool { - return p.Signature == nil +func (p Signature) Empty() bool { + return p.SignatureInner == nil } func SignatureFromBytes(sigBytes []byte) (sig Signature, err error) { @@ -65,7 +74,7 @@ func SignatureFromBytes(sigBytes []byte) (sig Signature, err error) { type SignatureEd25519 [64]byte func (sig SignatureEd25519) Bytes() []byte { - return wire.BinaryBytes(struct{ Signature }{sig}) + return wire.BinaryBytes(Signature{sig}) } func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 } @@ -73,7 +82,7 @@ func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 } func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } func (sig SignatureEd25519) Equals(other Signature) bool { - if otherEd, ok := other.(SignatureEd25519); ok { + if otherEd, ok := other.Unwrap().(SignatureEd25519); ok { return bytes.Equal(sig[:], otherEd[:]) } else { return false @@ -97,7 +106,7 @@ func (p *SignatureEd25519) UnmarshalJSON(enc []byte) error { type SignatureSecp256k1 []byte func (sig SignatureSecp256k1) Bytes() []byte { - return wire.BinaryBytes(struct{ Signature }{sig}) + return wire.BinaryBytes(Signature{sig}) } func (sig SignatureSecp256k1) IsZero() bool { return len(sig) == 0 } @@ -105,7 +114,7 @@ func (sig SignatureSecp256k1) IsZero() bool { return len(sig) == 0 } func (sig SignatureSecp256k1) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } func (sig SignatureSecp256k1) Equals(other Signature) bool { - if otherEd, ok := other.(SignatureSecp256k1); ok { + if otherEd, ok := other.Unwrap().(SignatureSecp256k1); ok { return bytes.Equal(sig[:], otherEd[:]) } else { return false diff --git a/signature_test.go b/signature_test.go index f04262b77..92fed906d 100644 --- a/signature_test.go +++ b/signature_test.go @@ -22,9 +22,9 @@ func TestSignAndValidateEd25519(t *testing.T) { assert.True(t, pubKey.VerifyBytes(msg, sig)) // Mutate the signature, just one bit. - sigEd := sig.(SignatureEd25519) - sigEd[0] ^= byte(0x01) - sig = Signature(sigEd) + sigEd := sig.Unwrap().(SignatureEd25519) + sigEd[7] ^= byte(0x01) + sig = WrapSignature(sigEd) assert.False(t, pubKey.VerifyBytes(msg, sig)) } @@ -39,28 +39,28 @@ func TestSignAndValidateSecp256k1(t *testing.T) { assert.True(t, pubKey.VerifyBytes(msg, sig)) // Mutate the signature, just one bit. - sigEd := sig.(SignatureSecp256k1) - sigEd[0] ^= byte(0x01) - sig = Signature(sigEd) + sigEd := sig.Unwrap().(SignatureSecp256k1) + sigEd[3] ^= byte(0x01) + sig = WrapSignature(sigEd) assert.False(t, pubKey.VerifyBytes(msg, sig)) } func TestSignatureEncodings(t *testing.T) { cases := []struct { - privKey PrivKeyS + privKey PrivKey sigSize int sigType byte sigName string }{ { - privKey: PrivKeyS{GenPrivKeyEd25519()}, + privKey: WrapPrivKey(GenPrivKeyEd25519()), sigSize: ed25519.SignatureSize, sigType: TypeEd25519, sigName: NameEd25519, }, { - privKey: PrivKeyS{GenPrivKeySecp256k1()}, + privKey: WrapPrivKey(GenPrivKeySecp256k1()), sigSize: 0, // unknown sigType: TypeSecp256k1, sigName: NameSecp256k1, @@ -69,10 +69,10 @@ func TestSignatureEncodings(t *testing.T) { for _, tc := range cases { // note we embed them from the beginning.... - pubKey := PubKeyS{tc.privKey.PubKey()} + pubKey := tc.privKey.PubKey() msg := CRandBytes(128) - sig := SignatureS{tc.privKey.Sign(msg)} + sig := tc.privKey.Sign(msg) // store as wire bin, err := data.ToWire(sig) @@ -83,7 +83,7 @@ func TestSignatureEncodings(t *testing.T) { assert.Equal(t, tc.sigType, bin[0]) // and back - sig2 := SignatureS{} + sig2 := Signature{} err = data.FromWire(bin, &sig2) require.Nil(t, err, "%+v", err) assert.EqualValues(t, sig, sig2) @@ -95,7 +95,7 @@ func TestSignatureEncodings(t *testing.T) { assert.True(t, strings.Contains(string(js), tc.sigName)) // and back - sig3 := SignatureS{} + sig3 := Signature{} err = data.FromJSON(js, &sig3) require.Nil(t, err, "%+v", err) assert.EqualValues(t, sig, sig3) @@ -118,25 +118,25 @@ func TestWrapping(t *testing.T) { sig := priv.Sign(msg) // do some wrapping - pubs := []PubKeyS{ + pubs := []PubKey{ WrapPubKey(nil), WrapPubKey(pub), WrapPubKey(WrapPubKey(WrapPubKey(WrapPubKey(pub)))), - WrapPubKey(PubKeyS{PubKeyS{PubKeyS{pub}}}), + WrapPubKey(PubKey{PubKey{PubKey{pub}}}), } for _, p := range pubs { - _, ok := p.PubKey.(PubKeyS) + _, ok := p.PubKeyInner.(PubKey) assert.False(ok) } - sigs := []SignatureS{ + sigs := []Signature{ WrapSignature(nil), WrapSignature(sig), WrapSignature(WrapSignature(WrapSignature(WrapSignature(sig)))), - WrapSignature(SignatureS{SignatureS{SignatureS{sig}}}), + WrapSignature(Signature{Signature{Signature{sig}}}), } for _, s := range sigs { - _, ok := s.Signature.(SignatureS) + _, ok := s.SignatureInner.(Signature) assert.False(ok) } From 5b94758d4c5f0aa7842f56b31e88a8d2bdb736e2 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 22 Mar 2017 15:59:00 +0100 Subject: [PATCH 053/287] Make PubKey struct compatible with go-wire.JSONBytes/ReadJSON --- encode_test.go | 20 ++++++++++++++++++++ priv_key.go | 2 +- pub_key.go | 2 +- signature.go | 2 +- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/encode_test.go b/encode_test.go index 667132a6f..71b7b3ae6 100644 --- a/encode_test.go +++ b/encode_test.go @@ -1,12 +1,14 @@ package crypto import ( + "fmt" "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" data "github.com/tendermint/go-data" + wire "github.com/tendermint/go-wire" ) type byter interface { @@ -48,6 +50,18 @@ func checkJSON(t *testing.T, in interface{}, reader interface{}, typ string) { assert.True(t, strings.Contains(string(js), parts[1])) } +// make sure go-wire json can still figure this out... +func checkWireJSON(t *testing.T, in interface{}, reader interface{}, typ byte) { + // test to and from binary + var err error + js := wire.JSONBytes(in) + btyp := fmt.Sprintf("[%d,", typ) + assert.True(t, strings.HasPrefix(string(js), btyp), string(js)) + + wire.ReadJSON(reader, js, &err) + require.Nil(t, err, "%+v", err) +} + func TestKeyEncodings(t *testing.T) { cases := []struct { privKey PrivKey @@ -74,6 +88,9 @@ func TestKeyEncodings(t *testing.T) { priv3 := PrivKey{} checkJSON(t, tc.privKey, &priv3, tc.keyName) assert.EqualValues(t, tc.privKey, priv3) + priv4 := PrivKey{} + checkWireJSON(t, tc.privKey, &priv4, tc.keyType) + assert.EqualValues(t, tc.privKey, priv4) // check (de/en)codings of public key pubKey := tc.privKey.PubKey() @@ -83,6 +100,9 @@ func TestKeyEncodings(t *testing.T) { pub3 := PubKey{} checkJSON(t, pubKey, &pub3, tc.keyName) assert.EqualValues(t, pubKey, pub3) + pub4 := PubKey{} + checkWireJSON(t, pubKey, &pub4, tc.keyType) + assert.EqualValues(t, pubKey, pub4) } } diff --git a/priv_key.go b/priv_key.go index f00a762d8..5aa2d05ad 100644 --- a/priv_key.go +++ b/priv_key.go @@ -38,7 +38,7 @@ func init() { // PrivKey handles all encoding and exposes methods type PrivKey struct { - PrivKeyInner + PrivKeyInner `json:"unwrap"` } func WrapPrivKey(pk PrivKeyInner) PrivKey { diff --git a/pub_key.go b/pub_key.go index fa91b12f4..8373eb347 100644 --- a/pub_key.go +++ b/pub_key.go @@ -33,7 +33,7 @@ func init() { // PubKey add json serialization to PubKeyInner type PubKey struct { - PubKeyInner + PubKeyInner `json:"unwrap"` } func WrapPubKey(pk PubKeyInner) PubKey { diff --git a/signature.go b/signature.go index e7b6b1745..ba40166cd 100644 --- a/signature.go +++ b/signature.go @@ -29,7 +29,7 @@ func init() { // Signature add json serialization to Signature type Signature struct { - SignatureInner + SignatureInner `json:"unwrap"` } func WrapSignature(pk SignatureInner) Signature { From eb6fcef8d2d26bee5ba49c88fd5af305881fd3e9 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 29 Mar 2017 15:17:06 +0200 Subject: [PATCH 054/287] Better docs and naming thanks to bucky --- embed_test.go | 4 ++++ encode_test.go | 14 +++++--------- priv_key.go | 14 ++++++++++++-- pub_key.go | 14 ++++++++++++-- signature.go | 15 ++++++++++++--- 5 files changed, 45 insertions(+), 16 deletions(-) diff --git a/embed_test.go b/embed_test.go index 77b821f03..eda72b438 100644 --- a/embed_test.go +++ b/embed_test.go @@ -95,7 +95,11 @@ func TestEncodeDemo(t *testing.T) { }{ {PubName{Foo{"pub-foo"}}, &PubName{}, "Foo: pub-foo"}, {PubName{Bar{7}}, &PubName{}, "Bar #7"}, + // Note these fail - if you can figure a solution here, I'll buy you a beer :) + // (ebuchman is right, you must either break the reflection system, or modify go-wire) + // but such a mod would let us make REALLY sure that no one could construct like this + // {PrivName{Foo{"priv-foo"}}, &PrivName{}, "Foo: priv-foo"}, // {PrivName{Bar{9}}, &PrivName{}, "Bar #9"}, } diff --git a/encode_test.go b/encode_test.go index 71b7b3ae6..9a8e5902c 100644 --- a/encode_test.go +++ b/encode_test.go @@ -82,25 +82,21 @@ func TestKeyEncodings(t *testing.T) { for _, tc := range cases { // check (de/en)codings of private key - priv2 := PrivKey{} + var priv2, priv3, priv4 PrivKey checkWire(t, tc.privKey, &priv2, tc.keyType) assert.EqualValues(t, tc.privKey, priv2) - priv3 := PrivKey{} checkJSON(t, tc.privKey, &priv3, tc.keyName) assert.EqualValues(t, tc.privKey, priv3) - priv4 := PrivKey{} checkWireJSON(t, tc.privKey, &priv4, tc.keyType) assert.EqualValues(t, tc.privKey, priv4) // check (de/en)codings of public key pubKey := tc.privKey.PubKey() - pub2 := PubKey{} + var pub2, pub3, pub4 PubKey checkWire(t, pubKey, &pub2, tc.keyType) assert.EqualValues(t, pubKey, pub2) - pub3 := PubKey{} checkJSON(t, pubKey, &pub3, tc.keyName) assert.EqualValues(t, pubKey, pub3) - pub4 := PubKey{} checkWireJSON(t, pubKey, &pub4, tc.keyType) assert.EqualValues(t, pubKey, pub4) } @@ -115,17 +111,17 @@ func toFromJSON(t *testing.T, in interface{}, recvr interface{}) { func TestNilEncodings(t *testing.T) { // make sure sigs are okay with nil - a, b := Signature{}, Signature{} + var a, b Signature toFromJSON(t, a, &b) assert.EqualValues(t, a, b) // make sure sigs are okay with nil - c, d := PubKey{}, PubKey{} + var c, d PubKey toFromJSON(t, c, &d) assert.EqualValues(t, c, d) // make sure sigs are okay with nil - e, f := PrivKey{}, PrivKey{} + var e, f PrivKey toFromJSON(t, e, &f) assert.EqualValues(t, e, f) diff --git a/priv_key.go b/priv_key.go index 5aa2d05ad..d21bdf458 100644 --- a/priv_key.go +++ b/priv_key.go @@ -11,7 +11,14 @@ import ( "github.com/tendermint/go-wire" ) -// PrivKeyInner is now the interface itself, use PrivKey in all code +/* +DO NOT USE this interface. + +It is public by necessity but should never be used directly +outside of this package. + +Only use the PrivKey, never the PrivKeyInner +*/ type PrivKeyInner interface { Bytes() []byte Sign(msg []byte) Signature @@ -36,11 +43,13 @@ func init() { RegisterImplementation(PrivKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) } -// PrivKey handles all encoding and exposes methods +// PrivKey should be used instead of an interface in all external packages +// unless you demand a concrete implementation, then use that directly. type PrivKey struct { PrivKeyInner `json:"unwrap"` } +// WrapPrivKey goes from concrete implementation to "interface" struct func WrapPrivKey(pk PrivKeyInner) PrivKey { if wrap, ok := pk.(PrivKey); ok { pk = wrap.Unwrap() @@ -48,6 +57,7 @@ func WrapPrivKey(pk PrivKeyInner) PrivKey { return PrivKey{pk} } +// Unwrap recovers the concrete interface safely (regardless of levels of embeds) func (p PrivKey) Unwrap() PrivKeyInner { pk := p.PrivKeyInner for wrap, ok := pk.(PrivKey); ok; wrap, ok = pk.(PrivKey) { diff --git a/pub_key.go b/pub_key.go index 8373eb347..a763688fe 100644 --- a/pub_key.go +++ b/pub_key.go @@ -13,7 +13,14 @@ import ( "golang.org/x/crypto/ripemd160" ) -// PubKeyInner is now the interface itself, use PubKey struct in all code +/* +DO NOT USE this interface. + +It is public by necessity but should never be used directly +outside of this package. + +Only use the PubKey, never the PubKeyInner +*/ type PubKeyInner interface { Address() []byte Bytes() []byte @@ -31,11 +38,13 @@ func init() { RegisterImplementation(PubKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) } -// PubKey add json serialization to PubKeyInner +// PubKey should be used instead of an interface in all external packages +// unless you demand a concrete implementation, then use that directly. type PubKey struct { PubKeyInner `json:"unwrap"` } +// WrapPubKey goes from concrete implementation to "interface" struct func WrapPubKey(pk PubKeyInner) PubKey { if wrap, ok := pk.(PubKey); ok { pk = wrap.Unwrap() @@ -43,6 +52,7 @@ func WrapPubKey(pk PubKeyInner) PubKey { return PubKey{pk} } +// Unwrap recovers the concrete interface safely (regardless of levels of embeds) func (p PubKey) Unwrap() PubKeyInner { pk := p.PubKeyInner for wrap, ok := pk.(PubKey); ok; wrap, ok = pk.(PubKey) { diff --git a/signature.go b/signature.go index ba40166cd..bb3e8f11b 100644 --- a/signature.go +++ b/signature.go @@ -9,8 +9,14 @@ import ( "github.com/tendermint/go-wire" ) -// SignatureInner is now the interface itself. -// Use Signature in all code +/* +DO NOT USE this interface. + +It is public by necessity but should never be used directly +outside of this package. + +Only use the Signature, never the SignatureInner +*/ type SignatureInner interface { Bytes() []byte IsZero() bool @@ -27,11 +33,13 @@ func init() { RegisterImplementation(SignatureSecp256k1{}, NameSecp256k1, TypeSecp256k1) } -// Signature add json serialization to Signature +// Signature should be used instead of an interface in all external packages +// unless you demand a concrete implementation, then use that directly. type Signature struct { SignatureInner `json:"unwrap"` } +// WrapSignature goes from concrete implementation to "interface" struct func WrapSignature(pk SignatureInner) Signature { if wrap, ok := pk.(Signature); ok { pk = wrap.Unwrap() @@ -39,6 +47,7 @@ func WrapSignature(pk SignatureInner) Signature { return Signature{pk} } +// Unwrap recovers the concrete interface safely (regardless of levels of embeds) func (p Signature) Unwrap() SignatureInner { pk := p.SignatureInner for wrap, ok := pk.(Signature); ok; wrap, ok = pk.(Signature) { From a3324cc97bf90b49437eb4cf1da3c7733259b62d Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sun, 9 Apr 2017 00:32:54 -0700 Subject: [PATCH 055/287] Cleanup; Implement .Wrap() --- crypto.go | 9 ++++ embed_test.go | 102 +++++++++++++++------------------------------- encode_test.go | 4 +- priv_key.go | 91 ++++++++++++++++++----------------------- pub_key.go | 85 ++++++++++++++++++-------------------- signature.go | 99 +++++++++++++++++++++----------------------- signature_test.go | 24 +++++------ 7 files changed, 181 insertions(+), 233 deletions(-) create mode 100644 crypto.go diff --git a/crypto.go b/crypto.go new file mode 100644 index 000000000..d9caf1ad9 --- /dev/null +++ b/crypto.go @@ -0,0 +1,9 @@ +package crypto + +// Types of implementations +const ( + TypeEd25519 = byte(0x01) + TypeSecp256k1 = byte(0x02) + NameEd25519 = "ed25519" + NameSecp256k1 = "secp256k1" +) diff --git a/embed_test.go b/embed_test.go index eda72b438..6ebba893c 100644 --- a/embed_test.go +++ b/embed_test.go @@ -9,50 +9,13 @@ import ( data "github.com/tendermint/go-data" ) -type Foo struct { - Name string -} - -func (f Foo) Greet() string { - return "Foo: " + f.Name -} - -type Bar struct { - Age int -} - -func (b Bar) Greet() string { - return fmt.Sprintf("Bar #%d", b.Age) +type PubName struct { + PubNameInner } type PubNameInner interface { - Greet() string -} - -type privNameInner interface { - Greet() string -} - -type Greeter interface { - Greet() string -} - -var ( - pubNameMapper, privNameMapper data.Mapper -) - -// register both public key types with go-data (and thus go-wire) -func init() { - pubNameMapper = data.NewMapper(PubName{}). - RegisterImplementation(Foo{}, "foo", 1). - RegisterImplementation(Bar{}, "bar", 2) - privNameMapper = data.NewMapper(PrivName{}). - RegisterImplementation(Foo{}, "foo", 1). - RegisterImplementation(Bar{}, "bar", 2) -} - -type PubName struct { - PubNameInner + AssertIsPubNameInner() + String() string } func (p PubName) MarshalJSON() ([]byte, error) { @@ -67,62 +30,61 @@ func (p *PubName) UnmarshalJSON(data []byte) error { return err } -type PrivName struct { - privNameInner -} +var pubNameMapper = data.NewMapper(PubName{}). + RegisterImplementation(PubNameFoo{}, "foo", 1). + RegisterImplementation(PubNameBar{}, "bar", 2) -func (p PrivName) MarshalJSON() ([]byte, error) { - return privNameMapper.ToJSON(p.privNameInner) +func (f PubNameFoo) AssertIsPubNameInner() {} +func (f PubNameBar) AssertIsPubNameInner() {} + +//---------------------------------------- + +type PubNameFoo struct { + Name string } -func (p *PrivName) UnmarshalJSON(data []byte) error { - parsed, err := privNameMapper.FromJSON(data) - if err == nil && parsed != nil { - p.privNameInner = parsed.(privNameInner) - } - return err +func (f PubNameFoo) String() string { return "Foo: " + f.Name } + +type PubNameBar struct { + Age int } +func (b PubNameBar) String() string { return fmt.Sprintf("Bar #%d", b.Age) } + +//---------------------------------------- + // TestEncodeDemo tries the various strategies to encode the objects func TestEncodeDemo(t *testing.T) { assert, require := assert.New(t), require.New(t) - // assert := assert.New(t) - // require := require.New(t) cases := []struct { - in, out Greeter + in, out PubNameInner expected string }{ - {PubName{Foo{"pub-foo"}}, &PubName{}, "Foo: pub-foo"}, - {PubName{Bar{7}}, &PubName{}, "Bar #7"}, - - // Note these fail - if you can figure a solution here, I'll buy you a beer :) - // (ebuchman is right, you must either break the reflection system, or modify go-wire) - // but such a mod would let us make REALLY sure that no one could construct like this - - // {PrivName{Foo{"priv-foo"}}, &PrivName{}, "Foo: priv-foo"}, - // {PrivName{Bar{9}}, &PrivName{}, "Bar #9"}, + {PubName{PubNameFoo{"pub-foo"}}, &PubName{}, "Foo: pub-foo"}, + {PubName{PubNameBar{7}}, &PubName{}, "Bar #7"}, } for i, tc := range cases { - // make sure it is proper to start - require.Equal(tc.expected, tc.in.Greet()) - // now, try to encode as binary + // Make sure it is proper to start + require.Equal(tc.expected, tc.in.String()) + + // Try to encode as binary b, err := data.ToWire(tc.in) if assert.Nil(err, "%d: %#v", i, tc.in) { err := data.FromWire(b, tc.out) if assert.Nil(err) { - assert.Equal(tc.expected, tc.out.Greet()) + assert.Equal(tc.expected, tc.out.String()) } } - // try to encode it as json + // Try to encode it as json j, err := data.ToJSON(tc.in) if assert.Nil(err, "%d: %#v", i, tc.in) { err := data.FromJSON(j, tc.out) if assert.Nil(err) { - assert.Equal(tc.expected, tc.out.Greet()) + assert.Equal(tc.expected, tc.out.String()) } } } diff --git a/encode_test.go b/encode_test.go index 9a8e5902c..2d709b943 100644 --- a/encode_test.go +++ b/encode_test.go @@ -69,12 +69,12 @@ func TestKeyEncodings(t *testing.T) { keyName string }{ { - privKey: WrapPrivKey(GenPrivKeyEd25519()), + privKey: GenPrivKeyEd25519().Wrap(), keyType: TypeEd25519, keyName: NameEd25519, }, { - privKey: WrapPrivKey(GenPrivKeySecp256k1()), + privKey: GenPrivKeySecp256k1().Wrap(), keyType: TypeSecp256k1, keyName: NameSecp256k1, }, diff --git a/priv_key.go b/priv_key.go index d21bdf458..74d5b5a3e 100644 --- a/priv_key.go +++ b/priv_key.go @@ -11,50 +11,38 @@ import ( "github.com/tendermint/go-wire" ) -/* -DO NOT USE this interface. +func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { + err = wire.ReadBinaryBytes(privKeyBytes, &privKey) + return +} -It is public by necessity but should never be used directly -outside of this package. +//---------------------------------------- -Only use the PrivKey, never the PrivKeyInner -*/ +type PrivKey struct { + PrivKeyInner `json:"unwrap"` +} + +// DO NOT USE THIS INTERFACE. +// You probably want to use PubKey type PrivKeyInner interface { + AssertIsPrivKeyInner() Bytes() []byte Sign(msg []byte) Signature PubKey() PubKey Equals(PrivKey) bool + Wrap() PrivKey } -// Types of implementations -const ( - TypeEd25519 = byte(0x01) - TypeSecp256k1 = byte(0x02) - NameEd25519 = "ed25519" - NameSecp256k1 = "secp256k1" -) - -var privKeyMapper data.Mapper - -// register both private key types with go-data (and thus go-wire) -func init() { - privKeyMapper = data.NewMapper(PrivKey{}). - RegisterImplementation(PrivKeyEd25519{}, NameEd25519, TypeEd25519). - RegisterImplementation(PrivKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) -} - -// PrivKey should be used instead of an interface in all external packages -// unless you demand a concrete implementation, then use that directly. -type PrivKey struct { - PrivKeyInner `json:"unwrap"` +func (p PrivKey) MarshalJSON() ([]byte, error) { + return privKeyMapper.ToJSON(p.PrivKeyInner) } -// WrapPrivKey goes from concrete implementation to "interface" struct -func WrapPrivKey(pk PrivKeyInner) PrivKey { - if wrap, ok := pk.(PrivKey); ok { - pk = wrap.Unwrap() +func (p *PrivKey) UnmarshalJSON(data []byte) (err error) { + parsed, err := privKeyMapper.FromJSON(data) + if err == nil && parsed != nil { + p.PrivKeyInner = parsed.(PrivKeyInner) } - return PrivKey{pk} + return } // Unwrap recovers the concrete interface safely (regardless of levels of embeds) @@ -66,32 +54,21 @@ func (p PrivKey) Unwrap() PrivKeyInner { return pk } -func (p PrivKey) MarshalJSON() ([]byte, error) { - return privKeyMapper.ToJSON(p.PrivKeyInner) -} - -func (p *PrivKey) UnmarshalJSON(data []byte) (err error) { - parsed, err := privKeyMapper.FromJSON(data) - if err == nil && parsed != nil { - p.PrivKeyInner = parsed.(PrivKeyInner) - } - return -} - func (p PrivKey) Empty() bool { return p.PrivKeyInner == nil } -func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { - err = wire.ReadBinaryBytes(privKeyBytes, &privKey) - return -} +var privKeyMapper = data.NewMapper(PrivKey{}). + RegisterImplementation(PrivKeyEd25519{}, NameEd25519, TypeEd25519). + RegisterImplementation(PrivKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) //------------------------------------- // Implements PrivKey type PrivKeyEd25519 [64]byte +func (privKey PrivKeyEd25519) AssertIsPrivKeyInner() {} + func (privKey PrivKeyEd25519) Bytes() []byte { return wire.BinaryBytes(PrivKey{privKey}) } @@ -99,13 +76,13 @@ func (privKey PrivKeyEd25519) Bytes() []byte { func (privKey PrivKeyEd25519) Sign(msg []byte) Signature { privKeyBytes := [64]byte(privKey) signatureBytes := ed25519.Sign(&privKeyBytes, msg) - return WrapSignature(SignatureEd25519(*signatureBytes)) + return SignatureEd25519(*signatureBytes).Wrap() } func (privKey PrivKeyEd25519) PubKey() PubKey { privKeyBytes := [64]byte(privKey) pubBytes := *ed25519.MakePublicKey(&privKeyBytes) - return WrapPubKey(PubKeyEd25519(pubBytes)) + return PubKeyEd25519(pubBytes).Wrap() } func (privKey PrivKeyEd25519) Equals(other PrivKey) bool { @@ -149,6 +126,10 @@ func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519 { return PrivKeyEd25519(newKey) } +func (privKey PrivKeyEd25519) Wrap() PrivKey { + return PrivKey{privKey} +} + func GenPrivKeyEd25519() PrivKeyEd25519 { privKeyBytes := new([64]byte) copy(privKeyBytes[:32], CRandBytes(32)) @@ -171,6 +152,8 @@ func GenPrivKeyEd25519FromSecret(secret []byte) PrivKeyEd25519 { // Implements PrivKey type PrivKeySecp256k1 [32]byte +func (privKey PrivKeySecp256k1) AssertIsPrivKeyInner() {} + func (privKey PrivKeySecp256k1) Bytes() []byte { return wire.BinaryBytes(PrivKey{privKey}) } @@ -181,14 +164,14 @@ func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature { if err != nil { PanicSanity(err) } - return WrapSignature(SignatureSecp256k1(sig__.Serialize())) + return SignatureSecp256k1(sig__.Serialize()).Wrap() } func (privKey PrivKeySecp256k1) PubKey() PubKey { _, pub__ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) var pub PubKeySecp256k1 copy(pub[:], pub__.SerializeCompressed()) - return WrapPubKey(pub) + return pub.Wrap() } func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool { @@ -214,6 +197,10 @@ func (privKey PrivKeySecp256k1) String() string { return Fmt("PrivKeySecp256k1{*****}") } +func (privKey PrivKeySecp256k1) Wrap() PrivKey { + return PrivKey{privKey} +} + /* // Deterministically generates new priv-key bytes from key. func (key PrivKeySecp256k1) Generate(index int) PrivKeySecp256k1 { diff --git a/pub_key.go b/pub_key.go index a763688fe..e6567d347 100644 --- a/pub_key.go +++ b/pub_key.go @@ -13,80 +13,65 @@ import ( "golang.org/x/crypto/ripemd160" ) -/* -DO NOT USE this interface. +func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { + err = wire.ReadBinaryBytes(pubKeyBytes, &pubKey) + return +} -It is public by necessity but should never be used directly -outside of this package. +//---------------------------------------- -Only use the PubKey, never the PubKeyInner -*/ +type PubKey struct { + PubKeyInner `json:"unwrap"` +} + +// DO NOT USE THIS INTERFACE. +// You probably want to use PubKey type PubKeyInner interface { + AssertIsPubKeyInner() Address() []byte Bytes() []byte KeyString() string VerifyBytes(msg []byte, sig Signature) bool Equals(PubKey) bool + Wrap() PubKey } -var pubKeyMapper data.Mapper - -// register both public key types with go-data (and thus go-wire) -func init() { - pubKeyMapper = data.NewMapper(PubKey{}). - RegisterImplementation(PubKeyEd25519{}, NameEd25519, TypeEd25519). - RegisterImplementation(PubKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) +func (pk PubKey) MarshalJSON() ([]byte, error) { + return pubKeyMapper.ToJSON(pk.PubKeyInner) } -// PubKey should be used instead of an interface in all external packages -// unless you demand a concrete implementation, then use that directly. -type PubKey struct { - PubKeyInner `json:"unwrap"` -} - -// WrapPubKey goes from concrete implementation to "interface" struct -func WrapPubKey(pk PubKeyInner) PubKey { - if wrap, ok := pk.(PubKey); ok { - pk = wrap.Unwrap() +func (pk *PubKey) UnmarshalJSON(data []byte) (err error) { + parsed, err := pubKeyMapper.FromJSON(data) + if err == nil && parsed != nil { + pk.PubKeyInner = parsed.(PubKeyInner) } - return PubKey{pk} + return } // Unwrap recovers the concrete interface safely (regardless of levels of embeds) -func (p PubKey) Unwrap() PubKeyInner { - pk := p.PubKeyInner - for wrap, ok := pk.(PubKey); ok; wrap, ok = pk.(PubKey) { - pk = wrap.PubKeyInner - } - return pk -} - -func (p PubKey) MarshalJSON() ([]byte, error) { - return pubKeyMapper.ToJSON(p.PubKeyInner) -} - -func (p *PubKey) UnmarshalJSON(data []byte) (err error) { - parsed, err := pubKeyMapper.FromJSON(data) - if err == nil && parsed != nil { - p.PubKeyInner = parsed.(PubKeyInner) +func (pk PubKey) Unwrap() PubKeyInner { + pkI := pk.PubKeyInner + for wrap, ok := pkI.(PubKey); ok; wrap, ok = pkI.(PubKey) { + pkI = wrap.PubKeyInner } - return + return pkI } func (p PubKey) Empty() bool { return p.PubKeyInner == nil } -func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { - err = wire.ReadBinaryBytes(pubKeyBytes, &pubKey) - return -} +var pubKeyMapper = data.NewMapper(PubKey{}). + RegisterImplementation(PubKeyEd25519{}, NameEd25519, TypeEd25519). + RegisterImplementation(PubKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) //------------------------------------- // Implements PubKeyInner type PubKeyEd25519 [32]byte +func (pubKey PubKeyEd25519) AssertIsPubKeyInner() {} + func (pubKey PubKeyEd25519) Address() []byte { w, n, err := new(bytes.Buffer), new(int), new(error) wire.WriteBinary(pubKey[:], w, n, err) @@ -155,6 +140,10 @@ func (pubKey PubKeyEd25519) Equals(other PubKey) bool { } } +func (pubKey PubKeyEd25519) Wrap() PubKey { + return PubKey{pubKey} +} + //------------------------------------- // Implements PubKey. @@ -162,6 +151,8 @@ func (pubKey PubKeyEd25519) Equals(other PubKey) bool { // prefixed with 0x02 or 0x03, depending on the y-cord. type PubKeySecp256k1 [33]byte +func (pubKey PubKeySecp256k1) AssertIsPubKeyInner() {} + // Implements Bitcoin style addresses: RIPEMD160(SHA256(pubkey)) func (pubKey PubKeySecp256k1) Address() []byte { hasherSHA256 := sha256.New() @@ -223,3 +214,7 @@ func (pubKey PubKeySecp256k1) Equals(other PubKey) bool { return false } } + +func (pubKey PubKeySecp256k1) Wrap() PubKey { + return PubKey{pubKey} +} diff --git a/signature.go b/signature.go index bb3e8f11b..66c9a8a27 100644 --- a/signature.go +++ b/signature.go @@ -9,79 +9,64 @@ import ( "github.com/tendermint/go-wire" ) -/* -DO NOT USE this interface. +func SignatureFromBytes(sigBytes []byte) (sig Signature, err error) { + err = wire.ReadBinaryBytes(sigBytes, &sig) + return +} -It is public by necessity but should never be used directly -outside of this package. +//---------------------------------------- -Only use the Signature, never the SignatureInner -*/ +type Signature struct { + SignatureInner `json:"unwrap"` +} + +// DO NOT USE THIS INTERFACE. +// You probably want to use Signature. type SignatureInner interface { + AssertIsSignatureInner() Bytes() []byte IsZero() bool String() string Equals(Signature) bool + Wrap() Signature } -var sigMapper data.Mapper - -// register both public key types with go-data (and thus go-wire) -func init() { - sigMapper = data.NewMapper(Signature{}). - RegisterImplementation(SignatureEd25519{}, NameEd25519, TypeEd25519). - RegisterImplementation(SignatureSecp256k1{}, NameSecp256k1, TypeSecp256k1) +func (sig Signature) MarshalJSON() ([]byte, error) { + return sigMapper.ToJSON(sig.SignatureInner) } -// Signature should be used instead of an interface in all external packages -// unless you demand a concrete implementation, then use that directly. -type Signature struct { - SignatureInner `json:"unwrap"` -} - -// WrapSignature goes from concrete implementation to "interface" struct -func WrapSignature(pk SignatureInner) Signature { - if wrap, ok := pk.(Signature); ok { - pk = wrap.Unwrap() +func (sig *Signature) UnmarshalJSON(data []byte) (err error) { + parsed, err := sigMapper.FromJSON(data) + if err == nil && parsed != nil { + sig.SignatureInner = parsed.(SignatureInner) } - return Signature{pk} + return } // Unwrap recovers the concrete interface safely (regardless of levels of embeds) -func (p Signature) Unwrap() SignatureInner { - pk := p.SignatureInner +func (sig Signature) Unwrap() SignatureInner { + pk := sig.SignatureInner for wrap, ok := pk.(Signature); ok; wrap, ok = pk.(Signature) { pk = wrap.SignatureInner } return pk } -func (p Signature) MarshalJSON() ([]byte, error) { - return sigMapper.ToJSON(p.SignatureInner) -} - -func (p *Signature) UnmarshalJSON(data []byte) (err error) { - parsed, err := sigMapper.FromJSON(data) - if err == nil && parsed != nil { - p.SignatureInner = parsed.(SignatureInner) - } - return +func (sig Signature) Empty() bool { + return sig.SignatureInner == nil } -func (p Signature) Empty() bool { - return p.SignatureInner == nil -} - -func SignatureFromBytes(sigBytes []byte) (sig Signature, err error) { - err = wire.ReadBinaryBytes(sigBytes, &sig) - return -} +var sigMapper = data.NewMapper(Signature{}). + RegisterImplementation(SignatureEd25519{}, NameEd25519, TypeEd25519). + RegisterImplementation(SignatureSecp256k1{}, NameSecp256k1, TypeSecp256k1) //------------------------------------- // Implements Signature type SignatureEd25519 [64]byte +func (sig SignatureEd25519) AssertIsSignatureInner() {} + func (sig SignatureEd25519) Bytes() []byte { return wire.BinaryBytes(Signature{sig}) } @@ -98,22 +83,28 @@ func (sig SignatureEd25519) Equals(other Signature) bool { } } -func (p SignatureEd25519) MarshalJSON() ([]byte, error) { - return data.Encoder.Marshal(p[:]) +func (sig SignatureEd25519) MarshalJSON() ([]byte, error) { + return data.Encoder.Marshal(sig[:]) } -func (p *SignatureEd25519) UnmarshalJSON(enc []byte) error { +func (sig *SignatureEd25519) UnmarshalJSON(enc []byte) error { var ref []byte err := data.Encoder.Unmarshal(&ref, enc) - copy(p[:], ref) + copy(sig[:], ref) return err } +func (sig SignatureEd25519) Wrap() Signature { + return Signature{sig} +} + //------------------------------------- // Implements Signature type SignatureSecp256k1 []byte +func (sig SignatureSecp256k1) AssertIsSignatureInner() {} + func (sig SignatureSecp256k1) Bytes() []byte { return wire.BinaryBytes(Signature{sig}) } @@ -129,10 +120,14 @@ func (sig SignatureSecp256k1) Equals(other Signature) bool { return false } } -func (p SignatureSecp256k1) MarshalJSON() ([]byte, error) { - return data.Encoder.Marshal(p) +func (sig SignatureSecp256k1) MarshalJSON() ([]byte, error) { + return data.Encoder.Marshal(sig) +} + +func (sig *SignatureSecp256k1) UnmarshalJSON(enc []byte) error { + return data.Encoder.Unmarshal((*[]byte)(sig), enc) } -func (p *SignatureSecp256k1) UnmarshalJSON(enc []byte) error { - return data.Encoder.Unmarshal((*[]byte)(p), enc) +func (sig SignatureSecp256k1) Wrap() Signature { + return Signature{sig} } diff --git a/signature_test.go b/signature_test.go index 92fed906d..93aa17279 100644 --- a/signature_test.go +++ b/signature_test.go @@ -24,7 +24,7 @@ func TestSignAndValidateEd25519(t *testing.T) { // Mutate the signature, just one bit. sigEd := sig.Unwrap().(SignatureEd25519) sigEd[7] ^= byte(0x01) - sig = WrapSignature(sigEd) + sig = sigEd.Wrap() assert.False(t, pubKey.VerifyBytes(msg, sig)) } @@ -41,7 +41,7 @@ func TestSignAndValidateSecp256k1(t *testing.T) { // Mutate the signature, just one bit. sigEd := sig.Unwrap().(SignatureSecp256k1) sigEd[3] ^= byte(0x01) - sig = WrapSignature(sigEd) + sig = sigEd.Wrap() assert.False(t, pubKey.VerifyBytes(msg, sig)) } @@ -54,13 +54,13 @@ func TestSignatureEncodings(t *testing.T) { sigName string }{ { - privKey: WrapPrivKey(GenPrivKeyEd25519()), + privKey: GenPrivKeyEd25519().Wrap(), sigSize: ed25519.SignatureSize, sigType: TypeEd25519, sigName: NameEd25519, }, { - privKey: WrapPrivKey(GenPrivKeySecp256k1()), + privKey: GenPrivKeySecp256k1().Wrap(), sigSize: 0, // unknown sigType: TypeSecp256k1, sigName: NameSecp256k1, @@ -119,10 +119,10 @@ func TestWrapping(t *testing.T) { // do some wrapping pubs := []PubKey{ - WrapPubKey(nil), - WrapPubKey(pub), - WrapPubKey(WrapPubKey(WrapPubKey(WrapPubKey(pub)))), - WrapPubKey(PubKey{PubKey{PubKey{pub}}}), + PubKey{nil}, + pub.Wrap(), + pub.Wrap().Wrap().Wrap(), + PubKey{PubKey{PubKey{pub}}}.Wrap(), } for _, p := range pubs { _, ok := p.PubKeyInner.(PubKey) @@ -130,10 +130,10 @@ func TestWrapping(t *testing.T) { } sigs := []Signature{ - WrapSignature(nil), - WrapSignature(sig), - WrapSignature(WrapSignature(WrapSignature(WrapSignature(sig)))), - WrapSignature(Signature{Signature{Signature{sig}}}), + Signature{nil}, + sig.Wrap(), + sig.Wrap().Wrap().Wrap(), + Signature{Signature{Signature{sig}}}.Wrap(), } for _, s := range sigs { _, ok := s.SignatureInner.(Signature) From 926741c0a1b409d734ab635d52f6ffa5c4c03d2b Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sun, 9 Apr 2017 01:29:33 -0700 Subject: [PATCH 056/287] remove coin param --- hd/address.go | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/hd/address.go b/hd/address.go index afdeefbc4..139707e46 100644 --- a/hd/address.go +++ b/hd/address.go @@ -22,21 +22,13 @@ import ( "golang.org/x/crypto/ripemd160" ) -const ( - // BIP32 chainpath prefix - CHAINPATH_PREFIX_DEPOSIT = 0 - CHAINPATH_PREFIX_CHANGE = 1 - CHAINPATH_PREFIX_SWEEP = 2 - CHAINPATH_PREFIX_SWEEP_DRY = 102 -) - -func ComputeAddress(coin string, pubKeyHex string, chainHex string, path string, index int32) string { +func ComputeAddress(pubKeyHex string, chainHex string, path string, index int32) string { pubKeyBytes := DerivePublicKeyForPath( HexDecode(pubKeyHex), HexDecode(chainHex), fmt.Sprintf("%v/%v", path, index), ) - return AddrFromPubKeyBytes(coin, pubKeyBytes) + return AddrFromPubKeyBytes(pubKeyBytes) } func ComputePrivateKey(mprivHex string, chainHex string, path string, index int32) string { @@ -48,9 +40,9 @@ func ComputePrivateKey(mprivHex string, chainHex string, path string, index int3 return HexEncode(privKeyBytes) } -func ComputeAddressForPrivKey(coin string, privKey string) string { +func ComputeAddressForPrivKey(privKey string) string { pubKeyBytes := PubKeyBytesFromPrivKeyBytes(HexDecode(privKey), true) - return AddrFromPubKeyBytes(coin, pubKeyBytes) + return AddrFromPubKeyBytes(pubKeyBytes) } func SignMessage(privKey string, message string, compress bool) string { @@ -86,8 +78,8 @@ func ComputeMastersFromSeed(seed string) (string, string, string, string) { return HexEncode(pubKeyBytes), HexEncode(secret), HexEncode(chain), HexEncode(secret) } -func ComputeWIF(coin string, privKey string, compress bool) string { - return WIFFromPrivKeyBytes(coin, HexDecode(privKey), compress) +func ComputeWIF(privKey string, compress bool) string { + return WIFFromPrivKeyBytes(HexDecode(privKey), compress) } func ComputeTxId(rawTxHex string) string { @@ -100,7 +92,7 @@ func printKeyInfo(privKeyBytes []byte, pubKeyBytes []byte, chain []byte) { if pubKeyBytes == nil { pubKeyBytes = PubKeyBytesFromPrivKeyBytes(privKeyBytes, true) } - addr := AddrFromPubKeyBytes("BTC", pubKeyBytes) + addr := AddrFromPubKeyBytes(pubKeyBytes) log.Println("\nprikey:\t%v\npubKeyBytes:\t%v\naddr:\t%v\nchain:\t%v", HexEncode(privKeyBytes), HexEncode(pubKeyBytes), @@ -225,8 +217,9 @@ func I64(key []byte, data []byte) ([]byte, []byte) { return I[:32], I[32:] } -func AddrFromPubKeyBytes(coin string, pubKeyBytes []byte) string { - prefix := byte(0x00) // TODO Make const or configurable +// This returns a Bitcoin-like address. +func AddrFromPubKeyBytes(pubKeyBytes []byte) string { + prefix := byte(0x80) // TODO Make const or configurable h160 := CalcHash160(pubKeyBytes) h160 = append([]byte{prefix}, h160...) checksum := CalcHash256(h160) @@ -234,7 +227,15 @@ func AddrFromPubKeyBytes(coin string, pubKeyBytes []byte) string { return base58.Encode(b) } -func WIFFromPrivKeyBytes(coin string, privKeyBytes []byte, compress bool) string { +func AddrBytesFromPubKeyBytes(pubKeyBytes []byte) (addrBytes []byte, checksum []byte) { + prefix := byte(0x80) // TODO Make const or configurable + h160 := CalcHash160(pubKeyBytes) + _h160 := append([]byte{prefix}, h160...) + checksum = CalcHash256(_h160)[:4] + return h160, checksum +} + +func WIFFromPrivKeyBytes(privKeyBytes []byte, compress bool) string { prefix := byte(0x80) // TODO Make const or configurable bytes := append([]byte{prefix}, privKeyBytes...) if compress { From f17e6bf44c323d0b8883963428bc774aefebfda8 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Mon, 10 Apr 2017 03:01:35 -0700 Subject: [PATCH 057/287] Fix bitcoin addr scheme --- hd/address.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hd/address.go b/hd/address.go index 139707e46..28f70a98f 100644 --- a/hd/address.go +++ b/hd/address.go @@ -219,7 +219,7 @@ func I64(key []byte, data []byte) ([]byte, []byte) { // This returns a Bitcoin-like address. func AddrFromPubKeyBytes(pubKeyBytes []byte) string { - prefix := byte(0x80) // TODO Make const or configurable + prefix := byte(0x00) // TODO Make const or configurable h160 := CalcHash160(pubKeyBytes) h160 = append([]byte{prefix}, h160...) checksum := CalcHash256(h160) @@ -228,7 +228,7 @@ func AddrFromPubKeyBytes(pubKeyBytes []byte) string { } func AddrBytesFromPubKeyBytes(pubKeyBytes []byte) (addrBytes []byte, checksum []byte) { - prefix := byte(0x80) // TODO Make const or configurable + prefix := byte(0x00) // TODO Make const or configurable h160 := CalcHash160(pubKeyBytes) _h160 := append([]byte{prefix}, h160...) checksum = CalcHash256(_h160)[:4] From 9e57d521efa0bf734c51e0cad34837d31becc60b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 10 Apr 2017 13:05:52 +0200 Subject: [PATCH 058/287] Add type assertions for sig/pub/privkey implemenetations --- priv_key.go | 4 ++++ pub_key.go | 4 ++++ signature.go | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/priv_key.go b/priv_key.go index 74d5b5a3e..efb85908c 100644 --- a/priv_key.go +++ b/priv_key.go @@ -64,6 +64,8 @@ var privKeyMapper = data.NewMapper(PrivKey{}). //------------------------------------- +var _ PrivKeyInner = PrivKeyEd25519{} + // Implements PrivKey type PrivKeyEd25519 [64]byte @@ -149,6 +151,8 @@ func GenPrivKeyEd25519FromSecret(secret []byte) PrivKeyEd25519 { //------------------------------------- +var _ PrivKeyInner = PrivKeySecp256k1{} + // Implements PrivKey type PrivKeySecp256k1 [32]byte diff --git a/pub_key.go b/pub_key.go index e6567d347..4de7d59cd 100644 --- a/pub_key.go +++ b/pub_key.go @@ -67,6 +67,8 @@ var pubKeyMapper = data.NewMapper(PubKey{}). //------------------------------------- +var _ PubKeyInner = PubKeyEd25519{} + // Implements PubKeyInner type PubKeyEd25519 [32]byte @@ -146,6 +148,8 @@ func (pubKey PubKeyEd25519) Wrap() PubKey { //------------------------------------- +var _ PubKeyInner = PubKeySecp256k1{} + // Implements PubKey. // Compressed pubkey (just the x-cord), // prefixed with 0x02 or 0x03, depending on the y-cord. diff --git a/signature.go b/signature.go index 66c9a8a27..5a165dc42 100644 --- a/signature.go +++ b/signature.go @@ -62,6 +62,8 @@ var sigMapper = data.NewMapper(Signature{}). //------------------------------------- +var _ SignatureInner = SignatureEd25519{} + // Implements Signature type SignatureEd25519 [64]byte @@ -100,6 +102,8 @@ func (sig SignatureEd25519) Wrap() Signature { //------------------------------------- +var _ SignatureInner = SignatureSecp256k1{} + // Implements Signature type SignatureSecp256k1 []byte From aecc32d3636d86cf66af9b39fc20bb53578c78c2 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 10 Apr 2017 13:10:57 +0200 Subject: [PATCH 059/287] Make dependencies explicit in glide.yaml --- .gitignore | 5 +++++ Makefile | 2 +- glide.yaml | 31 +++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 glide.yaml diff --git a/.gitignore b/.gitignore index 381931381..aac058142 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ *.swp *.swo +vendor + +# these should be locked in the including repo, the dependencies are mainly +# for testing and documentation +glide.lock diff --git a/Makefile b/Makefile index 0cd05448a..b6bd861a6 100644 --- a/Makefile +++ b/Makefile @@ -6,4 +6,4 @@ docs: godoc2md $(REPO) > README.md test: - go test ./... + go test `glide novendor` diff --git a/glide.yaml b/glide.yaml new file mode 100644 index 000000000..4703d68c6 --- /dev/null +++ b/glide.yaml @@ -0,0 +1,31 @@ +package: github.com/tendermint/go-crypto +import: +- package: github.com/btcsuite/btcd + subpackages: + - btcec +- package: github.com/btcsuite/btcutil + subpackages: + - base58 +- package: github.com/tendermint/ed25519 + subpackages: + - extra25519 +- package: github.com/tendermint/go-common +- package: github.com/tendermint/go-data + version: develop +- package: github.com/tendermint/go-wire + version: develop +- package: golang.org/x/crypto + subpackages: + - blowfish + - nacl/secretbox + - openpgp/armor + - ripemd160 +testImport: +- package: github.com/mndrix/btcutil +- package: github.com/stretchr/testify + version: ^1.1.4 + subpackages: + - assert + - require +- package: github.com/tyler-smith/go-bip32 +- package: github.com/tyler-smith/go-bip39 From c410fc5e246e9accf95c6e80cb3c6aca2280755c Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 10 Apr 2017 14:24:07 +0200 Subject: [PATCH 060/287] Add extra test for encoding with sig,for p2p test fail --- encode_test.go | 73 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/encode_test.go b/encode_test.go index 2d709b943..c3380d435 100644 --- a/encode_test.go +++ b/encode_test.go @@ -16,13 +16,15 @@ type byter interface { } // go to wire encoding and back -func checkWire(t *testing.T, in byter, reader interface{}, typ byte) { +func checkWire(t *testing.T, in byter, reader interface{}, typ byte, size int) { // test to and from binary bin, err := data.ToWire(in) require.Nil(t, err, "%+v", err) assert.Equal(t, typ, bin[0]) // make sure this is compatible with current (Bytes()) encoding assert.Equal(t, in.Bytes(), bin) + // make sure we have the expected length + assert.Equal(t, size, len(bin)) err = data.FromWire(bin, reader) require.Nil(t, err, "%+v", err) @@ -67,23 +69,29 @@ func TestKeyEncodings(t *testing.T) { privKey PrivKey keyType byte keyName string + // 1 (type byte) + size of byte array + privSize, pubSize int }{ { - privKey: GenPrivKeyEd25519().Wrap(), - keyType: TypeEd25519, - keyName: NameEd25519, + privKey: GenPrivKeyEd25519().Wrap(), + keyType: TypeEd25519, + keyName: NameEd25519, + privSize: 65, + pubSize: 33, }, { - privKey: GenPrivKeySecp256k1().Wrap(), - keyType: TypeSecp256k1, - keyName: NameSecp256k1, + privKey: GenPrivKeySecp256k1().Wrap(), + keyType: TypeSecp256k1, + keyName: NameSecp256k1, + privSize: 33, + pubSize: 34, }, } for _, tc := range cases { // check (de/en)codings of private key var priv2, priv3, priv4 PrivKey - checkWire(t, tc.privKey, &priv2, tc.keyType) + checkWire(t, tc.privKey, &priv2, tc.keyType, tc.privSize) assert.EqualValues(t, tc.privKey, priv2) checkJSON(t, tc.privKey, &priv3, tc.keyName) assert.EqualValues(t, tc.privKey, priv3) @@ -93,7 +101,7 @@ func TestKeyEncodings(t *testing.T) { // check (de/en)codings of public key pubKey := tc.privKey.PubKey() var pub2, pub3, pub4 PubKey - checkWire(t, pubKey, &pub2, tc.keyType) + checkWire(t, pubKey, &pub2, tc.keyType, tc.pubSize) assert.EqualValues(t, pubKey, pub2) checkJSON(t, pubKey, &pub3, tc.keyName) assert.EqualValues(t, pubKey, pub3) @@ -126,3 +134,50 @@ func TestNilEncodings(t *testing.T) { assert.EqualValues(t, e, f) } + +type SigMessage struct { + Key PubKey + Sig Signature +} + +func (s SigMessage) Bytes() []byte { + return wire.BinaryBytes(s) +} + +func TestEmbededWireEncodings(t *testing.T) { + assert := assert.New(t) + + cases := []struct { + privKey PrivKey + keyType byte + keyName string + size int // pub + sig size + }{ + { + privKey: GenPrivKeyEd25519().Wrap(), + keyType: TypeEd25519, + keyName: NameEd25519, + size: 2 + 32 + 64, + }, + // { + // privKey: GenPrivKeySecp256k1().Wrap(), + // keyType: TypeSecp256k1, + // keyName: NameSecp256k1, + // size: 2 + 33 + 72, // ugh, either 72 or 73 depending.... + // }, + } + + payload := randBytes(20) + for i, tc := range cases { + pubKey := tc.privKey.PubKey() + sig := tc.privKey.Sign(payload) + assert.True(pubKey.VerifyBytes(payload, sig), "%d", i) + + msg := SigMessage{ + Key: pubKey, + Sig: sig, + } + var msg2 SigMessage + checkWire(t, msg, &msg2, tc.keyType, tc.size) + } +} From 8bb25ec5ed8fcdc75cd67e77765379b524fd6931 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 18 Apr 2017 18:17:02 -0400 Subject: [PATCH 061/287] update paths --- armor.go | 2 +- embed_test.go | 2 +- encode_test.go | 2 +- glide.yaml | 7 +++---- priv_key.go | 4 ++-- pub_key.go | 4 ++-- random.go | 2 +- signature.go | 4 ++-- signature_test.go | 2 +- symmetric.go | 2 +- 10 files changed, 15 insertions(+), 16 deletions(-) diff --git a/armor.go b/armor.go index 9343284e1..3d2eff5e7 100644 --- a/armor.go +++ b/armor.go @@ -4,7 +4,7 @@ import ( "bytes" "io/ioutil" - . "github.com/tendermint/go-common" + . "github.com/tendermint/tmlibs/common" "golang.org/x/crypto/openpgp/armor" ) diff --git a/embed_test.go b/embed_test.go index 6ebba893c..e2d2fe504 100644 --- a/embed_test.go +++ b/embed_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - data "github.com/tendermint/go-data" + data "github.com/tendermint/go-wire/data" ) type PubName struct { diff --git a/encode_test.go b/encode_test.go index c3380d435..6c5d03a1d 100644 --- a/encode_test.go +++ b/encode_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - data "github.com/tendermint/go-data" + data "github.com/tendermint/go-wire/data" wire "github.com/tendermint/go-wire" ) diff --git a/glide.yaml b/glide.yaml index 4703d68c6..d5e0e2bbf 100644 --- a/glide.yaml +++ b/glide.yaml @@ -9,11 +9,10 @@ import: - package: github.com/tendermint/ed25519 subpackages: - extra25519 -- package: github.com/tendermint/go-common -- package: github.com/tendermint/go-data - version: develop +- package: github.com/tendermint/tmlibs + version: unstable - package: github.com/tendermint/go-wire - version: develop + version: unstable - package: golang.org/x/crypto subpackages: - blowfish diff --git a/priv_key.go b/priv_key.go index efb85908c..85f8a8ec4 100644 --- a/priv_key.go +++ b/priv_key.go @@ -6,8 +6,8 @@ import ( secp256k1 "github.com/btcsuite/btcd/btcec" "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" - . "github.com/tendermint/go-common" - data "github.com/tendermint/go-data" + . "github.com/tendermint/tmlibs/common" + data "github.com/tendermint/go-wire/data" "github.com/tendermint/go-wire" ) diff --git a/pub_key.go b/pub_key.go index 4de7d59cd..99839f288 100644 --- a/pub_key.go +++ b/pub_key.go @@ -7,8 +7,8 @@ import ( secp256k1 "github.com/btcsuite/btcd/btcec" "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" - . "github.com/tendermint/go-common" - data "github.com/tendermint/go-data" + . "github.com/tendermint/tmlibs/common" + data "github.com/tendermint/go-wire/data" "github.com/tendermint/go-wire" "golang.org/x/crypto/ripemd160" ) diff --git a/random.go b/random.go index edadeaab6..40cbcf8fa 100644 --- a/random.go +++ b/random.go @@ -8,7 +8,7 @@ import ( "io" "sync" - . "github.com/tendermint/go-common" + . "github.com/tendermint/tmlibs/common" ) var gRandInfo *randInfo diff --git a/signature.go b/signature.go index 5a165dc42..36451ed48 100644 --- a/signature.go +++ b/signature.go @@ -4,8 +4,8 @@ import ( "bytes" "fmt" - . "github.com/tendermint/go-common" - data "github.com/tendermint/go-data" + . "github.com/tendermint/tmlibs/common" + data "github.com/tendermint/go-wire/data" "github.com/tendermint/go-wire" ) diff --git a/signature_test.go b/signature_test.go index 93aa17279..5e9f06723 100644 --- a/signature_test.go +++ b/signature_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tendermint/ed25519" - data "github.com/tendermint/go-data" + data "github.com/tendermint/go-wire/data" ) func TestSignAndValidateEd25519(t *testing.T) { diff --git a/symmetric.go b/symmetric.go index 36bddd44c..d4ac9b55b 100644 --- a/symmetric.go +++ b/symmetric.go @@ -3,7 +3,7 @@ package crypto import ( "errors" - . "github.com/tendermint/go-common" + . "github.com/tendermint/tmlibs/common" "golang.org/x/crypto/nacl/secretbox" ) From 17ed6d178d8d1eff960ff84b38be4ceda97bade8 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 19 Apr 2017 16:51:29 +0200 Subject: [PATCH 062/287] move go-crypto files pre-keys merge --- LICENSE => crypto/LICENSE | 0 Makefile => crypto/Makefile | 0 README.md => crypto/README.md | 0 armor.go => crypto/armor.go | 0 armor_test.go => crypto/armor_test.go | 0 {bcrypt => crypto/bcrypt}/base64.go | 0 {bcrypt => crypto/bcrypt}/bcrypt.go | 0 crypto.go => crypto/crypto.go | 0 embed_test.go => crypto/embed_test.go | 0 encode_test.go => crypto/encode_test.go | 0 glide.yaml => crypto/glide.yaml | 0 hash.go => crypto/hash.go | 0 {hd => crypto/hd}/address.go | 0 {hd => crypto/hd}/address_test.go | 0 {hd => crypto/hd}/hd_test.go | 0 {hd => crypto/hd}/test.json | 0 priv_key.go => crypto/priv_key.go | 0 pub_key.go => crypto/pub_key.go | 0 pub_key_test.go => crypto/pub_key_test.go | 0 random.go => crypto/random.go | 0 signature.go => crypto/signature.go | 0 signature_test.go => crypto/signature_test.go | 0 symmetric.go => crypto/symmetric.go | 0 symmetric_test.go => crypto/symmetric_test.go | 0 24 files changed, 0 insertions(+), 0 deletions(-) rename LICENSE => crypto/LICENSE (100%) rename Makefile => crypto/Makefile (100%) rename README.md => crypto/README.md (100%) rename armor.go => crypto/armor.go (100%) rename armor_test.go => crypto/armor_test.go (100%) rename {bcrypt => crypto/bcrypt}/base64.go (100%) rename {bcrypt => crypto/bcrypt}/bcrypt.go (100%) rename crypto.go => crypto/crypto.go (100%) rename embed_test.go => crypto/embed_test.go (100%) rename encode_test.go => crypto/encode_test.go (100%) rename glide.yaml => crypto/glide.yaml (100%) rename hash.go => crypto/hash.go (100%) rename {hd => crypto/hd}/address.go (100%) rename {hd => crypto/hd}/address_test.go (100%) rename {hd => crypto/hd}/hd_test.go (100%) rename {hd => crypto/hd}/test.json (100%) rename priv_key.go => crypto/priv_key.go (100%) rename pub_key.go => crypto/pub_key.go (100%) rename pub_key_test.go => crypto/pub_key_test.go (100%) rename random.go => crypto/random.go (100%) rename signature.go => crypto/signature.go (100%) rename signature_test.go => crypto/signature_test.go (100%) rename symmetric.go => crypto/symmetric.go (100%) rename symmetric_test.go => crypto/symmetric_test.go (100%) diff --git a/LICENSE b/crypto/LICENSE similarity index 100% rename from LICENSE rename to crypto/LICENSE diff --git a/Makefile b/crypto/Makefile similarity index 100% rename from Makefile rename to crypto/Makefile diff --git a/README.md b/crypto/README.md similarity index 100% rename from README.md rename to crypto/README.md diff --git a/armor.go b/crypto/armor.go similarity index 100% rename from armor.go rename to crypto/armor.go diff --git a/armor_test.go b/crypto/armor_test.go similarity index 100% rename from armor_test.go rename to crypto/armor_test.go diff --git a/bcrypt/base64.go b/crypto/bcrypt/base64.go similarity index 100% rename from bcrypt/base64.go rename to crypto/bcrypt/base64.go diff --git a/bcrypt/bcrypt.go b/crypto/bcrypt/bcrypt.go similarity index 100% rename from bcrypt/bcrypt.go rename to crypto/bcrypt/bcrypt.go diff --git a/crypto.go b/crypto/crypto.go similarity index 100% rename from crypto.go rename to crypto/crypto.go diff --git a/embed_test.go b/crypto/embed_test.go similarity index 100% rename from embed_test.go rename to crypto/embed_test.go diff --git a/encode_test.go b/crypto/encode_test.go similarity index 100% rename from encode_test.go rename to crypto/encode_test.go diff --git a/glide.yaml b/crypto/glide.yaml similarity index 100% rename from glide.yaml rename to crypto/glide.yaml diff --git a/hash.go b/crypto/hash.go similarity index 100% rename from hash.go rename to crypto/hash.go diff --git a/hd/address.go b/crypto/hd/address.go similarity index 100% rename from hd/address.go rename to crypto/hd/address.go diff --git a/hd/address_test.go b/crypto/hd/address_test.go similarity index 100% rename from hd/address_test.go rename to crypto/hd/address_test.go diff --git a/hd/hd_test.go b/crypto/hd/hd_test.go similarity index 100% rename from hd/hd_test.go rename to crypto/hd/hd_test.go diff --git a/hd/test.json b/crypto/hd/test.json similarity index 100% rename from hd/test.json rename to crypto/hd/test.json diff --git a/priv_key.go b/crypto/priv_key.go similarity index 100% rename from priv_key.go rename to crypto/priv_key.go diff --git a/pub_key.go b/crypto/pub_key.go similarity index 100% rename from pub_key.go rename to crypto/pub_key.go diff --git a/pub_key_test.go b/crypto/pub_key_test.go similarity index 100% rename from pub_key_test.go rename to crypto/pub_key_test.go diff --git a/random.go b/crypto/random.go similarity index 100% rename from random.go rename to crypto/random.go diff --git a/signature.go b/crypto/signature.go similarity index 100% rename from signature.go rename to crypto/signature.go diff --git a/signature_test.go b/crypto/signature_test.go similarity index 100% rename from signature_test.go rename to crypto/signature_test.go diff --git a/symmetric.go b/crypto/symmetric.go similarity index 100% rename from symmetric.go rename to crypto/symmetric.go diff --git a/symmetric_test.go b/crypto/symmetric_test.go similarity index 100% rename from symmetric_test.go rename to crypto/symmetric_test.go From 9016390a6e4d957b909650dbfa63b81510c3a68d Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 19 Apr 2017 16:55:15 +0200 Subject: [PATCH 063/287] Moved crypto code to top level again --- crypto/LICENSE => LICENSE | 0 crypto/Makefile => Makefile | 0 crypto/README.md => README.md | 0 crypto/armor.go => armor.go | 0 crypto/armor_test.go => armor_test.go | 0 {crypto/bcrypt => bcrypt}/base64.go | 0 {crypto/bcrypt => bcrypt}/bcrypt.go | 0 crypto/crypto.go => crypto.go | 0 crypto/embed_test.go => embed_test.go | 0 crypto/encode_test.go => encode_test.go | 0 crypto/glide.yaml => glide.yaml | 0 crypto/hash.go => hash.go | 0 {crypto/hd => hd}/address.go | 0 {crypto/hd => hd}/address_test.go | 0 {crypto/hd => hd}/hd_test.go | 0 {crypto/hd => hd}/test.json | 0 keys/cmd/keys/main.go | 2 +- keys/cmd/root.go | 6 +++--- keys/cmd/serve.go | 2 +- keys/cmd/utils.go | 2 +- keys/cryptostore/enc_storage.go | 2 +- keys/cryptostore/encoder_test.go | 2 +- keys/cryptostore/holder.go | 2 +- keys/cryptostore/holder_test.go | 4 ++-- keys/cryptostore/storage_test.go | 2 +- keys/server/helpers.go | 2 +- keys/server/keys.go | 4 ++-- keys/server/keys_test.go | 10 +++++----- keys/storage/filestorage/main.go | 2 +- keys/storage/filestorage/main_test.go | 2 +- keys/storage/memstorage/main.go | 2 +- keys/storage/memstorage/main_test.go | 2 +- keys/tx/multi_test.go | 6 +++--- keys/tx/one_test.go | 6 +++--- keys/tx/reader.go | 2 +- keys/tx/reader_test.go | 4 ++-- crypto/priv_key.go => priv_key.go | 0 crypto/pub_key.go => pub_key.go | 0 crypto/pub_key_test.go => pub_key_test.go | 0 crypto/random.go => random.go | 0 crypto/signature.go => signature.go | 0 crypto/signature_test.go => signature_test.go | 0 crypto/symmetric.go => symmetric.go | 0 crypto/symmetric_test.go => symmetric_test.go | 0 44 files changed, 33 insertions(+), 33 deletions(-) rename crypto/LICENSE => LICENSE (100%) rename crypto/Makefile => Makefile (100%) rename crypto/README.md => README.md (100%) rename crypto/armor.go => armor.go (100%) rename crypto/armor_test.go => armor_test.go (100%) rename {crypto/bcrypt => bcrypt}/base64.go (100%) rename {crypto/bcrypt => bcrypt}/bcrypt.go (100%) rename crypto/crypto.go => crypto.go (100%) rename crypto/embed_test.go => embed_test.go (100%) rename crypto/encode_test.go => encode_test.go (100%) rename crypto/glide.yaml => glide.yaml (100%) rename crypto/hash.go => hash.go (100%) rename {crypto/hd => hd}/address.go (100%) rename {crypto/hd => hd}/address_test.go (100%) rename {crypto/hd => hd}/hd_test.go (100%) rename {crypto/hd => hd}/test.json (100%) rename crypto/priv_key.go => priv_key.go (100%) rename crypto/pub_key.go => pub_key.go (100%) rename crypto/pub_key_test.go => pub_key_test.go (100%) rename crypto/random.go => random.go (100%) rename crypto/signature.go => signature.go (100%) rename crypto/signature_test.go => signature_test.go (100%) rename crypto/symmetric.go => symmetric.go (100%) rename crypto/symmetric_test.go => symmetric_test.go (100%) diff --git a/crypto/LICENSE b/LICENSE similarity index 100% rename from crypto/LICENSE rename to LICENSE diff --git a/crypto/Makefile b/Makefile similarity index 100% rename from crypto/Makefile rename to Makefile diff --git a/crypto/README.md b/README.md similarity index 100% rename from crypto/README.md rename to README.md diff --git a/crypto/armor.go b/armor.go similarity index 100% rename from crypto/armor.go rename to armor.go diff --git a/crypto/armor_test.go b/armor_test.go similarity index 100% rename from crypto/armor_test.go rename to armor_test.go diff --git a/crypto/bcrypt/base64.go b/bcrypt/base64.go similarity index 100% rename from crypto/bcrypt/base64.go rename to bcrypt/base64.go diff --git a/crypto/bcrypt/bcrypt.go b/bcrypt/bcrypt.go similarity index 100% rename from crypto/bcrypt/bcrypt.go rename to bcrypt/bcrypt.go diff --git a/crypto/crypto.go b/crypto.go similarity index 100% rename from crypto/crypto.go rename to crypto.go diff --git a/crypto/embed_test.go b/embed_test.go similarity index 100% rename from crypto/embed_test.go rename to embed_test.go diff --git a/crypto/encode_test.go b/encode_test.go similarity index 100% rename from crypto/encode_test.go rename to encode_test.go diff --git a/crypto/glide.yaml b/glide.yaml similarity index 100% rename from crypto/glide.yaml rename to glide.yaml diff --git a/crypto/hash.go b/hash.go similarity index 100% rename from crypto/hash.go rename to hash.go diff --git a/crypto/hd/address.go b/hd/address.go similarity index 100% rename from crypto/hd/address.go rename to hd/address.go diff --git a/crypto/hd/address_test.go b/hd/address_test.go similarity index 100% rename from crypto/hd/address_test.go rename to hd/address_test.go diff --git a/crypto/hd/hd_test.go b/hd/hd_test.go similarity index 100% rename from crypto/hd/hd_test.go rename to hd/hd_test.go diff --git a/crypto/hd/test.json b/hd/test.json similarity index 100% rename from crypto/hd/test.json rename to hd/test.json diff --git a/keys/cmd/keys/main.go b/keys/cmd/keys/main.go index 8b92b3f49..995df845b 100644 --- a/keys/cmd/keys/main.go +++ b/keys/cmd/keys/main.go @@ -17,7 +17,7 @@ package main import ( "os" - "github.com/tendermint/go-keys/cmd" + "github.com/tendermint/go-crypto/keys/cmd" ) func main() { diff --git a/keys/cmd/root.go b/keys/cmd/root.go index 64adf2b0b..401e7ec38 100644 --- a/keys/cmd/root.go +++ b/keys/cmd/root.go @@ -19,9 +19,9 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - keys "github.com/tendermint/go-keys" - "github.com/tendermint/go-keys/cryptostore" - "github.com/tendermint/go-keys/storage/filestorage" + keys "github.com/tendermint/go-crypto/keys" + "github.com/tendermint/go-crypto/keys/cryptostore" + "github.com/tendermint/go-crypto/keys/storage/filestorage" ) const KeySubdir = "keys" diff --git a/keys/cmd/serve.go b/keys/cmd/serve.go index c3f7dbe39..5ea96db3f 100644 --- a/keys/cmd/serve.go +++ b/keys/cmd/serve.go @@ -25,7 +25,7 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/tendermint/go-keys/server" + "github.com/tendermint/go-crypto/keys/server" ) // serveCmd represents the serve command diff --git a/keys/cmd/utils.go b/keys/cmd/utils.go index 31a3a8df3..c61383004 100644 --- a/keys/cmd/utils.go +++ b/keys/cmd/utils.go @@ -7,7 +7,7 @@ import ( "github.com/pkg/errors" "github.com/spf13/viper" data "github.com/tendermint/go-data" - keys "github.com/tendermint/go-keys" + keys "github.com/tendermint/go-crypto/keys" ) const PassLength = 10 diff --git a/keys/cryptostore/enc_storage.go b/keys/cryptostore/enc_storage.go index 9589f4cc1..70e212138 100644 --- a/keys/cryptostore/enc_storage.go +++ b/keys/cryptostore/enc_storage.go @@ -2,7 +2,7 @@ package cryptostore import ( crypto "github.com/tendermint/go-crypto" - keys "github.com/tendermint/go-keys" + keys "github.com/tendermint/go-crypto/keys" ) // encryptedStorage needs passphrase to get private keys diff --git a/keys/cryptostore/encoder_test.go b/keys/cryptostore/encoder_test.go index 8b72509ed..0535737d7 100644 --- a/keys/cryptostore/encoder_test.go +++ b/keys/cryptostore/encoder_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/tendermint/go-keys/cryptostore" + "github.com/tendermint/go-crypto/keys/cryptostore" ) func TestNoopEncoder(t *testing.T) { diff --git a/keys/cryptostore/holder.go b/keys/cryptostore/holder.go index 549326614..42d4662de 100644 --- a/keys/cryptostore/holder.go +++ b/keys/cryptostore/holder.go @@ -1,6 +1,6 @@ package cryptostore -import keys "github.com/tendermint/go-keys" +import keys "github.com/tendermint/go-crypto/keys" // Manager combines encyption and storage implementation to provide // a full-featured key manager diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index 860869c86..4f0383198 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -6,8 +6,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" crypto "github.com/tendermint/go-crypto" - "github.com/tendermint/go-keys/cryptostore" - "github.com/tendermint/go-keys/storage/memstorage" + "github.com/tendermint/go-crypto/keys/cryptostore" + "github.com/tendermint/go-crypto/keys/storage/memstorage" ) // TestKeyManagement makes sure we can manipulate these keys well diff --git a/keys/cryptostore/storage_test.go b/keys/cryptostore/storage_test.go index 78d107c11..b109c44e8 100644 --- a/keys/cryptostore/storage_test.go +++ b/keys/cryptostore/storage_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - keys "github.com/tendermint/go-keys" + keys "github.com/tendermint/go-crypto/keys" ) func TestSortKeys(t *testing.T) { diff --git a/keys/server/helpers.go b/keys/server/helpers.go index 111f158e7..954922060 100644 --- a/keys/server/helpers.go +++ b/keys/server/helpers.go @@ -13,7 +13,7 @@ import ( "net/http" data "github.com/tendermint/go-data" - "github.com/tendermint/go-keys/server/types" + "github.com/tendermint/go-crypto/keys/server/types" "github.com/pkg/errors" ) diff --git a/keys/server/keys.go b/keys/server/keys.go index 78a382e5e..90d6da2b0 100644 --- a/keys/server/keys.go +++ b/keys/server/keys.go @@ -5,8 +5,8 @@ import ( "net/http" "github.com/gorilla/mux" - keys "github.com/tendermint/go-keys" - "github.com/tendermint/go-keys/server/types" + keys "github.com/tendermint/go-crypto/keys" + "github.com/tendermint/go-crypto/keys/server/types" ) type Keys struct { diff --git a/keys/server/keys_test.go b/keys/server/keys_test.go index 8333e8e53..4908559b0 100644 --- a/keys/server/keys_test.go +++ b/keys/server/keys_test.go @@ -10,11 +10,11 @@ import ( "github.com/gorilla/mux" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - keys "github.com/tendermint/go-keys" - "github.com/tendermint/go-keys/cryptostore" - "github.com/tendermint/go-keys/server" - "github.com/tendermint/go-keys/server/types" - "github.com/tendermint/go-keys/storage/memstorage" + keys "github.com/tendermint/go-crypto/keys" + "github.com/tendermint/go-crypto/keys/cryptostore" + "github.com/tendermint/go-crypto/keys/server" + "github.com/tendermint/go-crypto/keys/server/types" + "github.com/tendermint/go-crypto/keys/storage/memstorage" ) func TestKeyServer(t *testing.T) { diff --git a/keys/storage/filestorage/main.go b/keys/storage/filestorage/main.go index 737f0772c..1add482e2 100644 --- a/keys/storage/filestorage/main.go +++ b/keys/storage/filestorage/main.go @@ -14,7 +14,7 @@ import ( "github.com/pkg/errors" crypto "github.com/tendermint/go-crypto" - keys "github.com/tendermint/go-keys" + keys "github.com/tendermint/go-crypto/keys" ) const ( diff --git a/keys/storage/filestorage/main_test.go b/keys/storage/filestorage/main_test.go index 890898dcb..c569eb6f9 100644 --- a/keys/storage/filestorage/main_test.go +++ b/keys/storage/filestorage/main_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" crypto "github.com/tendermint/go-crypto" - keys "github.com/tendermint/go-keys" + keys "github.com/tendermint/go-crypto/keys" ) func TestBasicCRUD(t *testing.T) { diff --git a/keys/storage/memstorage/main.go b/keys/storage/memstorage/main.go index 69c8d9b03..195fa7a17 100644 --- a/keys/storage/memstorage/main.go +++ b/keys/storage/memstorage/main.go @@ -7,7 +7,7 @@ package memstorage import ( "github.com/pkg/errors" - keys "github.com/tendermint/go-keys" + keys "github.com/tendermint/go-crypto/keys" ) type data struct { diff --git a/keys/storage/memstorage/main_test.go b/keys/storage/memstorage/main_test.go index 7605c8225..8bc7e355f 100644 --- a/keys/storage/memstorage/main_test.go +++ b/keys/storage/memstorage/main_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" crypto "github.com/tendermint/go-crypto" - keys "github.com/tendermint/go-keys" + keys "github.com/tendermint/go-crypto/keys" ) func TestBasicCRUD(t *testing.T) { diff --git a/keys/tx/multi_test.go b/keys/tx/multi_test.go index 815b9e15a..97463a5f7 100644 --- a/keys/tx/multi_test.go +++ b/keys/tx/multi_test.go @@ -6,9 +6,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" crypto "github.com/tendermint/go-crypto" - keys "github.com/tendermint/go-keys" - "github.com/tendermint/go-keys/cryptostore" - "github.com/tendermint/go-keys/storage/memstorage" + keys "github.com/tendermint/go-crypto/keys" + "github.com/tendermint/go-crypto/keys/cryptostore" + "github.com/tendermint/go-crypto/keys/storage/memstorage" ) func TestMultiSig(t *testing.T) { diff --git a/keys/tx/one_test.go b/keys/tx/one_test.go index 71b8011ef..05af347b4 100644 --- a/keys/tx/one_test.go +++ b/keys/tx/one_test.go @@ -6,9 +6,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" crypto "github.com/tendermint/go-crypto" - keys "github.com/tendermint/go-keys" - "github.com/tendermint/go-keys/cryptostore" - "github.com/tendermint/go-keys/storage/memstorage" + keys "github.com/tendermint/go-crypto/keys" + "github.com/tendermint/go-crypto/keys/cryptostore" + "github.com/tendermint/go-crypto/keys/storage/memstorage" ) func TestOneSig(t *testing.T) { diff --git a/keys/tx/reader.go b/keys/tx/reader.go index 7689693cb..16a403719 100644 --- a/keys/tx/reader.go +++ b/keys/tx/reader.go @@ -3,7 +3,7 @@ package tx import ( crypto "github.com/tendermint/go-crypto" data "github.com/tendermint/go-data" - keys "github.com/tendermint/go-keys" + keys "github.com/tendermint/go-crypto/keys" ) const ( diff --git a/keys/tx/reader_test.go b/keys/tx/reader_test.go index 54b76af96..4b365604d 100644 --- a/keys/tx/reader_test.go +++ b/keys/tx/reader_test.go @@ -7,8 +7,8 @@ import ( "github.com/stretchr/testify/require" crypto "github.com/tendermint/go-crypto" data "github.com/tendermint/go-data" - "github.com/tendermint/go-keys/cryptostore" - "github.com/tendermint/go-keys/storage/memstorage" + "github.com/tendermint/go-crypto/keys/cryptostore" + "github.com/tendermint/go-crypto/keys/storage/memstorage" ) func TestReader(t *testing.T) { diff --git a/crypto/priv_key.go b/priv_key.go similarity index 100% rename from crypto/priv_key.go rename to priv_key.go diff --git a/crypto/pub_key.go b/pub_key.go similarity index 100% rename from crypto/pub_key.go rename to pub_key.go diff --git a/crypto/pub_key_test.go b/pub_key_test.go similarity index 100% rename from crypto/pub_key_test.go rename to pub_key_test.go diff --git a/crypto/random.go b/random.go similarity index 100% rename from crypto/random.go rename to random.go diff --git a/crypto/signature.go b/signature.go similarity index 100% rename from crypto/signature.go rename to signature.go diff --git a/crypto/signature_test.go b/signature_test.go similarity index 100% rename from crypto/signature_test.go rename to signature_test.go diff --git a/crypto/symmetric.go b/symmetric.go similarity index 100% rename from crypto/symmetric.go rename to symmetric.go diff --git a/crypto/symmetric_test.go b/symmetric_test.go similarity index 100% rename from crypto/symmetric_test.go rename to symmetric_test.go From 0bfae964e140ef1d8b25e5838430c459e04760e1 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 19 Apr 2017 17:07:12 +0200 Subject: [PATCH 064/287] Moved keys cmd to top level --- .gitignore | 4 - Makefile | 20 +++- {keys/cmd => cmd}/README.md | 0 {keys/cmd => cmd}/common.go | 2 +- {keys/cmd => cmd}/get.go | 0 {keys/cmd => cmd}/keys/main.go | 2 +- {keys/cmd => cmd}/list.go | 0 {keys/cmd => cmd}/new.go | 0 {keys/cmd => cmd}/root.go | 0 {keys/cmd => cmd}/serve.go | 0 {keys/cmd => cmd}/update.go | 0 {keys/cmd => cmd}/utils.go | 2 +- keys/glide.lock => glide.lock | 75 ++++++++---- glide.yaml | 10 ++ keys/LICENSE | 202 --------------------------------- keys/glide.yaml | 19 ---- 16 files changed, 82 insertions(+), 254 deletions(-) rename {keys/cmd => cmd}/README.md (100%) rename {keys/cmd => cmd}/common.go (98%) rename {keys/cmd => cmd}/get.go (100%) rename {keys/cmd => cmd}/keys/main.go (94%) rename {keys/cmd => cmd}/list.go (100%) rename {keys/cmd => cmd}/new.go (100%) rename {keys/cmd => cmd}/root.go (100%) rename {keys/cmd => cmd}/serve.go (100%) rename {keys/cmd => cmd}/update.go (100%) rename {keys/cmd => cmd}/utils.go (97%) rename keys/glide.lock => glide.lock (60%) delete mode 100644 keys/LICENSE delete mode 100644 keys/glide.yaml diff --git a/.gitignore b/.gitignore index aac058142..f37225baa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,3 @@ *.swp *.swo vendor - -# these should be locked in the including repo, the dependencies are mainly -# for testing and documentation -glide.lock diff --git a/Makefile b/Makefile index b6bd861a6..59440fe66 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,27 @@ -.PHONY: docs +.PHONEY: all docs test install get_vendor_deps ensure_tools + +GOTOOLS = \ + github.com/Masterminds/glide REPO:=github.com/tendermint/go-crypto docs: @go get github.com/davecheney/godoc2md godoc2md $(REPO) > README.md +all: install test + +install: + go install ./cmd/keys + test: go test `glide novendor` + +get_vendor_deps: ensure_tools + @rm -rf vendor/ + @echo "--> Running glide install" + @glide install + +ensure_tools: + go get $(GOTOOLS) + + diff --git a/keys/cmd/README.md b/cmd/README.md similarity index 100% rename from keys/cmd/README.md rename to cmd/README.md diff --git a/keys/cmd/common.go b/cmd/common.go similarity index 98% rename from keys/cmd/common.go rename to cmd/common.go index eb7a158ae..c68cd4304 100644 --- a/keys/cmd/common.go +++ b/cmd/common.go @@ -8,8 +8,8 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" - data "github.com/tendermint/go-data" "github.com/tendermint/go-data/base58" + data "github.com/tendermint/go-wire/data" ) /******* diff --git a/keys/cmd/get.go b/cmd/get.go similarity index 100% rename from keys/cmd/get.go rename to cmd/get.go diff --git a/keys/cmd/keys/main.go b/cmd/keys/main.go similarity index 94% rename from keys/cmd/keys/main.go rename to cmd/keys/main.go index 995df845b..8dd8d6505 100644 --- a/keys/cmd/keys/main.go +++ b/cmd/keys/main.go @@ -17,7 +17,7 @@ package main import ( "os" - "github.com/tendermint/go-crypto/keys/cmd" + "github.com/tendermint/go-crypto/cmd" ) func main() { diff --git a/keys/cmd/list.go b/cmd/list.go similarity index 100% rename from keys/cmd/list.go rename to cmd/list.go diff --git a/keys/cmd/new.go b/cmd/new.go similarity index 100% rename from keys/cmd/new.go rename to cmd/new.go diff --git a/keys/cmd/root.go b/cmd/root.go similarity index 100% rename from keys/cmd/root.go rename to cmd/root.go diff --git a/keys/cmd/serve.go b/cmd/serve.go similarity index 100% rename from keys/cmd/serve.go rename to cmd/serve.go diff --git a/keys/cmd/update.go b/cmd/update.go similarity index 100% rename from keys/cmd/update.go rename to cmd/update.go diff --git a/keys/cmd/utils.go b/cmd/utils.go similarity index 97% rename from keys/cmd/utils.go rename to cmd/utils.go index c61383004..a75262676 100644 --- a/keys/cmd/utils.go +++ b/cmd/utils.go @@ -6,8 +6,8 @@ import ( "github.com/bgentry/speakeasy" "github.com/pkg/errors" "github.com/spf13/viper" - data "github.com/tendermint/go-data" keys "github.com/tendermint/go-crypto/keys" + data "github.com/tendermint/go-wire/data" ) const PassLength = 10 diff --git a/keys/glide.lock b/glide.lock similarity index 60% rename from keys/glide.lock rename to glide.lock index c74262a4e..b804b4801 100644 --- a/keys/glide.lock +++ b/glide.lock @@ -1,14 +1,26 @@ -hash: 4a517b0f71ea6e3aadcf98286cde97c2f567e9e7999a4c7ec9ce6e5b6c21564a -updated: 2017-03-02T16:57:20.740518259-05:00 +hash: 8a63c035134ec024df64d8cc43a732712e48e4cfc5de30d45c1b692b3e9a75b8 +updated: 2017-04-19T17:06:49.640329917+02:00 imports: - name: github.com/bgentry/speakeasy version: 675b82c74c0ed12283ee81ba8a534c8982c07b85 - name: github.com/btcsuite/btcd - version: d06c0bb181529331be8f8d9350288c420d9e60e4 + version: 583684b21bfbde9b5fc4403916fd7c807feb0289 subpackages: - btcec + - chaincfg + - chaincfg/chainhash + - wire +- name: github.com/btcsuite/btcutil + version: a5ecb5d9547afe8d1672073dbdc348203de744a0 + subpackages: + - base58 + - hdkeychain +- name: github.com/btcsuite/golangcrypto + version: 53f62d9b43e87a6c56975cf862af7edf33a8d0df + subpackages: + - ripemd160 - name: github.com/fsnotify/fsnotify - version: 7d7316ed6e1ed2de075aab8dfc76de5d158d66e1 + version: 4da3e2cfbabc9f751898f250b49f2439785783a1 - name: github.com/go-playground/locales version: 084b0226cf88d891a2bdeccac01d592af13a8f7b subpackages: @@ -20,9 +32,9 @@ imports: - name: github.com/gorilla/context version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42 - name: github.com/gorilla/handlers - version: 13d73096a474cac93275c679c7b8a2dc17ddba82 + version: 3a5767ca75ece5f7f1440b1d16975247f8d8b221 - name: github.com/gorilla/mux - version: 599cba5e7b6137d46ddf58fb1765f5d928e69604 + version: 392c28fe23e1c45ddba891b0320b3b5df220beea - name: github.com/hashicorp/hcl version: 630949a3c5fa3c613328e1b8256052cbc2327c9b subpackages: @@ -37,25 +49,25 @@ imports: - name: github.com/inconshreveable/mousetrap version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 - name: github.com/magiconair/properties - version: b3b15ef068fd0b17ddf408a23669f20811d194d2 + version: 51463bfca2576e06c62a8504b5c0f06d61312647 - name: github.com/mattn/go-colorable - version: 5411d3eea5978e6cdc258b30de592b60df6aba96 + version: a392f450ea64cee2b268dfaacdc2502b50a22b18 - name: github.com/mattn/go-isatty - version: 281032e84ae07510239465db46bf442aa44b953a + version: 57fdcb988a5c543893cc61bce354a6e24ab70022 - name: github.com/mitchellh/mapstructure - version: db1efb556f84b25a0a13a04aad883943538ad2e0 + version: 53818660ed4955e899c0bcafa97299a388bd7c8e - name: github.com/pelletier/go-buffruneio version: c37440a7cf42ac63b919c752ca73a85067e05992 - name: github.com/pelletier/go-toml version: 13d49d4606eb801b8f01ae542b4afc4c6ee3d84a - name: github.com/pkg/errors - version: 248dadf4e9068a0b3e79f02ed0a610d935de5302 + version: bfd5150e4e41705ded2129ec33379de1cb90b513 - name: github.com/spf13/afero version: 9be650865eab0c12963d8753212f4f9c66cdcf12 subpackages: - mem - name: github.com/spf13/cast - version: f820543c3592e283e311a60d2a600a664e39f6f7 + version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4 - name: github.com/spf13/cobra version: fcd0c5a1df88f5d6784cb4feead962c3f3d0b66c - name: github.com/spf13/jwalterweatherman @@ -63,55 +75,64 @@ imports: - name: github.com/spf13/pflag version: 9ff6c6923cfffbcd502984b8e0c80539a94968b7 - name: github.com/spf13/viper - version: 7538d73b4eb9511d85a9f1dfef202eeb8ac260f4 + version: 5d46e70da8c0b6f812e0b170b7a985753b5c63cb - name: github.com/tendermint/ed25519 version: 1f52c6f8b8a5c7908aff4497c186af344b428925 subpackages: - edwards25519 - extra25519 -- name: github.com/tendermint/go-common - version: 339e135776142939d82bc8e699db0bf391fd938d -- name: github.com/tendermint/go-crypto - version: 562b4cc9ef0d20217f6e95679f9e83cb7bc98b17 - name: github.com/tendermint/go-data - version: 32271140e8fd5abdbb22e268d7a02421fa382f0b + version: e7fcc6d081ec8518912fcdc103188275f83a3ee5 subpackages: - base58 -- name: github.com/tendermint/go-logger - version: cefb3a45c0bf3c493a04e9bcd9b1540528be59f2 - name: github.com/tendermint/go-wire - version: 3216ec9d47bbdf8d4fc27d22169ea86a6688bc15 + version: 9127836cbb6dd99e020cb840a0cedcedc4671468 + subpackages: + - data + - data/base58 - name: github.com/tendermint/log15 version: ae0f3d6450da9eac7074b439c8e1c3cabf0d5ce6 subpackages: - term +- name: github.com/tendermint/tmlibs + version: 2f8551d3b614dd0c0c6c114c42ab25901cc41a52 + subpackages: + - common + - logger - name: golang.org/x/crypto - version: 453249f01cfeb54c3d549ddb75ff152ca243f9d8 + version: 728b753d0135da6801d45a38e6f43ff55779c5c2 subpackages: + - bcrypt + - blowfish - nacl/secretbox - openpgp/armor - openpgp/errors + - pbkdf2 - poly1305 - ripemd160 - salsa20/salsa - name: golang.org/x/sys - version: e24f485414aeafb646f6fca458b0bf869c0880a1 + version: 99f16d856c9836c42d24e7ab64ea72916925fa97 subpackages: - unix - name: golang.org/x/text - version: d680ca3ed853995402af43b866311167281bdc20 + version: f4b4367115ec2de254587813edaa901bc1c723a8 subpackages: - transform - unicode/norm - name: gopkg.in/go-playground/validator.v9 version: 4bd19358521c53f09639f21e2a9d6883d6890f24 - name: gopkg.in/yaml.v2 - version: a3f3340b5840cee44f372bddb5880fcbc419b46a + version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b testImports: +- name: github.com/cmars/basen + version: fe3947df716ebfda9847eb1b9a48f9592e06478c - name: github.com/davecgh/go-spew version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 subpackages: - spew +- name: github.com/mndrix/btcutil + version: d3a63a5752ecf3fbc06bd97365da752111c263df - name: github.com/pmezard/go-difflib version: d8ed2627bdf02c080bf22230dbb337003b7aba2d subpackages: @@ -121,3 +142,7 @@ testImports: subpackages: - assert - require +- name: github.com/tyler-smith/go-bip32 + version: eb790af526c30f23a7c8b00a48e342f9d0bd6386 +- name: github.com/tyler-smith/go-bip39 + version: 8e7a99b3e716f36d3b080a9a70f9eb45abe4edcc diff --git a/glide.yaml b/glide.yaml index d5e0e2bbf..2566feef9 100644 --- a/glide.yaml +++ b/glide.yaml @@ -13,12 +13,22 @@ import: version: unstable - package: github.com/tendermint/go-wire version: unstable + subpackages: + - data + - data/base58 - package: golang.org/x/crypto subpackages: - blowfish - nacl/secretbox - openpgp/armor - ripemd160 +- package: github.com/bgentry/speakeasy +- package: github.com/gorilla/handlers +- package: github.com/gorilla/mux +- package: github.com/pkg/errors +- package: github.com/spf13/cobra +- package: github.com/spf13/viper +- package: gopkg.in/go-playground/validator.v9 testImport: - package: github.com/mndrix/btcutil - package: github.com/stretchr/testify diff --git a/keys/LICENSE b/keys/LICENSE deleted file mode 100644 index d64569567..000000000 --- a/keys/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/keys/glide.yaml b/keys/glide.yaml deleted file mode 100644 index 39402fa8b..000000000 --- a/keys/glide.yaml +++ /dev/null @@ -1,19 +0,0 @@ -package: github.com/tendermint/go-keys -import: -- package: github.com/bgentry/speakeasy -- package: github.com/gorilla/handlers -- package: github.com/gorilla/mux -- package: github.com/pkg/errors -- package: github.com/spf13/cobra -- package: github.com/spf13/viper -- package: github.com/tendermint/go-crypto - version: develop -- package: github.com/tendermint/go-data - subpackages: - - base58 -- package: gopkg.in/go-playground/validator.v9 -testImport: -- package: github.com/stretchr/testify - subpackages: - - assert - - require From 91bd7efb7bcc2eecda2715286a08b8dddf5f3f64 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 19 Apr 2017 17:14:19 +0200 Subject: [PATCH 065/287] Fixed all imports in keys --- keys/cryptostore/enc_storage.go | 4 ++-- keys/cryptostore/encoder.go | 2 +- keys/cryptostore/encoder_test.go | 2 +- keys/cryptostore/generator.go | 4 ++-- keys/server/helpers.go | 2 +- keys/storage/filestorage/main.go | 2 +- keys/storage/filestorage/main_test.go | 2 +- keys/storage/memstorage/main_test.go | 2 +- keys/transactions.go | 4 ++-- keys/tx/multi.go | 10 +++++----- keys/tx/one.go | 7 +++---- keys/tx/reader.go | 6 +++--- keys/tx/reader_test.go | 2 +- 13 files changed, 24 insertions(+), 25 deletions(-) diff --git a/keys/cryptostore/enc_storage.go b/keys/cryptostore/enc_storage.go index 70e212138..daeb220b5 100644 --- a/keys/cryptostore/enc_storage.go +++ b/keys/cryptostore/enc_storage.go @@ -24,7 +24,7 @@ func (es encryptedStorage) Put(name, pass string, key crypto.PrivKey) error { func (es encryptedStorage) Get(name, pass string) (crypto.PrivKey, keys.Info, error) { secret, info, err := es.store.Get(name) if err != nil { - return nil, info, err + return crypto.PrivKey{}, info, err } key, err := es.coder.Decrypt(secret, pass) return key, info, err @@ -44,6 +44,6 @@ func info(name string, key crypto.PrivKey) keys.Info { return keys.Info{ Name: name, Address: pub.Address(), - PubKey: crypto.PubKeyS{pub}, + PubKey: pub, } } diff --git a/keys/cryptostore/encoder.go b/keys/cryptostore/encoder.go index 03bc1e4e8..12792813c 100644 --- a/keys/cryptostore/encoder.go +++ b/keys/cryptostore/encoder.go @@ -37,7 +37,7 @@ func (e secretbox) Decrypt(data []byte, pass string) (crypto.PrivKey, error) { s := secret(pass) private, err := crypto.DecryptSymmetric(data, s) if err != nil { - return nil, errors.Wrap(err, "Invalid Passphrase") + return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") } key, err := crypto.PrivKeyFromBytes(private) return key, errors.Wrap(err, "Invalid Passphrase") diff --git a/keys/cryptostore/encoder_test.go b/keys/cryptostore/encoder_test.go index 0535737d7..e5ea21111 100644 --- a/keys/cryptostore/encoder_test.go +++ b/keys/cryptostore/encoder_test.go @@ -50,7 +50,7 @@ func TestSecretBox(t *testing.T) { // decoding with a different pass is an error pk, err := enc.Decrypt(b, "decode") require.NotNil(err) - require.Nil(pk) + require.True(pk.Empty()) // but decoding with the same passphrase gets us our key pk, err = enc.Decrypt(b, pass) diff --git a/keys/cryptostore/generator.go b/keys/cryptostore/generator.go index cf877f20b..6bbdb6441 100644 --- a/keys/cryptostore/generator.go +++ b/keys/cryptostore/generator.go @@ -25,11 +25,11 @@ func (f GenFunc) Generate() crypto.PrivKey { } func genEd25519() crypto.PrivKey { - return crypto.GenPrivKeyEd25519() + return crypto.GenPrivKeyEd25519().Wrap() } func genSecp256() crypto.PrivKey { - return crypto.GenPrivKeySecp256k1() + return crypto.GenPrivKeySecp256k1().Wrap() } func getGenerator(algo string) (Generator, error) { diff --git a/keys/server/helpers.go b/keys/server/helpers.go index 954922060..710e4f392 100644 --- a/keys/server/helpers.go +++ b/keys/server/helpers.go @@ -12,7 +12,7 @@ import ( "io/ioutil" "net/http" - data "github.com/tendermint/go-data" + data "github.com/tendermint/go-wire/data" "github.com/tendermint/go-crypto/keys/server/types" "github.com/pkg/errors" diff --git a/keys/storage/filestorage/main.go b/keys/storage/filestorage/main.go index 1add482e2..696b200fc 100644 --- a/keys/storage/filestorage/main.go +++ b/keys/storage/filestorage/main.go @@ -135,7 +135,7 @@ func readInfo(path string) (info keys.Info, err error) { return } pk, err := crypto.PubKeyFromBytes(data) - info.PubKey = crypto.PubKeyS{pk} + info.PubKey = pk return } diff --git a/keys/storage/filestorage/main_test.go b/keys/storage/filestorage/main_test.go index c569eb6f9..28c950c2c 100644 --- a/keys/storage/filestorage/main_test.go +++ b/keys/storage/filestorage/main_test.go @@ -25,7 +25,7 @@ func TestBasicCRUD(t *testing.T) { pubkey := crypto.GenPrivKeyEd25519().PubKey() info := keys.Info{ Name: name, - PubKey: crypto.PubKeyS{pubkey}, + PubKey: pubkey.Wrap(), } // No data: Get and Delete return nothing diff --git a/keys/storage/memstorage/main_test.go b/keys/storage/memstorage/main_test.go index 8bc7e355f..feccb387f 100644 --- a/keys/storage/memstorage/main_test.go +++ b/keys/storage/memstorage/main_test.go @@ -17,7 +17,7 @@ func TestBasicCRUD(t *testing.T) { pubkey := crypto.GenPrivKeyEd25519().PubKey() info := keys.Info{ Name: name, - PubKey: crypto.PubKeyS{pubkey}, + PubKey: pubkey, } // No data: Get and Delete return nothing diff --git a/keys/transactions.go b/keys/transactions.go index 91dc0e273..aafb77873 100644 --- a/keys/transactions.go +++ b/keys/transactions.go @@ -4,14 +4,14 @@ import ( "sort" crypto "github.com/tendermint/go-crypto" - data "github.com/tendermint/go-data" + data "github.com/tendermint/go-wire/data" ) // Info is the public information about a key type Info struct { Name string `json:"name"` Address data.Bytes `json:"address"` - PubKey crypto.PubKeyS `json:"pubkey"` + PubKey crypto.PubKey `json:"pubkey"` } func (i *Info) Format() Info { diff --git a/keys/tx/multi.go b/keys/tx/multi.go index eac86b010..f069fb273 100644 --- a/keys/tx/multi.go +++ b/keys/tx/multi.go @@ -3,7 +3,7 @@ package tx import ( "github.com/pkg/errors" crypto "github.com/tendermint/go-crypto" - data "github.com/tendermint/go-data" + data "github.com/tendermint/go-wire/data" ) // MultiSig lets us wrap arbitrary data with a go-crypto signature @@ -16,8 +16,8 @@ type MultiSig struct { } type Signed struct { - Sig crypto.SignatureS - Pubkey crypto.PubKeyS + Sig crypto.Signature + Pubkey crypto.PubKey } var _ SigInner = &MultiSig{} @@ -36,12 +36,12 @@ func (s *MultiSig) SignBytes() []byte { // Depending on the Signable, one may be able to call this multiple times for multisig // Returns error if called with invalid data or too many times func (s *MultiSig) Sign(pubkey crypto.PubKey, sig crypto.Signature) error { - if pubkey == nil || sig == nil { + if pubkey.Empty() || sig.Empty() { return errors.New("Signature or Key missing") } // set the value once we are happy - x := Signed{crypto.SignatureS{sig}, crypto.PubKeyS{pubkey}} + x := Signed{sig, pubkey} s.Sigs = append(s.Sigs, x) return nil } diff --git a/keys/tx/one.go b/keys/tx/one.go index 0ad61dd50..af468cc2c 100644 --- a/keys/tx/one.go +++ b/keys/tx/one.go @@ -3,7 +3,7 @@ package tx import ( "github.com/pkg/errors" crypto "github.com/tendermint/go-crypto" - data "github.com/tendermint/go-data" + data "github.com/tendermint/go-wire/data" ) // OneSig lets us wrap arbitrary data with a go-crypto signature @@ -31,7 +31,7 @@ func (s *OneSig) SignBytes() []byte { // Depending on the Signable, one may be able to call this multiple times for multisig // Returns error if called with invalid data or too many times func (s *OneSig) Sign(pubkey crypto.PubKey, sig crypto.Signature) error { - if pubkey == nil || sig == nil { + if pubkey.Empty() || sig.Empty() { return errors.New("Signature or Key missing") } if !s.Sig.Empty() { @@ -39,8 +39,7 @@ func (s *OneSig) Sign(pubkey crypto.PubKey, sig crypto.Signature) error { } // set the value once we are happy - s.Pubkey = crypto.PubKeyS{pubkey} - s.Sig = crypto.SignatureS{sig} + s.Signed = Signed{sig, pubkey} return nil } diff --git a/keys/tx/reader.go b/keys/tx/reader.go index 16a403719..265e88b46 100644 --- a/keys/tx/reader.go +++ b/keys/tx/reader.go @@ -2,8 +2,8 @@ package tx import ( crypto "github.com/tendermint/go-crypto" - data "github.com/tendermint/go-data" keys "github.com/tendermint/go-crypto/keys" + data "github.com/tendermint/go-wire/data" ) const ( @@ -18,8 +18,8 @@ var TxMapper data.Mapper func init() { TxMapper = data.NewMapper(Sig{}). - RegisterInterface(&OneSig{}, nameOneSig, typeOneSig). - RegisterInterface(&MultiSig{}, nameMultiSig, typeMultiSig) + RegisterImplementation(&OneSig{}, nameOneSig, typeOneSig). + RegisterImplementation(&MultiSig{}, nameMultiSig, typeMultiSig) } /* diff --git a/keys/tx/reader_test.go b/keys/tx/reader_test.go index 4b365604d..c50481f14 100644 --- a/keys/tx/reader_test.go +++ b/keys/tx/reader_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" crypto "github.com/tendermint/go-crypto" - data "github.com/tendermint/go-data" + data "github.com/tendermint/go-wire/data" "github.com/tendermint/go-crypto/keys/cryptostore" "github.com/tendermint/go-crypto/keys/storage/memstorage" ) From e3f9b8731bb2e8cb38f2d49dee92713e95f264bb Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 21 Apr 2017 14:31:49 -0400 Subject: [PATCH 066/287] circle.yml --- circle.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 circle.yml diff --git a/circle.yml b/circle.yml new file mode 100644 index 000000000..23ac4bd9f --- /dev/null +++ b/circle.yml @@ -0,0 +1,21 @@ +machine: + environment: + GOPATH: /home/ubuntu/.go_workspace + PROJECT_PARENT_PATH: "$GOPATH/src/github.com/$CIRCLE_PROJECT_USERNAME" + PROJECT_PATH: $GOPATH/src/github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME + GO15VENDOREXPERIMENT: 1 + hosts: + circlehost: 127.0.0.1 + localhost: 127.0.0.1 + +dependencies: + override: + - mkdir -p "$PROJECT_PARENT_PATH" + - ln -sf "$HOME/$CIRCLE_PROJECT_REPONAME/" "$PROJECT_PATH" + post: + - go version + +test: + override: + - "go version" + - "cd $PROJECT_PATH && make get_vendor_deps && make test" From 9b95da8fa4187f6799558d89b271dc8ab6485615 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 21 Apr 2017 16:10:06 -0400 Subject: [PATCH 067/287] go-data -> go-wire/data --- cmd/common.go | 2 +- glide.lock | 20 ++++++++------------ glide.yaml | 4 ++-- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/cmd/common.go b/cmd/common.go index c68cd4304..098bb6c7d 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -8,8 +8,8 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/tendermint/go-data/base58" data "github.com/tendermint/go-wire/data" + "github.com/tendermint/go-wire/data/base58" ) /******* diff --git a/glide.lock b/glide.lock index b804b4801..dd8ec1952 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 8a63c035134ec024df64d8cc43a732712e48e4cfc5de30d45c1b692b3e9a75b8 -updated: 2017-04-19T17:06:49.640329917+02:00 +hash: 3bcee9fbccf29d21217b24b6a83ec51e1514f37b2ae5d8718cf6c5df80f4fb2c +updated: 2017-04-21T16:09:28.762932633-04:00 imports: - name: github.com/bgentry/speakeasy version: 675b82c74c0ed12283ee81ba8a534c8982c07b85 @@ -51,9 +51,9 @@ imports: - name: github.com/magiconair/properties version: 51463bfca2576e06c62a8504b5c0f06d61312647 - name: github.com/mattn/go-colorable - version: a392f450ea64cee2b268dfaacdc2502b50a22b18 + version: d228849504861217f796da67fae4f6e347643f15 - name: github.com/mattn/go-isatty - version: 57fdcb988a5c543893cc61bce354a6e24ab70022 + version: 30a891c33c7cde7b02a981314b4228ec99380cca - name: github.com/mitchellh/mapstructure version: 53818660ed4955e899c0bcafa97299a388bd7c8e - name: github.com/pelletier/go-buffruneio @@ -81,12 +81,8 @@ imports: subpackages: - edwards25519 - extra25519 -- name: github.com/tendermint/go-data - version: e7fcc6d081ec8518912fcdc103188275f83a3ee5 - subpackages: - - base58 - name: github.com/tendermint/go-wire - version: 9127836cbb6dd99e020cb840a0cedcedc4671468 + version: 334005c236d19c632fb5f073f9de3b0fab6a522b subpackages: - data - data/base58 @@ -95,12 +91,12 @@ imports: subpackages: - term - name: github.com/tendermint/tmlibs - version: 2f8551d3b614dd0c0c6c114c42ab25901cc41a52 + version: 1ea866fd691ded9c1de16408934927d133550efc subpackages: - common - logger - name: golang.org/x/crypto - version: 728b753d0135da6801d45a38e6f43ff55779c5c2 + version: 7c6cc321c680f03b9ef0764448e780704f486b51 subpackages: - bcrypt - blowfish @@ -112,7 +108,7 @@ imports: - ripemd160 - salsa20/salsa - name: golang.org/x/sys - version: 99f16d856c9836c42d24e7ab64ea72916925fa97 + version: d75a52659825e75fff6158388dddc6a5b04f9ba5 subpackages: - unix - name: golang.org/x/text diff --git a/glide.yaml b/glide.yaml index 2566feef9..58e3aecca 100644 --- a/glide.yaml +++ b/glide.yaml @@ -10,9 +10,9 @@ import: subpackages: - extra25519 - package: github.com/tendermint/tmlibs - version: unstable + version: develop - package: github.com/tendermint/go-wire - version: unstable + version: develop subpackages: - data - data/base58 From 197a2b270fd94ee03824b158e738fce62862d0b8 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 27 Apr 2017 20:59:48 +0200 Subject: [PATCH 068/287] Consolidate keys.Manager interface --- keys/transactions.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/keys/transactions.go b/keys/transactions.go index aafb77873..13d37feb5 100644 --- a/keys/transactions.go +++ b/keys/transactions.go @@ -9,8 +9,8 @@ import ( // Info is the public information about a key type Info struct { - Name string `json:"name"` - Address data.Bytes `json:"address"` + Name string `json:"name"` + Address data.Bytes `json:"address"` PubKey crypto.PubKey `json:"pubkey"` } @@ -62,6 +62,7 @@ type Signer interface { // Manager allows simple CRUD on a keystore, as an aid to signing type Manager interface { + Signer Create(name, passphrase, algo string) (Info, error) List() (Infos, error) Get(name string) (Info, error) From 524ba917a3a1636f21ab2c0bf76b6526903ab879 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 2 May 2017 17:18:08 +0200 Subject: [PATCH 069/287] Use new PrepareMainCmd from tmlibs/cli --- cmd/keys/main.go | 3 ++- glide.lock | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/keys/main.go b/cmd/keys/main.go index 8dd8d6505..0b0d93dec 100644 --- a/cmd/keys/main.go +++ b/cmd/keys/main.go @@ -18,10 +18,11 @@ import ( "os" "github.com/tendermint/go-crypto/cmd" + "github.com/tendermint/tmlibs/cli" ) func main() { - cmd.PrepareMainCmd(cmd.RootCmd, "TM", os.ExpandEnv("$HOME/.tlc")) + cli.PrepareMainCmd(cmd.RootCmd, "TM", os.ExpandEnv("$HOME/.tlc")) cmd.RootCmd.Execute() // exec() } diff --git a/glide.lock b/glide.lock index dd8ec1952..485e75c76 100644 --- a/glide.lock +++ b/glide.lock @@ -91,10 +91,11 @@ imports: subpackages: - term - name: github.com/tendermint/tmlibs - version: 1ea866fd691ded9c1de16408934927d133550efc + version: d4ab9679d71c8fc174284696d15930cb799fa24f subpackages: - common - logger + - cli - name: golang.org/x/crypto version: 7c6cc321c680f03b9ef0764448e780704f486b51 subpackages: From e71bbb2509b586f0b24f120b6ba57f32aefa1579 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Fri, 5 May 2017 19:25:44 +0200 Subject: [PATCH 070/287] Update to make full use of new tmlibs/cli helpers --- cmd/common.go | 120 ----------------------------------------------- cmd/get.go | 15 +++--- cmd/keys/main.go | 5 +- cmd/list.go | 16 ++----- cmd/new.go | 20 ++++---- cmd/root.go | 3 +- cmd/update.go | 21 ++++----- cmd/utils.go | 5 +- glide.lock | 39 ++++++++------- 9 files changed, 55 insertions(+), 189 deletions(-) delete mode 100644 cmd/common.go diff --git a/cmd/common.go b/cmd/common.go deleted file mode 100644 index 098bb6c7d..000000000 --- a/cmd/common.go +++ /dev/null @@ -1,120 +0,0 @@ -package cmd - -import ( - "fmt" - "os" - "strings" - - "github.com/pkg/errors" - "github.com/spf13/cobra" - "github.com/spf13/viper" - data "github.com/tendermint/go-wire/data" - "github.com/tendermint/go-wire/data/base58" -) - -/******* - -TODO - -This file should move into go-common or the like as a basis for all cli tools. -It is here for experimentation of re-use between go-keys and light-client. - -*********/ - -const ( - RootFlag = "root" - OutputFlag = "output" - EncodingFlag = "encoding" -) - -func PrepareMainCmd(cmd *cobra.Command, envPrefix, defautRoot string) func() { - cobra.OnInitialize(func() { initEnv(envPrefix) }) - cmd.PersistentFlags().StringP(RootFlag, "r", defautRoot, "root directory for config and data") - cmd.PersistentFlags().StringP(EncodingFlag, "e", "hex", "Binary encoding (hex|b64|btc)") - cmd.PersistentFlags().StringP(OutputFlag, "o", "text", "Output format (text|json)") - cmd.PersistentPreRunE = multiE(bindFlags, setEncoding, validateOutput, cmd.PersistentPreRunE) - return func() { execute(cmd) } -} - -// initEnv sets to use ENV variables if set. -func initEnv(prefix string) { - // env variables with TM prefix (eg. TM_ROOT) - viper.SetEnvPrefix(prefix) - viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) - viper.AutomaticEnv() -} - -// execute adds all child commands to the root command sets flags appropriately. -// This is called by main.main(). It only needs to happen once to the rootCmd. -func execute(cmd *cobra.Command) { - if err := cmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(-1) - } -} - -type wrapE func(cmd *cobra.Command, args []string) error - -func multiE(fs ...wrapE) wrapE { - return func(cmd *cobra.Command, args []string) error { - for _, f := range fs { - if f != nil { - if err := f(cmd, args); err != nil { - return err - } - } - } - return nil - } -} - -func bindFlags(cmd *cobra.Command, args []string) error { - // cmd.Flags() includes flags from this command and all persistent flags from the parent - if err := viper.BindPFlags(cmd.Flags()); err != nil { - return err - } - - // rootDir is command line flag, env variable, or default $HOME/.tlc - rootDir := viper.GetString("root") - viper.SetConfigName("config") // name of config file (without extension) - viper.AddConfigPath(rootDir) // search root directory - - // If a config file is found, read it in. - if err := viper.ReadInConfig(); err == nil { - // stderr, so if we redirect output to json file, this doesn't appear - // fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) - } else if _, ok := err.(viper.ConfigFileNotFoundError); !ok { - // we ignore not found error, only parse error - // stderr, so if we redirect output to json file, this doesn't appear - fmt.Fprintf(os.Stderr, "%#v", err) - } - return nil -} - -// setEncoding reads the encoding flag -func setEncoding(cmd *cobra.Command, args []string) error { - // validate and set encoding - enc := viper.GetString("encoding") - switch enc { - case "hex": - data.Encoder = data.HexEncoder - case "b64": - data.Encoder = data.B64Encoder - case "btc": - data.Encoder = base58.BTCEncoder - default: - return errors.Errorf("Unsupported encoding: %s", enc) - } - return nil -} - -func validateOutput(cmd *cobra.Command, args []string) error { - // validate output format - output := viper.GetString(OutputFlag) - switch output { - case "text", "json": - default: - return errors.Errorf("Unsupported output format: %s", output) - } - return nil -} diff --git a/cmd/get.go b/cmd/get.go index 9b8718996..6e8c620d0 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -15,7 +15,7 @@ package cmd import ( - "fmt" + "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -25,20 +25,17 @@ var getCmd = &cobra.Command{ Use: "get ", Short: "Get details of one key", Long: `Return public details of one local key.`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { if len(args) != 1 || len(args[0]) == 0 { - fmt.Println("You must provide a name for the key") - return + return errors.New("You must provide a name for the key") } name := args[0] info, err := GetKeyManager().Get(name) - if err != nil { - fmt.Println(err.Error()) - return + if err == nil { + printInfo(info) } - - printInfo(info) + return err }, } diff --git a/cmd/keys/main.go b/cmd/keys/main.go index 0b0d93dec..82b355346 100644 --- a/cmd/keys/main.go +++ b/cmd/keys/main.go @@ -22,7 +22,6 @@ import ( ) func main() { - cli.PrepareMainCmd(cmd.RootCmd, "TM", os.ExpandEnv("$HOME/.tlc")) - cmd.RootCmd.Execute() - // exec() + root := cli.PrepareMainCmd(cmd.RootCmd, "TM", os.ExpandEnv("$HOME/.tlc")) + root.Execute() } diff --git a/cmd/list.go b/cmd/list.go index 875520159..b0419a1e4 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -14,11 +14,7 @@ package cmd -import ( - "fmt" - - "github.com/spf13/cobra" -) +import "github.com/spf13/cobra" // listCmd represents the list command var listCmd = &cobra.Command{ @@ -26,14 +22,12 @@ var listCmd = &cobra.Command{ Short: "List all keys", Long: `Return a list of all public keys stored by this key manager along with their associated name and address.`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { infos, err := GetKeyManager().List() - if err != nil { - fmt.Println(err.Error()) - return + if err == nil { + printInfos(infos) } - - printInfos(infos) + return err }, } diff --git a/cmd/new.go b/cmd/new.go index b59874bb0..033410e6a 100644 --- a/cmd/new.go +++ b/cmd/new.go @@ -15,7 +15,7 @@ package cmd import ( - "fmt" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -28,7 +28,7 @@ var newCmd = &cobra.Command{ Long: `Add a public/private key pair to the key store. The password muts be entered in the terminal and not passed as a command line argument for security.`, - Run: newPassword, + RunE: newPassword, } func init() { @@ -36,25 +36,21 @@ func init() { newCmd.Flags().StringP("type", "t", "ed25519", "Type of key (ed25519|secp256k1)") } -func newPassword(cmd *cobra.Command, args []string) { +func newPassword(cmd *cobra.Command, args []string) error { if len(args) != 1 || len(args[0]) == 0 { - fmt.Println("You must provide a name for the key") - return + return errors.New("You must provide a name for the key") } name := args[0] algo := viper.GetString("type") pass, err := getCheckPassword("Enter a passphrase:", "Repeat the passphrase:") if err != nil { - fmt.Println(err.Error()) - return + return err } info, err := GetKeyManager().Create(name, pass, algo) - if err != nil { - fmt.Println(err.Error()) - return + if err == nil { + printInfo(info) } - - printInfo(info) + return err } diff --git a/cmd/root.go b/cmd/root.go index 401e7ec38..33153d850 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -22,6 +22,7 @@ import ( keys "github.com/tendermint/go-crypto/keys" "github.com/tendermint/go-crypto/keys/cryptostore" "github.com/tendermint/go-crypto/keys/storage/filestorage" + "github.com/tendermint/tmlibs/cli" ) const KeySubdir = "keys" @@ -45,7 +46,7 @@ needs to sign with a private key.`, func GetKeyManager() keys.Manager { if manager == nil { // store the keys directory - rootDir := viper.GetString("root") + rootDir := viper.GetString(cli.HomeFlag) keyDir := filepath.Join(rootDir, KeySubdir) // and construct the key manager manager = cryptostore.New( diff --git a/cmd/update.go b/cmd/update.go index 3835242c5..c046af126 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -17,6 +17,8 @@ package cmd import ( "fmt" + "github.com/pkg/errors" + "github.com/spf13/cobra" ) @@ -25,35 +27,32 @@ var updateCmd = &cobra.Command{ Use: "update ", Short: "Change the password for a private key", Long: `Change the password for a private key.`, - Run: updatePassword, + RunE: updatePassword, } func init() { RootCmd.AddCommand(updateCmd) } -func updatePassword(cmd *cobra.Command, args []string) { +func updatePassword(cmd *cobra.Command, args []string) error { if len(args) != 1 || len(args[0]) == 0 { - fmt.Println("You must provide a name for the key") - return + return errors.New("You must provide a name for the key") } name := args[0] oldpass, err := getPassword("Enter the current passphrase:") if err != nil { - fmt.Println(err.Error()) - return + return err } newpass, err := getCheckPassword("Enter the new passphrase:", "Repeat the new passphrase:") if err != nil { - fmt.Println(err.Error()) - return + return err } err = GetKeyManager().Update(name, oldpass, newpass) if err != nil { - fmt.Println(err.Error()) - } else { - fmt.Println("Password successfully updated!") + return err } + fmt.Println("Password successfully updated!") + return nil } diff --git a/cmd/utils.go b/cmd/utils.go index a75262676..f2faa892b 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -8,6 +8,7 @@ import ( "github.com/spf13/viper" keys "github.com/tendermint/go-crypto/keys" data "github.com/tendermint/go-wire/data" + "github.com/tendermint/tmlibs/cli" ) const PassLength = 10 @@ -40,7 +41,7 @@ func getCheckPassword(prompt, prompt2 string) (string, error) { } func printInfo(info keys.Info) { - switch viper.Get(OutputFlag) { + switch viper.Get(cli.OutputFlag) { case "text": addr, err := data.ToText(info.Address) if err != nil { @@ -61,7 +62,7 @@ func printInfo(info keys.Info) { } func printInfos(infos keys.Infos) { - switch viper.Get(OutputFlag) { + switch viper.Get(cli.OutputFlag) { case "text": fmt.Println("All keys:") for _, i := range infos { diff --git a/glide.lock b/glide.lock index 485e75c76..7b3087993 100644 --- a/glide.lock +++ b/glide.lock @@ -1,10 +1,10 @@ hash: 3bcee9fbccf29d21217b24b6a83ec51e1514f37b2ae5d8718cf6c5df80f4fb2c -updated: 2017-04-21T16:09:28.762932633-04:00 +updated: 2017-05-05T19:07:08.418096598+02:00 imports: - name: github.com/bgentry/speakeasy version: 675b82c74c0ed12283ee81ba8a534c8982c07b85 - name: github.com/btcsuite/btcd - version: 583684b21bfbde9b5fc4403916fd7c807feb0289 + version: 4b348c1d33373d672edd83fc576892d0e46686d2 subpackages: - btcec - chaincfg @@ -28,7 +28,7 @@ imports: - name: github.com/go-playground/universal-translator version: b32fa301c9fe55953584134cb6853a13c87ec0a1 - name: github.com/go-stack/stack - version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82 + version: 7a2f19628aabfe68f0766b59e74d6315f8347d22 - name: github.com/gorilla/context version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42 - name: github.com/gorilla/handlers @@ -36,7 +36,7 @@ imports: - name: github.com/gorilla/mux version: 392c28fe23e1c45ddba891b0320b3b5df220beea - name: github.com/hashicorp/hcl - version: 630949a3c5fa3c613328e1b8256052cbc2327c9b + version: a4b07c25de5ff55ad3b8936cea69a79a3d95a855 subpackages: - hcl/ast - hcl/parser @@ -51,17 +51,17 @@ imports: - name: github.com/magiconair/properties version: 51463bfca2576e06c62a8504b5c0f06d61312647 - name: github.com/mattn/go-colorable - version: d228849504861217f796da67fae4f6e347643f15 + version: ded68f7a9561c023e790de24279db7ebf473ea80 - name: github.com/mattn/go-isatty - version: 30a891c33c7cde7b02a981314b4228ec99380cca + version: fc9e8d8ef48496124e79ae0df75490096eccf6fe - name: github.com/mitchellh/mapstructure - version: 53818660ed4955e899c0bcafa97299a388bd7c8e + version: cc8532a8e9a55ea36402aa21efdf403a60d34096 - name: github.com/pelletier/go-buffruneio version: c37440a7cf42ac63b919c752ca73a85067e05992 - name: github.com/pelletier/go-toml - version: 13d49d4606eb801b8f01ae542b4afc4c6ee3d84a + version: 97253b98df84f9eef872866d079e74b8265150f1 - name: github.com/pkg/errors - version: bfd5150e4e41705ded2129ec33379de1cb90b513 + version: c605e284fe17294bda444b34710735b29d1a9d90 - name: github.com/spf13/afero version: 9be650865eab0c12963d8753212f4f9c66cdcf12 subpackages: @@ -69,35 +69,34 @@ imports: - name: github.com/spf13/cast version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4 - name: github.com/spf13/cobra - version: fcd0c5a1df88f5d6784cb4feead962c3f3d0b66c + version: 8f0203be891287870100e4af46262cdf4a4261d1 - name: github.com/spf13/jwalterweatherman version: fa7ca7e836cf3a8bb4ebf799f472c12d7e903d66 - name: github.com/spf13/pflag - version: 9ff6c6923cfffbcd502984b8e0c80539a94968b7 + version: c990990ab4981d84da820b7b00c85139ca150b5f - name: github.com/spf13/viper - version: 5d46e70da8c0b6f812e0b170b7a985753b5c63cb + version: 0967fc9aceab2ce9da34061253ac10fb99bba5b2 - name: github.com/tendermint/ed25519 version: 1f52c6f8b8a5c7908aff4497c186af344b428925 subpackages: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: 334005c236d19c632fb5f073f9de3b0fab6a522b + version: b53add0b622662731985485f3a19be7f684660b8 subpackages: - data - data/base58 - name: github.com/tendermint/log15 - version: ae0f3d6450da9eac7074b439c8e1c3cabf0d5ce6 + version: f91285dece9f4875421b481da3e613d83d44f29b subpackages: - term - name: github.com/tendermint/tmlibs - version: d4ab9679d71c8fc174284696d15930cb799fa24f + version: 706b9fbd671d5d49ecf1b2ea3bb34e51d61ff091 subpackages: - - common - - logger - cli + - common - name: golang.org/x/crypto - version: 7c6cc321c680f03b9ef0764448e780704f486b51 + version: 5a033cc77e57eca05bdb50522851d29e03569cbe subpackages: - bcrypt - blowfish @@ -109,11 +108,11 @@ imports: - ripemd160 - salsa20/salsa - name: golang.org/x/sys - version: d75a52659825e75fff6158388dddc6a5b04f9ba5 + version: 9ccfe848b9db8435a24c424abbc07a921adf1df5 subpackages: - unix - name: golang.org/x/text - version: f4b4367115ec2de254587813edaa901bc1c723a8 + version: 470f45bf29f4147d6fbd7dfd0a02a848e49f5bf4 subpackages: - transform - unicode/norm From d901fba6628e15b83d564753b3bd3cf2c5438686 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 15 May 2017 09:40:00 -0400 Subject: [PATCH 071/287] add changelog and version --- CHANGELOG.md | 27 +++++++++++++++++++++++++++ version.go | 3 +++ 2 files changed, 30 insertions(+) create mode 100644 CHANGELOG.md create mode 100644 version.go diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..72c4bf2cd --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,27 @@ +# Changelog + +## 0.2.0 (May 15, 2017) + +BREAKING CHANGES: + +- [hd] The following functions no longer take a `coin string` as argument: `ComputeAddress`, `AddrFromPubKeyBytes`, `ComputeAddressForPrivKey`, `ComputeWIF`, `WIFFromPrivKeyBytes` +- Changes to `PrivKey`, `PubKey`, and `Signature` (denoted `Xxx` below): + - interfaces are renamed `XxxInner`, and are not for use outside the package, though they must be exposed for sake of serialization. + - `Xxx` is now a struct that wraps the corresponding `XxxInner` interface + +FEATURES: + +- `github.com/tendermint/go-keys -> github.com/tendermint/go-crypto/keys` - command and lib for generating and managing encrypted keys +- [hd] New function `WIFFromPrivKeyBytes(privKeyBytes []byte, compress bool) string` +- Changes to `PrivKey`, `PubKey`, and `Signature` (denoted `Xxx` below): + - Expose a new method `Unwrap() XxxInner` on the `Xxx` struct which returns the corresponding `XxxInner` interface + - Expose a new method `Wrap() Xxx` on the `XxxInner` interface which returns the corresponding `Xxx` struct + +IMPROVEMENTS: + +- Update to use new `tmlibs` repository + +## 0.1.0 (April 14, 2017) + +Initial release + diff --git a/version.go b/version.go new file mode 100644 index 000000000..e2c9c787b --- /dev/null +++ b/version.go @@ -0,0 +1,3 @@ +package crypto + +const Version = "0.2.0" From a42b10e0feb465eb56fbc6bb5b71d57ef646ec57 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 15 May 2017 09:41:07 -0400 Subject: [PATCH 072/287] update glide --- glide.lock | 62 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/glide.lock b/glide.lock index 7b3087993..1f026ceb9 100644 --- a/glide.lock +++ b/glide.lock @@ -1,34 +1,42 @@ hash: 3bcee9fbccf29d21217b24b6a83ec51e1514f37b2ae5d8718cf6c5df80f4fb2c -updated: 2017-05-05T19:07:08.418096598+02:00 +updated: 2017-05-15T09:40:53.073691731-04:00 imports: - name: github.com/bgentry/speakeasy - version: 675b82c74c0ed12283ee81ba8a534c8982c07b85 + version: 4aabc24848ce5fd31929f7d1e4ea74d3709c14cd - name: github.com/btcsuite/btcd - version: 4b348c1d33373d672edd83fc576892d0e46686d2 + version: b8df516b4b267acf2de46be593a9d948d1d2c420 subpackages: - btcec - chaincfg - chaincfg/chainhash - wire - name: github.com/btcsuite/btcutil - version: a5ecb5d9547afe8d1672073dbdc348203de744a0 + version: 66871daeb12123ece012a9628d2798d01195c4b3 subpackages: - base58 - hdkeychain -- name: github.com/btcsuite/golangcrypto - version: 53f62d9b43e87a6c56975cf862af7edf33a8d0df - subpackages: - - ripemd160 +- name: github.com/btcsuite/fastsha256 + version: 637e656429416087660c84436a2a035d69d54e2e +- name: github.com/clipperhouse/typewriter + version: c1a48da378ebb7db1db9f35981b5cc24bf2e5b85 - name: github.com/fsnotify/fsnotify version: 4da3e2cfbabc9f751898f250b49f2439785783a1 +- name: github.com/go-kit/kit + version: d67bb4c202e3b91377d1079b110a6c9ce23ab2f8 + subpackages: + - log + - log/level + - log/term +- name: github.com/go-logfmt/logfmt + version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5 - name: github.com/go-playground/locales - version: 084b0226cf88d891a2bdeccac01d592af13a8f7b + version: 1e5f1161c6416a5ff48840eb8724a394e48cc534 subpackages: - currency - name: github.com/go-playground/universal-translator - version: b32fa301c9fe55953584134cb6853a13c87ec0a1 + version: 71201497bace774495daed26a3874fd339e0b538 - name: github.com/go-stack/stack - version: 7a2f19628aabfe68f0766b59e74d6315f8347d22 + version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82 - name: github.com/gorilla/context version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42 - name: github.com/gorilla/handlers @@ -48,20 +56,18 @@ imports: - json/token - name: github.com/inconshreveable/mousetrap version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 +- name: github.com/kr/logfmt + version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0 - name: github.com/magiconair/properties version: 51463bfca2576e06c62a8504b5c0f06d61312647 -- name: github.com/mattn/go-colorable - version: ded68f7a9561c023e790de24279db7ebf473ea80 -- name: github.com/mattn/go-isatty - version: fc9e8d8ef48496124e79ae0df75490096eccf6fe - name: github.com/mitchellh/mapstructure version: cc8532a8e9a55ea36402aa21efdf403a60d34096 - name: github.com/pelletier/go-buffruneio version: c37440a7cf42ac63b919c752ca73a85067e05992 - name: github.com/pelletier/go-toml - version: 97253b98df84f9eef872866d079e74b8265150f1 + version: 13d49d4606eb801b8f01ae542b4afc4c6ee3d84a - name: github.com/pkg/errors - version: c605e284fe17294bda444b34710735b29d1a9d90 + version: ff09b135c25aae272398c51a07235b90a75aa4f0 - name: github.com/spf13/afero version: 9be650865eab0c12963d8753212f4f9c66cdcf12 subpackages: @@ -69,11 +75,11 @@ imports: - name: github.com/spf13/cast version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4 - name: github.com/spf13/cobra - version: 8f0203be891287870100e4af46262cdf4a4261d1 + version: db6b9a8b3f3f400c8ecb4a4d7d02245b8facad66 - name: github.com/spf13/jwalterweatherman version: fa7ca7e836cf3a8bb4ebf799f472c12d7e903d66 - name: github.com/spf13/pflag - version: c990990ab4981d84da820b7b00c85139ca150b5f + version: 80fe0fb4eba54167e2ccae1c6c950e72abf61b73 - name: github.com/spf13/viper version: 0967fc9aceab2ce9da34061253ac10fb99bba5b2 - name: github.com/tendermint/ed25519 @@ -82,21 +88,18 @@ imports: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: b53add0b622662731985485f3a19be7f684660b8 + version: 59ba5af720a8cbaf5594595e1d8aae23bfd18e31 subpackages: - data - data/base58 -- name: github.com/tendermint/log15 - version: f91285dece9f4875421b481da3e613d83d44f29b - subpackages: - - term - name: github.com/tendermint/tmlibs - version: 706b9fbd671d5d49ecf1b2ea3bb34e51d61ff091 + version: 8f5a175ff4c869fedde710615a11f5745ff69bf3 subpackages: - cli - common + - log - name: golang.org/x/crypto - version: 5a033cc77e57eca05bdb50522851d29e03569cbe + version: c7af5bf2638a1164f2eb5467c39c6cffbd13a02e subpackages: - bcrypt - blowfish @@ -116,8 +119,13 @@ imports: subpackages: - transform - unicode/norm +- name: golang.org/x/tools + version: 144c6642b5d832d6c44a53dad6ee61665dd432ce + subpackages: + - go/ast/astutil + - imports - name: gopkg.in/go-playground/validator.v9 - version: 4bd19358521c53f09639f21e2a9d6883d6890f24 + version: 6d8c18553ea1ac493d049edd6f102f52e618f085 - name: gopkg.in/yaml.v2 version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b testImports: From c38a6f55b375c3f213e8acbd66f399d8a7b8ea70 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 15 May 2017 02:22:58 +0200 Subject: [PATCH 073/287] Prepare for codegen --- _gen.go | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 _gen.go diff --git a/_gen.go b/_gen.go new file mode 100644 index 000000000..36e39887f --- /dev/null +++ b/_gen.go @@ -0,0 +1,7 @@ +package main + +import ( + _ "github.com/tendermint/go-wire/data" + _ "github.com/clipperhouse/stringer" + _ "github.com/clipperhouse/set" +) From f16f71199218d8c0e7e9ef0284c361a51b258afd Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 15 May 2017 02:31:05 +0200 Subject: [PATCH 074/287] First code from codegen... wrong names --- pub_key.go | 47 +++----------------------------- pubkeyinner_holder.go | 62 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 43 deletions(-) create mode 100644 pubkeyinner_holder.go diff --git a/pub_key.go b/pub_key.go index 99839f288..a4da59d2f 100644 --- a/pub_key.go +++ b/pub_key.go @@ -7,9 +7,9 @@ import ( secp256k1 "github.com/btcsuite/btcd/btcec" "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" - . "github.com/tendermint/tmlibs/common" - data "github.com/tendermint/go-wire/data" "github.com/tendermint/go-wire" + data "github.com/tendermint/go-wire/data" + . "github.com/tendermint/tmlibs/common" "golang.org/x/crypto/ripemd160" ) @@ -20,12 +20,10 @@ func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { //---------------------------------------- -type PubKey struct { - PubKeyInner `json:"unwrap"` -} - // DO NOT USE THIS INTERFACE. // You probably want to use PubKey + +// +gen holder:"PubKey,Impl[PubKeyEd25519,PubKeySecp256k1]" type PubKeyInner interface { AssertIsPubKeyInner() Address() []byte @@ -36,35 +34,6 @@ type PubKeyInner interface { Wrap() PubKey } -func (pk PubKey) MarshalJSON() ([]byte, error) { - return pubKeyMapper.ToJSON(pk.PubKeyInner) -} - -func (pk *PubKey) UnmarshalJSON(data []byte) (err error) { - parsed, err := pubKeyMapper.FromJSON(data) - if err == nil && parsed != nil { - pk.PubKeyInner = parsed.(PubKeyInner) - } - return -} - -// Unwrap recovers the concrete interface safely (regardless of levels of embeds) -func (pk PubKey) Unwrap() PubKeyInner { - pkI := pk.PubKeyInner - for wrap, ok := pkI.(PubKey); ok; wrap, ok = pkI.(PubKey) { - pkI = wrap.PubKeyInner - } - return pkI -} - -func (p PubKey) Empty() bool { - return p.PubKeyInner == nil -} - -var pubKeyMapper = data.NewMapper(PubKey{}). - RegisterImplementation(PubKeyEd25519{}, NameEd25519, TypeEd25519). - RegisterImplementation(PubKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) - //------------------------------------- var _ PubKeyInner = PubKeyEd25519{} @@ -142,10 +111,6 @@ func (pubKey PubKeyEd25519) Equals(other PubKey) bool { } } -func (pubKey PubKeyEd25519) Wrap() PubKey { - return PubKey{pubKey} -} - //------------------------------------- var _ PubKeyInner = PubKeySecp256k1{} @@ -218,7 +183,3 @@ func (pubKey PubKeySecp256k1) Equals(other PubKey) bool { return false } } - -func (pubKey PubKeySecp256k1) Wrap() PubKey { - return PubKey{pubKey} -} diff --git a/pubkeyinner_holder.go b/pubkeyinner_holder.go new file mode 100644 index 000000000..16bfcf8a8 --- /dev/null +++ b/pubkeyinner_holder.go @@ -0,0 +1,62 @@ +// Generated by: main +// TypeWriter: holder +// Directive: +gen on PubKeyInner + +package crypto + +import ( + "github.com/tendermint/go-wire/data" +) + +// Auto-generated adapters for happily unmarshaling interfaces +// Apache License 2.0 +// Copyright (c) 2017 Ethan Frey (ethan.frey@tendermint.com) + +type PubKey struct { + PubKeyInner +} + +var PubKeyMapper = data.NewMapper(PubKey{}) + +func (h PubKey) MarshalJSON() ([]byte, error) { + return PubKeyMapper.ToJSON(h.PubKeyInner) +} + +func (h *PubKey) UnmarshalJSON(data []byte) (err error) { + parsed, err := PubKeyMapper.FromJSON(data) + if err == nil && parsed != nil { + h.PubKeyInner = parsed.(PubKeyInner) + } + return err +} + +// Unwrap recovers the concrete interface safely (regardless of levels of embeds) +func (h PubKey) Unwrap() PubKeyInner { + hi := h.PubKeyInner + for wrap, ok := hi.(PubKey); ok; wrap, ok = hi.(PubKey) { + hi = wrap.PubKeyInner + } + return hi +} + +func (h PubKey) Empty() bool { + return h.PubKeyInner == nil +} + +/*** below are bindings for each implementation ***/ + +func init() { + PubKeyMapper.RegisterImplementation(PubKeyEd25519{}, "pubkeyed25519", 0x1) +} + +func (hi PubKeyEd25519) Wrap() PubKey { + return PubKey{hi} +} + +func init() { + PubKeyMapper.RegisterImplementation(PubKeySecp256k1{}, "pubkeysecp256k1", 0x2) +} + +func (hi PubKeySecp256k1) Wrap() PubKey { + return PubKey{hi} +} From ee200d998fb42e23462569745c53c800fbdc6891 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 15 May 2017 02:46:28 +0200 Subject: [PATCH 075/287] Fix unwrap for proper json format --- encode_test.go | 4 ++-- pub_key.go | 3 +-- pubkeyinner_holder.go | 6 +++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/encode_test.go b/encode_test.go index 6c5d03a1d..1b70d88ec 100644 --- a/encode_test.go +++ b/encode_test.go @@ -7,8 +7,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - data "github.com/tendermint/go-wire/data" wire "github.com/tendermint/go-wire" + data "github.com/tendermint/go-wire/data" ) type byter interface { @@ -58,7 +58,7 @@ func checkWireJSON(t *testing.T, in interface{}, reader interface{}, typ byte) { var err error js := wire.JSONBytes(in) btyp := fmt.Sprintf("[%d,", typ) - assert.True(t, strings.HasPrefix(string(js), btyp), string(js)) + assert.True(t, strings.HasPrefix(string(js), btyp), string(js), btyp) wire.ReadJSON(reader, js, &err) require.Nil(t, err, "%+v", err) diff --git a/pub_key.go b/pub_key.go index a4da59d2f..7483ff93a 100644 --- a/pub_key.go +++ b/pub_key.go @@ -22,8 +22,7 @@ func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { // DO NOT USE THIS INTERFACE. // You probably want to use PubKey - -// +gen holder:"PubKey,Impl[PubKeyEd25519,PubKeySecp256k1]" +// +gen holder:"PubKey,Impl[PubKeyEd25519,PubKeySecp256k1],ed25519,secp256k1" type PubKeyInner interface { AssertIsPubKeyInner() Address() []byte diff --git a/pubkeyinner_holder.go b/pubkeyinner_holder.go index 16bfcf8a8..ee0ca9f00 100644 --- a/pubkeyinner_holder.go +++ b/pubkeyinner_holder.go @@ -13,7 +13,7 @@ import ( // Copyright (c) 2017 Ethan Frey (ethan.frey@tendermint.com) type PubKey struct { - PubKeyInner + PubKeyInner "json:\"unwrap\"" } var PubKeyMapper = data.NewMapper(PubKey{}) @@ -46,7 +46,7 @@ func (h PubKey) Empty() bool { /*** below are bindings for each implementation ***/ func init() { - PubKeyMapper.RegisterImplementation(PubKeyEd25519{}, "pubkeyed25519", 0x1) + PubKeyMapper.RegisterImplementation(PubKeyEd25519{}, "ed25519", 0x1) } func (hi PubKeyEd25519) Wrap() PubKey { @@ -54,7 +54,7 @@ func (hi PubKeyEd25519) Wrap() PubKey { } func init() { - PubKeyMapper.RegisterImplementation(PubKeySecp256k1{}, "pubkeysecp256k1", 0x2) + PubKeyMapper.RegisterImplementation(PubKeySecp256k1{}, "secp256k1", 0x2) } func (hi PubKeySecp256k1) Wrap() PubKey { From 746a2e286df37747cc00d60bd326f1c21e8aef02 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 15 May 2017 02:51:52 +0200 Subject: [PATCH 076/287] Codegen wrappers for privkey and signature as well --- priv_key.go | 46 ++--------------------------- privkeyinner_holder.go | 62 ++++++++++++++++++++++++++++++++++++++++ signature.go | 47 +++--------------------------- signatureinner_holder.go | 62 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+), 86 deletions(-) create mode 100644 privkeyinner_holder.go create mode 100644 signatureinner_holder.go diff --git a/priv_key.go b/priv_key.go index 85f8a8ec4..056e50b55 100644 --- a/priv_key.go +++ b/priv_key.go @@ -6,9 +6,9 @@ import ( secp256k1 "github.com/btcsuite/btcd/btcec" "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" - . "github.com/tendermint/tmlibs/common" - data "github.com/tendermint/go-wire/data" "github.com/tendermint/go-wire" + data "github.com/tendermint/go-wire/data" + . "github.com/tendermint/tmlibs/common" ) func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { @@ -18,12 +18,9 @@ func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { //---------------------------------------- -type PrivKey struct { - PrivKeyInner `json:"unwrap"` -} - // DO NOT USE THIS INTERFACE. // You probably want to use PubKey +// +gen holder:"PrivKey,Impl[PrivKeyEd25519,PrivKeySecp256k1],ed25519,secp256k1" type PrivKeyInner interface { AssertIsPrivKeyInner() Bytes() []byte @@ -33,35 +30,6 @@ type PrivKeyInner interface { Wrap() PrivKey } -func (p PrivKey) MarshalJSON() ([]byte, error) { - return privKeyMapper.ToJSON(p.PrivKeyInner) -} - -func (p *PrivKey) UnmarshalJSON(data []byte) (err error) { - parsed, err := privKeyMapper.FromJSON(data) - if err == nil && parsed != nil { - p.PrivKeyInner = parsed.(PrivKeyInner) - } - return -} - -// Unwrap recovers the concrete interface safely (regardless of levels of embeds) -func (p PrivKey) Unwrap() PrivKeyInner { - pk := p.PrivKeyInner - for wrap, ok := pk.(PrivKey); ok; wrap, ok = pk.(PrivKey) { - pk = wrap.PrivKeyInner - } - return pk -} - -func (p PrivKey) Empty() bool { - return p.PrivKeyInner == nil -} - -var privKeyMapper = data.NewMapper(PrivKey{}). - RegisterImplementation(PrivKeyEd25519{}, NameEd25519, TypeEd25519). - RegisterImplementation(PrivKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) - //------------------------------------- var _ PrivKeyInner = PrivKeyEd25519{} @@ -128,10 +96,6 @@ func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519 { return PrivKeyEd25519(newKey) } -func (privKey PrivKeyEd25519) Wrap() PrivKey { - return PrivKey{privKey} -} - func GenPrivKeyEd25519() PrivKeyEd25519 { privKeyBytes := new([64]byte) copy(privKeyBytes[:32], CRandBytes(32)) @@ -201,10 +165,6 @@ func (privKey PrivKeySecp256k1) String() string { return Fmt("PrivKeySecp256k1{*****}") } -func (privKey PrivKeySecp256k1) Wrap() PrivKey { - return PrivKey{privKey} -} - /* // Deterministically generates new priv-key bytes from key. func (key PrivKeySecp256k1) Generate(index int) PrivKeySecp256k1 { diff --git a/privkeyinner_holder.go b/privkeyinner_holder.go new file mode 100644 index 000000000..2621ca560 --- /dev/null +++ b/privkeyinner_holder.go @@ -0,0 +1,62 @@ +// Generated by: main +// TypeWriter: holder +// Directive: +gen on PrivKeyInner + +package crypto + +import ( + "github.com/tendermint/go-wire/data" +) + +// Auto-generated adapters for happily unmarshaling interfaces +// Apache License 2.0 +// Copyright (c) 2017 Ethan Frey (ethan.frey@tendermint.com) + +type PrivKey struct { + PrivKeyInner "json:\"unwrap\"" +} + +var PrivKeyMapper = data.NewMapper(PrivKey{}) + +func (h PrivKey) MarshalJSON() ([]byte, error) { + return PrivKeyMapper.ToJSON(h.PrivKeyInner) +} + +func (h *PrivKey) UnmarshalJSON(data []byte) (err error) { + parsed, err := PrivKeyMapper.FromJSON(data) + if err == nil && parsed != nil { + h.PrivKeyInner = parsed.(PrivKeyInner) + } + return err +} + +// Unwrap recovers the concrete interface safely (regardless of levels of embeds) +func (h PrivKey) Unwrap() PrivKeyInner { + hi := h.PrivKeyInner + for wrap, ok := hi.(PrivKey); ok; wrap, ok = hi.(PrivKey) { + hi = wrap.PrivKeyInner + } + return hi +} + +func (h PrivKey) Empty() bool { + return h.PrivKeyInner == nil +} + +/*** below are bindings for each implementation ***/ + +func init() { + PrivKeyMapper.RegisterImplementation(PrivKeyEd25519{}, "ed25519", 0x1) +} + +func (hi PrivKeyEd25519) Wrap() PrivKey { + return PrivKey{hi} +} + +func init() { + PrivKeyMapper.RegisterImplementation(PrivKeySecp256k1{}, "secp256k1", 0x2) +} + +func (hi PrivKeySecp256k1) Wrap() PrivKey { + return PrivKey{hi} +} diff --git a/signature.go b/signature.go index 36451ed48..12b584d71 100644 --- a/signature.go +++ b/signature.go @@ -4,9 +4,9 @@ import ( "bytes" "fmt" - . "github.com/tendermint/tmlibs/common" - data "github.com/tendermint/go-wire/data" "github.com/tendermint/go-wire" + data "github.com/tendermint/go-wire/data" + . "github.com/tendermint/tmlibs/common" ) func SignatureFromBytes(sigBytes []byte) (sig Signature, err error) { @@ -16,12 +16,9 @@ func SignatureFromBytes(sigBytes []byte) (sig Signature, err error) { //---------------------------------------- -type Signature struct { - SignatureInner `json:"unwrap"` -} - // DO NOT USE THIS INTERFACE. // You probably want to use Signature. +// +gen holder:"Signature,Impl[SignatureEd25519,SignatureSecp256k1],ed25519,secp256k1" type SignatureInner interface { AssertIsSignatureInner() Bytes() []byte @@ -31,35 +28,6 @@ type SignatureInner interface { Wrap() Signature } -func (sig Signature) MarshalJSON() ([]byte, error) { - return sigMapper.ToJSON(sig.SignatureInner) -} - -func (sig *Signature) UnmarshalJSON(data []byte) (err error) { - parsed, err := sigMapper.FromJSON(data) - if err == nil && parsed != nil { - sig.SignatureInner = parsed.(SignatureInner) - } - return -} - -// Unwrap recovers the concrete interface safely (regardless of levels of embeds) -func (sig Signature) Unwrap() SignatureInner { - pk := sig.SignatureInner - for wrap, ok := pk.(Signature); ok; wrap, ok = pk.(Signature) { - pk = wrap.SignatureInner - } - return pk -} - -func (sig Signature) Empty() bool { - return sig.SignatureInner == nil -} - -var sigMapper = data.NewMapper(Signature{}). - RegisterImplementation(SignatureEd25519{}, NameEd25519, TypeEd25519). - RegisterImplementation(SignatureSecp256k1{}, NameSecp256k1, TypeSecp256k1) - //------------------------------------- var _ SignatureInner = SignatureEd25519{} @@ -96,10 +64,6 @@ func (sig *SignatureEd25519) UnmarshalJSON(enc []byte) error { return err } -func (sig SignatureEd25519) Wrap() Signature { - return Signature{sig} -} - //------------------------------------- var _ SignatureInner = SignatureSecp256k1{} @@ -124,6 +88,7 @@ func (sig SignatureSecp256k1) Equals(other Signature) bool { return false } } + func (sig SignatureSecp256k1) MarshalJSON() ([]byte, error) { return data.Encoder.Marshal(sig) } @@ -131,7 +96,3 @@ func (sig SignatureSecp256k1) MarshalJSON() ([]byte, error) { func (sig *SignatureSecp256k1) UnmarshalJSON(enc []byte) error { return data.Encoder.Unmarshal((*[]byte)(sig), enc) } - -func (sig SignatureSecp256k1) Wrap() Signature { - return Signature{sig} -} diff --git a/signatureinner_holder.go b/signatureinner_holder.go new file mode 100644 index 000000000..cbe1fe093 --- /dev/null +++ b/signatureinner_holder.go @@ -0,0 +1,62 @@ +// Generated by: main +// TypeWriter: holder +// Directive: +gen on SignatureInner + +package crypto + +import ( + "github.com/tendermint/go-wire/data" +) + +// Auto-generated adapters for happily unmarshaling interfaces +// Apache License 2.0 +// Copyright (c) 2017 Ethan Frey (ethan.frey@tendermint.com) + +type Signature struct { + SignatureInner "json:\"unwrap\"" +} + +var SignatureMapper = data.NewMapper(Signature{}) + +func (h Signature) MarshalJSON() ([]byte, error) { + return SignatureMapper.ToJSON(h.SignatureInner) +} + +func (h *Signature) UnmarshalJSON(data []byte) (err error) { + parsed, err := SignatureMapper.FromJSON(data) + if err == nil && parsed != nil { + h.SignatureInner = parsed.(SignatureInner) + } + return err +} + +// Unwrap recovers the concrete interface safely (regardless of levels of embeds) +func (h Signature) Unwrap() SignatureInner { + hi := h.SignatureInner + for wrap, ok := hi.(Signature); ok; wrap, ok = hi.(Signature) { + hi = wrap.SignatureInner + } + return hi +} + +func (h Signature) Empty() bool { + return h.SignatureInner == nil +} + +/*** below are bindings for each implementation ***/ + +func init() { + SignatureMapper.RegisterImplementation(SignatureEd25519{}, "ed25519", 0x1) +} + +func (hi SignatureEd25519) Wrap() Signature { + return Signature{hi} +} + +func init() { + SignatureMapper.RegisterImplementation(SignatureSecp256k1{}, "secp256k1", 0x2) +} + +func (hi SignatureSecp256k1) Wrap() Signature { + return Signature{hi} +} From 79c580492e6b8658605c8ceea5f6bc52739d0339 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 15 May 2017 15:56:08 +0200 Subject: [PATCH 077/287] add make codegen for gen --- Makefile | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 59440fe66..d453f7ad1 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONEY: all docs test install get_vendor_deps ensure_tools +.PHONEY: all docs test install get_vendor_deps ensure_tools codegen GOTOOLS = \ github.com/Masterminds/glide @@ -24,4 +24,12 @@ get_vendor_deps: ensure_tools ensure_tools: go get $(GOTOOLS) +prepgen: install + cd ../go-wire && make tools + go install ./vendor/github.com/btcsuite/btcutil/base58 + go install ./vendor/github.com/stretchr/testify/assert + go install ./vendor/github.com/stretchr/testify/require + go install ./vendor/golang.org/x/crypto/bcrypt +codegen: prepgen + gen From bee63ce4ff15b8d48a0ee6fa9d902775f86fa1a1 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 15 May 2017 19:13:49 +0200 Subject: [PATCH 078/287] Cleaned up build process, moved codegen to separate package in go-wire --- Makefile | 7 ++++--- _gen.go | 3 +-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index d453f7ad1..ca9703399 100644 --- a/Makefile +++ b/Makefile @@ -25,11 +25,12 @@ ensure_tools: go get $(GOTOOLS) prepgen: install - cd ../go-wire && make tools go install ./vendor/github.com/btcsuite/btcutil/base58 go install ./vendor/github.com/stretchr/testify/assert go install ./vendor/github.com/stretchr/testify/require go install ./vendor/golang.org/x/crypto/bcrypt -codegen: prepgen - gen +codegen: + @echo "--> regenerating all interface wrappers" + @gen + @echo "Done!" diff --git a/_gen.go b/_gen.go index 36e39887f..a98feaf4e 100644 --- a/_gen.go +++ b/_gen.go @@ -1,7 +1,6 @@ package main import ( - _ "github.com/tendermint/go-wire/data" + _ "github.com/tendermint/go-wire/gen" _ "github.com/clipperhouse/stringer" - _ "github.com/clipperhouse/set" ) From db5cb8d92c3e993786f406e9fcfebbbd60bd2d87 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 16 May 2017 16:59:40 +0200 Subject: [PATCH 079/287] Change codegen name holder->wrapper --- glide.lock | 2 +- priv_key.go | 2 +- privkeyinner_holder.go => privkeyinner_wrapper.go | 2 +- pub_key.go | 2 +- pubkeyinner_holder.go => pubkeyinner_wrapper.go | 2 +- signature.go | 2 +- signatureinner_holder.go => signatureinner_wrapper.go | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) rename privkeyinner_holder.go => privkeyinner_wrapper.go (98%) rename pubkeyinner_holder.go => pubkeyinner_wrapper.go (98%) rename signatureinner_holder.go => signatureinner_wrapper.go (98%) diff --git a/glide.lock b/glide.lock index 1f026ceb9..82dd5111e 100644 --- a/glide.lock +++ b/glide.lock @@ -88,7 +88,7 @@ imports: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: 59ba5af720a8cbaf5594595e1d8aae23bfd18e31 + version: 97beaedf0f4dbc035309157c92be3b30cc6e5d74 subpackages: - data - data/base58 diff --git a/priv_key.go b/priv_key.go index 056e50b55..0c6bd2ae7 100644 --- a/priv_key.go +++ b/priv_key.go @@ -20,7 +20,7 @@ func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { // DO NOT USE THIS INTERFACE. // You probably want to use PubKey -// +gen holder:"PrivKey,Impl[PrivKeyEd25519,PrivKeySecp256k1],ed25519,secp256k1" +// +gen wrapper:"PrivKey,Impl[PrivKeyEd25519,PrivKeySecp256k1],ed25519,secp256k1" type PrivKeyInner interface { AssertIsPrivKeyInner() Bytes() []byte diff --git a/privkeyinner_holder.go b/privkeyinner_wrapper.go similarity index 98% rename from privkeyinner_holder.go rename to privkeyinner_wrapper.go index 2621ca560..05ce69672 100644 --- a/privkeyinner_holder.go +++ b/privkeyinner_wrapper.go @@ -1,5 +1,5 @@ // Generated by: main -// TypeWriter: holder +// TypeWriter: wrapper // Directive: +gen on PrivKeyInner package crypto diff --git a/pub_key.go b/pub_key.go index 7483ff93a..4d5c31b21 100644 --- a/pub_key.go +++ b/pub_key.go @@ -22,7 +22,7 @@ func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { // DO NOT USE THIS INTERFACE. // You probably want to use PubKey -// +gen holder:"PubKey,Impl[PubKeyEd25519,PubKeySecp256k1],ed25519,secp256k1" +// +gen wrapper:"PubKey,Impl[PubKeyEd25519,PubKeySecp256k1],ed25519,secp256k1" type PubKeyInner interface { AssertIsPubKeyInner() Address() []byte diff --git a/pubkeyinner_holder.go b/pubkeyinner_wrapper.go similarity index 98% rename from pubkeyinner_holder.go rename to pubkeyinner_wrapper.go index ee0ca9f00..7b36c324d 100644 --- a/pubkeyinner_holder.go +++ b/pubkeyinner_wrapper.go @@ -1,5 +1,5 @@ // Generated by: main -// TypeWriter: holder +// TypeWriter: wrapper // Directive: +gen on PubKeyInner package crypto diff --git a/signature.go b/signature.go index 12b584d71..1c5b8d69e 100644 --- a/signature.go +++ b/signature.go @@ -18,7 +18,7 @@ func SignatureFromBytes(sigBytes []byte) (sig Signature, err error) { // DO NOT USE THIS INTERFACE. // You probably want to use Signature. -// +gen holder:"Signature,Impl[SignatureEd25519,SignatureSecp256k1],ed25519,secp256k1" +// +gen wrapper:"Signature,Impl[SignatureEd25519,SignatureSecp256k1],ed25519,secp256k1" type SignatureInner interface { AssertIsSignatureInner() Bytes() []byte diff --git a/signatureinner_holder.go b/signatureinner_wrapper.go similarity index 98% rename from signatureinner_holder.go rename to signatureinner_wrapper.go index cbe1fe093..1fdd790d6 100644 --- a/signatureinner_holder.go +++ b/signatureinner_wrapper.go @@ -1,5 +1,5 @@ // Generated by: main -// TypeWriter: holder +// TypeWriter: wrapper // Directive: +gen on SignatureInner package crypto From c61497b56e43096e47872ec12782d5bf9e20b4f0 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Thu, 18 May 2017 11:35:32 +0200 Subject: [PATCH 080/287] CHANGELOG: update release date --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72c4bf2cd..510785477 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 0.2.0 (May 15, 2017) +## 0.2.0 (May 18, 2017) BREAKING CHANGES: From 0edd1297a9a90b2569c117bbc38a901d468a9efd Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 19 Jun 2017 17:07:12 +0200 Subject: [PATCH 081/287] Got basic key test working --- .gitignore | 1 + Makefile | 17 ++++++++++++++--- tests/keys.sh | 30 ++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100755 tests/keys.sh diff --git a/.gitignore b/.gitignore index f37225baa..d19e6457f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.swp *.swo vendor +shunit2 diff --git a/Makefile b/Makefile index ca9703399..e40d0e6ff 100644 --- a/Makefile +++ b/Makefile @@ -8,13 +8,24 @@ docs: @go get github.com/davecheney/godoc2md godoc2md $(REPO) > README.md -all: install test +all: get_vendor_deps install test install: go install ./cmd/keys -test: +test: test_unit test_cli + +test_unit: go test `glide novendor` + #go run tests/tendermint/*.go + +test_cli: tests/shunit2 + # sudo apt-get install jq + @./tests/keys.sh + +tests/shunit2: + wget "https://raw.githubusercontent.com/kward/shunit2/master/source/2.1/src/shunit2" \ + -q -O tests/shunit2 get_vendor_deps: ensure_tools @rm -rf vendor/ @@ -30,7 +41,7 @@ prepgen: install go install ./vendor/github.com/stretchr/testify/require go install ./vendor/golang.org/x/crypto/bcrypt -codegen: +codegen: @echo "--> regenerating all interface wrappers" @gen @echo "Done!" diff --git a/tests/keys.sh b/tests/keys.sh new file mode 100755 index 000000000..b4bdcdd40 --- /dev/null +++ b/tests/keys.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +EXE=keys + +oneTimeSetUp() { + PASS=qwertyuiop + export TM_HOME=$HOME/.keys_test + rm -rf $TM_HOME + assertTrue $? +} + +newKey(){ + assertNotNull "keyname required" "$1" + KEYPASS=${2:-qwertyuiop} + (echo $KEYPASS; echo $KEYPASS) | ${EXE} new $1 >/dev/null 2>&1 + assertTrue "created $1" $? +} + +testMakeKeys() { + USER=demouser + assertFalse "already user $USER" "${EXE} list | grep $USER" + assertEquals "1" `${EXE} list | wc -l` + newKey $USER + assertTrue "no user $USER" "${EXE} list | grep $USER" + assertEquals "2" `${EXE} list | wc -l` +} + +# load and run these tests with shunit2! +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #get this files directory +. $DIR/shunit2 From 0c32d2722fc32523829029953bf9ade2933f4a7c Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 19 Jun 2017 17:49:16 +0200 Subject: [PATCH 082/287] #17 - better support passwords in tests, more cli tests --- cmd/utils.go | 40 +++++++++++++++++++++++++++++++++++++--- glide.lock | 15 +++++---------- tests/keys.sh | 46 ++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 82 insertions(+), 19 deletions(-) diff --git a/cmd/utils.go b/cmd/utils.go index f2faa892b..d082bbbc9 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -1,20 +1,49 @@ package cmd import ( + "bufio" "fmt" + "os" + "strings" "github.com/bgentry/speakeasy" + "github.com/mattn/go-isatty" "github.com/pkg/errors" "github.com/spf13/viper" - keys "github.com/tendermint/go-crypto/keys" + data "github.com/tendermint/go-wire/data" "github.com/tendermint/tmlibs/cli" + + keys "github.com/tendermint/go-crypto/keys" ) const PassLength = 10 -func getPassword(prompt string) (string, error) { - pass, err := speakeasy.Ask(prompt) +// if we read from non-tty, we just need to init the buffer reader once, +// in case we try to read multiple passwords (eg. update) +var buf *bufio.Reader + +func inputIsTty() bool { + return isatty.IsTerminal(os.Stdin.Fd()) || isatty.IsCygwinTerminal(os.Stdin.Fd()) +} + +func stdinPassword() (string, error) { + if buf == nil { + buf = bufio.NewReader(os.Stdin) + } + pass, err := buf.ReadString('\n') + if err != nil { + return "", err + } + return strings.TrimSpace(pass), nil +} + +func getPassword(prompt string) (pass string, err error) { + if inputIsTty() { + pass, err = speakeasy.Ask(prompt) + } else { + pass, err = stdinPassword() + } if err != nil { return "", err } @@ -25,6 +54,11 @@ func getPassword(prompt string) (string, error) { } func getCheckPassword(prompt, prompt2 string) (string, error) { + // simple read on no-tty + if !inputIsTty() { + return getPassword(prompt) + } + // TODO: own function??? pass, err := getPassword(prompt) if err != nil { diff --git a/glide.lock b/glide.lock index 82dd5111e..71292ce11 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ hash: 3bcee9fbccf29d21217b24b6a83ec51e1514f37b2ae5d8718cf6c5df80f4fb2c -updated: 2017-05-15T09:40:53.073691731-04:00 +updated: 2017-06-19T17:16:58.037568333+02:00 imports: - name: github.com/bgentry/speakeasy version: 4aabc24848ce5fd31929f7d1e4ea74d3709c14cd @@ -17,8 +17,6 @@ imports: - hdkeychain - name: github.com/btcsuite/fastsha256 version: 637e656429416087660c84436a2a035d69d54e2e -- name: github.com/clipperhouse/typewriter - version: c1a48da378ebb7db1db9f35981b5cc24bf2e5b85 - name: github.com/fsnotify/fsnotify version: 4da3e2cfbabc9f751898f250b49f2439785783a1 - name: github.com/go-kit/kit @@ -60,6 +58,8 @@ imports: version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0 - name: github.com/magiconair/properties version: 51463bfca2576e06c62a8504b5c0f06d61312647 +- name: github.com/mattn/go-isatty + version: 9622e0cc9d8f9be434ca605520ff9a16808fee47 - name: github.com/mitchellh/mapstructure version: cc8532a8e9a55ea36402aa21efdf403a60d34096 - name: github.com/pelletier/go-buffruneio @@ -88,12 +88,12 @@ imports: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: 97beaedf0f4dbc035309157c92be3b30cc6e5d74 + version: 5f88da3dbc1a72844e6dfaf274ce87f851d488eb subpackages: - data - data/base58 - name: github.com/tendermint/tmlibs - version: 8f5a175ff4c869fedde710615a11f5745ff69bf3 + version: bd9d0d1637dadf1330e167189d5e5031aadcda6f subpackages: - cli - common @@ -119,11 +119,6 @@ imports: subpackages: - transform - unicode/norm -- name: golang.org/x/tools - version: 144c6642b5d832d6c44a53dad6ee61665dd432ce - subpackages: - - go/ast/astutil - - imports - name: gopkg.in/go-playground/validator.v9 version: 6d8c18553ea1ac493d049edd6f102f52e618f085 - name: gopkg.in/yaml.v2 diff --git a/tests/keys.sh b/tests/keys.sh index b4bdcdd40..82c8083ec 100755 --- a/tests/keys.sh +++ b/tests/keys.sh @@ -12,17 +12,51 @@ oneTimeSetUp() { newKey(){ assertNotNull "keyname required" "$1" KEYPASS=${2:-qwertyuiop} - (echo $KEYPASS; echo $KEYPASS) | ${EXE} new $1 >/dev/null 2>&1 + KEY=$(echo $KEYPASS | ${EXE} new $1) assertTrue "created $1" $? + return $? } -testMakeKeys() { +# updateKey +updateKey() { + (echo $2; echo $3) | keys update $1 > /dev/null + return $? +} + +test00MakeKeys() { USER=demouser - assertFalse "already user $USER" "${EXE} list | grep $USER" - assertEquals "1" `${EXE} list | wc -l` + assertFalse "already user $USER" "${EXE} get $USER" newKey $USER - assertTrue "no user $USER" "${EXE} list | grep $USER" - assertEquals "2" `${EXE} list | wc -l` + assertTrue "no user $USER" "${EXE} get $USER" + # make sure bad password not accepted + assertFalse "accepts short password" "echo 123 | keys new badpass" +} + +test01ListKeys() { + # one line plus the number of keys + assertEquals "2" $(keys list | wc -l) + newKey foobar + assertEquals "3" $(keys list | wc -l) + # we got the proper name here... + assertEquals "foobar" $(keys list -o json | jq .[1].name | tr -d \" ) + # we get all names in normal output + EXPECTEDNAMES=$(echo demouser; echo foobar) + TEXTNAMES=$(keys list | tail -n +2 | cut -f1) + assertEquals "$EXPECTEDNAMES" "$TEXTNAMES" + # let's make sure the addresses match! + assertEquals "text and json addresses don't match" $(keys list | tail -1 | cut -f3) $(keys list -o json | jq .[1].address | tr -d \") +} + +test02updateKeys() { + USER=changer + PASS1=awsedrftgyhu + PASS2=S4H.9j.D9S7hso + PASS3=h8ybO7GY6d2 + + newKey $USER $PASS1 + assertFalse "accepts invalid pass" "updateKey $USER $PASS2 $PASS2" + assertTrue "doesn't update" "updateKey $USER $PASS1 $PASS2" + assertTrue "takes new key after update" "updateKey $USER $PASS2 $PASS3" } # load and run these tests with shunit2! From ea4f45828d2ebf78c485d36de129ed6e8a62b643 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 19 Jun 2017 17:52:45 +0200 Subject: [PATCH 083/287] Update circle ci for new cli tests --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index 23ac4bd9f..a37187dd9 100644 --- a/circle.yml +++ b/circle.yml @@ -18,4 +18,4 @@ dependencies: test: override: - "go version" - - "cd $PROJECT_PATH && make get_vendor_deps && make test" + - "cd $PROJECT_PATH && make all" From 2278f566bf90ea989042ce39a892d8226a935471 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 14:57:49 +0200 Subject: [PATCH 084/287] Add beginning of wordcodec for bytes --- keys/wordcodec.go | 152 +++ keys/wordcodec_test.go | 85 ++ keys/wordlist/english.txt | 2048 +++++++++++++++++++++++++++++++++++++ 3 files changed, 2285 insertions(+) create mode 100644 keys/wordcodec.go create mode 100644 keys/wordcodec_test.go create mode 100644 keys/wordlist/english.txt diff --git a/keys/wordcodec.go b/keys/wordcodec.go new file mode 100644 index 000000000..3a750940b --- /dev/null +++ b/keys/wordcodec.go @@ -0,0 +1,152 @@ +package keys + +import ( + "fmt" + "io/ioutil" + "math/big" + "os" + "strings" + + "github.com/pkg/errors" +) + +const BankSize = 2048 + +// TODO: add error-checking codecs for invalid phrases + +type Codec interface { + BytesToWords([]byte) ([]string, error) + WordsToBytes([]string) ([]byte, error) +} + +type WordCodec struct { + words []string + bytes map[string]int +} + +var _ Codec = WordCodec{} + +func NewCodec(words []string) (codec WordCodec, err error) { + if len(words) != BankSize { + return codec, errors.Errorf("Bank must have %d words, found %d", BankSize, len(words)) + } + + b := map[string]int{} + for i, w := range words { + if _, ok := b[w]; ok { + return codec, errors.Errorf("Duplicate word in list: %s", w) + } + b[w] = i + } + + return WordCodec{words, b}, nil +} + +func LoadCodec(bank string) (codec WordCodec, err error) { + words, err := loadBank(bank) + if err != nil { + return codec, err + } + return NewCodec(words) +} + +// loadBank opens a wordlist file and returns all words inside +func loadBank(bank string) ([]string, error) { + filename := "wordlist/" + bank + ".txt" + words, err := getData(filename) + if err != nil { + return nil, err + } + wordsAll := strings.Split(strings.TrimSpace(words), "\n") + return wordsAll, nil +} + +// TODO: read from go-bind assets +func getData(filename string) (string, error) { + f, err := os.Open(filename) + if err != nil { + return "", errors.WithStack(err) + } + defer f.Close() + + data, err := ioutil.ReadAll(f) + if err != nil { + return "", errors.WithStack(err) + } + + return string(data), nil +} + +// given this many bytes, we will produce this many words +func wordlenFromBytes(numBytes int) int { + // 8 bits per byte, and we add +10 so it rounds up + return (8*numBytes + 10) / 11 +} + +// given this many words, we will produce this many bytes. +// sometimes there are two possibilities. +// if maybeShorter is true, then represents len OR len-1 bytes +func bytelenFromWords(numWords int) (length int, maybeShorter bool) { + // calculate the max number of complete bytes we could store in this word + length = 11 * numWords / 8 + // if one less byte would also generate this length, set maybeShorter + if wordlenFromBytes(length-1) == numWords { + maybeShorter = true + } + return +} + +// TODO: add checksum +func (c WordCodec) BytesToWords(data []byte) (words []string, err error) { + // 2048 words per bank, which is 2^11. + numWords := wordlenFromBytes(len(data)) + + n2048 := big.NewInt(2048) + nData := big.NewInt(0).SetBytes(data) + nRem := big.NewInt(0) + // Alternative, use condition "nData.BitLen() > 0" + // to allow for shorter words when data has leading 0's + for i := 0; i < numWords; i++ { + nData.DivMod(nData, n2048, nRem) + rem := nRem.Int64() + words = append(words, c.words[rem]) + } + fmt.Println(words) + return words, nil +} + +func (c WordCodec) WordsToBytes(words []string) ([]byte, error) { + // // 2048 words per bank, which is 2^11. + // numWords := (8*len(dest) + 10) / 11 + // if numWords != len(words) { + // return errors.New(Fmt("Expected %v words for %v dest bytes", numWords, len(dest))) + // } + + l := len(words) + n2048 := big.NewInt(2048) + nData := big.NewInt(0) + // since we output words based on the remainder, the first word has the lowest + // value... we must load them in reverse order + for i := 1; i <= l; i++ { + w := words[l-i] + rem, ok := c.bytes[w] + if !ok { + return nil, errors.Errorf("Unrecognized word: %s", w) + } + nRem := big.NewInt(int64(rem)) + nData.Mul(nData, n2048) + nData.Add(nData, nRem) + fmt.Printf("+%d: %v\n", rem, nData) + } + + // we copy into a slice of the expected size, so it is not shorter if there + // are lots of leading 0s + dataBytes := nData.Bytes() + fmt.Printf("%#v\n", dataBytes) + + outLen, _ := bytelenFromWords(len(words)) + output := make([]byte, outLen) + copy(output[outLen-len(dataBytes):], dataBytes) + fmt.Printf("%#v\n", output) + return output, nil +} diff --git a/keys/wordcodec_test.go b/keys/wordcodec_test.go new file mode 100644 index 000000000..b75bc9661 --- /dev/null +++ b/keys/wordcodec_test.go @@ -0,0 +1,85 @@ +package keys + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestLengthCalc(t *testing.T) { + assert := assert.New(t) + + cases := []struct { + bytes, words int + flexible bool + }{ + {1, 1, false}, + {2, 2, false}, + // bytes pairs with same word count + {3, 3, true}, + {4, 3, true}, + {5, 4, false}, + // bytes pairs with same word count + {10, 8, true}, + {11, 8, true}, + {12, 9, false}, + {13, 10, false}, + {20, 15, false}, + // bytes pairs with same word count + {21, 16, true}, + {32, 24, true}, + } + + for _, tc := range cases { + wl := wordlenFromBytes(tc.bytes) + assert.Equal(tc.words, wl, "%d", tc.bytes) + + bl, flex := bytelenFromWords(tc.words) + assert.Equal(tc.flexible, flex, "%d", tc.words) + if !flex { + assert.Equal(tc.bytes, bl, "%d", tc.words) + } else { + // check if it is either tc.bytes or tc.bytes +1 + choices := []int{tc.bytes, tc.bytes + 1} + assert.Contains(choices, bl, "%d", tc.words) + } + } +} + +func TestEncodeDecode(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + codec, err := LoadCodec("english") + require.Nil(err, "%+v", err) + + cases := [][]byte{ + // {7, 8, 9}, // TODO: 3 words -> 3 or 4 bytes + // {12, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes + {1, 2, 3, 4, 5}, // normal + {0, 0, 0, 0, 5, 22, 123, 55, 22}, // leading 0s (9 chars, clear) + {22, 44, 55, 1, 13, 0, 0, 0, 0}, // trailing 0s (9 chars, clear) + {0, 5, 253, 2, 0}, // leading and trailing zeros + // others? + } + + for i, tc := range cases { + w, err := codec.BytesToWords(tc) + if assert.Nil(err, "%d: %v", i, err) { + b, err := codec.WordsToBytes(w) + if assert.Nil(err, "%d: %v", i, err) { + assert.Equal(len(tc), len(b)) + assert.Equal(tc, b) + } + } + } +} + +func TestCheckInvalidLists(t *testing.T) { + // assert, require := assert.New(t), require.New(t) + +} + +func TestCheckTypoDetection(t *testing.T) { + +} diff --git a/keys/wordlist/english.txt b/keys/wordlist/english.txt new file mode 100644 index 000000000..942040ed5 --- /dev/null +++ b/keys/wordlist/english.txt @@ -0,0 +1,2048 @@ +abandon +ability +able +about +above +absent +absorb +abstract +absurd +abuse +access +accident +account +accuse +achieve +acid +acoustic +acquire +across +act +action +actor +actress +actual +adapt +add +addict +address +adjust +admit +adult +advance +advice +aerobic +affair +afford +afraid +again +age +agent +agree +ahead +aim +air +airport +aisle +alarm +album +alcohol +alert +alien +all +alley +allow +almost +alone +alpha +already +also +alter +always +amateur +amazing +among +amount +amused +analyst +anchor +ancient +anger +angle +angry +animal +ankle +announce +annual +another +answer +antenna +antique +anxiety +any +apart +apology +appear +apple +approve +april +arch +arctic +area +arena +argue +arm +armed +armor +army +around +arrange +arrest +arrive +arrow +art +artefact +artist +artwork +ask +aspect +assault +asset +assist +assume +asthma +athlete +atom +attack +attend +attitude +attract +auction +audit +august +aunt +author +auto +autumn +average +avocado +avoid +awake +aware +away +awesome +awful +awkward +axis +baby +bachelor +bacon +badge +bag +balance +balcony +ball +bamboo +banana +banner +bar +barely +bargain +barrel +base +basic +basket +battle +beach +bean +beauty +because +become +beef +before +begin +behave +behind +believe +below +belt +bench +benefit +best +betray +better +between +beyond +bicycle +bid +bike +bind +biology +bird +birth +bitter +black +blade +blame +blanket +blast +bleak +bless +blind +blood +blossom +blouse +blue +blur +blush +board +boat +body +boil +bomb +bone +bonus +book +boost +border +boring +borrow +boss +bottom +bounce +box +boy +bracket +brain +brand +brass +brave +bread +breeze +brick +bridge +brief +bright +bring +brisk +broccoli +broken +bronze +broom +brother +brown +brush +bubble +buddy +budget +buffalo +build +bulb +bulk +bullet +bundle +bunker +burden +burger +burst +bus +business +busy +butter +buyer +buzz +cabbage +cabin +cable +cactus +cage +cake +call +calm +camera +camp +can +canal +cancel +candy +cannon +canoe +canvas +canyon +capable +capital +captain +car +carbon +card +cargo +carpet +carry +cart +case +cash +casino +castle +casual +cat +catalog +catch +category +cattle +caught +cause +caution +cave +ceiling +celery +cement +census +century +cereal +certain +chair +chalk +champion +change +chaos +chapter +charge +chase +chat +cheap +check +cheese +chef +cherry +chest +chicken +chief +child +chimney +choice +choose +chronic +chuckle +chunk +churn +cigar +cinnamon +circle +citizen +city +civil +claim +clap +clarify +claw +clay +clean +clerk +clever +click +client +cliff +climb +clinic +clip +clock +clog +close +cloth +cloud +clown +club +clump +cluster +clutch +coach +coast +coconut +code +coffee +coil +coin +collect +color +column +combine +come +comfort +comic +common +company +concert +conduct +confirm +congress +connect +consider +control +convince +cook +cool +copper +copy +coral +core +corn +correct +cost +cotton +couch +country +couple +course +cousin +cover +coyote +crack +cradle +craft +cram +crane +crash +crater +crawl +crazy +cream +credit +creek +crew +cricket +crime +crisp +critic +crop +cross +crouch +crowd +crucial +cruel +cruise +crumble +crunch +crush +cry +crystal +cube +culture +cup +cupboard +curious +current +curtain +curve +cushion +custom +cute +cycle +dad +damage +damp +dance +danger +daring +dash +daughter +dawn +day +deal +debate +debris +decade +december +decide +decline +decorate +decrease +deer +defense +define +defy +degree +delay +deliver +demand +demise +denial +dentist +deny +depart +depend +deposit +depth +deputy +derive +describe +desert +design +desk +despair +destroy +detail +detect +develop +device +devote +diagram +dial +diamond +diary +dice +diesel +diet +differ +digital +dignity +dilemma +dinner +dinosaur +direct +dirt +disagree +discover +disease +dish +dismiss +disorder +display +distance +divert +divide +divorce +dizzy +doctor +document +dog +doll +dolphin +domain +donate +donkey +donor +door +dose +double +dove +draft +dragon +drama +drastic +draw +dream +dress +drift +drill +drink +drip +drive +drop +drum +dry +duck +dumb +dune +during +dust +dutch +duty +dwarf +dynamic +eager +eagle +early +earn +earth +easily +east +easy +echo +ecology +economy +edge +edit +educate +effort +egg +eight +either +elbow +elder +electric +elegant +element +elephant +elevator +elite +else +embark +embody +embrace +emerge +emotion +employ +empower +empty +enable +enact +end +endless +endorse +enemy +energy +enforce +engage +engine +enhance +enjoy +enlist +enough +enrich +enroll +ensure +enter +entire +entry +envelope +episode +equal +equip +era +erase +erode +erosion +error +erupt +escape +essay +essence +estate +eternal +ethics +evidence +evil +evoke +evolve +exact +example +excess +exchange +excite +exclude +excuse +execute +exercise +exhaust +exhibit +exile +exist +exit +exotic +expand +expect +expire +explain +expose +express +extend +extra +eye +eyebrow +fabric +face +faculty +fade +faint +faith +fall +false +fame +family +famous +fan +fancy +fantasy +farm +fashion +fat +fatal +father +fatigue +fault +favorite +feature +february +federal +fee +feed +feel +female +fence +festival +fetch +fever +few +fiber +fiction +field +figure +file +film +filter +final +find +fine +finger +finish +fire +firm +first +fiscal +fish +fit +fitness +fix +flag +flame +flash +flat +flavor +flee +flight +flip +float +flock +floor +flower +fluid +flush +fly +foam +focus +fog +foil +fold +follow +food +foot +force +forest +forget +fork +fortune +forum +forward +fossil +foster +found +fox +fragile +frame +frequent +fresh +friend +fringe +frog +front +frost +frown +frozen +fruit +fuel +fun +funny +furnace +fury +future +gadget +gain +galaxy +gallery +game +gap +garage +garbage +garden +garlic +garment +gas +gasp +gate +gather +gauge +gaze +general +genius +genre +gentle +genuine +gesture +ghost +giant +gift +giggle +ginger +giraffe +girl +give +glad +glance +glare +glass +glide +glimpse +globe +gloom +glory +glove +glow +glue +goat +goddess +gold +good +goose +gorilla +gospel +gossip +govern +gown +grab +grace +grain +grant +grape +grass +gravity +great +green +grid +grief +grit +grocery +group +grow +grunt +guard +guess +guide +guilt +guitar +gun +gym +habit +hair +half +hammer +hamster +hand +happy +harbor +hard +harsh +harvest +hat +have +hawk +hazard +head +health +heart +heavy +hedgehog +height +hello +helmet +help +hen +hero +hidden +high +hill +hint +hip +hire +history +hobby +hockey +hold +hole +holiday +hollow +home +honey +hood +hope +horn +horror +horse +hospital +host +hotel +hour +hover +hub +huge +human +humble +humor +hundred +hungry +hunt +hurdle +hurry +hurt +husband +hybrid +ice +icon +idea +identify +idle +ignore +ill +illegal +illness +image +imitate +immense +immune +impact +impose +improve +impulse +inch +include +income +increase +index +indicate +indoor +industry +infant +inflict +inform +inhale +inherit +initial +inject +injury +inmate +inner +innocent +input +inquiry +insane +insect +inside +inspire +install +intact +interest +into +invest +invite +involve +iron +island +isolate +issue +item +ivory +jacket +jaguar +jar +jazz +jealous +jeans +jelly +jewel +job +join +joke +journey +joy +judge +juice +jump +jungle +junior +junk +just +kangaroo +keen +keep +ketchup +key +kick +kid +kidney +kind +kingdom +kiss +kit +kitchen +kite +kitten +kiwi +knee +knife +knock +know +lab +label +labor +ladder +lady +lake +lamp +language +laptop +large +later +latin +laugh +laundry +lava +law +lawn +lawsuit +layer +lazy +leader +leaf +learn +leave +lecture +left +leg +legal +legend +leisure +lemon +lend +length +lens +leopard +lesson +letter +level +liar +liberty +library +license +life +lift +light +like +limb +limit +link +lion +liquid +list +little +live +lizard +load +loan +lobster +local +lock +logic +lonely +long +loop +lottery +loud +lounge +love +loyal +lucky +luggage +lumber +lunar +lunch +luxury +lyrics +machine +mad +magic +magnet +maid +mail +main +major +make +mammal +man +manage +mandate +mango +mansion +manual +maple +marble +march +margin +marine +market +marriage +mask +mass +master +match +material +math +matrix +matter +maximum +maze +meadow +mean +measure +meat +mechanic +medal +media +melody +melt +member +memory +mention +menu +mercy +merge +merit +merry +mesh +message +metal +method +middle +midnight +milk +million +mimic +mind +minimum +minor +minute +miracle +mirror +misery +miss +mistake +mix +mixed +mixture +mobile +model +modify +mom +moment +monitor +monkey +monster +month +moon +moral +more +morning +mosquito +mother +motion +motor +mountain +mouse +move +movie +much +muffin +mule +multiply +muscle +museum +mushroom +music +must +mutual +myself +mystery +myth +naive +name +napkin +narrow +nasty +nation +nature +near +neck +need +negative +neglect +neither +nephew +nerve +nest +net +network +neutral +never +news +next +nice +night +noble +noise +nominee +noodle +normal +north +nose +notable +note +nothing +notice +novel +now +nuclear +number +nurse +nut +oak +obey +object +oblige +obscure +observe +obtain +obvious +occur +ocean +october +odor +off +offer +office +often +oil +okay +old +olive +olympic +omit +once +one +onion +online +only +open +opera +opinion +oppose +option +orange +orbit +orchard +order +ordinary +organ +orient +original +orphan +ostrich +other +outdoor +outer +output +outside +oval +oven +over +own +owner +oxygen +oyster +ozone +pact +paddle +page +pair +palace +palm +panda +panel +panic +panther +paper +parade +parent +park +parrot +party +pass +patch +path +patient +patrol +pattern +pause +pave +payment +peace +peanut +pear +peasant +pelican +pen +penalty +pencil +people +pepper +perfect +permit +person +pet +phone +photo +phrase +physical +piano +picnic +picture +piece +pig +pigeon +pill +pilot +pink +pioneer +pipe +pistol +pitch +pizza +place +planet +plastic +plate +play +please +pledge +pluck +plug +plunge +poem +poet +point +polar +pole +police +pond +pony +pool +popular +portion +position +possible +post +potato +pottery +poverty +powder +power +practice +praise +predict +prefer +prepare +present +pretty +prevent +price +pride +primary +print +priority +prison +private +prize +problem +process +produce +profit +program +project +promote +proof +property +prosper +protect +proud +provide +public +pudding +pull +pulp +pulse +pumpkin +punch +pupil +puppy +purchase +purity +purpose +purse +push +put +puzzle +pyramid +quality +quantum +quarter +question +quick +quit +quiz +quote +rabbit +raccoon +race +rack +radar +radio +rail +rain +raise +rally +ramp +ranch +random +range +rapid +rare +rate +rather +raven +raw +razor +ready +real +reason +rebel +rebuild +recall +receive +recipe +record +recycle +reduce +reflect +reform +refuse +region +regret +regular +reject +relax +release +relief +rely +remain +remember +remind +remove +render +renew +rent +reopen +repair +repeat +replace +report +require +rescue +resemble +resist +resource +response +result +retire +retreat +return +reunion +reveal +review +reward +rhythm +rib +ribbon +rice +rich +ride +ridge +rifle +right +rigid +ring +riot +ripple +risk +ritual +rival +river +road +roast +robot +robust +rocket +romance +roof +rookie +room +rose +rotate +rough +round +route +royal +rubber +rude +rug +rule +run +runway +rural +sad +saddle +sadness +safe +sail +salad +salmon +salon +salt +salute +same +sample +sand +satisfy +satoshi +sauce +sausage +save +say +scale +scan +scare +scatter +scene +scheme +school +science +scissors +scorpion +scout +scrap +screen +script +scrub +sea +search +season +seat +second +secret +section +security +seed +seek +segment +select +sell +seminar +senior +sense +sentence +series +service +session +settle +setup +seven +shadow +shaft +shallow +share +shed +shell +sheriff +shield +shift +shine +ship +shiver +shock +shoe +shoot +shop +short +shoulder +shove +shrimp +shrug +shuffle +shy +sibling +sick +side +siege +sight +sign +silent +silk +silly +silver +similar +simple +since +sing +siren +sister +situate +six +size +skate +sketch +ski +skill +skin +skirt +skull +slab +slam +sleep +slender +slice +slide +slight +slim +slogan +slot +slow +slush +small +smart +smile +smoke +smooth +snack +snake +snap +sniff +snow +soap +soccer +social +sock +soda +soft +solar +soldier +solid +solution +solve +someone +song +soon +sorry +sort +soul +sound +soup +source +south +space +spare +spatial +spawn +speak +special +speed +spell +spend +sphere +spice +spider +spike +spin +spirit +split +spoil +sponsor +spoon +sport +spot +spray +spread +spring +spy +square +squeeze +squirrel +stable +stadium +staff +stage +stairs +stamp +stand +start +state +stay +steak +steel +stem +step +stereo +stick +still +sting +stock +stomach +stone +stool +story +stove +strategy +street +strike +strong +struggle +student +stuff +stumble +style +subject +submit +subway +success +such +sudden +suffer +sugar +suggest +suit +summer +sun +sunny +sunset +super +supply +supreme +sure +surface +surge +surprise +surround +survey +suspect +sustain +swallow +swamp +swap +swarm +swear +sweet +swift +swim +swing +switch +sword +symbol +symptom +syrup +system +table +tackle +tag +tail +talent +talk +tank +tape +target +task +taste +tattoo +taxi +teach +team +tell +ten +tenant +tennis +tent +term +test +text +thank +that +theme +then +theory +there +they +thing +this +thought +three +thrive +throw +thumb +thunder +ticket +tide +tiger +tilt +timber +time +tiny +tip +tired +tissue +title +toast +tobacco +today +toddler +toe +together +toilet +token +tomato +tomorrow +tone +tongue +tonight +tool +tooth +top +topic +topple +torch +tornado +tortoise +toss +total +tourist +toward +tower +town +toy +track +trade +traffic +tragic +train +transfer +trap +trash +travel +tray +treat +tree +trend +trial +tribe +trick +trigger +trim +trip +trophy +trouble +truck +true +truly +trumpet +trust +truth +try +tube +tuition +tumble +tuna +tunnel +turkey +turn +turtle +twelve +twenty +twice +twin +twist +two +type +typical +ugly +umbrella +unable +unaware +uncle +uncover +under +undo +unfair +unfold +unhappy +uniform +unique +unit +universe +unknown +unlock +until +unusual +unveil +update +upgrade +uphold +upon +upper +upset +urban +urge +usage +use +used +useful +useless +usual +utility +vacant +vacuum +vague +valid +valley +valve +van +vanish +vapor +various +vast +vault +vehicle +velvet +vendor +venture +venue +verb +verify +version +very +vessel +veteran +viable +vibrant +vicious +victory +video +view +village +vintage +violin +virtual +virus +visa +visit +visual +vital +vivid +vocal +voice +void +volcano +volume +vote +voyage +wage +wagon +wait +walk +wall +walnut +want +warfare +warm +warrior +wash +wasp +waste +water +wave +way +wealth +weapon +wear +weasel +weather +web +wedding +weekend +weird +welcome +west +wet +whale +what +wheat +wheel +when +where +whip +whisper +wide +width +wife +wild +will +win +window +wine +wing +wink +winner +winter +wire +wisdom +wise +wish +witness +wolf +woman +wonder +wood +wool +word +work +world +worry +worth +wrap +wreck +wrestle +wrist +write +wrong +yard +year +yellow +you +young +youth +zebra +zero +zone +zoo From e20cdfcbaeac42a42ac8ec62ed808001379d592b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 15:20:40 +0200 Subject: [PATCH 085/287] Cleanup wordcodec --- keys/wordcodec.go | 46 +++++++++++++++++++++++++----------------- keys/wordcodec_test.go | 10 ++++++--- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/keys/wordcodec.go b/keys/wordcodec.go index 3a750940b..b3e45e2c6 100644 --- a/keys/wordcodec.go +++ b/keys/wordcodec.go @@ -1,7 +1,6 @@ package keys import ( - "fmt" "io/ioutil" "math/big" "os" @@ -31,15 +30,7 @@ func NewCodec(words []string) (codec WordCodec, err error) { return codec, errors.Errorf("Bank must have %d words, found %d", BankSize, len(words)) } - b := map[string]int{} - for i, w := range words { - if _, ok := b[w]; ok { - return codec, errors.Errorf("Duplicate word in list: %s", w) - } - b[w] = i - } - - return WordCodec{words, b}, nil + return WordCodec{words: words}, nil } func LoadCodec(bank string) (codec WordCodec, err error) { @@ -111,7 +102,6 @@ func (c WordCodec) BytesToWords(data []byte) (words []string, err error) { rem := nRem.Int64() words = append(words, c.words[rem]) } - fmt.Println(words) return words, nil } @@ -128,25 +118,45 @@ func (c WordCodec) WordsToBytes(words []string) ([]byte, error) { // since we output words based on the remainder, the first word has the lowest // value... we must load them in reverse order for i := 1; i <= l; i++ { - w := words[l-i] - rem, ok := c.bytes[w] - if !ok { - return nil, errors.Errorf("Unrecognized word: %s", w) + rem, err := c.GetIndex(words[l-i]) + if err != nil { + return nil, err } nRem := big.NewInt(int64(rem)) nData.Mul(nData, n2048) nData.Add(nData, nRem) - fmt.Printf("+%d: %v\n", rem, nData) } // we copy into a slice of the expected size, so it is not shorter if there // are lots of leading 0s dataBytes := nData.Bytes() - fmt.Printf("%#v\n", dataBytes) outLen, _ := bytelenFromWords(len(words)) output := make([]byte, outLen) copy(output[outLen-len(dataBytes):], dataBytes) - fmt.Printf("%#v\n", output) return output, nil } + +// GetIndex finds the index of the words to create bytes +// Generates a map the first time it is loaded, to avoid needless +// computation when list is not used. +func (c WordCodec) GetIndex(word string) (int, error) { + // generate the first time + if c.bytes == nil { + b := map[string]int{} + for i, w := range c.words { + if _, ok := b[w]; ok { + return -1, errors.Errorf("Duplicate word in list: %s", w) + } + b[w] = i + } + c.bytes = b + } + + // get the index, or an error + rem, ok := c.bytes[word] + if !ok { + return -1, errors.Errorf("Unrecognized word: %s", word) + } + return rem, nil +} diff --git a/keys/wordcodec_test.go b/keys/wordcodec_test.go index b75bc9661..e96912072 100644 --- a/keys/wordcodec_test.go +++ b/keys/wordcodec_test.go @@ -54,12 +54,16 @@ func TestEncodeDecode(t *testing.T) { require.Nil(err, "%+v", err) cases := [][]byte{ - // {7, 8, 9}, // TODO: 3 words -> 3 or 4 bytes - // {12, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes - {1, 2, 3, 4, 5}, // normal + // {7, 8, 9}, // TODO: 3 words -> 3 or 4 bytes + {12, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes + {0, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes, detect leading 0 + {1, 2, 3, 4, 5}, // normal + // {0, 0, 0, 0, 122, 23, 82, 195}, // leading 0s (8 chars, unclear) {0, 0, 0, 0, 5, 22, 123, 55, 22}, // leading 0s (9 chars, clear) {22, 44, 55, 1, 13, 0, 0, 0, 0}, // trailing 0s (9 chars, clear) {0, 5, 253, 2, 0}, // leading and trailing zeros + {255, 196, 172, 234, 192, 255}, // big numbers + // {255, 196, 172, 1, 234, 192, 255}, // big numbers, two length choices // others? } From 55a25f0f6233557212c1b2c0cbd3ae40600b259b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 15:49:17 +0200 Subject: [PATCH 086/287] Add first pass of ecc checksuming --- keys/ecc.go | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ keys/ecc_test.go | 52 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 keys/ecc.go create mode 100644 keys/ecc_test.go diff --git a/keys/ecc.go b/keys/ecc.go new file mode 100644 index 000000000..ff16345d3 --- /dev/null +++ b/keys/ecc.go @@ -0,0 +1,56 @@ +package keys + +import ( + "encoding/binary" + "errors" + "hash/crc32" +) + +// ECC is used for anything that calculates an error-correcting code +type ECC interface { + // AddECC calculates an error-correcting code for the input + // returns an output with the code appended + AddECC([]byte) []byte + + // CheckECC verifies if the ECC is proper on the input and returns + // the data with the code removed, or an error + CheckECC([]byte) ([]byte, error) +} + +// NoECC is a no-op placeholder, kind of useless... except for tests +type NoECC struct{} + +var _ ECC = NoECC{} + +func (_ NoECC) AddECC(input []byte) []byte { return input } +func (_ NoECC) CheckECC(input []byte) ([]byte, error) { return input, nil } + +// CRC32 does the ieee crc32 polynomial check +type CRC32 struct{} + +var _ ECC = CRC32{} + +func (_ CRC32) AddECC(input []byte) []byte { + // get crc and convert to some bytes... + crc := crc32.ChecksumIEEE(input) + check := make([]byte, 4) + binary.BigEndian.PutUint32(check, crc) + + // append it to the input + output := append(input, check...) + return output +} + +func (_ CRC32) CheckECC(input []byte) ([]byte, error) { + if len(input) <= 4 { + return nil, errors.New("input too short, no checksum present") + } + cut := len(input) - 4 + data, check := input[:cut], input[cut:] + crc := binary.BigEndian.Uint32(check) + calc := crc32.ChecksumIEEE(data) + if crc != calc { + return nil, errors.New("Checksum does not match") + } + return data, nil +} diff --git a/keys/ecc_test.go b/keys/ecc_test.go new file mode 100644 index 000000000..f58bc7a9c --- /dev/null +++ b/keys/ecc_test.go @@ -0,0 +1,52 @@ +package keys + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + cmn "github.com/tendermint/tmlibs/common" +) + +// TestECCPasses makes sure that the AddECC/CheckECC methods are symetric +func TestECCPasses(t *testing.T) { + assert := assert.New(t) + + checks := []ECC{NoECC{}, CRC32{}} + + for _, check := range checks { + for i := 0; i < 2000; i++ { + numBytes := cmn.RandInt()%60 + 1 + data := cmn.RandBytes(numBytes) + + checked := check.AddECC(data) + res, err := check.CheckECC(checked) + if assert.Nil(err, "%v: %+v", check, err) { + assert.Equal(data, res, "%v", check) + } + } + } +} + +// TestECCFails makes sure random data will (usually) fail the checksum +func TestECCFails(t *testing.T) { + assert := assert.New(t) + + checks := []ECC{CRC32{}} + + attempts := 2000 + + for _, check := range checks { + failed := 0 + for i := 0; i < attempts; i++ { + numBytes := cmn.RandInt()%60 + 1 + data := cmn.RandBytes(numBytes) + _, err := check.CheckECC(data) + if err != nil { + failed += 1 + } + } + // we allow up to 1 falsely accepted checksums, as there are random matches + assert.InDelta(attempts, failed, 1, "%v", check) + } +} From ce6b08761ed3970ba46e82b632816ba03776314f Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 15:56:12 +0200 Subject: [PATCH 087/287] Improve crc32 --- keys/ecc.go | 35 ++++++++++++++++++++++++++--------- keys/ecc_test.go | 5 +++-- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/keys/ecc.go b/keys/ecc.go index ff16345d3..ba754d525 100644 --- a/keys/ecc.go +++ b/keys/ecc.go @@ -26,14 +26,19 @@ func (_ NoECC) AddECC(input []byte) []byte { return input } func (_ NoECC) CheckECC(input []byte) ([]byte, error) { return input, nil } // CRC32 does the ieee crc32 polynomial check -type CRC32 struct{} +type CRC32 struct { + Poly uint32 + table *crc32.Table +} + +var _ ECC = &CRC32{} -var _ ECC = CRC32{} +func (c *CRC32) AddECC(input []byte) []byte { + table := c.getTable() -func (_ CRC32) AddECC(input []byte) []byte { // get crc and convert to some bytes... - crc := crc32.ChecksumIEEE(input) - check := make([]byte, 4) + crc := crc32.Checksum(input, table) + check := make([]byte, crc32.Size) binary.BigEndian.PutUint32(check, crc) // append it to the input @@ -41,16 +46,28 @@ func (_ CRC32) AddECC(input []byte) []byte { return output } -func (_ CRC32) CheckECC(input []byte) ([]byte, error) { - if len(input) <= 4 { +func (c *CRC32) CheckECC(input []byte) ([]byte, error) { + table := c.getTable() + + if len(input) <= crc32.Size { return nil, errors.New("input too short, no checksum present") } - cut := len(input) - 4 + cut := len(input) - crc32.Size data, check := input[:cut], input[cut:] crc := binary.BigEndian.Uint32(check) - calc := crc32.ChecksumIEEE(data) + calc := crc32.Checksum(data, table) if crc != calc { return nil, errors.New("Checksum does not match") } return data, nil } + +func (c *CRC32) getTable() *crc32.Table { + if c.table == nil { + if c.Poly == 0 { + c.Poly = crc32.IEEE + } + c.table = crc32.MakeTable(c.Poly) + } + return c.table +} diff --git a/keys/ecc_test.go b/keys/ecc_test.go index f58bc7a9c..a85d4ddd7 100644 --- a/keys/ecc_test.go +++ b/keys/ecc_test.go @@ -1,6 +1,7 @@ package keys import ( + "hash/crc32" "testing" "github.com/stretchr/testify/assert" @@ -12,7 +13,7 @@ import ( func TestECCPasses(t *testing.T) { assert := assert.New(t) - checks := []ECC{NoECC{}, CRC32{}} + checks := []ECC{NoECC{}, &CRC32{}, &CRC32{Poly: crc32.Castagnoli}} for _, check := range checks { for i := 0; i < 2000; i++ { @@ -32,7 +33,7 @@ func TestECCPasses(t *testing.T) { func TestECCFails(t *testing.T) { assert := assert.New(t) - checks := []ECC{CRC32{}} + checks := []ECC{&CRC32{}, &CRC32{Poly: crc32.Castagnoli}} attempts := 2000 From 0b0e994cd1ca63c386e8d2cda8aec9188a5834a6 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 16:02:47 +0200 Subject: [PATCH 088/287] Add crc64, constructors --- keys/ecc.go | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ keys/ecc_test.go | 20 +++++++++++--- 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/keys/ecc.go b/keys/ecc.go index ba754d525..96590cd91 100644 --- a/keys/ecc.go +++ b/keys/ecc.go @@ -4,6 +4,7 @@ import ( "encoding/binary" "errors" "hash/crc32" + "hash/crc64" ) // ECC is used for anything that calculates an error-correcting code @@ -33,6 +34,18 @@ type CRC32 struct { var _ ECC = &CRC32{} +func NewIEEECRC32() *CRC32 { + return &CRC32{Poly: crc32.IEEE} +} + +func NewCastagnoliCRC32() *CRC32 { + return &CRC32{Poly: crc32.Castagnoli} +} + +func NewKoopmanCRC32() *CRC32 { + return &CRC32{Poly: crc32.Koopman} +} + func (c *CRC32) AddECC(input []byte) []byte { table := c.getTable() @@ -71,3 +84,58 @@ func (c *CRC32) getTable() *crc32.Table { } return c.table } + +// CRC64 does the ieee crc64 polynomial check +type CRC64 struct { + Poly uint64 + table *crc64.Table +} + +var _ ECC = &CRC64{} + +func NewISOCRC64() *CRC64 { + return &CRC64{Poly: crc64.ISO} +} + +func NewECMACRC64() *CRC64 { + return &CRC64{Poly: crc64.ECMA} +} + +func (c *CRC64) AddECC(input []byte) []byte { + table := c.getTable() + + // get crc and convert to some bytes... + crc := crc64.Checksum(input, table) + check := make([]byte, crc64.Size) + binary.BigEndian.PutUint64(check, crc) + + // append it to the input + output := append(input, check...) + return output +} + +func (c *CRC64) CheckECC(input []byte) ([]byte, error) { + table := c.getTable() + + if len(input) <= crc64.Size { + return nil, errors.New("input too short, no checksum present") + } + cut := len(input) - crc64.Size + data, check := input[:cut], input[cut:] + crc := binary.BigEndian.Uint64(check) + calc := crc64.Checksum(data, table) + if crc != calc { + return nil, errors.New("Checksum does not match") + } + return data, nil +} + +func (c *CRC64) getTable() *crc64.Table { + if c.table == nil { + if c.Poly == 0 { + c.Poly = crc64.ISO + } + c.table = crc64.MakeTable(c.Poly) + } + return c.table +} diff --git a/keys/ecc_test.go b/keys/ecc_test.go index a85d4ddd7..334c49423 100644 --- a/keys/ecc_test.go +++ b/keys/ecc_test.go @@ -1,7 +1,6 @@ package keys import ( - "hash/crc32" "testing" "github.com/stretchr/testify/assert" @@ -13,7 +12,14 @@ import ( func TestECCPasses(t *testing.T) { assert := assert.New(t) - checks := []ECC{NoECC{}, &CRC32{}, &CRC32{Poly: crc32.Castagnoli}} + checks := []ECC{ + NoECC{}, + NewIEEECRC32(), + NewCastagnoliCRC32(), + NewKoopmanCRC32(), + NewISOCRC64(), + NewECMACRC64(), + } for _, check := range checks { for i := 0; i < 2000; i++ { @@ -22,7 +28,7 @@ func TestECCPasses(t *testing.T) { checked := check.AddECC(data) res, err := check.CheckECC(checked) - if assert.Nil(err, "%v: %+v", check, err) { + if assert.Nil(err, "%#v: %+v", check, err) { assert.Equal(data, res, "%v", check) } } @@ -33,7 +39,13 @@ func TestECCPasses(t *testing.T) { func TestECCFails(t *testing.T) { assert := assert.New(t) - checks := []ECC{&CRC32{}, &CRC32{Poly: crc32.Castagnoli}} + checks := []ECC{ + NewIEEECRC32(), + NewCastagnoliCRC32(), + NewKoopmanCRC32(), + NewISOCRC64(), + NewECMACRC64(), + } attempts := 2000 From ad029d1293fbec4b687b9b4c5ac63b9e76d9e89b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 16:10:15 +0200 Subject: [PATCH 089/287] Integrate ecc into word-byte codec --- keys/wordcodec.go | 39 ++++++++++++++++++++++++++------------- keys/wordcodec_test.go | 20 ++++++++++---------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/keys/wordcodec.go b/keys/wordcodec.go index b3e45e2c6..7778b9b53 100644 --- a/keys/wordcodec.go +++ b/keys/wordcodec.go @@ -21,6 +21,7 @@ type Codec interface { type WordCodec struct { words []string bytes map[string]int + check ECC } var _ Codec = WordCodec{} @@ -30,7 +31,13 @@ func NewCodec(words []string) (codec WordCodec, err error) { return codec, errors.Errorf("Bank must have %d words, found %d", BankSize, len(words)) } - return WordCodec{words: words}, nil + res := WordCodec{ + words: words, + // TODO: configure this outside??? + check: NewIEEECRC32(), + } + + return res, nil } func LoadCodec(bank string) (codec WordCodec, err error) { @@ -70,6 +77,7 @@ func getData(filename string) (string, error) { // given this many bytes, we will produce this many words func wordlenFromBytes(numBytes int) int { + // 2048 words per bank, which is 2^11. // 8 bits per byte, and we add +10 so it rounds up return (8*numBytes + 10) / 11 } @@ -88,8 +96,9 @@ func bytelenFromWords(numWords int) (length int, maybeShorter bool) { } // TODO: add checksum -func (c WordCodec) BytesToWords(data []byte) (words []string, err error) { - // 2048 words per bank, which is 2^11. +func (c WordCodec) BytesToWords(raw []byte) (words []string, err error) { + // always add a checksum to the data + data := c.check.AddECC(raw) numWords := wordlenFromBytes(len(data)) n2048 := big.NewInt(2048) @@ -106,12 +115,6 @@ func (c WordCodec) BytesToWords(data []byte) (words []string, err error) { } func (c WordCodec) WordsToBytes(words []string) ([]byte, error) { - // // 2048 words per bank, which is 2^11. - // numWords := (8*len(dest) + 10) / 11 - // if numWords != len(words) { - // return errors.New(Fmt("Expected %v words for %v dest bytes", numWords, len(dest))) - // } - l := len(words) n2048 := big.NewInt(2048) nData := big.NewInt(0) @@ -131,10 +134,20 @@ func (c WordCodec) WordsToBytes(words []string) ([]byte, error) { // are lots of leading 0s dataBytes := nData.Bytes() - outLen, _ := bytelenFromWords(len(words)) - output := make([]byte, outLen) - copy(output[outLen-len(dataBytes):], dataBytes) - return output, nil + // copy into the container we have with the expected size + outLen, flex := bytelenFromWords(len(words)) + toCheck := make([]byte, outLen) + copy(toCheck[outLen-len(dataBytes):], dataBytes) + + // validate the checksum... + output, err := c.check.CheckECC(toCheck) + if flex && err != nil { + // if flex, try again one shorter.... + toCheck = toCheck[1:] + output, err = c.check.CheckECC(toCheck) + } + + return output, err } // GetIndex finds the index of the words to create bytes diff --git a/keys/wordcodec_test.go b/keys/wordcodec_test.go index e96912072..e650eb0dd 100644 --- a/keys/wordcodec_test.go +++ b/keys/wordcodec_test.go @@ -54,16 +54,16 @@ func TestEncodeDecode(t *testing.T) { require.Nil(err, "%+v", err) cases := [][]byte{ - // {7, 8, 9}, // TODO: 3 words -> 3 or 4 bytes - {12, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes - {0, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes, detect leading 0 - {1, 2, 3, 4, 5}, // normal - // {0, 0, 0, 0, 122, 23, 82, 195}, // leading 0s (8 chars, unclear) - {0, 0, 0, 0, 5, 22, 123, 55, 22}, // leading 0s (9 chars, clear) - {22, 44, 55, 1, 13, 0, 0, 0, 0}, // trailing 0s (9 chars, clear) - {0, 5, 253, 2, 0}, // leading and trailing zeros - {255, 196, 172, 234, 192, 255}, // big numbers - // {255, 196, 172, 1, 234, 192, 255}, // big numbers, two length choices + {7, 8, 9}, // TODO: 3 words -> 3 or 4 bytes + {12, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes + {0, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes, detect leading 0 + {1, 2, 3, 4, 5}, // normal + {0, 0, 0, 0, 122, 23, 82, 195}, // leading 0s (8 chars, unclear) + {0, 0, 0, 0, 5, 22, 123, 55, 22}, // leading 0s (9 chars, clear) + {22, 44, 55, 1, 13, 0, 0, 0, 0}, // trailing 0s (9 chars, clear) + {0, 5, 253, 2, 0}, // leading and trailing zeros + {255, 196, 172, 234, 192, 255}, // big numbers + {255, 196, 172, 1, 234, 192, 255}, // big numbers, two length choices // others? } From 65c880e7533b8150df406f8761087506b8d88f91 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 16:32:33 +0200 Subject: [PATCH 090/287] Test validation of word banks upon load --- keys/wordcodec.go | 8 ++++++- keys/wordcodec_test.go | 48 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/keys/wordcodec.go b/keys/wordcodec.go index 7778b9b53..c69f7ae1d 100644 --- a/keys/wordcodec.go +++ b/keys/wordcodec.go @@ -109,7 +109,13 @@ func (c WordCodec) BytesToWords(raw []byte) (words []string, err error) { for i := 0; i < numWords; i++ { nData.DivMod(nData, n2048, nRem) rem := nRem.Int64() - words = append(words, c.words[rem]) + w := c.words[rem] + // double-check bank on generation... + _, err := c.GetIndex(w) + if err != nil { + return nil, err + } + words = append(words, w) } return words, nil } diff --git a/keys/wordcodec_test.go b/keys/wordcodec_test.go index e650eb0dd..40ac24f42 100644 --- a/keys/wordcodec_test.go +++ b/keys/wordcodec_test.go @@ -5,6 +5,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + cmn "github.com/tendermint/tmlibs/common" ) func TestLengthCalc(t *testing.T) { @@ -80,7 +82,51 @@ func TestEncodeDecode(t *testing.T) { } func TestCheckInvalidLists(t *testing.T) { - // assert, require := assert.New(t), require.New(t) + assert := assert.New(t) + + trivial := []string{"abc", "def"} + short := make([]string, 1234) + long := make([]string, BankSize+1) + right := make([]string, BankSize) + dups := make([]string, BankSize) + + for _, list := range [][]string{short, long, right, dups} { + for i := range list { + list[i] = cmn.RandStr(8) + } + } + // create one single duplicate + dups[192] = dups[782] + + cases := []struct { + words []string + loadable bool + valid bool + }{ + {trivial, false, false}, + {short, false, false}, + {long, false, false}, + {dups, true, false}, // we only check dups on first use... + {right, true, true}, + } + + for i, tc := range cases { + codec, err := NewCodec(tc.words) + if !tc.loadable { + assert.NotNil(err, "%d", i) + } else if assert.Nil(err, "%d: %+v", i, err) { + data := cmn.RandBytes(32) + w, err := codec.BytesToWords(data) + if tc.valid { + assert.Nil(err, "%d: %+v", i, err) + b, err := codec.WordsToBytes(w) + assert.Nil(err, "%d: %+v", i, err) + assert.Equal(data, b) + } else { + assert.NotNil(err, "%d", i) + } + } + } } From 2c0d52f4b5a70a798bea3d2c7a203d9664eb1240 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 16:52:04 +0200 Subject: [PATCH 091/287] Add typo detector test, fix panics --- keys/wordcodec.go | 8 ++++++++ keys/wordcodec_test.go | 46 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/keys/wordcodec.go b/keys/wordcodec.go index c69f7ae1d..5ac32f812 100644 --- a/keys/wordcodec.go +++ b/keys/wordcodec.go @@ -122,6 +122,11 @@ func (c WordCodec) BytesToWords(raw []byte) (words []string, err error) { func (c WordCodec) WordsToBytes(words []string) ([]byte, error) { l := len(words) + + if l == 0 { + return nil, errors.New("Didn't provide any words") + } + n2048 := big.NewInt(2048) nData := big.NewInt(0) // since we output words based on the remainder, the first word has the lowest @@ -143,6 +148,9 @@ func (c WordCodec) WordsToBytes(words []string) ([]byte, error) { // copy into the container we have with the expected size outLen, flex := bytelenFromWords(len(words)) toCheck := make([]byte, outLen) + if len(dataBytes) > outLen { + return nil, errors.New("Invalid data, could not have been generated by this codec") + } copy(toCheck[outLen-len(dataBytes):], dataBytes) // validate the checksum... diff --git a/keys/wordcodec_test.go b/keys/wordcodec_test.go index 40ac24f42..b9496a0ef 100644 --- a/keys/wordcodec_test.go +++ b/keys/wordcodec_test.go @@ -130,6 +130,52 @@ func TestCheckInvalidLists(t *testing.T) { } +func getRandWord(c WordCodec) string { + idx := cmn.RandInt() % BankSize + return c.words[idx] +} + +func getDiffWord(c WordCodec, not string) string { + w := getRandWord(c) + if w == not { + w = getRandWord(c) + } + return w +} + func TestCheckTypoDetection(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + banks := []string{"english"} + + for _, bank := range banks { + codec, err := LoadCodec(bank) + require.Nil(err, "%s: %+v", bank, err) + for i := 0; i < 10; i++ { + numBytes := cmn.RandInt()%60 + 1 + data := cmn.RandBytes(numBytes) + + words, err := codec.BytesToWords(data) + assert.Nil(err, "%s: %+v", bank, err) + good, err := codec.WordsToBytes(words) + assert.Nil(err, "%s: %+v", bank, err) + assert.Equal(data, good, bank) + + // now try some tweaks... + cut := words[1:] + _, err = codec.WordsToBytes(cut) + assert.NotNil(err, "%s: %s", bank, words) + + // swap a word within the bank, should fails + words[3] = getDiffWord(codec, words[3]) + _, err = codec.WordsToBytes(words) + assert.NotNil(err, "%s: %s", bank, words) + + // put a random word here, must fail + words[3] = cmn.RandStr(10) + _, err = codec.WordsToBytes(words) + assert.NotNil(err, "%s: %s", bank, words) + } + } } From 1e978ba8381f25c39df1ac4a3fad18e8cd0fa38a Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 16:53:07 +0200 Subject: [PATCH 092/287] Import multiple language wordbanks, test them --- keys/wordcodec_test.go | 2 +- keys/wordlist/chinese_simplified.txt | 2048 ++++++++++++++++++++++++++ keys/wordlist/japanese.txt | 2048 ++++++++++++++++++++++++++ keys/wordlist/spanish.txt | 2048 ++++++++++++++++++++++++++ 4 files changed, 6145 insertions(+), 1 deletion(-) create mode 100644 keys/wordlist/chinese_simplified.txt create mode 100644 keys/wordlist/japanese.txt create mode 100644 keys/wordlist/spanish.txt diff --git a/keys/wordcodec_test.go b/keys/wordcodec_test.go index b9496a0ef..c3a5a2cac 100644 --- a/keys/wordcodec_test.go +++ b/keys/wordcodec_test.go @@ -146,7 +146,7 @@ func getDiffWord(c WordCodec, not string) string { func TestCheckTypoDetection(t *testing.T) { assert, require := assert.New(t), require.New(t) - banks := []string{"english"} + banks := []string{"english", "spanish", "japanese", "chinese_simplified"} for _, bank := range banks { codec, err := LoadCodec(bank) diff --git a/keys/wordlist/chinese_simplified.txt b/keys/wordlist/chinese_simplified.txt new file mode 100644 index 000000000..b90f1ed85 --- /dev/null +++ b/keys/wordlist/chinese_simplified.txt @@ -0,0 +1,2048 @@ +的 +一 +是 +在 +不 +了 +有 +和 +人 +这 +中 +大 +为 +上 +个 +国 +我 +以 +要 +他 +时 +来 +用 +们 +生 +到 +作 +地 +于 +出 +就 +分 +对 +成 +会 +可 +主 +发 +年 +动 +同 +工 +也 +能 +下 +过 +子 +说 +产 +种 +面 +而 +方 +后 +多 +定 +行 +学 +法 +所 +民 +得 +经 +十 +三 +之 +进 +着 +等 +部 +度 +家 +电 +力 +里 +如 +水 +化 +高 +自 +二 +理 +起 +小 +物 +现 +实 +加 +量 +都 +两 +体 +制 +机 +当 +使 +点 +从 +业 +本 +去 +把 +性 +好 +应 +开 +它 +合 +还 +因 +由 +其 +些 +然 +前 +外 +天 +政 +四 +日 +那 +社 +义 +事 +平 +形 +相 +全 +表 +间 +样 +与 +关 +各 +重 +新 +线 +内 +数 +正 +心 +反 +你 +明 +看 +原 +又 +么 +利 +比 +或 +但 +质 +气 +第 +向 +道 +命 +此 +变 +条 +只 +没 +结 +解 +问 +意 +建 +月 +公 +无 +系 +军 +很 +情 +者 +最 +立 +代 +想 +已 +通 +并 +提 +直 +题 +党 +程 +展 +五 +果 +料 +象 +员 +革 +位 +入 +常 +文 +总 +次 +品 +式 +活 +设 +及 +管 +特 +件 +长 +求 +老 +头 +基 +资 +边 +流 +路 +级 +少 +图 +山 +统 +接 +知 +较 +将 +组 +见 +计 +别 +她 +手 +角 +期 +根 +论 +运 +农 +指 +几 +九 +区 +强 +放 +决 +西 +被 +干 +做 +必 +战 +先 +回 +则 +任 +取 +据 +处 +队 +南 +给 +色 +光 +门 +即 +保 +治 +北 +造 +百 +规 +热 +领 +七 +海 +口 +东 +导 +器 +压 +志 +世 +金 +增 +争 +济 +阶 +油 +思 +术 +极 +交 +受 +联 +什 +认 +六 +共 +权 +收 +证 +改 +清 +美 +再 +采 +转 +更 +单 +风 +切 +打 +白 +教 +速 +花 +带 +安 +场 +身 +车 +例 +真 +务 +具 +万 +每 +目 +至 +达 +走 +积 +示 +议 +声 +报 +斗 +完 +类 +八 +离 +华 +名 +确 +才 +科 +张 +信 +马 +节 +话 +米 +整 +空 +元 +况 +今 +集 +温 +传 +土 +许 +步 +群 +广 +石 +记 +需 +段 +研 +界 +拉 +林 +律 +叫 +且 +究 +观 +越 +织 +装 +影 +算 +低 +持 +音 +众 +书 +布 +复 +容 +儿 +须 +际 +商 +非 +验 +连 +断 +深 +难 +近 +矿 +千 +周 +委 +素 +技 +备 +半 +办 +青 +省 +列 +习 +响 +约 +支 +般 +史 +感 +劳 +便 +团 +往 +酸 +历 +市 +克 +何 +除 +消 +构 +府 +称 +太 +准 +精 +值 +号 +率 +族 +维 +划 +选 +标 +写 +存 +候 +毛 +亲 +快 +效 +斯 +院 +查 +江 +型 +眼 +王 +按 +格 +养 +易 +置 +派 +层 +片 +始 +却 +专 +状 +育 +厂 +京 +识 +适 +属 +圆 +包 +火 +住 +调 +满 +县 +局 +照 +参 +红 +细 +引 +听 +该 +铁 +价 +严 +首 +底 +液 +官 +德 +随 +病 +苏 +失 +尔 +死 +讲 +配 +女 +黄 +推 +显 +谈 +罪 +神 +艺 +呢 +席 +含 +企 +望 +密 +批 +营 +项 +防 +举 +球 +英 +氧 +势 +告 +李 +台 +落 +木 +帮 +轮 +破 +亚 +师 +围 +注 +远 +字 +材 +排 +供 +河 +态 +封 +另 +施 +减 +树 +溶 +怎 +止 +案 +言 +士 +均 +武 +固 +叶 +鱼 +波 +视 +仅 +费 +紧 +爱 +左 +章 +早 +朝 +害 +续 +轻 +服 +试 +食 +充 +兵 +源 +判 +护 +司 +足 +某 +练 +差 +致 +板 +田 +降 +黑 +犯 +负 +击 +范 +继 +兴 +似 +余 +坚 +曲 +输 +修 +故 +城 +夫 +够 +送 +笔 +船 +占 +右 +财 +吃 +富 +春 +职 +觉 +汉 +画 +功 +巴 +跟 +虽 +杂 +飞 +检 +吸 +助 +升 +阳 +互 +初 +创 +抗 +考 +投 +坏 +策 +古 +径 +换 +未 +跑 +留 +钢 +曾 +端 +责 +站 +简 +述 +钱 +副 +尽 +帝 +射 +草 +冲 +承 +独 +令 +限 +阿 +宣 +环 +双 +请 +超 +微 +让 +控 +州 +良 +轴 +找 +否 +纪 +益 +依 +优 +顶 +础 +载 +倒 +房 +突 +坐 +粉 +敌 +略 +客 +袁 +冷 +胜 +绝 +析 +块 +剂 +测 +丝 +协 +诉 +念 +陈 +仍 +罗 +盐 +友 +洋 +错 +苦 +夜 +刑 +移 +频 +逐 +靠 +混 +母 +短 +皮 +终 +聚 +汽 +村 +云 +哪 +既 +距 +卫 +停 +烈 +央 +察 +烧 +迅 +境 +若 +印 +洲 +刻 +括 +激 +孔 +搞 +甚 +室 +待 +核 +校 +散 +侵 +吧 +甲 +游 +久 +菜 +味 +旧 +模 +湖 +货 +损 +预 +阻 +毫 +普 +稳 +乙 +妈 +植 +息 +扩 +银 +语 +挥 +酒 +守 +拿 +序 +纸 +医 +缺 +雨 +吗 +针 +刘 +啊 +急 +唱 +误 +训 +愿 +审 +附 +获 +茶 +鲜 +粮 +斤 +孩 +脱 +硫 +肥 +善 +龙 +演 +父 +渐 +血 +欢 +械 +掌 +歌 +沙 +刚 +攻 +谓 +盾 +讨 +晚 +粒 +乱 +燃 +矛 +乎 +杀 +药 +宁 +鲁 +贵 +钟 +煤 +读 +班 +伯 +香 +介 +迫 +句 +丰 +培 +握 +兰 +担 +弦 +蛋 +沉 +假 +穿 +执 +答 +乐 +谁 +顺 +烟 +缩 +征 +脸 +喜 +松 +脚 +困 +异 +免 +背 +星 +福 +买 +染 +井 +概 +慢 +怕 +磁 +倍 +祖 +皇 +促 +静 +补 +评 +翻 +肉 +践 +尼 +衣 +宽 +扬 +棉 +希 +伤 +操 +垂 +秋 +宜 +氢 +套 +督 +振 +架 +亮 +末 +宪 +庆 +编 +牛 +触 +映 +雷 +销 +诗 +座 +居 +抓 +裂 +胞 +呼 +娘 +景 +威 +绿 +晶 +厚 +盟 +衡 +鸡 +孙 +延 +危 +胶 +屋 +乡 +临 +陆 +顾 +掉 +呀 +灯 +岁 +措 +束 +耐 +剧 +玉 +赵 +跳 +哥 +季 +课 +凯 +胡 +额 +款 +绍 +卷 +齐 +伟 +蒸 +殖 +永 +宗 +苗 +川 +炉 +岩 +弱 +零 +杨 +奏 +沿 +露 +杆 +探 +滑 +镇 +饭 +浓 +航 +怀 +赶 +库 +夺 +伊 +灵 +税 +途 +灭 +赛 +归 +召 +鼓 +播 +盘 +裁 +险 +康 +唯 +录 +菌 +纯 +借 +糖 +盖 +横 +符 +私 +努 +堂 +域 +枪 +润 +幅 +哈 +竟 +熟 +虫 +泽 +脑 +壤 +碳 +欧 +遍 +侧 +寨 +敢 +彻 +虑 +斜 +薄 +庭 +纳 +弹 +饲 +伸 +折 +麦 +湿 +暗 +荷 +瓦 +塞 +床 +筑 +恶 +户 +访 +塔 +奇 +透 +梁 +刀 +旋 +迹 +卡 +氯 +遇 +份 +毒 +泥 +退 +洗 +摆 +灰 +彩 +卖 +耗 +夏 +择 +忙 +铜 +献 +硬 +予 +繁 +圈 +雪 +函 +亦 +抽 +篇 +阵 +阴 +丁 +尺 +追 +堆 +雄 +迎 +泛 +爸 +楼 +避 +谋 +吨 +野 +猪 +旗 +累 +偏 +典 +馆 +索 +秦 +脂 +潮 +爷 +豆 +忽 +托 +惊 +塑 +遗 +愈 +朱 +替 +纤 +粗 +倾 +尚 +痛 +楚 +谢 +奋 +购 +磨 +君 +池 +旁 +碎 +骨 +监 +捕 +弟 +暴 +割 +贯 +殊 +释 +词 +亡 +壁 +顿 +宝 +午 +尘 +闻 +揭 +炮 +残 +冬 +桥 +妇 +警 +综 +招 +吴 +付 +浮 +遭 +徐 +您 +摇 +谷 +赞 +箱 +隔 +订 +男 +吹 +园 +纷 +唐 +败 +宋 +玻 +巨 +耕 +坦 +荣 +闭 +湾 +键 +凡 +驻 +锅 +救 +恩 +剥 +凝 +碱 +齿 +截 +炼 +麻 +纺 +禁 +废 +盛 +版 +缓 +净 +睛 +昌 +婚 +涉 +筒 +嘴 +插 +岸 +朗 +庄 +街 +藏 +姑 +贸 +腐 +奴 +啦 +惯 +乘 +伙 +恢 +匀 +纱 +扎 +辩 +耳 +彪 +臣 +亿 +璃 +抵 +脉 +秀 +萨 +俄 +网 +舞 +店 +喷 +纵 +寸 +汗 +挂 +洪 +贺 +闪 +柬 +爆 +烯 +津 +稻 +墙 +软 +勇 +像 +滚 +厘 +蒙 +芳 +肯 +坡 +柱 +荡 +腿 +仪 +旅 +尾 +轧 +冰 +贡 +登 +黎 +削 +钻 +勒 +逃 +障 +氨 +郭 +峰 +币 +港 +伏 +轨 +亩 +毕 +擦 +莫 +刺 +浪 +秘 +援 +株 +健 +售 +股 +岛 +甘 +泡 +睡 +童 +铸 +汤 +阀 +休 +汇 +舍 +牧 +绕 +炸 +哲 +磷 +绩 +朋 +淡 +尖 +启 +陷 +柴 +呈 +徒 +颜 +泪 +稍 +忘 +泵 +蓝 +拖 +洞 +授 +镜 +辛 +壮 +锋 +贫 +虚 +弯 +摩 +泰 +幼 +廷 +尊 +窗 +纲 +弄 +隶 +疑 +氏 +宫 +姐 +震 +瑞 +怪 +尤 +琴 +循 +描 +膜 +违 +夹 +腰 +缘 +珠 +穷 +森 +枝 +竹 +沟 +催 +绳 +忆 +邦 +剩 +幸 +浆 +栏 +拥 +牙 +贮 +礼 +滤 +钠 +纹 +罢 +拍 +咱 +喊 +袖 +埃 +勤 +罚 +焦 +潜 +伍 +墨 +欲 +缝 +姓 +刊 +饱 +仿 +奖 +铝 +鬼 +丽 +跨 +默 +挖 +链 +扫 +喝 +袋 +炭 +污 +幕 +诸 +弧 +励 +梅 +奶 +洁 +灾 +舟 +鉴 +苯 +讼 +抱 +毁 +懂 +寒 +智 +埔 +寄 +届 +跃 +渡 +挑 +丹 +艰 +贝 +碰 +拔 +爹 +戴 +码 +梦 +芽 +熔 +赤 +渔 +哭 +敬 +颗 +奔 +铅 +仲 +虎 +稀 +妹 +乏 +珍 +申 +桌 +遵 +允 +隆 +螺 +仓 +魏 +锐 +晓 +氮 +兼 +隐 +碍 +赫 +拨 +忠 +肃 +缸 +牵 +抢 +博 +巧 +壳 +兄 +杜 +讯 +诚 +碧 +祥 +柯 +页 +巡 +矩 +悲 +灌 +龄 +伦 +票 +寻 +桂 +铺 +圣 +恐 +恰 +郑 +趣 +抬 +荒 +腾 +贴 +柔 +滴 +猛 +阔 +辆 +妻 +填 +撤 +储 +签 +闹 +扰 +紫 +砂 +递 +戏 +吊 +陶 +伐 +喂 +疗 +瓶 +婆 +抚 +臂 +摸 +忍 +虾 +蜡 +邻 +胸 +巩 +挤 +偶 +弃 +槽 +劲 +乳 +邓 +吉 +仁 +烂 +砖 +租 +乌 +舰 +伴 +瓜 +浅 +丙 +暂 +燥 +橡 +柳 +迷 +暖 +牌 +秧 +胆 +详 +簧 +踏 +瓷 +谱 +呆 +宾 +糊 +洛 +辉 +愤 +竞 +隙 +怒 +粘 +乃 +绪 +肩 +籍 +敏 +涂 +熙 +皆 +侦 +悬 +掘 +享 +纠 +醒 +狂 +锁 +淀 +恨 +牲 +霸 +爬 +赏 +逆 +玩 +陵 +祝 +秒 +浙 +貌 +役 +彼 +悉 +鸭 +趋 +凤 +晨 +畜 +辈 +秩 +卵 +署 +梯 +炎 +滩 +棋 +驱 +筛 +峡 +冒 +啥 +寿 +译 +浸 +泉 +帽 +迟 +硅 +疆 +贷 +漏 +稿 +冠 +嫩 +胁 +芯 +牢 +叛 +蚀 +奥 +鸣 +岭 +羊 +凭 +串 +塘 +绘 +酵 +融 +盆 +锡 +庙 +筹 +冻 +辅 +摄 +袭 +筋 +拒 +僚 +旱 +钾 +鸟 +漆 +沈 +眉 +疏 +添 +棒 +穗 +硝 +韩 +逼 +扭 +侨 +凉 +挺 +碗 +栽 +炒 +杯 +患 +馏 +劝 +豪 +辽 +勃 +鸿 +旦 +吏 +拜 +狗 +埋 +辊 +掩 +饮 +搬 +骂 +辞 +勾 +扣 +估 +蒋 +绒 +雾 +丈 +朵 +姆 +拟 +宇 +辑 +陕 +雕 +偿 +蓄 +崇 +剪 +倡 +厅 +咬 +驶 +薯 +刷 +斥 +番 +赋 +奉 +佛 +浇 +漫 +曼 +扇 +钙 +桃 +扶 +仔 +返 +俗 +亏 +腔 +鞋 +棱 +覆 +框 +悄 +叔 +撞 +骗 +勘 +旺 +沸 +孤 +吐 +孟 +渠 +屈 +疾 +妙 +惜 +仰 +狠 +胀 +谐 +抛 +霉 +桑 +岗 +嘛 +衰 +盗 +渗 +脏 +赖 +涌 +甜 +曹 +阅 +肌 +哩 +厉 +烃 +纬 +毅 +昨 +伪 +症 +煮 +叹 +钉 +搭 +茎 +笼 +酷 +偷 +弓 +锥 +恒 +杰 +坑 +鼻 +翼 +纶 +叙 +狱 +逮 +罐 +络 +棚 +抑 +膨 +蔬 +寺 +骤 +穆 +冶 +枯 +册 +尸 +凸 +绅 +坯 +牺 +焰 +轰 +欣 +晋 +瘦 +御 +锭 +锦 +丧 +旬 +锻 +垄 +搜 +扑 +邀 +亭 +酯 +迈 +舒 +脆 +酶 +闲 +忧 +酚 +顽 +羽 +涨 +卸 +仗 +陪 +辟 +惩 +杭 +姚 +肚 +捉 +飘 +漂 +昆 +欺 +吾 +郎 +烷 +汁 +呵 +饰 +萧 +雅 +邮 +迁 +燕 +撒 +姻 +赴 +宴 +烦 +债 +帐 +斑 +铃 +旨 +醇 +董 +饼 +雏 +姿 +拌 +傅 +腹 +妥 +揉 +贤 +拆 +歪 +葡 +胺 +丢 +浩 +徽 +昂 +垫 +挡 +览 +贪 +慰 +缴 +汪 +慌 +冯 +诺 +姜 +谊 +凶 +劣 +诬 +耀 +昏 +躺 +盈 +骑 +乔 +溪 +丛 +卢 +抹 +闷 +咨 +刮 +驾 +缆 +悟 +摘 +铒 +掷 +颇 +幻 +柄 +惠 +惨 +佳 +仇 +腊 +窝 +涤 +剑 +瞧 +堡 +泼 +葱 +罩 +霍 +捞 +胎 +苍 +滨 +俩 +捅 +湘 +砍 +霞 +邵 +萄 +疯 +淮 +遂 +熊 +粪 +烘 +宿 +档 +戈 +驳 +嫂 +裕 +徙 +箭 +捐 +肠 +撑 +晒 +辨 +殿 +莲 +摊 +搅 +酱 +屏 +疫 +哀 +蔡 +堵 +沫 +皱 +畅 +叠 +阁 +莱 +敲 +辖 +钩 +痕 +坝 +巷 +饿 +祸 +丘 +玄 +溜 +曰 +逻 +彭 +尝 +卿 +妨 +艇 +吞 +韦 +怨 +矮 +歇 diff --git a/keys/wordlist/japanese.txt b/keys/wordlist/japanese.txt new file mode 100644 index 000000000..c4c9dca4e --- /dev/null +++ b/keys/wordlist/japanese.txt @@ -0,0 +1,2048 @@ +あいこくしん +あいさつ +あいだ +あおぞら +あかちゃん +あきる +あけがた +あける +あこがれる +あさい +あさひ +あしあと +あじわう +あずかる +あずき +あそぶ +あたえる +あたためる +あたりまえ +あたる +あつい +あつかう +あっしゅく +あつまり +あつめる +あてな +あてはまる +あひる +あぶら +あぶる +あふれる +あまい +あまど +あまやかす +あまり +あみもの +あめりか +あやまる +あゆむ +あらいぐま +あらし +あらすじ +あらためる +あらゆる +あらわす +ありがとう +あわせる +あわてる +あんい +あんがい +あんこ +あんぜん +あんてい +あんない +あんまり +いいだす +いおん +いがい +いがく +いきおい +いきなり +いきもの +いきる +いくじ +いくぶん +いけばな +いけん +いこう +いこく +いこつ +いさましい +いさん +いしき +いじゅう +いじょう +いじわる +いずみ +いずれ +いせい +いせえび +いせかい +いせき +いぜん +いそうろう +いそがしい +いだい +いだく +いたずら +いたみ +いたりあ +いちおう +いちじ +いちど +いちば +いちぶ +いちりゅう +いつか +いっしゅん +いっせい +いっそう +いったん +いっち +いってい +いっぽう +いてざ +いてん +いどう +いとこ +いない +いなか +いねむり +いのち +いのる +いはつ +いばる +いはん +いびき +いひん +いふく +いへん +いほう +いみん +いもうと +いもたれ +いもり +いやがる +いやす +いよかん +いよく +いらい +いらすと +いりぐち +いりょう +いれい +いれもの +いれる +いろえんぴつ +いわい +いわう +いわかん +いわば +いわゆる +いんげんまめ +いんさつ +いんしょう +いんよう +うえき +うえる +うおざ +うがい +うかぶ +うかべる +うきわ +うくらいな +うくれれ +うけたまわる +うけつけ +うけとる +うけもつ +うける +うごかす +うごく +うこん +うさぎ +うしなう +うしろがみ +うすい +うすぎ +うすぐらい +うすめる +うせつ +うちあわせ +うちがわ +うちき +うちゅう +うっかり +うつくしい +うったえる +うつる +うどん +うなぎ +うなじ +うなずく +うなる +うねる +うのう +うぶげ +うぶごえ +うまれる +うめる +うもう +うやまう +うよく +うらがえす +うらぐち +うらない +うりあげ +うりきれ +うるさい +うれしい +うれゆき +うれる +うろこ +うわき +うわさ +うんこう +うんちん +うんてん +うんどう +えいえん +えいが +えいきょう +えいご +えいせい +えいぶん +えいよう +えいわ +えおり +えがお +えがく +えきたい +えくせる +えしゃく +えすて +えつらん +えのぐ +えほうまき +えほん +えまき +えもじ +えもの +えらい +えらぶ +えりあ +えんえん +えんかい +えんぎ +えんげき +えんしゅう +えんぜつ +えんそく +えんちょう +えんとつ +おいかける +おいこす +おいしい +おいつく +おうえん +おうさま +おうじ +おうせつ +おうたい +おうふく +おうべい +おうよう +おえる +おおい +おおう +おおどおり +おおや +おおよそ +おかえり +おかず +おがむ +おかわり +おぎなう +おきる +おくさま +おくじょう +おくりがな +おくる +おくれる +おこす +おこなう +おこる +おさえる +おさない +おさめる +おしいれ +おしえる +おじぎ +おじさん +おしゃれ +おそらく +おそわる +おたがい +おたく +おだやか +おちつく +おっと +おつり +おでかけ +おとしもの +おとなしい +おどり +おどろかす +おばさん +おまいり +おめでとう +おもいで +おもう +おもたい +おもちゃ +おやつ +おやゆび +およぼす +おらんだ +おろす +おんがく +おんけい +おんしゃ +おんせん +おんだん +おんちゅう +おんどけい +かあつ +かいが +がいき +がいけん +がいこう +かいさつ +かいしゃ +かいすいよく +かいぜん +かいぞうど +かいつう +かいてん +かいとう +かいふく +がいへき +かいほう +かいよう +がいらい +かいわ +かえる +かおり +かかえる +かがく +かがし +かがみ +かくご +かくとく +かざる +がぞう +かたい +かたち +がちょう +がっきゅう +がっこう +がっさん +がっしょう +かなざわし +かのう +がはく +かぶか +かほう +かほご +かまう +かまぼこ +かめれおん +かゆい +かようび +からい +かるい +かろう +かわく +かわら +がんか +かんけい +かんこう +かんしゃ +かんそう +かんたん +かんち +がんばる +きあい +きあつ +きいろ +ぎいん +きうい +きうん +きえる +きおう +きおく +きおち +きおん +きかい +きかく +きかんしゃ +ききて +きくばり +きくらげ +きけんせい +きこう +きこえる +きこく +きさい +きさく +きさま +きさらぎ +ぎじかがく +ぎしき +ぎじたいけん +ぎじにってい +ぎじゅつしゃ +きすう +きせい +きせき +きせつ +きそう +きぞく +きぞん +きたえる +きちょう +きつえん +ぎっちり +きつつき +きつね +きてい +きどう +きどく +きない +きなが +きなこ +きぬごし +きねん +きのう +きのした +きはく +きびしい +きひん +きふく +きぶん +きぼう +きほん +きまる +きみつ +きむずかしい +きめる +きもだめし +きもち +きもの +きゃく +きやく +ぎゅうにく +きよう +きょうりゅう +きらい +きらく +きりん +きれい +きれつ +きろく +ぎろん +きわめる +ぎんいろ +きんかくじ +きんじょ +きんようび +ぐあい +くいず +くうかん +くうき +くうぐん +くうこう +ぐうせい +くうそう +ぐうたら +くうふく +くうぼ +くかん +くきょう +くげん +ぐこう +くさい +くさき +くさばな +くさる +くしゃみ +くしょう +くすのき +くすりゆび +くせげ +くせん +ぐたいてき +くださる +くたびれる +くちこみ +くちさき +くつした +ぐっすり +くつろぐ +くとうてん +くどく +くなん +くねくね +くのう +くふう +くみあわせ +くみたてる +くめる +くやくしょ +くらす +くらべる +くるま +くれる +くろう +くわしい +ぐんかん +ぐんしょく +ぐんたい +ぐんて +けあな +けいかく +けいけん +けいこ +けいさつ +げいじゅつ +けいたい +げいのうじん +けいれき +けいろ +けおとす +けおりもの +げきか +げきげん +げきだん +げきちん +げきとつ +げきは +げきやく +げこう +げこくじょう +げざい +けさき +げざん +けしき +けしごむ +けしょう +げすと +けたば +けちゃっぷ +けちらす +けつあつ +けつい +けつえき +けっこん +けつじょ +けっせき +けってい +けつまつ +げつようび +げつれい +けつろん +げどく +けとばす +けとる +けなげ +けなす +けなみ +けぬき +げねつ +けねん +けはい +げひん +けぶかい +げぼく +けまり +けみかる +けむし +けむり +けもの +けらい +けろけろ +けわしい +けんい +けんえつ +けんお +けんか +げんき +けんげん +けんこう +けんさく +けんしゅう +けんすう +げんそう +けんちく +けんてい +けんとう +けんない +けんにん +げんぶつ +けんま +けんみん +けんめい +けんらん +けんり +こあくま +こいぬ +こいびと +ごうい +こうえん +こうおん +こうかん +ごうきゅう +ごうけい +こうこう +こうさい +こうじ +こうすい +ごうせい +こうそく +こうたい +こうちゃ +こうつう +こうてい +こうどう +こうない +こうはい +ごうほう +ごうまん +こうもく +こうりつ +こえる +こおり +ごかい +ごがつ +ごかん +こくご +こくさい +こくとう +こくない +こくはく +こぐま +こけい +こける +ここのか +こころ +こさめ +こしつ +こすう +こせい +こせき +こぜん +こそだて +こたい +こたえる +こたつ +こちょう +こっか +こつこつ +こつばん +こつぶ +こてい +こてん +ことがら +ことし +ことば +ことり +こなごな +こねこね +このまま +このみ +このよ +ごはん +こひつじ +こふう +こふん +こぼれる +ごまあぶら +こまかい +ごますり +こまつな +こまる +こむぎこ +こもじ +こもち +こもの +こもん +こやく +こやま +こゆう +こゆび +こよい +こよう +こりる +これくしょん +ころっけ +こわもて +こわれる +こんいん +こんかい +こんき +こんしゅう +こんすい +こんだて +こんとん +こんなん +こんびに +こんぽん +こんまけ +こんや +こんれい +こんわく +ざいえき +さいかい +さいきん +ざいげん +ざいこ +さいしょ +さいせい +ざいたく +ざいちゅう +さいてき +ざいりょう +さうな +さかいし +さがす +さかな +さかみち +さがる +さぎょう +さくし +さくひん +さくら +さこく +さこつ +さずかる +ざせき +さたん +さつえい +ざつおん +ざっか +ざつがく +さっきょく +ざっし +さつじん +ざっそう +さつたば +さつまいも +さてい +さといも +さとう +さとおや +さとし +さとる +さのう +さばく +さびしい +さべつ +さほう +さほど +さます +さみしい +さみだれ +さむけ +さめる +さやえんどう +さゆう +さよう +さよく +さらだ +ざるそば +さわやか +さわる +さんいん +さんか +さんきゃく +さんこう +さんさい +ざんしょ +さんすう +さんせい +さんそ +さんち +さんま +さんみ +さんらん +しあい +しあげ +しあさって +しあわせ +しいく +しいん +しうち +しえい +しおけ +しかい +しかく +じかん +しごと +しすう +じだい +したうけ +したぎ +したて +したみ +しちょう +しちりん +しっかり +しつじ +しつもん +してい +してき +してつ +じてん +じどう +しなぎれ +しなもの +しなん +しねま +しねん +しのぐ +しのぶ +しはい +しばかり +しはつ +しはらい +しはん +しひょう +しふく +じぶん +しへい +しほう +しほん +しまう +しまる +しみん +しむける +じむしょ +しめい +しめる +しもん +しゃいん +しゃうん +しゃおん +じゃがいも +しやくしょ +しゃくほう +しゃけん +しゃこ +しゃざい +しゃしん +しゃせん +しゃそう +しゃたい +しゃちょう +しゃっきん +じゃま +しゃりん +しゃれい +じゆう +じゅうしょ +しゅくはく +じゅしん +しゅっせき +しゅみ +しゅらば +じゅんばん +しょうかい +しょくたく +しょっけん +しょどう +しょもつ +しらせる +しらべる +しんか +しんこう +じんじゃ +しんせいじ +しんちく +しんりん +すあげ +すあし +すあな +ずあん +すいえい +すいか +すいとう +ずいぶん +すいようび +すうがく +すうじつ +すうせん +すおどり +すきま +すくう +すくない +すける +すごい +すこし +ずさん +すずしい +すすむ +すすめる +すっかり +ずっしり +ずっと +すてき +すてる +すねる +すのこ +すはだ +すばらしい +ずひょう +ずぶぬれ +すぶり +すふれ +すべて +すべる +ずほう +すぼん +すまい +すめし +すもう +すやき +すらすら +するめ +すれちがう +すろっと +すわる +すんぜん +すんぽう +せあぶら +せいかつ +せいげん +せいじ +せいよう +せおう +せかいかん +せきにん +せきむ +せきゆ +せきらんうん +せけん +せこう +せすじ +せたい +せたけ +せっかく +せっきゃく +ぜっく +せっけん +せっこつ +せっさたくま +せつぞく +せつだん +せつでん +せっぱん +せつび +せつぶん +せつめい +せつりつ +せなか +せのび +せはば +せびろ +せぼね +せまい +せまる +せめる +せもたれ +せりふ +ぜんあく +せんい +せんえい +せんか +せんきょ +せんく +せんげん +ぜんご +せんさい +せんしゅ +せんすい +せんせい +せんぞ +せんたく +せんちょう +せんてい +せんとう +せんぬき +せんねん +せんぱい +ぜんぶ +ぜんぽう +せんむ +せんめんじょ +せんもん +せんやく +せんゆう +せんよう +ぜんら +ぜんりゃく +せんれい +せんろ +そあく +そいとげる +そいね +そうがんきょう +そうき +そうご +そうしん +そうだん +そうなん +そうび +そうめん +そうり +そえもの +そえん +そがい +そげき +そこう +そこそこ +そざい +そしな +そせい +そせん +そそぐ +そだてる +そつう +そつえん +そっかん +そつぎょう +そっけつ +そっこう +そっせん +そっと +そとがわ +そとづら +そなえる +そなた +そふぼ +そぼく +そぼろ +そまつ +そまる +そむく +そむりえ +そめる +そもそも +そよかぜ +そらまめ +そろう +そんかい +そんけい +そんざい +そんしつ +そんぞく +そんちょう +ぞんび +ぞんぶん +そんみん +たあい +たいいん +たいうん +たいえき +たいおう +だいがく +たいき +たいぐう +たいけん +たいこ +たいざい +だいじょうぶ +だいすき +たいせつ +たいそう +だいたい +たいちょう +たいてい +だいどころ +たいない +たいねつ +たいのう +たいはん +だいひょう +たいふう +たいへん +たいほ +たいまつばな +たいみんぐ +たいむ +たいめん +たいやき +たいよう +たいら +たいりょく +たいる +たいわん +たうえ +たえる +たおす +たおる +たおれる +たかい +たかね +たきび +たくさん +たこく +たこやき +たさい +たしざん +だじゃれ +たすける +たずさわる +たそがれ +たたかう +たたく +ただしい +たたみ +たちばな +だっかい +だっきゃく +だっこ +だっしゅつ +だったい +たてる +たとえる +たなばた +たにん +たぬき +たのしみ +たはつ +たぶん +たべる +たぼう +たまご +たまる +だむる +ためいき +ためす +ためる +たもつ +たやすい +たよる +たらす +たりきほんがん +たりょう +たりる +たると +たれる +たれんと +たろっと +たわむれる +だんあつ +たんい +たんおん +たんか +たんき +たんけん +たんご +たんさん +たんじょうび +だんせい +たんそく +たんたい +だんち +たんてい +たんとう +だんな +たんにん +だんねつ +たんのう +たんぴん +だんぼう +たんまつ +たんめい +だんれつ +だんろ +だんわ +ちあい +ちあん +ちいき +ちいさい +ちえん +ちかい +ちから +ちきゅう +ちきん +ちけいず +ちけん +ちこく +ちさい +ちしき +ちしりょう +ちせい +ちそう +ちたい +ちたん +ちちおや +ちつじょ +ちてき +ちてん +ちぬき +ちぬり +ちのう +ちひょう +ちへいせん +ちほう +ちまた +ちみつ +ちみどろ +ちめいど +ちゃんこなべ +ちゅうい +ちゆりょく +ちょうし +ちょさくけん +ちらし +ちらみ +ちりがみ +ちりょう +ちるど +ちわわ +ちんたい +ちんもく +ついか +ついたち +つうか +つうじょう +つうはん +つうわ +つかう +つかれる +つくね +つくる +つけね +つける +つごう +つたえる +つづく +つつじ +つつむ +つとめる +つながる +つなみ +つねづね +つのる +つぶす +つまらない +つまる +つみき +つめたい +つもり +つもる +つよい +つるぼ +つるみく +つわもの +つわり +てあし +てあて +てあみ +ていおん +ていか +ていき +ていけい +ていこく +ていさつ +ていし +ていせい +ていたい +ていど +ていねい +ていひょう +ていへん +ていぼう +てうち +ておくれ +てきとう +てくび +でこぼこ +てさぎょう +てさげ +てすり +てそう +てちがい +てちょう +てつがく +てつづき +でっぱ +てつぼう +てつや +でぬかえ +てぬき +てぬぐい +てのひら +てはい +てぶくろ +てふだ +てほどき +てほん +てまえ +てまきずし +てみじか +てみやげ +てらす +てれび +てわけ +てわたし +でんあつ +てんいん +てんかい +てんき +てんぐ +てんけん +てんごく +てんさい +てんし +てんすう +でんち +てんてき +てんとう +てんない +てんぷら +てんぼうだい +てんめつ +てんらんかい +でんりょく +でんわ +どあい +といれ +どうかん +とうきゅう +どうぐ +とうし +とうむぎ +とおい +とおか +とおく +とおす +とおる +とかい +とかす +ときおり +ときどき +とくい +とくしゅう +とくてん +とくに +とくべつ +とけい +とける +とこや +とさか +としょかん +とそう +とたん +とちゅう +とっきゅう +とっくん +とつぜん +とつにゅう +とどける +ととのえる +とない +となえる +となり +とのさま +とばす +どぶがわ +とほう +とまる +とめる +ともだち +ともる +どようび +とらえる +とんかつ +どんぶり +ないかく +ないこう +ないしょ +ないす +ないせん +ないそう +なおす +ながい +なくす +なげる +なこうど +なさけ +なたでここ +なっとう +なつやすみ +ななおし +なにごと +なにもの +なにわ +なのか +なふだ +なまいき +なまえ +なまみ +なみだ +なめらか +なめる +なやむ +ならう +ならび +ならぶ +なれる +なわとび +なわばり +にあう +にいがた +にうけ +におい +にかい +にがて +にきび +にくしみ +にくまん +にげる +にさんかたんそ +にしき +にせもの +にちじょう +にちようび +にっか +にっき +にっけい +にっこう +にっさん +にっしょく +にっすう +にっせき +にってい +になう +にほん +にまめ +にもつ +にやり +にゅういん +にりんしゃ +にわとり +にんい +にんか +にんき +にんげん +にんしき +にんずう +にんそう +にんたい +にんち +にんてい +にんにく +にんぷ +にんまり +にんむ +にんめい +にんよう +ぬいくぎ +ぬかす +ぬぐいとる +ぬぐう +ぬくもり +ぬすむ +ぬまえび +ぬめり +ぬらす +ぬんちゃく +ねあげ +ねいき +ねいる +ねいろ +ねぐせ +ねくたい +ねくら +ねこぜ +ねこむ +ねさげ +ねすごす +ねそべる +ねだん +ねつい +ねっしん +ねつぞう +ねったいぎょ +ねぶそく +ねふだ +ねぼう +ねほりはほり +ねまき +ねまわし +ねみみ +ねむい +ねむたい +ねもと +ねらう +ねわざ +ねんいり +ねんおし +ねんかん +ねんきん +ねんぐ +ねんざ +ねんし +ねんちゃく +ねんど +ねんぴ +ねんぶつ +ねんまつ +ねんりょう +ねんれい +のいず +のおづま +のがす +のきなみ +のこぎり +のこす +のこる +のせる +のぞく +のぞむ +のたまう +のちほど +のっく +のばす +のはら +のべる +のぼる +のみもの +のやま +のらいぬ +のらねこ +のりもの +のりゆき +のれん +のんき +ばあい +はあく +ばあさん +ばいか +ばいく +はいけん +はいご +はいしん +はいすい +はいせん +はいそう +はいち +ばいばい +はいれつ +はえる +はおる +はかい +ばかり +はかる +はくしゅ +はけん +はこぶ +はさみ +はさん +はしご +ばしょ +はしる +はせる +ぱそこん +はそん +はたん +はちみつ +はつおん +はっかく +はづき +はっきり +はっくつ +はっけん +はっこう +はっさん +はっしん +はったつ +はっちゅう +はってん +はっぴょう +はっぽう +はなす +はなび +はにかむ +はぶらし +はみがき +はむかう +はめつ +はやい +はやし +はらう +はろうぃん +はわい +はんい +はんえい +はんおん +はんかく +はんきょう +ばんぐみ +はんこ +はんしゃ +はんすう +はんだん +ぱんち +ぱんつ +はんてい +はんとし +はんのう +はんぱ +はんぶん +はんぺん +はんぼうき +はんめい +はんらん +はんろん +ひいき +ひうん +ひえる +ひかく +ひかり +ひかる +ひかん +ひくい +ひけつ +ひこうき +ひこく +ひさい +ひさしぶり +ひさん +びじゅつかん +ひしょ +ひそか +ひそむ +ひたむき +ひだり +ひたる +ひつぎ +ひっこし +ひっし +ひつじゅひん +ひっす +ひつぜん +ぴったり +ぴっちり +ひつよう +ひてい +ひとごみ +ひなまつり +ひなん +ひねる +ひはん +ひびく +ひひょう +ひほう +ひまわり +ひまん +ひみつ +ひめい +ひめじし +ひやけ +ひやす +ひよう +びょうき +ひらがな +ひらく +ひりつ +ひりょう +ひるま +ひるやすみ +ひれい +ひろい +ひろう +ひろき +ひろゆき +ひんかく +ひんけつ +ひんこん +ひんしゅ +ひんそう +ぴんち +ひんぱん +びんぼう +ふあん +ふいうち +ふうけい +ふうせん +ぷうたろう +ふうとう +ふうふ +ふえる +ふおん +ふかい +ふきん +ふくざつ +ふくぶくろ +ふこう +ふさい +ふしぎ +ふじみ +ふすま +ふせい +ふせぐ +ふそく +ぶたにく +ふたん +ふちょう +ふつう +ふつか +ふっかつ +ふっき +ふっこく +ぶどう +ふとる +ふとん +ふのう +ふはい +ふひょう +ふへん +ふまん +ふみん +ふめつ +ふめん +ふよう +ふりこ +ふりる +ふるい +ふんいき +ぶんがく +ぶんぐ +ふんしつ +ぶんせき +ふんそう +ぶんぽう +へいあん +へいおん +へいがい +へいき +へいげん +へいこう +へいさ +へいしゃ +へいせつ +へいそ +へいたく +へいてん +へいねつ +へいわ +へきが +へこむ +べにいろ +べにしょうが +へらす +へんかん +べんきょう +べんごし +へんさい +へんたい +べんり +ほあん +ほいく +ぼうぎょ +ほうこく +ほうそう +ほうほう +ほうもん +ほうりつ +ほえる +ほおん +ほかん +ほきょう +ぼきん +ほくろ +ほけつ +ほけん +ほこう +ほこる +ほしい +ほしつ +ほしゅ +ほしょう +ほせい +ほそい +ほそく +ほたて +ほたる +ぽちぶくろ +ほっきょく +ほっさ +ほったん +ほとんど +ほめる +ほんい +ほんき +ほんけ +ほんしつ +ほんやく +まいにち +まかい +まかせる +まがる +まける +まこと +まさつ +まじめ +ますく +まぜる +まつり +まとめ +まなぶ +まぬけ +まねく +まほう +まもる +まゆげ +まよう +まろやか +まわす +まわり +まわる +まんが +まんきつ +まんぞく +まんなか +みいら +みうち +みえる +みがく +みかた +みかん +みけん +みこん +みじかい +みすい +みすえる +みせる +みっか +みつかる +みつける +みてい +みとめる +みなと +みなみかさい +みねらる +みのう +みのがす +みほん +みもと +みやげ +みらい +みりょく +みわく +みんか +みんぞく +むいか +むえき +むえん +むかい +むかう +むかえ +むかし +むぎちゃ +むける +むげん +むさぼる +むしあつい +むしば +むじゅん +むしろ +むすう +むすこ +むすぶ +むすめ +むせる +むせん +むちゅう +むなしい +むのう +むやみ +むよう +むらさき +むりょう +むろん +めいあん +めいうん +めいえん +めいかく +めいきょく +めいさい +めいし +めいそう +めいぶつ +めいれい +めいわく +めぐまれる +めざす +めした +めずらしい +めだつ +めまい +めやす +めんきょ +めんせき +めんどう +もうしあげる +もうどうけん +もえる +もくし +もくてき +もくようび +もちろん +もどる +もらう +もんく +もんだい +やおや +やける +やさい +やさしい +やすい +やすたろう +やすみ +やせる +やそう +やたい +やちん +やっと +やっぱり +やぶる +やめる +ややこしい +やよい +やわらかい +ゆうき +ゆうびんきょく +ゆうべ +ゆうめい +ゆけつ +ゆしゅつ +ゆせん +ゆそう +ゆたか +ゆちゃく +ゆでる +ゆにゅう +ゆびわ +ゆらい +ゆれる +ようい +ようか +ようきゅう +ようじ +ようす +ようちえん +よかぜ +よかん +よきん +よくせい +よくぼう +よけい +よごれる +よさん +よしゅう +よそう +よそく +よっか +よてい +よどがわく +よねつ +よやく +よゆう +よろこぶ +よろしい +らいう +らくがき +らくご +らくさつ +らくだ +らしんばん +らせん +らぞく +らたい +らっか +られつ +りえき +りかい +りきさく +りきせつ +りくぐん +りくつ +りけん +りこう +りせい +りそう +りそく +りてん +りねん +りゆう +りゅうがく +りよう +りょうり +りょかん +りょくちゃ +りょこう +りりく +りれき +りろん +りんご +るいけい +るいさい +るいじ +るいせき +るすばん +るりがわら +れいかん +れいぎ +れいせい +れいぞうこ +れいとう +れいぼう +れきし +れきだい +れんあい +れんけい +れんこん +れんさい +れんしゅう +れんぞく +れんらく +ろうか +ろうご +ろうじん +ろうそく +ろくが +ろこつ +ろじうら +ろしゅつ +ろせん +ろてん +ろめん +ろれつ +ろんぎ +ろんぱ +ろんぶん +ろんり +わかす +わかめ +わかやま +わかれる +わしつ +わじまし +わすれもの +わらう +われる diff --git a/keys/wordlist/spanish.txt b/keys/wordlist/spanish.txt new file mode 100644 index 000000000..d0900c2c7 --- /dev/null +++ b/keys/wordlist/spanish.txt @@ -0,0 +1,2048 @@ +ábaco +abdomen +abeja +abierto +abogado +abono +aborto +abrazo +abrir +abuelo +abuso +acabar +academia +acceso +acción +aceite +acelga +acento +aceptar +ácido +aclarar +acné +acoger +acoso +activo +acto +actriz +actuar +acudir +acuerdo +acusar +adicto +admitir +adoptar +adorno +aduana +adulto +aéreo +afectar +afición +afinar +afirmar +ágil +agitar +agonía +agosto +agotar +agregar +agrio +agua +agudo +águila +aguja +ahogo +ahorro +aire +aislar +ajedrez +ajeno +ajuste +alacrán +alambre +alarma +alba +álbum +alcalde +aldea +alegre +alejar +alerta +aleta +alfiler +alga +algodón +aliado +aliento +alivio +alma +almeja +almíbar +altar +alteza +altivo +alto +altura +alumno +alzar +amable +amante +amapola +amargo +amasar +ámbar +ámbito +ameno +amigo +amistad +amor +amparo +amplio +ancho +anciano +ancla +andar +andén +anemia +ángulo +anillo +ánimo +anís +anotar +antena +antiguo +antojo +anual +anular +anuncio +añadir +añejo +año +apagar +aparato +apetito +apio +aplicar +apodo +aporte +apoyo +aprender +aprobar +apuesta +apuro +arado +araña +arar +árbitro +árbol +arbusto +archivo +arco +arder +ardilla +arduo +área +árido +aries +armonía +arnés +aroma +arpa +arpón +arreglo +arroz +arruga +arte +artista +asa +asado +asalto +ascenso +asegurar +aseo +asesor +asiento +asilo +asistir +asno +asombro +áspero +astilla +astro +astuto +asumir +asunto +atajo +ataque +atar +atento +ateo +ático +atleta +átomo +atraer +atroz +atún +audaz +audio +auge +aula +aumento +ausente +autor +aval +avance +avaro +ave +avellana +avena +avestruz +avión +aviso +ayer +ayuda +ayuno +azafrán +azar +azote +azúcar +azufre +azul +baba +babor +bache +bahía +baile +bajar +balanza +balcón +balde +bambú +banco +banda +baño +barba +barco +barniz +barro +báscula +bastón +basura +batalla +batería +batir +batuta +baúl +bazar +bebé +bebida +bello +besar +beso +bestia +bicho +bien +bingo +blanco +bloque +blusa +boa +bobina +bobo +boca +bocina +boda +bodega +boina +bola +bolero +bolsa +bomba +bondad +bonito +bono +bonsái +borde +borrar +bosque +bote +botín +bóveda +bozal +bravo +brazo +brecha +breve +brillo +brinco +brisa +broca +broma +bronce +brote +bruja +brusco +bruto +buceo +bucle +bueno +buey +bufanda +bufón +búho +buitre +bulto +burbuja +burla +burro +buscar +butaca +buzón +caballo +cabeza +cabina +cabra +cacao +cadáver +cadena +caer +café +caída +caimán +caja +cajón +cal +calamar +calcio +caldo +calidad +calle +calma +calor +calvo +cama +cambio +camello +camino +campo +cáncer +candil +canela +canguro +canica +canto +caña +cañón +caoba +caos +capaz +capitán +capote +captar +capucha +cara +carbón +cárcel +careta +carga +cariño +carne +carpeta +carro +carta +casa +casco +casero +caspa +castor +catorce +catre +caudal +causa +cazo +cebolla +ceder +cedro +celda +célebre +celoso +célula +cemento +ceniza +centro +cerca +cerdo +cereza +cero +cerrar +certeza +césped +cetro +chacal +chaleco +champú +chancla +chapa +charla +chico +chiste +chivo +choque +choza +chuleta +chupar +ciclón +ciego +cielo +cien +cierto +cifra +cigarro +cima +cinco +cine +cinta +ciprés +circo +ciruela +cisne +cita +ciudad +clamor +clan +claro +clase +clave +cliente +clima +clínica +cobre +cocción +cochino +cocina +coco +código +codo +cofre +coger +cohete +cojín +cojo +cola +colcha +colegio +colgar +colina +collar +colmo +columna +combate +comer +comida +cómodo +compra +conde +conejo +conga +conocer +consejo +contar +copa +copia +corazón +corbata +corcho +cordón +corona +correr +coser +cosmos +costa +cráneo +cráter +crear +crecer +creído +crema +cría +crimen +cripta +crisis +cromo +crónica +croqueta +crudo +cruz +cuadro +cuarto +cuatro +cubo +cubrir +cuchara +cuello +cuento +cuerda +cuesta +cueva +cuidar +culebra +culpa +culto +cumbre +cumplir +cuna +cuneta +cuota +cupón +cúpula +curar +curioso +curso +curva +cutis +dama +danza +dar +dardo +dátil +deber +débil +década +decir +dedo +defensa +definir +dejar +delfín +delgado +delito +demora +denso +dental +deporte +derecho +derrota +desayuno +deseo +desfile +desnudo +destino +desvío +detalle +detener +deuda +día +diablo +diadema +diamante +diana +diario +dibujo +dictar +diente +dieta +diez +difícil +digno +dilema +diluir +dinero +directo +dirigir +disco +diseño +disfraz +diva +divino +doble +doce +dolor +domingo +don +donar +dorado +dormir +dorso +dos +dosis +dragón +droga +ducha +duda +duelo +dueño +dulce +dúo +duque +durar +dureza +duro +ébano +ebrio +echar +eco +ecuador +edad +edición +edificio +editor +educar +efecto +eficaz +eje +ejemplo +elefante +elegir +elemento +elevar +elipse +élite +elixir +elogio +eludir +embudo +emitir +emoción +empate +empeño +empleo +empresa +enano +encargo +enchufe +encía +enemigo +enero +enfado +enfermo +engaño +enigma +enlace +enorme +enredo +ensayo +enseñar +entero +entrar +envase +envío +época +equipo +erizo +escala +escena +escolar +escribir +escudo +esencia +esfera +esfuerzo +espada +espejo +espía +esposa +espuma +esquí +estar +este +estilo +estufa +etapa +eterno +ética +etnia +evadir +evaluar +evento +evitar +exacto +examen +exceso +excusa +exento +exigir +exilio +existir +éxito +experto +explicar +exponer +extremo +fábrica +fábula +fachada +fácil +factor +faena +faja +falda +fallo +falso +faltar +fama +familia +famoso +faraón +farmacia +farol +farsa +fase +fatiga +fauna +favor +fax +febrero +fecha +feliz +feo +feria +feroz +fértil +fervor +festín +fiable +fianza +fiar +fibra +ficción +ficha +fideo +fiebre +fiel +fiera +fiesta +figura +fijar +fijo +fila +filete +filial +filtro +fin +finca +fingir +finito +firma +flaco +flauta +flecha +flor +flota +fluir +flujo +flúor +fobia +foca +fogata +fogón +folio +folleto +fondo +forma +forro +fortuna +forzar +fosa +foto +fracaso +frágil +franja +frase +fraude +freír +freno +fresa +frío +frito +fruta +fuego +fuente +fuerza +fuga +fumar +función +funda +furgón +furia +fusil +fútbol +futuro +gacela +gafas +gaita +gajo +gala +galería +gallo +gamba +ganar +gancho +ganga +ganso +garaje +garza +gasolina +gastar +gato +gavilán +gemelo +gemir +gen +género +genio +gente +geranio +gerente +germen +gesto +gigante +gimnasio +girar +giro +glaciar +globo +gloria +gol +golfo +goloso +golpe +goma +gordo +gorila +gorra +gota +goteo +gozar +grada +gráfico +grano +grasa +gratis +grave +grieta +grillo +gripe +gris +grito +grosor +grúa +grueso +grumo +grupo +guante +guapo +guardia +guerra +guía +guiño +guion +guiso +guitarra +gusano +gustar +haber +hábil +hablar +hacer +hacha +hada +hallar +hamaca +harina +haz +hazaña +hebilla +hebra +hecho +helado +helio +hembra +herir +hermano +héroe +hervir +hielo +hierro +hígado +higiene +hijo +himno +historia +hocico +hogar +hoguera +hoja +hombre +hongo +honor +honra +hora +hormiga +horno +hostil +hoyo +hueco +huelga +huerta +hueso +huevo +huida +huir +humano +húmedo +humilde +humo +hundir +huracán +hurto +icono +ideal +idioma +ídolo +iglesia +iglú +igual +ilegal +ilusión +imagen +imán +imitar +impar +imperio +imponer +impulso +incapaz +índice +inerte +infiel +informe +ingenio +inicio +inmenso +inmune +innato +insecto +instante +interés +íntimo +intuir +inútil +invierno +ira +iris +ironía +isla +islote +jabalí +jabón +jamón +jarabe +jardín +jarra +jaula +jazmín +jefe +jeringa +jinete +jornada +joroba +joven +joya +juerga +jueves +juez +jugador +jugo +juguete +juicio +junco +jungla +junio +juntar +júpiter +jurar +justo +juvenil +juzgar +kilo +koala +labio +lacio +lacra +lado +ladrón +lagarto +lágrima +laguna +laico +lamer +lámina +lámpara +lana +lancha +langosta +lanza +lápiz +largo +larva +lástima +lata +látex +latir +laurel +lavar +lazo +leal +lección +leche +lector +leer +legión +legumbre +lejano +lengua +lento +leña +león +leopardo +lesión +letal +letra +leve +leyenda +libertad +libro +licor +líder +lidiar +lienzo +liga +ligero +lima +límite +limón +limpio +lince +lindo +línea +lingote +lino +linterna +líquido +liso +lista +litera +litio +litro +llaga +llama +llanto +llave +llegar +llenar +llevar +llorar +llover +lluvia +lobo +loción +loco +locura +lógica +logro +lombriz +lomo +lonja +lote +lucha +lucir +lugar +lujo +luna +lunes +lupa +lustro +luto +luz +maceta +macho +madera +madre +maduro +maestro +mafia +magia +mago +maíz +maldad +maleta +malla +malo +mamá +mambo +mamut +manco +mando +manejar +manga +maniquí +manjar +mano +manso +manta +mañana +mapa +máquina +mar +marco +marea +marfil +margen +marido +mármol +marrón +martes +marzo +masa +máscara +masivo +matar +materia +matiz +matriz +máximo +mayor +mazorca +mecha +medalla +medio +médula +mejilla +mejor +melena +melón +memoria +menor +mensaje +mente +menú +mercado +merengue +mérito +mes +mesón +meta +meter +método +metro +mezcla +miedo +miel +miembro +miga +mil +milagro +militar +millón +mimo +mina +minero +mínimo +minuto +miope +mirar +misa +miseria +misil +mismo +mitad +mito +mochila +moción +moda +modelo +moho +mojar +molde +moler +molino +momento +momia +monarca +moneda +monja +monto +moño +morada +morder +moreno +morir +morro +morsa +mortal +mosca +mostrar +motivo +mover +móvil +mozo +mucho +mudar +mueble +muela +muerte +muestra +mugre +mujer +mula +muleta +multa +mundo +muñeca +mural +muro +músculo +museo +musgo +música +muslo +nácar +nación +nadar +naipe +naranja +nariz +narrar +nasal +natal +nativo +natural +náusea +naval +nave +navidad +necio +néctar +negar +negocio +negro +neón +nervio +neto +neutro +nevar +nevera +nicho +nido +niebla +nieto +niñez +niño +nítido +nivel +nobleza +noche +nómina +noria +norma +norte +nota +noticia +novato +novela +novio +nube +nuca +núcleo +nudillo +nudo +nuera +nueve +nuez +nulo +número +nutria +oasis +obeso +obispo +objeto +obra +obrero +observar +obtener +obvio +oca +ocaso +océano +ochenta +ocho +ocio +ocre +octavo +octubre +oculto +ocupar +ocurrir +odiar +odio +odisea +oeste +ofensa +oferta +oficio +ofrecer +ogro +oído +oír +ojo +ola +oleada +olfato +olivo +olla +olmo +olor +olvido +ombligo +onda +onza +opaco +opción +ópera +opinar +oponer +optar +óptica +opuesto +oración +orador +oral +órbita +orca +orden +oreja +órgano +orgía +orgullo +oriente +origen +orilla +oro +orquesta +oruga +osadía +oscuro +osezno +oso +ostra +otoño +otro +oveja +óvulo +óxido +oxígeno +oyente +ozono +pacto +padre +paella +página +pago +país +pájaro +palabra +palco +paleta +pálido +palma +paloma +palpar +pan +panal +pánico +pantera +pañuelo +papá +papel +papilla +paquete +parar +parcela +pared +parir +paro +párpado +parque +párrafo +parte +pasar +paseo +pasión +paso +pasta +pata +patio +patria +pausa +pauta +pavo +payaso +peatón +pecado +pecera +pecho +pedal +pedir +pegar +peine +pelar +peldaño +pelea +peligro +pellejo +pelo +peluca +pena +pensar +peñón +peón +peor +pepino +pequeño +pera +percha +perder +pereza +perfil +perico +perla +permiso +perro +persona +pesa +pesca +pésimo +pestaña +pétalo +petróleo +pez +pezuña +picar +pichón +pie +piedra +pierna +pieza +pijama +pilar +piloto +pimienta +pino +pintor +pinza +piña +piojo +pipa +pirata +pisar +piscina +piso +pista +pitón +pizca +placa +plan +plata +playa +plaza +pleito +pleno +plomo +pluma +plural +pobre +poco +poder +podio +poema +poesía +poeta +polen +policía +pollo +polvo +pomada +pomelo +pomo +pompa +poner +porción +portal +posada +poseer +posible +poste +potencia +potro +pozo +prado +precoz +pregunta +premio +prensa +preso +previo +primo +príncipe +prisión +privar +proa +probar +proceso +producto +proeza +profesor +programa +prole +promesa +pronto +propio +próximo +prueba +público +puchero +pudor +pueblo +puerta +puesto +pulga +pulir +pulmón +pulpo +pulso +puma +punto +puñal +puño +pupa +pupila +puré +quedar +queja +quemar +querer +queso +quieto +química +quince +quitar +rábano +rabia +rabo +ración +radical +raíz +rama +rampa +rancho +rango +rapaz +rápido +rapto +rasgo +raspa +rato +rayo +raza +razón +reacción +realidad +rebaño +rebote +recaer +receta +rechazo +recoger +recreo +recto +recurso +red +redondo +reducir +reflejo +reforma +refrán +refugio +regalo +regir +regla +regreso +rehén +reino +reír +reja +relato +relevo +relieve +relleno +reloj +remar +remedio +remo +rencor +rendir +renta +reparto +repetir +reposo +reptil +res +rescate +resina +respeto +resto +resumen +retiro +retorno +retrato +reunir +revés +revista +rey +rezar +rico +riego +rienda +riesgo +rifa +rígido +rigor +rincón +riñón +río +riqueza +risa +ritmo +rito +rizo +roble +roce +rociar +rodar +rodeo +rodilla +roer +rojizo +rojo +romero +romper +ron +ronco +ronda +ropa +ropero +rosa +rosca +rostro +rotar +rubí +rubor +rudo +rueda +rugir +ruido +ruina +ruleta +rulo +rumbo +rumor +ruptura +ruta +rutina +sábado +saber +sabio +sable +sacar +sagaz +sagrado +sala +saldo +salero +salir +salmón +salón +salsa +salto +salud +salvar +samba +sanción +sandía +sanear +sangre +sanidad +sano +santo +sapo +saque +sardina +sartén +sastre +satán +sauna +saxofón +sección +seco +secreto +secta +sed +seguir +seis +sello +selva +semana +semilla +senda +sensor +señal +señor +separar +sepia +sequía +ser +serie +sermón +servir +sesenta +sesión +seta +setenta +severo +sexo +sexto +sidra +siesta +siete +siglo +signo +sílaba +silbar +silencio +silla +símbolo +simio +sirena +sistema +sitio +situar +sobre +socio +sodio +sol +solapa +soldado +soledad +sólido +soltar +solución +sombra +sondeo +sonido +sonoro +sonrisa +sopa +soplar +soporte +sordo +sorpresa +sorteo +sostén +sótano +suave +subir +suceso +sudor +suegra +suelo +sueño +suerte +sufrir +sujeto +sultán +sumar +superar +suplir +suponer +supremo +sur +surco +sureño +surgir +susto +sutil +tabaco +tabique +tabla +tabú +taco +tacto +tajo +talar +talco +talento +talla +talón +tamaño +tambor +tango +tanque +tapa +tapete +tapia +tapón +taquilla +tarde +tarea +tarifa +tarjeta +tarot +tarro +tarta +tatuaje +tauro +taza +tazón +teatro +techo +tecla +técnica +tejado +tejer +tejido +tela +teléfono +tema +temor +templo +tenaz +tender +tener +tenis +tenso +teoría +terapia +terco +término +ternura +terror +tesis +tesoro +testigo +tetera +texto +tez +tibio +tiburón +tiempo +tienda +tierra +tieso +tigre +tijera +tilde +timbre +tímido +timo +tinta +tío +típico +tipo +tira +tirón +titán +títere +título +tiza +toalla +tobillo +tocar +tocino +todo +toga +toldo +tomar +tono +tonto +topar +tope +toque +tórax +torero +tormenta +torneo +toro +torpedo +torre +torso +tortuga +tos +tosco +toser +tóxico +trabajo +tractor +traer +tráfico +trago +traje +tramo +trance +trato +trauma +trazar +trébol +tregua +treinta +tren +trepar +tres +tribu +trigo +tripa +triste +triunfo +trofeo +trompa +tronco +tropa +trote +trozo +truco +trueno +trufa +tubería +tubo +tuerto +tumba +tumor +túnel +túnica +turbina +turismo +turno +tutor +ubicar +úlcera +umbral +unidad +unir +universo +uno +untar +uña +urbano +urbe +urgente +urna +usar +usuario +útil +utopía +uva +vaca +vacío +vacuna +vagar +vago +vaina +vajilla +vale +válido +valle +valor +válvula +vampiro +vara +variar +varón +vaso +vecino +vector +vehículo +veinte +vejez +vela +velero +veloz +vena +vencer +venda +veneno +vengar +venir +venta +venus +ver +verano +verbo +verde +vereda +verja +verso +verter +vía +viaje +vibrar +vicio +víctima +vida +vídeo +vidrio +viejo +viernes +vigor +vil +villa +vinagre +vino +viñedo +violín +viral +virgo +virtud +visor +víspera +vista +vitamina +viudo +vivaz +vivero +vivir +vivo +volcán +volumen +volver +voraz +votar +voto +voz +vuelo +vulgar +yacer +yate +yegua +yema +yerno +yeso +yodo +yoga +yogur +zafiro +zanja +zapato +zarza +zona +zorro +zumo +zurdo From daab270ff71646ded0dc8337021aa2fa8814079d Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 17:02:28 +0200 Subject: [PATCH 093/287] First obvious speedup --- keys/wordcodec.go | 14 +++++++------- keys/wordcodec_test.go | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/keys/wordcodec.go b/keys/wordcodec.go index 5ac32f812..d4c7bce2a 100644 --- a/keys/wordcodec.go +++ b/keys/wordcodec.go @@ -24,14 +24,14 @@ type WordCodec struct { check ECC } -var _ Codec = WordCodec{} +var _ Codec = &WordCodec{} -func NewCodec(words []string) (codec WordCodec, err error) { +func NewCodec(words []string) (codec *WordCodec, err error) { if len(words) != BankSize { return codec, errors.Errorf("Bank must have %d words, found %d", BankSize, len(words)) } - res := WordCodec{ + res := &WordCodec{ words: words, // TODO: configure this outside??? check: NewIEEECRC32(), @@ -40,7 +40,7 @@ func NewCodec(words []string) (codec WordCodec, err error) { return res, nil } -func LoadCodec(bank string) (codec WordCodec, err error) { +func LoadCodec(bank string) (codec *WordCodec, err error) { words, err := loadBank(bank) if err != nil { return codec, err @@ -96,7 +96,7 @@ func bytelenFromWords(numWords int) (length int, maybeShorter bool) { } // TODO: add checksum -func (c WordCodec) BytesToWords(raw []byte) (words []string, err error) { +func (c *WordCodec) BytesToWords(raw []byte) (words []string, err error) { // always add a checksum to the data data := c.check.AddECC(raw) numWords := wordlenFromBytes(len(data)) @@ -120,7 +120,7 @@ func (c WordCodec) BytesToWords(raw []byte) (words []string, err error) { return words, nil } -func (c WordCodec) WordsToBytes(words []string) ([]byte, error) { +func (c *WordCodec) WordsToBytes(words []string) ([]byte, error) { l := len(words) if l == 0 { @@ -167,7 +167,7 @@ func (c WordCodec) WordsToBytes(words []string) ([]byte, error) { // GetIndex finds the index of the words to create bytes // Generates a map the first time it is loaded, to avoid needless // computation when list is not used. -func (c WordCodec) GetIndex(word string) (int, error) { +func (c *WordCodec) GetIndex(word string) (int, error) { // generate the first time if c.bytes == nil { b := map[string]int{} diff --git a/keys/wordcodec_test.go b/keys/wordcodec_test.go index c3a5a2cac..3bdec110f 100644 --- a/keys/wordcodec_test.go +++ b/keys/wordcodec_test.go @@ -130,12 +130,12 @@ func TestCheckInvalidLists(t *testing.T) { } -func getRandWord(c WordCodec) string { +func getRandWord(c *WordCodec) string { idx := cmn.RandInt() % BankSize return c.words[idx] } -func getDiffWord(c WordCodec, not string) string { +func getDiffWord(c *WordCodec, not string) string { w := getRandWord(c) if w == not { w = getRandWord(c) @@ -151,7 +151,7 @@ func TestCheckTypoDetection(t *testing.T) { for _, bank := range banks { codec, err := LoadCodec(bank) require.Nil(err, "%s: %+v", bank, err) - for i := 0; i < 10; i++ { + for i := 0; i < 1000; i++ { numBytes := cmn.RandInt()%60 + 1 data := cmn.RandBytes(numBytes) @@ -177,5 +177,34 @@ func TestCheckTypoDetection(t *testing.T) { assert.NotNil(err, "%s: %s", bank, words) } } +} + +func warmupCodec(bank string) *WordCodec { + codec, err := LoadCodec(bank) + if err != nil { + panic(err) + } + _, err = codec.GetIndex(codec.words[123]) + if err != nil { + panic(err) + } + return codec +} +func BenchmarkWordGeneration(b *testing.B) { + // banks := []string{"english", "spanish", "japanese", "chinese_simplified"} + bank := "english" + + codec := warmupCodec(bank) + b.ResetTimer() + + numBytes := 32 + data := cmn.RandBytes(numBytes) + + for i := 1; i <= b.N; i++ { + _, err := codec.BytesToWords(data) + if err != nil { + panic(err) + } + } } From 1e15c8f75b599f6f3032d1c10efccd78e7bea3f3 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 17:13:10 +0200 Subject: [PATCH 094/287] Extend wordcodec benchmarks --- keys/wordcodec_test.go | 30 ---------------- keys/wordcodecbench_test.go | 68 +++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 30 deletions(-) create mode 100644 keys/wordcodecbench_test.go diff --git a/keys/wordcodec_test.go b/keys/wordcodec_test.go index 3bdec110f..1ae97d8a7 100644 --- a/keys/wordcodec_test.go +++ b/keys/wordcodec_test.go @@ -178,33 +178,3 @@ func TestCheckTypoDetection(t *testing.T) { } } } - -func warmupCodec(bank string) *WordCodec { - codec, err := LoadCodec(bank) - if err != nil { - panic(err) - } - _, err = codec.GetIndex(codec.words[123]) - if err != nil { - panic(err) - } - return codec -} - -func BenchmarkWordGeneration(b *testing.B) { - // banks := []string{"english", "spanish", "japanese", "chinese_simplified"} - bank := "english" - - codec := warmupCodec(bank) - b.ResetTimer() - - numBytes := 32 - data := cmn.RandBytes(numBytes) - - for i := 1; i <= b.N; i++ { - _, err := codec.BytesToWords(data) - if err != nil { - panic(err) - } - } -} diff --git a/keys/wordcodecbench_test.go b/keys/wordcodecbench_test.go new file mode 100644 index 000000000..e100a443a --- /dev/null +++ b/keys/wordcodecbench_test.go @@ -0,0 +1,68 @@ +package keys + +import ( + "testing" + + cmn "github.com/tendermint/tmlibs/common" +) + +func warmupCodec(bank string) *WordCodec { + codec, err := LoadCodec(bank) + if err != nil { + panic(err) + } + _, err = codec.GetIndex(codec.words[123]) + if err != nil { + panic(err) + } + return codec +} + +func BenchmarkCodec(b *testing.B) { + banks := []string{"english", "spanish", "japanese", "chinese_simplified"} + + for _, bank := range banks { + b.Run(bank, func(sub *testing.B) { + codec := warmupCodec(bank) + sub.ResetTimer() + benchSuite(sub, codec) + }) + } +} + +func benchSuite(b *testing.B, codec *WordCodec) { + b.Run("to_words", func(sub *testing.B) { + benchMakeWords(sub, codec) + }) + b.Run("to_bytes", func(sub *testing.B) { + benchParseWords(sub, codec) + }) +} + +func benchMakeWords(b *testing.B, codec *WordCodec) { + numBytes := 32 + data := cmn.RandBytes(numBytes) + for i := 1; i <= b.N; i++ { + _, err := codec.BytesToWords(data) + if err != nil { + panic(err) + } + } +} + +func benchParseWords(b *testing.B, codec *WordCodec) { + // generate a valid test string to parse + numBytes := 32 + data := cmn.RandBytes(numBytes) + words, err := codec.BytesToWords(data) + if err != nil { + panic(err) + } + + for i := 1; i <= b.N; i++ { + _, err := codec.WordsToBytes(words) + if err != nil { + panic(err) + } + } +} From 878c8b3a876286d78aa96699f122b2a490f6ba23 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 17:51:25 +0200 Subject: [PATCH 095/287] Removed obsolete file --- keys/Makefile | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 keys/Makefile diff --git a/keys/Makefile b/keys/Makefile deleted file mode 100644 index 63eb70787..000000000 --- a/keys/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -GOTOOLS = \ - github.com/mitchellh/gox \ - github.com/Masterminds/glide - -.PHONEY: all test install get_vendor_deps ensure_tools - -all: install test - -test: - go test `glide novendor` - -install: - go install ./cmd/keys - -get_vendor_deps: ensure_tools - @rm -rf vendor/ - @echo "--> Running glide install" - @glide install - -ensure_tools: - go get $(GOTOOLS) - From 56200e167a9e3158a0a3287082029e64c10807e3 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 18:03:17 +0200 Subject: [PATCH 096/287] Use go-bindata to embed wordlist in a binary --- Makefile | 8 +- keys/wordcodec.go | 40 ++--- keys/wordlist/wordlist.go | 308 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 334 insertions(+), 22 deletions(-) create mode 100644 keys/wordlist/wordlist.go diff --git a/Makefile b/Makefile index e40d0e6ff..537b6396f 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ -.PHONEY: all docs test install get_vendor_deps ensure_tools codegen +.PHONEY: all docs test install get_vendor_deps ensure_tools codegen wordlist GOTOOLS = \ - github.com/Masterminds/glide + github.com/Masterminds/glide \ + github.com/jteeuwen/go-bindata/go-bindata REPO:=github.com/tendermint/go-crypto docs: @@ -35,6 +36,9 @@ get_vendor_deps: ensure_tools ensure_tools: go get $(GOTOOLS) +wordlist: + go-bindata -ignore ".*\.go" -o keys/wordlist/wordlist.go -pkg "wordlist" keys/wordlist/... + prepgen: install go install ./vendor/github.com/btcsuite/btcutil/base58 go install ./vendor/github.com/stretchr/testify/assert diff --git a/keys/wordcodec.go b/keys/wordcodec.go index d4c7bce2a..f66d1e983 100644 --- a/keys/wordcodec.go +++ b/keys/wordcodec.go @@ -1,12 +1,12 @@ package keys import ( - "io/ioutil" "math/big" - "os" "strings" "github.com/pkg/errors" + + "github.com/tendermint/go-crypto/keys/wordlist" ) const BankSize = 2048 @@ -50,30 +50,30 @@ func LoadCodec(bank string) (codec *WordCodec, err error) { // loadBank opens a wordlist file and returns all words inside func loadBank(bank string) ([]string, error) { - filename := "wordlist/" + bank + ".txt" - words, err := getData(filename) + filename := "keys/wordlist/" + bank + ".txt" + words, err := wordlist.Asset(filename) if err != nil { return nil, err } - wordsAll := strings.Split(strings.TrimSpace(words), "\n") + wordsAll := strings.Split(strings.TrimSpace(string(words)), "\n") return wordsAll, nil } -// TODO: read from go-bind assets -func getData(filename string) (string, error) { - f, err := os.Open(filename) - if err != nil { - return "", errors.WithStack(err) - } - defer f.Close() - - data, err := ioutil.ReadAll(f) - if err != nil { - return "", errors.WithStack(err) - } - - return string(data), nil -} +// // TODO: read from go-bind assets +// func getData(filename string) (string, error) { +// f, err := os.Open(filename) +// if err != nil { +// return "", errors.WithStack(err) +// } +// defer f.Close() + +// data, err := ioutil.ReadAll(f) +// if err != nil { +// return "", errors.WithStack(err) +// } + +// return string(data), nil +// } // given this many bytes, we will produce this many words func wordlenFromBytes(numBytes int) int { diff --git a/keys/wordlist/wordlist.go b/keys/wordlist/wordlist.go new file mode 100644 index 000000000..97ddb2369 --- /dev/null +++ b/keys/wordlist/wordlist.go @@ -0,0 +1,308 @@ +// Code generated by go-bindata. +// sources: +// keys/wordlist/chinese_simplified.txt +// keys/wordlist/english.txt +// keys/wordlist/japanese.txt +// keys/wordlist/spanish.txt +// DO NOT EDIT! + +package wordlist + +import ( + "bytes" + "compress/gzip" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" +) + +func bindataRead(data []byte, name string) ([]byte, error) { + gz, err := gzip.NewReader(bytes.NewBuffer(data)) + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + + var buf bytes.Buffer + _, err = io.Copy(&buf, gz) + clErr := gz.Close() + + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + if clErr != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +type asset struct { + bytes []byte + info os.FileInfo +} + +type bindataFileInfo struct { + name string + size int64 + mode os.FileMode + modTime time.Time +} + +func (fi bindataFileInfo) Name() string { + return fi.name +} +func (fi bindataFileInfo) Size() int64 { + return fi.size +} +func (fi bindataFileInfo) Mode() os.FileMode { + return fi.mode +} +func (fi bindataFileInfo) ModTime() time.Time { + return fi.modTime +} +func (fi bindataFileInfo) IsDir() bool { + return false +} +func (fi bindataFileInfo) Sys() interface{} { + return nil +} + +var _keysWordlistChinese_simplifiedTxt = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x1c\x97\x55\x76\xeb\x30\x14\x45\xff\xf7\xa8\xc3\xcc\x49\xc3\x69\x98\xda\x86\xd9\x0e\x4c\xc6\xf7\x4a\x9a\xc5\x5b\x7e\x7f\x5d\x5d\x6d\x6c\x45\x07\xf6\x31\xdd\x04\xc1\x3d\x82\xb6\x77\x48\x7f\x45\x70\x2f\x12\x78\x29\xb4\x9f\x45\x6a\x05\x02\xcf\xc3\x7e\x3a\x04\xf7\x0d\x32\x5b\x12\xdc\x3d\x82\x7b\x8e\xe0\xfe\x83\xf4\x5e\x68\xa6\x4a\xe0\xcf\xb1\x8b\x28\x81\xdf\x44\x5b\x57\x74\x30\xc7\x34\x56\x04\xfe\x1f\xa6\x31\x44\x32\x7b\x82\x57\x1f\xe9\xef\x09\xbc\x12\x92\xf6\x90\xfd\x01\xc9\xa4\x90\xdd\x03\xcd\x54\x08\x9e\x5d\xa4\xbc\x23\xb8\xfb\x48\xb9\x8a\x3c\xce\x48\x6e\x85\x54\x0a\xc8\x6d\x4e\xf0\x18\x62\xe3\x2f\x82\x7b\x1e\xfb\x49\x23\x9b\x0a\x76\x77\x26\xf0\x96\x98\x65\x11\x37\x98\x60\x23\x05\xb4\xf9\x40\x2a\x25\x64\xd6\x45\xb6\x5d\xec\xb8\x80\x6c\x16\xe8\xe9\x0b\xcd\x46\xd0\x7d\x15\x79\xb7\x30\x7e\x19\x29\x46\x09\xee\x59\x82\x47\xf8\x99\x3d\xcc\x20\x82\xd9\x64\x71\xf1\x15\xe2\x2d\x90\xed\x15\xd3\xb8\x20\xb9\x1e\x2e\x5d\x40\x16\x31\x74\x7f\x46\x0a\x4d\xdc\x6f\x1b\x9b\xfe\x21\xf0\x0a\x98\x4a\x0a\x7b\xb9\x21\xfb\x32\x26\xbb\xc6\x94\xf6\xc8\xf6\x1b\xc9\x8d\x70\xe9\x32\xee\xff\x7b\xcf\x08\x5e\x75\x24\x73\x45\xfb\x1e\xf2\xaa\x13\xbc\x3e\x98\xd8\x83\xc0\x2f\x11\xdc\xbb\x68\xff\x0f\x29\xf9\x68\x2e\x87\x46\x96\xc8\xfc\x85\x78\x0d\xe4\x19\x41\xb6\x71\xa4\x92\xc1\x7e\xda\x48\x6f\x84\x69\x1c\x90\xe4\x95\xc0\xeb\x61\x12\x57\x24\x5b\x44\x66\x4d\x64\xb6\x46\x1b\x1f\xa4\xd7\x43\x5b\x73\x5c\x6c\x8a\x99\xbd\x09\x1e\x59\x02\x2f\x8f\x3c\x4e\xc8\x6b\x82\xe9\xdd\x91\xe4\x0a\x3b\x5e\xe1\x5a\x67\x74\x74\x23\xb8\x97\x90\xe4\x09\xa9\x24\x70\xe9\x22\xda\xdc\x63\xbc\x0f\x92\x4a\xa2\x5f\x7b\x74\x33\x45\x3e\x71\xa4\x5c\x24\x78\x8d\xd0\x76\x09\xd3\xcf\x23\xa5\x21\x52\xce\x10\x3c\x32\x48\x66\x8d\xee\x1a\x68\xa6\x49\xf0\x4a\x61\xcf\x2b\x74\xdf\xc0\xfc\xfd\x21\x95\x2a\x2e\x5a\x47\xaa\x2f\x74\x33\x43\xca\x6d\x74\x30\x46\xca\x3f\xe8\x71\x8c\xf1\xeb\xd8\xe5\x14\xd7\xda\xa2\x89\x32\xe2\x7b\x68\x3f\x83\x24\xff\xd0\xd6\x08\x73\xf2\x91\x54\x0f\x79\x67\xd0\x78\x12\x1b\x49\xa2\xfd\x08\xe6\x37\x4f\xe0\x4f\xd1\xf8\x09\xb9\x1d\x71\x91\x2e\xf2\xb8\xa2\xe5\x0a\xa6\x77\xc6\x4d\xda\x48\xb2\x8b\x59\xe5\x91\xc3\x17\x81\xd7\x40\xbf\xfb\x68\xb3\x83\x3d\x8c\x91\x6a\x1b\x37\x58\x13\xbc\x8a\x48\x72\x8e\xdc\xef\x68\x33\x8d\x46\x7c\xf4\x6f\x8c\xd4\xa3\xc8\xb3\x8c\x9e\x7d\xec\xf6\x8d\x94\x73\x98\xed\x18\x93\x0d\xef\xee\x8a\xfb\xfa\xa0\x87\x18\x36\x12\x45\x66\x67\x64\xe8\x61\x2f\x09\xec\xfb\x81\x5e\xa2\xd8\xdb\x0e\xe3\x2d\x91\x50\x7b\xbd\x37\x72\x38\x60\xfc\x21\x5a\x9a\x63\x86\x73\xec\x3b\x8e\xec\x53\x18\x3f\x81\x5d\x46\xb1\xdb\x31\x92\xf9\x45\xe6\x0f\x34\x9b\xc7\x2e\x6b\x68\x7f\x88\x8e\x1e\xd8\x6d\xe8\xc7\x0a\x92\xea\xa3\x85\x34\x92\x1e\x11\x3c\x06\x48\xc1\x43\x9e\x1e\xda\x78\x23\xa9\x13\x76\xfe\xc1\x4e\x7e\x91\xc7\x11\x89\x76\x91\x4f\x12\xcd\x84\xdf\x43\x06\xe9\x7d\x23\x99\x0e\x81\x1f\x7a\xad\x89\x16\xb7\xc8\x2c\x81\x6b\x0f\x91\x62\xe8\x8d\x0e\x36\x7b\x44\x92\x59\x5c\x6b\x85\x14\x4f\x04\x9f\x01\x7a\xf4\x91\x42\x0b\x17\x19\x61\x3a\x6f\xec\x32\x81\x89\x6f\x70\x93\x14\xc1\x3d\x8e\x86\x1e\x28\x4f\x09\xee\x7d\x64\xf7\x44\x3a\x2b\xa4\x94\x47\x3e\x2d\x82\x7b\x13\x97\xae\x22\x93\x6f\x02\x2f\x8b\x5e\x4a\xb8\xf6\x15\x3d\x3e\xd0\xc8\x00\xed\xef\xd0\xef\x28\x81\x17\xea\xa2\x85\x8d\x36\x08\xfc\x08\x76\x3b\x43\x92\x1b\x24\x79\x40\x07\x71\xb4\x71\xc5\xee\xa2\x68\xe3\x81\xde\x93\x98\x77\x09\x49\x15\x71\xe9\x34\xf6\xf5\x87\xf6\xce\x48\xf1\x0b\x37\x2d\x21\x99\x34\x9a\xad\x63\x3a\x2f\xf4\xab\x83\x8b\x0c\xb1\xb9\x03\x72\x0f\xbd\x9d\x45\xfa\x1e\xd6\xfb\xc5\xbe\x16\x04\xef\x3c\xa6\x3f\x44\x72\x63\x24\x19\x7a\x21\x8d\xee\xca\x98\xde\x16\x9b\x3e\x61\xdf\x6f\xec\x65\x8f\x59\xee\x30\x33\x0f\xbb\xdd\x22\xd3\x3d\x9a\x9b\xa3\xcd\x16\xb2\x2d\x60\x0e\x3e\x92\xfc\xc5\x2c\x7c\xa4\x58\x42\x2a\x45\xcc\x78\x8b\x66\x8b\x98\x65\x15\x79\x8e\x08\x3e\x63\xdc\xfa\x0f\x9b\x8b\x61\x77\x03\xcc\xe1\x84\x7e\x9d\x31\x6b\x0f\x49\xc6\x91\xd4\x85\xc0\xcf\xe1\x7a\x29\xf4\xbe\x26\x78\x8e\x90\xfe\x10\xbb\xbd\xa3\x9b\x39\xe6\x3d\x43\x1e\x1f\xcc\xf0\x84\xdd\xee\x71\xfd\x08\xba\xbd\x60\x46\x0d\xcc\x57\x01\xcd\x67\xd1\xef\x16\xf2\xce\x23\xe5\x5f\x82\x7b\x03\xb3\xbe\x62\x97\x31\xec\x35\x87\xf1\xd3\xd8\x69\x12\x79\x1d\x30\xdb\x16\xc1\xab\x84\x16\xa2\xb8\xe1\x89\xe0\xd9\x22\x78\x2c\x90\x7b\x1c\x99\x15\x91\xed\x03\x49\x7c\x70\x63\x1f\xd7\x49\x22\x5f\x29\xdc\xe0\x1b\xf7\x53\xc0\x7e\xbe\xd1\xe6\x06\xbd\x1d\x70\xdd\x37\xf6\x53\xc5\x0c\x3f\x48\x31\x8e\x54\x57\xc8\xb2\x81\x39\x8f\xd0\x5c\x04\x99\xa5\x91\x62\x0e\xc9\x7d\xe3\x06\x35\x4c\x3f\x8a\x64\xc2\x67\x8d\x90\x7a\x11\xe3\x2d\xd0\xc6\x0e\x9b\xf9\x43\xca\x47\x34\x11\xde\xc3\x89\xe0\x1d\xe6\xd8\x04\x79\x47\x70\xc9\x3b\x52\x4a\x21\xf7\x18\x92\xcc\x13\xbc\xbe\x70\x9d\x19\x7a\xcd\xa0\xdf\x09\xc4\xeb\x63\x96\x7b\x64\xf6\x83\xa4\x53\x98\xe3\x1b\x89\x3c\x91\xf2\x0d\x53\x4a\xa3\xad\x32\xc6\x3f\x23\x99\x1a\x2e\x92\x45\x47\x69\x24\xd5\x41\x36\x6d\x24\xd2\x41\x77\x3d\x02\xef\x88\x7c\x7e\xd1\xaf\x0c\xda\xdc\xe1\x3a\x13\x74\x38\x47\x0f\x43\xe4\x3b\xd4\xc7\x13\x53\xca\xa3\x85\xf0\xff\x9f\x48\xd2\x47\xdb\x75\xcc\x6b\x8b\x9e\x43\x5f\xc7\x30\xd9\x34\xb2\xcc\x23\xc5\x33\xc1\xbd\x8e\xc9\x5d\xb1\xb1\x23\x52\x8a\x11\x78\x7f\xd8\x5d\x0a\x17\x89\x21\x87\x6f\xa4\x9f\x42\x0a\x49\x4c\xf4\x97\xe0\x55\xc6\xee\xe3\xa8\x3f\x46\x4a\x1f\xe4\x10\xc1\x24\x97\x48\x39\x86\xf1\x26\x18\x3f\x85\x3c\xbf\x90\x4a\xf8\x19\x73\x5c\x3d\xec\xdb\x50\xa7\x73\xdc\xa2\x89\x78\x5f\xe8\xf5\x88\x6c\xdb\xc8\xfb\x86\xeb\x96\x31\xad\x24\x36\x5f\x46\x66\x07\x64\xdf\x40\x37\x61\x7e\x1d\x71\xc9\x22\x32\x3f\xe1\xfc\x04\x5a\x5a\xa1\xed\x37\x76\x9f\xc1\xbc\x7e\x30\xf3\x6f\x6c\xd6\x43\xaa\x13\x24\xec\xfc\xca\x2f\xc1\x33\x8a\xf6\x7b\xc8\x2e\x85\x66\x1f\xd8\xca\x1c\x37\x7e\xe0\xda\x47\x82\xfb\x1b\x53\x89\x63\xf3\x07\x74\xbf\x44\x72\x1f\xa4\x9a\x43\x07\x25\xa4\xbc\xc7\x56\x5e\x68\x7f\x85\xdc\xb7\xd8\xd7\x16\x33\x0a\x3b\xbb\x8b\xdc\xc3\x1c\x3a\xa3\xa7\x15\xf6\xd3\x47\x36\x2d\x74\x50\x41\x4b\x35\x82\x77\x0f\x3d\x9e\xd0\x30\x4f\xf7\x51\xa4\xbc\x40\x9b\x2f\x24\x5d\x46\x47\x55\xd4\xbb\xa2\x91\x12\xba\x99\xa0\xe3\x0c\x76\x15\x41\xa6\xbf\xc8\x20\x8d\x6e\x16\x48\xcf\x43\xca\x57\xdc\xe1\x89\x9e\x26\xd8\x65\x8a\xc0\x4f\x62\xcf\x0f\xcc\x79\x89\xc9\x1c\x90\xdb\x02\xf3\x3b\x42\x5b\x6b\xb4\x3f\x40\xb6\x27\x8c\xbf\xc1\xbe\x7c\xb4\x5f\xc4\xee\xc2\x0c\x19\x22\xc9\x24\x92\xbc\xa0\x5e\x05\xc9\xcc\xd0\x5c\x98\x4f\x77\xec\xf5\x84\x0e\x2b\x18\x3f\x8e\xdc\xc2\x8c\x38\xa3\x83\x0f\xa6\xb1\xc7\x75\x8a\x38\xbf\x8a\xc9\xed\xb0\xe7\x21\x92\xf6\xb1\x85\x38\xc6\x5f\x22\xc9\x33\xc1\xf3\x49\xf0\xea\x20\x83\x2e\xda\x3b\x62\xdf\x75\x82\xcf\x16\xfd\x4a\x22\xc3\x90\x5d\x7e\x91\xd9\x10\x17\x89\x62\xfe\x1a\xd8\xcc\x03\x29\x8e\x90\xf2\x09\x7b\x9e\x20\x95\x38\xb2\x2b\xa0\xed\x39\x36\x5a\xc0\x2e\xb3\xe8\x21\x8b\x69\xf8\x48\x6e\x88\xdc\xce\xd8\xdb\x10\x1b\xe6\xde\x20\x86\x9b\x7e\xa3\xd3\x08\x52\xb9\x23\xb9\x35\x52\x4c\xe3\xda\x27\x02\xaf\x86\x64\x06\x48\xa6\x87\xe6\x5a\xd8\x48\x1c\xcd\x7d\x21\x83\x32\x66\xd3\x44\xca\x33\xe4\x9d\x40\x8b\x13\xb4\xff\x83\xbd\x55\x31\x61\x8e\xd6\x26\x68\xef\x8d\xf9\x0d\xcf\x37\xc5\xfc\x76\x30\xdb\x08\xf6\xb3\xc7\xd5\x0e\x48\x76\x87\xec\x5f\xc8\x7d\x80\xec\x13\xd8\x62\x16\x49\x1d\xd1\xec\x07\x93\xff\x23\xf0\x67\xb8\x4e\x05\xd7\xfe\x20\xdb\x29\xa6\xb4\x43\xca\x05\xec\xee\x86\xbd\x26\x91\xf7\x16\xbb\x5d\xa3\xa5\x25\x72\x0b\xf5\xb8\xc3\xbe\xce\x68\xf6\x8d\x54\x16\x18\xef\x07\xd3\xcb\x11\xbc\x07\x04\xcf\x36\x6e\x7c\xc5\x8c\x23\xd8\xd7\x0b\x89\xd4\xd0\xcc\x07\xf3\x13\x45\x06\x15\xcc\x31\x8b\x7e\x15\x30\x5f\x73\x64\x3b\xc1\x4e\xa2\x48\xea\x86\x8d\xf7\x31\xfe\x00\xfd\xae\x20\x83\x16\x92\x8d\xa1\x97\x3c\x41\xf8\xce\xc5\x32\x76\x97\x45\x3e\x17\x5c\x27\x43\xe0\x17\x31\xaf\x16\xa6\x57\x41\xca\x79\xf4\x9c\xc7\x35\x3a\xd8\xfc\x02\x99\xf5\x91\x4c\x15\xb3\xf4\x71\x93\x2a\x2e\x52\xc1\x0d\x46\xe8\xed\x86\xee\x8a\x98\xe1\x06\xd3\xdd\x62\xfc\x0c\x36\xda\x45\x0f\xe1\x9d\x54\x09\xbc\x2a\x52\xff\x41\x5b\x13\xec\x2d\x7c\xe6\x2f\x12\xed\x63\xe2\x19\x64\xb6\x45\x76\x43\x4c\x7c\x89\xfd\x24\x91\x49\xe8\xaf\x39\x52\xdc\xa3\xe7\x23\x92\xf1\xd1\xfc\x1f\xfa\x89\x20\x9b\x06\x5a\xf9\xc6\x34\x42\xde\x0d\xef\x2b\x89\x8e\xee\xe8\x68\x8c\x7e\x4d\x09\xde\x17\xa4\xb2\xc4\x34\x8e\xe8\xfd\x4e\xf0\x48\x62\xcb\x7d\xa4\x7a\x42\x5b\x4b\x74\x35\x46\x1f\x4d\xec\x79\x89\x16\x87\xb8\x49\xc8\x01\x3e\xba\xfb\x45\x3b\x5b\xcc\xea\x44\xf0\xe8\x20\x8b\x0c\x3a\x2b\xa2\xd1\x1d\x9a\x5d\xe3\xea\x61\x0f\x6f\xd0\xc2\x1c\x97\xac\x21\xdb\x0c\x9a\xff\x20\x5e\x19\xe3\xdd\x91\x82\x8f\x79\x7a\xb8\x5e\xc8\xf0\x2d\x5c\x2d\x64\xc3\x36\xf2\x15\xb2\xed\x1c\x69\x1c\xb0\xbb\x1d\x76\xbb\x41\x13\xa1\x0e\xc6\xb8\x4e\x02\x5b\xba\x61\x0b\x57\xdc\xb1\x8f\x39\x6e\xd1\xe6\x0c\xd9\xac\xb1\x89\x03\x66\xfc\x8b\x8d\xcd\x91\x66\x02\xf7\xee\xa0\xcf\x06\x26\xe4\xe9\x7b\x05\x3b\x8e\xa0\x7f\x13\x74\xb2\x47\x4b\x05\x74\x53\x40\x8f\x1d\x24\xd3\x45\x1b\x3e\x76\x5f\xc7\xf4\xde\xd8\xed\x0a\xed\x74\x31\xc7\x1a\xc1\xe3\x80\x49\xc7\x31\xc3\x1e\xc1\xa3\x84\x0e\x22\xd8\xe2\x0e\xd9\x46\x71\xc7\x28\xf6\x7c\xc1\xd5\x86\x98\xe4\x0c\xbb\xf3\x31\xe5\x0d\xc1\x73\x87\x5b\x84\xec\x14\x6e\x86\x5f\xa4\x3c\x27\xb8\xef\x91\xe1\x03\x2d\x87\xec\xb0\x47\xf3\x49\xe4\xb9\xc0\xf6\xf2\xe8\x31\x8b\x44\xd3\x98\xf5\x07\xcd\x2e\x31\x9b\x06\xc1\xa3\x82\xdd\x47\x71\x63\x0f\x13\x1f\x62\x9e\x6b\xe4\x1d\xc5\x26\xee\x48\xb3\x8f\x0e\xde\xd8\x44\x17\xe9\xed\x91\x67\xd8\x77\x45\x6c\x3c\xf4\xfb\x10\xb3\x28\x13\x3c\xf6\xe8\xb0\x4e\x10\x66\x7e\xb8\x49\x92\x13\x34\xf2\x85\x99\x46\x91\x48\x11\x33\x6f\x62\xba\x69\x82\x4f\x1c\x37\xe8\x60\xc7\x73\xec\x2e\x81\xf9\xf8\xd8\x58\x16\x7b\xbb\x20\xfb\x27\x76\x3c\x45\xb6\x2f\x34\xfb\x87\x4e\xb3\xc8\xbd\x40\xf0\x9c\xa1\xf5\x22\xf2\x1d\xc3\x84\x3d\xb6\xed\xa3\xfb\x09\x32\x6f\x61\x06\x53\xb4\x10\x72\x5a\xb8\x3b\xb6\x68\xff\x17\xd9\xfe\x20\x5e\x0a\xf3\x6c\x62\xb2\x3d\xec\x72\x81\xb6\x47\xb8\xde\x0d\xd7\x88\x60\x77\x2d\x24\x64\xdf\x43\x12\xcd\xd5\xb1\xd3\x18\x36\xfe\x8d\x54\x9f\xc8\xaa\x8d\x76\x76\xc8\x2a\x8a\xf1\x3f\x68\xe7\x8a\x94\xba\x98\xde\x10\x3b\x1e\xe3\xee\x63\x64\xd3\x41\xfc\x2b\x52\x3c\x60\xe3\x57\xe4\x90\x27\x78\x8c\x09\xee\x67\x5c\x27\x85\x1b\xbf\xd1\x52\x16\xa9\x46\x30\xd1\x1d\x72\x8c\xa2\xa5\x1f\x74\x30\xc4\x46\x2a\x48\xf8\x9d\x97\xb2\xd8\xcb\x05\x7b\x3b\x21\xf5\x39\xb2\x99\x62\x77\x6f\x24\xbd\xc3\xc6\xc7\xb8\xc9\x00\xfd\x7b\x63\xfc\x22\x52\xbc\xe1\x5e\xe1\x1e\x1d\x62\x6b\x77\x74\xdb\x44\xf7\x77\x64\xdb\xc2\xe6\x5b\xc8\x6d\x80\x89\x65\x91\xe3\x1a\x79\x1e\x70\xbd\x70\xef\xae\x90\x79\x19\x3d\x7e\x70\xfd\x23\x3a\x48\xa1\xa5\x09\xea\x57\x71\x5f\x69\xdc\x7c\x83\x5e\xea\xd8\xcc\x0f\x1a\x89\x60\x2f\x57\xc4\xab\x23\x33\x8f\xe0\x99\xc3\x44\x2f\x98\x55\x09\x17\x69\x60\xa2\x1b\xec\xa5\x87\xbc\x6a\x48\xf9\x0f\xf7\xac\xa3\xb5\x0d\xa6\xd7\xc6\x4e\xa3\xb8\xce\x1a\xf1\x6e\x48\x63\x87\xbc\xbe\xb0\xe5\x02\xc6\xdb\x21\x91\x21\xe6\xd4\xc4\xf4\x9a\xe8\xea\x07\xf3\xb7\xc0\x2c\xa3\x48\xee\x07\x19\xc5\x90\xe1\x10\xfd\xfe\x41\xaf\x0b\xe4\x91\x44\xea\x19\xcc\xef\x10\x93\x0a\x7b\xe2\x17\x3d\xbd\xb0\x89\x2a\x32\x9d\x61\x26\x27\xf4\x6f\x89\x8b\x16\x09\xde\x4b\x64\xb7\x42\xbf\x26\xc8\xcb\xc7\x76\xaa\x68\xb3\x8f\x6d\x86\xcc\xb5\xc1\x78\x27\xe4\xf9\xc0\xcd\x8f\x04\xcf\x3b\x9a\x6b\xe3\x42\x9e\x7b\x7c\xd0\x6e\x0b\x5b\xbc\x61\xea\x0b\x64\xfc\x8d\x78\x39\xcc\xa6\x8a\x46\xaf\x68\xe6\x86\xdd\x7e\x90\x71\x03\x99\xa7\x71\x91\x32\x1a\x66\x73\x26\x82\xb6\x42\x6f\x85\x9d\x37\x46\xf7\x3b\x5c\x34\x4d\xe0\xbf\xd0\x5d\x0d\x3d\xcd\x71\x91\x08\x7a\x6e\xa1\xd5\x14\x26\xba\x47\x5e\x61\xa7\x35\xb1\x91\x16\x32\x2b\xa3\xf9\x35\xf2\xe9\xe0\xea\x7d\x4c\x61\x8b\x19\xff\x11\x78\x19\xcc\x23\x8a\xf4\x33\xb8\x5e\xc8\x88\x2f\x82\xf0\x3d\x73\x2f\xcc\x2e\xec\xc3\x0b\xae\x1d\x32\x5b\xc8\x1c\xe1\xc6\x7a\x21\xa3\x14\xae\x97\xc0\x7e\x4a\xe8\xa9\x87\xc9\xdc\xd1\xf9\x13\x17\xfd\x60\xf7\x79\xa4\xb2\xc2\xa5\x4b\x98\x42\x98\xe3\x2d\xcc\x79\x87\x44\xcb\x48\xf2\x8e\x5b\xa4\x30\xe7\x09\x66\xb9\xc0\x26\x62\x68\xc8\x3e\xe1\x99\x0f\x29\xe4\x13\x7a\xae\x8d\xc6\x73\xc8\x38\xdc\xc4\x2d\x34\x91\x41\xfb\x07\xb4\xf7\xc1\x78\x33\xcc\xb1\x85\x44\xde\xc8\xbe\x8b\x69\xf5\xd0\x79\x17\xfb\xdf\x87\x79\xec\x79\x83\x99\x86\xb9\xda\x43\x0f\x21\xc3\x44\x31\x93\x12\xee\x67\x85\xe9\x55\xd1\xe2\x17\xf2\x1c\xa2\xdd\x33\x92\x3d\x62\xcf\x3b\x74\x9b\xc3\xa5\x73\xd8\x5d\x91\xc0\x1b\x23\xa1\x96\xc6\x61\xee\x86\xdd\x93\x41\xf6\x6d\x5c\xcb\x47\xcb\x1b\x4c\x6c\x8b\x6e\xf3\x48\xea\x0f\x1d\xcf\x91\x45\x1a\xbb\x59\x60\xfc\x27\x9a\xef\x21\x95\x33\x81\xdf\x46\x2f\x5b\x5c\x74\x83\xbc\x2b\x68\x6c\x85\x56\xd3\xd8\xfd\x0d\x7b\xf9\xc6\x6c\xc3\x5d\xd0\xc0\x6e\x27\x98\xc6\x0d\xa9\x3c\x90\x5e\xa8\x97\x50\xbb\x15\xec\x39\xec\xe3\x3c\xa6\xe4\x23\xb7\x15\x36\x12\x72\xc7\x02\x5b\x0c\xf7\xff\x06\x7d\xbc\x71\x8d\x2d\x92\x0e\xf7\x92\x8f\x6b\x24\xd1\xaf\x50\x3b\x6b\x24\x3b\x47\xd2\x03\xcc\xe4\x80\x7b\x7d\xd0\xcc\x0f\x26\xf6\xc4\x79\x3e\xc6\xf3\x30\x8b\x28\xe2\x0d\x31\xbd\x1e\x26\x9b\xc1\x3c\xeb\x48\x3a\x82\x19\xf4\xd0\x76\x01\x59\x77\xd1\x6b\x16\xb3\xa9\x21\xed\x33\x5a\xae\x21\xc7\x3b\xda\x0f\xb3\x2a\x81\x1d\xb7\xb0\xad\x32\xb2\xac\x62\xcf\x77\x6c\xb2\x82\xcc\xcf\xc8\xd7\x02\x8d\xef\x08\x1e\x6d\x82\x67\x07\x8d\x4e\x90\x42\x04\xe3\x1d\xd0\x6c\x09\xfb\x5e\x63\x23\x27\xe4\xf5\x83\x4d\x4f\x09\xbc\x0f\xa6\x16\x32\xd5\x05\x9b\xc8\x62\x96\x11\x6c\x65\x45\xf0\x49\x60\x5e\x55\x6c\x26\xf4\x44\x0b\x69\xde\x30\xde\x05\xd9\xdd\xd1\x43\x0b\x2d\xc4\xd0\xf3\x0f\xf6\xec\xe1\x5a\x3f\xe8\xf0\x0f\x93\x49\x61\xe2\x3b\xf4\x3c\xc7\xac\x7c\x64\xd2\xc1\xbe\x76\x48\x3e\x8d\xc4\xcb\xa8\xdf\x45\x4a\x6d\x6c\xad\x83\xcd\x9d\xb0\xb1\x1d\x32\x18\xa3\xc3\x03\xb6\x38\xc6\x26\x3f\x04\x7e\xa8\xd3\x24\xb2\x7f\x63\x5f\x4b\x24\xb5\xc7\x9e\xc7\x98\x8e\x8f\xf3\x4b\x48\x36\x87\xab\xf9\x48\x3e\xdc\x48\x71\x5c\x37\xcc\xfe\x15\x2e\xbe\x41\x4e\x7b\xe4\x1e\x45\xef\x3b\x82\x67\x19\xfb\x5a\x11\x78\x6b\x74\xf7\x85\xd6\x17\xd8\xd2\x2f\x92\xf1\xd0\xcb\x0f\x66\xd9\x46\xcb\x67\x74\xf4\x83\x44\xc3\xae\xdf\x62\x63\x63\xe4\xd8\xc3\x34\xda\xe8\x69\x8c\x19\x8c\x31\xbf\xe1\x8e\x09\xcf\x3c\xc3\xb5\x23\x04\xcf\x2a\x7a\x48\x63\x33\x45\x4c\x98\xdb\xfe\x17\x26\x76\x47\xea\x47\xcc\xf4\x86\xf1\x43\x56\xcf\xa3\xb7\x31\xb2\x6f\x22\x95\x70\xa3\xdd\xd0\xe1\x19\xa9\x66\x90\x77\x0d\x37\xe9\xa3\xa7\x1f\xcc\xaa\x88\x7c\xc2\x67\x5d\xb0\xf5\x01\x9a\x6f\xa2\xe7\x6f\xb4\x94\xc1\x7d\xf5\xb1\xef\x1e\x32\xdd\xe2\x1a\xa1\x9f\x7e\xb1\x9d\x2e\xf2\xdc\xa1\xd5\x35\x1a\x9e\xf5\xf1\x44\xfc\x1b\xb2\xcf\x61\x7e\x5a\x98\x70\x1b\x3e\x13\xb8\xee\x15\xd3\xac\xa2\xfb\x32\xb2\xfd\x45\x96\x15\x5c\x3f\x8d\xa9\x7e\xa3\x91\x1f\x64\x3f\xc3\x54\xce\xc8\xfb\x07\x2d\x97\xb1\xa9\x3e\xf6\x33\x40\x66\x0f\x6c\x72\x8f\x79\xb6\x31\xe5\x11\x66\x7d\x43\xa7\x5b\xf4\x7b\x80\xf9\x7d\xa0\xc7\x21\x12\xfb\xc3\xf8\x27\xe4\x93\xc2\xc5\x16\x48\x76\x8d\x3c\xee\xe8\x25\x85\x8e\xc2\x5c\x9b\x63\xb2\x1d\xec\x79\x8b\x99\x3d\xd1\x90\xa3\x6b\x23\x8c\xf7\xc0\xbc\x26\x68\xbe\x88\x84\xfc\xdd\xcc\x61\x27\x4d\x64\x18\x47\xf2\x33\xcc\xab\x8b\x49\x2c\xd0\x57\x9f\xe0\x59\x44\x26\x2b\xf4\xef\x88\x79\x0e\x90\x65\x1d\xc9\xe4\x70\xf3\x03\x81\xff\x41\xe6\x4d\x5c\x7d\x80\xfb\x7b\x12\xdc\x5f\xd8\xdb\x0a\x17\x7a\xbd\x10\xfe\xfe\x8d\x66\x7f\x91\xe6\x00\x3b\xc9\x63\x62\x1b\xf4\x30\x46\x1e\x5f\xd8\xdd\x1d\x79\x86\xfb\xef\x80\x4e\x92\xc8\xfc\x8a\x9e\xa3\x98\xe8\x1b\x9b\x19\xe2\xb2\x67\x6c\x3e\xe4\xbd\x27\x1a\xfe\xcd\x2e\x8a\xa6\x63\x48\x98\xe9\x1d\x0f\x19\x36\x90\x5d\x02\x39\xe4\xb0\xb7\x38\x7a\x1f\xa3\x85\x2a\xc1\xfd\x81\xcd\x86\x3a\x0d\xfd\x1e\xb2\x55\xc8\x7c\x0f\x34\x73\xc6\x8c\xa2\xe8\x64\x81\x0d\x33\x3c\xd5\xc0\x5e\x66\xe8\xbd\x81\xd4\x37\xe8\xd7\x1f\x6e\xd2\x42\xe6\x0d\x5c\x3d\x49\xe0\x1f\xb1\x9d\x12\x26\xdc\x8a\x8b\x07\xc1\xa3\x8c\x29\x17\x31\x8d\x13\x3a\x2e\xe0\xa2\x17\x24\x19\xc5\x75\x53\xd8\x6f\x8f\xc0\xaf\xe3\x36\x65\x5c\xa3\x82\x76\xea\xe8\x7e\x8b\x24\x9f\xb8\x6e\x05\x33\x29\x62\x2f\xbf\x68\x7e\x85\x7c\x46\xd8\x58\x1c\xf3\xbc\x63\xb2\x17\x34\x37\x41\x8a\x5d\xe4\xb6\x44\xa6\x27\x24\x99\x40\x07\x7d\xec\x76\x87\xdd\x75\x31\x93\x25\x66\x3e\x47\x87\x3b\xdc\xf8\x82\xdc\xc6\x98\xe1\x1a\x8d\x1d\x31\xd1\x02\xee\x9d\x20\x78\x2e\x30\xf3\x15\xb2\xf3\xd1\x71\x0c\x57\xf7\x90\xfe\x14\x8d\x56\xd0\xe8\x1e\x17\xaf\x62\xaf\x53\x34\xf7\x87\x2d\xd6\xb0\xc9\x37\xf6\x7c\x46\x87\x0d\xd4\x3f\x63\x0a\x3d\x5c\xbb\x81\x7d\xa7\x90\x85\x8f\x8c\x7f\xd1\xda\x0c\x89\xad\x30\x9b\x37\xae\xf5\x40\xb3\x7b\xcc\xf9\x17\x33\x8a\xe1\xfe\x6f\xa6\x32\x52\xc9\xe1\x3a\x57\x82\x67\x05\x69\xc6\x30\xcd\x16\xa6\x7e\x45\xd6\x29\x34\xd7\xc5\xa6\x63\x68\xf5\x8e\x7c\x8a\xd8\xce\x1b\xdb\x1f\xe3\x62\x3e\x36\x7e\x47\x6e\x6b\xb4\x30\x43\xa2\x57\xe4\x19\x47\x97\x2f\x24\x77\x24\x78\x9c\x70\xb1\x3a\x52\xc9\x12\xf8\x51\x4c\x3c\x86\x19\x35\x31\xcb\x21\xc1\xa3\x80\xcd\xec\x09\x9e\x67\x4c\xbd\x8f\x5e\x92\x04\xf7\x0e\xda\x8d\x61\xd2\x73\x74\x1d\xe6\xd7\x09\xfb\xb9\xa1\xdd\x90\x2f\x0b\x98\xe5\x12\x1b\x4f\x61\x77\x0b\xcc\x7e\x89\xbd\x97\x31\xf5\x1b\x76\x7f\x40\xaa\x29\x64\xfb\xc6\x9c\x72\xe8\xb9\x87\x7d\x67\xd1\xc4\x0c\xf3\xfb\x8d\xeb\x76\xd0\x48\x0d\x73\x6c\x13\x3c\xc2\x2d\xfe\x83\x8d\xad\x31\x87\x22\xfa\x55\x46\xaf\x31\x4c\xaa\x83\xe9\xa6\x08\xde\x0b\x34\xf6\x87\x96\xda\x04\xde\x2f\xc6\x1b\xe1\x52\x35\x4c\x3e\x86\x6b\x44\xd1\x5b\x04\x8d\xae\x30\xd9\x23\xae\x7f\xc7\x64\xfe\xb0\x97\x32\x2e\x92\xc2\x94\xd6\xb8\xce\x05\x33\x1f\x60\x96\x35\xf4\xd2\xc1\x1e\x0b\xc8\xeb\x81\xbc\x9e\x68\x2c\x8b\xbb\x6f\xb0\xd7\x3c\x92\x9e\xa1\x9d\x15\xe6\x7f\x1e\x65\x30\xcb\x90\x63\x2e\x98\xd7\x11\x9d\xec\x30\xb1\x12\x1a\x66\xde\x34\x8f\x5b\x1f\x30\x9b\x1e\x72\x1a\x23\xa9\x1a\x12\xee\xd9\xdd\x07\xbb\xab\xa2\x97\x3b\x7a\x0a\xf9\xfd\x85\xfd\x0c\x31\xe3\x24\xa6\x99\xc2\x9e\x6f\xe8\xb3\x8c\x59\x7d\x90\xd4\x08\xf9\x5d\x63\xe3\x51\x6c\x6e\x87\xc9\x4e\x90\x72\x0f\xdb\x8d\x20\xf3\x39\xee\x3e\x45\x8e\x1b\xcc\x3b\x87\xa4\x37\x04\xf7\x23\x32\x6e\x63\xfc\x36\x2e\x79\xc1\x7e\x17\x31\xbd\x14\xae\x31\x46\xbc\x0e\x66\xf3\x40\x52\x3e\x36\xdc\x9b\xd5\x04\x76\xb2\xc1\x6c\xf2\x68\xbe\x86\xc4\xbb\x68\xeb\x80\xab\xbd\x71\xf7\x21\xfa\x4c\xa1\xc7\x0c\xa6\x9f\xc5\x34\xcb\xe8\xcd\x47\xa7\x35\xcc\xba\x85\x19\x0f\x70\xc3\x35\x2e\xf2\x44\xb3\x1b\x82\xf7\x0a\x49\x67\xd1\x82\x87\x99\xb4\xd0\xd1\x0b\x13\xab\xa1\x83\x1d\x1a\x9b\xe2\x16\x65\x24\x37\xc0\x1e\x7e\xb0\xef\x17\x92\x8f\xe3\xee\x1f\xb4\xb5\x40\x2a\x61\x46\xf6\x31\x21\xa7\x0f\xf3\xd8\x77\x0e\x0d\xef\x63\xbe\x45\x2b\x7f\xb8\x9f\x18\xf6\xfd\x8d\xe4\xc3\x1c\x9b\x12\x3c\xf7\xd8\x5a\x1e\xe3\xd7\x70\xbd\x37\xc1\x3d\x64\xb0\x0b\xb2\x4c\xa1\xf9\x21\xb2\x4d\x63\xdf\x55\x5c\xe7\x0b\xd7\xfb\x42\x42\xee\xab\x27\x90\x73\x1a\xc9\xfe\x20\x91\x31\x52\x4a\x22\xb5\x3f\xdc\xfa\x8a\x6d\xee\x90\xcc\x0d\x6d\xce\x31\x5f\x3f\xd8\x4b\x1e\x99\x67\x09\x5e\x3d\xf4\x92\x46\x9f\xbf\x68\x2f\x3c\x67\x1a\x57\xeb\xa0\xe3\x38\x9a\xbd\x12\xf8\x0d\xec\xa7\x41\xf0\x69\x11\x78\x65\x6c\xb2\x81\xfb\xce\xa3\xd3\x03\x76\x91\x42\xc7\x29\x34\x96\x40\xca\x0d\xb4\xf6\x8d\xfb\x69\x21\xf9\x36\xda\xf2\xd0\xe3\x1d\xd9\xcc\x90\x4a\x05\xd9\x0c\xd1\xfb\x08\x39\x64\x30\xcd\x37\xb2\xe8\xa0\xf1\x3e\x81\xbf\xc7\xe4\x47\xd8\x78\x04\xbb\xaf\xa0\xb9\x1e\xae\x9f\x45\xc7\x55\x24\xe4\xcc\x76\x0f\x3b\xde\x63\x7a\x2d\xf4\xde\xc2\x26\xca\xd8\x4b\x13\xbd\x16\x30\x8d\x3e\xda\x7b\xe0\xda\x49\x6c\xac\x80\xd4\xd7\x48\x29\x8b\x89\xc7\x31\xde\x1f\xba\x4b\xa2\xed\x15\xc1\xf3\x07\xd3\x4a\x63\x92\x5b\xa4\xfc\xc0\xd5\xb2\x68\x65\x83\x2d\x94\x30\x7f\x4f\x5c\xf2\x86\x44\x6f\xc8\xb3\x8e\x6b\xcc\xd1\x68\x78\xa7\x7b\x64\x50\xc5\x3d\x7d\xcc\xe7\x89\xf1\xae\x48\xb9\x83\xc9\x1f\x70\x91\x2d\xe6\x55\xc1\xf8\x7d\x74\xda\x45\x73\x55\x6c\x6a\x85\x6d\xfc\x21\x3b\x0f\xf7\x33\xc3\xac\x53\x48\xea\x8a\x7e\xef\x90\x54\x01\x09\x77\x5a\xfa\x8e\xf1\x93\xc8\x20\xd4\xb8\x87\x49\xec\xb1\xaf\x3d\xfa\x37\x45\x3b\x79\x4c\x7b\x81\xbc\xc7\xb8\xc6\x06\xd7\x58\x10\xdc\x97\x68\xeb\x0f\xd7\xf0\x91\xef\x04\x5a\xe9\xa3\xd9\x2a\x2e\x16\x21\xf0\x36\xb8\xe4\x0e\xfb\xc9\x60\x33\x35\x6c\x22\x85\x4b\x5e\x71\xad\x23\xf2\x59\xe2\x92\x5d\xdc\xf8\x85\x79\xbf\xd0\xeb\x0a\x29\xde\x09\xfc\x16\xae\x13\x6a\x73\x88\xc6\xd7\xe8\x60\x83\x2c\xbb\xd8\x58\x17\x2d\x66\x71\xd3\x36\xfa\x8c\xa1\xed\x14\xfa\xe7\x21\x95\x37\x2e\x5e\xc2\xc4\x6f\xe8\x21\x8a\x54\x2f\xb8\xf9\x1e\x5b\x59\xe2\x7a\x49\x5c\x6c\x8b\xfd\x44\x31\xe9\x2f\xb4\x56\x43\x96\x3e\xf6\x72\x46\xb6\x67\x4c\x7c\x81\x44\x3c\xe4\x5e\x41\x9b\x55\x5c\x3d\x8e\xb6\x56\xb8\x54\x1a\x5b\x9d\xe2\xc2\xad\xd2\x0b\x39\xf6\x83\xe6\x0b\x48\x2c\x89\x4d\x3e\x90\xc5\x1c\x2d\x67\xb1\xe7\x19\x9a\x4f\xa1\x9b\x1f\x6c\x75\x8c\x8d\x7b\x04\xf7\x09\x7a\x59\x23\xe1\x99\xda\x31\xe4\xfb\x17\x2d\x8c\xb1\xcb\x0c\xf6\xfc\x83\xfe\x67\x98\x33\x7a\x08\x7f\x2e\x20\xa9\xb0\xd7\x3c\x64\xd9\xc7\xee\xc3\xec\xb8\x22\xb9\x70\x5f\xff\x61\xc3\x9d\xd6\x2e\x63\x43\x26\xef\x65\x70\x3f\x55\x82\x47\x03\xf5\x7e\x08\xee\x3d\xa4\x38\x41\x73\x0f\x5c\xeb\x86\xd4\x56\x48\x66\x8b\x5b\xbf\x31\x61\x5e\xc4\x86\x68\xb5\x8d\xab\xd7\xd0\xd2\x0d\x37\x49\x23\x0f\x1f\x1d\x26\xd0\xf8\x08\x8d\xaf\x08\x5e\x27\x02\x3f\x8d\x4d\x86\x8c\x36\x40\xaf\x33\x24\x5b\xc5\x7c\x2f\x91\xd1\x18\x3d\x3d\xb1\xd5\x03\xe6\xb5\xc6\xf5\x8b\x68\xf1\x1b\x1b\x2f\x61\xf3\x45\xd4\x0f\x39\x7c\x8d\x16\x93\xe8\xa3\x8d\x19\x15\x71\xfd\x6f\x5c\xec\x82\xad\x24\x30\xcd\x1d\x7a\x0b\xf7\x4d\xd8\x0b\x39\xcc\xf1\x07\x13\x6f\x23\xdb\x0f\x3a\x9e\xa2\x99\x0c\x6e\x7d\x42\x7e\x63\xd8\xe9\x17\xf2\xee\x60\xb6\x1b\xb4\x58\xc1\xc6\x46\x68\xad\x8a\x76\x6a\xd8\xf7\x0a\xdd\x7e\xb0\xa5\x23\x5a\xcd\xa1\x95\x24\x2e\x79\x40\x0e\x65\x4c\xf3\x17\xa9\x47\xb0\x61\xa6\x8e\x2e\xe8\xf1\x17\xd3\x3d\x60\xbe\x92\x48\x79\x84\x6b\x47\xb1\xa5\x03\xfa\x75\xc4\xbe\x9b\xb8\xda\x1a\xd3\x0a\x77\xd2\x00\xb9\xdd\x70\xf3\x0f\x66\x7e\x27\xb8\xb7\x31\xa5\x04\xea\x85\x5e\xdd\xe3\x22\x3e\xf2\xda\x20\xfb\x70\xdb\x7d\x90\xc5\x0a\x9b\x4d\x23\x95\x6f\xdc\x70\x81\x46\x56\x98\xe1\x16\xdd\xa4\xf9\x17\x00\x00\xff\xff\xbf\x1b\x72\xe3\x00\x20\x00\x00") + +func keysWordlistChinese_simplifiedTxtBytes() ([]byte, error) { + return bindataRead( + _keysWordlistChinese_simplifiedTxt, + "keys/wordlist/chinese_simplified.txt", + ) +} + +func keysWordlistChinese_simplifiedTxt() (*asset, error) { + bytes, err := keysWordlistChinese_simplifiedTxtBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "keys/wordlist/chinese_simplified.txt", size: 8192, mode: os.FileMode(420), modTime: time.Unix(1497960590, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _keysWordlistEnglishTxt = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x2c\x5b\xdd\xbe\xbc\x2a\x08\xbd\xf7\x2d\xc9\xa8\xd8\xa3\xe2\x41\x9d\x76\xfb\xe9\xcf\x6f\xad\xfe\x17\x83\xe5\x07\x2a\x22\x2c\xcc\x91\x4d\xda\xee\x2d\xc9\x66\xc5\xe6\x93\x64\x2b\x9a\x64\xf3\x35\x41\xbf\x78\x1e\xda\xf0\x32\x3c\x36\x24\x33\x24\xf3\x7d\xc5\x9e\x64\x5b\x43\x93\xe4\xac\x63\x20\xb1\x9d\x95\x73\xf6\xf5\xa6\x6f\xf1\x65\x0a\x56\xd9\xf6\x24\xd9\xd7\x98\x96\x93\xe4\xff\x96\x05\x72\xc3\xd9\x18\xf5\xa7\x61\x2c\x79\x7a\x80\xc6\xcb\x75\x2e\x29\x49\x76\xe9\x33\xc9\xbe\xe3\x67\x99\x8f\x6f\xf9\xfe\xb3\x06\x5e\xab\x81\xae\x02\xfa\x95\x96\x15\xa9\x21\xd1\xf0\x0d\x3d\x1e\x87\x58\x20\x71\x0c\xfd\x08\xc1\x78\x4e\xb1\x96\xe4\x54\xfc\x30\xe6\x33\x54\x93\x5c\x2a\x7b\x12\xab\x89\x2d\x2c\xba\xc7\x4c\x62\x03\xd2\x29\x12\x35\x49\xd9\x16\x68\xf6\xcb\x4b\x92\xa2\x28\x2f\xa6\x2d\x49\xc1\x7b\xd1\x07\xd4\xef\x24\xa5\x3a\x06\x58\xbc\xa1\x71\xbf\x24\x49\x09\x95\x1d\x15\x86\x27\x29\x53\x23\x49\xb9\xe5\x19\x49\xaa\x4c\x5d\x81\xf4\xcf\xda\x99\xa4\xfa\x4b\x29\xcf\xba\x86\xee\x49\x9a\x94\x07\x1c\x5b\xbe\x20\xa8\x96\x8d\x23\x6f\x27\xf8\xb4\x13\x63\x6c\x67\x3c\x49\x9a\x55\x88\xae\x7d\x98\xd5\x7c\x51\x2a\xad\x51\xa0\xcd\xe7\xc5\x06\xe3\x66\x32\xb5\x35\x41\x6a\xff\x2d\xd4\xfa\x35\x85\x42\xb4\x27\x49\x17\xcc\xae\x7b\xf1\x13\x6f\x5d\x25\x90\x80\x6b\xef\x41\x35\xe9\x61\x25\x49\xe4\x0b\x84\xeb\x1b\x2a\x20\xe0\x19\x27\x38\x42\x6a\x51\x31\x81\xa8\x18\x77\xd4\x27\x49\xf8\x6a\xc8\x09\x0c\x1f\xa9\x62\x66\x11\xf6\xe5\x1b\xe4\x87\xbe\x63\xea\x41\x15\x89\x69\xac\x30\x6f\x8f\x4f\x92\x81\x5f\x57\x94\x8c\x21\x5c\xfc\x31\x94\x94\xf5\xc6\x58\x55\x93\x8c\x79\x55\x49\x32\xaf\xa2\x53\x93\x4c\xaf\x49\xe6\x94\xfc\x41\xa2\x18\xc0\x9c\x36\xd7\x8e\xb2\x7f\x0a\xbe\xfe\x29\xe3\xda\xa1\x57\xeb\xa4\x92\x71\x15\xd6\xa4\xd8\xd7\x74\x90\x55\x5b\x92\xaf\x06\x55\xe8\xeb\x59\x76\x47\x0a\xd5\xba\xe5\xa3\xa0\x41\xfa\x24\xb9\x75\x38\x86\x73\x1f\xab\x24\xb9\x3f\xb7\x40\x11\x7f\x6d\xa4\x4d\xb6\x27\x6d\x92\x2f\x2d\x1e\x78\xf0\x96\x36\xd9\x4f\x4d\x9b\x9c\x69\x93\x42\x85\xde\xa0\x6f\x0d\x15\x4b\x49\x9b\xd4\xcd\x3d\x6d\xd2\xa4\x09\x92\xa6\x68\xc9\x9f\x16\x54\x0a\xea\xf6\x06\xa1\xa2\xfa\x00\x83\x61\x19\xf4\xa3\x33\x6d\x32\x67\xd1\xb4\xa9\xe4\x0b\xb4\x81\xac\xf9\xa4\x4d\xb3\x60\xe3\x6e\x9a\x31\xdc\x4d\xf5\x48\x9b\x1e\x1e\x78\x3e\xc1\x52\x2f\xf9\xe2\xe5\xb2\xb6\xa7\x4d\x0b\xf7\xf7\xa6\x50\xf7\x4d\xcb\x4c\x9b\x36\xf2\x6c\x7a\x18\xde\x06\xc8\x0c\x01\xef\x09\x75\xdf\x74\xde\xaa\xe0\xf4\x38\x58\x58\x7e\x32\xc6\x62\x78\xfe\xe0\x81\xb9\xaf\xc6\x6d\x16\x78\x89\x79\xa5\xcd\xde\xe6\x05\x6b\xb7\x15\xd9\x15\xb4\x92\x36\x4e\xaa\x08\x3a\x2b\x2a\x28\x87\x81\xd8\x0a\x79\x15\x77\xd2\x31\xbc\x22\xe5\x04\xcb\x22\x01\xc3\x35\xae\xb4\x39\x16\x64\x73\x99\x69\xf3\xfd\x49\x9b\x5b\x49\x9b\xd7\x2d\x6d\xd8\xbc\x9b\xb7\x35\xd2\xe6\xfe\x01\x41\x37\x1e\x3b\x46\xe3\x81\xbd\xba\x39\xf5\x75\x83\x39\xdb\x7c\x42\xc9\xb6\x77\xcb\x6d\xfe\x9b\x36\x7f\xd2\x16\x92\x39\xc8\xe0\xc2\x84\x60\x60\x21\xa8\x1f\x14\x28\xcc\x02\xa8\xfe\xe1\xc5\x30\xc7\x30\x6a\x41\x18\x16\x21\xec\xbc\xd0\x9c\xdd\x85\x0d\x94\x7b\xce\x5e\x0c\x0f\x1f\x08\x34\xbc\xb1\xb1\xa3\xfb\x78\xf7\xf8\x16\x7e\xa3\x88\x73\x5c\x1b\x6c\xfc\xb6\x76\x4c\x70\xed\x27\xc6\xb3\x8e\x43\x8a\xa7\x6d\x59\xd9\xd3\xb6\xca\x06\xf2\x01\x29\x2c\x6e\x3b\x9b\xb4\x0f\x98\xad\xd8\xd1\xd1\x8a\xf3\x7d\x83\x20\x20\x97\x35\xac\x51\xe0\x6b\x80\xf3\xbb\x50\xeb\x21\xfd\xfb\x4b\x59\xb6\x0d\x9b\x24\xcb\x66\x0d\xb4\xe0\x39\xcf\x35\x52\x7e\xf3\x3f\x20\xa5\x80\xd4\x94\xa5\x6a\x08\x92\x9e\xb2\xa0\x41\x13\x14\xb5\xac\x4c\xf6\x07\xb4\x39\x4b\x1c\x2d\xdb\x57\xc0\xaa\x3d\xcc\xeb\xff\x3a\xe8\x36\xd9\xae\x4f\x61\xb7\x81\xdf\xc6\x2a\xb1\x83\x9c\x0e\xda\x75\x22\x09\x70\x0d\x3c\x0e\x34\x1e\x17\x88\x35\x54\x19\x93\xfc\xc6\x22\x3b\x54\x99\x52\xfc\x44\x9a\x51\x6d\xea\xe9\x6c\x3e\xdf\x8a\x0b\x4b\xf5\x6e\xa4\x2c\x8b\xc6\x24\x63\x91\xb3\x5a\xc1\xfa\x65\x2d\x8a\xfa\x5a\x61\xbd\xb3\xb6\x01\x49\x68\x9b\x8b\xb9\xa1\xe8\x47\xe3\x1d\xf6\x05\x3f\x94\x2f\x29\x1f\xd0\xda\xc9\xed\xa2\xcd\xcc\x97\xf8\x00\xed\x10\x78\xbe\x24\xde\xcc\x41\x3a\x53\xbe\x54\x3a\x68\x46\x5b\x55\xe6\xeb\x01\xc2\xe9\x5e\xd8\x9d\xf9\xb2\x0c\xf5\x81\xab\x46\x11\xf4\x20\x5f\x56\x9b\xa2\x86\xc3\x8d\xe6\xcb\x9d\x6d\xc3\x9b\xe5\x94\xaf\x95\xe1\x57\xf2\xb5\x1a\x18\xaf\x68\x29\xdb\x09\xf9\x5a\x6b\xf0\x5b\x29\x5b\x60\x53\x67\x9b\xf6\x07\xde\x00\x18\xd9\xbe\x56\x52\x2e\xf0\xad\xb9\x60\x60\x45\xc2\x8e\x07\xe9\x0d\x82\x27\xd8\xa2\x5c\x34\x3e\xa0\x5f\xcc\xaa\x60\x2f\xe4\x42\x47\x97\x8b\x1d\x07\x68\xdd\x40\x39\x98\x62\xe0\xe4\xac\x84\x35\x29\x1c\x6a\xf1\x79\x81\xae\x1d\xf4\x06\xd3\x85\x36\x0b\x3a\x55\xd6\xa0\xc0\xca\xe2\xfa\xb9\xbc\x14\xc2\xf0\xec\x6d\x21\xdd\x35\x65\x3f\x0e\x45\x82\x61\x3b\xd6\xc2\x4b\x81\xc3\xc9\x0e\x53\x9d\xbd\xc0\x03\x64\xaf\x9b\x35\x54\xab\x24\x07\xf0\x42\xf6\x8a\xb1\x79\xa5\x30\xbc\x76\x38\xd3\xec\x0d\xab\x8a\x74\x5f\x64\xd3\x0e\x8b\x8a\xf4\x24\xa0\xc9\xde\xda\xcb\xbf\x0d\x83\x79\xc9\xde\x66\x38\x7a\x6f\x5f\x83\x39\xc9\xb0\x40\xd9\x99\xd5\x3b\x6b\x74\x30\x0e\x68\x0c\xac\x74\x76\x2c\x86\x47\xbc\x7c\x38\xa5\x39\x39\x88\xc5\x59\xae\x36\xb1\xf4\xbe\xe0\xc3\xb3\xaf\x18\x4c\x06\xa7\x47\x81\xfb\xe3\x53\x53\x86\xc1\x02\xc5\xfe\xcf\x21\xc7\x04\xad\x20\x8d\x19\xd8\x20\x21\x94\x63\xc8\x5d\x40\xff\x9e\x94\x43\x59\x49\xe1\x3b\x73\xa8\x82\x87\xde\x29\xc3\xa4\x61\xa3\x85\x41\x4c\x61\xa3\x83\x02\x2e\xe4\x70\x3c\xc3\x76\xe6\x78\x47\x19\x7e\xef\x29\xc7\xca\x86\x79\xc5\x52\x52\xc3\x50\x63\x55\xee\xee\x58\x8d\x35\x17\xc7\x81\x8e\x9f\xc1\xed\xbe\x36\x4d\x79\x95\xb9\x20\x8d\xd5\xf1\x7b\x8d\x7b\x5e\x61\x8e\x8d\xb6\x22\xa8\x4c\xeb\xdf\x0e\x5b\x81\xbd\xb9\xc6\xc5\xad\xb5\x06\xcc\x77\x5e\x90\x01\x3d\xd3\x2e\x7b\xda\xa5\xc2\x50\xed\x30\x49\x3b\x1d\xf2\xfe\x82\xae\x5d\x68\x91\x77\x88\x63\xe7\xc6\x67\xe6\xdd\xd2\x2e\x4f\xda\xb1\x93\x77\xdd\x64\x2a\x92\xb0\x91\x76\xcd\x70\x5d\xbb\x66\xad\x1b\xea\x2a\xa0\x33\x92\x02\x2d\xda\x15\x8b\xc9\xea\x10\xe5\xc0\x03\x6b\x1d\xda\xf8\x72\xbc\xb5\x0e\x30\x27\x60\xdd\xb5\xb0\xa7\x62\x5f\x56\xac\x70\x2d\xbb\x56\x63\xf5\x66\x1c\x41\x23\x76\xda\xb5\xa1\x26\x31\xdd\xae\x5d\x59\xb1\xfb\x30\xbe\xce\x0b\x14\x28\x60\x57\x82\xb0\x5d\x47\x0e\xdb\xf8\xa0\x6c\x32\xec\x6c\x48\x3e\x20\x1d\x86\x69\xd7\x31\xc3\xd1\x64\x8a\xa1\xa7\x09\xc5\xdb\xf5\xab\xc5\x3b\x52\xd8\x8f\x5d\xbf\x50\xa9\xdd\xe4\x84\x0a\xed\x1c\x93\xc1\x50\xec\x48\xe3\x49\x3b\xab\x99\x0e\x45\x89\xce\xb4\xdb\x71\x60\x3a\x76\xd2\x88\xef\x76\x36\xd8\x90\xdd\x8a\xd6\x2a\x69\x37\x62\x9e\xdd\x9a\x0f\x59\x78\xa0\xc2\xef\x86\x61\xda\x78\xa1\xfc\x6e\xe3\x55\xe9\xdd\xc6\x2b\x4a\xc3\x2a\xd9\xa8\x36\x06\xd2\xd7\x87\xef\x36\x3a\x45\x68\x63\xbe\x4b\x0b\x49\x82\xcf\x97\x2b\x63\x5f\x0f\xe6\xfe\xfd\x3d\x69\x77\x86\x28\xbb\xe7\x45\xe3\xbd\xfb\x99\x76\x2f\x05\xa4\x5f\xd6\xd2\xee\x55\x98\x34\xae\xa2\xb7\x8f\xa2\x55\x63\x23\x12\x0c\xc4\x17\x94\x78\x07\x7e\xde\xb9\xb7\xf6\x90\xd3\x1b\x12\xcc\x2e\x84\x81\xd2\x1e\x72\xa7\x9d\x3b\xea\x8d\x78\xf6\x30\xd6\x35\x74\x18\xd6\x3e\xa0\x1d\x84\x8c\x20\xf1\x58\xa8\xfc\xa4\x7d\xe5\x4f\xda\x57\xdd\xd2\xbe\xa0\x31\xeb\xd5\x53\x60\xd9\x9d\x66\x6f\xe7\x4a\xdf\x12\x47\xda\x9f\x26\xb0\x57\x2a\x50\x69\x15\xc4\x11\x2a\x51\x1e\xd0\x06\x32\xaf\xa4\x32\x8c\x39\x63\x82\x3c\x49\xf3\xe5\x49\xf3\x0b\xd4\x34\x7b\xf3\xfa\x24\x05\x64\xe1\xe6\xd7\x7d\xc1\x33\x26\x3d\x68\x11\xf5\x3c\x93\x12\xc3\xa8\x11\x99\x68\xd9\xfc\x4e\x5a\x76\x3e\x6b\x9e\x81\x11\x14\x3d\xa5\x4d\xa4\x14\xaf\x16\xed\xd7\xbf\x8c\xaf\x40\xf2\x5a\x0c\x4c\xcb\xd0\xa4\x75\x93\xf8\x20\x01\x62\xd3\x0a\x8c\x85\x5c\x85\x1b\xd4\xea\x74\xbc\x5a\x7b\x71\x94\x76\x47\xb0\xa3\xb5\xcf\x27\x69\x23\x44\xd0\x06\xbc\x8f\x6d\xa0\x80\x39\x63\x20\x75\x58\x44\x6d\x8a\xc9\x34\x0d\xcc\xad\x1d\xd4\x00\x6d\x27\x8c\x80\xb6\x13\x7b\x50\xdb\x45\x6d\xd1\xf6\x03\xfe\xad\x60\x87\x69\xf3\x75\x5e\x49\x5b\x58\x66\x02\xd5\x80\x7f\x0f\x54\x84\x6d\xc0\x56\x7c\x5f\x02\xad\xb8\x4f\x34\x69\xb7\x01\x97\xa3\xff\x01\x63\xe8\x7f\xcb\x7a\x02\x06\xd2\x80\xde\x6a\xb0\x2c\x7c\x70\x46\x11\x90\x43\xac\x3e\x93\x8e\x2c\x68\x3e\x86\x3c\xa0\xca\x11\x8d\x49\xc1\x4f\x0d\x00\x27\x9d\x97\xe5\x91\x14\xda\xcc\x62\xb8\x61\xfd\xfa\x07\x8f\x5e\xbe\x9a\xf4\x97\x72\xf8\x95\x0a\xa7\xa0\xbf\x8c\xe9\xf5\xf7\x1f\xca\xd0\xdf\x4c\x91\xff\xe6\x82\x30\x49\x7f\x19\xda\xeb\xaf\xd2\x46\xea\xaf\x46\x36\x66\x5c\x02\xed\xd2\xdf\xcb\x36\xac\xff\xaf\x91\x19\xc5\xf2\xcb\x0c\x87\x52\xeb\x6f\x87\x85\xd2\x5f\xc6\x6e\xfa\xdb\x29\x8e\xdf\x5e\xb0\x6d\xf4\xb7\x3b\x79\xf5\x78\xc7\xc0\x10\x4d\x7f\x27\x64\xf1\x28\x7e\x40\xb4\xe9\x10\x60\xe4\x74\x60\xc1\x0f\x81\xb9\x7f\xd2\x01\xbb\x7a\x88\xb5\x09\x3a\xaf\x74\x00\x51\x1e\x02\x55\x39\x10\x28\x1c\x52\xa1\xc1\x07\x62\xea\x91\x0e\x69\xf8\x65\x64\xb4\x09\x85\x3e\x10\xa7\x1e\xf2\xfa\x81\x43\xc0\x06\xb6\xe7\x10\xea\xeb\x21\xd3\x10\xcc\x1e\x8c\x35\x0f\xf9\x7a\x40\x2c\x87\x0a\x5d\xcd\xa1\x5b\x2c\x98\xb2\x43\x77\x85\x3b\x06\x74\x38\x54\x77\x10\xbc\x55\x29\xc8\xc0\x0a\x1c\x3a\xa6\x7d\x59\x07\x3b\xf1\x20\xd0\x39\xf4\x4e\x87\xc1\x25\x1c\xf6\x06\xa0\x87\x69\xd9\xd3\x61\x27\xf9\x43\x9a\x87\x95\x0a\x32\x59\x0b\x8b\x7b\x20\xc2\xa1\x4f\x38\x8c\x0e\xe9\xb0\x06\x2b\x77\x18\xdb\x60\x42\x06\x98\x7e\xd8\xc8\xac\xce\x32\xbc\x4f\x22\xf6\xc3\x7e\xd3\x51\xe4\x04\x81\x88\x0a\x1c\xd9\x51\x30\xf9\x82\x29\xa6\xa3\x60\x1e\x85\x3b\xf7\x00\xd6\x3a\x8a\xb3\x14\x88\xeb\x28\xce\x2a\xdc\x5a\x47\x59\xb6\x83\x92\xc3\x93\x0e\x97\x9a\x0e\xcf\x90\xb5\x9f\xe9\x00\x8c\x3a\x1c\x33\x72\x9e\x8e\x1c\x08\xcb\x0e\xf7\x99\xde\xed\x85\x28\x73\xf0\x05\x81\xc9\x81\x20\x1f\x96\x03\xd6\xeb\x70\x98\xb5\xc3\x83\x61\xf3\xe1\x63\x90\x17\x51\xdc\xc1\x63\x84\xc3\x7f\xd3\x11\x72\x52\x4a\xc1\xa9\x84\xfe\xb7\x60\x43\x8e\x50\x8c\x28\x0c\xaa\x74\xc0\x0c\xa2\x10\x23\x0a\x67\x31\x50\xd2\xc1\x38\xe9\x08\x07\x5c\x3d\x62\x41\x44\x80\x1d\xc7\x6a\xf8\xb5\x27\x1d\x2b\x1a\xd5\x0d\x20\xfd\x58\x5c\xf4\x53\x18\x44\x31\xd8\x3e\xa5\xc8\xef\x83\x84\xe0\xfe\xc4\x18\x4e\xe9\xe9\x14\x1e\x10\x9c\x12\xdb\xbf\x14\x31\xd4\x29\x51\x2c\x23\xa1\x9d\x3b\x65\xe0\x87\xda\x13\x75\xa8\x71\xa7\x2c\x36\xf8\xd3\x74\xc2\x14\x49\x41\x6a\x6b\x20\x09\x66\x22\xde\x38\xb5\x2d\x28\xc0\xa9\xe3\x1d\xd4\x85\x09\x9d\x06\xb3\x79\xc2\x5f\x9c\x76\xc2\xa2\x9f\xaf\x82\x9c\x16\x72\x1c\x78\x8d\x92\x4e\x38\x8e\xb3\xc8\x0e\x02\xd5\x3c\x8b\x04\xe9\x18\xe9\x2c\xf0\x7f\x67\xb1\xda\x07\x52\xdf\x48\xbd\x82\x62\x8a\xc5\xd9\xda\xef\x74\x22\x9c\x3e\xa1\x18\xa7\xef\x3b\x14\xeb\xc4\x4a\x9f\x58\xe2\x93\xc1\xc3\xe9\xf0\x5a\x92\x4e\x1f\x5d\x0b\x92\x61\x3d\x9d\xf0\xcf\x2d\x9d\x10\xfe\x19\xb2\x81\x60\x14\x8c\x92\xcf\xe0\x14\x02\x16\xee\x64\xac\x7c\x86\x7c\x01\x03\xce\x50\x74\x15\x0a\x49\x86\xed\x20\x7a\x80\x22\xd7\x33\x17\x20\x7c\x75\xd0\x3b\x9d\xb1\xc0\x68\x41\x79\xce\xc5\xd1\x2d\x4e\x6d\x59\x41\xbe\x4d\x89\x74\xae\x96\xce\xa7\xa6\x4b\x60\xbd\x18\x75\x5d\x52\x8e\x74\x49\xad\x8a\xe7\x4a\x75\xbb\x60\xbc\x2e\xe9\xfd\x49\x17\xa2\x49\xe4\x04\x72\x62\x5c\xa0\x5f\xe8\x30\x82\x2f\x9e\x93\x5c\x72\x7f\xd2\x25\x7f\xac\x82\x08\xff\x52\x29\xf3\x42\x12\x13\xf4\xfb\xa4\x0b\x3e\xf3\xf2\x33\x5d\xaf\x7f\xbc\xb4\x14\x07\xad\xca\x97\x9e\x2e\x6d\xe9\xd2\xf0\x74\xd9\x0e\xe5\xb9\xec\xbc\xd2\x05\x10\x70\xc1\xda\x5d\xd6\xd3\x85\xfd\x7e\xd9\x98\x58\x98\xcb\xb7\x0d\x34\x03\x7b\x5c\x58\x88\xcb\x8b\x82\x18\x50\xe9\xf5\xee\xbf\x0b\x01\xcb\xe5\x8d\x75\x1c\x75\x3a\xde\xa3\x81\xc0\xc5\x5c\x74\x85\x97\x8f\x37\x90\xa6\x5a\x5d\x3e\x15\x8f\x0b\xc5\x30\x5b\xd7\xda\xd2\x05\x3d\xbd\x56\x95\x06\x0a\xcf\x7a\xad\x0a\x06\xab\xed\xa1\x3b\xd2\x13\xc3\xc2\x2a\x5c\x2b\x76\x56\x08\xe6\x40\x0a\x6b\x6c\x14\xea\xb3\x61\x29\x81\x04\x2d\x7b\x4b\xb6\xab\x24\x1e\x2b\x23\x48\x34\xb4\xb2\xb3\x21\xc8\xc1\xcc\xad\x00\x2a\x30\xa5\x21\x33\x02\x74\xab\x46\xdf\x67\xb5\x12\x2f\x5b\xad\xb0\x1f\x56\x3b\x3c\x9c\x55\x7a\x17\xab\xef\xc9\xa5\xd5\xbe\xe0\x1c\x0c\x91\x84\xb5\xd7\xbd\x59\x63\x20\x67\xed\x1f\xfc\xb6\xb6\xeb\x2f\xa8\x11\xcd\x58\x23\x8a\xb3\x06\x24\x15\x4f\xb2\x06\xef\x81\xa4\x58\x66\xea\x51\x93\xb5\x0b\xd6\xde\xda\xa5\x50\x49\x6b\x36\x81\x79\xad\xfd\x28\x2b\xfd\x2c\x36\xad\x2f\x47\x20\x59\x6b\xcd\xb3\x92\x53\x5f\xa0\xff\x2d\x63\x9d\x81\x70\xcb\xda\x78\x1b\x22\x2c\x44\x42\xa7\x69\x0d\x11\x0f\xd8\x4e\xce\x0e\xf8\x02\xda\x67\x6d\x7a\xb2\xf6\x7d\x9f\xbf\xc6\x4e\x5e\x4f\x6f\x01\xc1\x8e\x02\x79\xdb\xf0\xc2\x01\x8c\xb1\x34\xd9\xd4\x9a\x00\x75\x9f\xf4\xf3\x1e\x55\xfd\x08\x76\x4c\xfa\xe1\xef\xef\x2f\xfd\xa8\x14\x38\xce\x1f\x95\x06\x5a\xca\x93\x7e\xf4\xd6\x92\x7e\x7c\x4b\x3f\x08\x90\x7f\x00\x2a\x7e\x7c\x05\x94\x0a\xb0\xe8\x67\x01\x0f\xfe\x2c\x2c\xea\x0f\x62\xef\x9f\xc5\x53\xea\x9f\xd5\xcc\x03\xc9\x27\xf1\x10\xff\x23\xed\x94\x70\x4f\x1f\xec\xe9\x8f\x6a\x4f\x1f\x38\xc7\x85\xf4\x49\x1f\xcb\x9f\xf4\xb1\x1d\xbf\xc6\xf7\x86\xe7\x76\xee\x5e\xd3\x07\x70\xfe\x63\x13\xbf\x8c\xbd\xf2\xc1\x94\x3f\x36\x27\x9f\x6f\x4b\x9f\xa6\x9a\x3e\xcd\x0e\x50\x38\xae\x4f\xf3\x3b\x15\xd9\xf0\xd3\x02\xea\x91\x8a\xec\x00\xa3\x45\xf6\x27\x15\xf9\x68\x2a\x08\xf7\x8a\xb4\x73\x41\xb7\x8a\xf4\xe9\x78\x0f\xbe\x4c\x56\x9d\xd6\x52\x41\xdc\x07\xda\x00\xbc\x8b\x7c\x25\x15\x01\xfb\x1b\x65\xf7\x80\x33\x29\xf2\xb0\xfe\xdf\x93\x8a\x0a\xbb\x51\x39\x40\xa2\x81\x7e\x35\x01\x03\xc3\x7e\x17\x3d\x66\x2a\x7a\xa6\x57\xc1\x8b\x9e\x70\x5c\x45\x6d\xbc\xa5\xd5\xd1\x82\x59\xed\x9c\x17\x92\x91\x8a\x7a\x87\x91\x01\x8a\x65\x39\xcf\xe0\x0a\xe2\xb0\x54\x4c\x22\x15\x40\x8b\xf9\x20\x0d\xc0\x94\x62\x99\x3b\xa4\x40\x28\x05\x6e\xe2\xf5\xf1\xc5\x30\x71\xab\x1b\x08\x06\x8e\x28\xa3\x00\x8e\x14\xfb\x0f\x0e\x9e\x38\xb7\x18\x8f\xba\x10\x73\xa6\x62\x34\x6f\xc5\x85\xa4\xa5\xe2\x1b\x4d\x65\x71\x40\x0e\x02\x85\xe2\xa7\xe5\x54\xbc\x69\x79\x90\x9c\xa9\x38\x64\xe9\x18\x26\x72\x16\xda\x2e\xb8\x66\x3a\x95\xe2\x0f\x9a\xae\xfc\x79\x52\x59\x27\x71\x77\x59\x0c\x98\xcb\x6a\x42\x9a\xaf\x54\xd6\x2f\x76\x52\x79\x02\x08\xb7\x4a\xbe\xe0\x08\xab\xec\xa9\x0a\x3a\xac\x72\x36\x9d\xa9\x8a\x21\xc7\x4a\x62\x6c\x56\xe5\xc7\x23\x55\xac\x70\x95\x5a\x05\xd9\xc8\x6d\xe8\x05\xe1\x33\x76\x45\x95\x76\x3a\x28\x31\x77\x15\x7e\x39\xa9\x02\x80\x5c\x25\xb6\x37\xc9\x17\xe8\x49\x9e\xf1\x76\x1d\x1f\x76\x18\x61\x2f\xb7\xf1\x01\xc1\xe0\x28\x93\xca\x23\x43\x6c\xfc\x30\x32\x9c\x7c\x0b\xfb\x45\xf2\xd6\xf8\xb5\xba\x6a\xaa\xf0\xfb\x55\x65\xf7\x1b\x49\x03\xa1\x06\x54\xf8\xbe\xaa\x40\xe7\x98\xa2\xee\xe0\xa3\xbb\x49\xaa\x5a\x10\x09\x55\x2d\xa8\x40\x69\x55\xad\xd8\xd2\x00\x19\x9c\x87\xb6\x95\xaa\x46\x46\x16\xf4\xb8\xd2\x40\x55\x9e\x07\x56\xe0\xa4\x8a\x58\x82\x05\x93\x7c\xe7\xe5\x7b\xaa\xb6\xc3\xfc\x56\xdb\x1b\x95\xa4\x5a\xf9\x80\x50\x2f\xaa\x21\x76\xac\xd8\x91\xd5\xda\x3b\x76\x43\xbc\x5b\xad\x21\x42\xa8\x16\x92\xd9\x9a\x5e\xa5\xda\xc0\x92\x33\x06\xaf\x08\xb9\xb1\x0c\x98\xbe\xfd\x2a\x38\xfc\x72\x13\x54\xdf\x00\xe5\xaa\xef\x5a\x40\xe1\x02\xaa\x57\xfc\x60\x25\xab\x37\x43\x34\x58\xdf\xf8\xba\x7a\x7b\xa5\xeb\x0d\xf2\x74\x8c\x8a\x67\x62\xd5\xc9\x2b\x1a\x82\xdf\xea\xe3\xbf\x65\xd3\x53\x7d\xcf\xc6\xff\x45\x88\xd5\x5f\x4e\xab\xf1\x38\xa8\xf2\xfb\x40\x85\x16\x56\xff\x9a\xa6\xba\xb0\x62\xeb\x38\x50\xb8\x30\xa8\x55\xa6\xf5\xf2\xa4\xba\x06\x27\xb6\x86\x62\xd2\x6b\x5c\x3c\x7b\xaf\x6b\x40\x20\x30\x6b\x75\xf1\x13\x66\x7d\x86\x96\x03\x09\xd5\xbd\x3e\xf3\x4a\x4d\xb0\x79\x1a\x60\x62\x93\xfe\xb1\x96\xda\xfb\xd5\xab\xc9\x98\x4f\x6a\xc2\xc1\xb5\x37\xba\x68\x2a\x91\x9a\xe6\x4f\x6a\x08\x29\x9a\x9e\x32\xd9\x5c\x4f\x9e\x48\xb6\x7f\x41\x75\xd3\x7e\xe9\x9d\x9a\x06\x0b\x07\x4a\xf8\xe3\x37\xb3\xa6\x6b\x42\x2a\x8d\x01\x47\xd3\x7b\xa4\xa6\xbf\x33\x35\x98\xe7\x77\x65\x9b\x43\xb5\x9b\x23\xa2\x6b\x5e\x0d\x86\xb3\xb9\xef\xcc\x0c\xec\x95\xe6\x81\xd1\x3b\x2b\x4c\x79\xab\x4f\x92\x0b\x52\x6e\x88\xf2\xf0\x0a\xd3\x03\x33\xdb\x56\x2e\x1c\xfe\xbb\x7f\x1b\x8f\x1c\xdb\x9a\xc9\xe5\x93\x7c\xd3\x27\xf9\x46\xbf\xe8\x5b\xb1\x53\x93\x6f\x23\x63\xce\xbe\x0d\x4e\xc3\x37\xae\x8b\x6f\x5f\x1e\xdf\x79\xce\x2b\x92\x67\x6c\x09\xcf\xd3\xc1\xd3\x77\x8f\xe4\xc7\x81\x9f\xf2\x09\x43\xf0\x03\x0e\x00\x61\x87\x7f\xe4\x49\xc0\x41\x4e\x8b\xe5\xe5\xa9\xdd\x72\x72\x18\x38\x07\xec\xf5\x86\x1f\x04\xee\x8d\xe7\x70\xde\xca\x93\xbc\xa3\x7d\x47\x20\xee\xdd\xde\xe2\x4e\x08\xe1\x9d\xab\xe3\xef\xb7\x4b\x0f\x40\x46\x8f\x4c\x28\xf8\x9e\x2a\x79\xec\xd6\x60\x68\x3d\x4e\x8c\x34\x78\x80\xed\x61\x27\xe3\x36\x8f\x7e\x21\x7b\x4c\x9e\x14\xbc\x0a\xe9\x6b\x12\x5d\xf8\x9a\xef\x1b\xa0\x80\xaf\x49\xaf\xef\x08\x18\xfd\x8b\x11\x61\xf5\x80\x98\xfd\x06\x74\xf0\xdf\xe7\x44\x2e\x95\x2b\xf9\x1f\xe6\x42\xb8\xd3\x85\xbb\xb6\x63\x3b\xf3\xb0\xae\x4b\x01\xba\xee\x52\x6a\x42\x10\x2e\xa0\x5a\x40\x2d\x83\x72\x14\x5d\x3a\x69\x20\x9e\xee\xc2\xb3\xd2\x2e\xf1\x01\x09\xe7\xf3\x7c\x52\x87\x51\xeb\xb4\x66\x1d\x46\xac\xcb\xb4\xb7\x26\x4f\xac\x3b\x8d\x59\x4b\x9d\x5f\x41\x3a\xfc\x5b\x97\x87\x7b\xb7\x2b\x07\xa1\x02\x1d\xe0\x07\xe5\xae\x32\x84\x25\xc5\xb2\xb4\x04\xb1\x77\x6d\x82\xa8\xbe\x6b\xcb\x56\x52\x57\x87\xe9\xed\xca\x53\xef\xae\x71\x40\x63\xba\x06\x96\xb0\x6b\xc0\xe9\x75\x9d\xa9\x5f\x9c\xfe\xe5\xd3\x53\xbf\x78\x7a\xd2\xaf\x67\x18\x3c\x51\x37\x69\x9e\xba\x65\xce\xd6\x5e\x6f\xdb\x4d\x31\x1a\x3b\xf1\x53\x70\x01\xba\xec\x56\x30\x53\xf8\xbe\x6e\xde\x14\x7d\x5a\x47\xbd\x31\x31\x3b\xe3\xbc\xed\xef\x4f\x52\x7f\x65\x5a\x04\x3b\xad\x97\xf7\xe4\xae\x13\x59\xf1\x58\xb1\x17\xe2\xc8\x5e\x78\x34\xd6\xe1\xd3\x40\x4f\x10\x28\x4f\x77\xad\x20\x33\x75\x07\x9a\xef\x5e\x20\x12\x00\xf6\xee\xf0\xd2\xa9\x7b\xdb\x41\x9e\xd4\x1d\x9d\x7b\x5f\x6f\x95\xa0\x12\xf2\x00\xf7\xdf\xc3\xb0\x8d\xed\x06\xf8\x4c\x81\x10\xfe\xb9\xd8\x0e\xad\x81\x3c\xfd\x86\x7a\xbe\xa7\x61\x3d\x24\x73\xb7\xf6\x10\xec\xf8\x1e\xca\x1b\x16\x3d\xf4\x60\xb1\x62\xfd\x91\xf2\x2a\x48\x0f\x9d\x60\x11\xfa\x7d\x5f\xdf\xa6\xd0\xce\x1e\x56\xa1\xed\x3d\xec\x2d\xf1\x30\x56\x35\xae\x4c\xd8\x97\x02\x09\xfb\x03\x85\x91\xa9\x48\x79\xd2\xd4\xc3\xf7\x45\x4e\x7e\x60\x35\xc3\x79\x4c\xdc\xc3\x69\x16\x7a\x78\x75\x36\x76\x3f\x40\xfb\x3b\x91\x40\x24\x89\x41\xfa\xfc\x57\x6d\xed\xa0\x3c\xb5\xed\x6b\x43\x7c\xdd\xd7\xbe\xc3\x28\xf5\x85\x45\x5d\xa5\xa7\x17\xf2\xf7\x55\x69\x72\x3b\x61\x44\x5f\x1d\x2a\xb6\x10\xd4\xf5\x15\xef\x17\xb4\xbe\xde\x19\xac\xe0\x8e\xef\x34\x5b\x7d\x0d\x54\x9f\xa9\xaf\xbf\x3f\x48\xfa\x09\xa9\xb6\xa7\xff\x96\xf0\x12\xcd\x7f\x4b\xda\x5c\x15\x69\x60\x37\xfe\xb7\x74\x70\x6d\xfe\x5b\x40\xb0\x70\x3f\x20\x7f\xe9\xbf\x85\x29\x85\x6c\xb0\x1c\x21\x39\xc3\x67\x31\xf6\xe5\x77\x97\x90\x5d\x02\xd4\x3c\x05\x80\x0b\x03\xe2\x77\x91\x42\x80\xbc\x03\xd8\x34\x04\xc3\x0f\x69\x80\xc1\xaf\x2d\x0a\xe9\xb6\xa7\xc0\xb2\xf1\x3b\x42\xbc\x67\x09\x21\xb0\x1c\x21\x77\x0a\xf9\xf3\x48\xef\x2d\x14\x7e\x69\x44\x9c\x83\xce\x15\x48\x38\xf4\xfd\x12\x1c\xca\xef\xb1\xa1\x59\x61\x31\x43\x33\xd4\x3f\x34\x7b\xb0\x90\x5f\x46\x42\xb9\x6e\xa1\x07\x9d\x50\x28\x83\x9f\xd0\x03\x7b\x3e\xf4\x34\xb2\x3d\x43\x51\x76\x52\x69\x43\x7f\xde\xaa\x45\x7e\x41\xb9\x37\x42\x0b\xc2\x77\xde\x5d\x08\x25\x46\x0b\xfd\x07\x60\x42\x89\x2c\x42\xe9\x91\x43\xdb\xce\xcc\xa6\x77\xa2\x65\x0a\xa5\x95\x86\xa6\x1a\x0a\x3a\xd0\x51\xe8\xbb\x2b\x43\x79\x7b\x27\xf4\xbd\x70\x14\x3a\xf2\x62\xa2\x8c\x52\x43\x79\x55\x24\x74\xf8\x0a\x56\x1f\xdd\x1b\x07\x34\x56\x41\xc1\x7c\x9b\xcd\x78\xb9\xce\x15\xe8\x6a\xb5\x77\x66\xdf\x57\x7c\x5f\xe3\x60\x78\x36\x15\xd7\x33\xaf\x9a\xc2\x36\xfc\x36\x54\xc3\x26\xa1\x91\xe7\x46\x79\x3f\xea\x87\x1d\xe8\x9f\x2e\x17\x2e\x61\x4f\x3c\x9e\x0f\x73\xbc\xf3\x7e\x0d\xbf\xf1\x87\x11\x3f\x04\x4f\x0b\x83\x5f\x78\x02\x38\x3b\xf8\xb5\x32\x7c\x73\xd2\xc5\x17\x46\x6d\xe1\x95\x07\x39\xdc\x2c\xe1\xfe\x31\x3e\xd7\x14\xd0\xe2\x70\x86\xc7\xc1\x53\xea\xf7\x02\x4e\xc0\xdb\xa4\x20\xe0\x8e\xb5\x51\xe6\x08\x84\x63\x9d\x29\x00\x77\x62\x35\xfc\x6e\x79\x52\x2c\xc0\x87\x21\x3b\x7e\xf0\x2d\x43\x76\x46\xdf\x43\x0e\xbc\x18\x0a\x0b\x8b\x0b\xc2\x94\x21\xe5\xa5\x13\x04\xfd\x0c\xe0\x9d\xf1\x1e\x34\x0f\x44\xa1\x43\xa6\x8d\xe3\x41\xea\xe3\xb2\x34\x04\x2a\x35\x64\x11\x85\x0e\x38\x8e\x21\x4f\x1a\x19\x01\xf5\x80\x77\x18\x19\xca\x3d\xf2\x0b\x97\x47\xd6\x86\xb7\x4b\x2b\x13\x58\xc8\x91\x8d\xe7\xac\x23\xdb\x18\x1e\x23\x8d\xec\xc1\x0f\xe7\x23\xfb\x9a\x69\xe4\x90\x0e\x8a\x58\x73\xe4\xb0\xce\xbc\xb5\xa5\xa1\x82\x1f\x80\xfd\x78\xb7\xc5\xc0\xca\x0f\xcd\xb0\xc1\x43\x33\x74\x19\xb1\x38\x99\x69\x7e\x6d\xc4\x00\x26\x1b\xaa\x9f\x34\xf4\xa4\x8f\x1b\xfc\xa2\x81\xa4\xa4\x01\x0d\x96\x48\x43\x19\xf3\x0e\x86\x5d\xb0\xa7\xef\x18\x35\x4c\x07\x12\x7e\x2a\x1b\x3a\xc6\xcb\x9b\x01\xd6\xd0\xb9\x7a\x1a\xb0\xb7\x69\x5c\x8c\x05\xc6\x25\xc7\x04\xe5\x21\xce\xb8\x28\x8c\x0b\x03\xb8\xd8\xdb\xa5\x61\xc7\x91\xc6\xc5\xd3\xe3\x71\x19\x6b\x03\xd3\x8c\xcb\x3a\x08\xb4\x68\x5c\x08\xcb\xc6\xe5\xc8\x76\x47\x15\x47\x21\xb6\xcb\xb8\x7c\xf1\xb3\xcc\xb8\xb0\xe7\xc6\x15\x56\x51\x06\x8d\x18\xd7\x3a\xa0\xba\xe3\x7a\x12\x9c\x0d\xb4\x76\xc0\xb4\x11\xa3\x0c\x53\x2c\x1a\xd5\x9a\xdf\x0a\x87\x15\x8a\x03\xf1\xc2\x30\xd8\xad\x61\x85\xfd\x5b\x35\xd8\x83\x61\xaf\x2a\xf0\xeb\xf6\x78\xb9\x05\x26\x6b\x44\x33\x03\xfa\x0f\xb5\xb1\xdf\x34\xe0\x3b\xc6\x87\xaf\x3c\x1b\x48\xe3\x63\xf8\x61\xd6\x30\xe6\xe3\x63\x18\xfd\x07\xb6\x7e\x20\xb8\x1f\x45\x6a\x1a\x45\xb5\x83\xd2\x72\x0c\x7a\xd4\xc1\x93\xcd\xf1\x46\xbc\xa3\x18\x6a\x39\x60\xda\x80\xdb\x1f\x14\x2c\xcf\xb1\x47\x85\x15\x1c\x55\xc0\xb8\x22\x22\x19\xd5\x3f\xa4\x3e\xaf\x34\x1a\x8c\xf5\x68\x88\x61\x46\x83\x4e\x35\xca\x1e\xb0\x77\x38\xde\x3d\x67\xf4\xea\xfc\x92\x3d\x28\x73\xdf\x25\x0d\xc7\xaa\xd0\xd3\x0f\x2f\xbb\xb1\x4e\xb1\x1d\xf4\xbd\x30\x32\x78\x5e\x33\xbc\x2a\x00\xcd\x40\xc8\x3c\x9c\xf9\x08\xd5\x06\xd7\xc9\x17\x78\x62\x13\x0f\x87\x9a\xbc\x56\x6c\xf8\xc2\xd0\x3a\x0c\xe0\xa0\xff\x1e\x00\x67\xe8\xbf\xcb\xdd\xd2\xe8\x2a\x1f\xd0\x77\x4c\x9d\xca\xdb\xa9\x3b\xfc\x24\x3c\xfa\xa5\x6c\x44\x49\x75\x5e\x44\x18\xdd\x3e\x7c\x41\x73\x43\xc8\x38\x7a\x21\x05\xbc\xa6\xd5\x84\x6a\x77\x8e\x90\x36\x77\x74\x48\xb2\x07\xf6\x6e\xe7\xe5\xa6\xd1\x69\xe3\x46\x7f\xd2\x80\x7f\x54\x24\xbc\xef\x84\xb0\x8c\x37\xd5\xc6\x1b\x4f\x8c\x29\xbb\xad\x8a\x14\xd2\x9c\xb4\x04\x53\x0c\x3b\x79\xc2\xef\x8d\x49\xd3\x31\xb9\x2c\xb4\x68\x63\xa2\xa3\xc9\x99\x4d\x25\x2b\x05\x03\x2c\xfd\xd4\x50\x4f\xc0\x65\x28\xa4\xba\x4c\x8e\x64\x72\x3d\xa6\x57\x81\x32\x4d\x0a\x7a\xd2\x80\xf0\x18\x75\x4c\xaa\xff\x84\x1f\x3d\xf1\x1a\x8a\xdd\x3f\x83\xb2\x98\xc1\x35\x99\xb1\x78\xba\x3e\xe6\xe2\x0d\xd8\x31\x17\xc7\xfc\x9e\x83\x8e\xf9\x80\xae\x37\xc0\x19\x6b\x03\x5c\x1d\x6b\x83\x31\x1d\xeb\xbd\x3c\x3b\x10\x5f\x8e\xc5\x93\xdd\xb1\x18\xc0\x8c\x75\x0a\xe9\x89\x10\x8e\x07\x48\x63\xf1\x18\x7a\x2c\x54\x6a\x0d\xcd\xdb\xc0\x70\x56\x67\x76\x47\x40\x3a\x56\x0f\xda\x41\x20\xdb\xb1\x82\xdf\xc7\xc6\x42\xa0\x3f\x56\x00\x8c\xf1\xe1\x35\xfc\x63\xc5\x57\xd1\xe6\xbd\x45\x39\xd6\x60\x9c\x35\xee\x7f\x96\xe5\xa6\xa4\x6f\x21\x89\x9a\xc6\x0d\xac\x3e\x6e\x0a\xe1\xa6\x59\xb9\xb1\x73\x6e\xca\xf2\x26\x24\x1e\x37\xf0\xc1\x78\xea\x06\x29\x3e\xb5\x4f\xaf\x69\x3c\x01\xed\x7c\xb8\x24\xef\x0a\x4f\xe1\x0d\xa2\x29\x67\xe2\xbd\x81\x29\xb4\x13\x53\xca\x27\x4d\x69\x20\x1d\xc5\xfc\x14\x34\x65\x20\x63\x4c\xe4\xcc\xe9\x9e\xa6\xfc\x5a\x9a\xbc\xbd\x38\x55\x6a\x9a\xd0\x5e\x04\x7b\x53\x1b\x02\x89\xa9\xad\xd9\x40\x82\xe7\x40\x85\x81\xa7\xdf\x99\xe6\x45\xf6\x97\xe0\x11\xb2\x9a\x17\xda\x5d\x8a\x15\x9f\xd4\xfc\x79\x29\x1e\x31\xad\x79\x81\xcd\xe5\xbc\xd1\x35\xaf\x50\x94\xf2\x6b\xfb\xbc\x10\xab\xcf\x6b\xd5\x0d\x94\xc6\x65\xbe\x77\x5c\x26\x8c\xcb\xb4\x93\x39\x05\xef\x44\x32\xd3\xd0\x9b\xb5\x27\x4d\xeb\x09\xc8\x62\x4f\xf3\x3d\x7c\x9d\x06\x63\x3f\xe9\xd4\xa7\x6f\x80\x83\x69\xfa\x2e\x0f\xe8\x5e\xd0\xd8\x51\x7e\x2a\xc1\xdc\x74\x2b\xe8\x87\xd7\xfe\xa0\xbe\x13\xd5\xeb\x7b\x09\x91\x6a\x3c\xbd\x9d\x8b\x09\x4d\x1c\x95\x7a\xd2\x64\x4d\xef\xf8\x59\x06\xed\xec\x15\xde\x6e\x7a\x34\xd9\xc1\x26\x26\x83\xff\xe9\x63\xa4\xe9\x53\xd0\x70\x85\x71\x64\x84\x38\x93\xa1\xc3\x44\x00\x3a\xfd\x49\x93\x80\x75\x32\x5a\x9c\x21\x08\xbd\x91\x9e\x6f\x62\x0d\xb4\x0d\x68\xf5\x84\xd7\x9d\xbc\x39\x34\x81\x47\x4b\xe2\xbd\xd0\x17\x5c\x4d\xca\x16\xf8\x2e\x4d\x1e\x8d\x4d\x5e\x3d\x99\xbc\x0a\x39\xc3\x4e\x8a\x33\xac\x82\x80\x8d\xf7\x0b\x6d\xdf\x9b\x14\x33\x16\xab\x2d\x3e\x16\x14\xac\x8a\x78\x70\x06\xb0\xd1\x0c\x98\xc4\x89\x15\x5e\x60\xba\xde\x80\xe9\xdf\x26\x9d\xab\x09\x08\x42\xe1\xb9\xe2\x83\xd5\x07\xd0\x9b\x2b\xb8\x2c\xb7\xc2\x14\xcf\x5b\xdb\x7c\xd2\xbc\x61\x16\xe7\x8d\x89\xdd\x94\xca\xed\x69\x3e\xd0\xd6\xa7\x33\xcc\x5c\x67\x79\xd2\xaa\x5b\x68\x29\x92\xd6\x7b\xd5\x60\xb5\xf7\x36\xf0\x6a\x99\x6f\xef\xc5\x94\x57\x6d\x56\xdb\x3d\xad\xc6\x2b\xea\xab\xf1\x13\xe9\x6a\xef\x27\xa6\xd5\x8c\x98\x7a\x35\x5e\xcd\x5e\xcd\x26\xc8\x57\x11\x8c\xac\xf6\x69\x58\x85\xd5\x78\xc6\xba\xda\xb4\x92\x56\x5b\xbc\xa7\xb8\xda\x57\xf1\xda\x79\x9a\xb9\xfa\xc9\x05\x5a\x9d\x9f\x83\x56\xf7\x96\x16\x43\xe9\xd5\x61\x45\x56\x6c\xd2\x12\x0d\xc5\x0b\xbc\x80\xe0\x79\xe5\x7c\x0d\x3d\x56\x41\xc2\x0b\x12\xff\x98\xcf\xf7\x3f\x03\x5f\xc9\xd8\x6e\x5f\xc9\x6b\xd5\xf4\x15\xe8\xdc\x57\xe0\xc7\xbe\xef\x3d\xf8\xaf\x40\x74\x5f\x69\xf8\xd9\xb8\xd2\x57\xba\x47\xfa\xca\x7b\x15\xeb\x0b\x85\xff\xf2\x83\xfa\x57\x2f\x83\x68\xbe\x10\x36\x5e\xdb\x8e\x8a\xbc\x14\x89\xdc\x06\xd6\x1a\x1b\x88\x1d\x0f\x12\x02\xa5\x2f\x82\xdb\xaf\x8e\xa1\x25\x7d\x75\x6a\xa0\x2f\xa3\xcc\xbf\xb6\xf1\x0b\xe2\xd7\xf2\xdb\x9b\x65\xda\x75\x04\x88\x9e\x88\xda\xbf\x56\x0a\xa6\xfb\xb5\x36\xdf\xd4\x8b\x81\x41\x10\x77\x7f\x2d\xd8\x6e\x08\x88\x81\xd5\x78\xf3\x27\xe9\x17\x33\xe5\x29\xf7\x97\x17\x25\x79\xf9\xfb\xeb\x25\x4b\x73\xa4\xab\x22\x6f\x82\x3c\x60\x7f\xff\x23\xde\xd2\x2d\x36\xd3\x0d\x7b\x07\x7b\x0b\xd2\x16\x32\x1a\x48\x1c\xd0\x15\x5a\xdd\x5b\x02\xc1\x74\xba\xb1\x6d\x6e\x19\x1d\x64\xa2\x10\xf8\xe8\x06\x3e\x86\x33\xb9\xdf\xef\x8a\xb7\x0a\x96\x96\x96\xfa\x46\x6c\x55\x90\xd0\x68\xdc\xba\xa5\x5b\xdf\x70\xf8\x56\xfd\x60\xa7\xdd\x6a\x01\x5a\xf8\xcd\xeb\x86\x91\xbc\x75\xa6\x9b\x5f\xaf\x6e\xd8\xc8\xfb\xd2\x97\x82\x13\x2c\xe5\x4d\x13\x79\x03\x4a\xde\x97\x31\x02\xbf\x61\xef\x6e\xdb\xd1\xbf\x1d\x78\x2c\x3b\x48\x49\xd8\x25\xb7\x35\xc0\xd6\x1b\x08\x94\xae\xe2\xb6\xf6\x01\x69\x6c\xca\x4b\x31\x37\xc2\xac\xdb\x06\xc2\xd8\x1b\xd6\xe7\x86\xae\xdc\xff\xee\x28\xdc\x5e\x8e\x74\x23\xae\x49\xb7\x73\xc7\xdc\xee\x3b\x48\x49\xf4\x37\x3c\xdc\xbc\x3d\x0a\x1f\xe3\x01\xc5\x60\x60\x6f\xee\xd0\xfc\x01\xe5\x25\xde\x9b\x86\xec\xe6\xcd\x8d\x9b\x0e\xfc\x81\x49\x7b\x20\xaf\x47\xe9\xf7\x1e\x5f\xf8\xa1\x88\x40\xea\x4f\xb7\x90\xf4\xa7\xe1\x89\x47\x6b\x7f\xee\xe9\xff\x00\x00\x00\xff\xff\x96\xd2\xdb\xc1\x3c\x33\x00\x00") + +func keysWordlistEnglishTxtBytes() ([]byte, error) { + return bindataRead( + _keysWordlistEnglishTxt, + "keys/wordlist/english.txt", + ) +} + +func keysWordlistEnglishTxt() (*asset, error) { + bytes, err := keysWordlistEnglishTxtBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "keys/wordlist/english.txt", size: 13116, mode: os.FileMode(420), modTime: time.Unix(1497960590, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _keysWordlistJapaneseTxt = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x5c\x5c\xff\x72\xe2\xb8\xd2\xfd\x9f\xa7\x5e\xbc\x5c\x2f\x01\x3c\x0e\x71\x1c\xc7\x61\x58\x87\x8a\x2f\x43\x60\x80\x0c\x59\xb8\x93\x8f\x2c\x3c\x8c\x5f\xe4\x2b\xf5\xe9\x3e\xea\x99\xaa\x54\xea\x1c\x59\xd6\xcf\x56\x77\xab\x25\xd3\xf5\x93\xae\x3f\xe8\xfa\x45\xd7\xcf\xbb\x7e\xd5\x25\x45\xcf\x92\xca\xae\xdf\x92\x3c\x03\x8d\xba\xfe\xdf\x5d\x72\x03\x32\xee\xfa\x8b\x2e\xf9\x93\xef\x64\x5d\x32\x06\x9a\x76\xfd\x49\xd7\x6f\x8c\x58\x72\x11\x92\x93\x09\x79\xd9\xf5\x07\x44\x07\xa0\x4a\xfe\xaf\x40\x1e\xbb\x24\xef\xfa\x29\xc8\x53\xa8\xd1\x5e\x7d\xea\xfa\x19\xd0\xbc\xeb\x9f\x80\x9a\xae\x3f\x64\x86\x26\xfc\x25\x7d\xc7\x93\x51\xd7\xbf\x74\xfd\x21\xb9\x3e\x69\xd9\x8a\x56\xfa\xa4\xd5\xbd\xc8\x70\xfc\xa7\xeb\xe7\x7c\x78\xe9\x92\x91\x11\x57\xf4\xb2\xeb\xaf\x89\xf6\x92\x4d\x9f\x1c\x88\x4e\x1c\xb5\x13\xd3\x8e\x7e\x2c\x2e\x6c\xc5\xa5\xeb\xbf\x1a\x4a\x06\xd2\xa4\x9a\x5c\xeb\xbf\x76\x49\xd2\xf5\x77\x42\x42\x4b\x46\x5d\x1f\xe5\x84\x17\x58\x7f\x92\x76\xc9\x1f\x40\x37\x32\x8b\xb7\x5d\xff\x42\x5e\x11\xd5\x5d\xff\x91\xc4\x8f\x5a\x72\x23\x65\x44\x92\x5b\x5b\x42\x8d\x93\xae\xbf\xb2\xe1\x0a\x4f\x66\xcc\x99\x87\xa1\x30\x52\x58\xcf\x12\x99\x7f\x47\x0a\xa2\xaf\x26\x44\x81\x2c\x7d\x9e\xb5\x27\x3a\x00\x03\x88\x24\xda\x32\x08\x52\x29\x6f\x0f\x58\x3c\x50\x0e\x94\x89\xd8\x0e\x48\xd6\x2c\x24\xe3\x28\x0e\x28\xbd\x03\x59\x08\x8f\x44\x27\x96\x3d\xed\xfa\x6f\x98\x69\x21\x96\x5c\x60\x08\x74\x0d\x11\xb5\x3d\x5b\x44\x17\x11\xea\x81\x71\x7b\xaf\x82\x04\x0f\x44\xca\xff\xc3\x42\x1e\xbb\xe4\x2f\x4f\x72\x36\xeb\xa9\xeb\x5f\x0d\x25\x13\xa0\x19\x0b\x9e\x05\xe1\xef\xbf\x93\x8c\xfd\x13\xad\xe8\x2b\x2b\x9f\x77\xfd\xb4\x4b\x32\x56\x34\x97\x01\x8b\xcd\x7c\xf6\x48\x3b\xd5\x48\xc5\x37\x24\x57\x43\x41\x16\x12\x90\x85\x8c\x75\x4a\xf2\x48\xf4\x4a\xf4\x46\x74\x32\x94\x8c\xfc\x10\xb4\x10\xe6\x41\x5c\x83\xd6\xec\x17\xdf\xe3\x17\x74\x83\xa4\xf1\xd9\x16\x44\x4b\xff\xc2\xbf\x7c\x61\xd9\xf5\x1f\x0c\xd9\x7b\xaf\x7c\xba\x82\x70\x0e\x28\x7f\x40\xda\xac\x6d\x97\xfc\x41\x21\xda\xb1\xb2\x1d\xa7\x6a\xcf\xf9\x7f\x73\x69\x56\xcd\x3b\x27\xe4\xc0\xb4\x23\x87\xf9\x27\xd3\xce\x6c\xce\xd5\xd2\x82\xbc\xa6\x50\x8f\x20\x8d\x89\x42\x92\x58\x8b\x12\x91\x7e\xad\x36\x10\xac\x92\x64\x28\xfa\xb3\x20\x41\x7d\xa2\x19\x88\x6a\x96\x3d\x12\x6d\xb1\x30\x12\x85\x32\xe1\x1a\x0b\xda\x8b\xeb\x27\x89\x55\x66\xa2\x87\x8b\xae\xff\x8f\x0d\x43\x50\x08\x03\xa2\x94\x28\xb6\x27\x37\xb9\x08\x02\x9f\xb2\xa8\xa2\xeb\xdf\xd9\xca\xef\x33\xa9\x64\xb9\x85\x08\x48\x6c\x5b\x21\x3d\x0b\x24\x95\xf5\x90\x19\x92\x02\x53\x91\xce\x07\x20\xed\x46\x2a\x4b\xe5\x44\xf4\xc1\xac\x59\x97\xe4\x40\xb9\xe9\xcf\x35\xf9\x04\xe3\x9e\x8a\x5a\x68\xa4\x7d\x39\xdf\x9c\x8a\x0c\x4f\x49\x56\xee\x49\x18\xb1\x96\x44\x93\xef\xa9\xe5\x41\xb4\xde\x02\xc3\x93\x4a\x8f\xbf\x00\x55\x22\x88\xa9\x91\x30\xd8\x13\xac\xc5\x54\xa6\x6f\x40\xf4\x85\xe8\x96\xb3\x2c\xdc\xf4\x7b\x2a\xab\x49\x1b\xb3\xa0\x16\x27\x9f\x70\x00\x16\x1c\xc9\x05\x17\x6a\x2a\x0b\x6a\x0c\xa9\x4b\xa5\xc7\x39\x55\x48\xaa\x2b\xd2\x8d\x7c\x4b\xf4\xca\x6e\xad\xd9\xca\x35\x74\x05\xd0\x13\x47\x60\xcd\x97\xb6\x44\x3b\xd6\x7f\xea\xfa\x77\x44\xf7\x30\xed\xa9\xcc\xc5\xc4\x72\xc7\xbe\xca\xd2\x01\x12\x1b\x69\x64\x68\x95\x85\x31\x9a\x88\xd4\xd4\xe4\xba\x04\x40\xd6\xd6\x37\x51\x78\x56\x77\x20\x99\x49\x43\x32\xa6\x57\x93\xca\x4a\xa9\x1c\x49\x52\x1b\x46\xd7\xbe\x0c\x9a\x26\x95\xb1\xcf\x88\x4a\xa0\x82\xf6\x05\x64\x61\x43\x07\x3b\xe9\x88\xea\xae\xa1\xc8\xe9\x10\x4f\x40\x26\x44\x19\x97\x0a\xf8\x3d\x91\x6a\x55\x90\x93\x7b\xdb\x96\x13\x48\x0e\x34\xc2\xa4\x0f\x65\xbc\x22\xd2\xa7\x99\x4c\xbc\x16\x17\xdd\x82\xa1\x88\xeb\x9f\xcc\x56\x77\xfd\x25\x50\x2b\xae\x85\x56\xb9\xeb\xfa\xb7\x40\x67\x9d\x4c\x19\x15\xe1\x96\x87\x69\x61\x4e\x1f\x89\x76\x40\x37\x56\x79\x40\x27\x20\xb5\x50\x50\x4b\x1c\x9d\x40\xc6\xcc\x5d\x40\x18\x87\xaa\x75\xac\x8a\xc2\xfc\xc0\x94\xfc\x2b\x56\x0d\xc8\xdc\x7a\xa4\xf3\xf3\x97\xcf\xb9\x42\xce\x91\x8c\xeb\x98\x4b\x7e\x64\x5e\x42\x4d\xa2\x82\x32\x32\x0b\x98\x83\xa4\x6c\xee\xc8\x14\xc1\x85\xe4\x91\x68\xc6\x7a\x52\x8e\x3e\xc8\xd1\x17\xf5\xe1\x9e\xd8\xcc\x8e\xb8\x48\x47\x74\x94\x46\x34\xe3\x40\xaf\x9c\x73\xe1\x09\xf3\x84\x42\xe6\x20\x63\x0c\x34\xc9\x13\xd0\x04\x2e\xa8\xa4\x05\x15\xa9\x19\xbe\x50\x8d\x8d\xe8\x7a\x8d\x44\x5c\x62\x0f\x73\xef\x0d\x09\x57\xaf\x73\x4d\xce\xd7\x6c\x45\x8d\xfc\xb0\x16\xbe\x92\x82\x19\x4a\xdf\xe3\x92\xeb\x5a\x88\xe9\x8b\x11\x66\x04\xeb\x1a\x24\xbe\xf3\x08\x49\x01\x2a\x39\x3d\x22\xde\xf6\xc2\x5c\xc4\x2f\x27\x89\x8d\x6d\x68\x7b\x40\x34\xcf\x33\x9c\x7d\x90\x85\x97\x81\x17\x18\xe5\x91\xac\x14\x1d\xbf\x6f\x10\x27\x90\x95\xd4\xad\x2b\x00\x7c\xed\x25\xea\x95\xaf\xbd\x8a\xc2\x19\x73\x84\xde\x7c\xfb\x2f\xb0\xf5\x42\x92\xbe\xd4\xb1\xb2\xe1\x4b\xb0\x0d\xfc\x46\x12\x93\x29\x6e\x81\x84\x0d\x21\xc8\xc0\x44\x32\x19\x88\xe6\x7b\xef\x99\xc0\x7c\x5a\xf5\xb2\xec\xb1\xb7\x1c\x49\xc3\x34\xb9\xa0\x3a\x01\x99\xb2\x06\x2c\xc6\x3f\x49\x66\xd6\x78\x29\xc7\x93\x68\xa8\x46\xa6\x1f\xb5\x98\x31\x76\x70\x40\xaa\x1f\x27\xd0\x8f\x44\xea\xde\x4f\xbc\x87\x3f\xf6\xbb\xe2\xb1\x2e\x5a\x69\x0b\x48\xed\x1d\xab\xb1\x77\xb8\x41\xfe\x86\xf1\x23\x6f\x7d\xb1\x4b\x9f\x73\xe5\x9f\xe8\x02\x9e\xa8\x73\x28\x8d\x1c\x7b\xff\x70\xec\xf5\xf4\xc4\xfb\x74\x63\x2a\xed\x31\xc5\x77\xcc\xa5\x3c\xfe\x2d\x79\xc2\x96\x4f\xb0\x39\x1c\xd3\xb5\x18\xcb\x62\xbc\x27\x5a\x31\xeb\x03\x5e\x9f\xa0\x7b\x48\x6b\x58\x7b\x03\xf3\x39\xf1\x8a\x71\x22\x02\x9d\x71\x7a\xc0\x0b\x4f\x4a\x8e\xfe\x8b\xf7\xef\xc6\x22\xd6\x0f\x62\x1f\xb5\x7d\x3b\xbe\xb6\x67\x93\x4e\x58\x45\x63\x3f\x40\x67\xb6\xfe\xc2\xb4\x8b\x48\x22\x46\x3d\x2c\xfb\x09\x37\x92\x63\x11\x58\xf4\x41\x06\x16\xd2\x3b\x76\x03\x9b\x8c\x89\x32\x2b\x31\xb4\x2b\x37\x24\x1b\xa5\x09\x4c\x0c\xd2\x0a\x27\x81\xce\xb0\x8f\xbd\x54\x8f\xcd\xa4\xc4\x27\x0d\xdb\x54\xd8\x68\x06\xa4\x1b\x8b\x0c\x01\x1a\xa2\x16\x28\x78\xe1\x3d\xd1\xb2\x03\xbc\x9e\x49\x2f\x06\x86\x2c\x6d\xc8\x52\x54\xdf\x03\xe5\x44\x0b\x43\xf6\xc6\x98\xa5\x8c\x99\xef\x97\x2e\x64\xf2\xb7\x04\xca\xa5\xa1\x23\x23\x61\xfc\xee\x40\xa6\xba\x7e\xad\xb4\x82\xf5\x17\xbe\x59\x05\x2b\x29\x99\xb5\xf4\x69\x17\x43\xa1\xec\x2f\xe8\xf3\xa3\x97\xe7\x2f\xdc\x6a\xe3\x49\xe3\x17\x38\x92\x36\x7e\xa3\xf8\xc5\x36\xe4\xad\xef\x52\xcd\xe6\xc5\x26\xeb\xc6\x3a\xa3\xf9\xcd\x38\x75\x99\xac\x87\xdc\x90\x0d\x5e\xe3\xbb\x16\x97\x44\x26\x95\x0d\xd9\xa4\x17\xec\x89\xf9\xa4\x65\x45\x6d\xd7\xdf\x02\x2d\xd9\x8c\x57\x16\xf2\xca\x2a\xd7\x7c\xba\x86\x82\x03\xd2\x66\x7c\x17\x6f\xb9\x02\xd9\xb2\x75\x3b\x16\xb4\x93\x31\x6b\x40\xf6\x2c\xf5\x9d\x46\x25\xe3\xde\x35\xa3\x86\xca\xe8\x39\x66\xb2\xb2\xb4\xac\x33\xd3\x2e\xec\xfa\xd5\xc6\x2b\xf9\x43\xe3\x7a\xb1\x60\xb3\xc0\x08\xce\x3c\x8b\x25\xaa\xc8\x17\x3d\x1f\xb6\xc9\xe8\x50\x66\x62\x70\x30\xdf\xa2\x59\x64\x56\xf5\xc9\xd0\x1a\x23\x03\xee\xa3\x0d\x19\x97\x74\x46\x7b\x9d\x49\x06\xb4\xd9\x36\xbb\x40\xda\xe6\x8c\x15\x65\xcc\x97\xb3\xdd\x5f\x10\xf1\xc2\x02\xcc\xcc\xc7\xd4\x98\x12\x78\xf0\x6a\x8c\x38\xfd\x72\xcb\xb5\x9c\x23\xcc\x03\x94\x72\x9f\x0c\x92\x11\xdd\xfa\x64\x5d\x40\xb7\xe6\x0f\x0e\xf8\x64\xee\x9f\x34\xd0\x4c\xb9\x77\x0e\x41\x3e\x81\x62\x5d\x71\xbb\x90\x63\x1b\x8e\x42\x0a\xa6\x95\xac\xa5\x64\xb3\x4a\x46\xc9\x84\xc8\x90\xe4\xe6\xfa\x5f\x49\x62\xc1\xb5\x88\x5b\x66\x24\x8c\xbd\x8e\x87\xec\x1d\x44\x5f\xe4\xb4\xf4\xb7\xb6\x80\x97\x7c\xe7\xd9\xd7\xd3\x04\x29\x35\x67\x30\x17\x47\xaa\x60\xbd\x0b\xdf\xd0\x96\x32\x7e\x2b\x2b\xae\xc6\x8a\x93\x27\x61\x8a\x6f\x7b\x66\xea\x52\x9a\xe7\x9c\x6b\x2c\x97\xbd\xa9\xa6\x6d\xf1\x1f\x64\xc7\x9e\x1d\x89\xae\x7e\x73\x0d\xde\x30\x44\x1a\x45\x27\x87\x10\x63\x80\x7a\xa6\x30\x6b\xa2\x0f\x66\x1b\x43\xf1\xe5\xae\xab\x66\x87\x72\xd8\x47\x4c\xcd\xad\xca\x9f\x8e\x5d\x8c\x97\xe4\xe4\x8d\xcf\x19\xd4\xf6\x54\xc4\x70\x0d\x34\xa0\x9e\x9f\x7a\xbd\x09\x12\x91\x7a\x45\x77\x2e\x9e\xd9\xf2\xa1\xd6\x70\x67\xe1\xb2\x54\xb2\xf0\xe5\xb0\xb2\x32\x12\x45\xf0\x62\x6b\x23\xc9\x88\x6b\xfe\x0e\x26\x87\x48\x05\x13\xe4\xd9\x93\x85\x27\x2b\xb6\x30\xa8\x34\x43\xa6\x34\xee\x28\xd6\x77\x76\x16\x12\xb7\x1e\x77\xc1\xe9\x90\x2e\x4c\x29\x40\x92\x66\x7d\xa8\xd8\x81\x2a\x68\x56\xd9\xf0\x4c\xbd\x98\xdf\x31\xb2\x86\x68\xd1\x1b\x90\x9c\x9e\x04\xd9\xfb\x1f\xf9\x0d\x3b\xdd\xd2\x9e\x4f\x79\x46\x31\x55\x43\x61\xd5\xbd\x30\x46\x84\x27\xaa\x58\xa6\x16\x29\x8d\xd9\x96\xbe\x80\x0b\xc7\xa2\xf5\xfa\x07\x7c\xe2\x72\x9a\x82\xbb\xa3\xdc\x4b\x34\x2b\xac\xf0\xba\xe7\x43\x5b\x53\x31\x2f\x77\x44\x35\xd1\x15\xe8\x3b\x87\x6d\xcb\x4e\x6d\xd9\xf4\x3d\x25\xe4\xc0\xb4\x13\x7d\x8d\x3b\x31\x27\x5a\xbb\x1e\x01\x4c\x65\x11\x8d\xad\xf6\x60\x47\x2a\x43\x9a\xc1\x04\x66\x4a\x1d\x3f\x95\x45\x32\x35\x21\x73\xeb\x64\xca\x63\x8a\xa9\x86\x08\xb4\x91\x81\x8c\x88\x20\x75\x01\x65\x4c\xbb\xb3\x16\x3b\x9f\x6e\x6a\x61\xca\x9c\x24\xc6\x10\xc0\x6b\x93\x0c\xe7\xf0\x4d\x75\xe7\xe2\x5e\x5b\xfa\x56\xad\x7c\xb6\xb5\x7f\xb2\xb1\x79\x0a\xe4\xe4\x1b\x7f\x21\xba\xba\x86\x06\xa3\xca\xb7\x2d\xfa\x02\x12\x7a\x5b\x88\xec\xe5\x78\x5b\xac\x59\xff\x3b\xd1\x3b\x24\xf9\x9e\x1e\x65\xe1\xc3\x14\x85\x86\x59\x1d\x51\xf5\x73\x6f\x51\x55\x1d\x87\x7b\x0b\x8f\xc6\x32\x74\xf8\x0a\x0b\x75\xc4\x27\x8f\x44\x1a\xe3\xbc\xf7\x76\xae\x30\x3b\x97\x93\x34\xfe\x89\xee\x4a\x0b\x0b\x54\xc6\x4a\x96\x3e\xdb\xab\x7f\xb2\xf6\x4f\xf6\xbe\xd2\xb3\x6f\xff\xc5\xf5\x34\x48\x1c\x5b\x90\x8c\x30\x0d\xd1\x9d\x2d\xb8\xf5\xba\xa7\x6c\xdf\x8b\x9f\xda\x5a\x9a\x95\xa5\xbb\xad\xc2\x9b\xd9\x82\xf6\x88\x64\xed\x9f\xec\x59\xf9\x2d\x27\x2e\x8e\xee\x94\x6d\x28\x44\x09\x93\xc8\x62\x28\x10\xfb\x00\xaa\xd8\xf0\x9a\x95\xc5\x81\x56\xb5\x12\x0f\xed\x20\xbf\xcf\x30\x1e\x85\x1f\xf9\xc6\x77\xbd\x61\xa9\xd1\xf1\x2d\x10\x43\x06\x6a\x79\x6e\x06\xf2\xc6\xe2\x5b\xc4\xf1\x0a\x3f\x5d\x4b\x3e\x5d\xc9\x96\xe8\x86\xa4\x22\x7a\x33\x64\x42\xbd\x96\x61\x5e\x83\x6c\xf1\xbf\x67\x23\x72\xe1\xa8\xed\xa0\xb6\x04\x25\x43\xcc\xcd\x9e\xf5\x1d\xa0\x6a\x41\x8e\xec\xc8\x91\x19\x3e\x69\x95\xef\xa5\xd4\x78\xfc\x2b\x07\x19\x6e\xea\x2f\x74\x3b\xf0\xa4\x65\xe3\x2e\x36\x6e\x41\xb3\x7d\x81\xa9\x2d\x18\xef\x2c\xe8\x0b\x17\x54\x73\x82\xb4\x09\x66\xd6\x80\xd0\xab\xe0\x55\xa5\x44\xef\x40\x43\x1b\x4f\xf3\x91\x0b\x31\xb5\x5a\xf5\x24\x7a\x6b\x56\x70\x26\x33\x36\x05\xc9\xa5\xf2\x25\xc9\x84\x6f\x16\xdc\x78\x16\x3e\xca\x5a\x50\x77\x16\xbf\x29\xc5\xc2\x94\x62\xcc\x46\x89\x82\xea\x73\xa5\xad\x3d\x79\xef\xfa\x1b\x92\x7f\xfd\x93\x0b\x1b\x5a\x20\x64\x09\x34\x71\x95\xd8\x96\xfd\x41\xc3\xe6\xd2\xb6\xd2\xdc\x9e\x01\x89\xda\x41\x64\xbb\xf3\xa4\x60\x1e\x75\xda\x4a\x1f\x50\x7f\x30\x07\x28\x56\x12\x03\x53\xa5\x77\x64\x1f\x7e\x3b\x68\x2b\xa1\x84\x80\x34\xda\x04\x32\x81\x79\x45\x72\xcc\x70\x85\x40\x94\x3c\xfc\x2b\x65\x2f\x12\x8b\xcb\x59\x42\x4e\x3b\x5b\xc2\xb5\x04\xd2\xbd\x76\xc9\x75\x58\xfa\x4b\x17\x0f\x5c\xfa\x25\x83\x12\xa5\xf9\x23\xda\xd7\x96\x9a\xff\x81\x2b\x1b\xc9\x13\x96\xfd\x62\x1b\x8b\x9c\xd9\x2a\x16\xf5\xe8\xdf\x9e\xb3\xe9\x2d\xbd\xa6\xd2\x1c\x98\x41\x97\x24\xe0\x4b\x4e\xd4\xca\x27\xaf\xf8\xf6\x8a\x31\xeb\x92\x0a\xa2\xa4\xeb\x52\xd2\x65\xc7\xd6\x45\x9b\x19\xf7\xba\xa5\xc4\xcd\x75\x3c\xce\xcc\x7a\x46\x2c\x0f\x07\xfc\x3a\x21\x57\xff\xd2\x55\xdc\xd1\x89\x90\xb0\x8a\xa7\x3d\x1f\x60\x2e\x65\x69\x0e\xfd\xd9\x4d\xc9\x35\x5a\x72\x3d\x96\x8c\x28\x22\xc2\xf1\xdc\x43\xcc\x4d\x46\x07\x03\x92\xe4\x8c\x1c\x97\x8c\x33\x97\x7e\x0d\x96\x74\x5e\x80\xe2\xb6\xb9\xf4\x5e\x4b\x69\x5e\x0b\x66\xd3\x36\x0b\x7c\x52\xfb\x6c\x33\xeb\xa7\xf8\x2f\x44\x0b\xa2\x0b\xd1\xd5\x90\x39\x1a\x15\x37\xba\x15\x0f\xd2\x2a\xbb\x07\xf4\x82\x65\x5f\xf9\x2d\x93\x84\xe2\xa5\xc1\x15\x3b\x55\xc1\xb2\xf7\x34\x36\x6f\xc5\x8d\x30\xd0\x15\x17\x70\xc5\x1d\xcc\x23\x2d\xac\xb8\xe9\xe2\xc5\x54\xec\xd6\x23\x6f\x3d\x54\x22\x6d\x29\x0b\x6a\x10\x58\x02\x5a\x12\x5d\x81\xa2\x35\xab\xec\x2a\x83\x56\x11\x8f\x47\x2b\x9a\x0c\x41\xa6\xa8\x2b\x0a\x6f\x45\x3d\x00\xd4\xa2\x41\x6a\xe4\x1e\x29\x22\x38\xfd\xfd\x02\xb1\x12\x62\xea\xbf\xa2\x5a\xac\xc4\xb4\x5d\x0c\x59\x9a\x1e\xac\x01\x9d\x80\xf6\xac\xfd\xcd\xb7\x55\xaf\x2f\x08\x32\xdf\xb9\xa2\x09\xac\x44\x7b\xc4\x3e\x1f\x39\xba\x27\x66\xf8\xc9\x97\xce\xcc\x77\xe6\xd3\x0b\xd3\xd4\xcc\x55\xf4\x4e\x2b\x2c\x15\x24\x3f\xc2\xaf\x87\x0c\x56\x74\x5a\x2b\x2e\xa2\xca\x0d\x65\x10\xe9\x81\x27\xa9\x27\x23\x1b\xc9\x40\x26\xd4\x13\xd5\x6f\x3b\x6e\x3d\xa1\x74\xcd\x0e\x7c\xea\x4b\x8a\xe8\x81\xcd\xf9\x93\x57\xe7\x40\x66\x9e\xcc\x7d\x51\x8d\x7f\xc7\x8b\x8e\xee\x04\x33\xdf\xce\x8b\x3d\x89\x42\x25\x27\x4c\x28\xe3\x91\xea\xe2\xd1\x42\x5e\xb1\x17\xff\xf1\x2e\x21\x9e\xc7\x16\xfe\xc7\xef\x0f\xc1\xaf\x86\xc2\x7c\xbf\xd9\x3b\x1a\x68\xd6\xd7\xfe\xb2\x3b\x12\x03\xf2\x9c\xc6\x0d\xfc\xc5\x0f\xd6\x5f\x4e\x6c\x83\x0b\x91\x98\x58\x85\x3a\x66\x9c\xc1\x18\xd8\xa8\xa8\xa7\x2a\xaf\x97\x1e\x2d\x68\xf6\x27\x9f\xcc\x10\x68\x20\x5f\xb0\x11\x05\x07\xab\xa6\x6e\x01\xaa\x88\x82\xd1\x7c\xc2\x9d\xb2\x9e\x9e\xdb\x98\x06\x01\x19\x13\xa9\x15\x79\xf2\x07\xe3\x3c\xe8\x51\x3f\xaa\xb6\xfb\x24\x39\xc9\x23\xba\x5a\xeb\x26\xc5\x5e\x8b\x67\x71\x35\x22\xa2\x40\x7a\x27\xa6\xf6\x3e\x7d\xcd\x55\x50\x8b\xb2\xd2\xb4\x02\xfd\x78\xe2\x21\x49\x2d\xa4\x62\x86\x1a\xe1\x87\xda\x5f\xf4\xa8\xbd\x2e\x7a\xb2\x53\x95\x48\x56\xc8\xa3\x1a\xa8\x66\x64\xaa\xe6\xb5\x0b\x04\xe9\xb4\xbe\x3d\xcc\x50\x2d\xb2\x71\xc3\xca\x9f\xbc\x5e\x78\x92\x6d\xe8\x77\x28\xaa\x5a\x86\x4e\xbb\x7d\x64\xda\x07\xb4\x69\xcd\xf9\x7f\xe2\xba\xab\xc5\x8b\xd6\xfa\x2e\xd6\x39\x0b\x05\xd7\x3c\x81\xac\x65\xfd\xa2\xd5\xb8\xbf\x24\xce\x4c\x1d\x2c\xa4\x6c\x67\x6a\x59\x2e\x72\x99\xc5\x5e\xc8\x5c\x9f\xcd\x5c\xd6\xfe\x16\x62\xad\xae\xa4\xbc\x30\xf3\xfe\xfb\xcc\x3c\xc3\x96\x44\x9d\xc1\x28\x90\x33\x7f\x1c\x37\xe3\xc1\xca\xcc\xbc\xb8\x31\x5f\xc8\xb8\x6f\x9f\x21\x16\x4e\x94\x12\xe1\x84\x34\x65\xb6\x29\x51\xc1\x72\x6b\x56\xac\xda\x05\x68\x0a\xf4\x42\xfb\x37\x33\x0d\xa3\xc6\xff\xab\xf0\xf8\x24\x96\xfd\x42\x17\x70\xa6\x07\x72\xb2\xcc\x21\xb0\x33\x31\x66\x7f\xf3\xcd\x96\x61\x37\x90\x6f\xbe\x98\x1f\xfe\xc9\x3b\xd1\xc9\x25\x9b\x5a\x07\x19\xb1\x5e\xbd\x6f\x37\x13\xd1\xd3\x57\xf7\x50\x4e\x33\x89\xf2\x66\x40\x9f\xd8\xc4\xcd\x28\x28\x33\xda\x95\x19\x97\xc0\xcc\xdf\x96\x9b\x49\x35\xc7\x1e\x66\x1c\xb1\x0e\x24\x17\x56\x82\x06\x81\x22\x19\x13\x65\x50\xb2\x20\xf1\x3d\x15\x04\x94\x78\xcf\xe4\xd2\x17\x12\x34\x2c\x49\xed\x9f\xcc\x3c\xf9\x9b\xa8\xf1\x35\x44\x73\x31\xf3\xb1\xa1\x99\x8f\x0d\x81\x68\xb4\x0d\x64\x6b\x63\x1d\xc8\x0f\xbc\x83\x56\x9e\x88\xfe\x75\x6f\xab\x1c\x22\x4a\xe4\x8e\x2b\x90\x94\xb8\xd2\x6c\x9b\x09\x92\xfa\x32\x54\xfe\xbf\xc2\xed\x23\x1a\x51\xf8\x66\x7e\x2f\x06\x12\x9a\x3c\xe7\x6c\xcc\x4d\xff\xde\x61\x06\xc1\xb7\x3d\xbd\xbc\xaa\xc7\xa0\xf1\x8c\x62\xce\xc3\x11\xa0\x7b\x22\x35\x7c\x20\xcf\x9e\xac\x3d\x79\x37\x24\xdd\x26\x19\x01\xc5\x2b\x46\x73\xc6\xba\xe6\xbc\xc9\x31\xe7\x8d\xa1\x39\x57\xe6\xdc\x42\x23\x9a\xf5\x81\x59\x2b\x98\xa0\x39\xa7\x7d\x4e\x23\x31\x97\xbf\xdb\x1e\x63\x2a\xec\x7c\xcb\x52\x5b\xdf\x80\x17\x6a\x14\x3c\xf9\xe2\x07\xe4\x05\x71\x5c\x92\xc2\x3f\x99\xf9\x32\x56\x40\x2b\xde\xfa\x03\xf9\x2f\x26\x6f\x2e\xab\x71\xc8\xb6\xac\x71\x70\x32\x17\xe7\xef\x13\xe8\x93\xd3\xf6\xc9\xa9\xbc\xb0\xf2\x8b\xbd\x1b\x3c\xba\xdc\x50\x58\x86\x43\x90\x3e\x33\x24\xf8\x0f\x22\x97\x56\xfb\x5f\x7b\x76\xa1\x46\xef\x81\xce\x79\xdc\x31\xf7\xf1\x85\xb9\x3f\x65\x07\x79\xf0\xa4\xb2\xf6\xc8\x2a\x63\x43\x7e\x59\x5b\x7f\x23\xaa\x40\x74\xb2\x61\x72\x31\xd4\x86\x1b\x18\x1c\x46\x0d\x98\x3c\xa0\xb2\x6e\x7c\x48\x01\x44\x4d\xc1\x33\xae\x9d\xa0\xfa\x86\x37\x4f\x80\x6e\x91\xe7\x97\x53\xea\x86\x91\x06\x20\xed\xd3\x73\xe7\x2e\x8c\x63\x35\x3f\xdb\x4d\x94\x58\xa0\x9e\x4d\x83\xcc\x7d\x0b\x1a\xdf\x85\x38\x00\x3c\x5f\x8b\x75\xbc\x32\x50\x88\x87\x6b\xff\xe6\xd6\x57\xb0\xf3\x65\xe8\x86\x01\x65\x1c\x7e\xab\xe0\xe8\xc9\x4f\xdf\xd1\x33\xd1\x45\x03\x81\xb2\x5c\x90\x74\x95\x79\xb8\x35\x2e\xca\x0a\xa8\xef\xca\x48\xfc\x98\x9a\x32\x02\xb9\x21\x1a\x31\x0c\x01\x3e\x26\xca\x59\x54\x0a\x01\x8d\x91\xcc\x46\xa6\xb1\x36\x14\xd3\x2c\xfa\xd5\x50\x1a\x81\xb6\x40\x19\x64\xaa\xb1\x73\x51\x2d\xbf\x60\x03\x0a\xdf\xe8\x92\x25\x54\x3c\x68\x7a\xd6\x6d\x81\x98\xb0\xc6\x7b\x88\x8d\x39\x84\x39\xf9\x1c\x9f\xda\xf4\xf4\x43\x18\xfb\xae\xa5\xa1\x49\x69\xa4\xc0\x8a\xf5\xe8\x86\xb6\xc1\x15\x7d\x8c\xf8\xb3\x79\x0f\x03\x92\xe8\x3d\x80\x17\x44\x15\x4f\xfd\x9e\xed\xf2\xaf\x16\xbd\x64\xab\x56\x7e\x18\xd7\x52\x4f\x03\xb2\xe1\x88\x7c\xe7\x20\xe0\x16\x82\xb6\x6a\x4f\x29\x3b\x31\xeb\x07\xcb\xfa\x64\xf7\x2e\xd0\xfc\x0d\x55\xce\xb3\x28\x1a\xe4\x13\x57\xc3\xca\x0f\xa4\xee\xf9\x0f\x5e\x1a\xee\x51\x1a\x5c\x9c\xb7\x2e\x24\x6c\xb5\x1d\xd0\x35\x7a\xef\x57\x76\xb5\x30\x46\x96\x1a\xc5\x3c\xa1\x7c\x24\x63\xa8\xd8\xc6\x89\x49\x02\x0b\xa6\xc9\xd1\x2b\x6d\x64\x1e\xff\x60\xce\x67\xf3\x51\xb4\x61\x05\x5b\x55\x70\x5f\xdb\xd0\x47\x69\x18\x62\x6d\x54\x19\xba\x0c\xf7\x44\xa5\x4f\xa6\x0a\x79\x67\x75\x33\x5f\xc9\xdc\x44\xc6\x9d\x17\x3f\x33\xdc\xd3\x78\x67\xa4\xf1\xce\x08\xf2\xac\x99\xbc\x31\x41\x86\x5b\xe2\x3a\x44\xb5\x91\xc8\x67\x03\x2e\xdb\xa7\x7f\x72\x71\xef\x98\xdb\xf8\x6c\x8e\x44\x4b\x92\x11\x85\x66\x2f\xa8\xac\x17\xdc\xf3\x2d\x28\x07\x0b\x3b\xbf\xd6\x0c\x43\x66\x18\x33\x6d\x0c\xad\xb1\xf0\xa7\x57\x0b\xee\xd5\x17\x76\xce\xfd\x64\xc4\x92\x75\x71\x2f\x7c\xf9\x15\xab\xad\xbc\xb0\x2c\x38\xe4\x0b\x6a\xe9\x05\x07\x7b\xc1\x88\xeb\x42\xbf\xb1\x49\x34\x39\x1e\xfa\x2e\xb8\x81\x5b\x30\x70\xb4\xe0\x72\x12\x24\xbe\xcc\x82\xa3\xbd\xf0\x4a\x79\x81\xa0\x0d\xdd\x82\x05\xf7\x62\x0b\x19\xf7\x06\x48\x6f\xee\x00\xbd\x62\xa8\x17\xb6\xae\x5e\x7b\xfc\x22\xd0\x8e\x5b\x3e\x7a\x8c\x78\x5b\x57\x92\xd4\xab\xde\x85\xc9\x5e\x45\x82\x08\x35\x87\xd1\xbe\x55\x03\xba\xf6\x34\xca\x66\x77\x13\x17\xbf\x0e\x63\x58\x69\xda\x8e\xdc\xe6\xdf\x89\xed\x42\x9d\x58\xa9\xbb\xe5\x66\xbf\x35\x83\xb8\x00\x49\x99\x9c\xfa\x9b\x00\xad\x1e\x06\x4a\xcb\x5a\xdc\xd5\xef\xf9\xef\x06\x05\xd9\xc2\x6d\x79\x2d\xa4\xe5\x65\xe5\x16\x27\xdf\x86\x2c\xed\x9e\xaf\x47\x4b\xd3\x06\xf7\xcb\xda\xa9\xe1\x43\x41\x62\xf3\x5a\x09\x60\xf7\x99\x75\xcd\xb8\x7f\xcb\x73\xf7\x56\x56\xd9\x7f\x59\xdf\x8e\x19\x4e\xd0\x62\xf8\xa6\x31\x7e\xda\xd0\x52\x6b\xb6\x32\xc1\x59\xcf\x36\x68\x8d\x65\xb0\xef\x8c\x80\x90\xd5\x8e\x91\x5a\x19\xfd\x4f\xa2\xab\x35\x5f\x4f\x8a\x76\x24\xa1\x84\x25\xa3\x32\x40\x4b\xa2\x2b\x50\xfc\xb2\x6f\xc9\x89\x5a\x72\xe1\x2e\xd5\x43\x92\x9a\x97\x76\x51\x37\x27\xd1\x2b\x29\x4b\x1e\x9d\x2c\xfd\xc1\xcc\xd2\x7b\x40\x4b\x4a\xef\xd2\x3c\x9a\x98\x1c\x97\xc8\xd2\xbb\x2a\x20\x9f\x7c\xa2\xb1\xe8\x25\xef\xa3\x83\x64\x54\x86\x4b\x91\x86\xa0\x61\xbf\xe9\x29\x61\x5f\xcb\xf9\xe5\xa0\x06\xfc\x0e\xa8\xe6\x48\xcd\xf9\x74\xc1\x4d\xc7\xd2\x7b\x6d\x4b\x7f\xcc\xb2\x34\xe9\xc9\x50\x5d\xd8\x88\x33\xf9\xd3\xbd\x20\x6a\xe4\x9b\x68\x89\x31\x3c\x9d\x25\x55\x06\xd0\x2d\xeb\xda\xc9\x58\xdc\xf4\xec\x33\x57\x4d\x3e\xe1\xf2\x11\xc8\x11\xa1\xa1\x25\x8e\x47\x58\xce\x99\x63\x76\x61\x2d\x17\x19\x9c\x27\xce\xcd\x15\x01\x7a\x23\xc1\xfe\x62\x14\xcc\xe4\x2e\x45\xcb\xbf\x03\xe5\x88\x6f\x00\x35\x28\xe4\x9b\x37\x94\x4b\x7f\x00\xb2\xf4\x9b\x84\x25\x2d\xe4\x92\xbe\xe4\xd2\xdb\x4a\x90\x7b\x1b\x4a\xb7\x8b\x07\xa9\x88\xf4\xe8\xe0\x1b\x6d\xe1\xd2\x6c\x61\x2c\x9e\xd3\xef\x2e\x6d\x80\xfc\xcf\x46\xd3\xec\x1c\x4f\x20\x96\x66\xe0\xd8\x13\x0d\x04\x69\x17\xbe\xd9\x66\x5a\x95\xe8\x37\x1a\xbb\x57\x1a\x3b\x1c\x86\x4d\x90\x16\x6f\x61\xac\x7e\xbb\x85\x81\x87\xb7\x7c\x52\x19\x92\x83\xe7\x9e\x9e\x9e\x59\x89\xfa\x9d\xf1\x8a\xb7\x84\x57\x74\x87\x57\x74\x87\x57\x6c\xe7\x8a\xdf\x1a\xac\xec\x1a\xf1\x88\x44\xc5\x63\x85\xeb\x8e\x44\xf1\x4c\x18\x7c\xc9\x76\xe7\x38\xe9\x05\xd2\x23\xb9\x15\x55\xc0\x8a\xfa\x74\x05\x67\x1a\xa8\x64\x8b\x11\x91\x8e\xc3\x30\x67\x2d\x0d\xd3\x16\xbe\xf2\x5f\xae\xa9\x83\xe7\xcc\xd9\x32\x5c\x08\xb2\xf1\x39\x5f\x7d\x5b\x56\xb2\x74\x86\xe4\x6b\xb6\x77\xfd\x6b\xb2\x8d\xcd\x8e\x17\x9b\xe3\x55\xab\x57\x59\x68\xba\x37\x5f\xd1\x36\xaf\xa8\xb0\xa3\x31\x58\xe9\xc5\x59\x11\xc8\x15\xd5\xf4\xab\x0f\x59\xaf\x64\x55\xb1\x72\x15\xad\x16\xd9\x0a\x86\x6b\xd7\xfe\x02\xe0\xda\x7f\x0c\xb1\xf6\x47\xde\x20\x35\x91\xba\x10\x6b\xbf\xe5\x5c\x53\x50\xd6\x54\x60\x6b\xdc\xf9\x04\xd2\x30\xcf\x9a\x97\x71\x40\x4a\x2c\xf4\xb5\xac\x72\x68\x4e\x2d\xfb\x85\x6b\x6b\x0d\x55\x26\xeb\xf1\x0a\x8e\xea\x2a\x90\x0d\x8f\xfb\x84\x98\x29\x02\xd1\xae\xe9\x95\x98\x35\x75\xd8\x5a\x8f\x99\x45\x48\xd7\xd4\x5c\x40\x5a\xcb\xd5\xb2\x86\xb1\xbf\xb1\x12\x6c\x22\xd6\xf2\xe9\xcb\x1f\x40\x37\xd6\xd4\x80\xde\x89\x4e\x40\x13\xbe\x81\x2b\x3e\xef\x24\x7a\x7d\x7e\x23\xeb\x3a\x05\x1a\xf0\xe7\x15\x36\x3c\xa7\xdc\x70\x99\x6e\xb8\xfc\x36\x92\x6f\x09\xa4\x1b\xd0\x8d\x7d\xa6\x79\x25\xd1\x2b\x4c\x1b\xce\xc1\x86\x47\xc6\xdc\x01\x20\x55\x9d\xd7\x8d\xc5\x53\x77\x20\x0b\xef\x23\x09\x77\xa2\xb6\xe1\x4d\x00\xa0\x8c\x68\xca\x56\xc6\xd0\xd4\xc6\x7f\x00\xb2\x71\x1f\x80\xe4\xe4\xb5\xcf\x39\xf3\x05\x2e\x59\xe0\x9a\x79\xce\x2c\x4a\x43\x47\x1b\x6e\xf2\x36\x32\x3f\x18\x5d\xf3\x50\x2d\x77\xf2\xcb\xc7\x46\x1b\x9d\x17\xcb\x5c\x58\x45\xb6\xeb\xda\xd0\xa6\x6c\x7c\x30\x78\x63\x51\xa7\xf8\xe4\xc9\x5a\x96\xc4\x7b\x7f\x1b\xef\xa1\x6e\x68\x4c\x36\x7e\x63\xb5\xd1\x1d\x94\x0e\x84\xd8\x0f\xa2\x8b\x6b\x99\x08\xdc\xc6\xef\x90\x36\x3e\x22\xfb\x1d\x47\xe9\xd0\xed\xdf\xa9\x9f\xd5\xd2\xf3\x56\xc4\x77\x46\xa2\xbe\x8b\xd6\x53\xaf\xef\x3b\x0f\x98\xbe\x63\x45\x60\x8e\xbf\xe3\x47\x28\x80\x6e\xac\x44\x8d\xab\x69\xbc\x60\xcb\xe3\xb8\x2d\x97\xd5\x96\x71\x97\x2d\x2f\xff\x6e\xa5\xe6\x59\xcf\xae\x55\xeb\xb0\x6c\x79\x53\x05\xf7\xb6\xbe\x1a\x92\xd6\x6c\xe9\x35\x6d\xed\xc0\xac\x06\x99\x33\x4c\xb0\x65\xf0\x77\xcb\x0b\xb5\x5b\x93\xb0\x98\xac\xdf\x31\x6d\x19\xc4\x80\x77\x86\xa4\x13\x37\xc3\x5b\x2a\x8a\x2d\x5d\xaa\xad\x88\xdb\x48\xbc\xa3\x33\xc6\x63\xcb\xaf\x55\xb7\xfa\x91\xb8\x28\xa5\xad\xe8\x8e\x6b\x4f\x7f\x4b\x40\xdb\x12\x10\xbb\x9b\xe8\xcf\xa0\x6c\xa9\x3b\xb6\xf2\xfa\x03\x10\x9c\x9b\x11\xc9\xc8\x0a\x4e\xe2\x85\xef\xad\x85\xc8\x23\xb9\x25\x8a\xe5\xc4\xf7\xfc\x6c\xc9\xc5\x14\xa2\x7f\x88\xf4\x76\xe9\xd6\x6f\xc8\xb7\xce\x1f\x49\xc9\x55\xcb\xef\xb8\x39\xde\x49\x33\xff\x0b\xdb\xb6\xe3\x4d\xa6\x9d\x7d\x9e\x72\x05\x29\x64\xc4\x47\x24\xb5\x21\x99\xc6\x1d\xcf\x8e\x77\x8c\xe1\x0a\x12\x41\xd8\x59\x10\x28\x05\x59\xf0\xa2\xce\x8e\xa7\x5d\x3b\x5a\xd5\x1d\x6e\x38\x00\x7d\xb0\xd4\x4f\xa2\xf8\x3b\x2b\x3b\x5e\xa5\xdb\xd9\xaf\x01\x7c\x27\xd9\xc2\x28\xed\xfc\x3d\xf5\x9d\x7d\xca\x90\x81\x68\x88\x68\x47\x4d\xf1\x46\x57\x6d\xcf\x43\x8f\x37\xbd\x05\x23\x59\xdf\xb8\xeb\x79\xe3\xfd\x97\xbd\x8f\x0b\x83\xdc\x13\x55\x3e\xb9\x66\xd9\xd1\x22\xef\xbd\x45\x06\x59\xb0\xf8\x37\xf7\x82\xc5\x53\xf6\x74\x12\xf6\x74\xef\xf6\xb4\x2f\xf1\xd2\xc8\x9e\xd7\xc4\xf6\x74\xe2\x40\x62\x53\xf5\xc0\x69\x8f\xcb\x51\x86\xec\x69\x85\x8e\xbc\xd1\xa9\x90\x34\x2b\x52\x67\xfc\x87\x9e\xaa\xd8\x4b\x73\xa2\x86\x28\x06\x29\xf6\xfe\x42\xda\xde\x9f\x84\xee\xb9\x39\xda\x9b\x9b\x37\x22\xc9\xf9\xf6\x8b\x6f\x7e\xb4\x51\x7b\x6f\xa3\xf6\x5e\x83\xec\x4d\x69\xc4\x02\xa2\x47\xb9\x57\x1b\xe5\x72\xfe\xc3\x15\xb3\xf7\x3f\x4f\xb2\xe7\x1d\x7a\xa0\x77\x20\x31\xec\x22\xe5\x7b\x9c\x48\x63\xe9\xee\xa5\xc3\x13\xeb\x4f\x50\x22\x63\x2b\xc7\xf6\x10\x7b\x91\xde\x01\x11\xde\x33\xc5\xb2\xc7\x69\x4a\xd7\xff\xd3\x1a\x67\x3f\xd8\xb1\xa7\xad\x03\x1a\x7a\xc2\x91\x55\x57\x21\x27\x89\xa7\x72\x6f\xd0\x3a\x36\xe1\x89\xba\x6f\x7b\x6f\x5d\xf7\x7e\x2f\x05\xa2\x8a\xfa\x07\x6d\x21\x50\xcb\x0c\x4b\xdf\x90\x15\x3b\x14\x43\x89\x20\x3f\x88\x4e\xbe\xb1\xff\xe7\xc9\x27\x0f\x0e\xf7\xde\x6a\xee\x3b\x77\x63\x0d\x44\x35\xe9\x81\xf6\xeb\xc0\xd3\x9e\x03\x17\xca\x81\x63\x71\xe0\xf2\x38\x70\x79\x1c\xa8\x9c\x0f\xdc\xf7\x1c\x78\x4a\x77\x30\xe7\x37\x23\xd1\x82\x4a\x66\x2d\x65\xad\x9c\x58\xb0\xca\xe1\xbb\xfb\x6c\x31\xd6\xa0\x6b\xe9\x20\xeb\x66\x6c\x48\x64\xe8\x20\x8b\xe6\x0f\xd6\xf5\xcc\x12\x1b\x36\xb5\x85\x9b\x70\x30\xe9\xaf\x48\x2a\x66\x40\xad\x07\x56\xf9\x02\xc9\x3d\xf8\x2d\xd2\x3f\xf6\x03\x3d\x23\x92\x05\xab\x6b\xe9\x9b\x1c\x38\xaf\x07\x99\xd4\x7b\x88\xcd\xc1\xbc\xee\x96\xef\xac\x59\xdd\x96\x8d\xdd\x33\xed\x9d\xc3\x16\x83\x37\x07\xee\x99\x0e\xf6\x6b\x2d\x23\x12\x7d\xef\x6a\xb3\x60\x32\x00\xf4\x68\xdd\x0d\x2b\x67\x4a\x84\x5e\x5a\xdb\xdf\x2d\x8e\x89\xe1\xd4\x1f\x13\x59\x93\xa0\x41\x76\xbd\xe1\xe0\xad\xe5\x81\xdf\x73\x09\x72\x1b\x99\x03\x8d\xe8\x41\x96\x68\x44\x29\x51\x66\x28\x89\x95\x17\x4e\x06\xf5\x44\xb4\x25\x29\xac\xbf\xee\x46\xc2\xc1\xbb\xa3\xff\x70\xd5\x21\xf9\x87\x49\x98\x8b\xc7\x1f\x19\x4a\x3f\xea\xa1\xa7\xbc\x70\xf4\xdf\x74\x1c\xfd\xed\xa7\xff\xd9\xd7\x87\x19\x0b\x48\xb9\x81\x03\x39\x02\xe9\x3a\x3a\x52\xc1\x1c\x69\x70\x8e\xf4\x66\x8e\xb2\x7a\x1e\xd0\xaf\xa3\xfe\x52\x97\x05\xa2\x8e\x54\xd5\x47\xae\x9c\xa3\x2c\x9b\x2f\x40\x8f\x18\xde\x23\xae\x17\x01\xcd\x98\x6f\x06\x37\xe9\x48\x5f\xef\xa4\x47\x54\x42\x8e\x34\x36\x47\x1f\x7f\x3b\xf2\x84\xfe\xc8\x5f\xb0\x3a\x9a\xcd\x69\x49\x32\xa2\x82\x65\xbf\xf2\xbd\x15\xbb\xbe\x62\x15\x3b\x3e\xdd\xb3\x85\x07\x5f\xed\x4f\x66\xbd\x10\x5d\x0d\x99\x01\x38\xf2\x7c\xf4\x48\x91\x3d\x8a\x38\x16\x86\xb4\xea\x84\x63\x0d\x1f\x53\x9a\x7c\xd2\x53\x2e\x6d\xb2\x79\x92\xc7\xce\x9d\xaa\x9f\xec\xe0\x28\xe3\x13\x15\x28\x3c\x51\xe3\x86\x53\x06\x15\x9e\x9f\x3e\xca\xfb\xd3\x76\xb6\x03\x92\x8c\xe8\xce\xe7\x29\x7c\x51\x25\x91\xda\x93\x9f\xfe\xdc\x1b\x64\x4e\xa4\xc7\x9f\x3f\x3b\xf7\xab\x0b\x3f\xfd\x39\xf6\xcf\xce\x7e\x34\xe1\xa7\xf8\xa5\x13\x20\xdd\x68\x7c\xe8\x06\x5c\xe4\xec\x43\x37\xc5\xba\xf2\x91\xd3\xf6\x3f\x3f\xbd\x27\xfe\xf1\x9b\x59\xfc\xb0\x10\x63\xc5\x9c\xa5\xf5\xdb\xed\x05\x3f\x3a\xfb\x22\xeb\xcc\x21\x3b\xd3\x17\x84\xe1\xd2\xcd\xc9\xd9\x3e\xa0\xca\x49\x74\xf4\xcf\xfe\xa3\xa5\xb3\x7e\xa7\x64\x45\xc5\xef\x94\xce\x5c\x79\x67\xce\xc8\x99\x1d\x38\xfb\xd6\x7f\x72\x19\x9e\xb9\xe6\xce\xd4\x32\x67\x7a\x4d\x67\xce\xd4\x99\xee\xfb\x99\x87\xce\x67\x4a\xce\x99\x7a\xe8\xdc\xb9\xaf\x26\xcf\x5c\x94\x67\x5c\xff\x21\xd2\x3e\xea\x75\xec\x33\x4d\xd6\xbf\xf8\x59\x39\xdf\xa8\x5f\x3e\x37\x00\x2f\x89\x1a\xb6\x73\xc5\xfd\xce\x99\xf1\x9b\x33\x9d\x9f\x33\x9d\x76\xa0\x29\x11\x7b\xe0\xae\x43\x21\x6c\xb4\x81\x46\x8c\xdf\xfb\x00\xa9\x27\x7b\xe1\x71\xcd\x85\xb1\xc2\x0b\xbe\x56\x02\xd2\xe3\x8b\x8b\x18\xd8\x7e\x4f\xbf\x15\xb2\xf2\xbf\xf2\x0d\xb5\x89\x17\x44\x00\x81\xd6\xf0\xb4\x2f\xb2\x4b\x9f\x02\x6d\xf9\xae\x4a\xc2\x85\x91\xc1\x8b\x98\x8e\x3b\xa0\x21\x9f\x66\xfc\xac\xe0\xc2\x1f\x7e\x8c\x86\x33\xfe\xe0\xd9\x05\xba\x81\x28\xb3\x96\xbb\x4b\x36\x17\x8b\x7e\x87\x17\xae\xbc\x87\x71\xa5\xe1\xb8\x52\xfa\xae\xd4\x33\x57\x04\xa0\x0c\xc9\x54\x5d\x29\x5c\x57\x5a\xb2\xab\xfd\xe2\xc3\x00\xa4\xf6\x28\x96\x3a\x23\x7a\x61\x3b\x5a\x3a\x66\x57\x7f\x22\x77\xa5\x23\x72\xf5\x91\xd5\xab\x74\x61\x45\x84\x06\x96\xcc\x29\x5b\x75\xcb\xa9\x7a\xfb\xea\x77\xba\x57\xc6\xa3\xae\xdc\xdf\xc7\xa3\x8e\x2b\x2f\xdb\x5f\x7d\x70\xff\xca\xaf\x94\xae\x8c\x37\x5d\xdd\xe0\x4a\xfc\x40\x92\x03\xc2\x85\x23\xa0\x50\x93\x6e\x07\x06\x3d\xb7\x31\x50\x34\x24\xaa\x7a\xf6\x9d\x19\xbe\x94\x8c\x77\xf0\x03\xba\x63\x41\xa5\xed\x8d\x71\x2f\x3f\xfe\x7a\xaa\xf2\x37\xa0\x47\xfb\xcd\x46\xbd\xbe\xaf\x0d\xaa\x59\x79\x2d\x66\x47\xd1\xc9\x50\x10\xdf\x80\x66\xac\x62\xc6\x52\xb8\x8d\x0a\x84\x3f\x6e\x14\xc8\xce\x92\xc3\x30\x5e\x81\x86\x4c\xbb\xb1\x2f\xb6\x71\xdb\x4c\x55\x4b\x20\xd0\x60\x7a\x72\x9d\x78\x92\x7a\x32\xf4\x04\x4e\x95\xdd\x22\xb1\x19\x52\x0e\x39\x50\x52\x11\x41\x0b\x2b\x41\xf0\x04\x44\x5d\x3b\x25\x39\x8b\xba\x75\xbf\x60\x17\xf8\x83\xc8\x8e\xdc\x7d\x96\xd5\x10\xd0\x93\xbb\x78\x1d\xf8\x33\xcb\xbd\x58\x9a\xba\xa8\x7a\x87\x13\x97\x56\x95\xc0\x46\x2b\x81\xf7\xa1\x3f\x2c\xa9\xdf\xe3\xa0\xee\x84\x1f\xc5\xda\xa2\x0b\x49\x43\x3e\x44\x2c\x4b\x11\xce\xbc\x40\x62\xf4\x57\x7f\x12\x2a\xe3\xdb\xaf\xf6\xb6\xee\x3d\x13\xfc\xb0\x6b\x4e\x84\x13\xb0\x64\x60\x97\x1c\x92\x01\x45\x31\x8e\xf1\xc0\xb6\x41\x4a\x6a\x8f\xe8\x63\x46\x47\x3a\x19\x50\xaa\xe2\x8c\xf0\xfc\x37\x19\xd8\x6f\x05\x24\x03\xbb\x85\xa3\xe8\x87\x28\xbb\x64\x60\x3f\xdb\x9b\x0c\x4c\x19\x24\xb8\x64\x56\xb8\x66\xe8\x31\x78\x82\x0b\x64\x37\x5c\x77\xa9\xed\x0b\x14\xbd\x3b\x67\x20\x67\xea\x87\x21\xdd\x7c\x24\xa9\x59\xd4\x24\x75\xb7\xab\x12\xba\xd4\x09\x4d\x7c\x82\xef\x9d\xc7\x40\x0c\xe2\x05\xf2\x0d\x8d\x4d\xdd\x01\x55\x82\x26\x20\x83\x6a\x9c\x84\xbf\x49\xa8\x73\x37\x20\x8a\x69\x3c\x0c\x53\xfe\x48\x54\x13\xf1\x06\x4d\xbc\xb9\x19\x7f\x78\x34\x19\x9a\xe3\x90\xd8\x4f\x03\x5a\x45\xb9\xed\x2c\x02\x99\x32\xf9\xde\x37\xab\xe4\xab\x95\x6f\xc9\xdc\xa3\x1c\xe8\x85\xed\x5e\xb2\xac\x57\x9c\x9f\x31\x0f\xfc\xbd\x64\x68\x76\x3b\xa0\xd4\xca\x4a\x32\x0b\x58\x29\xd1\x59\x46\xe4\x2f\x05\xca\x2d\xec\xa2\xe4\x9e\x08\xd6\x5b\xc9\x73\x4f\x57\x6b\xc2\xcf\x69\xf4\x0b\x18\x45\xaa\xc7\x6f\x28\x90\x37\xec\xc1\x8d\x85\xe2\xe4\xaa\x2c\x2a\x1b\x51\xb2\x46\xee\xf7\x90\x94\xcc\x98\x3b\xb7\x1f\x88\x51\xa2\xc9\x53\xa6\xc1\x37\x0b\x68\xc6\xe2\xe6\x4c\x9b\xb3\xd4\x25\xdf\xd8\x1a\xb2\x81\x1a\xd9\xc1\xc9\xc4\x72\x9b\xee\x1d\xf1\xc7\x76\x48\xc6\x7c\xfb\x2f\xfd\x39\x16\xb1\x35\xe0\x6c\x4c\x32\x62\x51\x13\xeb\xaf\x29\x10\x1c\xca\x84\x61\x1e\xbb\xdb\x1f\xc9\xd8\xeb\x5f\x90\x47\x22\x55\x76\x63\xfb\x60\xa5\x10\x82\x0b\x44\xfa\x3b\x5d\xc9\xa4\x8b\x5f\x66\x28\xf9\x42\xa4\x83\x03\x82\x1f\x71\x8b\xd9\xb0\x81\x55\xf2\x49\x92\x41\x35\x4e\xf4\x47\x49\xb4\x00\xbd\x9e\x10\xc9\xd4\x93\xc2\xaa\x8f\xbb\x01\x25\x51\xdc\x27\xde\xee\x4f\x34\x42\x25\x24\xe3\x62\xcd\xec\xfa\xbb\x22\x7c\x53\xab\x64\xce\xdc\xb9\xf8\x6c\x2a\xe7\x2d\xd0\xa3\xcc\xd8\x4d\x4f\x25\xde\x54\x4e\x46\x61\xcd\x28\x0d\x99\x6d\x28\x13\xfe\x36\x52\x82\x5f\x37\xfa\x42\xf4\x83\xe8\xc4\xac\xd8\xcf\xe0\xc7\x7f\x45\x6f\xe0\x27\x87\xfa\x44\x88\xb2\x2b\xd1\xc5\x9f\x9b\xa3\x9d\xc8\x0f\xb3\xc8\x4f\x6a\x83\xd4\xee\x57\x88\x55\xeb\xa6\xbd\xf8\x31\xfa\xff\x07\x00\x00\xff\xff\xaa\x0a\xcc\xb8\xdf\x5e\x00\x00") + +func keysWordlistJapaneseTxtBytes() ([]byte, error) { + return bindataRead( + _keysWordlistJapaneseTxt, + "keys/wordlist/japanese.txt", + ) +} + +func keysWordlistJapaneseTxt() (*asset, error) { + bytes, err := keysWordlistJapaneseTxtBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "keys/wordlist/japanese.txt", size: 24287, mode: os.FileMode(420), modTime: time.Unix(1497960590, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _keysWordlistSpanishTxt = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x34\x5b\xbb\x76\xfc\x2e\xaf\xed\x79\x4b\x8c\x65\x8f\xe6\x00\xe2\x27\xc0\x2b\x99\xb7\x49\x99\x62\x8a\xff\x4a\x97\xd6\x2f\x76\xd6\xde\xe4\x2b\x46\x98\x3b\xe8\x2e\x60\xee\xaf\x2d\x26\x0b\x71\xdb\xad\x48\x0d\x71\x93\x67\x0c\x71\x53\xf1\x81\x52\x3b\xe3\xce\xb4\x12\xae\x42\x8f\x2f\x26\xea\x21\x6e\x53\x32\x32\xb3\x5b\x88\x29\x6e\xd1\x91\xec\x52\x34\x86\x98\x92\xb0\x38\xe9\xfd\x53\x43\x4c\xa2\x43\x90\xe4\x13\x95\x52\x31\x5a\x92\x36\xa2\x87\xfb\x2b\x29\x66\x4a\x39\x3a\xc7\xa8\xf7\x77\x88\xc9\x4e\x41\xc6\x38\xcc\xd0\x8b\x09\x81\xeb\x0b\xc9\x64\xe3\xb9\x2b\x13\x71\x8e\x31\x3b\x4a\x77\x65\xd3\xbd\xe8\x40\xed\x6e\x9c\x28\xee\xe6\xd8\xcc\x3e\x63\x8d\x48\x32\x1a\xdd\xdf\x2e\x16\xe2\x21\x89\x6d\x0e\xfd\x5b\xf2\xa1\x75\xe5\xbd\x70\x91\xa7\xe6\x10\x4f\x65\xa3\xd3\xea\xfd\x8e\x48\x3b\x86\x38\x6d\x95\xba\x9c\x2b\x55\x14\x4e\x34\x98\xbb\xa1\xef\xd4\xcc\x1c\x30\xfc\xb0\xd3\x00\xdd\x2d\x44\x75\x09\x51\x7b\x46\xbf\xa7\xec\x2e\x2f\xa4\x58\xe5\x73\x76\xa0\x2c\xc7\xe4\xf7\x57\xc5\x47\xd9\x9c\x05\x5e\x62\x88\x79\x8b\xe1\xfe\xca\xdb\x2c\x21\xe6\x14\xf3\x8e\xaa\x5d\x50\x23\x27\xdb\xc9\x13\x83\x66\xf1\xc1\x42\xc2\x43\x33\xb0\x4a\x2a\xe4\xd3\x76\xee\x34\x2b\x29\x9d\x75\x91\x25\xeb\x85\xf5\x67\xce\x52\xc8\x14\xb9\xdc\x6f\xd2\x37\x8f\x05\xe5\x85\xd2\x45\x15\x62\x31\x8f\xe9\x28\x9a\x05\x6b\xcf\x2f\x34\x2b\x71\xcb\x82\xa4\x0e\x26\xcd\x80\x84\x12\x1d\xfb\x2f\xb1\x13\xad\x65\xfb\x4b\x14\xc3\x14\x6e\xbd\x28\x5b\x68\x1f\x71\x0f\xb1\x18\xc6\x6a\x11\xe8\x2a\x2d\x63\x6d\x35\x3d\x08\x35\x56\xa6\x18\xb7\xee\x98\xb3\xee\xf7\x77\x0d\xb1\x92\x0b\xef\xaf\x7a\x4e\xf0\x68\xd5\x9c\x41\x87\xaa\x05\xb9\xfb\xdd\x43\xac\x8b\x68\x75\x08\x98\xa1\x0e\x3d\x27\xea\x86\x3d\x91\xcc\x98\x01\x49\x97\x3a\x6b\xc2\xac\xf7\x7f\x91\xcc\x76\xff\x27\x4f\x66\x2d\xc4\x16\x49\xf2\x16\x3d\x62\xfd\x4d\x06\xf7\xd1\xd0\xbe\x65\x4d\xac\x34\xa0\xb7\x99\x03\x0d\xcd\x3e\x91\x71\xa9\x3b\x28\xd1\xdc\x88\xd8\x36\xa5\x83\x42\x6d\x62\x9b\x4e\x82\x38\x66\x0c\x14\x8a\xfb\xcb\x37\x1d\x6e\xfc\xb0\x1c\xa2\x6f\x93\xac\xe7\xe9\x41\x22\x38\x24\xd9\x39\xa4\xef\x9a\x81\x10\xdf\x27\xdb\x0b\x10\xe1\x14\x31\x57\xe9\x21\x7a\xf9\x63\x5f\xaf\xf7\x37\xf2\x06\x52\x7b\x23\x20\x47\xb8\xcb\x09\xbc\xb9\xdb\x0b\x70\x82\x5f\xb8\x7c\x1f\xca\x75\x76\xfe\x30\x66\x5f\x0c\xd0\x93\x54\x88\x6a\x97\x73\x52\x8c\xbb\x30\xd7\x41\xbd\xfe\xc7\x5a\x5d\x33\x61\xa7\x58\x76\x10\xaf\x5b\xd9\xb8\xaf\xde\x04\x5b\xef\x63\xad\xbe\x8f\x95\x9b\xec\x37\x0b\x3b\x4c\x8e\x32\xe2\x93\xf0\xdf\x14\x24\x1e\xe2\x58\xc3\x0f\xc1\x40\x43\x81\x8b\x41\x8e\xbf\xbf\x86\x81\xe4\xc3\x23\x50\x33\xb8\x9f\x71\xff\xd6\x10\xe7\x1e\x5f\x80\xa0\xd4\x3c\x25\xc4\x89\x69\x67\x59\x43\xcd\x2e\xe4\xda\x39\xb0\xfe\x0b\xdc\x70\xc5\x9a\x04\x09\x16\x76\xe1\x4b\x72\xa6\x26\xb9\x64\xc1\x3e\x7c\xbe\x42\xbc\x96\x02\xb9\x14\xf8\xf8\xc4\xbc\x9f\x73\x8f\x80\xd8\xf0\x2b\x1e\x4b\xa0\x29\x23\x2f\xc3\x2c\xaf\xfb\x97\x9c\xf2\x9a\x07\x44\xf7\x35\x73\xd8\xe2\x16\x01\xcc\xc3\x16\xd3\x43\xc2\x16\x1f\x20\xda\x16\x35\x23\x03\xe1\xde\x62\x8e\xf5\x85\xb2\x9c\x30\xe5\x46\x35\xb0\xc5\xb2\xdd\xbf\x61\x8b\x35\x19\xe0\x8e\x06\x60\xd6\x2d\x3a\xc7\x74\x96\x7b\xd5\x17\x12\xb7\xb0\xdd\x5f\x3d\x61\xfb\x5b\xec\x63\x0d\xd4\x21\xce\x5b\x1c\x31\xb3\x78\x88\xaf\xc9\x41\xb8\x2d\x8e\x39\x38\xe8\x2f\xd6\x89\x7d\x6c\xb2\xdd\xdf\x80\x8a\xd9\x04\xd2\xb6\x49\x67\x45\xe7\xe7\xd0\x18\x36\x85\xd8\x6e\x2a\x35\x6c\x5a\x4f\x0b\x5b\x5e\x6b\xcc\x06\x52\x6e\x79\xf6\x18\x36\xc3\x6f\xd3\xca\xc4\xc2\x66\x09\x5f\x69\x15\xec\x04\x72\x22\x59\x25\x99\x00\xac\xb3\x59\x66\xff\x82\x4d\x5a\xdd\xe3\x8e\x04\xe2\x48\x1b\xb6\x59\xed\xf7\x97\x86\xcd\x1c\x48\x32\x07\x97\x6e\xd6\x39\x35\xa8\xb0\xd9\xb8\xdf\x35\x6c\xf7\xcf\x25\x9c\xe7\x15\x73\xd8\x3c\x5e\x16\x96\xdd\xdb\x5c\xd2\x23\x22\xb9\x24\x6c\x4e\x9d\xb2\xb9\x72\x0b\xae\x98\xdb\xb9\x58\xca\xd3\xe6\x06\x76\xd9\x9c\x43\x3b\x34\xff\xe6\xb3\xb3\x2d\x78\x7a\x9b\x49\x08\x41\xcd\x09\xb5\xb7\x4d\xf9\x0c\xdb\x3c\x16\xc5\xe6\x41\x42\xdc\xbf\x40\xd9\xd4\xe1\x68\x96\xd9\xd1\x37\x8e\x36\x3d\x13\x62\xeb\xb3\x83\x7f\xb6\x39\x22\x16\x30\x5f\xe8\x0b\x93\x8c\x25\xa6\xb8\x41\x5d\xa7\x48\xa4\x26\x18\xf1\x90\x62\x8a\xa8\xd9\xef\xaf\x4b\x1c\x1f\xc2\x3a\x7e\x1f\xf7\x77\x48\xf1\x7e\xef\x28\xd1\x02\x66\x4d\xf1\x89\xcc\x73\x8d\x9b\xf1\x83\x22\x47\x0a\xd5\x08\xfb\x43\xa8\xc0\x7a\x8a\x39\x0b\x60\x41\x9f\x6c\x6c\x76\xa1\x9e\x05\x65\x63\x8f\x22\x6b\x71\x45\x2b\x93\x66\x21\xdd\x5f\x35\x71\x09\x75\x57\x4c\x52\x25\xa3\x47\x3d\xa1\x15\x53\xac\x9a\x98\x1d\xc8\x40\x37\x02\xae\x25\xd9\x86\x9c\xf5\x90\x62\x8b\x2f\x40\x1d\x6b\xe1\x0d\x04\x48\x91\x1e\x40\x8a\x6d\x82\x84\x29\x12\x07\xbe\xb1\xf3\xfd\xe5\x49\x30\x9d\x43\x65\xa4\xe8\x27\xa1\x42\x66\x52\xf4\x8a\xee\xde\xfe\xea\xb8\x10\xe7\x77\x27\x48\x28\xe8\xc2\xf2\xde\x58\x34\xb8\xe5\x61\x9e\xd0\x15\xa4\x4b\x50\x37\x98\x62\xb2\xd3\xcb\x42\x92\xcd\x20\x5b\x49\xa0\xb4\x93\xec\x18\x40\x32\x70\x7e\x7f\x67\x81\xa9\x4f\x92\xe1\xfd\x20\x3f\xd9\x72\xe9\xa6\x24\x55\x41\x4f\xa9\x83\x7d\x1c\x48\xa1\xfb\x93\xc4\x49\x69\x59\xe5\x60\xf0\x24\x4e\x63\x9d\xee\xef\xde\x64\x0f\x49\xd8\xe9\x11\x49\xc5\x47\xcc\x92\x98\x2d\xed\xfe\x45\x4a\x5b\x9a\x1e\xb1\x11\x3a\x33\xca\x26\x0a\x77\x64\x59\x9b\xf4\xa0\xc0\xa6\x87\x61\xe4\xc7\xa4\xaa\x4d\x8f\xd9\x30\xa1\xa6\x4c\xac\xaa\x9c\x06\x98\x09\x59\x00\x1f\x32\xe9\x01\xdc\xeb\xb9\x50\xa9\x60\x09\x8a\x50\x52\x20\x5a\x2b\x86\xd2\xe6\xb0\x4c\x49\x9d\x15\x3e\xc9\x07\xda\xd9\x82\x0d\x26\x19\x2d\xd3\x39\x48\x39\x56\x00\x8c\x97\x63\x17\xc0\x0b\x50\xa9\xc3\x53\xe6\x24\xf9\x7e\x2f\xfe\x31\xe2\xd6\xfe\x5c\xd3\x64\xe9\x41\x0e\x5c\x2a\x26\x19\x66\xbc\x7f\x76\xb8\x20\x09\x86\x3b\xd9\xc1\xf6\x70\x47\x93\x3d\x04\x23\xda\x13\x9a\x22\xc1\x55\x48\xd0\x40\xc9\x32\xd9\xca\xb2\x9c\xca\x32\x78\x05\xc9\xf2\x1a\x32\xe7\x95\x2b\xac\x9a\x85\x85\x05\x5a\x15\x29\xc7\x2d\x4a\xca\xff\x94\x35\x65\x69\x40\x92\xd5\x1d\x2d\xaa\x70\x9e\x7a\xb2\xc8\x28\x21\x56\xfb\x5f\x29\xf9\xda\x40\x2f\x6b\x0a\xe8\x71\x89\xbf\x39\xf4\x37\x52\xa8\xdd\x64\xbe\xff\x15\x1b\xe7\x77\xe7\x38\x7d\xc1\x02\xd1\x31\x98\x76\xba\x9b\x62\x4c\x07\x2a\x5d\x22\x61\x5a\x99\xfb\x8d\x15\xba\x14\x36\x7d\x03\x2a\xe2\x87\xe4\xda\xd8\x5d\xbb\xf6\x90\x1c\x76\x37\xf9\xfd\xb3\x90\xee\xe0\x18\x56\x4f\x76\x9f\xaf\x90\x66\x24\xd3\xcf\x48\xbe\x98\x91\x9c\x39\x37\x02\x44\x18\x09\xb2\x0a\x3c\xcc\xa5\x2a\xe6\x62\x7f\xb8\xfa\x2c\xe4\x6a\xa7\x5c\x80\x0a\xef\x2f\x4d\x08\x0e\xb2\xb9\x11\xb2\x39\xdd\xe6\x34\xe1\x3a\xa2\x09\x36\x3f\x2b\xd7\x32\x8d\xb0\x2d\x2d\xf0\xdb\x28\x65\xf4\x5e\xd2\x74\xa5\xec\x4d\x5f\x90\x93\x0c\xed\x61\x87\x12\xdb\x69\x76\x31\xe5\x1e\x21\x78\x3b\xbc\x8e\x1c\x76\xd9\xc4\xc3\x7e\x7f\x6f\xc8\xdc\xdf\x29\xee\x31\xec\x92\xd4\xc3\x2e\x68\x26\x87\xd4\x8e\xa2\x43\x2b\x0b\x61\xc5\x77\xc9\x07\xd8\x69\x47\x70\xc4\x56\x19\x46\x6b\x97\x62\x8e\xb6\x70\xab\x76\xa9\x23\x62\x82\xe5\x45\xee\x02\x53\x84\x62\x77\xec\x61\x97\xbe\xbc\x8b\x5d\xe0\x76\xed\xd2\xe1\xe8\x23\xad\x93\x23\xf6\xa1\xab\xf6\xba\xdf\x48\x07\x55\xf4\x2e\x43\x2a\x56\x2c\xf0\x4f\x76\x10\x73\xd7\xb8\x65\x43\xb2\x83\xc2\xbb\xfe\xb9\xef\xbb\xc2\xd3\xd9\x35\x22\xb6\xd9\x75\x9b\x4f\x24\x0c\x99\xf6\x25\x66\xbb\x02\xa7\xbb\xca\x2b\xec\x7a\xdc\xef\x04\x1c\xe8\x89\x69\x35\xaf\xb1\xf2\xc4\xa6\xb5\x42\x3f\xed\xea\x82\x20\x6d\x57\xd7\x93\xc5\xd0\xa4\xbb\x76\x81\xda\xdd\xb5\x1f\x1e\x31\xd2\x85\x8e\x17\x57\x6f\x08\x27\x76\x4b\x00\xb0\x2a\xbb\x15\xba\x11\xbb\x55\xfc\xb0\x14\xa3\xe7\xbc\x9b\xc3\x5f\xdc\x0d\xc4\xdb\xad\xe3\x07\xd2\x79\x3c\x41\xea\xdd\xed\x8c\x61\xa7\x25\xd8\xb9\x73\x46\xb2\xfb\x5c\x53\xcf\x8c\x19\xee\x5f\x7c\x42\xcd\xed\xe4\x88\x7d\x52\xb7\xee\xb0\x44\xf7\xf7\x86\xc0\x43\x36\x20\x03\x3e\x81\x07\xa8\x51\x01\x47\x9b\x07\x81\x6e\x92\xfd\x2f\x90\x94\x5d\x11\x53\x1a\x3e\x06\x6b\x27\x6c\xb5\x1c\xdc\xbe\x1c\x9a\xe2\x2b\xc8\x53\xf0\x2b\x2d\x5b\x90\x2c\x07\x71\x2e\xd0\x26\x8e\x64\x29\x7e\xc9\x72\xa1\x67\xd6\xd6\x25\xdc\xdf\x59\xd9\x48\x3f\xd8\xc8\xa0\x79\x24\x33\x1e\x96\xb2\x81\xee\xb2\xe2\x5f\x29\xf6\xb7\x94\xd2\xa0\x73\xa4\x34\xee\x14\xd3\x09\x13\x97\x1e\x83\x54\x6e\xaa\x26\x06\x68\x52\xd3\x63\x1e\x82\x14\x7c\x21\x88\xa8\x58\x0c\xe2\x49\x3d\x80\x67\xa9\x87\x78\x41\x7a\xd2\xc1\x94\xaa\x67\x41\xdb\x1c\x13\x7a\x9a\x17\x24\x2e\x6c\xdb\xe3\x27\x13\xb9\xff\xc3\x2e\xea\x58\x23\x0d\x67\xee\x82\xe2\x96\x4a\xfe\xbc\xbf\x1b\x1c\x29\xf9\x37\xb5\x59\x10\xd7\x97\x05\xe9\xf0\x39\x90\xc0\x53\x91\x0e\xbd\xeb\x48\x5d\x37\xe5\x07\x77\xdc\x05\x51\x61\x90\x7e\x88\x33\x99\xe2\xec\xdd\x20\x8b\xd2\x1b\xb4\xa6\xf4\xc6\x3d\xf5\x66\x9d\xc9\xc4\xaa\xfb\xbf\x79\xbf\x03\xb4\x0a\x86\x03\x9e\x10\x8b\xa0\xf5\x98\x47\x0c\x32\x60\x14\x65\x88\x57\xac\x70\x40\xad\xc9\xa8\x98\xec\x62\x5c\x28\x57\xcc\x13\x7d\xaf\x45\xad\x8b\x67\x05\xf2\xc1\x63\x0b\xf9\x40\x6c\x1b\xe4\x83\xe7\x22\xf2\x91\xe0\x08\xc8\xc7\x6a\xf9\x41\x09\x90\x0f\x45\x70\x2b\x1f\x2b\x3c\xba\xbf\x3f\x94\x95\x8d\x76\x53\x3e\xfe\xc2\x49\xf9\x68\x06\xa1\x95\x8f\xe1\x52\x2c\x1c\xf7\xd7\xe6\x58\x0c\x3e\xa0\xc1\x8e\x98\x1e\xd8\xec\x71\x7f\x41\x06\x0f\xcc\xef\xe1\x88\xc0\xdb\x01\x3f\xee\x88\x70\x33\x0e\x3a\x87\x47\xcc\x9d\x10\x6b\x3d\xa0\xdb\x8e\x58\x34\x2b\x53\x63\x95\x47\xf0\xce\x11\xbd\xc4\xc4\x72\x37\x8c\xea\x1d\xdf\x5d\xc2\x11\x87\x9e\xf8\x9e\x9c\xe0\xe2\x64\x1f\xe1\x80\x0f\xe3\x16\x0e\x3a\xcd\x87\x64\x7d\x85\x43\x90\x77\x8c\x22\x08\xc5\x8e\xfb\xdb\xa1\x38\x0f\x71\x76\x93\x4e\x17\xfc\x50\x9e\x1c\x1c\x4a\x35\x7b\x28\x96\xa6\x50\xec\x87\xfe\x59\xed\x43\x39\xa8\xee\x18\x50\xe9\x2d\x1d\x2a\x19\x80\xcd\x68\x1b\x0e\x45\x28\x1a\x0e\x7d\x72\x80\x27\x9a\x02\x3f\x9a\x61\xc4\x0f\xec\x12\x3d\x32\xec\xce\xa1\x18\xb4\x02\x8d\x5a\x41\x0d\x68\xe8\x81\x72\x07\x4e\x72\x4c\x06\x88\xb8\xe7\xc8\x6b\x47\x50\x41\x47\x36\x96\x40\xb1\x1d\x19\x4a\xf1\xc8\xf7\x2f\x2a\x6c\xc3\x2e\xc1\xc6\x87\x9d\xb0\xc3\x87\x51\xf9\x1c\x06\x22\x1f\x96\xb3\x60\x78\xab\x3b\x20\x27\xe1\x89\xd0\x61\x3e\x88\x48\x73\x04\x56\x07\x38\xf4\x30\x34\xf5\x98\x22\x08\xe2\xeb\x2c\xea\xf0\x58\x41\x4c\x27\x0d\x3c\xce\x1d\x89\xdc\x6f\x47\x52\xd1\x10\x52\x7d\x38\x24\xea\x70\x6e\xc6\xb9\xfe\x09\xcf\xec\x98\xd4\xda\x94\x0f\x94\x81\x82\x13\x2e\xfd\x31\xeb\x1f\x8e\x27\x02\x91\x63\xfa\x5a\xf7\x24\xd9\x66\xc7\xd4\xf7\xef\xd8\xc0\x04\x73\x40\x1d\x9e\x31\xc1\x3f\x3b\xe3\x11\x7b\x38\x23\x1c\xb4\x13\x21\xfa\x19\x59\x9a\x57\xec\x78\x92\xdf\xce\x88\xf0\xec\x8c\xd0\xd6\xe7\x3a\xc7\x39\x23\x3c\x9b\x33\xc2\xce\x9d\xd1\xe3\x53\x90\xbc\x50\xd4\x97\x07\x75\x46\x0a\xe5\x19\x07\x5a\x5c\x9a\xe1\xd9\x9f\x52\xa0\xb5\x4f\x81\xaa\x3f\xa5\x86\xf3\xfe\xa6\x72\x3a\xa5\x2a\xe1\x90\x70\x8a\xc7\x95\xf3\xff\xe5\x21\x86\xa7\x74\x0c\xa5\x27\xf5\xec\xa9\xa5\xc6\x8e\x56\x0a\x5d\x74\x2a\x06\xc9\x60\x76\x0f\x67\x46\x10\x7a\x66\xc3\xee\x4f\xcb\xf8\x1d\x06\x08\xe1\x38\x2d\x37\x09\x27\xe2\xbd\xd3\xe0\x08\x9c\xe6\x60\xb1\x13\xd1\x65\x38\xc1\x1b\xa7\x0d\x41\x39\x88\x79\x3a\xe4\xf2\xf4\xfb\xeb\x80\x4f\x7d\x3a\x14\xee\xe9\x08\x24\x4e\x8f\xf0\x2e\x4e\x87\xe7\x7a\x3a\x6d\xe9\xb9\x42\xcc\xd3\xb5\xb1\x0c\xd5\x20\xe3\xe9\xd6\x0d\xa3\xdd\xbf\x68\x34\xa1\x51\x4e\x9f\x85\xb0\x59\x38\xe7\xda\xd6\x8c\x2b\xe3\x3b\xd6\x3e\x85\x6b\x9a\xa4\xc5\x64\x70\x73\x4e\xb5\x0a\xd8\xf9\x3d\xe2\x6a\xd1\xb9\xac\x49\x9c\x3f\x22\x5c\x9a\xc7\xfd\x05\x97\xe6\x11\xb7\xcc\x32\xb8\x82\x0f\xa8\x99\x40\x4d\xf3\x88\x79\x95\x17\x84\x9f\x8f\xe8\x20\xda\x23\xbe\xf0\x63\x9c\xf6\x90\x8d\xa7\x3a\x0f\xba\x67\x0f\xfa\x2e\x0f\xc9\xb0\x21\x0f\x81\x3c\x3c\xa4\xac\x1a\xf8\x7d\x0f\xf1\x82\x25\x3c\xee\x6f\x37\x41\xf6\x42\x29\x43\x89\x87\xc2\xe5\x09\x8f\xfb\x4d\x5f\xe9\xa1\xa7\x4a\x95\xf0\x80\x74\x3f\xb4\xa0\x97\x22\xfe\xd2\x18\x1e\x96\x80\xe5\x87\xc1\x17\x7f\x18\x10\x80\xc2\x27\x00\x7d\xc2\x87\xc1\x7b\x78\x58\x35\xd4\x57\xd6\x2e\x50\xa0\xd0\x1e\x3c\x2d\x7e\x18\xac\x40\x78\xd8\xa7\x85\xc7\x84\x99\x7f\x4c\x9e\x62\x3f\x26\x4f\x56\x1f\x44\xff\x63\xca\x05\x08\x2f\xfe\x01\x65\xf0\x98\x7f\x5b\xf8\x2d\xb0\x7e\x8f\x59\x34\xef\x82\x14\x99\xba\xb3\x89\x47\x44\xbc\xf8\x18\x16\x14\xbe\x7d\xd0\x5d\x62\x0e\xba\x2b\x78\x0a\xae\x76\xb6\xa0\x67\x96\xae\x11\xe9\xfd\x1b\xf4\x9c\x68\x91\xe5\x64\x32\x3b\x85\x55\x4b\x84\x0c\xac\x68\x5d\x0b\x4d\x8f\x96\xb6\xa0\xc0\x4f\xd1\xb2\xec\x86\x96\x36\xa1\xf3\xa1\xec\x10\x2a\xdf\xef\xba\x6b\x92\x00\xb7\x6c\x20\xa1\x22\xd5\x7a\xd0\x7a\x6b\x5d\xe2\xa4\x95\x3e\x8c\xd6\x42\x7f\x54\x6b\x99\x15\xb5\x15\x32\xa9\xb5\xd3\x99\xd1\xda\x07\x59\x4f\x61\xdc\x11\xc1\xdd\xef\x3a\xb4\xa0\x66\x00\x2b\x5a\xef\x5f\x60\x53\xeb\xa5\xb4\xa3\xea\x31\x28\x38\x5b\x7d\x9d\x49\x6a\xcf\x04\x08\xda\x9f\x71\x8b\xf9\x7e\x23\xc5\x16\x9f\xb1\xac\xc4\xe3\x86\x4a\xdf\x61\x2b\x9e\x64\xda\x27\x4f\xef\x9e\xf1\x55\x58\x26\x87\x84\xa7\xb8\x42\xb1\x3c\xb5\x42\xdd\x3f\xcd\x2b\x78\xf5\x69\x6e\x1b\x92\x4b\x6a\x78\xda\x67\x0c\xcf\x29\x88\xf8\x9f\x53\x2e\xe9\x48\x5e\xe1\x39\x4f\x7a\x72\xcf\x79\x1a\xc0\xe4\x08\x93\x28\x78\x4e\x44\xab\xcf\x59\x4f\xcc\x38\xeb\x2a\x02\xbe\x9f\xf7\x6f\x53\x84\x4c\x4f\x7a\x8c\x4f\x9e\xd0\x3e\xe7\x25\x55\x73\x78\xce\x17\xf8\xf0\xff\xe0\x51\xfc\x9f\x41\x33\xe6\xb8\xa9\x05\xe8\x19\x42\x47\xc9\x8e\xcf\x1d\x51\x53\xc8\xf1\x64\x60\x94\xef\xaf\xd3\x11\xc1\xe6\x78\xc2\x30\xe4\x08\xae\xce\x11\x71\x63\xbe\xbf\x0a\x64\x0d\x69\x8b\x1c\x81\x2d\x2a\x44\x33\xc7\x7a\x32\xa2\x5b\x87\x84\xf9\xfe\x6a\xfa\x0a\x99\xde\x5d\x8e\x88\x68\xf2\xfd\xd5\xc7\x1a\x7a\x30\x37\xe4\x03\xdf\xea\x21\xc7\xe9\x92\x43\x8e\xf0\x38\x73\x7c\x59\xc8\x60\xcc\x2c\x7f\x06\x18\x36\x50\x00\xe1\x5b\x64\xc1\x5a\xe4\xfc\xab\x39\x57\xc8\x95\xe5\x09\x11\xc8\x52\xcf\x19\x91\x60\x33\x70\xfe\x00\xd9\xd0\x1a\xa3\x27\x70\xf7\x2a\x18\x9c\x62\x60\x23\x72\x61\x84\x4f\x81\x0d\xca\xba\x41\xd6\x76\x7c\xb8\x85\xac\x09\x93\xde\xef\x1d\xd3\x2a\x82\x92\x80\x58\x1f\x8b\x84\xe0\x66\x3d\x85\xcd\xb0\xb3\xfb\x5d\xe0\x26\x67\x25\xf3\x64\x2d\x0d\xe8\xd6\x9a\x50\x06\xe3\x9b\xef\x77\x15\x74\xaa\x50\xd5\x48\x59\x0f\x3f\x8f\xdd\xff\x4d\x45\x2b\xe8\xc8\xcc\xb3\x6f\xb8\xdd\xce\x84\x23\xc1\x7b\xc8\x20\x16\x60\x21\xe4\x4e\x79\x06\x91\x33\xaf\x84\x72\x96\xba\x12\xa2\x33\x9b\xaf\xe4\xc2\x06\xf2\xbc\x34\x06\xda\x99\xfc\xe7\xa8\x67\x4b\xcc\xc0\x7d\xc9\xf7\xcf\x09\xf7\x2e\xdb\x89\x99\xa0\xba\x40\x46\x84\xd7\xd9\xe0\x01\x50\x56\x32\xa3\x99\x3c\x11\x6b\xe6\xc9\x39\xe1\x8d\x64\x72\xcc\xac\xd2\x43\x9e\x0d\x9f\x3c\x57\xcf\x13\x2b\x9c\xaf\x50\x62\x82\xa5\x29\x11\x1a\xb9\xc4\x1d\x1b\x2b\x71\x77\x01\x84\x6d\x2f\x51\xd8\xa3\xc4\x43\x51\x75\x2e\x88\x82\xfb\x8d\xfe\x19\xc1\x4e\x59\xf7\x4b\x85\xa7\xc5\x25\x66\x54\x97\xfb\x0b\x70\xe3\xf7\x1c\xa1\xf0\xac\xb7\x44\xe0\xbc\xc4\xca\xd0\xb7\xd0\xf4\x97\x58\x95\xbe\x77\x81\x47\xc3\x52\x36\xe9\x84\x1c\xf7\xfe\x0f\x8c\x5d\xe0\x81\x97\xfb\xeb\xdf\x54\xe6\xd0\xd4\x39\xa8\x0b\xf3\x87\x66\x24\xd0\x84\x25\xf2\xca\xa3\xdc\x5f\x5e\x8c\xa5\x94\xaa\x12\x7d\x48\x47\xf2\x42\xbf\xce\xf1\x3a\xcf\x03\x4b\xec\x7a\xa1\x70\x70\xe0\x41\x3f\xb5\xc4\xa1\xd8\x26\x2f\x1d\xcb\xfd\xf5\x01\x6d\x56\xe2\xa7\xa1\xc9\xcb\x3c\xc5\x50\xe8\x0e\x16\xd9\xd7\xee\x65\x57\x4c\xfb\xbd\x4f\xe6\x9e\xba\x4a\x9f\xe8\x21\xe0\x03\x24\x5c\x0a\x02\x7c\x4c\x81\x40\x09\xb0\xc3\xf5\x29\xf4\x53\x8a\xd4\xfb\x37\x14\xf1\x04\x95\x50\xe0\xbd\x9c\x53\x30\x2c\x3d\x80\x82\x2d\x48\x5f\xa3\x00\x41\x08\x4b\x50\x3b\x8c\xcd\x49\x31\x79\x25\xcc\xac\xb0\x3f\x05\x3a\xbd\xa8\xf0\xae\x85\xd6\xad\x00\x55\x9a\xe3\xc9\x82\x4c\x83\x51\x34\xaf\x95\x71\x93\xc4\xf1\x0a\xd6\xa1\x55\xff\xca\xc0\x39\x45\xad\x49\x28\xf4\x96\x8a\x02\x87\xda\x17\xb6\xb4\x73\xd8\xce\xb6\x90\xd8\xc2\xe5\x5a\x7a\xc0\x2d\xfa\x5f\x1c\x5a\x6c\x47\x66\x87\x41\x2f\x06\xce\x33\xd2\xdd\x60\x22\x8b\x65\xe1\x37\x04\xb1\xd8\x0a\x7d\x8b\x15\x0c\x8f\x20\x3f\x31\x15\x8e\x00\xf6\x2f\xb6\x1a\xc0\xa1\x29\x46\x0f\xab\x18\x6f\xc2\x8a\xd1\x0f\x06\x96\x99\x71\x7e\x77\xd6\x43\xd3\x14\xeb\x1c\xac\x33\x04\x2d\xc6\xeb\xcc\x42\xa1\x2c\xf7\xcf\x85\x9d\x18\xb8\x64\x52\x38\xe6\x8e\x46\x53\x10\x99\x14\x1e\x48\x96\x49\x8b\x59\x26\x44\x04\xd9\x13\x72\x33\x9f\xe8\x4f\xe2\xaf\x83\xd1\x32\x33\x21\x19\x7f\xde\xff\x09\x26\x9d\x8e\x05\x50\xc2\xee\xdf\x9e\x26\x30\x31\xbb\x10\x9e\xab\x50\xd9\xae\x67\x0b\xf5\xfe\x42\xe4\x57\xe3\x42\x1f\xec\x18\x72\x70\x0b\x6b\x5c\x61\x40\x8d\x60\xd0\x1a\x79\xe8\x5b\x63\x8f\x39\xd4\x38\x16\xc4\xb6\x6a\x1c\x9c\xb2\xde\x5f\xb3\x0b\xda\x5f\xac\xbc\x30\xc4\xc5\x63\xfb\x2a\xb0\x44\xf5\xfe\xe6\xa9\x4e\xa5\xe2\xaa\x72\x1a\x4b\x05\x7c\x52\xa9\xb7\x2b\xfc\x31\x64\x06\xc0\x1c\xac\xb8\xd8\xf8\x82\xfe\xa8\xbc\xe6\xa9\x90\xbe\xaa\xb2\x65\x94\xb0\xad\xde\xff\xc9\x8b\x09\xa6\x79\x8f\xd5\xe2\x92\x1c\xaa\x6d\x59\x5e\x31\x54\x83\x55\xa9\xf7\x0f\x99\xaf\x52\x3c\x2a\x83\xa3\xca\x73\xaf\x0a\x8f\xba\xda\xd0\xc4\x8a\x0b\xce\x47\xb5\x0b\xc4\xa8\xc6\x45\xcd\x4d\x42\x9d\x29\x86\x7a\xff\xa6\x2c\x28\xd9\xe9\x45\xf3\x20\xac\xd2\x07\xac\xb0\xf4\x80\xaf\x50\x27\xd1\xfb\x5b\xc0\xe5\x75\x0e\x4c\x68\xb1\x6b\x0f\xc6\x9b\x2b\xdb\xb4\x37\x24\x4f\xec\xc0\xe0\xa3\xda\x0a\x6b\x6d\xeb\xe2\xd8\xb5\x6d\xeb\x10\xcd\x36\x2c\x00\x01\x9f\x31\x4e\xb3\x74\x7f\x43\x91\x61\x4b\x50\x62\x06\xac\x10\x99\x96\x5c\x82\xa5\x11\x2f\x7c\x8f\xb9\x31\xcb\xd3\x4a\x4b\x3c\x44\x87\xe6\x07\xd3\x1a\x6d\x9b\x41\xa3\xd8\xae\xa0\x9b\xf1\x64\xc2\xd6\x39\xa2\x1d\x74\x41\x6d\x9d\x2f\xd9\xb1\xce\x68\x69\x27\x8c\xc7\xb4\x86\x68\xd0\x9e\x16\x2c\xc7\x60\x59\x20\x1c\x96\x0f\xa0\xcd\x32\xd8\x82\x57\x10\x3c\x98\xe6\x89\x9a\xe5\x0b\x44\xb1\xb2\x65\x3d\x2d\x18\x8c\xaf\xc1\x79\xb0\x86\x00\xd8\xda\x62\xc0\xfb\xa7\x01\x8f\xd6\xf8\x44\xc2\x96\x5f\xb9\xde\x58\xdc\x3f\x8d\x27\x23\xc6\x0b\x6d\x0b\xe6\x7f\x4c\xcb\x93\x39\x47\x92\xc3\xfd\xe3\x1b\xa2\x44\xaa\x4f\xc8\x2a\xaa\xe5\x19\x51\x71\x12\x67\x7e\xc2\x19\x34\x3f\x27\x68\x67\xbe\x8e\x18\xcd\xf5\x64\x5b\xea\x54\xc3\x36\xfd\xdf\x3a\x07\x36\xde\x51\x5b\x8f\x3c\xc5\xb4\x9e\x20\x5a\xd6\xe5\x85\xd1\x40\x0d\x8a\xa8\x0d\xaa\x09\x03\xcf\xda\xb5\x66\xbc\xc0\x02\xf7\xcf\x07\x37\xfe\x71\xbf\x4f\xe8\x0c\xfb\x5c\x13\xbe\xe0\x93\x37\x9e\xe0\x34\x9a\xc5\x16\x05\x73\x37\xc4\xe0\x35\x86\x06\x53\xd8\xe2\xfd\xee\x28\x7a\x46\x47\x2e\xf3\x8a\xad\xc5\x9c\x98\x83\x0e\x68\xf7\x57\xc6\x04\x8d\x97\x62\x2d\x66\x5b\x09\x88\xdd\x62\xc5\x2f\x66\xb4\xaa\xca\x4e\x95\x2e\x46\x8b\xf7\x7f\x3c\x9a\x6c\xb1\xdd\x5f\x80\x92\x01\xb9\xfd\x16\xff\xd1\x2d\x6d\x7c\x20\xd0\xa2\x33\x08\x6f\xd1\x65\x07\x54\x96\x19\xc6\xf4\x16\x39\x35\x70\xc5\xbc\xc7\x83\x79\xf6\xee\xec\x0d\xd5\xd3\xe2\xf2\xc3\x1a\xd8\xb7\x21\xe6\x0e\x2d\x2e\xa0\x28\xa0\x74\x34\x5e\x61\x35\x9e\x84\x34\x70\x70\x8b\x9f\x6c\x2f\x91\x57\xc7\x4d\x68\xb2\x1a\x58\x31\x22\x79\x20\xb3\x63\x77\x82\xa8\xa7\x51\xaf\x34\xd1\x2a\xa1\x49\xe6\x77\xde\x79\x7c\xd8\x24\x0b\xba\x64\x05\x07\x37\xc9\x59\x9e\x4c\x09\x20\xd4\x0d\xe6\xb3\x81\xf7\xd1\x6d\xdd\xfd\x35\x59\xd0\x50\xd4\x60\x34\x9a\xfc\x5b\x47\xb9\x6d\x2d\xc1\x61\x9f\x9b\xd0\x26\xb4\x75\x45\xd6\x84\xbe\x02\x22\xa3\xc4\x76\x99\x65\x45\xb9\x13\xe7\xf4\xde\x8d\xb3\x75\x02\xcc\x7e\x7f\x77\x58\xc1\x06\x8e\x83\x1f\xdb\xee\xef\x11\xb9\xba\xe1\xf7\x0f\xb4\x4d\x93\x17\x7e\x93\xb5\x3c\xae\x6b\x9a\x1e\x5c\xa0\x0a\x7e\x3b\x56\xa4\xf4\x2d\x9b\x72\x25\xfa\x84\xd7\xd8\x94\xa8\xd0\x6c\x60\x35\x2d\x4a\x9d\xb1\xb6\xa3\x15\x4e\x76\xd3\xca\xe6\x6b\x68\x08\x75\xd3\x86\x4f\x27\x8d\x94\x38\xd1\xce\x5b\xac\xc6\x7d\xd0\x5b\x6d\xba\xc8\xa2\x2f\xec\x20\xc7\x05\x2b\xc0\xe0\xe7\x27\x21\x86\xce\x02\x63\xdd\x32\x04\xa0\xd1\xc1\x6c\x79\x62\x6d\x99\xa6\xa3\xf1\xe2\xac\xc1\x35\x6d\x46\x5c\x52\x31\x35\x13\xb4\x31\xe9\x90\xbc\x66\x64\x77\xcb\x52\x01\x35\xad\x42\x48\x71\xb3\x0c\x76\xb1\x02\x2d\xd4\x8c\xa7\x37\x8d\xb3\x58\xc1\x46\xa8\x45\x9a\xf9\xd2\x17\x6d\xd9\xe8\x06\x91\x46\x65\x17\xd6\x76\x85\xfd\x6d\x06\x2d\xd8\x6c\xac\xd3\xde\x46\x81\x6e\x30\xd6\x8d\x17\x00\xcd\x25\xd9\x0b\xc9\x39\x89\x47\x97\xa2\x2c\x86\xda\x6c\x0e\xd5\xde\x5c\x2e\x96\x91\xa4\x7e\xbf\x6b\x82\x41\x6d\xae\x7f\x52\xe0\x0a\xf5\xde\xdc\xd0\x83\xaf\x74\x9a\x5b\x5a\x5d\x6d\x9f\xd4\x09\x6e\xa4\xa1\xdb\xc1\x87\x2e\xcd\xed\x74\x92\xd3\x0d\xcb\x74\x2b\x64\x1f\xa7\x8f\xd2\xdc\x1a\x67\x84\xb6\xe1\xa4\x53\x36\x70\xd1\xef\x96\xc9\x86\x33\x3d\x60\x5a\xda\x84\xa6\x6c\x70\x35\x90\xa1\x8e\xff\x53\xa7\x6d\xe6\x13\x99\x0c\x49\x9a\x99\x31\x4d\x9b\xb9\xb1\x06\x2b\x23\xbd\xf8\x4c\xa6\x81\x09\x33\x13\x64\x80\xe1\x09\x2e\x0b\x6d\xfa\xfd\x1d\xfe\x4d\x81\x17\xf1\x6f\x42\x0b\xfe\x9b\x52\x56\xc6\x85\x49\xb7\xf0\x6f\xd2\x6a\xc3\x31\x2f\xd0\xe8\x70\xba\x93\x20\x81\x9e\xf7\xfb\x8b\x77\x20\x1e\x37\x8d\x80\xf8\x5c\x94\xf3\xb8\x6b\x8a\x39\x38\x23\x04\xa2\xc3\x23\x28\xec\xeb\xbc\xcf\x11\x97\x06\xe7\xe1\x83\x23\x28\xdd\x99\x1b\x80\x9d\x35\x9d\x8d\x59\xf0\x09\xf0\x42\x96\x97\x9a\x2e\xff\x7b\x52\xe8\xf2\xf7\xda\xc0\x65\xbd\x6e\x71\xe1\x2b\x0e\x17\xbe\x62\x80\x29\x1c\x31\xf0\xc5\xc6\x0b\x95\xeb\x02\xd7\x25\xb9\x30\x3b\x08\x79\xbd\x07\x8d\xe9\xb2\xf3\x28\xd6\x65\x67\x0c\xe5\x72\x50\xfb\xb8\xac\xc3\x59\x97\xf5\x6a\xc7\xe5\x98\xa7\xa2\xfc\x84\xe4\x3b\x6f\x68\x5c\xce\x8c\x26\x27\x19\xcb\xe5\x71\x7f\xa3\x25\x84\x77\x1d\xc8\xd2\xb8\xb9\x64\xee\x49\xb2\x5c\x4c\x14\x6e\x88\x43\xcd\xb1\x61\xb6\x67\x70\xd2\xc1\x65\x45\x11\x3c\xdf\x77\xa9\x08\x77\x5d\x78\x68\xe4\xd4\x0b\x2e\x8d\x67\x03\x2e\x4d\x06\x4b\x9b\x71\xe6\x36\x34\x07\x97\x8e\x5f\x8a\x44\x47\x87\x42\x70\xe9\x4d\xd8\xa1\x2f\x38\x8b\x60\x89\x43\x1d\xd9\xc1\xa3\x2e\x47\xe4\xcd\xea\x59\x39\xe8\x75\x7f\x63\xa4\x8b\x8a\xc4\xe5\x33\x40\x77\x7a\xa0\xce\x74\xde\xef\xc3\x30\xef\x11\x09\x29\xa7\x47\x0c\x7e\xbf\x4f\x92\x54\x4f\x2c\x5b\x2b\x9f\x26\xb9\x2e\x6d\xcd\xd3\x68\xd7\x7f\x13\x72\xc3\x47\x33\xae\x03\xbb\x84\xea\xe1\x45\x8f\xf3\x9a\x0f\x92\x06\x00\xff\xc7\x6d\x5f\x10\x94\xb3\xf5\xba\xcd\x0d\xd4\xb4\xe7\xea\x01\x42\x19\x7d\x38\xb7\xd2\x58\x53\xf1\xc3\x3a\xe9\xc4\xb8\x35\x82\xd5\x04\xb3\xd2\xf7\x77\x63\x70\xeb\x7c\x0a\xe8\x73\xbb\xdf\x80\x58\x36\xbc\x45\x87\x88\x04\x9f\x24\x31\x4f\x01\x9c\x81\xa7\x2f\xbf\xde\xe1\x38\xf8\x44\x84\xeb\xb3\xb0\x53\xe3\x2b\x48\x9e\xb2\xfb\x1c\x68\xdb\x21\x27\xbb\x85\xce\x73\xd4\xce\x23\x9f\xce\xdb\x8d\x1e\x61\x1e\x7a\x3c\xe3\x0b\xd0\x57\xab\x1c\x01\xd6\x27\x16\xdb\x23\x44\xbd\xc7\x25\xea\x3d\xe6\xbf\xa4\xb3\xdd\x60\x83\xb9\x03\x5e\x1c\xad\x6c\xa8\xf8\x3b\xc1\xef\xb1\xd2\x1d\xea\xb1\x0a\x6b\x2b\x22\x94\x1e\x2b\x05\x87\xc7\xbc\x9d\x87\x15\x3d\x36\x00\xf8\x07\x3d\xfa\xce\x85\x47\x1f\x60\xe3\x1e\xfb\x60\x27\x3e\xa7\xe9\xbc\xe4\xe9\xf1\xc3\xf8\x3c\xa9\xff\xef\x38\xa8\x4b\x32\x00\xb0\x12\xd2\x11\x43\x97\x3d\x74\x39\x27\x96\x2f\xda\x43\xe7\x25\x7e\x97\x7c\xa1\xae\x20\x9e\xef\x52\x48\xcc\x4e\x26\xea\x52\xa1\x43\x79\x3f\x98\x99\x30\xb7\xfc\x9b\x2e\x4d\xd1\xe4\x1f\xcf\xaf\x3b\x70\x29\xae\x02\xb8\x30\xb3\x0e\x89\xbb\x74\x0a\x48\xff\x3b\x52\xea\xc2\xcc\xf8\x2b\xbc\x88\x52\xf9\x20\xc0\x4a\x15\xf6\xb8\xaf\xeb\xa2\xae\x70\xa7\xba\x9e\x58\x26\x2f\xae\xfb\xfd\xce\x11\x08\xd5\x0c\xf5\xdf\x35\x0b\x5f\x82\xf6\xb5\xea\xfb\x5d\x36\x63\xe3\xc2\x42\x87\x77\xd2\xb5\x0f\x18\xc4\xce\xe3\xa1\xae\x7c\xa6\xdc\x69\x3a\x3b\xbd\xff\x4e\xab\xd9\x2d\xe3\x17\x5b\x44\xb2\x93\xf8\x96\x79\x73\xdc\xef\x1f\xfa\x8a\xdd\x78\x29\xd7\x2d\xcf\x3f\x24\x1b\x0f\xc9\xbb\x55\x48\x42\xb7\xba\x5a\x55\x38\xc2\xdd\x2a\xa5\xa9\x1b\x47\x6c\x99\x3d\xd7\x6b\x81\xce\xab\x89\x6e\xbe\xee\x79\x3b\x0a\x91\xef\x8b\xc0\xf7\xcf\x20\x27\x4c\x04\x83\x7d\x6e\x40\xe3\xa4\x9d\xeb\x34\x44\x7d\xca\x89\x69\xe9\x89\xf6\xe5\x59\xf5\x15\xfa\xf6\x79\x38\x9b\x33\x3c\xea\x33\x2f\x26\xe1\x3d\x52\x9f\x70\xbf\x98\x92\x85\xe7\x32\xf0\x7d\x36\xaa\xb5\x3e\xf1\xed\x89\x5f\x7f\x63\xfa\xc9\x86\x9d\x63\x41\x93\x8d\xc8\x27\xea\x23\x6e\xd0\x18\x48\x73\x04\xbc\x7f\xc3\x58\x15\xd0\xe3\x7c\x0f\x3a\x22\xb6\x3c\xe8\x74\x8f\xb8\x4e\x1b\xd7\xeb\xc5\xb1\x84\x66\xc4\x42\x3b\x31\x62\x81\x84\x0f\x5a\xa1\x11\xeb\x1a\xb8\xa1\x5d\x03\x03\x8c\x08\x4e\x1b\xb1\xad\x4e\xff\xa6\xae\x41\x7c\x47\x9d\x0b\xbf\xa1\xe8\x46\xf4\x27\xd8\x6b\x44\xb7\x01\xe8\x18\xcf\x59\x32\x66\x7c\xa2\xf9\x64\xd9\x0b\x45\xb4\x5f\x43\xf8\xca\x65\xd0\x2d\x1e\x92\x30\xf2\xfd\x9d\xf8\x46\x66\xc8\x13\x6c\x30\xe4\x29\x0e\xa8\xcc\xa0\x85\xe4\xfb\xfb\x40\x24\x42\xce\x1a\x02\x65\x33\xd6\x63\x81\x21\x35\xbe\x00\x77\x76\xaa\x0b\x6a\x07\xec\xa8\x36\x5e\xbe\x21\x9c\xe0\xb6\x04\x18\x1f\xf7\xb7\xf3\xd9\xdd\x10\xaf\xd0\x58\x03\x2e\x2f\x7a\x76\xf6\xec\xc6\x35\xf6\x81\x20\x70\x08\x63\x91\x41\x81\x19\xf2\x0a\x43\xa1\xc4\x86\x6e\x93\x27\x6a\x43\xa5\x34\xe4\x29\xc4\x43\x79\xcd\x34\x14\xfc\x33\x14\xfa\x66\xe8\x93\x03\xf0\x02\x64\x28\xcf\x86\x07\x9c\x0a\xec\x0f\x7e\xd0\xe0\xa3\xaf\x01\xcb\x30\xee\x77\x83\x75\x19\xca\x21\xd9\xed\x6f\x16\xb2\xd6\xb8\xdf\x43\x56\xff\x01\xf5\x3b\x14\xb8\xb5\x45\x67\xdb\x18\xe9\x0f\x83\x62\x1d\x96\xb8\x43\xc3\x2c\x76\xa2\x3a\xf3\xb3\xb0\x92\x55\xe4\x11\x6b\x2c\x68\x12\x06\x5f\xb5\x8d\xfb\xc7\xe3\x47\x18\xc6\x30\x7f\x98\x17\x2a\x0f\x98\x48\x61\x9e\xa0\x09\x07\x73\xac\x85\xcf\x4c\x86\xf9\x98\x9c\xa6\xe3\x87\x3d\xf0\x6d\xd5\x80\xb3\x87\x9c\xc7\x8d\x7c\xea\xeb\x3e\x7e\xbd\x48\x1e\xff\xbb\x0b\x1c\x8e\x48\x72\xf0\xf6\x73\x78\x2c\xfc\x86\xbf\xb5\x4c\xf2\xf0\x08\xcf\x6e\x38\x5f\xdb\x0e\xbf\xbf\x37\xcb\x61\xc0\xbf\x45\xa9\x2c\x0c\xba\x54\x00\x6e\x08\x4e\xc0\x70\xdd\x26\x20\x87\x46\xb4\x30\x9c\xcf\xf8\x86\xeb\xac\x07\x0a\xed\x10\x26\x85\x95\xb4\x98\x83\xc6\x72\xf0\xe1\xea\x70\x38\xd5\xc3\x27\xcb\xf9\x4c\x75\xf8\x04\xf3\xcf\x6d\x5d\xeb\x8e\xb9\x59\x18\x93\x6f\x14\xc6\x84\xf9\x19\x34\x86\xe3\xfe\xad\x92\x99\x90\xb9\xa7\xf3\xf9\xe9\x98\xce\xd3\xc1\x31\xe1\x71\x0c\x3e\xaf\x9e\x1b\x23\xa5\xfb\x37\x33\x66\x9c\xd0\x72\x39\xcc\x65\xa5\xe8\x8a\xcc\xaa\x17\xe2\xb1\x30\x2b\x7e\x50\x8b\x0c\xb1\xa6\xd3\x09\x9d\xbe\x49\x98\xbe\xae\x7c\x27\x62\x2b\xfe\x0d\x64\xf6\xc9\xe7\x4a\xeb\xce\x69\x0e\xe3\xab\x8f\x79\xc5\x70\x21\x0c\xba\x62\x02\xcb\x5d\x91\x6f\xc2\x2e\x3e\xe4\xbf\x40\x85\x2b\x2a\x0b\xd6\xd1\xed\x15\xb3\x84\xeb\x2f\x7e\xbf\xf8\x6e\xea\xe2\xa3\x56\x94\x5d\x93\x2d\x4a\x83\x1f\x75\x45\x47\xc6\x95\x03\x91\x6d\x2f\x84\xc6\x97\x90\x15\xaf\x75\x59\x72\xc9\xe3\x7e\xf3\xc0\xef\x02\xd9\x24\x5c\xf2\x94\x57\xe0\x21\xd6\x25\x34\xfa\x97\x64\x43\x09\x56\x21\x7c\x11\x7b\x51\xb8\x2e\xa9\xc2\x81\x2a\xd7\x2a\x40\xcd\x45\xee\xbc\xa4\xce\x1e\x2e\xb6\xe4\xad\xf2\x25\xbe\x11\xee\x98\xc0\x85\xbd\xfd\x49\xc8\x25\xf9\x40\x63\x20\xe4\x52\x30\xdd\xa5\x1b\xb4\xf5\xc5\xa3\xa4\xeb\x7e\x27\x5e\x0c\x5d\x8a\x8e\xf7\x1b\x06\xe7\xd2\x1d\xd8\xbc\x14\x7e\x31\xef\xef\xa4\x87\x8b\x5e\xde\xa5\x19\x3f\xec\x40\x6b\x84\xd0\xf3\xc5\xd6\xa5\xf7\x7f\x90\x93\x4b\x2d\xdf\xef\x1a\x2e\x05\x61\x2f\x75\x20\x59\x7d\xcc\x3d\x5c\xda\x89\xca\x77\x67\xb0\xbe\x5c\xcd\x4b\x47\xe4\x09\xe0\xa5\x93\xdd\xaf\xf8\x02\x24\x6e\x14\x76\xfe\xd2\xcb\xc2\x65\x99\xf7\xa7\x97\x65\xba\xb3\x97\x65\x62\xc0\x1c\xcd\xe9\xd3\x5d\x08\xa7\x2f\x20\x93\xd6\xeb\x9a\x7c\x98\xf9\xc9\x0b\xec\x4f\xf8\xc7\x9f\x94\xa0\x4f\xe8\xd5\x4f\xde\x48\x7e\x42\x71\x7d\x42\x6b\x7c\x42\x6b\x7c\xda\x39\x3d\xbc\xe2\x01\x02\xbf\x78\xd4\xfa\x8a\x0d\x22\xf9\xe2\x1b\x85\x97\x55\x00\xe8\xfe\xd7\x2c\x00\xb0\xb5\xff\x1f\x00\x00\xff\xff\x11\x91\x1a\xde\x5b\x35\x00\x00") + +func keysWordlistSpanishTxtBytes() ([]byte, error) { + return bindataRead( + _keysWordlistSpanishTxt, + "keys/wordlist/spanish.txt", + ) +} + +func keysWordlistSpanishTxt() (*asset, error) { + bytes, err := keysWordlistSpanishTxtBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "keys/wordlist/spanish.txt", size: 13659, mode: os.FileMode(420), modTime: time.Unix(1497960590, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +// Asset loads and returns the asset for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func Asset(name string) ([]byte, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) + } + return a.bytes, nil + } + return nil, fmt.Errorf("Asset %s not found", name) +} + +// MustAsset is like Asset but panics when Asset would return an error. +// It simplifies safe initialization of global variables. +func MustAsset(name string) []byte { + a, err := Asset(name) + if err != nil { + panic("asset: Asset(" + name + "): " + err.Error()) + } + + return a +} + +// AssetInfo loads and returns the asset info for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func AssetInfo(name string) (os.FileInfo, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) + } + return a.info, nil + } + return nil, fmt.Errorf("AssetInfo %s not found", name) +} + +// AssetNames returns the names of the assets. +func AssetNames() []string { + names := make([]string, 0, len(_bindata)) + for name := range _bindata { + names = append(names, name) + } + return names +} + +// _bindata is a table, holding each asset generator, mapped to its name. +var _bindata = map[string]func() (*asset, error){ + "keys/wordlist/chinese_simplified.txt": keysWordlistChinese_simplifiedTxt, + "keys/wordlist/english.txt": keysWordlistEnglishTxt, + "keys/wordlist/japanese.txt": keysWordlistJapaneseTxt, + "keys/wordlist/spanish.txt": keysWordlistSpanishTxt, +} + +// AssetDir returns the file names below a certain +// directory embedded in the file by go-bindata. +// For example if you run go-bindata on data/... and data contains the +// following hierarchy: +// data/ +// foo.txt +// img/ +// a.png +// b.png +// then AssetDir("data") would return []string{"foo.txt", "img"} +// AssetDir("data/img") would return []string{"a.png", "b.png"} +// AssetDir("foo.txt") and AssetDir("notexist") would return an error +// AssetDir("") will return []string{"data"}. +func AssetDir(name string) ([]string, error) { + node := _bintree + if len(name) != 0 { + cannonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(cannonicalName, "/") + for _, p := range pathList { + node = node.Children[p] + if node == nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + } + } + if node.Func != nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + rv := make([]string, 0, len(node.Children)) + for childName := range node.Children { + rv = append(rv, childName) + } + return rv, nil +} + +type bintree struct { + Func func() (*asset, error) + Children map[string]*bintree +} +var _bintree = &bintree{nil, map[string]*bintree{ + "keys": &bintree{nil, map[string]*bintree{ + "wordlist": &bintree{nil, map[string]*bintree{ + "chinese_simplified.txt": &bintree{keysWordlistChinese_simplifiedTxt, map[string]*bintree{}}, + "english.txt": &bintree{keysWordlistEnglishTxt, map[string]*bintree{}}, + "japanese.txt": &bintree{keysWordlistJapaneseTxt, map[string]*bintree{}}, + "spanish.txt": &bintree{keysWordlistSpanishTxt, map[string]*bintree{}}, + }}, + }}, +}} + +// RestoreAsset restores an asset under the given directory +func RestoreAsset(dir, name string) error { + data, err := Asset(name) + if err != nil { + return err + } + info, err := AssetInfo(name) + if err != nil { + return err + } + err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) + if err != nil { + return err + } + err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + if err != nil { + return err + } + err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) + if err != nil { + return err + } + return nil +} + +// RestoreAssets restores an asset under the given directory recursively +func RestoreAssets(dir, name string) error { + children, err := AssetDir(name) + // File + if err != nil { + return RestoreAsset(dir, name) + } + // Dir + for _, child := range children { + err = RestoreAssets(dir, filepath.Join(name, child)) + if err != nil { + return err + } + } + return nil +} + +func _filePath(dir, name string) string { + cannonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) +} + From 15609e12195e4c0e12a7787f543a7a06d32f637d Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 18:15:49 +0200 Subject: [PATCH 097/287] Updated Manager interface to return seed on create, fix server tests --- keys/cryptostore/holder.go | 12 +++++++++--- keys/server/keys.go | 5 +++-- keys/server/keys_test.go | 18 ++++++++++-------- keys/server/types/keys.go | 7 +++++++ keys/transactions.go | 5 ++++- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/keys/cryptostore/holder.go b/keys/cryptostore/holder.go index 42d4662de..0b139a14e 100644 --- a/keys/cryptostore/holder.go +++ b/keys/cryptostore/holder.go @@ -32,14 +32,20 @@ func (s Manager) assertKeyManager() keys.Manager { // // algo must be a supported go-crypto algorithm: // -func (s Manager) Create(name, passphrase, algo string) (keys.Info, error) { +func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error) { gen, err := getGenerator(algo) if err != nil { - return keys.Info{}, err + return keys.Info{}, "", err } key := gen.Generate() err = s.es.Put(name, passphrase, key) - return info(name, key), err + // TODO + return info(name, key), "", err +} + +func (s Manager) Recover(name, passphrase, seedphrase string) (keys.Info, error) { + // TODO + return keys.Info{}, nil } // List loads the keys from the storage and enforces alphabetical order diff --git a/keys/server/keys.go b/keys/server/keys.go index 90d6da2b0..80852802e 100644 --- a/keys/server/keys.go +++ b/keys/server/keys.go @@ -31,13 +31,14 @@ func (k Keys) GenerateKey(w http.ResponseWriter, r *http.Request) { return } - key, err := k.manager.Create(req.Name, req.Passphrase, req.Algo) + key, seed, err := k.manager.Create(req.Name, req.Passphrase, req.Algo) if err != nil { writeError(w, err) return } - writeSuccess(w, &key) + res := types.CreateKeyResponse{key, seed} + writeSuccess(w, &res) } func (k Keys) GetKey(w http.ResponseWriter, r *http.Request) { diff --git a/keys/server/keys_test.go b/keys/server/keys_test.go index 4908559b0..a0bca8bd3 100644 --- a/keys/server/keys_test.go +++ b/keys/server/keys_test.go @@ -40,13 +40,15 @@ func TestKeyServer(t *testing.T) { key, code, err := createKey(r, n1, p1, algo) require.Nil(err, "%+v", err) require.Equal(http.StatusOK, code) - require.Equal(key.Name, n1) + require.Equal(n1, key.Key.Name) + require.NotEmpty(n1, key.Seed) // the other one works key2, code, err := createKey(r, n2, p2, algo) require.Nil(err, "%+v", err) require.Equal(http.StatusOK, code) - require.Equal(key2.Name, n2) + require.Equal(key2.Key.Name, n2) + require.NotEmpty(n2, key.Seed) // let's abstract this out a bit.... keys, code, err = listKeys(r) @@ -62,9 +64,9 @@ func TestKeyServer(t *testing.T) { k, code, err := getKey(r, n1) require.Nil(err, "%+v", err) require.Equal(http.StatusOK, code) - assert.Equal(k.Name, n1) + assert.Equal(n1, k.Name) assert.NotNil(k.Address) - assert.Equal(k.Address, key.Address) + assert.Equal(key.Key.Address, k.Address) // delete with proper key _, code, err = deleteKey(r, n1, p1) @@ -134,7 +136,7 @@ func getKey(h http.Handler, name string) (*keys.Info, int, error) { return &data, rr.Code, err } -func createKey(h http.Handler, name, passphrase, algo string) (*keys.Info, int, error) { +func createKey(h http.Handler, name, passphrase, algo string) (*types.CreateKeyResponse, int, error) { rr := httptest.NewRecorder() post := types.CreateKeyRequest{ Name: name, @@ -157,9 +159,9 @@ func createKey(h http.Handler, name, passphrase, algo string) (*keys.Info, int, return nil, rr.Code, nil } - data := keys.Info{} - err = json.Unmarshal(rr.Body.Bytes(), &data) - return &data, rr.Code, err + data := new(types.CreateKeyResponse) + err = json.Unmarshal(rr.Body.Bytes(), data) + return data, rr.Code, err } func deleteKey(h http.Handler, name, passphrase string) (*types.ErrorResponse, int, error) { diff --git a/keys/server/types/keys.go b/keys/server/types/keys.go index ffdc542f1..56ed60ceb 100644 --- a/keys/server/types/keys.go +++ b/keys/server/types/keys.go @@ -1,5 +1,7 @@ package types +import "github.com/tendermint/go-crypto/keys" + // CreateKeyRequest is sent to create a new key type CreateKeyRequest struct { Name string `json:"name" validate:"required,min=4,printascii"` @@ -26,3 +28,8 @@ type ErrorResponse struct { Error string `json:"error"` // error message if Success is false Code int `json:"code"` // error code if Success is false } + +type CreateKeyResponse struct { + Key keys.Info `json:"key"` + Seed string `json:"seed_phrase"` +} diff --git a/keys/transactions.go b/keys/transactions.go index 13d37feb5..10da7a6fa 100644 --- a/keys/transactions.go +++ b/keys/transactions.go @@ -63,7 +63,10 @@ type Signer interface { // Manager allows simple CRUD on a keystore, as an aid to signing type Manager interface { Signer - Create(name, passphrase, algo string) (Info, error) + // Create also returns a seed phrase for cold-storage + Create(name, passphrase, algo string) (Info, string, error) + // Recover takes a seedphrase and loads in the private key + Recover(name, passphrase, seedphrase string) (Info, error) List() (Infos, error) Get(name string) (Info, error) Update(name, oldpass, newpass string) error From 7108dedc21ac17a7ca8f84c1a9b8ae76dffda24b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 18:17:50 +0200 Subject: [PATCH 098/287] Fix broken key manager tests --- keys/cryptostore/holder_test.go | 6 +++--- keys/tx/multi_test.go | 4 ++-- keys/tx/one_test.go | 4 ++-- keys/tx/reader_test.go | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index 4f0383198..9ad98bb9c 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -32,10 +32,10 @@ func TestKeyManagement(t *testing.T) { // create some keys _, err = cstore.Get(n1) assert.NotNil(err) - i, err := cstore.Create(n1, p1, algo) + i, _, err := cstore.Create(n1, p1, algo) require.Equal(n1, i.Name) require.Nil(err) - _, err = cstore.Create(n2, p2, algo) + _, _, err = cstore.Create(n2, p2, algo) require.Nil(err) // we can get these keys @@ -161,7 +161,7 @@ func TestAdvancedKeyManagement(t *testing.T) { p1, p2, p3, pt := "1234", "foobar", "ding booms!", "really-secure!@#$" // make sure key works with initial password - _, err := cstore.Create(n1, p1, algo) + _, _, err := cstore.Create(n1, p1, algo) require.Nil(err, "%+v", err) assertPassword(assert, cstore, n1, p1, p2) diff --git a/keys/tx/multi_test.go b/keys/tx/multi_test.go index 97463a5f7..e9477c8cd 100644 --- a/keys/tx/multi_test.go +++ b/keys/tx/multi_test.go @@ -22,9 +22,9 @@ func TestMultiSig(t *testing.T) { n, p := "foo", "bar" n2, p2 := "other", "thing" - acct, err := cstore.Create(n, p, algo) + acct, _, err := cstore.Create(n, p, algo) require.Nil(err, "%+v", err) - acct2, err := cstore.Create(n2, p2, algo) + acct2, _, err := cstore.Create(n2, p2, algo) require.Nil(err, "%+v", err) type signer struct { diff --git a/keys/tx/one_test.go b/keys/tx/one_test.go index 05af347b4..0480f5a33 100644 --- a/keys/tx/one_test.go +++ b/keys/tx/one_test.go @@ -22,9 +22,9 @@ func TestOneSig(t *testing.T) { n, p := "foo", "bar" n2, p2 := "other", "thing" - acct, err := cstore.Create(n, p, algo) + acct, _, err := cstore.Create(n, p, algo) require.Nil(err, "%+v", err) - acct2, err := cstore.Create(n2, p2, algo) + acct2, _, err := cstore.Create(n2, p2, algo) require.Nil(err, "%+v", err) cases := []struct { diff --git a/keys/tx/reader_test.go b/keys/tx/reader_test.go index c50481f14..7c622bff9 100644 --- a/keys/tx/reader_test.go +++ b/keys/tx/reader_test.go @@ -6,9 +6,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" crypto "github.com/tendermint/go-crypto" - data "github.com/tendermint/go-wire/data" "github.com/tendermint/go-crypto/keys/cryptostore" "github.com/tendermint/go-crypto/keys/storage/memstorage" + data "github.com/tendermint/go-wire/data" ) func TestReader(t *testing.T) { @@ -23,9 +23,9 @@ func TestReader(t *testing.T) { u := sigs{"alice", "1234"} u2 := sigs{"bob", "foobar"} - _, err := cstore.Create(u.name, u.pass, algo) + _, _, err := cstore.Create(u.name, u.pass, algo) require.Nil(err, "%+v", err) - _, err = cstore.Create(u2.name, u2.pass, algo) + _, _, err = cstore.Create(u2.name, u2.pass, algo) require.Nil(err, "%+v", err) cases := []struct { From 53e19e3dfaac5a9242204175e7a2d66c81574e8b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 18:35:16 +0200 Subject: [PATCH 099/287] Add codec to keys.Manager, recovery test passes --- keys/cryptostore/holder.go | 37 ++++++++++++++++++++++++++------ keys/cryptostore/holder_test.go | 38 +++++++++++++++++++++++++++++++++ keys/server/keys_test.go | 1 + keys/tx/multi_test.go | 1 + keys/tx/one_test.go | 1 + keys/tx/reader_test.go | 2 ++ keys/wordcodec.go | 10 +++++++++ 7 files changed, 83 insertions(+), 7 deletions(-) diff --git a/keys/cryptostore/holder.go b/keys/cryptostore/holder.go index 0b139a14e..6709687d6 100644 --- a/keys/cryptostore/holder.go +++ b/keys/cryptostore/holder.go @@ -1,19 +1,26 @@ package cryptostore -import keys "github.com/tendermint/go-crypto/keys" +import ( + "strings" + + crypto "github.com/tendermint/go-crypto" + keys "github.com/tendermint/go-crypto/keys" +) // Manager combines encyption and storage implementation to provide // a full-featured key manager type Manager struct { - es encryptedStorage + es encryptedStorage + codec keys.Codec } -func New(coder Encoder, store keys.Storage) Manager { +func New(coder Encoder, store keys.Storage, codec keys.Codec) Manager { return Manager{ es: encryptedStorage{ coder: coder, store: store, }, + codec: codec, } } @@ -39,13 +46,29 @@ func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error } key := gen.Generate() err = s.es.Put(name, passphrase, key) - // TODO - return info(name, key), "", err + if err != nil { + return keys.Info{}, "", err + } + seed, err := s.codec.BytesToWords(key.Bytes()) + phrase := strings.Join(seed, " ") + return info(name, key), phrase, err } func (s Manager) Recover(name, passphrase, seedphrase string) (keys.Info, error) { - // TODO - return keys.Info{}, nil + words := strings.Split(strings.TrimSpace(seedphrase), " ") + data, err := s.codec.WordsToBytes(words) + if err != nil { + return keys.Info{}, err + } + + key, err := crypto.PrivKeyFromBytes(data) + if err != nil { + return keys.Info{}, err + } + + // d00d, it worked! create the bugger.... + err = s.es.Put(name, passphrase, key) + return info(name, key), err } // List loads the keys from the storage and enforces alphabetical order diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index 9ad98bb9c..c17eef24b 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" crypto "github.com/tendermint/go-crypto" + "github.com/tendermint/go-crypto/keys" "github.com/tendermint/go-crypto/keys/cryptostore" "github.com/tendermint/go-crypto/keys/storage/memstorage" ) @@ -18,6 +19,7 @@ func TestKeyManagement(t *testing.T) { cstore := cryptostore.New( cryptostore.SecretBox, memstorage.New(), + keys.MustLoadCodec("english"), ) algo := crypto.NameEd25519 @@ -154,6 +156,7 @@ func TestAdvancedKeyManagement(t *testing.T) { cstore := cryptostore.New( cryptostore.SecretBox, memstorage.New(), + keys.MustLoadCodec("english"), ) algo := crypto.NameSecp256k1 @@ -199,6 +202,41 @@ func TestAdvancedKeyManagement(t *testing.T) { assertPassword(assert, cstore, n2, p3, pt) } +// TestSeedPhrase verifies restoring from a seed phrase +func TestSeedPhrase(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + // make the storage with reasonable defaults + cstore := cryptostore.New( + cryptostore.SecretBox, + memstorage.New(), + keys.MustLoadCodec("english"), + ) + + algo := crypto.NameEd25519 + n1, n2 := "lost-key", "found-again" + p1, p2 := "1234", "foobar" + + // make sure key works with initial password + info, seed, err := cstore.Create(n1, p1, algo) + require.Nil(err, "%+v", err) + assert.Equal(n1, info.Name) + assert.NotEmpty(seed) + + // now, let us delete this key + err = cstore.Delete(n1, p1) + require.Nil(err, "%+v", err) + _, err = cstore.Get(n1) + require.NotNil(err) + + // let us re-create it from the seed-phrase + newInfo, err := cstore.Recover(n2, p2, seed) + require.Nil(err, "%+v", err) + assert.Equal(n2, newInfo.Name) + assert.Equal(info.Address, newInfo.Address) + assert.Equal(info.PubKey, newInfo.PubKey) +} + // func ExampleStore() { // // Select the encryption and storage for your cryptostore // cstore := cryptostore.New( diff --git a/keys/server/keys_test.go b/keys/server/keys_test.go index a0bca8bd3..2aa17753c 100644 --- a/keys/server/keys_test.go +++ b/keys/server/keys_test.go @@ -91,6 +91,7 @@ func setupServer() http.Handler { cstore := cryptostore.New( cryptostore.SecretBox, memstorage.New(), + keys.MustLoadCodec("english"), ) // build your http server diff --git a/keys/tx/multi_test.go b/keys/tx/multi_test.go index e9477c8cd..22fb0ed75 100644 --- a/keys/tx/multi_test.go +++ b/keys/tx/multi_test.go @@ -18,6 +18,7 @@ func TestMultiSig(t *testing.T) { cstore := cryptostore.New( cryptostore.SecretBox, memstorage.New(), + keys.MustLoadCodec("english"), ) n, p := "foo", "bar" n2, p2 := "other", "thing" diff --git a/keys/tx/one_test.go b/keys/tx/one_test.go index 0480f5a33..e0a3f1056 100644 --- a/keys/tx/one_test.go +++ b/keys/tx/one_test.go @@ -18,6 +18,7 @@ func TestOneSig(t *testing.T) { cstore := cryptostore.New( cryptostore.SecretBox, memstorage.New(), + keys.MustLoadCodec("english"), ) n, p := "foo", "bar" n2, p2 := "other", "thing" diff --git a/keys/tx/reader_test.go b/keys/tx/reader_test.go index 7c622bff9..f0561301f 100644 --- a/keys/tx/reader_test.go +++ b/keys/tx/reader_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" crypto "github.com/tendermint/go-crypto" + "github.com/tendermint/go-crypto/keys" "github.com/tendermint/go-crypto/keys/cryptostore" "github.com/tendermint/go-crypto/keys/storage/memstorage" data "github.com/tendermint/go-wire/data" @@ -18,6 +19,7 @@ func TestReader(t *testing.T) { cstore := cryptostore.New( cryptostore.SecretBox, memstorage.New(), + keys.MustLoadCodec("english"), ) type sigs struct{ name, pass string } u := sigs{"alice", "1234"} diff --git a/keys/wordcodec.go b/keys/wordcodec.go index f66d1e983..ee1374644 100644 --- a/keys/wordcodec.go +++ b/keys/wordcodec.go @@ -40,6 +40,7 @@ func NewCodec(words []string) (codec *WordCodec, err error) { return res, nil } +// LoadCodec loads a pre-compiled language file func LoadCodec(bank string) (codec *WordCodec, err error) { words, err := loadBank(bank) if err != nil { @@ -48,6 +49,15 @@ func LoadCodec(bank string) (codec *WordCodec, err error) { return NewCodec(words) } +// MustLoadCodec panics if word bank is missing, only for tests +func MustLoadCodec(bank string) *WordCodec { + codec, err := LoadCodec(bank) + if err != nil { + panic(err) + } + return codec +} + // loadBank opens a wordlist file and returns all words inside func loadBank(bank string) ([]string, error) { filename := "keys/wordlist/" + bank + ".txt" From 7d08ea4c09a020e5721943eb7454d431ba08c4b2 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 18:50:53 +0200 Subject: [PATCH 100/287] Fixed all tests and binaries to compile --- cmd/new.go | 2 +- cmd/root.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cmd/new.go b/cmd/new.go index 033410e6a..0dd481e01 100644 --- a/cmd/new.go +++ b/cmd/new.go @@ -48,7 +48,7 @@ func newPassword(cmd *cobra.Command, args []string) error { return err } - info, err := GetKeyManager().Create(name, pass, algo) + info, _, err := GetKeyManager().Create(name, pass, algo) if err == nil { printInfo(info) } diff --git a/cmd/root.go b/cmd/root.go index 33153d850..cd1913273 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -48,10 +48,15 @@ func GetKeyManager() keys.Manager { // store the keys directory rootDir := viper.GetString(cli.HomeFlag) keyDir := filepath.Join(rootDir, KeySubdir) + + // TODO: smarter loading??? with language and fallback? + codec := keys.MustLoadCodec("english") + // and construct the key manager manager = cryptostore.New( cryptostore.SecretBox, filestorage.New(keyDir), + codec, ) } return manager From e9537b2da6554795d52eac68c5085f73ab6721cf Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 19:50:39 +0200 Subject: [PATCH 101/287] Freshen up existing cmd files --- cmd/get.go | 26 ++++++++++++-------------- cmd/keys/main.go | 3 +++ cmd/list.go | 16 +++++++--------- cmd/new.go | 13 ++++++++----- cmd/root.go | 33 +++++++++------------------------ cmd/serve.go | 22 +++++++++++++--------- cmd/update.go | 9 ++------- cmd/utils.go | 29 ++++++++++++++++++++++++++--- 8 files changed, 80 insertions(+), 71 deletions(-) diff --git a/cmd/get.go b/cmd/get.go index 6e8c620d0..9d30f49b8 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -25,20 +25,18 @@ var getCmd = &cobra.Command{ Use: "get ", Short: "Get details of one key", Long: `Return public details of one local key.`, - RunE: func(cmd *cobra.Command, args []string) error { - if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide a name for the key") - } - name := args[0] - - info, err := GetKeyManager().Get(name) - if err == nil { - printInfo(info) - } - return err - }, + RunE: runGetCmd, } -func init() { - RootCmd.AddCommand(getCmd) +func runGetCmd(cmd *cobra.Command, args []string) error { + if len(args) != 1 || len(args[0]) == 0 { + return errors.New("You must provide a name for the key") + } + name := args[0] + + info, err := GetKeyManager().Get(name) + if err == nil { + printInfo(info) + } + return err } diff --git a/cmd/keys/main.go b/cmd/keys/main.go index 82b355346..8780f7bbc 100644 --- a/cmd/keys/main.go +++ b/cmd/keys/main.go @@ -22,6 +22,9 @@ import ( ) func main() { + // for demos, we enable the key server, probably don't want this + // in most binaries we embed the key management into + cmd.RegisterServer() root := cli.PrepareMainCmd(cmd.RootCmd, "TM", os.ExpandEnv("$HOME/.tlc")) root.Execute() } diff --git a/cmd/list.go b/cmd/list.go index b0419a1e4..51eeeda12 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -22,15 +22,13 @@ var listCmd = &cobra.Command{ Short: "List all keys", Long: `Return a list of all public keys stored by this key manager along with their associated name and address.`, - RunE: func(cmd *cobra.Command, args []string) error { - infos, err := GetKeyManager().List() - if err == nil { - printInfos(infos) - } - return err - }, + RunE: runListCmd, } -func init() { - RootCmd.AddCommand(listCmd) +func runListCmd(cmd *cobra.Command, args []string) error { + infos, err := GetKeyManager().List() + if err == nil { + printInfos(infos) + } + return err } diff --git a/cmd/new.go b/cmd/new.go index 0dd481e01..b48f9727a 100644 --- a/cmd/new.go +++ b/cmd/new.go @@ -21,6 +21,10 @@ import ( "github.com/spf13/viper" ) +const ( + flagType = "type" +) + // newCmd represents the new command var newCmd = &cobra.Command{ Use: "new ", @@ -28,20 +32,19 @@ var newCmd = &cobra.Command{ Long: `Add a public/private key pair to the key store. The password muts be entered in the terminal and not passed as a command line argument for security.`, - RunE: newPassword, + RunE: runNewCmd, } func init() { - RootCmd.AddCommand(newCmd) - newCmd.Flags().StringP("type", "t", "ed25519", "Type of key (ed25519|secp256k1)") + newCmd.Flags().StringP(flagType, "t", "ed25519", "Type of key (ed25519|secp256k1)") } -func newPassword(cmd *cobra.Command, args []string) error { +func runNewCmd(cmd *cobra.Command, args []string) error { if len(args) != 1 || len(args[0]) == 0 { return errors.New("You must provide a name for the key") } name := args[0] - algo := viper.GetString("type") + algo := viper.GetString(flagType) pass, err := getCheckPassword("Enter a passphrase:", "Repeat the passphrase:") if err != nil { diff --git a/cmd/root.go b/cmd/root.go index cd1913273..ad5a633fb 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -15,14 +15,8 @@ package cmd import ( - "path/filepath" - "github.com/spf13/cobra" - "github.com/spf13/viper" keys "github.com/tendermint/go-crypto/keys" - "github.com/tendermint/go-crypto/keys/cryptostore" - "github.com/tendermint/go-crypto/keys/storage/filestorage" - "github.com/tendermint/tmlibs/cli" ) const KeySubdir = "keys" @@ -42,22 +36,13 @@ used by light-clients, full nodes, or any other application that needs to sign with a private key.`, } -// GetKeyManager initializes a key manager based on the configuration -func GetKeyManager() keys.Manager { - if manager == nil { - // store the keys directory - rootDir := viper.GetString(cli.HomeFlag) - keyDir := filepath.Join(rootDir, KeySubdir) - - // TODO: smarter loading??? with language and fallback? - codec := keys.MustLoadCodec("english") - - // and construct the key manager - manager = cryptostore.New( - cryptostore.SecretBox, - filestorage.New(keyDir), - codec, - ) - } - return manager +func init() { + RootCmd.AddCommand(getCmd) + RootCmd.AddCommand(listCmd) + RootCmd.AddCommand(newCmd) + RootCmd.AddCommand(updateCmd) +} + +func RegisterServer() { + RootCmd.AddCommand(serveCmd) } diff --git a/cmd/serve.go b/cmd/serve.go index 5ea96db3f..8cf7d12d4 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -28,6 +28,11 @@ import ( "github.com/tendermint/go-crypto/keys/server" ) +const ( + flagPort = "port" + flagSocket = "socket" +) + // serveCmd represents the serve command var serveCmd = &cobra.Command{ Use: "serve", @@ -36,27 +41,26 @@ var serveCmd = &cobra.Command{ private keys much more in depth than the cli can perform. In particular, this will allow you to sign transactions with the private keys in the store.`, - RunE: serveHTTP, + RunE: runServeCmd, } func init() { - RootCmd.AddCommand(serveCmd) - serveCmd.Flags().IntP("port", "p", 8118, "TCP Port for listen for http server") - serveCmd.Flags().StringP("socket", "s", "", "UNIX socket for more secure http server") - serveCmd.Flags().StringP("type", "t", "ed25519", "Default key type (ed25519|secp256k1)") + serveCmd.Flags().IntP(flagPort, "p", 8118, "TCP Port for listen for http server") + serveCmd.Flags().StringP(flagSocket, "s", "", "UNIX socket for more secure http server") + serveCmd.Flags().StringP(flagType, "t", "ed25519", "Default key type (ed25519|secp256k1)") } -func serveHTTP(cmd *cobra.Command, args []string) error { +func runServeCmd(cmd *cobra.Command, args []string) error { var l net.Listener var err error - socket := viper.GetString("socket") + socket := viper.GetString(flagSocket) if socket != "" { l, err = createSocket(socket) if err != nil { return errors.Wrap(err, "Cannot create socket") } } else { - port := viper.GetInt("port") + port := viper.GetInt(flagPort) l, err = net.Listen("tcp", fmt.Sprintf(":%d", port)) if err != nil { return errors.Errorf("Cannot listen on port %d", port) @@ -64,7 +68,7 @@ func serveHTTP(cmd *cobra.Command, args []string) error { } router := mux.NewRouter() - ks := server.New(GetKeyManager(), viper.GetString("type")) + ks := server.New(GetKeyManager(), viper.GetString(flagType)) ks.Register(router) // only set cors for tcp listener diff --git a/cmd/update.go b/cmd/update.go index c046af126..ec2bd2083 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -26,15 +26,10 @@ import ( var updateCmd = &cobra.Command{ Use: "update ", Short: "Change the password for a private key", - Long: `Change the password for a private key.`, - RunE: updatePassword, + RunE: runUpdateCmd, } -func init() { - RootCmd.AddCommand(updateCmd) -} - -func updatePassword(cmd *cobra.Command, args []string) error { +func runUpdateCmd(cmd *cobra.Command, args []string) error { if len(args) != 1 || len(args[0]) == 0 { return errors.New("You must provide a name for the key") } diff --git a/cmd/utils.go b/cmd/utils.go index d082bbbc9..e54343b7a 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -4,6 +4,7 @@ import ( "bufio" "fmt" "os" + "path/filepath" "strings" "github.com/bgentry/speakeasy" @@ -15,9 +16,31 @@ import ( "github.com/tendermint/tmlibs/cli" keys "github.com/tendermint/go-crypto/keys" + "github.com/tendermint/go-crypto/keys/cryptostore" + "github.com/tendermint/go-crypto/keys/storage/filestorage" ) -const PassLength = 10 +const MinPassLength = 10 + +// GetKeyManager initializes a key manager based on the configuration +func GetKeyManager() keys.Manager { + if manager == nil { + // store the keys directory + rootDir := viper.GetString(cli.HomeFlag) + keyDir := filepath.Join(rootDir, KeySubdir) + + // TODO: smarter loading??? with language and fallback? + codec := keys.MustLoadCodec("english") + + // and construct the key manager + manager = cryptostore.New( + cryptostore.SecretBox, + filestorage.New(keyDir), + codec, + ) + } + return manager +} // if we read from non-tty, we just need to init the buffer reader once, // in case we try to read multiple passwords (eg. update) @@ -47,8 +70,8 @@ func getPassword(prompt string) (pass string, err error) { if err != nil { return "", err } - if len(pass) < PassLength { - return "", errors.Errorf("Password must be at least %d characters", PassLength) + if len(pass) < MinPassLength { + return "", errors.Errorf("Password must be at least %d characters", MinPassLength) } return pass, nil } From 1ab9ab9494343c15979801129fa21654a8cd061b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 20:34:13 +0200 Subject: [PATCH 102/287] Add delete and recover commands, and test them --- cmd/delete.go | 49 ++++++++++++++++++++++++++++++++++++++++++++++ cmd/new.go | 41 +++++++++++++++++++++++++++++++++++--- cmd/recover.go | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ cmd/root.go | 2 ++ cmd/utils.go | 6 ++++++ tests/keys.sh | 51 ++++++++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 197 insertions(+), 5 deletions(-) create mode 100644 cmd/delete.go create mode 100644 cmd/recover.go diff --git a/cmd/delete.go b/cmd/delete.go new file mode 100644 index 000000000..6c0185166 --- /dev/null +++ b/cmd/delete.go @@ -0,0 +1,49 @@ +// Copyright © 2017 Ethan Frey +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "fmt" + + "github.com/pkg/errors" + + "github.com/spf13/cobra" +) + +// deleteCmd represents the delete command +var deleteCmd = &cobra.Command{ + Use: "delete ", + Short: "DANGER: Delete a private key from your system", + RunE: runDeleteCmd, +} + +func runDeleteCmd(cmd *cobra.Command, args []string) error { + if len(args) != 1 || len(args[0]) == 0 { + return errors.New("You must provide a name for the key") + } + name := args[0] + + oldpass, err := getPassword("DANGER - enter password to permanently delete key:") + if err != nil { + return err + } + + err = GetKeyManager().Delete(name, oldpass) + if err != nil { + return err + } + fmt.Println("Password deleted forever (uh oh!)") + return nil +} diff --git a/cmd/new.go b/cmd/new.go index b48f9727a..2969a1042 100644 --- a/cmd/new.go +++ b/cmd/new.go @@ -15,14 +15,20 @@ package cmd import ( + "fmt" + "github.com/pkg/errors" + "github.com/tendermint/go-crypto/keys" + "github.com/tendermint/go-wire/data" + "github.com/tendermint/tmlibs/cli" "github.com/spf13/cobra" "github.com/spf13/viper" ) const ( - flagType = "type" + flagType = "type" + flagNoBackup = "no-backup" ) // newCmd represents the new command @@ -37,6 +43,7 @@ passed as a command line argument for security.`, func init() { newCmd.Flags().StringP(flagType, "t", "ed25519", "Type of key (ed25519|secp256k1)") + newCmd.Flags().Bool(flagNoBackup, false, "Don't print out seed phrase (if others are watching the terminal)") } func runNewCmd(cmd *cobra.Command, args []string) error { @@ -51,9 +58,37 @@ func runNewCmd(cmd *cobra.Command, args []string) error { return err } - info, _, err := GetKeyManager().Create(name, pass, algo) + info, seed, err := GetKeyManager().Create(name, pass, algo) if err == nil { - printInfo(info) + printCreate(info, seed) } return err } + +type NewOutput struct { + Key keys.Info `json:"key"` + Seed string `json:"seed"` +} + +func printCreate(info keys.Info, seed string) { + switch viper.Get(cli.OutputFlag) { + case "text": + printInfo(info) + // print seed unless requested not to. + if !viper.GetBool(flagNoBackup) { + fmt.Println("**Important** write this seed phrase in a safe place.") + fmt.Println("It is the only way to recover your account if you ever forget your password.\n") + fmt.Println(seed) + } + case "json": + out := NewOutput{Key: info} + if !viper.GetBool(flagNoBackup) { + out.Seed = seed + } + json, err := data.ToJSON(out) + if err != nil { + panic(err) // really shouldn't happen... + } + fmt.Println(string(json)) + } +} diff --git a/cmd/recover.go b/cmd/recover.go new file mode 100644 index 000000000..e3bd919b1 --- /dev/null +++ b/cmd/recover.go @@ -0,0 +1,53 @@ +// Copyright © 2017 Ethan Frey +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "github.com/pkg/errors" + + "github.com/spf13/cobra" +) + +// recoverCmd represents the recover command +var recoverCmd = &cobra.Command{ + Use: "recover ", + Short: "Change the password for a private key", + RunE: runRecoverCmd, +} + +func runRecoverCmd(cmd *cobra.Command, args []string) error { + if len(args) != 1 || len(args[0]) == 0 { + return errors.New("You must provide a name for the key") + } + name := args[0] + + pass, err := getPassword("Enter the new passphrase:") + if err != nil { + return err + } + + // not really a password... huh? + seed, err := getSeed("Enter your recovery seed phrase") + if err != nil { + return err + } + + info, err := GetKeyManager().Recover(name, pass, seed) + if err != nil { + return err + } + printInfo(info) + return nil +} diff --git a/cmd/root.go b/cmd/root.go index ad5a633fb..cfd3d1adf 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -41,6 +41,8 @@ func init() { RootCmd.AddCommand(listCmd) RootCmd.AddCommand(newCmd) RootCmd.AddCommand(updateCmd) + RootCmd.AddCommand(deleteCmd) + RootCmd.AddCommand(recoverCmd) } func RegisterServer() { diff --git a/cmd/utils.go b/cmd/utils.go index e54343b7a..7978f78a7 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -76,6 +76,12 @@ func getPassword(prompt string) (pass string, err error) { return pass, nil } +func getSeed(prompt string) (seed string, err error) { + seed, err = stdinPassword() + seed = strings.TrimSpace(seed) + return +} + func getCheckPassword(prompt, prompt2 string) (string, error) { // simple read on no-tty if !inputIsTty() { diff --git a/tests/keys.sh b/tests/keys.sh index 82c8083ec..c848f8dd2 100755 --- a/tests/keys.sh +++ b/tests/keys.sh @@ -12,8 +12,9 @@ oneTimeSetUp() { newKey(){ assertNotNull "keyname required" "$1" KEYPASS=${2:-qwertyuiop} - KEY=$(echo $KEYPASS | ${EXE} new $1) - assertTrue "created $1" $? + KEY=$(echo $KEYPASS | ${EXE} new $1 -o json) + if ! assertTrue "created $1" $?; then return 1; fi + assertEquals "$1" $(echo $KEY | jq .key.name | tr -d \") return $? } @@ -59,6 +60,52 @@ test02updateKeys() { assertTrue "takes new key after update" "updateKey $USER $PASS2 $PASS3" } +test03recoverKeys() { + USER=sleepy + PASS1=S4H.9j.D9S7hso + + USER2=easy + PASS2=1234567890 + + # make a user and check they exist + echo "create..." + KEY=$(echo $PASS1 | ${EXE} new $USER -o json) + if ! assertTrue "created $USER" $?; then return 1; fi + if [ -n "$DEBUG" ]; then echo $KEY; echo; fi + + SEED=$(echo $KEY | jq .seed | tr -d \") + ADDR=$(echo $KEY | jq .key.address | tr -d \") + PUBKEY=$(echo $KEY | jq .key.pubkey | tr -d \") + assertTrue "${EXE} get $USER > /dev/null" + + # let's delete this key + echo "delete..." + assertFalse "echo foo | ${EXE} delete $USER > /dev/null" + assertTrue "echo $PASS1 | ${EXE} delete $USER > /dev/null" + assertFalse "${EXE} get $USER > /dev/null" + + # fails on short password + echo "recover..." + assertFalse "echo foo; echo $SEED | ${EXE} recover $USER2 -o json > /dev/null" + # fails on bad seed + assertFalse "echo $PASS2; echo \"silly white whale tower bongo\" | ${EXE} recover $USER2 -o json > /dev/null" + # now we got it + KEY2=$((echo $PASS2; echo $SEED) | ${EXE} recover $USER2 -o json) + if ! assertTrue "recovery failed: $KEY2" $?; then return 1; fi + if [ -n "$DEBUG" ]; then echo $KEY2; echo; fi + + # make sure it looks the same + NAME2=$(echo $KEY2 | jq .name | tr -d \") + ADDR2=$(echo $KEY2 | jq .address | tr -d \") + PUBKEY2=$(echo $KEY2 | jq .pubkey | tr -d \") + assertEquals "wrong username" "$USER2" "$NAME2" + assertEquals "address doesn't match" "$ADDR" "$ADDR2" + assertEquals "pubkey doesn't match" "$PUBKEY" "$PUBKEY2" + + # and we can find the info + assertTrue "${EXE} get $USER2 > /dev/null" +} + # load and run these tests with shunit2! DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #get this files directory . $DIR/shunit2 From a944bdebfc5ef4fca2f4e5ad6381d319dc4067e1 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 20:46:00 +0200 Subject: [PATCH 103/287] Make sure prompt looks good in interactive mode --- cmd/recover.go | 2 +- cmd/utils.go | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/recover.go b/cmd/recover.go index e3bd919b1..3a6953391 100644 --- a/cmd/recover.go +++ b/cmd/recover.go @@ -39,7 +39,7 @@ func runRecoverCmd(cmd *cobra.Command, args []string) error { } // not really a password... huh? - seed, err := getSeed("Enter your recovery seed phrase") + seed, err := getSeed("Enter your recovery seed phrase:") if err != nil { return err } diff --git a/cmd/utils.go b/cmd/utils.go index 7978f78a7..b1550a127 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -77,6 +77,9 @@ func getPassword(prompt string) (pass string, err error) { } func getSeed(prompt string) (seed string, err error) { + if inputIsTty() { + fmt.Println(prompt) + } seed, err = stdinPassword() seed = strings.TrimSpace(seed) return From d665c9ef103219a1990081a47ea735aada3620eb Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 21 Jun 2017 18:57:32 +0200 Subject: [PATCH 104/287] Code cleanup from review comments --- cmd/delete.go | 2 +- cmd/get.go | 2 +- cmd/new.go | 2 +- cmd/recover.go | 2 +- cmd/update.go | 2 +- keys/cryptostore/holder.go | 9 +++++++-- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/cmd/delete.go b/cmd/delete.go index 6c0185166..033cf2768 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -24,7 +24,7 @@ import ( // deleteCmd represents the delete command var deleteCmd = &cobra.Command{ - Use: "delete ", + Use: "delete [name]", Short: "DANGER: Delete a private key from your system", RunE: runDeleteCmd, } diff --git a/cmd/get.go b/cmd/get.go index 9d30f49b8..dfade2b74 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -22,7 +22,7 @@ import ( // getCmd represents the get command var getCmd = &cobra.Command{ - Use: "get ", + Use: "get [name]", Short: "Get details of one key", Long: `Return public details of one local key.`, RunE: runGetCmd, diff --git a/cmd/new.go b/cmd/new.go index 2969a1042..ce4634074 100644 --- a/cmd/new.go +++ b/cmd/new.go @@ -33,7 +33,7 @@ const ( // newCmd represents the new command var newCmd = &cobra.Command{ - Use: "new ", + Use: "new [name]", Short: "Create a new public/private key pair", Long: `Add a public/private key pair to the key store. The password muts be entered in the terminal and not diff --git a/cmd/recover.go b/cmd/recover.go index 3a6953391..f5e4f0527 100644 --- a/cmd/recover.go +++ b/cmd/recover.go @@ -22,7 +22,7 @@ import ( // recoverCmd represents the recover command var recoverCmd = &cobra.Command{ - Use: "recover ", + Use: "recover [name]", Short: "Change the password for a private key", RunE: runRecoverCmd, } diff --git a/cmd/update.go b/cmd/update.go index ec2bd2083..f31af509c 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -24,7 +24,7 @@ import ( // updateCmd represents the update command var updateCmd = &cobra.Command{ - Use: "update ", + Use: "update [name]", Short: "Change the password for a private key", RunE: runUpdateCmd, } diff --git a/keys/cryptostore/holder.go b/keys/cryptostore/holder.go index 6709687d6..0e4fde042 100644 --- a/keys/cryptostore/holder.go +++ b/keys/cryptostore/holder.go @@ -37,8 +37,7 @@ func (s Manager) assertKeyManager() keys.Manager { // Create adds a new key to the storage engine, returning error if // another key already stored under this name // -// algo must be a supported go-crypto algorithm: -// +// algo must be a supported go-crypto algorithm: ed25519, secp256k1 func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error) { gen, err := getGenerator(algo) if err != nil { @@ -54,6 +53,12 @@ func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error return info(name, key), phrase, err } +// Recover takes a seed phrase and tries to recover the private key. +// +// If the seed phrase is valid, it will create the private key and store +// it under name, protected by passphrase. +// +// Result similar to New(), except it doesn't return the seed again... func (s Manager) Recover(name, passphrase, seedphrase string) (keys.Info, error) { words := strings.Split(strings.TrimSpace(seedphrase), " ") data, err := s.codec.WordsToBytes(words) From ad70b2222698a2018c4bf18bab86f3727621f492 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 21 Jun 2017 19:35:57 +0200 Subject: [PATCH 105/287] Update to 0.2.1 --- CHANGELOG.md | 10 ++++++++++ version.go | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 510785477..346d34fd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 0.2.1 (June 21, 2017) + +- Improve keys command + - No password prompts in non-interactive mode (echo 'foobar' | keys new foo) + - Added support for seed phrases + - Seed phrase now returned on `keys new` + - Add `keys restore` to restore private key from key phrase + - Checksum to verify typos in the seed phrase (rather than just a useless key) + - Add `keys delete` to remove a key if needed + ## 0.2.0 (May 18, 2017) BREAKING CHANGES: diff --git a/version.go b/version.go index e2c9c787b..c785b1bca 100644 --- a/version.go +++ b/version.go @@ -1,3 +1,3 @@ package crypto -const Version = "0.2.0" +const Version = "0.2.1" From d31cfbaeaa4d930798ec327b52917975f3203c11 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Fri, 23 Jun 2017 09:10:59 +0200 Subject: [PATCH 106/287] Fixed up help text for "keys recover" --- cmd/recover.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cmd/recover.go b/cmd/recover.go index f5e4f0527..4896c4e05 100644 --- a/cmd/recover.go +++ b/cmd/recover.go @@ -23,8 +23,16 @@ import ( // recoverCmd represents the recover command var recoverCmd = &cobra.Command{ Use: "recover [name]", - Short: "Change the password for a private key", - RunE: runRecoverCmd, + Short: "Recover a private key from a seed phrase", + Long: `Recover a private key from a seed phrase. + +I really hope you wrote this down when you created the new key. +The seed is only displayed on creation, never again. + +You can also use this to copy a key between multiple testnets, +simply by "recovering" the key in the other nets you want to copy +to. Of course, it has no coins on the other nets, just the same address.`, + RunE: runRecoverCmd, } func runRecoverCmd(cmd *cobra.Command, args []string) error { From 65da3cf340e035254dcb3955fb069467d509301d Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sat, 22 Jul 2017 05:25:59 -0400 Subject: [PATCH 107/287] Add crc16 support --- glide.lock | 24 +++++++++--------- glide.yaml | 1 + keys/ecc.go | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ keys/ecc_test.go | 6 +++++ 4 files changed, 83 insertions(+), 11 deletions(-) diff --git a/glide.lock b/glide.lock index 71292ce11..4cd7c5670 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 3bcee9fbccf29d21217b24b6a83ec51e1514f37b2ae5d8718cf6c5df80f4fb2c -updated: 2017-06-19T17:16:58.037568333+02:00 +hash: c0a2db1b80c6b1b8aab31c526ce43e22e49b23c893c78b8fdb8546aa2e7b7cc6 +updated: 2017-07-22T05:24:42.82932575-04:00 imports: - name: github.com/bgentry/speakeasy version: 4aabc24848ce5fd31929f7d1e4ea74d3709c14cd @@ -38,11 +38,11 @@ imports: - name: github.com/gorilla/context version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42 - name: github.com/gorilla/handlers - version: 3a5767ca75ece5f7f1440b1d16975247f8d8b221 + version: a4043c62cc2329bacda331d33fc908ab11ef0ec3 - name: github.com/gorilla/mux - version: 392c28fe23e1c45ddba891b0320b3b5df220beea + version: bcd8bc72b08df0f70df986b97f95590779502d31 - name: github.com/hashicorp/hcl - version: a4b07c25de5ff55ad3b8936cea69a79a3d95a855 + version: 392dba7d905ed5d04a5794ba89f558b27e2ba1ca subpackages: - hcl/ast - hcl/parser @@ -52,6 +52,8 @@ imports: - json/parser - json/scanner - json/token +- name: github.com/howeyc/crc16 + version: 58da63c846043d0bea709c8d47039df06577d6d9 - name: github.com/inconshreveable/mousetrap version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 - name: github.com/kr/logfmt @@ -67,7 +69,7 @@ imports: - name: github.com/pelletier/go-toml version: 13d49d4606eb801b8f01ae542b4afc4c6ee3d84a - name: github.com/pkg/errors - version: ff09b135c25aae272398c51a07235b90a75aa4f0 + version: 645ef00459ed84a119197bfb8d8205042c6df63d - name: github.com/spf13/afero version: 9be650865eab0c12963d8753212f4f9c66cdcf12 subpackages: @@ -75,11 +77,11 @@ imports: - name: github.com/spf13/cast version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4 - name: github.com/spf13/cobra - version: db6b9a8b3f3f400c8ecb4a4d7d02245b8facad66 + version: 4cdb38c072b86bf795d2c81de50784d9fdd6eb77 - name: github.com/spf13/jwalterweatherman - version: fa7ca7e836cf3a8bb4ebf799f472c12d7e903d66 + version: 8f07c835e5cc1450c082fe3a439cf87b0cbb2d99 - name: github.com/spf13/pflag - version: 80fe0fb4eba54167e2ccae1c6c950e72abf61b73 + version: e57e3eeb33f795204c1ca35f56c44f83227c6e66 - name: github.com/spf13/viper version: 0967fc9aceab2ce9da34061253ac10fb99bba5b2 - name: github.com/tendermint/ed25519 @@ -93,7 +95,7 @@ imports: - data - data/base58 - name: github.com/tendermint/tmlibs - version: bd9d0d1637dadf1330e167189d5e5031aadcda6f + version: 2f6f3e6aa70bb19b70a6e73210273fa127041070 subpackages: - cli - common @@ -111,7 +113,7 @@ imports: - ripemd160 - salsa20/salsa - name: golang.org/x/sys - version: 9ccfe848b9db8435a24c424abbc07a921adf1df5 + version: e62c3de784db939836898e5c19ffd41bece347da subpackages: - unix - name: golang.org/x/text diff --git a/glide.yaml b/glide.yaml index 58e3aecca..a99d3b63f 100644 --- a/glide.yaml +++ b/glide.yaml @@ -29,6 +29,7 @@ import: - package: github.com/spf13/cobra - package: github.com/spf13/viper - package: gopkg.in/go-playground/validator.v9 +- package: github.com/howeyc/crc16 testImport: - package: github.com/mndrix/btcutil - package: github.com/stretchr/testify diff --git a/keys/ecc.go b/keys/ecc.go index 96590cd91..b94bf1fb9 100644 --- a/keys/ecc.go +++ b/keys/ecc.go @@ -5,6 +5,8 @@ import ( "errors" "hash/crc32" "hash/crc64" + + "github.com/howeyc/crc16" ) // ECC is used for anything that calculates an error-correcting code @@ -26,6 +28,67 @@ var _ ECC = NoECC{} func (_ NoECC) AddECC(input []byte) []byte { return input } func (_ NoECC) CheckECC(input []byte) ([]byte, error) { return input, nil } +// CRC16 does the ieee crc16 polynomial check +type CRC16 struct { + Poly uint16 + table *crc16.Table +} + +var _ ECC = &CRC16{} + +const crc16Size = 2 + +func NewIBMCRC16() *CRC16 { + return &CRC16{Poly: crc16.IBM} +} + +func NewSCSICRC16() *CRC16 { + return &CRC16{Poly: crc16.SCSI} +} + +func NewCCITTCRC16() *CRC16 { + return &CRC16{Poly: crc16.CCITT} +} + +func (c *CRC16) AddECC(input []byte) []byte { + table := c.getTable() + + // get crc and convert to some bytes... + crc := crc16.Checksum(input, table) + check := make([]byte, crc16Size) + binary.BigEndian.PutUint16(check, crc) + + // append it to the input + output := append(input, check...) + return output +} + +func (c *CRC16) CheckECC(input []byte) ([]byte, error) { + table := c.getTable() + + if len(input) <= crc16Size { + return nil, errors.New("input too short, no checksum present") + } + cut := len(input) - crc16Size + data, check := input[:cut], input[cut:] + crc := binary.BigEndian.Uint16(check) + calc := crc16.Checksum(data, table) + if crc != calc { + return nil, errors.New("Checksum does not match") + } + return data, nil +} + +func (c *CRC16) getTable() *crc16.Table { + if c.table == nil { + if c.Poly == 0 { + c.Poly = crc16.IBM + } + c.table = crc16.MakeTable(c.Poly) + } + return c.table +} + // CRC32 does the ieee crc32 polynomial check type CRC32 struct { Poly uint32 diff --git a/keys/ecc_test.go b/keys/ecc_test.go index 334c49423..930422b98 100644 --- a/keys/ecc_test.go +++ b/keys/ecc_test.go @@ -14,6 +14,9 @@ func TestECCPasses(t *testing.T) { checks := []ECC{ NoECC{}, + NewIBMCRC16(), + NewSCSICRC16(), + NewCCITTCRC16(), NewIEEECRC32(), NewCastagnoliCRC32(), NewKoopmanCRC32(), @@ -40,6 +43,9 @@ func TestECCFails(t *testing.T) { assert := assert.New(t) checks := []ECC{ + NewIBMCRC16(), + NewSCSICRC16(), + NewCCITTCRC16(), NewIEEECRC32(), NewCastagnoliCRC32(), NewKoopmanCRC32(), From 4ff889a236daa068db5666115637d74761a55a33 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sat, 22 Jul 2017 05:44:09 -0400 Subject: [PATCH 108/287] Use 16 random bytes for seed and key, crc16 by default --- keys/cryptostore/encoder_test.go | 9 ++++++--- keys/cryptostore/generator.go | 16 ++++++++-------- keys/cryptostore/holder.go | 21 ++++++++++++++------- keys/cryptostore/storage_test.go | 6 +++++- keys/wordcodec.go | 3 ++- keys/wordcodec_test.go | 2 +- 6 files changed, 36 insertions(+), 21 deletions(-) diff --git a/keys/cryptostore/encoder_test.go b/keys/cryptostore/encoder_test.go index e5ea21111..945e19865 100644 --- a/keys/cryptostore/encoder_test.go +++ b/keys/cryptostore/encoder_test.go @@ -5,6 +5,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + cmn "github.com/tendermint/tmlibs/common" + "github.com/tendermint/go-crypto/keys/cryptostore" ) @@ -12,8 +15,8 @@ func TestNoopEncoder(t *testing.T) { assert, require := assert.New(t), require.New(t) noop := cryptostore.Noop - key := cryptostore.GenEd25519.Generate() - key2 := cryptostore.GenSecp256k1.Generate() + key := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) + key2 := cryptostore.GenSecp256k1.Generate(cmn.RandBytes(16)) b, err := noop.Encrypt(key, "encode") require.Nil(err) @@ -40,7 +43,7 @@ func TestSecretBox(t *testing.T) { assert, require := assert.New(t), require.New(t) enc := cryptostore.SecretBox - key := cryptostore.GenEd25519.Generate() + key := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) pass := "some-special-secret" b, err := enc.Encrypt(key, pass) diff --git a/keys/cryptostore/generator.go b/keys/cryptostore/generator.go index 6bbdb6441..307a0ae86 100644 --- a/keys/cryptostore/generator.go +++ b/keys/cryptostore/generator.go @@ -14,22 +14,22 @@ var ( // Generator determines the type of private key the keystore creates type Generator interface { - Generate() crypto.PrivKey + Generate(secret []byte) crypto.PrivKey } // GenFunc is a helper to transform a function into a Generator -type GenFunc func() crypto.PrivKey +type GenFunc func(secret []byte) crypto.PrivKey -func (f GenFunc) Generate() crypto.PrivKey { - return f() +func (f GenFunc) Generate(secret []byte) crypto.PrivKey { + return f(secret) } -func genEd25519() crypto.PrivKey { - return crypto.GenPrivKeyEd25519().Wrap() +func genEd25519(secret []byte) crypto.PrivKey { + return crypto.GenPrivKeyEd25519FromSecret(secret).Wrap() } -func genSecp256() crypto.PrivKey { - return crypto.GenPrivKeySecp256k1().Wrap() +func genSecp256(secret []byte) crypto.PrivKey { + return crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap() } func getGenerator(algo string) (Generator, error) { diff --git a/keys/cryptostore/holder.go b/keys/cryptostore/holder.go index 0e4fde042..a3b5d2f61 100644 --- a/keys/cryptostore/holder.go +++ b/keys/cryptostore/holder.go @@ -43,12 +43,16 @@ func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error if err != nil { return keys.Info{}, "", err } - key := gen.Generate() + + // 128-bits the the all the randomness we can make use of + secret := crypto.CRandBytes(16) + key := gen.Generate(secret) err = s.es.Put(name, passphrase, key) if err != nil { return keys.Info{}, "", err } - seed, err := s.codec.BytesToWords(key.Bytes()) + + seed, err := s.codec.BytesToWords(secret) phrase := strings.Join(seed, " ") return info(name, key), phrase, err } @@ -61,15 +65,18 @@ func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error // Result similar to New(), except it doesn't return the seed again... func (s Manager) Recover(name, passphrase, seedphrase string) (keys.Info, error) { words := strings.Split(strings.TrimSpace(seedphrase), " ") - data, err := s.codec.WordsToBytes(words) + secret, err := s.codec.WordsToBytes(words) if err != nil { return keys.Info{}, err } - key, err := crypto.PrivKeyFromBytes(data) - if err != nil { - return keys.Info{}, err - } + // TODO: flag this??? + gen := GenEd25519 + // gen, err := getGenerator(algo) + // if err != nil { + // return keys.Info{}, "", err + // } + key := gen.Generate(secret) // d00d, it worked! create the bugger.... err = s.es.Put(name, passphrase, key) diff --git a/keys/cryptostore/storage_test.go b/keys/cryptostore/storage_test.go index b109c44e8..907a19f11 100644 --- a/keys/cryptostore/storage_test.go +++ b/keys/cryptostore/storage_test.go @@ -4,13 +4,17 @@ import ( "testing" "github.com/stretchr/testify/assert" + + crypto "github.com/tendermint/go-crypto" + cmn "github.com/tendermint/tmlibs/common" + keys "github.com/tendermint/go-crypto/keys" ) func TestSortKeys(t *testing.T) { assert := assert.New(t) - gen := GenEd25519.Generate + gen := func() crypto.PrivKey { return GenEd25519.Generate(cmn.RandBytes(16)) } assert.NotEqual(gen(), gen()) // alphabetical order is n3, n1, n2 diff --git a/keys/wordcodec.go b/keys/wordcodec.go index ee1374644..214fe7e0b 100644 --- a/keys/wordcodec.go +++ b/keys/wordcodec.go @@ -34,7 +34,8 @@ func NewCodec(words []string) (codec *WordCodec, err error) { res := &WordCodec{ words: words, // TODO: configure this outside??? - check: NewIEEECRC32(), + // check: NewIEEECRC32(), + check: NewIBMCRC16(), } return res, nil diff --git a/keys/wordcodec_test.go b/keys/wordcodec_test.go index 1ae97d8a7..25c5439a6 100644 --- a/keys/wordcodec_test.go +++ b/keys/wordcodec_test.go @@ -152,7 +152,7 @@ func TestCheckTypoDetection(t *testing.T) { codec, err := LoadCodec(bank) require.Nil(err, "%s: %+v", bank, err) for i := 0; i < 1000; i++ { - numBytes := cmn.RandInt()%60 + 1 + numBytes := cmn.RandInt()%60 + 4 data := cmn.RandBytes(numBytes) words, err := codec.BytesToWords(data) From c20e83565c959438f00c029195345e23485b9e50 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sat, 22 Jul 2017 05:53:46 -0400 Subject: [PATCH 109/287] Recovery also works with secp256 keys --- keys/cryptostore/generator.go | 11 +++++++++++ keys/cryptostore/holder.go | 17 ++++++++++------ tests/keys.sh | 37 ++++++++++++++++++++++++++++++++--- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/keys/cryptostore/generator.go b/keys/cryptostore/generator.go index 307a0ae86..0a2bb55c2 100644 --- a/keys/cryptostore/generator.go +++ b/keys/cryptostore/generator.go @@ -42,3 +42,14 @@ func getGenerator(algo string) (Generator, error) { return nil, errors.Errorf("Cannot generate keys for algorithm: %s", algo) } } + +func getGeneratorByType(typ byte) (Generator, error) { + switch typ { + case crypto.TypeEd25519: + return GenEd25519, nil + case crypto.TypeSecp256k1: + return GenSecp256k1, nil + default: + return nil, errors.Errorf("Cannot generate keys for algorithm: %X", typ) + } +} diff --git a/keys/cryptostore/holder.go b/keys/cryptostore/holder.go index a3b5d2f61..202e55973 100644 --- a/keys/cryptostore/holder.go +++ b/keys/cryptostore/holder.go @@ -52,6 +52,10 @@ func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error return keys.Info{}, "", err } + // TODO: clean up type/kind handling with go-data + typ := key.Bytes()[0] + secret = append(secret, typ) + seed, err := s.codec.BytesToWords(secret) phrase := strings.Join(seed, " ") return info(name, key), phrase, err @@ -70,12 +74,13 @@ func (s Manager) Recover(name, passphrase, seedphrase string) (keys.Info, error) return keys.Info{}, err } - // TODO: flag this??? - gen := GenEd25519 - // gen, err := getGenerator(algo) - // if err != nil { - // return keys.Info{}, "", err - // } + l := len(secret) + secret, typ := secret[:l-1], secret[l-1] + + gen, err := getGeneratorByType(typ) + if err != nil { + return keys.Info{}, err + } key := gen.Generate(secret) // d00d, it worked! create the bugger.... diff --git a/tests/keys.sh b/tests/keys.sh index c848f8dd2..599f3d743 100755 --- a/tests/keys.sh +++ b/tests/keys.sh @@ -68,7 +68,6 @@ test03recoverKeys() { PASS2=1234567890 # make a user and check they exist - echo "create..." KEY=$(echo $PASS1 | ${EXE} new $USER -o json) if ! assertTrue "created $USER" $?; then return 1; fi if [ -n "$DEBUG" ]; then echo $KEY; echo; fi @@ -79,13 +78,11 @@ test03recoverKeys() { assertTrue "${EXE} get $USER > /dev/null" # let's delete this key - echo "delete..." assertFalse "echo foo | ${EXE} delete $USER > /dev/null" assertTrue "echo $PASS1 | ${EXE} delete $USER > /dev/null" assertFalse "${EXE} get $USER > /dev/null" # fails on short password - echo "recover..." assertFalse "echo foo; echo $SEED | ${EXE} recover $USER2 -o json > /dev/null" # fails on bad seed assertFalse "echo $PASS2; echo \"silly white whale tower bongo\" | ${EXE} recover $USER2 -o json > /dev/null" @@ -106,6 +103,40 @@ test03recoverKeys() { assertTrue "${EXE} get $USER2 > /dev/null" } +# try recovery with secp256k1 keys +test03recoverSecp() { + USER=dings + PASS1=Sbub-U9byS7hso + + USER2=booms + PASS2=1234567890 + + KEY=$(echo $PASS1 | ${EXE} new $USER -o json -t secp256k1) + if ! assertTrue "created $USER" $?; then return 1; fi + if [ -n "$DEBUG" ]; then echo $KEY; echo; fi + + SEED=$(echo $KEY | jq .seed | tr -d \") + ADDR=$(echo $KEY | jq .key.address | tr -d \") + PUBKEY=$(echo $KEY | jq .key.pubkey | tr -d \") + assertTrue "${EXE} get $USER > /dev/null" + + # now we got it + KEY2=$((echo $PASS2; echo $SEED) | ${EXE} recover $USER2 -o json) + if ! assertTrue "recovery failed: $KEY2" $?; then return 1; fi + if [ -n "$DEBUG" ]; then echo $KEY2; echo; fi + + # make sure it looks the same + NAME2=$(echo $KEY2 | jq .name | tr -d \") + ADDR2=$(echo $KEY2 | jq .address | tr -d \") + PUBKEY2=$(echo $KEY2 | jq .pubkey | tr -d \") + assertEquals "wrong username" "$USER2" "$NAME2" + assertEquals "address doesn't match" "$ADDR" "$ADDR2" + assertEquals "pubkey doesn't match" "$PUBKEY" "$PUBKEY2" + + # and we can find the info + assertTrue "${EXE} get $USER2 > /dev/null" +} + # load and run these tests with shunit2! DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #get this files directory . $DIR/shunit2 From 10222adaf1dc58a0d844caafce36fdd001c1e0be Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 26 Jul 2017 16:12:25 -0400 Subject: [PATCH 110/287] Remove deprecated code. Now in basecoin/weave --- keys/tx/docs.go | 10 ------ keys/tx/multi.go | 67 ------------------------------------ keys/tx/multi_test.go | 78 ------------------------------------------ keys/tx/one.go | 57 ------------------------------ keys/tx/one_test.go | 74 --------------------------------------- keys/tx/reader.go | 76 ---------------------------------------- keys/tx/reader_test.go | 72 -------------------------------------- 7 files changed, 434 deletions(-) delete mode 100644 keys/tx/docs.go delete mode 100644 keys/tx/multi.go delete mode 100644 keys/tx/multi_test.go delete mode 100644 keys/tx/one.go delete mode 100644 keys/tx/one_test.go delete mode 100644 keys/tx/reader.go delete mode 100644 keys/tx/reader_test.go diff --git a/keys/tx/docs.go b/keys/tx/docs.go deleted file mode 100644 index 6a5ea3ce3..000000000 --- a/keys/tx/docs.go +++ /dev/null @@ -1,10 +0,0 @@ -/* -package tx contains generic Signable implementations that can be used -by your application or tests to handle authentication needs. - -It currently supports transaction data as opaque bytes and either single -or multiple private key signatures using straightforward algorithms. -It currently does not support N-of-M key share signing of other more -complex algorithms (although it would be great to add them) -*/ -package tx diff --git a/keys/tx/multi.go b/keys/tx/multi.go deleted file mode 100644 index f069fb273..000000000 --- a/keys/tx/multi.go +++ /dev/null @@ -1,67 +0,0 @@ -package tx - -import ( - "github.com/pkg/errors" - crypto "github.com/tendermint/go-crypto" - data "github.com/tendermint/go-wire/data" -) - -// MultiSig lets us wrap arbitrary data with a go-crypto signature -// -// TODO: rethink how we want to integrate this with KeyStore so it makes -// more sense (particularly the verify method) -type MultiSig struct { - Data data.Bytes - Sigs []Signed -} - -type Signed struct { - Sig crypto.Signature - Pubkey crypto.PubKey -} - -var _ SigInner = &MultiSig{} - -func NewMulti(data []byte) Sig { - return Sig{&MultiSig{Data: data}} -} - -// SignBytes returns the original data passed into `NewSig` -func (s *MultiSig) SignBytes() []byte { - return s.Data -} - -// Sign will add a signature and pubkey. -// -// Depending on the Signable, one may be able to call this multiple times for multisig -// Returns error if called with invalid data or too many times -func (s *MultiSig) Sign(pubkey crypto.PubKey, sig crypto.Signature) error { - if pubkey.Empty() || sig.Empty() { - return errors.New("Signature or Key missing") - } - - // set the value once we are happy - x := Signed{sig, pubkey} - s.Sigs = append(s.Sigs, x) - return nil -} - -// Signers will return the public key(s) that signed if the signature -// is valid, or an error if there is any issue with the signature, -// including if there are no signatures -func (s *MultiSig) Signers() ([]crypto.PubKey, error) { - if len(s.Sigs) == 0 { - return nil, errors.New("Never signed") - } - - keys := make([]crypto.PubKey, len(s.Sigs)) - for i := range s.Sigs { - ms := s.Sigs[i] - if !ms.Pubkey.VerifyBytes(s.Data, ms.Sig) { - return nil, errors.Errorf("Signature %d doesn't match (key: %X)", i, ms.Pubkey.Bytes()) - } - keys[i] = ms.Pubkey - } - - return keys, nil -} diff --git a/keys/tx/multi_test.go b/keys/tx/multi_test.go deleted file mode 100644 index 22fb0ed75..000000000 --- a/keys/tx/multi_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package tx - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - crypto "github.com/tendermint/go-crypto" - keys "github.com/tendermint/go-crypto/keys" - "github.com/tendermint/go-crypto/keys/cryptostore" - "github.com/tendermint/go-crypto/keys/storage/memstorage" -) - -func TestMultiSig(t *testing.T) { - assert, require := assert.New(t), require.New(t) - - algo := crypto.NameEd25519 - cstore := cryptostore.New( - cryptostore.SecretBox, - memstorage.New(), - keys.MustLoadCodec("english"), - ) - n, p := "foo", "bar" - n2, p2 := "other", "thing" - - acct, _, err := cstore.Create(n, p, algo) - require.Nil(err, "%+v", err) - acct2, _, err := cstore.Create(n2, p2, algo) - require.Nil(err, "%+v", err) - - type signer struct { - key keys.Info - name, pass string - } - cases := []struct { - data string - signers []signer - }{ - {"one", []signer{{acct, n, p}}}, - {"two", []signer{{acct2, n2, p2}}}, - {"both", []signer{{acct, n, p}, {acct2, n2, p2}}}, - } - - for _, tc := range cases { - tx := NewMulti([]byte(tc.data)) - // unsigned version - _, err = tx.Signers() - assert.NotNil(err) - orig, err := tx.TxBytes() - require.Nil(err, "%+v", err) - data := tx.SignBytes() - assert.Equal(tc.data, string(data)) - - // sign it - for _, s := range tc.signers { - err = cstore.Sign(s.name, s.pass, tx) - require.Nil(err, "%+v", err) - } - - // make sure it is proper now - sigs, err := tx.Signers() - require.Nil(err, "%+v", err) - if assert.Equal(len(tc.signers), len(sigs)) { - for i := range sigs { - // This must be refactored... - assert.Equal(tc.signers[i].key.PubKey, sigs[i]) - } - } - // the tx bytes should change after this - after, err := tx.TxBytes() - require.Nil(err, "%+v", err) - assert.NotEqual(orig, after, "%X != %X", orig, after) - - // sign bytes are the same - data = tx.SignBytes() - assert.Equal(tc.data, string(data)) - } -} diff --git a/keys/tx/one.go b/keys/tx/one.go deleted file mode 100644 index af468cc2c..000000000 --- a/keys/tx/one.go +++ /dev/null @@ -1,57 +0,0 @@ -package tx - -import ( - "github.com/pkg/errors" - crypto "github.com/tendermint/go-crypto" - data "github.com/tendermint/go-wire/data" -) - -// OneSig lets us wrap arbitrary data with a go-crypto signature -// -// TODO: rethink how we want to integrate this with KeyStore so it makes -// more sense (particularly the verify method) -type OneSig struct { - Data data.Bytes - Signed -} - -var _ SigInner = &OneSig{} - -func New(data []byte) Sig { - return WrapSig(&OneSig{Data: data}) -} - -// SignBytes returns the original data passed into `NewSig` -func (s *OneSig) SignBytes() []byte { - return s.Data -} - -// Sign will add a signature and pubkey. -// -// Depending on the Signable, one may be able to call this multiple times for multisig -// Returns error if called with invalid data or too many times -func (s *OneSig) Sign(pubkey crypto.PubKey, sig crypto.Signature) error { - if pubkey.Empty() || sig.Empty() { - return errors.New("Signature or Key missing") - } - if !s.Sig.Empty() { - return errors.New("Transaction can only be signed once") - } - - // set the value once we are happy - s.Signed = Signed{sig, pubkey} - return nil -} - -// Signers will return the public key(s) that signed if the signature -// is valid, or an error if there is any issue with the signature, -// including if there are no signatures -func (s *OneSig) Signers() ([]crypto.PubKey, error) { - if s.Pubkey.Empty() || s.Sig.Empty() { - return nil, errors.New("Never signed") - } - if !s.Pubkey.VerifyBytes(s.Data, s.Sig) { - return nil, errors.New("Signature doesn't match") - } - return []crypto.PubKey{s.Pubkey}, nil -} diff --git a/keys/tx/one_test.go b/keys/tx/one_test.go deleted file mode 100644 index e0a3f1056..000000000 --- a/keys/tx/one_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package tx - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - crypto "github.com/tendermint/go-crypto" - keys "github.com/tendermint/go-crypto/keys" - "github.com/tendermint/go-crypto/keys/cryptostore" - "github.com/tendermint/go-crypto/keys/storage/memstorage" -) - -func TestOneSig(t *testing.T) { - assert, require := assert.New(t), require.New(t) - - algo := crypto.NameEd25519 - cstore := cryptostore.New( - cryptostore.SecretBox, - memstorage.New(), - keys.MustLoadCodec("english"), - ) - n, p := "foo", "bar" - n2, p2 := "other", "thing" - - acct, _, err := cstore.Create(n, p, algo) - require.Nil(err, "%+v", err) - acct2, _, err := cstore.Create(n2, p2, algo) - require.Nil(err, "%+v", err) - - cases := []struct { - data string - key keys.Info - name, pass string - }{ - {"first", acct, n, p}, - {"kehfkhefy8y", acct, n, p}, - {"second", acct2, n2, p2}, - } - - for _, tc := range cases { - tx := New([]byte(tc.data)) - // unsigned version - _, err = tx.Signers() - assert.NotNil(err) - orig, err := tx.TxBytes() - require.Nil(err, "%+v", err) - data := tx.SignBytes() - assert.Equal(tc.data, string(data)) - - // sign it - err = cstore.Sign(tc.name, tc.pass, tx) - require.Nil(err, "%+v", err) - // but not twice - err = cstore.Sign(tc.name, tc.pass, tx) - require.NotNil(err) - - // make sure it is proper now - sigs, err := tx.Signers() - require.Nil(err, "%+v", err) - if assert.Equal(1, len(sigs)) { - // This must be refactored... - assert.Equal(tc.key.PubKey, sigs[0]) - } - // the tx bytes should change after this - after, err := tx.TxBytes() - require.Nil(err, "%+v", err) - assert.NotEqual(orig, after, "%X != %X", orig, after) - - // sign bytes are the same - data = tx.SignBytes() - assert.Equal(tc.data, string(data)) - } -} diff --git a/keys/tx/reader.go b/keys/tx/reader.go deleted file mode 100644 index 265e88b46..000000000 --- a/keys/tx/reader.go +++ /dev/null @@ -1,76 +0,0 @@ -package tx - -import ( - crypto "github.com/tendermint/go-crypto" - keys "github.com/tendermint/go-crypto/keys" - data "github.com/tendermint/go-wire/data" -) - -const ( - typeOneSig = byte(0x01) - typeMultiSig = byte(0x02) - nameOneSig = "sig" - nameMultiSig = "multi" -) - -var _ keys.Signable = Sig{} -var TxMapper data.Mapper - -func init() { - TxMapper = data.NewMapper(Sig{}). - RegisterImplementation(&OneSig{}, nameOneSig, typeOneSig). - RegisterImplementation(&MultiSig{}, nameMultiSig, typeMultiSig) -} - -/* -DO NOT USE this interface. - -It is public by necessity but should never be used directly -outside of this package. - -Only use Sig, never SigInner -*/ -type SigInner interface { - SignBytes() []byte - Sign(pubkey crypto.PubKey, sig crypto.Signature) error - Signers() ([]crypto.PubKey, error) -} - -// Sig is what is exported, and handles serialization -type Sig struct { - SigInner -} - -// TxBytes -func (s Sig) TxBytes() ([]byte, error) { - return data.ToWire(s) -} - -// WrapSig goes from concrete implementation to "interface" struct -func WrapSig(pk SigInner) Sig { - if wrap, ok := pk.(Sig); ok { - pk = wrap.Unwrap() - } - return Sig{pk} -} - -// Unwrap recovers the concrete interface safely (regardless of levels of embeds) -func (p Sig) Unwrap() SigInner { - pk := p.SigInner - for wrap, ok := pk.(Sig); ok; wrap, ok = pk.(Sig) { - pk = wrap.SigInner - } - return pk -} - -func (p Sig) MarshalJSON() ([]byte, error) { - return TxMapper.ToJSON(p.Unwrap()) -} - -func (p *Sig) UnmarshalJSON(data []byte) (err error) { - parsed, err := TxMapper.FromJSON(data) - if err == nil && parsed != nil { - p.SigInner = parsed.(SigInner) - } - return -} diff --git a/keys/tx/reader_test.go b/keys/tx/reader_test.go deleted file mode 100644 index f0561301f..000000000 --- a/keys/tx/reader_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package tx - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - crypto "github.com/tendermint/go-crypto" - "github.com/tendermint/go-crypto/keys" - "github.com/tendermint/go-crypto/keys/cryptostore" - "github.com/tendermint/go-crypto/keys/storage/memstorage" - data "github.com/tendermint/go-wire/data" -) - -func TestReader(t *testing.T) { - assert, require := assert.New(t), require.New(t) - - algo := crypto.NameEd25519 - cstore := cryptostore.New( - cryptostore.SecretBox, - memstorage.New(), - keys.MustLoadCodec("english"), - ) - type sigs struct{ name, pass string } - u := sigs{"alice", "1234"} - u2 := sigs{"bob", "foobar"} - - _, _, err := cstore.Create(u.name, u.pass, algo) - require.Nil(err, "%+v", err) - _, _, err = cstore.Create(u2.name, u2.pass, algo) - require.Nil(err, "%+v", err) - - cases := []struct { - tx Sig - sigs []sigs - }{ - {New([]byte("first")), nil}, - {New([]byte("second")), []sigs{u}}, - {New([]byte("other")), []sigs{u2}}, - {NewMulti([]byte("m-first")), nil}, - {NewMulti([]byte("m-second")), []sigs{u}}, - {NewMulti([]byte("m-other")), []sigs{u, u2}}, - } - - for _, tc := range cases { - tx := tc.tx - - // make sure json serialization and loading works w/o sigs - var pre Sig - pjs, err := data.ToJSON(tx) - require.Nil(err, "%+v", err) - err = data.FromJSON(pjs, &pre) - require.Nil(err, "%+v", err) - assert.Equal(tx, pre) - - for _, s := range tc.sigs { - err = cstore.Sign(s.name, s.pass, tx) - require.Nil(err, "%+v", err) - } - - var post Sig - sjs, err := data.ToJSON(tx) - require.Nil(err, "%+v", err) - err = data.FromJSON(sjs, &post) - require.Nil(err, "%+v\n%s", err, string(sjs)) - assert.Equal(tx, post) - - if len(tc.sigs) > 0 { - assert.NotEqual(pjs, sjs, "%s\n ------ %s", string(pjs), string(sjs)) - } - } -} From 050b9657083e3c2835dc6807291bd83b90345b61 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 27 Jul 2017 15:59:59 -0400 Subject: [PATCH 111/287] Code cleanup ala Emmanuel --- keys/cryptostore/holder.go | 7 +++++-- keys/ecc.go | 40 +++++++++++++++++++++----------------- keys/ecc_test.go | 35 +++++++++++++-------------------- 3 files changed, 40 insertions(+), 42 deletions(-) diff --git a/keys/cryptostore/holder.go b/keys/cryptostore/holder.go index 202e55973..18437a9b5 100644 --- a/keys/cryptostore/holder.go +++ b/keys/cryptostore/holder.go @@ -44,7 +44,7 @@ func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error return keys.Info{}, "", err } - // 128-bits the the all the randomness we can make use of + // 128-bits are the all the randomness we can make use of secret := crypto.CRandBytes(16) key := gen.Generate(secret) err = s.es.Put(name, passphrase, key) @@ -52,7 +52,8 @@ func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error return keys.Info{}, "", err } - // TODO: clean up type/kind handling with go-data + // we append the type byte to the serialized secret to help with recovery + // ie [secret] = [secret] + [type] typ := key.Bytes()[0] secret = append(secret, typ) @@ -74,6 +75,8 @@ func (s Manager) Recover(name, passphrase, seedphrase string) (keys.Info, error) return keys.Info{}, err } + // secret is comprised of the actual secret with the type appended + // ie [secret] = [secret] + [type] l := len(secret) secret, typ := secret[:l-1], secret[l-1] diff --git a/keys/ecc.go b/keys/ecc.go index b94bf1fb9..c1ac258fe 100644 --- a/keys/ecc.go +++ b/keys/ecc.go @@ -20,6 +20,9 @@ type ECC interface { CheckECC([]byte) ([]byte, error) } +var errInputTooShort = errors.New("input too short, no checksum present") +var errChecksumDoesntMatch = errors.New("checksum does not match") + // NoECC is a no-op placeholder, kind of useless... except for tests type NoECC struct{} @@ -34,9 +37,9 @@ type CRC16 struct { table *crc16.Table } -var _ ECC = &CRC16{} +var _ ECC = (*CRC16)(nil) -const crc16Size = 2 +const crc16ByteCount = 2 func NewIBMCRC16() *CRC16 { return &CRC16{Poly: crc16.IBM} @@ -55,7 +58,7 @@ func (c *CRC16) AddECC(input []byte) []byte { // get crc and convert to some bytes... crc := crc16.Checksum(input, table) - check := make([]byte, crc16Size) + check := make([]byte, crc16ByteCount) binary.BigEndian.PutUint16(check, crc) // append it to the input @@ -66,26 +69,27 @@ func (c *CRC16) AddECC(input []byte) []byte { func (c *CRC16) CheckECC(input []byte) ([]byte, error) { table := c.getTable() - if len(input) <= crc16Size { - return nil, errors.New("input too short, no checksum present") + if len(input) <= crc16ByteCount { + return nil, errInputTooShort } - cut := len(input) - crc16Size + cut := len(input) - crc16ByteCount data, check := input[:cut], input[cut:] crc := binary.BigEndian.Uint16(check) calc := crc16.Checksum(data, table) if crc != calc { - return nil, errors.New("Checksum does not match") + return nil, errChecksumDoesntMatch } return data, nil } func (c *CRC16) getTable() *crc16.Table { - if c.table == nil { - if c.Poly == 0 { - c.Poly = crc16.IBM - } - c.table = crc16.MakeTable(c.Poly) + if c.table != nil { + return c.table + } + if c.Poly == 0 { + c.Poly = crc16.IBM } + c.table = crc16.MakeTable(c.Poly) return c.table } @@ -95,7 +99,7 @@ type CRC32 struct { table *crc32.Table } -var _ ECC = &CRC32{} +var _ ECC = (*CRC32)(nil) func NewIEEECRC32() *CRC32 { return &CRC32{Poly: crc32.IEEE} @@ -126,14 +130,14 @@ func (c *CRC32) CheckECC(input []byte) ([]byte, error) { table := c.getTable() if len(input) <= crc32.Size { - return nil, errors.New("input too short, no checksum present") + return nil, errInputTooShort } cut := len(input) - crc32.Size data, check := input[:cut], input[cut:] crc := binary.BigEndian.Uint32(check) calc := crc32.Checksum(data, table) if crc != calc { - return nil, errors.New("Checksum does not match") + return nil, errChecksumDoesntMatch } return data, nil } @@ -154,7 +158,7 @@ type CRC64 struct { table *crc64.Table } -var _ ECC = &CRC64{} +var _ ECC = (*CRC64)(nil) func NewISOCRC64() *CRC64 { return &CRC64{Poly: crc64.ISO} @@ -181,14 +185,14 @@ func (c *CRC64) CheckECC(input []byte) ([]byte, error) { table := c.getTable() if len(input) <= crc64.Size { - return nil, errors.New("input too short, no checksum present") + return nil, errInputTooShort } cut := len(input) - crc64.Size data, check := input[:cut], input[cut:] crc := binary.BigEndian.Uint64(check) calc := crc64.Checksum(data, table) if crc != calc { - return nil, errors.New("Checksum does not match") + return nil, errChecksumDoesntMatch } return data, nil } diff --git a/keys/ecc_test.go b/keys/ecc_test.go index 930422b98..d6b536aaa 100644 --- a/keys/ecc_test.go +++ b/keys/ecc_test.go @@ -8,21 +8,22 @@ import ( cmn "github.com/tendermint/tmlibs/common" ) +var codecs = []ECC{ + NewIBMCRC16(), + NewSCSICRC16(), + NewCCITTCRC16(), + NewIEEECRC32(), + NewCastagnoliCRC32(), + NewKoopmanCRC32(), + NewISOCRC64(), + NewECMACRC64(), +} + // TestECCPasses makes sure that the AddECC/CheckECC methods are symetric func TestECCPasses(t *testing.T) { assert := assert.New(t) - checks := []ECC{ - NoECC{}, - NewIBMCRC16(), - NewSCSICRC16(), - NewCCITTCRC16(), - NewIEEECRC32(), - NewCastagnoliCRC32(), - NewKoopmanCRC32(), - NewISOCRC64(), - NewECMACRC64(), - } + checks := append(codecs, NoECC{}) for _, check := range checks { for i := 0; i < 2000; i++ { @@ -42,17 +43,7 @@ func TestECCPasses(t *testing.T) { func TestECCFails(t *testing.T) { assert := assert.New(t) - checks := []ECC{ - NewIBMCRC16(), - NewSCSICRC16(), - NewCCITTCRC16(), - NewIEEECRC32(), - NewCastagnoliCRC32(), - NewKoopmanCRC32(), - NewISOCRC64(), - NewECMACRC64(), - } - + checks := codecs attempts := 2000 for _, check := range checks { From ae9c5b1ca0c77ea7203bbfa4f1cd68cd6d480e17 Mon Sep 17 00:00:00 2001 From: Emmanuel Odeke Date: Wed, 26 Jul 2017 20:43:27 -0600 Subject: [PATCH 112/287] hd: optimize ReverseBytes + add tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Optimized ReverseBytes to: a) Minimally allocate --> 60.0% reduction in the number of allocations b) Only walk halfway the length of the string thus performing byte swaps from left to right. Improves the performance as well. Complexity is O(n/2) instead of O(n) which is still O(n) but benchmarks show the new time is in deed 1/2 of the original time. * Added unit tests and some common cases to ensure correctness. * Benchmark shoot out results: ```shell name old time/op new time/op delta ReverseBytes-4 554ns ± 4% 242ns ± 3% -56.20% (p=0.000 n=10+10) name old alloc/op new alloc/op delta ReverseBytes-4 208B ± 0% 114B ± 0% -45.19% (p=0.000 n=10+10) name old allocs/op new allocs/op delta ReverseBytes-4 10.0 ± 0% 4.0 ± 0% -60.00% (p=0.000 n=10+10) ``` --- hd/address.go | 17 ++++++++++++++--- hd/hd_test.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/hd/address.go b/hd/address.go index 28f70a98f..d7553a4d7 100644 --- a/hd/address.go +++ b/hd/address.go @@ -282,9 +282,20 @@ func CalcSha512(buf []byte) []byte { } func ReverseBytes(buf []byte) []byte { - res := []byte{} - for i := len(buf) - 1; i >= 0; i-- { - res = append(res, buf[i]) + var res []byte + if len(buf) == 0 { + return res + } + + // Walk till mid-way, swapping bytes from each end: + // b[i] and b[len-i-1] + blen := len(buf) + res = make([]byte, blen) + mid := blen / 2 + for left := 0; left <= mid; left++ { + right := blen - left - 1 + res[left] = buf[right] + res[right] = buf[left] } return res } diff --git a/hd/hd_test.go b/hd/hd_test.go index e771f14b6..b2f7d2e8f 100644 --- a/hd/hd_test.go +++ b/hd/hd_test.go @@ -89,6 +89,26 @@ func TestHDToAddr(t *testing.T) { } } +func TestReverseBytes(t *testing.T) { + tests := [...]struct { + v []byte + want []byte + }{ + {[]byte(""), []byte("")}, + {nil, nil}, + {[]byte("Tendermint"), []byte("tnimredneT")}, + {[]byte("T"), []byte("T")}, + {[]byte("Te"), []byte("eT")}, + } + + for i, tt := range tests { + got := ReverseBytes(tt.v) + if !bytes.Equal(got, tt.want) { + t.Errorf("#%d:\ngot= (%x)\nwant=(%x)", i, got, tt.want) + } + } +} + func ifExit(err error, n int) { if err != nil { fmt.Println(n, err) @@ -187,3 +207,36 @@ func tylerSmith(seed []byte) ([]byte, []byte, []byte) { pub := k.PublicKey().Key return masterKey.Key, priv, pub } + +// Benchmarks + +var revBytesCases = [][]byte{ + nil, + []byte(""), + + []byte("12"), + + // 16byte case + []byte("abcdefghijklmnop"), + + // 32byte case + []byte("abcdefghijklmnopqrstuvwxyz123456"), + + // 64byte case + []byte("abcdefghijklmnopqrstuvwxyz123456abcdefghijklmnopqrstuvwxyz123456"), +} + +func BenchmarkReverseBytes(b *testing.B) { + var sink []byte + for i := 0; i < b.N; i++ { + for _, tt := range revBytesCases { + sink = ReverseBytes(tt) + } + } + b.ReportAllocs() + + // sink is necessary to ensure if the compiler tries + // to smart, that it won't optimize away the benchmarks. + if sink != nil { + } +} From ce80f234c75b85383a20b19cae393aec0f2b1a50 Mon Sep 17 00:00:00 2001 From: Emmanuel Odeke Date: Fri, 28 Jul 2017 13:01:28 -0600 Subject: [PATCH 113/287] README: add godoc instead of tedious MD regeneration Add a godoc reference to delegate indexing and references to that service, thus keeping our library and usages upto date, instead of relying on generated markdown that goes stale especially for changing API signatures, and becomes tedious where someone has to remember to always regenerate the README markdown and then commit it. Fixes #24 --- Makefile | 6 +- README.md | 839 +----------------------------------------------------- 2 files changed, 5 insertions(+), 840 deletions(-) diff --git a/Makefile b/Makefile index 537b6396f..8387f0608 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,10 @@ -.PHONEY: all docs test install get_vendor_deps ensure_tools codegen wordlist +.PHONEY: all test install get_vendor_deps ensure_tools codegen wordlist GOTOOLS = \ github.com/Masterminds/glide \ github.com/jteeuwen/go-bindata/go-bindata REPO:=github.com/tendermint/go-crypto -docs: - @go get github.com/davecheney/godoc2md - godoc2md $(REPO) > README.md - all: get_vendor_deps install test install: diff --git a/README.md b/README.md index ada192080..da76fe823 100644 --- a/README.md +++ b/README.md @@ -1,837 +1,6 @@ +# go-crypto [![GoDoc](https://godoc.org/github.com/tendermint/go-crypto?status.svg)](https://godoc.org/github.com/tendermint/go-crypto) +go-crypto is the cryptographic package adapted for Tendermint's uses -# crypto -`import "github.com/tendermint/go-crypto"` - -* [Overview](#pkg-overview) -* [Index](#pkg-index) -* [Subdirectories](#pkg-subdirectories) - -## Overview - - - -## Index -* [Constants](#pkg-constants) -* [func CRandBytes(numBytes int) []byte](#CRandBytes) -* [func CRandHex(numDigits int) string](#CRandHex) -* [func CReader() io.Reader](#CReader) -* [func DecodeArmor(armorStr string) (blockType string, headers map[string]string, data []byte, err error)](#DecodeArmor) -* [func DecryptSymmetric(ciphertext []byte, secret []byte) (plaintext []byte, err error)](#DecryptSymmetric) -* [func EncodeArmor(blockType string, headers map[string]string, data []byte) string](#EncodeArmor) -* [func EncryptSymmetric(plaintext []byte, secret []byte) (ciphertext []byte)](#EncryptSymmetric) -* [func MixEntropy(seedBytes []byte)](#MixEntropy) -* [func Ripemd160(bytes []byte) []byte](#Ripemd160) -* [func Sha256(bytes []byte) []byte](#Sha256) -* [type PrivKey](#PrivKey) - * [func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error)](#PrivKeyFromBytes) -* [type PrivKeyEd25519](#PrivKeyEd25519) - * [func GenPrivKeyEd25519() PrivKeyEd25519](#GenPrivKeyEd25519) - * [func GenPrivKeyEd25519FromSecret(secret []byte) PrivKeyEd25519](#GenPrivKeyEd25519FromSecret) - * [func (privKey PrivKeyEd25519) Bytes() []byte](#PrivKeyEd25519.Bytes) - * [func (privKey PrivKeyEd25519) Equals(other PrivKey) bool](#PrivKeyEd25519.Equals) - * [func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519](#PrivKeyEd25519.Generate) - * [func (p PrivKeyEd25519) MarshalJSON() ([]byte, error)](#PrivKeyEd25519.MarshalJSON) - * [func (privKey PrivKeyEd25519) PubKey() PubKey](#PrivKeyEd25519.PubKey) - * [func (privKey PrivKeyEd25519) Sign(msg []byte) Signature](#PrivKeyEd25519.Sign) - * [func (privKey PrivKeyEd25519) String() string](#PrivKeyEd25519.String) - * [func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte](#PrivKeyEd25519.ToCurve25519) - * [func (p *PrivKeyEd25519) UnmarshalJSON(enc []byte) error](#PrivKeyEd25519.UnmarshalJSON) -* [type PrivKeyS](#PrivKeyS) - * [func (p PrivKeyS) Empty() bool](#PrivKeyS.Empty) - * [func (p PrivKeyS) MarshalJSON() ([]byte, error)](#PrivKeyS.MarshalJSON) - * [func (p *PrivKeyS) UnmarshalJSON(data []byte) (err error)](#PrivKeyS.UnmarshalJSON) -* [type PrivKeySecp256k1](#PrivKeySecp256k1) - * [func GenPrivKeySecp256k1() PrivKeySecp256k1](#GenPrivKeySecp256k1) - * [func GenPrivKeySecp256k1FromSecret(secret []byte) PrivKeySecp256k1](#GenPrivKeySecp256k1FromSecret) - * [func (privKey PrivKeySecp256k1) Bytes() []byte](#PrivKeySecp256k1.Bytes) - * [func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool](#PrivKeySecp256k1.Equals) - * [func (p PrivKeySecp256k1) MarshalJSON() ([]byte, error)](#PrivKeySecp256k1.MarshalJSON) - * [func (privKey PrivKeySecp256k1) PubKey() PubKey](#PrivKeySecp256k1.PubKey) - * [func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature](#PrivKeySecp256k1.Sign) - * [func (privKey PrivKeySecp256k1) String() string](#PrivKeySecp256k1.String) - * [func (p *PrivKeySecp256k1) UnmarshalJSON(enc []byte) error](#PrivKeySecp256k1.UnmarshalJSON) -* [type PubKey](#PubKey) - * [func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error)](#PubKeyFromBytes) -* [type PubKeyEd25519](#PubKeyEd25519) - * [func (pubKey PubKeyEd25519) Address() []byte](#PubKeyEd25519.Address) - * [func (pubKey PubKeyEd25519) Bytes() []byte](#PubKeyEd25519.Bytes) - * [func (pubKey PubKeyEd25519) Equals(other PubKey) bool](#PubKeyEd25519.Equals) - * [func (pubKey PubKeyEd25519) KeyString() string](#PubKeyEd25519.KeyString) - * [func (p PubKeyEd25519) MarshalJSON() ([]byte, error)](#PubKeyEd25519.MarshalJSON) - * [func (pubKey PubKeyEd25519) String() string](#PubKeyEd25519.String) - * [func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte](#PubKeyEd25519.ToCurve25519) - * [func (p *PubKeyEd25519) UnmarshalJSON(enc []byte) error](#PubKeyEd25519.UnmarshalJSON) - * [func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool](#PubKeyEd25519.VerifyBytes) -* [type PubKeyS](#PubKeyS) - * [func (p PubKeyS) Empty() bool](#PubKeyS.Empty) - * [func (p PubKeyS) MarshalJSON() ([]byte, error)](#PubKeyS.MarshalJSON) - * [func (p *PubKeyS) UnmarshalJSON(data []byte) (err error)](#PubKeyS.UnmarshalJSON) -* [type PubKeySecp256k1](#PubKeySecp256k1) - * [func (pubKey PubKeySecp256k1) Address() []byte](#PubKeySecp256k1.Address) - * [func (pubKey PubKeySecp256k1) Bytes() []byte](#PubKeySecp256k1.Bytes) - * [func (pubKey PubKeySecp256k1) Equals(other PubKey) bool](#PubKeySecp256k1.Equals) - * [func (pubKey PubKeySecp256k1) KeyString() string](#PubKeySecp256k1.KeyString) - * [func (p PubKeySecp256k1) MarshalJSON() ([]byte, error)](#PubKeySecp256k1.MarshalJSON) - * [func (pubKey PubKeySecp256k1) String() string](#PubKeySecp256k1.String) - * [func (p *PubKeySecp256k1) UnmarshalJSON(enc []byte) error](#PubKeySecp256k1.UnmarshalJSON) - * [func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool](#PubKeySecp256k1.VerifyBytes) -* [type Signature](#Signature) - * [func SignatureFromBytes(sigBytes []byte) (sig Signature, err error)](#SignatureFromBytes) -* [type SignatureEd25519](#SignatureEd25519) - * [func (sig SignatureEd25519) Bytes() []byte](#SignatureEd25519.Bytes) - * [func (sig SignatureEd25519) Equals(other Signature) bool](#SignatureEd25519.Equals) - * [func (sig SignatureEd25519) IsZero() bool](#SignatureEd25519.IsZero) - * [func (p SignatureEd25519) MarshalJSON() ([]byte, error)](#SignatureEd25519.MarshalJSON) - * [func (sig SignatureEd25519) String() string](#SignatureEd25519.String) - * [func (p *SignatureEd25519) UnmarshalJSON(enc []byte) error](#SignatureEd25519.UnmarshalJSON) -* [type SignatureS](#SignatureS) - * [func (p SignatureS) Empty() bool](#SignatureS.Empty) - * [func (p SignatureS) MarshalJSON() ([]byte, error)](#SignatureS.MarshalJSON) - * [func (p *SignatureS) UnmarshalJSON(data []byte) (err error)](#SignatureS.UnmarshalJSON) -* [type SignatureSecp256k1](#SignatureSecp256k1) - * [func (sig SignatureSecp256k1) Bytes() []byte](#SignatureSecp256k1.Bytes) - * [func (sig SignatureSecp256k1) Equals(other Signature) bool](#SignatureSecp256k1.Equals) - * [func (sig SignatureSecp256k1) IsZero() bool](#SignatureSecp256k1.IsZero) - * [func (p SignatureSecp256k1) MarshalJSON() ([]byte, error)](#SignatureSecp256k1.MarshalJSON) - * [func (sig SignatureSecp256k1) String() string](#SignatureSecp256k1.String) - * [func (p *SignatureSecp256k1) UnmarshalJSON(enc []byte) error](#SignatureSecp256k1.UnmarshalJSON) - - -#### Package files -[armor.go](/src/github.com/tendermint/go-crypto/armor.go) [hash.go](/src/github.com/tendermint/go-crypto/hash.go) [priv_key.go](/src/github.com/tendermint/go-crypto/priv_key.go) [pub_key.go](/src/github.com/tendermint/go-crypto/pub_key.go) [random.go](/src/github.com/tendermint/go-crypto/random.go) [signature.go](/src/github.com/tendermint/go-crypto/signature.go) [symmetric.go](/src/github.com/tendermint/go-crypto/symmetric.go) - - -## Constants -``` go -const ( - TypeEd25519 = byte(0x01) - TypeSecp256k1 = byte(0x02) - NameEd25519 = "ed25519" - NameSecp256k1 = "secp256k1" -) -``` -Types of implementations - - - - -## func [CRandBytes](/src/target/random.go?s=698:734#L28) -``` go -func CRandBytes(numBytes int) []byte -``` -This uses the OS and the Seed(s). - - - -## func [CRandHex](/src/target/random.go?s=924:959#L38) -``` go -func CRandHex(numDigits int) string -``` -RandHex(24) gives 96 bits of randomness, strong enough for most purposes. - - - -## func [CReader](/src/target/random.go?s=1078:1102#L43) -``` go -func CReader() io.Reader -``` -Returns a crand.Reader mixed with user-supplied entropy - - - -## func [DecodeArmor](/src/target/armor.go?s=596:699#L18) -``` go -func DecodeArmor(armorStr string) (blockType string, headers map[string]string, data []byte, err error) -``` - - -## func [DecryptSymmetric](/src/target/symmetric.go?s=1048:1133#L23) -``` go -func DecryptSymmetric(ciphertext []byte, secret []byte) (plaintext []byte, err error) -``` -secret must be 32 bytes long. Use something like Sha256(Bcrypt(passphrase)) -The ciphertext is (secretbox.Overhead + 24) bytes longer than the plaintext. - - - -## func [EncodeArmor](/src/target/armor.go?s=125:206#L1) -``` go -func EncodeArmor(blockType string, headers map[string]string, data []byte) string -``` - - -## func [EncryptSymmetric](/src/target/symmetric.go?s=356:430#L6) -``` go -func EncryptSymmetric(plaintext []byte, secret []byte) (ciphertext []byte) -``` -secret must be 32 bytes long. Use something like Sha256(Bcrypt(passphrase)) -The ciphertext is (secretbox.Overhead + 24) bytes longer than the plaintext. -NOTE: call crypto.MixEntropy() first. - - - -## func [MixEntropy](/src/target/random.go?s=407:440#L13) -``` go -func MixEntropy(seedBytes []byte) -``` -Mix additional bytes of randomness, e.g. from hardware, user-input, etc. -It is OK to call it multiple times. It does not diminish security. - - - -## func [Ripemd160](/src/target/hash.go?s=185:220#L4) -``` go -func Ripemd160(bytes []byte) []byte -``` - - -## func [Sha256](/src/target/hash.go?s=78:110#L1) -``` go -func Sha256(bytes []byte) []byte -``` - - - -## type [PrivKey](/src/target/priv_key.go?s=326:435#L5) -``` go -type PrivKey interface { - Bytes() []byte - Sign(msg []byte) Signature - PubKey() PubKey - Equals(PrivKey) bool -} -``` -PrivKey is part of PrivAccount and state.PrivValidator. - - - - - - - -### func [PrivKeyFromBytes](/src/target/priv_key.go?s=1302:1373#L50) -``` go -func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) -``` - - - - -## type [PrivKeyEd25519](/src/target/priv_key.go?s=1502:1530#L58) -``` go -type PrivKeyEd25519 [64]byte -``` -Implements PrivKey - - - - - - - -### func [GenPrivKeyEd25519](/src/target/priv_key.go?s=3003:3042#L116) -``` go -func GenPrivKeyEd25519() PrivKeyEd25519 -``` - -### func [GenPrivKeyEd25519FromSecret](/src/target/priv_key.go?s=3290:3352#L125) -``` go -func GenPrivKeyEd25519FromSecret(secret []byte) PrivKeyEd25519 -``` -NOTE: secret should be the output of a KDF like bcrypt, -if it's derived from user input. - - - - - -### func (PrivKeyEd25519) [Bytes](/src/target/priv_key.go?s=1532:1576#L60) -``` go -func (privKey PrivKeyEd25519) Bytes() []byte -``` - - - -### func (PrivKeyEd25519) [Equals](/src/target/priv_key.go?s=1973:2029#L75) -``` go -func (privKey PrivKeyEd25519) Equals(other PrivKey) bool -``` - - - -### func (PrivKeyEd25519) [Generate](/src/target/priv_key.go?s=2761:2825#L106) -``` go -func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519 -``` -Deterministically generates new priv-key bytes from key. - - - - -### func (PrivKeyEd25519) [MarshalJSON](/src/target/priv_key.go?s=2156:2209#L83) -``` go -func (p PrivKeyEd25519) MarshalJSON() ([]byte, error) -``` - - - -### func (PrivKeyEd25519) [PubKey](/src/target/priv_key.go?s=1826:1871#L70) -``` go -func (privKey PrivKeyEd25519) PubKey() PubKey -``` - - - -### func (PrivKeyEd25519) [Sign](/src/target/priv_key.go?s=1635:1691#L64) -``` go -func (privKey PrivKeyEd25519) Sign(msg []byte) Signature -``` - - - -### func (PrivKeyEd25519) [String](/src/target/priv_key.go?s=2613:2658#L101) -``` go -func (privKey PrivKeyEd25519) String() string -``` - - - -### func (PrivKeyEd25519) [ToCurve25519](/src/target/priv_key.go?s=2399:2453#L94) -``` go -func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte -``` - - - -### func (\*PrivKeyEd25519) [UnmarshalJSON](/src/target/priv_key.go?s=2250:2306#L87) -``` go -func (p *PrivKeyEd25519) UnmarshalJSON(enc []byte) error -``` - - - -## type [PrivKeyS](/src/target/priv_key.go?s=929:962#L30) -``` go -type PrivKeyS struct { - PrivKey -} -``` -PrivKeyS add json serialization to PrivKey - - - - - - - - - - -### func (PrivKeyS) [Empty](/src/target/priv_key.go?s=1241:1271#L46) -``` go -func (p PrivKeyS) Empty() bool -``` - - - -### func (PrivKeyS) [MarshalJSON](/src/target/priv_key.go?s=964:1011#L34) -``` go -func (p PrivKeyS) MarshalJSON() ([]byte, error) -``` - - - -### func (\*PrivKeyS) [UnmarshalJSON](/src/target/priv_key.go?s=1057:1114#L38) -``` go -func (p *PrivKeyS) UnmarshalJSON(data []byte) (err error) -``` - - - -## type [PrivKeySecp256k1](/src/target/priv_key.go?s=3635:3665#L136) -``` go -type PrivKeySecp256k1 [32]byte -``` -Implements PrivKey - - - - - - - -### func [GenPrivKeySecp256k1](/src/target/priv_key.go?s=5071:5114#L194) -``` go -func GenPrivKeySecp256k1() PrivKeySecp256k1 -``` - -### func [GenPrivKeySecp256k1FromSecret](/src/target/priv_key.go?s=5436:5502#L204) -``` go -func GenPrivKeySecp256k1FromSecret(secret []byte) PrivKeySecp256k1 -``` -NOTE: secret should be the output of a KDF like bcrypt, -if it's derived from user input. - - - - - -### func (PrivKeySecp256k1) [Bytes](/src/target/priv_key.go?s=3667:3713#L138) -``` go -func (privKey PrivKeySecp256k1) Bytes() []byte -``` - - - -### func (PrivKeySecp256k1) [Equals](/src/target/priv_key.go?s=4235:4293#L158) -``` go -func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool -``` - - - -### func (PrivKeySecp256k1) [MarshalJSON](/src/target/priv_key.go?s=4426:4481#L166) -``` go -func (p PrivKeySecp256k1) MarshalJSON() ([]byte, error) -``` - - - -### func (PrivKeySecp256k1) [PubKey](/src/target/priv_key.go?s=4032:4079#L151) -``` go -func (privKey PrivKeySecp256k1) PubKey() PubKey -``` - - - -### func (PrivKeySecp256k1) [Sign](/src/target/priv_key.go?s=3772:3830#L142) -``` go -func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature -``` - - - -### func (PrivKeySecp256k1) [String](/src/target/priv_key.go?s=4673:4720#L177) -``` go -func (privKey PrivKeySecp256k1) String() string -``` - - - -### func (\*PrivKeySecp256k1) [UnmarshalJSON](/src/target/priv_key.go?s=4522:4580#L170) -``` go -func (p *PrivKeySecp256k1) UnmarshalJSON(enc []byte) error -``` - - - -## type [PubKey](/src/target/pub_key.go?s=361:506#L7) -``` go -type PubKey interface { - Address() []byte - Bytes() []byte - KeyString() string - VerifyBytes(msg []byte, sig Signature) bool - Equals(PubKey) bool -} -``` -PubKey is part of Account and Validator. - - - - - - - -### func [PubKeyFromBytes](/src/target/pub_key.go?s=1203:1270#L45) -``` go -func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) -``` - - - - -## type [PubKeyEd25519](/src/target/pub_key.go?s=1396:1423#L53) -``` go -type PubKeyEd25519 [32]byte -``` -Implements PubKey - - - - - - - - - - -### func (PubKeyEd25519) [Address](/src/target/pub_key.go?s=1425:1469#L55) -``` go -func (pubKey PubKeyEd25519) Address() []byte -``` - - - -### func (PubKeyEd25519) [Bytes](/src/target/pub_key.go?s=1789:1831#L68) -``` go -func (pubKey PubKeyEd25519) Bytes() []byte -``` - - - -### func (PubKeyEd25519) [Equals](/src/target/pub_key.go?s=3064:3117#L119) -``` go -func (pubKey PubKeyEd25519) Equals(other PubKey) bool -``` - - - -### func (PubKeyEd25519) [KeyString](/src/target/pub_key.go?s=2983:3029#L115) -``` go -func (pubKey PubKeyEd25519) KeyString() string -``` -Must return the full bytes in hex. -Used for map keying, etc. - - - - -### func (PubKeyEd25519) [MarshalJSON](/src/target/pub_key.go?s=2279:2331#L87) -``` go -func (p PubKeyEd25519) MarshalJSON() ([]byte, error) -``` - - - -### func (PubKeyEd25519) [String](/src/target/pub_key.go?s=2823:2866#L109) -``` go -func (pubKey PubKeyEd25519) String() string -``` - - - -### func (PubKeyEd25519) [ToCurve25519](/src/target/pub_key.go?s=2585:2637#L100) -``` go -func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte -``` -For use with golang/crypto/nacl/box -If error, returns nil. - - - - -### func (\*PubKeyEd25519) [UnmarshalJSON](/src/target/pub_key.go?s=2372:2427#L91) -``` go -func (p *PubKeyEd25519) UnmarshalJSON(enc []byte) error -``` - - - -### func (PubKeyEd25519) [VerifyBytes](/src/target/pub_key.go?s=1888:1960#L72) -``` go -func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool -``` - - - -## type [PubKeyS](/src/target/pub_key.go?s=841:872#L25) -``` go -type PubKeyS struct { - PubKey -} -``` -PubKeyS add json serialization to PubKey - - - - - - - - - - -### func (PubKeyS) [Empty](/src/target/pub_key.go?s=1144:1173#L41) -``` go -func (p PubKeyS) Empty() bool -``` - - - -### func (PubKeyS) [MarshalJSON](/src/target/pub_key.go?s=874:920#L29) -``` go -func (p PubKeyS) MarshalJSON() ([]byte, error) -``` - - - -### func (\*PubKeyS) [UnmarshalJSON](/src/target/pub_key.go?s=964:1020#L33) -``` go -func (p *PubKeyS) UnmarshalJSON(data []byte) (err error) -``` - - - -## type [PubKeySecp256k1](/src/target/pub_key.go?s=3401:3430#L132) -``` go -type PubKeySecp256k1 [33]byte -``` -Implements PubKey. -Compressed pubkey (just the x-cord), -prefixed with 0x02 or 0x03, depending on the y-cord. - - - - - - - - - - -### func (PubKeySecp256k1) [Address](/src/target/pub_key.go?s=3497:3543#L135) -``` go -func (pubKey PubKeySecp256k1) Address() []byte -``` -Implements Bitcoin style addresses: RIPEMD160(SHA256(pubkey)) - - - - -### func (PubKeySecp256k1) [Bytes](/src/target/pub_key.go?s=3774:3818#L145) -``` go -func (pubKey PubKeySecp256k1) Bytes() []byte -``` - - - -### func (PubKeySecp256k1) [Equals](/src/target/pub_key.go?s=4897:4952#L192) -``` go -func (pubKey PubKeySecp256k1) Equals(other PubKey) bool -``` - - - -### func (PubKeySecp256k1) [KeyString](/src/target/pub_key.go?s=4814:4862#L188) -``` go -func (pubKey PubKeySecp256k1) KeyString() string -``` -Must return the full bytes in hex. -Used for map keying, etc. - - - - -### func (PubKeySecp256k1) [MarshalJSON](/src/target/pub_key.go?s=4405:4459#L171) -``` go -func (p PubKeySecp256k1) MarshalJSON() ([]byte, error) -``` - - - -### func (PubKeySecp256k1) [String](/src/target/pub_key.go?s=4650:4695#L182) -``` go -func (pubKey PubKeySecp256k1) String() string -``` - - - -### func (\*PubKeySecp256k1) [UnmarshalJSON](/src/target/pub_key.go?s=4500:4557#L175) -``` go -func (p *PubKeySecp256k1) UnmarshalJSON(enc []byte) error -``` - - - -### func (PubKeySecp256k1) [VerifyBytes](/src/target/pub_key.go?s=3875:3949#L149) -``` go -func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool -``` - - - -## type [Signature](/src/target/signature.go?s=204:304#L3) -``` go -type Signature interface { - Bytes() []byte - IsZero() bool - String() string - Equals(Signature) bool -} -``` -Signature is a part of Txs and consensus Votes. - - - - - - - -### func [SignatureFromBytes](/src/target/signature.go?s=1031:1098#L40) -``` go -func SignatureFromBytes(sigBytes []byte) (sig Signature, err error) -``` - - - - -## type [SignatureEd25519](/src/target/signature.go?s=1221:1251#L48) -``` go -type SignatureEd25519 [64]byte -``` -Implements Signature - - - - - - - - - - -### func (SignatureEd25519) [Bytes](/src/target/signature.go?s=1253:1295#L50) -``` go -func (sig SignatureEd25519) Bytes() []byte -``` - - - -### func (SignatureEd25519) [Equals](/src/target/signature.go?s=1520:1576#L58) -``` go -func (sig SignatureEd25519) Equals(other Signature) bool -``` - - - -### func (SignatureEd25519) [IsZero](/src/target/signature.go?s=1352:1393#L54) -``` go -func (sig SignatureEd25519) IsZero() bool -``` - - - -### func (SignatureEd25519) [MarshalJSON](/src/target/signature.go?s=1701:1756#L66) -``` go -func (p SignatureEd25519) MarshalJSON() ([]byte, error) -``` - - - -### func (SignatureEd25519) [String](/src/target/signature.go?s=1420:1463#L56) -``` go -func (sig SignatureEd25519) String() string -``` - - - -### func (\*SignatureEd25519) [UnmarshalJSON](/src/target/signature.go?s=1797:1855#L70) -``` go -func (p *SignatureEd25519) UnmarshalJSON(enc []byte) error -``` - - - -## type [SignatureS](/src/target/signature.go?s=648:685#L20) -``` go -type SignatureS struct { - Signature -} -``` -SignatureS add json serialization to Signature - - - - - - - - - - -### func (SignatureS) [Empty](/src/target/signature.go?s=966:998#L36) -``` go -func (p SignatureS) Empty() bool -``` - - - -### func (SignatureS) [MarshalJSON](/src/target/signature.go?s=687:736#L24) -``` go -func (p SignatureS) MarshalJSON() ([]byte, error) -``` - - - -### func (\*SignatureS) [UnmarshalJSON](/src/target/signature.go?s=780:839#L28) -``` go -func (p *SignatureS) UnmarshalJSON(data []byte) (err error) -``` - - - -## type [SignatureSecp256k1](/src/target/signature.go?s=2013:2043#L80) -``` go -type SignatureSecp256k1 []byte -``` -Implements Signature - - - - - - - - - - -### func (SignatureSecp256k1) [Bytes](/src/target/signature.go?s=2045:2089#L82) -``` go -func (sig SignatureSecp256k1) Bytes() []byte -``` - - - -### func (SignatureSecp256k1) [Equals](/src/target/signature.go?s=2318:2376#L90) -``` go -func (sig SignatureSecp256k1) Equals(other Signature) bool -``` - - - -### func (SignatureSecp256k1) [IsZero](/src/target/signature.go?s=2146:2189#L86) -``` go -func (sig SignatureSecp256k1) IsZero() bool -``` - - - -### func (SignatureSecp256k1) [MarshalJSON](/src/target/signature.go?s=2502:2559#L97) -``` go -func (p SignatureSecp256k1) MarshalJSON() ([]byte, error) -``` - - - -### func (SignatureSecp256k1) [String](/src/target/signature.go?s=2216:2261#L88) -``` go -func (sig SignatureSecp256k1) String() string -``` - - - -### func (\*SignatureSecp256k1) [UnmarshalJSON](/src/target/signature.go?s=2597:2657#L101) -``` go -func (p *SignatureSecp256k1) UnmarshalJSON(enc []byte) error -``` - - - - - - - -- - - -Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) +## Importing it +`import "github.com/tendermint/go-crypto"` \ No newline at end of file From 1bc8de4caa844f8b64c120e65b047898f22b7f3e Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 6 Sep 2017 02:32:37 -0400 Subject: [PATCH 114/287] remove String() from Signature. closes #29 --- signature.go | 1 - 1 file changed, 1 deletion(-) diff --git a/signature.go b/signature.go index 1c5b8d69e..5b1d6cb05 100644 --- a/signature.go +++ b/signature.go @@ -23,7 +23,6 @@ type SignatureInner interface { AssertIsSignatureInner() Bytes() []byte IsZero() bool - String() string Equals(Signature) bool Wrap() Signature } From 54260853d55178ce90c10f2c8b76327386403d9a Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 29 Aug 2017 20:42:50 +0200 Subject: [PATCH 115/287] encoder accepts empty string as unencoded bytes --- keys/cryptostore/encoder.go | 18 ++++++++++----- keys/cryptostore/encoder_test.go | 39 ++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/keys/cryptostore/encoder.go b/keys/cryptostore/encoder.go index 12792813c..31cbc2e54 100644 --- a/keys/cryptostore/encoder.go +++ b/keys/cryptostore/encoder.go @@ -28,18 +28,24 @@ func secret(passphrase string) []byte { type secretbox struct{} func (e secretbox) Encrypt(key crypto.PrivKey, pass string) ([]byte, error) { + if pass == "" { + return key.Bytes(), nil + } s := secret(pass) cipher := crypto.EncryptSymmetric(key.Bytes(), s) return cipher, nil } -func (e secretbox) Decrypt(data []byte, pass string) (crypto.PrivKey, error) { - s := secret(pass) - private, err := crypto.DecryptSymmetric(data, s) - if err != nil { - return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") +func (e secretbox) Decrypt(data []byte, pass string) (key crypto.PrivKey, err error) { + private := data + if pass != "" { + s := secret(pass) + private, err = crypto.DecryptSymmetric(data, s) + if err != nil { + return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") + } } - key, err := crypto.PrivKeyFromBytes(private) + key, err = crypto.PrivKeyFromBytes(private) return key, errors.Wrap(err, "Invalid Passphrase") } diff --git a/keys/cryptostore/encoder_test.go b/keys/cryptostore/encoder_test.go index 945e19865..f468591f3 100644 --- a/keys/cryptostore/encoder_test.go +++ b/keys/cryptostore/encoder_test.go @@ -60,3 +60,42 @@ func TestSecretBox(t *testing.T) { require.Nil(err) assert.Equal(key, pk) } + +func TestSecretBoxNoPass(t *testing.T) { + assert, require := assert.New(t), require.New(t) + enc := cryptostore.SecretBox + + key := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) + + cases := []struct { + encode string + decode string + valid bool + }{ + {"foo", "foo", true}, + {"foo", "food", false}, + {"", "", true}, + {"", "a", false}, + {"a", "", false}, + } + + for i, tc := range cases { + b, err := enc.Encrypt(key, tc.encode) + require.Nil(err, "%d: %+v", i, err) + assert.NotEmpty(b, "%d", i) + + pk, err := enc.Decrypt(b, tc.decode) + if tc.valid { + require.Nil(err, "%d: %+v", i, err) + assert.Equal(key, pk, "%d", i) + } else { + require.NotNil(err, "%d", i) + } + } + + // now let's make sure raw bytes also work... + b := key.Bytes() + pk, err := enc.Decrypt(b, "") + require.Nil(err, "%+v", err) + assert.Equal(key, pk) +} From e283f580b79a18c535efafa11588b641f0017931 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 29 Aug 2017 20:49:04 +0200 Subject: [PATCH 116/287] Test importing raw private key --- keys/cryptostore/holder_test.go | 39 ++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index c17eef24b..434966f46 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -5,6 +5,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + cmn "github.com/tendermint/tmlibs/common" + crypto "github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto/keys" "github.com/tendermint/go-crypto/keys/cryptostore" @@ -148,6 +151,32 @@ func assertPassword(assert *assert.Assertions, cstore cryptostore.Manager, name, assert.Nil(err, "%+v", err) } +// TestImportUnencrypted tests accepting raw priv keys bytes as input +func TestImportUnencrypted(t *testing.T) { + require := require.New(t) + + // make the storage with reasonable defaults + cstore := cryptostore.New( + cryptostore.SecretBox, + memstorage.New(), + keys.MustLoadCodec("english"), + ) + + key := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) + addr := key.PubKey().Address() + name := "john" + pass := "top-secret" + + // import raw bytes + err := cstore.Import(name, pass, "", key.Bytes()) + require.Nil(err, "%+v", err) + + // make sure the address matches + info, err := cstore.Get(name) + require.Nil(err, "%+v", err) + require.EqualValues(addr, info.Address) +} + // TestAdvancedKeyManagement verifies update, import, export functionality func TestAdvancedKeyManagement(t *testing.T) { assert, require := assert.New(t), require.New(t) @@ -190,16 +219,6 @@ func TestAdvancedKeyManagement(t *testing.T) { // import fails on bad transfer pass err = cstore.Import(n2, p3, p2, exported) assert.NotNil(err) - // import cannot overwrite existing keys - err = cstore.Import(n1, p3, pt, exported) - assert.NotNil(err) - // we can now import under another name - err = cstore.Import(n2, p3, pt, exported) - require.Nil(err, "%+v", err) - - // make sure both passwords are now properly set (not to the transfer pass) - assertPassword(assert, cstore, n1, p2, pt) - assertPassword(assert, cstore, n2, p3, pt) } // TestSeedPhrase verifies restoring from a seed phrase From 21f6b346a3799ab05bcf875dbc9149a3b73c587c Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Fri, 8 Sep 2017 20:26:56 +0200 Subject: [PATCH 117/287] Removed all cli as it goes into cosmos-sdk --- Makefile | 18 +----- cmd/README.md | 117 -------------------------------------- cmd/delete.go | 49 ---------------- cmd/get.go | 42 -------------- cmd/keys/main.go | 30 ---------- cmd/list.go | 34 ----------- cmd/new.go | 94 ------------------------------- cmd/recover.go | 61 -------------------- cmd/root.go | 50 ---------------- cmd/serve.go | 110 ------------------------------------ cmd/update.go | 53 ----------------- cmd/utils.go | 144 ----------------------------------------------- tests/keys.sh | 142 ---------------------------------------------- 13 files changed, 2 insertions(+), 942 deletions(-) delete mode 100644 cmd/README.md delete mode 100644 cmd/delete.go delete mode 100644 cmd/get.go delete mode 100644 cmd/keys/main.go delete mode 100644 cmd/list.go delete mode 100644 cmd/new.go delete mode 100644 cmd/recover.go delete mode 100644 cmd/root.go delete mode 100644 cmd/serve.go delete mode 100644 cmd/update.go delete mode 100644 cmd/utils.go delete mode 100755 tests/keys.sh diff --git a/Makefile b/Makefile index 8387f0608..0f414e1c2 100644 --- a/Makefile +++ b/Makefile @@ -5,24 +5,10 @@ GOTOOLS = \ github.com/jteeuwen/go-bindata/go-bindata REPO:=github.com/tendermint/go-crypto -all: get_vendor_deps install test +all: get_vendor_deps test -install: - go install ./cmd/keys - -test: test_unit test_cli - -test_unit: +test: go test `glide novendor` - #go run tests/tendermint/*.go - -test_cli: tests/shunit2 - # sudo apt-get install jq - @./tests/keys.sh - -tests/shunit2: - wget "https://raw.githubusercontent.com/kward/shunit2/master/source/2.1/src/shunit2" \ - -q -O tests/shunit2 get_vendor_deps: ensure_tools @rm -rf vendor/ diff --git a/cmd/README.md b/cmd/README.md deleted file mode 100644 index 8bf9ca73b..000000000 --- a/cmd/README.md +++ /dev/null @@ -1,117 +0,0 @@ -# Keys CLI - -This is as much an example how to expose cobra/viper, as for a cli itself -(I think this code is overkill for what go-keys needs). But please look at -the commands, and give feedback and changes. - -`RootCmd` calls some initialization functions (`cobra.OnInitialize` and `RootCmd.PersistentPreRunE`) which serve to connect environmental variables and cobra flags, as well as load the config file. It also validates the flags registered on root and creates the cryptomanager, which will be used by all subcommands. - -## Help info - -``` -# keys help - -Keys allows you to manage your local keystore for tendermint. - -These keys may be in any format supported by go-crypto and can be -used by light-clients, full nodes, or any other application that -needs to sign with a private key. - -Usage: - keys [command] - -Available Commands: - get Get details of one key - list List all keys - new Create a new public/private key pair - serve Run the key manager as an http server - update Change the password for a private key - -Flags: - --keydir string Directory to store private keys (subdir of root) (default "keys") - -o, --output string Output format (text|json) (default "text") - -r, --root string root directory for config and data (default "/Users/ethan/.tlc") - -Use "keys [command] --help" for more information about a command. -``` - -## Getting the config file - -The first step is to load in root, by checking the following in order: - -* -r, --root command line flag -* TM_ROOT environmental variable -* default ($HOME/.tlc evaluated at runtime) - -Once the `rootDir` is established, the script looks for a config file named `keys.{json,toml,yaml,hcl}` in that directory and parses it. These values will provide defaults for flags of the same name. - -There is an example config file for testing out locally, which writes keys to `./.mykeys`. You can - -## Getting/Setting variables - -When we want to get the value of a user-defined variable (eg. `output`), we can call `viper.GetString("output")`, which will do the following checks, until it finds a match: - -* Is `--output` command line flag present? -* Is `TM_OUTPUT` environmental variable set? -* Was a config file found and does it have an `output` variable? -* Is there a default set on the command line flag? - -If no variable is set and there was no default, we get back "". - -This setup allows us to have powerful command line flags, but use env variables or config files (local or 12-factor style) to avoid passing these arguments every time. - -## Nesting structures - -Sometimes we don't just need key-value pairs, but actually a multi-level config file, like - -``` -[mail] -from = "no-reply@example.com" -server = "mail.example.com" -port = 567 -password = "XXXXXX" -``` - -This CLI is too simple to warant such a structure, but I think eg. tendermint could benefit from such an approach. Here are some pointers: - -* [Accessing nested keys from config files](https://github.com/spf13/viper#accessing-nested-keys) -* [Overriding nested values with envvars](https://www.netlify.com/blog/2016/09/06/creating-a-microservice-boilerplate-in-go/#nested-config-values) - the mentioned outstanding PR is already merged into master! -* Overriding nested values with cli flags? (use `--log_config.level=info` ??) - -I'd love to see an example of this fully worked out in a more complex CLI. - -## Have your cake and eat it too - -It's easy to render data different ways. Some better for viewing, some better for importing to other programs. You can just add some global (persistent) flags to control the output formatting, and everyone gets what they want. - -``` -# keys list -e hex -All keys: -betty d0789984492b1674e276b590d56b7ae077f81adc -john b77f4720b220d1411a649b6c7f1151eb6b1c226a - -# keys list -e btc -All keys: -betty 3uTF4r29CbtnzsNHZoPSYsE4BDwH -john 3ZGp2Md35iw4XVtRvZDUaAEkCUZP - -# keys list -e b64 -o json -[ - { - "name": "betty", - "address": "0HiZhEkrFnTidrWQ1Wt64Hf4Gtw=", - "pubkey": { - "type": "secp256k1", - "data": "F83WvhT0KwttSoqQqd_0_r2ztUUaQix5EXdO8AZyREoV31Og780NW59HsqTAb2O4hZ-w-j0Z-4b2IjfdqqfhVQ==" - } - }, - { - "name": "john", - "address": "t39HILIg0UEaZJtsfxFR62scImo=", - "pubkey": { - "type": "ed25519", - "data": "t1LFmbg_8UTwj-n1wkqmnTp6NfaOivokEhlYySlGYCY=" - } - } -] -``` diff --git a/cmd/delete.go b/cmd/delete.go deleted file mode 100644 index 033cf2768..000000000 --- a/cmd/delete.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright © 2017 Ethan Frey -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cmd - -import ( - "fmt" - - "github.com/pkg/errors" - - "github.com/spf13/cobra" -) - -// deleteCmd represents the delete command -var deleteCmd = &cobra.Command{ - Use: "delete [name]", - Short: "DANGER: Delete a private key from your system", - RunE: runDeleteCmd, -} - -func runDeleteCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide a name for the key") - } - name := args[0] - - oldpass, err := getPassword("DANGER - enter password to permanently delete key:") - if err != nil { - return err - } - - err = GetKeyManager().Delete(name, oldpass) - if err != nil { - return err - } - fmt.Println("Password deleted forever (uh oh!)") - return nil -} diff --git a/cmd/get.go b/cmd/get.go deleted file mode 100644 index dfade2b74..000000000 --- a/cmd/get.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright © 2017 Ethan Frey -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cmd - -import ( - "github.com/pkg/errors" - - "github.com/spf13/cobra" -) - -// getCmd represents the get command -var getCmd = &cobra.Command{ - Use: "get [name]", - Short: "Get details of one key", - Long: `Return public details of one local key.`, - RunE: runGetCmd, -} - -func runGetCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide a name for the key") - } - name := args[0] - - info, err := GetKeyManager().Get(name) - if err == nil { - printInfo(info) - } - return err -} diff --git a/cmd/keys/main.go b/cmd/keys/main.go deleted file mode 100644 index 8780f7bbc..000000000 --- a/cmd/keys/main.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright © 2017 Ethan Frey -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "os" - - "github.com/tendermint/go-crypto/cmd" - "github.com/tendermint/tmlibs/cli" -) - -func main() { - // for demos, we enable the key server, probably don't want this - // in most binaries we embed the key management into - cmd.RegisterServer() - root := cli.PrepareMainCmd(cmd.RootCmd, "TM", os.ExpandEnv("$HOME/.tlc")) - root.Execute() -} diff --git a/cmd/list.go b/cmd/list.go deleted file mode 100644 index 51eeeda12..000000000 --- a/cmd/list.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright © 2017 Ethan Frey -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cmd - -import "github.com/spf13/cobra" - -// listCmd represents the list command -var listCmd = &cobra.Command{ - Use: "list", - Short: "List all keys", - Long: `Return a list of all public keys stored by this key manager -along with their associated name and address.`, - RunE: runListCmd, -} - -func runListCmd(cmd *cobra.Command, args []string) error { - infos, err := GetKeyManager().List() - if err == nil { - printInfos(infos) - } - return err -} diff --git a/cmd/new.go b/cmd/new.go deleted file mode 100644 index ce4634074..000000000 --- a/cmd/new.go +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright © 2017 Ethan Frey -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cmd - -import ( - "fmt" - - "github.com/pkg/errors" - "github.com/tendermint/go-crypto/keys" - "github.com/tendermint/go-wire/data" - "github.com/tendermint/tmlibs/cli" - - "github.com/spf13/cobra" - "github.com/spf13/viper" -) - -const ( - flagType = "type" - flagNoBackup = "no-backup" -) - -// newCmd represents the new command -var newCmd = &cobra.Command{ - Use: "new [name]", - Short: "Create a new public/private key pair", - Long: `Add a public/private key pair to the key store. -The password muts be entered in the terminal and not -passed as a command line argument for security.`, - RunE: runNewCmd, -} - -func init() { - newCmd.Flags().StringP(flagType, "t", "ed25519", "Type of key (ed25519|secp256k1)") - newCmd.Flags().Bool(flagNoBackup, false, "Don't print out seed phrase (if others are watching the terminal)") -} - -func runNewCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide a name for the key") - } - name := args[0] - algo := viper.GetString(flagType) - - pass, err := getCheckPassword("Enter a passphrase:", "Repeat the passphrase:") - if err != nil { - return err - } - - info, seed, err := GetKeyManager().Create(name, pass, algo) - if err == nil { - printCreate(info, seed) - } - return err -} - -type NewOutput struct { - Key keys.Info `json:"key"` - Seed string `json:"seed"` -} - -func printCreate(info keys.Info, seed string) { - switch viper.Get(cli.OutputFlag) { - case "text": - printInfo(info) - // print seed unless requested not to. - if !viper.GetBool(flagNoBackup) { - fmt.Println("**Important** write this seed phrase in a safe place.") - fmt.Println("It is the only way to recover your account if you ever forget your password.\n") - fmt.Println(seed) - } - case "json": - out := NewOutput{Key: info} - if !viper.GetBool(flagNoBackup) { - out.Seed = seed - } - json, err := data.ToJSON(out) - if err != nil { - panic(err) // really shouldn't happen... - } - fmt.Println(string(json)) - } -} diff --git a/cmd/recover.go b/cmd/recover.go deleted file mode 100644 index 4896c4e05..000000000 --- a/cmd/recover.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright © 2017 Ethan Frey -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cmd - -import ( - "github.com/pkg/errors" - - "github.com/spf13/cobra" -) - -// recoverCmd represents the recover command -var recoverCmd = &cobra.Command{ - Use: "recover [name]", - Short: "Recover a private key from a seed phrase", - Long: `Recover a private key from a seed phrase. - -I really hope you wrote this down when you created the new key. -The seed is only displayed on creation, never again. - -You can also use this to copy a key between multiple testnets, -simply by "recovering" the key in the other nets you want to copy -to. Of course, it has no coins on the other nets, just the same address.`, - RunE: runRecoverCmd, -} - -func runRecoverCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide a name for the key") - } - name := args[0] - - pass, err := getPassword("Enter the new passphrase:") - if err != nil { - return err - } - - // not really a password... huh? - seed, err := getSeed("Enter your recovery seed phrase:") - if err != nil { - return err - } - - info, err := GetKeyManager().Recover(name, pass, seed) - if err != nil { - return err - } - printInfo(info) - return nil -} diff --git a/cmd/root.go b/cmd/root.go deleted file mode 100644 index cfd3d1adf..000000000 --- a/cmd/root.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright © 2017 Ethan Frey -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cmd - -import ( - "github.com/spf13/cobra" - keys "github.com/tendermint/go-crypto/keys" -) - -const KeySubdir = "keys" - -var ( - manager keys.Manager -) - -// RootCmd represents the base command when called without any subcommands -var RootCmd = &cobra.Command{ - Use: "keys", - Short: "Key manager for tendermint clients", - Long: `Keys allows you to manage your local keystore for tendermint. - -These keys may be in any format supported by go-crypto and can be -used by light-clients, full nodes, or any other application that -needs to sign with a private key.`, -} - -func init() { - RootCmd.AddCommand(getCmd) - RootCmd.AddCommand(listCmd) - RootCmd.AddCommand(newCmd) - RootCmd.AddCommand(updateCmd) - RootCmd.AddCommand(deleteCmd) - RootCmd.AddCommand(recoverCmd) -} - -func RegisterServer() { - RootCmd.AddCommand(serveCmd) -} diff --git a/cmd/serve.go b/cmd/serve.go deleted file mode 100644 index 8cf7d12d4..000000000 --- a/cmd/serve.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright © 2017 Ethan Frey -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cmd - -import ( - "fmt" - "net" - "net/http" - "os" - - "github.com/gorilla/handlers" - "github.com/gorilla/mux" - "github.com/pkg/errors" - "github.com/spf13/cobra" - "github.com/spf13/viper" - "github.com/tendermint/go-crypto/keys/server" -) - -const ( - flagPort = "port" - flagSocket = "socket" -) - -// serveCmd represents the serve command -var serveCmd = &cobra.Command{ - Use: "serve", - Short: "Run the key manager as an http server", - Long: `Launch an http server with a rest api to manage the -private keys much more in depth than the cli can perform. -In particular, this will allow you to sign transactions with -the private keys in the store.`, - RunE: runServeCmd, -} - -func init() { - serveCmd.Flags().IntP(flagPort, "p", 8118, "TCP Port for listen for http server") - serveCmd.Flags().StringP(flagSocket, "s", "", "UNIX socket for more secure http server") - serveCmd.Flags().StringP(flagType, "t", "ed25519", "Default key type (ed25519|secp256k1)") -} - -func runServeCmd(cmd *cobra.Command, args []string) error { - var l net.Listener - var err error - socket := viper.GetString(flagSocket) - if socket != "" { - l, err = createSocket(socket) - if err != nil { - return errors.Wrap(err, "Cannot create socket") - } - } else { - port := viper.GetInt(flagPort) - l, err = net.Listen("tcp", fmt.Sprintf(":%d", port)) - if err != nil { - return errors.Errorf("Cannot listen on port %d", port) - } - } - - router := mux.NewRouter() - ks := server.New(GetKeyManager(), viper.GetString(flagType)) - ks.Register(router) - - // only set cors for tcp listener - var h http.Handler - if socket == "" { - allowedHeaders := handlers.AllowedHeaders([]string{"Content-Type"}) - h = handlers.CORS(allowedHeaders)(router) - } else { - h = router - } - - err = http.Serve(l, h) - fmt.Printf("Server Killed: %+v\n", err) - return nil -} - -// createSocket deletes existing socket if there, creates a new one, -// starts a server on the socket, and sets permissions to 0600 -func createSocket(socket string) (net.Listener, error) { - err := os.Remove(socket) - if err != nil && !os.IsNotExist(err) { - // only fail if it does exist and cannot be deleted - return nil, err - } - - l, err := net.Listen("unix", socket) - if err != nil { - return nil, err - } - - mode := os.FileMode(0700) | os.ModeSocket - err = os.Chmod(socket, mode) - if err != nil { - l.Close() - return nil, err - } - - return l, nil -} diff --git a/cmd/update.go b/cmd/update.go deleted file mode 100644 index f31af509c..000000000 --- a/cmd/update.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright © 2017 Ethan Frey -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cmd - -import ( - "fmt" - - "github.com/pkg/errors" - - "github.com/spf13/cobra" -) - -// updateCmd represents the update command -var updateCmd = &cobra.Command{ - Use: "update [name]", - Short: "Change the password for a private key", - RunE: runUpdateCmd, -} - -func runUpdateCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide a name for the key") - } - name := args[0] - - oldpass, err := getPassword("Enter the current passphrase:") - if err != nil { - return err - } - newpass, err := getCheckPassword("Enter the new passphrase:", "Repeat the new passphrase:") - if err != nil { - return err - } - - err = GetKeyManager().Update(name, oldpass, newpass) - if err != nil { - return err - } - fmt.Println("Password successfully updated!") - return nil -} diff --git a/cmd/utils.go b/cmd/utils.go deleted file mode 100644 index b1550a127..000000000 --- a/cmd/utils.go +++ /dev/null @@ -1,144 +0,0 @@ -package cmd - -import ( - "bufio" - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/bgentry/speakeasy" - "github.com/mattn/go-isatty" - "github.com/pkg/errors" - "github.com/spf13/viper" - - data "github.com/tendermint/go-wire/data" - "github.com/tendermint/tmlibs/cli" - - keys "github.com/tendermint/go-crypto/keys" - "github.com/tendermint/go-crypto/keys/cryptostore" - "github.com/tendermint/go-crypto/keys/storage/filestorage" -) - -const MinPassLength = 10 - -// GetKeyManager initializes a key manager based on the configuration -func GetKeyManager() keys.Manager { - if manager == nil { - // store the keys directory - rootDir := viper.GetString(cli.HomeFlag) - keyDir := filepath.Join(rootDir, KeySubdir) - - // TODO: smarter loading??? with language and fallback? - codec := keys.MustLoadCodec("english") - - // and construct the key manager - manager = cryptostore.New( - cryptostore.SecretBox, - filestorage.New(keyDir), - codec, - ) - } - return manager -} - -// if we read from non-tty, we just need to init the buffer reader once, -// in case we try to read multiple passwords (eg. update) -var buf *bufio.Reader - -func inputIsTty() bool { - return isatty.IsTerminal(os.Stdin.Fd()) || isatty.IsCygwinTerminal(os.Stdin.Fd()) -} - -func stdinPassword() (string, error) { - if buf == nil { - buf = bufio.NewReader(os.Stdin) - } - pass, err := buf.ReadString('\n') - if err != nil { - return "", err - } - return strings.TrimSpace(pass), nil -} - -func getPassword(prompt string) (pass string, err error) { - if inputIsTty() { - pass, err = speakeasy.Ask(prompt) - } else { - pass, err = stdinPassword() - } - if err != nil { - return "", err - } - if len(pass) < MinPassLength { - return "", errors.Errorf("Password must be at least %d characters", MinPassLength) - } - return pass, nil -} - -func getSeed(prompt string) (seed string, err error) { - if inputIsTty() { - fmt.Println(prompt) - } - seed, err = stdinPassword() - seed = strings.TrimSpace(seed) - return -} - -func getCheckPassword(prompt, prompt2 string) (string, error) { - // simple read on no-tty - if !inputIsTty() { - return getPassword(prompt) - } - - // TODO: own function??? - pass, err := getPassword(prompt) - if err != nil { - return "", err - } - pass2, err := getPassword(prompt2) - if err != nil { - return "", err - } - if pass != pass2 { - return "", errors.New("Passphrases don't match") - } - return pass, nil -} - -func printInfo(info keys.Info) { - switch viper.Get(cli.OutputFlag) { - case "text": - addr, err := data.ToText(info.Address) - if err != nil { - panic(err) // really shouldn't happen... - } - sep := "\t\t" - if len(info.Name) > 7 { - sep = "\t" - } - fmt.Printf("%s%s%s\n", info.Name, sep, addr) - case "json": - json, err := data.ToJSON(info) - if err != nil { - panic(err) // really shouldn't happen... - } - fmt.Println(string(json)) - } -} - -func printInfos(infos keys.Infos) { - switch viper.Get(cli.OutputFlag) { - case "text": - fmt.Println("All keys:") - for _, i := range infos { - printInfo(i) - } - case "json": - json, err := data.ToJSON(infos) - if err != nil { - panic(err) // really shouldn't happen... - } - fmt.Println(string(json)) - } -} diff --git a/tests/keys.sh b/tests/keys.sh deleted file mode 100755 index 599f3d743..000000000 --- a/tests/keys.sh +++ /dev/null @@ -1,142 +0,0 @@ -#!/bin/bash - -EXE=keys - -oneTimeSetUp() { - PASS=qwertyuiop - export TM_HOME=$HOME/.keys_test - rm -rf $TM_HOME - assertTrue $? -} - -newKey(){ - assertNotNull "keyname required" "$1" - KEYPASS=${2:-qwertyuiop} - KEY=$(echo $KEYPASS | ${EXE} new $1 -o json) - if ! assertTrue "created $1" $?; then return 1; fi - assertEquals "$1" $(echo $KEY | jq .key.name | tr -d \") - return $? -} - -# updateKey -updateKey() { - (echo $2; echo $3) | keys update $1 > /dev/null - return $? -} - -test00MakeKeys() { - USER=demouser - assertFalse "already user $USER" "${EXE} get $USER" - newKey $USER - assertTrue "no user $USER" "${EXE} get $USER" - # make sure bad password not accepted - assertFalse "accepts short password" "echo 123 | keys new badpass" -} - -test01ListKeys() { - # one line plus the number of keys - assertEquals "2" $(keys list | wc -l) - newKey foobar - assertEquals "3" $(keys list | wc -l) - # we got the proper name here... - assertEquals "foobar" $(keys list -o json | jq .[1].name | tr -d \" ) - # we get all names in normal output - EXPECTEDNAMES=$(echo demouser; echo foobar) - TEXTNAMES=$(keys list | tail -n +2 | cut -f1) - assertEquals "$EXPECTEDNAMES" "$TEXTNAMES" - # let's make sure the addresses match! - assertEquals "text and json addresses don't match" $(keys list | tail -1 | cut -f3) $(keys list -o json | jq .[1].address | tr -d \") -} - -test02updateKeys() { - USER=changer - PASS1=awsedrftgyhu - PASS2=S4H.9j.D9S7hso - PASS3=h8ybO7GY6d2 - - newKey $USER $PASS1 - assertFalse "accepts invalid pass" "updateKey $USER $PASS2 $PASS2" - assertTrue "doesn't update" "updateKey $USER $PASS1 $PASS2" - assertTrue "takes new key after update" "updateKey $USER $PASS2 $PASS3" -} - -test03recoverKeys() { - USER=sleepy - PASS1=S4H.9j.D9S7hso - - USER2=easy - PASS2=1234567890 - - # make a user and check they exist - KEY=$(echo $PASS1 | ${EXE} new $USER -o json) - if ! assertTrue "created $USER" $?; then return 1; fi - if [ -n "$DEBUG" ]; then echo $KEY; echo; fi - - SEED=$(echo $KEY | jq .seed | tr -d \") - ADDR=$(echo $KEY | jq .key.address | tr -d \") - PUBKEY=$(echo $KEY | jq .key.pubkey | tr -d \") - assertTrue "${EXE} get $USER > /dev/null" - - # let's delete this key - assertFalse "echo foo | ${EXE} delete $USER > /dev/null" - assertTrue "echo $PASS1 | ${EXE} delete $USER > /dev/null" - assertFalse "${EXE} get $USER > /dev/null" - - # fails on short password - assertFalse "echo foo; echo $SEED | ${EXE} recover $USER2 -o json > /dev/null" - # fails on bad seed - assertFalse "echo $PASS2; echo \"silly white whale tower bongo\" | ${EXE} recover $USER2 -o json > /dev/null" - # now we got it - KEY2=$((echo $PASS2; echo $SEED) | ${EXE} recover $USER2 -o json) - if ! assertTrue "recovery failed: $KEY2" $?; then return 1; fi - if [ -n "$DEBUG" ]; then echo $KEY2; echo; fi - - # make sure it looks the same - NAME2=$(echo $KEY2 | jq .name | tr -d \") - ADDR2=$(echo $KEY2 | jq .address | tr -d \") - PUBKEY2=$(echo $KEY2 | jq .pubkey | tr -d \") - assertEquals "wrong username" "$USER2" "$NAME2" - assertEquals "address doesn't match" "$ADDR" "$ADDR2" - assertEquals "pubkey doesn't match" "$PUBKEY" "$PUBKEY2" - - # and we can find the info - assertTrue "${EXE} get $USER2 > /dev/null" -} - -# try recovery with secp256k1 keys -test03recoverSecp() { - USER=dings - PASS1=Sbub-U9byS7hso - - USER2=booms - PASS2=1234567890 - - KEY=$(echo $PASS1 | ${EXE} new $USER -o json -t secp256k1) - if ! assertTrue "created $USER" $?; then return 1; fi - if [ -n "$DEBUG" ]; then echo $KEY; echo; fi - - SEED=$(echo $KEY | jq .seed | tr -d \") - ADDR=$(echo $KEY | jq .key.address | tr -d \") - PUBKEY=$(echo $KEY | jq .key.pubkey | tr -d \") - assertTrue "${EXE} get $USER > /dev/null" - - # now we got it - KEY2=$((echo $PASS2; echo $SEED) | ${EXE} recover $USER2 -o json) - if ! assertTrue "recovery failed: $KEY2" $?; then return 1; fi - if [ -n "$DEBUG" ]; then echo $KEY2; echo; fi - - # make sure it looks the same - NAME2=$(echo $KEY2 | jq .name | tr -d \") - ADDR2=$(echo $KEY2 | jq .address | tr -d \") - PUBKEY2=$(echo $KEY2 | jq .pubkey | tr -d \") - assertEquals "wrong username" "$USER2" "$NAME2" - assertEquals "address doesn't match" "$ADDR" "$ADDR2" - assertEquals "pubkey doesn't match" "$PUBKEY" "$PUBKEY2" - - # and we can find the info - assertTrue "${EXE} get $USER2 > /dev/null" -} - -# load and run these tests with shunit2! -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #get this files directory -. $DIR/shunit2 From c8b6d29161b9f5ca81585d55266916ccc89cd768 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 12 Sep 2017 19:31:00 -0400 Subject: [PATCH 118/287] version bump and changelog --- CHANGELOG.md | 18 ++++++++++++++++++ version.go | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 346d34fd1..798f74335 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## 0.3.0 (N/A) + +BREAKING CHANGES: + +- Remove `cmd` and `keys/tx` packages altogether: move it to the cosmos-sdk +- `cryptostore.Generator` takes a secret +- Remove `String()` from `Signature` interface + +FEATURES: + +- `keys`: add CRC16 error correcting code + +IMPROVEMENTS: + +- Allow no passwords on keys for development convenience + + + ## 0.2.1 (June 21, 2017) - Improve keys command diff --git a/version.go b/version.go index c785b1bca..23d065446 100644 --- a/version.go +++ b/version.go @@ -1,3 +1,3 @@ package crypto -const Version = "0.2.1" +const Version = "0.3.0" From 50e7c078170975532ca52004cb03a473afdebbff Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 13 Sep 2017 14:03:28 +0200 Subject: [PATCH 119/287] Use longer checksum again --- keys/wordcodec.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/keys/wordcodec.go b/keys/wordcodec.go index 214fe7e0b..c551e54ce 100644 --- a/keys/wordcodec.go +++ b/keys/wordcodec.go @@ -34,8 +34,8 @@ func NewCodec(words []string) (codec *WordCodec, err error) { res := &WordCodec{ words: words, // TODO: configure this outside??? - // check: NewIEEECRC32(), - check: NewIBMCRC16(), + check: NewIEEECRC32(), + // check: NewIBMCRC16(), } return res, nil From f6a250976439b2fd5f5b7b9e714d24220afc45e7 Mon Sep 17 00:00:00 2001 From: Emmanuel Odeke Date: Fri, 15 Sep 2017 17:07:14 -0600 Subject: [PATCH 120/287] doc.go file started Fixes #35 Updates https://github.com/tendermint/coding/issues/27 Started a doc.go file to provide an overview/high level dive into the functionality of this repo. Also added an example_test.go file in which we can put end-to-end code examples/actual usage patterns that can be copied and pasted and will always have to compile when tests are run to ensure that we don't regress. --- doc.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ example_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 doc.go create mode 100644 example_test.go diff --git a/doc.go b/doc.go new file mode 100644 index 000000000..c6701bc58 --- /dev/null +++ b/doc.go @@ -0,0 +1,48 @@ +/* +go-crypto is a customized/convenience cryptography package +for supporting Tendermint. + +It wraps select functionality of equivalent functions in the +Go standard library, for easy usage with our libraries. + +Keys: + +All key generation functions return an instance of the PrivKey interface +which implements methods + + AssertIsPrivKeyInner() + Bytes() []byte + Sign(msg []byte) Signature + PubKey() PubKey + Equals(PrivKey) bool + Wrap() PrivKey + +From the above method we can: +a) Retrieve the public key if needed + + pubKey := key.PubKey() + +For example: + privKey, err := crypto.GenPrivKeyEd25519() + if err != nil { + ... + } + pubKey := privKey.PubKey() + ... + // And then you can use the private and public key + doSomething(privKey, pubKey) + + +We also provide hashing wrappers around algorithms: + +Sha256 + sum := crypto.Sha256([]byte("This is Tendermint")) + fmt.Printf("%x\n", sum) + +Ripemd160 + sum := crypto.Ripemd160([]byte("This is consensus")) + fmt.Printf("%x\n", sum) +*/ +package crypto + +// TODO: Add more docs in here diff --git a/example_test.go b/example_test.go new file mode 100644 index 000000000..c9cd2688d --- /dev/null +++ b/example_test.go @@ -0,0 +1,35 @@ +// Copyright 2017 Tendermint. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package crypto_test + +import ( + "fmt" + + "github.com/tendermint/go-crypto" +) + +func Example_Sha256() { + sum := crypto.Sha256([]byte("This is Tendermint")) + fmt.Printf("%x\n", sum) + // Output: + // f91afb642f3d1c87c17eb01aae5cb65c242dfdbe7cf1066cc260f4ce5d33b94e +} + +func Example_Ripemd160() { + sum := crypto.Ripemd160([]byte("This is Tendermint")) + fmt.Printf("%x\n", sum) + // Output: + // 051e22663e8f0fd2f2302f1210f954adff009005 +} From e6ea9499ff958479e4a921850d2382eb599f204c Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 22 Sep 2017 10:22:55 -0400 Subject: [PATCH 121/287] glide and changelog --- CHANGELOG.md | 3 +-- glide.lock | 69 +++++++++++----------------------------------------- 2 files changed, 15 insertions(+), 57 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 798f74335..63d4af1d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 0.3.0 (N/A) +## 0.3.0 (September 22, 2017) BREAKING CHANGES: @@ -17,7 +17,6 @@ IMPROVEMENTS: - Allow no passwords on keys for development convenience - ## 0.2.1 (June 21, 2017) - Improve keys command diff --git a/glide.lock b/glide.lock index 4cd7c5670..1c23d8bea 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ hash: c0a2db1b80c6b1b8aab31c526ce43e22e49b23c893c78b8fdb8546aa2e7b7cc6 -updated: 2017-07-22T05:24:42.82932575-04:00 +updated: 2017-09-22T10:21:34.220901552-04:00 imports: - name: github.com/bgentry/speakeasy version: 4aabc24848ce5fd31929f7d1e4ea74d3709c14cd @@ -11,14 +11,16 @@ imports: - chaincfg/chainhash - wire - name: github.com/btcsuite/btcutil - version: 66871daeb12123ece012a9628d2798d01195c4b3 + version: 86346b5a958c0cf94186b87855469ae991be501c subpackages: - base58 - hdkeychain - name: github.com/btcsuite/fastsha256 version: 637e656429416087660c84436a2a035d69d54e2e -- name: github.com/fsnotify/fsnotify - version: 4da3e2cfbabc9f751898f250b49f2439785783a1 +- name: github.com/btcsuite/golangcrypto + version: 53f62d9b43e87a6c56975cf862af7edf33a8d0df + subpackages: + - ripemd160 - name: github.com/go-kit/kit version: d67bb4c202e3b91377d1079b110a6c9ce23ab2f8 subpackages: @@ -41,47 +43,14 @@ imports: version: a4043c62cc2329bacda331d33fc908ab11ef0ec3 - name: github.com/gorilla/mux version: bcd8bc72b08df0f70df986b97f95590779502d31 -- name: github.com/hashicorp/hcl - version: 392dba7d905ed5d04a5794ba89f558b27e2ba1ca - subpackages: - - hcl/ast - - hcl/parser - - hcl/scanner - - hcl/strconv - - hcl/token - - json/parser - - json/scanner - - json/token - name: github.com/howeyc/crc16 - version: 58da63c846043d0bea709c8d47039df06577d6d9 -- name: github.com/inconshreveable/mousetrap - version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 + version: 96a97a1abb579c7ff1a8ffa77f2e72d1c314b57f - name: github.com/kr/logfmt version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0 -- name: github.com/magiconair/properties - version: 51463bfca2576e06c62a8504b5c0f06d61312647 -- name: github.com/mattn/go-isatty - version: 9622e0cc9d8f9be434ca605520ff9a16808fee47 -- name: github.com/mitchellh/mapstructure - version: cc8532a8e9a55ea36402aa21efdf403a60d34096 -- name: github.com/pelletier/go-buffruneio - version: c37440a7cf42ac63b919c752ca73a85067e05992 -- name: github.com/pelletier/go-toml - version: 13d49d4606eb801b8f01ae542b4afc4c6ee3d84a - name: github.com/pkg/errors version: 645ef00459ed84a119197bfb8d8205042c6df63d -- name: github.com/spf13/afero - version: 9be650865eab0c12963d8753212f4f9c66cdcf12 - subpackages: - - mem -- name: github.com/spf13/cast - version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4 - name: github.com/spf13/cobra version: 4cdb38c072b86bf795d2c81de50784d9fdd6eb77 -- name: github.com/spf13/jwalterweatherman - version: 8f07c835e5cc1450c082fe3a439cf87b0cbb2d99 -- name: github.com/spf13/pflag - version: e57e3eeb33f795204c1ca35f56c44f83227c6e66 - name: github.com/spf13/viper version: 0967fc9aceab2ce9da34061253ac10fb99bba5b2 - name: github.com/tendermint/ed25519 @@ -95,9 +64,8 @@ imports: - data - data/base58 - name: github.com/tendermint/tmlibs - version: 2f6f3e6aa70bb19b70a6e73210273fa127041070 + version: bffe6744ec277d60f707ab442e25513617842f8e subpackages: - - cli - common - log - name: golang.org/x/crypto @@ -112,26 +80,17 @@ imports: - poly1305 - ripemd160 - salsa20/salsa -- name: golang.org/x/sys - version: e62c3de784db939836898e5c19ffd41bece347da - subpackages: - - unix -- name: golang.org/x/text - version: 470f45bf29f4147d6fbd7dfd0a02a848e49f5bf4 - subpackages: - - transform - - unicode/norm - name: gopkg.in/go-playground/validator.v9 - version: 6d8c18553ea1ac493d049edd6f102f52e618f085 -- name: gopkg.in/yaml.v2 - version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b + version: d529ee1b0f30352444f507cc6cdac96bfd12decc testImports: -- name: github.com/cmars/basen - version: fe3947df716ebfda9847eb1b9a48f9592e06478c - name: github.com/davecgh/go-spew version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 subpackages: - spew +- name: github.com/FactomProject/basen + version: fe3947df716ebfda9847eb1b9a48f9592e06478c +- name: github.com/FactomProject/btcutilecc + version: d3a63a5752ecf3fbc06bd97365da752111c263df - name: github.com/mndrix/btcutil version: d3a63a5752ecf3fbc06bd97365da752111c263df - name: github.com/pmezard/go-difflib @@ -144,6 +103,6 @@ testImports: - assert - require - name: github.com/tyler-smith/go-bip32 - version: eb790af526c30f23a7c8b00a48e342f9d0bd6386 + version: 2c9cfd17756470a0b7c3e4b7954bae7d11035504 - name: github.com/tyler-smith/go-bip39 version: 8e7a99b3e716f36d3b080a9a70f9eb45abe4edcc From fe66a683bcbb28d25a07299e45741a835cd13dbd Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Fri, 22 Sep 2017 13:31:01 -0400 Subject: [PATCH 122/287] linter: add metalinter to Makefile & apply some fixes --- Makefile | 38 ++++++++++++- _gen.go | 6 -- armor.go | 2 +- bcrypt/bcrypt.go | 2 +- hash.go | 1 + hd/address.go | 19 +------ hd/hd_test.go | 97 +------------------------------- keys/cryptostore/holder.go | 2 + keys/server/helpers.go | 4 +- keys/storage/filestorage/main.go | 5 +- keys/storage/memstorage/main.go | 1 + keys/wordcodec_test.go | 4 +- keys/wordlist/wordlist.go | 15 ++--- 13 files changed, 65 insertions(+), 131 deletions(-) delete mode 100644 _gen.go diff --git a/Makefile b/Makefile index 0f414e1c2..cdfee009b 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,9 @@ GOTOOLS = \ github.com/Masterminds/glide \ - github.com/jteeuwen/go-bindata/go-bindata + github.com/jteeuwen/go-bindata/go-bindata \ + github.com/alecthomas/gometalinter + REPO:=github.com/tendermint/go-crypto all: get_vendor_deps test @@ -31,3 +33,37 @@ codegen: @echo "--> regenerating all interface wrappers" @gen @echo "Done!" + +metalinter: ensure_tools + @gometalinter --install + gometalinter --vendor --deadline=600s --enable-all --disable=lll ./... + +metalinter_test: ensure_tools + @gometalinter --install + gometalinter --vendor --deadline=600s --disable-all \ + --enable=aligncheck \ + --enable=deadcode \ + --enable=gas \ + --enable=goconst \ + --enable=gocyclo \ + --enable=goimports \ + --enable=gosimple \ + --enable=gotype \ + --enable=ineffassign \ + --enable=interfacer \ + --enable=megacheck \ + --enable=misspell \ + --enable=safesql \ + --enable=staticcheck \ + --enable=structcheck \ + --enable=unconvert \ + --enable=unused \ + --enable=vetshadow \ + --enable=vet \ + --enable=unparam \ + --enable=varcheck \ + ./... + + #--enable=dupl \ + #--enable=errcheck \ + #--enable=golint \ <== comments on anything exported diff --git a/_gen.go b/_gen.go deleted file mode 100644 index a98feaf4e..000000000 --- a/_gen.go +++ /dev/null @@ -1,6 +0,0 @@ -package main - -import ( - _ "github.com/tendermint/go-wire/gen" - _ "github.com/clipperhouse/stringer" -) diff --git a/armor.go b/armor.go index 3d2eff5e7..5f199df43 100644 --- a/armor.go +++ b/armor.go @@ -22,7 +22,7 @@ func EncodeArmor(blockType string, headers map[string]string, data []byte) strin if err != nil { PanicSanity("Error encoding ascii armor: " + err.Error()) } - return string(buf.Bytes()) + return buf.String() } func DecodeArmor(armorStr string) (blockType string, headers map[string]string, data []byte, err error) { diff --git a/bcrypt/bcrypt.go b/bcrypt/bcrypt.go index a6b4a2cf6..6b23b7a9d 100644 --- a/bcrypt/bcrypt.go +++ b/bcrypt/bcrypt.go @@ -50,7 +50,7 @@ func (ih InvalidHashPrefixError) Error() string { type InvalidCostError int func (ic InvalidCostError) Error() string { - return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost)) + return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost)) // nolint: unconvert } const ( diff --git a/hash.go b/hash.go index 165b1e153..b04afe085 100644 --- a/hash.go +++ b/hash.go @@ -1,3 +1,4 @@ +// nolint: goimports package crypto import ( diff --git a/hd/address.go b/hd/address.go index d7553a4d7..b6532e351 100644 --- a/hd/address.go +++ b/hd/address.go @@ -11,7 +11,6 @@ import ( "errors" "fmt" "hash" - "log" "math/big" "strconv" "strings" @@ -88,18 +87,6 @@ func ComputeTxId(rawTxHex string) string { // Private methods... -func printKeyInfo(privKeyBytes []byte, pubKeyBytes []byte, chain []byte) { - if pubKeyBytes == nil { - pubKeyBytes = PubKeyBytesFromPrivKeyBytes(privKeyBytes, true) - } - addr := AddrFromPubKeyBytes(pubKeyBytes) - log.Println("\nprikey:\t%v\npubKeyBytes:\t%v\naddr:\t%v\nchain:\t%v", - HexEncode(privKeyBytes), - HexEncode(pubKeyBytes), - addr, - HexEncode(chain)) -} - func DerivePrivateKeyForPath(privKeyBytes []byte, chain []byte, path string) []byte { data := privKeyBytes parts := strings.Split(path, "/") @@ -144,7 +131,7 @@ func DerivePublicKeyForPath(pubKeyBytes []byte, chain []byte, path string) []byt } func DerivePrivateKey(privKeyBytes []byte, chain []byte, i uint32, prime bool) ([]byte, []byte) { - data := []byte{} + data := []byte{} // nolint [ megacheck, deadcode ] if prime { i = i | 0x80000000 data = append([]byte{byte(0)}, privKeyBytes...) @@ -177,7 +164,7 @@ func addPoints(a []byte, b []byte) []byte { panic(err) } sumX, sumY := btcec.S256().Add(ap.X, ap.Y, bp.X, bp.Y) - sum := (*btcec.PublicKey)(&btcec.PublicKey{ + sum := (*btcec.PublicKey)(&btcec.PublicKey{ // nolint: unconvert Curve: btcec.S256(), X: sumX, Y: sumY, @@ -248,7 +235,7 @@ func WIFFromPrivKeyBytes(privKeyBytes []byte, compress bool) string { func PubKeyBytesFromPrivKeyBytes(privKeyBytes []byte, compress bool) (pubKeyBytes []byte) { x, y := btcec.S256().ScalarBaseMult(privKeyBytes) - pub := (*btcec.PublicKey)(&btcec.PublicKey{ + pub := (*btcec.PublicKey)(&btcec.PublicKey{ // nolint: unconvert Curve: btcec.S256(), X: x, Y: y, diff --git a/hd/hd_test.go b/hd/hd_test.go index b2f7d2e8f..60d77ad66 100644 --- a/hd/hd_test.go +++ b/hd/hd_test.go @@ -1,10 +1,8 @@ +// nolint: goimports package hd import ( "bytes" - "crypto/hmac" - "crypto/sha512" - "encoding/binary" "encoding/hex" "encoding/json" "fmt" @@ -15,11 +13,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/tyler-smith/go-bip39" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcutil/hdkeychain" - "github.com/mndrix/btcutil" - "github.com/tyler-smith/go-bip32" - "github.com/tendermint/go-crypto" ) @@ -33,7 +26,7 @@ type addrData struct { } // NOTE: atom fundraiser address -var hdPath string = "m/44'/118'/0'/0/0" +// var hdPath string = "m/44'/118'/0'/0/0" var hdToAddrTable []addrData func init() { @@ -109,13 +102,6 @@ func TestReverseBytes(t *testing.T) { } } -func ifExit(err error, n int) { - if err != nil { - fmt.Println(n, err) - os.Exit(1) - } -} - func gocrypto(seed []byte) ([]byte, []byte, []byte) { _, priv, ch, _ := ComputeMastersFromSeed(string(seed)) @@ -131,83 +117,6 @@ func gocrypto(seed []byte) ([]byte, []byte, []byte) { return HexDecode(priv), privBytes, pubBytes } -func btcsuite(seed []byte) ([]byte, []byte, []byte) { - fmt.Println("HD") - masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams) - if err != nil { - hmac := hmac.New(sha512.New, []byte("Bitcoin seed")) - hmac.Write([]byte(seed)) - intermediary := hmac.Sum(nil) - - curve := btcutil.Secp256k1() - curveParams := curve.Params() - - // Split it into our key and chain code - keyBytes := intermediary[:32] - fmt.Printf("\t%X\n", keyBytes) - fmt.Printf("\t%X\n", curveParams.N.Bytes()) - keyInt, _ := binary.ReadVarint(bytes.NewBuffer(keyBytes)) - fmt.Printf("\t%d\n", keyInt) - } - fh := hdkeychain.HardenedKeyStart - k, err := masterKey.Child(uint32(fh + 44)) - ifExit(err, 44) - k, err = k.Child(uint32(fh + 118)) - ifExit(err, 118) - k, err = k.Child(uint32(fh + 0)) - ifExit(err, 1) - k, err = k.Child(uint32(0)) - ifExit(err, 2) - k, err = k.Child(uint32(0)) - ifExit(err, 3) - ecpriv, err := k.ECPrivKey() - ifExit(err, 10) - ecpub, err := k.ECPubKey() - ifExit(err, 11) - - priv := ecpriv.Serialize() - pub := ecpub.SerializeCompressed() - mkey, _ := masterKey.ECPrivKey() - return mkey.Serialize(), priv, pub -} - -// return priv and pub -func tylerSmith(seed []byte) ([]byte, []byte, []byte) { - masterKey, err := bip32.NewMasterKey(seed) - if err != nil { - hmac := hmac.New(sha512.New, []byte("Bitcoin seed")) - hmac.Write([]byte(seed)) - intermediary := hmac.Sum(nil) - - curve := btcutil.Secp256k1() - curveParams := curve.Params() - - // Split it into our key and chain code - keyBytes := intermediary[:32] - fmt.Printf("\t%X\n", keyBytes) - fmt.Printf("\t%X\n", curveParams.N.Bytes()) - keyInt, _ := binary.ReadVarint(bytes.NewBuffer(keyBytes)) - fmt.Printf("\t%d\n", keyInt) - - } - ifExit(err, 0) - fh := bip32.FirstHardenedChild - k, err := masterKey.NewChildKey(fh + 44) - ifExit(err, 44) - k, err = k.NewChildKey(fh + 118) - ifExit(err, 118) - k, err = k.NewChildKey(fh + 0) - ifExit(err, 1) - k, err = k.NewChildKey(0) - ifExit(err, 2) - k, err = k.NewChildKey(0) - ifExit(err, 3) - - priv := k.Key - pub := k.PublicKey().Key - return masterKey.Key, priv, pub -} - // Benchmarks var revBytesCases = [][]byte{ @@ -237,6 +146,6 @@ func BenchmarkReverseBytes(b *testing.B) { // sink is necessary to ensure if the compiler tries // to smart, that it won't optimize away the benchmarks. - if sink != nil { + if sink != nil { // nolint: megacheck } } diff --git a/keys/cryptostore/holder.go b/keys/cryptostore/holder.go index 18437a9b5..f9e5f5bb3 100644 --- a/keys/cryptostore/holder.go +++ b/keys/cryptostore/holder.go @@ -25,11 +25,13 @@ func New(coder Encoder, store keys.Storage, codec keys.Codec) Manager { } // exists just to make sure we fulfill the Signer interface +// nolint [ megacheck, deadcode ] func (s Manager) assertSigner() keys.Signer { return s } // exists just to make sure we fulfill the Manager interface +// nolint [ megacheck, deadcode ] func (s Manager) assertKeyManager() keys.Manager { return s } diff --git a/keys/server/helpers.go b/keys/server/helpers.go index 710e4f392..4820c937e 100644 --- a/keys/server/helpers.go +++ b/keys/server/helpers.go @@ -5,6 +5,8 @@ for key management, transaction signing, and query validation. Please read the README and godoc to see how to configure the server for your application. */ + +// nolint: goimports package server import ( @@ -12,8 +14,8 @@ import ( "io/ioutil" "net/http" - data "github.com/tendermint/go-wire/data" "github.com/tendermint/go-crypto/keys/server/types" + data "github.com/tendermint/go-wire/data" "github.com/pkg/errors" ) diff --git a/keys/storage/filestorage/main.go b/keys/storage/filestorage/main.go index 696b200fc..d8058a5b9 100644 --- a/keys/storage/filestorage/main.go +++ b/keys/storage/filestorage/main.go @@ -22,8 +22,8 @@ const ( PrivExt = "tlc" PubExt = "pub" keyPerm = os.FileMode(0600) - pubPerm = os.FileMode(0644) - dirPerm = os.FileMode(0700) + // pubPerm = os.FileMode(0644) + dirPerm = os.FileMode(0700) ) type FileStore struct { @@ -43,6 +43,7 @@ func New(dir string) FileStore { } // assertStorage just makes sure we implement the proper Storage interface +// nolint [ megacheck, deadcode ] func (s FileStore) assertStorage() keys.Storage { return s } diff --git a/keys/storage/memstorage/main.go b/keys/storage/memstorage/main.go index 195fa7a17..403a01318 100644 --- a/keys/storage/memstorage/main.go +++ b/keys/storage/memstorage/main.go @@ -23,6 +23,7 @@ func New() MemStore { } // assertStorage just makes sure we implement the Storage interface +// nolint [ megacheck, deadcode ] func (s MemStore) assertStorage() keys.Storage { return s } diff --git a/keys/wordcodec_test.go b/keys/wordcodec_test.go index 25c5439a6..a44607be2 100644 --- a/keys/wordcodec_test.go +++ b/keys/wordcodec_test.go @@ -119,8 +119,8 @@ func TestCheckInvalidLists(t *testing.T) { w, err := codec.BytesToWords(data) if tc.valid { assert.Nil(err, "%d: %+v", i, err) - b, err := codec.WordsToBytes(w) - assert.Nil(err, "%d: %+v", i, err) + b, err1 := codec.WordsToBytes(w) + assert.Nil(err1, "%d: %+v", i, err1) assert.Equal(data, b) } else { assert.NotNil(err, "%d", i) diff --git a/keys/wordlist/wordlist.go b/keys/wordlist/wordlist.go index 97ddb2369..915dda102 100644 --- a/keys/wordlist/wordlist.go +++ b/keys/wordlist/wordlist.go @@ -6,6 +6,7 @@ // keys/wordlist/spanish.txt // DO NOT EDIT! +// nolint: goimports package wordlist import ( @@ -204,9 +205,9 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ "keys/wordlist/chinese_simplified.txt": keysWordlistChinese_simplifiedTxt, - "keys/wordlist/english.txt": keysWordlistEnglishTxt, - "keys/wordlist/japanese.txt": keysWordlistJapaneseTxt, - "keys/wordlist/spanish.txt": keysWordlistSpanishTxt, + "keys/wordlist/english.txt": keysWordlistEnglishTxt, + "keys/wordlist/japanese.txt": keysWordlistJapaneseTxt, + "keys/wordlist/spanish.txt": keysWordlistSpanishTxt, } // AssetDir returns the file names below a certain @@ -248,13 +249,14 @@ type bintree struct { Func func() (*asset, error) Children map[string]*bintree } + var _bintree = &bintree{nil, map[string]*bintree{ "keys": &bintree{nil, map[string]*bintree{ "wordlist": &bintree{nil, map[string]*bintree{ "chinese_simplified.txt": &bintree{keysWordlistChinese_simplifiedTxt, map[string]*bintree{}}, - "english.txt": &bintree{keysWordlistEnglishTxt, map[string]*bintree{}}, - "japanese.txt": &bintree{keysWordlistJapaneseTxt, map[string]*bintree{}}, - "spanish.txt": &bintree{keysWordlistSpanishTxt, map[string]*bintree{}}, + "english.txt": &bintree{keysWordlistEnglishTxt, map[string]*bintree{}}, + "japanese.txt": &bintree{keysWordlistJapaneseTxt, map[string]*bintree{}}, + "spanish.txt": &bintree{keysWordlistSpanishTxt, map[string]*bintree{}}, }}, }}, }} @@ -305,4 +307,3 @@ func _filePath(dir, name string) string { cannonicalName := strings.Replace(name, "\\", "/", -1) return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) } - From 7921fb0c05c61cf55ad8dca18d492cea741e29dc Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Fri, 22 Sep 2017 13:35:02 -0400 Subject: [PATCH 123/287] linter: last fixes & add to circle --- Makefile | 2 +- keys/cryptostore/holder_test.go | 1 + keys/server/keys.go | 1 + keys/server/keys_test.go | 3 +++ 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index cdfee009b..4114de740 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ GOTOOLS = \ REPO:=github.com/tendermint/go-crypto -all: get_vendor_deps test +all: get_vendor_deps metalinter_test test test: go test `glide novendor` diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index 434966f46..0ef4ae4ba 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -144,6 +144,7 @@ func TestKeyManagement(t *testing.T) { // } // } +// nolint: unparam func assertPassword(assert *assert.Assertions, cstore cryptostore.Manager, name, pass, badpass string) { err := cstore.Update(name, badpass, pass) assert.NotNil(err) diff --git a/keys/server/keys.go b/keys/server/keys.go index 80852802e..cae3e451d 100644 --- a/keys/server/keys.go +++ b/keys/server/keys.go @@ -52,6 +52,7 @@ func (k Keys) GetKey(w http.ResponseWriter, r *http.Request) { writeSuccess(w, &key) } +// nolint: unparam func (k Keys) ListKeys(w http.ResponseWriter, r *http.Request) { keys, err := k.manager.List() diff --git a/keys/server/keys_test.go b/keys/server/keys_test.go index 2aa17753c..cad415644 100644 --- a/keys/server/keys_test.go +++ b/keys/server/keys_test.go @@ -120,6 +120,7 @@ func listKeys(h http.Handler) (keys.Infos, int, error) { return data, rr.Code, err } +// nolint: unparam func getKey(h http.Handler, name string) (*keys.Info, int, error) { rr := httptest.NewRecorder() req, err := http.NewRequest("GET", "/keys/"+name, nil) @@ -137,6 +138,7 @@ func getKey(h http.Handler, name string) (*keys.Info, int, error) { return &data, rr.Code, err } +// nolint: unparam func createKey(h http.Handler, name, passphrase, algo string) (*types.CreateKeyResponse, int, error) { rr := httptest.NewRecorder() post := types.CreateKeyRequest{ @@ -165,6 +167,7 @@ func createKey(h http.Handler, name, passphrase, algo string) (*types.CreateKeyR return data, rr.Code, err } +// nolint: unparam func deleteKey(h http.Handler, name, passphrase string) (*types.ErrorResponse, int, error) { rr := httptest.NewRecorder() post := types.DeleteKeyRequest{ From 87cb57c3e5e76cab8b766253c218ec7b68ecec09 Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Wed, 4 Oct 2017 18:16:48 -0400 Subject: [PATCH 124/287] linting: fixup some stuffs --- Makefile | 4 +- hash.go | 1 - hd/address.go | 24 ++++++-- hd/hd_test.go | 96 +++++++++++++++++++++++++++++++- keys/cryptostore/holder.go | 5 +- keys/cryptostore/holder_test.go | 1 - keys/server/helpers.go | 1 - keys/server/keys.go | 1 - keys/server/keys_test.go | 3 - keys/storage/filestorage/main.go | 3 +- keys/storage/memstorage/main.go | 3 +- keys/wordlist/wordlist.go | 1 - 12 files changed, 121 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 4114de740..b1dc51ae0 100644 --- a/Makefile +++ b/Makefile @@ -46,9 +46,7 @@ metalinter_test: ensure_tools --enable=gas \ --enable=goconst \ --enable=gocyclo \ - --enable=goimports \ --enable=gosimple \ - --enable=gotype \ --enable=ineffassign \ --enable=interfacer \ --enable=megacheck \ @@ -66,4 +64,6 @@ metalinter_test: ensure_tools #--enable=dupl \ #--enable=errcheck \ + #--enable=goimports \ #--enable=golint \ <== comments on anything exported + #--enable=gotype \ diff --git a/hash.go b/hash.go index b04afe085..165b1e153 100644 --- a/hash.go +++ b/hash.go @@ -1,4 +1,3 @@ -// nolint: goimports package crypto import ( diff --git a/hd/address.go b/hd/address.go index b6532e351..5b664b496 100644 --- a/hd/address.go +++ b/hd/address.go @@ -85,7 +85,19 @@ func ComputeTxId(rawTxHex string) string { return HexEncode(ReverseBytes(CalcHash256(HexDecode(rawTxHex)))) } -// Private methods... +/* +func printKeyInfo(privKeyBytes []byte, pubKeyBytes []byte, chain []byte) { + if pubKeyBytes == nil { + pubKeyBytes = PubKeyBytesFromPrivKeyBytes(privKeyBytes, true) + } + addr := AddrFromPubKeyBytes(pubKeyBytes) + log.Println("\nprikey:\t%v\npubKeyBytes:\t%v\naddr:\t%v\nchain:\t%v", + HexEncode(privKeyBytes), + HexEncode(pubKeyBytes), + addr, + HexEncode(chain)) +} +*/ func DerivePrivateKeyForPath(privKeyBytes []byte, chain []byte, path string) []byte { data := privKeyBytes @@ -131,7 +143,7 @@ func DerivePublicKeyForPath(pubKeyBytes []byte, chain []byte, path string) []byt } func DerivePrivateKey(privKeyBytes []byte, chain []byte, i uint32, prime bool) ([]byte, []byte) { - data := []byte{} // nolint [ megacheck, deadcode ] + var data []byte if prime { i = i | 0x80000000 data = append([]byte{byte(0)}, privKeyBytes...) @@ -164,11 +176,11 @@ func addPoints(a []byte, b []byte) []byte { panic(err) } sumX, sumY := btcec.S256().Add(ap.X, ap.Y, bp.X, bp.Y) - sum := (*btcec.PublicKey)(&btcec.PublicKey{ // nolint: unconvert + sum := &btcec.PublicKey{ Curve: btcec.S256(), X: sumX, Y: sumY, - }) + } return sum.SerializeCompressed() } @@ -235,11 +247,11 @@ func WIFFromPrivKeyBytes(privKeyBytes []byte, compress bool) string { func PubKeyBytesFromPrivKeyBytes(privKeyBytes []byte, compress bool) (pubKeyBytes []byte) { x, y := btcec.S256().ScalarBaseMult(privKeyBytes) - pub := (*btcec.PublicKey)(&btcec.PublicKey{ // nolint: unconvert + pub := &btcec.PublicKey{ Curve: btcec.S256(), X: x, Y: y, - }) + } if compress { return pub.SerializeCompressed() diff --git a/hd/hd_test.go b/hd/hd_test.go index 60d77ad66..fcb348b5c 100644 --- a/hd/hd_test.go +++ b/hd/hd_test.go @@ -1,8 +1,10 @@ -// nolint: goimports package hd import ( "bytes" + "crypto/hmac" + "crypto/sha512" + "encoding/binary" "encoding/hex" "encoding/json" "fmt" @@ -13,6 +15,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/tyler-smith/go-bip39" + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcutil/hdkeychain" + "github.com/mndrix/btcutil" + "github.com/tyler-smith/go-bip32" + "github.com/tendermint/go-crypto" ) @@ -102,6 +109,13 @@ func TestReverseBytes(t *testing.T) { } } +func ifExit(err error, n int) { + if err != nil { + fmt.Println(n, err) + os.Exit(1) + } +} + func gocrypto(seed []byte) ([]byte, []byte, []byte) { _, priv, ch, _ := ComputeMastersFromSeed(string(seed)) @@ -117,6 +131,83 @@ func gocrypto(seed []byte) ([]byte, []byte, []byte) { return HexDecode(priv), privBytes, pubBytes } +func btcsuite(seed []byte) ([]byte, []byte, []byte) { + fmt.Println("HD") + masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams) + if err != nil { + hmac := hmac.New(sha512.New, []byte("Bitcoin seed")) + hmac.Write([]byte(seed)) + intermediary := hmac.Sum(nil) + + curve := btcutil.Secp256k1() + curveParams := curve.Params() + + // Split it into our key and chain code + keyBytes := intermediary[:32] + fmt.Printf("\t%X\n", keyBytes) + fmt.Printf("\t%X\n", curveParams.N.Bytes()) + keyInt, _ := binary.ReadVarint(bytes.NewBuffer(keyBytes)) + fmt.Printf("\t%d\n", keyInt) + } + fh := hdkeychain.HardenedKeyStart + k, err := masterKey.Child(uint32(fh + 44)) + ifExit(err, 44) + k, err = k.Child(uint32(fh + 118)) + ifExit(err, 118) + k, err = k.Child(uint32(fh + 0)) + ifExit(err, 1) + k, err = k.Child(uint32(0)) + ifExit(err, 2) + k, err = k.Child(uint32(0)) + ifExit(err, 3) + ecpriv, err := k.ECPrivKey() + ifExit(err, 10) + ecpub, err := k.ECPubKey() + ifExit(err, 11) + + priv := ecpriv.Serialize() + pub := ecpub.SerializeCompressed() + mkey, _ := masterKey.ECPrivKey() + return mkey.Serialize(), priv, pub +} + +// return priv and pub +func tylerSmith(seed []byte) ([]byte, []byte, []byte) { + masterKey, err := bip32.NewMasterKey(seed) + if err != nil { + hmac := hmac.New(sha512.New, []byte("Bitcoin seed")) + hmac.Write([]byte(seed)) + intermediary := hmac.Sum(nil) + + curve := btcutil.Secp256k1() + curveParams := curve.Params() + + // Split it into our key and chain code + keyBytes := intermediary[:32] + fmt.Printf("\t%X\n", keyBytes) + fmt.Printf("\t%X\n", curveParams.N.Bytes()) + keyInt, _ := binary.ReadVarint(bytes.NewBuffer(keyBytes)) + fmt.Printf("\t%d\n", keyInt) + + } + ifExit(err, 0) + fh := bip32.FirstHardenedChild + k, err := masterKey.NewChildKey(fh + 44) + ifExit(err, 44) + k, err = k.NewChildKey(fh + 118) + ifExit(err, 118) + k, err = k.NewChildKey(fh + 0) + ifExit(err, 1) + k, err = k.NewChildKey(0) + ifExit(err, 2) + k, err = k.NewChildKey(0) + ifExit(err, 3) + + priv := k.Key + pub := k.PublicKey().Key + return masterKey.Key, priv, pub +} + // Benchmarks var revBytesCases = [][]byte{ @@ -146,6 +237,7 @@ func BenchmarkReverseBytes(b *testing.B) { // sink is necessary to ensure if the compiler tries // to smart, that it won't optimize away the benchmarks. - if sink != nil { // nolint: megacheck + if sink != nil { + _ = sink } } diff --git a/keys/cryptostore/holder.go b/keys/cryptostore/holder.go index f9e5f5bb3..f4d82583b 100644 --- a/keys/cryptostore/holder.go +++ b/keys/cryptostore/holder.go @@ -24,14 +24,15 @@ func New(coder Encoder, store keys.Storage, codec keys.Codec) Manager { } } +var _ keys.Signer = Manager{} +var _ keys.Manager = Manager{} + // exists just to make sure we fulfill the Signer interface -// nolint [ megacheck, deadcode ] func (s Manager) assertSigner() keys.Signer { return s } // exists just to make sure we fulfill the Manager interface -// nolint [ megacheck, deadcode ] func (s Manager) assertKeyManager() keys.Manager { return s } diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index 0ef4ae4ba..434966f46 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -144,7 +144,6 @@ func TestKeyManagement(t *testing.T) { // } // } -// nolint: unparam func assertPassword(assert *assert.Assertions, cstore cryptostore.Manager, name, pass, badpass string) { err := cstore.Update(name, badpass, pass) assert.NotNil(err) diff --git a/keys/server/helpers.go b/keys/server/helpers.go index 4820c937e..3fb947316 100644 --- a/keys/server/helpers.go +++ b/keys/server/helpers.go @@ -6,7 +6,6 @@ Please read the README and godoc to see how to configure the server for your application. */ -// nolint: goimports package server import ( diff --git a/keys/server/keys.go b/keys/server/keys.go index cae3e451d..80852802e 100644 --- a/keys/server/keys.go +++ b/keys/server/keys.go @@ -52,7 +52,6 @@ func (k Keys) GetKey(w http.ResponseWriter, r *http.Request) { writeSuccess(w, &key) } -// nolint: unparam func (k Keys) ListKeys(w http.ResponseWriter, r *http.Request) { keys, err := k.manager.List() diff --git a/keys/server/keys_test.go b/keys/server/keys_test.go index cad415644..2aa17753c 100644 --- a/keys/server/keys_test.go +++ b/keys/server/keys_test.go @@ -120,7 +120,6 @@ func listKeys(h http.Handler) (keys.Infos, int, error) { return data, rr.Code, err } -// nolint: unparam func getKey(h http.Handler, name string) (*keys.Info, int, error) { rr := httptest.NewRecorder() req, err := http.NewRequest("GET", "/keys/"+name, nil) @@ -138,7 +137,6 @@ func getKey(h http.Handler, name string) (*keys.Info, int, error) { return &data, rr.Code, err } -// nolint: unparam func createKey(h http.Handler, name, passphrase, algo string) (*types.CreateKeyResponse, int, error) { rr := httptest.NewRecorder() post := types.CreateKeyRequest{ @@ -167,7 +165,6 @@ func createKey(h http.Handler, name, passphrase, algo string) (*types.CreateKeyR return data, rr.Code, err } -// nolint: unparam func deleteKey(h http.Handler, name, passphrase string) (*types.ErrorResponse, int, error) { rr := httptest.NewRecorder() post := types.DeleteKeyRequest{ diff --git a/keys/storage/filestorage/main.go b/keys/storage/filestorage/main.go index d8058a5b9..e33ca5000 100644 --- a/keys/storage/filestorage/main.go +++ b/keys/storage/filestorage/main.go @@ -42,8 +42,9 @@ func New(dir string) FileStore { return FileStore{dir} } +var _ keys.Storage = FileStore{} + // assertStorage just makes sure we implement the proper Storage interface -// nolint [ megacheck, deadcode ] func (s FileStore) assertStorage() keys.Storage { return s } diff --git a/keys/storage/memstorage/main.go b/keys/storage/memstorage/main.go index 403a01318..6464b1308 100644 --- a/keys/storage/memstorage/main.go +++ b/keys/storage/memstorage/main.go @@ -22,8 +22,9 @@ func New() MemStore { return MemStore{} } +var _ keys.Storage = MemStore{} + // assertStorage just makes sure we implement the Storage interface -// nolint [ megacheck, deadcode ] func (s MemStore) assertStorage() keys.Storage { return s } diff --git a/keys/wordlist/wordlist.go b/keys/wordlist/wordlist.go index 915dda102..58ff41181 100644 --- a/keys/wordlist/wordlist.go +++ b/keys/wordlist/wordlist.go @@ -6,7 +6,6 @@ // keys/wordlist/spanish.txt // DO NOT EDIT! -// nolint: goimports package wordlist import ( From 796024f42f215b85ace955538ccbb5c2acddb8ea Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Wed, 4 Oct 2017 18:27:35 -0400 Subject: [PATCH 125/287] linting: little more fixes --- Makefile | 2 +- example_test.go | 10 ++++++---- hd/hd_test.go | 19 +++++++++++-------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index b1dc51ae0..c7d11ce0a 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,6 @@ metalinter_test: ensure_tools --enable=unused \ --enable=vetshadow \ --enable=vet \ - --enable=unparam \ --enable=varcheck \ ./... @@ -67,3 +66,4 @@ metalinter_test: ensure_tools #--enable=goimports \ #--enable=golint \ <== comments on anything exported #--enable=gotype \ + #--enable=unparam \ diff --git a/example_test.go b/example_test.go index c9cd2688d..fff49c84d 100644 --- a/example_test.go +++ b/example_test.go @@ -15,21 +15,23 @@ package crypto_test import ( - "fmt" +//"fmt" - "github.com/tendermint/go-crypto" +//"github.com/tendermint/go-crypto" ) -func Example_Sha256() { +/* +func example_Sha256() { sum := crypto.Sha256([]byte("This is Tendermint")) fmt.Printf("%x\n", sum) // Output: // f91afb642f3d1c87c17eb01aae5cb65c242dfdbe7cf1066cc260f4ce5d33b94e } -func Example_Ripemd160() { +func example_Ripemd160() { sum := crypto.Ripemd160([]byte("This is Tendermint")) fmt.Printf("%x\n", sum) // Output: // 051e22663e8f0fd2f2302f1210f954adff009005 } +*/ diff --git a/hd/hd_test.go b/hd/hd_test.go index fcb348b5c..02d80388c 100644 --- a/hd/hd_test.go +++ b/hd/hd_test.go @@ -2,9 +2,9 @@ package hd import ( "bytes" - "crypto/hmac" - "crypto/sha512" - "encoding/binary" + //"crypto/hmac" + //"crypto/sha512" + //"encoding/binary" "encoding/hex" "encoding/json" "fmt" @@ -15,10 +15,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/tyler-smith/go-bip39" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcutil/hdkeychain" - "github.com/mndrix/btcutil" - "github.com/tyler-smith/go-bip32" + //"github.com/btcsuite/btcd/chaincfg" + //"github.com/btcsuite/btcutil/hdkeychain" + //"github.com/mndrix/btcutil" + //"github.com/tyler-smith/go-bip32" "github.com/tendermint/go-crypto" ) @@ -109,12 +109,14 @@ func TestReverseBytes(t *testing.T) { } } +/* func ifExit(err error, n int) { if err != nil { fmt.Println(n, err) os.Exit(1) } } +*/ func gocrypto(seed []byte) ([]byte, []byte, []byte) { @@ -131,6 +133,7 @@ func gocrypto(seed []byte) ([]byte, []byte, []byte) { return HexDecode(priv), privBytes, pubBytes } +/* func btcsuite(seed []byte) ([]byte, []byte, []byte) { fmt.Println("HD") masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams) @@ -207,9 +210,9 @@ func tylerSmith(seed []byte) ([]byte, []byte, []byte) { pub := k.PublicKey().Key return masterKey.Key, priv, pub } +*/ // Benchmarks - var revBytesCases = [][]byte{ nil, []byte(""), From 1775be1cd93549a48bc3453adb4cfb96fa8d1c60 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Thu, 5 Oct 2017 22:19:48 -0400 Subject: [PATCH 126/287] remove some assertXxx funcs --- keys/cryptostore/holder.go | 11 +---------- keys/storage/filestorage/main.go | 6 +----- keys/storage/memstorage/main.go | 6 +----- 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/keys/cryptostore/holder.go b/keys/cryptostore/holder.go index f4d82583b..44332f175 100644 --- a/keys/cryptostore/holder.go +++ b/keys/cryptostore/holder.go @@ -24,19 +24,10 @@ func New(coder Encoder, store keys.Storage, codec keys.Codec) Manager { } } +// assert Manager satisfies keys.Signer and keys.Manager interfaces var _ keys.Signer = Manager{} var _ keys.Manager = Manager{} -// exists just to make sure we fulfill the Signer interface -func (s Manager) assertSigner() keys.Signer { - return s -} - -// exists just to make sure we fulfill the Manager interface -func (s Manager) assertKeyManager() keys.Manager { - return s -} - // Create adds a new key to the storage engine, returning error if // another key already stored under this name // diff --git a/keys/storage/filestorage/main.go b/keys/storage/filestorage/main.go index e33ca5000..bed80efb3 100644 --- a/keys/storage/filestorage/main.go +++ b/keys/storage/filestorage/main.go @@ -42,13 +42,9 @@ func New(dir string) FileStore { return FileStore{dir} } +// assert FileStore satisfies keys.Storage var _ keys.Storage = FileStore{} -// assertStorage just makes sure we implement the proper Storage interface -func (s FileStore) assertStorage() keys.Storage { - return s -} - // Put creates two files, one with the public info as json, the other // with the (encoded) private key as gpg ascii-armor style func (s FileStore) Put(name string, key []byte, info keys.Info) error { diff --git a/keys/storage/memstorage/main.go b/keys/storage/memstorage/main.go index 6464b1308..a988fe0ff 100644 --- a/keys/storage/memstorage/main.go +++ b/keys/storage/memstorage/main.go @@ -22,13 +22,9 @@ func New() MemStore { return MemStore{} } +// assert MemStore satisfies keys.Storage var _ keys.Storage = MemStore{} -// assertStorage just makes sure we implement the Storage interface -func (s MemStore) assertStorage() keys.Storage { - return s -} - // Put adds the given key, returns an error if it another key // is already stored under this name func (s MemStore) Put(name string, key []byte, info keys.Info) error { From 32dec98c1c78f9b0cb326e10e167a2d1cf12c515 Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Tue, 10 Oct 2017 17:33:51 -0400 Subject: [PATCH 127/287] example: fix func suffix --- example_test.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/example_test.go b/example_test.go index fff49c84d..2c8b94549 100644 --- a/example_test.go +++ b/example_test.go @@ -15,23 +15,21 @@ package crypto_test import ( -//"fmt" + "fmt" -//"github.com/tendermint/go-crypto" + "github.com/tendermint/go-crypto" ) -/* -func example_Sha256() { +func ExampleSha256() { sum := crypto.Sha256([]byte("This is Tendermint")) fmt.Printf("%x\n", sum) // Output: // f91afb642f3d1c87c17eb01aae5cb65c242dfdbe7cf1066cc260f4ce5d33b94e } -func example_Ripemd160() { +func ExampleRipemd160() { sum := crypto.Ripemd160([]byte("This is Tendermint")) fmt.Printf("%x\n", sum) // Output: // 051e22663e8f0fd2f2302f1210f954adff009005 } -*/ From 8e7f0e7701f92206679ad093d013b9b162427631 Mon Sep 17 00:00:00 2001 From: Adrian Brink <11320251+adrianbrink@users.noreply.github.com> Date: Thu, 12 Oct 2017 14:26:59 +0200 Subject: [PATCH 128/287] Upgrade keys to use bcrypt with salts (#38) This commit adds salts to the library using bcrypt. --- keys/cryptostore/enc_storage.go | 8 +- keys/cryptostore/encoder.go | 59 +++++++----- keys/cryptostore/encoder_test.go | 20 ++-- keys/cryptostore/generator.go | 1 + keys/cryptostore/holder.go | 18 ++-- keys/cryptostore/holder_test.go | 10 +- keys/cryptostore/storage_test.go | 2 +- keys/storage.go | 4 +- keys/storage/filestorage/main.go | 130 ++++++++++++++++++++------ keys/storage/filestorage/main_test.go | 13 +-- keys/storage/memstorage/main.go | 12 ++- keys/storage/memstorage/main_test.go | 13 +-- 12 files changed, 190 insertions(+), 100 deletions(-) diff --git a/keys/cryptostore/enc_storage.go b/keys/cryptostore/enc_storage.go index daeb220b5..e0c7e59a3 100644 --- a/keys/cryptostore/enc_storage.go +++ b/keys/cryptostore/enc_storage.go @@ -12,21 +12,21 @@ type encryptedStorage struct { } func (es encryptedStorage) Put(name, pass string, key crypto.PrivKey) error { - secret, err := es.coder.Encrypt(key, pass) + saltBytes, encBytes, err := es.coder.Encrypt(key, pass) if err != nil { return err } ki := info(name, key) - return es.store.Put(name, secret, ki) + return es.store.Put(name, saltBytes, encBytes, ki) } func (es encryptedStorage) Get(name, pass string) (crypto.PrivKey, keys.Info, error) { - secret, info, err := es.store.Get(name) + saltBytes, encBytes, info, err := es.store.Get(name) if err != nil { return crypto.PrivKey{}, info, err } - key, err := es.coder.Decrypt(secret, pass) + key, err := es.coder.Decrypt(saltBytes, encBytes, pass) return key, info, err } diff --git a/keys/cryptostore/encoder.go b/keys/cryptostore/encoder.go index 31cbc2e54..251543b60 100644 --- a/keys/cryptostore/encoder.go +++ b/keys/cryptostore/encoder.go @@ -2,7 +2,9 @@ package cryptostore import ( "github.com/pkg/errors" + crypto "github.com/tendermint/go-crypto" + "github.com/tendermint/go-crypto/bcrypt" ) var ( @@ -16,45 +18,54 @@ var ( // // This should use a well-designed symetric encryption algorithm type Encoder interface { - Encrypt(key crypto.PrivKey, pass string) ([]byte, error) - Decrypt(data []byte, pass string) (crypto.PrivKey, error) -} - -func secret(passphrase string) []byte { - // TODO: Sha256(Bcrypt(passphrase)) - return crypto.Sha256([]byte(passphrase)) + Encrypt(privKey crypto.PrivKey, passphrase string) (saltBytes []byte, encBytes []byte, err error) + Decrypt(saltBytes []byte, encBytes []byte, passphrase string) (privKey crypto.PrivKey, err error) } type secretbox struct{} -func (e secretbox) Encrypt(key crypto.PrivKey, pass string) ([]byte, error) { - if pass == "" { - return key.Bytes(), nil +func (e secretbox) Encrypt(privKey crypto.PrivKey, passphrase string) (saltBytes []byte, encBytes []byte, err error) { + if passphrase == "" { + return nil, privKey.Bytes(), nil + } + + saltBytes = crypto.CRandBytes(16) + key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 14) // TODO parameterize. 14 is good today (2016) + if err != nil { + return nil, nil, errors.Wrap(err, "Couldn't generate bcrypt key from passphrase.") } - s := secret(pass) - cipher := crypto.EncryptSymmetric(key.Bytes(), s) - return cipher, nil + key = crypto.Sha256(key) // Get 32 bytes + privKeyBytes := privKey.Bytes() + return saltBytes, crypto.EncryptSymmetric(privKeyBytes, key), nil } -func (e secretbox) Decrypt(data []byte, pass string) (key crypto.PrivKey, err error) { - private := data - if pass != "" { - s := secret(pass) - private, err = crypto.DecryptSymmetric(data, s) +func (e secretbox) Decrypt(saltBytes []byte, encBytes []byte, passphrase string) (privKey crypto.PrivKey, err error) { + privKeyBytes := encBytes + // NOTE: Some keys weren't encrypted with a passphrase and hence we have the conditional + if passphrase != "" { + key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 14) // TODO parameterize. 14 is good today (2016) if err != nil { return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") } + key = crypto.Sha256(key) // Get 32 bytes + privKeyBytes, err = crypto.DecryptSymmetric(encBytes, key) + if err != nil { + return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") + } + } + privKey, err = crypto.PrivKeyFromBytes(privKeyBytes) + if err != nil { + return crypto.PrivKey{}, errors.Wrap(err, "Couldn't get privKey from bytes") } - key, err = crypto.PrivKeyFromBytes(private) - return key, errors.Wrap(err, "Invalid Passphrase") + return privKey, nil } type noop struct{} -func (n noop) Encrypt(key crypto.PrivKey, pass string) ([]byte, error) { - return key.Bytes(), nil +func (n noop) Encrypt(key crypto.PrivKey, passphrase string) (saltBytes []byte, encBytes []byte, err error) { + return []byte{}, key.Bytes(), nil } -func (n noop) Decrypt(data []byte, pass string) (crypto.PrivKey, error) { - return crypto.PrivKeyFromBytes(data) +func (n noop) Decrypt(saltBytes []byte, encBytes []byte, passphrase string) (privKey crypto.PrivKey, err error) { + return crypto.PrivKeyFromBytes(encBytes) } diff --git a/keys/cryptostore/encoder_test.go b/keys/cryptostore/encoder_test.go index f468591f3..ce1118d20 100644 --- a/keys/cryptostore/encoder_test.go +++ b/keys/cryptostore/encoder_test.go @@ -18,22 +18,22 @@ func TestNoopEncoder(t *testing.T) { key := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) key2 := cryptostore.GenSecp256k1.Generate(cmn.RandBytes(16)) - b, err := noop.Encrypt(key, "encode") + _, b, err := noop.Encrypt(key, "encode") require.Nil(err) assert.NotEmpty(b) - b2, err := noop.Encrypt(key2, "encode") + _, b2, err := noop.Encrypt(key2, "encode") require.Nil(err) assert.NotEmpty(b2) assert.NotEqual(b, b2) // note the decode with a different password works - not secure! - pk, err := noop.Decrypt(b, "decode") + pk, err := noop.Decrypt(nil, b, "decode") require.Nil(err) require.NotNil(pk) assert.Equal(key, pk) - pk2, err := noop.Decrypt(b2, "kggugougp") + pk2, err := noop.Decrypt(nil, b2, "kggugougp") require.Nil(err) require.NotNil(pk2) assert.Equal(key2, pk2) @@ -46,17 +46,17 @@ func TestSecretBox(t *testing.T) { key := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) pass := "some-special-secret" - b, err := enc.Encrypt(key, pass) + s, b, err := enc.Encrypt(key, pass) require.Nil(err) assert.NotEmpty(b) // decoding with a different pass is an error - pk, err := enc.Decrypt(b, "decode") + pk, err := enc.Decrypt(s, b, "decode") require.NotNil(err) require.True(pk.Empty()) // but decoding with the same passphrase gets us our key - pk, err = enc.Decrypt(b, pass) + pk, err = enc.Decrypt(s, b, pass) require.Nil(err) assert.Equal(key, pk) } @@ -80,11 +80,11 @@ func TestSecretBoxNoPass(t *testing.T) { } for i, tc := range cases { - b, err := enc.Encrypt(key, tc.encode) + s, b, err := enc.Encrypt(key, tc.encode) require.Nil(err, "%d: %+v", i, err) assert.NotEmpty(b, "%d", i) - pk, err := enc.Decrypt(b, tc.decode) + pk, err := enc.Decrypt(s, b, tc.decode) if tc.valid { require.Nil(err, "%d: %+v", i, err) assert.Equal(key, pk, "%d", i) @@ -95,7 +95,7 @@ func TestSecretBoxNoPass(t *testing.T) { // now let's make sure raw bytes also work... b := key.Bytes() - pk, err := enc.Decrypt(b, "") + pk, err := enc.Decrypt(nil, b, "") require.Nil(err, "%+v", err) assert.Equal(key, pk) } diff --git a/keys/cryptostore/generator.go b/keys/cryptostore/generator.go index 0a2bb55c2..1f162ec08 100644 --- a/keys/cryptostore/generator.go +++ b/keys/cryptostore/generator.go @@ -2,6 +2,7 @@ package cryptostore import ( "github.com/pkg/errors" + crypto "github.com/tendermint/go-crypto" ) diff --git a/keys/cryptostore/holder.go b/keys/cryptostore/holder.go index 18437a9b5..2fc617b4e 100644 --- a/keys/cryptostore/holder.go +++ b/keys/cryptostore/holder.go @@ -100,7 +100,7 @@ func (s Manager) List() (keys.Infos, error) { // Get returns the public information about one key func (s Manager) Get(name string) (keys.Info, error) { - _, info, err := s.es.store.Get(name) + _, _, info, err := s.es.store.Get(name) return info, err } @@ -124,21 +124,23 @@ func (s Manager) Sign(name, passphrase string, tx keys.Signable) error { // // This is designed to copy from one device to another, or provide backups // during version updates. -func (s Manager) Export(name, oldpass, transferpass string) ([]byte, error) { +// TODO: How to handle Export with salt? +func (s Manager) Export(name, oldpass, transferpass string) (salt, data []byte, err error) { key, _, err := s.es.Get(name, oldpass) if err != nil { - return nil, err + return nil, nil, err } - res, err := s.es.coder.Encrypt(key, transferpass) - return res, err + salt, data, err = s.es.coder.Encrypt(key, transferpass) + return salt, data, err } // Import accepts bytes generated by Export along with the same transferpass -// If they are valid, it stores the password under the given name with the +// If they are valid, it stores the key under the given name with the // new passphrase. -func (s Manager) Import(name, newpass, transferpass string, data []byte) error { - key, err := s.es.coder.Decrypt(data, transferpass) +// TODO: How to handle Import with salt? +func (s Manager) Import(name, newpass, transferpass string, salt, data []byte) error { + key, err := s.es.coder.Decrypt(salt, data, transferpass) if err != nil { return err } diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index 434966f46..7484b1517 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -168,7 +168,7 @@ func TestImportUnencrypted(t *testing.T) { pass := "top-secret" // import raw bytes - err := cstore.Import(name, pass, "", key.Bytes()) + err := cstore.Import(name, pass, "", nil, key.Bytes()) require.Nil(err, "%+v", err) // make sure the address matches @@ -209,15 +209,15 @@ func TestAdvancedKeyManagement(t *testing.T) { assertPassword(assert, cstore, n1, p2, p1) // exporting requires the proper name and passphrase - _, err = cstore.Export(n2, p2, pt) + _, _, err = cstore.Export(n2, p2, pt) assert.NotNil(err) - _, err = cstore.Export(n1, p1, pt) + _, _, err = cstore.Export(n1, p1, pt) assert.NotNil(err) - exported, err := cstore.Export(n1, p2, pt) + salt, exported, err := cstore.Export(n1, p2, pt) require.Nil(err, "%+v", err) // import fails on bad transfer pass - err = cstore.Import(n2, p3, p2, exported) + err = cstore.Import(n2, p3, p2, salt, exported) assert.NotNil(err) } diff --git a/keys/cryptostore/storage_test.go b/keys/cryptostore/storage_test.go index 907a19f11..468435143 100644 --- a/keys/cryptostore/storage_test.go +++ b/keys/cryptostore/storage_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - crypto "github.com/tendermint/go-crypto" cmn "github.com/tendermint/tmlibs/common" + crypto "github.com/tendermint/go-crypto" keys "github.com/tendermint/go-crypto/keys" ) diff --git a/keys/storage.go b/keys/storage.go index 0c25eb8a5..0aba4ebdb 100644 --- a/keys/storage.go +++ b/keys/storage.go @@ -3,8 +3,8 @@ package keys // Storage has many implementation, based on security and sharing requirements // like disk-backed, mem-backed, vault, db, etc. type Storage interface { - Put(name string, key []byte, info Info) error - Get(name string) ([]byte, Info, error) + Put(name string, salt []byte, key []byte, info Info) error + Get(name string) (salt []byte, key []byte, info Info, err error) List() (Infos, error) Delete(name string) error } diff --git a/keys/storage/filestorage/main.go b/keys/storage/filestorage/main.go index 696b200fc..bd29ce41f 100644 --- a/keys/storage/filestorage/main.go +++ b/keys/storage/filestorage/main.go @@ -6,6 +6,7 @@ like standard ssh key storage. package filestorage import ( + "encoding/hex" "fmt" "io/ioutil" "os" @@ -13,19 +14,25 @@ import ( "strings" "github.com/pkg/errors" + crypto "github.com/tendermint/go-crypto" keys "github.com/tendermint/go-crypto/keys" ) const ( + // BlockType is the type of block. BlockType = "Tendermint Light Client" - PrivExt = "tlc" - PubExt = "pub" - keyPerm = os.FileMode(0600) - pubPerm = os.FileMode(0644) - dirPerm = os.FileMode(0700) + // PrivExt is the extension for private keys. + PrivExt = "tlc" + // PubExt is the extensions for public keys. + PubExt = "pub" + + keyPerm = os.FileMode(0600) + pubPerm = os.FileMode(0644) + dirPerm = os.FileMode(0700) ) +// FileStore is a file-based key storage with tight permissions. type FileStore struct { keyDir string } @@ -36,9 +43,11 @@ type FileStore struct { // be created if it doesn't exist already. func New(dir string) FileStore { err := os.MkdirAll(dir, dirPerm) + if err != nil { panic(err) } + return FileStore{dir} } @@ -49,7 +58,7 @@ func (s FileStore) assertStorage() keys.Storage { // Put creates two files, one with the public info as json, the other // with the (encoded) private key as gpg ascii-armor style -func (s FileStore) Put(name string, key []byte, info keys.Info) error { +func (s FileStore) Put(name string, salt, key []byte, info keys.Info) error { pub, priv := s.nameToPaths(name) // write public info @@ -59,31 +68,34 @@ func (s FileStore) Put(name string, key []byte, info keys.Info) error { } // write private info - return write(priv, name, key) + return write(priv, name, salt, key) } // Get loads the info and (encoded) private key from the directory // It uses `name` to generate the filename, and returns an error if the // files don't exist or are in the incorrect format -func (s FileStore) Get(name string) ([]byte, keys.Info, error) { +func (s FileStore) Get(name string) (salt []byte, key []byte, info keys.Info, err error) { pub, priv := s.nameToPaths(name) - info, err := readInfo(pub) + info, err = readInfo(pub) if err != nil { - return nil, info, err + return nil, nil, info, err } - key, _, err := read(priv) - return key, info.Format(), err + salt, key, _, err = read(priv) + return salt, key, info.Format(), err } // List parses the key directory for public info and returns a list of // Info for all keys located in this directory. func (s FileStore) List() (keys.Infos, error) { dir, err := os.Open(s.keyDir) + defer dir.Close() + if err != nil { return nil, errors.Wrap(err, "List Keys") } + names, err := dir.Readdirnames(0) if err != nil { return nil, errors.Wrap(err, "List Keys") @@ -111,61 +123,121 @@ func (s FileStore) List() (keys.Infos, error) { func (s FileStore) Delete(name string) error { pub, priv := s.nameToPaths(name) err := os.Remove(priv) + if err != nil { return errors.Wrap(err, "Deleting Private Key") } + err = os.Remove(pub) + return errors.Wrap(err, "Deleting Public Key") } func (s FileStore) nameToPaths(name string) (pub, priv string) { privName := fmt.Sprintf("%s.%s", name, PrivExt) pubName := fmt.Sprintf("%s.%s", name, PubExt) - return path.Join(s.keyDir, pubName), path.Join(s.keyDir, privName) -} -func writeInfo(path string, info keys.Info) error { - return write(path, info.Name, info.PubKey.Bytes()) + return path.Join(s.keyDir, pubName), path.Join(s.keyDir, privName) } func readInfo(path string) (info keys.Info, err error) { - var data []byte - data, info.Name, err = read(path) + f, err := os.Open(path) + defer f.Close() + if err != nil { - return + return info, errors.Wrap(err, "Reading data") } - pk, err := crypto.PubKeyFromBytes(data) + + d, err := ioutil.ReadAll(f) + if err != nil { + return info, errors.Wrap(err, "Reading data") + } + + block, headers, key, err := crypto.DecodeArmor(string(d)) + if err != nil { + return info, errors.Wrap(err, "Invalid Armor") + } + + if block != BlockType { + return info, errors.Errorf("Unknown key type: %s", block) + } + + pk, _ := crypto.PubKeyFromBytes(key) + info.Name = headers["name"] info.PubKey = pk - return + + return info, nil } -func read(path string) ([]byte, string, error) { +func read(path string) (salt, key []byte, name string, err error) { f, err := os.Open(path) + defer f.Close() + if err != nil { - return nil, "", errors.Wrap(err, "Reading data") + return nil, nil, "", errors.Wrap(err, "Reading data") } + d, err := ioutil.ReadAll(f) if err != nil { - return nil, "", errors.Wrap(err, "Reading data") + return nil, nil, "", errors.Wrap(err, "Reading data") } + block, headers, key, err := crypto.DecodeArmor(string(d)) if err != nil { - return nil, "", errors.Wrap(err, "Invalid Armor") + return nil, nil, "", errors.Wrap(err, "Invalid Armor") } + if block != BlockType { - return nil, "", errors.Errorf("Unknown key type: %s", block) + return nil, nil, "", errors.Errorf("Unknown key type: %s", block) + } + + if headers["kdf"] != "bcrypt" { + return nil, nil, "", errors.Errorf("Unrecognized KDF type: %v", headers["kdf"]) + } + + if headers["salt"] == "" { + return nil, nil, "", errors.Errorf("Missing salt bytes") } - return key, headers["name"], nil + + salt, err = hex.DecodeString(headers["salt"]) + if err != nil { + return nil, nil, "", errors.Errorf("Error decoding salt: %v", err.Error()) + } + + return salt, key, headers["name"], nil } -func write(path, name string, key []byte) error { +func writeInfo(path string, info keys.Info) error { f, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, keyPerm) + defer f.Close() + if err != nil { return errors.Wrap(err, "Writing data") } + + headers := map[string]string{"name": info.Name} + text := crypto.EncodeArmor(BlockType, headers, info.PubKey.Bytes()) + _, err = f.WriteString(text) + + return errors.Wrap(err, "Writing data") +} + +func write(path, name string, salt, key []byte) error { + f, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, keyPerm) defer f.Close() - headers := map[string]string{"name": name} + + if err != nil { + return errors.Wrap(err, "Writing data") + } + + headers := map[string]string{ + "name": name, + "kdf": "bcrypt", + "salt": fmt.Sprintf("%X", salt), + } + text := crypto.EncodeArmor(BlockType, headers, key) _, err = f.WriteString(text) + return errors.Wrap(err, "Writing data") } diff --git a/keys/storage/filestorage/main_test.go b/keys/storage/filestorage/main_test.go index 28c950c2c..bed46ab1f 100644 --- a/keys/storage/filestorage/main_test.go +++ b/keys/storage/filestorage/main_test.go @@ -22,6 +22,7 @@ func TestBasicCRUD(t *testing.T) { name := "bar" key := []byte("secret-key-here") + salt := []byte("salt-here") pubkey := crypto.GenPrivKeyEd25519().PubKey() info := keys.Info{ Name: name, @@ -29,7 +30,7 @@ func TestBasicCRUD(t *testing.T) { } // No data: Get and Delete return nothing - _, _, err = store.Get(name) + _, _, _, err = store.Get(name) assert.NotNil(err) err = store.Delete(name) assert.NotNil(err) @@ -39,14 +40,14 @@ func TestBasicCRUD(t *testing.T) { assert.Empty(l) // Putting the key in the store must work - err = store.Put(name, key, info) + err = store.Put(name, salt, key, info) assert.Nil(err) // But a second time is a failure - err = store.Put(name, key, info) + err = store.Put(name, salt, key, info) assert.NotNil(err) // Now, we can get and list properly - k, i, err := store.Get(name) + _, k, i, err := store.Get(name) require.Nil(err, "%+v", err) assert.Equal(key, k) assert.Equal(info.Name, i.Name) @@ -58,7 +59,7 @@ func TestBasicCRUD(t *testing.T) { assert.Equal(i, l[0]) // querying a non-existent key fails - _, _, err = store.Get("badname") + _, _, _, err = store.Get("badname") assert.NotNil(err) // We can only delete once @@ -68,7 +69,7 @@ func TestBasicCRUD(t *testing.T) { assert.NotNil(err) // and then Get and List don't work - _, _, err = store.Get(name) + _, _, _, err = store.Get(name) assert.NotNil(err) // List returns empty list l, err = store.List() diff --git a/keys/storage/memstorage/main.go b/keys/storage/memstorage/main.go index 195fa7a17..ddc46afc9 100644 --- a/keys/storage/memstorage/main.go +++ b/keys/storage/memstorage/main.go @@ -7,11 +7,13 @@ package memstorage import ( "github.com/pkg/errors" + keys "github.com/tendermint/go-crypto/keys" ) type data struct { info keys.Info + salt []byte key []byte } @@ -29,22 +31,22 @@ func (s MemStore) assertStorage() keys.Storage { // Put adds the given key, returns an error if it another key // is already stored under this name -func (s MemStore) Put(name string, key []byte, info keys.Info) error { +func (s MemStore) Put(name string, salt, key []byte, info keys.Info) error { if _, ok := s[name]; ok { return errors.Errorf("Key named '%s' already exists", name) } - s[name] = data{info, key} + s[name] = data{info, salt, key} return nil } // Get returns the key stored under the name, or returns an error if not present -func (s MemStore) Get(name string) ([]byte, keys.Info, error) { - var err error +func (s MemStore) Get(name string) (salt, key []byte, info keys.Info, err error) { d, ok := s[name] if !ok { err = errors.Errorf("Key named '%s' doesn't exist", name) } - return d.key, d.info.Format(), err + + return d.salt, d.key, d.info.Format(), err } // List returns the public info of all keys in the MemStore in unsorted order diff --git a/keys/storage/memstorage/main_test.go b/keys/storage/memstorage/main_test.go index feccb387f..01975df58 100644 --- a/keys/storage/memstorage/main_test.go +++ b/keys/storage/memstorage/main_test.go @@ -14,6 +14,7 @@ func TestBasicCRUD(t *testing.T) { name := "foo" key := []byte("secret-key-here") + salt := []byte("salt-here") pubkey := crypto.GenPrivKeyEd25519().PubKey() info := keys.Info{ Name: name, @@ -21,7 +22,7 @@ func TestBasicCRUD(t *testing.T) { } // No data: Get and Delete return nothing - _, _, err := store.Get(name) + _, _, _, err := store.Get(name) assert.NotNil(err) err = store.Delete(name) assert.NotNil(err) @@ -31,14 +32,14 @@ func TestBasicCRUD(t *testing.T) { assert.Empty(l) // Putting the key in the store must work - err = store.Put(name, key, info) + err = store.Put(name, salt, key, info) assert.Nil(err) // But a second time is a failure - err = store.Put(name, key, info) + err = store.Put(name, salt, key, info) assert.NotNil(err) // Now, we can get and list properly - k, i, err := store.Get(name) + _, k, i, err := store.Get(name) assert.Nil(err) assert.Equal(key, k) assert.Equal(info.Name, i.Name) @@ -50,7 +51,7 @@ func TestBasicCRUD(t *testing.T) { assert.Equal(i, l[0]) // querying a non-existent key fails - _, _, err = store.Get("badname") + _, _, _, err = store.Get("badname") assert.NotNil(err) // We can only delete once @@ -60,7 +61,7 @@ func TestBasicCRUD(t *testing.T) { assert.NotNil(err) // and then Get and List don't work - _, _, err = store.Get(name) + _, _, _, err = store.Get(name) assert.NotNil(err) // List returns empty list l, err = store.List() From 47d3fa47419156c3c2f0c6e83d6eb4dfded0eb42 Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Mon, 23 Oct 2017 08:30:18 -0400 Subject: [PATCH 129/287] linting: a few fixes --- Makefile | 2 +- embed_test.go | 8 ++++---- keys/cryptostore/holder_test.go | 14 +++++++------- keys/storage/filestorage/main.go | 15 +++++---------- 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index c7d11ce0a..f775704a9 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,6 @@ metalinter: ensure_tools metalinter_test: ensure_tools @gometalinter --install gometalinter --vendor --deadline=600s --disable-all \ - --enable=aligncheck \ --enable=deadcode \ --enable=gas \ --enable=goconst \ @@ -49,6 +48,7 @@ metalinter_test: ensure_tools --enable=gosimple \ --enable=ineffassign \ --enable=interfacer \ + --enable=maligned \ --enable=megacheck \ --enable=misspell \ --enable=safesql \ diff --git a/embed_test.go b/embed_test.go index e2d2fe504..e5c37c0c1 100644 --- a/embed_test.go +++ b/embed_test.go @@ -73,8 +73,8 @@ func TestEncodeDemo(t *testing.T) { // Try to encode as binary b, err := data.ToWire(tc.in) if assert.Nil(err, "%d: %#v", i, tc.in) { - err := data.FromWire(b, tc.out) - if assert.Nil(err) { + err2 := data.FromWire(b, tc.out) + if assert.Nil(err2) { assert.Equal(tc.expected, tc.out.String()) } } @@ -82,8 +82,8 @@ func TestEncodeDemo(t *testing.T) { // Try to encode it as json j, err := data.ToJSON(tc.in) if assert.Nil(err, "%d: %#v", i, tc.in) { - err := data.FromJSON(j, tc.out) - if assert.Nil(err) { + err2 := data.FromJSON(j, tc.out) + if assert.Nil(err2) { assert.Equal(tc.expected, tc.out.String()) } } diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index 7484b1517..a8fc90989 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -50,22 +50,22 @@ func TestKeyManagement(t *testing.T) { assert.NotNil(err) // list shows them in order - keys, err := cstore.List() + keyS, err := cstore.List() require.Nil(err) - require.Equal(2, len(keys)) + require.Equal(2, len(keyS)) // note these are in alphabetical order - assert.Equal(n2, keys[0].Name) - assert.Equal(n1, keys[1].Name) - assert.Equal(i2.PubKey, keys[0].PubKey) + assert.Equal(n2, keyS[0].Name) + assert.Equal(n1, keyS[1].Name) + assert.Equal(i2.PubKey, keyS[0].PubKey) // deleting a key removes it err = cstore.Delete("bad name", "foo") require.NotNil(err) err = cstore.Delete(n1, p1) require.Nil(err) - keys, err = cstore.List() + keyS, err = cstore.List() require.Nil(err) - assert.Equal(1, len(keys)) + assert.Equal(1, len(keyS)) _, err = cstore.Get(n1) assert.NotNil(err) diff --git a/keys/storage/filestorage/main.go b/keys/storage/filestorage/main.go index 70b7e6251..2bd4dcc1f 100644 --- a/keys/storage/filestorage/main.go +++ b/keys/storage/filestorage/main.go @@ -89,11 +89,10 @@ func (s FileStore) Get(name string) (salt []byte, key []byte, info keys.Info, er // Info for all keys located in this directory. func (s FileStore) List() (keys.Infos, error) { dir, err := os.Open(s.keyDir) - defer dir.Close() - if err != nil { return nil, errors.Wrap(err, "List Keys") } + defer dir.Close() names, err := dir.Readdirnames(0) if err != nil { @@ -141,11 +140,10 @@ func (s FileStore) nameToPaths(name string) (pub, priv string) { func readInfo(path string) (info keys.Info, err error) { f, err := os.Open(path) - defer f.Close() - if err != nil { return info, errors.Wrap(err, "Reading data") } + defer f.Close() d, err := ioutil.ReadAll(f) if err != nil { @@ -170,11 +168,10 @@ func readInfo(path string) (info keys.Info, err error) { func read(path string) (salt, key []byte, name string, err error) { f, err := os.Open(path) - defer f.Close() - if err != nil { return nil, nil, "", errors.Wrap(err, "Reading data") } + defer f.Close() d, err := ioutil.ReadAll(f) if err != nil { @@ -208,11 +205,10 @@ func read(path string) (salt, key []byte, name string, err error) { func writeInfo(path string, info keys.Info) error { f, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, keyPerm) - defer f.Close() - if err != nil { return errors.Wrap(err, "Writing data") } + defer f.Close() headers := map[string]string{"name": info.Name} text := crypto.EncodeArmor(BlockType, headers, info.PubKey.Bytes()) @@ -223,11 +219,10 @@ func writeInfo(path string, info keys.Info) error { func write(path, name string, salt, key []byte) error { f, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, keyPerm) - defer f.Close() - if err != nil { return errors.Wrap(err, "Writing data") } + defer f.Close() headers := map[string]string{ "name": name, From 0781c12ede58390a77f6ea5c7245e120895a6127 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Fri, 28 Jul 2017 23:44:16 -0400 Subject: [PATCH 130/287] Message encoding for nano --- nano/sign.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++ nano/sign_test.go | 51 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 nano/sign.go create mode 100644 nano/sign_test.go diff --git a/nano/sign.go b/nano/sign.go new file mode 100644 index 000000000..fbe550548 --- /dev/null +++ b/nano/sign.go @@ -0,0 +1,59 @@ +package nano + +import ( + "bytes" + "fmt" + + "github.com/pkg/errors" +) + +const ( + App = 0x80 + Init = 0x00 + Update = 0x01 + Digest = 0x02 + MaxChunk = 253 + KeyLength = 65 + SigLength = 64 +) + +var separator = []byte{0, 0xCA, 0xFE, 0} + +func generateSignRequests(payload []byte) [][]byte { + // nice one-shot + digest := []byte{App, Digest} + if len(payload) < MaxChunk { + return [][]byte{append(digest, payload...)} + } + + // large payload is multi-chunk + result := [][]byte{{App, Init}} + update := []byte{App, Update} + for len(payload) > MaxChunk { + msg := append(update, payload[:MaxChunk]...) + payload = payload[MaxChunk:] + result = append(result, msg) + } + result = append(result, append(update, payload...)) + result = append(result, digest) + return result +} + +func parseDigest(resp []byte) (key, sig []byte, err error) { + if resp[0] != App || resp[1] != Digest { + return nil, nil, errors.New("Invalid header") + } + resp = resp[2:] + if len(resp) != KeyLength+SigLength+len(separator) { + return nil, nil, errors.Errorf("Incorrect length: %d", len(resp)) + } + + key, resp = resp[:KeyLength], resp[KeyLength:] + if !bytes.Equal(separator, resp[:len(separator)]) { + return nil, nil, errors.New("Cannot find 0xCAFE") + } + fmt.Println("successs") + + sig = resp[len(separator):] + return key, sig, nil +} diff --git a/nano/sign_test.go b/nano/sign_test.go new file mode 100644 index 000000000..8029ef828 --- /dev/null +++ b/nano/sign_test.go @@ -0,0 +1,51 @@ +package nano + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestParseDigest(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + cases := []struct { + output string + key string + sig string + valid bool + }{ + { + output: "800204338EB1DD3CCDEE1F6FB586F66E640F56FFDD14537A3F0ED9EEEDF10B528FE4195FD17AC9EDAE9718A50196A1459E2434C1E53F1238F4CFDF177FAFBA8B39249B00CAFE00FFDEA42A699205B217004E7E2FFB884E174A548D644116F4B20469CBC32F60A9CB0EEB5BB6A7F266BD0F6A0A99A45B4F18F0F477AED7C854C404EF43530DAB00", + key: "04338EB1DD3CCDEE1F6FB586F66E640F56FFDD14537A3F0ED9EEEDF10B528FE4195FD17AC9EDAE9718A50196A1459E2434C1E53F1238F4CFDF177FAFBA8B39249B", + sig: "FFDEA42A699205B217004E7E2FFB884E174A548D644116F4B20469CBC32F60A9CB0EEB5BB6A7F266BD0F6A0A99A45B4F18F0F477AED7C854C404EF43530DAB00", + valid: true, + }, + { + output: "800235467890876543525437890796574535467890", + key: "", + sig: "", + valid: false, + }, + } + + for i, tc := range cases { + msg, err := hex.DecodeString(tc.output) + require.Nil(err, "%d: %+v", i, err) + + lKey, lSig, err := parseDigest(msg) + if !tc.valid { + assert.NotNil(err, "%d", i) + } else if assert.Nil(err, "%d: %+v", i, err) { + key, err := hex.DecodeString(tc.key) + require.Nil(err, "%d: %+v", i, err) + sig, err := hex.DecodeString(tc.sig) + require.Nil(err, "%d: %+v", i, err) + + assert.Equal(key, lKey, "%d", i) + assert.Equal(sig, lSig, "%d", i) + } + } +} From 8220d591784cfa064e003c4344dc7d1aa138882a Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Sat, 29 Jul 2017 13:35:52 -0400 Subject: [PATCH 131/287] Work on using returned bytes as crypto keys --- nano/sign.go | 19 +++++++++++++++++++ nano/sign_test.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/nano/sign.go b/nano/sign.go index fbe550548..b98b7f469 100644 --- a/nano/sign.go +++ b/nano/sign.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/pkg/errors" + crypto "github.com/tendermint/go-crypto" ) const ( @@ -57,3 +58,21 @@ func parseDigest(resp []byte) (key, sig []byte, err error) { sig = resp[len(separator):] return key, sig, nil } + +func parseKey(data []byte) (key crypto.PubKey, err error) { + ed := crypto.PubKeyEd25519{} + if len(data) < len(ed) { + return key, errors.Errorf("Key length too short: %d", len(data)) + } + copy(ed[:], data) + return ed.Wrap(), nil +} + +func parseSig(data []byte) (key crypto.Signature, err error) { + ed := crypto.SignatureEd25519{} + if len(data) < len(ed) { + return key, errors.Errorf("Sig length too short: %d", len(data)) + } + copy(ed[:], data) + return ed.Wrap(), nil +} diff --git a/nano/sign_test.go b/nano/sign_test.go index 8029ef828..be1e66c86 100644 --- a/nano/sign_test.go +++ b/nano/sign_test.go @@ -49,3 +49,50 @@ func TestParseDigest(t *testing.T) { } } } + +type cryptoCase struct { + msg string + key string + sig string + valid bool +} + +func toBytes(c cryptoCase) (msg, key, sig []byte, err error) { + msg, err = hex.DecodeString(c.msg) + if err != nil { + return + } + key, err = hex.DecodeString(c.key) + if err != nil { + return + } + sig, err = hex.DecodeString(c.sig) + return +} + +func TestCryptoConvert(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + cases := []cryptoCase{ + { + msg: "00", + key: "04338EB1DD3CCDEE1F6FB586F66E640F56FFDD14537A3F0ED9EEEDF10B528FE4195FD17AC9EDAE9718A50196A1459E2434C1E53F1238F4CFDF177FAFBA8B39249B", + sig: "FFDEA42A699205B217004E7E2FFB884E174A548D644116F4B20469CBC32F60A9CB0EEB5BB6A7F266BD0F6A0A99A45B4F18F0F477AED7C854C404EF43530DAB00", + valid: true, + }, + } + + for i, tc := range cases { + msg, key, sig, err := toBytes(tc) + require.Nil(err, "%d: %+v", i, err) + + pk, err := parseKey(key) + require.Nil(err, "%d: %+v", i, err) + psig, err := parseSig(sig) + require.Nil(err, "%d: %+v", i, err) + + // how do i make this valid? + valid := pk.VerifyBytes(msg, psig) + assert.Equal(tc.valid, valid, "%d", i) + } +} From 74878ee3130cff56dcd096a69ed7a3b97e7d233f Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 12 Sep 2017 09:50:07 +0200 Subject: [PATCH 132/287] Update code to work with current nano implementation --- nano/sign.go | 9 ++++++++- nano/sign_test.go | 19 ++++++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/nano/sign.go b/nano/sign.go index b98b7f469..50b874d15 100644 --- a/nano/sign.go +++ b/nano/sign.go @@ -2,9 +2,11 @@ package nano import ( "bytes" + "crypto/sha512" "fmt" "github.com/pkg/errors" + crypto "github.com/tendermint/go-crypto" ) @@ -14,7 +16,7 @@ const ( Update = 0x01 Digest = 0x02 MaxChunk = 253 - KeyLength = 65 + KeyLength = 32 SigLength = 64 ) @@ -76,3 +78,8 @@ func parseSig(data []byte) (key crypto.Signature, err error) { copy(ed[:], data) return ed.Wrap(), nil } + +func hashMsg(data []byte) []byte { + res := sha512.Sum512(data) + return res[:] +} diff --git a/nano/sign_test.go b/nano/sign_test.go index be1e66c86..2f94c5e6f 100644 --- a/nano/sign_test.go +++ b/nano/sign_test.go @@ -18,9 +18,9 @@ func TestParseDigest(t *testing.T) { valid bool }{ { - output: "800204338EB1DD3CCDEE1F6FB586F66E640F56FFDD14537A3F0ED9EEEDF10B528FE4195FD17AC9EDAE9718A50196A1459E2434C1E53F1238F4CFDF177FAFBA8B39249B00CAFE00FFDEA42A699205B217004E7E2FFB884E174A548D644116F4B20469CBC32F60A9CB0EEB5BB6A7F266BD0F6A0A99A45B4F18F0F477AED7C854C404EF43530DAB00", - key: "04338EB1DD3CCDEE1F6FB586F66E640F56FFDD14537A3F0ED9EEEDF10B528FE4195FD17AC9EDAE9718A50196A1459E2434C1E53F1238F4CFDF177FAFBA8B39249B", - sig: "FFDEA42A699205B217004E7E2FFB884E174A548D644116F4B20469CBC32F60A9CB0EEB5BB6A7F266BD0F6A0A99A45B4F18F0F477AED7C854C404EF43530DAB00", + output: "80028E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C9300CAFE00787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400", + key: "8E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C93", + sig: "787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400", valid: true, }, { @@ -75,9 +75,9 @@ func TestCryptoConvert(t *testing.T) { cases := []cryptoCase{ { - msg: "00", - key: "04338EB1DD3CCDEE1F6FB586F66E640F56FFDD14537A3F0ED9EEEDF10B528FE4195FD17AC9EDAE9718A50196A1459E2434C1E53F1238F4CFDF177FAFBA8B39249B", - sig: "FFDEA42A699205B217004E7E2FFB884E174A548D644116F4B20469CBC32F60A9CB0EEB5BB6A7F266BD0F6A0A99A45B4F18F0F477AED7C854C404EF43530DAB00", + msg: "F00D", + key: "8E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C93", + sig: "787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400", valid: true, }, } @@ -91,8 +91,13 @@ func TestCryptoConvert(t *testing.T) { psig, err := parseSig(sig) require.Nil(err, "%d: %+v", i, err) - // how do i make this valid? + // it is not the signature of the message itself valid := pk.VerifyBytes(msg, psig) + assert.NotEqual(tc.valid, valid, "%d", i) + + // but rather of the hash of the msg + hmsg := hashMsg(msg) + valid = pk.VerifyBytes(hmsg, psig) assert.Equal(tc.valid, valid, "%d", i) } } From 06d74b24dd3fc80ff7b63b5dca2afe89142a5558 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 12 Sep 2017 10:37:01 +0200 Subject: [PATCH 133/287] Wrote PrivKey/PubKey for ledger --- nano/keys.go | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 nano/keys.go diff --git a/nano/keys.go b/nano/keys.go new file mode 100644 index 000000000..7b76fa87f --- /dev/null +++ b/nano/keys.go @@ -0,0 +1,150 @@ +package nano + +import ( + "bytes" + "encoding/hex" + + crypto "github.com/tendermint/go-crypto" +) + +// // Implements PrivKey, calling the ledger nano +// type PrivKeyLedger struct{} + +// var _ PrivKeyInner = PrivKeyLedger{} + +// func (privKey PrivKeyLedger) AssertIsPrivKeyInner() {} + +// func (privKey PrivKeyLedger) Bytes() []byte { +// return wire.BinaryBytes(PrivKey{privKey}) +// } + +// func (privKey PrivKeyLedger) Sign(msg []byte) Signature { +// privKeyBytes := [64]byte(privKey) +// signatureBytes := ed25519.Sign(&privKeyBytes, msg) +// return SignatureEd25519(*signatureBytes).Wrap() +// } + +// func (privKey PrivKeyLedger) PubKey() PubKey { +// privKeyBytes := [64]byte(privKey) +// pubBytes := *ed25519.MakePublicKey(&privKeyBytes) +// return PubKeyEd25519(pubBytes).Wrap() +// } + +// func (privKey PrivKeyLedger) Equals(other PrivKey) bool { +// if otherEd, ok := other.Unwrap().(PrivKeyLedger); ok { +// return bytes.Equal(privKey[:], otherEd[:]) +// } else { +// return false +// } +// } + +// MockPrivKeyLedger behaves as the ledger, but stores a pre-packaged call-response +// for use in test cases +type MockPrivKeyLedger struct { + Msg []byte + Pub [KeyLength]byte + Sig [SigLength]byte +} + +// NewMockKey returns +func NewMockKey(msg, pubkey, sig string) (pk MockPrivKeyLedger) { + var err error + pk.Msg, err = hex.DecodeString(msg) + if err != nil { + panic(err) + } + + bpk, err := hex.DecodeString(pubkey) + if err != nil { + panic(err) + } + bsig, err := hex.DecodeString(sig) + if err != nil { + panic(err) + } + + copy(pk.Pub[:], bpk) + copy(pk.Sig[:], bsig) + return pk +} + +var _ crypto.PrivKeyInner = MockPrivKeyLedger{} + +// AssertIsPrivKeyInner fulfils PrivKey Interface +func (pk MockPrivKeyLedger) AssertIsPrivKeyInner() {} + +// Bytes fulfils PrivKey Interface - not supported +func (pk MockPrivKeyLedger) Bytes() []byte { + return nil +} + +// Sign returns a real SignatureLedger, if the msg matches what we expect +func (pk MockPrivKeyLedger) Sign(msg []byte) crypto.Signature { + if !bytes.Equal(pk.Msg, msg) { + panic("Mock key is for different msg") + } + return crypto.SignatureEd25519(pk.Sig).Wrap() +} + +// PubKey returns a real PubKeyLedger, that will verify this signature +func (pk MockPrivKeyLedger) PubKey() crypto.PubKey { + return PubKeyLedger{crypto.PubKeyEd25519(pk.Pub)}.Wrap() +} + +// Equals compares that two Mocks have the same data +func (pk MockPrivKeyLedger) Equals(other crypto.PrivKey) bool { + if mock, ok := other.Unwrap().(MockPrivKeyLedger); ok { + return bytes.Equal(mock.Pub[:], pk.Pub[:]) && + bytes.Equal(mock.Sig[:], pk.Sig[:]) && + bytes.Equal(mock.Msg, pk.Msg) + } + return false +} + +//////////////////////////////////////////// +// pubkey + +// PubKeyLedger works like a normal Ed25519 except a hash before the verify bytes +type PubKeyLedger struct { + crypto.PubKeyEd25519 +} + +// VerifyBytes uses the normal Ed25519 algorithm but a sha512 hash beforehand +func (pk PubKeyLedger) VerifyBytes(msg []byte, sig crypto.Signature) bool { + hmsg := hashMsg(msg) + return pk.PubKeyEd25519.VerifyBytes(hmsg, sig) +} + +// Equals implements PubKey interface +func (pk PubKeyLedger) Equals(other crypto.PubKey) bool { + if ledger, ok := other.Unwrap().(PubKeyLedger); ok { + return bytes.Equal(pk.PubKeyEd25519[:], ledger.PubKeyEd25519[:]) + } + return false +} + +/*** registration with go-data ***/ + +func init() { + crypto.PrivKeyMapper. + // RegisterImplementation(PrivKeyLedger{}, "ledger", 0x10). + RegisterImplementation(MockPrivKeyLedger{}, "mock-ledger", 0x11) + + crypto.PubKeyMapper. + RegisterImplementation(PubKeyLedger{}, "ledger", 0x10) +} + +// // Wrap fulfils interface for PrivKey struct +// func (hi PrivKeyLedger) Wrap() crypto.PrivKey { +// return PrivKey{hi} +// } + +// Wrap fulfils interface for PrivKey struct +func (pk MockPrivKeyLedger) Wrap() crypto.PrivKey { + return crypto.PrivKey{pk} +} + +// Wrap fulfils interface for PubKey struct +func (pk PubKeyLedger) Wrap() crypto.PubKey { + return crypto.PubKey{pk} +} From 7c5a10a7d49f2e908237644c496e90fa4fd2eb1d Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 12 Sep 2017 10:42:12 +0200 Subject: [PATCH 134/287] Add tests for pub/priv key validation --- nano/keys_test.go | 38 ++++++++++++++++++++++++++++++++++++++ nano/sign.go | 2 +- nano/sign_test.go | 2 +- 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 nano/keys_test.go diff --git a/nano/keys_test.go b/nano/keys_test.go new file mode 100644 index 000000000..32a0d444b --- /dev/null +++ b/nano/keys_test.go @@ -0,0 +1,38 @@ +package nano + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestLedgerKeys(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + // cryptoCase from sign_test + cases := []struct { + msg, pubkey, sig string + valid bool + }{ + { + msg: "F00D", + pubkey: "8E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C93", + sig: "787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400", + valid: true, + }, + } + + for i, tc := range cases { + bmsg, err := hex.DecodeString(tc.msg) + require.NoError(err, "%d", i) + + priv := NewMockKey(tc.msg, tc.pubkey, tc.sig) + pub := priv.PubKey() + sig := priv.Sign(bmsg) + + valid := pub.VerifyBytes(bmsg, sig) + assert.Equal(tc.valid, valid, "%d", i) + } +} diff --git a/nano/sign.go b/nano/sign.go index 50b874d15..3f0df9ee5 100644 --- a/nano/sign.go +++ b/nano/sign.go @@ -61,7 +61,7 @@ func parseDigest(resp []byte) (key, sig []byte, err error) { return key, sig, nil } -func parseKey(data []byte) (key crypto.PubKey, err error) { +func parseEdKey(data []byte) (key crypto.PubKey, err error) { ed := crypto.PubKeyEd25519{} if len(data) < len(ed) { return key, errors.Errorf("Key length too short: %d", len(data)) diff --git a/nano/sign_test.go b/nano/sign_test.go index 2f94c5e6f..2521514eb 100644 --- a/nano/sign_test.go +++ b/nano/sign_test.go @@ -86,7 +86,7 @@ func TestCryptoConvert(t *testing.T) { msg, key, sig, err := toBytes(tc) require.Nil(err, "%d: %+v", i, err) - pk, err := parseKey(key) + pk, err := parseEdKey(key) require.Nil(err, "%d: %+v", i, err) psig, err := parseSig(sig) require.Nil(err, "%d: %+v", i, err) From 265e261c6352e5b72d372e4bb8ed4eaff1fa2b09 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 12 Sep 2017 10:47:16 +0200 Subject: [PATCH 135/287] Add more test cases from running the ledger --- nano/keys_test.go | 39 +++++++++++++++++++++++++++++++++++++-- nano/sign_test.go | 40 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/nano/keys_test.go b/nano/keys_test.go index 32a0d444b..b46e4c9ff 100644 --- a/nano/keys_test.go +++ b/nano/keys_test.go @@ -11,17 +11,52 @@ import ( func TestLedgerKeys(t *testing.T) { assert, require := assert.New(t), require.New(t) - // cryptoCase from sign_test cases := []struct { msg, pubkey, sig string valid bool }{ - { + 0: { msg: "F00D", pubkey: "8E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C93", sig: "787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400", valid: true, }, + 1: { + msg: "DEADBEEF", + pubkey: "0C45ADC887A5463F668533443C829ED13EA8E2E890C778957DC28DB9D2AD5A6C", + sig: "00ED74EED8FDAC7988A14BF6BC222120CBAC249D569AF4C2ADABFC86B792F97DF73C4919BE4B6B0ACB53547273BF29FBF0A9E0992FFAB6CB6C9B09311FC86A00", + valid: true, + }, + 2: { + msg: "1234567890AA", + pubkey: "598FC1F0C76363D14D7480736DEEF390D85863360F075792A6975EFA149FD7EA", + sig: "59AAB7D7BDC4F936B6415DE672A8B77FA6B8B3451CD95B3A631F31F9A05DAEEE5E7E4F89B64DDEBB5F63DC042CA13B8FCB8185F82AD7FD5636FFDA6B0DC9570B", + valid: true, + }, + 3: { + msg: "1234432112344321", + pubkey: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", + sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", + valid: true, + }, + 4: { + msg: "12344321123443", + pubkey: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", + sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", + valid: false, + }, + 5: { + msg: "1234432112344321", + pubkey: "459E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", + sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", + valid: false, + }, + 6: { + msg: "1234432112344321", + pubkey: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", + sig: "716B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", + valid: false, + }, } for i, tc := range cases { diff --git a/nano/sign_test.go b/nano/sign_test.go index 2521514eb..89bd7568e 100644 --- a/nano/sign_test.go +++ b/nano/sign_test.go @@ -74,12 +74,48 @@ func TestCryptoConvert(t *testing.T) { assert, require := assert.New(t), require.New(t) cases := []cryptoCase{ - { + 0: { msg: "F00D", key: "8E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C93", sig: "787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400", valid: true, }, + 1: { + msg: "DEADBEEF", + key: "0C45ADC887A5463F668533443C829ED13EA8E2E890C778957DC28DB9D2AD5A6C", + sig: "00ED74EED8FDAC7988A14BF6BC222120CBAC249D569AF4C2ADABFC86B792F97DF73C4919BE4B6B0ACB53547273BF29FBF0A9E0992FFAB6CB6C9B09311FC86A00", + valid: true, + }, + 2: { + msg: "1234567890AA", + key: "598FC1F0C76363D14D7480736DEEF390D85863360F075792A6975EFA149FD7EA", + sig: "59AAB7D7BDC4F936B6415DE672A8B77FA6B8B3451CD95B3A631F31F9A05DAEEE5E7E4F89B64DDEBB5F63DC042CA13B8FCB8185F82AD7FD5636FFDA6B0DC9570B", + valid: true, + }, + 3: { + msg: "1234432112344321", + key: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", + sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", + valid: true, + }, + 4: { + msg: "12344321123443", + key: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", + sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", + valid: false, + }, + 5: { + msg: "1234432112344321", + key: "459E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", + sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", + valid: false, + }, + 6: { + msg: "1234432112344321", + key: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", + sig: "716B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", + valid: false, + }, } for i, tc := range cases { @@ -93,7 +129,7 @@ func TestCryptoConvert(t *testing.T) { // it is not the signature of the message itself valid := pk.VerifyBytes(msg, psig) - assert.NotEqual(tc.valid, valid, "%d", i) + assert.False(valid, "%d", i) // but rather of the hash of the msg hmsg := hashMsg(msg) From 623bd803c283d742f28f7ae46058b9b105628fbf Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 12 Sep 2017 11:40:30 +0200 Subject: [PATCH 136/287] write code to actually call ledger app --- nano/keys.go | 117 ++++++++++++++++++++++++++++++++++------------ nano/keys_test.go | 8 ++++ signature.go | 6 +++ 3 files changed, 101 insertions(+), 30 deletions(-) diff --git a/nano/keys.go b/nano/keys.go index 7b76fa87f..cd5c90317 100644 --- a/nano/keys.go +++ b/nano/keys.go @@ -4,39 +4,91 @@ import ( "bytes" "encoding/hex" + ledger "github.com/ethanfrey/ledger" + crypto "github.com/tendermint/go-crypto" ) -// // Implements PrivKey, calling the ledger nano -// type PrivKeyLedger struct{} +var device *ledger.Ledger + +// getLedger gets a copy of the device, and caches it +func getLedger() (*ledger.Ledger, error) { + var err error + if device == nil { + device, err = ledger.FindLedger() + } + return device, err +} + +func signLedger(device *ledger.Ledger, msg []byte) (pk crypto.PubKey, sig crypto.Signature, err error) { + var resp []byte + + packets := generateSignRequests(msg) + for _, pack := range packets { + resp, err = device.Exchange(pack, 100) + if err != nil { + return pk, sig, err + } + } + + // the last call is the result we want and needs to be parsed + key, bsig, err := parseDigest(resp) + if err != nil { + return pk, sig, err + } + + var b [32]byte + copy(b[:], key) + return PubKeyLedgerFromBytes(b), crypto.SignatureEd25519FromBytes(bsig), nil +} + +// PrivKeyLedger implements PrivKey, calling the ledger nano +// we cache the PubKey from the first call to use it later +type PrivKeyLedger struct { + pubKey crypto.PubKey +} + +var _ crypto.PrivKeyInner = &PrivKeyLedger{} + +// AssertIsPrivKeyInner fulfils PrivKey Interface +func (pk *PrivKeyLedger) AssertIsPrivKeyInner() {} -// var _ PrivKeyInner = PrivKeyLedger{} +// Bytes fulfils pk Interface - not supported +func (pk *PrivKeyLedger) Bytes() []byte { + return nil +} -// func (privKey PrivKeyLedger) AssertIsPrivKeyInner() {} +// Sign calls the ledger and stores the pk for future use +func (pk *PrivKeyLedger) Sign(msg []byte) crypto.Signature { + // oh, I wish there was better error handling + dev, err := getLedger() + if err != nil { + panic(err) + } -// func (privKey PrivKeyLedger) Bytes() []byte { -// return wire.BinaryBytes(PrivKey{privKey}) -// } + pub, sig, err := signLedger(dev, msg) + if err != nil { + panic(err) + } -// func (privKey PrivKeyLedger) Sign(msg []byte) Signature { -// privKeyBytes := [64]byte(privKey) -// signatureBytes := ed25519.Sign(&privKeyBytes, msg) -// return SignatureEd25519(*signatureBytes).Wrap() -// } + pk.pubKey = pub + return sig +} -// func (privKey PrivKeyLedger) PubKey() PubKey { -// privKeyBytes := [64]byte(privKey) -// pubBytes := *ed25519.MakePublicKey(&privKeyBytes) -// return PubKeyEd25519(pubBytes).Wrap() -// } +// PubKey returns the stored PubKey +// TODO: query the ledger if not there, once it is not volatile +func (pk *PrivKeyLedger) PubKey() crypto.PubKey { + return pk.pubKey +} -// func (privKey PrivKeyLedger) Equals(other PrivKey) bool { -// if otherEd, ok := other.Unwrap().(PrivKeyLedger); ok { -// return bytes.Equal(privKey[:], otherEd[:]) -// } else { -// return false -// } -// } +// Equals fulfils PrivKey Interface +// TODO: needs to be fixed +func (pk *PrivKeyLedger) Equals(other crypto.PrivKey) bool { + if _, ok := other.Unwrap().(*PrivKeyLedger); ok { + return true + } + return false +} // MockPrivKeyLedger behaves as the ledger, but stores a pre-packaged call-response // for use in test cases @@ -88,7 +140,7 @@ func (pk MockPrivKeyLedger) Sign(msg []byte) crypto.Signature { // PubKey returns a real PubKeyLedger, that will verify this signature func (pk MockPrivKeyLedger) PubKey() crypto.PubKey { - return PubKeyLedger{crypto.PubKeyEd25519(pk.Pub)}.Wrap() + return PubKeyLedgerFromBytes(pk.Pub) } // Equals compares that two Mocks have the same data @@ -109,6 +161,11 @@ type PubKeyLedger struct { crypto.PubKeyEd25519 } +// PubKeyLedgerFromBytes creates a PubKey from the raw bytes +func PubKeyLedgerFromBytes(key [32]byte) crypto.PubKey { + return PubKeyLedger{crypto.PubKeyEd25519(key)}.Wrap() +} + // VerifyBytes uses the normal Ed25519 algorithm but a sha512 hash beforehand func (pk PubKeyLedger) VerifyBytes(msg []byte, sig crypto.Signature) bool { hmsg := hashMsg(msg) @@ -127,17 +184,17 @@ func (pk PubKeyLedger) Equals(other crypto.PubKey) bool { func init() { crypto.PrivKeyMapper. - // RegisterImplementation(PrivKeyLedger{}, "ledger", 0x10). + RegisterImplementation(&PrivKeyLedger{}, "ledger", 0x10). RegisterImplementation(MockPrivKeyLedger{}, "mock-ledger", 0x11) crypto.PubKeyMapper. RegisterImplementation(PubKeyLedger{}, "ledger", 0x10) } -// // Wrap fulfils interface for PrivKey struct -// func (hi PrivKeyLedger) Wrap() crypto.PrivKey { -// return PrivKey{hi} -// } +// Wrap fulfils interface for PrivKey struct +func (pk *PrivKeyLedger) Wrap() crypto.PrivKey { + return crypto.PrivKey{pk} +} // Wrap fulfils interface for PrivKey struct func (pk MockPrivKeyLedger) Wrap() crypto.PrivKey { diff --git a/nano/keys_test.go b/nano/keys_test.go index b46e4c9ff..5ceae2afa 100644 --- a/nano/keys_test.go +++ b/nano/keys_test.go @@ -2,6 +2,7 @@ package nano import ( "encoding/hex" + "os" "testing" "github.com/stretchr/testify/assert" @@ -71,3 +72,10 @@ func TestLedgerKeys(t *testing.T) { assert.Equal(tc.valid, valid, "%d", i) } } + +func TestRealLedger(t *testing.T) { + if os.Getenv("WITH_LEDGER") == "" { + t.Skip("Set WITH_LEDGER to run code on real ledger") + } + // let's try for real.... +} diff --git a/signature.go b/signature.go index 5b1d6cb05..d2ea45132 100644 --- a/signature.go +++ b/signature.go @@ -63,6 +63,12 @@ func (sig *SignatureEd25519) UnmarshalJSON(enc []byte) error { return err } +func SignatureEd25519FromBytes(data []byte) Signature { + var sig SignatureEd25519 + copy(sig[:], data) + return sig.Wrap() +} + //------------------------------------- var _ SignatureInner = SignatureSecp256k1{} From 008dba3af821bacf599da3c282f387fb9394119d Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 12 Sep 2017 11:48:43 +0200 Subject: [PATCH 137/287] Test ledger calls --- nano/keys.go | 5 ++++- nano/keys_test.go | 10 +++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/nano/keys.go b/nano/keys.go index cd5c90317..55af915cb 100644 --- a/nano/keys.go +++ b/nano/keys.go @@ -48,7 +48,10 @@ type PrivKeyLedger struct { pubKey crypto.PubKey } -var _ crypto.PrivKeyInner = &PrivKeyLedger{} +func NewPrivKeyLedger() crypto.PrivKey { + var pk PrivKeyLedger + return pk.Wrap() +} // AssertIsPrivKeyInner fulfils PrivKey Interface func (pk *PrivKeyLedger) AssertIsPrivKeyInner() {} diff --git a/nano/keys_test.go b/nano/keys_test.go index 5ceae2afa..3f2eb9a1f 100644 --- a/nano/keys_test.go +++ b/nano/keys_test.go @@ -77,5 +77,13 @@ func TestRealLedger(t *testing.T) { if os.Getenv("WITH_LEDGER") == "" { t.Skip("Set WITH_LEDGER to run code on real ledger") } - // let's try for real.... + + priv := NewPrivKeyLedger() + msg := []byte("kuhehfeohg") + + sig := priv.Sign(msg) + pub := priv.PubKey() + + valid := pub.VerifyBytes(msg, sig) + assert.True(t, valid) } From 081f21af119b8d748c42c049e2b81815c93ae323 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 12 Sep 2017 12:57:30 +0200 Subject: [PATCH 138/287] Add glide version for ledger drivers --- glide.lock | 30 ++++++++++++++---------------- glide.yaml | 1 + 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/glide.lock b/glide.lock index 1c23d8bea..29124c3db 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: c0a2db1b80c6b1b8aab31c526ce43e22e49b23c893c78b8fdb8546aa2e7b7cc6 -updated: 2017-09-22T10:21:34.220901552-04:00 +hash: a2243bfd21937edf660778300855e7cb72185164641cb278dbf0c220e8a0f60a +updated: 2017-10-23T17:21:02.40831023+02:00 imports: - name: github.com/bgentry/speakeasy version: 4aabc24848ce5fd31929f7d1e4ea74d3709c14cd @@ -11,16 +11,16 @@ imports: - chaincfg/chainhash - wire - name: github.com/btcsuite/btcutil - version: 86346b5a958c0cf94186b87855469ae991be501c + version: 66871daeb12123ece012a9628d2798d01195c4b3 subpackages: - base58 - hdkeychain - name: github.com/btcsuite/fastsha256 version: 637e656429416087660c84436a2a035d69d54e2e -- name: github.com/btcsuite/golangcrypto - version: 53f62d9b43e87a6c56975cf862af7edf33a8d0df - subpackages: - - ripemd160 +- name: github.com/ethanfrey/ledger + version: 5e432577be582bd18a3b4a9cd75dae7a317ade36 +- name: github.com/flynn/hid + version: ed06a31c6245d4552e8dbba7e32e5b010b875d65 - name: github.com/go-kit/kit version: d67bb4c202e3b91377d1079b110a6c9ce23ab2f8 subpackages: @@ -44,7 +44,7 @@ imports: - name: github.com/gorilla/mux version: bcd8bc72b08df0f70df986b97f95590779502d31 - name: github.com/howeyc/crc16 - version: 96a97a1abb579c7ff1a8ffa77f2e72d1c314b57f + version: 58da63c846043d0bea709c8d47039df06577d6d9 - name: github.com/kr/logfmt version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0 - name: github.com/pkg/errors @@ -59,12 +59,12 @@ imports: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: 5f88da3dbc1a72844e6dfaf274ce87f851d488eb + version: 55ae61f1fc83cfaa57ab7d54250d7a1a2be0b83c subpackages: - data - data/base58 - name: github.com/tendermint/tmlibs - version: bffe6744ec277d60f707ab442e25513617842f8e + version: 8e5266a9ef2527e68a1571f932db8228a331b556 subpackages: - common - log @@ -81,16 +81,14 @@ imports: - ripemd160 - salsa20/salsa - name: gopkg.in/go-playground/validator.v9 - version: d529ee1b0f30352444f507cc6cdac96bfd12decc + version: 6d8c18553ea1ac493d049edd6f102f52e618f085 testImports: +- name: github.com/cmars/basen + version: fe3947df716ebfda9847eb1b9a48f9592e06478c - name: github.com/davecgh/go-spew version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 subpackages: - spew -- name: github.com/FactomProject/basen - version: fe3947df716ebfda9847eb1b9a48f9592e06478c -- name: github.com/FactomProject/btcutilecc - version: d3a63a5752ecf3fbc06bd97365da752111c263df - name: github.com/mndrix/btcutil version: d3a63a5752ecf3fbc06bd97365da752111c263df - name: github.com/pmezard/go-difflib @@ -103,6 +101,6 @@ testImports: - assert - require - name: github.com/tyler-smith/go-bip32 - version: 2c9cfd17756470a0b7c3e4b7954bae7d11035504 + version: eb790af526c30f23a7c8b00a48e342f9d0bd6386 - name: github.com/tyler-smith/go-bip39 version: 8e7a99b3e716f36d3b080a9a70f9eb45abe4edcc diff --git a/glide.yaml b/glide.yaml index a99d3b63f..9f20ddefc 100644 --- a/glide.yaml +++ b/glide.yaml @@ -30,6 +30,7 @@ import: - package: github.com/spf13/viper - package: gopkg.in/go-playground/validator.v9 - package: github.com/howeyc/crc16 +- package: github.com/ethanfrey/ledger testImport: - package: github.com/mndrix/btcutil - package: github.com/stretchr/testify From 3edeb0cd45a9a8a97dbafb901894a51c8f8af688 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 13 Sep 2017 11:53:14 +0200 Subject: [PATCH 139/287] Ledger caches pubkey, works with newer firmware --- nano/keys.go | 39 +++++++++++++++++++++++++++++++++++---- nano/keys_test.go | 10 ++++++---- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/nano/keys.go b/nano/keys.go index 55af915cb..7cac5eee8 100644 --- a/nano/keys.go +++ b/nano/keys.go @@ -4,6 +4,8 @@ import ( "bytes" "encoding/hex" + "github.com/pkg/errors" + ledger "github.com/ethanfrey/ledger" crypto "github.com/tendermint/go-crypto" @@ -48,9 +50,13 @@ type PrivKeyLedger struct { pubKey crypto.PubKey } -func NewPrivKeyLedger() crypto.PrivKey { +func NewPrivKeyLedger() (crypto.PrivKey, error) { var pk PrivKeyLedger - return pk.Wrap() + // getPubKey will cache the pubkey for later use, + // this allows us to return an error early if the ledger + // is not plugged in + _, err := pk.getPubKey() + return pk.Wrap(), err } // AssertIsPrivKeyInner fulfils PrivKey Interface @@ -74,14 +80,39 @@ func (pk *PrivKeyLedger) Sign(msg []byte) crypto.Signature { panic(err) } - pk.pubKey = pub + // if we have no pubkey yet, store it for future queries + if pk.pubKey.Empty() { + pk.pubKey = pub + } return sig } // PubKey returns the stored PubKey // TODO: query the ledger if not there, once it is not volatile func (pk *PrivKeyLedger) PubKey() crypto.PubKey { - return pk.pubKey + key, err := pk.getPubKey() + if err != nil { + panic(err) + } + return key +} + +// getPubKey reads the pubkey from cache or from the ledger itself +// since this involves IO, it may return an error, which is not exposed +// in the PubKey interface, so this function allows better error handling +func (pk *PrivKeyLedger) getPubKey() (key crypto.PubKey, err error) { + // if we have no pubkey, set it + if pk.pubKey.Empty() { + dev, err := getLedger() + if err != nil { + return key, errors.WithMessage(err, "Can't connect to ledger") + } + pk.pubKey, _, err = signLedger(dev, []byte{0}) + if err != nil { + return key, errors.WithMessage(err, "Can't sign with app") + } + } + return pk.pubKey, nil } // Equals fulfils PrivKey Interface diff --git a/nano/keys_test.go b/nano/keys_test.go index 3f2eb9a1f..3a4d9c1eb 100644 --- a/nano/keys_test.go +++ b/nano/keys_test.go @@ -74,16 +74,18 @@ func TestLedgerKeys(t *testing.T) { } func TestRealLedger(t *testing.T) { + assert, require := assert.New(t), require.New(t) + if os.Getenv("WITH_LEDGER") == "" { t.Skip("Set WITH_LEDGER to run code on real ledger") } - - priv := NewPrivKeyLedger() msg := []byte("kuhehfeohg") - sig := priv.Sign(msg) + priv, err := NewPrivKeyLedger() + require.Nil(err, "%+v", err) pub := priv.PubKey() + sig := priv.Sign(msg) valid := pub.VerifyBytes(msg, sig) - assert.True(t, valid) + assert.True(valid) } From 0383feab494f1a8a3d4d1327890375fa123f3f07 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 13 Sep 2017 11:59:17 +0200 Subject: [PATCH 140/287] Add and test serialization of ledger privkey --- nano/keys.go | 5 +++-- nano/keys_test.go | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/nano/keys.go b/nano/keys.go index 7cac5eee8..6b337e8b7 100644 --- a/nano/keys.go +++ b/nano/keys.go @@ -9,6 +9,7 @@ import ( ledger "github.com/ethanfrey/ledger" crypto "github.com/tendermint/go-crypto" + wire "github.com/tendermint/go-wire" ) var device *ledger.Ledger @@ -62,9 +63,9 @@ func NewPrivKeyLedger() (crypto.PrivKey, error) { // AssertIsPrivKeyInner fulfils PrivKey Interface func (pk *PrivKeyLedger) AssertIsPrivKeyInner() {} -// Bytes fulfils pk Interface - not supported +// Bytes fulfils pk Interface - no data, just type info func (pk *PrivKeyLedger) Bytes() []byte { - return nil + return wire.BinaryBytes(pk.Wrap()) } // Sign calls the ledger and stores the pk for future use diff --git a/nano/keys_test.go b/nano/keys_test.go index 3a4d9c1eb..b42b091f0 100644 --- a/nano/keys_test.go +++ b/nano/keys_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + crypto "github.com/tendermint/go-crypto" ) func TestLedgerKeys(t *testing.T) { @@ -88,4 +89,19 @@ func TestRealLedger(t *testing.T) { valid := pub.VerifyBytes(msg, sig) assert.True(valid) + + // now, let's serialize the key and make sure it still works + bs := priv.Bytes() + priv2, err := crypto.PrivKeyFromBytes(bs) + require.Nil(err, "%+v", err) + + // make sure we get the same pubkey when we load from disk + pub2 := priv2.PubKey() + require.Equal(pub, pub2) + + // signing with the loaded key should match the original pubkey + sig = priv2.Sign(msg) + valid = pub.VerifyBytes(msg, sig) + assert.True(valid) + } From 8c98c4fdf46aafc3b9d8690902ad38b8835a636a Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 13 Sep 2017 12:41:54 +0200 Subject: [PATCH 141/287] Add nano ledger to key manager --- keys/cryptostore/generator.go | 18 ++++++++++++++++++ nano/keys.go | 24 ++++++++++++++++-------- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/keys/cryptostore/generator.go b/keys/cryptostore/generator.go index 1f162ec08..c1984fc82 100644 --- a/keys/cryptostore/generator.go +++ b/keys/cryptostore/generator.go @@ -4,6 +4,7 @@ import ( "github.com/pkg/errors" crypto "github.com/tendermint/go-crypto" + "github.com/tendermint/go-crypto/nano" ) var ( @@ -11,6 +12,8 @@ var ( GenEd25519 Generator = GenFunc(genEd25519) // GenSecp256k1 produces Secp256k1 private keys GenSecp256k1 Generator = GenFunc(genSecp256) + // GenLedger used Ed25519 keys stored on nano ledger s with cosmos app + GenLedger Generator = GenFunc(genLedger) ) // Generator determines the type of private key the keystore creates @@ -33,12 +36,25 @@ func genSecp256(secret []byte) crypto.PrivKey { return crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap() } +// secret is completely ignored for the ledger... +// just for interface compatibility +func genLedger(secret []byte) crypto.PrivKey { + key, err := nano.NewPrivKeyLedger() + if err != nil { + // TODO: cleaner error handling + panic(err) + } + return key +} + func getGenerator(algo string) (Generator, error) { switch algo { case crypto.NameEd25519: return GenEd25519, nil case crypto.NameSecp256k1: return GenSecp256k1, nil + case nano.NameLedger: + return GenLedger, nil default: return nil, errors.Errorf("Cannot generate keys for algorithm: %s", algo) } @@ -50,6 +66,8 @@ func getGeneratorByType(typ byte) (Generator, error) { return GenEd25519, nil case crypto.TypeSecp256k1: return GenSecp256k1, nil + case nano.TypeLedger: + return GenLedger, nil default: return nil, errors.Errorf("Cannot generate keys for algorithm: %X", typ) } diff --git a/nano/keys.go b/nano/keys.go index 6b337e8b7..2ab4d59a8 100644 --- a/nano/keys.go +++ b/nano/keys.go @@ -12,6 +12,11 @@ import ( wire "github.com/tendermint/go-wire" ) +const ( + NameLedger = "ledger" + TypeLedger = 0x10 +) + var device *ledger.Ledger // getLedger gets a copy of the device, and caches it @@ -48,7 +53,10 @@ func signLedger(device *ledger.Ledger, msg []byte) (pk crypto.PubKey, sig crypto // PrivKeyLedger implements PrivKey, calling the ledger nano // we cache the PubKey from the first call to use it later type PrivKeyLedger struct { - pubKey crypto.PubKey + // PubKey should be private, but we want to encode it via go-wire + // so we can view the address later, even without having the ledger + // attached + CachedPubKey crypto.PubKey } func NewPrivKeyLedger() (crypto.PrivKey, error) { @@ -82,8 +90,8 @@ func (pk *PrivKeyLedger) Sign(msg []byte) crypto.Signature { } // if we have no pubkey yet, store it for future queries - if pk.pubKey.Empty() { - pk.pubKey = pub + if pk.CachedPubKey.Empty() { + pk.CachedPubKey = pub } return sig } @@ -103,17 +111,17 @@ func (pk *PrivKeyLedger) PubKey() crypto.PubKey { // in the PubKey interface, so this function allows better error handling func (pk *PrivKeyLedger) getPubKey() (key crypto.PubKey, err error) { // if we have no pubkey, set it - if pk.pubKey.Empty() { + if pk.CachedPubKey.Empty() { dev, err := getLedger() if err != nil { return key, errors.WithMessage(err, "Can't connect to ledger") } - pk.pubKey, _, err = signLedger(dev, []byte{0}) + pk.CachedPubKey, _, err = signLedger(dev, []byte{0}) if err != nil { return key, errors.WithMessage(err, "Can't sign with app") } } - return pk.pubKey, nil + return pk.CachedPubKey, nil } // Equals fulfils PrivKey Interface @@ -219,11 +227,11 @@ func (pk PubKeyLedger) Equals(other crypto.PubKey) bool { func init() { crypto.PrivKeyMapper. - RegisterImplementation(&PrivKeyLedger{}, "ledger", 0x10). + RegisterImplementation(&PrivKeyLedger{}, NameLedger, TypeLedger). RegisterImplementation(MockPrivKeyLedger{}, "mock-ledger", 0x11) crypto.PubKeyMapper. - RegisterImplementation(PubKeyLedger{}, "ledger", 0x10) + RegisterImplementation(PubKeyLedger{}, NameLedger, TypeLedger) } // Wrap fulfils interface for PrivKey struct From 34b9309f245df9bfdcd2697e7cd148f57e57fa2a Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 13 Sep 2017 13:13:38 +0200 Subject: [PATCH 142/287] Re-enable signing tests with cryptostore --- keys/cryptostore/holder_test.go | 118 +++++++++++++++++--------------- keys/transactions.go | 51 ++++++++++++++ 2 files changed, 112 insertions(+), 57 deletions(-) diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index a8fc90989..d9e2783af 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -84,65 +84,69 @@ func TestKeyManagement(t *testing.T) { // TestSignVerify does some detailed checks on how we sign and validate // signatures -// func TestSignVerify(t *testing.T) { -// assert, require := assert.New(t), require.New(t) +func TestSignVerify(t *testing.T) { + assert, require := assert.New(t), require.New(t) -// // make the storage with reasonable defaults -// cstore := cryptostore.New( -// cryptostore.GenSecp256k1, -// cryptostore.SecretBox, -// memstorage.New(), -// ) + // make the storage with reasonable defaults + cstore := cryptostore.New( + cryptostore.SecretBox, + memstorage.New(), + keys.MustLoadCodec("english"), + ) + algo := crypto.NameSecp256k1 -// n1, n2 := "some dude", "a dudette" -// p1, p2 := "1234", "foobar" - -// // create two users and get their info -// err := cstore.Create(n1, p1) -// require.Nil(err) -// i1, err := cstore.Get(n1) -// require.Nil(err) - -// err = cstore.Create(n2, p2) -// require.Nil(err) -// i2, err := cstore.Get(n2) -// require.Nil(err) - -// // let's try to sign some messages -// d1 := []byte("my first message") -// d2 := []byte("some other important info!") - -// // try signing both data with both keys... -// s11, err := cstore.Signature(n1, p1, d1) -// require.Nil(err) -// s12, err := cstore.Signature(n1, p1, d2) -// require.Nil(err) -// s21, err := cstore.Signature(n2, p2, d1) -// require.Nil(err) -// s22, err := cstore.Signature(n2, p2, d2) -// require.Nil(err) - -// // let's try to validate and make sure it only works when everything is proper -// keys := [][]byte{i1.PubKey, i2.PubKey} -// data := [][]byte{d1, d2} -// sigs := [][]byte{s11, s12, s21, s22} - -// // loop over keys and data -// for k := 0; k < 2; k++ { -// for d := 0; d < 2; d++ { -// // make sure only the proper sig works -// good := 2*k + d -// for s := 0; s < 4; s++ { -// err = cstore.Verify(data[d], sigs[s], keys[k]) -// if s == good { -// assert.Nil(err, "%+v", err) -// } else { -// assert.NotNil(err) -// } -// } -// } -// } -// } + n1, n2 := "some dude", "a dudette" + p1, p2 := "1234", "foobar" + + // create two users and get their info + i1, _, err := cstore.Create(n1, p1, algo) + require.Nil(err) + + i2, _, err := cstore.Create(n2, p2, algo) + require.Nil(err) + + // let's try to sign some messages + d1 := []byte("my first message") + d2 := []byte("some other important info!") + + // try signing both data with both keys... + s11 := keys.NewMockSignable(d1) + err = cstore.Sign(n1, p1, s11) + require.Nil(err) + s12 := keys.NewMockSignable(d2) + err = cstore.Sign(n1, p1, s12) + require.Nil(err) + s21 := keys.NewMockSignable(d1) + err = cstore.Sign(n2, p2, s21) + require.Nil(err) + s22 := keys.NewMockSignable(d2) + err = cstore.Sign(n2, p2, s22) + require.Nil(err) + + // let's try to validate and make sure it only works when everything is proper + cases := []struct { + key crypto.PubKey + data []byte + sig crypto.Signature + valid bool + }{ + // proper matches + {i1.PubKey, d1, s11.Signature, true}, + // change data, pubkey, or signature leads to fail + {i1.PubKey, d2, s11.Signature, false}, + {i2.PubKey, d1, s11.Signature, false}, + {i1.PubKey, d1, s21.Signature, false}, + // make sure other successes + {i1.PubKey, d2, s12.Signature, true}, + {i2.PubKey, d1, s21.Signature, true}, + {i2.PubKey, d2, s22.Signature, true}, + } + + for i, tc := range cases { + valid := tc.key.VerifyBytes(tc.data, tc.sig) + assert.Equal(tc.valid, valid, "%d", i) + } +} func assertPassword(assert *assert.Assertions, cstore cryptostore.Manager, name, pass, badpass string) { err := cstore.Update(name, badpass, pass) diff --git a/keys/transactions.go b/keys/transactions.go index 10da7a6fa..1834ada26 100644 --- a/keys/transactions.go +++ b/keys/transactions.go @@ -1,9 +1,11 @@ package keys import ( + "fmt" "sort" crypto "github.com/tendermint/go-crypto" + wire "github.com/tendermint/go-wire" data "github.com/tendermint/go-wire/data" ) @@ -72,3 +74,52 @@ type Manager interface { Update(name, oldpass, newpass string) error Delete(name, passphrase string) error } + +/**** MockSignable allows us to view data ***/ + +// MockSignable lets us wrap arbitrary data with a go-crypto signature +type MockSignable struct { + Data []byte + PubKey crypto.PubKey + Signature crypto.Signature +} + +var _ Signable = &MockSignable{} + +// NewMockSignable sets the data to sign +func NewMockSignable(data []byte) *MockSignable { + return &MockSignable{Data: data} +} + +// TxBytes returns the full data with signatures +func (s *MockSignable) TxBytes() ([]byte, error) { + return wire.BinaryBytes(s), nil +} + +// SignBytes returns the original data passed into `NewSig` +func (s *MockSignable) SignBytes() []byte { + return s.Data +} + +// Sign will add a signature and pubkey. +// +// Depending on the Signable, one may be able to call this multiple times for multisig +// Returns error if called with invalid data or too many times +func (s *MockSignable) Sign(pubkey crypto.PubKey, sig crypto.Signature) error { + s.PubKey = pubkey + s.Signature = sig + return nil +} + +// Signers will return the public key(s) that signed if the signature +// is valid, or an error if there is any issue with the signature, +// including if there are no signatures +func (s *MockSignable) Signers() ([]crypto.PubKey, error) { + if s.PubKey.Empty() { + return nil, fmt.Errorf("no signers") + } + if !s.PubKey.VerifyBytes(s.SignBytes(), s.Signature) { + return nil, fmt.Errorf("invalid signature") + } + return []crypto.PubKey{s.PubKey}, nil +} From 88475230c46274bfde4f58649d3228622b7c8eba Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 13 Sep 2017 13:23:18 +0200 Subject: [PATCH 143/287] Re-enabled crypostore example usage --- keys/cryptostore/holder_test.go | 100 ++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 42 deletions(-) diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index d9e2783af..59d3663ae 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -1,6 +1,8 @@ package cryptostore_test import ( + "bytes" + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -260,45 +262,59 @@ func TestSeedPhrase(t *testing.T) { assert.Equal(info.PubKey, newInfo.PubKey) } -// func ExampleStore() { -// // Select the encryption and storage for your cryptostore -// cstore := cryptostore.New( -// cryptostore.GenEd25519, -// cryptostore.SecretBox, -// // Note: use filestorage.New(dir) for real data -// memstorage.New(), -// ) - -// // Add keys and see they return in alphabetical order -// cstore.Create("Bob", "friend") -// cstore.Create("Alice", "secret") -// cstore.Create("Carl", "mitm") -// info, _ := cstore.List() -// for _, i := range info { -// fmt.Println(i.Name) -// } - -// // We need to use passphrase to generate a signature -// tx := mock.NewSig([]byte("deadbeef")) -// err := cstore.Sign("Bob", "friend", tx) -// if err != nil { -// fmt.Println("don't accept real passphrase") -// } - -// // and we can validate the signature with publically available info -// binfo, _ := cstore.Get("Bob") -// sigs, err := tx.Signers() -// if err != nil { -// fmt.Println("badly signed") -// } else if bytes.Equal(sigs[0].Bytes(), binfo.PubKey.Bytes()) { -// fmt.Println("signed by Bob") -// } else { -// fmt.Println("signed by someone else") -// } - -// // Output: -// // Alice -// // Bob -// // Carl -// // signed by Bob -// } +func ExampleStore() { + // Select the encryption and storage for your cryptostore + cstore := cryptostore.New( + cryptostore.SecretBox, + // Note: use filestorage.New(dir) for real data + memstorage.New(), + keys.MustLoadCodec("english"), + ) + ed := crypto.NameEd25519 + sec := crypto.NameSecp256k1 + + // Add keys and see they return in alphabetical order + bob, _, err := cstore.Create("Bob", "friend", ed) + if err != nil { + // this should never happen + fmt.Println(err) + } else { + // return info here just like in List + fmt.Println(bob.Name) + } + cstore.Create("Alice", "secret", sec) + cstore.Create("Carl", "mitm", ed) + info, _ := cstore.List() + for _, i := range info { + fmt.Println(i.Name) + } + + // We need to use passphrase to generate a signature + tx := keys.NewMockSignable([]byte("deadbeef")) + err = cstore.Sign("Bob", "friend", tx) + if err != nil { + fmt.Println("don't accept real passphrase") + } + + // and we can validate the signature with publically available info + binfo, _ := cstore.Get("Bob") + if !binfo.PubKey.Equals(bob.PubKey) { + fmt.Println("Get and Create return different keys") + } + + sigs, err := tx.Signers() + if err != nil { + fmt.Println("badly signed") + } else if bytes.Equal(sigs[0].Bytes(), binfo.PubKey.Bytes()) { + fmt.Println("signed by Bob") + } else { + fmt.Println("signed by someone else") + } + + // Output: + // Bob + // Alice + // Bob + // Carl + // signed by Bob +} From 91fccb8b14574c7a7041ed221663bcdc3f225939 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 13 Sep 2017 13:34:04 +0200 Subject: [PATCH 144/287] Add test for cryptostore working with ledger --- keys/cryptostore/holder_test.go | 55 +++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index 59d3663ae..dbd269717 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -3,6 +3,7 @@ package cryptostore_test import ( "bytes" "fmt" + "os" "testing" "github.com/stretchr/testify/assert" @@ -14,6 +15,7 @@ import ( "github.com/tendermint/go-crypto/keys" "github.com/tendermint/go-crypto/keys/cryptostore" "github.com/tendermint/go-crypto/keys/storage/memstorage" + "github.com/tendermint/go-crypto/nano" ) // TestKeyManagement makes sure we can manipulate these keys well @@ -150,6 +152,59 @@ func TestSignVerify(t *testing.T) { } } +// TestSignWithLedger makes sure we have ledger compatibility with +// the crypto store. +// +// This test will only succeed with a ledger attached to the computer +// and the cosmos app open +func TestSignWithLedger(t *testing.T) { + assert, require := assert.New(t), require.New(t) + if os.Getenv("WITH_LEDGER") == "" { + t.Skip("Set WITH_LEDGER to run code on real ledger") + } + + // make the storage with reasonable defaults + cstore := cryptostore.New( + cryptostore.SecretBox, + memstorage.New(), + keys.MustLoadCodec("english"), + ) + n := "nano-s" + p := "hard2hack" + + // create a nano user + c, _, err := cstore.Create(n, p, nano.NameLedger) + require.Nil(err, "%+v", err) + assert.Equal(c.Name, n) + _, ok := c.PubKey.Unwrap().(nano.PubKeyLedger) + require.True(ok) + + // make sure we can get it back + info, err := cstore.Get(n) + require.Nil(err, "%+v", err) + assert.Equal(info.Name, n) + key := info.PubKey + require.False(key.Empty()) + + // let's try to sign some messages + d1 := []byte("welcome to cosmos") + d2 := []byte("please turn on the app") + + // try signing both data with the ledger... + s1 := keys.NewMockSignable(d1) + err = cstore.Sign(n, p, s1) + require.Nil(err) + s2 := keys.NewMockSignable(d2) + err = cstore.Sign(n, p, s2) + require.Nil(err) + + // now, let's check those signatures work + assert.True(key.VerifyBytes(d1, s1.Signature)) + assert.True(key.VerifyBytes(d2, s2.Signature)) + // and mismatched signatures don't + assert.False(key.VerifyBytes(d1, s2.Signature)) +} + func assertPassword(assert *assert.Assertions, cstore cryptostore.Manager, name, pass, badpass string) { err := cstore.Update(name, badpass, pass) assert.NotNil(err) From 085d72d212b72aea196ffd1b32f06df908b09a9b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 13 Sep 2017 13:53:08 +0200 Subject: [PATCH 145/287] Cleanup nano calls, cannot run parallel test on one hardware device --- Makefile | 2 +- keys/cryptostore/holder_test.go | 1 + nano/keys.go | 2 ++ nano/sign.go | 2 -- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index f775704a9..c1974c410 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ REPO:=github.com/tendermint/go-crypto all: get_vendor_deps metalinter_test test test: - go test `glide novendor` + go test -p 1 `glide novendor` get_vendor_deps: ensure_tools @rm -rf vendor/ diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index dbd269717..f0dc77c4d 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -185,6 +185,7 @@ func TestSignWithLedger(t *testing.T) { assert.Equal(info.Name, n) key := info.PubKey require.False(key.Empty()) + require.True(key.Equals(c.PubKey)) // let's try to sign some messages d1 := []byte("welcome to cosmos") diff --git a/nano/keys.go b/nano/keys.go index 2ab4d59a8..c0eccc492 100644 --- a/nano/keys.go +++ b/nano/keys.go @@ -92,6 +92,8 @@ func (pk *PrivKeyLedger) Sign(msg []byte) crypto.Signature { // if we have no pubkey yet, store it for future queries if pk.CachedPubKey.Empty() { pk.CachedPubKey = pub + } else if !pk.CachedPubKey.Equals(pub) { + panic("signed with a different key than stored") } return sig } diff --git a/nano/sign.go b/nano/sign.go index 3f0df9ee5..874d134e8 100644 --- a/nano/sign.go +++ b/nano/sign.go @@ -3,7 +3,6 @@ package nano import ( "bytes" "crypto/sha512" - "fmt" "github.com/pkg/errors" @@ -55,7 +54,6 @@ func parseDigest(resp []byte) (key, sig []byte, err error) { if !bytes.Equal(separator, resp[:len(separator)]) { return nil, nil, errors.New("Cannot find 0xCAFE") } - fmt.Println("successs") sig = resp[len(separator):] return key, sig, nil From ae078ee915c8387bae25fd9104754a7b2342e68b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 23 Oct 2017 16:35:26 +0200 Subject: [PATCH 146/287] Generate/recover can return error, not panic on ledger --- keys/cryptostore/encoder_test.go | 12 ++++-- keys/cryptostore/generator.go | 63 ++++++++++++++++++++------------ keys/cryptostore/holder.go | 13 ++++--- keys/cryptostore/holder_test.go | 6 ++- keys/cryptostore/storage_test.go | 5 ++- 5 files changed, 62 insertions(+), 37 deletions(-) diff --git a/keys/cryptostore/encoder_test.go b/keys/cryptostore/encoder_test.go index ce1118d20..9cde95a12 100644 --- a/keys/cryptostore/encoder_test.go +++ b/keys/cryptostore/encoder_test.go @@ -15,8 +15,10 @@ func TestNoopEncoder(t *testing.T) { assert, require := assert.New(t), require.New(t) noop := cryptostore.Noop - key := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) - key2 := cryptostore.GenSecp256k1.Generate(cmn.RandBytes(16)) + key, err := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) + require.NoError(err) + key2, err := cryptostore.GenSecp256k1.Generate(cmn.RandBytes(16)) + require.NoError(err) _, b, err := noop.Encrypt(key, "encode") require.Nil(err) @@ -43,7 +45,8 @@ func TestSecretBox(t *testing.T) { assert, require := assert.New(t), require.New(t) enc := cryptostore.SecretBox - key := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) + key, err := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) + require.NoError(err) pass := "some-special-secret" s, b, err := enc.Encrypt(key, pass) @@ -65,7 +68,8 @@ func TestSecretBoxNoPass(t *testing.T) { assert, require := assert.New(t), require.New(t) enc := cryptostore.SecretBox - key := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) + key, err := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) + require.NoError(err) cases := []struct { encode string diff --git a/keys/cryptostore/generator.go b/keys/cryptostore/generator.go index c1984fc82..5a05b7e6e 100644 --- a/keys/cryptostore/generator.go +++ b/keys/cryptostore/generator.go @@ -18,57 +18,72 @@ var ( // Generator determines the type of private key the keystore creates type Generator interface { - Generate(secret []byte) crypto.PrivKey + Generate(secret []byte) (crypto.PrivKey, error) } // GenFunc is a helper to transform a function into a Generator -type GenFunc func(secret []byte) crypto.PrivKey +type GenFunc func(secret []byte) (crypto.PrivKey, error) -func (f GenFunc) Generate(secret []byte) crypto.PrivKey { +func (f GenFunc) Generate(secret []byte) (crypto.PrivKey, error) { return f(secret) } -func genEd25519(secret []byte) crypto.PrivKey { - return crypto.GenPrivKeyEd25519FromSecret(secret).Wrap() +func genEd25519(secret []byte) (crypto.PrivKey, error) { + key := crypto.GenPrivKeyEd25519FromSecret(secret).Wrap() + return key, nil } -func genSecp256(secret []byte) crypto.PrivKey { - return crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap() +func genSecp256(secret []byte) (crypto.PrivKey, error) { + key := crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap() + return key, nil } // secret is completely ignored for the ledger... // just for interface compatibility -func genLedger(secret []byte) crypto.PrivKey { - key, err := nano.NewPrivKeyLedger() - if err != nil { - // TODO: cleaner error handling - panic(err) - } - return key +func genLedger(secret []byte) (crypto.PrivKey, error) { + return nano.NewPrivKeyLedger() +} + +type genInvalidByte struct { + typ byte +} + +func (g genInvalidByte) Generate(secret []byte) (crypto.PrivKey, error) { + err := errors.Errorf("Cannot generate keys for algorithm: %X", g.typ) + return crypto.PrivKey{}, err +} + +type genInvalidAlgo struct { + algo string +} + +func (g genInvalidAlgo) Generate(secret []byte) (crypto.PrivKey, error) { + err := errors.Errorf("Cannot generate keys for algorithm: %s", g.algo) + return crypto.PrivKey{}, err } -func getGenerator(algo string) (Generator, error) { +func getGenerator(algo string) Generator { switch algo { case crypto.NameEd25519: - return GenEd25519, nil + return GenEd25519 case crypto.NameSecp256k1: - return GenSecp256k1, nil + return GenSecp256k1 case nano.NameLedger: - return GenLedger, nil + return GenLedger default: - return nil, errors.Errorf("Cannot generate keys for algorithm: %s", algo) + return genInvalidAlgo{algo} } } -func getGeneratorByType(typ byte) (Generator, error) { +func getGeneratorByType(typ byte) Generator { switch typ { case crypto.TypeEd25519: - return GenEd25519, nil + return GenEd25519 case crypto.TypeSecp256k1: - return GenSecp256k1, nil + return GenSecp256k1 case nano.TypeLedger: - return GenLedger, nil + return GenLedger default: - return nil, errors.Errorf("Cannot generate keys for algorithm: %X", typ) + return genInvalidByte{typ} } } diff --git a/keys/cryptostore/holder.go b/keys/cryptostore/holder.go index cb8a2e149..923190c1b 100644 --- a/keys/cryptostore/holder.go +++ b/keys/cryptostore/holder.go @@ -33,14 +33,15 @@ var _ keys.Manager = Manager{} // // algo must be a supported go-crypto algorithm: ed25519, secp256k1 func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error) { - gen, err := getGenerator(algo) + // 128-bits are the all the randomness we can make use of + secret := crypto.CRandBytes(16) + gen := getGenerator(algo) + + key, err := gen.Generate(secret) if err != nil { return keys.Info{}, "", err } - // 128-bits are the all the randomness we can make use of - secret := crypto.CRandBytes(16) - key := gen.Generate(secret) err = s.es.Put(name, passphrase, key) if err != nil { return keys.Info{}, "", err @@ -74,11 +75,11 @@ func (s Manager) Recover(name, passphrase, seedphrase string) (keys.Info, error) l := len(secret) secret, typ := secret[:l-1], secret[l-1] - gen, err := getGeneratorByType(typ) + gen := getGeneratorByType(typ) + key, err := gen.Generate(secret) if err != nil { return keys.Info{}, err } - key := gen.Generate(secret) // d00d, it worked! create the bugger.... err = s.es.Put(name, passphrase, key) diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index f0dc77c4d..80ebcc528 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -224,13 +224,15 @@ func TestImportUnencrypted(t *testing.T) { keys.MustLoadCodec("english"), ) - key := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) + key, err := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) + require.NoError(err) + addr := key.PubKey().Address() name := "john" pass := "top-secret" // import raw bytes - err := cstore.Import(name, pass, "", nil, key.Bytes()) + err = cstore.Import(name, pass, "", nil, key.Bytes()) require.Nil(err, "%+v", err) // make sure the address matches diff --git a/keys/cryptostore/storage_test.go b/keys/cryptostore/storage_test.go index 468435143..23931c294 100644 --- a/keys/cryptostore/storage_test.go +++ b/keys/cryptostore/storage_test.go @@ -14,7 +14,10 @@ import ( func TestSortKeys(t *testing.T) { assert := assert.New(t) - gen := func() crypto.PrivKey { return GenEd25519.Generate(cmn.RandBytes(16)) } + gen := func() crypto.PrivKey { + key, _ := GenEd25519.Generate(cmn.RandBytes(16)) + return key + } assert.NotEqual(gen(), gen()) // alphabetical order is n3, n1, n2 From 1b8d52bb8258c1490e3bc57a30b8b18a2cb25d40 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 23 Oct 2017 16:38:57 +0200 Subject: [PATCH 147/287] Rename NameLedger to NameLedgerEd25519 --- keys/cryptostore/generator.go | 4 ++-- keys/cryptostore/holder_test.go | 2 +- nano/keys.go | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/keys/cryptostore/generator.go b/keys/cryptostore/generator.go index 5a05b7e6e..6b2d47a1a 100644 --- a/keys/cryptostore/generator.go +++ b/keys/cryptostore/generator.go @@ -68,7 +68,7 @@ func getGenerator(algo string) Generator { return GenEd25519 case crypto.NameSecp256k1: return GenSecp256k1 - case nano.NameLedger: + case nano.NameLedgerEd25519: return GenLedger default: return genInvalidAlgo{algo} @@ -81,7 +81,7 @@ func getGeneratorByType(typ byte) Generator { return GenEd25519 case crypto.TypeSecp256k1: return GenSecp256k1 - case nano.TypeLedger: + case nano.TypeLedgerEd25519: return GenLedger default: return genInvalidByte{typ} diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index 80ebcc528..831fa251e 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -173,7 +173,7 @@ func TestSignWithLedger(t *testing.T) { p := "hard2hack" // create a nano user - c, _, err := cstore.Create(n, p, nano.NameLedger) + c, _, err := cstore.Create(n, p, nano.NameLedgerEd25519) require.Nil(err, "%+v", err) assert.Equal(c.Name, n) _, ok := c.PubKey.Unwrap().(nano.PubKeyLedger) diff --git a/nano/keys.go b/nano/keys.go index c0eccc492..bd56af6db 100644 --- a/nano/keys.go +++ b/nano/keys.go @@ -13,8 +13,8 @@ import ( ) const ( - NameLedger = "ledger" - TypeLedger = 0x10 + NameLedgerEd25519 = "ledger" + TypeLedgerEd25519 = 0x10 ) var device *ledger.Ledger @@ -229,11 +229,11 @@ func (pk PubKeyLedger) Equals(other crypto.PubKey) bool { func init() { crypto.PrivKeyMapper. - RegisterImplementation(&PrivKeyLedger{}, NameLedger, TypeLedger). + RegisterImplementation(&PrivKeyLedger{}, NameLedgerEd25519, TypeLedgerEd25519). RegisterImplementation(MockPrivKeyLedger{}, "mock-ledger", 0x11) crypto.PubKeyMapper. - RegisterImplementation(PubKeyLedger{}, NameLedger, TypeLedger) + RegisterImplementation(PubKeyLedger{}, NameLedgerEd25519, TypeLedgerEd25519) } // Wrap fulfils interface for PrivKey struct From bce88a20df7d06408453b99127e8b09e1b385933 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 23 Oct 2017 17:11:12 +0200 Subject: [PATCH 148/287] Enable privkey validity checking on load --- priv_key.go | 16 +++++++++++- priv_key_test.go | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 priv_key_test.go diff --git a/priv_key.go b/priv_key.go index 0c6bd2ae7..e6e7ac036 100644 --- a/priv_key.go +++ b/priv_key.go @@ -13,13 +13,27 @@ import ( func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { err = wire.ReadBinaryBytes(privKeyBytes, &privKey) + if err == nil { + // add support for a ValidateKey method on PrivKeys + // to make sure they load correctly + val, ok := privKey.Unwrap().(validatable) + if ok { + err = val.ValidateKey() + } + } return } +// validatable is an optional interface for keys that want to +// check integrity +type validatable interface { + ValidateKey() error +} + //---------------------------------------- // DO NOT USE THIS INTERFACE. -// You probably want to use PubKey +// You probably want to use PrivKey // +gen wrapper:"PrivKey,Impl[PrivKeyEd25519,PrivKeySecp256k1],ed25519,secp256k1" type PrivKeyInner interface { AssertIsPrivKeyInner() diff --git a/priv_key_test.go b/priv_key_test.go new file mode 100644 index 000000000..154df5593 --- /dev/null +++ b/priv_key_test.go @@ -0,0 +1,65 @@ +package crypto + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + wire "github.com/tendermint/go-wire" +) + +type BadKey struct { + PrivKeyEd25519 +} + +// Wrap fulfils interface for PrivKey struct +func (pk BadKey) Wrap() PrivKey { + return PrivKey{pk} +} + +func (pk BadKey) Bytes() []byte { + return wire.BinaryBytes(pk.Wrap()) +} + +func (pk BadKey) ValidateKey() error { + return fmt.Errorf("fuggly key") +} + +func init() { + PrivKeyMapper. + RegisterImplementation(BadKey{}, "bad", 0x66) +} + +func TestReadPrivKey(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + // garbage in, garbage out + garbage := []byte("hjgewugfbiewgofwgewr") + _, err := PrivKeyFromBytes(garbage) + require.Error(err) + + edKey := GenPrivKeyEd25519() + badKey := BadKey{edKey} + + cases := []struct { + key PrivKey + valid bool + }{ + {edKey.Wrap(), true}, + {badKey.Wrap(), false}, + } + + for i, tc := range cases { + data := tc.key.Bytes() + key, err := PrivKeyFromBytes(data) + if tc.valid { + assert.NoError(err, "%d", i) + assert.Equal(tc.key, key, "%d", i) + } else { + assert.Error(err, "%d: %#v", i, key) + } + } + +} From 2490952515786d308cd5097d4c789afc940f2a3b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 23 Oct 2017 17:19:35 +0200 Subject: [PATCH 149/287] nano validates key on load --- nano/keys.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/nano/keys.go b/nano/keys.go index bd56af6db..4bb0e97c5 100644 --- a/nano/keys.go +++ b/nano/keys.go @@ -59,6 +59,8 @@ type PrivKeyLedger struct { CachedPubKey crypto.PubKey } +// NewPrivKeyLedger will generate a new key and store the +// public key for later use. func NewPrivKeyLedger() (crypto.PrivKey, error) { var pk PrivKeyLedger // getPubKey will cache the pubkey for later use, @@ -68,6 +70,22 @@ func NewPrivKeyLedger() (crypto.PrivKey, error) { return pk.Wrap(), err } +// ValidateKey allows us to verify the sanity of a key +// after loading it from disk +func (pk *PrivKeyLedger) ValidateKey() error { + // getPubKey will return an error if the ledger is not + // properly set up... + pub, err := pk.getPubKey() + if err != nil { + return err + } + // verify this matches cached address + if !pub.Equals(pk.CachedPubKey) { + return errors.New("ledger doesn't match cached key") + } + return nil +} + // AssertIsPrivKeyInner fulfils PrivKey Interface func (pk *PrivKeyLedger) AssertIsPrivKeyInner() {} From 9afceb7ee844443cb41c2378f88871ec3c0dddce Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 23 Oct 2017 18:14:28 +0200 Subject: [PATCH 150/287] ledger pubkey serializes properly, better load checks --- nano/keys.go | 31 ++++++++++++++++++++++--------- nano/keys_test.go | 6 ++++++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/nano/keys.go b/nano/keys.go index 4bb0e97c5..a3337f1e5 100644 --- a/nano/keys.go +++ b/nano/keys.go @@ -12,6 +12,7 @@ import ( wire "github.com/tendermint/go-wire" ) +//nolint const ( NameLedgerEd25519 = "ledger" TypeLedgerEd25519 = 0x10 @@ -132,16 +133,23 @@ func (pk *PrivKeyLedger) PubKey() crypto.PubKey { func (pk *PrivKeyLedger) getPubKey() (key crypto.PubKey, err error) { // if we have no pubkey, set it if pk.CachedPubKey.Empty() { - dev, err := getLedger() - if err != nil { - return key, errors.WithMessage(err, "Can't connect to ledger") - } - pk.CachedPubKey, _, err = signLedger(dev, []byte{0}) - if err != nil { - return key, errors.WithMessage(err, "Can't sign with app") - } + pk.CachedPubKey, err = pk.forceGetPubKey() } - return pk.CachedPubKey, nil + return pk.CachedPubKey, err +} + +// forceGetPubKey is like getPubKey but ignores any cached key +// and ensures we get it from the ledger itself. +func (pk *PrivKeyLedger) forceGetPubKey() (key crypto.PubKey, err error) { + dev, err := getLedger() + if err != nil { + return key, errors.New("Can't connect to ledger device") + } + key, _, err = signLedger(dev, []byte{0}) + if err != nil { + return key, errors.New("Please open cosmos app on the ledger") + } + return key, err } // Equals fulfils PrivKey Interface @@ -229,6 +237,11 @@ func PubKeyLedgerFromBytes(key [32]byte) crypto.PubKey { return PubKeyLedger{crypto.PubKeyEd25519(key)}.Wrap() } +// Bytes fulfils pk Interface - no data, just type info +func (pk PubKeyLedger) Bytes() []byte { + return wire.BinaryBytes(pk.Wrap()) +} + // VerifyBytes uses the normal Ed25519 algorithm but a sha512 hash beforehand func (pk PubKeyLedger) VerifyBytes(msg []byte, sig crypto.Signature) bool { hmsg := hashMsg(msg) diff --git a/nano/keys_test.go b/nano/keys_test.go index b42b091f0..40cd1b486 100644 --- a/nano/keys_test.go +++ b/nano/keys_test.go @@ -104,4 +104,10 @@ func TestRealLedger(t *testing.T) { valid = pub.VerifyBytes(msg, sig) assert.True(valid) + // make sure pubkeys serialize properly as well + bs = pub.Bytes() + bpub, err := crypto.PubKeyFromBytes(bs) + require.NoError(err) + assert.Equal(pub, bpub) + } From 61d1bdb5eda2a335da51ed51fd286b404ea85087 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 23 Oct 2017 18:32:29 +0200 Subject: [PATCH 151/287] Test error handling, load without ledger --- nano/keys.go | 2 +- nano/keys_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/nano/keys.go b/nano/keys.go index a3337f1e5..8d4d3d06d 100644 --- a/nano/keys.go +++ b/nano/keys.go @@ -76,7 +76,7 @@ func NewPrivKeyLedger() (crypto.PrivKey, error) { func (pk *PrivKeyLedger) ValidateKey() error { // getPubKey will return an error if the ledger is not // properly set up... - pub, err := pk.getPubKey() + pub, err := pk.forceGetPubKey() if err != nil { return err } diff --git a/nano/keys_test.go b/nano/keys_test.go index 40cd1b486..3815d3944 100644 --- a/nano/keys_test.go +++ b/nano/keys_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + crypto "github.com/tendermint/go-crypto" ) @@ -109,5 +110,33 @@ func TestRealLedger(t *testing.T) { bpub, err := crypto.PubKeyFromBytes(bs) require.NoError(err) assert.Equal(pub, bpub) +} + +// TestRealLedgerErrorHandling calls. These tests assume +// the ledger is not plugged in.... +func TestRealLedgerErrorHandling(t *testing.T) { + require := require.New(t) + + if os.Getenv("WITH_LEDGER") != "" { + t.Skip("Skipping on WITH_LEDGER as it tests unplugged cases") + } + + // first, try to generate a key, must return an error + // (no panic) + _, err := NewPrivKeyLedger() + require.Error(err) + + led := PrivKeyLedger{} // empty + // or with some pub key + ed := crypto.GenPrivKeyEd25519() + led2 := PrivKeyLedger{CachedPubKey: ed.PubKey()} + + // loading these should return errors + bs := led.Bytes() + _, err = crypto.PrivKeyFromBytes(bs) + require.Error(err) + bs = led2.Bytes() + _, err = crypto.PrivKeyFromBytes(bs) + require.Error(err) } From 9601e48ab40a5a871992651b6e881b82fb88a26c Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 23 Oct 2017 18:39:34 +0200 Subject: [PATCH 152/287] Improve error message --- keys/cryptostore/encoder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keys/cryptostore/encoder.go b/keys/cryptostore/encoder.go index 251543b60..0b957d826 100644 --- a/keys/cryptostore/encoder.go +++ b/keys/cryptostore/encoder.go @@ -55,7 +55,7 @@ func (e secretbox) Decrypt(saltBytes []byte, encBytes []byte, passphrase string) } privKey, err = crypto.PrivKeyFromBytes(privKeyBytes) if err != nil { - return crypto.PrivKey{}, errors.Wrap(err, "Couldn't get privKey from bytes") + return crypto.PrivKey{}, errors.Wrap(err, "Private Key") } return privKey, nil } From 4a2c63f5e17f2278f31024112484454a75a7bf86 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 24 Oct 2017 11:23:09 +0200 Subject: [PATCH 153/287] Update ledger names to specify ed25519 --- keys/cryptostore/generator.go | 12 ++--- keys/cryptostore/holder_test.go | 2 +- nano/keys.go | 86 ++++++++++++++++----------------- nano/keys_test.go | 8 +-- 4 files changed, 54 insertions(+), 54 deletions(-) diff --git a/keys/cryptostore/generator.go b/keys/cryptostore/generator.go index 6b2d47a1a..65cc8e58b 100644 --- a/keys/cryptostore/generator.go +++ b/keys/cryptostore/generator.go @@ -12,8 +12,8 @@ var ( GenEd25519 Generator = GenFunc(genEd25519) // GenSecp256k1 produces Secp256k1 private keys GenSecp256k1 Generator = GenFunc(genSecp256) - // GenLedger used Ed25519 keys stored on nano ledger s with cosmos app - GenLedger Generator = GenFunc(genLedger) + // GenLedgerEd25519 used Ed25519 keys stored on nano ledger s with cosmos app + GenLedgerEd25519 Generator = GenFunc(genLedgerEd25519) ) // Generator determines the type of private key the keystore creates @@ -40,8 +40,8 @@ func genSecp256(secret []byte) (crypto.PrivKey, error) { // secret is completely ignored for the ledger... // just for interface compatibility -func genLedger(secret []byte) (crypto.PrivKey, error) { - return nano.NewPrivKeyLedger() +func genLedgerEd25519(secret []byte) (crypto.PrivKey, error) { + return nano.NewPrivKeyLedgerEd25519Ed25519() } type genInvalidByte struct { @@ -69,7 +69,7 @@ func getGenerator(algo string) Generator { case crypto.NameSecp256k1: return GenSecp256k1 case nano.NameLedgerEd25519: - return GenLedger + return GenLedgerEd25519 default: return genInvalidAlgo{algo} } @@ -82,7 +82,7 @@ func getGeneratorByType(typ byte) Generator { case crypto.TypeSecp256k1: return GenSecp256k1 case nano.TypeLedgerEd25519: - return GenLedger + return GenLedgerEd25519 default: return genInvalidByte{typ} } diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index 831fa251e..899f51f02 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -176,7 +176,7 @@ func TestSignWithLedger(t *testing.T) { c, _, err := cstore.Create(n, p, nano.NameLedgerEd25519) require.Nil(err, "%+v", err) assert.Equal(c.Name, n) - _, ok := c.PubKey.Unwrap().(nano.PubKeyLedger) + _, ok := c.PubKey.Unwrap().(nano.PubKeyLedgerEd25519) require.True(ok) // make sure we can get it back diff --git a/nano/keys.go b/nano/keys.go index 8d4d3d06d..dc1eec950 100644 --- a/nano/keys.go +++ b/nano/keys.go @@ -14,7 +14,7 @@ import ( //nolint const ( - NameLedgerEd25519 = "ledger" + NameLedgerEd25519 = "ledger-ed25519" TypeLedgerEd25519 = 0x10 ) @@ -48,22 +48,22 @@ func signLedger(device *ledger.Ledger, msg []byte) (pk crypto.PubKey, sig crypto var b [32]byte copy(b[:], key) - return PubKeyLedgerFromBytes(b), crypto.SignatureEd25519FromBytes(bsig), nil + return PubKeyLedgerEd25519FromBytes(b), crypto.SignatureEd25519FromBytes(bsig), nil } -// PrivKeyLedger implements PrivKey, calling the ledger nano +// PrivKeyLedgerEd25519 implements PrivKey, calling the ledger nano // we cache the PubKey from the first call to use it later -type PrivKeyLedger struct { +type PrivKeyLedgerEd25519 struct { // PubKey should be private, but we want to encode it via go-wire // so we can view the address later, even without having the ledger // attached CachedPubKey crypto.PubKey } -// NewPrivKeyLedger will generate a new key and store the +// NewPrivKeyLedgerEd25519Ed25519 will generate a new key and store the // public key for later use. -func NewPrivKeyLedger() (crypto.PrivKey, error) { - var pk PrivKeyLedger +func NewPrivKeyLedgerEd25519Ed25519() (crypto.PrivKey, error) { + var pk PrivKeyLedgerEd25519 // getPubKey will cache the pubkey for later use, // this allows us to return an error early if the ledger // is not plugged in @@ -73,7 +73,7 @@ func NewPrivKeyLedger() (crypto.PrivKey, error) { // ValidateKey allows us to verify the sanity of a key // after loading it from disk -func (pk *PrivKeyLedger) ValidateKey() error { +func (pk *PrivKeyLedgerEd25519) ValidateKey() error { // getPubKey will return an error if the ledger is not // properly set up... pub, err := pk.forceGetPubKey() @@ -88,15 +88,15 @@ func (pk *PrivKeyLedger) ValidateKey() error { } // AssertIsPrivKeyInner fulfils PrivKey Interface -func (pk *PrivKeyLedger) AssertIsPrivKeyInner() {} +func (pk *PrivKeyLedgerEd25519) AssertIsPrivKeyInner() {} // Bytes fulfils pk Interface - no data, just type info -func (pk *PrivKeyLedger) Bytes() []byte { +func (pk *PrivKeyLedgerEd25519) Bytes() []byte { return wire.BinaryBytes(pk.Wrap()) } // Sign calls the ledger and stores the pk for future use -func (pk *PrivKeyLedger) Sign(msg []byte) crypto.Signature { +func (pk *PrivKeyLedgerEd25519) Sign(msg []byte) crypto.Signature { // oh, I wish there was better error handling dev, err := getLedger() if err != nil { @@ -119,7 +119,7 @@ func (pk *PrivKeyLedger) Sign(msg []byte) crypto.Signature { // PubKey returns the stored PubKey // TODO: query the ledger if not there, once it is not volatile -func (pk *PrivKeyLedger) PubKey() crypto.PubKey { +func (pk *PrivKeyLedgerEd25519) PubKey() crypto.PubKey { key, err := pk.getPubKey() if err != nil { panic(err) @@ -130,7 +130,7 @@ func (pk *PrivKeyLedger) PubKey() crypto.PubKey { // getPubKey reads the pubkey from cache or from the ledger itself // since this involves IO, it may return an error, which is not exposed // in the PubKey interface, so this function allows better error handling -func (pk *PrivKeyLedger) getPubKey() (key crypto.PubKey, err error) { +func (pk *PrivKeyLedgerEd25519) getPubKey() (key crypto.PubKey, err error) { // if we have no pubkey, set it if pk.CachedPubKey.Empty() { pk.CachedPubKey, err = pk.forceGetPubKey() @@ -140,7 +140,7 @@ func (pk *PrivKeyLedger) getPubKey() (key crypto.PubKey, err error) { // forceGetPubKey is like getPubKey but ignores any cached key // and ensures we get it from the ledger itself. -func (pk *PrivKeyLedger) forceGetPubKey() (key crypto.PubKey, err error) { +func (pk *PrivKeyLedgerEd25519) forceGetPubKey() (key crypto.PubKey, err error) { dev, err := getLedger() if err != nil { return key, errors.New("Can't connect to ledger device") @@ -154,23 +154,23 @@ func (pk *PrivKeyLedger) forceGetPubKey() (key crypto.PubKey, err error) { // Equals fulfils PrivKey Interface // TODO: needs to be fixed -func (pk *PrivKeyLedger) Equals(other crypto.PrivKey) bool { - if _, ok := other.Unwrap().(*PrivKeyLedger); ok { +func (pk *PrivKeyLedgerEd25519) Equals(other crypto.PrivKey) bool { + if _, ok := other.Unwrap().(*PrivKeyLedgerEd25519); ok { return true } return false } -// MockPrivKeyLedger behaves as the ledger, but stores a pre-packaged call-response +// MockPrivKeyLedgerEd25519 behaves as the ledger, but stores a pre-packaged call-response // for use in test cases -type MockPrivKeyLedger struct { +type MockPrivKeyLedgerEd25519 struct { Msg []byte Pub [KeyLength]byte Sig [SigLength]byte } // NewMockKey returns -func NewMockKey(msg, pubkey, sig string) (pk MockPrivKeyLedger) { +func NewMockKey(msg, pubkey, sig string) (pk MockPrivKeyLedgerEd25519) { var err error pk.Msg, err = hex.DecodeString(msg) if err != nil { @@ -191,32 +191,32 @@ func NewMockKey(msg, pubkey, sig string) (pk MockPrivKeyLedger) { return pk } -var _ crypto.PrivKeyInner = MockPrivKeyLedger{} +var _ crypto.PrivKeyInner = MockPrivKeyLedgerEd25519{} // AssertIsPrivKeyInner fulfils PrivKey Interface -func (pk MockPrivKeyLedger) AssertIsPrivKeyInner() {} +func (pk MockPrivKeyLedgerEd25519) AssertIsPrivKeyInner() {} // Bytes fulfils PrivKey Interface - not supported -func (pk MockPrivKeyLedger) Bytes() []byte { +func (pk MockPrivKeyLedgerEd25519) Bytes() []byte { return nil } // Sign returns a real SignatureLedger, if the msg matches what we expect -func (pk MockPrivKeyLedger) Sign(msg []byte) crypto.Signature { +func (pk MockPrivKeyLedgerEd25519) Sign(msg []byte) crypto.Signature { if !bytes.Equal(pk.Msg, msg) { panic("Mock key is for different msg") } return crypto.SignatureEd25519(pk.Sig).Wrap() } -// PubKey returns a real PubKeyLedger, that will verify this signature -func (pk MockPrivKeyLedger) PubKey() crypto.PubKey { - return PubKeyLedgerFromBytes(pk.Pub) +// PubKey returns a real PubKeyLedgerEd25519, that will verify this signature +func (pk MockPrivKeyLedgerEd25519) PubKey() crypto.PubKey { + return PubKeyLedgerEd25519FromBytes(pk.Pub) } // Equals compares that two Mocks have the same data -func (pk MockPrivKeyLedger) Equals(other crypto.PrivKey) bool { - if mock, ok := other.Unwrap().(MockPrivKeyLedger); ok { +func (pk MockPrivKeyLedgerEd25519) Equals(other crypto.PrivKey) bool { + if mock, ok := other.Unwrap().(MockPrivKeyLedgerEd25519); ok { return bytes.Equal(mock.Pub[:], pk.Pub[:]) && bytes.Equal(mock.Sig[:], pk.Sig[:]) && bytes.Equal(mock.Msg, pk.Msg) @@ -227,30 +227,30 @@ func (pk MockPrivKeyLedger) Equals(other crypto.PrivKey) bool { //////////////////////////////////////////// // pubkey -// PubKeyLedger works like a normal Ed25519 except a hash before the verify bytes -type PubKeyLedger struct { +// PubKeyLedgerEd25519 works like a normal Ed25519 except a hash before the verify bytes +type PubKeyLedgerEd25519 struct { crypto.PubKeyEd25519 } -// PubKeyLedgerFromBytes creates a PubKey from the raw bytes -func PubKeyLedgerFromBytes(key [32]byte) crypto.PubKey { - return PubKeyLedger{crypto.PubKeyEd25519(key)}.Wrap() +// PubKeyLedgerEd25519FromBytes creates a PubKey from the raw bytes +func PubKeyLedgerEd25519FromBytes(key [32]byte) crypto.PubKey { + return PubKeyLedgerEd25519{crypto.PubKeyEd25519(key)}.Wrap() } // Bytes fulfils pk Interface - no data, just type info -func (pk PubKeyLedger) Bytes() []byte { +func (pk PubKeyLedgerEd25519) Bytes() []byte { return wire.BinaryBytes(pk.Wrap()) } // VerifyBytes uses the normal Ed25519 algorithm but a sha512 hash beforehand -func (pk PubKeyLedger) VerifyBytes(msg []byte, sig crypto.Signature) bool { +func (pk PubKeyLedgerEd25519) VerifyBytes(msg []byte, sig crypto.Signature) bool { hmsg := hashMsg(msg) return pk.PubKeyEd25519.VerifyBytes(hmsg, sig) } // Equals implements PubKey interface -func (pk PubKeyLedger) Equals(other crypto.PubKey) bool { - if ledger, ok := other.Unwrap().(PubKeyLedger); ok { +func (pk PubKeyLedgerEd25519) Equals(other crypto.PubKey) bool { + if ledger, ok := other.Unwrap().(PubKeyLedgerEd25519); ok { return bytes.Equal(pk.PubKeyEd25519[:], ledger.PubKeyEd25519[:]) } return false @@ -260,24 +260,24 @@ func (pk PubKeyLedger) Equals(other crypto.PubKey) bool { func init() { crypto.PrivKeyMapper. - RegisterImplementation(&PrivKeyLedger{}, NameLedgerEd25519, TypeLedgerEd25519). - RegisterImplementation(MockPrivKeyLedger{}, "mock-ledger", 0x11) + RegisterImplementation(&PrivKeyLedgerEd25519{}, NameLedgerEd25519, TypeLedgerEd25519). + RegisterImplementation(MockPrivKeyLedgerEd25519{}, "mock-ledger", 0x11) crypto.PubKeyMapper. - RegisterImplementation(PubKeyLedger{}, NameLedgerEd25519, TypeLedgerEd25519) + RegisterImplementation(PubKeyLedgerEd25519{}, NameLedgerEd25519, TypeLedgerEd25519) } // Wrap fulfils interface for PrivKey struct -func (pk *PrivKeyLedger) Wrap() crypto.PrivKey { +func (pk *PrivKeyLedgerEd25519) Wrap() crypto.PrivKey { return crypto.PrivKey{pk} } // Wrap fulfils interface for PrivKey struct -func (pk MockPrivKeyLedger) Wrap() crypto.PrivKey { +func (pk MockPrivKeyLedgerEd25519) Wrap() crypto.PrivKey { return crypto.PrivKey{pk} } // Wrap fulfils interface for PubKey struct -func (pk PubKeyLedger) Wrap() crypto.PubKey { +func (pk PubKeyLedgerEd25519) Wrap() crypto.PubKey { return crypto.PubKey{pk} } diff --git a/nano/keys_test.go b/nano/keys_test.go index 3815d3944..15aa0d545 100644 --- a/nano/keys_test.go +++ b/nano/keys_test.go @@ -83,7 +83,7 @@ func TestRealLedger(t *testing.T) { } msg := []byte("kuhehfeohg") - priv, err := NewPrivKeyLedger() + priv, err := NewPrivKeyLedgerEd25519Ed25519() require.Nil(err, "%+v", err) pub := priv.PubKey() sig := priv.Sign(msg) @@ -123,13 +123,13 @@ func TestRealLedgerErrorHandling(t *testing.T) { // first, try to generate a key, must return an error // (no panic) - _, err := NewPrivKeyLedger() + _, err := NewPrivKeyLedgerEd25519Ed25519() require.Error(err) - led := PrivKeyLedger{} // empty + led := PrivKeyLedgerEd25519{} // empty // or with some pub key ed := crypto.GenPrivKeyEd25519() - led2 := PrivKeyLedger{CachedPubKey: ed.PubKey()} + led2 := PrivKeyLedgerEd25519{CachedPubKey: ed.PubKey()} // loading these should return errors bs := led.Bytes() From 2d0454408878ef3fa011ccc159e7bff16d13e543 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 24 Oct 2017 11:31:38 +0200 Subject: [PATCH 154/287] Addressed Buckys PR review comments --- nano/keys.go | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/nano/keys.go b/nano/keys.go index dc1eec950..eb531ef41 100644 --- a/nano/keys.go +++ b/nano/keys.go @@ -16,6 +16,10 @@ import ( const ( NameLedgerEd25519 = "ledger-ed25519" TypeLedgerEd25519 = 0x10 + + // Timeout is the number of seconds to wait for a response from the ledger + // if eg. waiting for user confirmation on button push + Timeout = 20 ) var device *ledger.Ledger @@ -34,7 +38,7 @@ func signLedger(device *ledger.Ledger, msg []byte) (pk crypto.PubKey, sig crypto packets := generateSignRequests(msg) for _, pack := range packets { - resp, err = device.Exchange(pack, 100) + resp, err = device.Exchange(pack, Timeout) if err != nil { return pk, sig, err } @@ -90,12 +94,19 @@ func (pk *PrivKeyLedgerEd25519) ValidateKey() error { // AssertIsPrivKeyInner fulfils PrivKey Interface func (pk *PrivKeyLedgerEd25519) AssertIsPrivKeyInner() {} -// Bytes fulfils pk Interface - no data, just type info +// Bytes fulfils pk Interface - stores the cached pubkey so we can verify +// the same key when we reconnect to a ledger func (pk *PrivKeyLedgerEd25519) Bytes() []byte { return wire.BinaryBytes(pk.Wrap()) } // Sign calls the ledger and stores the pk for future use +// +// XXX/TODO: panics if there is an error communicating with the ledger. +// +// Communication is checked on NewPrivKeyLedger and PrivKeyFromBytes, +// returning an error, so this should only trigger if the privkey is held +// in memory for a while before use. func (pk *PrivKeyLedgerEd25519) Sign(msg []byte) crypto.Signature { // oh, I wish there was better error handling dev, err := getLedger() @@ -152,11 +163,11 @@ func (pk *PrivKeyLedgerEd25519) forceGetPubKey() (key crypto.PubKey, err error) return key, err } -// Equals fulfils PrivKey Interface -// TODO: needs to be fixed +// Equals fulfils PrivKey Interface - makes sure both keys refer to the +// same func (pk *PrivKeyLedgerEd25519) Equals(other crypto.PrivKey) bool { - if _, ok := other.Unwrap().(*PrivKeyLedgerEd25519); ok { - return true + if ledger, ok := other.Unwrap().(*PrivKeyLedgerEd25519); ok { + return pk.CachedPubKey.Equals(ledger.CachedPubKey) } return false } @@ -251,7 +262,7 @@ func (pk PubKeyLedgerEd25519) VerifyBytes(msg []byte, sig crypto.Signature) bool // Equals implements PubKey interface func (pk PubKeyLedgerEd25519) Equals(other crypto.PubKey) bool { if ledger, ok := other.Unwrap().(PubKeyLedgerEd25519); ok { - return bytes.Equal(pk.PubKeyEd25519[:], ledger.PubKeyEd25519[:]) + return pk.PubKeyEd25519.Equals(ledger.PubKeyEd25519.Wrap()) } return false } From 6f6bbf718e4769fb321af88533769b2c1a154b72 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 24 Oct 2017 11:56:37 +0200 Subject: [PATCH 155/287] Fix metalinter complaints --- keys/cryptostore/encoder.go | 4 ++-- keys/cryptostore/encoder_test.go | 8 ++++---- keys/cryptostore/holder_test.go | 2 +- nano/keys.go | 6 +++--- nano/sign.go | 20 -------------------- nano/sign_test.go | 20 ++++++++++++++++++++ 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/keys/cryptostore/encoder.go b/keys/cryptostore/encoder.go index 0b957d826..531a534ad 100644 --- a/keys/cryptostore/encoder.go +++ b/keys/cryptostore/encoder.go @@ -39,7 +39,7 @@ func (e secretbox) Encrypt(privKey crypto.PrivKey, passphrase string) (saltBytes return saltBytes, crypto.EncryptSymmetric(privKeyBytes, key), nil } -func (e secretbox) Decrypt(saltBytes []byte, encBytes []byte, passphrase string) (privKey crypto.PrivKey, err error) { +func (e secretbox) Decrypt(saltBytes []byte, encBytes []byte, passphrase string) (crypto.PrivKey, error) { privKeyBytes := encBytes // NOTE: Some keys weren't encrypted with a passphrase and hence we have the conditional if passphrase != "" { @@ -53,7 +53,7 @@ func (e secretbox) Decrypt(saltBytes []byte, encBytes []byte, passphrase string) return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") } } - privKey, err = crypto.PrivKeyFromBytes(privKeyBytes) + privKey, err := crypto.PrivKeyFromBytes(privKeyBytes) if err != nil { return crypto.PrivKey{}, errors.Wrap(err, "Private Key") } diff --git a/keys/cryptostore/encoder_test.go b/keys/cryptostore/encoder_test.go index 9cde95a12..614286a19 100644 --- a/keys/cryptostore/encoder_test.go +++ b/keys/cryptostore/encoder_test.go @@ -68,8 +68,8 @@ func TestSecretBoxNoPass(t *testing.T) { assert, require := assert.New(t), require.New(t) enc := cryptostore.SecretBox - key, err := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) - require.NoError(err) + key, rerr := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) + require.NoError(rerr) cases := []struct { encode string @@ -99,7 +99,7 @@ func TestSecretBoxNoPass(t *testing.T) { // now let's make sure raw bytes also work... b := key.Bytes() - pk, err := enc.Decrypt(nil, b, "") - require.Nil(err, "%+v", err) + pk, rerr := enc.Decrypt(nil, b, "") + require.NoError(rerr) assert.Equal(key, pk) } diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index 899f51f02..3709cc55d 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -320,7 +320,7 @@ func TestSeedPhrase(t *testing.T) { assert.Equal(info.PubKey, newInfo.PubKey) } -func ExampleStore() { +func ExampleNew() { // Select the encryption and storage for your cryptostore cstore := cryptostore.New( cryptostore.SecretBox, diff --git a/nano/keys.go b/nano/keys.go index eb531ef41..a6d3ea8e4 100644 --- a/nano/keys.go +++ b/nano/keys.go @@ -280,15 +280,15 @@ func init() { // Wrap fulfils interface for PrivKey struct func (pk *PrivKeyLedgerEd25519) Wrap() crypto.PrivKey { - return crypto.PrivKey{pk} + return crypto.PrivKey{PrivKeyInner: pk} } // Wrap fulfils interface for PrivKey struct func (pk MockPrivKeyLedgerEd25519) Wrap() crypto.PrivKey { - return crypto.PrivKey{pk} + return crypto.PrivKey{PrivKeyInner: pk} } // Wrap fulfils interface for PubKey struct func (pk PubKeyLedgerEd25519) Wrap() crypto.PubKey { - return crypto.PubKey{pk} + return crypto.PubKey{PubKeyInner: pk} } diff --git a/nano/sign.go b/nano/sign.go index 874d134e8..c40801583 100644 --- a/nano/sign.go +++ b/nano/sign.go @@ -5,8 +5,6 @@ import ( "crypto/sha512" "github.com/pkg/errors" - - crypto "github.com/tendermint/go-crypto" ) const ( @@ -59,24 +57,6 @@ func parseDigest(resp []byte) (key, sig []byte, err error) { return key, sig, nil } -func parseEdKey(data []byte) (key crypto.PubKey, err error) { - ed := crypto.PubKeyEd25519{} - if len(data) < len(ed) { - return key, errors.Errorf("Key length too short: %d", len(data)) - } - copy(ed[:], data) - return ed.Wrap(), nil -} - -func parseSig(data []byte) (key crypto.Signature, err error) { - ed := crypto.SignatureEd25519{} - if len(data) < len(ed) { - return key, errors.Errorf("Sig length too short: %d", len(data)) - } - copy(ed[:], data) - return ed.Wrap(), nil -} - func hashMsg(data []byte) []byte { res := sha512.Sum512(data) return res[:] diff --git a/nano/sign_test.go b/nano/sign_test.go index 89bd7568e..04a6d0be7 100644 --- a/nano/sign_test.go +++ b/nano/sign_test.go @@ -4,10 +4,30 @@ import ( "encoding/hex" "testing" + "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + crypto "github.com/tendermint/go-crypto" ) +func parseEdKey(data []byte) (key crypto.PubKey, err error) { + ed := crypto.PubKeyEd25519{} + if len(data) < len(ed) { + return key, errors.Errorf("Key length too short: %d", len(data)) + } + copy(ed[:], data) + return ed.Wrap(), nil +} + +func parseSig(data []byte) (key crypto.Signature, err error) { + ed := crypto.SignatureEd25519{} + if len(data) < len(ed) { + return key, errors.Errorf("Sig length too short: %d", len(data)) + } + copy(ed[:], data) + return ed.Wrap(), nil +} + func TestParseDigest(t *testing.T) { assert, require := assert.New(t), require.New(t) From 69a7b389b87f0218f367f16eb156f23867246dc0 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 24 Oct 2017 11:59:44 +0200 Subject: [PATCH 156/287] Removed keys/server as it is now in cosmos-sdk --- keys/server/README.md | 13 --- keys/server/helpers.go | 59 ------------ keys/server/keys.go | 128 ------------------------- keys/server/keys_test.go | 193 -------------------------------------- keys/server/types/keys.go | 35 ------- keys/server/valid.go | 12 --- 6 files changed, 440 deletions(-) delete mode 100644 keys/server/README.md delete mode 100644 keys/server/helpers.go delete mode 100644 keys/server/keys.go delete mode 100644 keys/server/keys_test.go delete mode 100644 keys/server/types/keys.go delete mode 100644 keys/server/valid.go diff --git a/keys/server/README.md b/keys/server/README.md deleted file mode 100644 index 032cf574e..000000000 --- a/keys/server/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Proxy Server - -This package provides all the functionality for a local http server, providing access to key management functionality (creating, listing, updating, and deleting keys). This is a nice building block for larger apps, and the HTTP handlers here can be embedded in a larger server that does nice things like signing transactions and posting them to a tendermint chain (which requires domain-knowledge of the transactions types and out of scope of this generic app). - -## Key Management - -We expose a number of methods for safely managing your keychain. If you are embedding this in a larger server, you will typically want to mount all these paths under `/keys`. - -* `POST /` - provide a name and passphrase and create a brand new key -* `GET /` - get a list of all available key names, along with their public key and address -* `GET /{name}` - get public key and address for this named key -* `PUT /{name}` - update the passphrase for the given key. requires you to correctly provide the current passphrase, as well as a new one. -* `DELETE /{name}` - permanently delete this private key. requires you to correctly provide the current passphrase diff --git a/keys/server/helpers.go b/keys/server/helpers.go deleted file mode 100644 index 3fb947316..000000000 --- a/keys/server/helpers.go +++ /dev/null @@ -1,59 +0,0 @@ -/* -package server provides http handlers to construct a server server -for key management, transaction signing, and query validation. - -Please read the README and godoc to see how to -configure the server for your application. -*/ - -package server - -import ( - "encoding/json" - "io/ioutil" - "net/http" - - "github.com/tendermint/go-crypto/keys/server/types" - data "github.com/tendermint/go-wire/data" - - "github.com/pkg/errors" -) - -func readRequest(r *http.Request, o interface{}) error { - defer r.Body.Close() - data, err := ioutil.ReadAll(r.Body) - if err != nil { - return errors.Wrap(err, "Read Request") - } - err = json.Unmarshal(data, o) - if err != nil { - return errors.Wrap(err, "Parse") - } - return validate(o) -} - -// most errors are bad input, so 406... do better.... -func writeError(w http.ResponseWriter, err error) { - // fmt.Printf("Error: %+v\n", err) - res := types.ErrorResponse{ - Code: 406, - Error: err.Error(), - } - writeCode(w, &res, 406) -} - -func writeCode(w http.ResponseWriter, o interface{}, code int) { - // two space indent to make it easier to read - data, err := data.ToJSON(o) - if err != nil { - writeError(w, err) - } else { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(code) - w.Write(data) - } -} - -func writeSuccess(w http.ResponseWriter, o interface{}) { - writeCode(w, o, 200) -} diff --git a/keys/server/keys.go b/keys/server/keys.go deleted file mode 100644 index 80852802e..000000000 --- a/keys/server/keys.go +++ /dev/null @@ -1,128 +0,0 @@ -package server - -import ( - "errors" - "net/http" - - "github.com/gorilla/mux" - keys "github.com/tendermint/go-crypto/keys" - "github.com/tendermint/go-crypto/keys/server/types" -) - -type Keys struct { - manager keys.Manager - algo string -} - -func New(manager keys.Manager, algo string) Keys { - return Keys{ - manager: manager, - algo: algo, - } -} - -func (k Keys) GenerateKey(w http.ResponseWriter, r *http.Request) { - req := types.CreateKeyRequest{ - Algo: k.algo, // default key type from cli - } - err := readRequest(r, &req) - if err != nil { - writeError(w, err) - return - } - - key, seed, err := k.manager.Create(req.Name, req.Passphrase, req.Algo) - if err != nil { - writeError(w, err) - return - } - - res := types.CreateKeyResponse{key, seed} - writeSuccess(w, &res) -} - -func (k Keys) GetKey(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - name := vars["name"] - key, err := k.manager.Get(name) - if err != nil { - writeError(w, err) - return - } - writeSuccess(w, &key) -} - -func (k Keys) ListKeys(w http.ResponseWriter, r *http.Request) { - - keys, err := k.manager.List() - if err != nil { - writeError(w, err) - return - } - writeSuccess(w, keys) -} - -func (k Keys) UpdateKey(w http.ResponseWriter, r *http.Request) { - req := types.UpdateKeyRequest{} - err := readRequest(r, &req) - if err != nil { - writeError(w, err) - return - } - - vars := mux.Vars(r) - name := vars["name"] - if name != req.Name { - writeError(w, errors.New("path and json key names don't match")) - return - } - - err = k.manager.Update(req.Name, req.OldPass, req.NewPass) - if err != nil { - writeError(w, err) - return - } - - key, err := k.manager.Get(req.Name) - if err != nil { - writeError(w, err) - return - } - writeSuccess(w, &key) -} - -func (k Keys) DeleteKey(w http.ResponseWriter, r *http.Request) { - req := types.DeleteKeyRequest{} - err := readRequest(r, &req) - if err != nil { - writeError(w, err) - return - } - - vars := mux.Vars(r) - name := vars["name"] - if name != req.Name { - writeError(w, errors.New("path and json key names don't match")) - return - } - - err = k.manager.Delete(req.Name, req.Passphrase) - if err != nil { - writeError(w, err) - return - } - - // not really an error, but something generic - resp := types.ErrorResponse{ - Success: true, - } - writeSuccess(w, &resp) -} - -func (k Keys) Register(r *mux.Router) { - r.HandleFunc("/", k.GenerateKey).Methods("POST") - r.HandleFunc("/", k.ListKeys).Methods("GET") - r.HandleFunc("/{name}", k.GetKey).Methods("GET") - r.HandleFunc("/{name}", k.UpdateKey).Methods("POST", "PUT") - r.HandleFunc("/{name}", k.DeleteKey).Methods("DELETE") -} diff --git a/keys/server/keys_test.go b/keys/server/keys_test.go deleted file mode 100644 index 2aa17753c..000000000 --- a/keys/server/keys_test.go +++ /dev/null @@ -1,193 +0,0 @@ -package server_test - -import ( - "bytes" - "encoding/json" - "net/http" - "net/http/httptest" - "testing" - - "github.com/gorilla/mux" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - keys "github.com/tendermint/go-crypto/keys" - "github.com/tendermint/go-crypto/keys/cryptostore" - "github.com/tendermint/go-crypto/keys/server" - "github.com/tendermint/go-crypto/keys/server/types" - "github.com/tendermint/go-crypto/keys/storage/memstorage" -) - -func TestKeyServer(t *testing.T) { - assert, require := assert.New(t), require.New(t) - r := setupServer() - - // let's abstract this out a bit.... - keys, code, err := listKeys(r) - require.Nil(err) - require.Equal(http.StatusOK, code) - assert.Equal(0, len(keys)) - - algo := "ed25519" - n1, n2 := "personal", "business" - p0, p1, p2 := "1234", "over10chars...", "really-secure!@#$" - - // this fails for validation - _, code, err = createKey(r, n1, p0, algo) - require.Nil(err, "%+v", err) - require.NotEqual(http.StatusOK, code) - - // new password better - key, code, err := createKey(r, n1, p1, algo) - require.Nil(err, "%+v", err) - require.Equal(http.StatusOK, code) - require.Equal(n1, key.Key.Name) - require.NotEmpty(n1, key.Seed) - - // the other one works - key2, code, err := createKey(r, n2, p2, algo) - require.Nil(err, "%+v", err) - require.Equal(http.StatusOK, code) - require.Equal(key2.Key.Name, n2) - require.NotEmpty(n2, key.Seed) - - // let's abstract this out a bit.... - keys, code, err = listKeys(r) - require.Nil(err) - require.Equal(http.StatusOK, code) - if assert.Equal(2, len(keys)) { - // in alphabetical order - assert.Equal(keys[0].Name, n2) - assert.Equal(keys[1].Name, n1) - } - - // get works - k, code, err := getKey(r, n1) - require.Nil(err, "%+v", err) - require.Equal(http.StatusOK, code) - assert.Equal(n1, k.Name) - assert.NotNil(k.Address) - assert.Equal(key.Key.Address, k.Address) - - // delete with proper key - _, code, err = deleteKey(r, n1, p1) - require.Nil(err, "%+v", err) - require.Equal(http.StatusOK, code) - - // after delete, get and list different - _, code, err = getKey(r, n1) - require.Nil(err, "%+v", err) - require.NotEqual(http.StatusOK, code) - keys, code, err = listKeys(r) - require.Nil(err, "%+v", err) - require.Equal(http.StatusOK, code) - if assert.Equal(1, len(keys)) { - assert.Equal(keys[0].Name, n2) - } - -} - -func setupServer() http.Handler { - // make the storage with reasonable defaults - cstore := cryptostore.New( - cryptostore.SecretBox, - memstorage.New(), - keys.MustLoadCodec("english"), - ) - - // build your http server - ks := server.New(cstore, "ed25519") - r := mux.NewRouter() - sk := r.PathPrefix("/keys").Subrouter() - ks.Register(sk) - return r -} - -// return data, status code, and error -func listKeys(h http.Handler) (keys.Infos, int, error) { - rr := httptest.NewRecorder() - req, err := http.NewRequest("GET", "/keys/", nil) - if err != nil { - return nil, 0, err - } - - h.ServeHTTP(rr, req) - if http.StatusOK != rr.Code { - return nil, rr.Code, nil - } - - data := keys.Infos{} - err = json.Unmarshal(rr.Body.Bytes(), &data) - return data, rr.Code, err -} - -func getKey(h http.Handler, name string) (*keys.Info, int, error) { - rr := httptest.NewRecorder() - req, err := http.NewRequest("GET", "/keys/"+name, nil) - if err != nil { - return nil, 0, err - } - - h.ServeHTTP(rr, req) - if http.StatusOK != rr.Code { - return nil, rr.Code, nil - } - - data := keys.Info{} - err = json.Unmarshal(rr.Body.Bytes(), &data) - return &data, rr.Code, err -} - -func createKey(h http.Handler, name, passphrase, algo string) (*types.CreateKeyResponse, int, error) { - rr := httptest.NewRecorder() - post := types.CreateKeyRequest{ - Name: name, - Passphrase: passphrase, - Algo: algo, - } - var b bytes.Buffer - err := json.NewEncoder(&b).Encode(&post) - if err != nil { - return nil, 0, err - } - - req, err := http.NewRequest("POST", "/keys/", &b) - if err != nil { - return nil, 0, err - } - - h.ServeHTTP(rr, req) - if http.StatusOK != rr.Code { - return nil, rr.Code, nil - } - - data := new(types.CreateKeyResponse) - err = json.Unmarshal(rr.Body.Bytes(), data) - return data, rr.Code, err -} - -func deleteKey(h http.Handler, name, passphrase string) (*types.ErrorResponse, int, error) { - rr := httptest.NewRecorder() - post := types.DeleteKeyRequest{ - Name: name, - Passphrase: passphrase, - } - var b bytes.Buffer - err := json.NewEncoder(&b).Encode(&post) - if err != nil { - return nil, 0, err - } - - req, err := http.NewRequest("DELETE", "/keys/"+name, &b) - if err != nil { - return nil, 0, err - } - - h.ServeHTTP(rr, req) - if http.StatusOK != rr.Code { - return nil, rr.Code, nil - } - - data := types.ErrorResponse{} - err = json.Unmarshal(rr.Body.Bytes(), &data) - return &data, rr.Code, err -} diff --git a/keys/server/types/keys.go b/keys/server/types/keys.go deleted file mode 100644 index 56ed60ceb..000000000 --- a/keys/server/types/keys.go +++ /dev/null @@ -1,35 +0,0 @@ -package types - -import "github.com/tendermint/go-crypto/keys" - -// CreateKeyRequest is sent to create a new key -type CreateKeyRequest struct { - Name string `json:"name" validate:"required,min=4,printascii"` - Passphrase string `json:"passphrase" validate:"required,min=10"` - Algo string `json:"algo"` -} - -// DeleteKeyRequest to destroy a key permanently (careful!) -type DeleteKeyRequest struct { - Name string `json:"name" validate:"required,min=4,printascii"` - Passphrase string `json:"passphrase" validate:"required,min=10"` -} - -// UpdateKeyRequest is sent to update the passphrase for an existing key -type UpdateKeyRequest struct { - Name string `json:"name" validate:"required,min=4,printascii"` - OldPass string `json:"passphrase" validate:"required,min=10"` - NewPass string `json:"new_passphrase" validate:"required,min=10"` -} - -// ErrorResponse is returned for 4xx and 5xx errors -type ErrorResponse struct { - Success bool `json:"success"` - Error string `json:"error"` // error message if Success is false - Code int `json:"code"` // error code if Success is false -} - -type CreateKeyResponse struct { - Key keys.Info `json:"key"` - Seed string `json:"seed_phrase"` -} diff --git a/keys/server/valid.go b/keys/server/valid.go deleted file mode 100644 index 50b51e21b..000000000 --- a/keys/server/valid.go +++ /dev/null @@ -1,12 +0,0 @@ -package server - -import ( - "github.com/pkg/errors" - "gopkg.in/go-playground/validator.v9" -) - -var v = validator.New() - -func validate(req interface{}) error { - return errors.Wrap(v.Struct(req), "Validate") -} From 0219ba2a63e2dcf027b8af8741900409a962224b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 24 Oct 2017 12:14:20 +0200 Subject: [PATCH 157/287] Fix bug introduced by metalinting... --- keys/cryptostore/encoder.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/keys/cryptostore/encoder.go b/keys/cryptostore/encoder.go index 531a534ad..31f49c3f7 100644 --- a/keys/cryptostore/encoder.go +++ b/keys/cryptostore/encoder.go @@ -39,11 +39,12 @@ func (e secretbox) Encrypt(privKey crypto.PrivKey, passphrase string) (saltBytes return saltBytes, crypto.EncryptSymmetric(privKeyBytes, key), nil } -func (e secretbox) Decrypt(saltBytes []byte, encBytes []byte, passphrase string) (crypto.PrivKey, error) { +func (e secretbox) Decrypt(saltBytes []byte, encBytes []byte, passphrase string) (privKey crypto.PrivKey, err error) { privKeyBytes := encBytes // NOTE: Some keys weren't encrypted with a passphrase and hence we have the conditional if passphrase != "" { - key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 14) // TODO parameterize. 14 is good today (2016) + var key []byte + key, err = bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 14) // TODO parameterize. 14 is good today (2016) if err != nil { return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") } @@ -53,7 +54,7 @@ func (e secretbox) Decrypt(saltBytes []byte, encBytes []byte, passphrase string) return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") } } - privKey, err := crypto.PrivKeyFromBytes(privKeyBytes) + privKey, err = crypto.PrivKeyFromBytes(privKeyBytes) if err != nil { return crypto.PrivKey{}, errors.Wrap(err, "Private Key") } From dfc4cdd2d71513e4a9922d679c74f36357c4c862 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 24 Oct 2017 11:48:13 +0200 Subject: [PATCH 158/287] Parameterize and lower bcrypt cost --- keys/cryptostore/encoder.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/keys/cryptostore/encoder.go b/keys/cryptostore/encoder.go index 31f49c3f7..99241f1b7 100644 --- a/keys/cryptostore/encoder.go +++ b/keys/cryptostore/encoder.go @@ -7,6 +7,20 @@ import ( "github.com/tendermint/go-crypto/bcrypt" ) +const ( + // BcryptCost is as parameter to increase the resistance of the + // encoded keys to brute force password guessing + // + // Jae: 14 is good today (2016) + // + // Ethan: loading the key (at each signing) takes a second on my desktop, + // this is hard for laptops and deadly for mobile. You can raise it again, + // but for now, I will make this usable + // + // TODO: review value + BCryptCost = 12 +) + var ( // SecretBox uses the algorithm from NaCL to store secrets securely SecretBox Encoder = secretbox{} @@ -30,7 +44,7 @@ func (e secretbox) Encrypt(privKey crypto.PrivKey, passphrase string) (saltBytes } saltBytes = crypto.CRandBytes(16) - key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 14) // TODO parameterize. 14 is good today (2016) + key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), BCryptCost) if err != nil { return nil, nil, errors.Wrap(err, "Couldn't generate bcrypt key from passphrase.") } @@ -44,7 +58,7 @@ func (e secretbox) Decrypt(saltBytes []byte, encBytes []byte, passphrase string) // NOTE: Some keys weren't encrypted with a passphrase and hence we have the conditional if passphrase != "" { var key []byte - key, err = bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 14) // TODO parameterize. 14 is good today (2016) + key, err = bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), BCryptCost) if err != nil { return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") } From 3df2ca128d12a20c63fb05fd20d37132b7576760 Mon Sep 17 00:00:00 2001 From: Emmanuel Odeke Date: Wed, 25 Oct 2017 19:56:08 -0700 Subject: [PATCH 159/287] make PrivateKey + Signature comparisons use constant time comparisons Fixes https://github.com/tendermint/go-crypto/issues/43 Avoid susceptibility to timing/side channel attacks by ensuring that private key and signature comparisons use `subtle.ConstantTimeCompare` instead of `bytes.Equal` --- priv_key.go | 14 +++++++++++--- signature.go | 14 +++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/priv_key.go b/priv_key.go index 0c6bd2ae7..456985615 100644 --- a/priv_key.go +++ b/priv_key.go @@ -1,7 +1,7 @@ package crypto import ( - "bytes" + "crypto/subtle" secp256k1 "github.com/btcsuite/btcd/btcec" "github.com/tendermint/ed25519" @@ -57,7 +57,11 @@ func (privKey PrivKeyEd25519) PubKey() PubKey { func (privKey PrivKeyEd25519) Equals(other PrivKey) bool { if otherEd, ok := other.Unwrap().(PrivKeyEd25519); ok { - return bytes.Equal(privKey[:], otherEd[:]) + // It is essential that we constant time compare + // private keys and signatures instead of bytes.Equal, + // to avoid susceptibility to timing/side channel attacks. + // See Issue https://github.com/tendermint/go-crypto/issues/43 + return subtle.ConstantTimeCompare(privKey[:], otherEd[:]) == 0 } else { return false } @@ -144,7 +148,11 @@ func (privKey PrivKeySecp256k1) PubKey() PubKey { func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool { if otherSecp, ok := other.Unwrap().(PrivKeySecp256k1); ok { - return bytes.Equal(privKey[:], otherSecp[:]) + // It is essential that we constant time compare + // private keys and signatures instead of bytes.Equal, + // to avoid susceptibility to timing/side channel attacks. + // See Issue https://github.com/tendermint/go-crypto/issues/43 + return subtle.ConstantTimeCompare(privKey[:], otherSecp[:]) == 0 } else { return false } diff --git a/signature.go b/signature.go index 5b1d6cb05..fb07aba96 100644 --- a/signature.go +++ b/signature.go @@ -1,7 +1,7 @@ package crypto import ( - "bytes" + "crypto/subtle" "fmt" "github.com/tendermint/go-wire" @@ -46,7 +46,11 @@ func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fing func (sig SignatureEd25519) Equals(other Signature) bool { if otherEd, ok := other.Unwrap().(SignatureEd25519); ok { - return bytes.Equal(sig[:], otherEd[:]) + // It is essential that we constant time compare + // private keys and signatures instead of bytes.Equal, + // to avoid susceptibility to timing/side channel attacks. + // See Issue https://github.com/tendermint/go-crypto/issues/43 + return subtle.ConstantTimeCompare(sig[:], otherEd[:]) == 0 } else { return false } @@ -82,7 +86,11 @@ func (sig SignatureSecp256k1) String() string { return fmt.Sprintf("/%X.../", Fi func (sig SignatureSecp256k1) Equals(other Signature) bool { if otherEd, ok := other.Unwrap().(SignatureSecp256k1); ok { - return bytes.Equal(sig[:], otherEd[:]) + // It is essential that we constant time compare + // private keys and signatures instead of bytes.Equal, + // to avoid susceptibility to timing/side channel attacks. + // See Issue https://github.com/tendermint/go-crypto/issues/43 + return subtle.ConstantTimeCompare(sig[:], otherEd[:]) == 0 } else { return false } From 5d8890530a26d86cb7b7baa179473ebac60e07e6 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 26 Oct 2017 12:00:36 +0200 Subject: [PATCH 160/287] Update glide deps, nano/hid for osx/golang1.9 --- glide.lock | 32 +++++++------------------------- glide.yaml | 6 ------ 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/glide.lock b/glide.lock index 29124c3db..7df64f79f 100644 --- a/glide.lock +++ b/glide.lock @@ -1,26 +1,20 @@ -hash: a2243bfd21937edf660778300855e7cb72185164641cb278dbf0c220e8a0f60a -updated: 2017-10-23T17:21:02.40831023+02:00 +hash: 6e06a42eafe0aeff112cee86aef6b2cab0e2f62c2e6bfccfb629aa22f6b62773 +updated: 2017-10-26T11:57:48.785457739+02:00 imports: -- name: github.com/bgentry/speakeasy - version: 4aabc24848ce5fd31929f7d1e4ea74d3709c14cd - name: github.com/btcsuite/btcd version: b8df516b4b267acf2de46be593a9d948d1d2c420 subpackages: - btcec - - chaincfg - - chaincfg/chainhash - - wire - name: github.com/btcsuite/btcutil version: 66871daeb12123ece012a9628d2798d01195c4b3 subpackages: - base58 - - hdkeychain - name: github.com/btcsuite/fastsha256 version: 637e656429416087660c84436a2a035d69d54e2e +- name: github.com/ethanfrey/hid + version: f379bda1dbc8e79333b04563f71a12e86206efe5 - name: github.com/ethanfrey/ledger - version: 5e432577be582bd18a3b4a9cd75dae7a317ade36 -- name: github.com/flynn/hid - version: ed06a31c6245d4552e8dbba7e32e5b010b875d65 + version: 3689ce9be93e1a5bef836b1cc2abb18381c79176 - name: github.com/go-kit/kit version: d67bb4c202e3b91377d1079b110a6c9ce23ab2f8 subpackages: @@ -37,34 +31,24 @@ imports: version: 71201497bace774495daed26a3874fd339e0b538 - name: github.com/go-stack/stack version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82 -- name: github.com/gorilla/context - version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42 -- name: github.com/gorilla/handlers - version: a4043c62cc2329bacda331d33fc908ab11ef0ec3 -- name: github.com/gorilla/mux - version: bcd8bc72b08df0f70df986b97f95590779502d31 - name: github.com/howeyc/crc16 version: 58da63c846043d0bea709c8d47039df06577d6d9 - name: github.com/kr/logfmt version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0 - name: github.com/pkg/errors version: 645ef00459ed84a119197bfb8d8205042c6df63d -- name: github.com/spf13/cobra - version: 4cdb38c072b86bf795d2c81de50784d9fdd6eb77 -- name: github.com/spf13/viper - version: 0967fc9aceab2ce9da34061253ac10fb99bba5b2 - name: github.com/tendermint/ed25519 version: 1f52c6f8b8a5c7908aff4497c186af344b428925 subpackages: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: 55ae61f1fc83cfaa57ab7d54250d7a1a2be0b83c + version: 3180c867ca52bcd9ba6c905ce63613f8d8e9837c subpackages: - data - data/base58 - name: github.com/tendermint/tmlibs - version: 8e5266a9ef2527e68a1571f932db8228a331b556 + version: b30e3ba26d4077edeed83c50a4e0c38b0ec9ddb3 subpackages: - common - log @@ -83,8 +67,6 @@ imports: - name: gopkg.in/go-playground/validator.v9 version: 6d8c18553ea1ac493d049edd6f102f52e618f085 testImports: -- name: github.com/cmars/basen - version: fe3947df716ebfda9847eb1b9a48f9592e06478c - name: github.com/davecgh/go-spew version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 subpackages: diff --git a/glide.yaml b/glide.yaml index 9f20ddefc..2f3e72471 100644 --- a/glide.yaml +++ b/glide.yaml @@ -22,13 +22,7 @@ import: - nacl/secretbox - openpgp/armor - ripemd160 -- package: github.com/bgentry/speakeasy -- package: github.com/gorilla/handlers -- package: github.com/gorilla/mux - package: github.com/pkg/errors -- package: github.com/spf13/cobra -- package: github.com/spf13/viper -- package: gopkg.in/go-playground/validator.v9 - package: github.com/howeyc/crc16 - package: github.com/ethanfrey/ledger testImport: From 57346134a57c16559ce009464a96dfd37547a06c Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Thu, 26 Oct 2017 16:43:32 -0400 Subject: [PATCH 161/287] keys: transactions.go -> types.go --- keys/storage.go | 10 ---------- keys/{transactions.go => types.go} | 9 +++++++++ 2 files changed, 9 insertions(+), 10 deletions(-) delete mode 100644 keys/storage.go rename keys/{transactions.go => types.go} (91%) diff --git a/keys/storage.go b/keys/storage.go deleted file mode 100644 index 0aba4ebdb..000000000 --- a/keys/storage.go +++ /dev/null @@ -1,10 +0,0 @@ -package keys - -// Storage has many implementation, based on security and sharing requirements -// like disk-backed, mem-backed, vault, db, etc. -type Storage interface { - Put(name string, salt []byte, key []byte, info Info) error - Get(name string) (salt []byte, key []byte, info Info, err error) - List() (Infos, error) - Delete(name string) error -} diff --git a/keys/transactions.go b/keys/types.go similarity index 91% rename from keys/transactions.go rename to keys/types.go index 1834ada26..008a6f7ae 100644 --- a/keys/transactions.go +++ b/keys/types.go @@ -9,6 +9,15 @@ import ( data "github.com/tendermint/go-wire/data" ) +// Storage has many implementation, based on security and sharing requirements +// like disk-backed, mem-backed, vault, db, etc. +type Storage interface { + Put(name string, salt []byte, key []byte, info Info) error + Get(name string) (salt []byte, key []byte, info Info, err error) + List() (Infos, error) + Delete(name string) error +} + // Info is the public information about a key type Info struct { Name string `json:"name"` From 944d36ab00d5f82ef590ea515d437134e2e161ad Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 27 Oct 2017 12:04:31 -0400 Subject: [PATCH 162/287] changelog --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63d4af1d8..99f1ea7da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 0.4.0 (October 27, 2017) + +BREAKING CHANGES: + +- `keys`: use bcrypt plus salt + +FEATURES: + +- add support for signing via Ledger Nano + ## 0.3.0 (September 22, 2017) BREAKING CHANGES: From ad31f6a95327a1997e1c75fd57645ee5dd731332 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Fri, 27 Oct 2017 18:46:21 +0200 Subject: [PATCH 163/287] osx + hid = <3 --- glide.lock | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/glide.lock b/glide.lock index 7df64f79f..096ec5c15 100644 --- a/glide.lock +++ b/glide.lock @@ -1,22 +1,20 @@ hash: 6e06a42eafe0aeff112cee86aef6b2cab0e2f62c2e6bfccfb629aa22f6b62773 -updated: 2017-10-26T11:57:48.785457739+02:00 +updated: 2017-10-27T18:45:18.350198941+02:00 imports: - name: github.com/btcsuite/btcd - version: b8df516b4b267acf2de46be593a9d948d1d2c420 + version: c7588cbf7690cd9f047a28efa2dcd8f2435a4e5e subpackages: - btcec - name: github.com/btcsuite/btcutil version: 66871daeb12123ece012a9628d2798d01195c4b3 subpackages: - base58 -- name: github.com/btcsuite/fastsha256 - version: 637e656429416087660c84436a2a035d69d54e2e - name: github.com/ethanfrey/hid - version: f379bda1dbc8e79333b04563f71a12e86206efe5 + version: 660bb717bd4e7cbcdf0f7cd5cadf1cb2e4be452a - name: github.com/ethanfrey/ledger - version: 3689ce9be93e1a5bef836b1cc2abb18381c79176 + version: 23a7bb9d74bc83a862fcb4bddde24215b2295ad9 - name: github.com/go-kit/kit - version: d67bb4c202e3b91377d1079b110a6c9ce23ab2f8 + version: e2b298466b32c7cd5579a9b9b07e968fc9d9452c subpackages: - log - log/level @@ -24,36 +22,36 @@ imports: - name: github.com/go-logfmt/logfmt version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5 - name: github.com/go-playground/locales - version: 1e5f1161c6416a5ff48840eb8724a394e48cc534 + version: e4cbcb5d0652150d40ad0646651076b6bd2be4f6 subpackages: - currency - name: github.com/go-playground/universal-translator version: 71201497bace774495daed26a3874fd339e0b538 - name: github.com/go-stack/stack - version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82 + version: 817915b46b97fd7bb80e8ab6b69f01a53ac3eebf - name: github.com/howeyc/crc16 - version: 58da63c846043d0bea709c8d47039df06577d6d9 + version: 96a97a1abb579c7ff1a8ffa77f2e72d1c314b57f - name: github.com/kr/logfmt version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0 - name: github.com/pkg/errors version: 645ef00459ed84a119197bfb8d8205042c6df63d - name: github.com/tendermint/ed25519 - version: 1f52c6f8b8a5c7908aff4497c186af344b428925 + version: d8387025d2b9d158cf4efb07e7ebf814bcce2057 subpackages: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: 3180c867ca52bcd9ba6c905ce63613f8d8e9837c + version: 8ee84b5b2581530168daf66fc89c548d27403c57 subpackages: - data - data/base58 - name: github.com/tendermint/tmlibs - version: b30e3ba26d4077edeed83c50a4e0c38b0ec9ddb3 + version: 092eb701c7276907cdbed258750e22ce895b6735 subpackages: - common - log - name: golang.org/x/crypto - version: c7af5bf2638a1164f2eb5467c39c6cffbd13a02e + version: edd5e9b0879d13ee6970a50153d85b8fec9f7686 subpackages: - bcrypt - blowfish @@ -65,7 +63,7 @@ imports: - ripemd160 - salsa20/salsa - name: gopkg.in/go-playground/validator.v9 - version: 6d8c18553ea1ac493d049edd6f102f52e618f085 + version: 1304298bf10d085adec514b076772a79c9cadb6b testImports: - name: github.com/davecgh/go-spew version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 From 8630b724b2f267940f696885cebda954f9eaa7cd Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 27 Oct 2017 12:57:26 -0400 Subject: [PATCH 164/287] version and changelog --- CHANGELOG.md | 4 ++++ version.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99f1ea7da..64dc9998b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ FEATURES: - add support for signing via Ledger Nano +IMPROVEMENTS: + +- linting and comments + ## 0.3.0 (September 22, 2017) BREAKING CHANGES: diff --git a/version.go b/version.go index 23d065446..585d7e0d7 100644 --- a/version.go +++ b/version.go @@ -1,3 +1,3 @@ package crypto -const Version = "0.3.0" +const Version = "0.4.0" From 87badb090ff941c5359b4017705f67976e8c3ca2 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 27 Oct 2017 21:58:02 -0400 Subject: [PATCH 165/287] Revert "Parameterize and lower bcrypt cost" This reverts commit dfc4cdd2d71513e4a9922d679c74f36357c4c862. --- keys/cryptostore/encoder.go | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/keys/cryptostore/encoder.go b/keys/cryptostore/encoder.go index 99241f1b7..31f49c3f7 100644 --- a/keys/cryptostore/encoder.go +++ b/keys/cryptostore/encoder.go @@ -7,20 +7,6 @@ import ( "github.com/tendermint/go-crypto/bcrypt" ) -const ( - // BcryptCost is as parameter to increase the resistance of the - // encoded keys to brute force password guessing - // - // Jae: 14 is good today (2016) - // - // Ethan: loading the key (at each signing) takes a second on my desktop, - // this is hard for laptops and deadly for mobile. You can raise it again, - // but for now, I will make this usable - // - // TODO: review value - BCryptCost = 12 -) - var ( // SecretBox uses the algorithm from NaCL to store secrets securely SecretBox Encoder = secretbox{} @@ -44,7 +30,7 @@ func (e secretbox) Encrypt(privKey crypto.PrivKey, passphrase string) (saltBytes } saltBytes = crypto.CRandBytes(16) - key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), BCryptCost) + key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 14) // TODO parameterize. 14 is good today (2016) if err != nil { return nil, nil, errors.Wrap(err, "Couldn't generate bcrypt key from passphrase.") } @@ -58,7 +44,7 @@ func (e secretbox) Decrypt(saltBytes []byte, encBytes []byte, passphrase string) // NOTE: Some keys weren't encrypted with a passphrase and hence we have the conditional if passphrase != "" { var key []byte - key, err = bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), BCryptCost) + key, err = bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 14) // TODO parameterize. 14 is good today (2016) if err != nil { return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") } From 64056182206e90f16833c1a270414cf82c1856d6 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 27 Oct 2017 22:02:44 -0400 Subject: [PATCH 166/287] Revert "Upgrade keys to use bcrypt with salts (#38)" This reverts commit 8e7f0e7701f92206679ad093d013b9b162427631. --- keys/cryptostore/enc_storage.go | 8 +- keys/cryptostore/encoder.go | 60 ++++++-------- keys/cryptostore/encoder_test.go | 22 +++--- keys/cryptostore/generator.go | 1 - keys/cryptostore/holder.go | 18 ++--- keys/cryptostore/holder_test.go | 10 +-- keys/cryptostore/storage_test.go | 2 +- keys/storage/filestorage/main.go | 108 ++++++-------------------- keys/storage/filestorage/main_test.go | 13 ++-- keys/storage/memstorage/main.go | 12 ++- keys/storage/memstorage/main_test.go | 13 ++-- 11 files changed, 94 insertions(+), 173 deletions(-) diff --git a/keys/cryptostore/enc_storage.go b/keys/cryptostore/enc_storage.go index e0c7e59a3..daeb220b5 100644 --- a/keys/cryptostore/enc_storage.go +++ b/keys/cryptostore/enc_storage.go @@ -12,21 +12,21 @@ type encryptedStorage struct { } func (es encryptedStorage) Put(name, pass string, key crypto.PrivKey) error { - saltBytes, encBytes, err := es.coder.Encrypt(key, pass) + secret, err := es.coder.Encrypt(key, pass) if err != nil { return err } ki := info(name, key) - return es.store.Put(name, saltBytes, encBytes, ki) + return es.store.Put(name, secret, ki) } func (es encryptedStorage) Get(name, pass string) (crypto.PrivKey, keys.Info, error) { - saltBytes, encBytes, info, err := es.store.Get(name) + secret, info, err := es.store.Get(name) if err != nil { return crypto.PrivKey{}, info, err } - key, err := es.coder.Decrypt(saltBytes, encBytes, pass) + key, err := es.coder.Decrypt(secret, pass) return key, info, err } diff --git a/keys/cryptostore/encoder.go b/keys/cryptostore/encoder.go index 31f49c3f7..31cbc2e54 100644 --- a/keys/cryptostore/encoder.go +++ b/keys/cryptostore/encoder.go @@ -2,9 +2,7 @@ package cryptostore import ( "github.com/pkg/errors" - crypto "github.com/tendermint/go-crypto" - "github.com/tendermint/go-crypto/bcrypt" ) var ( @@ -18,55 +16,45 @@ var ( // // This should use a well-designed symetric encryption algorithm type Encoder interface { - Encrypt(privKey crypto.PrivKey, passphrase string) (saltBytes []byte, encBytes []byte, err error) - Decrypt(saltBytes []byte, encBytes []byte, passphrase string) (privKey crypto.PrivKey, err error) + Encrypt(key crypto.PrivKey, pass string) ([]byte, error) + Decrypt(data []byte, pass string) (crypto.PrivKey, error) } -type secretbox struct{} +func secret(passphrase string) []byte { + // TODO: Sha256(Bcrypt(passphrase)) + return crypto.Sha256([]byte(passphrase)) +} -func (e secretbox) Encrypt(privKey crypto.PrivKey, passphrase string) (saltBytes []byte, encBytes []byte, err error) { - if passphrase == "" { - return nil, privKey.Bytes(), nil - } +type secretbox struct{} - saltBytes = crypto.CRandBytes(16) - key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 14) // TODO parameterize. 14 is good today (2016) - if err != nil { - return nil, nil, errors.Wrap(err, "Couldn't generate bcrypt key from passphrase.") +func (e secretbox) Encrypt(key crypto.PrivKey, pass string) ([]byte, error) { + if pass == "" { + return key.Bytes(), nil } - key = crypto.Sha256(key) // Get 32 bytes - privKeyBytes := privKey.Bytes() - return saltBytes, crypto.EncryptSymmetric(privKeyBytes, key), nil + s := secret(pass) + cipher := crypto.EncryptSymmetric(key.Bytes(), s) + return cipher, nil } -func (e secretbox) Decrypt(saltBytes []byte, encBytes []byte, passphrase string) (privKey crypto.PrivKey, err error) { - privKeyBytes := encBytes - // NOTE: Some keys weren't encrypted with a passphrase and hence we have the conditional - if passphrase != "" { - var key []byte - key, err = bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 14) // TODO parameterize. 14 is good today (2016) +func (e secretbox) Decrypt(data []byte, pass string) (key crypto.PrivKey, err error) { + private := data + if pass != "" { + s := secret(pass) + private, err = crypto.DecryptSymmetric(data, s) if err != nil { return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") } - key = crypto.Sha256(key) // Get 32 bytes - privKeyBytes, err = crypto.DecryptSymmetric(encBytes, key) - if err != nil { - return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") - } - } - privKey, err = crypto.PrivKeyFromBytes(privKeyBytes) - if err != nil { - return crypto.PrivKey{}, errors.Wrap(err, "Private Key") } - return privKey, nil + key, err = crypto.PrivKeyFromBytes(private) + return key, errors.Wrap(err, "Invalid Passphrase") } type noop struct{} -func (n noop) Encrypt(key crypto.PrivKey, passphrase string) (saltBytes []byte, encBytes []byte, err error) { - return []byte{}, key.Bytes(), nil +func (n noop) Encrypt(key crypto.PrivKey, pass string) ([]byte, error) { + return key.Bytes(), nil } -func (n noop) Decrypt(saltBytes []byte, encBytes []byte, passphrase string) (privKey crypto.PrivKey, err error) { - return crypto.PrivKeyFromBytes(encBytes) +func (n noop) Decrypt(data []byte, pass string) (crypto.PrivKey, error) { + return crypto.PrivKeyFromBytes(data) } diff --git a/keys/cryptostore/encoder_test.go b/keys/cryptostore/encoder_test.go index 614286a19..9a0757b73 100644 --- a/keys/cryptostore/encoder_test.go +++ b/keys/cryptostore/encoder_test.go @@ -20,22 +20,22 @@ func TestNoopEncoder(t *testing.T) { key2, err := cryptostore.GenSecp256k1.Generate(cmn.RandBytes(16)) require.NoError(err) - _, b, err := noop.Encrypt(key, "encode") + b, err := noop.Encrypt(key, "encode") require.Nil(err) assert.NotEmpty(b) - _, b2, err := noop.Encrypt(key2, "encode") + b2, err := noop.Encrypt(key2, "encode") require.Nil(err) assert.NotEmpty(b2) assert.NotEqual(b, b2) // note the decode with a different password works - not secure! - pk, err := noop.Decrypt(nil, b, "decode") + pk, err := noop.Decrypt(b, "decode") require.Nil(err) require.NotNil(pk) assert.Equal(key, pk) - pk2, err := noop.Decrypt(nil, b2, "kggugougp") + pk2, err := noop.Decrypt(b2, "kggugougp") require.Nil(err) require.NotNil(pk2) assert.Equal(key2, pk2) @@ -49,17 +49,17 @@ func TestSecretBox(t *testing.T) { require.NoError(err) pass := "some-special-secret" - s, b, err := enc.Encrypt(key, pass) + b, err := enc.Encrypt(key, pass) require.Nil(err) assert.NotEmpty(b) // decoding with a different pass is an error - pk, err := enc.Decrypt(s, b, "decode") + pk, err := enc.Decrypt(b, "decode") require.NotNil(err) require.True(pk.Empty()) // but decoding with the same passphrase gets us our key - pk, err = enc.Decrypt(s, b, pass) + pk, err = enc.Decrypt(b, pass) require.Nil(err) assert.Equal(key, pk) } @@ -84,11 +84,11 @@ func TestSecretBoxNoPass(t *testing.T) { } for i, tc := range cases { - s, b, err := enc.Encrypt(key, tc.encode) + b, err := enc.Encrypt(key, tc.encode) require.Nil(err, "%d: %+v", i, err) assert.NotEmpty(b, "%d", i) - pk, err := enc.Decrypt(s, b, tc.decode) + pk, err := enc.Decrypt(b, tc.decode) if tc.valid { require.Nil(err, "%d: %+v", i, err) assert.Equal(key, pk, "%d", i) @@ -99,7 +99,7 @@ func TestSecretBoxNoPass(t *testing.T) { // now let's make sure raw bytes also work... b := key.Bytes() - pk, rerr := enc.Decrypt(nil, b, "") - require.NoError(rerr) + pk, err := enc.Decrypt(b, "") + require.Nil(err, "%+v", err) assert.Equal(key, pk) } diff --git a/keys/cryptostore/generator.go b/keys/cryptostore/generator.go index 65cc8e58b..81277eda9 100644 --- a/keys/cryptostore/generator.go +++ b/keys/cryptostore/generator.go @@ -2,7 +2,6 @@ package cryptostore import ( "github.com/pkg/errors" - crypto "github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto/nano" ) diff --git a/keys/cryptostore/holder.go b/keys/cryptostore/holder.go index 923190c1b..7e89dda38 100644 --- a/keys/cryptostore/holder.go +++ b/keys/cryptostore/holder.go @@ -95,7 +95,7 @@ func (s Manager) List() (keys.Infos, error) { // Get returns the public information about one key func (s Manager) Get(name string) (keys.Info, error) { - _, _, info, err := s.es.store.Get(name) + _, info, err := s.es.store.Get(name) return info, err } @@ -119,23 +119,21 @@ func (s Manager) Sign(name, passphrase string, tx keys.Signable) error { // // This is designed to copy from one device to another, or provide backups // during version updates. -// TODO: How to handle Export with salt? -func (s Manager) Export(name, oldpass, transferpass string) (salt, data []byte, err error) { +func (s Manager) Export(name, oldpass, transferpass string) ([]byte, error) { key, _, err := s.es.Get(name, oldpass) if err != nil { - return nil, nil, err + return nil, err } - salt, data, err = s.es.coder.Encrypt(key, transferpass) - return salt, data, err + res, err := s.es.coder.Encrypt(key, transferpass) + return res, err } // Import accepts bytes generated by Export along with the same transferpass -// If they are valid, it stores the key under the given name with the +// If they are valid, it stores the password under the given name with the // new passphrase. -// TODO: How to handle Import with salt? -func (s Manager) Import(name, newpass, transferpass string, salt, data []byte) error { - key, err := s.es.coder.Decrypt(salt, data, transferpass) +func (s Manager) Import(name, newpass, transferpass string, data []byte) error { + key, err := s.es.coder.Decrypt(data, transferpass) if err != nil { return err } diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index 3709cc55d..a9056f0de 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -232,7 +232,7 @@ func TestImportUnencrypted(t *testing.T) { pass := "top-secret" // import raw bytes - err = cstore.Import(name, pass, "", nil, key.Bytes()) + err = cstore.Import(name, pass, "", key.Bytes()) require.Nil(err, "%+v", err) // make sure the address matches @@ -273,15 +273,15 @@ func TestAdvancedKeyManagement(t *testing.T) { assertPassword(assert, cstore, n1, p2, p1) // exporting requires the proper name and passphrase - _, _, err = cstore.Export(n2, p2, pt) + _, err = cstore.Export(n2, p2, pt) assert.NotNil(err) - _, _, err = cstore.Export(n1, p1, pt) + _, err = cstore.Export(n1, p1, pt) assert.NotNil(err) - salt, exported, err := cstore.Export(n1, p2, pt) + exported, err := cstore.Export(n1, p2, pt) require.Nil(err, "%+v", err) // import fails on bad transfer pass - err = cstore.Import(n2, p3, p2, salt, exported) + err = cstore.Import(n2, p3, p2, exported) assert.NotNil(err) } diff --git a/keys/cryptostore/storage_test.go b/keys/cryptostore/storage_test.go index 23931c294..6d475fdc9 100644 --- a/keys/cryptostore/storage_test.go +++ b/keys/cryptostore/storage_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" + crypto "github.com/tendermint/go-crypto" cmn "github.com/tendermint/tmlibs/common" - crypto "github.com/tendermint/go-crypto" keys "github.com/tendermint/go-crypto/keys" ) diff --git a/keys/storage/filestorage/main.go b/keys/storage/filestorage/main.go index 2bd4dcc1f..1f9702995 100644 --- a/keys/storage/filestorage/main.go +++ b/keys/storage/filestorage/main.go @@ -6,7 +6,6 @@ like standard ssh key storage. package filestorage import ( - "encoding/hex" "fmt" "io/ioutil" "os" @@ -14,13 +13,11 @@ import ( "strings" "github.com/pkg/errors" - crypto "github.com/tendermint/go-crypto" keys "github.com/tendermint/go-crypto/keys" ) const ( - // BlockType is the type of block. BlockType = "Tendermint Light Client" // PrivExt is the extension for private keys. @@ -33,7 +30,6 @@ const ( dirPerm = os.FileMode(0700) ) -// FileStore is a file-based key storage with tight permissions. type FileStore struct { keyDir string } @@ -44,11 +40,9 @@ type FileStore struct { // be created if it doesn't exist already. func New(dir string) FileStore { err := os.MkdirAll(dir, dirPerm) - if err != nil { panic(err) } - return FileStore{dir} } @@ -57,7 +51,7 @@ var _ keys.Storage = FileStore{} // Put creates two files, one with the public info as json, the other // with the (encoded) private key as gpg ascii-armor style -func (s FileStore) Put(name string, salt, key []byte, info keys.Info) error { +func (s FileStore) Put(name string, key []byte, info keys.Info) error { pub, priv := s.nameToPaths(name) // write public info @@ -67,22 +61,22 @@ func (s FileStore) Put(name string, salt, key []byte, info keys.Info) error { } // write private info - return write(priv, name, salt, key) + return write(priv, name, key) } // Get loads the info and (encoded) private key from the directory // It uses `name` to generate the filename, and returns an error if the // files don't exist or are in the incorrect format -func (s FileStore) Get(name string) (salt []byte, key []byte, info keys.Info, err error) { +func (s FileStore) Get(name string) ([]byte, keys.Info, error) { pub, priv := s.nameToPaths(name) - info, err = readInfo(pub) + info, err := readInfo(pub) if err != nil { - return nil, nil, info, err + return nil, info, err } - salt, key, _, err = read(priv) - return salt, key, info.Format(), err + key, _, err := read(priv) + return key, info.Format(), err } // List parses the key directory for public info and returns a list of @@ -121,117 +115,63 @@ func (s FileStore) List() (keys.Infos, error) { func (s FileStore) Delete(name string) error { pub, priv := s.nameToPaths(name) err := os.Remove(priv) - if err != nil { return errors.Wrap(err, "Deleting Private Key") } - err = os.Remove(pub) - return errors.Wrap(err, "Deleting Public Key") } func (s FileStore) nameToPaths(name string) (pub, priv string) { privName := fmt.Sprintf("%s.%s", name, PrivExt) pubName := fmt.Sprintf("%s.%s", name, PubExt) - return path.Join(s.keyDir, pubName), path.Join(s.keyDir, privName) } -func readInfo(path string) (info keys.Info, err error) { - f, err := os.Open(path) - if err != nil { - return info, errors.Wrap(err, "Reading data") - } - defer f.Close() - - d, err := ioutil.ReadAll(f) - if err != nil { - return info, errors.Wrap(err, "Reading data") - } +func writeInfo(path string, info keys.Info) error { + return write(path, info.Name, info.PubKey.Bytes()) +} - block, headers, key, err := crypto.DecodeArmor(string(d)) +func readInfo(path string) (info keys.Info, err error) { + var data []byte + data, info.Name, err = read(path) if err != nil { - return info, errors.Wrap(err, "Invalid Armor") + return } - - if block != BlockType { - return info, errors.Errorf("Unknown key type: %s", block) - } - - pk, _ := crypto.PubKeyFromBytes(key) - info.Name = headers["name"] + pk, err := crypto.PubKeyFromBytes(data) info.PubKey = pk - - return info, nil + return } -func read(path string) (salt, key []byte, name string, err error) { +func read(path string) ([]byte, string, error) { f, err := os.Open(path) if err != nil { - return nil, nil, "", errors.Wrap(err, "Reading data") + return nil, "", errors.Wrap(err, "Reading data") } defer f.Close() d, err := ioutil.ReadAll(f) if err != nil { - return nil, nil, "", errors.Wrap(err, "Reading data") + return nil, "", errors.Wrap(err, "Reading data") } - block, headers, key, err := crypto.DecodeArmor(string(d)) if err != nil { - return nil, nil, "", errors.Wrap(err, "Invalid Armor") + return nil, "", errors.Wrap(err, "Invalid Armor") } - if block != BlockType { - return nil, nil, "", errors.Errorf("Unknown key type: %s", block) - } - - if headers["kdf"] != "bcrypt" { - return nil, nil, "", errors.Errorf("Unrecognized KDF type: %v", headers["kdf"]) + return nil, "", errors.Errorf("Unknown key type: %s", block) } - - if headers["salt"] == "" { - return nil, nil, "", errors.Errorf("Missing salt bytes") - } - - salt, err = hex.DecodeString(headers["salt"]) - if err != nil { - return nil, nil, "", errors.Errorf("Error decoding salt: %v", err.Error()) - } - - return salt, key, headers["name"], nil + return key, headers["name"], nil } -func writeInfo(path string, info keys.Info) error { +func write(path, name string, key []byte) error { f, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, keyPerm) if err != nil { return errors.Wrap(err, "Writing data") } defer f.Close() - - headers := map[string]string{"name": info.Name} - text := crypto.EncodeArmor(BlockType, headers, info.PubKey.Bytes()) - _, err = f.WriteString(text) - - return errors.Wrap(err, "Writing data") -} - -func write(path, name string, salt, key []byte) error { - f, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, keyPerm) - if err != nil { - return errors.Wrap(err, "Writing data") - } - defer f.Close() - - headers := map[string]string{ - "name": name, - "kdf": "bcrypt", - "salt": fmt.Sprintf("%X", salt), - } - + headers := map[string]string{"name": name} text := crypto.EncodeArmor(BlockType, headers, key) _, err = f.WriteString(text) - return errors.Wrap(err, "Writing data") } diff --git a/keys/storage/filestorage/main_test.go b/keys/storage/filestorage/main_test.go index bed46ab1f..28c950c2c 100644 --- a/keys/storage/filestorage/main_test.go +++ b/keys/storage/filestorage/main_test.go @@ -22,7 +22,6 @@ func TestBasicCRUD(t *testing.T) { name := "bar" key := []byte("secret-key-here") - salt := []byte("salt-here") pubkey := crypto.GenPrivKeyEd25519().PubKey() info := keys.Info{ Name: name, @@ -30,7 +29,7 @@ func TestBasicCRUD(t *testing.T) { } // No data: Get and Delete return nothing - _, _, _, err = store.Get(name) + _, _, err = store.Get(name) assert.NotNil(err) err = store.Delete(name) assert.NotNil(err) @@ -40,14 +39,14 @@ func TestBasicCRUD(t *testing.T) { assert.Empty(l) // Putting the key in the store must work - err = store.Put(name, salt, key, info) + err = store.Put(name, key, info) assert.Nil(err) // But a second time is a failure - err = store.Put(name, salt, key, info) + err = store.Put(name, key, info) assert.NotNil(err) // Now, we can get and list properly - _, k, i, err := store.Get(name) + k, i, err := store.Get(name) require.Nil(err, "%+v", err) assert.Equal(key, k) assert.Equal(info.Name, i.Name) @@ -59,7 +58,7 @@ func TestBasicCRUD(t *testing.T) { assert.Equal(i, l[0]) // querying a non-existent key fails - _, _, _, err = store.Get("badname") + _, _, err = store.Get("badname") assert.NotNil(err) // We can only delete once @@ -69,7 +68,7 @@ func TestBasicCRUD(t *testing.T) { assert.NotNil(err) // and then Get and List don't work - _, _, _, err = store.Get(name) + _, _, err = store.Get(name) assert.NotNil(err) // List returns empty list l, err = store.List() diff --git a/keys/storage/memstorage/main.go b/keys/storage/memstorage/main.go index 516aa40b8..a988fe0ff 100644 --- a/keys/storage/memstorage/main.go +++ b/keys/storage/memstorage/main.go @@ -7,13 +7,11 @@ package memstorage import ( "github.com/pkg/errors" - keys "github.com/tendermint/go-crypto/keys" ) type data struct { info keys.Info - salt []byte key []byte } @@ -29,22 +27,22 @@ var _ keys.Storage = MemStore{} // Put adds the given key, returns an error if it another key // is already stored under this name -func (s MemStore) Put(name string, salt, key []byte, info keys.Info) error { +func (s MemStore) Put(name string, key []byte, info keys.Info) error { if _, ok := s[name]; ok { return errors.Errorf("Key named '%s' already exists", name) } - s[name] = data{info, salt, key} + s[name] = data{info, key} return nil } // Get returns the key stored under the name, or returns an error if not present -func (s MemStore) Get(name string) (salt, key []byte, info keys.Info, err error) { +func (s MemStore) Get(name string) ([]byte, keys.Info, error) { + var err error d, ok := s[name] if !ok { err = errors.Errorf("Key named '%s' doesn't exist", name) } - - return d.salt, d.key, d.info.Format(), err + return d.key, d.info.Format(), err } // List returns the public info of all keys in the MemStore in unsorted order diff --git a/keys/storage/memstorage/main_test.go b/keys/storage/memstorage/main_test.go index 01975df58..feccb387f 100644 --- a/keys/storage/memstorage/main_test.go +++ b/keys/storage/memstorage/main_test.go @@ -14,7 +14,6 @@ func TestBasicCRUD(t *testing.T) { name := "foo" key := []byte("secret-key-here") - salt := []byte("salt-here") pubkey := crypto.GenPrivKeyEd25519().PubKey() info := keys.Info{ Name: name, @@ -22,7 +21,7 @@ func TestBasicCRUD(t *testing.T) { } // No data: Get and Delete return nothing - _, _, _, err := store.Get(name) + _, _, err := store.Get(name) assert.NotNil(err) err = store.Delete(name) assert.NotNil(err) @@ -32,14 +31,14 @@ func TestBasicCRUD(t *testing.T) { assert.Empty(l) // Putting the key in the store must work - err = store.Put(name, salt, key, info) + err = store.Put(name, key, info) assert.Nil(err) // But a second time is a failure - err = store.Put(name, salt, key, info) + err = store.Put(name, key, info) assert.NotNil(err) // Now, we can get and list properly - _, k, i, err := store.Get(name) + k, i, err := store.Get(name) assert.Nil(err) assert.Equal(key, k) assert.Equal(info.Name, i.Name) @@ -51,7 +50,7 @@ func TestBasicCRUD(t *testing.T) { assert.Equal(i, l[0]) // querying a non-existent key fails - _, _, _, err = store.Get("badname") + _, _, err = store.Get("badname") assert.NotNil(err) // We can only delete once @@ -61,7 +60,7 @@ func TestBasicCRUD(t *testing.T) { assert.NotNil(err) // and then Get and List don't work - _, _, _, err = store.Get(name) + _, _, err = store.Get(name) assert.NotNil(err) // List returns empty list l, err = store.List() From 377d3c7e1122a882a760d005aca8be498ba628aa Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 27 Oct 2017 22:04:22 -0400 Subject: [PATCH 167/287] fix from revert --- keys/types.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/keys/types.go b/keys/types.go index 008a6f7ae..b3d3a374a 100644 --- a/keys/types.go +++ b/keys/types.go @@ -12,8 +12,8 @@ import ( // Storage has many implementation, based on security and sharing requirements // like disk-backed, mem-backed, vault, db, etc. type Storage interface { - Put(name string, salt []byte, key []byte, info Info) error - Get(name string) (salt []byte, key []byte, info Info, err error) + Put(name string, key []byte, info Info) error + Get(name string) (key []byte, info Info, err error) List() (Infos, error) Delete(name string) error } From d2b1a7096e72bbac6ef0256d7e92edd3c00f61b7 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 27 Oct 2017 22:05:44 -0400 Subject: [PATCH 168/287] changelog --- CHANGELOG.md | 10 ++++++++++ version.go | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64dc9998b..af0539300 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 0.4.1 (October 27, 2017) + +This release removes support for bcrypt as it was merged too soon without an upgrade plan +for existing keys. + +REVERTS THE FOLLOWING COMMITS: + +- Parameterize and lower bcrypt cost - dfc4cdd2d71513e4a9922d679c74f36357c4c862 +- Upgrade keys to use bcrypt with salts (#38) - 8e7f0e7701f92206679ad093d013b9b162427631 + ## 0.4.0 (October 27, 2017) BREAKING CHANGES: diff --git a/version.go b/version.go index 585d7e0d7..c39dd627c 100644 --- a/version.go +++ b/version.go @@ -1,3 +1,3 @@ package crypto -const Version = "0.4.0" +const Version = "0.4.1" From b0cf4b47571c93faa4eb67f2f17afbdf783f48ef Mon Sep 17 00:00:00 2001 From: Emmanuel Odeke Date: Sat, 28 Oct 2017 14:11:17 -0700 Subject: [PATCH 169/287] PubKeyFromBytes: return zero value PubKey on error Fixes https://github.com/tendermint/go-crypto/issues/48. This previously skewed up my fuzzing tests so ensure that on error we return the zero value PubKey. --- pub_key.go | 6 ++++-- pub_key_test.go | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/pub_key.go b/pub_key.go index 4d5c31b21..dfa012969 100644 --- a/pub_key.go +++ b/pub_key.go @@ -14,8 +14,10 @@ import ( ) func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { - err = wire.ReadBinaryBytes(pubKeyBytes, &pubKey) - return + if err := wire.ReadBinaryBytes(pubKeyBytes, &pubKey); err != nil { + return PubKey{}, err + } + return pubKey, nil } //---------------------------------------- diff --git a/pub_key_test.go b/pub_key_test.go index 31642233c..097c5ea3b 100644 --- a/pub_key_test.go +++ b/pub_key_test.go @@ -6,6 +6,7 @@ import ( "github.com/btcsuite/btcutil/base58" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) type keyData struct { @@ -39,3 +40,9 @@ func TestPubKeySecp256k1Address(t *testing.T) { assert.Equal(t, addr, addrB, "Expected addresses to match") } } + +func TestPubKeyInvalidDataProperReturnsEmpty(t *testing.T) { + pk, err := PubKeyFromBytes([]byte("foo")) + require.NotNil(t, err, "expecting a non-nil error") + require.True(t, pk.Empty(), "expecting an empty public key on error") +} From a2583e278334c35b170352e467a741166474b6da Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Wed, 1 Nov 2017 16:38:11 -0500 Subject: [PATCH 170/287] Draft of suggested changes --- keys/cryptostore/docs.go | 25 --- keys/cryptostore/enc_storage.go | 49 ----- keys/cryptostore/encoder.go | 60 ------ keys/cryptostore/encoder_test.go | 105 ----------- keys/cryptostore/generator.go | 88 --------- keys/cryptostore/storage_test.go | 48 ----- keys/{cryptostore/holder.go => keybase.go} | 84 +++++---- .../holder_test.go => keybase_test.go} | 0 keys/storage/filestorage/main.go | 177 ------------------ keys/storage/filestorage/main_test.go | 106 ----------- keys/storage/memstorage/main.go | 68 ------- keys/storage/memstorage/main_test.go | 69 ------- keys/types.go | 124 +----------- 13 files changed, 52 insertions(+), 951 deletions(-) delete mode 100644 keys/cryptostore/docs.go delete mode 100644 keys/cryptostore/enc_storage.go delete mode 100644 keys/cryptostore/encoder.go delete mode 100644 keys/cryptostore/encoder_test.go delete mode 100644 keys/cryptostore/generator.go delete mode 100644 keys/cryptostore/storage_test.go rename keys/{cryptostore/holder.go => keybase.go} (61%) rename keys/{cryptostore/holder_test.go => keybase_test.go} (100%) delete mode 100644 keys/storage/filestorage/main.go delete mode 100644 keys/storage/filestorage/main_test.go delete mode 100644 keys/storage/memstorage/main.go delete mode 100644 keys/storage/memstorage/main_test.go diff --git a/keys/cryptostore/docs.go b/keys/cryptostore/docs.go deleted file mode 100644 index 5c66fba2d..000000000 --- a/keys/cryptostore/docs.go +++ /dev/null @@ -1,25 +0,0 @@ -/* -package cryptostore maintains everything needed for doing public-key signing and -key management in software, based on the go-crypto library from tendermint. - -It is flexible, and allows the user to provide a key generation algorithm -(currently Ed25519 or Secp256k1), an encoder to passphrase-encrypt our keys -when storing them (currently SecretBox from NaCl), and a method to persist -the keys (currently FileStorage like ssh, or MemStorage for tests). -It should be relatively simple to write your own implementation of these -interfaces to match your specific security requirements. - -Note that the private keys are never exposed outside the package, and the -interface of Manager could be implemented by an HSM in the future for -enhanced security. It would require a completely different implementation -however. - -This Manager aims to implement Signer and KeyManager interfaces, along -with some extensions to allow importing/exporting keys and updating the -passphrase. - -Encoder and Generator implementations are currently in this package, -keys.Storage implementations exist as subpackages of -keys/storage -*/ -package cryptostore diff --git a/keys/cryptostore/enc_storage.go b/keys/cryptostore/enc_storage.go deleted file mode 100644 index daeb220b5..000000000 --- a/keys/cryptostore/enc_storage.go +++ /dev/null @@ -1,49 +0,0 @@ -package cryptostore - -import ( - crypto "github.com/tendermint/go-crypto" - keys "github.com/tendermint/go-crypto/keys" -) - -// encryptedStorage needs passphrase to get private keys -type encryptedStorage struct { - coder Encoder - store keys.Storage -} - -func (es encryptedStorage) Put(name, pass string, key crypto.PrivKey) error { - secret, err := es.coder.Encrypt(key, pass) - if err != nil { - return err - } - - ki := info(name, key) - return es.store.Put(name, secret, ki) -} - -func (es encryptedStorage) Get(name, pass string) (crypto.PrivKey, keys.Info, error) { - secret, info, err := es.store.Get(name) - if err != nil { - return crypto.PrivKey{}, info, err - } - key, err := es.coder.Decrypt(secret, pass) - return key, info, err -} - -func (es encryptedStorage) List() (keys.Infos, error) { - return es.store.List() -} - -func (es encryptedStorage) Delete(name string) error { - return es.store.Delete(name) -} - -// info hardcodes the encoding of keys -func info(name string, key crypto.PrivKey) keys.Info { - pub := key.PubKey() - return keys.Info{ - Name: name, - Address: pub.Address(), - PubKey: pub, - } -} diff --git a/keys/cryptostore/encoder.go b/keys/cryptostore/encoder.go deleted file mode 100644 index 31cbc2e54..000000000 --- a/keys/cryptostore/encoder.go +++ /dev/null @@ -1,60 +0,0 @@ -package cryptostore - -import ( - "github.com/pkg/errors" - crypto "github.com/tendermint/go-crypto" -) - -var ( - // SecretBox uses the algorithm from NaCL to store secrets securely - SecretBox Encoder = secretbox{} - // Noop doesn't do any encryption, should only be used in test code - Noop Encoder = noop{} -) - -// Encoder is used to encrypt any key with a passphrase for storage. -// -// This should use a well-designed symetric encryption algorithm -type Encoder interface { - Encrypt(key crypto.PrivKey, pass string) ([]byte, error) - Decrypt(data []byte, pass string) (crypto.PrivKey, error) -} - -func secret(passphrase string) []byte { - // TODO: Sha256(Bcrypt(passphrase)) - return crypto.Sha256([]byte(passphrase)) -} - -type secretbox struct{} - -func (e secretbox) Encrypt(key crypto.PrivKey, pass string) ([]byte, error) { - if pass == "" { - return key.Bytes(), nil - } - s := secret(pass) - cipher := crypto.EncryptSymmetric(key.Bytes(), s) - return cipher, nil -} - -func (e secretbox) Decrypt(data []byte, pass string) (key crypto.PrivKey, err error) { - private := data - if pass != "" { - s := secret(pass) - private, err = crypto.DecryptSymmetric(data, s) - if err != nil { - return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") - } - } - key, err = crypto.PrivKeyFromBytes(private) - return key, errors.Wrap(err, "Invalid Passphrase") -} - -type noop struct{} - -func (n noop) Encrypt(key crypto.PrivKey, pass string) ([]byte, error) { - return key.Bytes(), nil -} - -func (n noop) Decrypt(data []byte, pass string) (crypto.PrivKey, error) { - return crypto.PrivKeyFromBytes(data) -} diff --git a/keys/cryptostore/encoder_test.go b/keys/cryptostore/encoder_test.go deleted file mode 100644 index 9a0757b73..000000000 --- a/keys/cryptostore/encoder_test.go +++ /dev/null @@ -1,105 +0,0 @@ -package cryptostore_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - cmn "github.com/tendermint/tmlibs/common" - - "github.com/tendermint/go-crypto/keys/cryptostore" -) - -func TestNoopEncoder(t *testing.T) { - assert, require := assert.New(t), require.New(t) - noop := cryptostore.Noop - - key, err := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) - require.NoError(err) - key2, err := cryptostore.GenSecp256k1.Generate(cmn.RandBytes(16)) - require.NoError(err) - - b, err := noop.Encrypt(key, "encode") - require.Nil(err) - assert.NotEmpty(b) - - b2, err := noop.Encrypt(key2, "encode") - require.Nil(err) - assert.NotEmpty(b2) - assert.NotEqual(b, b2) - - // note the decode with a different password works - not secure! - pk, err := noop.Decrypt(b, "decode") - require.Nil(err) - require.NotNil(pk) - assert.Equal(key, pk) - - pk2, err := noop.Decrypt(b2, "kggugougp") - require.Nil(err) - require.NotNil(pk2) - assert.Equal(key2, pk2) -} - -func TestSecretBox(t *testing.T) { - assert, require := assert.New(t), require.New(t) - enc := cryptostore.SecretBox - - key, err := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) - require.NoError(err) - pass := "some-special-secret" - - b, err := enc.Encrypt(key, pass) - require.Nil(err) - assert.NotEmpty(b) - - // decoding with a different pass is an error - pk, err := enc.Decrypt(b, "decode") - require.NotNil(err) - require.True(pk.Empty()) - - // but decoding with the same passphrase gets us our key - pk, err = enc.Decrypt(b, pass) - require.Nil(err) - assert.Equal(key, pk) -} - -func TestSecretBoxNoPass(t *testing.T) { - assert, require := assert.New(t), require.New(t) - enc := cryptostore.SecretBox - - key, rerr := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) - require.NoError(rerr) - - cases := []struct { - encode string - decode string - valid bool - }{ - {"foo", "foo", true}, - {"foo", "food", false}, - {"", "", true}, - {"", "a", false}, - {"a", "", false}, - } - - for i, tc := range cases { - b, err := enc.Encrypt(key, tc.encode) - require.Nil(err, "%d: %+v", i, err) - assert.NotEmpty(b, "%d", i) - - pk, err := enc.Decrypt(b, tc.decode) - if tc.valid { - require.Nil(err, "%d: %+v", i, err) - assert.Equal(key, pk, "%d", i) - } else { - require.NotNil(err, "%d", i) - } - } - - // now let's make sure raw bytes also work... - b := key.Bytes() - pk, err := enc.Decrypt(b, "") - require.Nil(err, "%+v", err) - assert.Equal(key, pk) -} diff --git a/keys/cryptostore/generator.go b/keys/cryptostore/generator.go deleted file mode 100644 index 81277eda9..000000000 --- a/keys/cryptostore/generator.go +++ /dev/null @@ -1,88 +0,0 @@ -package cryptostore - -import ( - "github.com/pkg/errors" - crypto "github.com/tendermint/go-crypto" - "github.com/tendermint/go-crypto/nano" -) - -var ( - // GenEd25519 produces Ed25519 private keys - GenEd25519 Generator = GenFunc(genEd25519) - // GenSecp256k1 produces Secp256k1 private keys - GenSecp256k1 Generator = GenFunc(genSecp256) - // GenLedgerEd25519 used Ed25519 keys stored on nano ledger s with cosmos app - GenLedgerEd25519 Generator = GenFunc(genLedgerEd25519) -) - -// Generator determines the type of private key the keystore creates -type Generator interface { - Generate(secret []byte) (crypto.PrivKey, error) -} - -// GenFunc is a helper to transform a function into a Generator -type GenFunc func(secret []byte) (crypto.PrivKey, error) - -func (f GenFunc) Generate(secret []byte) (crypto.PrivKey, error) { - return f(secret) -} - -func genEd25519(secret []byte) (crypto.PrivKey, error) { - key := crypto.GenPrivKeyEd25519FromSecret(secret).Wrap() - return key, nil -} - -func genSecp256(secret []byte) (crypto.PrivKey, error) { - key := crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap() - return key, nil -} - -// secret is completely ignored for the ledger... -// just for interface compatibility -func genLedgerEd25519(secret []byte) (crypto.PrivKey, error) { - return nano.NewPrivKeyLedgerEd25519Ed25519() -} - -type genInvalidByte struct { - typ byte -} - -func (g genInvalidByte) Generate(secret []byte) (crypto.PrivKey, error) { - err := errors.Errorf("Cannot generate keys for algorithm: %X", g.typ) - return crypto.PrivKey{}, err -} - -type genInvalidAlgo struct { - algo string -} - -func (g genInvalidAlgo) Generate(secret []byte) (crypto.PrivKey, error) { - err := errors.Errorf("Cannot generate keys for algorithm: %s", g.algo) - return crypto.PrivKey{}, err -} - -func getGenerator(algo string) Generator { - switch algo { - case crypto.NameEd25519: - return GenEd25519 - case crypto.NameSecp256k1: - return GenSecp256k1 - case nano.NameLedgerEd25519: - return GenLedgerEd25519 - default: - return genInvalidAlgo{algo} - } -} - -func getGeneratorByType(typ byte) Generator { - switch typ { - case crypto.TypeEd25519: - return GenEd25519 - case crypto.TypeSecp256k1: - return GenSecp256k1 - case nano.TypeLedgerEd25519: - return GenLedgerEd25519 - default: - return genInvalidByte{typ} - } -} diff --git a/keys/cryptostore/storage_test.go b/keys/cryptostore/storage_test.go deleted file mode 100644 index 6d475fdc9..000000000 --- a/keys/cryptostore/storage_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package cryptostore - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - crypto "github.com/tendermint/go-crypto" - cmn "github.com/tendermint/tmlibs/common" - - keys "github.com/tendermint/go-crypto/keys" -) - -func TestSortKeys(t *testing.T) { - assert := assert.New(t) - - gen := func() crypto.PrivKey { - key, _ := GenEd25519.Generate(cmn.RandBytes(16)) - return key - } - assert.NotEqual(gen(), gen()) - - // alphabetical order is n3, n1, n2 - n1, n2, n3 := "john", "mike", "alice" - infos := keys.Infos{ - info(n1, gen()), - info(n2, gen()), - info(n3, gen()), - } - - // make sure they are initialized unsorted - assert.Equal(n1, infos[0].Name) - assert.Equal(n2, infos[1].Name) - assert.Equal(n3, infos[2].Name) - - // now they are sorted - infos.Sort() - assert.Equal(n3, infos[0].Name) - assert.Equal(n1, infos[1].Name) - assert.Equal(n2, infos[2].Name) - - // make sure info put some real data there... - assert.NotEmpty(infos[0].PubKey) - assert.NotEmpty(infos[0].PubKey.Address()) - assert.NotEmpty(infos[1].PubKey) - assert.NotEmpty(infos[1].PubKey.Address()) - assert.NotEqual(infos[0].PubKey, infos[1].PubKey) -} diff --git a/keys/cryptostore/holder.go b/keys/keybase.go similarity index 61% rename from keys/cryptostore/holder.go rename to keys/keybase.go index 7e89dda38..df75b08b7 100644 --- a/keys/cryptostore/holder.go +++ b/keys/keybase.go @@ -4,47 +4,49 @@ import ( "strings" crypto "github.com/tendermint/go-crypto" - keys "github.com/tendermint/go-crypto/keys" + dbm "github.com/tendermint/tmlibs/db" ) -// Manager combines encyption and storage implementation to provide +// XXX Lets use go-crypto/bcrypt and ascii encoding directly in here without +// further wrappers around a store or DB. +// Copy functions from: https://github.com/tendermint/mintkey/blob/master/cmd/mintkey/common.go +// +// dbKeybase combines encyption and storage implementation to provide // a full-featured key manager -type Manager struct { - es encryptedStorage - codec keys.Codec +type dbKeybase struct { + db dbm.DB + codec Codec } -func New(coder Encoder, store keys.Storage, codec keys.Codec) Manager { - return Manager{ +func New(db dbm.DB, codec Codec) dbKeybase { + return dbKeybase{ es: encryptedStorage{ + db: db, coder: coder, - store: store, }, codec: codec, } } -// assert Manager satisfies keys.Signer and keys.Manager interfaces -var _ keys.Signer = Manager{} -var _ keys.Manager = Manager{} +var _ Keybase = dbKeybase{} // Create adds a new key to the storage engine, returning error if // another key already stored under this name // // algo must be a supported go-crypto algorithm: ed25519, secp256k1 -func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error) { +func (kb dbKeybase) Create(name, passphrase, algo string) (Info, string, error) { // 128-bits are the all the randomness we can make use of secret := crypto.CRandBytes(16) gen := getGenerator(algo) key, err := gen.Generate(secret) if err != nil { - return keys.Info{}, "", err + return Info{}, "", err } - err = s.es.Put(name, passphrase, key) + err = kb.es.Put(name, passphrase, key) if err != nil { - return keys.Info{}, "", err + return Info{}, "", err } // we append the type byte to the serialized secret to help with recovery @@ -52,7 +54,7 @@ func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error typ := key.Bytes()[0] secret = append(secret, typ) - seed, err := s.codec.BytesToWords(secret) + seed, err := kb.codec.BytesToWords(secret) phrase := strings.Join(seed, " ") return info(name, key), phrase, err } @@ -63,11 +65,11 @@ func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error // it under name, protected by passphrase. // // Result similar to New(), except it doesn't return the seed again... -func (s Manager) Recover(name, passphrase, seedphrase string) (keys.Info, error) { +func (s dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { words := strings.Split(strings.TrimSpace(seedphrase), " ") - secret, err := s.codec.WordsToBytes(words) + secret, err := kb.codec.WordsToBytes(words) if err != nil { - return keys.Info{}, err + return Info{}, err } // secret is comprised of the actual secret with the type appended @@ -78,24 +80,24 @@ func (s Manager) Recover(name, passphrase, seedphrase string) (keys.Info, error) gen := getGeneratorByType(typ) key, err := gen.Generate(secret) if err != nil { - return keys.Info{}, err + return Info{}, err } // d00d, it worked! create the bugger.... - err = s.es.Put(name, passphrase, key) + err = kb.es.Put(name, passphrase, key) return info(name, key), err } // List loads the keys from the storage and enforces alphabetical order -func (s Manager) List() (keys.Infos, error) { - res, err := s.es.List() +func (s dbKeybase) List() (Infos, error) { + res, err := kb.es.List() res.Sort() return res, err } // Get returns the public information about one key -func (s Manager) Get(name string) (keys.Info, error) { - _, info, err := s.es.store.Get(name) +func (s dbKeybase) Get(name string) (Info, error) { + _, info, err := kb.es.store.Get(name) return info, err } @@ -103,8 +105,8 @@ func (s Manager) Get(name string) (keys.Info, error) { // this public key // // If no key for this name, or the passphrase doesn't match, returns an error -func (s Manager) Sign(name, passphrase string, tx keys.Signable) error { - key, _, err := s.es.Get(name, passphrase) +func (s dbKeybase) Sign(name, passphrase string, msg []byte) error { + key, _, err := kb.es.Get(name, passphrase) if err != nil { return err } @@ -115,55 +117,55 @@ func (s Manager) Sign(name, passphrase string, tx keys.Signable) error { // Export decodes the private key with the current password, encodes // it with a secure one-time password and generates a sequence that can be -// Imported by another Manager +// Imported by another dbKeybase // // This is designed to copy from one device to another, or provide backups // during version updates. -func (s Manager) Export(name, oldpass, transferpass string) ([]byte, error) { - key, _, err := s.es.Get(name, oldpass) +func (s dbKeybase) Export(name, oldpass, transferpass string) ([]byte, error) { + key, _, err := kb.es.Get(name, oldpass) if err != nil { return nil, err } - res, err := s.es.coder.Encrypt(key, transferpass) + res, err := kb.es.coder.Encrypt(key, transferpass) return res, err } // Import accepts bytes generated by Export along with the same transferpass // If they are valid, it stores the password under the given name with the // new passphrase. -func (s Manager) Import(name, newpass, transferpass string, data []byte) error { - key, err := s.es.coder.Decrypt(data, transferpass) +func (s dbKeybase) Import(name, newpass, transferpass string, data []byte) error { + key, err := kb.es.coder.Decrypt(data, transferpass) if err != nil { return err } - return s.es.Put(name, newpass, key) + return kb.es.Put(name, newpass, key) } // Delete removes key forever, but we must present the // proper passphrase before deleting it (for security) -func (s Manager) Delete(name, passphrase string) error { +func (s dbKeybase) Delete(name, passphrase string) error { // verify we have the proper password before deleting - _, _, err := s.es.Get(name, passphrase) + _, _, err := kb.es.Get(name, passphrase) if err != nil { return err } - return s.es.Delete(name) + return kb.es.Delete(name) } // Update changes the passphrase with which a already stored key is encoded. // // oldpass must be the current passphrase used for encoding, newpass will be // the only valid passphrase from this time forward -func (s Manager) Update(name, oldpass, newpass string) error { - key, _, err := s.es.Get(name, oldpass) +func (s dbKeybase) Update(name, oldpass, newpass string) error { + key, _, err := kb.es.Get(name, oldpass) if err != nil { return err } // we must delete first, as Putting over an existing name returns an error - s.Delete(name, oldpass) + kb.Delete(name, oldpass) - return s.es.Put(name, newpass, key) + return kb.es.Put(name, newpass, key) } diff --git a/keys/cryptostore/holder_test.go b/keys/keybase_test.go similarity index 100% rename from keys/cryptostore/holder_test.go rename to keys/keybase_test.go diff --git a/keys/storage/filestorage/main.go b/keys/storage/filestorage/main.go deleted file mode 100644 index 1f9702995..000000000 --- a/keys/storage/filestorage/main.go +++ /dev/null @@ -1,177 +0,0 @@ -/* -package filestorage provides a secure on-disk storage of private keys and -metadata. Security is enforced by file and directory permissions, much -like standard ssh key storage. -*/ -package filestorage - -import ( - "fmt" - "io/ioutil" - "os" - "path" - "strings" - - "github.com/pkg/errors" - crypto "github.com/tendermint/go-crypto" - keys "github.com/tendermint/go-crypto/keys" -) - -const ( - BlockType = "Tendermint Light Client" - - // PrivExt is the extension for private keys. - PrivExt = "tlc" - // PubExt is the extensions for public keys. - PubExt = "pub" - - keyPerm = os.FileMode(0600) - // pubPerm = os.FileMode(0644) - dirPerm = os.FileMode(0700) -) - -type FileStore struct { - keyDir string -} - -// New creates an instance of file-based key storage with tight permissions -// -// dir should be an absolute path of a directory owner by this user. It will -// be created if it doesn't exist already. -func New(dir string) FileStore { - err := os.MkdirAll(dir, dirPerm) - if err != nil { - panic(err) - } - return FileStore{dir} -} - -// assert FileStore satisfies keys.Storage -var _ keys.Storage = FileStore{} - -// Put creates two files, one with the public info as json, the other -// with the (encoded) private key as gpg ascii-armor style -func (s FileStore) Put(name string, key []byte, info keys.Info) error { - pub, priv := s.nameToPaths(name) - - // write public info - err := writeInfo(pub, info) - if err != nil { - return err - } - - // write private info - return write(priv, name, key) -} - -// Get loads the info and (encoded) private key from the directory -// It uses `name` to generate the filename, and returns an error if the -// files don't exist or are in the incorrect format -func (s FileStore) Get(name string) ([]byte, keys.Info, error) { - pub, priv := s.nameToPaths(name) - - info, err := readInfo(pub) - if err != nil { - return nil, info, err - } - - key, _, err := read(priv) - return key, info.Format(), err -} - -// List parses the key directory for public info and returns a list of -// Info for all keys located in this directory. -func (s FileStore) List() (keys.Infos, error) { - dir, err := os.Open(s.keyDir) - if err != nil { - return nil, errors.Wrap(err, "List Keys") - } - defer dir.Close() - - names, err := dir.Readdirnames(0) - if err != nil { - return nil, errors.Wrap(err, "List Keys") - } - - // filter names for .pub ending and load them one by one - // half the files is a good guess for pre-allocating the slice - infos := make([]keys.Info, 0, len(names)/2) - for _, name := range names { - if strings.HasSuffix(name, PubExt) { - p := path.Join(s.keyDir, name) - info, err := readInfo(p) - if err != nil { - return nil, err - } - infos = append(infos, info.Format()) - } - } - - return infos, nil -} - -// Delete permanently removes the public and private info for the named key -// The calling function should provide some security checks first. -func (s FileStore) Delete(name string) error { - pub, priv := s.nameToPaths(name) - err := os.Remove(priv) - if err != nil { - return errors.Wrap(err, "Deleting Private Key") - } - err = os.Remove(pub) - return errors.Wrap(err, "Deleting Public Key") -} - -func (s FileStore) nameToPaths(name string) (pub, priv string) { - privName := fmt.Sprintf("%s.%s", name, PrivExt) - pubName := fmt.Sprintf("%s.%s", name, PubExt) - return path.Join(s.keyDir, pubName), path.Join(s.keyDir, privName) -} - -func writeInfo(path string, info keys.Info) error { - return write(path, info.Name, info.PubKey.Bytes()) -} - -func readInfo(path string) (info keys.Info, err error) { - var data []byte - data, info.Name, err = read(path) - if err != nil { - return - } - pk, err := crypto.PubKeyFromBytes(data) - info.PubKey = pk - return -} - -func read(path string) ([]byte, string, error) { - f, err := os.Open(path) - if err != nil { - return nil, "", errors.Wrap(err, "Reading data") - } - defer f.Close() - - d, err := ioutil.ReadAll(f) - if err != nil { - return nil, "", errors.Wrap(err, "Reading data") - } - block, headers, key, err := crypto.DecodeArmor(string(d)) - if err != nil { - return nil, "", errors.Wrap(err, "Invalid Armor") - } - if block != BlockType { - return nil, "", errors.Errorf("Unknown key type: %s", block) - } - return key, headers["name"], nil -} - -func write(path, name string, key []byte) error { - f, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, keyPerm) - if err != nil { - return errors.Wrap(err, "Writing data") - } - defer f.Close() - headers := map[string]string{"name": name} - text := crypto.EncodeArmor(BlockType, headers, key) - _, err = f.WriteString(text) - return errors.Wrap(err, "Writing data") -} diff --git a/keys/storage/filestorage/main_test.go b/keys/storage/filestorage/main_test.go deleted file mode 100644 index 28c950c2c..000000000 --- a/keys/storage/filestorage/main_test.go +++ /dev/null @@ -1,106 +0,0 @@ -package filestorage - -import ( - "io/ioutil" - "os" - "path" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - crypto "github.com/tendermint/go-crypto" - keys "github.com/tendermint/go-crypto/keys" -) - -func TestBasicCRUD(t *testing.T) { - assert, require := assert.New(t), require.New(t) - - dir, err := ioutil.TempDir("", "filestorage-test") - assert.Nil(err) - defer os.RemoveAll(dir) - store := New(dir) - - name := "bar" - key := []byte("secret-key-here") - pubkey := crypto.GenPrivKeyEd25519().PubKey() - info := keys.Info{ - Name: name, - PubKey: pubkey.Wrap(), - } - - // No data: Get and Delete return nothing - _, _, err = store.Get(name) - assert.NotNil(err) - err = store.Delete(name) - assert.NotNil(err) - // List returns empty list - l, err := store.List() - assert.Nil(err) - assert.Empty(l) - - // Putting the key in the store must work - err = store.Put(name, key, info) - assert.Nil(err) - // But a second time is a failure - err = store.Put(name, key, info) - assert.NotNil(err) - - // Now, we can get and list properly - k, i, err := store.Get(name) - require.Nil(err, "%+v", err) - assert.Equal(key, k) - assert.Equal(info.Name, i.Name) - assert.Equal(info.PubKey, i.PubKey) - assert.NotEmpty(i.Address) - l, err = store.List() - require.Nil(err, "%+v", err) - assert.Equal(1, len(l)) - assert.Equal(i, l[0]) - - // querying a non-existent key fails - _, _, err = store.Get("badname") - assert.NotNil(err) - - // We can only delete once - err = store.Delete(name) - assert.Nil(err) - err = store.Delete(name) - assert.NotNil(err) - - // and then Get and List don't work - _, _, err = store.Get(name) - assert.NotNil(err) - // List returns empty list - l, err = store.List() - assert.Nil(err) - assert.Empty(l) -} - -func TestDirectoryHandling(t *testing.T) { - assert, require := assert.New(t), require.New(t) - - // prepare a temp dir and make sure it is not there - newDir := path.Join(os.TempDir(), "file-test-dir") - _, err := os.Open(newDir) - assert.True(os.IsNotExist(err)) - defer os.RemoveAll(newDir) - - // now, check with two levels deep.... - parentDir := path.Join(os.TempDir(), "missing-dir") - nestedDir := path.Join(parentDir, "lots", "of", "levels", "here") - _, err = os.Open(parentDir) - assert.True(os.IsNotExist(err)) - defer os.RemoveAll(parentDir) - - // create a new storage, and verify it creates the directory with good permissions - for _, dir := range []string{newDir, nestedDir, newDir} { - New(dir) - d, err := os.Open(dir) - require.Nil(err) - defer d.Close() - - stat, err := d.Stat() - require.Nil(err) - assert.Equal(dirPerm, stat.Mode()&os.ModePerm) - } -} diff --git a/keys/storage/memstorage/main.go b/keys/storage/memstorage/main.go deleted file mode 100644 index a988fe0ff..000000000 --- a/keys/storage/memstorage/main.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -package memstorage provides a simple in-memory key store designed for -use in test cases, particularly to isolate them from the filesystem, -concurrency, and cleanup issues. -*/ -package memstorage - -import ( - "github.com/pkg/errors" - keys "github.com/tendermint/go-crypto/keys" -) - -type data struct { - info keys.Info - key []byte -} - -type MemStore map[string]data - -// New creates an instance of file-based key storage with tight permissions -func New() MemStore { - return MemStore{} -} - -// assert MemStore satisfies keys.Storage -var _ keys.Storage = MemStore{} - -// Put adds the given key, returns an error if it another key -// is already stored under this name -func (s MemStore) Put(name string, key []byte, info keys.Info) error { - if _, ok := s[name]; ok { - return errors.Errorf("Key named '%s' already exists", name) - } - s[name] = data{info, key} - return nil -} - -// Get returns the key stored under the name, or returns an error if not present -func (s MemStore) Get(name string) ([]byte, keys.Info, error) { - var err error - d, ok := s[name] - if !ok { - err = errors.Errorf("Key named '%s' doesn't exist", name) - } - return d.key, d.info.Format(), err -} - -// List returns the public info of all keys in the MemStore in unsorted order -func (s MemStore) List() (keys.Infos, error) { - res := make([]keys.Info, len(s)) - i := 0 - for _, d := range s { - res[i] = d.info.Format() - i++ - } - return res, nil -} - -// Delete removes the named key from the MemStore, raising an error if it -// wasn't present yet. -func (s MemStore) Delete(name string) error { - _, ok := s[name] - if !ok { - return errors.Errorf("Key named '%s' doesn't exist", name) - } - delete(s, name) - return nil -} diff --git a/keys/storage/memstorage/main_test.go b/keys/storage/memstorage/main_test.go deleted file mode 100644 index feccb387f..000000000 --- a/keys/storage/memstorage/main_test.go +++ /dev/null @@ -1,69 +0,0 @@ -package memstorage - -import ( - "testing" - - "github.com/stretchr/testify/assert" - crypto "github.com/tendermint/go-crypto" - keys "github.com/tendermint/go-crypto/keys" -) - -func TestBasicCRUD(t *testing.T) { - assert := assert.New(t) - store := New() - - name := "foo" - key := []byte("secret-key-here") - pubkey := crypto.GenPrivKeyEd25519().PubKey() - info := keys.Info{ - Name: name, - PubKey: pubkey, - } - - // No data: Get and Delete return nothing - _, _, err := store.Get(name) - assert.NotNil(err) - err = store.Delete(name) - assert.NotNil(err) - // List returns empty list - l, err := store.List() - assert.Nil(err) - assert.Empty(l) - - // Putting the key in the store must work - err = store.Put(name, key, info) - assert.Nil(err) - // But a second time is a failure - err = store.Put(name, key, info) - assert.NotNil(err) - - // Now, we can get and list properly - k, i, err := store.Get(name) - assert.Nil(err) - assert.Equal(key, k) - assert.Equal(info.Name, i.Name) - assert.Equal(info.PubKey, i.PubKey) - assert.NotEmpty(i.Address) - l, err = store.List() - assert.Nil(err) - assert.Equal(1, len(l)) - assert.Equal(i, l[0]) - - // querying a non-existent key fails - _, _, err = store.Get("badname") - assert.NotNil(err) - - // We can only delete once - err = store.Delete(name) - assert.Nil(err) - err = store.Delete(name) - assert.NotNil(err) - - // and then Get and List don't work - _, _, err = store.Get(name) - assert.NotNil(err) - // List returns empty list - l, err = store.List() - assert.Nil(err) - assert.Empty(l) -} diff --git a/keys/types.go b/keys/types.go index b3d3a374a..534da0720 100644 --- a/keys/types.go +++ b/keys/types.go @@ -1,134 +1,28 @@ package keys import ( - "fmt" "sort" crypto "github.com/tendermint/go-crypto" - wire "github.com/tendermint/go-wire" data "github.com/tendermint/go-wire/data" ) -// Storage has many implementation, based on security and sharing requirements -// like disk-backed, mem-backed, vault, db, etc. -type Storage interface { - Put(name string, key []byte, info Info) error - Get(name string) (key []byte, info Info, err error) - List() (Infos, error) - Delete(name string) error -} - // Info is the public information about a key type Info struct { - Name string `json:"name"` - Address data.Bytes `json:"address"` - PubKey crypto.PubKey `json:"pubkey"` -} - -func (i *Info) Format() Info { - if !i.PubKey.Empty() { - i.Address = i.PubKey.Address() - } - return *i -} - -// Infos is a wrapper to allows alphabetical sorting of the keys -type Infos []Info - -func (k Infos) Len() int { return len(k) } -func (k Infos) Less(i, j int) bool { return k[i].Name < k[j].Name } -func (k Infos) Swap(i, j int) { k[i], k[j] = k[j], k[i] } -func (k Infos) Sort() { - if k != nil { - sort.Sort(k) - } -} - -// Signable represents any transaction we wish to send to tendermint core -// These methods allow us to sign arbitrary Tx with the KeyStore -type Signable interface { - // SignBytes is the immutable data, which needs to be signed - SignBytes() []byte - - // Sign will add a signature and pubkey. - // - // Depending on the Signable, one may be able to call this multiple times for multisig - // Returns error if called with invalid data or too many times - Sign(pubkey crypto.PubKey, sig crypto.Signature) error - - // Signers will return the public key(s) that signed if the signature - // is valid, or an error if there is any issue with the signature, - // including if there are no signatures - Signers() ([]crypto.PubKey, error) - - // TxBytes returns the transaction data as well as all signatures - // It should return an error if Sign was never called - TxBytes() ([]byte, error) -} - -// Signer allows one to use a keystore to sign transactions -type Signer interface { - Sign(name, passphrase string, tx Signable) error + Name string `json:"name"` + PubKey crypto.PubKey `json:"pubkey"` } -// Manager allows simple CRUD on a keystore, as an aid to signing -type Manager interface { - Signer - // Create also returns a seed phrase for cold-storage - Create(name, passphrase, algo string) (Info, string, error) - // Recover takes a seedphrase and loads in the private key +// Keybase allows simple CRUD on a keystore, as an aid to signing +type Keybase interface { + // Sign some bytes + Sign(name, passphrase string, msg []byte) (crypto.Signature, error) + // Create a new keypair + Create(name, passphrase, algo string) (_ Info, seedphrase string, _ error) + // Recover takes a seedphrase and loads in the key Recover(name, passphrase, seedphrase string) (Info, error) List() (Infos, error) Get(name string) (Info, error) Update(name, oldpass, newpass string) error Delete(name, passphrase string) error } - -/**** MockSignable allows us to view data ***/ - -// MockSignable lets us wrap arbitrary data with a go-crypto signature -type MockSignable struct { - Data []byte - PubKey crypto.PubKey - Signature crypto.Signature -} - -var _ Signable = &MockSignable{} - -// NewMockSignable sets the data to sign -func NewMockSignable(data []byte) *MockSignable { - return &MockSignable{Data: data} -} - -// TxBytes returns the full data with signatures -func (s *MockSignable) TxBytes() ([]byte, error) { - return wire.BinaryBytes(s), nil -} - -// SignBytes returns the original data passed into `NewSig` -func (s *MockSignable) SignBytes() []byte { - return s.Data -} - -// Sign will add a signature and pubkey. -// -// Depending on the Signable, one may be able to call this multiple times for multisig -// Returns error if called with invalid data or too many times -func (s *MockSignable) Sign(pubkey crypto.PubKey, sig crypto.Signature) error { - s.PubKey = pubkey - s.Signature = sig - return nil -} - -// Signers will return the public key(s) that signed if the signature -// is valid, or an error if there is any issue with the signature, -// including if there are no signatures -func (s *MockSignable) Signers() ([]crypto.PubKey, error) { - if s.PubKey.Empty() { - return nil, fmt.Errorf("no signers") - } - if !s.PubKey.VerifyBytes(s.SignBytes(), s.Signature) { - return nil, fmt.Errorf("invalid signature") - } - return []crypto.PubKey{s.PubKey}, nil -} From ac841a6124a65cdb4d51e857f2fa7e6bfe7e3cae Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 2 Nov 2017 14:09:59 -0500 Subject: [PATCH 171/287] Fixed imports --- glide.lock | 30 ++++++++++++++++++++++++----- glide.yaml | 7 +++++++ keys/keybase.go | 2 +- keys/keybase_test.go | 45 ++++++++++++++++++-------------------------- 4 files changed, 51 insertions(+), 33 deletions(-) diff --git a/glide.lock b/glide.lock index 096ec5c15..c1400b3f9 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 6e06a42eafe0aeff112cee86aef6b2cab0e2f62c2e6bfccfb629aa22f6b62773 -updated: 2017-10-27T18:45:18.350198941+02:00 +hash: 86d02329c537ccb46ccb062918f0cb9e839f2cf894dfd57223c3ea4de14266db +updated: 2017-11-02T14:09:11.208038182-05:00 imports: - name: github.com/btcsuite/btcd version: c7588cbf7690cd9f047a28efa2dcd8f2435a4e5e @@ -29,29 +29,49 @@ imports: version: 71201497bace774495daed26a3874fd339e0b538 - name: github.com/go-stack/stack version: 817915b46b97fd7bb80e8ab6b69f01a53ac3eebf +- name: github.com/golang/snappy + version: 553a641470496b2327abcac10b36396bd98e45c9 - name: github.com/howeyc/crc16 version: 96a97a1abb579c7ff1a8ffa77f2e72d1c314b57f +- name: github.com/jmhodges/levigo + version: c42d9e0ca023e2198120196f842701bb4c55d7b9 - name: github.com/kr/logfmt version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0 - name: github.com/pkg/errors version: 645ef00459ed84a119197bfb8d8205042c6df63d +- name: github.com/syndtr/goleveldb + version: b89cc31ef7977104127d34c1bd31ebd1a9db2199 + subpackages: + - leveldb + - leveldb/cache + - leveldb/comparer + - leveldb/errors + - leveldb/filter + - leveldb/iterator + - leveldb/journal + - leveldb/memdb + - leveldb/opt + - leveldb/storage + - leveldb/table + - leveldb/util - name: github.com/tendermint/ed25519 version: d8387025d2b9d158cf4efb07e7ebf814bcce2057 subpackages: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: 8ee84b5b2581530168daf66fc89c548d27403c57 + version: 2baffcb6b690057568bc90ef1d457efb150b979a subpackages: - data - data/base58 - name: github.com/tendermint/tmlibs - version: 092eb701c7276907cdbed258750e22ce895b6735 + version: d9525c0fb671204450b160807480e1263053fb20 subpackages: - common + - db - log - name: golang.org/x/crypto - version: edd5e9b0879d13ee6970a50153d85b8fec9f7686 + version: bd6f299fb381e4c3393d1c4b1f0b94f5e77650c8 subpackages: - bcrypt - blowfish diff --git a/glide.yaml b/glide.yaml index 2f3e72471..a0b6650fa 100644 --- a/glide.yaml +++ b/glide.yaml @@ -6,6 +6,13 @@ import: - package: github.com/btcsuite/btcutil subpackages: - base58 +- package: github.com/syndtr/goleveldb + subpackages: + - leveldb + - leveldb/errors + - leveldb/iterator + - leveldb/opt + - leveldb/util - package: github.com/tendermint/ed25519 subpackages: - extra25519 diff --git a/keys/keybase.go b/keys/keybase.go index df75b08b7..54827d3a9 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -1,4 +1,4 @@ -package cryptostore +package keys import ( "strings" diff --git a/keys/keybase_test.go b/keys/keybase_test.go index a9056f0de..a57284e9c 100644 --- a/keys/keybase_test.go +++ b/keys/keybase_test.go @@ -1,4 +1,4 @@ -package cryptostore_test +package keys_test import ( "bytes" @@ -10,11 +10,10 @@ import ( "github.com/stretchr/testify/require" cmn "github.com/tendermint/tmlibs/common" + dbm "github.com/tendermint/tmlibs/db" crypto "github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto/keys" - "github.com/tendermint/go-crypto/keys/cryptostore" - "github.com/tendermint/go-crypto/keys/storage/memstorage" "github.com/tendermint/go-crypto/nano" ) @@ -23,9 +22,8 @@ func TestKeyManagement(t *testing.T) { assert, require := assert.New(t), require.New(t) // make the storage with reasonable defaults - cstore := cryptostore.New( - cryptostore.SecretBox, - memstorage.New(), + cstore := keys.New( + dbm.NewMemDB(), keys.MustLoadCodec("english"), ) @@ -92,9 +90,8 @@ func TestSignVerify(t *testing.T) { assert, require := assert.New(t), require.New(t) // make the storage with reasonable defaults - cstore := cryptostore.New( - cryptostore.SecretBox, - memstorage.New(), + cstore := keys.New( + dbm.NewMemDB(), keys.MustLoadCodec("english"), ) algo := crypto.NameSecp256k1 @@ -164,9 +161,8 @@ func TestSignWithLedger(t *testing.T) { } // make the storage with reasonable defaults - cstore := cryptostore.New( - cryptostore.SecretBox, - memstorage.New(), + cstore := keys.New( + dbm.NewMemDB(), keys.MustLoadCodec("english"), ) n := "nano-s" @@ -206,7 +202,7 @@ func TestSignWithLedger(t *testing.T) { assert.False(key.VerifyBytes(d1, s2.Signature)) } -func assertPassword(assert *assert.Assertions, cstore cryptostore.Manager, name, pass, badpass string) { +func assertPassword(assert *assert.Assertions, cstore keys.KeyBase, name, pass, badpass string) { err := cstore.Update(name, badpass, pass) assert.NotNil(err) err = cstore.Update(name, pass, pass) @@ -218,13 +214,12 @@ func TestImportUnencrypted(t *testing.T) { require := require.New(t) // make the storage with reasonable defaults - cstore := cryptostore.New( - cryptostore.SecretBox, - memstorage.New(), + cstore := keys.New( + dbm.NewMemDB(), keys.MustLoadCodec("english"), ) - key, err := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) + key, err := keys.GenEd25519.Generate(cmn.RandBytes(16)) require.NoError(err) addr := key.PubKey().Address() @@ -246,9 +241,8 @@ func TestAdvancedKeyManagement(t *testing.T) { assert, require := assert.New(t), require.New(t) // make the storage with reasonable defaults - cstore := cryptostore.New( - cryptostore.SecretBox, - memstorage.New(), + cstore := keys.New( + dbm.NewMemDB(), keys.MustLoadCodec("english"), ) @@ -290,9 +284,8 @@ func TestSeedPhrase(t *testing.T) { assert, require := assert.New(t), require.New(t) // make the storage with reasonable defaults - cstore := cryptostore.New( - cryptostore.SecretBox, - memstorage.New(), + cstore := keys.New( + dbm.NewMemDB(), keys.MustLoadCodec("english"), ) @@ -322,10 +315,8 @@ func TestSeedPhrase(t *testing.T) { func ExampleNew() { // Select the encryption and storage for your cryptostore - cstore := cryptostore.New( - cryptostore.SecretBox, - // Note: use filestorage.New(dir) for real data - memstorage.New(), + cstore := keys.New( + dbm.NewMemDB(), keys.MustLoadCodec("english"), ) ed := crypto.NameEd25519 From 946c9c573e3615fec3473288832a84c4c85946e4 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 2 Nov 2017 16:31:29 -0500 Subject: [PATCH 172/287] Handle generating keys --- keys/keybase.go | 46 +++++++++++++++++++++++++++++++++++++--------- keys/types.go | 7 ++----- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/keys/keybase.go b/keys/keybase.go index 54827d3a9..bdffb9dce 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -3,8 +3,11 @@ package keys import ( "strings" + "github.com/pkg/errors" crypto "github.com/tendermint/go-crypto" dbm "github.com/tendermint/tmlibs/db" + + "github.com/tendermint/go-crypto/nano" ) // XXX Lets use go-crypto/bcrypt and ascii encoding directly in here without @@ -37,9 +40,7 @@ var _ Keybase = dbKeybase{} func (kb dbKeybase) Create(name, passphrase, algo string) (Info, string, error) { // 128-bits are the all the randomness we can make use of secret := crypto.CRandBytes(16) - gen := getGenerator(algo) - - key, err := gen.Generate(secret) + key, err := generate(algo, secret) if err != nil { return Info{}, "", err } @@ -77,8 +78,7 @@ func (s dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { l := len(secret) secret, typ := secret[:l-1], secret[l-1] - gen := getGeneratorByType(typ) - key, err := gen.Generate(secret) + key, err := generateByType(typ, secret) if err != nil { return Info{}, err } @@ -89,9 +89,9 @@ func (s dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { } // List loads the keys from the storage and enforces alphabetical order -func (s dbKeybase) List() (Infos, error) { - res, err := kb.es.List() - res.Sort() +func (s dbKeybase) List() ([]Info, error) { + res, err := s.es.List() + sort.SortSlice(res) return res, err } @@ -105,7 +105,7 @@ func (s dbKeybase) Get(name string) (Info, error) { // this public key // // If no key for this name, or the passphrase doesn't match, returns an error -func (s dbKeybase) Sign(name, passphrase string, msg []byte) error { +func (s dbKeybase) Sign(name, passphrase string, msg []byte) (crypto.Signature, crypto.PubKey, error) { key, _, err := kb.es.Get(name, passphrase) if err != nil { return err @@ -169,3 +169,31 @@ func (s dbKeybase) Update(name, oldpass, newpass string) error { return kb.es.Put(name, newpass, key) } + +func generate(algo string, secret []byte) (crypto.PrivKey, error) { + switch algo { + case crypto.NameEd25519: + return crypto.GenPrivKeyEd25519FromSecret(secret).Wrap(), nil + case crypto.NameSecp256k1: + return crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap(), nil + case nano.NameLedgerEd25519: + return nano.NewPrivKeyLedgerEd25519Ed25519() + default: + err := errors.Errorf("Cannot generate keys for algorithm: %s", algo) + return crypto.PrivKey{}, err + } +} + +func generateByType(typ byte, secret []byte) (crypto.PrivKey, error) { + switch typ { + case crypto.TypeEd25519: + return generate(crypto.NameEd25519, secret) + case crypto.TypeSecp256k1: + return generate(crypto.NameSecp256k1, secret) + case nano.TypeLedgerEd25519: + return generate(nano.NameLedgerEd25519, secret) + default: + err := errors.Errorf("Cannot generate keys for algorithm: %X", typ) + return crypto.PrivKey{}, err + } +} diff --git a/keys/types.go b/keys/types.go index 534da0720..110cd3ded 100644 --- a/keys/types.go +++ b/keys/types.go @@ -1,10 +1,7 @@ package keys import ( - "sort" - crypto "github.com/tendermint/go-crypto" - data "github.com/tendermint/go-wire/data" ) // Info is the public information about a key @@ -16,12 +13,12 @@ type Info struct { // Keybase allows simple CRUD on a keystore, as an aid to signing type Keybase interface { // Sign some bytes - Sign(name, passphrase string, msg []byte) (crypto.Signature, error) + Sign(name, passphrase string, msg []byte) (crypto.Signature, crypto.PubKey, error) // Create a new keypair Create(name, passphrase, algo string) (_ Info, seedphrase string, _ error) // Recover takes a seedphrase and loads in the key Recover(name, passphrase, seedphrase string) (Info, error) - List() (Infos, error) + List() ([]Info, error) Get(name string) (Info, error) Update(name, oldpass, newpass string) error Delete(name, passphrase string) error From 9ef978c5ecb32c22db58a91c46f78239c7a8c588 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 2 Nov 2017 16:46:10 -0500 Subject: [PATCH 173/287] Fix errors except for es missing --- keys/keybase.go | 59 +++++++++++++++++++++++++++++++++---------------- keys/types.go | 7 ++++++ 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/keys/keybase.go b/keys/keybase.go index bdffb9dce..5fa32635e 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -1,6 +1,7 @@ package keys import ( + "sort" "strings" "github.com/pkg/errors" @@ -23,10 +24,7 @@ type dbKeybase struct { func New(db dbm.DB, codec Codec) dbKeybase { return dbKeybase{ - es: encryptedStorage{ - db: db, - coder: coder, - }, + db: db, codec: codec, } } @@ -66,7 +64,7 @@ func (kb dbKeybase) Create(name, passphrase, algo string) (Info, string, error) // it under name, protected by passphrase. // // Result similar to New(), except it doesn't return the seed again... -func (s dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { +func (kb dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { words := strings.Split(strings.TrimSpace(seedphrase), " ") secret, err := kb.codec.WordsToBytes(words) if err != nil { @@ -89,14 +87,14 @@ func (s dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { } // List loads the keys from the storage and enforces alphabetical order -func (s dbKeybase) List() ([]Info, error) { - res, err := s.es.List() - sort.SortSlice(res) +func (kb dbKeybase) List() ([]Info, error) { + res, err := kb.es.List() + sort.Slice(res, func(a, b int) bool { return res[a].Name < res[b].Name }) return res, err } // Get returns the public information about one key -func (s dbKeybase) Get(name string) (Info, error) { +func (kb dbKeybase) Get(name string) (Info, error) { _, info, err := kb.es.store.Get(name) return info, err } @@ -105,14 +103,15 @@ func (s dbKeybase) Get(name string) (Info, error) { // this public key // // If no key for this name, or the passphrase doesn't match, returns an error -func (s dbKeybase) Sign(name, passphrase string, msg []byte) (crypto.Signature, crypto.PubKey, error) { - key, _, err := kb.es.Get(name, passphrase) +func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signature, pk crypto.PubKey, err error) { + var key crypto.PrivKey + key, _, err = kb.es.Get(name, passphrase) if err != nil { - return err + return } - sig := key.Sign(tx.SignBytes()) - pubkey := key.PubKey() - return tx.Sign(pubkey, sig) + sig = key.Sign(msg) + pk = key.PubKey() + return } // Export decodes the private key with the current password, encodes @@ -121,7 +120,7 @@ func (s dbKeybase) Sign(name, passphrase string, msg []byte) (crypto.Signature, // // This is designed to copy from one device to another, or provide backups // during version updates. -func (s dbKeybase) Export(name, oldpass, transferpass string) ([]byte, error) { +func (kb dbKeybase) Export(name, oldpass, transferpass string) ([]byte, error) { key, _, err := kb.es.Get(name, oldpass) if err != nil { return nil, err @@ -134,7 +133,7 @@ func (s dbKeybase) Export(name, oldpass, transferpass string) ([]byte, error) { // Import accepts bytes generated by Export along with the same transferpass // If they are valid, it stores the password under the given name with the // new passphrase. -func (s dbKeybase) Import(name, newpass, transferpass string, data []byte) error { +func (kb dbKeybase) Import(name, newpass, transferpass string, data []byte) error { key, err := kb.es.coder.Decrypt(data, transferpass) if err != nil { return err @@ -145,7 +144,7 @@ func (s dbKeybase) Import(name, newpass, transferpass string, data []byte) error // Delete removes key forever, but we must present the // proper passphrase before deleting it (for security) -func (s dbKeybase) Delete(name, passphrase string) error { +func (kb dbKeybase) Delete(name, passphrase string) error { // verify we have the proper password before deleting _, _, err := kb.es.Get(name, passphrase) if err != nil { @@ -158,7 +157,7 @@ func (s dbKeybase) Delete(name, passphrase string) error { // // oldpass must be the current passphrase used for encoding, newpass will be // the only valid passphrase from this time forward -func (s dbKeybase) Update(name, oldpass, newpass string) error { +func (kb dbKeybase) Update(name, oldpass, newpass string) error { key, _, err := kb.es.Get(name, oldpass) if err != nil { return err @@ -197,3 +196,25 @@ func generateByType(typ byte, secret []byte) (crypto.PrivKey, error) { return crypto.PrivKey{}, err } } + +func encrypt(key crypto.PrivKey, pass string) ([]byte, error) { + if pass == "" { + return key.Bytes(), nil + } + s := secret(pass) + cipher := crypto.EncryptSymmetric(key.Bytes(), s) + return cipher, nil +} + +func decrypt(data []byte, pass string) (key crypto.PrivKey, err error) { + private := data + if pass != "" { + s := secret(pass) + private, err = crypto.DecryptSymmetric(data, s) + if err != nil { + return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") + } + } + key, err = crypto.PrivKeyFromBytes(private) + return key, errors.Wrap(err, "Invalid Passphrase") +} diff --git a/keys/types.go b/keys/types.go index 110cd3ded..b126f7267 100644 --- a/keys/types.go +++ b/keys/types.go @@ -10,6 +10,13 @@ type Info struct { PubKey crypto.PubKey `json:"pubkey"` } +func info(name string, privKey crypto.PrivKey) Info { + return Info{ + Name: name, + PubKey: privKey.PubKey(), + } +} + // Keybase allows simple CRUD on a keystore, as an aid to signing type Keybase interface { // Sign some bytes From 4173d1031e6a7361392fb80e46f0cc5469cb4499 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 2 Nov 2017 18:32:12 -0500 Subject: [PATCH 174/287] go build compiles --- keys/keybase.go | 117 +++++++++++++++++++++++++++++------------------- keys/mintkey.go | 73 ++++++++++++++++++++++++++++++ keys/types.go | 11 +++++ 3 files changed, 156 insertions(+), 45 deletions(-) create mode 100644 keys/mintkey.go diff --git a/keys/keybase.go b/keys/keybase.go index 5fa32635e..00de1ad55 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -1,7 +1,7 @@ package keys import ( - "sort" + "fmt" "strings" "github.com/pkg/errors" @@ -43,10 +43,7 @@ func (kb dbKeybase) Create(name, passphrase, algo string) (Info, string, error) return Info{}, "", err } - err = kb.es.Put(name, passphrase, key) - if err != nil { - return Info{}, "", err - } + public := kb.writeKey(key, name, passphrase) // we append the type byte to the serialized secret to help with recovery // ie [secret] = [secret] + [type] @@ -55,7 +52,7 @@ func (kb dbKeybase) Create(name, passphrase, algo string) (Info, string, error) seed, err := kb.codec.BytesToWords(secret) phrase := strings.Join(seed, " ") - return info(name, key), phrase, err + return public, phrase, err } // Recover takes a seed phrase and tries to recover the private key. @@ -82,21 +79,31 @@ func (kb dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { } // d00d, it worked! create the bugger.... - err = kb.es.Put(name, passphrase, key) - return info(name, key), err + public := kb.writeKey(key, name, passphrase) + return public, err } // List loads the keys from the storage and enforces alphabetical order func (kb dbKeybase) List() ([]Info, error) { - res, err := kb.es.List() - sort.Slice(res, func(a, b int) bool { return res[a].Name < res[b].Name }) - return res, err + var res []Info + var more = true + for iter := kb.db.Iterator(); more; more = iter.Next() { + key := iter.Key() + if isPub(key) { + info, err := readInfo(iter.Value()) + if err != nil { + return nil, err + } + res = append(res, info) + } + } + return res, nil } // Get returns the public information about one key func (kb dbKeybase) Get(name string) (Info, error) { - _, info, err := kb.es.store.Get(name) - return info, err + bs := kb.db.Get(pubName(name)) + return readInfo(bs) } // Sign will modify the Signable in order to attach a valid signature with @@ -105,10 +112,12 @@ func (kb dbKeybase) Get(name string) (Info, error) { // If no key for this name, or the passphrase doesn't match, returns an error func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signature, pk crypto.PubKey, err error) { var key crypto.PrivKey - key, _, err = kb.es.Get(name, passphrase) + bs := kb.db.Get(privName(name)) + key, err = unarmorDecryptPrivKey(string(bs), passphrase) if err != nil { return } + sig = key.Sign(msg) pk = key.PubKey() return @@ -121,36 +130,49 @@ func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signat // This is designed to copy from one device to another, or provide backups // during version updates. func (kb dbKeybase) Export(name, oldpass, transferpass string) ([]byte, error) { - key, _, err := kb.es.Get(name, oldpass) + bs := kb.db.Get(privName(name)) + key, err := unarmorDecryptPrivKey(string(bs), oldpass) if err != nil { return nil, err } - res, err := kb.es.coder.Encrypt(key, transferpass) - return res, err + if transferpass == "" { + return key.Bytes(), nil + } + res := encryptArmorPrivKey(key, transferpass) + return []byte(res), nil } // Import accepts bytes generated by Export along with the same transferpass // If they are valid, it stores the password under the given name with the // new passphrase. -func (kb dbKeybase) Import(name, newpass, transferpass string, data []byte) error { - key, err := kb.es.coder.Decrypt(data, transferpass) +func (kb dbKeybase) Import(name, newpass, transferpass string, data []byte) (err error) { + var key crypto.PrivKey + if transferpass == "" { + key, err = crypto.PrivKeyFromBytes(data) + } else { + key, err = unarmorDecryptPrivKey(string(data), transferpass) + } if err != nil { return err } - return kb.es.Put(name, newpass, key) + kb.writeKey(key, name, newpass) + return nil } // Delete removes key forever, but we must present the // proper passphrase before deleting it (for security) func (kb dbKeybase) Delete(name, passphrase string) error { // verify we have the proper password before deleting - _, _, err := kb.es.Get(name, passphrase) + bs := kb.db.Get(privName(name)) + _, err := unarmorDecryptPrivKey(string(bs), passphrase) if err != nil { return err } - return kb.es.Delete(name) + kb.db.DeleteSync(pubName(name)) + kb.db.DeleteSync(privName(name)) + return nil } // Update changes the passphrase with which a already stored key is encoded. @@ -158,15 +180,30 @@ func (kb dbKeybase) Delete(name, passphrase string) error { // oldpass must be the current passphrase used for encoding, newpass will be // the only valid passphrase from this time forward func (kb dbKeybase) Update(name, oldpass, newpass string) error { - key, _, err := kb.es.Get(name, oldpass) + bs := kb.db.Get(privName(name)) + key, err := unarmorDecryptPrivKey(string(bs), oldpass) if err != nil { return err } // we must delete first, as Putting over an existing name returns an error - kb.Delete(name, oldpass) + kb.db.DeleteSync(pubName(name)) + kb.db.DeleteSync(privName(name)) + kb.writeKey(key, name, newpass) + return nil +} - return kb.es.Put(name, newpass, key) +func (kb dbKeybase) writeKey(priv crypto.PrivKey, name, passphrase string) Info { + // generate the public bytes + public := info(name, priv) + // generate the encrypted privkey + private := encryptArmorPrivKey(priv, passphrase) + + // write them both + kb.db.SetSync(pubName(name), public.bytes()) + kb.db.SetSync(privName(name), []byte(private)) + + return public } func generate(algo string, secret []byte) (crypto.PrivKey, error) { @@ -197,24 +234,14 @@ func generateByType(typ byte, secret []byte) (crypto.PrivKey, error) { } } -func encrypt(key crypto.PrivKey, pass string) ([]byte, error) { - if pass == "" { - return key.Bytes(), nil - } - s := secret(pass) - cipher := crypto.EncryptSymmetric(key.Bytes(), s) - return cipher, nil -} - -func decrypt(data []byte, pass string) (key crypto.PrivKey, err error) { - private := data - if pass != "" { - s := secret(pass) - private, err = crypto.DecryptSymmetric(data, s) - if err != nil { - return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") - } - } - key, err = crypto.PrivKeyFromBytes(private) - return key, errors.Wrap(err, "Invalid Passphrase") +func pubName(name string) []byte { + return []byte(fmt.Sprintf("%s.pub", name)) +} + +func privName(name string) []byte { + return []byte(fmt.Sprintf("%s.priv", name)) +} + +func isPub(name []byte) bool { + return strings.HasSuffix(string(name), ".pub") } diff --git a/keys/mintkey.go b/keys/mintkey.go new file mode 100644 index 000000000..c948848be --- /dev/null +++ b/keys/mintkey.go @@ -0,0 +1,73 @@ +package keys + +import ( + "encoding/hex" + "fmt" + + cmn "github.com/tendermint/tmlibs/common" + + "github.com/tendermint/go-crypto" + "github.com/tendermint/go-crypto/bcrypt" +) + +const ( + blockTypePrivKey = "TENDERMINT PRIVATE KEY" +) + +func encryptArmorPrivKey(privKey crypto.PrivKey, passphrase string) string { + saltBytes, encBytes := encryptPrivKey(privKey, passphrase) + header := map[string]string{ + "kdf": "bcrypt", + "salt": fmt.Sprintf("%X", saltBytes), + } + armorStr := crypto.EncodeArmor(blockTypePrivKey, header, encBytes) + return armorStr +} + +func unarmorDecryptPrivKey(armorStr string, passphrase string) (crypto.PrivKey, error) { + var privKey crypto.PrivKey + blockType, header, encBytes, err := crypto.DecodeArmor(armorStr) + if err != nil { + return privKey, err + } + if blockType != blockTypePrivKey { + return privKey, fmt.Errorf("Unrecognized armor type: %v", blockType) + } + if header["kdf"] != "bcrypt" { + return privKey, fmt.Errorf("Unrecognized KDF type: %v", header["KDF"]) + } + if header["salt"] == "" { + return privKey, fmt.Errorf("Missing salt bytes") + } + saltBytes, err := hex.DecodeString(header["salt"]) + if err != nil { + return privKey, fmt.Errorf("Error decoding salt: %v", err.Error()) + } + privKey, err = decryptPrivKey(saltBytes, encBytes, passphrase) + return privKey, err +} + +func encryptPrivKey(privKey crypto.PrivKey, passphrase string) (saltBytes []byte, encBytes []byte) { + saltBytes = crypto.CRandBytes(16) + key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 12) // TODO parameterize. 12 is good today (2016) + if err != nil { + cmn.Exit("Error generating bcrypt key from passphrase: " + err.Error()) + } + key = crypto.Sha256(key) // Get 32 bytes + privKeyBytes := privKey.Bytes() + return saltBytes, crypto.EncryptSymmetric(privKeyBytes, key) +} + +func decryptPrivKey(saltBytes []byte, encBytes []byte, passphrase string) (privKey crypto.PrivKey, err error) { + key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 12) // TODO parameterize. 12 is good today (2016) + if err != nil { + cmn.Exit("Error generating bcrypt key from passphrase: " + err.Error()) + } + key = crypto.Sha256(key) // Get 32 bytes + privKeyBytes, err := crypto.DecryptSymmetric(encBytes, key) + if err != nil { + return privKey, err + } + privKey, err = crypto.PrivKeyFromBytes(privKeyBytes) + return privKey, err +} diff --git a/keys/types.go b/keys/types.go index b126f7267..4c546cca7 100644 --- a/keys/types.go +++ b/keys/types.go @@ -1,6 +1,8 @@ package keys import ( + wire "github.com/tendermint/go-wire" + crypto "github.com/tendermint/go-crypto" ) @@ -10,6 +12,15 @@ type Info struct { PubKey crypto.PubKey `json:"pubkey"` } +func (i Info) bytes() []byte { + return wire.BinaryBytes(i) +} + +func readInfo(bs []byte) (info Info, err error) { + err = wire.ReadBinaryBytes(bs, &info) + return +} + func info(name string, privKey crypto.PrivKey) Info { return Info{ Name: name, From 2d4544d6ce40d3a26e4f9ca3edb19ffae21889db Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 2 Nov 2017 18:45:37 -0500 Subject: [PATCH 175/287] Tests compile --- keys/keybase_test.go | 74 ++++++++++++++++++++++---------------------- keys/types.go | 5 +++ 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/keys/keybase_test.go b/keys/keybase_test.go index a57284e9c..bb6602b48 100644 --- a/keys/keybase_test.go +++ b/keys/keybase_test.go @@ -1,7 +1,6 @@ package keys_test import ( - "bytes" "fmt" "os" "testing" @@ -111,18 +110,21 @@ func TestSignVerify(t *testing.T) { d2 := []byte("some other important info!") // try signing both data with both keys... - s11 := keys.NewMockSignable(d1) - err = cstore.Sign(n1, p1, s11) + s11, pub1, err := cstore.Sign(n1, p1, d1) require.Nil(err) - s12 := keys.NewMockSignable(d2) - err = cstore.Sign(n1, p1, s12) + require.Equal(i1.PubKey, pub1) + + s12, pub1, err := cstore.Sign(n1, p1, d2) require.Nil(err) - s21 := keys.NewMockSignable(d1) - err = cstore.Sign(n2, p2, s21) + require.Equal(i1.PubKey, pub1) + + s21, pub2, err := cstore.Sign(n2, p2, d1) require.Nil(err) - s22 := keys.NewMockSignable(d2) - err = cstore.Sign(n2, p2, s22) + require.Equal(i2.PubKey, pub2) + + s22, pub2, err := cstore.Sign(n2, p2, d2) require.Nil(err) + require.Equal(i2.PubKey, pub2) // let's try to validate and make sure it only works when everything is proper cases := []struct { @@ -132,15 +134,15 @@ func TestSignVerify(t *testing.T) { valid bool }{ // proper matches - {i1.PubKey, d1, s11.Signature, true}, + {i1.PubKey, d1, s11, true}, // change data, pubkey, or signature leads to fail - {i1.PubKey, d2, s11.Signature, false}, - {i2.PubKey, d1, s11.Signature, false}, - {i1.PubKey, d1, s21.Signature, false}, + {i1.PubKey, d2, s11, false}, + {i2.PubKey, d1, s11, false}, + {i1.PubKey, d1, s21, false}, // make sure other successes - {i1.PubKey, d2, s12.Signature, true}, - {i2.PubKey, d1, s21.Signature, true}, - {i2.PubKey, d2, s22.Signature, true}, + {i1.PubKey, d2, s12, true}, + {i2.PubKey, d1, s21, true}, + {i2.PubKey, d2, s22, true}, } for i, tc := range cases { @@ -188,21 +190,22 @@ func TestSignWithLedger(t *testing.T) { d2 := []byte("please turn on the app") // try signing both data with the ledger... - s1 := keys.NewMockSignable(d1) - err = cstore.Sign(n, p, s1) + s1, pub, err := cstore.Sign(n, p, d1) require.Nil(err) - s2 := keys.NewMockSignable(d2) - err = cstore.Sign(n, p, s2) + require.Equal(info.PubKey, pub) + + s2, pub, err := cstore.Sign(n, p, d2) require.Nil(err) + require.Equal(info.PubKey, pub) // now, let's check those signatures work - assert.True(key.VerifyBytes(d1, s1.Signature)) - assert.True(key.VerifyBytes(d2, s2.Signature)) + assert.True(key.VerifyBytes(d1, s1)) + assert.True(key.VerifyBytes(d2, s2)) // and mismatched signatures don't - assert.False(key.VerifyBytes(d1, s2.Signature)) + assert.False(key.VerifyBytes(d1, s2)) } -func assertPassword(assert *assert.Assertions, cstore keys.KeyBase, name, pass, badpass string) { +func assertPassword(assert *assert.Assertions, cstore keys.Keybase, name, pass, badpass string) { err := cstore.Update(name, badpass, pass) assert.NotNil(err) err = cstore.Update(name, pass, pass) @@ -219,21 +222,20 @@ func TestImportUnencrypted(t *testing.T) { keys.MustLoadCodec("english"), ) - key, err := keys.GenEd25519.Generate(cmn.RandBytes(16)) - require.NoError(err) + key := crypto.GenPrivKeyEd25519FromSecret(cmn.RandBytes(16)).Wrap() addr := key.PubKey().Address() name := "john" pass := "top-secret" // import raw bytes - err = cstore.Import(name, pass, "", key.Bytes()) + err := cstore.Import(name, pass, "", key.Bytes()) require.Nil(err, "%+v", err) // make sure the address matches info, err := cstore.Get(name) require.Nil(err, "%+v", err) - require.EqualValues(addr, info.Address) + require.EqualValues(addr, info.Address()) } // TestAdvancedKeyManagement verifies update, import, export functionality @@ -309,7 +311,7 @@ func TestSeedPhrase(t *testing.T) { newInfo, err := cstore.Recover(n2, p2, seed) require.Nil(err, "%+v", err) assert.Equal(n2, newInfo.Name) - assert.Equal(info.Address, newInfo.Address) + assert.Equal(info.Address(), newInfo.Address()) assert.Equal(info.PubKey, newInfo.PubKey) } @@ -339,8 +341,8 @@ func ExampleNew() { } // We need to use passphrase to generate a signature - tx := keys.NewMockSignable([]byte("deadbeef")) - err = cstore.Sign("Bob", "friend", tx) + tx := []byte("deadbeef") + sig, pub, err := cstore.Sign("Bob", "friend", tx) if err != nil { fmt.Println("don't accept real passphrase") } @@ -351,13 +353,11 @@ func ExampleNew() { fmt.Println("Get and Create return different keys") } - sigs, err := tx.Signers() - if err != nil { - fmt.Println("badly signed") - } else if bytes.Equal(sigs[0].Bytes(), binfo.PubKey.Bytes()) { + if pub.Equals(binfo.PubKey) { fmt.Println("signed by Bob") - } else { - fmt.Println("signed by someone else") + } + if !pub.VerifyBytes(tx, sig) { + fmt.Println("invalid signature") } // Output: diff --git a/keys/types.go b/keys/types.go index 4c546cca7..541234b37 100644 --- a/keys/types.go +++ b/keys/types.go @@ -12,6 +12,11 @@ type Info struct { PubKey crypto.PubKey `json:"pubkey"` } +// Address is a helper function to calculate the address from the pubkey +func (i Info) Address() []byte { + return i.PubKey.Address() +} + func (i Info) bytes() []byte { return wire.BinaryBytes(i) } From 9d78be41b5826cc5e8d52f214856c7bd55d900fe Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 13 Nov 2017 14:41:00 +0100 Subject: [PATCH 176/287] Update tmlibs to sdk-develop, fix broken test --- glide.lock | 12 ++++++------ glide.yaml | 2 +- keys/keybase.go | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/glide.lock b/glide.lock index c1400b3f9..c8c922c6a 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 86d02329c537ccb46ccb062918f0cb9e839f2cf894dfd57223c3ea4de14266db -updated: 2017-11-02T14:09:11.208038182-05:00 +hash: 765599cf3dcac232d3d2ece65c3b016d0abe55d0536adfe93d11e0dd29287de4 +updated: 2017-11-13T14:37:54.127163059+01:00 imports: - name: github.com/btcsuite/btcd version: c7588cbf7690cd9f047a28efa2dcd8f2435a4e5e @@ -10,7 +10,7 @@ imports: subpackages: - base58 - name: github.com/ethanfrey/hid - version: 660bb717bd4e7cbcdf0f7cd5cadf1cb2e4be452a + version: ea8f4c923d3bc8c9c312b7d38724a294f184258a - name: github.com/ethanfrey/ledger version: 23a7bb9d74bc83a862fcb4bddde24215b2295ad9 - name: github.com/go-kit/kit @@ -60,18 +60,18 @@ imports: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: 2baffcb6b690057568bc90ef1d457efb150b979a + version: 1c96861c03231361546944d883d99593b2e6b408 subpackages: - data - data/base58 - name: github.com/tendermint/tmlibs - version: d9525c0fb671204450b160807480e1263053fb20 + version: 56e51bc1133bd54a331e0314d5f80fb547460362 subpackages: - common - db - log - name: golang.org/x/crypto - version: bd6f299fb381e4c3393d1c4b1f0b94f5e77650c8 + version: edd5e9b0879d13ee6970a50153d85b8fec9f7686 subpackages: - bcrypt - blowfish diff --git a/glide.yaml b/glide.yaml index a0b6650fa..64b275f10 100644 --- a/glide.yaml +++ b/glide.yaml @@ -17,7 +17,7 @@ import: subpackages: - extra25519 - package: github.com/tendermint/tmlibs - version: develop + version: sdk-develop - package: github.com/tendermint/go-wire version: develop subpackages: diff --git a/keys/keybase.go b/keys/keybase.go index 00de1ad55..14775060a 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -86,8 +86,7 @@ func (kb dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { // List loads the keys from the storage and enforces alphabetical order func (kb dbKeybase) List() ([]Info, error) { var res []Info - var more = true - for iter := kb.db.Iterator(); more; more = iter.Next() { + for iter := kb.db.Iterator(); iter.Valid(); iter.Next() { key := iter.Key() if isPub(key) { info, err := readInfo(iter.Value()) From 2649c056cd37716ab7f9dcea759874d97c22870a Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 13 Nov 2017 14:54:14 +0100 Subject: [PATCH 177/287] Minor cleanup --- Makefile | 3 ++- keys/keybase.go | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index c1974c410..31ea0214a 100644 --- a/Makefile +++ b/Makefile @@ -56,11 +56,12 @@ metalinter_test: ensure_tools --enable=structcheck \ --enable=unconvert \ --enable=unused \ - --enable=vetshadow \ --enable=vet \ --enable=varcheck \ ./... + # --enable=vetshadow \ <= doesn't like assert := assert.New(t) + #--enable=dupl \ #--enable=errcheck \ #--enable=goimports \ diff --git a/keys/keybase.go b/keys/keybase.go index 14775060a..7f53b2979 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -222,11 +222,11 @@ func generate(algo string, secret []byte) (crypto.PrivKey, error) { func generateByType(typ byte, secret []byte) (crypto.PrivKey, error) { switch typ { case crypto.TypeEd25519: - return generate(crypto.NameEd25519, secret) + return crypto.GenPrivKeyEd25519FromSecret(secret).Wrap(), nil case crypto.TypeSecp256k1: - return generate(crypto.NameSecp256k1, secret) + return crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap(), nil case nano.TypeLedgerEd25519: - return generate(nano.NameLedgerEd25519, secret) + return nano.NewPrivKeyLedgerEd25519Ed25519() default: err := errors.Errorf("Cannot generate keys for algorithm: %X", typ) return crypto.PrivKey{}, err From 086e1f6508e6b32159b82ded17f335abd76caaf7 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 15 Nov 2017 13:57:17 +0100 Subject: [PATCH 178/287] Make vetshadow and zach happy --- Makefile | 2 +- encode_test.go | 4 +--- keys/ecc_test.go | 6 +++--- keys/keybase_test.go | 18 +++++++++--------- keys/wordcodec_test.go | 12 ++++++------ nano/keys_test.go | 10 +++++----- nano/sign_test.go | 9 +++++---- signature_test.go | 6 ++---- 8 files changed, 32 insertions(+), 35 deletions(-) diff --git a/Makefile b/Makefile index 31ea0214a..9e2530a94 100644 --- a/Makefile +++ b/Makefile @@ -58,9 +58,9 @@ metalinter_test: ensure_tools --enable=unused \ --enable=vet \ --enable=varcheck \ + --enable=vetshadow \ ./... - # --enable=vetshadow \ <= doesn't like assert := assert.New(t) #--enable=dupl \ #--enable=errcheck \ diff --git a/encode_test.go b/encode_test.go index 1b70d88ec..947d91901 100644 --- a/encode_test.go +++ b/encode_test.go @@ -145,8 +145,6 @@ func (s SigMessage) Bytes() []byte { } func TestEmbededWireEncodings(t *testing.T) { - assert := assert.New(t) - cases := []struct { privKey PrivKey keyType byte @@ -171,7 +169,7 @@ func TestEmbededWireEncodings(t *testing.T) { for i, tc := range cases { pubKey := tc.privKey.PubKey() sig := tc.privKey.Sign(payload) - assert.True(pubKey.VerifyBytes(payload, sig), "%d", i) + assert.True(t, pubKey.VerifyBytes(payload, sig), "%d", i) msg := SigMessage{ Key: pubKey, diff --git a/keys/ecc_test.go b/keys/ecc_test.go index d6b536aaa..6d3e3bec8 100644 --- a/keys/ecc_test.go +++ b/keys/ecc_test.go @@ -3,7 +3,7 @@ package keys import ( "testing" - "github.com/stretchr/testify/assert" + asrt "github.com/stretchr/testify/assert" cmn "github.com/tendermint/tmlibs/common" ) @@ -21,7 +21,7 @@ var codecs = []ECC{ // TestECCPasses makes sure that the AddECC/CheckECC methods are symetric func TestECCPasses(t *testing.T) { - assert := assert.New(t) + assert := asrt.New(t) checks := append(codecs, NoECC{}) @@ -41,7 +41,7 @@ func TestECCPasses(t *testing.T) { // TestECCFails makes sure random data will (usually) fail the checksum func TestECCFails(t *testing.T) { - assert := assert.New(t) + assert := asrt.New(t) checks := codecs attempts := 2000 diff --git a/keys/keybase_test.go b/keys/keybase_test.go index bb6602b48..72476a02e 100644 --- a/keys/keybase_test.go +++ b/keys/keybase_test.go @@ -5,8 +5,8 @@ import ( "os" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + asrt "github.com/stretchr/testify/assert" + rqr "github.com/stretchr/testify/require" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" @@ -18,7 +18,7 @@ import ( // TestKeyManagement makes sure we can manipulate these keys well func TestKeyManagement(t *testing.T) { - assert, require := assert.New(t), require.New(t) + assert, require := asrt.New(t), rqr.New(t) // make the storage with reasonable defaults cstore := keys.New( @@ -86,7 +86,7 @@ func TestKeyManagement(t *testing.T) { // TestSignVerify does some detailed checks on how we sign and validate // signatures func TestSignVerify(t *testing.T) { - assert, require := assert.New(t), require.New(t) + assert, require := asrt.New(t), rqr.New(t) // make the storage with reasonable defaults cstore := keys.New( @@ -157,7 +157,7 @@ func TestSignVerify(t *testing.T) { // This test will only succeed with a ledger attached to the computer // and the cosmos app open func TestSignWithLedger(t *testing.T) { - assert, require := assert.New(t), require.New(t) + assert, require := asrt.New(t), rqr.New(t) if os.Getenv("WITH_LEDGER") == "" { t.Skip("Set WITH_LEDGER to run code on real ledger") } @@ -205,7 +205,7 @@ func TestSignWithLedger(t *testing.T) { assert.False(key.VerifyBytes(d1, s2)) } -func assertPassword(assert *assert.Assertions, cstore keys.Keybase, name, pass, badpass string) { +func assertPassword(assert *asrt.Assertions, cstore keys.Keybase, name, pass, badpass string) { err := cstore.Update(name, badpass, pass) assert.NotNil(err) err = cstore.Update(name, pass, pass) @@ -214,7 +214,7 @@ func assertPassword(assert *assert.Assertions, cstore keys.Keybase, name, pass, // TestImportUnencrypted tests accepting raw priv keys bytes as input func TestImportUnencrypted(t *testing.T) { - require := require.New(t) + require := rqr.New(t) // make the storage with reasonable defaults cstore := keys.New( @@ -240,7 +240,7 @@ func TestImportUnencrypted(t *testing.T) { // TestAdvancedKeyManagement verifies update, import, export functionality func TestAdvancedKeyManagement(t *testing.T) { - assert, require := assert.New(t), require.New(t) + assert, require := asrt.New(t), rqr.New(t) // make the storage with reasonable defaults cstore := keys.New( @@ -283,7 +283,7 @@ func TestAdvancedKeyManagement(t *testing.T) { // TestSeedPhrase verifies restoring from a seed phrase func TestSeedPhrase(t *testing.T) { - assert, require := assert.New(t), require.New(t) + assert, require := asrt.New(t), rqr.New(t) // make the storage with reasonable defaults cstore := keys.New( diff --git a/keys/wordcodec_test.go b/keys/wordcodec_test.go index a44607be2..f79ebcad0 100644 --- a/keys/wordcodec_test.go +++ b/keys/wordcodec_test.go @@ -3,14 +3,14 @@ package keys import ( "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + asrt "github.com/stretchr/testify/assert" + rqr "github.com/stretchr/testify/require" cmn "github.com/tendermint/tmlibs/common" ) func TestLengthCalc(t *testing.T) { - assert := assert.New(t) + assert := asrt.New(t) cases := []struct { bytes, words int @@ -50,7 +50,7 @@ func TestLengthCalc(t *testing.T) { } func TestEncodeDecode(t *testing.T) { - assert, require := assert.New(t), require.New(t) + assert, require := asrt.New(t), rqr.New(t) codec, err := LoadCodec("english") require.Nil(err, "%+v", err) @@ -82,7 +82,7 @@ func TestEncodeDecode(t *testing.T) { } func TestCheckInvalidLists(t *testing.T) { - assert := assert.New(t) + assert := asrt.New(t) trivial := []string{"abc", "def"} short := make([]string, 1234) @@ -144,7 +144,7 @@ func getDiffWord(c *WordCodec, not string) string { } func TestCheckTypoDetection(t *testing.T) { - assert, require := assert.New(t), require.New(t) + assert, require := asrt.New(t), rqr.New(t) banks := []string{"english", "spanish", "japanese", "chinese_simplified"} diff --git a/nano/keys_test.go b/nano/keys_test.go index 15aa0d545..2e5142e30 100644 --- a/nano/keys_test.go +++ b/nano/keys_test.go @@ -5,14 +5,14 @@ import ( "os" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + asrt "github.com/stretchr/testify/assert" + rqr "github.com/stretchr/testify/require" crypto "github.com/tendermint/go-crypto" ) func TestLedgerKeys(t *testing.T) { - assert, require := assert.New(t), require.New(t) + assert, require := asrt.New(t), rqr.New(t) cases := []struct { msg, pubkey, sig string @@ -76,7 +76,7 @@ func TestLedgerKeys(t *testing.T) { } func TestRealLedger(t *testing.T) { - assert, require := assert.New(t), require.New(t) + assert, require := asrt.New(t), rqr.New(t) if os.Getenv("WITH_LEDGER") == "" { t.Skip("Set WITH_LEDGER to run code on real ledger") @@ -115,7 +115,7 @@ func TestRealLedger(t *testing.T) { // TestRealLedgerErrorHandling calls. These tests assume // the ledger is not plugged in.... func TestRealLedgerErrorHandling(t *testing.T) { - require := require.New(t) + require := rqr.New(t) if os.Getenv("WITH_LEDGER") != "" { t.Skip("Skipping on WITH_LEDGER as it tests unplugged cases") diff --git a/nano/sign_test.go b/nano/sign_test.go index 04a6d0be7..18e4e0d0b 100644 --- a/nano/sign_test.go +++ b/nano/sign_test.go @@ -5,8 +5,9 @@ import ( "testing" "github.com/pkg/errors" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + asrt "github.com/stretchr/testify/assert" + rqr "github.com/stretchr/testify/require" + crypto "github.com/tendermint/go-crypto" ) @@ -29,7 +30,7 @@ func parseSig(data []byte) (key crypto.Signature, err error) { } func TestParseDigest(t *testing.T) { - assert, require := assert.New(t), require.New(t) + assert, require := asrt.New(t), rqr.New(t) cases := []struct { output string @@ -91,7 +92,7 @@ func toBytes(c cryptoCase) (msg, key, sig []byte, err error) { } func TestCryptoConvert(t *testing.T) { - assert, require := assert.New(t), require.New(t) + assert, require := asrt.New(t), rqr.New(t) cases := []cryptoCase{ 0: { diff --git a/signature_test.go b/signature_test.go index 5e9f06723..6659c5b9d 100644 --- a/signature_test.go +++ b/signature_test.go @@ -109,8 +109,6 @@ func TestSignatureEncodings(t *testing.T) { } func TestWrapping(t *testing.T) { - assert := assert.New(t) - // construct some basic constructs msg := CRandBytes(128) priv := GenPrivKeyEd25519() @@ -126,7 +124,7 @@ func TestWrapping(t *testing.T) { } for _, p := range pubs { _, ok := p.PubKeyInner.(PubKey) - assert.False(ok) + assert.False(t, ok) } sigs := []Signature{ @@ -137,7 +135,7 @@ func TestWrapping(t *testing.T) { } for _, s := range sigs { _, ok := s.SignatureInner.(Signature) - assert.False(ok) + assert.False(t, ok) } } From eaf4b8c79500e7be9b227c5dca8b9813bb75842d Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Thu, 21 Dec 2017 19:51:57 -0500 Subject: [PATCH 179/287] fix Equals --- priv_key.go | 16 ++++++---------- signature.go | 16 ++++------------ signature_test.go | 24 ++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/priv_key.go b/priv_key.go index 456985615..613d94593 100644 --- a/priv_key.go +++ b/priv_key.go @@ -55,13 +55,11 @@ func (privKey PrivKeyEd25519) PubKey() PubKey { return PubKeyEd25519(pubBytes).Wrap() } +// Equals - you probably don't need to use this. +// Runs in constant time based on length of the keys. func (privKey PrivKeyEd25519) Equals(other PrivKey) bool { if otherEd, ok := other.Unwrap().(PrivKeyEd25519); ok { - // It is essential that we constant time compare - // private keys and signatures instead of bytes.Equal, - // to avoid susceptibility to timing/side channel attacks. - // See Issue https://github.com/tendermint/go-crypto/issues/43 - return subtle.ConstantTimeCompare(privKey[:], otherEd[:]) == 0 + return subtle.ConstantTimeCompare(privKey[:], otherEd[:]) == 1 } else { return false } @@ -146,13 +144,11 @@ func (privKey PrivKeySecp256k1) PubKey() PubKey { return pub.Wrap() } +// Equals - you probably don't need to use this. +// Runs in constant time based on length of the keys. func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool { if otherSecp, ok := other.Unwrap().(PrivKeySecp256k1); ok { - // It is essential that we constant time compare - // private keys and signatures instead of bytes.Equal, - // to avoid susceptibility to timing/side channel attacks. - // See Issue https://github.com/tendermint/go-crypto/issues/43 - return subtle.ConstantTimeCompare(privKey[:], otherSecp[:]) == 0 + return subtle.ConstantTimeCompare(privKey[:], otherSecp[:]) == 1 } else { return false } diff --git a/signature.go b/signature.go index fb07aba96..be1f24905 100644 --- a/signature.go +++ b/signature.go @@ -1,7 +1,7 @@ package crypto import ( - "crypto/subtle" + "bytes" "fmt" "github.com/tendermint/go-wire" @@ -46,11 +46,7 @@ func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fing func (sig SignatureEd25519) Equals(other Signature) bool { if otherEd, ok := other.Unwrap().(SignatureEd25519); ok { - // It is essential that we constant time compare - // private keys and signatures instead of bytes.Equal, - // to avoid susceptibility to timing/side channel attacks. - // See Issue https://github.com/tendermint/go-crypto/issues/43 - return subtle.ConstantTimeCompare(sig[:], otherEd[:]) == 0 + return bytes.Equal(sig[:], otherEd[:]) } else { return false } @@ -85,12 +81,8 @@ func (sig SignatureSecp256k1) IsZero() bool { return len(sig) == 0 } func (sig SignatureSecp256k1) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } func (sig SignatureSecp256k1) Equals(other Signature) bool { - if otherEd, ok := other.Unwrap().(SignatureSecp256k1); ok { - // It is essential that we constant time compare - // private keys and signatures instead of bytes.Equal, - // to avoid susceptibility to timing/side channel attacks. - // See Issue https://github.com/tendermint/go-crypto/issues/43 - return subtle.ConstantTimeCompare(sig[:], otherEd[:]) == 0 + if otherSecp, ok := other.Unwrap().(SignatureSecp256k1); ok { + return bytes.Equal(sig[:], otherSecp[:]) } else { return false } diff --git a/signature_test.go b/signature_test.go index 5e9f06723..4801e5fef 100644 --- a/signature_test.go +++ b/signature_test.go @@ -141,3 +141,27 @@ func TestWrapping(t *testing.T) { } } + +func TestPrivKeyEquality(t *testing.T) { + { + privKey := GenPrivKeySecp256k1().Wrap() + privKey2 := GenPrivKeySecp256k1().Wrap() + assert.False(t, privKey.Equals(privKey2)) + assert.False(t, privKey2.Equals(privKey)) + + privKeyCopy := privKey // copy + assert.True(t, privKey.Equals(privKeyCopy)) + assert.True(t, privKeyCopy.Equals(privKey)) + } + + { + privKey := GenPrivKeyEd25519().Wrap() + privKey2 := GenPrivKeyEd25519().Wrap() + assert.False(t, privKey.Equals(privKey2)) + assert.False(t, privKey2.Equals(privKey)) + + privKeyCopy := privKey // copy + assert.True(t, privKey.Equals(privKeyCopy)) + assert.True(t, privKeyCopy.Equals(privKey)) + } +} From 62115b55ef895f154ea70e999532d3d682c1ab20 Mon Sep 17 00:00:00 2001 From: Emmanuel Odeke Date: Fri, 22 Dec 2017 23:16:31 -0700 Subject: [PATCH 180/287] CRandHex: fix up doc to mention length of digits The previous doc seemed misleading and was out of date i.e. RandHex(24) not CRandHex. Anyways provide a doc of what the function does in relation to the length of digits of the hex value returned i.e. floor(numDigits / 2) * 2 so the even lowest number e.g: * len(CRandHex(5)) = 4 * len(CRandHex(4)) = 4 --- random.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/random.go b/random.go index 40cbcf8fa..46754219d 100644 --- a/random.go +++ b/random.go @@ -44,7 +44,10 @@ func CRandBytes(numBytes int) []byte { return b } -// RandHex(24) gives 96 bits of randomness, strong enough for most purposes. +// CRandHex returns a hex encoded string that's floor(numDigits/2) * 2 long. +// +// Note: CRandHex(24) gives 96 bits of randomness that +// are usually strong enough for most purposes. func CRandHex(numDigits int) string { return hex.EncodeToString(CRandBytes(numDigits / 2)) } From 9472476a8b5814d42b96881e28a01536acfdabb3 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Tue, 26 Dec 2017 00:28:07 -0800 Subject: [PATCH 181/287] Update Makefile --- Makefile | 107 ++++++++++++++++++++++++-------------- keys/wordlist/wordlist.go | 30 +++++------ 2 files changed, 83 insertions(+), 54 deletions(-) diff --git a/Makefile b/Makefile index 9e2530a94..6f23f8ef7 100644 --- a/Makefile +++ b/Makefile @@ -1,70 +1,99 @@ -.PHONEY: all test install get_vendor_deps ensure_tools codegen wordlist - GOTOOLS = \ github.com/Masterminds/glide \ github.com/jteeuwen/go-bindata/go-bindata \ - github.com/alecthomas/gometalinter + gopkg.in/alecthomas/gometalinter.v2 \ +GOTOOLS_CHECK = glide go-bindata gometalinter.v2 -REPO:=github.com/tendermint/go-crypto +all: check get_vendor_deps build test install metalinter -all: get_vendor_deps metalinter_test test +check: check_tools -test: - go test -p 1 `glide novendor` -get_vendor_deps: ensure_tools +######################################## +### Build + +wordlist: + # Generating wordlist.go... + go-bindata -ignore ".*\.go" -o keys/wordlist/wordlist.go -pkg "wordlist" keys/wordlist/... + +build: wordlist + # Nothing else to build! + +install: + # Nothing to install! + + +######################################## +### Tools & dependencies + +check_tools: + @# https://stackoverflow.com/a/25668869 + @echo "Found tools: $(foreach tool,$(GOTOOLS_CHECK),\ + $(if $(shell which $(tool)),$(tool),$(error "No $(tool) in PATH")))" + +get_tools: + @echo "--> Installing tools" + go get -u -v $(GOTOOLS) + @gometalinter.v2 --install + +update_tools: + @echo "--> Updating tools" + @go get -u $(GOTOOLS) + +get_vendor_deps: @rm -rf vendor/ @echo "--> Running glide install" @glide install -ensure_tools: - go get $(GOTOOLS) -wordlist: - go-bindata -ignore ".*\.go" -o keys/wordlist/wordlist.go -pkg "wordlist" keys/wordlist/... +######################################## +### Testing -prepgen: install - go install ./vendor/github.com/btcsuite/btcutil/base58 - go install ./vendor/github.com/stretchr/testify/assert - go install ./vendor/github.com/stretchr/testify/require - go install ./vendor/golang.org/x/crypto/bcrypt +test: + go test -p 1 `glide novendor` -codegen: - @echo "--> regenerating all interface wrappers" - @gen - @echo "Done!" -metalinter: ensure_tools - @gometalinter --install - gometalinter --vendor --deadline=600s --enable-all --disable=lll ./... +######################################## +### Formatting, linting, and vetting -metalinter_test: ensure_tools - @gometalinter --install - gometalinter --vendor --deadline=600s --disable-all \ +fmt: + @go fmt ./... + +metalinter: + @echo "==> Running linter" + gometalinter.v2 --vendor --deadline=600s --disable-all \ + --enable=maligned \ --enable=deadcode \ - --enable=gas \ --enable=goconst \ - --enable=gocyclo \ + --enable=goimports \ --enable=gosimple \ - --enable=ineffassign \ - --enable=interfacer \ - --enable=maligned \ + --enable=ineffassign \ --enable=megacheck \ - --enable=misspell \ - --enable=safesql \ + --enable=misspell \ --enable=staticcheck \ + --enable=safesql \ --enable=structcheck \ - --enable=unconvert \ + --enable=unconvert \ --enable=unused \ - --enable=vet \ --enable=varcheck \ --enable=vetshadow \ ./... - - + #--enable=gas \ #--enable=dupl \ #--enable=errcheck \ - #--enable=goimports \ + #--enable=gocyclo \ #--enable=golint \ <== comments on anything exported #--enable=gotype \ + #--enable=interfacer \ #--enable=unparam \ + #--enable=vet \ + +metalinter_all: + protoc $(INCLUDE) --lint_out=. types/*.proto + gometalinter.v2 --vendor --deadline=600s --enable-all --disable=lll ./... + + +# To avoid unintended conflicts with file names, always add to .PHONY +# unless there is a reason not to. +# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html +.PHONEY: check wordlist build install check_tools get_tools update_tools get_vendor_deps test fmt metalinter metalinter_all diff --git a/keys/wordlist/wordlist.go b/keys/wordlist/wordlist.go index 58ff41181..dd531b6dd 100644 --- a/keys/wordlist/wordlist.go +++ b/keys/wordlist/wordlist.go @@ -71,7 +71,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _keysWordlistChinese_simplifiedTxt = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x1c\x97\x55\x76\xeb\x30\x14\x45\xff\xf7\xa8\xc3\xcc\x49\xc3\x69\x98\xda\x86\xd9\x0e\x4c\xc6\xf7\x4a\x9a\xc5\x5b\x7e\x7f\x5d\x5d\x6d\x6c\x45\x07\xf6\x31\xdd\x04\xc1\x3d\x82\xb6\x77\x48\x7f\x45\x70\x2f\x12\x78\x29\xb4\x9f\x45\x6a\x05\x02\xcf\xc3\x7e\x3a\x04\xf7\x0d\x32\x5b\x12\xdc\x3d\x82\x7b\x8e\xe0\xfe\x83\xf4\x5e\x68\xa6\x4a\xe0\xcf\xb1\x8b\x28\x81\xdf\x44\x5b\x57\x74\x30\xc7\x34\x56\x04\xfe\x1f\xa6\x31\x44\x32\x7b\x82\x57\x1f\xe9\xef\x09\xbc\x12\x92\xf6\x90\xfd\x01\xc9\xa4\x90\xdd\x03\xcd\x54\x08\x9e\x5d\xa4\xbc\x23\xb8\xfb\x48\xb9\x8a\x3c\xce\x48\x6e\x85\x54\x0a\xc8\x6d\x4e\xf0\x18\x62\xe3\x2f\x82\x7b\x1e\xfb\x49\x23\x9b\x0a\x76\x77\x26\xf0\x96\x98\x65\x11\x37\x98\x60\x23\x05\xb4\xf9\x40\x2a\x25\x64\xd6\x45\xb6\x5d\xec\xb8\x80\x6c\x16\xe8\xe9\x0b\xcd\x46\xd0\x7d\x15\x79\xb7\x30\x7e\x19\x29\x46\x09\xee\x59\x82\x47\xf8\x99\x3d\xcc\x20\x82\xd9\x64\x71\xf1\x15\xe2\x2d\x90\xed\x15\xd3\xb8\x20\xb9\x1e\x2e\x5d\x40\x16\x31\x74\x7f\x46\x0a\x4d\xdc\x6f\x1b\x9b\xfe\x21\xf0\x0a\x98\x4a\x0a\x7b\xb9\x21\xfb\x32\x26\xbb\xc6\x94\xf6\xc8\xf6\x1b\xc9\x8d\x70\xe9\x32\xee\xff\x7b\xcf\x08\x5e\x75\x24\x73\x45\xfb\x1e\xf2\xaa\x13\xbc\x3e\x98\xd8\x83\xc0\x2f\x11\xdc\xbb\x68\xff\x0f\x29\xf9\x68\x2e\x87\x46\x96\xc8\xfc\x85\x78\x0d\xe4\x19\x41\xb6\x71\xa4\x92\xc1\x7e\xda\x48\x6f\x84\x69\x1c\x90\xe4\x95\xc0\xeb\x61\x12\x57\x24\x5b\x44\x66\x4d\x64\xb6\x46\x1b\x1f\xa4\xd7\x43\x5b\x73\x5c\x6c\x8a\x99\xbd\x09\x1e\x59\x02\x2f\x8f\x3c\x4e\xc8\x6b\x82\xe9\xdd\x91\xe4\x0a\x3b\x5e\xe1\x5a\x67\x74\x74\x23\xb8\x97\x90\xe4\x09\xa9\x24\x70\xe9\x22\xda\xdc\x63\xbc\x0f\x92\x4a\xa2\x5f\x7b\x74\x33\x45\x3e\x71\xa4\x5c\x24\x78\x8d\xd0\x76\x09\xd3\xcf\x23\xa5\x21\x52\xce\x10\x3c\x32\x48\x66\x8d\xee\x1a\x68\xa6\x49\xf0\x4a\x61\xcf\x2b\x74\xdf\xc0\xfc\xfd\x21\x95\x2a\x2e\x5a\x47\xaa\x2f\x74\x33\x43\xca\x6d\x74\x30\x46\xca\x3f\xe8\x71\x8c\xf1\xeb\xd8\xe5\x14\xd7\xda\xa2\x89\x32\xe2\x7b\x68\x3f\x83\x24\xff\xd0\xd6\x08\x73\xf2\x91\x54\x0f\x79\x67\xd0\x78\x12\x1b\x49\xa2\xfd\x08\xe6\x37\x4f\xe0\x4f\xd1\xf8\x09\xb9\x1d\x71\x91\x2e\xf2\xb8\xa2\xe5\x0a\xa6\x77\xc6\x4d\xda\x48\xb2\x8b\x59\xe5\x91\xc3\x17\x81\xd7\x40\xbf\xfb\x68\xb3\x83\x3d\x8c\x91\x6a\x1b\x37\x58\x13\xbc\x8a\x48\x72\x8e\xdc\xef\x68\x33\x8d\x46\x7c\xf4\x6f\x8c\xd4\xa3\xc8\xb3\x8c\x9e\x7d\xec\xf6\x8d\x94\x73\x98\xed\x18\x93\x0d\xef\xee\x8a\xfb\xfa\xa0\x87\x18\x36\x12\x45\x66\x67\x64\xe8\x61\x2f\x09\xec\xfb\x81\x5e\xa2\xd8\xdb\x0e\xe3\x2d\x91\x50\x7b\xbd\x37\x72\x38\x60\xfc\x21\x5a\x9a\x63\x86\x73\xec\x3b\x8e\xec\x53\x18\x3f\x81\x5d\x46\xb1\xdb\x31\x92\xf9\x45\xe6\x0f\x34\x9b\xc7\x2e\x6b\x68\x7f\x88\x8e\x1e\xd8\x6d\xe8\xc7\x0a\x92\xea\xa3\x85\x34\x92\x1e\x11\x3c\x06\x48\xc1\x43\x9e\x1e\xda\x78\x23\xa9\x13\x76\xfe\xc1\x4e\x7e\x91\xc7\x11\x89\x76\x91\x4f\x12\xcd\x84\xdf\x43\x06\xe9\x7d\x23\x99\x0e\x81\x1f\x7a\xad\x89\x16\xb7\xc8\x2c\x81\x6b\x0f\x91\x62\xe8\x8d\x0e\x36\x7b\x44\x92\x59\x5c\x6b\x85\x14\x4f\x04\x9f\x01\x7a\xf4\x91\x42\x0b\x17\x19\x61\x3a\x6f\xec\x32\x81\x89\x6f\x70\x93\x14\xc1\x3d\x8e\x86\x1e\x28\x4f\x09\xee\x7d\x64\xf7\x44\x3a\x2b\xa4\x94\x47\x3e\x2d\x82\x7b\x13\x97\xae\x22\x93\x6f\x02\x2f\x8b\x5e\x4a\xb8\xf6\x15\x3d\x3e\xd0\xc8\x00\xed\xef\xd0\xef\x28\x81\x17\xea\xa2\x85\x8d\x36\x08\xfc\x08\x76\x3b\x43\x92\x1b\x24\x79\x40\x07\x71\xb4\x71\xc5\xee\xa2\x68\xe3\x81\xde\x93\x98\x77\x09\x49\x15\x71\xe9\x34\xf6\xf5\x87\xf6\xce\x48\xf1\x0b\x37\x2d\x21\x99\x34\x9a\xad\x63\x3a\x2f\xf4\xab\x83\x8b\x0c\xb1\xb9\x03\x72\x0f\xbd\x9d\x45\xfa\x1e\xd6\xfb\xc5\xbe\x16\x04\xef\x3c\xa6\x3f\x44\x72\x63\x24\x19\x7a\x21\x8d\xee\xca\x98\xde\x16\x9b\x3e\x61\xdf\x6f\xec\x65\x8f\x59\xee\x30\x33\x0f\xbb\xdd\x22\xd3\x3d\x9a\x9b\xa3\xcd\x16\xb2\x2d\x60\x0e\x3e\x92\xfc\xc5\x2c\x7c\xa4\x58\x42\x2a\x45\xcc\x78\x8b\x66\x8b\x98\x65\x15\x79\x8e\x08\x3e\x63\xdc\xfa\x0f\x9b\x8b\x61\x77\x03\xcc\xe1\x84\x7e\x9d\x31\x6b\x0f\x49\xc6\x91\xd4\x85\xc0\xcf\xe1\x7a\x29\xf4\xbe\x26\x78\x8e\x90\xfe\x10\xbb\xbd\xa3\x9b\x39\xe6\x3d\x43\x1e\x1f\xcc\xf0\x84\xdd\xee\x71\xfd\x08\xba\xbd\x60\x46\x0d\xcc\x57\x01\xcd\x67\xd1\xef\x16\xf2\xce\x23\xe5\x5f\x82\x7b\x03\xb3\xbe\x62\x97\x31\xec\x35\x87\xf1\xd3\xd8\x69\x12\x79\x1d\x30\xdb\x16\xc1\xab\x84\x16\xa2\xb8\xe1\x89\xe0\xd9\x22\x78\x2c\x90\x7b\x1c\x99\x15\x91\xed\x03\x49\x7c\x70\x63\x1f\xd7\x49\x22\x5f\x29\xdc\xe0\x1b\xf7\x53\xc0\x7e\xbe\xd1\xe6\x06\xbd\x1d\x70\xdd\x37\xf6\x53\xc5\x0c\x3f\x48\x31\x8e\x54\x57\xc8\xb2\x81\x39\x8f\xd0\x5c\x04\x99\xa5\x91\x62\x0e\xc9\x7d\xe3\x06\x35\x4c\x3f\x8a\x64\xc2\x67\x8d\x90\x7a\x11\xe3\x2d\xd0\xc6\x0e\x9b\xf9\x43\xca\x47\x34\x11\xde\xc3\x89\xe0\x1d\xe6\xd8\x04\x79\x47\x70\xc9\x3b\x52\x4a\x21\xf7\x18\x92\xcc\x13\xbc\xbe\x70\x9d\x19\x7a\xcd\xa0\xdf\x09\xc4\xeb\x63\x96\x7b\x64\xf6\x83\xa4\x53\x98\xe3\x1b\x89\x3c\x91\xf2\x0d\x53\x4a\xa3\xad\x32\xc6\x3f\x23\x99\x1a\x2e\x92\x45\x47\x69\x24\xd5\x41\x36\x6d\x24\xd2\x41\x77\x3d\x02\xef\x88\x7c\x7e\xd1\xaf\x0c\xda\xdc\xe1\x3a\x13\x74\x38\x47\x0f\x43\xe4\x3b\xd4\xc7\x13\x53\xca\xa3\x85\xf0\xff\x9f\x48\xd2\x47\xdb\x75\xcc\x6b\x8b\x9e\x43\x5f\xc7\x30\xd9\x34\xb2\xcc\x23\xc5\x33\xc1\xbd\x8e\xc9\x5d\xb1\xb1\x23\x52\x8a\x11\x78\x7f\xd8\x5d\x0a\x17\x89\x21\x87\x6f\xa4\x9f\x42\x0a\x49\x4c\xf4\x97\xe0\x55\xc6\xee\xe3\xa8\x3f\x46\x4a\x1f\xe4\x10\xc1\x24\x97\x48\x39\x86\xf1\x26\x18\x3f\x85\x3c\xbf\x90\x4a\xf8\x19\x73\x5c\x3d\xec\xdb\x50\xa7\x73\xdc\xa2\x89\x78\x5f\xe8\xf5\x88\x6c\xdb\xc8\xfb\x86\xeb\x96\x31\xad\x24\x36\x5f\x46\x66\x07\x64\xdf\x40\x37\x61\x7e\x1d\x71\xc9\x22\x32\x3f\xe1\xfc\x04\x5a\x5a\xa1\xed\x37\x76\x9f\xc1\xbc\x7e\x30\xf3\x6f\x6c\xd6\x43\xaa\x13\x24\xec\xfc\xca\x2f\xc1\x33\x8a\xf6\x7b\xc8\x2e\x85\x66\x1f\xd8\xca\x1c\x37\x7e\xe0\xda\x47\x82\xfb\x1b\x53\x89\x63\xf3\x07\x74\xbf\x44\x72\x1f\xa4\x9a\x43\x07\x25\xa4\xbc\xc7\x56\x5e\x68\x7f\x85\xdc\xb7\xd8\xd7\x16\x33\x0a\x3b\xbb\x8b\xdc\xc3\x1c\x3a\xa3\xa7\x15\xf6\xd3\x47\x36\x2d\x74\x50\x41\x4b\x35\x82\x77\x0f\x3d\x9e\xd0\x30\x4f\xf7\x51\xa4\xbc\x40\x9b\x2f\x24\x5d\x46\x47\x55\xd4\xbb\xa2\x91\x12\xba\x99\xa0\xe3\x0c\x76\x15\x41\xa6\xbf\xc8\x20\x8d\x6e\x16\x48\xcf\x43\xca\x57\xdc\xe1\x89\x9e\x26\xd8\x65\x8a\xc0\x4f\x62\xcf\x0f\xcc\x79\x89\xc9\x1c\x90\xdb\x02\xf3\x3b\x42\x5b\x6b\xb4\x3f\x40\xb6\x27\x8c\xbf\xc1\xbe\x7c\xb4\x5f\xc4\xee\xc2\x0c\x19\x22\xc9\x24\x92\xbc\xa0\x5e\x05\xc9\xcc\xd0\x5c\x98\x4f\x77\xec\xf5\x84\x0e\x2b\x18\x3f\x8e\xdc\xc2\x8c\x38\xa3\x83\x0f\xa6\xb1\xc7\x75\x8a\x38\xbf\x8a\xc9\xed\xb0\xe7\x21\x92\xf6\xb1\x85\x38\xc6\x5f\x22\xc9\x33\xc1\xf3\x49\xf0\xea\x20\x83\x2e\xda\x3b\x62\xdf\x75\x82\xcf\x16\xfd\x4a\x22\xc3\x90\x5d\x7e\x91\xd9\x10\x17\x89\x62\xfe\x1a\xd8\xcc\x03\x29\x8e\x90\xf2\x09\x7b\x9e\x20\x95\x38\xb2\x2b\xa0\xed\x39\x36\x5a\xc0\x2e\xb3\xe8\x21\x8b\x69\xf8\x48\x6e\x88\xdc\xce\xd8\xdb\x10\x1b\xe6\xde\x20\x86\x9b\x7e\xa3\xd3\x08\x52\xb9\x23\xb9\x35\x52\x4c\xe3\xda\x27\x02\xaf\x86\x64\x06\x48\xa6\x87\xe6\x5a\xd8\x48\x1c\xcd\x7d\x21\x83\x32\x66\xd3\x44\xca\x33\xe4\x9d\x40\x8b\x13\xb4\xff\x83\xbd\x55\x31\x61\x8e\xd6\x26\x68\xef\x8d\xf9\x0d\xcf\x37\xc5\xfc\x76\x30\xdb\x08\xf6\xb3\xc7\xd5\x0e\x48\x76\x87\xec\x5f\xc8\x7d\x80\xec\x13\xd8\x62\x16\x49\x1d\xd1\xec\x07\x93\xff\x23\xf0\x67\xb8\x4e\x05\xd7\xfe\x20\xdb\x29\xa6\xb4\x43\xca\x05\xec\xee\x86\xbd\x26\x91\xf7\x16\xbb\x5d\xa3\xa5\x25\x72\x0b\xf5\xb8\xc3\xbe\xce\x68\xf6\x8d\x54\x16\x18\xef\x07\xd3\xcb\x11\xbc\x07\x04\xcf\x36\x6e\x7c\xc5\x8c\x23\xd8\xd7\x0b\x89\xd4\xd0\xcc\x07\xf3\x13\x45\x06\x15\xcc\x31\x8b\x7e\x15\x30\x5f\x73\x64\x3b\xc1\x4e\xa2\x48\xea\x86\x8d\xf7\x31\xfe\x00\xfd\xae\x20\x83\x16\x92\x8d\xa1\x97\x3c\x41\xf8\xce\xc5\x32\x76\x97\x45\x3e\x17\x5c\x27\x43\xe0\x17\x31\xaf\x16\xa6\x57\x41\xca\x79\xf4\x9c\xc7\x35\x3a\xd8\xfc\x02\x99\xf5\x91\x4c\x15\xb3\xf4\x71\x93\x2a\x2e\x52\xc1\x0d\x46\xe8\xed\x86\xee\x8a\x98\xe1\x06\xd3\xdd\x62\xfc\x0c\x36\xda\x45\x0f\xe1\x9d\x54\x09\xbc\x2a\x52\xff\x41\x5b\x13\xec\x2d\x7c\xe6\x2f\x12\xed\x63\xe2\x19\x64\xb6\x45\x76\x43\x4c\x7c\x89\xfd\x24\x91\x49\xe8\xaf\x39\x52\xdc\xa3\xe7\x23\x92\xf1\xd1\xfc\x1f\xfa\x89\x20\x9b\x06\x5a\xf9\xc6\x34\x42\xde\x0d\xef\x2b\x89\x8e\xee\xe8\x68\x8c\x7e\x4d\x09\xde\x17\xa4\xb2\xc4\x34\x8e\xe8\xfd\x4e\xf0\x48\x62\xcb\x7d\xa4\x7a\x42\x5b\x4b\x74\x35\x46\x1f\x4d\xec\x79\x89\x16\x87\xb8\x49\xc8\x01\x3e\xba\xfb\x45\x3b\x5b\xcc\xea\x44\xf0\xe8\x20\x8b\x0c\x3a\x2b\xa2\xd1\x1d\x9a\x5d\xe3\xea\x61\x0f\x6f\xd0\xc2\x1c\x97\xac\x21\xdb\x0c\x9a\xff\x20\x5e\x19\xe3\xdd\x91\x82\x8f\x79\x7a\xb8\x5e\xc8\xf0\x2d\x5c\x2d\x64\xc3\x36\xf2\x15\xb2\xed\x1c\x69\x1c\xb0\xbb\x1d\x76\xbb\x41\x13\xa1\x0e\xc6\xb8\x4e\x02\x5b\xba\x61\x0b\x57\xdc\xb1\x8f\x39\x6e\xd1\xe6\x0c\xd9\xac\xb1\x89\x03\x66\xfc\x8b\x8d\xcd\x91\x66\x02\xf7\xee\xa0\xcf\x06\x26\xe4\xe9\x7b\x05\x3b\x8e\xa0\x7f\x13\x74\xb2\x47\x4b\x05\x74\x53\x40\x8f\x1d\x24\xd3\x45\x1b\x3e\x76\x5f\xc7\xf4\xde\xd8\xed\x0a\xed\x74\x31\xc7\x1a\xc1\xe3\x80\x49\xc7\x31\xc3\x1e\xc1\xa3\x84\x0e\x22\xd8\xe2\x0e\xd9\x46\x71\xc7\x28\xf6\x7c\xc1\xd5\x86\x98\xe4\x0c\xbb\xf3\x31\xe5\x0d\xc1\x73\x87\x5b\x84\xec\x14\x6e\x86\x5f\xa4\x3c\x27\xb8\xef\x91\xe1\x03\x2d\x87\xec\xb0\x47\xf3\x49\xe4\xb9\xc0\xf6\xf2\xe8\x31\x8b\x44\xd3\x98\xf5\x07\xcd\x2e\x31\x9b\x06\xc1\xa3\x82\xdd\x47\x71\x63\x0f\x13\x1f\x62\x9e\x6b\xe4\x1d\xc5\x26\xee\x48\xb3\x8f\x0e\xde\xd8\x44\x17\xe9\xed\x91\x67\xd8\x77\x45\x6c\x3c\xf4\xfb\x10\xb3\x28\x13\x3c\xf6\xe8\xb0\x4e\x10\x66\x7e\xb8\x49\x92\x13\x34\xf2\x85\x99\x46\x91\x48\x11\x33\x6f\x62\xba\x69\x82\x4f\x1c\x37\xe8\x60\xc7\x73\xec\x2e\x81\xf9\xf8\xd8\x58\x16\x7b\xbb\x20\xfb\x27\x76\x3c\x45\xb6\x2f\x34\xfb\x87\x4e\xb3\xc8\xbd\x40\xf0\x9c\xa1\xf5\x22\xf2\x1d\xc3\x84\x3d\xb6\xed\xa3\xfb\x09\x32\x6f\x61\x06\x53\xb4\x10\x72\x5a\xb8\x3b\xb6\x68\xff\x17\xd9\xfe\x20\x5e\x0a\xf3\x6c\x62\xb2\x3d\xec\x72\x81\xb6\x47\xb8\xde\x0d\xd7\x88\x60\x77\x2d\x24\x64\xdf\x43\x12\xcd\xd5\xb1\xd3\x18\x36\xfe\x8d\x54\x9f\xc8\xaa\x8d\x76\x76\xc8\x2a\x8a\xf1\x3f\x68\xe7\x8a\x94\xba\x98\xde\x10\x3b\x1e\xe3\xee\x63\x64\xd3\x41\xfc\x2b\x52\x3c\x60\xe3\x57\xe4\x90\x27\x78\x8c\x09\xee\x67\x5c\x27\x85\x1b\xbf\xd1\x52\x16\xa9\x46\x30\xd1\x1d\x72\x8c\xa2\xa5\x1f\x74\x30\xc4\x46\x2a\x48\xf8\x9d\x97\xb2\xd8\xcb\x05\x7b\x3b\x21\xf5\x39\xb2\x99\x62\x77\x6f\x24\xbd\xc3\xc6\xc7\xb8\xc9\x00\xfd\x7b\x63\xfc\x22\x52\xbc\xe1\x5e\xe1\x1e\x1d\x62\x6b\x77\x74\xdb\x44\xf7\x77\x64\xdb\xc2\xe6\x5b\xc8\x6d\x80\x89\x65\x91\xe3\x1a\x79\x1e\x70\xbd\x70\xef\xae\x90\x79\x19\x3d\x7e\x70\xfd\x23\x3a\x48\xa1\xa5\x09\xea\x57\x71\x5f\x69\xdc\x7c\x83\x5e\xea\xd8\xcc\x0f\x1a\x89\x60\x2f\x57\xc4\xab\x23\x33\x8f\xe0\x99\xc3\x44\x2f\x98\x55\x09\x17\x69\x60\xa2\x1b\xec\xa5\x87\xbc\x6a\x48\xf9\x0f\xf7\xac\xa3\xb5\x0d\xa6\xd7\xc6\x4e\xa3\xb8\xce\x1a\xf1\x6e\x48\x63\x87\xbc\xbe\xb0\xe5\x02\xc6\xdb\x21\x91\x21\xe6\xd4\xc4\xf4\x9a\xe8\xea\x07\xf3\xb7\xc0\x2c\xa3\x48\xee\x07\x19\xc5\x90\xe1\x10\xfd\xfe\x41\xaf\x0b\xe4\x91\x44\xea\x19\xcc\xef\x10\x93\x0a\x7b\xe2\x17\x3d\xbd\xb0\x89\x2a\x32\x9d\x61\x26\x27\xf4\x6f\x89\x8b\x16\x09\xde\x4b\x64\xb7\x42\xbf\x26\xc8\xcb\xc7\x76\xaa\x68\xb3\x8f\x6d\x86\xcc\xb5\xc1\x78\x27\xe4\xf9\xc0\xcd\x8f\x04\xcf\x3b\x9a\x6b\xe3\x42\x9e\x7b\x7c\xd0\x6e\x0b\x5b\xbc\x61\xea\x0b\x64\xfc\x8d\x78\x39\xcc\xa6\x8a\x46\xaf\x68\xe6\x86\xdd\x7e\x90\x71\x03\x99\xa7\x71\x91\x32\x1a\x66\x73\x26\x82\xb6\x42\x6f\x85\x9d\x37\x46\xf7\x3b\x5c\x34\x4d\xe0\xbf\xd0\x5d\x0d\x3d\xcd\x71\x91\x08\x7a\x6e\xa1\xd5\x14\x26\xba\x47\x5e\x61\xa7\x35\xb1\x91\x16\x32\x2b\xa3\xf9\x35\xf2\xe9\xe0\xea\x7d\x4c\x61\x8b\x19\xff\x11\x78\x19\xcc\x23\x8a\xf4\x33\xb8\x5e\xc8\x88\x2f\x82\xf0\x3d\x73\x2f\xcc\x2e\xec\xc3\x0b\xae\x1d\x32\x5b\xc8\x1c\xe1\xc6\x7a\x21\xa3\x14\xae\x97\xc0\x7e\x4a\xe8\xa9\x87\xc9\xdc\xd1\xf9\x13\x17\xfd\x60\xf7\x79\xa4\xb2\xc2\xa5\x4b\x98\x42\x98\xe3\x2d\xcc\x79\x87\x44\xcb\x48\xf2\x8e\x5b\xa4\x30\xe7\x09\x66\xb9\xc0\x26\x62\x68\xc8\x3e\xe1\x99\x0f\x29\xe4\x13\x7a\xae\x8d\xc6\x73\xc8\x38\xdc\xc4\x2d\x34\x91\x41\xfb\x07\xb4\xf7\xc1\x78\x33\xcc\xb1\x85\x44\xde\xc8\xbe\x8b\x69\xf5\xd0\x79\x17\xfb\xdf\x87\x79\xec\x79\x83\x99\x86\xb9\xda\x43\x0f\x21\xc3\x44\x31\x93\x12\xee\x67\x85\xe9\x55\xd1\xe2\x17\xf2\x1c\xa2\xdd\x33\x92\x3d\x62\xcf\x3b\x74\x9b\xc3\xa5\x73\xd8\x5d\x91\xc0\x1b\x23\xa1\x96\xc6\x61\xee\x86\xdd\x93\x41\xf6\x6d\x5c\xcb\x47\xcb\x1b\x4c\x6c\x8b\x6e\xf3\x48\xea\x0f\x1d\xcf\x91\x45\x1a\xbb\x59\x60\xfc\x27\x9a\xef\x21\x95\x33\x81\xdf\x46\x2f\x5b\x5c\x74\x83\xbc\x2b\x68\x6c\x85\x56\xd3\xd8\xfd\x0d\x7b\xf9\xc6\x6c\xc3\x5d\xd0\xc0\x6e\x27\x98\xc6\x0d\xa9\x3c\x90\x5e\xa8\x97\x50\xbb\x15\xec\x39\xec\xe3\x3c\xa6\xe4\x23\xb7\x15\x36\x12\x72\xc7\x02\x5b\x0c\xf7\xff\x06\x7d\xbc\x71\x8d\x2d\x92\x0e\xf7\x92\x8f\x6b\x24\xd1\xaf\x50\x3b\x6b\x24\x3b\x47\xd2\x03\xcc\xe4\x80\x7b\x7d\xd0\xcc\x0f\x26\xf6\xc4\x79\x3e\xc6\xf3\x30\x8b\x28\xe2\x0d\x31\xbd\x1e\x26\x9b\xc1\x3c\xeb\x48\x3a\x82\x19\xf4\xd0\x76\x01\x59\x77\xd1\x6b\x16\xb3\xa9\x21\xed\x33\x5a\xae\x21\xc7\x3b\xda\x0f\xb3\x2a\x81\x1d\xb7\xb0\xad\x32\xb2\xac\x62\xcf\x77\x6c\xb2\x82\xcc\xcf\xc8\xd7\x02\x8d\xef\x08\x1e\x6d\x82\x67\x07\x8d\x4e\x90\x42\x04\xe3\x1d\xd0\x6c\x09\xfb\x5e\x63\x23\x27\xe4\xf5\x83\x4d\x4f\x09\xbc\x0f\xa6\x16\x32\xd5\x05\x9b\xc8\x62\x96\x11\x6c\x65\x45\xf0\x49\x60\x5e\x55\x6c\x26\xf4\x44\x0b\x69\xde\x30\xde\x05\xd9\xdd\xd1\x43\x0b\x2d\xc4\xd0\xf3\x0f\xf6\xec\xe1\x5a\x3f\xe8\xf0\x0f\x93\x49\x61\xe2\x3b\xf4\x3c\xc7\xac\x7c\x64\xd2\xc1\xbe\x76\x48\x3e\x8d\xc4\xcb\xa8\xdf\x45\x4a\x6d\x6c\xad\x83\xcd\x9d\xb0\xb1\x1d\x32\x18\xa3\xc3\x03\xb6\x38\xc6\x26\x3f\x04\x7e\xa8\xd3\x24\xb2\x7f\x63\x5f\x4b\x24\xb5\xc7\x9e\xc7\x98\x8e\x8f\xf3\x4b\x48\x36\x87\xab\xf9\x48\x3e\xdc\x48\x71\x5c\x37\xcc\xfe\x15\x2e\xbe\x41\x4e\x7b\xe4\x1e\x45\xef\x3b\x82\x67\x19\xfb\x5a\x11\x78\x6b\x74\xf7\x85\xd6\x17\xd8\xd2\x2f\x92\xf1\xd0\xcb\x0f\x66\xd9\x46\xcb\x67\x74\xf4\x83\x44\xc3\xae\xdf\x62\x63\x63\xe4\xd8\xc3\x34\xda\xe8\x69\x8c\x19\x8c\x31\xbf\xe1\x8e\x09\xcf\x3c\xc3\xb5\x23\x04\xcf\x2a\x7a\x48\x63\x33\x45\x4c\x98\xdb\xfe\x17\x26\x76\x47\xea\x47\xcc\xf4\x86\xf1\x43\x56\xcf\xa3\xb7\x31\xb2\x6f\x22\x95\x70\xa3\xdd\xd0\xe1\x19\xa9\x66\x90\x77\x0d\x37\xe9\xa3\xa7\x1f\xcc\xaa\x88\x7c\xc2\x67\x5d\xb0\xf5\x01\x9a\x6f\xa2\xe7\x6f\xb4\x94\xc1\x7d\xf5\xb1\xef\x1e\x32\xdd\xe2\x1a\xa1\x9f\x7e\xb1\x9d\x2e\xf2\xdc\xa1\xd5\x35\x1a\x9e\xf5\xf1\x44\xfc\x1b\xb2\xcf\x61\x7e\x5a\x98\x70\x1b\x3e\x13\xb8\xee\x15\xd3\xac\xa2\xfb\x32\xb2\xfd\x45\x96\x15\x5c\x3f\x8d\xa9\x7e\xa3\x91\x1f\x64\x3f\xc3\x54\xce\xc8\xfb\x07\x2d\x97\xb1\xa9\x3e\xf6\x33\x40\x66\x0f\x6c\x72\x8f\x79\xb6\x31\xe5\x11\x66\x7d\x43\xa7\x5b\xf4\x7b\x80\xf9\x7d\xa0\xc7\x21\x12\xfb\xc3\xf8\x27\xe4\x93\xc2\xc5\x16\x48\x76\x8d\x3c\xee\xe8\x25\x85\x8e\xc2\x5c\x9b\x63\xb2\x1d\xec\x79\x8b\x99\x3d\xd1\x90\xa3\x6b\x23\x8c\xf7\xc0\xbc\x26\x68\xbe\x88\x84\xfc\xdd\xcc\x61\x27\x4d\x64\x18\x47\xf2\x33\xcc\xab\x8b\x49\x2c\xd0\x57\x9f\xe0\x59\x44\x26\x2b\xf4\xef\x88\x79\x0e\x90\x65\x1d\xc9\xe4\x70\xf3\x03\x81\xff\x41\xe6\x4d\x5c\x7d\x80\xfb\x7b\x12\xdc\x5f\xd8\xdb\x0a\x17\x7a\xbd\x10\xfe\xfe\x8d\x66\x7f\x91\xe6\x00\x3b\xc9\x63\x62\x1b\xf4\x30\x46\x1e\x5f\xd8\xdd\x1d\x79\x86\xfb\xef\x80\x4e\x92\xc8\xfc\x8a\x9e\xa3\x98\xe8\x1b\x9b\x19\xe2\xb2\x67\x6c\x3e\xe4\xbd\x27\x1a\xfe\xcd\x2e\x8a\xa6\x63\x48\x98\xe9\x1d\x0f\x19\x36\x90\x5d\x02\x39\xe4\xb0\xb7\x38\x7a\x1f\xa3\x85\x2a\xc1\xfd\x81\xcd\x86\x3a\x0d\xfd\x1e\xb2\x55\xc8\x7c\x0f\x34\x73\xc6\x8c\xa2\xe8\x64\x81\x0d\x33\x3c\xd5\xc0\x5e\x66\xe8\xbd\x81\xd4\x37\xe8\xd7\x1f\x6e\xd2\x42\xe6\x0d\x5c\x3d\x49\xe0\x1f\xb1\x9d\x12\x26\xdc\x8a\x8b\x07\xc1\xa3\x8c\x29\x17\x31\x8d\x13\x3a\x2e\xe0\xa2\x17\x24\x19\xc5\x75\x53\xd8\x6f\x8f\xc0\xaf\xe3\x36\x65\x5c\xa3\x82\x76\xea\xe8\x7e\x8b\x24\x9f\xb8\x6e\x05\x33\x29\x62\x2f\xbf\x68\x7e\x85\x7c\x46\xd8\x58\x1c\xf3\xbc\x63\xb2\x17\x34\x37\x41\x8a\x5d\xe4\xb6\x44\xa6\x27\x24\x99\x40\x07\x7d\xec\x76\x87\xdd\x75\x31\x93\x25\x66\x3e\x47\x87\x3b\xdc\xf8\x82\xdc\xc6\x98\xe1\x1a\x8d\x1d\x31\xd1\x02\xee\x9d\x20\x78\x2e\x30\xf3\x15\xb2\xf3\xd1\x71\x0c\x57\xf7\x90\xfe\x14\x8d\x56\xd0\xe8\x1e\x17\xaf\x62\xaf\x53\x34\xf7\x87\x2d\xd6\xb0\xc9\x37\xf6\x7c\x46\x87\x0d\xd4\x3f\x63\x0a\x3d\x5c\xbb\x81\x7d\xa7\x90\x85\x8f\x8c\x7f\xd1\xda\x0c\x89\xad\x30\x9b\x37\xae\xf5\x40\xb3\x7b\xcc\xf9\x17\x33\x8a\xe1\xfe\x6f\xa6\x32\x52\xc9\xe1\x3a\x57\x82\x67\x05\x69\xc6\x30\xcd\x16\xa6\x7e\x45\xd6\x29\x34\xd7\xc5\xa6\x63\x68\xf5\x8e\x7c\x8a\xd8\xce\x1b\xdb\x1f\xe3\x62\x3e\x36\x7e\x47\x6e\x6b\xb4\x30\x43\xa2\x57\xe4\x19\x47\x97\x2f\x24\x77\x24\x78\x9c\x70\xb1\x3a\x52\xc9\x12\xf8\x51\x4c\x3c\x86\x19\x35\x31\xcb\x21\xc1\xa3\x80\xcd\xec\x09\x9e\x67\x4c\xbd\x8f\x5e\x92\x04\xf7\x0e\xda\x8d\x61\xd2\x73\x74\x1d\xe6\xd7\x09\xfb\xb9\xa1\xdd\x90\x2f\x0b\x98\xe5\x12\x1b\x4f\x61\x77\x0b\xcc\x7e\x89\xbd\x97\x31\xf5\x1b\x76\x7f\x40\xaa\x29\x64\xfb\xc6\x9c\x72\xe8\xb9\x87\x7d\x67\xd1\xc4\x0c\xf3\xfb\x8d\xeb\x76\xd0\x48\x0d\x73\x6c\x13\x3c\xc2\x2d\xfe\x83\x8d\xad\x31\x87\x22\xfa\x55\x46\xaf\x31\x4c\xaa\x83\xe9\xa6\x08\xde\x0b\x34\xf6\x87\x96\xda\x04\xde\x2f\xc6\x1b\xe1\x52\x35\x4c\x3e\x86\x6b\x44\xd1\x5b\x04\x8d\xae\x30\xd9\x23\xae\x7f\xc7\x64\xfe\xb0\x97\x32\x2e\x92\xc2\x94\xd6\xb8\xce\x05\x33\x1f\x60\x96\x35\xf4\xd2\xc1\x1e\x0b\xc8\xeb\x81\xbc\x9e\x68\x2c\x8b\xbb\x6f\xb0\xd7\x3c\x92\x9e\xa1\x9d\x15\xe6\x7f\x1e\x65\x30\xcb\x90\x63\x2e\x98\xd7\x11\x9d\xec\x30\xb1\x12\x1a\x66\xde\x34\x8f\x5b\x1f\x30\x9b\x1e\x72\x1a\x23\xa9\x1a\x12\xee\xd9\xdd\x07\xbb\xab\xa2\x97\x3b\x7a\x0a\xf9\xfd\x85\xfd\x0c\x31\xe3\x24\xa6\x99\xc2\x9e\x6f\xe8\xb3\x8c\x59\x7d\x90\xd4\x08\xf9\x5d\x63\xe3\x51\x6c\x6e\x87\xc9\x4e\x90\x72\x0f\xdb\x8d\x20\xf3\x39\xee\x3e\x45\x8e\x1b\xcc\x3b\x87\xa4\x37\x04\xf7\x23\x32\x6e\x63\xfc\x36\x2e\x79\xc1\x7e\x17\x31\xbd\x14\xae\x31\x46\xbc\x0e\x66\xf3\x40\x52\x3e\x36\xdc\x9b\xd5\x04\x76\xb2\xc1\x6c\xf2\x68\xbe\x86\xc4\xbb\x68\xeb\x80\xab\xbd\x71\xf7\x21\xfa\x4c\xa1\xc7\x0c\xa6\x9f\xc5\x34\xcb\xe8\xcd\x47\xa7\x35\xcc\xba\x85\x19\x0f\x70\xc3\x35\x2e\xf2\x44\xb3\x1b\x82\xf7\x0a\x49\x67\xd1\x82\x87\x99\xb4\xd0\xd1\x0b\x13\xab\xa1\x83\x1d\x1a\x9b\xe2\x16\x65\x24\x37\xc0\x1e\x7e\xb0\xef\x17\x92\x8f\xe3\xee\x1f\xb4\xb5\x40\x2a\x61\x46\xf6\x31\x21\xa7\x0f\xf3\xd8\x77\x0e\x0d\xef\x63\xbe\x45\x2b\x7f\xb8\x9f\x18\xf6\xfd\x8d\xe4\xc3\x1c\x9b\x12\x3c\xf7\xd8\x5a\x1e\xe3\xd7\x70\xbd\x37\xc1\x3d\x64\xb0\x0b\xb2\x4c\xa1\xf9\x21\xb2\x4d\x63\xdf\x55\x5c\xe7\x0b\xd7\xfb\x42\x42\xee\xab\x27\x90\x73\x1a\xc9\xfe\x20\x91\x31\x52\x4a\x22\xb5\x3f\xdc\xfa\x8a\x6d\xee\x90\xcc\x0d\x6d\xce\x31\x5f\x3f\xd8\x4b\x1e\x99\x67\x09\x5e\x3d\xf4\x92\x46\x9f\xbf\x68\x2f\x3c\x67\x1a\x57\xeb\xa0\xe3\x38\x9a\xbd\x12\xf8\x0d\xec\xa7\x41\xf0\x69\x11\x78\x65\x6c\xb2\x81\xfb\xce\xa3\xd3\x03\x76\x91\x42\xc7\x29\x34\x96\x40\xca\x0d\xb4\xf6\x8d\xfb\x69\x21\xf9\x36\xda\xf2\xd0\xe3\x1d\xd9\xcc\x90\x4a\x05\xd9\x0c\xd1\xfb\x08\x39\x64\x30\xcd\x37\xb2\xe8\xa0\xf1\x3e\x81\xbf\xc7\xe4\x47\xd8\x78\x04\xbb\xaf\xa0\xb9\x1e\xae\x9f\x45\xc7\x55\x24\xe4\xcc\x76\x0f\x3b\xde\x63\x7a\x2d\xf4\xde\xc2\x26\xca\xd8\x4b\x13\xbd\x16\x30\x8d\x3e\xda\x7b\xe0\xda\x49\x6c\xac\x80\xd4\xd7\x48\x29\x8b\x89\xc7\x31\xde\x1f\xba\x4b\xa2\xed\x15\xc1\xf3\x07\xd3\x4a\x63\x92\x5b\xa4\xfc\xc0\xd5\xb2\x68\x65\x83\x2d\x94\x30\x7f\x4f\x5c\xf2\x86\x44\x6f\xc8\xb3\x8e\x6b\xcc\xd1\x68\x78\xa7\x7b\x64\x50\xc5\x3d\x7d\xcc\xe7\x89\xf1\xae\x48\xb9\x83\xc9\x1f\x70\x91\x2d\xe6\x55\xc1\xf8\x7d\x74\xda\x45\x73\x55\x6c\x6a\x85\x6d\xfc\x21\x3b\x0f\xf7\x33\xc3\xac\x53\x48\xea\x8a\x7e\xef\x90\x54\x01\x09\x77\x5a\xfa\x8e\xf1\x93\xc8\x20\xd4\xb8\x87\x49\xec\xb1\xaf\x3d\xfa\x37\x45\x3b\x79\x4c\x7b\x81\xbc\xc7\xb8\xc6\x06\xd7\x58\x10\xdc\x97\x68\xeb\x0f\xd7\xf0\x91\xef\x04\x5a\xe9\xa3\xd9\x2a\x2e\x16\x21\xf0\x36\xb8\xe4\x0e\xfb\xc9\x60\x33\x35\x6c\x22\x85\x4b\x5e\x71\xad\x23\xf2\x59\xe2\x92\x5d\xdc\xf8\x85\x79\xbf\xd0\xeb\x0a\x29\xde\x09\xfc\x16\xae\x13\x6a\x73\x88\xc6\xd7\xe8\x60\x83\x2c\xbb\xd8\x58\x17\x2d\x66\x71\xd3\x36\xfa\x8c\xa1\xed\x14\xfa\xe7\x21\x95\x37\x2e\x5e\xc2\xc4\x6f\xe8\x21\x8a\x54\x2f\xb8\xf9\x1e\x5b\x59\xe2\x7a\x49\x5c\x6c\x8b\xfd\x44\x31\xe9\x2f\xb4\x56\x43\x96\x3e\xf6\x72\x46\xb6\x67\x4c\x7c\x81\x44\x3c\xe4\x5e\x41\x9b\x55\x5c\x3d\x8e\xb6\x56\xb8\x54\x1a\x5b\x9d\xe2\xc2\xad\xd2\x0b\x39\xf6\x83\xe6\x0b\x48\x2c\x89\x4d\x3e\x90\xc5\x1c\x2d\x67\xb1\xe7\x19\x9a\x4f\xa1\x9b\x1f\x6c\x75\x8c\x8d\x7b\x04\xf7\x09\x7a\x59\x23\xe1\x99\xda\x31\xe4\xfb\x17\x2d\x8c\xb1\xcb\x0c\xf6\xfc\x83\xfe\x67\x98\x33\x7a\x08\x7f\x2e\x20\xa9\xb0\xd7\x3c\x64\xd9\xc7\xee\xc3\xec\xb8\x22\xb9\x70\x5f\xff\x61\xc3\x9d\xd6\x2e\x63\x43\x26\xef\x65\x70\x3f\x55\x82\x47\x03\xf5\x7e\x08\xee\x3d\xa4\x38\x41\x73\x0f\x5c\xeb\x86\xd4\x56\x48\x66\x8b\x5b\xbf\x31\x61\x5e\xc4\x86\x68\xb5\x8d\xab\xd7\xd0\xd2\x0d\x37\x49\x23\x0f\x1f\x1d\x26\xd0\xf8\x08\x8d\xaf\x08\x5e\x27\x02\x3f\x8d\x4d\x86\x8c\x36\x40\xaf\x33\x24\x5b\xc5\x7c\x2f\x91\xd1\x18\x3d\x3d\xb1\xd5\x03\xe6\xb5\xc6\xf5\x8b\x68\xf1\x1b\x1b\x2f\x61\xf3\x45\xd4\x0f\x39\x7c\x8d\x16\x93\xe8\xa3\x8d\x19\x15\x71\xfd\x6f\x5c\xec\x82\xad\x24\x30\xcd\x1d\x7a\x0b\xf7\x4d\xd8\x0b\x39\xcc\xf1\x07\x13\x6f\x23\xdb\x0f\x3a\x9e\xa2\x99\x0c\x6e\x7d\x42\x7e\x63\xd8\xe9\x17\xf2\xee\x60\xb6\x1b\xb4\x58\xc1\xc6\x46\x68\xad\x8a\x76\x6a\xd8\xf7\x0a\xdd\x7e\xb0\xa5\x23\x5a\xcd\xa1\x95\x24\x2e\x79\x40\x0e\x65\x4c\xf3\x17\xa9\x47\xb0\x61\xa6\x8e\x2e\xe8\xf1\x17\xd3\x3d\x60\xbe\x92\x48\x79\x84\x6b\x47\xb1\xa5\x03\xfa\x75\xc4\xbe\x9b\xb8\xda\x1a\xd3\x0a\x77\xd2\x00\xb9\xdd\x70\xf3\x0f\x66\x7e\x27\xb8\xb7\x31\xa5\x04\xea\x85\x5e\xdd\xe3\x22\x3e\xf2\xda\x20\xfb\x70\xdb\x7d\x90\xc5\x0a\x9b\x4d\x23\x95\x6f\xdc\x70\x81\x46\x56\x98\xe1\x16\xdd\xa4\xf9\x17\x00\x00\xff\xff\xbf\x1b\x72\xe3\x00\x20\x00\x00") +var _keysWordlistChinese_simplifiedTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x1c\x97\x55\x76\xeb\x30\x14\x45\xff\xf7\xa8\xc3\xcc\x49\xc3\x69\x98\xda\x86\xd9\x0e\x4c\xc6\xf7\x4a\x9a\xc5\x5b\x7e\x7f\x5d\x5d\x6d\x6c\x45\x07\xf6\x31\xdd\x04\xc1\x3d\x82\xb6\x77\x48\x7f\x45\x70\x2f\x12\x78\x29\xb4\x9f\x45\x6a\x05\x02\xcf\xc3\x7e\x3a\x04\xf7\x0d\x32\x5b\x12\xdc\x3d\x82\x7b\x8e\xe0\xfe\x83\xf4\x5e\x68\xa6\x4a\xe0\xcf\xb1\x8b\x28\x81\xdf\x44\x5b\x57\x74\x30\xc7\x34\x56\x04\xfe\x1f\xa6\x31\x44\x32\x7b\x82\x57\x1f\xe9\xef\x09\xbc\x12\x92\xf6\x90\xfd\x01\xc9\xa4\x90\xdd\x03\xcd\x54\x08\x9e\x5d\xa4\xbc\x23\xb8\xfb\x48\xb9\x8a\x3c\xce\x48\x6e\x85\x54\x0a\xc8\x6d\x4e\xf0\x18\x62\xe3\x2f\x82\x7b\x1e\xfb\x49\x23\x9b\x0a\x76\x77\x26\xf0\x96\x98\x65\x11\x37\x98\x60\x23\x05\xb4\xf9\x40\x2a\x25\x64\xd6\x45\xb6\x5d\xec\xb8\x80\x6c\x16\xe8\xe9\x0b\xcd\x46\xd0\x7d\x15\x79\xb7\x30\x7e\x19\x29\x46\x09\xee\x59\x82\x47\xf8\x99\x3d\xcc\x20\x82\xd9\x64\x71\xf1\x15\xe2\x2d\x90\xed\x15\xd3\xb8\x20\xb9\x1e\x2e\x5d\x40\x16\x31\x74\x7f\x46\x0a\x4d\xdc\x6f\x1b\x9b\xfe\x21\xf0\x0a\x98\x4a\x0a\x7b\xb9\x21\xfb\x32\x26\xbb\xc6\x94\xf6\xc8\xf6\x1b\xc9\x8d\x70\xe9\x32\xee\xff\x7b\xcf\x08\x5e\x75\x24\x73\x45\xfb\x1e\xf2\xaa\x13\xbc\x3e\x98\xd8\x83\xc0\x2f\x11\xdc\xbb\x68\xff\x0f\x29\xf9\x68\x2e\x87\x46\x96\xc8\xfc\x85\x78\x0d\xe4\x19\x41\xb6\x71\xa4\x92\xc1\x7e\xda\x48\x6f\x84\x69\x1c\x90\xe4\x95\xc0\xeb\x61\x12\x57\x24\x5b\x44\x66\x4d\x64\xb6\x46\x1b\x1f\xa4\xd7\x43\x5b\x73\x5c\x6c\x8a\x99\xbd\x09\x1e\x59\x02\x2f\x8f\x3c\x4e\xc8\x6b\x82\xe9\xdd\x91\xe4\x0a\x3b\x5e\xe1\x5a\x67\x74\x74\x23\xb8\x97\x90\xe4\x09\xa9\x24\x70\xe9\x22\xda\xdc\x63\xbc\x0f\x92\x4a\xa2\x5f\x7b\x74\x33\x45\x3e\x71\xa4\x5c\x24\x78\x8d\xd0\x76\x09\xd3\xcf\x23\xa5\x21\x52\xce\x10\x3c\x32\x48\x66\x8d\xee\x1a\x68\xa6\x49\xf0\x4a\x61\xcf\x2b\x74\xdf\xc0\xfc\xfd\x21\x95\x2a\x2e\x5a\x47\xaa\x2f\x74\x33\x43\xca\x6d\x74\x30\x46\xca\x3f\xe8\x71\x8c\xf1\xeb\xd8\xe5\x14\xd7\xda\xa2\x89\x32\xe2\x7b\x68\x3f\x83\x24\xff\xd0\xd6\x08\x73\xf2\x91\x54\x0f\x79\x67\xd0\x78\x12\x1b\x49\xa2\xfd\x08\xe6\x37\x4f\xe0\x4f\xd1\xf8\x09\xb9\x1d\x71\x91\x2e\xf2\xb8\xa2\xe5\x0a\xa6\x77\xc6\x4d\xda\x48\xb2\x8b\x59\xe5\x91\xc3\x17\x81\xd7\x40\xbf\xfb\x68\xb3\x83\x3d\x8c\x91\x6a\x1b\x37\x58\x13\xbc\x8a\x48\x72\x8e\xdc\xef\x68\x33\x8d\x46\x7c\xf4\x6f\x8c\xd4\xa3\xc8\xb3\x8c\x9e\x7d\xec\xf6\x8d\x94\x73\x98\xed\x18\x93\x0d\xef\xee\x8a\xfb\xfa\xa0\x87\x18\x36\x12\x45\x66\x67\x64\xe8\x61\x2f\x09\xec\xfb\x81\x5e\xa2\xd8\xdb\x0e\xe3\x2d\x91\x50\x7b\xbd\x37\x72\x38\x60\xfc\x21\x5a\x9a\x63\x86\x73\xec\x3b\x8e\xec\x53\x18\x3f\x81\x5d\x46\xb1\xdb\x31\x92\xf9\x45\xe6\x0f\x34\x9b\xc7\x2e\x6b\x68\x7f\x88\x8e\x1e\xd8\x6d\xe8\xc7\x0a\x92\xea\xa3\x85\x34\x92\x1e\x11\x3c\x06\x48\xc1\x43\x9e\x1e\xda\x78\x23\xa9\x13\x76\xfe\xc1\x4e\x7e\x91\xc7\x11\x89\x76\x91\x4f\x12\xcd\x84\xdf\x43\x06\xe9\x7d\x23\x99\x0e\x81\x1f\x7a\xad\x89\x16\xb7\xc8\x2c\x81\x6b\x0f\x91\x62\xe8\x8d\x0e\x36\x7b\x44\x92\x59\x5c\x6b\x85\x14\x4f\x04\x9f\x01\x7a\xf4\x91\x42\x0b\x17\x19\x61\x3a\x6f\xec\x32\x81\x89\x6f\x70\x93\x14\xc1\x3d\x8e\x86\x1e\x28\x4f\x09\xee\x7d\x64\xf7\x44\x3a\x2b\xa4\x94\x47\x3e\x2d\x82\x7b\x13\x97\xae\x22\x93\x6f\x02\x2f\x8b\x5e\x4a\xb8\xf6\x15\x3d\x3e\xd0\xc8\x00\xed\xef\xd0\xef\x28\x81\x17\xea\xa2\x85\x8d\x36\x08\xfc\x08\x76\x3b\x43\x92\x1b\x24\x79\x40\x07\x71\xb4\x71\xc5\xee\xa2\x68\xe3\x81\xde\x93\x98\x77\x09\x49\x15\x71\xe9\x34\xf6\xf5\x87\xf6\xce\x48\xf1\x0b\x37\x2d\x21\x99\x34\x9a\xad\x63\x3a\x2f\xf4\xab\x83\x8b\x0c\xb1\xb9\x03\x72\x0f\xbd\x9d\x45\xfa\x1e\xd6\xfb\xc5\xbe\x16\x04\xef\x3c\xa6\x3f\x44\x72\x63\x24\x19\x7a\x21\x8d\xee\xca\x98\xde\x16\x9b\x3e\x61\xdf\x6f\xec\x65\x8f\x59\xee\x30\x33\x0f\xbb\xdd\x22\xd3\x3d\x9a\x9b\xa3\xcd\x16\xb2\x2d\x60\x0e\x3e\x92\xfc\xc5\x2c\x7c\xa4\x58\x42\x2a\x45\xcc\x78\x8b\x66\x8b\x98\x65\x15\x79\x8e\x08\x3e\x63\xdc\xfa\x0f\x9b\x8b\x61\x77\x03\xcc\xe1\x84\x7e\x9d\x31\x6b\x0f\x49\xc6\x91\xd4\x85\xc0\xcf\xe1\x7a\x29\xf4\xbe\x26\x78\x8e\x90\xfe\x10\xbb\xbd\xa3\x9b\x39\xe6\x3d\x43\x1e\x1f\xcc\xf0\x84\xdd\xee\x71\xfd\x08\xba\xbd\x60\x46\x0d\xcc\x57\x01\xcd\x67\xd1\xef\x16\xf2\xce\x23\xe5\x5f\x82\x7b\x03\xb3\xbe\x62\x97\x31\xec\x35\x87\xf1\xd3\xd8\x69\x12\x79\x1d\x30\xdb\x16\xc1\xab\x84\x16\xa2\xb8\xe1\x89\xe0\xd9\x22\x78\x2c\x90\x7b\x1c\x99\x15\x91\xed\x03\x49\x7c\x70\x63\x1f\xd7\x49\x22\x5f\x29\xdc\xe0\x1b\xf7\x53\xc0\x7e\xbe\xd1\xe6\x06\xbd\x1d\x70\xdd\x37\xf6\x53\xc5\x0c\x3f\x48\x31\x8e\x54\x57\xc8\xb2\x81\x39\x8f\xd0\x5c\x04\x99\xa5\x91\x62\x0e\xc9\x7d\xe3\x06\x35\x4c\x3f\x8a\x64\xc2\x67\x8d\x90\x7a\x11\xe3\x2d\xd0\xc6\x0e\x9b\xf9\x43\xca\x47\x34\x11\xde\xc3\x89\xe0\x1d\xe6\xd8\x04\x79\x47\x70\xc9\x3b\x52\x4a\x21\xf7\x18\x92\xcc\x13\xbc\xbe\x70\x9d\x19\x7a\xcd\xa0\xdf\x09\xc4\xeb\x63\x96\x7b\x64\xf6\x83\xa4\x53\x98\xe3\x1b\x89\x3c\x91\xf2\x0d\x53\x4a\xa3\xad\x32\xc6\x3f\x23\x99\x1a\x2e\x92\x45\x47\x69\x24\xd5\x41\x36\x6d\x24\xd2\x41\x77\x3d\x02\xef\x88\x7c\x7e\xd1\xaf\x0c\xda\xdc\xe1\x3a\x13\x74\x38\x47\x0f\x43\xe4\x3b\xd4\xc7\x13\x53\xca\xa3\x85\xf0\xff\x9f\x48\xd2\x47\xdb\x75\xcc\x6b\x8b\x9e\x43\x5f\xc7\x30\xd9\x34\xb2\xcc\x23\xc5\x33\xc1\xbd\x8e\xc9\x5d\xb1\xb1\x23\x52\x8a\x11\x78\x7f\xd8\x5d\x0a\x17\x89\x21\x87\x6f\xa4\x9f\x42\x0a\x49\x4c\xf4\x97\xe0\x55\xc6\xee\xe3\xa8\x3f\x46\x4a\x1f\xe4\x10\xc1\x24\x97\x48\x39\x86\xf1\x26\x18\x3f\x85\x3c\xbf\x90\x4a\xf8\x19\x73\x5c\x3d\xec\xdb\x50\xa7\x73\xdc\xa2\x89\x78\x5f\xe8\xf5\x88\x6c\xdb\xc8\xfb\x86\xeb\x96\x31\xad\x24\x36\x5f\x46\x66\x07\x64\xdf\x40\x37\x61\x7e\x1d\x71\xc9\x22\x32\x3f\xe1\xfc\x04\x5a\x5a\xa1\xed\x37\x76\x9f\xc1\xbc\x7e\x30\xf3\x6f\x6c\xd6\x43\xaa\x13\x24\xec\xfc\xca\x2f\xc1\x33\x8a\xf6\x7b\xc8\x2e\x85\x66\x1f\xd8\xca\x1c\x37\x7e\xe0\xda\x47\x82\xfb\x1b\x53\x89\x63\xf3\x07\x74\xbf\x44\x72\x1f\xa4\x9a\x43\x07\x25\xa4\xbc\xc7\x56\x5e\x68\x7f\x85\xdc\xb7\xd8\xd7\x16\x33\x0a\x3b\xbb\x8b\xdc\xc3\x1c\x3a\xa3\xa7\x15\xf6\xd3\x47\x36\x2d\x74\x50\x41\x4b\x35\x82\x77\x0f\x3d\x9e\xd0\x30\x4f\xf7\x51\xa4\xbc\x40\x9b\x2f\x24\x5d\x46\x47\x55\xd4\xbb\xa2\x91\x12\xba\x99\xa0\xe3\x0c\x76\x15\x41\xa6\xbf\xc8\x20\x8d\x6e\x16\x48\xcf\x43\xca\x57\xdc\xe1\x89\x9e\x26\xd8\x65\x8a\xc0\x4f\x62\xcf\x0f\xcc\x79\x89\xc9\x1c\x90\xdb\x02\xf3\x3b\x42\x5b\x6b\xb4\x3f\x40\xb6\x27\x8c\xbf\xc1\xbe\x7c\xb4\x5f\xc4\xee\xc2\x0c\x19\x22\xc9\x24\x92\xbc\xa0\x5e\x05\xc9\xcc\xd0\x5c\x98\x4f\x77\xec\xf5\x84\x0e\x2b\x18\x3f\x8e\xdc\xc2\x8c\x38\xa3\x83\x0f\xa6\xb1\xc7\x75\x8a\x38\xbf\x8a\xc9\xed\xb0\xe7\x21\x92\xf6\xb1\x85\x38\xc6\x5f\x22\xc9\x33\xc1\xf3\x49\xf0\xea\x20\x83\x2e\xda\x3b\x62\xdf\x75\x82\xcf\x16\xfd\x4a\x22\xc3\x90\x5d\x7e\x91\xd9\x10\x17\x89\x62\xfe\x1a\xd8\xcc\x03\x29\x8e\x90\xf2\x09\x7b\x9e\x20\x95\x38\xb2\x2b\xa0\xed\x39\x36\x5a\xc0\x2e\xb3\xe8\x21\x8b\x69\xf8\x48\x6e\x88\xdc\xce\xd8\xdb\x10\x1b\xe6\xde\x20\x86\x9b\x7e\xa3\xd3\x08\x52\xb9\x23\xb9\x35\x52\x4c\xe3\xda\x27\x02\xaf\x86\x64\x06\x48\xa6\x87\xe6\x5a\xd8\x48\x1c\xcd\x7d\x21\x83\x32\x66\xd3\x44\xca\x33\xe4\x9d\x40\x8b\x13\xb4\xff\x83\xbd\x55\x31\x61\x8e\xd6\x26\x68\xef\x8d\xf9\x0d\xcf\x37\xc5\xfc\x76\x30\xdb\x08\xf6\xb3\xc7\xd5\x0e\x48\x76\x87\xec\x5f\xc8\x7d\x80\xec\x13\xd8\x62\x16\x49\x1d\xd1\xec\x07\x93\xff\x23\xf0\x67\xb8\x4e\x05\xd7\xfe\x20\xdb\x29\xa6\xb4\x43\xca\x05\xec\xee\x86\xbd\x26\x91\xf7\x16\xbb\x5d\xa3\xa5\x25\x72\x0b\xf5\xb8\xc3\xbe\xce\x68\xf6\x8d\x54\x16\x18\xef\x07\xd3\xcb\x11\xbc\x07\x04\xcf\x36\x6e\x7c\xc5\x8c\x23\xd8\xd7\x0b\x89\xd4\xd0\xcc\x07\xf3\x13\x45\x06\x15\xcc\x31\x8b\x7e\x15\x30\x5f\x73\x64\x3b\xc1\x4e\xa2\x48\xea\x86\x8d\xf7\x31\xfe\x00\xfd\xae\x20\x83\x16\x92\x8d\xa1\x97\x3c\x41\xf8\xce\xc5\x32\x76\x97\x45\x3e\x17\x5c\x27\x43\xe0\x17\x31\xaf\x16\xa6\x57\x41\xca\x79\xf4\x9c\xc7\x35\x3a\xd8\xfc\x02\x99\xf5\x91\x4c\x15\xb3\xf4\x71\x93\x2a\x2e\x52\xc1\x0d\x46\xe8\xed\x86\xee\x8a\x98\xe1\x06\xd3\xdd\x62\xfc\x0c\x36\xda\x45\x0f\xe1\x9d\x54\x09\xbc\x2a\x52\xff\x41\x5b\x13\xec\x2d\x7c\xe6\x2f\x12\xed\x63\xe2\x19\x64\xb6\x45\x76\x43\x4c\x7c\x89\xfd\x24\x91\x49\xe8\xaf\x39\x52\xdc\xa3\xe7\x23\x92\xf1\xd1\xfc\x1f\xfa\x89\x20\x9b\x06\x5a\xf9\xc6\x34\x42\xde\x0d\xef\x2b\x89\x8e\xee\xe8\x68\x8c\x7e\x4d\x09\xde\x17\xa4\xb2\xc4\x34\x8e\xe8\xfd\x4e\xf0\x48\x62\xcb\x7d\xa4\x7a\x42\x5b\x4b\x74\x35\x46\x1f\x4d\xec\x79\x89\x16\x87\xb8\x49\xc8\x01\x3e\xba\xfb\x45\x3b\x5b\xcc\xea\x44\xf0\xe8\x20\x8b\x0c\x3a\x2b\xa2\xd1\x1d\x9a\x5d\xe3\xea\x61\x0f\x6f\xd0\xc2\x1c\x97\xac\x21\xdb\x0c\x9a\xff\x20\x5e\x19\xe3\xdd\x91\x82\x8f\x79\x7a\xb8\x5e\xc8\xf0\x2d\x5c\x2d\x64\xc3\x36\xf2\x15\xb2\xed\x1c\x69\x1c\xb0\xbb\x1d\x76\xbb\x41\x13\xa1\x0e\xc6\xb8\x4e\x02\x5b\xba\x61\x0b\x57\xdc\xb1\x8f\x39\x6e\xd1\xe6\x0c\xd9\xac\xb1\x89\x03\x66\xfc\x8b\x8d\xcd\x91\x66\x02\xf7\xee\xa0\xcf\x06\x26\xe4\xe9\x7b\x05\x3b\x8e\xa0\x7f\x13\x74\xb2\x47\x4b\x05\x74\x53\x40\x8f\x1d\x24\xd3\x45\x1b\x3e\x76\x5f\xc7\xf4\xde\xd8\xed\x0a\xed\x74\x31\xc7\x1a\xc1\xe3\x80\x49\xc7\x31\xc3\x1e\xc1\xa3\x84\x0e\x22\xd8\xe2\x0e\xd9\x46\x71\xc7\x28\xf6\x7c\xc1\xd5\x86\x98\xe4\x0c\xbb\xf3\x31\xe5\x0d\xc1\x73\x87\x5b\x84\xec\x14\x6e\x86\x5f\xa4\x3c\x27\xb8\xef\x91\xe1\x03\x2d\x87\xec\xb0\x47\xf3\x49\xe4\xb9\xc0\xf6\xf2\xe8\x31\x8b\x44\xd3\x98\xf5\x07\xcd\x2e\x31\x9b\x06\xc1\xa3\x82\xdd\x47\x71\x63\x0f\x13\x1f\x62\x9e\x6b\xe4\x1d\xc5\x26\xee\x48\xb3\x8f\x0e\xde\xd8\x44\x17\xe9\xed\x91\x67\xd8\x77\x45\x6c\x3c\xf4\xfb\x10\xb3\x28\x13\x3c\xf6\xe8\xb0\x4e\x10\x66\x7e\xb8\x49\x92\x13\x34\xf2\x85\x99\x46\x91\x48\x11\x33\x6f\x62\xba\x69\x82\x4f\x1c\x37\xe8\x60\xc7\x73\xec\x2e\x81\xf9\xf8\xd8\x58\x16\x7b\xbb\x20\xfb\x27\x76\x3c\x45\xb6\x2f\x34\xfb\x87\x4e\xb3\xc8\xbd\x40\xf0\x9c\xa1\xf5\x22\xf2\x1d\xc3\x84\x3d\xb6\xed\xa3\xfb\x09\x32\x6f\x61\x06\x53\xb4\x10\x72\x5a\xb8\x3b\xb6\x68\xff\x17\xd9\xfe\x20\x5e\x0a\xf3\x6c\x62\xb2\x3d\xec\x72\x81\xb6\x47\xb8\xde\x0d\xd7\x88\x60\x77\x2d\x24\x64\xdf\x43\x12\xcd\xd5\xb1\xd3\x18\x36\xfe\x8d\x54\x9f\xc8\xaa\x8d\x76\x76\xc8\x2a\x8a\xf1\x3f\x68\xe7\x8a\x94\xba\x98\xde\x10\x3b\x1e\xe3\xee\x63\x64\xd3\x41\xfc\x2b\x52\x3c\x60\xe3\x57\xe4\x90\x27\x78\x8c\x09\xee\x67\x5c\x27\x85\x1b\xbf\xd1\x52\x16\xa9\x46\x30\xd1\x1d\x72\x8c\xa2\xa5\x1f\x74\x30\xc4\x46\x2a\x48\xf8\x9d\x97\xb2\xd8\xcb\x05\x7b\x3b\x21\xf5\x39\xb2\x99\x62\x77\x6f\x24\xbd\xc3\xc6\xc7\xb8\xc9\x00\xfd\x7b\x63\xfc\x22\x52\xbc\xe1\x5e\xe1\x1e\x1d\x62\x6b\x77\x74\xdb\x44\xf7\x77\x64\xdb\xc2\xe6\x5b\xc8\x6d\x80\x89\x65\x91\xe3\x1a\x79\x1e\x70\xbd\x70\xef\xae\x90\x79\x19\x3d\x7e\x70\xfd\x23\x3a\x48\xa1\xa5\x09\xea\x57\x71\x5f\x69\xdc\x7c\x83\x5e\xea\xd8\xcc\x0f\x1a\x89\x60\x2f\x57\xc4\xab\x23\x33\x8f\xe0\x99\xc3\x44\x2f\x98\x55\x09\x17\x69\x60\xa2\x1b\xec\xa5\x87\xbc\x6a\x48\xf9\x0f\xf7\xac\xa3\xb5\x0d\xa6\xd7\xc6\x4e\xa3\xb8\xce\x1a\xf1\x6e\x48\x63\x87\xbc\xbe\xb0\xe5\x02\xc6\xdb\x21\x91\x21\xe6\xd4\xc4\xf4\x9a\xe8\xea\x07\xf3\xb7\xc0\x2c\xa3\x48\xee\x07\x19\xc5\x90\xe1\x10\xfd\xfe\x41\xaf\x0b\xe4\x91\x44\xea\x19\xcc\xef\x10\x93\x0a\x7b\xe2\x17\x3d\xbd\xb0\x89\x2a\x32\x9d\x61\x26\x27\xf4\x6f\x89\x8b\x16\x09\xde\x4b\x64\xb7\x42\xbf\x26\xc8\xcb\xc7\x76\xaa\x68\xb3\x8f\x6d\x86\xcc\xb5\xc1\x78\x27\xe4\xf9\xc0\xcd\x8f\x04\xcf\x3b\x9a\x6b\xe3\x42\x9e\x7b\x7c\xd0\x6e\x0b\x5b\xbc\x61\xea\x0b\x64\xfc\x8d\x78\x39\xcc\xa6\x8a\x46\xaf\x68\xe6\x86\xdd\x7e\x90\x71\x03\x99\xa7\x71\x91\x32\x1a\x66\x73\x26\x82\xb6\x42\x6f\x85\x9d\x37\x46\xf7\x3b\x5c\x34\x4d\xe0\xbf\xd0\x5d\x0d\x3d\xcd\x71\x91\x08\x7a\x6e\xa1\xd5\x14\x26\xba\x47\x5e\x61\xa7\x35\xb1\x91\x16\x32\x2b\xa3\xf9\x35\xf2\xe9\xe0\xea\x7d\x4c\x61\x8b\x19\xff\x11\x78\x19\xcc\x23\x8a\xf4\x33\xb8\x5e\xc8\x88\x2f\x82\xf0\x3d\x73\x2f\xcc\x2e\xec\xc3\x0b\xae\x1d\x32\x5b\xc8\x1c\xe1\xc6\x7a\x21\xa3\x14\xae\x97\xc0\x7e\x4a\xe8\xa9\x87\xc9\xdc\xd1\xf9\x13\x17\xfd\x60\xf7\x79\xa4\xb2\xc2\xa5\x4b\x98\x42\x98\xe3\x2d\xcc\x79\x87\x44\xcb\x48\xf2\x8e\x5b\xa4\x30\xe7\x09\x66\xb9\xc0\x26\x62\x68\xc8\x3e\xe1\x99\x0f\x29\xe4\x13\x7a\xae\x8d\xc6\x73\xc8\x38\xdc\xc4\x2d\x34\x91\x41\xfb\x07\xb4\xf7\xc1\x78\x33\xcc\xb1\x85\x44\xde\xc8\xbe\x8b\x69\xf5\xd0\x79\x17\xfb\xdf\x87\x79\xec\x79\x83\x99\x86\xb9\xda\x43\x0f\x21\xc3\x44\x31\x93\x12\xee\x67\x85\xe9\x55\xd1\xe2\x17\xf2\x1c\xa2\xdd\x33\x92\x3d\x62\xcf\x3b\x74\x9b\xc3\xa5\x73\xd8\x5d\x91\xc0\x1b\x23\xa1\x96\xc6\x61\xee\x86\xdd\x93\x41\xf6\x6d\x5c\xcb\x47\xcb\x1b\x4c\x6c\x8b\x6e\xf3\x48\xea\x0f\x1d\xcf\x91\x45\x1a\xbb\x59\x60\xfc\x27\x9a\xef\x21\x95\x33\x81\xdf\x46\x2f\x5b\x5c\x74\x83\xbc\x2b\x68\x6c\x85\x56\xd3\xd8\xfd\x0d\x7b\xf9\xc6\x6c\xc3\x5d\xd0\xc0\x6e\x27\x98\xc6\x0d\xa9\x3c\x90\x5e\xa8\x97\x50\xbb\x15\xec\x39\xec\xe3\x3c\xa6\xe4\x23\xb7\x15\x36\x12\x72\xc7\x02\x5b\x0c\xf7\xff\x06\x7d\xbc\x71\x8d\x2d\x92\x0e\xf7\x92\x8f\x6b\x24\xd1\xaf\x50\x3b\x6b\x24\x3b\x47\xd2\x03\xcc\xe4\x80\x7b\x7d\xd0\xcc\x0f\x26\xf6\xc4\x79\x3e\xc6\xf3\x30\x8b\x28\xe2\x0d\x31\xbd\x1e\x26\x9b\xc1\x3c\xeb\x48\x3a\x82\x19\xf4\xd0\x76\x01\x59\x77\xd1\x6b\x16\xb3\xa9\x21\xed\x33\x5a\xae\x21\xc7\x3b\xda\x0f\xb3\x2a\x81\x1d\xb7\xb0\xad\x32\xb2\xac\x62\xcf\x77\x6c\xb2\x82\xcc\xcf\xc8\xd7\x02\x8d\xef\x08\x1e\x6d\x82\x67\x07\x8d\x4e\x90\x42\x04\xe3\x1d\xd0\x6c\x09\xfb\x5e\x63\x23\x27\xe4\xf5\x83\x4d\x4f\x09\xbc\x0f\xa6\x16\x32\xd5\x05\x9b\xc8\x62\x96\x11\x6c\x65\x45\xf0\x49\x60\x5e\x55\x6c\x26\xf4\x44\x0b\x69\xde\x30\xde\x05\xd9\xdd\xd1\x43\x0b\x2d\xc4\xd0\xf3\x0f\xf6\xec\xe1\x5a\x3f\xe8\xf0\x0f\x93\x49\x61\xe2\x3b\xf4\x3c\xc7\xac\x7c\x64\xd2\xc1\xbe\x76\x48\x3e\x8d\xc4\xcb\xa8\xdf\x45\x4a\x6d\x6c\xad\x83\xcd\x9d\xb0\xb1\x1d\x32\x18\xa3\xc3\x03\xb6\x38\xc6\x26\x3f\x04\x7e\xa8\xd3\x24\xb2\x7f\x63\x5f\x4b\x24\xb5\xc7\x9e\xc7\x98\x8e\x8f\xf3\x4b\x48\x36\x87\xab\xf9\x48\x3e\xdc\x48\x71\x5c\x37\xcc\xfe\x15\x2e\xbe\x41\x4e\x7b\xe4\x1e\x45\xef\x3b\x82\x67\x19\xfb\x5a\x11\x78\x6b\x74\xf7\x85\xd6\x17\xd8\xd2\x2f\x92\xf1\xd0\xcb\x0f\x66\xd9\x46\xcb\x67\x74\xf4\x83\x44\xc3\xae\xdf\x62\x63\x63\xe4\xd8\xc3\x34\xda\xe8\x69\x8c\x19\x8c\x31\xbf\xe1\x8e\x09\xcf\x3c\xc3\xb5\x23\x04\xcf\x2a\x7a\x48\x63\x33\x45\x4c\x98\xdb\xfe\x17\x26\x76\x47\xea\x47\xcc\xf4\x86\xf1\x43\x56\xcf\xa3\xb7\x31\xb2\x6f\x22\x95\x70\xa3\xdd\xd0\xe1\x19\xa9\x66\x90\x77\x0d\x37\xe9\xa3\xa7\x1f\xcc\xaa\x88\x7c\xc2\x67\x5d\xb0\xf5\x01\x9a\x6f\xa2\xe7\x6f\xb4\x94\xc1\x7d\xf5\xb1\xef\x1e\x32\xdd\xe2\x1a\xa1\x9f\x7e\xb1\x9d\x2e\xf2\xdc\xa1\xd5\x35\x1a\x9e\xf5\xf1\x44\xfc\x1b\xb2\xcf\x61\x7e\x5a\x98\x70\x1b\x3e\x13\xb8\xee\x15\xd3\xac\xa2\xfb\x32\xb2\xfd\x45\x96\x15\x5c\x3f\x8d\xa9\x7e\xa3\x91\x1f\x64\x3f\xc3\x54\xce\xc8\xfb\x07\x2d\x97\xb1\xa9\x3e\xf6\x33\x40\x66\x0f\x6c\x72\x8f\x79\xb6\x31\xe5\x11\x66\x7d\x43\xa7\x5b\xf4\x7b\x80\xf9\x7d\xa0\xc7\x21\x12\xfb\xc3\xf8\x27\xe4\x93\xc2\xc5\x16\x48\x76\x8d\x3c\xee\xe8\x25\x85\x8e\xc2\x5c\x9b\x63\xb2\x1d\xec\x79\x8b\x99\x3d\xd1\x90\xa3\x6b\x23\x8c\xf7\xc0\xbc\x26\x68\xbe\x88\x84\xfc\xdd\xcc\x61\x27\x4d\x64\x18\x47\xf2\x33\xcc\xab\x8b\x49\x2c\xd0\x57\x9f\xe0\x59\x44\x26\x2b\xf4\xef\x88\x79\x0e\x90\x65\x1d\xc9\xe4\x70\xf3\x03\x81\xff\x41\xe6\x4d\x5c\x7d\x80\xfb\x7b\x12\xdc\x5f\xd8\xdb\x0a\x17\x7a\xbd\x10\xfe\xfe\x8d\x66\x7f\x91\xe6\x00\x3b\xc9\x63\x62\x1b\xf4\x30\x46\x1e\x5f\xd8\xdd\x1d\x79\x86\xfb\xef\x80\x4e\x92\xc8\xfc\x8a\x9e\xa3\x98\xe8\x1b\x9b\x19\xe2\xb2\x67\x6c\x3e\xe4\xbd\x27\x1a\xfe\xcd\x2e\x8a\xa6\x63\x48\x98\xe9\x1d\x0f\x19\x36\x90\x5d\x02\x39\xe4\xb0\xb7\x38\x7a\x1f\xa3\x85\x2a\xc1\xfd\x81\xcd\x86\x3a\x0d\xfd\x1e\xb2\x55\xc8\x7c\x0f\x34\x73\xc6\x8c\xa2\xe8\x64\x81\x0d\x33\x3c\xd5\xc0\x5e\x66\xe8\xbd\x81\xd4\x37\xe8\xd7\x1f\x6e\xd2\x42\xe6\x0d\x5c\x3d\x49\xe0\x1f\xb1\x9d\x12\x26\xdc\x8a\x8b\x07\xc1\xa3\x8c\x29\x17\x31\x8d\x13\x3a\x2e\xe0\xa2\x17\x24\x19\xc5\x75\x53\xd8\x6f\x8f\xc0\xaf\xe3\x36\x65\x5c\xa3\x82\x76\xea\xe8\x7e\x8b\x24\x9f\xb8\x6e\x05\x33\x29\x62\x2f\xbf\x68\x7e\x85\x7c\x46\xd8\x58\x1c\xf3\xbc\x63\xb2\x17\x34\x37\x41\x8a\x5d\xe4\xb6\x44\xa6\x27\x24\x99\x40\x07\x7d\xec\x76\x87\xdd\x75\x31\x93\x25\x66\x3e\x47\x87\x3b\xdc\xf8\x82\xdc\xc6\x98\xe1\x1a\x8d\x1d\x31\xd1\x02\xee\x9d\x20\x78\x2e\x30\xf3\x15\xb2\xf3\xd1\x71\x0c\x57\xf7\x90\xfe\x14\x8d\x56\xd0\xe8\x1e\x17\xaf\x62\xaf\x53\x34\xf7\x87\x2d\xd6\xb0\xc9\x37\xf6\x7c\x46\x87\x0d\xd4\x3f\x63\x0a\x3d\x5c\xbb\x81\x7d\xa7\x90\x85\x8f\x8c\x7f\xd1\xda\x0c\x89\xad\x30\x9b\x37\xae\xf5\x40\xb3\x7b\xcc\xf9\x17\x33\x8a\xe1\xfe\x6f\xa6\x32\x52\xc9\xe1\x3a\x57\x82\x67\x05\x69\xc6\x30\xcd\x16\xa6\x7e\x45\xd6\x29\x34\xd7\xc5\xa6\x63\x68\xf5\x8e\x7c\x8a\xd8\xce\x1b\xdb\x1f\xe3\x62\x3e\x36\x7e\x47\x6e\x6b\xb4\x30\x43\xa2\x57\xe4\x19\x47\x97\x2f\x24\x77\x24\x78\x9c\x70\xb1\x3a\x52\xc9\x12\xf8\x51\x4c\x3c\x86\x19\x35\x31\xcb\x21\xc1\xa3\x80\xcd\xec\x09\x9e\x67\x4c\xbd\x8f\x5e\x92\x04\xf7\x0e\xda\x8d\x61\xd2\x73\x74\x1d\xe6\xd7\x09\xfb\xb9\xa1\xdd\x90\x2f\x0b\x98\xe5\x12\x1b\x4f\x61\x77\x0b\xcc\x7e\x89\xbd\x97\x31\xf5\x1b\x76\x7f\x40\xaa\x29\x64\xfb\xc6\x9c\x72\xe8\xb9\x87\x7d\x67\xd1\xc4\x0c\xf3\xfb\x8d\xeb\x76\xd0\x48\x0d\x73\x6c\x13\x3c\xc2\x2d\xfe\x83\x8d\xad\x31\x87\x22\xfa\x55\x46\xaf\x31\x4c\xaa\x83\xe9\xa6\x08\xde\x0b\x34\xf6\x87\x96\xda\x04\xde\x2f\xc6\x1b\xe1\x52\x35\x4c\x3e\x86\x6b\x44\xd1\x5b\x04\x8d\xae\x30\xd9\x23\xae\x7f\xc7\x64\xfe\xb0\x97\x32\x2e\x92\xc2\x94\xd6\xb8\xce\x05\x33\x1f\x60\x96\x35\xf4\xd2\xc1\x1e\x0b\xc8\xeb\x81\xbc\x9e\x68\x2c\x8b\xbb\x6f\xb0\xd7\x3c\x92\x9e\xa1\x9d\x15\xe6\x7f\x1e\x65\x30\xcb\x90\x63\x2e\x98\xd7\x11\x9d\xec\x30\xb1\x12\x1a\x66\xde\x34\x8f\x5b\x1f\x30\x9b\x1e\x72\x1a\x23\xa9\x1a\x12\xee\xd9\xdd\x07\xbb\xab\xa2\x97\x3b\x7a\x0a\xf9\xfd\x85\xfd\x0c\x31\xe3\x24\xa6\x99\xc2\x9e\x6f\xe8\xb3\x8c\x59\x7d\x90\xd4\x08\xf9\x5d\x63\xe3\x51\x6c\x6e\x87\xc9\x4e\x90\x72\x0f\xdb\x8d\x20\xf3\x39\xee\x3e\x45\x8e\x1b\xcc\x3b\x87\xa4\x37\x04\xf7\x23\x32\x6e\x63\xfc\x36\x2e\x79\xc1\x7e\x17\x31\xbd\x14\xae\x31\x46\xbc\x0e\x66\xf3\x40\x52\x3e\x36\xdc\x9b\xd5\x04\x76\xb2\xc1\x6c\xf2\x68\xbe\x86\xc4\xbb\x68\xeb\x80\xab\xbd\x71\xf7\x21\xfa\x4c\xa1\xc7\x0c\xa6\x9f\xc5\x34\xcb\xe8\xcd\x47\xa7\x35\xcc\xba\x85\x19\x0f\x70\xc3\x35\x2e\xf2\x44\xb3\x1b\x82\xf7\x0a\x49\x67\xd1\x82\x87\x99\xb4\xd0\xd1\x0b\x13\xab\xa1\x83\x1d\x1a\x9b\xe2\x16\x65\x24\x37\xc0\x1e\x7e\xb0\xef\x17\x92\x8f\xe3\xee\x1f\xb4\xb5\x40\x2a\x61\x46\xf6\x31\x21\xa7\x0f\xf3\xd8\x77\x0e\x0d\xef\x63\xbe\x45\x2b\x7f\xb8\x9f\x18\xf6\xfd\x8d\xe4\xc3\x1c\x9b\x12\x3c\xf7\xd8\x5a\x1e\xe3\xd7\x70\xbd\x37\xc1\x3d\x64\xb0\x0b\xb2\x4c\xa1\xf9\x21\xb2\x4d\x63\xdf\x55\x5c\xe7\x0b\xd7\xfb\x42\x42\xee\xab\x27\x90\x73\x1a\xc9\xfe\x20\x91\x31\x52\x4a\x22\xb5\x3f\xdc\xfa\x8a\x6d\xee\x90\xcc\x0d\x6d\xce\x31\x5f\x3f\xd8\x4b\x1e\x99\x67\x09\x5e\x3d\xf4\x92\x46\x9f\xbf\x68\x2f\x3c\x67\x1a\x57\xeb\xa0\xe3\x38\x9a\xbd\x12\xf8\x0d\xec\xa7\x41\xf0\x69\x11\x78\x65\x6c\xb2\x81\xfb\xce\xa3\xd3\x03\x76\x91\x42\xc7\x29\x34\x96\x40\xca\x0d\xb4\xf6\x8d\xfb\x69\x21\xf9\x36\xda\xf2\xd0\xe3\x1d\xd9\xcc\x90\x4a\x05\xd9\x0c\xd1\xfb\x08\x39\x64\x30\xcd\x37\xb2\xe8\xa0\xf1\x3e\x81\xbf\xc7\xe4\x47\xd8\x78\x04\xbb\xaf\xa0\xb9\x1e\xae\x9f\x45\xc7\x55\x24\xe4\xcc\x76\x0f\x3b\xde\x63\x7a\x2d\xf4\xde\xc2\x26\xca\xd8\x4b\x13\xbd\x16\x30\x8d\x3e\xda\x7b\xe0\xda\x49\x6c\xac\x80\xd4\xd7\x48\x29\x8b\x89\xc7\x31\xde\x1f\xba\x4b\xa2\xed\x15\xc1\xf3\x07\xd3\x4a\x63\x92\x5b\xa4\xfc\xc0\xd5\xb2\x68\x65\x83\x2d\x94\x30\x7f\x4f\x5c\xf2\x86\x44\x6f\xc8\xb3\x8e\x6b\xcc\xd1\x68\x78\xa7\x7b\x64\x50\xc5\x3d\x7d\xcc\xe7\x89\xf1\xae\x48\xb9\x83\xc9\x1f\x70\x91\x2d\xe6\x55\xc1\xf8\x7d\x74\xda\x45\x73\x55\x6c\x6a\x85\x6d\xfc\x21\x3b\x0f\xf7\x33\xc3\xac\x53\x48\xea\x8a\x7e\xef\x90\x54\x01\x09\x77\x5a\xfa\x8e\xf1\x93\xc8\x20\xd4\xb8\x87\x49\xec\xb1\xaf\x3d\xfa\x37\x45\x3b\x79\x4c\x7b\x81\xbc\xc7\xb8\xc6\x06\xd7\x58\x10\xdc\x97\x68\xeb\x0f\xd7\xf0\x91\xef\x04\x5a\xe9\xa3\xd9\x2a\x2e\x16\x21\xf0\x36\xb8\xe4\x0e\xfb\xc9\x60\x33\x35\x6c\x22\x85\x4b\x5e\x71\xad\x23\xf2\x59\xe2\x92\x5d\xdc\xf8\x85\x79\xbf\xd0\xeb\x0a\x29\xde\x09\xfc\x16\xae\x13\x6a\x73\x88\xc6\xd7\xe8\x60\x83\x2c\xbb\xd8\x58\x17\x2d\x66\x71\xd3\x36\xfa\x8c\xa1\xed\x14\xfa\xe7\x21\x95\x37\x2e\x5e\xc2\xc4\x6f\xe8\x21\x8a\x54\x2f\xb8\xf9\x1e\x5b\x59\xe2\x7a\x49\x5c\x6c\x8b\xfd\x44\x31\xe9\x2f\xb4\x56\x43\x96\x3e\xf6\x72\x46\xb6\x67\x4c\x7c\x81\x44\x3c\xe4\x5e\x41\x9b\x55\x5c\x3d\x8e\xb6\x56\xb8\x54\x1a\x5b\x9d\xe2\xc2\xad\xd2\x0b\x39\xf6\x83\xe6\x0b\x48\x2c\x89\x4d\x3e\x90\xc5\x1c\x2d\x67\xb1\xe7\x19\x9a\x4f\xa1\x9b\x1f\x6c\x75\x8c\x8d\x7b\x04\xf7\x09\x7a\x59\x23\xe1\x99\xda\x31\xe4\xfb\x17\x2d\x8c\xb1\xcb\x0c\xf6\xfc\x83\xfe\x67\x98\x33\x7a\x08\x7f\x2e\x20\xa9\xb0\xd7\x3c\x64\xd9\xc7\xee\xc3\xec\xb8\x22\xb9\x70\x5f\xff\x61\xc3\x9d\xd6\x2e\x63\x43\x26\xef\x65\x70\x3f\x55\x82\x47\x03\xf5\x7e\x08\xee\x3d\xa4\x38\x41\x73\x0f\x5c\xeb\x86\xd4\x56\x48\x66\x8b\x5b\xbf\x31\x61\x5e\xc4\x86\x68\xb5\x8d\xab\xd7\xd0\xd2\x0d\x37\x49\x23\x0f\x1f\x1d\x26\xd0\xf8\x08\x8d\xaf\x08\x5e\x27\x02\x3f\x8d\x4d\x86\x8c\x36\x40\xaf\x33\x24\x5b\xc5\x7c\x2f\x91\xd1\x18\x3d\x3d\xb1\xd5\x03\xe6\xb5\xc6\xf5\x8b\x68\xf1\x1b\x1b\x2f\x61\xf3\x45\xd4\x0f\x39\x7c\x8d\x16\x93\xe8\xa3\x8d\x19\x15\x71\xfd\x6f\x5c\xec\x82\xad\x24\x30\xcd\x1d\x7a\x0b\xf7\x4d\xd8\x0b\x39\xcc\xf1\x07\x13\x6f\x23\xdb\x0f\x3a\x9e\xa2\x99\x0c\x6e\x7d\x42\x7e\x63\xd8\xe9\x17\xf2\xee\x60\xb6\x1b\xb4\x58\xc1\xc6\x46\x68\xad\x8a\x76\x6a\xd8\xf7\x0a\xdd\x7e\xb0\xa5\x23\x5a\xcd\xa1\x95\x24\x2e\x79\x40\x0e\x65\x4c\xf3\x17\xa9\x47\xb0\x61\xa6\x8e\x2e\xe8\xf1\x17\xd3\x3d\x60\xbe\x92\x48\x79\x84\x6b\x47\xb1\xa5\x03\xfa\x75\xc4\xbe\x9b\xb8\xda\x1a\xd3\x0a\x77\xd2\x00\xb9\xdd\x70\xf3\x0f\x66\x7e\x27\xb8\xb7\x31\xa5\x04\xea\x85\x5e\xdd\xe3\x22\x3e\xf2\xda\x20\xfb\x70\xdb\x7d\x90\xc5\x0a\x9b\x4d\x23\x95\x6f\xdc\x70\x81\x46\x56\x98\xe1\x16\xdd\xa4\xf9\x17\x00\x00\xff\xff\xbf\x1b\x72\xe3\x00\x20\x00\x00") func keysWordlistChinese_simplifiedTxtBytes() ([]byte, error) { return bindataRead( @@ -86,12 +86,12 @@ func keysWordlistChinese_simplifiedTxt() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/wordlist/chinese_simplified.txt", size: 8192, mode: os.FileMode(420), modTime: time.Unix(1497960590, 0)} + info := bindataFileInfo{name: "keys/wordlist/chinese_simplified.txt", size: 8192, mode: os.FileMode(420), modTime: time.Unix(1511602021, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _keysWordlistEnglishTxt = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x2c\x5b\xdd\xbe\xbc\x2a\x08\xbd\xf7\x2d\xc9\xa8\xd8\xa3\xe2\x41\x9d\x76\xfb\xe9\xcf\x6f\xad\xfe\x17\x83\xe5\x07\x2a\x22\x2c\xcc\x91\x4d\xda\xee\x2d\xc9\x66\xc5\xe6\x93\x64\x2b\x9a\x64\xf3\x35\x41\xbf\x78\x1e\xda\xf0\x32\x3c\x36\x24\x33\x24\xf3\x7d\xc5\x9e\x64\x5b\x43\x93\xe4\xac\x63\x20\xb1\x9d\x95\x73\xf6\xf5\xa6\x6f\xf1\x65\x0a\x56\xd9\xf6\x24\xd9\xd7\x98\x96\x93\xe4\xff\x96\x05\x72\xc3\xd9\x18\xf5\xa7\x61\x2c\x79\x7a\x80\xc6\xcb\x75\x2e\x29\x49\x76\xe9\x33\xc9\xbe\xe3\x67\x99\x8f\x6f\xf9\xfe\xb3\x06\x5e\xab\x81\xae\x02\xfa\x95\x96\x15\xa9\x21\xd1\xf0\x0d\x3d\x1e\x87\x58\x20\x71\x0c\xfd\x08\xc1\x78\x4e\xb1\x96\xe4\x54\xfc\x30\xe6\x33\x54\x93\x5c\x2a\x7b\x12\xab\x89\x2d\x2c\xba\xc7\x4c\x62\x03\xd2\x29\x12\x35\x49\xd9\x16\x68\xf6\xcb\x4b\x92\xa2\x28\x2f\xa6\x2d\x49\xc1\x7b\xd1\x07\xd4\xef\x24\xa5\x3a\x06\x58\xbc\xa1\x71\xbf\x24\x49\x09\x95\x1d\x15\x86\x27\x29\x53\x23\x49\xb9\xe5\x19\x49\xaa\x4c\x5d\x81\xf4\xcf\xda\x99\xa4\xfa\x4b\x29\xcf\xba\x86\xee\x49\x9a\x94\x07\x1c\x5b\xbe\x20\xa8\x96\x8d\x23\x6f\x27\xf8\xb4\x13\x63\x6c\x67\x3c\x49\x9a\x55\x88\xae\x7d\x98\xd5\x7c\x51\x2a\xad\x51\xa0\xcd\xe7\xc5\x06\xe3\x66\x32\xb5\x35\x41\x6a\xff\x2d\xd4\xfa\x35\x85\x42\xb4\x27\x49\x17\xcc\xae\x7b\xf1\x13\x6f\x5d\x25\x90\x80\x6b\xef\x41\x35\xe9\x61\x25\x49\xe4\x0b\x84\xeb\x1b\x2a\x20\xe0\x19\x27\x38\x42\x6a\x51\x31\x81\xa8\x18\x77\xd4\x27\x49\xf8\x6a\xc8\x09\x0c\x1f\xa9\x62\x66\x11\xf6\xe5\x1b\xe4\x87\xbe\x63\xea\x41\x15\x89\x69\xac\x30\x6f\x8f\x4f\x92\x81\x5f\x57\x94\x8c\x21\x5c\xfc\x31\x94\x94\xf5\xc6\x58\x55\x93\x8c\x79\x55\x49\x32\xaf\xa2\x53\x93\x4c\xaf\x49\xe6\x94\xfc\x41\xa2\x18\xc0\x9c\x36\xd7\x8e\xb2\x7f\x0a\xbe\xfe\x29\xe3\xda\xa1\x57\xeb\xa4\x92\x71\x15\xd6\xa4\xd8\xd7\x74\x90\x55\x5b\x92\xaf\x06\x55\xe8\xeb\x59\x76\x47\x0a\xd5\xba\xe5\xa3\xa0\x41\xfa\x24\xb9\x75\x38\x86\x73\x1f\xab\x24\xb9\x3f\xb7\x40\x11\x7f\x6d\xa4\x4d\xb6\x27\x6d\x92\x2f\x2d\x1e\x78\xf0\x96\x36\xd9\x4f\x4d\x9b\x9c\x69\x93\x42\x85\xde\xa0\x6f\x0d\x15\x4b\x49\x9b\xd4\xcd\x3d\x6d\xd2\xa4\x09\x92\xa6\x68\xc9\x9f\x16\x54\x0a\xea\xf6\x06\xa1\xa2\xfa\x00\x83\x61\x19\xf4\xa3\x33\x6d\x32\x67\xd1\xb4\xa9\xe4\x0b\xb4\x81\xac\xf9\xa4\x4d\xb3\x60\xe3\x6e\x9a\x31\xdc\x4d\xf5\x48\x9b\x1e\x1e\x78\x3e\xc1\x52\x2f\xf9\xe2\xe5\xb2\xb6\xa7\x4d\x0b\xf7\xf7\xa6\x50\xf7\x4d\xcb\x4c\x9b\x36\xf2\x6c\x7a\x18\xde\x06\xc8\x0c\x01\xef\x09\x75\xdf\x74\xde\xaa\xe0\xf4\x38\x58\x58\x7e\x32\xc6\x62\x78\xfe\xe0\x81\xb9\xaf\xc6\x6d\x16\x78\x89\x79\xa5\xcd\xde\xe6\x05\x6b\xb7\x15\xd9\x15\xb4\x92\x36\x4e\xaa\x08\x3a\x2b\x2a\x28\x87\x81\xd8\x0a\x79\x15\x77\xd2\x31\xbc\x22\xe5\x04\xcb\x22\x01\xc3\x35\xae\xb4\x39\x16\x64\x73\x99\x69\xf3\xfd\x49\x9b\x5b\x49\x9b\xd7\x2d\x6d\xd8\xbc\x9b\xb7\x35\xd2\xe6\xfe\x01\x41\x37\x1e\x3b\x46\xe3\x81\xbd\xba\x39\xf5\x75\x83\x39\xdb\x7c\x42\xc9\xb6\x77\xcb\x6d\xfe\x9b\x36\x7f\xd2\x16\x92\x39\xc8\xe0\xc2\x84\x60\x60\x21\xa8\x1f\x14\x28\xcc\x02\xa8\xfe\xe1\xc5\x30\xc7\x30\x6a\x41\x18\x16\x21\xec\xbc\xd0\x9c\xdd\x85\x0d\x94\x7b\xce\x5e\x0c\x0f\x1f\x08\x34\xbc\xb1\xb1\xa3\xfb\x78\xf7\xf8\x16\x7e\xa3\x88\x73\x5c\x1b\x6c\xfc\xb6\x76\x4c\x70\xed\x27\xc6\xb3\x8e\x43\x8a\xa7\x6d\x59\xd9\xd3\xb6\xca\x06\xf2\x01\x29\x2c\x6e\x3b\x9b\xb4\x0f\x98\xad\xd8\xd1\xd1\x8a\xf3\x7d\x83\x20\x20\x97\x35\xac\x51\xe0\x6b\x80\xf3\xbb\x50\xeb\x21\xfd\xfb\x4b\x59\xb6\x0d\x9b\x24\xcb\x66\x0d\xb4\xe0\x39\xcf\x35\x52\x7e\xf3\x3f\x20\xa5\x80\xd4\x94\xa5\x6a\x08\x92\x9e\xb2\xa0\x41\x13\x14\xb5\xac\x4c\xf6\x07\xb4\x39\x4b\x1c\x2d\xdb\x57\xc0\xaa\x3d\xcc\xeb\xff\x3a\xe8\x36\xd9\xae\x4f\x61\xb7\x81\xdf\xc6\x2a\xb1\x83\x9c\x0e\xda\x75\x22\x09\x70\x0d\x3c\x0e\x34\x1e\x17\x88\x35\x54\x19\x93\xfc\xc6\x22\x3b\x54\x99\x52\xfc\x44\x9a\x51\x6d\xea\xe9\x6c\x3e\xdf\x8a\x0b\x4b\xf5\x6e\xa4\x2c\x8b\xc6\x24\x63\x91\xb3\x5a\xc1\xfa\x65\x2d\x8a\xfa\x5a\x61\xbd\xb3\xb6\x01\x49\x68\x9b\x8b\xb9\xa1\xe8\x47\xe3\x1d\xf6\x05\x3f\x94\x2f\x29\x1f\xd0\xda\xc9\xed\xa2\xcd\xcc\x97\xf8\x00\xed\x10\x78\xbe\x24\xde\xcc\x41\x3a\x53\xbe\x54\x3a\x68\x46\x5b\x55\xe6\xeb\x01\xc2\xe9\x5e\xd8\x9d\xf9\xb2\x0c\xf5\x81\xab\x46\x11\xf4\x20\x5f\x56\x9b\xa2\x86\xc3\x8d\xe6\xcb\x9d\x6d\xc3\x9b\xe5\x94\xaf\x95\xe1\x57\xf2\xb5\x1a\x18\xaf\x68\x29\xdb\x09\xf9\x5a\x6b\xf0\x5b\x29\x5b\x60\x53\x67\x9b\xf6\x07\xde\x00\x18\xd9\xbe\x56\x52\x2e\xf0\xad\xb9\x60\x60\x45\xc2\x8e\x07\xe9\x0d\x82\x27\xd8\xa2\x5c\x34\x3e\xa0\x5f\xcc\xaa\x60\x2f\xe4\x42\x47\x97\x8b\x1d\x07\x68\xdd\x40\x39\x98\x62\xe0\xe4\xac\x84\x35\x29\x1c\x6a\xf1\x79\x81\xae\x1d\xf4\x06\xd3\x85\x36\x0b\x3a\x55\xd6\xa0\xc0\xca\xe2\xfa\xb9\xbc\x14\xc2\xf0\xec\x6d\x21\xdd\x35\x65\x3f\x0e\x45\x82\x61\x3b\xd6\xc2\x4b\x81\xc3\xc9\x0e\x53\x9d\xbd\xc0\x03\x64\xaf\x9b\x35\x54\xab\x24\x07\xf0\x42\xf6\x8a\xb1\x79\xa5\x30\xbc\x76\x38\xd3\xec\x0d\xab\x8a\x74\x5f\x64\xd3\x0e\x8b\x8a\xf4\x24\xa0\xc9\xde\xda\xcb\xbf\x0d\x83\x79\xc9\xde\x66\x38\x7a\x6f\x5f\x83\x39\xc9\xb0\x40\xd9\x99\xd5\x3b\x6b\x74\x30\x0e\x68\x0c\xac\x74\x76\x2c\x86\x47\xbc\x7c\x38\xa5\x39\x39\x88\xc5\x59\xae\x36\xb1\xf4\xbe\xe0\xc3\xb3\xaf\x18\x4c\x06\xa7\x47\x81\xfb\xe3\x53\x53\x86\xc1\x02\xc5\xfe\xcf\x21\xc7\x04\xad\x20\x8d\x19\xd8\x20\x21\x94\x63\xc8\x5d\x40\xff\x9e\x94\x43\x59\x49\xe1\x3b\x73\xa8\x82\x87\xde\x29\xc3\xa4\x61\xa3\x85\x41\x4c\x61\xa3\x83\x02\x2e\xe4\x70\x3c\xc3\x76\xe6\x78\x47\x19\x7e\xef\x29\xc7\xca\x86\x79\xc5\x52\x52\xc3\x50\x63\x55\xee\xee\x58\x8d\x35\x17\xc7\x81\x8e\x9f\xc1\xed\xbe\x36\x4d\x79\x95\xb9\x20\x8d\xd5\xf1\x7b\x8d\x7b\x5e\x61\x8e\x8d\xb6\x22\xa8\x4c\xeb\xdf\x0e\x5b\x81\xbd\xb9\xc6\xc5\xad\xb5\x06\xcc\x77\x5e\x90\x01\x3d\xd3\x2e\x7b\xda\xa5\xc2\x50\xed\x30\x49\x3b\x1d\xf2\xfe\x82\xae\x5d\x68\x91\x77\x88\x63\xe7\xc6\x67\xe6\xdd\xd2\x2e\x4f\xda\xb1\x93\x77\xdd\x64\x2a\x92\xb0\x91\x76\xcd\x70\x5d\xbb\x66\xad\x1b\xea\x2a\xa0\x33\x92\x02\x2d\xda\x15\x8b\xc9\xea\x10\xe5\xc0\x03\x6b\x1d\xda\xf8\x72\xbc\xb5\x0e\x30\x27\x60\xdd\xb5\xb0\xa7\x62\x5f\x56\xac\x70\x2d\xbb\x56\x63\xf5\x66\x1c\x41\x23\x76\xda\xb5\xa1\x26\x31\xdd\xae\x5d\x59\xb1\xfb\x30\xbe\xce\x0b\x14\x28\x60\x57\x82\xb0\x5d\x47\x0e\xdb\xf8\xa0\x6c\x32\xec\x6c\x48\x3e\x20\x1d\x86\x69\xd7\x31\xc3\xd1\x64\x8a\xa1\xa7\x09\xc5\xdb\xf5\xab\xc5\x3b\x52\xd8\x8f\x5d\xbf\x50\xa9\xdd\xe4\x84\x0a\xed\x1c\x93\xc1\x50\xec\x48\xe3\x49\x3b\xab\x99\x0e\x45\x89\xce\xb4\xdb\x71\x60\x3a\x76\xd2\x88\xef\x76\x36\xd8\x90\xdd\x8a\xd6\x2a\x69\x37\x62\x9e\xdd\x9a\x0f\x59\x78\xa0\xc2\xef\x86\x61\xda\x78\xa1\xfc\x6e\xe3\x55\xe9\xdd\xc6\x2b\x4a\xc3\x2a\xd9\xa8\x36\x06\xd2\xd7\x87\xef\x36\x3a\x45\x68\x63\xbe\x4b\x0b\x49\x82\xcf\x97\x2b\x63\x5f\x0f\xe6\xfe\xfd\x3d\x69\x77\x86\x28\xbb\xe7\x45\xe3\xbd\xfb\x99\x76\x2f\x05\xa4\x5f\xd6\xd2\xee\x55\x98\x34\xae\xa2\xb7\x8f\xa2\x55\x63\x23\x12\x0c\xc4\x17\x94\x78\x07\x7e\xde\xb9\xb7\xf6\x90\xd3\x1b\x12\xcc\x2e\x84\x81\xd2\x1e\x72\xa7\x9d\x3b\xea\x8d\x78\xf6\x30\xd6\x35\x74\x18\xd6\x3e\xa0\x1d\x84\x8c\x20\xf1\x58\xa8\xfc\xa4\x7d\xe5\x4f\xda\x57\xdd\xd2\xbe\xa0\x31\xeb\xd5\x53\x60\xd9\x9d\x66\x6f\xe7\x4a\xdf\x12\x47\xda\x9f\x26\xb0\x57\x2a\x50\x69\x15\xc4\x11\x2a\x51\x1e\xd0\x06\x32\xaf\xa4\x32\x8c\x39\x63\x82\x3c\x49\xf3\xe5\x49\xf3\x0b\xd4\x34\x7b\xf3\xfa\x24\x05\x64\xe1\xe6\xd7\x7d\xc1\x33\x26\x3d\x68\x11\xf5\x3c\x93\x12\xc3\xa8\x11\x99\x68\xd9\xfc\x4e\x5a\x76\x3e\x6b\x9e\x81\x11\x14\x3d\xa5\x4d\xa4\x14\xaf\x16\xed\xd7\xbf\x8c\xaf\x40\xf2\x5a\x0c\x4c\xcb\xd0\xa4\x75\x93\xf8\x20\x01\x62\xd3\x0a\x8c\x85\x5c\x85\x1b\xd4\xea\x74\xbc\x5a\x7b\x71\x94\x76\x47\xb0\xa3\xb5\xcf\x27\x69\x23\x44\xd0\x06\xbc\x8f\x6d\xa0\x80\x39\x63\x20\x75\x58\x44\x6d\x8a\xc9\x34\x0d\xcc\xad\x1d\xd4\x00\x6d\x27\x8c\x80\xb6\x13\x7b\x50\xdb\x45\x6d\xd1\xf6\x03\xfe\xad\x60\x87\x69\xf3\x75\x5e\x49\x5b\x58\x66\x02\xd5\x80\x7f\x0f\x54\x84\x6d\xc0\x56\x7c\x5f\x02\xad\xb8\x4f\x34\x69\xb7\x01\x97\xa3\xff\x01\x63\xe8\x7f\xcb\x7a\x02\x06\xd2\x80\xde\x6a\xb0\x2c\x7c\x70\x46\x11\x90\x43\xac\x3e\x93\x8e\x2c\x68\x3e\x86\x3c\xa0\xca\x11\x8d\x49\xc1\x4f\x0d\x00\x27\x9d\x97\xe5\x91\x14\xda\xcc\x62\xb8\x61\xfd\xfa\x07\x8f\x5e\xbe\x9a\xf4\x97\x72\xf8\x95\x0a\xa7\xa0\xbf\x8c\xe9\xf5\xf7\x1f\xca\xd0\xdf\x4c\x91\xff\xe6\x82\x30\x49\x7f\x19\xda\xeb\xaf\xd2\x46\xea\xaf\x46\x36\x66\x5c\x02\xed\xd2\xdf\xcb\x36\xac\xff\xaf\x91\x19\xc5\xf2\xcb\x0c\x87\x52\xeb\x6f\x87\x85\xd2\x5f\xc6\x6e\xfa\xdb\x29\x8e\xdf\x5e\xb0\x6d\xf4\xb7\x3b\x79\xf5\x78\xc7\xc0\x10\x4d\x7f\x27\x64\xf1\x28\x7e\x40\xb4\xe9\x10\x60\xe4\x74\x60\xc1\x0f\x81\xb9\x7f\xd2\x01\xbb\x7a\x88\xb5\x09\x3a\xaf\x74\x00\x51\x1e\x02\x55\x39\x10\x28\x1c\x52\xa1\xc1\x07\x62\xea\x91\x0e\x69\xf8\x65\x64\xb4\x09\x85\x3e\x10\xa7\x1e\xf2\xfa\x81\x43\xc0\x06\xb6\xe7\x10\xea\xeb\x21\xd3\x10\xcc\x1e\x8c\x35\x0f\xf9\x7a\x40\x2c\x87\x0a\x5d\xcd\xa1\x5b\x2c\x98\xb2\x43\x77\x85\x3b\x06\x74\x38\x54\x77\x10\xbc\x55\x29\xc8\xc0\x0a\x1c\x3a\xa6\x7d\x59\x07\x3b\xf1\x20\xd0\x39\xf4\x4e\x87\xc1\x25\x1c\xf6\x06\xa0\x87\x69\xd9\xd3\x61\x27\xf9\x43\x9a\x87\x95\x0a\x32\x59\x0b\x8b\x7b\x20\xc2\xa1\x4f\x38\x8c\x0e\xe9\xb0\x06\x2b\x77\x18\xdb\x60\x42\x06\x98\x7e\xd8\xc8\xac\xce\x32\xbc\x4f\x22\xf6\xc3\x7e\xd3\x51\xe4\x04\x81\x88\x0a\x1c\xd9\x51\x30\xf9\x82\x29\xa6\xa3\x60\x1e\x85\x3b\xf7\x00\xd6\x3a\x8a\xb3\x14\x88\xeb\x28\xce\x2a\xdc\x5a\x47\x59\xb6\x83\x92\xc3\x93\x0e\x97\x9a\x0e\xcf\x90\xb5\x9f\xe9\x00\x8c\x3a\x1c\x33\x72\x9e\x8e\x1c\x08\xcb\x0e\xf7\x99\xde\xed\x85\x28\x73\xf0\x05\x81\xc9\x81\x20\x1f\x96\x03\xd6\xeb\x70\x98\xb5\xc3\x83\x61\xf3\xe1\x63\x90\x17\x51\xdc\xc1\x63\x84\xc3\x7f\xd3\x11\x72\x52\x4a\xc1\xa9\x84\xfe\xb7\x60\x43\x8e\x50\x8c\x28\x0c\xaa\x74\xc0\x0c\xa2\x10\x23\x0a\x67\x31\x50\xd2\xc1\x38\xe9\x08\x07\x5c\x3d\x62\x41\x44\x80\x1d\xc7\x6a\xf8\xb5\x27\x1d\x2b\x1a\xd5\x0d\x20\xfd\x58\x5c\xf4\x53\x18\x44\x31\xd8\x3e\xa5\xc8\xef\x83\x84\xe0\xfe\xc4\x18\x4e\xe9\xe9\x14\x1e\x10\x9c\x12\xdb\xbf\x14\x31\xd4\x29\x51\x2c\x23\xa1\x9d\x3b\x65\xe0\x87\xda\x13\x75\xa8\x71\xa7\x2c\x36\xf8\xd3\x74\xc2\x14\x49\x41\x6a\x6b\x20\x09\x66\x22\xde\x38\xb5\x2d\x28\xc0\xa9\xe3\x1d\xd4\x85\x09\x9d\x06\xb3\x79\xc2\x5f\x9c\x76\xc2\xa2\x9f\xaf\x82\x9c\x16\x72\x1c\x78\x8d\x92\x4e\x38\x8e\xb3\xc8\x0e\x02\xd5\x3c\x8b\x04\xe9\x18\xe9\x2c\xf0\x7f\x67\xb1\xda\x07\x52\xdf\x48\xbd\x82\x62\x8a\xc5\xd9\xda\xef\x74\x22\x9c\x3e\xa1\x18\xa7\xef\x3b\x14\xeb\xc4\x4a\x9f\x58\xe2\x93\xc1\xc3\xe9\xf0\x5a\x92\x4e\x1f\x5d\x0b\x92\x61\x3d\x9d\xf0\xcf\x2d\x9d\x10\xfe\x19\xb2\x81\x60\x14\x8c\x92\xcf\xe0\x14\x02\x16\xee\x64\xac\x7c\x86\x7c\x01\x03\xce\x50\x74\x15\x0a\x49\x86\xed\x20\x7a\x80\x22\xd7\x33\x17\x20\x7c\x75\xd0\x3b\x9d\xb1\xc0\x68\x41\x79\xce\xc5\xd1\x2d\x4e\x6d\x59\x41\xbe\x4d\x89\x74\xae\x96\xce\xa7\xa6\x4b\x60\xbd\x18\x75\x5d\x52\x8e\x74\x49\xad\x8a\xe7\x4a\x75\xbb\x60\xbc\x2e\xe9\xfd\x49\x17\xa2\x49\xe4\x04\x72\x62\x5c\xa0\x5f\xe8\x30\x82\x2f\x9e\x93\x5c\x72\x7f\xd2\x25\x7f\xac\x82\x08\xff\x52\x29\xf3\x42\x12\x13\xf4\xfb\xa4\x0b\x3e\xf3\xf2\x33\x5d\xaf\x7f\xbc\xb4\x14\x07\xad\xca\x97\x9e\x2e\x6d\xe9\xd2\xf0\x74\xd9\x0e\xe5\xb9\xec\xbc\xd2\x05\x10\x70\xc1\xda\x5d\xd6\xd3\x85\xfd\x7e\xd9\x98\x58\x98\xcb\xb7\x0d\x34\x03\x7b\x5c\x58\x88\xcb\x8b\x82\x18\x50\xe9\xf5\xee\xbf\x0b\x01\xcb\xe5\x8d\x75\x1c\x75\x3a\xde\xa3\x81\xc0\xc5\x5c\x74\x85\x97\x8f\x37\x90\xa6\x5a\x5d\x3e\x15\x8f\x0b\xc5\x30\x5b\xd7\xda\xd2\x05\x3d\xbd\x56\x95\x06\x0a\xcf\x7a\xad\x0a\x06\xab\xed\xa1\x3b\xd2\x13\xc3\xc2\x2a\x5c\x2b\x76\x56\x08\xe6\x40\x0a\x6b\x6c\x14\xea\xb3\x61\x29\x81\x04\x2d\x7b\x4b\xb6\xab\x24\x1e\x2b\x23\x48\x34\xb4\xb2\xb3\x21\xc8\xc1\xcc\xad\x00\x2a\x30\xa5\x21\x33\x02\x74\xab\x46\xdf\x67\xb5\x12\x2f\x5b\xad\xb0\x1f\x56\x3b\x3c\x9c\x55\x7a\x17\xab\xef\xc9\xa5\xd5\xbe\xe0\x1c\x0c\x91\x84\xb5\xd7\xbd\x59\x63\x20\x67\xed\x1f\xfc\xb6\xb6\xeb\x2f\xa8\x11\xcd\x58\x23\x8a\xb3\x06\x24\x15\x4f\xb2\x06\xef\x81\xa4\x58\x66\xea\x51\x93\xb5\x0b\xd6\xde\xda\xa5\x50\x49\x6b\x36\x81\x79\xad\xfd\x28\x2b\xfd\x2c\x36\xad\x2f\x47\x20\x59\x6b\xcd\xb3\x92\x53\x5f\xa0\xff\x2d\x63\x9d\x81\x70\xcb\xda\x78\x1b\x22\x2c\x44\x42\xa7\x69\x0d\x11\x0f\xd8\x4e\xce\x0e\xf8\x02\xda\x67\x6d\x7a\xb2\xf6\x7d\x9f\xbf\xc6\x4e\x5e\x4f\x6f\x01\xc1\x8e\x02\x79\xdb\xf0\xc2\x01\x8c\xb1\x34\xd9\xd4\x9a\x00\x75\x9f\xf4\xf3\x1e\x55\xfd\x08\x76\x4c\xfa\xe1\xef\xef\x2f\xfd\xa8\x14\x38\xce\x1f\x95\x06\x5a\xca\x93\x7e\xf4\xd6\x92\x7e\x7c\x4b\x3f\x08\x90\x7f\x00\x2a\x7e\x7c\x05\x94\x0a\xb0\xe8\x67\x01\x0f\xfe\x2c\x2c\xea\x0f\x62\xef\x9f\xc5\x53\xea\x9f\xd5\xcc\x03\xc9\x27\xf1\x10\xff\x23\xed\x94\x70\x4f\x1f\xec\xe9\x8f\x6a\x4f\x1f\x38\xc7\x85\xf4\x49\x1f\xcb\x9f\xf4\xb1\x1d\xbf\xc6\xf7\x86\xe7\x76\xee\x5e\xd3\x07\x70\xfe\x63\x13\xbf\x8c\xbd\xf2\xc1\x94\x3f\x36\x27\x9f\x6f\x4b\x9f\xa6\x9a\x3e\xcd\x0e\x50\x38\xae\x4f\xf3\x3b\x15\xd9\xf0\xd3\x02\xea\x91\x8a\xec\x00\xa3\x45\xf6\x27\x15\xf9\x68\x2a\x08\xf7\x8a\xb4\x73\x41\xb7\x8a\xf4\xe9\x78\x0f\xbe\x4c\x56\x9d\xd6\x52\x41\xdc\x07\xda\x00\xbc\x8b\x7c\x25\x15\x01\xfb\x1b\x65\xf7\x80\x33\x29\xf2\xb0\xfe\xdf\x93\x8a\x0a\xbb\x51\x39\x40\xa2\x81\x7e\x35\x01\x03\xc3\x7e\x17\x3d\x66\x2a\x7a\xa6\x57\xc1\x8b\x9e\x70\x5c\x45\x6d\xbc\xa5\xd5\xd1\x82\x59\xed\x9c\x17\x92\x91\x8a\x7a\x87\x91\x01\x8a\x65\x39\xcf\xe0\x0a\xe2\xb0\x54\x4c\x22\x15\x40\x8b\xf9\x20\x0d\xc0\x94\x62\x99\x3b\xa4\x40\x28\x05\x6e\xe2\xf5\xf1\xc5\x30\x71\xab\x1b\x08\x06\x8e\x28\xa3\x00\x8e\x14\xfb\x0f\x0e\x9e\x38\xb7\x18\x8f\xba\x10\x73\xa6\x62\x34\x6f\xc5\x85\xa4\xa5\xe2\x1b\x4d\x65\x71\x40\x0e\x02\x85\xe2\xa7\xe5\x54\xbc\x69\x79\x90\x9c\xa9\x38\x64\xe9\x18\x26\x72\x16\xda\x2e\xb8\x66\x3a\x95\xe2\x0f\x9a\xae\xfc\x79\x52\x59\x27\x71\x77\x59\x0c\x98\xcb\x6a\x42\x9a\xaf\x54\xd6\x2f\x76\x52\x79\x02\x08\xb7\x4a\xbe\xe0\x08\xab\xec\xa9\x0a\x3a\xac\x72\x36\x9d\xa9\x8a\x21\xc7\x4a\x62\x6c\x56\xe5\xc7\x23\x55\xac\x70\x95\x5a\x05\xd9\xc8\x6d\xe8\x05\xe1\x33\x76\x45\x95\x76\x3a\x28\x31\x77\x15\x7e\x39\xa9\x02\x80\x5c\x25\xb6\x37\xc9\x17\xe8\x49\x9e\xf1\x76\x1d\x1f\x76\x18\x61\x2f\xb7\xf1\x01\xc1\xe0\x28\x93\xca\x23\x43\x6c\xfc\x30\x32\x9c\x7c\x0b\xfb\x45\xf2\xd6\xf8\xb5\xba\x6a\xaa\xf0\xfb\x55\x65\xf7\x1b\x49\x03\xa1\x06\x54\xf8\xbe\xaa\x40\xe7\x98\xa2\xee\xe0\xa3\xbb\x49\xaa\x5a\x10\x09\x55\x2d\xa8\x40\x69\x55\xad\xd8\xd2\x00\x19\x9c\x87\xb6\x95\xaa\x46\x46\x16\xf4\xb8\xd2\x40\x55\x9e\x07\x56\xe0\xa4\x8a\x58\x82\x05\x93\x7c\xe7\xe5\x7b\xaa\xb6\xc3\xfc\x56\xdb\x1b\x95\xa4\x5a\xf9\x80\x50\x2f\xaa\x21\x76\xac\xd8\x91\xd5\xda\x3b\x76\x43\xbc\x5b\xad\x21\x42\xa8\x16\x92\xd9\x9a\x5e\xa5\xda\xc0\x92\x33\x06\xaf\x08\xb9\xb1\x0c\x98\xbe\xfd\x2a\x38\xfc\x72\x13\x54\xdf\x00\xe5\xaa\xef\x5a\x40\xe1\x02\xaa\x57\xfc\x60\x25\xab\x37\x43\x34\x58\xdf\xf8\xba\x7a\x7b\xa5\xeb\x0d\xf2\x74\x8c\x8a\x67\x62\xd5\xc9\x2b\x1a\x82\xdf\xea\xe3\xbf\x65\xd3\x53\x7d\xcf\xc6\xff\x45\x88\xd5\x5f\x4e\xab\xf1\x38\xa8\xf2\xfb\x40\x85\x16\x56\xff\x9a\xa6\xba\xb0\x62\xeb\x38\x50\xb8\x30\xa8\x55\xa6\xf5\xf2\xa4\xba\x06\x27\xb6\x86\x62\xd2\x6b\x5c\x3c\x7b\xaf\x6b\x40\x20\x30\x6b\x75\xf1\x13\x66\x7d\x86\x96\x03\x09\xd5\xbd\x3e\xf3\x4a\x4d\xb0\x79\x1a\x60\x62\x93\xfe\xb1\x96\xda\xfb\xd5\xab\xc9\x98\x4f\x6a\xc2\xc1\xb5\x37\xba\x68\x2a\x91\x9a\xe6\x4f\x6a\x08\x29\x9a\x9e\x32\xd9\x5c\x4f\x9e\x48\xb6\x7f\x41\x75\xd3\x7e\xe9\x9d\x9a\x06\x0b\x07\x4a\xf8\xe3\x37\xb3\xa6\x6b\x42\x2a\x8d\x01\x47\xd3\x7b\xa4\xa6\xbf\x33\x35\x98\xe7\x77\x65\x9b\x43\xb5\x9b\x23\xa2\x6b\x5e\x0d\x86\xb3\xb9\xef\xcc\x0c\xec\x95\xe6\x81\xd1\x3b\x2b\x4c\x79\xab\x4f\x92\x0b\x52\x6e\x88\xf2\xf0\x0a\xd3\x03\x33\xdb\x56\x2e\x1c\xfe\xbb\x7f\x1b\x8f\x1c\xdb\x9a\xc9\xe5\x93\x7c\xd3\x27\xf9\x46\xbf\xe8\x5b\xb1\x53\x93\x6f\x23\x63\xce\xbe\x0d\x4e\xc3\x37\xae\x8b\x6f\x5f\x1e\xdf\x79\xce\x2b\x92\x67\x6c\x09\xcf\xd3\xc1\xd3\x77\x8f\xe4\xc7\x81\x9f\xf2\x09\x43\xf0\x03\x0e\x00\x61\x87\x7f\xe4\x49\xc0\x41\x4e\x8b\xe5\xe5\xa9\xdd\x72\x72\x18\x38\x07\xec\xf5\x86\x1f\x04\xee\x8d\xe7\x70\xde\xca\x93\xbc\xa3\x7d\x47\x20\xee\xdd\xde\xe2\x4e\x08\xe1\x9d\xab\xe3\xef\xb7\x4b\x0f\x40\x46\x8f\x4c\x28\xf8\x9e\x2a\x79\xec\xd6\x60\x68\x3d\x4e\x8c\x34\x78\x80\xed\x61\x27\xe3\x36\x8f\x7e\x21\x7b\x4c\x9e\x14\xbc\x0a\xe9\x6b\x12\x5d\xf8\x9a\xef\x1b\xa0\x80\xaf\x49\xaf\xef\x08\x18\xfd\x8b\x11\x61\xf5\x80\x98\xfd\x06\x74\xf0\xdf\xe7\x44\x2e\x95\x2b\xf9\x1f\xe6\x42\xb8\xd3\x85\xbb\xb6\x63\x3b\xf3\xb0\xae\x4b\x01\xba\xee\x52\x6a\x42\x10\x2e\xa0\x5a\x40\x2d\x83\x72\x14\x5d\x3a\x69\x20\x9e\xee\xc2\xb3\xd2\x2e\xf1\x01\x09\xe7\xf3\x7c\x52\x87\x51\xeb\xb4\x66\x1d\x46\xac\xcb\xb4\xb7\x26\x4f\xac\x3b\x8d\x59\x4b\x9d\x5f\x41\x3a\xfc\x5b\x97\x87\x7b\xb7\x2b\x07\xa1\x02\x1d\xe0\x07\xe5\xae\x32\x84\x25\xc5\xb2\xb4\x04\xb1\x77\x6d\x82\xa8\xbe\x6b\xcb\x56\x52\x57\x87\xe9\xed\xca\x53\xef\xae\x71\x40\x63\xba\x06\x96\xb0\x6b\xc0\xe9\x75\x9d\xa9\x5f\x9c\xfe\xe5\xd3\x53\xbf\x78\x7a\xd2\xaf\x67\x18\x3c\x51\x37\x69\x9e\xba\x65\xce\xd6\x5e\x6f\xdb\x4d\x31\x1a\x3b\xf1\x53\x70\x01\xba\xec\x56\x30\x53\xf8\xbe\x6e\xde\x14\x7d\x5a\x47\xbd\x31\x31\x3b\xe3\xbc\xed\xef\x4f\x52\x7f\x65\x5a\x04\x3b\xad\x97\xf7\xe4\xae\x13\x59\xf1\x58\xb1\x17\xe2\xc8\x5e\x78\x34\xd6\xe1\xd3\x40\x4f\x10\x28\x4f\x77\xad\x20\x33\x75\x07\x9a\xef\x5e\x20\x12\x00\xf6\xee\xf0\xd2\xa9\x7b\xdb\x41\x9e\xd4\x1d\x9d\x7b\x5f\x6f\x95\xa0\x12\xf2\x00\xf7\xdf\xc3\xb0\x8d\xed\x06\xf8\x4c\x81\x10\xfe\xb9\xd8\x0e\xad\x81\x3c\xfd\x86\x7a\xbe\xa7\x61\x3d\x24\x73\xb7\xf6\x10\xec\xf8\x1e\xca\x1b\x16\x3d\xf4\x60\xb1\x62\xfd\x91\xf2\x2a\x48\x0f\x9d\x60\x11\xfa\x7d\x5f\xdf\xa6\xd0\xce\x1e\x56\xa1\xed\x3d\xec\x2d\xf1\x30\x56\x35\xae\x4c\xd8\x97\x02\x09\xfb\x03\x85\x91\xa9\x48\x79\xd2\xd4\xc3\xf7\x45\x4e\x7e\x60\x35\xc3\x79\x4c\xdc\xc3\x69\x16\x7a\x78\x75\x36\x76\x3f\x40\xfb\x3b\x91\x40\x24\x89\x41\xfa\xfc\x57\x6d\xed\xa0\x3c\xb5\xed\x6b\x43\x7c\xdd\xd7\xbe\xc3\x28\xf5\x85\x45\x5d\xa5\xa7\x17\xf2\xf7\x55\x69\x72\x3b\x61\x44\x5f\x1d\x2a\xb6\x10\xd4\xf5\x15\xef\x17\xb4\xbe\xde\x19\xac\xe0\x8e\xef\x34\x5b\x7d\x0d\x54\x9f\xa9\xaf\xbf\x3f\x48\xfa\x09\xa9\xb6\xa7\xff\x96\xf0\x12\xcd\x7f\x4b\xda\x5c\x15\x69\x60\x37\xfe\xb7\x74\x70\x6d\xfe\x5b\x40\xb0\x70\x3f\x20\x7f\xe9\xbf\x85\x29\x85\x6c\xb0\x1c\x21\x39\xc3\x67\x31\xf6\xe5\x77\x97\x90\x5d\x02\xd4\x3c\x05\x80\x0b\x03\xe2\x77\x91\x42\x80\xbc\x03\xd8\x34\x04\xc3\x0f\x69\x80\xc1\xaf\x2d\x0a\xe9\xb6\xa7\xc0\xb2\xf1\x3b\x42\xbc\x67\x09\x21\xb0\x1c\x21\x77\x0a\xf9\xf3\x48\xef\x2d\x14\x7e\x69\x44\x9c\x83\xce\x15\x48\x38\xf4\xfd\x12\x1c\xca\xef\xb1\xa1\x59\x61\x31\x43\x33\xd4\x3f\x34\x7b\xb0\x90\x5f\x46\x42\xb9\x6e\xa1\x07\x9d\x50\x28\x83\x9f\xd0\x03\x7b\x3e\xf4\x34\xb2\x3d\x43\x51\x76\x52\x69\x43\x7f\xde\xaa\x45\x7e\x41\xb9\x37\x42\x0b\xc2\x77\xde\x5d\x08\x25\x46\x0b\xfd\x07\x60\x42\x89\x2c\x42\xe9\x91\x43\xdb\xce\xcc\xa6\x77\xa2\x65\x0a\xa5\x95\x86\xa6\x1a\x0a\x3a\xd0\x51\xe8\xbb\x2b\x43\x79\x7b\x27\xf4\xbd\x70\x14\x3a\xf2\x62\xa2\x8c\x52\x43\x79\x55\x24\x74\xf8\x0a\x56\x1f\xdd\x1b\x07\x34\x56\x41\xc1\x7c\x9b\xcd\x78\xb9\xce\x15\xe8\x6a\xb5\x77\x66\xdf\x57\x7c\x5f\xe3\x60\x78\x36\x15\xd7\x33\xaf\x9a\xc2\x36\xfc\x36\x54\xc3\x26\xa1\x91\xe7\x46\x79\x3f\xea\x87\x1d\xe8\x9f\x2e\x17\x2e\x61\x4f\x3c\x9e\x0f\x73\xbc\xf3\x7e\x0d\xbf\xf1\x87\x11\x3f\x04\x4f\x0b\x83\x5f\x78\x02\x38\x3b\xf8\xb5\x32\x7c\x73\xd2\xc5\x17\x46\x6d\xe1\x95\x07\x39\xdc\x2c\xe1\xfe\x31\x3e\xd7\x14\xd0\xe2\x70\x86\xc7\xc1\x53\xea\xf7\x02\x4e\xc0\xdb\xa4\x20\xe0\x8e\xb5\x51\xe6\x08\x84\x63\x9d\x29\x00\x77\x62\x35\xfc\x6e\x79\x52\x2c\xc0\x87\x21\x3b\x7e\xf0\x2d\x43\x76\x46\xdf\x43\x0e\xbc\x18\x0a\x0b\x8b\x0b\xc2\x94\x21\xe5\xa5\x13\x04\xfd\x0c\xe0\x9d\xf1\x1e\x34\x0f\x44\xa1\x43\xa6\x8d\xe3\x41\xea\xe3\xb2\x34\x04\x2a\x35\x64\x11\x85\x0e\x38\x8e\x21\x4f\x1a\x19\x01\xf5\x80\x77\x18\x19\xca\x3d\xf2\x0b\x97\x47\xd6\x86\xb7\x4b\x2b\x13\x58\xc8\x91\x8d\xe7\xac\x23\xdb\x18\x1e\x23\x8d\xec\xc1\x0f\xe7\x23\xfb\x9a\x69\xe4\x90\x0e\x8a\x58\x73\xe4\xb0\xce\xbc\xb5\xa5\xa1\x82\x1f\x80\xfd\x78\xb7\xc5\xc0\xca\x0f\xcd\xb0\xc1\x43\x33\x74\x19\xb1\x38\x99\x69\x7e\x6d\xc4\x00\x26\x1b\xaa\x9f\x34\xf4\xa4\x8f\x1b\xfc\xa2\x81\xa4\xa4\x01\x0d\x96\x48\x43\x19\xf3\x0e\x86\x5d\xb0\xa7\xef\x18\x35\x4c\x07\x12\x7e\x2a\x1b\x3a\xc6\xcb\x9b\x01\xd6\xd0\xb9\x7a\x1a\xb0\xb7\x69\x5c\x8c\x05\xc6\x25\xc7\x04\xe5\x21\xce\xb8\x28\x8c\x0b\x03\xb8\xd8\xdb\xa5\x61\xc7\x91\xc6\xc5\xd3\xe3\x71\x19\x6b\x03\xd3\x8c\xcb\x3a\x08\xb4\x68\x5c\x08\xcb\xc6\xe5\xc8\x76\x47\x15\x47\x21\xb6\xcb\xb8\x7c\xf1\xb3\xcc\xb8\xb0\xe7\xc6\x15\x56\x51\x06\x8d\x18\xd7\x3a\xa0\xba\xe3\x7a\x12\x9c\x0d\xb4\x76\xc0\xb4\x11\xa3\x0c\x53\x2c\x1a\xd5\x9a\xdf\x0a\x87\x15\x8a\x03\xf1\xc2\x30\xd8\xad\x61\x85\xfd\x5b\x35\xd8\x83\x61\xaf\x2a\xf0\xeb\xf6\x78\xb9\x05\x26\x6b\x44\x33\x03\xfa\x0f\xb5\xb1\xdf\x34\xe0\x3b\xc6\x87\xaf\x3c\x1b\x48\xe3\x63\xf8\x61\xd6\x30\xe6\xe3\x63\x18\xfd\x07\xb6\x7e\x20\xb8\x1f\x45\x6a\x1a\x45\xb5\x83\xd2\x72\x0c\x7a\xd4\xc1\x93\xcd\xf1\x46\xbc\xa3\x18\x6a\x39\x60\xda\x80\xdb\x1f\x14\x2c\xcf\xb1\x47\x85\x15\x1c\x55\xc0\xb8\x22\x22\x19\xd5\x3f\xa4\x3e\xaf\x34\x1a\x8c\xf5\x68\x88\x61\x46\x83\x4e\x35\xca\x1e\xb0\x77\x38\xde\x3d\x67\xf4\xea\xfc\x92\x3d\x28\x73\xdf\x25\x0d\xc7\xaa\xd0\xd3\x0f\x2f\xbb\xb1\x4e\xb1\x1d\xf4\xbd\x30\x32\x78\x5e\x33\xbc\x2a\x00\xcd\x40\xc8\x3c\x9c\xf9\x08\xd5\x06\xd7\xc9\x17\x78\x62\x13\x0f\x87\x9a\xbc\x56\x6c\xf8\xc2\xd0\x3a\x0c\xe0\xa0\xff\x1e\x00\x67\xe8\xbf\xcb\xdd\xd2\xe8\x2a\x1f\xd0\x77\x4c\x9d\xca\xdb\xa9\x3b\xfc\x24\x3c\xfa\xa5\x6c\x44\x49\x75\x5e\x44\x18\xdd\x3e\x7c\x41\x73\x43\xc8\x38\x7a\x21\x05\xbc\xa6\xd5\x84\x6a\x77\x8e\x90\x36\x77\x74\x48\xb2\x07\xf6\x6e\xe7\xe5\xa6\xd1\x69\xe3\x46\x7f\xd2\x80\x7f\x54\x24\xbc\xef\x84\xb0\x8c\x37\xd5\xc6\x1b\x4f\x8c\x29\xbb\xad\x8a\x14\xd2\x9c\xb4\x04\x53\x0c\x3b\x79\xc2\xef\x8d\x49\xd3\x31\xb9\x2c\xb4\x68\x63\xa2\xa3\xc9\x99\x4d\x25\x2b\x05\x03\x2c\xfd\xd4\x50\x4f\xc0\x65\x28\xa4\xba\x4c\x8e\x64\x72\x3d\xa6\x57\x81\x32\x4d\x0a\x7a\xd2\x80\xf0\x18\x75\x4c\xaa\xff\x84\x1f\x3d\xf1\x1a\x8a\xdd\x3f\x83\xb2\x98\xc1\x35\x99\xb1\x78\xba\x3e\xe6\xe2\x0d\xd8\x31\x17\xc7\xfc\x9e\x83\x8e\xf9\x80\xae\x37\xc0\x19\x6b\x03\x5c\x1d\x6b\x83\x31\x1d\xeb\xbd\x3c\x3b\x10\x5f\x8e\xc5\x93\xdd\xb1\x18\xc0\x8c\x75\x0a\xe9\x89\x10\x8e\x07\x48\x63\xf1\x18\x7a\x2c\x54\x6a\x0d\xcd\xdb\xc0\x70\x56\x67\x76\x47\x40\x3a\x56\x0f\xda\x41\x20\xdb\xb1\x82\xdf\xc7\xc6\x42\xa0\x3f\x56\x00\x8c\xf1\xe1\x35\xfc\x63\xc5\x57\xd1\xe6\xbd\x45\x39\xd6\x60\x9c\x35\xee\x7f\x96\xe5\xa6\xa4\x6f\x21\x89\x9a\xc6\x0d\xac\x3e\x6e\x0a\xe1\xa6\x59\xb9\xb1\x73\x6e\xca\xf2\x26\x24\x1e\x37\xf0\xc1\x78\xea\x06\x29\x3e\xb5\x4f\xaf\x69\x3c\x01\xed\x7c\xb8\x24\xef\x0a\x4f\xe1\x0d\xa2\x29\x67\xe2\xbd\x81\x29\xb4\x13\x53\xca\x27\x4d\x69\x20\x1d\xc5\xfc\x14\x34\x65\x20\x63\x4c\xe4\xcc\xe9\x9e\xa6\xfc\x5a\x9a\xbc\xbd\x38\x55\x6a\x9a\xd0\x5e\x04\x7b\x53\x1b\x02\x89\xa9\xad\xd9\x40\x82\xe7\x40\x85\x81\xa7\xdf\x99\xe6\x45\xf6\x97\xe0\x11\xb2\x9a\x17\xda\x5d\x8a\x15\x9f\xd4\xfc\x79\x29\x1e\x31\xad\x79\x81\xcd\xe5\xbc\xd1\x35\xaf\x50\x94\xf2\x6b\xfb\xbc\x10\xab\xcf\x6b\xd5\x0d\x94\xc6\x65\xbe\x77\x5c\x26\x8c\xcb\xb4\x93\x39\x05\xef\x44\x32\xd3\xd0\x9b\xb5\x27\x4d\xeb\x09\xc8\x62\x4f\xf3\x3d\x7c\x9d\x06\x63\x3f\xe9\xd4\xa7\x6f\x80\x83\x69\xfa\x2e\x0f\xe8\x5e\xd0\xd8\x51\x7e\x2a\xc1\xdc\x74\x2b\xe8\x87\xd7\xfe\xa0\xbe\x13\xd5\xeb\x7b\x09\x91\x6a\x3c\xbd\x9d\x8b\x09\x4d\x1c\x95\x7a\xd2\x64\x4d\xef\xf8\x59\x06\xed\xec\x15\xde\x6e\x7a\x34\xd9\xc1\x26\x26\x83\xff\xe9\x63\xa4\xe9\x53\xd0\x70\x85\x71\x64\x84\x38\x93\xa1\xc3\x44\x00\x3a\xfd\x49\x93\x80\x75\x32\x5a\x9c\x21\x08\xbd\x91\x9e\x6f\x62\x0d\xb4\x0d\x68\xf5\x84\xd7\x9d\xbc\x39\x34\x81\x47\x4b\xe2\xbd\xd0\x17\x5c\x4d\xca\x16\xf8\x2e\x4d\x1e\x8d\x4d\x5e\x3d\x99\xbc\x0a\x39\xc3\x4e\x8a\x33\xac\x82\x80\x8d\xf7\x0b\x6d\xdf\x9b\x14\x33\x16\xab\x2d\x3e\x16\x14\xac\x8a\x78\x70\x06\xb0\xd1\x0c\x98\xc4\x89\x15\x5e\x60\xba\xde\x80\xe9\xdf\x26\x9d\xab\x09\x08\x42\xe1\xb9\xe2\x83\xd5\x07\xd0\x9b\x2b\xb8\x2c\xb7\xc2\x14\xcf\x5b\xdb\x7c\xd2\xbc\x61\x16\xe7\x8d\x89\xdd\x94\xca\xed\x69\x3e\xd0\xd6\xa7\x33\xcc\x5c\x67\x79\xd2\xaa\x5b\x68\x29\x92\xd6\x7b\xd5\x60\xb5\xf7\x36\xf0\x6a\x99\x6f\xef\xc5\x94\x57\x6d\x56\xdb\x3d\xad\xc6\x2b\xea\xab\xf1\x13\xe9\x6a\xef\x27\xa6\xd5\x8c\x98\x7a\x35\x5e\xcd\x5e\xcd\x26\xc8\x57\x11\x8c\xac\xf6\x69\x58\x85\xd5\x78\xc6\xba\xda\xb4\x92\x56\x5b\xbc\xa7\xb8\xda\x57\xf1\xda\x79\x9a\xb9\xfa\xc9\x05\x5a\x9d\x9f\x83\x56\xf7\x96\x16\x43\xe9\xd5\x61\x45\x56\x6c\xd2\x12\x0d\xc5\x0b\xbc\x80\xe0\x79\xe5\x7c\x0d\x3d\x56\x41\xc2\x0b\x12\xff\x98\xcf\xf7\x3f\x03\x5f\xc9\xd8\x6e\x5f\xc9\x6b\xd5\xf4\x15\xe8\xdc\x57\xe0\xc7\xbe\xef\x3d\xf8\xaf\x40\x74\x5f\x69\xf8\xd9\xb8\xd2\x57\xba\x47\xfa\xca\x7b\x15\xeb\x0b\x85\xff\xf2\x83\xfa\x57\x2f\x83\x68\xbe\x10\x36\x5e\xdb\x8e\x8a\xbc\x14\x89\xdc\x06\xd6\x1a\x1b\x88\x1d\x0f\x12\x02\xa5\x2f\x82\xdb\xaf\x8e\xa1\x25\x7d\x75\x6a\xa0\x2f\xa3\xcc\xbf\xb6\xf1\x0b\xe2\xd7\xf2\xdb\x9b\x65\xda\x75\x04\x88\x9e\x88\xda\xbf\x56\x0a\xa6\xfb\xb5\x36\xdf\xd4\x8b\x81\x41\x10\x77\x7f\x2d\xd8\x6e\x08\x88\x81\xd5\x78\xf3\x27\xe9\x17\x33\xe5\x29\xf7\x97\x17\x25\x79\xf9\xfb\xeb\x25\x4b\x73\xa4\xab\x22\x6f\x82\x3c\x60\x7f\xff\x23\xde\xd2\x2d\x36\xd3\x0d\x7b\x07\x7b\x0b\xd2\x16\x32\x1a\x48\x1c\xd0\x15\x5a\xdd\x5b\x02\xc1\x74\xba\xb1\x6d\x6e\x19\x1d\x64\xa2\x10\xf8\xe8\x06\x3e\x86\x33\xb9\xdf\xef\x8a\xb7\x0a\x96\x96\x96\xfa\x46\x6c\x55\x90\xd0\x68\xdc\xba\xa5\x5b\xdf\x70\xf8\x56\xfd\x60\xa7\xdd\x6a\x01\x5a\xf8\xcd\xeb\x86\x91\xbc\x75\xa6\x9b\x5f\xaf\x6e\xd8\xc8\xfb\xd2\x97\x82\x13\x2c\xe5\x4d\x13\x79\x03\x4a\xde\x97\x31\x02\xbf\x61\xef\x6e\xdb\xd1\xbf\x1d\x78\x2c\x3b\x48\x49\xd8\x25\xb7\x35\xc0\xd6\x1b\x08\x94\xae\xe2\xb6\xf6\x01\x69\x6c\xca\x4b\x31\x37\xc2\xac\xdb\x06\xc2\xd8\x1b\xd6\xe7\x86\xae\xdc\xff\xee\x28\xdc\x5e\x8e\x74\x23\xae\x49\xb7\x73\xc7\xdc\xee\x3b\x48\x49\xf4\x37\x3c\xdc\xbc\x3d\x0a\x1f\xe3\x01\xc5\x60\x60\x6f\xee\xd0\xfc\x01\xe5\x25\xde\x9b\x86\xec\xe6\xcd\x8d\x9b\x0e\xfc\x81\x49\x7b\x20\xaf\x47\xe9\xf7\x1e\x5f\xf8\xa1\x88\x40\xea\x4f\xb7\x90\xf4\xa7\xe1\x89\x47\x6b\x7f\xee\xe9\xff\x00\x00\x00\xff\xff\x96\xd2\xdb\xc1\x3c\x33\x00\x00") +var _keysWordlistEnglishTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\x5b\xdd\xbe\xbc\x2a\x08\xbd\xf7\x2d\xc9\xa8\xd8\xa3\xe2\x41\x9d\x76\xfb\xe9\xcf\x6f\xad\xfe\x17\x83\xe5\x07\x2a\x22\x2c\xcc\x91\x4d\xda\xee\x2d\xc9\x66\xc5\xe6\x93\x64\x2b\x9a\x64\xf3\x35\x41\xbf\x78\x1e\xda\xf0\x32\x3c\x36\x24\x33\x24\xf3\x7d\xc5\x9e\x64\x5b\x43\x93\xe4\xac\x63\x20\xb1\x9d\x95\x73\xf6\xf5\xa6\x6f\xf1\x65\x0a\x56\xd9\xf6\x24\xd9\xd7\x98\x96\x93\xe4\xff\x96\x05\x72\xc3\xd9\x18\xf5\xa7\x61\x2c\x79\x7a\x80\xc6\xcb\x75\x2e\x29\x49\x76\xe9\x33\xc9\xbe\xe3\x67\x99\x8f\x6f\xf9\xfe\xb3\x06\x5e\xab\x81\xae\x02\xfa\x95\x96\x15\xa9\x21\xd1\xf0\x0d\x3d\x1e\x87\x58\x20\x71\x0c\xfd\x08\xc1\x78\x4e\xb1\x96\xe4\x54\xfc\x30\xe6\x33\x54\x93\x5c\x2a\x7b\x12\xab\x89\x2d\x2c\xba\xc7\x4c\x62\x03\xd2\x29\x12\x35\x49\xd9\x16\x68\xf6\xcb\x4b\x92\xa2\x28\x2f\xa6\x2d\x49\xc1\x7b\xd1\x07\xd4\xef\x24\xa5\x3a\x06\x58\xbc\xa1\x71\xbf\x24\x49\x09\x95\x1d\x15\x86\x27\x29\x53\x23\x49\xb9\xe5\x19\x49\xaa\x4c\x5d\x81\xf4\xcf\xda\x99\xa4\xfa\x4b\x29\xcf\xba\x86\xee\x49\x9a\x94\x07\x1c\x5b\xbe\x20\xa8\x96\x8d\x23\x6f\x27\xf8\xb4\x13\x63\x6c\x67\x3c\x49\x9a\x55\x88\xae\x7d\x98\xd5\x7c\x51\x2a\xad\x51\xa0\xcd\xe7\xc5\x06\xe3\x66\x32\xb5\x35\x41\x6a\xff\x2d\xd4\xfa\x35\x85\x42\xb4\x27\x49\x17\xcc\xae\x7b\xf1\x13\x6f\x5d\x25\x90\x80\x6b\xef\x41\x35\xe9\x61\x25\x49\xe4\x0b\x84\xeb\x1b\x2a\x20\xe0\x19\x27\x38\x42\x6a\x51\x31\x81\xa8\x18\x77\xd4\x27\x49\xf8\x6a\xc8\x09\x0c\x1f\xa9\x62\x66\x11\xf6\xe5\x1b\xe4\x87\xbe\x63\xea\x41\x15\x89\x69\xac\x30\x6f\x8f\x4f\x92\x81\x5f\x57\x94\x8c\x21\x5c\xfc\x31\x94\x94\xf5\xc6\x58\x55\x93\x8c\x79\x55\x49\x32\xaf\xa2\x53\x93\x4c\xaf\x49\xe6\x94\xfc\x41\xa2\x18\xc0\x9c\x36\xd7\x8e\xb2\x7f\x0a\xbe\xfe\x29\xe3\xda\xa1\x57\xeb\xa4\x92\x71\x15\xd6\xa4\xd8\xd7\x74\x90\x55\x5b\x92\xaf\x06\x55\xe8\xeb\x59\x76\x47\x0a\xd5\xba\xe5\xa3\xa0\x41\xfa\x24\xb9\x75\x38\x86\x73\x1f\xab\x24\xb9\x3f\xb7\x40\x11\x7f\x6d\xa4\x4d\xb6\x27\x6d\x92\x2f\x2d\x1e\x78\xf0\x96\x36\xd9\x4f\x4d\x9b\x9c\x69\x93\x42\x85\xde\xa0\x6f\x0d\x15\x4b\x49\x9b\xd4\xcd\x3d\x6d\xd2\xa4\x09\x92\xa6\x68\xc9\x9f\x16\x54\x0a\xea\xf6\x06\xa1\xa2\xfa\x00\x83\x61\x19\xf4\xa3\x33\x6d\x32\x67\xd1\xb4\xa9\xe4\x0b\xb4\x81\xac\xf9\xa4\x4d\xb3\x60\xe3\x6e\x9a\x31\xdc\x4d\xf5\x48\x9b\x1e\x1e\x78\x3e\xc1\x52\x2f\xf9\xe2\xe5\xb2\xb6\xa7\x4d\x0b\xf7\xf7\xa6\x50\xf7\x4d\xcb\x4c\x9b\x36\xf2\x6c\x7a\x18\xde\x06\xc8\x0c\x01\xef\x09\x75\xdf\x74\xde\xaa\xe0\xf4\x38\x58\x58\x7e\x32\xc6\x62\x78\xfe\xe0\x81\xb9\xaf\xc6\x6d\x16\x78\x89\x79\xa5\xcd\xde\xe6\x05\x6b\xb7\x15\xd9\x15\xb4\x92\x36\x4e\xaa\x08\x3a\x2b\x2a\x28\x87\x81\xd8\x0a\x79\x15\x77\xd2\x31\xbc\x22\xe5\x04\xcb\x22\x01\xc3\x35\xae\xb4\x39\x16\x64\x73\x99\x69\xf3\xfd\x49\x9b\x5b\x49\x9b\xd7\x2d\x6d\xd8\xbc\x9b\xb7\x35\xd2\xe6\xfe\x01\x41\x37\x1e\x3b\x46\xe3\x81\xbd\xba\x39\xf5\x75\x83\x39\xdb\x7c\x42\xc9\xb6\x77\xcb\x6d\xfe\x9b\x36\x7f\xd2\x16\x92\x39\xc8\xe0\xc2\x84\x60\x60\x21\xa8\x1f\x14\x28\xcc\x02\xa8\xfe\xe1\xc5\x30\xc7\x30\x6a\x41\x18\x16\x21\xec\xbc\xd0\x9c\xdd\x85\x0d\x94\x7b\xce\x5e\x0c\x0f\x1f\x08\x34\xbc\xb1\xb1\xa3\xfb\x78\xf7\xf8\x16\x7e\xa3\x88\x73\x5c\x1b\x6c\xfc\xb6\x76\x4c\x70\xed\x27\xc6\xb3\x8e\x43\x8a\xa7\x6d\x59\xd9\xd3\xb6\xca\x06\xf2\x01\x29\x2c\x6e\x3b\x9b\xb4\x0f\x98\xad\xd8\xd1\xd1\x8a\xf3\x7d\x83\x20\x20\x97\x35\xac\x51\xe0\x6b\x80\xf3\xbb\x50\xeb\x21\xfd\xfb\x4b\x59\xb6\x0d\x9b\x24\xcb\x66\x0d\xb4\xe0\x39\xcf\x35\x52\x7e\xf3\x3f\x20\xa5\x80\xd4\x94\xa5\x6a\x08\x92\x9e\xb2\xa0\x41\x13\x14\xb5\xac\x4c\xf6\x07\xb4\x39\x4b\x1c\x2d\xdb\x57\xc0\xaa\x3d\xcc\xeb\xff\x3a\xe8\x36\xd9\xae\x4f\x61\xb7\x81\xdf\xc6\x2a\xb1\x83\x9c\x0e\xda\x75\x22\x09\x70\x0d\x3c\x0e\x34\x1e\x17\x88\x35\x54\x19\x93\xfc\xc6\x22\x3b\x54\x99\x52\xfc\x44\x9a\x51\x6d\xea\xe9\x6c\x3e\xdf\x8a\x0b\x4b\xf5\x6e\xa4\x2c\x8b\xc6\x24\x63\x91\xb3\x5a\xc1\xfa\x65\x2d\x8a\xfa\x5a\x61\xbd\xb3\xb6\x01\x49\x68\x9b\x8b\xb9\xa1\xe8\x47\xe3\x1d\xf6\x05\x3f\x94\x2f\x29\x1f\xd0\xda\xc9\xed\xa2\xcd\xcc\x97\xf8\x00\xed\x10\x78\xbe\x24\xde\xcc\x41\x3a\x53\xbe\x54\x3a\x68\x46\x5b\x55\xe6\xeb\x01\xc2\xe9\x5e\xd8\x9d\xf9\xb2\x0c\xf5\x81\xab\x46\x11\xf4\x20\x5f\x56\x9b\xa2\x86\xc3\x8d\xe6\xcb\x9d\x6d\xc3\x9b\xe5\x94\xaf\x95\xe1\x57\xf2\xb5\x1a\x18\xaf\x68\x29\xdb\x09\xf9\x5a\x6b\xf0\x5b\x29\x5b\x60\x53\x67\x9b\xf6\x07\xde\x00\x18\xd9\xbe\x56\x52\x2e\xf0\xad\xb9\x60\x60\x45\xc2\x8e\x07\xe9\x0d\x82\x27\xd8\xa2\x5c\x34\x3e\xa0\x5f\xcc\xaa\x60\x2f\xe4\x42\x47\x97\x8b\x1d\x07\x68\xdd\x40\x39\x98\x62\xe0\xe4\xac\x84\x35\x29\x1c\x6a\xf1\x79\x81\xae\x1d\xf4\x06\xd3\x85\x36\x0b\x3a\x55\xd6\xa0\xc0\xca\xe2\xfa\xb9\xbc\x14\xc2\xf0\xec\x6d\x21\xdd\x35\x65\x3f\x0e\x45\x82\x61\x3b\xd6\xc2\x4b\x81\xc3\xc9\x0e\x53\x9d\xbd\xc0\x03\x64\xaf\x9b\x35\x54\xab\x24\x07\xf0\x42\xf6\x8a\xb1\x79\xa5\x30\xbc\x76\x38\xd3\xec\x0d\xab\x8a\x74\x5f\x64\xd3\x0e\x8b\x8a\xf4\x24\xa0\xc9\xde\xda\xcb\xbf\x0d\x83\x79\xc9\xde\x66\x38\x7a\x6f\x5f\x83\x39\xc9\xb0\x40\xd9\x99\xd5\x3b\x6b\x74\x30\x0e\x68\x0c\xac\x74\x76\x2c\x86\x47\xbc\x7c\x38\xa5\x39\x39\x88\xc5\x59\xae\x36\xb1\xf4\xbe\xe0\xc3\xb3\xaf\x18\x4c\x06\xa7\x47\x81\xfb\xe3\x53\x53\x86\xc1\x02\xc5\xfe\xcf\x21\xc7\x04\xad\x20\x8d\x19\xd8\x20\x21\x94\x63\xc8\x5d\x40\xff\x9e\x94\x43\x59\x49\xe1\x3b\x73\xa8\x82\x87\xde\x29\xc3\xa4\x61\xa3\x85\x41\x4c\x61\xa3\x83\x02\x2e\xe4\x70\x3c\xc3\x76\xe6\x78\x47\x19\x7e\xef\x29\xc7\xca\x86\x79\xc5\x52\x52\xc3\x50\x63\x55\xee\xee\x58\x8d\x35\x17\xc7\x81\x8e\x9f\xc1\xed\xbe\x36\x4d\x79\x95\xb9\x20\x8d\xd5\xf1\x7b\x8d\x7b\x5e\x61\x8e\x8d\xb6\x22\xa8\x4c\xeb\xdf\x0e\x5b\x81\xbd\xb9\xc6\xc5\xad\xb5\x06\xcc\x77\x5e\x90\x01\x3d\xd3\x2e\x7b\xda\xa5\xc2\x50\xed\x30\x49\x3b\x1d\xf2\xfe\x82\xae\x5d\x68\x91\x77\x88\x63\xe7\xc6\x67\xe6\xdd\xd2\x2e\x4f\xda\xb1\x93\x77\xdd\x64\x2a\x92\xb0\x91\x76\xcd\x70\x5d\xbb\x66\xad\x1b\xea\x2a\xa0\x33\x92\x02\x2d\xda\x15\x8b\xc9\xea\x10\xe5\xc0\x03\x6b\x1d\xda\xf8\x72\xbc\xb5\x0e\x30\x27\x60\xdd\xb5\xb0\xa7\x62\x5f\x56\xac\x70\x2d\xbb\x56\x63\xf5\x66\x1c\x41\x23\x76\xda\xb5\xa1\x26\x31\xdd\xae\x5d\x59\xb1\xfb\x30\xbe\xce\x0b\x14\x28\x60\x57\x82\xb0\x5d\x47\x0e\xdb\xf8\xa0\x6c\x32\xec\x6c\x48\x3e\x20\x1d\x86\x69\xd7\x31\xc3\xd1\x64\x8a\xa1\xa7\x09\xc5\xdb\xf5\xab\xc5\x3b\x52\xd8\x8f\x5d\xbf\x50\xa9\xdd\xe4\x84\x0a\xed\x1c\x93\xc1\x50\xec\x48\xe3\x49\x3b\xab\x99\x0e\x45\x89\xce\xb4\xdb\x71\x60\x3a\x76\xd2\x88\xef\x76\x36\xd8\x90\xdd\x8a\xd6\x2a\x69\x37\x62\x9e\xdd\x9a\x0f\x59\x78\xa0\xc2\xef\x86\x61\xda\x78\xa1\xfc\x6e\xe3\x55\xe9\xdd\xc6\x2b\x4a\xc3\x2a\xd9\xa8\x36\x06\xd2\xd7\x87\xef\x36\x3a\x45\x68\x63\xbe\x4b\x0b\x49\x82\xcf\x97\x2b\x63\x5f\x0f\xe6\xfe\xfd\x3d\x69\x77\x86\x28\xbb\xe7\x45\xe3\xbd\xfb\x99\x76\x2f\x05\xa4\x5f\xd6\xd2\xee\x55\x98\x34\xae\xa2\xb7\x8f\xa2\x55\x63\x23\x12\x0c\xc4\x17\x94\x78\x07\x7e\xde\xb9\xb7\xf6\x90\xd3\x1b\x12\xcc\x2e\x84\x81\xd2\x1e\x72\xa7\x9d\x3b\xea\x8d\x78\xf6\x30\xd6\x35\x74\x18\xd6\x3e\xa0\x1d\x84\x8c\x20\xf1\x58\xa8\xfc\xa4\x7d\xe5\x4f\xda\x57\xdd\xd2\xbe\xa0\x31\xeb\xd5\x53\x60\xd9\x9d\x66\x6f\xe7\x4a\xdf\x12\x47\xda\x9f\x26\xb0\x57\x2a\x50\x69\x15\xc4\x11\x2a\x51\x1e\xd0\x06\x32\xaf\xa4\x32\x8c\x39\x63\x82\x3c\x49\xf3\xe5\x49\xf3\x0b\xd4\x34\x7b\xf3\xfa\x24\x05\x64\xe1\xe6\xd7\x7d\xc1\x33\x26\x3d\x68\x11\xf5\x3c\x93\x12\xc3\xa8\x11\x99\x68\xd9\xfc\x4e\x5a\x76\x3e\x6b\x9e\x81\x11\x14\x3d\xa5\x4d\xa4\x14\xaf\x16\xed\xd7\xbf\x8c\xaf\x40\xf2\x5a\x0c\x4c\xcb\xd0\xa4\x75\x93\xf8\x20\x01\x62\xd3\x0a\x8c\x85\x5c\x85\x1b\xd4\xea\x74\xbc\x5a\x7b\x71\x94\x76\x47\xb0\xa3\xb5\xcf\x27\x69\x23\x44\xd0\x06\xbc\x8f\x6d\xa0\x80\x39\x63\x20\x75\x58\x44\x6d\x8a\xc9\x34\x0d\xcc\xad\x1d\xd4\x00\x6d\x27\x8c\x80\xb6\x13\x7b\x50\xdb\x45\x6d\xd1\xf6\x03\xfe\xad\x60\x87\x69\xf3\x75\x5e\x49\x5b\x58\x66\x02\xd5\x80\x7f\x0f\x54\x84\x6d\xc0\x56\x7c\x5f\x02\xad\xb8\x4f\x34\x69\xb7\x01\x97\xa3\xff\x01\x63\xe8\x7f\xcb\x7a\x02\x06\xd2\x80\xde\x6a\xb0\x2c\x7c\x70\x46\x11\x90\x43\xac\x3e\x93\x8e\x2c\x68\x3e\x86\x3c\xa0\xca\x11\x8d\x49\xc1\x4f\x0d\x00\x27\x9d\x97\xe5\x91\x14\xda\xcc\x62\xb8\x61\xfd\xfa\x07\x8f\x5e\xbe\x9a\xf4\x97\x72\xf8\x95\x0a\xa7\xa0\xbf\x8c\xe9\xf5\xf7\x1f\xca\xd0\xdf\x4c\x91\xff\xe6\x82\x30\x49\x7f\x19\xda\xeb\xaf\xd2\x46\xea\xaf\x46\x36\x66\x5c\x02\xed\xd2\xdf\xcb\x36\xac\xff\xaf\x91\x19\xc5\xf2\xcb\x0c\x87\x52\xeb\x6f\x87\x85\xd2\x5f\xc6\x6e\xfa\xdb\x29\x8e\xdf\x5e\xb0\x6d\xf4\xb7\x3b\x79\xf5\x78\xc7\xc0\x10\x4d\x7f\x27\x64\xf1\x28\x7e\x40\xb4\xe9\x10\x60\xe4\x74\x60\xc1\x0f\x81\xb9\x7f\xd2\x01\xbb\x7a\x88\xb5\x09\x3a\xaf\x74\x00\x51\x1e\x02\x55\x39\x10\x28\x1c\x52\xa1\xc1\x07\x62\xea\x91\x0e\x69\xf8\x65\x64\xb4\x09\x85\x3e\x10\xa7\x1e\xf2\xfa\x81\x43\xc0\x06\xb6\xe7\x10\xea\xeb\x21\xd3\x10\xcc\x1e\x8c\x35\x0f\xf9\x7a\x40\x2c\x87\x0a\x5d\xcd\xa1\x5b\x2c\x98\xb2\x43\x77\x85\x3b\x06\x74\x38\x54\x77\x10\xbc\x55\x29\xc8\xc0\x0a\x1c\x3a\xa6\x7d\x59\x07\x3b\xf1\x20\xd0\x39\xf4\x4e\x87\xc1\x25\x1c\xf6\x06\xa0\x87\x69\xd9\xd3\x61\x27\xf9\x43\x9a\x87\x95\x0a\x32\x59\x0b\x8b\x7b\x20\xc2\xa1\x4f\x38\x8c\x0e\xe9\xb0\x06\x2b\x77\x18\xdb\x60\x42\x06\x98\x7e\xd8\xc8\xac\xce\x32\xbc\x4f\x22\xf6\xc3\x7e\xd3\x51\xe4\x04\x81\x88\x0a\x1c\xd9\x51\x30\xf9\x82\x29\xa6\xa3\x60\x1e\x85\x3b\xf7\x00\xd6\x3a\x8a\xb3\x14\x88\xeb\x28\xce\x2a\xdc\x5a\x47\x59\xb6\x83\x92\xc3\x93\x0e\x97\x9a\x0e\xcf\x90\xb5\x9f\xe9\x00\x8c\x3a\x1c\x33\x72\x9e\x8e\x1c\x08\xcb\x0e\xf7\x99\xde\xed\x85\x28\x73\xf0\x05\x81\xc9\x81\x20\x1f\x96\x03\xd6\xeb\x70\x98\xb5\xc3\x83\x61\xf3\xe1\x63\x90\x17\x51\xdc\xc1\x63\x84\xc3\x7f\xd3\x11\x72\x52\x4a\xc1\xa9\x84\xfe\xb7\x60\x43\x8e\x50\x8c\x28\x0c\xaa\x74\xc0\x0c\xa2\x10\x23\x0a\x67\x31\x50\xd2\xc1\x38\xe9\x08\x07\x5c\x3d\x62\x41\x44\x80\x1d\xc7\x6a\xf8\xb5\x27\x1d\x2b\x1a\xd5\x0d\x20\xfd\x58\x5c\xf4\x53\x18\x44\x31\xd8\x3e\xa5\xc8\xef\x83\x84\xe0\xfe\xc4\x18\x4e\xe9\xe9\x14\x1e\x10\x9c\x12\xdb\xbf\x14\x31\xd4\x29\x51\x2c\x23\xa1\x9d\x3b\x65\xe0\x87\xda\x13\x75\xa8\x71\xa7\x2c\x36\xf8\xd3\x74\xc2\x14\x49\x41\x6a\x6b\x20\x09\x66\x22\xde\x38\xb5\x2d\x28\xc0\xa9\xe3\x1d\xd4\x85\x09\x9d\x06\xb3\x79\xc2\x5f\x9c\x76\xc2\xa2\x9f\xaf\x82\x9c\x16\x72\x1c\x78\x8d\x92\x4e\x38\x8e\xb3\xc8\x0e\x02\xd5\x3c\x8b\x04\xe9\x18\xe9\x2c\xf0\x7f\x67\xb1\xda\x07\x52\xdf\x48\xbd\x82\x62\x8a\xc5\xd9\xda\xef\x74\x22\x9c\x3e\xa1\x18\xa7\xef\x3b\x14\xeb\xc4\x4a\x9f\x58\xe2\x93\xc1\xc3\xe9\xf0\x5a\x92\x4e\x1f\x5d\x0b\x92\x61\x3d\x9d\xf0\xcf\x2d\x9d\x10\xfe\x19\xb2\x81\x60\x14\x8c\x92\xcf\xe0\x14\x02\x16\xee\x64\xac\x7c\x86\x7c\x01\x03\xce\x50\x74\x15\x0a\x49\x86\xed\x20\x7a\x80\x22\xd7\x33\x17\x20\x7c\x75\xd0\x3b\x9d\xb1\xc0\x68\x41\x79\xce\xc5\xd1\x2d\x4e\x6d\x59\x41\xbe\x4d\x89\x74\xae\x96\xce\xa7\xa6\x4b\x60\xbd\x18\x75\x5d\x52\x8e\x74\x49\xad\x8a\xe7\x4a\x75\xbb\x60\xbc\x2e\xe9\xfd\x49\x17\xa2\x49\xe4\x04\x72\x62\x5c\xa0\x5f\xe8\x30\x82\x2f\x9e\x93\x5c\x72\x7f\xd2\x25\x7f\xac\x82\x08\xff\x52\x29\xf3\x42\x12\x13\xf4\xfb\xa4\x0b\x3e\xf3\xf2\x33\x5d\xaf\x7f\xbc\xb4\x14\x07\xad\xca\x97\x9e\x2e\x6d\xe9\xd2\xf0\x74\xd9\x0e\xe5\xb9\xec\xbc\xd2\x05\x10\x70\xc1\xda\x5d\xd6\xd3\x85\xfd\x7e\xd9\x98\x58\x98\xcb\xb7\x0d\x34\x03\x7b\x5c\x58\x88\xcb\x8b\x82\x18\x50\xe9\xf5\xee\xbf\x0b\x01\xcb\xe5\x8d\x75\x1c\x75\x3a\xde\xa3\x81\xc0\xc5\x5c\x74\x85\x97\x8f\x37\x90\xa6\x5a\x5d\x3e\x15\x8f\x0b\xc5\x30\x5b\xd7\xda\xd2\x05\x3d\xbd\x56\x95\x06\x0a\xcf\x7a\xad\x0a\x06\xab\xed\xa1\x3b\xd2\x13\xc3\xc2\x2a\x5c\x2b\x76\x56\x08\xe6\x40\x0a\x6b\x6c\x14\xea\xb3\x61\x29\x81\x04\x2d\x7b\x4b\xb6\xab\x24\x1e\x2b\x23\x48\x34\xb4\xb2\xb3\x21\xc8\xc1\xcc\xad\x00\x2a\x30\xa5\x21\x33\x02\x74\xab\x46\xdf\x67\xb5\x12\x2f\x5b\xad\xb0\x1f\x56\x3b\x3c\x9c\x55\x7a\x17\xab\xef\xc9\xa5\xd5\xbe\xe0\x1c\x0c\x91\x84\xb5\xd7\xbd\x59\x63\x20\x67\xed\x1f\xfc\xb6\xb6\xeb\x2f\xa8\x11\xcd\x58\x23\x8a\xb3\x06\x24\x15\x4f\xb2\x06\xef\x81\xa4\x58\x66\xea\x51\x93\xb5\x0b\xd6\xde\xda\xa5\x50\x49\x6b\x36\x81\x79\xad\xfd\x28\x2b\xfd\x2c\x36\xad\x2f\x47\x20\x59\x6b\xcd\xb3\x92\x53\x5f\xa0\xff\x2d\x63\x9d\x81\x70\xcb\xda\x78\x1b\x22\x2c\x44\x42\xa7\x69\x0d\x11\x0f\xd8\x4e\xce\x0e\xf8\x02\xda\x67\x6d\x7a\xb2\xf6\x7d\x9f\xbf\xc6\x4e\x5e\x4f\x6f\x01\xc1\x8e\x02\x79\xdb\xf0\xc2\x01\x8c\xb1\x34\xd9\xd4\x9a\x00\x75\x9f\xf4\xf3\x1e\x55\xfd\x08\x76\x4c\xfa\xe1\xef\xef\x2f\xfd\xa8\x14\x38\xce\x1f\x95\x06\x5a\xca\x93\x7e\xf4\xd6\x92\x7e\x7c\x4b\x3f\x08\x90\x7f\x00\x2a\x7e\x7c\x05\x94\x0a\xb0\xe8\x67\x01\x0f\xfe\x2c\x2c\xea\x0f\x62\xef\x9f\xc5\x53\xea\x9f\xd5\xcc\x03\xc9\x27\xf1\x10\xff\x23\xed\x94\x70\x4f\x1f\xec\xe9\x8f\x6a\x4f\x1f\x38\xc7\x85\xf4\x49\x1f\xcb\x9f\xf4\xb1\x1d\xbf\xc6\xf7\x86\xe7\x76\xee\x5e\xd3\x07\x70\xfe\x63\x13\xbf\x8c\xbd\xf2\xc1\x94\x3f\x36\x27\x9f\x6f\x4b\x9f\xa6\x9a\x3e\xcd\x0e\x50\x38\xae\x4f\xf3\x3b\x15\xd9\xf0\xd3\x02\xea\x91\x8a\xec\x00\xa3\x45\xf6\x27\x15\xf9\x68\x2a\x08\xf7\x8a\xb4\x73\x41\xb7\x8a\xf4\xe9\x78\x0f\xbe\x4c\x56\x9d\xd6\x52\x41\xdc\x07\xda\x00\xbc\x8b\x7c\x25\x15\x01\xfb\x1b\x65\xf7\x80\x33\x29\xf2\xb0\xfe\xdf\x93\x8a\x0a\xbb\x51\x39\x40\xa2\x81\x7e\x35\x01\x03\xc3\x7e\x17\x3d\x66\x2a\x7a\xa6\x57\xc1\x8b\x9e\x70\x5c\x45\x6d\xbc\xa5\xd5\xd1\x82\x59\xed\x9c\x17\x92\x91\x8a\x7a\x87\x91\x01\x8a\x65\x39\xcf\xe0\x0a\xe2\xb0\x54\x4c\x22\x15\x40\x8b\xf9\x20\x0d\xc0\x94\x62\x99\x3b\xa4\x40\x28\x05\x6e\xe2\xf5\xf1\xc5\x30\x71\xab\x1b\x08\x06\x8e\x28\xa3\x00\x8e\x14\xfb\x0f\x0e\x9e\x38\xb7\x18\x8f\xba\x10\x73\xa6\x62\x34\x6f\xc5\x85\xa4\xa5\xe2\x1b\x4d\x65\x71\x40\x0e\x02\x85\xe2\xa7\xe5\x54\xbc\x69\x79\x90\x9c\xa9\x38\x64\xe9\x18\x26\x72\x16\xda\x2e\xb8\x66\x3a\x95\xe2\x0f\x9a\xae\xfc\x79\x52\x59\x27\x71\x77\x59\x0c\x98\xcb\x6a\x42\x9a\xaf\x54\xd6\x2f\x76\x52\x79\x02\x08\xb7\x4a\xbe\xe0\x08\xab\xec\xa9\x0a\x3a\xac\x72\x36\x9d\xa9\x8a\x21\xc7\x4a\x62\x6c\x56\xe5\xc7\x23\x55\xac\x70\x95\x5a\x05\xd9\xc8\x6d\xe8\x05\xe1\x33\x76\x45\x95\x76\x3a\x28\x31\x77\x15\x7e\x39\xa9\x02\x80\x5c\x25\xb6\x37\xc9\x17\xe8\x49\x9e\xf1\x76\x1d\x1f\x76\x18\x61\x2f\xb7\xf1\x01\xc1\xe0\x28\x93\xca\x23\x43\x6c\xfc\x30\x32\x9c\x7c\x0b\xfb\x45\xf2\xd6\xf8\xb5\xba\x6a\xaa\xf0\xfb\x55\x65\xf7\x1b\x49\x03\xa1\x06\x54\xf8\xbe\xaa\x40\xe7\x98\xa2\xee\xe0\xa3\xbb\x49\xaa\x5a\x10\x09\x55\x2d\xa8\x40\x69\x55\xad\xd8\xd2\x00\x19\x9c\x87\xb6\x95\xaa\x46\x46\x16\xf4\xb8\xd2\x40\x55\x9e\x07\x56\xe0\xa4\x8a\x58\x82\x05\x93\x7c\xe7\xe5\x7b\xaa\xb6\xc3\xfc\x56\xdb\x1b\x95\xa4\x5a\xf9\x80\x50\x2f\xaa\x21\x76\xac\xd8\x91\xd5\xda\x3b\x76\x43\xbc\x5b\xad\x21\x42\xa8\x16\x92\xd9\x9a\x5e\xa5\xda\xc0\x92\x33\x06\xaf\x08\xb9\xb1\x0c\x98\xbe\xfd\x2a\x38\xfc\x72\x13\x54\xdf\x00\xe5\xaa\xef\x5a\x40\xe1\x02\xaa\x57\xfc\x60\x25\xab\x37\x43\x34\x58\xdf\xf8\xba\x7a\x7b\xa5\xeb\x0d\xf2\x74\x8c\x8a\x67\x62\xd5\xc9\x2b\x1a\x82\xdf\xea\xe3\xbf\x65\xd3\x53\x7d\xcf\xc6\xff\x45\x88\xd5\x5f\x4e\xab\xf1\x38\xa8\xf2\xfb\x40\x85\x16\x56\xff\x9a\xa6\xba\xb0\x62\xeb\x38\x50\xb8\x30\xa8\x55\xa6\xf5\xf2\xa4\xba\x06\x27\xb6\x86\x62\xd2\x6b\x5c\x3c\x7b\xaf\x6b\x40\x20\x30\x6b\x75\xf1\x13\x66\x7d\x86\x96\x03\x09\xd5\xbd\x3e\xf3\x4a\x4d\xb0\x79\x1a\x60\x62\x93\xfe\xb1\x96\xda\xfb\xd5\xab\xc9\x98\x4f\x6a\xc2\xc1\xb5\x37\xba\x68\x2a\x91\x9a\xe6\x4f\x6a\x08\x29\x9a\x9e\x32\xd9\x5c\x4f\x9e\x48\xb6\x7f\x41\x75\xd3\x7e\xe9\x9d\x9a\x06\x0b\x07\x4a\xf8\xe3\x37\xb3\xa6\x6b\x42\x2a\x8d\x01\x47\xd3\x7b\xa4\xa6\xbf\x33\x35\x98\xe7\x77\x65\x9b\x43\xb5\x9b\x23\xa2\x6b\x5e\x0d\x86\xb3\xb9\xef\xcc\x0c\xec\x95\xe6\x81\xd1\x3b\x2b\x4c\x79\xab\x4f\x92\x0b\x52\x6e\x88\xf2\xf0\x0a\xd3\x03\x33\xdb\x56\x2e\x1c\xfe\xbb\x7f\x1b\x8f\x1c\xdb\x9a\xc9\xe5\x93\x7c\xd3\x27\xf9\x46\xbf\xe8\x5b\xb1\x53\x93\x6f\x23\x63\xce\xbe\x0d\x4e\xc3\x37\xae\x8b\x6f\x5f\x1e\xdf\x79\xce\x2b\x92\x67\x6c\x09\xcf\xd3\xc1\xd3\x77\x8f\xe4\xc7\x81\x9f\xf2\x09\x43\xf0\x03\x0e\x00\x61\x87\x7f\xe4\x49\xc0\x41\x4e\x8b\xe5\xe5\xa9\xdd\x72\x72\x18\x38\x07\xec\xf5\x86\x1f\x04\xee\x8d\xe7\x70\xde\xca\x93\xbc\xa3\x7d\x47\x20\xee\xdd\xde\xe2\x4e\x08\xe1\x9d\xab\xe3\xef\xb7\x4b\x0f\x40\x46\x8f\x4c\x28\xf8\x9e\x2a\x79\xec\xd6\x60\x68\x3d\x4e\x8c\x34\x78\x80\xed\x61\x27\xe3\x36\x8f\x7e\x21\x7b\x4c\x9e\x14\xbc\x0a\xe9\x6b\x12\x5d\xf8\x9a\xef\x1b\xa0\x80\xaf\x49\xaf\xef\x08\x18\xfd\x8b\x11\x61\xf5\x80\x98\xfd\x06\x74\xf0\xdf\xe7\x44\x2e\x95\x2b\xf9\x1f\xe6\x42\xb8\xd3\x85\xbb\xb6\x63\x3b\xf3\xb0\xae\x4b\x01\xba\xee\x52\x6a\x42\x10\x2e\xa0\x5a\x40\x2d\x83\x72\x14\x5d\x3a\x69\x20\x9e\xee\xc2\xb3\xd2\x2e\xf1\x01\x09\xe7\xf3\x7c\x52\x87\x51\xeb\xb4\x66\x1d\x46\xac\xcb\xb4\xb7\x26\x4f\xac\x3b\x8d\x59\x4b\x9d\x5f\x41\x3a\xfc\x5b\x97\x87\x7b\xb7\x2b\x07\xa1\x02\x1d\xe0\x07\xe5\xae\x32\x84\x25\xc5\xb2\xb4\x04\xb1\x77\x6d\x82\xa8\xbe\x6b\xcb\x56\x52\x57\x87\xe9\xed\xca\x53\xef\xae\x71\x40\x63\xba\x06\x96\xb0\x6b\xc0\xe9\x75\x9d\xa9\x5f\x9c\xfe\xe5\xd3\x53\xbf\x78\x7a\xd2\xaf\x67\x18\x3c\x51\x37\x69\x9e\xba\x65\xce\xd6\x5e\x6f\xdb\x4d\x31\x1a\x3b\xf1\x53\x70\x01\xba\xec\x56\x30\x53\xf8\xbe\x6e\xde\x14\x7d\x5a\x47\xbd\x31\x31\x3b\xe3\xbc\xed\xef\x4f\x52\x7f\x65\x5a\x04\x3b\xad\x97\xf7\xe4\xae\x13\x59\xf1\x58\xb1\x17\xe2\xc8\x5e\x78\x34\xd6\xe1\xd3\x40\x4f\x10\x28\x4f\x77\xad\x20\x33\x75\x07\x9a\xef\x5e\x20\x12\x00\xf6\xee\xf0\xd2\xa9\x7b\xdb\x41\x9e\xd4\x1d\x9d\x7b\x5f\x6f\x95\xa0\x12\xf2\x00\xf7\xdf\xc3\xb0\x8d\xed\x06\xf8\x4c\x81\x10\xfe\xb9\xd8\x0e\xad\x81\x3c\xfd\x86\x7a\xbe\xa7\x61\x3d\x24\x73\xb7\xf6\x10\xec\xf8\x1e\xca\x1b\x16\x3d\xf4\x60\xb1\x62\xfd\x91\xf2\x2a\x48\x0f\x9d\x60\x11\xfa\x7d\x5f\xdf\xa6\xd0\xce\x1e\x56\xa1\xed\x3d\xec\x2d\xf1\x30\x56\x35\xae\x4c\xd8\x97\x02\x09\xfb\x03\x85\x91\xa9\x48\x79\xd2\xd4\xc3\xf7\x45\x4e\x7e\x60\x35\xc3\x79\x4c\xdc\xc3\x69\x16\x7a\x78\x75\x36\x76\x3f\x40\xfb\x3b\x91\x40\x24\x89\x41\xfa\xfc\x57\x6d\xed\xa0\x3c\xb5\xed\x6b\x43\x7c\xdd\xd7\xbe\xc3\x28\xf5\x85\x45\x5d\xa5\xa7\x17\xf2\xf7\x55\x69\x72\x3b\x61\x44\x5f\x1d\x2a\xb6\x10\xd4\xf5\x15\xef\x17\xb4\xbe\xde\x19\xac\xe0\x8e\xef\x34\x5b\x7d\x0d\x54\x9f\xa9\xaf\xbf\x3f\x48\xfa\x09\xa9\xb6\xa7\xff\x96\xf0\x12\xcd\x7f\x4b\xda\x5c\x15\x69\x60\x37\xfe\xb7\x74\x70\x6d\xfe\x5b\x40\xb0\x70\x3f\x20\x7f\xe9\xbf\x85\x29\x85\x6c\xb0\x1c\x21\x39\xc3\x67\x31\xf6\xe5\x77\x97\x90\x5d\x02\xd4\x3c\x05\x80\x0b\x03\xe2\x77\x91\x42\x80\xbc\x03\xd8\x34\x04\xc3\x0f\x69\x80\xc1\xaf\x2d\x0a\xe9\xb6\xa7\xc0\xb2\xf1\x3b\x42\xbc\x67\x09\x21\xb0\x1c\x21\x77\x0a\xf9\xf3\x48\xef\x2d\x14\x7e\x69\x44\x9c\x83\xce\x15\x48\x38\xf4\xfd\x12\x1c\xca\xef\xb1\xa1\x59\x61\x31\x43\x33\xd4\x3f\x34\x7b\xb0\x90\x5f\x46\x42\xb9\x6e\xa1\x07\x9d\x50\x28\x83\x9f\xd0\x03\x7b\x3e\xf4\x34\xb2\x3d\x43\x51\x76\x52\x69\x43\x7f\xde\xaa\x45\x7e\x41\xb9\x37\x42\x0b\xc2\x77\xde\x5d\x08\x25\x46\x0b\xfd\x07\x60\x42\x89\x2c\x42\xe9\x91\x43\xdb\xce\xcc\xa6\x77\xa2\x65\x0a\xa5\x95\x86\xa6\x1a\x0a\x3a\xd0\x51\xe8\xbb\x2b\x43\x79\x7b\x27\xf4\xbd\x70\x14\x3a\xf2\x62\xa2\x8c\x52\x43\x79\x55\x24\x74\xf8\x0a\x56\x1f\xdd\x1b\x07\x34\x56\x41\xc1\x7c\x9b\xcd\x78\xb9\xce\x15\xe8\x6a\xb5\x77\x66\xdf\x57\x7c\x5f\xe3\x60\x78\x36\x15\xd7\x33\xaf\x9a\xc2\x36\xfc\x36\x54\xc3\x26\xa1\x91\xe7\x46\x79\x3f\xea\x87\x1d\xe8\x9f\x2e\x17\x2e\x61\x4f\x3c\x9e\x0f\x73\xbc\xf3\x7e\x0d\xbf\xf1\x87\x11\x3f\x04\x4f\x0b\x83\x5f\x78\x02\x38\x3b\xf8\xb5\x32\x7c\x73\xd2\xc5\x17\x46\x6d\xe1\x95\x07\x39\xdc\x2c\xe1\xfe\x31\x3e\xd7\x14\xd0\xe2\x70\x86\xc7\xc1\x53\xea\xf7\x02\x4e\xc0\xdb\xa4\x20\xe0\x8e\xb5\x51\xe6\x08\x84\x63\x9d\x29\x00\x77\x62\x35\xfc\x6e\x79\x52\x2c\xc0\x87\x21\x3b\x7e\xf0\x2d\x43\x76\x46\xdf\x43\x0e\xbc\x18\x0a\x0b\x8b\x0b\xc2\x94\x21\xe5\xa5\x13\x04\xfd\x0c\xe0\x9d\xf1\x1e\x34\x0f\x44\xa1\x43\xa6\x8d\xe3\x41\xea\xe3\xb2\x34\x04\x2a\x35\x64\x11\x85\x0e\x38\x8e\x21\x4f\x1a\x19\x01\xf5\x80\x77\x18\x19\xca\x3d\xf2\x0b\x97\x47\xd6\x86\xb7\x4b\x2b\x13\x58\xc8\x91\x8d\xe7\xac\x23\xdb\x18\x1e\x23\x8d\xec\xc1\x0f\xe7\x23\xfb\x9a\x69\xe4\x90\x0e\x8a\x58\x73\xe4\xb0\xce\xbc\xb5\xa5\xa1\x82\x1f\x80\xfd\x78\xb7\xc5\xc0\xca\x0f\xcd\xb0\xc1\x43\x33\x74\x19\xb1\x38\x99\x69\x7e\x6d\xc4\x00\x26\x1b\xaa\x9f\x34\xf4\xa4\x8f\x1b\xfc\xa2\x81\xa4\xa4\x01\x0d\x96\x48\x43\x19\xf3\x0e\x86\x5d\xb0\xa7\xef\x18\x35\x4c\x07\x12\x7e\x2a\x1b\x3a\xc6\xcb\x9b\x01\xd6\xd0\xb9\x7a\x1a\xb0\xb7\x69\x5c\x8c\x05\xc6\x25\xc7\x04\xe5\x21\xce\xb8\x28\x8c\x0b\x03\xb8\xd8\xdb\xa5\x61\xc7\x91\xc6\xc5\xd3\xe3\x71\x19\x6b\x03\xd3\x8c\xcb\x3a\x08\xb4\x68\x5c\x08\xcb\xc6\xe5\xc8\x76\x47\x15\x47\x21\xb6\xcb\xb8\x7c\xf1\xb3\xcc\xb8\xb0\xe7\xc6\x15\x56\x51\x06\x8d\x18\xd7\x3a\xa0\xba\xe3\x7a\x12\x9c\x0d\xb4\x76\xc0\xb4\x11\xa3\x0c\x53\x2c\x1a\xd5\x9a\xdf\x0a\x87\x15\x8a\x03\xf1\xc2\x30\xd8\xad\x61\x85\xfd\x5b\x35\xd8\x83\x61\xaf\x2a\xf0\xeb\xf6\x78\xb9\x05\x26\x6b\x44\x33\x03\xfa\x0f\xb5\xb1\xdf\x34\xe0\x3b\xc6\x87\xaf\x3c\x1b\x48\xe3\x63\xf8\x61\xd6\x30\xe6\xe3\x63\x18\xfd\x07\xb6\x7e\x20\xb8\x1f\x45\x6a\x1a\x45\xb5\x83\xd2\x72\x0c\x7a\xd4\xc1\x93\xcd\xf1\x46\xbc\xa3\x18\x6a\x39\x60\xda\x80\xdb\x1f\x14\x2c\xcf\xb1\x47\x85\x15\x1c\x55\xc0\xb8\x22\x22\x19\xd5\x3f\xa4\x3e\xaf\x34\x1a\x8c\xf5\x68\x88\x61\x46\x83\x4e\x35\xca\x1e\xb0\x77\x38\xde\x3d\x67\xf4\xea\xfc\x92\x3d\x28\x73\xdf\x25\x0d\xc7\xaa\xd0\xd3\x0f\x2f\xbb\xb1\x4e\xb1\x1d\xf4\xbd\x30\x32\x78\x5e\x33\xbc\x2a\x00\xcd\x40\xc8\x3c\x9c\xf9\x08\xd5\x06\xd7\xc9\x17\x78\x62\x13\x0f\x87\x9a\xbc\x56\x6c\xf8\xc2\xd0\x3a\x0c\xe0\xa0\xff\x1e\x00\x67\xe8\xbf\xcb\xdd\xd2\xe8\x2a\x1f\xd0\x77\x4c\x9d\xca\xdb\xa9\x3b\xfc\x24\x3c\xfa\xa5\x6c\x44\x49\x75\x5e\x44\x18\xdd\x3e\x7c\x41\x73\x43\xc8\x38\x7a\x21\x05\xbc\xa6\xd5\x84\x6a\x77\x8e\x90\x36\x77\x74\x48\xb2\x07\xf6\x6e\xe7\xe5\xa6\xd1\x69\xe3\x46\x7f\xd2\x80\x7f\x54\x24\xbc\xef\x84\xb0\x8c\x37\xd5\xc6\x1b\x4f\x8c\x29\xbb\xad\x8a\x14\xd2\x9c\xb4\x04\x53\x0c\x3b\x79\xc2\xef\x8d\x49\xd3\x31\xb9\x2c\xb4\x68\x63\xa2\xa3\xc9\x99\x4d\x25\x2b\x05\x03\x2c\xfd\xd4\x50\x4f\xc0\x65\x28\xa4\xba\x4c\x8e\x64\x72\x3d\xa6\x57\x81\x32\x4d\x0a\x7a\xd2\x80\xf0\x18\x75\x4c\xaa\xff\x84\x1f\x3d\xf1\x1a\x8a\xdd\x3f\x83\xb2\x98\xc1\x35\x99\xb1\x78\xba\x3e\xe6\xe2\x0d\xd8\x31\x17\xc7\xfc\x9e\x83\x8e\xf9\x80\xae\x37\xc0\x19\x6b\x03\x5c\x1d\x6b\x83\x31\x1d\xeb\xbd\x3c\x3b\x10\x5f\x8e\xc5\x93\xdd\xb1\x18\xc0\x8c\x75\x0a\xe9\x89\x10\x8e\x07\x48\x63\xf1\x18\x7a\x2c\x54\x6a\x0d\xcd\xdb\xc0\x70\x56\x67\x76\x47\x40\x3a\x56\x0f\xda\x41\x20\xdb\xb1\x82\xdf\xc7\xc6\x42\xa0\x3f\x56\x00\x8c\xf1\xe1\x35\xfc\x63\xc5\x57\xd1\xe6\xbd\x45\x39\xd6\x60\x9c\x35\xee\x7f\x96\xe5\xa6\xa4\x6f\x21\x89\x9a\xc6\x0d\xac\x3e\x6e\x0a\xe1\xa6\x59\xb9\xb1\x73\x6e\xca\xf2\x26\x24\x1e\x37\xf0\xc1\x78\xea\x06\x29\x3e\xb5\x4f\xaf\x69\x3c\x01\xed\x7c\xb8\x24\xef\x0a\x4f\xe1\x0d\xa2\x29\x67\xe2\xbd\x81\x29\xb4\x13\x53\xca\x27\x4d\x69\x20\x1d\xc5\xfc\x14\x34\x65\x20\x63\x4c\xe4\xcc\xe9\x9e\xa6\xfc\x5a\x9a\xbc\xbd\x38\x55\x6a\x9a\xd0\x5e\x04\x7b\x53\x1b\x02\x89\xa9\xad\xd9\x40\x82\xe7\x40\x85\x81\xa7\xdf\x99\xe6\x45\xf6\x97\xe0\x11\xb2\x9a\x17\xda\x5d\x8a\x15\x9f\xd4\xfc\x79\x29\x1e\x31\xad\x79\x81\xcd\xe5\xbc\xd1\x35\xaf\x50\x94\xf2\x6b\xfb\xbc\x10\xab\xcf\x6b\xd5\x0d\x94\xc6\x65\xbe\x77\x5c\x26\x8c\xcb\xb4\x93\x39\x05\xef\x44\x32\xd3\xd0\x9b\xb5\x27\x4d\xeb\x09\xc8\x62\x4f\xf3\x3d\x7c\x9d\x06\x63\x3f\xe9\xd4\xa7\x6f\x80\x83\x69\xfa\x2e\x0f\xe8\x5e\xd0\xd8\x51\x7e\x2a\xc1\xdc\x74\x2b\xe8\x87\xd7\xfe\xa0\xbe\x13\xd5\xeb\x7b\x09\x91\x6a\x3c\xbd\x9d\x8b\x09\x4d\x1c\x95\x7a\xd2\x64\x4d\xef\xf8\x59\x06\xed\xec\x15\xde\x6e\x7a\x34\xd9\xc1\x26\x26\x83\xff\xe9\x63\xa4\xe9\x53\xd0\x70\x85\x71\x64\x84\x38\x93\xa1\xc3\x44\x00\x3a\xfd\x49\x93\x80\x75\x32\x5a\x9c\x21\x08\xbd\x91\x9e\x6f\x62\x0d\xb4\x0d\x68\xf5\x84\xd7\x9d\xbc\x39\x34\x81\x47\x4b\xe2\xbd\xd0\x17\x5c\x4d\xca\x16\xf8\x2e\x4d\x1e\x8d\x4d\x5e\x3d\x99\xbc\x0a\x39\xc3\x4e\x8a\x33\xac\x82\x80\x8d\xf7\x0b\x6d\xdf\x9b\x14\x33\x16\xab\x2d\x3e\x16\x14\xac\x8a\x78\x70\x06\xb0\xd1\x0c\x98\xc4\x89\x15\x5e\x60\xba\xde\x80\xe9\xdf\x26\x9d\xab\x09\x08\x42\xe1\xb9\xe2\x83\xd5\x07\xd0\x9b\x2b\xb8\x2c\xb7\xc2\x14\xcf\x5b\xdb\x7c\xd2\xbc\x61\x16\xe7\x8d\x89\xdd\x94\xca\xed\x69\x3e\xd0\xd6\xa7\x33\xcc\x5c\x67\x79\xd2\xaa\x5b\x68\x29\x92\xd6\x7b\xd5\x60\xb5\xf7\x36\xf0\x6a\x99\x6f\xef\xc5\x94\x57\x6d\x56\xdb\x3d\xad\xc6\x2b\xea\xab\xf1\x13\xe9\x6a\xef\x27\xa6\xd5\x8c\x98\x7a\x35\x5e\xcd\x5e\xcd\x26\xc8\x57\x11\x8c\xac\xf6\x69\x58\x85\xd5\x78\xc6\xba\xda\xb4\x92\x56\x5b\xbc\xa7\xb8\xda\x57\xf1\xda\x79\x9a\xb9\xfa\xc9\x05\x5a\x9d\x9f\x83\x56\xf7\x96\x16\x43\xe9\xd5\x61\x45\x56\x6c\xd2\x12\x0d\xc5\x0b\xbc\x80\xe0\x79\xe5\x7c\x0d\x3d\x56\x41\xc2\x0b\x12\xff\x98\xcf\xf7\x3f\x03\x5f\xc9\xd8\x6e\x5f\xc9\x6b\xd5\xf4\x15\xe8\xdc\x57\xe0\xc7\xbe\xef\x3d\xf8\xaf\x40\x74\x5f\x69\xf8\xd9\xb8\xd2\x57\xba\x47\xfa\xca\x7b\x15\xeb\x0b\x85\xff\xf2\x83\xfa\x57\x2f\x83\x68\xbe\x10\x36\x5e\xdb\x8e\x8a\xbc\x14\x89\xdc\x06\xd6\x1a\x1b\x88\x1d\x0f\x12\x02\xa5\x2f\x82\xdb\xaf\x8e\xa1\x25\x7d\x75\x6a\xa0\x2f\xa3\xcc\xbf\xb6\xf1\x0b\xe2\xd7\xf2\xdb\x9b\x65\xda\x75\x04\x88\x9e\x88\xda\xbf\x56\x0a\xa6\xfb\xb5\x36\xdf\xd4\x8b\x81\x41\x10\x77\x7f\x2d\xd8\x6e\x08\x88\x81\xd5\x78\xf3\x27\xe9\x17\x33\xe5\x29\xf7\x97\x17\x25\x79\xf9\xfb\xeb\x25\x4b\x73\xa4\xab\x22\x6f\x82\x3c\x60\x7f\xff\x23\xde\xd2\x2d\x36\xd3\x0d\x7b\x07\x7b\x0b\xd2\x16\x32\x1a\x48\x1c\xd0\x15\x5a\xdd\x5b\x02\xc1\x74\xba\xb1\x6d\x6e\x19\x1d\x64\xa2\x10\xf8\xe8\x06\x3e\x86\x33\xb9\xdf\xef\x8a\xb7\x0a\x96\x96\x96\xfa\x46\x6c\x55\x90\xd0\x68\xdc\xba\xa5\x5b\xdf\x70\xf8\x56\xfd\x60\xa7\xdd\x6a\x01\x5a\xf8\xcd\xeb\x86\x91\xbc\x75\xa6\x9b\x5f\xaf\x6e\xd8\xc8\xfb\xd2\x97\x82\x13\x2c\xe5\x4d\x13\x79\x03\x4a\xde\x97\x31\x02\xbf\x61\xef\x6e\xdb\xd1\xbf\x1d\x78\x2c\x3b\x48\x49\xd8\x25\xb7\x35\xc0\xd6\x1b\x08\x94\xae\xe2\xb6\xf6\x01\x69\x6c\xca\x4b\x31\x37\xc2\xac\xdb\x06\xc2\xd8\x1b\xd6\xe7\x86\xae\xdc\xff\xee\x28\xdc\x5e\x8e\x74\x23\xae\x49\xb7\x73\xc7\xdc\xee\x3b\x48\x49\xf4\x37\x3c\xdc\xbc\x3d\x0a\x1f\xe3\x01\xc5\x60\x60\x6f\xee\xd0\xfc\x01\xe5\x25\xde\x9b\x86\xec\xe6\xcd\x8d\x9b\x0e\xfc\x81\x49\x7b\x20\xaf\x47\xe9\xf7\x1e\x5f\xf8\xa1\x88\x40\xea\x4f\xb7\x90\xf4\xa7\xe1\x89\x47\x6b\x7f\xee\xe9\xff\x00\x00\x00\xff\xff\x96\xd2\xdb\xc1\x3c\x33\x00\x00") func keysWordlistEnglishTxtBytes() ([]byte, error) { return bindataRead( @@ -106,12 +106,12 @@ func keysWordlistEnglishTxt() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/wordlist/english.txt", size: 13116, mode: os.FileMode(420), modTime: time.Unix(1497960590, 0)} + info := bindataFileInfo{name: "keys/wordlist/english.txt", size: 13116, mode: os.FileMode(420), modTime: time.Unix(1511602021, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _keysWordlistJapaneseTxt = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x5c\x5c\xff\x72\xe2\xb8\xd2\xfd\x9f\xa7\x5e\xbc\x5c\x2f\x01\x3c\x0e\x71\x1c\xc7\x61\x58\x87\x8a\x2f\x43\x60\x80\x0c\x59\xb8\x93\x8f\x2c\x3c\x8c\x5f\xe4\x2b\xf5\xe9\x3e\xea\x99\xaa\x54\xea\x1c\x59\xd6\xcf\x56\x77\xab\x25\xd3\xf5\x93\xae\x3f\xe8\xfa\x45\xd7\xcf\xbb\x7e\xd5\x25\x45\xcf\x92\xca\xae\xdf\x92\x3c\x03\x8d\xba\xfe\xdf\x5d\x72\x03\x32\xee\xfa\x8b\x2e\xf9\x93\xef\x64\x5d\x32\x06\x9a\x76\xfd\x49\xd7\x6f\x8c\x58\x72\x11\x92\x93\x09\x79\xd9\xf5\x07\x44\x07\xa0\x4a\xfe\xaf\x40\x1e\xbb\x24\xef\xfa\x29\xc8\x53\xa8\xd1\x5e\x7d\xea\xfa\x19\xd0\xbc\xeb\x9f\x80\x9a\xae\x3f\x64\x86\x26\xfc\x25\x7d\xc7\x93\x51\xd7\xbf\x74\xfd\x21\xb9\x3e\x69\xd9\x8a\x56\xfa\xa4\xd5\xbd\xc8\x70\xfc\xa7\xeb\xe7\x7c\x78\xe9\x92\x91\x11\x57\xf4\xb2\xeb\xaf\x89\xf6\x92\x4d\x9f\x1c\x88\x4e\x1c\xb5\x13\xd3\x8e\x7e\x2c\x2e\x6c\xc5\xa5\xeb\xbf\x1a\x4a\x06\xd2\xa4\x9a\x5c\xeb\xbf\x76\x49\xd2\xf5\x77\x42\x42\x4b\x46\x5d\x1f\xe5\x84\x17\x58\x7f\x92\x76\xc9\x1f\x40\x37\x32\x8b\xb7\x5d\xff\x42\x5e\x11\xd5\x5d\xff\x91\xc4\x8f\x5a\x72\x23\x65\x44\x92\x5b\x5b\x42\x8d\x93\xae\xbf\xb2\xe1\x0a\x4f\x66\xcc\x99\x87\xa1\x30\x52\x58\xcf\x12\x99\x7f\x47\x0a\xa2\xaf\x26\x44\x81\x2c\x7d\x9e\xb5\x27\x3a\x00\x03\x88\x24\xda\x32\x08\x52\x29\x6f\x0f\x58\x3c\x50\x0e\x94\x89\xd8\x0e\x48\xd6\x2c\x24\xe3\x28\x0e\x28\xbd\x03\x59\x08\x8f\x44\x27\x96\x3d\xed\xfa\x6f\x98\x69\x21\x96\x5c\x60\x08\x74\x0d\x11\xb5\x3d\x5b\x44\x17\x11\xea\x81\x71\x7b\xaf\x82\x04\x0f\x44\xca\xff\xc3\x42\x1e\xbb\xe4\x2f\x4f\x72\x36\xeb\xa9\xeb\x5f\x0d\x25\x13\xa0\x19\x0b\x9e\x05\xe1\xef\xbf\x93\x8c\xfd\x13\xad\xe8\x2b\x2b\x9f\x77\xfd\xb4\x4b\x32\x56\x34\x97\x01\x8b\xcd\x7c\xf6\x48\x3b\xd5\x48\xc5\x37\x24\x57\x43\x41\x16\x12\x90\x85\x8c\x75\x4a\xf2\x48\xf4\x4a\xf4\x46\x74\x32\x94\x8c\xfc\x10\xb4\x10\xe6\x41\x5c\x83\xd6\xec\x17\xdf\xe3\x17\x74\x83\xa4\xf1\xd9\x16\x44\x4b\xff\xc2\xbf\x7c\x61\xd9\xf5\x1f\x0c\xd9\x7b\xaf\x7c\xba\x82\x70\x0e\x28\x7f\x40\xda\xac\x6d\x97\xfc\x41\x21\xda\xb1\xb2\x1d\xa7\x6a\xcf\xf9\x7f\x73\x69\x56\xcd\x3b\x27\xe4\xc0\xb4\x23\x87\xf9\x27\xd3\xce\x6c\xce\xd5\xd2\x82\xbc\xa6\x50\x8f\x20\x8d\x89\x42\x92\x58\x8b\x12\x91\x7e\xad\x36\x10\xac\x92\x64\x28\xfa\xb3\x20\x41\x7d\xa2\x19\x88\x6a\x96\x3d\x12\x6d\xb1\x30\x12\x85\x32\xe1\x1a\x0b\xda\x8b\xeb\x27\x89\x55\x66\xa2\x87\x8b\xae\xff\x8f\x0d\x43\x50\x08\x03\xa2\x94\x28\xb6\x27\x37\xb9\x08\x02\x9f\xb2\xa8\xa2\xeb\xdf\xd9\xca\xef\x33\xa9\x64\xb9\x85\x08\x48\x6c\x5b\x21\x3d\x0b\x24\x95\xf5\x90\x19\x92\x02\x53\x91\xce\x07\x20\xed\x46\x2a\x4b\xe5\x44\xf4\xc1\xac\x59\x97\xe4\x40\xb9\xe9\xcf\x35\xf9\x04\xe3\x9e\x8a\x5a\x68\xa4\x7d\x39\xdf\x9c\x8a\x0c\x4f\x49\x56\xee\x49\x18\xb1\x96\x44\x93\xef\xa9\xe5\x41\xb4\xde\x02\xc3\x93\x4a\x8f\xbf\x00\x55\x22\x88\xa9\x91\x30\xd8\x13\xac\xc5\x54\xa6\x6f\x40\xf4\x85\xe8\x96\xb3\x2c\xdc\xf4\x7b\x2a\xab\x49\x1b\xb3\xa0\x16\x27\x9f\x70\x00\x16\x1c\xc9\x05\x17\x6a\x2a\x0b\x6a\x0c\xa9\x4b\xa5\xc7\x39\x55\x48\xaa\x2b\xd2\x8d\x7c\x4b\xf4\xca\x6e\xad\xd9\xca\x35\x74\x05\xd0\x13\x47\x60\xcd\x97\xb6\x44\x3b\xd6\x7f\xea\xfa\x77\x44\xf7\x30\xed\xa9\xcc\xc5\xc4\x72\xc7\xbe\xca\xd2\x01\x12\x1b\x69\x64\x68\x95\x85\x31\x9a\x88\xd4\xd4\xe4\xba\x04\x40\xd6\xd6\x37\x51\x78\x56\x77\x20\x99\x49\x43\x32\xa6\x57\x93\xca\x4a\xa9\x1c\x49\x52\x1b\x46\xd7\xbe\x0c\x9a\x26\x95\xb1\xcf\x88\x4a\xa0\x82\xf6\x05\x64\x61\x43\x07\x3b\xe9\x88\xea\xae\xa1\xc8\xe9\x10\x4f\x40\x26\x44\x19\x97\x0a\xf8\x3d\x91\x6a\x55\x90\x93\x7b\xdb\x96\x13\x48\x0e\x34\xc2\xa4\x0f\x65\xbc\x22\xd2\xa7\x99\x4c\xbc\x16\x17\xdd\x82\xa1\x88\xeb\x9f\xcc\x56\x77\xfd\x25\x50\x2b\xae\x85\x56\xb9\xeb\xfa\xb7\x40\x67\x9d\x4c\x19\x15\xe1\x96\x87\x69\x61\x4e\x1f\x89\x76\x40\x37\x56\x79\x40\x27\x20\xb5\x50\x50\x4b\x1c\x9d\x40\xc6\xcc\x5d\x40\x18\x87\xaa\x75\xac\x8a\xc2\xfc\xc0\x94\xfc\x2b\x56\x0d\xc8\xdc\x7a\xa4\xf3\xf3\x97\xcf\xb9\x42\xce\x91\x8c\xeb\x98\x4b\x7e\x64\x5e\x42\x4d\xa2\x82\x32\x32\x0b\x98\x83\xa4\x6c\xee\xc8\x14\xc1\x85\xe4\x91\x68\xc6\x7a\x52\x8e\x3e\xc8\xd1\x17\xf5\xe1\x9e\xd8\xcc\x8e\xb8\x48\x47\x74\x94\x46\x34\xe3\x40\xaf\x9c\x73\xe1\x09\xf3\x84\x42\xe6\x20\x63\x0c\x34\xc9\x13\xd0\x04\x2e\xa8\xa4\x05\x15\xa9\x19\xbe\x50\x8d\x8d\xe8\x7a\x8d\x44\x5c\x62\x0f\x73\xef\x0d\x09\x57\xaf\x73\x4d\xce\xd7\x6c\x45\x8d\xfc\xb0\x16\xbe\x92\x82\x19\x4a\xdf\xe3\x92\xeb\x5a\x88\xe9\x8b\x11\x66\x04\xeb\x1a\x24\xbe\xf3\x08\x49\x01\x2a\x39\x3d\x22\xde\xf6\xc2\x5c\xc4\x2f\x27\x89\x8d\x6d\x68\x7b\x40\x34\xcf\x33\x9c\x7d\x90\x85\x97\x81\x17\x18\xe5\x91\xac\x14\x1d\xbf\x6f\x10\x27\x90\x95\xd4\xad\x2b\x00\x7c\xed\x25\xea\x95\xaf\xbd\x8a\xc2\x19\x73\x84\xde\x7c\xfb\x2f\xb0\xf5\x42\x92\xbe\xd4\xb1\xb2\xe1\x4b\xb0\x0d\xfc\x46\x12\x93\x29\x6e\x81\x84\x0d\x21\xc8\xc0\x44\x32\x19\x88\xe6\x7b\xef\x99\xc0\x7c\x5a\xf5\xb2\xec\xb1\xb7\x1c\x49\xc3\x34\xb9\xa0\x3a\x01\x99\xb2\x06\x2c\xc6\x3f\x49\x66\xd6\x78\x29\xc7\x93\x68\xa8\x46\xa6\x1f\xb5\x98\x31\x76\x70\x40\xaa\x1f\x27\xd0\x8f\x44\xea\xde\x4f\xbc\x87\x3f\xf6\xbb\xe2\xb1\x2e\x5a\x69\x0b\x48\xed\x1d\xab\xb1\x77\xb8\x41\xfe\x86\xf1\x23\x6f\x7d\xb1\x4b\x9f\x73\xe5\x9f\xe8\x02\x9e\xa8\x73\x28\x8d\x1c\x7b\xff\x70\xec\xf5\xf4\xc4\xfb\x74\x63\x2a\xed\x31\xc5\x77\xcc\xa5\x3c\xfe\x2d\x79\xc2\x96\x4f\xb0\x39\x1c\xd3\xb5\x18\xcb\x62\xbc\x27\x5a\x31\xeb\x03\x5e\x9f\xa0\x7b\x48\x6b\x58\x7b\x03\xf3\x39\xf1\x8a\x71\x22\x02\x9d\x71\x7a\xc0\x0b\x4f\x4a\x8e\xfe\x8b\xf7\xef\xc6\x22\xd6\x0f\x62\x1f\xb5\x7d\x3b\xbe\xb6\x67\x93\x4e\x58\x45\x63\x3f\x40\x67\xb6\xfe\xc2\xb4\x8b\x48\x22\x46\x3d\x2c\xfb\x09\x37\x92\x63\x11\x58\xf4\x41\x06\x16\xd2\x3b\x76\x03\x9b\x8c\x89\x32\x2b\x31\xb4\x2b\x37\x24\x1b\xa5\x09\x4c\x0c\xd2\x0a\x27\x81\xce\xb0\x8f\xbd\x54\x8f\xcd\xa4\xc4\x27\x0d\xdb\x54\xd8\x68\x06\xa4\x1b\x8b\x0c\x01\x1a\xa2\x16\x28\x78\xe1\x3d\xd1\xb2\x03\xbc\x9e\x49\x2f\x06\x86\x2c\x6d\xc8\x52\x54\xdf\x03\xe5\x44\x0b\x43\xf6\xc6\x98\xa5\x8c\x99\xef\x97\x2e\x64\xf2\xb7\x04\xca\xa5\xa1\x23\x23\x61\xfc\xee\x40\xa6\xba\x7e\xad\xb4\x82\xf5\x17\xbe\x59\x05\x2b\x29\x99\xb5\xf4\x69\x17\x43\xa1\xec\x2f\xe8\xf3\xa3\x97\xe7\x2f\xdc\x6a\xe3\x49\xe3\x17\x38\x92\x36\x7e\xa3\xf8\xc5\x36\xe4\xad\xef\x52\xcd\xe6\xc5\x26\xeb\xc6\x3a\xa3\xf9\xcd\x38\x75\x99\xac\x87\xdc\x90\x0d\x5e\xe3\xbb\x16\x97\x44\x26\x95\x0d\xd9\xa4\x17\xec\x89\xf9\xa4\x65\x45\x6d\xd7\xdf\x02\x2d\xd9\x8c\x57\x16\xf2\xca\x2a\xd7\x7c\xba\x86\x82\x03\xd2\x66\x7c\x17\x6f\xb9\x02\xd9\xb2\x75\x3b\x16\xb4\x93\x31\x6b\x40\xf6\x2c\xf5\x9d\x46\x25\xe3\xde\x35\xa3\x86\xca\xe8\x39\x66\xb2\xb2\xb4\xac\x33\xd3\x2e\xec\xfa\xd5\xc6\x2b\xf9\x43\xe3\x7a\xb1\x60\xb3\xc0\x08\xce\x3c\x8b\x25\xaa\xc8\x17\x3d\x1f\xb6\xc9\xe8\x50\x66\x62\x70\x30\xdf\xa2\x59\x64\x56\xf5\xc9\xd0\x1a\x23\x03\xee\xa3\x0d\x19\x97\x74\x46\x7b\x9d\x49\x06\xb4\xd9\x36\xbb\x40\xda\xe6\x8c\x15\x65\xcc\x97\xb3\xdd\x5f\x10\xf1\xc2\x02\xcc\xcc\xc7\xd4\x98\x12\x78\xf0\x6a\x8c\x38\xfd\x72\xcb\xb5\x9c\x23\xcc\x03\x94\x72\x9f\x0c\x92\x11\xdd\xfa\x64\x5d\x40\xb7\xe6\x0f\x0e\xf8\x64\xee\x9f\x34\xd0\x4c\xb9\x77\x0e\x41\x3e\x81\x62\x5d\x71\xbb\x90\x63\x1b\x8e\x42\x0a\xa6\x95\xac\xa5\x64\xb3\x4a\x46\xc9\x84\xc8\x90\xe4\xe6\xfa\x5f\x49\x62\xc1\xb5\x88\x5b\x66\x24\x8c\xbd\x8e\x87\xec\x1d\x44\x5f\xe4\xb4\xf4\xb7\xb6\x80\x97\x7c\xe7\xd9\xd7\xd3\x04\x29\x35\x67\x30\x17\x47\xaa\x60\xbd\x0b\xdf\xd0\x96\x32\x7e\x2b\x2b\xae\xc6\x8a\x93\x27\x61\x8a\x6f\x7b\x66\xea\x52\x9a\xe7\x9c\x6b\x2c\x97\xbd\xa9\xa6\x6d\xf1\x1f\x64\xc7\x9e\x1d\x89\xae\x7e\x73\x0d\xde\x30\x44\x1a\x45\x27\x87\x10\x63\x80\x7a\xa6\x30\x6b\xa2\x0f\x66\x1b\x43\xf1\xe5\xae\xab\x66\x87\x72\xd8\x47\x4c\xcd\xad\xca\x9f\x8e\x5d\x8c\x97\xe4\xe4\x8d\xcf\x19\xd4\xf6\x54\xc4\x70\x0d\x34\xa0\x9e\x9f\x7a\xbd\x09\x12\x91\x7a\x45\x77\x2e\x9e\xd9\xf2\xa1\xd6\x70\x67\xe1\xb2\x54\xb2\xf0\xe5\xb0\xb2\x32\x12\x45\xf0\x62\x6b\x23\xc9\x88\x6b\xfe\x0e\x26\x87\x48\x05\x13\xe4\xd9\x93\x85\x27\x2b\xb6\x30\xa8\x34\x43\xa6\x34\xee\x28\xd6\x77\x76\x16\x12\xb7\x1e\x77\xc1\xe9\x90\x2e\x4c\x29\x40\x92\x66\x7d\xa8\xd8\x81\x2a\x68\x56\xd9\xf0\x4c\xbd\x98\xdf\x31\xb2\x86\x68\xd1\x1b\x90\x9c\x9e\x04\xd9\xfb\x1f\xf9\x0d\x3b\xdd\xd2\x9e\x4f\x79\x46\x31\x55\x43\x61\xd5\xbd\x30\x46\x84\x27\xaa\x58\xa6\x16\x29\x8d\xd9\x96\xbe\x80\x0b\xc7\xa2\xf5\xfa\x07\x7c\xe2\x72\x9a\x82\xbb\xa3\xdc\x4b\x34\x2b\xac\xf0\xba\xe7\x43\x5b\x53\x31\x2f\x77\x44\x35\xd1\x15\xe8\x3b\x87\x6d\xcb\x4e\x6d\xd9\xf4\x3d\x25\xe4\xc0\xb4\x13\x7d\x8d\x3b\x31\x27\x5a\xbb\x1e\x01\x4c\x65\x11\x8d\xad\xf6\x60\x47\x2a\x43\x9a\xc1\x04\x66\x4a\x1d\x3f\x95\x45\x32\x35\x21\x73\xeb\x64\xca\x63\x8a\xa9\x86\x08\xb4\x91\x81\x8c\x88\x20\x75\x01\x65\x4c\xbb\xb3\x16\x3b\x9f\x6e\x6a\x61\xca\x9c\x24\xc6\x10\xc0\x6b\x93\x0c\xe7\xf0\x4d\x75\xe7\xe2\x5e\x5b\xfa\x56\xad\x7c\xb6\xb5\x7f\xb2\xb1\x79\x0a\xe4\xe4\x1b\x7f\x21\xba\xba\x86\x06\xa3\xca\xb7\x2d\xfa\x02\x12\x7a\x5b\x88\xec\xe5\x78\x5b\xac\x59\xff\x3b\xd1\x3b\x24\xf9\x9e\x1e\x65\xe1\xc3\x14\x85\x86\x59\x1d\x51\xf5\x73\x6f\x51\x55\x1d\x87\x7b\x0b\x8f\xc6\x32\x74\xf8\x0a\x0b\x75\xc4\x27\x8f\x44\x1a\xe3\xbc\xf7\x76\xae\x30\x3b\x97\x93\x34\xfe\x89\xee\x4a\x0b\x0b\x54\xc6\x4a\x96\x3e\xdb\xab\x7f\xb2\xf6\x4f\xf6\xbe\xd2\xb3\x6f\xff\xc5\xf5\x34\x48\x1c\x5b\x90\x8c\x30\x0d\xd1\x9d\x2d\xb8\xf5\xba\xa7\x6c\xdf\x8b\x9f\xda\x5a\x9a\x95\xa5\xbb\xad\xc2\x9b\xd9\x82\xf6\x88\x64\xed\x9f\xec\x59\xf9\x2d\x27\x2e\x8e\xee\x94\x6d\x28\x44\x09\x93\xc8\x62\x28\x10\xfb\x00\xaa\xd8\xf0\x9a\x95\xc5\x81\x56\xb5\x12\x0f\xed\x20\xbf\xcf\x30\x1e\x85\x1f\xf9\xc6\x77\xbd\x61\xa9\xd1\xf1\x2d\x10\x43\x06\x6a\x79\x6e\x06\xf2\xc6\xe2\x5b\xc4\xf1\x0a\x3f\x5d\x4b\x3e\x5d\xc9\x96\xe8\x86\xa4\x22\x7a\x33\x64\x42\xbd\x96\x61\x5e\x83\x6c\xf1\xbf\x67\x23\x72\xe1\xa8\xed\xa0\xb6\x04\x25\x43\xcc\xcd\x9e\xf5\x1d\xa0\x6a\x41\x8e\xec\xc8\x91\x19\x3e\x69\x95\xef\xa5\xd4\x78\xfc\x2b\x07\x19\x6e\xea\x2f\x74\x3b\xf0\xa4\x65\xe3\x2e\x36\x6e\x41\xb3\x7d\x81\xa9\x2d\x18\xef\x2c\xe8\x0b\x17\x54\x73\x82\xb4\x09\x66\xd6\x80\xd0\xab\xe0\x55\xa5\x44\xef\x40\x43\x1b\x4f\xf3\x91\x0b\x31\xb5\x5a\xf5\x24\x7a\x6b\x56\x70\x26\x33\x36\x05\xc9\xa5\xf2\x25\xc9\x84\x6f\x16\xdc\x78\x16\x3e\xca\x5a\x50\x77\x16\xbf\x29\xc5\xc2\x94\x62\xcc\x46\x89\x82\xea\x73\xa5\xad\x3d\x79\xef\xfa\x1b\x92\x7f\xfd\x93\x0b\x1b\x5a\x20\x64\x09\x34\x71\x95\xd8\x96\xfd\x41\xc3\xe6\xd2\xb6\xd2\xdc\x9e\x01\x89\xda\x41\x64\xbb\xf3\xa4\x60\x1e\x75\xda\x4a\x1f\x50\x7f\x30\x07\x28\x56\x12\x03\x53\xa5\x77\x64\x1f\x7e\x3b\x68\x2b\xa1\x84\x80\x34\xda\x04\x32\x81\x79\x45\x72\xcc\x70\x85\x40\x94\x3c\xfc\x2b\x65\x2f\x12\x8b\xcb\x59\x42\x4e\x3b\x5b\xc2\xb5\x04\xd2\xbd\x76\xc9\x75\x58\xfa\x4b\x17\x0f\x5c\xfa\x25\x83\x12\xa5\xf9\x23\xda\xd7\x96\x9a\xff\x81\x2b\x1b\xc9\x13\x96\xfd\x62\x1b\x8b\x9c\xd9\x2a\x16\xf5\xe8\xdf\x9e\xb3\xe9\x2d\xbd\xa6\xd2\x1c\x98\x41\x97\x24\xe0\x4b\x4e\xd4\xca\x27\xaf\xf8\xf6\x8a\x31\xeb\x92\x0a\xa2\xa4\xeb\x52\xd2\x65\xc7\xd6\x45\x9b\x19\xf7\xba\xa5\xc4\xcd\x75\x3c\xce\xcc\x7a\x46\x2c\x0f\x07\xfc\x3a\x21\x57\xff\xd2\x55\xdc\xd1\x89\x90\xb0\x8a\xa7\x3d\x1f\x60\x2e\x65\x69\x0e\xfd\xd9\x4d\xc9\x35\x5a\x72\x3d\x96\x8c\x28\x22\xc2\xf1\xdc\x43\xcc\x4d\x46\x07\x03\x92\xe4\x8c\x1c\x97\x8c\x33\x97\x7e\x0d\x96\x74\x5e\x80\xe2\xb6\xb9\xf4\x5e\x4b\x69\x5e\x0b\x66\xd3\x36\x0b\x7c\x52\xfb\x6c\x33\xeb\xa7\xf8\x2f\x44\x0b\xa2\x0b\xd1\xd5\x90\x39\x1a\x15\x37\xba\x15\x0f\xd2\x2a\xbb\x07\xf4\x82\x65\x5f\xf9\x2d\x93\x84\xe2\xa5\xc1\x15\x3b\x55\xc1\xb2\xf7\x34\x36\x6f\xc5\x8d\x30\xd0\x15\x17\x70\xc5\x1d\xcc\x23\x2d\xac\xb8\xe9\xe2\xc5\x54\xec\xd6\x23\x6f\x3d\x54\x22\x6d\x29\x0b\x6a\x10\x58\x02\x5a\x12\x5d\x81\xa2\x35\xab\xec\x2a\x83\x56\x11\x8f\x47\x2b\x9a\x0c\x41\xa6\xa8\x2b\x0a\x6f\x45\x3d\x00\xd4\xa2\x41\x6a\xe4\x1e\x29\x22\x38\xfd\xfd\x02\xb1\x12\x62\xea\xbf\xa2\x5a\xac\xc4\xb4\x5d\x0c\x59\x9a\x1e\xac\x01\x9d\x80\xf6\xac\xfd\xcd\xb7\x55\xaf\x2f\x08\x32\xdf\xb9\xa2\x09\xac\x44\x7b\xc4\x3e\x1f\x39\xba\x27\x66\xf8\xc9\x97\xce\xcc\x77\xe6\xd3\x0b\xd3\xd4\xcc\x55\xf4\x4e\x2b\x2c\x15\x24\x3f\xc2\xaf\x87\x0c\x56\x74\x5a\x2b\x2e\xa2\xca\x0d\x65\x10\xe9\x81\x27\xa9\x27\x23\x1b\xc9\x40\x26\xd4\x13\xd5\x6f\x3b\x6e\x3d\xa1\x74\xcd\x0e\x7c\xea\x4b\x8a\xe8\x81\xcd\xf9\x93\x57\xe7\x40\x66\x9e\xcc\x7d\x51\x8d\x7f\xc7\x8b\x8e\xee\x04\x33\xdf\xce\x8b\x3d\x89\x42\x25\x27\x4c\x28\xe3\x91\xea\xe2\xd1\x42\x5e\xb1\x17\xff\xf1\x2e\x21\x9e\xc7\x16\xfe\xc7\xef\x0f\xc1\xaf\x86\xc2\x7c\xbf\xd9\x3b\x1a\x68\xd6\xd7\xfe\xb2\x3b\x12\x03\xf2\x9c\xc6\x0d\xfc\xc5\x0f\xd6\x5f\x4e\x6c\x83\x0b\x91\x98\x58\x85\x3a\x66\x9c\xc1\x18\xd8\xa8\xa8\xa7\x2a\xaf\x97\x1e\x2d\x68\xf6\x27\x9f\xcc\x10\x68\x20\x5f\xb0\x11\x05\x07\xab\xa6\x6e\x01\xaa\x88\x82\xd1\x7c\xc2\x9d\xb2\x9e\x9e\xdb\x98\x06\x01\x19\x13\xa9\x15\x79\xf2\x07\xe3\x3c\xe8\x51\x3f\xaa\xb6\xfb\x24\x39\xc9\x23\xba\x5a\xeb\x26\xc5\x5e\x8b\x67\x71\x35\x22\xa2\x40\x7a\x27\xa6\xf6\x3e\x7d\xcd\x55\x50\x8b\xb2\xd2\xb4\x02\xfd\x78\xe2\x21\x49\x2d\xa4\x62\x86\x1a\xe1\x87\xda\x5f\xf4\xa8\xbd\x2e\x7a\xb2\x53\x95\x48\x56\xc8\xa3\x1a\xa8\x66\x64\xaa\xe6\xb5\x0b\x04\xe9\xb4\xbe\x3d\xcc\x50\x2d\xb2\x71\xc3\xca\x9f\xbc\x5e\x78\x92\x6d\xe8\x77\x28\xaa\x5a\x86\x4e\xbb\x7d\x64\xda\x07\xb4\x69\xcd\xf9\x7f\xe2\xba\xab\xc5\x8b\xd6\xfa\x2e\xd6\x39\x0b\x05\xd7\x3c\x81\xac\x65\xfd\xa2\xd5\xb8\xbf\x24\xce\x4c\x1d\x2c\xa4\x6c\x67\x6a\x59\x2e\x72\x99\xc5\x5e\xc8\x5c\x9f\xcd\x5c\xd6\xfe\x16\x62\xad\xae\xa4\xbc\x30\xf3\xfe\xfb\xcc\x3c\xc3\x96\x44\x9d\xc1\x28\x90\x33\x7f\x1c\x37\xe3\xc1\xca\xcc\xbc\xb8\x31\x5f\xc8\xb8\x6f\x9f\x21\x16\x4e\x94\x12\xe1\x84\x34\x65\xb6\x29\x51\xc1\x72\x6b\x56\xac\xda\x05\x68\x0a\xf4\x42\xfb\x37\x33\x0d\xa3\xc6\xff\xab\xf0\xf8\x24\x96\xfd\x42\x17\x70\xa6\x07\x72\xb2\xcc\x21\xb0\x33\x31\x66\x7f\xf3\xcd\x96\x61\x37\x90\x6f\xbe\x98\x1f\xfe\xc9\x3b\xd1\xc9\x25\x9b\x5a\x07\x19\xb1\x5e\xbd\x6f\x37\x13\xd1\xd3\x57\xf7\x50\x4e\x33\x89\xf2\x66\x40\x9f\xd8\xc4\xcd\x28\x28\x33\xda\x95\x19\x97\xc0\xcc\xdf\x96\x9b\x49\x35\xc7\x1e\x66\x1c\xb1\x0e\x24\x17\x56\x82\x06\x81\x22\x19\x13\x65\x50\xb2\x20\xf1\x3d\x15\x04\x94\x78\xcf\xe4\xd2\x17\x12\x34\x2c\x49\xed\x9f\xcc\x3c\xf9\x9b\xa8\xf1\x35\x44\x73\x31\xf3\xb1\xa1\x99\x8f\x0d\x81\x68\xb4\x0d\x64\x6b\x63\x1d\xc8\x0f\xbc\x83\x56\x9e\x88\xfe\x75\x6f\xab\x1c\x22\x4a\xe4\x8e\x2b\x90\x94\xb8\xd2\x6c\x9b\x09\x92\xfa\x32\x54\xfe\xbf\xc2\xed\x23\x1a\x51\xf8\x66\x7e\x2f\x06\x12\x9a\x3c\xe7\x6c\xcc\x4d\xff\xde\x61\x06\xc1\xb7\x3d\xbd\xbc\xaa\xc7\xa0\xf1\x8c\x62\xce\xc3\x11\xa0\x7b\x22\x35\x7c\x20\xcf\x9e\xac\x3d\x79\x37\x24\xdd\x26\x19\x01\xc5\x2b\x46\x73\xc6\xba\xe6\xbc\xc9\x31\xe7\x8d\xa1\x39\x57\xe6\xdc\x42\x23\x9a\xf5\x81\x59\x2b\x98\xa0\x39\xa7\x7d\x4e\x23\x31\x97\xbf\xdb\x1e\x63\x2a\xec\x7c\xcb\x52\x5b\xdf\x80\x17\x6a\x14\x3c\xf9\xe2\x07\xe4\x05\x71\x5c\x92\xc2\x3f\x99\xf9\x32\x56\x40\x2b\xde\xfa\x03\xf9\x2f\x26\x6f\x2e\xab\x71\xc8\xb6\xac\x71\x70\x32\x17\xe7\xef\x13\xe8\x93\xd3\xf6\xc9\xa9\xbc\xb0\xf2\x8b\xbd\x1b\x3c\xba\xdc\x50\x58\x86\x43\x90\x3e\x33\x24\xf8\x0f\x22\x97\x56\xfb\x5f\x7b\x76\xa1\x46\xef\x81\xce\x79\xdc\x31\xf7\xf1\x85\xb9\x3f\x65\x07\x79\xf0\xa4\xb2\xf6\xc8\x2a\x63\x43\x7e\x59\x5b\x7f\x23\xaa\x40\x74\xb2\x61\x72\x31\xd4\x86\x1b\x18\x1c\x46\x0d\x98\x3c\xa0\xb2\x6e\x7c\x48\x01\x44\x4d\xc1\x33\xae\x9d\xa0\xfa\x86\x37\x4f\x80\x6e\x91\xe7\x97\x53\xea\x86\x91\x06\x20\xed\xd3\x73\xe7\x2e\x8c\x63\x35\x3f\xdb\x4d\x94\x58\xa0\x9e\x4d\x83\xcc\x7d\x0b\x1a\xdf\x85\x38\x00\x3c\x5f\x8b\x75\xbc\x32\x50\x88\x87\x6b\xff\xe6\xd6\x57\xb0\xf3\x65\xe8\x86\x01\x65\x1c\x7e\xab\xe0\xe8\xc9\x4f\xdf\xd1\x33\xd1\x45\x03\x81\xb2\x5c\x90\x74\x95\x79\xb8\x35\x2e\xca\x0a\xa8\xef\xca\x48\xfc\x98\x9a\x32\x02\xb9\x21\x1a\x31\x0c\x01\x3e\x26\xca\x59\x54\x0a\x01\x8d\x91\xcc\x46\xa6\xb1\x36\x14\xd3\x2c\xfa\xd5\x50\x1a\x81\xb6\x40\x19\x64\xaa\xb1\x73\x51\x2d\xbf\x60\x03\x0a\xdf\xe8\x92\x25\x54\x3c\x68\x7a\xd6\x6d\x81\x98\xb0\xc6\x7b\x88\x8d\x39\x84\x39\xf9\x1c\x9f\xda\xf4\xf4\x43\x18\xfb\xae\xa5\xa1\x49\x69\xa4\xc0\x8a\xf5\xe8\x86\xb6\xc1\x15\x7d\x8c\xf8\xb3\x79\x0f\x03\x92\xe8\x3d\x80\x17\x44\x15\x4f\xfd\x9e\xed\xf2\xaf\x16\xbd\x64\xab\x56\x7e\x18\xd7\x52\x4f\x03\xb2\xe1\x88\x7c\xe7\x20\xe0\x16\x82\xb6\x6a\x4f\x29\x3b\x31\xeb\x07\xcb\xfa\x64\xf7\x2e\xd0\xfc\x0d\x55\xce\xb3\x28\x1a\xe4\x13\x57\xc3\xca\x0f\xa4\xee\xf9\x0f\x5e\x1a\xee\x51\x1a\x5c\x9c\xb7\x2e\x24\x6c\xb5\x1d\xd0\x35\x7a\xef\x57\x76\xb5\x30\x46\x96\x1a\xc5\x3c\xa1\x7c\x24\x63\xa8\xd8\xc6\x89\x49\x02\x0b\xa6\xc9\xd1\x2b\x6d\x64\x1e\xff\x60\xce\x67\xf3\x51\xb4\x61\x05\x5b\x55\x70\x5f\xdb\xd0\x47\x69\x18\x62\x6d\x54\x19\xba\x0c\xf7\x44\xa5\x4f\xa6\x0a\x79\x67\x75\x33\x5f\xc9\xdc\x44\xc6\x9d\x17\x3f\x33\xdc\xd3\x78\x67\xa4\xf1\xce\x08\xf2\xac\x99\xbc\x31\x41\x86\x5b\xe2\x3a\x44\xb5\x91\xc8\x67\x03\x2e\xdb\xa7\x7f\x72\x71\xef\x98\xdb\xf8\x6c\x8e\x44\x4b\x92\x11\x85\x66\x2f\xa8\xac\x17\xdc\xf3\x2d\x28\x07\x0b\x3b\xbf\xd6\x0c\x43\x66\x18\x33\x6d\x0c\xad\xb1\xf0\xa7\x57\x0b\xee\xd5\x17\x76\xce\xfd\x64\xc4\x92\x75\x71\x2f\x7c\xf9\x15\xab\xad\xbc\xb0\x2c\x38\xe4\x0b\x6a\xe9\x05\x07\x7b\xc1\x88\xeb\x42\xbf\xb1\x49\x34\x39\x1e\xfa\x2e\xb8\x81\x5b\x30\x70\xb4\xe0\x72\x12\x24\xbe\xcc\x82\xa3\xbd\xf0\x4a\x79\x81\xa0\x0d\xdd\x82\x05\xf7\x62\x0b\x19\xf7\x06\x48\x6f\xee\x00\xbd\x62\xa8\x17\xb6\xae\x5e\x7b\xfc\x22\xd0\x8e\x5b\x3e\x7a\x8c\x78\x5b\x57\x92\xd4\xab\xde\x85\xc9\x5e\x45\x82\x08\x35\x87\xd1\xbe\x55\x03\xba\xf6\x34\xca\x66\x77\x13\x17\xbf\x0e\x63\x58\x69\xda\x8e\xdc\xe6\xdf\x89\xed\x42\x9d\x58\xa9\xbb\xe5\x66\xbf\x35\x83\xb8\x00\x49\x99\x9c\xfa\x9b\x00\xad\x1e\x06\x4a\xcb\x5a\xdc\xd5\xef\xf9\xef\x06\x05\xd9\xc2\x6d\x79\x2d\xa4\xe5\x65\xe5\x16\x27\xdf\x86\x2c\xed\x9e\xaf\x47\x4b\xd3\x06\xf7\xcb\xda\xa9\xe1\x43\x41\x62\xf3\x5a\x09\x60\xf7\x99\x75\xcd\xb8\x7f\xcb\x73\xf7\x56\x56\xd9\x7f\x59\xdf\x8e\x19\x4e\xd0\x62\xf8\xa6\x31\x7e\xda\xd0\x52\x6b\xb6\x32\xc1\x59\xcf\x36\x68\x8d\x65\xb0\xef\x8c\x80\x90\xd5\x8e\x91\x5a\x19\xfd\x4f\xa2\xab\x35\x5f\x4f\x8a\x76\x24\xa1\x84\x25\xa3\x32\x40\x4b\xa2\x2b\x50\xfc\xb2\x6f\xc9\x89\x5a\x72\xe1\x2e\xd5\x43\x92\x9a\x97\x76\x51\x37\x27\xd1\x2b\x29\x4b\x1e\x9d\x2c\xfd\xc1\xcc\xd2\x7b\x40\x4b\x4a\xef\xd2\x3c\x9a\x98\x1c\x97\xc8\xd2\xbb\x2a\x20\x9f\x7c\xa2\xb1\xe8\x25\xef\xa3\x83\x64\x54\x86\x4b\x91\x86\xa0\x61\xbf\xe9\x29\x61\x5f\xcb\xf9\xe5\xa0\x06\xfc\x0e\xa8\xe6\x48\xcd\xf9\x74\xc1\x4d\xc7\xd2\x7b\x6d\x4b\x7f\xcc\xb2\x34\xe9\xc9\x50\x5d\xd8\x88\x33\xf9\xd3\xbd\x20\x6a\xe4\x9b\x68\x89\x31\x3c\x9d\x25\x55\x06\xd0\x2d\xeb\xda\xc9\x58\xdc\xf4\xec\x33\x57\x4d\x3e\xe1\xf2\x11\xc8\x11\xa1\xa1\x25\x8e\x47\x58\xce\x99\x63\x76\x61\x2d\x17\x19\x9c\x27\xce\xcd\x15\x01\x7a\x23\xc1\xfe\x62\x14\xcc\xe4\x2e\x45\xcb\xbf\x03\xe5\x88\x6f\x00\x35\x28\xe4\x9b\x37\x94\x4b\x7f\x00\xb2\xf4\x9b\x84\x25\x2d\xe4\x92\xbe\xe4\xd2\xdb\x4a\x90\x7b\x1b\x4a\xb7\x8b\x07\xa9\x88\xf4\xe8\xe0\x1b\x6d\xe1\xd2\x6c\x61\x2c\x9e\xd3\xef\x2e\x6d\x80\xfc\xcf\x46\xd3\xec\x1c\x4f\x20\x96\x66\xe0\xd8\x13\x0d\x04\x69\x17\xbe\xd9\x66\x5a\x95\xe8\x37\x1a\xbb\x57\x1a\x3b\x1c\x86\x4d\x90\x16\x6f\x61\xac\x7e\xbb\x85\x81\x87\xb7\x7c\x52\x19\x92\x83\xe7\x9e\x9e\x9e\x59\x89\xfa\x9d\xf1\x8a\xb7\x84\x57\x74\x87\x57\x74\x87\x57\x6c\xe7\x8a\xdf\x1a\xac\xec\x1a\xf1\x88\x44\xc5\x63\x85\xeb\x8e\x44\xf1\x4c\x18\x7c\xc9\x76\xe7\x38\xe9\x05\xd2\x23\xb9\x15\x55\xc0\x8a\xfa\x74\x05\x67\x1a\xa8\x64\x8b\x11\x91\x8e\xc3\x30\x67\x2d\x0d\xd3\x16\xbe\xf2\x5f\xae\xa9\x83\xe7\xcc\xd9\x32\x5c\x08\xb2\xf1\x39\x5f\x7d\x5b\x56\xb2\x74\x86\xe4\x6b\xb6\x77\xfd\x6b\xb2\x8d\xcd\x8e\x17\x9b\xe3\x55\xab\x57\x59\x68\xba\x37\x5f\xd1\x36\xaf\xa8\xb0\xa3\x31\x58\xe9\xc5\x59\x11\xc8\x15\xd5\xf4\xab\x0f\x59\xaf\x64\x55\xb1\x72\x15\xad\x16\xd9\x0a\x86\x6b\xd7\xfe\x02\xe0\xda\x7f\x0c\xb1\xf6\x47\xde\x20\x35\x91\xba\x10\x6b\xbf\xe5\x5c\x53\x50\xd6\x54\x60\x6b\xdc\xf9\x04\xd2\x30\xcf\x9a\x97\x71\x40\x4a\x2c\xf4\xb5\xac\x72\x68\x4e\x2d\xfb\x85\x6b\x6b\x0d\x55\x26\xeb\xf1\x0a\x8e\xea\x2a\x90\x0d\x8f\xfb\x84\x98\x29\x02\xd1\xae\xe9\x95\x98\x35\x75\xd8\x5a\x8f\x99\x45\x48\xd7\xd4\x5c\x40\x5a\xcb\xd5\xb2\x86\xb1\xbf\xb1\x12\x6c\x22\xd6\xf2\xe9\xcb\x1f\x40\x37\xd6\xd4\x80\xde\x89\x4e\x40\x13\xbe\x81\x2b\x3e\xef\x24\x7a\x7d\x7e\x23\xeb\x3a\x05\x1a\xf0\xe7\x15\x36\x3c\xa7\xdc\x70\x99\x6e\xb8\xfc\x36\x92\x6f\x09\xa4\x1b\xd0\x8d\x7d\xa6\x79\x25\xd1\x2b\x4c\x1b\xce\xc1\x86\x47\xc6\xdc\x01\x20\x55\x9d\xd7\x8d\xc5\x53\x77\x20\x0b\xef\x23\x09\x77\xa2\xb6\xe1\x4d\x00\xa0\x8c\x68\xca\x56\xc6\xd0\xd4\xc6\x7f\x00\xb2\x71\x1f\x80\xe4\xe4\xb5\xcf\x39\xf3\x05\x2e\x59\xe0\x9a\x79\xce\x2c\x4a\x43\x47\x1b\x6e\xf2\x36\x32\x3f\x18\x5d\xf3\x50\x2d\x77\xf2\xcb\xc7\x46\x1b\x9d\x17\xcb\x5c\x58\x45\xb6\xeb\xda\xd0\xa6\x6c\x7c\x30\x78\x63\x51\xa7\xf8\xe4\xc9\x5a\x96\xc4\x7b\x7f\x1b\xef\xa1\x6e\x68\x4c\x36\x7e\x63\xb5\xd1\x1d\x94\x0e\x84\xd8\x0f\xa2\x8b\x6b\x99\x08\xdc\xc6\xef\x90\x36\x3e\x22\xfb\x1d\x47\xe9\xd0\xed\xdf\xa9\x9f\xd5\xd2\xf3\x56\xc4\x77\x46\xa2\xbe\x8b\xd6\x53\xaf\xef\x3b\x0f\x98\xbe\x63\x45\x60\x8e\xbf\xe3\x47\x28\x80\x6e\xac\x44\x8d\xab\x69\xbc\x60\xcb\xe3\xb8\x2d\x97\xd5\x96\x71\x97\x2d\x2f\xff\x6e\xa5\xe6\x59\xcf\xae\x55\xeb\xb0\x6c\x79\x53\x05\xf7\xb6\xbe\x1a\x92\xd6\x6c\xe9\x35\x6d\xed\xc0\xac\x06\x99\x33\x4c\xb0\x65\xf0\x77\xcb\x0b\xb5\x5b\x93\xb0\x98\xac\xdf\x31\x6d\x19\xc4\x80\x77\x86\xa4\x13\x37\xc3\x5b\x2a\x8a\x2d\x5d\xaa\xad\x88\xdb\x48\xbc\xa3\x33\xc6\x63\xcb\xaf\x55\xb7\xfa\x91\xb8\x28\xa5\xad\xe8\x8e\x6b\x4f\x7f\x4b\x40\xdb\x12\x10\xbb\x9b\xe8\xcf\xa0\x6c\xa9\x3b\xb6\xf2\xfa\x03\x10\x9c\x9b\x11\xc9\xc8\x0a\x4e\xe2\x85\xef\xad\x85\xc8\x23\xb9\x25\x8a\xe5\xc4\xf7\xfc\x6c\xc9\xc5\x14\xa2\x7f\x88\xf4\x76\xe9\xd6\x6f\xc8\xb7\xce\x1f\x49\xc9\x55\xcb\xef\xb8\x39\xde\x49\x33\xff\x0b\xdb\xb6\xe3\x4d\xa6\x9d\x7d\x9e\x72\x05\x29\x64\xc4\x47\x24\xb5\x21\x99\xc6\x1d\xcf\x8e\x77\x8c\xe1\x0a\x12\x41\xd8\x59\x10\x28\x05\x59\xf0\xa2\xce\x8e\xa7\x5d\x3b\x5a\xd5\x1d\x6e\x38\x00\x7d\xb0\xd4\x4f\xa2\xf8\x3b\x2b\x3b\x5e\xa5\xdb\xd9\xaf\x01\x7c\x27\xd9\xc2\x28\xed\xfc\x3d\xf5\x9d\x7d\xca\x90\x81\x68\x88\x68\x47\x4d\xf1\x46\x57\x6d\xcf\x43\x8f\x37\xbd\x05\x23\x59\xdf\xb8\xeb\x79\xe3\xfd\x97\xbd\x8f\x0b\x83\xdc\x13\x55\x3e\xb9\x66\xd9\xd1\x22\xef\xbd\x45\x06\x59\xb0\xf8\x37\xf7\x82\xc5\x53\xf6\x74\x12\xf6\x74\xef\xf6\xb4\x2f\xf1\xd2\xc8\x9e\xd7\xc4\xf6\x74\xe2\x40\x62\x53\xf5\xc0\x69\x8f\xcb\x51\x86\xec\x69\x85\x8e\xbc\xd1\xa9\x90\x34\x2b\x52\x67\xfc\x87\x9e\xaa\xd8\x4b\x73\xa2\x86\x28\x06\x29\xf6\xfe\x42\xda\xde\x9f\x84\xee\xb9\x39\xda\x9b\x9b\x37\x22\xc9\xf9\xf6\x8b\x6f\x7e\xb4\x51\x7b\x6f\xa3\xf6\x5e\x83\xec\x4d\x69\xc4\x02\xa2\x47\xb9\x57\x1b\xe5\x72\xfe\xc3\x15\xb3\xf7\x3f\x4f\xb2\xe7\x1d\x7a\xa0\x77\x20\x31\xec\x22\xe5\x7b\x9c\x48\x63\xe9\xee\xa5\xc3\x13\xeb\x4f\x50\x22\x63\x2b\xc7\xf6\x10\x7b\x91\xde\x01\x11\xde\x33\xc5\xb2\xc7\x69\x4a\xd7\xff\xd3\x1a\x67\x3f\xd8\xb1\xa7\xad\x03\x1a\x7a\xc2\x91\x55\x57\x21\x27\x89\xa7\x72\x6f\xd0\x3a\x36\xe1\x89\xba\x6f\x7b\x6f\x5d\xf7\x7e\x2f\x05\xa2\x8a\xfa\x07\x6d\x21\x50\xcb\x0c\x4b\xdf\x90\x15\x3b\x14\x43\x89\x20\x3f\x88\x4e\xbe\xb1\xff\xe7\xc9\x27\x0f\x0e\xf7\xde\x6a\xee\x3b\x77\x63\x0d\x44\x35\xe9\x81\xf6\xeb\xc0\xd3\x9e\x03\x17\xca\x81\x63\x71\xe0\xf2\x38\x70\x79\x1c\xa8\x9c\x0f\xdc\xf7\x1c\x78\x4a\x77\x30\xe7\x37\x23\xd1\x82\x4a\x66\x2d\x65\xad\x9c\x58\xb0\xca\xe1\xbb\xfb\x6c\x31\xd6\xa0\x6b\xe9\x20\xeb\x66\x6c\x48\x64\xe8\x20\x8b\xe6\x0f\xd6\xf5\xcc\x12\x1b\x36\xb5\x85\x9b\x70\x30\xe9\xaf\x48\x2a\x66\x40\xad\x07\x56\xf9\x02\xc9\x3d\xf8\x2d\xd2\x3f\xf6\x03\x3d\x23\x92\x05\xab\x6b\xe9\x9b\x1c\x38\xaf\x07\x99\xd4\x7b\x88\xcd\xc1\xbc\xee\x96\xef\xac\x59\xdd\x96\x8d\xdd\x33\xed\x9d\xc3\x16\x83\x37\x07\xee\x99\x0e\xf6\x6b\x2d\x23\x12\x7d\xef\x6a\xb3\x60\x32\x00\xf4\x68\xdd\x0d\x2b\x67\x4a\x84\x5e\x5a\xdb\xdf\x2d\x8e\x89\xe1\xd4\x1f\x13\x59\x93\xa0\x41\x76\xbd\xe1\xe0\xad\xe5\x81\xdf\x73\x09\x72\x1b\x99\x03\x8d\xe8\x41\x96\x68\x44\x29\x51\x66\x28\x89\x95\x17\x4e\x06\xf5\x44\xb4\x25\x29\xac\xbf\xee\x46\xc2\xc1\xbb\xa3\xff\x70\xd5\x21\xf9\x87\x49\x98\x8b\xc7\x1f\x19\x4a\x3f\xea\xa1\xa7\xbc\x70\xf4\xdf\x74\x1c\xfd\xed\xa7\xff\xd9\xd7\x87\x19\x0b\x48\xb9\x81\x03\x39\x02\xe9\x3a\x3a\x52\xc1\x1c\x69\x70\x8e\xf4\x66\x8e\xb2\x7a\x1e\xd0\xaf\xa3\xfe\x52\x97\x05\xa2\x8e\x54\xd5\x47\xae\x9c\xa3\x2c\x9b\x2f\x40\x8f\x18\xde\x23\xae\x17\x01\xcd\x98\x6f\x06\x37\xe9\x48\x5f\xef\xa4\x47\x54\x42\x8e\x34\x36\x47\x1f\x7f\x3b\xf2\x84\xfe\xc8\x5f\xb0\x3a\x9a\xcd\x69\x49\x32\xa2\x82\x65\xbf\xf2\xbd\x15\xbb\xbe\x62\x15\x3b\x3e\xdd\xb3\x85\x07\x5f\xed\x4f\x66\xbd\x10\x5d\x0d\x99\x01\x38\xf2\x7c\xf4\x48\x91\x3d\x8a\x38\x16\x86\xb4\xea\x84\x63\x0d\x1f\x53\x9a\x7c\xd2\x53\x2e\x6d\xb2\x79\x92\xc7\xce\x9d\xaa\x9f\xec\xe0\x28\xe3\x13\x15\x28\x3c\x51\xe3\x86\x53\x06\x15\x9e\x9f\x3e\xca\xfb\xd3\x76\xb6\x03\x92\x8c\xe8\xce\xe7\x29\x7c\x51\x25\x91\xda\x93\x9f\xfe\xdc\x1b\x64\x4e\xa4\xc7\x9f\x3f\x3b\xf7\xab\x0b\x3f\xfd\x39\xf6\xcf\xce\x7e\x34\xe1\xa7\xf8\xa5\x13\x20\xdd\x68\x7c\xe8\x06\x5c\xe4\xec\x43\x37\xc5\xba\xf2\x91\xd3\xf6\x3f\x3f\xbd\x27\xfe\xf1\x9b\x59\xfc\xb0\x10\x63\xc5\x9c\xa5\xf5\xdb\xed\x05\x3f\x3a\xfb\x22\xeb\xcc\x21\x3b\xd3\x17\x84\xe1\xd2\xcd\xc9\xd9\x3e\xa0\xca\x49\x74\xf4\xcf\xfe\xa3\xa5\xb3\x7e\xa7\x64\x45\xc5\xef\x94\xce\x5c\x79\x67\xce\xc8\x99\x1d\x38\xfb\xd6\x7f\x72\x19\x9e\xb9\xe6\xce\xd4\x32\x67\x7a\x4d\x67\xce\xd4\x99\xee\xfb\x99\x87\xce\x67\x4a\xce\x99\x7a\xe8\xdc\xb9\xaf\x26\xcf\x5c\x94\x67\x5c\xff\x21\xd2\x3e\xea\x75\xec\x33\x4d\xd6\xbf\xf8\x59\x39\xdf\xa8\x5f\x3e\x37\x00\x2f\x89\x1a\xb6\x73\xc5\xfd\xce\x99\xf1\x9b\x33\x9d\x9f\x33\x9d\x76\xa0\x29\x11\x7b\xe0\xae\x43\x21\x6c\xb4\x81\x46\x8c\xdf\xfb\x00\xa9\x27\x7b\xe1\x71\xcd\x85\xb1\xc2\x0b\xbe\x56\x02\xd2\xe3\x8b\x8b\x18\xd8\x7e\x4f\xbf\x15\xb2\xf2\xbf\xf2\x0d\xb5\x89\x17\x44\x00\x81\xd6\xf0\xb4\x2f\xb2\x4b\x9f\x02\x6d\xf9\xae\x4a\xc2\x85\x91\xc1\x8b\x98\x8e\x3b\xa0\x21\x9f\x66\xfc\xac\xe0\xc2\x1f\x7e\x8c\x86\x33\xfe\xe0\xd9\x05\xba\x81\x28\xb3\x96\xbb\x4b\x36\x17\x8b\x7e\x87\x17\xae\xbc\x87\x71\xa5\xe1\xb8\x52\xfa\xae\xd4\x33\x57\x04\xa0\x0c\xc9\x54\x5d\x29\x5c\x57\x5a\xb2\xab\xfd\xe2\xc3\x00\xa4\xf6\x28\x96\x3a\x23\x7a\x61\x3b\x5a\x3a\x66\x57\x7f\x22\x77\xa5\x23\x72\xf5\x91\xd5\xab\x74\x61\x45\x84\x06\x96\xcc\x29\x5b\x75\xcb\xa9\x7a\xfb\xea\x77\xba\x57\xc6\xa3\xae\xdc\xdf\xc7\xa3\x8e\x2b\x2f\xdb\x5f\x7d\x70\xff\xca\xaf\x94\xae\x8c\x37\x5d\xdd\xe0\x4a\xfc\x40\x92\x03\xc2\x85\x23\xa0\x50\x93\x6e\x07\x06\x3d\xb7\x31\x50\x34\x24\xaa\x7a\xf6\x9d\x19\xbe\x94\x8c\x77\xf0\x03\xba\x63\x41\xa5\xed\x8d\x71\x2f\x3f\xfe\x7a\xaa\xf2\x37\xa0\x47\xfb\xcd\x46\xbd\xbe\xaf\x0d\xaa\x59\x79\x2d\x66\x47\xd1\xc9\x50\x10\xdf\x80\x66\xac\x62\xc6\x52\xb8\x8d\x0a\x84\x3f\x6e\x14\xc8\xce\x92\xc3\x30\x5e\x81\x86\x4c\xbb\xb1\x2f\xb6\x71\xdb\x4c\x55\x4b\x20\xd0\x60\x7a\x72\x9d\x78\x92\x7a\x32\xf4\x04\x4e\x95\xdd\x22\xb1\x19\x52\x0e\x39\x50\x52\x11\x41\x0b\x2b\x41\xf0\x04\x44\x5d\x3b\x25\x39\x8b\xba\x75\xbf\x60\x17\xf8\x83\xc8\x8e\xdc\x7d\x96\xd5\x10\xd0\x93\xbb\x78\x1d\xf8\x33\xcb\xbd\x58\x9a\xba\xa8\x7a\x87\x13\x97\x56\x95\xc0\x46\x2b\x81\xf7\xa1\x3f\x2c\xa9\xdf\xe3\xa0\xee\x84\x1f\xc5\xda\xa2\x0b\x49\x43\x3e\x44\x2c\x4b\x11\xce\xbc\x40\x62\xf4\x57\x7f\x12\x2a\xe3\xdb\xaf\xf6\xb6\xee\x3d\x13\xfc\xb0\x6b\x4e\x84\x13\xb0\x64\x60\x97\x1c\x92\x01\x45\x31\x8e\xf1\xc0\xb6\x41\x4a\x6a\x8f\xe8\x63\x46\x47\x3a\x19\x50\xaa\xe2\x8c\xf0\xfc\x37\x19\xd8\x6f\x05\x24\x03\xbb\x85\xa3\xe8\x87\x28\xbb\x64\x60\x3f\xdb\x9b\x0c\x4c\x19\x24\xb8\x64\x56\xb8\x66\xe8\x31\x78\x82\x0b\x64\x37\x5c\x77\xa9\xed\x0b\x14\xbd\x3b\x67\x20\x67\xea\x87\x21\xdd\x7c\x24\xa9\x59\xd4\x24\x75\xb7\xab\x12\xba\xd4\x09\x4d\x7c\x82\xef\x9d\xc7\x40\x0c\xe2\x05\xf2\x0d\x8d\x4d\xdd\x01\x55\x82\x26\x20\x83\x6a\x9c\x84\xbf\x49\xa8\x73\x37\x20\x8a\x69\x3c\x0c\x53\xfe\x48\x54\x13\xf1\x06\x4d\xbc\xb9\x19\x7f\x78\x34\x19\x9a\xe3\x90\xd8\x4f\x03\x5a\x45\xb9\xed\x2c\x02\x99\x32\xf9\xde\x37\xab\xe4\xab\x95\x6f\xc9\xdc\xa3\x1c\xe8\x85\xed\x5e\xb2\xac\x57\x9c\x9f\x31\x0f\xfc\xbd\x64\x68\x76\x3b\xa0\xd4\xca\x4a\x32\x0b\x58\x29\xd1\x59\x46\xe4\x2f\x05\xca\x2d\xec\xa2\xe4\x9e\x08\xd6\x5b\xc9\x73\x4f\x57\x6b\xc2\xcf\x69\xf4\x0b\x18\x45\xaa\xc7\x6f\x28\x90\x37\xec\xc1\x8d\x85\xe2\xe4\xaa\x2c\x2a\x1b\x51\xb2\x46\xee\xf7\x90\x94\xcc\x98\x3b\xb7\x1f\x88\x51\xa2\xc9\x53\xa6\xc1\x37\x0b\x68\xc6\xe2\xe6\x4c\x9b\xb3\xd4\x25\xdf\xd8\x1a\xb2\x81\x1a\xd9\xc1\xc9\xc4\x72\x9b\xee\x1d\xf1\xc7\x76\x48\xc6\x7c\xfb\x2f\xfd\x39\x16\xb1\x35\xe0\x6c\x4c\x32\x62\x51\x13\xeb\xaf\x29\x10\x1c\xca\x84\x61\x1e\xbb\xdb\x1f\xc9\xd8\xeb\x5f\x90\x47\x22\x55\x76\x63\xfb\x60\xa5\x10\x82\x0b\x44\xfa\x3b\x5d\xc9\xa4\x8b\x5f\x66\x28\xf9\x42\xa4\x83\x03\x82\x1f\x71\x8b\xd9\xb0\x81\x55\xf2\x49\x92\x41\x35\x4e\xf4\x47\x49\xb4\x00\xbd\x9e\x10\xc9\xd4\x93\xc2\xaa\x8f\xbb\x01\x25\x51\xdc\x27\xde\xee\x4f\x34\x42\x25\x24\xe3\x62\xcd\xec\xfa\xbb\x22\x7c\x53\xab\x64\xce\xdc\xb9\xf8\x6c\x2a\xe7\x2d\xd0\xa3\xcc\xd8\x4d\x4f\x25\xde\x54\x4e\x46\x61\xcd\x28\x0d\x99\x6d\x28\x13\xfe\x36\x52\x82\x5f\x37\xfa\x42\xf4\x83\xe8\xc4\xac\xd8\xcf\xe0\xc7\x7f\x45\x6f\xe0\x27\x87\xfa\x44\x88\xb2\x2b\xd1\xc5\x9f\x9b\xa3\x9d\xc8\x0f\xb3\xc8\x4f\x6a\x83\xd4\xee\x57\x88\x55\xeb\xa6\xbd\xf8\x31\xfa\xff\x07\x00\x00\xff\xff\xaa\x0a\xcc\xb8\xdf\x5e\x00\x00") +var _keysWordlistJapaneseTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x5c\xff\x72\xe2\xb8\xd2\xfd\x9f\xa7\x5e\xbc\x5c\x2f\x01\x3c\x0e\x71\x1c\xc7\x61\x58\x87\x8a\x2f\x43\x60\x80\x0c\x59\xb8\x93\x8f\x2c\x3c\x8c\x5f\xe4\x2b\xf5\xe9\x3e\xea\x99\xaa\x54\xea\x1c\x59\xd6\xcf\x56\x77\xab\x25\xd3\xf5\x93\xae\x3f\xe8\xfa\x45\xd7\xcf\xbb\x7e\xd5\x25\x45\xcf\x92\xca\xae\xdf\x92\x3c\x03\x8d\xba\xfe\xdf\x5d\x72\x03\x32\xee\xfa\x8b\x2e\xf9\x93\xef\x64\x5d\x32\x06\x9a\x76\xfd\x49\xd7\x6f\x8c\x58\x72\x11\x92\x93\x09\x79\xd9\xf5\x07\x44\x07\xa0\x4a\xfe\xaf\x40\x1e\xbb\x24\xef\xfa\x29\xc8\x53\xa8\xd1\x5e\x7d\xea\xfa\x19\xd0\xbc\xeb\x9f\x80\x9a\xae\x3f\x64\x86\x26\xfc\x25\x7d\xc7\x93\x51\xd7\xbf\x74\xfd\x21\xb9\x3e\x69\xd9\x8a\x56\xfa\xa4\xd5\xbd\xc8\x70\xfc\xa7\xeb\xe7\x7c\x78\xe9\x92\x91\x11\x57\xf4\xb2\xeb\xaf\x89\xf6\x92\x4d\x9f\x1c\x88\x4e\x1c\xb5\x13\xd3\x8e\x7e\x2c\x2e\x6c\xc5\xa5\xeb\xbf\x1a\x4a\x06\xd2\xa4\x9a\x5c\xeb\xbf\x76\x49\xd2\xf5\x77\x42\x42\x4b\x46\x5d\x1f\xe5\x84\x17\x58\x7f\x92\x76\xc9\x1f\x40\x37\x32\x8b\xb7\x5d\xff\x42\x5e\x11\xd5\x5d\xff\x91\xc4\x8f\x5a\x72\x23\x65\x44\x92\x5b\x5b\x42\x8d\x93\xae\xbf\xb2\xe1\x0a\x4f\x66\xcc\x99\x87\xa1\x30\x52\x58\xcf\x12\x99\x7f\x47\x0a\xa2\xaf\x26\x44\x81\x2c\x7d\x9e\xb5\x27\x3a\x00\x03\x88\x24\xda\x32\x08\x52\x29\x6f\x0f\x58\x3c\x50\x0e\x94\x89\xd8\x0e\x48\xd6\x2c\x24\xe3\x28\x0e\x28\xbd\x03\x59\x08\x8f\x44\x27\x96\x3d\xed\xfa\x6f\x98\x69\x21\x96\x5c\x60\x08\x74\x0d\x11\xb5\x3d\x5b\x44\x17\x11\xea\x81\x71\x7b\xaf\x82\x04\x0f\x44\xca\xff\xc3\x42\x1e\xbb\xe4\x2f\x4f\x72\x36\xeb\xa9\xeb\x5f\x0d\x25\x13\xa0\x19\x0b\x9e\x05\xe1\xef\xbf\x93\x8c\xfd\x13\xad\xe8\x2b\x2b\x9f\x77\xfd\xb4\x4b\x32\x56\x34\x97\x01\x8b\xcd\x7c\xf6\x48\x3b\xd5\x48\xc5\x37\x24\x57\x43\x41\x16\x12\x90\x85\x8c\x75\x4a\xf2\x48\xf4\x4a\xf4\x46\x74\x32\x94\x8c\xfc\x10\xb4\x10\xe6\x41\x5c\x83\xd6\xec\x17\xdf\xe3\x17\x74\x83\xa4\xf1\xd9\x16\x44\x4b\xff\xc2\xbf\x7c\x61\xd9\xf5\x1f\x0c\xd9\x7b\xaf\x7c\xba\x82\x70\x0e\x28\x7f\x40\xda\xac\x6d\x97\xfc\x41\x21\xda\xb1\xb2\x1d\xa7\x6a\xcf\xf9\x7f\x73\x69\x56\xcd\x3b\x27\xe4\xc0\xb4\x23\x87\xf9\x27\xd3\xce\x6c\xce\xd5\xd2\x82\xbc\xa6\x50\x8f\x20\x8d\x89\x42\x92\x58\x8b\x12\x91\x7e\xad\x36\x10\xac\x92\x64\x28\xfa\xb3\x20\x41\x7d\xa2\x19\x88\x6a\x96\x3d\x12\x6d\xb1\x30\x12\x85\x32\xe1\x1a\x0b\xda\x8b\xeb\x27\x89\x55\x66\xa2\x87\x8b\xae\xff\x8f\x0d\x43\x50\x08\x03\xa2\x94\x28\xb6\x27\x37\xb9\x08\x02\x9f\xb2\xa8\xa2\xeb\xdf\xd9\xca\xef\x33\xa9\x64\xb9\x85\x08\x48\x6c\x5b\x21\x3d\x0b\x24\x95\xf5\x90\x19\x92\x02\x53\x91\xce\x07\x20\xed\x46\x2a\x4b\xe5\x44\xf4\xc1\xac\x59\x97\xe4\x40\xb9\xe9\xcf\x35\xf9\x04\xe3\x9e\x8a\x5a\x68\xa4\x7d\x39\xdf\x9c\x8a\x0c\x4f\x49\x56\xee\x49\x18\xb1\x96\x44\x93\xef\xa9\xe5\x41\xb4\xde\x02\xc3\x93\x4a\x8f\xbf\x00\x55\x22\x88\xa9\x91\x30\xd8\x13\xac\xc5\x54\xa6\x6f\x40\xf4\x85\xe8\x96\xb3\x2c\xdc\xf4\x7b\x2a\xab\x49\x1b\xb3\xa0\x16\x27\x9f\x70\x00\x16\x1c\xc9\x05\x17\x6a\x2a\x0b\x6a\x0c\xa9\x4b\xa5\xc7\x39\x55\x48\xaa\x2b\xd2\x8d\x7c\x4b\xf4\xca\x6e\xad\xd9\xca\x35\x74\x05\xd0\x13\x47\x60\xcd\x97\xb6\x44\x3b\xd6\x7f\xea\xfa\x77\x44\xf7\x30\xed\xa9\xcc\xc5\xc4\x72\xc7\xbe\xca\xd2\x01\x12\x1b\x69\x64\x68\x95\x85\x31\x9a\x88\xd4\xd4\xe4\xba\x04\x40\xd6\xd6\x37\x51\x78\x56\x77\x20\x99\x49\x43\x32\xa6\x57\x93\xca\x4a\xa9\x1c\x49\x52\x1b\x46\xd7\xbe\x0c\x9a\x26\x95\xb1\xcf\x88\x4a\xa0\x82\xf6\x05\x64\x61\x43\x07\x3b\xe9\x88\xea\xae\xa1\xc8\xe9\x10\x4f\x40\x26\x44\x19\x97\x0a\xf8\x3d\x91\x6a\x55\x90\x93\x7b\xdb\x96\x13\x48\x0e\x34\xc2\xa4\x0f\x65\xbc\x22\xd2\xa7\x99\x4c\xbc\x16\x17\xdd\x82\xa1\x88\xeb\x9f\xcc\x56\x77\xfd\x25\x50\x2b\xae\x85\x56\xb9\xeb\xfa\xb7\x40\x67\x9d\x4c\x19\x15\xe1\x96\x87\x69\x61\x4e\x1f\x89\x76\x40\x37\x56\x79\x40\x27\x20\xb5\x50\x50\x4b\x1c\x9d\x40\xc6\xcc\x5d\x40\x18\x87\xaa\x75\xac\x8a\xc2\xfc\xc0\x94\xfc\x2b\x56\x0d\xc8\xdc\x7a\xa4\xf3\xf3\x97\xcf\xb9\x42\xce\x91\x8c\xeb\x98\x4b\x7e\x64\x5e\x42\x4d\xa2\x82\x32\x32\x0b\x98\x83\xa4\x6c\xee\xc8\x14\xc1\x85\xe4\x91\x68\xc6\x7a\x52\x8e\x3e\xc8\xd1\x17\xf5\xe1\x9e\xd8\xcc\x8e\xb8\x48\x47\x74\x94\x46\x34\xe3\x40\xaf\x9c\x73\xe1\x09\xf3\x84\x42\xe6\x20\x63\x0c\x34\xc9\x13\xd0\x04\x2e\xa8\xa4\x05\x15\xa9\x19\xbe\x50\x8d\x8d\xe8\x7a\x8d\x44\x5c\x62\x0f\x73\xef\x0d\x09\x57\xaf\x73\x4d\xce\xd7\x6c\x45\x8d\xfc\xb0\x16\xbe\x92\x82\x19\x4a\xdf\xe3\x92\xeb\x5a\x88\xe9\x8b\x11\x66\x04\xeb\x1a\x24\xbe\xf3\x08\x49\x01\x2a\x39\x3d\x22\xde\xf6\xc2\x5c\xc4\x2f\x27\x89\x8d\x6d\x68\x7b\x40\x34\xcf\x33\x9c\x7d\x90\x85\x97\x81\x17\x18\xe5\x91\xac\x14\x1d\xbf\x6f\x10\x27\x90\x95\xd4\xad\x2b\x00\x7c\xed\x25\xea\x95\xaf\xbd\x8a\xc2\x19\x73\x84\xde\x7c\xfb\x2f\xb0\xf5\x42\x92\xbe\xd4\xb1\xb2\xe1\x4b\xb0\x0d\xfc\x46\x12\x93\x29\x6e\x81\x84\x0d\x21\xc8\xc0\x44\x32\x19\x88\xe6\x7b\xef\x99\xc0\x7c\x5a\xf5\xb2\xec\xb1\xb7\x1c\x49\xc3\x34\xb9\xa0\x3a\x01\x99\xb2\x06\x2c\xc6\x3f\x49\x66\xd6\x78\x29\xc7\x93\x68\xa8\x46\xa6\x1f\xb5\x98\x31\x76\x70\x40\xaa\x1f\x27\xd0\x8f\x44\xea\xde\x4f\xbc\x87\x3f\xf6\xbb\xe2\xb1\x2e\x5a\x69\x0b\x48\xed\x1d\xab\xb1\x77\xb8\x41\xfe\x86\xf1\x23\x6f\x7d\xb1\x4b\x9f\x73\xe5\x9f\xe8\x02\x9e\xa8\x73\x28\x8d\x1c\x7b\xff\x70\xec\xf5\xf4\xc4\xfb\x74\x63\x2a\xed\x31\xc5\x77\xcc\xa5\x3c\xfe\x2d\x79\xc2\x96\x4f\xb0\x39\x1c\xd3\xb5\x18\xcb\x62\xbc\x27\x5a\x31\xeb\x03\x5e\x9f\xa0\x7b\x48\x6b\x58\x7b\x03\xf3\x39\xf1\x8a\x71\x22\x02\x9d\x71\x7a\xc0\x0b\x4f\x4a\x8e\xfe\x8b\xf7\xef\xc6\x22\xd6\x0f\x62\x1f\xb5\x7d\x3b\xbe\xb6\x67\x93\x4e\x58\x45\x63\x3f\x40\x67\xb6\xfe\xc2\xb4\x8b\x48\x22\x46\x3d\x2c\xfb\x09\x37\x92\x63\x11\x58\xf4\x41\x06\x16\xd2\x3b\x76\x03\x9b\x8c\x89\x32\x2b\x31\xb4\x2b\x37\x24\x1b\xa5\x09\x4c\x0c\xd2\x0a\x27\x81\xce\xb0\x8f\xbd\x54\x8f\xcd\xa4\xc4\x27\x0d\xdb\x54\xd8\x68\x06\xa4\x1b\x8b\x0c\x01\x1a\xa2\x16\x28\x78\xe1\x3d\xd1\xb2\x03\xbc\x9e\x49\x2f\x06\x86\x2c\x6d\xc8\x52\x54\xdf\x03\xe5\x44\x0b\x43\xf6\xc6\x98\xa5\x8c\x99\xef\x97\x2e\x64\xf2\xb7\x04\xca\xa5\xa1\x23\x23\x61\xfc\xee\x40\xa6\xba\x7e\xad\xb4\x82\xf5\x17\xbe\x59\x05\x2b\x29\x99\xb5\xf4\x69\x17\x43\xa1\xec\x2f\xe8\xf3\xa3\x97\xe7\x2f\xdc\x6a\xe3\x49\xe3\x17\x38\x92\x36\x7e\xa3\xf8\xc5\x36\xe4\xad\xef\x52\xcd\xe6\xc5\x26\xeb\xc6\x3a\xa3\xf9\xcd\x38\x75\x99\xac\x87\xdc\x90\x0d\x5e\xe3\xbb\x16\x97\x44\x26\x95\x0d\xd9\xa4\x17\xec\x89\xf9\xa4\x65\x45\x6d\xd7\xdf\x02\x2d\xd9\x8c\x57\x16\xf2\xca\x2a\xd7\x7c\xba\x86\x82\x03\xd2\x66\x7c\x17\x6f\xb9\x02\xd9\xb2\x75\x3b\x16\xb4\x93\x31\x6b\x40\xf6\x2c\xf5\x9d\x46\x25\xe3\xde\x35\xa3\x86\xca\xe8\x39\x66\xb2\xb2\xb4\xac\x33\xd3\x2e\xec\xfa\xd5\xc6\x2b\xf9\x43\xe3\x7a\xb1\x60\xb3\xc0\x08\xce\x3c\x8b\x25\xaa\xc8\x17\x3d\x1f\xb6\xc9\xe8\x50\x66\x62\x70\x30\xdf\xa2\x59\x64\x56\xf5\xc9\xd0\x1a\x23\x03\xee\xa3\x0d\x19\x97\x74\x46\x7b\x9d\x49\x06\xb4\xd9\x36\xbb\x40\xda\xe6\x8c\x15\x65\xcc\x97\xb3\xdd\x5f\x10\xf1\xc2\x02\xcc\xcc\xc7\xd4\x98\x12\x78\xf0\x6a\x8c\x38\xfd\x72\xcb\xb5\x9c\x23\xcc\x03\x94\x72\x9f\x0c\x92\x11\xdd\xfa\x64\x5d\x40\xb7\xe6\x0f\x0e\xf8\x64\xee\x9f\x34\xd0\x4c\xb9\x77\x0e\x41\x3e\x81\x62\x5d\x71\xbb\x90\x63\x1b\x8e\x42\x0a\xa6\x95\xac\xa5\x64\xb3\x4a\x46\xc9\x84\xc8\x90\xe4\xe6\xfa\x5f\x49\x62\xc1\xb5\x88\x5b\x66\x24\x8c\xbd\x8e\x87\xec\x1d\x44\x5f\xe4\xb4\xf4\xb7\xb6\x80\x97\x7c\xe7\xd9\xd7\xd3\x04\x29\x35\x67\x30\x17\x47\xaa\x60\xbd\x0b\xdf\xd0\x96\x32\x7e\x2b\x2b\xae\xc6\x8a\x93\x27\x61\x8a\x6f\x7b\x66\xea\x52\x9a\xe7\x9c\x6b\x2c\x97\xbd\xa9\xa6\x6d\xf1\x1f\x64\xc7\x9e\x1d\x89\xae\x7e\x73\x0d\xde\x30\x44\x1a\x45\x27\x87\x10\x63\x80\x7a\xa6\x30\x6b\xa2\x0f\x66\x1b\x43\xf1\xe5\xae\xab\x66\x87\x72\xd8\x47\x4c\xcd\xad\xca\x9f\x8e\x5d\x8c\x97\xe4\xe4\x8d\xcf\x19\xd4\xf6\x54\xc4\x70\x0d\x34\xa0\x9e\x9f\x7a\xbd\x09\x12\x91\x7a\x45\x77\x2e\x9e\xd9\xf2\xa1\xd6\x70\x67\xe1\xb2\x54\xb2\xf0\xe5\xb0\xb2\x32\x12\x45\xf0\x62\x6b\x23\xc9\x88\x6b\xfe\x0e\x26\x87\x48\x05\x13\xe4\xd9\x93\x85\x27\x2b\xb6\x30\xa8\x34\x43\xa6\x34\xee\x28\xd6\x77\x76\x16\x12\xb7\x1e\x77\xc1\xe9\x90\x2e\x4c\x29\x40\x92\x66\x7d\xa8\xd8\x81\x2a\x68\x56\xd9\xf0\x4c\xbd\x98\xdf\x31\xb2\x86\x68\xd1\x1b\x90\x9c\x9e\x04\xd9\xfb\x1f\xf9\x0d\x3b\xdd\xd2\x9e\x4f\x79\x46\x31\x55\x43\x61\xd5\xbd\x30\x46\x84\x27\xaa\x58\xa6\x16\x29\x8d\xd9\x96\xbe\x80\x0b\xc7\xa2\xf5\xfa\x07\x7c\xe2\x72\x9a\x82\xbb\xa3\xdc\x4b\x34\x2b\xac\xf0\xba\xe7\x43\x5b\x53\x31\x2f\x77\x44\x35\xd1\x15\xe8\x3b\x87\x6d\xcb\x4e\x6d\xd9\xf4\x3d\x25\xe4\xc0\xb4\x13\x7d\x8d\x3b\x31\x27\x5a\xbb\x1e\x01\x4c\x65\x11\x8d\xad\xf6\x60\x47\x2a\x43\x9a\xc1\x04\x66\x4a\x1d\x3f\x95\x45\x32\x35\x21\x73\xeb\x64\xca\x63\x8a\xa9\x86\x08\xb4\x91\x81\x8c\x88\x20\x75\x01\x65\x4c\xbb\xb3\x16\x3b\x9f\x6e\x6a\x61\xca\x9c\x24\xc6\x10\xc0\x6b\x93\x0c\xe7\xf0\x4d\x75\xe7\xe2\x5e\x5b\xfa\x56\xad\x7c\xb6\xb5\x7f\xb2\xb1\x79\x0a\xe4\xe4\x1b\x7f\x21\xba\xba\x86\x06\xa3\xca\xb7\x2d\xfa\x02\x12\x7a\x5b\x88\xec\xe5\x78\x5b\xac\x59\xff\x3b\xd1\x3b\x24\xf9\x9e\x1e\x65\xe1\xc3\x14\x85\x86\x59\x1d\x51\xf5\x73\x6f\x51\x55\x1d\x87\x7b\x0b\x8f\xc6\x32\x74\xf8\x0a\x0b\x75\xc4\x27\x8f\x44\x1a\xe3\xbc\xf7\x76\xae\x30\x3b\x97\x93\x34\xfe\x89\xee\x4a\x0b\x0b\x54\xc6\x4a\x96\x3e\xdb\xab\x7f\xb2\xf6\x4f\xf6\xbe\xd2\xb3\x6f\xff\xc5\xf5\x34\x48\x1c\x5b\x90\x8c\x30\x0d\xd1\x9d\x2d\xb8\xf5\xba\xa7\x6c\xdf\x8b\x9f\xda\x5a\x9a\x95\xa5\xbb\xad\xc2\x9b\xd9\x82\xf6\x88\x64\xed\x9f\xec\x59\xf9\x2d\x27\x2e\x8e\xee\x94\x6d\x28\x44\x09\x93\xc8\x62\x28\x10\xfb\x00\xaa\xd8\xf0\x9a\x95\xc5\x81\x56\xb5\x12\x0f\xed\x20\xbf\xcf\x30\x1e\x85\x1f\xf9\xc6\x77\xbd\x61\xa9\xd1\xf1\x2d\x10\x43\x06\x6a\x79\x6e\x06\xf2\xc6\xe2\x5b\xc4\xf1\x0a\x3f\x5d\x4b\x3e\x5d\xc9\x96\xe8\x86\xa4\x22\x7a\x33\x64\x42\xbd\x96\x61\x5e\x83\x6c\xf1\xbf\x67\x23\x72\xe1\xa8\xed\xa0\xb6\x04\x25\x43\xcc\xcd\x9e\xf5\x1d\xa0\x6a\x41\x8e\xec\xc8\x91\x19\x3e\x69\x95\xef\xa5\xd4\x78\xfc\x2b\x07\x19\x6e\xea\x2f\x74\x3b\xf0\xa4\x65\xe3\x2e\x36\x6e\x41\xb3\x7d\x81\xa9\x2d\x18\xef\x2c\xe8\x0b\x17\x54\x73\x82\xb4\x09\x66\xd6\x80\xd0\xab\xe0\x55\xa5\x44\xef\x40\x43\x1b\x4f\xf3\x91\x0b\x31\xb5\x5a\xf5\x24\x7a\x6b\x56\x70\x26\x33\x36\x05\xc9\xa5\xf2\x25\xc9\x84\x6f\x16\xdc\x78\x16\x3e\xca\x5a\x50\x77\x16\xbf\x29\xc5\xc2\x94\x62\xcc\x46\x89\x82\xea\x73\xa5\xad\x3d\x79\xef\xfa\x1b\x92\x7f\xfd\x93\x0b\x1b\x5a\x20\x64\x09\x34\x71\x95\xd8\x96\xfd\x41\xc3\xe6\xd2\xb6\xd2\xdc\x9e\x01\x89\xda\x41\x64\xbb\xf3\xa4\x60\x1e\x75\xda\x4a\x1f\x50\x7f\x30\x07\x28\x56\x12\x03\x53\xa5\x77\x64\x1f\x7e\x3b\x68\x2b\xa1\x84\x80\x34\xda\x04\x32\x81\x79\x45\x72\xcc\x70\x85\x40\x94\x3c\xfc\x2b\x65\x2f\x12\x8b\xcb\x59\x42\x4e\x3b\x5b\xc2\xb5\x04\xd2\xbd\x76\xc9\x75\x58\xfa\x4b\x17\x0f\x5c\xfa\x25\x83\x12\xa5\xf9\x23\xda\xd7\x96\x9a\xff\x81\x2b\x1b\xc9\x13\x96\xfd\x62\x1b\x8b\x9c\xd9\x2a\x16\xf5\xe8\xdf\x9e\xb3\xe9\x2d\xbd\xa6\xd2\x1c\x98\x41\x97\x24\xe0\x4b\x4e\xd4\xca\x27\xaf\xf8\xf6\x8a\x31\xeb\x92\x0a\xa2\xa4\xeb\x52\xd2\x65\xc7\xd6\x45\x9b\x19\xf7\xba\xa5\xc4\xcd\x75\x3c\xce\xcc\x7a\x46\x2c\x0f\x07\xfc\x3a\x21\x57\xff\xd2\x55\xdc\xd1\x89\x90\xb0\x8a\xa7\x3d\x1f\x60\x2e\x65\x69\x0e\xfd\xd9\x4d\xc9\x35\x5a\x72\x3d\x96\x8c\x28\x22\xc2\xf1\xdc\x43\xcc\x4d\x46\x07\x03\x92\xe4\x8c\x1c\x97\x8c\x33\x97\x7e\x0d\x96\x74\x5e\x80\xe2\xb6\xb9\xf4\x5e\x4b\x69\x5e\x0b\x66\xd3\x36\x0b\x7c\x52\xfb\x6c\x33\xeb\xa7\xf8\x2f\x44\x0b\xa2\x0b\xd1\xd5\x90\x39\x1a\x15\x37\xba\x15\x0f\xd2\x2a\xbb\x07\xf4\x82\x65\x5f\xf9\x2d\x93\x84\xe2\xa5\xc1\x15\x3b\x55\xc1\xb2\xf7\x34\x36\x6f\xc5\x8d\x30\xd0\x15\x17\x70\xc5\x1d\xcc\x23\x2d\xac\xb8\xe9\xe2\xc5\x54\xec\xd6\x23\x6f\x3d\x54\x22\x6d\x29\x0b\x6a\x10\x58\x02\x5a\x12\x5d\x81\xa2\x35\xab\xec\x2a\x83\x56\x11\x8f\x47\x2b\x9a\x0c\x41\xa6\xa8\x2b\x0a\x6f\x45\x3d\x00\xd4\xa2\x41\x6a\xe4\x1e\x29\x22\x38\xfd\xfd\x02\xb1\x12\x62\xea\xbf\xa2\x5a\xac\xc4\xb4\x5d\x0c\x59\x9a\x1e\xac\x01\x9d\x80\xf6\xac\xfd\xcd\xb7\x55\xaf\x2f\x08\x32\xdf\xb9\xa2\x09\xac\x44\x7b\xc4\x3e\x1f\x39\xba\x27\x66\xf8\xc9\x97\xce\xcc\x77\xe6\xd3\x0b\xd3\xd4\xcc\x55\xf4\x4e\x2b\x2c\x15\x24\x3f\xc2\xaf\x87\x0c\x56\x74\x5a\x2b\x2e\xa2\xca\x0d\x65\x10\xe9\x81\x27\xa9\x27\x23\x1b\xc9\x40\x26\xd4\x13\xd5\x6f\x3b\x6e\x3d\xa1\x74\xcd\x0e\x7c\xea\x4b\x8a\xe8\x81\xcd\xf9\x93\x57\xe7\x40\x66\x9e\xcc\x7d\x51\x8d\x7f\xc7\x8b\x8e\xee\x04\x33\xdf\xce\x8b\x3d\x89\x42\x25\x27\x4c\x28\xe3\x91\xea\xe2\xd1\x42\x5e\xb1\x17\xff\xf1\x2e\x21\x9e\xc7\x16\xfe\xc7\xef\x0f\xc1\xaf\x86\xc2\x7c\xbf\xd9\x3b\x1a\x68\xd6\xd7\xfe\xb2\x3b\x12\x03\xf2\x9c\xc6\x0d\xfc\xc5\x0f\xd6\x5f\x4e\x6c\x83\x0b\x91\x98\x58\x85\x3a\x66\x9c\xc1\x18\xd8\xa8\xa8\xa7\x2a\xaf\x97\x1e\x2d\x68\xf6\x27\x9f\xcc\x10\x68\x20\x5f\xb0\x11\x05\x07\xab\xa6\x6e\x01\xaa\x88\x82\xd1\x7c\xc2\x9d\xb2\x9e\x9e\xdb\x98\x06\x01\x19\x13\xa9\x15\x79\xf2\x07\xe3\x3c\xe8\x51\x3f\xaa\xb6\xfb\x24\x39\xc9\x23\xba\x5a\xeb\x26\xc5\x5e\x8b\x67\x71\x35\x22\xa2\x40\x7a\x27\xa6\xf6\x3e\x7d\xcd\x55\x50\x8b\xb2\xd2\xb4\x02\xfd\x78\xe2\x21\x49\x2d\xa4\x62\x86\x1a\xe1\x87\xda\x5f\xf4\xa8\xbd\x2e\x7a\xb2\x53\x95\x48\x56\xc8\xa3\x1a\xa8\x66\x64\xaa\xe6\xb5\x0b\x04\xe9\xb4\xbe\x3d\xcc\x50\x2d\xb2\x71\xc3\xca\x9f\xbc\x5e\x78\x92\x6d\xe8\x77\x28\xaa\x5a\x86\x4e\xbb\x7d\x64\xda\x07\xb4\x69\xcd\xf9\x7f\xe2\xba\xab\xc5\x8b\xd6\xfa\x2e\xd6\x39\x0b\x05\xd7\x3c\x81\xac\x65\xfd\xa2\xd5\xb8\xbf\x24\xce\x4c\x1d\x2c\xa4\x6c\x67\x6a\x59\x2e\x72\x99\xc5\x5e\xc8\x5c\x9f\xcd\x5c\xd6\xfe\x16\x62\xad\xae\xa4\xbc\x30\xf3\xfe\xfb\xcc\x3c\xc3\x96\x44\x9d\xc1\x28\x90\x33\x7f\x1c\x37\xe3\xc1\xca\xcc\xbc\xb8\x31\x5f\xc8\xb8\x6f\x9f\x21\x16\x4e\x94\x12\xe1\x84\x34\x65\xb6\x29\x51\xc1\x72\x6b\x56\xac\xda\x05\x68\x0a\xf4\x42\xfb\x37\x33\x0d\xa3\xc6\xff\xab\xf0\xf8\x24\x96\xfd\x42\x17\x70\xa6\x07\x72\xb2\xcc\x21\xb0\x33\x31\x66\x7f\xf3\xcd\x96\x61\x37\x90\x6f\xbe\x98\x1f\xfe\xc9\x3b\xd1\xc9\x25\x9b\x5a\x07\x19\xb1\x5e\xbd\x6f\x37\x13\xd1\xd3\x57\xf7\x50\x4e\x33\x89\xf2\x66\x40\x9f\xd8\xc4\xcd\x28\x28\x33\xda\x95\x19\x97\xc0\xcc\xdf\x96\x9b\x49\x35\xc7\x1e\x66\x1c\xb1\x0e\x24\x17\x56\x82\x06\x81\x22\x19\x13\x65\x50\xb2\x20\xf1\x3d\x15\x04\x94\x78\xcf\xe4\xd2\x17\x12\x34\x2c\x49\xed\x9f\xcc\x3c\xf9\x9b\xa8\xf1\x35\x44\x73\x31\xf3\xb1\xa1\x99\x8f\x0d\x81\x68\xb4\x0d\x64\x6b\x63\x1d\xc8\x0f\xbc\x83\x56\x9e\x88\xfe\x75\x6f\xab\x1c\x22\x4a\xe4\x8e\x2b\x90\x94\xb8\xd2\x6c\x9b\x09\x92\xfa\x32\x54\xfe\xbf\xc2\xed\x23\x1a\x51\xf8\x66\x7e\x2f\x06\x12\x9a\x3c\xe7\x6c\xcc\x4d\xff\xde\x61\x06\xc1\xb7\x3d\xbd\xbc\xaa\xc7\xa0\xf1\x8c\x62\xce\xc3\x11\xa0\x7b\x22\x35\x7c\x20\xcf\x9e\xac\x3d\x79\x37\x24\xdd\x26\x19\x01\xc5\x2b\x46\x73\xc6\xba\xe6\xbc\xc9\x31\xe7\x8d\xa1\x39\x57\xe6\xdc\x42\x23\x9a\xf5\x81\x59\x2b\x98\xa0\x39\xa7\x7d\x4e\x23\x31\x97\xbf\xdb\x1e\x63\x2a\xec\x7c\xcb\x52\x5b\xdf\x80\x17\x6a\x14\x3c\xf9\xe2\x07\xe4\x05\x71\x5c\x92\xc2\x3f\x99\xf9\x32\x56\x40\x2b\xde\xfa\x03\xf9\x2f\x26\x6f\x2e\xab\x71\xc8\xb6\xac\x71\x70\x32\x17\xe7\xef\x13\xe8\x93\xd3\xf6\xc9\xa9\xbc\xb0\xf2\x8b\xbd\x1b\x3c\xba\xdc\x50\x58\x86\x43\x90\x3e\x33\x24\xf8\x0f\x22\x97\x56\xfb\x5f\x7b\x76\xa1\x46\xef\x81\xce\x79\xdc\x31\xf7\xf1\x85\xb9\x3f\x65\x07\x79\xf0\xa4\xb2\xf6\xc8\x2a\x63\x43\x7e\x59\x5b\x7f\x23\xaa\x40\x74\xb2\x61\x72\x31\xd4\x86\x1b\x18\x1c\x46\x0d\x98\x3c\xa0\xb2\x6e\x7c\x48\x01\x44\x4d\xc1\x33\xae\x9d\xa0\xfa\x86\x37\x4f\x80\x6e\x91\xe7\x97\x53\xea\x86\x91\x06\x20\xed\xd3\x73\xe7\x2e\x8c\x63\x35\x3f\xdb\x4d\x94\x58\xa0\x9e\x4d\x83\xcc\x7d\x0b\x1a\xdf\x85\x38\x00\x3c\x5f\x8b\x75\xbc\x32\x50\x88\x87\x6b\xff\xe6\xd6\x57\xb0\xf3\x65\xe8\x86\x01\x65\x1c\x7e\xab\xe0\xe8\xc9\x4f\xdf\xd1\x33\xd1\x45\x03\x81\xb2\x5c\x90\x74\x95\x79\xb8\x35\x2e\xca\x0a\xa8\xef\xca\x48\xfc\x98\x9a\x32\x02\xb9\x21\x1a\x31\x0c\x01\x3e\x26\xca\x59\x54\x0a\x01\x8d\x91\xcc\x46\xa6\xb1\x36\x14\xd3\x2c\xfa\xd5\x50\x1a\x81\xb6\x40\x19\x64\xaa\xb1\x73\x51\x2d\xbf\x60\x03\x0a\xdf\xe8\x92\x25\x54\x3c\x68\x7a\xd6\x6d\x81\x98\xb0\xc6\x7b\x88\x8d\x39\x84\x39\xf9\x1c\x9f\xda\xf4\xf4\x43\x18\xfb\xae\xa5\xa1\x49\x69\xa4\xc0\x8a\xf5\xe8\x86\xb6\xc1\x15\x7d\x8c\xf8\xb3\x79\x0f\x03\x92\xe8\x3d\x80\x17\x44\x15\x4f\xfd\x9e\xed\xf2\xaf\x16\xbd\x64\xab\x56\x7e\x18\xd7\x52\x4f\x03\xb2\xe1\x88\x7c\xe7\x20\xe0\x16\x82\xb6\x6a\x4f\x29\x3b\x31\xeb\x07\xcb\xfa\x64\xf7\x2e\xd0\xfc\x0d\x55\xce\xb3\x28\x1a\xe4\x13\x57\xc3\xca\x0f\xa4\xee\xf9\x0f\x5e\x1a\xee\x51\x1a\x5c\x9c\xb7\x2e\x24\x6c\xb5\x1d\xd0\x35\x7a\xef\x57\x76\xb5\x30\x46\x96\x1a\xc5\x3c\xa1\x7c\x24\x63\xa8\xd8\xc6\x89\x49\x02\x0b\xa6\xc9\xd1\x2b\x6d\x64\x1e\xff\x60\xce\x67\xf3\x51\xb4\x61\x05\x5b\x55\x70\x5f\xdb\xd0\x47\x69\x18\x62\x6d\x54\x19\xba\x0c\xf7\x44\xa5\x4f\xa6\x0a\x79\x67\x75\x33\x5f\xc9\xdc\x44\xc6\x9d\x17\x3f\x33\xdc\xd3\x78\x67\xa4\xf1\xce\x08\xf2\xac\x99\xbc\x31\x41\x86\x5b\xe2\x3a\x44\xb5\x91\xc8\x67\x03\x2e\xdb\xa7\x7f\x72\x71\xef\x98\xdb\xf8\x6c\x8e\x44\x4b\x92\x11\x85\x66\x2f\xa8\xac\x17\xdc\xf3\x2d\x28\x07\x0b\x3b\xbf\xd6\x0c\x43\x66\x18\x33\x6d\x0c\xad\xb1\xf0\xa7\x57\x0b\xee\xd5\x17\x76\xce\xfd\x64\xc4\x92\x75\x71\x2f\x7c\xf9\x15\xab\xad\xbc\xb0\x2c\x38\xe4\x0b\x6a\xe9\x05\x07\x7b\xc1\x88\xeb\x42\xbf\xb1\x49\x34\x39\x1e\xfa\x2e\xb8\x81\x5b\x30\x70\xb4\xe0\x72\x12\x24\xbe\xcc\x82\xa3\xbd\xf0\x4a\x79\x81\xa0\x0d\xdd\x82\x05\xf7\x62\x0b\x19\xf7\x06\x48\x6f\xee\x00\xbd\x62\xa8\x17\xb6\xae\x5e\x7b\xfc\x22\xd0\x8e\x5b\x3e\x7a\x8c\x78\x5b\x57\x92\xd4\xab\xde\x85\xc9\x5e\x45\x82\x08\x35\x87\xd1\xbe\x55\x03\xba\xf6\x34\xca\x66\x77\x13\x17\xbf\x0e\x63\x58\x69\xda\x8e\xdc\xe6\xdf\x89\xed\x42\x9d\x58\xa9\xbb\xe5\x66\xbf\x35\x83\xb8\x00\x49\x99\x9c\xfa\x9b\x00\xad\x1e\x06\x4a\xcb\x5a\xdc\xd5\xef\xf9\xef\x06\x05\xd9\xc2\x6d\x79\x2d\xa4\xe5\x65\xe5\x16\x27\xdf\x86\x2c\xed\x9e\xaf\x47\x4b\xd3\x06\xf7\xcb\xda\xa9\xe1\x43\x41\x62\xf3\x5a\x09\x60\xf7\x99\x75\xcd\xb8\x7f\xcb\x73\xf7\x56\x56\xd9\x7f\x59\xdf\x8e\x19\x4e\xd0\x62\xf8\xa6\x31\x7e\xda\xd0\x52\x6b\xb6\x32\xc1\x59\xcf\x36\x68\x8d\x65\xb0\xef\x8c\x80\x90\xd5\x8e\x91\x5a\x19\xfd\x4f\xa2\xab\x35\x5f\x4f\x8a\x76\x24\xa1\x84\x25\xa3\x32\x40\x4b\xa2\x2b\x50\xfc\xb2\x6f\xc9\x89\x5a\x72\xe1\x2e\xd5\x43\x92\x9a\x97\x76\x51\x37\x27\xd1\x2b\x29\x4b\x1e\x9d\x2c\xfd\xc1\xcc\xd2\x7b\x40\x4b\x4a\xef\xd2\x3c\x9a\x98\x1c\x97\xc8\xd2\xbb\x2a\x20\x9f\x7c\xa2\xb1\xe8\x25\xef\xa3\x83\x64\x54\x86\x4b\x91\x86\xa0\x61\xbf\xe9\x29\x61\x5f\xcb\xf9\xe5\xa0\x06\xfc\x0e\xa8\xe6\x48\xcd\xf9\x74\xc1\x4d\xc7\xd2\x7b\x6d\x4b\x7f\xcc\xb2\x34\xe9\xc9\x50\x5d\xd8\x88\x33\xf9\xd3\xbd\x20\x6a\xe4\x9b\x68\x89\x31\x3c\x9d\x25\x55\x06\xd0\x2d\xeb\xda\xc9\x58\xdc\xf4\xec\x33\x57\x4d\x3e\xe1\xf2\x11\xc8\x11\xa1\xa1\x25\x8e\x47\x58\xce\x99\x63\x76\x61\x2d\x17\x19\x9c\x27\xce\xcd\x15\x01\x7a\x23\xc1\xfe\x62\x14\xcc\xe4\x2e\x45\xcb\xbf\x03\xe5\x88\x6f\x00\x35\x28\xe4\x9b\x37\x94\x4b\x7f\x00\xb2\xf4\x9b\x84\x25\x2d\xe4\x92\xbe\xe4\xd2\xdb\x4a\x90\x7b\x1b\x4a\xb7\x8b\x07\xa9\x88\xf4\xe8\xe0\x1b\x6d\xe1\xd2\x6c\x61\x2c\x9e\xd3\xef\x2e\x6d\x80\xfc\xcf\x46\xd3\xec\x1c\x4f\x20\x96\x66\xe0\xd8\x13\x0d\x04\x69\x17\xbe\xd9\x66\x5a\x95\xe8\x37\x1a\xbb\x57\x1a\x3b\x1c\x86\x4d\x90\x16\x6f\x61\xac\x7e\xbb\x85\x81\x87\xb7\x7c\x52\x19\x92\x83\xe7\x9e\x9e\x9e\x59\x89\xfa\x9d\xf1\x8a\xb7\x84\x57\x74\x87\x57\x74\x87\x57\x6c\xe7\x8a\xdf\x1a\xac\xec\x1a\xf1\x88\x44\xc5\x63\x85\xeb\x8e\x44\xf1\x4c\x18\x7c\xc9\x76\xe7\x38\xe9\x05\xd2\x23\xb9\x15\x55\xc0\x8a\xfa\x74\x05\x67\x1a\xa8\x64\x8b\x11\x91\x8e\xc3\x30\x67\x2d\x0d\xd3\x16\xbe\xf2\x5f\xae\xa9\x83\xe7\xcc\xd9\x32\x5c\x08\xb2\xf1\x39\x5f\x7d\x5b\x56\xb2\x74\x86\xe4\x6b\xb6\x77\xfd\x6b\xb2\x8d\xcd\x8e\x17\x9b\xe3\x55\xab\x57\x59\x68\xba\x37\x5f\xd1\x36\xaf\xa8\xb0\xa3\x31\x58\xe9\xc5\x59\x11\xc8\x15\xd5\xf4\xab\x0f\x59\xaf\x64\x55\xb1\x72\x15\xad\x16\xd9\x0a\x86\x6b\xd7\xfe\x02\xe0\xda\x7f\x0c\xb1\xf6\x47\xde\x20\x35\x91\xba\x10\x6b\xbf\xe5\x5c\x53\x50\xd6\x54\x60\x6b\xdc\xf9\x04\xd2\x30\xcf\x9a\x97\x71\x40\x4a\x2c\xf4\xb5\xac\x72\x68\x4e\x2d\xfb\x85\x6b\x6b\x0d\x55\x26\xeb\xf1\x0a\x8e\xea\x2a\x90\x0d\x8f\xfb\x84\x98\x29\x02\xd1\xae\xe9\x95\x98\x35\x75\xd8\x5a\x8f\x99\x45\x48\xd7\xd4\x5c\x40\x5a\xcb\xd5\xb2\x86\xb1\xbf\xb1\x12\x6c\x22\xd6\xf2\xe9\xcb\x1f\x40\x37\xd6\xd4\x80\xde\x89\x4e\x40\x13\xbe\x81\x2b\x3e\xef\x24\x7a\x7d\x7e\x23\xeb\x3a\x05\x1a\xf0\xe7\x15\x36\x3c\xa7\xdc\x70\x99\x6e\xb8\xfc\x36\x92\x6f\x09\xa4\x1b\xd0\x8d\x7d\xa6\x79\x25\xd1\x2b\x4c\x1b\xce\xc1\x86\x47\xc6\xdc\x01\x20\x55\x9d\xd7\x8d\xc5\x53\x77\x20\x0b\xef\x23\x09\x77\xa2\xb6\xe1\x4d\x00\xa0\x8c\x68\xca\x56\xc6\xd0\xd4\xc6\x7f\x00\xb2\x71\x1f\x80\xe4\xe4\xb5\xcf\x39\xf3\x05\x2e\x59\xe0\x9a\x79\xce\x2c\x4a\x43\x47\x1b\x6e\xf2\x36\x32\x3f\x18\x5d\xf3\x50\x2d\x77\xf2\xcb\xc7\x46\x1b\x9d\x17\xcb\x5c\x58\x45\xb6\xeb\xda\xd0\xa6\x6c\x7c\x30\x78\x63\x51\xa7\xf8\xe4\xc9\x5a\x96\xc4\x7b\x7f\x1b\xef\xa1\x6e\x68\x4c\x36\x7e\x63\xb5\xd1\x1d\x94\x0e\x84\xd8\x0f\xa2\x8b\x6b\x99\x08\xdc\xc6\xef\x90\x36\x3e\x22\xfb\x1d\x47\xe9\xd0\xed\xdf\xa9\x9f\xd5\xd2\xf3\x56\xc4\x77\x46\xa2\xbe\x8b\xd6\x53\xaf\xef\x3b\x0f\x98\xbe\x63\x45\x60\x8e\xbf\xe3\x47\x28\x80\x6e\xac\x44\x8d\xab\x69\xbc\x60\xcb\xe3\xb8\x2d\x97\xd5\x96\x71\x97\x2d\x2f\xff\x6e\xa5\xe6\x59\xcf\xae\x55\xeb\xb0\x6c\x79\x53\x05\xf7\xb6\xbe\x1a\x92\xd6\x6c\xe9\x35\x6d\xed\xc0\xac\x06\x99\x33\x4c\xb0\x65\xf0\x77\xcb\x0b\xb5\x5b\x93\xb0\x98\xac\xdf\x31\x6d\x19\xc4\x80\x77\x86\xa4\x13\x37\xc3\x5b\x2a\x8a\x2d\x5d\xaa\xad\x88\xdb\x48\xbc\xa3\x33\xc6\x63\xcb\xaf\x55\xb7\xfa\x91\xb8\x28\xa5\xad\xe8\x8e\x6b\x4f\x7f\x4b\x40\xdb\x12\x10\xbb\x9b\xe8\xcf\xa0\x6c\xa9\x3b\xb6\xf2\xfa\x03\x10\x9c\x9b\x11\xc9\xc8\x0a\x4e\xe2\x85\xef\xad\x85\xc8\x23\xb9\x25\x8a\xe5\xc4\xf7\xfc\x6c\xc9\xc5\x14\xa2\x7f\x88\xf4\x76\xe9\xd6\x6f\xc8\xb7\xce\x1f\x49\xc9\x55\xcb\xef\xb8\x39\xde\x49\x33\xff\x0b\xdb\xb6\xe3\x4d\xa6\x9d\x7d\x9e\x72\x05\x29\x64\xc4\x47\x24\xb5\x21\x99\xc6\x1d\xcf\x8e\x77\x8c\xe1\x0a\x12\x41\xd8\x59\x10\x28\x05\x59\xf0\xa2\xce\x8e\xa7\x5d\x3b\x5a\xd5\x1d\x6e\x38\x00\x7d\xb0\xd4\x4f\xa2\xf8\x3b\x2b\x3b\x5e\xa5\xdb\xd9\xaf\x01\x7c\x27\xd9\xc2\x28\xed\xfc\x3d\xf5\x9d\x7d\xca\x90\x81\x68\x88\x68\x47\x4d\xf1\x46\x57\x6d\xcf\x43\x8f\x37\xbd\x05\x23\x59\xdf\xb8\xeb\x79\xe3\xfd\x97\xbd\x8f\x0b\x83\xdc\x13\x55\x3e\xb9\x66\xd9\xd1\x22\xef\xbd\x45\x06\x59\xb0\xf8\x37\xf7\x82\xc5\x53\xf6\x74\x12\xf6\x74\xef\xf6\xb4\x2f\xf1\xd2\xc8\x9e\xd7\xc4\xf6\x74\xe2\x40\x62\x53\xf5\xc0\x69\x8f\xcb\x51\x86\xec\x69\x85\x8e\xbc\xd1\xa9\x90\x34\x2b\x52\x67\xfc\x87\x9e\xaa\xd8\x4b\x73\xa2\x86\x28\x06\x29\xf6\xfe\x42\xda\xde\x9f\x84\xee\xb9\x39\xda\x9b\x9b\x37\x22\xc9\xf9\xf6\x8b\x6f\x7e\xb4\x51\x7b\x6f\xa3\xf6\x5e\x83\xec\x4d\x69\xc4\x02\xa2\x47\xb9\x57\x1b\xe5\x72\xfe\xc3\x15\xb3\xf7\x3f\x4f\xb2\xe7\x1d\x7a\xa0\x77\x20\x31\xec\x22\xe5\x7b\x9c\x48\x63\xe9\xee\xa5\xc3\x13\xeb\x4f\x50\x22\x63\x2b\xc7\xf6\x10\x7b\x91\xde\x01\x11\xde\x33\xc5\xb2\xc7\x69\x4a\xd7\xff\xd3\x1a\x67\x3f\xd8\xb1\xa7\xad\x03\x1a\x7a\xc2\x91\x55\x57\x21\x27\x89\xa7\x72\x6f\xd0\x3a\x36\xe1\x89\xba\x6f\x7b\x6f\x5d\xf7\x7e\x2f\x05\xa2\x8a\xfa\x07\x6d\x21\x50\xcb\x0c\x4b\xdf\x90\x15\x3b\x14\x43\x89\x20\x3f\x88\x4e\xbe\xb1\xff\xe7\xc9\x27\x0f\x0e\xf7\xde\x6a\xee\x3b\x77\x63\x0d\x44\x35\xe9\x81\xf6\xeb\xc0\xd3\x9e\x03\x17\xca\x81\x63\x71\xe0\xf2\x38\x70\x79\x1c\xa8\x9c\x0f\xdc\xf7\x1c\x78\x4a\x77\x30\xe7\x37\x23\xd1\x82\x4a\x66\x2d\x65\xad\x9c\x58\xb0\xca\xe1\xbb\xfb\x6c\x31\xd6\xa0\x6b\xe9\x20\xeb\x66\x6c\x48\x64\xe8\x20\x8b\xe6\x0f\xd6\xf5\xcc\x12\x1b\x36\xb5\x85\x9b\x70\x30\xe9\xaf\x48\x2a\x66\x40\xad\x07\x56\xf9\x02\xc9\x3d\xf8\x2d\xd2\x3f\xf6\x03\x3d\x23\x92\x05\xab\x6b\xe9\x9b\x1c\x38\xaf\x07\x99\xd4\x7b\x88\xcd\xc1\xbc\xee\x96\xef\xac\x59\xdd\x96\x8d\xdd\x33\xed\x9d\xc3\x16\x83\x37\x07\xee\x99\x0e\xf6\x6b\x2d\x23\x12\x7d\xef\x6a\xb3\x60\x32\x00\xf4\x68\xdd\x0d\x2b\x67\x4a\x84\x5e\x5a\xdb\xdf\x2d\x8e\x89\xe1\xd4\x1f\x13\x59\x93\xa0\x41\x76\xbd\xe1\xe0\xad\xe5\x81\xdf\x73\x09\x72\x1b\x99\x03\x8d\xe8\x41\x96\x68\x44\x29\x51\x66\x28\x89\x95\x17\x4e\x06\xf5\x44\xb4\x25\x29\xac\xbf\xee\x46\xc2\xc1\xbb\xa3\xff\x70\xd5\x21\xf9\x87\x49\x98\x8b\xc7\x1f\x19\x4a\x3f\xea\xa1\xa7\xbc\x70\xf4\xdf\x74\x1c\xfd\xed\xa7\xff\xd9\xd7\x87\x19\x0b\x48\xb9\x81\x03\x39\x02\xe9\x3a\x3a\x52\xc1\x1c\x69\x70\x8e\xf4\x66\x8e\xb2\x7a\x1e\xd0\xaf\xa3\xfe\x52\x97\x05\xa2\x8e\x54\xd5\x47\xae\x9c\xa3\x2c\x9b\x2f\x40\x8f\x18\xde\x23\xae\x17\x01\xcd\x98\x6f\x06\x37\xe9\x48\x5f\xef\xa4\x47\x54\x42\x8e\x34\x36\x47\x1f\x7f\x3b\xf2\x84\xfe\xc8\x5f\xb0\x3a\x9a\xcd\x69\x49\x32\xa2\x82\x65\xbf\xf2\xbd\x15\xbb\xbe\x62\x15\x3b\x3e\xdd\xb3\x85\x07\x5f\xed\x4f\x66\xbd\x10\x5d\x0d\x99\x01\x38\xf2\x7c\xf4\x48\x91\x3d\x8a\x38\x16\x86\xb4\xea\x84\x63\x0d\x1f\x53\x9a\x7c\xd2\x53\x2e\x6d\xb2\x79\x92\xc7\xce\x9d\xaa\x9f\xec\xe0\x28\xe3\x13\x15\x28\x3c\x51\xe3\x86\x53\x06\x15\x9e\x9f\x3e\xca\xfb\xd3\x76\xb6\x03\x92\x8c\xe8\xce\xe7\x29\x7c\x51\x25\x91\xda\x93\x9f\xfe\xdc\x1b\x64\x4e\xa4\xc7\x9f\x3f\x3b\xf7\xab\x0b\x3f\xfd\x39\xf6\xcf\xce\x7e\x34\xe1\xa7\xf8\xa5\x13\x20\xdd\x68\x7c\xe8\x06\x5c\xe4\xec\x43\x37\xc5\xba\xf2\x91\xd3\xf6\x3f\x3f\xbd\x27\xfe\xf1\x9b\x59\xfc\xb0\x10\x63\xc5\x9c\xa5\xf5\xdb\xed\x05\x3f\x3a\xfb\x22\xeb\xcc\x21\x3b\xd3\x17\x84\xe1\xd2\xcd\xc9\xd9\x3e\xa0\xca\x49\x74\xf4\xcf\xfe\xa3\xa5\xb3\x7e\xa7\x64\x45\xc5\xef\x94\xce\x5c\x79\x67\xce\xc8\x99\x1d\x38\xfb\xd6\x7f\x72\x19\x9e\xb9\xe6\xce\xd4\x32\x67\x7a\x4d\x67\xce\xd4\x99\xee\xfb\x99\x87\xce\x67\x4a\xce\x99\x7a\xe8\xdc\xb9\xaf\x26\xcf\x5c\x94\x67\x5c\xff\x21\xd2\x3e\xea\x75\xec\x33\x4d\xd6\xbf\xf8\x59\x39\xdf\xa8\x5f\x3e\x37\x00\x2f\x89\x1a\xb6\x73\xc5\xfd\xce\x99\xf1\x9b\x33\x9d\x9f\x33\x9d\x76\xa0\x29\x11\x7b\xe0\xae\x43\x21\x6c\xb4\x81\x46\x8c\xdf\xfb\x00\xa9\x27\x7b\xe1\x71\xcd\x85\xb1\xc2\x0b\xbe\x56\x02\xd2\xe3\x8b\x8b\x18\xd8\x7e\x4f\xbf\x15\xb2\xf2\xbf\xf2\x0d\xb5\x89\x17\x44\x00\x81\xd6\xf0\xb4\x2f\xb2\x4b\x9f\x02\x6d\xf9\xae\x4a\xc2\x85\x91\xc1\x8b\x98\x8e\x3b\xa0\x21\x9f\x66\xfc\xac\xe0\xc2\x1f\x7e\x8c\x86\x33\xfe\xe0\xd9\x05\xba\x81\x28\xb3\x96\xbb\x4b\x36\x17\x8b\x7e\x87\x17\xae\xbc\x87\x71\xa5\xe1\xb8\x52\xfa\xae\xd4\x33\x57\x04\xa0\x0c\xc9\x54\x5d\x29\x5c\x57\x5a\xb2\xab\xfd\xe2\xc3\x00\xa4\xf6\x28\x96\x3a\x23\x7a\x61\x3b\x5a\x3a\x66\x57\x7f\x22\x77\xa5\x23\x72\xf5\x91\xd5\xab\x74\x61\x45\x84\x06\x96\xcc\x29\x5b\x75\xcb\xa9\x7a\xfb\xea\x77\xba\x57\xc6\xa3\xae\xdc\xdf\xc7\xa3\x8e\x2b\x2f\xdb\x5f\x7d\x70\xff\xca\xaf\x94\xae\x8c\x37\x5d\xdd\xe0\x4a\xfc\x40\x92\x03\xc2\x85\x23\xa0\x50\x93\x6e\x07\x06\x3d\xb7\x31\x50\x34\x24\xaa\x7a\xf6\x9d\x19\xbe\x94\x8c\x77\xf0\x03\xba\x63\x41\xa5\xed\x8d\x71\x2f\x3f\xfe\x7a\xaa\xf2\x37\xa0\x47\xfb\xcd\x46\xbd\xbe\xaf\x0d\xaa\x59\x79\x2d\x66\x47\xd1\xc9\x50\x10\xdf\x80\x66\xac\x62\xc6\x52\xb8\x8d\x0a\x84\x3f\x6e\x14\xc8\xce\x92\xc3\x30\x5e\x81\x86\x4c\xbb\xb1\x2f\xb6\x71\xdb\x4c\x55\x4b\x20\xd0\x60\x7a\x72\x9d\x78\x92\x7a\x32\xf4\x04\x4e\x95\xdd\x22\xb1\x19\x52\x0e\x39\x50\x52\x11\x41\x0b\x2b\x41\xf0\x04\x44\x5d\x3b\x25\x39\x8b\xba\x75\xbf\x60\x17\xf8\x83\xc8\x8e\xdc\x7d\x96\xd5\x10\xd0\x93\xbb\x78\x1d\xf8\x33\xcb\xbd\x58\x9a\xba\xa8\x7a\x87\x13\x97\x56\x95\xc0\x46\x2b\x81\xf7\xa1\x3f\x2c\xa9\xdf\xe3\xa0\xee\x84\x1f\xc5\xda\xa2\x0b\x49\x43\x3e\x44\x2c\x4b\x11\xce\xbc\x40\x62\xf4\x57\x7f\x12\x2a\xe3\xdb\xaf\xf6\xb6\xee\x3d\x13\xfc\xb0\x6b\x4e\x84\x13\xb0\x64\x60\x97\x1c\x92\x01\x45\x31\x8e\xf1\xc0\xb6\x41\x4a\x6a\x8f\xe8\x63\x46\x47\x3a\x19\x50\xaa\xe2\x8c\xf0\xfc\x37\x19\xd8\x6f\x05\x24\x03\xbb\x85\xa3\xe8\x87\x28\xbb\x64\x60\x3f\xdb\x9b\x0c\x4c\x19\x24\xb8\x64\x56\xb8\x66\xe8\x31\x78\x82\x0b\x64\x37\x5c\x77\xa9\xed\x0b\x14\xbd\x3b\x67\x20\x67\xea\x87\x21\xdd\x7c\x24\xa9\x59\xd4\x24\x75\xb7\xab\x12\xba\xd4\x09\x4d\x7c\x82\xef\x9d\xc7\x40\x0c\xe2\x05\xf2\x0d\x8d\x4d\xdd\x01\x55\x82\x26\x20\x83\x6a\x9c\x84\xbf\x49\xa8\x73\x37\x20\x8a\x69\x3c\x0c\x53\xfe\x48\x54\x13\xf1\x06\x4d\xbc\xb9\x19\x7f\x78\x34\x19\x9a\xe3\x90\xd8\x4f\x03\x5a\x45\xb9\xed\x2c\x02\x99\x32\xf9\xde\x37\xab\xe4\xab\x95\x6f\xc9\xdc\xa3\x1c\xe8\x85\xed\x5e\xb2\xac\x57\x9c\x9f\x31\x0f\xfc\xbd\x64\x68\x76\x3b\xa0\xd4\xca\x4a\x32\x0b\x58\x29\xd1\x59\x46\xe4\x2f\x05\xca\x2d\xec\xa2\xe4\x9e\x08\xd6\x5b\xc9\x73\x4f\x57\x6b\xc2\xcf\x69\xf4\x0b\x18\x45\xaa\xc7\x6f\x28\x90\x37\xec\xc1\x8d\x85\xe2\xe4\xaa\x2c\x2a\x1b\x51\xb2\x46\xee\xf7\x90\x94\xcc\x98\x3b\xb7\x1f\x88\x51\xa2\xc9\x53\xa6\xc1\x37\x0b\x68\xc6\xe2\xe6\x4c\x9b\xb3\xd4\x25\xdf\xd8\x1a\xb2\x81\x1a\xd9\xc1\xc9\xc4\x72\x9b\xee\x1d\xf1\xc7\x76\x48\xc6\x7c\xfb\x2f\xfd\x39\x16\xb1\x35\xe0\x6c\x4c\x32\x62\x51\x13\xeb\xaf\x29\x10\x1c\xca\x84\x61\x1e\xbb\xdb\x1f\xc9\xd8\xeb\x5f\x90\x47\x22\x55\x76\x63\xfb\x60\xa5\x10\x82\x0b\x44\xfa\x3b\x5d\xc9\xa4\x8b\x5f\x66\x28\xf9\x42\xa4\x83\x03\x82\x1f\x71\x8b\xd9\xb0\x81\x55\xf2\x49\x92\x41\x35\x4e\xf4\x47\x49\xb4\x00\xbd\x9e\x10\xc9\xd4\x93\xc2\xaa\x8f\xbb\x01\x25\x51\xdc\x27\xde\xee\x4f\x34\x42\x25\x24\xe3\x62\xcd\xec\xfa\xbb\x22\x7c\x53\xab\x64\xce\xdc\xb9\xf8\x6c\x2a\xe7\x2d\xd0\xa3\xcc\xd8\x4d\x4f\x25\xde\x54\x4e\x46\x61\xcd\x28\x0d\x99\x6d\x28\x13\xfe\x36\x52\x82\x5f\x37\xfa\x42\xf4\x83\xe8\xc4\xac\xd8\xcf\xe0\xc7\x7f\x45\x6f\xe0\x27\x87\xfa\x44\x88\xb2\x2b\xd1\xc5\x9f\x9b\xa3\x9d\xc8\x0f\xb3\xc8\x4f\x6a\x83\xd4\xee\x57\x88\x55\xeb\xa6\xbd\xf8\x31\xfa\xff\x07\x00\x00\xff\xff\xaa\x0a\xcc\xb8\xdf\x5e\x00\x00") func keysWordlistJapaneseTxtBytes() ([]byte, error) { return bindataRead( @@ -126,12 +126,12 @@ func keysWordlistJapaneseTxt() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/wordlist/japanese.txt", size: 24287, mode: os.FileMode(420), modTime: time.Unix(1497960590, 0)} + info := bindataFileInfo{name: "keys/wordlist/japanese.txt", size: 24287, mode: os.FileMode(420), modTime: time.Unix(1511602021, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _keysWordlistSpanishTxt = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x34\x5b\xbb\x76\xfc\x2e\xaf\xed\x79\x4b\x8c\x65\x8f\xe6\x00\xe2\x27\xc0\x2b\x99\xb7\x49\x99\x62\x8a\xff\x4a\x97\xd6\x2f\x76\xd6\xde\xe4\x2b\x46\x98\x3b\xe8\x2e\x60\xee\xaf\x2d\x26\x0b\x71\xdb\xad\x48\x0d\x71\x93\x67\x0c\x71\x53\xf1\x81\x52\x3b\xe3\xce\xb4\x12\xae\x42\x8f\x2f\x26\xea\x21\x6e\x53\x32\x32\xb3\x5b\x88\x29\x6e\xd1\x91\xec\x52\x34\x86\x98\x92\xb0\x38\xe9\xfd\x53\x43\x4c\xa2\x43\x90\xe4\x13\x95\x52\x31\x5a\x92\x36\xa2\x87\xfb\x2b\x29\x66\x4a\x39\x3a\xc7\xa8\xf7\x77\x88\xc9\x4e\x41\xc6\x38\xcc\xd0\x8b\x09\x81\xeb\x0b\xc9\x64\xe3\xb9\x2b\x13\x71\x8e\x31\x3b\x4a\x77\x65\xd3\xbd\xe8\x40\xed\x6e\x9c\x28\xee\xe6\xd8\xcc\x3e\x63\x8d\x48\x32\x1a\xdd\xdf\x2e\x16\xe2\x21\x89\x6d\x0e\xfd\x5b\xf2\xa1\x75\xe5\xbd\x70\x91\xa7\xe6\x10\x4f\x65\xa3\xd3\xea\xfd\x8e\x48\x3b\x86\x38\x6d\x95\xba\x9c\x2b\x55\x14\x4e\x34\x98\xbb\xa1\xef\xd4\xcc\x1c\x30\xfc\xb0\xd3\x00\xdd\x2d\x44\x75\x09\x51\x7b\x46\xbf\xa7\xec\x2e\x2f\xa4\x58\xe5\x73\x76\xa0\x2c\xc7\xe4\xf7\x57\xc5\x47\xd9\x9c\x05\x5e\x62\x88\x79\x8b\xe1\xfe\xca\xdb\x2c\x21\xe6\x14\xf3\x8e\xaa\x5d\x50\x23\x27\xdb\xc9\x13\x83\x66\xf1\xc1\x42\xc2\x43\x33\xb0\x4a\x2a\xe4\xd3\x76\xee\x34\x2b\x29\x9d\x75\x91\x25\xeb\x85\xf5\x67\xce\x52\xc8\x14\xb9\xdc\x6f\xd2\x37\x8f\x05\xe5\x85\xd2\x45\x15\x62\x31\x8f\xe9\x28\x9a\x05\x6b\xcf\x2f\x34\x2b\x71\xcb\x82\xa4\x0e\x26\xcd\x80\x84\x12\x1d\xfb\x2f\xb1\x13\xad\x65\xfb\x4b\x14\xc3\x14\x6e\xbd\x28\x5b\x68\x1f\x71\x0f\xb1\x18\xc6\x6a\x11\xe8\x2a\x2d\x63\x6d\x35\x3d\x08\x35\x56\xa6\x18\xb7\xee\x98\xb3\xee\xf7\x77\x0d\xb1\x92\x0b\xef\xaf\x7a\x4e\xf0\x68\xd5\x9c\x41\x87\xaa\x05\xb9\xfb\xdd\x43\xac\x8b\x68\x75\x08\x98\xa1\x0e\x3d\x27\xea\x86\x3d\x91\xcc\x98\x01\x49\x97\x3a\x6b\xc2\xac\xf7\x7f\x91\xcc\x76\xff\x27\x4f\x66\x2d\xc4\x16\x49\xf2\x16\x3d\x62\xfd\x4d\x06\xf7\xd1\xd0\xbe\x65\x4d\xac\x34\xa0\xb7\x99\x03\x0d\xcd\x3e\x91\x71\xa9\x3b\x28\xd1\xdc\x88\xd8\x36\xa5\x83\x42\x6d\x62\x9b\x4e\x82\x38\x66\x0c\x14\x8a\xfb\xcb\x37\x1d\x6e\xfc\xb0\x1c\xa2\x6f\x93\xac\xe7\xe9\x41\x22\x38\x24\xd9\x39\xa4\xef\x9a\x81\x10\xdf\x27\xdb\x0b\x10\xe1\x14\x31\x57\xe9\x21\x7a\xf9\x63\x5f\xaf\xf7\x37\xf2\x06\x52\x7b\x23\x20\x47\xb8\xcb\x09\xbc\xb9\xdb\x0b\x70\x82\x5f\xb8\x7c\x1f\xca\x75\x76\xfe\x30\x66\x5f\x0c\xd0\x93\x54\x88\x6a\x97\x73\x52\x8c\xbb\x30\xd7\x41\xbd\xfe\xc7\x5a\x5d\x33\x61\xa7\x58\x76\x10\xaf\x5b\xd9\xb8\xaf\xde\x04\x5b\xef\x63\xad\xbe\x8f\x95\x9b\xec\x37\x0b\x3b\x4c\x8e\x32\xe2\x93\xf0\xdf\x14\x24\x1e\xe2\x58\xc3\x0f\xc1\x40\x43\x81\x8b\x41\x8e\xbf\xbf\x86\x81\xe4\xc3\x23\x50\x33\xb8\x9f\x71\xff\xd6\x10\xe7\x1e\x5f\x80\xa0\xd4\x3c\x25\xc4\x89\x69\x67\x59\x43\xcd\x2e\xe4\xda\x39\xb0\xfe\x0b\xdc\x70\xc5\x9a\x04\x09\x16\x76\xe1\x4b\x72\xa6\x26\xb9\x64\xc1\x3e\x7c\xbe\x42\xbc\x96\x02\xb9\x14\xf8\xf8\xc4\xbc\x9f\x73\x8f\x80\xd8\xf0\x2b\x1e\x4b\xa0\x29\x23\x2f\xc3\x2c\xaf\xfb\x97\x9c\xf2\x9a\x07\x44\xf7\x35\x73\xd8\xe2\x16\x01\xcc\xc3\x16\xd3\x43\xc2\x16\x1f\x20\xda\x16\x35\x23\x03\xe1\xde\x62\x8e\xf5\x85\xb2\x9c\x30\xe5\x46\x35\xb0\xc5\xb2\xdd\xbf\x61\x8b\x35\x19\xe0\x8e\x06\x60\xd6\x2d\x3a\xc7\x74\x96\x7b\xd5\x17\x12\xb7\xb0\xdd\x5f\x3d\x61\xfb\x5b\xec\x63\x0d\xd4\x21\xce\x5b\x1c\x31\xb3\x78\x88\xaf\xc9\x41\xb8\x2d\x8e\x39\x38\xe8\x2f\xd6\x89\x7d\x6c\xb2\xdd\xdf\x80\x8a\xd9\x04\xd2\xb6\x49\x67\x45\xe7\xe7\xd0\x18\x36\x85\xd8\x6e\x2a\x35\x6c\x5a\x4f\x0b\x5b\x5e\x6b\xcc\x06\x52\x6e\x79\xf6\x18\x36\xc3\x6f\xd3\xca\xc4\xc2\x66\x09\x5f\x69\x15\xec\x04\x72\x22\x59\x25\x99\x00\xac\xb3\x59\x66\xff\x82\x4d\x5a\xdd\xe3\x8e\x04\xe2\x48\x1b\xb6\x59\xed\xf7\x97\x86\xcd\x1c\x48\x32\x07\x97\x6e\xd6\x39\x35\xa8\xb0\xd9\xb8\xdf\x35\x6c\xf7\xcf\x25\x9c\xe7\x15\x73\xd8\x3c\x5e\x16\x96\xdd\xdb\x5c\xd2\x23\x22\xb9\x24\x6c\x4e\x9d\xb2\xb9\x72\x0b\xae\x98\xdb\xb9\x58\xca\xd3\xe6\x06\x76\xd9\x9c\x43\x3b\x34\xff\xe6\xb3\xb3\x2d\x78\x7a\x9b\x49\x08\x41\xcd\x09\xb5\xb7\x4d\xf9\x0c\xdb\x3c\x16\xc5\xe6\x41\x42\xdc\xbf\x40\xd9\xd4\xe1\x68\x96\xd9\xd1\x37\x8e\x36\x3d\x13\x62\xeb\xb3\x83\x7f\xb6\x39\x22\x16\x30\x5f\xe8\x0b\x93\x8c\x25\xa6\xb8\x41\x5d\xa7\x48\xa4\x26\x18\xf1\x90\x62\x8a\xa8\xd9\xef\xaf\x4b\x1c\x1f\xc2\x3a\x7e\x1f\xf7\x77\x48\xf1\x7e\xef\x28\xd1\x02\x66\x4d\xf1\x89\xcc\x73\x8d\x9b\xf1\x83\x22\x47\x0a\xd5\x08\xfb\x43\xa8\xc0\x7a\x8a\x39\x0b\x60\x41\x9f\x6c\x6c\x76\xa1\x9e\x05\x65\x63\x8f\x22\x6b\x71\x45\x2b\x93\x66\x21\xdd\x5f\x35\x71\x09\x75\x57\x4c\x52\x25\xa3\x47\x3d\xa1\x15\x53\xac\x9a\x98\x1d\xc8\x40\x37\x02\xae\x25\xd9\x86\x9c\xf5\x90\x62\x8b\x2f\x40\x1d\x6b\xe1\x0d\x04\x48\x91\x1e\x40\x8a\x6d\x82\x84\x29\x12\x07\xbe\xb1\xf3\xfd\xe5\x49\x30\x9d\x43\x65\xa4\xe8\x27\xa1\x42\x66\x52\xf4\x8a\xee\xde\xfe\xea\xb8\x10\xe7\x77\x27\x48\x28\xe8\xc2\xf2\xde\x58\x34\xb8\xe5\x61\x9e\xd0\x15\xa4\x4b\x50\x37\x98\x62\xb2\xd3\xcb\x42\x92\xcd\x20\x5b\x49\xa0\xb4\x93\xec\x18\x40\x32\x70\x7e\x7f\x67\x81\xa9\x4f\x92\xe1\xfd\x20\x3f\xd9\x72\xe9\xa6\x24\x55\x41\x4f\xa9\x83\x7d\x1c\x48\xa1\xfb\x93\xc4\x49\x69\x59\xe5\x60\xf0\x24\x4e\x63\x9d\xee\xef\xde\x64\x0f\x49\xd8\xe9\x11\x49\xc5\x47\xcc\x92\x98\x2d\xed\xfe\x45\x4a\x5b\x9a\x1e\xb1\x11\x3a\x33\xca\x26\x0a\x77\x64\x59\x9b\xf4\xa0\xc0\xa6\x87\x61\xe4\xc7\xa4\xaa\x4d\x8f\xd9\x30\xa1\xa6\x4c\xac\xaa\x9c\x06\x98\x09\x59\x00\x1f\x32\xe9\x01\xdc\xeb\xb9\x50\xa9\x60\x09\x8a\x50\x52\x20\x5a\x2b\x86\xd2\xe6\xb0\x4c\x49\x9d\x15\x3e\xc9\x07\xda\xd9\x82\x0d\x26\x19\x2d\xd3\x39\x48\x39\x56\x00\x8c\x97\x63\x17\xc0\x0b\x50\xa9\xc3\x53\xe6\x24\xf9\x7e\x2f\xfe\x31\xe2\xd6\xfe\x5c\xd3\x64\xe9\x41\x0e\x5c\x2a\x26\x19\x66\xbc\x7f\x76\xb8\x20\x09\x86\x3b\xd9\xc1\xf6\x70\x47\x93\x3d\x04\x23\xda\x13\x9a\x22\xc1\x55\x48\xd0\x40\xc9\x32\xd9\xca\xb2\x9c\xca\x32\x78\x05\xc9\xf2\x1a\x32\xe7\x95\x2b\xac\x9a\x85\x85\x05\x5a\x15\x29\xc7\x2d\x4a\xca\xff\x94\x35\x65\x69\x40\x92\xd5\x1d\x2d\xaa\x70\x9e\x7a\xb2\xc8\x28\x21\x56\xfb\x5f\x29\xf9\xda\x40\x2f\x6b\x0a\xe8\x71\x89\xbf\x39\xf4\x37\x52\xa8\xdd\x64\xbe\xff\x15\x1b\xe7\x77\xe7\x38\x7d\xc1\x02\xd1\x31\x98\x76\xba\x9b\x62\x4c\x07\x2a\x5d\x22\x61\x5a\x99\xfb\x8d\x15\xba\x14\x36\x7d\x03\x2a\xe2\x87\xe4\xda\xd8\x5d\xbb\xf6\x90\x1c\x76\x37\xf9\xfd\xb3\x90\xee\xe0\x18\x56\x4f\x76\x9f\xaf\x90\x66\x24\xd3\xcf\x48\xbe\x98\x91\x9c\x39\x37\x02\x44\x18\x09\xb2\x0a\x3c\xcc\xa5\x2a\xe6\x62\x7f\xb8\xfa\x2c\xe4\x6a\xa7\x5c\x80\x0a\xef\x2f\x4d\x08\x0e\xb2\xb9\x11\xb2\x39\xdd\xe6\x34\xe1\x3a\xa2\x09\x36\x3f\x2b\xd7\x32\x8d\xb0\x2d\x2d\xf0\xdb\x28\x65\xf4\x5e\xd2\x74\xa5\xec\x4d\x5f\x90\x93\x0c\xed\x61\x87\x12\xdb\x69\x76\x31\xe5\x1e\x21\x78\x3b\xbc\x8e\x1c\x76\xd9\xc4\xc3\x7e\x7f\x6f\xc8\xdc\xdf\x29\xee\x31\xec\x92\xd4\xc3\x2e\x68\x26\x87\xd4\x8e\xa2\x43\x2b\x0b\x61\xc5\x77\xc9\x07\xd8\x69\x47\x70\xc4\x56\x19\x46\x6b\x97\x62\x8e\xb6\x70\xab\x76\xa9\x23\x62\x82\xe5\x45\xee\x02\x53\x84\x62\x77\xec\x61\x97\xbe\xbc\x8b\x5d\xe0\x76\xed\xd2\xe1\xe8\x23\xad\x93\x23\xf6\xa1\xab\xf6\xba\xdf\x48\x07\x55\xf4\x2e\x43\x2a\x56\x2c\xf0\x4f\x76\x10\x73\xd7\xb8\x65\x43\xb2\x83\xc2\xbb\xfe\xb9\xef\xbb\xc2\xd3\xd9\x35\x22\xb6\xd9\x75\x9b\x4f\x24\x0c\x99\xf6\x25\x66\xbb\x02\xa7\xbb\xca\x2b\xec\x7a\xdc\xef\x04\x1c\xe8\x89\x69\x35\xaf\xb1\xf2\xc4\xa6\xb5\x42\x3f\xed\xea\x82\x20\x6d\x57\xd7\x93\xc5\xd0\xa4\xbb\x76\x81\xda\xdd\xb5\x1f\x1e\x31\xd2\x85\x8e\x17\x57\x6f\x08\x27\x76\x4b\x00\xb0\x2a\xbb\x15\xba\x11\xbb\x55\xfc\xb0\x14\xa3\xe7\xbc\x9b\xc3\x5f\xdc\x0d\xc4\xdb\xad\xe3\x07\xd2\x79\x3c\x41\xea\xdd\xed\x8c\x61\xa7\x25\xd8\xb9\x73\x46\xb2\xfb\x5c\x53\xcf\x8c\x19\xee\x5f\x7c\x42\xcd\xed\xe4\x88\x7d\x52\xb7\xee\xb0\x44\xf7\xf7\x86\xc0\x43\x36\x20\x03\x3e\x81\x07\xa8\x51\x01\x47\x9b\x07\x81\x6e\x92\xfd\x2f\x90\x94\x5d\x11\x53\x1a\x3e\x06\x6b\x27\x6c\xb5\x1c\xdc\xbe\x1c\x9a\xe2\x2b\xc8\x53\xf0\x2b\x2d\x5b\x90\x2c\x07\x71\x2e\xd0\x26\x8e\x64\x29\x7e\xc9\x72\xa1\x67\xd6\xd6\x25\xdc\xdf\x59\xd9\x48\x3f\xd8\xc8\xa0\x79\x24\x33\x1e\x96\xb2\x81\xee\xb2\xe2\x5f\x29\xf6\xb7\x94\xd2\xa0\x73\xa4\x34\xee\x14\xd3\x09\x13\x97\x1e\x83\x54\x6e\xaa\x26\x06\x68\x52\xd3\x63\x1e\x82\x14\x7c\x21\x88\xa8\x58\x0c\xe2\x49\x3d\x80\x67\xa9\x87\x78\x41\x7a\xd2\xc1\x94\xaa\x67\x41\xdb\x1c\x13\x7a\x9a\x17\x24\x2e\x6c\xdb\xe3\x27\x13\xb9\xff\xc3\x2e\xea\x58\x23\x0d\x67\xee\x82\xe2\x96\x4a\xfe\xbc\xbf\x1b\x1c\x29\xf9\x37\xb5\x59\x10\xd7\x97\x05\xe9\xf0\x39\x90\xc0\x53\x91\x0e\xbd\xeb\x48\x5d\x37\xe5\x07\x77\xdc\x05\x51\x61\x90\x7e\x88\x33\x99\xe2\xec\xdd\x20\x8b\xd2\x1b\xb4\xa6\xf4\xc6\x3d\xf5\x66\x9d\xc9\xc4\xaa\xfb\xbf\x79\xbf\x03\xb4\x0a\x86\x03\x9e\x10\x8b\xa0\xf5\x98\x47\x0c\x32\x60\x14\x65\x88\x57\xac\x70\x40\xad\xc9\xa8\x98\xec\x62\x5c\x28\x57\xcc\x13\x7d\xaf\x45\xad\x8b\x67\x05\xf2\xc1\x63\x0b\xf9\x40\x6c\x1b\xe4\x83\xe7\x22\xf2\x91\xe0\x08\xc8\xc7\x6a\xf9\x41\x09\x90\x0f\x45\x70\x2b\x1f\x2b\x3c\xba\xbf\x3f\x94\x95\x8d\x76\x53\x3e\xfe\xc2\x49\xf9\x68\x06\xa1\x95\x8f\xe1\x52\x2c\x1c\xf7\xd7\xe6\x58\x0c\x3e\xa0\xc1\x8e\x98\x1e\xd8\xec\x71\x7f\x41\x06\x0f\xcc\xef\xe1\x88\xc0\xdb\x01\x3f\xee\x88\x70\x33\x0e\x3a\x87\x47\xcc\x9d\x10\x6b\x3d\xa0\xdb\x8e\x58\x34\x2b\x53\x63\x95\x47\xf0\xce\x11\xbd\xc4\xc4\x72\x37\x8c\xea\x1d\xdf\x5d\xc2\x11\x87\x9e\xf8\x9e\x9c\xe0\xe2\x64\x1f\xe1\x80\x0f\xe3\x16\x0e\x3a\xcd\x87\x64\x7d\x85\x43\x90\x77\x8c\x22\x08\xc5\x8e\xfb\xdb\xa1\x38\x0f\x71\x76\x93\x4e\x17\xfc\x50\x9e\x1c\x1c\x4a\x35\x7b\x28\x96\xa6\x50\xec\x87\xfe\x59\xed\x43\x39\xa8\xee\x18\x50\xe9\x2d\x1d\x2a\x19\x80\xcd\x68\x1b\x0e\x45\x28\x1a\x0e\x7d\x72\x80\x27\x9a\x02\x3f\x9a\x61\xc4\x0f\xec\x12\x3d\x32\xec\xce\xa1\x18\xb4\x02\x8d\x5a\x41\x0d\x68\xe8\x81\x72\x07\x4e\x72\x4c\x06\x88\xb8\xe7\xc8\x6b\x47\x50\x41\x47\x36\x96\x40\xb1\x1d\x19\x4a\xf1\xc8\xf7\x2f\x2a\x6c\xc3\x2e\xc1\xc6\x87\x9d\xb0\xc3\x87\x51\xf9\x1c\x06\x22\x1f\x96\xb3\x60\x78\xab\x3b\x20\x27\xe1\x89\xd0\x61\x3e\x88\x48\x73\x04\x56\x07\x38\xf4\x30\x34\xf5\x98\x22\x08\xe2\xeb\x2c\xea\xf0\x58\x41\x4c\x27\x0d\x3c\xce\x1d\x89\xdc\x6f\x47\x52\xd1\x10\x52\x7d\x38\x24\xea\x70\x6e\xc6\xb9\xfe\x09\xcf\xec\x98\xd4\xda\x94\x0f\x94\x81\x82\x13\x2e\xfd\x31\xeb\x1f\x8e\x27\x02\x91\x63\xfa\x5a\xf7\x24\xd9\x66\xc7\xd4\xf7\xef\xd8\xc0\x04\x73\x40\x1d\x9e\x31\xc1\x3f\x3b\xe3\x11\x7b\x38\x23\x1c\xb4\x13\x21\xfa\x19\x59\x9a\x57\xec\x78\x92\xdf\xce\x88\xf0\xec\x8c\xd0\xd6\xe7\x3a\xc7\x39\x23\x3c\x9b\x33\xc2\xce\x9d\xd1\xe3\x53\x90\xbc\x50\xd4\x97\x07\x75\x46\x0a\xe5\x19\x07\x5a\x5c\x9a\xe1\xd9\x9f\x52\xa0\xb5\x4f\x81\xaa\x3f\xa5\x86\xf3\xfe\xa6\x72\x3a\xa5\x2a\xe1\x90\x70\x8a\xc7\x95\xf3\xff\xe5\x21\x86\xa7\x74\x0c\xa5\x27\xf5\xec\xa9\xa5\xc6\x8e\x56\x0a\x5d\x74\x2a\x06\xc9\x60\x76\x0f\x67\x46\x10\x7a\x66\xc3\xee\x4f\xcb\xf8\x1d\x06\x08\xe1\x38\x2d\x37\x09\x27\xe2\xbd\xd3\xe0\x08\x9c\xe6\x60\xb1\x13\xd1\x65\x38\xc1\x1b\xa7\x0d\x41\x39\x88\x79\x3a\xe4\xf2\xf4\xfb\xeb\x80\x4f\x7d\x3a\x14\xee\xe9\x08\x24\x4e\x8f\xf0\x2e\x4e\x87\xe7\x7a\x3a\x6d\xe9\xb9\x42\xcc\xd3\xb5\xb1\x0c\xd5\x20\xe3\xe9\xd6\x0d\xa3\xdd\xbf\x68\x34\xa1\x51\x4e\x9f\x85\xb0\x59\x38\xe7\xda\xd6\x8c\x2b\xe3\x3b\xd6\x3e\x85\x6b\x9a\xa4\xc5\x64\x70\x73\x4e\xb5\x0a\xd8\xf9\x3d\xe2\x6a\xd1\xb9\xac\x49\x9c\x3f\x22\x5c\x9a\xc7\xfd\x05\x97\xe6\x11\xb7\xcc\x32\xb8\x82\x0f\xa8\x99\x40\x4d\xf3\x88\x79\x95\x17\x84\x9f\x8f\xe8\x20\xda\x23\xbe\xf0\x63\x9c\xf6\x90\x8d\xa7\x3a\x0f\xba\x67\x0f\xfa\x2e\x0f\xc9\xb0\x21\x0f\x81\x3c\x3c\xa4\xac\x1a\xf8\x7d\x0f\xf1\x82\x25\x3c\xee\x6f\x37\x41\xf6\x42\x29\x43\x89\x87\xc2\xe5\x09\x8f\xfb\x4d\x5f\xe9\xa1\xa7\x4a\x95\xf0\x80\x74\x3f\xb4\xa0\x97\x22\xfe\xd2\x18\x1e\x96\x80\xe5\x87\xc1\x17\x7f\x18\x10\x80\xc2\x27\x00\x7d\xc2\x87\xc1\x7b\x78\x58\x35\xd4\x57\xd6\x2e\x50\xa0\xd0\x1e\x3c\x2d\x7e\x18\xac\x40\x78\xd8\xa7\x85\xc7\x84\x99\x7f\x4c\x9e\x62\x3f\x26\x4f\x56\x1f\x44\xff\x63\xca\x05\x08\x2f\xfe\x01\x65\xf0\x98\x7f\x5b\xf8\x2d\xb0\x7e\x8f\x59\x34\xef\x82\x14\x99\xba\xb3\x89\x47\x44\xbc\xf8\x18\x16\x14\xbe\x7d\xd0\x5d\x62\x0e\xba\x2b\x78\x0a\xae\x76\xb6\xa0\x67\x96\xae\x11\xe9\xfd\x1b\xf4\x9c\x68\x91\xe5\x64\x32\x3b\x85\x55\x4b\x84\x0c\xac\x68\x5d\x0b\x4d\x8f\x96\xb6\xa0\xc0\x4f\xd1\xb2\xec\x86\x96\x36\xa1\xf3\xa1\xec\x10\x2a\xdf\xef\xba\x6b\x92\x00\xb7\x6c\x20\xa1\x22\xd5\x7a\xd0\x7a\x6b\x5d\xe2\xa4\x95\x3e\x8c\xd6\x42\x7f\x54\x6b\x99\x15\xb5\x15\x32\xa9\xb5\xd3\x99\xd1\xda\x07\x59\x4f\x61\xdc\x11\xc1\xdd\xef\x3a\xb4\xa0\x66\x00\x2b\x5a\xef\x5f\x60\x53\xeb\xa5\xb4\xa3\xea\x31\x28\x38\x5b\x7d\x9d\x49\x6a\xcf\x04\x08\xda\x9f\x71\x8b\xf9\x7e\x23\xc5\x16\x9f\xb1\xac\xc4\xe3\x86\x4a\xdf\x61\x2b\x9e\x64\xda\x27\x4f\xef\x9e\xf1\x55\x58\x26\x87\x84\xa7\xb8\x42\xb1\x3c\xb5\x42\xdd\x3f\xcd\x2b\x78\xf5\x69\x6e\x1b\x92\x4b\x6a\x78\xda\x67\x0c\xcf\x29\x88\xf8\x9f\x53\x2e\xe9\x48\x5e\xe1\x39\x4f\x7a\x72\xcf\x79\x1a\xc0\xe4\x08\x93\x28\x78\x4e\x44\xab\xcf\x59\x4f\xcc\x38\xeb\x2a\x02\xbe\x9f\xf7\x6f\x53\x84\x4c\x4f\x7a\x8c\x4f\x9e\xd0\x3e\xe7\x25\x55\x73\x78\xce\x17\xf8\xf0\xff\xe0\x51\xfc\x9f\x41\x33\xe6\xb8\xa9\x05\xe8\x19\x42\x47\xc9\x8e\xcf\x1d\x51\x53\xc8\xf1\x64\x60\x94\xef\xaf\xd3\x11\xc1\xe6\x78\xc2\x30\xe4\x08\xae\xce\x11\x71\x63\xbe\xbf\x0a\x64\x0d\x69\x8b\x1c\x81\x2d\x2a\x44\x33\xc7\x7a\x32\xa2\x5b\x87\x84\xf9\xfe\x6a\xfa\x0a\x99\xde\x5d\x8e\x88\x68\xf2\xfd\xd5\xc7\x1a\x7a\x30\x37\xe4\x03\xdf\xea\x21\xc7\xe9\x92\x43\x8e\xf0\x38\x73\x7c\x59\xc8\x60\xcc\x2c\x7f\x06\x18\x36\x50\x00\xe1\x5b\x64\xc1\x5a\xe4\xfc\xab\x39\x57\xc8\x95\xe5\x09\x11\xc8\x52\xcf\x19\x91\x60\x33\x70\xfe\x00\xd9\xd0\x1a\xa3\x27\x70\xf7\x2a\x18\x9c\x62\x60\x23\x72\x61\x84\x4f\x81\x0d\xca\xba\x41\xd6\x76\x7c\xb8\x85\xac\x09\x93\xde\xef\x1d\xd3\x2a\x82\x92\x80\x58\x1f\x8b\x84\xe0\x66\x3d\x85\xcd\xb0\xb3\xfb\x5d\xe0\x26\x67\x25\xf3\x64\x2d\x0d\xe8\xd6\x9a\x50\x06\xe3\x9b\xef\x77\x15\x74\xaa\x50\xd5\x48\x59\x0f\x3f\x8f\xdd\xff\x4d\x45\x2b\xe8\xc8\xcc\xb3\x6f\xb8\xdd\xce\x84\x23\xc1\x7b\xc8\x20\x16\x60\x21\xe4\x4e\x79\x06\x91\x33\xaf\x84\x72\x96\xba\x12\xa2\x33\x9b\xaf\xe4\xc2\x06\xf2\xbc\x34\x06\xda\x99\xfc\xe7\xa8\x67\x4b\xcc\xc0\x7d\xc9\xf7\xcf\x09\xf7\x2e\xdb\x89\x99\xa0\xba\x40\x46\x84\xd7\xd9\xe0\x01\x50\x56\x32\xa3\x99\x3c\x11\x6b\xe6\xc9\x39\xe1\x8d\x64\x72\xcc\xac\xd2\x43\x9e\x0d\x9f\x3c\x57\xcf\x13\x2b\x9c\xaf\x50\x62\x82\xa5\x29\x11\x1a\xb9\xc4\x1d\x1b\x2b\x71\x77\x01\x84\x6d\x2f\x51\xd8\xa3\xc4\x43\x51\x75\x2e\x88\x82\xfb\x8d\xfe\x19\xc1\x4e\x59\xf7\x4b\x85\xa7\xc5\x25\x66\x54\x97\xfb\x0b\x70\xe3\xf7\x1c\xa1\xf0\xac\xb7\x44\xe0\xbc\xc4\xca\xd0\xb7\xd0\xf4\x97\x58\x95\xbe\x77\x81\x47\xc3\x52\x36\xe9\x84\x1c\xf7\xfe\x0f\x8c\x5d\xe0\x81\x97\xfb\xeb\xdf\x54\xe6\xd0\xd4\x39\xa8\x0b\xf3\x87\x66\x24\xd0\x84\x25\xf2\xca\xa3\xdc\x5f\x5e\x8c\xa5\x94\xaa\x12\x7d\x48\x47\xf2\x42\xbf\xce\xf1\x3a\xcf\x03\x4b\xec\x7a\xa1\x70\x70\xe0\x41\x3f\xb5\xc4\xa1\xd8\x26\x2f\x1d\xcb\xfd\xf5\x01\x6d\x56\xe2\xa7\xa1\xc9\xcb\x3c\xc5\x50\xe8\x0e\x16\xd9\xd7\xee\x65\x57\x4c\xfb\xbd\x4f\xe6\x9e\xba\x4a\x9f\xe8\x21\xe0\x03\x24\x5c\x0a\x02\x7c\x4c\x81\x40\x09\xb0\xc3\xf5\x29\xf4\x53\x8a\xd4\xfb\x37\x14\xf1\x04\x95\x50\xe0\xbd\x9c\x53\x30\x2c\x3d\x80\x82\x2d\x48\x5f\xa3\x00\x41\x08\x4b\x50\x3b\x8c\xcd\x49\x31\x79\x25\xcc\xac\xb0\x3f\x05\x3a\xbd\xa8\xf0\xae\x85\xd6\xad\x00\x55\x9a\xe3\xc9\x82\x4c\x83\x51\x34\xaf\x95\x71\x93\xc4\xf1\x0a\xd6\xa1\x55\xff\xca\xc0\x39\x45\xad\x49\x28\xf4\x96\x8a\x02\x87\xda\x17\xb6\xb4\x73\xd8\xce\xb6\x90\xd8\xc2\xe5\x5a\x7a\xc0\x2d\xfa\x5f\x1c\x5a\x6c\x47\x66\x87\x41\x2f\x06\xce\x33\xd2\xdd\x60\x22\x8b\x65\xe1\x37\x04\xb1\xd8\x0a\x7d\x8b\x15\x0c\x8f\x20\x3f\x31\x15\x8e\x00\xf6\x2f\xb6\x1a\xc0\xa1\x29\x46\x0f\xab\x18\x6f\xc2\x8a\xd1\x0f\x06\x96\x99\x71\x7e\x77\xd6\x43\xd3\x14\xeb\x1c\xac\x33\x04\x2d\xc6\xeb\xcc\x42\xa1\x2c\xf7\xcf\x85\x9d\x18\xb8\x64\x52\x38\xe6\x8e\x46\x53\x10\x99\x14\x1e\x48\x96\x49\x8b\x59\x26\x44\x04\xd9\x13\x72\x33\x9f\xe8\x4f\xe2\xaf\x83\xd1\x32\x33\x21\x19\x7f\xde\xff\x09\x26\x9d\x8e\x05\x50\xc2\xee\xdf\x9e\x26\x30\x31\xbb\x10\x9e\xab\x50\xd9\xae\x67\x0b\xf5\xfe\x42\xe4\x57\xe3\x42\x1f\xec\x18\x72\x70\x0b\x6b\x5c\x61\x40\x8d\x60\xd0\x1a\x79\xe8\x5b\x63\x8f\x39\xd4\x38\x16\xc4\xb6\x6a\x1c\x9c\xb2\xde\x5f\xb3\x0b\xda\x5f\xac\xbc\x30\xc4\xc5\x63\xfb\x2a\xb0\x44\xf5\xfe\xe6\xa9\x4e\xa5\xe2\xaa\x72\x1a\x4b\x05\x7c\x52\xa9\xb7\x2b\xfc\x31\x64\x06\xc0\x1c\xac\xb8\xd8\xf8\x82\xfe\xa8\xbc\xe6\xa9\x90\xbe\xaa\xb2\x65\x94\xb0\xad\xde\xff\xc9\x8b\x09\xa6\x79\x8f\xd5\xe2\x92\x1c\xaa\x6d\x59\x5e\x31\x54\x83\x55\xa9\xf7\x0f\x99\xaf\x52\x3c\x2a\x83\xa3\xca\x73\xaf\x0a\x8f\xba\xda\xd0\xc4\x8a\x0b\xce\x47\xb5\x0b\xc4\xa8\xc6\x45\xcd\x4d\x42\x9d\x29\x86\x7a\xff\xa6\x2c\x28\xd9\xe9\x45\xf3\x20\xac\xd2\x07\xac\xb0\xf4\x80\xaf\x50\x27\xd1\xfb\x5b\xc0\xe5\x75\x0e\x4c\x68\xb1\x6b\x0f\xc6\x9b\x2b\xdb\xb4\x37\x24\x4f\xec\xc0\xe0\xa3\xda\x0a\x6b\x6d\xeb\xe2\xd8\xb5\x6d\xeb\x10\xcd\x36\x2c\x00\x01\x9f\x31\x4e\xb3\x74\x7f\x43\x91\x61\x4b\x50\x62\x06\xac\x10\x99\x96\x5c\x82\xa5\x11\x2f\x7c\x8f\xb9\x31\xcb\xd3\x4a\x4b\x3c\x44\x87\xe6\x07\xd3\x1a\x6d\x9b\x41\xa3\xd8\xae\xa0\x9b\xf1\x64\xc2\xd6\x39\xa2\x1d\x74\x41\x6d\x9d\x2f\xd9\xb1\xce\x68\x69\x27\x8c\xc7\xb4\x86\x68\xd0\x9e\x16\x2c\xc7\x60\x59\x20\x1c\x96\x0f\xa0\xcd\x32\xd8\x82\x57\x10\x3c\x98\xe6\x89\x9a\xe5\x0b\x44\xb1\xb2\x65\x3d\x2d\x18\x8c\xaf\xc1\x79\xb0\x86\x00\xd8\xda\x62\xc0\xfb\xa7\x01\x8f\xd6\xf8\x44\xc2\x96\x5f\xb9\xde\x58\xdc\x3f\x8d\x27\x23\xc6\x0b\x6d\x0b\xe6\x7f\x4c\xcb\x93\x39\x47\x92\xc3\xfd\xe3\x1b\xa2\x44\xaa\x4f\xc8\x2a\xaa\xe5\x19\x51\x71\x12\x67\x7e\xc2\x19\x34\x3f\x27\x68\x67\xbe\x8e\x18\xcd\xf5\x64\x5b\xea\x54\xc3\x36\xfd\xdf\x3a\x07\x36\xde\x51\x5b\x8f\x3c\xc5\xb4\x9e\x20\x5a\xd6\xe5\x85\xd1\x40\x0d\x8a\xa8\x0d\xaa\x09\x03\xcf\xda\xb5\x66\xbc\xc0\x02\xf7\xcf\x07\x37\xfe\x71\xbf\x4f\xe8\x0c\xfb\x5c\x13\xbe\xe0\x93\x37\x9e\xe0\x34\x9a\xc5\x16\x05\x73\x37\xc4\xe0\x35\x86\x06\x53\xd8\xe2\xfd\xee\x28\x7a\x46\x47\x2e\xf3\x8a\xad\xc5\x9c\x98\x83\x0e\x68\xf7\x57\xc6\x04\x8d\x97\x62\x2d\x66\x5b\x09\x88\xdd\x62\xc5\x2f\x66\xb4\xaa\xca\x4e\x95\x2e\x46\x8b\xf7\x7f\x3c\x9a\x6c\xb1\xdd\x5f\x80\x92\x01\xb9\xfd\x16\xff\xd1\x2d\x6d\x7c\x20\xd0\xa2\x33\x08\x6f\xd1\x65\x07\x54\x96\x19\xc6\xf4\x16\x39\x35\x70\xc5\xbc\xc7\x83\x79\xf6\xee\xec\x0d\xd5\xd3\xe2\xf2\xc3\x1a\xd8\xb7\x21\xe6\x0e\x2d\x2e\xa0\x28\xa0\x74\x34\x5e\x61\x35\x9e\x84\x34\x70\x70\x8b\x9f\x6c\x2f\x91\x57\xc7\x4d\x68\xb2\x1a\x58\x31\x22\x79\x20\xb3\x63\x77\x82\xa8\xa7\x51\xaf\x34\xd1\x2a\xa1\x49\xe6\x77\xde\x79\x7c\xd8\x24\x0b\xba\x64\x05\x07\x37\xc9\x59\x9e\x4c\x09\x20\xd4\x0d\xe6\xb3\x81\xf7\xd1\x6d\xdd\xfd\x35\x59\xd0\x50\xd4\x60\x34\x9a\xfc\x5b\x47\xb9\x6d\x2d\xc1\x61\x9f\x9b\xd0\x26\xb4\x75\x45\xd6\x84\xbe\x02\x22\xa3\xc4\x76\x99\x65\x45\xb9\x13\xe7\xf4\xde\x8d\xb3\x75\x02\xcc\x7e\x7f\x77\x58\xc1\x06\x8e\x83\x1f\xdb\xee\xef\x11\xb9\xba\xe1\xf7\x0f\xb4\x4d\x93\x17\x7e\x93\xb5\x3c\xae\x6b\x9a\x1e\x5c\xa0\x0a\x7e\x3b\x56\xa4\xf4\x2d\x9b\x72\x25\xfa\x84\xd7\xd8\x94\xa8\xd0\x6c\x60\x35\x2d\x4a\x9d\xb1\xb6\xa3\x15\x4e\x76\xd3\xca\xe6\x6b\x68\x08\x75\xd3\x86\x4f\x27\x8d\x94\x38\xd1\xce\x5b\xac\xc6\x7d\xd0\x5b\x6d\xba\xc8\xa2\x2f\xec\x20\xc7\x05\x2b\xc0\xe0\xe7\x27\x21\x86\xce\x02\x63\xdd\x32\x04\xa0\xd1\xc1\x6c\x79\x62\x6d\x99\xa6\xa3\xf1\xe2\xac\xc1\x35\x6d\x46\x5c\x52\x31\x35\x13\xb4\x31\xe9\x90\xbc\x66\x64\x77\xcb\x52\x01\x35\xad\x42\x48\x71\xb3\x0c\x76\xb1\x02\x2d\xd4\x8c\xa7\x37\x8d\xb3\x58\xc1\x46\xa8\x45\x9a\xf9\xd2\x17\x6d\xd9\xe8\x06\x91\x46\x65\x17\xd6\x76\x85\xfd\x6d\x06\x2d\xd8\x6c\xac\xd3\xde\x46\x81\x6e\x30\xd6\x8d\x17\x00\xcd\x25\xd9\x0b\xc9\x39\x89\x47\x97\xa2\x2c\x86\xda\x6c\x0e\xd5\xde\x5c\x2e\x96\x91\xa4\x7e\xbf\x6b\x82\x41\x6d\xae\x7f\x52\xe0\x0a\xf5\xde\xdc\xd0\x83\xaf\x74\x9a\x5b\x5a\x5d\x6d\x9f\xd4\x09\x6e\xa4\xa1\xdb\xc1\x87\x2e\xcd\xed\x74\x92\xd3\x0d\xcb\x74\x2b\x64\x1f\xa7\x8f\xd2\xdc\x1a\x67\x84\xb6\xe1\xa4\x53\x36\x70\xd1\xef\x96\xc9\x86\x33\x3d\x60\x5a\xda\x84\xa6\x6c\x70\x35\x90\xa1\x8e\xff\x53\xa7\x6d\xe6\x13\x99\x0c\x49\x9a\x99\x31\x4d\x9b\xb9\xb1\x06\x2b\x23\xbd\xf8\x4c\xa6\x81\x09\x33\x13\x64\x80\xe1\x09\x2e\x0b\x6d\xfa\xfd\x1d\xfe\x4d\x81\x17\xf1\x6f\x42\x0b\xfe\x9b\x52\x56\xc6\x85\x49\xb7\xf0\x6f\xd2\x6a\xc3\x31\x2f\xd0\xe8\x70\xba\x93\x20\x81\x9e\xf7\xfb\x8b\x77\x20\x1e\x37\x8d\x80\xf8\x5c\x94\xf3\xb8\x6b\x8a\x39\x38\x23\x04\xa2\xc3\x23\x28\xec\xeb\xbc\xcf\x11\x97\x06\xe7\xe1\x83\x23\x28\xdd\x99\x1b\x80\x9d\x35\x9d\x8d\x59\xf0\x09\xf0\x42\x96\x97\x9a\x2e\xff\x7b\x52\xe8\xf2\xf7\xda\xc0\x65\xbd\x6e\x71\xe1\x2b\x0e\x17\xbe\x62\x80\x29\x1c\x31\xf0\xc5\xc6\x0b\x95\xeb\x02\xd7\x25\xb9\x30\x3b\x08\x79\xbd\x07\x8d\xe9\xb2\xf3\x28\xd6\x65\x67\x0c\xe5\x72\x50\xfb\xb8\xac\xc3\x59\x97\xf5\x6a\xc7\xe5\x98\xa7\xa2\xfc\x84\xe4\x3b\x6f\x68\x5c\xce\x8c\x26\x27\x19\xcb\xe5\x71\x7f\xa3\x25\x84\x77\x1d\xc8\xd2\xb8\xb9\x64\xee\x49\xb2\x5c\x4c\x14\x6e\x88\x43\xcd\xb1\x61\xb6\x67\x70\xd2\xc1\x65\x45\x11\x3c\xdf\x77\xa9\x08\x77\x5d\x78\x68\xe4\xd4\x0b\x2e\x8d\x67\x03\x2e\x4d\x06\x4b\x9b\x71\xe6\x36\x34\x07\x97\x8e\x5f\x8a\x44\x47\x87\x42\x70\xe9\x4d\xd8\xa1\x2f\x38\x8b\x60\x89\x43\x1d\xd9\xc1\xa3\x2e\x47\xe4\xcd\xea\x59\x39\xe8\x75\x7f\x63\xa4\x8b\x8a\xc4\xe5\x33\x40\x77\x7a\xa0\xce\x74\xde\xef\xc3\x30\xef\x11\x09\x29\xa7\x47\x0c\x7e\xbf\x4f\x92\x54\x4f\x2c\x5b\x2b\x9f\x26\xb9\x2e\x6d\xcd\xd3\x68\xd7\x7f\x13\x72\xc3\x47\x33\xae\x03\xbb\x84\xea\xe1\x45\x8f\xf3\x9a\x0f\x92\x06\x00\xff\xc7\x6d\x5f\x10\x94\xb3\xf5\xba\xcd\x0d\xd4\xb4\xe7\xea\x01\x42\x19\x7d\x38\xb7\xd2\x58\x53\xf1\xc3\x3a\xe9\xc4\xb8\x35\x82\xd5\x04\xb3\xd2\xf7\x77\x63\x70\xeb\x7c\x0a\xe8\x73\xbb\xdf\x80\x58\x36\xbc\x45\x87\x88\x04\x9f\x24\x31\x4f\x01\x9c\x81\xa7\x2f\xbf\xde\xe1\x38\xf8\x44\x84\xeb\xb3\xb0\x53\xe3\x2b\x48\x9e\xb2\xfb\x1c\x68\xdb\x21\x27\xbb\x85\xce\x73\xd4\xce\x23\x9f\xce\xdb\x8d\x1e\x61\x1e\x7a\x3c\xe3\x0b\xd0\x57\xab\x1c\x01\xd6\x27\x16\xdb\x23\x44\xbd\xc7\x25\xea\x3d\xe6\xbf\xa4\xb3\xdd\x60\x83\xb9\x03\x5e\x1c\xad\x6c\xa8\xf8\x3b\xc1\xef\xb1\xd2\x1d\xea\xb1\x0a\x6b\x2b\x22\x94\x1e\x2b\x05\x87\xc7\xbc\x9d\x87\x15\x3d\x36\x00\xf8\x07\x3d\xfa\xce\x85\x47\x1f\x60\xe3\x1e\xfb\x60\x27\x3e\xa7\xe9\xbc\xe4\xe9\xf1\xc3\xf8\x3c\xa9\xff\xef\x38\xa8\x4b\x32\x00\xb0\x12\xd2\x11\x43\x97\x3d\x74\x39\x27\x96\x2f\xda\x43\xe7\x25\x7e\x97\x7c\xa1\xae\x20\x9e\xef\x52\x48\xcc\x4e\x26\xea\x52\xa1\x43\x79\x3f\x98\x99\x30\xb7\xfc\x9b\x2e\x4d\xd1\xe4\x1f\xcf\xaf\x3b\x70\x29\xae\x02\xb8\x30\xb3\x0e\x89\xbb\x74\x0a\x48\xff\x3b\x52\xea\xc2\xcc\xf8\x2b\xbc\x88\x52\xf9\x20\xc0\x4a\x15\xf6\xb8\xaf\xeb\xa2\xae\x70\xa7\xba\x9e\x58\x26\x2f\xae\xfb\xfd\xce\x11\x08\xd5\x0c\xf5\xdf\x35\x0b\x5f\x82\xf6\xb5\xea\xfb\x5d\x36\x63\xe3\xc2\x42\x87\x77\xd2\xb5\x0f\x18\xc4\xce\xe3\xa1\xae\x7c\xa6\xdc\x69\x3a\x3b\xbd\xff\x4e\xab\xd9\x2d\xe3\x17\x5b\x44\xb2\x93\xf8\x96\x79\x73\xdc\xef\x1f\xfa\x8a\xdd\x78\x29\xd7\x2d\xcf\x3f\x24\x1b\x0f\xc9\xbb\x55\x48\x42\xb7\xba\x5a\x55\x38\xc2\xdd\x2a\xa5\xa9\x1b\x47\x6c\x99\x3d\xd7\x6b\x81\xce\xab\x89\x6e\xbe\xee\x79\x3b\x0a\x91\xef\x8b\xc0\xf7\xcf\x20\x27\x4c\x04\x83\x7d\x6e\x40\xe3\xa4\x9d\xeb\x34\x44\x7d\xca\x89\x69\xe9\x89\xf6\xe5\x59\xf5\x15\xfa\xf6\x79\x38\x9b\x33\x3c\xea\x33\x2f\x26\xe1\x3d\x52\x9f\x70\xbf\x98\x92\x85\xe7\x32\xf0\x7d\x36\xaa\xb5\x3e\xf1\xed\x89\x5f\x7f\x63\xfa\xc9\x86\x9d\x63\x41\x93\x8d\xc8\x27\xea\x23\x6e\xd0\x18\x48\x73\x04\xbc\x7f\xc3\x58\x15\xd0\xe3\x7c\x0f\x3a\x22\xb6\x3c\xe8\x74\x8f\xb8\x4e\x1b\xd7\xeb\xc5\xb1\x84\x66\xc4\x42\x3b\x31\x62\x81\x84\x0f\x5a\xa1\x11\xeb\x1a\xb8\xa1\x5d\x03\x03\x8c\x08\x4e\x1b\xb1\xad\x4e\xff\xa6\xae\x41\x7c\x47\x9d\x0b\xbf\xa1\xe8\x46\xf4\x27\xd8\x6b\x44\xb7\x01\xe8\x18\xcf\x59\x32\x66\x7c\xa2\xf9\x64\xd9\x0b\x45\xb4\x5f\x43\xf8\xca\x65\xd0\x2d\x1e\x92\x30\xf2\xfd\x9d\xf8\x46\x66\xc8\x13\x6c\x30\xe4\x29\x0e\xa8\xcc\xa0\x85\xe4\xfb\xfb\x40\x24\x42\xce\x1a\x02\x65\x33\xd6\x63\x81\x21\x35\xbe\x00\x77\x76\xaa\x0b\x6a\x07\xec\xa8\x36\x5e\xbe\x21\x9c\xe0\xb6\x04\x18\x1f\xf7\xb7\xf3\xd9\xdd\x10\xaf\xd0\x58\x03\x2e\x2f\x7a\x76\xf6\xec\xc6\x35\xf6\x81\x20\x70\x08\x63\x91\x41\x81\x19\xf2\x0a\x43\xa1\xc4\x86\x6e\x93\x27\x6a\x43\xa5\x34\xe4\x29\xc4\x43\x79\xcd\x34\x14\xfc\x33\x14\xfa\x66\xe8\x93\x03\xf0\x02\x64\x28\xcf\x86\x07\x9c\x0a\xec\x0f\x7e\xd0\xe0\xa3\xaf\x01\xcb\x30\xee\x77\x83\x75\x19\xca\x21\xd9\xed\x6f\x16\xb2\xd6\xb8\xdf\x43\x56\xff\x01\xf5\x3b\x14\xb8\xb5\x45\x67\xdb\x18\xe9\x0f\x83\x62\x1d\x96\xb8\x43\xc3\x2c\x76\xa2\x3a\xf3\xb3\xb0\x92\x55\xe4\x11\x6b\x2c\x68\x12\x06\x5f\xb5\x8d\xfb\xc7\xe3\x47\x18\xc6\x30\x7f\x98\x17\x2a\x0f\x98\x48\x61\x9e\xa0\x09\x07\x73\xac\x85\xcf\x4c\x86\xf9\x98\x9c\xa6\xe3\x87\x3d\xf0\x6d\xd5\x80\xb3\x87\x9c\xc7\x8d\x7c\xea\xeb\x3e\x7e\xbd\x48\x1e\xff\xbb\x0b\x1c\x8e\x48\x72\xf0\xf6\x73\x78\x2c\xfc\x86\xbf\xb5\x4c\xf2\xf0\x08\xcf\x6e\x38\x5f\xdb\x0e\xbf\xbf\x37\xcb\x61\xc0\xbf\x45\xa9\x2c\x0c\xba\x54\x00\x6e\x08\x4e\xc0\x70\xdd\x26\x20\x87\x46\xb4\x30\x9c\xcf\xf8\x86\xeb\xac\x07\x0a\xed\x10\x26\x85\x95\xb4\x98\x83\xc6\x72\xf0\xe1\xea\x70\x38\xd5\xc3\x27\xcb\xf9\x4c\x75\xf8\x04\xf3\xcf\x6d\x5d\xeb\x8e\xb9\x59\x18\x93\x6f\x14\xc6\x84\xf9\x19\x34\x86\xe3\xfe\xad\x92\x99\x90\xb9\xa7\xf3\xf9\xe9\x98\xce\xd3\xc1\x31\xe1\x71\x0c\x3e\xaf\x9e\x1b\x23\xa5\xfb\x37\x33\x66\x9c\xd0\x72\x39\xcc\x65\xa5\xe8\x8a\xcc\xaa\x17\xe2\xb1\x30\x2b\x7e\x50\x8b\x0c\xb1\xa6\xd3\x09\x9d\xbe\x49\x98\xbe\xae\x7c\x27\x62\x2b\xfe\x0d\x64\xf6\xc9\xe7\x4a\xeb\xce\x69\x0e\xe3\xab\x8f\x79\xc5\x70\x21\x0c\xba\x62\x02\xcb\x5d\x91\x6f\xc2\x2e\x3e\xe4\xbf\x40\x85\x2b\x2a\x0b\xd6\xd1\xed\x15\xb3\x84\xeb\x2f\x7e\xbf\xf8\x6e\xea\xe2\xa3\x56\x94\x5d\x93\x2d\x4a\x83\x1f\x75\x45\x47\xc6\x95\x03\x91\x6d\x2f\x84\xc6\x97\x90\x15\xaf\x75\x59\x72\xc9\xe3\x7e\xf3\xc0\xef\x02\xd9\x24\x5c\xf2\x94\x57\xe0\x21\xd6\x25\x34\xfa\x97\x64\x43\x09\x56\x21\x7c\x11\x7b\x51\xb8\x2e\xa9\xc2\x81\x2a\xd7\x2a\x40\xcd\x45\xee\xbc\xa4\xce\x1e\x2e\xb6\xe4\xad\xf2\x25\xbe\x11\xee\x98\xc0\x85\xbd\xfd\x49\xc8\x25\xf9\x40\x63\x20\xe4\x52\x30\xdd\xa5\x1b\xb4\xf5\xc5\xa3\xa4\xeb\x7e\x27\x5e\x0c\x5d\x8a\x8e\xf7\x1b\x06\xe7\xd2\x1d\xd8\xbc\x14\x7e\x31\xef\xef\xa4\x87\x8b\x5e\xde\xa5\x19\x3f\xec\x40\x6b\x84\xd0\xf3\xc5\xd6\xa5\xf7\x7f\x90\x93\x4b\x2d\xdf\xef\x1a\x2e\x05\x61\x2f\x75\x20\x59\x7d\xcc\x3d\x5c\xda\x89\xca\x77\x67\xb0\xbe\x5c\xcd\x4b\x47\xe4\x09\xe0\xa5\x93\xdd\xaf\xf8\x02\x24\x6e\x14\x76\xfe\xd2\xcb\xc2\x65\x99\xf7\xa7\x97\x65\xba\xb3\x97\x65\x62\xc0\x1c\xcd\xe9\xd3\x5d\x08\xa7\x2f\x20\x93\xd6\xeb\x9a\x7c\x98\xf9\xc9\x0b\xec\x4f\xf8\xc7\x9f\x94\xa0\x4f\xe8\xd5\x4f\xde\x48\x7e\x42\x71\x7d\x42\x6b\x7c\x42\x6b\x7c\xda\x39\x3d\xbc\xe2\x01\x02\xbf\x78\xd4\xfa\x8a\x0d\x22\xf9\xe2\x1b\x85\x97\x55\x00\xe8\xfe\xd7\x2c\x00\xb0\xb5\xff\x1f\x00\x00\xff\xff\x11\x91\x1a\xde\x5b\x35\x00\x00") +var _keysWordlistSpanishTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x34\x5b\xbb\x76\xfc\x2e\xaf\xed\x79\x4b\x8c\x65\x8f\xe6\x00\xe2\x27\xc0\x2b\x99\xb7\x49\x99\x62\x8a\xff\x4a\x97\xd6\x2f\x76\xd6\xde\xe4\x2b\x46\x98\x3b\xe8\x2e\x60\xee\xaf\x2d\x26\x0b\x71\xdb\xad\x48\x0d\x71\x93\x67\x0c\x71\x53\xf1\x81\x52\x3b\xe3\xce\xb4\x12\xae\x42\x8f\x2f\x26\xea\x21\x6e\x53\x32\x32\xb3\x5b\x88\x29\x6e\xd1\x91\xec\x52\x34\x86\x98\x92\xb0\x38\xe9\xfd\x53\x43\x4c\xa2\x43\x90\xe4\x13\x95\x52\x31\x5a\x92\x36\xa2\x87\xfb\x2b\x29\x66\x4a\x39\x3a\xc7\xa8\xf7\x77\x88\xc9\x4e\x41\xc6\x38\xcc\xd0\x8b\x09\x81\xeb\x0b\xc9\x64\xe3\xb9\x2b\x13\x71\x8e\x31\x3b\x4a\x77\x65\xd3\xbd\xe8\x40\xed\x6e\x9c\x28\xee\xe6\xd8\xcc\x3e\x63\x8d\x48\x32\x1a\xdd\xdf\x2e\x16\xe2\x21\x89\x6d\x0e\xfd\x5b\xf2\xa1\x75\xe5\xbd\x70\x91\xa7\xe6\x10\x4f\x65\xa3\xd3\xea\xfd\x8e\x48\x3b\x86\x38\x6d\x95\xba\x9c\x2b\x55\x14\x4e\x34\x98\xbb\xa1\xef\xd4\xcc\x1c\x30\xfc\xb0\xd3\x00\xdd\x2d\x44\x75\x09\x51\x7b\x46\xbf\xa7\xec\x2e\x2f\xa4\x58\xe5\x73\x76\xa0\x2c\xc7\xe4\xf7\x57\xc5\x47\xd9\x9c\x05\x5e\x62\x88\x79\x8b\xe1\xfe\xca\xdb\x2c\x21\xe6\x14\xf3\x8e\xaa\x5d\x50\x23\x27\xdb\xc9\x13\x83\x66\xf1\xc1\x42\xc2\x43\x33\xb0\x4a\x2a\xe4\xd3\x76\xee\x34\x2b\x29\x9d\x75\x91\x25\xeb\x85\xf5\x67\xce\x52\xc8\x14\xb9\xdc\x6f\xd2\x37\x8f\x05\xe5\x85\xd2\x45\x15\x62\x31\x8f\xe9\x28\x9a\x05\x6b\xcf\x2f\x34\x2b\x71\xcb\x82\xa4\x0e\x26\xcd\x80\x84\x12\x1d\xfb\x2f\xb1\x13\xad\x65\xfb\x4b\x14\xc3\x14\x6e\xbd\x28\x5b\x68\x1f\x71\x0f\xb1\x18\xc6\x6a\x11\xe8\x2a\x2d\x63\x6d\x35\x3d\x08\x35\x56\xa6\x18\xb7\xee\x98\xb3\xee\xf7\x77\x0d\xb1\x92\x0b\xef\xaf\x7a\x4e\xf0\x68\xd5\x9c\x41\x87\xaa\x05\xb9\xfb\xdd\x43\xac\x8b\x68\x75\x08\x98\xa1\x0e\x3d\x27\xea\x86\x3d\x91\xcc\x98\x01\x49\x97\x3a\x6b\xc2\xac\xf7\x7f\x91\xcc\x76\xff\x27\x4f\x66\x2d\xc4\x16\x49\xf2\x16\x3d\x62\xfd\x4d\x06\xf7\xd1\xd0\xbe\x65\x4d\xac\x34\xa0\xb7\x99\x03\x0d\xcd\x3e\x91\x71\xa9\x3b\x28\xd1\xdc\x88\xd8\x36\xa5\x83\x42\x6d\x62\x9b\x4e\x82\x38\x66\x0c\x14\x8a\xfb\xcb\x37\x1d\x6e\xfc\xb0\x1c\xa2\x6f\x93\xac\xe7\xe9\x41\x22\x38\x24\xd9\x39\xa4\xef\x9a\x81\x10\xdf\x27\xdb\x0b\x10\xe1\x14\x31\x57\xe9\x21\x7a\xf9\x63\x5f\xaf\xf7\x37\xf2\x06\x52\x7b\x23\x20\x47\xb8\xcb\x09\xbc\xb9\xdb\x0b\x70\x82\x5f\xb8\x7c\x1f\xca\x75\x76\xfe\x30\x66\x5f\x0c\xd0\x93\x54\x88\x6a\x97\x73\x52\x8c\xbb\x30\xd7\x41\xbd\xfe\xc7\x5a\x5d\x33\x61\xa7\x58\x76\x10\xaf\x5b\xd9\xb8\xaf\xde\x04\x5b\xef\x63\xad\xbe\x8f\x95\x9b\xec\x37\x0b\x3b\x4c\x8e\x32\xe2\x93\xf0\xdf\x14\x24\x1e\xe2\x58\xc3\x0f\xc1\x40\x43\x81\x8b\x41\x8e\xbf\xbf\x86\x81\xe4\xc3\x23\x50\x33\xb8\x9f\x71\xff\xd6\x10\xe7\x1e\x5f\x80\xa0\xd4\x3c\x25\xc4\x89\x69\x67\x59\x43\xcd\x2e\xe4\xda\x39\xb0\xfe\x0b\xdc\x70\xc5\x9a\x04\x09\x16\x76\xe1\x4b\x72\xa6\x26\xb9\x64\xc1\x3e\x7c\xbe\x42\xbc\x96\x02\xb9\x14\xf8\xf8\xc4\xbc\x9f\x73\x8f\x80\xd8\xf0\x2b\x1e\x4b\xa0\x29\x23\x2f\xc3\x2c\xaf\xfb\x97\x9c\xf2\x9a\x07\x44\xf7\x35\x73\xd8\xe2\x16\x01\xcc\xc3\x16\xd3\x43\xc2\x16\x1f\x20\xda\x16\x35\x23\x03\xe1\xde\x62\x8e\xf5\x85\xb2\x9c\x30\xe5\x46\x35\xb0\xc5\xb2\xdd\xbf\x61\x8b\x35\x19\xe0\x8e\x06\x60\xd6\x2d\x3a\xc7\x74\x96\x7b\xd5\x17\x12\xb7\xb0\xdd\x5f\x3d\x61\xfb\x5b\xec\x63\x0d\xd4\x21\xce\x5b\x1c\x31\xb3\x78\x88\xaf\xc9\x41\xb8\x2d\x8e\x39\x38\xe8\x2f\xd6\x89\x7d\x6c\xb2\xdd\xdf\x80\x8a\xd9\x04\xd2\xb6\x49\x67\x45\xe7\xe7\xd0\x18\x36\x85\xd8\x6e\x2a\x35\x6c\x5a\x4f\x0b\x5b\x5e\x6b\xcc\x06\x52\x6e\x79\xf6\x18\x36\xc3\x6f\xd3\xca\xc4\xc2\x66\x09\x5f\x69\x15\xec\x04\x72\x22\x59\x25\x99\x00\xac\xb3\x59\x66\xff\x82\x4d\x5a\xdd\xe3\x8e\x04\xe2\x48\x1b\xb6\x59\xed\xf7\x97\x86\xcd\x1c\x48\x32\x07\x97\x6e\xd6\x39\x35\xa8\xb0\xd9\xb8\xdf\x35\x6c\xf7\xcf\x25\x9c\xe7\x15\x73\xd8\x3c\x5e\x16\x96\xdd\xdb\x5c\xd2\x23\x22\xb9\x24\x6c\x4e\x9d\xb2\xb9\x72\x0b\xae\x98\xdb\xb9\x58\xca\xd3\xe6\x06\x76\xd9\x9c\x43\x3b\x34\xff\xe6\xb3\xb3\x2d\x78\x7a\x9b\x49\x08\x41\xcd\x09\xb5\xb7\x4d\xf9\x0c\xdb\x3c\x16\xc5\xe6\x41\x42\xdc\xbf\x40\xd9\xd4\xe1\x68\x96\xd9\xd1\x37\x8e\x36\x3d\x13\x62\xeb\xb3\x83\x7f\xb6\x39\x22\x16\x30\x5f\xe8\x0b\x93\x8c\x25\xa6\xb8\x41\x5d\xa7\x48\xa4\x26\x18\xf1\x90\x62\x8a\xa8\xd9\xef\xaf\x4b\x1c\x1f\xc2\x3a\x7e\x1f\xf7\x77\x48\xf1\x7e\xef\x28\xd1\x02\x66\x4d\xf1\x89\xcc\x73\x8d\x9b\xf1\x83\x22\x47\x0a\xd5\x08\xfb\x43\xa8\xc0\x7a\x8a\x39\x0b\x60\x41\x9f\x6c\x6c\x76\xa1\x9e\x05\x65\x63\x8f\x22\x6b\x71\x45\x2b\x93\x66\x21\xdd\x5f\x35\x71\x09\x75\x57\x4c\x52\x25\xa3\x47\x3d\xa1\x15\x53\xac\x9a\x98\x1d\xc8\x40\x37\x02\xae\x25\xd9\x86\x9c\xf5\x90\x62\x8b\x2f\x40\x1d\x6b\xe1\x0d\x04\x48\x91\x1e\x40\x8a\x6d\x82\x84\x29\x12\x07\xbe\xb1\xf3\xfd\xe5\x49\x30\x9d\x43\x65\xa4\xe8\x27\xa1\x42\x66\x52\xf4\x8a\xee\xde\xfe\xea\xb8\x10\xe7\x77\x27\x48\x28\xe8\xc2\xf2\xde\x58\x34\xb8\xe5\x61\x9e\xd0\x15\xa4\x4b\x50\x37\x98\x62\xb2\xd3\xcb\x42\x92\xcd\x20\x5b\x49\xa0\xb4\x93\xec\x18\x40\x32\x70\x7e\x7f\x67\x81\xa9\x4f\x92\xe1\xfd\x20\x3f\xd9\x72\xe9\xa6\x24\x55\x41\x4f\xa9\x83\x7d\x1c\x48\xa1\xfb\x93\xc4\x49\x69\x59\xe5\x60\xf0\x24\x4e\x63\x9d\xee\xef\xde\x64\x0f\x49\xd8\xe9\x11\x49\xc5\x47\xcc\x92\x98\x2d\xed\xfe\x45\x4a\x5b\x9a\x1e\xb1\x11\x3a\x33\xca\x26\x0a\x77\x64\x59\x9b\xf4\xa0\xc0\xa6\x87\x61\xe4\xc7\xa4\xaa\x4d\x8f\xd9\x30\xa1\xa6\x4c\xac\xaa\x9c\x06\x98\x09\x59\x00\x1f\x32\xe9\x01\xdc\xeb\xb9\x50\xa9\x60\x09\x8a\x50\x52\x20\x5a\x2b\x86\xd2\xe6\xb0\x4c\x49\x9d\x15\x3e\xc9\x07\xda\xd9\x82\x0d\x26\x19\x2d\xd3\x39\x48\x39\x56\x00\x8c\x97\x63\x17\xc0\x0b\x50\xa9\xc3\x53\xe6\x24\xf9\x7e\x2f\xfe\x31\xe2\xd6\xfe\x5c\xd3\x64\xe9\x41\x0e\x5c\x2a\x26\x19\x66\xbc\x7f\x76\xb8\x20\x09\x86\x3b\xd9\xc1\xf6\x70\x47\x93\x3d\x04\x23\xda\x13\x9a\x22\xc1\x55\x48\xd0\x40\xc9\x32\xd9\xca\xb2\x9c\xca\x32\x78\x05\xc9\xf2\x1a\x32\xe7\x95\x2b\xac\x9a\x85\x85\x05\x5a\x15\x29\xc7\x2d\x4a\xca\xff\x94\x35\x65\x69\x40\x92\xd5\x1d\x2d\xaa\x70\x9e\x7a\xb2\xc8\x28\x21\x56\xfb\x5f\x29\xf9\xda\x40\x2f\x6b\x0a\xe8\x71\x89\xbf\x39\xf4\x37\x52\xa8\xdd\x64\xbe\xff\x15\x1b\xe7\x77\xe7\x38\x7d\xc1\x02\xd1\x31\x98\x76\xba\x9b\x62\x4c\x07\x2a\x5d\x22\x61\x5a\x99\xfb\x8d\x15\xba\x14\x36\x7d\x03\x2a\xe2\x87\xe4\xda\xd8\x5d\xbb\xf6\x90\x1c\x76\x37\xf9\xfd\xb3\x90\xee\xe0\x18\x56\x4f\x76\x9f\xaf\x90\x66\x24\xd3\xcf\x48\xbe\x98\x91\x9c\x39\x37\x02\x44\x18\x09\xb2\x0a\x3c\xcc\xa5\x2a\xe6\x62\x7f\xb8\xfa\x2c\xe4\x6a\xa7\x5c\x80\x0a\xef\x2f\x4d\x08\x0e\xb2\xb9\x11\xb2\x39\xdd\xe6\x34\xe1\x3a\xa2\x09\x36\x3f\x2b\xd7\x32\x8d\xb0\x2d\x2d\xf0\xdb\x28\x65\xf4\x5e\xd2\x74\xa5\xec\x4d\x5f\x90\x93\x0c\xed\x61\x87\x12\xdb\x69\x76\x31\xe5\x1e\x21\x78\x3b\xbc\x8e\x1c\x76\xd9\xc4\xc3\x7e\x7f\x6f\xc8\xdc\xdf\x29\xee\x31\xec\x92\xd4\xc3\x2e\x68\x26\x87\xd4\x8e\xa2\x43\x2b\x0b\x61\xc5\x77\xc9\x07\xd8\x69\x47\x70\xc4\x56\x19\x46\x6b\x97\x62\x8e\xb6\x70\xab\x76\xa9\x23\x62\x82\xe5\x45\xee\x02\x53\x84\x62\x77\xec\x61\x97\xbe\xbc\x8b\x5d\xe0\x76\xed\xd2\xe1\xe8\x23\xad\x93\x23\xf6\xa1\xab\xf6\xba\xdf\x48\x07\x55\xf4\x2e\x43\x2a\x56\x2c\xf0\x4f\x76\x10\x73\xd7\xb8\x65\x43\xb2\x83\xc2\xbb\xfe\xb9\xef\xbb\xc2\xd3\xd9\x35\x22\xb6\xd9\x75\x9b\x4f\x24\x0c\x99\xf6\x25\x66\xbb\x02\xa7\xbb\xca\x2b\xec\x7a\xdc\xef\x04\x1c\xe8\x89\x69\x35\xaf\xb1\xf2\xc4\xa6\xb5\x42\x3f\xed\xea\x82\x20\x6d\x57\xd7\x93\xc5\xd0\xa4\xbb\x76\x81\xda\xdd\xb5\x1f\x1e\x31\xd2\x85\x8e\x17\x57\x6f\x08\x27\x76\x4b\x00\xb0\x2a\xbb\x15\xba\x11\xbb\x55\xfc\xb0\x14\xa3\xe7\xbc\x9b\xc3\x5f\xdc\x0d\xc4\xdb\xad\xe3\x07\xd2\x79\x3c\x41\xea\xdd\xed\x8c\x61\xa7\x25\xd8\xb9\x73\x46\xb2\xfb\x5c\x53\xcf\x8c\x19\xee\x5f\x7c\x42\xcd\xed\xe4\x88\x7d\x52\xb7\xee\xb0\x44\xf7\xf7\x86\xc0\x43\x36\x20\x03\x3e\x81\x07\xa8\x51\x01\x47\x9b\x07\x81\x6e\x92\xfd\x2f\x90\x94\x5d\x11\x53\x1a\x3e\x06\x6b\x27\x6c\xb5\x1c\xdc\xbe\x1c\x9a\xe2\x2b\xc8\x53\xf0\x2b\x2d\x5b\x90\x2c\x07\x71\x2e\xd0\x26\x8e\x64\x29\x7e\xc9\x72\xa1\x67\xd6\xd6\x25\xdc\xdf\x59\xd9\x48\x3f\xd8\xc8\xa0\x79\x24\x33\x1e\x96\xb2\x81\xee\xb2\xe2\x5f\x29\xf6\xb7\x94\xd2\xa0\x73\xa4\x34\xee\x14\xd3\x09\x13\x97\x1e\x83\x54\x6e\xaa\x26\x06\x68\x52\xd3\x63\x1e\x82\x14\x7c\x21\x88\xa8\x58\x0c\xe2\x49\x3d\x80\x67\xa9\x87\x78\x41\x7a\xd2\xc1\x94\xaa\x67\x41\xdb\x1c\x13\x7a\x9a\x17\x24\x2e\x6c\xdb\xe3\x27\x13\xb9\xff\xc3\x2e\xea\x58\x23\x0d\x67\xee\x82\xe2\x96\x4a\xfe\xbc\xbf\x1b\x1c\x29\xf9\x37\xb5\x59\x10\xd7\x97\x05\xe9\xf0\x39\x90\xc0\x53\x91\x0e\xbd\xeb\x48\x5d\x37\xe5\x07\x77\xdc\x05\x51\x61\x90\x7e\x88\x33\x99\xe2\xec\xdd\x20\x8b\xd2\x1b\xb4\xa6\xf4\xc6\x3d\xf5\x66\x9d\xc9\xc4\xaa\xfb\xbf\x79\xbf\x03\xb4\x0a\x86\x03\x9e\x10\x8b\xa0\xf5\x98\x47\x0c\x32\x60\x14\x65\x88\x57\xac\x70\x40\xad\xc9\xa8\x98\xec\x62\x5c\x28\x57\xcc\x13\x7d\xaf\x45\xad\x8b\x67\x05\xf2\xc1\x63\x0b\xf9\x40\x6c\x1b\xe4\x83\xe7\x22\xf2\x91\xe0\x08\xc8\xc7\x6a\xf9\x41\x09\x90\x0f\x45\x70\x2b\x1f\x2b\x3c\xba\xbf\x3f\x94\x95\x8d\x76\x53\x3e\xfe\xc2\x49\xf9\x68\x06\xa1\x95\x8f\xe1\x52\x2c\x1c\xf7\xd7\xe6\x58\x0c\x3e\xa0\xc1\x8e\x98\x1e\xd8\xec\x71\x7f\x41\x06\x0f\xcc\xef\xe1\x88\xc0\xdb\x01\x3f\xee\x88\x70\x33\x0e\x3a\x87\x47\xcc\x9d\x10\x6b\x3d\xa0\xdb\x8e\x58\x34\x2b\x53\x63\x95\x47\xf0\xce\x11\xbd\xc4\xc4\x72\x37\x8c\xea\x1d\xdf\x5d\xc2\x11\x87\x9e\xf8\x9e\x9c\xe0\xe2\x64\x1f\xe1\x80\x0f\xe3\x16\x0e\x3a\xcd\x87\x64\x7d\x85\x43\x90\x77\x8c\x22\x08\xc5\x8e\xfb\xdb\xa1\x38\x0f\x71\x76\x93\x4e\x17\xfc\x50\x9e\x1c\x1c\x4a\x35\x7b\x28\x96\xa6\x50\xec\x87\xfe\x59\xed\x43\x39\xa8\xee\x18\x50\xe9\x2d\x1d\x2a\x19\x80\xcd\x68\x1b\x0e\x45\x28\x1a\x0e\x7d\x72\x80\x27\x9a\x02\x3f\x9a\x61\xc4\x0f\xec\x12\x3d\x32\xec\xce\xa1\x18\xb4\x02\x8d\x5a\x41\x0d\x68\xe8\x81\x72\x07\x4e\x72\x4c\x06\x88\xb8\xe7\xc8\x6b\x47\x50\x41\x47\x36\x96\x40\xb1\x1d\x19\x4a\xf1\xc8\xf7\x2f\x2a\x6c\xc3\x2e\xc1\xc6\x87\x9d\xb0\xc3\x87\x51\xf9\x1c\x06\x22\x1f\x96\xb3\x60\x78\xab\x3b\x20\x27\xe1\x89\xd0\x61\x3e\x88\x48\x73\x04\x56\x07\x38\xf4\x30\x34\xf5\x98\x22\x08\xe2\xeb\x2c\xea\xf0\x58\x41\x4c\x27\x0d\x3c\xce\x1d\x89\xdc\x6f\x47\x52\xd1\x10\x52\x7d\x38\x24\xea\x70\x6e\xc6\xb9\xfe\x09\xcf\xec\x98\xd4\xda\x94\x0f\x94\x81\x82\x13\x2e\xfd\x31\xeb\x1f\x8e\x27\x02\x91\x63\xfa\x5a\xf7\x24\xd9\x66\xc7\xd4\xf7\xef\xd8\xc0\x04\x73\x40\x1d\x9e\x31\xc1\x3f\x3b\xe3\x11\x7b\x38\x23\x1c\xb4\x13\x21\xfa\x19\x59\x9a\x57\xec\x78\x92\xdf\xce\x88\xf0\xec\x8c\xd0\xd6\xe7\x3a\xc7\x39\x23\x3c\x9b\x33\xc2\xce\x9d\xd1\xe3\x53\x90\xbc\x50\xd4\x97\x07\x75\x46\x0a\xe5\x19\x07\x5a\x5c\x9a\xe1\xd9\x9f\x52\xa0\xb5\x4f\x81\xaa\x3f\xa5\x86\xf3\xfe\xa6\x72\x3a\xa5\x2a\xe1\x90\x70\x8a\xc7\x95\xf3\xff\xe5\x21\x86\xa7\x74\x0c\xa5\x27\xf5\xec\xa9\xa5\xc6\x8e\x56\x0a\x5d\x74\x2a\x06\xc9\x60\x76\x0f\x67\x46\x10\x7a\x66\xc3\xee\x4f\xcb\xf8\x1d\x06\x08\xe1\x38\x2d\x37\x09\x27\xe2\xbd\xd3\xe0\x08\x9c\xe6\x60\xb1\x13\xd1\x65\x38\xc1\x1b\xa7\x0d\x41\x39\x88\x79\x3a\xe4\xf2\xf4\xfb\xeb\x80\x4f\x7d\x3a\x14\xee\xe9\x08\x24\x4e\x8f\xf0\x2e\x4e\x87\xe7\x7a\x3a\x6d\xe9\xb9\x42\xcc\xd3\xb5\xb1\x0c\xd5\x20\xe3\xe9\xd6\x0d\xa3\xdd\xbf\x68\x34\xa1\x51\x4e\x9f\x85\xb0\x59\x38\xe7\xda\xd6\x8c\x2b\xe3\x3b\xd6\x3e\x85\x6b\x9a\xa4\xc5\x64\x70\x73\x4e\xb5\x0a\xd8\xf9\x3d\xe2\x6a\xd1\xb9\xac\x49\x9c\x3f\x22\x5c\x9a\xc7\xfd\x05\x97\xe6\x11\xb7\xcc\x32\xb8\x82\x0f\xa8\x99\x40\x4d\xf3\x88\x79\x95\x17\x84\x9f\x8f\xe8\x20\xda\x23\xbe\xf0\x63\x9c\xf6\x90\x8d\xa7\x3a\x0f\xba\x67\x0f\xfa\x2e\x0f\xc9\xb0\x21\x0f\x81\x3c\x3c\xa4\xac\x1a\xf8\x7d\x0f\xf1\x82\x25\x3c\xee\x6f\x37\x41\xf6\x42\x29\x43\x89\x87\xc2\xe5\x09\x8f\xfb\x4d\x5f\xe9\xa1\xa7\x4a\x95\xf0\x80\x74\x3f\xb4\xa0\x97\x22\xfe\xd2\x18\x1e\x96\x80\xe5\x87\xc1\x17\x7f\x18\x10\x80\xc2\x27\x00\x7d\xc2\x87\xc1\x7b\x78\x58\x35\xd4\x57\xd6\x2e\x50\xa0\xd0\x1e\x3c\x2d\x7e\x18\xac\x40\x78\xd8\xa7\x85\xc7\x84\x99\x7f\x4c\x9e\x62\x3f\x26\x4f\x56\x1f\x44\xff\x63\xca\x05\x08\x2f\xfe\x01\x65\xf0\x98\x7f\x5b\xf8\x2d\xb0\x7e\x8f\x59\x34\xef\x82\x14\x99\xba\xb3\x89\x47\x44\xbc\xf8\x18\x16\x14\xbe\x7d\xd0\x5d\x62\x0e\xba\x2b\x78\x0a\xae\x76\xb6\xa0\x67\x96\xae\x11\xe9\xfd\x1b\xf4\x9c\x68\x91\xe5\x64\x32\x3b\x85\x55\x4b\x84\x0c\xac\x68\x5d\x0b\x4d\x8f\x96\xb6\xa0\xc0\x4f\xd1\xb2\xec\x86\x96\x36\xa1\xf3\xa1\xec\x10\x2a\xdf\xef\xba\x6b\x92\x00\xb7\x6c\x20\xa1\x22\xd5\x7a\xd0\x7a\x6b\x5d\xe2\xa4\x95\x3e\x8c\xd6\x42\x7f\x54\x6b\x99\x15\xb5\x15\x32\xa9\xb5\xd3\x99\xd1\xda\x07\x59\x4f\x61\xdc\x11\xc1\xdd\xef\x3a\xb4\xa0\x66\x00\x2b\x5a\xef\x5f\x60\x53\xeb\xa5\xb4\xa3\xea\x31\x28\x38\x5b\x7d\x9d\x49\x6a\xcf\x04\x08\xda\x9f\x71\x8b\xf9\x7e\x23\xc5\x16\x9f\xb1\xac\xc4\xe3\x86\x4a\xdf\x61\x2b\x9e\x64\xda\x27\x4f\xef\x9e\xf1\x55\x58\x26\x87\x84\xa7\xb8\x42\xb1\x3c\xb5\x42\xdd\x3f\xcd\x2b\x78\xf5\x69\x6e\x1b\x92\x4b\x6a\x78\xda\x67\x0c\xcf\x29\x88\xf8\x9f\x53\x2e\xe9\x48\x5e\xe1\x39\x4f\x7a\x72\xcf\x79\x1a\xc0\xe4\x08\x93\x28\x78\x4e\x44\xab\xcf\x59\x4f\xcc\x38\xeb\x2a\x02\xbe\x9f\xf7\x6f\x53\x84\x4c\x4f\x7a\x8c\x4f\x9e\xd0\x3e\xe7\x25\x55\x73\x78\xce\x17\xf8\xf0\xff\xe0\x51\xfc\x9f\x41\x33\xe6\xb8\xa9\x05\xe8\x19\x42\x47\xc9\x8e\xcf\x1d\x51\x53\xc8\xf1\x64\x60\x94\xef\xaf\xd3\x11\xc1\xe6\x78\xc2\x30\xe4\x08\xae\xce\x11\x71\x63\xbe\xbf\x0a\x64\x0d\x69\x8b\x1c\x81\x2d\x2a\x44\x33\xc7\x7a\x32\xa2\x5b\x87\x84\xf9\xfe\x6a\xfa\x0a\x99\xde\x5d\x8e\x88\x68\xf2\xfd\xd5\xc7\x1a\x7a\x30\x37\xe4\x03\xdf\xea\x21\xc7\xe9\x92\x43\x8e\xf0\x38\x73\x7c\x59\xc8\x60\xcc\x2c\x7f\x06\x18\x36\x50\x00\xe1\x5b\x64\xc1\x5a\xe4\xfc\xab\x39\x57\xc8\x95\xe5\x09\x11\xc8\x52\xcf\x19\x91\x60\x33\x70\xfe\x00\xd9\xd0\x1a\xa3\x27\x70\xf7\x2a\x18\x9c\x62\x60\x23\x72\x61\x84\x4f\x81\x0d\xca\xba\x41\xd6\x76\x7c\xb8\x85\xac\x09\x93\xde\xef\x1d\xd3\x2a\x82\x92\x80\x58\x1f\x8b\x84\xe0\x66\x3d\x85\xcd\xb0\xb3\xfb\x5d\xe0\x26\x67\x25\xf3\x64\x2d\x0d\xe8\xd6\x9a\x50\x06\xe3\x9b\xef\x77\x15\x74\xaa\x50\xd5\x48\x59\x0f\x3f\x8f\xdd\xff\x4d\x45\x2b\xe8\xc8\xcc\xb3\x6f\xb8\xdd\xce\x84\x23\xc1\x7b\xc8\x20\x16\x60\x21\xe4\x4e\x79\x06\x91\x33\xaf\x84\x72\x96\xba\x12\xa2\x33\x9b\xaf\xe4\xc2\x06\xf2\xbc\x34\x06\xda\x99\xfc\xe7\xa8\x67\x4b\xcc\xc0\x7d\xc9\xf7\xcf\x09\xf7\x2e\xdb\x89\x99\xa0\xba\x40\x46\x84\xd7\xd9\xe0\x01\x50\x56\x32\xa3\x99\x3c\x11\x6b\xe6\xc9\x39\xe1\x8d\x64\x72\xcc\xac\xd2\x43\x9e\x0d\x9f\x3c\x57\xcf\x13\x2b\x9c\xaf\x50\x62\x82\xa5\x29\x11\x1a\xb9\xc4\x1d\x1b\x2b\x71\x77\x01\x84\x6d\x2f\x51\xd8\xa3\xc4\x43\x51\x75\x2e\x88\x82\xfb\x8d\xfe\x19\xc1\x4e\x59\xf7\x4b\x85\xa7\xc5\x25\x66\x54\x97\xfb\x0b\x70\xe3\xf7\x1c\xa1\xf0\xac\xb7\x44\xe0\xbc\xc4\xca\xd0\xb7\xd0\xf4\x97\x58\x95\xbe\x77\x81\x47\xc3\x52\x36\xe9\x84\x1c\xf7\xfe\x0f\x8c\x5d\xe0\x81\x97\xfb\xeb\xdf\x54\xe6\xd0\xd4\x39\xa8\x0b\xf3\x87\x66\x24\xd0\x84\x25\xf2\xca\xa3\xdc\x5f\x5e\x8c\xa5\x94\xaa\x12\x7d\x48\x47\xf2\x42\xbf\xce\xf1\x3a\xcf\x03\x4b\xec\x7a\xa1\x70\x70\xe0\x41\x3f\xb5\xc4\xa1\xd8\x26\x2f\x1d\xcb\xfd\xf5\x01\x6d\x56\xe2\xa7\xa1\xc9\xcb\x3c\xc5\x50\xe8\x0e\x16\xd9\xd7\xee\x65\x57\x4c\xfb\xbd\x4f\xe6\x9e\xba\x4a\x9f\xe8\x21\xe0\x03\x24\x5c\x0a\x02\x7c\x4c\x81\x40\x09\xb0\xc3\xf5\x29\xf4\x53\x8a\xd4\xfb\x37\x14\xf1\x04\x95\x50\xe0\xbd\x9c\x53\x30\x2c\x3d\x80\x82\x2d\x48\x5f\xa3\x00\x41\x08\x4b\x50\x3b\x8c\xcd\x49\x31\x79\x25\xcc\xac\xb0\x3f\x05\x3a\xbd\xa8\xf0\xae\x85\xd6\xad\x00\x55\x9a\xe3\xc9\x82\x4c\x83\x51\x34\xaf\x95\x71\x93\xc4\xf1\x0a\xd6\xa1\x55\xff\xca\xc0\x39\x45\xad\x49\x28\xf4\x96\x8a\x02\x87\xda\x17\xb6\xb4\x73\xd8\xce\xb6\x90\xd8\xc2\xe5\x5a\x7a\xc0\x2d\xfa\x5f\x1c\x5a\x6c\x47\x66\x87\x41\x2f\x06\xce\x33\xd2\xdd\x60\x22\x8b\x65\xe1\x37\x04\xb1\xd8\x0a\x7d\x8b\x15\x0c\x8f\x20\x3f\x31\x15\x8e\x00\xf6\x2f\xb6\x1a\xc0\xa1\x29\x46\x0f\xab\x18\x6f\xc2\x8a\xd1\x0f\x06\x96\x99\x71\x7e\x77\xd6\x43\xd3\x14\xeb\x1c\xac\x33\x04\x2d\xc6\xeb\xcc\x42\xa1\x2c\xf7\xcf\x85\x9d\x18\xb8\x64\x52\x38\xe6\x8e\x46\x53\x10\x99\x14\x1e\x48\x96\x49\x8b\x59\x26\x44\x04\xd9\x13\x72\x33\x9f\xe8\x4f\xe2\xaf\x83\xd1\x32\x33\x21\x19\x7f\xde\xff\x09\x26\x9d\x8e\x05\x50\xc2\xee\xdf\x9e\x26\x30\x31\xbb\x10\x9e\xab\x50\xd9\xae\x67\x0b\xf5\xfe\x42\xe4\x57\xe3\x42\x1f\xec\x18\x72\x70\x0b\x6b\x5c\x61\x40\x8d\x60\xd0\x1a\x79\xe8\x5b\x63\x8f\x39\xd4\x38\x16\xc4\xb6\x6a\x1c\x9c\xb2\xde\x5f\xb3\x0b\xda\x5f\xac\xbc\x30\xc4\xc5\x63\xfb\x2a\xb0\x44\xf5\xfe\xe6\xa9\x4e\xa5\xe2\xaa\x72\x1a\x4b\x05\x7c\x52\xa9\xb7\x2b\xfc\x31\x64\x06\xc0\x1c\xac\xb8\xd8\xf8\x82\xfe\xa8\xbc\xe6\xa9\x90\xbe\xaa\xb2\x65\x94\xb0\xad\xde\xff\xc9\x8b\x09\xa6\x79\x8f\xd5\xe2\x92\x1c\xaa\x6d\x59\x5e\x31\x54\x83\x55\xa9\xf7\x0f\x99\xaf\x52\x3c\x2a\x83\xa3\xca\x73\xaf\x0a\x8f\xba\xda\xd0\xc4\x8a\x0b\xce\x47\xb5\x0b\xc4\xa8\xc6\x45\xcd\x4d\x42\x9d\x29\x86\x7a\xff\xa6\x2c\x28\xd9\xe9\x45\xf3\x20\xac\xd2\x07\xac\xb0\xf4\x80\xaf\x50\x27\xd1\xfb\x5b\xc0\xe5\x75\x0e\x4c\x68\xb1\x6b\x0f\xc6\x9b\x2b\xdb\xb4\x37\x24\x4f\xec\xc0\xe0\xa3\xda\x0a\x6b\x6d\xeb\xe2\xd8\xb5\x6d\xeb\x10\xcd\x36\x2c\x00\x01\x9f\x31\x4e\xb3\x74\x7f\x43\x91\x61\x4b\x50\x62\x06\xac\x10\x99\x96\x5c\x82\xa5\x11\x2f\x7c\x8f\xb9\x31\xcb\xd3\x4a\x4b\x3c\x44\x87\xe6\x07\xd3\x1a\x6d\x9b\x41\xa3\xd8\xae\xa0\x9b\xf1\x64\xc2\xd6\x39\xa2\x1d\x74\x41\x6d\x9d\x2f\xd9\xb1\xce\x68\x69\x27\x8c\xc7\xb4\x86\x68\xd0\x9e\x16\x2c\xc7\x60\x59\x20\x1c\x96\x0f\xa0\xcd\x32\xd8\x82\x57\x10\x3c\x98\xe6\x89\x9a\xe5\x0b\x44\xb1\xb2\x65\x3d\x2d\x18\x8c\xaf\xc1\x79\xb0\x86\x00\xd8\xda\x62\xc0\xfb\xa7\x01\x8f\xd6\xf8\x44\xc2\x96\x5f\xb9\xde\x58\xdc\x3f\x8d\x27\x23\xc6\x0b\x6d\x0b\xe6\x7f\x4c\xcb\x93\x39\x47\x92\xc3\xfd\xe3\x1b\xa2\x44\xaa\x4f\xc8\x2a\xaa\xe5\x19\x51\x71\x12\x67\x7e\xc2\x19\x34\x3f\x27\x68\x67\xbe\x8e\x18\xcd\xf5\x64\x5b\xea\x54\xc3\x36\xfd\xdf\x3a\x07\x36\xde\x51\x5b\x8f\x3c\xc5\xb4\x9e\x20\x5a\xd6\xe5\x85\xd1\x40\x0d\x8a\xa8\x0d\xaa\x09\x03\xcf\xda\xb5\x66\xbc\xc0\x02\xf7\xcf\x07\x37\xfe\x71\xbf\x4f\xe8\x0c\xfb\x5c\x13\xbe\xe0\x93\x37\x9e\xe0\x34\x9a\xc5\x16\x05\x73\x37\xc4\xe0\x35\x86\x06\x53\xd8\xe2\xfd\xee\x28\x7a\x46\x47\x2e\xf3\x8a\xad\xc5\x9c\x98\x83\x0e\x68\xf7\x57\xc6\x04\x8d\x97\x62\x2d\x66\x5b\x09\x88\xdd\x62\xc5\x2f\x66\xb4\xaa\xca\x4e\x95\x2e\x46\x8b\xf7\x7f\x3c\x9a\x6c\xb1\xdd\x5f\x80\x92\x01\xb9\xfd\x16\xff\xd1\x2d\x6d\x7c\x20\xd0\xa2\x33\x08\x6f\xd1\x65\x07\x54\x96\x19\xc6\xf4\x16\x39\x35\x70\xc5\xbc\xc7\x83\x79\xf6\xee\xec\x0d\xd5\xd3\xe2\xf2\xc3\x1a\xd8\xb7\x21\xe6\x0e\x2d\x2e\xa0\x28\xa0\x74\x34\x5e\x61\x35\x9e\x84\x34\x70\x70\x8b\x9f\x6c\x2f\x91\x57\xc7\x4d\x68\xb2\x1a\x58\x31\x22\x79\x20\xb3\x63\x77\x82\xa8\xa7\x51\xaf\x34\xd1\x2a\xa1\x49\xe6\x77\xde\x79\x7c\xd8\x24\x0b\xba\x64\x05\x07\x37\xc9\x59\x9e\x4c\x09\x20\xd4\x0d\xe6\xb3\x81\xf7\xd1\x6d\xdd\xfd\x35\x59\xd0\x50\xd4\x60\x34\x9a\xfc\x5b\x47\xb9\x6d\x2d\xc1\x61\x9f\x9b\xd0\x26\xb4\x75\x45\xd6\x84\xbe\x02\x22\xa3\xc4\x76\x99\x65\x45\xb9\x13\xe7\xf4\xde\x8d\xb3\x75\x02\xcc\x7e\x7f\x77\x58\xc1\x06\x8e\x83\x1f\xdb\xee\xef\x11\xb9\xba\xe1\xf7\x0f\xb4\x4d\x93\x17\x7e\x93\xb5\x3c\xae\x6b\x9a\x1e\x5c\xa0\x0a\x7e\x3b\x56\xa4\xf4\x2d\x9b\x72\x25\xfa\x84\xd7\xd8\x94\xa8\xd0\x6c\x60\x35\x2d\x4a\x9d\xb1\xb6\xa3\x15\x4e\x76\xd3\xca\xe6\x6b\x68\x08\x75\xd3\x86\x4f\x27\x8d\x94\x38\xd1\xce\x5b\xac\xc6\x7d\xd0\x5b\x6d\xba\xc8\xa2\x2f\xec\x20\xc7\x05\x2b\xc0\xe0\xe7\x27\x21\x86\xce\x02\x63\xdd\x32\x04\xa0\xd1\xc1\x6c\x79\x62\x6d\x99\xa6\xa3\xf1\xe2\xac\xc1\x35\x6d\x46\x5c\x52\x31\x35\x13\xb4\x31\xe9\x90\xbc\x66\x64\x77\xcb\x52\x01\x35\xad\x42\x48\x71\xb3\x0c\x76\xb1\x02\x2d\xd4\x8c\xa7\x37\x8d\xb3\x58\xc1\x46\xa8\x45\x9a\xf9\xd2\x17\x6d\xd9\xe8\x06\x91\x46\x65\x17\xd6\x76\x85\xfd\x6d\x06\x2d\xd8\x6c\xac\xd3\xde\x46\x81\x6e\x30\xd6\x8d\x17\x00\xcd\x25\xd9\x0b\xc9\x39\x89\x47\x97\xa2\x2c\x86\xda\x6c\x0e\xd5\xde\x5c\x2e\x96\x91\xa4\x7e\xbf\x6b\x82\x41\x6d\xae\x7f\x52\xe0\x0a\xf5\xde\xdc\xd0\x83\xaf\x74\x9a\x5b\x5a\x5d\x6d\x9f\xd4\x09\x6e\xa4\xa1\xdb\xc1\x87\x2e\xcd\xed\x74\x92\xd3\x0d\xcb\x74\x2b\x64\x1f\xa7\x8f\xd2\xdc\x1a\x67\x84\xb6\xe1\xa4\x53\x36\x70\xd1\xef\x96\xc9\x86\x33\x3d\x60\x5a\xda\x84\xa6\x6c\x70\x35\x90\xa1\x8e\xff\x53\xa7\x6d\xe6\x13\x99\x0c\x49\x9a\x99\x31\x4d\x9b\xb9\xb1\x06\x2b\x23\xbd\xf8\x4c\xa6\x81\x09\x33\x13\x64\x80\xe1\x09\x2e\x0b\x6d\xfa\xfd\x1d\xfe\x4d\x81\x17\xf1\x6f\x42\x0b\xfe\x9b\x52\x56\xc6\x85\x49\xb7\xf0\x6f\xd2\x6a\xc3\x31\x2f\xd0\xe8\x70\xba\x93\x20\x81\x9e\xf7\xfb\x8b\x77\x20\x1e\x37\x8d\x80\xf8\x5c\x94\xf3\xb8\x6b\x8a\x39\x38\x23\x04\xa2\xc3\x23\x28\xec\xeb\xbc\xcf\x11\x97\x06\xe7\xe1\x83\x23\x28\xdd\x99\x1b\x80\x9d\x35\x9d\x8d\x59\xf0\x09\xf0\x42\x96\x97\x9a\x2e\xff\x7b\x52\xe8\xf2\xf7\xda\xc0\x65\xbd\x6e\x71\xe1\x2b\x0e\x17\xbe\x62\x80\x29\x1c\x31\xf0\xc5\xc6\x0b\x95\xeb\x02\xd7\x25\xb9\x30\x3b\x08\x79\xbd\x07\x8d\xe9\xb2\xf3\x28\xd6\x65\x67\x0c\xe5\x72\x50\xfb\xb8\xac\xc3\x59\x97\xf5\x6a\xc7\xe5\x98\xa7\xa2\xfc\x84\xe4\x3b\x6f\x68\x5c\xce\x8c\x26\x27\x19\xcb\xe5\x71\x7f\xa3\x25\x84\x77\x1d\xc8\xd2\xb8\xb9\x64\xee\x49\xb2\x5c\x4c\x14\x6e\x88\x43\xcd\xb1\x61\xb6\x67\x70\xd2\xc1\x65\x45\x11\x3c\xdf\x77\xa9\x08\x77\x5d\x78\x68\xe4\xd4\x0b\x2e\x8d\x67\x03\x2e\x4d\x06\x4b\x9b\x71\xe6\x36\x34\x07\x97\x8e\x5f\x8a\x44\x47\x87\x42\x70\xe9\x4d\xd8\xa1\x2f\x38\x8b\x60\x89\x43\x1d\xd9\xc1\xa3\x2e\x47\xe4\xcd\xea\x59\x39\xe8\x75\x7f\x63\xa4\x8b\x8a\xc4\xe5\x33\x40\x77\x7a\xa0\xce\x74\xde\xef\xc3\x30\xef\x11\x09\x29\xa7\x47\x0c\x7e\xbf\x4f\x92\x54\x4f\x2c\x5b\x2b\x9f\x26\xb9\x2e\x6d\xcd\xd3\x68\xd7\x7f\x13\x72\xc3\x47\x33\xae\x03\xbb\x84\xea\xe1\x45\x8f\xf3\x9a\x0f\x92\x06\x00\xff\xc7\x6d\x5f\x10\x94\xb3\xf5\xba\xcd\x0d\xd4\xb4\xe7\xea\x01\x42\x19\x7d\x38\xb7\xd2\x58\x53\xf1\xc3\x3a\xe9\xc4\xb8\x35\x82\xd5\x04\xb3\xd2\xf7\x77\x63\x70\xeb\x7c\x0a\xe8\x73\xbb\xdf\x80\x58\x36\xbc\x45\x87\x88\x04\x9f\x24\x31\x4f\x01\x9c\x81\xa7\x2f\xbf\xde\xe1\x38\xf8\x44\x84\xeb\xb3\xb0\x53\xe3\x2b\x48\x9e\xb2\xfb\x1c\x68\xdb\x21\x27\xbb\x85\xce\x73\xd4\xce\x23\x9f\xce\xdb\x8d\x1e\x61\x1e\x7a\x3c\xe3\x0b\xd0\x57\xab\x1c\x01\xd6\x27\x16\xdb\x23\x44\xbd\xc7\x25\xea\x3d\xe6\xbf\xa4\xb3\xdd\x60\x83\xb9\x03\x5e\x1c\xad\x6c\xa8\xf8\x3b\xc1\xef\xb1\xd2\x1d\xea\xb1\x0a\x6b\x2b\x22\x94\x1e\x2b\x05\x87\xc7\xbc\x9d\x87\x15\x3d\x36\x00\xf8\x07\x3d\xfa\xce\x85\x47\x1f\x60\xe3\x1e\xfb\x60\x27\x3e\xa7\xe9\xbc\xe4\xe9\xf1\xc3\xf8\x3c\xa9\xff\xef\x38\xa8\x4b\x32\x00\xb0\x12\xd2\x11\x43\x97\x3d\x74\x39\x27\x96\x2f\xda\x43\xe7\x25\x7e\x97\x7c\xa1\xae\x20\x9e\xef\x52\x48\xcc\x4e\x26\xea\x52\xa1\x43\x79\x3f\x98\x99\x30\xb7\xfc\x9b\x2e\x4d\xd1\xe4\x1f\xcf\xaf\x3b\x70\x29\xae\x02\xb8\x30\xb3\x0e\x89\xbb\x74\x0a\x48\xff\x3b\x52\xea\xc2\xcc\xf8\x2b\xbc\x88\x52\xf9\x20\xc0\x4a\x15\xf6\xb8\xaf\xeb\xa2\xae\x70\xa7\xba\x9e\x58\x26\x2f\xae\xfb\xfd\xce\x11\x08\xd5\x0c\xf5\xdf\x35\x0b\x5f\x82\xf6\xb5\xea\xfb\x5d\x36\x63\xe3\xc2\x42\x87\x77\xd2\xb5\x0f\x18\xc4\xce\xe3\xa1\xae\x7c\xa6\xdc\x69\x3a\x3b\xbd\xff\x4e\xab\xd9\x2d\xe3\x17\x5b\x44\xb2\x93\xf8\x96\x79\x73\xdc\xef\x1f\xfa\x8a\xdd\x78\x29\xd7\x2d\xcf\x3f\x24\x1b\x0f\xc9\xbb\x55\x48\x42\xb7\xba\x5a\x55\x38\xc2\xdd\x2a\xa5\xa9\x1b\x47\x6c\x99\x3d\xd7\x6b\x81\xce\xab\x89\x6e\xbe\xee\x79\x3b\x0a\x91\xef\x8b\xc0\xf7\xcf\x20\x27\x4c\x04\x83\x7d\x6e\x40\xe3\xa4\x9d\xeb\x34\x44\x7d\xca\x89\x69\xe9\x89\xf6\xe5\x59\xf5\x15\xfa\xf6\x79\x38\x9b\x33\x3c\xea\x33\x2f\x26\xe1\x3d\x52\x9f\x70\xbf\x98\x92\x85\xe7\x32\xf0\x7d\x36\xaa\xb5\x3e\xf1\xed\x89\x5f\x7f\x63\xfa\xc9\x86\x9d\x63\x41\x93\x8d\xc8\x27\xea\x23\x6e\xd0\x18\x48\x73\x04\xbc\x7f\xc3\x58\x15\xd0\xe3\x7c\x0f\x3a\x22\xb6\x3c\xe8\x74\x8f\xb8\x4e\x1b\xd7\xeb\xc5\xb1\x84\x66\xc4\x42\x3b\x31\x62\x81\x84\x0f\x5a\xa1\x11\xeb\x1a\xb8\xa1\x5d\x03\x03\x8c\x08\x4e\x1b\xb1\xad\x4e\xff\xa6\xae\x41\x7c\x47\x9d\x0b\xbf\xa1\xe8\x46\xf4\x27\xd8\x6b\x44\xb7\x01\xe8\x18\xcf\x59\x32\x66\x7c\xa2\xf9\x64\xd9\x0b\x45\xb4\x5f\x43\xf8\xca\x65\xd0\x2d\x1e\x92\x30\xf2\xfd\x9d\xf8\x46\x66\xc8\x13\x6c\x30\xe4\x29\x0e\xa8\xcc\xa0\x85\xe4\xfb\xfb\x40\x24\x42\xce\x1a\x02\x65\x33\xd6\x63\x81\x21\x35\xbe\x00\x77\x76\xaa\x0b\x6a\x07\xec\xa8\x36\x5e\xbe\x21\x9c\xe0\xb6\x04\x18\x1f\xf7\xb7\xf3\xd9\xdd\x10\xaf\xd0\x58\x03\x2e\x2f\x7a\x76\xf6\xec\xc6\x35\xf6\x81\x20\x70\x08\x63\x91\x41\x81\x19\xf2\x0a\x43\xa1\xc4\x86\x6e\x93\x27\x6a\x43\xa5\x34\xe4\x29\xc4\x43\x79\xcd\x34\x14\xfc\x33\x14\xfa\x66\xe8\x93\x03\xf0\x02\x64\x28\xcf\x86\x07\x9c\x0a\xec\x0f\x7e\xd0\xe0\xa3\xaf\x01\xcb\x30\xee\x77\x83\x75\x19\xca\x21\xd9\xed\x6f\x16\xb2\xd6\xb8\xdf\x43\x56\xff\x01\xf5\x3b\x14\xb8\xb5\x45\x67\xdb\x18\xe9\x0f\x83\x62\x1d\x96\xb8\x43\xc3\x2c\x76\xa2\x3a\xf3\xb3\xb0\x92\x55\xe4\x11\x6b\x2c\x68\x12\x06\x5f\xb5\x8d\xfb\xc7\xe3\x47\x18\xc6\x30\x7f\x98\x17\x2a\x0f\x98\x48\x61\x9e\xa0\x09\x07\x73\xac\x85\xcf\x4c\x86\xf9\x98\x9c\xa6\xe3\x87\x3d\xf0\x6d\xd5\x80\xb3\x87\x9c\xc7\x8d\x7c\xea\xeb\x3e\x7e\xbd\x48\x1e\xff\xbb\x0b\x1c\x8e\x48\x72\xf0\xf6\x73\x78\x2c\xfc\x86\xbf\xb5\x4c\xf2\xf0\x08\xcf\x6e\x38\x5f\xdb\x0e\xbf\xbf\x37\xcb\x61\xc0\xbf\x45\xa9\x2c\x0c\xba\x54\x00\x6e\x08\x4e\xc0\x70\xdd\x26\x20\x87\x46\xb4\x30\x9c\xcf\xf8\x86\xeb\xac\x07\x0a\xed\x10\x26\x85\x95\xb4\x98\x83\xc6\x72\xf0\xe1\xea\x70\x38\xd5\xc3\x27\xcb\xf9\x4c\x75\xf8\x04\xf3\xcf\x6d\x5d\xeb\x8e\xb9\x59\x18\x93\x6f\x14\xc6\x84\xf9\x19\x34\x86\xe3\xfe\xad\x92\x99\x90\xb9\xa7\xf3\xf9\xe9\x98\xce\xd3\xc1\x31\xe1\x71\x0c\x3e\xaf\x9e\x1b\x23\xa5\xfb\x37\x33\x66\x9c\xd0\x72\x39\xcc\x65\xa5\xe8\x8a\xcc\xaa\x17\xe2\xb1\x30\x2b\x7e\x50\x8b\x0c\xb1\xa6\xd3\x09\x9d\xbe\x49\x98\xbe\xae\x7c\x27\x62\x2b\xfe\x0d\x64\xf6\xc9\xe7\x4a\xeb\xce\x69\x0e\xe3\xab\x8f\x79\xc5\x70\x21\x0c\xba\x62\x02\xcb\x5d\x91\x6f\xc2\x2e\x3e\xe4\xbf\x40\x85\x2b\x2a\x0b\xd6\xd1\xed\x15\xb3\x84\xeb\x2f\x7e\xbf\xf8\x6e\xea\xe2\xa3\x56\x94\x5d\x93\x2d\x4a\x83\x1f\x75\x45\x47\xc6\x95\x03\x91\x6d\x2f\x84\xc6\x97\x90\x15\xaf\x75\x59\x72\xc9\xe3\x7e\xf3\xc0\xef\x02\xd9\x24\x5c\xf2\x94\x57\xe0\x21\xd6\x25\x34\xfa\x97\x64\x43\x09\x56\x21\x7c\x11\x7b\x51\xb8\x2e\xa9\xc2\x81\x2a\xd7\x2a\x40\xcd\x45\xee\xbc\xa4\xce\x1e\x2e\xb6\xe4\xad\xf2\x25\xbe\x11\xee\x98\xc0\x85\xbd\xfd\x49\xc8\x25\xf9\x40\x63\x20\xe4\x52\x30\xdd\xa5\x1b\xb4\xf5\xc5\xa3\xa4\xeb\x7e\x27\x5e\x0c\x5d\x8a\x8e\xf7\x1b\x06\xe7\xd2\x1d\xd8\xbc\x14\x7e\x31\xef\xef\xa4\x87\x8b\x5e\xde\xa5\x19\x3f\xec\x40\x6b\x84\xd0\xf3\xc5\xd6\xa5\xf7\x7f\x90\x93\x4b\x2d\xdf\xef\x1a\x2e\x05\x61\x2f\x75\x20\x59\x7d\xcc\x3d\x5c\xda\x89\xca\x77\x67\xb0\xbe\x5c\xcd\x4b\x47\xe4\x09\xe0\xa5\x93\xdd\xaf\xf8\x02\x24\x6e\x14\x76\xfe\xd2\xcb\xc2\x65\x99\xf7\xa7\x97\x65\xba\xb3\x97\x65\x62\xc0\x1c\xcd\xe9\xd3\x5d\x08\xa7\x2f\x20\x93\xd6\xeb\x9a\x7c\x98\xf9\xc9\x0b\xec\x4f\xf8\xc7\x9f\x94\xa0\x4f\xe8\xd5\x4f\xde\x48\x7e\x42\x71\x7d\x42\x6b\x7c\x42\x6b\x7c\xda\x39\x3d\xbc\xe2\x01\x02\xbf\x78\xd4\xfa\x8a\x0d\x22\xf9\xe2\x1b\x85\x97\x55\x00\xe8\xfe\xd7\x2c\x00\xb0\xb5\xff\x1f\x00\x00\xff\xff\x11\x91\x1a\xde\x5b\x35\x00\x00") func keysWordlistSpanishTxtBytes() ([]byte, error) { return bindataRead( @@ -146,7 +146,7 @@ func keysWordlistSpanishTxt() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/wordlist/spanish.txt", size: 13659, mode: os.FileMode(420), modTime: time.Unix(1497960590, 0)} + info := bindataFileInfo{name: "keys/wordlist/spanish.txt", size: 13659, mode: os.FileMode(420), modTime: time.Unix(1511602021, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -204,9 +204,9 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ "keys/wordlist/chinese_simplified.txt": keysWordlistChinese_simplifiedTxt, - "keys/wordlist/english.txt": keysWordlistEnglishTxt, - "keys/wordlist/japanese.txt": keysWordlistJapaneseTxt, - "keys/wordlist/spanish.txt": keysWordlistSpanishTxt, + "keys/wordlist/english.txt": keysWordlistEnglishTxt, + "keys/wordlist/japanese.txt": keysWordlistJapaneseTxt, + "keys/wordlist/spanish.txt": keysWordlistSpanishTxt, } // AssetDir returns the file names below a certain @@ -248,14 +248,13 @@ type bintree struct { Func func() (*asset, error) Children map[string]*bintree } - var _bintree = &bintree{nil, map[string]*bintree{ "keys": &bintree{nil, map[string]*bintree{ "wordlist": &bintree{nil, map[string]*bintree{ "chinese_simplified.txt": &bintree{keysWordlistChinese_simplifiedTxt, map[string]*bintree{}}, - "english.txt": &bintree{keysWordlistEnglishTxt, map[string]*bintree{}}, - "japanese.txt": &bintree{keysWordlistJapaneseTxt, map[string]*bintree{}}, - "spanish.txt": &bintree{keysWordlistSpanishTxt, map[string]*bintree{}}, + "english.txt": &bintree{keysWordlistEnglishTxt, map[string]*bintree{}}, + "japanese.txt": &bintree{keysWordlistJapaneseTxt, map[string]*bintree{}}, + "spanish.txt": &bintree{keysWordlistSpanishTxt, map[string]*bintree{}}, }}, }}, }} @@ -306,3 +305,4 @@ func _filePath(dir, name string) string { cannonicalName := strings.Replace(name, "\\", "/", -1) return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) } + From f48baf86fb190f61b8e44baa9d033c6d85658b28 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Wed, 27 Dec 2017 14:37:37 -0800 Subject: [PATCH 182/287] Add Address type which is HexBytes --- glide.lock | 30 ++++++++++++++---------------- glide.yaml | 2 +- hd/address.go | 4 ++++ hd/hd_test.go | 10 +--------- keys/keybase.go | 4 +++- pub_key.go | 27 ++++++++++++++++----------- pub_key_test.go | 3 ++- 7 files changed, 41 insertions(+), 39 deletions(-) diff --git a/glide.lock b/glide.lock index c8c922c6a..5032685c2 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 765599cf3dcac232d3d2ece65c3b016d0abe55d0536adfe93d11e0dd29287de4 -updated: 2017-11-13T14:37:54.127163059+01:00 +hash: a21061afc44c148eb6bfeb91478b520661f3d086234383a0208d915b0cb058b8 +updated: 2017-12-27T14:29:49.534901894-08:00 imports: - name: github.com/btcsuite/btcd version: c7588cbf7690cd9f047a28efa2dcd8f2435a4e5e @@ -9,10 +9,10 @@ imports: version: 66871daeb12123ece012a9628d2798d01195c4b3 subpackages: - base58 -- name: github.com/ethanfrey/hid - version: ea8f4c923d3bc8c9c312b7d38724a294f184258a - name: github.com/ethanfrey/ledger - version: 23a7bb9d74bc83a862fcb4bddde24215b2295ad9 + version: 5e432577be582bd18a3b4a9cd75dae7a317ade36 +- name: github.com/flynn/hid + version: ed06a31c6245d4552e8dbba7e32e5b010b875d65 - name: github.com/go-kit/kit version: e2b298466b32c7cd5579a9b9b07e968fc9d9452c subpackages: @@ -21,14 +21,14 @@ imports: - log/term - name: github.com/go-logfmt/logfmt version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5 -- name: github.com/go-playground/locales - version: e4cbcb5d0652150d40ad0646651076b6bd2be4f6 - subpackages: - - currency -- name: github.com/go-playground/universal-translator - version: 71201497bace774495daed26a3874fd339e0b538 - name: github.com/go-stack/stack version: 817915b46b97fd7bb80e8ab6b69f01a53ac3eebf +- name: github.com/gogo/protobuf + version: 342cbe0a04158f6dcb03ca0079991a51a4248c02 + subpackages: + - gogoproto + - proto + - protoc-gen-gogo/descriptor - name: github.com/golang/snappy version: 553a641470496b2327abcac10b36396bd98e45c9 - name: github.com/howeyc/crc16 @@ -55,17 +55,17 @@ imports: - leveldb/table - leveldb/util - name: github.com/tendermint/ed25519 - version: d8387025d2b9d158cf4efb07e7ebf814bcce2057 + version: 1f52c6f8b8a5c7908aff4497c186af344b428925 subpackages: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: 1c96861c03231361546944d883d99593b2e6b408 + version: 27be46e25124ddf775e23317a83647ce62a93f6b subpackages: - data - data/base58 - name: github.com/tendermint/tmlibs - version: 56e51bc1133bd54a331e0314d5f80fb547460362 + version: 93c05aa8c06ef38f2b15fcdd1d91eafefda2732d subpackages: - common - db @@ -82,8 +82,6 @@ imports: - poly1305 - ripemd160 - salsa20/salsa -- name: gopkg.in/go-playground/validator.v9 - version: 1304298bf10d085adec514b076772a79c9cadb6b testImports: - name: github.com/davecgh/go-spew version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 diff --git a/glide.yaml b/glide.yaml index 64b275f10..f9df5c18d 100644 --- a/glide.yaml +++ b/glide.yaml @@ -17,7 +17,7 @@ import: subpackages: - extra25519 - package: github.com/tendermint/tmlibs - version: sdk-develop + version: sdk2 - package: github.com/tendermint/go-wire version: develop subpackages: diff --git a/hd/address.go b/hd/address.go index 5b664b496..f59876739 100644 --- a/hd/address.go +++ b/hd/address.go @@ -1,5 +1,9 @@ package hd +// XXX This package doesn't work with our address scheme, +// XXX and it probably doesn't work for our other pubkey types. +// XXX Fix it up to be more general but compatible. + import ( "crypto/ecdsa" "crypto/hmac" diff --git a/hd/hd_test.go b/hd/hd_test.go index 02d80388c..0ec47f5c3 100644 --- a/hd/hd_test.go +++ b/hd/hd_test.go @@ -2,9 +2,6 @@ package hd import ( "bytes" - //"crypto/hmac" - //"crypto/sha512" - //"encoding/binary" "encoding/hex" "encoding/json" "fmt" @@ -15,11 +12,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/tyler-smith/go-bip39" - //"github.com/btcsuite/btcd/chaincfg" - //"github.com/btcsuite/btcutil/hdkeychain" - //"github.com/mndrix/btcutil" - //"github.com/tyler-smith/go-bip32" - "github.com/tendermint/go-crypto" ) @@ -84,7 +76,7 @@ func TestHDToAddr(t *testing.T) { copy(pubT[:], pub) addr := pubT.Address() fmt.Printf("ADDR \t%X %X\n", addrB, addr) - assert.Equal(t, addr, addrB, fmt.Sprintf("Expected addresses to match %d", i)) + assert.Equal(t, addr, crypto.Address(addrB), fmt.Sprintf("Expected addresses to match %d", i)) } } diff --git a/keys/keybase.go b/keys/keybase.go index 7f53b2979..c68564d5a 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -86,7 +86,9 @@ func (kb dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { // List loads the keys from the storage and enforces alphabetical order func (kb dbKeybase) List() ([]Info, error) { var res []Info - for iter := kb.db.Iterator(); iter.Valid(); iter.Next() { + iter := kb.db.Iterator(nil, nil) + defer iter.Close() + for ; iter.Valid(); iter.Next() { key := iter.Key() if isPub(key) { info, err := readInfo(iter.Value()) diff --git a/pub_key.go b/pub_key.go index dfa012969..cda01a9df 100644 --- a/pub_key.go +++ b/pub_key.go @@ -3,16 +3,21 @@ package crypto import ( "bytes" "crypto/sha256" + "fmt" secp256k1 "github.com/btcsuite/btcd/btcec" "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" "github.com/tendermint/go-wire" data "github.com/tendermint/go-wire/data" - . "github.com/tendermint/tmlibs/common" + cmn "github.com/tendermint/tmlibs/common" "golang.org/x/crypto/ripemd160" ) +// An address is a []byte, but hex-encoded even in JSON. +// []byte leaves us the option to change the address length. +type Address cmn.HexBytes + func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { if err := wire.ReadBinaryBytes(pubKeyBytes, &pubKey); err != nil { return PubKey{}, err @@ -27,7 +32,7 @@ func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { // +gen wrapper:"PubKey,Impl[PubKeyEd25519,PubKeySecp256k1],ed25519,secp256k1" type PubKeyInner interface { AssertIsPubKeyInner() - Address() []byte + Address() Address Bytes() []byte KeyString() string VerifyBytes(msg []byte, sig Signature) bool @@ -44,17 +49,17 @@ type PubKeyEd25519 [32]byte func (pubKey PubKeyEd25519) AssertIsPubKeyInner() {} -func (pubKey PubKeyEd25519) Address() []byte { +func (pubKey PubKeyEd25519) Address() Address { w, n, err := new(bytes.Buffer), new(int), new(error) wire.WriteBinary(pubKey[:], w, n, err) if *err != nil { - PanicCrisis(*err) + panic(*err) } // append type byte encodedPubkey := append([]byte{TypeEd25519}, w.Bytes()...) hasher := ripemd160.New() hasher.Write(encodedPubkey) // does not error - return hasher.Sum(nil) + return Address(hasher.Sum(nil)) } func (pubKey PubKeyEd25519) Bytes() []byte { @@ -95,13 +100,13 @@ func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte { } func (pubKey PubKeyEd25519) String() string { - return Fmt("PubKeyEd25519{%X}", pubKey[:]) + return fmt.Sprintf("PubKeyEd25519{%X}", pubKey[:]) } // Must return the full bytes in hex. // Used for map keying, etc. func (pubKey PubKeyEd25519) KeyString() string { - return Fmt("%X", pubKey[:]) + return fmt.Sprintf("%X", pubKey[:]) } func (pubKey PubKeyEd25519) Equals(other PubKey) bool { @@ -124,14 +129,14 @@ type PubKeySecp256k1 [33]byte func (pubKey PubKeySecp256k1) AssertIsPubKeyInner() {} // Implements Bitcoin style addresses: RIPEMD160(SHA256(pubkey)) -func (pubKey PubKeySecp256k1) Address() []byte { +func (pubKey PubKeySecp256k1) Address() Address { hasherSHA256 := sha256.New() hasherSHA256.Write(pubKey[:]) // does not error sha := hasherSHA256.Sum(nil) hasherRIPEMD160 := ripemd160.New() hasherRIPEMD160.Write(sha) // does not error - return hasherRIPEMD160.Sum(nil) + return Address(hasherRIPEMD160.Sum(nil)) } func (pubKey PubKeySecp256k1) Bytes() []byte { @@ -168,13 +173,13 @@ func (p *PubKeySecp256k1) UnmarshalJSON(enc []byte) error { } func (pubKey PubKeySecp256k1) String() string { - return Fmt("PubKeySecp256k1{%X}", pubKey[:]) + return fmt.Sprintf("PubKeySecp256k1{%X}", pubKey[:]) } // Must return the full bytes in hex. // Used for map keying, etc. func (pubKey PubKeySecp256k1) KeyString() string { - return Fmt("%X", pubKey[:]) + return fmt.Sprintf("%X", pubKey[:]) } func (pubKey PubKeySecp256k1) Equals(other PubKey) bool { diff --git a/pub_key_test.go b/pub_key_test.go index 097c5ea3b..95c82534d 100644 --- a/pub_key_test.go +++ b/pub_key_test.go @@ -27,7 +27,8 @@ func TestPubKeySecp256k1Address(t *testing.T) { for _, d := range secpDataTable { privB, _ := hex.DecodeString(d.priv) pubB, _ := hex.DecodeString(d.pub) - addrB, _, _ := base58.CheckDecode(d.addr) + addrBbz, _, _ := base58.CheckDecode(d.addr) + addrB := Address(addrBbz) var priv PrivKeySecp256k1 copy(priv[:], privB) From 87f2005fa88af1311c4cbc34f3593461e85809bc Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 29 Dec 2017 22:53:27 -0500 Subject: [PATCH 183/287] hd: comments and some cleanup --- hd/address.go | 144 +++++++++++++++++++++++++++++++++----------------- hd/hd_test.go | 2 +- 2 files changed, 97 insertions(+), 49 deletions(-) diff --git a/hd/address.go b/hd/address.go index f59876739..9511ffad2 100644 --- a/hd/address.go +++ b/hd/address.go @@ -21,19 +21,30 @@ import ( "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcutil/base58" - "github.com/tendermint/go-crypto" "golang.org/x/crypto/ripemd160" ) -func ComputeAddress(pubKeyHex string, chainHex string, path string, index int32) string { +/* + + This file implements BIP32 HD wallets. + Note it only works for SECP256k1 keys. + It also includes some Bitcoin specific utility functions. + +*/ + +// ComputeBTCAddress returns the BTC address using the pubKeyHex and chainCodeHex +// for the given path and index. +func ComputeBTCAddress(pubKeyHex string, chainCodeHex string, path string, index int32) string { pubKeyBytes := DerivePublicKeyForPath( HexDecode(pubKeyHex), - HexDecode(chainHex), + HexDecode(chainCodeHex), fmt.Sprintf("%v/%v", path, index), ) - return AddrFromPubKeyBytes(pubKeyBytes) + return BTCAddrFromPubKeyBytes(pubKeyBytes) } +// ComputePrivateKey returns the private key using the master mprivHex and chainCodeHex +// for the given path and index. func ComputePrivateKey(mprivHex string, chainHex string, path string, index int32) string { privKeyBytes := DerivePrivateKeyForPath( HexDecode(mprivHex), @@ -43,12 +54,14 @@ func ComputePrivateKey(mprivHex string, chainHex string, path string, index int3 return HexEncode(privKeyBytes) } -func ComputeAddressForPrivKey(privKey string) string { +// ComputeBTCAddressForPrivKey returns the Bitcoin address for the given privKey. +func ComputeBTCAddressForPrivKey(privKey string) string { pubKeyBytes := PubKeyBytesFromPrivKeyBytes(HexDecode(privKey), true) - return AddrFromPubKeyBytes(pubKeyBytes) + return BTCAddrFromPubKeyBytes(pubKeyBytes) } -func SignMessage(privKey string, message string, compress bool) string { +// SignBTCMessage signs a "Bitcoin Signed Message". +func SignBTCMessage(privKey string, message string, compress bool) string { prefixBytes := []byte("Bitcoin Signed Message:\n") messageBytes := []byte(message) bytes := []byte{} @@ -67,25 +80,28 @@ func SignMessage(privKey string, message string, compress bool) string { PublicKey: ecdsaPubKey, D: new(big.Int).SetBytes(privKeyBytes), } - sigbytes, err := btcec.SignCompact(btcec.S256(), ecdsaPrivKey, crypto.Sha256(crypto.Sha256(bytes)), compress) + sigbytes, err := btcec.SignCompact(btcec.S256(), ecdsaPrivKey, CalcHash256(bytes), compress) if err != nil { panic(err) } return base64.StdEncoding.EncodeToString(sigbytes) } -// returns MPK, Chain, and master secret in hex. -func ComputeMastersFromSeed(seed string) (string, string, string, string) { - secret, chain := I64([]byte("Bitcoin seed"), []byte(seed)) +// ComputeMastersFromSeed returns the master public key, master secret, and chain code in hex. +func ComputeMastersFromSeed(seed string) (string, string, string) { + key, data := []byte("Bitcoin seed"), []byte(seed) + secret, chain := I64(key, data) pubKeyBytes := PubKeyBytesFromPrivKeyBytes(secret, true) - return HexEncode(pubKeyBytes), HexEncode(secret), HexEncode(chain), HexEncode(secret) + return HexEncode(pubKeyBytes), HexEncode(secret), HexEncode(chain) } +// ComputeWIF returns the privKey in Wallet Import Format. func ComputeWIF(privKey string, compress bool) string { return WIFFromPrivKeyBytes(HexDecode(privKey), compress) } -func ComputeTxId(rawTxHex string) string { +// ComputeBTCTxId returns the bitcoin transaction ID. +func ComputeBTCTxId(rawTxHex string) string { return HexEncode(ReverseBytes(CalcHash256(HexDecode(rawTxHex)))) } @@ -103,7 +119,11 @@ func printKeyInfo(privKeyBytes []byte, pubKeyBytes []byte, chain []byte) { } */ -func DerivePrivateKeyForPath(privKeyBytes []byte, chain []byte, path string) []byte { +//------------------------------------------------------------------- + +// DerivePrivateKeyForPath derives the private key by following the path from privKeyBytes, +// using the given chainCode. +func DerivePrivateKeyForPath(privKeyBytes []byte, chainCode []byte, path string) []byte { data := privKeyBytes parts := strings.Split(path, "/") for _, part := range parts { @@ -119,13 +139,15 @@ func DerivePrivateKeyForPath(privKeyBytes []byte, chain []byte, path string) []b if i < 0 { panic(errors.New("index too large.")) } - data, chain = DerivePrivateKey(data, chain, uint32(i), prime) + data, chainCode = DerivePrivateKey(data, chainCode, uint32(i), prime) //printKeyInfo(data, nil, chain) } return data } -func DerivePublicKeyForPath(pubKeyBytes []byte, chain []byte, path string) []byte { +// DerivePublicKeyForPath derives the public key by following the path from pubKeyBytes +// using the given chainCode. +func DerivePublicKeyForPath(pubKeyBytes []byte, chainCode []byte, path string) []byte { data := pubKeyBytes parts := strings.Split(path, "/") for _, part := range parts { @@ -140,36 +162,42 @@ func DerivePublicKeyForPath(pubKeyBytes []byte, chain []byte, path string) []byt if i < 0 { panic(errors.New("index too large.")) } - data, chain = DerivePublicKey(data, chain, uint32(i)) - //printKeyInfo(nil, data, chain) + data, chainCode = DerivePublicKey(data, chainCode, uint32(i)) + //printKeyInfo(nil, data, chainCode) } return data } -func DerivePrivateKey(privKeyBytes []byte, chain []byte, i uint32, prime bool) ([]byte, []byte) { +// DerivePrivateKey derives the private key with index and chainCode. +// If prime is true, the derivation is 'hardened'. +// It returns the new private key and new chain code. +func DerivePrivateKey(privKeyBytes []byte, chainCode []byte, index uint32, prime bool) ([]byte, []byte) { var data []byte if prime { - i = i | 0x80000000 + index = index | 0x80000000 data = append([]byte{byte(0)}, privKeyBytes...) } else { public := PubKeyBytesFromPrivKeyBytes(privKeyBytes, true) data = public } - data = append(data, uint32ToBytes(i)...) - data2, chain2 := I64(chain, data) + data = append(data, uint32ToBytes(index)...) + data2, chainCode2 := I64(chainCode, data) x := addScalars(privKeyBytes, data2) - return x, chain2 + return x, chainCode2 } -func DerivePublicKey(pubKeyBytes []byte, chain []byte, i uint32) ([]byte, []byte) { +// DerivePublicKey derives the public key with index and chainCode. +// It returns the new public key and new chain code. +func DerivePublicKey(pubKeyBytes []byte, chainCode []byte, index uint32) ([]byte, []byte) { data := []byte{} data = append(data, pubKeyBytes...) - data = append(data, uint32ToBytes(i)...) - data2, chain2 := I64(chain, data) + data = append(data, uint32ToBytes(index)...) + data2, chainCode2 := I64(chainCode, data) data2p := PubKeyBytesFromPrivKeyBytes(data2, true) - return addPoints(pubKeyBytes, data2p), chain2 + return addPoints(pubKeyBytes, data2p), chainCode2 } +// eliptic curve pubkey addition func addPoints(a []byte, b []byte) []byte { ap, err := btcec.ParsePubKey(a, btcec.S256()) if err != nil { @@ -188,6 +216,7 @@ func addPoints(a []byte, b []byte) []byte { return sum.SerializeCompressed() } +// modular big endian addition func addScalars(a []byte, b []byte) []byte { aInt := new(big.Int).SetBytes(a) bInt := new(big.Int).SetBytes(b) @@ -204,15 +233,21 @@ func uint32ToBytes(i uint32) []byte { return b[:] } +//------------------------------------------------------------------- + +// HexEncode encodes b in hex. func HexEncode(b []byte) string { return hex.EncodeToString(b) } +// HexDecode hex decodes the str. If str is not valid hex +// it will return an empty byte slice. func HexDecode(str string) []byte { b, _ := hex.DecodeString(str) return b } +// I64 returns the two halfs of the SHA512 HMAC of key and data. func I64(key []byte, data []byte) ([]byte, []byte) { mac := hmac.New(sha512.New, key) mac.Write(data) @@ -220,27 +255,36 @@ func I64(key []byte, data []byte) ([]byte, []byte) { return I[:32], I[32:] } -// This returns a Bitcoin-like address. -func AddrFromPubKeyBytes(pubKeyBytes []byte) string { - prefix := byte(0x00) // TODO Make const or configurable +//------------------------------------------------------------------- + +const ( + btcPrefixPubKeyHash = byte(0x00) + btcPrefixPrivKey = byte(0x80) +) + +// BTCAddrFromPubKeyBytes returns a B58 encoded Bitcoin mainnet address. +func BTCAddrFromPubKeyBytes(pubKeyBytes []byte) string { + versionPrefix := btcPrefixPubKeyHash // TODO Make const or configurable h160 := CalcHash160(pubKeyBytes) - h160 = append([]byte{prefix}, h160...) + h160 = append([]byte{versionPrefix}, h160...) checksum := CalcHash256(h160) b := append(h160, checksum[:4]...) return base58.Encode(b) } -func AddrBytesFromPubKeyBytes(pubKeyBytes []byte) (addrBytes []byte, checksum []byte) { - prefix := byte(0x00) // TODO Make const or configurable +// BTCAddrBytesFromPubKeyBytes returns a hex Bitcoin mainnet address and its checksum. +func BTCAddrBytesFromPubKeyBytes(pubKeyBytes []byte) (addrBytes []byte, checksum []byte) { + versionPrefix := btcPrefixPubKeyHash // TODO Make const or configurable h160 := CalcHash160(pubKeyBytes) - _h160 := append([]byte{prefix}, h160...) + _h160 := append([]byte{versionPrefix}, h160...) checksum = CalcHash256(_h160)[:4] return h160, checksum } +// WIFFromPrivKeyBytes returns the privKeyBytes in Wallet Import Format. func WIFFromPrivKeyBytes(privKeyBytes []byte, compress bool) string { - prefix := byte(0x80) // TODO Make const or configurable - bytes := append([]byte{prefix}, privKeyBytes...) + versionPrefix := btcPrefixPrivKey // TODO Make const or configurable + bytes := append([]byte{versionPrefix}, privKeyBytes...) if compress { bytes = append(bytes, byte(1)) } @@ -249,6 +293,7 @@ func WIFFromPrivKeyBytes(privKeyBytes []byte, compress bool) string { return base58.Encode(bytes) } +// PubKeyBytesFromPrivKeyBytes returns the optionally compressed public key bytes. func PubKeyBytesFromPrivKeyBytes(privKeyBytes []byte, compress bool) (pubKeyBytes []byte) { x, y := btcec.S256().ScalarBaseMult(privKeyBytes) pub := &btcec.PublicKey{ @@ -263,27 +308,30 @@ func PubKeyBytesFromPrivKeyBytes(privKeyBytes []byte, compress bool) (pubKeyByte return pub.SerializeUncompressed() } -// Calculate the hash of hasher over buf. -func CalcHash(buf []byte, hasher hash.Hash) []byte { - hasher.Write(buf) +//-------------------------------------------------------------- + +// CalcHash returns the hash of data using hasher. +func CalcHash(data []byte, hasher hash.Hash) []byte { + hasher.Write(data) return hasher.Sum(nil) } -// calculate hash160 which is ripemd160(sha256(data)) -func CalcHash160(buf []byte) []byte { - return CalcHash(CalcHash(buf, sha256.New()), ripemd160.New()) +// CalcHash160 returns the ripemd160(sha256(data)). +func CalcHash160(data []byte) []byte { + return CalcHash(CalcHash(data, sha256.New()), ripemd160.New()) } -// calculate hash256 which is sha256(sha256(data)) -func CalcHash256(buf []byte) []byte { - return CalcHash(CalcHash(buf, sha256.New()), sha256.New()) +// CalcHash256 returns the sha256(sha256(data)). +func CalcHash256(data []byte) []byte { + return CalcHash(CalcHash(data, sha256.New()), sha256.New()) } -// calculate sha512(data) -func CalcSha512(buf []byte) []byte { - return CalcHash(buf, sha512.New()) +// CalcSha512 returns the sha512(data). +func CalcSha512(data []byte) []byte { + return CalcHash(data, sha512.New()) } +// ReverseBytes returns the buf in the opposite order func ReverseBytes(buf []byte) []byte { var res []byte if len(buf) == 0 { diff --git a/hd/hd_test.go b/hd/hd_test.go index 0ec47f5c3..c9e540ad5 100644 --- a/hd/hd_test.go +++ b/hd/hd_test.go @@ -112,7 +112,7 @@ func ifExit(err error, n int) { func gocrypto(seed []byte) ([]byte, []byte, []byte) { - _, priv, ch, _ := ComputeMastersFromSeed(string(seed)) + _, priv, ch := ComputeMastersFromSeed(string(seed)) privBytes := DerivePrivateKeyForPath( HexDecode(priv), From 7c77f6b2da6e51c1a4f07544cf616fa4a1d6bc81 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 30 Dec 2017 11:39:59 -0500 Subject: [PATCH 184/287] move hd into keys/hd --- {hd => keys/hd}/address.go | 0 {hd => keys/hd}/address_test.go | 0 {hd => keys/hd}/hd_test.go | 0 {hd => keys/hd}/test.json | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename {hd => keys/hd}/address.go (100%) rename {hd => keys/hd}/address_test.go (100%) rename {hd => keys/hd}/hd_test.go (100%) rename {hd => keys/hd}/test.json (100%) diff --git a/hd/address.go b/keys/hd/address.go similarity index 100% rename from hd/address.go rename to keys/hd/address.go diff --git a/hd/address_test.go b/keys/hd/address_test.go similarity index 100% rename from hd/address_test.go rename to keys/hd/address_test.go diff --git a/hd/hd_test.go b/keys/hd/hd_test.go similarity index 100% rename from hd/hd_test.go rename to keys/hd/hd_test.go diff --git a/hd/test.json b/keys/hd/test.json similarity index 100% rename from hd/test.json rename to keys/hd/test.json From 1f8e66fdb3c34c697b8cadf469775a61ad9513af Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Thu, 21 Dec 2017 19:43:33 -0500 Subject: [PATCH 185/287] nano: update comments --- nano/keys.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/nano/keys.go b/nano/keys.go index a6d3ea8e4..b50efd7ec 100644 --- a/nano/keys.go +++ b/nano/keys.go @@ -33,21 +33,21 @@ func getLedger() (*ledger.Ledger, error) { return device, err } -func signLedger(device *ledger.Ledger, msg []byte) (pk crypto.PubKey, sig crypto.Signature, err error) { +func signLedger(device *ledger.Ledger, msg []byte) (pub crypto.PubKey, sig crypto.Signature, err error) { var resp []byte packets := generateSignRequests(msg) for _, pack := range packets { resp, err = device.Exchange(pack, Timeout) if err != nil { - return pk, sig, err + return pub, sig, err } } // the last call is the result we want and needs to be parsed key, bsig, err := parseDigest(resp) if err != nil { - return pk, sig, err + return pub, sig, err } var b [32]byte @@ -64,9 +64,9 @@ type PrivKeyLedgerEd25519 struct { CachedPubKey crypto.PubKey } -// NewPrivKeyLedgerEd25519Ed25519 will generate a new key and store the +// NewPrivKeyLedgerEd25519 will generate a new key and store the // public key for later use. -func NewPrivKeyLedgerEd25519Ed25519() (crypto.PrivKey, error) { +func NewPrivKeyLedgerEd25519() (crypto.PrivKey, error) { var pk PrivKeyLedgerEd25519 // getPubKey will cache the pubkey for later use, // this allows us to return an error early if the ledger @@ -94,13 +94,13 @@ func (pk *PrivKeyLedgerEd25519) ValidateKey() error { // AssertIsPrivKeyInner fulfils PrivKey Interface func (pk *PrivKeyLedgerEd25519) AssertIsPrivKeyInner() {} -// Bytes fulfils pk Interface - stores the cached pubkey so we can verify +// Bytes fulfils PrivKey Interface - but it stores the cached pubkey so we can verify // the same key when we reconnect to a ledger func (pk *PrivKeyLedgerEd25519) Bytes() []byte { return wire.BinaryBytes(pk.Wrap()) } -// Sign calls the ledger and stores the pk for future use +// Sign calls the ledger and stores the PubKey for future use // // XXX/TODO: panics if there is an error communicating with the ledger. // From f3f49c23620505f50eb0e0398cb9b1837046e201 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 30 Dec 2017 16:46:58 -0500 Subject: [PATCH 186/287] keys/words --- keys/keybase.go | 9 +++++---- keys/keybase_test.go | 15 ++++++++------- keys/{ => words}/ecc.go | 2 +- keys/{ => words}/ecc_test.go | 2 +- keys/{ => words}/wordcodec.go | 4 ++-- keys/{ => words}/wordcodec_test.go | 2 +- keys/{ => words}/wordcodecbench_test.go | 2 +- keys/{ => words}/wordlist/chinese_simplified.txt | 0 keys/{ => words}/wordlist/english.txt | 0 keys/{ => words}/wordlist/japanese.txt | 0 keys/{ => words}/wordlist/spanish.txt | 0 keys/{ => words}/wordlist/wordlist.go | 0 12 files changed, 19 insertions(+), 17 deletions(-) rename keys/{ => words}/ecc.go (99%) rename keys/{ => words}/ecc_test.go (98%) rename keys/{ => words}/wordcodec.go (98%) rename keys/{ => words}/wordcodec_test.go (99%) rename keys/{ => words}/wordcodecbench_test.go (98%) rename keys/{ => words}/wordlist/chinese_simplified.txt (100%) rename keys/{ => words}/wordlist/english.txt (100%) rename keys/{ => words}/wordlist/japanese.txt (100%) rename keys/{ => words}/wordlist/spanish.txt (100%) rename keys/{ => words}/wordlist/wordlist.go (100%) diff --git a/keys/keybase.go b/keys/keybase.go index c68564d5a..b5f7a3c5e 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -8,6 +8,7 @@ import ( crypto "github.com/tendermint/go-crypto" dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/go-crypto/keys/words" "github.com/tendermint/go-crypto/nano" ) @@ -19,10 +20,10 @@ import ( // a full-featured key manager type dbKeybase struct { db dbm.DB - codec Codec + codec words.Codec } -func New(db dbm.DB, codec Codec) dbKeybase { +func New(db dbm.DB, codec words.Codec) dbKeybase { return dbKeybase{ db: db, codec: codec, @@ -214,7 +215,7 @@ func generate(algo string, secret []byte) (crypto.PrivKey, error) { case crypto.NameSecp256k1: return crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap(), nil case nano.NameLedgerEd25519: - return nano.NewPrivKeyLedgerEd25519Ed25519() + return nano.NewPrivKeyLedgerEd25519() default: err := errors.Errorf("Cannot generate keys for algorithm: %s", algo) return crypto.PrivKey{}, err @@ -228,7 +229,7 @@ func generateByType(typ byte, secret []byte) (crypto.PrivKey, error) { case crypto.TypeSecp256k1: return crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap(), nil case nano.TypeLedgerEd25519: - return nano.NewPrivKeyLedgerEd25519Ed25519() + return nano.NewPrivKeyLedgerEd25519() default: err := errors.Errorf("Cannot generate keys for algorithm: %X", typ) return crypto.PrivKey{}, err diff --git a/keys/keybase_test.go b/keys/keybase_test.go index 72476a02e..5b4d11303 100644 --- a/keys/keybase_test.go +++ b/keys/keybase_test.go @@ -13,6 +13,7 @@ import ( crypto "github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto/keys" + "github.com/tendermint/go-crypto/keys/words" "github.com/tendermint/go-crypto/nano" ) @@ -23,7 +24,7 @@ func TestKeyManagement(t *testing.T) { // make the storage with reasonable defaults cstore := keys.New( dbm.NewMemDB(), - keys.MustLoadCodec("english"), + words.MustLoadCodec("english"), ) algo := crypto.NameEd25519 @@ -91,7 +92,7 @@ func TestSignVerify(t *testing.T) { // make the storage with reasonable defaults cstore := keys.New( dbm.NewMemDB(), - keys.MustLoadCodec("english"), + words.MustLoadCodec("english"), ) algo := crypto.NameSecp256k1 @@ -165,7 +166,7 @@ func TestSignWithLedger(t *testing.T) { // make the storage with reasonable defaults cstore := keys.New( dbm.NewMemDB(), - keys.MustLoadCodec("english"), + words.MustLoadCodec("english"), ) n := "nano-s" p := "hard2hack" @@ -219,7 +220,7 @@ func TestImportUnencrypted(t *testing.T) { // make the storage with reasonable defaults cstore := keys.New( dbm.NewMemDB(), - keys.MustLoadCodec("english"), + words.MustLoadCodec("english"), ) key := crypto.GenPrivKeyEd25519FromSecret(cmn.RandBytes(16)).Wrap() @@ -245,7 +246,7 @@ func TestAdvancedKeyManagement(t *testing.T) { // make the storage with reasonable defaults cstore := keys.New( dbm.NewMemDB(), - keys.MustLoadCodec("english"), + words.MustLoadCodec("english"), ) algo := crypto.NameSecp256k1 @@ -288,7 +289,7 @@ func TestSeedPhrase(t *testing.T) { // make the storage with reasonable defaults cstore := keys.New( dbm.NewMemDB(), - keys.MustLoadCodec("english"), + words.MustLoadCodec("english"), ) algo := crypto.NameEd25519 @@ -319,7 +320,7 @@ func ExampleNew() { // Select the encryption and storage for your cryptostore cstore := keys.New( dbm.NewMemDB(), - keys.MustLoadCodec("english"), + words.MustLoadCodec("english"), ) ed := crypto.NameEd25519 sec := crypto.NameSecp256k1 diff --git a/keys/ecc.go b/keys/words/ecc.go similarity index 99% rename from keys/ecc.go rename to keys/words/ecc.go index c1ac258fe..c511ad6e4 100644 --- a/keys/ecc.go +++ b/keys/words/ecc.go @@ -1,4 +1,4 @@ -package keys +package words import ( "encoding/binary" diff --git a/keys/ecc_test.go b/keys/words/ecc_test.go similarity index 98% rename from keys/ecc_test.go rename to keys/words/ecc_test.go index 6d3e3bec8..9e1772b9f 100644 --- a/keys/ecc_test.go +++ b/keys/words/ecc_test.go @@ -1,4 +1,4 @@ -package keys +package words import ( "testing" diff --git a/keys/wordcodec.go b/keys/words/wordcodec.go similarity index 98% rename from keys/wordcodec.go rename to keys/words/wordcodec.go index c551e54ce..fbf32160f 100644 --- a/keys/wordcodec.go +++ b/keys/words/wordcodec.go @@ -1,4 +1,4 @@ -package keys +package words import ( "math/big" @@ -6,7 +6,7 @@ import ( "github.com/pkg/errors" - "github.com/tendermint/go-crypto/keys/wordlist" + "github.com/tendermint/go-crypto/keys/words/wordlist" ) const BankSize = 2048 diff --git a/keys/wordcodec_test.go b/keys/words/wordcodec_test.go similarity index 99% rename from keys/wordcodec_test.go rename to keys/words/wordcodec_test.go index f79ebcad0..367e3799a 100644 --- a/keys/wordcodec_test.go +++ b/keys/words/wordcodec_test.go @@ -1,4 +1,4 @@ -package keys +package words import ( "testing" diff --git a/keys/wordcodecbench_test.go b/keys/words/wordcodecbench_test.go similarity index 98% rename from keys/wordcodecbench_test.go rename to keys/words/wordcodecbench_test.go index e100a443a..04417a936 100644 --- a/keys/wordcodecbench_test.go +++ b/keys/words/wordcodecbench_test.go @@ -1,4 +1,4 @@ -package keys +package words import ( "testing" diff --git a/keys/wordlist/chinese_simplified.txt b/keys/words/wordlist/chinese_simplified.txt similarity index 100% rename from keys/wordlist/chinese_simplified.txt rename to keys/words/wordlist/chinese_simplified.txt diff --git a/keys/wordlist/english.txt b/keys/words/wordlist/english.txt similarity index 100% rename from keys/wordlist/english.txt rename to keys/words/wordlist/english.txt diff --git a/keys/wordlist/japanese.txt b/keys/words/wordlist/japanese.txt similarity index 100% rename from keys/wordlist/japanese.txt rename to keys/words/wordlist/japanese.txt diff --git a/keys/wordlist/spanish.txt b/keys/words/wordlist/spanish.txt similarity index 100% rename from keys/wordlist/spanish.txt rename to keys/words/wordlist/spanish.txt diff --git a/keys/wordlist/wordlist.go b/keys/words/wordlist/wordlist.go similarity index 100% rename from keys/wordlist/wordlist.go rename to keys/words/wordlist/wordlist.go From bd30cb4de9dbc28273e1c864509c795e7c8576ef Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 30 Dec 2017 17:02:18 -0500 Subject: [PATCH 187/287] keys/keybase.go: comments and fixes --- keys/keybase.go | 146 +++++++++++++++++++++---------------------- keys/keybase_test.go | 14 ++--- keys/types.go | 4 +- 3 files changed, 81 insertions(+), 83 deletions(-) diff --git a/keys/keybase.go b/keys/keybase.go index b5f7a3c5e..c72518748 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -32,59 +32,61 @@ func New(db dbm.DB, codec words.Codec) dbKeybase { var _ Keybase = dbKeybase{} -// Create adds a new key to the storage engine, returning error if -// another key already stored under this name -// -// algo must be a supported go-crypto algorithm: ed25519, secp256k1 -func (kb dbKeybase) Create(name, passphrase, algo string) (Info, string, error) { - // 128-bits are the all the randomness we can make use of +// Create generates a new key and persists it storage, encrypted using the passphrase. +// It returns the generated seedphrase (mnemonic) and the key Info. +// It returns an error if it fails to generate a key for the given algo type, +// or if another key is already stored under the same name. +func (kb dbKeybase) Create(name, passphrase, algo string) (string, Info, error) { + // NOTE: secret is SHA256 hashed by secp256k1 and ed25519. + // 16 byte secret corresponds to 12 BIP39 words. + // XXX: Ledgers use 24 words now - should we ? secret := crypto.CRandBytes(16) key, err := generate(algo, secret) if err != nil { - return Info{}, "", err + return "", Info{}, err } + // encrypt and persist the key public := kb.writeKey(key, name, passphrase) - // we append the type byte to the serialized secret to help with recovery - // ie [secret] = [secret] + [type] - typ := key.Bytes()[0] - secret = append(secret, typ) - - seed, err := kb.codec.BytesToWords(secret) - phrase := strings.Join(seed, " ") - return public, phrase, err + // return the mnemonic phrase + words, err := kb.codec.BytesToWords(secret) + seedphrase := strings.Join(words, " ") + return seedphrase, public, err } -// Recover takes a seed phrase and tries to recover the private key. -// -// If the seed phrase is valid, it will create the private key and store -// it under name, protected by passphrase. -// -// Result similar to New(), except it doesn't return the seed again... -func (kb dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { - words := strings.Split(strings.TrimSpace(seedphrase), " ") - secret, err := kb.codec.WordsToBytes(words) +// Recover converts a seedphrase to a private key and persists it, encrypted with the given passphrase. +// Functions like Create, but seedphrase is input not output. +func (kb dbKeybase) Recover(name, passphrase, algo string, seedphrase string) (Info, error) { + + key, err := kb.SeedToPrivKey(algo, seedphrase) if err != nil { return Info{}, err } - // secret is comprised of the actual secret with the type appended - // ie [secret] = [secret] + [type] - l := len(secret) - secret, typ := secret[:l-1], secret[l-1] + // Valid seedphrase. Encrypt key and persist to disk. + public := kb.writeKey(key, name, passphrase) + return public, nil +} - key, err := generateByType(typ, secret) +// SeedToPrivKey returns the private key corresponding to a seedphrase +// without persisting the private key. +// TODO: enable the keybase to just hold these in memory so we can sign without persisting (?) +func (kb dbKeybase) SeedToPrivKey(algo, seedphrase string) (crypto.PrivKey, error) { + words := strings.Split(strings.TrimSpace(seedphrase), " ") + secret, err := kb.codec.WordsToBytes(words) if err != nil { - return Info{}, err + return crypto.PrivKey{}, err } - // d00d, it worked! create the bugger.... - public := kb.writeKey(key, name, passphrase) - return public, err + key, err := generate(algo, secret) + if err != nil { + return crypto.PrivKey{}, err + } + return key, nil } -// List loads the keys from the storage and enforces alphabetical order +// List returns the keys from storage in alphabetical order. func (kb dbKeybase) List() ([]Info, error) { var res []Info iter := kb.db.Iterator(nil, nil) @@ -102,20 +104,19 @@ func (kb dbKeybase) List() ([]Info, error) { return res, nil } -// Get returns the public information about one key +// Get returns the public information about one key. func (kb dbKeybase) Get(name string) (Info, error) { bs := kb.db.Get(pubName(name)) return readInfo(bs) } -// Sign will modify the Signable in order to attach a valid signature with -// this public key -// -// If no key for this name, or the passphrase doesn't match, returns an error +// Sign signs the msg with the named key. +// It returns an error if the key doesn't exist or the decryption fails. +// TODO: what if leddger fails ? func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signature, pk crypto.PubKey, err error) { var key crypto.PrivKey - bs := kb.db.Get(privName(name)) - key, err = unarmorDecryptPrivKey(string(bs), passphrase) + armorStr := kb.db.Get(privName(name)) + key, err = unarmorDecryptPrivKey(string(armorStr), passphrase) if err != nil { return } @@ -125,15 +126,15 @@ func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signat return } -// Export decodes the private key with the current password, encodes -// it with a secure one-time password and generates a sequence that can be -// Imported by another dbKeybase +// Export decodes the private key with the current password, encrypts +// it with a secure one-time password and generates an armored private key +// that can be Imported by another dbKeybase. // // This is designed to copy from one device to another, or provide backups // during version updates. func (kb dbKeybase) Export(name, oldpass, transferpass string) ([]byte, error) { - bs := kb.db.Get(privName(name)) - key, err := unarmorDecryptPrivKey(string(bs), oldpass) + armorStr := kb.db.Get(privName(name)) + key, err := unarmorDecryptPrivKey(string(armorStr), oldpass) if err != nil { return nil, err } @@ -141,11 +142,11 @@ func (kb dbKeybase) Export(name, oldpass, transferpass string) ([]byte, error) { if transferpass == "" { return key.Bytes(), nil } - res := encryptArmorPrivKey(key, transferpass) - return []byte(res), nil + armorBytes := encryptArmorPrivKey(key, transferpass) + return []byte(armorBytes), nil } -// Import accepts bytes generated by Export along with the same transferpass +// Import accepts bytes generated by Export along with the same transferpass. // If they are valid, it stores the password under the given name with the // new passphrase. func (kb dbKeybase) Import(name, newpass, transferpass string, data []byte) (err error) { @@ -164,7 +165,7 @@ func (kb dbKeybase) Import(name, newpass, transferpass string, data []byte) (err } // Delete removes key forever, but we must present the -// proper passphrase before deleting it (for security) +// proper passphrase before deleting it (for security). func (kb dbKeybase) Delete(name, passphrase string) error { // verify we have the proper password before deleting bs := kb.db.Get(privName(name)) @@ -177,10 +178,10 @@ func (kb dbKeybase) Delete(name, passphrase string) error { return nil } -// Update changes the passphrase with which a already stored key is encoded. +// Update changes the passphrase with which an already stored key is encrypted. // -// oldpass must be the current passphrase used for encoding, newpass will be -// the only valid passphrase from this time forward +// oldpass must be the current passphrase used for encryption, newpass will be +// the only valid passphrase from this time forward. func (kb dbKeybase) Update(name, oldpass, newpass string) error { bs := kb.db.Get(privName(name)) key, err := unarmorDecryptPrivKey(string(bs), oldpass) @@ -188,26 +189,37 @@ func (kb dbKeybase) Update(name, oldpass, newpass string) error { return err } - // we must delete first, as Putting over an existing name returns an error - kb.db.DeleteSync(pubName(name)) - kb.db.DeleteSync(privName(name)) - kb.writeKey(key, name, newpass) + // Generate the public bytes and the encrypted privkey + public := info(name, key) + private := encryptArmorPrivKey(key, newpass) + + // We must delete first, as Putting over an existing name returns an error. + // Must be done atomically with the write or we could lose the key. + batch := kb.db.NewBatch() + batch.Delete(pubName(name)) + batch.Delete(privName(name)) + batch.Set(pubName(name), public.bytes()) + batch.Set(privName(name), []byte(private)) + batch.Write() + return nil } +//--------------------------------------------------------------------------------------- + func (kb dbKeybase) writeKey(priv crypto.PrivKey, name, passphrase string) Info { - // generate the public bytes + // Generate the public bytes and the encrypted privkey public := info(name, priv) - // generate the encrypted privkey private := encryptArmorPrivKey(priv, passphrase) - // write them both + // Write them both kb.db.SetSync(pubName(name), public.bytes()) kb.db.SetSync(privName(name), []byte(private)) return public } +// TODO: use a `type TypeKeyAlgo string` (?) func generate(algo string, secret []byte) (crypto.PrivKey, error) { switch algo { case crypto.NameEd25519: @@ -222,20 +234,6 @@ func generate(algo string, secret []byte) (crypto.PrivKey, error) { } } -func generateByType(typ byte, secret []byte) (crypto.PrivKey, error) { - switch typ { - case crypto.TypeEd25519: - return crypto.GenPrivKeyEd25519FromSecret(secret).Wrap(), nil - case crypto.TypeSecp256k1: - return crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap(), nil - case nano.TypeLedgerEd25519: - return nano.NewPrivKeyLedgerEd25519() - default: - err := errors.Errorf("Cannot generate keys for algorithm: %X", typ) - return crypto.PrivKey{}, err - } -} - func pubName(name string) []byte { return []byte(fmt.Sprintf("%s.pub", name)) } diff --git a/keys/keybase_test.go b/keys/keybase_test.go index 5b4d11303..12e5205b0 100644 --- a/keys/keybase_test.go +++ b/keys/keybase_test.go @@ -39,7 +39,7 @@ func TestKeyManagement(t *testing.T) { // create some keys _, err = cstore.Get(n1) assert.NotNil(err) - i, _, err := cstore.Create(n1, p1, algo) + _, i, err := cstore.Create(n1, p1, algo) require.Equal(n1, i.Name) require.Nil(err) _, _, err = cstore.Create(n2, p2, algo) @@ -100,10 +100,10 @@ func TestSignVerify(t *testing.T) { p1, p2 := "1234", "foobar" // create two users and get their info - i1, _, err := cstore.Create(n1, p1, algo) + _, i1, err := cstore.Create(n1, p1, algo) require.Nil(err) - i2, _, err := cstore.Create(n2, p2, algo) + _, i2, err := cstore.Create(n2, p2, algo) require.Nil(err) // let's try to sign some messages @@ -172,7 +172,7 @@ func TestSignWithLedger(t *testing.T) { p := "hard2hack" // create a nano user - c, _, err := cstore.Create(n, p, nano.NameLedgerEd25519) + _, c, err := cstore.Create(n, p, nano.NameLedgerEd25519) require.Nil(err, "%+v", err) assert.Equal(c.Name, n) _, ok := c.PubKey.Unwrap().(nano.PubKeyLedgerEd25519) @@ -297,7 +297,7 @@ func TestSeedPhrase(t *testing.T) { p1, p2 := "1234", "foobar" // make sure key works with initial password - info, seed, err := cstore.Create(n1, p1, algo) + seed, info, err := cstore.Create(n1, p1, algo) require.Nil(err, "%+v", err) assert.Equal(n1, info.Name) assert.NotEmpty(seed) @@ -309,7 +309,7 @@ func TestSeedPhrase(t *testing.T) { require.NotNil(err) // let us re-create it from the seed-phrase - newInfo, err := cstore.Recover(n2, p2, seed) + newInfo, err := cstore.Recover(n2, p2, algo, seed) require.Nil(err, "%+v", err) assert.Equal(n2, newInfo.Name) assert.Equal(info.Address(), newInfo.Address()) @@ -326,7 +326,7 @@ func ExampleNew() { sec := crypto.NameSecp256k1 // Add keys and see they return in alphabetical order - bob, _, err := cstore.Create("Bob", "friend", ed) + _, bob, err := cstore.Create("Bob", "friend", ed) if err != nil { // this should never happen fmt.Println(err) diff --git a/keys/types.go b/keys/types.go index 541234b37..fdb729e0a 100644 --- a/keys/types.go +++ b/keys/types.go @@ -38,9 +38,9 @@ type Keybase interface { // Sign some bytes Sign(name, passphrase string, msg []byte) (crypto.Signature, crypto.PubKey, error) // Create a new keypair - Create(name, passphrase, algo string) (_ Info, seedphrase string, _ error) + Create(name, passphrase, algo string) (seedphrase string, _ Info, _ error) // Recover takes a seedphrase and loads in the key - Recover(name, passphrase, seedphrase string) (Info, error) + Recover(name, passphrase, algo, seedphrase string) (Info, error) List() ([]Info, error) Get(name string) (Info, error) Update(name, oldpass, newpass string) error From 8c61bb27b74414fb0fc06cad5deb99fc2df3232e Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 30 Dec 2017 17:25:43 -0500 Subject: [PATCH 188/287] fix nano test --- nano/keys_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nano/keys_test.go b/nano/keys_test.go index 2e5142e30..fda096e29 100644 --- a/nano/keys_test.go +++ b/nano/keys_test.go @@ -83,7 +83,7 @@ func TestRealLedger(t *testing.T) { } msg := []byte("kuhehfeohg") - priv, err := NewPrivKeyLedgerEd25519Ed25519() + priv, err := NewPrivKeyLedgerEd25519() require.Nil(err, "%+v", err) pub := priv.PubKey() sig := priv.Sign(msg) @@ -123,7 +123,7 @@ func TestRealLedgerErrorHandling(t *testing.T) { // first, try to generate a key, must return an error // (no panic) - _, err := NewPrivKeyLedgerEd25519Ed25519() + _, err := NewPrivKeyLedgerEd25519() require.Error(err) led := PrivKeyLedgerEd25519{} // empty From d058d0098f63b783abe55dbafdd912a15f3e08a2 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 30 Dec 2017 17:25:55 -0500 Subject: [PATCH 189/287] keys/bcrypt --- {bcrypt => keys/bcrypt}/base64.go | 0 {bcrypt => keys/bcrypt}/bcrypt.go | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {bcrypt => keys/bcrypt}/base64.go (100%) rename {bcrypt => keys/bcrypt}/bcrypt.go (100%) diff --git a/bcrypt/base64.go b/keys/bcrypt/base64.go similarity index 100% rename from bcrypt/base64.go rename to keys/bcrypt/base64.go diff --git a/bcrypt/bcrypt.go b/keys/bcrypt/bcrypt.go similarity index 100% rename from bcrypt/bcrypt.go rename to keys/bcrypt/bcrypt.go From b31d37b480d06f817919858e34cbec3501145e5a Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 30 Dec 2017 18:25:42 -0500 Subject: [PATCH 190/287] update circle.yml --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index a37187dd9..af63a0594 100644 --- a/circle.yml +++ b/circle.yml @@ -18,4 +18,4 @@ dependencies: test: override: - "go version" - - "cd $PROJECT_PATH && make all" + - "cd $PROJECT_PATH && make get_tools && make all" From 793d7717dc0f3d25c0f7b102db564b9d6b994e6f Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 2 Jan 2018 16:25:01 -0500 Subject: [PATCH 191/287] no metalinter for now --- Makefile | 11 ++++++----- keys/mintkey.go | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 6f23f8ef7..c4a4fe30b 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,11 @@ GOTOOLS = \ github.com/Masterminds/glide \ - github.com/jteeuwen/go-bindata/go-bindata \ - gopkg.in/alecthomas/gometalinter.v2 \ -GOTOOLS_CHECK = glide go-bindata gometalinter.v2 + github.com/jteeuwen/go-bindata/go-bindata + # gopkg.in/alecthomas/gometalinter.v2 \ + # +GOTOOLS_CHECK = glide go-bindata #gometalinter.v2 -all: check get_vendor_deps build test install metalinter +all: check get_vendor_deps build test install check: check_tools @@ -34,7 +35,7 @@ check_tools: get_tools: @echo "--> Installing tools" go get -u -v $(GOTOOLS) - @gometalinter.v2 --install + #@gometalinter.v2 --install update_tools: @echo "--> Updating tools" diff --git a/keys/mintkey.go b/keys/mintkey.go index c948848be..d2724d658 100644 --- a/keys/mintkey.go +++ b/keys/mintkey.go @@ -7,7 +7,7 @@ import ( cmn "github.com/tendermint/tmlibs/common" "github.com/tendermint/go-crypto" - "github.com/tendermint/go-crypto/bcrypt" + "github.com/tendermint/go-crypto/keys/bcrypt" ) const ( From 156416fe27625bdc103aa43aeb6e909e5b9dd4df Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 2 Jan 2018 16:39:43 -0500 Subject: [PATCH 192/287] fix wordlist paths --- Makefile | 2 +- keys/words/wordcodec.go | 2 +- keys/words/wordlist/wordlist.go | 84 +++++++++++++++++---------------- 3 files changed, 45 insertions(+), 43 deletions(-) diff --git a/Makefile b/Makefile index c4a4fe30b..19d797f1d 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ check: check_tools wordlist: # Generating wordlist.go... - go-bindata -ignore ".*\.go" -o keys/wordlist/wordlist.go -pkg "wordlist" keys/wordlist/... + go-bindata -ignore ".*\.go" -o keys/words/wordlist/wordlist.go -pkg "wordlist" keys/words/wordlist/... build: wordlist # Nothing else to build! diff --git a/keys/words/wordcodec.go b/keys/words/wordcodec.go index fbf32160f..27032ce32 100644 --- a/keys/words/wordcodec.go +++ b/keys/words/wordcodec.go @@ -61,7 +61,7 @@ func MustLoadCodec(bank string) *WordCodec { // loadBank opens a wordlist file and returns all words inside func loadBank(bank string) ([]string, error) { - filename := "keys/wordlist/" + bank + ".txt" + filename := "keys/words/wordlist/" + bank + ".txt" words, err := wordlist.Asset(filename) if err != nil { return nil, err diff --git a/keys/words/wordlist/wordlist.go b/keys/words/wordlist/wordlist.go index dd531b6dd..4efff82cb 100644 --- a/keys/words/wordlist/wordlist.go +++ b/keys/words/wordlist/wordlist.go @@ -1,9 +1,9 @@ // Code generated by go-bindata. // sources: -// keys/wordlist/chinese_simplified.txt -// keys/wordlist/english.txt -// keys/wordlist/japanese.txt -// keys/wordlist/spanish.txt +// keys/words/wordlist/chinese_simplified.txt +// keys/words/wordlist/english.txt +// keys/words/wordlist/japanese.txt +// keys/words/wordlist/spanish.txt // DO NOT EDIT! package wordlist @@ -71,82 +71,82 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _keysWordlistChinese_simplifiedTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x1c\x97\x55\x76\xeb\x30\x14\x45\xff\xf7\xa8\xc3\xcc\x49\xc3\x69\x98\xda\x86\xd9\x0e\x4c\xc6\xf7\x4a\x9a\xc5\x5b\x7e\x7f\x5d\x5d\x6d\x6c\x45\x07\xf6\x31\xdd\x04\xc1\x3d\x82\xb6\x77\x48\x7f\x45\x70\x2f\x12\x78\x29\xb4\x9f\x45\x6a\x05\x02\xcf\xc3\x7e\x3a\x04\xf7\x0d\x32\x5b\x12\xdc\x3d\x82\x7b\x8e\xe0\xfe\x83\xf4\x5e\x68\xa6\x4a\xe0\xcf\xb1\x8b\x28\x81\xdf\x44\x5b\x57\x74\x30\xc7\x34\x56\x04\xfe\x1f\xa6\x31\x44\x32\x7b\x82\x57\x1f\xe9\xef\x09\xbc\x12\x92\xf6\x90\xfd\x01\xc9\xa4\x90\xdd\x03\xcd\x54\x08\x9e\x5d\xa4\xbc\x23\xb8\xfb\x48\xb9\x8a\x3c\xce\x48\x6e\x85\x54\x0a\xc8\x6d\x4e\xf0\x18\x62\xe3\x2f\x82\x7b\x1e\xfb\x49\x23\x9b\x0a\x76\x77\x26\xf0\x96\x98\x65\x11\x37\x98\x60\x23\x05\xb4\xf9\x40\x2a\x25\x64\xd6\x45\xb6\x5d\xec\xb8\x80\x6c\x16\xe8\xe9\x0b\xcd\x46\xd0\x7d\x15\x79\xb7\x30\x7e\x19\x29\x46\x09\xee\x59\x82\x47\xf8\x99\x3d\xcc\x20\x82\xd9\x64\x71\xf1\x15\xe2\x2d\x90\xed\x15\xd3\xb8\x20\xb9\x1e\x2e\x5d\x40\x16\x31\x74\x7f\x46\x0a\x4d\xdc\x6f\x1b\x9b\xfe\x21\xf0\x0a\x98\x4a\x0a\x7b\xb9\x21\xfb\x32\x26\xbb\xc6\x94\xf6\xc8\xf6\x1b\xc9\x8d\x70\xe9\x32\xee\xff\x7b\xcf\x08\x5e\x75\x24\x73\x45\xfb\x1e\xf2\xaa\x13\xbc\x3e\x98\xd8\x83\xc0\x2f\x11\xdc\xbb\x68\xff\x0f\x29\xf9\x68\x2e\x87\x46\x96\xc8\xfc\x85\x78\x0d\xe4\x19\x41\xb6\x71\xa4\x92\xc1\x7e\xda\x48\x6f\x84\x69\x1c\x90\xe4\x95\xc0\xeb\x61\x12\x57\x24\x5b\x44\x66\x4d\x64\xb6\x46\x1b\x1f\xa4\xd7\x43\x5b\x73\x5c\x6c\x8a\x99\xbd\x09\x1e\x59\x02\x2f\x8f\x3c\x4e\xc8\x6b\x82\xe9\xdd\x91\xe4\x0a\x3b\x5e\xe1\x5a\x67\x74\x74\x23\xb8\x97\x90\xe4\x09\xa9\x24\x70\xe9\x22\xda\xdc\x63\xbc\x0f\x92\x4a\xa2\x5f\x7b\x74\x33\x45\x3e\x71\xa4\x5c\x24\x78\x8d\xd0\x76\x09\xd3\xcf\x23\xa5\x21\x52\xce\x10\x3c\x32\x48\x66\x8d\xee\x1a\x68\xa6\x49\xf0\x4a\x61\xcf\x2b\x74\xdf\xc0\xfc\xfd\x21\x95\x2a\x2e\x5a\x47\xaa\x2f\x74\x33\x43\xca\x6d\x74\x30\x46\xca\x3f\xe8\x71\x8c\xf1\xeb\xd8\xe5\x14\xd7\xda\xa2\x89\x32\xe2\x7b\x68\x3f\x83\x24\xff\xd0\xd6\x08\x73\xf2\x91\x54\x0f\x79\x67\xd0\x78\x12\x1b\x49\xa2\xfd\x08\xe6\x37\x4f\xe0\x4f\xd1\xf8\x09\xb9\x1d\x71\x91\x2e\xf2\xb8\xa2\xe5\x0a\xa6\x77\xc6\x4d\xda\x48\xb2\x8b\x59\xe5\x91\xc3\x17\x81\xd7\x40\xbf\xfb\x68\xb3\x83\x3d\x8c\x91\x6a\x1b\x37\x58\x13\xbc\x8a\x48\x72\x8e\xdc\xef\x68\x33\x8d\x46\x7c\xf4\x6f\x8c\xd4\xa3\xc8\xb3\x8c\x9e\x7d\xec\xf6\x8d\x94\x73\x98\xed\x18\x93\x0d\xef\xee\x8a\xfb\xfa\xa0\x87\x18\x36\x12\x45\x66\x67\x64\xe8\x61\x2f\x09\xec\xfb\x81\x5e\xa2\xd8\xdb\x0e\xe3\x2d\x91\x50\x7b\xbd\x37\x72\x38\x60\xfc\x21\x5a\x9a\x63\x86\x73\xec\x3b\x8e\xec\x53\x18\x3f\x81\x5d\x46\xb1\xdb\x31\x92\xf9\x45\xe6\x0f\x34\x9b\xc7\x2e\x6b\x68\x7f\x88\x8e\x1e\xd8\x6d\xe8\xc7\x0a\x92\xea\xa3\x85\x34\x92\x1e\x11\x3c\x06\x48\xc1\x43\x9e\x1e\xda\x78\x23\xa9\x13\x76\xfe\xc1\x4e\x7e\x91\xc7\x11\x89\x76\x91\x4f\x12\xcd\x84\xdf\x43\x06\xe9\x7d\x23\x99\x0e\x81\x1f\x7a\xad\x89\x16\xb7\xc8\x2c\x81\x6b\x0f\x91\x62\xe8\x8d\x0e\x36\x7b\x44\x92\x59\x5c\x6b\x85\x14\x4f\x04\x9f\x01\x7a\xf4\x91\x42\x0b\x17\x19\x61\x3a\x6f\xec\x32\x81\x89\x6f\x70\x93\x14\xc1\x3d\x8e\x86\x1e\x28\x4f\x09\xee\x7d\x64\xf7\x44\x3a\x2b\xa4\x94\x47\x3e\x2d\x82\x7b\x13\x97\xae\x22\x93\x6f\x02\x2f\x8b\x5e\x4a\xb8\xf6\x15\x3d\x3e\xd0\xc8\x00\xed\xef\xd0\xef\x28\x81\x17\xea\xa2\x85\x8d\x36\x08\xfc\x08\x76\x3b\x43\x92\x1b\x24\x79\x40\x07\x71\xb4\x71\xc5\xee\xa2\x68\xe3\x81\xde\x93\x98\x77\x09\x49\x15\x71\xe9\x34\xf6\xf5\x87\xf6\xce\x48\xf1\x0b\x37\x2d\x21\x99\x34\x9a\xad\x63\x3a\x2f\xf4\xab\x83\x8b\x0c\xb1\xb9\x03\x72\x0f\xbd\x9d\x45\xfa\x1e\xd6\xfb\xc5\xbe\x16\x04\xef\x3c\xa6\x3f\x44\x72\x63\x24\x19\x7a\x21\x8d\xee\xca\x98\xde\x16\x9b\x3e\x61\xdf\x6f\xec\x65\x8f\x59\xee\x30\x33\x0f\xbb\xdd\x22\xd3\x3d\x9a\x9b\xa3\xcd\x16\xb2\x2d\x60\x0e\x3e\x92\xfc\xc5\x2c\x7c\xa4\x58\x42\x2a\x45\xcc\x78\x8b\x66\x8b\x98\x65\x15\x79\x8e\x08\x3e\x63\xdc\xfa\x0f\x9b\x8b\x61\x77\x03\xcc\xe1\x84\x7e\x9d\x31\x6b\x0f\x49\xc6\x91\xd4\x85\xc0\xcf\xe1\x7a\x29\xf4\xbe\x26\x78\x8e\x90\xfe\x10\xbb\xbd\xa3\x9b\x39\xe6\x3d\x43\x1e\x1f\xcc\xf0\x84\xdd\xee\x71\xfd\x08\xba\xbd\x60\x46\x0d\xcc\x57\x01\xcd\x67\xd1\xef\x16\xf2\xce\x23\xe5\x5f\x82\x7b\x03\xb3\xbe\x62\x97\x31\xec\x35\x87\xf1\xd3\xd8\x69\x12\x79\x1d\x30\xdb\x16\xc1\xab\x84\x16\xa2\xb8\xe1\x89\xe0\xd9\x22\x78\x2c\x90\x7b\x1c\x99\x15\x91\xed\x03\x49\x7c\x70\x63\x1f\xd7\x49\x22\x5f\x29\xdc\xe0\x1b\xf7\x53\xc0\x7e\xbe\xd1\xe6\x06\xbd\x1d\x70\xdd\x37\xf6\x53\xc5\x0c\x3f\x48\x31\x8e\x54\x57\xc8\xb2\x81\x39\x8f\xd0\x5c\x04\x99\xa5\x91\x62\x0e\xc9\x7d\xe3\x06\x35\x4c\x3f\x8a\x64\xc2\x67\x8d\x90\x7a\x11\xe3\x2d\xd0\xc6\x0e\x9b\xf9\x43\xca\x47\x34\x11\xde\xc3\x89\xe0\x1d\xe6\xd8\x04\x79\x47\x70\xc9\x3b\x52\x4a\x21\xf7\x18\x92\xcc\x13\xbc\xbe\x70\x9d\x19\x7a\xcd\xa0\xdf\x09\xc4\xeb\x63\x96\x7b\x64\xf6\x83\xa4\x53\x98\xe3\x1b\x89\x3c\x91\xf2\x0d\x53\x4a\xa3\xad\x32\xc6\x3f\x23\x99\x1a\x2e\x92\x45\x47\x69\x24\xd5\x41\x36\x6d\x24\xd2\x41\x77\x3d\x02\xef\x88\x7c\x7e\xd1\xaf\x0c\xda\xdc\xe1\x3a\x13\x74\x38\x47\x0f\x43\xe4\x3b\xd4\xc7\x13\x53\xca\xa3\x85\xf0\xff\x9f\x48\xd2\x47\xdb\x75\xcc\x6b\x8b\x9e\x43\x5f\xc7\x30\xd9\x34\xb2\xcc\x23\xc5\x33\xc1\xbd\x8e\xc9\x5d\xb1\xb1\x23\x52\x8a\x11\x78\x7f\xd8\x5d\x0a\x17\x89\x21\x87\x6f\xa4\x9f\x42\x0a\x49\x4c\xf4\x97\xe0\x55\xc6\xee\xe3\xa8\x3f\x46\x4a\x1f\xe4\x10\xc1\x24\x97\x48\x39\x86\xf1\x26\x18\x3f\x85\x3c\xbf\x90\x4a\xf8\x19\x73\x5c\x3d\xec\xdb\x50\xa7\x73\xdc\xa2\x89\x78\x5f\xe8\xf5\x88\x6c\xdb\xc8\xfb\x86\xeb\x96\x31\xad\x24\x36\x5f\x46\x66\x07\x64\xdf\x40\x37\x61\x7e\x1d\x71\xc9\x22\x32\x3f\xe1\xfc\x04\x5a\x5a\xa1\xed\x37\x76\x9f\xc1\xbc\x7e\x30\xf3\x6f\x6c\xd6\x43\xaa\x13\x24\xec\xfc\xca\x2f\xc1\x33\x8a\xf6\x7b\xc8\x2e\x85\x66\x1f\xd8\xca\x1c\x37\x7e\xe0\xda\x47\x82\xfb\x1b\x53\x89\x63\xf3\x07\x74\xbf\x44\x72\x1f\xa4\x9a\x43\x07\x25\xa4\xbc\xc7\x56\x5e\x68\x7f\x85\xdc\xb7\xd8\xd7\x16\x33\x0a\x3b\xbb\x8b\xdc\xc3\x1c\x3a\xa3\xa7\x15\xf6\xd3\x47\x36\x2d\x74\x50\x41\x4b\x35\x82\x77\x0f\x3d\x9e\xd0\x30\x4f\xf7\x51\xa4\xbc\x40\x9b\x2f\x24\x5d\x46\x47\x55\xd4\xbb\xa2\x91\x12\xba\x99\xa0\xe3\x0c\x76\x15\x41\xa6\xbf\xc8\x20\x8d\x6e\x16\x48\xcf\x43\xca\x57\xdc\xe1\x89\x9e\x26\xd8\x65\x8a\xc0\x4f\x62\xcf\x0f\xcc\x79\x89\xc9\x1c\x90\xdb\x02\xf3\x3b\x42\x5b\x6b\xb4\x3f\x40\xb6\x27\x8c\xbf\xc1\xbe\x7c\xb4\x5f\xc4\xee\xc2\x0c\x19\x22\xc9\x24\x92\xbc\xa0\x5e\x05\xc9\xcc\xd0\x5c\x98\x4f\x77\xec\xf5\x84\x0e\x2b\x18\x3f\x8e\xdc\xc2\x8c\x38\xa3\x83\x0f\xa6\xb1\xc7\x75\x8a\x38\xbf\x8a\xc9\xed\xb0\xe7\x21\x92\xf6\xb1\x85\x38\xc6\x5f\x22\xc9\x33\xc1\xf3\x49\xf0\xea\x20\x83\x2e\xda\x3b\x62\xdf\x75\x82\xcf\x16\xfd\x4a\x22\xc3\x90\x5d\x7e\x91\xd9\x10\x17\x89\x62\xfe\x1a\xd8\xcc\x03\x29\x8e\x90\xf2\x09\x7b\x9e\x20\x95\x38\xb2\x2b\xa0\xed\x39\x36\x5a\xc0\x2e\xb3\xe8\x21\x8b\x69\xf8\x48\x6e\x88\xdc\xce\xd8\xdb\x10\x1b\xe6\xde\x20\x86\x9b\x7e\xa3\xd3\x08\x52\xb9\x23\xb9\x35\x52\x4c\xe3\xda\x27\x02\xaf\x86\x64\x06\x48\xa6\x87\xe6\x5a\xd8\x48\x1c\xcd\x7d\x21\x83\x32\x66\xd3\x44\xca\x33\xe4\x9d\x40\x8b\x13\xb4\xff\x83\xbd\x55\x31\x61\x8e\xd6\x26\x68\xef\x8d\xf9\x0d\xcf\x37\xc5\xfc\x76\x30\xdb\x08\xf6\xb3\xc7\xd5\x0e\x48\x76\x87\xec\x5f\xc8\x7d\x80\xec\x13\xd8\x62\x16\x49\x1d\xd1\xec\x07\x93\xff\x23\xf0\x67\xb8\x4e\x05\xd7\xfe\x20\xdb\x29\xa6\xb4\x43\xca\x05\xec\xee\x86\xbd\x26\x91\xf7\x16\xbb\x5d\xa3\xa5\x25\x72\x0b\xf5\xb8\xc3\xbe\xce\x68\xf6\x8d\x54\x16\x18\xef\x07\xd3\xcb\x11\xbc\x07\x04\xcf\x36\x6e\x7c\xc5\x8c\x23\xd8\xd7\x0b\x89\xd4\xd0\xcc\x07\xf3\x13\x45\x06\x15\xcc\x31\x8b\x7e\x15\x30\x5f\x73\x64\x3b\xc1\x4e\xa2\x48\xea\x86\x8d\xf7\x31\xfe\x00\xfd\xae\x20\x83\x16\x92\x8d\xa1\x97\x3c\x41\xf8\xce\xc5\x32\x76\x97\x45\x3e\x17\x5c\x27\x43\xe0\x17\x31\xaf\x16\xa6\x57\x41\xca\x79\xf4\x9c\xc7\x35\x3a\xd8\xfc\x02\x99\xf5\x91\x4c\x15\xb3\xf4\x71\x93\x2a\x2e\x52\xc1\x0d\x46\xe8\xed\x86\xee\x8a\x98\xe1\x06\xd3\xdd\x62\xfc\x0c\x36\xda\x45\x0f\xe1\x9d\x54\x09\xbc\x2a\x52\xff\x41\x5b\x13\xec\x2d\x7c\xe6\x2f\x12\xed\x63\xe2\x19\x64\xb6\x45\x76\x43\x4c\x7c\x89\xfd\x24\x91\x49\xe8\xaf\x39\x52\xdc\xa3\xe7\x23\x92\xf1\xd1\xfc\x1f\xfa\x89\x20\x9b\x06\x5a\xf9\xc6\x34\x42\xde\x0d\xef\x2b\x89\x8e\xee\xe8\x68\x8c\x7e\x4d\x09\xde\x17\xa4\xb2\xc4\x34\x8e\xe8\xfd\x4e\xf0\x48\x62\xcb\x7d\xa4\x7a\x42\x5b\x4b\x74\x35\x46\x1f\x4d\xec\x79\x89\x16\x87\xb8\x49\xc8\x01\x3e\xba\xfb\x45\x3b\x5b\xcc\xea\x44\xf0\xe8\x20\x8b\x0c\x3a\x2b\xa2\xd1\x1d\x9a\x5d\xe3\xea\x61\x0f\x6f\xd0\xc2\x1c\x97\xac\x21\xdb\x0c\x9a\xff\x20\x5e\x19\xe3\xdd\x91\x82\x8f\x79\x7a\xb8\x5e\xc8\xf0\x2d\x5c\x2d\x64\xc3\x36\xf2\x15\xb2\xed\x1c\x69\x1c\xb0\xbb\x1d\x76\xbb\x41\x13\xa1\x0e\xc6\xb8\x4e\x02\x5b\xba\x61\x0b\x57\xdc\xb1\x8f\x39\x6e\xd1\xe6\x0c\xd9\xac\xb1\x89\x03\x66\xfc\x8b\x8d\xcd\x91\x66\x02\xf7\xee\xa0\xcf\x06\x26\xe4\xe9\x7b\x05\x3b\x8e\xa0\x7f\x13\x74\xb2\x47\x4b\x05\x74\x53\x40\x8f\x1d\x24\xd3\x45\x1b\x3e\x76\x5f\xc7\xf4\xde\xd8\xed\x0a\xed\x74\x31\xc7\x1a\xc1\xe3\x80\x49\xc7\x31\xc3\x1e\xc1\xa3\x84\x0e\x22\xd8\xe2\x0e\xd9\x46\x71\xc7\x28\xf6\x7c\xc1\xd5\x86\x98\xe4\x0c\xbb\xf3\x31\xe5\x0d\xc1\x73\x87\x5b\x84\xec\x14\x6e\x86\x5f\xa4\x3c\x27\xb8\xef\x91\xe1\x03\x2d\x87\xec\xb0\x47\xf3\x49\xe4\xb9\xc0\xf6\xf2\xe8\x31\x8b\x44\xd3\x98\xf5\x07\xcd\x2e\x31\x9b\x06\xc1\xa3\x82\xdd\x47\x71\x63\x0f\x13\x1f\x62\x9e\x6b\xe4\x1d\xc5\x26\xee\x48\xb3\x8f\x0e\xde\xd8\x44\x17\xe9\xed\x91\x67\xd8\x77\x45\x6c\x3c\xf4\xfb\x10\xb3\x28\x13\x3c\xf6\xe8\xb0\x4e\x10\x66\x7e\xb8\x49\x92\x13\x34\xf2\x85\x99\x46\x91\x48\x11\x33\x6f\x62\xba\x69\x82\x4f\x1c\x37\xe8\x60\xc7\x73\xec\x2e\x81\xf9\xf8\xd8\x58\x16\x7b\xbb\x20\xfb\x27\x76\x3c\x45\xb6\x2f\x34\xfb\x87\x4e\xb3\xc8\xbd\x40\xf0\x9c\xa1\xf5\x22\xf2\x1d\xc3\x84\x3d\xb6\xed\xa3\xfb\x09\x32\x6f\x61\x06\x53\xb4\x10\x72\x5a\xb8\x3b\xb6\x68\xff\x17\xd9\xfe\x20\x5e\x0a\xf3\x6c\x62\xb2\x3d\xec\x72\x81\xb6\x47\xb8\xde\x0d\xd7\x88\x60\x77\x2d\x24\x64\xdf\x43\x12\xcd\xd5\xb1\xd3\x18\x36\xfe\x8d\x54\x9f\xc8\xaa\x8d\x76\x76\xc8\x2a\x8a\xf1\x3f\x68\xe7\x8a\x94\xba\x98\xde\x10\x3b\x1e\xe3\xee\x63\x64\xd3\x41\xfc\x2b\x52\x3c\x60\xe3\x57\xe4\x90\x27\x78\x8c\x09\xee\x67\x5c\x27\x85\x1b\xbf\xd1\x52\x16\xa9\x46\x30\xd1\x1d\x72\x8c\xa2\xa5\x1f\x74\x30\xc4\x46\x2a\x48\xf8\x9d\x97\xb2\xd8\xcb\x05\x7b\x3b\x21\xf5\x39\xb2\x99\x62\x77\x6f\x24\xbd\xc3\xc6\xc7\xb8\xc9\x00\xfd\x7b\x63\xfc\x22\x52\xbc\xe1\x5e\xe1\x1e\x1d\x62\x6b\x77\x74\xdb\x44\xf7\x77\x64\xdb\xc2\xe6\x5b\xc8\x6d\x80\x89\x65\x91\xe3\x1a\x79\x1e\x70\xbd\x70\xef\xae\x90\x79\x19\x3d\x7e\x70\xfd\x23\x3a\x48\xa1\xa5\x09\xea\x57\x71\x5f\x69\xdc\x7c\x83\x5e\xea\xd8\xcc\x0f\x1a\x89\x60\x2f\x57\xc4\xab\x23\x33\x8f\xe0\x99\xc3\x44\x2f\x98\x55\x09\x17\x69\x60\xa2\x1b\xec\xa5\x87\xbc\x6a\x48\xf9\x0f\xf7\xac\xa3\xb5\x0d\xa6\xd7\xc6\x4e\xa3\xb8\xce\x1a\xf1\x6e\x48\x63\x87\xbc\xbe\xb0\xe5\x02\xc6\xdb\x21\x91\x21\xe6\xd4\xc4\xf4\x9a\xe8\xea\x07\xf3\xb7\xc0\x2c\xa3\x48\xee\x07\x19\xc5\x90\xe1\x10\xfd\xfe\x41\xaf\x0b\xe4\x91\x44\xea\x19\xcc\xef\x10\x93\x0a\x7b\xe2\x17\x3d\xbd\xb0\x89\x2a\x32\x9d\x61\x26\x27\xf4\x6f\x89\x8b\x16\x09\xde\x4b\x64\xb7\x42\xbf\x26\xc8\xcb\xc7\x76\xaa\x68\xb3\x8f\x6d\x86\xcc\xb5\xc1\x78\x27\xe4\xf9\xc0\xcd\x8f\x04\xcf\x3b\x9a\x6b\xe3\x42\x9e\x7b\x7c\xd0\x6e\x0b\x5b\xbc\x61\xea\x0b\x64\xfc\x8d\x78\x39\xcc\xa6\x8a\x46\xaf\x68\xe6\x86\xdd\x7e\x90\x71\x03\x99\xa7\x71\x91\x32\x1a\x66\x73\x26\x82\xb6\x42\x6f\x85\x9d\x37\x46\xf7\x3b\x5c\x34\x4d\xe0\xbf\xd0\x5d\x0d\x3d\xcd\x71\x91\x08\x7a\x6e\xa1\xd5\x14\x26\xba\x47\x5e\x61\xa7\x35\xb1\x91\x16\x32\x2b\xa3\xf9\x35\xf2\xe9\xe0\xea\x7d\x4c\x61\x8b\x19\xff\x11\x78\x19\xcc\x23\x8a\xf4\x33\xb8\x5e\xc8\x88\x2f\x82\xf0\x3d\x73\x2f\xcc\x2e\xec\xc3\x0b\xae\x1d\x32\x5b\xc8\x1c\xe1\xc6\x7a\x21\xa3\x14\xae\x97\xc0\x7e\x4a\xe8\xa9\x87\xc9\xdc\xd1\xf9\x13\x17\xfd\x60\xf7\x79\xa4\xb2\xc2\xa5\x4b\x98\x42\x98\xe3\x2d\xcc\x79\x87\x44\xcb\x48\xf2\x8e\x5b\xa4\x30\xe7\x09\x66\xb9\xc0\x26\x62\x68\xc8\x3e\xe1\x99\x0f\x29\xe4\x13\x7a\xae\x8d\xc6\x73\xc8\x38\xdc\xc4\x2d\x34\x91\x41\xfb\x07\xb4\xf7\xc1\x78\x33\xcc\xb1\x85\x44\xde\xc8\xbe\x8b\x69\xf5\xd0\x79\x17\xfb\xdf\x87\x79\xec\x79\x83\x99\x86\xb9\xda\x43\x0f\x21\xc3\x44\x31\x93\x12\xee\x67\x85\xe9\x55\xd1\xe2\x17\xf2\x1c\xa2\xdd\x33\x92\x3d\x62\xcf\x3b\x74\x9b\xc3\xa5\x73\xd8\x5d\x91\xc0\x1b\x23\xa1\x96\xc6\x61\xee\x86\xdd\x93\x41\xf6\x6d\x5c\xcb\x47\xcb\x1b\x4c\x6c\x8b\x6e\xf3\x48\xea\x0f\x1d\xcf\x91\x45\x1a\xbb\x59\x60\xfc\x27\x9a\xef\x21\x95\x33\x81\xdf\x46\x2f\x5b\x5c\x74\x83\xbc\x2b\x68\x6c\x85\x56\xd3\xd8\xfd\x0d\x7b\xf9\xc6\x6c\xc3\x5d\xd0\xc0\x6e\x27\x98\xc6\x0d\xa9\x3c\x90\x5e\xa8\x97\x50\xbb\x15\xec\x39\xec\xe3\x3c\xa6\xe4\x23\xb7\x15\x36\x12\x72\xc7\x02\x5b\x0c\xf7\xff\x06\x7d\xbc\x71\x8d\x2d\x92\x0e\xf7\x92\x8f\x6b\x24\xd1\xaf\x50\x3b\x6b\x24\x3b\x47\xd2\x03\xcc\xe4\x80\x7b\x7d\xd0\xcc\x0f\x26\xf6\xc4\x79\x3e\xc6\xf3\x30\x8b\x28\xe2\x0d\x31\xbd\x1e\x26\x9b\xc1\x3c\xeb\x48\x3a\x82\x19\xf4\xd0\x76\x01\x59\x77\xd1\x6b\x16\xb3\xa9\x21\xed\x33\x5a\xae\x21\xc7\x3b\xda\x0f\xb3\x2a\x81\x1d\xb7\xb0\xad\x32\xb2\xac\x62\xcf\x77\x6c\xb2\x82\xcc\xcf\xc8\xd7\x02\x8d\xef\x08\x1e\x6d\x82\x67\x07\x8d\x4e\x90\x42\x04\xe3\x1d\xd0\x6c\x09\xfb\x5e\x63\x23\x27\xe4\xf5\x83\x4d\x4f\x09\xbc\x0f\xa6\x16\x32\xd5\x05\x9b\xc8\x62\x96\x11\x6c\x65\x45\xf0\x49\x60\x5e\x55\x6c\x26\xf4\x44\x0b\x69\xde\x30\xde\x05\xd9\xdd\xd1\x43\x0b\x2d\xc4\xd0\xf3\x0f\xf6\xec\xe1\x5a\x3f\xe8\xf0\x0f\x93\x49\x61\xe2\x3b\xf4\x3c\xc7\xac\x7c\x64\xd2\xc1\xbe\x76\x48\x3e\x8d\xc4\xcb\xa8\xdf\x45\x4a\x6d\x6c\xad\x83\xcd\x9d\xb0\xb1\x1d\x32\x18\xa3\xc3\x03\xb6\x38\xc6\x26\x3f\x04\x7e\xa8\xd3\x24\xb2\x7f\x63\x5f\x4b\x24\xb5\xc7\x9e\xc7\x98\x8e\x8f\xf3\x4b\x48\x36\x87\xab\xf9\x48\x3e\xdc\x48\x71\x5c\x37\xcc\xfe\x15\x2e\xbe\x41\x4e\x7b\xe4\x1e\x45\xef\x3b\x82\x67\x19\xfb\x5a\x11\x78\x6b\x74\xf7\x85\xd6\x17\xd8\xd2\x2f\x92\xf1\xd0\xcb\x0f\x66\xd9\x46\xcb\x67\x74\xf4\x83\x44\xc3\xae\xdf\x62\x63\x63\xe4\xd8\xc3\x34\xda\xe8\x69\x8c\x19\x8c\x31\xbf\xe1\x8e\x09\xcf\x3c\xc3\xb5\x23\x04\xcf\x2a\x7a\x48\x63\x33\x45\x4c\x98\xdb\xfe\x17\x26\x76\x47\xea\x47\xcc\xf4\x86\xf1\x43\x56\xcf\xa3\xb7\x31\xb2\x6f\x22\x95\x70\xa3\xdd\xd0\xe1\x19\xa9\x66\x90\x77\x0d\x37\xe9\xa3\xa7\x1f\xcc\xaa\x88\x7c\xc2\x67\x5d\xb0\xf5\x01\x9a\x6f\xa2\xe7\x6f\xb4\x94\xc1\x7d\xf5\xb1\xef\x1e\x32\xdd\xe2\x1a\xa1\x9f\x7e\xb1\x9d\x2e\xf2\xdc\xa1\xd5\x35\x1a\x9e\xf5\xf1\x44\xfc\x1b\xb2\xcf\x61\x7e\x5a\x98\x70\x1b\x3e\x13\xb8\xee\x15\xd3\xac\xa2\xfb\x32\xb2\xfd\x45\x96\x15\x5c\x3f\x8d\xa9\x7e\xa3\x91\x1f\x64\x3f\xc3\x54\xce\xc8\xfb\x07\x2d\x97\xb1\xa9\x3e\xf6\x33\x40\x66\x0f\x6c\x72\x8f\x79\xb6\x31\xe5\x11\x66\x7d\x43\xa7\x5b\xf4\x7b\x80\xf9\x7d\xa0\xc7\x21\x12\xfb\xc3\xf8\x27\xe4\x93\xc2\xc5\x16\x48\x76\x8d\x3c\xee\xe8\x25\x85\x8e\xc2\x5c\x9b\x63\xb2\x1d\xec\x79\x8b\x99\x3d\xd1\x90\xa3\x6b\x23\x8c\xf7\xc0\xbc\x26\x68\xbe\x88\x84\xfc\xdd\xcc\x61\x27\x4d\x64\x18\x47\xf2\x33\xcc\xab\x8b\x49\x2c\xd0\x57\x9f\xe0\x59\x44\x26\x2b\xf4\xef\x88\x79\x0e\x90\x65\x1d\xc9\xe4\x70\xf3\x03\x81\xff\x41\xe6\x4d\x5c\x7d\x80\xfb\x7b\x12\xdc\x5f\xd8\xdb\x0a\x17\x7a\xbd\x10\xfe\xfe\x8d\x66\x7f\x91\xe6\x00\x3b\xc9\x63\x62\x1b\xf4\x30\x46\x1e\x5f\xd8\xdd\x1d\x79\x86\xfb\xef\x80\x4e\x92\xc8\xfc\x8a\x9e\xa3\x98\xe8\x1b\x9b\x19\xe2\xb2\x67\x6c\x3e\xe4\xbd\x27\x1a\xfe\xcd\x2e\x8a\xa6\x63\x48\x98\xe9\x1d\x0f\x19\x36\x90\x5d\x02\x39\xe4\xb0\xb7\x38\x7a\x1f\xa3\x85\x2a\xc1\xfd\x81\xcd\x86\x3a\x0d\xfd\x1e\xb2\x55\xc8\x7c\x0f\x34\x73\xc6\x8c\xa2\xe8\x64\x81\x0d\x33\x3c\xd5\xc0\x5e\x66\xe8\xbd\x81\xd4\x37\xe8\xd7\x1f\x6e\xd2\x42\xe6\x0d\x5c\x3d\x49\xe0\x1f\xb1\x9d\x12\x26\xdc\x8a\x8b\x07\xc1\xa3\x8c\x29\x17\x31\x8d\x13\x3a\x2e\xe0\xa2\x17\x24\x19\xc5\x75\x53\xd8\x6f\x8f\xc0\xaf\xe3\x36\x65\x5c\xa3\x82\x76\xea\xe8\x7e\x8b\x24\x9f\xb8\x6e\x05\x33\x29\x62\x2f\xbf\x68\x7e\x85\x7c\x46\xd8\x58\x1c\xf3\xbc\x63\xb2\x17\x34\x37\x41\x8a\x5d\xe4\xb6\x44\xa6\x27\x24\x99\x40\x07\x7d\xec\x76\x87\xdd\x75\x31\x93\x25\x66\x3e\x47\x87\x3b\xdc\xf8\x82\xdc\xc6\x98\xe1\x1a\x8d\x1d\x31\xd1\x02\xee\x9d\x20\x78\x2e\x30\xf3\x15\xb2\xf3\xd1\x71\x0c\x57\xf7\x90\xfe\x14\x8d\x56\xd0\xe8\x1e\x17\xaf\x62\xaf\x53\x34\xf7\x87\x2d\xd6\xb0\xc9\x37\xf6\x7c\x46\x87\x0d\xd4\x3f\x63\x0a\x3d\x5c\xbb\x81\x7d\xa7\x90\x85\x8f\x8c\x7f\xd1\xda\x0c\x89\xad\x30\x9b\x37\xae\xf5\x40\xb3\x7b\xcc\xf9\x17\x33\x8a\xe1\xfe\x6f\xa6\x32\x52\xc9\xe1\x3a\x57\x82\x67\x05\x69\xc6\x30\xcd\x16\xa6\x7e\x45\xd6\x29\x34\xd7\xc5\xa6\x63\x68\xf5\x8e\x7c\x8a\xd8\xce\x1b\xdb\x1f\xe3\x62\x3e\x36\x7e\x47\x6e\x6b\xb4\x30\x43\xa2\x57\xe4\x19\x47\x97\x2f\x24\x77\x24\x78\x9c\x70\xb1\x3a\x52\xc9\x12\xf8\x51\x4c\x3c\x86\x19\x35\x31\xcb\x21\xc1\xa3\x80\xcd\xec\x09\x9e\x67\x4c\xbd\x8f\x5e\x92\x04\xf7\x0e\xda\x8d\x61\xd2\x73\x74\x1d\xe6\xd7\x09\xfb\xb9\xa1\xdd\x90\x2f\x0b\x98\xe5\x12\x1b\x4f\x61\x77\x0b\xcc\x7e\x89\xbd\x97\x31\xf5\x1b\x76\x7f\x40\xaa\x29\x64\xfb\xc6\x9c\x72\xe8\xb9\x87\x7d\x67\xd1\xc4\x0c\xf3\xfb\x8d\xeb\x76\xd0\x48\x0d\x73\x6c\x13\x3c\xc2\x2d\xfe\x83\x8d\xad\x31\x87\x22\xfa\x55\x46\xaf\x31\x4c\xaa\x83\xe9\xa6\x08\xde\x0b\x34\xf6\x87\x96\xda\x04\xde\x2f\xc6\x1b\xe1\x52\x35\x4c\x3e\x86\x6b\x44\xd1\x5b\x04\x8d\xae\x30\xd9\x23\xae\x7f\xc7\x64\xfe\xb0\x97\x32\x2e\x92\xc2\x94\xd6\xb8\xce\x05\x33\x1f\x60\x96\x35\xf4\xd2\xc1\x1e\x0b\xc8\xeb\x81\xbc\x9e\x68\x2c\x8b\xbb\x6f\xb0\xd7\x3c\x92\x9e\xa1\x9d\x15\xe6\x7f\x1e\x65\x30\xcb\x90\x63\x2e\x98\xd7\x11\x9d\xec\x30\xb1\x12\x1a\x66\xde\x34\x8f\x5b\x1f\x30\x9b\x1e\x72\x1a\x23\xa9\x1a\x12\xee\xd9\xdd\x07\xbb\xab\xa2\x97\x3b\x7a\x0a\xf9\xfd\x85\xfd\x0c\x31\xe3\x24\xa6\x99\xc2\x9e\x6f\xe8\xb3\x8c\x59\x7d\x90\xd4\x08\xf9\x5d\x63\xe3\x51\x6c\x6e\x87\xc9\x4e\x90\x72\x0f\xdb\x8d\x20\xf3\x39\xee\x3e\x45\x8e\x1b\xcc\x3b\x87\xa4\x37\x04\xf7\x23\x32\x6e\x63\xfc\x36\x2e\x79\xc1\x7e\x17\x31\xbd\x14\xae\x31\x46\xbc\x0e\x66\xf3\x40\x52\x3e\x36\xdc\x9b\xd5\x04\x76\xb2\xc1\x6c\xf2\x68\xbe\x86\xc4\xbb\x68\xeb\x80\xab\xbd\x71\xf7\x21\xfa\x4c\xa1\xc7\x0c\xa6\x9f\xc5\x34\xcb\xe8\xcd\x47\xa7\x35\xcc\xba\x85\x19\x0f\x70\xc3\x35\x2e\xf2\x44\xb3\x1b\x82\xf7\x0a\x49\x67\xd1\x82\x87\x99\xb4\xd0\xd1\x0b\x13\xab\xa1\x83\x1d\x1a\x9b\xe2\x16\x65\x24\x37\xc0\x1e\x7e\xb0\xef\x17\x92\x8f\xe3\xee\x1f\xb4\xb5\x40\x2a\x61\x46\xf6\x31\x21\xa7\x0f\xf3\xd8\x77\x0e\x0d\xef\x63\xbe\x45\x2b\x7f\xb8\x9f\x18\xf6\xfd\x8d\xe4\xc3\x1c\x9b\x12\x3c\xf7\xd8\x5a\x1e\xe3\xd7\x70\xbd\x37\xc1\x3d\x64\xb0\x0b\xb2\x4c\xa1\xf9\x21\xb2\x4d\x63\xdf\x55\x5c\xe7\x0b\xd7\xfb\x42\x42\xee\xab\x27\x90\x73\x1a\xc9\xfe\x20\x91\x31\x52\x4a\x22\xb5\x3f\xdc\xfa\x8a\x6d\xee\x90\xcc\x0d\x6d\xce\x31\x5f\x3f\xd8\x4b\x1e\x99\x67\x09\x5e\x3d\xf4\x92\x46\x9f\xbf\x68\x2f\x3c\x67\x1a\x57\xeb\xa0\xe3\x38\x9a\xbd\x12\xf8\x0d\xec\xa7\x41\xf0\x69\x11\x78\x65\x6c\xb2\x81\xfb\xce\xa3\xd3\x03\x76\x91\x42\xc7\x29\x34\x96\x40\xca\x0d\xb4\xf6\x8d\xfb\x69\x21\xf9\x36\xda\xf2\xd0\xe3\x1d\xd9\xcc\x90\x4a\x05\xd9\x0c\xd1\xfb\x08\x39\x64\x30\xcd\x37\xb2\xe8\xa0\xf1\x3e\x81\xbf\xc7\xe4\x47\xd8\x78\x04\xbb\xaf\xa0\xb9\x1e\xae\x9f\x45\xc7\x55\x24\xe4\xcc\x76\x0f\x3b\xde\x63\x7a\x2d\xf4\xde\xc2\x26\xca\xd8\x4b\x13\xbd\x16\x30\x8d\x3e\xda\x7b\xe0\xda\x49\x6c\xac\x80\xd4\xd7\x48\x29\x8b\x89\xc7\x31\xde\x1f\xba\x4b\xa2\xed\x15\xc1\xf3\x07\xd3\x4a\x63\x92\x5b\xa4\xfc\xc0\xd5\xb2\x68\x65\x83\x2d\x94\x30\x7f\x4f\x5c\xf2\x86\x44\x6f\xc8\xb3\x8e\x6b\xcc\xd1\x68\x78\xa7\x7b\x64\x50\xc5\x3d\x7d\xcc\xe7\x89\xf1\xae\x48\xb9\x83\xc9\x1f\x70\x91\x2d\xe6\x55\xc1\xf8\x7d\x74\xda\x45\x73\x55\x6c\x6a\x85\x6d\xfc\x21\x3b\x0f\xf7\x33\xc3\xac\x53\x48\xea\x8a\x7e\xef\x90\x54\x01\x09\x77\x5a\xfa\x8e\xf1\x93\xc8\x20\xd4\xb8\x87\x49\xec\xb1\xaf\x3d\xfa\x37\x45\x3b\x79\x4c\x7b\x81\xbc\xc7\xb8\xc6\x06\xd7\x58\x10\xdc\x97\x68\xeb\x0f\xd7\xf0\x91\xef\x04\x5a\xe9\xa3\xd9\x2a\x2e\x16\x21\xf0\x36\xb8\xe4\x0e\xfb\xc9\x60\x33\x35\x6c\x22\x85\x4b\x5e\x71\xad\x23\xf2\x59\xe2\x92\x5d\xdc\xf8\x85\x79\xbf\xd0\xeb\x0a\x29\xde\x09\xfc\x16\xae\x13\x6a\x73\x88\xc6\xd7\xe8\x60\x83\x2c\xbb\xd8\x58\x17\x2d\x66\x71\xd3\x36\xfa\x8c\xa1\xed\x14\xfa\xe7\x21\x95\x37\x2e\x5e\xc2\xc4\x6f\xe8\x21\x8a\x54\x2f\xb8\xf9\x1e\x5b\x59\xe2\x7a\x49\x5c\x6c\x8b\xfd\x44\x31\xe9\x2f\xb4\x56\x43\x96\x3e\xf6\x72\x46\xb6\x67\x4c\x7c\x81\x44\x3c\xe4\x5e\x41\x9b\x55\x5c\x3d\x8e\xb6\x56\xb8\x54\x1a\x5b\x9d\xe2\xc2\xad\xd2\x0b\x39\xf6\x83\xe6\x0b\x48\x2c\x89\x4d\x3e\x90\xc5\x1c\x2d\x67\xb1\xe7\x19\x9a\x4f\xa1\x9b\x1f\x6c\x75\x8c\x8d\x7b\x04\xf7\x09\x7a\x59\x23\xe1\x99\xda\x31\xe4\xfb\x17\x2d\x8c\xb1\xcb\x0c\xf6\xfc\x83\xfe\x67\x98\x33\x7a\x08\x7f\x2e\x20\xa9\xb0\xd7\x3c\x64\xd9\xc7\xee\xc3\xec\xb8\x22\xb9\x70\x5f\xff\x61\xc3\x9d\xd6\x2e\x63\x43\x26\xef\x65\x70\x3f\x55\x82\x47\x03\xf5\x7e\x08\xee\x3d\xa4\x38\x41\x73\x0f\x5c\xeb\x86\xd4\x56\x48\x66\x8b\x5b\xbf\x31\x61\x5e\xc4\x86\x68\xb5\x8d\xab\xd7\xd0\xd2\x0d\x37\x49\x23\x0f\x1f\x1d\x26\xd0\xf8\x08\x8d\xaf\x08\x5e\x27\x02\x3f\x8d\x4d\x86\x8c\x36\x40\xaf\x33\x24\x5b\xc5\x7c\x2f\x91\xd1\x18\x3d\x3d\xb1\xd5\x03\xe6\xb5\xc6\xf5\x8b\x68\xf1\x1b\x1b\x2f\x61\xf3\x45\xd4\x0f\x39\x7c\x8d\x16\x93\xe8\xa3\x8d\x19\x15\x71\xfd\x6f\x5c\xec\x82\xad\x24\x30\xcd\x1d\x7a\x0b\xf7\x4d\xd8\x0b\x39\xcc\xf1\x07\x13\x6f\x23\xdb\x0f\x3a\x9e\xa2\x99\x0c\x6e\x7d\x42\x7e\x63\xd8\xe9\x17\xf2\xee\x60\xb6\x1b\xb4\x58\xc1\xc6\x46\x68\xad\x8a\x76\x6a\xd8\xf7\x0a\xdd\x7e\xb0\xa5\x23\x5a\xcd\xa1\x95\x24\x2e\x79\x40\x0e\x65\x4c\xf3\x17\xa9\x47\xb0\x61\xa6\x8e\x2e\xe8\xf1\x17\xd3\x3d\x60\xbe\x92\x48\x79\x84\x6b\x47\xb1\xa5\x03\xfa\x75\xc4\xbe\x9b\xb8\xda\x1a\xd3\x0a\x77\xd2\x00\xb9\xdd\x70\xf3\x0f\x66\x7e\x27\xb8\xb7\x31\xa5\x04\xea\x85\x5e\xdd\xe3\x22\x3e\xf2\xda\x20\xfb\x70\xdb\x7d\x90\xc5\x0a\x9b\x4d\x23\x95\x6f\xdc\x70\x81\x46\x56\x98\xe1\x16\xdd\xa4\xf9\x17\x00\x00\xff\xff\xbf\x1b\x72\xe3\x00\x20\x00\x00") +var _keysWordsWordlistChinese_simplifiedTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x1c\x97\x55\x76\xeb\x30\x14\x45\xff\xf7\xa8\xc3\xcc\x49\xc3\x69\x98\xda\x86\xd9\x0e\x4c\xc6\xf7\x4a\x9a\xc5\x5b\x7e\x7f\x5d\x5d\x6d\x6c\x45\x07\xf6\x31\xdd\x04\xc1\x3d\x82\xb6\x77\x48\x7f\x45\x70\x2f\x12\x78\x29\xb4\x9f\x45\x6a\x05\x02\xcf\xc3\x7e\x3a\x04\xf7\x0d\x32\x5b\x12\xdc\x3d\x82\x7b\x8e\xe0\xfe\x83\xf4\x5e\x68\xa6\x4a\xe0\xcf\xb1\x8b\x28\x81\xdf\x44\x5b\x57\x74\x30\xc7\x34\x56\x04\xfe\x1f\xa6\x31\x44\x32\x7b\x82\x57\x1f\xe9\xef\x09\xbc\x12\x92\xf6\x90\xfd\x01\xc9\xa4\x90\xdd\x03\xcd\x54\x08\x9e\x5d\xa4\xbc\x23\xb8\xfb\x48\xb9\x8a\x3c\xce\x48\x6e\x85\x54\x0a\xc8\x6d\x4e\xf0\x18\x62\xe3\x2f\x82\x7b\x1e\xfb\x49\x23\x9b\x0a\x76\x77\x26\xf0\x96\x98\x65\x11\x37\x98\x60\x23\x05\xb4\xf9\x40\x2a\x25\x64\xd6\x45\xb6\x5d\xec\xb8\x80\x6c\x16\xe8\xe9\x0b\xcd\x46\xd0\x7d\x15\x79\xb7\x30\x7e\x19\x29\x46\x09\xee\x59\x82\x47\xf8\x99\x3d\xcc\x20\x82\xd9\x64\x71\xf1\x15\xe2\x2d\x90\xed\x15\xd3\xb8\x20\xb9\x1e\x2e\x5d\x40\x16\x31\x74\x7f\x46\x0a\x4d\xdc\x6f\x1b\x9b\xfe\x21\xf0\x0a\x98\x4a\x0a\x7b\xb9\x21\xfb\x32\x26\xbb\xc6\x94\xf6\xc8\xf6\x1b\xc9\x8d\x70\xe9\x32\xee\xff\x7b\xcf\x08\x5e\x75\x24\x73\x45\xfb\x1e\xf2\xaa\x13\xbc\x3e\x98\xd8\x83\xc0\x2f\x11\xdc\xbb\x68\xff\x0f\x29\xf9\x68\x2e\x87\x46\x96\xc8\xfc\x85\x78\x0d\xe4\x19\x41\xb6\x71\xa4\x92\xc1\x7e\xda\x48\x6f\x84\x69\x1c\x90\xe4\x95\xc0\xeb\x61\x12\x57\x24\x5b\x44\x66\x4d\x64\xb6\x46\x1b\x1f\xa4\xd7\x43\x5b\x73\x5c\x6c\x8a\x99\xbd\x09\x1e\x59\x02\x2f\x8f\x3c\x4e\xc8\x6b\x82\xe9\xdd\x91\xe4\x0a\x3b\x5e\xe1\x5a\x67\x74\x74\x23\xb8\x97\x90\xe4\x09\xa9\x24\x70\xe9\x22\xda\xdc\x63\xbc\x0f\x92\x4a\xa2\x5f\x7b\x74\x33\x45\x3e\x71\xa4\x5c\x24\x78\x8d\xd0\x76\x09\xd3\xcf\x23\xa5\x21\x52\xce\x10\x3c\x32\x48\x66\x8d\xee\x1a\x68\xa6\x49\xf0\x4a\x61\xcf\x2b\x74\xdf\xc0\xfc\xfd\x21\x95\x2a\x2e\x5a\x47\xaa\x2f\x74\x33\x43\xca\x6d\x74\x30\x46\xca\x3f\xe8\x71\x8c\xf1\xeb\xd8\xe5\x14\xd7\xda\xa2\x89\x32\xe2\x7b\x68\x3f\x83\x24\xff\xd0\xd6\x08\x73\xf2\x91\x54\x0f\x79\x67\xd0\x78\x12\x1b\x49\xa2\xfd\x08\xe6\x37\x4f\xe0\x4f\xd1\xf8\x09\xb9\x1d\x71\x91\x2e\xf2\xb8\xa2\xe5\x0a\xa6\x77\xc6\x4d\xda\x48\xb2\x8b\x59\xe5\x91\xc3\x17\x81\xd7\x40\xbf\xfb\x68\xb3\x83\x3d\x8c\x91\x6a\x1b\x37\x58\x13\xbc\x8a\x48\x72\x8e\xdc\xef\x68\x33\x8d\x46\x7c\xf4\x6f\x8c\xd4\xa3\xc8\xb3\x8c\x9e\x7d\xec\xf6\x8d\x94\x73\x98\xed\x18\x93\x0d\xef\xee\x8a\xfb\xfa\xa0\x87\x18\x36\x12\x45\x66\x67\x64\xe8\x61\x2f\x09\xec\xfb\x81\x5e\xa2\xd8\xdb\x0e\xe3\x2d\x91\x50\x7b\xbd\x37\x72\x38\x60\xfc\x21\x5a\x9a\x63\x86\x73\xec\x3b\x8e\xec\x53\x18\x3f\x81\x5d\x46\xb1\xdb\x31\x92\xf9\x45\xe6\x0f\x34\x9b\xc7\x2e\x6b\x68\x7f\x88\x8e\x1e\xd8\x6d\xe8\xc7\x0a\x92\xea\xa3\x85\x34\x92\x1e\x11\x3c\x06\x48\xc1\x43\x9e\x1e\xda\x78\x23\xa9\x13\x76\xfe\xc1\x4e\x7e\x91\xc7\x11\x89\x76\x91\x4f\x12\xcd\x84\xdf\x43\x06\xe9\x7d\x23\x99\x0e\x81\x1f\x7a\xad\x89\x16\xb7\xc8\x2c\x81\x6b\x0f\x91\x62\xe8\x8d\x0e\x36\x7b\x44\x92\x59\x5c\x6b\x85\x14\x4f\x04\x9f\x01\x7a\xf4\x91\x42\x0b\x17\x19\x61\x3a\x6f\xec\x32\x81\x89\x6f\x70\x93\x14\xc1\x3d\x8e\x86\x1e\x28\x4f\x09\xee\x7d\x64\xf7\x44\x3a\x2b\xa4\x94\x47\x3e\x2d\x82\x7b\x13\x97\xae\x22\x93\x6f\x02\x2f\x8b\x5e\x4a\xb8\xf6\x15\x3d\x3e\xd0\xc8\x00\xed\xef\xd0\xef\x28\x81\x17\xea\xa2\x85\x8d\x36\x08\xfc\x08\x76\x3b\x43\x92\x1b\x24\x79\x40\x07\x71\xb4\x71\xc5\xee\xa2\x68\xe3\x81\xde\x93\x98\x77\x09\x49\x15\x71\xe9\x34\xf6\xf5\x87\xf6\xce\x48\xf1\x0b\x37\x2d\x21\x99\x34\x9a\xad\x63\x3a\x2f\xf4\xab\x83\x8b\x0c\xb1\xb9\x03\x72\x0f\xbd\x9d\x45\xfa\x1e\xd6\xfb\xc5\xbe\x16\x04\xef\x3c\xa6\x3f\x44\x72\x63\x24\x19\x7a\x21\x8d\xee\xca\x98\xde\x16\x9b\x3e\x61\xdf\x6f\xec\x65\x8f\x59\xee\x30\x33\x0f\xbb\xdd\x22\xd3\x3d\x9a\x9b\xa3\xcd\x16\xb2\x2d\x60\x0e\x3e\x92\xfc\xc5\x2c\x7c\xa4\x58\x42\x2a\x45\xcc\x78\x8b\x66\x8b\x98\x65\x15\x79\x8e\x08\x3e\x63\xdc\xfa\x0f\x9b\x8b\x61\x77\x03\xcc\xe1\x84\x7e\x9d\x31\x6b\x0f\x49\xc6\x91\xd4\x85\xc0\xcf\xe1\x7a\x29\xf4\xbe\x26\x78\x8e\x90\xfe\x10\xbb\xbd\xa3\x9b\x39\xe6\x3d\x43\x1e\x1f\xcc\xf0\x84\xdd\xee\x71\xfd\x08\xba\xbd\x60\x46\x0d\xcc\x57\x01\xcd\x67\xd1\xef\x16\xf2\xce\x23\xe5\x5f\x82\x7b\x03\xb3\xbe\x62\x97\x31\xec\x35\x87\xf1\xd3\xd8\x69\x12\x79\x1d\x30\xdb\x16\xc1\xab\x84\x16\xa2\xb8\xe1\x89\xe0\xd9\x22\x78\x2c\x90\x7b\x1c\x99\x15\x91\xed\x03\x49\x7c\x70\x63\x1f\xd7\x49\x22\x5f\x29\xdc\xe0\x1b\xf7\x53\xc0\x7e\xbe\xd1\xe6\x06\xbd\x1d\x70\xdd\x37\xf6\x53\xc5\x0c\x3f\x48\x31\x8e\x54\x57\xc8\xb2\x81\x39\x8f\xd0\x5c\x04\x99\xa5\x91\x62\x0e\xc9\x7d\xe3\x06\x35\x4c\x3f\x8a\x64\xc2\x67\x8d\x90\x7a\x11\xe3\x2d\xd0\xc6\x0e\x9b\xf9\x43\xca\x47\x34\x11\xde\xc3\x89\xe0\x1d\xe6\xd8\x04\x79\x47\x70\xc9\x3b\x52\x4a\x21\xf7\x18\x92\xcc\x13\xbc\xbe\x70\x9d\x19\x7a\xcd\xa0\xdf\x09\xc4\xeb\x63\x96\x7b\x64\xf6\x83\xa4\x53\x98\xe3\x1b\x89\x3c\x91\xf2\x0d\x53\x4a\xa3\xad\x32\xc6\x3f\x23\x99\x1a\x2e\x92\x45\x47\x69\x24\xd5\x41\x36\x6d\x24\xd2\x41\x77\x3d\x02\xef\x88\x7c\x7e\xd1\xaf\x0c\xda\xdc\xe1\x3a\x13\x74\x38\x47\x0f\x43\xe4\x3b\xd4\xc7\x13\x53\xca\xa3\x85\xf0\xff\x9f\x48\xd2\x47\xdb\x75\xcc\x6b\x8b\x9e\x43\x5f\xc7\x30\xd9\x34\xb2\xcc\x23\xc5\x33\xc1\xbd\x8e\xc9\x5d\xb1\xb1\x23\x52\x8a\x11\x78\x7f\xd8\x5d\x0a\x17\x89\x21\x87\x6f\xa4\x9f\x42\x0a\x49\x4c\xf4\x97\xe0\x55\xc6\xee\xe3\xa8\x3f\x46\x4a\x1f\xe4\x10\xc1\x24\x97\x48\x39\x86\xf1\x26\x18\x3f\x85\x3c\xbf\x90\x4a\xf8\x19\x73\x5c\x3d\xec\xdb\x50\xa7\x73\xdc\xa2\x89\x78\x5f\xe8\xf5\x88\x6c\xdb\xc8\xfb\x86\xeb\x96\x31\xad\x24\x36\x5f\x46\x66\x07\x64\xdf\x40\x37\x61\x7e\x1d\x71\xc9\x22\x32\x3f\xe1\xfc\x04\x5a\x5a\xa1\xed\x37\x76\x9f\xc1\xbc\x7e\x30\xf3\x6f\x6c\xd6\x43\xaa\x13\x24\xec\xfc\xca\x2f\xc1\x33\x8a\xf6\x7b\xc8\x2e\x85\x66\x1f\xd8\xca\x1c\x37\x7e\xe0\xda\x47\x82\xfb\x1b\x53\x89\x63\xf3\x07\x74\xbf\x44\x72\x1f\xa4\x9a\x43\x07\x25\xa4\xbc\xc7\x56\x5e\x68\x7f\x85\xdc\xb7\xd8\xd7\x16\x33\x0a\x3b\xbb\x8b\xdc\xc3\x1c\x3a\xa3\xa7\x15\xf6\xd3\x47\x36\x2d\x74\x50\x41\x4b\x35\x82\x77\x0f\x3d\x9e\xd0\x30\x4f\xf7\x51\xa4\xbc\x40\x9b\x2f\x24\x5d\x46\x47\x55\xd4\xbb\xa2\x91\x12\xba\x99\xa0\xe3\x0c\x76\x15\x41\xa6\xbf\xc8\x20\x8d\x6e\x16\x48\xcf\x43\xca\x57\xdc\xe1\x89\x9e\x26\xd8\x65\x8a\xc0\x4f\x62\xcf\x0f\xcc\x79\x89\xc9\x1c\x90\xdb\x02\xf3\x3b\x42\x5b\x6b\xb4\x3f\x40\xb6\x27\x8c\xbf\xc1\xbe\x7c\xb4\x5f\xc4\xee\xc2\x0c\x19\x22\xc9\x24\x92\xbc\xa0\x5e\x05\xc9\xcc\xd0\x5c\x98\x4f\x77\xec\xf5\x84\x0e\x2b\x18\x3f\x8e\xdc\xc2\x8c\x38\xa3\x83\x0f\xa6\xb1\xc7\x75\x8a\x38\xbf\x8a\xc9\xed\xb0\xe7\x21\x92\xf6\xb1\x85\x38\xc6\x5f\x22\xc9\x33\xc1\xf3\x49\xf0\xea\x20\x83\x2e\xda\x3b\x62\xdf\x75\x82\xcf\x16\xfd\x4a\x22\xc3\x90\x5d\x7e\x91\xd9\x10\x17\x89\x62\xfe\x1a\xd8\xcc\x03\x29\x8e\x90\xf2\x09\x7b\x9e\x20\x95\x38\xb2\x2b\xa0\xed\x39\x36\x5a\xc0\x2e\xb3\xe8\x21\x8b\x69\xf8\x48\x6e\x88\xdc\xce\xd8\xdb\x10\x1b\xe6\xde\x20\x86\x9b\x7e\xa3\xd3\x08\x52\xb9\x23\xb9\x35\x52\x4c\xe3\xda\x27\x02\xaf\x86\x64\x06\x48\xa6\x87\xe6\x5a\xd8\x48\x1c\xcd\x7d\x21\x83\x32\x66\xd3\x44\xca\x33\xe4\x9d\x40\x8b\x13\xb4\xff\x83\xbd\x55\x31\x61\x8e\xd6\x26\x68\xef\x8d\xf9\x0d\xcf\x37\xc5\xfc\x76\x30\xdb\x08\xf6\xb3\xc7\xd5\x0e\x48\x76\x87\xec\x5f\xc8\x7d\x80\xec\x13\xd8\x62\x16\x49\x1d\xd1\xec\x07\x93\xff\x23\xf0\x67\xb8\x4e\x05\xd7\xfe\x20\xdb\x29\xa6\xb4\x43\xca\x05\xec\xee\x86\xbd\x26\x91\xf7\x16\xbb\x5d\xa3\xa5\x25\x72\x0b\xf5\xb8\xc3\xbe\xce\x68\xf6\x8d\x54\x16\x18\xef\x07\xd3\xcb\x11\xbc\x07\x04\xcf\x36\x6e\x7c\xc5\x8c\x23\xd8\xd7\x0b\x89\xd4\xd0\xcc\x07\xf3\x13\x45\x06\x15\xcc\x31\x8b\x7e\x15\x30\x5f\x73\x64\x3b\xc1\x4e\xa2\x48\xea\x86\x8d\xf7\x31\xfe\x00\xfd\xae\x20\x83\x16\x92\x8d\xa1\x97\x3c\x41\xf8\xce\xc5\x32\x76\x97\x45\x3e\x17\x5c\x27\x43\xe0\x17\x31\xaf\x16\xa6\x57\x41\xca\x79\xf4\x9c\xc7\x35\x3a\xd8\xfc\x02\x99\xf5\x91\x4c\x15\xb3\xf4\x71\x93\x2a\x2e\x52\xc1\x0d\x46\xe8\xed\x86\xee\x8a\x98\xe1\x06\xd3\xdd\x62\xfc\x0c\x36\xda\x45\x0f\xe1\x9d\x54\x09\xbc\x2a\x52\xff\x41\x5b\x13\xec\x2d\x7c\xe6\x2f\x12\xed\x63\xe2\x19\x64\xb6\x45\x76\x43\x4c\x7c\x89\xfd\x24\x91\x49\xe8\xaf\x39\x52\xdc\xa3\xe7\x23\x92\xf1\xd1\xfc\x1f\xfa\x89\x20\x9b\x06\x5a\xf9\xc6\x34\x42\xde\x0d\xef\x2b\x89\x8e\xee\xe8\x68\x8c\x7e\x4d\x09\xde\x17\xa4\xb2\xc4\x34\x8e\xe8\xfd\x4e\xf0\x48\x62\xcb\x7d\xa4\x7a\x42\x5b\x4b\x74\x35\x46\x1f\x4d\xec\x79\x89\x16\x87\xb8\x49\xc8\x01\x3e\xba\xfb\x45\x3b\x5b\xcc\xea\x44\xf0\xe8\x20\x8b\x0c\x3a\x2b\xa2\xd1\x1d\x9a\x5d\xe3\xea\x61\x0f\x6f\xd0\xc2\x1c\x97\xac\x21\xdb\x0c\x9a\xff\x20\x5e\x19\xe3\xdd\x91\x82\x8f\x79\x7a\xb8\x5e\xc8\xf0\x2d\x5c\x2d\x64\xc3\x36\xf2\x15\xb2\xed\x1c\x69\x1c\xb0\xbb\x1d\x76\xbb\x41\x13\xa1\x0e\xc6\xb8\x4e\x02\x5b\xba\x61\x0b\x57\xdc\xb1\x8f\x39\x6e\xd1\xe6\x0c\xd9\xac\xb1\x89\x03\x66\xfc\x8b\x8d\xcd\x91\x66\x02\xf7\xee\xa0\xcf\x06\x26\xe4\xe9\x7b\x05\x3b\x8e\xa0\x7f\x13\x74\xb2\x47\x4b\x05\x74\x53\x40\x8f\x1d\x24\xd3\x45\x1b\x3e\x76\x5f\xc7\xf4\xde\xd8\xed\x0a\xed\x74\x31\xc7\x1a\xc1\xe3\x80\x49\xc7\x31\xc3\x1e\xc1\xa3\x84\x0e\x22\xd8\xe2\x0e\xd9\x46\x71\xc7\x28\xf6\x7c\xc1\xd5\x86\x98\xe4\x0c\xbb\xf3\x31\xe5\x0d\xc1\x73\x87\x5b\x84\xec\x14\x6e\x86\x5f\xa4\x3c\x27\xb8\xef\x91\xe1\x03\x2d\x87\xec\xb0\x47\xf3\x49\xe4\xb9\xc0\xf6\xf2\xe8\x31\x8b\x44\xd3\x98\xf5\x07\xcd\x2e\x31\x9b\x06\xc1\xa3\x82\xdd\x47\x71\x63\x0f\x13\x1f\x62\x9e\x6b\xe4\x1d\xc5\x26\xee\x48\xb3\x8f\x0e\xde\xd8\x44\x17\xe9\xed\x91\x67\xd8\x77\x45\x6c\x3c\xf4\xfb\x10\xb3\x28\x13\x3c\xf6\xe8\xb0\x4e\x10\x66\x7e\xb8\x49\x92\x13\x34\xf2\x85\x99\x46\x91\x48\x11\x33\x6f\x62\xba\x69\x82\x4f\x1c\x37\xe8\x60\xc7\x73\xec\x2e\x81\xf9\xf8\xd8\x58\x16\x7b\xbb\x20\xfb\x27\x76\x3c\x45\xb6\x2f\x34\xfb\x87\x4e\xb3\xc8\xbd\x40\xf0\x9c\xa1\xf5\x22\xf2\x1d\xc3\x84\x3d\xb6\xed\xa3\xfb\x09\x32\x6f\x61\x06\x53\xb4\x10\x72\x5a\xb8\x3b\xb6\x68\xff\x17\xd9\xfe\x20\x5e\x0a\xf3\x6c\x62\xb2\x3d\xec\x72\x81\xb6\x47\xb8\xde\x0d\xd7\x88\x60\x77\x2d\x24\x64\xdf\x43\x12\xcd\xd5\xb1\xd3\x18\x36\xfe\x8d\x54\x9f\xc8\xaa\x8d\x76\x76\xc8\x2a\x8a\xf1\x3f\x68\xe7\x8a\x94\xba\x98\xde\x10\x3b\x1e\xe3\xee\x63\x64\xd3\x41\xfc\x2b\x52\x3c\x60\xe3\x57\xe4\x90\x27\x78\x8c\x09\xee\x67\x5c\x27\x85\x1b\xbf\xd1\x52\x16\xa9\x46\x30\xd1\x1d\x72\x8c\xa2\xa5\x1f\x74\x30\xc4\x46\x2a\x48\xf8\x9d\x97\xb2\xd8\xcb\x05\x7b\x3b\x21\xf5\x39\xb2\x99\x62\x77\x6f\x24\xbd\xc3\xc6\xc7\xb8\xc9\x00\xfd\x7b\x63\xfc\x22\x52\xbc\xe1\x5e\xe1\x1e\x1d\x62\x6b\x77\x74\xdb\x44\xf7\x77\x64\xdb\xc2\xe6\x5b\xc8\x6d\x80\x89\x65\x91\xe3\x1a\x79\x1e\x70\xbd\x70\xef\xae\x90\x79\x19\x3d\x7e\x70\xfd\x23\x3a\x48\xa1\xa5\x09\xea\x57\x71\x5f\x69\xdc\x7c\x83\x5e\xea\xd8\xcc\x0f\x1a\x89\x60\x2f\x57\xc4\xab\x23\x33\x8f\xe0\x99\xc3\x44\x2f\x98\x55\x09\x17\x69\x60\xa2\x1b\xec\xa5\x87\xbc\x6a\x48\xf9\x0f\xf7\xac\xa3\xb5\x0d\xa6\xd7\xc6\x4e\xa3\xb8\xce\x1a\xf1\x6e\x48\x63\x87\xbc\xbe\xb0\xe5\x02\xc6\xdb\x21\x91\x21\xe6\xd4\xc4\xf4\x9a\xe8\xea\x07\xf3\xb7\xc0\x2c\xa3\x48\xee\x07\x19\xc5\x90\xe1\x10\xfd\xfe\x41\xaf\x0b\xe4\x91\x44\xea\x19\xcc\xef\x10\x93\x0a\x7b\xe2\x17\x3d\xbd\xb0\x89\x2a\x32\x9d\x61\x26\x27\xf4\x6f\x89\x8b\x16\x09\xde\x4b\x64\xb7\x42\xbf\x26\xc8\xcb\xc7\x76\xaa\x68\xb3\x8f\x6d\x86\xcc\xb5\xc1\x78\x27\xe4\xf9\xc0\xcd\x8f\x04\xcf\x3b\x9a\x6b\xe3\x42\x9e\x7b\x7c\xd0\x6e\x0b\x5b\xbc\x61\xea\x0b\x64\xfc\x8d\x78\x39\xcc\xa6\x8a\x46\xaf\x68\xe6\x86\xdd\x7e\x90\x71\x03\x99\xa7\x71\x91\x32\x1a\x66\x73\x26\x82\xb6\x42\x6f\x85\x9d\x37\x46\xf7\x3b\x5c\x34\x4d\xe0\xbf\xd0\x5d\x0d\x3d\xcd\x71\x91\x08\x7a\x6e\xa1\xd5\x14\x26\xba\x47\x5e\x61\xa7\x35\xb1\x91\x16\x32\x2b\xa3\xf9\x35\xf2\xe9\xe0\xea\x7d\x4c\x61\x8b\x19\xff\x11\x78\x19\xcc\x23\x8a\xf4\x33\xb8\x5e\xc8\x88\x2f\x82\xf0\x3d\x73\x2f\xcc\x2e\xec\xc3\x0b\xae\x1d\x32\x5b\xc8\x1c\xe1\xc6\x7a\x21\xa3\x14\xae\x97\xc0\x7e\x4a\xe8\xa9\x87\xc9\xdc\xd1\xf9\x13\x17\xfd\x60\xf7\x79\xa4\xb2\xc2\xa5\x4b\x98\x42\x98\xe3\x2d\xcc\x79\x87\x44\xcb\x48\xf2\x8e\x5b\xa4\x30\xe7\x09\x66\xb9\xc0\x26\x62\x68\xc8\x3e\xe1\x99\x0f\x29\xe4\x13\x7a\xae\x8d\xc6\x73\xc8\x38\xdc\xc4\x2d\x34\x91\x41\xfb\x07\xb4\xf7\xc1\x78\x33\xcc\xb1\x85\x44\xde\xc8\xbe\x8b\x69\xf5\xd0\x79\x17\xfb\xdf\x87\x79\xec\x79\x83\x99\x86\xb9\xda\x43\x0f\x21\xc3\x44\x31\x93\x12\xee\x67\x85\xe9\x55\xd1\xe2\x17\xf2\x1c\xa2\xdd\x33\x92\x3d\x62\xcf\x3b\x74\x9b\xc3\xa5\x73\xd8\x5d\x91\xc0\x1b\x23\xa1\x96\xc6\x61\xee\x86\xdd\x93\x41\xf6\x6d\x5c\xcb\x47\xcb\x1b\x4c\x6c\x8b\x6e\xf3\x48\xea\x0f\x1d\xcf\x91\x45\x1a\xbb\x59\x60\xfc\x27\x9a\xef\x21\x95\x33\x81\xdf\x46\x2f\x5b\x5c\x74\x83\xbc\x2b\x68\x6c\x85\x56\xd3\xd8\xfd\x0d\x7b\xf9\xc6\x6c\xc3\x5d\xd0\xc0\x6e\x27\x98\xc6\x0d\xa9\x3c\x90\x5e\xa8\x97\x50\xbb\x15\xec\x39\xec\xe3\x3c\xa6\xe4\x23\xb7\x15\x36\x12\x72\xc7\x02\x5b\x0c\xf7\xff\x06\x7d\xbc\x71\x8d\x2d\x92\x0e\xf7\x92\x8f\x6b\x24\xd1\xaf\x50\x3b\x6b\x24\x3b\x47\xd2\x03\xcc\xe4\x80\x7b\x7d\xd0\xcc\x0f\x26\xf6\xc4\x79\x3e\xc6\xf3\x30\x8b\x28\xe2\x0d\x31\xbd\x1e\x26\x9b\xc1\x3c\xeb\x48\x3a\x82\x19\xf4\xd0\x76\x01\x59\x77\xd1\x6b\x16\xb3\xa9\x21\xed\x33\x5a\xae\x21\xc7\x3b\xda\x0f\xb3\x2a\x81\x1d\xb7\xb0\xad\x32\xb2\xac\x62\xcf\x77\x6c\xb2\x82\xcc\xcf\xc8\xd7\x02\x8d\xef\x08\x1e\x6d\x82\x67\x07\x8d\x4e\x90\x42\x04\xe3\x1d\xd0\x6c\x09\xfb\x5e\x63\x23\x27\xe4\xf5\x83\x4d\x4f\x09\xbc\x0f\xa6\x16\x32\xd5\x05\x9b\xc8\x62\x96\x11\x6c\x65\x45\xf0\x49\x60\x5e\x55\x6c\x26\xf4\x44\x0b\x69\xde\x30\xde\x05\xd9\xdd\xd1\x43\x0b\x2d\xc4\xd0\xf3\x0f\xf6\xec\xe1\x5a\x3f\xe8\xf0\x0f\x93\x49\x61\xe2\x3b\xf4\x3c\xc7\xac\x7c\x64\xd2\xc1\xbe\x76\x48\x3e\x8d\xc4\xcb\xa8\xdf\x45\x4a\x6d\x6c\xad\x83\xcd\x9d\xb0\xb1\x1d\x32\x18\xa3\xc3\x03\xb6\x38\xc6\x26\x3f\x04\x7e\xa8\xd3\x24\xb2\x7f\x63\x5f\x4b\x24\xb5\xc7\x9e\xc7\x98\x8e\x8f\xf3\x4b\x48\x36\x87\xab\xf9\x48\x3e\xdc\x48\x71\x5c\x37\xcc\xfe\x15\x2e\xbe\x41\x4e\x7b\xe4\x1e\x45\xef\x3b\x82\x67\x19\xfb\x5a\x11\x78\x6b\x74\xf7\x85\xd6\x17\xd8\xd2\x2f\x92\xf1\xd0\xcb\x0f\x66\xd9\x46\xcb\x67\x74\xf4\x83\x44\xc3\xae\xdf\x62\x63\x63\xe4\xd8\xc3\x34\xda\xe8\x69\x8c\x19\x8c\x31\xbf\xe1\x8e\x09\xcf\x3c\xc3\xb5\x23\x04\xcf\x2a\x7a\x48\x63\x33\x45\x4c\x98\xdb\xfe\x17\x26\x76\x47\xea\x47\xcc\xf4\x86\xf1\x43\x56\xcf\xa3\xb7\x31\xb2\x6f\x22\x95\x70\xa3\xdd\xd0\xe1\x19\xa9\x66\x90\x77\x0d\x37\xe9\xa3\xa7\x1f\xcc\xaa\x88\x7c\xc2\x67\x5d\xb0\xf5\x01\x9a\x6f\xa2\xe7\x6f\xb4\x94\xc1\x7d\xf5\xb1\xef\x1e\x32\xdd\xe2\x1a\xa1\x9f\x7e\xb1\x9d\x2e\xf2\xdc\xa1\xd5\x35\x1a\x9e\xf5\xf1\x44\xfc\x1b\xb2\xcf\x61\x7e\x5a\x98\x70\x1b\x3e\x13\xb8\xee\x15\xd3\xac\xa2\xfb\x32\xb2\xfd\x45\x96\x15\x5c\x3f\x8d\xa9\x7e\xa3\x91\x1f\x64\x3f\xc3\x54\xce\xc8\xfb\x07\x2d\x97\xb1\xa9\x3e\xf6\x33\x40\x66\x0f\x6c\x72\x8f\x79\xb6\x31\xe5\x11\x66\x7d\x43\xa7\x5b\xf4\x7b\x80\xf9\x7d\xa0\xc7\x21\x12\xfb\xc3\xf8\x27\xe4\x93\xc2\xc5\x16\x48\x76\x8d\x3c\xee\xe8\x25\x85\x8e\xc2\x5c\x9b\x63\xb2\x1d\xec\x79\x8b\x99\x3d\xd1\x90\xa3\x6b\x23\x8c\xf7\xc0\xbc\x26\x68\xbe\x88\x84\xfc\xdd\xcc\x61\x27\x4d\x64\x18\x47\xf2\x33\xcc\xab\x8b\x49\x2c\xd0\x57\x9f\xe0\x59\x44\x26\x2b\xf4\xef\x88\x79\x0e\x90\x65\x1d\xc9\xe4\x70\xf3\x03\x81\xff\x41\xe6\x4d\x5c\x7d\x80\xfb\x7b\x12\xdc\x5f\xd8\xdb\x0a\x17\x7a\xbd\x10\xfe\xfe\x8d\x66\x7f\x91\xe6\x00\x3b\xc9\x63\x62\x1b\xf4\x30\x46\x1e\x5f\xd8\xdd\x1d\x79\x86\xfb\xef\x80\x4e\x92\xc8\xfc\x8a\x9e\xa3\x98\xe8\x1b\x9b\x19\xe2\xb2\x67\x6c\x3e\xe4\xbd\x27\x1a\xfe\xcd\x2e\x8a\xa6\x63\x48\x98\xe9\x1d\x0f\x19\x36\x90\x5d\x02\x39\xe4\xb0\xb7\x38\x7a\x1f\xa3\x85\x2a\xc1\xfd\x81\xcd\x86\x3a\x0d\xfd\x1e\xb2\x55\xc8\x7c\x0f\x34\x73\xc6\x8c\xa2\xe8\x64\x81\x0d\x33\x3c\xd5\xc0\x5e\x66\xe8\xbd\x81\xd4\x37\xe8\xd7\x1f\x6e\xd2\x42\xe6\x0d\x5c\x3d\x49\xe0\x1f\xb1\x9d\x12\x26\xdc\x8a\x8b\x07\xc1\xa3\x8c\x29\x17\x31\x8d\x13\x3a\x2e\xe0\xa2\x17\x24\x19\xc5\x75\x53\xd8\x6f\x8f\xc0\xaf\xe3\x36\x65\x5c\xa3\x82\x76\xea\xe8\x7e\x8b\x24\x9f\xb8\x6e\x05\x33\x29\x62\x2f\xbf\x68\x7e\x85\x7c\x46\xd8\x58\x1c\xf3\xbc\x63\xb2\x17\x34\x37\x41\x8a\x5d\xe4\xb6\x44\xa6\x27\x24\x99\x40\x07\x7d\xec\x76\x87\xdd\x75\x31\x93\x25\x66\x3e\x47\x87\x3b\xdc\xf8\x82\xdc\xc6\x98\xe1\x1a\x8d\x1d\x31\xd1\x02\xee\x9d\x20\x78\x2e\x30\xf3\x15\xb2\xf3\xd1\x71\x0c\x57\xf7\x90\xfe\x14\x8d\x56\xd0\xe8\x1e\x17\xaf\x62\xaf\x53\x34\xf7\x87\x2d\xd6\xb0\xc9\x37\xf6\x7c\x46\x87\x0d\xd4\x3f\x63\x0a\x3d\x5c\xbb\x81\x7d\xa7\x90\x85\x8f\x8c\x7f\xd1\xda\x0c\x89\xad\x30\x9b\x37\xae\xf5\x40\xb3\x7b\xcc\xf9\x17\x33\x8a\xe1\xfe\x6f\xa6\x32\x52\xc9\xe1\x3a\x57\x82\x67\x05\x69\xc6\x30\xcd\x16\xa6\x7e\x45\xd6\x29\x34\xd7\xc5\xa6\x63\x68\xf5\x8e\x7c\x8a\xd8\xce\x1b\xdb\x1f\xe3\x62\x3e\x36\x7e\x47\x6e\x6b\xb4\x30\x43\xa2\x57\xe4\x19\x47\x97\x2f\x24\x77\x24\x78\x9c\x70\xb1\x3a\x52\xc9\x12\xf8\x51\x4c\x3c\x86\x19\x35\x31\xcb\x21\xc1\xa3\x80\xcd\xec\x09\x9e\x67\x4c\xbd\x8f\x5e\x92\x04\xf7\x0e\xda\x8d\x61\xd2\x73\x74\x1d\xe6\xd7\x09\xfb\xb9\xa1\xdd\x90\x2f\x0b\x98\xe5\x12\x1b\x4f\x61\x77\x0b\xcc\x7e\x89\xbd\x97\x31\xf5\x1b\x76\x7f\x40\xaa\x29\x64\xfb\xc6\x9c\x72\xe8\xb9\x87\x7d\x67\xd1\xc4\x0c\xf3\xfb\x8d\xeb\x76\xd0\x48\x0d\x73\x6c\x13\x3c\xc2\x2d\xfe\x83\x8d\xad\x31\x87\x22\xfa\x55\x46\xaf\x31\x4c\xaa\x83\xe9\xa6\x08\xde\x0b\x34\xf6\x87\x96\xda\x04\xde\x2f\xc6\x1b\xe1\x52\x35\x4c\x3e\x86\x6b\x44\xd1\x5b\x04\x8d\xae\x30\xd9\x23\xae\x7f\xc7\x64\xfe\xb0\x97\x32\x2e\x92\xc2\x94\xd6\xb8\xce\x05\x33\x1f\x60\x96\x35\xf4\xd2\xc1\x1e\x0b\xc8\xeb\x81\xbc\x9e\x68\x2c\x8b\xbb\x6f\xb0\xd7\x3c\x92\x9e\xa1\x9d\x15\xe6\x7f\x1e\x65\x30\xcb\x90\x63\x2e\x98\xd7\x11\x9d\xec\x30\xb1\x12\x1a\x66\xde\x34\x8f\x5b\x1f\x30\x9b\x1e\x72\x1a\x23\xa9\x1a\x12\xee\xd9\xdd\x07\xbb\xab\xa2\x97\x3b\x7a\x0a\xf9\xfd\x85\xfd\x0c\x31\xe3\x24\xa6\x99\xc2\x9e\x6f\xe8\xb3\x8c\x59\x7d\x90\xd4\x08\xf9\x5d\x63\xe3\x51\x6c\x6e\x87\xc9\x4e\x90\x72\x0f\xdb\x8d\x20\xf3\x39\xee\x3e\x45\x8e\x1b\xcc\x3b\x87\xa4\x37\x04\xf7\x23\x32\x6e\x63\xfc\x36\x2e\x79\xc1\x7e\x17\x31\xbd\x14\xae\x31\x46\xbc\x0e\x66\xf3\x40\x52\x3e\x36\xdc\x9b\xd5\x04\x76\xb2\xc1\x6c\xf2\x68\xbe\x86\xc4\xbb\x68\xeb\x80\xab\xbd\x71\xf7\x21\xfa\x4c\xa1\xc7\x0c\xa6\x9f\xc5\x34\xcb\xe8\xcd\x47\xa7\x35\xcc\xba\x85\x19\x0f\x70\xc3\x35\x2e\xf2\x44\xb3\x1b\x82\xf7\x0a\x49\x67\xd1\x82\x87\x99\xb4\xd0\xd1\x0b\x13\xab\xa1\x83\x1d\x1a\x9b\xe2\x16\x65\x24\x37\xc0\x1e\x7e\xb0\xef\x17\x92\x8f\xe3\xee\x1f\xb4\xb5\x40\x2a\x61\x46\xf6\x31\x21\xa7\x0f\xf3\xd8\x77\x0e\x0d\xef\x63\xbe\x45\x2b\x7f\xb8\x9f\x18\xf6\xfd\x8d\xe4\xc3\x1c\x9b\x12\x3c\xf7\xd8\x5a\x1e\xe3\xd7\x70\xbd\x37\xc1\x3d\x64\xb0\x0b\xb2\x4c\xa1\xf9\x21\xb2\x4d\x63\xdf\x55\x5c\xe7\x0b\xd7\xfb\x42\x42\xee\xab\x27\x90\x73\x1a\xc9\xfe\x20\x91\x31\x52\x4a\x22\xb5\x3f\xdc\xfa\x8a\x6d\xee\x90\xcc\x0d\x6d\xce\x31\x5f\x3f\xd8\x4b\x1e\x99\x67\x09\x5e\x3d\xf4\x92\x46\x9f\xbf\x68\x2f\x3c\x67\x1a\x57\xeb\xa0\xe3\x38\x9a\xbd\x12\xf8\x0d\xec\xa7\x41\xf0\x69\x11\x78\x65\x6c\xb2\x81\xfb\xce\xa3\xd3\x03\x76\x91\x42\xc7\x29\x34\x96\x40\xca\x0d\xb4\xf6\x8d\xfb\x69\x21\xf9\x36\xda\xf2\xd0\xe3\x1d\xd9\xcc\x90\x4a\x05\xd9\x0c\xd1\xfb\x08\x39\x64\x30\xcd\x37\xb2\xe8\xa0\xf1\x3e\x81\xbf\xc7\xe4\x47\xd8\x78\x04\xbb\xaf\xa0\xb9\x1e\xae\x9f\x45\xc7\x55\x24\xe4\xcc\x76\x0f\x3b\xde\x63\x7a\x2d\xf4\xde\xc2\x26\xca\xd8\x4b\x13\xbd\x16\x30\x8d\x3e\xda\x7b\xe0\xda\x49\x6c\xac\x80\xd4\xd7\x48\x29\x8b\x89\xc7\x31\xde\x1f\xba\x4b\xa2\xed\x15\xc1\xf3\x07\xd3\x4a\x63\x92\x5b\xa4\xfc\xc0\xd5\xb2\x68\x65\x83\x2d\x94\x30\x7f\x4f\x5c\xf2\x86\x44\x6f\xc8\xb3\x8e\x6b\xcc\xd1\x68\x78\xa7\x7b\x64\x50\xc5\x3d\x7d\xcc\xe7\x89\xf1\xae\x48\xb9\x83\xc9\x1f\x70\x91\x2d\xe6\x55\xc1\xf8\x7d\x74\xda\x45\x73\x55\x6c\x6a\x85\x6d\xfc\x21\x3b\x0f\xf7\x33\xc3\xac\x53\x48\xea\x8a\x7e\xef\x90\x54\x01\x09\x77\x5a\xfa\x8e\xf1\x93\xc8\x20\xd4\xb8\x87\x49\xec\xb1\xaf\x3d\xfa\x37\x45\x3b\x79\x4c\x7b\x81\xbc\xc7\xb8\xc6\x06\xd7\x58\x10\xdc\x97\x68\xeb\x0f\xd7\xf0\x91\xef\x04\x5a\xe9\xa3\xd9\x2a\x2e\x16\x21\xf0\x36\xb8\xe4\x0e\xfb\xc9\x60\x33\x35\x6c\x22\x85\x4b\x5e\x71\xad\x23\xf2\x59\xe2\x92\x5d\xdc\xf8\x85\x79\xbf\xd0\xeb\x0a\x29\xde\x09\xfc\x16\xae\x13\x6a\x73\x88\xc6\xd7\xe8\x60\x83\x2c\xbb\xd8\x58\x17\x2d\x66\x71\xd3\x36\xfa\x8c\xa1\xed\x14\xfa\xe7\x21\x95\x37\x2e\x5e\xc2\xc4\x6f\xe8\x21\x8a\x54\x2f\xb8\xf9\x1e\x5b\x59\xe2\x7a\x49\x5c\x6c\x8b\xfd\x44\x31\xe9\x2f\xb4\x56\x43\x96\x3e\xf6\x72\x46\xb6\x67\x4c\x7c\x81\x44\x3c\xe4\x5e\x41\x9b\x55\x5c\x3d\x8e\xb6\x56\xb8\x54\x1a\x5b\x9d\xe2\xc2\xad\xd2\x0b\x39\xf6\x83\xe6\x0b\x48\x2c\x89\x4d\x3e\x90\xc5\x1c\x2d\x67\xb1\xe7\x19\x9a\x4f\xa1\x9b\x1f\x6c\x75\x8c\x8d\x7b\x04\xf7\x09\x7a\x59\x23\xe1\x99\xda\x31\xe4\xfb\x17\x2d\x8c\xb1\xcb\x0c\xf6\xfc\x83\xfe\x67\x98\x33\x7a\x08\x7f\x2e\x20\xa9\xb0\xd7\x3c\x64\xd9\xc7\xee\xc3\xec\xb8\x22\xb9\x70\x5f\xff\x61\xc3\x9d\xd6\x2e\x63\x43\x26\xef\x65\x70\x3f\x55\x82\x47\x03\xf5\x7e\x08\xee\x3d\xa4\x38\x41\x73\x0f\x5c\xeb\x86\xd4\x56\x48\x66\x8b\x5b\xbf\x31\x61\x5e\xc4\x86\x68\xb5\x8d\xab\xd7\xd0\xd2\x0d\x37\x49\x23\x0f\x1f\x1d\x26\xd0\xf8\x08\x8d\xaf\x08\x5e\x27\x02\x3f\x8d\x4d\x86\x8c\x36\x40\xaf\x33\x24\x5b\xc5\x7c\x2f\x91\xd1\x18\x3d\x3d\xb1\xd5\x03\xe6\xb5\xc6\xf5\x8b\x68\xf1\x1b\x1b\x2f\x61\xf3\x45\xd4\x0f\x39\x7c\x8d\x16\x93\xe8\xa3\x8d\x19\x15\x71\xfd\x6f\x5c\xec\x82\xad\x24\x30\xcd\x1d\x7a\x0b\xf7\x4d\xd8\x0b\x39\xcc\xf1\x07\x13\x6f\x23\xdb\x0f\x3a\x9e\xa2\x99\x0c\x6e\x7d\x42\x7e\x63\xd8\xe9\x17\xf2\xee\x60\xb6\x1b\xb4\x58\xc1\xc6\x46\x68\xad\x8a\x76\x6a\xd8\xf7\x0a\xdd\x7e\xb0\xa5\x23\x5a\xcd\xa1\x95\x24\x2e\x79\x40\x0e\x65\x4c\xf3\x17\xa9\x47\xb0\x61\xa6\x8e\x2e\xe8\xf1\x17\xd3\x3d\x60\xbe\x92\x48\x79\x84\x6b\x47\xb1\xa5\x03\xfa\x75\xc4\xbe\x9b\xb8\xda\x1a\xd3\x0a\x77\xd2\x00\xb9\xdd\x70\xf3\x0f\x66\x7e\x27\xb8\xb7\x31\xa5\x04\xea\x85\x5e\xdd\xe3\x22\x3e\xf2\xda\x20\xfb\x70\xdb\x7d\x90\xc5\x0a\x9b\x4d\x23\x95\x6f\xdc\x70\x81\x46\x56\x98\xe1\x16\xdd\xa4\xf9\x17\x00\x00\xff\xff\xbf\x1b\x72\xe3\x00\x20\x00\x00") -func keysWordlistChinese_simplifiedTxtBytes() ([]byte, error) { +func keysWordsWordlistChinese_simplifiedTxtBytes() ([]byte, error) { return bindataRead( - _keysWordlistChinese_simplifiedTxt, - "keys/wordlist/chinese_simplified.txt", + _keysWordsWordlistChinese_simplifiedTxt, + "keys/words/wordlist/chinese_simplified.txt", ) } -func keysWordlistChinese_simplifiedTxt() (*asset, error) { - bytes, err := keysWordlistChinese_simplifiedTxtBytes() +func keysWordsWordlistChinese_simplifiedTxt() (*asset, error) { + bytes, err := keysWordsWordlistChinese_simplifiedTxtBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "keys/wordlist/chinese_simplified.txt", size: 8192, mode: os.FileMode(420), modTime: time.Unix(1511602021, 0)} + info := bindataFileInfo{name: "keys/words/wordlist/chinese_simplified.txt", size: 8192, mode: os.FileMode(420), modTime: time.Unix(1514928181, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _keysWordlistEnglishTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\x5b\xdd\xbe\xbc\x2a\x08\xbd\xf7\x2d\xc9\xa8\xd8\xa3\xe2\x41\x9d\x76\xfb\xe9\xcf\x6f\xad\xfe\x17\x83\xe5\x07\x2a\x22\x2c\xcc\x91\x4d\xda\xee\x2d\xc9\x66\xc5\xe6\x93\x64\x2b\x9a\x64\xf3\x35\x41\xbf\x78\x1e\xda\xf0\x32\x3c\x36\x24\x33\x24\xf3\x7d\xc5\x9e\x64\x5b\x43\x93\xe4\xac\x63\x20\xb1\x9d\x95\x73\xf6\xf5\xa6\x6f\xf1\x65\x0a\x56\xd9\xf6\x24\xd9\xd7\x98\x96\x93\xe4\xff\x96\x05\x72\xc3\xd9\x18\xf5\xa7\x61\x2c\x79\x7a\x80\xc6\xcb\x75\x2e\x29\x49\x76\xe9\x33\xc9\xbe\xe3\x67\x99\x8f\x6f\xf9\xfe\xb3\x06\x5e\xab\x81\xae\x02\xfa\x95\x96\x15\xa9\x21\xd1\xf0\x0d\x3d\x1e\x87\x58\x20\x71\x0c\xfd\x08\xc1\x78\x4e\xb1\x96\xe4\x54\xfc\x30\xe6\x33\x54\x93\x5c\x2a\x7b\x12\xab\x89\x2d\x2c\xba\xc7\x4c\x62\x03\xd2\x29\x12\x35\x49\xd9\x16\x68\xf6\xcb\x4b\x92\xa2\x28\x2f\xa6\x2d\x49\xc1\x7b\xd1\x07\xd4\xef\x24\xa5\x3a\x06\x58\xbc\xa1\x71\xbf\x24\x49\x09\x95\x1d\x15\x86\x27\x29\x53\x23\x49\xb9\xe5\x19\x49\xaa\x4c\x5d\x81\xf4\xcf\xda\x99\xa4\xfa\x4b\x29\xcf\xba\x86\xee\x49\x9a\x94\x07\x1c\x5b\xbe\x20\xa8\x96\x8d\x23\x6f\x27\xf8\xb4\x13\x63\x6c\x67\x3c\x49\x9a\x55\x88\xae\x7d\x98\xd5\x7c\x51\x2a\xad\x51\xa0\xcd\xe7\xc5\x06\xe3\x66\x32\xb5\x35\x41\x6a\xff\x2d\xd4\xfa\x35\x85\x42\xb4\x27\x49\x17\xcc\xae\x7b\xf1\x13\x6f\x5d\x25\x90\x80\x6b\xef\x41\x35\xe9\x61\x25\x49\xe4\x0b\x84\xeb\x1b\x2a\x20\xe0\x19\x27\x38\x42\x6a\x51\x31\x81\xa8\x18\x77\xd4\x27\x49\xf8\x6a\xc8\x09\x0c\x1f\xa9\x62\x66\x11\xf6\xe5\x1b\xe4\x87\xbe\x63\xea\x41\x15\x89\x69\xac\x30\x6f\x8f\x4f\x92\x81\x5f\x57\x94\x8c\x21\x5c\xfc\x31\x94\x94\xf5\xc6\x58\x55\x93\x8c\x79\x55\x49\x32\xaf\xa2\x53\x93\x4c\xaf\x49\xe6\x94\xfc\x41\xa2\x18\xc0\x9c\x36\xd7\x8e\xb2\x7f\x0a\xbe\xfe\x29\xe3\xda\xa1\x57\xeb\xa4\x92\x71\x15\xd6\xa4\xd8\xd7\x74\x90\x55\x5b\x92\xaf\x06\x55\xe8\xeb\x59\x76\x47\x0a\xd5\xba\xe5\xa3\xa0\x41\xfa\x24\xb9\x75\x38\x86\x73\x1f\xab\x24\xb9\x3f\xb7\x40\x11\x7f\x6d\xa4\x4d\xb6\x27\x6d\x92\x2f\x2d\x1e\x78\xf0\x96\x36\xd9\x4f\x4d\x9b\x9c\x69\x93\x42\x85\xde\xa0\x6f\x0d\x15\x4b\x49\x9b\xd4\xcd\x3d\x6d\xd2\xa4\x09\x92\xa6\x68\xc9\x9f\x16\x54\x0a\xea\xf6\x06\xa1\xa2\xfa\x00\x83\x61\x19\xf4\xa3\x33\x6d\x32\x67\xd1\xb4\xa9\xe4\x0b\xb4\x81\xac\xf9\xa4\x4d\xb3\x60\xe3\x6e\x9a\x31\xdc\x4d\xf5\x48\x9b\x1e\x1e\x78\x3e\xc1\x52\x2f\xf9\xe2\xe5\xb2\xb6\xa7\x4d\x0b\xf7\xf7\xa6\x50\xf7\x4d\xcb\x4c\x9b\x36\xf2\x6c\x7a\x18\xde\x06\xc8\x0c\x01\xef\x09\x75\xdf\x74\xde\xaa\xe0\xf4\x38\x58\x58\x7e\x32\xc6\x62\x78\xfe\xe0\x81\xb9\xaf\xc6\x6d\x16\x78\x89\x79\xa5\xcd\xde\xe6\x05\x6b\xb7\x15\xd9\x15\xb4\x92\x36\x4e\xaa\x08\x3a\x2b\x2a\x28\x87\x81\xd8\x0a\x79\x15\x77\xd2\x31\xbc\x22\xe5\x04\xcb\x22\x01\xc3\x35\xae\xb4\x39\x16\x64\x73\x99\x69\xf3\xfd\x49\x9b\x5b\x49\x9b\xd7\x2d\x6d\xd8\xbc\x9b\xb7\x35\xd2\xe6\xfe\x01\x41\x37\x1e\x3b\x46\xe3\x81\xbd\xba\x39\xf5\x75\x83\x39\xdb\x7c\x42\xc9\xb6\x77\xcb\x6d\xfe\x9b\x36\x7f\xd2\x16\x92\x39\xc8\xe0\xc2\x84\x60\x60\x21\xa8\x1f\x14\x28\xcc\x02\xa8\xfe\xe1\xc5\x30\xc7\x30\x6a\x41\x18\x16\x21\xec\xbc\xd0\x9c\xdd\x85\x0d\x94\x7b\xce\x5e\x0c\x0f\x1f\x08\x34\xbc\xb1\xb1\xa3\xfb\x78\xf7\xf8\x16\x7e\xa3\x88\x73\x5c\x1b\x6c\xfc\xb6\x76\x4c\x70\xed\x27\xc6\xb3\x8e\x43\x8a\xa7\x6d\x59\xd9\xd3\xb6\xca\x06\xf2\x01\x29\x2c\x6e\x3b\x9b\xb4\x0f\x98\xad\xd8\xd1\xd1\x8a\xf3\x7d\x83\x20\x20\x97\x35\xac\x51\xe0\x6b\x80\xf3\xbb\x50\xeb\x21\xfd\xfb\x4b\x59\xb6\x0d\x9b\x24\xcb\x66\x0d\xb4\xe0\x39\xcf\x35\x52\x7e\xf3\x3f\x20\xa5\x80\xd4\x94\xa5\x6a\x08\x92\x9e\xb2\xa0\x41\x13\x14\xb5\xac\x4c\xf6\x07\xb4\x39\x4b\x1c\x2d\xdb\x57\xc0\xaa\x3d\xcc\xeb\xff\x3a\xe8\x36\xd9\xae\x4f\x61\xb7\x81\xdf\xc6\x2a\xb1\x83\x9c\x0e\xda\x75\x22\x09\x70\x0d\x3c\x0e\x34\x1e\x17\x88\x35\x54\x19\x93\xfc\xc6\x22\x3b\x54\x99\x52\xfc\x44\x9a\x51\x6d\xea\xe9\x6c\x3e\xdf\x8a\x0b\x4b\xf5\x6e\xa4\x2c\x8b\xc6\x24\x63\x91\xb3\x5a\xc1\xfa\x65\x2d\x8a\xfa\x5a\x61\xbd\xb3\xb6\x01\x49\x68\x9b\x8b\xb9\xa1\xe8\x47\xe3\x1d\xf6\x05\x3f\x94\x2f\x29\x1f\xd0\xda\xc9\xed\xa2\xcd\xcc\x97\xf8\x00\xed\x10\x78\xbe\x24\xde\xcc\x41\x3a\x53\xbe\x54\x3a\x68\x46\x5b\x55\xe6\xeb\x01\xc2\xe9\x5e\xd8\x9d\xf9\xb2\x0c\xf5\x81\xab\x46\x11\xf4\x20\x5f\x56\x9b\xa2\x86\xc3\x8d\xe6\xcb\x9d\x6d\xc3\x9b\xe5\x94\xaf\x95\xe1\x57\xf2\xb5\x1a\x18\xaf\x68\x29\xdb\x09\xf9\x5a\x6b\xf0\x5b\x29\x5b\x60\x53\x67\x9b\xf6\x07\xde\x00\x18\xd9\xbe\x56\x52\x2e\xf0\xad\xb9\x60\x60\x45\xc2\x8e\x07\xe9\x0d\x82\x27\xd8\xa2\x5c\x34\x3e\xa0\x5f\xcc\xaa\x60\x2f\xe4\x42\x47\x97\x8b\x1d\x07\x68\xdd\x40\x39\x98\x62\xe0\xe4\xac\x84\x35\x29\x1c\x6a\xf1\x79\x81\xae\x1d\xf4\x06\xd3\x85\x36\x0b\x3a\x55\xd6\xa0\xc0\xca\xe2\xfa\xb9\xbc\x14\xc2\xf0\xec\x6d\x21\xdd\x35\x65\x3f\x0e\x45\x82\x61\x3b\xd6\xc2\x4b\x81\xc3\xc9\x0e\x53\x9d\xbd\xc0\x03\x64\xaf\x9b\x35\x54\xab\x24\x07\xf0\x42\xf6\x8a\xb1\x79\xa5\x30\xbc\x76\x38\xd3\xec\x0d\xab\x8a\x74\x5f\x64\xd3\x0e\x8b\x8a\xf4\x24\xa0\xc9\xde\xda\xcb\xbf\x0d\x83\x79\xc9\xde\x66\x38\x7a\x6f\x5f\x83\x39\xc9\xb0\x40\xd9\x99\xd5\x3b\x6b\x74\x30\x0e\x68\x0c\xac\x74\x76\x2c\x86\x47\xbc\x7c\x38\xa5\x39\x39\x88\xc5\x59\xae\x36\xb1\xf4\xbe\xe0\xc3\xb3\xaf\x18\x4c\x06\xa7\x47\x81\xfb\xe3\x53\x53\x86\xc1\x02\xc5\xfe\xcf\x21\xc7\x04\xad\x20\x8d\x19\xd8\x20\x21\x94\x63\xc8\x5d\x40\xff\x9e\x94\x43\x59\x49\xe1\x3b\x73\xa8\x82\x87\xde\x29\xc3\xa4\x61\xa3\x85\x41\x4c\x61\xa3\x83\x02\x2e\xe4\x70\x3c\xc3\x76\xe6\x78\x47\x19\x7e\xef\x29\xc7\xca\x86\x79\xc5\x52\x52\xc3\x50\x63\x55\xee\xee\x58\x8d\x35\x17\xc7\x81\x8e\x9f\xc1\xed\xbe\x36\x4d\x79\x95\xb9\x20\x8d\xd5\xf1\x7b\x8d\x7b\x5e\x61\x8e\x8d\xb6\x22\xa8\x4c\xeb\xdf\x0e\x5b\x81\xbd\xb9\xc6\xc5\xad\xb5\x06\xcc\x77\x5e\x90\x01\x3d\xd3\x2e\x7b\xda\xa5\xc2\x50\xed\x30\x49\x3b\x1d\xf2\xfe\x82\xae\x5d\x68\x91\x77\x88\x63\xe7\xc6\x67\xe6\xdd\xd2\x2e\x4f\xda\xb1\x93\x77\xdd\x64\x2a\x92\xb0\x91\x76\xcd\x70\x5d\xbb\x66\xad\x1b\xea\x2a\xa0\x33\x92\x02\x2d\xda\x15\x8b\xc9\xea\x10\xe5\xc0\x03\x6b\x1d\xda\xf8\x72\xbc\xb5\x0e\x30\x27\x60\xdd\xb5\xb0\xa7\x62\x5f\x56\xac\x70\x2d\xbb\x56\x63\xf5\x66\x1c\x41\x23\x76\xda\xb5\xa1\x26\x31\xdd\xae\x5d\x59\xb1\xfb\x30\xbe\xce\x0b\x14\x28\x60\x57\x82\xb0\x5d\x47\x0e\xdb\xf8\xa0\x6c\x32\xec\x6c\x48\x3e\x20\x1d\x86\x69\xd7\x31\xc3\xd1\x64\x8a\xa1\xa7\x09\xc5\xdb\xf5\xab\xc5\x3b\x52\xd8\x8f\x5d\xbf\x50\xa9\xdd\xe4\x84\x0a\xed\x1c\x93\xc1\x50\xec\x48\xe3\x49\x3b\xab\x99\x0e\x45\x89\xce\xb4\xdb\x71\x60\x3a\x76\xd2\x88\xef\x76\x36\xd8\x90\xdd\x8a\xd6\x2a\x69\x37\x62\x9e\xdd\x9a\x0f\x59\x78\xa0\xc2\xef\x86\x61\xda\x78\xa1\xfc\x6e\xe3\x55\xe9\xdd\xc6\x2b\x4a\xc3\x2a\xd9\xa8\x36\x06\xd2\xd7\x87\xef\x36\x3a\x45\x68\x63\xbe\x4b\x0b\x49\x82\xcf\x97\x2b\x63\x5f\x0f\xe6\xfe\xfd\x3d\x69\x77\x86\x28\xbb\xe7\x45\xe3\xbd\xfb\x99\x76\x2f\x05\xa4\x5f\xd6\xd2\xee\x55\x98\x34\xae\xa2\xb7\x8f\xa2\x55\x63\x23\x12\x0c\xc4\x17\x94\x78\x07\x7e\xde\xb9\xb7\xf6\x90\xd3\x1b\x12\xcc\x2e\x84\x81\xd2\x1e\x72\xa7\x9d\x3b\xea\x8d\x78\xf6\x30\xd6\x35\x74\x18\xd6\x3e\xa0\x1d\x84\x8c\x20\xf1\x58\xa8\xfc\xa4\x7d\xe5\x4f\xda\x57\xdd\xd2\xbe\xa0\x31\xeb\xd5\x53\x60\xd9\x9d\x66\x6f\xe7\x4a\xdf\x12\x47\xda\x9f\x26\xb0\x57\x2a\x50\x69\x15\xc4\x11\x2a\x51\x1e\xd0\x06\x32\xaf\xa4\x32\x8c\x39\x63\x82\x3c\x49\xf3\xe5\x49\xf3\x0b\xd4\x34\x7b\xf3\xfa\x24\x05\x64\xe1\xe6\xd7\x7d\xc1\x33\x26\x3d\x68\x11\xf5\x3c\x93\x12\xc3\xa8\x11\x99\x68\xd9\xfc\x4e\x5a\x76\x3e\x6b\x9e\x81\x11\x14\x3d\xa5\x4d\xa4\x14\xaf\x16\xed\xd7\xbf\x8c\xaf\x40\xf2\x5a\x0c\x4c\xcb\xd0\xa4\x75\x93\xf8\x20\x01\x62\xd3\x0a\x8c\x85\x5c\x85\x1b\xd4\xea\x74\xbc\x5a\x7b\x71\x94\x76\x47\xb0\xa3\xb5\xcf\x27\x69\x23\x44\xd0\x06\xbc\x8f\x6d\xa0\x80\x39\x63\x20\x75\x58\x44\x6d\x8a\xc9\x34\x0d\xcc\xad\x1d\xd4\x00\x6d\x27\x8c\x80\xb6\x13\x7b\x50\xdb\x45\x6d\xd1\xf6\x03\xfe\xad\x60\x87\x69\xf3\x75\x5e\x49\x5b\x58\x66\x02\xd5\x80\x7f\x0f\x54\x84\x6d\xc0\x56\x7c\x5f\x02\xad\xb8\x4f\x34\x69\xb7\x01\x97\xa3\xff\x01\x63\xe8\x7f\xcb\x7a\x02\x06\xd2\x80\xde\x6a\xb0\x2c\x7c\x70\x46\x11\x90\x43\xac\x3e\x93\x8e\x2c\x68\x3e\x86\x3c\xa0\xca\x11\x8d\x49\xc1\x4f\x0d\x00\x27\x9d\x97\xe5\x91\x14\xda\xcc\x62\xb8\x61\xfd\xfa\x07\x8f\x5e\xbe\x9a\xf4\x97\x72\xf8\x95\x0a\xa7\xa0\xbf\x8c\xe9\xf5\xf7\x1f\xca\xd0\xdf\x4c\x91\xff\xe6\x82\x30\x49\x7f\x19\xda\xeb\xaf\xd2\x46\xea\xaf\x46\x36\x66\x5c\x02\xed\xd2\xdf\xcb\x36\xac\xff\xaf\x91\x19\xc5\xf2\xcb\x0c\x87\x52\xeb\x6f\x87\x85\xd2\x5f\xc6\x6e\xfa\xdb\x29\x8e\xdf\x5e\xb0\x6d\xf4\xb7\x3b\x79\xf5\x78\xc7\xc0\x10\x4d\x7f\x27\x64\xf1\x28\x7e\x40\xb4\xe9\x10\x60\xe4\x74\x60\xc1\x0f\x81\xb9\x7f\xd2\x01\xbb\x7a\x88\xb5\x09\x3a\xaf\x74\x00\x51\x1e\x02\x55\x39\x10\x28\x1c\x52\xa1\xc1\x07\x62\xea\x91\x0e\x69\xf8\x65\x64\xb4\x09\x85\x3e\x10\xa7\x1e\xf2\xfa\x81\x43\xc0\x06\xb6\xe7\x10\xea\xeb\x21\xd3\x10\xcc\x1e\x8c\x35\x0f\xf9\x7a\x40\x2c\x87\x0a\x5d\xcd\xa1\x5b\x2c\x98\xb2\x43\x77\x85\x3b\x06\x74\x38\x54\x77\x10\xbc\x55\x29\xc8\xc0\x0a\x1c\x3a\xa6\x7d\x59\x07\x3b\xf1\x20\xd0\x39\xf4\x4e\x87\xc1\x25\x1c\xf6\x06\xa0\x87\x69\xd9\xd3\x61\x27\xf9\x43\x9a\x87\x95\x0a\x32\x59\x0b\x8b\x7b\x20\xc2\xa1\x4f\x38\x8c\x0e\xe9\xb0\x06\x2b\x77\x18\xdb\x60\x42\x06\x98\x7e\xd8\xc8\xac\xce\x32\xbc\x4f\x22\xf6\xc3\x7e\xd3\x51\xe4\x04\x81\x88\x0a\x1c\xd9\x51\x30\xf9\x82\x29\xa6\xa3\x60\x1e\x85\x3b\xf7\x00\xd6\x3a\x8a\xb3\x14\x88\xeb\x28\xce\x2a\xdc\x5a\x47\x59\xb6\x83\x92\xc3\x93\x0e\x97\x9a\x0e\xcf\x90\xb5\x9f\xe9\x00\x8c\x3a\x1c\x33\x72\x9e\x8e\x1c\x08\xcb\x0e\xf7\x99\xde\xed\x85\x28\x73\xf0\x05\x81\xc9\x81\x20\x1f\x96\x03\xd6\xeb\x70\x98\xb5\xc3\x83\x61\xf3\xe1\x63\x90\x17\x51\xdc\xc1\x63\x84\xc3\x7f\xd3\x11\x72\x52\x4a\xc1\xa9\x84\xfe\xb7\x60\x43\x8e\x50\x8c\x28\x0c\xaa\x74\xc0\x0c\xa2\x10\x23\x0a\x67\x31\x50\xd2\xc1\x38\xe9\x08\x07\x5c\x3d\x62\x41\x44\x80\x1d\xc7\x6a\xf8\xb5\x27\x1d\x2b\x1a\xd5\x0d\x20\xfd\x58\x5c\xf4\x53\x18\x44\x31\xd8\x3e\xa5\xc8\xef\x83\x84\xe0\xfe\xc4\x18\x4e\xe9\xe9\x14\x1e\x10\x9c\x12\xdb\xbf\x14\x31\xd4\x29\x51\x2c\x23\xa1\x9d\x3b\x65\xe0\x87\xda\x13\x75\xa8\x71\xa7\x2c\x36\xf8\xd3\x74\xc2\x14\x49\x41\x6a\x6b\x20\x09\x66\x22\xde\x38\xb5\x2d\x28\xc0\xa9\xe3\x1d\xd4\x85\x09\x9d\x06\xb3\x79\xc2\x5f\x9c\x76\xc2\xa2\x9f\xaf\x82\x9c\x16\x72\x1c\x78\x8d\x92\x4e\x38\x8e\xb3\xc8\x0e\x02\xd5\x3c\x8b\x04\xe9\x18\xe9\x2c\xf0\x7f\x67\xb1\xda\x07\x52\xdf\x48\xbd\x82\x62\x8a\xc5\xd9\xda\xef\x74\x22\x9c\x3e\xa1\x18\xa7\xef\x3b\x14\xeb\xc4\x4a\x9f\x58\xe2\x93\xc1\xc3\xe9\xf0\x5a\x92\x4e\x1f\x5d\x0b\x92\x61\x3d\x9d\xf0\xcf\x2d\x9d\x10\xfe\x19\xb2\x81\x60\x14\x8c\x92\xcf\xe0\x14\x02\x16\xee\x64\xac\x7c\x86\x7c\x01\x03\xce\x50\x74\x15\x0a\x49\x86\xed\x20\x7a\x80\x22\xd7\x33\x17\x20\x7c\x75\xd0\x3b\x9d\xb1\xc0\x68\x41\x79\xce\xc5\xd1\x2d\x4e\x6d\x59\x41\xbe\x4d\x89\x74\xae\x96\xce\xa7\xa6\x4b\x60\xbd\x18\x75\x5d\x52\x8e\x74\x49\xad\x8a\xe7\x4a\x75\xbb\x60\xbc\x2e\xe9\xfd\x49\x17\xa2\x49\xe4\x04\x72\x62\x5c\xa0\x5f\xe8\x30\x82\x2f\x9e\x93\x5c\x72\x7f\xd2\x25\x7f\xac\x82\x08\xff\x52\x29\xf3\x42\x12\x13\xf4\xfb\xa4\x0b\x3e\xf3\xf2\x33\x5d\xaf\x7f\xbc\xb4\x14\x07\xad\xca\x97\x9e\x2e\x6d\xe9\xd2\xf0\x74\xd9\x0e\xe5\xb9\xec\xbc\xd2\x05\x10\x70\xc1\xda\x5d\xd6\xd3\x85\xfd\x7e\xd9\x98\x58\x98\xcb\xb7\x0d\x34\x03\x7b\x5c\x58\x88\xcb\x8b\x82\x18\x50\xe9\xf5\xee\xbf\x0b\x01\xcb\xe5\x8d\x75\x1c\x75\x3a\xde\xa3\x81\xc0\xc5\x5c\x74\x85\x97\x8f\x37\x90\xa6\x5a\x5d\x3e\x15\x8f\x0b\xc5\x30\x5b\xd7\xda\xd2\x05\x3d\xbd\x56\x95\x06\x0a\xcf\x7a\xad\x0a\x06\xab\xed\xa1\x3b\xd2\x13\xc3\xc2\x2a\x5c\x2b\x76\x56\x08\xe6\x40\x0a\x6b\x6c\x14\xea\xb3\x61\x29\x81\x04\x2d\x7b\x4b\xb6\xab\x24\x1e\x2b\x23\x48\x34\xb4\xb2\xb3\x21\xc8\xc1\xcc\xad\x00\x2a\x30\xa5\x21\x33\x02\x74\xab\x46\xdf\x67\xb5\x12\x2f\x5b\xad\xb0\x1f\x56\x3b\x3c\x9c\x55\x7a\x17\xab\xef\xc9\xa5\xd5\xbe\xe0\x1c\x0c\x91\x84\xb5\xd7\xbd\x59\x63\x20\x67\xed\x1f\xfc\xb6\xb6\xeb\x2f\xa8\x11\xcd\x58\x23\x8a\xb3\x06\x24\x15\x4f\xb2\x06\xef\x81\xa4\x58\x66\xea\x51\x93\xb5\x0b\xd6\xde\xda\xa5\x50\x49\x6b\x36\x81\x79\xad\xfd\x28\x2b\xfd\x2c\x36\xad\x2f\x47\x20\x59\x6b\xcd\xb3\x92\x53\x5f\xa0\xff\x2d\x63\x9d\x81\x70\xcb\xda\x78\x1b\x22\x2c\x44\x42\xa7\x69\x0d\x11\x0f\xd8\x4e\xce\x0e\xf8\x02\xda\x67\x6d\x7a\xb2\xf6\x7d\x9f\xbf\xc6\x4e\x5e\x4f\x6f\x01\xc1\x8e\x02\x79\xdb\xf0\xc2\x01\x8c\xb1\x34\xd9\xd4\x9a\x00\x75\x9f\xf4\xf3\x1e\x55\xfd\x08\x76\x4c\xfa\xe1\xef\xef\x2f\xfd\xa8\x14\x38\xce\x1f\x95\x06\x5a\xca\x93\x7e\xf4\xd6\x92\x7e\x7c\x4b\x3f\x08\x90\x7f\x00\x2a\x7e\x7c\x05\x94\x0a\xb0\xe8\x67\x01\x0f\xfe\x2c\x2c\xea\x0f\x62\xef\x9f\xc5\x53\xea\x9f\xd5\xcc\x03\xc9\x27\xf1\x10\xff\x23\xed\x94\x70\x4f\x1f\xec\xe9\x8f\x6a\x4f\x1f\x38\xc7\x85\xf4\x49\x1f\xcb\x9f\xf4\xb1\x1d\xbf\xc6\xf7\x86\xe7\x76\xee\x5e\xd3\x07\x70\xfe\x63\x13\xbf\x8c\xbd\xf2\xc1\x94\x3f\x36\x27\x9f\x6f\x4b\x9f\xa6\x9a\x3e\xcd\x0e\x50\x38\xae\x4f\xf3\x3b\x15\xd9\xf0\xd3\x02\xea\x91\x8a\xec\x00\xa3\x45\xf6\x27\x15\xf9\x68\x2a\x08\xf7\x8a\xb4\x73\x41\xb7\x8a\xf4\xe9\x78\x0f\xbe\x4c\x56\x9d\xd6\x52\x41\xdc\x07\xda\x00\xbc\x8b\x7c\x25\x15\x01\xfb\x1b\x65\xf7\x80\x33\x29\xf2\xb0\xfe\xdf\x93\x8a\x0a\xbb\x51\x39\x40\xa2\x81\x7e\x35\x01\x03\xc3\x7e\x17\x3d\x66\x2a\x7a\xa6\x57\xc1\x8b\x9e\x70\x5c\x45\x6d\xbc\xa5\xd5\xd1\x82\x59\xed\x9c\x17\x92\x91\x8a\x7a\x87\x91\x01\x8a\x65\x39\xcf\xe0\x0a\xe2\xb0\x54\x4c\x22\x15\x40\x8b\xf9\x20\x0d\xc0\x94\x62\x99\x3b\xa4\x40\x28\x05\x6e\xe2\xf5\xf1\xc5\x30\x71\xab\x1b\x08\x06\x8e\x28\xa3\x00\x8e\x14\xfb\x0f\x0e\x9e\x38\xb7\x18\x8f\xba\x10\x73\xa6\x62\x34\x6f\xc5\x85\xa4\xa5\xe2\x1b\x4d\x65\x71\x40\x0e\x02\x85\xe2\xa7\xe5\x54\xbc\x69\x79\x90\x9c\xa9\x38\x64\xe9\x18\x26\x72\x16\xda\x2e\xb8\x66\x3a\x95\xe2\x0f\x9a\xae\xfc\x79\x52\x59\x27\x71\x77\x59\x0c\x98\xcb\x6a\x42\x9a\xaf\x54\xd6\x2f\x76\x52\x79\x02\x08\xb7\x4a\xbe\xe0\x08\xab\xec\xa9\x0a\x3a\xac\x72\x36\x9d\xa9\x8a\x21\xc7\x4a\x62\x6c\x56\xe5\xc7\x23\x55\xac\x70\x95\x5a\x05\xd9\xc8\x6d\xe8\x05\xe1\x33\x76\x45\x95\x76\x3a\x28\x31\x77\x15\x7e\x39\xa9\x02\x80\x5c\x25\xb6\x37\xc9\x17\xe8\x49\x9e\xf1\x76\x1d\x1f\x76\x18\x61\x2f\xb7\xf1\x01\xc1\xe0\x28\x93\xca\x23\x43\x6c\xfc\x30\x32\x9c\x7c\x0b\xfb\x45\xf2\xd6\xf8\xb5\xba\x6a\xaa\xf0\xfb\x55\x65\xf7\x1b\x49\x03\xa1\x06\x54\xf8\xbe\xaa\x40\xe7\x98\xa2\xee\xe0\xa3\xbb\x49\xaa\x5a\x10\x09\x55\x2d\xa8\x40\x69\x55\xad\xd8\xd2\x00\x19\x9c\x87\xb6\x95\xaa\x46\x46\x16\xf4\xb8\xd2\x40\x55\x9e\x07\x56\xe0\xa4\x8a\x58\x82\x05\x93\x7c\xe7\xe5\x7b\xaa\xb6\xc3\xfc\x56\xdb\x1b\x95\xa4\x5a\xf9\x80\x50\x2f\xaa\x21\x76\xac\xd8\x91\xd5\xda\x3b\x76\x43\xbc\x5b\xad\x21\x42\xa8\x16\x92\xd9\x9a\x5e\xa5\xda\xc0\x92\x33\x06\xaf\x08\xb9\xb1\x0c\x98\xbe\xfd\x2a\x38\xfc\x72\x13\x54\xdf\x00\xe5\xaa\xef\x5a\x40\xe1\x02\xaa\x57\xfc\x60\x25\xab\x37\x43\x34\x58\xdf\xf8\xba\x7a\x7b\xa5\xeb\x0d\xf2\x74\x8c\x8a\x67\x62\xd5\xc9\x2b\x1a\x82\xdf\xea\xe3\xbf\x65\xd3\x53\x7d\xcf\xc6\xff\x45\x88\xd5\x5f\x4e\xab\xf1\x38\xa8\xf2\xfb\x40\x85\x16\x56\xff\x9a\xa6\xba\xb0\x62\xeb\x38\x50\xb8\x30\xa8\x55\xa6\xf5\xf2\xa4\xba\x06\x27\xb6\x86\x62\xd2\x6b\x5c\x3c\x7b\xaf\x6b\x40\x20\x30\x6b\x75\xf1\x13\x66\x7d\x86\x96\x03\x09\xd5\xbd\x3e\xf3\x4a\x4d\xb0\x79\x1a\x60\x62\x93\xfe\xb1\x96\xda\xfb\xd5\xab\xc9\x98\x4f\x6a\xc2\xc1\xb5\x37\xba\x68\x2a\x91\x9a\xe6\x4f\x6a\x08\x29\x9a\x9e\x32\xd9\x5c\x4f\x9e\x48\xb6\x7f\x41\x75\xd3\x7e\xe9\x9d\x9a\x06\x0b\x07\x4a\xf8\xe3\x37\xb3\xa6\x6b\x42\x2a\x8d\x01\x47\xd3\x7b\xa4\xa6\xbf\x33\x35\x98\xe7\x77\x65\x9b\x43\xb5\x9b\x23\xa2\x6b\x5e\x0d\x86\xb3\xb9\xef\xcc\x0c\xec\x95\xe6\x81\xd1\x3b\x2b\x4c\x79\xab\x4f\x92\x0b\x52\x6e\x88\xf2\xf0\x0a\xd3\x03\x33\xdb\x56\x2e\x1c\xfe\xbb\x7f\x1b\x8f\x1c\xdb\x9a\xc9\xe5\x93\x7c\xd3\x27\xf9\x46\xbf\xe8\x5b\xb1\x53\x93\x6f\x23\x63\xce\xbe\x0d\x4e\xc3\x37\xae\x8b\x6f\x5f\x1e\xdf\x79\xce\x2b\x92\x67\x6c\x09\xcf\xd3\xc1\xd3\x77\x8f\xe4\xc7\x81\x9f\xf2\x09\x43\xf0\x03\x0e\x00\x61\x87\x7f\xe4\x49\xc0\x41\x4e\x8b\xe5\xe5\xa9\xdd\x72\x72\x18\x38\x07\xec\xf5\x86\x1f\x04\xee\x8d\xe7\x70\xde\xca\x93\xbc\xa3\x7d\x47\x20\xee\xdd\xde\xe2\x4e\x08\xe1\x9d\xab\xe3\xef\xb7\x4b\x0f\x40\x46\x8f\x4c\x28\xf8\x9e\x2a\x79\xec\xd6\x60\x68\x3d\x4e\x8c\x34\x78\x80\xed\x61\x27\xe3\x36\x8f\x7e\x21\x7b\x4c\x9e\x14\xbc\x0a\xe9\x6b\x12\x5d\xf8\x9a\xef\x1b\xa0\x80\xaf\x49\xaf\xef\x08\x18\xfd\x8b\x11\x61\xf5\x80\x98\xfd\x06\x74\xf0\xdf\xe7\x44\x2e\x95\x2b\xf9\x1f\xe6\x42\xb8\xd3\x85\xbb\xb6\x63\x3b\xf3\xb0\xae\x4b\x01\xba\xee\x52\x6a\x42\x10\x2e\xa0\x5a\x40\x2d\x83\x72\x14\x5d\x3a\x69\x20\x9e\xee\xc2\xb3\xd2\x2e\xf1\x01\x09\xe7\xf3\x7c\x52\x87\x51\xeb\xb4\x66\x1d\x46\xac\xcb\xb4\xb7\x26\x4f\xac\x3b\x8d\x59\x4b\x9d\x5f\x41\x3a\xfc\x5b\x97\x87\x7b\xb7\x2b\x07\xa1\x02\x1d\xe0\x07\xe5\xae\x32\x84\x25\xc5\xb2\xb4\x04\xb1\x77\x6d\x82\xa8\xbe\x6b\xcb\x56\x52\x57\x87\xe9\xed\xca\x53\xef\xae\x71\x40\x63\xba\x06\x96\xb0\x6b\xc0\xe9\x75\x9d\xa9\x5f\x9c\xfe\xe5\xd3\x53\xbf\x78\x7a\xd2\xaf\x67\x18\x3c\x51\x37\x69\x9e\xba\x65\xce\xd6\x5e\x6f\xdb\x4d\x31\x1a\x3b\xf1\x53\x70\x01\xba\xec\x56\x30\x53\xf8\xbe\x6e\xde\x14\x7d\x5a\x47\xbd\x31\x31\x3b\xe3\xbc\xed\xef\x4f\x52\x7f\x65\x5a\x04\x3b\xad\x97\xf7\xe4\xae\x13\x59\xf1\x58\xb1\x17\xe2\xc8\x5e\x78\x34\xd6\xe1\xd3\x40\x4f\x10\x28\x4f\x77\xad\x20\x33\x75\x07\x9a\xef\x5e\x20\x12\x00\xf6\xee\xf0\xd2\xa9\x7b\xdb\x41\x9e\xd4\x1d\x9d\x7b\x5f\x6f\x95\xa0\x12\xf2\x00\xf7\xdf\xc3\xb0\x8d\xed\x06\xf8\x4c\x81\x10\xfe\xb9\xd8\x0e\xad\x81\x3c\xfd\x86\x7a\xbe\xa7\x61\x3d\x24\x73\xb7\xf6\x10\xec\xf8\x1e\xca\x1b\x16\x3d\xf4\x60\xb1\x62\xfd\x91\xf2\x2a\x48\x0f\x9d\x60\x11\xfa\x7d\x5f\xdf\xa6\xd0\xce\x1e\x56\xa1\xed\x3d\xec\x2d\xf1\x30\x56\x35\xae\x4c\xd8\x97\x02\x09\xfb\x03\x85\x91\xa9\x48\x79\xd2\xd4\xc3\xf7\x45\x4e\x7e\x60\x35\xc3\x79\x4c\xdc\xc3\x69\x16\x7a\x78\x75\x36\x76\x3f\x40\xfb\x3b\x91\x40\x24\x89\x41\xfa\xfc\x57\x6d\xed\xa0\x3c\xb5\xed\x6b\x43\x7c\xdd\xd7\xbe\xc3\x28\xf5\x85\x45\x5d\xa5\xa7\x17\xf2\xf7\x55\x69\x72\x3b\x61\x44\x5f\x1d\x2a\xb6\x10\xd4\xf5\x15\xef\x17\xb4\xbe\xde\x19\xac\xe0\x8e\xef\x34\x5b\x7d\x0d\x54\x9f\xa9\xaf\xbf\x3f\x48\xfa\x09\xa9\xb6\xa7\xff\x96\xf0\x12\xcd\x7f\x4b\xda\x5c\x15\x69\x60\x37\xfe\xb7\x74\x70\x6d\xfe\x5b\x40\xb0\x70\x3f\x20\x7f\xe9\xbf\x85\x29\x85\x6c\xb0\x1c\x21\x39\xc3\x67\x31\xf6\xe5\x77\x97\x90\x5d\x02\xd4\x3c\x05\x80\x0b\x03\xe2\x77\x91\x42\x80\xbc\x03\xd8\x34\x04\xc3\x0f\x69\x80\xc1\xaf\x2d\x0a\xe9\xb6\xa7\xc0\xb2\xf1\x3b\x42\xbc\x67\x09\x21\xb0\x1c\x21\x77\x0a\xf9\xf3\x48\xef\x2d\x14\x7e\x69\x44\x9c\x83\xce\x15\x48\x38\xf4\xfd\x12\x1c\xca\xef\xb1\xa1\x59\x61\x31\x43\x33\xd4\x3f\x34\x7b\xb0\x90\x5f\x46\x42\xb9\x6e\xa1\x07\x9d\x50\x28\x83\x9f\xd0\x03\x7b\x3e\xf4\x34\xb2\x3d\x43\x51\x76\x52\x69\x43\x7f\xde\xaa\x45\x7e\x41\xb9\x37\x42\x0b\xc2\x77\xde\x5d\x08\x25\x46\x0b\xfd\x07\x60\x42\x89\x2c\x42\xe9\x91\x43\xdb\xce\xcc\xa6\x77\xa2\x65\x0a\xa5\x95\x86\xa6\x1a\x0a\x3a\xd0\x51\xe8\xbb\x2b\x43\x79\x7b\x27\xf4\xbd\x70\x14\x3a\xf2\x62\xa2\x8c\x52\x43\x79\x55\x24\x74\xf8\x0a\x56\x1f\xdd\x1b\x07\x34\x56\x41\xc1\x7c\x9b\xcd\x78\xb9\xce\x15\xe8\x6a\xb5\x77\x66\xdf\x57\x7c\x5f\xe3\x60\x78\x36\x15\xd7\x33\xaf\x9a\xc2\x36\xfc\x36\x54\xc3\x26\xa1\x91\xe7\x46\x79\x3f\xea\x87\x1d\xe8\x9f\x2e\x17\x2e\x61\x4f\x3c\x9e\x0f\x73\xbc\xf3\x7e\x0d\xbf\xf1\x87\x11\x3f\x04\x4f\x0b\x83\x5f\x78\x02\x38\x3b\xf8\xb5\x32\x7c\x73\xd2\xc5\x17\x46\x6d\xe1\x95\x07\x39\xdc\x2c\xe1\xfe\x31\x3e\xd7\x14\xd0\xe2\x70\x86\xc7\xc1\x53\xea\xf7\x02\x4e\xc0\xdb\xa4\x20\xe0\x8e\xb5\x51\xe6\x08\x84\x63\x9d\x29\x00\x77\x62\x35\xfc\x6e\x79\x52\x2c\xc0\x87\x21\x3b\x7e\xf0\x2d\x43\x76\x46\xdf\x43\x0e\xbc\x18\x0a\x0b\x8b\x0b\xc2\x94\x21\xe5\xa5\x13\x04\xfd\x0c\xe0\x9d\xf1\x1e\x34\x0f\x44\xa1\x43\xa6\x8d\xe3\x41\xea\xe3\xb2\x34\x04\x2a\x35\x64\x11\x85\x0e\x38\x8e\x21\x4f\x1a\x19\x01\xf5\x80\x77\x18\x19\xca\x3d\xf2\x0b\x97\x47\xd6\x86\xb7\x4b\x2b\x13\x58\xc8\x91\x8d\xe7\xac\x23\xdb\x18\x1e\x23\x8d\xec\xc1\x0f\xe7\x23\xfb\x9a\x69\xe4\x90\x0e\x8a\x58\x73\xe4\xb0\xce\xbc\xb5\xa5\xa1\x82\x1f\x80\xfd\x78\xb7\xc5\xc0\xca\x0f\xcd\xb0\xc1\x43\x33\x74\x19\xb1\x38\x99\x69\x7e\x6d\xc4\x00\x26\x1b\xaa\x9f\x34\xf4\xa4\x8f\x1b\xfc\xa2\x81\xa4\xa4\x01\x0d\x96\x48\x43\x19\xf3\x0e\x86\x5d\xb0\xa7\xef\x18\x35\x4c\x07\x12\x7e\x2a\x1b\x3a\xc6\xcb\x9b\x01\xd6\xd0\xb9\x7a\x1a\xb0\xb7\x69\x5c\x8c\x05\xc6\x25\xc7\x04\xe5\x21\xce\xb8\x28\x8c\x0b\x03\xb8\xd8\xdb\xa5\x61\xc7\x91\xc6\xc5\xd3\xe3\x71\x19\x6b\x03\xd3\x8c\xcb\x3a\x08\xb4\x68\x5c\x08\xcb\xc6\xe5\xc8\x76\x47\x15\x47\x21\xb6\xcb\xb8\x7c\xf1\xb3\xcc\xb8\xb0\xe7\xc6\x15\x56\x51\x06\x8d\x18\xd7\x3a\xa0\xba\xe3\x7a\x12\x9c\x0d\xb4\x76\xc0\xb4\x11\xa3\x0c\x53\x2c\x1a\xd5\x9a\xdf\x0a\x87\x15\x8a\x03\xf1\xc2\x30\xd8\xad\x61\x85\xfd\x5b\x35\xd8\x83\x61\xaf\x2a\xf0\xeb\xf6\x78\xb9\x05\x26\x6b\x44\x33\x03\xfa\x0f\xb5\xb1\xdf\x34\xe0\x3b\xc6\x87\xaf\x3c\x1b\x48\xe3\x63\xf8\x61\xd6\x30\xe6\xe3\x63\x18\xfd\x07\xb6\x7e\x20\xb8\x1f\x45\x6a\x1a\x45\xb5\x83\xd2\x72\x0c\x7a\xd4\xc1\x93\xcd\xf1\x46\xbc\xa3\x18\x6a\x39\x60\xda\x80\xdb\x1f\x14\x2c\xcf\xb1\x47\x85\x15\x1c\x55\xc0\xb8\x22\x22\x19\xd5\x3f\xa4\x3e\xaf\x34\x1a\x8c\xf5\x68\x88\x61\x46\x83\x4e\x35\xca\x1e\xb0\x77\x38\xde\x3d\x67\xf4\xea\xfc\x92\x3d\x28\x73\xdf\x25\x0d\xc7\xaa\xd0\xd3\x0f\x2f\xbb\xb1\x4e\xb1\x1d\xf4\xbd\x30\x32\x78\x5e\x33\xbc\x2a\x00\xcd\x40\xc8\x3c\x9c\xf9\x08\xd5\x06\xd7\xc9\x17\x78\x62\x13\x0f\x87\x9a\xbc\x56\x6c\xf8\xc2\xd0\x3a\x0c\xe0\xa0\xff\x1e\x00\x67\xe8\xbf\xcb\xdd\xd2\xe8\x2a\x1f\xd0\x77\x4c\x9d\xca\xdb\xa9\x3b\xfc\x24\x3c\xfa\xa5\x6c\x44\x49\x75\x5e\x44\x18\xdd\x3e\x7c\x41\x73\x43\xc8\x38\x7a\x21\x05\xbc\xa6\xd5\x84\x6a\x77\x8e\x90\x36\x77\x74\x48\xb2\x07\xf6\x6e\xe7\xe5\xa6\xd1\x69\xe3\x46\x7f\xd2\x80\x7f\x54\x24\xbc\xef\x84\xb0\x8c\x37\xd5\xc6\x1b\x4f\x8c\x29\xbb\xad\x8a\x14\xd2\x9c\xb4\x04\x53\x0c\x3b\x79\xc2\xef\x8d\x49\xd3\x31\xb9\x2c\xb4\x68\x63\xa2\xa3\xc9\x99\x4d\x25\x2b\x05\x03\x2c\xfd\xd4\x50\x4f\xc0\x65\x28\xa4\xba\x4c\x8e\x64\x72\x3d\xa6\x57\x81\x32\x4d\x0a\x7a\xd2\x80\xf0\x18\x75\x4c\xaa\xff\x84\x1f\x3d\xf1\x1a\x8a\xdd\x3f\x83\xb2\x98\xc1\x35\x99\xb1\x78\xba\x3e\xe6\xe2\x0d\xd8\x31\x17\xc7\xfc\x9e\x83\x8e\xf9\x80\xae\x37\xc0\x19\x6b\x03\x5c\x1d\x6b\x83\x31\x1d\xeb\xbd\x3c\x3b\x10\x5f\x8e\xc5\x93\xdd\xb1\x18\xc0\x8c\x75\x0a\xe9\x89\x10\x8e\x07\x48\x63\xf1\x18\x7a\x2c\x54\x6a\x0d\xcd\xdb\xc0\x70\x56\x67\x76\x47\x40\x3a\x56\x0f\xda\x41\x20\xdb\xb1\x82\xdf\xc7\xc6\x42\xa0\x3f\x56\x00\x8c\xf1\xe1\x35\xfc\x63\xc5\x57\xd1\xe6\xbd\x45\x39\xd6\x60\x9c\x35\xee\x7f\x96\xe5\xa6\xa4\x6f\x21\x89\x9a\xc6\x0d\xac\x3e\x6e\x0a\xe1\xa6\x59\xb9\xb1\x73\x6e\xca\xf2\x26\x24\x1e\x37\xf0\xc1\x78\xea\x06\x29\x3e\xb5\x4f\xaf\x69\x3c\x01\xed\x7c\xb8\x24\xef\x0a\x4f\xe1\x0d\xa2\x29\x67\xe2\xbd\x81\x29\xb4\x13\x53\xca\x27\x4d\x69\x20\x1d\xc5\xfc\x14\x34\x65\x20\x63\x4c\xe4\xcc\xe9\x9e\xa6\xfc\x5a\x9a\xbc\xbd\x38\x55\x6a\x9a\xd0\x5e\x04\x7b\x53\x1b\x02\x89\xa9\xad\xd9\x40\x82\xe7\x40\x85\x81\xa7\xdf\x99\xe6\x45\xf6\x97\xe0\x11\xb2\x9a\x17\xda\x5d\x8a\x15\x9f\xd4\xfc\x79\x29\x1e\x31\xad\x79\x81\xcd\xe5\xbc\xd1\x35\xaf\x50\x94\xf2\x6b\xfb\xbc\x10\xab\xcf\x6b\xd5\x0d\x94\xc6\x65\xbe\x77\x5c\x26\x8c\xcb\xb4\x93\x39\x05\xef\x44\x32\xd3\xd0\x9b\xb5\x27\x4d\xeb\x09\xc8\x62\x4f\xf3\x3d\x7c\x9d\x06\x63\x3f\xe9\xd4\xa7\x6f\x80\x83\x69\xfa\x2e\x0f\xe8\x5e\xd0\xd8\x51\x7e\x2a\xc1\xdc\x74\x2b\xe8\x87\xd7\xfe\xa0\xbe\x13\xd5\xeb\x7b\x09\x91\x6a\x3c\xbd\x9d\x8b\x09\x4d\x1c\x95\x7a\xd2\x64\x4d\xef\xf8\x59\x06\xed\xec\x15\xde\x6e\x7a\x34\xd9\xc1\x26\x26\x83\xff\xe9\x63\xa4\xe9\x53\xd0\x70\x85\x71\x64\x84\x38\x93\xa1\xc3\x44\x00\x3a\xfd\x49\x93\x80\x75\x32\x5a\x9c\x21\x08\xbd\x91\x9e\x6f\x62\x0d\xb4\x0d\x68\xf5\x84\xd7\x9d\xbc\x39\x34\x81\x47\x4b\xe2\xbd\xd0\x17\x5c\x4d\xca\x16\xf8\x2e\x4d\x1e\x8d\x4d\x5e\x3d\x99\xbc\x0a\x39\xc3\x4e\x8a\x33\xac\x82\x80\x8d\xf7\x0b\x6d\xdf\x9b\x14\x33\x16\xab\x2d\x3e\x16\x14\xac\x8a\x78\x70\x06\xb0\xd1\x0c\x98\xc4\x89\x15\x5e\x60\xba\xde\x80\xe9\xdf\x26\x9d\xab\x09\x08\x42\xe1\xb9\xe2\x83\xd5\x07\xd0\x9b\x2b\xb8\x2c\xb7\xc2\x14\xcf\x5b\xdb\x7c\xd2\xbc\x61\x16\xe7\x8d\x89\xdd\x94\xca\xed\x69\x3e\xd0\xd6\xa7\x33\xcc\x5c\x67\x79\xd2\xaa\x5b\x68\x29\x92\xd6\x7b\xd5\x60\xb5\xf7\x36\xf0\x6a\x99\x6f\xef\xc5\x94\x57\x6d\x56\xdb\x3d\xad\xc6\x2b\xea\xab\xf1\x13\xe9\x6a\xef\x27\xa6\xd5\x8c\x98\x7a\x35\x5e\xcd\x5e\xcd\x26\xc8\x57\x11\x8c\xac\xf6\x69\x58\x85\xd5\x78\xc6\xba\xda\xb4\x92\x56\x5b\xbc\xa7\xb8\xda\x57\xf1\xda\x79\x9a\xb9\xfa\xc9\x05\x5a\x9d\x9f\x83\x56\xf7\x96\x16\x43\xe9\xd5\x61\x45\x56\x6c\xd2\x12\x0d\xc5\x0b\xbc\x80\xe0\x79\xe5\x7c\x0d\x3d\x56\x41\xc2\x0b\x12\xff\x98\xcf\xf7\x3f\x03\x5f\xc9\xd8\x6e\x5f\xc9\x6b\xd5\xf4\x15\xe8\xdc\x57\xe0\xc7\xbe\xef\x3d\xf8\xaf\x40\x74\x5f\x69\xf8\xd9\xb8\xd2\x57\xba\x47\xfa\xca\x7b\x15\xeb\x0b\x85\xff\xf2\x83\xfa\x57\x2f\x83\x68\xbe\x10\x36\x5e\xdb\x8e\x8a\xbc\x14\x89\xdc\x06\xd6\x1a\x1b\x88\x1d\x0f\x12\x02\xa5\x2f\x82\xdb\xaf\x8e\xa1\x25\x7d\x75\x6a\xa0\x2f\xa3\xcc\xbf\xb6\xf1\x0b\xe2\xd7\xf2\xdb\x9b\x65\xda\x75\x04\x88\x9e\x88\xda\xbf\x56\x0a\xa6\xfb\xb5\x36\xdf\xd4\x8b\x81\x41\x10\x77\x7f\x2d\xd8\x6e\x08\x88\x81\xd5\x78\xf3\x27\xe9\x17\x33\xe5\x29\xf7\x97\x17\x25\x79\xf9\xfb\xeb\x25\x4b\x73\xa4\xab\x22\x6f\x82\x3c\x60\x7f\xff\x23\xde\xd2\x2d\x36\xd3\x0d\x7b\x07\x7b\x0b\xd2\x16\x32\x1a\x48\x1c\xd0\x15\x5a\xdd\x5b\x02\xc1\x74\xba\xb1\x6d\x6e\x19\x1d\x64\xa2\x10\xf8\xe8\x06\x3e\x86\x33\xb9\xdf\xef\x8a\xb7\x0a\x96\x96\x96\xfa\x46\x6c\x55\x90\xd0\x68\xdc\xba\xa5\x5b\xdf\x70\xf8\x56\xfd\x60\xa7\xdd\x6a\x01\x5a\xf8\xcd\xeb\x86\x91\xbc\x75\xa6\x9b\x5f\xaf\x6e\xd8\xc8\xfb\xd2\x97\x82\x13\x2c\xe5\x4d\x13\x79\x03\x4a\xde\x97\x31\x02\xbf\x61\xef\x6e\xdb\xd1\xbf\x1d\x78\x2c\x3b\x48\x49\xd8\x25\xb7\x35\xc0\xd6\x1b\x08\x94\xae\xe2\xb6\xf6\x01\x69\x6c\xca\x4b\x31\x37\xc2\xac\xdb\x06\xc2\xd8\x1b\xd6\xe7\x86\xae\xdc\xff\xee\x28\xdc\x5e\x8e\x74\x23\xae\x49\xb7\x73\xc7\xdc\xee\x3b\x48\x49\xf4\x37\x3c\xdc\xbc\x3d\x0a\x1f\xe3\x01\xc5\x60\x60\x6f\xee\xd0\xfc\x01\xe5\x25\xde\x9b\x86\xec\xe6\xcd\x8d\x9b\x0e\xfc\x81\x49\x7b\x20\xaf\x47\xe9\xf7\x1e\x5f\xf8\xa1\x88\x40\xea\x4f\xb7\x90\xf4\xa7\xe1\x89\x47\x6b\x7f\xee\xe9\xff\x00\x00\x00\xff\xff\x96\xd2\xdb\xc1\x3c\x33\x00\x00") +var _keysWordsWordlistEnglishTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\x5b\xdd\xbe\xbc\x2a\x08\xbd\xf7\x2d\xc9\xa8\xd8\xa3\xe2\x41\x9d\x76\xfb\xe9\xcf\x6f\xad\xfe\x17\x83\xe5\x07\x2a\x22\x2c\xcc\x91\x4d\xda\xee\x2d\xc9\x66\xc5\xe6\x93\x64\x2b\x9a\x64\xf3\x35\x41\xbf\x78\x1e\xda\xf0\x32\x3c\x36\x24\x33\x24\xf3\x7d\xc5\x9e\x64\x5b\x43\x93\xe4\xac\x63\x20\xb1\x9d\x95\x73\xf6\xf5\xa6\x6f\xf1\x65\x0a\x56\xd9\xf6\x24\xd9\xd7\x98\x96\x93\xe4\xff\x96\x05\x72\xc3\xd9\x18\xf5\xa7\x61\x2c\x79\x7a\x80\xc6\xcb\x75\x2e\x29\x49\x76\xe9\x33\xc9\xbe\xe3\x67\x99\x8f\x6f\xf9\xfe\xb3\x06\x5e\xab\x81\xae\x02\xfa\x95\x96\x15\xa9\x21\xd1\xf0\x0d\x3d\x1e\x87\x58\x20\x71\x0c\xfd\x08\xc1\x78\x4e\xb1\x96\xe4\x54\xfc\x30\xe6\x33\x54\x93\x5c\x2a\x7b\x12\xab\x89\x2d\x2c\xba\xc7\x4c\x62\x03\xd2\x29\x12\x35\x49\xd9\x16\x68\xf6\xcb\x4b\x92\xa2\x28\x2f\xa6\x2d\x49\xc1\x7b\xd1\x07\xd4\xef\x24\xa5\x3a\x06\x58\xbc\xa1\x71\xbf\x24\x49\x09\x95\x1d\x15\x86\x27\x29\x53\x23\x49\xb9\xe5\x19\x49\xaa\x4c\x5d\x81\xf4\xcf\xda\x99\xa4\xfa\x4b\x29\xcf\xba\x86\xee\x49\x9a\x94\x07\x1c\x5b\xbe\x20\xa8\x96\x8d\x23\x6f\x27\xf8\xb4\x13\x63\x6c\x67\x3c\x49\x9a\x55\x88\xae\x7d\x98\xd5\x7c\x51\x2a\xad\x51\xa0\xcd\xe7\xc5\x06\xe3\x66\x32\xb5\x35\x41\x6a\xff\x2d\xd4\xfa\x35\x85\x42\xb4\x27\x49\x17\xcc\xae\x7b\xf1\x13\x6f\x5d\x25\x90\x80\x6b\xef\x41\x35\xe9\x61\x25\x49\xe4\x0b\x84\xeb\x1b\x2a\x20\xe0\x19\x27\x38\x42\x6a\x51\x31\x81\xa8\x18\x77\xd4\x27\x49\xf8\x6a\xc8\x09\x0c\x1f\xa9\x62\x66\x11\xf6\xe5\x1b\xe4\x87\xbe\x63\xea\x41\x15\x89\x69\xac\x30\x6f\x8f\x4f\x92\x81\x5f\x57\x94\x8c\x21\x5c\xfc\x31\x94\x94\xf5\xc6\x58\x55\x93\x8c\x79\x55\x49\x32\xaf\xa2\x53\x93\x4c\xaf\x49\xe6\x94\xfc\x41\xa2\x18\xc0\x9c\x36\xd7\x8e\xb2\x7f\x0a\xbe\xfe\x29\xe3\xda\xa1\x57\xeb\xa4\x92\x71\x15\xd6\xa4\xd8\xd7\x74\x90\x55\x5b\x92\xaf\x06\x55\xe8\xeb\x59\x76\x47\x0a\xd5\xba\xe5\xa3\xa0\x41\xfa\x24\xb9\x75\x38\x86\x73\x1f\xab\x24\xb9\x3f\xb7\x40\x11\x7f\x6d\xa4\x4d\xb6\x27\x6d\x92\x2f\x2d\x1e\x78\xf0\x96\x36\xd9\x4f\x4d\x9b\x9c\x69\x93\x42\x85\xde\xa0\x6f\x0d\x15\x4b\x49\x9b\xd4\xcd\x3d\x6d\xd2\xa4\x09\x92\xa6\x68\xc9\x9f\x16\x54\x0a\xea\xf6\x06\xa1\xa2\xfa\x00\x83\x61\x19\xf4\xa3\x33\x6d\x32\x67\xd1\xb4\xa9\xe4\x0b\xb4\x81\xac\xf9\xa4\x4d\xb3\x60\xe3\x6e\x9a\x31\xdc\x4d\xf5\x48\x9b\x1e\x1e\x78\x3e\xc1\x52\x2f\xf9\xe2\xe5\xb2\xb6\xa7\x4d\x0b\xf7\xf7\xa6\x50\xf7\x4d\xcb\x4c\x9b\x36\xf2\x6c\x7a\x18\xde\x06\xc8\x0c\x01\xef\x09\x75\xdf\x74\xde\xaa\xe0\xf4\x38\x58\x58\x7e\x32\xc6\x62\x78\xfe\xe0\x81\xb9\xaf\xc6\x6d\x16\x78\x89\x79\xa5\xcd\xde\xe6\x05\x6b\xb7\x15\xd9\x15\xb4\x92\x36\x4e\xaa\x08\x3a\x2b\x2a\x28\x87\x81\xd8\x0a\x79\x15\x77\xd2\x31\xbc\x22\xe5\x04\xcb\x22\x01\xc3\x35\xae\xb4\x39\x16\x64\x73\x99\x69\xf3\xfd\x49\x9b\x5b\x49\x9b\xd7\x2d\x6d\xd8\xbc\x9b\xb7\x35\xd2\xe6\xfe\x01\x41\x37\x1e\x3b\x46\xe3\x81\xbd\xba\x39\xf5\x75\x83\x39\xdb\x7c\x42\xc9\xb6\x77\xcb\x6d\xfe\x9b\x36\x7f\xd2\x16\x92\x39\xc8\xe0\xc2\x84\x60\x60\x21\xa8\x1f\x14\x28\xcc\x02\xa8\xfe\xe1\xc5\x30\xc7\x30\x6a\x41\x18\x16\x21\xec\xbc\xd0\x9c\xdd\x85\x0d\x94\x7b\xce\x5e\x0c\x0f\x1f\x08\x34\xbc\xb1\xb1\xa3\xfb\x78\xf7\xf8\x16\x7e\xa3\x88\x73\x5c\x1b\x6c\xfc\xb6\x76\x4c\x70\xed\x27\xc6\xb3\x8e\x43\x8a\xa7\x6d\x59\xd9\xd3\xb6\xca\x06\xf2\x01\x29\x2c\x6e\x3b\x9b\xb4\x0f\x98\xad\xd8\xd1\xd1\x8a\xf3\x7d\x83\x20\x20\x97\x35\xac\x51\xe0\x6b\x80\xf3\xbb\x50\xeb\x21\xfd\xfb\x4b\x59\xb6\x0d\x9b\x24\xcb\x66\x0d\xb4\xe0\x39\xcf\x35\x52\x7e\xf3\x3f\x20\xa5\x80\xd4\x94\xa5\x6a\x08\x92\x9e\xb2\xa0\x41\x13\x14\xb5\xac\x4c\xf6\x07\xb4\x39\x4b\x1c\x2d\xdb\x57\xc0\xaa\x3d\xcc\xeb\xff\x3a\xe8\x36\xd9\xae\x4f\x61\xb7\x81\xdf\xc6\x2a\xb1\x83\x9c\x0e\xda\x75\x22\x09\x70\x0d\x3c\x0e\x34\x1e\x17\x88\x35\x54\x19\x93\xfc\xc6\x22\x3b\x54\x99\x52\xfc\x44\x9a\x51\x6d\xea\xe9\x6c\x3e\xdf\x8a\x0b\x4b\xf5\x6e\xa4\x2c\x8b\xc6\x24\x63\x91\xb3\x5a\xc1\xfa\x65\x2d\x8a\xfa\x5a\x61\xbd\xb3\xb6\x01\x49\x68\x9b\x8b\xb9\xa1\xe8\x47\xe3\x1d\xf6\x05\x3f\x94\x2f\x29\x1f\xd0\xda\xc9\xed\xa2\xcd\xcc\x97\xf8\x00\xed\x10\x78\xbe\x24\xde\xcc\x41\x3a\x53\xbe\x54\x3a\x68\x46\x5b\x55\xe6\xeb\x01\xc2\xe9\x5e\xd8\x9d\xf9\xb2\x0c\xf5\x81\xab\x46\x11\xf4\x20\x5f\x56\x9b\xa2\x86\xc3\x8d\xe6\xcb\x9d\x6d\xc3\x9b\xe5\x94\xaf\x95\xe1\x57\xf2\xb5\x1a\x18\xaf\x68\x29\xdb\x09\xf9\x5a\x6b\xf0\x5b\x29\x5b\x60\x53\x67\x9b\xf6\x07\xde\x00\x18\xd9\xbe\x56\x52\x2e\xf0\xad\xb9\x60\x60\x45\xc2\x8e\x07\xe9\x0d\x82\x27\xd8\xa2\x5c\x34\x3e\xa0\x5f\xcc\xaa\x60\x2f\xe4\x42\x47\x97\x8b\x1d\x07\x68\xdd\x40\x39\x98\x62\xe0\xe4\xac\x84\x35\x29\x1c\x6a\xf1\x79\x81\xae\x1d\xf4\x06\xd3\x85\x36\x0b\x3a\x55\xd6\xa0\xc0\xca\xe2\xfa\xb9\xbc\x14\xc2\xf0\xec\x6d\x21\xdd\x35\x65\x3f\x0e\x45\x82\x61\x3b\xd6\xc2\x4b\x81\xc3\xc9\x0e\x53\x9d\xbd\xc0\x03\x64\xaf\x9b\x35\x54\xab\x24\x07\xf0\x42\xf6\x8a\xb1\x79\xa5\x30\xbc\x76\x38\xd3\xec\x0d\xab\x8a\x74\x5f\x64\xd3\x0e\x8b\x8a\xf4\x24\xa0\xc9\xde\xda\xcb\xbf\x0d\x83\x79\xc9\xde\x66\x38\x7a\x6f\x5f\x83\x39\xc9\xb0\x40\xd9\x99\xd5\x3b\x6b\x74\x30\x0e\x68\x0c\xac\x74\x76\x2c\x86\x47\xbc\x7c\x38\xa5\x39\x39\x88\xc5\x59\xae\x36\xb1\xf4\xbe\xe0\xc3\xb3\xaf\x18\x4c\x06\xa7\x47\x81\xfb\xe3\x53\x53\x86\xc1\x02\xc5\xfe\xcf\x21\xc7\x04\xad\x20\x8d\x19\xd8\x20\x21\x94\x63\xc8\x5d\x40\xff\x9e\x94\x43\x59\x49\xe1\x3b\x73\xa8\x82\x87\xde\x29\xc3\xa4\x61\xa3\x85\x41\x4c\x61\xa3\x83\x02\x2e\xe4\x70\x3c\xc3\x76\xe6\x78\x47\x19\x7e\xef\x29\xc7\xca\x86\x79\xc5\x52\x52\xc3\x50\x63\x55\xee\xee\x58\x8d\x35\x17\xc7\x81\x8e\x9f\xc1\xed\xbe\x36\x4d\x79\x95\xb9\x20\x8d\xd5\xf1\x7b\x8d\x7b\x5e\x61\x8e\x8d\xb6\x22\xa8\x4c\xeb\xdf\x0e\x5b\x81\xbd\xb9\xc6\xc5\xad\xb5\x06\xcc\x77\x5e\x90\x01\x3d\xd3\x2e\x7b\xda\xa5\xc2\x50\xed\x30\x49\x3b\x1d\xf2\xfe\x82\xae\x5d\x68\x91\x77\x88\x63\xe7\xc6\x67\xe6\xdd\xd2\x2e\x4f\xda\xb1\x93\x77\xdd\x64\x2a\x92\xb0\x91\x76\xcd\x70\x5d\xbb\x66\xad\x1b\xea\x2a\xa0\x33\x92\x02\x2d\xda\x15\x8b\xc9\xea\x10\xe5\xc0\x03\x6b\x1d\xda\xf8\x72\xbc\xb5\x0e\x30\x27\x60\xdd\xb5\xb0\xa7\x62\x5f\x56\xac\x70\x2d\xbb\x56\x63\xf5\x66\x1c\x41\x23\x76\xda\xb5\xa1\x26\x31\xdd\xae\x5d\x59\xb1\xfb\x30\xbe\xce\x0b\x14\x28\x60\x57\x82\xb0\x5d\x47\x0e\xdb\xf8\xa0\x6c\x32\xec\x6c\x48\x3e\x20\x1d\x86\x69\xd7\x31\xc3\xd1\x64\x8a\xa1\xa7\x09\xc5\xdb\xf5\xab\xc5\x3b\x52\xd8\x8f\x5d\xbf\x50\xa9\xdd\xe4\x84\x0a\xed\x1c\x93\xc1\x50\xec\x48\xe3\x49\x3b\xab\x99\x0e\x45\x89\xce\xb4\xdb\x71\x60\x3a\x76\xd2\x88\xef\x76\x36\xd8\x90\xdd\x8a\xd6\x2a\x69\x37\x62\x9e\xdd\x9a\x0f\x59\x78\xa0\xc2\xef\x86\x61\xda\x78\xa1\xfc\x6e\xe3\x55\xe9\xdd\xc6\x2b\x4a\xc3\x2a\xd9\xa8\x36\x06\xd2\xd7\x87\xef\x36\x3a\x45\x68\x63\xbe\x4b\x0b\x49\x82\xcf\x97\x2b\x63\x5f\x0f\xe6\xfe\xfd\x3d\x69\x77\x86\x28\xbb\xe7\x45\xe3\xbd\xfb\x99\x76\x2f\x05\xa4\x5f\xd6\xd2\xee\x55\x98\x34\xae\xa2\xb7\x8f\xa2\x55\x63\x23\x12\x0c\xc4\x17\x94\x78\x07\x7e\xde\xb9\xb7\xf6\x90\xd3\x1b\x12\xcc\x2e\x84\x81\xd2\x1e\x72\xa7\x9d\x3b\xea\x8d\x78\xf6\x30\xd6\x35\x74\x18\xd6\x3e\xa0\x1d\x84\x8c\x20\xf1\x58\xa8\xfc\xa4\x7d\xe5\x4f\xda\x57\xdd\xd2\xbe\xa0\x31\xeb\xd5\x53\x60\xd9\x9d\x66\x6f\xe7\x4a\xdf\x12\x47\xda\x9f\x26\xb0\x57\x2a\x50\x69\x15\xc4\x11\x2a\x51\x1e\xd0\x06\x32\xaf\xa4\x32\x8c\x39\x63\x82\x3c\x49\xf3\xe5\x49\xf3\x0b\xd4\x34\x7b\xf3\xfa\x24\x05\x64\xe1\xe6\xd7\x7d\xc1\x33\x26\x3d\x68\x11\xf5\x3c\x93\x12\xc3\xa8\x11\x99\x68\xd9\xfc\x4e\x5a\x76\x3e\x6b\x9e\x81\x11\x14\x3d\xa5\x4d\xa4\x14\xaf\x16\xed\xd7\xbf\x8c\xaf\x40\xf2\x5a\x0c\x4c\xcb\xd0\xa4\x75\x93\xf8\x20\x01\x62\xd3\x0a\x8c\x85\x5c\x85\x1b\xd4\xea\x74\xbc\x5a\x7b\x71\x94\x76\x47\xb0\xa3\xb5\xcf\x27\x69\x23\x44\xd0\x06\xbc\x8f\x6d\xa0\x80\x39\x63\x20\x75\x58\x44\x6d\x8a\xc9\x34\x0d\xcc\xad\x1d\xd4\x00\x6d\x27\x8c\x80\xb6\x13\x7b\x50\xdb\x45\x6d\xd1\xf6\x03\xfe\xad\x60\x87\x69\xf3\x75\x5e\x49\x5b\x58\x66\x02\xd5\x80\x7f\x0f\x54\x84\x6d\xc0\x56\x7c\x5f\x02\xad\xb8\x4f\x34\x69\xb7\x01\x97\xa3\xff\x01\x63\xe8\x7f\xcb\x7a\x02\x06\xd2\x80\xde\x6a\xb0\x2c\x7c\x70\x46\x11\x90\x43\xac\x3e\x93\x8e\x2c\x68\x3e\x86\x3c\xa0\xca\x11\x8d\x49\xc1\x4f\x0d\x00\x27\x9d\x97\xe5\x91\x14\xda\xcc\x62\xb8\x61\xfd\xfa\x07\x8f\x5e\xbe\x9a\xf4\x97\x72\xf8\x95\x0a\xa7\xa0\xbf\x8c\xe9\xf5\xf7\x1f\xca\xd0\xdf\x4c\x91\xff\xe6\x82\x30\x49\x7f\x19\xda\xeb\xaf\xd2\x46\xea\xaf\x46\x36\x66\x5c\x02\xed\xd2\xdf\xcb\x36\xac\xff\xaf\x91\x19\xc5\xf2\xcb\x0c\x87\x52\xeb\x6f\x87\x85\xd2\x5f\xc6\x6e\xfa\xdb\x29\x8e\xdf\x5e\xb0\x6d\xf4\xb7\x3b\x79\xf5\x78\xc7\xc0\x10\x4d\x7f\x27\x64\xf1\x28\x7e\x40\xb4\xe9\x10\x60\xe4\x74\x60\xc1\x0f\x81\xb9\x7f\xd2\x01\xbb\x7a\x88\xb5\x09\x3a\xaf\x74\x00\x51\x1e\x02\x55\x39\x10\x28\x1c\x52\xa1\xc1\x07\x62\xea\x91\x0e\x69\xf8\x65\x64\xb4\x09\x85\x3e\x10\xa7\x1e\xf2\xfa\x81\x43\xc0\x06\xb6\xe7\x10\xea\xeb\x21\xd3\x10\xcc\x1e\x8c\x35\x0f\xf9\x7a\x40\x2c\x87\x0a\x5d\xcd\xa1\x5b\x2c\x98\xb2\x43\x77\x85\x3b\x06\x74\x38\x54\x77\x10\xbc\x55\x29\xc8\xc0\x0a\x1c\x3a\xa6\x7d\x59\x07\x3b\xf1\x20\xd0\x39\xf4\x4e\x87\xc1\x25\x1c\xf6\x06\xa0\x87\x69\xd9\xd3\x61\x27\xf9\x43\x9a\x87\x95\x0a\x32\x59\x0b\x8b\x7b\x20\xc2\xa1\x4f\x38\x8c\x0e\xe9\xb0\x06\x2b\x77\x18\xdb\x60\x42\x06\x98\x7e\xd8\xc8\xac\xce\x32\xbc\x4f\x22\xf6\xc3\x7e\xd3\x51\xe4\x04\x81\x88\x0a\x1c\xd9\x51\x30\xf9\x82\x29\xa6\xa3\x60\x1e\x85\x3b\xf7\x00\xd6\x3a\x8a\xb3\x14\x88\xeb\x28\xce\x2a\xdc\x5a\x47\x59\xb6\x83\x92\xc3\x93\x0e\x97\x9a\x0e\xcf\x90\xb5\x9f\xe9\x00\x8c\x3a\x1c\x33\x72\x9e\x8e\x1c\x08\xcb\x0e\xf7\x99\xde\xed\x85\x28\x73\xf0\x05\x81\xc9\x81\x20\x1f\x96\x03\xd6\xeb\x70\x98\xb5\xc3\x83\x61\xf3\xe1\x63\x90\x17\x51\xdc\xc1\x63\x84\xc3\x7f\xd3\x11\x72\x52\x4a\xc1\xa9\x84\xfe\xb7\x60\x43\x8e\x50\x8c\x28\x0c\xaa\x74\xc0\x0c\xa2\x10\x23\x0a\x67\x31\x50\xd2\xc1\x38\xe9\x08\x07\x5c\x3d\x62\x41\x44\x80\x1d\xc7\x6a\xf8\xb5\x27\x1d\x2b\x1a\xd5\x0d\x20\xfd\x58\x5c\xf4\x53\x18\x44\x31\xd8\x3e\xa5\xc8\xef\x83\x84\xe0\xfe\xc4\x18\x4e\xe9\xe9\x14\x1e\x10\x9c\x12\xdb\xbf\x14\x31\xd4\x29\x51\x2c\x23\xa1\x9d\x3b\x65\xe0\x87\xda\x13\x75\xa8\x71\xa7\x2c\x36\xf8\xd3\x74\xc2\x14\x49\x41\x6a\x6b\x20\x09\x66\x22\xde\x38\xb5\x2d\x28\xc0\xa9\xe3\x1d\xd4\x85\x09\x9d\x06\xb3\x79\xc2\x5f\x9c\x76\xc2\xa2\x9f\xaf\x82\x9c\x16\x72\x1c\x78\x8d\x92\x4e\x38\x8e\xb3\xc8\x0e\x02\xd5\x3c\x8b\x04\xe9\x18\xe9\x2c\xf0\x7f\x67\xb1\xda\x07\x52\xdf\x48\xbd\x82\x62\x8a\xc5\xd9\xda\xef\x74\x22\x9c\x3e\xa1\x18\xa7\xef\x3b\x14\xeb\xc4\x4a\x9f\x58\xe2\x93\xc1\xc3\xe9\xf0\x5a\x92\x4e\x1f\x5d\x0b\x92\x61\x3d\x9d\xf0\xcf\x2d\x9d\x10\xfe\x19\xb2\x81\x60\x14\x8c\x92\xcf\xe0\x14\x02\x16\xee\x64\xac\x7c\x86\x7c\x01\x03\xce\x50\x74\x15\x0a\x49\x86\xed\x20\x7a\x80\x22\xd7\x33\x17\x20\x7c\x75\xd0\x3b\x9d\xb1\xc0\x68\x41\x79\xce\xc5\xd1\x2d\x4e\x6d\x59\x41\xbe\x4d\x89\x74\xae\x96\xce\xa7\xa6\x4b\x60\xbd\x18\x75\x5d\x52\x8e\x74\x49\xad\x8a\xe7\x4a\x75\xbb\x60\xbc\x2e\xe9\xfd\x49\x17\xa2\x49\xe4\x04\x72\x62\x5c\xa0\x5f\xe8\x30\x82\x2f\x9e\x93\x5c\x72\x7f\xd2\x25\x7f\xac\x82\x08\xff\x52\x29\xf3\x42\x12\x13\xf4\xfb\xa4\x0b\x3e\xf3\xf2\x33\x5d\xaf\x7f\xbc\xb4\x14\x07\xad\xca\x97\x9e\x2e\x6d\xe9\xd2\xf0\x74\xd9\x0e\xe5\xb9\xec\xbc\xd2\x05\x10\x70\xc1\xda\x5d\xd6\xd3\x85\xfd\x7e\xd9\x98\x58\x98\xcb\xb7\x0d\x34\x03\x7b\x5c\x58\x88\xcb\x8b\x82\x18\x50\xe9\xf5\xee\xbf\x0b\x01\xcb\xe5\x8d\x75\x1c\x75\x3a\xde\xa3\x81\xc0\xc5\x5c\x74\x85\x97\x8f\x37\x90\xa6\x5a\x5d\x3e\x15\x8f\x0b\xc5\x30\x5b\xd7\xda\xd2\x05\x3d\xbd\x56\x95\x06\x0a\xcf\x7a\xad\x0a\x06\xab\xed\xa1\x3b\xd2\x13\xc3\xc2\x2a\x5c\x2b\x76\x56\x08\xe6\x40\x0a\x6b\x6c\x14\xea\xb3\x61\x29\x81\x04\x2d\x7b\x4b\xb6\xab\x24\x1e\x2b\x23\x48\x34\xb4\xb2\xb3\x21\xc8\xc1\xcc\xad\x00\x2a\x30\xa5\x21\x33\x02\x74\xab\x46\xdf\x67\xb5\x12\x2f\x5b\xad\xb0\x1f\x56\x3b\x3c\x9c\x55\x7a\x17\xab\xef\xc9\xa5\xd5\xbe\xe0\x1c\x0c\x91\x84\xb5\xd7\xbd\x59\x63\x20\x67\xed\x1f\xfc\xb6\xb6\xeb\x2f\xa8\x11\xcd\x58\x23\x8a\xb3\x06\x24\x15\x4f\xb2\x06\xef\x81\xa4\x58\x66\xea\x51\x93\xb5\x0b\xd6\xde\xda\xa5\x50\x49\x6b\x36\x81\x79\xad\xfd\x28\x2b\xfd\x2c\x36\xad\x2f\x47\x20\x59\x6b\xcd\xb3\x92\x53\x5f\xa0\xff\x2d\x63\x9d\x81\x70\xcb\xda\x78\x1b\x22\x2c\x44\x42\xa7\x69\x0d\x11\x0f\xd8\x4e\xce\x0e\xf8\x02\xda\x67\x6d\x7a\xb2\xf6\x7d\x9f\xbf\xc6\x4e\x5e\x4f\x6f\x01\xc1\x8e\x02\x79\xdb\xf0\xc2\x01\x8c\xb1\x34\xd9\xd4\x9a\x00\x75\x9f\xf4\xf3\x1e\x55\xfd\x08\x76\x4c\xfa\xe1\xef\xef\x2f\xfd\xa8\x14\x38\xce\x1f\x95\x06\x5a\xca\x93\x7e\xf4\xd6\x92\x7e\x7c\x4b\x3f\x08\x90\x7f\x00\x2a\x7e\x7c\x05\x94\x0a\xb0\xe8\x67\x01\x0f\xfe\x2c\x2c\xea\x0f\x62\xef\x9f\xc5\x53\xea\x9f\xd5\xcc\x03\xc9\x27\xf1\x10\xff\x23\xed\x94\x70\x4f\x1f\xec\xe9\x8f\x6a\x4f\x1f\x38\xc7\x85\xf4\x49\x1f\xcb\x9f\xf4\xb1\x1d\xbf\xc6\xf7\x86\xe7\x76\xee\x5e\xd3\x07\x70\xfe\x63\x13\xbf\x8c\xbd\xf2\xc1\x94\x3f\x36\x27\x9f\x6f\x4b\x9f\xa6\x9a\x3e\xcd\x0e\x50\x38\xae\x4f\xf3\x3b\x15\xd9\xf0\xd3\x02\xea\x91\x8a\xec\x00\xa3\x45\xf6\x27\x15\xf9\x68\x2a\x08\xf7\x8a\xb4\x73\x41\xb7\x8a\xf4\xe9\x78\x0f\xbe\x4c\x56\x9d\xd6\x52\x41\xdc\x07\xda\x00\xbc\x8b\x7c\x25\x15\x01\xfb\x1b\x65\xf7\x80\x33\x29\xf2\xb0\xfe\xdf\x93\x8a\x0a\xbb\x51\x39\x40\xa2\x81\x7e\x35\x01\x03\xc3\x7e\x17\x3d\x66\x2a\x7a\xa6\x57\xc1\x8b\x9e\x70\x5c\x45\x6d\xbc\xa5\xd5\xd1\x82\x59\xed\x9c\x17\x92\x91\x8a\x7a\x87\x91\x01\x8a\x65\x39\xcf\xe0\x0a\xe2\xb0\x54\x4c\x22\x15\x40\x8b\xf9\x20\x0d\xc0\x94\x62\x99\x3b\xa4\x40\x28\x05\x6e\xe2\xf5\xf1\xc5\x30\x71\xab\x1b\x08\x06\x8e\x28\xa3\x00\x8e\x14\xfb\x0f\x0e\x9e\x38\xb7\x18\x8f\xba\x10\x73\xa6\x62\x34\x6f\xc5\x85\xa4\xa5\xe2\x1b\x4d\x65\x71\x40\x0e\x02\x85\xe2\xa7\xe5\x54\xbc\x69\x79\x90\x9c\xa9\x38\x64\xe9\x18\x26\x72\x16\xda\x2e\xb8\x66\x3a\x95\xe2\x0f\x9a\xae\xfc\x79\x52\x59\x27\x71\x77\x59\x0c\x98\xcb\x6a\x42\x9a\xaf\x54\xd6\x2f\x76\x52\x79\x02\x08\xb7\x4a\xbe\xe0\x08\xab\xec\xa9\x0a\x3a\xac\x72\x36\x9d\xa9\x8a\x21\xc7\x4a\x62\x6c\x56\xe5\xc7\x23\x55\xac\x70\x95\x5a\x05\xd9\xc8\x6d\xe8\x05\xe1\x33\x76\x45\x95\x76\x3a\x28\x31\x77\x15\x7e\x39\xa9\x02\x80\x5c\x25\xb6\x37\xc9\x17\xe8\x49\x9e\xf1\x76\x1d\x1f\x76\x18\x61\x2f\xb7\xf1\x01\xc1\xe0\x28\x93\xca\x23\x43\x6c\xfc\x30\x32\x9c\x7c\x0b\xfb\x45\xf2\xd6\xf8\xb5\xba\x6a\xaa\xf0\xfb\x55\x65\xf7\x1b\x49\x03\xa1\x06\x54\xf8\xbe\xaa\x40\xe7\x98\xa2\xee\xe0\xa3\xbb\x49\xaa\x5a\x10\x09\x55\x2d\xa8\x40\x69\x55\xad\xd8\xd2\x00\x19\x9c\x87\xb6\x95\xaa\x46\x46\x16\xf4\xb8\xd2\x40\x55\x9e\x07\x56\xe0\xa4\x8a\x58\x82\x05\x93\x7c\xe7\xe5\x7b\xaa\xb6\xc3\xfc\x56\xdb\x1b\x95\xa4\x5a\xf9\x80\x50\x2f\xaa\x21\x76\xac\xd8\x91\xd5\xda\x3b\x76\x43\xbc\x5b\xad\x21\x42\xa8\x16\x92\xd9\x9a\x5e\xa5\xda\xc0\x92\x33\x06\xaf\x08\xb9\xb1\x0c\x98\xbe\xfd\x2a\x38\xfc\x72\x13\x54\xdf\x00\xe5\xaa\xef\x5a\x40\xe1\x02\xaa\x57\xfc\x60\x25\xab\x37\x43\x34\x58\xdf\xf8\xba\x7a\x7b\xa5\xeb\x0d\xf2\x74\x8c\x8a\x67\x62\xd5\xc9\x2b\x1a\x82\xdf\xea\xe3\xbf\x65\xd3\x53\x7d\xcf\xc6\xff\x45\x88\xd5\x5f\x4e\xab\xf1\x38\xa8\xf2\xfb\x40\x85\x16\x56\xff\x9a\xa6\xba\xb0\x62\xeb\x38\x50\xb8\x30\xa8\x55\xa6\xf5\xf2\xa4\xba\x06\x27\xb6\x86\x62\xd2\x6b\x5c\x3c\x7b\xaf\x6b\x40\x20\x30\x6b\x75\xf1\x13\x66\x7d\x86\x96\x03\x09\xd5\xbd\x3e\xf3\x4a\x4d\xb0\x79\x1a\x60\x62\x93\xfe\xb1\x96\xda\xfb\xd5\xab\xc9\x98\x4f\x6a\xc2\xc1\xb5\x37\xba\x68\x2a\x91\x9a\xe6\x4f\x6a\x08\x29\x9a\x9e\x32\xd9\x5c\x4f\x9e\x48\xb6\x7f\x41\x75\xd3\x7e\xe9\x9d\x9a\x06\x0b\x07\x4a\xf8\xe3\x37\xb3\xa6\x6b\x42\x2a\x8d\x01\x47\xd3\x7b\xa4\xa6\xbf\x33\x35\x98\xe7\x77\x65\x9b\x43\xb5\x9b\x23\xa2\x6b\x5e\x0d\x86\xb3\xb9\xef\xcc\x0c\xec\x95\xe6\x81\xd1\x3b\x2b\x4c\x79\xab\x4f\x92\x0b\x52\x6e\x88\xf2\xf0\x0a\xd3\x03\x33\xdb\x56\x2e\x1c\xfe\xbb\x7f\x1b\x8f\x1c\xdb\x9a\xc9\xe5\x93\x7c\xd3\x27\xf9\x46\xbf\xe8\x5b\xb1\x53\x93\x6f\x23\x63\xce\xbe\x0d\x4e\xc3\x37\xae\x8b\x6f\x5f\x1e\xdf\x79\xce\x2b\x92\x67\x6c\x09\xcf\xd3\xc1\xd3\x77\x8f\xe4\xc7\x81\x9f\xf2\x09\x43\xf0\x03\x0e\x00\x61\x87\x7f\xe4\x49\xc0\x41\x4e\x8b\xe5\xe5\xa9\xdd\x72\x72\x18\x38\x07\xec\xf5\x86\x1f\x04\xee\x8d\xe7\x70\xde\xca\x93\xbc\xa3\x7d\x47\x20\xee\xdd\xde\xe2\x4e\x08\xe1\x9d\xab\xe3\xef\xb7\x4b\x0f\x40\x46\x8f\x4c\x28\xf8\x9e\x2a\x79\xec\xd6\x60\x68\x3d\x4e\x8c\x34\x78\x80\xed\x61\x27\xe3\x36\x8f\x7e\x21\x7b\x4c\x9e\x14\xbc\x0a\xe9\x6b\x12\x5d\xf8\x9a\xef\x1b\xa0\x80\xaf\x49\xaf\xef\x08\x18\xfd\x8b\x11\x61\xf5\x80\x98\xfd\x06\x74\xf0\xdf\xe7\x44\x2e\x95\x2b\xf9\x1f\xe6\x42\xb8\xd3\x85\xbb\xb6\x63\x3b\xf3\xb0\xae\x4b\x01\xba\xee\x52\x6a\x42\x10\x2e\xa0\x5a\x40\x2d\x83\x72\x14\x5d\x3a\x69\x20\x9e\xee\xc2\xb3\xd2\x2e\xf1\x01\x09\xe7\xf3\x7c\x52\x87\x51\xeb\xb4\x66\x1d\x46\xac\xcb\xb4\xb7\x26\x4f\xac\x3b\x8d\x59\x4b\x9d\x5f\x41\x3a\xfc\x5b\x97\x87\x7b\xb7\x2b\x07\xa1\x02\x1d\xe0\x07\xe5\xae\x32\x84\x25\xc5\xb2\xb4\x04\xb1\x77\x6d\x82\xa8\xbe\x6b\xcb\x56\x52\x57\x87\xe9\xed\xca\x53\xef\xae\x71\x40\x63\xba\x06\x96\xb0\x6b\xc0\xe9\x75\x9d\xa9\x5f\x9c\xfe\xe5\xd3\x53\xbf\x78\x7a\xd2\xaf\x67\x18\x3c\x51\x37\x69\x9e\xba\x65\xce\xd6\x5e\x6f\xdb\x4d\x31\x1a\x3b\xf1\x53\x70\x01\xba\xec\x56\x30\x53\xf8\xbe\x6e\xde\x14\x7d\x5a\x47\xbd\x31\x31\x3b\xe3\xbc\xed\xef\x4f\x52\x7f\x65\x5a\x04\x3b\xad\x97\xf7\xe4\xae\x13\x59\xf1\x58\xb1\x17\xe2\xc8\x5e\x78\x34\xd6\xe1\xd3\x40\x4f\x10\x28\x4f\x77\xad\x20\x33\x75\x07\x9a\xef\x5e\x20\x12\x00\xf6\xee\xf0\xd2\xa9\x7b\xdb\x41\x9e\xd4\x1d\x9d\x7b\x5f\x6f\x95\xa0\x12\xf2\x00\xf7\xdf\xc3\xb0\x8d\xed\x06\xf8\x4c\x81\x10\xfe\xb9\xd8\x0e\xad\x81\x3c\xfd\x86\x7a\xbe\xa7\x61\x3d\x24\x73\xb7\xf6\x10\xec\xf8\x1e\xca\x1b\x16\x3d\xf4\x60\xb1\x62\xfd\x91\xf2\x2a\x48\x0f\x9d\x60\x11\xfa\x7d\x5f\xdf\xa6\xd0\xce\x1e\x56\xa1\xed\x3d\xec\x2d\xf1\x30\x56\x35\xae\x4c\xd8\x97\x02\x09\xfb\x03\x85\x91\xa9\x48\x79\xd2\xd4\xc3\xf7\x45\x4e\x7e\x60\x35\xc3\x79\x4c\xdc\xc3\x69\x16\x7a\x78\x75\x36\x76\x3f\x40\xfb\x3b\x91\x40\x24\x89\x41\xfa\xfc\x57\x6d\xed\xa0\x3c\xb5\xed\x6b\x43\x7c\xdd\xd7\xbe\xc3\x28\xf5\x85\x45\x5d\xa5\xa7\x17\xf2\xf7\x55\x69\x72\x3b\x61\x44\x5f\x1d\x2a\xb6\x10\xd4\xf5\x15\xef\x17\xb4\xbe\xde\x19\xac\xe0\x8e\xef\x34\x5b\x7d\x0d\x54\x9f\xa9\xaf\xbf\x3f\x48\xfa\x09\xa9\xb6\xa7\xff\x96\xf0\x12\xcd\x7f\x4b\xda\x5c\x15\x69\x60\x37\xfe\xb7\x74\x70\x6d\xfe\x5b\x40\xb0\x70\x3f\x20\x7f\xe9\xbf\x85\x29\x85\x6c\xb0\x1c\x21\x39\xc3\x67\x31\xf6\xe5\x77\x97\x90\x5d\x02\xd4\x3c\x05\x80\x0b\x03\xe2\x77\x91\x42\x80\xbc\x03\xd8\x34\x04\xc3\x0f\x69\x80\xc1\xaf\x2d\x0a\xe9\xb6\xa7\xc0\xb2\xf1\x3b\x42\xbc\x67\x09\x21\xb0\x1c\x21\x77\x0a\xf9\xf3\x48\xef\x2d\x14\x7e\x69\x44\x9c\x83\xce\x15\x48\x38\xf4\xfd\x12\x1c\xca\xef\xb1\xa1\x59\x61\x31\x43\x33\xd4\x3f\x34\x7b\xb0\x90\x5f\x46\x42\xb9\x6e\xa1\x07\x9d\x50\x28\x83\x9f\xd0\x03\x7b\x3e\xf4\x34\xb2\x3d\x43\x51\x76\x52\x69\x43\x7f\xde\xaa\x45\x7e\x41\xb9\x37\x42\x0b\xc2\x77\xde\x5d\x08\x25\x46\x0b\xfd\x07\x60\x42\x89\x2c\x42\xe9\x91\x43\xdb\xce\xcc\xa6\x77\xa2\x65\x0a\xa5\x95\x86\xa6\x1a\x0a\x3a\xd0\x51\xe8\xbb\x2b\x43\x79\x7b\x27\xf4\xbd\x70\x14\x3a\xf2\x62\xa2\x8c\x52\x43\x79\x55\x24\x74\xf8\x0a\x56\x1f\xdd\x1b\x07\x34\x56\x41\xc1\x7c\x9b\xcd\x78\xb9\xce\x15\xe8\x6a\xb5\x77\x66\xdf\x57\x7c\x5f\xe3\x60\x78\x36\x15\xd7\x33\xaf\x9a\xc2\x36\xfc\x36\x54\xc3\x26\xa1\x91\xe7\x46\x79\x3f\xea\x87\x1d\xe8\x9f\x2e\x17\x2e\x61\x4f\x3c\x9e\x0f\x73\xbc\xf3\x7e\x0d\xbf\xf1\x87\x11\x3f\x04\x4f\x0b\x83\x5f\x78\x02\x38\x3b\xf8\xb5\x32\x7c\x73\xd2\xc5\x17\x46\x6d\xe1\x95\x07\x39\xdc\x2c\xe1\xfe\x31\x3e\xd7\x14\xd0\xe2\x70\x86\xc7\xc1\x53\xea\xf7\x02\x4e\xc0\xdb\xa4\x20\xe0\x8e\xb5\x51\xe6\x08\x84\x63\x9d\x29\x00\x77\x62\x35\xfc\x6e\x79\x52\x2c\xc0\x87\x21\x3b\x7e\xf0\x2d\x43\x76\x46\xdf\x43\x0e\xbc\x18\x0a\x0b\x8b\x0b\xc2\x94\x21\xe5\xa5\x13\x04\xfd\x0c\xe0\x9d\xf1\x1e\x34\x0f\x44\xa1\x43\xa6\x8d\xe3\x41\xea\xe3\xb2\x34\x04\x2a\x35\x64\x11\x85\x0e\x38\x8e\x21\x4f\x1a\x19\x01\xf5\x80\x77\x18\x19\xca\x3d\xf2\x0b\x97\x47\xd6\x86\xb7\x4b\x2b\x13\x58\xc8\x91\x8d\xe7\xac\x23\xdb\x18\x1e\x23\x8d\xec\xc1\x0f\xe7\x23\xfb\x9a\x69\xe4\x90\x0e\x8a\x58\x73\xe4\xb0\xce\xbc\xb5\xa5\xa1\x82\x1f\x80\xfd\x78\xb7\xc5\xc0\xca\x0f\xcd\xb0\xc1\x43\x33\x74\x19\xb1\x38\x99\x69\x7e\x6d\xc4\x00\x26\x1b\xaa\x9f\x34\xf4\xa4\x8f\x1b\xfc\xa2\x81\xa4\xa4\x01\x0d\x96\x48\x43\x19\xf3\x0e\x86\x5d\xb0\xa7\xef\x18\x35\x4c\x07\x12\x7e\x2a\x1b\x3a\xc6\xcb\x9b\x01\xd6\xd0\xb9\x7a\x1a\xb0\xb7\x69\x5c\x8c\x05\xc6\x25\xc7\x04\xe5\x21\xce\xb8\x28\x8c\x0b\x03\xb8\xd8\xdb\xa5\x61\xc7\x91\xc6\xc5\xd3\xe3\x71\x19\x6b\x03\xd3\x8c\xcb\x3a\x08\xb4\x68\x5c\x08\xcb\xc6\xe5\xc8\x76\x47\x15\x47\x21\xb6\xcb\xb8\x7c\xf1\xb3\xcc\xb8\xb0\xe7\xc6\x15\x56\x51\x06\x8d\x18\xd7\x3a\xa0\xba\xe3\x7a\x12\x9c\x0d\xb4\x76\xc0\xb4\x11\xa3\x0c\x53\x2c\x1a\xd5\x9a\xdf\x0a\x87\x15\x8a\x03\xf1\xc2\x30\xd8\xad\x61\x85\xfd\x5b\x35\xd8\x83\x61\xaf\x2a\xf0\xeb\xf6\x78\xb9\x05\x26\x6b\x44\x33\x03\xfa\x0f\xb5\xb1\xdf\x34\xe0\x3b\xc6\x87\xaf\x3c\x1b\x48\xe3\x63\xf8\x61\xd6\x30\xe6\xe3\x63\x18\xfd\x07\xb6\x7e\x20\xb8\x1f\x45\x6a\x1a\x45\xb5\x83\xd2\x72\x0c\x7a\xd4\xc1\x93\xcd\xf1\x46\xbc\xa3\x18\x6a\x39\x60\xda\x80\xdb\x1f\x14\x2c\xcf\xb1\x47\x85\x15\x1c\x55\xc0\xb8\x22\x22\x19\xd5\x3f\xa4\x3e\xaf\x34\x1a\x8c\xf5\x68\x88\x61\x46\x83\x4e\x35\xca\x1e\xb0\x77\x38\xde\x3d\x67\xf4\xea\xfc\x92\x3d\x28\x73\xdf\x25\x0d\xc7\xaa\xd0\xd3\x0f\x2f\xbb\xb1\x4e\xb1\x1d\xf4\xbd\x30\x32\x78\x5e\x33\xbc\x2a\x00\xcd\x40\xc8\x3c\x9c\xf9\x08\xd5\x06\xd7\xc9\x17\x78\x62\x13\x0f\x87\x9a\xbc\x56\x6c\xf8\xc2\xd0\x3a\x0c\xe0\xa0\xff\x1e\x00\x67\xe8\xbf\xcb\xdd\xd2\xe8\x2a\x1f\xd0\x77\x4c\x9d\xca\xdb\xa9\x3b\xfc\x24\x3c\xfa\xa5\x6c\x44\x49\x75\x5e\x44\x18\xdd\x3e\x7c\x41\x73\x43\xc8\x38\x7a\x21\x05\xbc\xa6\xd5\x84\x6a\x77\x8e\x90\x36\x77\x74\x48\xb2\x07\xf6\x6e\xe7\xe5\xa6\xd1\x69\xe3\x46\x7f\xd2\x80\x7f\x54\x24\xbc\xef\x84\xb0\x8c\x37\xd5\xc6\x1b\x4f\x8c\x29\xbb\xad\x8a\x14\xd2\x9c\xb4\x04\x53\x0c\x3b\x79\xc2\xef\x8d\x49\xd3\x31\xb9\x2c\xb4\x68\x63\xa2\xa3\xc9\x99\x4d\x25\x2b\x05\x03\x2c\xfd\xd4\x50\x4f\xc0\x65\x28\xa4\xba\x4c\x8e\x64\x72\x3d\xa6\x57\x81\x32\x4d\x0a\x7a\xd2\x80\xf0\x18\x75\x4c\xaa\xff\x84\x1f\x3d\xf1\x1a\x8a\xdd\x3f\x83\xb2\x98\xc1\x35\x99\xb1\x78\xba\x3e\xe6\xe2\x0d\xd8\x31\x17\xc7\xfc\x9e\x83\x8e\xf9\x80\xae\x37\xc0\x19\x6b\x03\x5c\x1d\x6b\x83\x31\x1d\xeb\xbd\x3c\x3b\x10\x5f\x8e\xc5\x93\xdd\xb1\x18\xc0\x8c\x75\x0a\xe9\x89\x10\x8e\x07\x48\x63\xf1\x18\x7a\x2c\x54\x6a\x0d\xcd\xdb\xc0\x70\x56\x67\x76\x47\x40\x3a\x56\x0f\xda\x41\x20\xdb\xb1\x82\xdf\xc7\xc6\x42\xa0\x3f\x56\x00\x8c\xf1\xe1\x35\xfc\x63\xc5\x57\xd1\xe6\xbd\x45\x39\xd6\x60\x9c\x35\xee\x7f\x96\xe5\xa6\xa4\x6f\x21\x89\x9a\xc6\x0d\xac\x3e\x6e\x0a\xe1\xa6\x59\xb9\xb1\x73\x6e\xca\xf2\x26\x24\x1e\x37\xf0\xc1\x78\xea\x06\x29\x3e\xb5\x4f\xaf\x69\x3c\x01\xed\x7c\xb8\x24\xef\x0a\x4f\xe1\x0d\xa2\x29\x67\xe2\xbd\x81\x29\xb4\x13\x53\xca\x27\x4d\x69\x20\x1d\xc5\xfc\x14\x34\x65\x20\x63\x4c\xe4\xcc\xe9\x9e\xa6\xfc\x5a\x9a\xbc\xbd\x38\x55\x6a\x9a\xd0\x5e\x04\x7b\x53\x1b\x02\x89\xa9\xad\xd9\x40\x82\xe7\x40\x85\x81\xa7\xdf\x99\xe6\x45\xf6\x97\xe0\x11\xb2\x9a\x17\xda\x5d\x8a\x15\x9f\xd4\xfc\x79\x29\x1e\x31\xad\x79\x81\xcd\xe5\xbc\xd1\x35\xaf\x50\x94\xf2\x6b\xfb\xbc\x10\xab\xcf\x6b\xd5\x0d\x94\xc6\x65\xbe\x77\x5c\x26\x8c\xcb\xb4\x93\x39\x05\xef\x44\x32\xd3\xd0\x9b\xb5\x27\x4d\xeb\x09\xc8\x62\x4f\xf3\x3d\x7c\x9d\x06\x63\x3f\xe9\xd4\xa7\x6f\x80\x83\x69\xfa\x2e\x0f\xe8\x5e\xd0\xd8\x51\x7e\x2a\xc1\xdc\x74\x2b\xe8\x87\xd7\xfe\xa0\xbe\x13\xd5\xeb\x7b\x09\x91\x6a\x3c\xbd\x9d\x8b\x09\x4d\x1c\x95\x7a\xd2\x64\x4d\xef\xf8\x59\x06\xed\xec\x15\xde\x6e\x7a\x34\xd9\xc1\x26\x26\x83\xff\xe9\x63\xa4\xe9\x53\xd0\x70\x85\x71\x64\x84\x38\x93\xa1\xc3\x44\x00\x3a\xfd\x49\x93\x80\x75\x32\x5a\x9c\x21\x08\xbd\x91\x9e\x6f\x62\x0d\xb4\x0d\x68\xf5\x84\xd7\x9d\xbc\x39\x34\x81\x47\x4b\xe2\xbd\xd0\x17\x5c\x4d\xca\x16\xf8\x2e\x4d\x1e\x8d\x4d\x5e\x3d\x99\xbc\x0a\x39\xc3\x4e\x8a\x33\xac\x82\x80\x8d\xf7\x0b\x6d\xdf\x9b\x14\x33\x16\xab\x2d\x3e\x16\x14\xac\x8a\x78\x70\x06\xb0\xd1\x0c\x98\xc4\x89\x15\x5e\x60\xba\xde\x80\xe9\xdf\x26\x9d\xab\x09\x08\x42\xe1\xb9\xe2\x83\xd5\x07\xd0\x9b\x2b\xb8\x2c\xb7\xc2\x14\xcf\x5b\xdb\x7c\xd2\xbc\x61\x16\xe7\x8d\x89\xdd\x94\xca\xed\x69\x3e\xd0\xd6\xa7\x33\xcc\x5c\x67\x79\xd2\xaa\x5b\x68\x29\x92\xd6\x7b\xd5\x60\xb5\xf7\x36\xf0\x6a\x99\x6f\xef\xc5\x94\x57\x6d\x56\xdb\x3d\xad\xc6\x2b\xea\xab\xf1\x13\xe9\x6a\xef\x27\xa6\xd5\x8c\x98\x7a\x35\x5e\xcd\x5e\xcd\x26\xc8\x57\x11\x8c\xac\xf6\x69\x58\x85\xd5\x78\xc6\xba\xda\xb4\x92\x56\x5b\xbc\xa7\xb8\xda\x57\xf1\xda\x79\x9a\xb9\xfa\xc9\x05\x5a\x9d\x9f\x83\x56\xf7\x96\x16\x43\xe9\xd5\x61\x45\x56\x6c\xd2\x12\x0d\xc5\x0b\xbc\x80\xe0\x79\xe5\x7c\x0d\x3d\x56\x41\xc2\x0b\x12\xff\x98\xcf\xf7\x3f\x03\x5f\xc9\xd8\x6e\x5f\xc9\x6b\xd5\xf4\x15\xe8\xdc\x57\xe0\xc7\xbe\xef\x3d\xf8\xaf\x40\x74\x5f\x69\xf8\xd9\xb8\xd2\x57\xba\x47\xfa\xca\x7b\x15\xeb\x0b\x85\xff\xf2\x83\xfa\x57\x2f\x83\x68\xbe\x10\x36\x5e\xdb\x8e\x8a\xbc\x14\x89\xdc\x06\xd6\x1a\x1b\x88\x1d\x0f\x12\x02\xa5\x2f\x82\xdb\xaf\x8e\xa1\x25\x7d\x75\x6a\xa0\x2f\xa3\xcc\xbf\xb6\xf1\x0b\xe2\xd7\xf2\xdb\x9b\x65\xda\x75\x04\x88\x9e\x88\xda\xbf\x56\x0a\xa6\xfb\xb5\x36\xdf\xd4\x8b\x81\x41\x10\x77\x7f\x2d\xd8\x6e\x08\x88\x81\xd5\x78\xf3\x27\xe9\x17\x33\xe5\x29\xf7\x97\x17\x25\x79\xf9\xfb\xeb\x25\x4b\x73\xa4\xab\x22\x6f\x82\x3c\x60\x7f\xff\x23\xde\xd2\x2d\x36\xd3\x0d\x7b\x07\x7b\x0b\xd2\x16\x32\x1a\x48\x1c\xd0\x15\x5a\xdd\x5b\x02\xc1\x74\xba\xb1\x6d\x6e\x19\x1d\x64\xa2\x10\xf8\xe8\x06\x3e\x86\x33\xb9\xdf\xef\x8a\xb7\x0a\x96\x96\x96\xfa\x46\x6c\x55\x90\xd0\x68\xdc\xba\xa5\x5b\xdf\x70\xf8\x56\xfd\x60\xa7\xdd\x6a\x01\x5a\xf8\xcd\xeb\x86\x91\xbc\x75\xa6\x9b\x5f\xaf\x6e\xd8\xc8\xfb\xd2\x97\x82\x13\x2c\xe5\x4d\x13\x79\x03\x4a\xde\x97\x31\x02\xbf\x61\xef\x6e\xdb\xd1\xbf\x1d\x78\x2c\x3b\x48\x49\xd8\x25\xb7\x35\xc0\xd6\x1b\x08\x94\xae\xe2\xb6\xf6\x01\x69\x6c\xca\x4b\x31\x37\xc2\xac\xdb\x06\xc2\xd8\x1b\xd6\xe7\x86\xae\xdc\xff\xee\x28\xdc\x5e\x8e\x74\x23\xae\x49\xb7\x73\xc7\xdc\xee\x3b\x48\x49\xf4\x37\x3c\xdc\xbc\x3d\x0a\x1f\xe3\x01\xc5\x60\x60\x6f\xee\xd0\xfc\x01\xe5\x25\xde\x9b\x86\xec\xe6\xcd\x8d\x9b\x0e\xfc\x81\x49\x7b\x20\xaf\x47\xe9\xf7\x1e\x5f\xf8\xa1\x88\x40\xea\x4f\xb7\x90\xf4\xa7\xe1\x89\x47\x6b\x7f\xee\xe9\xff\x00\x00\x00\xff\xff\x96\xd2\xdb\xc1\x3c\x33\x00\x00") -func keysWordlistEnglishTxtBytes() ([]byte, error) { +func keysWordsWordlistEnglishTxtBytes() ([]byte, error) { return bindataRead( - _keysWordlistEnglishTxt, - "keys/wordlist/english.txt", + _keysWordsWordlistEnglishTxt, + "keys/words/wordlist/english.txt", ) } -func keysWordlistEnglishTxt() (*asset, error) { - bytes, err := keysWordlistEnglishTxtBytes() +func keysWordsWordlistEnglishTxt() (*asset, error) { + bytes, err := keysWordsWordlistEnglishTxtBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "keys/wordlist/english.txt", size: 13116, mode: os.FileMode(420), modTime: time.Unix(1511602021, 0)} + info := bindataFileInfo{name: "keys/words/wordlist/english.txt", size: 13116, mode: os.FileMode(420), modTime: time.Unix(1514928181, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _keysWordlistJapaneseTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x5c\xff\x72\xe2\xb8\xd2\xfd\x9f\xa7\x5e\xbc\x5c\x2f\x01\x3c\x0e\x71\x1c\xc7\x61\x58\x87\x8a\x2f\x43\x60\x80\x0c\x59\xb8\x93\x8f\x2c\x3c\x8c\x5f\xe4\x2b\xf5\xe9\x3e\xea\x99\xaa\x54\xea\x1c\x59\xd6\xcf\x56\x77\xab\x25\xd3\xf5\x93\xae\x3f\xe8\xfa\x45\xd7\xcf\xbb\x7e\xd5\x25\x45\xcf\x92\xca\xae\xdf\x92\x3c\x03\x8d\xba\xfe\xdf\x5d\x72\x03\x32\xee\xfa\x8b\x2e\xf9\x93\xef\x64\x5d\x32\x06\x9a\x76\xfd\x49\xd7\x6f\x8c\x58\x72\x11\x92\x93\x09\x79\xd9\xf5\x07\x44\x07\xa0\x4a\xfe\xaf\x40\x1e\xbb\x24\xef\xfa\x29\xc8\x53\xa8\xd1\x5e\x7d\xea\xfa\x19\xd0\xbc\xeb\x9f\x80\x9a\xae\x3f\x64\x86\x26\xfc\x25\x7d\xc7\x93\x51\xd7\xbf\x74\xfd\x21\xb9\x3e\x69\xd9\x8a\x56\xfa\xa4\xd5\xbd\xc8\x70\xfc\xa7\xeb\xe7\x7c\x78\xe9\x92\x91\x11\x57\xf4\xb2\xeb\xaf\x89\xf6\x92\x4d\x9f\x1c\x88\x4e\x1c\xb5\x13\xd3\x8e\x7e\x2c\x2e\x6c\xc5\xa5\xeb\xbf\x1a\x4a\x06\xd2\xa4\x9a\x5c\xeb\xbf\x76\x49\xd2\xf5\x77\x42\x42\x4b\x46\x5d\x1f\xe5\x84\x17\x58\x7f\x92\x76\xc9\x1f\x40\x37\x32\x8b\xb7\x5d\xff\x42\x5e\x11\xd5\x5d\xff\x91\xc4\x8f\x5a\x72\x23\x65\x44\x92\x5b\x5b\x42\x8d\x93\xae\xbf\xb2\xe1\x0a\x4f\x66\xcc\x99\x87\xa1\x30\x52\x58\xcf\x12\x99\x7f\x47\x0a\xa2\xaf\x26\x44\x81\x2c\x7d\x9e\xb5\x27\x3a\x00\x03\x88\x24\xda\x32\x08\x52\x29\x6f\x0f\x58\x3c\x50\x0e\x94\x89\xd8\x0e\x48\xd6\x2c\x24\xe3\x28\x0e\x28\xbd\x03\x59\x08\x8f\x44\x27\x96\x3d\xed\xfa\x6f\x98\x69\x21\x96\x5c\x60\x08\x74\x0d\x11\xb5\x3d\x5b\x44\x17\x11\xea\x81\x71\x7b\xaf\x82\x04\x0f\x44\xca\xff\xc3\x42\x1e\xbb\xe4\x2f\x4f\x72\x36\xeb\xa9\xeb\x5f\x0d\x25\x13\xa0\x19\x0b\x9e\x05\xe1\xef\xbf\x93\x8c\xfd\x13\xad\xe8\x2b\x2b\x9f\x77\xfd\xb4\x4b\x32\x56\x34\x97\x01\x8b\xcd\x7c\xf6\x48\x3b\xd5\x48\xc5\x37\x24\x57\x43\x41\x16\x12\x90\x85\x8c\x75\x4a\xf2\x48\xf4\x4a\xf4\x46\x74\x32\x94\x8c\xfc\x10\xb4\x10\xe6\x41\x5c\x83\xd6\xec\x17\xdf\xe3\x17\x74\x83\xa4\xf1\xd9\x16\x44\x4b\xff\xc2\xbf\x7c\x61\xd9\xf5\x1f\x0c\xd9\x7b\xaf\x7c\xba\x82\x70\x0e\x28\x7f\x40\xda\xac\x6d\x97\xfc\x41\x21\xda\xb1\xb2\x1d\xa7\x6a\xcf\xf9\x7f\x73\x69\x56\xcd\x3b\x27\xe4\xc0\xb4\x23\x87\xf9\x27\xd3\xce\x6c\xce\xd5\xd2\x82\xbc\xa6\x50\x8f\x20\x8d\x89\x42\x92\x58\x8b\x12\x91\x7e\xad\x36\x10\xac\x92\x64\x28\xfa\xb3\x20\x41\x7d\xa2\x19\x88\x6a\x96\x3d\x12\x6d\xb1\x30\x12\x85\x32\xe1\x1a\x0b\xda\x8b\xeb\x27\x89\x55\x66\xa2\x87\x8b\xae\xff\x8f\x0d\x43\x50\x08\x03\xa2\x94\x28\xb6\x27\x37\xb9\x08\x02\x9f\xb2\xa8\xa2\xeb\xdf\xd9\xca\xef\x33\xa9\x64\xb9\x85\x08\x48\x6c\x5b\x21\x3d\x0b\x24\x95\xf5\x90\x19\x92\x02\x53\x91\xce\x07\x20\xed\x46\x2a\x4b\xe5\x44\xf4\xc1\xac\x59\x97\xe4\x40\xb9\xe9\xcf\x35\xf9\x04\xe3\x9e\x8a\x5a\x68\xa4\x7d\x39\xdf\x9c\x8a\x0c\x4f\x49\x56\xee\x49\x18\xb1\x96\x44\x93\xef\xa9\xe5\x41\xb4\xde\x02\xc3\x93\x4a\x8f\xbf\x00\x55\x22\x88\xa9\x91\x30\xd8\x13\xac\xc5\x54\xa6\x6f\x40\xf4\x85\xe8\x96\xb3\x2c\xdc\xf4\x7b\x2a\xab\x49\x1b\xb3\xa0\x16\x27\x9f\x70\x00\x16\x1c\xc9\x05\x17\x6a\x2a\x0b\x6a\x0c\xa9\x4b\xa5\xc7\x39\x55\x48\xaa\x2b\xd2\x8d\x7c\x4b\xf4\xca\x6e\xad\xd9\xca\x35\x74\x05\xd0\x13\x47\x60\xcd\x97\xb6\x44\x3b\xd6\x7f\xea\xfa\x77\x44\xf7\x30\xed\xa9\xcc\xc5\xc4\x72\xc7\xbe\xca\xd2\x01\x12\x1b\x69\x64\x68\x95\x85\x31\x9a\x88\xd4\xd4\xe4\xba\x04\x40\xd6\xd6\x37\x51\x78\x56\x77\x20\x99\x49\x43\x32\xa6\x57\x93\xca\x4a\xa9\x1c\x49\x52\x1b\x46\xd7\xbe\x0c\x9a\x26\x95\xb1\xcf\x88\x4a\xa0\x82\xf6\x05\x64\x61\x43\x07\x3b\xe9\x88\xea\xae\xa1\xc8\xe9\x10\x4f\x40\x26\x44\x19\x97\x0a\xf8\x3d\x91\x6a\x55\x90\x93\x7b\xdb\x96\x13\x48\x0e\x34\xc2\xa4\x0f\x65\xbc\x22\xd2\xa7\x99\x4c\xbc\x16\x17\xdd\x82\xa1\x88\xeb\x9f\xcc\x56\x77\xfd\x25\x50\x2b\xae\x85\x56\xb9\xeb\xfa\xb7\x40\x67\x9d\x4c\x19\x15\xe1\x96\x87\x69\x61\x4e\x1f\x89\x76\x40\x37\x56\x79\x40\x27\x20\xb5\x50\x50\x4b\x1c\x9d\x40\xc6\xcc\x5d\x40\x18\x87\xaa\x75\xac\x8a\xc2\xfc\xc0\x94\xfc\x2b\x56\x0d\xc8\xdc\x7a\xa4\xf3\xf3\x97\xcf\xb9\x42\xce\x91\x8c\xeb\x98\x4b\x7e\x64\x5e\x42\x4d\xa2\x82\x32\x32\x0b\x98\x83\xa4\x6c\xee\xc8\x14\xc1\x85\xe4\x91\x68\xc6\x7a\x52\x8e\x3e\xc8\xd1\x17\xf5\xe1\x9e\xd8\xcc\x8e\xb8\x48\x47\x74\x94\x46\x34\xe3\x40\xaf\x9c\x73\xe1\x09\xf3\x84\x42\xe6\x20\x63\x0c\x34\xc9\x13\xd0\x04\x2e\xa8\xa4\x05\x15\xa9\x19\xbe\x50\x8d\x8d\xe8\x7a\x8d\x44\x5c\x62\x0f\x73\xef\x0d\x09\x57\xaf\x73\x4d\xce\xd7\x6c\x45\x8d\xfc\xb0\x16\xbe\x92\x82\x19\x4a\xdf\xe3\x92\xeb\x5a\x88\xe9\x8b\x11\x66\x04\xeb\x1a\x24\xbe\xf3\x08\x49\x01\x2a\x39\x3d\x22\xde\xf6\xc2\x5c\xc4\x2f\x27\x89\x8d\x6d\x68\x7b\x40\x34\xcf\x33\x9c\x7d\x90\x85\x97\x81\x17\x18\xe5\x91\xac\x14\x1d\xbf\x6f\x10\x27\x90\x95\xd4\xad\x2b\x00\x7c\xed\x25\xea\x95\xaf\xbd\x8a\xc2\x19\x73\x84\xde\x7c\xfb\x2f\xb0\xf5\x42\x92\xbe\xd4\xb1\xb2\xe1\x4b\xb0\x0d\xfc\x46\x12\x93\x29\x6e\x81\x84\x0d\x21\xc8\xc0\x44\x32\x19\x88\xe6\x7b\xef\x99\xc0\x7c\x5a\xf5\xb2\xec\xb1\xb7\x1c\x49\xc3\x34\xb9\xa0\x3a\x01\x99\xb2\x06\x2c\xc6\x3f\x49\x66\xd6\x78\x29\xc7\x93\x68\xa8\x46\xa6\x1f\xb5\x98\x31\x76\x70\x40\xaa\x1f\x27\xd0\x8f\x44\xea\xde\x4f\xbc\x87\x3f\xf6\xbb\xe2\xb1\x2e\x5a\x69\x0b\x48\xed\x1d\xab\xb1\x77\xb8\x41\xfe\x86\xf1\x23\x6f\x7d\xb1\x4b\x9f\x73\xe5\x9f\xe8\x02\x9e\xa8\x73\x28\x8d\x1c\x7b\xff\x70\xec\xf5\xf4\xc4\xfb\x74\x63\x2a\xed\x31\xc5\x77\xcc\xa5\x3c\xfe\x2d\x79\xc2\x96\x4f\xb0\x39\x1c\xd3\xb5\x18\xcb\x62\xbc\x27\x5a\x31\xeb\x03\x5e\x9f\xa0\x7b\x48\x6b\x58\x7b\x03\xf3\x39\xf1\x8a\x71\x22\x02\x9d\x71\x7a\xc0\x0b\x4f\x4a\x8e\xfe\x8b\xf7\xef\xc6\x22\xd6\x0f\x62\x1f\xb5\x7d\x3b\xbe\xb6\x67\x93\x4e\x58\x45\x63\x3f\x40\x67\xb6\xfe\xc2\xb4\x8b\x48\x22\x46\x3d\x2c\xfb\x09\x37\x92\x63\x11\x58\xf4\x41\x06\x16\xd2\x3b\x76\x03\x9b\x8c\x89\x32\x2b\x31\xb4\x2b\x37\x24\x1b\xa5\x09\x4c\x0c\xd2\x0a\x27\x81\xce\xb0\x8f\xbd\x54\x8f\xcd\xa4\xc4\x27\x0d\xdb\x54\xd8\x68\x06\xa4\x1b\x8b\x0c\x01\x1a\xa2\x16\x28\x78\xe1\x3d\xd1\xb2\x03\xbc\x9e\x49\x2f\x06\x86\x2c\x6d\xc8\x52\x54\xdf\x03\xe5\x44\x0b\x43\xf6\xc6\x98\xa5\x8c\x99\xef\x97\x2e\x64\xf2\xb7\x04\xca\xa5\xa1\x23\x23\x61\xfc\xee\x40\xa6\xba\x7e\xad\xb4\x82\xf5\x17\xbe\x59\x05\x2b\x29\x99\xb5\xf4\x69\x17\x43\xa1\xec\x2f\xe8\xf3\xa3\x97\xe7\x2f\xdc\x6a\xe3\x49\xe3\x17\x38\x92\x36\x7e\xa3\xf8\xc5\x36\xe4\xad\xef\x52\xcd\xe6\xc5\x26\xeb\xc6\x3a\xa3\xf9\xcd\x38\x75\x99\xac\x87\xdc\x90\x0d\x5e\xe3\xbb\x16\x97\x44\x26\x95\x0d\xd9\xa4\x17\xec\x89\xf9\xa4\x65\x45\x6d\xd7\xdf\x02\x2d\xd9\x8c\x57\x16\xf2\xca\x2a\xd7\x7c\xba\x86\x82\x03\xd2\x66\x7c\x17\x6f\xb9\x02\xd9\xb2\x75\x3b\x16\xb4\x93\x31\x6b\x40\xf6\x2c\xf5\x9d\x46\x25\xe3\xde\x35\xa3\x86\xca\xe8\x39\x66\xb2\xb2\xb4\xac\x33\xd3\x2e\xec\xfa\xd5\xc6\x2b\xf9\x43\xe3\x7a\xb1\x60\xb3\xc0\x08\xce\x3c\x8b\x25\xaa\xc8\x17\x3d\x1f\xb6\xc9\xe8\x50\x66\x62\x70\x30\xdf\xa2\x59\x64\x56\xf5\xc9\xd0\x1a\x23\x03\xee\xa3\x0d\x19\x97\x74\x46\x7b\x9d\x49\x06\xb4\xd9\x36\xbb\x40\xda\xe6\x8c\x15\x65\xcc\x97\xb3\xdd\x5f\x10\xf1\xc2\x02\xcc\xcc\xc7\xd4\x98\x12\x78\xf0\x6a\x8c\x38\xfd\x72\xcb\xb5\x9c\x23\xcc\x03\x94\x72\x9f\x0c\x92\x11\xdd\xfa\x64\x5d\x40\xb7\xe6\x0f\x0e\xf8\x64\xee\x9f\x34\xd0\x4c\xb9\x77\x0e\x41\x3e\x81\x62\x5d\x71\xbb\x90\x63\x1b\x8e\x42\x0a\xa6\x95\xac\xa5\x64\xb3\x4a\x46\xc9\x84\xc8\x90\xe4\xe6\xfa\x5f\x49\x62\xc1\xb5\x88\x5b\x66\x24\x8c\xbd\x8e\x87\xec\x1d\x44\x5f\xe4\xb4\xf4\xb7\xb6\x80\x97\x7c\xe7\xd9\xd7\xd3\x04\x29\x35\x67\x30\x17\x47\xaa\x60\xbd\x0b\xdf\xd0\x96\x32\x7e\x2b\x2b\xae\xc6\x8a\x93\x27\x61\x8a\x6f\x7b\x66\xea\x52\x9a\xe7\x9c\x6b\x2c\x97\xbd\xa9\xa6\x6d\xf1\x1f\x64\xc7\x9e\x1d\x89\xae\x7e\x73\x0d\xde\x30\x44\x1a\x45\x27\x87\x10\x63\x80\x7a\xa6\x30\x6b\xa2\x0f\x66\x1b\x43\xf1\xe5\xae\xab\x66\x87\x72\xd8\x47\x4c\xcd\xad\xca\x9f\x8e\x5d\x8c\x97\xe4\xe4\x8d\xcf\x19\xd4\xf6\x54\xc4\x70\x0d\x34\xa0\x9e\x9f\x7a\xbd\x09\x12\x91\x7a\x45\x77\x2e\x9e\xd9\xf2\xa1\xd6\x70\x67\xe1\xb2\x54\xb2\xf0\xe5\xb0\xb2\x32\x12\x45\xf0\x62\x6b\x23\xc9\x88\x6b\xfe\x0e\x26\x87\x48\x05\x13\xe4\xd9\x93\x85\x27\x2b\xb6\x30\xa8\x34\x43\xa6\x34\xee\x28\xd6\x77\x76\x16\x12\xb7\x1e\x77\xc1\xe9\x90\x2e\x4c\x29\x40\x92\x66\x7d\xa8\xd8\x81\x2a\x68\x56\xd9\xf0\x4c\xbd\x98\xdf\x31\xb2\x86\x68\xd1\x1b\x90\x9c\x9e\x04\xd9\xfb\x1f\xf9\x0d\x3b\xdd\xd2\x9e\x4f\x79\x46\x31\x55\x43\x61\xd5\xbd\x30\x46\x84\x27\xaa\x58\xa6\x16\x29\x8d\xd9\x96\xbe\x80\x0b\xc7\xa2\xf5\xfa\x07\x7c\xe2\x72\x9a\x82\xbb\xa3\xdc\x4b\x34\x2b\xac\xf0\xba\xe7\x43\x5b\x53\x31\x2f\x77\x44\x35\xd1\x15\xe8\x3b\x87\x6d\xcb\x4e\x6d\xd9\xf4\x3d\x25\xe4\xc0\xb4\x13\x7d\x8d\x3b\x31\x27\x5a\xbb\x1e\x01\x4c\x65\x11\x8d\xad\xf6\x60\x47\x2a\x43\x9a\xc1\x04\x66\x4a\x1d\x3f\x95\x45\x32\x35\x21\x73\xeb\x64\xca\x63\x8a\xa9\x86\x08\xb4\x91\x81\x8c\x88\x20\x75\x01\x65\x4c\xbb\xb3\x16\x3b\x9f\x6e\x6a\x61\xca\x9c\x24\xc6\x10\xc0\x6b\x93\x0c\xe7\xf0\x4d\x75\xe7\xe2\x5e\x5b\xfa\x56\xad\x7c\xb6\xb5\x7f\xb2\xb1\x79\x0a\xe4\xe4\x1b\x7f\x21\xba\xba\x86\x06\xa3\xca\xb7\x2d\xfa\x02\x12\x7a\x5b\x88\xec\xe5\x78\x5b\xac\x59\xff\x3b\xd1\x3b\x24\xf9\x9e\x1e\x65\xe1\xc3\x14\x85\x86\x59\x1d\x51\xf5\x73\x6f\x51\x55\x1d\x87\x7b\x0b\x8f\xc6\x32\x74\xf8\x0a\x0b\x75\xc4\x27\x8f\x44\x1a\xe3\xbc\xf7\x76\xae\x30\x3b\x97\x93\x34\xfe\x89\xee\x4a\x0b\x0b\x54\xc6\x4a\x96\x3e\xdb\xab\x7f\xb2\xf6\x4f\xf6\xbe\xd2\xb3\x6f\xff\xc5\xf5\x34\x48\x1c\x5b\x90\x8c\x30\x0d\xd1\x9d\x2d\xb8\xf5\xba\xa7\x6c\xdf\x8b\x9f\xda\x5a\x9a\x95\xa5\xbb\xad\xc2\x9b\xd9\x82\xf6\x88\x64\xed\x9f\xec\x59\xf9\x2d\x27\x2e\x8e\xee\x94\x6d\x28\x44\x09\x93\xc8\x62\x28\x10\xfb\x00\xaa\xd8\xf0\x9a\x95\xc5\x81\x56\xb5\x12\x0f\xed\x20\xbf\xcf\x30\x1e\x85\x1f\xf9\xc6\x77\xbd\x61\xa9\xd1\xf1\x2d\x10\x43\x06\x6a\x79\x6e\x06\xf2\xc6\xe2\x5b\xc4\xf1\x0a\x3f\x5d\x4b\x3e\x5d\xc9\x96\xe8\x86\xa4\x22\x7a\x33\x64\x42\xbd\x96\x61\x5e\x83\x6c\xf1\xbf\x67\x23\x72\xe1\xa8\xed\xa0\xb6\x04\x25\x43\xcc\xcd\x9e\xf5\x1d\xa0\x6a\x41\x8e\xec\xc8\x91\x19\x3e\x69\x95\xef\xa5\xd4\x78\xfc\x2b\x07\x19\x6e\xea\x2f\x74\x3b\xf0\xa4\x65\xe3\x2e\x36\x6e\x41\xb3\x7d\x81\xa9\x2d\x18\xef\x2c\xe8\x0b\x17\x54\x73\x82\xb4\x09\x66\xd6\x80\xd0\xab\xe0\x55\xa5\x44\xef\x40\x43\x1b\x4f\xf3\x91\x0b\x31\xb5\x5a\xf5\x24\x7a\x6b\x56\x70\x26\x33\x36\x05\xc9\xa5\xf2\x25\xc9\x84\x6f\x16\xdc\x78\x16\x3e\xca\x5a\x50\x77\x16\xbf\x29\xc5\xc2\x94\x62\xcc\x46\x89\x82\xea\x73\xa5\xad\x3d\x79\xef\xfa\x1b\x92\x7f\xfd\x93\x0b\x1b\x5a\x20\x64\x09\x34\x71\x95\xd8\x96\xfd\x41\xc3\xe6\xd2\xb6\xd2\xdc\x9e\x01\x89\xda\x41\x64\xbb\xf3\xa4\x60\x1e\x75\xda\x4a\x1f\x50\x7f\x30\x07\x28\x56\x12\x03\x53\xa5\x77\x64\x1f\x7e\x3b\x68\x2b\xa1\x84\x80\x34\xda\x04\x32\x81\x79\x45\x72\xcc\x70\x85\x40\x94\x3c\xfc\x2b\x65\x2f\x12\x8b\xcb\x59\x42\x4e\x3b\x5b\xc2\xb5\x04\xd2\xbd\x76\xc9\x75\x58\xfa\x4b\x17\x0f\x5c\xfa\x25\x83\x12\xa5\xf9\x23\xda\xd7\x96\x9a\xff\x81\x2b\x1b\xc9\x13\x96\xfd\x62\x1b\x8b\x9c\xd9\x2a\x16\xf5\xe8\xdf\x9e\xb3\xe9\x2d\xbd\xa6\xd2\x1c\x98\x41\x97\x24\xe0\x4b\x4e\xd4\xca\x27\xaf\xf8\xf6\x8a\x31\xeb\x92\x0a\xa2\xa4\xeb\x52\xd2\x65\xc7\xd6\x45\x9b\x19\xf7\xba\xa5\xc4\xcd\x75\x3c\xce\xcc\x7a\x46\x2c\x0f\x07\xfc\x3a\x21\x57\xff\xd2\x55\xdc\xd1\x89\x90\xb0\x8a\xa7\x3d\x1f\x60\x2e\x65\x69\x0e\xfd\xd9\x4d\xc9\x35\x5a\x72\x3d\x96\x8c\x28\x22\xc2\xf1\xdc\x43\xcc\x4d\x46\x07\x03\x92\xe4\x8c\x1c\x97\x8c\x33\x97\x7e\x0d\x96\x74\x5e\x80\xe2\xb6\xb9\xf4\x5e\x4b\x69\x5e\x0b\x66\xd3\x36\x0b\x7c\x52\xfb\x6c\x33\xeb\xa7\xf8\x2f\x44\x0b\xa2\x0b\xd1\xd5\x90\x39\x1a\x15\x37\xba\x15\x0f\xd2\x2a\xbb\x07\xf4\x82\x65\x5f\xf9\x2d\x93\x84\xe2\xa5\xc1\x15\x3b\x55\xc1\xb2\xf7\x34\x36\x6f\xc5\x8d\x30\xd0\x15\x17\x70\xc5\x1d\xcc\x23\x2d\xac\xb8\xe9\xe2\xc5\x54\xec\xd6\x23\x6f\x3d\x54\x22\x6d\x29\x0b\x6a\x10\x58\x02\x5a\x12\x5d\x81\xa2\x35\xab\xec\x2a\x83\x56\x11\x8f\x47\x2b\x9a\x0c\x41\xa6\xa8\x2b\x0a\x6f\x45\x3d\x00\xd4\xa2\x41\x6a\xe4\x1e\x29\x22\x38\xfd\xfd\x02\xb1\x12\x62\xea\xbf\xa2\x5a\xac\xc4\xb4\x5d\x0c\x59\x9a\x1e\xac\x01\x9d\x80\xf6\xac\xfd\xcd\xb7\x55\xaf\x2f\x08\x32\xdf\xb9\xa2\x09\xac\x44\x7b\xc4\x3e\x1f\x39\xba\x27\x66\xf8\xc9\x97\xce\xcc\x77\xe6\xd3\x0b\xd3\xd4\xcc\x55\xf4\x4e\x2b\x2c\x15\x24\x3f\xc2\xaf\x87\x0c\x56\x74\x5a\x2b\x2e\xa2\xca\x0d\x65\x10\xe9\x81\x27\xa9\x27\x23\x1b\xc9\x40\x26\xd4\x13\xd5\x6f\x3b\x6e\x3d\xa1\x74\xcd\x0e\x7c\xea\x4b\x8a\xe8\x81\xcd\xf9\x93\x57\xe7\x40\x66\x9e\xcc\x7d\x51\x8d\x7f\xc7\x8b\x8e\xee\x04\x33\xdf\xce\x8b\x3d\x89\x42\x25\x27\x4c\x28\xe3\x91\xea\xe2\xd1\x42\x5e\xb1\x17\xff\xf1\x2e\x21\x9e\xc7\x16\xfe\xc7\xef\x0f\xc1\xaf\x86\xc2\x7c\xbf\xd9\x3b\x1a\x68\xd6\xd7\xfe\xb2\x3b\x12\x03\xf2\x9c\xc6\x0d\xfc\xc5\x0f\xd6\x5f\x4e\x6c\x83\x0b\x91\x98\x58\x85\x3a\x66\x9c\xc1\x18\xd8\xa8\xa8\xa7\x2a\xaf\x97\x1e\x2d\x68\xf6\x27\x9f\xcc\x10\x68\x20\x5f\xb0\x11\x05\x07\xab\xa6\x6e\x01\xaa\x88\x82\xd1\x7c\xc2\x9d\xb2\x9e\x9e\xdb\x98\x06\x01\x19\x13\xa9\x15\x79\xf2\x07\xe3\x3c\xe8\x51\x3f\xaa\xb6\xfb\x24\x39\xc9\x23\xba\x5a\xeb\x26\xc5\x5e\x8b\x67\x71\x35\x22\xa2\x40\x7a\x27\xa6\xf6\x3e\x7d\xcd\x55\x50\x8b\xb2\xd2\xb4\x02\xfd\x78\xe2\x21\x49\x2d\xa4\x62\x86\x1a\xe1\x87\xda\x5f\xf4\xa8\xbd\x2e\x7a\xb2\x53\x95\x48\x56\xc8\xa3\x1a\xa8\x66\x64\xaa\xe6\xb5\x0b\x04\xe9\xb4\xbe\x3d\xcc\x50\x2d\xb2\x71\xc3\xca\x9f\xbc\x5e\x78\x92\x6d\xe8\x77\x28\xaa\x5a\x86\x4e\xbb\x7d\x64\xda\x07\xb4\x69\xcd\xf9\x7f\xe2\xba\xab\xc5\x8b\xd6\xfa\x2e\xd6\x39\x0b\x05\xd7\x3c\x81\xac\x65\xfd\xa2\xd5\xb8\xbf\x24\xce\x4c\x1d\x2c\xa4\x6c\x67\x6a\x59\x2e\x72\x99\xc5\x5e\xc8\x5c\x9f\xcd\x5c\xd6\xfe\x16\x62\xad\xae\xa4\xbc\x30\xf3\xfe\xfb\xcc\x3c\xc3\x96\x44\x9d\xc1\x28\x90\x33\x7f\x1c\x37\xe3\xc1\xca\xcc\xbc\xb8\x31\x5f\xc8\xb8\x6f\x9f\x21\x16\x4e\x94\x12\xe1\x84\x34\x65\xb6\x29\x51\xc1\x72\x6b\x56\xac\xda\x05\x68\x0a\xf4\x42\xfb\x37\x33\x0d\xa3\xc6\xff\xab\xf0\xf8\x24\x96\xfd\x42\x17\x70\xa6\x07\x72\xb2\xcc\x21\xb0\x33\x31\x66\x7f\xf3\xcd\x96\x61\x37\x90\x6f\xbe\x98\x1f\xfe\xc9\x3b\xd1\xc9\x25\x9b\x5a\x07\x19\xb1\x5e\xbd\x6f\x37\x13\xd1\xd3\x57\xf7\x50\x4e\x33\x89\xf2\x66\x40\x9f\xd8\xc4\xcd\x28\x28\x33\xda\x95\x19\x97\xc0\xcc\xdf\x96\x9b\x49\x35\xc7\x1e\x66\x1c\xb1\x0e\x24\x17\x56\x82\x06\x81\x22\x19\x13\x65\x50\xb2\x20\xf1\x3d\x15\x04\x94\x78\xcf\xe4\xd2\x17\x12\x34\x2c\x49\xed\x9f\xcc\x3c\xf9\x9b\xa8\xf1\x35\x44\x73\x31\xf3\xb1\xa1\x99\x8f\x0d\x81\x68\xb4\x0d\x64\x6b\x63\x1d\xc8\x0f\xbc\x83\x56\x9e\x88\xfe\x75\x6f\xab\x1c\x22\x4a\xe4\x8e\x2b\x90\x94\xb8\xd2\x6c\x9b\x09\x92\xfa\x32\x54\xfe\xbf\xc2\xed\x23\x1a\x51\xf8\x66\x7e\x2f\x06\x12\x9a\x3c\xe7\x6c\xcc\x4d\xff\xde\x61\x06\xc1\xb7\x3d\xbd\xbc\xaa\xc7\xa0\xf1\x8c\x62\xce\xc3\x11\xa0\x7b\x22\x35\x7c\x20\xcf\x9e\xac\x3d\x79\x37\x24\xdd\x26\x19\x01\xc5\x2b\x46\x73\xc6\xba\xe6\xbc\xc9\x31\xe7\x8d\xa1\x39\x57\xe6\xdc\x42\x23\x9a\xf5\x81\x59\x2b\x98\xa0\x39\xa7\x7d\x4e\x23\x31\x97\xbf\xdb\x1e\x63\x2a\xec\x7c\xcb\x52\x5b\xdf\x80\x17\x6a\x14\x3c\xf9\xe2\x07\xe4\x05\x71\x5c\x92\xc2\x3f\x99\xf9\x32\x56\x40\x2b\xde\xfa\x03\xf9\x2f\x26\x6f\x2e\xab\x71\xc8\xb6\xac\x71\x70\x32\x17\xe7\xef\x13\xe8\x93\xd3\xf6\xc9\xa9\xbc\xb0\xf2\x8b\xbd\x1b\x3c\xba\xdc\x50\x58\x86\x43\x90\x3e\x33\x24\xf8\x0f\x22\x97\x56\xfb\x5f\x7b\x76\xa1\x46\xef\x81\xce\x79\xdc\x31\xf7\xf1\x85\xb9\x3f\x65\x07\x79\xf0\xa4\xb2\xf6\xc8\x2a\x63\x43\x7e\x59\x5b\x7f\x23\xaa\x40\x74\xb2\x61\x72\x31\xd4\x86\x1b\x18\x1c\x46\x0d\x98\x3c\xa0\xb2\x6e\x7c\x48\x01\x44\x4d\xc1\x33\xae\x9d\xa0\xfa\x86\x37\x4f\x80\x6e\x91\xe7\x97\x53\xea\x86\x91\x06\x20\xed\xd3\x73\xe7\x2e\x8c\x63\x35\x3f\xdb\x4d\x94\x58\xa0\x9e\x4d\x83\xcc\x7d\x0b\x1a\xdf\x85\x38\x00\x3c\x5f\x8b\x75\xbc\x32\x50\x88\x87\x6b\xff\xe6\xd6\x57\xb0\xf3\x65\xe8\x86\x01\x65\x1c\x7e\xab\xe0\xe8\xc9\x4f\xdf\xd1\x33\xd1\x45\x03\x81\xb2\x5c\x90\x74\x95\x79\xb8\x35\x2e\xca\x0a\xa8\xef\xca\x48\xfc\x98\x9a\x32\x02\xb9\x21\x1a\x31\x0c\x01\x3e\x26\xca\x59\x54\x0a\x01\x8d\x91\xcc\x46\xa6\xb1\x36\x14\xd3\x2c\xfa\xd5\x50\x1a\x81\xb6\x40\x19\x64\xaa\xb1\x73\x51\x2d\xbf\x60\x03\x0a\xdf\xe8\x92\x25\x54\x3c\x68\x7a\xd6\x6d\x81\x98\xb0\xc6\x7b\x88\x8d\x39\x84\x39\xf9\x1c\x9f\xda\xf4\xf4\x43\x18\xfb\xae\xa5\xa1\x49\x69\xa4\xc0\x8a\xf5\xe8\x86\xb6\xc1\x15\x7d\x8c\xf8\xb3\x79\x0f\x03\x92\xe8\x3d\x80\x17\x44\x15\x4f\xfd\x9e\xed\xf2\xaf\x16\xbd\x64\xab\x56\x7e\x18\xd7\x52\x4f\x03\xb2\xe1\x88\x7c\xe7\x20\xe0\x16\x82\xb6\x6a\x4f\x29\x3b\x31\xeb\x07\xcb\xfa\x64\xf7\x2e\xd0\xfc\x0d\x55\xce\xb3\x28\x1a\xe4\x13\x57\xc3\xca\x0f\xa4\xee\xf9\x0f\x5e\x1a\xee\x51\x1a\x5c\x9c\xb7\x2e\x24\x6c\xb5\x1d\xd0\x35\x7a\xef\x57\x76\xb5\x30\x46\x96\x1a\xc5\x3c\xa1\x7c\x24\x63\xa8\xd8\xc6\x89\x49\x02\x0b\xa6\xc9\xd1\x2b\x6d\x64\x1e\xff\x60\xce\x67\xf3\x51\xb4\x61\x05\x5b\x55\x70\x5f\xdb\xd0\x47\x69\x18\x62\x6d\x54\x19\xba\x0c\xf7\x44\xa5\x4f\xa6\x0a\x79\x67\x75\x33\x5f\xc9\xdc\x44\xc6\x9d\x17\x3f\x33\xdc\xd3\x78\x67\xa4\xf1\xce\x08\xf2\xac\x99\xbc\x31\x41\x86\x5b\xe2\x3a\x44\xb5\x91\xc8\x67\x03\x2e\xdb\xa7\x7f\x72\x71\xef\x98\xdb\xf8\x6c\x8e\x44\x4b\x92\x11\x85\x66\x2f\xa8\xac\x17\xdc\xf3\x2d\x28\x07\x0b\x3b\xbf\xd6\x0c\x43\x66\x18\x33\x6d\x0c\xad\xb1\xf0\xa7\x57\x0b\xee\xd5\x17\x76\xce\xfd\x64\xc4\x92\x75\x71\x2f\x7c\xf9\x15\xab\xad\xbc\xb0\x2c\x38\xe4\x0b\x6a\xe9\x05\x07\x7b\xc1\x88\xeb\x42\xbf\xb1\x49\x34\x39\x1e\xfa\x2e\xb8\x81\x5b\x30\x70\xb4\xe0\x72\x12\x24\xbe\xcc\x82\xa3\xbd\xf0\x4a\x79\x81\xa0\x0d\xdd\x82\x05\xf7\x62\x0b\x19\xf7\x06\x48\x6f\xee\x00\xbd\x62\xa8\x17\xb6\xae\x5e\x7b\xfc\x22\xd0\x8e\x5b\x3e\x7a\x8c\x78\x5b\x57\x92\xd4\xab\xde\x85\xc9\x5e\x45\x82\x08\x35\x87\xd1\xbe\x55\x03\xba\xf6\x34\xca\x66\x77\x13\x17\xbf\x0e\x63\x58\x69\xda\x8e\xdc\xe6\xdf\x89\xed\x42\x9d\x58\xa9\xbb\xe5\x66\xbf\x35\x83\xb8\x00\x49\x99\x9c\xfa\x9b\x00\xad\x1e\x06\x4a\xcb\x5a\xdc\xd5\xef\xf9\xef\x06\x05\xd9\xc2\x6d\x79\x2d\xa4\xe5\x65\xe5\x16\x27\xdf\x86\x2c\xed\x9e\xaf\x47\x4b\xd3\x06\xf7\xcb\xda\xa9\xe1\x43\x41\x62\xf3\x5a\x09\x60\xf7\x99\x75\xcd\xb8\x7f\xcb\x73\xf7\x56\x56\xd9\x7f\x59\xdf\x8e\x19\x4e\xd0\x62\xf8\xa6\x31\x7e\xda\xd0\x52\x6b\xb6\x32\xc1\x59\xcf\x36\x68\x8d\x65\xb0\xef\x8c\x80\x90\xd5\x8e\x91\x5a\x19\xfd\x4f\xa2\xab\x35\x5f\x4f\x8a\x76\x24\xa1\x84\x25\xa3\x32\x40\x4b\xa2\x2b\x50\xfc\xb2\x6f\xc9\x89\x5a\x72\xe1\x2e\xd5\x43\x92\x9a\x97\x76\x51\x37\x27\xd1\x2b\x29\x4b\x1e\x9d\x2c\xfd\xc1\xcc\xd2\x7b\x40\x4b\x4a\xef\xd2\x3c\x9a\x98\x1c\x97\xc8\xd2\xbb\x2a\x20\x9f\x7c\xa2\xb1\xe8\x25\xef\xa3\x83\x64\x54\x86\x4b\x91\x86\xa0\x61\xbf\xe9\x29\x61\x5f\xcb\xf9\xe5\xa0\x06\xfc\x0e\xa8\xe6\x48\xcd\xf9\x74\xc1\x4d\xc7\xd2\x7b\x6d\x4b\x7f\xcc\xb2\x34\xe9\xc9\x50\x5d\xd8\x88\x33\xf9\xd3\xbd\x20\x6a\xe4\x9b\x68\x89\x31\x3c\x9d\x25\x55\x06\xd0\x2d\xeb\xda\xc9\x58\xdc\xf4\xec\x33\x57\x4d\x3e\xe1\xf2\x11\xc8\x11\xa1\xa1\x25\x8e\x47\x58\xce\x99\x63\x76\x61\x2d\x17\x19\x9c\x27\xce\xcd\x15\x01\x7a\x23\xc1\xfe\x62\x14\xcc\xe4\x2e\x45\xcb\xbf\x03\xe5\x88\x6f\x00\x35\x28\xe4\x9b\x37\x94\x4b\x7f\x00\xb2\xf4\x9b\x84\x25\x2d\xe4\x92\xbe\xe4\xd2\xdb\x4a\x90\x7b\x1b\x4a\xb7\x8b\x07\xa9\x88\xf4\xe8\xe0\x1b\x6d\xe1\xd2\x6c\x61\x2c\x9e\xd3\xef\x2e\x6d\x80\xfc\xcf\x46\xd3\xec\x1c\x4f\x20\x96\x66\xe0\xd8\x13\x0d\x04\x69\x17\xbe\xd9\x66\x5a\x95\xe8\x37\x1a\xbb\x57\x1a\x3b\x1c\x86\x4d\x90\x16\x6f\x61\xac\x7e\xbb\x85\x81\x87\xb7\x7c\x52\x19\x92\x83\xe7\x9e\x9e\x9e\x59\x89\xfa\x9d\xf1\x8a\xb7\x84\x57\x74\x87\x57\x74\x87\x57\x6c\xe7\x8a\xdf\x1a\xac\xec\x1a\xf1\x88\x44\xc5\x63\x85\xeb\x8e\x44\xf1\x4c\x18\x7c\xc9\x76\xe7\x38\xe9\x05\xd2\x23\xb9\x15\x55\xc0\x8a\xfa\x74\x05\x67\x1a\xa8\x64\x8b\x11\x91\x8e\xc3\x30\x67\x2d\x0d\xd3\x16\xbe\xf2\x5f\xae\xa9\x83\xe7\xcc\xd9\x32\x5c\x08\xb2\xf1\x39\x5f\x7d\x5b\x56\xb2\x74\x86\xe4\x6b\xb6\x77\xfd\x6b\xb2\x8d\xcd\x8e\x17\x9b\xe3\x55\xab\x57\x59\x68\xba\x37\x5f\xd1\x36\xaf\xa8\xb0\xa3\x31\x58\xe9\xc5\x59\x11\xc8\x15\xd5\xf4\xab\x0f\x59\xaf\x64\x55\xb1\x72\x15\xad\x16\xd9\x0a\x86\x6b\xd7\xfe\x02\xe0\xda\x7f\x0c\xb1\xf6\x47\xde\x20\x35\x91\xba\x10\x6b\xbf\xe5\x5c\x53\x50\xd6\x54\x60\x6b\xdc\xf9\x04\xd2\x30\xcf\x9a\x97\x71\x40\x4a\x2c\xf4\xb5\xac\x72\x68\x4e\x2d\xfb\x85\x6b\x6b\x0d\x55\x26\xeb\xf1\x0a\x8e\xea\x2a\x90\x0d\x8f\xfb\x84\x98\x29\x02\xd1\xae\xe9\x95\x98\x35\x75\xd8\x5a\x8f\x99\x45\x48\xd7\xd4\x5c\x40\x5a\xcb\xd5\xb2\x86\xb1\xbf\xb1\x12\x6c\x22\xd6\xf2\xe9\xcb\x1f\x40\x37\xd6\xd4\x80\xde\x89\x4e\x40\x13\xbe\x81\x2b\x3e\xef\x24\x7a\x7d\x7e\x23\xeb\x3a\x05\x1a\xf0\xe7\x15\x36\x3c\xa7\xdc\x70\x99\x6e\xb8\xfc\x36\x92\x6f\x09\xa4\x1b\xd0\x8d\x7d\xa6\x79\x25\xd1\x2b\x4c\x1b\xce\xc1\x86\x47\xc6\xdc\x01\x20\x55\x9d\xd7\x8d\xc5\x53\x77\x20\x0b\xef\x23\x09\x77\xa2\xb6\xe1\x4d\x00\xa0\x8c\x68\xca\x56\xc6\xd0\xd4\xc6\x7f\x00\xb2\x71\x1f\x80\xe4\xe4\xb5\xcf\x39\xf3\x05\x2e\x59\xe0\x9a\x79\xce\x2c\x4a\x43\x47\x1b\x6e\xf2\x36\x32\x3f\x18\x5d\xf3\x50\x2d\x77\xf2\xcb\xc7\x46\x1b\x9d\x17\xcb\x5c\x58\x45\xb6\xeb\xda\xd0\xa6\x6c\x7c\x30\x78\x63\x51\xa7\xf8\xe4\xc9\x5a\x96\xc4\x7b\x7f\x1b\xef\xa1\x6e\x68\x4c\x36\x7e\x63\xb5\xd1\x1d\x94\x0e\x84\xd8\x0f\xa2\x8b\x6b\x99\x08\xdc\xc6\xef\x90\x36\x3e\x22\xfb\x1d\x47\xe9\xd0\xed\xdf\xa9\x9f\xd5\xd2\xf3\x56\xc4\x77\x46\xa2\xbe\x8b\xd6\x53\xaf\xef\x3b\x0f\x98\xbe\x63\x45\x60\x8e\xbf\xe3\x47\x28\x80\x6e\xac\x44\x8d\xab\x69\xbc\x60\xcb\xe3\xb8\x2d\x97\xd5\x96\x71\x97\x2d\x2f\xff\x6e\xa5\xe6\x59\xcf\xae\x55\xeb\xb0\x6c\x79\x53\x05\xf7\xb6\xbe\x1a\x92\xd6\x6c\xe9\x35\x6d\xed\xc0\xac\x06\x99\x33\x4c\xb0\x65\xf0\x77\xcb\x0b\xb5\x5b\x93\xb0\x98\xac\xdf\x31\x6d\x19\xc4\x80\x77\x86\xa4\x13\x37\xc3\x5b\x2a\x8a\x2d\x5d\xaa\xad\x88\xdb\x48\xbc\xa3\x33\xc6\x63\xcb\xaf\x55\xb7\xfa\x91\xb8\x28\xa5\xad\xe8\x8e\x6b\x4f\x7f\x4b\x40\xdb\x12\x10\xbb\x9b\xe8\xcf\xa0\x6c\xa9\x3b\xb6\xf2\xfa\x03\x10\x9c\x9b\x11\xc9\xc8\x0a\x4e\xe2\x85\xef\xad\x85\xc8\x23\xb9\x25\x8a\xe5\xc4\xf7\xfc\x6c\xc9\xc5\x14\xa2\x7f\x88\xf4\x76\xe9\xd6\x6f\xc8\xb7\xce\x1f\x49\xc9\x55\xcb\xef\xb8\x39\xde\x49\x33\xff\x0b\xdb\xb6\xe3\x4d\xa6\x9d\x7d\x9e\x72\x05\x29\x64\xc4\x47\x24\xb5\x21\x99\xc6\x1d\xcf\x8e\x77\x8c\xe1\x0a\x12\x41\xd8\x59\x10\x28\x05\x59\xf0\xa2\xce\x8e\xa7\x5d\x3b\x5a\xd5\x1d\x6e\x38\x00\x7d\xb0\xd4\x4f\xa2\xf8\x3b\x2b\x3b\x5e\xa5\xdb\xd9\xaf\x01\x7c\x27\xd9\xc2\x28\xed\xfc\x3d\xf5\x9d\x7d\xca\x90\x81\x68\x88\x68\x47\x4d\xf1\x46\x57\x6d\xcf\x43\x8f\x37\xbd\x05\x23\x59\xdf\xb8\xeb\x79\xe3\xfd\x97\xbd\x8f\x0b\x83\xdc\x13\x55\x3e\xb9\x66\xd9\xd1\x22\xef\xbd\x45\x06\x59\xb0\xf8\x37\xf7\x82\xc5\x53\xf6\x74\x12\xf6\x74\xef\xf6\xb4\x2f\xf1\xd2\xc8\x9e\xd7\xc4\xf6\x74\xe2\x40\x62\x53\xf5\xc0\x69\x8f\xcb\x51\x86\xec\x69\x85\x8e\xbc\xd1\xa9\x90\x34\x2b\x52\x67\xfc\x87\x9e\xaa\xd8\x4b\x73\xa2\x86\x28\x06\x29\xf6\xfe\x42\xda\xde\x9f\x84\xee\xb9\x39\xda\x9b\x9b\x37\x22\xc9\xf9\xf6\x8b\x6f\x7e\xb4\x51\x7b\x6f\xa3\xf6\x5e\x83\xec\x4d\x69\xc4\x02\xa2\x47\xb9\x57\x1b\xe5\x72\xfe\xc3\x15\xb3\xf7\x3f\x4f\xb2\xe7\x1d\x7a\xa0\x77\x20\x31\xec\x22\xe5\x7b\x9c\x48\x63\xe9\xee\xa5\xc3\x13\xeb\x4f\x50\x22\x63\x2b\xc7\xf6\x10\x7b\x91\xde\x01\x11\xde\x33\xc5\xb2\xc7\x69\x4a\xd7\xff\xd3\x1a\x67\x3f\xd8\xb1\xa7\xad\x03\x1a\x7a\xc2\x91\x55\x57\x21\x27\x89\xa7\x72\x6f\xd0\x3a\x36\xe1\x89\xba\x6f\x7b\x6f\x5d\xf7\x7e\x2f\x05\xa2\x8a\xfa\x07\x6d\x21\x50\xcb\x0c\x4b\xdf\x90\x15\x3b\x14\x43\x89\x20\x3f\x88\x4e\xbe\xb1\xff\xe7\xc9\x27\x0f\x0e\xf7\xde\x6a\xee\x3b\x77\x63\x0d\x44\x35\xe9\x81\xf6\xeb\xc0\xd3\x9e\x03\x17\xca\x81\x63\x71\xe0\xf2\x38\x70\x79\x1c\xa8\x9c\x0f\xdc\xf7\x1c\x78\x4a\x77\x30\xe7\x37\x23\xd1\x82\x4a\x66\x2d\x65\xad\x9c\x58\xb0\xca\xe1\xbb\xfb\x6c\x31\xd6\xa0\x6b\xe9\x20\xeb\x66\x6c\x48\x64\xe8\x20\x8b\xe6\x0f\xd6\xf5\xcc\x12\x1b\x36\xb5\x85\x9b\x70\x30\xe9\xaf\x48\x2a\x66\x40\xad\x07\x56\xf9\x02\xc9\x3d\xf8\x2d\xd2\x3f\xf6\x03\x3d\x23\x92\x05\xab\x6b\xe9\x9b\x1c\x38\xaf\x07\x99\xd4\x7b\x88\xcd\xc1\xbc\xee\x96\xef\xac\x59\xdd\x96\x8d\xdd\x33\xed\x9d\xc3\x16\x83\x37\x07\xee\x99\x0e\xf6\x6b\x2d\x23\x12\x7d\xef\x6a\xb3\x60\x32\x00\xf4\x68\xdd\x0d\x2b\x67\x4a\x84\x5e\x5a\xdb\xdf\x2d\x8e\x89\xe1\xd4\x1f\x13\x59\x93\xa0\x41\x76\xbd\xe1\xe0\xad\xe5\x81\xdf\x73\x09\x72\x1b\x99\x03\x8d\xe8\x41\x96\x68\x44\x29\x51\x66\x28\x89\x95\x17\x4e\x06\xf5\x44\xb4\x25\x29\xac\xbf\xee\x46\xc2\xc1\xbb\xa3\xff\x70\xd5\x21\xf9\x87\x49\x98\x8b\xc7\x1f\x19\x4a\x3f\xea\xa1\xa7\xbc\x70\xf4\xdf\x74\x1c\xfd\xed\xa7\xff\xd9\xd7\x87\x19\x0b\x48\xb9\x81\x03\x39\x02\xe9\x3a\x3a\x52\xc1\x1c\x69\x70\x8e\xf4\x66\x8e\xb2\x7a\x1e\xd0\xaf\xa3\xfe\x52\x97\x05\xa2\x8e\x54\xd5\x47\xae\x9c\xa3\x2c\x9b\x2f\x40\x8f\x18\xde\x23\xae\x17\x01\xcd\x98\x6f\x06\x37\xe9\x48\x5f\xef\xa4\x47\x54\x42\x8e\x34\x36\x47\x1f\x7f\x3b\xf2\x84\xfe\xc8\x5f\xb0\x3a\x9a\xcd\x69\x49\x32\xa2\x82\x65\xbf\xf2\xbd\x15\xbb\xbe\x62\x15\x3b\x3e\xdd\xb3\x85\x07\x5f\xed\x4f\x66\xbd\x10\x5d\x0d\x99\x01\x38\xf2\x7c\xf4\x48\x91\x3d\x8a\x38\x16\x86\xb4\xea\x84\x63\x0d\x1f\x53\x9a\x7c\xd2\x53\x2e\x6d\xb2\x79\x92\xc7\xce\x9d\xaa\x9f\xec\xe0\x28\xe3\x13\x15\x28\x3c\x51\xe3\x86\x53\x06\x15\x9e\x9f\x3e\xca\xfb\xd3\x76\xb6\x03\x92\x8c\xe8\xce\xe7\x29\x7c\x51\x25\x91\xda\x93\x9f\xfe\xdc\x1b\x64\x4e\xa4\xc7\x9f\x3f\x3b\xf7\xab\x0b\x3f\xfd\x39\xf6\xcf\xce\x7e\x34\xe1\xa7\xf8\xa5\x13\x20\xdd\x68\x7c\xe8\x06\x5c\xe4\xec\x43\x37\xc5\xba\xf2\x91\xd3\xf6\x3f\x3f\xbd\x27\xfe\xf1\x9b\x59\xfc\xb0\x10\x63\xc5\x9c\xa5\xf5\xdb\xed\x05\x3f\x3a\xfb\x22\xeb\xcc\x21\x3b\xd3\x17\x84\xe1\xd2\xcd\xc9\xd9\x3e\xa0\xca\x49\x74\xf4\xcf\xfe\xa3\xa5\xb3\x7e\xa7\x64\x45\xc5\xef\x94\xce\x5c\x79\x67\xce\xc8\x99\x1d\x38\xfb\xd6\x7f\x72\x19\x9e\xb9\xe6\xce\xd4\x32\x67\x7a\x4d\x67\xce\xd4\x99\xee\xfb\x99\x87\xce\x67\x4a\xce\x99\x7a\xe8\xdc\xb9\xaf\x26\xcf\x5c\x94\x67\x5c\xff\x21\xd2\x3e\xea\x75\xec\x33\x4d\xd6\xbf\xf8\x59\x39\xdf\xa8\x5f\x3e\x37\x00\x2f\x89\x1a\xb6\x73\xc5\xfd\xce\x99\xf1\x9b\x33\x9d\x9f\x33\x9d\x76\xa0\x29\x11\x7b\xe0\xae\x43\x21\x6c\xb4\x81\x46\x8c\xdf\xfb\x00\xa9\x27\x7b\xe1\x71\xcd\x85\xb1\xc2\x0b\xbe\x56\x02\xd2\xe3\x8b\x8b\x18\xd8\x7e\x4f\xbf\x15\xb2\xf2\xbf\xf2\x0d\xb5\x89\x17\x44\x00\x81\xd6\xf0\xb4\x2f\xb2\x4b\x9f\x02\x6d\xf9\xae\x4a\xc2\x85\x91\xc1\x8b\x98\x8e\x3b\xa0\x21\x9f\x66\xfc\xac\xe0\xc2\x1f\x7e\x8c\x86\x33\xfe\xe0\xd9\x05\xba\x81\x28\xb3\x96\xbb\x4b\x36\x17\x8b\x7e\x87\x17\xae\xbc\x87\x71\xa5\xe1\xb8\x52\xfa\xae\xd4\x33\x57\x04\xa0\x0c\xc9\x54\x5d\x29\x5c\x57\x5a\xb2\xab\xfd\xe2\xc3\x00\xa4\xf6\x28\x96\x3a\x23\x7a\x61\x3b\x5a\x3a\x66\x57\x7f\x22\x77\xa5\x23\x72\xf5\x91\xd5\xab\x74\x61\x45\x84\x06\x96\xcc\x29\x5b\x75\xcb\xa9\x7a\xfb\xea\x77\xba\x57\xc6\xa3\xae\xdc\xdf\xc7\xa3\x8e\x2b\x2f\xdb\x5f\x7d\x70\xff\xca\xaf\x94\xae\x8c\x37\x5d\xdd\xe0\x4a\xfc\x40\x92\x03\xc2\x85\x23\xa0\x50\x93\x6e\x07\x06\x3d\xb7\x31\x50\x34\x24\xaa\x7a\xf6\x9d\x19\xbe\x94\x8c\x77\xf0\x03\xba\x63\x41\xa5\xed\x8d\x71\x2f\x3f\xfe\x7a\xaa\xf2\x37\xa0\x47\xfb\xcd\x46\xbd\xbe\xaf\x0d\xaa\x59\x79\x2d\x66\x47\xd1\xc9\x50\x10\xdf\x80\x66\xac\x62\xc6\x52\xb8\x8d\x0a\x84\x3f\x6e\x14\xc8\xce\x92\xc3\x30\x5e\x81\x86\x4c\xbb\xb1\x2f\xb6\x71\xdb\x4c\x55\x4b\x20\xd0\x60\x7a\x72\x9d\x78\x92\x7a\x32\xf4\x04\x4e\x95\xdd\x22\xb1\x19\x52\x0e\x39\x50\x52\x11\x41\x0b\x2b\x41\xf0\x04\x44\x5d\x3b\x25\x39\x8b\xba\x75\xbf\x60\x17\xf8\x83\xc8\x8e\xdc\x7d\x96\xd5\x10\xd0\x93\xbb\x78\x1d\xf8\x33\xcb\xbd\x58\x9a\xba\xa8\x7a\x87\x13\x97\x56\x95\xc0\x46\x2b\x81\xf7\xa1\x3f\x2c\xa9\xdf\xe3\xa0\xee\x84\x1f\xc5\xda\xa2\x0b\x49\x43\x3e\x44\x2c\x4b\x11\xce\xbc\x40\x62\xf4\x57\x7f\x12\x2a\xe3\xdb\xaf\xf6\xb6\xee\x3d\x13\xfc\xb0\x6b\x4e\x84\x13\xb0\x64\x60\x97\x1c\x92\x01\x45\x31\x8e\xf1\xc0\xb6\x41\x4a\x6a\x8f\xe8\x63\x46\x47\x3a\x19\x50\xaa\xe2\x8c\xf0\xfc\x37\x19\xd8\x6f\x05\x24\x03\xbb\x85\xa3\xe8\x87\x28\xbb\x64\x60\x3f\xdb\x9b\x0c\x4c\x19\x24\xb8\x64\x56\xb8\x66\xe8\x31\x78\x82\x0b\x64\x37\x5c\x77\xa9\xed\x0b\x14\xbd\x3b\x67\x20\x67\xea\x87\x21\xdd\x7c\x24\xa9\x59\xd4\x24\x75\xb7\xab\x12\xba\xd4\x09\x4d\x7c\x82\xef\x9d\xc7\x40\x0c\xe2\x05\xf2\x0d\x8d\x4d\xdd\x01\x55\x82\x26\x20\x83\x6a\x9c\x84\xbf\x49\xa8\x73\x37\x20\x8a\x69\x3c\x0c\x53\xfe\x48\x54\x13\xf1\x06\x4d\xbc\xb9\x19\x7f\x78\x34\x19\x9a\xe3\x90\xd8\x4f\x03\x5a\x45\xb9\xed\x2c\x02\x99\x32\xf9\xde\x37\xab\xe4\xab\x95\x6f\xc9\xdc\xa3\x1c\xe8\x85\xed\x5e\xb2\xac\x57\x9c\x9f\x31\x0f\xfc\xbd\x64\x68\x76\x3b\xa0\xd4\xca\x4a\x32\x0b\x58\x29\xd1\x59\x46\xe4\x2f\x05\xca\x2d\xec\xa2\xe4\x9e\x08\xd6\x5b\xc9\x73\x4f\x57\x6b\xc2\xcf\x69\xf4\x0b\x18\x45\xaa\xc7\x6f\x28\x90\x37\xec\xc1\x8d\x85\xe2\xe4\xaa\x2c\x2a\x1b\x51\xb2\x46\xee\xf7\x90\x94\xcc\x98\x3b\xb7\x1f\x88\x51\xa2\xc9\x53\xa6\xc1\x37\x0b\x68\xc6\xe2\xe6\x4c\x9b\xb3\xd4\x25\xdf\xd8\x1a\xb2\x81\x1a\xd9\xc1\xc9\xc4\x72\x9b\xee\x1d\xf1\xc7\x76\x48\xc6\x7c\xfb\x2f\xfd\x39\x16\xb1\x35\xe0\x6c\x4c\x32\x62\x51\x13\xeb\xaf\x29\x10\x1c\xca\x84\x61\x1e\xbb\xdb\x1f\xc9\xd8\xeb\x5f\x90\x47\x22\x55\x76\x63\xfb\x60\xa5\x10\x82\x0b\x44\xfa\x3b\x5d\xc9\xa4\x8b\x5f\x66\x28\xf9\x42\xa4\x83\x03\x82\x1f\x71\x8b\xd9\xb0\x81\x55\xf2\x49\x92\x41\x35\x4e\xf4\x47\x49\xb4\x00\xbd\x9e\x10\xc9\xd4\x93\xc2\xaa\x8f\xbb\x01\x25\x51\xdc\x27\xde\xee\x4f\x34\x42\x25\x24\xe3\x62\xcd\xec\xfa\xbb\x22\x7c\x53\xab\x64\xce\xdc\xb9\xf8\x6c\x2a\xe7\x2d\xd0\xa3\xcc\xd8\x4d\x4f\x25\xde\x54\x4e\x46\x61\xcd\x28\x0d\x99\x6d\x28\x13\xfe\x36\x52\x82\x5f\x37\xfa\x42\xf4\x83\xe8\xc4\xac\xd8\xcf\xe0\xc7\x7f\x45\x6f\xe0\x27\x87\xfa\x44\x88\xb2\x2b\xd1\xc5\x9f\x9b\xa3\x9d\xc8\x0f\xb3\xc8\x4f\x6a\x83\xd4\xee\x57\x88\x55\xeb\xa6\xbd\xf8\x31\xfa\xff\x07\x00\x00\xff\xff\xaa\x0a\xcc\xb8\xdf\x5e\x00\x00") +var _keysWordsWordlistJapaneseTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x5c\xff\x72\xe2\xb8\xd2\xfd\x9f\xa7\x5e\xbc\x5c\x2f\x01\x3c\x0e\x71\x1c\xc7\x61\x58\x87\x8a\x2f\x43\x60\x80\x0c\x59\xb8\x93\x8f\x2c\x3c\x8c\x5f\xe4\x2b\xf5\xe9\x3e\xea\x99\xaa\x54\xea\x1c\x59\xd6\xcf\x56\x77\xab\x25\xd3\xf5\x93\xae\x3f\xe8\xfa\x45\xd7\xcf\xbb\x7e\xd5\x25\x45\xcf\x92\xca\xae\xdf\x92\x3c\x03\x8d\xba\xfe\xdf\x5d\x72\x03\x32\xee\xfa\x8b\x2e\xf9\x93\xef\x64\x5d\x32\x06\x9a\x76\xfd\x49\xd7\x6f\x8c\x58\x72\x11\x92\x93\x09\x79\xd9\xf5\x07\x44\x07\xa0\x4a\xfe\xaf\x40\x1e\xbb\x24\xef\xfa\x29\xc8\x53\xa8\xd1\x5e\x7d\xea\xfa\x19\xd0\xbc\xeb\x9f\x80\x9a\xae\x3f\x64\x86\x26\xfc\x25\x7d\xc7\x93\x51\xd7\xbf\x74\xfd\x21\xb9\x3e\x69\xd9\x8a\x56\xfa\xa4\xd5\xbd\xc8\x70\xfc\xa7\xeb\xe7\x7c\x78\xe9\x92\x91\x11\x57\xf4\xb2\xeb\xaf\x89\xf6\x92\x4d\x9f\x1c\x88\x4e\x1c\xb5\x13\xd3\x8e\x7e\x2c\x2e\x6c\xc5\xa5\xeb\xbf\x1a\x4a\x06\xd2\xa4\x9a\x5c\xeb\xbf\x76\x49\xd2\xf5\x77\x42\x42\x4b\x46\x5d\x1f\xe5\x84\x17\x58\x7f\x92\x76\xc9\x1f\x40\x37\x32\x8b\xb7\x5d\xff\x42\x5e\x11\xd5\x5d\xff\x91\xc4\x8f\x5a\x72\x23\x65\x44\x92\x5b\x5b\x42\x8d\x93\xae\xbf\xb2\xe1\x0a\x4f\x66\xcc\x99\x87\xa1\x30\x52\x58\xcf\x12\x99\x7f\x47\x0a\xa2\xaf\x26\x44\x81\x2c\x7d\x9e\xb5\x27\x3a\x00\x03\x88\x24\xda\x32\x08\x52\x29\x6f\x0f\x58\x3c\x50\x0e\x94\x89\xd8\x0e\x48\xd6\x2c\x24\xe3\x28\x0e\x28\xbd\x03\x59\x08\x8f\x44\x27\x96\x3d\xed\xfa\x6f\x98\x69\x21\x96\x5c\x60\x08\x74\x0d\x11\xb5\x3d\x5b\x44\x17\x11\xea\x81\x71\x7b\xaf\x82\x04\x0f\x44\xca\xff\xc3\x42\x1e\xbb\xe4\x2f\x4f\x72\x36\xeb\xa9\xeb\x5f\x0d\x25\x13\xa0\x19\x0b\x9e\x05\xe1\xef\xbf\x93\x8c\xfd\x13\xad\xe8\x2b\x2b\x9f\x77\xfd\xb4\x4b\x32\x56\x34\x97\x01\x8b\xcd\x7c\xf6\x48\x3b\xd5\x48\xc5\x37\x24\x57\x43\x41\x16\x12\x90\x85\x8c\x75\x4a\xf2\x48\xf4\x4a\xf4\x46\x74\x32\x94\x8c\xfc\x10\xb4\x10\xe6\x41\x5c\x83\xd6\xec\x17\xdf\xe3\x17\x74\x83\xa4\xf1\xd9\x16\x44\x4b\xff\xc2\xbf\x7c\x61\xd9\xf5\x1f\x0c\xd9\x7b\xaf\x7c\xba\x82\x70\x0e\x28\x7f\x40\xda\xac\x6d\x97\xfc\x41\x21\xda\xb1\xb2\x1d\xa7\x6a\xcf\xf9\x7f\x73\x69\x56\xcd\x3b\x27\xe4\xc0\xb4\x23\x87\xf9\x27\xd3\xce\x6c\xce\xd5\xd2\x82\xbc\xa6\x50\x8f\x20\x8d\x89\x42\x92\x58\x8b\x12\x91\x7e\xad\x36\x10\xac\x92\x64\x28\xfa\xb3\x20\x41\x7d\xa2\x19\x88\x6a\x96\x3d\x12\x6d\xb1\x30\x12\x85\x32\xe1\x1a\x0b\xda\x8b\xeb\x27\x89\x55\x66\xa2\x87\x8b\xae\xff\x8f\x0d\x43\x50\x08\x03\xa2\x94\x28\xb6\x27\x37\xb9\x08\x02\x9f\xb2\xa8\xa2\xeb\xdf\xd9\xca\xef\x33\xa9\x64\xb9\x85\x08\x48\x6c\x5b\x21\x3d\x0b\x24\x95\xf5\x90\x19\x92\x02\x53\x91\xce\x07\x20\xed\x46\x2a\x4b\xe5\x44\xf4\xc1\xac\x59\x97\xe4\x40\xb9\xe9\xcf\x35\xf9\x04\xe3\x9e\x8a\x5a\x68\xa4\x7d\x39\xdf\x9c\x8a\x0c\x4f\x49\x56\xee\x49\x18\xb1\x96\x44\x93\xef\xa9\xe5\x41\xb4\xde\x02\xc3\x93\x4a\x8f\xbf\x00\x55\x22\x88\xa9\x91\x30\xd8\x13\xac\xc5\x54\xa6\x6f\x40\xf4\x85\xe8\x96\xb3\x2c\xdc\xf4\x7b\x2a\xab\x49\x1b\xb3\xa0\x16\x27\x9f\x70\x00\x16\x1c\xc9\x05\x17\x6a\x2a\x0b\x6a\x0c\xa9\x4b\xa5\xc7\x39\x55\x48\xaa\x2b\xd2\x8d\x7c\x4b\xf4\xca\x6e\xad\xd9\xca\x35\x74\x05\xd0\x13\x47\x60\xcd\x97\xb6\x44\x3b\xd6\x7f\xea\xfa\x77\x44\xf7\x30\xed\xa9\xcc\xc5\xc4\x72\xc7\xbe\xca\xd2\x01\x12\x1b\x69\x64\x68\x95\x85\x31\x9a\x88\xd4\xd4\xe4\xba\x04\x40\xd6\xd6\x37\x51\x78\x56\x77\x20\x99\x49\x43\x32\xa6\x57\x93\xca\x4a\xa9\x1c\x49\x52\x1b\x46\xd7\xbe\x0c\x9a\x26\x95\xb1\xcf\x88\x4a\xa0\x82\xf6\x05\x64\x61\x43\x07\x3b\xe9\x88\xea\xae\xa1\xc8\xe9\x10\x4f\x40\x26\x44\x19\x97\x0a\xf8\x3d\x91\x6a\x55\x90\x93\x7b\xdb\x96\x13\x48\x0e\x34\xc2\xa4\x0f\x65\xbc\x22\xd2\xa7\x99\x4c\xbc\x16\x17\xdd\x82\xa1\x88\xeb\x9f\xcc\x56\x77\xfd\x25\x50\x2b\xae\x85\x56\xb9\xeb\xfa\xb7\x40\x67\x9d\x4c\x19\x15\xe1\x96\x87\x69\x61\x4e\x1f\x89\x76\x40\x37\x56\x79\x40\x27\x20\xb5\x50\x50\x4b\x1c\x9d\x40\xc6\xcc\x5d\x40\x18\x87\xaa\x75\xac\x8a\xc2\xfc\xc0\x94\xfc\x2b\x56\x0d\xc8\xdc\x7a\xa4\xf3\xf3\x97\xcf\xb9\x42\xce\x91\x8c\xeb\x98\x4b\x7e\x64\x5e\x42\x4d\xa2\x82\x32\x32\x0b\x98\x83\xa4\x6c\xee\xc8\x14\xc1\x85\xe4\x91\x68\xc6\x7a\x52\x8e\x3e\xc8\xd1\x17\xf5\xe1\x9e\xd8\xcc\x8e\xb8\x48\x47\x74\x94\x46\x34\xe3\x40\xaf\x9c\x73\xe1\x09\xf3\x84\x42\xe6\x20\x63\x0c\x34\xc9\x13\xd0\x04\x2e\xa8\xa4\x05\x15\xa9\x19\xbe\x50\x8d\x8d\xe8\x7a\x8d\x44\x5c\x62\x0f\x73\xef\x0d\x09\x57\xaf\x73\x4d\xce\xd7\x6c\x45\x8d\xfc\xb0\x16\xbe\x92\x82\x19\x4a\xdf\xe3\x92\xeb\x5a\x88\xe9\x8b\x11\x66\x04\xeb\x1a\x24\xbe\xf3\x08\x49\x01\x2a\x39\x3d\x22\xde\xf6\xc2\x5c\xc4\x2f\x27\x89\x8d\x6d\x68\x7b\x40\x34\xcf\x33\x9c\x7d\x90\x85\x97\x81\x17\x18\xe5\x91\xac\x14\x1d\xbf\x6f\x10\x27\x90\x95\xd4\xad\x2b\x00\x7c\xed\x25\xea\x95\xaf\xbd\x8a\xc2\x19\x73\x84\xde\x7c\xfb\x2f\xb0\xf5\x42\x92\xbe\xd4\xb1\xb2\xe1\x4b\xb0\x0d\xfc\x46\x12\x93\x29\x6e\x81\x84\x0d\x21\xc8\xc0\x44\x32\x19\x88\xe6\x7b\xef\x99\xc0\x7c\x5a\xf5\xb2\xec\xb1\xb7\x1c\x49\xc3\x34\xb9\xa0\x3a\x01\x99\xb2\x06\x2c\xc6\x3f\x49\x66\xd6\x78\x29\xc7\x93\x68\xa8\x46\xa6\x1f\xb5\x98\x31\x76\x70\x40\xaa\x1f\x27\xd0\x8f\x44\xea\xde\x4f\xbc\x87\x3f\xf6\xbb\xe2\xb1\x2e\x5a\x69\x0b\x48\xed\x1d\xab\xb1\x77\xb8\x41\xfe\x86\xf1\x23\x6f\x7d\xb1\x4b\x9f\x73\xe5\x9f\xe8\x02\x9e\xa8\x73\x28\x8d\x1c\x7b\xff\x70\xec\xf5\xf4\xc4\xfb\x74\x63\x2a\xed\x31\xc5\x77\xcc\xa5\x3c\xfe\x2d\x79\xc2\x96\x4f\xb0\x39\x1c\xd3\xb5\x18\xcb\x62\xbc\x27\x5a\x31\xeb\x03\x5e\x9f\xa0\x7b\x48\x6b\x58\x7b\x03\xf3\x39\xf1\x8a\x71\x22\x02\x9d\x71\x7a\xc0\x0b\x4f\x4a\x8e\xfe\x8b\xf7\xef\xc6\x22\xd6\x0f\x62\x1f\xb5\x7d\x3b\xbe\xb6\x67\x93\x4e\x58\x45\x63\x3f\x40\x67\xb6\xfe\xc2\xb4\x8b\x48\x22\x46\x3d\x2c\xfb\x09\x37\x92\x63\x11\x58\xf4\x41\x06\x16\xd2\x3b\x76\x03\x9b\x8c\x89\x32\x2b\x31\xb4\x2b\x37\x24\x1b\xa5\x09\x4c\x0c\xd2\x0a\x27\x81\xce\xb0\x8f\xbd\x54\x8f\xcd\xa4\xc4\x27\x0d\xdb\x54\xd8\x68\x06\xa4\x1b\x8b\x0c\x01\x1a\xa2\x16\x28\x78\xe1\x3d\xd1\xb2\x03\xbc\x9e\x49\x2f\x06\x86\x2c\x6d\xc8\x52\x54\xdf\x03\xe5\x44\x0b\x43\xf6\xc6\x98\xa5\x8c\x99\xef\x97\x2e\x64\xf2\xb7\x04\xca\xa5\xa1\x23\x23\x61\xfc\xee\x40\xa6\xba\x7e\xad\xb4\x82\xf5\x17\xbe\x59\x05\x2b\x29\x99\xb5\xf4\x69\x17\x43\xa1\xec\x2f\xe8\xf3\xa3\x97\xe7\x2f\xdc\x6a\xe3\x49\xe3\x17\x38\x92\x36\x7e\xa3\xf8\xc5\x36\xe4\xad\xef\x52\xcd\xe6\xc5\x26\xeb\xc6\x3a\xa3\xf9\xcd\x38\x75\x99\xac\x87\xdc\x90\x0d\x5e\xe3\xbb\x16\x97\x44\x26\x95\x0d\xd9\xa4\x17\xec\x89\xf9\xa4\x65\x45\x6d\xd7\xdf\x02\x2d\xd9\x8c\x57\x16\xf2\xca\x2a\xd7\x7c\xba\x86\x82\x03\xd2\x66\x7c\x17\x6f\xb9\x02\xd9\xb2\x75\x3b\x16\xb4\x93\x31\x6b\x40\xf6\x2c\xf5\x9d\x46\x25\xe3\xde\x35\xa3\x86\xca\xe8\x39\x66\xb2\xb2\xb4\xac\x33\xd3\x2e\xec\xfa\xd5\xc6\x2b\xf9\x43\xe3\x7a\xb1\x60\xb3\xc0\x08\xce\x3c\x8b\x25\xaa\xc8\x17\x3d\x1f\xb6\xc9\xe8\x50\x66\x62\x70\x30\xdf\xa2\x59\x64\x56\xf5\xc9\xd0\x1a\x23\x03\xee\xa3\x0d\x19\x97\x74\x46\x7b\x9d\x49\x06\xb4\xd9\x36\xbb\x40\xda\xe6\x8c\x15\x65\xcc\x97\xb3\xdd\x5f\x10\xf1\xc2\x02\xcc\xcc\xc7\xd4\x98\x12\x78\xf0\x6a\x8c\x38\xfd\x72\xcb\xb5\x9c\x23\xcc\x03\x94\x72\x9f\x0c\x92\x11\xdd\xfa\x64\x5d\x40\xb7\xe6\x0f\x0e\xf8\x64\xee\x9f\x34\xd0\x4c\xb9\x77\x0e\x41\x3e\x81\x62\x5d\x71\xbb\x90\x63\x1b\x8e\x42\x0a\xa6\x95\xac\xa5\x64\xb3\x4a\x46\xc9\x84\xc8\x90\xe4\xe6\xfa\x5f\x49\x62\xc1\xb5\x88\x5b\x66\x24\x8c\xbd\x8e\x87\xec\x1d\x44\x5f\xe4\xb4\xf4\xb7\xb6\x80\x97\x7c\xe7\xd9\xd7\xd3\x04\x29\x35\x67\x30\x17\x47\xaa\x60\xbd\x0b\xdf\xd0\x96\x32\x7e\x2b\x2b\xae\xc6\x8a\x93\x27\x61\x8a\x6f\x7b\x66\xea\x52\x9a\xe7\x9c\x6b\x2c\x97\xbd\xa9\xa6\x6d\xf1\x1f\x64\xc7\x9e\x1d\x89\xae\x7e\x73\x0d\xde\x30\x44\x1a\x45\x27\x87\x10\x63\x80\x7a\xa6\x30\x6b\xa2\x0f\x66\x1b\x43\xf1\xe5\xae\xab\x66\x87\x72\xd8\x47\x4c\xcd\xad\xca\x9f\x8e\x5d\x8c\x97\xe4\xe4\x8d\xcf\x19\xd4\xf6\x54\xc4\x70\x0d\x34\xa0\x9e\x9f\x7a\xbd\x09\x12\x91\x7a\x45\x77\x2e\x9e\xd9\xf2\xa1\xd6\x70\x67\xe1\xb2\x54\xb2\xf0\xe5\xb0\xb2\x32\x12\x45\xf0\x62\x6b\x23\xc9\x88\x6b\xfe\x0e\x26\x87\x48\x05\x13\xe4\xd9\x93\x85\x27\x2b\xb6\x30\xa8\x34\x43\xa6\x34\xee\x28\xd6\x77\x76\x16\x12\xb7\x1e\x77\xc1\xe9\x90\x2e\x4c\x29\x40\x92\x66\x7d\xa8\xd8\x81\x2a\x68\x56\xd9\xf0\x4c\xbd\x98\xdf\x31\xb2\x86\x68\xd1\x1b\x90\x9c\x9e\x04\xd9\xfb\x1f\xf9\x0d\x3b\xdd\xd2\x9e\x4f\x79\x46\x31\x55\x43\x61\xd5\xbd\x30\x46\x84\x27\xaa\x58\xa6\x16\x29\x8d\xd9\x96\xbe\x80\x0b\xc7\xa2\xf5\xfa\x07\x7c\xe2\x72\x9a\x82\xbb\xa3\xdc\x4b\x34\x2b\xac\xf0\xba\xe7\x43\x5b\x53\x31\x2f\x77\x44\x35\xd1\x15\xe8\x3b\x87\x6d\xcb\x4e\x6d\xd9\xf4\x3d\x25\xe4\xc0\xb4\x13\x7d\x8d\x3b\x31\x27\x5a\xbb\x1e\x01\x4c\x65\x11\x8d\xad\xf6\x60\x47\x2a\x43\x9a\xc1\x04\x66\x4a\x1d\x3f\x95\x45\x32\x35\x21\x73\xeb\x64\xca\x63\x8a\xa9\x86\x08\xb4\x91\x81\x8c\x88\x20\x75\x01\x65\x4c\xbb\xb3\x16\x3b\x9f\x6e\x6a\x61\xca\x9c\x24\xc6\x10\xc0\x6b\x93\x0c\xe7\xf0\x4d\x75\xe7\xe2\x5e\x5b\xfa\x56\xad\x7c\xb6\xb5\x7f\xb2\xb1\x79\x0a\xe4\xe4\x1b\x7f\x21\xba\xba\x86\x06\xa3\xca\xb7\x2d\xfa\x02\x12\x7a\x5b\x88\xec\xe5\x78\x5b\xac\x59\xff\x3b\xd1\x3b\x24\xf9\x9e\x1e\x65\xe1\xc3\x14\x85\x86\x59\x1d\x51\xf5\x73\x6f\x51\x55\x1d\x87\x7b\x0b\x8f\xc6\x32\x74\xf8\x0a\x0b\x75\xc4\x27\x8f\x44\x1a\xe3\xbc\xf7\x76\xae\x30\x3b\x97\x93\x34\xfe\x89\xee\x4a\x0b\x0b\x54\xc6\x4a\x96\x3e\xdb\xab\x7f\xb2\xf6\x4f\xf6\xbe\xd2\xb3\x6f\xff\xc5\xf5\x34\x48\x1c\x5b\x90\x8c\x30\x0d\xd1\x9d\x2d\xb8\xf5\xba\xa7\x6c\xdf\x8b\x9f\xda\x5a\x9a\x95\xa5\xbb\xad\xc2\x9b\xd9\x82\xf6\x88\x64\xed\x9f\xec\x59\xf9\x2d\x27\x2e\x8e\xee\x94\x6d\x28\x44\x09\x93\xc8\x62\x28\x10\xfb\x00\xaa\xd8\xf0\x9a\x95\xc5\x81\x56\xb5\x12\x0f\xed\x20\xbf\xcf\x30\x1e\x85\x1f\xf9\xc6\x77\xbd\x61\xa9\xd1\xf1\x2d\x10\x43\x06\x6a\x79\x6e\x06\xf2\xc6\xe2\x5b\xc4\xf1\x0a\x3f\x5d\x4b\x3e\x5d\xc9\x96\xe8\x86\xa4\x22\x7a\x33\x64\x42\xbd\x96\x61\x5e\x83\x6c\xf1\xbf\x67\x23\x72\xe1\xa8\xed\xa0\xb6\x04\x25\x43\xcc\xcd\x9e\xf5\x1d\xa0\x6a\x41\x8e\xec\xc8\x91\x19\x3e\x69\x95\xef\xa5\xd4\x78\xfc\x2b\x07\x19\x6e\xea\x2f\x74\x3b\xf0\xa4\x65\xe3\x2e\x36\x6e\x41\xb3\x7d\x81\xa9\x2d\x18\xef\x2c\xe8\x0b\x17\x54\x73\x82\xb4\x09\x66\xd6\x80\xd0\xab\xe0\x55\xa5\x44\xef\x40\x43\x1b\x4f\xf3\x91\x0b\x31\xb5\x5a\xf5\x24\x7a\x6b\x56\x70\x26\x33\x36\x05\xc9\xa5\xf2\x25\xc9\x84\x6f\x16\xdc\x78\x16\x3e\xca\x5a\x50\x77\x16\xbf\x29\xc5\xc2\x94\x62\xcc\x46\x89\x82\xea\x73\xa5\xad\x3d\x79\xef\xfa\x1b\x92\x7f\xfd\x93\x0b\x1b\x5a\x20\x64\x09\x34\x71\x95\xd8\x96\xfd\x41\xc3\xe6\xd2\xb6\xd2\xdc\x9e\x01\x89\xda\x41\x64\xbb\xf3\xa4\x60\x1e\x75\xda\x4a\x1f\x50\x7f\x30\x07\x28\x56\x12\x03\x53\xa5\x77\x64\x1f\x7e\x3b\x68\x2b\xa1\x84\x80\x34\xda\x04\x32\x81\x79\x45\x72\xcc\x70\x85\x40\x94\x3c\xfc\x2b\x65\x2f\x12\x8b\xcb\x59\x42\x4e\x3b\x5b\xc2\xb5\x04\xd2\xbd\x76\xc9\x75\x58\xfa\x4b\x17\x0f\x5c\xfa\x25\x83\x12\xa5\xf9\x23\xda\xd7\x96\x9a\xff\x81\x2b\x1b\xc9\x13\x96\xfd\x62\x1b\x8b\x9c\xd9\x2a\x16\xf5\xe8\xdf\x9e\xb3\xe9\x2d\xbd\xa6\xd2\x1c\x98\x41\x97\x24\xe0\x4b\x4e\xd4\xca\x27\xaf\xf8\xf6\x8a\x31\xeb\x92\x0a\xa2\xa4\xeb\x52\xd2\x65\xc7\xd6\x45\x9b\x19\xf7\xba\xa5\xc4\xcd\x75\x3c\xce\xcc\x7a\x46\x2c\x0f\x07\xfc\x3a\x21\x57\xff\xd2\x55\xdc\xd1\x89\x90\xb0\x8a\xa7\x3d\x1f\x60\x2e\x65\x69\x0e\xfd\xd9\x4d\xc9\x35\x5a\x72\x3d\x96\x8c\x28\x22\xc2\xf1\xdc\x43\xcc\x4d\x46\x07\x03\x92\xe4\x8c\x1c\x97\x8c\x33\x97\x7e\x0d\x96\x74\x5e\x80\xe2\xb6\xb9\xf4\x5e\x4b\x69\x5e\x0b\x66\xd3\x36\x0b\x7c\x52\xfb\x6c\x33\xeb\xa7\xf8\x2f\x44\x0b\xa2\x0b\xd1\xd5\x90\x39\x1a\x15\x37\xba\x15\x0f\xd2\x2a\xbb\x07\xf4\x82\x65\x5f\xf9\x2d\x93\x84\xe2\xa5\xc1\x15\x3b\x55\xc1\xb2\xf7\x34\x36\x6f\xc5\x8d\x30\xd0\x15\x17\x70\xc5\x1d\xcc\x23\x2d\xac\xb8\xe9\xe2\xc5\x54\xec\xd6\x23\x6f\x3d\x54\x22\x6d\x29\x0b\x6a\x10\x58\x02\x5a\x12\x5d\x81\xa2\x35\xab\xec\x2a\x83\x56\x11\x8f\x47\x2b\x9a\x0c\x41\xa6\xa8\x2b\x0a\x6f\x45\x3d\x00\xd4\xa2\x41\x6a\xe4\x1e\x29\x22\x38\xfd\xfd\x02\xb1\x12\x62\xea\xbf\xa2\x5a\xac\xc4\xb4\x5d\x0c\x59\x9a\x1e\xac\x01\x9d\x80\xf6\xac\xfd\xcd\xb7\x55\xaf\x2f\x08\x32\xdf\xb9\xa2\x09\xac\x44\x7b\xc4\x3e\x1f\x39\xba\x27\x66\xf8\xc9\x97\xce\xcc\x77\xe6\xd3\x0b\xd3\xd4\xcc\x55\xf4\x4e\x2b\x2c\x15\x24\x3f\xc2\xaf\x87\x0c\x56\x74\x5a\x2b\x2e\xa2\xca\x0d\x65\x10\xe9\x81\x27\xa9\x27\x23\x1b\xc9\x40\x26\xd4\x13\xd5\x6f\x3b\x6e\x3d\xa1\x74\xcd\x0e\x7c\xea\x4b\x8a\xe8\x81\xcd\xf9\x93\x57\xe7\x40\x66\x9e\xcc\x7d\x51\x8d\x7f\xc7\x8b\x8e\xee\x04\x33\xdf\xce\x8b\x3d\x89\x42\x25\x27\x4c\x28\xe3\x91\xea\xe2\xd1\x42\x5e\xb1\x17\xff\xf1\x2e\x21\x9e\xc7\x16\xfe\xc7\xef\x0f\xc1\xaf\x86\xc2\x7c\xbf\xd9\x3b\x1a\x68\xd6\xd7\xfe\xb2\x3b\x12\x03\xf2\x9c\xc6\x0d\xfc\xc5\x0f\xd6\x5f\x4e\x6c\x83\x0b\x91\x98\x58\x85\x3a\x66\x9c\xc1\x18\xd8\xa8\xa8\xa7\x2a\xaf\x97\x1e\x2d\x68\xf6\x27\x9f\xcc\x10\x68\x20\x5f\xb0\x11\x05\x07\xab\xa6\x6e\x01\xaa\x88\x82\xd1\x7c\xc2\x9d\xb2\x9e\x9e\xdb\x98\x06\x01\x19\x13\xa9\x15\x79\xf2\x07\xe3\x3c\xe8\x51\x3f\xaa\xb6\xfb\x24\x39\xc9\x23\xba\x5a\xeb\x26\xc5\x5e\x8b\x67\x71\x35\x22\xa2\x40\x7a\x27\xa6\xf6\x3e\x7d\xcd\x55\x50\x8b\xb2\xd2\xb4\x02\xfd\x78\xe2\x21\x49\x2d\xa4\x62\x86\x1a\xe1\x87\xda\x5f\xf4\xa8\xbd\x2e\x7a\xb2\x53\x95\x48\x56\xc8\xa3\x1a\xa8\x66\x64\xaa\xe6\xb5\x0b\x04\xe9\xb4\xbe\x3d\xcc\x50\x2d\xb2\x71\xc3\xca\x9f\xbc\x5e\x78\x92\x6d\xe8\x77\x28\xaa\x5a\x86\x4e\xbb\x7d\x64\xda\x07\xb4\x69\xcd\xf9\x7f\xe2\xba\xab\xc5\x8b\xd6\xfa\x2e\xd6\x39\x0b\x05\xd7\x3c\x81\xac\x65\xfd\xa2\xd5\xb8\xbf\x24\xce\x4c\x1d\x2c\xa4\x6c\x67\x6a\x59\x2e\x72\x99\xc5\x5e\xc8\x5c\x9f\xcd\x5c\xd6\xfe\x16\x62\xad\xae\xa4\xbc\x30\xf3\xfe\xfb\xcc\x3c\xc3\x96\x44\x9d\xc1\x28\x90\x33\x7f\x1c\x37\xe3\xc1\xca\xcc\xbc\xb8\x31\x5f\xc8\xb8\x6f\x9f\x21\x16\x4e\x94\x12\xe1\x84\x34\x65\xb6\x29\x51\xc1\x72\x6b\x56\xac\xda\x05\x68\x0a\xf4\x42\xfb\x37\x33\x0d\xa3\xc6\xff\xab\xf0\xf8\x24\x96\xfd\x42\x17\x70\xa6\x07\x72\xb2\xcc\x21\xb0\x33\x31\x66\x7f\xf3\xcd\x96\x61\x37\x90\x6f\xbe\x98\x1f\xfe\xc9\x3b\xd1\xc9\x25\x9b\x5a\x07\x19\xb1\x5e\xbd\x6f\x37\x13\xd1\xd3\x57\xf7\x50\x4e\x33\x89\xf2\x66\x40\x9f\xd8\xc4\xcd\x28\x28\x33\xda\x95\x19\x97\xc0\xcc\xdf\x96\x9b\x49\x35\xc7\x1e\x66\x1c\xb1\x0e\x24\x17\x56\x82\x06\x81\x22\x19\x13\x65\x50\xb2\x20\xf1\x3d\x15\x04\x94\x78\xcf\xe4\xd2\x17\x12\x34\x2c\x49\xed\x9f\xcc\x3c\xf9\x9b\xa8\xf1\x35\x44\x73\x31\xf3\xb1\xa1\x99\x8f\x0d\x81\x68\xb4\x0d\x64\x6b\x63\x1d\xc8\x0f\xbc\x83\x56\x9e\x88\xfe\x75\x6f\xab\x1c\x22\x4a\xe4\x8e\x2b\x90\x94\xb8\xd2\x6c\x9b\x09\x92\xfa\x32\x54\xfe\xbf\xc2\xed\x23\x1a\x51\xf8\x66\x7e\x2f\x06\x12\x9a\x3c\xe7\x6c\xcc\x4d\xff\xde\x61\x06\xc1\xb7\x3d\xbd\xbc\xaa\xc7\xa0\xf1\x8c\x62\xce\xc3\x11\xa0\x7b\x22\x35\x7c\x20\xcf\x9e\xac\x3d\x79\x37\x24\xdd\x26\x19\x01\xc5\x2b\x46\x73\xc6\xba\xe6\xbc\xc9\x31\xe7\x8d\xa1\x39\x57\xe6\xdc\x42\x23\x9a\xf5\x81\x59\x2b\x98\xa0\x39\xa7\x7d\x4e\x23\x31\x97\xbf\xdb\x1e\x63\x2a\xec\x7c\xcb\x52\x5b\xdf\x80\x17\x6a\x14\x3c\xf9\xe2\x07\xe4\x05\x71\x5c\x92\xc2\x3f\x99\xf9\x32\x56\x40\x2b\xde\xfa\x03\xf9\x2f\x26\x6f\x2e\xab\x71\xc8\xb6\xac\x71\x70\x32\x17\xe7\xef\x13\xe8\x93\xd3\xf6\xc9\xa9\xbc\xb0\xf2\x8b\xbd\x1b\x3c\xba\xdc\x50\x58\x86\x43\x90\x3e\x33\x24\xf8\x0f\x22\x97\x56\xfb\x5f\x7b\x76\xa1\x46\xef\x81\xce\x79\xdc\x31\xf7\xf1\x85\xb9\x3f\x65\x07\x79\xf0\xa4\xb2\xf6\xc8\x2a\x63\x43\x7e\x59\x5b\x7f\x23\xaa\x40\x74\xb2\x61\x72\x31\xd4\x86\x1b\x18\x1c\x46\x0d\x98\x3c\xa0\xb2\x6e\x7c\x48\x01\x44\x4d\xc1\x33\xae\x9d\xa0\xfa\x86\x37\x4f\x80\x6e\x91\xe7\x97\x53\xea\x86\x91\x06\x20\xed\xd3\x73\xe7\x2e\x8c\x63\x35\x3f\xdb\x4d\x94\x58\xa0\x9e\x4d\x83\xcc\x7d\x0b\x1a\xdf\x85\x38\x00\x3c\x5f\x8b\x75\xbc\x32\x50\x88\x87\x6b\xff\xe6\xd6\x57\xb0\xf3\x65\xe8\x86\x01\x65\x1c\x7e\xab\xe0\xe8\xc9\x4f\xdf\xd1\x33\xd1\x45\x03\x81\xb2\x5c\x90\x74\x95\x79\xb8\x35\x2e\xca\x0a\xa8\xef\xca\x48\xfc\x98\x9a\x32\x02\xb9\x21\x1a\x31\x0c\x01\x3e\x26\xca\x59\x54\x0a\x01\x8d\x91\xcc\x46\xa6\xb1\x36\x14\xd3\x2c\xfa\xd5\x50\x1a\x81\xb6\x40\x19\x64\xaa\xb1\x73\x51\x2d\xbf\x60\x03\x0a\xdf\xe8\x92\x25\x54\x3c\x68\x7a\xd6\x6d\x81\x98\xb0\xc6\x7b\x88\x8d\x39\x84\x39\xf9\x1c\x9f\xda\xf4\xf4\x43\x18\xfb\xae\xa5\xa1\x49\x69\xa4\xc0\x8a\xf5\xe8\x86\xb6\xc1\x15\x7d\x8c\xf8\xb3\x79\x0f\x03\x92\xe8\x3d\x80\x17\x44\x15\x4f\xfd\x9e\xed\xf2\xaf\x16\xbd\x64\xab\x56\x7e\x18\xd7\x52\x4f\x03\xb2\xe1\x88\x7c\xe7\x20\xe0\x16\x82\xb6\x6a\x4f\x29\x3b\x31\xeb\x07\xcb\xfa\x64\xf7\x2e\xd0\xfc\x0d\x55\xce\xb3\x28\x1a\xe4\x13\x57\xc3\xca\x0f\xa4\xee\xf9\x0f\x5e\x1a\xee\x51\x1a\x5c\x9c\xb7\x2e\x24\x6c\xb5\x1d\xd0\x35\x7a\xef\x57\x76\xb5\x30\x46\x96\x1a\xc5\x3c\xa1\x7c\x24\x63\xa8\xd8\xc6\x89\x49\x02\x0b\xa6\xc9\xd1\x2b\x6d\x64\x1e\xff\x60\xce\x67\xf3\x51\xb4\x61\x05\x5b\x55\x70\x5f\xdb\xd0\x47\x69\x18\x62\x6d\x54\x19\xba\x0c\xf7\x44\xa5\x4f\xa6\x0a\x79\x67\x75\x33\x5f\xc9\xdc\x44\xc6\x9d\x17\x3f\x33\xdc\xd3\x78\x67\xa4\xf1\xce\x08\xf2\xac\x99\xbc\x31\x41\x86\x5b\xe2\x3a\x44\xb5\x91\xc8\x67\x03\x2e\xdb\xa7\x7f\x72\x71\xef\x98\xdb\xf8\x6c\x8e\x44\x4b\x92\x11\x85\x66\x2f\xa8\xac\x17\xdc\xf3\x2d\x28\x07\x0b\x3b\xbf\xd6\x0c\x43\x66\x18\x33\x6d\x0c\xad\xb1\xf0\xa7\x57\x0b\xee\xd5\x17\x76\xce\xfd\x64\xc4\x92\x75\x71\x2f\x7c\xf9\x15\xab\xad\xbc\xb0\x2c\x38\xe4\x0b\x6a\xe9\x05\x07\x7b\xc1\x88\xeb\x42\xbf\xb1\x49\x34\x39\x1e\xfa\x2e\xb8\x81\x5b\x30\x70\xb4\xe0\x72\x12\x24\xbe\xcc\x82\xa3\xbd\xf0\x4a\x79\x81\xa0\x0d\xdd\x82\x05\xf7\x62\x0b\x19\xf7\x06\x48\x6f\xee\x00\xbd\x62\xa8\x17\xb6\xae\x5e\x7b\xfc\x22\xd0\x8e\x5b\x3e\x7a\x8c\x78\x5b\x57\x92\xd4\xab\xde\x85\xc9\x5e\x45\x82\x08\x35\x87\xd1\xbe\x55\x03\xba\xf6\x34\xca\x66\x77\x13\x17\xbf\x0e\x63\x58\x69\xda\x8e\xdc\xe6\xdf\x89\xed\x42\x9d\x58\xa9\xbb\xe5\x66\xbf\x35\x83\xb8\x00\x49\x99\x9c\xfa\x9b\x00\xad\x1e\x06\x4a\xcb\x5a\xdc\xd5\xef\xf9\xef\x06\x05\xd9\xc2\x6d\x79\x2d\xa4\xe5\x65\xe5\x16\x27\xdf\x86\x2c\xed\x9e\xaf\x47\x4b\xd3\x06\xf7\xcb\xda\xa9\xe1\x43\x41\x62\xf3\x5a\x09\x60\xf7\x99\x75\xcd\xb8\x7f\xcb\x73\xf7\x56\x56\xd9\x7f\x59\xdf\x8e\x19\x4e\xd0\x62\xf8\xa6\x31\x7e\xda\xd0\x52\x6b\xb6\x32\xc1\x59\xcf\x36\x68\x8d\x65\xb0\xef\x8c\x80\x90\xd5\x8e\x91\x5a\x19\xfd\x4f\xa2\xab\x35\x5f\x4f\x8a\x76\x24\xa1\x84\x25\xa3\x32\x40\x4b\xa2\x2b\x50\xfc\xb2\x6f\xc9\x89\x5a\x72\xe1\x2e\xd5\x43\x92\x9a\x97\x76\x51\x37\x27\xd1\x2b\x29\x4b\x1e\x9d\x2c\xfd\xc1\xcc\xd2\x7b\x40\x4b\x4a\xef\xd2\x3c\x9a\x98\x1c\x97\xc8\xd2\xbb\x2a\x20\x9f\x7c\xa2\xb1\xe8\x25\xef\xa3\x83\x64\x54\x86\x4b\x91\x86\xa0\x61\xbf\xe9\x29\x61\x5f\xcb\xf9\xe5\xa0\x06\xfc\x0e\xa8\xe6\x48\xcd\xf9\x74\xc1\x4d\xc7\xd2\x7b\x6d\x4b\x7f\xcc\xb2\x34\xe9\xc9\x50\x5d\xd8\x88\x33\xf9\xd3\xbd\x20\x6a\xe4\x9b\x68\x89\x31\x3c\x9d\x25\x55\x06\xd0\x2d\xeb\xda\xc9\x58\xdc\xf4\xec\x33\x57\x4d\x3e\xe1\xf2\x11\xc8\x11\xa1\xa1\x25\x8e\x47\x58\xce\x99\x63\x76\x61\x2d\x17\x19\x9c\x27\xce\xcd\x15\x01\x7a\x23\xc1\xfe\x62\x14\xcc\xe4\x2e\x45\xcb\xbf\x03\xe5\x88\x6f\x00\x35\x28\xe4\x9b\x37\x94\x4b\x7f\x00\xb2\xf4\x9b\x84\x25\x2d\xe4\x92\xbe\xe4\xd2\xdb\x4a\x90\x7b\x1b\x4a\xb7\x8b\x07\xa9\x88\xf4\xe8\xe0\x1b\x6d\xe1\xd2\x6c\x61\x2c\x9e\xd3\xef\x2e\x6d\x80\xfc\xcf\x46\xd3\xec\x1c\x4f\x20\x96\x66\xe0\xd8\x13\x0d\x04\x69\x17\xbe\xd9\x66\x5a\x95\xe8\x37\x1a\xbb\x57\x1a\x3b\x1c\x86\x4d\x90\x16\x6f\x61\xac\x7e\xbb\x85\x81\x87\xb7\x7c\x52\x19\x92\x83\xe7\x9e\x9e\x9e\x59\x89\xfa\x9d\xf1\x8a\xb7\x84\x57\x74\x87\x57\x74\x87\x57\x6c\xe7\x8a\xdf\x1a\xac\xec\x1a\xf1\x88\x44\xc5\x63\x85\xeb\x8e\x44\xf1\x4c\x18\x7c\xc9\x76\xe7\x38\xe9\x05\xd2\x23\xb9\x15\x55\xc0\x8a\xfa\x74\x05\x67\x1a\xa8\x64\x8b\x11\x91\x8e\xc3\x30\x67\x2d\x0d\xd3\x16\xbe\xf2\x5f\xae\xa9\x83\xe7\xcc\xd9\x32\x5c\x08\xb2\xf1\x39\x5f\x7d\x5b\x56\xb2\x74\x86\xe4\x6b\xb6\x77\xfd\x6b\xb2\x8d\xcd\x8e\x17\x9b\xe3\x55\xab\x57\x59\x68\xba\x37\x5f\xd1\x36\xaf\xa8\xb0\xa3\x31\x58\xe9\xc5\x59\x11\xc8\x15\xd5\xf4\xab\x0f\x59\xaf\x64\x55\xb1\x72\x15\xad\x16\xd9\x0a\x86\x6b\xd7\xfe\x02\xe0\xda\x7f\x0c\xb1\xf6\x47\xde\x20\x35\x91\xba\x10\x6b\xbf\xe5\x5c\x53\x50\xd6\x54\x60\x6b\xdc\xf9\x04\xd2\x30\xcf\x9a\x97\x71\x40\x4a\x2c\xf4\xb5\xac\x72\x68\x4e\x2d\xfb\x85\x6b\x6b\x0d\x55\x26\xeb\xf1\x0a\x8e\xea\x2a\x90\x0d\x8f\xfb\x84\x98\x29\x02\xd1\xae\xe9\x95\x98\x35\x75\xd8\x5a\x8f\x99\x45\x48\xd7\xd4\x5c\x40\x5a\xcb\xd5\xb2\x86\xb1\xbf\xb1\x12\x6c\x22\xd6\xf2\xe9\xcb\x1f\x40\x37\xd6\xd4\x80\xde\x89\x4e\x40\x13\xbe\x81\x2b\x3e\xef\x24\x7a\x7d\x7e\x23\xeb\x3a\x05\x1a\xf0\xe7\x15\x36\x3c\xa7\xdc\x70\x99\x6e\xb8\xfc\x36\x92\x6f\x09\xa4\x1b\xd0\x8d\x7d\xa6\x79\x25\xd1\x2b\x4c\x1b\xce\xc1\x86\x47\xc6\xdc\x01\x20\x55\x9d\xd7\x8d\xc5\x53\x77\x20\x0b\xef\x23\x09\x77\xa2\xb6\xe1\x4d\x00\xa0\x8c\x68\xca\x56\xc6\xd0\xd4\xc6\x7f\x00\xb2\x71\x1f\x80\xe4\xe4\xb5\xcf\x39\xf3\x05\x2e\x59\xe0\x9a\x79\xce\x2c\x4a\x43\x47\x1b\x6e\xf2\x36\x32\x3f\x18\x5d\xf3\x50\x2d\x77\xf2\xcb\xc7\x46\x1b\x9d\x17\xcb\x5c\x58\x45\xb6\xeb\xda\xd0\xa6\x6c\x7c\x30\x78\x63\x51\xa7\xf8\xe4\xc9\x5a\x96\xc4\x7b\x7f\x1b\xef\xa1\x6e\x68\x4c\x36\x7e\x63\xb5\xd1\x1d\x94\x0e\x84\xd8\x0f\xa2\x8b\x6b\x99\x08\xdc\xc6\xef\x90\x36\x3e\x22\xfb\x1d\x47\xe9\xd0\xed\xdf\xa9\x9f\xd5\xd2\xf3\x56\xc4\x77\x46\xa2\xbe\x8b\xd6\x53\xaf\xef\x3b\x0f\x98\xbe\x63\x45\x60\x8e\xbf\xe3\x47\x28\x80\x6e\xac\x44\x8d\xab\x69\xbc\x60\xcb\xe3\xb8\x2d\x97\xd5\x96\x71\x97\x2d\x2f\xff\x6e\xa5\xe6\x59\xcf\xae\x55\xeb\xb0\x6c\x79\x53\x05\xf7\xb6\xbe\x1a\x92\xd6\x6c\xe9\x35\x6d\xed\xc0\xac\x06\x99\x33\x4c\xb0\x65\xf0\x77\xcb\x0b\xb5\x5b\x93\xb0\x98\xac\xdf\x31\x6d\x19\xc4\x80\x77\x86\xa4\x13\x37\xc3\x5b\x2a\x8a\x2d\x5d\xaa\xad\x88\xdb\x48\xbc\xa3\x33\xc6\x63\xcb\xaf\x55\xb7\xfa\x91\xb8\x28\xa5\xad\xe8\x8e\x6b\x4f\x7f\x4b\x40\xdb\x12\x10\xbb\x9b\xe8\xcf\xa0\x6c\xa9\x3b\xb6\xf2\xfa\x03\x10\x9c\x9b\x11\xc9\xc8\x0a\x4e\xe2\x85\xef\xad\x85\xc8\x23\xb9\x25\x8a\xe5\xc4\xf7\xfc\x6c\xc9\xc5\x14\xa2\x7f\x88\xf4\x76\xe9\xd6\x6f\xc8\xb7\xce\x1f\x49\xc9\x55\xcb\xef\xb8\x39\xde\x49\x33\xff\x0b\xdb\xb6\xe3\x4d\xa6\x9d\x7d\x9e\x72\x05\x29\x64\xc4\x47\x24\xb5\x21\x99\xc6\x1d\xcf\x8e\x77\x8c\xe1\x0a\x12\x41\xd8\x59\x10\x28\x05\x59\xf0\xa2\xce\x8e\xa7\x5d\x3b\x5a\xd5\x1d\x6e\x38\x00\x7d\xb0\xd4\x4f\xa2\xf8\x3b\x2b\x3b\x5e\xa5\xdb\xd9\xaf\x01\x7c\x27\xd9\xc2\x28\xed\xfc\x3d\xf5\x9d\x7d\xca\x90\x81\x68\x88\x68\x47\x4d\xf1\x46\x57\x6d\xcf\x43\x8f\x37\xbd\x05\x23\x59\xdf\xb8\xeb\x79\xe3\xfd\x97\xbd\x8f\x0b\x83\xdc\x13\x55\x3e\xb9\x66\xd9\xd1\x22\xef\xbd\x45\x06\x59\xb0\xf8\x37\xf7\x82\xc5\x53\xf6\x74\x12\xf6\x74\xef\xf6\xb4\x2f\xf1\xd2\xc8\x9e\xd7\xc4\xf6\x74\xe2\x40\x62\x53\xf5\xc0\x69\x8f\xcb\x51\x86\xec\x69\x85\x8e\xbc\xd1\xa9\x90\x34\x2b\x52\x67\xfc\x87\x9e\xaa\xd8\x4b\x73\xa2\x86\x28\x06\x29\xf6\xfe\x42\xda\xde\x9f\x84\xee\xb9\x39\xda\x9b\x9b\x37\x22\xc9\xf9\xf6\x8b\x6f\x7e\xb4\x51\x7b\x6f\xa3\xf6\x5e\x83\xec\x4d\x69\xc4\x02\xa2\x47\xb9\x57\x1b\xe5\x72\xfe\xc3\x15\xb3\xf7\x3f\x4f\xb2\xe7\x1d\x7a\xa0\x77\x20\x31\xec\x22\xe5\x7b\x9c\x48\x63\xe9\xee\xa5\xc3\x13\xeb\x4f\x50\x22\x63\x2b\xc7\xf6\x10\x7b\x91\xde\x01\x11\xde\x33\xc5\xb2\xc7\x69\x4a\xd7\xff\xd3\x1a\x67\x3f\xd8\xb1\xa7\xad\x03\x1a\x7a\xc2\x91\x55\x57\x21\x27\x89\xa7\x72\x6f\xd0\x3a\x36\xe1\x89\xba\x6f\x7b\x6f\x5d\xf7\x7e\x2f\x05\xa2\x8a\xfa\x07\x6d\x21\x50\xcb\x0c\x4b\xdf\x90\x15\x3b\x14\x43\x89\x20\x3f\x88\x4e\xbe\xb1\xff\xe7\xc9\x27\x0f\x0e\xf7\xde\x6a\xee\x3b\x77\x63\x0d\x44\x35\xe9\x81\xf6\xeb\xc0\xd3\x9e\x03\x17\xca\x81\x63\x71\xe0\xf2\x38\x70\x79\x1c\xa8\x9c\x0f\xdc\xf7\x1c\x78\x4a\x77\x30\xe7\x37\x23\xd1\x82\x4a\x66\x2d\x65\xad\x9c\x58\xb0\xca\xe1\xbb\xfb\x6c\x31\xd6\xa0\x6b\xe9\x20\xeb\x66\x6c\x48\x64\xe8\x20\x8b\xe6\x0f\xd6\xf5\xcc\x12\x1b\x36\xb5\x85\x9b\x70\x30\xe9\xaf\x48\x2a\x66\x40\xad\x07\x56\xf9\x02\xc9\x3d\xf8\x2d\xd2\x3f\xf6\x03\x3d\x23\x92\x05\xab\x6b\xe9\x9b\x1c\x38\xaf\x07\x99\xd4\x7b\x88\xcd\xc1\xbc\xee\x96\xef\xac\x59\xdd\x96\x8d\xdd\x33\xed\x9d\xc3\x16\x83\x37\x07\xee\x99\x0e\xf6\x6b\x2d\x23\x12\x7d\xef\x6a\xb3\x60\x32\x00\xf4\x68\xdd\x0d\x2b\x67\x4a\x84\x5e\x5a\xdb\xdf\x2d\x8e\x89\xe1\xd4\x1f\x13\x59\x93\xa0\x41\x76\xbd\xe1\xe0\xad\xe5\x81\xdf\x73\x09\x72\x1b\x99\x03\x8d\xe8\x41\x96\x68\x44\x29\x51\x66\x28\x89\x95\x17\x4e\x06\xf5\x44\xb4\x25\x29\xac\xbf\xee\x46\xc2\xc1\xbb\xa3\xff\x70\xd5\x21\xf9\x87\x49\x98\x8b\xc7\x1f\x19\x4a\x3f\xea\xa1\xa7\xbc\x70\xf4\xdf\x74\x1c\xfd\xed\xa7\xff\xd9\xd7\x87\x19\x0b\x48\xb9\x81\x03\x39\x02\xe9\x3a\x3a\x52\xc1\x1c\x69\x70\x8e\xf4\x66\x8e\xb2\x7a\x1e\xd0\xaf\xa3\xfe\x52\x97\x05\xa2\x8e\x54\xd5\x47\xae\x9c\xa3\x2c\x9b\x2f\x40\x8f\x18\xde\x23\xae\x17\x01\xcd\x98\x6f\x06\x37\xe9\x48\x5f\xef\xa4\x47\x54\x42\x8e\x34\x36\x47\x1f\x7f\x3b\xf2\x84\xfe\xc8\x5f\xb0\x3a\x9a\xcd\x69\x49\x32\xa2\x82\x65\xbf\xf2\xbd\x15\xbb\xbe\x62\x15\x3b\x3e\xdd\xb3\x85\x07\x5f\xed\x4f\x66\xbd\x10\x5d\x0d\x99\x01\x38\xf2\x7c\xf4\x48\x91\x3d\x8a\x38\x16\x86\xb4\xea\x84\x63\x0d\x1f\x53\x9a\x7c\xd2\x53\x2e\x6d\xb2\x79\x92\xc7\xce\x9d\xaa\x9f\xec\xe0\x28\xe3\x13\x15\x28\x3c\x51\xe3\x86\x53\x06\x15\x9e\x9f\x3e\xca\xfb\xd3\x76\xb6\x03\x92\x8c\xe8\xce\xe7\x29\x7c\x51\x25\x91\xda\x93\x9f\xfe\xdc\x1b\x64\x4e\xa4\xc7\x9f\x3f\x3b\xf7\xab\x0b\x3f\xfd\x39\xf6\xcf\xce\x7e\x34\xe1\xa7\xf8\xa5\x13\x20\xdd\x68\x7c\xe8\x06\x5c\xe4\xec\x43\x37\xc5\xba\xf2\x91\xd3\xf6\x3f\x3f\xbd\x27\xfe\xf1\x9b\x59\xfc\xb0\x10\x63\xc5\x9c\xa5\xf5\xdb\xed\x05\x3f\x3a\xfb\x22\xeb\xcc\x21\x3b\xd3\x17\x84\xe1\xd2\xcd\xc9\xd9\x3e\xa0\xca\x49\x74\xf4\xcf\xfe\xa3\xa5\xb3\x7e\xa7\x64\x45\xc5\xef\x94\xce\x5c\x79\x67\xce\xc8\x99\x1d\x38\xfb\xd6\x7f\x72\x19\x9e\xb9\xe6\xce\xd4\x32\x67\x7a\x4d\x67\xce\xd4\x99\xee\xfb\x99\x87\xce\x67\x4a\xce\x99\x7a\xe8\xdc\xb9\xaf\x26\xcf\x5c\x94\x67\x5c\xff\x21\xd2\x3e\xea\x75\xec\x33\x4d\xd6\xbf\xf8\x59\x39\xdf\xa8\x5f\x3e\x37\x00\x2f\x89\x1a\xb6\x73\xc5\xfd\xce\x99\xf1\x9b\x33\x9d\x9f\x33\x9d\x76\xa0\x29\x11\x7b\xe0\xae\x43\x21\x6c\xb4\x81\x46\x8c\xdf\xfb\x00\xa9\x27\x7b\xe1\x71\xcd\x85\xb1\xc2\x0b\xbe\x56\x02\xd2\xe3\x8b\x8b\x18\xd8\x7e\x4f\xbf\x15\xb2\xf2\xbf\xf2\x0d\xb5\x89\x17\x44\x00\x81\xd6\xf0\xb4\x2f\xb2\x4b\x9f\x02\x6d\xf9\xae\x4a\xc2\x85\x91\xc1\x8b\x98\x8e\x3b\xa0\x21\x9f\x66\xfc\xac\xe0\xc2\x1f\x7e\x8c\x86\x33\xfe\xe0\xd9\x05\xba\x81\x28\xb3\x96\xbb\x4b\x36\x17\x8b\x7e\x87\x17\xae\xbc\x87\x71\xa5\xe1\xb8\x52\xfa\xae\xd4\x33\x57\x04\xa0\x0c\xc9\x54\x5d\x29\x5c\x57\x5a\xb2\xab\xfd\xe2\xc3\x00\xa4\xf6\x28\x96\x3a\x23\x7a\x61\x3b\x5a\x3a\x66\x57\x7f\x22\x77\xa5\x23\x72\xf5\x91\xd5\xab\x74\x61\x45\x84\x06\x96\xcc\x29\x5b\x75\xcb\xa9\x7a\xfb\xea\x77\xba\x57\xc6\xa3\xae\xdc\xdf\xc7\xa3\x8e\x2b\x2f\xdb\x5f\x7d\x70\xff\xca\xaf\x94\xae\x8c\x37\x5d\xdd\xe0\x4a\xfc\x40\x92\x03\xc2\x85\x23\xa0\x50\x93\x6e\x07\x06\x3d\xb7\x31\x50\x34\x24\xaa\x7a\xf6\x9d\x19\xbe\x94\x8c\x77\xf0\x03\xba\x63\x41\xa5\xed\x8d\x71\x2f\x3f\xfe\x7a\xaa\xf2\x37\xa0\x47\xfb\xcd\x46\xbd\xbe\xaf\x0d\xaa\x59\x79\x2d\x66\x47\xd1\xc9\x50\x10\xdf\x80\x66\xac\x62\xc6\x52\xb8\x8d\x0a\x84\x3f\x6e\x14\xc8\xce\x92\xc3\x30\x5e\x81\x86\x4c\xbb\xb1\x2f\xb6\x71\xdb\x4c\x55\x4b\x20\xd0\x60\x7a\x72\x9d\x78\x92\x7a\x32\xf4\x04\x4e\x95\xdd\x22\xb1\x19\x52\x0e\x39\x50\x52\x11\x41\x0b\x2b\x41\xf0\x04\x44\x5d\x3b\x25\x39\x8b\xba\x75\xbf\x60\x17\xf8\x83\xc8\x8e\xdc\x7d\x96\xd5\x10\xd0\x93\xbb\x78\x1d\xf8\x33\xcb\xbd\x58\x9a\xba\xa8\x7a\x87\x13\x97\x56\x95\xc0\x46\x2b\x81\xf7\xa1\x3f\x2c\xa9\xdf\xe3\xa0\xee\x84\x1f\xc5\xda\xa2\x0b\x49\x43\x3e\x44\x2c\x4b\x11\xce\xbc\x40\x62\xf4\x57\x7f\x12\x2a\xe3\xdb\xaf\xf6\xb6\xee\x3d\x13\xfc\xb0\x6b\x4e\x84\x13\xb0\x64\x60\x97\x1c\x92\x01\x45\x31\x8e\xf1\xc0\xb6\x41\x4a\x6a\x8f\xe8\x63\x46\x47\x3a\x19\x50\xaa\xe2\x8c\xf0\xfc\x37\x19\xd8\x6f\x05\x24\x03\xbb\x85\xa3\xe8\x87\x28\xbb\x64\x60\x3f\xdb\x9b\x0c\x4c\x19\x24\xb8\x64\x56\xb8\x66\xe8\x31\x78\x82\x0b\x64\x37\x5c\x77\xa9\xed\x0b\x14\xbd\x3b\x67\x20\x67\xea\x87\x21\xdd\x7c\x24\xa9\x59\xd4\x24\x75\xb7\xab\x12\xba\xd4\x09\x4d\x7c\x82\xef\x9d\xc7\x40\x0c\xe2\x05\xf2\x0d\x8d\x4d\xdd\x01\x55\x82\x26\x20\x83\x6a\x9c\x84\xbf\x49\xa8\x73\x37\x20\x8a\x69\x3c\x0c\x53\xfe\x48\x54\x13\xf1\x06\x4d\xbc\xb9\x19\x7f\x78\x34\x19\x9a\xe3\x90\xd8\x4f\x03\x5a\x45\xb9\xed\x2c\x02\x99\x32\xf9\xde\x37\xab\xe4\xab\x95\x6f\xc9\xdc\xa3\x1c\xe8\x85\xed\x5e\xb2\xac\x57\x9c\x9f\x31\x0f\xfc\xbd\x64\x68\x76\x3b\xa0\xd4\xca\x4a\x32\x0b\x58\x29\xd1\x59\x46\xe4\x2f\x05\xca\x2d\xec\xa2\xe4\x9e\x08\xd6\x5b\xc9\x73\x4f\x57\x6b\xc2\xcf\x69\xf4\x0b\x18\x45\xaa\xc7\x6f\x28\x90\x37\xec\xc1\x8d\x85\xe2\xe4\xaa\x2c\x2a\x1b\x51\xb2\x46\xee\xf7\x90\x94\xcc\x98\x3b\xb7\x1f\x88\x51\xa2\xc9\x53\xa6\xc1\x37\x0b\x68\xc6\xe2\xe6\x4c\x9b\xb3\xd4\x25\xdf\xd8\x1a\xb2\x81\x1a\xd9\xc1\xc9\xc4\x72\x9b\xee\x1d\xf1\xc7\x76\x48\xc6\x7c\xfb\x2f\xfd\x39\x16\xb1\x35\xe0\x6c\x4c\x32\x62\x51\x13\xeb\xaf\x29\x10\x1c\xca\x84\x61\x1e\xbb\xdb\x1f\xc9\xd8\xeb\x5f\x90\x47\x22\x55\x76\x63\xfb\x60\xa5\x10\x82\x0b\x44\xfa\x3b\x5d\xc9\xa4\x8b\x5f\x66\x28\xf9\x42\xa4\x83\x03\x82\x1f\x71\x8b\xd9\xb0\x81\x55\xf2\x49\x92\x41\x35\x4e\xf4\x47\x49\xb4\x00\xbd\x9e\x10\xc9\xd4\x93\xc2\xaa\x8f\xbb\x01\x25\x51\xdc\x27\xde\xee\x4f\x34\x42\x25\x24\xe3\x62\xcd\xec\xfa\xbb\x22\x7c\x53\xab\x64\xce\xdc\xb9\xf8\x6c\x2a\xe7\x2d\xd0\xa3\xcc\xd8\x4d\x4f\x25\xde\x54\x4e\x46\x61\xcd\x28\x0d\x99\x6d\x28\x13\xfe\x36\x52\x82\x5f\x37\xfa\x42\xf4\x83\xe8\xc4\xac\xd8\xcf\xe0\xc7\x7f\x45\x6f\xe0\x27\x87\xfa\x44\x88\xb2\x2b\xd1\xc5\x9f\x9b\xa3\x9d\xc8\x0f\xb3\xc8\x4f\x6a\x83\xd4\xee\x57\x88\x55\xeb\xa6\xbd\xf8\x31\xfa\xff\x07\x00\x00\xff\xff\xaa\x0a\xcc\xb8\xdf\x5e\x00\x00") -func keysWordlistJapaneseTxtBytes() ([]byte, error) { +func keysWordsWordlistJapaneseTxtBytes() ([]byte, error) { return bindataRead( - _keysWordlistJapaneseTxt, - "keys/wordlist/japanese.txt", + _keysWordsWordlistJapaneseTxt, + "keys/words/wordlist/japanese.txt", ) } -func keysWordlistJapaneseTxt() (*asset, error) { - bytes, err := keysWordlistJapaneseTxtBytes() +func keysWordsWordlistJapaneseTxt() (*asset, error) { + bytes, err := keysWordsWordlistJapaneseTxtBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "keys/wordlist/japanese.txt", size: 24287, mode: os.FileMode(420), modTime: time.Unix(1511602021, 0)} + info := bindataFileInfo{name: "keys/words/wordlist/japanese.txt", size: 24287, mode: os.FileMode(420), modTime: time.Unix(1514928181, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _keysWordlistSpanishTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x34\x5b\xbb\x76\xfc\x2e\xaf\xed\x79\x4b\x8c\x65\x8f\xe6\x00\xe2\x27\xc0\x2b\x99\xb7\x49\x99\x62\x8a\xff\x4a\x97\xd6\x2f\x76\xd6\xde\xe4\x2b\x46\x98\x3b\xe8\x2e\x60\xee\xaf\x2d\x26\x0b\x71\xdb\xad\x48\x0d\x71\x93\x67\x0c\x71\x53\xf1\x81\x52\x3b\xe3\xce\xb4\x12\xae\x42\x8f\x2f\x26\xea\x21\x6e\x53\x32\x32\xb3\x5b\x88\x29\x6e\xd1\x91\xec\x52\x34\x86\x98\x92\xb0\x38\xe9\xfd\x53\x43\x4c\xa2\x43\x90\xe4\x13\x95\x52\x31\x5a\x92\x36\xa2\x87\xfb\x2b\x29\x66\x4a\x39\x3a\xc7\xa8\xf7\x77\x88\xc9\x4e\x41\xc6\x38\xcc\xd0\x8b\x09\x81\xeb\x0b\xc9\x64\xe3\xb9\x2b\x13\x71\x8e\x31\x3b\x4a\x77\x65\xd3\xbd\xe8\x40\xed\x6e\x9c\x28\xee\xe6\xd8\xcc\x3e\x63\x8d\x48\x32\x1a\xdd\xdf\x2e\x16\xe2\x21\x89\x6d\x0e\xfd\x5b\xf2\xa1\x75\xe5\xbd\x70\x91\xa7\xe6\x10\x4f\x65\xa3\xd3\xea\xfd\x8e\x48\x3b\x86\x38\x6d\x95\xba\x9c\x2b\x55\x14\x4e\x34\x98\xbb\xa1\xef\xd4\xcc\x1c\x30\xfc\xb0\xd3\x00\xdd\x2d\x44\x75\x09\x51\x7b\x46\xbf\xa7\xec\x2e\x2f\xa4\x58\xe5\x73\x76\xa0\x2c\xc7\xe4\xf7\x57\xc5\x47\xd9\x9c\x05\x5e\x62\x88\x79\x8b\xe1\xfe\xca\xdb\x2c\x21\xe6\x14\xf3\x8e\xaa\x5d\x50\x23\x27\xdb\xc9\x13\x83\x66\xf1\xc1\x42\xc2\x43\x33\xb0\x4a\x2a\xe4\xd3\x76\xee\x34\x2b\x29\x9d\x75\x91\x25\xeb\x85\xf5\x67\xce\x52\xc8\x14\xb9\xdc\x6f\xd2\x37\x8f\x05\xe5\x85\xd2\x45\x15\x62\x31\x8f\xe9\x28\x9a\x05\x6b\xcf\x2f\x34\x2b\x71\xcb\x82\xa4\x0e\x26\xcd\x80\x84\x12\x1d\xfb\x2f\xb1\x13\xad\x65\xfb\x4b\x14\xc3\x14\x6e\xbd\x28\x5b\x68\x1f\x71\x0f\xb1\x18\xc6\x6a\x11\xe8\x2a\x2d\x63\x6d\x35\x3d\x08\x35\x56\xa6\x18\xb7\xee\x98\xb3\xee\xf7\x77\x0d\xb1\x92\x0b\xef\xaf\x7a\x4e\xf0\x68\xd5\x9c\x41\x87\xaa\x05\xb9\xfb\xdd\x43\xac\x8b\x68\x75\x08\x98\xa1\x0e\x3d\x27\xea\x86\x3d\x91\xcc\x98\x01\x49\x97\x3a\x6b\xc2\xac\xf7\x7f\x91\xcc\x76\xff\x27\x4f\x66\x2d\xc4\x16\x49\xf2\x16\x3d\x62\xfd\x4d\x06\xf7\xd1\xd0\xbe\x65\x4d\xac\x34\xa0\xb7\x99\x03\x0d\xcd\x3e\x91\x71\xa9\x3b\x28\xd1\xdc\x88\xd8\x36\xa5\x83\x42\x6d\x62\x9b\x4e\x82\x38\x66\x0c\x14\x8a\xfb\xcb\x37\x1d\x6e\xfc\xb0\x1c\xa2\x6f\x93\xac\xe7\xe9\x41\x22\x38\x24\xd9\x39\xa4\xef\x9a\x81\x10\xdf\x27\xdb\x0b\x10\xe1\x14\x31\x57\xe9\x21\x7a\xf9\x63\x5f\xaf\xf7\x37\xf2\x06\x52\x7b\x23\x20\x47\xb8\xcb\x09\xbc\xb9\xdb\x0b\x70\x82\x5f\xb8\x7c\x1f\xca\x75\x76\xfe\x30\x66\x5f\x0c\xd0\x93\x54\x88\x6a\x97\x73\x52\x8c\xbb\x30\xd7\x41\xbd\xfe\xc7\x5a\x5d\x33\x61\xa7\x58\x76\x10\xaf\x5b\xd9\xb8\xaf\xde\x04\x5b\xef\x63\xad\xbe\x8f\x95\x9b\xec\x37\x0b\x3b\x4c\x8e\x32\xe2\x93\xf0\xdf\x14\x24\x1e\xe2\x58\xc3\x0f\xc1\x40\x43\x81\x8b\x41\x8e\xbf\xbf\x86\x81\xe4\xc3\x23\x50\x33\xb8\x9f\x71\xff\xd6\x10\xe7\x1e\x5f\x80\xa0\xd4\x3c\x25\xc4\x89\x69\x67\x59\x43\xcd\x2e\xe4\xda\x39\xb0\xfe\x0b\xdc\x70\xc5\x9a\x04\x09\x16\x76\xe1\x4b\x72\xa6\x26\xb9\x64\xc1\x3e\x7c\xbe\x42\xbc\x96\x02\xb9\x14\xf8\xf8\xc4\xbc\x9f\x73\x8f\x80\xd8\xf0\x2b\x1e\x4b\xa0\x29\x23\x2f\xc3\x2c\xaf\xfb\x97\x9c\xf2\x9a\x07\x44\xf7\x35\x73\xd8\xe2\x16\x01\xcc\xc3\x16\xd3\x43\xc2\x16\x1f\x20\xda\x16\x35\x23\x03\xe1\xde\x62\x8e\xf5\x85\xb2\x9c\x30\xe5\x46\x35\xb0\xc5\xb2\xdd\xbf\x61\x8b\x35\x19\xe0\x8e\x06\x60\xd6\x2d\x3a\xc7\x74\x96\x7b\xd5\x17\x12\xb7\xb0\xdd\x5f\x3d\x61\xfb\x5b\xec\x63\x0d\xd4\x21\xce\x5b\x1c\x31\xb3\x78\x88\xaf\xc9\x41\xb8\x2d\x8e\x39\x38\xe8\x2f\xd6\x89\x7d\x6c\xb2\xdd\xdf\x80\x8a\xd9\x04\xd2\xb6\x49\x67\x45\xe7\xe7\xd0\x18\x36\x85\xd8\x6e\x2a\x35\x6c\x5a\x4f\x0b\x5b\x5e\x6b\xcc\x06\x52\x6e\x79\xf6\x18\x36\xc3\x6f\xd3\xca\xc4\xc2\x66\x09\x5f\x69\x15\xec\x04\x72\x22\x59\x25\x99\x00\xac\xb3\x59\x66\xff\x82\x4d\x5a\xdd\xe3\x8e\x04\xe2\x48\x1b\xb6\x59\xed\xf7\x97\x86\xcd\x1c\x48\x32\x07\x97\x6e\xd6\x39\x35\xa8\xb0\xd9\xb8\xdf\x35\x6c\xf7\xcf\x25\x9c\xe7\x15\x73\xd8\x3c\x5e\x16\x96\xdd\xdb\x5c\xd2\x23\x22\xb9\x24\x6c\x4e\x9d\xb2\xb9\x72\x0b\xae\x98\xdb\xb9\x58\xca\xd3\xe6\x06\x76\xd9\x9c\x43\x3b\x34\xff\xe6\xb3\xb3\x2d\x78\x7a\x9b\x49\x08\x41\xcd\x09\xb5\xb7\x4d\xf9\x0c\xdb\x3c\x16\xc5\xe6\x41\x42\xdc\xbf\x40\xd9\xd4\xe1\x68\x96\xd9\xd1\x37\x8e\x36\x3d\x13\x62\xeb\xb3\x83\x7f\xb6\x39\x22\x16\x30\x5f\xe8\x0b\x93\x8c\x25\xa6\xb8\x41\x5d\xa7\x48\xa4\x26\x18\xf1\x90\x62\x8a\xa8\xd9\xef\xaf\x4b\x1c\x1f\xc2\x3a\x7e\x1f\xf7\x77\x48\xf1\x7e\xef\x28\xd1\x02\x66\x4d\xf1\x89\xcc\x73\x8d\x9b\xf1\x83\x22\x47\x0a\xd5\x08\xfb\x43\xa8\xc0\x7a\x8a\x39\x0b\x60\x41\x9f\x6c\x6c\x76\xa1\x9e\x05\x65\x63\x8f\x22\x6b\x71\x45\x2b\x93\x66\x21\xdd\x5f\x35\x71\x09\x75\x57\x4c\x52\x25\xa3\x47\x3d\xa1\x15\x53\xac\x9a\x98\x1d\xc8\x40\x37\x02\xae\x25\xd9\x86\x9c\xf5\x90\x62\x8b\x2f\x40\x1d\x6b\xe1\x0d\x04\x48\x91\x1e\x40\x8a\x6d\x82\x84\x29\x12\x07\xbe\xb1\xf3\xfd\xe5\x49\x30\x9d\x43\x65\xa4\xe8\x27\xa1\x42\x66\x52\xf4\x8a\xee\xde\xfe\xea\xb8\x10\xe7\x77\x27\x48\x28\xe8\xc2\xf2\xde\x58\x34\xb8\xe5\x61\x9e\xd0\x15\xa4\x4b\x50\x37\x98\x62\xb2\xd3\xcb\x42\x92\xcd\x20\x5b\x49\xa0\xb4\x93\xec\x18\x40\x32\x70\x7e\x7f\x67\x81\xa9\x4f\x92\xe1\xfd\x20\x3f\xd9\x72\xe9\xa6\x24\x55\x41\x4f\xa9\x83\x7d\x1c\x48\xa1\xfb\x93\xc4\x49\x69\x59\xe5\x60\xf0\x24\x4e\x63\x9d\xee\xef\xde\x64\x0f\x49\xd8\xe9\x11\x49\xc5\x47\xcc\x92\x98\x2d\xed\xfe\x45\x4a\x5b\x9a\x1e\xb1\x11\x3a\x33\xca\x26\x0a\x77\x64\x59\x9b\xf4\xa0\xc0\xa6\x87\x61\xe4\xc7\xa4\xaa\x4d\x8f\xd9\x30\xa1\xa6\x4c\xac\xaa\x9c\x06\x98\x09\x59\x00\x1f\x32\xe9\x01\xdc\xeb\xb9\x50\xa9\x60\x09\x8a\x50\x52\x20\x5a\x2b\x86\xd2\xe6\xb0\x4c\x49\x9d\x15\x3e\xc9\x07\xda\xd9\x82\x0d\x26\x19\x2d\xd3\x39\x48\x39\x56\x00\x8c\x97\x63\x17\xc0\x0b\x50\xa9\xc3\x53\xe6\x24\xf9\x7e\x2f\xfe\x31\xe2\xd6\xfe\x5c\xd3\x64\xe9\x41\x0e\x5c\x2a\x26\x19\x66\xbc\x7f\x76\xb8\x20\x09\x86\x3b\xd9\xc1\xf6\x70\x47\x93\x3d\x04\x23\xda\x13\x9a\x22\xc1\x55\x48\xd0\x40\xc9\x32\xd9\xca\xb2\x9c\xca\x32\x78\x05\xc9\xf2\x1a\x32\xe7\x95\x2b\xac\x9a\x85\x85\x05\x5a\x15\x29\xc7\x2d\x4a\xca\xff\x94\x35\x65\x69\x40\x92\xd5\x1d\x2d\xaa\x70\x9e\x7a\xb2\xc8\x28\x21\x56\xfb\x5f\x29\xf9\xda\x40\x2f\x6b\x0a\xe8\x71\x89\xbf\x39\xf4\x37\x52\xa8\xdd\x64\xbe\xff\x15\x1b\xe7\x77\xe7\x38\x7d\xc1\x02\xd1\x31\x98\x76\xba\x9b\x62\x4c\x07\x2a\x5d\x22\x61\x5a\x99\xfb\x8d\x15\xba\x14\x36\x7d\x03\x2a\xe2\x87\xe4\xda\xd8\x5d\xbb\xf6\x90\x1c\x76\x37\xf9\xfd\xb3\x90\xee\xe0\x18\x56\x4f\x76\x9f\xaf\x90\x66\x24\xd3\xcf\x48\xbe\x98\x91\x9c\x39\x37\x02\x44\x18\x09\xb2\x0a\x3c\xcc\xa5\x2a\xe6\x62\x7f\xb8\xfa\x2c\xe4\x6a\xa7\x5c\x80\x0a\xef\x2f\x4d\x08\x0e\xb2\xb9\x11\xb2\x39\xdd\xe6\x34\xe1\x3a\xa2\x09\x36\x3f\x2b\xd7\x32\x8d\xb0\x2d\x2d\xf0\xdb\x28\x65\xf4\x5e\xd2\x74\xa5\xec\x4d\x5f\x90\x93\x0c\xed\x61\x87\x12\xdb\x69\x76\x31\xe5\x1e\x21\x78\x3b\xbc\x8e\x1c\x76\xd9\xc4\xc3\x7e\x7f\x6f\xc8\xdc\xdf\x29\xee\x31\xec\x92\xd4\xc3\x2e\x68\x26\x87\xd4\x8e\xa2\x43\x2b\x0b\x61\xc5\x77\xc9\x07\xd8\x69\x47\x70\xc4\x56\x19\x46\x6b\x97\x62\x8e\xb6\x70\xab\x76\xa9\x23\x62\x82\xe5\x45\xee\x02\x53\x84\x62\x77\xec\x61\x97\xbe\xbc\x8b\x5d\xe0\x76\xed\xd2\xe1\xe8\x23\xad\x93\x23\xf6\xa1\xab\xf6\xba\xdf\x48\x07\x55\xf4\x2e\x43\x2a\x56\x2c\xf0\x4f\x76\x10\x73\xd7\xb8\x65\x43\xb2\x83\xc2\xbb\xfe\xb9\xef\xbb\xc2\xd3\xd9\x35\x22\xb6\xd9\x75\x9b\x4f\x24\x0c\x99\xf6\x25\x66\xbb\x02\xa7\xbb\xca\x2b\xec\x7a\xdc\xef\x04\x1c\xe8\x89\x69\x35\xaf\xb1\xf2\xc4\xa6\xb5\x42\x3f\xed\xea\x82\x20\x6d\x57\xd7\x93\xc5\xd0\xa4\xbb\x76\x81\xda\xdd\xb5\x1f\x1e\x31\xd2\x85\x8e\x17\x57\x6f\x08\x27\x76\x4b\x00\xb0\x2a\xbb\x15\xba\x11\xbb\x55\xfc\xb0\x14\xa3\xe7\xbc\x9b\xc3\x5f\xdc\x0d\xc4\xdb\xad\xe3\x07\xd2\x79\x3c\x41\xea\xdd\xed\x8c\x61\xa7\x25\xd8\xb9\x73\x46\xb2\xfb\x5c\x53\xcf\x8c\x19\xee\x5f\x7c\x42\xcd\xed\xe4\x88\x7d\x52\xb7\xee\xb0\x44\xf7\xf7\x86\xc0\x43\x36\x20\x03\x3e\x81\x07\xa8\x51\x01\x47\x9b\x07\x81\x6e\x92\xfd\x2f\x90\x94\x5d\x11\x53\x1a\x3e\x06\x6b\x27\x6c\xb5\x1c\xdc\xbe\x1c\x9a\xe2\x2b\xc8\x53\xf0\x2b\x2d\x5b\x90\x2c\x07\x71\x2e\xd0\x26\x8e\x64\x29\x7e\xc9\x72\xa1\x67\xd6\xd6\x25\xdc\xdf\x59\xd9\x48\x3f\xd8\xc8\xa0\x79\x24\x33\x1e\x96\xb2\x81\xee\xb2\xe2\x5f\x29\xf6\xb7\x94\xd2\xa0\x73\xa4\x34\xee\x14\xd3\x09\x13\x97\x1e\x83\x54\x6e\xaa\x26\x06\x68\x52\xd3\x63\x1e\x82\x14\x7c\x21\x88\xa8\x58\x0c\xe2\x49\x3d\x80\x67\xa9\x87\x78\x41\x7a\xd2\xc1\x94\xaa\x67\x41\xdb\x1c\x13\x7a\x9a\x17\x24\x2e\x6c\xdb\xe3\x27\x13\xb9\xff\xc3\x2e\xea\x58\x23\x0d\x67\xee\x82\xe2\x96\x4a\xfe\xbc\xbf\x1b\x1c\x29\xf9\x37\xb5\x59\x10\xd7\x97\x05\xe9\xf0\x39\x90\xc0\x53\x91\x0e\xbd\xeb\x48\x5d\x37\xe5\x07\x77\xdc\x05\x51\x61\x90\x7e\x88\x33\x99\xe2\xec\xdd\x20\x8b\xd2\x1b\xb4\xa6\xf4\xc6\x3d\xf5\x66\x9d\xc9\xc4\xaa\xfb\xbf\x79\xbf\x03\xb4\x0a\x86\x03\x9e\x10\x8b\xa0\xf5\x98\x47\x0c\x32\x60\x14\x65\x88\x57\xac\x70\x40\xad\xc9\xa8\x98\xec\x62\x5c\x28\x57\xcc\x13\x7d\xaf\x45\xad\x8b\x67\x05\xf2\xc1\x63\x0b\xf9\x40\x6c\x1b\xe4\x83\xe7\x22\xf2\x91\xe0\x08\xc8\xc7\x6a\xf9\x41\x09\x90\x0f\x45\x70\x2b\x1f\x2b\x3c\xba\xbf\x3f\x94\x95\x8d\x76\x53\x3e\xfe\xc2\x49\xf9\x68\x06\xa1\x95\x8f\xe1\x52\x2c\x1c\xf7\xd7\xe6\x58\x0c\x3e\xa0\xc1\x8e\x98\x1e\xd8\xec\x71\x7f\x41\x06\x0f\xcc\xef\xe1\x88\xc0\xdb\x01\x3f\xee\x88\x70\x33\x0e\x3a\x87\x47\xcc\x9d\x10\x6b\x3d\xa0\xdb\x8e\x58\x34\x2b\x53\x63\x95\x47\xf0\xce\x11\xbd\xc4\xc4\x72\x37\x8c\xea\x1d\xdf\x5d\xc2\x11\x87\x9e\xf8\x9e\x9c\xe0\xe2\x64\x1f\xe1\x80\x0f\xe3\x16\x0e\x3a\xcd\x87\x64\x7d\x85\x43\x90\x77\x8c\x22\x08\xc5\x8e\xfb\xdb\xa1\x38\x0f\x71\x76\x93\x4e\x17\xfc\x50\x9e\x1c\x1c\x4a\x35\x7b\x28\x96\xa6\x50\xec\x87\xfe\x59\xed\x43\x39\xa8\xee\x18\x50\xe9\x2d\x1d\x2a\x19\x80\xcd\x68\x1b\x0e\x45\x28\x1a\x0e\x7d\x72\x80\x27\x9a\x02\x3f\x9a\x61\xc4\x0f\xec\x12\x3d\x32\xec\xce\xa1\x18\xb4\x02\x8d\x5a\x41\x0d\x68\xe8\x81\x72\x07\x4e\x72\x4c\x06\x88\xb8\xe7\xc8\x6b\x47\x50\x41\x47\x36\x96\x40\xb1\x1d\x19\x4a\xf1\xc8\xf7\x2f\x2a\x6c\xc3\x2e\xc1\xc6\x87\x9d\xb0\xc3\x87\x51\xf9\x1c\x06\x22\x1f\x96\xb3\x60\x78\xab\x3b\x20\x27\xe1\x89\xd0\x61\x3e\x88\x48\x73\x04\x56\x07\x38\xf4\x30\x34\xf5\x98\x22\x08\xe2\xeb\x2c\xea\xf0\x58\x41\x4c\x27\x0d\x3c\xce\x1d\x89\xdc\x6f\x47\x52\xd1\x10\x52\x7d\x38\x24\xea\x70\x6e\xc6\xb9\xfe\x09\xcf\xec\x98\xd4\xda\x94\x0f\x94\x81\x82\x13\x2e\xfd\x31\xeb\x1f\x8e\x27\x02\x91\x63\xfa\x5a\xf7\x24\xd9\x66\xc7\xd4\xf7\xef\xd8\xc0\x04\x73\x40\x1d\x9e\x31\xc1\x3f\x3b\xe3\x11\x7b\x38\x23\x1c\xb4\x13\x21\xfa\x19\x59\x9a\x57\xec\x78\x92\xdf\xce\x88\xf0\xec\x8c\xd0\xd6\xe7\x3a\xc7\x39\x23\x3c\x9b\x33\xc2\xce\x9d\xd1\xe3\x53\x90\xbc\x50\xd4\x97\x07\x75\x46\x0a\xe5\x19\x07\x5a\x5c\x9a\xe1\xd9\x9f\x52\xa0\xb5\x4f\x81\xaa\x3f\xa5\x86\xf3\xfe\xa6\x72\x3a\xa5\x2a\xe1\x90\x70\x8a\xc7\x95\xf3\xff\xe5\x21\x86\xa7\x74\x0c\xa5\x27\xf5\xec\xa9\xa5\xc6\x8e\x56\x0a\x5d\x74\x2a\x06\xc9\x60\x76\x0f\x67\x46\x10\x7a\x66\xc3\xee\x4f\xcb\xf8\x1d\x06\x08\xe1\x38\x2d\x37\x09\x27\xe2\xbd\xd3\xe0\x08\x9c\xe6\x60\xb1\x13\xd1\x65\x38\xc1\x1b\xa7\x0d\x41\x39\x88\x79\x3a\xe4\xf2\xf4\xfb\xeb\x80\x4f\x7d\x3a\x14\xee\xe9\x08\x24\x4e\x8f\xf0\x2e\x4e\x87\xe7\x7a\x3a\x6d\xe9\xb9\x42\xcc\xd3\xb5\xb1\x0c\xd5\x20\xe3\xe9\xd6\x0d\xa3\xdd\xbf\x68\x34\xa1\x51\x4e\x9f\x85\xb0\x59\x38\xe7\xda\xd6\x8c\x2b\xe3\x3b\xd6\x3e\x85\x6b\x9a\xa4\xc5\x64\x70\x73\x4e\xb5\x0a\xd8\xf9\x3d\xe2\x6a\xd1\xb9\xac\x49\x9c\x3f\x22\x5c\x9a\xc7\xfd\x05\x97\xe6\x11\xb7\xcc\x32\xb8\x82\x0f\xa8\x99\x40\x4d\xf3\x88\x79\x95\x17\x84\x9f\x8f\xe8\x20\xda\x23\xbe\xf0\x63\x9c\xf6\x90\x8d\xa7\x3a\x0f\xba\x67\x0f\xfa\x2e\x0f\xc9\xb0\x21\x0f\x81\x3c\x3c\xa4\xac\x1a\xf8\x7d\x0f\xf1\x82\x25\x3c\xee\x6f\x37\x41\xf6\x42\x29\x43\x89\x87\xc2\xe5\x09\x8f\xfb\x4d\x5f\xe9\xa1\xa7\x4a\x95\xf0\x80\x74\x3f\xb4\xa0\x97\x22\xfe\xd2\x18\x1e\x96\x80\xe5\x87\xc1\x17\x7f\x18\x10\x80\xc2\x27\x00\x7d\xc2\x87\xc1\x7b\x78\x58\x35\xd4\x57\xd6\x2e\x50\xa0\xd0\x1e\x3c\x2d\x7e\x18\xac\x40\x78\xd8\xa7\x85\xc7\x84\x99\x7f\x4c\x9e\x62\x3f\x26\x4f\x56\x1f\x44\xff\x63\xca\x05\x08\x2f\xfe\x01\x65\xf0\x98\x7f\x5b\xf8\x2d\xb0\x7e\x8f\x59\x34\xef\x82\x14\x99\xba\xb3\x89\x47\x44\xbc\xf8\x18\x16\x14\xbe\x7d\xd0\x5d\x62\x0e\xba\x2b\x78\x0a\xae\x76\xb6\xa0\x67\x96\xae\x11\xe9\xfd\x1b\xf4\x9c\x68\x91\xe5\x64\x32\x3b\x85\x55\x4b\x84\x0c\xac\x68\x5d\x0b\x4d\x8f\x96\xb6\xa0\xc0\x4f\xd1\xb2\xec\x86\x96\x36\xa1\xf3\xa1\xec\x10\x2a\xdf\xef\xba\x6b\x92\x00\xb7\x6c\x20\xa1\x22\xd5\x7a\xd0\x7a\x6b\x5d\xe2\xa4\x95\x3e\x8c\xd6\x42\x7f\x54\x6b\x99\x15\xb5\x15\x32\xa9\xb5\xd3\x99\xd1\xda\x07\x59\x4f\x61\xdc\x11\xc1\xdd\xef\x3a\xb4\xa0\x66\x00\x2b\x5a\xef\x5f\x60\x53\xeb\xa5\xb4\xa3\xea\x31\x28\x38\x5b\x7d\x9d\x49\x6a\xcf\x04\x08\xda\x9f\x71\x8b\xf9\x7e\x23\xc5\x16\x9f\xb1\xac\xc4\xe3\x86\x4a\xdf\x61\x2b\x9e\x64\xda\x27\x4f\xef\x9e\xf1\x55\x58\x26\x87\x84\xa7\xb8\x42\xb1\x3c\xb5\x42\xdd\x3f\xcd\x2b\x78\xf5\x69\x6e\x1b\x92\x4b\x6a\x78\xda\x67\x0c\xcf\x29\x88\xf8\x9f\x53\x2e\xe9\x48\x5e\xe1\x39\x4f\x7a\x72\xcf\x79\x1a\xc0\xe4\x08\x93\x28\x78\x4e\x44\xab\xcf\x59\x4f\xcc\x38\xeb\x2a\x02\xbe\x9f\xf7\x6f\x53\x84\x4c\x4f\x7a\x8c\x4f\x9e\xd0\x3e\xe7\x25\x55\x73\x78\xce\x17\xf8\xf0\xff\xe0\x51\xfc\x9f\x41\x33\xe6\xb8\xa9\x05\xe8\x19\x42\x47\xc9\x8e\xcf\x1d\x51\x53\xc8\xf1\x64\x60\x94\xef\xaf\xd3\x11\xc1\xe6\x78\xc2\x30\xe4\x08\xae\xce\x11\x71\x63\xbe\xbf\x0a\x64\x0d\x69\x8b\x1c\x81\x2d\x2a\x44\x33\xc7\x7a\x32\xa2\x5b\x87\x84\xf9\xfe\x6a\xfa\x0a\x99\xde\x5d\x8e\x88\x68\xf2\xfd\xd5\xc7\x1a\x7a\x30\x37\xe4\x03\xdf\xea\x21\xc7\xe9\x92\x43\x8e\xf0\x38\x73\x7c\x59\xc8\x60\xcc\x2c\x7f\x06\x18\x36\x50\x00\xe1\x5b\x64\xc1\x5a\xe4\xfc\xab\x39\x57\xc8\x95\xe5\x09\x11\xc8\x52\xcf\x19\x91\x60\x33\x70\xfe\x00\xd9\xd0\x1a\xa3\x27\x70\xf7\x2a\x18\x9c\x62\x60\x23\x72\x61\x84\x4f\x81\x0d\xca\xba\x41\xd6\x76\x7c\xb8\x85\xac\x09\x93\xde\xef\x1d\xd3\x2a\x82\x92\x80\x58\x1f\x8b\x84\xe0\x66\x3d\x85\xcd\xb0\xb3\xfb\x5d\xe0\x26\x67\x25\xf3\x64\x2d\x0d\xe8\xd6\x9a\x50\x06\xe3\x9b\xef\x77\x15\x74\xaa\x50\xd5\x48\x59\x0f\x3f\x8f\xdd\xff\x4d\x45\x2b\xe8\xc8\xcc\xb3\x6f\xb8\xdd\xce\x84\x23\xc1\x7b\xc8\x20\x16\x60\x21\xe4\x4e\x79\x06\x91\x33\xaf\x84\x72\x96\xba\x12\xa2\x33\x9b\xaf\xe4\xc2\x06\xf2\xbc\x34\x06\xda\x99\xfc\xe7\xa8\x67\x4b\xcc\xc0\x7d\xc9\xf7\xcf\x09\xf7\x2e\xdb\x89\x99\xa0\xba\x40\x46\x84\xd7\xd9\xe0\x01\x50\x56\x32\xa3\x99\x3c\x11\x6b\xe6\xc9\x39\xe1\x8d\x64\x72\xcc\xac\xd2\x43\x9e\x0d\x9f\x3c\x57\xcf\x13\x2b\x9c\xaf\x50\x62\x82\xa5\x29\x11\x1a\xb9\xc4\x1d\x1b\x2b\x71\x77\x01\x84\x6d\x2f\x51\xd8\xa3\xc4\x43\x51\x75\x2e\x88\x82\xfb\x8d\xfe\x19\xc1\x4e\x59\xf7\x4b\x85\xa7\xc5\x25\x66\x54\x97\xfb\x0b\x70\xe3\xf7\x1c\xa1\xf0\xac\xb7\x44\xe0\xbc\xc4\xca\xd0\xb7\xd0\xf4\x97\x58\x95\xbe\x77\x81\x47\xc3\x52\x36\xe9\x84\x1c\xf7\xfe\x0f\x8c\x5d\xe0\x81\x97\xfb\xeb\xdf\x54\xe6\xd0\xd4\x39\xa8\x0b\xf3\x87\x66\x24\xd0\x84\x25\xf2\xca\xa3\xdc\x5f\x5e\x8c\xa5\x94\xaa\x12\x7d\x48\x47\xf2\x42\xbf\xce\xf1\x3a\xcf\x03\x4b\xec\x7a\xa1\x70\x70\xe0\x41\x3f\xb5\xc4\xa1\xd8\x26\x2f\x1d\xcb\xfd\xf5\x01\x6d\x56\xe2\xa7\xa1\xc9\xcb\x3c\xc5\x50\xe8\x0e\x16\xd9\xd7\xee\x65\x57\x4c\xfb\xbd\x4f\xe6\x9e\xba\x4a\x9f\xe8\x21\xe0\x03\x24\x5c\x0a\x02\x7c\x4c\x81\x40\x09\xb0\xc3\xf5\x29\xf4\x53\x8a\xd4\xfb\x37\x14\xf1\x04\x95\x50\xe0\xbd\x9c\x53\x30\x2c\x3d\x80\x82\x2d\x48\x5f\xa3\x00\x41\x08\x4b\x50\x3b\x8c\xcd\x49\x31\x79\x25\xcc\xac\xb0\x3f\x05\x3a\xbd\xa8\xf0\xae\x85\xd6\xad\x00\x55\x9a\xe3\xc9\x82\x4c\x83\x51\x34\xaf\x95\x71\x93\xc4\xf1\x0a\xd6\xa1\x55\xff\xca\xc0\x39\x45\xad\x49\x28\xf4\x96\x8a\x02\x87\xda\x17\xb6\xb4\x73\xd8\xce\xb6\x90\xd8\xc2\xe5\x5a\x7a\xc0\x2d\xfa\x5f\x1c\x5a\x6c\x47\x66\x87\x41\x2f\x06\xce\x33\xd2\xdd\x60\x22\x8b\x65\xe1\x37\x04\xb1\xd8\x0a\x7d\x8b\x15\x0c\x8f\x20\x3f\x31\x15\x8e\x00\xf6\x2f\xb6\x1a\xc0\xa1\x29\x46\x0f\xab\x18\x6f\xc2\x8a\xd1\x0f\x06\x96\x99\x71\x7e\x77\xd6\x43\xd3\x14\xeb\x1c\xac\x33\x04\x2d\xc6\xeb\xcc\x42\xa1\x2c\xf7\xcf\x85\x9d\x18\xb8\x64\x52\x38\xe6\x8e\x46\x53\x10\x99\x14\x1e\x48\x96\x49\x8b\x59\x26\x44\x04\xd9\x13\x72\x33\x9f\xe8\x4f\xe2\xaf\x83\xd1\x32\x33\x21\x19\x7f\xde\xff\x09\x26\x9d\x8e\x05\x50\xc2\xee\xdf\x9e\x26\x30\x31\xbb\x10\x9e\xab\x50\xd9\xae\x67\x0b\xf5\xfe\x42\xe4\x57\xe3\x42\x1f\xec\x18\x72\x70\x0b\x6b\x5c\x61\x40\x8d\x60\xd0\x1a\x79\xe8\x5b\x63\x8f\x39\xd4\x38\x16\xc4\xb6\x6a\x1c\x9c\xb2\xde\x5f\xb3\x0b\xda\x5f\xac\xbc\x30\xc4\xc5\x63\xfb\x2a\xb0\x44\xf5\xfe\xe6\xa9\x4e\xa5\xe2\xaa\x72\x1a\x4b\x05\x7c\x52\xa9\xb7\x2b\xfc\x31\x64\x06\xc0\x1c\xac\xb8\xd8\xf8\x82\xfe\xa8\xbc\xe6\xa9\x90\xbe\xaa\xb2\x65\x94\xb0\xad\xde\xff\xc9\x8b\x09\xa6\x79\x8f\xd5\xe2\x92\x1c\xaa\x6d\x59\x5e\x31\x54\x83\x55\xa9\xf7\x0f\x99\xaf\x52\x3c\x2a\x83\xa3\xca\x73\xaf\x0a\x8f\xba\xda\xd0\xc4\x8a\x0b\xce\x47\xb5\x0b\xc4\xa8\xc6\x45\xcd\x4d\x42\x9d\x29\x86\x7a\xff\xa6\x2c\x28\xd9\xe9\x45\xf3\x20\xac\xd2\x07\xac\xb0\xf4\x80\xaf\x50\x27\xd1\xfb\x5b\xc0\xe5\x75\x0e\x4c\x68\xb1\x6b\x0f\xc6\x9b\x2b\xdb\xb4\x37\x24\x4f\xec\xc0\xe0\xa3\xda\x0a\x6b\x6d\xeb\xe2\xd8\xb5\x6d\xeb\x10\xcd\x36\x2c\x00\x01\x9f\x31\x4e\xb3\x74\x7f\x43\x91\x61\x4b\x50\x62\x06\xac\x10\x99\x96\x5c\x82\xa5\x11\x2f\x7c\x8f\xb9\x31\xcb\xd3\x4a\x4b\x3c\x44\x87\xe6\x07\xd3\x1a\x6d\x9b\x41\xa3\xd8\xae\xa0\x9b\xf1\x64\xc2\xd6\x39\xa2\x1d\x74\x41\x6d\x9d\x2f\xd9\xb1\xce\x68\x69\x27\x8c\xc7\xb4\x86\x68\xd0\x9e\x16\x2c\xc7\x60\x59\x20\x1c\x96\x0f\xa0\xcd\x32\xd8\x82\x57\x10\x3c\x98\xe6\x89\x9a\xe5\x0b\x44\xb1\xb2\x65\x3d\x2d\x18\x8c\xaf\xc1\x79\xb0\x86\x00\xd8\xda\x62\xc0\xfb\xa7\x01\x8f\xd6\xf8\x44\xc2\x96\x5f\xb9\xde\x58\xdc\x3f\x8d\x27\x23\xc6\x0b\x6d\x0b\xe6\x7f\x4c\xcb\x93\x39\x47\x92\xc3\xfd\xe3\x1b\xa2\x44\xaa\x4f\xc8\x2a\xaa\xe5\x19\x51\x71\x12\x67\x7e\xc2\x19\x34\x3f\x27\x68\x67\xbe\x8e\x18\xcd\xf5\x64\x5b\xea\x54\xc3\x36\xfd\xdf\x3a\x07\x36\xde\x51\x5b\x8f\x3c\xc5\xb4\x9e\x20\x5a\xd6\xe5\x85\xd1\x40\x0d\x8a\xa8\x0d\xaa\x09\x03\xcf\xda\xb5\x66\xbc\xc0\x02\xf7\xcf\x07\x37\xfe\x71\xbf\x4f\xe8\x0c\xfb\x5c\x13\xbe\xe0\x93\x37\x9e\xe0\x34\x9a\xc5\x16\x05\x73\x37\xc4\xe0\x35\x86\x06\x53\xd8\xe2\xfd\xee\x28\x7a\x46\x47\x2e\xf3\x8a\xad\xc5\x9c\x98\x83\x0e\x68\xf7\x57\xc6\x04\x8d\x97\x62\x2d\x66\x5b\x09\x88\xdd\x62\xc5\x2f\x66\xb4\xaa\xca\x4e\x95\x2e\x46\x8b\xf7\x7f\x3c\x9a\x6c\xb1\xdd\x5f\x80\x92\x01\xb9\xfd\x16\xff\xd1\x2d\x6d\x7c\x20\xd0\xa2\x33\x08\x6f\xd1\x65\x07\x54\x96\x19\xc6\xf4\x16\x39\x35\x70\xc5\xbc\xc7\x83\x79\xf6\xee\xec\x0d\xd5\xd3\xe2\xf2\xc3\x1a\xd8\xb7\x21\xe6\x0e\x2d\x2e\xa0\x28\xa0\x74\x34\x5e\x61\x35\x9e\x84\x34\x70\x70\x8b\x9f\x6c\x2f\x91\x57\xc7\x4d\x68\xb2\x1a\x58\x31\x22\x79\x20\xb3\x63\x77\x82\xa8\xa7\x51\xaf\x34\xd1\x2a\xa1\x49\xe6\x77\xde\x79\x7c\xd8\x24\x0b\xba\x64\x05\x07\x37\xc9\x59\x9e\x4c\x09\x20\xd4\x0d\xe6\xb3\x81\xf7\xd1\x6d\xdd\xfd\x35\x59\xd0\x50\xd4\x60\x34\x9a\xfc\x5b\x47\xb9\x6d\x2d\xc1\x61\x9f\x9b\xd0\x26\xb4\x75\x45\xd6\x84\xbe\x02\x22\xa3\xc4\x76\x99\x65\x45\xb9\x13\xe7\xf4\xde\x8d\xb3\x75\x02\xcc\x7e\x7f\x77\x58\xc1\x06\x8e\x83\x1f\xdb\xee\xef\x11\xb9\xba\xe1\xf7\x0f\xb4\x4d\x93\x17\x7e\x93\xb5\x3c\xae\x6b\x9a\x1e\x5c\xa0\x0a\x7e\x3b\x56\xa4\xf4\x2d\x9b\x72\x25\xfa\x84\xd7\xd8\x94\xa8\xd0\x6c\x60\x35\x2d\x4a\x9d\xb1\xb6\xa3\x15\x4e\x76\xd3\xca\xe6\x6b\x68\x08\x75\xd3\x86\x4f\x27\x8d\x94\x38\xd1\xce\x5b\xac\xc6\x7d\xd0\x5b\x6d\xba\xc8\xa2\x2f\xec\x20\xc7\x05\x2b\xc0\xe0\xe7\x27\x21\x86\xce\x02\x63\xdd\x32\x04\xa0\xd1\xc1\x6c\x79\x62\x6d\x99\xa6\xa3\xf1\xe2\xac\xc1\x35\x6d\x46\x5c\x52\x31\x35\x13\xb4\x31\xe9\x90\xbc\x66\x64\x77\xcb\x52\x01\x35\xad\x42\x48\x71\xb3\x0c\x76\xb1\x02\x2d\xd4\x8c\xa7\x37\x8d\xb3\x58\xc1\x46\xa8\x45\x9a\xf9\xd2\x17\x6d\xd9\xe8\x06\x91\x46\x65\x17\xd6\x76\x85\xfd\x6d\x06\x2d\xd8\x6c\xac\xd3\xde\x46\x81\x6e\x30\xd6\x8d\x17\x00\xcd\x25\xd9\x0b\xc9\x39\x89\x47\x97\xa2\x2c\x86\xda\x6c\x0e\xd5\xde\x5c\x2e\x96\x91\xa4\x7e\xbf\x6b\x82\x41\x6d\xae\x7f\x52\xe0\x0a\xf5\xde\xdc\xd0\x83\xaf\x74\x9a\x5b\x5a\x5d\x6d\x9f\xd4\x09\x6e\xa4\xa1\xdb\xc1\x87\x2e\xcd\xed\x74\x92\xd3\x0d\xcb\x74\x2b\x64\x1f\xa7\x8f\xd2\xdc\x1a\x67\x84\xb6\xe1\xa4\x53\x36\x70\xd1\xef\x96\xc9\x86\x33\x3d\x60\x5a\xda\x84\xa6\x6c\x70\x35\x90\xa1\x8e\xff\x53\xa7\x6d\xe6\x13\x99\x0c\x49\x9a\x99\x31\x4d\x9b\xb9\xb1\x06\x2b\x23\xbd\xf8\x4c\xa6\x81\x09\x33\x13\x64\x80\xe1\x09\x2e\x0b\x6d\xfa\xfd\x1d\xfe\x4d\x81\x17\xf1\x6f\x42\x0b\xfe\x9b\x52\x56\xc6\x85\x49\xb7\xf0\x6f\xd2\x6a\xc3\x31\x2f\xd0\xe8\x70\xba\x93\x20\x81\x9e\xf7\xfb\x8b\x77\x20\x1e\x37\x8d\x80\xf8\x5c\x94\xf3\xb8\x6b\x8a\x39\x38\x23\x04\xa2\xc3\x23\x28\xec\xeb\xbc\xcf\x11\x97\x06\xe7\xe1\x83\x23\x28\xdd\x99\x1b\x80\x9d\x35\x9d\x8d\x59\xf0\x09\xf0\x42\x96\x97\x9a\x2e\xff\x7b\x52\xe8\xf2\xf7\xda\xc0\x65\xbd\x6e\x71\xe1\x2b\x0e\x17\xbe\x62\x80\x29\x1c\x31\xf0\xc5\xc6\x0b\x95\xeb\x02\xd7\x25\xb9\x30\x3b\x08\x79\xbd\x07\x8d\xe9\xb2\xf3\x28\xd6\x65\x67\x0c\xe5\x72\x50\xfb\xb8\xac\xc3\x59\x97\xf5\x6a\xc7\xe5\x98\xa7\xa2\xfc\x84\xe4\x3b\x6f\x68\x5c\xce\x8c\x26\x27\x19\xcb\xe5\x71\x7f\xa3\x25\x84\x77\x1d\xc8\xd2\xb8\xb9\x64\xee\x49\xb2\x5c\x4c\x14\x6e\x88\x43\xcd\xb1\x61\xb6\x67\x70\xd2\xc1\x65\x45\x11\x3c\xdf\x77\xa9\x08\x77\x5d\x78\x68\xe4\xd4\x0b\x2e\x8d\x67\x03\x2e\x4d\x06\x4b\x9b\x71\xe6\x36\x34\x07\x97\x8e\x5f\x8a\x44\x47\x87\x42\x70\xe9\x4d\xd8\xa1\x2f\x38\x8b\x60\x89\x43\x1d\xd9\xc1\xa3\x2e\x47\xe4\xcd\xea\x59\x39\xe8\x75\x7f\x63\xa4\x8b\x8a\xc4\xe5\x33\x40\x77\x7a\xa0\xce\x74\xde\xef\xc3\x30\xef\x11\x09\x29\xa7\x47\x0c\x7e\xbf\x4f\x92\x54\x4f\x2c\x5b\x2b\x9f\x26\xb9\x2e\x6d\xcd\xd3\x68\xd7\x7f\x13\x72\xc3\x47\x33\xae\x03\xbb\x84\xea\xe1\x45\x8f\xf3\x9a\x0f\x92\x06\x00\xff\xc7\x6d\x5f\x10\x94\xb3\xf5\xba\xcd\x0d\xd4\xb4\xe7\xea\x01\x42\x19\x7d\x38\xb7\xd2\x58\x53\xf1\xc3\x3a\xe9\xc4\xb8\x35\x82\xd5\x04\xb3\xd2\xf7\x77\x63\x70\xeb\x7c\x0a\xe8\x73\xbb\xdf\x80\x58\x36\xbc\x45\x87\x88\x04\x9f\x24\x31\x4f\x01\x9c\x81\xa7\x2f\xbf\xde\xe1\x38\xf8\x44\x84\xeb\xb3\xb0\x53\xe3\x2b\x48\x9e\xb2\xfb\x1c\x68\xdb\x21\x27\xbb\x85\xce\x73\xd4\xce\x23\x9f\xce\xdb\x8d\x1e\x61\x1e\x7a\x3c\xe3\x0b\xd0\x57\xab\x1c\x01\xd6\x27\x16\xdb\x23\x44\xbd\xc7\x25\xea\x3d\xe6\xbf\xa4\xb3\xdd\x60\x83\xb9\x03\x5e\x1c\xad\x6c\xa8\xf8\x3b\xc1\xef\xb1\xd2\x1d\xea\xb1\x0a\x6b\x2b\x22\x94\x1e\x2b\x05\x87\xc7\xbc\x9d\x87\x15\x3d\x36\x00\xf8\x07\x3d\xfa\xce\x85\x47\x1f\x60\xe3\x1e\xfb\x60\x27\x3e\xa7\xe9\xbc\xe4\xe9\xf1\xc3\xf8\x3c\xa9\xff\xef\x38\xa8\x4b\x32\x00\xb0\x12\xd2\x11\x43\x97\x3d\x74\x39\x27\x96\x2f\xda\x43\xe7\x25\x7e\x97\x7c\xa1\xae\x20\x9e\xef\x52\x48\xcc\x4e\x26\xea\x52\xa1\x43\x79\x3f\x98\x99\x30\xb7\xfc\x9b\x2e\x4d\xd1\xe4\x1f\xcf\xaf\x3b\x70\x29\xae\x02\xb8\x30\xb3\x0e\x89\xbb\x74\x0a\x48\xff\x3b\x52\xea\xc2\xcc\xf8\x2b\xbc\x88\x52\xf9\x20\xc0\x4a\x15\xf6\xb8\xaf\xeb\xa2\xae\x70\xa7\xba\x9e\x58\x26\x2f\xae\xfb\xfd\xce\x11\x08\xd5\x0c\xf5\xdf\x35\x0b\x5f\x82\xf6\xb5\xea\xfb\x5d\x36\x63\xe3\xc2\x42\x87\x77\xd2\xb5\x0f\x18\xc4\xce\xe3\xa1\xae\x7c\xa6\xdc\x69\x3a\x3b\xbd\xff\x4e\xab\xd9\x2d\xe3\x17\x5b\x44\xb2\x93\xf8\x96\x79\x73\xdc\xef\x1f\xfa\x8a\xdd\x78\x29\xd7\x2d\xcf\x3f\x24\x1b\x0f\xc9\xbb\x55\x48\x42\xb7\xba\x5a\x55\x38\xc2\xdd\x2a\xa5\xa9\x1b\x47\x6c\x99\x3d\xd7\x6b\x81\xce\xab\x89\x6e\xbe\xee\x79\x3b\x0a\x91\xef\x8b\xc0\xf7\xcf\x20\x27\x4c\x04\x83\x7d\x6e\x40\xe3\xa4\x9d\xeb\x34\x44\x7d\xca\x89\x69\xe9\x89\xf6\xe5\x59\xf5\x15\xfa\xf6\x79\x38\x9b\x33\x3c\xea\x33\x2f\x26\xe1\x3d\x52\x9f\x70\xbf\x98\x92\x85\xe7\x32\xf0\x7d\x36\xaa\xb5\x3e\xf1\xed\x89\x5f\x7f\x63\xfa\xc9\x86\x9d\x63\x41\x93\x8d\xc8\x27\xea\x23\x6e\xd0\x18\x48\x73\x04\xbc\x7f\xc3\x58\x15\xd0\xe3\x7c\x0f\x3a\x22\xb6\x3c\xe8\x74\x8f\xb8\x4e\x1b\xd7\xeb\xc5\xb1\x84\x66\xc4\x42\x3b\x31\x62\x81\x84\x0f\x5a\xa1\x11\xeb\x1a\xb8\xa1\x5d\x03\x03\x8c\x08\x4e\x1b\xb1\xad\x4e\xff\xa6\xae\x41\x7c\x47\x9d\x0b\xbf\xa1\xe8\x46\xf4\x27\xd8\x6b\x44\xb7\x01\xe8\x18\xcf\x59\x32\x66\x7c\xa2\xf9\x64\xd9\x0b\x45\xb4\x5f\x43\xf8\xca\x65\xd0\x2d\x1e\x92\x30\xf2\xfd\x9d\xf8\x46\x66\xc8\x13\x6c\x30\xe4\x29\x0e\xa8\xcc\xa0\x85\xe4\xfb\xfb\x40\x24\x42\xce\x1a\x02\x65\x33\xd6\x63\x81\x21\x35\xbe\x00\x77\x76\xaa\x0b\x6a\x07\xec\xa8\x36\x5e\xbe\x21\x9c\xe0\xb6\x04\x18\x1f\xf7\xb7\xf3\xd9\xdd\x10\xaf\xd0\x58\x03\x2e\x2f\x7a\x76\xf6\xec\xc6\x35\xf6\x81\x20\x70\x08\x63\x91\x41\x81\x19\xf2\x0a\x43\xa1\xc4\x86\x6e\x93\x27\x6a\x43\xa5\x34\xe4\x29\xc4\x43\x79\xcd\x34\x14\xfc\x33\x14\xfa\x66\xe8\x93\x03\xf0\x02\x64\x28\xcf\x86\x07\x9c\x0a\xec\x0f\x7e\xd0\xe0\xa3\xaf\x01\xcb\x30\xee\x77\x83\x75\x19\xca\x21\xd9\xed\x6f\x16\xb2\xd6\xb8\xdf\x43\x56\xff\x01\xf5\x3b\x14\xb8\xb5\x45\x67\xdb\x18\xe9\x0f\x83\x62\x1d\x96\xb8\x43\xc3\x2c\x76\xa2\x3a\xf3\xb3\xb0\x92\x55\xe4\x11\x6b\x2c\x68\x12\x06\x5f\xb5\x8d\xfb\xc7\xe3\x47\x18\xc6\x30\x7f\x98\x17\x2a\x0f\x98\x48\x61\x9e\xa0\x09\x07\x73\xac\x85\xcf\x4c\x86\xf9\x98\x9c\xa6\xe3\x87\x3d\xf0\x6d\xd5\x80\xb3\x87\x9c\xc7\x8d\x7c\xea\xeb\x3e\x7e\xbd\x48\x1e\xff\xbb\x0b\x1c\x8e\x48\x72\xf0\xf6\x73\x78\x2c\xfc\x86\xbf\xb5\x4c\xf2\xf0\x08\xcf\x6e\x38\x5f\xdb\x0e\xbf\xbf\x37\xcb\x61\xc0\xbf\x45\xa9\x2c\x0c\xba\x54\x00\x6e\x08\x4e\xc0\x70\xdd\x26\x20\x87\x46\xb4\x30\x9c\xcf\xf8\x86\xeb\xac\x07\x0a\xed\x10\x26\x85\x95\xb4\x98\x83\xc6\x72\xf0\xe1\xea\x70\x38\xd5\xc3\x27\xcb\xf9\x4c\x75\xf8\x04\xf3\xcf\x6d\x5d\xeb\x8e\xb9\x59\x18\x93\x6f\x14\xc6\x84\xf9\x19\x34\x86\xe3\xfe\xad\x92\x99\x90\xb9\xa7\xf3\xf9\xe9\x98\xce\xd3\xc1\x31\xe1\x71\x0c\x3e\xaf\x9e\x1b\x23\xa5\xfb\x37\x33\x66\x9c\xd0\x72\x39\xcc\x65\xa5\xe8\x8a\xcc\xaa\x17\xe2\xb1\x30\x2b\x7e\x50\x8b\x0c\xb1\xa6\xd3\x09\x9d\xbe\x49\x98\xbe\xae\x7c\x27\x62\x2b\xfe\x0d\x64\xf6\xc9\xe7\x4a\xeb\xce\x69\x0e\xe3\xab\x8f\x79\xc5\x70\x21\x0c\xba\x62\x02\xcb\x5d\x91\x6f\xc2\x2e\x3e\xe4\xbf\x40\x85\x2b\x2a\x0b\xd6\xd1\xed\x15\xb3\x84\xeb\x2f\x7e\xbf\xf8\x6e\xea\xe2\xa3\x56\x94\x5d\x93\x2d\x4a\x83\x1f\x75\x45\x47\xc6\x95\x03\x91\x6d\x2f\x84\xc6\x97\x90\x15\xaf\x75\x59\x72\xc9\xe3\x7e\xf3\xc0\xef\x02\xd9\x24\x5c\xf2\x94\x57\xe0\x21\xd6\x25\x34\xfa\x97\x64\x43\x09\x56\x21\x7c\x11\x7b\x51\xb8\x2e\xa9\xc2\x81\x2a\xd7\x2a\x40\xcd\x45\xee\xbc\xa4\xce\x1e\x2e\xb6\xe4\xad\xf2\x25\xbe\x11\xee\x98\xc0\x85\xbd\xfd\x49\xc8\x25\xf9\x40\x63\x20\xe4\x52\x30\xdd\xa5\x1b\xb4\xf5\xc5\xa3\xa4\xeb\x7e\x27\x5e\x0c\x5d\x8a\x8e\xf7\x1b\x06\xe7\xd2\x1d\xd8\xbc\x14\x7e\x31\xef\xef\xa4\x87\x8b\x5e\xde\xa5\x19\x3f\xec\x40\x6b\x84\xd0\xf3\xc5\xd6\xa5\xf7\x7f\x90\x93\x4b\x2d\xdf\xef\x1a\x2e\x05\x61\x2f\x75\x20\x59\x7d\xcc\x3d\x5c\xda\x89\xca\x77\x67\xb0\xbe\x5c\xcd\x4b\x47\xe4\x09\xe0\xa5\x93\xdd\xaf\xf8\x02\x24\x6e\x14\x76\xfe\xd2\xcb\xc2\x65\x99\xf7\xa7\x97\x65\xba\xb3\x97\x65\x62\xc0\x1c\xcd\xe9\xd3\x5d\x08\xa7\x2f\x20\x93\xd6\xeb\x9a\x7c\x98\xf9\xc9\x0b\xec\x4f\xf8\xc7\x9f\x94\xa0\x4f\xe8\xd5\x4f\xde\x48\x7e\x42\x71\x7d\x42\x6b\x7c\x42\x6b\x7c\xda\x39\x3d\xbc\xe2\x01\x02\xbf\x78\xd4\xfa\x8a\x0d\x22\xf9\xe2\x1b\x85\x97\x55\x00\xe8\xfe\xd7\x2c\x00\xb0\xb5\xff\x1f\x00\x00\xff\xff\x11\x91\x1a\xde\x5b\x35\x00\x00") +var _keysWordsWordlistSpanishTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x34\x5b\xbb\x76\xfc\x2e\xaf\xed\x79\x4b\x8c\x65\x8f\xe6\x00\xe2\x27\xc0\x2b\x99\xb7\x49\x99\x62\x8a\xff\x4a\x97\xd6\x2f\x76\xd6\xde\xe4\x2b\x46\x98\x3b\xe8\x2e\x60\xee\xaf\x2d\x26\x0b\x71\xdb\xad\x48\x0d\x71\x93\x67\x0c\x71\x53\xf1\x81\x52\x3b\xe3\xce\xb4\x12\xae\x42\x8f\x2f\x26\xea\x21\x6e\x53\x32\x32\xb3\x5b\x88\x29\x6e\xd1\x91\xec\x52\x34\x86\x98\x92\xb0\x38\xe9\xfd\x53\x43\x4c\xa2\x43\x90\xe4\x13\x95\x52\x31\x5a\x92\x36\xa2\x87\xfb\x2b\x29\x66\x4a\x39\x3a\xc7\xa8\xf7\x77\x88\xc9\x4e\x41\xc6\x38\xcc\xd0\x8b\x09\x81\xeb\x0b\xc9\x64\xe3\xb9\x2b\x13\x71\x8e\x31\x3b\x4a\x77\x65\xd3\xbd\xe8\x40\xed\x6e\x9c\x28\xee\xe6\xd8\xcc\x3e\x63\x8d\x48\x32\x1a\xdd\xdf\x2e\x16\xe2\x21\x89\x6d\x0e\xfd\x5b\xf2\xa1\x75\xe5\xbd\x70\x91\xa7\xe6\x10\x4f\x65\xa3\xd3\xea\xfd\x8e\x48\x3b\x86\x38\x6d\x95\xba\x9c\x2b\x55\x14\x4e\x34\x98\xbb\xa1\xef\xd4\xcc\x1c\x30\xfc\xb0\xd3\x00\xdd\x2d\x44\x75\x09\x51\x7b\x46\xbf\xa7\xec\x2e\x2f\xa4\x58\xe5\x73\x76\xa0\x2c\xc7\xe4\xf7\x57\xc5\x47\xd9\x9c\x05\x5e\x62\x88\x79\x8b\xe1\xfe\xca\xdb\x2c\x21\xe6\x14\xf3\x8e\xaa\x5d\x50\x23\x27\xdb\xc9\x13\x83\x66\xf1\xc1\x42\xc2\x43\x33\xb0\x4a\x2a\xe4\xd3\x76\xee\x34\x2b\x29\x9d\x75\x91\x25\xeb\x85\xf5\x67\xce\x52\xc8\x14\xb9\xdc\x6f\xd2\x37\x8f\x05\xe5\x85\xd2\x45\x15\x62\x31\x8f\xe9\x28\x9a\x05\x6b\xcf\x2f\x34\x2b\x71\xcb\x82\xa4\x0e\x26\xcd\x80\x84\x12\x1d\xfb\x2f\xb1\x13\xad\x65\xfb\x4b\x14\xc3\x14\x6e\xbd\x28\x5b\x68\x1f\x71\x0f\xb1\x18\xc6\x6a\x11\xe8\x2a\x2d\x63\x6d\x35\x3d\x08\x35\x56\xa6\x18\xb7\xee\x98\xb3\xee\xf7\x77\x0d\xb1\x92\x0b\xef\xaf\x7a\x4e\xf0\x68\xd5\x9c\x41\x87\xaa\x05\xb9\xfb\xdd\x43\xac\x8b\x68\x75\x08\x98\xa1\x0e\x3d\x27\xea\x86\x3d\x91\xcc\x98\x01\x49\x97\x3a\x6b\xc2\xac\xf7\x7f\x91\xcc\x76\xff\x27\x4f\x66\x2d\xc4\x16\x49\xf2\x16\x3d\x62\xfd\x4d\x06\xf7\xd1\xd0\xbe\x65\x4d\xac\x34\xa0\xb7\x99\x03\x0d\xcd\x3e\x91\x71\xa9\x3b\x28\xd1\xdc\x88\xd8\x36\xa5\x83\x42\x6d\x62\x9b\x4e\x82\x38\x66\x0c\x14\x8a\xfb\xcb\x37\x1d\x6e\xfc\xb0\x1c\xa2\x6f\x93\xac\xe7\xe9\x41\x22\x38\x24\xd9\x39\xa4\xef\x9a\x81\x10\xdf\x27\xdb\x0b\x10\xe1\x14\x31\x57\xe9\x21\x7a\xf9\x63\x5f\xaf\xf7\x37\xf2\x06\x52\x7b\x23\x20\x47\xb8\xcb\x09\xbc\xb9\xdb\x0b\x70\x82\x5f\xb8\x7c\x1f\xca\x75\x76\xfe\x30\x66\x5f\x0c\xd0\x93\x54\x88\x6a\x97\x73\x52\x8c\xbb\x30\xd7\x41\xbd\xfe\xc7\x5a\x5d\x33\x61\xa7\x58\x76\x10\xaf\x5b\xd9\xb8\xaf\xde\x04\x5b\xef\x63\xad\xbe\x8f\x95\x9b\xec\x37\x0b\x3b\x4c\x8e\x32\xe2\x93\xf0\xdf\x14\x24\x1e\xe2\x58\xc3\x0f\xc1\x40\x43\x81\x8b\x41\x8e\xbf\xbf\x86\x81\xe4\xc3\x23\x50\x33\xb8\x9f\x71\xff\xd6\x10\xe7\x1e\x5f\x80\xa0\xd4\x3c\x25\xc4\x89\x69\x67\x59\x43\xcd\x2e\xe4\xda\x39\xb0\xfe\x0b\xdc\x70\xc5\x9a\x04\x09\x16\x76\xe1\x4b\x72\xa6\x26\xb9\x64\xc1\x3e\x7c\xbe\x42\xbc\x96\x02\xb9\x14\xf8\xf8\xc4\xbc\x9f\x73\x8f\x80\xd8\xf0\x2b\x1e\x4b\xa0\x29\x23\x2f\xc3\x2c\xaf\xfb\x97\x9c\xf2\x9a\x07\x44\xf7\x35\x73\xd8\xe2\x16\x01\xcc\xc3\x16\xd3\x43\xc2\x16\x1f\x20\xda\x16\x35\x23\x03\xe1\xde\x62\x8e\xf5\x85\xb2\x9c\x30\xe5\x46\x35\xb0\xc5\xb2\xdd\xbf\x61\x8b\x35\x19\xe0\x8e\x06\x60\xd6\x2d\x3a\xc7\x74\x96\x7b\xd5\x17\x12\xb7\xb0\xdd\x5f\x3d\x61\xfb\x5b\xec\x63\x0d\xd4\x21\xce\x5b\x1c\x31\xb3\x78\x88\xaf\xc9\x41\xb8\x2d\x8e\x39\x38\xe8\x2f\xd6\x89\x7d\x6c\xb2\xdd\xdf\x80\x8a\xd9\x04\xd2\xb6\x49\x67\x45\xe7\xe7\xd0\x18\x36\x85\xd8\x6e\x2a\x35\x6c\x5a\x4f\x0b\x5b\x5e\x6b\xcc\x06\x52\x6e\x79\xf6\x18\x36\xc3\x6f\xd3\xca\xc4\xc2\x66\x09\x5f\x69\x15\xec\x04\x72\x22\x59\x25\x99\x00\xac\xb3\x59\x66\xff\x82\x4d\x5a\xdd\xe3\x8e\x04\xe2\x48\x1b\xb6\x59\xed\xf7\x97\x86\xcd\x1c\x48\x32\x07\x97\x6e\xd6\x39\x35\xa8\xb0\xd9\xb8\xdf\x35\x6c\xf7\xcf\x25\x9c\xe7\x15\x73\xd8\x3c\x5e\x16\x96\xdd\xdb\x5c\xd2\x23\x22\xb9\x24\x6c\x4e\x9d\xb2\xb9\x72\x0b\xae\x98\xdb\xb9\x58\xca\xd3\xe6\x06\x76\xd9\x9c\x43\x3b\x34\xff\xe6\xb3\xb3\x2d\x78\x7a\x9b\x49\x08\x41\xcd\x09\xb5\xb7\x4d\xf9\x0c\xdb\x3c\x16\xc5\xe6\x41\x42\xdc\xbf\x40\xd9\xd4\xe1\x68\x96\xd9\xd1\x37\x8e\x36\x3d\x13\x62\xeb\xb3\x83\x7f\xb6\x39\x22\x16\x30\x5f\xe8\x0b\x93\x8c\x25\xa6\xb8\x41\x5d\xa7\x48\xa4\x26\x18\xf1\x90\x62\x8a\xa8\xd9\xef\xaf\x4b\x1c\x1f\xc2\x3a\x7e\x1f\xf7\x77\x48\xf1\x7e\xef\x28\xd1\x02\x66\x4d\xf1\x89\xcc\x73\x8d\x9b\xf1\x83\x22\x47\x0a\xd5\x08\xfb\x43\xa8\xc0\x7a\x8a\x39\x0b\x60\x41\x9f\x6c\x6c\x76\xa1\x9e\x05\x65\x63\x8f\x22\x6b\x71\x45\x2b\x93\x66\x21\xdd\x5f\x35\x71\x09\x75\x57\x4c\x52\x25\xa3\x47\x3d\xa1\x15\x53\xac\x9a\x98\x1d\xc8\x40\x37\x02\xae\x25\xd9\x86\x9c\xf5\x90\x62\x8b\x2f\x40\x1d\x6b\xe1\x0d\x04\x48\x91\x1e\x40\x8a\x6d\x82\x84\x29\x12\x07\xbe\xb1\xf3\xfd\xe5\x49\x30\x9d\x43\x65\xa4\xe8\x27\xa1\x42\x66\x52\xf4\x8a\xee\xde\xfe\xea\xb8\x10\xe7\x77\x27\x48\x28\xe8\xc2\xf2\xde\x58\x34\xb8\xe5\x61\x9e\xd0\x15\xa4\x4b\x50\x37\x98\x62\xb2\xd3\xcb\x42\x92\xcd\x20\x5b\x49\xa0\xb4\x93\xec\x18\x40\x32\x70\x7e\x7f\x67\x81\xa9\x4f\x92\xe1\xfd\x20\x3f\xd9\x72\xe9\xa6\x24\x55\x41\x4f\xa9\x83\x7d\x1c\x48\xa1\xfb\x93\xc4\x49\x69\x59\xe5\x60\xf0\x24\x4e\x63\x9d\xee\xef\xde\x64\x0f\x49\xd8\xe9\x11\x49\xc5\x47\xcc\x92\x98\x2d\xed\xfe\x45\x4a\x5b\x9a\x1e\xb1\x11\x3a\x33\xca\x26\x0a\x77\x64\x59\x9b\xf4\xa0\xc0\xa6\x87\x61\xe4\xc7\xa4\xaa\x4d\x8f\xd9\x30\xa1\xa6\x4c\xac\xaa\x9c\x06\x98\x09\x59\x00\x1f\x32\xe9\x01\xdc\xeb\xb9\x50\xa9\x60\x09\x8a\x50\x52\x20\x5a\x2b\x86\xd2\xe6\xb0\x4c\x49\x9d\x15\x3e\xc9\x07\xda\xd9\x82\x0d\x26\x19\x2d\xd3\x39\x48\x39\x56\x00\x8c\x97\x63\x17\xc0\x0b\x50\xa9\xc3\x53\xe6\x24\xf9\x7e\x2f\xfe\x31\xe2\xd6\xfe\x5c\xd3\x64\xe9\x41\x0e\x5c\x2a\x26\x19\x66\xbc\x7f\x76\xb8\x20\x09\x86\x3b\xd9\xc1\xf6\x70\x47\x93\x3d\x04\x23\xda\x13\x9a\x22\xc1\x55\x48\xd0\x40\xc9\x32\xd9\xca\xb2\x9c\xca\x32\x78\x05\xc9\xf2\x1a\x32\xe7\x95\x2b\xac\x9a\x85\x85\x05\x5a\x15\x29\xc7\x2d\x4a\xca\xff\x94\x35\x65\x69\x40\x92\xd5\x1d\x2d\xaa\x70\x9e\x7a\xb2\xc8\x28\x21\x56\xfb\x5f\x29\xf9\xda\x40\x2f\x6b\x0a\xe8\x71\x89\xbf\x39\xf4\x37\x52\xa8\xdd\x64\xbe\xff\x15\x1b\xe7\x77\xe7\x38\x7d\xc1\x02\xd1\x31\x98\x76\xba\x9b\x62\x4c\x07\x2a\x5d\x22\x61\x5a\x99\xfb\x8d\x15\xba\x14\x36\x7d\x03\x2a\xe2\x87\xe4\xda\xd8\x5d\xbb\xf6\x90\x1c\x76\x37\xf9\xfd\xb3\x90\xee\xe0\x18\x56\x4f\x76\x9f\xaf\x90\x66\x24\xd3\xcf\x48\xbe\x98\x91\x9c\x39\x37\x02\x44\x18\x09\xb2\x0a\x3c\xcc\xa5\x2a\xe6\x62\x7f\xb8\xfa\x2c\xe4\x6a\xa7\x5c\x80\x0a\xef\x2f\x4d\x08\x0e\xb2\xb9\x11\xb2\x39\xdd\xe6\x34\xe1\x3a\xa2\x09\x36\x3f\x2b\xd7\x32\x8d\xb0\x2d\x2d\xf0\xdb\x28\x65\xf4\x5e\xd2\x74\xa5\xec\x4d\x5f\x90\x93\x0c\xed\x61\x87\x12\xdb\x69\x76\x31\xe5\x1e\x21\x78\x3b\xbc\x8e\x1c\x76\xd9\xc4\xc3\x7e\x7f\x6f\xc8\xdc\xdf\x29\xee\x31\xec\x92\xd4\xc3\x2e\x68\x26\x87\xd4\x8e\xa2\x43\x2b\x0b\x61\xc5\x77\xc9\x07\xd8\x69\x47\x70\xc4\x56\x19\x46\x6b\x97\x62\x8e\xb6\x70\xab\x76\xa9\x23\x62\x82\xe5\x45\xee\x02\x53\x84\x62\x77\xec\x61\x97\xbe\xbc\x8b\x5d\xe0\x76\xed\xd2\xe1\xe8\x23\xad\x93\x23\xf6\xa1\xab\xf6\xba\xdf\x48\x07\x55\xf4\x2e\x43\x2a\x56\x2c\xf0\x4f\x76\x10\x73\xd7\xb8\x65\x43\xb2\x83\xc2\xbb\xfe\xb9\xef\xbb\xc2\xd3\xd9\x35\x22\xb6\xd9\x75\x9b\x4f\x24\x0c\x99\xf6\x25\x66\xbb\x02\xa7\xbb\xca\x2b\xec\x7a\xdc\xef\x04\x1c\xe8\x89\x69\x35\xaf\xb1\xf2\xc4\xa6\xb5\x42\x3f\xed\xea\x82\x20\x6d\x57\xd7\x93\xc5\xd0\xa4\xbb\x76\x81\xda\xdd\xb5\x1f\x1e\x31\xd2\x85\x8e\x17\x57\x6f\x08\x27\x76\x4b\x00\xb0\x2a\xbb\x15\xba\x11\xbb\x55\xfc\xb0\x14\xa3\xe7\xbc\x9b\xc3\x5f\xdc\x0d\xc4\xdb\xad\xe3\x07\xd2\x79\x3c\x41\xea\xdd\xed\x8c\x61\xa7\x25\xd8\xb9\x73\x46\xb2\xfb\x5c\x53\xcf\x8c\x19\xee\x5f\x7c\x42\xcd\xed\xe4\x88\x7d\x52\xb7\xee\xb0\x44\xf7\xf7\x86\xc0\x43\x36\x20\x03\x3e\x81\x07\xa8\x51\x01\x47\x9b\x07\x81\x6e\x92\xfd\x2f\x90\x94\x5d\x11\x53\x1a\x3e\x06\x6b\x27\x6c\xb5\x1c\xdc\xbe\x1c\x9a\xe2\x2b\xc8\x53\xf0\x2b\x2d\x5b\x90\x2c\x07\x71\x2e\xd0\x26\x8e\x64\x29\x7e\xc9\x72\xa1\x67\xd6\xd6\x25\xdc\xdf\x59\xd9\x48\x3f\xd8\xc8\xa0\x79\x24\x33\x1e\x96\xb2\x81\xee\xb2\xe2\x5f\x29\xf6\xb7\x94\xd2\xa0\x73\xa4\x34\xee\x14\xd3\x09\x13\x97\x1e\x83\x54\x6e\xaa\x26\x06\x68\x52\xd3\x63\x1e\x82\x14\x7c\x21\x88\xa8\x58\x0c\xe2\x49\x3d\x80\x67\xa9\x87\x78\x41\x7a\xd2\xc1\x94\xaa\x67\x41\xdb\x1c\x13\x7a\x9a\x17\x24\x2e\x6c\xdb\xe3\x27\x13\xb9\xff\xc3\x2e\xea\x58\x23\x0d\x67\xee\x82\xe2\x96\x4a\xfe\xbc\xbf\x1b\x1c\x29\xf9\x37\xb5\x59\x10\xd7\x97\x05\xe9\xf0\x39\x90\xc0\x53\x91\x0e\xbd\xeb\x48\x5d\x37\xe5\x07\x77\xdc\x05\x51\x61\x90\x7e\x88\x33\x99\xe2\xec\xdd\x20\x8b\xd2\x1b\xb4\xa6\xf4\xc6\x3d\xf5\x66\x9d\xc9\xc4\xaa\xfb\xbf\x79\xbf\x03\xb4\x0a\x86\x03\x9e\x10\x8b\xa0\xf5\x98\x47\x0c\x32\x60\x14\x65\x88\x57\xac\x70\x40\xad\xc9\xa8\x98\xec\x62\x5c\x28\x57\xcc\x13\x7d\xaf\x45\xad\x8b\x67\x05\xf2\xc1\x63\x0b\xf9\x40\x6c\x1b\xe4\x83\xe7\x22\xf2\x91\xe0\x08\xc8\xc7\x6a\xf9\x41\x09\x90\x0f\x45\x70\x2b\x1f\x2b\x3c\xba\xbf\x3f\x94\x95\x8d\x76\x53\x3e\xfe\xc2\x49\xf9\x68\x06\xa1\x95\x8f\xe1\x52\x2c\x1c\xf7\xd7\xe6\x58\x0c\x3e\xa0\xc1\x8e\x98\x1e\xd8\xec\x71\x7f\x41\x06\x0f\xcc\xef\xe1\x88\xc0\xdb\x01\x3f\xee\x88\x70\x33\x0e\x3a\x87\x47\xcc\x9d\x10\x6b\x3d\xa0\xdb\x8e\x58\x34\x2b\x53\x63\x95\x47\xf0\xce\x11\xbd\xc4\xc4\x72\x37\x8c\xea\x1d\xdf\x5d\xc2\x11\x87\x9e\xf8\x9e\x9c\xe0\xe2\x64\x1f\xe1\x80\x0f\xe3\x16\x0e\x3a\xcd\x87\x64\x7d\x85\x43\x90\x77\x8c\x22\x08\xc5\x8e\xfb\xdb\xa1\x38\x0f\x71\x76\x93\x4e\x17\xfc\x50\x9e\x1c\x1c\x4a\x35\x7b\x28\x96\xa6\x50\xec\x87\xfe\x59\xed\x43\x39\xa8\xee\x18\x50\xe9\x2d\x1d\x2a\x19\x80\xcd\x68\x1b\x0e\x45\x28\x1a\x0e\x7d\x72\x80\x27\x9a\x02\x3f\x9a\x61\xc4\x0f\xec\x12\x3d\x32\xec\xce\xa1\x18\xb4\x02\x8d\x5a\x41\x0d\x68\xe8\x81\x72\x07\x4e\x72\x4c\x06\x88\xb8\xe7\xc8\x6b\x47\x50\x41\x47\x36\x96\x40\xb1\x1d\x19\x4a\xf1\xc8\xf7\x2f\x2a\x6c\xc3\x2e\xc1\xc6\x87\x9d\xb0\xc3\x87\x51\xf9\x1c\x06\x22\x1f\x96\xb3\x60\x78\xab\x3b\x20\x27\xe1\x89\xd0\x61\x3e\x88\x48\x73\x04\x56\x07\x38\xf4\x30\x34\xf5\x98\x22\x08\xe2\xeb\x2c\xea\xf0\x58\x41\x4c\x27\x0d\x3c\xce\x1d\x89\xdc\x6f\x47\x52\xd1\x10\x52\x7d\x38\x24\xea\x70\x6e\xc6\xb9\xfe\x09\xcf\xec\x98\xd4\xda\x94\x0f\x94\x81\x82\x13\x2e\xfd\x31\xeb\x1f\x8e\x27\x02\x91\x63\xfa\x5a\xf7\x24\xd9\x66\xc7\xd4\xf7\xef\xd8\xc0\x04\x73\x40\x1d\x9e\x31\xc1\x3f\x3b\xe3\x11\x7b\x38\x23\x1c\xb4\x13\x21\xfa\x19\x59\x9a\x57\xec\x78\x92\xdf\xce\x88\xf0\xec\x8c\xd0\xd6\xe7\x3a\xc7\x39\x23\x3c\x9b\x33\xc2\xce\x9d\xd1\xe3\x53\x90\xbc\x50\xd4\x97\x07\x75\x46\x0a\xe5\x19\x07\x5a\x5c\x9a\xe1\xd9\x9f\x52\xa0\xb5\x4f\x81\xaa\x3f\xa5\x86\xf3\xfe\xa6\x72\x3a\xa5\x2a\xe1\x90\x70\x8a\xc7\x95\xf3\xff\xe5\x21\x86\xa7\x74\x0c\xa5\x27\xf5\xec\xa9\xa5\xc6\x8e\x56\x0a\x5d\x74\x2a\x06\xc9\x60\x76\x0f\x67\x46\x10\x7a\x66\xc3\xee\x4f\xcb\xf8\x1d\x06\x08\xe1\x38\x2d\x37\x09\x27\xe2\xbd\xd3\xe0\x08\x9c\xe6\x60\xb1\x13\xd1\x65\x38\xc1\x1b\xa7\x0d\x41\x39\x88\x79\x3a\xe4\xf2\xf4\xfb\xeb\x80\x4f\x7d\x3a\x14\xee\xe9\x08\x24\x4e\x8f\xf0\x2e\x4e\x87\xe7\x7a\x3a\x6d\xe9\xb9\x42\xcc\xd3\xb5\xb1\x0c\xd5\x20\xe3\xe9\xd6\x0d\xa3\xdd\xbf\x68\x34\xa1\x51\x4e\x9f\x85\xb0\x59\x38\xe7\xda\xd6\x8c\x2b\xe3\x3b\xd6\x3e\x85\x6b\x9a\xa4\xc5\x64\x70\x73\x4e\xb5\x0a\xd8\xf9\x3d\xe2\x6a\xd1\xb9\xac\x49\x9c\x3f\x22\x5c\x9a\xc7\xfd\x05\x97\xe6\x11\xb7\xcc\x32\xb8\x82\x0f\xa8\x99\x40\x4d\xf3\x88\x79\x95\x17\x84\x9f\x8f\xe8\x20\xda\x23\xbe\xf0\x63\x9c\xf6\x90\x8d\xa7\x3a\x0f\xba\x67\x0f\xfa\x2e\x0f\xc9\xb0\x21\x0f\x81\x3c\x3c\xa4\xac\x1a\xf8\x7d\x0f\xf1\x82\x25\x3c\xee\x6f\x37\x41\xf6\x42\x29\x43\x89\x87\xc2\xe5\x09\x8f\xfb\x4d\x5f\xe9\xa1\xa7\x4a\x95\xf0\x80\x74\x3f\xb4\xa0\x97\x22\xfe\xd2\x18\x1e\x96\x80\xe5\x87\xc1\x17\x7f\x18\x10\x80\xc2\x27\x00\x7d\xc2\x87\xc1\x7b\x78\x58\x35\xd4\x57\xd6\x2e\x50\xa0\xd0\x1e\x3c\x2d\x7e\x18\xac\x40\x78\xd8\xa7\x85\xc7\x84\x99\x7f\x4c\x9e\x62\x3f\x26\x4f\x56\x1f\x44\xff\x63\xca\x05\x08\x2f\xfe\x01\x65\xf0\x98\x7f\x5b\xf8\x2d\xb0\x7e\x8f\x59\x34\xef\x82\x14\x99\xba\xb3\x89\x47\x44\xbc\xf8\x18\x16\x14\xbe\x7d\xd0\x5d\x62\x0e\xba\x2b\x78\x0a\xae\x76\xb6\xa0\x67\x96\xae\x11\xe9\xfd\x1b\xf4\x9c\x68\x91\xe5\x64\x32\x3b\x85\x55\x4b\x84\x0c\xac\x68\x5d\x0b\x4d\x8f\x96\xb6\xa0\xc0\x4f\xd1\xb2\xec\x86\x96\x36\xa1\xf3\xa1\xec\x10\x2a\xdf\xef\xba\x6b\x92\x00\xb7\x6c\x20\xa1\x22\xd5\x7a\xd0\x7a\x6b\x5d\xe2\xa4\x95\x3e\x8c\xd6\x42\x7f\x54\x6b\x99\x15\xb5\x15\x32\xa9\xb5\xd3\x99\xd1\xda\x07\x59\x4f\x61\xdc\x11\xc1\xdd\xef\x3a\xb4\xa0\x66\x00\x2b\x5a\xef\x5f\x60\x53\xeb\xa5\xb4\xa3\xea\x31\x28\x38\x5b\x7d\x9d\x49\x6a\xcf\x04\x08\xda\x9f\x71\x8b\xf9\x7e\x23\xc5\x16\x9f\xb1\xac\xc4\xe3\x86\x4a\xdf\x61\x2b\x9e\x64\xda\x27\x4f\xef\x9e\xf1\x55\x58\x26\x87\x84\xa7\xb8\x42\xb1\x3c\xb5\x42\xdd\x3f\xcd\x2b\x78\xf5\x69\x6e\x1b\x92\x4b\x6a\x78\xda\x67\x0c\xcf\x29\x88\xf8\x9f\x53\x2e\xe9\x48\x5e\xe1\x39\x4f\x7a\x72\xcf\x79\x1a\xc0\xe4\x08\x93\x28\x78\x4e\x44\xab\xcf\x59\x4f\xcc\x38\xeb\x2a\x02\xbe\x9f\xf7\x6f\x53\x84\x4c\x4f\x7a\x8c\x4f\x9e\xd0\x3e\xe7\x25\x55\x73\x78\xce\x17\xf8\xf0\xff\xe0\x51\xfc\x9f\x41\x33\xe6\xb8\xa9\x05\xe8\x19\x42\x47\xc9\x8e\xcf\x1d\x51\x53\xc8\xf1\x64\x60\x94\xef\xaf\xd3\x11\xc1\xe6\x78\xc2\x30\xe4\x08\xae\xce\x11\x71\x63\xbe\xbf\x0a\x64\x0d\x69\x8b\x1c\x81\x2d\x2a\x44\x33\xc7\x7a\x32\xa2\x5b\x87\x84\xf9\xfe\x6a\xfa\x0a\x99\xde\x5d\x8e\x88\x68\xf2\xfd\xd5\xc7\x1a\x7a\x30\x37\xe4\x03\xdf\xea\x21\xc7\xe9\x92\x43\x8e\xf0\x38\x73\x7c\x59\xc8\x60\xcc\x2c\x7f\x06\x18\x36\x50\x00\xe1\x5b\x64\xc1\x5a\xe4\xfc\xab\x39\x57\xc8\x95\xe5\x09\x11\xc8\x52\xcf\x19\x91\x60\x33\x70\xfe\x00\xd9\xd0\x1a\xa3\x27\x70\xf7\x2a\x18\x9c\x62\x60\x23\x72\x61\x84\x4f\x81\x0d\xca\xba\x41\xd6\x76\x7c\xb8\x85\xac\x09\x93\xde\xef\x1d\xd3\x2a\x82\x92\x80\x58\x1f\x8b\x84\xe0\x66\x3d\x85\xcd\xb0\xb3\xfb\x5d\xe0\x26\x67\x25\xf3\x64\x2d\x0d\xe8\xd6\x9a\x50\x06\xe3\x9b\xef\x77\x15\x74\xaa\x50\xd5\x48\x59\x0f\x3f\x8f\xdd\xff\x4d\x45\x2b\xe8\xc8\xcc\xb3\x6f\xb8\xdd\xce\x84\x23\xc1\x7b\xc8\x20\x16\x60\x21\xe4\x4e\x79\x06\x91\x33\xaf\x84\x72\x96\xba\x12\xa2\x33\x9b\xaf\xe4\xc2\x06\xf2\xbc\x34\x06\xda\x99\xfc\xe7\xa8\x67\x4b\xcc\xc0\x7d\xc9\xf7\xcf\x09\xf7\x2e\xdb\x89\x99\xa0\xba\x40\x46\x84\xd7\xd9\xe0\x01\x50\x56\x32\xa3\x99\x3c\x11\x6b\xe6\xc9\x39\xe1\x8d\x64\x72\xcc\xac\xd2\x43\x9e\x0d\x9f\x3c\x57\xcf\x13\x2b\x9c\xaf\x50\x62\x82\xa5\x29\x11\x1a\xb9\xc4\x1d\x1b\x2b\x71\x77\x01\x84\x6d\x2f\x51\xd8\xa3\xc4\x43\x51\x75\x2e\x88\x82\xfb\x8d\xfe\x19\xc1\x4e\x59\xf7\x4b\x85\xa7\xc5\x25\x66\x54\x97\xfb\x0b\x70\xe3\xf7\x1c\xa1\xf0\xac\xb7\x44\xe0\xbc\xc4\xca\xd0\xb7\xd0\xf4\x97\x58\x95\xbe\x77\x81\x47\xc3\x52\x36\xe9\x84\x1c\xf7\xfe\x0f\x8c\x5d\xe0\x81\x97\xfb\xeb\xdf\x54\xe6\xd0\xd4\x39\xa8\x0b\xf3\x87\x66\x24\xd0\x84\x25\xf2\xca\xa3\xdc\x5f\x5e\x8c\xa5\x94\xaa\x12\x7d\x48\x47\xf2\x42\xbf\xce\xf1\x3a\xcf\x03\x4b\xec\x7a\xa1\x70\x70\xe0\x41\x3f\xb5\xc4\xa1\xd8\x26\x2f\x1d\xcb\xfd\xf5\x01\x6d\x56\xe2\xa7\xa1\xc9\xcb\x3c\xc5\x50\xe8\x0e\x16\xd9\xd7\xee\x65\x57\x4c\xfb\xbd\x4f\xe6\x9e\xba\x4a\x9f\xe8\x21\xe0\x03\x24\x5c\x0a\x02\x7c\x4c\x81\x40\x09\xb0\xc3\xf5\x29\xf4\x53\x8a\xd4\xfb\x37\x14\xf1\x04\x95\x50\xe0\xbd\x9c\x53\x30\x2c\x3d\x80\x82\x2d\x48\x5f\xa3\x00\x41\x08\x4b\x50\x3b\x8c\xcd\x49\x31\x79\x25\xcc\xac\xb0\x3f\x05\x3a\xbd\xa8\xf0\xae\x85\xd6\xad\x00\x55\x9a\xe3\xc9\x82\x4c\x83\x51\x34\xaf\x95\x71\x93\xc4\xf1\x0a\xd6\xa1\x55\xff\xca\xc0\x39\x45\xad\x49\x28\xf4\x96\x8a\x02\x87\xda\x17\xb6\xb4\x73\xd8\xce\xb6\x90\xd8\xc2\xe5\x5a\x7a\xc0\x2d\xfa\x5f\x1c\x5a\x6c\x47\x66\x87\x41\x2f\x06\xce\x33\xd2\xdd\x60\x22\x8b\x65\xe1\x37\x04\xb1\xd8\x0a\x7d\x8b\x15\x0c\x8f\x20\x3f\x31\x15\x8e\x00\xf6\x2f\xb6\x1a\xc0\xa1\x29\x46\x0f\xab\x18\x6f\xc2\x8a\xd1\x0f\x06\x96\x99\x71\x7e\x77\xd6\x43\xd3\x14\xeb\x1c\xac\x33\x04\x2d\xc6\xeb\xcc\x42\xa1\x2c\xf7\xcf\x85\x9d\x18\xb8\x64\x52\x38\xe6\x8e\x46\x53\x10\x99\x14\x1e\x48\x96\x49\x8b\x59\x26\x44\x04\xd9\x13\x72\x33\x9f\xe8\x4f\xe2\xaf\x83\xd1\x32\x33\x21\x19\x7f\xde\xff\x09\x26\x9d\x8e\x05\x50\xc2\xee\xdf\x9e\x26\x30\x31\xbb\x10\x9e\xab\x50\xd9\xae\x67\x0b\xf5\xfe\x42\xe4\x57\xe3\x42\x1f\xec\x18\x72\x70\x0b\x6b\x5c\x61\x40\x8d\x60\xd0\x1a\x79\xe8\x5b\x63\x8f\x39\xd4\x38\x16\xc4\xb6\x6a\x1c\x9c\xb2\xde\x5f\xb3\x0b\xda\x5f\xac\xbc\x30\xc4\xc5\x63\xfb\x2a\xb0\x44\xf5\xfe\xe6\xa9\x4e\xa5\xe2\xaa\x72\x1a\x4b\x05\x7c\x52\xa9\xb7\x2b\xfc\x31\x64\x06\xc0\x1c\xac\xb8\xd8\xf8\x82\xfe\xa8\xbc\xe6\xa9\x90\xbe\xaa\xb2\x65\x94\xb0\xad\xde\xff\xc9\x8b\x09\xa6\x79\x8f\xd5\xe2\x92\x1c\xaa\x6d\x59\x5e\x31\x54\x83\x55\xa9\xf7\x0f\x99\xaf\x52\x3c\x2a\x83\xa3\xca\x73\xaf\x0a\x8f\xba\xda\xd0\xc4\x8a\x0b\xce\x47\xb5\x0b\xc4\xa8\xc6\x45\xcd\x4d\x42\x9d\x29\x86\x7a\xff\xa6\x2c\x28\xd9\xe9\x45\xf3\x20\xac\xd2\x07\xac\xb0\xf4\x80\xaf\x50\x27\xd1\xfb\x5b\xc0\xe5\x75\x0e\x4c\x68\xb1\x6b\x0f\xc6\x9b\x2b\xdb\xb4\x37\x24\x4f\xec\xc0\xe0\xa3\xda\x0a\x6b\x6d\xeb\xe2\xd8\xb5\x6d\xeb\x10\xcd\x36\x2c\x00\x01\x9f\x31\x4e\xb3\x74\x7f\x43\x91\x61\x4b\x50\x62\x06\xac\x10\x99\x96\x5c\x82\xa5\x11\x2f\x7c\x8f\xb9\x31\xcb\xd3\x4a\x4b\x3c\x44\x87\xe6\x07\xd3\x1a\x6d\x9b\x41\xa3\xd8\xae\xa0\x9b\xf1\x64\xc2\xd6\x39\xa2\x1d\x74\x41\x6d\x9d\x2f\xd9\xb1\xce\x68\x69\x27\x8c\xc7\xb4\x86\x68\xd0\x9e\x16\x2c\xc7\x60\x59\x20\x1c\x96\x0f\xa0\xcd\x32\xd8\x82\x57\x10\x3c\x98\xe6\x89\x9a\xe5\x0b\x44\xb1\xb2\x65\x3d\x2d\x18\x8c\xaf\xc1\x79\xb0\x86\x00\xd8\xda\x62\xc0\xfb\xa7\x01\x8f\xd6\xf8\x44\xc2\x96\x5f\xb9\xde\x58\xdc\x3f\x8d\x27\x23\xc6\x0b\x6d\x0b\xe6\x7f\x4c\xcb\x93\x39\x47\x92\xc3\xfd\xe3\x1b\xa2\x44\xaa\x4f\xc8\x2a\xaa\xe5\x19\x51\x71\x12\x67\x7e\xc2\x19\x34\x3f\x27\x68\x67\xbe\x8e\x18\xcd\xf5\x64\x5b\xea\x54\xc3\x36\xfd\xdf\x3a\x07\x36\xde\x51\x5b\x8f\x3c\xc5\xb4\x9e\x20\x5a\xd6\xe5\x85\xd1\x40\x0d\x8a\xa8\x0d\xaa\x09\x03\xcf\xda\xb5\x66\xbc\xc0\x02\xf7\xcf\x07\x37\xfe\x71\xbf\x4f\xe8\x0c\xfb\x5c\x13\xbe\xe0\x93\x37\x9e\xe0\x34\x9a\xc5\x16\x05\x73\x37\xc4\xe0\x35\x86\x06\x53\xd8\xe2\xfd\xee\x28\x7a\x46\x47\x2e\xf3\x8a\xad\xc5\x9c\x98\x83\x0e\x68\xf7\x57\xc6\x04\x8d\x97\x62\x2d\x66\x5b\x09\x88\xdd\x62\xc5\x2f\x66\xb4\xaa\xca\x4e\x95\x2e\x46\x8b\xf7\x7f\x3c\x9a\x6c\xb1\xdd\x5f\x80\x92\x01\xb9\xfd\x16\xff\xd1\x2d\x6d\x7c\x20\xd0\xa2\x33\x08\x6f\xd1\x65\x07\x54\x96\x19\xc6\xf4\x16\x39\x35\x70\xc5\xbc\xc7\x83\x79\xf6\xee\xec\x0d\xd5\xd3\xe2\xf2\xc3\x1a\xd8\xb7\x21\xe6\x0e\x2d\x2e\xa0\x28\xa0\x74\x34\x5e\x61\x35\x9e\x84\x34\x70\x70\x8b\x9f\x6c\x2f\x91\x57\xc7\x4d\x68\xb2\x1a\x58\x31\x22\x79\x20\xb3\x63\x77\x82\xa8\xa7\x51\xaf\x34\xd1\x2a\xa1\x49\xe6\x77\xde\x79\x7c\xd8\x24\x0b\xba\x64\x05\x07\x37\xc9\x59\x9e\x4c\x09\x20\xd4\x0d\xe6\xb3\x81\xf7\xd1\x6d\xdd\xfd\x35\x59\xd0\x50\xd4\x60\x34\x9a\xfc\x5b\x47\xb9\x6d\x2d\xc1\x61\x9f\x9b\xd0\x26\xb4\x75\x45\xd6\x84\xbe\x02\x22\xa3\xc4\x76\x99\x65\x45\xb9\x13\xe7\xf4\xde\x8d\xb3\x75\x02\xcc\x7e\x7f\x77\x58\xc1\x06\x8e\x83\x1f\xdb\xee\xef\x11\xb9\xba\xe1\xf7\x0f\xb4\x4d\x93\x17\x7e\x93\xb5\x3c\xae\x6b\x9a\x1e\x5c\xa0\x0a\x7e\x3b\x56\xa4\xf4\x2d\x9b\x72\x25\xfa\x84\xd7\xd8\x94\xa8\xd0\x6c\x60\x35\x2d\x4a\x9d\xb1\xb6\xa3\x15\x4e\x76\xd3\xca\xe6\x6b\x68\x08\x75\xd3\x86\x4f\x27\x8d\x94\x38\xd1\xce\x5b\xac\xc6\x7d\xd0\x5b\x6d\xba\xc8\xa2\x2f\xec\x20\xc7\x05\x2b\xc0\xe0\xe7\x27\x21\x86\xce\x02\x63\xdd\x32\x04\xa0\xd1\xc1\x6c\x79\x62\x6d\x99\xa6\xa3\xf1\xe2\xac\xc1\x35\x6d\x46\x5c\x52\x31\x35\x13\xb4\x31\xe9\x90\xbc\x66\x64\x77\xcb\x52\x01\x35\xad\x42\x48\x71\xb3\x0c\x76\xb1\x02\x2d\xd4\x8c\xa7\x37\x8d\xb3\x58\xc1\x46\xa8\x45\x9a\xf9\xd2\x17\x6d\xd9\xe8\x06\x91\x46\x65\x17\xd6\x76\x85\xfd\x6d\x06\x2d\xd8\x6c\xac\xd3\xde\x46\x81\x6e\x30\xd6\x8d\x17\x00\xcd\x25\xd9\x0b\xc9\x39\x89\x47\x97\xa2\x2c\x86\xda\x6c\x0e\xd5\xde\x5c\x2e\x96\x91\xa4\x7e\xbf\x6b\x82\x41\x6d\xae\x7f\x52\xe0\x0a\xf5\xde\xdc\xd0\x83\xaf\x74\x9a\x5b\x5a\x5d\x6d\x9f\xd4\x09\x6e\xa4\xa1\xdb\xc1\x87\x2e\xcd\xed\x74\x92\xd3\x0d\xcb\x74\x2b\x64\x1f\xa7\x8f\xd2\xdc\x1a\x67\x84\xb6\xe1\xa4\x53\x36\x70\xd1\xef\x96\xc9\x86\x33\x3d\x60\x5a\xda\x84\xa6\x6c\x70\x35\x90\xa1\x8e\xff\x53\xa7\x6d\xe6\x13\x99\x0c\x49\x9a\x99\x31\x4d\x9b\xb9\xb1\x06\x2b\x23\xbd\xf8\x4c\xa6\x81\x09\x33\x13\x64\x80\xe1\x09\x2e\x0b\x6d\xfa\xfd\x1d\xfe\x4d\x81\x17\xf1\x6f\x42\x0b\xfe\x9b\x52\x56\xc6\x85\x49\xb7\xf0\x6f\xd2\x6a\xc3\x31\x2f\xd0\xe8\x70\xba\x93\x20\x81\x9e\xf7\xfb\x8b\x77\x20\x1e\x37\x8d\x80\xf8\x5c\x94\xf3\xb8\x6b\x8a\x39\x38\x23\x04\xa2\xc3\x23\x28\xec\xeb\xbc\xcf\x11\x97\x06\xe7\xe1\x83\x23\x28\xdd\x99\x1b\x80\x9d\x35\x9d\x8d\x59\xf0\x09\xf0\x42\x96\x97\x9a\x2e\xff\x7b\x52\xe8\xf2\xf7\xda\xc0\x65\xbd\x6e\x71\xe1\x2b\x0e\x17\xbe\x62\x80\x29\x1c\x31\xf0\xc5\xc6\x0b\x95\xeb\x02\xd7\x25\xb9\x30\x3b\x08\x79\xbd\x07\x8d\xe9\xb2\xf3\x28\xd6\x65\x67\x0c\xe5\x72\x50\xfb\xb8\xac\xc3\x59\x97\xf5\x6a\xc7\xe5\x98\xa7\xa2\xfc\x84\xe4\x3b\x6f\x68\x5c\xce\x8c\x26\x27\x19\xcb\xe5\x71\x7f\xa3\x25\x84\x77\x1d\xc8\xd2\xb8\xb9\x64\xee\x49\xb2\x5c\x4c\x14\x6e\x88\x43\xcd\xb1\x61\xb6\x67\x70\xd2\xc1\x65\x45\x11\x3c\xdf\x77\xa9\x08\x77\x5d\x78\x68\xe4\xd4\x0b\x2e\x8d\x67\x03\x2e\x4d\x06\x4b\x9b\x71\xe6\x36\x34\x07\x97\x8e\x5f\x8a\x44\x47\x87\x42\x70\xe9\x4d\xd8\xa1\x2f\x38\x8b\x60\x89\x43\x1d\xd9\xc1\xa3\x2e\x47\xe4\xcd\xea\x59\x39\xe8\x75\x7f\x63\xa4\x8b\x8a\xc4\xe5\x33\x40\x77\x7a\xa0\xce\x74\xde\xef\xc3\x30\xef\x11\x09\x29\xa7\x47\x0c\x7e\xbf\x4f\x92\x54\x4f\x2c\x5b\x2b\x9f\x26\xb9\x2e\x6d\xcd\xd3\x68\xd7\x7f\x13\x72\xc3\x47\x33\xae\x03\xbb\x84\xea\xe1\x45\x8f\xf3\x9a\x0f\x92\x06\x00\xff\xc7\x6d\x5f\x10\x94\xb3\xf5\xba\xcd\x0d\xd4\xb4\xe7\xea\x01\x42\x19\x7d\x38\xb7\xd2\x58\x53\xf1\xc3\x3a\xe9\xc4\xb8\x35\x82\xd5\x04\xb3\xd2\xf7\x77\x63\x70\xeb\x7c\x0a\xe8\x73\xbb\xdf\x80\x58\x36\xbc\x45\x87\x88\x04\x9f\x24\x31\x4f\x01\x9c\x81\xa7\x2f\xbf\xde\xe1\x38\xf8\x44\x84\xeb\xb3\xb0\x53\xe3\x2b\x48\x9e\xb2\xfb\x1c\x68\xdb\x21\x27\xbb\x85\xce\x73\xd4\xce\x23\x9f\xce\xdb\x8d\x1e\x61\x1e\x7a\x3c\xe3\x0b\xd0\x57\xab\x1c\x01\xd6\x27\x16\xdb\x23\x44\xbd\xc7\x25\xea\x3d\xe6\xbf\xa4\xb3\xdd\x60\x83\xb9\x03\x5e\x1c\xad\x6c\xa8\xf8\x3b\xc1\xef\xb1\xd2\x1d\xea\xb1\x0a\x6b\x2b\x22\x94\x1e\x2b\x05\x87\xc7\xbc\x9d\x87\x15\x3d\x36\x00\xf8\x07\x3d\xfa\xce\x85\x47\x1f\x60\xe3\x1e\xfb\x60\x27\x3e\xa7\xe9\xbc\xe4\xe9\xf1\xc3\xf8\x3c\xa9\xff\xef\x38\xa8\x4b\x32\x00\xb0\x12\xd2\x11\x43\x97\x3d\x74\x39\x27\x96\x2f\xda\x43\xe7\x25\x7e\x97\x7c\xa1\xae\x20\x9e\xef\x52\x48\xcc\x4e\x26\xea\x52\xa1\x43\x79\x3f\x98\x99\x30\xb7\xfc\x9b\x2e\x4d\xd1\xe4\x1f\xcf\xaf\x3b\x70\x29\xae\x02\xb8\x30\xb3\x0e\x89\xbb\x74\x0a\x48\xff\x3b\x52\xea\xc2\xcc\xf8\x2b\xbc\x88\x52\xf9\x20\xc0\x4a\x15\xf6\xb8\xaf\xeb\xa2\xae\x70\xa7\xba\x9e\x58\x26\x2f\xae\xfb\xfd\xce\x11\x08\xd5\x0c\xf5\xdf\x35\x0b\x5f\x82\xf6\xb5\xea\xfb\x5d\x36\x63\xe3\xc2\x42\x87\x77\xd2\xb5\x0f\x18\xc4\xce\xe3\xa1\xae\x7c\xa6\xdc\x69\x3a\x3b\xbd\xff\x4e\xab\xd9\x2d\xe3\x17\x5b\x44\xb2\x93\xf8\x96\x79\x73\xdc\xef\x1f\xfa\x8a\xdd\x78\x29\xd7\x2d\xcf\x3f\x24\x1b\x0f\xc9\xbb\x55\x48\x42\xb7\xba\x5a\x55\x38\xc2\xdd\x2a\xa5\xa9\x1b\x47\x6c\x99\x3d\xd7\x6b\x81\xce\xab\x89\x6e\xbe\xee\x79\x3b\x0a\x91\xef\x8b\xc0\xf7\xcf\x20\x27\x4c\x04\x83\x7d\x6e\x40\xe3\xa4\x9d\xeb\x34\x44\x7d\xca\x89\x69\xe9\x89\xf6\xe5\x59\xf5\x15\xfa\xf6\x79\x38\x9b\x33\x3c\xea\x33\x2f\x26\xe1\x3d\x52\x9f\x70\xbf\x98\x92\x85\xe7\x32\xf0\x7d\x36\xaa\xb5\x3e\xf1\xed\x89\x5f\x7f\x63\xfa\xc9\x86\x9d\x63\x41\x93\x8d\xc8\x27\xea\x23\x6e\xd0\x18\x48\x73\x04\xbc\x7f\xc3\x58\x15\xd0\xe3\x7c\x0f\x3a\x22\xb6\x3c\xe8\x74\x8f\xb8\x4e\x1b\xd7\xeb\xc5\xb1\x84\x66\xc4\x42\x3b\x31\x62\x81\x84\x0f\x5a\xa1\x11\xeb\x1a\xb8\xa1\x5d\x03\x03\x8c\x08\x4e\x1b\xb1\xad\x4e\xff\xa6\xae\x41\x7c\x47\x9d\x0b\xbf\xa1\xe8\x46\xf4\x27\xd8\x6b\x44\xb7\x01\xe8\x18\xcf\x59\x32\x66\x7c\xa2\xf9\x64\xd9\x0b\x45\xb4\x5f\x43\xf8\xca\x65\xd0\x2d\x1e\x92\x30\xf2\xfd\x9d\xf8\x46\x66\xc8\x13\x6c\x30\xe4\x29\x0e\xa8\xcc\xa0\x85\xe4\xfb\xfb\x40\x24\x42\xce\x1a\x02\x65\x33\xd6\x63\x81\x21\x35\xbe\x00\x77\x76\xaa\x0b\x6a\x07\xec\xa8\x36\x5e\xbe\x21\x9c\xe0\xb6\x04\x18\x1f\xf7\xb7\xf3\xd9\xdd\x10\xaf\xd0\x58\x03\x2e\x2f\x7a\x76\xf6\xec\xc6\x35\xf6\x81\x20\x70\x08\x63\x91\x41\x81\x19\xf2\x0a\x43\xa1\xc4\x86\x6e\x93\x27\x6a\x43\xa5\x34\xe4\x29\xc4\x43\x79\xcd\x34\x14\xfc\x33\x14\xfa\x66\xe8\x93\x03\xf0\x02\x64\x28\xcf\x86\x07\x9c\x0a\xec\x0f\x7e\xd0\xe0\xa3\xaf\x01\xcb\x30\xee\x77\x83\x75\x19\xca\x21\xd9\xed\x6f\x16\xb2\xd6\xb8\xdf\x43\x56\xff\x01\xf5\x3b\x14\xb8\xb5\x45\x67\xdb\x18\xe9\x0f\x83\x62\x1d\x96\xb8\x43\xc3\x2c\x76\xa2\x3a\xf3\xb3\xb0\x92\x55\xe4\x11\x6b\x2c\x68\x12\x06\x5f\xb5\x8d\xfb\xc7\xe3\x47\x18\xc6\x30\x7f\x98\x17\x2a\x0f\x98\x48\x61\x9e\xa0\x09\x07\x73\xac\x85\xcf\x4c\x86\xf9\x98\x9c\xa6\xe3\x87\x3d\xf0\x6d\xd5\x80\xb3\x87\x9c\xc7\x8d\x7c\xea\xeb\x3e\x7e\xbd\x48\x1e\xff\xbb\x0b\x1c\x8e\x48\x72\xf0\xf6\x73\x78\x2c\xfc\x86\xbf\xb5\x4c\xf2\xf0\x08\xcf\x6e\x38\x5f\xdb\x0e\xbf\xbf\x37\xcb\x61\xc0\xbf\x45\xa9\x2c\x0c\xba\x54\x00\x6e\x08\x4e\xc0\x70\xdd\x26\x20\x87\x46\xb4\x30\x9c\xcf\xf8\x86\xeb\xac\x07\x0a\xed\x10\x26\x85\x95\xb4\x98\x83\xc6\x72\xf0\xe1\xea\x70\x38\xd5\xc3\x27\xcb\xf9\x4c\x75\xf8\x04\xf3\xcf\x6d\x5d\xeb\x8e\xb9\x59\x18\x93\x6f\x14\xc6\x84\xf9\x19\x34\x86\xe3\xfe\xad\x92\x99\x90\xb9\xa7\xf3\xf9\xe9\x98\xce\xd3\xc1\x31\xe1\x71\x0c\x3e\xaf\x9e\x1b\x23\xa5\xfb\x37\x33\x66\x9c\xd0\x72\x39\xcc\x65\xa5\xe8\x8a\xcc\xaa\x17\xe2\xb1\x30\x2b\x7e\x50\x8b\x0c\xb1\xa6\xd3\x09\x9d\xbe\x49\x98\xbe\xae\x7c\x27\x62\x2b\xfe\x0d\x64\xf6\xc9\xe7\x4a\xeb\xce\x69\x0e\xe3\xab\x8f\x79\xc5\x70\x21\x0c\xba\x62\x02\xcb\x5d\x91\x6f\xc2\x2e\x3e\xe4\xbf\x40\x85\x2b\x2a\x0b\xd6\xd1\xed\x15\xb3\x84\xeb\x2f\x7e\xbf\xf8\x6e\xea\xe2\xa3\x56\x94\x5d\x93\x2d\x4a\x83\x1f\x75\x45\x47\xc6\x95\x03\x91\x6d\x2f\x84\xc6\x97\x90\x15\xaf\x75\x59\x72\xc9\xe3\x7e\xf3\xc0\xef\x02\xd9\x24\x5c\xf2\x94\x57\xe0\x21\xd6\x25\x34\xfa\x97\x64\x43\x09\x56\x21\x7c\x11\x7b\x51\xb8\x2e\xa9\xc2\x81\x2a\xd7\x2a\x40\xcd\x45\xee\xbc\xa4\xce\x1e\x2e\xb6\xe4\xad\xf2\x25\xbe\x11\xee\x98\xc0\x85\xbd\xfd\x49\xc8\x25\xf9\x40\x63\x20\xe4\x52\x30\xdd\xa5\x1b\xb4\xf5\xc5\xa3\xa4\xeb\x7e\x27\x5e\x0c\x5d\x8a\x8e\xf7\x1b\x06\xe7\xd2\x1d\xd8\xbc\x14\x7e\x31\xef\xef\xa4\x87\x8b\x5e\xde\xa5\x19\x3f\xec\x40\x6b\x84\xd0\xf3\xc5\xd6\xa5\xf7\x7f\x90\x93\x4b\x2d\xdf\xef\x1a\x2e\x05\x61\x2f\x75\x20\x59\x7d\xcc\x3d\x5c\xda\x89\xca\x77\x67\xb0\xbe\x5c\xcd\x4b\x47\xe4\x09\xe0\xa5\x93\xdd\xaf\xf8\x02\x24\x6e\x14\x76\xfe\xd2\xcb\xc2\x65\x99\xf7\xa7\x97\x65\xba\xb3\x97\x65\x62\xc0\x1c\xcd\xe9\xd3\x5d\x08\xa7\x2f\x20\x93\xd6\xeb\x9a\x7c\x98\xf9\xc9\x0b\xec\x4f\xf8\xc7\x9f\x94\xa0\x4f\xe8\xd5\x4f\xde\x48\x7e\x42\x71\x7d\x42\x6b\x7c\x42\x6b\x7c\xda\x39\x3d\xbc\xe2\x01\x02\xbf\x78\xd4\xfa\x8a\x0d\x22\xf9\xe2\x1b\x85\x97\x55\x00\xe8\xfe\xd7\x2c\x00\xb0\xb5\xff\x1f\x00\x00\xff\xff\x11\x91\x1a\xde\x5b\x35\x00\x00") -func keysWordlistSpanishTxtBytes() ([]byte, error) { +func keysWordsWordlistSpanishTxtBytes() ([]byte, error) { return bindataRead( - _keysWordlistSpanishTxt, - "keys/wordlist/spanish.txt", + _keysWordsWordlistSpanishTxt, + "keys/words/wordlist/spanish.txt", ) } -func keysWordlistSpanishTxt() (*asset, error) { - bytes, err := keysWordlistSpanishTxtBytes() +func keysWordsWordlistSpanishTxt() (*asset, error) { + bytes, err := keysWordsWordlistSpanishTxtBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "keys/wordlist/spanish.txt", size: 13659, mode: os.FileMode(420), modTime: time.Unix(1511602021, 0)} + info := bindataFileInfo{name: "keys/words/wordlist/spanish.txt", size: 13659, mode: os.FileMode(420), modTime: time.Unix(1514928181, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -203,10 +203,10 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ - "keys/wordlist/chinese_simplified.txt": keysWordlistChinese_simplifiedTxt, - "keys/wordlist/english.txt": keysWordlistEnglishTxt, - "keys/wordlist/japanese.txt": keysWordlistJapaneseTxt, - "keys/wordlist/spanish.txt": keysWordlistSpanishTxt, + "keys/words/wordlist/chinese_simplified.txt": keysWordsWordlistChinese_simplifiedTxt, + "keys/words/wordlist/english.txt": keysWordsWordlistEnglishTxt, + "keys/words/wordlist/japanese.txt": keysWordsWordlistJapaneseTxt, + "keys/words/wordlist/spanish.txt": keysWordsWordlistSpanishTxt, } // AssetDir returns the file names below a certain @@ -250,11 +250,13 @@ type bintree struct { } var _bintree = &bintree{nil, map[string]*bintree{ "keys": &bintree{nil, map[string]*bintree{ - "wordlist": &bintree{nil, map[string]*bintree{ - "chinese_simplified.txt": &bintree{keysWordlistChinese_simplifiedTxt, map[string]*bintree{}}, - "english.txt": &bintree{keysWordlistEnglishTxt, map[string]*bintree{}}, - "japanese.txt": &bintree{keysWordlistJapaneseTxt, map[string]*bintree{}}, - "spanish.txt": &bintree{keysWordlistSpanishTxt, map[string]*bintree{}}, + "words": &bintree{nil, map[string]*bintree{ + "wordlist": &bintree{nil, map[string]*bintree{ + "chinese_simplified.txt": &bintree{keysWordsWordlistChinese_simplifiedTxt, map[string]*bintree{}}, + "english.txt": &bintree{keysWordsWordlistEnglishTxt, map[string]*bintree{}}, + "japanese.txt": &bintree{keysWordsWordlistJapaneseTxt, map[string]*bintree{}}, + "spanish.txt": &bintree{keysWordsWordlistSpanishTxt, map[string]*bintree{}}, + }}, }}, }}, }} From 67a47e6a0bf474a76f6a8f09b39cfdf382f39b90 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 6 Jan 2018 16:05:50 -0500 Subject: [PATCH 193/287] Address is a type alias --- pub_key.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pub_key.go b/pub_key.go index cda01a9df..32c0b3237 100644 --- a/pub_key.go +++ b/pub_key.go @@ -16,7 +16,8 @@ import ( // An address is a []byte, but hex-encoded even in JSON. // []byte leaves us the option to change the address length. -type Address cmn.HexBytes +// Use an alias so Unmarshal methods (with ptr receivers) are available too. +type Address = cmn.HexBytes func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { if err := wire.ReadBinaryBytes(pubKeyBytes, &pubKey); err != nil { From 788cc0a79256d4fe0448e17a90217acf3d61346b Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sun, 14 Jan 2018 00:31:39 -0800 Subject: [PATCH 194/287] Use new go-wire; PubKey etc are interfaces; Keybase refactor --- {nano => _nano}/keys.go | 0 {nano => _nano}/keys_test.go | 0 {nano => _nano}/sign.go | 0 {nano => _nano}/sign_test.go | 0 crypto.go | 9 -- embed_test.go | 91 ------------- encode_test.go | 4 + glide.lock | 35 ++--- glide.yaml | 8 +- keys/keybase.go | 227 +++++++++++++------------------- keys/keybase_test.go | 242 ++++++++++++++++++----------------- keys/keys.go | 32 +++++ keys/mintkey.go | 26 ++++ keys/types.go | 63 +++++---- keys/wire.go | 12 ++ priv_key.go | 88 +++++-------- priv_key_test.go | 32 ++--- privkeyinner_wrapper.go | 62 --------- pub_key.go | 86 +++---------- pub_key_test.go | 4 +- pubkeyinner_wrapper.go | 62 --------- signature.go | 58 +++------ signature_test.go | 132 ++++++------------- signatureinner_wrapper.go | 62 --------- wire.go | 36 ++++++ 25 files changed, 494 insertions(+), 877 deletions(-) rename {nano => _nano}/keys.go (100%) rename {nano => _nano}/keys_test.go (100%) rename {nano => _nano}/sign.go (100%) rename {nano => _nano}/sign_test.go (100%) delete mode 100644 crypto.go delete mode 100644 embed_test.go create mode 100644 keys/keys.go create mode 100644 keys/wire.go delete mode 100644 privkeyinner_wrapper.go delete mode 100644 pubkeyinner_wrapper.go delete mode 100644 signatureinner_wrapper.go create mode 100644 wire.go diff --git a/nano/keys.go b/_nano/keys.go similarity index 100% rename from nano/keys.go rename to _nano/keys.go diff --git a/nano/keys_test.go b/_nano/keys_test.go similarity index 100% rename from nano/keys_test.go rename to _nano/keys_test.go diff --git a/nano/sign.go b/_nano/sign.go similarity index 100% rename from nano/sign.go rename to _nano/sign.go diff --git a/nano/sign_test.go b/_nano/sign_test.go similarity index 100% rename from nano/sign_test.go rename to _nano/sign_test.go diff --git a/crypto.go b/crypto.go deleted file mode 100644 index d9caf1ad9..000000000 --- a/crypto.go +++ /dev/null @@ -1,9 +0,0 @@ -package crypto - -// Types of implementations -const ( - TypeEd25519 = byte(0x01) - TypeSecp256k1 = byte(0x02) - NameEd25519 = "ed25519" - NameSecp256k1 = "secp256k1" -) diff --git a/embed_test.go b/embed_test.go deleted file mode 100644 index e5c37c0c1..000000000 --- a/embed_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package crypto_test - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - data "github.com/tendermint/go-wire/data" -) - -type PubName struct { - PubNameInner -} - -type PubNameInner interface { - AssertIsPubNameInner() - String() string -} - -func (p PubName) MarshalJSON() ([]byte, error) { - return pubNameMapper.ToJSON(p.PubNameInner) -} - -func (p *PubName) UnmarshalJSON(data []byte) error { - parsed, err := pubNameMapper.FromJSON(data) - if err == nil && parsed != nil { - p.PubNameInner = parsed.(PubNameInner) - } - return err -} - -var pubNameMapper = data.NewMapper(PubName{}). - RegisterImplementation(PubNameFoo{}, "foo", 1). - RegisterImplementation(PubNameBar{}, "bar", 2) - -func (f PubNameFoo) AssertIsPubNameInner() {} -func (f PubNameBar) AssertIsPubNameInner() {} - -//---------------------------------------- - -type PubNameFoo struct { - Name string -} - -func (f PubNameFoo) String() string { return "Foo: " + f.Name } - -type PubNameBar struct { - Age int -} - -func (b PubNameBar) String() string { return fmt.Sprintf("Bar #%d", b.Age) } - -//---------------------------------------- - -// TestEncodeDemo tries the various strategies to encode the objects -func TestEncodeDemo(t *testing.T) { - assert, require := assert.New(t), require.New(t) - - cases := []struct { - in, out PubNameInner - expected string - }{ - {PubName{PubNameFoo{"pub-foo"}}, &PubName{}, "Foo: pub-foo"}, - {PubName{PubNameBar{7}}, &PubName{}, "Bar #7"}, - } - - for i, tc := range cases { - - // Make sure it is proper to start - require.Equal(tc.expected, tc.in.String()) - - // Try to encode as binary - b, err := data.ToWire(tc.in) - if assert.Nil(err, "%d: %#v", i, tc.in) { - err2 := data.FromWire(b, tc.out) - if assert.Nil(err2) { - assert.Equal(tc.expected, tc.out.String()) - } - } - - // Try to encode it as json - j, err := data.ToJSON(tc.in) - if assert.Nil(err, "%d: %#v", i, tc.in) { - err2 := data.FromJSON(j, tc.out) - if assert.Nil(err2) { - assert.Equal(tc.expected, tc.out.String()) - } - } - } -} diff --git a/encode_test.go b/encode_test.go index 947d91901..bcd9e60c2 100644 --- a/encode_test.go +++ b/encode_test.go @@ -1,5 +1,8 @@ package crypto +/* +XXX Needs to be refactored to not use go-wire/data + import ( "fmt" "strings" @@ -179,3 +182,4 @@ func TestEmbededWireEncodings(t *testing.T) { checkWire(t, msg, &msg2, tc.keyType, tc.size) } } +*/ diff --git a/glide.lock b/glide.lock index 5032685c2..c8e47160f 100644 --- a/glide.lock +++ b/glide.lock @@ -1,18 +1,18 @@ -hash: a21061afc44c148eb6bfeb91478b520661f3d086234383a0208d915b0cb058b8 -updated: 2017-12-27T14:29:49.534901894-08:00 +hash: ed34b08bfc24f64edbc1a16ad2e34198afefc0e2dc133be2c92c6f764f953234 +updated: 2018-01-13T18:02:43.833267692-08:00 imports: - name: github.com/btcsuite/btcd - version: c7588cbf7690cd9f047a28efa2dcd8f2435a4e5e + version: 2e60448ffcc6bf78332d1fe590260095f554dd78 subpackages: - btcec - name: github.com/btcsuite/btcutil - version: 66871daeb12123ece012a9628d2798d01195c4b3 + version: 501929d3d046174c3d39f0ea54ece471aa17238c subpackages: - base58 -- name: github.com/ethanfrey/ledger - version: 5e432577be582bd18a3b4a9cd75dae7a317ade36 -- name: github.com/flynn/hid - version: ed06a31c6245d4552e8dbba7e32e5b010b875d65 +- name: github.com/davecgh/go-spew + version: 04cdfd42973bb9c8589fd6a731800cf222fde1a9 + subpackages: + - spew - name: github.com/go-kit/kit version: e2b298466b32c7cd5579a9b9b07e968fc9d9452c subpackages: @@ -32,7 +32,7 @@ imports: - name: github.com/golang/snappy version: 553a641470496b2327abcac10b36396bd98e45c9 - name: github.com/howeyc/crc16 - version: 96a97a1abb579c7ff1a8ffa77f2e72d1c314b57f + version: 2b2a61e366a66d3efb279e46176e7291001e0354 - name: github.com/jmhodges/levigo version: c42d9e0ca023e2198120196f842701bb4c55d7b9 - name: github.com/kr/logfmt @@ -55,17 +55,14 @@ imports: - leveldb/table - leveldb/util - name: github.com/tendermint/ed25519 - version: 1f52c6f8b8a5c7908aff4497c186af344b428925 + version: d8387025d2b9d158cf4efb07e7ebf814bcce2057 subpackages: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: 27be46e25124ddf775e23317a83647ce62a93f6b - subpackages: - - data - - data/base58 + version: fde4a0bf4dd4c0ec0df2504f79f23ed7e6b3b452 - name: github.com/tendermint/tmlibs - version: 93c05aa8c06ef38f2b15fcdd1d91eafefda2732d + version: 2bb538b150f197a04a0b969a27e9ea24d35edbc1 subpackages: - common - db @@ -83,10 +80,6 @@ imports: - ripemd160 - salsa20/salsa testImports: -- name: github.com/davecgh/go-spew - version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 - subpackages: - - spew - name: github.com/mndrix/btcutil version: d3a63a5752ecf3fbc06bd97365da752111c263df - name: github.com/pmezard/go-difflib @@ -94,11 +87,11 @@ testImports: subpackages: - difflib - name: github.com/stretchr/testify - version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0 + version: b91bfb9ebec76498946beb6af7c0230c7cc7ba6c subpackages: - assert - require - name: github.com/tyler-smith/go-bip32 - version: eb790af526c30f23a7c8b00a48e342f9d0bd6386 + version: 2c9cfd17756470a0b7c3e4b7954bae7d11035504 - name: github.com/tyler-smith/go-bip39 version: 8e7a99b3e716f36d3b080a9a70f9eb45abe4edcc diff --git a/glide.yaml b/glide.yaml index f9df5c18d..f92a8c9a4 100644 --- a/glide.yaml +++ b/glide.yaml @@ -19,10 +19,7 @@ import: - package: github.com/tendermint/tmlibs version: sdk2 - package: github.com/tendermint/go-wire - version: develop - subpackages: - - data - - data/base58 + version: sdk2 - package: golang.org/x/crypto subpackages: - blowfish @@ -31,7 +28,8 @@ import: - ripemd160 - package: github.com/pkg/errors - package: github.com/howeyc/crc16 -- package: github.com/ethanfrey/ledger +# Needs refactoring, shouldn't be implementing PrivKey +#- package: github.com/ethanfrey/ledger testImport: - package: github.com/mndrix/btcutil - package: github.com/stretchr/testify diff --git a/keys/keybase.go b/keys/keybase.go index c72518748..88a12000c 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -6,16 +6,10 @@ import ( "github.com/pkg/errors" crypto "github.com/tendermint/go-crypto" - dbm "github.com/tendermint/tmlibs/db" - "github.com/tendermint/go-crypto/keys/words" - "github.com/tendermint/go-crypto/nano" + dbm "github.com/tendermint/tmlibs/db" ) -// XXX Lets use go-crypto/bcrypt and ascii encoding directly in here without -// further wrappers around a store or DB. -// Copy functions from: https://github.com/tendermint/mintkey/blob/master/cmd/mintkey/common.go -// // dbKeybase combines encyption and storage implementation to provide // a full-featured key manager type dbKeybase struct { @@ -32,58 +26,59 @@ func New(db dbm.DB, codec words.Codec) dbKeybase { var _ Keybase = dbKeybase{} -// Create generates a new key and persists it storage, encrypted using the passphrase. -// It returns the generated seedphrase (mnemonic) and the key Info. -// It returns an error if it fails to generate a key for the given algo type, -// or if another key is already stored under the same name. -func (kb dbKeybase) Create(name, passphrase, algo string) (string, Info, error) { +// Create generates a new key and persists it to storage, encrypted +// using the passphrase. It returns the generated seedphrase +// (mnemonic) and the key Info. It returns an error if it fails to +// generate a key for the given algo type, or if another key is +// already stored under the same name. +func (kb dbKeybase) Create(name, passphrase string, algo CryptoAlgo) (Info, string, error) { // NOTE: secret is SHA256 hashed by secp256k1 and ed25519. // 16 byte secret corresponds to 12 BIP39 words. // XXX: Ledgers use 24 words now - should we ? secret := crypto.CRandBytes(16) - key, err := generate(algo, secret) + priv, err := generate(algo, secret) if err != nil { - return "", Info{}, err + return Info{}, "", err } // encrypt and persist the key - public := kb.writeKey(key, name, passphrase) + info := kb.writeKey(priv, name, passphrase) + + // we append the type byte to the serialized secret to help with + // recovery + // ie [secret] = [type] + [secret] + typ := cryptoAlgoToByte(algo) + secret = append([]byte{typ}, secret...) // return the mnemonic phrase words, err := kb.codec.BytesToWords(secret) - seedphrase := strings.Join(words, " ") - return seedphrase, public, err -} - -// Recover converts a seedphrase to a private key and persists it, encrypted with the given passphrase. -// Functions like Create, but seedphrase is input not output. -func (kb dbKeybase) Recover(name, passphrase, algo string, seedphrase string) (Info, error) { - - key, err := kb.SeedToPrivKey(algo, seedphrase) - if err != nil { - return Info{}, err - } - - // Valid seedphrase. Encrypt key and persist to disk. - public := kb.writeKey(key, name, passphrase) - return public, nil + seed := strings.Join(words, " ") + return info, seed, err } -// SeedToPrivKey returns the private key corresponding to a seedphrase -// without persisting the private key. -// TODO: enable the keybase to just hold these in memory so we can sign without persisting (?) -func (kb dbKeybase) SeedToPrivKey(algo, seedphrase string) (crypto.PrivKey, error) { +// Recover converts a seedphrase to a private key and persists it, +// encrypted with the given passphrase. Functions like Create, but +// seedphrase is input not output. +func (kb dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { words := strings.Split(strings.TrimSpace(seedphrase), " ") secret, err := kb.codec.WordsToBytes(words) if err != nil { - return crypto.PrivKey{}, err + return Info{}, err } - key, err := generate(algo, secret) + // secret is comprised of the actual secret with the type + // appended. + // ie [secret] = [type] + [secret] + typ, secret := secret[0], secret[1:] + algo := byteToCryptoAlgo(typ) + priv, err := generate(algo, secret) if err != nil { - return crypto.PrivKey{}, err + return Info{}, err } - return key, nil + + // encrypt and persist key. + public := kb.writeKey(priv, name, passphrase) + return public, err } // List returns the keys from storage in alphabetical order. @@ -92,75 +87,56 @@ func (kb dbKeybase) List() ([]Info, error) { iter := kb.db.Iterator(nil, nil) defer iter.Close() for ; iter.Valid(); iter.Next() { - key := iter.Key() - if isPub(key) { - info, err := readInfo(iter.Value()) - if err != nil { - return nil, err - } - res = append(res, info) + // key := iter.Key() + info, err := readInfo(iter.Value()) + if err != nil { + return nil, err } + res = append(res, info) } return res, nil } // Get returns the public information about one key. func (kb dbKeybase) Get(name string) (Info, error) { - bs := kb.db.Get(pubName(name)) + bs := kb.db.Get(infoKey(name)) return readInfo(bs) } // Sign signs the msg with the named key. // It returns an error if the key doesn't exist or the decryption fails. -// TODO: what if leddger fails ? -func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signature, pk crypto.PubKey, err error) { - var key crypto.PrivKey - armorStr := kb.db.Get(privName(name)) - key, err = unarmorDecryptPrivKey(string(armorStr), passphrase) +func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signature, pub crypto.PubKey, err error) { + info, err := kb.Get(name) if err != nil { return } - - sig = key.Sign(msg) - pk = key.PubKey() - return -} - -// Export decodes the private key with the current password, encrypts -// it with a secure one-time password and generates an armored private key -// that can be Imported by another dbKeybase. -// -// This is designed to copy from one device to another, or provide backups -// during version updates. -func (kb dbKeybase) Export(name, oldpass, transferpass string) ([]byte, error) { - armorStr := kb.db.Get(privName(name)) - key, err := unarmorDecryptPrivKey(string(armorStr), oldpass) + priv, err := unarmorDecryptPrivKey(info.PrivKeyArmor, passphrase) if err != nil { - return nil, err + return } + sig = priv.Sign(msg) + pub = priv.PubKey() + return +} - if transferpass == "" { - return key.Bytes(), nil +func (kb dbKeybase) Export(name string) (armor string, err error) { + bz := kb.db.Get(infoKey(name)) + if bz == nil { + return "", errors.New("No key to export with name " + name) } - armorBytes := encryptArmorPrivKey(key, transferpass) - return []byte(armorBytes), nil + return armorInfoBytes(bz), nil } -// Import accepts bytes generated by Export along with the same transferpass. -// If they are valid, it stores the password under the given name with the -// new passphrase. -func (kb dbKeybase) Import(name, newpass, transferpass string, data []byte) (err error) { - var key crypto.PrivKey - if transferpass == "" { - key, err = crypto.PrivKeyFromBytes(data) - } else { - key, err = unarmorDecryptPrivKey(string(data), transferpass) +func (kb dbKeybase) Import(name string, armor string) (err error) { + bz := kb.db.Get(infoKey(name)) + if len(bz) > 0 { + return errors.New("Cannot overwrite data for name " + name) } + infoBytes, err := unarmorInfoBytes(armor) if err != nil { - return err + return } - - kb.writeKey(key, name, newpass) + kb.db.Set(infoKey(name), infoBytes) return nil } @@ -168,80 +144,59 @@ func (kb dbKeybase) Import(name, newpass, transferpass string, data []byte) (err // proper passphrase before deleting it (for security). func (kb dbKeybase) Delete(name, passphrase string) error { // verify we have the proper password before deleting - bs := kb.db.Get(privName(name)) - _, err := unarmorDecryptPrivKey(string(bs), passphrase) + info, err := kb.Get(name) if err != nil { return err } - kb.db.DeleteSync(pubName(name)) - kb.db.DeleteSync(privName(name)) + _, err = unarmorDecryptPrivKey(info.PrivKeyArmor, passphrase) + if err != nil { + return err + } + kb.db.DeleteSync(infoKey(name)) return nil } -// Update changes the passphrase with which an already stored key is encrypted. +// Update changes the passphrase with which an already stored key is +// encrypted. // -// oldpass must be the current passphrase used for encryption, newpass will be -// the only valid passphrase from this time forward. +// oldpass must be the current passphrase used for encryption, +// newpass will be the only valid passphrase from this time forward. func (kb dbKeybase) Update(name, oldpass, newpass string) error { - bs := kb.db.Get(privName(name)) - key, err := unarmorDecryptPrivKey(string(bs), oldpass) + info, err := kb.Get(name) + if err != nil { + return err + } + key, err := unarmorDecryptPrivKey(info.PrivKeyArmor, oldpass) if err != nil { return err } - // Generate the public bytes and the encrypted privkey - public := info(name, key) - private := encryptArmorPrivKey(key, newpass) - - // We must delete first, as Putting over an existing name returns an error. - // Must be done atomically with the write or we could lose the key. - batch := kb.db.NewBatch() - batch.Delete(pubName(name)) - batch.Delete(privName(name)) - batch.Set(pubName(name), public.bytes()) - batch.Set(privName(name), []byte(private)) - batch.Write() - + kb.writeKey(key, name, newpass) return nil } - -//--------------------------------------------------------------------------------------- - func (kb dbKeybase) writeKey(priv crypto.PrivKey, name, passphrase string) Info { - // Generate the public bytes and the encrypted privkey - public := info(name, priv) - private := encryptArmorPrivKey(priv, passphrase) - - // Write them both - kb.db.SetSync(pubName(name), public.bytes()) - kb.db.SetSync(privName(name), []byte(private)) + // generate the encrypted privkey + privArmor := encryptArmorPrivKey(priv, passphrase) + // make Info + info := newInfo(name, priv.PubKey(), privArmor) - return public + // write them both + kb.db.SetSync(infoKey(name), info.bytes()) + return info } -// TODO: use a `type TypeKeyAlgo string` (?) -func generate(algo string, secret []byte) (crypto.PrivKey, error) { +func generate(algo CryptoAlgo, secret []byte) (crypto.PrivKey, error) { switch algo { - case crypto.NameEd25519: - return crypto.GenPrivKeyEd25519FromSecret(secret).Wrap(), nil - case crypto.NameSecp256k1: - return crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap(), nil - case nano.NameLedgerEd25519: - return nano.NewPrivKeyLedgerEd25519() + case AlgoEd25519: + return crypto.GenPrivKeyEd25519FromSecret(secret), nil + case AlgoSecp256k1: + return crypto.GenPrivKeySecp256k1FromSecret(secret), nil default: err := errors.Errorf("Cannot generate keys for algorithm: %s", algo) - return crypto.PrivKey{}, err + return nil, err } } -func pubName(name string) []byte { - return []byte(fmt.Sprintf("%s.pub", name)) -} - -func privName(name string) []byte { - return []byte(fmt.Sprintf("%s.priv", name)) -} - -func isPub(name []byte) bool { - return strings.HasSuffix(string(name), ".pub") +func infoKey(name string) []byte { + return []byte(fmt.Sprintf("%s.info", name)) } diff --git a/keys/keybase_test.go b/keys/keybase_test.go index 12e5205b0..84c81c81f 100644 --- a/keys/keybase_test.go +++ b/keys/keybase_test.go @@ -2,24 +2,20 @@ package keys_test import ( "fmt" - "os" "testing" - asrt "github.com/stretchr/testify/assert" - rqr "github.com/stretchr/testify/require" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" - cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" - crypto "github.com/tendermint/go-crypto" + "github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto/keys" "github.com/tendermint/go-crypto/keys/words" - "github.com/tendermint/go-crypto/nano" ) // TestKeyManagement makes sure we can manipulate these keys well func TestKeyManagement(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) // make the storage with reasonable defaults cstore := keys.New( @@ -27,84 +23,83 @@ func TestKeyManagement(t *testing.T) { words.MustLoadCodec("english"), ) - algo := crypto.NameEd25519 + algo := keys.AlgoEd25519 n1, n2, n3 := "personal", "business", "other" p1, p2 := "1234", "really-secure!@#$" // Check empty state l, err := cstore.List() - require.Nil(err) - assert.Empty(l) + require.Nil(t, err) + assert.Empty(t, l) // create some keys _, err = cstore.Get(n1) - assert.NotNil(err) - _, i, err := cstore.Create(n1, p1, algo) - require.Equal(n1, i.Name) - require.Nil(err) + assert.NotNil(t, err) + i, _, err := cstore.Create(n1, p1, algo) + require.Equal(t, n1, i.Name) + require.Nil(t, err) _, _, err = cstore.Create(n2, p2, algo) - require.Nil(err) + require.Nil(t, err) // we can get these keys i2, err := cstore.Get(n2) - assert.Nil(err) + assert.Nil(t, err) _, err = cstore.Get(n3) - assert.NotNil(err) + assert.NotNil(t, err) // list shows them in order keyS, err := cstore.List() - require.Nil(err) - require.Equal(2, len(keyS)) + require.Nil(t, err) + require.Equal(t, 2, len(keyS)) // note these are in alphabetical order - assert.Equal(n2, keyS[0].Name) - assert.Equal(n1, keyS[1].Name) - assert.Equal(i2.PubKey, keyS[0].PubKey) + assert.Equal(t, n2, keyS[0].Name) + assert.Equal(t, n1, keyS[1].Name) + assert.Equal(t, i2.PubKey, keyS[0].PubKey) // deleting a key removes it err = cstore.Delete("bad name", "foo") - require.NotNil(err) + require.NotNil(t, err) err = cstore.Delete(n1, p1) - require.Nil(err) + require.Nil(t, err) keyS, err = cstore.List() - require.Nil(err) - assert.Equal(1, len(keyS)) + require.Nil(t, err) + assert.Equal(t, 1, len(keyS)) _, err = cstore.Get(n1) - assert.NotNil(err) + assert.NotNil(t, err) // make sure that it only signs with the right password // tx := mock.NewSig([]byte("mytransactiondata")) // err = cstore.Sign(n2, p1, tx) - // assert.NotNil(err) + // assert.NotNil(t, err) // err = cstore.Sign(n2, p2, tx) - // assert.Nil(err, "%+v", err) + // assert.Nil(t, err, "%+v", err) // sigs, err := tx.Signers() - // assert.Nil(err, "%+v", err) - // if assert.Equal(1, len(sigs)) { - // assert.Equal(i2.PubKey, sigs[0]) + // assert.Nil(t, err, "%+v", err) + // if assert.Equal(t, 1, len(sigs)) { + // assert.Equal(t, i2.PubKey, sigs[0]) // } } // TestSignVerify does some detailed checks on how we sign and validate // signatures func TestSignVerify(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) // make the storage with reasonable defaults cstore := keys.New( dbm.NewMemDB(), words.MustLoadCodec("english"), ) - algo := crypto.NameSecp256k1 + algo := keys.AlgoSecp256k1 n1, n2 := "some dude", "a dudette" p1, p2 := "1234", "foobar" // create two users and get their info - _, i1, err := cstore.Create(n1, p1, algo) - require.Nil(err) + i1, _, err := cstore.Create(n1, p1, algo) + require.Nil(t, err) - _, i2, err := cstore.Create(n2, p2, algo) - require.Nil(err) + i2, _, err := cstore.Create(n2, p2, algo) + require.Nil(t, err) // let's try to sign some messages d1 := []byte("my first message") @@ -112,20 +107,20 @@ func TestSignVerify(t *testing.T) { // try signing both data with both keys... s11, pub1, err := cstore.Sign(n1, p1, d1) - require.Nil(err) - require.Equal(i1.PubKey, pub1) + require.Nil(t, err) + require.Equal(t, i1.PubKey, pub1) s12, pub1, err := cstore.Sign(n1, p1, d2) - require.Nil(err) - require.Equal(i1.PubKey, pub1) + require.Nil(t, err) + require.Equal(t, i1.PubKey, pub1) s21, pub2, err := cstore.Sign(n2, p2, d1) - require.Nil(err) - require.Equal(i2.PubKey, pub2) + require.Nil(t, err) + require.Equal(t, i2.PubKey, pub2) s22, pub2, err := cstore.Sign(n2, p2, d2) - require.Nil(err) - require.Equal(i2.PubKey, pub2) + require.Nil(t, err) + require.Equal(t, i2.PubKey, pub2) // let's try to validate and make sure it only works when everything is proper cases := []struct { @@ -148,17 +143,17 @@ func TestSignVerify(t *testing.T) { for i, tc := range cases { valid := tc.key.VerifyBytes(tc.data, tc.sig) - assert.Equal(tc.valid, valid, "%d", i) + assert.Equal(t, tc.valid, valid, "%d", i) } } +/* // TestSignWithLedger makes sure we have ledger compatibility with // the crypto store. // // This test will only succeed with a ledger attached to the computer // and the cosmos app open func TestSignWithLedger(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) if os.Getenv("WITH_LEDGER") == "" { t.Skip("Set WITH_LEDGER to run code on real ledger") } @@ -172,19 +167,19 @@ func TestSignWithLedger(t *testing.T) { p := "hard2hack" // create a nano user - _, c, err := cstore.Create(n, p, nano.NameLedgerEd25519) - require.Nil(err, "%+v", err) - assert.Equal(c.Name, n) + c, _, err := cstore.Create(n, p, nano.KeyLedgerEd25519) + require.Nil(t, err, "%+v", err) + assert.Equal(t, c.Key, n) _, ok := c.PubKey.Unwrap().(nano.PubKeyLedgerEd25519) - require.True(ok) + require.True(t, ok) // make sure we can get it back info, err := cstore.Get(n) - require.Nil(err, "%+v", err) - assert.Equal(info.Name, n) + require.Nil(t, err, "%+v", err) + assert.Equal(t, info.Key, n) key := info.PubKey - require.False(key.Empty()) - require.True(key.Equals(c.PubKey)) + require.False(t ,key.Empty()) + require.True(t, key.Equals(c.PubKey)) // let's try to sign some messages d1 := []byte("welcome to cosmos") @@ -192,56 +187,64 @@ func TestSignWithLedger(t *testing.T) { // try signing both data with the ledger... s1, pub, err := cstore.Sign(n, p, d1) - require.Nil(err) - require.Equal(info.PubKey, pub) + require.Nil(t, err) + require.Equal(t, info.PubKey, pub) s2, pub, err := cstore.Sign(n, p, d2) - require.Nil(err) - require.Equal(info.PubKey, pub) + require.Nil(t, err) + require.Equal(t, info.PubKey, pub) // now, let's check those signatures work - assert.True(key.VerifyBytes(d1, s1)) - assert.True(key.VerifyBytes(d2, s2)) + assert.True(t, key.VerifyBytes(d1, s1)) + assert.True(t, key.VerifyBytes(d2, s2)) // and mismatched signatures don't - assert.False(key.VerifyBytes(d1, s2)) + assert.False(t, key.VerifyBytes(d1, s2)) } +*/ -func assertPassword(assert *asrt.Assertions, cstore keys.Keybase, name, pass, badpass string) { +func assertPassword(t *testing.T, cstore keys.Keybase, name, pass, badpass string) { err := cstore.Update(name, badpass, pass) - assert.NotNil(err) + assert.NotNil(t, err) err = cstore.Update(name, pass, pass) - assert.Nil(err, "%+v", err) + assert.Nil(t, err, "%+v", err) } -// TestImportUnencrypted tests accepting raw priv keys bytes as input -func TestImportUnencrypted(t *testing.T) { - require := rqr.New(t) +// TestExportImport tests exporting and importing keys. +func TestExportImport(t *testing.T) { // make the storage with reasonable defaults + db := dbm.NewMemDB() cstore := keys.New( - dbm.NewMemDB(), + db, words.MustLoadCodec("english"), ) - key := crypto.GenPrivKeyEd25519FromSecret(cmn.RandBytes(16)).Wrap() + info, _, err := cstore.Create("john", "passphrase", keys.AlgoEd25519) + assert.Nil(t, err) + assert.Equal(t, info.Name, "john") + addr := info.PubKey.Address() + + john, err := cstore.Get("john") + assert.Nil(t, err) + assert.Equal(t, john.Name, "john") + assert.Equal(t, john.PubKey.Address(), addr) - addr := key.PubKey().Address() - name := "john" - pass := "top-secret" + armor, err := cstore.Export("john") + assert.Nil(t, err) - // import raw bytes - err := cstore.Import(name, pass, "", key.Bytes()) - require.Nil(err, "%+v", err) + err = cstore.Import("john2", armor) + assert.Nil(t, err) - // make sure the address matches - info, err := cstore.Get(name) - require.Nil(err, "%+v", err) - require.EqualValues(addr, info.Address()) + john2, err := cstore.Get("john2") + assert.Nil(t, err) + + assert.Equal(t, john.PubKey.Address(), addr) + assert.Equal(t, john.Name, "john") + assert.Equal(t, john, john2) } // TestAdvancedKeyManagement verifies update, import, export functionality func TestAdvancedKeyManagement(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) // make the storage with reasonable defaults cstore := keys.New( @@ -249,42 +252,49 @@ func TestAdvancedKeyManagement(t *testing.T) { words.MustLoadCodec("english"), ) - algo := crypto.NameSecp256k1 + algo := keys.AlgoSecp256k1 n1, n2 := "old-name", "new name" - p1, p2, p3, pt := "1234", "foobar", "ding booms!", "really-secure!@#$" + p1, p2 := "1234", "foobar" // make sure key works with initial password _, _, err := cstore.Create(n1, p1, algo) - require.Nil(err, "%+v", err) - assertPassword(assert, cstore, n1, p1, p2) + require.Nil(t, err, "%+v", err) + assertPassword(t, cstore, n1, p1, p2) // update password requires the existing password err = cstore.Update(n1, "jkkgkg", p2) - assert.NotNil(err) - assertPassword(assert, cstore, n1, p1, p2) + assert.NotNil(t, err) + assertPassword(t, cstore, n1, p1, p2) // then it changes the password when correct err = cstore.Update(n1, p1, p2) - assert.Nil(err) + assert.Nil(t, err) // p2 is now the proper one! - assertPassword(assert, cstore, n1, p2, p1) + assertPassword(t, cstore, n1, p2, p1) // exporting requires the proper name and passphrase - _, err = cstore.Export(n2, p2, pt) - assert.NotNil(err) - _, err = cstore.Export(n1, p1, pt) - assert.NotNil(err) - exported, err := cstore.Export(n1, p2, pt) - require.Nil(err, "%+v", err) - - // import fails on bad transfer pass - err = cstore.Import(n2, p3, p2, exported) - assert.NotNil(err) + _, err = cstore.Export(n1 + ".notreal") + assert.NotNil(t, err) + _, err = cstore.Export(" " + n1) + assert.NotNil(t, err) + _, err = cstore.Export(n1 + " ") + assert.NotNil(t, err) + _, err = cstore.Export("") + assert.NotNil(t, err) + exported, err := cstore.Export(n1) + require.Nil(t, err, "%+v", err) + + // import succeeds + err = cstore.Import(n2, exported) + assert.Nil(t, err) + + // second import fails + err = cstore.Import(n2, exported) + assert.NotNil(t, err) } // TestSeedPhrase verifies restoring from a seed phrase func TestSeedPhrase(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) // make the storage with reasonable defaults cstore := keys.New( @@ -292,28 +302,28 @@ func TestSeedPhrase(t *testing.T) { words.MustLoadCodec("english"), ) - algo := crypto.NameEd25519 + algo := keys.AlgoEd25519 n1, n2 := "lost-key", "found-again" p1, p2 := "1234", "foobar" // make sure key works with initial password - seed, info, err := cstore.Create(n1, p1, algo) - require.Nil(err, "%+v", err) - assert.Equal(n1, info.Name) - assert.NotEmpty(seed) + info, seed, err := cstore.Create(n1, p1, algo) + require.Nil(t, err, "%+v", err) + assert.Equal(t, n1, info.Name) + assert.NotEmpty(t, seed) // now, let us delete this key err = cstore.Delete(n1, p1) - require.Nil(err, "%+v", err) + require.Nil(t, err, "%+v", err) _, err = cstore.Get(n1) - require.NotNil(err) + require.NotNil(t, err) // let us re-create it from the seed-phrase - newInfo, err := cstore.Recover(n2, p2, algo, seed) - require.Nil(err, "%+v", err) - assert.Equal(n2, newInfo.Name) - assert.Equal(info.Address(), newInfo.Address()) - assert.Equal(info.PubKey, newInfo.PubKey) + newInfo, err := cstore.Recover(n2, p2, seed) + require.Nil(t, err, "%+v", err) + assert.Equal(t, n2, newInfo.Name) + assert.Equal(t, info.Address(), newInfo.Address()) + assert.Equal(t, info.PubKey, newInfo.PubKey) } func ExampleNew() { @@ -322,11 +332,11 @@ func ExampleNew() { dbm.NewMemDB(), words.MustLoadCodec("english"), ) - ed := crypto.NameEd25519 - sec := crypto.NameSecp256k1 + ed := keys.AlgoEd25519 + sec := keys.AlgoSecp256k1 // Add keys and see they return in alphabetical order - _, bob, err := cstore.Create("Bob", "friend", ed) + bob, _, err := cstore.Create("Bob", "friend", ed) if err != nil { // this should never happen fmt.Println(err) diff --git a/keys/keys.go b/keys/keys.go new file mode 100644 index 000000000..0ed89b3fd --- /dev/null +++ b/keys/keys.go @@ -0,0 +1,32 @@ +package keys + +import "fmt" + +type CryptoAlgo string + +const ( + AlgoEd25519 = CryptoAlgo("ed25519") + AlgoSecp256k1 = CryptoAlgo("secp256k1") +) + +func cryptoAlgoToByte(key CryptoAlgo) byte { + switch key { + case AlgoEd25519: + return 0x01 + case AlgoSecp256k1: + return 0x02 + default: + panic(fmt.Sprintf("Unexpected type key %v", key)) + } +} + +func byteToCryptoAlgo(b byte) CryptoAlgo { + switch b { + case 0x01: + return AlgoEd25519 + case 0x02: + return AlgoSecp256k1 + default: + panic(fmt.Sprintf("Unexpected type byte %X", b)) + } +} diff --git a/keys/mintkey.go b/keys/mintkey.go index d2724d658..73263b83a 100644 --- a/keys/mintkey.go +++ b/keys/mintkey.go @@ -12,8 +12,34 @@ import ( const ( blockTypePrivKey = "TENDERMINT PRIVATE KEY" + blockTypeKeyInfo = "TENDERMINT KEY INFO" ) +func armorInfoBytes(bz []byte) string { + header := map[string]string{ + "type": "Info", + "version": "0.0.0", + } + armorStr := crypto.EncodeArmor(blockTypeKeyInfo, header, bz) + return armorStr +} + +func unarmorInfoBytes(armorStr string) (bz []byte, err error) { + blockType, header, bz, err := crypto.DecodeArmor(armorStr) + if err != nil { + return + } + if blockType != blockTypeKeyInfo { + err = fmt.Errorf("Unrecognized armor type: %v", blockType) + return + } + if header["version"] != "0.0.0" { + err = fmt.Errorf("Unrecognized version: %v", header["version"]) + return + } + return +} + func encryptArmorPrivKey(privKey crypto.PrivKey, passphrase string) string { saltBytes, encBytes := encryptPrivKey(privKey, passphrase) header := map[string]string{ diff --git a/keys/types.go b/keys/types.go index fdb729e0a..16b8f6dd0 100644 --- a/keys/types.go +++ b/keys/types.go @@ -1,15 +1,39 @@ package keys import ( - wire "github.com/tendermint/go-wire" - crypto "github.com/tendermint/go-crypto" ) +// Keybase allows simple CRUD on a keystore, as an aid to signing +type Keybase interface { + // Sign some bytes + Sign(name, passphrase string, msg []byte) (crypto.Signature, crypto.PubKey, error) + // Create a new keypair + Create(name, passphrase string, algo CryptoAlgo) (info Info, seed string, err error) + // Recover takes a seedphrase and loads in the key + Recover(name, passphrase, seedphrase string) (info Info, erro error) + List() ([]Info, error) + Get(name string) (Info, error) + Update(name, oldpass, newpass string) error + Delete(name, passphrase string) error + + Import(name string, armor string) (err error) + Export(name string) (armor string, err error) +} + // Info is the public information about a key type Info struct { - Name string `json:"name"` - PubKey crypto.PubKey `json:"pubkey"` + Name string `json:"name"` + PubKey crypto.PubKey `json:"pubkey"` + PrivKeyArmor string `json:"privkey.armor"` +} + +func newInfo(name string, pub crypto.PubKey, privArmor string) Info { + return Info{ + Name: name, + PubKey: pub, + PrivKeyArmor: privArmor, + } } // Address is a helper function to calculate the address from the pubkey @@ -18,31 +42,14 @@ func (i Info) Address() []byte { } func (i Info) bytes() []byte { - return wire.BinaryBytes(i) -} - -func readInfo(bs []byte) (info Info, err error) { - err = wire.ReadBinaryBytes(bs, &info) - return -} - -func info(name string, privKey crypto.PrivKey) Info { - return Info{ - Name: name, - PubKey: privKey.PubKey(), + bz, err := cdc.MarshalBinary(i) + if err != nil { + panic(err) } + return bz } -// Keybase allows simple CRUD on a keystore, as an aid to signing -type Keybase interface { - // Sign some bytes - Sign(name, passphrase string, msg []byte) (crypto.Signature, crypto.PubKey, error) - // Create a new keypair - Create(name, passphrase, algo string) (seedphrase string, _ Info, _ error) - // Recover takes a seedphrase and loads in the key - Recover(name, passphrase, algo, seedphrase string) (Info, error) - List() ([]Info, error) - Get(name string) (Info, error) - Update(name, oldpass, newpass string) error - Delete(name, passphrase string) error +func readInfo(bz []byte) (info Info, err error) { + err = cdc.UnmarshalBinary(bz, &info) + return } diff --git a/keys/wire.go b/keys/wire.go new file mode 100644 index 000000000..65d69ba5e --- /dev/null +++ b/keys/wire.go @@ -0,0 +1,12 @@ +package keys + +import ( + "github.com/tendermint/go-crypto" + "github.com/tendermint/go-wire" +) + +var cdc = wire.NewCodec() + +func init() { + crypto.RegisterWire(cdc) +} diff --git a/priv_key.go b/priv_key.go index 11dcb686f..b86b30f8b 100644 --- a/priv_key.go +++ b/priv_key.go @@ -7,89 +7,60 @@ import ( "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" "github.com/tendermint/go-wire" - data "github.com/tendermint/go-wire/data" . "github.com/tendermint/tmlibs/common" ) func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { - err = wire.ReadBinaryBytes(privKeyBytes, &privKey) - if err == nil { - // add support for a ValidateKey method on PrivKeys - // to make sure they load correctly - val, ok := privKey.Unwrap().(validatable) - if ok { - err = val.ValidateKey() - } - } + err = cdc.UnmarshalBinary(privKeyBytes, &privKey) return } -// validatable is an optional interface for keys that want to -// check integrity -type validatable interface { - ValidateKey() error -} - //---------------------------------------- -// DO NOT USE THIS INTERFACE. -// You probably want to use PrivKey -// +gen wrapper:"PrivKey,Impl[PrivKeyEd25519,PrivKeySecp256k1],ed25519,secp256k1" -type PrivKeyInner interface { - AssertIsPrivKeyInner() +type PrivKey interface { Bytes() []byte Sign(msg []byte) Signature PubKey() PubKey Equals(PrivKey) bool - Wrap() PrivKey } //------------------------------------- -var _ PrivKeyInner = PrivKeyEd25519{} +var _ PrivKey = PrivKeyEd25519{} // Implements PrivKey type PrivKeyEd25519 [64]byte -func (privKey PrivKeyEd25519) AssertIsPrivKeyInner() {} - func (privKey PrivKeyEd25519) Bytes() []byte { - return wire.BinaryBytes(PrivKey{privKey}) + bz, err := cdc.MarshalBinary(privKey) + if err != nil { + panic(err) + } + return bz } func (privKey PrivKeyEd25519) Sign(msg []byte) Signature { privKeyBytes := [64]byte(privKey) signatureBytes := ed25519.Sign(&privKeyBytes, msg) - return SignatureEd25519(*signatureBytes).Wrap() + return SignatureEd25519(*signatureBytes) } func (privKey PrivKeyEd25519) PubKey() PubKey { privKeyBytes := [64]byte(privKey) pubBytes := *ed25519.MakePublicKey(&privKeyBytes) - return PubKeyEd25519(pubBytes).Wrap() + return PubKeyEd25519(pubBytes) } // Equals - you probably don't need to use this. // Runs in constant time based on length of the keys. func (privKey PrivKeyEd25519) Equals(other PrivKey) bool { - if otherEd, ok := other.Unwrap().(PrivKeyEd25519); ok { + if otherEd, ok := other.(PrivKeyEd25519); ok { return subtle.ConstantTimeCompare(privKey[:], otherEd[:]) == 1 } else { return false } } -func (p PrivKeyEd25519) MarshalJSON() ([]byte, error) { - return data.Encoder.Marshal(p[:]) -} - -func (p *PrivKeyEd25519) UnmarshalJSON(enc []byte) error { - var ref []byte - err := data.Encoder.Unmarshal(&ref, enc) - copy(p[:], ref) - return err -} - func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte { keyCurve25519 := new([32]byte) privKeyBytes := [64]byte(privKey) @@ -97,16 +68,22 @@ func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte { return keyCurve25519 } +/* func (privKey PrivKeyEd25519) String() string { return Fmt("PrivKeyEd25519{*****}") } +*/ // Deterministically generates new priv-key bytes from key. func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519 { - newBytes := wire.BinarySha256(struct { + bz, err := wire.MarshalBinary(struct { PrivKey [64]byte Index int }{privKey, index}) + if err != nil { + panic(err) + } + newBytes := Sha256(bz) var newKey [64]byte copy(newKey[:], newBytes) return PrivKeyEd25519(newKey) @@ -131,15 +108,17 @@ func GenPrivKeyEd25519FromSecret(secret []byte) PrivKeyEd25519 { //------------------------------------- -var _ PrivKeyInner = PrivKeySecp256k1{} +var _ PrivKey = PrivKeySecp256k1{} // Implements PrivKey type PrivKeySecp256k1 [32]byte -func (privKey PrivKeySecp256k1) AssertIsPrivKeyInner() {} - func (privKey PrivKeySecp256k1) Bytes() []byte { - return wire.BinaryBytes(PrivKey{privKey}) + bz, err := cdc.MarshalBinary(privKey) + if err != nil { + panic(err) + } + return bz } func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature { @@ -148,40 +127,31 @@ func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature { if err != nil { PanicSanity(err) } - return SignatureSecp256k1(sig__.Serialize()).Wrap() + return SignatureSecp256k1(sig__.Serialize()) } func (privKey PrivKeySecp256k1) PubKey() PubKey { _, pub__ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) var pub PubKeySecp256k1 copy(pub[:], pub__.SerializeCompressed()) - return pub.Wrap() + return pub } // Equals - you probably don't need to use this. // Runs in constant time based on length of the keys. func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool { - if otherSecp, ok := other.Unwrap().(PrivKeySecp256k1); ok { + if otherSecp, ok := other.(PrivKeySecp256k1); ok { return subtle.ConstantTimeCompare(privKey[:], otherSecp[:]) == 1 } else { return false } } -func (p PrivKeySecp256k1) MarshalJSON() ([]byte, error) { - return data.Encoder.Marshal(p[:]) -} - -func (p *PrivKeySecp256k1) UnmarshalJSON(enc []byte) error { - var ref []byte - err := data.Encoder.Unmarshal(&ref, enc) - copy(p[:], ref) - return err -} - +/* func (privKey PrivKeySecp256k1) String() string { return Fmt("PrivKeySecp256k1{*****}") } +*/ /* // Deterministically generates new priv-key bytes from key. diff --git a/priv_key_test.go b/priv_key_test.go index 154df5593..3fbfba34d 100644 --- a/priv_key_test.go +++ b/priv_key_test.go @@ -1,42 +1,26 @@ package crypto +/* + import ( "fmt" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - - wire "github.com/tendermint/go-wire" ) type BadKey struct { PrivKeyEd25519 } -// Wrap fulfils interface for PrivKey struct -func (pk BadKey) Wrap() PrivKey { - return PrivKey{pk} -} - -func (pk BadKey) Bytes() []byte { - return wire.BinaryBytes(pk.Wrap()) -} - -func (pk BadKey) ValidateKey() error { - return fmt.Errorf("fuggly key") -} - -func init() { - PrivKeyMapper. - RegisterImplementation(BadKey{}, "bad", 0x66) -} - func TestReadPrivKey(t *testing.T) { assert, require := assert.New(t), require.New(t) // garbage in, garbage out garbage := []byte("hjgewugfbiewgofwgewr") + XXX This test wants to register BadKey globally to go-crypto, + but we don't want to support that. _, err := PrivKeyFromBytes(garbage) require.Error(err) @@ -47,13 +31,15 @@ func TestReadPrivKey(t *testing.T) { key PrivKey valid bool }{ - {edKey.Wrap(), true}, - {badKey.Wrap(), false}, + {edKey, true}, + {badKey, false}, } for i, tc := range cases { data := tc.key.Bytes() + fmt.Println(">>>", data) key, err := PrivKeyFromBytes(data) + fmt.Printf("!!! %#v\n", key, err) if tc.valid { assert.NoError(err, "%d", i) assert.Equal(tc.key, key, "%d", i) @@ -61,5 +47,5 @@ func TestReadPrivKey(t *testing.T) { assert.Error(err, "%d: %#v", i, key) } } - } +*/ diff --git a/privkeyinner_wrapper.go b/privkeyinner_wrapper.go deleted file mode 100644 index 05ce69672..000000000 --- a/privkeyinner_wrapper.go +++ /dev/null @@ -1,62 +0,0 @@ -// Generated by: main -// TypeWriter: wrapper -// Directive: +gen on PrivKeyInner - -package crypto - -import ( - "github.com/tendermint/go-wire/data" -) - -// Auto-generated adapters for happily unmarshaling interfaces -// Apache License 2.0 -// Copyright (c) 2017 Ethan Frey (ethan.frey@tendermint.com) - -type PrivKey struct { - PrivKeyInner "json:\"unwrap\"" -} - -var PrivKeyMapper = data.NewMapper(PrivKey{}) - -func (h PrivKey) MarshalJSON() ([]byte, error) { - return PrivKeyMapper.ToJSON(h.PrivKeyInner) -} - -func (h *PrivKey) UnmarshalJSON(data []byte) (err error) { - parsed, err := PrivKeyMapper.FromJSON(data) - if err == nil && parsed != nil { - h.PrivKeyInner = parsed.(PrivKeyInner) - } - return err -} - -// Unwrap recovers the concrete interface safely (regardless of levels of embeds) -func (h PrivKey) Unwrap() PrivKeyInner { - hi := h.PrivKeyInner - for wrap, ok := hi.(PrivKey); ok; wrap, ok = hi.(PrivKey) { - hi = wrap.PrivKeyInner - } - return hi -} - -func (h PrivKey) Empty() bool { - return h.PrivKeyInner == nil -} - -/*** below are bindings for each implementation ***/ - -func init() { - PrivKeyMapper.RegisterImplementation(PrivKeyEd25519{}, "ed25519", 0x1) -} - -func (hi PrivKeyEd25519) Wrap() PrivKey { - return PrivKey{hi} -} - -func init() { - PrivKeyMapper.RegisterImplementation(PrivKeySecp256k1{}, "secp256k1", 0x2) -} - -func (hi PrivKeySecp256k1) Wrap() PrivKey { - return PrivKey{hi} -} diff --git a/pub_key.go b/pub_key.go index 32c0b3237..8ed1df356 100644 --- a/pub_key.go +++ b/pub_key.go @@ -8,8 +8,6 @@ import ( secp256k1 "github.com/btcsuite/btcd/btcec" "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" - "github.com/tendermint/go-wire" - data "github.com/tendermint/go-wire/data" cmn "github.com/tendermint/tmlibs/common" "golang.org/x/crypto/ripemd160" ) @@ -20,56 +18,44 @@ import ( type Address = cmn.HexBytes func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { - if err := wire.ReadBinaryBytes(pubKeyBytes, &pubKey); err != nil { - return PubKey{}, err - } - return pubKey, nil + err = cdc.UnmarshalBinary(pubKeyBytes, &pubKey) + return } //---------------------------------------- -// DO NOT USE THIS INTERFACE. -// You probably want to use PubKey -// +gen wrapper:"PubKey,Impl[PubKeyEd25519,PubKeySecp256k1],ed25519,secp256k1" -type PubKeyInner interface { - AssertIsPubKeyInner() +type PubKey interface { Address() Address Bytes() []byte - KeyString() string VerifyBytes(msg []byte, sig Signature) bool Equals(PubKey) bool - Wrap() PubKey } //------------------------------------- -var _ PubKeyInner = PubKeyEd25519{} +var _ PubKey = PubKeyEd25519{} // Implements PubKeyInner type PubKeyEd25519 [32]byte -func (pubKey PubKeyEd25519) AssertIsPubKeyInner() {} - func (pubKey PubKeyEd25519) Address() Address { - w, n, err := new(bytes.Buffer), new(int), new(error) - wire.WriteBinary(pubKey[:], w, n, err) - if *err != nil { - panic(*err) - } // append type byte - encodedPubkey := append([]byte{TypeEd25519}, w.Bytes()...) hasher := ripemd160.New() - hasher.Write(encodedPubkey) // does not error + hasher.Write(pubKey.Bytes()) // does not error return Address(hasher.Sum(nil)) } func (pubKey PubKeyEd25519) Bytes() []byte { - return wire.BinaryBytes(PubKey{pubKey}) + bz, err := cdc.MarshalBinary(pubKey) + if err != nil { + panic(err) + } + return bz } func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool { // make sure we use the same algorithm to sign - sig, ok := sig_.Unwrap().(SignatureEd25519) + sig, ok := sig_.(SignatureEd25519) if !ok { return false } @@ -78,17 +64,6 @@ func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool { return ed25519.Verify(&pubKeyBytes, msg, &sigBytes) } -func (p PubKeyEd25519) MarshalJSON() ([]byte, error) { - return data.Encoder.Marshal(p[:]) -} - -func (p *PubKeyEd25519) UnmarshalJSON(enc []byte) error { - var ref []byte - err := data.Encoder.Unmarshal(&ref, enc) - copy(p[:], ref) - return err -} - // For use with golang/crypto/nacl/box // If error, returns nil. func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte { @@ -104,14 +79,8 @@ func (pubKey PubKeyEd25519) String() string { return fmt.Sprintf("PubKeyEd25519{%X}", pubKey[:]) } -// Must return the full bytes in hex. -// Used for map keying, etc. -func (pubKey PubKeyEd25519) KeyString() string { - return fmt.Sprintf("%X", pubKey[:]) -} - func (pubKey PubKeyEd25519) Equals(other PubKey) bool { - if otherEd, ok := other.Unwrap().(PubKeyEd25519); ok { + if otherEd, ok := other.(PubKeyEd25519); ok { return bytes.Equal(pubKey[:], otherEd[:]) } else { return false @@ -120,15 +89,13 @@ func (pubKey PubKeyEd25519) Equals(other PubKey) bool { //------------------------------------- -var _ PubKeyInner = PubKeySecp256k1{} +var _ PubKey = PubKeySecp256k1{} // Implements PubKey. // Compressed pubkey (just the x-cord), // prefixed with 0x02 or 0x03, depending on the y-cord. type PubKeySecp256k1 [33]byte -func (pubKey PubKeySecp256k1) AssertIsPubKeyInner() {} - // Implements Bitcoin style addresses: RIPEMD160(SHA256(pubkey)) func (pubKey PubKeySecp256k1) Address() Address { hasherSHA256 := sha256.New() @@ -141,12 +108,16 @@ func (pubKey PubKeySecp256k1) Address() Address { } func (pubKey PubKeySecp256k1) Bytes() []byte { - return wire.BinaryBytes(PubKey{pubKey}) + bz, err := cdc.MarshalBinary(pubKey) + if err != nil { + panic(err) + } + return bz } func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool { // and assert same algorithm to sign and verify - sig, ok := sig_.Unwrap().(SignatureSecp256k1) + sig, ok := sig_.(SignatureSecp256k1) if !ok { return false } @@ -162,29 +133,12 @@ func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool { return sig__.Verify(Sha256(msg), pub__) } -func (p PubKeySecp256k1) MarshalJSON() ([]byte, error) { - return data.Encoder.Marshal(p[:]) -} - -func (p *PubKeySecp256k1) UnmarshalJSON(enc []byte) error { - var ref []byte - err := data.Encoder.Unmarshal(&ref, enc) - copy(p[:], ref) - return err -} - func (pubKey PubKeySecp256k1) String() string { return fmt.Sprintf("PubKeySecp256k1{%X}", pubKey[:]) } -// Must return the full bytes in hex. -// Used for map keying, etc. -func (pubKey PubKeySecp256k1) KeyString() string { - return fmt.Sprintf("%X", pubKey[:]) -} - func (pubKey PubKeySecp256k1) Equals(other PubKey) bool { - if otherSecp, ok := other.Unwrap().(PubKeySecp256k1); ok { + if otherSecp, ok := other.(PubKeySecp256k1); ok { return bytes.Equal(pubKey[:], otherSecp[:]) } else { return false diff --git a/pub_key_test.go b/pub_key_test.go index 95c82534d..29672390b 100644 --- a/pub_key_test.go +++ b/pub_key_test.go @@ -33,7 +33,7 @@ func TestPubKeySecp256k1Address(t *testing.T) { var priv PrivKeySecp256k1 copy(priv[:], privB) - pubT := priv.PubKey().Unwrap().(PubKeySecp256k1) + pubT := priv.PubKey().(PubKeySecp256k1) pub := pubT[:] addr := priv.PubKey().Address() @@ -45,5 +45,5 @@ func TestPubKeySecp256k1Address(t *testing.T) { func TestPubKeyInvalidDataProperReturnsEmpty(t *testing.T) { pk, err := PubKeyFromBytes([]byte("foo")) require.NotNil(t, err, "expecting a non-nil error") - require.True(t, pk.Empty(), "expecting an empty public key on error") + require.Nil(t, pk, "expecting an empty public key on error") } diff --git a/pubkeyinner_wrapper.go b/pubkeyinner_wrapper.go deleted file mode 100644 index 7b36c324d..000000000 --- a/pubkeyinner_wrapper.go +++ /dev/null @@ -1,62 +0,0 @@ -// Generated by: main -// TypeWriter: wrapper -// Directive: +gen on PubKeyInner - -package crypto - -import ( - "github.com/tendermint/go-wire/data" -) - -// Auto-generated adapters for happily unmarshaling interfaces -// Apache License 2.0 -// Copyright (c) 2017 Ethan Frey (ethan.frey@tendermint.com) - -type PubKey struct { - PubKeyInner "json:\"unwrap\"" -} - -var PubKeyMapper = data.NewMapper(PubKey{}) - -func (h PubKey) MarshalJSON() ([]byte, error) { - return PubKeyMapper.ToJSON(h.PubKeyInner) -} - -func (h *PubKey) UnmarshalJSON(data []byte) (err error) { - parsed, err := PubKeyMapper.FromJSON(data) - if err == nil && parsed != nil { - h.PubKeyInner = parsed.(PubKeyInner) - } - return err -} - -// Unwrap recovers the concrete interface safely (regardless of levels of embeds) -func (h PubKey) Unwrap() PubKeyInner { - hi := h.PubKeyInner - for wrap, ok := hi.(PubKey); ok; wrap, ok = hi.(PubKey) { - hi = wrap.PubKeyInner - } - return hi -} - -func (h PubKey) Empty() bool { - return h.PubKeyInner == nil -} - -/*** below are bindings for each implementation ***/ - -func init() { - PubKeyMapper.RegisterImplementation(PubKeyEd25519{}, "ed25519", 0x1) -} - -func (hi PubKeyEd25519) Wrap() PubKey { - return PubKey{hi} -} - -func init() { - PubKeyMapper.RegisterImplementation(PubKeySecp256k1{}, "secp256k1", 0x2) -} - -func (hi PubKeySecp256k1) Wrap() PubKey { - return PubKey{hi} -} diff --git a/signature.go b/signature.go index cd40331cf..3a0f6a7a7 100644 --- a/signature.go +++ b/signature.go @@ -4,40 +4,35 @@ import ( "bytes" "fmt" - "github.com/tendermint/go-wire" - data "github.com/tendermint/go-wire/data" . "github.com/tendermint/tmlibs/common" ) -func SignatureFromBytes(sigBytes []byte) (sig Signature, err error) { - err = wire.ReadBinaryBytes(sigBytes, &sig) +func SignatureFromBytes(pubKeyBytes []byte) (pubKey Signature, err error) { + err = cdc.UnmarshalBinary(pubKeyBytes, &pubKey) return } //---------------------------------------- -// DO NOT USE THIS INTERFACE. -// You probably want to use Signature. -// +gen wrapper:"Signature,Impl[SignatureEd25519,SignatureSecp256k1],ed25519,secp256k1" -type SignatureInner interface { - AssertIsSignatureInner() +type Signature interface { Bytes() []byte IsZero() bool Equals(Signature) bool - Wrap() Signature } //------------------------------------- -var _ SignatureInner = SignatureEd25519{} +var _ Signature = SignatureEd25519{} // Implements Signature type SignatureEd25519 [64]byte -func (sig SignatureEd25519) AssertIsSignatureInner() {} - func (sig SignatureEd25519) Bytes() []byte { - return wire.BinaryBytes(Signature{sig}) + bz, err := cdc.MarshalBinary(sig) + if err != nil { + panic(err) + } + return bz } func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 } @@ -45,41 +40,32 @@ func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 } func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } func (sig SignatureEd25519) Equals(other Signature) bool { - if otherEd, ok := other.Unwrap().(SignatureEd25519); ok { + if otherEd, ok := other.(SignatureEd25519); ok { return bytes.Equal(sig[:], otherEd[:]) } else { return false } } -func (sig SignatureEd25519) MarshalJSON() ([]byte, error) { - return data.Encoder.Marshal(sig[:]) -} - -func (sig *SignatureEd25519) UnmarshalJSON(enc []byte) error { - var ref []byte - err := data.Encoder.Unmarshal(&ref, enc) - copy(sig[:], ref) - return err -} - func SignatureEd25519FromBytes(data []byte) Signature { var sig SignatureEd25519 copy(sig[:], data) - return sig.Wrap() + return sig } //------------------------------------- -var _ SignatureInner = SignatureSecp256k1{} +var _ Signature = SignatureSecp256k1{} // Implements Signature type SignatureSecp256k1 []byte -func (sig SignatureSecp256k1) AssertIsSignatureInner() {} - func (sig SignatureSecp256k1) Bytes() []byte { - return wire.BinaryBytes(Signature{sig}) + bz, err := cdc.MarshalBinary(sig) + if err != nil { + panic(err) + } + return bz } func (sig SignatureSecp256k1) IsZero() bool { return len(sig) == 0 } @@ -87,17 +73,9 @@ func (sig SignatureSecp256k1) IsZero() bool { return len(sig) == 0 } func (sig SignatureSecp256k1) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } func (sig SignatureSecp256k1) Equals(other Signature) bool { - if otherSecp, ok := other.Unwrap().(SignatureSecp256k1); ok { + if otherSecp, ok := other.(SignatureSecp256k1); ok { return bytes.Equal(sig[:], otherSecp[:]) } else { return false } } - -func (sig SignatureSecp256k1) MarshalJSON() ([]byte, error) { - return data.Encoder.Marshal(sig) -} - -func (sig *SignatureSecp256k1) UnmarshalJSON(enc []byte) error { - return data.Encoder.Unmarshal((*[]byte)(sig), enc) -} diff --git a/signature_test.go b/signature_test.go index 08e51940b..7bc94e677 100644 --- a/signature_test.go +++ b/signature_test.go @@ -1,13 +1,12 @@ package crypto import ( - "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tendermint/ed25519" - data "github.com/tendermint/go-wire/data" + "github.com/tendermint/go-wire" ) func TestSignAndValidateEd25519(t *testing.T) { @@ -22,9 +21,9 @@ func TestSignAndValidateEd25519(t *testing.T) { assert.True(t, pubKey.VerifyBytes(msg, sig)) // Mutate the signature, just one bit. - sigEd := sig.Unwrap().(SignatureEd25519) + sigEd := sig.(SignatureEd25519) sigEd[7] ^= byte(0x01) - sig = sigEd.Wrap() + sig = sigEd assert.False(t, pubKey.VerifyBytes(msg, sig)) } @@ -39,31 +38,28 @@ func TestSignAndValidateSecp256k1(t *testing.T) { assert.True(t, pubKey.VerifyBytes(msg, sig)) // Mutate the signature, just one bit. - sigEd := sig.Unwrap().(SignatureSecp256k1) + sigEd := sig.(SignatureSecp256k1) sigEd[3] ^= byte(0x01) - sig = sigEd.Wrap() + sig = sigEd assert.False(t, pubKey.VerifyBytes(msg, sig)) } func TestSignatureEncodings(t *testing.T) { cases := []struct { - privKey PrivKey - sigSize int - sigType byte - sigName string + privKey PrivKey + sigSize int + sigPrefix wire.PrefixBytes }{ { - privKey: GenPrivKeyEd25519().Wrap(), - sigSize: ed25519.SignatureSize, - sigType: TypeEd25519, - sigName: NameEd25519, + privKey: GenPrivKeyEd25519(), + sigSize: ed25519.SignatureSize, + sigPrefix: [4]byte{0xe4, 0x51, 0x7b, 0xa3}, }, { - privKey: GenPrivKeySecp256k1().Wrap(), - sigSize: 0, // unknown - sigType: TypeSecp256k1, - sigName: NameSecp256k1, + privKey: GenPrivKeySecp256k1(), + sigSize: 0, // unknown + sigPrefix: [4]byte{0x37, 0xb9, 0x21, 0x3e}, }, } @@ -75,91 +71,37 @@ func TestSignatureEncodings(t *testing.T) { sig := tc.privKey.Sign(msg) // store as wire - bin, err := data.ToWire(sig) + bin, err := cdc.MarshalBinary(sig) require.Nil(t, err, "%+v", err) if tc.sigSize != 0 { - assert.Equal(t, tc.sigSize+1, len(bin)) + assert.Equal(t, tc.sigSize+4, len(bin)) } - assert.Equal(t, tc.sigType, bin[0]) + assert.Equal(t, tc.sigPrefix[:], bin[0:4]) // and back - sig2 := Signature{} - err = data.FromWire(bin, &sig2) + sig2 := Signature(nil) + err = cdc.UnmarshalBinary(bin, &sig2) require.Nil(t, err, "%+v", err) assert.EqualValues(t, sig, sig2) assert.True(t, pubKey.VerifyBytes(msg, sig2)) - // store as json - js, err := data.ToJSON(sig) - require.Nil(t, err, "%+v", err) - assert.True(t, strings.Contains(string(js), tc.sigName)) - - // and back - sig3 := Signature{} - err = data.FromJSON(js, &sig3) - require.Nil(t, err, "%+v", err) - assert.EqualValues(t, sig, sig3) - assert.True(t, pubKey.VerifyBytes(msg, sig3)) - - // and make sure we can textify it - text, err := data.ToText(sig) - require.Nil(t, err, "%+v", err) - assert.True(t, strings.HasPrefix(text, tc.sigName)) - } -} - -func TestWrapping(t *testing.T) { - // construct some basic constructs - msg := CRandBytes(128) - priv := GenPrivKeyEd25519() - pub := priv.PubKey() - sig := priv.Sign(msg) - - // do some wrapping - pubs := []PubKey{ - PubKey{nil}, - pub.Wrap(), - pub.Wrap().Wrap().Wrap(), - PubKey{PubKey{PubKey{pub}}}.Wrap(), - } - for _, p := range pubs { - _, ok := p.PubKeyInner.(PubKey) - assert.False(t, ok) - } - - sigs := []Signature{ - Signature{nil}, - sig.Wrap(), - sig.Wrap().Wrap().Wrap(), - Signature{Signature{Signature{sig}}}.Wrap(), - } - for _, s := range sigs { - _, ok := s.SignatureInner.(Signature) - assert.False(t, ok) - } - -} - -func TestPrivKeyEquality(t *testing.T) { - { - privKey := GenPrivKeySecp256k1().Wrap() - privKey2 := GenPrivKeySecp256k1().Wrap() - assert.False(t, privKey.Equals(privKey2)) - assert.False(t, privKey2.Equals(privKey)) - - privKeyCopy := privKey // copy - assert.True(t, privKey.Equals(privKeyCopy)) - assert.True(t, privKeyCopy.Equals(privKey)) - } - - { - privKey := GenPrivKeyEd25519().Wrap() - privKey2 := GenPrivKeyEd25519().Wrap() - assert.False(t, privKey.Equals(privKey2)) - assert.False(t, privKey2.Equals(privKey)) - - privKeyCopy := privKey // copy - assert.True(t, privKey.Equals(privKeyCopy)) - assert.True(t, privKeyCopy.Equals(privKey)) + /* + // store as json + js, err := data.ToJSON(sig) + require.Nil(t, err, "%+v", err) + assert.True(t, strings.Contains(string(js), tc.sigName)) + + // and back + sig3 := Signature{} + err = data.FromJSON(js, &sig3) + require.Nil(t, err, "%+v", err) + assert.EqualValues(t, sig, sig3) + assert.True(t, pubKey.VerifyBytes(msg, sig3)) + + // and make sure we can textify it + text, err := data.ToText(sig) + require.Nil(t, err, "%+v", err) + assert.True(t, strings.HasPrefix(text, tc.sigName)) + */ } } diff --git a/signatureinner_wrapper.go b/signatureinner_wrapper.go deleted file mode 100644 index 1fdd790d6..000000000 --- a/signatureinner_wrapper.go +++ /dev/null @@ -1,62 +0,0 @@ -// Generated by: main -// TypeWriter: wrapper -// Directive: +gen on SignatureInner - -package crypto - -import ( - "github.com/tendermint/go-wire/data" -) - -// Auto-generated adapters for happily unmarshaling interfaces -// Apache License 2.0 -// Copyright (c) 2017 Ethan Frey (ethan.frey@tendermint.com) - -type Signature struct { - SignatureInner "json:\"unwrap\"" -} - -var SignatureMapper = data.NewMapper(Signature{}) - -func (h Signature) MarshalJSON() ([]byte, error) { - return SignatureMapper.ToJSON(h.SignatureInner) -} - -func (h *Signature) UnmarshalJSON(data []byte) (err error) { - parsed, err := SignatureMapper.FromJSON(data) - if err == nil && parsed != nil { - h.SignatureInner = parsed.(SignatureInner) - } - return err -} - -// Unwrap recovers the concrete interface safely (regardless of levels of embeds) -func (h Signature) Unwrap() SignatureInner { - hi := h.SignatureInner - for wrap, ok := hi.(Signature); ok; wrap, ok = hi.(Signature) { - hi = wrap.SignatureInner - } - return hi -} - -func (h Signature) Empty() bool { - return h.SignatureInner == nil -} - -/*** below are bindings for each implementation ***/ - -func init() { - SignatureMapper.RegisterImplementation(SignatureEd25519{}, "ed25519", 0x1) -} - -func (hi SignatureEd25519) Wrap() Signature { - return Signature{hi} -} - -func init() { - SignatureMapper.RegisterImplementation(SignatureSecp256k1{}, "secp256k1", 0x2) -} - -func (hi SignatureSecp256k1) Wrap() Signature { - return Signature{hi} -} diff --git a/wire.go b/wire.go new file mode 100644 index 000000000..18035964f --- /dev/null +++ b/wire.go @@ -0,0 +1,36 @@ +package crypto + +import ( + "github.com/tendermint/go-wire" +) + +var cdc = wire.NewCodec() + +func init() { + // NOTE: It's important that there be no conflicts here, + // as that would change the canonical representations, + // and therefore change the address. + // TODO: Add feature to go-wire to ensure that there + // are no conflicts. + RegisterWire(cdc) +} + +func RegisterWire(cdc *wire.Codec) { + cdc.RegisterInterface((*PubKey)(nil), nil) + cdc.RegisterConcrete(PubKeyEd25519{}, + "com.tendermint.wire.PubKeyEd25519", nil) + cdc.RegisterConcrete(PubKeySecp256k1{}, + "com.tendermint.wire.PubKeySecp256k1", nil) + + cdc.RegisterInterface((*PrivKey)(nil), nil) + cdc.RegisterConcrete(PrivKeyEd25519{}, + "com.tendermint.wire.PrivKeyEd25519", nil) + cdc.RegisterConcrete(PrivKeySecp256k1{}, + "com.tendermint.wire.PrivKeySecp256k1", nil) + + cdc.RegisterInterface((*Signature)(nil), nil) + cdc.RegisterConcrete(SignatureEd25519{}, + "com.tendermint.wire.SignatureKeyEd25519", nil) + cdc.RegisterConcrete(SignatureSecp256k1{}, + "com.tendermint.wire.SignatureKeySecp256k1", nil) +} From 32741be2126500d600cede1e2016bbbe2754cb46 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sun, 14 Jan 2018 17:40:16 -0500 Subject: [PATCH 195/287] update glide for go-wire and tmlibs --- glide.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/glide.lock b/glide.lock index c8e47160f..4cdfefa8c 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ hash: ed34b08bfc24f64edbc1a16ad2e34198afefc0e2dc133be2c92c6f764f953234 -updated: 2018-01-13T18:02:43.833267692-08:00 +updated: 2018-01-14T17:39:01.480031112-05:00 imports: - name: github.com/btcsuite/btcd version: 2e60448ffcc6bf78332d1fe590260095f554dd78 @@ -14,7 +14,7 @@ imports: subpackages: - spew - name: github.com/go-kit/kit - version: e2b298466b32c7cd5579a9b9b07e968fc9d9452c + version: 953e747656a7bbb5e1f998608b460458958b70cc subpackages: - log - log/level @@ -22,7 +22,7 @@ imports: - name: github.com/go-logfmt/logfmt version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5 - name: github.com/go-stack/stack - version: 817915b46b97fd7bb80e8ab6b69f01a53ac3eebf + version: 259ab82a6cad3992b4e21ff5cac294ccb06474bc - name: github.com/gogo/protobuf version: 342cbe0a04158f6dcb03ca0079991a51a4248c02 subpackages: @@ -40,7 +40,7 @@ imports: - name: github.com/pkg/errors version: 645ef00459ed84a119197bfb8d8205042c6df63d - name: github.com/syndtr/goleveldb - version: b89cc31ef7977104127d34c1bd31ebd1a9db2199 + version: 34011bf325bce385408353a30b101fe5e923eb6e subpackages: - leveldb - leveldb/cache @@ -60,15 +60,15 @@ imports: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: fde4a0bf4dd4c0ec0df2504f79f23ed7e6b3b452 + version: b93ebdd4f306833936c243561ec30af3455dc764 - name: github.com/tendermint/tmlibs - version: 2bb538b150f197a04a0b969a27e9ea24d35edbc1 + version: f2bc5432c31974bb3f5b1a80a53c38e37d481b8d subpackages: - common - db - log - name: golang.org/x/crypto - version: edd5e9b0879d13ee6970a50153d85b8fec9f7686 + version: 95a4943f35d008beabde8c11e5075a1b714e6419 subpackages: - bcrypt - blowfish From 12142af1cb4e3479ea4ac98a3171debff87519c6 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sun, 21 Jan 2018 19:03:23 -0800 Subject: [PATCH 196/287] Remove reliance on global wire.Marshal --- glide.lock | 14 +++++++------- priv_key.go | 5 ++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/glide.lock b/glide.lock index 4cdfefa8c..768641d19 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ hash: ed34b08bfc24f64edbc1a16ad2e34198afefc0e2dc133be2c92c6f764f953234 -updated: 2018-01-14T17:39:01.480031112-05:00 +updated: 2018-01-21T19:02:30.081003208-08:00 imports: - name: github.com/btcsuite/btcd version: 2e60448ffcc6bf78332d1fe590260095f554dd78 @@ -14,7 +14,7 @@ imports: subpackages: - spew - name: github.com/go-kit/kit - version: 953e747656a7bbb5e1f998608b460458958b70cc + version: e2b298466b32c7cd5579a9b9b07e968fc9d9452c subpackages: - log - log/level @@ -22,7 +22,7 @@ imports: - name: github.com/go-logfmt/logfmt version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5 - name: github.com/go-stack/stack - version: 259ab82a6cad3992b4e21ff5cac294ccb06474bc + version: 817915b46b97fd7bb80e8ab6b69f01a53ac3eebf - name: github.com/gogo/protobuf version: 342cbe0a04158f6dcb03ca0079991a51a4248c02 subpackages: @@ -40,7 +40,7 @@ imports: - name: github.com/pkg/errors version: 645ef00459ed84a119197bfb8d8205042c6df63d - name: github.com/syndtr/goleveldb - version: 34011bf325bce385408353a30b101fe5e923eb6e + version: b89cc31ef7977104127d34c1bd31ebd1a9db2199 subpackages: - leveldb - leveldb/cache @@ -60,15 +60,15 @@ imports: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: b93ebdd4f306833936c243561ec30af3455dc764 + version: 0cce10e82786f2d501827fbe158747dbc4ceeb43 - name: github.com/tendermint/tmlibs - version: f2bc5432c31974bb3f5b1a80a53c38e37d481b8d + version: 7a52d47a1676a9fe61d07fde0a48a733cce564c6 subpackages: - common - db - log - name: golang.org/x/crypto - version: 95a4943f35d008beabde8c11e5075a1b714e6419 + version: edd5e9b0879d13ee6970a50153d85b8fec9f7686 subpackages: - bcrypt - blowfish diff --git a/priv_key.go b/priv_key.go index b86b30f8b..adacb1379 100644 --- a/priv_key.go +++ b/priv_key.go @@ -6,7 +6,6 @@ import ( secp256k1 "github.com/btcsuite/btcd/btcec" "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" - "github.com/tendermint/go-wire" . "github.com/tendermint/tmlibs/common" ) @@ -76,7 +75,7 @@ func (privKey PrivKeyEd25519) String() string { // Deterministically generates new priv-key bytes from key. func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519 { - bz, err := wire.MarshalBinary(struct { + bz, err := cdc.MarshalBinary(struct { PrivKey [64]byte Index int }{privKey, index}) @@ -156,7 +155,7 @@ func (privKey PrivKeySecp256k1) String() string { /* // Deterministically generates new priv-key bytes from key. func (key PrivKeySecp256k1) Generate(index int) PrivKeySecp256k1 { - newBytes := wire.BinarySha256(struct { + newBytes := cdc.BinarySha256(struct { PrivKey [64]byte Index int }{key, index}) From 6b2409f714c7cd8709be64dcdd98e51460335a70 Mon Sep 17 00:00:00 2001 From: Adrian Brink Date: Fri, 2 Feb 2018 14:12:29 +0100 Subject: [PATCH 197/287] Update go-wire to develop --- glide.lock | 14 +++++++------- glide.yaml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/glide.lock b/glide.lock index 768641d19..1c6825b35 100644 --- a/glide.lock +++ b/glide.lock @@ -1,8 +1,8 @@ -hash: ed34b08bfc24f64edbc1a16ad2e34198afefc0e2dc133be2c92c6f764f953234 -updated: 2018-01-21T19:02:30.081003208-08:00 +hash: fd4a3648af3dd1d49623ce248ba98804bf5a9c6a1bc28d61d93d5e878ccd04d4 +updated: 2018-02-02T14:07:48.239589+01:00 imports: - name: github.com/btcsuite/btcd - version: 2e60448ffcc6bf78332d1fe590260095f554dd78 + version: c7588cbf7690cd9f047a28efa2dcd8f2435a4e5e subpackages: - btcec - name: github.com/btcsuite/btcutil @@ -55,14 +55,14 @@ imports: - leveldb/table - leveldb/util - name: github.com/tendermint/ed25519 - version: d8387025d2b9d158cf4efb07e7ebf814bcce2057 + version: 1f52c6f8b8a5c7908aff4497c186af344b428925 subpackages: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: 0cce10e82786f2d501827fbe158747dbc4ceeb43 + version: e723d95ac2838b7ae9919ada25004859236c32ff - name: github.com/tendermint/tmlibs - version: 7a52d47a1676a9fe61d07fde0a48a733cce564c6 + version: 95b53c80e1771be6b8c7083771a417e2a888c765 subpackages: - common - db @@ -87,7 +87,7 @@ testImports: subpackages: - difflib - name: github.com/stretchr/testify - version: b91bfb9ebec76498946beb6af7c0230c7cc7ba6c + version: 12b6f73e6084dad08a7c6e575284b177ecafbc71 subpackages: - assert - require diff --git a/glide.yaml b/glide.yaml index f92a8c9a4..be471e973 100644 --- a/glide.yaml +++ b/glide.yaml @@ -19,7 +19,7 @@ import: - package: github.com/tendermint/tmlibs version: sdk2 - package: github.com/tendermint/go-wire - version: sdk2 + version: develop - package: golang.org/x/crypto subpackages: - blowfish From 0391e499fb7881b164f70db24ce9f894cb6f5167 Mon Sep 17 00:00:00 2001 From: Adrian Brink Date: Fri, 2 Feb 2018 18:31:25 +0100 Subject: [PATCH 198/287] Clean up glide.yaml --- glide.lock | 16 ++++++---------- glide.yaml | 25 +++++++++---------------- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/glide.lock b/glide.lock index 1c6825b35..4ffe6a73c 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: fd4a3648af3dd1d49623ce248ba98804bf5a9c6a1bc28d61d93d5e878ccd04d4 -updated: 2018-02-02T14:07:48.239589+01:00 +hash: 1466255448cc0ab79ed6e575df6db01d53895f9e39c141dbb4494fe8cb9ba506 +updated: 2018-02-02T18:29:54.201489+01:00 imports: - name: github.com/btcsuite/btcd version: c7588cbf7690cd9f047a28efa2dcd8f2435a4e5e @@ -10,11 +10,11 @@ imports: subpackages: - base58 - name: github.com/davecgh/go-spew - version: 04cdfd42973bb9c8589fd6a731800cf222fde1a9 + version: 346938d642f2ec3594ed81d874461961cd0faa76 subpackages: - spew - name: github.com/go-kit/kit - version: e2b298466b32c7cd5579a9b9b07e968fc9d9452c + version: 4dc7be5d2d12881735283bcab7352178e190fc71 subpackages: - log - log/level @@ -24,7 +24,7 @@ imports: - name: github.com/go-stack/stack version: 817915b46b97fd7bb80e8ab6b69f01a53ac3eebf - name: github.com/gogo/protobuf - version: 342cbe0a04158f6dcb03ca0079991a51a4248c02 + version: 1adfc126b41513cc696b209667c8656ea7aac67c subpackages: - gogoproto - proto @@ -62,7 +62,7 @@ imports: - name: github.com/tendermint/go-wire version: e723d95ac2838b7ae9919ada25004859236c32ff - name: github.com/tendermint/tmlibs - version: 95b53c80e1771be6b8c7083771a417e2a888c765 + version: 2e765462234e7749806cd00fa326acc25d704448 subpackages: - common - db @@ -80,8 +80,6 @@ imports: - ripemd160 - salsa20/salsa testImports: -- name: github.com/mndrix/btcutil - version: d3a63a5752ecf3fbc06bd97365da752111c263df - name: github.com/pmezard/go-difflib version: d8ed2627bdf02c080bf22230dbb337003b7aba2d subpackages: @@ -91,7 +89,5 @@ testImports: subpackages: - assert - require -- name: github.com/tyler-smith/go-bip32 - version: 2c9cfd17756470a0b7c3e4b7954bae7d11035504 - name: github.com/tyler-smith/go-bip39 version: 8e7a99b3e716f36d3b080a9a70f9eb45abe4edcc diff --git a/glide.yaml b/glide.yaml index be471e973..09e7c0671 100644 --- a/glide.yaml +++ b/glide.yaml @@ -6,36 +6,29 @@ import: - package: github.com/btcsuite/btcutil subpackages: - base58 -- package: github.com/syndtr/goleveldb - subpackages: - - leveldb - - leveldb/errors - - leveldb/iterator - - leveldb/opt - - leveldb/util +- package: github.com/howeyc/crc16 +- package: github.com/pkg/errors + version: ^0.8.0 - package: github.com/tendermint/ed25519 subpackages: - extra25519 -- package: github.com/tendermint/tmlibs - version: sdk2 - package: github.com/tendermint/go-wire version: develop +- package: github.com/tendermint/tmlibs + version: 2e765462234e7749806cd00fa326acc25d704448 + subpackages: + - common + - db - package: golang.org/x/crypto subpackages: - blowfish - nacl/secretbox - openpgp/armor - ripemd160 -- package: github.com/pkg/errors -- package: github.com/howeyc/crc16 -# Needs refactoring, shouldn't be implementing PrivKey -#- package: github.com/ethanfrey/ledger testImport: -- package: github.com/mndrix/btcutil - package: github.com/stretchr/testify - version: ^1.1.4 + version: ^1.2.1 subpackages: - assert - require -- package: github.com/tyler-smith/go-bip32 - package: github.com/tyler-smith/go-bip39 From 45b71f7d11214c35ae63dfb81f42c0da8db9e69e Mon Sep 17 00:00:00 2001 From: Adrian Brink Date: Fri, 2 Feb 2018 18:51:41 +0100 Subject: [PATCH 199/287] Bump tmlibs commit. Needs to be changed to develop as soon as tmlibs PR is merged --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index 09e7c0671..3bf7ad8b4 100644 --- a/glide.yaml +++ b/glide.yaml @@ -15,7 +15,7 @@ import: - package: github.com/tendermint/go-wire version: develop - package: github.com/tendermint/tmlibs - version: 2e765462234e7749806cd00fa326acc25d704448 + version: cbc63518e589d6b0069f9750127fa83dd6ea5ee3 subpackages: - common - db From 9e897ab8b03501fd40d9286112d9b6705131ce40 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 2 Feb 2018 23:34:07 -0500 Subject: [PATCH 200/287] update glide --- glide.lock | 12 ++++++------ glide.yaml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/glide.lock b/glide.lock index 4ffe6a73c..6e712c790 100644 --- a/glide.lock +++ b/glide.lock @@ -1,8 +1,8 @@ -hash: 1466255448cc0ab79ed6e575df6db01d53895f9e39c141dbb4494fe8cb9ba506 -updated: 2018-02-02T18:29:54.201489+01:00 +hash: 95b2c2a089ca7242bc52c3bfe5a0286ae68201197f7f5855dd6e8f2ee3974068 +updated: 2018-02-02T23:14:21.166130626-05:00 imports: - name: github.com/btcsuite/btcd - version: c7588cbf7690cd9f047a28efa2dcd8f2435a4e5e + version: 2e60448ffcc6bf78332d1fe590260095f554dd78 subpackages: - btcec - name: github.com/btcsuite/btcutil @@ -55,14 +55,14 @@ imports: - leveldb/table - leveldb/util - name: github.com/tendermint/ed25519 - version: 1f52c6f8b8a5c7908aff4497c186af344b428925 + version: d8387025d2b9d158cf4efb07e7ebf814bcce2057 subpackages: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: e723d95ac2838b7ae9919ada25004859236c32ff + version: 4c92f560ad0aa4105e19d0ed47cecb630353b57b - name: github.com/tendermint/tmlibs - version: 2e765462234e7749806cd00fa326acc25d704448 + version: 690d6c60701758ab757d11ef674906f64e6b618d subpackages: - common - db diff --git a/glide.yaml b/glide.yaml index 3bf7ad8b4..d99809211 100644 --- a/glide.yaml +++ b/glide.yaml @@ -15,7 +15,7 @@ import: - package: github.com/tendermint/go-wire version: develop - package: github.com/tendermint/tmlibs - version: cbc63518e589d6b0069f9750127fa83dd6ea5ee3 + version: develop subpackages: - common - db From 5a94049dbc076d447df4a9364e0aaf8e7ca2248a Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 2 Feb 2018 23:42:22 -0500 Subject: [PATCH 201/287] update glide again --- glide.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/glide.lock b/glide.lock index 6e712c790..02ad7f77b 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ hash: 95b2c2a089ca7242bc52c3bfe5a0286ae68201197f7f5855dd6e8f2ee3974068 -updated: 2018-02-02T23:14:21.166130626-05:00 +updated: 2018-02-02T23:41:28.391448359-05:00 imports: - name: github.com/btcsuite/btcd version: 2e60448ffcc6bf78332d1fe590260095f554dd78 @@ -60,7 +60,7 @@ imports: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: 4c92f560ad0aa4105e19d0ed47cecb630353b57b + version: dec83f641903b22f039da3974607859715d0377e - name: github.com/tendermint/tmlibs version: 690d6c60701758ab757d11ef674906f64e6b618d subpackages: From 4fc3055dbd17aa1203d0abc64b9293f378da22ec Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 2 Feb 2018 23:50:24 -0500 Subject: [PATCH 202/287] update glide again --- glide.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/glide.lock b/glide.lock index 02ad7f77b..6db38099a 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ hash: 95b2c2a089ca7242bc52c3bfe5a0286ae68201197f7f5855dd6e8f2ee3974068 -updated: 2018-02-02T23:41:28.391448359-05:00 +updated: 2018-02-02T23:50:03.327504896-05:00 imports: - name: github.com/btcsuite/btcd version: 2e60448ffcc6bf78332d1fe590260095f554dd78 @@ -62,7 +62,7 @@ imports: - name: github.com/tendermint/go-wire version: dec83f641903b22f039da3974607859715d0377e - name: github.com/tendermint/tmlibs - version: 690d6c60701758ab757d11ef674906f64e6b618d + version: 1d7fc78ea171587e9e63da566d3da1b127bfd14c subpackages: - common - db From b6d029050ba0d137d6c69f438d9c00303c584b97 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Sun, 25 Feb 2018 08:48:53 -0800 Subject: [PATCH 203/287] Switch to dep from glide for dependency resolution --- Gopkg.lock | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Gopkg.toml | 62 ++++++++++++++++++++ Makefile | 9 ++- 3 files changed, 234 insertions(+), 5 deletions(-) create mode 100644 Gopkg.lock create mode 100644 Gopkg.toml diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 000000000..6dd1154b1 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,168 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/btcsuite/btcd" + packages = ["btcec"] + revision = "2e60448ffcc6bf78332d1fe590260095f554dd78" + +[[projects]] + branch = "master" + name = "github.com/btcsuite/btcutil" + packages = ["base58"] + revision = "501929d3d046174c3d39f0ea54ece471aa17238c" + +[[projects]] + name = "github.com/davecgh/go-spew" + packages = ["spew"] + revision = "346938d642f2ec3594ed81d874461961cd0faa76" + version = "v1.1.0" + +[[projects]] + name = "github.com/go-kit/kit" + packages = [ + "log", + "log/level", + "log/term" + ] + revision = "4dc7be5d2d12881735283bcab7352178e190fc71" + version = "v0.6.0" + +[[projects]] + name = "github.com/go-logfmt/logfmt" + packages = ["."] + revision = "390ab7935ee28ec6b286364bba9b4dd6410cb3d5" + version = "v0.3.0" + +[[projects]] + name = "github.com/go-stack/stack" + packages = ["."] + revision = "817915b46b97fd7bb80e8ab6b69f01a53ac3eebf" + version = "v1.6.0" + +[[projects]] + name = "github.com/gogo/protobuf" + packages = [ + "gogoproto", + "proto", + "protoc-gen-gogo/descriptor" + ] + revision = "1adfc126b41513cc696b209667c8656ea7aac67c" + version = "v1.0.0" + +[[projects]] + branch = "master" + name = "github.com/golang/snappy" + packages = ["."] + revision = "553a641470496b2327abcac10b36396bd98e45c9" + +[[projects]] + branch = "master" + name = "github.com/howeyc/crc16" + packages = ["."] + revision = "2b2a61e366a66d3efb279e46176e7291001e0354" + +[[projects]] + branch = "master" + name = "github.com/jmhodges/levigo" + packages = ["."] + revision = "c42d9e0ca023e2198120196f842701bb4c55d7b9" + +[[projects]] + branch = "master" + name = "github.com/kr/logfmt" + packages = ["."] + revision = "b84e30acd515aadc4b783ad4ff83aff3299bdfe0" + +[[projects]] + name = "github.com/pkg/errors" + packages = ["."] + revision = "645ef00459ed84a119197bfb8d8205042c6df63d" + version = "v0.8.0" + +[[projects]] + name = "github.com/pmezard/go-difflib" + packages = ["difflib"] + revision = "792786c7400a136282c1664665ae0a8db921c6c2" + version = "v1.0.0" + +[[projects]] + name = "github.com/stretchr/testify" + packages = [ + "assert", + "require" + ] + revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" + version = "v1.2.1" + +[[projects]] + name = "github.com/syndtr/goleveldb" + packages = [ + "leveldb", + "leveldb/cache", + "leveldb/comparer", + "leveldb/errors", + "leveldb/filter", + "leveldb/iterator", + "leveldb/journal", + "leveldb/memdb", + "leveldb/opt", + "leveldb/storage", + "leveldb/table", + "leveldb/util" + ] + revision = "b89cc31ef7977104127d34c1bd31ebd1a9db2199" + +[[projects]] + branch = "master" + name = "github.com/tendermint/ed25519" + packages = [ + ".", + "edwards25519", + "extra25519" + ] + revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057" + +[[projects]] + branch = "develop" + name = "github.com/tendermint/go-wire" + packages = ["."] + revision = "dec83f641903b22f039da3974607859715d0377e" + +[[projects]] + branch = "develop" + name = "github.com/tendermint/tmlibs" + packages = [ + "common", + "db", + "log" + ] + revision = "1d7fc78ea171587e9e63da566d3da1b127bfd14c" + +[[projects]] + branch = "master" + name = "github.com/tyler-smith/go-bip39" + packages = ["."] + revision = "8e7a99b3e716f36d3b080a9a70f9eb45abe4edcc" + +[[projects]] + name = "golang.org/x/crypto" + packages = [ + "bcrypt", + "blowfish", + "nacl/secretbox", + "openpgp/armor", + "openpgp/errors", + "pbkdf2", + "poly1305", + "ripemd160", + "salsa20/salsa" + ] + revision = "edd5e9b0879d13ee6970a50153d85b8fec9f7686" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "e0628df240b8ceeb91403f5218f5561d8580f15f3d5b0ea0da40710d1cba3707" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 000000000..058eb5838 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,62 @@ +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + + +[[constraint]] + branch = "master" + name = "github.com/btcsuite/btcutil" + +[[constraint]] + branch = "master" + name = "github.com/howeyc/crc16" + +[[constraint]] + name = "github.com/pkg/errors" + version = "0.8.0" + +[[constraint]] + name = "github.com/stretchr/testify" + version = "1.2.1" + +[[constraint]] + branch = "master" + name = "github.com/tendermint/ed25519" + +[[constraint]] + branch = "develop" + name = "github.com/tendermint/go-wire" + +[[constraint]] + branch = "develop" + name = "github.com/tendermint/tmlibs" + +[[constraint]] + branch = "master" + name = "github.com/tyler-smith/go-bip39" + +[prune] + go-tests = true + unused-packages = true diff --git a/Makefile b/Makefile index 19d797f1d..2b7e99c7f 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ GOTOOLS = \ - github.com/Masterminds/glide \ + github.com/golang/dep/cmd/dep \ github.com/jteeuwen/go-bindata/go-bindata # gopkg.in/alecthomas/gometalinter.v2 \ # @@ -43,16 +43,15 @@ update_tools: get_vendor_deps: @rm -rf vendor/ - @echo "--> Running glide install" - @glide install + @echo "--> Running dep ensure" + @dep ensure ######################################## ### Testing test: - go test -p 1 `glide novendor` - + go test -p 1 $(go list ./... | grep -v vendor) ######################################## ### Formatting, linting, and vetting From 3570c2eb9e8c6fef75a416d6f7eb08a075f846b0 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Sun, 25 Feb 2018 09:41:32 -0800 Subject: [PATCH 204/287] Fix test in makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2b7e99c7f..b8c95b7df 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ get_vendor_deps: ### Testing test: - go test -p 1 $(go list ./... | grep -v vendor) + go test -p 1 $(shell go list ./... | grep -v vendor) ######################################## ### Formatting, linting, and vetting From 6c6d01b51c56f8b155cf9712e79de8fb12a82803 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 2 Mar 2018 03:08:48 -0500 Subject: [PATCH 205/287] Keybase refactor Same as 788cc0a79256d4fe0448e17a90217acf3d61346b but without the new go-wire --- {nano => _nano}/keys.go | 0 {nano => _nano}/keys_test.go | 0 {nano => _nano}/sign.go | 0 {nano => _nano}/sign_test.go | 0 glide.lock | 32 +++-- glide.yaml | 4 +- keys/keybase.go | 221 +++++++++++++------------------- keys/keybase_test.go | 242 ++++++++++++++++++----------------- keys/keys.go | 32 +++++ keys/mintkey.go | 26 ++++ keys/types.go | 64 +++++---- 11 files changed, 325 insertions(+), 296 deletions(-) rename {nano => _nano}/keys.go (100%) rename {nano => _nano}/keys_test.go (100%) rename {nano => _nano}/sign.go (100%) rename {nano => _nano}/sign_test.go (100%) create mode 100644 keys/keys.go diff --git a/nano/keys.go b/_nano/keys.go similarity index 100% rename from nano/keys.go rename to _nano/keys.go diff --git a/nano/keys_test.go b/_nano/keys_test.go similarity index 100% rename from nano/keys_test.go rename to _nano/keys_test.go diff --git a/nano/sign.go b/_nano/sign.go similarity index 100% rename from nano/sign.go rename to _nano/sign.go diff --git a/nano/sign_test.go b/_nano/sign_test.go similarity index 100% rename from nano/sign_test.go rename to _nano/sign_test.go diff --git a/glide.lock b/glide.lock index 5032685c2..add082c5b 100644 --- a/glide.lock +++ b/glide.lock @@ -1,8 +1,8 @@ -hash: a21061afc44c148eb6bfeb91478b520661f3d086234383a0208d915b0cb058b8 -updated: 2017-12-27T14:29:49.534901894-08:00 +hash: 575a7b42282ded36e66490c44105140387d305b07e8e5a9e8e4b9eeb6f995e66 +updated: 2018-03-02T03:06:22.122862726-05:00 imports: - name: github.com/btcsuite/btcd - version: c7588cbf7690cd9f047a28efa2dcd8f2435a4e5e + version: 50de9da05b50eb15658bb350f6ea24368a111ab7 subpackages: - btcec - name: github.com/btcsuite/btcutil @@ -10,11 +10,9 @@ imports: subpackages: - base58 - name: github.com/ethanfrey/ledger - version: 5e432577be582bd18a3b4a9cd75dae7a317ade36 -- name: github.com/flynn/hid - version: ed06a31c6245d4552e8dbba7e32e5b010b875d65 + version: 23a7bb9d74bc83a862fcb4bddde24215b2295ad9 - name: github.com/go-kit/kit - version: e2b298466b32c7cd5579a9b9b07e968fc9d9452c + version: 4dc7be5d2d12881735283bcab7352178e190fc71 subpackages: - log - log/level @@ -22,9 +20,9 @@ imports: - name: github.com/go-logfmt/logfmt version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5 - name: github.com/go-stack/stack - version: 817915b46b97fd7bb80e8ab6b69f01a53ac3eebf + version: 259ab82a6cad3992b4e21ff5cac294ccb06474bc - name: github.com/gogo/protobuf - version: 342cbe0a04158f6dcb03ca0079991a51a4248c02 + version: 1adfc126b41513cc696b209667c8656ea7aac67c subpackages: - gogoproto - proto @@ -40,7 +38,7 @@ imports: - name: github.com/pkg/errors version: 645ef00459ed84a119197bfb8d8205042c6df63d - name: github.com/syndtr/goleveldb - version: b89cc31ef7977104127d34c1bd31ebd1a9db2199 + version: 34011bf325bce385408353a30b101fe5e923eb6e subpackages: - leveldb - leveldb/cache @@ -55,23 +53,23 @@ imports: - leveldb/table - leveldb/util - name: github.com/tendermint/ed25519 - version: 1f52c6f8b8a5c7908aff4497c186af344b428925 + version: d8387025d2b9d158cf4efb07e7ebf814bcce2057 subpackages: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: 27be46e25124ddf775e23317a83647ce62a93f6b + version: 67ee274c5f9da166622f3b6e6747003b563e3742 subpackages: - data - data/base58 - name: github.com/tendermint/tmlibs - version: 93c05aa8c06ef38f2b15fcdd1d91eafefda2732d + version: 1b9b5652a199ab0be2e781393fb275b66377309d subpackages: - common - db - log - name: golang.org/x/crypto - version: edd5e9b0879d13ee6970a50153d85b8fec9f7686 + version: 1875d0a70c90e57f11972aefd42276df65e895b9 subpackages: - bcrypt - blowfish @@ -84,17 +82,17 @@ imports: - salsa20/salsa testImports: - name: github.com/davecgh/go-spew - version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 + version: 346938d642f2ec3594ed81d874461961cd0faa76 subpackages: - spew - name: github.com/mndrix/btcutil version: d3a63a5752ecf3fbc06bd97365da752111c263df - name: github.com/pmezard/go-difflib - version: d8ed2627bdf02c080bf22230dbb337003b7aba2d + version: 792786c7400a136282c1664665ae0a8db921c6c2 subpackages: - difflib - name: github.com/stretchr/testify - version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0 + version: 12b6f73e6084dad08a7c6e575284b177ecafbc71 subpackages: - assert - require diff --git a/glide.yaml b/glide.yaml index f9df5c18d..c5ac4992b 100644 --- a/glide.yaml +++ b/glide.yaml @@ -17,9 +17,9 @@ import: subpackages: - extra25519 - package: github.com/tendermint/tmlibs - version: sdk2 + version: master - package: github.com/tendermint/go-wire - version: develop + version: bucky/new-go-wire-api subpackages: - data - data/base58 diff --git a/keys/keybase.go b/keys/keybase.go index c72518748..2c1d64a27 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -6,16 +6,10 @@ import ( "github.com/pkg/errors" crypto "github.com/tendermint/go-crypto" - dbm "github.com/tendermint/tmlibs/db" - "github.com/tendermint/go-crypto/keys/words" - "github.com/tendermint/go-crypto/nano" + dbm "github.com/tendermint/tmlibs/db" ) -// XXX Lets use go-crypto/bcrypt and ascii encoding directly in here without -// further wrappers around a store or DB. -// Copy functions from: https://github.com/tendermint/mintkey/blob/master/cmd/mintkey/common.go -// // dbKeybase combines encyption and storage implementation to provide // a full-featured key manager type dbKeybase struct { @@ -32,58 +26,59 @@ func New(db dbm.DB, codec words.Codec) dbKeybase { var _ Keybase = dbKeybase{} -// Create generates a new key and persists it storage, encrypted using the passphrase. -// It returns the generated seedphrase (mnemonic) and the key Info. -// It returns an error if it fails to generate a key for the given algo type, -// or if another key is already stored under the same name. -func (kb dbKeybase) Create(name, passphrase, algo string) (string, Info, error) { +// Create generates a new key and persists it to storage, encrypted +// using the passphrase. It returns the generated seedphrase +// (mnemonic) and the key Info. It returns an error if it fails to +// generate a key for the given algo type, or if another key is +// already stored under the same name. +func (kb dbKeybase) Create(name, passphrase string, algo CryptoAlgo) (Info, string, error) { // NOTE: secret is SHA256 hashed by secp256k1 and ed25519. // 16 byte secret corresponds to 12 BIP39 words. // XXX: Ledgers use 24 words now - should we ? secret := crypto.CRandBytes(16) - key, err := generate(algo, secret) + priv, err := generate(algo, secret) if err != nil { - return "", Info{}, err + return Info{}, "", err } // encrypt and persist the key - public := kb.writeKey(key, name, passphrase) + info := kb.writeKey(priv, name, passphrase) + + // we append the type byte to the serialized secret to help with + // recovery + // ie [secret] = [type] + [secret] + typ := cryptoAlgoToByte(algo) + secret = append([]byte{typ}, secret...) // return the mnemonic phrase words, err := kb.codec.BytesToWords(secret) - seedphrase := strings.Join(words, " ") - return seedphrase, public, err -} - -// Recover converts a seedphrase to a private key and persists it, encrypted with the given passphrase. -// Functions like Create, but seedphrase is input not output. -func (kb dbKeybase) Recover(name, passphrase, algo string, seedphrase string) (Info, error) { - - key, err := kb.SeedToPrivKey(algo, seedphrase) - if err != nil { - return Info{}, err - } - - // Valid seedphrase. Encrypt key and persist to disk. - public := kb.writeKey(key, name, passphrase) - return public, nil + seed := strings.Join(words, " ") + return info, seed, err } -// SeedToPrivKey returns the private key corresponding to a seedphrase -// without persisting the private key. -// TODO: enable the keybase to just hold these in memory so we can sign without persisting (?) -func (kb dbKeybase) SeedToPrivKey(algo, seedphrase string) (crypto.PrivKey, error) { +// Recover converts a seedphrase to a private key and persists it, +// encrypted with the given passphrase. Functions like Create, but +// seedphrase is input not output. +func (kb dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { words := strings.Split(strings.TrimSpace(seedphrase), " ") secret, err := kb.codec.WordsToBytes(words) if err != nil { - return crypto.PrivKey{}, err + return Info{}, err } - key, err := generate(algo, secret) + // secret is comprised of the actual secret with the type + // appended. + // ie [secret] = [type] + [secret] + typ, secret := secret[0], secret[1:] + algo := byteToCryptoAlgo(typ) + priv, err := generate(algo, secret) if err != nil { - return crypto.PrivKey{}, err + return Info{}, err } - return key, nil + + // encrypt and persist key. + public := kb.writeKey(priv, name, passphrase) + return public, err } // List returns the keys from storage in alphabetical order. @@ -92,75 +87,56 @@ func (kb dbKeybase) List() ([]Info, error) { iter := kb.db.Iterator(nil, nil) defer iter.Close() for ; iter.Valid(); iter.Next() { - key := iter.Key() - if isPub(key) { - info, err := readInfo(iter.Value()) - if err != nil { - return nil, err - } - res = append(res, info) + // key := iter.Key() + info, err := readInfo(iter.Value()) + if err != nil { + return nil, err } + res = append(res, info) } return res, nil } // Get returns the public information about one key. func (kb dbKeybase) Get(name string) (Info, error) { - bs := kb.db.Get(pubName(name)) + bs := kb.db.Get(infoKey(name)) return readInfo(bs) } // Sign signs the msg with the named key. // It returns an error if the key doesn't exist or the decryption fails. -// TODO: what if leddger fails ? -func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signature, pk crypto.PubKey, err error) { - var key crypto.PrivKey - armorStr := kb.db.Get(privName(name)) - key, err = unarmorDecryptPrivKey(string(armorStr), passphrase) +func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signature, pub crypto.PubKey, err error) { + info, err := kb.Get(name) if err != nil { return } - - sig = key.Sign(msg) - pk = key.PubKey() - return -} - -// Export decodes the private key with the current password, encrypts -// it with a secure one-time password and generates an armored private key -// that can be Imported by another dbKeybase. -// -// This is designed to copy from one device to another, or provide backups -// during version updates. -func (kb dbKeybase) Export(name, oldpass, transferpass string) ([]byte, error) { - armorStr := kb.db.Get(privName(name)) - key, err := unarmorDecryptPrivKey(string(armorStr), oldpass) + priv, err := unarmorDecryptPrivKey(info.PrivKeyArmor, passphrase) if err != nil { - return nil, err + return } + sig = priv.Sign(msg) + pub = priv.PubKey() + return +} - if transferpass == "" { - return key.Bytes(), nil +func (kb dbKeybase) Export(name string) (armor string, err error) { + bz := kb.db.Get(infoKey(name)) + if bz == nil { + return "", errors.New("No key to export with name " + name) } - armorBytes := encryptArmorPrivKey(key, transferpass) - return []byte(armorBytes), nil + return armorInfoBytes(bz), nil } -// Import accepts bytes generated by Export along with the same transferpass. -// If they are valid, it stores the password under the given name with the -// new passphrase. -func (kb dbKeybase) Import(name, newpass, transferpass string, data []byte) (err error) { - var key crypto.PrivKey - if transferpass == "" { - key, err = crypto.PrivKeyFromBytes(data) - } else { - key, err = unarmorDecryptPrivKey(string(data), transferpass) +func (kb dbKeybase) Import(name string, armor string) (err error) { + bz := kb.db.Get(infoKey(name)) + if len(bz) > 0 { + return errors.New("Cannot overwrite data for name " + name) } + infoBytes, err := unarmorInfoBytes(armor) if err != nil { - return err + return } - - kb.writeKey(key, name, newpass) + kb.db.Set(infoKey(name), infoBytes) return nil } @@ -168,80 +144,59 @@ func (kb dbKeybase) Import(name, newpass, transferpass string, data []byte) (err // proper passphrase before deleting it (for security). func (kb dbKeybase) Delete(name, passphrase string) error { // verify we have the proper password before deleting - bs := kb.db.Get(privName(name)) - _, err := unarmorDecryptPrivKey(string(bs), passphrase) + info, err := kb.Get(name) if err != nil { return err } - kb.db.DeleteSync(pubName(name)) - kb.db.DeleteSync(privName(name)) + _, err = unarmorDecryptPrivKey(info.PrivKeyArmor, passphrase) + if err != nil { + return err + } + kb.db.DeleteSync(infoKey(name)) return nil } -// Update changes the passphrase with which an already stored key is encrypted. +// Update changes the passphrase with which an already stored key is +// encrypted. // -// oldpass must be the current passphrase used for encryption, newpass will be -// the only valid passphrase from this time forward. +// oldpass must be the current passphrase used for encryption, +// newpass will be the only valid passphrase from this time forward. func (kb dbKeybase) Update(name, oldpass, newpass string) error { - bs := kb.db.Get(privName(name)) - key, err := unarmorDecryptPrivKey(string(bs), oldpass) + info, err := kb.Get(name) + if err != nil { + return err + } + key, err := unarmorDecryptPrivKey(info.PrivKeyArmor, oldpass) if err != nil { return err } - // Generate the public bytes and the encrypted privkey - public := info(name, key) - private := encryptArmorPrivKey(key, newpass) - - // We must delete first, as Putting over an existing name returns an error. - // Must be done atomically with the write or we could lose the key. - batch := kb.db.NewBatch() - batch.Delete(pubName(name)) - batch.Delete(privName(name)) - batch.Set(pubName(name), public.bytes()) - batch.Set(privName(name), []byte(private)) - batch.Write() - + kb.writeKey(key, name, newpass) return nil } - -//--------------------------------------------------------------------------------------- - func (kb dbKeybase) writeKey(priv crypto.PrivKey, name, passphrase string) Info { - // Generate the public bytes and the encrypted privkey - public := info(name, priv) - private := encryptArmorPrivKey(priv, passphrase) + // generate the encrypted privkey + privArmor := encryptArmorPrivKey(priv, passphrase) + // make Info + info := newInfo(name, priv.PubKey(), privArmor) - // Write them both - kb.db.SetSync(pubName(name), public.bytes()) - kb.db.SetSync(privName(name), []byte(private)) - - return public + // write them both + kb.db.SetSync(infoKey(name), info.bytes()) + return info } -// TODO: use a `type TypeKeyAlgo string` (?) -func generate(algo string, secret []byte) (crypto.PrivKey, error) { +func generate(algo CryptoAlgo, secret []byte) (crypto.PrivKey, error) { switch algo { - case crypto.NameEd25519: + case AlgoEd25519: return crypto.GenPrivKeyEd25519FromSecret(secret).Wrap(), nil - case crypto.NameSecp256k1: + case AlgoSecp256k1: return crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap(), nil - case nano.NameLedgerEd25519: - return nano.NewPrivKeyLedgerEd25519() default: err := errors.Errorf("Cannot generate keys for algorithm: %s", algo) return crypto.PrivKey{}, err } } -func pubName(name string) []byte { - return []byte(fmt.Sprintf("%s.pub", name)) -} - -func privName(name string) []byte { - return []byte(fmt.Sprintf("%s.priv", name)) -} - -func isPub(name []byte) bool { - return strings.HasSuffix(string(name), ".pub") +func infoKey(name string) []byte { + return []byte(fmt.Sprintf("%s.info", name)) } diff --git a/keys/keybase_test.go b/keys/keybase_test.go index 12e5205b0..84c81c81f 100644 --- a/keys/keybase_test.go +++ b/keys/keybase_test.go @@ -2,24 +2,20 @@ package keys_test import ( "fmt" - "os" "testing" - asrt "github.com/stretchr/testify/assert" - rqr "github.com/stretchr/testify/require" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" - cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" - crypto "github.com/tendermint/go-crypto" + "github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto/keys" "github.com/tendermint/go-crypto/keys/words" - "github.com/tendermint/go-crypto/nano" ) // TestKeyManagement makes sure we can manipulate these keys well func TestKeyManagement(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) // make the storage with reasonable defaults cstore := keys.New( @@ -27,84 +23,83 @@ func TestKeyManagement(t *testing.T) { words.MustLoadCodec("english"), ) - algo := crypto.NameEd25519 + algo := keys.AlgoEd25519 n1, n2, n3 := "personal", "business", "other" p1, p2 := "1234", "really-secure!@#$" // Check empty state l, err := cstore.List() - require.Nil(err) - assert.Empty(l) + require.Nil(t, err) + assert.Empty(t, l) // create some keys _, err = cstore.Get(n1) - assert.NotNil(err) - _, i, err := cstore.Create(n1, p1, algo) - require.Equal(n1, i.Name) - require.Nil(err) + assert.NotNil(t, err) + i, _, err := cstore.Create(n1, p1, algo) + require.Equal(t, n1, i.Name) + require.Nil(t, err) _, _, err = cstore.Create(n2, p2, algo) - require.Nil(err) + require.Nil(t, err) // we can get these keys i2, err := cstore.Get(n2) - assert.Nil(err) + assert.Nil(t, err) _, err = cstore.Get(n3) - assert.NotNil(err) + assert.NotNil(t, err) // list shows them in order keyS, err := cstore.List() - require.Nil(err) - require.Equal(2, len(keyS)) + require.Nil(t, err) + require.Equal(t, 2, len(keyS)) // note these are in alphabetical order - assert.Equal(n2, keyS[0].Name) - assert.Equal(n1, keyS[1].Name) - assert.Equal(i2.PubKey, keyS[0].PubKey) + assert.Equal(t, n2, keyS[0].Name) + assert.Equal(t, n1, keyS[1].Name) + assert.Equal(t, i2.PubKey, keyS[0].PubKey) // deleting a key removes it err = cstore.Delete("bad name", "foo") - require.NotNil(err) + require.NotNil(t, err) err = cstore.Delete(n1, p1) - require.Nil(err) + require.Nil(t, err) keyS, err = cstore.List() - require.Nil(err) - assert.Equal(1, len(keyS)) + require.Nil(t, err) + assert.Equal(t, 1, len(keyS)) _, err = cstore.Get(n1) - assert.NotNil(err) + assert.NotNil(t, err) // make sure that it only signs with the right password // tx := mock.NewSig([]byte("mytransactiondata")) // err = cstore.Sign(n2, p1, tx) - // assert.NotNil(err) + // assert.NotNil(t, err) // err = cstore.Sign(n2, p2, tx) - // assert.Nil(err, "%+v", err) + // assert.Nil(t, err, "%+v", err) // sigs, err := tx.Signers() - // assert.Nil(err, "%+v", err) - // if assert.Equal(1, len(sigs)) { - // assert.Equal(i2.PubKey, sigs[0]) + // assert.Nil(t, err, "%+v", err) + // if assert.Equal(t, 1, len(sigs)) { + // assert.Equal(t, i2.PubKey, sigs[0]) // } } // TestSignVerify does some detailed checks on how we sign and validate // signatures func TestSignVerify(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) // make the storage with reasonable defaults cstore := keys.New( dbm.NewMemDB(), words.MustLoadCodec("english"), ) - algo := crypto.NameSecp256k1 + algo := keys.AlgoSecp256k1 n1, n2 := "some dude", "a dudette" p1, p2 := "1234", "foobar" // create two users and get their info - _, i1, err := cstore.Create(n1, p1, algo) - require.Nil(err) + i1, _, err := cstore.Create(n1, p1, algo) + require.Nil(t, err) - _, i2, err := cstore.Create(n2, p2, algo) - require.Nil(err) + i2, _, err := cstore.Create(n2, p2, algo) + require.Nil(t, err) // let's try to sign some messages d1 := []byte("my first message") @@ -112,20 +107,20 @@ func TestSignVerify(t *testing.T) { // try signing both data with both keys... s11, pub1, err := cstore.Sign(n1, p1, d1) - require.Nil(err) - require.Equal(i1.PubKey, pub1) + require.Nil(t, err) + require.Equal(t, i1.PubKey, pub1) s12, pub1, err := cstore.Sign(n1, p1, d2) - require.Nil(err) - require.Equal(i1.PubKey, pub1) + require.Nil(t, err) + require.Equal(t, i1.PubKey, pub1) s21, pub2, err := cstore.Sign(n2, p2, d1) - require.Nil(err) - require.Equal(i2.PubKey, pub2) + require.Nil(t, err) + require.Equal(t, i2.PubKey, pub2) s22, pub2, err := cstore.Sign(n2, p2, d2) - require.Nil(err) - require.Equal(i2.PubKey, pub2) + require.Nil(t, err) + require.Equal(t, i2.PubKey, pub2) // let's try to validate and make sure it only works when everything is proper cases := []struct { @@ -148,17 +143,17 @@ func TestSignVerify(t *testing.T) { for i, tc := range cases { valid := tc.key.VerifyBytes(tc.data, tc.sig) - assert.Equal(tc.valid, valid, "%d", i) + assert.Equal(t, tc.valid, valid, "%d", i) } } +/* // TestSignWithLedger makes sure we have ledger compatibility with // the crypto store. // // This test will only succeed with a ledger attached to the computer // and the cosmos app open func TestSignWithLedger(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) if os.Getenv("WITH_LEDGER") == "" { t.Skip("Set WITH_LEDGER to run code on real ledger") } @@ -172,19 +167,19 @@ func TestSignWithLedger(t *testing.T) { p := "hard2hack" // create a nano user - _, c, err := cstore.Create(n, p, nano.NameLedgerEd25519) - require.Nil(err, "%+v", err) - assert.Equal(c.Name, n) + c, _, err := cstore.Create(n, p, nano.KeyLedgerEd25519) + require.Nil(t, err, "%+v", err) + assert.Equal(t, c.Key, n) _, ok := c.PubKey.Unwrap().(nano.PubKeyLedgerEd25519) - require.True(ok) + require.True(t, ok) // make sure we can get it back info, err := cstore.Get(n) - require.Nil(err, "%+v", err) - assert.Equal(info.Name, n) + require.Nil(t, err, "%+v", err) + assert.Equal(t, info.Key, n) key := info.PubKey - require.False(key.Empty()) - require.True(key.Equals(c.PubKey)) + require.False(t ,key.Empty()) + require.True(t, key.Equals(c.PubKey)) // let's try to sign some messages d1 := []byte("welcome to cosmos") @@ -192,56 +187,64 @@ func TestSignWithLedger(t *testing.T) { // try signing both data with the ledger... s1, pub, err := cstore.Sign(n, p, d1) - require.Nil(err) - require.Equal(info.PubKey, pub) + require.Nil(t, err) + require.Equal(t, info.PubKey, pub) s2, pub, err := cstore.Sign(n, p, d2) - require.Nil(err) - require.Equal(info.PubKey, pub) + require.Nil(t, err) + require.Equal(t, info.PubKey, pub) // now, let's check those signatures work - assert.True(key.VerifyBytes(d1, s1)) - assert.True(key.VerifyBytes(d2, s2)) + assert.True(t, key.VerifyBytes(d1, s1)) + assert.True(t, key.VerifyBytes(d2, s2)) // and mismatched signatures don't - assert.False(key.VerifyBytes(d1, s2)) + assert.False(t, key.VerifyBytes(d1, s2)) } +*/ -func assertPassword(assert *asrt.Assertions, cstore keys.Keybase, name, pass, badpass string) { +func assertPassword(t *testing.T, cstore keys.Keybase, name, pass, badpass string) { err := cstore.Update(name, badpass, pass) - assert.NotNil(err) + assert.NotNil(t, err) err = cstore.Update(name, pass, pass) - assert.Nil(err, "%+v", err) + assert.Nil(t, err, "%+v", err) } -// TestImportUnencrypted tests accepting raw priv keys bytes as input -func TestImportUnencrypted(t *testing.T) { - require := rqr.New(t) +// TestExportImport tests exporting and importing keys. +func TestExportImport(t *testing.T) { // make the storage with reasonable defaults + db := dbm.NewMemDB() cstore := keys.New( - dbm.NewMemDB(), + db, words.MustLoadCodec("english"), ) - key := crypto.GenPrivKeyEd25519FromSecret(cmn.RandBytes(16)).Wrap() + info, _, err := cstore.Create("john", "passphrase", keys.AlgoEd25519) + assert.Nil(t, err) + assert.Equal(t, info.Name, "john") + addr := info.PubKey.Address() + + john, err := cstore.Get("john") + assert.Nil(t, err) + assert.Equal(t, john.Name, "john") + assert.Equal(t, john.PubKey.Address(), addr) - addr := key.PubKey().Address() - name := "john" - pass := "top-secret" + armor, err := cstore.Export("john") + assert.Nil(t, err) - // import raw bytes - err := cstore.Import(name, pass, "", key.Bytes()) - require.Nil(err, "%+v", err) + err = cstore.Import("john2", armor) + assert.Nil(t, err) - // make sure the address matches - info, err := cstore.Get(name) - require.Nil(err, "%+v", err) - require.EqualValues(addr, info.Address()) + john2, err := cstore.Get("john2") + assert.Nil(t, err) + + assert.Equal(t, john.PubKey.Address(), addr) + assert.Equal(t, john.Name, "john") + assert.Equal(t, john, john2) } // TestAdvancedKeyManagement verifies update, import, export functionality func TestAdvancedKeyManagement(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) // make the storage with reasonable defaults cstore := keys.New( @@ -249,42 +252,49 @@ func TestAdvancedKeyManagement(t *testing.T) { words.MustLoadCodec("english"), ) - algo := crypto.NameSecp256k1 + algo := keys.AlgoSecp256k1 n1, n2 := "old-name", "new name" - p1, p2, p3, pt := "1234", "foobar", "ding booms!", "really-secure!@#$" + p1, p2 := "1234", "foobar" // make sure key works with initial password _, _, err := cstore.Create(n1, p1, algo) - require.Nil(err, "%+v", err) - assertPassword(assert, cstore, n1, p1, p2) + require.Nil(t, err, "%+v", err) + assertPassword(t, cstore, n1, p1, p2) // update password requires the existing password err = cstore.Update(n1, "jkkgkg", p2) - assert.NotNil(err) - assertPassword(assert, cstore, n1, p1, p2) + assert.NotNil(t, err) + assertPassword(t, cstore, n1, p1, p2) // then it changes the password when correct err = cstore.Update(n1, p1, p2) - assert.Nil(err) + assert.Nil(t, err) // p2 is now the proper one! - assertPassword(assert, cstore, n1, p2, p1) + assertPassword(t, cstore, n1, p2, p1) // exporting requires the proper name and passphrase - _, err = cstore.Export(n2, p2, pt) - assert.NotNil(err) - _, err = cstore.Export(n1, p1, pt) - assert.NotNil(err) - exported, err := cstore.Export(n1, p2, pt) - require.Nil(err, "%+v", err) - - // import fails on bad transfer pass - err = cstore.Import(n2, p3, p2, exported) - assert.NotNil(err) + _, err = cstore.Export(n1 + ".notreal") + assert.NotNil(t, err) + _, err = cstore.Export(" " + n1) + assert.NotNil(t, err) + _, err = cstore.Export(n1 + " ") + assert.NotNil(t, err) + _, err = cstore.Export("") + assert.NotNil(t, err) + exported, err := cstore.Export(n1) + require.Nil(t, err, "%+v", err) + + // import succeeds + err = cstore.Import(n2, exported) + assert.Nil(t, err) + + // second import fails + err = cstore.Import(n2, exported) + assert.NotNil(t, err) } // TestSeedPhrase verifies restoring from a seed phrase func TestSeedPhrase(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) // make the storage with reasonable defaults cstore := keys.New( @@ -292,28 +302,28 @@ func TestSeedPhrase(t *testing.T) { words.MustLoadCodec("english"), ) - algo := crypto.NameEd25519 + algo := keys.AlgoEd25519 n1, n2 := "lost-key", "found-again" p1, p2 := "1234", "foobar" // make sure key works with initial password - seed, info, err := cstore.Create(n1, p1, algo) - require.Nil(err, "%+v", err) - assert.Equal(n1, info.Name) - assert.NotEmpty(seed) + info, seed, err := cstore.Create(n1, p1, algo) + require.Nil(t, err, "%+v", err) + assert.Equal(t, n1, info.Name) + assert.NotEmpty(t, seed) // now, let us delete this key err = cstore.Delete(n1, p1) - require.Nil(err, "%+v", err) + require.Nil(t, err, "%+v", err) _, err = cstore.Get(n1) - require.NotNil(err) + require.NotNil(t, err) // let us re-create it from the seed-phrase - newInfo, err := cstore.Recover(n2, p2, algo, seed) - require.Nil(err, "%+v", err) - assert.Equal(n2, newInfo.Name) - assert.Equal(info.Address(), newInfo.Address()) - assert.Equal(info.PubKey, newInfo.PubKey) + newInfo, err := cstore.Recover(n2, p2, seed) + require.Nil(t, err, "%+v", err) + assert.Equal(t, n2, newInfo.Name) + assert.Equal(t, info.Address(), newInfo.Address()) + assert.Equal(t, info.PubKey, newInfo.PubKey) } func ExampleNew() { @@ -322,11 +332,11 @@ func ExampleNew() { dbm.NewMemDB(), words.MustLoadCodec("english"), ) - ed := crypto.NameEd25519 - sec := crypto.NameSecp256k1 + ed := keys.AlgoEd25519 + sec := keys.AlgoSecp256k1 // Add keys and see they return in alphabetical order - _, bob, err := cstore.Create("Bob", "friend", ed) + bob, _, err := cstore.Create("Bob", "friend", ed) if err != nil { // this should never happen fmt.Println(err) diff --git a/keys/keys.go b/keys/keys.go new file mode 100644 index 000000000..0ed89b3fd --- /dev/null +++ b/keys/keys.go @@ -0,0 +1,32 @@ +package keys + +import "fmt" + +type CryptoAlgo string + +const ( + AlgoEd25519 = CryptoAlgo("ed25519") + AlgoSecp256k1 = CryptoAlgo("secp256k1") +) + +func cryptoAlgoToByte(key CryptoAlgo) byte { + switch key { + case AlgoEd25519: + return 0x01 + case AlgoSecp256k1: + return 0x02 + default: + panic(fmt.Sprintf("Unexpected type key %v", key)) + } +} + +func byteToCryptoAlgo(b byte) CryptoAlgo { + switch b { + case 0x01: + return AlgoEd25519 + case 0x02: + return AlgoSecp256k1 + default: + panic(fmt.Sprintf("Unexpected type byte %X", b)) + } +} diff --git a/keys/mintkey.go b/keys/mintkey.go index d2724d658..73263b83a 100644 --- a/keys/mintkey.go +++ b/keys/mintkey.go @@ -12,8 +12,34 @@ import ( const ( blockTypePrivKey = "TENDERMINT PRIVATE KEY" + blockTypeKeyInfo = "TENDERMINT KEY INFO" ) +func armorInfoBytes(bz []byte) string { + header := map[string]string{ + "type": "Info", + "version": "0.0.0", + } + armorStr := crypto.EncodeArmor(blockTypeKeyInfo, header, bz) + return armorStr +} + +func unarmorInfoBytes(armorStr string) (bz []byte, err error) { + blockType, header, bz, err := crypto.DecodeArmor(armorStr) + if err != nil { + return + } + if blockType != blockTypeKeyInfo { + err = fmt.Errorf("Unrecognized armor type: %v", blockType) + return + } + if header["version"] != "0.0.0" { + err = fmt.Errorf("Unrecognized version: %v", header["version"]) + return + } + return +} + func encryptArmorPrivKey(privKey crypto.PrivKey, passphrase string) string { saltBytes, encBytes := encryptPrivKey(privKey, passphrase) header := map[string]string{ diff --git a/keys/types.go b/keys/types.go index fdb729e0a..cec9c36db 100644 --- a/keys/types.go +++ b/keys/types.go @@ -1,15 +1,40 @@ package keys import ( - wire "github.com/tendermint/go-wire" - crypto "github.com/tendermint/go-crypto" + wire "github.com/tendermint/go-wire" ) +// Keybase allows simple CRUD on a keystore, as an aid to signing +type Keybase interface { + // Sign some bytes + Sign(name, passphrase string, msg []byte) (crypto.Signature, crypto.PubKey, error) + // Create a new keypair + Create(name, passphrase string, algo CryptoAlgo) (info Info, seed string, err error) + // Recover takes a seedphrase and loads in the key + Recover(name, passphrase, seedphrase string) (info Info, erro error) + List() ([]Info, error) + Get(name string) (Info, error) + Update(name, oldpass, newpass string) error + Delete(name, passphrase string) error + + Import(name string, armor string) (err error) + Export(name string) (armor string, err error) +} + // Info is the public information about a key type Info struct { - Name string `json:"name"` - PubKey crypto.PubKey `json:"pubkey"` + Name string `json:"name"` + PubKey crypto.PubKey `json:"pubkey"` + PrivKeyArmor string `json:"privkey.armor"` +} + +func newInfo(name string, pub crypto.PubKey, privArmor string) Info { + return Info{ + Name: name, + PubKey: pub, + PrivKeyArmor: privArmor, + } } // Address is a helper function to calculate the address from the pubkey @@ -18,31 +43,14 @@ func (i Info) Address() []byte { } func (i Info) bytes() []byte { - return wire.BinaryBytes(i) -} - -func readInfo(bs []byte) (info Info, err error) { - err = wire.ReadBinaryBytes(bs, &info) - return -} - -func info(name string, privKey crypto.PrivKey) Info { - return Info{ - Name: name, - PubKey: privKey.PubKey(), + bz, err := wire.MarshalBinary(i) + if err != nil { + panic(err) } + return bz } -// Keybase allows simple CRUD on a keystore, as an aid to signing -type Keybase interface { - // Sign some bytes - Sign(name, passphrase string, msg []byte) (crypto.Signature, crypto.PubKey, error) - // Create a new keypair - Create(name, passphrase, algo string) (seedphrase string, _ Info, _ error) - // Recover takes a seedphrase and loads in the key - Recover(name, passphrase, algo, seedphrase string) (Info, error) - List() ([]Info, error) - Get(name string) (Info, error) - Update(name, oldpass, newpass string) error - Delete(name, passphrase string) error +func readInfo(bz []byte) (info Info, err error) { + err = wire.UnmarshalBinary(bz, &info) + return } From 3a929316572d6ad9e976b8d00e57c81282aae932 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 2 Mar 2018 10:40:36 -0500 Subject: [PATCH 206/287] changelog, version, glide --- CHANGELOG.md | 18 ++++++++++++++++++ glide.lock | 24 ++++++++++++------------ glide.yaml | 4 ++-- version.go | 2 +- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af0539300..f9fb33eb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## 0.5.0 (March 2, 2017) + +BREAKING CHANGES + +- nano: moved to `_nano` now while we're having build issues +- bcrypt: moved to `keys/bcrypt` +- hd: moved to `keys/hd`; `BTC` added to some function names; other function cleanup +- keys/cryptostore: moved to `keys`, renamed to `keybase`, and completely refactored +- keys: moved BIP39 related code to `keys/words` + +FEATURE + +- `Address` is a type alias for `cmn.HexBytes` + +BUG FIX + +- PrivKey comparisons done in constant time + ## 0.4.1 (October 27, 2017) This release removes support for bcrypt as it was merged too soon without an upgrade plan diff --git a/glide.lock b/glide.lock index add082c5b..48430920f 100644 --- a/glide.lock +++ b/glide.lock @@ -1,16 +1,16 @@ -hash: 575a7b42282ded36e66490c44105140387d305b07e8e5a9e8e4b9eeb6f995e66 -updated: 2018-03-02T03:06:22.122862726-05:00 +hash: 2b121bf7364ed02c60faff6d619a22acb0489d59843be669be3f8823b8658b75 +updated: 2018-03-02T10:39:45.076725737-05:00 imports: - name: github.com/btcsuite/btcd - version: 50de9da05b50eb15658bb350f6ea24368a111ab7 + version: 2be2f12b358dc57d70b8f501b00be450192efbc3 subpackages: - btcec - name: github.com/btcsuite/btcutil - version: 66871daeb12123ece012a9628d2798d01195c4b3 + version: 501929d3d046174c3d39f0ea54ece471aa17238c subpackages: - base58 - name: github.com/ethanfrey/ledger - version: 23a7bb9d74bc83a862fcb4bddde24215b2295ad9 + version: f7f2f056357db77db845a79aa1abdadc3ae66369 - name: github.com/go-kit/kit version: 4dc7be5d2d12881735283bcab7352178e190fc71 subpackages: @@ -30,15 +30,15 @@ imports: - name: github.com/golang/snappy version: 553a641470496b2327abcac10b36396bd98e45c9 - name: github.com/howeyc/crc16 - version: 96a97a1abb579c7ff1a8ffa77f2e72d1c314b57f + version: 2b2a61e366a66d3efb279e46176e7291001e0354 - name: github.com/jmhodges/levigo version: c42d9e0ca023e2198120196f842701bb4c55d7b9 - name: github.com/kr/logfmt version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0 - name: github.com/pkg/errors - version: 645ef00459ed84a119197bfb8d8205042c6df63d + version: 30136e27e2ac8d167177e8a583aa4c3fea5be833 - name: github.com/syndtr/goleveldb - version: 34011bf325bce385408353a30b101fe5e923eb6e + version: c7a14d4b00e222eab6111b4cd1af829c13f53ec2 subpackages: - leveldb - leveldb/cache @@ -58,7 +58,7 @@ imports: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: 67ee274c5f9da166622f3b6e6747003b563e3742 + version: fa721242b042ecd4c6ed1a934ee740db4f74e45c subpackages: - data - data/base58 @@ -69,7 +69,7 @@ imports: - db - log - name: golang.org/x/crypto - version: 1875d0a70c90e57f11972aefd42276df65e895b9 + version: 91a49db82a88618983a78a06c1cbd4e00ab749ab subpackages: - bcrypt - blowfish @@ -82,7 +82,7 @@ imports: - salsa20/salsa testImports: - name: github.com/davecgh/go-spew - version: 346938d642f2ec3594ed81d874461961cd0faa76 + version: 8991bc29aa16c548c550c7ff78260e27b9ab7c73 subpackages: - spew - name: github.com/mndrix/btcutil @@ -97,6 +97,6 @@ testImports: - assert - require - name: github.com/tyler-smith/go-bip32 - version: eb790af526c30f23a7c8b00a48e342f9d0bd6386 + version: 2c9cfd17756470a0b7c3e4b7954bae7d11035504 - name: github.com/tyler-smith/go-bip39 version: 8e7a99b3e716f36d3b080a9a70f9eb45abe4edcc diff --git a/glide.yaml b/glide.yaml index c5ac4992b..9b1f23a51 100644 --- a/glide.yaml +++ b/glide.yaml @@ -17,9 +17,9 @@ import: subpackages: - extra25519 - package: github.com/tendermint/tmlibs - version: master + version: v0.7.0 - package: github.com/tendermint/go-wire - version: bucky/new-go-wire-api + version: v0.7.3 subpackages: - data - data/base58 diff --git a/version.go b/version.go index c39dd627c..0281a5ea2 100644 --- a/version.go +++ b/version.go @@ -1,3 +1,3 @@ package crypto -const Version = "0.4.1" +const Version = "0.5.0" From 5e073562648998d31286e27c109b0e0c991e46b0 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 2 Mar 2018 11:43:58 -0500 Subject: [PATCH 207/287] use previously working new go-wire. not bleeding edge --- glide.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.lock b/glide.lock index 0a99eb1e3..b97d8bc07 100644 --- a/glide.lock +++ b/glide.lock @@ -60,7 +60,7 @@ imports: - edwards25519 - extra25519 - name: github.com/tendermint/go-wire - version: 3d2fb07b5c65de21d624919c4680b1cd1b2cfe90 + version: dec83f641903b22f039da3974607859715d0377e - name: github.com/tendermint/tmlibs version: 26f2ab65f82cfc6873c312e8030104c47c05f10e subpackages: From f499ce871362f456e127da24fd3dc244dc863f00 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Mon, 12 Mar 2018 12:18:30 +0400 Subject: [PATCH 208/287] update go-amino --- Gopkg.lock | 6 +++--- Gopkg.toml | 2 +- README.md | 2 +- _nano/keys.go | 8 ++++---- wire.go => amino.go | 22 +++++++++++----------- encode_test.go | 16 ++++++++-------- glide.lock | 2 +- glide.yaml | 2 +- keys/wire.go | 8 ++++---- signature_test.go | 19 ++++++++++--------- 10 files changed, 44 insertions(+), 43 deletions(-) rename wire.go => amino.go (56%) diff --git a/Gopkg.lock b/Gopkg.lock index 6dd1154b1..b945d9199 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -125,9 +125,9 @@ [[projects]] branch = "develop" - name = "github.com/tendermint/go-wire" + name = "github.com/tendermint/go-amino" packages = ["."] - revision = "dec83f641903b22f039da3974607859715d0377e" + revision = "3b9e2b978447707c255922bc3f87a53d55c400c9" [[projects]] branch = "develop" @@ -163,6 +163,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "e0628df240b8ceeb91403f5218f5561d8580f15f3d5b0ea0da40710d1cba3707" + inputs-digest = "375b661ad202b62c6847981416c03ce0518c33ac293f5f0863b69af04d2af91f" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 058eb5838..84a26764e 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -47,7 +47,7 @@ [[constraint]] branch = "develop" - name = "github.com/tendermint/go-wire" + name = "github.com/tendermint/go-amino" [[constraint]] branch = "develop" diff --git a/README.md b/README.md index da76fe823..3c33532fc 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,4 @@ go-crypto is the cryptographic package adapted for Tendermint's uses ## Importing it -`import "github.com/tendermint/go-crypto"` \ No newline at end of file +`import "github.com/tendermint/go-crypto"` diff --git a/_nano/keys.go b/_nano/keys.go index b50efd7ec..8cf1c3721 100644 --- a/_nano/keys.go +++ b/_nano/keys.go @@ -9,7 +9,7 @@ import ( ledger "github.com/ethanfrey/ledger" crypto "github.com/tendermint/go-crypto" - wire "github.com/tendermint/go-wire" + amino "github.com/tendermint/go-amino" ) //nolint @@ -58,7 +58,7 @@ func signLedger(device *ledger.Ledger, msg []byte) (pub crypto.PubKey, sig crypt // PrivKeyLedgerEd25519 implements PrivKey, calling the ledger nano // we cache the PubKey from the first call to use it later type PrivKeyLedgerEd25519 struct { - // PubKey should be private, but we want to encode it via go-wire + // PubKey should be private, but we want to encode it via go-amino // so we can view the address later, even without having the ledger // attached CachedPubKey crypto.PubKey @@ -97,7 +97,7 @@ func (pk *PrivKeyLedgerEd25519) AssertIsPrivKeyInner() {} // Bytes fulfils PrivKey Interface - but it stores the cached pubkey so we can verify // the same key when we reconnect to a ledger func (pk *PrivKeyLedgerEd25519) Bytes() []byte { - return wire.BinaryBytes(pk.Wrap()) + return amino.BinaryBytes(pk.Wrap()) } // Sign calls the ledger and stores the PubKey for future use @@ -250,7 +250,7 @@ func PubKeyLedgerEd25519FromBytes(key [32]byte) crypto.PubKey { // Bytes fulfils pk Interface - no data, just type info func (pk PubKeyLedgerEd25519) Bytes() []byte { - return wire.BinaryBytes(pk.Wrap()) + return amino.BinaryBytes(pk.Wrap()) } // VerifyBytes uses the normal Ed25519 algorithm but a sha512 hash beforehand diff --git a/wire.go b/amino.go similarity index 56% rename from wire.go rename to amino.go index 18035964f..f9d7b9580 100644 --- a/wire.go +++ b/amino.go @@ -1,36 +1,36 @@ package crypto import ( - "github.com/tendermint/go-wire" + amino "github.com/tendermint/go-amino" ) -var cdc = wire.NewCodec() +var cdc = amino.NewCodec() func init() { // NOTE: It's important that there be no conflicts here, // as that would change the canonical representations, // and therefore change the address. - // TODO: Add feature to go-wire to ensure that there + // TODO: Add feature to go-amino to ensure that there // are no conflicts. - RegisterWire(cdc) + RegisterAmino(cdc) } -func RegisterWire(cdc *wire.Codec) { +func RegisterAmino(cdc *amino.Codec) { cdc.RegisterInterface((*PubKey)(nil), nil) cdc.RegisterConcrete(PubKeyEd25519{}, - "com.tendermint.wire.PubKeyEd25519", nil) + "com.tendermint.amino.PubKeyEd25519", nil) cdc.RegisterConcrete(PubKeySecp256k1{}, - "com.tendermint.wire.PubKeySecp256k1", nil) + "com.tendermint.amino.PubKeySecp256k1", nil) cdc.RegisterInterface((*PrivKey)(nil), nil) cdc.RegisterConcrete(PrivKeyEd25519{}, - "com.tendermint.wire.PrivKeyEd25519", nil) + "com.tendermint.amino.PrivKeyEd25519", nil) cdc.RegisterConcrete(PrivKeySecp256k1{}, - "com.tendermint.wire.PrivKeySecp256k1", nil) + "com.tendermint.amino.PrivKeySecp256k1", nil) cdc.RegisterInterface((*Signature)(nil), nil) cdc.RegisterConcrete(SignatureEd25519{}, - "com.tendermint.wire.SignatureKeyEd25519", nil) + "com.tendermint.amino.SignatureKeyEd25519", nil) cdc.RegisterConcrete(SignatureSecp256k1{}, - "com.tendermint.wire.SignatureKeySecp256k1", nil) + "com.tendermint.amino.SignatureKeySecp256k1", nil) } diff --git a/encode_test.go b/encode_test.go index bcd9e60c2..bc3f1a736 100644 --- a/encode_test.go +++ b/encode_test.go @@ -1,7 +1,7 @@ package crypto /* -XXX Needs to be refactored to not use go-wire/data +XXX Needs to be refactored to not use go-amino/data import ( "fmt" @@ -10,15 +10,15 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - wire "github.com/tendermint/go-wire" - data "github.com/tendermint/go-wire/data" + amino "github.com/tendermint/go-amino" + data "github.com/tendermint/go-amino/data" ) type byter interface { Bytes() []byte } -// go to wire encoding and back +// go to amino encoding and back func checkWire(t *testing.T, in byter, reader interface{}, typ byte, size int) { // test to and from binary bin, err := data.ToWire(in) @@ -55,15 +55,15 @@ func checkJSON(t *testing.T, in interface{}, reader interface{}, typ string) { assert.True(t, strings.Contains(string(js), parts[1])) } -// make sure go-wire json can still figure this out... +// make sure go-amino json can still figure this out... func checkWireJSON(t *testing.T, in interface{}, reader interface{}, typ byte) { // test to and from binary var err error - js := wire.JSONBytes(in) + js := amino.JSONBytes(in) btyp := fmt.Sprintf("[%d,", typ) assert.True(t, strings.HasPrefix(string(js), btyp), string(js), btyp) - wire.ReadJSON(reader, js, &err) + amino.ReadJSON(reader, js, &err) require.Nil(t, err, "%+v", err) } @@ -144,7 +144,7 @@ type SigMessage struct { } func (s SigMessage) Bytes() []byte { - return wire.BinaryBytes(s) + return amino.BinaryBytes(s) } func TestEmbededWireEncodings(t *testing.T) { diff --git a/glide.lock b/glide.lock index b97d8bc07..ff6e97630 100644 --- a/glide.lock +++ b/glide.lock @@ -59,7 +59,7 @@ imports: subpackages: - edwards25519 - extra25519 -- name: github.com/tendermint/go-wire +- name: github.com/tendermint/go-amino version: dec83f641903b22f039da3974607859715d0377e - name: github.com/tendermint/tmlibs version: 26f2ab65f82cfc6873c312e8030104c47c05f10e diff --git a/glide.yaml b/glide.yaml index d99809211..8e8b55b50 100644 --- a/glide.yaml +++ b/glide.yaml @@ -12,7 +12,7 @@ import: - package: github.com/tendermint/ed25519 subpackages: - extra25519 -- package: github.com/tendermint/go-wire +- package: github.com/tendermint/go-amino version: develop - package: github.com/tendermint/tmlibs version: develop diff --git a/keys/wire.go b/keys/wire.go index 65d69ba5e..7deaad673 100644 --- a/keys/wire.go +++ b/keys/wire.go @@ -1,12 +1,12 @@ package keys import ( - "github.com/tendermint/go-crypto" - "github.com/tendermint/go-wire" + amino "github.com/tendermint/go-amino" + crypto "github.com/tendermint/go-crypto" ) -var cdc = wire.NewCodec() +var cdc = amino.NewCodec() func init() { - crypto.RegisterWire(cdc) + crypto.RegisterAmino(cdc) } diff --git a/signature_test.go b/signature_test.go index 7bc94e677..b698e5167 100644 --- a/signature_test.go +++ b/signature_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tendermint/ed25519" - "github.com/tendermint/go-wire" + amino "github.com/tendermint/go-amino" ) func TestSignAndValidateEd25519(t *testing.T) { @@ -49,17 +49,17 @@ func TestSignatureEncodings(t *testing.T) { cases := []struct { privKey PrivKey sigSize int - sigPrefix wire.PrefixBytes + sigPrefix amino.PrefixBytes }{ { privKey: GenPrivKeyEd25519(), sigSize: ed25519.SignatureSize, - sigPrefix: [4]byte{0xe4, 0x51, 0x7b, 0xa3}, + sigPrefix: [4]byte{0xc8, 0x5d, 0xf4, 0xba}, }, { privKey: GenPrivKeySecp256k1(), sigSize: 0, // unknown - sigPrefix: [4]byte{0x37, 0xb9, 0x21, 0x3e}, + sigPrefix: [4]byte{0xc6, 0xa0, 0xa, 0x42}, }, } @@ -70,17 +70,18 @@ func TestSignatureEncodings(t *testing.T) { msg := CRandBytes(128) sig := tc.privKey.Sign(msg) - // store as wire - bin, err := cdc.MarshalBinary(sig) + // store as amino + bin, err := cdc.MarshalBinaryBare(sig) require.Nil(t, err, "%+v", err) if tc.sigSize != 0 { - assert.Equal(t, tc.sigSize+4, len(bin)) + // Q: where is 1 byte coming from? + assert.Equal(t, tc.sigSize+amino.PrefixBytesLen+1, len(bin)) } - assert.Equal(t, tc.sigPrefix[:], bin[0:4]) + assert.Equal(t, tc.sigPrefix[:], bin[0:amino.PrefixBytesLen]) // and back sig2 := Signature(nil) - err = cdc.UnmarshalBinary(bin, &sig2) + err = cdc.UnmarshalBinaryBare(bin, &sig2) require.Nil(t, err, "%+v", err) assert.EqualValues(t, sig, sig2) assert.True(t, pubKey.VerifyBytes(msg, sig2)) From 47b8a8864b7e7b63b2d34902cee6e7b5a99466d2 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Mon, 12 Mar 2018 12:34:43 +0400 Subject: [PATCH 209/287] remove any mention of glide --- Makefile | 6 ++-- glide.lock | 93 ------------------------------------------------------ glide.yaml | 34 -------------------- 3 files changed, 3 insertions(+), 130 deletions(-) delete mode 100644 glide.lock delete mode 100644 glide.yaml diff --git a/Makefile b/Makefile index b8c95b7df..9ae475983 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ GOTOOLS = \ github.com/golang/dep/cmd/dep \ - github.com/jteeuwen/go-bindata/go-bindata + github.com/jteeuwen/go-bindata/go-bindata # gopkg.in/alecthomas/gometalinter.v2 \ # -GOTOOLS_CHECK = glide go-bindata #gometalinter.v2 +GOTOOLS_CHECK = dep go-bindata #gometalinter.v2 -all: check get_vendor_deps build test install +all: check get_vendor_deps build test install check: check_tools diff --git a/glide.lock b/glide.lock deleted file mode 100644 index ff6e97630..000000000 --- a/glide.lock +++ /dev/null @@ -1,93 +0,0 @@ -hash: 95b2c2a089ca7242bc52c3bfe5a0286ae68201197f7f5855dd6e8f2ee3974068 -updated: 2018-03-02T11:41:11.205350024-05:00 -imports: -- name: github.com/btcsuite/btcd - version: 2be2f12b358dc57d70b8f501b00be450192efbc3 - subpackages: - - btcec -- name: github.com/btcsuite/btcutil - version: 501929d3d046174c3d39f0ea54ece471aa17238c - subpackages: - - base58 -- name: github.com/davecgh/go-spew - version: 346938d642f2ec3594ed81d874461961cd0faa76 - subpackages: - - spew -- name: github.com/go-kit/kit - version: 4dc7be5d2d12881735283bcab7352178e190fc71 - subpackages: - - log - - log/level - - log/term -- name: github.com/go-logfmt/logfmt - version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5 -- name: github.com/go-stack/stack - version: 259ab82a6cad3992b4e21ff5cac294ccb06474bc -- name: github.com/gogo/protobuf - version: 1adfc126b41513cc696b209667c8656ea7aac67c - subpackages: - - gogoproto - - proto - - protoc-gen-gogo/descriptor -- name: github.com/golang/snappy - version: 553a641470496b2327abcac10b36396bd98e45c9 -- name: github.com/howeyc/crc16 - version: 2b2a61e366a66d3efb279e46176e7291001e0354 -- name: github.com/jmhodges/levigo - version: c42d9e0ca023e2198120196f842701bb4c55d7b9 -- name: github.com/kr/logfmt - version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0 -- name: github.com/pkg/errors - version: 645ef00459ed84a119197bfb8d8205042c6df63d -- name: github.com/syndtr/goleveldb - version: c7a14d4b00e222eab6111b4cd1af829c13f53ec2 - subpackages: - - leveldb - - leveldb/cache - - leveldb/comparer - - leveldb/errors - - leveldb/filter - - leveldb/iterator - - leveldb/journal - - leveldb/memdb - - leveldb/opt - - leveldb/storage - - leveldb/table - - leveldb/util -- name: github.com/tendermint/ed25519 - version: d8387025d2b9d158cf4efb07e7ebf814bcce2057 - subpackages: - - edwards25519 - - extra25519 -- name: github.com/tendermint/go-amino - version: dec83f641903b22f039da3974607859715d0377e -- name: github.com/tendermint/tmlibs - version: 26f2ab65f82cfc6873c312e8030104c47c05f10e - subpackages: - - common - - db - - log -- name: golang.org/x/crypto - version: 91a49db82a88618983a78a06c1cbd4e00ab749ab - subpackages: - - bcrypt - - blowfish - - nacl/secretbox - - openpgp/armor - - openpgp/errors - - pbkdf2 - - poly1305 - - ripemd160 - - salsa20/salsa -testImports: -- name: github.com/pmezard/go-difflib - version: 792786c7400a136282c1664665ae0a8db921c6c2 - subpackages: - - difflib -- name: github.com/stretchr/testify - version: 12b6f73e6084dad08a7c6e575284b177ecafbc71 - subpackages: - - assert - - require -- name: github.com/tyler-smith/go-bip39 - version: 8e7a99b3e716f36d3b080a9a70f9eb45abe4edcc diff --git a/glide.yaml b/glide.yaml deleted file mode 100644 index 8e8b55b50..000000000 --- a/glide.yaml +++ /dev/null @@ -1,34 +0,0 @@ -package: github.com/tendermint/go-crypto -import: -- package: github.com/btcsuite/btcd - subpackages: - - btcec -- package: github.com/btcsuite/btcutil - subpackages: - - base58 -- package: github.com/howeyc/crc16 -- package: github.com/pkg/errors - version: ^0.8.0 -- package: github.com/tendermint/ed25519 - subpackages: - - extra25519 -- package: github.com/tendermint/go-amino - version: develop -- package: github.com/tendermint/tmlibs - version: develop - subpackages: - - common - - db -- package: golang.org/x/crypto - subpackages: - - blowfish - - nacl/secretbox - - openpgp/armor - - ripemd160 -testImport: -- package: github.com/stretchr/testify - version: ^1.2.1 - subpackages: - - assert - - require -- package: github.com/tyler-smith/go-bip39 From 73407e7cff462bf4ffcc44d55a9dd4570dd57fed Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Mon, 12 Mar 2018 12:37:19 +0400 Subject: [PATCH 210/287] add CODEOWNERS file --- .github/CODEOWNERS | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..3876c1ac5 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# CODEOWNERS: https://help.github.com/articles/about-codeowners/ + +* @ebuchman @jaekwon From a3800da0a15c8272cbd3c155e024bff28fe9692c Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Fri, 16 Mar 2018 07:01:02 -0700 Subject: [PATCH 211/287] Update Gopkg.lock to use go-amino --- Gopkg.lock | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index b945d9199..6369f55bd 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -2,9 +2,10 @@ [[projects]] + branch = "master" name = "github.com/btcsuite/btcd" packages = ["btcec"] - revision = "2e60448ffcc6bf78332d1fe590260095f554dd78" + revision = "2be2f12b358dc57d70b8f501b00be450192efbc3" [[projects]] branch = "master" @@ -37,8 +38,8 @@ [[projects]] name = "github.com/go-stack/stack" packages = ["."] - revision = "817915b46b97fd7bb80e8ab6b69f01a53ac3eebf" - version = "v1.6.0" + revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc" + version = "v1.7.0" [[projects]] name = "github.com/gogo/protobuf" @@ -96,6 +97,7 @@ version = "v1.2.1" [[projects]] + branch = "master" name = "github.com/syndtr/goleveldb" packages = [ "leveldb", @@ -111,7 +113,7 @@ "leveldb/table", "leveldb/util" ] - revision = "b89cc31ef7977104127d34c1bd31ebd1a9db2199" + revision = "169b1b37be738edb2813dab48c97a549bcf99bb5" [[projects]] branch = "master" @@ -137,7 +139,7 @@ "db", "log" ] - revision = "1d7fc78ea171587e9e63da566d3da1b127bfd14c" + revision = "d289c9286e816a37336289a75752752a751bc918" [[projects]] branch = "master" @@ -146,6 +148,7 @@ revision = "8e7a99b3e716f36d3b080a9a70f9eb45abe4edcc" [[projects]] + branch = "master" name = "golang.org/x/crypto" packages = [ "bcrypt", @@ -158,7 +161,7 @@ "ripemd160", "salsa20/salsa" ] - revision = "edd5e9b0879d13ee6970a50153d85b8fec9f7686" + revision = "b4956d363a8b14623cc81db401707679605930a3" [solve-meta] analyzer-name = "dep" From f01046263907258b8d7fc4f91ee0b6138d2c1baf Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sun, 18 Mar 2018 23:45:46 +0100 Subject: [PATCH 212/287] Make concrete registered name be tendermint/* --- amino.go | 12 ++++++------ signature_test.go | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/amino.go b/amino.go index f9d7b9580..89636895a 100644 --- a/amino.go +++ b/amino.go @@ -18,19 +18,19 @@ func init() { func RegisterAmino(cdc *amino.Codec) { cdc.RegisterInterface((*PubKey)(nil), nil) cdc.RegisterConcrete(PubKeyEd25519{}, - "com.tendermint.amino.PubKeyEd25519", nil) + "tendermint/PubKeyEd25519", nil) cdc.RegisterConcrete(PubKeySecp256k1{}, - "com.tendermint.amino.PubKeySecp256k1", nil) + "tendermint/PubKeySecp256k1", nil) cdc.RegisterInterface((*PrivKey)(nil), nil) cdc.RegisterConcrete(PrivKeyEd25519{}, - "com.tendermint.amino.PrivKeyEd25519", nil) + "tendermint/PrivKeyEd25519", nil) cdc.RegisterConcrete(PrivKeySecp256k1{}, - "com.tendermint.amino.PrivKeySecp256k1", nil) + "tendermint/PrivKeySecp256k1", nil) cdc.RegisterInterface((*Signature)(nil), nil) cdc.RegisterConcrete(SignatureEd25519{}, - "com.tendermint.amino.SignatureKeyEd25519", nil) + "tendermint/SignatureKeyEd25519", nil) cdc.RegisterConcrete(SignatureSecp256k1{}, - "com.tendermint.amino.SignatureKeySecp256k1", nil) + "tendermint/SignatureKeySecp256k1", nil) } diff --git a/signature_test.go b/signature_test.go index b698e5167..0ba44ded5 100644 --- a/signature_test.go +++ b/signature_test.go @@ -54,12 +54,12 @@ func TestSignatureEncodings(t *testing.T) { { privKey: GenPrivKeyEd25519(), sigSize: ed25519.SignatureSize, - sigPrefix: [4]byte{0xc8, 0x5d, 0xf4, 0xba}, + sigPrefix: [4]byte{0x3d, 0xa1, 0xdb, 0x2a}, }, { privKey: GenPrivKeySecp256k1(), sigSize: 0, // unknown - sigPrefix: [4]byte{0xc6, 0xa0, 0xa, 0x42}, + sigPrefix: [4]byte{0x16, 0xe1, 0xfe, 0xea}, }, } From a04f2ae5c6ba037014531241ed973116290b029e Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sun, 25 Mar 2018 07:14:11 +0200 Subject: [PATCH 213/287] tmlibs 0.8.0-dev; canonical concrete names --- CHANGELOG.md | 6 ++++++ Gopkg.lock | 10 +++++----- Gopkg.toml | 12 ++++++------ version.go | 2 +- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9fb33eb8..1f58e18ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.6.0 (March 2, 2017) + +BREAKING CHANGES + +- Update Amino names from "com.tendermint/..." to "tendermint/" + ## 0.5.0 (March 2, 2017) BREAKING CHANGES diff --git a/Gopkg.lock b/Gopkg.lock index 6369f55bd..03473487d 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -126,20 +126,20 @@ revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057" [[projects]] - branch = "develop" name = "github.com/tendermint/go-amino" packages = ["."] - revision = "3b9e2b978447707c255922bc3f87a53d55c400c9" + revision = "8b10adccaa7e4c2edc29c7b762169c34f4a36b32" + version = "0.9.1" [[projects]] - branch = "develop" name = "github.com/tendermint/tmlibs" packages = [ "common", "db", "log" ] - revision = "d289c9286e816a37336289a75752752a751bc918" + revision = "e9cf47606cfcbdc28a7c16671b4a70b459e9d4cc" + version = "v0.8.0-dev" [[projects]] branch = "master" @@ -166,6 +166,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "375b661ad202b62c6847981416c03ce0518c33ac293f5f0863b69af04d2af91f" + inputs-digest = "ff08a2810853f018b3ce056747de63fe4c1782268796f457d3fa28305de2bd1d" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 84a26764e..908e48f5f 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -26,12 +26,12 @@ [[constraint]] - branch = "master" name = "github.com/btcsuite/btcutil" + branch = "master" [[constraint]] - branch = "master" name = "github.com/howeyc/crc16" + branch = "master" [[constraint]] name = "github.com/pkg/errors" @@ -42,20 +42,20 @@ version = "1.2.1" [[constraint]] - branch = "master" name = "github.com/tendermint/ed25519" + branch = "master" [[constraint]] - branch = "develop" name = "github.com/tendermint/go-amino" + version = "0.9.1" [[constraint]] - branch = "develop" name = "github.com/tendermint/tmlibs" + version = "0.8.0-dev" [[constraint]] - branch = "master" name = "github.com/tyler-smith/go-bip39" + branch = "master" [prune] go-tests = true diff --git a/version.go b/version.go index 0281a5ea2..f641e03a3 100644 --- a/version.go +++ b/version.go @@ -1,3 +1,3 @@ package crypto -const Version = "0.5.0" +const Version = "0.6.0" From 0d4436dea7592f48bdbaefc4af90756cf58ddacd Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Mon, 26 Mar 2018 10:41:04 +0200 Subject: [PATCH 214/287] Use MarshalBinaryBare; Fix encode_test; Bump version --- Gopkg.lock | 6 +- Gopkg.toml | 2 +- encode_test.go | 172 ++++++++++++------------------------------------- keys/types.go | 4 +- priv_key.go | 8 +-- pub_key.go | 6 +- signature.go | 6 +- version.go | 2 +- 8 files changed, 58 insertions(+), 148 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 03473487d..bfe089b72 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -128,8 +128,8 @@ [[projects]] name = "github.com/tendermint/go-amino" packages = ["."] - revision = "8b10adccaa7e4c2edc29c7b762169c34f4a36b32" - version = "0.9.1" + revision = "f55c3351f30e5987500020631f00e87a035ed415" + version = "0.9.3" [[projects]] name = "github.com/tendermint/tmlibs" @@ -166,6 +166,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "ff08a2810853f018b3ce056747de63fe4c1782268796f457d3fa28305de2bd1d" + inputs-digest = "9748e96106582387ac49df1db8e4456bd51c8e9362c86992d6ce7011c1783f55" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 908e48f5f..a7f84bb59 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -47,7 +47,7 @@ [[constraint]] name = "github.com/tendermint/go-amino" - version = "0.9.1" + version = "0.9.3" [[constraint]] name = "github.com/tendermint/tmlibs" diff --git a/encode_test.go b/encode_test.go index bc3f1a736..d9332238e 100644 --- a/encode_test.go +++ b/encode_test.go @@ -1,185 +1,95 @@ package crypto -/* -XXX Needs to be refactored to not use go-amino/data - import ( - "fmt" - "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - amino "github.com/tendermint/go-amino" - data "github.com/tendermint/go-amino/data" ) type byter interface { Bytes() []byte } -// go to amino encoding and back -func checkWire(t *testing.T, in byter, reader interface{}, typ byte, size int) { - // test to and from binary - bin, err := data.ToWire(in) +func checkAminoBinary(t *testing.T, src byter, dst interface{}, size int) { + // Marshal to binary bytes. + bz, err := cdc.MarshalBinaryBare(src) require.Nil(t, err, "%+v", err) - assert.Equal(t, typ, bin[0]) - // make sure this is compatible with current (Bytes()) encoding - assert.Equal(t, in.Bytes(), bin) - // make sure we have the expected length - assert.Equal(t, size, len(bin)) - - err = data.FromWire(bin, reader) + // Make sure this is compatible with current (Bytes()) encoding. + assert.Equal(t, src.Bytes(), bz, "Amino binary vs Bytes() mismatch") + // Make sure we have the expected length. + assert.Equal(t, size, len(bz), "Amino binary size mismatch") + // Unmarshal. + err = cdc.UnmarshalBinaryBare(bz, dst) require.Nil(t, err, "%+v", err) } -// go to json encoding and back -func checkJSON(t *testing.T, in interface{}, reader interface{}, typ string) { - // test to and from binary - js, err := data.ToJSON(in) - require.Nil(t, err, "%+v", err) - styp := `"` + typ + `"` - assert.True(t, strings.Contains(string(js), styp)) - - err = data.FromJSON(js, reader) +func checkAminoJSON(t *testing.T, src interface{}, dst interface{}, isNil bool) { + // Marshal to JSON bytes. + js, err := cdc.MarshalJSON(src) require.Nil(t, err, "%+v", err) - - // also check text format - text, err := data.ToText(in) - require.Nil(t, err, "%+v", err) - parts := strings.Split(text, ":") - require.Equal(t, 2, len(parts)) - // make sure the first part is the typ string - assert.Equal(t, typ, parts[0]) - // and the data is also present in the json - assert.True(t, strings.Contains(string(js), parts[1])) -} - -// make sure go-amino json can still figure this out... -func checkWireJSON(t *testing.T, in interface{}, reader interface{}, typ byte) { - // test to and from binary - var err error - js := amino.JSONBytes(in) - btyp := fmt.Sprintf("[%d,", typ) - assert.True(t, strings.HasPrefix(string(js), btyp), string(js), btyp) - - amino.ReadJSON(reader, js, &err) + if isNil { + assert.Equal(t, string(js), `null`) + } else { + assert.Contains(t, string(js), `"type":`) + assert.Contains(t, string(js), `"value":`) + } + // Unmarshal. + err = cdc.UnmarshalJSON(js, dst) require.Nil(t, err, "%+v", err) } func TestKeyEncodings(t *testing.T) { cases := []struct { privKey PrivKey - keyType byte - keyName string // 1 (type byte) + size of byte array privSize, pubSize int }{ { - privKey: GenPrivKeyEd25519().Wrap(), - keyType: TypeEd25519, - keyName: NameEd25519, - privSize: 65, - pubSize: 33, + privKey: GenPrivKeyEd25519(), + privSize: 69, + pubSize: 37, }, { - privKey: GenPrivKeySecp256k1().Wrap(), - keyType: TypeSecp256k1, - keyName: NameSecp256k1, - privSize: 33, - pubSize: 34, + privKey: GenPrivKeySecp256k1(), + privSize: 37, + pubSize: 38, }, } for _, tc := range cases { - // check (de/en)codings of private key - var priv2, priv3, priv4 PrivKey - checkWire(t, tc.privKey, &priv2, tc.keyType, tc.privSize) + // Check (de/en)codings of PrivKeys. + var priv2, priv3 PrivKey + checkAminoBinary(t, tc.privKey, &priv2, tc.privSize) assert.EqualValues(t, tc.privKey, priv2) - checkJSON(t, tc.privKey, &priv3, tc.keyName) + checkAminoJSON(t, tc.privKey, &priv3, false) // TODO also check Prefix bytes. assert.EqualValues(t, tc.privKey, priv3) - checkWireJSON(t, tc.privKey, &priv4, tc.keyType) - assert.EqualValues(t, tc.privKey, priv4) - // check (de/en)codings of public key + // Check (de/en)codings of PubKeys. pubKey := tc.privKey.PubKey() - var pub2, pub3, pub4 PubKey - checkWire(t, pubKey, &pub2, tc.keyType, tc.pubSize) + var pub2, pub3 PubKey + checkAminoBinary(t, pubKey, &pub2, tc.pubSize) assert.EqualValues(t, pubKey, pub2) - checkJSON(t, pubKey, &pub3, tc.keyName) + checkAminoJSON(t, pubKey, &pub3, false) // TODO also check Prefix bytes. assert.EqualValues(t, pubKey, pub3) - checkWireJSON(t, pubKey, &pub4, tc.keyType) - assert.EqualValues(t, pubKey, pub4) } } -func toFromJSON(t *testing.T, in interface{}, recvr interface{}) { - js, err := data.ToJSON(in) - require.Nil(t, err, "%+v", err) - err = data.FromJSON(js, recvr) - require.Nil(t, err, "%+v", err) -} - func TestNilEncodings(t *testing.T) { - // make sure sigs are okay with nil + + // Check nil Signature. var a, b Signature - toFromJSON(t, a, &b) + checkAminoJSON(t, &a, &b, true) assert.EqualValues(t, a, b) - // make sure sigs are okay with nil + // Check nil PubKey. var c, d PubKey - toFromJSON(t, c, &d) + checkAminoJSON(t, &c, &d, true) assert.EqualValues(t, c, d) - // make sure sigs are okay with nil + // Check nil PrivKey. var e, f PrivKey - toFromJSON(t, e, &f) + checkAminoJSON(t, &e, &f, true) assert.EqualValues(t, e, f) } - -type SigMessage struct { - Key PubKey - Sig Signature -} - -func (s SigMessage) Bytes() []byte { - return amino.BinaryBytes(s) -} - -func TestEmbededWireEncodings(t *testing.T) { - cases := []struct { - privKey PrivKey - keyType byte - keyName string - size int // pub + sig size - }{ - { - privKey: GenPrivKeyEd25519().Wrap(), - keyType: TypeEd25519, - keyName: NameEd25519, - size: 2 + 32 + 64, - }, - // { - // privKey: GenPrivKeySecp256k1().Wrap(), - // keyType: TypeSecp256k1, - // keyName: NameSecp256k1, - // size: 2 + 33 + 72, // ugh, either 72 or 73 depending.... - // }, - } - - payload := randBytes(20) - for i, tc := range cases { - pubKey := tc.privKey.PubKey() - sig := tc.privKey.Sign(payload) - assert.True(t, pubKey.VerifyBytes(payload, sig), "%d", i) - - msg := SigMessage{ - Key: pubKey, - Sig: sig, - } - var msg2 SigMessage - checkWire(t, msg, &msg2, tc.keyType, tc.size) - } -} -*/ diff --git a/keys/types.go b/keys/types.go index 16b8f6dd0..40751ad77 100644 --- a/keys/types.go +++ b/keys/types.go @@ -42,7 +42,7 @@ func (i Info) Address() []byte { } func (i Info) bytes() []byte { - bz, err := cdc.MarshalBinary(i) + bz, err := cdc.MarshalBinaryBare(i) if err != nil { panic(err) } @@ -50,6 +50,6 @@ func (i Info) bytes() []byte { } func readInfo(bz []byte) (info Info, err error) { - err = cdc.UnmarshalBinary(bz, &info) + err = cdc.UnmarshalBinaryBare(bz, &info) return } diff --git a/priv_key.go b/priv_key.go index adacb1379..61d373f60 100644 --- a/priv_key.go +++ b/priv_key.go @@ -10,7 +10,7 @@ import ( ) func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { - err = cdc.UnmarshalBinary(privKeyBytes, &privKey) + err = cdc.UnmarshalBinaryBare(privKeyBytes, &privKey) return } @@ -31,7 +31,7 @@ var _ PrivKey = PrivKeyEd25519{} type PrivKeyEd25519 [64]byte func (privKey PrivKeyEd25519) Bytes() []byte { - bz, err := cdc.MarshalBinary(privKey) + bz, err := cdc.MarshalBinaryBare(privKey) if err != nil { panic(err) } @@ -75,7 +75,7 @@ func (privKey PrivKeyEd25519) String() string { // Deterministically generates new priv-key bytes from key. func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519 { - bz, err := cdc.MarshalBinary(struct { + bz, err := cdc.MarshalBinaryBare(struct { PrivKey [64]byte Index int }{privKey, index}) @@ -113,7 +113,7 @@ var _ PrivKey = PrivKeySecp256k1{} type PrivKeySecp256k1 [32]byte func (privKey PrivKeySecp256k1) Bytes() []byte { - bz, err := cdc.MarshalBinary(privKey) + bz, err := cdc.MarshalBinaryBare(privKey) if err != nil { panic(err) } diff --git a/pub_key.go b/pub_key.go index 8ed1df356..9be64acdf 100644 --- a/pub_key.go +++ b/pub_key.go @@ -18,7 +18,7 @@ import ( type Address = cmn.HexBytes func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) { - err = cdc.UnmarshalBinary(pubKeyBytes, &pubKey) + err = cdc.UnmarshalBinaryBare(pubKeyBytes, &pubKey) return } @@ -46,7 +46,7 @@ func (pubKey PubKeyEd25519) Address() Address { } func (pubKey PubKeyEd25519) Bytes() []byte { - bz, err := cdc.MarshalBinary(pubKey) + bz, err := cdc.MarshalBinaryBare(pubKey) if err != nil { panic(err) } @@ -108,7 +108,7 @@ func (pubKey PubKeySecp256k1) Address() Address { } func (pubKey PubKeySecp256k1) Bytes() []byte { - bz, err := cdc.MarshalBinary(pubKey) + bz, err := cdc.MarshalBinaryBare(pubKey) if err != nil { panic(err) } diff --git a/signature.go b/signature.go index 3a0f6a7a7..cfe927137 100644 --- a/signature.go +++ b/signature.go @@ -8,7 +8,7 @@ import ( ) func SignatureFromBytes(pubKeyBytes []byte) (pubKey Signature, err error) { - err = cdc.UnmarshalBinary(pubKeyBytes, &pubKey) + err = cdc.UnmarshalBinaryBare(pubKeyBytes, &pubKey) return } @@ -28,7 +28,7 @@ var _ Signature = SignatureEd25519{} type SignatureEd25519 [64]byte func (sig SignatureEd25519) Bytes() []byte { - bz, err := cdc.MarshalBinary(sig) + bz, err := cdc.MarshalBinaryBare(sig) if err != nil { panic(err) } @@ -61,7 +61,7 @@ var _ Signature = SignatureSecp256k1{} type SignatureSecp256k1 []byte func (sig SignatureSecp256k1) Bytes() []byte { - bz, err := cdc.MarshalBinary(sig) + bz, err := cdc.MarshalBinaryBare(sig) if err != nil { panic(err) } diff --git a/version.go b/version.go index f641e03a3..9c51b256f 100644 --- a/version.go +++ b/version.go @@ -1,3 +1,3 @@ package crypto -const Version = "0.6.0" +const Version = "0.6.1" From 5d5f580f49ca66c13400938c64334186068c8b7c Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Mon, 26 Mar 2018 10:44:04 +0200 Subject: [PATCH 215/287] Update changelog for v0.6.1 --- CHANGELOG.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f58e18ca..8f72be957 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,18 @@ # Changelog -## 0.6.0 (March 2, 2017) +## 0.6.1 (March 26, 2018) + +BREAKING CHANGES + +- Encoding uses MarshalBinaryBare rather than MarshalBinary (which auto-length-prefixes) for pub/priv/sig. + +## 0.6.0 (March 2, 2018) BREAKING CHANGES - Update Amino names from "com.tendermint/..." to "tendermint/" -## 0.5.0 (March 2, 2017) +## 0.5.0 (March 2, 2018) BREAKING CHANGES From 7fb3f704b38492fb24cc6f807baee524ef7f4f8d Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Mon, 26 Mar 2018 10:59:10 +0200 Subject: [PATCH 216/287] Update README with examples; Add signature test --- README.md | 15 +++++++++++++++ encode_test.go | 18 ++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3c33532fc..785e887b8 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,18 @@ go-crypto is the cryptographic package adapted for Tendermint's uses ## Importing it `import "github.com/tendermint/go-crypto"` + +## Binary encoding + +go-crypto `.Bytes()` uses Amino:binary encoding, but Amino:JSON is also supported. + +```go +Example Amino:JSON encodings: + +crypto.PrivKeyEd25519 - {"type":"954568A3288910","value":"EVkqJO/jIXp3rkASXfh9YnyToYXRXhBr6g9cQVxPFnQBP/5povV4HTjvsy530kybxKHwEi85iU8YL0qQhSYVoQ=="} +crypto.SignatureEd25519 - {"type":"6BF5903DA1DB28","value":"77sQNZOrf7ltExpf7AV1WaYPCHbyRLgjBsoWVzcduuLk+jIGmYk+s5R6Emm29p12HeiNAuhUJgdFGmwkpeGJCA=="} +crypto.PubKeyEd25519 - {"type":"AC26791624DE60","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="} +crypto.PrivKeySecp256k1 - {"type":"019E82E1B0F798","value":"zx4Pnh67N+g2V+5vZbQzEyRerX9c4ccNZOVzM9RvJ0Y="} +crypto.SignatureSecp256k1 - {"type":"6D1EA416E1FEE8","value":"MEUCIQCIg5TqS1l7I+MKTrSPIuUN2+4m5tA29dcauqn3NhEJ2wIgICaZ+lgRc5aOTVahU/XoLopXKn8BZcl0bnuYWLvohR8="} +crypto.PubKeySecp256k1 - {"type":"F8CCEAEB5AE980","value":"A8lPKJXcNl5VHt1FK8a244K9EJuS4WX1hFBnwisi0IJx"} +``` diff --git a/encode_test.go b/encode_test.go index d9332238e..0bd450829 100644 --- a/encode_test.go +++ b/encode_test.go @@ -18,7 +18,9 @@ func checkAminoBinary(t *testing.T, src byter, dst interface{}, size int) { // Make sure this is compatible with current (Bytes()) encoding. assert.Equal(t, src.Bytes(), bz, "Amino binary vs Bytes() mismatch") // Make sure we have the expected length. - assert.Equal(t, size, len(bz), "Amino binary size mismatch") + if size != -1 { + assert.Equal(t, size, len(bz), "Amino binary size mismatch") + } // Unmarshal. err = cdc.UnmarshalBinaryBare(bz, dst) require.Nil(t, err, "%+v", err) @@ -41,9 +43,8 @@ func checkAminoJSON(t *testing.T, src interface{}, dst interface{}, isNil bool) func TestKeyEncodings(t *testing.T) { cases := []struct { - privKey PrivKey - // 1 (type byte) + size of byte array - privSize, pubSize int + privKey PrivKey + privSize, pubSize int // binary sizes }{ { privKey: GenPrivKeyEd25519(), @@ -58,6 +59,7 @@ func TestKeyEncodings(t *testing.T) { } for _, tc := range cases { + // Check (de/en)codings of PrivKeys. var priv2, priv3 PrivKey checkAminoBinary(t, tc.privKey, &priv2, tc.privSize) @@ -65,6 +67,14 @@ func TestKeyEncodings(t *testing.T) { checkAminoJSON(t, tc.privKey, &priv3, false) // TODO also check Prefix bytes. assert.EqualValues(t, tc.privKey, priv3) + // Check (de/en)codings of Signatures. + var sig1, sig2, sig3 Signature + sig1 = tc.privKey.Sign([]byte("something")) + checkAminoBinary(t, sig1, &sig2, -1) // Siganture size changes for Secp anyways. + assert.EqualValues(t, sig1, sig2) + checkAminoJSON(t, sig1, &sig3, false) // TODO also check Prefix bytes. + assert.EqualValues(t, sig1, sig3) + // Check (de/en)codings of PubKeys. pubKey := tc.privKey.PubKey() var pub2, pub3 PubKey From 9c02c8ce933cc67b3e7241f6d6d44c9bcfff3485 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Wed, 4 Apr 2018 23:25:14 +0100 Subject: [PATCH 217/287] Add import/export of public keys #79 --- keys/keybase.go | 47 +++++++++++++++++++++++++++++++++++ keys/keybase_test.go | 59 ++++++++++++++++++++++++++++++++++++++++++-- keys/mintkey.go | 26 +++++++++++++++---- keys/types.go | 2 ++ 4 files changed, 127 insertions(+), 7 deletions(-) diff --git a/keys/keybase.go b/keys/keybase.go index 88a12000c..5c7b64723 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -110,6 +110,10 @@ func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signat if err != nil { return } + if info.PrivKeyArmor == "" { + err = fmt.Errorf("private key not available") + return + } priv, err := unarmorDecryptPrivKey(info.PrivKeyArmor, passphrase) if err != nil { return @@ -127,6 +131,22 @@ func (kb dbKeybase) Export(name string) (armor string, err error) { return armorInfoBytes(bz), nil } +// ExportPubKey returns public keys in ASCII armored format. +func (kb dbKeybase) ExportPubKey(name string) (armor string, err error) { + bz := kb.db.Get(infoKey(name)) + if bz == nil { + return "", errors.New("No key to export with name " + name) + } + info, err := readInfo(bz) + if err != nil { + return + } + return armorPubKeyBytes(info.PubKey.Bytes()), nil +} + +// ExportPubKey imports ASCII-armored public keys. +// Store a new Info object holding a public key only, i.e. it will +// not be possible to sign with it as it lacks the secret key. func (kb dbKeybase) Import(name string, armor string) (err error) { bz := kb.db.Get(infoKey(name)) if len(bz) > 0 { @@ -140,6 +160,23 @@ func (kb dbKeybase) Import(name string, armor string) (err error) { return nil } +func (kb dbKeybase) ImportPubKey(name string, armor string) (err error) { + bz := kb.db.Get(infoKey(name)) + if len(bz) > 0 { + return errors.New("Cannot overwrite data for name " + name) + } + pubBytes, err := unarmorPubKeyBytes(armor) + if err != nil { + return + } + pubKey, err := crypto.PubKeyFromBytes(pubBytes) + if err != nil { + return + } + kb.writePubKey(pubKey, name) + return +} + // Delete removes key forever, but we must present the // proper passphrase before deleting it (for security). func (kb dbKeybase) Delete(name, passphrase string) error { @@ -174,6 +211,16 @@ func (kb dbKeybase) Update(name, oldpass, newpass string) error { kb.writeKey(key, name, newpass) return nil } + +func (kb dbKeybase) writePubKey(pub crypto.PubKey, name string) Info { + // make Info + info := newInfo(name, pub, "") + + // write them both + kb.db.SetSync(infoKey(name), info.bytes()) + return info +} + func (kb dbKeybase) writeKey(priv crypto.PrivKey, name, passphrase string) Info { // generate the encrypted privkey privArmor := encryptArmorPrivKey(priv, passphrase) diff --git a/keys/keybase_test.go b/keys/keybase_test.go index 84c81c81f..aaf3b92fb 100644 --- a/keys/keybase_test.go +++ b/keys/keybase_test.go @@ -91,8 +91,8 @@ func TestSignVerify(t *testing.T) { ) algo := keys.AlgoSecp256k1 - n1, n2 := "some dude", "a dudette" - p1, p2 := "1234", "foobar" + n1, n2, n3 := "some dude", "a dudette", "dude-ish" + p1, p2, p3 := "1234", "foobar", "foobar" // create two users and get their info i1, _, err := cstore.Create(n1, p1, algo) @@ -101,9 +101,18 @@ func TestSignVerify(t *testing.T) { i2, _, err := cstore.Create(n2, p2, algo) require.Nil(t, err) + // Import a public key + armor, err := cstore.ExportPubKey(n2) + require.Nil(t, err) + cstore.ImportPubKey(n3, armor) + i3, err := cstore.Get(n3) + require.Nil(t, err) + require.Equal(t, i3.PrivKeyArmor, "") + // let's try to sign some messages d1 := []byte("my first message") d2 := []byte("some other important info!") + d3 := []byte("feels like I forgot something...") // try signing both data with both keys... s11, pub1, err := cstore.Sign(n1, p1, d1) @@ -145,6 +154,10 @@ func TestSignVerify(t *testing.T) { valid := tc.key.VerifyBytes(tc.data, tc.sig) assert.Equal(t, tc.valid, valid, "%d", i) } + + // Now try to sign data with a secret-less key + _, _, err = cstore.Sign(n3, p3, d3) + assert.NotNil(t, err) } /* @@ -243,6 +256,48 @@ func TestExportImport(t *testing.T) { assert.Equal(t, john, john2) } +func TestExportImportPubKey(t *testing.T) { + // make the storage with reasonable defaults + db := dbm.NewMemDB() + cstore := keys.New( + db, + words.MustLoadCodec("english"), + ) + + // Create a private-public key pair and ensure consistency + info, _, err := cstore.Create("john", "passphrase", keys.AlgoEd25519) + assert.Nil(t, err) + assert.NotEqual(t, info.PrivKeyArmor, "") + assert.Equal(t, info.Name, "john") + addr := info.PubKey.Address() + john, err := cstore.Get("john") + assert.Nil(t, err) + assert.Equal(t, john.Name, "john") + assert.Equal(t, john.PubKey.Address(), addr) + + // Export the public key only + armor, err := cstore.ExportPubKey("john") + assert.Nil(t, err) + // Import it under a different name + err = cstore.ImportPubKey("john-pubkey-only", armor) + assert.Nil(t, err) + // Ensure consistency + john2, err := cstore.Get("john-pubkey-only") + assert.Nil(t, err) + assert.Equal(t, john2.PrivKeyArmor, "") + // Compare the public keys + assert.True(t, john.PubKey.Equals(john2.PubKey)) + // Ensure the original key hasn't changed + john, err = cstore.Get("john") + assert.Nil(t, err) + assert.Equal(t, john.PubKey.Address(), addr) + assert.Equal(t, john.Name, "john") + + // Ensure keys cannot be overwritten + err = cstore.ImportPubKey("john-pubkey-only", armor) + assert.NotNil(t, err) +} + // TestAdvancedKeyManagement verifies update, import, export functionality func TestAdvancedKeyManagement(t *testing.T) { diff --git a/keys/mintkey.go b/keys/mintkey.go index 73263b83a..264a9747d 100644 --- a/keys/mintkey.go +++ b/keys/mintkey.go @@ -13,24 +13,40 @@ import ( const ( blockTypePrivKey = "TENDERMINT PRIVATE KEY" blockTypeKeyInfo = "TENDERMINT KEY INFO" + blockTypePubKey = "TENDERMINT PUBLIC KEY" ) func armorInfoBytes(bz []byte) string { + return armorBytes(bz, blockTypeKeyInfo) +} + +func armorPubKeyBytes(bz []byte) string { + return armorBytes(bz, blockTypePubKey) +} + +func armorBytes(bz []byte, blockType string) string { header := map[string]string{ "type": "Info", "version": "0.0.0", } - armorStr := crypto.EncodeArmor(blockTypeKeyInfo, header, bz) - return armorStr + return crypto.EncodeArmor(blockType, header, bz) } func unarmorInfoBytes(armorStr string) (bz []byte, err error) { - blockType, header, bz, err := crypto.DecodeArmor(armorStr) + return unarmorBytes(armorStr, blockTypeKeyInfo) +} + +func unarmorPubKeyBytes(armorStr string) (bz []byte, err error) { + return unarmorBytes(armorStr, blockTypePubKey) +} + +func unarmorBytes(armorStr, blockType string) (bz []byte, err error) { + bType, header, bz, err := crypto.DecodeArmor(armorStr) if err != nil { return } - if blockType != blockTypeKeyInfo { - err = fmt.Errorf("Unrecognized armor type: %v", blockType) + if bType != blockType { + err = fmt.Errorf("Unrecognized armor type %q, expected: %q", bType, blockType) return } if header["version"] != "0.0.0" { diff --git a/keys/types.go b/keys/types.go index 40751ad77..e1df644ab 100644 --- a/keys/types.go +++ b/keys/types.go @@ -18,7 +18,9 @@ type Keybase interface { Delete(name, passphrase string) error Import(name string, armor string) (err error) + ImportPubKey(name string, armor string) (err error) Export(name string) (armor string, err error) + ExportPubKey(name string) (armor string, err error) } // Info is the public information about a key From 105847b7dd804b297a03959d356dba458f608932 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Thu, 5 Apr 2018 08:13:13 +0100 Subject: [PATCH 218/287] Fix comments --- keys/keybase.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/keys/keybase.go b/keys/keybase.go index 5c7b64723..876eef8f5 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -132,6 +132,8 @@ func (kb dbKeybase) Export(name string) (armor string, err error) { } // ExportPubKey returns public keys in ASCII armored format. +// Retrieve a Info object by its name and return the public key in +// a portable format. func (kb dbKeybase) ExportPubKey(name string) (armor string, err error) { bz := kb.db.Get(infoKey(name)) if bz == nil { @@ -144,9 +146,6 @@ func (kb dbKeybase) ExportPubKey(name string) (armor string, err error) { return armorPubKeyBytes(info.PubKey.Bytes()), nil } -// ExportPubKey imports ASCII-armored public keys. -// Store a new Info object holding a public key only, i.e. it will -// not be possible to sign with it as it lacks the secret key. func (kb dbKeybase) Import(name string, armor string) (err error) { bz := kb.db.Get(infoKey(name)) if len(bz) > 0 { @@ -160,6 +159,9 @@ func (kb dbKeybase) Import(name string, armor string) (err error) { return nil } +// ExportPubKey imports ASCII-armored public keys. +// Store a new Info object holding a public key only, i.e. it will +// not be possible to sign with it as it lacks the secret key. func (kb dbKeybase) ImportPubKey(name string, armor string) (err error) { bz := kb.db.Get(infoKey(name)) if len(bz) > 0 { From 915416979bf70efa4bcbf1c6cd5d64c5fff9fc19 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 9 Apr 2018 16:21:58 +0300 Subject: [PATCH 219/287] update for latest amino. bump version --- CHANGELOG.md | 6 ++++++ Gopkg.lock | 14 +++++++------- Gopkg.toml | 4 ++-- version.go | 2 +- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f72be957..91dcfab52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.6.2 (April 9, 2018) + +IMPROVEMENTS + +- Update for latest go-amino + ## 0.6.1 (March 26, 2018) BREAKING CHANGES diff --git a/Gopkg.lock b/Gopkg.lock index bfe089b72..f52af5591 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -113,7 +113,7 @@ "leveldb/table", "leveldb/util" ] - revision = "169b1b37be738edb2813dab48c97a549bcf99bb5" + revision = "714f901b98fdb3aa954b4193d8cbd64a28d80cad" [[projects]] branch = "master" @@ -128,8 +128,8 @@ [[projects]] name = "github.com/tendermint/go-amino" packages = ["."] - revision = "f55c3351f30e5987500020631f00e87a035ed415" - version = "0.9.3" + revision = "42246108ff925a457fb709475070a03dfd3e2b5c" + version = "0.9.6" [[projects]] name = "github.com/tendermint/tmlibs" @@ -138,8 +138,8 @@ "db", "log" ] - revision = "e9cf47606cfcbdc28a7c16671b4a70b459e9d4cc" - version = "v0.8.0-dev" + revision = "2e24b64fc121dcdf1cabceab8dc2f7257675483c" + version = "v0.8.1" [[projects]] branch = "master" @@ -161,11 +161,11 @@ "ripemd160", "salsa20/salsa" ] - revision = "b4956d363a8b14623cc81db401707679605930a3" + revision = "b2aa35443fbc700ab74c586ae79b81c171851023" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "9748e96106582387ac49df1db8e4456bd51c8e9362c86992d6ce7011c1783f55" + inputs-digest = "f9ccfa2cadfcbfb43bf729b871a0ad2f8d4f4acb118cd859e6faf9b24842b840" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index a7f84bb59..4ccb8c07d 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -47,11 +47,11 @@ [[constraint]] name = "github.com/tendermint/go-amino" - version = "0.9.3" + version = "0.9.6" [[constraint]] name = "github.com/tendermint/tmlibs" - version = "0.8.0-dev" + version = "0.8.1" [[constraint]] name = "github.com/tyler-smith/go-bip39" diff --git a/version.go b/version.go index 9c51b256f..aac87c4f3 100644 --- a/version.go +++ b/version.go @@ -1,3 +1,3 @@ package crypto -const Version = "0.6.1" +const Version = "0.6.2" From ad837a8183fcfe84248cc3a92157fb463b2d7b09 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 5 May 2018 19:17:21 -0400 Subject: [PATCH 220/287] fix ed25519 Generate --- priv_key.go | 7 ++++--- priv_key_test.go | 16 +++++++++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/priv_key.go b/priv_key.go index 61d373f60..82e1cfced 100644 --- a/priv_key.go +++ b/priv_key.go @@ -83,9 +83,10 @@ func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519 { panic(err) } newBytes := Sha256(bz) - var newKey [64]byte - copy(newKey[:], newBytes) - return PrivKeyEd25519(newKey) + newKey := new([64]byte) + copy(newKey[:32], newBytes) + ed25519.MakePublicKey(newKey) + return PrivKeyEd25519(*newKey) } func GenPrivKeyEd25519() PrivKeyEd25519 { diff --git a/priv_key_test.go b/priv_key_test.go index 3fbfba34d..6abe36ac5 100644 --- a/priv_key_test.go +++ b/priv_key_test.go @@ -1,15 +1,21 @@ -package crypto - -/* +package crypto_test import ( - "fmt" "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + crypto "github.com/tendermint/go-crypto" ) +func TestGeneratePrivKey(t *testing.T) { + testPriv := crypto.GenPrivKeyEd25519() + testGenerate := testPriv.Generate(1) + signBytes := []byte("something to sign") + assert.True(t, testGenerate.PubKey().VerifyBytes(signBytes, testGenerate.Sign(signBytes))) +} + +/* + type BadKey struct { PrivKeyEd25519 } From 94ce56d243e02cbfab1dfc1868a06a79cb07a0e4 Mon Sep 17 00:00:00 2001 From: Liamsi Date: Wed, 9 May 2018 11:48:46 +0100 Subject: [PATCH 221/287] Use constant-time comparator (sublte.ConstantTimeCompare) to compare signatures prevents potential signature forgery resolves #91 --- signature.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/signature.go b/signature.go index cfe927137..4f55420c5 100644 --- a/signature.go +++ b/signature.go @@ -1,9 +1,10 @@ package crypto import ( - "bytes" "fmt" + "crypto/subtle" + . "github.com/tendermint/tmlibs/common" ) @@ -41,7 +42,7 @@ func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fing func (sig SignatureEd25519) Equals(other Signature) bool { if otherEd, ok := other.(SignatureEd25519); ok { - return bytes.Equal(sig[:], otherEd[:]) + return subtle.ConstantTimeCompare(sig[:], otherEd[:]) == 1 } else { return false } @@ -74,7 +75,7 @@ func (sig SignatureSecp256k1) String() string { return fmt.Sprintf("/%X.../", Fi func (sig SignatureSecp256k1) Equals(other Signature) bool { if otherSecp, ok := other.(SignatureSecp256k1); ok { - return bytes.Equal(sig[:], otherSecp[:]) + return subtle.ConstantTimeCompare(sig[:], otherSecp[:]) == 1 } else { return false } From 3477dd7a9042e04517d79d0eb153f8fe715c3786 Mon Sep 17 00:00:00 2001 From: Liamsi Date: Wed, 9 May 2018 14:30:17 +0100 Subject: [PATCH 222/287] safer PRNG seeding: hash concatenation of fresh seedBytes with current seedBytes --- random.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/random.go b/random.go index 46754219d..66da035a9 100644 --- a/random.go +++ b/random.go @@ -4,6 +4,7 @@ import ( "crypto/aes" "crypto/cipher" crand "crypto/rand" + "crypto/sha256" "encoding/hex" "io" "sync" @@ -72,8 +73,12 @@ type randInfo struct { func (ri *randInfo) MixEntropy(seedBytes []byte) { ri.mtx.Lock() defer ri.mtx.Unlock() - // Make new ri.seedBytes - hashBytes := Sha256(seedBytes) + // Make new ri.seedBytes using passed seedBytes and current ri.seedBytes: + // ri.seedBytes = sha256( seedBytes || ri.seedBytes ) + h := sha256.New() + h.Write(seedBytes) + h.Write(ri.seedBytes[:]) + hashBytes := h.Sum(nil) hashBytes32 := [32]byte{} copy(hashBytes32[:], hashBytes) ri.seedBytes = xorBytes32(ri.seedBytes, hashBytes32) From 35cf21c6ebdad9632414d3f244824302b2717e56 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Wed, 9 May 2018 13:48:21 -0700 Subject: [PATCH 223/287] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 785e887b8..4a524c014 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,10 @@ go-crypto is the cryptographic package adapted for Tendermint's uses ## Binary encoding +For Binary encoding, please refer to the [Tendermint encoding spec](https://github.com/tendermint/tendermint/blob/develop/docs/specification/new-spec/encoding.md). + +## JSON Encoding + go-crypto `.Bytes()` uses Amino:binary encoding, but Amino:JSON is also supported. ```go From 43570388a9dbb56e098bb30ff61d4b0d8795ae09 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Wed, 9 May 2018 13:48:49 -0700 Subject: [PATCH 224/287] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 785e887b8..4a524c014 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,10 @@ go-crypto is the cryptographic package adapted for Tendermint's uses ## Binary encoding +For Binary encoding, please refer to the [Tendermint encoding spec](https://github.com/tendermint/tendermint/blob/develop/docs/specification/new-spec/encoding.md). + +## JSON Encoding + go-crypto `.Bytes()` uses Amino:binary encoding, but Amino:JSON is also supported. ```go From 1c8dffaa282ba9ebfe597e38f9849bc70f40efe5 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Sun, 13 May 2018 11:06:20 -0400 Subject: [PATCH 225/287] Initial implementation of xchacha20poly1035 aead --- xchacha20poly1035/xchachapoly.go | 237 +++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 xchacha20poly1035/xchachapoly.go diff --git a/xchacha20poly1035/xchachapoly.go b/xchacha20poly1035/xchachapoly.go new file mode 100644 index 000000000..b9d823414 --- /dev/null +++ b/xchacha20poly1035/xchachapoly.go @@ -0,0 +1,237 @@ +package xchacha20poly1305 + +import ( + "crypto/cipher" + "encoding/binary" + "errors" + + "golang.org/x/crypto/chacha20poly1305" +) + +var sigma = [4]uint32{0x61707865, 0x3320646e, 0x79622d32, 0x6b206574} + +type xchacha20poly1305 struct { + key [KeySize]byte +} + +const ( + // KeySize is the size of the key used by this AEAD, in bytes. + KeySize = 32 + // NonceSize is the size of the nonce used with this AEAD, in bytes. + NonceSize = 24 +) + +//New xChaChapoly1305 AEAD with 24 byte nonces +func New(key []byte) (cipher.AEAD, error) { + if len(key) != KeySize { + return nil, errors.New("chacha20poly1305: bad key length") + } + ret := new(xchacha20poly1305) + copy(ret.key[:], key) + return ret, nil + +} +func (c *xchacha20poly1305) NonceSize() int { + return NonceSize +} + +func (c *xchacha20poly1305) Overhead() int { + return 16 +} + +func (c *xchacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte { + if len(nonce) != NonceSize { + panic("chacha20poly1305: bad nonce length passed to Seal") + } + + if uint64(len(plaintext)) > (1<<38)-64 { + panic("chacha20poly1305: plaintext too large") + } + + var subKey [KeySize]byte + var hNonce [16]byte + var subNonce [chacha20poly1305.NonceSize]byte + copy(hNonce[:], nonce[:16]) + + HChaCha20(&subKey, &hNonce, &c.key) + + chacha20poly1305, _ := chacha20poly1305.New(subKey[:]) + + copy(subNonce[4:], nonce[16:]) + + return chacha20poly1305.Seal(dst, subNonce[:], plaintext, additionalData) +} + +func (c *xchacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { + if len(nonce) != NonceSize { + panic("chacha20poly1305: bad nonce length passed to Open") + } + if uint64(len(ciphertext)) > (1<<38)-48 { + panic("chacha20poly1305: ciphertext too large") + } + var subKey [KeySize]byte + var hNonce [16]byte + var subNonce [chacha20poly1305.NonceSize]byte + copy(hNonce[:], nonce[:16]) + + HChaCha20(&subKey, &hNonce, &c.key) + + chacha20poly1305, _ := chacha20poly1305.New(subKey[:]) + + copy(subNonce[4:], nonce[16:]) + + return chacha20poly1305.Open(dst, subNonce[:], ciphertext, additionalData) +} + +// The MIT License (MIT) + +// Copyright (c) 2016 Andreas Auernhammer + +// 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. + +// HChaCha20 generates 32 pseudo-random bytes from a 128 bit nonce and a 256 bit secret key. +// It can be used as a key-derivation-function (KDF). +func HChaCha20(out *[32]byte, nonce *[16]byte, key *[32]byte) { hChaCha20Generic(out, nonce, key) } + +func hChaCha20Generic(out *[32]byte, nonce *[16]byte, key *[32]byte) { + v00 := sigma[0] + v01 := sigma[1] + v02 := sigma[2] + v03 := sigma[3] + v04 := binary.LittleEndian.Uint32(key[0:]) + v05 := binary.LittleEndian.Uint32(key[4:]) + v06 := binary.LittleEndian.Uint32(key[8:]) + v07 := binary.LittleEndian.Uint32(key[12:]) + v08 := binary.LittleEndian.Uint32(key[16:]) + v09 := binary.LittleEndian.Uint32(key[20:]) + v10 := binary.LittleEndian.Uint32(key[24:]) + v11 := binary.LittleEndian.Uint32(key[28:]) + v12 := binary.LittleEndian.Uint32(nonce[0:]) + v13 := binary.LittleEndian.Uint32(nonce[4:]) + v14 := binary.LittleEndian.Uint32(nonce[8:]) + v15 := binary.LittleEndian.Uint32(nonce[12:]) + + for i := 0; i < 20; i += 2 { + v00 += v04 + v12 ^= v00 + v12 = (v12 << 16) | (v12 >> 16) + v08 += v12 + v04 ^= v08 + v04 = (v04 << 12) | (v04 >> 20) + v00 += v04 + v12 ^= v00 + v12 = (v12 << 8) | (v12 >> 24) + v08 += v12 + v04 ^= v08 + v04 = (v04 << 7) | (v04 >> 25) + v01 += v05 + v13 ^= v01 + v13 = (v13 << 16) | (v13 >> 16) + v09 += v13 + v05 ^= v09 + v05 = (v05 << 12) | (v05 >> 20) + v01 += v05 + v13 ^= v01 + v13 = (v13 << 8) | (v13 >> 24) + v09 += v13 + v05 ^= v09 + v05 = (v05 << 7) | (v05 >> 25) + v02 += v06 + v14 ^= v02 + v14 = (v14 << 16) | (v14 >> 16) + v10 += v14 + v06 ^= v10 + v06 = (v06 << 12) | (v06 >> 20) + v02 += v06 + v14 ^= v02 + v14 = (v14 << 8) | (v14 >> 24) + v10 += v14 + v06 ^= v10 + v06 = (v06 << 7) | (v06 >> 25) + v03 += v07 + v15 ^= v03 + v15 = (v15 << 16) | (v15 >> 16) + v11 += v15 + v07 ^= v11 + v07 = (v07 << 12) | (v07 >> 20) + v03 += v07 + v15 ^= v03 + v15 = (v15 << 8) | (v15 >> 24) + v11 += v15 + v07 ^= v11 + v07 = (v07 << 7) | (v07 >> 25) + v00 += v05 + v15 ^= v00 + v15 = (v15 << 16) | (v15 >> 16) + v10 += v15 + v05 ^= v10 + v05 = (v05 << 12) | (v05 >> 20) + v00 += v05 + v15 ^= v00 + v15 = (v15 << 8) | (v15 >> 24) + v10 += v15 + v05 ^= v10 + v05 = (v05 << 7) | (v05 >> 25) + v01 += v06 + v12 ^= v01 + v12 = (v12 << 16) | (v12 >> 16) + v11 += v12 + v06 ^= v11 + v06 = (v06 << 12) | (v06 >> 20) + v01 += v06 + v12 ^= v01 + v12 = (v12 << 8) | (v12 >> 24) + v11 += v12 + v06 ^= v11 + v06 = (v06 << 7) | (v06 >> 25) + v02 += v07 + v13 ^= v02 + v13 = (v13 << 16) | (v13 >> 16) + v08 += v13 + v07 ^= v08 + v07 = (v07 << 12) | (v07 >> 20) + v02 += v07 + v13 ^= v02 + v13 = (v13 << 8) | (v13 >> 24) + v08 += v13 + v07 ^= v08 + v07 = (v07 << 7) | (v07 >> 25) + v03 += v04 + v14 ^= v03 + v14 = (v14 << 16) | (v14 >> 16) + v09 += v14 + v04 ^= v09 + v04 = (v04 << 12) | (v04 >> 20) + v03 += v04 + v14 ^= v03 + v14 = (v14 << 8) | (v14 >> 24) + v09 += v14 + v04 ^= v09 + v04 = (v04 << 7) | (v04 >> 25) + } + + binary.LittleEndian.PutUint32(out[0:], v00) + binary.LittleEndian.PutUint32(out[4:], v01) + binary.LittleEndian.PutUint32(out[8:], v02) + binary.LittleEndian.PutUint32(out[12:], v03) + binary.LittleEndian.PutUint32(out[16:], v12) + binary.LittleEndian.PutUint32(out[20:], v13) + binary.LittleEndian.PutUint32(out[24:], v14) + binary.LittleEndian.PutUint32(out[28:], v15) +} From 1c9ff46e98df9e76d4b9a160c4635d72afd12f04 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 30 Apr 2018 16:42:11 +0200 Subject: [PATCH 226/287] Ledger integration, WIP --- Gopkg.lock | 14 ++- Gopkg.toml | 4 + _nano/keys.go | 294 --------------------------------------------- _nano/keys_test.go | 142 ---------------------- _nano/sign.go | 63 ---------- _nano/sign_test.go | 160 ------------------------ amino.go | 2 + ledger.go | 154 ++++++++++++++++++++++++ ledger_test.go | 72 +++++++++++ signature.go | 6 + 10 files changed, 251 insertions(+), 660 deletions(-) delete mode 100644 _nano/keys.go delete mode 100644 _nano/keys_test.go delete mode 100644 _nano/sign.go delete mode 100644 _nano/sign_test.go create mode 100644 ledger.go create mode 100644 ledger_test.go diff --git a/Gopkg.lock b/Gopkg.lock index f52af5591..fbfaa63fa 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1,6 +1,12 @@ # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. +[[projects]] + branch = "master" + name = "github.com/brejski/hid" + packages = ["."] + revision = "06112dcfcc50a7e0e4fd06e17f9791e788fdaafc" + [[projects]] branch = "master" name = "github.com/btcsuite/btcd" @@ -147,6 +153,12 @@ packages = ["."] revision = "8e7a99b3e716f36d3b080a9a70f9eb45abe4edcc" +[[projects]] + branch = "master" + name = "github.com/zondax/ledger-goclient" + packages = ["."] + revision = "0eb48e14b06efd0354c2e0e18f15db121c64b9b8" + [[projects]] branch = "master" name = "golang.org/x/crypto" @@ -166,6 +178,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "f9ccfa2cadfcbfb43bf729b871a0ad2f8d4f4acb118cd859e6faf9b24842b840" + inputs-digest = "f3cfb54414cb9d59bab79226c7778673e7ac5b7a464baf9b2ea76c1f2563631e" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 4ccb8c07d..3737ec5f9 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -57,6 +57,10 @@ name = "github.com/tyler-smith/go-bip39" branch = "master" +[[constraint]] + name = "github.com/zondax/ledger-goclient" + branch = "master" + [prune] go-tests = true unused-packages = true diff --git a/_nano/keys.go b/_nano/keys.go deleted file mode 100644 index 8cf1c3721..000000000 --- a/_nano/keys.go +++ /dev/null @@ -1,294 +0,0 @@ -package nano - -import ( - "bytes" - "encoding/hex" - - "github.com/pkg/errors" - - ledger "github.com/ethanfrey/ledger" - - crypto "github.com/tendermint/go-crypto" - amino "github.com/tendermint/go-amino" -) - -//nolint -const ( - NameLedgerEd25519 = "ledger-ed25519" - TypeLedgerEd25519 = 0x10 - - // Timeout is the number of seconds to wait for a response from the ledger - // if eg. waiting for user confirmation on button push - Timeout = 20 -) - -var device *ledger.Ledger - -// getLedger gets a copy of the device, and caches it -func getLedger() (*ledger.Ledger, error) { - var err error - if device == nil { - device, err = ledger.FindLedger() - } - return device, err -} - -func signLedger(device *ledger.Ledger, msg []byte) (pub crypto.PubKey, sig crypto.Signature, err error) { - var resp []byte - - packets := generateSignRequests(msg) - for _, pack := range packets { - resp, err = device.Exchange(pack, Timeout) - if err != nil { - return pub, sig, err - } - } - - // the last call is the result we want and needs to be parsed - key, bsig, err := parseDigest(resp) - if err != nil { - return pub, sig, err - } - - var b [32]byte - copy(b[:], key) - return PubKeyLedgerEd25519FromBytes(b), crypto.SignatureEd25519FromBytes(bsig), nil -} - -// PrivKeyLedgerEd25519 implements PrivKey, calling the ledger nano -// we cache the PubKey from the first call to use it later -type PrivKeyLedgerEd25519 struct { - // PubKey should be private, but we want to encode it via go-amino - // so we can view the address later, even without having the ledger - // attached - CachedPubKey crypto.PubKey -} - -// NewPrivKeyLedgerEd25519 will generate a new key and store the -// public key for later use. -func NewPrivKeyLedgerEd25519() (crypto.PrivKey, error) { - var pk PrivKeyLedgerEd25519 - // getPubKey will cache the pubkey for later use, - // this allows us to return an error early if the ledger - // is not plugged in - _, err := pk.getPubKey() - return pk.Wrap(), err -} - -// ValidateKey allows us to verify the sanity of a key -// after loading it from disk -func (pk *PrivKeyLedgerEd25519) ValidateKey() error { - // getPubKey will return an error if the ledger is not - // properly set up... - pub, err := pk.forceGetPubKey() - if err != nil { - return err - } - // verify this matches cached address - if !pub.Equals(pk.CachedPubKey) { - return errors.New("ledger doesn't match cached key") - } - return nil -} - -// AssertIsPrivKeyInner fulfils PrivKey Interface -func (pk *PrivKeyLedgerEd25519) AssertIsPrivKeyInner() {} - -// Bytes fulfils PrivKey Interface - but it stores the cached pubkey so we can verify -// the same key when we reconnect to a ledger -func (pk *PrivKeyLedgerEd25519) Bytes() []byte { - return amino.BinaryBytes(pk.Wrap()) -} - -// Sign calls the ledger and stores the PubKey for future use -// -// XXX/TODO: panics if there is an error communicating with the ledger. -// -// Communication is checked on NewPrivKeyLedger and PrivKeyFromBytes, -// returning an error, so this should only trigger if the privkey is held -// in memory for a while before use. -func (pk *PrivKeyLedgerEd25519) Sign(msg []byte) crypto.Signature { - // oh, I wish there was better error handling - dev, err := getLedger() - if err != nil { - panic(err) - } - - pub, sig, err := signLedger(dev, msg) - if err != nil { - panic(err) - } - - // if we have no pubkey yet, store it for future queries - if pk.CachedPubKey.Empty() { - pk.CachedPubKey = pub - } else if !pk.CachedPubKey.Equals(pub) { - panic("signed with a different key than stored") - } - return sig -} - -// PubKey returns the stored PubKey -// TODO: query the ledger if not there, once it is not volatile -func (pk *PrivKeyLedgerEd25519) PubKey() crypto.PubKey { - key, err := pk.getPubKey() - if err != nil { - panic(err) - } - return key -} - -// getPubKey reads the pubkey from cache or from the ledger itself -// since this involves IO, it may return an error, which is not exposed -// in the PubKey interface, so this function allows better error handling -func (pk *PrivKeyLedgerEd25519) getPubKey() (key crypto.PubKey, err error) { - // if we have no pubkey, set it - if pk.CachedPubKey.Empty() { - pk.CachedPubKey, err = pk.forceGetPubKey() - } - return pk.CachedPubKey, err -} - -// forceGetPubKey is like getPubKey but ignores any cached key -// and ensures we get it from the ledger itself. -func (pk *PrivKeyLedgerEd25519) forceGetPubKey() (key crypto.PubKey, err error) { - dev, err := getLedger() - if err != nil { - return key, errors.New("Can't connect to ledger device") - } - key, _, err = signLedger(dev, []byte{0}) - if err != nil { - return key, errors.New("Please open cosmos app on the ledger") - } - return key, err -} - -// Equals fulfils PrivKey Interface - makes sure both keys refer to the -// same -func (pk *PrivKeyLedgerEd25519) Equals(other crypto.PrivKey) bool { - if ledger, ok := other.Unwrap().(*PrivKeyLedgerEd25519); ok { - return pk.CachedPubKey.Equals(ledger.CachedPubKey) - } - return false -} - -// MockPrivKeyLedgerEd25519 behaves as the ledger, but stores a pre-packaged call-response -// for use in test cases -type MockPrivKeyLedgerEd25519 struct { - Msg []byte - Pub [KeyLength]byte - Sig [SigLength]byte -} - -// NewMockKey returns -func NewMockKey(msg, pubkey, sig string) (pk MockPrivKeyLedgerEd25519) { - var err error - pk.Msg, err = hex.DecodeString(msg) - if err != nil { - panic(err) - } - - bpk, err := hex.DecodeString(pubkey) - if err != nil { - panic(err) - } - bsig, err := hex.DecodeString(sig) - if err != nil { - panic(err) - } - - copy(pk.Pub[:], bpk) - copy(pk.Sig[:], bsig) - return pk -} - -var _ crypto.PrivKeyInner = MockPrivKeyLedgerEd25519{} - -// AssertIsPrivKeyInner fulfils PrivKey Interface -func (pk MockPrivKeyLedgerEd25519) AssertIsPrivKeyInner() {} - -// Bytes fulfils PrivKey Interface - not supported -func (pk MockPrivKeyLedgerEd25519) Bytes() []byte { - return nil -} - -// Sign returns a real SignatureLedger, if the msg matches what we expect -func (pk MockPrivKeyLedgerEd25519) Sign(msg []byte) crypto.Signature { - if !bytes.Equal(pk.Msg, msg) { - panic("Mock key is for different msg") - } - return crypto.SignatureEd25519(pk.Sig).Wrap() -} - -// PubKey returns a real PubKeyLedgerEd25519, that will verify this signature -func (pk MockPrivKeyLedgerEd25519) PubKey() crypto.PubKey { - return PubKeyLedgerEd25519FromBytes(pk.Pub) -} - -// Equals compares that two Mocks have the same data -func (pk MockPrivKeyLedgerEd25519) Equals(other crypto.PrivKey) bool { - if mock, ok := other.Unwrap().(MockPrivKeyLedgerEd25519); ok { - return bytes.Equal(mock.Pub[:], pk.Pub[:]) && - bytes.Equal(mock.Sig[:], pk.Sig[:]) && - bytes.Equal(mock.Msg, pk.Msg) - } - return false -} - -//////////////////////////////////////////// -// pubkey - -// PubKeyLedgerEd25519 works like a normal Ed25519 except a hash before the verify bytes -type PubKeyLedgerEd25519 struct { - crypto.PubKeyEd25519 -} - -// PubKeyLedgerEd25519FromBytes creates a PubKey from the raw bytes -func PubKeyLedgerEd25519FromBytes(key [32]byte) crypto.PubKey { - return PubKeyLedgerEd25519{crypto.PubKeyEd25519(key)}.Wrap() -} - -// Bytes fulfils pk Interface - no data, just type info -func (pk PubKeyLedgerEd25519) Bytes() []byte { - return amino.BinaryBytes(pk.Wrap()) -} - -// VerifyBytes uses the normal Ed25519 algorithm but a sha512 hash beforehand -func (pk PubKeyLedgerEd25519) VerifyBytes(msg []byte, sig crypto.Signature) bool { - hmsg := hashMsg(msg) - return pk.PubKeyEd25519.VerifyBytes(hmsg, sig) -} - -// Equals implements PubKey interface -func (pk PubKeyLedgerEd25519) Equals(other crypto.PubKey) bool { - if ledger, ok := other.Unwrap().(PubKeyLedgerEd25519); ok { - return pk.PubKeyEd25519.Equals(ledger.PubKeyEd25519.Wrap()) - } - return false -} - -/*** registration with go-data ***/ - -func init() { - crypto.PrivKeyMapper. - RegisterImplementation(&PrivKeyLedgerEd25519{}, NameLedgerEd25519, TypeLedgerEd25519). - RegisterImplementation(MockPrivKeyLedgerEd25519{}, "mock-ledger", 0x11) - - crypto.PubKeyMapper. - RegisterImplementation(PubKeyLedgerEd25519{}, NameLedgerEd25519, TypeLedgerEd25519) -} - -// Wrap fulfils interface for PrivKey struct -func (pk *PrivKeyLedgerEd25519) Wrap() crypto.PrivKey { - return crypto.PrivKey{PrivKeyInner: pk} -} - -// Wrap fulfils interface for PrivKey struct -func (pk MockPrivKeyLedgerEd25519) Wrap() crypto.PrivKey { - return crypto.PrivKey{PrivKeyInner: pk} -} - -// Wrap fulfils interface for PubKey struct -func (pk PubKeyLedgerEd25519) Wrap() crypto.PubKey { - return crypto.PubKey{PubKeyInner: pk} -} diff --git a/_nano/keys_test.go b/_nano/keys_test.go deleted file mode 100644 index fda096e29..000000000 --- a/_nano/keys_test.go +++ /dev/null @@ -1,142 +0,0 @@ -package nano - -import ( - "encoding/hex" - "os" - "testing" - - asrt "github.com/stretchr/testify/assert" - rqr "github.com/stretchr/testify/require" - - crypto "github.com/tendermint/go-crypto" -) - -func TestLedgerKeys(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) - - cases := []struct { - msg, pubkey, sig string - valid bool - }{ - 0: { - msg: "F00D", - pubkey: "8E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C93", - sig: "787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400", - valid: true, - }, - 1: { - msg: "DEADBEEF", - pubkey: "0C45ADC887A5463F668533443C829ED13EA8E2E890C778957DC28DB9D2AD5A6C", - sig: "00ED74EED8FDAC7988A14BF6BC222120CBAC249D569AF4C2ADABFC86B792F97DF73C4919BE4B6B0ACB53547273BF29FBF0A9E0992FFAB6CB6C9B09311FC86A00", - valid: true, - }, - 2: { - msg: "1234567890AA", - pubkey: "598FC1F0C76363D14D7480736DEEF390D85863360F075792A6975EFA149FD7EA", - sig: "59AAB7D7BDC4F936B6415DE672A8B77FA6B8B3451CD95B3A631F31F9A05DAEEE5E7E4F89B64DDEBB5F63DC042CA13B8FCB8185F82AD7FD5636FFDA6B0DC9570B", - valid: true, - }, - 3: { - msg: "1234432112344321", - pubkey: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: true, - }, - 4: { - msg: "12344321123443", - pubkey: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: false, - }, - 5: { - msg: "1234432112344321", - pubkey: "459E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: false, - }, - 6: { - msg: "1234432112344321", - pubkey: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "716B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: false, - }, - } - - for i, tc := range cases { - bmsg, err := hex.DecodeString(tc.msg) - require.NoError(err, "%d", i) - - priv := NewMockKey(tc.msg, tc.pubkey, tc.sig) - pub := priv.PubKey() - sig := priv.Sign(bmsg) - - valid := pub.VerifyBytes(bmsg, sig) - assert.Equal(tc.valid, valid, "%d", i) - } -} - -func TestRealLedger(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) - - if os.Getenv("WITH_LEDGER") == "" { - t.Skip("Set WITH_LEDGER to run code on real ledger") - } - msg := []byte("kuhehfeohg") - - priv, err := NewPrivKeyLedgerEd25519() - require.Nil(err, "%+v", err) - pub := priv.PubKey() - sig := priv.Sign(msg) - - valid := pub.VerifyBytes(msg, sig) - assert.True(valid) - - // now, let's serialize the key and make sure it still works - bs := priv.Bytes() - priv2, err := crypto.PrivKeyFromBytes(bs) - require.Nil(err, "%+v", err) - - // make sure we get the same pubkey when we load from disk - pub2 := priv2.PubKey() - require.Equal(pub, pub2) - - // signing with the loaded key should match the original pubkey - sig = priv2.Sign(msg) - valid = pub.VerifyBytes(msg, sig) - assert.True(valid) - - // make sure pubkeys serialize properly as well - bs = pub.Bytes() - bpub, err := crypto.PubKeyFromBytes(bs) - require.NoError(err) - assert.Equal(pub, bpub) -} - -// TestRealLedgerErrorHandling calls. These tests assume -// the ledger is not plugged in.... -func TestRealLedgerErrorHandling(t *testing.T) { - require := rqr.New(t) - - if os.Getenv("WITH_LEDGER") != "" { - t.Skip("Skipping on WITH_LEDGER as it tests unplugged cases") - } - - // first, try to generate a key, must return an error - // (no panic) - _, err := NewPrivKeyLedgerEd25519() - require.Error(err) - - led := PrivKeyLedgerEd25519{} // empty - // or with some pub key - ed := crypto.GenPrivKeyEd25519() - led2 := PrivKeyLedgerEd25519{CachedPubKey: ed.PubKey()} - - // loading these should return errors - bs := led.Bytes() - _, err = crypto.PrivKeyFromBytes(bs) - require.Error(err) - - bs = led2.Bytes() - _, err = crypto.PrivKeyFromBytes(bs) - require.Error(err) -} diff --git a/_nano/sign.go b/_nano/sign.go deleted file mode 100644 index c40801583..000000000 --- a/_nano/sign.go +++ /dev/null @@ -1,63 +0,0 @@ -package nano - -import ( - "bytes" - "crypto/sha512" - - "github.com/pkg/errors" -) - -const ( - App = 0x80 - Init = 0x00 - Update = 0x01 - Digest = 0x02 - MaxChunk = 253 - KeyLength = 32 - SigLength = 64 -) - -var separator = []byte{0, 0xCA, 0xFE, 0} - -func generateSignRequests(payload []byte) [][]byte { - // nice one-shot - digest := []byte{App, Digest} - if len(payload) < MaxChunk { - return [][]byte{append(digest, payload...)} - } - - // large payload is multi-chunk - result := [][]byte{{App, Init}} - update := []byte{App, Update} - for len(payload) > MaxChunk { - msg := append(update, payload[:MaxChunk]...) - payload = payload[MaxChunk:] - result = append(result, msg) - } - result = append(result, append(update, payload...)) - result = append(result, digest) - return result -} - -func parseDigest(resp []byte) (key, sig []byte, err error) { - if resp[0] != App || resp[1] != Digest { - return nil, nil, errors.New("Invalid header") - } - resp = resp[2:] - if len(resp) != KeyLength+SigLength+len(separator) { - return nil, nil, errors.Errorf("Incorrect length: %d", len(resp)) - } - - key, resp = resp[:KeyLength], resp[KeyLength:] - if !bytes.Equal(separator, resp[:len(separator)]) { - return nil, nil, errors.New("Cannot find 0xCAFE") - } - - sig = resp[len(separator):] - return key, sig, nil -} - -func hashMsg(data []byte) []byte { - res := sha512.Sum512(data) - return res[:] -} diff --git a/_nano/sign_test.go b/_nano/sign_test.go deleted file mode 100644 index 18e4e0d0b..000000000 --- a/_nano/sign_test.go +++ /dev/null @@ -1,160 +0,0 @@ -package nano - -import ( - "encoding/hex" - "testing" - - "github.com/pkg/errors" - asrt "github.com/stretchr/testify/assert" - rqr "github.com/stretchr/testify/require" - - crypto "github.com/tendermint/go-crypto" -) - -func parseEdKey(data []byte) (key crypto.PubKey, err error) { - ed := crypto.PubKeyEd25519{} - if len(data) < len(ed) { - return key, errors.Errorf("Key length too short: %d", len(data)) - } - copy(ed[:], data) - return ed.Wrap(), nil -} - -func parseSig(data []byte) (key crypto.Signature, err error) { - ed := crypto.SignatureEd25519{} - if len(data) < len(ed) { - return key, errors.Errorf("Sig length too short: %d", len(data)) - } - copy(ed[:], data) - return ed.Wrap(), nil -} - -func TestParseDigest(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) - - cases := []struct { - output string - key string - sig string - valid bool - }{ - { - output: "80028E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C9300CAFE00787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400", - key: "8E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C93", - sig: "787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400", - valid: true, - }, - { - output: "800235467890876543525437890796574535467890", - key: "", - sig: "", - valid: false, - }, - } - - for i, tc := range cases { - msg, err := hex.DecodeString(tc.output) - require.Nil(err, "%d: %+v", i, err) - - lKey, lSig, err := parseDigest(msg) - if !tc.valid { - assert.NotNil(err, "%d", i) - } else if assert.Nil(err, "%d: %+v", i, err) { - key, err := hex.DecodeString(tc.key) - require.Nil(err, "%d: %+v", i, err) - sig, err := hex.DecodeString(tc.sig) - require.Nil(err, "%d: %+v", i, err) - - assert.Equal(key, lKey, "%d", i) - assert.Equal(sig, lSig, "%d", i) - } - } -} - -type cryptoCase struct { - msg string - key string - sig string - valid bool -} - -func toBytes(c cryptoCase) (msg, key, sig []byte, err error) { - msg, err = hex.DecodeString(c.msg) - if err != nil { - return - } - key, err = hex.DecodeString(c.key) - if err != nil { - return - } - sig, err = hex.DecodeString(c.sig) - return -} - -func TestCryptoConvert(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) - - cases := []cryptoCase{ - 0: { - msg: "F00D", - key: "8E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C93", - sig: "787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400", - valid: true, - }, - 1: { - msg: "DEADBEEF", - key: "0C45ADC887A5463F668533443C829ED13EA8E2E890C778957DC28DB9D2AD5A6C", - sig: "00ED74EED8FDAC7988A14BF6BC222120CBAC249D569AF4C2ADABFC86B792F97DF73C4919BE4B6B0ACB53547273BF29FBF0A9E0992FFAB6CB6C9B09311FC86A00", - valid: true, - }, - 2: { - msg: "1234567890AA", - key: "598FC1F0C76363D14D7480736DEEF390D85863360F075792A6975EFA149FD7EA", - sig: "59AAB7D7BDC4F936B6415DE672A8B77FA6B8B3451CD95B3A631F31F9A05DAEEE5E7E4F89B64DDEBB5F63DC042CA13B8FCB8185F82AD7FD5636FFDA6B0DC9570B", - valid: true, - }, - 3: { - msg: "1234432112344321", - key: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: true, - }, - 4: { - msg: "12344321123443", - key: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: false, - }, - 5: { - msg: "1234432112344321", - key: "459E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: false, - }, - 6: { - msg: "1234432112344321", - key: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "716B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: false, - }, - } - - for i, tc := range cases { - msg, key, sig, err := toBytes(tc) - require.Nil(err, "%d: %+v", i, err) - - pk, err := parseEdKey(key) - require.Nil(err, "%d: %+v", i, err) - psig, err := parseSig(sig) - require.Nil(err, "%d: %+v", i, err) - - // it is not the signature of the message itself - valid := pk.VerifyBytes(msg, psig) - assert.False(valid, "%d", i) - - // but rather of the hash of the msg - hmsg := hashMsg(msg) - valid = pk.VerifyBytes(hmsg, psig) - assert.Equal(tc.valid, valid, "%d", i) - } -} diff --git a/amino.go b/amino.go index 89636895a..2af765434 100644 --- a/amino.go +++ b/amino.go @@ -27,6 +27,8 @@ func RegisterAmino(cdc *amino.Codec) { "tendermint/PrivKeyEd25519", nil) cdc.RegisterConcrete(PrivKeySecp256k1{}, "tendermint/PrivKeySecp256k1", nil) + cdc.RegisterConcrete(PrivKeyLedgerSecp256k1{}, + "tendermint/PrivKeyLedgerSecp256k1", nil) cdc.RegisterInterface((*Signature)(nil), nil) cdc.RegisterConcrete(SignatureEd25519{}, diff --git a/ledger.go b/ledger.go new file mode 100644 index 000000000..0fe4b7d39 --- /dev/null +++ b/ledger.go @@ -0,0 +1,154 @@ +package crypto + +import ( + "github.com/pkg/errors" + + // secp256k1 "github.com/btcsuite/btcd/btcec" + ledger "github.com/zondax/ledger-goclient" +) + +var device *ledger.Ledger + +// getLedger gets a copy of the device, and caches it +func getLedger() (*ledger.Ledger, error) { + var err error + if device == nil { + device, err = ledger.FindLedger() + } + return device, err +} + +func signLedger(device *ledger.Ledger, msg []byte) (pub PubKey, sig Signature, err error) { + bsig, err := device.Sign(msg) + if err != nil { + return pub, sig, err + } + key, err := device.GetPublicKey() + if err != nil { + return pub, sig, err + } + var p PubKeySecp256k1 + copy(p[:], key) + return p, SignatureSecp256k1FromBytes(bsig), nil +} + +// PrivKeyLedgerSecp256k1 implements PrivKey, calling the ledger nano +// we cache the PubKey from the first call to use it later +type PrivKeyLedgerSecp256k1 struct { + // PubKey should be private, but we want to encode it via go-amino + // so we can view the address later, even without having the ledger + // attached + CachedPubKey PubKey +} + +// NewPrivKeyLedgerSecp256k1 will generate a new key and store the +// public key for later use. +func NewPrivKeyLedgerSecp256k1() (PrivKey, error) { + var pk PrivKeyLedgerSecp256k1 + // getPubKey will cache the pubkey for later use, + // this allows us to return an error early if the ledger + // is not plugged in + _, err := pk.getPubKey() + return &pk, err +} + +// ValidateKey allows us to verify the sanity of a key +// after loading it from disk +func (pk PrivKeyLedgerSecp256k1) ValidateKey() error { + // getPubKey will return an error if the ledger is not + // properly set up... + pub, err := pk.forceGetPubKey() + if err != nil { + return err + } + // verify this matches cached address + if !pub.Equals(pk.CachedPubKey) { + return errors.New("ledger doesn't match cached key") + } + return nil +} + +// AssertIsPrivKeyInner fulfils PrivKey Interface +func (pk *PrivKeyLedgerSecp256k1) AssertIsPrivKeyInner() {} + +// Bytes fulfils PrivKey Interface - but it stores the cached pubkey so we can verify +// the same key when we reconnect to a ledger +func (pk PrivKeyLedgerSecp256k1) Bytes() []byte { + bin, err := cdc.MarshalBinaryBare(pk) + if err != nil { + panic(err) + } + return bin +} + +// Sign calls the ledger and stores the PubKey for future use +// +// XXX/TODO: panics if there is an error communicating with the ledger. +// +// Communication is checked on NewPrivKeyLedger and PrivKeyFromBytes, +// returning an error, so this should only trigger if the privkey is held +// in memory for a while before use. +func (pk PrivKeyLedgerSecp256k1) Sign(msg []byte) Signature { + // oh, I wish there was better error handling + dev, err := getLedger() + if err != nil { + panic(err) + } + + pub, sig, err := signLedger(dev, msg) + if err != nil { + panic(err) + } + + // if we have no pubkey yet, store it for future queries + if pk.CachedPubKey == nil { + pk.CachedPubKey = pub + } else if !pk.CachedPubKey.Equals(pub) { + panic("signed with a different key than stored") + } + return sig +} + +// PubKey returns the stored PubKey +// TODO: query the ledger if not there, once it is not volatile +func (pk PrivKeyLedgerSecp256k1) PubKey() PubKey { + key, err := pk.getPubKey() + if err != nil { + panic(err) + } + return key +} + +// getPubKey reads the pubkey from cache or from the ledger itself +// since this involves IO, it may return an error, which is not exposed +// in the PubKey interface, so this function allows better error handling +func (pk PrivKeyLedgerSecp256k1) getPubKey() (key PubKey, err error) { + // if we have no pubkey, set it + if pk.CachedPubKey == nil { + pk.CachedPubKey, err = pk.forceGetPubKey() + } + return pk.CachedPubKey, err +} + +// forceGetPubKey is like getPubKey but ignores any cached key +// and ensures we get it from the ledger itself. +func (pk PrivKeyLedgerSecp256k1) forceGetPubKey() (key PubKey, err error) { + dev, err := getLedger() + if err != nil { + return key, errors.New("Can't connect to ledger device") + } + key, _, err = signLedger(dev, []byte{0}) + if err != nil { + return key, errors.New("Please open cosmos app on the ledger") + } + return key, err +} + +// Equals fulfils PrivKey Interface - makes sure both keys refer to the +// same +func (pk PrivKeyLedgerSecp256k1) Equals(other PrivKey) bool { + if ledger, ok := other.(*PrivKeyLedgerSecp256k1); ok { + return pk.CachedPubKey.Equals(ledger.CachedPubKey) + } + return false +} diff --git a/ledger_test.go b/ledger_test.go new file mode 100644 index 000000000..848c2cece --- /dev/null +++ b/ledger_test.go @@ -0,0 +1,72 @@ +package crypto + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestRealLedger(t *testing.T) { + + if os.Getenv("WITH_LEDGER") == "" { + t.Skip("Set WITH_LEDGER to run code on real ledger") + } + msg := []byte("kuhehfeohg") + + priv, err := NewPrivKeyLedgerSecp256k1() + require.Nil(t, err, "%+v", err) + pub := priv.PubKey() + sig := priv.Sign(msg) + + valid := pub.VerifyBytes(msg, sig) + assert.True(t, valid) + + // now, let's serialize the key and make sure it still works + bs := priv.Bytes() + priv2, err := PrivKeyFromBytes(bs) + require.Nil(t, err, "%+v", err) + + // make sure we get the same pubkey when we load from disk + pub2 := priv2.PubKey() + require.Equal(t, pub, pub2) + + // signing with the loaded key should match the original pubkey + sig = priv2.Sign(msg) + valid = pub.VerifyBytes(msg, sig) + assert.True(t, valid) + + // make sure pubkeys serialize properly as well + bs = pub.Bytes() + bpub, err := PubKeyFromBytes(bs) + require.NoError(t, err) + assert.Equal(t, pub, bpub) +} + +// TestRealLedgerErrorHandling calls. These tests assume +// the ledger is not plugged in.... +func TestRealLedgerErrorHandling(t *testing.T) { + if os.Getenv("WITH_LEDGER") != "" { + t.Skip("Skipping on WITH_LEDGER as it tests unplugged cases") + } + + // first, try to generate a key, must return an error + // (no panic) + _, err := NewPrivKeyLedgerSecp256k1() + require.Error(t, err) + + led := PrivKeyLedgerSecp256k1{} // empty + // or with some pub key + ed := GenPrivKeySecp256k1() + led2 := PrivKeyLedgerSecp256k1{CachedPubKey: ed.PubKey()} + + // loading these should return errors + bs := led.Bytes() + _, err = PrivKeyFromBytes(bs) + require.Error(t, err) + + bs = led2.Bytes() + _, err = PrivKeyFromBytes(bs) + require.Error(t, err) +} diff --git a/signature.go b/signature.go index cfe927137..8bf151b41 100644 --- a/signature.go +++ b/signature.go @@ -79,3 +79,9 @@ func (sig SignatureSecp256k1) Equals(other Signature) bool { return false } } + +func SignatureSecp256k1FromBytes(data []byte) Signature { + var sig SignatureSecp256k1 + copy(sig[:], data) + return sig +} From 065c3943b1918e9bcbd55ede1df3ee6392552d41 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 30 Apr 2018 16:49:11 +0200 Subject: [PATCH 227/287] Fix no-Ledger testcase --- ledger_test.go | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/ledger_test.go b/ledger_test.go index 848c2cece..7b2b4ea1e 100644 --- a/ledger_test.go +++ b/ledger_test.go @@ -55,18 +55,4 @@ func TestRealLedgerErrorHandling(t *testing.T) { // (no panic) _, err := NewPrivKeyLedgerSecp256k1() require.Error(t, err) - - led := PrivKeyLedgerSecp256k1{} // empty - // or with some pub key - ed := GenPrivKeySecp256k1() - led2 := PrivKeyLedgerSecp256k1{CachedPubKey: ed.PubKey()} - - // loading these should return errors - bs := led.Bytes() - _, err = PrivKeyFromBytes(bs) - require.Error(t, err) - - bs = led2.Bytes() - _, err = PrivKeyFromBytes(bs) - require.Error(t, err) } From e25a64fdf1e4aae53ad5e2780d0b4cc56eedaae6 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 30 Apr 2018 19:34:19 +0200 Subject: [PATCH 228/287] Fix testcases, all looks OK --- ledger.go | 9 ++++++--- signature.go | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ledger.go b/ledger.go index 0fe4b7d39..b2b06415d 100644 --- a/ledger.go +++ b/ledger.go @@ -3,7 +3,7 @@ package crypto import ( "github.com/pkg/errors" - // secp256k1 "github.com/btcsuite/btcd/btcec" + secp256k1 "github.com/btcsuite/btcd/btcec" ledger "github.com/zondax/ledger-goclient" ) @@ -23,13 +23,16 @@ func signLedger(device *ledger.Ledger, msg []byte) (pub PubKey, sig Signature, e if err != nil { return pub, sig, err } + sig = SignatureSecp256k1FromBytes(bsig) key, err := device.GetPublicKey() if err != nil { return pub, sig, err } var p PubKeySecp256k1 - copy(p[:], key) - return p, SignatureSecp256k1FromBytes(bsig), nil + // Reserialize in the 33-byte compressed format + cmp, err := secp256k1.ParsePubKey(key[:], secp256k1.S256()) + copy(p[:], cmp.SerializeCompressed()) + return p, sig, nil } // PrivKeyLedgerSecp256k1 implements PrivKey, calling the ledger nano diff --git a/signature.go b/signature.go index 8bf151b41..a364dc7fb 100644 --- a/signature.go +++ b/signature.go @@ -81,7 +81,7 @@ func (sig SignatureSecp256k1) Equals(other Signature) bool { } func SignatureSecp256k1FromBytes(data []byte) Signature { - var sig SignatureSecp256k1 + sig := make(SignatureSecp256k1, len(data)) copy(sig[:], data) return sig } From 391936b7346a116053b301fd6c74ace17eac4d75 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 2 May 2018 17:10:32 +0200 Subject: [PATCH 229/287] Prevent unnecessary signatures, improve error messages --- ledger.go | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/ledger.go b/ledger.go index b2b06415d..18fdf478e 100644 --- a/ledger.go +++ b/ledger.go @@ -18,21 +18,25 @@ func getLedger() (*ledger.Ledger, error) { return device, err } -func signLedger(device *ledger.Ledger, msg []byte) (pub PubKey, sig Signature, err error) { - bsig, err := device.Sign(msg) - if err != nil { - return pub, sig, err - } - sig = SignatureSecp256k1FromBytes(bsig) +func pubkeyLedger(device *ledger.Ledger) (pub PubKey, err error) { key, err := device.GetPublicKey() if err != nil { - return pub, sig, err + return pub, err } var p PubKeySecp256k1 // Reserialize in the 33-byte compressed format cmp, err := secp256k1.ParsePubKey(key[:], secp256k1.S256()) copy(p[:], cmp.SerializeCompressed()) - return p, sig, nil + return pub, err +} + +func signLedger(device *ledger.Ledger, msg []byte) (sig Signature, err error) { + bsig, err := device.Sign(msg) + if err != nil { + return sig, err + } + sig = SignatureSecp256k1FromBytes(bsig) + return sig, nil } // PrivKeyLedgerSecp256k1 implements PrivKey, calling the ledger nano @@ -66,7 +70,7 @@ func (pk PrivKeyLedgerSecp256k1) ValidateKey() error { } // verify this matches cached address if !pub.Equals(pk.CachedPubKey) { - return errors.New("ledger doesn't match cached key") + return errors.New("Cached key does not match retrieved key") } return nil } @@ -98,7 +102,12 @@ func (pk PrivKeyLedgerSecp256k1) Sign(msg []byte) Signature { panic(err) } - pub, sig, err := signLedger(dev, msg) + sig, err := signLedger(dev, msg) + if err != nil { + panic(err) + } + + pub, err := pubkeyLedger(dev) if err != nil { panic(err) } @@ -107,7 +116,7 @@ func (pk PrivKeyLedgerSecp256k1) Sign(msg []byte) Signature { if pk.CachedPubKey == nil { pk.CachedPubKey = pub } else if !pk.CachedPubKey.Equals(pub) { - panic("signed with a different key than stored") + panic("Stored key does not match signing key") } return sig } @@ -138,11 +147,11 @@ func (pk PrivKeyLedgerSecp256k1) getPubKey() (key PubKey, err error) { func (pk PrivKeyLedgerSecp256k1) forceGetPubKey() (key PubKey, err error) { dev, err := getLedger() if err != nil { - return key, errors.New("Can't connect to ledger device") + return key, errors.New("Cannot connect to Ledger device") } - key, _, err = signLedger(dev, []byte{0}) + key, err = pubkeyLedger(dev) if err != nil { - return key, errors.New("Please open cosmos app on the ledger") + return key, errors.New("Please open Cosmos app on the Ledger device") } return key, err } From 86b09b0cd7c3a7b6a4ce825564ede75a80d5605b Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 3 May 2018 06:26:58 +0200 Subject: [PATCH 230/287] Bugfix --- ledger.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ledger.go b/ledger.go index 18fdf478e..4effa2590 100644 --- a/ledger.go +++ b/ledger.go @@ -27,7 +27,7 @@ func pubkeyLedger(device *ledger.Ledger) (pub PubKey, err error) { // Reserialize in the 33-byte compressed format cmp, err := secp256k1.ParsePubKey(key[:], secp256k1.S256()) copy(p[:], cmp.SerializeCompressed()) - return pub, err + return p, err } func signLedger(device *ledger.Ledger, msg []byte) (sig Signature, err error) { From 49e03fb481075d3f8d601dfc73e9f34ff8edd9d6 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 10 May 2018 01:41:15 +0200 Subject: [PATCH 231/287] Update dependency versions --- Gopkg.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index fbfaa63fa..3e44587e1 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -11,7 +11,7 @@ branch = "master" name = "github.com/btcsuite/btcd" packages = ["btcec"] - revision = "2be2f12b358dc57d70b8f501b00be450192efbc3" + revision = "675abc5df3c5531bc741b56a765e35623459da6d" [[projects]] branch = "master" @@ -119,7 +119,7 @@ "leveldb/table", "leveldb/util" ] - revision = "714f901b98fdb3aa954b4193d8cbd64a28d80cad" + revision = "ae970a0732be3a1f5311da86118d37b9f4bd2a5a" [[projects]] branch = "master" @@ -134,8 +134,8 @@ [[projects]] name = "github.com/tendermint/go-amino" packages = ["."] - revision = "42246108ff925a457fb709475070a03dfd3e2b5c" - version = "0.9.6" + revision = "ed62928576cfcaf887209dc96142cd79cdfff389" + version = "0.9.9" [[projects]] name = "github.com/tendermint/tmlibs" @@ -144,8 +144,8 @@ "db", "log" ] - revision = "2e24b64fc121dcdf1cabceab8dc2f7257675483c" - version = "v0.8.1" + revision = "d94e312673e16a11ea55d742cefb3e331228f898" + version = "v0.8.2" [[projects]] branch = "master" @@ -157,7 +157,7 @@ branch = "master" name = "github.com/zondax/ledger-goclient" packages = ["."] - revision = "0eb48e14b06efd0354c2e0e18f15db121c64b9b8" + revision = "a242cfad962597a588288f99fa3425a01a820295" [[projects]] branch = "master" @@ -173,7 +173,7 @@ "ripemd160", "salsa20/salsa" ] - revision = "b2aa35443fbc700ab74c586ae79b81c171851023" + revision = "2d027ae1dddd4694d54f7a8b6cbe78dca8720226" [solve-meta] analyzer-name = "dep" From 337ad8e594d31a16449cf2756ed33ba959ea3964 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 10 May 2018 02:03:28 +0200 Subject: [PATCH 232/287] Update to new Ledger API in progress --- ledger.go | 19 +++++++++++-------- ledger_test.go | 7 +++++-- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/ledger.go b/ledger.go index 4effa2590..d44b2dab9 100644 --- a/ledger.go +++ b/ledger.go @@ -9,6 +9,8 @@ import ( var device *ledger.Ledger +type DerivationPath = []uint32 + // getLedger gets a copy of the device, and caches it func getLedger() (*ledger.Ledger, error) { var err error @@ -18,8 +20,8 @@ func getLedger() (*ledger.Ledger, error) { return device, err } -func pubkeyLedger(device *ledger.Ledger) (pub PubKey, err error) { - key, err := device.GetPublicKey() +func pubkeyLedger(device *ledger.Ledger, path DerivationPath) (pub PubKey, err error) { + key, err := device.GetPublicKeySECP256K1(path) if err != nil { return pub, err } @@ -30,8 +32,8 @@ func pubkeyLedger(device *ledger.Ledger) (pub PubKey, err error) { return p, err } -func signLedger(device *ledger.Ledger, msg []byte) (sig Signature, err error) { - bsig, err := device.Sign(msg) +func signLedger(device *ledger.Ledger, path DerivationPath, msg []byte) (sig Signature, err error) { + bsig, err := device.SignSECP256K1(path, msg) if err != nil { return sig, err } @@ -46,11 +48,12 @@ type PrivKeyLedgerSecp256k1 struct { // so we can view the address later, even without having the ledger // attached CachedPubKey PubKey + Path DerivationPath } // NewPrivKeyLedgerSecp256k1 will generate a new key and store the // public key for later use. -func NewPrivKeyLedgerSecp256k1() (PrivKey, error) { +func NewPrivKeyLedgerSecp256k1(path DerivationPath) (PrivKey, error) { var pk PrivKeyLedgerSecp256k1 // getPubKey will cache the pubkey for later use, // this allows us to return an error early if the ledger @@ -102,12 +105,12 @@ func (pk PrivKeyLedgerSecp256k1) Sign(msg []byte) Signature { panic(err) } - sig, err := signLedger(dev, msg) + sig, err := signLedger(dev, pk.Path, msg) if err != nil { panic(err) } - pub, err := pubkeyLedger(dev) + pub, err := pubkeyLedger(dev, pk.Path) if err != nil { panic(err) } @@ -149,7 +152,7 @@ func (pk PrivKeyLedgerSecp256k1) forceGetPubKey() (key PubKey, err error) { if err != nil { return key, errors.New("Cannot connect to Ledger device") } - key, err = pubkeyLedger(dev) + key, err = pubkeyLedger(dev, pk.Path) if err != nil { return key, errors.New("Please open Cosmos app on the Ledger device") } diff --git a/ledger_test.go b/ledger_test.go index 7b2b4ea1e..1c193b5f1 100644 --- a/ledger_test.go +++ b/ledger_test.go @@ -15,7 +15,9 @@ func TestRealLedger(t *testing.T) { } msg := []byte("kuhehfeohg") - priv, err := NewPrivKeyLedgerSecp256k1() + path := DerivationPath{44, 60, 0, 0, 0} + + priv, err := NewPrivKeyLedgerSecp256k1(path) require.Nil(t, err, "%+v", err) pub := priv.PubKey() sig := priv.Sign(msg) @@ -53,6 +55,7 @@ func TestRealLedgerErrorHandling(t *testing.T) { // first, try to generate a key, must return an error // (no panic) - _, err := NewPrivKeyLedgerSecp256k1() + path := DerivationPath{44, 60, 0, 0, 0} + _, err := NewPrivKeyLedgerSecp256k1(path) require.Error(t, err) } From e6d0ade0e1a8315613e026fe64b006f24f58beab Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 14 May 2018 15:33:10 +0200 Subject: [PATCH 233/287] Update to latest upstream, debugging information --- Gopkg.lock | 6 +++--- ledger.go | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 3e44587e1..d65f87b68 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -119,7 +119,7 @@ "leveldb/table", "leveldb/util" ] - revision = "ae970a0732be3a1f5311da86118d37b9f4bd2a5a" + revision = "9637fa0b2f0db13c99d899b91007edb7df4610b7" [[projects]] branch = "master" @@ -157,7 +157,7 @@ branch = "master" name = "github.com/zondax/ledger-goclient" packages = ["."] - revision = "a242cfad962597a588288f99fa3425a01a820295" + revision = "5b2fe84d3139027c29bd8f0c054ed9444f8a7622" [[projects]] branch = "master" @@ -173,7 +173,7 @@ "ripemd160", "salsa20/salsa" ] - revision = "2d027ae1dddd4694d54f7a8b6cbe78dca8720226" + revision = "034e5325b6ab92faa14d15c30e86919e911cf8e0" [solve-meta] analyzer-name = "dep" diff --git a/ledger.go b/ledger.go index d44b2dab9..a9bc1d975 100644 --- a/ledger.go +++ b/ledger.go @@ -1,6 +1,7 @@ package crypto import ( + "fmt" "github.com/pkg/errors" secp256k1 "github.com/btcsuite/btcd/btcec" @@ -23,7 +24,7 @@ func getLedger() (*ledger.Ledger, error) { func pubkeyLedger(device *ledger.Ledger, path DerivationPath) (pub PubKey, err error) { key, err := device.GetPublicKeySECP256K1(path) if err != nil { - return pub, err + return pub, fmt.Errorf("Error fetching public key: %v", err) } var p PubKeySecp256k1 // Reserialize in the 33-byte compressed format @@ -55,6 +56,7 @@ type PrivKeyLedgerSecp256k1 struct { // public key for later use. func NewPrivKeyLedgerSecp256k1(path DerivationPath) (PrivKey, error) { var pk PrivKeyLedgerSecp256k1 + pk.Path = path // getPubKey will cache the pubkey for later use, // this allows us to return an error early if the ledger // is not plugged in @@ -150,11 +152,11 @@ func (pk PrivKeyLedgerSecp256k1) getPubKey() (key PubKey, err error) { func (pk PrivKeyLedgerSecp256k1) forceGetPubKey() (key PubKey, err error) { dev, err := getLedger() if err != nil { - return key, errors.New("Cannot connect to Ledger device") + return key, errors.New(fmt.Sprintf("Cannot connect to Ledger device - error: %v", err)) } key, err = pubkeyLedger(dev, pk.Path) if err != nil { - return key, errors.New("Please open Cosmos app on the Ledger device") + return key, errors.New(fmt.Sprintf("Please open Cosmos app on the Ledger device - error: %v", err)) } return key, err } From aa2b6b546f85a625fd06f511421d36b2f579fa3e Mon Sep 17 00:00:00 2001 From: Liamsi Date: Tue, 15 May 2018 11:39:48 +0100 Subject: [PATCH 234/287] Remove outdated non-building code in _nano --- _nano/keys.go | 294 --------------------------------------------- _nano/keys_test.go | 142 ---------------------- _nano/sign.go | 63 ---------- _nano/sign_test.go | 160 ------------------------ 4 files changed, 659 deletions(-) delete mode 100644 _nano/keys.go delete mode 100644 _nano/keys_test.go delete mode 100644 _nano/sign.go delete mode 100644 _nano/sign_test.go diff --git a/_nano/keys.go b/_nano/keys.go deleted file mode 100644 index 8cf1c3721..000000000 --- a/_nano/keys.go +++ /dev/null @@ -1,294 +0,0 @@ -package nano - -import ( - "bytes" - "encoding/hex" - - "github.com/pkg/errors" - - ledger "github.com/ethanfrey/ledger" - - crypto "github.com/tendermint/go-crypto" - amino "github.com/tendermint/go-amino" -) - -//nolint -const ( - NameLedgerEd25519 = "ledger-ed25519" - TypeLedgerEd25519 = 0x10 - - // Timeout is the number of seconds to wait for a response from the ledger - // if eg. waiting for user confirmation on button push - Timeout = 20 -) - -var device *ledger.Ledger - -// getLedger gets a copy of the device, and caches it -func getLedger() (*ledger.Ledger, error) { - var err error - if device == nil { - device, err = ledger.FindLedger() - } - return device, err -} - -func signLedger(device *ledger.Ledger, msg []byte) (pub crypto.PubKey, sig crypto.Signature, err error) { - var resp []byte - - packets := generateSignRequests(msg) - for _, pack := range packets { - resp, err = device.Exchange(pack, Timeout) - if err != nil { - return pub, sig, err - } - } - - // the last call is the result we want and needs to be parsed - key, bsig, err := parseDigest(resp) - if err != nil { - return pub, sig, err - } - - var b [32]byte - copy(b[:], key) - return PubKeyLedgerEd25519FromBytes(b), crypto.SignatureEd25519FromBytes(bsig), nil -} - -// PrivKeyLedgerEd25519 implements PrivKey, calling the ledger nano -// we cache the PubKey from the first call to use it later -type PrivKeyLedgerEd25519 struct { - // PubKey should be private, but we want to encode it via go-amino - // so we can view the address later, even without having the ledger - // attached - CachedPubKey crypto.PubKey -} - -// NewPrivKeyLedgerEd25519 will generate a new key and store the -// public key for later use. -func NewPrivKeyLedgerEd25519() (crypto.PrivKey, error) { - var pk PrivKeyLedgerEd25519 - // getPubKey will cache the pubkey for later use, - // this allows us to return an error early if the ledger - // is not plugged in - _, err := pk.getPubKey() - return pk.Wrap(), err -} - -// ValidateKey allows us to verify the sanity of a key -// after loading it from disk -func (pk *PrivKeyLedgerEd25519) ValidateKey() error { - // getPubKey will return an error if the ledger is not - // properly set up... - pub, err := pk.forceGetPubKey() - if err != nil { - return err - } - // verify this matches cached address - if !pub.Equals(pk.CachedPubKey) { - return errors.New("ledger doesn't match cached key") - } - return nil -} - -// AssertIsPrivKeyInner fulfils PrivKey Interface -func (pk *PrivKeyLedgerEd25519) AssertIsPrivKeyInner() {} - -// Bytes fulfils PrivKey Interface - but it stores the cached pubkey so we can verify -// the same key when we reconnect to a ledger -func (pk *PrivKeyLedgerEd25519) Bytes() []byte { - return amino.BinaryBytes(pk.Wrap()) -} - -// Sign calls the ledger and stores the PubKey for future use -// -// XXX/TODO: panics if there is an error communicating with the ledger. -// -// Communication is checked on NewPrivKeyLedger and PrivKeyFromBytes, -// returning an error, so this should only trigger if the privkey is held -// in memory for a while before use. -func (pk *PrivKeyLedgerEd25519) Sign(msg []byte) crypto.Signature { - // oh, I wish there was better error handling - dev, err := getLedger() - if err != nil { - panic(err) - } - - pub, sig, err := signLedger(dev, msg) - if err != nil { - panic(err) - } - - // if we have no pubkey yet, store it for future queries - if pk.CachedPubKey.Empty() { - pk.CachedPubKey = pub - } else if !pk.CachedPubKey.Equals(pub) { - panic("signed with a different key than stored") - } - return sig -} - -// PubKey returns the stored PubKey -// TODO: query the ledger if not there, once it is not volatile -func (pk *PrivKeyLedgerEd25519) PubKey() crypto.PubKey { - key, err := pk.getPubKey() - if err != nil { - panic(err) - } - return key -} - -// getPubKey reads the pubkey from cache or from the ledger itself -// since this involves IO, it may return an error, which is not exposed -// in the PubKey interface, so this function allows better error handling -func (pk *PrivKeyLedgerEd25519) getPubKey() (key crypto.PubKey, err error) { - // if we have no pubkey, set it - if pk.CachedPubKey.Empty() { - pk.CachedPubKey, err = pk.forceGetPubKey() - } - return pk.CachedPubKey, err -} - -// forceGetPubKey is like getPubKey but ignores any cached key -// and ensures we get it from the ledger itself. -func (pk *PrivKeyLedgerEd25519) forceGetPubKey() (key crypto.PubKey, err error) { - dev, err := getLedger() - if err != nil { - return key, errors.New("Can't connect to ledger device") - } - key, _, err = signLedger(dev, []byte{0}) - if err != nil { - return key, errors.New("Please open cosmos app on the ledger") - } - return key, err -} - -// Equals fulfils PrivKey Interface - makes sure both keys refer to the -// same -func (pk *PrivKeyLedgerEd25519) Equals(other crypto.PrivKey) bool { - if ledger, ok := other.Unwrap().(*PrivKeyLedgerEd25519); ok { - return pk.CachedPubKey.Equals(ledger.CachedPubKey) - } - return false -} - -// MockPrivKeyLedgerEd25519 behaves as the ledger, but stores a pre-packaged call-response -// for use in test cases -type MockPrivKeyLedgerEd25519 struct { - Msg []byte - Pub [KeyLength]byte - Sig [SigLength]byte -} - -// NewMockKey returns -func NewMockKey(msg, pubkey, sig string) (pk MockPrivKeyLedgerEd25519) { - var err error - pk.Msg, err = hex.DecodeString(msg) - if err != nil { - panic(err) - } - - bpk, err := hex.DecodeString(pubkey) - if err != nil { - panic(err) - } - bsig, err := hex.DecodeString(sig) - if err != nil { - panic(err) - } - - copy(pk.Pub[:], bpk) - copy(pk.Sig[:], bsig) - return pk -} - -var _ crypto.PrivKeyInner = MockPrivKeyLedgerEd25519{} - -// AssertIsPrivKeyInner fulfils PrivKey Interface -func (pk MockPrivKeyLedgerEd25519) AssertIsPrivKeyInner() {} - -// Bytes fulfils PrivKey Interface - not supported -func (pk MockPrivKeyLedgerEd25519) Bytes() []byte { - return nil -} - -// Sign returns a real SignatureLedger, if the msg matches what we expect -func (pk MockPrivKeyLedgerEd25519) Sign(msg []byte) crypto.Signature { - if !bytes.Equal(pk.Msg, msg) { - panic("Mock key is for different msg") - } - return crypto.SignatureEd25519(pk.Sig).Wrap() -} - -// PubKey returns a real PubKeyLedgerEd25519, that will verify this signature -func (pk MockPrivKeyLedgerEd25519) PubKey() crypto.PubKey { - return PubKeyLedgerEd25519FromBytes(pk.Pub) -} - -// Equals compares that two Mocks have the same data -func (pk MockPrivKeyLedgerEd25519) Equals(other crypto.PrivKey) bool { - if mock, ok := other.Unwrap().(MockPrivKeyLedgerEd25519); ok { - return bytes.Equal(mock.Pub[:], pk.Pub[:]) && - bytes.Equal(mock.Sig[:], pk.Sig[:]) && - bytes.Equal(mock.Msg, pk.Msg) - } - return false -} - -//////////////////////////////////////////// -// pubkey - -// PubKeyLedgerEd25519 works like a normal Ed25519 except a hash before the verify bytes -type PubKeyLedgerEd25519 struct { - crypto.PubKeyEd25519 -} - -// PubKeyLedgerEd25519FromBytes creates a PubKey from the raw bytes -func PubKeyLedgerEd25519FromBytes(key [32]byte) crypto.PubKey { - return PubKeyLedgerEd25519{crypto.PubKeyEd25519(key)}.Wrap() -} - -// Bytes fulfils pk Interface - no data, just type info -func (pk PubKeyLedgerEd25519) Bytes() []byte { - return amino.BinaryBytes(pk.Wrap()) -} - -// VerifyBytes uses the normal Ed25519 algorithm but a sha512 hash beforehand -func (pk PubKeyLedgerEd25519) VerifyBytes(msg []byte, sig crypto.Signature) bool { - hmsg := hashMsg(msg) - return pk.PubKeyEd25519.VerifyBytes(hmsg, sig) -} - -// Equals implements PubKey interface -func (pk PubKeyLedgerEd25519) Equals(other crypto.PubKey) bool { - if ledger, ok := other.Unwrap().(PubKeyLedgerEd25519); ok { - return pk.PubKeyEd25519.Equals(ledger.PubKeyEd25519.Wrap()) - } - return false -} - -/*** registration with go-data ***/ - -func init() { - crypto.PrivKeyMapper. - RegisterImplementation(&PrivKeyLedgerEd25519{}, NameLedgerEd25519, TypeLedgerEd25519). - RegisterImplementation(MockPrivKeyLedgerEd25519{}, "mock-ledger", 0x11) - - crypto.PubKeyMapper. - RegisterImplementation(PubKeyLedgerEd25519{}, NameLedgerEd25519, TypeLedgerEd25519) -} - -// Wrap fulfils interface for PrivKey struct -func (pk *PrivKeyLedgerEd25519) Wrap() crypto.PrivKey { - return crypto.PrivKey{PrivKeyInner: pk} -} - -// Wrap fulfils interface for PrivKey struct -func (pk MockPrivKeyLedgerEd25519) Wrap() crypto.PrivKey { - return crypto.PrivKey{PrivKeyInner: pk} -} - -// Wrap fulfils interface for PubKey struct -func (pk PubKeyLedgerEd25519) Wrap() crypto.PubKey { - return crypto.PubKey{PubKeyInner: pk} -} diff --git a/_nano/keys_test.go b/_nano/keys_test.go deleted file mode 100644 index fda096e29..000000000 --- a/_nano/keys_test.go +++ /dev/null @@ -1,142 +0,0 @@ -package nano - -import ( - "encoding/hex" - "os" - "testing" - - asrt "github.com/stretchr/testify/assert" - rqr "github.com/stretchr/testify/require" - - crypto "github.com/tendermint/go-crypto" -) - -func TestLedgerKeys(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) - - cases := []struct { - msg, pubkey, sig string - valid bool - }{ - 0: { - msg: "F00D", - pubkey: "8E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C93", - sig: "787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400", - valid: true, - }, - 1: { - msg: "DEADBEEF", - pubkey: "0C45ADC887A5463F668533443C829ED13EA8E2E890C778957DC28DB9D2AD5A6C", - sig: "00ED74EED8FDAC7988A14BF6BC222120CBAC249D569AF4C2ADABFC86B792F97DF73C4919BE4B6B0ACB53547273BF29FBF0A9E0992FFAB6CB6C9B09311FC86A00", - valid: true, - }, - 2: { - msg: "1234567890AA", - pubkey: "598FC1F0C76363D14D7480736DEEF390D85863360F075792A6975EFA149FD7EA", - sig: "59AAB7D7BDC4F936B6415DE672A8B77FA6B8B3451CD95B3A631F31F9A05DAEEE5E7E4F89B64DDEBB5F63DC042CA13B8FCB8185F82AD7FD5636FFDA6B0DC9570B", - valid: true, - }, - 3: { - msg: "1234432112344321", - pubkey: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: true, - }, - 4: { - msg: "12344321123443", - pubkey: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: false, - }, - 5: { - msg: "1234432112344321", - pubkey: "459E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: false, - }, - 6: { - msg: "1234432112344321", - pubkey: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "716B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: false, - }, - } - - for i, tc := range cases { - bmsg, err := hex.DecodeString(tc.msg) - require.NoError(err, "%d", i) - - priv := NewMockKey(tc.msg, tc.pubkey, tc.sig) - pub := priv.PubKey() - sig := priv.Sign(bmsg) - - valid := pub.VerifyBytes(bmsg, sig) - assert.Equal(tc.valid, valid, "%d", i) - } -} - -func TestRealLedger(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) - - if os.Getenv("WITH_LEDGER") == "" { - t.Skip("Set WITH_LEDGER to run code on real ledger") - } - msg := []byte("kuhehfeohg") - - priv, err := NewPrivKeyLedgerEd25519() - require.Nil(err, "%+v", err) - pub := priv.PubKey() - sig := priv.Sign(msg) - - valid := pub.VerifyBytes(msg, sig) - assert.True(valid) - - // now, let's serialize the key and make sure it still works - bs := priv.Bytes() - priv2, err := crypto.PrivKeyFromBytes(bs) - require.Nil(err, "%+v", err) - - // make sure we get the same pubkey when we load from disk - pub2 := priv2.PubKey() - require.Equal(pub, pub2) - - // signing with the loaded key should match the original pubkey - sig = priv2.Sign(msg) - valid = pub.VerifyBytes(msg, sig) - assert.True(valid) - - // make sure pubkeys serialize properly as well - bs = pub.Bytes() - bpub, err := crypto.PubKeyFromBytes(bs) - require.NoError(err) - assert.Equal(pub, bpub) -} - -// TestRealLedgerErrorHandling calls. These tests assume -// the ledger is not plugged in.... -func TestRealLedgerErrorHandling(t *testing.T) { - require := rqr.New(t) - - if os.Getenv("WITH_LEDGER") != "" { - t.Skip("Skipping on WITH_LEDGER as it tests unplugged cases") - } - - // first, try to generate a key, must return an error - // (no panic) - _, err := NewPrivKeyLedgerEd25519() - require.Error(err) - - led := PrivKeyLedgerEd25519{} // empty - // or with some pub key - ed := crypto.GenPrivKeyEd25519() - led2 := PrivKeyLedgerEd25519{CachedPubKey: ed.PubKey()} - - // loading these should return errors - bs := led.Bytes() - _, err = crypto.PrivKeyFromBytes(bs) - require.Error(err) - - bs = led2.Bytes() - _, err = crypto.PrivKeyFromBytes(bs) - require.Error(err) -} diff --git a/_nano/sign.go b/_nano/sign.go deleted file mode 100644 index c40801583..000000000 --- a/_nano/sign.go +++ /dev/null @@ -1,63 +0,0 @@ -package nano - -import ( - "bytes" - "crypto/sha512" - - "github.com/pkg/errors" -) - -const ( - App = 0x80 - Init = 0x00 - Update = 0x01 - Digest = 0x02 - MaxChunk = 253 - KeyLength = 32 - SigLength = 64 -) - -var separator = []byte{0, 0xCA, 0xFE, 0} - -func generateSignRequests(payload []byte) [][]byte { - // nice one-shot - digest := []byte{App, Digest} - if len(payload) < MaxChunk { - return [][]byte{append(digest, payload...)} - } - - // large payload is multi-chunk - result := [][]byte{{App, Init}} - update := []byte{App, Update} - for len(payload) > MaxChunk { - msg := append(update, payload[:MaxChunk]...) - payload = payload[MaxChunk:] - result = append(result, msg) - } - result = append(result, append(update, payload...)) - result = append(result, digest) - return result -} - -func parseDigest(resp []byte) (key, sig []byte, err error) { - if resp[0] != App || resp[1] != Digest { - return nil, nil, errors.New("Invalid header") - } - resp = resp[2:] - if len(resp) != KeyLength+SigLength+len(separator) { - return nil, nil, errors.Errorf("Incorrect length: %d", len(resp)) - } - - key, resp = resp[:KeyLength], resp[KeyLength:] - if !bytes.Equal(separator, resp[:len(separator)]) { - return nil, nil, errors.New("Cannot find 0xCAFE") - } - - sig = resp[len(separator):] - return key, sig, nil -} - -func hashMsg(data []byte) []byte { - res := sha512.Sum512(data) - return res[:] -} diff --git a/_nano/sign_test.go b/_nano/sign_test.go deleted file mode 100644 index 18e4e0d0b..000000000 --- a/_nano/sign_test.go +++ /dev/null @@ -1,160 +0,0 @@ -package nano - -import ( - "encoding/hex" - "testing" - - "github.com/pkg/errors" - asrt "github.com/stretchr/testify/assert" - rqr "github.com/stretchr/testify/require" - - crypto "github.com/tendermint/go-crypto" -) - -func parseEdKey(data []byte) (key crypto.PubKey, err error) { - ed := crypto.PubKeyEd25519{} - if len(data) < len(ed) { - return key, errors.Errorf("Key length too short: %d", len(data)) - } - copy(ed[:], data) - return ed.Wrap(), nil -} - -func parseSig(data []byte) (key crypto.Signature, err error) { - ed := crypto.SignatureEd25519{} - if len(data) < len(ed) { - return key, errors.Errorf("Sig length too short: %d", len(data)) - } - copy(ed[:], data) - return ed.Wrap(), nil -} - -func TestParseDigest(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) - - cases := []struct { - output string - key string - sig string - valid bool - }{ - { - output: "80028E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C9300CAFE00787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400", - key: "8E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C93", - sig: "787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400", - valid: true, - }, - { - output: "800235467890876543525437890796574535467890", - key: "", - sig: "", - valid: false, - }, - } - - for i, tc := range cases { - msg, err := hex.DecodeString(tc.output) - require.Nil(err, "%d: %+v", i, err) - - lKey, lSig, err := parseDigest(msg) - if !tc.valid { - assert.NotNil(err, "%d", i) - } else if assert.Nil(err, "%d: %+v", i, err) { - key, err := hex.DecodeString(tc.key) - require.Nil(err, "%d: %+v", i, err) - sig, err := hex.DecodeString(tc.sig) - require.Nil(err, "%d: %+v", i, err) - - assert.Equal(key, lKey, "%d", i) - assert.Equal(sig, lSig, "%d", i) - } - } -} - -type cryptoCase struct { - msg string - key string - sig string - valid bool -} - -func toBytes(c cryptoCase) (msg, key, sig []byte, err error) { - msg, err = hex.DecodeString(c.msg) - if err != nil { - return - } - key, err = hex.DecodeString(c.key) - if err != nil { - return - } - sig, err = hex.DecodeString(c.sig) - return -} - -func TestCryptoConvert(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) - - cases := []cryptoCase{ - 0: { - msg: "F00D", - key: "8E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C93", - sig: "787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400", - valid: true, - }, - 1: { - msg: "DEADBEEF", - key: "0C45ADC887A5463F668533443C829ED13EA8E2E890C778957DC28DB9D2AD5A6C", - sig: "00ED74EED8FDAC7988A14BF6BC222120CBAC249D569AF4C2ADABFC86B792F97DF73C4919BE4B6B0ACB53547273BF29FBF0A9E0992FFAB6CB6C9B09311FC86A00", - valid: true, - }, - 2: { - msg: "1234567890AA", - key: "598FC1F0C76363D14D7480736DEEF390D85863360F075792A6975EFA149FD7EA", - sig: "59AAB7D7BDC4F936B6415DE672A8B77FA6B8B3451CD95B3A631F31F9A05DAEEE5E7E4F89B64DDEBB5F63DC042CA13B8FCB8185F82AD7FD5636FFDA6B0DC9570B", - valid: true, - }, - 3: { - msg: "1234432112344321", - key: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: true, - }, - 4: { - msg: "12344321123443", - key: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: false, - }, - 5: { - msg: "1234432112344321", - key: "459E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: false, - }, - 6: { - msg: "1234432112344321", - key: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120", - sig: "716B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208", - valid: false, - }, - } - - for i, tc := range cases { - msg, key, sig, err := toBytes(tc) - require.Nil(err, "%d: %+v", i, err) - - pk, err := parseEdKey(key) - require.Nil(err, "%d: %+v", i, err) - psig, err := parseSig(sig) - require.Nil(err, "%d: %+v", i, err) - - // it is not the signature of the message itself - valid := pk.VerifyBytes(msg, psig) - assert.False(valid, "%d", i) - - // but rather of the hash of the msg - hmsg := hashMsg(msg) - valid = pk.VerifyBytes(hmsg, psig) - assert.Equal(tc.valid, valid, "%d", i) - } -} From 91361407192ed45b390c9d111e87fe5b54c6281b Mon Sep 17 00:00:00 2001 From: Liamsi Date: Tue, 15 May 2018 12:07:05 +0100 Subject: [PATCH 235/287] get rid of go-bindata dependency in Makefile; hardcode its output instead --- Makefile | 18 +++++++++--------- keys/words/wordlist/wordlist.go | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 9ae475983..68fb8344c 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,8 @@ GOTOOLS = \ github.com/golang/dep/cmd/dep \ - github.com/jteeuwen/go-bindata/go-bindata # gopkg.in/alecthomas/gometalinter.v2 \ - # -GOTOOLS_CHECK = dep go-bindata #gometalinter.v2 + +GOTOOLS_CHECK = dep #gometalinter.v2 all: check get_vendor_deps build test install @@ -13,12 +12,13 @@ check: check_tools ######################################## ### Build -wordlist: - # Generating wordlist.go... - go-bindata -ignore ".*\.go" -o keys/words/wordlist/wordlist.go -pkg "wordlist" keys/words/wordlist/... +# Command to generate the workd list (kept here for documentation purposes only): +# wordlist: + # Generating wordlist.go ... + # go-bindata -ignore ".*\.go" -o keys/words/wordlist/wordlist.go -pkg "wordlist" keys/words/wordlist/... -build: wordlist - # Nothing else to build! +#build: wordlist +# # Nothing else to build! install: # Nothing to install! @@ -96,4 +96,4 @@ metalinter_all: # To avoid unintended conflicts with file names, always add to .PHONY # unless there is a reason not to. # https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html -.PHONEY: check wordlist build install check_tools get_tools update_tools get_vendor_deps test fmt metalinter metalinter_all +.PHONEY: check build install check_tools get_tools update_tools get_vendor_deps test fmt metalinter metalinter_all diff --git a/keys/words/wordlist/wordlist.go b/keys/words/wordlist/wordlist.go index 4efff82cb..9ffbb1539 100644 --- a/keys/words/wordlist/wordlist.go +++ b/keys/words/wordlist/wordlist.go @@ -86,7 +86,7 @@ func keysWordsWordlistChinese_simplifiedTxt() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/words/wordlist/chinese_simplified.txt", size: 8192, mode: os.FileMode(420), modTime: time.Unix(1514928181, 0)} + info := bindataFileInfo{name: "keys/words/wordlist/chinese_simplified.txt", size: 8192, mode: os.FileMode(420), modTime: time.Unix(1523115814, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -106,7 +106,7 @@ func keysWordsWordlistEnglishTxt() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/words/wordlist/english.txt", size: 13116, mode: os.FileMode(420), modTime: time.Unix(1514928181, 0)} + info := bindataFileInfo{name: "keys/words/wordlist/english.txt", size: 13116, mode: os.FileMode(420), modTime: time.Unix(1523115814, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -126,7 +126,7 @@ func keysWordsWordlistJapaneseTxt() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/words/wordlist/japanese.txt", size: 24287, mode: os.FileMode(420), modTime: time.Unix(1514928181, 0)} + info := bindataFileInfo{name: "keys/words/wordlist/japanese.txt", size: 24287, mode: os.FileMode(420), modTime: time.Unix(1523115814, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -146,7 +146,7 @@ func keysWordsWordlistSpanishTxt() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/words/wordlist/spanish.txt", size: 13659, mode: os.FileMode(420), modTime: time.Unix(1514928181, 0)} + info := bindataFileInfo{name: "keys/words/wordlist/spanish.txt", size: 13659, mode: os.FileMode(420), modTime: time.Unix(1523115814, 0)} a := &asset{bytes: bytes, info: info} return a, nil } From 3fe985e289f12955161effd2fa4cb0988dc1445c Mon Sep 17 00:00:00 2001 From: Liamsi Date: Tue, 15 May 2018 12:23:33 +0100 Subject: [PATCH 236/287] fix makefile --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 68fb8344c..74af29941 100644 --- a/Makefile +++ b/Makefile @@ -13,12 +13,12 @@ check: check_tools ### Build # Command to generate the workd list (kept here for documentation purposes only): -# wordlist: - # Generating wordlist.go ... +wordlist: + # To re-generate wordlist.go run: # go-bindata -ignore ".*\.go" -o keys/words/wordlist/wordlist.go -pkg "wordlist" keys/words/wordlist/... -#build: wordlist -# # Nothing else to build! +build: wordlist + # Nothing else to build! install: # Nothing to install! From 8423f6ef5a7fd29bd76636cc16702911d246b4b1 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Mon, 21 May 2018 20:45:36 -0700 Subject: [PATCH 237/287] Add the libsodium test vector --- xchacha20poly1035/xchachapoly.go | 8 +-- xchacha20poly1035/xchachapoly_test.go | 91 +++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 xchacha20poly1035/xchachapoly_test.go diff --git a/xchacha20poly1035/xchachapoly.go b/xchacha20poly1035/xchachapoly.go index b9d823414..96413b8c1 100644 --- a/xchacha20poly1035/xchachapoly.go +++ b/xchacha20poly1035/xchachapoly.go @@ -41,11 +41,11 @@ func (c *xchacha20poly1305) Overhead() int { func (c *xchacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte { if len(nonce) != NonceSize { - panic("chacha20poly1305: bad nonce length passed to Seal") + panic("xchacha20poly1305: bad nonce length passed to Seal") } if uint64(len(plaintext)) > (1<<38)-64 { - panic("chacha20poly1305: plaintext too large") + panic("xchacha20poly1305: plaintext too large") } var subKey [KeySize]byte @@ -64,10 +64,10 @@ func (c *xchacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) [ func (c *xchacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { if len(nonce) != NonceSize { - panic("chacha20poly1305: bad nonce length passed to Open") + panic("xchacha20poly1305: bad nonce length passed to Open") } if uint64(len(ciphertext)) > (1<<38)-48 { - panic("chacha20poly1305: ciphertext too large") + panic("xchacha20poly1305: ciphertext too large") } var subKey [KeySize]byte var hNonce [16]byte diff --git a/xchacha20poly1035/xchachapoly_test.go b/xchacha20poly1035/xchachapoly_test.go new file mode 100644 index 000000000..5e522e0b1 --- /dev/null +++ b/xchacha20poly1035/xchachapoly_test.go @@ -0,0 +1,91 @@ +package xchacha20poly1305 + +import ( + "bytes" + "encoding/hex" + "testing" +) + +func toHex(bits []byte) string { + return hex.EncodeToString(bits) +} + +func fromHex(bits string) []byte { + b, err := hex.DecodeString(bits) + if err != nil { + panic(err) + } + return b +} + +func TestHChaCha20(t *testing.T) { + for i, v := range hChaCha20Vectors { + var key [32]byte + var nonce [16]byte + copy(key[:], v.key) + copy(nonce[:], v.nonce) + + HChaCha20(&key, &nonce, &key) + if !bytes.Equal(key[:], v.keystream) { + t.Errorf("Test %d: keystream mismatch:\n \t got: %s\n \t want: %s", i, toHex(key[:]), toHex(v.keystream)) + } + } +} + +var hChaCha20Vectors = []struct { + key, nonce, keystream []byte +}{ + { + fromHex("0000000000000000000000000000000000000000000000000000000000000000"), + fromHex("000000000000000000000000000000000000000000000000"), + fromHex("1140704c328d1d5d0e30086cdf209dbd6a43b8f41518a11cc387b669b2ee6586"), + }, + { + fromHex("8000000000000000000000000000000000000000000000000000000000000000"), + fromHex("000000000000000000000000000000000000000000000000"), + fromHex("7d266a7fd808cae4c02a0a70dcbfbcc250dae65ce3eae7fc210f54cc8f77df86"), + }, + { + fromHex("0000000000000000000000000000000000000000000000000000000000000001"), + fromHex("000000000000000000000000000000000000000000000002"), + fromHex("e0c77ff931bb9163a5460c02ac281c2b53d792b1c43fea817e9ad275ae546963"), + }, + { + fromHex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), + fromHex("000102030405060708090a0b0c0d0e0f1011121314151617"), + fromHex("51e3ff45a895675c4b33b46c64f4a9ace110d34df6a2ceab486372bacbd3eff6"), + }, +} + +func TestVectors(t *testing.T) { + for i, v := range vectors { + if len(v.plaintext) == 0 { + v.plaintext = make([]byte, len(v.ciphertext)) + } + + var nonce [24]byte + copy(nonce[:], v.nonce) + + aead, err := New(v.key) + if err != nil { + t.Error(err) + } + + dst := aead.Seal(nil, nonce[:], v.plaintext, v.ad) + if !bytes.Equal(dst, v.ciphertext) { + t.Errorf("Test %d: ciphertext mismatch:\n \t got: %s\n \t want: %s", i, toHex(dst), toHex(v.ciphertext)) + } + } +} + +var vectors = []struct { + key, nonce, ad, plaintext, ciphertext []byte +}{ + { + []byte{0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f}, + []byte{0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b}, + []byte{0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7}, + []byte("Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."), + []byte{0x45, 0x3c, 0x06, 0x93, 0xa7, 0x40, 0x7f, 0x04, 0xff, 0x4c, 0x56, 0xae, 0xdb, 0x17, 0xa3, 0xc0, 0xa1, 0xaf, 0xff, 0x01, 0x17, 0x49, 0x30, 0xfc, 0x22, 0x28, 0x7c, 0x33, 0xdb, 0xcf, 0x0a, 0xc8, 0xb8, 0x9a, 0xd9, 0x29, 0x53, 0x0a, 0x1b, 0xb3, 0xab, 0x5e, 0x69, 0xf2, 0x4c, 0x7f, 0x60, 0x70, 0xc8, 0xf8, 0x40, 0xc9, 0xab, 0xb4, 0xf6, 0x9f, 0xbf, 0xc8, 0xa7, 0xff, 0x51, 0x26, 0xfa, 0xee, 0xbb, 0xb5, 0x58, 0x05, 0xee, 0x9c, 0x1c, 0xf2, 0xce, 0x5a, 0x57, 0x26, 0x32, 0x87, 0xae, 0xc5, 0x78, 0x0f, 0x04, 0xec, 0x32, 0x4c, 0x35, 0x14, 0x12, 0x2c, 0xfc, 0x32, 0x31, 0xfc, 0x1a, 0x8b, 0x71, 0x8a, 0x62, 0x86, 0x37, 0x30, 0xa2, 0x70, 0x2b, 0xb7, 0x63, 0x66, 0x11, 0x6b, 0xed, 0x09, 0xe0, 0xfd, 0x5c, 0x6d, 0x84, 0xb6, 0xb0, 0xc1, 0xab, 0xaf, 0x24, 0x9d, 0x5d, 0xd0, 0xf7, 0xf5, 0xa7, 0xea}, + }, +} From 134fdf716930c308ac9f6cd3a80f55ee57f40254 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 22 May 2018 12:43:44 -0400 Subject: [PATCH 238/287] bring in merkle from tmlibs --- merkle/README.md | 4 ++ merkle/simple_map.go | 84 ++++++++++++++++++++++ merkle/simple_map_test.go | 53 ++++++++++++++ merkle/simple_proof.go | 144 +++++++++++++++++++++++++++++++++++++ merkle/simple_tree.go | 91 +++++++++++++++++++++++ merkle/simple_tree_test.go | 87 ++++++++++++++++++++++ merkle/types.go | 47 ++++++++++++ 7 files changed, 510 insertions(+) create mode 100644 merkle/README.md create mode 100644 merkle/simple_map.go create mode 100644 merkle/simple_map_test.go create mode 100644 merkle/simple_proof.go create mode 100644 merkle/simple_tree.go create mode 100644 merkle/simple_tree_test.go create mode 100644 merkle/types.go diff --git a/merkle/README.md b/merkle/README.md new file mode 100644 index 000000000..c44978368 --- /dev/null +++ b/merkle/README.md @@ -0,0 +1,4 @@ +## Simple Merkle Tree + +For smaller static data structures that don't require immutable snapshots or mutability; +for instance the transactions and validation signatures of a block can be hashed using this simple merkle tree logic. diff --git a/merkle/simple_map.go b/merkle/simple_map.go new file mode 100644 index 000000000..cd38de761 --- /dev/null +++ b/merkle/simple_map.go @@ -0,0 +1,84 @@ +package merkle + +import ( + cmn "github.com/tendermint/tmlibs/common" + "golang.org/x/crypto/ripemd160" +) + +type SimpleMap struct { + kvs cmn.KVPairs + sorted bool +} + +func NewSimpleMap() *SimpleMap { + return &SimpleMap{ + kvs: nil, + sorted: false, + } +} + +func (sm *SimpleMap) Set(key string, value Hasher) { + sm.sorted = false + + // Hash the key to blind it... why not? + khash := SimpleHashFromBytes([]byte(key)) + + // And the value is hashed too, so you can + // check for equality with a cached value (say) + // and make a determination to fetch or not. + vhash := value.Hash() + + sm.kvs = append(sm.kvs, cmn.KVPair{ + Key: khash, + Value: vhash, + }) +} + +// Merkle root hash of items sorted by key +// (UNSTABLE: and by value too if duplicate key). +func (sm *SimpleMap) Hash() []byte { + sm.Sort() + return hashKVPairs(sm.kvs) +} + +func (sm *SimpleMap) Sort() { + if sm.sorted { + return + } + sm.kvs.Sort() + sm.sorted = true +} + +// Returns a copy of sorted KVPairs. +func (sm *SimpleMap) KVPairs() cmn.KVPairs { + sm.Sort() + kvs := make(cmn.KVPairs, len(sm.kvs)) + copy(kvs, sm.kvs) + return kvs +} + +//---------------------------------------- + +// A local extension to KVPair that can be hashed. +type KVPair cmn.KVPair + +func (kv KVPair) Hash() []byte { + hasher := ripemd160.New() + err := encodeByteSlice(hasher, kv.Key) + if err != nil { + panic(err) + } + err = encodeByteSlice(hasher, kv.Value) + if err != nil { + panic(err) + } + return hasher.Sum(nil) +} + +func hashKVPairs(kvs cmn.KVPairs) []byte { + kvsH := make([]Hasher, 0, len(kvs)) + for _, kvp := range kvs { + kvsH = append(kvsH, KVPair(kvp)) + } + return SimpleHashFromHashers(kvsH) +} diff --git a/merkle/simple_map_test.go b/merkle/simple_map_test.go new file mode 100644 index 000000000..c9c871354 --- /dev/null +++ b/merkle/simple_map_test.go @@ -0,0 +1,53 @@ +package merkle + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +type strHasher string + +func (str strHasher) Hash() []byte { + return SimpleHashFromBytes([]byte(str)) +} + +func TestSimpleMap(t *testing.T) { + { + db := NewSimpleMap() + db.Set("key1", strHasher("value1")) + assert.Equal(t, "acdb4f121bc6f25041eb263ab463f1cd79236a32", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + } + { + db := NewSimpleMap() + db.Set("key1", strHasher("value2")) + assert.Equal(t, "b8cbf5adee8c524e14f531da9b49adbbbd66fffa", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + } + { + db := NewSimpleMap() + db.Set("key1", strHasher("value1")) + db.Set("key2", strHasher("value2")) + assert.Equal(t, "1708aabc85bbe00242d3db8c299516aa54e48c38", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + } + { + db := NewSimpleMap() + db.Set("key2", strHasher("value2")) // NOTE: out of order + db.Set("key1", strHasher("value1")) + assert.Equal(t, "1708aabc85bbe00242d3db8c299516aa54e48c38", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + } + { + db := NewSimpleMap() + db.Set("key1", strHasher("value1")) + db.Set("key2", strHasher("value2")) + db.Set("key3", strHasher("value3")) + assert.Equal(t, "e728afe72ce351eed6aca65c5f78da19b9a6e214", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + } + { + db := NewSimpleMap() + db.Set("key2", strHasher("value2")) // NOTE: out of order + db.Set("key1", strHasher("value1")) + db.Set("key3", strHasher("value3")) + assert.Equal(t, "e728afe72ce351eed6aca65c5f78da19b9a6e214", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + } +} diff --git a/merkle/simple_proof.go b/merkle/simple_proof.go new file mode 100644 index 000000000..ca6ccf372 --- /dev/null +++ b/merkle/simple_proof.go @@ -0,0 +1,144 @@ +package merkle + +import ( + "bytes" + "fmt" +) + +type SimpleProof struct { + Aunts [][]byte `json:"aunts"` // Hashes from leaf's sibling to a root's child. +} + +// proofs[0] is the proof for items[0]. +func SimpleProofsFromHashers(items []Hasher) (rootHash []byte, proofs []*SimpleProof) { + trails, rootSPN := trailsFromHashers(items) + rootHash = rootSPN.Hash + proofs = make([]*SimpleProof, len(items)) + for i, trail := range trails { + proofs[i] = &SimpleProof{ + Aunts: trail.FlattenAunts(), + } + } + return +} + +func SimpleProofsFromMap(m map[string]Hasher) (rootHash []byte, proofs []*SimpleProof) { + sm := NewSimpleMap() + for k, v := range m { + sm.Set(k, v) + } + sm.Sort() + kvs := sm.kvs + kvsH := make([]Hasher, 0, len(kvs)) + for _, kvp := range kvs { + kvsH = append(kvsH, KVPair(kvp)) + } + return SimpleProofsFromHashers(kvsH) +} + +// Verify that leafHash is a leaf hash of the simple-merkle-tree +// which hashes to rootHash. +func (sp *SimpleProof) Verify(index int, total int, leafHash []byte, rootHash []byte) bool { + computedHash := computeHashFromAunts(index, total, leafHash, sp.Aunts) + return computedHash != nil && bytes.Equal(computedHash, rootHash) +} + +func (sp *SimpleProof) String() string { + return sp.StringIndented("") +} + +func (sp *SimpleProof) StringIndented(indent string) string { + return fmt.Sprintf(`SimpleProof{ +%s Aunts: %X +%s}`, + indent, sp.Aunts, + indent) +} + +// Use the leafHash and innerHashes to get the root merkle hash. +// If the length of the innerHashes slice isn't exactly correct, the result is nil. +// Recursive impl. +func computeHashFromAunts(index int, total int, leafHash []byte, innerHashes [][]byte) []byte { + if index >= total || index < 0 || total <= 0 { + return nil + } + switch total { + case 0: + panic("Cannot call computeHashFromAunts() with 0 total") + case 1: + if len(innerHashes) != 0 { + return nil + } + return leafHash + default: + if len(innerHashes) == 0 { + return nil + } + numLeft := (total + 1) / 2 + if index < numLeft { + leftHash := computeHashFromAunts(index, numLeft, leafHash, innerHashes[:len(innerHashes)-1]) + if leftHash == nil { + return nil + } + return SimpleHashFromTwoHashes(leftHash, innerHashes[len(innerHashes)-1]) + } + rightHash := computeHashFromAunts(index-numLeft, total-numLeft, leafHash, innerHashes[:len(innerHashes)-1]) + if rightHash == nil { + return nil + } + return SimpleHashFromTwoHashes(innerHashes[len(innerHashes)-1], rightHash) + } +} + +// Helper structure to construct merkle proof. +// The node and the tree is thrown away afterwards. +// Exactly one of node.Left and node.Right is nil, unless node is the root, in which case both are nil. +// node.Parent.Hash = hash(node.Hash, node.Right.Hash) or +// hash(node.Left.Hash, node.Hash), depending on whether node is a left/right child. +type SimpleProofNode struct { + Hash []byte + Parent *SimpleProofNode + Left *SimpleProofNode // Left sibling (only one of Left,Right is set) + Right *SimpleProofNode // Right sibling (only one of Left,Right is set) +} + +// Starting from a leaf SimpleProofNode, FlattenAunts() will return +// the inner hashes for the item corresponding to the leaf. +func (spn *SimpleProofNode) FlattenAunts() [][]byte { + // Nonrecursive impl. + innerHashes := [][]byte{} + for spn != nil { + if spn.Left != nil { + innerHashes = append(innerHashes, spn.Left.Hash) + } else if spn.Right != nil { + innerHashes = append(innerHashes, spn.Right.Hash) + } else { + break + } + spn = spn.Parent + } + return innerHashes +} + +// trails[0].Hash is the leaf hash for items[0]. +// trails[i].Parent.Parent....Parent == root for all i. +func trailsFromHashers(items []Hasher) (trails []*SimpleProofNode, root *SimpleProofNode) { + // Recursive impl. + switch len(items) { + case 0: + return nil, nil + case 1: + trail := &SimpleProofNode{items[0].Hash(), nil, nil, nil} + return []*SimpleProofNode{trail}, trail + default: + lefts, leftRoot := trailsFromHashers(items[:(len(items)+1)/2]) + rights, rightRoot := trailsFromHashers(items[(len(items)+1)/2:]) + rootHash := SimpleHashFromTwoHashes(leftRoot.Hash, rightRoot.Hash) + root := &SimpleProofNode{rootHash, nil, nil, nil} + leftRoot.Parent = root + leftRoot.Right = rightRoot + rightRoot.Parent = root + rightRoot.Left = leftRoot + return append(lefts, rights...), root + } +} diff --git a/merkle/simple_tree.go b/merkle/simple_tree.go new file mode 100644 index 000000000..9bdf52cb2 --- /dev/null +++ b/merkle/simple_tree.go @@ -0,0 +1,91 @@ +/* +Computes a deterministic minimal height merkle tree hash. +If the number of items is not a power of two, some leaves +will be at different levels. Tries to keep both sides of +the tree the same size, but the left may be one greater. + +Use this for short deterministic trees, such as the validator list. +For larger datasets, use IAVLTree. + + * + / \ + / \ + / \ + / \ + * * + / \ / \ + / \ / \ + / \ / \ + * * * h6 + / \ / \ / \ + h0 h1 h2 h3 h4 h5 + +*/ + +package merkle + +import ( + "golang.org/x/crypto/ripemd160" +) + +func SimpleHashFromTwoHashes(left []byte, right []byte) []byte { + var hasher = ripemd160.New() + err := encodeByteSlice(hasher, left) + if err != nil { + panic(err) + } + err = encodeByteSlice(hasher, right) + if err != nil { + panic(err) + } + return hasher.Sum(nil) +} + +func SimpleHashFromHashes(hashes [][]byte) []byte { + // Recursive impl. + switch len(hashes) { + case 0: + return nil + case 1: + return hashes[0] + default: + left := SimpleHashFromHashes(hashes[:(len(hashes)+1)/2]) + right := SimpleHashFromHashes(hashes[(len(hashes)+1)/2:]) + return SimpleHashFromTwoHashes(left, right) + } +} + +// NOTE: Do not implement this, use SimpleHashFromByteslices instead. +// type Byteser interface { Bytes() []byte } +// func SimpleHashFromBytesers(items []Byteser) []byte { ... } + +func SimpleHashFromByteslices(bzs [][]byte) []byte { + hashes := make([][]byte, len(bzs)) + for i, bz := range bzs { + hashes[i] = SimpleHashFromBytes(bz) + } + return SimpleHashFromHashes(hashes) +} + +func SimpleHashFromBytes(bz []byte) []byte { + hasher := ripemd160.New() + hasher.Write(bz) + return hasher.Sum(nil) +} + +func SimpleHashFromHashers(items []Hasher) []byte { + hashes := make([][]byte, len(items)) + for i, item := range items { + hash := item.Hash() + hashes[i] = hash + } + return SimpleHashFromHashes(hashes) +} + +func SimpleHashFromMap(m map[string]Hasher) []byte { + sm := NewSimpleMap() + for k, v := range m { + sm.Set(k, v) + } + return sm.Hash() +} diff --git a/merkle/simple_tree_test.go b/merkle/simple_tree_test.go new file mode 100644 index 000000000..8c4ed01f8 --- /dev/null +++ b/merkle/simple_tree_test.go @@ -0,0 +1,87 @@ +package merkle + +import ( + "bytes" + + cmn "github.com/tendermint/tmlibs/common" + . "github.com/tendermint/tmlibs/test" + + "testing" +) + +type testItem []byte + +func (tI testItem) Hash() []byte { + return []byte(tI) +} + +func TestSimpleProof(t *testing.T) { + + total := 100 + + items := make([]Hasher, total) + for i := 0; i < total; i++ { + items[i] = testItem(cmn.RandBytes(32)) + } + + rootHash := SimpleHashFromHashers(items) + + rootHash2, proofs := SimpleProofsFromHashers(items) + + if !bytes.Equal(rootHash, rootHash2) { + t.Errorf("Unmatched root hashes: %X vs %X", rootHash, rootHash2) + } + + // For each item, check the trail. + for i, item := range items { + itemHash := item.Hash() + proof := proofs[i] + + // Verify success + ok := proof.Verify(i, total, itemHash, rootHash) + if !ok { + t.Errorf("Verification failed for index %v.", i) + } + + // Wrong item index should make it fail + { + ok = proof.Verify((i+1)%total, total, itemHash, rootHash) + if ok { + t.Errorf("Expected verification to fail for wrong index %v.", i) + } + } + + // Trail too long should make it fail + origAunts := proof.Aunts + proof.Aunts = append(proof.Aunts, cmn.RandBytes(32)) + { + ok = proof.Verify(i, total, itemHash, rootHash) + if ok { + t.Errorf("Expected verification to fail for wrong trail length.") + } + } + proof.Aunts = origAunts + + // Trail too short should make it fail + proof.Aunts = proof.Aunts[0 : len(proof.Aunts)-1] + { + ok = proof.Verify(i, total, itemHash, rootHash) + if ok { + t.Errorf("Expected verification to fail for wrong trail length.") + } + } + proof.Aunts = origAunts + + // Mutating the itemHash should make it fail. + ok = proof.Verify(i, total, MutateByteSlice(itemHash), rootHash) + if ok { + t.Errorf("Expected verification to fail for mutated leaf hash") + } + + // Mutating the rootHash should make it fail. + ok = proof.Verify(i, total, itemHash, MutateByteSlice(rootHash)) + if ok { + t.Errorf("Expected verification to fail for mutated root hash") + } + } +} diff --git a/merkle/types.go b/merkle/types.go new file mode 100644 index 000000000..a0c491a7e --- /dev/null +++ b/merkle/types.go @@ -0,0 +1,47 @@ +package merkle + +import ( + "encoding/binary" + "io" +) + +type Tree interface { + Size() (size int) + Height() (height int8) + Has(key []byte) (has bool) + Proof(key []byte) (value []byte, proof []byte, exists bool) // TODO make it return an index + Get(key []byte) (index int, value []byte, exists bool) + GetByIndex(index int) (key []byte, value []byte) + Set(key []byte, value []byte) (updated bool) + Remove(key []byte) (value []byte, removed bool) + HashWithCount() (hash []byte, count int) + Hash() (hash []byte) + Save() (hash []byte) + Load(hash []byte) + Copy() Tree + Iterate(func(key []byte, value []byte) (stop bool)) (stopped bool) + IterateRange(start []byte, end []byte, ascending bool, fx func(key []byte, value []byte) (stop bool)) (stopped bool) +} + +type Hasher interface { + Hash() []byte +} + +//----------------------------------------------------------------------- +// NOTE: these are duplicated from go-amino so we dont need go-amino as a dep + +func encodeByteSlice(w io.Writer, bz []byte) (err error) { + err = encodeUvarint(w, uint64(len(bz))) + if err != nil { + return + } + _, err = w.Write(bz) + return +} + +func encodeUvarint(w io.Writer, i uint64) (err error) { + var buf [10]byte + n := binary.PutUvarint(buf[:], i) + _, err = w.Write(buf[0:n]) + return +} From 4663ffdf087b571e5ccbc0df5ec6a6b8ad36cce1 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 22 May 2018 12:46:15 -0400 Subject: [PATCH 239/287] add tmhash --- merkle/simple_map.go | 4 ++-- merkle/simple_map_test.go | 12 ++++++------ merkle/simple_tree.go | 6 +++--- tmhash/hash.go | 41 +++++++++++++++++++++++++++++++++++++++ tmhash/hash_test.go | 23 ++++++++++++++++++++++ 5 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 tmhash/hash.go create mode 100644 tmhash/hash_test.go diff --git a/merkle/simple_map.go b/merkle/simple_map.go index cd38de761..41d1ccd56 100644 --- a/merkle/simple_map.go +++ b/merkle/simple_map.go @@ -2,7 +2,7 @@ package merkle import ( cmn "github.com/tendermint/tmlibs/common" - "golang.org/x/crypto/ripemd160" + "github.com/tendermint/go-crypto/tmhash" ) type SimpleMap struct { @@ -63,7 +63,7 @@ func (sm *SimpleMap) KVPairs() cmn.KVPairs { type KVPair cmn.KVPair func (kv KVPair) Hash() []byte { - hasher := ripemd160.New() + hasher := tmhash.New() err := encodeByteSlice(hasher, kv.Key) if err != nil { panic(err) diff --git a/merkle/simple_map_test.go b/merkle/simple_map_test.go index c9c871354..6e1004db2 100644 --- a/merkle/simple_map_test.go +++ b/merkle/simple_map_test.go @@ -17,37 +17,37 @@ func TestSimpleMap(t *testing.T) { { db := NewSimpleMap() db.Set("key1", strHasher("value1")) - assert.Equal(t, "acdb4f121bc6f25041eb263ab463f1cd79236a32", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + assert.Equal(t, "3dafc06a52039d029be57c75c9d16356a4256ef4", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } { db := NewSimpleMap() db.Set("key1", strHasher("value2")) - assert.Equal(t, "b8cbf5adee8c524e14f531da9b49adbbbd66fffa", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + assert.Equal(t, "03eb5cfdff646bc4e80fec844e72fd248a1c6b2c", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } { db := NewSimpleMap() db.Set("key1", strHasher("value1")) db.Set("key2", strHasher("value2")) - assert.Equal(t, "1708aabc85bbe00242d3db8c299516aa54e48c38", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + assert.Equal(t, "acc3971eab8513171cc90ce8b74f368c38f9657d", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } { db := NewSimpleMap() db.Set("key2", strHasher("value2")) // NOTE: out of order db.Set("key1", strHasher("value1")) - assert.Equal(t, "1708aabc85bbe00242d3db8c299516aa54e48c38", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + assert.Equal(t, "acc3971eab8513171cc90ce8b74f368c38f9657d", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } { db := NewSimpleMap() db.Set("key1", strHasher("value1")) db.Set("key2", strHasher("value2")) db.Set("key3", strHasher("value3")) - assert.Equal(t, "e728afe72ce351eed6aca65c5f78da19b9a6e214", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + assert.Equal(t, "0cd117ad14e6cd22edcd9aa0d84d7063b54b862f", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } { db := NewSimpleMap() db.Set("key2", strHasher("value2")) // NOTE: out of order db.Set("key1", strHasher("value1")) db.Set("key3", strHasher("value3")) - assert.Equal(t, "e728afe72ce351eed6aca65c5f78da19b9a6e214", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + assert.Equal(t, "0cd117ad14e6cd22edcd9aa0d84d7063b54b862f", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } } diff --git a/merkle/simple_tree.go b/merkle/simple_tree.go index 9bdf52cb2..3c31b1337 100644 --- a/merkle/simple_tree.go +++ b/merkle/simple_tree.go @@ -25,11 +25,11 @@ For larger datasets, use IAVLTree. package merkle import ( - "golang.org/x/crypto/ripemd160" + "github.com/tendermint/go-crypto/tmhash" ) func SimpleHashFromTwoHashes(left []byte, right []byte) []byte { - var hasher = ripemd160.New() + var hasher = tmhash.New() err := encodeByteSlice(hasher, left) if err != nil { panic(err) @@ -68,7 +68,7 @@ func SimpleHashFromByteslices(bzs [][]byte) []byte { } func SimpleHashFromBytes(bz []byte) []byte { - hasher := ripemd160.New() + hasher := tmhash.New() hasher.Write(bz) return hasher.Sum(nil) } diff --git a/tmhash/hash.go b/tmhash/hash.go new file mode 100644 index 000000000..de69c406f --- /dev/null +++ b/tmhash/hash.go @@ -0,0 +1,41 @@ +package tmhash + +import ( + "crypto/sha256" + "hash" +) + +var ( + Size = 20 + BlockSize = sha256.BlockSize +) + +type sha256trunc struct { + sha256 hash.Hash +} + +func (h sha256trunc) Write(p []byte) (n int, err error) { + return h.sha256.Write(p) +} +func (h sha256trunc) Sum(b []byte) []byte { + shasum := h.sha256.Sum(b) + return shasum[:Size] +} + +func (h sha256trunc) Reset() { + h.sha256.Reset() +} + +func (h sha256trunc) Size() int { + return Size +} + +func (h sha256trunc) BlockSize() int { + return h.sha256.BlockSize() +} + +func New() hash.Hash { + return sha256trunc{ + sha256: sha256.New(), + } +} diff --git a/tmhash/hash_test.go b/tmhash/hash_test.go new file mode 100644 index 000000000..abf0247ab --- /dev/null +++ b/tmhash/hash_test.go @@ -0,0 +1,23 @@ +package tmhash_test + +import ( + "crypto/sha256" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/tendermint/go-crypto/tmhash" +) + +func TestHash(t *testing.T) { + testVector := []byte("abc") + hasher := tmhash.New() + hasher.Write(testVector) + bz := hasher.Sum(nil) + + hasher = sha256.New() + hasher.Write(testVector) + bz2 := hasher.Sum(nil) + bz2 = bz2[:20] + + assert.Equal(t, bz, bz2) +} From c2636c3c6b95cc314e6a7ddc079daf236a9a1a5a Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 22 May 2018 13:04:42 -0400 Subject: [PATCH 240/287] tmhash: add Sum function --- tmhash/hash.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tmhash/hash.go b/tmhash/hash.go index de69c406f..9f684ce01 100644 --- a/tmhash/hash.go +++ b/tmhash/hash.go @@ -34,8 +34,15 @@ func (h sha256trunc) BlockSize() int { return h.sha256.BlockSize() } +// New returns a new hash.Hash. func New() hash.Hash { return sha256trunc{ sha256: sha256.New(), } } + +// Sum returns the first 20 bytes of SHA256 of the bz. +func Sum(bz []byte) []byte { + hash := sha256.Sum256(bz) + return hash[:Size] +} From 384f1e399afb23a30f01e629145c82afb3498664 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Wed, 23 May 2018 23:54:26 +0200 Subject: [PATCH 241/287] Fixed the directory name and added a test vector --- {xchacha20poly1035 => xchacha20poly1305}/xchachapoly.go | 0 {xchacha20poly1035 => xchacha20poly1305}/xchachapoly_test.go | 5 +++++ 2 files changed, 5 insertions(+) rename {xchacha20poly1035 => xchacha20poly1305}/xchachapoly.go (100%) rename {xchacha20poly1035 => xchacha20poly1305}/xchachapoly_test.go (94%) diff --git a/xchacha20poly1035/xchachapoly.go b/xchacha20poly1305/xchachapoly.go similarity index 100% rename from xchacha20poly1035/xchachapoly.go rename to xchacha20poly1305/xchachapoly.go diff --git a/xchacha20poly1035/xchachapoly_test.go b/xchacha20poly1305/xchachapoly_test.go similarity index 94% rename from xchacha20poly1035/xchachapoly_test.go rename to xchacha20poly1305/xchachapoly_test.go index 5e522e0b1..460b90ab4 100644 --- a/xchacha20poly1035/xchachapoly_test.go +++ b/xchacha20poly1305/xchachapoly_test.go @@ -55,6 +55,11 @@ var hChaCha20Vectors = []struct { fromHex("000102030405060708090a0b0c0d0e0f1011121314151617"), fromHex("51e3ff45a895675c4b33b46c64f4a9ace110d34df6a2ceab486372bacbd3eff6"), }, + { + fromHex("24f11cce8a1b3d61e441561a696c1c1b7e173d084fd4812425435a8896a013dc"), + fromHex("d9660c5900ae19ddad28d6e06e45fe5e"), + fromHex("5966b3eec3bff1189f831f06afe4d4e3be97fa9235ec8c20d08acfbbb4e851e3"), + }, } func TestVectors(t *testing.T) { From 05a5294e528161ca7192295a9397d0d8e8adea63 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Thu, 24 May 2018 00:12:54 +0200 Subject: [PATCH 242/287] Remove panic and check the round trip --- xchacha20poly1305/xchachapoly.go | 5 +++-- xchacha20poly1305/xchachapoly_test.go | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/xchacha20poly1305/xchachapoly.go b/xchacha20poly1305/xchachapoly.go index 96413b8c1..9e0778579 100644 --- a/xchacha20poly1305/xchachapoly.go +++ b/xchacha20poly1305/xchachapoly.go @@ -4,6 +4,7 @@ import ( "crypto/cipher" "encoding/binary" "errors" + "fmt" "golang.org/x/crypto/chacha20poly1305" ) @@ -64,10 +65,10 @@ func (c *xchacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) [ func (c *xchacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { if len(nonce) != NonceSize { - panic("xchacha20poly1305: bad nonce length passed to Open") + return nil, fmt.Errorf("xchacha20poly1305: bad nonce length passed to Open") } if uint64(len(ciphertext)) > (1<<38)-48 { - panic("xchacha20poly1305: ciphertext too large") + return nil, fmt.Errorf("xchacha20poly1305: ciphertext too large") } var subKey [KeySize]byte var hNonce [16]byte diff --git a/xchacha20poly1305/xchachapoly_test.go b/xchacha20poly1305/xchachapoly_test.go index 460b90ab4..3001217f4 100644 --- a/xchacha20poly1305/xchachapoly_test.go +++ b/xchacha20poly1305/xchachapoly_test.go @@ -80,6 +80,13 @@ func TestVectors(t *testing.T) { if !bytes.Equal(dst, v.ciphertext) { t.Errorf("Test %d: ciphertext mismatch:\n \t got: %s\n \t want: %s", i, toHex(dst), toHex(v.ciphertext)) } + open, err := aead.Open(nil, nonce[:], dst, v.ad) + if err != nil { + t.Error(err) + } + if !bytes.Equal(open, v.plaintext) { + t.Errorf("Test %d: plaintext mismatch:\n \t got: %s\n \t want: %s", i, string(open), string(v.plaintext)) + } } } From 707d27c11e34f87fda4c2d5623f6e0a6b15d2d14 Mon Sep 17 00:00:00 2001 From: vrde Date: Thu, 24 May 2018 16:57:37 +0200 Subject: [PATCH 243/287] Fix dead link in README.md (#106) * Fix dead link in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4a524c014..be087e045 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ go-crypto is the cryptographic package adapted for Tendermint's uses ## Binary encoding -For Binary encoding, please refer to the [Tendermint encoding spec](https://github.com/tendermint/tendermint/blob/develop/docs/specification/new-spec/encoding.md). +For Binary encoding, please refer to the [Tendermint encoding spec](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/encoding.md). ## JSON Encoding From e534559bdc88e0cdbecaf41bc0023f3fb57c9785 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 30 May 2018 01:39:50 +0200 Subject: [PATCH 244/287] Update upstream Ledger code --- Gopkg.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index d65f87b68..332714ee4 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -11,13 +11,13 @@ branch = "master" name = "github.com/btcsuite/btcd" packages = ["btcec"] - revision = "675abc5df3c5531bc741b56a765e35623459da6d" + revision = "bc0944904505aab55e089371a892be2f87883161" [[projects]] branch = "master" name = "github.com/btcsuite/btcutil" packages = ["base58"] - revision = "501929d3d046174c3d39f0ea54ece471aa17238c" + revision = "d4cc87b860166d00d6b5b9e0d3b3d71d6088d4d4" [[projects]] name = "github.com/davecgh/go-spew" @@ -61,7 +61,7 @@ branch = "master" name = "github.com/golang/snappy" packages = ["."] - revision = "553a641470496b2327abcac10b36396bd98e45c9" + revision = "2e65f85255dbc3072edf28d6b5b8efc472979f5a" [[projects]] branch = "master" @@ -119,7 +119,7 @@ "leveldb/table", "leveldb/util" ] - revision = "9637fa0b2f0db13c99d899b91007edb7df4610b7" + revision = "5d6fca44a948d2be89a9702de7717f0168403d3d" [[projects]] branch = "master" @@ -134,8 +134,8 @@ [[projects]] name = "github.com/tendermint/go-amino" packages = ["."] - revision = "ed62928576cfcaf887209dc96142cd79cdfff389" - version = "0.9.9" + revision = "3c22a7a539411f89a96738fcfa14c1027e24e5ec" + version = "0.9.10" [[projects]] name = "github.com/tendermint/tmlibs" @@ -144,8 +144,8 @@ "db", "log" ] - revision = "d94e312673e16a11ea55d742cefb3e331228f898" - version = "v0.8.2" + revision = "d970af87248a4e162590300dbb74e102183a417d" + version = "v0.8.3" [[projects]] branch = "master" @@ -157,7 +157,7 @@ branch = "master" name = "github.com/zondax/ledger-goclient" packages = ["."] - revision = "5b2fe84d3139027c29bd8f0c054ed9444f8a7622" + revision = "3e2146609cdb97894c064d59e9d00accd8c2b1dd" [[projects]] branch = "master" @@ -173,7 +173,7 @@ "ripemd160", "salsa20/salsa" ] - revision = "034e5325b6ab92faa14d15c30e86919e911cf8e0" + revision = "ab813273cd59e1333f7ae7bff5d027d4aadf528c" [solve-meta] analyzer-name = "dep" From 3186dc4cef541ab8f4a7bd107b2894b1186a601a Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 30 May 2018 03:29:42 +0200 Subject: [PATCH 245/287] Clarify function names --- ledger.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ledger.go b/ledger.go index a9bc1d975..5b681cda8 100644 --- a/ledger.go +++ b/ledger.go @@ -21,7 +21,7 @@ func getLedger() (*ledger.Ledger, error) { return device, err } -func pubkeyLedger(device *ledger.Ledger, path DerivationPath) (pub PubKey, err error) { +func pubkeyLedgerSecp256k1(device *ledger.Ledger, path DerivationPath) (pub PubKey, err error) { key, err := device.GetPublicKeySECP256K1(path) if err != nil { return pub, fmt.Errorf("Error fetching public key: %v", err) @@ -33,7 +33,7 @@ func pubkeyLedger(device *ledger.Ledger, path DerivationPath) (pub PubKey, err e return p, err } -func signLedger(device *ledger.Ledger, path DerivationPath, msg []byte) (sig Signature, err error) { +func signLedgerSecp256k1(device *ledger.Ledger, path DerivationPath, msg []byte) (sig Signature, err error) { bsig, err := device.SignSECP256K1(path, msg) if err != nil { return sig, err @@ -107,12 +107,12 @@ func (pk PrivKeyLedgerSecp256k1) Sign(msg []byte) Signature { panic(err) } - sig, err := signLedger(dev, pk.Path, msg) + sig, err := signLedgerSecp256k1(dev, pk.Path, msg) if err != nil { panic(err) } - pub, err := pubkeyLedger(dev, pk.Path) + pub, err := pubkeyLedgerSecp256k1(dev, pk.Path) if err != nil { panic(err) } @@ -154,7 +154,7 @@ func (pk PrivKeyLedgerSecp256k1) forceGetPubKey() (key PubKey, err error) { if err != nil { return key, errors.New(fmt.Sprintf("Cannot connect to Ledger device - error: %v", err)) } - key, err = pubkeyLedger(dev, pk.Path) + key, err = pubkeyLedgerSecp256k1(dev, pk.Path) if err != nil { return key, errors.New(fmt.Sprintf("Please open Cosmos app on the Ledger device - error: %v", err)) } From ee411daa1778470e93f6cbc634c22ded60e40ea6 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 30 May 2018 03:42:47 +0200 Subject: [PATCH 246/287] Add ed25519, tests will fail until ed25519 verification fix --- ledger_common.go | 19 ++++ ledger_ed25519.go | 156 +++++++++++++++++++++++++++++++ ledger.go => ledger_secp256k1.go | 13 --- ledger_test.go | 40 +++++++- 4 files changed, 214 insertions(+), 14 deletions(-) create mode 100644 ledger_common.go create mode 100644 ledger_ed25519.go rename ledger.go => ledger_secp256k1.go (94%) diff --git a/ledger_common.go b/ledger_common.go new file mode 100644 index 000000000..39f15464a --- /dev/null +++ b/ledger_common.go @@ -0,0 +1,19 @@ +package crypto + +import ( + ledger "github.com/zondax/ledger-goclient" +) + +var device *ledger.Ledger + +// Ledger derivation path +type DerivationPath = []uint32 + +// getLedger gets a copy of the device, and caches it +func getLedger() (*ledger.Ledger, error) { + var err error + if device == nil { + device, err = ledger.FindLedger() + } + return device, err +} diff --git a/ledger_ed25519.go b/ledger_ed25519.go new file mode 100644 index 000000000..0c9cd157f --- /dev/null +++ b/ledger_ed25519.go @@ -0,0 +1,156 @@ +package crypto + +import ( + "fmt" + "github.com/pkg/errors" + + // "github.com/tendermint/ed25519" + ledger "github.com/zondax/ledger-goclient" +) + +func pubkeyLedgerEd25519(device *ledger.Ledger, path DerivationPath) (pub PubKey, err error) { + key, err := device.GetPublicKeyED25519(path) + if err != nil { + return pub, fmt.Errorf("Error fetching public key: %v", err) + } + var p PubKeyEd25519 + copy(p[:], key[0:32]) + return p, err +} + +func signLedgerEd25519(device *ledger.Ledger, path DerivationPath, msg []byte) (sig Signature, err error) { + bsig, err := device.SignED25519(path, msg) + if err != nil { + return sig, err + } + sig = SignatureEd25519FromBytes(bsig) + return sig, nil +} + +// PrivKeyLedgerEd25519 implements PrivKey, calling the ledger nano +// we cache the PubKey from the first call to use it later +type PrivKeyLedgerEd25519 struct { + // PubKey should be private, but we want to encode it via go-amino + // so we can view the address later, even without having the ledger + // attached + CachedPubKey PubKey + Path DerivationPath +} + +// NewPrivKeyLedgerEd25519 will generate a new key and store the +// public key for later use. +func NewPrivKeyLedgerEd25519(path DerivationPath) (PrivKey, error) { + var pk PrivKeyLedgerEd25519 + pk.Path = path + // getPubKey will cache the pubkey for later use, + // this allows us to return an error early if the ledger + // is not plugged in + _, err := pk.getPubKey() + return &pk, err +} + +// ValidateKey allows us to verify the sanity of a key +// after loading it from disk +func (pk PrivKeyLedgerEd25519) ValidateKey() error { + // getPubKey will return an error if the ledger is not + // properly set up... + pub, err := pk.forceGetPubKey() + if err != nil { + return err + } + // verify this matches cached address + if !pub.Equals(pk.CachedPubKey) { + return errors.New("Cached key does not match retrieved key") + } + return nil +} + +// AssertIsPrivKeyInner fulfils PrivKey Interface +func (pk *PrivKeyLedgerEd25519) AssertIsPrivKeyInner() {} + +// Bytes fulfils PrivKey Interface - but it stores the cached pubkey so we can verify +// the same key when we reconnect to a ledger +func (pk PrivKeyLedgerEd25519) Bytes() []byte { + bin, err := cdc.MarshalBinaryBare(pk) + if err != nil { + panic(err) + } + return bin +} + +// Sign calls the ledger and stores the PubKey for future use +// +// XXX/TODO: panics if there is an error communicating with the ledger. +// +// Communication is checked on NewPrivKeyLedger and PrivKeyFromBytes, +// returning an error, so this should only trigger if the privkey is held +// in memory for a while before use. +func (pk PrivKeyLedgerEd25519) Sign(msg []byte) Signature { + // oh, I wish there was better error handling + dev, err := getLedger() + if err != nil { + panic(err) + } + + sig, err := signLedgerEd25519(dev, pk.Path, msg) + if err != nil { + panic(err) + } + + pub, err := pubkeyLedgerEd25519(dev, pk.Path) + if err != nil { + panic(err) + } + + // if we have no pubkey yet, store it for future queries + if pk.CachedPubKey == nil { + pk.CachedPubKey = pub + } else if !pk.CachedPubKey.Equals(pub) { + panic("Stored key does not match signing key") + } + return sig +} + +// PubKey returns the stored PubKey +// TODO: query the ledger if not there, once it is not volatile +func (pk PrivKeyLedgerEd25519) PubKey() PubKey { + key, err := pk.getPubKey() + if err != nil { + panic(err) + } + return key +} + +// getPubKey reads the pubkey from cache or from the ledger itself +// since this involves IO, it may return an error, which is not exposed +// in the PubKey interface, so this function allows better error handling +func (pk PrivKeyLedgerEd25519) getPubKey() (key PubKey, err error) { + // if we have no pubkey, set it + if pk.CachedPubKey == nil { + pk.CachedPubKey, err = pk.forceGetPubKey() + } + return pk.CachedPubKey, err +} + +// forceGetPubKey is like getPubKey but ignores any cached key +// and ensures we get it from the ledger itself. +func (pk PrivKeyLedgerEd25519) forceGetPubKey() (key PubKey, err error) { + dev, err := getLedger() + if err != nil { + return key, errors.New(fmt.Sprintf("Cannot connect to Ledger device - error: %v", err)) + } + key, err = pubkeyLedgerEd25519(dev, pk.Path) + if err != nil { + return key, errors.New(fmt.Sprintf("Please open Cosmos app on the Ledger device - error: %v", err)) + } + return key, err +} + +// Equals fulfils PrivKey Interface - makes sure both keys refer to the +// same +func (pk PrivKeyLedgerEd25519) Equals(other PrivKey) bool { + if ledger, ok := other.(*PrivKeyLedgerEd25519); ok { + return pk.CachedPubKey.Equals(ledger.CachedPubKey) + } + return false +} diff --git a/ledger.go b/ledger_secp256k1.go similarity index 94% rename from ledger.go rename to ledger_secp256k1.go index 5b681cda8..b574035d4 100644 --- a/ledger.go +++ b/ledger_secp256k1.go @@ -8,19 +8,6 @@ import ( ledger "github.com/zondax/ledger-goclient" ) -var device *ledger.Ledger - -type DerivationPath = []uint32 - -// getLedger gets a copy of the device, and caches it -func getLedger() (*ledger.Ledger, error) { - var err error - if device == nil { - device, err = ledger.FindLedger() - } - return device, err -} - func pubkeyLedgerSecp256k1(device *ledger.Ledger, path DerivationPath) (pub PubKey, err error) { key, err := device.GetPublicKeySECP256K1(path) if err != nil { diff --git a/ledger_test.go b/ledger_test.go index 1c193b5f1..a0ea35837 100644 --- a/ledger_test.go +++ b/ledger_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" ) -func TestRealLedger(t *testing.T) { +func TestRealLedgerSecp256k1(t *testing.T) { if os.Getenv("WITH_LEDGER") == "" { t.Skip("Set WITH_LEDGER to run code on real ledger") @@ -46,6 +46,44 @@ func TestRealLedger(t *testing.T) { assert.Equal(t, pub, bpub) } +func TestRealLedgerEd25519(t *testing.T) { + + if os.Getenv("WITH_LEDGER") == "" { + t.Skip("Set WITH_LEDGER to run code on real ledger") + } + msg := []byte("kuhehfeohg") + + path := DerivationPath{44, 60, 0, 0, 0} + + priv, err := NewPrivKeyLedgerEd25519(path) + require.Nil(t, err, "%+v", err) + pub := priv.PubKey() + sig := priv.Sign(msg) + + valid := pub.VerifyBytes(msg, sig) + assert.True(t, valid) + + // now, let's serialize the key and make sure it still works + bs := priv.Bytes() + priv2, err := PrivKeyFromBytes(bs) + require.Nil(t, err, "%+v", err) + + // make sure we get the same pubkey when we load from disk + pub2 := priv2.PubKey() + require.Equal(t, pub, pub2) + + // signing with the loaded key should match the original pubkey + sig = priv2.Sign(msg) + valid = pub.VerifyBytes(msg, sig) + assert.True(t, valid) + + // make sure pubkeys serialize properly as well + bs = pub.Bytes() + bpub, err := PubKeyFromBytes(bs) + require.NoError(t, err) + assert.Equal(t, pub, bpub) +} + // TestRealLedgerErrorHandling calls. These tests assume // the ledger is not plugged in.... func TestRealLedgerErrorHandling(t *testing.T) { From c689f38cb587be1d4681c19e7ebea7ec8e35794e Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 30 May 2018 22:07:20 +0200 Subject: [PATCH 247/287] Implement PubKeyLedgerEd25519 --- amino.go | 4 +++ ledger_ed25519.go | 2 +- ledger_pub_key.go | 68 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 ledger_pub_key.go diff --git a/amino.go b/amino.go index 2af765434..b78a15ed9 100644 --- a/amino.go +++ b/amino.go @@ -19,6 +19,8 @@ func RegisterAmino(cdc *amino.Codec) { cdc.RegisterInterface((*PubKey)(nil), nil) cdc.RegisterConcrete(PubKeyEd25519{}, "tendermint/PubKeyEd25519", nil) + cdc.RegisterConcrete(PubKeyLedgerEd25519{}, + "tendermint/PubKeyLedgerEd25519", nil) cdc.RegisterConcrete(PubKeySecp256k1{}, "tendermint/PubKeySecp256k1", nil) @@ -29,6 +31,8 @@ func RegisterAmino(cdc *amino.Codec) { "tendermint/PrivKeySecp256k1", nil) cdc.RegisterConcrete(PrivKeyLedgerSecp256k1{}, "tendermint/PrivKeyLedgerSecp256k1", nil) + cdc.RegisterConcrete(PrivKeyLedgerEd25519{}, + "tendermint/PrivKeyLedgerEd25519", nil) cdc.RegisterInterface((*Signature)(nil), nil) cdc.RegisterConcrete(SignatureEd25519{}, diff --git a/ledger_ed25519.go b/ledger_ed25519.go index 0c9cd157f..2110b8871 100644 --- a/ledger_ed25519.go +++ b/ledger_ed25519.go @@ -13,7 +13,7 @@ func pubkeyLedgerEd25519(device *ledger.Ledger, path DerivationPath) (pub PubKey if err != nil { return pub, fmt.Errorf("Error fetching public key: %v", err) } - var p PubKeyEd25519 + var p PubKeyLedgerEd25519 copy(p[:], key[0:32]) return p, err } diff --git a/ledger_pub_key.go b/ledger_pub_key.go new file mode 100644 index 000000000..0a5222577 --- /dev/null +++ b/ledger_pub_key.go @@ -0,0 +1,68 @@ +package crypto + +import ( + "bytes" + "crypto/sha512" + "fmt" + + "github.com/tendermint/ed25519" + "github.com/tendermint/ed25519/extra25519" + "golang.org/x/crypto/ripemd160" +) + +var _ PubKey = PubKeyLedgerEd25519{} + +// Implements PubKeyInner +type PubKeyLedgerEd25519 [32]byte + +func (pubKey PubKeyLedgerEd25519) Address() Address { + // append type byte + hasher := ripemd160.New() + hasher.Write(pubKey.Bytes()) // does not error + return Address(hasher.Sum(nil)) +} + +func (pubKey PubKeyLedgerEd25519) Bytes() []byte { + bz, err := cdc.MarshalBinaryBare(pubKey) + if err != nil { + panic(err) + } + return bz +} + +func (pubKey PubKeyLedgerEd25519) VerifyBytes(msg []byte, sig_ Signature) bool { + // must verify sha512 hash of msg, no padding, for Ledger compatibility + sig, ok := sig_.(SignatureEd25519) + if !ok { + return false + } + pubKeyBytes := [32]byte(pubKey) + sigBytes := [64]byte(sig) + h := sha512.New() + h.Write(msg) + digest := h.Sum(nil) + return ed25519.Verify(&pubKeyBytes, digest, &sigBytes) +} + +// For use with golang/crypto/nacl/box +// If error, returns nil. +func (pubKey PubKeyLedgerEd25519) ToCurve25519() *[32]byte { + keyCurve25519, pubKeyBytes := new([32]byte), [32]byte(pubKey) + ok := extra25519.PublicKeyToCurve25519(keyCurve25519, &pubKeyBytes) + if !ok { + return nil + } + return keyCurve25519 +} + +func (pubKey PubKeyLedgerEd25519) String() string { + return fmt.Sprintf("PubKeyLedgerEd25519{%X}", pubKey[:]) +} + +func (pubKey PubKeyLedgerEd25519) Equals(other PubKey) bool { + if otherEd, ok := other.(PubKeyLedgerEd25519); ok { + return bytes.Equal(pubKey[:], otherEd[:]) + } else { + return false + } +} From bb81e4aa5f88218d5b2c478e133909908a5619b4 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 30 May 2018 22:16:30 +0200 Subject: [PATCH 248/287] Pin to an upstream revision --- Gopkg.lock | 3 +-- Gopkg.toml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 332714ee4..2090ac2e3 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -154,7 +154,6 @@ revision = "8e7a99b3e716f36d3b080a9a70f9eb45abe4edcc" [[projects]] - branch = "master" name = "github.com/zondax/ledger-goclient" packages = ["."] revision = "3e2146609cdb97894c064d59e9d00accd8c2b1dd" @@ -178,6 +177,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "f3cfb54414cb9d59bab79226c7778673e7ac5b7a464baf9b2ea76c1f2563631e" + inputs-digest = "365c3bca75ced49eb0ebcdc5c98fd47b534850684fcc94c16d1bc6a671116395" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 3737ec5f9..10931a1a6 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -59,7 +59,7 @@ [[constraint]] name = "github.com/zondax/ledger-goclient" - branch = "master" + revision = "3e2146609cdb97894c064d59e9d00accd8c2b1dd" [prune] go-tests = true From 9f04935caa0ba104421c5c856bae92d5307e3869 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 22 May 2018 13:05:27 -0400 Subject: [PATCH 249/287] merkle: remove unused funcs. unexport simplemap. improv docs --- merkle/simple_map.go | 44 ++++++++++-------- merkle/simple_map_test.go | 17 ++++--- merkle/simple_proof.go | 18 ++++++-- merkle/simple_tree.go | 93 ++++++++++++-------------------------- merkle/simple_tree_test.go | 3 +- merkle/types.go | 2 + tmhash/hash.go | 2 +- 7 files changed, 84 insertions(+), 95 deletions(-) diff --git a/merkle/simple_map.go b/merkle/simple_map.go index 41d1ccd56..b073ecdd6 100644 --- a/merkle/simple_map.go +++ b/merkle/simple_map.go @@ -5,23 +5,27 @@ import ( "github.com/tendermint/go-crypto/tmhash" ) -type SimpleMap struct { +// Merkle tree from a map. +// Leaves are `hash(key) | hash(value)`. +// Leaves are sorted before Merkle hashing. +type simpleMap struct { kvs cmn.KVPairs sorted bool } -func NewSimpleMap() *SimpleMap { - return &SimpleMap{ +func newSimpleMap() *simpleMap { + return &simpleMap{ kvs: nil, sorted: false, } } -func (sm *SimpleMap) Set(key string, value Hasher) { +// Set hashes the key and value and appends it to the kv pairs. +func (sm *simpleMap) Set(key string, value Hasher) { sm.sorted = false // Hash the key to blind it... why not? - khash := SimpleHashFromBytes([]byte(key)) + khash := tmhash.Sum([]byte(key)) // And the value is hashed too, so you can // check for equality with a cached value (say) @@ -34,14 +38,14 @@ func (sm *SimpleMap) Set(key string, value Hasher) { }) } -// Merkle root hash of items sorted by key +// Hash Merkle root hash of items sorted by key // (UNSTABLE: and by value too if duplicate key). -func (sm *SimpleMap) Hash() []byte { +func (sm *simpleMap) Hash() []byte { sm.Sort() return hashKVPairs(sm.kvs) } -func (sm *SimpleMap) Sort() { +func (sm *simpleMap) Sort() { if sm.sorted { return } @@ -50,7 +54,8 @@ func (sm *SimpleMap) Sort() { } // Returns a copy of sorted KVPairs. -func (sm *SimpleMap) KVPairs() cmn.KVPairs { +// NOTE these contain the hashed key and value. +func (sm *simpleMap) KVPairs() cmn.KVPairs { sm.Sort() kvs := make(cmn.KVPairs, len(sm.kvs)) copy(kvs, sm.kvs) @@ -60,25 +65,28 @@ func (sm *SimpleMap) KVPairs() cmn.KVPairs { //---------------------------------------- // A local extension to KVPair that can be hashed. -type KVPair cmn.KVPair +// XXX: key and value do not need to already be hashed - +// the kvpair ("abc", "def") would not give the same result +// as ("ab", "cdef") as we're using length-prefixing. +type kvPair cmn.KVPair -func (kv KVPair) Hash() []byte { +func (kv kvPair) Hash() []byte { hasher := tmhash.New() err := encodeByteSlice(hasher, kv.Key) if err != nil { - panic(err) - } + panic(err) + } err = encodeByteSlice(hasher, kv.Value) if err != nil { - panic(err) - } + panic(err) + } return hasher.Sum(nil) } func hashKVPairs(kvs cmn.KVPairs) []byte { - kvsH := make([]Hasher, 0, len(kvs)) - for _, kvp := range kvs { - kvsH = append(kvsH, KVPair(kvp)) + kvsH := make([]Hasher, len(kvs)) + for i, kvp := range kvs { + kvsH[i] = kvPair(kvp) } return SimpleHashFromHashers(kvsH) } diff --git a/merkle/simple_map_test.go b/merkle/simple_map_test.go index 6e1004db2..9d0c25a2a 100644 --- a/merkle/simple_map_test.go +++ b/merkle/simple_map_test.go @@ -5,46 +5,49 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/tendermint/go-crypto/tmhash" ) type strHasher string func (str strHasher) Hash() []byte { - return SimpleHashFromBytes([]byte(str)) + h := tmhash.New() + h.Write([]byte(str)) + return h.Sum(nil) } func TestSimpleMap(t *testing.T) { { - db := NewSimpleMap() + db := newSimpleMap() db.Set("key1", strHasher("value1")) assert.Equal(t, "3dafc06a52039d029be57c75c9d16356a4256ef4", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } { - db := NewSimpleMap() + db := newSimpleMap() db.Set("key1", strHasher("value2")) assert.Equal(t, "03eb5cfdff646bc4e80fec844e72fd248a1c6b2c", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } { - db := NewSimpleMap() + db := newSimpleMap() db.Set("key1", strHasher("value1")) db.Set("key2", strHasher("value2")) assert.Equal(t, "acc3971eab8513171cc90ce8b74f368c38f9657d", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } { - db := NewSimpleMap() + db := newSimpleMap() db.Set("key2", strHasher("value2")) // NOTE: out of order db.Set("key1", strHasher("value1")) assert.Equal(t, "acc3971eab8513171cc90ce8b74f368c38f9657d", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } { - db := NewSimpleMap() + db := newSimpleMap() db.Set("key1", strHasher("value1")) db.Set("key2", strHasher("value2")) db.Set("key3", strHasher("value3")) assert.Equal(t, "0cd117ad14e6cd22edcd9aa0d84d7063b54b862f", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } { - db := NewSimpleMap() + db := newSimpleMap() db.Set("key2", strHasher("value2")) // NOTE: out of order db.Set("key1", strHasher("value1")) db.Set("key3", strHasher("value3")) diff --git a/merkle/simple_proof.go b/merkle/simple_proof.go index ca6ccf372..f52d1ad9f 100644 --- a/merkle/simple_proof.go +++ b/merkle/simple_proof.go @@ -5,10 +5,12 @@ import ( "fmt" ) +// SimpleProof represents a simple merkle proof. type SimpleProof struct { Aunts [][]byte `json:"aunts"` // Hashes from leaf's sibling to a root's child. } +// SimpleProofsFromHashers computes inclusion proof for given items. // proofs[0] is the proof for items[0]. func SimpleProofsFromHashers(items []Hasher) (rootHash []byte, proofs []*SimpleProof) { trails, rootSPN := trailsFromHashers(items) @@ -22,8 +24,11 @@ func SimpleProofsFromHashers(items []Hasher) (rootHash []byte, proofs []*SimpleP return } +// SimpleProofsFromMap generates proofs from a map. The keys/values of the map will be used as the keys/values +// in the underlying key-value pairs. +// The keys are sorted before the proofs are computed. func SimpleProofsFromMap(m map[string]Hasher) (rootHash []byte, proofs []*SimpleProof) { - sm := NewSimpleMap() + sm := newSimpleMap() for k, v := range m { sm.Set(k, v) } @@ -31,7 +36,7 @@ func SimpleProofsFromMap(m map[string]Hasher) (rootHash []byte, proofs []*Simple kvs := sm.kvs kvsH := make([]Hasher, 0, len(kvs)) for _, kvp := range kvs { - kvsH = append(kvsH, KVPair(kvp)) + kvsH = append(kvsH, kvPair(kvp)) } return SimpleProofsFromHashers(kvsH) } @@ -43,10 +48,13 @@ func (sp *SimpleProof) Verify(index int, total int, leafHash []byte, rootHash [] return computedHash != nil && bytes.Equal(computedHash, rootHash) } +// String implements the stringer interface for SimpleProof. +// It is a wrapper around StringIndented. func (sp *SimpleProof) String() string { return sp.StringIndented("") } +// StringIndented generates a canonical string representation of a SimpleProof. func (sp *SimpleProof) StringIndented(indent string) string { return fmt.Sprintf(`SimpleProof{ %s Aunts: %X @@ -90,7 +98,7 @@ func computeHashFromAunts(index int, total int, leafHash []byte, innerHashes [][ } } -// Helper structure to construct merkle proof. +// SimpleProofNode is a helper structure to construct merkle proof. // The node and the tree is thrown away afterwards. // Exactly one of node.Left and node.Right is nil, unless node is the root, in which case both are nil. // node.Parent.Hash = hash(node.Hash, node.Right.Hash) or @@ -102,8 +110,8 @@ type SimpleProofNode struct { Right *SimpleProofNode // Right sibling (only one of Left,Right is set) } -// Starting from a leaf SimpleProofNode, FlattenAunts() will return -// the inner hashes for the item corresponding to the leaf. +// FlattenAunts will return the inner hashes for the item corresponding to the leaf, +// starting from a leaf SimpleProofNode. func (spn *SimpleProofNode) FlattenAunts() [][]byte { // Nonrecursive impl. innerHashes := [][]byte{} diff --git a/merkle/simple_tree.go b/merkle/simple_tree.go index 3c31b1337..c23f84264 100644 --- a/merkle/simple_tree.go +++ b/merkle/simple_tree.go @@ -1,91 +1,58 @@ -/* -Computes a deterministic minimal height merkle tree hash. -If the number of items is not a power of two, some leaves -will be at different levels. Tries to keep both sides of -the tree the same size, but the left may be one greater. - -Use this for short deterministic trees, such as the validator list. -For larger datasets, use IAVLTree. - - * - / \ - / \ - / \ - / \ - * * - / \ / \ - / \ / \ - / \ / \ - * * * h6 - / \ / \ / \ - h0 h1 h2 h3 h4 h5 - -*/ - package merkle import ( "github.com/tendermint/go-crypto/tmhash" ) -func SimpleHashFromTwoHashes(left []byte, right []byte) []byte { +// SimpleHashFromTwoHashes is the basic operation of the Merkle tree: Hash(left | right). +func SimpleHashFromTwoHashes(left, right []byte) []byte { var hasher = tmhash.New() err := encodeByteSlice(hasher, left) if err != nil { - panic(err) - } + panic(err) + } err = encodeByteSlice(hasher, right) if err != nil { - panic(err) - } - return hasher.Sum(nil) -} - -func SimpleHashFromHashes(hashes [][]byte) []byte { - // Recursive impl. - switch len(hashes) { - case 0: - return nil - case 1: - return hashes[0] - default: - left := SimpleHashFromHashes(hashes[:(len(hashes)+1)/2]) - right := SimpleHashFromHashes(hashes[(len(hashes)+1)/2:]) - return SimpleHashFromTwoHashes(left, right) - } -} - -// NOTE: Do not implement this, use SimpleHashFromByteslices instead. -// type Byteser interface { Bytes() []byte } -// func SimpleHashFromBytesers(items []Byteser) []byte { ... } - -func SimpleHashFromByteslices(bzs [][]byte) []byte { - hashes := make([][]byte, len(bzs)) - for i, bz := range bzs { - hashes[i] = SimpleHashFromBytes(bz) - } - return SimpleHashFromHashes(hashes) -} - -func SimpleHashFromBytes(bz []byte) []byte { - hasher := tmhash.New() - hasher.Write(bz) + panic(err) + } return hasher.Sum(nil) } +// SimpleHashFromHashers computes a Merkle tree from items that can be hashed. func SimpleHashFromHashers(items []Hasher) []byte { hashes := make([][]byte, len(items)) for i, item := range items { hash := item.Hash() hashes[i] = hash } - return SimpleHashFromHashes(hashes) + return simpleHashFromHashes(hashes) } +// SimpleHashFromMap computes a Merkle tree from sorted map. +// Like calling SimpleHashFromHashers with +// `item = []byte(Hash(key) | Hash(value))`, +// sorted by `item`. func SimpleHashFromMap(m map[string]Hasher) []byte { - sm := NewSimpleMap() + sm := newSimpleMap() for k, v := range m { sm.Set(k, v) } return sm.Hash() } + +//---------------------------------------------------------------- + +// Expects hashes! +func simpleHashFromHashes(hashes [][]byte) []byte { + // Recursive impl. + switch len(hashes) { + case 0: + return nil + case 1: + return hashes[0] + default: + left := simpleHashFromHashes(hashes[:(len(hashes)+1)/2]) + right := simpleHashFromHashes(hashes[(len(hashes)+1)/2:]) + return SimpleHashFromTwoHashes(left, right) + } +} diff --git a/merkle/simple_tree_test.go b/merkle/simple_tree_test.go index 8c4ed01f8..db8e3d7ff 100644 --- a/merkle/simple_tree_test.go +++ b/merkle/simple_tree_test.go @@ -7,6 +7,7 @@ import ( . "github.com/tendermint/tmlibs/test" "testing" + "github.com/tendermint/go-crypto/tmhash" ) type testItem []byte @@ -21,7 +22,7 @@ func TestSimpleProof(t *testing.T) { items := make([]Hasher, total) for i := 0; i < total; i++ { - items[i] = testItem(cmn.RandBytes(32)) + items[i] = testItem(cmn.RandBytes(tmhash.Size)) } rootHash := SimpleHashFromHashers(items) diff --git a/merkle/types.go b/merkle/types.go index a0c491a7e..ddc420659 100644 --- a/merkle/types.go +++ b/merkle/types.go @@ -5,6 +5,7 @@ import ( "io" ) +// Tree is a Merkle tree interface. type Tree interface { Size() (size int) Height() (height int8) @@ -23,6 +24,7 @@ type Tree interface { IterateRange(start []byte, end []byte, ascending bool, fx func(key []byte, value []byte) (stop bool)) (stopped bool) } +// Hasher represents a hashable piece of data which can be hashed in the Tree. type Hasher interface { Hash() []byte } diff --git a/tmhash/hash.go b/tmhash/hash.go index 9f684ce01..1b29d8680 100644 --- a/tmhash/hash.go +++ b/tmhash/hash.go @@ -5,7 +5,7 @@ import ( "hash" ) -var ( +const ( Size = 20 BlockSize = sha256.BlockSize ) From 862d3c342a03861c74cfbc649439cc81ceff5396 Mon Sep 17 00:00:00 2001 From: Liamsi Date: Wed, 30 May 2018 17:28:20 +0100 Subject: [PATCH 250/287] commit doc.go --- merkle/doc.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 merkle/doc.go diff --git a/merkle/doc.go b/merkle/doc.go new file mode 100644 index 000000000..da65dd858 --- /dev/null +++ b/merkle/doc.go @@ -0,0 +1,31 @@ +/* +Package merkle computes a deterministic minimal height Merkle tree hash. +If the number of items is not a power of two, some leaves +will be at different levels. Tries to keep both sides of +the tree the same size, but the left may be one greater. + +Use this for short deterministic trees, such as the validator list. +For larger datasets, use IAVLTree. + +Be aware that the current implementation by itself does not prevent +second pre-image attacks. Hence, use this library with caution. +Otherwise you might run into similar issues as, e.g., in early Bitcoin: +https://bitcointalk.org/?topic=102395 + + * + / \ + / \ + / \ + / \ + * * + / \ / \ + / \ / \ + / \ / \ + * * * h6 + / \ / \ / \ + h0 h1 h2 h3 h4 h5 + +TODO(ismail): add 2nd pre-image protection or clarify further on how we use this and why this secure. + +*/ +package merkle \ No newline at end of file From 52bd867fd918513e7cab9d57cf4fdf9c78396a03 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 30 May 2018 17:50:17 -0400 Subject: [PATCH 251/287] merkle: use amino for byteslice encoding --- merkle/simple_map.go | 15 +++++++-------- merkle/simple_map_test.go | 4 +--- merkle/types.go | 19 ++++--------------- 3 files changed, 12 insertions(+), 26 deletions(-) diff --git a/merkle/simple_map.go b/merkle/simple_map.go index b073ecdd6..cde5924f4 100644 --- a/merkle/simple_map.go +++ b/merkle/simple_map.go @@ -1,8 +1,8 @@ package merkle import ( - cmn "github.com/tendermint/tmlibs/common" "github.com/tendermint/go-crypto/tmhash" + cmn "github.com/tendermint/tmlibs/common" ) // Merkle tree from a map. @@ -65,21 +65,20 @@ func (sm *simpleMap) KVPairs() cmn.KVPairs { //---------------------------------------- // A local extension to KVPair that can be hashed. -// XXX: key and value do not need to already be hashed - -// the kvpair ("abc", "def") would not give the same result -// as ("ab", "cdef") as we're using length-prefixing. +// Key and value are length prefixed and concatenated, +// then hashed. type kvPair cmn.KVPair func (kv kvPair) Hash() []byte { hasher := tmhash.New() err := encodeByteSlice(hasher, kv.Key) if err != nil { - panic(err) - } + panic(err) + } err = encodeByteSlice(hasher, kv.Value) if err != nil { - panic(err) - } + panic(err) + } return hasher.Sum(nil) } diff --git a/merkle/simple_map_test.go b/merkle/simple_map_test.go index 9d0c25a2a..a89289a8f 100644 --- a/merkle/simple_map_test.go +++ b/merkle/simple_map_test.go @@ -11,9 +11,7 @@ import ( type strHasher string func (str strHasher) Hash() []byte { - h := tmhash.New() - h.Write([]byte(str)) - return h.Sum(nil) + return tmhash.Sum([]byte(str)) } func TestSimpleMap(t *testing.T) { diff --git a/merkle/types.go b/merkle/types.go index ddc420659..2fcb3f39d 100644 --- a/merkle/types.go +++ b/merkle/types.go @@ -1,8 +1,9 @@ package merkle import ( - "encoding/binary" "io" + + amino "github.com/tendermint/go-amino" ) // Tree is a Merkle tree interface. @@ -30,20 +31,8 @@ type Hasher interface { } //----------------------------------------------------------------------- -// NOTE: these are duplicated from go-amino so we dont need go-amino as a dep +// Uvarint length prefixed byteslice func encodeByteSlice(w io.Writer, bz []byte) (err error) { - err = encodeUvarint(w, uint64(len(bz))) - if err != nil { - return - } - _, err = w.Write(bz) - return -} - -func encodeUvarint(w io.Writer, i uint64) (err error) { - var buf [10]byte - n := binary.PutUvarint(buf[:], i) - _, err = w.Write(buf[0:n]) - return + return amino.EncodeByteSlice(w, bz) } From 20fdec6c0efd1d1387e4177ab82efea67b2dadf1 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 30 May 2018 18:34:11 -0400 Subject: [PATCH 252/287] fix comment --- keys/keybase.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keys/keybase.go b/keys/keybase.go index 876eef8f5..dd9726478 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -159,7 +159,7 @@ func (kb dbKeybase) Import(name string, armor string) (err error) { return nil } -// ExportPubKey imports ASCII-armored public keys. +// ImportPubKey imports ASCII-armored public keys. // Store a new Info object holding a public key only, i.e. it will // not be possible to sign with it as it lacks the secret key. func (kb dbKeybase) ImportPubKey(name string, armor string) (err error) { From 21b821d661ea22a2001bb9f394188ba98c07ad03 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 30 May 2018 18:41:08 -0400 Subject: [PATCH 253/287] SignatureKey -> Signature --- amino.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/amino.go b/amino.go index 89636895a..5b9d28994 100644 --- a/amino.go +++ b/amino.go @@ -30,7 +30,7 @@ func RegisterAmino(cdc *amino.Codec) { cdc.RegisterInterface((*Signature)(nil), nil) cdc.RegisterConcrete(SignatureEd25519{}, - "tendermint/SignatureKeyEd25519", nil) + "tendermint/SignatureEd25519", nil) cdc.RegisterConcrete(SignatureSecp256k1{}, - "tendermint/SignatureKeySecp256k1", nil) + "tendermint/SignatureSecp256k1", nil) } From 970693523338af9e9cd6e344c4c9500ef517c159 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 30 May 2018 18:57:53 -0400 Subject: [PATCH 254/287] fix link in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4a524c014..959290573 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ go-crypto is the cryptographic package adapted for Tendermint's uses ## Binary encoding -For Binary encoding, please refer to the [Tendermint encoding spec](https://github.com/tendermint/tendermint/blob/develop/docs/specification/new-spec/encoding.md). +For Binary encoding, please refer to the [Tendermint encoding spec](https://github.com/tendermint/tendermint/blob/develop/docs/spec/blockchain/encoding.md). ## JSON Encoding From e1ce3ffe0fd100816e597d842ee6e476dd320b9c Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 30 May 2018 20:48:52 -0400 Subject: [PATCH 255/287] changelog and version --- CHANGELOG.md | 30 ++++++++++++++++++++++++++++++ version.go | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91dcfab52..5db3a6109 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # Changelog +## 0.7.0 + +**May 30th, 2018** + +BREAKING CHANGES + +No breaking changes compared to 0.6.2, but making up for the version bump that +should have happened in 0.6.1. + +We also bring in the `tmlibs/merkle` package with breaking changes: + +- change the hash function from RIPEMD160 to tmhash (first 20-bytes of SHA256) +- remove unused funcs and unexport SimpleMap + +FEATURES + +- [xchacha20poly1305] New authenticated encryption module +- [merkle] Moved in from tmlibs +- [merkle/tmhash] New hash function: the first 20-bytes of SHA256 + +IMPROVEMENTS + +- Remove some dead code +- Use constant-time compare for signatures + +BUG FIXES + +- Fix MixEntropy weakness +- Fix PrivKeyEd25519.Generate() + ## 0.6.2 (April 9, 2018) IMPROVEMENTS diff --git a/version.go b/version.go index aac87c4f3..4cf5685a5 100644 --- a/version.go +++ b/version.go @@ -1,3 +1,3 @@ package crypto -const Version = "0.6.2" +const Version = "0.7.0" From 63aac6559032f9fbc1a6a94b2a20ae9b30de0f65 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 31 May 2018 21:21:50 +0200 Subject: [PATCH 256/287] Remove Ledger ed25519 support, for now --- amino.go | 4 -- ledger_ed25519.go | 156 ---------------------------------------------- ledger_pub_key.go | 68 -------------------- ledger_test.go | 38 ----------- 4 files changed, 266 deletions(-) delete mode 100644 ledger_ed25519.go delete mode 100644 ledger_pub_key.go diff --git a/amino.go b/amino.go index b78a15ed9..2af765434 100644 --- a/amino.go +++ b/amino.go @@ -19,8 +19,6 @@ func RegisterAmino(cdc *amino.Codec) { cdc.RegisterInterface((*PubKey)(nil), nil) cdc.RegisterConcrete(PubKeyEd25519{}, "tendermint/PubKeyEd25519", nil) - cdc.RegisterConcrete(PubKeyLedgerEd25519{}, - "tendermint/PubKeyLedgerEd25519", nil) cdc.RegisterConcrete(PubKeySecp256k1{}, "tendermint/PubKeySecp256k1", nil) @@ -31,8 +29,6 @@ func RegisterAmino(cdc *amino.Codec) { "tendermint/PrivKeySecp256k1", nil) cdc.RegisterConcrete(PrivKeyLedgerSecp256k1{}, "tendermint/PrivKeyLedgerSecp256k1", nil) - cdc.RegisterConcrete(PrivKeyLedgerEd25519{}, - "tendermint/PrivKeyLedgerEd25519", nil) cdc.RegisterInterface((*Signature)(nil), nil) cdc.RegisterConcrete(SignatureEd25519{}, diff --git a/ledger_ed25519.go b/ledger_ed25519.go deleted file mode 100644 index 2110b8871..000000000 --- a/ledger_ed25519.go +++ /dev/null @@ -1,156 +0,0 @@ -package crypto - -import ( - "fmt" - "github.com/pkg/errors" - - // "github.com/tendermint/ed25519" - ledger "github.com/zondax/ledger-goclient" -) - -func pubkeyLedgerEd25519(device *ledger.Ledger, path DerivationPath) (pub PubKey, err error) { - key, err := device.GetPublicKeyED25519(path) - if err != nil { - return pub, fmt.Errorf("Error fetching public key: %v", err) - } - var p PubKeyLedgerEd25519 - copy(p[:], key[0:32]) - return p, err -} - -func signLedgerEd25519(device *ledger.Ledger, path DerivationPath, msg []byte) (sig Signature, err error) { - bsig, err := device.SignED25519(path, msg) - if err != nil { - return sig, err - } - sig = SignatureEd25519FromBytes(bsig) - return sig, nil -} - -// PrivKeyLedgerEd25519 implements PrivKey, calling the ledger nano -// we cache the PubKey from the first call to use it later -type PrivKeyLedgerEd25519 struct { - // PubKey should be private, but we want to encode it via go-amino - // so we can view the address later, even without having the ledger - // attached - CachedPubKey PubKey - Path DerivationPath -} - -// NewPrivKeyLedgerEd25519 will generate a new key and store the -// public key for later use. -func NewPrivKeyLedgerEd25519(path DerivationPath) (PrivKey, error) { - var pk PrivKeyLedgerEd25519 - pk.Path = path - // getPubKey will cache the pubkey for later use, - // this allows us to return an error early if the ledger - // is not plugged in - _, err := pk.getPubKey() - return &pk, err -} - -// ValidateKey allows us to verify the sanity of a key -// after loading it from disk -func (pk PrivKeyLedgerEd25519) ValidateKey() error { - // getPubKey will return an error if the ledger is not - // properly set up... - pub, err := pk.forceGetPubKey() - if err != nil { - return err - } - // verify this matches cached address - if !pub.Equals(pk.CachedPubKey) { - return errors.New("Cached key does not match retrieved key") - } - return nil -} - -// AssertIsPrivKeyInner fulfils PrivKey Interface -func (pk *PrivKeyLedgerEd25519) AssertIsPrivKeyInner() {} - -// Bytes fulfils PrivKey Interface - but it stores the cached pubkey so we can verify -// the same key when we reconnect to a ledger -func (pk PrivKeyLedgerEd25519) Bytes() []byte { - bin, err := cdc.MarshalBinaryBare(pk) - if err != nil { - panic(err) - } - return bin -} - -// Sign calls the ledger and stores the PubKey for future use -// -// XXX/TODO: panics if there is an error communicating with the ledger. -// -// Communication is checked on NewPrivKeyLedger and PrivKeyFromBytes, -// returning an error, so this should only trigger if the privkey is held -// in memory for a while before use. -func (pk PrivKeyLedgerEd25519) Sign(msg []byte) Signature { - // oh, I wish there was better error handling - dev, err := getLedger() - if err != nil { - panic(err) - } - - sig, err := signLedgerEd25519(dev, pk.Path, msg) - if err != nil { - panic(err) - } - - pub, err := pubkeyLedgerEd25519(dev, pk.Path) - if err != nil { - panic(err) - } - - // if we have no pubkey yet, store it for future queries - if pk.CachedPubKey == nil { - pk.CachedPubKey = pub - } else if !pk.CachedPubKey.Equals(pub) { - panic("Stored key does not match signing key") - } - return sig -} - -// PubKey returns the stored PubKey -// TODO: query the ledger if not there, once it is not volatile -func (pk PrivKeyLedgerEd25519) PubKey() PubKey { - key, err := pk.getPubKey() - if err != nil { - panic(err) - } - return key -} - -// getPubKey reads the pubkey from cache or from the ledger itself -// since this involves IO, it may return an error, which is not exposed -// in the PubKey interface, so this function allows better error handling -func (pk PrivKeyLedgerEd25519) getPubKey() (key PubKey, err error) { - // if we have no pubkey, set it - if pk.CachedPubKey == nil { - pk.CachedPubKey, err = pk.forceGetPubKey() - } - return pk.CachedPubKey, err -} - -// forceGetPubKey is like getPubKey but ignores any cached key -// and ensures we get it from the ledger itself. -func (pk PrivKeyLedgerEd25519) forceGetPubKey() (key PubKey, err error) { - dev, err := getLedger() - if err != nil { - return key, errors.New(fmt.Sprintf("Cannot connect to Ledger device - error: %v", err)) - } - key, err = pubkeyLedgerEd25519(dev, pk.Path) - if err != nil { - return key, errors.New(fmt.Sprintf("Please open Cosmos app on the Ledger device - error: %v", err)) - } - return key, err -} - -// Equals fulfils PrivKey Interface - makes sure both keys refer to the -// same -func (pk PrivKeyLedgerEd25519) Equals(other PrivKey) bool { - if ledger, ok := other.(*PrivKeyLedgerEd25519); ok { - return pk.CachedPubKey.Equals(ledger.CachedPubKey) - } - return false -} diff --git a/ledger_pub_key.go b/ledger_pub_key.go deleted file mode 100644 index 0a5222577..000000000 --- a/ledger_pub_key.go +++ /dev/null @@ -1,68 +0,0 @@ -package crypto - -import ( - "bytes" - "crypto/sha512" - "fmt" - - "github.com/tendermint/ed25519" - "github.com/tendermint/ed25519/extra25519" - "golang.org/x/crypto/ripemd160" -) - -var _ PubKey = PubKeyLedgerEd25519{} - -// Implements PubKeyInner -type PubKeyLedgerEd25519 [32]byte - -func (pubKey PubKeyLedgerEd25519) Address() Address { - // append type byte - hasher := ripemd160.New() - hasher.Write(pubKey.Bytes()) // does not error - return Address(hasher.Sum(nil)) -} - -func (pubKey PubKeyLedgerEd25519) Bytes() []byte { - bz, err := cdc.MarshalBinaryBare(pubKey) - if err != nil { - panic(err) - } - return bz -} - -func (pubKey PubKeyLedgerEd25519) VerifyBytes(msg []byte, sig_ Signature) bool { - // must verify sha512 hash of msg, no padding, for Ledger compatibility - sig, ok := sig_.(SignatureEd25519) - if !ok { - return false - } - pubKeyBytes := [32]byte(pubKey) - sigBytes := [64]byte(sig) - h := sha512.New() - h.Write(msg) - digest := h.Sum(nil) - return ed25519.Verify(&pubKeyBytes, digest, &sigBytes) -} - -// For use with golang/crypto/nacl/box -// If error, returns nil. -func (pubKey PubKeyLedgerEd25519) ToCurve25519() *[32]byte { - keyCurve25519, pubKeyBytes := new([32]byte), [32]byte(pubKey) - ok := extra25519.PublicKeyToCurve25519(keyCurve25519, &pubKeyBytes) - if !ok { - return nil - } - return keyCurve25519 -} - -func (pubKey PubKeyLedgerEd25519) String() string { - return fmt.Sprintf("PubKeyLedgerEd25519{%X}", pubKey[:]) -} - -func (pubKey PubKeyLedgerEd25519) Equals(other PubKey) bool { - if otherEd, ok := other.(PubKeyLedgerEd25519); ok { - return bytes.Equal(pubKey[:], otherEd[:]) - } else { - return false - } -} diff --git a/ledger_test.go b/ledger_test.go index a0ea35837..dda3d3d3d 100644 --- a/ledger_test.go +++ b/ledger_test.go @@ -46,44 +46,6 @@ func TestRealLedgerSecp256k1(t *testing.T) { assert.Equal(t, pub, bpub) } -func TestRealLedgerEd25519(t *testing.T) { - - if os.Getenv("WITH_LEDGER") == "" { - t.Skip("Set WITH_LEDGER to run code on real ledger") - } - msg := []byte("kuhehfeohg") - - path := DerivationPath{44, 60, 0, 0, 0} - - priv, err := NewPrivKeyLedgerEd25519(path) - require.Nil(t, err, "%+v", err) - pub := priv.PubKey() - sig := priv.Sign(msg) - - valid := pub.VerifyBytes(msg, sig) - assert.True(t, valid) - - // now, let's serialize the key and make sure it still works - bs := priv.Bytes() - priv2, err := PrivKeyFromBytes(bs) - require.Nil(t, err, "%+v", err) - - // make sure we get the same pubkey when we load from disk - pub2 := priv2.PubKey() - require.Equal(t, pub, pub2) - - // signing with the loaded key should match the original pubkey - sig = priv2.Sign(msg) - valid = pub.VerifyBytes(msg, sig) - assert.True(t, valid) - - // make sure pubkeys serialize properly as well - bs = pub.Bytes() - bpub, err := PubKeyFromBytes(bs) - require.NoError(t, err) - assert.Equal(t, pub, bpub) -} - // TestRealLedgerErrorHandling calls. These tests assume // the ledger is not plugged in.... func TestRealLedgerErrorHandling(t *testing.T) { From 80e97522504e79dca2f0e2c35168e6f47dc307ce Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 31 May 2018 21:30:20 +0200 Subject: [PATCH 257/287] Move TODOs to #114 --- Gopkg.lock | 4 ++-- ledger_secp256k1.go | 19 ++++++++----------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 2090ac2e3..f51e2b229 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -11,7 +11,7 @@ branch = "master" name = "github.com/btcsuite/btcd" packages = ["btcec"] - revision = "bc0944904505aab55e089371a892be2f87883161" + revision = "86fed781132ac890ee03e906e4ecd5d6fa180c64" [[projects]] branch = "master" @@ -172,7 +172,7 @@ "ripemd160", "salsa20/salsa" ] - revision = "ab813273cd59e1333f7ae7bff5d027d4aadf528c" + revision = "5ba7f63082460102a45837dbd1827e10f9479ac0" [solve-meta] analyzer-name = "dep" diff --git a/ledger_secp256k1.go b/ledger_secp256k1.go index b574035d4..f485bb415 100644 --- a/ledger_secp256k1.go +++ b/ledger_secp256k1.go @@ -2,7 +2,6 @@ package crypto import ( "fmt" - "github.com/pkg/errors" secp256k1 "github.com/btcsuite/btcd/btcec" ledger "github.com/zondax/ledger-goclient" @@ -11,13 +10,14 @@ import ( func pubkeyLedgerSecp256k1(device *ledger.Ledger, path DerivationPath) (pub PubKey, err error) { key, err := device.GetPublicKeySECP256K1(path) if err != nil { - return pub, fmt.Errorf("Error fetching public key: %v", err) + return nil, fmt.Errorf("error fetching public key: %v", err) } var p PubKeySecp256k1 // Reserialize in the 33-byte compressed format cmp, err := secp256k1.ParsePubKey(key[:], secp256k1.S256()) copy(p[:], cmp.SerializeCompressed()) - return p, err + pub = p + return } func signLedgerSecp256k1(device *ledger.Ledger, path DerivationPath, msg []byte) (sig Signature, err error) { @@ -26,7 +26,7 @@ func signLedgerSecp256k1(device *ledger.Ledger, path DerivationPath, msg []byte) return sig, err } sig = SignatureSecp256k1FromBytes(bsig) - return sig, nil + return } // PrivKeyLedgerSecp256k1 implements PrivKey, calling the ledger nano @@ -62,7 +62,7 @@ func (pk PrivKeyLedgerSecp256k1) ValidateKey() error { } // verify this matches cached address if !pub.Equals(pk.CachedPubKey) { - return errors.New("Cached key does not match retrieved key") + return fmt.Errorf("cached key does not match retrieved key") } return nil } @@ -82,8 +82,6 @@ func (pk PrivKeyLedgerSecp256k1) Bytes() []byte { // Sign calls the ledger and stores the PubKey for future use // -// XXX/TODO: panics if there is an error communicating with the ledger. -// // Communication is checked on NewPrivKeyLedger and PrivKeyFromBytes, // returning an error, so this should only trigger if the privkey is held // in memory for a while before use. @@ -108,13 +106,12 @@ func (pk PrivKeyLedgerSecp256k1) Sign(msg []byte) Signature { if pk.CachedPubKey == nil { pk.CachedPubKey = pub } else if !pk.CachedPubKey.Equals(pub) { - panic("Stored key does not match signing key") + panic("stored key does not match signing key") } return sig } // PubKey returns the stored PubKey -// TODO: query the ledger if not there, once it is not volatile func (pk PrivKeyLedgerSecp256k1) PubKey() PubKey { key, err := pk.getPubKey() if err != nil { @@ -139,11 +136,11 @@ func (pk PrivKeyLedgerSecp256k1) getPubKey() (key PubKey, err error) { func (pk PrivKeyLedgerSecp256k1) forceGetPubKey() (key PubKey, err error) { dev, err := getLedger() if err != nil { - return key, errors.New(fmt.Sprintf("Cannot connect to Ledger device - error: %v", err)) + return key, fmt.Errorf("cannot connect to Ledger device - error: %v", err) } key, err = pubkeyLedgerSecp256k1(dev, pk.Path) if err != nil { - return key, errors.New(fmt.Sprintf("Please open Cosmos app on the Ledger device - error: %v", err)) + return key, fmt.Errorf("please open Cosmos app on the Ledger device - error: %v", err) } return key, err } From 854eb323ddb27d10eddc7dfb36e91e98165dd6c2 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 8 Jun 2018 17:28:50 -0700 Subject: [PATCH 258/287] dev version bump --- CHANGELOG.md | 4 ++++ version.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5db3a6109..4c31551b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.8.0 + +**TBD** + ## 0.7.0 **May 30th, 2018** diff --git a/version.go b/version.go index 4cf5685a5..57806e26c 100644 --- a/version.go +++ b/version.go @@ -1,3 +1,3 @@ package crypto -const Version = "0.7.0" +const Version = "0.8.0-dev" From c21f67c5af7fef3ca064fa578084a73ac9fdfb81 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Sun, 10 Jun 2018 10:01:41 +0200 Subject: [PATCH 259/287] Unify local and external keys in keybase interface (#117) * Return errors on priv.Sign(), priv.PubKey() * Add CreateLedger, CreateOffline * Add switch on .Sign() for Ledger wallets * Add offline signing switch on .Sign() * Use MustUnmarshalBinaryBare() * Add confirmation to delete offline/Ledger keys * Lowercase error message * Add human-readable .GetType() function to Info interface * Rename CryptoAlgo => SignAlgo * assert.Nil(t, err) => assert.NoError(t, err) --- Gopkg.lock | 23 ++++-- Gopkg.toml | 3 +- encode_test.go | 6 +- keys/keybase.go | 168 ++++++++++++++++++++++++++++++++----------- keys/keybase_test.go | 147 ++++++++++++++++++++----------------- keys/keys.go | 10 +-- keys/types.go | 124 ++++++++++++++++++++++++++------ keys/wire.go | 4 ++ ledger_secp256k1.go | 27 +++---- ledger_test.go | 12 ++-- priv_key.go | 47 ++++-------- priv_key_test.go | 6 +- pub_key_test.go | 6 +- signature_test.go | 18 +++-- 14 files changed, 391 insertions(+), 210 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index f51e2b229..24b638a55 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -119,7 +119,7 @@ "leveldb/table", "leveldb/util" ] - revision = "5d6fca44a948d2be89a9702de7717f0168403d3d" + revision = "e2150783cd35f5b607daca48afd8c57ec54cc995" [[projects]] branch = "master" @@ -142,10 +142,11 @@ packages = [ "common", "db", - "log" + "log", + "test" ] - revision = "d970af87248a4e162590300dbb74e102183a417d" - version = "v0.8.3" + revision = "692f1d86a6e2c0efa698fd1e4541b68c74ffaf38" + version = "v0.8.4" [[projects]] branch = "master" @@ -156,7 +157,7 @@ [[projects]] name = "github.com/zondax/ledger-goclient" packages = ["."] - revision = "3e2146609cdb97894c064d59e9d00accd8c2b1dd" + revision = "065cbf938a16f20335c40cfe180f9cd4955c6a5a" [[projects]] branch = "master" @@ -164,6 +165,8 @@ packages = [ "bcrypt", "blowfish", + "chacha20poly1305", + "internal/chacha20", "nacl/secretbox", "openpgp/armor", "openpgp/errors", @@ -172,11 +175,17 @@ "ripemd160", "salsa20/salsa" ] - revision = "5ba7f63082460102a45837dbd1827e10f9479ac0" + revision = "8ac0e0d97ce45cd83d1d7243c060cb8461dda5e9" + +[[projects]] + branch = "master" + name = "golang.org/x/sys" + packages = ["cpu"] + revision = "9527bec2660bd847c050fda93a0f0c6dee0800bb" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "365c3bca75ced49eb0ebcdc5c98fd47b534850684fcc94c16d1bc6a671116395" + inputs-digest = "f20e34cd998442d4ffe2f9aa45ab87a55ba6e4cd19f29009adaadac3b5dccf26" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 10931a1a6..d2b50e5a1 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -24,7 +24,6 @@ # go-tests = true # unused-packages = true - [[constraint]] name = "github.com/btcsuite/btcutil" branch = "master" @@ -59,7 +58,7 @@ [[constraint]] name = "github.com/zondax/ledger-goclient" - revision = "3e2146609cdb97894c064d59e9d00accd8c2b1dd" + revision = "065cbf938a16f20335c40cfe180f9cd4955c6a5a" [prune] go-tests = true diff --git a/encode_test.go b/encode_test.go index 0bd450829..f78d9439c 100644 --- a/encode_test.go +++ b/encode_test.go @@ -69,14 +69,16 @@ func TestKeyEncodings(t *testing.T) { // Check (de/en)codings of Signatures. var sig1, sig2, sig3 Signature - sig1 = tc.privKey.Sign([]byte("something")) + sig1, err := tc.privKey.Sign([]byte("something")) + assert.NoError(t, err) checkAminoBinary(t, sig1, &sig2, -1) // Siganture size changes for Secp anyways. assert.EqualValues(t, sig1, sig2) checkAminoJSON(t, sig1, &sig3, false) // TODO also check Prefix bytes. assert.EqualValues(t, sig1, sig3) // Check (de/en)codings of PubKeys. - pubKey := tc.privKey.PubKey() + pubKey, err := tc.privKey.PubKey() + assert.NoError(t, err) var pub2, pub3 PubKey checkAminoBinary(t, pubKey, &pub2, tc.pubSize) assert.EqualValues(t, pubKey, pub2) diff --git a/keys/keybase.go b/keys/keybase.go index dd9726478..39a3de59e 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -1,7 +1,9 @@ package keys import ( + "bufio" "fmt" + "os" "strings" "github.com/pkg/errors" @@ -26,23 +28,23 @@ func New(db dbm.DB, codec words.Codec) dbKeybase { var _ Keybase = dbKeybase{} -// Create generates a new key and persists it to storage, encrypted +// CreateMnemonic generates a new key and persists it to storage, encrypted // using the passphrase. It returns the generated seedphrase // (mnemonic) and the key Info. It returns an error if it fails to // generate a key for the given algo type, or if another key is // already stored under the same name. -func (kb dbKeybase) Create(name, passphrase string, algo CryptoAlgo) (Info, string, error) { +func (kb dbKeybase) CreateMnemonic(name, passphrase string, algo SignAlgo) (Info, string, error) { // NOTE: secret is SHA256 hashed by secp256k1 and ed25519. // 16 byte secret corresponds to 12 BIP39 words. // XXX: Ledgers use 24 words now - should we ? secret := crypto.CRandBytes(16) priv, err := generate(algo, secret) if err != nil { - return Info{}, "", err + return nil, "", err } // encrypt and persist the key - info := kb.writeKey(priv, name, passphrase) + info := kb.writeLocalKey(priv, name, passphrase) // we append the type byte to the serialized secret to help with // recovery @@ -56,6 +58,29 @@ func (kb dbKeybase) Create(name, passphrase string, algo CryptoAlgo) (Info, stri return info, seed, err } +// CreateLedger creates a new locally-stored reference to a Ledger keypair +// It returns the created key info and an error if the Ledger could not be queried +func (kb dbKeybase) CreateLedger(name string, path crypto.DerivationPath, algo SignAlgo) (Info, error) { + if algo != AlgoSecp256k1 { + return nil, fmt.Errorf("Only secp256k1 is supported for Ledger devices") + } + priv, err := crypto.NewPrivKeyLedgerSecp256k1(path) + if err != nil { + return nil, err + } + pub, err := priv.PubKey() + if err != nil { + return nil, err + } + return kb.writeLedgerKey(pub, path, name), nil +} + +// CreateOffline creates a new reference to an offline keypair +// It returns the created key info +func (kb dbKeybase) CreateOffline(name string, pub crypto.PubKey) (Info, error) { + return kb.writeOfflineKey(pub, name), nil +} + // Recover converts a seedphrase to a private key and persists it, // encrypted with the given passphrase. Functions like Create, but // seedphrase is input not output. @@ -63,22 +88,22 @@ func (kb dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { words := strings.Split(strings.TrimSpace(seedphrase), " ") secret, err := kb.codec.WordsToBytes(words) if err != nil { - return Info{}, err + return nil, err } // secret is comprised of the actual secret with the type // appended. // ie [secret] = [type] + [secret] typ, secret := secret[0], secret[1:] - algo := byteToCryptoAlgo(typ) + algo := byteToSignAlgo(typ) priv, err := generate(algo, secret) if err != nil { - return Info{}, err + return nil, err } // encrypt and persist key. - public := kb.writeKey(priv, name, passphrase) - return public, err + public := kb.writeLocalKey(priv, name, passphrase) + return public, nil } // List returns the keys from storage in alphabetical order. @@ -87,7 +112,6 @@ func (kb dbKeybase) List() ([]Info, error) { iter := kb.db.Iterator(nil, nil) defer iter.Close() for ; iter.Valid(); iter.Next() { - // key := iter.Key() info, err := readInfo(iter.Value()) if err != nil { return nil, err @@ -110,17 +134,46 @@ func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signat if err != nil { return } - if info.PrivKeyArmor == "" { - err = fmt.Errorf("private key not available") - return + var priv crypto.PrivKey + switch info.(type) { + case localInfo: + linfo := info.(localInfo) + if linfo.PrivKeyArmor == "" { + err = fmt.Errorf("private key not available") + return + } + priv, err = unarmorDecryptPrivKey(linfo.PrivKeyArmor, passphrase) + if err != nil { + return nil, nil, err + } + case ledgerInfo: + linfo := info.(ledgerInfo) + priv, err = crypto.NewPrivKeyLedgerSecp256k1(linfo.Path) + if err != nil { + return + } + case offlineInfo: + linfo := info.(offlineInfo) + fmt.Printf("Bytes to sign:\n%s", msg) + buf := bufio.NewReader(os.Stdin) + fmt.Printf("\nEnter Amino-encoded signature:\n") + // Will block until user inputs the signature + signed, err := buf.ReadString('\n') + if err != nil { + return nil, nil, err + } + cdc.MustUnmarshalBinary([]byte(signed), sig) + return sig, linfo.GetPubKey(), nil } - priv, err := unarmorDecryptPrivKey(info.PrivKeyArmor, passphrase) + sig, err = priv.Sign(msg) if err != nil { - return + return nil, nil, err } - sig = priv.Sign(msg) - pub = priv.PubKey() - return + pub, err = priv.PubKey() + if err != nil { + return nil, nil, err + } + return sig, pub, nil } func (kb dbKeybase) Export(name string) (armor string, err error) { @@ -143,7 +196,7 @@ func (kb dbKeybase) ExportPubKey(name string) (armor string, err error) { if err != nil { return } - return armorPubKeyBytes(info.PubKey.Bytes()), nil + return armorPubKeyBytes(info.GetPubKey().Bytes()), nil } func (kb dbKeybase) Import(name string, armor string) (err error) { @@ -175,23 +228,37 @@ func (kb dbKeybase) ImportPubKey(name string, armor string) (err error) { if err != nil { return } - kb.writePubKey(pubKey, name) + kb.writeOfflineKey(pubKey, name) return } // Delete removes key forever, but we must present the // proper passphrase before deleting it (for security). +// A passphrase of 'yes' is used to delete stored +// references to offline and Ledger / HW wallet keys func (kb dbKeybase) Delete(name, passphrase string) error { // verify we have the proper password before deleting info, err := kb.Get(name) if err != nil { return err } - _, err = unarmorDecryptPrivKey(info.PrivKeyArmor, passphrase) - if err != nil { - return err + switch info.(type) { + case localInfo: + linfo := info.(localInfo) + _, err = unarmorDecryptPrivKey(linfo.PrivKeyArmor, passphrase) + if err != nil { + return err + } + kb.db.DeleteSync(infoKey(name)) + return nil + case ledgerInfo: + case offlineInfo: + if passphrase != "yes" { + return fmt.Errorf("enter exactly 'yes' to delete the key") + } + kb.db.DeleteSync(infoKey(name)) + return nil } - kb.db.DeleteSync(infoKey(name)) return nil } @@ -205,36 +272,51 @@ func (kb dbKeybase) Update(name, oldpass, newpass string) error { if err != nil { return err } - key, err := unarmorDecryptPrivKey(info.PrivKeyArmor, oldpass) - if err != nil { - return err + switch info.(type) { + case localInfo: + linfo := info.(localInfo) + key, err := unarmorDecryptPrivKey(linfo.PrivKeyArmor, oldpass) + if err != nil { + return err + } + kb.writeLocalKey(key, name, newpass) + return nil + default: + return fmt.Errorf("Locally stored key required") } - - kb.writeKey(key, name, newpass) - return nil } -func (kb dbKeybase) writePubKey(pub crypto.PubKey, name string) Info { +func (kb dbKeybase) writeLocalKey(priv crypto.PrivKey, name, passphrase string) Info { + // encrypt private key using passphrase + privArmor := encryptArmorPrivKey(priv, passphrase) // make Info - info := newInfo(name, pub, "") - - // write them both - kb.db.SetSync(infoKey(name), info.bytes()) + pub, err := priv.PubKey() + if err != nil { + panic(err) + } + info := newLocalInfo(name, pub, privArmor) + kb.writeInfo(info, name) return info } -func (kb dbKeybase) writeKey(priv crypto.PrivKey, name, passphrase string) Info { - // generate the encrypted privkey - privArmor := encryptArmorPrivKey(priv, passphrase) - // make Info - info := newInfo(name, priv.PubKey(), privArmor) +func (kb dbKeybase) writeLedgerKey(pub crypto.PubKey, path crypto.DerivationPath, name string) Info { + info := newLedgerInfo(name, pub, path) + kb.writeInfo(info, name) + return info +} - // write them both - kb.db.SetSync(infoKey(name), info.bytes()) +func (kb dbKeybase) writeOfflineKey(pub crypto.PubKey, name string) Info { + info := newOfflineInfo(name, pub) + kb.writeInfo(info, name) return info } -func generate(algo CryptoAlgo, secret []byte) (crypto.PrivKey, error) { +func (kb dbKeybase) writeInfo(info Info, name string) { + // write the info by key + kb.db.SetSync(infoKey(name), writeInfo(info)) +} + +func generate(algo SignAlgo, secret []byte) (crypto.PrivKey, error) { switch algo { case AlgoEd25519: return crypto.GenPrivKeyEd25519FromSecret(secret), nil diff --git a/keys/keybase_test.go b/keys/keybase_test.go index aaf3b92fb..3627626cb 100644 --- a/keys/keybase_test.go +++ b/keys/keybase_test.go @@ -35,15 +35,15 @@ func TestKeyManagement(t *testing.T) { // create some keys _, err = cstore.Get(n1) assert.NotNil(t, err) - i, _, err := cstore.Create(n1, p1, algo) - require.Equal(t, n1, i.Name) + i, _, err := cstore.CreateMnemonic(n1, p1, algo) + require.Equal(t, n1, i.GetName()) require.Nil(t, err) - _, _, err = cstore.Create(n2, p2, algo) + _, _, err = cstore.CreateMnemonic(n2, p2, algo) require.Nil(t, err) // we can get these keys i2, err := cstore.Get(n2) - assert.Nil(t, err) + assert.NoError(t, err) _, err = cstore.Get(n3) assert.NotNil(t, err) @@ -52,9 +52,9 @@ func TestKeyManagement(t *testing.T) { require.Nil(t, err) require.Equal(t, 2, len(keyS)) // note these are in alphabetical order - assert.Equal(t, n2, keyS[0].Name) - assert.Equal(t, n1, keyS[1].Name) - assert.Equal(t, i2.PubKey, keyS[0].PubKey) + assert.Equal(t, n2, keyS[0].GetName()) + assert.Equal(t, n1, keyS[1].GetName()) + assert.Equal(t, i2.GetPubKey(), keyS[0].GetPubKey()) // deleting a key removes it err = cstore.Delete("bad name", "foo") @@ -67,6 +67,26 @@ func TestKeyManagement(t *testing.T) { _, err = cstore.Get(n1) assert.NotNil(t, err) + // create an offline key + o1 := "offline" + priv1 := crypto.GenPrivKeyEd25519() + pub1, err := priv1.PubKey() + require.Nil(t, err) + i, err = cstore.CreateOffline(o1, pub1) + require.Nil(t, err) + require.Equal(t, pub1, i.GetPubKey()) + require.Equal(t, o1, i.GetName()) + keyS, err = cstore.List() + require.Equal(t, 2, len(keyS)) + + // delete the offline key + err = cstore.Delete(o1, "no") + require.NotNil(t, err) + err = cstore.Delete(o1, "yes") + require.Nil(t, err) + keyS, err = cstore.List() + require.Equal(t, 1, len(keyS)) + // make sure that it only signs with the right password // tx := mock.NewSig([]byte("mytransactiondata")) // err = cstore.Sign(n2, p1, tx) @@ -95,19 +115,18 @@ func TestSignVerify(t *testing.T) { p1, p2, p3 := "1234", "foobar", "foobar" // create two users and get their info - i1, _, err := cstore.Create(n1, p1, algo) + i1, _, err := cstore.CreateMnemonic(n1, p1, algo) require.Nil(t, err) - i2, _, err := cstore.Create(n2, p2, algo) + i2, _, err := cstore.CreateMnemonic(n2, p2, algo) require.Nil(t, err) // Import a public key armor, err := cstore.ExportPubKey(n2) require.Nil(t, err) cstore.ImportPubKey(n3, armor) - i3, err := cstore.Get(n3) + _, err = cstore.Get(n3) require.Nil(t, err) - require.Equal(t, i3.PrivKeyArmor, "") // let's try to sign some messages d1 := []byte("my first message") @@ -117,19 +136,19 @@ func TestSignVerify(t *testing.T) { // try signing both data with both keys... s11, pub1, err := cstore.Sign(n1, p1, d1) require.Nil(t, err) - require.Equal(t, i1.PubKey, pub1) + require.Equal(t, i1.GetPubKey(), pub1) s12, pub1, err := cstore.Sign(n1, p1, d2) require.Nil(t, err) - require.Equal(t, i1.PubKey, pub1) + require.Equal(t, i1.GetPubKey(), pub1) s21, pub2, err := cstore.Sign(n2, p2, d1) require.Nil(t, err) - require.Equal(t, i2.PubKey, pub2) + require.Equal(t, i2.GetPubKey(), pub2) s22, pub2, err := cstore.Sign(n2, p2, d2) require.Nil(t, err) - require.Equal(t, i2.PubKey, pub2) + require.Equal(t, i2.GetPubKey(), pub2) // let's try to validate and make sure it only works when everything is proper cases := []struct { @@ -139,15 +158,15 @@ func TestSignVerify(t *testing.T) { valid bool }{ // proper matches - {i1.PubKey, d1, s11, true}, + {i1.GetPubKey(), d1, s11, true}, // change data, pubkey, or signature leads to fail - {i1.PubKey, d2, s11, false}, - {i2.PubKey, d1, s11, false}, - {i1.PubKey, d1, s21, false}, + {i1.GetPubKey(), d2, s11, false}, + {i2.GetPubKey(), d1, s11, false}, + {i1.GetPubKey(), d1, s21, false}, // make sure other successes - {i1.PubKey, d2, s12, true}, - {i2.PubKey, d1, s21, true}, - {i2.PubKey, d2, s22, true}, + {i1.GetPubKey(), d2, s12, true}, + {i2.GetPubKey(), d1, s21, true}, + {i2.GetPubKey(), d2, s22, true}, } for i, tc := range cases { @@ -232,27 +251,27 @@ func TestExportImport(t *testing.T) { words.MustLoadCodec("english"), ) - info, _, err := cstore.Create("john", "passphrase", keys.AlgoEd25519) - assert.Nil(t, err) - assert.Equal(t, info.Name, "john") - addr := info.PubKey.Address() + info, _, err := cstore.CreateMnemonic("john", "passphrase", keys.AlgoEd25519) + assert.NoError(t, err) + assert.Equal(t, info.GetName(), "john") + addr := info.GetPubKey().Address() john, err := cstore.Get("john") - assert.Nil(t, err) - assert.Equal(t, john.Name, "john") - assert.Equal(t, john.PubKey.Address(), addr) + assert.NoError(t, err) + assert.Equal(t, john.GetName(), "john") + assert.Equal(t, john.GetPubKey().Address(), addr) armor, err := cstore.Export("john") - assert.Nil(t, err) + assert.NoError(t, err) err = cstore.Import("john2", armor) - assert.Nil(t, err) + assert.NoError(t, err) john2, err := cstore.Get("john2") - assert.Nil(t, err) + assert.NoError(t, err) - assert.Equal(t, john.PubKey.Address(), addr) - assert.Equal(t, john.Name, "john") + assert.Equal(t, john.GetPubKey().Address(), addr) + assert.Equal(t, john.GetName(), "john") assert.Equal(t, john, john2) } @@ -265,33 +284,31 @@ func TestExportImportPubKey(t *testing.T) { ) // Create a private-public key pair and ensure consistency - info, _, err := cstore.Create("john", "passphrase", keys.AlgoEd25519) - assert.Nil(t, err) - assert.NotEqual(t, info.PrivKeyArmor, "") - assert.Equal(t, info.Name, "john") - addr := info.PubKey.Address() + info, _, err := cstore.CreateMnemonic("john", "passphrase", keys.AlgoEd25519) + assert.NoError(t, err) + assert.Equal(t, info.GetName(), "john") + addr := info.GetPubKey().Address() john, err := cstore.Get("john") - assert.Nil(t, err) - assert.Equal(t, john.Name, "john") - assert.Equal(t, john.PubKey.Address(), addr) + assert.NoError(t, err) + assert.Equal(t, john.GetName(), "john") + assert.Equal(t, john.GetPubKey().Address(), addr) // Export the public key only armor, err := cstore.ExportPubKey("john") - assert.Nil(t, err) + assert.NoError(t, err) // Import it under a different name err = cstore.ImportPubKey("john-pubkey-only", armor) - assert.Nil(t, err) + assert.NoError(t, err) // Ensure consistency john2, err := cstore.Get("john-pubkey-only") - assert.Nil(t, err) - assert.Equal(t, john2.PrivKeyArmor, "") + assert.NoError(t, err) // Compare the public keys - assert.True(t, john.PubKey.Equals(john2.PubKey)) + assert.True(t, john.GetPubKey().Equals(john2.GetPubKey())) // Ensure the original key hasn't changed john, err = cstore.Get("john") - assert.Nil(t, err) - assert.Equal(t, john.PubKey.Address(), addr) - assert.Equal(t, john.Name, "john") + assert.NoError(t, err) + assert.Equal(t, john.GetPubKey().Address(), addr) + assert.Equal(t, john.GetName(), "john") // Ensure keys cannot be overwritten err = cstore.ImportPubKey("john-pubkey-only", armor) @@ -312,7 +329,7 @@ func TestAdvancedKeyManagement(t *testing.T) { p1, p2 := "1234", "foobar" // make sure key works with initial password - _, _, err := cstore.Create(n1, p1, algo) + _, _, err := cstore.CreateMnemonic(n1, p1, algo) require.Nil(t, err, "%+v", err) assertPassword(t, cstore, n1, p1, p2) @@ -323,7 +340,7 @@ func TestAdvancedKeyManagement(t *testing.T) { // then it changes the password when correct err = cstore.Update(n1, p1, p2) - assert.Nil(t, err) + assert.NoError(t, err) // p2 is now the proper one! assertPassword(t, cstore, n1, p2, p1) @@ -341,7 +358,7 @@ func TestAdvancedKeyManagement(t *testing.T) { // import succeeds err = cstore.Import(n2, exported) - assert.Nil(t, err) + assert.NoError(t, err) // second import fails err = cstore.Import(n2, exported) @@ -362,9 +379,9 @@ func TestSeedPhrase(t *testing.T) { p1, p2 := "1234", "foobar" // make sure key works with initial password - info, seed, err := cstore.Create(n1, p1, algo) + info, seed, err := cstore.CreateMnemonic(n1, p1, algo) require.Nil(t, err, "%+v", err) - assert.Equal(t, n1, info.Name) + assert.Equal(t, n1, info.GetName()) assert.NotEmpty(t, seed) // now, let us delete this key @@ -376,9 +393,9 @@ func TestSeedPhrase(t *testing.T) { // let us re-create it from the seed-phrase newInfo, err := cstore.Recover(n2, p2, seed) require.Nil(t, err, "%+v", err) - assert.Equal(t, n2, newInfo.Name) - assert.Equal(t, info.Address(), newInfo.Address()) - assert.Equal(t, info.PubKey, newInfo.PubKey) + assert.Equal(t, n2, newInfo.GetName()) + assert.Equal(t, info.GetPubKey().Address(), newInfo.GetPubKey().Address()) + assert.Equal(t, info.GetPubKey(), newInfo.GetPubKey()) } func ExampleNew() { @@ -391,19 +408,19 @@ func ExampleNew() { sec := keys.AlgoSecp256k1 // Add keys and see they return in alphabetical order - bob, _, err := cstore.Create("Bob", "friend", ed) + bob, _, err := cstore.CreateMnemonic("Bob", "friend", ed) if err != nil { // this should never happen fmt.Println(err) } else { // return info here just like in List - fmt.Println(bob.Name) + fmt.Println(bob.GetName()) } - cstore.Create("Alice", "secret", sec) - cstore.Create("Carl", "mitm", ed) + cstore.CreateMnemonic("Alice", "secret", sec) + cstore.CreateMnemonic("Carl", "mitm", ed) info, _ := cstore.List() for _, i := range info { - fmt.Println(i.Name) + fmt.Println(i.GetName()) } // We need to use passphrase to generate a signature @@ -415,11 +432,11 @@ func ExampleNew() { // and we can validate the signature with publically available info binfo, _ := cstore.Get("Bob") - if !binfo.PubKey.Equals(bob.PubKey) { + if !binfo.GetPubKey().Equals(bob.GetPubKey()) { fmt.Println("Get and Create return different keys") } - if pub.Equals(binfo.PubKey) { + if pub.Equals(binfo.GetPubKey()) { fmt.Println("signed by Bob") } if !pub.VerifyBytes(tx, sig) { diff --git a/keys/keys.go b/keys/keys.go index 0ed89b3fd..c8e25da3c 100644 --- a/keys/keys.go +++ b/keys/keys.go @@ -2,14 +2,14 @@ package keys import "fmt" -type CryptoAlgo string +type SignAlgo string const ( - AlgoEd25519 = CryptoAlgo("ed25519") - AlgoSecp256k1 = CryptoAlgo("secp256k1") + AlgoEd25519 = SignAlgo("ed25519") + AlgoSecp256k1 = SignAlgo("secp256k1") ) -func cryptoAlgoToByte(key CryptoAlgo) byte { +func cryptoAlgoToByte(key SignAlgo) byte { switch key { case AlgoEd25519: return 0x01 @@ -20,7 +20,7 @@ func cryptoAlgoToByte(key CryptoAlgo) byte { } } -func byteToCryptoAlgo(b byte) CryptoAlgo { +func byteToSignAlgo(b byte) SignAlgo { switch b { case 0x01: return AlgoEd25519 diff --git a/keys/types.go b/keys/types.go index e1df644ab..53821e8bf 100644 --- a/keys/types.go +++ b/keys/types.go @@ -4,54 +4,136 @@ import ( crypto "github.com/tendermint/go-crypto" ) -// Keybase allows simple CRUD on a keystore, as an aid to signing +// Keybase exposes operations on a generic keystore type Keybase interface { - // Sign some bytes - Sign(name, passphrase string, msg []byte) (crypto.Signature, crypto.PubKey, error) - // Create a new keypair - Create(name, passphrase string, algo CryptoAlgo) (info Info, seed string, err error) - // Recover takes a seedphrase and loads in the key - Recover(name, passphrase, seedphrase string) (info Info, erro error) + + // CRUD on the keystore List() ([]Info, error) Get(name string) (Info, error) - Update(name, oldpass, newpass string) error Delete(name, passphrase string) error + // Sign some bytes, looking up the private key to use + Sign(name, passphrase string, msg []byte) (crypto.Signature, crypto.PubKey, error) + + // Create a new locally-stored keypair, returning the mnemonic + CreateMnemonic(name, passphrase string, algo SignAlgo) (info Info, seed string, err error) + // Recover takes a seedphrase and loads in the key + Recover(name, passphrase, seedphrase string) (info Info, erro error) + + // Create, store, and return a new Ledger key reference + CreateLedger(name string, path crypto.DerivationPath, algo SignAlgo) (info Info, err error) + + // Create, store, and return a new offline key reference + CreateOffline(name string, pubkey crypto.PubKey) (info Info, err error) + + // The following operations will *only* work on locally-stored keys + Update(name, oldpass, newpass string) error Import(name string, armor string) (err error) ImportPubKey(name string, armor string) (err error) Export(name string) (armor string, err error) ExportPubKey(name string) (armor string, err error) } -// Info is the public information about a key -type Info struct { +// Publically exposed information about a keypair +type Info interface { + // Human-readable type for key listing + GetType() string + // Name of the key + GetName() string + // Public key + GetPubKey() crypto.PubKey +} + +var _ Info = &localInfo{} +var _ Info = &ledgerInfo{} +var _ Info = &offlineInfo{} + +// localInfo is the public information about a locally stored key +type localInfo struct { Name string `json:"name"` PubKey crypto.PubKey `json:"pubkey"` PrivKeyArmor string `json:"privkey.armor"` } -func newInfo(name string, pub crypto.PubKey, privArmor string) Info { - return Info{ +func newLocalInfo(name string, pub crypto.PubKey, privArmor string) Info { + return &localInfo{ Name: name, PubKey: pub, PrivKeyArmor: privArmor, } } -// Address is a helper function to calculate the address from the pubkey -func (i Info) Address() []byte { - return i.PubKey.Address() +func (i localInfo) GetType() string { + return "local" } -func (i Info) bytes() []byte { - bz, err := cdc.MarshalBinaryBare(i) - if err != nil { - panic(err) +func (i localInfo) GetName() string { + return i.Name +} + +func (i localInfo) GetPubKey() crypto.PubKey { + return i.PubKey +} + +// ledgerInfo is the public information about a Ledger key +type ledgerInfo struct { + Name string `json:"name"` + PubKey crypto.PubKey `json:"pubkey"` + Path crypto.DerivationPath `json:"path"` +} + +func newLedgerInfo(name string, pub crypto.PubKey, path crypto.DerivationPath) Info { + return &ledgerInfo{ + Name: name, + PubKey: pub, + Path: path, + } +} + +func (i ledgerInfo) GetType() string { + return "ledger" +} + +func (i ledgerInfo) GetName() string { + return i.Name +} + +func (i ledgerInfo) GetPubKey() crypto.PubKey { + return i.PubKey +} + +// offlineInfo is the public information about an offline key +type offlineInfo struct { + Name string `json:"name"` + PubKey crypto.PubKey `json:"pubkey"` +} + +func newOfflineInfo(name string, pub crypto.PubKey) Info { + return &offlineInfo{ + Name: name, + PubKey: pub, } - return bz } +func (i offlineInfo) GetType() string { + return "offline" +} + +func (i offlineInfo) GetName() string { + return i.Name +} + +func (i offlineInfo) GetPubKey() crypto.PubKey { + return i.PubKey +} + +// encoding info +func writeInfo(i Info) []byte { + return cdc.MustMarshalBinary(i) +} + +// decoding info func readInfo(bz []byte) (info Info, err error) { - err = cdc.UnmarshalBinaryBare(bz, &info) + err = cdc.UnmarshalBinary(bz, &info) return } diff --git a/keys/wire.go b/keys/wire.go index 7deaad673..7cde0dd45 100644 --- a/keys/wire.go +++ b/keys/wire.go @@ -9,4 +9,8 @@ var cdc = amino.NewCodec() func init() { crypto.RegisterAmino(cdc) + cdc.RegisterInterface((*Info)(nil), nil) + cdc.RegisterConcrete(localInfo{}, "crypto/keys/localInfo", nil) + cdc.RegisterConcrete(ledgerInfo{}, "crypto/keys/ledgerInfo", nil) + cdc.RegisterConcrete(offlineInfo{}, "crypto/keys/offlineInfo", nil) } diff --git a/ledger_secp256k1.go b/ledger_secp256k1.go index f485bb415..1a7887ad3 100644 --- a/ledger_secp256k1.go +++ b/ledger_secp256k1.go @@ -73,11 +73,7 @@ func (pk *PrivKeyLedgerSecp256k1) AssertIsPrivKeyInner() {} // Bytes fulfils PrivKey Interface - but it stores the cached pubkey so we can verify // the same key when we reconnect to a ledger func (pk PrivKeyLedgerSecp256k1) Bytes() []byte { - bin, err := cdc.MarshalBinaryBare(pk) - if err != nil { - panic(err) - } - return bin + return cdc.MustMarshalBinaryBare(pk) } // Sign calls the ledger and stores the PubKey for future use @@ -85,39 +81,34 @@ func (pk PrivKeyLedgerSecp256k1) Bytes() []byte { // Communication is checked on NewPrivKeyLedger and PrivKeyFromBytes, // returning an error, so this should only trigger if the privkey is held // in memory for a while before use. -func (pk PrivKeyLedgerSecp256k1) Sign(msg []byte) Signature { - // oh, I wish there was better error handling +func (pk PrivKeyLedgerSecp256k1) Sign(msg []byte) (Signature, error) { dev, err := getLedger() if err != nil { - panic(err) + return nil, err } sig, err := signLedgerSecp256k1(dev, pk.Path, msg) if err != nil { - panic(err) + return nil, err } pub, err := pubkeyLedgerSecp256k1(dev, pk.Path) if err != nil { - panic(err) + return nil, err } // if we have no pubkey yet, store it for future queries if pk.CachedPubKey == nil { pk.CachedPubKey = pub } else if !pk.CachedPubKey.Equals(pub) { - panic("stored key does not match signing key") + return nil, fmt.Errorf("stored key does not match signing key") } - return sig + return sig, nil } // PubKey returns the stored PubKey -func (pk PrivKeyLedgerSecp256k1) PubKey() PubKey { - key, err := pk.getPubKey() - if err != nil { - panic(err) - } - return key +func (pk PrivKeyLedgerSecp256k1) PubKey() (PubKey, error) { + return pk.getPubKey() } // getPubKey reads the pubkey from cache or from the ledger itself diff --git a/ledger_test.go b/ledger_test.go index dda3d3d3d..4a7ae46e4 100644 --- a/ledger_test.go +++ b/ledger_test.go @@ -19,8 +19,10 @@ func TestRealLedgerSecp256k1(t *testing.T) { priv, err := NewPrivKeyLedgerSecp256k1(path) require.Nil(t, err, "%+v", err) - pub := priv.PubKey() - sig := priv.Sign(msg) + pub, err := priv.PubKey() + require.Nil(t, err) + sig, err := priv.Sign(msg) + require.Nil(t, err) valid := pub.VerifyBytes(msg, sig) assert.True(t, valid) @@ -31,11 +33,13 @@ func TestRealLedgerSecp256k1(t *testing.T) { require.Nil(t, err, "%+v", err) // make sure we get the same pubkey when we load from disk - pub2 := priv2.PubKey() + pub2, err := priv2.PubKey() + require.Nil(t, err) require.Equal(t, pub, pub2) // signing with the loaded key should match the original pubkey - sig = priv2.Sign(msg) + sig, err = priv2.Sign(msg) + require.Nil(t, err) valid = pub.VerifyBytes(msg, sig) assert.True(t, valid) diff --git a/priv_key.go b/priv_key.go index 82e1cfced..2c06f3452 100644 --- a/priv_key.go +++ b/priv_key.go @@ -6,7 +6,6 @@ import ( secp256k1 "github.com/btcsuite/btcd/btcec" "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" - . "github.com/tendermint/tmlibs/common" ) func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { @@ -18,8 +17,8 @@ func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { type PrivKey interface { Bytes() []byte - Sign(msg []byte) Signature - PubKey() PubKey + Sign(msg []byte) (Signature, error) + PubKey() (PubKey, error) Equals(PrivKey) bool } @@ -31,23 +30,19 @@ var _ PrivKey = PrivKeyEd25519{} type PrivKeyEd25519 [64]byte func (privKey PrivKeyEd25519) Bytes() []byte { - bz, err := cdc.MarshalBinaryBare(privKey) - if err != nil { - panic(err) - } - return bz + return cdc.MustMarshalBinaryBare(privKey) } -func (privKey PrivKeyEd25519) Sign(msg []byte) Signature { +func (privKey PrivKeyEd25519) Sign(msg []byte) (Signature, error) { privKeyBytes := [64]byte(privKey) signatureBytes := ed25519.Sign(&privKeyBytes, msg) - return SignatureEd25519(*signatureBytes) + return SignatureEd25519(*signatureBytes), nil } -func (privKey PrivKeyEd25519) PubKey() PubKey { +func (privKey PrivKeyEd25519) PubKey() (PubKey, error) { privKeyBytes := [64]byte(privKey) pubBytes := *ed25519.MakePublicKey(&privKeyBytes) - return PubKeyEd25519(pubBytes) + return PubKeyEd25519(pubBytes), nil } // Equals - you probably don't need to use this. @@ -67,12 +62,6 @@ func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte { return keyCurve25519 } -/* -func (privKey PrivKeyEd25519) String() string { - return Fmt("PrivKeyEd25519{*****}") -} -*/ - // Deterministically generates new priv-key bytes from key. func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519 { bz, err := cdc.MarshalBinaryBare(struct { @@ -114,27 +103,23 @@ var _ PrivKey = PrivKeySecp256k1{} type PrivKeySecp256k1 [32]byte func (privKey PrivKeySecp256k1) Bytes() []byte { - bz, err := cdc.MarshalBinaryBare(privKey) - if err != nil { - panic(err) - } - return bz + return cdc.MustMarshalBinaryBare(privKey) } -func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature { +func (privKey PrivKeySecp256k1) Sign(msg []byte) (Signature, error) { priv__, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) sig__, err := priv__.Sign(Sha256(msg)) if err != nil { - PanicSanity(err) + return nil, err } - return SignatureSecp256k1(sig__.Serialize()) + return SignatureSecp256k1(sig__.Serialize()), nil } -func (privKey PrivKeySecp256k1) PubKey() PubKey { +func (privKey PrivKeySecp256k1) PubKey() (PubKey, error) { _, pub__ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) var pub PubKeySecp256k1 copy(pub[:], pub__.SerializeCompressed()) - return pub + return pub, nil } // Equals - you probably don't need to use this. @@ -147,12 +132,6 @@ func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool { } } -/* -func (privKey PrivKeySecp256k1) String() string { - return Fmt("PrivKeySecp256k1{*****}") -} -*/ - /* // Deterministically generates new priv-key bytes from key. func (key PrivKeySecp256k1) Generate(index int) PrivKeySecp256k1 { diff --git a/priv_key_test.go b/priv_key_test.go index 6abe36ac5..33f3eb7ee 100644 --- a/priv_key_test.go +++ b/priv_key_test.go @@ -11,7 +11,11 @@ func TestGeneratePrivKey(t *testing.T) { testPriv := crypto.GenPrivKeyEd25519() testGenerate := testPriv.Generate(1) signBytes := []byte("something to sign") - assert.True(t, testGenerate.PubKey().VerifyBytes(signBytes, testGenerate.Sign(signBytes))) + pub, err := testGenerate.PubKey() + assert.NoError(t, err) + sig, err := testGenerate.Sign(signBytes) + assert.NoError(t, err) + assert.True(t, pub.VerifyBytes(signBytes, sig)) } /* diff --git a/pub_key_test.go b/pub_key_test.go index 29672390b..35c78a46a 100644 --- a/pub_key_test.go +++ b/pub_key_test.go @@ -33,9 +33,11 @@ func TestPubKeySecp256k1Address(t *testing.T) { var priv PrivKeySecp256k1 copy(priv[:], privB) - pubT := priv.PubKey().(PubKeySecp256k1) + pubKey, err := priv.PubKey() + assert.NoError(t, err) + pubT, _ := pubKey.(PubKeySecp256k1) pub := pubT[:] - addr := priv.PubKey().Address() + addr := pubKey.Address() assert.Equal(t, pub, pubB, "Expected pub keys to match") assert.Equal(t, addr, addrB, "Expected addresses to match") diff --git a/signature_test.go b/signature_test.go index 0ba44ded5..52da65572 100644 --- a/signature_test.go +++ b/signature_test.go @@ -12,10 +12,12 @@ import ( func TestSignAndValidateEd25519(t *testing.T) { privKey := GenPrivKeyEd25519() - pubKey := privKey.PubKey() + pubKey, err := privKey.PubKey() + require.Nil(t, err) msg := CRandBytes(128) - sig := privKey.Sign(msg) + sig, err := privKey.Sign(msg) + require.Nil(t, err) // Test the signature assert.True(t, pubKey.VerifyBytes(msg, sig)) @@ -30,10 +32,12 @@ func TestSignAndValidateEd25519(t *testing.T) { func TestSignAndValidateSecp256k1(t *testing.T) { privKey := GenPrivKeySecp256k1() - pubKey := privKey.PubKey() + pubKey, err := privKey.PubKey() + require.Nil(t, err) msg := CRandBytes(128) - sig := privKey.Sign(msg) + sig, err := privKey.Sign(msg) + require.Nil(t, err) assert.True(t, pubKey.VerifyBytes(msg, sig)) @@ -65,10 +69,12 @@ func TestSignatureEncodings(t *testing.T) { for _, tc := range cases { // note we embed them from the beginning.... - pubKey := tc.privKey.PubKey() + pubKey, err := tc.privKey.PubKey() + require.Nil(t, err) msg := CRandBytes(128) - sig := tc.privKey.Sign(msg) + sig, err := tc.privKey.Sign(msg) + require.Nil(t, err) // store as amino bin, err := cdc.MarshalBinaryBare(sig) From 66794a174ac0f0a03235ba1348321e247f391822 Mon Sep 17 00:00:00 2001 From: Joon Date: Sun, 10 Jun 2018 20:43:40 -0700 Subject: [PATCH 260/287] Move from tmlibs #213 (#115) * move from tmlibs 213 * expose KVPair, simpleproofsfrommap returns keys --- merkle/simple_map.go | 13 +++++-------- merkle/simple_map_test.go | 12 ++++++------ merkle/simple_proof.go | 14 +++++++++++--- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/merkle/simple_map.go b/merkle/simple_map.go index cde5924f4..24863267b 100644 --- a/merkle/simple_map.go +++ b/merkle/simple_map.go @@ -24,16 +24,13 @@ func newSimpleMap() *simpleMap { func (sm *simpleMap) Set(key string, value Hasher) { sm.sorted = false - // Hash the key to blind it... why not? - khash := tmhash.Sum([]byte(key)) - - // And the value is hashed too, so you can + // The value is hashed, so you can // check for equality with a cached value (say) // and make a determination to fetch or not. vhash := value.Hash() sm.kvs = append(sm.kvs, cmn.KVPair{ - Key: khash, + Key: []byte(key), Value: vhash, }) } @@ -67,9 +64,9 @@ func (sm *simpleMap) KVPairs() cmn.KVPairs { // A local extension to KVPair that can be hashed. // Key and value are length prefixed and concatenated, // then hashed. -type kvPair cmn.KVPair +type KVPair cmn.KVPair -func (kv kvPair) Hash() []byte { +func (kv KVPair) Hash() []byte { hasher := tmhash.New() err := encodeByteSlice(hasher, kv.Key) if err != nil { @@ -85,7 +82,7 @@ func (kv kvPair) Hash() []byte { func hashKVPairs(kvs cmn.KVPairs) []byte { kvsH := make([]Hasher, len(kvs)) for i, kvp := range kvs { - kvsH[i] = kvPair(kvp) + kvsH[i] = KVPair(kvp) } return SimpleHashFromHashers(kvsH) } diff --git a/merkle/simple_map_test.go b/merkle/simple_map_test.go index a89289a8f..d9d635115 100644 --- a/merkle/simple_map_test.go +++ b/merkle/simple_map_test.go @@ -18,37 +18,37 @@ func TestSimpleMap(t *testing.T) { { db := newSimpleMap() db.Set("key1", strHasher("value1")) - assert.Equal(t, "3dafc06a52039d029be57c75c9d16356a4256ef4", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + assert.Equal(t, "fa9bc106ffd932d919bee935ceb6cf2b3dd72d8f", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } { db := newSimpleMap() db.Set("key1", strHasher("value2")) - assert.Equal(t, "03eb5cfdff646bc4e80fec844e72fd248a1c6b2c", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + assert.Equal(t, "e00e7dcfe54e9fafef5111e813a587f01ba9c3e8", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } { db := newSimpleMap() db.Set("key1", strHasher("value1")) db.Set("key2", strHasher("value2")) - assert.Equal(t, "acc3971eab8513171cc90ce8b74f368c38f9657d", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + assert.Equal(t, "eff12d1c703a1022ab509287c0f196130123d786", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } { db := newSimpleMap() db.Set("key2", strHasher("value2")) // NOTE: out of order db.Set("key1", strHasher("value1")) - assert.Equal(t, "acc3971eab8513171cc90ce8b74f368c38f9657d", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + assert.Equal(t, "eff12d1c703a1022ab509287c0f196130123d786", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } { db := newSimpleMap() db.Set("key1", strHasher("value1")) db.Set("key2", strHasher("value2")) db.Set("key3", strHasher("value3")) - assert.Equal(t, "0cd117ad14e6cd22edcd9aa0d84d7063b54b862f", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + assert.Equal(t, "b2c62a277c08dbd2ad73ca53cd1d6bfdf5830d26", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } { db := newSimpleMap() db.Set("key2", strHasher("value2")) // NOTE: out of order db.Set("key1", strHasher("value1")) db.Set("key3", strHasher("value3")) - assert.Equal(t, "0cd117ad14e6cd22edcd9aa0d84d7063b54b862f", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") + assert.Equal(t, "b2c62a277c08dbd2ad73ca53cd1d6bfdf5830d26", fmt.Sprintf("%x", db.Hash()), "Hash didn't match") } } diff --git a/merkle/simple_proof.go b/merkle/simple_proof.go index f52d1ad9f..2541b6d38 100644 --- a/merkle/simple_proof.go +++ b/merkle/simple_proof.go @@ -27,7 +27,7 @@ func SimpleProofsFromHashers(items []Hasher) (rootHash []byte, proofs []*SimpleP // SimpleProofsFromMap generates proofs from a map. The keys/values of the map will be used as the keys/values // in the underlying key-value pairs. // The keys are sorted before the proofs are computed. -func SimpleProofsFromMap(m map[string]Hasher) (rootHash []byte, proofs []*SimpleProof) { +func SimpleProofsFromMap(m map[string]Hasher) (rootHash []byte, proofs map[string]*SimpleProof, keys []string) { sm := newSimpleMap() for k, v := range m { sm.Set(k, v) @@ -36,9 +36,17 @@ func SimpleProofsFromMap(m map[string]Hasher) (rootHash []byte, proofs []*Simple kvs := sm.kvs kvsH := make([]Hasher, 0, len(kvs)) for _, kvp := range kvs { - kvsH = append(kvsH, kvPair(kvp)) + kvsH = append(kvsH, KVPair(kvp)) } - return SimpleProofsFromHashers(kvsH) + + rootHash, proofList := SimpleProofsFromHashers(kvsH) + proofs = make(map[string]*SimpleProof) + keys = make([]string, len(proofList)) + for i, kvp := range kvs { + proofs[string(kvp.Key)] = proofList[i] + keys[i] = string(kvp.Key) + } + return } // Verify that leafHash is a leaf hash of the simple-merkle-tree From e694c309ba2ad13dfac65c3f0fdd1efb535b27c5 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 11 Jun 2018 15:43:32 -0700 Subject: [PATCH 261/287] update ed25519 address scheme (#112) make PubKeyEd25519.Address() returns the first 20 bytes of the hash of the raw 32-byte pubkey, no amino required --- pub_key.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/pub_key.go b/pub_key.go index 9be64acdf..c509ff8de 100644 --- a/pub_key.go +++ b/pub_key.go @@ -5,11 +5,16 @@ import ( "crypto/sha256" "fmt" + "golang.org/x/crypto/ripemd160" + secp256k1 "github.com/btcsuite/btcd/btcec" + "github.com/tendermint/ed25519" "github.com/tendermint/ed25519/extra25519" + cmn "github.com/tendermint/tmlibs/common" - "golang.org/x/crypto/ripemd160" + + "github.com/tendermint/go-crypto/tmhash" ) // An address is a []byte, but hex-encoded even in JSON. @@ -38,11 +43,9 @@ var _ PubKey = PubKeyEd25519{} // Implements PubKeyInner type PubKeyEd25519 [32]byte +// Address is the SHA256-20 of the raw pubkey bytes. func (pubKey PubKeyEd25519) Address() Address { - // append type byte - hasher := ripemd160.New() - hasher.Write(pubKey.Bytes()) // does not error - return Address(hasher.Sum(nil)) + return Address(tmhash.Sum(pubKey[:])) } func (pubKey PubKeyEd25519) Bytes() []byte { From 45a1c8aef36641b5020098dac004675a1c8fbfd4 Mon Sep 17 00:00:00 2001 From: Liamsi Date: Mon, 11 Jun 2018 16:23:34 -0700 Subject: [PATCH 262/287] fix tests, move encoding to encode_test.go, include an example --- Gopkg.lock | 11 +++++--- Gopkg.toml | 2 +- encode_test.go | 13 ++++++++++ signature_test.go | 65 ----------------------------------------------- 4 files changed, 21 insertions(+), 70 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index f52af5591..2bcf5cdd5 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -128,15 +128,16 @@ [[projects]] name = "github.com/tendermint/go-amino" packages = ["."] - revision = "42246108ff925a457fb709475070a03dfd3e2b5c" - version = "0.9.6" + revision = "1715b7b78c65d6adcc5937315be4710234cefe09" + version = "0.10.0-rc2" [[projects]] name = "github.com/tendermint/tmlibs" packages = [ "common", "db", - "log" + "log", + "test" ] revision = "2e24b64fc121dcdf1cabceab8dc2f7257675483c" version = "v0.8.1" @@ -153,6 +154,8 @@ packages = [ "bcrypt", "blowfish", + "chacha20poly1305", + "internal/chacha20", "nacl/secretbox", "openpgp/armor", "openpgp/errors", @@ -166,6 +169,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "f9ccfa2cadfcbfb43bf729b871a0ad2f8d4f4acb118cd859e6faf9b24842b840" + inputs-digest = "b34cf043cab77178eebff1b7cfce8b31b6c2b6b3318c6d01add271b68f550345" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 4ccb8c07d..5761cf69f 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -47,7 +47,7 @@ [[constraint]] name = "github.com/tendermint/go-amino" - version = "0.9.6" + version = "0.10.0-rc2" [[constraint]] name = "github.com/tendermint/tmlibs" diff --git a/encode_test.go b/encode_test.go index 0bd450829..99ff17d43 100644 --- a/encode_test.go +++ b/encode_test.go @@ -1,6 +1,7 @@ package crypto import ( + "os" "testing" "github.com/stretchr/testify/assert" @@ -41,6 +42,18 @@ func checkAminoJSON(t *testing.T, src interface{}, dst interface{}, isNil bool) require.Nil(t, err, "%+v", err) } +func ExamplePrintRegisteredTypes() { + cdc.PrintTypes(os.Stdout) + // Output: | Type | Name | Prefix | Length | Notes | + //| ---- | ---- | ------ | ----- | ------ | + //| PubKeyEd25519 | tendermint/PubKeyEd25519 | 0x1624DE64 | 0x20 | | + //| PubKeySecp256k1 | tendermint/PubKeySecp256k1 | 0xEB5AE987 | 0x21 | | + //| PrivKeyEd25519 | tendermint/PrivKeyEd25519 | 0xA3288910 | 0x40 | | + //| PrivKeySecp256k1 | tendermint/PrivKeySecp256k1 | 0xE1B0F79B | 0x20 | | + //| SignatureEd25519 | tendermint/SignatureEd25519 | 0x2031EA53 | 0x40 | | + //| SignatureSecp256k1 | tendermint/SignatureSecp256k1 | 0x7FC4A495 | variable | | +} + func TestKeyEncodings(t *testing.T) { cases := []struct { privKey PrivKey diff --git a/signature_test.go b/signature_test.go index 0ba44ded5..3b1d74ad3 100644 --- a/signature_test.go +++ b/signature_test.go @@ -4,9 +4,6 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/tendermint/ed25519" - amino "github.com/tendermint/go-amino" ) func TestSignAndValidateEd25519(t *testing.T) { @@ -44,65 +41,3 @@ func TestSignAndValidateSecp256k1(t *testing.T) { assert.False(t, pubKey.VerifyBytes(msg, sig)) } - -func TestSignatureEncodings(t *testing.T) { - cases := []struct { - privKey PrivKey - sigSize int - sigPrefix amino.PrefixBytes - }{ - { - privKey: GenPrivKeyEd25519(), - sigSize: ed25519.SignatureSize, - sigPrefix: [4]byte{0x3d, 0xa1, 0xdb, 0x2a}, - }, - { - privKey: GenPrivKeySecp256k1(), - sigSize: 0, // unknown - sigPrefix: [4]byte{0x16, 0xe1, 0xfe, 0xea}, - }, - } - - for _, tc := range cases { - // note we embed them from the beginning.... - pubKey := tc.privKey.PubKey() - - msg := CRandBytes(128) - sig := tc.privKey.Sign(msg) - - // store as amino - bin, err := cdc.MarshalBinaryBare(sig) - require.Nil(t, err, "%+v", err) - if tc.sigSize != 0 { - // Q: where is 1 byte coming from? - assert.Equal(t, tc.sigSize+amino.PrefixBytesLen+1, len(bin)) - } - assert.Equal(t, tc.sigPrefix[:], bin[0:amino.PrefixBytesLen]) - - // and back - sig2 := Signature(nil) - err = cdc.UnmarshalBinaryBare(bin, &sig2) - require.Nil(t, err, "%+v", err) - assert.EqualValues(t, sig, sig2) - assert.True(t, pubKey.VerifyBytes(msg, sig2)) - - /* - // store as json - js, err := data.ToJSON(sig) - require.Nil(t, err, "%+v", err) - assert.True(t, strings.Contains(string(js), tc.sigName)) - - // and back - sig3 := Signature{} - err = data.FromJSON(js, &sig3) - require.Nil(t, err, "%+v", err) - assert.EqualValues(t, sig, sig3) - assert.True(t, pubKey.VerifyBytes(msg, sig3)) - - // and make sure we can textify it - text, err := data.ToText(sig) - require.Nil(t, err, "%+v", err) - assert.True(t, strings.HasPrefix(text, tc.sigName)) - */ - } -} From f4663e5bb790065f4b730d873fb02fef5fed2ca1 Mon Sep 17 00:00:00 2001 From: Liamsi Date: Mon, 11 Jun 2018 16:37:14 -0700 Subject: [PATCH 263/287] fix tests, bump amino version, move encoding to encode_test.go, include an example, do not err check on info ... bur for empty info instead --- keys/keybase_test.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/keys/keybase_test.go b/keys/keybase_test.go index aaf3b92fb..820add7b9 100644 --- a/keys/keybase_test.go +++ b/keys/keybase_test.go @@ -33,9 +33,9 @@ func TestKeyManagement(t *testing.T) { assert.Empty(t, l) // create some keys - _, err = cstore.Get(n1) - assert.NotNil(t, err) - i, _, err := cstore.Create(n1, p1, algo) + i, err := cstore.Get(n1) + assert.Equal(t, i, keys.Info{}) + i, _, err = cstore.Create(n1, p1, algo) require.Equal(t, n1, i.Name) require.Nil(t, err) _, _, err = cstore.Create(n2, p2, algo) @@ -44,8 +44,8 @@ func TestKeyManagement(t *testing.T) { // we can get these keys i2, err := cstore.Get(n2) assert.Nil(t, err) - _, err = cstore.Get(n3) - assert.NotNil(t, err) + i, err = cstore.Get(n3) + assert.Equal(t, i, keys.Info{}) // list shows them in order keyS, err := cstore.List() @@ -64,8 +64,8 @@ func TestKeyManagement(t *testing.T) { keyS, err = cstore.List() require.Nil(t, err) assert.Equal(t, 1, len(keyS)) - _, err = cstore.Get(n1) - assert.NotNil(t, err) + i, err = cstore.Get(n1) + assert.Equal(t, i, keys.Info{}) // make sure that it only signs with the right password // tx := mock.NewSig([]byte("mytransactiondata")) @@ -370,8 +370,8 @@ func TestSeedPhrase(t *testing.T) { // now, let us delete this key err = cstore.Delete(n1, p1) require.Nil(t, err, "%+v", err) - _, err = cstore.Get(n1) - require.NotNil(t, err) + i, err := cstore.Get(n1) + require.Equal(t, i, keys.Info{}, "expected empty info") // let us re-create it from the seed-phrase newInfo, err := cstore.Recover(n2, p2, seed) From e552d344e3551b7382f42c216118c6c302a31dd8 Mon Sep 17 00:00:00 2001 From: Liamsi Date: Mon, 11 Jun 2018 16:51:38 -0700 Subject: [PATCH 264/287] forgot PrivKeyLedgerSecp256k1 --- encode_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/encode_test.go b/encode_test.go index fa9465ddd..ed5395db8 100644 --- a/encode_test.go +++ b/encode_test.go @@ -50,6 +50,7 @@ func ExamplePrintRegisteredTypes() { //| PubKeySecp256k1 | tendermint/PubKeySecp256k1 | 0xEB5AE987 | 0x21 | | //| PrivKeyEd25519 | tendermint/PrivKeyEd25519 | 0xA3288910 | 0x40 | | //| PrivKeySecp256k1 | tendermint/PrivKeySecp256k1 | 0xE1B0F79B | 0x20 | | + //| PrivKeyLedgerSecp256k1 | tendermint/PrivKeyLedgerSecp256k1 | 0x10CAB393 | variable | | //| SignatureEd25519 | tendermint/SignatureEd25519 | 0x2031EA53 | 0x40 | | //| SignatureSecp256k1 | tendermint/SignatureSecp256k1 | 0x7FC4A495 | variable | | } From 42c6a64e0421c149de4733a14884c0ca4be7d6d5 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Mon, 11 Jun 2018 17:27:32 -0700 Subject: [PATCH 265/287] version bump (#128) version bump --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 57806e26c..77c0bed8a 100644 --- a/version.go +++ b/version.go @@ -1,3 +1,3 @@ package crypto -const Version = "0.8.0-dev" +const Version = "0.9.0-dev" From 8e273220a35e200caa63ad6d1fbe5a91a49b45e2 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 12 Jun 2018 22:35:22 +0200 Subject: [PATCH 266/287] Remove error from priv.PubKey() (#131) * Remove error from priv.PubKey() * Update changelog --- CHANGELOG.md | 6 ++++++ Gopkg.lock | 8 ++++---- encode_test.go | 3 +-- keys/keybase.go | 15 +++------------ keys/keybase_test.go | 3 +-- ledger_secp256k1.go | 42 ++++++++++-------------------------------- ledger_test.go | 6 ++---- priv_key.go | 10 +++++----- priv_key_test.go | 3 +-- pub_key_test.go | 3 +-- signature_test.go | 8 +++----- 11 files changed, 37 insertions(+), 70 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c31551b5..dd7c1039f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.9.0 + +BREAKING CHANGES + +- `priv.PubKey()` no longer returns an error. Any applicable errors (such as when fetching the public key from a hardware wallet) should be checked and returned when constructing the private key. + ## 0.8.0 **TBD** diff --git a/Gopkg.lock b/Gopkg.lock index a475c6656..fbfd54dcf 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -99,8 +99,8 @@ "assert", "require" ] - revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" - version = "v1.2.1" + revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686" + version = "v1.2.2" [[projects]] branch = "master" @@ -181,11 +181,11 @@ branch = "master" name = "golang.org/x/sys" packages = ["cpu"] - revision = "9527bec2660bd847c050fda93a0f0c6dee0800bb" + revision = "a9e25c09b96b8870693763211309e213c6ef299d" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "f20e34cd998442d4ffe2f9aa45ab87a55ba6e4cd19f29009adaadac3b5dccf26" + inputs-digest = "1731880d432026bbd22865582cf7c7dd6d5c65618149de586e30ce156d338c01" solver-name = "gps-cdcl" solver-version = 1 diff --git a/encode_test.go b/encode_test.go index ed5395db8..025b09c80 100644 --- a/encode_test.go +++ b/encode_test.go @@ -91,8 +91,7 @@ func TestKeyEncodings(t *testing.T) { assert.EqualValues(t, sig1, sig3) // Check (de/en)codings of PubKeys. - pubKey, err := tc.privKey.PubKey() - assert.NoError(t, err) + pubKey := tc.privKey.PubKey() var pub2, pub3 PubKey checkAminoBinary(t, pubKey, &pub2, tc.pubSize) assert.EqualValues(t, pubKey, pub2) diff --git a/keys/keybase.go b/keys/keybase.go index 39a3de59e..79e6f15fa 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -68,10 +68,7 @@ func (kb dbKeybase) CreateLedger(name string, path crypto.DerivationPath, algo S if err != nil { return nil, err } - pub, err := priv.PubKey() - if err != nil { - return nil, err - } + pub := priv.PubKey() return kb.writeLedgerKey(pub, path, name), nil } @@ -169,10 +166,7 @@ func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signat if err != nil { return nil, nil, err } - pub, err = priv.PubKey() - if err != nil { - return nil, nil, err - } + pub = priv.PubKey() return sig, pub, nil } @@ -290,10 +284,7 @@ func (kb dbKeybase) writeLocalKey(priv crypto.PrivKey, name, passphrase string) // encrypt private key using passphrase privArmor := encryptArmorPrivKey(priv, passphrase) // make Info - pub, err := priv.PubKey() - if err != nil { - panic(err) - } + pub := priv.PubKey() info := newLocalInfo(name, pub, privArmor) kb.writeInfo(info, name) return info diff --git a/keys/keybase_test.go b/keys/keybase_test.go index 3627626cb..5caf82af8 100644 --- a/keys/keybase_test.go +++ b/keys/keybase_test.go @@ -70,8 +70,7 @@ func TestKeyManagement(t *testing.T) { // create an offline key o1 := "offline" priv1 := crypto.GenPrivKeyEd25519() - pub1, err := priv1.PubKey() - require.Nil(t, err) + pub1 := priv1.PubKey() i, err = cstore.CreateOffline(o1, pub1) require.Nil(t, err) require.Equal(t, pub1, i.GetPubKey()) diff --git a/ledger_secp256k1.go b/ledger_secp256k1.go index 1a7887ad3..21dfbb8b5 100644 --- a/ledger_secp256k1.go +++ b/ledger_secp256k1.go @@ -44,10 +44,12 @@ type PrivKeyLedgerSecp256k1 struct { func NewPrivKeyLedgerSecp256k1(path DerivationPath) (PrivKey, error) { var pk PrivKeyLedgerSecp256k1 pk.Path = path - // getPubKey will cache the pubkey for later use, - // this allows us to return an error early if the ledger - // is not plugged in - _, err := pk.getPubKey() + // cache the pubkey for later use + pubKey, err := pk.getPubKey() + if err != nil { + return nil, err + } + pk.CachedPubKey = pubKey return &pk, err } @@ -55,8 +57,7 @@ func NewPrivKeyLedgerSecp256k1(path DerivationPath) (PrivKey, error) { // after loading it from disk func (pk PrivKeyLedgerSecp256k1) ValidateKey() error { // getPubKey will return an error if the ledger is not - // properly set up... - pub, err := pk.forceGetPubKey() + pub, err := pk.getPubKey() if err != nil { return err } @@ -86,45 +87,22 @@ func (pk PrivKeyLedgerSecp256k1) Sign(msg []byte) (Signature, error) { if err != nil { return nil, err } - sig, err := signLedgerSecp256k1(dev, pk.Path, msg) if err != nil { return nil, err } - - pub, err := pubkeyLedgerSecp256k1(dev, pk.Path) - if err != nil { - return nil, err - } - - // if we have no pubkey yet, store it for future queries - if pk.CachedPubKey == nil { - pk.CachedPubKey = pub - } else if !pk.CachedPubKey.Equals(pub) { - return nil, fmt.Errorf("stored key does not match signing key") - } return sig, nil } // PubKey returns the stored PubKey -func (pk PrivKeyLedgerSecp256k1) PubKey() (PubKey, error) { - return pk.getPubKey() +func (pk PrivKeyLedgerSecp256k1) PubKey() PubKey { + return pk.CachedPubKey } -// getPubKey reads the pubkey from cache or from the ledger itself +// getPubKey reads the pubkey the ledger itself // since this involves IO, it may return an error, which is not exposed // in the PubKey interface, so this function allows better error handling func (pk PrivKeyLedgerSecp256k1) getPubKey() (key PubKey, err error) { - // if we have no pubkey, set it - if pk.CachedPubKey == nil { - pk.CachedPubKey, err = pk.forceGetPubKey() - } - return pk.CachedPubKey, err -} - -// forceGetPubKey is like getPubKey but ignores any cached key -// and ensures we get it from the ledger itself. -func (pk PrivKeyLedgerSecp256k1) forceGetPubKey() (key PubKey, err error) { dev, err := getLedger() if err != nil { return key, fmt.Errorf("cannot connect to Ledger device - error: %v", err) diff --git a/ledger_test.go b/ledger_test.go index 4a7ae46e4..83390cc36 100644 --- a/ledger_test.go +++ b/ledger_test.go @@ -19,8 +19,7 @@ func TestRealLedgerSecp256k1(t *testing.T) { priv, err := NewPrivKeyLedgerSecp256k1(path) require.Nil(t, err, "%+v", err) - pub, err := priv.PubKey() - require.Nil(t, err) + pub := priv.PubKey() sig, err := priv.Sign(msg) require.Nil(t, err) @@ -33,8 +32,7 @@ func TestRealLedgerSecp256k1(t *testing.T) { require.Nil(t, err, "%+v", err) // make sure we get the same pubkey when we load from disk - pub2, err := priv2.PubKey() - require.Nil(t, err) + pub2 := priv2.PubKey() require.Equal(t, pub, pub2) // signing with the loaded key should match the original pubkey diff --git a/priv_key.go b/priv_key.go index 2c06f3452..dbfe64c33 100644 --- a/priv_key.go +++ b/priv_key.go @@ -18,7 +18,7 @@ func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) { type PrivKey interface { Bytes() []byte Sign(msg []byte) (Signature, error) - PubKey() (PubKey, error) + PubKey() PubKey Equals(PrivKey) bool } @@ -39,10 +39,10 @@ func (privKey PrivKeyEd25519) Sign(msg []byte) (Signature, error) { return SignatureEd25519(*signatureBytes), nil } -func (privKey PrivKeyEd25519) PubKey() (PubKey, error) { +func (privKey PrivKeyEd25519) PubKey() PubKey { privKeyBytes := [64]byte(privKey) pubBytes := *ed25519.MakePublicKey(&privKeyBytes) - return PubKeyEd25519(pubBytes), nil + return PubKeyEd25519(pubBytes) } // Equals - you probably don't need to use this. @@ -115,11 +115,11 @@ func (privKey PrivKeySecp256k1) Sign(msg []byte) (Signature, error) { return SignatureSecp256k1(sig__.Serialize()), nil } -func (privKey PrivKeySecp256k1) PubKey() (PubKey, error) { +func (privKey PrivKeySecp256k1) PubKey() PubKey { _, pub__ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) var pub PubKeySecp256k1 copy(pub[:], pub__.SerializeCompressed()) - return pub, nil + return pub } // Equals - you probably don't need to use this. diff --git a/priv_key_test.go b/priv_key_test.go index 33f3eb7ee..c43a6d1b1 100644 --- a/priv_key_test.go +++ b/priv_key_test.go @@ -11,8 +11,7 @@ func TestGeneratePrivKey(t *testing.T) { testPriv := crypto.GenPrivKeyEd25519() testGenerate := testPriv.Generate(1) signBytes := []byte("something to sign") - pub, err := testGenerate.PubKey() - assert.NoError(t, err) + pub := testGenerate.PubKey() sig, err := testGenerate.Sign(signBytes) assert.NoError(t, err) assert.True(t, pub.VerifyBytes(signBytes, sig)) diff --git a/pub_key_test.go b/pub_key_test.go index 35c78a46a..7b856cf18 100644 --- a/pub_key_test.go +++ b/pub_key_test.go @@ -33,8 +33,7 @@ func TestPubKeySecp256k1Address(t *testing.T) { var priv PrivKeySecp256k1 copy(priv[:], privB) - pubKey, err := priv.PubKey() - assert.NoError(t, err) + pubKey := priv.PubKey() pubT, _ := pubKey.(PubKeySecp256k1) pub := pubT[:] addr := pubKey.Address() diff --git a/signature_test.go b/signature_test.go index 560815ccf..d6ae2b7a9 100644 --- a/signature_test.go +++ b/signature_test.go @@ -3,15 +3,14 @@ package crypto import ( "testing" - "github.com/stretchr/testify/require" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSignAndValidateEd25519(t *testing.T) { privKey := GenPrivKeyEd25519() - pubKey, err := privKey.PubKey() - require.Nil(t, err) + pubKey := privKey.PubKey() msg := CRandBytes(128) sig, err := privKey.Sign(msg) @@ -30,8 +29,7 @@ func TestSignAndValidateEd25519(t *testing.T) { func TestSignAndValidateSecp256k1(t *testing.T) { privKey := GenPrivKeySecp256k1() - pubKey, err := privKey.PubKey() - require.Nil(t, err) + pubKey := privKey.PubKey() msg := CRandBytes(128) sig, err := privKey.Sign(msg) From 41369d7529bb0f79a327446dd0d35e5fe162e711 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 14 Jun 2018 00:04:30 -0700 Subject: [PATCH 267/287] circleci 2.0 (#134) * circleci 2.0 --- .circleci/circle.yml | 25 +++++++++++++++++++++++++ circle.yml | 21 --------------------- 2 files changed, 25 insertions(+), 21 deletions(-) create mode 100644 .circleci/circle.yml delete mode 100644 circle.yml diff --git a/.circleci/circle.yml b/.circleci/circle.yml new file mode 100644 index 000000000..3fc8f0b64 --- /dev/null +++ b/.circleci/circle.yml @@ -0,0 +1,25 @@ +version: 2 + +jobs: + build: + working_directory: /go/src/github.com/tendermint/go-crypto + docker: + - image: circleci/golang:1.10.0 + environment: + GOBIN: /tmp/workspace/bin + steps: + - run: mkdir -p /tmp/workspace/bin + - run: mkdir -p /tmp/workspace/profiles + - checkout + - restore_cache: + keys: + - v1-dep-{{ .Branch }} + - run: + name: test + command: | + go version + cd $PROJECT_PATH && make get_tools && make all + - save_cache: + key: v1-dep-{{ .Branch }} + paths: + - /go/pkg diff --git a/circle.yml b/circle.yml deleted file mode 100644 index af63a0594..000000000 --- a/circle.yml +++ /dev/null @@ -1,21 +0,0 @@ -machine: - environment: - GOPATH: /home/ubuntu/.go_workspace - PROJECT_PARENT_PATH: "$GOPATH/src/github.com/$CIRCLE_PROJECT_USERNAME" - PROJECT_PATH: $GOPATH/src/github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME - GO15VENDOREXPERIMENT: 1 - hosts: - circlehost: 127.0.0.1 - localhost: 127.0.0.1 - -dependencies: - override: - - mkdir -p "$PROJECT_PARENT_PATH" - - ln -sf "$HOME/$CIRCLE_PROJECT_REPONAME/" "$PROJECT_PATH" - post: - - go version - -test: - override: - - "go version" - - "cd $PROJECT_PATH && make get_tools && make all" From 1a2f468695f9a57907cda7f018855ea7cc912175 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Fri, 15 Jun 2018 15:17:40 -0700 Subject: [PATCH 268/287] fix circleci 2.0 config (#139) --- .circleci/{circle.yml => config.yml} | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) rename .circleci/{circle.yml => config.yml} (56%) diff --git a/.circleci/circle.yml b/.circleci/config.yml similarity index 56% rename from .circleci/circle.yml rename to .circleci/config.yml index 3fc8f0b64..c0bab9eae 100644 --- a/.circleci/circle.yml +++ b/.circleci/config.yml @@ -1,12 +1,13 @@ version: 2 - jobs: build: - working_directory: /go/src/github.com/tendermint/go-crypto docker: - - image: circleci/golang:1.10.0 - environment: - GOBIN: /tmp/workspace/bin + - image: circleci/golang:1.10.3 + environment: + GOBIN: /tmp/workspace/bin + + working_directory: /go/src/github.com/tendermint/go-crypto + steps: - run: mkdir -p /tmp/workspace/bin - run: mkdir -p /tmp/workspace/profiles @@ -17,9 +18,11 @@ jobs: - run: name: test command: | + export PATH="$GOBIN:$PATH" + go env go version - cd $PROJECT_PATH && make get_tools && make all - - save_cache: - key: v1-dep-{{ .Branch }} - paths: - - /go/pkg + make get_tools && make all + - save_cache: + key: v1-dep-{{ .Branch }} + paths: + - /go/pkg From fed8807a32014d14d29af31a1e02a3880b11eac5 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Tue, 19 Jun 2018 22:18:36 -0700 Subject: [PATCH 269/287] Switch xchachapoly to hkdfchachapoly (#135) * Switch from xchachapoly to hkdfchachapoly --- Gopkg.lock | 3 +- hkdfchacha20poly1305/hkdfchachapoly.go | 105 +++++++++ hkdfchacha20poly1305/hkdfchachapoly_test.go | 139 ++++++++++++ xchacha20poly1305/xchachapoly.go | 238 -------------------- xchacha20poly1305/xchachapoly_test.go | 103 --------- 5 files changed, 246 insertions(+), 342 deletions(-) create mode 100644 hkdfchacha20poly1305/hkdfchachapoly.go create mode 100644 hkdfchacha20poly1305/hkdfchachapoly_test.go delete mode 100644 xchacha20poly1305/xchachapoly.go delete mode 100644 xchacha20poly1305/xchachapoly_test.go diff --git a/Gopkg.lock b/Gopkg.lock index fbfd54dcf..7d3bac984 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -166,6 +166,7 @@ "bcrypt", "blowfish", "chacha20poly1305", + "hkdf", "internal/chacha20", "nacl/secretbox", "openpgp/armor", @@ -186,6 +187,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "1731880d432026bbd22865582cf7c7dd6d5c65618149de586e30ce156d338c01" + inputs-digest = "684746f2b651a722ee32eae056b437baf7a2213d68ddbfcefe04a1c3df27c93b" solver-name = "gps-cdcl" solver-version = 1 diff --git a/hkdfchacha20poly1305/hkdfchachapoly.go b/hkdfchacha20poly1305/hkdfchachapoly.go new file mode 100644 index 000000000..ab3b9df3a --- /dev/null +++ b/hkdfchacha20poly1305/hkdfchachapoly.go @@ -0,0 +1,105 @@ +// Package hkdfchacha20poly1305 creates an AEAD using hkdf, chacha20, and poly1305 +// When sealing and opening, the hkdf is used to obtain the nonce and subkey for +// chacha20. Other than the change for the how the subkey and nonce for chacha +// are obtained, this is the same as chacha20poly1305 +package hkdfchacha20poly1305 + +import ( + "crypto/cipher" + "crypto/sha256" + "errors" + "io" + + "golang.org/x/crypto/chacha20poly1305" + "golang.org/x/crypto/hkdf" +) + +type hkdfchacha20poly1305 struct { + key [KeySize]byte +} + +const ( + // KeySize is the size of the key used by this AEAD, in bytes. + KeySize = 32 + // NonceSize is the size of the nonce used with this AEAD, in bytes. + NonceSize = 24 + // TagSize is the size added from poly1305 + TagSize = 16 + // MaxPlaintextSize is the max size that can be passed into a single call of Seal + MaxPlaintextSize = (1 << 38) - 64 + // MaxCiphertextSize is the max size that can be passed into a single call of Open, + // this differs from plaintext size due to the tag + MaxCiphertextSize = (1 << 38) - 48 + // HkdfInfo is the parameter used internally for Hkdf's info parameter. + HkdfInfo = "TENDERMINT_SECRET_CONNECTION_FRAME_KEY_DERIVE" +) + +//New xChaChapoly1305 AEAD with 24 byte nonces +func New(key []byte) (cipher.AEAD, error) { + if len(key) != KeySize { + return nil, errors.New("chacha20poly1305: bad key length") + } + ret := new(hkdfchacha20poly1305) + copy(ret.key[:], key) + return ret, nil + +} +func (c *hkdfchacha20poly1305) NonceSize() int { + return NonceSize +} + +func (c *hkdfchacha20poly1305) Overhead() int { + return TagSize +} + +func (c *hkdfchacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte { + if len(nonce) != NonceSize { + panic("hkdfchacha20poly1305: bad nonce length passed to Seal") + } + + if uint64(len(plaintext)) > MaxPlaintextSize { + panic("hkdfchacha20poly1305: plaintext too large") + } + + subKey, chachaNonce := getSubkeyAndChachaNonceFromHkdf(&c.key, &nonce) + + aead, err := chacha20poly1305.New(subKey[:]) + if err != nil { + panic("hkdfchacha20poly1305: failed to initialize chacha20poly1305") + } + + return aead.Seal(dst, chachaNonce[:], plaintext, additionalData) +} + +func (c *hkdfchacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { + if len(nonce) != NonceSize { + return nil, errors.New("hkdfchacha20poly1305: bad nonce length passed to Open") + } + if uint64(len(ciphertext)) > MaxCiphertextSize { + return nil, errors.New("hkdfchacha20poly1305: ciphertext too large") + } + + subKey, chachaNonce := getSubkeyAndChachaNonceFromHkdf(&c.key, &nonce) + + aead, err := chacha20poly1305.New(subKey[:]) + if err != nil { + panic("hkdfchacha20poly1305: failed to initialize chacha20poly1305") + } + + return aead.Open(dst, chachaNonce[:], ciphertext, additionalData) +} + +func getSubkeyAndChachaNonceFromHkdf(cKey *[32]byte, nonce *[]byte) ( + subKey [KeySize]byte, chachaNonce [chacha20poly1305.NonceSize]byte) { + hash := sha256.New + hkdf := hkdf.New(hash, (*cKey)[:], *nonce, []byte(HkdfInfo)) + _, err := io.ReadFull(hkdf, subKey[:]) + if err != nil { + panic("hkdfchacha20poly1305: failed to read subkey from hkdf") + } + _, err = io.ReadFull(hkdf, chachaNonce[:]) + if err != nil { + panic("hkdfchacha20poly1305: failed to read chachaNonce from hkdf") + } + return +} diff --git a/hkdfchacha20poly1305/hkdfchachapoly_test.go b/hkdfchacha20poly1305/hkdfchachapoly_test.go new file mode 100644 index 000000000..66b770a18 --- /dev/null +++ b/hkdfchacha20poly1305/hkdfchachapoly_test.go @@ -0,0 +1,139 @@ +package hkdfchacha20poly1305 + +import ( + "bytes" + cr "crypto/rand" + "encoding/hex" + mr "math/rand" + "testing" + + "github.com/stretchr/testify/assert" +) + +// Test that a test vector we generated is valid. (Ensures backwards +// compatability) +func TestVector(t *testing.T) { + key, _ := hex.DecodeString("56f8de45d3c294c7675bcaf457bdd4b71c380b9b2408ce9412b348d0f08b69ee") + aead, err := New(key[:]) + if err != nil { + t.Fatal(err) + } + cts := []string{"e20a8bf42c535ac30125cfc52031577f0b", + "657695b37ba30f67b25860d90a6f1d00d8", + "e9aa6f3b7f625d957fd50f05bcdf20d014", + "8a00b3b5a6014e0d2033bebc5935086245", + "aadd74867b923879e6866ea9e03c009039", + "fc59773c2c864ee3b4cc971876b3c7bed4", + "caec14e3a9a52ce1a2682c6737defa4752", + "0b89511ffe490d2049d6950494ee51f919", + "7de854ea71f43ca35167a07566c769083d", + "cd477327f4ea4765c71e311c5fec1edbfb"} + + for i := 0; i < 10; i++ { + ct, _ := hex.DecodeString(cts[i]) + + byteArr := []byte{byte(i)} + nonce := make([]byte, 24, 24) + nonce[0] = byteArr[0] + + plaintext, err := aead.Open(nil, nonce, ct, byteArr) + if err != nil { + t.Errorf("%dth Open failed", i) + continue + } + assert.Equal(t, byteArr, plaintext) + } +} + +// The following test is taken from +// https://github.com/golang/crypto/blob/master/chacha20poly1305/chacha20poly1305_test.go#L69 +// It requires the below copyright notice, where "this source code" refers to the following function. +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found at the bottom of this file. +func TestRandom(t *testing.T) { + // Some random tests to verify Open(Seal) == Plaintext + for i := 0; i < 256; i++ { + var nonce [24]byte + var key [32]byte + + al := mr.Intn(128) + pl := mr.Intn(16384) + ad := make([]byte, al) + plaintext := make([]byte, pl) + cr.Read(key[:]) + cr.Read(nonce[:]) + cr.Read(ad) + cr.Read(plaintext) + + aead, err := New(key[:]) + if err != nil { + t.Fatal(err) + } + + ct := aead.Seal(nil, nonce[:], plaintext, ad) + + plaintext2, err := aead.Open(nil, nonce[:], ct, ad) + if err != nil { + t.Errorf("Random #%d: Open failed", i) + continue + } + + if !bytes.Equal(plaintext, plaintext2) { + t.Errorf("Random #%d: plaintext's don't match: got %x vs %x", i, plaintext2, plaintext) + continue + } + + if len(ad) > 0 { + alterAdIdx := mr.Intn(len(ad)) + ad[alterAdIdx] ^= 0x80 + if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil { + t.Errorf("Random #%d: Open was successful after altering additional data", i) + } + ad[alterAdIdx] ^= 0x80 + } + + alterNonceIdx := mr.Intn(aead.NonceSize()) + nonce[alterNonceIdx] ^= 0x80 + if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil { + t.Errorf("Random #%d: Open was successful after altering nonce", i) + } + nonce[alterNonceIdx] ^= 0x80 + + alterCtIdx := mr.Intn(len(ct)) + ct[alterCtIdx] ^= 0x80 + if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil { + t.Errorf("Random #%d: Open was successful after altering ciphertext", i) + } + ct[alterCtIdx] ^= 0x80 + } +} + +// AFOREMENTIONED LICENCE +// Copyright (c) 2009 The Go Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/xchacha20poly1305/xchachapoly.go b/xchacha20poly1305/xchachapoly.go deleted file mode 100644 index 9e0778579..000000000 --- a/xchacha20poly1305/xchachapoly.go +++ /dev/null @@ -1,238 +0,0 @@ -package xchacha20poly1305 - -import ( - "crypto/cipher" - "encoding/binary" - "errors" - "fmt" - - "golang.org/x/crypto/chacha20poly1305" -) - -var sigma = [4]uint32{0x61707865, 0x3320646e, 0x79622d32, 0x6b206574} - -type xchacha20poly1305 struct { - key [KeySize]byte -} - -const ( - // KeySize is the size of the key used by this AEAD, in bytes. - KeySize = 32 - // NonceSize is the size of the nonce used with this AEAD, in bytes. - NonceSize = 24 -) - -//New xChaChapoly1305 AEAD with 24 byte nonces -func New(key []byte) (cipher.AEAD, error) { - if len(key) != KeySize { - return nil, errors.New("chacha20poly1305: bad key length") - } - ret := new(xchacha20poly1305) - copy(ret.key[:], key) - return ret, nil - -} -func (c *xchacha20poly1305) NonceSize() int { - return NonceSize -} - -func (c *xchacha20poly1305) Overhead() int { - return 16 -} - -func (c *xchacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte { - if len(nonce) != NonceSize { - panic("xchacha20poly1305: bad nonce length passed to Seal") - } - - if uint64(len(plaintext)) > (1<<38)-64 { - panic("xchacha20poly1305: plaintext too large") - } - - var subKey [KeySize]byte - var hNonce [16]byte - var subNonce [chacha20poly1305.NonceSize]byte - copy(hNonce[:], nonce[:16]) - - HChaCha20(&subKey, &hNonce, &c.key) - - chacha20poly1305, _ := chacha20poly1305.New(subKey[:]) - - copy(subNonce[4:], nonce[16:]) - - return chacha20poly1305.Seal(dst, subNonce[:], plaintext, additionalData) -} - -func (c *xchacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { - if len(nonce) != NonceSize { - return nil, fmt.Errorf("xchacha20poly1305: bad nonce length passed to Open") - } - if uint64(len(ciphertext)) > (1<<38)-48 { - return nil, fmt.Errorf("xchacha20poly1305: ciphertext too large") - } - var subKey [KeySize]byte - var hNonce [16]byte - var subNonce [chacha20poly1305.NonceSize]byte - copy(hNonce[:], nonce[:16]) - - HChaCha20(&subKey, &hNonce, &c.key) - - chacha20poly1305, _ := chacha20poly1305.New(subKey[:]) - - copy(subNonce[4:], nonce[16:]) - - return chacha20poly1305.Open(dst, subNonce[:], ciphertext, additionalData) -} - -// The MIT License (MIT) - -// Copyright (c) 2016 Andreas Auernhammer - -// 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. - -// HChaCha20 generates 32 pseudo-random bytes from a 128 bit nonce and a 256 bit secret key. -// It can be used as a key-derivation-function (KDF). -func HChaCha20(out *[32]byte, nonce *[16]byte, key *[32]byte) { hChaCha20Generic(out, nonce, key) } - -func hChaCha20Generic(out *[32]byte, nonce *[16]byte, key *[32]byte) { - v00 := sigma[0] - v01 := sigma[1] - v02 := sigma[2] - v03 := sigma[3] - v04 := binary.LittleEndian.Uint32(key[0:]) - v05 := binary.LittleEndian.Uint32(key[4:]) - v06 := binary.LittleEndian.Uint32(key[8:]) - v07 := binary.LittleEndian.Uint32(key[12:]) - v08 := binary.LittleEndian.Uint32(key[16:]) - v09 := binary.LittleEndian.Uint32(key[20:]) - v10 := binary.LittleEndian.Uint32(key[24:]) - v11 := binary.LittleEndian.Uint32(key[28:]) - v12 := binary.LittleEndian.Uint32(nonce[0:]) - v13 := binary.LittleEndian.Uint32(nonce[4:]) - v14 := binary.LittleEndian.Uint32(nonce[8:]) - v15 := binary.LittleEndian.Uint32(nonce[12:]) - - for i := 0; i < 20; i += 2 { - v00 += v04 - v12 ^= v00 - v12 = (v12 << 16) | (v12 >> 16) - v08 += v12 - v04 ^= v08 - v04 = (v04 << 12) | (v04 >> 20) - v00 += v04 - v12 ^= v00 - v12 = (v12 << 8) | (v12 >> 24) - v08 += v12 - v04 ^= v08 - v04 = (v04 << 7) | (v04 >> 25) - v01 += v05 - v13 ^= v01 - v13 = (v13 << 16) | (v13 >> 16) - v09 += v13 - v05 ^= v09 - v05 = (v05 << 12) | (v05 >> 20) - v01 += v05 - v13 ^= v01 - v13 = (v13 << 8) | (v13 >> 24) - v09 += v13 - v05 ^= v09 - v05 = (v05 << 7) | (v05 >> 25) - v02 += v06 - v14 ^= v02 - v14 = (v14 << 16) | (v14 >> 16) - v10 += v14 - v06 ^= v10 - v06 = (v06 << 12) | (v06 >> 20) - v02 += v06 - v14 ^= v02 - v14 = (v14 << 8) | (v14 >> 24) - v10 += v14 - v06 ^= v10 - v06 = (v06 << 7) | (v06 >> 25) - v03 += v07 - v15 ^= v03 - v15 = (v15 << 16) | (v15 >> 16) - v11 += v15 - v07 ^= v11 - v07 = (v07 << 12) | (v07 >> 20) - v03 += v07 - v15 ^= v03 - v15 = (v15 << 8) | (v15 >> 24) - v11 += v15 - v07 ^= v11 - v07 = (v07 << 7) | (v07 >> 25) - v00 += v05 - v15 ^= v00 - v15 = (v15 << 16) | (v15 >> 16) - v10 += v15 - v05 ^= v10 - v05 = (v05 << 12) | (v05 >> 20) - v00 += v05 - v15 ^= v00 - v15 = (v15 << 8) | (v15 >> 24) - v10 += v15 - v05 ^= v10 - v05 = (v05 << 7) | (v05 >> 25) - v01 += v06 - v12 ^= v01 - v12 = (v12 << 16) | (v12 >> 16) - v11 += v12 - v06 ^= v11 - v06 = (v06 << 12) | (v06 >> 20) - v01 += v06 - v12 ^= v01 - v12 = (v12 << 8) | (v12 >> 24) - v11 += v12 - v06 ^= v11 - v06 = (v06 << 7) | (v06 >> 25) - v02 += v07 - v13 ^= v02 - v13 = (v13 << 16) | (v13 >> 16) - v08 += v13 - v07 ^= v08 - v07 = (v07 << 12) | (v07 >> 20) - v02 += v07 - v13 ^= v02 - v13 = (v13 << 8) | (v13 >> 24) - v08 += v13 - v07 ^= v08 - v07 = (v07 << 7) | (v07 >> 25) - v03 += v04 - v14 ^= v03 - v14 = (v14 << 16) | (v14 >> 16) - v09 += v14 - v04 ^= v09 - v04 = (v04 << 12) | (v04 >> 20) - v03 += v04 - v14 ^= v03 - v14 = (v14 << 8) | (v14 >> 24) - v09 += v14 - v04 ^= v09 - v04 = (v04 << 7) | (v04 >> 25) - } - - binary.LittleEndian.PutUint32(out[0:], v00) - binary.LittleEndian.PutUint32(out[4:], v01) - binary.LittleEndian.PutUint32(out[8:], v02) - binary.LittleEndian.PutUint32(out[12:], v03) - binary.LittleEndian.PutUint32(out[16:], v12) - binary.LittleEndian.PutUint32(out[20:], v13) - binary.LittleEndian.PutUint32(out[24:], v14) - binary.LittleEndian.PutUint32(out[28:], v15) -} diff --git a/xchacha20poly1305/xchachapoly_test.go b/xchacha20poly1305/xchachapoly_test.go deleted file mode 100644 index 3001217f4..000000000 --- a/xchacha20poly1305/xchachapoly_test.go +++ /dev/null @@ -1,103 +0,0 @@ -package xchacha20poly1305 - -import ( - "bytes" - "encoding/hex" - "testing" -) - -func toHex(bits []byte) string { - return hex.EncodeToString(bits) -} - -func fromHex(bits string) []byte { - b, err := hex.DecodeString(bits) - if err != nil { - panic(err) - } - return b -} - -func TestHChaCha20(t *testing.T) { - for i, v := range hChaCha20Vectors { - var key [32]byte - var nonce [16]byte - copy(key[:], v.key) - copy(nonce[:], v.nonce) - - HChaCha20(&key, &nonce, &key) - if !bytes.Equal(key[:], v.keystream) { - t.Errorf("Test %d: keystream mismatch:\n \t got: %s\n \t want: %s", i, toHex(key[:]), toHex(v.keystream)) - } - } -} - -var hChaCha20Vectors = []struct { - key, nonce, keystream []byte -}{ - { - fromHex("0000000000000000000000000000000000000000000000000000000000000000"), - fromHex("000000000000000000000000000000000000000000000000"), - fromHex("1140704c328d1d5d0e30086cdf209dbd6a43b8f41518a11cc387b669b2ee6586"), - }, - { - fromHex("8000000000000000000000000000000000000000000000000000000000000000"), - fromHex("000000000000000000000000000000000000000000000000"), - fromHex("7d266a7fd808cae4c02a0a70dcbfbcc250dae65ce3eae7fc210f54cc8f77df86"), - }, - { - fromHex("0000000000000000000000000000000000000000000000000000000000000001"), - fromHex("000000000000000000000000000000000000000000000002"), - fromHex("e0c77ff931bb9163a5460c02ac281c2b53d792b1c43fea817e9ad275ae546963"), - }, - { - fromHex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), - fromHex("000102030405060708090a0b0c0d0e0f1011121314151617"), - fromHex("51e3ff45a895675c4b33b46c64f4a9ace110d34df6a2ceab486372bacbd3eff6"), - }, - { - fromHex("24f11cce8a1b3d61e441561a696c1c1b7e173d084fd4812425435a8896a013dc"), - fromHex("d9660c5900ae19ddad28d6e06e45fe5e"), - fromHex("5966b3eec3bff1189f831f06afe4d4e3be97fa9235ec8c20d08acfbbb4e851e3"), - }, -} - -func TestVectors(t *testing.T) { - for i, v := range vectors { - if len(v.plaintext) == 0 { - v.plaintext = make([]byte, len(v.ciphertext)) - } - - var nonce [24]byte - copy(nonce[:], v.nonce) - - aead, err := New(v.key) - if err != nil { - t.Error(err) - } - - dst := aead.Seal(nil, nonce[:], v.plaintext, v.ad) - if !bytes.Equal(dst, v.ciphertext) { - t.Errorf("Test %d: ciphertext mismatch:\n \t got: %s\n \t want: %s", i, toHex(dst), toHex(v.ciphertext)) - } - open, err := aead.Open(nil, nonce[:], dst, v.ad) - if err != nil { - t.Error(err) - } - if !bytes.Equal(open, v.plaintext) { - t.Errorf("Test %d: plaintext mismatch:\n \t got: %s\n \t want: %s", i, string(open), string(v.plaintext)) - } - } -} - -var vectors = []struct { - key, nonce, ad, plaintext, ciphertext []byte -}{ - { - []byte{0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f}, - []byte{0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b}, - []byte{0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7}, - []byte("Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."), - []byte{0x45, 0x3c, 0x06, 0x93, 0xa7, 0x40, 0x7f, 0x04, 0xff, 0x4c, 0x56, 0xae, 0xdb, 0x17, 0xa3, 0xc0, 0xa1, 0xaf, 0xff, 0x01, 0x17, 0x49, 0x30, 0xfc, 0x22, 0x28, 0x7c, 0x33, 0xdb, 0xcf, 0x0a, 0xc8, 0xb8, 0x9a, 0xd9, 0x29, 0x53, 0x0a, 0x1b, 0xb3, 0xab, 0x5e, 0x69, 0xf2, 0x4c, 0x7f, 0x60, 0x70, 0xc8, 0xf8, 0x40, 0xc9, 0xab, 0xb4, 0xf6, 0x9f, 0xbf, 0xc8, 0xa7, 0xff, 0x51, 0x26, 0xfa, 0xee, 0xbb, 0xb5, 0x58, 0x05, 0xee, 0x9c, 0x1c, 0xf2, 0xce, 0x5a, 0x57, 0x26, 0x32, 0x87, 0xae, 0xc5, 0x78, 0x0f, 0x04, 0xec, 0x32, 0x4c, 0x35, 0x14, 0x12, 0x2c, 0xfc, 0x32, 0x31, 0xfc, 0x1a, 0x8b, 0x71, 0x8a, 0x62, 0x86, 0x37, 0x30, 0xa2, 0x70, 0x2b, 0xb7, 0x63, 0x66, 0x11, 0x6b, 0xed, 0x09, 0xe0, 0xfd, 0x5c, 0x6d, 0x84, 0xb6, 0xb0, 0xc1, 0xab, 0xaf, 0x24, 0x9d, 0x5d, 0xd0, 0xf7, 0xf5, 0xa7, 0xea}, - }, -} From 4634063698d3ffdcd1645769ea8fee989cd362fe Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Wed, 20 Jun 2018 13:30:22 -0700 Subject: [PATCH 270/287] keys package: fundraiser compatibility and HD keys (BIP 39 & BIP 32 / BIP 44) (#118) - fundraiser compatibility for HD keys (BIP 39 & BIP 32 / BIP 44) --- Gopkg.lock | 12 +- Gopkg.toml | 4 - Makefile | 2 +- amino.go | 1 + armor.go | 8 +- keys/bcrypt/bcrypt.go | 2 +- keys/bip39/wordcodec.go | 62 + keys/bip39/wordcodec_test.go | 15 + keys/hd/address.go | 352 ---- keys/hd/address_test.go | 37 - keys/hd/fundraiser_test.go | 83 + keys/hd/hd_test.go | 238 --- keys/hd/hdpath.go | 168 ++ keys/hd/hdpath_test.go | 73 + keys/keybase.go | 174 +- keys/keybase_test.go | 172 +- keys/keys.go | 36 +- keys/types.go | 17 +- keys/words/ecc.go | 208 -- keys/words/ecc_test.go | 62 - keys/words/wordcodec.go | 200 -- keys/words/wordcodec_test.go | 180 -- keys/words/wordcodecbench_test.go | 68 - keys/words/wordlist/chinese_simplified.txt | 2048 -------------------- keys/words/wordlist/english.txt | 2048 -------------------- keys/words/wordlist/japanese.txt | 2048 -------------------- keys/words/wordlist/spanish.txt | 2048 -------------------- keys/words/wordlist/wordlist.go | 310 --- 28 files changed, 590 insertions(+), 10086 deletions(-) create mode 100644 keys/bip39/wordcodec.go create mode 100644 keys/bip39/wordcodec_test.go delete mode 100644 keys/hd/address.go delete mode 100644 keys/hd/address_test.go create mode 100644 keys/hd/fundraiser_test.go delete mode 100644 keys/hd/hd_test.go create mode 100644 keys/hd/hdpath.go create mode 100644 keys/hd/hdpath_test.go delete mode 100644 keys/words/ecc.go delete mode 100644 keys/words/ecc_test.go delete mode 100644 keys/words/wordcodec.go delete mode 100644 keys/words/wordcodec_test.go delete mode 100644 keys/words/wordcodecbench_test.go delete mode 100644 keys/words/wordlist/chinese_simplified.txt delete mode 100644 keys/words/wordlist/english.txt delete mode 100644 keys/words/wordlist/japanese.txt delete mode 100644 keys/words/wordlist/spanish.txt delete mode 100644 keys/words/wordlist/wordlist.go diff --git a/Gopkg.lock b/Gopkg.lock index 7d3bac984..83fe33bd7 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1,6 +1,12 @@ # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. +[[projects]] + branch = "master" + name = "github.com/bartekn/go-bip39" + packages = ["."] + revision = "a05967ea095d81c8fe4833776774cfaff8e5036c" + [[projects]] branch = "master" name = "github.com/brejski/hid" @@ -63,12 +69,6 @@ packages = ["."] revision = "2e65f85255dbc3072edf28d6b5b8efc472979f5a" -[[projects]] - branch = "master" - name = "github.com/howeyc/crc16" - packages = ["."] - revision = "2b2a61e366a66d3efb279e46176e7291001e0354" - [[projects]] branch = "master" name = "github.com/jmhodges/levigo" diff --git a/Gopkg.toml b/Gopkg.toml index df7e5e221..92bfecacd 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -28,10 +28,6 @@ name = "github.com/btcsuite/btcutil" branch = "master" -[[constraint]] - name = "github.com/howeyc/crc16" - branch = "master" - [[constraint]] name = "github.com/pkg/errors" version = "0.8.0" diff --git a/Makefile b/Makefile index 74af29941..96f4ae06d 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ check: check_tools # Command to generate the workd list (kept here for documentation purposes only): wordlist: # To re-generate wordlist.go run: - # go-bindata -ignore ".*\.go" -o keys/words/wordlist/wordlist.go -pkg "wordlist" keys/words/wordlist/... + # go-bindata -ignore ".*\.go" -o keys/words/bip39/wordlist.go -pkg "wordlist" keys/bip39/wordlist/... build: wordlist # Nothing else to build! diff --git a/amino.go b/amino.go index ddf3e193a..63e4c4ac3 100644 --- a/amino.go +++ b/amino.go @@ -15,6 +15,7 @@ func init() { RegisterAmino(cdc) } +// RegisterAmino registers all go-crypto related types in the given (amino) codec. func RegisterAmino(cdc *amino.Codec) { cdc.RegisterInterface((*PubKey)(nil), nil) cdc.RegisterConcrete(PubKeyEd25519{}, diff --git a/armor.go b/armor.go index 5f199df43..4146048ad 100644 --- a/armor.go +++ b/armor.go @@ -2,9 +2,9 @@ package crypto import ( "bytes" + "fmt" "io/ioutil" - . "github.com/tendermint/tmlibs/common" "golang.org/x/crypto/openpgp/armor" ) @@ -12,15 +12,15 @@ func EncodeArmor(blockType string, headers map[string]string, data []byte) strin buf := new(bytes.Buffer) w, err := armor.Encode(buf, blockType, headers) if err != nil { - PanicSanity("Error encoding ascii armor: " + err.Error()) + panic(fmt.Errorf("could not encode ascii armor: %s", err)) } _, err = w.Write(data) if err != nil { - PanicSanity("Error encoding ascii armor: " + err.Error()) + panic(fmt.Errorf("could not encode ascii armor: %s", err)) } err = w.Close() if err != nil { - PanicSanity("Error encoding ascii armor: " + err.Error()) + panic(fmt.Errorf("could not encode ascii armor: %s", err)) } return buf.String() } diff --git a/keys/bcrypt/bcrypt.go b/keys/bcrypt/bcrypt.go index 6b23b7a9d..ce2b9f4bc 100644 --- a/keys/bcrypt/bcrypt.go +++ b/keys/bcrypt/bcrypt.go @@ -88,7 +88,7 @@ type hashed struct { // to compare the returned hashed password with its cleartext version. func GenerateFromPassword(salt []byte, password []byte, cost int) ([]byte, error) { if len(salt) != maxSaltSize { - return nil, fmt.Errorf("Salt len must be %v", maxSaltSize) + return nil, fmt.Errorf("salt len must be %v", maxSaltSize) } p, err := newFromPassword(salt, password, cost) if err != nil { diff --git a/keys/bip39/wordcodec.go b/keys/bip39/wordcodec.go new file mode 100644 index 000000000..b0c23e629 --- /dev/null +++ b/keys/bip39/wordcodec.go @@ -0,0 +1,62 @@ +package bip39 + +import ( + "strings" + + "github.com/bartekn/go-bip39" +) + +// ValidSentenceLen defines the mnemonic sentence lengths supported by this BIP 39 library. +type ValidSentenceLen uint8 + +const ( + // FundRaiser is the sentence length used during the cosmos fundraiser (12 words). + FundRaiser ValidSentenceLen = 12 + // FreshKey is the sentence length used for newly created keys (24 words). + FreshKey ValidSentenceLen = 24 +) + +// NewMnemonic will return a string consisting of the mnemonic words for +// the given sentence length. +func NewMnemonic(len ValidSentenceLen) (words []string, err error) { + // len = (ENT + checksum) / 11 + var ENT int + switch len { + case FundRaiser: + ENT = 128 + case FreshKey: + ENT = 256 + } + var entropy []byte + entropy, err = bip39.NewEntropy(ENT) + if err != nil { + return + } + var mnemonic string + mnemonic, err = bip39.NewMnemonic(entropy) + if err != nil { + return + } + words = strings.Split(mnemonic, " ") + return +} + +// MnemonicToSeed creates a BIP 39 seed from the passed mnemonic (with an empty BIP 39 password). +// This method does not validate the mnemonics checksum. +func MnemonicToSeed(mne string) (seed []byte) { + // we do not checksum here... + seed = bip39.NewSeed(mne, "") + return +} + +// MnemonicToSeedWithErrChecking returns the same seed as MnemonicToSeed. +// It creates a BIP 39 seed from the passed mnemonic (with an empty BIP 39 password). +// +// Different from MnemonicToSeed it validates the checksum. +// For details on the checksum see the BIP 39 spec. +func MnemonicToSeedWithErrChecking(mne string) (seed []byte, err error) { + seed, err = bip39.NewSeedWithErrorChecking(mne, "") + return +} + + diff --git a/keys/bip39/wordcodec_test.go b/keys/bip39/wordcodec_test.go new file mode 100644 index 000000000..dbc5c0d02 --- /dev/null +++ b/keys/bip39/wordcodec_test.go @@ -0,0 +1,15 @@ +package bip39 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestWordCodec_NewMnemonic(t *testing.T) { + _, err := NewMnemonic(FundRaiser) + assert.NoError(t, err, "unexpected error generating fundraiser mnemonic") + + _, err = NewMnemonic(FreshKey) + assert.NoError(t, err, "unexpected error generating new 24-word mnemonic") +} diff --git a/keys/hd/address.go b/keys/hd/address.go deleted file mode 100644 index 9511ffad2..000000000 --- a/keys/hd/address.go +++ /dev/null @@ -1,352 +0,0 @@ -package hd - -// XXX This package doesn't work with our address scheme, -// XXX and it probably doesn't work for our other pubkey types. -// XXX Fix it up to be more general but compatible. - -import ( - "crypto/ecdsa" - "crypto/hmac" - "crypto/sha256" - "crypto/sha512" - "encoding/base64" - "encoding/binary" - "encoding/hex" - "errors" - "fmt" - "hash" - "math/big" - "strconv" - "strings" - - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcutil/base58" - "golang.org/x/crypto/ripemd160" -) - -/* - - This file implements BIP32 HD wallets. - Note it only works for SECP256k1 keys. - It also includes some Bitcoin specific utility functions. - -*/ - -// ComputeBTCAddress returns the BTC address using the pubKeyHex and chainCodeHex -// for the given path and index. -func ComputeBTCAddress(pubKeyHex string, chainCodeHex string, path string, index int32) string { - pubKeyBytes := DerivePublicKeyForPath( - HexDecode(pubKeyHex), - HexDecode(chainCodeHex), - fmt.Sprintf("%v/%v", path, index), - ) - return BTCAddrFromPubKeyBytes(pubKeyBytes) -} - -// ComputePrivateKey returns the private key using the master mprivHex and chainCodeHex -// for the given path and index. -func ComputePrivateKey(mprivHex string, chainHex string, path string, index int32) string { - privKeyBytes := DerivePrivateKeyForPath( - HexDecode(mprivHex), - HexDecode(chainHex), - fmt.Sprintf("%v/%v", path, index), - ) - return HexEncode(privKeyBytes) -} - -// ComputeBTCAddressForPrivKey returns the Bitcoin address for the given privKey. -func ComputeBTCAddressForPrivKey(privKey string) string { - pubKeyBytes := PubKeyBytesFromPrivKeyBytes(HexDecode(privKey), true) - return BTCAddrFromPubKeyBytes(pubKeyBytes) -} - -// SignBTCMessage signs a "Bitcoin Signed Message". -func SignBTCMessage(privKey string, message string, compress bool) string { - prefixBytes := []byte("Bitcoin Signed Message:\n") - messageBytes := []byte(message) - bytes := []byte{} - bytes = append(bytes, byte(len(prefixBytes))) - bytes = append(bytes, prefixBytes...) - bytes = append(bytes, byte(len(messageBytes))) - bytes = append(bytes, messageBytes...) - privKeyBytes := HexDecode(privKey) - x, y := btcec.S256().ScalarBaseMult(privKeyBytes) - ecdsaPubKey := ecdsa.PublicKey{ - Curve: btcec.S256(), - X: x, - Y: y, - } - ecdsaPrivKey := &btcec.PrivateKey{ - PublicKey: ecdsaPubKey, - D: new(big.Int).SetBytes(privKeyBytes), - } - sigbytes, err := btcec.SignCompact(btcec.S256(), ecdsaPrivKey, CalcHash256(bytes), compress) - if err != nil { - panic(err) - } - return base64.StdEncoding.EncodeToString(sigbytes) -} - -// ComputeMastersFromSeed returns the master public key, master secret, and chain code in hex. -func ComputeMastersFromSeed(seed string) (string, string, string) { - key, data := []byte("Bitcoin seed"), []byte(seed) - secret, chain := I64(key, data) - pubKeyBytes := PubKeyBytesFromPrivKeyBytes(secret, true) - return HexEncode(pubKeyBytes), HexEncode(secret), HexEncode(chain) -} - -// ComputeWIF returns the privKey in Wallet Import Format. -func ComputeWIF(privKey string, compress bool) string { - return WIFFromPrivKeyBytes(HexDecode(privKey), compress) -} - -// ComputeBTCTxId returns the bitcoin transaction ID. -func ComputeBTCTxId(rawTxHex string) string { - return HexEncode(ReverseBytes(CalcHash256(HexDecode(rawTxHex)))) -} - -/* -func printKeyInfo(privKeyBytes []byte, pubKeyBytes []byte, chain []byte) { - if pubKeyBytes == nil { - pubKeyBytes = PubKeyBytesFromPrivKeyBytes(privKeyBytes, true) - } - addr := AddrFromPubKeyBytes(pubKeyBytes) - log.Println("\nprikey:\t%v\npubKeyBytes:\t%v\naddr:\t%v\nchain:\t%v", - HexEncode(privKeyBytes), - HexEncode(pubKeyBytes), - addr, - HexEncode(chain)) -} -*/ - -//------------------------------------------------------------------- - -// DerivePrivateKeyForPath derives the private key by following the path from privKeyBytes, -// using the given chainCode. -func DerivePrivateKeyForPath(privKeyBytes []byte, chainCode []byte, path string) []byte { - data := privKeyBytes - parts := strings.Split(path, "/") - for _, part := range parts { - prime := part[len(part)-1:] == "'" - // prime == private derivation. Otherwise public. - if prime { - part = part[:len(part)-1] - } - i, err := strconv.Atoi(part) - if err != nil { - panic(err) - } - if i < 0 { - panic(errors.New("index too large.")) - } - data, chainCode = DerivePrivateKey(data, chainCode, uint32(i), prime) - //printKeyInfo(data, nil, chain) - } - return data -} - -// DerivePublicKeyForPath derives the public key by following the path from pubKeyBytes -// using the given chainCode. -func DerivePublicKeyForPath(pubKeyBytes []byte, chainCode []byte, path string) []byte { - data := pubKeyBytes - parts := strings.Split(path, "/") - for _, part := range parts { - prime := part[len(part)-1:] == "'" - if prime { - panic(errors.New("cannot do a prime derivation from public key")) - } - i, err := strconv.Atoi(part) - if err != nil { - panic(err) - } - if i < 0 { - panic(errors.New("index too large.")) - } - data, chainCode = DerivePublicKey(data, chainCode, uint32(i)) - //printKeyInfo(nil, data, chainCode) - } - return data -} - -// DerivePrivateKey derives the private key with index and chainCode. -// If prime is true, the derivation is 'hardened'. -// It returns the new private key and new chain code. -func DerivePrivateKey(privKeyBytes []byte, chainCode []byte, index uint32, prime bool) ([]byte, []byte) { - var data []byte - if prime { - index = index | 0x80000000 - data = append([]byte{byte(0)}, privKeyBytes...) - } else { - public := PubKeyBytesFromPrivKeyBytes(privKeyBytes, true) - data = public - } - data = append(data, uint32ToBytes(index)...) - data2, chainCode2 := I64(chainCode, data) - x := addScalars(privKeyBytes, data2) - return x, chainCode2 -} - -// DerivePublicKey derives the public key with index and chainCode. -// It returns the new public key and new chain code. -func DerivePublicKey(pubKeyBytes []byte, chainCode []byte, index uint32) ([]byte, []byte) { - data := []byte{} - data = append(data, pubKeyBytes...) - data = append(data, uint32ToBytes(index)...) - data2, chainCode2 := I64(chainCode, data) - data2p := PubKeyBytesFromPrivKeyBytes(data2, true) - return addPoints(pubKeyBytes, data2p), chainCode2 -} - -// eliptic curve pubkey addition -func addPoints(a []byte, b []byte) []byte { - ap, err := btcec.ParsePubKey(a, btcec.S256()) - if err != nil { - panic(err) - } - bp, err := btcec.ParsePubKey(b, btcec.S256()) - if err != nil { - panic(err) - } - sumX, sumY := btcec.S256().Add(ap.X, ap.Y, bp.X, bp.Y) - sum := &btcec.PublicKey{ - Curve: btcec.S256(), - X: sumX, - Y: sumY, - } - return sum.SerializeCompressed() -} - -// modular big endian addition -func addScalars(a []byte, b []byte) []byte { - aInt := new(big.Int).SetBytes(a) - bInt := new(big.Int).SetBytes(b) - sInt := new(big.Int).Add(aInt, bInt) - x := sInt.Mod(sInt, btcec.S256().N).Bytes() - x2 := [32]byte{} - copy(x2[32-len(x):], x) - return x2[:] -} - -func uint32ToBytes(i uint32) []byte { - b := [4]byte{} - binary.BigEndian.PutUint32(b[:], i) - return b[:] -} - -//------------------------------------------------------------------- - -// HexEncode encodes b in hex. -func HexEncode(b []byte) string { - return hex.EncodeToString(b) -} - -// HexDecode hex decodes the str. If str is not valid hex -// it will return an empty byte slice. -func HexDecode(str string) []byte { - b, _ := hex.DecodeString(str) - return b -} - -// I64 returns the two halfs of the SHA512 HMAC of key and data. -func I64(key []byte, data []byte) ([]byte, []byte) { - mac := hmac.New(sha512.New, key) - mac.Write(data) - I := mac.Sum(nil) - return I[:32], I[32:] -} - -//------------------------------------------------------------------- - -const ( - btcPrefixPubKeyHash = byte(0x00) - btcPrefixPrivKey = byte(0x80) -) - -// BTCAddrFromPubKeyBytes returns a B58 encoded Bitcoin mainnet address. -func BTCAddrFromPubKeyBytes(pubKeyBytes []byte) string { - versionPrefix := btcPrefixPubKeyHash // TODO Make const or configurable - h160 := CalcHash160(pubKeyBytes) - h160 = append([]byte{versionPrefix}, h160...) - checksum := CalcHash256(h160) - b := append(h160, checksum[:4]...) - return base58.Encode(b) -} - -// BTCAddrBytesFromPubKeyBytes returns a hex Bitcoin mainnet address and its checksum. -func BTCAddrBytesFromPubKeyBytes(pubKeyBytes []byte) (addrBytes []byte, checksum []byte) { - versionPrefix := btcPrefixPubKeyHash // TODO Make const or configurable - h160 := CalcHash160(pubKeyBytes) - _h160 := append([]byte{versionPrefix}, h160...) - checksum = CalcHash256(_h160)[:4] - return h160, checksum -} - -// WIFFromPrivKeyBytes returns the privKeyBytes in Wallet Import Format. -func WIFFromPrivKeyBytes(privKeyBytes []byte, compress bool) string { - versionPrefix := btcPrefixPrivKey // TODO Make const or configurable - bytes := append([]byte{versionPrefix}, privKeyBytes...) - if compress { - bytes = append(bytes, byte(1)) - } - checksum := CalcHash256(bytes) - bytes = append(bytes, checksum[:4]...) - return base58.Encode(bytes) -} - -// PubKeyBytesFromPrivKeyBytes returns the optionally compressed public key bytes. -func PubKeyBytesFromPrivKeyBytes(privKeyBytes []byte, compress bool) (pubKeyBytes []byte) { - x, y := btcec.S256().ScalarBaseMult(privKeyBytes) - pub := &btcec.PublicKey{ - Curve: btcec.S256(), - X: x, - Y: y, - } - - if compress { - return pub.SerializeCompressed() - } - return pub.SerializeUncompressed() -} - -//-------------------------------------------------------------- - -// CalcHash returns the hash of data using hasher. -func CalcHash(data []byte, hasher hash.Hash) []byte { - hasher.Write(data) - return hasher.Sum(nil) -} - -// CalcHash160 returns the ripemd160(sha256(data)). -func CalcHash160(data []byte) []byte { - return CalcHash(CalcHash(data, sha256.New()), ripemd160.New()) -} - -// CalcHash256 returns the sha256(sha256(data)). -func CalcHash256(data []byte) []byte { - return CalcHash(CalcHash(data, sha256.New()), sha256.New()) -} - -// CalcSha512 returns the sha512(data). -func CalcSha512(data []byte) []byte { - return CalcHash(data, sha512.New()) -} - -// ReverseBytes returns the buf in the opposite order -func ReverseBytes(buf []byte) []byte { - var res []byte - if len(buf) == 0 { - return res - } - - // Walk till mid-way, swapping bytes from each end: - // b[i] and b[len-i-1] - blen := len(buf) - res = make([]byte, blen) - mid := blen / 2 - for left := 0; left <= mid; left++ { - right := blen - left - 1 - res[left] = buf[right] - res[right] = buf[left] - } - return res -} diff --git a/keys/hd/address_test.go b/keys/hd/address_test.go deleted file mode 100644 index 0554733f1..000000000 --- a/keys/hd/address_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package hd - -/* - -import ( - "encoding/hex" - "fmt" - "testing" -) - -func TestManual(t *testing.T) { - bytes, _ := hex.DecodeString("dfac699f1618c9be4df2befe94dc5f313946ebafa386756bd4926a1ecfd7cf2438426ede521d1ee6512391bc200b7910bcbea593e68d52b874c29bdc5a308ed1") - fmt.Println(bytes) - puk, prk, ch, se := ComputeMastersFromSeed(string(bytes)) - fmt.Println(puk, ch, se) - - pubBytes2 := DerivePublicKeyForPath( - HexDecode(puk), - HexDecode(ch), - //"44'/118'/0'/0/0", - "0/0", - ) - fmt.Printf("PUB2 %X\n", pubBytes2) - - privBytes := DerivePrivateKeyForPath( - HexDecode(prk), - HexDecode(ch), - //"44'/118'/0'/0/0", - //"0/0", - "44'/118'/0'/0/0", - ) - fmt.Printf("PRIV %X\n", privBytes) - pubBytes := PubKeyBytesFromPrivKeyBytes(privBytes, true) - fmt.Printf("PUB %X\n", pubBytes) -} - -*/ diff --git a/keys/hd/fundraiser_test.go b/keys/hd/fundraiser_test.go new file mode 100644 index 000000000..63607b0a5 --- /dev/null +++ b/keys/hd/fundraiser_test.go @@ -0,0 +1,83 @@ +package hd + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "io/ioutil" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/tyler-smith/go-bip39" + + "github.com/tendermint/go-crypto" +) + +type addrData struct { + Mnemonic string + Master string + Seed string + Priv string + Pub string + Addr string +} + + +func initFundraiserTestVectors(t *testing.T) []addrData { + // NOTE: atom fundraiser address + // var hdPath string = "m/44'/118'/0'/0/0" + var hdToAddrTable []addrData + + b, err := ioutil.ReadFile("test.json") + if err != nil { + t.Fatalf("could not read fundraiser test vector file (test.json): %s", err) + } + + err = json.Unmarshal(b, &hdToAddrTable) + if err != nil { + t.Fatalf("could not decode test vectors (test.json): %s", err) + } + return hdToAddrTable +} + +func TestFundraiserCompatibility(t *testing.T) { + hdToAddrTable := initFundraiserTestVectors(t) + + for i, d := range hdToAddrTable { + privB, _ := hex.DecodeString(d.Priv) + pubB, _ := hex.DecodeString(d.Pub) + addrB, _ := hex.DecodeString(d.Addr) + seedB, _ := hex.DecodeString(d.Seed) + masterB, _ := hex.DecodeString(d.Master) + + seed := bip39.NewSeed(d.Mnemonic, "") + + t.Log("================================") + t.Logf("ROUND: %d MNEMONIC: %s", i, d.Mnemonic) + + master, ch := ComputeMastersFromSeed(seed) + priv, err := DerivePrivateKeyForPath(master, ch, "44'/118'/0'/0/0") + assert.NoError(t, err) + pub := crypto.PrivKeySecp256k1(priv).PubKey() + + t.Log("\tNODEJS GOLANG\n") + t.Logf("SEED \t%X %X\n", seedB, seed) + t.Logf("MSTR \t%X %X\n", masterB, master) + t.Logf("PRIV \t%X %X\n", privB, priv) + t.Logf("PUB \t%X %X\n", pubB, pub) + + assert.Equal(t, seedB, seed) + assert.Equal(t, master[:], masterB, fmt.Sprintf("Expected masters to match for %d", i)) + assert.Equal(t, priv[:], privB, "Expected priv keys to match") + var pubBFixed [33]byte + copy(pubBFixed[:], pubB) + assert.Equal(t, pub, crypto.PubKeySecp256k1(pubBFixed), fmt.Sprintf("Expected pub keys to match for %d", i)) + + addr := pub.Address() + t.Logf("ADDR \t%X %X\n", addrB, addr) + assert.Equal(t, addr, crypto.Address(addrB), fmt.Sprintf("Expected addresses to match %d", i)) + + } +} + + diff --git a/keys/hd/hd_test.go b/keys/hd/hd_test.go deleted file mode 100644 index c9e540ad5..000000000 --- a/keys/hd/hd_test.go +++ /dev/null @@ -1,238 +0,0 @@ -package hd - -import ( - "bytes" - "encoding/hex" - "encoding/json" - "fmt" - "io/ioutil" - "os" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/tyler-smith/go-bip39" - - "github.com/tendermint/go-crypto" -) - -type addrData struct { - Mnemonic string - Master string - Seed string - Priv string - Pub string - Addr string -} - -// NOTE: atom fundraiser address -// var hdPath string = "m/44'/118'/0'/0/0" -var hdToAddrTable []addrData - -func init() { - - b, err := ioutil.ReadFile("test.json") - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - err = json.Unmarshal(b, &hdToAddrTable) - if err != nil { - fmt.Println(err) - os.Exit(1) - } -} - -func TestHDToAddr(t *testing.T) { - - for i, d := range hdToAddrTable { - privB, _ := hex.DecodeString(d.Priv) - pubB, _ := hex.DecodeString(d.Pub) - addrB, _ := hex.DecodeString(d.Addr) - seedB, _ := hex.DecodeString(d.Seed) - masterB, _ := hex.DecodeString(d.Master) - - seed := bip39.NewSeed(d.Mnemonic, "") - - fmt.Println("================================") - fmt.Println("ROUND:", i, "MNEMONIC:", d.Mnemonic) - - // master, priv, pub := tylerSmith(seed) - // master, priv, pub := btcsuite(seed) - master, priv, pub := gocrypto(seed) - - fmt.Printf("\tNODEJS GOLANG\n") - fmt.Printf("SEED \t%X %X\n", seedB, seed) - fmt.Printf("MSTR \t%X %X\n", masterB, master) - fmt.Printf("PRIV \t%X %X\n", privB, priv) - fmt.Printf("PUB \t%X %X\n", pubB, pub) - _, _ = priv, privB - - assert.Equal(t, master, masterB, fmt.Sprintf("Expected masters to match for %d", i)) - assert.Equal(t, priv, privB, "Expected priv keys to match") - assert.Equal(t, pub, pubB, fmt.Sprintf("Expected pub keys to match for %d", i)) - - var pubT crypto.PubKeySecp256k1 - copy(pubT[:], pub) - addr := pubT.Address() - fmt.Printf("ADDR \t%X %X\n", addrB, addr) - assert.Equal(t, addr, crypto.Address(addrB), fmt.Sprintf("Expected addresses to match %d", i)) - - } -} - -func TestReverseBytes(t *testing.T) { - tests := [...]struct { - v []byte - want []byte - }{ - {[]byte(""), []byte("")}, - {nil, nil}, - {[]byte("Tendermint"), []byte("tnimredneT")}, - {[]byte("T"), []byte("T")}, - {[]byte("Te"), []byte("eT")}, - } - - for i, tt := range tests { - got := ReverseBytes(tt.v) - if !bytes.Equal(got, tt.want) { - t.Errorf("#%d:\ngot= (%x)\nwant=(%x)", i, got, tt.want) - } - } -} - -/* -func ifExit(err error, n int) { - if err != nil { - fmt.Println(n, err) - os.Exit(1) - } -} -*/ - -func gocrypto(seed []byte) ([]byte, []byte, []byte) { - - _, priv, ch := ComputeMastersFromSeed(string(seed)) - - privBytes := DerivePrivateKeyForPath( - HexDecode(priv), - HexDecode(ch), - "44'/118'/0'/0/0", - ) - - pubBytes := PubKeyBytesFromPrivKeyBytes(privBytes, true) - - return HexDecode(priv), privBytes, pubBytes -} - -/* -func btcsuite(seed []byte) ([]byte, []byte, []byte) { - fmt.Println("HD") - masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams) - if err != nil { - hmac := hmac.New(sha512.New, []byte("Bitcoin seed")) - hmac.Write([]byte(seed)) - intermediary := hmac.Sum(nil) - - curve := btcutil.Secp256k1() - curveParams := curve.Params() - - // Split it into our key and chain code - keyBytes := intermediary[:32] - fmt.Printf("\t%X\n", keyBytes) - fmt.Printf("\t%X\n", curveParams.N.Bytes()) - keyInt, _ := binary.ReadVarint(bytes.NewBuffer(keyBytes)) - fmt.Printf("\t%d\n", keyInt) - } - fh := hdkeychain.HardenedKeyStart - k, err := masterKey.Child(uint32(fh + 44)) - ifExit(err, 44) - k, err = k.Child(uint32(fh + 118)) - ifExit(err, 118) - k, err = k.Child(uint32(fh + 0)) - ifExit(err, 1) - k, err = k.Child(uint32(0)) - ifExit(err, 2) - k, err = k.Child(uint32(0)) - ifExit(err, 3) - ecpriv, err := k.ECPrivKey() - ifExit(err, 10) - ecpub, err := k.ECPubKey() - ifExit(err, 11) - - priv := ecpriv.Serialize() - pub := ecpub.SerializeCompressed() - mkey, _ := masterKey.ECPrivKey() - return mkey.Serialize(), priv, pub -} - -// return priv and pub -func tylerSmith(seed []byte) ([]byte, []byte, []byte) { - masterKey, err := bip32.NewMasterKey(seed) - if err != nil { - hmac := hmac.New(sha512.New, []byte("Bitcoin seed")) - hmac.Write([]byte(seed)) - intermediary := hmac.Sum(nil) - - curve := btcutil.Secp256k1() - curveParams := curve.Params() - - // Split it into our key and chain code - keyBytes := intermediary[:32] - fmt.Printf("\t%X\n", keyBytes) - fmt.Printf("\t%X\n", curveParams.N.Bytes()) - keyInt, _ := binary.ReadVarint(bytes.NewBuffer(keyBytes)) - fmt.Printf("\t%d\n", keyInt) - - } - ifExit(err, 0) - fh := bip32.FirstHardenedChild - k, err := masterKey.NewChildKey(fh + 44) - ifExit(err, 44) - k, err = k.NewChildKey(fh + 118) - ifExit(err, 118) - k, err = k.NewChildKey(fh + 0) - ifExit(err, 1) - k, err = k.NewChildKey(0) - ifExit(err, 2) - k, err = k.NewChildKey(0) - ifExit(err, 3) - - priv := k.Key - pub := k.PublicKey().Key - return masterKey.Key, priv, pub -} -*/ - -// Benchmarks -var revBytesCases = [][]byte{ - nil, - []byte(""), - - []byte("12"), - - // 16byte case - []byte("abcdefghijklmnop"), - - // 32byte case - []byte("abcdefghijklmnopqrstuvwxyz123456"), - - // 64byte case - []byte("abcdefghijklmnopqrstuvwxyz123456abcdefghijklmnopqrstuvwxyz123456"), -} - -func BenchmarkReverseBytes(b *testing.B) { - var sink []byte - for i := 0; i < b.N; i++ { - for _, tt := range revBytesCases { - sink = ReverseBytes(tt) - } - } - b.ReportAllocs() - - // sink is necessary to ensure if the compiler tries - // to smart, that it won't optimize away the benchmarks. - if sink != nil { - _ = sink - } -} diff --git a/keys/hd/hdpath.go b/keys/hd/hdpath.go new file mode 100644 index 000000000..00d0572cc --- /dev/null +++ b/keys/hd/hdpath.go @@ -0,0 +1,168 @@ +// Package hd provides basic functionality Hierarchical Deterministic Wallets. +// +// The user must understand the overall concept of the BIP 32 and the BIP 44 specs: +// https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki +// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki +// +// In combination with the bip39 package in go-crypto this package provides the functionality for deriving keys using a +// BIP 44 HD path, or, more general, by passing a BIP 32 path. +// +// In particular, this package (together with bip39) provides all necessary functionality to derive keys from +// mnemonics generated during the cosmos fundraiser. +package hd + +import ( + "crypto/hmac" + "crypto/sha512" + "encoding/binary" + "errors" + "fmt" + "math/big" + "strconv" + "strings" + + "github.com/btcsuite/btcd/btcec" + "github.com/tendermint/go-crypto" +) + +// BIP44Prefix is the parts of the BIP32 HD path that are fixed by what we used during the fundraiser. +const ( + BIP44Prefix = "44'/118'/" + FullFundraiserPath = BIP44Prefix + "0'/0/0" +) + +// BIP44Params wraps BIP 44 params (5 level BIP 32 path). +// To receive a canonical string representation ala +// m / purpose' / coin_type' / account' / change / address_index +// call String() on a BIP44Params instance. +type BIP44Params struct { + purpose uint32 + coinType uint32 + account uint32 + change bool + addressIdx uint32 +} + +// NewParams creates a BIP 44 parameter object from the params: +// m / purpose' / coin_type' / account' / change / address_index +func NewParams(purpose, coinType, account uint32, change bool, addressIdx uint32) *BIP44Params { + return &BIP44Params{ + purpose: purpose, + coinType: coinType, + account: account, + change: change, + addressIdx: addressIdx, + } +} + +// NewFundraiserParams creates a BIP 44 parameter object from the params: +// m / 44' / 118' / account' / 0 / address_index +// The fixed parameters (purpose', coin_type', and change) are determined by what was used in the fundraiser. +func NewFundraiserParams(account uint32, addressIdx uint32) *BIP44Params { + return NewParams(44, 118, account, false, addressIdx) +} + +func (p BIP44Params) String() string { + var changeStr string + if p.change { + changeStr = "1" + } else { + changeStr = "0" + } + // m / purpose' / coin_type' / account' / change / address_index + return fmt.Sprintf("%d'/%d'/%d'/%s/%d", + p.purpose, + p.coinType, + p.account, + changeStr, + p.addressIdx) +} + +// ComputeMastersFromSeed returns the master public key, master secret, and chain code in hex. +func ComputeMastersFromSeed(seed []byte) (secret [32]byte, chainCode [32]byte) { + masterSecret := []byte("Bitcoin seed") + secret, chainCode = i64(masterSecret, seed) + + return +} + +// DerivePrivateKeyForPath derives the private key by following the BIP 32/44 path from privKeyBytes, +// using the given chainCode. +func DerivePrivateKeyForPath(privKeyBytes [32]byte, chainCode [32]byte, path string) ([32]byte, error) { + data := privKeyBytes + parts := strings.Split(path, "/") + for _, part := range parts { + // do we have an apostrophe? + harden := part[len(part)-1:] == "'" + // harden == private derivation, else public derivation: + if harden { + part = part[:len(part)-1] + } + idx, err := strconv.Atoi(part) + if err != nil { + return [32]byte{}, fmt.Errorf("invalid BIP 32 path: %s", err) + } + if idx < 0 { + return [32]byte{}, errors.New("invalid BIP 32 path: index negative ot too large") + } + data, chainCode = derivePrivateKey(data, chainCode, uint32(idx), harden) + } + var derivedKey [32]byte + n := copy(derivedKey[:], data[:]) + if n != 32 || len(data) != 32 { + return [32]byte{}, fmt.Errorf("expected a (secp256k1) key of length 32, got length: %v", len(data)) + } + + return derivedKey, nil +} + +// derivePrivateKey derives the private key with index and chainCode. +// If harden is true, the derivation is 'hardened'. +// It returns the new private key and new chain code. +// For more information on hardened keys see: +// - https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki +func derivePrivateKey(privKeyBytes [32]byte, chainCode [32]byte, index uint32, harden bool) ([32]byte, [32]byte) { + var data []byte + if harden { + index = index | 0x80000000 + data = append([]byte{byte(0)}, privKeyBytes[:]...) + } else { + // this can't return an error: + pubkey := crypto.PrivKeySecp256k1(privKeyBytes).PubKey() + + public := pubkey.(crypto.PubKeySecp256k1) + data = public[:] + } + data = append(data, uint32ToBytes(index)...) + data2, chainCode2 := i64(chainCode[:], data) + x := addScalars(privKeyBytes[:], data2[:]) + return x, chainCode2 +} + +// modular big endian addition +func addScalars(a []byte, b []byte) [32]byte { + aInt := new(big.Int).SetBytes(a) + bInt := new(big.Int).SetBytes(b) + sInt := new(big.Int).Add(aInt, bInt) + x := sInt.Mod(sInt, btcec.S256().N).Bytes() + x2 := [32]byte{} + copy(x2[32-len(x):], x) + return x2 +} + +func uint32ToBytes(i uint32) []byte { + b := [4]byte{} + binary.BigEndian.PutUint32(b[:], i) + return b[:] +} + +// i64 returns the two halfs of the SHA512 HMAC of key and data. +func i64(key []byte, data []byte) (IL [32]byte, IR [32]byte) { + mac := hmac.New(sha512.New, key) + // sha512 does not err + _, _ = mac.Write(data) + I := mac.Sum(nil) + copy(IL[:], I[:32]) + copy(IR[:], I[32:]) + return +} diff --git a/keys/hd/hdpath_test.go b/keys/hd/hdpath_test.go new file mode 100644 index 000000000..b014ae804 --- /dev/null +++ b/keys/hd/hdpath_test.go @@ -0,0 +1,73 @@ +package hd + +import ( + "encoding/hex" + "fmt" + "github.com/tendermint/go-crypto/keys/bip39" +) + +func ExampleStringifyPathParams() { + path := NewParams(44, 0, 0, false, 0) + fmt.Println(path.String()) + // Output: 44'/0'/0'/0/0 +} + +func ExampleSomeBIP32TestVecs() { + + seed := bip39.MnemonicToSeed("barrel original fuel morning among eternal " + + "filter ball stove pluck matrix mechanic") + master, ch := ComputeMastersFromSeed(seed) + fmt.Println("keys from fundraiser test-vector (cosmos, bitcoin, ether)") + fmt.Println() + // cosmos + priv, _ := DerivePrivateKeyForPath(master, ch, FullFundraiserPath) + fmt.Println(hex.EncodeToString(priv[:])) + // bitcoin + priv, _ = DerivePrivateKeyForPath(master, ch, "44'/0'/0'/0/0") + fmt.Println(hex.EncodeToString(priv[:])) + // ether + priv, _ = DerivePrivateKeyForPath(master, ch, "44'/60'/0'/0/0") + fmt.Println(hex.EncodeToString(priv[:])) + + fmt.Println() + fmt.Println("keys generated via https://coinomi.com/recovery-phrase-tool.html") + fmt.Println() + + seed = bip39.MnemonicToSeed( + "advice process birth april short trust crater change bacon monkey medal garment " + + "gorilla ranch hour rival razor call lunar mention taste vacant woman sister") + master, ch = ComputeMastersFromSeed(seed) + priv, _ = DerivePrivateKeyForPath(master, ch, "44'/1'/1'/0/4") + fmt.Println(hex.EncodeToString(priv[:])) + + seed = bip39.MnemonicToSeed("idea naive region square margin day captain habit " + + "gun second farm pact pulse someone armed") + master, ch = ComputeMastersFromSeed(seed) + priv, _ = DerivePrivateKeyForPath(master, ch, "44'/0'/0'/0/420") + fmt.Println(hex.EncodeToString(priv[:])) + + fmt.Println() + fmt.Println("BIP 32 example") + fmt.Println() + + // bip32 path: m/0/7 + seed = bip39.MnemonicToSeed("monitor flock loyal sick object grunt duty ride develop assault harsh history") + master, ch = ComputeMastersFromSeed(seed) + priv, _ = DerivePrivateKeyForPath(master, ch, "0/7") + fmt.Println(hex.EncodeToString(priv[:])) + + // Output: keys from fundraiser test-vector (cosmos, bitcoin, ether) + // + // bfcb217c058d8bbafd5e186eae936106ca3e943889b0b4a093ae13822fd3170c + // e77c3de76965ad89997451de97b95bb65ede23a6bf185a55d80363d92ee37c3d + // 7fc4d8a8146dea344ba04c593517d3f377fa6cded36cd55aee0a0bb968e651bc + // + // keys generated via https://coinomi.com/recovery-phrase-tool.html + // + // a61f10c5fecf40c084c94fa54273b6f5d7989386be4a37669e6d6f7b0169c163 + // 32c4599843de3ef161a629a461d12c60b009b676c35050be5f7ded3a3b23501f + // + // BIP 32 example + // + // c4c11d8c03625515905d7e89d25dfc66126fbc629ecca6db489a1a72fc4bda78 +} diff --git a/keys/keybase.go b/keys/keybase.go index 79e6f15fa..b55658d2f 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -7,62 +7,117 @@ import ( "strings" "github.com/pkg/errors" - crypto "github.com/tendermint/go-crypto" - "github.com/tendermint/go-crypto/keys/words" + "github.com/tendermint/go-crypto" + "github.com/tendermint/go-crypto/keys/bip39" + "github.com/tendermint/go-crypto/keys/hd" dbm "github.com/tendermint/tmlibs/db" ) -// dbKeybase combines encyption and storage implementation to provide +var _ Keybase = dbKeybase{} + +// Language is a language to create the BIP 39 mnemonic in. +// Currently, only english is supported though. +// Find a list of all supported languages in the BIP 39 spec (word lists). +type Language int + +const ( + // English is the default language to create a mnemonic. + // It is the only supported language by this package. + English Language = iota + 1 + // Japanese is currently not supported. + Japanese + // Korean is currently not supported. + Korean + // Spanish is currently not supported. + Spanish + // ChineseSimplified is currently not supported. + ChineseSimplified + // ChineseTraditional is currently not supported. + ChineseTraditional + // French is currently not supported. + French + // Italian is currently not supported. + Italian +) + +var ( + // ErrUnsupportedSigningAlgo is raised when the caller tries to use a different signing scheme than secp256k1. + ErrUnsupportedSigningAlgo = errors.New("unsupported signing algo: only secp256k1 is supported") + // ErrUnsupportedLanguage is raised when the caller tries to use a different language than english for creating + // a mnemonic sentence. + ErrUnsupportedLanguage = errors.New("unsupported language: only english is supported") +) + +// dbKeybase combines encryption and storage implementation to provide // a full-featured key manager type dbKeybase struct { - db dbm.DB - codec words.Codec + db dbm.DB } -func New(db dbm.DB, codec words.Codec) dbKeybase { +// New creates a new keybase instance using the passed DB for reading and writing keys. +func New(db dbm.DB) Keybase { return dbKeybase{ - db: db, - codec: codec, + db: db, } } -var _ Keybase = dbKeybase{} - // CreateMnemonic generates a new key and persists it to storage, encrypted -// using the passphrase. It returns the generated seedphrase -// (mnemonic) and the key Info. It returns an error if it fails to +// using the provided password. +// It returns the generated mnemonic and the key Info. +// It returns an error if it fails to // generate a key for the given algo type, or if another key is // already stored under the same name. -func (kb dbKeybase) CreateMnemonic(name, passphrase string, algo SignAlgo) (Info, string, error) { - // NOTE: secret is SHA256 hashed by secp256k1 and ed25519. - // 16 byte secret corresponds to 12 BIP39 words. - // XXX: Ledgers use 24 words now - should we ? - secret := crypto.CRandBytes(16) - priv, err := generate(algo, secret) +func (kb dbKeybase) CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, mnemonic string, err error) { + if language != English { + return nil, "", ErrUnsupportedLanguage + } + if algo != Secp256k1 { + err = ErrUnsupportedSigningAlgo + return + } + + // default number of words (24): + mnemonicS, err := bip39.NewMnemonic(bip39.FreshKey) if err != nil { - return nil, "", err + return } + mnemonic = strings.Join(mnemonicS, " ") + seed := bip39.MnemonicToSeed(mnemonic) + info, err = kb.persistDerivedKey(seed, passwd, name, hd.FullFundraiserPath) + return +} - // encrypt and persist the key - info := kb.writeLocalKey(priv, name, passphrase) +// CreateFundraiserKey converts a mnemonic to a private key and persists it, +// encrypted with the given password. +// TODO(ismail) +func (kb dbKeybase) CreateFundraiserKey(name, mnemonic, passwd string) (info Info, err error) { + words := strings.Split(mnemonic, " ") + if len(words) != 12 { + err = fmt.Errorf("recovering only works with 12 word (fundraiser) mnemonics, got: %v words", len(words)) + return + } + seed, err := bip39.MnemonicToSeedWithErrChecking(mnemonic) + if err != nil { + return + } + info, err = kb.persistDerivedKey(seed, passwd, name, hd.FullFundraiserPath) + return +} - // we append the type byte to the serialized secret to help with - // recovery - // ie [secret] = [type] + [secret] - typ := cryptoAlgoToByte(algo) - secret = append([]byte{typ}, secret...) +func (kb dbKeybase) Derive(name, mnemonic, passwd string, params hd.BIP44Params) (info Info, err error) { + seed, err := bip39.MnemonicToSeedWithErrChecking(mnemonic) + if err != nil { + return + } + info, err = kb.persistDerivedKey(seed, passwd, name, params.String()) - // return the mnemonic phrase - words, err := kb.codec.BytesToWords(secret) - seed := strings.Join(words, " ") - return info, seed, err + return } - // CreateLedger creates a new locally-stored reference to a Ledger keypair // It returns the created key info and an error if the Ledger could not be queried -func (kb dbKeybase) CreateLedger(name string, path crypto.DerivationPath, algo SignAlgo) (Info, error) { - if algo != AlgoSecp256k1 { - return nil, fmt.Errorf("Only secp256k1 is supported for Ledger devices") +func (kb dbKeybase) CreateLedger(name string, path crypto.DerivationPath, algo SigningAlgo) (Info, error) { + if algo != Secp256k1 { + return nil, ErrUnsupportedSigningAlgo } priv, err := crypto.NewPrivKeyLedgerSecp256k1(path) if err != nil { @@ -78,29 +133,24 @@ func (kb dbKeybase) CreateOffline(name string, pub crypto.PubKey) (Info, error) return kb.writeOfflineKey(pub, name), nil } -// Recover converts a seedphrase to a private key and persists it, -// encrypted with the given passphrase. Functions like Create, but -// seedphrase is input not output. -func (kb dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { - words := strings.Split(strings.TrimSpace(seedphrase), " ") - secret, err := kb.codec.WordsToBytes(words) - if err != nil { - return nil, err - } - // secret is comprised of the actual secret with the type - // appended. - // ie [secret] = [type] + [secret] - typ, secret := secret[0], secret[1:] - algo := byteToSignAlgo(typ) - priv, err := generate(algo, secret) +func (kb *dbKeybase) persistDerivedKey(seed []byte, passwd, name, fullHdPath string) (info Info, err error) { + // create master key and derive first key: + masterPriv, ch := hd.ComputeMastersFromSeed(seed) + derivedPriv, err := hd.DerivePrivateKeyForPath(masterPriv, ch, fullHdPath) if err != nil { - return nil, err + return } - // encrypt and persist key. - public := kb.writeLocalKey(priv, name, passphrase) - return public, nil + // if we have a password, use it to encrypt the private key and store it + // else store the public key only + if passwd != "" { + info = kb.writeLocalKey(crypto.PrivKeySecp256k1(derivedPriv), name, passwd) + } else { + pubk := crypto.PrivKeySecp256k1(derivedPriv).PubKey() + info = kb.writeOfflineKey(pubk, name) + } + return } // List returns the keys from storage in alphabetical order. @@ -173,7 +223,7 @@ func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signat func (kb dbKeybase) Export(name string) (armor string, err error) { bz := kb.db.Get(infoKey(name)) if bz == nil { - return "", errors.New("No key to export with name " + name) + return "", fmt.Errorf("no key to export with name %s", name) } return armorInfoBytes(bz), nil } @@ -184,7 +234,7 @@ func (kb dbKeybase) Export(name string) (armor string, err error) { func (kb dbKeybase) ExportPubKey(name string) (armor string, err error) { bz := kb.db.Get(infoKey(name)) if bz == nil { - return "", errors.New("No key to export with name " + name) + return "", fmt.Errorf("no key to export with name %s", name) } info, err := readInfo(bz) if err != nil { @@ -276,7 +326,7 @@ func (kb dbKeybase) Update(name, oldpass, newpass string) error { kb.writeLocalKey(key, name, newpass) return nil default: - return fmt.Errorf("Locally stored key required") + return fmt.Errorf("locally stored key required") } } @@ -307,18 +357,6 @@ func (kb dbKeybase) writeInfo(info Info, name string) { kb.db.SetSync(infoKey(name), writeInfo(info)) } -func generate(algo SignAlgo, secret []byte) (crypto.PrivKey, error) { - switch algo { - case AlgoEd25519: - return crypto.GenPrivKeyEd25519FromSecret(secret), nil - case AlgoSecp256k1: - return crypto.GenPrivKeySecp256k1FromSecret(secret), nil - default: - err := errors.Errorf("Cannot generate keys for algorithm: %s", algo) - return nil, err - } -} - func infoKey(name string) []byte { return []byte(fmt.Sprintf("%s.info", name)) } diff --git a/keys/keybase_test.go b/keys/keybase_test.go index 5caf82af8..a3957f8e9 100644 --- a/keys/keybase_test.go +++ b/keys/keybase_test.go @@ -6,24 +6,21 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - - dbm "github.com/tendermint/tmlibs/db" - "github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto/keys" - "github.com/tendermint/go-crypto/keys/words" + "github.com/tendermint/go-crypto/keys/hd" + + dbm "github.com/tendermint/tmlibs/db" ) // TestKeyManagement makes sure we can manipulate these keys well func TestKeyManagement(t *testing.T) { - // make the storage with reasonable defaults cstore := keys.New( dbm.NewMemDB(), - words.MustLoadCodec("english"), ) - algo := keys.AlgoEd25519 + algo := keys.Secp256k1 n1, n2, n3 := "personal", "business", "other" p1, p2 := "1234", "really-secure!@#$" @@ -32,14 +29,18 @@ func TestKeyManagement(t *testing.T) { require.Nil(t, err) assert.Empty(t, l) + _, _, err = cstore.CreateMnemonic(n1, keys.English, p1, keys.Ed25519) + assert.Error(t, err, "ed25519 keys are currently not supported by keybase") + // create some keys _, err = cstore.Get(n1) - assert.NotNil(t, err) - i, _, err := cstore.CreateMnemonic(n1, p1, algo) + assert.Error(t, err) + i, _, err := cstore.CreateMnemonic(n1, keys.English, p1, algo) + + require.NoError(t, err) require.Equal(t, n1, i.GetName()) - require.Nil(t, err) - _, _, err = cstore.CreateMnemonic(n2, p2, algo) - require.Nil(t, err) + _, _, err = cstore.CreateMnemonic(n2, keys.English, p2, algo) + require.NoError(t, err) // we can get these keys i2, err := cstore.Get(n2) @@ -49,7 +50,7 @@ func TestKeyManagement(t *testing.T) { // list shows them in order keyS, err := cstore.List() - require.Nil(t, err) + require.NoError(t, err) require.Equal(t, 2, len(keyS)) // note these are in alphabetical order assert.Equal(t, n2, keyS[0].GetName()) @@ -60,12 +61,12 @@ func TestKeyManagement(t *testing.T) { err = cstore.Delete("bad name", "foo") require.NotNil(t, err) err = cstore.Delete(n1, p1) - require.Nil(t, err) + require.NoError(t, err) keyS, err = cstore.List() - require.Nil(t, err) + require.NoError(t, err) assert.Equal(t, 1, len(keyS)) _, err = cstore.Get(n1) - assert.NotNil(t, err) + assert.Error(t, err) // create an offline key o1 := "offline" @@ -76,56 +77,45 @@ func TestKeyManagement(t *testing.T) { require.Equal(t, pub1, i.GetPubKey()) require.Equal(t, o1, i.GetName()) keyS, err = cstore.List() + require.NoError(t, err) require.Equal(t, 2, len(keyS)) // delete the offline key err = cstore.Delete(o1, "no") require.NotNil(t, err) err = cstore.Delete(o1, "yes") - require.Nil(t, err) + require.NoError(t, err) keyS, err = cstore.List() + require.NoError(t, err) require.Equal(t, 1, len(keyS)) - - // make sure that it only signs with the right password - // tx := mock.NewSig([]byte("mytransactiondata")) - // err = cstore.Sign(n2, p1, tx) - // assert.NotNil(t, err) - // err = cstore.Sign(n2, p2, tx) - // assert.Nil(t, err, "%+v", err) - // sigs, err := tx.Signers() - // assert.Nil(t, err, "%+v", err) - // if assert.Equal(t, 1, len(sigs)) { - // assert.Equal(t, i2.PubKey, sigs[0]) - // } } // TestSignVerify does some detailed checks on how we sign and validate // signatures func TestSignVerify(t *testing.T) { - - // make the storage with reasonable defaults cstore := keys.New( dbm.NewMemDB(), - words.MustLoadCodec("english"), ) - algo := keys.AlgoSecp256k1 + algo := keys.Secp256k1 n1, n2, n3 := "some dude", "a dudette", "dude-ish" p1, p2, p3 := "1234", "foobar", "foobar" // create two users and get their info - i1, _, err := cstore.CreateMnemonic(n1, p1, algo) + i1, _, err := cstore.CreateMnemonic(n1, keys.English, p1, algo) require.Nil(t, err) - i2, _, err := cstore.CreateMnemonic(n2, p2, algo) + i2, _, err := cstore.CreateMnemonic(n2, keys.English, p2, algo) require.Nil(t, err) // Import a public key armor, err := cstore.ExportPubKey(n2) require.Nil(t, err) cstore.ImportPubKey(n3, armor) - _, err = cstore.Get(n3) - require.Nil(t, err) + i3, err := cstore.Get(n3) + require.NoError(t, err) + require.Equal(t, i3.GetName(), n3) + // let's try to sign some messages d1 := []byte("my first message") @@ -178,61 +168,6 @@ func TestSignVerify(t *testing.T) { assert.NotNil(t, err) } -/* -// TestSignWithLedger makes sure we have ledger compatibility with -// the crypto store. -// -// This test will only succeed with a ledger attached to the computer -// and the cosmos app open -func TestSignWithLedger(t *testing.T) { - if os.Getenv("WITH_LEDGER") == "" { - t.Skip("Set WITH_LEDGER to run code on real ledger") - } - - // make the storage with reasonable defaults - cstore := keys.New( - dbm.NewMemDB(), - words.MustLoadCodec("english"), - ) - n := "nano-s" - p := "hard2hack" - - // create a nano user - c, _, err := cstore.Create(n, p, nano.KeyLedgerEd25519) - require.Nil(t, err, "%+v", err) - assert.Equal(t, c.Key, n) - _, ok := c.PubKey.Unwrap().(nano.PubKeyLedgerEd25519) - require.True(t, ok) - - // make sure we can get it back - info, err := cstore.Get(n) - require.Nil(t, err, "%+v", err) - assert.Equal(t, info.Key, n) - key := info.PubKey - require.False(t ,key.Empty()) - require.True(t, key.Equals(c.PubKey)) - - // let's try to sign some messages - d1 := []byte("welcome to cosmos") - d2 := []byte("please turn on the app") - - // try signing both data with the ledger... - s1, pub, err := cstore.Sign(n, p, d1) - require.Nil(t, err) - require.Equal(t, info.PubKey, pub) - - s2, pub, err := cstore.Sign(n, p, d2) - require.Nil(t, err) - require.Equal(t, info.PubKey, pub) - - // now, let's check those signatures work - assert.True(t, key.VerifyBytes(d1, s1)) - assert.True(t, key.VerifyBytes(d2, s2)) - // and mismatched signatures don't - assert.False(t, key.VerifyBytes(d1, s2)) -} -*/ - func assertPassword(t *testing.T, cstore keys.Keybase, name, pass, badpass string) { err := cstore.Update(name, badpass, pass) assert.NotNil(t, err) @@ -247,18 +182,16 @@ func TestExportImport(t *testing.T) { db := dbm.NewMemDB() cstore := keys.New( db, - words.MustLoadCodec("english"), ) - info, _, err := cstore.CreateMnemonic("john", "passphrase", keys.AlgoEd25519) + info, _, err := cstore.CreateMnemonic("john", keys.English,"secretcpw", keys.Secp256k1) assert.NoError(t, err) assert.Equal(t, info.GetName(), "john") - addr := info.GetPubKey().Address() john, err := cstore.Get("john") assert.NoError(t, err) - assert.Equal(t, john.GetName(), "john") - assert.Equal(t, john.GetPubKey().Address(), addr) + assert.Equal(t, info.GetName(), "john") + johnAddr := info.GetPubKey().Address() armor, err := cstore.Export("john") assert.NoError(t, err) @@ -269,22 +202,23 @@ func TestExportImport(t *testing.T) { john2, err := cstore.Get("john2") assert.NoError(t, err) - assert.Equal(t, john.GetPubKey().Address(), addr) + assert.Equal(t, john.GetPubKey().Address(), johnAddr) assert.Equal(t, john.GetName(), "john") assert.Equal(t, john, john2) } - +// func TestExportImportPubKey(t *testing.T) { // make the storage with reasonable defaults db := dbm.NewMemDB() cstore := keys.New( db, - words.MustLoadCodec("english"), ) - // Create a private-public key pair and ensure consistency - info, _, err := cstore.CreateMnemonic("john", "passphrase", keys.AlgoEd25519) - assert.NoError(t, err) + // CreateMnemonic a private-public key pair and ensure consistency + notPasswd := "n9y25ah7" + info, _, err := cstore.CreateMnemonic("john", keys.English, notPasswd, keys.Secp256k1) + assert.Nil(t, err) + assert.NotEqual(t, info, "") assert.Equal(t, info.GetName(), "john") addr := info.GetPubKey().Address() john, err := cstore.Get("john") @@ -320,15 +254,14 @@ func TestAdvancedKeyManagement(t *testing.T) { // make the storage with reasonable defaults cstore := keys.New( dbm.NewMemDB(), - words.MustLoadCodec("english"), ) - algo := keys.AlgoSecp256k1 + algo := keys.Secp256k1 n1, n2 := "old-name", "new name" p1, p2 := "1234", "foobar" // make sure key works with initial password - _, _, err := cstore.CreateMnemonic(n1, p1, algo) + _, _, err := cstore.CreateMnemonic(n1, keys.English, p1, algo) require.Nil(t, err, "%+v", err) assertPassword(t, cstore, n1, p1, p2) @@ -370,18 +303,17 @@ func TestSeedPhrase(t *testing.T) { // make the storage with reasonable defaults cstore := keys.New( dbm.NewMemDB(), - words.MustLoadCodec("english"), ) - algo := keys.AlgoEd25519 + algo := keys.Secp256k1 n1, n2 := "lost-key", "found-again" p1, p2 := "1234", "foobar" // make sure key works with initial password - info, seed, err := cstore.CreateMnemonic(n1, p1, algo) + info, mnemonic, err := cstore.CreateMnemonic(n1, keys.English, p1, algo) require.Nil(t, err, "%+v", err) assert.Equal(t, n1, info.GetName()) - assert.NotEmpty(t, seed) + assert.NotEmpty(t, mnemonic) // now, let us delete this key err = cstore.Delete(n1, p1) @@ -389,9 +321,10 @@ func TestSeedPhrase(t *testing.T) { _, err = cstore.Get(n1) require.NotNil(t, err) - // let us re-create it from the seed-phrase - newInfo, err := cstore.Recover(n2, p2, seed) - require.Nil(t, err, "%+v", err) + // let us re-create it from the mnemonic-phrase + params := *hd.NewFundraiserParams(0 ,0 ) + newInfo, err := cstore.Derive(n2,mnemonic, p2, params) + require.NoError(t, err) assert.Equal(t, n2, newInfo.GetName()) assert.Equal(t, info.GetPubKey().Address(), newInfo.GetPubKey().Address()) assert.Equal(t, info.GetPubKey(), newInfo.GetPubKey()) @@ -401,13 +334,12 @@ func ExampleNew() { // Select the encryption and storage for your cryptostore cstore := keys.New( dbm.NewMemDB(), - words.MustLoadCodec("english"), ) - ed := keys.AlgoEd25519 - sec := keys.AlgoSecp256k1 + + sec := keys.Secp256k1 // Add keys and see they return in alphabetical order - bob, _, err := cstore.CreateMnemonic("Bob", "friend", ed) + bob, _, err := cstore.CreateMnemonic("Bob", keys.English, "friend", sec) if err != nil { // this should never happen fmt.Println(err) @@ -415,8 +347,8 @@ func ExampleNew() { // return info here just like in List fmt.Println(bob.GetName()) } - cstore.CreateMnemonic("Alice", "secret", sec) - cstore.CreateMnemonic("Carl", "mitm", ed) + cstore.CreateMnemonic("Alice", keys.English, "secret", sec) + cstore.CreateMnemonic("Carl", keys.English, "mitm", sec) info, _ := cstore.List() for _, i := range info { fmt.Println(i.GetName()) @@ -429,7 +361,7 @@ func ExampleNew() { fmt.Println("don't accept real passphrase") } - // and we can validate the signature with publically available info + // and we can validate the signature with publicly available info binfo, _ := cstore.Get("Bob") if !binfo.GetPubKey().Equals(bob.GetPubKey()) { fmt.Println("Get and Create return different keys") diff --git a/keys/keys.go b/keys/keys.go index c8e25da3c..b3fad70f3 100644 --- a/keys/keys.go +++ b/keys/keys.go @@ -1,32 +1,12 @@ package keys -import "fmt" - -type SignAlgo string +// SigningAlgo defines an algorithm to derive key-pairs which can be used for cryptographic signing. +type SigningAlgo string const ( - AlgoEd25519 = SignAlgo("ed25519") - AlgoSecp256k1 = SignAlgo("secp256k1") -) - -func cryptoAlgoToByte(key SignAlgo) byte { - switch key { - case AlgoEd25519: - return 0x01 - case AlgoSecp256k1: - return 0x02 - default: - panic(fmt.Sprintf("Unexpected type key %v", key)) - } -} - -func byteToSignAlgo(b byte) SignAlgo { - switch b { - case 0x01: - return AlgoEd25519 - case 0x02: - return AlgoSecp256k1 - default: - panic(fmt.Sprintf("Unexpected type byte %X", b)) - } -} + // Secp256k1 uses the Bitcoin secp256k1 ECDSA parameters. + Secp256k1 = SigningAlgo("secp256k1") + // Ed25519 represents the Ed25519 signature system. + // It is currently not supported for end-user keys (wallets/ledgers). + Ed25519 = SigningAlgo("ed25519") +) \ No newline at end of file diff --git a/keys/types.go b/keys/types.go index 53821e8bf..09fbb399e 100644 --- a/keys/types.go +++ b/keys/types.go @@ -2,6 +2,7 @@ package keys import ( crypto "github.com/tendermint/go-crypto" + "github.com/tendermint/go-crypto/keys/hd" ) // Keybase exposes operations on a generic keystore @@ -15,13 +16,15 @@ type Keybase interface { // Sign some bytes, looking up the private key to use Sign(name, passphrase string, msg []byte) (crypto.Signature, crypto.PubKey, error) - // Create a new locally-stored keypair, returning the mnemonic - CreateMnemonic(name, passphrase string, algo SignAlgo) (info Info, seed string, err error) - // Recover takes a seedphrase and loads in the key - Recover(name, passphrase, seedphrase string) (info Info, erro error) - + // CreateMnemonic creates a new mnemonic, and derives a hierarchical deterministic + // key from that. + CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, seed string, err error) + // CreateFundraiserKey takes a mnemonic and derives, a password + CreateFundraiserKey(name, mnemonic, passwd string) (info Info, err error) + // Derive derives a key from the passed mnemonic using a BIP44 path. + Derive(name, mnemonic, passwd string, params hd.BIP44Params) (Info, error) // Create, store, and return a new Ledger key reference - CreateLedger(name string, path crypto.DerivationPath, algo SignAlgo) (info Info, err error) + CreateLedger(name string, path crypto.DerivationPath, algo SigningAlgo) (info Info, err error) // Create, store, and return a new offline key reference CreateOffline(name string, pubkey crypto.PubKey) (info Info, err error) @@ -34,7 +37,7 @@ type Keybase interface { ExportPubKey(name string) (armor string, err error) } -// Publically exposed information about a keypair +// Info is the publicly exposed information about a keypair type Info interface { // Human-readable type for key listing GetType() string diff --git a/keys/words/ecc.go b/keys/words/ecc.go deleted file mode 100644 index c511ad6e4..000000000 --- a/keys/words/ecc.go +++ /dev/null @@ -1,208 +0,0 @@ -package words - -import ( - "encoding/binary" - "errors" - "hash/crc32" - "hash/crc64" - - "github.com/howeyc/crc16" -) - -// ECC is used for anything that calculates an error-correcting code -type ECC interface { - // AddECC calculates an error-correcting code for the input - // returns an output with the code appended - AddECC([]byte) []byte - - // CheckECC verifies if the ECC is proper on the input and returns - // the data with the code removed, or an error - CheckECC([]byte) ([]byte, error) -} - -var errInputTooShort = errors.New("input too short, no checksum present") -var errChecksumDoesntMatch = errors.New("checksum does not match") - -// NoECC is a no-op placeholder, kind of useless... except for tests -type NoECC struct{} - -var _ ECC = NoECC{} - -func (_ NoECC) AddECC(input []byte) []byte { return input } -func (_ NoECC) CheckECC(input []byte) ([]byte, error) { return input, nil } - -// CRC16 does the ieee crc16 polynomial check -type CRC16 struct { - Poly uint16 - table *crc16.Table -} - -var _ ECC = (*CRC16)(nil) - -const crc16ByteCount = 2 - -func NewIBMCRC16() *CRC16 { - return &CRC16{Poly: crc16.IBM} -} - -func NewSCSICRC16() *CRC16 { - return &CRC16{Poly: crc16.SCSI} -} - -func NewCCITTCRC16() *CRC16 { - return &CRC16{Poly: crc16.CCITT} -} - -func (c *CRC16) AddECC(input []byte) []byte { - table := c.getTable() - - // get crc and convert to some bytes... - crc := crc16.Checksum(input, table) - check := make([]byte, crc16ByteCount) - binary.BigEndian.PutUint16(check, crc) - - // append it to the input - output := append(input, check...) - return output -} - -func (c *CRC16) CheckECC(input []byte) ([]byte, error) { - table := c.getTable() - - if len(input) <= crc16ByteCount { - return nil, errInputTooShort - } - cut := len(input) - crc16ByteCount - data, check := input[:cut], input[cut:] - crc := binary.BigEndian.Uint16(check) - calc := crc16.Checksum(data, table) - if crc != calc { - return nil, errChecksumDoesntMatch - } - return data, nil -} - -func (c *CRC16) getTable() *crc16.Table { - if c.table != nil { - return c.table - } - if c.Poly == 0 { - c.Poly = crc16.IBM - } - c.table = crc16.MakeTable(c.Poly) - return c.table -} - -// CRC32 does the ieee crc32 polynomial check -type CRC32 struct { - Poly uint32 - table *crc32.Table -} - -var _ ECC = (*CRC32)(nil) - -func NewIEEECRC32() *CRC32 { - return &CRC32{Poly: crc32.IEEE} -} - -func NewCastagnoliCRC32() *CRC32 { - return &CRC32{Poly: crc32.Castagnoli} -} - -func NewKoopmanCRC32() *CRC32 { - return &CRC32{Poly: crc32.Koopman} -} - -func (c *CRC32) AddECC(input []byte) []byte { - table := c.getTable() - - // get crc and convert to some bytes... - crc := crc32.Checksum(input, table) - check := make([]byte, crc32.Size) - binary.BigEndian.PutUint32(check, crc) - - // append it to the input - output := append(input, check...) - return output -} - -func (c *CRC32) CheckECC(input []byte) ([]byte, error) { - table := c.getTable() - - if len(input) <= crc32.Size { - return nil, errInputTooShort - } - cut := len(input) - crc32.Size - data, check := input[:cut], input[cut:] - crc := binary.BigEndian.Uint32(check) - calc := crc32.Checksum(data, table) - if crc != calc { - return nil, errChecksumDoesntMatch - } - return data, nil -} - -func (c *CRC32) getTable() *crc32.Table { - if c.table == nil { - if c.Poly == 0 { - c.Poly = crc32.IEEE - } - c.table = crc32.MakeTable(c.Poly) - } - return c.table -} - -// CRC64 does the ieee crc64 polynomial check -type CRC64 struct { - Poly uint64 - table *crc64.Table -} - -var _ ECC = (*CRC64)(nil) - -func NewISOCRC64() *CRC64 { - return &CRC64{Poly: crc64.ISO} -} - -func NewECMACRC64() *CRC64 { - return &CRC64{Poly: crc64.ECMA} -} - -func (c *CRC64) AddECC(input []byte) []byte { - table := c.getTable() - - // get crc and convert to some bytes... - crc := crc64.Checksum(input, table) - check := make([]byte, crc64.Size) - binary.BigEndian.PutUint64(check, crc) - - // append it to the input - output := append(input, check...) - return output -} - -func (c *CRC64) CheckECC(input []byte) ([]byte, error) { - table := c.getTable() - - if len(input) <= crc64.Size { - return nil, errInputTooShort - } - cut := len(input) - crc64.Size - data, check := input[:cut], input[cut:] - crc := binary.BigEndian.Uint64(check) - calc := crc64.Checksum(data, table) - if crc != calc { - return nil, errChecksumDoesntMatch - } - return data, nil -} - -func (c *CRC64) getTable() *crc64.Table { - if c.table == nil { - if c.Poly == 0 { - c.Poly = crc64.ISO - } - c.table = crc64.MakeTable(c.Poly) - } - return c.table -} diff --git a/keys/words/ecc_test.go b/keys/words/ecc_test.go deleted file mode 100644 index 9e1772b9f..000000000 --- a/keys/words/ecc_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package words - -import ( - "testing" - - asrt "github.com/stretchr/testify/assert" - - cmn "github.com/tendermint/tmlibs/common" -) - -var codecs = []ECC{ - NewIBMCRC16(), - NewSCSICRC16(), - NewCCITTCRC16(), - NewIEEECRC32(), - NewCastagnoliCRC32(), - NewKoopmanCRC32(), - NewISOCRC64(), - NewECMACRC64(), -} - -// TestECCPasses makes sure that the AddECC/CheckECC methods are symetric -func TestECCPasses(t *testing.T) { - assert := asrt.New(t) - - checks := append(codecs, NoECC{}) - - for _, check := range checks { - for i := 0; i < 2000; i++ { - numBytes := cmn.RandInt()%60 + 1 - data := cmn.RandBytes(numBytes) - - checked := check.AddECC(data) - res, err := check.CheckECC(checked) - if assert.Nil(err, "%#v: %+v", check, err) { - assert.Equal(data, res, "%v", check) - } - } - } -} - -// TestECCFails makes sure random data will (usually) fail the checksum -func TestECCFails(t *testing.T) { - assert := asrt.New(t) - - checks := codecs - attempts := 2000 - - for _, check := range checks { - failed := 0 - for i := 0; i < attempts; i++ { - numBytes := cmn.RandInt()%60 + 1 - data := cmn.RandBytes(numBytes) - _, err := check.CheckECC(data) - if err != nil { - failed += 1 - } - } - // we allow up to 1 falsely accepted checksums, as there are random matches - assert.InDelta(attempts, failed, 1, "%v", check) - } -} diff --git a/keys/words/wordcodec.go b/keys/words/wordcodec.go deleted file mode 100644 index 27032ce32..000000000 --- a/keys/words/wordcodec.go +++ /dev/null @@ -1,200 +0,0 @@ -package words - -import ( - "math/big" - "strings" - - "github.com/pkg/errors" - - "github.com/tendermint/go-crypto/keys/words/wordlist" -) - -const BankSize = 2048 - -// TODO: add error-checking codecs for invalid phrases - -type Codec interface { - BytesToWords([]byte) ([]string, error) - WordsToBytes([]string) ([]byte, error) -} - -type WordCodec struct { - words []string - bytes map[string]int - check ECC -} - -var _ Codec = &WordCodec{} - -func NewCodec(words []string) (codec *WordCodec, err error) { - if len(words) != BankSize { - return codec, errors.Errorf("Bank must have %d words, found %d", BankSize, len(words)) - } - - res := &WordCodec{ - words: words, - // TODO: configure this outside??? - check: NewIEEECRC32(), - // check: NewIBMCRC16(), - } - - return res, nil -} - -// LoadCodec loads a pre-compiled language file -func LoadCodec(bank string) (codec *WordCodec, err error) { - words, err := loadBank(bank) - if err != nil { - return codec, err - } - return NewCodec(words) -} - -// MustLoadCodec panics if word bank is missing, only for tests -func MustLoadCodec(bank string) *WordCodec { - codec, err := LoadCodec(bank) - if err != nil { - panic(err) - } - return codec -} - -// loadBank opens a wordlist file and returns all words inside -func loadBank(bank string) ([]string, error) { - filename := "keys/words/wordlist/" + bank + ".txt" - words, err := wordlist.Asset(filename) - if err != nil { - return nil, err - } - wordsAll := strings.Split(strings.TrimSpace(string(words)), "\n") - return wordsAll, nil -} - -// // TODO: read from go-bind assets -// func getData(filename string) (string, error) { -// f, err := os.Open(filename) -// if err != nil { -// return "", errors.WithStack(err) -// } -// defer f.Close() - -// data, err := ioutil.ReadAll(f) -// if err != nil { -// return "", errors.WithStack(err) -// } - -// return string(data), nil -// } - -// given this many bytes, we will produce this many words -func wordlenFromBytes(numBytes int) int { - // 2048 words per bank, which is 2^11. - // 8 bits per byte, and we add +10 so it rounds up - return (8*numBytes + 10) / 11 -} - -// given this many words, we will produce this many bytes. -// sometimes there are two possibilities. -// if maybeShorter is true, then represents len OR len-1 bytes -func bytelenFromWords(numWords int) (length int, maybeShorter bool) { - // calculate the max number of complete bytes we could store in this word - length = 11 * numWords / 8 - // if one less byte would also generate this length, set maybeShorter - if wordlenFromBytes(length-1) == numWords { - maybeShorter = true - } - return -} - -// TODO: add checksum -func (c *WordCodec) BytesToWords(raw []byte) (words []string, err error) { - // always add a checksum to the data - data := c.check.AddECC(raw) - numWords := wordlenFromBytes(len(data)) - - n2048 := big.NewInt(2048) - nData := big.NewInt(0).SetBytes(data) - nRem := big.NewInt(0) - // Alternative, use condition "nData.BitLen() > 0" - // to allow for shorter words when data has leading 0's - for i := 0; i < numWords; i++ { - nData.DivMod(nData, n2048, nRem) - rem := nRem.Int64() - w := c.words[rem] - // double-check bank on generation... - _, err := c.GetIndex(w) - if err != nil { - return nil, err - } - words = append(words, w) - } - return words, nil -} - -func (c *WordCodec) WordsToBytes(words []string) ([]byte, error) { - l := len(words) - - if l == 0 { - return nil, errors.New("Didn't provide any words") - } - - n2048 := big.NewInt(2048) - nData := big.NewInt(0) - // since we output words based on the remainder, the first word has the lowest - // value... we must load them in reverse order - for i := 1; i <= l; i++ { - rem, err := c.GetIndex(words[l-i]) - if err != nil { - return nil, err - } - nRem := big.NewInt(int64(rem)) - nData.Mul(nData, n2048) - nData.Add(nData, nRem) - } - - // we copy into a slice of the expected size, so it is not shorter if there - // are lots of leading 0s - dataBytes := nData.Bytes() - - // copy into the container we have with the expected size - outLen, flex := bytelenFromWords(len(words)) - toCheck := make([]byte, outLen) - if len(dataBytes) > outLen { - return nil, errors.New("Invalid data, could not have been generated by this codec") - } - copy(toCheck[outLen-len(dataBytes):], dataBytes) - - // validate the checksum... - output, err := c.check.CheckECC(toCheck) - if flex && err != nil { - // if flex, try again one shorter.... - toCheck = toCheck[1:] - output, err = c.check.CheckECC(toCheck) - } - - return output, err -} - -// GetIndex finds the index of the words to create bytes -// Generates a map the first time it is loaded, to avoid needless -// computation when list is not used. -func (c *WordCodec) GetIndex(word string) (int, error) { - // generate the first time - if c.bytes == nil { - b := map[string]int{} - for i, w := range c.words { - if _, ok := b[w]; ok { - return -1, errors.Errorf("Duplicate word in list: %s", w) - } - b[w] = i - } - c.bytes = b - } - - // get the index, or an error - rem, ok := c.bytes[word] - if !ok { - return -1, errors.Errorf("Unrecognized word: %s", word) - } - return rem, nil -} diff --git a/keys/words/wordcodec_test.go b/keys/words/wordcodec_test.go deleted file mode 100644 index 367e3799a..000000000 --- a/keys/words/wordcodec_test.go +++ /dev/null @@ -1,180 +0,0 @@ -package words - -import ( - "testing" - - asrt "github.com/stretchr/testify/assert" - rqr "github.com/stretchr/testify/require" - - cmn "github.com/tendermint/tmlibs/common" -) - -func TestLengthCalc(t *testing.T) { - assert := asrt.New(t) - - cases := []struct { - bytes, words int - flexible bool - }{ - {1, 1, false}, - {2, 2, false}, - // bytes pairs with same word count - {3, 3, true}, - {4, 3, true}, - {5, 4, false}, - // bytes pairs with same word count - {10, 8, true}, - {11, 8, true}, - {12, 9, false}, - {13, 10, false}, - {20, 15, false}, - // bytes pairs with same word count - {21, 16, true}, - {32, 24, true}, - } - - for _, tc := range cases { - wl := wordlenFromBytes(tc.bytes) - assert.Equal(tc.words, wl, "%d", tc.bytes) - - bl, flex := bytelenFromWords(tc.words) - assert.Equal(tc.flexible, flex, "%d", tc.words) - if !flex { - assert.Equal(tc.bytes, bl, "%d", tc.words) - } else { - // check if it is either tc.bytes or tc.bytes +1 - choices := []int{tc.bytes, tc.bytes + 1} - assert.Contains(choices, bl, "%d", tc.words) - } - } -} - -func TestEncodeDecode(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) - - codec, err := LoadCodec("english") - require.Nil(err, "%+v", err) - - cases := [][]byte{ - {7, 8, 9}, // TODO: 3 words -> 3 or 4 bytes - {12, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes - {0, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes, detect leading 0 - {1, 2, 3, 4, 5}, // normal - {0, 0, 0, 0, 122, 23, 82, 195}, // leading 0s (8 chars, unclear) - {0, 0, 0, 0, 5, 22, 123, 55, 22}, // leading 0s (9 chars, clear) - {22, 44, 55, 1, 13, 0, 0, 0, 0}, // trailing 0s (9 chars, clear) - {0, 5, 253, 2, 0}, // leading and trailing zeros - {255, 196, 172, 234, 192, 255}, // big numbers - {255, 196, 172, 1, 234, 192, 255}, // big numbers, two length choices - // others? - } - - for i, tc := range cases { - w, err := codec.BytesToWords(tc) - if assert.Nil(err, "%d: %v", i, err) { - b, err := codec.WordsToBytes(w) - if assert.Nil(err, "%d: %v", i, err) { - assert.Equal(len(tc), len(b)) - assert.Equal(tc, b) - } - } - } -} - -func TestCheckInvalidLists(t *testing.T) { - assert := asrt.New(t) - - trivial := []string{"abc", "def"} - short := make([]string, 1234) - long := make([]string, BankSize+1) - right := make([]string, BankSize) - dups := make([]string, BankSize) - - for _, list := range [][]string{short, long, right, dups} { - for i := range list { - list[i] = cmn.RandStr(8) - } - } - // create one single duplicate - dups[192] = dups[782] - - cases := []struct { - words []string - loadable bool - valid bool - }{ - {trivial, false, false}, - {short, false, false}, - {long, false, false}, - {dups, true, false}, // we only check dups on first use... - {right, true, true}, - } - - for i, tc := range cases { - codec, err := NewCodec(tc.words) - if !tc.loadable { - assert.NotNil(err, "%d", i) - } else if assert.Nil(err, "%d: %+v", i, err) { - data := cmn.RandBytes(32) - w, err := codec.BytesToWords(data) - if tc.valid { - assert.Nil(err, "%d: %+v", i, err) - b, err1 := codec.WordsToBytes(w) - assert.Nil(err1, "%d: %+v", i, err1) - assert.Equal(data, b) - } else { - assert.NotNil(err, "%d", i) - } - } - } - -} - -func getRandWord(c *WordCodec) string { - idx := cmn.RandInt() % BankSize - return c.words[idx] -} - -func getDiffWord(c *WordCodec, not string) string { - w := getRandWord(c) - if w == not { - w = getRandWord(c) - } - return w -} - -func TestCheckTypoDetection(t *testing.T) { - assert, require := asrt.New(t), rqr.New(t) - - banks := []string{"english", "spanish", "japanese", "chinese_simplified"} - - for _, bank := range banks { - codec, err := LoadCodec(bank) - require.Nil(err, "%s: %+v", bank, err) - for i := 0; i < 1000; i++ { - numBytes := cmn.RandInt()%60 + 4 - data := cmn.RandBytes(numBytes) - - words, err := codec.BytesToWords(data) - assert.Nil(err, "%s: %+v", bank, err) - good, err := codec.WordsToBytes(words) - assert.Nil(err, "%s: %+v", bank, err) - assert.Equal(data, good, bank) - - // now try some tweaks... - cut := words[1:] - _, err = codec.WordsToBytes(cut) - assert.NotNil(err, "%s: %s", bank, words) - - // swap a word within the bank, should fails - words[3] = getDiffWord(codec, words[3]) - _, err = codec.WordsToBytes(words) - assert.NotNil(err, "%s: %s", bank, words) - - // put a random word here, must fail - words[3] = cmn.RandStr(10) - _, err = codec.WordsToBytes(words) - assert.NotNil(err, "%s: %s", bank, words) - } - } -} diff --git a/keys/words/wordcodecbench_test.go b/keys/words/wordcodecbench_test.go deleted file mode 100644 index 04417a936..000000000 --- a/keys/words/wordcodecbench_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package words - -import ( - "testing" - - cmn "github.com/tendermint/tmlibs/common" -) - -func warmupCodec(bank string) *WordCodec { - codec, err := LoadCodec(bank) - if err != nil { - panic(err) - } - _, err = codec.GetIndex(codec.words[123]) - if err != nil { - panic(err) - } - return codec -} - -func BenchmarkCodec(b *testing.B) { - banks := []string{"english", "spanish", "japanese", "chinese_simplified"} - - for _, bank := range banks { - b.Run(bank, func(sub *testing.B) { - codec := warmupCodec(bank) - sub.ResetTimer() - benchSuite(sub, codec) - }) - } -} - -func benchSuite(b *testing.B, codec *WordCodec) { - b.Run("to_words", func(sub *testing.B) { - benchMakeWords(sub, codec) - }) - b.Run("to_bytes", func(sub *testing.B) { - benchParseWords(sub, codec) - }) -} - -func benchMakeWords(b *testing.B, codec *WordCodec) { - numBytes := 32 - data := cmn.RandBytes(numBytes) - for i := 1; i <= b.N; i++ { - _, err := codec.BytesToWords(data) - if err != nil { - panic(err) - } - } -} - -func benchParseWords(b *testing.B, codec *WordCodec) { - // generate a valid test string to parse - numBytes := 32 - data := cmn.RandBytes(numBytes) - words, err := codec.BytesToWords(data) - if err != nil { - panic(err) - } - - for i := 1; i <= b.N; i++ { - _, err := codec.WordsToBytes(words) - if err != nil { - panic(err) - } - } -} diff --git a/keys/words/wordlist/chinese_simplified.txt b/keys/words/wordlist/chinese_simplified.txt deleted file mode 100644 index b90f1ed85..000000000 --- a/keys/words/wordlist/chinese_simplified.txt +++ /dev/null @@ -1,2048 +0,0 @@ -的 -一 -是 -在 -不 -了 -有 -和 -人 -这 -中 -大 -为 -上 -个 -国 -我 -以 -要 -他 -时 -来 -用 -们 -生 -到 -作 -地 -于 -出 -就 -分 -对 -成 -会 -可 -主 -发 -年 -动 -同 -工 -也 -能 -下 -过 -子 -说 -产 -种 -面 -而 -方 -后 -多 -定 -行 -学 -法 -所 -民 -得 -经 -十 -三 -之 -进 -着 -等 -部 -度 -家 -电 -力 -里 -如 -水 -化 -高 -自 -二 -理 -起 -小 -物 -现 -实 -加 -量 -都 -两 -体 -制 -机 -当 -使 -点 -从 -业 -本 -去 -把 -性 -好 -应 -开 -它 -合 -还 -因 -由 -其 -些 -然 -前 -外 -天 -政 -四 -日 -那 -社 -义 -事 -平 -形 -相 -全 -表 -间 -样 -与 -关 -各 -重 -新 -线 -内 -数 -正 -心 -反 -你 -明 -看 -原 -又 -么 -利 -比 -或 -但 -质 -气 -第 -向 -道 -命 -此 -变 -条 -只 -没 -结 -解 -问 -意 -建 -月 -公 -无 -系 -军 -很 -情 -者 -最 -立 -代 -想 -已 -通 -并 -提 -直 -题 -党 -程 -展 -五 -果 -料 -象 -员 -革 -位 -入 -常 -文 -总 -次 -品 -式 -活 -设 -及 -管 -特 -件 -长 -求 -老 -头 -基 -资 -边 -流 -路 -级 -少 -图 -山 -统 -接 -知 -较 -将 -组 -见 -计 -别 -她 -手 -角 -期 -根 -论 -运 -农 -指 -几 -九 -区 -强 -放 -决 -西 -被 -干 -做 -必 -战 -先 -回 -则 -任 -取 -据 -处 -队 -南 -给 -色 -光 -门 -即 -保 -治 -北 -造 -百 -规 -热 -领 -七 -海 -口 -东 -导 -器 -压 -志 -世 -金 -增 -争 -济 -阶 -油 -思 -术 -极 -交 -受 -联 -什 -认 -六 -共 -权 -收 -证 -改 -清 -美 -再 -采 -转 -更 -单 -风 -切 -打 -白 -教 -速 -花 -带 -安 -场 -身 -车 -例 -真 -务 -具 -万 -每 -目 -至 -达 -走 -积 -示 -议 -声 -报 -斗 -完 -类 -八 -离 -华 -名 -确 -才 -科 -张 -信 -马 -节 -话 -米 -整 -空 -元 -况 -今 -集 -温 -传 -土 -许 -步 -群 -广 -石 -记 -需 -段 -研 -界 -拉 -林 -律 -叫 -且 -究 -观 -越 -织 -装 -影 -算 -低 -持 -音 -众 -书 -布 -复 -容 -儿 -须 -际 -商 -非 -验 -连 -断 -深 -难 -近 -矿 -千 -周 -委 -素 -技 -备 -半 -办 -青 -省 -列 -习 -响 -约 -支 -般 -史 -感 -劳 -便 -团 -往 -酸 -历 -市 -克 -何 -除 -消 -构 -府 -称 -太 -准 -精 -值 -号 -率 -族 -维 -划 -选 -标 -写 -存 -候 -毛 -亲 -快 -效 -斯 -院 -查 -江 -型 -眼 -王 -按 -格 -养 -易 -置 -派 -层 -片 -始 -却 -专 -状 -育 -厂 -京 -识 -适 -属 -圆 -包 -火 -住 -调 -满 -县 -局 -照 -参 -红 -细 -引 -听 -该 -铁 -价 -严 -首 -底 -液 -官 -德 -随 -病 -苏 -失 -尔 -死 -讲 -配 -女 -黄 -推 -显 -谈 -罪 -神 -艺 -呢 -席 -含 -企 -望 -密 -批 -营 -项 -防 -举 -球 -英 -氧 -势 -告 -李 -台 -落 -木 -帮 -轮 -破 -亚 -师 -围 -注 -远 -字 -材 -排 -供 -河 -态 -封 -另 -施 -减 -树 -溶 -怎 -止 -案 -言 -士 -均 -武 -固 -叶 -鱼 -波 -视 -仅 -费 -紧 -爱 -左 -章 -早 -朝 -害 -续 -轻 -服 -试 -食 -充 -兵 -源 -判 -护 -司 -足 -某 -练 -差 -致 -板 -田 -降 -黑 -犯 -负 -击 -范 -继 -兴 -似 -余 -坚 -曲 -输 -修 -故 -城 -夫 -够 -送 -笔 -船 -占 -右 -财 -吃 -富 -春 -职 -觉 -汉 -画 -功 -巴 -跟 -虽 -杂 -飞 -检 -吸 -助 -升 -阳 -互 -初 -创 -抗 -考 -投 -坏 -策 -古 -径 -换 -未 -跑 -留 -钢 -曾 -端 -责 -站 -简 -述 -钱 -副 -尽 -帝 -射 -草 -冲 -承 -独 -令 -限 -阿 -宣 -环 -双 -请 -超 -微 -让 -控 -州 -良 -轴 -找 -否 -纪 -益 -依 -优 -顶 -础 -载 -倒 -房 -突 -坐 -粉 -敌 -略 -客 -袁 -冷 -胜 -绝 -析 -块 -剂 -测 -丝 -协 -诉 -念 -陈 -仍 -罗 -盐 -友 -洋 -错 -苦 -夜 -刑 -移 -频 -逐 -靠 -混 -母 -短 -皮 -终 -聚 -汽 -村 -云 -哪 -既 -距 -卫 -停 -烈 -央 -察 -烧 -迅 -境 -若 -印 -洲 -刻 -括 -激 -孔 -搞 -甚 -室 -待 -核 -校 -散 -侵 -吧 -甲 -游 -久 -菜 -味 -旧 -模 -湖 -货 -损 -预 -阻 -毫 -普 -稳 -乙 -妈 -植 -息 -扩 -银 -语 -挥 -酒 -守 -拿 -序 -纸 -医 -缺 -雨 -吗 -针 -刘 -啊 -急 -唱 -误 -训 -愿 -审 -附 -获 -茶 -鲜 -粮 -斤 -孩 -脱 -硫 -肥 -善 -龙 -演 -父 -渐 -血 -欢 -械 -掌 -歌 -沙 -刚 -攻 -谓 -盾 -讨 -晚 -粒 -乱 -燃 -矛 -乎 -杀 -药 -宁 -鲁 -贵 -钟 -煤 -读 -班 -伯 -香 -介 -迫 -句 -丰 -培 -握 -兰 -担 -弦 -蛋 -沉 -假 -穿 -执 -答 -乐 -谁 -顺 -烟 -缩 -征 -脸 -喜 -松 -脚 -困 -异 -免 -背 -星 -福 -买 -染 -井 -概 -慢 -怕 -磁 -倍 -祖 -皇 -促 -静 -补 -评 -翻 -肉 -践 -尼 -衣 -宽 -扬 -棉 -希 -伤 -操 -垂 -秋 -宜 -氢 -套 -督 -振 -架 -亮 -末 -宪 -庆 -编 -牛 -触 -映 -雷 -销 -诗 -座 -居 -抓 -裂 -胞 -呼 -娘 -景 -威 -绿 -晶 -厚 -盟 -衡 -鸡 -孙 -延 -危 -胶 -屋 -乡 -临 -陆 -顾 -掉 -呀 -灯 -岁 -措 -束 -耐 -剧 -玉 -赵 -跳 -哥 -季 -课 -凯 -胡 -额 -款 -绍 -卷 -齐 -伟 -蒸 -殖 -永 -宗 -苗 -川 -炉 -岩 -弱 -零 -杨 -奏 -沿 -露 -杆 -探 -滑 -镇 -饭 -浓 -航 -怀 -赶 -库 -夺 -伊 -灵 -税 -途 -灭 -赛 -归 -召 -鼓 -播 -盘 -裁 -险 -康 -唯 -录 -菌 -纯 -借 -糖 -盖 -横 -符 -私 -努 -堂 -域 -枪 -润 -幅 -哈 -竟 -熟 -虫 -泽 -脑 -壤 -碳 -欧 -遍 -侧 -寨 -敢 -彻 -虑 -斜 -薄 -庭 -纳 -弹 -饲 -伸 -折 -麦 -湿 -暗 -荷 -瓦 -塞 -床 -筑 -恶 -户 -访 -塔 -奇 -透 -梁 -刀 -旋 -迹 -卡 -氯 -遇 -份 -毒 -泥 -退 -洗 -摆 -灰 -彩 -卖 -耗 -夏 -择 -忙 -铜 -献 -硬 -予 -繁 -圈 -雪 -函 -亦 -抽 -篇 -阵 -阴 -丁 -尺 -追 -堆 -雄 -迎 -泛 -爸 -楼 -避 -谋 -吨 -野 -猪 -旗 -累 -偏 -典 -馆 -索 -秦 -脂 -潮 -爷 -豆 -忽 -托 -惊 -塑 -遗 -愈 -朱 -替 -纤 -粗 -倾 -尚 -痛 -楚 -谢 -奋 -购 -磨 -君 -池 -旁 -碎 -骨 -监 -捕 -弟 -暴 -割 -贯 -殊 -释 -词 -亡 -壁 -顿 -宝 -午 -尘 -闻 -揭 -炮 -残 -冬 -桥 -妇 -警 -综 -招 -吴 -付 -浮 -遭 -徐 -您 -摇 -谷 -赞 -箱 -隔 -订 -男 -吹 -园 -纷 -唐 -败 -宋 -玻 -巨 -耕 -坦 -荣 -闭 -湾 -键 -凡 -驻 -锅 -救 -恩 -剥 -凝 -碱 -齿 -截 -炼 -麻 -纺 -禁 -废 -盛 -版 -缓 -净 -睛 -昌 -婚 -涉 -筒 -嘴 -插 -岸 -朗 -庄 -街 -藏 -姑 -贸 -腐 -奴 -啦 -惯 -乘 -伙 -恢 -匀 -纱 -扎 -辩 -耳 -彪 -臣 -亿 -璃 -抵 -脉 -秀 -萨 -俄 -网 -舞 -店 -喷 -纵 -寸 -汗 -挂 -洪 -贺 -闪 -柬 -爆 -烯 -津 -稻 -墙 -软 -勇 -像 -滚 -厘 -蒙 -芳 -肯 -坡 -柱 -荡 -腿 -仪 -旅 -尾 -轧 -冰 -贡 -登 -黎 -削 -钻 -勒 -逃 -障 -氨 -郭 -峰 -币 -港 -伏 -轨 -亩 -毕 -擦 -莫 -刺 -浪 -秘 -援 -株 -健 -售 -股 -岛 -甘 -泡 -睡 -童 -铸 -汤 -阀 -休 -汇 -舍 -牧 -绕 -炸 -哲 -磷 -绩 -朋 -淡 -尖 -启 -陷 -柴 -呈 -徒 -颜 -泪 -稍 -忘 -泵 -蓝 -拖 -洞 -授 -镜 -辛 -壮 -锋 -贫 -虚 -弯 -摩 -泰 -幼 -廷 -尊 -窗 -纲 -弄 -隶 -疑 -氏 -宫 -姐 -震 -瑞 -怪 -尤 -琴 -循 -描 -膜 -违 -夹 -腰 -缘 -珠 -穷 -森 -枝 -竹 -沟 -催 -绳 -忆 -邦 -剩 -幸 -浆 -栏 -拥 -牙 -贮 -礼 -滤 -钠 -纹 -罢 -拍 -咱 -喊 -袖 -埃 -勤 -罚 -焦 -潜 -伍 -墨 -欲 -缝 -姓 -刊 -饱 -仿 -奖 -铝 -鬼 -丽 -跨 -默 -挖 -链 -扫 -喝 -袋 -炭 -污 -幕 -诸 -弧 -励 -梅 -奶 -洁 -灾 -舟 -鉴 -苯 -讼 -抱 -毁 -懂 -寒 -智 -埔 -寄 -届 -跃 -渡 -挑 -丹 -艰 -贝 -碰 -拔 -爹 -戴 -码 -梦 -芽 -熔 -赤 -渔 -哭 -敬 -颗 -奔 -铅 -仲 -虎 -稀 -妹 -乏 -珍 -申 -桌 -遵 -允 -隆 -螺 -仓 -魏 -锐 -晓 -氮 -兼 -隐 -碍 -赫 -拨 -忠 -肃 -缸 -牵 -抢 -博 -巧 -壳 -兄 -杜 -讯 -诚 -碧 -祥 -柯 -页 -巡 -矩 -悲 -灌 -龄 -伦 -票 -寻 -桂 -铺 -圣 -恐 -恰 -郑 -趣 -抬 -荒 -腾 -贴 -柔 -滴 -猛 -阔 -辆 -妻 -填 -撤 -储 -签 -闹 -扰 -紫 -砂 -递 -戏 -吊 -陶 -伐 -喂 -疗 -瓶 -婆 -抚 -臂 -摸 -忍 -虾 -蜡 -邻 -胸 -巩 -挤 -偶 -弃 -槽 -劲 -乳 -邓 -吉 -仁 -烂 -砖 -租 -乌 -舰 -伴 -瓜 -浅 -丙 -暂 -燥 -橡 -柳 -迷 -暖 -牌 -秧 -胆 -详 -簧 -踏 -瓷 -谱 -呆 -宾 -糊 -洛 -辉 -愤 -竞 -隙 -怒 -粘 -乃 -绪 -肩 -籍 -敏 -涂 -熙 -皆 -侦 -悬 -掘 -享 -纠 -醒 -狂 -锁 -淀 -恨 -牲 -霸 -爬 -赏 -逆 -玩 -陵 -祝 -秒 -浙 -貌 -役 -彼 -悉 -鸭 -趋 -凤 -晨 -畜 -辈 -秩 -卵 -署 -梯 -炎 -滩 -棋 -驱 -筛 -峡 -冒 -啥 -寿 -译 -浸 -泉 -帽 -迟 -硅 -疆 -贷 -漏 -稿 -冠 -嫩 -胁 -芯 -牢 -叛 -蚀 -奥 -鸣 -岭 -羊 -凭 -串 -塘 -绘 -酵 -融 -盆 -锡 -庙 -筹 -冻 -辅 -摄 -袭 -筋 -拒 -僚 -旱 -钾 -鸟 -漆 -沈 -眉 -疏 -添 -棒 -穗 -硝 -韩 -逼 -扭 -侨 -凉 -挺 -碗 -栽 -炒 -杯 -患 -馏 -劝 -豪 -辽 -勃 -鸿 -旦 -吏 -拜 -狗 -埋 -辊 -掩 -饮 -搬 -骂 -辞 -勾 -扣 -估 -蒋 -绒 -雾 -丈 -朵 -姆 -拟 -宇 -辑 -陕 -雕 -偿 -蓄 -崇 -剪 -倡 -厅 -咬 -驶 -薯 -刷 -斥 -番 -赋 -奉 -佛 -浇 -漫 -曼 -扇 -钙 -桃 -扶 -仔 -返 -俗 -亏 -腔 -鞋 -棱 -覆 -框 -悄 -叔 -撞 -骗 -勘 -旺 -沸 -孤 -吐 -孟 -渠 -屈 -疾 -妙 -惜 -仰 -狠 -胀 -谐 -抛 -霉 -桑 -岗 -嘛 -衰 -盗 -渗 -脏 -赖 -涌 -甜 -曹 -阅 -肌 -哩 -厉 -烃 -纬 -毅 -昨 -伪 -症 -煮 -叹 -钉 -搭 -茎 -笼 -酷 -偷 -弓 -锥 -恒 -杰 -坑 -鼻 -翼 -纶 -叙 -狱 -逮 -罐 -络 -棚 -抑 -膨 -蔬 -寺 -骤 -穆 -冶 -枯 -册 -尸 -凸 -绅 -坯 -牺 -焰 -轰 -欣 -晋 -瘦 -御 -锭 -锦 -丧 -旬 -锻 -垄 -搜 -扑 -邀 -亭 -酯 -迈 -舒 -脆 -酶 -闲 -忧 -酚 -顽 -羽 -涨 -卸 -仗 -陪 -辟 -惩 -杭 -姚 -肚 -捉 -飘 -漂 -昆 -欺 -吾 -郎 -烷 -汁 -呵 -饰 -萧 -雅 -邮 -迁 -燕 -撒 -姻 -赴 -宴 -烦 -债 -帐 -斑 -铃 -旨 -醇 -董 -饼 -雏 -姿 -拌 -傅 -腹 -妥 -揉 -贤 -拆 -歪 -葡 -胺 -丢 -浩 -徽 -昂 -垫 -挡 -览 -贪 -慰 -缴 -汪 -慌 -冯 -诺 -姜 -谊 -凶 -劣 -诬 -耀 -昏 -躺 -盈 -骑 -乔 -溪 -丛 -卢 -抹 -闷 -咨 -刮 -驾 -缆 -悟 -摘 -铒 -掷 -颇 -幻 -柄 -惠 -惨 -佳 -仇 -腊 -窝 -涤 -剑 -瞧 -堡 -泼 -葱 -罩 -霍 -捞 -胎 -苍 -滨 -俩 -捅 -湘 -砍 -霞 -邵 -萄 -疯 -淮 -遂 -熊 -粪 -烘 -宿 -档 -戈 -驳 -嫂 -裕 -徙 -箭 -捐 -肠 -撑 -晒 -辨 -殿 -莲 -摊 -搅 -酱 -屏 -疫 -哀 -蔡 -堵 -沫 -皱 -畅 -叠 -阁 -莱 -敲 -辖 -钩 -痕 -坝 -巷 -饿 -祸 -丘 -玄 -溜 -曰 -逻 -彭 -尝 -卿 -妨 -艇 -吞 -韦 -怨 -矮 -歇 diff --git a/keys/words/wordlist/english.txt b/keys/words/wordlist/english.txt deleted file mode 100644 index 942040ed5..000000000 --- a/keys/words/wordlist/english.txt +++ /dev/null @@ -1,2048 +0,0 @@ -abandon -ability -able -about -above -absent -absorb -abstract -absurd -abuse -access -accident -account -accuse -achieve -acid -acoustic -acquire -across -act -action -actor -actress -actual -adapt -add -addict -address -adjust -admit -adult -advance -advice -aerobic -affair -afford -afraid -again -age -agent -agree -ahead -aim -air -airport -aisle -alarm -album -alcohol -alert -alien -all -alley -allow -almost -alone -alpha -already -also -alter -always -amateur -amazing -among -amount -amused -analyst -anchor -ancient -anger -angle -angry -animal -ankle -announce -annual -another -answer -antenna -antique -anxiety -any -apart -apology -appear -apple -approve -april -arch -arctic -area -arena -argue -arm -armed -armor -army -around -arrange -arrest -arrive -arrow -art -artefact -artist -artwork -ask -aspect -assault -asset -assist -assume -asthma -athlete -atom -attack -attend -attitude -attract -auction -audit -august -aunt -author -auto -autumn -average -avocado -avoid -awake -aware -away -awesome -awful -awkward -axis -baby -bachelor -bacon -badge -bag -balance -balcony -ball -bamboo -banana -banner -bar -barely -bargain -barrel -base -basic -basket -battle -beach -bean -beauty -because -become -beef -before -begin -behave -behind -believe -below -belt -bench -benefit -best -betray -better -between -beyond -bicycle -bid -bike -bind -biology -bird -birth -bitter -black -blade -blame -blanket -blast -bleak -bless -blind -blood -blossom -blouse -blue -blur -blush -board -boat -body -boil -bomb -bone -bonus -book -boost -border -boring -borrow -boss -bottom -bounce -box -boy -bracket -brain -brand -brass -brave -bread -breeze -brick -bridge -brief -bright -bring -brisk -broccoli -broken -bronze -broom -brother -brown -brush -bubble -buddy -budget -buffalo -build -bulb -bulk -bullet -bundle -bunker -burden -burger -burst -bus -business -busy -butter -buyer -buzz -cabbage -cabin -cable -cactus -cage -cake -call -calm -camera -camp -can -canal -cancel -candy -cannon -canoe -canvas -canyon -capable -capital -captain -car -carbon -card -cargo -carpet -carry -cart -case -cash -casino -castle -casual -cat -catalog -catch -category -cattle -caught -cause -caution -cave -ceiling -celery -cement -census -century -cereal -certain -chair -chalk -champion -change -chaos -chapter -charge -chase -chat -cheap -check -cheese -chef -cherry -chest -chicken -chief -child -chimney -choice -choose -chronic -chuckle -chunk -churn -cigar -cinnamon -circle -citizen -city -civil -claim -clap -clarify -claw -clay -clean -clerk -clever -click -client -cliff -climb -clinic -clip -clock -clog -close -cloth -cloud -clown -club -clump -cluster -clutch -coach -coast -coconut -code -coffee -coil -coin -collect -color -column -combine -come -comfort -comic -common -company -concert -conduct -confirm -congress -connect -consider -control -convince -cook -cool -copper -copy -coral -core -corn -correct -cost -cotton -couch -country -couple -course -cousin -cover -coyote -crack -cradle -craft -cram -crane -crash -crater -crawl -crazy -cream -credit -creek -crew -cricket -crime -crisp -critic -crop -cross -crouch -crowd -crucial -cruel -cruise -crumble -crunch -crush -cry -crystal -cube -culture -cup -cupboard -curious -current -curtain -curve -cushion -custom -cute -cycle -dad -damage -damp -dance -danger -daring -dash -daughter -dawn -day -deal -debate -debris -decade -december -decide -decline -decorate -decrease -deer -defense -define -defy -degree -delay -deliver -demand -demise -denial -dentist -deny -depart -depend -deposit -depth -deputy -derive -describe -desert -design -desk -despair -destroy -detail -detect -develop -device -devote -diagram -dial -diamond -diary -dice -diesel -diet -differ -digital -dignity -dilemma -dinner -dinosaur -direct -dirt -disagree -discover -disease -dish -dismiss -disorder -display -distance -divert -divide -divorce -dizzy -doctor -document -dog -doll -dolphin -domain -donate -donkey -donor -door -dose -double -dove -draft -dragon -drama -drastic -draw -dream -dress -drift -drill -drink -drip -drive -drop -drum -dry -duck -dumb -dune -during -dust -dutch -duty -dwarf -dynamic -eager -eagle -early -earn -earth -easily -east -easy -echo -ecology -economy -edge -edit -educate -effort -egg -eight -either -elbow -elder -electric -elegant -element -elephant -elevator -elite -else -embark -embody -embrace -emerge -emotion -employ -empower -empty -enable -enact -end -endless -endorse -enemy -energy -enforce -engage -engine -enhance -enjoy -enlist -enough -enrich -enroll -ensure -enter -entire -entry -envelope -episode -equal -equip -era -erase -erode -erosion -error -erupt -escape -essay -essence -estate -eternal -ethics -evidence -evil -evoke -evolve -exact -example -excess -exchange -excite -exclude -excuse -execute -exercise -exhaust -exhibit -exile -exist -exit -exotic -expand -expect -expire -explain -expose -express -extend -extra -eye -eyebrow -fabric -face -faculty -fade -faint -faith -fall -false -fame -family -famous -fan -fancy -fantasy -farm -fashion -fat -fatal -father -fatigue -fault -favorite -feature -february -federal -fee -feed -feel -female -fence -festival -fetch -fever -few -fiber -fiction -field -figure -file -film -filter -final -find -fine -finger -finish -fire -firm -first -fiscal -fish -fit -fitness -fix -flag -flame -flash -flat -flavor -flee -flight -flip -float -flock -floor -flower -fluid -flush -fly -foam -focus -fog -foil -fold -follow -food -foot -force -forest -forget -fork -fortune -forum -forward -fossil -foster -found -fox -fragile -frame -frequent -fresh -friend -fringe -frog -front -frost -frown -frozen -fruit -fuel -fun -funny -furnace -fury -future -gadget -gain -galaxy -gallery -game -gap -garage -garbage -garden -garlic -garment -gas -gasp -gate -gather -gauge -gaze -general -genius -genre -gentle -genuine -gesture -ghost -giant -gift -giggle -ginger -giraffe -girl -give -glad -glance -glare -glass -glide -glimpse -globe -gloom -glory -glove -glow -glue -goat -goddess -gold -good -goose -gorilla -gospel -gossip -govern -gown -grab -grace -grain -grant -grape -grass -gravity -great -green -grid -grief -grit -grocery -group -grow -grunt -guard -guess -guide -guilt -guitar -gun -gym -habit -hair -half -hammer -hamster -hand -happy -harbor -hard -harsh -harvest -hat -have -hawk -hazard -head -health -heart -heavy -hedgehog -height -hello -helmet -help -hen -hero -hidden -high -hill -hint -hip -hire -history -hobby -hockey -hold -hole -holiday -hollow -home -honey -hood -hope -horn -horror -horse -hospital -host -hotel -hour -hover -hub -huge -human -humble -humor -hundred -hungry -hunt -hurdle -hurry -hurt -husband -hybrid -ice -icon -idea -identify -idle -ignore -ill -illegal -illness -image -imitate -immense -immune -impact -impose -improve -impulse -inch -include -income -increase -index -indicate -indoor -industry -infant -inflict -inform -inhale -inherit -initial -inject -injury -inmate -inner -innocent -input -inquiry -insane -insect -inside -inspire -install -intact -interest -into -invest -invite -involve -iron -island -isolate -issue -item -ivory -jacket -jaguar -jar -jazz -jealous -jeans -jelly -jewel -job -join -joke -journey -joy -judge -juice -jump -jungle -junior -junk -just -kangaroo -keen -keep -ketchup -key -kick -kid -kidney -kind -kingdom -kiss -kit -kitchen -kite -kitten -kiwi -knee -knife -knock -know -lab -label -labor -ladder -lady -lake -lamp -language -laptop -large -later -latin -laugh -laundry -lava -law -lawn -lawsuit -layer -lazy -leader -leaf -learn -leave -lecture -left -leg -legal -legend -leisure -lemon -lend -length -lens -leopard -lesson -letter -level -liar -liberty -library -license -life -lift -light -like -limb -limit -link -lion -liquid -list -little -live -lizard -load -loan -lobster -local -lock -logic -lonely -long -loop -lottery -loud -lounge -love -loyal -lucky -luggage -lumber -lunar -lunch -luxury -lyrics -machine -mad -magic -magnet -maid -mail -main -major -make -mammal -man -manage -mandate -mango -mansion -manual -maple -marble -march -margin -marine -market -marriage -mask -mass -master -match -material -math -matrix -matter -maximum -maze -meadow -mean -measure -meat -mechanic -medal -media -melody -melt -member -memory -mention -menu -mercy -merge -merit -merry -mesh -message -metal -method -middle -midnight -milk -million -mimic -mind -minimum -minor -minute -miracle -mirror -misery -miss -mistake -mix -mixed -mixture -mobile -model -modify -mom -moment -monitor -monkey -monster -month -moon -moral -more -morning -mosquito -mother -motion -motor -mountain -mouse -move -movie -much -muffin -mule -multiply -muscle -museum -mushroom -music -must -mutual -myself -mystery -myth -naive -name -napkin -narrow -nasty -nation -nature -near -neck -need -negative -neglect -neither -nephew -nerve -nest -net -network -neutral -never -news -next -nice -night -noble -noise -nominee -noodle -normal -north -nose -notable -note -nothing -notice -novel -now -nuclear -number -nurse -nut -oak -obey -object -oblige -obscure -observe -obtain -obvious -occur -ocean -october -odor -off -offer -office -often -oil -okay -old -olive -olympic -omit -once -one -onion -online -only -open -opera -opinion -oppose -option -orange -orbit -orchard -order -ordinary -organ -orient -original -orphan -ostrich -other -outdoor -outer -output -outside -oval -oven -over -own -owner -oxygen -oyster -ozone -pact -paddle -page -pair -palace -palm -panda -panel -panic -panther -paper -parade -parent -park -parrot -party -pass -patch -path -patient -patrol -pattern -pause -pave -payment -peace -peanut -pear -peasant -pelican -pen -penalty -pencil -people -pepper -perfect -permit -person -pet -phone -photo -phrase -physical -piano -picnic -picture -piece -pig -pigeon -pill -pilot -pink -pioneer -pipe -pistol -pitch -pizza -place -planet -plastic -plate -play -please -pledge -pluck -plug -plunge -poem -poet -point -polar -pole -police -pond -pony -pool -popular -portion -position -possible -post -potato -pottery -poverty -powder -power -practice -praise -predict -prefer -prepare -present -pretty -prevent -price -pride -primary -print -priority -prison -private -prize -problem -process -produce -profit -program -project -promote -proof -property -prosper -protect -proud -provide -public -pudding -pull -pulp -pulse -pumpkin -punch -pupil -puppy -purchase -purity -purpose -purse -push -put -puzzle -pyramid -quality -quantum -quarter -question -quick -quit -quiz -quote -rabbit -raccoon -race -rack -radar -radio -rail -rain -raise -rally -ramp -ranch -random -range -rapid -rare -rate -rather -raven -raw -razor -ready -real -reason -rebel -rebuild -recall -receive -recipe -record -recycle -reduce -reflect -reform -refuse -region -regret -regular -reject -relax -release -relief -rely -remain -remember -remind -remove -render -renew -rent -reopen -repair -repeat -replace -report -require -rescue -resemble -resist -resource -response -result -retire -retreat -return -reunion -reveal -review -reward -rhythm -rib -ribbon -rice -rich -ride -ridge -rifle -right -rigid -ring -riot -ripple -risk -ritual -rival -river -road -roast -robot -robust -rocket -romance -roof -rookie -room -rose -rotate -rough -round -route -royal -rubber -rude -rug -rule -run -runway -rural -sad -saddle -sadness -safe -sail -salad -salmon -salon -salt -salute -same -sample -sand -satisfy -satoshi -sauce -sausage -save -say -scale -scan -scare -scatter -scene -scheme -school -science -scissors -scorpion -scout -scrap -screen -script -scrub -sea -search -season -seat -second -secret -section -security -seed -seek -segment -select -sell -seminar -senior -sense -sentence -series -service -session -settle -setup -seven -shadow -shaft -shallow -share -shed -shell -sheriff -shield -shift -shine -ship -shiver -shock -shoe -shoot -shop -short -shoulder -shove -shrimp -shrug -shuffle -shy -sibling -sick -side -siege -sight -sign -silent -silk -silly -silver -similar -simple -since -sing -siren -sister -situate -six -size -skate -sketch -ski -skill -skin -skirt -skull -slab -slam -sleep -slender -slice -slide -slight -slim -slogan -slot -slow -slush -small -smart -smile -smoke -smooth -snack -snake -snap -sniff -snow -soap -soccer -social -sock -soda -soft -solar -soldier -solid -solution -solve -someone -song -soon -sorry -sort -soul -sound -soup -source -south -space -spare -spatial -spawn -speak -special -speed -spell -spend -sphere -spice -spider -spike -spin -spirit -split -spoil -sponsor -spoon -sport -spot -spray -spread -spring -spy -square -squeeze -squirrel -stable -stadium -staff -stage -stairs -stamp -stand -start -state -stay -steak -steel -stem -step -stereo -stick -still -sting -stock -stomach -stone -stool -story -stove -strategy -street -strike -strong -struggle -student -stuff -stumble -style -subject -submit -subway -success -such -sudden -suffer -sugar -suggest -suit -summer -sun -sunny -sunset -super -supply -supreme -sure -surface -surge -surprise -surround -survey -suspect -sustain -swallow -swamp -swap -swarm -swear -sweet -swift -swim -swing -switch -sword -symbol -symptom -syrup -system -table -tackle -tag -tail -talent -talk -tank -tape -target -task -taste -tattoo -taxi -teach -team -tell -ten -tenant -tennis -tent -term -test -text -thank -that -theme -then -theory -there -they -thing -this -thought -three -thrive -throw -thumb -thunder -ticket -tide -tiger -tilt -timber -time -tiny -tip -tired -tissue -title -toast -tobacco -today -toddler -toe -together -toilet -token -tomato -tomorrow -tone -tongue -tonight -tool -tooth -top -topic -topple -torch -tornado -tortoise -toss -total -tourist -toward -tower -town -toy -track -trade -traffic -tragic -train -transfer -trap -trash -travel -tray -treat -tree -trend -trial -tribe -trick -trigger -trim -trip -trophy -trouble -truck -true -truly -trumpet -trust -truth -try -tube -tuition -tumble -tuna -tunnel -turkey -turn -turtle -twelve -twenty -twice -twin -twist -two -type -typical -ugly -umbrella -unable -unaware -uncle -uncover -under -undo -unfair -unfold -unhappy -uniform -unique -unit -universe -unknown -unlock -until -unusual -unveil -update -upgrade -uphold -upon -upper -upset -urban -urge -usage -use -used -useful -useless -usual -utility -vacant -vacuum -vague -valid -valley -valve -van -vanish -vapor -various -vast -vault -vehicle -velvet -vendor -venture -venue -verb -verify -version -very -vessel -veteran -viable -vibrant -vicious -victory -video -view -village -vintage -violin -virtual -virus -visa -visit -visual -vital -vivid -vocal -voice -void -volcano -volume -vote -voyage -wage -wagon -wait -walk -wall -walnut -want -warfare -warm -warrior -wash -wasp -waste -water -wave -way -wealth -weapon -wear -weasel -weather -web -wedding -weekend -weird -welcome -west -wet -whale -what -wheat -wheel -when -where -whip -whisper -wide -width -wife -wild -will -win -window -wine -wing -wink -winner -winter -wire -wisdom -wise -wish -witness -wolf -woman -wonder -wood -wool -word -work -world -worry -worth -wrap -wreck -wrestle -wrist -write -wrong -yard -year -yellow -you -young -youth -zebra -zero -zone -zoo diff --git a/keys/words/wordlist/japanese.txt b/keys/words/wordlist/japanese.txt deleted file mode 100644 index c4c9dca4e..000000000 --- a/keys/words/wordlist/japanese.txt +++ /dev/null @@ -1,2048 +0,0 @@ -あいこくしん -あいさつ -あいだ -あおぞら -あかちゃん -あきる -あけがた -あける -あこがれる -あさい -あさひ -あしあと -あじわう -あずかる -あずき -あそぶ -あたえる -あたためる -あたりまえ -あたる -あつい -あつかう -あっしゅく -あつまり -あつめる -あてな -あてはまる -あひる -あぶら -あぶる -あふれる -あまい -あまど -あまやかす -あまり -あみもの -あめりか -あやまる -あゆむ -あらいぐま -あらし -あらすじ -あらためる -あらゆる -あらわす -ありがとう -あわせる -あわてる -あんい -あんがい -あんこ -あんぜん -あんてい -あんない -あんまり -いいだす -いおん -いがい -いがく -いきおい -いきなり -いきもの -いきる -いくじ -いくぶん -いけばな -いけん -いこう -いこく -いこつ -いさましい -いさん -いしき -いじゅう -いじょう -いじわる -いずみ -いずれ -いせい -いせえび -いせかい -いせき -いぜん -いそうろう -いそがしい -いだい -いだく -いたずら -いたみ -いたりあ -いちおう -いちじ -いちど -いちば -いちぶ -いちりゅう -いつか -いっしゅん -いっせい -いっそう -いったん -いっち -いってい -いっぽう -いてざ -いてん -いどう -いとこ -いない -いなか -いねむり -いのち -いのる -いはつ -いばる -いはん -いびき -いひん -いふく -いへん -いほう -いみん -いもうと -いもたれ -いもり -いやがる -いやす -いよかん -いよく -いらい -いらすと -いりぐち -いりょう -いれい -いれもの -いれる -いろえんぴつ -いわい -いわう -いわかん -いわば -いわゆる -いんげんまめ -いんさつ -いんしょう -いんよう -うえき -うえる -うおざ -うがい -うかぶ -うかべる -うきわ -うくらいな -うくれれ -うけたまわる -うけつけ -うけとる -うけもつ -うける -うごかす -うごく -うこん -うさぎ -うしなう -うしろがみ -うすい -うすぎ -うすぐらい -うすめる -うせつ -うちあわせ -うちがわ -うちき -うちゅう -うっかり -うつくしい -うったえる -うつる -うどん -うなぎ -うなじ -うなずく -うなる -うねる -うのう -うぶげ -うぶごえ -うまれる -うめる -うもう -うやまう -うよく -うらがえす -うらぐち -うらない -うりあげ -うりきれ -うるさい -うれしい -うれゆき -うれる -うろこ -うわき -うわさ -うんこう -うんちん -うんてん -うんどう -えいえん -えいが -えいきょう -えいご -えいせい -えいぶん -えいよう -えいわ -えおり -えがお -えがく -えきたい -えくせる -えしゃく -えすて -えつらん -えのぐ -えほうまき -えほん -えまき -えもじ -えもの -えらい -えらぶ -えりあ -えんえん -えんかい -えんぎ -えんげき -えんしゅう -えんぜつ -えんそく -えんちょう -えんとつ -おいかける -おいこす -おいしい -おいつく -おうえん -おうさま -おうじ -おうせつ -おうたい -おうふく -おうべい -おうよう -おえる -おおい -おおう -おおどおり -おおや -おおよそ -おかえり -おかず -おがむ -おかわり -おぎなう -おきる -おくさま -おくじょう -おくりがな -おくる -おくれる -おこす -おこなう -おこる -おさえる -おさない -おさめる -おしいれ -おしえる -おじぎ -おじさん -おしゃれ -おそらく -おそわる -おたがい -おたく -おだやか -おちつく -おっと -おつり -おでかけ -おとしもの -おとなしい -おどり -おどろかす -おばさん -おまいり -おめでとう -おもいで -おもう -おもたい -おもちゃ -おやつ -おやゆび -およぼす -おらんだ -おろす -おんがく -おんけい -おんしゃ -おんせん -おんだん -おんちゅう -おんどけい -かあつ -かいが -がいき -がいけん -がいこう -かいさつ -かいしゃ -かいすいよく -かいぜん -かいぞうど -かいつう -かいてん -かいとう -かいふく -がいへき -かいほう -かいよう -がいらい -かいわ -かえる -かおり -かかえる -かがく -かがし -かがみ -かくご -かくとく -かざる -がぞう -かたい -かたち -がちょう -がっきゅう -がっこう -がっさん -がっしょう -かなざわし -かのう -がはく -かぶか -かほう -かほご -かまう -かまぼこ -かめれおん -かゆい -かようび -からい -かるい -かろう -かわく -かわら -がんか -かんけい -かんこう -かんしゃ -かんそう -かんたん -かんち -がんばる -きあい -きあつ -きいろ -ぎいん -きうい -きうん -きえる -きおう -きおく -きおち -きおん -きかい -きかく -きかんしゃ -ききて -きくばり -きくらげ -きけんせい -きこう -きこえる -きこく -きさい -きさく -きさま -きさらぎ -ぎじかがく -ぎしき -ぎじたいけん -ぎじにってい -ぎじゅつしゃ -きすう -きせい -きせき -きせつ -きそう -きぞく -きぞん -きたえる -きちょう -きつえん -ぎっちり -きつつき -きつね -きてい -きどう -きどく -きない -きなが -きなこ -きぬごし -きねん -きのう -きのした -きはく -きびしい -きひん -きふく -きぶん -きぼう -きほん -きまる -きみつ -きむずかしい -きめる -きもだめし -きもち -きもの -きゃく -きやく -ぎゅうにく -きよう -きょうりゅう -きらい -きらく -きりん -きれい -きれつ -きろく -ぎろん -きわめる -ぎんいろ -きんかくじ -きんじょ -きんようび -ぐあい -くいず -くうかん -くうき -くうぐん -くうこう -ぐうせい -くうそう -ぐうたら -くうふく -くうぼ -くかん -くきょう -くげん -ぐこう -くさい -くさき -くさばな -くさる -くしゃみ -くしょう -くすのき -くすりゆび -くせげ -くせん -ぐたいてき -くださる -くたびれる -くちこみ -くちさき -くつした -ぐっすり -くつろぐ -くとうてん -くどく -くなん -くねくね -くのう -くふう -くみあわせ -くみたてる -くめる -くやくしょ -くらす -くらべる -くるま -くれる -くろう -くわしい -ぐんかん -ぐんしょく -ぐんたい -ぐんて -けあな -けいかく -けいけん -けいこ -けいさつ -げいじゅつ -けいたい -げいのうじん -けいれき -けいろ -けおとす -けおりもの -げきか -げきげん -げきだん -げきちん -げきとつ -げきは -げきやく -げこう -げこくじょう -げざい -けさき -げざん -けしき -けしごむ -けしょう -げすと -けたば -けちゃっぷ -けちらす -けつあつ -けつい -けつえき -けっこん -けつじょ -けっせき -けってい -けつまつ -げつようび -げつれい -けつろん -げどく -けとばす -けとる -けなげ -けなす -けなみ -けぬき -げねつ -けねん -けはい -げひん -けぶかい -げぼく -けまり -けみかる -けむし -けむり -けもの -けらい -けろけろ -けわしい -けんい -けんえつ -けんお -けんか -げんき -けんげん -けんこう -けんさく -けんしゅう -けんすう -げんそう -けんちく -けんてい -けんとう -けんない -けんにん -げんぶつ -けんま -けんみん -けんめい -けんらん -けんり -こあくま -こいぬ -こいびと -ごうい -こうえん -こうおん -こうかん -ごうきゅう -ごうけい -こうこう -こうさい -こうじ -こうすい -ごうせい -こうそく -こうたい -こうちゃ -こうつう -こうてい -こうどう -こうない -こうはい -ごうほう -ごうまん -こうもく -こうりつ -こえる -こおり -ごかい -ごがつ -ごかん -こくご -こくさい -こくとう -こくない -こくはく -こぐま -こけい -こける -ここのか -こころ -こさめ -こしつ -こすう -こせい -こせき -こぜん -こそだて -こたい -こたえる -こたつ -こちょう -こっか -こつこつ -こつばん -こつぶ -こてい -こてん -ことがら -ことし -ことば -ことり -こなごな -こねこね -このまま -このみ -このよ -ごはん -こひつじ -こふう -こふん -こぼれる -ごまあぶら -こまかい -ごますり -こまつな -こまる -こむぎこ -こもじ -こもち -こもの -こもん -こやく -こやま -こゆう -こゆび -こよい -こよう -こりる -これくしょん -ころっけ -こわもて -こわれる -こんいん -こんかい -こんき -こんしゅう -こんすい -こんだて -こんとん -こんなん -こんびに -こんぽん -こんまけ -こんや -こんれい -こんわく -ざいえき -さいかい -さいきん -ざいげん -ざいこ -さいしょ -さいせい -ざいたく -ざいちゅう -さいてき -ざいりょう -さうな -さかいし -さがす -さかな -さかみち -さがる -さぎょう -さくし -さくひん -さくら -さこく -さこつ -さずかる -ざせき -さたん -さつえい -ざつおん -ざっか -ざつがく -さっきょく -ざっし -さつじん -ざっそう -さつたば -さつまいも -さてい -さといも -さとう -さとおや -さとし -さとる -さのう -さばく -さびしい -さべつ -さほう -さほど -さます -さみしい -さみだれ -さむけ -さめる -さやえんどう -さゆう -さよう -さよく -さらだ -ざるそば -さわやか -さわる -さんいん -さんか -さんきゃく -さんこう -さんさい -ざんしょ -さんすう -さんせい -さんそ -さんち -さんま -さんみ -さんらん -しあい -しあげ -しあさって -しあわせ -しいく -しいん -しうち -しえい -しおけ -しかい -しかく -じかん -しごと -しすう -じだい -したうけ -したぎ -したて -したみ -しちょう -しちりん -しっかり -しつじ -しつもん -してい -してき -してつ -じてん -じどう -しなぎれ -しなもの -しなん -しねま -しねん -しのぐ -しのぶ -しはい -しばかり -しはつ -しはらい -しはん -しひょう -しふく -じぶん -しへい -しほう -しほん -しまう -しまる -しみん -しむける -じむしょ -しめい -しめる -しもん -しゃいん -しゃうん -しゃおん -じゃがいも -しやくしょ -しゃくほう -しゃけん -しゃこ -しゃざい -しゃしん -しゃせん -しゃそう -しゃたい -しゃちょう -しゃっきん -じゃま -しゃりん -しゃれい -じゆう -じゅうしょ -しゅくはく -じゅしん -しゅっせき -しゅみ -しゅらば -じゅんばん -しょうかい -しょくたく -しょっけん -しょどう -しょもつ -しらせる -しらべる -しんか -しんこう -じんじゃ -しんせいじ -しんちく -しんりん -すあげ -すあし -すあな -ずあん -すいえい -すいか -すいとう -ずいぶん -すいようび -すうがく -すうじつ -すうせん -すおどり -すきま -すくう -すくない -すける -すごい -すこし -ずさん -すずしい -すすむ -すすめる -すっかり -ずっしり -ずっと -すてき -すてる -すねる -すのこ -すはだ -すばらしい -ずひょう -ずぶぬれ -すぶり -すふれ -すべて -すべる -ずほう -すぼん -すまい -すめし -すもう -すやき -すらすら -するめ -すれちがう -すろっと -すわる -すんぜん -すんぽう -せあぶら -せいかつ -せいげん -せいじ -せいよう -せおう -せかいかん -せきにん -せきむ -せきゆ -せきらんうん -せけん -せこう -せすじ -せたい -せたけ -せっかく -せっきゃく -ぜっく -せっけん -せっこつ -せっさたくま -せつぞく -せつだん -せつでん -せっぱん -せつび -せつぶん -せつめい -せつりつ -せなか -せのび -せはば -せびろ -せぼね -せまい -せまる -せめる -せもたれ -せりふ -ぜんあく -せんい -せんえい -せんか -せんきょ -せんく -せんげん -ぜんご -せんさい -せんしゅ -せんすい -せんせい -せんぞ -せんたく -せんちょう -せんてい -せんとう -せんぬき -せんねん -せんぱい -ぜんぶ -ぜんぽう -せんむ -せんめんじょ -せんもん -せんやく -せんゆう -せんよう -ぜんら -ぜんりゃく -せんれい -せんろ -そあく -そいとげる -そいね -そうがんきょう -そうき -そうご -そうしん -そうだん -そうなん -そうび -そうめん -そうり -そえもの -そえん -そがい -そげき -そこう -そこそこ -そざい -そしな -そせい -そせん -そそぐ -そだてる -そつう -そつえん -そっかん -そつぎょう -そっけつ -そっこう -そっせん -そっと -そとがわ -そとづら -そなえる -そなた -そふぼ -そぼく -そぼろ -そまつ -そまる -そむく -そむりえ -そめる -そもそも -そよかぜ -そらまめ -そろう -そんかい -そんけい -そんざい -そんしつ -そんぞく -そんちょう -ぞんび -ぞんぶん -そんみん -たあい -たいいん -たいうん -たいえき -たいおう -だいがく -たいき -たいぐう -たいけん -たいこ -たいざい -だいじょうぶ -だいすき -たいせつ -たいそう -だいたい -たいちょう -たいてい -だいどころ -たいない -たいねつ -たいのう -たいはん -だいひょう -たいふう -たいへん -たいほ -たいまつばな -たいみんぐ -たいむ -たいめん -たいやき -たいよう -たいら -たいりょく -たいる -たいわん -たうえ -たえる -たおす -たおる -たおれる -たかい -たかね -たきび -たくさん -たこく -たこやき -たさい -たしざん -だじゃれ -たすける -たずさわる -たそがれ -たたかう -たたく -ただしい -たたみ -たちばな -だっかい -だっきゃく -だっこ -だっしゅつ -だったい -たてる -たとえる -たなばた -たにん -たぬき -たのしみ -たはつ -たぶん -たべる -たぼう -たまご -たまる -だむる -ためいき -ためす -ためる -たもつ -たやすい -たよる -たらす -たりきほんがん -たりょう -たりる -たると -たれる -たれんと -たろっと -たわむれる -だんあつ -たんい -たんおん -たんか -たんき -たんけん -たんご -たんさん -たんじょうび -だんせい -たんそく -たんたい -だんち -たんてい -たんとう -だんな -たんにん -だんねつ -たんのう -たんぴん -だんぼう -たんまつ -たんめい -だんれつ -だんろ -だんわ -ちあい -ちあん -ちいき -ちいさい -ちえん -ちかい -ちから -ちきゅう -ちきん -ちけいず -ちけん -ちこく -ちさい -ちしき -ちしりょう -ちせい -ちそう -ちたい -ちたん -ちちおや -ちつじょ -ちてき -ちてん -ちぬき -ちぬり -ちのう -ちひょう -ちへいせん -ちほう -ちまた -ちみつ -ちみどろ -ちめいど -ちゃんこなべ -ちゅうい -ちゆりょく -ちょうし -ちょさくけん -ちらし -ちらみ -ちりがみ -ちりょう -ちるど -ちわわ -ちんたい -ちんもく -ついか -ついたち -つうか -つうじょう -つうはん -つうわ -つかう -つかれる -つくね -つくる -つけね -つける -つごう -つたえる -つづく -つつじ -つつむ -つとめる -つながる -つなみ -つねづね -つのる -つぶす -つまらない -つまる -つみき -つめたい -つもり -つもる -つよい -つるぼ -つるみく -つわもの -つわり -てあし -てあて -てあみ -ていおん -ていか -ていき -ていけい -ていこく -ていさつ -ていし -ていせい -ていたい -ていど -ていねい -ていひょう -ていへん -ていぼう -てうち -ておくれ -てきとう -てくび -でこぼこ -てさぎょう -てさげ -てすり -てそう -てちがい -てちょう -てつがく -てつづき -でっぱ -てつぼう -てつや -でぬかえ -てぬき -てぬぐい -てのひら -てはい -てぶくろ -てふだ -てほどき -てほん -てまえ -てまきずし -てみじか -てみやげ -てらす -てれび -てわけ -てわたし -でんあつ -てんいん -てんかい -てんき -てんぐ -てんけん -てんごく -てんさい -てんし -てんすう -でんち -てんてき -てんとう -てんない -てんぷら -てんぼうだい -てんめつ -てんらんかい -でんりょく -でんわ -どあい -といれ -どうかん -とうきゅう -どうぐ -とうし -とうむぎ -とおい -とおか -とおく -とおす -とおる -とかい -とかす -ときおり -ときどき -とくい -とくしゅう -とくてん -とくに -とくべつ -とけい -とける -とこや -とさか -としょかん -とそう -とたん -とちゅう -とっきゅう -とっくん -とつぜん -とつにゅう -とどける -ととのえる -とない -となえる -となり -とのさま -とばす -どぶがわ -とほう -とまる -とめる -ともだち -ともる -どようび -とらえる -とんかつ -どんぶり -ないかく -ないこう -ないしょ -ないす -ないせん -ないそう -なおす -ながい -なくす -なげる -なこうど -なさけ -なたでここ -なっとう -なつやすみ -ななおし -なにごと -なにもの -なにわ -なのか -なふだ -なまいき -なまえ -なまみ -なみだ -なめらか -なめる -なやむ -ならう -ならび -ならぶ -なれる -なわとび -なわばり -にあう -にいがた -にうけ -におい -にかい -にがて -にきび -にくしみ -にくまん -にげる -にさんかたんそ -にしき -にせもの -にちじょう -にちようび -にっか -にっき -にっけい -にっこう -にっさん -にっしょく -にっすう -にっせき -にってい -になう -にほん -にまめ -にもつ -にやり -にゅういん -にりんしゃ -にわとり -にんい -にんか -にんき -にんげん -にんしき -にんずう -にんそう -にんたい -にんち -にんてい -にんにく -にんぷ -にんまり -にんむ -にんめい -にんよう -ぬいくぎ -ぬかす -ぬぐいとる -ぬぐう -ぬくもり -ぬすむ -ぬまえび -ぬめり -ぬらす -ぬんちゃく -ねあげ -ねいき -ねいる -ねいろ -ねぐせ -ねくたい -ねくら -ねこぜ -ねこむ -ねさげ -ねすごす -ねそべる -ねだん -ねつい -ねっしん -ねつぞう -ねったいぎょ -ねぶそく -ねふだ -ねぼう -ねほりはほり -ねまき -ねまわし -ねみみ -ねむい -ねむたい -ねもと -ねらう -ねわざ -ねんいり -ねんおし -ねんかん -ねんきん -ねんぐ -ねんざ -ねんし -ねんちゃく -ねんど -ねんぴ -ねんぶつ -ねんまつ -ねんりょう -ねんれい -のいず -のおづま -のがす -のきなみ -のこぎり -のこす -のこる -のせる -のぞく -のぞむ -のたまう -のちほど -のっく -のばす -のはら -のべる -のぼる -のみもの -のやま -のらいぬ -のらねこ -のりもの -のりゆき -のれん -のんき -ばあい -はあく -ばあさん -ばいか -ばいく -はいけん -はいご -はいしん -はいすい -はいせん -はいそう -はいち -ばいばい -はいれつ -はえる -はおる -はかい -ばかり -はかる -はくしゅ -はけん -はこぶ -はさみ -はさん -はしご -ばしょ -はしる -はせる -ぱそこん -はそん -はたん -はちみつ -はつおん -はっかく -はづき -はっきり -はっくつ -はっけん -はっこう -はっさん -はっしん -はったつ -はっちゅう -はってん -はっぴょう -はっぽう -はなす -はなび -はにかむ -はぶらし -はみがき -はむかう -はめつ -はやい -はやし -はらう -はろうぃん -はわい -はんい -はんえい -はんおん -はんかく -はんきょう -ばんぐみ -はんこ -はんしゃ -はんすう -はんだん -ぱんち -ぱんつ -はんてい -はんとし -はんのう -はんぱ -はんぶん -はんぺん -はんぼうき -はんめい -はんらん -はんろん -ひいき -ひうん -ひえる -ひかく -ひかり -ひかる -ひかん -ひくい -ひけつ -ひこうき -ひこく -ひさい -ひさしぶり -ひさん -びじゅつかん -ひしょ -ひそか -ひそむ -ひたむき -ひだり -ひたる -ひつぎ -ひっこし -ひっし -ひつじゅひん -ひっす -ひつぜん -ぴったり -ぴっちり -ひつよう -ひてい -ひとごみ -ひなまつり -ひなん -ひねる -ひはん -ひびく -ひひょう -ひほう -ひまわり -ひまん -ひみつ -ひめい -ひめじし -ひやけ -ひやす -ひよう -びょうき -ひらがな -ひらく -ひりつ -ひりょう -ひるま -ひるやすみ -ひれい -ひろい -ひろう -ひろき -ひろゆき -ひんかく -ひんけつ -ひんこん -ひんしゅ -ひんそう -ぴんち -ひんぱん -びんぼう -ふあん -ふいうち -ふうけい -ふうせん -ぷうたろう -ふうとう -ふうふ -ふえる -ふおん -ふかい -ふきん -ふくざつ -ふくぶくろ -ふこう -ふさい -ふしぎ -ふじみ -ふすま -ふせい -ふせぐ -ふそく -ぶたにく -ふたん -ふちょう -ふつう -ふつか -ふっかつ -ふっき -ふっこく -ぶどう -ふとる -ふとん -ふのう -ふはい -ふひょう -ふへん -ふまん -ふみん -ふめつ -ふめん -ふよう -ふりこ -ふりる -ふるい -ふんいき -ぶんがく -ぶんぐ -ふんしつ -ぶんせき -ふんそう -ぶんぽう -へいあん -へいおん -へいがい -へいき -へいげん -へいこう -へいさ -へいしゃ -へいせつ -へいそ -へいたく -へいてん -へいねつ -へいわ -へきが -へこむ -べにいろ -べにしょうが -へらす -へんかん -べんきょう -べんごし -へんさい -へんたい -べんり -ほあん -ほいく -ぼうぎょ -ほうこく -ほうそう -ほうほう -ほうもん -ほうりつ -ほえる -ほおん -ほかん -ほきょう -ぼきん -ほくろ -ほけつ -ほけん -ほこう -ほこる -ほしい -ほしつ -ほしゅ -ほしょう -ほせい -ほそい -ほそく -ほたて -ほたる -ぽちぶくろ -ほっきょく -ほっさ -ほったん -ほとんど -ほめる -ほんい -ほんき -ほんけ -ほんしつ -ほんやく -まいにち -まかい -まかせる -まがる -まける -まこと -まさつ -まじめ -ますく -まぜる -まつり -まとめ -まなぶ -まぬけ -まねく -まほう -まもる -まゆげ -まよう -まろやか -まわす -まわり -まわる -まんが -まんきつ -まんぞく -まんなか -みいら -みうち -みえる -みがく -みかた -みかん -みけん -みこん -みじかい -みすい -みすえる -みせる -みっか -みつかる -みつける -みてい -みとめる -みなと -みなみかさい -みねらる -みのう -みのがす -みほん -みもと -みやげ -みらい -みりょく -みわく -みんか -みんぞく -むいか -むえき -むえん -むかい -むかう -むかえ -むかし -むぎちゃ -むける -むげん -むさぼる -むしあつい -むしば -むじゅん -むしろ -むすう -むすこ -むすぶ -むすめ -むせる -むせん -むちゅう -むなしい -むのう -むやみ -むよう -むらさき -むりょう -むろん -めいあん -めいうん -めいえん -めいかく -めいきょく -めいさい -めいし -めいそう -めいぶつ -めいれい -めいわく -めぐまれる -めざす -めした -めずらしい -めだつ -めまい -めやす -めんきょ -めんせき -めんどう -もうしあげる -もうどうけん -もえる -もくし -もくてき -もくようび -もちろん -もどる -もらう -もんく -もんだい -やおや -やける -やさい -やさしい -やすい -やすたろう -やすみ -やせる -やそう -やたい -やちん -やっと -やっぱり -やぶる -やめる -ややこしい -やよい -やわらかい -ゆうき -ゆうびんきょく -ゆうべ -ゆうめい -ゆけつ -ゆしゅつ -ゆせん -ゆそう -ゆたか -ゆちゃく -ゆでる -ゆにゅう -ゆびわ -ゆらい -ゆれる -ようい -ようか -ようきゅう -ようじ -ようす -ようちえん -よかぜ -よかん -よきん -よくせい -よくぼう -よけい -よごれる -よさん -よしゅう -よそう -よそく -よっか -よてい -よどがわく -よねつ -よやく -よゆう -よろこぶ -よろしい -らいう -らくがき -らくご -らくさつ -らくだ -らしんばん -らせん -らぞく -らたい -らっか -られつ -りえき -りかい -りきさく -りきせつ -りくぐん -りくつ -りけん -りこう -りせい -りそう -りそく -りてん -りねん -りゆう -りゅうがく -りよう -りょうり -りょかん -りょくちゃ -りょこう -りりく -りれき -りろん -りんご -るいけい -るいさい -るいじ -るいせき -るすばん -るりがわら -れいかん -れいぎ -れいせい -れいぞうこ -れいとう -れいぼう -れきし -れきだい -れんあい -れんけい -れんこん -れんさい -れんしゅう -れんぞく -れんらく -ろうか -ろうご -ろうじん -ろうそく -ろくが -ろこつ -ろじうら -ろしゅつ -ろせん -ろてん -ろめん -ろれつ -ろんぎ -ろんぱ -ろんぶん -ろんり -わかす -わかめ -わかやま -わかれる -わしつ -わじまし -わすれもの -わらう -われる diff --git a/keys/words/wordlist/spanish.txt b/keys/words/wordlist/spanish.txt deleted file mode 100644 index d0900c2c7..000000000 --- a/keys/words/wordlist/spanish.txt +++ /dev/null @@ -1,2048 +0,0 @@ -ábaco -abdomen -abeja -abierto -abogado -abono -aborto -abrazo -abrir -abuelo -abuso -acabar -academia -acceso -acción -aceite -acelga -acento -aceptar -ácido -aclarar -acné -acoger -acoso -activo -acto -actriz -actuar -acudir -acuerdo -acusar -adicto -admitir -adoptar -adorno -aduana -adulto -aéreo -afectar -afición -afinar -afirmar -ágil -agitar -agonía -agosto -agotar -agregar -agrio -agua -agudo -águila -aguja -ahogo -ahorro -aire -aislar -ajedrez -ajeno -ajuste -alacrán -alambre -alarma -alba -álbum -alcalde -aldea -alegre -alejar -alerta -aleta -alfiler -alga -algodón -aliado -aliento -alivio -alma -almeja -almíbar -altar -alteza -altivo -alto -altura -alumno -alzar -amable -amante -amapola -amargo -amasar -ámbar -ámbito -ameno -amigo -amistad -amor -amparo -amplio -ancho -anciano -ancla -andar -andén -anemia -ángulo -anillo -ánimo -anís -anotar -antena -antiguo -antojo -anual -anular -anuncio -añadir -añejo -año -apagar -aparato -apetito -apio -aplicar -apodo -aporte -apoyo -aprender -aprobar -apuesta -apuro -arado -araña -arar -árbitro -árbol -arbusto -archivo -arco -arder -ardilla -arduo -área -árido -aries -armonía -arnés -aroma -arpa -arpón -arreglo -arroz -arruga -arte -artista -asa -asado -asalto -ascenso -asegurar -aseo -asesor -asiento -asilo -asistir -asno -asombro -áspero -astilla -astro -astuto -asumir -asunto -atajo -ataque -atar -atento -ateo -ático -atleta -átomo -atraer -atroz -atún -audaz -audio -auge -aula -aumento -ausente -autor -aval -avance -avaro -ave -avellana -avena -avestruz -avión -aviso -ayer -ayuda -ayuno -azafrán -azar -azote -azúcar -azufre -azul -baba -babor -bache -bahía -baile -bajar -balanza -balcón -balde -bambú -banco -banda -baño -barba -barco -barniz -barro -báscula -bastón -basura -batalla -batería -batir -batuta -baúl -bazar -bebé -bebida -bello -besar -beso -bestia -bicho -bien -bingo -blanco -bloque -blusa -boa -bobina -bobo -boca -bocina -boda -bodega -boina -bola -bolero -bolsa -bomba -bondad -bonito -bono -bonsái -borde -borrar -bosque -bote -botín -bóveda -bozal -bravo -brazo -brecha -breve -brillo -brinco -brisa -broca -broma -bronce -brote -bruja -brusco -bruto -buceo -bucle -bueno -buey -bufanda -bufón -búho -buitre -bulto -burbuja -burla -burro -buscar -butaca -buzón -caballo -cabeza -cabina -cabra -cacao -cadáver -cadena -caer -café -caída -caimán -caja -cajón -cal -calamar -calcio -caldo -calidad -calle -calma -calor -calvo -cama -cambio -camello -camino -campo -cáncer -candil -canela -canguro -canica -canto -caña -cañón -caoba -caos -capaz -capitán -capote -captar -capucha -cara -carbón -cárcel -careta -carga -cariño -carne -carpeta -carro -carta -casa -casco -casero -caspa -castor -catorce -catre -caudal -causa -cazo -cebolla -ceder -cedro -celda -célebre -celoso -célula -cemento -ceniza -centro -cerca -cerdo -cereza -cero -cerrar -certeza -césped -cetro -chacal -chaleco -champú -chancla -chapa -charla -chico -chiste -chivo -choque -choza -chuleta -chupar -ciclón -ciego -cielo -cien -cierto -cifra -cigarro -cima -cinco -cine -cinta -ciprés -circo -ciruela -cisne -cita -ciudad -clamor -clan -claro -clase -clave -cliente -clima -clínica -cobre -cocción -cochino -cocina -coco -código -codo -cofre -coger -cohete -cojín -cojo -cola -colcha -colegio -colgar -colina -collar -colmo -columna -combate -comer -comida -cómodo -compra -conde -conejo -conga -conocer -consejo -contar -copa -copia -corazón -corbata -corcho -cordón -corona -correr -coser -cosmos -costa -cráneo -cráter -crear -crecer -creído -crema -cría -crimen -cripta -crisis -cromo -crónica -croqueta -crudo -cruz -cuadro -cuarto -cuatro -cubo -cubrir -cuchara -cuello -cuento -cuerda -cuesta -cueva -cuidar -culebra -culpa -culto -cumbre -cumplir -cuna -cuneta -cuota -cupón -cúpula -curar -curioso -curso -curva -cutis -dama -danza -dar -dardo -dátil -deber -débil -década -decir -dedo -defensa -definir -dejar -delfín -delgado -delito -demora -denso -dental -deporte -derecho -derrota -desayuno -deseo -desfile -desnudo -destino -desvío -detalle -detener -deuda -día -diablo -diadema -diamante -diana -diario -dibujo -dictar -diente -dieta -diez -difícil -digno -dilema -diluir -dinero -directo -dirigir -disco -diseño -disfraz -diva -divino -doble -doce -dolor -domingo -don -donar -dorado -dormir -dorso -dos -dosis -dragón -droga -ducha -duda -duelo -dueño -dulce -dúo -duque -durar -dureza -duro -ébano -ebrio -echar -eco -ecuador -edad -edición -edificio -editor -educar -efecto -eficaz -eje -ejemplo -elefante -elegir -elemento -elevar -elipse -élite -elixir -elogio -eludir -embudo -emitir -emoción -empate -empeño -empleo -empresa -enano -encargo -enchufe -encía -enemigo -enero -enfado -enfermo -engaño -enigma -enlace -enorme -enredo -ensayo -enseñar -entero -entrar -envase -envío -época -equipo -erizo -escala -escena -escolar -escribir -escudo -esencia -esfera -esfuerzo -espada -espejo -espía -esposa -espuma -esquí -estar -este -estilo -estufa -etapa -eterno -ética -etnia -evadir -evaluar -evento -evitar -exacto -examen -exceso -excusa -exento -exigir -exilio -existir -éxito -experto -explicar -exponer -extremo -fábrica -fábula -fachada -fácil -factor -faena -faja -falda -fallo -falso -faltar -fama -familia -famoso -faraón -farmacia -farol -farsa -fase -fatiga -fauna -favor -fax -febrero -fecha -feliz -feo -feria -feroz -fértil -fervor -festín -fiable -fianza -fiar -fibra -ficción -ficha -fideo -fiebre -fiel -fiera -fiesta -figura -fijar -fijo -fila -filete -filial -filtro -fin -finca -fingir -finito -firma -flaco -flauta -flecha -flor -flota -fluir -flujo -flúor -fobia -foca -fogata -fogón -folio -folleto -fondo -forma -forro -fortuna -forzar -fosa -foto -fracaso -frágil -franja -frase -fraude -freír -freno -fresa -frío -frito -fruta -fuego -fuente -fuerza -fuga -fumar -función -funda -furgón -furia -fusil -fútbol -futuro -gacela -gafas -gaita -gajo -gala -galería -gallo -gamba -ganar -gancho -ganga -ganso -garaje -garza -gasolina -gastar -gato -gavilán -gemelo -gemir -gen -género -genio -gente -geranio -gerente -germen -gesto -gigante -gimnasio -girar -giro -glaciar -globo -gloria -gol -golfo -goloso -golpe -goma -gordo -gorila -gorra -gota -goteo -gozar -grada -gráfico -grano -grasa -gratis -grave -grieta -grillo -gripe -gris -grito -grosor -grúa -grueso -grumo -grupo -guante -guapo -guardia -guerra -guía -guiño -guion -guiso -guitarra -gusano -gustar -haber -hábil -hablar -hacer -hacha -hada -hallar -hamaca -harina -haz -hazaña -hebilla -hebra -hecho -helado -helio -hembra -herir -hermano -héroe -hervir -hielo -hierro -hígado -higiene -hijo -himno -historia -hocico -hogar -hoguera -hoja -hombre -hongo -honor -honra -hora -hormiga -horno -hostil -hoyo -hueco -huelga -huerta -hueso -huevo -huida -huir -humano -húmedo -humilde -humo -hundir -huracán -hurto -icono -ideal -idioma -ídolo -iglesia -iglú -igual -ilegal -ilusión -imagen -imán -imitar -impar -imperio -imponer -impulso -incapaz -índice -inerte -infiel -informe -ingenio -inicio -inmenso -inmune -innato -insecto -instante -interés -íntimo -intuir -inútil -invierno -ira -iris -ironía -isla -islote -jabalí -jabón -jamón -jarabe -jardín -jarra -jaula -jazmín -jefe -jeringa -jinete -jornada -joroba -joven -joya -juerga -jueves -juez -jugador -jugo -juguete -juicio -junco -jungla -junio -juntar -júpiter -jurar -justo -juvenil -juzgar -kilo -koala -labio -lacio -lacra -lado -ladrón -lagarto -lágrima -laguna -laico -lamer -lámina -lámpara -lana -lancha -langosta -lanza -lápiz -largo -larva -lástima -lata -látex -latir -laurel -lavar -lazo -leal -lección -leche -lector -leer -legión -legumbre -lejano -lengua -lento -leña -león -leopardo -lesión -letal -letra -leve -leyenda -libertad -libro -licor -líder -lidiar -lienzo -liga -ligero -lima -límite -limón -limpio -lince -lindo -línea -lingote -lino -linterna -líquido -liso -lista -litera -litio -litro -llaga -llama -llanto -llave -llegar -llenar -llevar -llorar -llover -lluvia -lobo -loción -loco -locura -lógica -logro -lombriz -lomo -lonja -lote -lucha -lucir -lugar -lujo -luna -lunes -lupa -lustro -luto -luz -maceta -macho -madera -madre -maduro -maestro -mafia -magia -mago -maíz -maldad -maleta -malla -malo -mamá -mambo -mamut -manco -mando -manejar -manga -maniquí -manjar -mano -manso -manta -mañana -mapa -máquina -mar -marco -marea -marfil -margen -marido -mármol -marrón -martes -marzo -masa -máscara -masivo -matar -materia -matiz -matriz -máximo -mayor -mazorca -mecha -medalla -medio -médula -mejilla -mejor -melena -melón -memoria -menor -mensaje -mente -menú -mercado -merengue -mérito -mes -mesón -meta -meter -método -metro -mezcla -miedo -miel -miembro -miga -mil -milagro -militar -millón -mimo -mina -minero -mínimo -minuto -miope -mirar -misa -miseria -misil -mismo -mitad -mito -mochila -moción -moda -modelo -moho -mojar -molde -moler -molino -momento -momia -monarca -moneda -monja -monto -moño -morada -morder -moreno -morir -morro -morsa -mortal -mosca -mostrar -motivo -mover -móvil -mozo -mucho -mudar -mueble -muela -muerte -muestra -mugre -mujer -mula -muleta -multa -mundo -muñeca -mural -muro -músculo -museo -musgo -música -muslo -nácar -nación -nadar -naipe -naranja -nariz -narrar -nasal -natal -nativo -natural -náusea -naval -nave -navidad -necio -néctar -negar -negocio -negro -neón -nervio -neto -neutro -nevar -nevera -nicho -nido -niebla -nieto -niñez -niño -nítido -nivel -nobleza -noche -nómina -noria -norma -norte -nota -noticia -novato -novela -novio -nube -nuca -núcleo -nudillo -nudo -nuera -nueve -nuez -nulo -número -nutria -oasis -obeso -obispo -objeto -obra -obrero -observar -obtener -obvio -oca -ocaso -océano -ochenta -ocho -ocio -ocre -octavo -octubre -oculto -ocupar -ocurrir -odiar -odio -odisea -oeste -ofensa -oferta -oficio -ofrecer -ogro -oído -oír -ojo -ola -oleada -olfato -olivo -olla -olmo -olor -olvido -ombligo -onda -onza -opaco -opción -ópera -opinar -oponer -optar -óptica -opuesto -oración -orador -oral -órbita -orca -orden -oreja -órgano -orgía -orgullo -oriente -origen -orilla -oro -orquesta -oruga -osadía -oscuro -osezno -oso -ostra -otoño -otro -oveja -óvulo -óxido -oxígeno -oyente -ozono -pacto -padre -paella -página -pago -país -pájaro -palabra -palco -paleta -pálido -palma -paloma -palpar -pan -panal -pánico -pantera -pañuelo -papá -papel -papilla -paquete -parar -parcela -pared -parir -paro -párpado -parque -párrafo -parte -pasar -paseo -pasión -paso -pasta -pata -patio -patria -pausa -pauta -pavo -payaso -peatón -pecado -pecera -pecho -pedal -pedir -pegar -peine -pelar -peldaño -pelea -peligro -pellejo -pelo -peluca -pena -pensar -peñón -peón -peor -pepino -pequeño -pera -percha -perder -pereza -perfil -perico -perla -permiso -perro -persona -pesa -pesca -pésimo -pestaña -pétalo -petróleo -pez -pezuña -picar -pichón -pie -piedra -pierna -pieza -pijama -pilar -piloto -pimienta -pino -pintor -pinza -piña -piojo -pipa -pirata -pisar -piscina -piso -pista -pitón -pizca -placa -plan -plata -playa -plaza -pleito -pleno -plomo -pluma -plural -pobre -poco -poder -podio -poema -poesía -poeta -polen -policía -pollo -polvo -pomada -pomelo -pomo -pompa -poner -porción -portal -posada -poseer -posible -poste -potencia -potro -pozo -prado -precoz -pregunta -premio -prensa -preso -previo -primo -príncipe -prisión -privar -proa -probar -proceso -producto -proeza -profesor -programa -prole -promesa -pronto -propio -próximo -prueba -público -puchero -pudor -pueblo -puerta -puesto -pulga -pulir -pulmón -pulpo -pulso -puma -punto -puñal -puño -pupa -pupila -puré -quedar -queja -quemar -querer -queso -quieto -química -quince -quitar -rábano -rabia -rabo -ración -radical -raíz -rama -rampa -rancho -rango -rapaz -rápido -rapto -rasgo -raspa -rato -rayo -raza -razón -reacción -realidad -rebaño -rebote -recaer -receta -rechazo -recoger -recreo -recto -recurso -red -redondo -reducir -reflejo -reforma -refrán -refugio -regalo -regir -regla -regreso -rehén -reino -reír -reja -relato -relevo -relieve -relleno -reloj -remar -remedio -remo -rencor -rendir -renta -reparto -repetir -reposo -reptil -res -rescate -resina -respeto -resto -resumen -retiro -retorno -retrato -reunir -revés -revista -rey -rezar -rico -riego -rienda -riesgo -rifa -rígido -rigor -rincón -riñón -río -riqueza -risa -ritmo -rito -rizo -roble -roce -rociar -rodar -rodeo -rodilla -roer -rojizo -rojo -romero -romper -ron -ronco -ronda -ropa -ropero -rosa -rosca -rostro -rotar -rubí -rubor -rudo -rueda -rugir -ruido -ruina -ruleta -rulo -rumbo -rumor -ruptura -ruta -rutina -sábado -saber -sabio -sable -sacar -sagaz -sagrado -sala -saldo -salero -salir -salmón -salón -salsa -salto -salud -salvar -samba -sanción -sandía -sanear -sangre -sanidad -sano -santo -sapo -saque -sardina -sartén -sastre -satán -sauna -saxofón -sección -seco -secreto -secta -sed -seguir -seis -sello -selva -semana -semilla -senda -sensor -señal -señor -separar -sepia -sequía -ser -serie -sermón -servir -sesenta -sesión -seta -setenta -severo -sexo -sexto -sidra -siesta -siete -siglo -signo -sílaba -silbar -silencio -silla -símbolo -simio -sirena -sistema -sitio -situar -sobre -socio -sodio -sol -solapa -soldado -soledad -sólido -soltar -solución -sombra -sondeo -sonido -sonoro -sonrisa -sopa -soplar -soporte -sordo -sorpresa -sorteo -sostén -sótano -suave -subir -suceso -sudor -suegra -suelo -sueño -suerte -sufrir -sujeto -sultán -sumar -superar -suplir -suponer -supremo -sur -surco -sureño -surgir -susto -sutil -tabaco -tabique -tabla -tabú -taco -tacto -tajo -talar -talco -talento -talla -talón -tamaño -tambor -tango -tanque -tapa -tapete -tapia -tapón -taquilla -tarde -tarea -tarifa -tarjeta -tarot -tarro -tarta -tatuaje -tauro -taza -tazón -teatro -techo -tecla -técnica -tejado -tejer -tejido -tela -teléfono -tema -temor -templo -tenaz -tender -tener -tenis -tenso -teoría -terapia -terco -término -ternura -terror -tesis -tesoro -testigo -tetera -texto -tez -tibio -tiburón -tiempo -tienda -tierra -tieso -tigre -tijera -tilde -timbre -tímido -timo -tinta -tío -típico -tipo -tira -tirón -titán -títere -título -tiza -toalla -tobillo -tocar -tocino -todo -toga -toldo -tomar -tono -tonto -topar -tope -toque -tórax -torero -tormenta -torneo -toro -torpedo -torre -torso -tortuga -tos -tosco -toser -tóxico -trabajo -tractor -traer -tráfico -trago -traje -tramo -trance -trato -trauma -trazar -trébol -tregua -treinta -tren -trepar -tres -tribu -trigo -tripa -triste -triunfo -trofeo -trompa -tronco -tropa -trote -trozo -truco -trueno -trufa -tubería -tubo -tuerto -tumba -tumor -túnel -túnica -turbina -turismo -turno -tutor -ubicar -úlcera -umbral -unidad -unir -universo -uno -untar -uña -urbano -urbe -urgente -urna -usar -usuario -útil -utopía -uva -vaca -vacío -vacuna -vagar -vago -vaina -vajilla -vale -válido -valle -valor -válvula -vampiro -vara -variar -varón -vaso -vecino -vector -vehículo -veinte -vejez -vela -velero -veloz -vena -vencer -venda -veneno -vengar -venir -venta -venus -ver -verano -verbo -verde -vereda -verja -verso -verter -vía -viaje -vibrar -vicio -víctima -vida -vídeo -vidrio -viejo -viernes -vigor -vil -villa -vinagre -vino -viñedo -violín -viral -virgo -virtud -visor -víspera -vista -vitamina -viudo -vivaz -vivero -vivir -vivo -volcán -volumen -volver -voraz -votar -voto -voz -vuelo -vulgar -yacer -yate -yegua -yema -yerno -yeso -yodo -yoga -yogur -zafiro -zanja -zapato -zarza -zona -zorro -zumo -zurdo diff --git a/keys/words/wordlist/wordlist.go b/keys/words/wordlist/wordlist.go deleted file mode 100644 index 9ffbb1539..000000000 --- a/keys/words/wordlist/wordlist.go +++ /dev/null @@ -1,310 +0,0 @@ -// Code generated by go-bindata. -// sources: -// keys/words/wordlist/chinese_simplified.txt -// keys/words/wordlist/english.txt -// keys/words/wordlist/japanese.txt -// keys/words/wordlist/spanish.txt -// DO NOT EDIT! - -package wordlist - -import ( - "bytes" - "compress/gzip" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strings" - "time" -) - -func bindataRead(data []byte, name string) ([]byte, error) { - gz, err := gzip.NewReader(bytes.NewBuffer(data)) - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - - var buf bytes.Buffer - _, err = io.Copy(&buf, gz) - clErr := gz.Close() - - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - if clErr != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -type asset struct { - bytes []byte - info os.FileInfo -} - -type bindataFileInfo struct { - name string - size int64 - mode os.FileMode - modTime time.Time -} - -func (fi bindataFileInfo) Name() string { - return fi.name -} -func (fi bindataFileInfo) Size() int64 { - return fi.size -} -func (fi bindataFileInfo) Mode() os.FileMode { - return fi.mode -} -func (fi bindataFileInfo) ModTime() time.Time { - return fi.modTime -} -func (fi bindataFileInfo) IsDir() bool { - return false -} -func (fi bindataFileInfo) Sys() interface{} { - return nil -} - -var _keysWordsWordlistChinese_simplifiedTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x1c\x97\x55\x76\xeb\x30\x14\x45\xff\xf7\xa8\xc3\xcc\x49\xc3\x69\x98\xda\x86\xd9\x0e\x4c\xc6\xf7\x4a\x9a\xc5\x5b\x7e\x7f\x5d\x5d\x6d\x6c\x45\x07\xf6\x31\xdd\x04\xc1\x3d\x82\xb6\x77\x48\x7f\x45\x70\x2f\x12\x78\x29\xb4\x9f\x45\x6a\x05\x02\xcf\xc3\x7e\x3a\x04\xf7\x0d\x32\x5b\x12\xdc\x3d\x82\x7b\x8e\xe0\xfe\x83\xf4\x5e\x68\xa6\x4a\xe0\xcf\xb1\x8b\x28\x81\xdf\x44\x5b\x57\x74\x30\xc7\x34\x56\x04\xfe\x1f\xa6\x31\x44\x32\x7b\x82\x57\x1f\xe9\xef\x09\xbc\x12\x92\xf6\x90\xfd\x01\xc9\xa4\x90\xdd\x03\xcd\x54\x08\x9e\x5d\xa4\xbc\x23\xb8\xfb\x48\xb9\x8a\x3c\xce\x48\x6e\x85\x54\x0a\xc8\x6d\x4e\xf0\x18\x62\xe3\x2f\x82\x7b\x1e\xfb\x49\x23\x9b\x0a\x76\x77\x26\xf0\x96\x98\x65\x11\x37\x98\x60\x23\x05\xb4\xf9\x40\x2a\x25\x64\xd6\x45\xb6\x5d\xec\xb8\x80\x6c\x16\xe8\xe9\x0b\xcd\x46\xd0\x7d\x15\x79\xb7\x30\x7e\x19\x29\x46\x09\xee\x59\x82\x47\xf8\x99\x3d\xcc\x20\x82\xd9\x64\x71\xf1\x15\xe2\x2d\x90\xed\x15\xd3\xb8\x20\xb9\x1e\x2e\x5d\x40\x16\x31\x74\x7f\x46\x0a\x4d\xdc\x6f\x1b\x9b\xfe\x21\xf0\x0a\x98\x4a\x0a\x7b\xb9\x21\xfb\x32\x26\xbb\xc6\x94\xf6\xc8\xf6\x1b\xc9\x8d\x70\xe9\x32\xee\xff\x7b\xcf\x08\x5e\x75\x24\x73\x45\xfb\x1e\xf2\xaa\x13\xbc\x3e\x98\xd8\x83\xc0\x2f\x11\xdc\xbb\x68\xff\x0f\x29\xf9\x68\x2e\x87\x46\x96\xc8\xfc\x85\x78\x0d\xe4\x19\x41\xb6\x71\xa4\x92\xc1\x7e\xda\x48\x6f\x84\x69\x1c\x90\xe4\x95\xc0\xeb\x61\x12\x57\x24\x5b\x44\x66\x4d\x64\xb6\x46\x1b\x1f\xa4\xd7\x43\x5b\x73\x5c\x6c\x8a\x99\xbd\x09\x1e\x59\x02\x2f\x8f\x3c\x4e\xc8\x6b\x82\xe9\xdd\x91\xe4\x0a\x3b\x5e\xe1\x5a\x67\x74\x74\x23\xb8\x97\x90\xe4\x09\xa9\x24\x70\xe9\x22\xda\xdc\x63\xbc\x0f\x92\x4a\xa2\x5f\x7b\x74\x33\x45\x3e\x71\xa4\x5c\x24\x78\x8d\xd0\x76\x09\xd3\xcf\x23\xa5\x21\x52\xce\x10\x3c\x32\x48\x66\x8d\xee\x1a\x68\xa6\x49\xf0\x4a\x61\xcf\x2b\x74\xdf\xc0\xfc\xfd\x21\x95\x2a\x2e\x5a\x47\xaa\x2f\x74\x33\x43\xca\x6d\x74\x30\x46\xca\x3f\xe8\x71\x8c\xf1\xeb\xd8\xe5\x14\xd7\xda\xa2\x89\x32\xe2\x7b\x68\x3f\x83\x24\xff\xd0\xd6\x08\x73\xf2\x91\x54\x0f\x79\x67\xd0\x78\x12\x1b\x49\xa2\xfd\x08\xe6\x37\x4f\xe0\x4f\xd1\xf8\x09\xb9\x1d\x71\x91\x2e\xf2\xb8\xa2\xe5\x0a\xa6\x77\xc6\x4d\xda\x48\xb2\x8b\x59\xe5\x91\xc3\x17\x81\xd7\x40\xbf\xfb\x68\xb3\x83\x3d\x8c\x91\x6a\x1b\x37\x58\x13\xbc\x8a\x48\x72\x8e\xdc\xef\x68\x33\x8d\x46\x7c\xf4\x6f\x8c\xd4\xa3\xc8\xb3\x8c\x9e\x7d\xec\xf6\x8d\x94\x73\x98\xed\x18\x93\x0d\xef\xee\x8a\xfb\xfa\xa0\x87\x18\x36\x12\x45\x66\x67\x64\xe8\x61\x2f\x09\xec\xfb\x81\x5e\xa2\xd8\xdb\x0e\xe3\x2d\x91\x50\x7b\xbd\x37\x72\x38\x60\xfc\x21\x5a\x9a\x63\x86\x73\xec\x3b\x8e\xec\x53\x18\x3f\x81\x5d\x46\xb1\xdb\x31\x92\xf9\x45\xe6\x0f\x34\x9b\xc7\x2e\x6b\x68\x7f\x88\x8e\x1e\xd8\x6d\xe8\xc7\x0a\x92\xea\xa3\x85\x34\x92\x1e\x11\x3c\x06\x48\xc1\x43\x9e\x1e\xda\x78\x23\xa9\x13\x76\xfe\xc1\x4e\x7e\x91\xc7\x11\x89\x76\x91\x4f\x12\xcd\x84\xdf\x43\x06\xe9\x7d\x23\x99\x0e\x81\x1f\x7a\xad\x89\x16\xb7\xc8\x2c\x81\x6b\x0f\x91\x62\xe8\x8d\x0e\x36\x7b\x44\x92\x59\x5c\x6b\x85\x14\x4f\x04\x9f\x01\x7a\xf4\x91\x42\x0b\x17\x19\x61\x3a\x6f\xec\x32\x81\x89\x6f\x70\x93\x14\xc1\x3d\x8e\x86\x1e\x28\x4f\x09\xee\x7d\x64\xf7\x44\x3a\x2b\xa4\x94\x47\x3e\x2d\x82\x7b\x13\x97\xae\x22\x93\x6f\x02\x2f\x8b\x5e\x4a\xb8\xf6\x15\x3d\x3e\xd0\xc8\x00\xed\xef\xd0\xef\x28\x81\x17\xea\xa2\x85\x8d\x36\x08\xfc\x08\x76\x3b\x43\x92\x1b\x24\x79\x40\x07\x71\xb4\x71\xc5\xee\xa2\x68\xe3\x81\xde\x93\x98\x77\x09\x49\x15\x71\xe9\x34\xf6\xf5\x87\xf6\xce\x48\xf1\x0b\x37\x2d\x21\x99\x34\x9a\xad\x63\x3a\x2f\xf4\xab\x83\x8b\x0c\xb1\xb9\x03\x72\x0f\xbd\x9d\x45\xfa\x1e\xd6\xfb\xc5\xbe\x16\x04\xef\x3c\xa6\x3f\x44\x72\x63\x24\x19\x7a\x21\x8d\xee\xca\x98\xde\x16\x9b\x3e\x61\xdf\x6f\xec\x65\x8f\x59\xee\x30\x33\x0f\xbb\xdd\x22\xd3\x3d\x9a\x9b\xa3\xcd\x16\xb2\x2d\x60\x0e\x3e\x92\xfc\xc5\x2c\x7c\xa4\x58\x42\x2a\x45\xcc\x78\x8b\x66\x8b\x98\x65\x15\x79\x8e\x08\x3e\x63\xdc\xfa\x0f\x9b\x8b\x61\x77\x03\xcc\xe1\x84\x7e\x9d\x31\x6b\x0f\x49\xc6\x91\xd4\x85\xc0\xcf\xe1\x7a\x29\xf4\xbe\x26\x78\x8e\x90\xfe\x10\xbb\xbd\xa3\x9b\x39\xe6\x3d\x43\x1e\x1f\xcc\xf0\x84\xdd\xee\x71\xfd\x08\xba\xbd\x60\x46\x0d\xcc\x57\x01\xcd\x67\xd1\xef\x16\xf2\xce\x23\xe5\x5f\x82\x7b\x03\xb3\xbe\x62\x97\x31\xec\x35\x87\xf1\xd3\xd8\x69\x12\x79\x1d\x30\xdb\x16\xc1\xab\x84\x16\xa2\xb8\xe1\x89\xe0\xd9\x22\x78\x2c\x90\x7b\x1c\x99\x15\x91\xed\x03\x49\x7c\x70\x63\x1f\xd7\x49\x22\x5f\x29\xdc\xe0\x1b\xf7\x53\xc0\x7e\xbe\xd1\xe6\x06\xbd\x1d\x70\xdd\x37\xf6\x53\xc5\x0c\x3f\x48\x31\x8e\x54\x57\xc8\xb2\x81\x39\x8f\xd0\x5c\x04\x99\xa5\x91\x62\x0e\xc9\x7d\xe3\x06\x35\x4c\x3f\x8a\x64\xc2\x67\x8d\x90\x7a\x11\xe3\x2d\xd0\xc6\x0e\x9b\xf9\x43\xca\x47\x34\x11\xde\xc3\x89\xe0\x1d\xe6\xd8\x04\x79\x47\x70\xc9\x3b\x52\x4a\x21\xf7\x18\x92\xcc\x13\xbc\xbe\x70\x9d\x19\x7a\xcd\xa0\xdf\x09\xc4\xeb\x63\x96\x7b\x64\xf6\x83\xa4\x53\x98\xe3\x1b\x89\x3c\x91\xf2\x0d\x53\x4a\xa3\xad\x32\xc6\x3f\x23\x99\x1a\x2e\x92\x45\x47\x69\x24\xd5\x41\x36\x6d\x24\xd2\x41\x77\x3d\x02\xef\x88\x7c\x7e\xd1\xaf\x0c\xda\xdc\xe1\x3a\x13\x74\x38\x47\x0f\x43\xe4\x3b\xd4\xc7\x13\x53\xca\xa3\x85\xf0\xff\x9f\x48\xd2\x47\xdb\x75\xcc\x6b\x8b\x9e\x43\x5f\xc7\x30\xd9\x34\xb2\xcc\x23\xc5\x33\xc1\xbd\x8e\xc9\x5d\xb1\xb1\x23\x52\x8a\x11\x78\x7f\xd8\x5d\x0a\x17\x89\x21\x87\x6f\xa4\x9f\x42\x0a\x49\x4c\xf4\x97\xe0\x55\xc6\xee\xe3\xa8\x3f\x46\x4a\x1f\xe4\x10\xc1\x24\x97\x48\x39\x86\xf1\x26\x18\x3f\x85\x3c\xbf\x90\x4a\xf8\x19\x73\x5c\x3d\xec\xdb\x50\xa7\x73\xdc\xa2\x89\x78\x5f\xe8\xf5\x88\x6c\xdb\xc8\xfb\x86\xeb\x96\x31\xad\x24\x36\x5f\x46\x66\x07\x64\xdf\x40\x37\x61\x7e\x1d\x71\xc9\x22\x32\x3f\xe1\xfc\x04\x5a\x5a\xa1\xed\x37\x76\x9f\xc1\xbc\x7e\x30\xf3\x6f\x6c\xd6\x43\xaa\x13\x24\xec\xfc\xca\x2f\xc1\x33\x8a\xf6\x7b\xc8\x2e\x85\x66\x1f\xd8\xca\x1c\x37\x7e\xe0\xda\x47\x82\xfb\x1b\x53\x89\x63\xf3\x07\x74\xbf\x44\x72\x1f\xa4\x9a\x43\x07\x25\xa4\xbc\xc7\x56\x5e\x68\x7f\x85\xdc\xb7\xd8\xd7\x16\x33\x0a\x3b\xbb\x8b\xdc\xc3\x1c\x3a\xa3\xa7\x15\xf6\xd3\x47\x36\x2d\x74\x50\x41\x4b\x35\x82\x77\x0f\x3d\x9e\xd0\x30\x4f\xf7\x51\xa4\xbc\x40\x9b\x2f\x24\x5d\x46\x47\x55\xd4\xbb\xa2\x91\x12\xba\x99\xa0\xe3\x0c\x76\x15\x41\xa6\xbf\xc8\x20\x8d\x6e\x16\x48\xcf\x43\xca\x57\xdc\xe1\x89\x9e\x26\xd8\x65\x8a\xc0\x4f\x62\xcf\x0f\xcc\x79\x89\xc9\x1c\x90\xdb\x02\xf3\x3b\x42\x5b\x6b\xb4\x3f\x40\xb6\x27\x8c\xbf\xc1\xbe\x7c\xb4\x5f\xc4\xee\xc2\x0c\x19\x22\xc9\x24\x92\xbc\xa0\x5e\x05\xc9\xcc\xd0\x5c\x98\x4f\x77\xec\xf5\x84\x0e\x2b\x18\x3f\x8e\xdc\xc2\x8c\x38\xa3\x83\x0f\xa6\xb1\xc7\x75\x8a\x38\xbf\x8a\xc9\xed\xb0\xe7\x21\x92\xf6\xb1\x85\x38\xc6\x5f\x22\xc9\x33\xc1\xf3\x49\xf0\xea\x20\x83\x2e\xda\x3b\x62\xdf\x75\x82\xcf\x16\xfd\x4a\x22\xc3\x90\x5d\x7e\x91\xd9\x10\x17\x89\x62\xfe\x1a\xd8\xcc\x03\x29\x8e\x90\xf2\x09\x7b\x9e\x20\x95\x38\xb2\x2b\xa0\xed\x39\x36\x5a\xc0\x2e\xb3\xe8\x21\x8b\x69\xf8\x48\x6e\x88\xdc\xce\xd8\xdb\x10\x1b\xe6\xde\x20\x86\x9b\x7e\xa3\xd3\x08\x52\xb9\x23\xb9\x35\x52\x4c\xe3\xda\x27\x02\xaf\x86\x64\x06\x48\xa6\x87\xe6\x5a\xd8\x48\x1c\xcd\x7d\x21\x83\x32\x66\xd3\x44\xca\x33\xe4\x9d\x40\x8b\x13\xb4\xff\x83\xbd\x55\x31\x61\x8e\xd6\x26\x68\xef\x8d\xf9\x0d\xcf\x37\xc5\xfc\x76\x30\xdb\x08\xf6\xb3\xc7\xd5\x0e\x48\x76\x87\xec\x5f\xc8\x7d\x80\xec\x13\xd8\x62\x16\x49\x1d\xd1\xec\x07\x93\xff\x23\xf0\x67\xb8\x4e\x05\xd7\xfe\x20\xdb\x29\xa6\xb4\x43\xca\x05\xec\xee\x86\xbd\x26\x91\xf7\x16\xbb\x5d\xa3\xa5\x25\x72\x0b\xf5\xb8\xc3\xbe\xce\x68\xf6\x8d\x54\x16\x18\xef\x07\xd3\xcb\x11\xbc\x07\x04\xcf\x36\x6e\x7c\xc5\x8c\x23\xd8\xd7\x0b\x89\xd4\xd0\xcc\x07\xf3\x13\x45\x06\x15\xcc\x31\x8b\x7e\x15\x30\x5f\x73\x64\x3b\xc1\x4e\xa2\x48\xea\x86\x8d\xf7\x31\xfe\x00\xfd\xae\x20\x83\x16\x92\x8d\xa1\x97\x3c\x41\xf8\xce\xc5\x32\x76\x97\x45\x3e\x17\x5c\x27\x43\xe0\x17\x31\xaf\x16\xa6\x57\x41\xca\x79\xf4\x9c\xc7\x35\x3a\xd8\xfc\x02\x99\xf5\x91\x4c\x15\xb3\xf4\x71\x93\x2a\x2e\x52\xc1\x0d\x46\xe8\xed\x86\xee\x8a\x98\xe1\x06\xd3\xdd\x62\xfc\x0c\x36\xda\x45\x0f\xe1\x9d\x54\x09\xbc\x2a\x52\xff\x41\x5b\x13\xec\x2d\x7c\xe6\x2f\x12\xed\x63\xe2\x19\x64\xb6\x45\x76\x43\x4c\x7c\x89\xfd\x24\x91\x49\xe8\xaf\x39\x52\xdc\xa3\xe7\x23\x92\xf1\xd1\xfc\x1f\xfa\x89\x20\x9b\x06\x5a\xf9\xc6\x34\x42\xde\x0d\xef\x2b\x89\x8e\xee\xe8\x68\x8c\x7e\x4d\x09\xde\x17\xa4\xb2\xc4\x34\x8e\xe8\xfd\x4e\xf0\x48\x62\xcb\x7d\xa4\x7a\x42\x5b\x4b\x74\x35\x46\x1f\x4d\xec\x79\x89\x16\x87\xb8\x49\xc8\x01\x3e\xba\xfb\x45\x3b\x5b\xcc\xea\x44\xf0\xe8\x20\x8b\x0c\x3a\x2b\xa2\xd1\x1d\x9a\x5d\xe3\xea\x61\x0f\x6f\xd0\xc2\x1c\x97\xac\x21\xdb\x0c\x9a\xff\x20\x5e\x19\xe3\xdd\x91\x82\x8f\x79\x7a\xb8\x5e\xc8\xf0\x2d\x5c\x2d\x64\xc3\x36\xf2\x15\xb2\xed\x1c\x69\x1c\xb0\xbb\x1d\x76\xbb\x41\x13\xa1\x0e\xc6\xb8\x4e\x02\x5b\xba\x61\x0b\x57\xdc\xb1\x8f\x39\x6e\xd1\xe6\x0c\xd9\xac\xb1\x89\x03\x66\xfc\x8b\x8d\xcd\x91\x66\x02\xf7\xee\xa0\xcf\x06\x26\xe4\xe9\x7b\x05\x3b\x8e\xa0\x7f\x13\x74\xb2\x47\x4b\x05\x74\x53\x40\x8f\x1d\x24\xd3\x45\x1b\x3e\x76\x5f\xc7\xf4\xde\xd8\xed\x0a\xed\x74\x31\xc7\x1a\xc1\xe3\x80\x49\xc7\x31\xc3\x1e\xc1\xa3\x84\x0e\x22\xd8\xe2\x0e\xd9\x46\x71\xc7\x28\xf6\x7c\xc1\xd5\x86\x98\xe4\x0c\xbb\xf3\x31\xe5\x0d\xc1\x73\x87\x5b\x84\xec\x14\x6e\x86\x5f\xa4\x3c\x27\xb8\xef\x91\xe1\x03\x2d\x87\xec\xb0\x47\xf3\x49\xe4\xb9\xc0\xf6\xf2\xe8\x31\x8b\x44\xd3\x98\xf5\x07\xcd\x2e\x31\x9b\x06\xc1\xa3\x82\xdd\x47\x71\x63\x0f\x13\x1f\x62\x9e\x6b\xe4\x1d\xc5\x26\xee\x48\xb3\x8f\x0e\xde\xd8\x44\x17\xe9\xed\x91\x67\xd8\x77\x45\x6c\x3c\xf4\xfb\x10\xb3\x28\x13\x3c\xf6\xe8\xb0\x4e\x10\x66\x7e\xb8\x49\x92\x13\x34\xf2\x85\x99\x46\x91\x48\x11\x33\x6f\x62\xba\x69\x82\x4f\x1c\x37\xe8\x60\xc7\x73\xec\x2e\x81\xf9\xf8\xd8\x58\x16\x7b\xbb\x20\xfb\x27\x76\x3c\x45\xb6\x2f\x34\xfb\x87\x4e\xb3\xc8\xbd\x40\xf0\x9c\xa1\xf5\x22\xf2\x1d\xc3\x84\x3d\xb6\xed\xa3\xfb\x09\x32\x6f\x61\x06\x53\xb4\x10\x72\x5a\xb8\x3b\xb6\x68\xff\x17\xd9\xfe\x20\x5e\x0a\xf3\x6c\x62\xb2\x3d\xec\x72\x81\xb6\x47\xb8\xde\x0d\xd7\x88\x60\x77\x2d\x24\x64\xdf\x43\x12\xcd\xd5\xb1\xd3\x18\x36\xfe\x8d\x54\x9f\xc8\xaa\x8d\x76\x76\xc8\x2a\x8a\xf1\x3f\x68\xe7\x8a\x94\xba\x98\xde\x10\x3b\x1e\xe3\xee\x63\x64\xd3\x41\xfc\x2b\x52\x3c\x60\xe3\x57\xe4\x90\x27\x78\x8c\x09\xee\x67\x5c\x27\x85\x1b\xbf\xd1\x52\x16\xa9\x46\x30\xd1\x1d\x72\x8c\xa2\xa5\x1f\x74\x30\xc4\x46\x2a\x48\xf8\x9d\x97\xb2\xd8\xcb\x05\x7b\x3b\x21\xf5\x39\xb2\x99\x62\x77\x6f\x24\xbd\xc3\xc6\xc7\xb8\xc9\x00\xfd\x7b\x63\xfc\x22\x52\xbc\xe1\x5e\xe1\x1e\x1d\x62\x6b\x77\x74\xdb\x44\xf7\x77\x64\xdb\xc2\xe6\x5b\xc8\x6d\x80\x89\x65\x91\xe3\x1a\x79\x1e\x70\xbd\x70\xef\xae\x90\x79\x19\x3d\x7e\x70\xfd\x23\x3a\x48\xa1\xa5\x09\xea\x57\x71\x5f\x69\xdc\x7c\x83\x5e\xea\xd8\xcc\x0f\x1a\x89\x60\x2f\x57\xc4\xab\x23\x33\x8f\xe0\x99\xc3\x44\x2f\x98\x55\x09\x17\x69\x60\xa2\x1b\xec\xa5\x87\xbc\x6a\x48\xf9\x0f\xf7\xac\xa3\xb5\x0d\xa6\xd7\xc6\x4e\xa3\xb8\xce\x1a\xf1\x6e\x48\x63\x87\xbc\xbe\xb0\xe5\x02\xc6\xdb\x21\x91\x21\xe6\xd4\xc4\xf4\x9a\xe8\xea\x07\xf3\xb7\xc0\x2c\xa3\x48\xee\x07\x19\xc5\x90\xe1\x10\xfd\xfe\x41\xaf\x0b\xe4\x91\x44\xea\x19\xcc\xef\x10\x93\x0a\x7b\xe2\x17\x3d\xbd\xb0\x89\x2a\x32\x9d\x61\x26\x27\xf4\x6f\x89\x8b\x16\x09\xde\x4b\x64\xb7\x42\xbf\x26\xc8\xcb\xc7\x76\xaa\x68\xb3\x8f\x6d\x86\xcc\xb5\xc1\x78\x27\xe4\xf9\xc0\xcd\x8f\x04\xcf\x3b\x9a\x6b\xe3\x42\x9e\x7b\x7c\xd0\x6e\x0b\x5b\xbc\x61\xea\x0b\x64\xfc\x8d\x78\x39\xcc\xa6\x8a\x46\xaf\x68\xe6\x86\xdd\x7e\x90\x71\x03\x99\xa7\x71\x91\x32\x1a\x66\x73\x26\x82\xb6\x42\x6f\x85\x9d\x37\x46\xf7\x3b\x5c\x34\x4d\xe0\xbf\xd0\x5d\x0d\x3d\xcd\x71\x91\x08\x7a\x6e\xa1\xd5\x14\x26\xba\x47\x5e\x61\xa7\x35\xb1\x91\x16\x32\x2b\xa3\xf9\x35\xf2\xe9\xe0\xea\x7d\x4c\x61\x8b\x19\xff\x11\x78\x19\xcc\x23\x8a\xf4\x33\xb8\x5e\xc8\x88\x2f\x82\xf0\x3d\x73\x2f\xcc\x2e\xec\xc3\x0b\xae\x1d\x32\x5b\xc8\x1c\xe1\xc6\x7a\x21\xa3\x14\xae\x97\xc0\x7e\x4a\xe8\xa9\x87\xc9\xdc\xd1\xf9\x13\x17\xfd\x60\xf7\x79\xa4\xb2\xc2\xa5\x4b\x98\x42\x98\xe3\x2d\xcc\x79\x87\x44\xcb\x48\xf2\x8e\x5b\xa4\x30\xe7\x09\x66\xb9\xc0\x26\x62\x68\xc8\x3e\xe1\x99\x0f\x29\xe4\x13\x7a\xae\x8d\xc6\x73\xc8\x38\xdc\xc4\x2d\x34\x91\x41\xfb\x07\xb4\xf7\xc1\x78\x33\xcc\xb1\x85\x44\xde\xc8\xbe\x8b\x69\xf5\xd0\x79\x17\xfb\xdf\x87\x79\xec\x79\x83\x99\x86\xb9\xda\x43\x0f\x21\xc3\x44\x31\x93\x12\xee\x67\x85\xe9\x55\xd1\xe2\x17\xf2\x1c\xa2\xdd\x33\x92\x3d\x62\xcf\x3b\x74\x9b\xc3\xa5\x73\xd8\x5d\x91\xc0\x1b\x23\xa1\x96\xc6\x61\xee\x86\xdd\x93\x41\xf6\x6d\x5c\xcb\x47\xcb\x1b\x4c\x6c\x8b\x6e\xf3\x48\xea\x0f\x1d\xcf\x91\x45\x1a\xbb\x59\x60\xfc\x27\x9a\xef\x21\x95\x33\x81\xdf\x46\x2f\x5b\x5c\x74\x83\xbc\x2b\x68\x6c\x85\x56\xd3\xd8\xfd\x0d\x7b\xf9\xc6\x6c\xc3\x5d\xd0\xc0\x6e\x27\x98\xc6\x0d\xa9\x3c\x90\x5e\xa8\x97\x50\xbb\x15\xec\x39\xec\xe3\x3c\xa6\xe4\x23\xb7\x15\x36\x12\x72\xc7\x02\x5b\x0c\xf7\xff\x06\x7d\xbc\x71\x8d\x2d\x92\x0e\xf7\x92\x8f\x6b\x24\xd1\xaf\x50\x3b\x6b\x24\x3b\x47\xd2\x03\xcc\xe4\x80\x7b\x7d\xd0\xcc\x0f\x26\xf6\xc4\x79\x3e\xc6\xf3\x30\x8b\x28\xe2\x0d\x31\xbd\x1e\x26\x9b\xc1\x3c\xeb\x48\x3a\x82\x19\xf4\xd0\x76\x01\x59\x77\xd1\x6b\x16\xb3\xa9\x21\xed\x33\x5a\xae\x21\xc7\x3b\xda\x0f\xb3\x2a\x81\x1d\xb7\xb0\xad\x32\xb2\xac\x62\xcf\x77\x6c\xb2\x82\xcc\xcf\xc8\xd7\x02\x8d\xef\x08\x1e\x6d\x82\x67\x07\x8d\x4e\x90\x42\x04\xe3\x1d\xd0\x6c\x09\xfb\x5e\x63\x23\x27\xe4\xf5\x83\x4d\x4f\x09\xbc\x0f\xa6\x16\x32\xd5\x05\x9b\xc8\x62\x96\x11\x6c\x65\x45\xf0\x49\x60\x5e\x55\x6c\x26\xf4\x44\x0b\x69\xde\x30\xde\x05\xd9\xdd\xd1\x43\x0b\x2d\xc4\xd0\xf3\x0f\xf6\xec\xe1\x5a\x3f\xe8\xf0\x0f\x93\x49\x61\xe2\x3b\xf4\x3c\xc7\xac\x7c\x64\xd2\xc1\xbe\x76\x48\x3e\x8d\xc4\xcb\xa8\xdf\x45\x4a\x6d\x6c\xad\x83\xcd\x9d\xb0\xb1\x1d\x32\x18\xa3\xc3\x03\xb6\x38\xc6\x26\x3f\x04\x7e\xa8\xd3\x24\xb2\x7f\x63\x5f\x4b\x24\xb5\xc7\x9e\xc7\x98\x8e\x8f\xf3\x4b\x48\x36\x87\xab\xf9\x48\x3e\xdc\x48\x71\x5c\x37\xcc\xfe\x15\x2e\xbe\x41\x4e\x7b\xe4\x1e\x45\xef\x3b\x82\x67\x19\xfb\x5a\x11\x78\x6b\x74\xf7\x85\xd6\x17\xd8\xd2\x2f\x92\xf1\xd0\xcb\x0f\x66\xd9\x46\xcb\x67\x74\xf4\x83\x44\xc3\xae\xdf\x62\x63\x63\xe4\xd8\xc3\x34\xda\xe8\x69\x8c\x19\x8c\x31\xbf\xe1\x8e\x09\xcf\x3c\xc3\xb5\x23\x04\xcf\x2a\x7a\x48\x63\x33\x45\x4c\x98\xdb\xfe\x17\x26\x76\x47\xea\x47\xcc\xf4\x86\xf1\x43\x56\xcf\xa3\xb7\x31\xb2\x6f\x22\x95\x70\xa3\xdd\xd0\xe1\x19\xa9\x66\x90\x77\x0d\x37\xe9\xa3\xa7\x1f\xcc\xaa\x88\x7c\xc2\x67\x5d\xb0\xf5\x01\x9a\x6f\xa2\xe7\x6f\xb4\x94\xc1\x7d\xf5\xb1\xef\x1e\x32\xdd\xe2\x1a\xa1\x9f\x7e\xb1\x9d\x2e\xf2\xdc\xa1\xd5\x35\x1a\x9e\xf5\xf1\x44\xfc\x1b\xb2\xcf\x61\x7e\x5a\x98\x70\x1b\x3e\x13\xb8\xee\x15\xd3\xac\xa2\xfb\x32\xb2\xfd\x45\x96\x15\x5c\x3f\x8d\xa9\x7e\xa3\x91\x1f\x64\x3f\xc3\x54\xce\xc8\xfb\x07\x2d\x97\xb1\xa9\x3e\xf6\x33\x40\x66\x0f\x6c\x72\x8f\x79\xb6\x31\xe5\x11\x66\x7d\x43\xa7\x5b\xf4\x7b\x80\xf9\x7d\xa0\xc7\x21\x12\xfb\xc3\xf8\x27\xe4\x93\xc2\xc5\x16\x48\x76\x8d\x3c\xee\xe8\x25\x85\x8e\xc2\x5c\x9b\x63\xb2\x1d\xec\x79\x8b\x99\x3d\xd1\x90\xa3\x6b\x23\x8c\xf7\xc0\xbc\x26\x68\xbe\x88\x84\xfc\xdd\xcc\x61\x27\x4d\x64\x18\x47\xf2\x33\xcc\xab\x8b\x49\x2c\xd0\x57\x9f\xe0\x59\x44\x26\x2b\xf4\xef\x88\x79\x0e\x90\x65\x1d\xc9\xe4\x70\xf3\x03\x81\xff\x41\xe6\x4d\x5c\x7d\x80\xfb\x7b\x12\xdc\x5f\xd8\xdb\x0a\x17\x7a\xbd\x10\xfe\xfe\x8d\x66\x7f\x91\xe6\x00\x3b\xc9\x63\x62\x1b\xf4\x30\x46\x1e\x5f\xd8\xdd\x1d\x79\x86\xfb\xef\x80\x4e\x92\xc8\xfc\x8a\x9e\xa3\x98\xe8\x1b\x9b\x19\xe2\xb2\x67\x6c\x3e\xe4\xbd\x27\x1a\xfe\xcd\x2e\x8a\xa6\x63\x48\x98\xe9\x1d\x0f\x19\x36\x90\x5d\x02\x39\xe4\xb0\xb7\x38\x7a\x1f\xa3\x85\x2a\xc1\xfd\x81\xcd\x86\x3a\x0d\xfd\x1e\xb2\x55\xc8\x7c\x0f\x34\x73\xc6\x8c\xa2\xe8\x64\x81\x0d\x33\x3c\xd5\xc0\x5e\x66\xe8\xbd\x81\xd4\x37\xe8\xd7\x1f\x6e\xd2\x42\xe6\x0d\x5c\x3d\x49\xe0\x1f\xb1\x9d\x12\x26\xdc\x8a\x8b\x07\xc1\xa3\x8c\x29\x17\x31\x8d\x13\x3a\x2e\xe0\xa2\x17\x24\x19\xc5\x75\x53\xd8\x6f\x8f\xc0\xaf\xe3\x36\x65\x5c\xa3\x82\x76\xea\xe8\x7e\x8b\x24\x9f\xb8\x6e\x05\x33\x29\x62\x2f\xbf\x68\x7e\x85\x7c\x46\xd8\x58\x1c\xf3\xbc\x63\xb2\x17\x34\x37\x41\x8a\x5d\xe4\xb6\x44\xa6\x27\x24\x99\x40\x07\x7d\xec\x76\x87\xdd\x75\x31\x93\x25\x66\x3e\x47\x87\x3b\xdc\xf8\x82\xdc\xc6\x98\xe1\x1a\x8d\x1d\x31\xd1\x02\xee\x9d\x20\x78\x2e\x30\xf3\x15\xb2\xf3\xd1\x71\x0c\x57\xf7\x90\xfe\x14\x8d\x56\xd0\xe8\x1e\x17\xaf\x62\xaf\x53\x34\xf7\x87\x2d\xd6\xb0\xc9\x37\xf6\x7c\x46\x87\x0d\xd4\x3f\x63\x0a\x3d\x5c\xbb\x81\x7d\xa7\x90\x85\x8f\x8c\x7f\xd1\xda\x0c\x89\xad\x30\x9b\x37\xae\xf5\x40\xb3\x7b\xcc\xf9\x17\x33\x8a\xe1\xfe\x6f\xa6\x32\x52\xc9\xe1\x3a\x57\x82\x67\x05\x69\xc6\x30\xcd\x16\xa6\x7e\x45\xd6\x29\x34\xd7\xc5\xa6\x63\x68\xf5\x8e\x7c\x8a\xd8\xce\x1b\xdb\x1f\xe3\x62\x3e\x36\x7e\x47\x6e\x6b\xb4\x30\x43\xa2\x57\xe4\x19\x47\x97\x2f\x24\x77\x24\x78\x9c\x70\xb1\x3a\x52\xc9\x12\xf8\x51\x4c\x3c\x86\x19\x35\x31\xcb\x21\xc1\xa3\x80\xcd\xec\x09\x9e\x67\x4c\xbd\x8f\x5e\x92\x04\xf7\x0e\xda\x8d\x61\xd2\x73\x74\x1d\xe6\xd7\x09\xfb\xb9\xa1\xdd\x90\x2f\x0b\x98\xe5\x12\x1b\x4f\x61\x77\x0b\xcc\x7e\x89\xbd\x97\x31\xf5\x1b\x76\x7f\x40\xaa\x29\x64\xfb\xc6\x9c\x72\xe8\xb9\x87\x7d\x67\xd1\xc4\x0c\xf3\xfb\x8d\xeb\x76\xd0\x48\x0d\x73\x6c\x13\x3c\xc2\x2d\xfe\x83\x8d\xad\x31\x87\x22\xfa\x55\x46\xaf\x31\x4c\xaa\x83\xe9\xa6\x08\xde\x0b\x34\xf6\x87\x96\xda\x04\xde\x2f\xc6\x1b\xe1\x52\x35\x4c\x3e\x86\x6b\x44\xd1\x5b\x04\x8d\xae\x30\xd9\x23\xae\x7f\xc7\x64\xfe\xb0\x97\x32\x2e\x92\xc2\x94\xd6\xb8\xce\x05\x33\x1f\x60\x96\x35\xf4\xd2\xc1\x1e\x0b\xc8\xeb\x81\xbc\x9e\x68\x2c\x8b\xbb\x6f\xb0\xd7\x3c\x92\x9e\xa1\x9d\x15\xe6\x7f\x1e\x65\x30\xcb\x90\x63\x2e\x98\xd7\x11\x9d\xec\x30\xb1\x12\x1a\x66\xde\x34\x8f\x5b\x1f\x30\x9b\x1e\x72\x1a\x23\xa9\x1a\x12\xee\xd9\xdd\x07\xbb\xab\xa2\x97\x3b\x7a\x0a\xf9\xfd\x85\xfd\x0c\x31\xe3\x24\xa6\x99\xc2\x9e\x6f\xe8\xb3\x8c\x59\x7d\x90\xd4\x08\xf9\x5d\x63\xe3\x51\x6c\x6e\x87\xc9\x4e\x90\x72\x0f\xdb\x8d\x20\xf3\x39\xee\x3e\x45\x8e\x1b\xcc\x3b\x87\xa4\x37\x04\xf7\x23\x32\x6e\x63\xfc\x36\x2e\x79\xc1\x7e\x17\x31\xbd\x14\xae\x31\x46\xbc\x0e\x66\xf3\x40\x52\x3e\x36\xdc\x9b\xd5\x04\x76\xb2\xc1\x6c\xf2\x68\xbe\x86\xc4\xbb\x68\xeb\x80\xab\xbd\x71\xf7\x21\xfa\x4c\xa1\xc7\x0c\xa6\x9f\xc5\x34\xcb\xe8\xcd\x47\xa7\x35\xcc\xba\x85\x19\x0f\x70\xc3\x35\x2e\xf2\x44\xb3\x1b\x82\xf7\x0a\x49\x67\xd1\x82\x87\x99\xb4\xd0\xd1\x0b\x13\xab\xa1\x83\x1d\x1a\x9b\xe2\x16\x65\x24\x37\xc0\x1e\x7e\xb0\xef\x17\x92\x8f\xe3\xee\x1f\xb4\xb5\x40\x2a\x61\x46\xf6\x31\x21\xa7\x0f\xf3\xd8\x77\x0e\x0d\xef\x63\xbe\x45\x2b\x7f\xb8\x9f\x18\xf6\xfd\x8d\xe4\xc3\x1c\x9b\x12\x3c\xf7\xd8\x5a\x1e\xe3\xd7\x70\xbd\x37\xc1\x3d\x64\xb0\x0b\xb2\x4c\xa1\xf9\x21\xb2\x4d\x63\xdf\x55\x5c\xe7\x0b\xd7\xfb\x42\x42\xee\xab\x27\x90\x73\x1a\xc9\xfe\x20\x91\x31\x52\x4a\x22\xb5\x3f\xdc\xfa\x8a\x6d\xee\x90\xcc\x0d\x6d\xce\x31\x5f\x3f\xd8\x4b\x1e\x99\x67\x09\x5e\x3d\xf4\x92\x46\x9f\xbf\x68\x2f\x3c\x67\x1a\x57\xeb\xa0\xe3\x38\x9a\xbd\x12\xf8\x0d\xec\xa7\x41\xf0\x69\x11\x78\x65\x6c\xb2\x81\xfb\xce\xa3\xd3\x03\x76\x91\x42\xc7\x29\x34\x96\x40\xca\x0d\xb4\xf6\x8d\xfb\x69\x21\xf9\x36\xda\xf2\xd0\xe3\x1d\xd9\xcc\x90\x4a\x05\xd9\x0c\xd1\xfb\x08\x39\x64\x30\xcd\x37\xb2\xe8\xa0\xf1\x3e\x81\xbf\xc7\xe4\x47\xd8\x78\x04\xbb\xaf\xa0\xb9\x1e\xae\x9f\x45\xc7\x55\x24\xe4\xcc\x76\x0f\x3b\xde\x63\x7a\x2d\xf4\xde\xc2\x26\xca\xd8\x4b\x13\xbd\x16\x30\x8d\x3e\xda\x7b\xe0\xda\x49\x6c\xac\x80\xd4\xd7\x48\x29\x8b\x89\xc7\x31\xde\x1f\xba\x4b\xa2\xed\x15\xc1\xf3\x07\xd3\x4a\x63\x92\x5b\xa4\xfc\xc0\xd5\xb2\x68\x65\x83\x2d\x94\x30\x7f\x4f\x5c\xf2\x86\x44\x6f\xc8\xb3\x8e\x6b\xcc\xd1\x68\x78\xa7\x7b\x64\x50\xc5\x3d\x7d\xcc\xe7\x89\xf1\xae\x48\xb9\x83\xc9\x1f\x70\x91\x2d\xe6\x55\xc1\xf8\x7d\x74\xda\x45\x73\x55\x6c\x6a\x85\x6d\xfc\x21\x3b\x0f\xf7\x33\xc3\xac\x53\x48\xea\x8a\x7e\xef\x90\x54\x01\x09\x77\x5a\xfa\x8e\xf1\x93\xc8\x20\xd4\xb8\x87\x49\xec\xb1\xaf\x3d\xfa\x37\x45\x3b\x79\x4c\x7b\x81\xbc\xc7\xb8\xc6\x06\xd7\x58\x10\xdc\x97\x68\xeb\x0f\xd7\xf0\x91\xef\x04\x5a\xe9\xa3\xd9\x2a\x2e\x16\x21\xf0\x36\xb8\xe4\x0e\xfb\xc9\x60\x33\x35\x6c\x22\x85\x4b\x5e\x71\xad\x23\xf2\x59\xe2\x92\x5d\xdc\xf8\x85\x79\xbf\xd0\xeb\x0a\x29\xde\x09\xfc\x16\xae\x13\x6a\x73\x88\xc6\xd7\xe8\x60\x83\x2c\xbb\xd8\x58\x17\x2d\x66\x71\xd3\x36\xfa\x8c\xa1\xed\x14\xfa\xe7\x21\x95\x37\x2e\x5e\xc2\xc4\x6f\xe8\x21\x8a\x54\x2f\xb8\xf9\x1e\x5b\x59\xe2\x7a\x49\x5c\x6c\x8b\xfd\x44\x31\xe9\x2f\xb4\x56\x43\x96\x3e\xf6\x72\x46\xb6\x67\x4c\x7c\x81\x44\x3c\xe4\x5e\x41\x9b\x55\x5c\x3d\x8e\xb6\x56\xb8\x54\x1a\x5b\x9d\xe2\xc2\xad\xd2\x0b\x39\xf6\x83\xe6\x0b\x48\x2c\x89\x4d\x3e\x90\xc5\x1c\x2d\x67\xb1\xe7\x19\x9a\x4f\xa1\x9b\x1f\x6c\x75\x8c\x8d\x7b\x04\xf7\x09\x7a\x59\x23\xe1\x99\xda\x31\xe4\xfb\x17\x2d\x8c\xb1\xcb\x0c\xf6\xfc\x83\xfe\x67\x98\x33\x7a\x08\x7f\x2e\x20\xa9\xb0\xd7\x3c\x64\xd9\xc7\xee\xc3\xec\xb8\x22\xb9\x70\x5f\xff\x61\xc3\x9d\xd6\x2e\x63\x43\x26\xef\x65\x70\x3f\x55\x82\x47\x03\xf5\x7e\x08\xee\x3d\xa4\x38\x41\x73\x0f\x5c\xeb\x86\xd4\x56\x48\x66\x8b\x5b\xbf\x31\x61\x5e\xc4\x86\x68\xb5\x8d\xab\xd7\xd0\xd2\x0d\x37\x49\x23\x0f\x1f\x1d\x26\xd0\xf8\x08\x8d\xaf\x08\x5e\x27\x02\x3f\x8d\x4d\x86\x8c\x36\x40\xaf\x33\x24\x5b\xc5\x7c\x2f\x91\xd1\x18\x3d\x3d\xb1\xd5\x03\xe6\xb5\xc6\xf5\x8b\x68\xf1\x1b\x1b\x2f\x61\xf3\x45\xd4\x0f\x39\x7c\x8d\x16\x93\xe8\xa3\x8d\x19\x15\x71\xfd\x6f\x5c\xec\x82\xad\x24\x30\xcd\x1d\x7a\x0b\xf7\x4d\xd8\x0b\x39\xcc\xf1\x07\x13\x6f\x23\xdb\x0f\x3a\x9e\xa2\x99\x0c\x6e\x7d\x42\x7e\x63\xd8\xe9\x17\xf2\xee\x60\xb6\x1b\xb4\x58\xc1\xc6\x46\x68\xad\x8a\x76\x6a\xd8\xf7\x0a\xdd\x7e\xb0\xa5\x23\x5a\xcd\xa1\x95\x24\x2e\x79\x40\x0e\x65\x4c\xf3\x17\xa9\x47\xb0\x61\xa6\x8e\x2e\xe8\xf1\x17\xd3\x3d\x60\xbe\x92\x48\x79\x84\x6b\x47\xb1\xa5\x03\xfa\x75\xc4\xbe\x9b\xb8\xda\x1a\xd3\x0a\x77\xd2\x00\xb9\xdd\x70\xf3\x0f\x66\x7e\x27\xb8\xb7\x31\xa5\x04\xea\x85\x5e\xdd\xe3\x22\x3e\xf2\xda\x20\xfb\x70\xdb\x7d\x90\xc5\x0a\x9b\x4d\x23\x95\x6f\xdc\x70\x81\x46\x56\x98\xe1\x16\xdd\xa4\xf9\x17\x00\x00\xff\xff\xbf\x1b\x72\xe3\x00\x20\x00\x00") - -func keysWordsWordlistChinese_simplifiedTxtBytes() ([]byte, error) { - return bindataRead( - _keysWordsWordlistChinese_simplifiedTxt, - "keys/words/wordlist/chinese_simplified.txt", - ) -} - -func keysWordsWordlistChinese_simplifiedTxt() (*asset, error) { - bytes, err := keysWordsWordlistChinese_simplifiedTxtBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "keys/words/wordlist/chinese_simplified.txt", size: 8192, mode: os.FileMode(420), modTime: time.Unix(1523115814, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _keysWordsWordlistEnglishTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\x5b\xdd\xbe\xbc\x2a\x08\xbd\xf7\x2d\xc9\xa8\xd8\xa3\xe2\x41\x9d\x76\xfb\xe9\xcf\x6f\xad\xfe\x17\x83\xe5\x07\x2a\x22\x2c\xcc\x91\x4d\xda\xee\x2d\xc9\x66\xc5\xe6\x93\x64\x2b\x9a\x64\xf3\x35\x41\xbf\x78\x1e\xda\xf0\x32\x3c\x36\x24\x33\x24\xf3\x7d\xc5\x9e\x64\x5b\x43\x93\xe4\xac\x63\x20\xb1\x9d\x95\x73\xf6\xf5\xa6\x6f\xf1\x65\x0a\x56\xd9\xf6\x24\xd9\xd7\x98\x96\x93\xe4\xff\x96\x05\x72\xc3\xd9\x18\xf5\xa7\x61\x2c\x79\x7a\x80\xc6\xcb\x75\x2e\x29\x49\x76\xe9\x33\xc9\xbe\xe3\x67\x99\x8f\x6f\xf9\xfe\xb3\x06\x5e\xab\x81\xae\x02\xfa\x95\x96\x15\xa9\x21\xd1\xf0\x0d\x3d\x1e\x87\x58\x20\x71\x0c\xfd\x08\xc1\x78\x4e\xb1\x96\xe4\x54\xfc\x30\xe6\x33\x54\x93\x5c\x2a\x7b\x12\xab\x89\x2d\x2c\xba\xc7\x4c\x62\x03\xd2\x29\x12\x35\x49\xd9\x16\x68\xf6\xcb\x4b\x92\xa2\x28\x2f\xa6\x2d\x49\xc1\x7b\xd1\x07\xd4\xef\x24\xa5\x3a\x06\x58\xbc\xa1\x71\xbf\x24\x49\x09\x95\x1d\x15\x86\x27\x29\x53\x23\x49\xb9\xe5\x19\x49\xaa\x4c\x5d\x81\xf4\xcf\xda\x99\xa4\xfa\x4b\x29\xcf\xba\x86\xee\x49\x9a\x94\x07\x1c\x5b\xbe\x20\xa8\x96\x8d\x23\x6f\x27\xf8\xb4\x13\x63\x6c\x67\x3c\x49\x9a\x55\x88\xae\x7d\x98\xd5\x7c\x51\x2a\xad\x51\xa0\xcd\xe7\xc5\x06\xe3\x66\x32\xb5\x35\x41\x6a\xff\x2d\xd4\xfa\x35\x85\x42\xb4\x27\x49\x17\xcc\xae\x7b\xf1\x13\x6f\x5d\x25\x90\x80\x6b\xef\x41\x35\xe9\x61\x25\x49\xe4\x0b\x84\xeb\x1b\x2a\x20\xe0\x19\x27\x38\x42\x6a\x51\x31\x81\xa8\x18\x77\xd4\x27\x49\xf8\x6a\xc8\x09\x0c\x1f\xa9\x62\x66\x11\xf6\xe5\x1b\xe4\x87\xbe\x63\xea\x41\x15\x89\x69\xac\x30\x6f\x8f\x4f\x92\x81\x5f\x57\x94\x8c\x21\x5c\xfc\x31\x94\x94\xf5\xc6\x58\x55\x93\x8c\x79\x55\x49\x32\xaf\xa2\x53\x93\x4c\xaf\x49\xe6\x94\xfc\x41\xa2\x18\xc0\x9c\x36\xd7\x8e\xb2\x7f\x0a\xbe\xfe\x29\xe3\xda\xa1\x57\xeb\xa4\x92\x71\x15\xd6\xa4\xd8\xd7\x74\x90\x55\x5b\x92\xaf\x06\x55\xe8\xeb\x59\x76\x47\x0a\xd5\xba\xe5\xa3\xa0\x41\xfa\x24\xb9\x75\x38\x86\x73\x1f\xab\x24\xb9\x3f\xb7\x40\x11\x7f\x6d\xa4\x4d\xb6\x27\x6d\x92\x2f\x2d\x1e\x78\xf0\x96\x36\xd9\x4f\x4d\x9b\x9c\x69\x93\x42\x85\xde\xa0\x6f\x0d\x15\x4b\x49\x9b\xd4\xcd\x3d\x6d\xd2\xa4\x09\x92\xa6\x68\xc9\x9f\x16\x54\x0a\xea\xf6\x06\xa1\xa2\xfa\x00\x83\x61\x19\xf4\xa3\x33\x6d\x32\x67\xd1\xb4\xa9\xe4\x0b\xb4\x81\xac\xf9\xa4\x4d\xb3\x60\xe3\x6e\x9a\x31\xdc\x4d\xf5\x48\x9b\x1e\x1e\x78\x3e\xc1\x52\x2f\xf9\xe2\xe5\xb2\xb6\xa7\x4d\x0b\xf7\xf7\xa6\x50\xf7\x4d\xcb\x4c\x9b\x36\xf2\x6c\x7a\x18\xde\x06\xc8\x0c\x01\xef\x09\x75\xdf\x74\xde\xaa\xe0\xf4\x38\x58\x58\x7e\x32\xc6\x62\x78\xfe\xe0\x81\xb9\xaf\xc6\x6d\x16\x78\x89\x79\xa5\xcd\xde\xe6\x05\x6b\xb7\x15\xd9\x15\xb4\x92\x36\x4e\xaa\x08\x3a\x2b\x2a\x28\x87\x81\xd8\x0a\x79\x15\x77\xd2\x31\xbc\x22\xe5\x04\xcb\x22\x01\xc3\x35\xae\xb4\x39\x16\x64\x73\x99\x69\xf3\xfd\x49\x9b\x5b\x49\x9b\xd7\x2d\x6d\xd8\xbc\x9b\xb7\x35\xd2\xe6\xfe\x01\x41\x37\x1e\x3b\x46\xe3\x81\xbd\xba\x39\xf5\x75\x83\x39\xdb\x7c\x42\xc9\xb6\x77\xcb\x6d\xfe\x9b\x36\x7f\xd2\x16\x92\x39\xc8\xe0\xc2\x84\x60\x60\x21\xa8\x1f\x14\x28\xcc\x02\xa8\xfe\xe1\xc5\x30\xc7\x30\x6a\x41\x18\x16\x21\xec\xbc\xd0\x9c\xdd\x85\x0d\x94\x7b\xce\x5e\x0c\x0f\x1f\x08\x34\xbc\xb1\xb1\xa3\xfb\x78\xf7\xf8\x16\x7e\xa3\x88\x73\x5c\x1b\x6c\xfc\xb6\x76\x4c\x70\xed\x27\xc6\xb3\x8e\x43\x8a\xa7\x6d\x59\xd9\xd3\xb6\xca\x06\xf2\x01\x29\x2c\x6e\x3b\x9b\xb4\x0f\x98\xad\xd8\xd1\xd1\x8a\xf3\x7d\x83\x20\x20\x97\x35\xac\x51\xe0\x6b\x80\xf3\xbb\x50\xeb\x21\xfd\xfb\x4b\x59\xb6\x0d\x9b\x24\xcb\x66\x0d\xb4\xe0\x39\xcf\x35\x52\x7e\xf3\x3f\x20\xa5\x80\xd4\x94\xa5\x6a\x08\x92\x9e\xb2\xa0\x41\x13\x14\xb5\xac\x4c\xf6\x07\xb4\x39\x4b\x1c\x2d\xdb\x57\xc0\xaa\x3d\xcc\xeb\xff\x3a\xe8\x36\xd9\xae\x4f\x61\xb7\x81\xdf\xc6\x2a\xb1\x83\x9c\x0e\xda\x75\x22\x09\x70\x0d\x3c\x0e\x34\x1e\x17\x88\x35\x54\x19\x93\xfc\xc6\x22\x3b\x54\x99\x52\xfc\x44\x9a\x51\x6d\xea\xe9\x6c\x3e\xdf\x8a\x0b\x4b\xf5\x6e\xa4\x2c\x8b\xc6\x24\x63\x91\xb3\x5a\xc1\xfa\x65\x2d\x8a\xfa\x5a\x61\xbd\xb3\xb6\x01\x49\x68\x9b\x8b\xb9\xa1\xe8\x47\xe3\x1d\xf6\x05\x3f\x94\x2f\x29\x1f\xd0\xda\xc9\xed\xa2\xcd\xcc\x97\xf8\x00\xed\x10\x78\xbe\x24\xde\xcc\x41\x3a\x53\xbe\x54\x3a\x68\x46\x5b\x55\xe6\xeb\x01\xc2\xe9\x5e\xd8\x9d\xf9\xb2\x0c\xf5\x81\xab\x46\x11\xf4\x20\x5f\x56\x9b\xa2\x86\xc3\x8d\xe6\xcb\x9d\x6d\xc3\x9b\xe5\x94\xaf\x95\xe1\x57\xf2\xb5\x1a\x18\xaf\x68\x29\xdb\x09\xf9\x5a\x6b\xf0\x5b\x29\x5b\x60\x53\x67\x9b\xf6\x07\xde\x00\x18\xd9\xbe\x56\x52\x2e\xf0\xad\xb9\x60\x60\x45\xc2\x8e\x07\xe9\x0d\x82\x27\xd8\xa2\x5c\x34\x3e\xa0\x5f\xcc\xaa\x60\x2f\xe4\x42\x47\x97\x8b\x1d\x07\x68\xdd\x40\x39\x98\x62\xe0\xe4\xac\x84\x35\x29\x1c\x6a\xf1\x79\x81\xae\x1d\xf4\x06\xd3\x85\x36\x0b\x3a\x55\xd6\xa0\xc0\xca\xe2\xfa\xb9\xbc\x14\xc2\xf0\xec\x6d\x21\xdd\x35\x65\x3f\x0e\x45\x82\x61\x3b\xd6\xc2\x4b\x81\xc3\xc9\x0e\x53\x9d\xbd\xc0\x03\x64\xaf\x9b\x35\x54\xab\x24\x07\xf0\x42\xf6\x8a\xb1\x79\xa5\x30\xbc\x76\x38\xd3\xec\x0d\xab\x8a\x74\x5f\x64\xd3\x0e\x8b\x8a\xf4\x24\xa0\xc9\xde\xda\xcb\xbf\x0d\x83\x79\xc9\xde\x66\x38\x7a\x6f\x5f\x83\x39\xc9\xb0\x40\xd9\x99\xd5\x3b\x6b\x74\x30\x0e\x68\x0c\xac\x74\x76\x2c\x86\x47\xbc\x7c\x38\xa5\x39\x39\x88\xc5\x59\xae\x36\xb1\xf4\xbe\xe0\xc3\xb3\xaf\x18\x4c\x06\xa7\x47\x81\xfb\xe3\x53\x53\x86\xc1\x02\xc5\xfe\xcf\x21\xc7\x04\xad\x20\x8d\x19\xd8\x20\x21\x94\x63\xc8\x5d\x40\xff\x9e\x94\x43\x59\x49\xe1\x3b\x73\xa8\x82\x87\xde\x29\xc3\xa4\x61\xa3\x85\x41\x4c\x61\xa3\x83\x02\x2e\xe4\x70\x3c\xc3\x76\xe6\x78\x47\x19\x7e\xef\x29\xc7\xca\x86\x79\xc5\x52\x52\xc3\x50\x63\x55\xee\xee\x58\x8d\x35\x17\xc7\x81\x8e\x9f\xc1\xed\xbe\x36\x4d\x79\x95\xb9\x20\x8d\xd5\xf1\x7b\x8d\x7b\x5e\x61\x8e\x8d\xb6\x22\xa8\x4c\xeb\xdf\x0e\x5b\x81\xbd\xb9\xc6\xc5\xad\xb5\x06\xcc\x77\x5e\x90\x01\x3d\xd3\x2e\x7b\xda\xa5\xc2\x50\xed\x30\x49\x3b\x1d\xf2\xfe\x82\xae\x5d\x68\x91\x77\x88\x63\xe7\xc6\x67\xe6\xdd\xd2\x2e\x4f\xda\xb1\x93\x77\xdd\x64\x2a\x92\xb0\x91\x76\xcd\x70\x5d\xbb\x66\xad\x1b\xea\x2a\xa0\x33\x92\x02\x2d\xda\x15\x8b\xc9\xea\x10\xe5\xc0\x03\x6b\x1d\xda\xf8\x72\xbc\xb5\x0e\x30\x27\x60\xdd\xb5\xb0\xa7\x62\x5f\x56\xac\x70\x2d\xbb\x56\x63\xf5\x66\x1c\x41\x23\x76\xda\xb5\xa1\x26\x31\xdd\xae\x5d\x59\xb1\xfb\x30\xbe\xce\x0b\x14\x28\x60\x57\x82\xb0\x5d\x47\x0e\xdb\xf8\xa0\x6c\x32\xec\x6c\x48\x3e\x20\x1d\x86\x69\xd7\x31\xc3\xd1\x64\x8a\xa1\xa7\x09\xc5\xdb\xf5\xab\xc5\x3b\x52\xd8\x8f\x5d\xbf\x50\xa9\xdd\xe4\x84\x0a\xed\x1c\x93\xc1\x50\xec\x48\xe3\x49\x3b\xab\x99\x0e\x45\x89\xce\xb4\xdb\x71\x60\x3a\x76\xd2\x88\xef\x76\x36\xd8\x90\xdd\x8a\xd6\x2a\x69\x37\x62\x9e\xdd\x9a\x0f\x59\x78\xa0\xc2\xef\x86\x61\xda\x78\xa1\xfc\x6e\xe3\x55\xe9\xdd\xc6\x2b\x4a\xc3\x2a\xd9\xa8\x36\x06\xd2\xd7\x87\xef\x36\x3a\x45\x68\x63\xbe\x4b\x0b\x49\x82\xcf\x97\x2b\x63\x5f\x0f\xe6\xfe\xfd\x3d\x69\x77\x86\x28\xbb\xe7\x45\xe3\xbd\xfb\x99\x76\x2f\x05\xa4\x5f\xd6\xd2\xee\x55\x98\x34\xae\xa2\xb7\x8f\xa2\x55\x63\x23\x12\x0c\xc4\x17\x94\x78\x07\x7e\xde\xb9\xb7\xf6\x90\xd3\x1b\x12\xcc\x2e\x84\x81\xd2\x1e\x72\xa7\x9d\x3b\xea\x8d\x78\xf6\x30\xd6\x35\x74\x18\xd6\x3e\xa0\x1d\x84\x8c\x20\xf1\x58\xa8\xfc\xa4\x7d\xe5\x4f\xda\x57\xdd\xd2\xbe\xa0\x31\xeb\xd5\x53\x60\xd9\x9d\x66\x6f\xe7\x4a\xdf\x12\x47\xda\x9f\x26\xb0\x57\x2a\x50\x69\x15\xc4\x11\x2a\x51\x1e\xd0\x06\x32\xaf\xa4\x32\x8c\x39\x63\x82\x3c\x49\xf3\xe5\x49\xf3\x0b\xd4\x34\x7b\xf3\xfa\x24\x05\x64\xe1\xe6\xd7\x7d\xc1\x33\x26\x3d\x68\x11\xf5\x3c\x93\x12\xc3\xa8\x11\x99\x68\xd9\xfc\x4e\x5a\x76\x3e\x6b\x9e\x81\x11\x14\x3d\xa5\x4d\xa4\x14\xaf\x16\xed\xd7\xbf\x8c\xaf\x40\xf2\x5a\x0c\x4c\xcb\xd0\xa4\x75\x93\xf8\x20\x01\x62\xd3\x0a\x8c\x85\x5c\x85\x1b\xd4\xea\x74\xbc\x5a\x7b\x71\x94\x76\x47\xb0\xa3\xb5\xcf\x27\x69\x23\x44\xd0\x06\xbc\x8f\x6d\xa0\x80\x39\x63\x20\x75\x58\x44\x6d\x8a\xc9\x34\x0d\xcc\xad\x1d\xd4\x00\x6d\x27\x8c\x80\xb6\x13\x7b\x50\xdb\x45\x6d\xd1\xf6\x03\xfe\xad\x60\x87\x69\xf3\x75\x5e\x49\x5b\x58\x66\x02\xd5\x80\x7f\x0f\x54\x84\x6d\xc0\x56\x7c\x5f\x02\xad\xb8\x4f\x34\x69\xb7\x01\x97\xa3\xff\x01\x63\xe8\x7f\xcb\x7a\x02\x06\xd2\x80\xde\x6a\xb0\x2c\x7c\x70\x46\x11\x90\x43\xac\x3e\x93\x8e\x2c\x68\x3e\x86\x3c\xa0\xca\x11\x8d\x49\xc1\x4f\x0d\x00\x27\x9d\x97\xe5\x91\x14\xda\xcc\x62\xb8\x61\xfd\xfa\x07\x8f\x5e\xbe\x9a\xf4\x97\x72\xf8\x95\x0a\xa7\xa0\xbf\x8c\xe9\xf5\xf7\x1f\xca\xd0\xdf\x4c\x91\xff\xe6\x82\x30\x49\x7f\x19\xda\xeb\xaf\xd2\x46\xea\xaf\x46\x36\x66\x5c\x02\xed\xd2\xdf\xcb\x36\xac\xff\xaf\x91\x19\xc5\xf2\xcb\x0c\x87\x52\xeb\x6f\x87\x85\xd2\x5f\xc6\x6e\xfa\xdb\x29\x8e\xdf\x5e\xb0\x6d\xf4\xb7\x3b\x79\xf5\x78\xc7\xc0\x10\x4d\x7f\x27\x64\xf1\x28\x7e\x40\xb4\xe9\x10\x60\xe4\x74\x60\xc1\x0f\x81\xb9\x7f\xd2\x01\xbb\x7a\x88\xb5\x09\x3a\xaf\x74\x00\x51\x1e\x02\x55\x39\x10\x28\x1c\x52\xa1\xc1\x07\x62\xea\x91\x0e\x69\xf8\x65\x64\xb4\x09\x85\x3e\x10\xa7\x1e\xf2\xfa\x81\x43\xc0\x06\xb6\xe7\x10\xea\xeb\x21\xd3\x10\xcc\x1e\x8c\x35\x0f\xf9\x7a\x40\x2c\x87\x0a\x5d\xcd\xa1\x5b\x2c\x98\xb2\x43\x77\x85\x3b\x06\x74\x38\x54\x77\x10\xbc\x55\x29\xc8\xc0\x0a\x1c\x3a\xa6\x7d\x59\x07\x3b\xf1\x20\xd0\x39\xf4\x4e\x87\xc1\x25\x1c\xf6\x06\xa0\x87\x69\xd9\xd3\x61\x27\xf9\x43\x9a\x87\x95\x0a\x32\x59\x0b\x8b\x7b\x20\xc2\xa1\x4f\x38\x8c\x0e\xe9\xb0\x06\x2b\x77\x18\xdb\x60\x42\x06\x98\x7e\xd8\xc8\xac\xce\x32\xbc\x4f\x22\xf6\xc3\x7e\xd3\x51\xe4\x04\x81\x88\x0a\x1c\xd9\x51\x30\xf9\x82\x29\xa6\xa3\x60\x1e\x85\x3b\xf7\x00\xd6\x3a\x8a\xb3\x14\x88\xeb\x28\xce\x2a\xdc\x5a\x47\x59\xb6\x83\x92\xc3\x93\x0e\x97\x9a\x0e\xcf\x90\xb5\x9f\xe9\x00\x8c\x3a\x1c\x33\x72\x9e\x8e\x1c\x08\xcb\x0e\xf7\x99\xde\xed\x85\x28\x73\xf0\x05\x81\xc9\x81\x20\x1f\x96\x03\xd6\xeb\x70\x98\xb5\xc3\x83\x61\xf3\xe1\x63\x90\x17\x51\xdc\xc1\x63\x84\xc3\x7f\xd3\x11\x72\x52\x4a\xc1\xa9\x84\xfe\xb7\x60\x43\x8e\x50\x8c\x28\x0c\xaa\x74\xc0\x0c\xa2\x10\x23\x0a\x67\x31\x50\xd2\xc1\x38\xe9\x08\x07\x5c\x3d\x62\x41\x44\x80\x1d\xc7\x6a\xf8\xb5\x27\x1d\x2b\x1a\xd5\x0d\x20\xfd\x58\x5c\xf4\x53\x18\x44\x31\xd8\x3e\xa5\xc8\xef\x83\x84\xe0\xfe\xc4\x18\x4e\xe9\xe9\x14\x1e\x10\x9c\x12\xdb\xbf\x14\x31\xd4\x29\x51\x2c\x23\xa1\x9d\x3b\x65\xe0\x87\xda\x13\x75\xa8\x71\xa7\x2c\x36\xf8\xd3\x74\xc2\x14\x49\x41\x6a\x6b\x20\x09\x66\x22\xde\x38\xb5\x2d\x28\xc0\xa9\xe3\x1d\xd4\x85\x09\x9d\x06\xb3\x79\xc2\x5f\x9c\x76\xc2\xa2\x9f\xaf\x82\x9c\x16\x72\x1c\x78\x8d\x92\x4e\x38\x8e\xb3\xc8\x0e\x02\xd5\x3c\x8b\x04\xe9\x18\xe9\x2c\xf0\x7f\x67\xb1\xda\x07\x52\xdf\x48\xbd\x82\x62\x8a\xc5\xd9\xda\xef\x74\x22\x9c\x3e\xa1\x18\xa7\xef\x3b\x14\xeb\xc4\x4a\x9f\x58\xe2\x93\xc1\xc3\xe9\xf0\x5a\x92\x4e\x1f\x5d\x0b\x92\x61\x3d\x9d\xf0\xcf\x2d\x9d\x10\xfe\x19\xb2\x81\x60\x14\x8c\x92\xcf\xe0\x14\x02\x16\xee\x64\xac\x7c\x86\x7c\x01\x03\xce\x50\x74\x15\x0a\x49\x86\xed\x20\x7a\x80\x22\xd7\x33\x17\x20\x7c\x75\xd0\x3b\x9d\xb1\xc0\x68\x41\x79\xce\xc5\xd1\x2d\x4e\x6d\x59\x41\xbe\x4d\x89\x74\xae\x96\xce\xa7\xa6\x4b\x60\xbd\x18\x75\x5d\x52\x8e\x74\x49\xad\x8a\xe7\x4a\x75\xbb\x60\xbc\x2e\xe9\xfd\x49\x17\xa2\x49\xe4\x04\x72\x62\x5c\xa0\x5f\xe8\x30\x82\x2f\x9e\x93\x5c\x72\x7f\xd2\x25\x7f\xac\x82\x08\xff\x52\x29\xf3\x42\x12\x13\xf4\xfb\xa4\x0b\x3e\xf3\xf2\x33\x5d\xaf\x7f\xbc\xb4\x14\x07\xad\xca\x97\x9e\x2e\x6d\xe9\xd2\xf0\x74\xd9\x0e\xe5\xb9\xec\xbc\xd2\x05\x10\x70\xc1\xda\x5d\xd6\xd3\x85\xfd\x7e\xd9\x98\x58\x98\xcb\xb7\x0d\x34\x03\x7b\x5c\x58\x88\xcb\x8b\x82\x18\x50\xe9\xf5\xee\xbf\x0b\x01\xcb\xe5\x8d\x75\x1c\x75\x3a\xde\xa3\x81\xc0\xc5\x5c\x74\x85\x97\x8f\x37\x90\xa6\x5a\x5d\x3e\x15\x8f\x0b\xc5\x30\x5b\xd7\xda\xd2\x05\x3d\xbd\x56\x95\x06\x0a\xcf\x7a\xad\x0a\x06\xab\xed\xa1\x3b\xd2\x13\xc3\xc2\x2a\x5c\x2b\x76\x56\x08\xe6\x40\x0a\x6b\x6c\x14\xea\xb3\x61\x29\x81\x04\x2d\x7b\x4b\xb6\xab\x24\x1e\x2b\x23\x48\x34\xb4\xb2\xb3\x21\xc8\xc1\xcc\xad\x00\x2a\x30\xa5\x21\x33\x02\x74\xab\x46\xdf\x67\xb5\x12\x2f\x5b\xad\xb0\x1f\x56\x3b\x3c\x9c\x55\x7a\x17\xab\xef\xc9\xa5\xd5\xbe\xe0\x1c\x0c\x91\x84\xb5\xd7\xbd\x59\x63\x20\x67\xed\x1f\xfc\xb6\xb6\xeb\x2f\xa8\x11\xcd\x58\x23\x8a\xb3\x06\x24\x15\x4f\xb2\x06\xef\x81\xa4\x58\x66\xea\x51\x93\xb5\x0b\xd6\xde\xda\xa5\x50\x49\x6b\x36\x81\x79\xad\xfd\x28\x2b\xfd\x2c\x36\xad\x2f\x47\x20\x59\x6b\xcd\xb3\x92\x53\x5f\xa0\xff\x2d\x63\x9d\x81\x70\xcb\xda\x78\x1b\x22\x2c\x44\x42\xa7\x69\x0d\x11\x0f\xd8\x4e\xce\x0e\xf8\x02\xda\x67\x6d\x7a\xb2\xf6\x7d\x9f\xbf\xc6\x4e\x5e\x4f\x6f\x01\xc1\x8e\x02\x79\xdb\xf0\xc2\x01\x8c\xb1\x34\xd9\xd4\x9a\x00\x75\x9f\xf4\xf3\x1e\x55\xfd\x08\x76\x4c\xfa\xe1\xef\xef\x2f\xfd\xa8\x14\x38\xce\x1f\x95\x06\x5a\xca\x93\x7e\xf4\xd6\x92\x7e\x7c\x4b\x3f\x08\x90\x7f\x00\x2a\x7e\x7c\x05\x94\x0a\xb0\xe8\x67\x01\x0f\xfe\x2c\x2c\xea\x0f\x62\xef\x9f\xc5\x53\xea\x9f\xd5\xcc\x03\xc9\x27\xf1\x10\xff\x23\xed\x94\x70\x4f\x1f\xec\xe9\x8f\x6a\x4f\x1f\x38\xc7\x85\xf4\x49\x1f\xcb\x9f\xf4\xb1\x1d\xbf\xc6\xf7\x86\xe7\x76\xee\x5e\xd3\x07\x70\xfe\x63\x13\xbf\x8c\xbd\xf2\xc1\x94\x3f\x36\x27\x9f\x6f\x4b\x9f\xa6\x9a\x3e\xcd\x0e\x50\x38\xae\x4f\xf3\x3b\x15\xd9\xf0\xd3\x02\xea\x91\x8a\xec\x00\xa3\x45\xf6\x27\x15\xf9\x68\x2a\x08\xf7\x8a\xb4\x73\x41\xb7\x8a\xf4\xe9\x78\x0f\xbe\x4c\x56\x9d\xd6\x52\x41\xdc\x07\xda\x00\xbc\x8b\x7c\x25\x15\x01\xfb\x1b\x65\xf7\x80\x33\x29\xf2\xb0\xfe\xdf\x93\x8a\x0a\xbb\x51\x39\x40\xa2\x81\x7e\x35\x01\x03\xc3\x7e\x17\x3d\x66\x2a\x7a\xa6\x57\xc1\x8b\x9e\x70\x5c\x45\x6d\xbc\xa5\xd5\xd1\x82\x59\xed\x9c\x17\x92\x91\x8a\x7a\x87\x91\x01\x8a\x65\x39\xcf\xe0\x0a\xe2\xb0\x54\x4c\x22\x15\x40\x8b\xf9\x20\x0d\xc0\x94\x62\x99\x3b\xa4\x40\x28\x05\x6e\xe2\xf5\xf1\xc5\x30\x71\xab\x1b\x08\x06\x8e\x28\xa3\x00\x8e\x14\xfb\x0f\x0e\x9e\x38\xb7\x18\x8f\xba\x10\x73\xa6\x62\x34\x6f\xc5\x85\xa4\xa5\xe2\x1b\x4d\x65\x71\x40\x0e\x02\x85\xe2\xa7\xe5\x54\xbc\x69\x79\x90\x9c\xa9\x38\x64\xe9\x18\x26\x72\x16\xda\x2e\xb8\x66\x3a\x95\xe2\x0f\x9a\xae\xfc\x79\x52\x59\x27\x71\x77\x59\x0c\x98\xcb\x6a\x42\x9a\xaf\x54\xd6\x2f\x76\x52\x79\x02\x08\xb7\x4a\xbe\xe0\x08\xab\xec\xa9\x0a\x3a\xac\x72\x36\x9d\xa9\x8a\x21\xc7\x4a\x62\x6c\x56\xe5\xc7\x23\x55\xac\x70\x95\x5a\x05\xd9\xc8\x6d\xe8\x05\xe1\x33\x76\x45\x95\x76\x3a\x28\x31\x77\x15\x7e\x39\xa9\x02\x80\x5c\x25\xb6\x37\xc9\x17\xe8\x49\x9e\xf1\x76\x1d\x1f\x76\x18\x61\x2f\xb7\xf1\x01\xc1\xe0\x28\x93\xca\x23\x43\x6c\xfc\x30\x32\x9c\x7c\x0b\xfb\x45\xf2\xd6\xf8\xb5\xba\x6a\xaa\xf0\xfb\x55\x65\xf7\x1b\x49\x03\xa1\x06\x54\xf8\xbe\xaa\x40\xe7\x98\xa2\xee\xe0\xa3\xbb\x49\xaa\x5a\x10\x09\x55\x2d\xa8\x40\x69\x55\xad\xd8\xd2\x00\x19\x9c\x87\xb6\x95\xaa\x46\x46\x16\xf4\xb8\xd2\x40\x55\x9e\x07\x56\xe0\xa4\x8a\x58\x82\x05\x93\x7c\xe7\xe5\x7b\xaa\xb6\xc3\xfc\x56\xdb\x1b\x95\xa4\x5a\xf9\x80\x50\x2f\xaa\x21\x76\xac\xd8\x91\xd5\xda\x3b\x76\x43\xbc\x5b\xad\x21\x42\xa8\x16\x92\xd9\x9a\x5e\xa5\xda\xc0\x92\x33\x06\xaf\x08\xb9\xb1\x0c\x98\xbe\xfd\x2a\x38\xfc\x72\x13\x54\xdf\x00\xe5\xaa\xef\x5a\x40\xe1\x02\xaa\x57\xfc\x60\x25\xab\x37\x43\x34\x58\xdf\xf8\xba\x7a\x7b\xa5\xeb\x0d\xf2\x74\x8c\x8a\x67\x62\xd5\xc9\x2b\x1a\x82\xdf\xea\xe3\xbf\x65\xd3\x53\x7d\xcf\xc6\xff\x45\x88\xd5\x5f\x4e\xab\xf1\x38\xa8\xf2\xfb\x40\x85\x16\x56\xff\x9a\xa6\xba\xb0\x62\xeb\x38\x50\xb8\x30\xa8\x55\xa6\xf5\xf2\xa4\xba\x06\x27\xb6\x86\x62\xd2\x6b\x5c\x3c\x7b\xaf\x6b\x40\x20\x30\x6b\x75\xf1\x13\x66\x7d\x86\x96\x03\x09\xd5\xbd\x3e\xf3\x4a\x4d\xb0\x79\x1a\x60\x62\x93\xfe\xb1\x96\xda\xfb\xd5\xab\xc9\x98\x4f\x6a\xc2\xc1\xb5\x37\xba\x68\x2a\x91\x9a\xe6\x4f\x6a\x08\x29\x9a\x9e\x32\xd9\x5c\x4f\x9e\x48\xb6\x7f\x41\x75\xd3\x7e\xe9\x9d\x9a\x06\x0b\x07\x4a\xf8\xe3\x37\xb3\xa6\x6b\x42\x2a\x8d\x01\x47\xd3\x7b\xa4\xa6\xbf\x33\x35\x98\xe7\x77\x65\x9b\x43\xb5\x9b\x23\xa2\x6b\x5e\x0d\x86\xb3\xb9\xef\xcc\x0c\xec\x95\xe6\x81\xd1\x3b\x2b\x4c\x79\xab\x4f\x92\x0b\x52\x6e\x88\xf2\xf0\x0a\xd3\x03\x33\xdb\x56\x2e\x1c\xfe\xbb\x7f\x1b\x8f\x1c\xdb\x9a\xc9\xe5\x93\x7c\xd3\x27\xf9\x46\xbf\xe8\x5b\xb1\x53\x93\x6f\x23\x63\xce\xbe\x0d\x4e\xc3\x37\xae\x8b\x6f\x5f\x1e\xdf\x79\xce\x2b\x92\x67\x6c\x09\xcf\xd3\xc1\xd3\x77\x8f\xe4\xc7\x81\x9f\xf2\x09\x43\xf0\x03\x0e\x00\x61\x87\x7f\xe4\x49\xc0\x41\x4e\x8b\xe5\xe5\xa9\xdd\x72\x72\x18\x38\x07\xec\xf5\x86\x1f\x04\xee\x8d\xe7\x70\xde\xca\x93\xbc\xa3\x7d\x47\x20\xee\xdd\xde\xe2\x4e\x08\xe1\x9d\xab\xe3\xef\xb7\x4b\x0f\x40\x46\x8f\x4c\x28\xf8\x9e\x2a\x79\xec\xd6\x60\x68\x3d\x4e\x8c\x34\x78\x80\xed\x61\x27\xe3\x36\x8f\x7e\x21\x7b\x4c\x9e\x14\xbc\x0a\xe9\x6b\x12\x5d\xf8\x9a\xef\x1b\xa0\x80\xaf\x49\xaf\xef\x08\x18\xfd\x8b\x11\x61\xf5\x80\x98\xfd\x06\x74\xf0\xdf\xe7\x44\x2e\x95\x2b\xf9\x1f\xe6\x42\xb8\xd3\x85\xbb\xb6\x63\x3b\xf3\xb0\xae\x4b\x01\xba\xee\x52\x6a\x42\x10\x2e\xa0\x5a\x40\x2d\x83\x72\x14\x5d\x3a\x69\x20\x9e\xee\xc2\xb3\xd2\x2e\xf1\x01\x09\xe7\xf3\x7c\x52\x87\x51\xeb\xb4\x66\x1d\x46\xac\xcb\xb4\xb7\x26\x4f\xac\x3b\x8d\x59\x4b\x9d\x5f\x41\x3a\xfc\x5b\x97\x87\x7b\xb7\x2b\x07\xa1\x02\x1d\xe0\x07\xe5\xae\x32\x84\x25\xc5\xb2\xb4\x04\xb1\x77\x6d\x82\xa8\xbe\x6b\xcb\x56\x52\x57\x87\xe9\xed\xca\x53\xef\xae\x71\x40\x63\xba\x06\x96\xb0\x6b\xc0\xe9\x75\x9d\xa9\x5f\x9c\xfe\xe5\xd3\x53\xbf\x78\x7a\xd2\xaf\x67\x18\x3c\x51\x37\x69\x9e\xba\x65\xce\xd6\x5e\x6f\xdb\x4d\x31\x1a\x3b\xf1\x53\x70\x01\xba\xec\x56\x30\x53\xf8\xbe\x6e\xde\x14\x7d\x5a\x47\xbd\x31\x31\x3b\xe3\xbc\xed\xef\x4f\x52\x7f\x65\x5a\x04\x3b\xad\x97\xf7\xe4\xae\x13\x59\xf1\x58\xb1\x17\xe2\xc8\x5e\x78\x34\xd6\xe1\xd3\x40\x4f\x10\x28\x4f\x77\xad\x20\x33\x75\x07\x9a\xef\x5e\x20\x12\x00\xf6\xee\xf0\xd2\xa9\x7b\xdb\x41\x9e\xd4\x1d\x9d\x7b\x5f\x6f\x95\xa0\x12\xf2\x00\xf7\xdf\xc3\xb0\x8d\xed\x06\xf8\x4c\x81\x10\xfe\xb9\xd8\x0e\xad\x81\x3c\xfd\x86\x7a\xbe\xa7\x61\x3d\x24\x73\xb7\xf6\x10\xec\xf8\x1e\xca\x1b\x16\x3d\xf4\x60\xb1\x62\xfd\x91\xf2\x2a\x48\x0f\x9d\x60\x11\xfa\x7d\x5f\xdf\xa6\xd0\xce\x1e\x56\xa1\xed\x3d\xec\x2d\xf1\x30\x56\x35\xae\x4c\xd8\x97\x02\x09\xfb\x03\x85\x91\xa9\x48\x79\xd2\xd4\xc3\xf7\x45\x4e\x7e\x60\x35\xc3\x79\x4c\xdc\xc3\x69\x16\x7a\x78\x75\x36\x76\x3f\x40\xfb\x3b\x91\x40\x24\x89\x41\xfa\xfc\x57\x6d\xed\xa0\x3c\xb5\xed\x6b\x43\x7c\xdd\xd7\xbe\xc3\x28\xf5\x85\x45\x5d\xa5\xa7\x17\xf2\xf7\x55\x69\x72\x3b\x61\x44\x5f\x1d\x2a\xb6\x10\xd4\xf5\x15\xef\x17\xb4\xbe\xde\x19\xac\xe0\x8e\xef\x34\x5b\x7d\x0d\x54\x9f\xa9\xaf\xbf\x3f\x48\xfa\x09\xa9\xb6\xa7\xff\x96\xf0\x12\xcd\x7f\x4b\xda\x5c\x15\x69\x60\x37\xfe\xb7\x74\x70\x6d\xfe\x5b\x40\xb0\x70\x3f\x20\x7f\xe9\xbf\x85\x29\x85\x6c\xb0\x1c\x21\x39\xc3\x67\x31\xf6\xe5\x77\x97\x90\x5d\x02\xd4\x3c\x05\x80\x0b\x03\xe2\x77\x91\x42\x80\xbc\x03\xd8\x34\x04\xc3\x0f\x69\x80\xc1\xaf\x2d\x0a\xe9\xb6\xa7\xc0\xb2\xf1\x3b\x42\xbc\x67\x09\x21\xb0\x1c\x21\x77\x0a\xf9\xf3\x48\xef\x2d\x14\x7e\x69\x44\x9c\x83\xce\x15\x48\x38\xf4\xfd\x12\x1c\xca\xef\xb1\xa1\x59\x61\x31\x43\x33\xd4\x3f\x34\x7b\xb0\x90\x5f\x46\x42\xb9\x6e\xa1\x07\x9d\x50\x28\x83\x9f\xd0\x03\x7b\x3e\xf4\x34\xb2\x3d\x43\x51\x76\x52\x69\x43\x7f\xde\xaa\x45\x7e\x41\xb9\x37\x42\x0b\xc2\x77\xde\x5d\x08\x25\x46\x0b\xfd\x07\x60\x42\x89\x2c\x42\xe9\x91\x43\xdb\xce\xcc\xa6\x77\xa2\x65\x0a\xa5\x95\x86\xa6\x1a\x0a\x3a\xd0\x51\xe8\xbb\x2b\x43\x79\x7b\x27\xf4\xbd\x70\x14\x3a\xf2\x62\xa2\x8c\x52\x43\x79\x55\x24\x74\xf8\x0a\x56\x1f\xdd\x1b\x07\x34\x56\x41\xc1\x7c\x9b\xcd\x78\xb9\xce\x15\xe8\x6a\xb5\x77\x66\xdf\x57\x7c\x5f\xe3\x60\x78\x36\x15\xd7\x33\xaf\x9a\xc2\x36\xfc\x36\x54\xc3\x26\xa1\x91\xe7\x46\x79\x3f\xea\x87\x1d\xe8\x9f\x2e\x17\x2e\x61\x4f\x3c\x9e\x0f\x73\xbc\xf3\x7e\x0d\xbf\xf1\x87\x11\x3f\x04\x4f\x0b\x83\x5f\x78\x02\x38\x3b\xf8\xb5\x32\x7c\x73\xd2\xc5\x17\x46\x6d\xe1\x95\x07\x39\xdc\x2c\xe1\xfe\x31\x3e\xd7\x14\xd0\xe2\x70\x86\xc7\xc1\x53\xea\xf7\x02\x4e\xc0\xdb\xa4\x20\xe0\x8e\xb5\x51\xe6\x08\x84\x63\x9d\x29\x00\x77\x62\x35\xfc\x6e\x79\x52\x2c\xc0\x87\x21\x3b\x7e\xf0\x2d\x43\x76\x46\xdf\x43\x0e\xbc\x18\x0a\x0b\x8b\x0b\xc2\x94\x21\xe5\xa5\x13\x04\xfd\x0c\xe0\x9d\xf1\x1e\x34\x0f\x44\xa1\x43\xa6\x8d\xe3\x41\xea\xe3\xb2\x34\x04\x2a\x35\x64\x11\x85\x0e\x38\x8e\x21\x4f\x1a\x19\x01\xf5\x80\x77\x18\x19\xca\x3d\xf2\x0b\x97\x47\xd6\x86\xb7\x4b\x2b\x13\x58\xc8\x91\x8d\xe7\xac\x23\xdb\x18\x1e\x23\x8d\xec\xc1\x0f\xe7\x23\xfb\x9a\x69\xe4\x90\x0e\x8a\x58\x73\xe4\xb0\xce\xbc\xb5\xa5\xa1\x82\x1f\x80\xfd\x78\xb7\xc5\xc0\xca\x0f\xcd\xb0\xc1\x43\x33\x74\x19\xb1\x38\x99\x69\x7e\x6d\xc4\x00\x26\x1b\xaa\x9f\x34\xf4\xa4\x8f\x1b\xfc\xa2\x81\xa4\xa4\x01\x0d\x96\x48\x43\x19\xf3\x0e\x86\x5d\xb0\xa7\xef\x18\x35\x4c\x07\x12\x7e\x2a\x1b\x3a\xc6\xcb\x9b\x01\xd6\xd0\xb9\x7a\x1a\xb0\xb7\x69\x5c\x8c\x05\xc6\x25\xc7\x04\xe5\x21\xce\xb8\x28\x8c\x0b\x03\xb8\xd8\xdb\xa5\x61\xc7\x91\xc6\xc5\xd3\xe3\x71\x19\x6b\x03\xd3\x8c\xcb\x3a\x08\xb4\x68\x5c\x08\xcb\xc6\xe5\xc8\x76\x47\x15\x47\x21\xb6\xcb\xb8\x7c\xf1\xb3\xcc\xb8\xb0\xe7\xc6\x15\x56\x51\x06\x8d\x18\xd7\x3a\xa0\xba\xe3\x7a\x12\x9c\x0d\xb4\x76\xc0\xb4\x11\xa3\x0c\x53\x2c\x1a\xd5\x9a\xdf\x0a\x87\x15\x8a\x03\xf1\xc2\x30\xd8\xad\x61\x85\xfd\x5b\x35\xd8\x83\x61\xaf\x2a\xf0\xeb\xf6\x78\xb9\x05\x26\x6b\x44\x33\x03\xfa\x0f\xb5\xb1\xdf\x34\xe0\x3b\xc6\x87\xaf\x3c\x1b\x48\xe3\x63\xf8\x61\xd6\x30\xe6\xe3\x63\x18\xfd\x07\xb6\x7e\x20\xb8\x1f\x45\x6a\x1a\x45\xb5\x83\xd2\x72\x0c\x7a\xd4\xc1\x93\xcd\xf1\x46\xbc\xa3\x18\x6a\x39\x60\xda\x80\xdb\x1f\x14\x2c\xcf\xb1\x47\x85\x15\x1c\x55\xc0\xb8\x22\x22\x19\xd5\x3f\xa4\x3e\xaf\x34\x1a\x8c\xf5\x68\x88\x61\x46\x83\x4e\x35\xca\x1e\xb0\x77\x38\xde\x3d\x67\xf4\xea\xfc\x92\x3d\x28\x73\xdf\x25\x0d\xc7\xaa\xd0\xd3\x0f\x2f\xbb\xb1\x4e\xb1\x1d\xf4\xbd\x30\x32\x78\x5e\x33\xbc\x2a\x00\xcd\x40\xc8\x3c\x9c\xf9\x08\xd5\x06\xd7\xc9\x17\x78\x62\x13\x0f\x87\x9a\xbc\x56\x6c\xf8\xc2\xd0\x3a\x0c\xe0\xa0\xff\x1e\x00\x67\xe8\xbf\xcb\xdd\xd2\xe8\x2a\x1f\xd0\x77\x4c\x9d\xca\xdb\xa9\x3b\xfc\x24\x3c\xfa\xa5\x6c\x44\x49\x75\x5e\x44\x18\xdd\x3e\x7c\x41\x73\x43\xc8\x38\x7a\x21\x05\xbc\xa6\xd5\x84\x6a\x77\x8e\x90\x36\x77\x74\x48\xb2\x07\xf6\x6e\xe7\xe5\xa6\xd1\x69\xe3\x46\x7f\xd2\x80\x7f\x54\x24\xbc\xef\x84\xb0\x8c\x37\xd5\xc6\x1b\x4f\x8c\x29\xbb\xad\x8a\x14\xd2\x9c\xb4\x04\x53\x0c\x3b\x79\xc2\xef\x8d\x49\xd3\x31\xb9\x2c\xb4\x68\x63\xa2\xa3\xc9\x99\x4d\x25\x2b\x05\x03\x2c\xfd\xd4\x50\x4f\xc0\x65\x28\xa4\xba\x4c\x8e\x64\x72\x3d\xa6\x57\x81\x32\x4d\x0a\x7a\xd2\x80\xf0\x18\x75\x4c\xaa\xff\x84\x1f\x3d\xf1\x1a\x8a\xdd\x3f\x83\xb2\x98\xc1\x35\x99\xb1\x78\xba\x3e\xe6\xe2\x0d\xd8\x31\x17\xc7\xfc\x9e\x83\x8e\xf9\x80\xae\x37\xc0\x19\x6b\x03\x5c\x1d\x6b\x83\x31\x1d\xeb\xbd\x3c\x3b\x10\x5f\x8e\xc5\x93\xdd\xb1\x18\xc0\x8c\x75\x0a\xe9\x89\x10\x8e\x07\x48\x63\xf1\x18\x7a\x2c\x54\x6a\x0d\xcd\xdb\xc0\x70\x56\x67\x76\x47\x40\x3a\x56\x0f\xda\x41\x20\xdb\xb1\x82\xdf\xc7\xc6\x42\xa0\x3f\x56\x00\x8c\xf1\xe1\x35\xfc\x63\xc5\x57\xd1\xe6\xbd\x45\x39\xd6\x60\x9c\x35\xee\x7f\x96\xe5\xa6\xa4\x6f\x21\x89\x9a\xc6\x0d\xac\x3e\x6e\x0a\xe1\xa6\x59\xb9\xb1\x73\x6e\xca\xf2\x26\x24\x1e\x37\xf0\xc1\x78\xea\x06\x29\x3e\xb5\x4f\xaf\x69\x3c\x01\xed\x7c\xb8\x24\xef\x0a\x4f\xe1\x0d\xa2\x29\x67\xe2\xbd\x81\x29\xb4\x13\x53\xca\x27\x4d\x69\x20\x1d\xc5\xfc\x14\x34\x65\x20\x63\x4c\xe4\xcc\xe9\x9e\xa6\xfc\x5a\x9a\xbc\xbd\x38\x55\x6a\x9a\xd0\x5e\x04\x7b\x53\x1b\x02\x89\xa9\xad\xd9\x40\x82\xe7\x40\x85\x81\xa7\xdf\x99\xe6\x45\xf6\x97\xe0\x11\xb2\x9a\x17\xda\x5d\x8a\x15\x9f\xd4\xfc\x79\x29\x1e\x31\xad\x79\x81\xcd\xe5\xbc\xd1\x35\xaf\x50\x94\xf2\x6b\xfb\xbc\x10\xab\xcf\x6b\xd5\x0d\x94\xc6\x65\xbe\x77\x5c\x26\x8c\xcb\xb4\x93\x39\x05\xef\x44\x32\xd3\xd0\x9b\xb5\x27\x4d\xeb\x09\xc8\x62\x4f\xf3\x3d\x7c\x9d\x06\x63\x3f\xe9\xd4\xa7\x6f\x80\x83\x69\xfa\x2e\x0f\xe8\x5e\xd0\xd8\x51\x7e\x2a\xc1\xdc\x74\x2b\xe8\x87\xd7\xfe\xa0\xbe\x13\xd5\xeb\x7b\x09\x91\x6a\x3c\xbd\x9d\x8b\x09\x4d\x1c\x95\x7a\xd2\x64\x4d\xef\xf8\x59\x06\xed\xec\x15\xde\x6e\x7a\x34\xd9\xc1\x26\x26\x83\xff\xe9\x63\xa4\xe9\x53\xd0\x70\x85\x71\x64\x84\x38\x93\xa1\xc3\x44\x00\x3a\xfd\x49\x93\x80\x75\x32\x5a\x9c\x21\x08\xbd\x91\x9e\x6f\x62\x0d\xb4\x0d\x68\xf5\x84\xd7\x9d\xbc\x39\x34\x81\x47\x4b\xe2\xbd\xd0\x17\x5c\x4d\xca\x16\xf8\x2e\x4d\x1e\x8d\x4d\x5e\x3d\x99\xbc\x0a\x39\xc3\x4e\x8a\x33\xac\x82\x80\x8d\xf7\x0b\x6d\xdf\x9b\x14\x33\x16\xab\x2d\x3e\x16\x14\xac\x8a\x78\x70\x06\xb0\xd1\x0c\x98\xc4\x89\x15\x5e\x60\xba\xde\x80\xe9\xdf\x26\x9d\xab\x09\x08\x42\xe1\xb9\xe2\x83\xd5\x07\xd0\x9b\x2b\xb8\x2c\xb7\xc2\x14\xcf\x5b\xdb\x7c\xd2\xbc\x61\x16\xe7\x8d\x89\xdd\x94\xca\xed\x69\x3e\xd0\xd6\xa7\x33\xcc\x5c\x67\x79\xd2\xaa\x5b\x68\x29\x92\xd6\x7b\xd5\x60\xb5\xf7\x36\xf0\x6a\x99\x6f\xef\xc5\x94\x57\x6d\x56\xdb\x3d\xad\xc6\x2b\xea\xab\xf1\x13\xe9\x6a\xef\x27\xa6\xd5\x8c\x98\x7a\x35\x5e\xcd\x5e\xcd\x26\xc8\x57\x11\x8c\xac\xf6\x69\x58\x85\xd5\x78\xc6\xba\xda\xb4\x92\x56\x5b\xbc\xa7\xb8\xda\x57\xf1\xda\x79\x9a\xb9\xfa\xc9\x05\x5a\x9d\x9f\x83\x56\xf7\x96\x16\x43\xe9\xd5\x61\x45\x56\x6c\xd2\x12\x0d\xc5\x0b\xbc\x80\xe0\x79\xe5\x7c\x0d\x3d\x56\x41\xc2\x0b\x12\xff\x98\xcf\xf7\x3f\x03\x5f\xc9\xd8\x6e\x5f\xc9\x6b\xd5\xf4\x15\xe8\xdc\x57\xe0\xc7\xbe\xef\x3d\xf8\xaf\x40\x74\x5f\x69\xf8\xd9\xb8\xd2\x57\xba\x47\xfa\xca\x7b\x15\xeb\x0b\x85\xff\xf2\x83\xfa\x57\x2f\x83\x68\xbe\x10\x36\x5e\xdb\x8e\x8a\xbc\x14\x89\xdc\x06\xd6\x1a\x1b\x88\x1d\x0f\x12\x02\xa5\x2f\x82\xdb\xaf\x8e\xa1\x25\x7d\x75\x6a\xa0\x2f\xa3\xcc\xbf\xb6\xf1\x0b\xe2\xd7\xf2\xdb\x9b\x65\xda\x75\x04\x88\x9e\x88\xda\xbf\x56\x0a\xa6\xfb\xb5\x36\xdf\xd4\x8b\x81\x41\x10\x77\x7f\x2d\xd8\x6e\x08\x88\x81\xd5\x78\xf3\x27\xe9\x17\x33\xe5\x29\xf7\x97\x17\x25\x79\xf9\xfb\xeb\x25\x4b\x73\xa4\xab\x22\x6f\x82\x3c\x60\x7f\xff\x23\xde\xd2\x2d\x36\xd3\x0d\x7b\x07\x7b\x0b\xd2\x16\x32\x1a\x48\x1c\xd0\x15\x5a\xdd\x5b\x02\xc1\x74\xba\xb1\x6d\x6e\x19\x1d\x64\xa2\x10\xf8\xe8\x06\x3e\x86\x33\xb9\xdf\xef\x8a\xb7\x0a\x96\x96\x96\xfa\x46\x6c\x55\x90\xd0\x68\xdc\xba\xa5\x5b\xdf\x70\xf8\x56\xfd\x60\xa7\xdd\x6a\x01\x5a\xf8\xcd\xeb\x86\x91\xbc\x75\xa6\x9b\x5f\xaf\x6e\xd8\xc8\xfb\xd2\x97\x82\x13\x2c\xe5\x4d\x13\x79\x03\x4a\xde\x97\x31\x02\xbf\x61\xef\x6e\xdb\xd1\xbf\x1d\x78\x2c\x3b\x48\x49\xd8\x25\xb7\x35\xc0\xd6\x1b\x08\x94\xae\xe2\xb6\xf6\x01\x69\x6c\xca\x4b\x31\x37\xc2\xac\xdb\x06\xc2\xd8\x1b\xd6\xe7\x86\xae\xdc\xff\xee\x28\xdc\x5e\x8e\x74\x23\xae\x49\xb7\x73\xc7\xdc\xee\x3b\x48\x49\xf4\x37\x3c\xdc\xbc\x3d\x0a\x1f\xe3\x01\xc5\x60\x60\x6f\xee\xd0\xfc\x01\xe5\x25\xde\x9b\x86\xec\xe6\xcd\x8d\x9b\x0e\xfc\x81\x49\x7b\x20\xaf\x47\xe9\xf7\x1e\x5f\xf8\xa1\x88\x40\xea\x4f\xb7\x90\xf4\xa7\xe1\x89\x47\x6b\x7f\xee\xe9\xff\x00\x00\x00\xff\xff\x96\xd2\xdb\xc1\x3c\x33\x00\x00") - -func keysWordsWordlistEnglishTxtBytes() ([]byte, error) { - return bindataRead( - _keysWordsWordlistEnglishTxt, - "keys/words/wordlist/english.txt", - ) -} - -func keysWordsWordlistEnglishTxt() (*asset, error) { - bytes, err := keysWordsWordlistEnglishTxtBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "keys/words/wordlist/english.txt", size: 13116, mode: os.FileMode(420), modTime: time.Unix(1523115814, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _keysWordsWordlistJapaneseTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x5c\xff\x72\xe2\xb8\xd2\xfd\x9f\xa7\x5e\xbc\x5c\x2f\x01\x3c\x0e\x71\x1c\xc7\x61\x58\x87\x8a\x2f\x43\x60\x80\x0c\x59\xb8\x93\x8f\x2c\x3c\x8c\x5f\xe4\x2b\xf5\xe9\x3e\xea\x99\xaa\x54\xea\x1c\x59\xd6\xcf\x56\x77\xab\x25\xd3\xf5\x93\xae\x3f\xe8\xfa\x45\xd7\xcf\xbb\x7e\xd5\x25\x45\xcf\x92\xca\xae\xdf\x92\x3c\x03\x8d\xba\xfe\xdf\x5d\x72\x03\x32\xee\xfa\x8b\x2e\xf9\x93\xef\x64\x5d\x32\x06\x9a\x76\xfd\x49\xd7\x6f\x8c\x58\x72\x11\x92\x93\x09\x79\xd9\xf5\x07\x44\x07\xa0\x4a\xfe\xaf\x40\x1e\xbb\x24\xef\xfa\x29\xc8\x53\xa8\xd1\x5e\x7d\xea\xfa\x19\xd0\xbc\xeb\x9f\x80\x9a\xae\x3f\x64\x86\x26\xfc\x25\x7d\xc7\x93\x51\xd7\xbf\x74\xfd\x21\xb9\x3e\x69\xd9\x8a\x56\xfa\xa4\xd5\xbd\xc8\x70\xfc\xa7\xeb\xe7\x7c\x78\xe9\x92\x91\x11\x57\xf4\xb2\xeb\xaf\x89\xf6\x92\x4d\x9f\x1c\x88\x4e\x1c\xb5\x13\xd3\x8e\x7e\x2c\x2e\x6c\xc5\xa5\xeb\xbf\x1a\x4a\x06\xd2\xa4\x9a\x5c\xeb\xbf\x76\x49\xd2\xf5\x77\x42\x42\x4b\x46\x5d\x1f\xe5\x84\x17\x58\x7f\x92\x76\xc9\x1f\x40\x37\x32\x8b\xb7\x5d\xff\x42\x5e\x11\xd5\x5d\xff\x91\xc4\x8f\x5a\x72\x23\x65\x44\x92\x5b\x5b\x42\x8d\x93\xae\xbf\xb2\xe1\x0a\x4f\x66\xcc\x99\x87\xa1\x30\x52\x58\xcf\x12\x99\x7f\x47\x0a\xa2\xaf\x26\x44\x81\x2c\x7d\x9e\xb5\x27\x3a\x00\x03\x88\x24\xda\x32\x08\x52\x29\x6f\x0f\x58\x3c\x50\x0e\x94\x89\xd8\x0e\x48\xd6\x2c\x24\xe3\x28\x0e\x28\xbd\x03\x59\x08\x8f\x44\x27\x96\x3d\xed\xfa\x6f\x98\x69\x21\x96\x5c\x60\x08\x74\x0d\x11\xb5\x3d\x5b\x44\x17\x11\xea\x81\x71\x7b\xaf\x82\x04\x0f\x44\xca\xff\xc3\x42\x1e\xbb\xe4\x2f\x4f\x72\x36\xeb\xa9\xeb\x5f\x0d\x25\x13\xa0\x19\x0b\x9e\x05\xe1\xef\xbf\x93\x8c\xfd\x13\xad\xe8\x2b\x2b\x9f\x77\xfd\xb4\x4b\x32\x56\x34\x97\x01\x8b\xcd\x7c\xf6\x48\x3b\xd5\x48\xc5\x37\x24\x57\x43\x41\x16\x12\x90\x85\x8c\x75\x4a\xf2\x48\xf4\x4a\xf4\x46\x74\x32\x94\x8c\xfc\x10\xb4\x10\xe6\x41\x5c\x83\xd6\xec\x17\xdf\xe3\x17\x74\x83\xa4\xf1\xd9\x16\x44\x4b\xff\xc2\xbf\x7c\x61\xd9\xf5\x1f\x0c\xd9\x7b\xaf\x7c\xba\x82\x70\x0e\x28\x7f\x40\xda\xac\x6d\x97\xfc\x41\x21\xda\xb1\xb2\x1d\xa7\x6a\xcf\xf9\x7f\x73\x69\x56\xcd\x3b\x27\xe4\xc0\xb4\x23\x87\xf9\x27\xd3\xce\x6c\xce\xd5\xd2\x82\xbc\xa6\x50\x8f\x20\x8d\x89\x42\x92\x58\x8b\x12\x91\x7e\xad\x36\x10\xac\x92\x64\x28\xfa\xb3\x20\x41\x7d\xa2\x19\x88\x6a\x96\x3d\x12\x6d\xb1\x30\x12\x85\x32\xe1\x1a\x0b\xda\x8b\xeb\x27\x89\x55\x66\xa2\x87\x8b\xae\xff\x8f\x0d\x43\x50\x08\x03\xa2\x94\x28\xb6\x27\x37\xb9\x08\x02\x9f\xb2\xa8\xa2\xeb\xdf\xd9\xca\xef\x33\xa9\x64\xb9\x85\x08\x48\x6c\x5b\x21\x3d\x0b\x24\x95\xf5\x90\x19\x92\x02\x53\x91\xce\x07\x20\xed\x46\x2a\x4b\xe5\x44\xf4\xc1\xac\x59\x97\xe4\x40\xb9\xe9\xcf\x35\xf9\x04\xe3\x9e\x8a\x5a\x68\xa4\x7d\x39\xdf\x9c\x8a\x0c\x4f\x49\x56\xee\x49\x18\xb1\x96\x44\x93\xef\xa9\xe5\x41\xb4\xde\x02\xc3\x93\x4a\x8f\xbf\x00\x55\x22\x88\xa9\x91\x30\xd8\x13\xac\xc5\x54\xa6\x6f\x40\xf4\x85\xe8\x96\xb3\x2c\xdc\xf4\x7b\x2a\xab\x49\x1b\xb3\xa0\x16\x27\x9f\x70\x00\x16\x1c\xc9\x05\x17\x6a\x2a\x0b\x6a\x0c\xa9\x4b\xa5\xc7\x39\x55\x48\xaa\x2b\xd2\x8d\x7c\x4b\xf4\xca\x6e\xad\xd9\xca\x35\x74\x05\xd0\x13\x47\x60\xcd\x97\xb6\x44\x3b\xd6\x7f\xea\xfa\x77\x44\xf7\x30\xed\xa9\xcc\xc5\xc4\x72\xc7\xbe\xca\xd2\x01\x12\x1b\x69\x64\x68\x95\x85\x31\x9a\x88\xd4\xd4\xe4\xba\x04\x40\xd6\xd6\x37\x51\x78\x56\x77\x20\x99\x49\x43\x32\xa6\x57\x93\xca\x4a\xa9\x1c\x49\x52\x1b\x46\xd7\xbe\x0c\x9a\x26\x95\xb1\xcf\x88\x4a\xa0\x82\xf6\x05\x64\x61\x43\x07\x3b\xe9\x88\xea\xae\xa1\xc8\xe9\x10\x4f\x40\x26\x44\x19\x97\x0a\xf8\x3d\x91\x6a\x55\x90\x93\x7b\xdb\x96\x13\x48\x0e\x34\xc2\xa4\x0f\x65\xbc\x22\xd2\xa7\x99\x4c\xbc\x16\x17\xdd\x82\xa1\x88\xeb\x9f\xcc\x56\x77\xfd\x25\x50\x2b\xae\x85\x56\xb9\xeb\xfa\xb7\x40\x67\x9d\x4c\x19\x15\xe1\x96\x87\x69\x61\x4e\x1f\x89\x76\x40\x37\x56\x79\x40\x27\x20\xb5\x50\x50\x4b\x1c\x9d\x40\xc6\xcc\x5d\x40\x18\x87\xaa\x75\xac\x8a\xc2\xfc\xc0\x94\xfc\x2b\x56\x0d\xc8\xdc\x7a\xa4\xf3\xf3\x97\xcf\xb9\x42\xce\x91\x8c\xeb\x98\x4b\x7e\x64\x5e\x42\x4d\xa2\x82\x32\x32\x0b\x98\x83\xa4\x6c\xee\xc8\x14\xc1\x85\xe4\x91\x68\xc6\x7a\x52\x8e\x3e\xc8\xd1\x17\xf5\xe1\x9e\xd8\xcc\x8e\xb8\x48\x47\x74\x94\x46\x34\xe3\x40\xaf\x9c\x73\xe1\x09\xf3\x84\x42\xe6\x20\x63\x0c\x34\xc9\x13\xd0\x04\x2e\xa8\xa4\x05\x15\xa9\x19\xbe\x50\x8d\x8d\xe8\x7a\x8d\x44\x5c\x62\x0f\x73\xef\x0d\x09\x57\xaf\x73\x4d\xce\xd7\x6c\x45\x8d\xfc\xb0\x16\xbe\x92\x82\x19\x4a\xdf\xe3\x92\xeb\x5a\x88\xe9\x8b\x11\x66\x04\xeb\x1a\x24\xbe\xf3\x08\x49\x01\x2a\x39\x3d\x22\xde\xf6\xc2\x5c\xc4\x2f\x27\x89\x8d\x6d\x68\x7b\x40\x34\xcf\x33\x9c\x7d\x90\x85\x97\x81\x17\x18\xe5\x91\xac\x14\x1d\xbf\x6f\x10\x27\x90\x95\xd4\xad\x2b\x00\x7c\xed\x25\xea\x95\xaf\xbd\x8a\xc2\x19\x73\x84\xde\x7c\xfb\x2f\xb0\xf5\x42\x92\xbe\xd4\xb1\xb2\xe1\x4b\xb0\x0d\xfc\x46\x12\x93\x29\x6e\x81\x84\x0d\x21\xc8\xc0\x44\x32\x19\x88\xe6\x7b\xef\x99\xc0\x7c\x5a\xf5\xb2\xec\xb1\xb7\x1c\x49\xc3\x34\xb9\xa0\x3a\x01\x99\xb2\x06\x2c\xc6\x3f\x49\x66\xd6\x78\x29\xc7\x93\x68\xa8\x46\xa6\x1f\xb5\x98\x31\x76\x70\x40\xaa\x1f\x27\xd0\x8f\x44\xea\xde\x4f\xbc\x87\x3f\xf6\xbb\xe2\xb1\x2e\x5a\x69\x0b\x48\xed\x1d\xab\xb1\x77\xb8\x41\xfe\x86\xf1\x23\x6f\x7d\xb1\x4b\x9f\x73\xe5\x9f\xe8\x02\x9e\xa8\x73\x28\x8d\x1c\x7b\xff\x70\xec\xf5\xf4\xc4\xfb\x74\x63\x2a\xed\x31\xc5\x77\xcc\xa5\x3c\xfe\x2d\x79\xc2\x96\x4f\xb0\x39\x1c\xd3\xb5\x18\xcb\x62\xbc\x27\x5a\x31\xeb\x03\x5e\x9f\xa0\x7b\x48\x6b\x58\x7b\x03\xf3\x39\xf1\x8a\x71\x22\x02\x9d\x71\x7a\xc0\x0b\x4f\x4a\x8e\xfe\x8b\xf7\xef\xc6\x22\xd6\x0f\x62\x1f\xb5\x7d\x3b\xbe\xb6\x67\x93\x4e\x58\x45\x63\x3f\x40\x67\xb6\xfe\xc2\xb4\x8b\x48\x22\x46\x3d\x2c\xfb\x09\x37\x92\x63\x11\x58\xf4\x41\x06\x16\xd2\x3b\x76\x03\x9b\x8c\x89\x32\x2b\x31\xb4\x2b\x37\x24\x1b\xa5\x09\x4c\x0c\xd2\x0a\x27\x81\xce\xb0\x8f\xbd\x54\x8f\xcd\xa4\xc4\x27\x0d\xdb\x54\xd8\x68\x06\xa4\x1b\x8b\x0c\x01\x1a\xa2\x16\x28\x78\xe1\x3d\xd1\xb2\x03\xbc\x9e\x49\x2f\x06\x86\x2c\x6d\xc8\x52\x54\xdf\x03\xe5\x44\x0b\x43\xf6\xc6\x98\xa5\x8c\x99\xef\x97\x2e\x64\xf2\xb7\x04\xca\xa5\xa1\x23\x23\x61\xfc\xee\x40\xa6\xba\x7e\xad\xb4\x82\xf5\x17\xbe\x59\x05\x2b\x29\x99\xb5\xf4\x69\x17\x43\xa1\xec\x2f\xe8\xf3\xa3\x97\xe7\x2f\xdc\x6a\xe3\x49\xe3\x17\x38\x92\x36\x7e\xa3\xf8\xc5\x36\xe4\xad\xef\x52\xcd\xe6\xc5\x26\xeb\xc6\x3a\xa3\xf9\xcd\x38\x75\x99\xac\x87\xdc\x90\x0d\x5e\xe3\xbb\x16\x97\x44\x26\x95\x0d\xd9\xa4\x17\xec\x89\xf9\xa4\x65\x45\x6d\xd7\xdf\x02\x2d\xd9\x8c\x57\x16\xf2\xca\x2a\xd7\x7c\xba\x86\x82\x03\xd2\x66\x7c\x17\x6f\xb9\x02\xd9\xb2\x75\x3b\x16\xb4\x93\x31\x6b\x40\xf6\x2c\xf5\x9d\x46\x25\xe3\xde\x35\xa3\x86\xca\xe8\x39\x66\xb2\xb2\xb4\xac\x33\xd3\x2e\xec\xfa\xd5\xc6\x2b\xf9\x43\xe3\x7a\xb1\x60\xb3\xc0\x08\xce\x3c\x8b\x25\xaa\xc8\x17\x3d\x1f\xb6\xc9\xe8\x50\x66\x62\x70\x30\xdf\xa2\x59\x64\x56\xf5\xc9\xd0\x1a\x23\x03\xee\xa3\x0d\x19\x97\x74\x46\x7b\x9d\x49\x06\xb4\xd9\x36\xbb\x40\xda\xe6\x8c\x15\x65\xcc\x97\xb3\xdd\x5f\x10\xf1\xc2\x02\xcc\xcc\xc7\xd4\x98\x12\x78\xf0\x6a\x8c\x38\xfd\x72\xcb\xb5\x9c\x23\xcc\x03\x94\x72\x9f\x0c\x92\x11\xdd\xfa\x64\x5d\x40\xb7\xe6\x0f\x0e\xf8\x64\xee\x9f\x34\xd0\x4c\xb9\x77\x0e\x41\x3e\x81\x62\x5d\x71\xbb\x90\x63\x1b\x8e\x42\x0a\xa6\x95\xac\xa5\x64\xb3\x4a\x46\xc9\x84\xc8\x90\xe4\xe6\xfa\x5f\x49\x62\xc1\xb5\x88\x5b\x66\x24\x8c\xbd\x8e\x87\xec\x1d\x44\x5f\xe4\xb4\xf4\xb7\xb6\x80\x97\x7c\xe7\xd9\xd7\xd3\x04\x29\x35\x67\x30\x17\x47\xaa\x60\xbd\x0b\xdf\xd0\x96\x32\x7e\x2b\x2b\xae\xc6\x8a\x93\x27\x61\x8a\x6f\x7b\x66\xea\x52\x9a\xe7\x9c\x6b\x2c\x97\xbd\xa9\xa6\x6d\xf1\x1f\x64\xc7\x9e\x1d\x89\xae\x7e\x73\x0d\xde\x30\x44\x1a\x45\x27\x87\x10\x63\x80\x7a\xa6\x30\x6b\xa2\x0f\x66\x1b\x43\xf1\xe5\xae\xab\x66\x87\x72\xd8\x47\x4c\xcd\xad\xca\x9f\x8e\x5d\x8c\x97\xe4\xe4\x8d\xcf\x19\xd4\xf6\x54\xc4\x70\x0d\x34\xa0\x9e\x9f\x7a\xbd\x09\x12\x91\x7a\x45\x77\x2e\x9e\xd9\xf2\xa1\xd6\x70\x67\xe1\xb2\x54\xb2\xf0\xe5\xb0\xb2\x32\x12\x45\xf0\x62\x6b\x23\xc9\x88\x6b\xfe\x0e\x26\x87\x48\x05\x13\xe4\xd9\x93\x85\x27\x2b\xb6\x30\xa8\x34\x43\xa6\x34\xee\x28\xd6\x77\x76\x16\x12\xb7\x1e\x77\xc1\xe9\x90\x2e\x4c\x29\x40\x92\x66\x7d\xa8\xd8\x81\x2a\x68\x56\xd9\xf0\x4c\xbd\x98\xdf\x31\xb2\x86\x68\xd1\x1b\x90\x9c\x9e\x04\xd9\xfb\x1f\xf9\x0d\x3b\xdd\xd2\x9e\x4f\x79\x46\x31\x55\x43\x61\xd5\xbd\x30\x46\x84\x27\xaa\x58\xa6\x16\x29\x8d\xd9\x96\xbe\x80\x0b\xc7\xa2\xf5\xfa\x07\x7c\xe2\x72\x9a\x82\xbb\xa3\xdc\x4b\x34\x2b\xac\xf0\xba\xe7\x43\x5b\x53\x31\x2f\x77\x44\x35\xd1\x15\xe8\x3b\x87\x6d\xcb\x4e\x6d\xd9\xf4\x3d\x25\xe4\xc0\xb4\x13\x7d\x8d\x3b\x31\x27\x5a\xbb\x1e\x01\x4c\x65\x11\x8d\xad\xf6\x60\x47\x2a\x43\x9a\xc1\x04\x66\x4a\x1d\x3f\x95\x45\x32\x35\x21\x73\xeb\x64\xca\x63\x8a\xa9\x86\x08\xb4\x91\x81\x8c\x88\x20\x75\x01\x65\x4c\xbb\xb3\x16\x3b\x9f\x6e\x6a\x61\xca\x9c\x24\xc6\x10\xc0\x6b\x93\x0c\xe7\xf0\x4d\x75\xe7\xe2\x5e\x5b\xfa\x56\xad\x7c\xb6\xb5\x7f\xb2\xb1\x79\x0a\xe4\xe4\x1b\x7f\x21\xba\xba\x86\x06\xa3\xca\xb7\x2d\xfa\x02\x12\x7a\x5b\x88\xec\xe5\x78\x5b\xac\x59\xff\x3b\xd1\x3b\x24\xf9\x9e\x1e\x65\xe1\xc3\x14\x85\x86\x59\x1d\x51\xf5\x73\x6f\x51\x55\x1d\x87\x7b\x0b\x8f\xc6\x32\x74\xf8\x0a\x0b\x75\xc4\x27\x8f\x44\x1a\xe3\xbc\xf7\x76\xae\x30\x3b\x97\x93\x34\xfe\x89\xee\x4a\x0b\x0b\x54\xc6\x4a\x96\x3e\xdb\xab\x7f\xb2\xf6\x4f\xf6\xbe\xd2\xb3\x6f\xff\xc5\xf5\x34\x48\x1c\x5b\x90\x8c\x30\x0d\xd1\x9d\x2d\xb8\xf5\xba\xa7\x6c\xdf\x8b\x9f\xda\x5a\x9a\x95\xa5\xbb\xad\xc2\x9b\xd9\x82\xf6\x88\x64\xed\x9f\xec\x59\xf9\x2d\x27\x2e\x8e\xee\x94\x6d\x28\x44\x09\x93\xc8\x62\x28\x10\xfb\x00\xaa\xd8\xf0\x9a\x95\xc5\x81\x56\xb5\x12\x0f\xed\x20\xbf\xcf\x30\x1e\x85\x1f\xf9\xc6\x77\xbd\x61\xa9\xd1\xf1\x2d\x10\x43\x06\x6a\x79\x6e\x06\xf2\xc6\xe2\x5b\xc4\xf1\x0a\x3f\x5d\x4b\x3e\x5d\xc9\x96\xe8\x86\xa4\x22\x7a\x33\x64\x42\xbd\x96\x61\x5e\x83\x6c\xf1\xbf\x67\x23\x72\xe1\xa8\xed\xa0\xb6\x04\x25\x43\xcc\xcd\x9e\xf5\x1d\xa0\x6a\x41\x8e\xec\xc8\x91\x19\x3e\x69\x95\xef\xa5\xd4\x78\xfc\x2b\x07\x19\x6e\xea\x2f\x74\x3b\xf0\xa4\x65\xe3\x2e\x36\x6e\x41\xb3\x7d\x81\xa9\x2d\x18\xef\x2c\xe8\x0b\x17\x54\x73\x82\xb4\x09\x66\xd6\x80\xd0\xab\xe0\x55\xa5\x44\xef\x40\x43\x1b\x4f\xf3\x91\x0b\x31\xb5\x5a\xf5\x24\x7a\x6b\x56\x70\x26\x33\x36\x05\xc9\xa5\xf2\x25\xc9\x84\x6f\x16\xdc\x78\x16\x3e\xca\x5a\x50\x77\x16\xbf\x29\xc5\xc2\x94\x62\xcc\x46\x89\x82\xea\x73\xa5\xad\x3d\x79\xef\xfa\x1b\x92\x7f\xfd\x93\x0b\x1b\x5a\x20\x64\x09\x34\x71\x95\xd8\x96\xfd\x41\xc3\xe6\xd2\xb6\xd2\xdc\x9e\x01\x89\xda\x41\x64\xbb\xf3\xa4\x60\x1e\x75\xda\x4a\x1f\x50\x7f\x30\x07\x28\x56\x12\x03\x53\xa5\x77\x64\x1f\x7e\x3b\x68\x2b\xa1\x84\x80\x34\xda\x04\x32\x81\x79\x45\x72\xcc\x70\x85\x40\x94\x3c\xfc\x2b\x65\x2f\x12\x8b\xcb\x59\x42\x4e\x3b\x5b\xc2\xb5\x04\xd2\xbd\x76\xc9\x75\x58\xfa\x4b\x17\x0f\x5c\xfa\x25\x83\x12\xa5\xf9\x23\xda\xd7\x96\x9a\xff\x81\x2b\x1b\xc9\x13\x96\xfd\x62\x1b\x8b\x9c\xd9\x2a\x16\xf5\xe8\xdf\x9e\xb3\xe9\x2d\xbd\xa6\xd2\x1c\x98\x41\x97\x24\xe0\x4b\x4e\xd4\xca\x27\xaf\xf8\xf6\x8a\x31\xeb\x92\x0a\xa2\xa4\xeb\x52\xd2\x65\xc7\xd6\x45\x9b\x19\xf7\xba\xa5\xc4\xcd\x75\x3c\xce\xcc\x7a\x46\x2c\x0f\x07\xfc\x3a\x21\x57\xff\xd2\x55\xdc\xd1\x89\x90\xb0\x8a\xa7\x3d\x1f\x60\x2e\x65\x69\x0e\xfd\xd9\x4d\xc9\x35\x5a\x72\x3d\x96\x8c\x28\x22\xc2\xf1\xdc\x43\xcc\x4d\x46\x07\x03\x92\xe4\x8c\x1c\x97\x8c\x33\x97\x7e\x0d\x96\x74\x5e\x80\xe2\xb6\xb9\xf4\x5e\x4b\x69\x5e\x0b\x66\xd3\x36\x0b\x7c\x52\xfb\x6c\x33\xeb\xa7\xf8\x2f\x44\x0b\xa2\x0b\xd1\xd5\x90\x39\x1a\x15\x37\xba\x15\x0f\xd2\x2a\xbb\x07\xf4\x82\x65\x5f\xf9\x2d\x93\x84\xe2\xa5\xc1\x15\x3b\x55\xc1\xb2\xf7\x34\x36\x6f\xc5\x8d\x30\xd0\x15\x17\x70\xc5\x1d\xcc\x23\x2d\xac\xb8\xe9\xe2\xc5\x54\xec\xd6\x23\x6f\x3d\x54\x22\x6d\x29\x0b\x6a\x10\x58\x02\x5a\x12\x5d\x81\xa2\x35\xab\xec\x2a\x83\x56\x11\x8f\x47\x2b\x9a\x0c\x41\xa6\xa8\x2b\x0a\x6f\x45\x3d\x00\xd4\xa2\x41\x6a\xe4\x1e\x29\x22\x38\xfd\xfd\x02\xb1\x12\x62\xea\xbf\xa2\x5a\xac\xc4\xb4\x5d\x0c\x59\x9a\x1e\xac\x01\x9d\x80\xf6\xac\xfd\xcd\xb7\x55\xaf\x2f\x08\x32\xdf\xb9\xa2\x09\xac\x44\x7b\xc4\x3e\x1f\x39\xba\x27\x66\xf8\xc9\x97\xce\xcc\x77\xe6\xd3\x0b\xd3\xd4\xcc\x55\xf4\x4e\x2b\x2c\x15\x24\x3f\xc2\xaf\x87\x0c\x56\x74\x5a\x2b\x2e\xa2\xca\x0d\x65\x10\xe9\x81\x27\xa9\x27\x23\x1b\xc9\x40\x26\xd4\x13\xd5\x6f\x3b\x6e\x3d\xa1\x74\xcd\x0e\x7c\xea\x4b\x8a\xe8\x81\xcd\xf9\x93\x57\xe7\x40\x66\x9e\xcc\x7d\x51\x8d\x7f\xc7\x8b\x8e\xee\x04\x33\xdf\xce\x8b\x3d\x89\x42\x25\x27\x4c\x28\xe3\x91\xea\xe2\xd1\x42\x5e\xb1\x17\xff\xf1\x2e\x21\x9e\xc7\x16\xfe\xc7\xef\x0f\xc1\xaf\x86\xc2\x7c\xbf\xd9\x3b\x1a\x68\xd6\xd7\xfe\xb2\x3b\x12\x03\xf2\x9c\xc6\x0d\xfc\xc5\x0f\xd6\x5f\x4e\x6c\x83\x0b\x91\x98\x58\x85\x3a\x66\x9c\xc1\x18\xd8\xa8\xa8\xa7\x2a\xaf\x97\x1e\x2d\x68\xf6\x27\x9f\xcc\x10\x68\x20\x5f\xb0\x11\x05\x07\xab\xa6\x6e\x01\xaa\x88\x82\xd1\x7c\xc2\x9d\xb2\x9e\x9e\xdb\x98\x06\x01\x19\x13\xa9\x15\x79\xf2\x07\xe3\x3c\xe8\x51\x3f\xaa\xb6\xfb\x24\x39\xc9\x23\xba\x5a\xeb\x26\xc5\x5e\x8b\x67\x71\x35\x22\xa2\x40\x7a\x27\xa6\xf6\x3e\x7d\xcd\x55\x50\x8b\xb2\xd2\xb4\x02\xfd\x78\xe2\x21\x49\x2d\xa4\x62\x86\x1a\xe1\x87\xda\x5f\xf4\xa8\xbd\x2e\x7a\xb2\x53\x95\x48\x56\xc8\xa3\x1a\xa8\x66\x64\xaa\xe6\xb5\x0b\x04\xe9\xb4\xbe\x3d\xcc\x50\x2d\xb2\x71\xc3\xca\x9f\xbc\x5e\x78\x92\x6d\xe8\x77\x28\xaa\x5a\x86\x4e\xbb\x7d\x64\xda\x07\xb4\x69\xcd\xf9\x7f\xe2\xba\xab\xc5\x8b\xd6\xfa\x2e\xd6\x39\x0b\x05\xd7\x3c\x81\xac\x65\xfd\xa2\xd5\xb8\xbf\x24\xce\x4c\x1d\x2c\xa4\x6c\x67\x6a\x59\x2e\x72\x99\xc5\x5e\xc8\x5c\x9f\xcd\x5c\xd6\xfe\x16\x62\xad\xae\xa4\xbc\x30\xf3\xfe\xfb\xcc\x3c\xc3\x96\x44\x9d\xc1\x28\x90\x33\x7f\x1c\x37\xe3\xc1\xca\xcc\xbc\xb8\x31\x5f\xc8\xb8\x6f\x9f\x21\x16\x4e\x94\x12\xe1\x84\x34\x65\xb6\x29\x51\xc1\x72\x6b\x56\xac\xda\x05\x68\x0a\xf4\x42\xfb\x37\x33\x0d\xa3\xc6\xff\xab\xf0\xf8\x24\x96\xfd\x42\x17\x70\xa6\x07\x72\xb2\xcc\x21\xb0\x33\x31\x66\x7f\xf3\xcd\x96\x61\x37\x90\x6f\xbe\x98\x1f\xfe\xc9\x3b\xd1\xc9\x25\x9b\x5a\x07\x19\xb1\x5e\xbd\x6f\x37\x13\xd1\xd3\x57\xf7\x50\x4e\x33\x89\xf2\x66\x40\x9f\xd8\xc4\xcd\x28\x28\x33\xda\x95\x19\x97\xc0\xcc\xdf\x96\x9b\x49\x35\xc7\x1e\x66\x1c\xb1\x0e\x24\x17\x56\x82\x06\x81\x22\x19\x13\x65\x50\xb2\x20\xf1\x3d\x15\x04\x94\x78\xcf\xe4\xd2\x17\x12\x34\x2c\x49\xed\x9f\xcc\x3c\xf9\x9b\xa8\xf1\x35\x44\x73\x31\xf3\xb1\xa1\x99\x8f\x0d\x81\x68\xb4\x0d\x64\x6b\x63\x1d\xc8\x0f\xbc\x83\x56\x9e\x88\xfe\x75\x6f\xab\x1c\x22\x4a\xe4\x8e\x2b\x90\x94\xb8\xd2\x6c\x9b\x09\x92\xfa\x32\x54\xfe\xbf\xc2\xed\x23\x1a\x51\xf8\x66\x7e\x2f\x06\x12\x9a\x3c\xe7\x6c\xcc\x4d\xff\xde\x61\x06\xc1\xb7\x3d\xbd\xbc\xaa\xc7\xa0\xf1\x8c\x62\xce\xc3\x11\xa0\x7b\x22\x35\x7c\x20\xcf\x9e\xac\x3d\x79\x37\x24\xdd\x26\x19\x01\xc5\x2b\x46\x73\xc6\xba\xe6\xbc\xc9\x31\xe7\x8d\xa1\x39\x57\xe6\xdc\x42\x23\x9a\xf5\x81\x59\x2b\x98\xa0\x39\xa7\x7d\x4e\x23\x31\x97\xbf\xdb\x1e\x63\x2a\xec\x7c\xcb\x52\x5b\xdf\x80\x17\x6a\x14\x3c\xf9\xe2\x07\xe4\x05\x71\x5c\x92\xc2\x3f\x99\xf9\x32\x56\x40\x2b\xde\xfa\x03\xf9\x2f\x26\x6f\x2e\xab\x71\xc8\xb6\xac\x71\x70\x32\x17\xe7\xef\x13\xe8\x93\xd3\xf6\xc9\xa9\xbc\xb0\xf2\x8b\xbd\x1b\x3c\xba\xdc\x50\x58\x86\x43\x90\x3e\x33\x24\xf8\x0f\x22\x97\x56\xfb\x5f\x7b\x76\xa1\x46\xef\x81\xce\x79\xdc\x31\xf7\xf1\x85\xb9\x3f\x65\x07\x79\xf0\xa4\xb2\xf6\xc8\x2a\x63\x43\x7e\x59\x5b\x7f\x23\xaa\x40\x74\xb2\x61\x72\x31\xd4\x86\x1b\x18\x1c\x46\x0d\x98\x3c\xa0\xb2\x6e\x7c\x48\x01\x44\x4d\xc1\x33\xae\x9d\xa0\xfa\x86\x37\x4f\x80\x6e\x91\xe7\x97\x53\xea\x86\x91\x06\x20\xed\xd3\x73\xe7\x2e\x8c\x63\x35\x3f\xdb\x4d\x94\x58\xa0\x9e\x4d\x83\xcc\x7d\x0b\x1a\xdf\x85\x38\x00\x3c\x5f\x8b\x75\xbc\x32\x50\x88\x87\x6b\xff\xe6\xd6\x57\xb0\xf3\x65\xe8\x86\x01\x65\x1c\x7e\xab\xe0\xe8\xc9\x4f\xdf\xd1\x33\xd1\x45\x03\x81\xb2\x5c\x90\x74\x95\x79\xb8\x35\x2e\xca\x0a\xa8\xef\xca\x48\xfc\x98\x9a\x32\x02\xb9\x21\x1a\x31\x0c\x01\x3e\x26\xca\x59\x54\x0a\x01\x8d\x91\xcc\x46\xa6\xb1\x36\x14\xd3\x2c\xfa\xd5\x50\x1a\x81\xb6\x40\x19\x64\xaa\xb1\x73\x51\x2d\xbf\x60\x03\x0a\xdf\xe8\x92\x25\x54\x3c\x68\x7a\xd6\x6d\x81\x98\xb0\xc6\x7b\x88\x8d\x39\x84\x39\xf9\x1c\x9f\xda\xf4\xf4\x43\x18\xfb\xae\xa5\xa1\x49\x69\xa4\xc0\x8a\xf5\xe8\x86\xb6\xc1\x15\x7d\x8c\xf8\xb3\x79\x0f\x03\x92\xe8\x3d\x80\x17\x44\x15\x4f\xfd\x9e\xed\xf2\xaf\x16\xbd\x64\xab\x56\x7e\x18\xd7\x52\x4f\x03\xb2\xe1\x88\x7c\xe7\x20\xe0\x16\x82\xb6\x6a\x4f\x29\x3b\x31\xeb\x07\xcb\xfa\x64\xf7\x2e\xd0\xfc\x0d\x55\xce\xb3\x28\x1a\xe4\x13\x57\xc3\xca\x0f\xa4\xee\xf9\x0f\x5e\x1a\xee\x51\x1a\x5c\x9c\xb7\x2e\x24\x6c\xb5\x1d\xd0\x35\x7a\xef\x57\x76\xb5\x30\x46\x96\x1a\xc5\x3c\xa1\x7c\x24\x63\xa8\xd8\xc6\x89\x49\x02\x0b\xa6\xc9\xd1\x2b\x6d\x64\x1e\xff\x60\xce\x67\xf3\x51\xb4\x61\x05\x5b\x55\x70\x5f\xdb\xd0\x47\x69\x18\x62\x6d\x54\x19\xba\x0c\xf7\x44\xa5\x4f\xa6\x0a\x79\x67\x75\x33\x5f\xc9\xdc\x44\xc6\x9d\x17\x3f\x33\xdc\xd3\x78\x67\xa4\xf1\xce\x08\xf2\xac\x99\xbc\x31\x41\x86\x5b\xe2\x3a\x44\xb5\x91\xc8\x67\x03\x2e\xdb\xa7\x7f\x72\x71\xef\x98\xdb\xf8\x6c\x8e\x44\x4b\x92\x11\x85\x66\x2f\xa8\xac\x17\xdc\xf3\x2d\x28\x07\x0b\x3b\xbf\xd6\x0c\x43\x66\x18\x33\x6d\x0c\xad\xb1\xf0\xa7\x57\x0b\xee\xd5\x17\x76\xce\xfd\x64\xc4\x92\x75\x71\x2f\x7c\xf9\x15\xab\xad\xbc\xb0\x2c\x38\xe4\x0b\x6a\xe9\x05\x07\x7b\xc1\x88\xeb\x42\xbf\xb1\x49\x34\x39\x1e\xfa\x2e\xb8\x81\x5b\x30\x70\xb4\xe0\x72\x12\x24\xbe\xcc\x82\xa3\xbd\xf0\x4a\x79\x81\xa0\x0d\xdd\x82\x05\xf7\x62\x0b\x19\xf7\x06\x48\x6f\xee\x00\xbd\x62\xa8\x17\xb6\xae\x5e\x7b\xfc\x22\xd0\x8e\x5b\x3e\x7a\x8c\x78\x5b\x57\x92\xd4\xab\xde\x85\xc9\x5e\x45\x82\x08\x35\x87\xd1\xbe\x55\x03\xba\xf6\x34\xca\x66\x77\x13\x17\xbf\x0e\x63\x58\x69\xda\x8e\xdc\xe6\xdf\x89\xed\x42\x9d\x58\xa9\xbb\xe5\x66\xbf\x35\x83\xb8\x00\x49\x99\x9c\xfa\x9b\x00\xad\x1e\x06\x4a\xcb\x5a\xdc\xd5\xef\xf9\xef\x06\x05\xd9\xc2\x6d\x79\x2d\xa4\xe5\x65\xe5\x16\x27\xdf\x86\x2c\xed\x9e\xaf\x47\x4b\xd3\x06\xf7\xcb\xda\xa9\xe1\x43\x41\x62\xf3\x5a\x09\x60\xf7\x99\x75\xcd\xb8\x7f\xcb\x73\xf7\x56\x56\xd9\x7f\x59\xdf\x8e\x19\x4e\xd0\x62\xf8\xa6\x31\x7e\xda\xd0\x52\x6b\xb6\x32\xc1\x59\xcf\x36\x68\x8d\x65\xb0\xef\x8c\x80\x90\xd5\x8e\x91\x5a\x19\xfd\x4f\xa2\xab\x35\x5f\x4f\x8a\x76\x24\xa1\x84\x25\xa3\x32\x40\x4b\xa2\x2b\x50\xfc\xb2\x6f\xc9\x89\x5a\x72\xe1\x2e\xd5\x43\x92\x9a\x97\x76\x51\x37\x27\xd1\x2b\x29\x4b\x1e\x9d\x2c\xfd\xc1\xcc\xd2\x7b\x40\x4b\x4a\xef\xd2\x3c\x9a\x98\x1c\x97\xc8\xd2\xbb\x2a\x20\x9f\x7c\xa2\xb1\xe8\x25\xef\xa3\x83\x64\x54\x86\x4b\x91\x86\xa0\x61\xbf\xe9\x29\x61\x5f\xcb\xf9\xe5\xa0\x06\xfc\x0e\xa8\xe6\x48\xcd\xf9\x74\xc1\x4d\xc7\xd2\x7b\x6d\x4b\x7f\xcc\xb2\x34\xe9\xc9\x50\x5d\xd8\x88\x33\xf9\xd3\xbd\x20\x6a\xe4\x9b\x68\x89\x31\x3c\x9d\x25\x55\x06\xd0\x2d\xeb\xda\xc9\x58\xdc\xf4\xec\x33\x57\x4d\x3e\xe1\xf2\x11\xc8\x11\xa1\xa1\x25\x8e\x47\x58\xce\x99\x63\x76\x61\x2d\x17\x19\x9c\x27\xce\xcd\x15\x01\x7a\x23\xc1\xfe\x62\x14\xcc\xe4\x2e\x45\xcb\xbf\x03\xe5\x88\x6f\x00\x35\x28\xe4\x9b\x37\x94\x4b\x7f\x00\xb2\xf4\x9b\x84\x25\x2d\xe4\x92\xbe\xe4\xd2\xdb\x4a\x90\x7b\x1b\x4a\xb7\x8b\x07\xa9\x88\xf4\xe8\xe0\x1b\x6d\xe1\xd2\x6c\x61\x2c\x9e\xd3\xef\x2e\x6d\x80\xfc\xcf\x46\xd3\xec\x1c\x4f\x20\x96\x66\xe0\xd8\x13\x0d\x04\x69\x17\xbe\xd9\x66\x5a\x95\xe8\x37\x1a\xbb\x57\x1a\x3b\x1c\x86\x4d\x90\x16\x6f\x61\xac\x7e\xbb\x85\x81\x87\xb7\x7c\x52\x19\x92\x83\xe7\x9e\x9e\x9e\x59\x89\xfa\x9d\xf1\x8a\xb7\x84\x57\x74\x87\x57\x74\x87\x57\x6c\xe7\x8a\xdf\x1a\xac\xec\x1a\xf1\x88\x44\xc5\x63\x85\xeb\x8e\x44\xf1\x4c\x18\x7c\xc9\x76\xe7\x38\xe9\x05\xd2\x23\xb9\x15\x55\xc0\x8a\xfa\x74\x05\x67\x1a\xa8\x64\x8b\x11\x91\x8e\xc3\x30\x67\x2d\x0d\xd3\x16\xbe\xf2\x5f\xae\xa9\x83\xe7\xcc\xd9\x32\x5c\x08\xb2\xf1\x39\x5f\x7d\x5b\x56\xb2\x74\x86\xe4\x6b\xb6\x77\xfd\x6b\xb2\x8d\xcd\x8e\x17\x9b\xe3\x55\xab\x57\x59\x68\xba\x37\x5f\xd1\x36\xaf\xa8\xb0\xa3\x31\x58\xe9\xc5\x59\x11\xc8\x15\xd5\xf4\xab\x0f\x59\xaf\x64\x55\xb1\x72\x15\xad\x16\xd9\x0a\x86\x6b\xd7\xfe\x02\xe0\xda\x7f\x0c\xb1\xf6\x47\xde\x20\x35\x91\xba\x10\x6b\xbf\xe5\x5c\x53\x50\xd6\x54\x60\x6b\xdc\xf9\x04\xd2\x30\xcf\x9a\x97\x71\x40\x4a\x2c\xf4\xb5\xac\x72\x68\x4e\x2d\xfb\x85\x6b\x6b\x0d\x55\x26\xeb\xf1\x0a\x8e\xea\x2a\x90\x0d\x8f\xfb\x84\x98\x29\x02\xd1\xae\xe9\x95\x98\x35\x75\xd8\x5a\x8f\x99\x45\x48\xd7\xd4\x5c\x40\x5a\xcb\xd5\xb2\x86\xb1\xbf\xb1\x12\x6c\x22\xd6\xf2\xe9\xcb\x1f\x40\x37\xd6\xd4\x80\xde\x89\x4e\x40\x13\xbe\x81\x2b\x3e\xef\x24\x7a\x7d\x7e\x23\xeb\x3a\x05\x1a\xf0\xe7\x15\x36\x3c\xa7\xdc\x70\x99\x6e\xb8\xfc\x36\x92\x6f\x09\xa4\x1b\xd0\x8d\x7d\xa6\x79\x25\xd1\x2b\x4c\x1b\xce\xc1\x86\x47\xc6\xdc\x01\x20\x55\x9d\xd7\x8d\xc5\x53\x77\x20\x0b\xef\x23\x09\x77\xa2\xb6\xe1\x4d\x00\xa0\x8c\x68\xca\x56\xc6\xd0\xd4\xc6\x7f\x00\xb2\x71\x1f\x80\xe4\xe4\xb5\xcf\x39\xf3\x05\x2e\x59\xe0\x9a\x79\xce\x2c\x4a\x43\x47\x1b\x6e\xf2\x36\x32\x3f\x18\x5d\xf3\x50\x2d\x77\xf2\xcb\xc7\x46\x1b\x9d\x17\xcb\x5c\x58\x45\xb6\xeb\xda\xd0\xa6\x6c\x7c\x30\x78\x63\x51\xa7\xf8\xe4\xc9\x5a\x96\xc4\x7b\x7f\x1b\xef\xa1\x6e\x68\x4c\x36\x7e\x63\xb5\xd1\x1d\x94\x0e\x84\xd8\x0f\xa2\x8b\x6b\x99\x08\xdc\xc6\xef\x90\x36\x3e\x22\xfb\x1d\x47\xe9\xd0\xed\xdf\xa9\x9f\xd5\xd2\xf3\x56\xc4\x77\x46\xa2\xbe\x8b\xd6\x53\xaf\xef\x3b\x0f\x98\xbe\x63\x45\x60\x8e\xbf\xe3\x47\x28\x80\x6e\xac\x44\x8d\xab\x69\xbc\x60\xcb\xe3\xb8\x2d\x97\xd5\x96\x71\x97\x2d\x2f\xff\x6e\xa5\xe6\x59\xcf\xae\x55\xeb\xb0\x6c\x79\x53\x05\xf7\xb6\xbe\x1a\x92\xd6\x6c\xe9\x35\x6d\xed\xc0\xac\x06\x99\x33\x4c\xb0\x65\xf0\x77\xcb\x0b\xb5\x5b\x93\xb0\x98\xac\xdf\x31\x6d\x19\xc4\x80\x77\x86\xa4\x13\x37\xc3\x5b\x2a\x8a\x2d\x5d\xaa\xad\x88\xdb\x48\xbc\xa3\x33\xc6\x63\xcb\xaf\x55\xb7\xfa\x91\xb8\x28\xa5\xad\xe8\x8e\x6b\x4f\x7f\x4b\x40\xdb\x12\x10\xbb\x9b\xe8\xcf\xa0\x6c\xa9\x3b\xb6\xf2\xfa\x03\x10\x9c\x9b\x11\xc9\xc8\x0a\x4e\xe2\x85\xef\xad\x85\xc8\x23\xb9\x25\x8a\xe5\xc4\xf7\xfc\x6c\xc9\xc5\x14\xa2\x7f\x88\xf4\x76\xe9\xd6\x6f\xc8\xb7\xce\x1f\x49\xc9\x55\xcb\xef\xb8\x39\xde\x49\x33\xff\x0b\xdb\xb6\xe3\x4d\xa6\x9d\x7d\x9e\x72\x05\x29\x64\xc4\x47\x24\xb5\x21\x99\xc6\x1d\xcf\x8e\x77\x8c\xe1\x0a\x12\x41\xd8\x59\x10\x28\x05\x59\xf0\xa2\xce\x8e\xa7\x5d\x3b\x5a\xd5\x1d\x6e\x38\x00\x7d\xb0\xd4\x4f\xa2\xf8\x3b\x2b\x3b\x5e\xa5\xdb\xd9\xaf\x01\x7c\x27\xd9\xc2\x28\xed\xfc\x3d\xf5\x9d\x7d\xca\x90\x81\x68\x88\x68\x47\x4d\xf1\x46\x57\x6d\xcf\x43\x8f\x37\xbd\x05\x23\x59\xdf\xb8\xeb\x79\xe3\xfd\x97\xbd\x8f\x0b\x83\xdc\x13\x55\x3e\xb9\x66\xd9\xd1\x22\xef\xbd\x45\x06\x59\xb0\xf8\x37\xf7\x82\xc5\x53\xf6\x74\x12\xf6\x74\xef\xf6\xb4\x2f\xf1\xd2\xc8\x9e\xd7\xc4\xf6\x74\xe2\x40\x62\x53\xf5\xc0\x69\x8f\xcb\x51\x86\xec\x69\x85\x8e\xbc\xd1\xa9\x90\x34\x2b\x52\x67\xfc\x87\x9e\xaa\xd8\x4b\x73\xa2\x86\x28\x06\x29\xf6\xfe\x42\xda\xde\x9f\x84\xee\xb9\x39\xda\x9b\x9b\x37\x22\xc9\xf9\xf6\x8b\x6f\x7e\xb4\x51\x7b\x6f\xa3\xf6\x5e\x83\xec\x4d\x69\xc4\x02\xa2\x47\xb9\x57\x1b\xe5\x72\xfe\xc3\x15\xb3\xf7\x3f\x4f\xb2\xe7\x1d\x7a\xa0\x77\x20\x31\xec\x22\xe5\x7b\x9c\x48\x63\xe9\xee\xa5\xc3\x13\xeb\x4f\x50\x22\x63\x2b\xc7\xf6\x10\x7b\x91\xde\x01\x11\xde\x33\xc5\xb2\xc7\x69\x4a\xd7\xff\xd3\x1a\x67\x3f\xd8\xb1\xa7\xad\x03\x1a\x7a\xc2\x91\x55\x57\x21\x27\x89\xa7\x72\x6f\xd0\x3a\x36\xe1\x89\xba\x6f\x7b\x6f\x5d\xf7\x7e\x2f\x05\xa2\x8a\xfa\x07\x6d\x21\x50\xcb\x0c\x4b\xdf\x90\x15\x3b\x14\x43\x89\x20\x3f\x88\x4e\xbe\xb1\xff\xe7\xc9\x27\x0f\x0e\xf7\xde\x6a\xee\x3b\x77\x63\x0d\x44\x35\xe9\x81\xf6\xeb\xc0\xd3\x9e\x03\x17\xca\x81\x63\x71\xe0\xf2\x38\x70\x79\x1c\xa8\x9c\x0f\xdc\xf7\x1c\x78\x4a\x77\x30\xe7\x37\x23\xd1\x82\x4a\x66\x2d\x65\xad\x9c\x58\xb0\xca\xe1\xbb\xfb\x6c\x31\xd6\xa0\x6b\xe9\x20\xeb\x66\x6c\x48\x64\xe8\x20\x8b\xe6\x0f\xd6\xf5\xcc\x12\x1b\x36\xb5\x85\x9b\x70\x30\xe9\xaf\x48\x2a\x66\x40\xad\x07\x56\xf9\x02\xc9\x3d\xf8\x2d\xd2\x3f\xf6\x03\x3d\x23\x92\x05\xab\x6b\xe9\x9b\x1c\x38\xaf\x07\x99\xd4\x7b\x88\xcd\xc1\xbc\xee\x96\xef\xac\x59\xdd\x96\x8d\xdd\x33\xed\x9d\xc3\x16\x83\x37\x07\xee\x99\x0e\xf6\x6b\x2d\x23\x12\x7d\xef\x6a\xb3\x60\x32\x00\xf4\x68\xdd\x0d\x2b\x67\x4a\x84\x5e\x5a\xdb\xdf\x2d\x8e\x89\xe1\xd4\x1f\x13\x59\x93\xa0\x41\x76\xbd\xe1\xe0\xad\xe5\x81\xdf\x73\x09\x72\x1b\x99\x03\x8d\xe8\x41\x96\x68\x44\x29\x51\x66\x28\x89\x95\x17\x4e\x06\xf5\x44\xb4\x25\x29\xac\xbf\xee\x46\xc2\xc1\xbb\xa3\xff\x70\xd5\x21\xf9\x87\x49\x98\x8b\xc7\x1f\x19\x4a\x3f\xea\xa1\xa7\xbc\x70\xf4\xdf\x74\x1c\xfd\xed\xa7\xff\xd9\xd7\x87\x19\x0b\x48\xb9\x81\x03\x39\x02\xe9\x3a\x3a\x52\xc1\x1c\x69\x70\x8e\xf4\x66\x8e\xb2\x7a\x1e\xd0\xaf\xa3\xfe\x52\x97\x05\xa2\x8e\x54\xd5\x47\xae\x9c\xa3\x2c\x9b\x2f\x40\x8f\x18\xde\x23\xae\x17\x01\xcd\x98\x6f\x06\x37\xe9\x48\x5f\xef\xa4\x47\x54\x42\x8e\x34\x36\x47\x1f\x7f\x3b\xf2\x84\xfe\xc8\x5f\xb0\x3a\x9a\xcd\x69\x49\x32\xa2\x82\x65\xbf\xf2\xbd\x15\xbb\xbe\x62\x15\x3b\x3e\xdd\xb3\x85\x07\x5f\xed\x4f\x66\xbd\x10\x5d\x0d\x99\x01\x38\xf2\x7c\xf4\x48\x91\x3d\x8a\x38\x16\x86\xb4\xea\x84\x63\x0d\x1f\x53\x9a\x7c\xd2\x53\x2e\x6d\xb2\x79\x92\xc7\xce\x9d\xaa\x9f\xec\xe0\x28\xe3\x13\x15\x28\x3c\x51\xe3\x86\x53\x06\x15\x9e\x9f\x3e\xca\xfb\xd3\x76\xb6\x03\x92\x8c\xe8\xce\xe7\x29\x7c\x51\x25\x91\xda\x93\x9f\xfe\xdc\x1b\x64\x4e\xa4\xc7\x9f\x3f\x3b\xf7\xab\x0b\x3f\xfd\x39\xf6\xcf\xce\x7e\x34\xe1\xa7\xf8\xa5\x13\x20\xdd\x68\x7c\xe8\x06\x5c\xe4\xec\x43\x37\xc5\xba\xf2\x91\xd3\xf6\x3f\x3f\xbd\x27\xfe\xf1\x9b\x59\xfc\xb0\x10\x63\xc5\x9c\xa5\xf5\xdb\xed\x05\x3f\x3a\xfb\x22\xeb\xcc\x21\x3b\xd3\x17\x84\xe1\xd2\xcd\xc9\xd9\x3e\xa0\xca\x49\x74\xf4\xcf\xfe\xa3\xa5\xb3\x7e\xa7\x64\x45\xc5\xef\x94\xce\x5c\x79\x67\xce\xc8\x99\x1d\x38\xfb\xd6\x7f\x72\x19\x9e\xb9\xe6\xce\xd4\x32\x67\x7a\x4d\x67\xce\xd4\x99\xee\xfb\x99\x87\xce\x67\x4a\xce\x99\x7a\xe8\xdc\xb9\xaf\x26\xcf\x5c\x94\x67\x5c\xff\x21\xd2\x3e\xea\x75\xec\x33\x4d\xd6\xbf\xf8\x59\x39\xdf\xa8\x5f\x3e\x37\x00\x2f\x89\x1a\xb6\x73\xc5\xfd\xce\x99\xf1\x9b\x33\x9d\x9f\x33\x9d\x76\xa0\x29\x11\x7b\xe0\xae\x43\x21\x6c\xb4\x81\x46\x8c\xdf\xfb\x00\xa9\x27\x7b\xe1\x71\xcd\x85\xb1\xc2\x0b\xbe\x56\x02\xd2\xe3\x8b\x8b\x18\xd8\x7e\x4f\xbf\x15\xb2\xf2\xbf\xf2\x0d\xb5\x89\x17\x44\x00\x81\xd6\xf0\xb4\x2f\xb2\x4b\x9f\x02\x6d\xf9\xae\x4a\xc2\x85\x91\xc1\x8b\x98\x8e\x3b\xa0\x21\x9f\x66\xfc\xac\xe0\xc2\x1f\x7e\x8c\x86\x33\xfe\xe0\xd9\x05\xba\x81\x28\xb3\x96\xbb\x4b\x36\x17\x8b\x7e\x87\x17\xae\xbc\x87\x71\xa5\xe1\xb8\x52\xfa\xae\xd4\x33\x57\x04\xa0\x0c\xc9\x54\x5d\x29\x5c\x57\x5a\xb2\xab\xfd\xe2\xc3\x00\xa4\xf6\x28\x96\x3a\x23\x7a\x61\x3b\x5a\x3a\x66\x57\x7f\x22\x77\xa5\x23\x72\xf5\x91\xd5\xab\x74\x61\x45\x84\x06\x96\xcc\x29\x5b\x75\xcb\xa9\x7a\xfb\xea\x77\xba\x57\xc6\xa3\xae\xdc\xdf\xc7\xa3\x8e\x2b\x2f\xdb\x5f\x7d\x70\xff\xca\xaf\x94\xae\x8c\x37\x5d\xdd\xe0\x4a\xfc\x40\x92\x03\xc2\x85\x23\xa0\x50\x93\x6e\x07\x06\x3d\xb7\x31\x50\x34\x24\xaa\x7a\xf6\x9d\x19\xbe\x94\x8c\x77\xf0\x03\xba\x63\x41\xa5\xed\x8d\x71\x2f\x3f\xfe\x7a\xaa\xf2\x37\xa0\x47\xfb\xcd\x46\xbd\xbe\xaf\x0d\xaa\x59\x79\x2d\x66\x47\xd1\xc9\x50\x10\xdf\x80\x66\xac\x62\xc6\x52\xb8\x8d\x0a\x84\x3f\x6e\x14\xc8\xce\x92\xc3\x30\x5e\x81\x86\x4c\xbb\xb1\x2f\xb6\x71\xdb\x4c\x55\x4b\x20\xd0\x60\x7a\x72\x9d\x78\x92\x7a\x32\xf4\x04\x4e\x95\xdd\x22\xb1\x19\x52\x0e\x39\x50\x52\x11\x41\x0b\x2b\x41\xf0\x04\x44\x5d\x3b\x25\x39\x8b\xba\x75\xbf\x60\x17\xf8\x83\xc8\x8e\xdc\x7d\x96\xd5\x10\xd0\x93\xbb\x78\x1d\xf8\x33\xcb\xbd\x58\x9a\xba\xa8\x7a\x87\x13\x97\x56\x95\xc0\x46\x2b\x81\xf7\xa1\x3f\x2c\xa9\xdf\xe3\xa0\xee\x84\x1f\xc5\xda\xa2\x0b\x49\x43\x3e\x44\x2c\x4b\x11\xce\xbc\x40\x62\xf4\x57\x7f\x12\x2a\xe3\xdb\xaf\xf6\xb6\xee\x3d\x13\xfc\xb0\x6b\x4e\x84\x13\xb0\x64\x60\x97\x1c\x92\x01\x45\x31\x8e\xf1\xc0\xb6\x41\x4a\x6a\x8f\xe8\x63\x46\x47\x3a\x19\x50\xaa\xe2\x8c\xf0\xfc\x37\x19\xd8\x6f\x05\x24\x03\xbb\x85\xa3\xe8\x87\x28\xbb\x64\x60\x3f\xdb\x9b\x0c\x4c\x19\x24\xb8\x64\x56\xb8\x66\xe8\x31\x78\x82\x0b\x64\x37\x5c\x77\xa9\xed\x0b\x14\xbd\x3b\x67\x20\x67\xea\x87\x21\xdd\x7c\x24\xa9\x59\xd4\x24\x75\xb7\xab\x12\xba\xd4\x09\x4d\x7c\x82\xef\x9d\xc7\x40\x0c\xe2\x05\xf2\x0d\x8d\x4d\xdd\x01\x55\x82\x26\x20\x83\x6a\x9c\x84\xbf\x49\xa8\x73\x37\x20\x8a\x69\x3c\x0c\x53\xfe\x48\x54\x13\xf1\x06\x4d\xbc\xb9\x19\x7f\x78\x34\x19\x9a\xe3\x90\xd8\x4f\x03\x5a\x45\xb9\xed\x2c\x02\x99\x32\xf9\xde\x37\xab\xe4\xab\x95\x6f\xc9\xdc\xa3\x1c\xe8\x85\xed\x5e\xb2\xac\x57\x9c\x9f\x31\x0f\xfc\xbd\x64\x68\x76\x3b\xa0\xd4\xca\x4a\x32\x0b\x58\x29\xd1\x59\x46\xe4\x2f\x05\xca\x2d\xec\xa2\xe4\x9e\x08\xd6\x5b\xc9\x73\x4f\x57\x6b\xc2\xcf\x69\xf4\x0b\x18\x45\xaa\xc7\x6f\x28\x90\x37\xec\xc1\x8d\x85\xe2\xe4\xaa\x2c\x2a\x1b\x51\xb2\x46\xee\xf7\x90\x94\xcc\x98\x3b\xb7\x1f\x88\x51\xa2\xc9\x53\xa6\xc1\x37\x0b\x68\xc6\xe2\xe6\x4c\x9b\xb3\xd4\x25\xdf\xd8\x1a\xb2\x81\x1a\xd9\xc1\xc9\xc4\x72\x9b\xee\x1d\xf1\xc7\x76\x48\xc6\x7c\xfb\x2f\xfd\x39\x16\xb1\x35\xe0\x6c\x4c\x32\x62\x51\x13\xeb\xaf\x29\x10\x1c\xca\x84\x61\x1e\xbb\xdb\x1f\xc9\xd8\xeb\x5f\x90\x47\x22\x55\x76\x63\xfb\x60\xa5\x10\x82\x0b\x44\xfa\x3b\x5d\xc9\xa4\x8b\x5f\x66\x28\xf9\x42\xa4\x83\x03\x82\x1f\x71\x8b\xd9\xb0\x81\x55\xf2\x49\x92\x41\x35\x4e\xf4\x47\x49\xb4\x00\xbd\x9e\x10\xc9\xd4\x93\xc2\xaa\x8f\xbb\x01\x25\x51\xdc\x27\xde\xee\x4f\x34\x42\x25\x24\xe3\x62\xcd\xec\xfa\xbb\x22\x7c\x53\xab\x64\xce\xdc\xb9\xf8\x6c\x2a\xe7\x2d\xd0\xa3\xcc\xd8\x4d\x4f\x25\xde\x54\x4e\x46\x61\xcd\x28\x0d\x99\x6d\x28\x13\xfe\x36\x52\x82\x5f\x37\xfa\x42\xf4\x83\xe8\xc4\xac\xd8\xcf\xe0\xc7\x7f\x45\x6f\xe0\x27\x87\xfa\x44\x88\xb2\x2b\xd1\xc5\x9f\x9b\xa3\x9d\xc8\x0f\xb3\xc8\x4f\x6a\x83\xd4\xee\x57\x88\x55\xeb\xa6\xbd\xf8\x31\xfa\xff\x07\x00\x00\xff\xff\xaa\x0a\xcc\xb8\xdf\x5e\x00\x00") - -func keysWordsWordlistJapaneseTxtBytes() ([]byte, error) { - return bindataRead( - _keysWordsWordlistJapaneseTxt, - "keys/words/wordlist/japanese.txt", - ) -} - -func keysWordsWordlistJapaneseTxt() (*asset, error) { - bytes, err := keysWordsWordlistJapaneseTxtBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "keys/words/wordlist/japanese.txt", size: 24287, mode: os.FileMode(420), modTime: time.Unix(1523115814, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _keysWordsWordlistSpanishTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x34\x5b\xbb\x76\xfc\x2e\xaf\xed\x79\x4b\x8c\x65\x8f\xe6\x00\xe2\x27\xc0\x2b\x99\xb7\x49\x99\x62\x8a\xff\x4a\x97\xd6\x2f\x76\xd6\xde\xe4\x2b\x46\x98\x3b\xe8\x2e\x60\xee\xaf\x2d\x26\x0b\x71\xdb\xad\x48\x0d\x71\x93\x67\x0c\x71\x53\xf1\x81\x52\x3b\xe3\xce\xb4\x12\xae\x42\x8f\x2f\x26\xea\x21\x6e\x53\x32\x32\xb3\x5b\x88\x29\x6e\xd1\x91\xec\x52\x34\x86\x98\x92\xb0\x38\xe9\xfd\x53\x43\x4c\xa2\x43\x90\xe4\x13\x95\x52\x31\x5a\x92\x36\xa2\x87\xfb\x2b\x29\x66\x4a\x39\x3a\xc7\xa8\xf7\x77\x88\xc9\x4e\x41\xc6\x38\xcc\xd0\x8b\x09\x81\xeb\x0b\xc9\x64\xe3\xb9\x2b\x13\x71\x8e\x31\x3b\x4a\x77\x65\xd3\xbd\xe8\x40\xed\x6e\x9c\x28\xee\xe6\xd8\xcc\x3e\x63\x8d\x48\x32\x1a\xdd\xdf\x2e\x16\xe2\x21\x89\x6d\x0e\xfd\x5b\xf2\xa1\x75\xe5\xbd\x70\x91\xa7\xe6\x10\x4f\x65\xa3\xd3\xea\xfd\x8e\x48\x3b\x86\x38\x6d\x95\xba\x9c\x2b\x55\x14\x4e\x34\x98\xbb\xa1\xef\xd4\xcc\x1c\x30\xfc\xb0\xd3\x00\xdd\x2d\x44\x75\x09\x51\x7b\x46\xbf\xa7\xec\x2e\x2f\xa4\x58\xe5\x73\x76\xa0\x2c\xc7\xe4\xf7\x57\xc5\x47\xd9\x9c\x05\x5e\x62\x88\x79\x8b\xe1\xfe\xca\xdb\x2c\x21\xe6\x14\xf3\x8e\xaa\x5d\x50\x23\x27\xdb\xc9\x13\x83\x66\xf1\xc1\x42\xc2\x43\x33\xb0\x4a\x2a\xe4\xd3\x76\xee\x34\x2b\x29\x9d\x75\x91\x25\xeb\x85\xf5\x67\xce\x52\xc8\x14\xb9\xdc\x6f\xd2\x37\x8f\x05\xe5\x85\xd2\x45\x15\x62\x31\x8f\xe9\x28\x9a\x05\x6b\xcf\x2f\x34\x2b\x71\xcb\x82\xa4\x0e\x26\xcd\x80\x84\x12\x1d\xfb\x2f\xb1\x13\xad\x65\xfb\x4b\x14\xc3\x14\x6e\xbd\x28\x5b\x68\x1f\x71\x0f\xb1\x18\xc6\x6a\x11\xe8\x2a\x2d\x63\x6d\x35\x3d\x08\x35\x56\xa6\x18\xb7\xee\x98\xb3\xee\xf7\x77\x0d\xb1\x92\x0b\xef\xaf\x7a\x4e\xf0\x68\xd5\x9c\x41\x87\xaa\x05\xb9\xfb\xdd\x43\xac\x8b\x68\x75\x08\x98\xa1\x0e\x3d\x27\xea\x86\x3d\x91\xcc\x98\x01\x49\x97\x3a\x6b\xc2\xac\xf7\x7f\x91\xcc\x76\xff\x27\x4f\x66\x2d\xc4\x16\x49\xf2\x16\x3d\x62\xfd\x4d\x06\xf7\xd1\xd0\xbe\x65\x4d\xac\x34\xa0\xb7\x99\x03\x0d\xcd\x3e\x91\x71\xa9\x3b\x28\xd1\xdc\x88\xd8\x36\xa5\x83\x42\x6d\x62\x9b\x4e\x82\x38\x66\x0c\x14\x8a\xfb\xcb\x37\x1d\x6e\xfc\xb0\x1c\xa2\x6f\x93\xac\xe7\xe9\x41\x22\x38\x24\xd9\x39\xa4\xef\x9a\x81\x10\xdf\x27\xdb\x0b\x10\xe1\x14\x31\x57\xe9\x21\x7a\xf9\x63\x5f\xaf\xf7\x37\xf2\x06\x52\x7b\x23\x20\x47\xb8\xcb\x09\xbc\xb9\xdb\x0b\x70\x82\x5f\xb8\x7c\x1f\xca\x75\x76\xfe\x30\x66\x5f\x0c\xd0\x93\x54\x88\x6a\x97\x73\x52\x8c\xbb\x30\xd7\x41\xbd\xfe\xc7\x5a\x5d\x33\x61\xa7\x58\x76\x10\xaf\x5b\xd9\xb8\xaf\xde\x04\x5b\xef\x63\xad\xbe\x8f\x95\x9b\xec\x37\x0b\x3b\x4c\x8e\x32\xe2\x93\xf0\xdf\x14\x24\x1e\xe2\x58\xc3\x0f\xc1\x40\x43\x81\x8b\x41\x8e\xbf\xbf\x86\x81\xe4\xc3\x23\x50\x33\xb8\x9f\x71\xff\xd6\x10\xe7\x1e\x5f\x80\xa0\xd4\x3c\x25\xc4\x89\x69\x67\x59\x43\xcd\x2e\xe4\xda\x39\xb0\xfe\x0b\xdc\x70\xc5\x9a\x04\x09\x16\x76\xe1\x4b\x72\xa6\x26\xb9\x64\xc1\x3e\x7c\xbe\x42\xbc\x96\x02\xb9\x14\xf8\xf8\xc4\xbc\x9f\x73\x8f\x80\xd8\xf0\x2b\x1e\x4b\xa0\x29\x23\x2f\xc3\x2c\xaf\xfb\x97\x9c\xf2\x9a\x07\x44\xf7\x35\x73\xd8\xe2\x16\x01\xcc\xc3\x16\xd3\x43\xc2\x16\x1f\x20\xda\x16\x35\x23\x03\xe1\xde\x62\x8e\xf5\x85\xb2\x9c\x30\xe5\x46\x35\xb0\xc5\xb2\xdd\xbf\x61\x8b\x35\x19\xe0\x8e\x06\x60\xd6\x2d\x3a\xc7\x74\x96\x7b\xd5\x17\x12\xb7\xb0\xdd\x5f\x3d\x61\xfb\x5b\xec\x63\x0d\xd4\x21\xce\x5b\x1c\x31\xb3\x78\x88\xaf\xc9\x41\xb8\x2d\x8e\x39\x38\xe8\x2f\xd6\x89\x7d\x6c\xb2\xdd\xdf\x80\x8a\xd9\x04\xd2\xb6\x49\x67\x45\xe7\xe7\xd0\x18\x36\x85\xd8\x6e\x2a\x35\x6c\x5a\x4f\x0b\x5b\x5e\x6b\xcc\x06\x52\x6e\x79\xf6\x18\x36\xc3\x6f\xd3\xca\xc4\xc2\x66\x09\x5f\x69\x15\xec\x04\x72\x22\x59\x25\x99\x00\xac\xb3\x59\x66\xff\x82\x4d\x5a\xdd\xe3\x8e\x04\xe2\x48\x1b\xb6\x59\xed\xf7\x97\x86\xcd\x1c\x48\x32\x07\x97\x6e\xd6\x39\x35\xa8\xb0\xd9\xb8\xdf\x35\x6c\xf7\xcf\x25\x9c\xe7\x15\x73\xd8\x3c\x5e\x16\x96\xdd\xdb\x5c\xd2\x23\x22\xb9\x24\x6c\x4e\x9d\xb2\xb9\x72\x0b\xae\x98\xdb\xb9\x58\xca\xd3\xe6\x06\x76\xd9\x9c\x43\x3b\x34\xff\xe6\xb3\xb3\x2d\x78\x7a\x9b\x49\x08\x41\xcd\x09\xb5\xb7\x4d\xf9\x0c\xdb\x3c\x16\xc5\xe6\x41\x42\xdc\xbf\x40\xd9\xd4\xe1\x68\x96\xd9\xd1\x37\x8e\x36\x3d\x13\x62\xeb\xb3\x83\x7f\xb6\x39\x22\x16\x30\x5f\xe8\x0b\x93\x8c\x25\xa6\xb8\x41\x5d\xa7\x48\xa4\x26\x18\xf1\x90\x62\x8a\xa8\xd9\xef\xaf\x4b\x1c\x1f\xc2\x3a\x7e\x1f\xf7\x77\x48\xf1\x7e\xef\x28\xd1\x02\x66\x4d\xf1\x89\xcc\x73\x8d\x9b\xf1\x83\x22\x47\x0a\xd5\x08\xfb\x43\xa8\xc0\x7a\x8a\x39\x0b\x60\x41\x9f\x6c\x6c\x76\xa1\x9e\x05\x65\x63\x8f\x22\x6b\x71\x45\x2b\x93\x66\x21\xdd\x5f\x35\x71\x09\x75\x57\x4c\x52\x25\xa3\x47\x3d\xa1\x15\x53\xac\x9a\x98\x1d\xc8\x40\x37\x02\xae\x25\xd9\x86\x9c\xf5\x90\x62\x8b\x2f\x40\x1d\x6b\xe1\x0d\x04\x48\x91\x1e\x40\x8a\x6d\x82\x84\x29\x12\x07\xbe\xb1\xf3\xfd\xe5\x49\x30\x9d\x43\x65\xa4\xe8\x27\xa1\x42\x66\x52\xf4\x8a\xee\xde\xfe\xea\xb8\x10\xe7\x77\x27\x48\x28\xe8\xc2\xf2\xde\x58\x34\xb8\xe5\x61\x9e\xd0\x15\xa4\x4b\x50\x37\x98\x62\xb2\xd3\xcb\x42\x92\xcd\x20\x5b\x49\xa0\xb4\x93\xec\x18\x40\x32\x70\x7e\x7f\x67\x81\xa9\x4f\x92\xe1\xfd\x20\x3f\xd9\x72\xe9\xa6\x24\x55\x41\x4f\xa9\x83\x7d\x1c\x48\xa1\xfb\x93\xc4\x49\x69\x59\xe5\x60\xf0\x24\x4e\x63\x9d\xee\xef\xde\x64\x0f\x49\xd8\xe9\x11\x49\xc5\x47\xcc\x92\x98\x2d\xed\xfe\x45\x4a\x5b\x9a\x1e\xb1\x11\x3a\x33\xca\x26\x0a\x77\x64\x59\x9b\xf4\xa0\xc0\xa6\x87\x61\xe4\xc7\xa4\xaa\x4d\x8f\xd9\x30\xa1\xa6\x4c\xac\xaa\x9c\x06\x98\x09\x59\x00\x1f\x32\xe9\x01\xdc\xeb\xb9\x50\xa9\x60\x09\x8a\x50\x52\x20\x5a\x2b\x86\xd2\xe6\xb0\x4c\x49\x9d\x15\x3e\xc9\x07\xda\xd9\x82\x0d\x26\x19\x2d\xd3\x39\x48\x39\x56\x00\x8c\x97\x63\x17\xc0\x0b\x50\xa9\xc3\x53\xe6\x24\xf9\x7e\x2f\xfe\x31\xe2\xd6\xfe\x5c\xd3\x64\xe9\x41\x0e\x5c\x2a\x26\x19\x66\xbc\x7f\x76\xb8\x20\x09\x86\x3b\xd9\xc1\xf6\x70\x47\x93\x3d\x04\x23\xda\x13\x9a\x22\xc1\x55\x48\xd0\x40\xc9\x32\xd9\xca\xb2\x9c\xca\x32\x78\x05\xc9\xf2\x1a\x32\xe7\x95\x2b\xac\x9a\x85\x85\x05\x5a\x15\x29\xc7\x2d\x4a\xca\xff\x94\x35\x65\x69\x40\x92\xd5\x1d\x2d\xaa\x70\x9e\x7a\xb2\xc8\x28\x21\x56\xfb\x5f\x29\xf9\xda\x40\x2f\x6b\x0a\xe8\x71\x89\xbf\x39\xf4\x37\x52\xa8\xdd\x64\xbe\xff\x15\x1b\xe7\x77\xe7\x38\x7d\xc1\x02\xd1\x31\x98\x76\xba\x9b\x62\x4c\x07\x2a\x5d\x22\x61\x5a\x99\xfb\x8d\x15\xba\x14\x36\x7d\x03\x2a\xe2\x87\xe4\xda\xd8\x5d\xbb\xf6\x90\x1c\x76\x37\xf9\xfd\xb3\x90\xee\xe0\x18\x56\x4f\x76\x9f\xaf\x90\x66\x24\xd3\xcf\x48\xbe\x98\x91\x9c\x39\x37\x02\x44\x18\x09\xb2\x0a\x3c\xcc\xa5\x2a\xe6\x62\x7f\xb8\xfa\x2c\xe4\x6a\xa7\x5c\x80\x0a\xef\x2f\x4d\x08\x0e\xb2\xb9\x11\xb2\x39\xdd\xe6\x34\xe1\x3a\xa2\x09\x36\x3f\x2b\xd7\x32\x8d\xb0\x2d\x2d\xf0\xdb\x28\x65\xf4\x5e\xd2\x74\xa5\xec\x4d\x5f\x90\x93\x0c\xed\x61\x87\x12\xdb\x69\x76\x31\xe5\x1e\x21\x78\x3b\xbc\x8e\x1c\x76\xd9\xc4\xc3\x7e\x7f\x6f\xc8\xdc\xdf\x29\xee\x31\xec\x92\xd4\xc3\x2e\x68\x26\x87\xd4\x8e\xa2\x43\x2b\x0b\x61\xc5\x77\xc9\x07\xd8\x69\x47\x70\xc4\x56\x19\x46\x6b\x97\x62\x8e\xb6\x70\xab\x76\xa9\x23\x62\x82\xe5\x45\xee\x02\x53\x84\x62\x77\xec\x61\x97\xbe\xbc\x8b\x5d\xe0\x76\xed\xd2\xe1\xe8\x23\xad\x93\x23\xf6\xa1\xab\xf6\xba\xdf\x48\x07\x55\xf4\x2e\x43\x2a\x56\x2c\xf0\x4f\x76\x10\x73\xd7\xb8\x65\x43\xb2\x83\xc2\xbb\xfe\xb9\xef\xbb\xc2\xd3\xd9\x35\x22\xb6\xd9\x75\x9b\x4f\x24\x0c\x99\xf6\x25\x66\xbb\x02\xa7\xbb\xca\x2b\xec\x7a\xdc\xef\x04\x1c\xe8\x89\x69\x35\xaf\xb1\xf2\xc4\xa6\xb5\x42\x3f\xed\xea\x82\x20\x6d\x57\xd7\x93\xc5\xd0\xa4\xbb\x76\x81\xda\xdd\xb5\x1f\x1e\x31\xd2\x85\x8e\x17\x57\x6f\x08\x27\x76\x4b\x00\xb0\x2a\xbb\x15\xba\x11\xbb\x55\xfc\xb0\x14\xa3\xe7\xbc\x9b\xc3\x5f\xdc\x0d\xc4\xdb\xad\xe3\x07\xd2\x79\x3c\x41\xea\xdd\xed\x8c\x61\xa7\x25\xd8\xb9\x73\x46\xb2\xfb\x5c\x53\xcf\x8c\x19\xee\x5f\x7c\x42\xcd\xed\xe4\x88\x7d\x52\xb7\xee\xb0\x44\xf7\xf7\x86\xc0\x43\x36\x20\x03\x3e\x81\x07\xa8\x51\x01\x47\x9b\x07\x81\x6e\x92\xfd\x2f\x90\x94\x5d\x11\x53\x1a\x3e\x06\x6b\x27\x6c\xb5\x1c\xdc\xbe\x1c\x9a\xe2\x2b\xc8\x53\xf0\x2b\x2d\x5b\x90\x2c\x07\x71\x2e\xd0\x26\x8e\x64\x29\x7e\xc9\x72\xa1\x67\xd6\xd6\x25\xdc\xdf\x59\xd9\x48\x3f\xd8\xc8\xa0\x79\x24\x33\x1e\x96\xb2\x81\xee\xb2\xe2\x5f\x29\xf6\xb7\x94\xd2\xa0\x73\xa4\x34\xee\x14\xd3\x09\x13\x97\x1e\x83\x54\x6e\xaa\x26\x06\x68\x52\xd3\x63\x1e\x82\x14\x7c\x21\x88\xa8\x58\x0c\xe2\x49\x3d\x80\x67\xa9\x87\x78\x41\x7a\xd2\xc1\x94\xaa\x67\x41\xdb\x1c\x13\x7a\x9a\x17\x24\x2e\x6c\xdb\xe3\x27\x13\xb9\xff\xc3\x2e\xea\x58\x23\x0d\x67\xee\x82\xe2\x96\x4a\xfe\xbc\xbf\x1b\x1c\x29\xf9\x37\xb5\x59\x10\xd7\x97\x05\xe9\xf0\x39\x90\xc0\x53\x91\x0e\xbd\xeb\x48\x5d\x37\xe5\x07\x77\xdc\x05\x51\x61\x90\x7e\x88\x33\x99\xe2\xec\xdd\x20\x8b\xd2\x1b\xb4\xa6\xf4\xc6\x3d\xf5\x66\x9d\xc9\xc4\xaa\xfb\xbf\x79\xbf\x03\xb4\x0a\x86\x03\x9e\x10\x8b\xa0\xf5\x98\x47\x0c\x32\x60\x14\x65\x88\x57\xac\x70\x40\xad\xc9\xa8\x98\xec\x62\x5c\x28\x57\xcc\x13\x7d\xaf\x45\xad\x8b\x67\x05\xf2\xc1\x63\x0b\xf9\x40\x6c\x1b\xe4\x83\xe7\x22\xf2\x91\xe0\x08\xc8\xc7\x6a\xf9\x41\x09\x90\x0f\x45\x70\x2b\x1f\x2b\x3c\xba\xbf\x3f\x94\x95\x8d\x76\x53\x3e\xfe\xc2\x49\xf9\x68\x06\xa1\x95\x8f\xe1\x52\x2c\x1c\xf7\xd7\xe6\x58\x0c\x3e\xa0\xc1\x8e\x98\x1e\xd8\xec\x71\x7f\x41\x06\x0f\xcc\xef\xe1\x88\xc0\xdb\x01\x3f\xee\x88\x70\x33\x0e\x3a\x87\x47\xcc\x9d\x10\x6b\x3d\xa0\xdb\x8e\x58\x34\x2b\x53\x63\x95\x47\xf0\xce\x11\xbd\xc4\xc4\x72\x37\x8c\xea\x1d\xdf\x5d\xc2\x11\x87\x9e\xf8\x9e\x9c\xe0\xe2\x64\x1f\xe1\x80\x0f\xe3\x16\x0e\x3a\xcd\x87\x64\x7d\x85\x43\x90\x77\x8c\x22\x08\xc5\x8e\xfb\xdb\xa1\x38\x0f\x71\x76\x93\x4e\x17\xfc\x50\x9e\x1c\x1c\x4a\x35\x7b\x28\x96\xa6\x50\xec\x87\xfe\x59\xed\x43\x39\xa8\xee\x18\x50\xe9\x2d\x1d\x2a\x19\x80\xcd\x68\x1b\x0e\x45\x28\x1a\x0e\x7d\x72\x80\x27\x9a\x02\x3f\x9a\x61\xc4\x0f\xec\x12\x3d\x32\xec\xce\xa1\x18\xb4\x02\x8d\x5a\x41\x0d\x68\xe8\x81\x72\x07\x4e\x72\x4c\x06\x88\xb8\xe7\xc8\x6b\x47\x50\x41\x47\x36\x96\x40\xb1\x1d\x19\x4a\xf1\xc8\xf7\x2f\x2a\x6c\xc3\x2e\xc1\xc6\x87\x9d\xb0\xc3\x87\x51\xf9\x1c\x06\x22\x1f\x96\xb3\x60\x78\xab\x3b\x20\x27\xe1\x89\xd0\x61\x3e\x88\x48\x73\x04\x56\x07\x38\xf4\x30\x34\xf5\x98\x22\x08\xe2\xeb\x2c\xea\xf0\x58\x41\x4c\x27\x0d\x3c\xce\x1d\x89\xdc\x6f\x47\x52\xd1\x10\x52\x7d\x38\x24\xea\x70\x6e\xc6\xb9\xfe\x09\xcf\xec\x98\xd4\xda\x94\x0f\x94\x81\x82\x13\x2e\xfd\x31\xeb\x1f\x8e\x27\x02\x91\x63\xfa\x5a\xf7\x24\xd9\x66\xc7\xd4\xf7\xef\xd8\xc0\x04\x73\x40\x1d\x9e\x31\xc1\x3f\x3b\xe3\x11\x7b\x38\x23\x1c\xb4\x13\x21\xfa\x19\x59\x9a\x57\xec\x78\x92\xdf\xce\x88\xf0\xec\x8c\xd0\xd6\xe7\x3a\xc7\x39\x23\x3c\x9b\x33\xc2\xce\x9d\xd1\xe3\x53\x90\xbc\x50\xd4\x97\x07\x75\x46\x0a\xe5\x19\x07\x5a\x5c\x9a\xe1\xd9\x9f\x52\xa0\xb5\x4f\x81\xaa\x3f\xa5\x86\xf3\xfe\xa6\x72\x3a\xa5\x2a\xe1\x90\x70\x8a\xc7\x95\xf3\xff\xe5\x21\x86\xa7\x74\x0c\xa5\x27\xf5\xec\xa9\xa5\xc6\x8e\x56\x0a\x5d\x74\x2a\x06\xc9\x60\x76\x0f\x67\x46\x10\x7a\x66\xc3\xee\x4f\xcb\xf8\x1d\x06\x08\xe1\x38\x2d\x37\x09\x27\xe2\xbd\xd3\xe0\x08\x9c\xe6\x60\xb1\x13\xd1\x65\x38\xc1\x1b\xa7\x0d\x41\x39\x88\x79\x3a\xe4\xf2\xf4\xfb\xeb\x80\x4f\x7d\x3a\x14\xee\xe9\x08\x24\x4e\x8f\xf0\x2e\x4e\x87\xe7\x7a\x3a\x6d\xe9\xb9\x42\xcc\xd3\xb5\xb1\x0c\xd5\x20\xe3\xe9\xd6\x0d\xa3\xdd\xbf\x68\x34\xa1\x51\x4e\x9f\x85\xb0\x59\x38\xe7\xda\xd6\x8c\x2b\xe3\x3b\xd6\x3e\x85\x6b\x9a\xa4\xc5\x64\x70\x73\x4e\xb5\x0a\xd8\xf9\x3d\xe2\x6a\xd1\xb9\xac\x49\x9c\x3f\x22\x5c\x9a\xc7\xfd\x05\x97\xe6\x11\xb7\xcc\x32\xb8\x82\x0f\xa8\x99\x40\x4d\xf3\x88\x79\x95\x17\x84\x9f\x8f\xe8\x20\xda\x23\xbe\xf0\x63\x9c\xf6\x90\x8d\xa7\x3a\x0f\xba\x67\x0f\xfa\x2e\x0f\xc9\xb0\x21\x0f\x81\x3c\x3c\xa4\xac\x1a\xf8\x7d\x0f\xf1\x82\x25\x3c\xee\x6f\x37\x41\xf6\x42\x29\x43\x89\x87\xc2\xe5\x09\x8f\xfb\x4d\x5f\xe9\xa1\xa7\x4a\x95\xf0\x80\x74\x3f\xb4\xa0\x97\x22\xfe\xd2\x18\x1e\x96\x80\xe5\x87\xc1\x17\x7f\x18\x10\x80\xc2\x27\x00\x7d\xc2\x87\xc1\x7b\x78\x58\x35\xd4\x57\xd6\x2e\x50\xa0\xd0\x1e\x3c\x2d\x7e\x18\xac\x40\x78\xd8\xa7\x85\xc7\x84\x99\x7f\x4c\x9e\x62\x3f\x26\x4f\x56\x1f\x44\xff\x63\xca\x05\x08\x2f\xfe\x01\x65\xf0\x98\x7f\x5b\xf8\x2d\xb0\x7e\x8f\x59\x34\xef\x82\x14\x99\xba\xb3\x89\x47\x44\xbc\xf8\x18\x16\x14\xbe\x7d\xd0\x5d\x62\x0e\xba\x2b\x78\x0a\xae\x76\xb6\xa0\x67\x96\xae\x11\xe9\xfd\x1b\xf4\x9c\x68\x91\xe5\x64\x32\x3b\x85\x55\x4b\x84\x0c\xac\x68\x5d\x0b\x4d\x8f\x96\xb6\xa0\xc0\x4f\xd1\xb2\xec\x86\x96\x36\xa1\xf3\xa1\xec\x10\x2a\xdf\xef\xba\x6b\x92\x00\xb7\x6c\x20\xa1\x22\xd5\x7a\xd0\x7a\x6b\x5d\xe2\xa4\x95\x3e\x8c\xd6\x42\x7f\x54\x6b\x99\x15\xb5\x15\x32\xa9\xb5\xd3\x99\xd1\xda\x07\x59\x4f\x61\xdc\x11\xc1\xdd\xef\x3a\xb4\xa0\x66\x00\x2b\x5a\xef\x5f\x60\x53\xeb\xa5\xb4\xa3\xea\x31\x28\x38\x5b\x7d\x9d\x49\x6a\xcf\x04\x08\xda\x9f\x71\x8b\xf9\x7e\x23\xc5\x16\x9f\xb1\xac\xc4\xe3\x86\x4a\xdf\x61\x2b\x9e\x64\xda\x27\x4f\xef\x9e\xf1\x55\x58\x26\x87\x84\xa7\xb8\x42\xb1\x3c\xb5\x42\xdd\x3f\xcd\x2b\x78\xf5\x69\x6e\x1b\x92\x4b\x6a\x78\xda\x67\x0c\xcf\x29\x88\xf8\x9f\x53\x2e\xe9\x48\x5e\xe1\x39\x4f\x7a\x72\xcf\x79\x1a\xc0\xe4\x08\x93\x28\x78\x4e\x44\xab\xcf\x59\x4f\xcc\x38\xeb\x2a\x02\xbe\x9f\xf7\x6f\x53\x84\x4c\x4f\x7a\x8c\x4f\x9e\xd0\x3e\xe7\x25\x55\x73\x78\xce\x17\xf8\xf0\xff\xe0\x51\xfc\x9f\x41\x33\xe6\xb8\xa9\x05\xe8\x19\x42\x47\xc9\x8e\xcf\x1d\x51\x53\xc8\xf1\x64\x60\x94\xef\xaf\xd3\x11\xc1\xe6\x78\xc2\x30\xe4\x08\xae\xce\x11\x71\x63\xbe\xbf\x0a\x64\x0d\x69\x8b\x1c\x81\x2d\x2a\x44\x33\xc7\x7a\x32\xa2\x5b\x87\x84\xf9\xfe\x6a\xfa\x0a\x99\xde\x5d\x8e\x88\x68\xf2\xfd\xd5\xc7\x1a\x7a\x30\x37\xe4\x03\xdf\xea\x21\xc7\xe9\x92\x43\x8e\xf0\x38\x73\x7c\x59\xc8\x60\xcc\x2c\x7f\x06\x18\x36\x50\x00\xe1\x5b\x64\xc1\x5a\xe4\xfc\xab\x39\x57\xc8\x95\xe5\x09\x11\xc8\x52\xcf\x19\x91\x60\x33\x70\xfe\x00\xd9\xd0\x1a\xa3\x27\x70\xf7\x2a\x18\x9c\x62\x60\x23\x72\x61\x84\x4f\x81\x0d\xca\xba\x41\xd6\x76\x7c\xb8\x85\xac\x09\x93\xde\xef\x1d\xd3\x2a\x82\x92\x80\x58\x1f\x8b\x84\xe0\x66\x3d\x85\xcd\xb0\xb3\xfb\x5d\xe0\x26\x67\x25\xf3\x64\x2d\x0d\xe8\xd6\x9a\x50\x06\xe3\x9b\xef\x77\x15\x74\xaa\x50\xd5\x48\x59\x0f\x3f\x8f\xdd\xff\x4d\x45\x2b\xe8\xc8\xcc\xb3\x6f\xb8\xdd\xce\x84\x23\xc1\x7b\xc8\x20\x16\x60\x21\xe4\x4e\x79\x06\x91\x33\xaf\x84\x72\x96\xba\x12\xa2\x33\x9b\xaf\xe4\xc2\x06\xf2\xbc\x34\x06\xda\x99\xfc\xe7\xa8\x67\x4b\xcc\xc0\x7d\xc9\xf7\xcf\x09\xf7\x2e\xdb\x89\x99\xa0\xba\x40\x46\x84\xd7\xd9\xe0\x01\x50\x56\x32\xa3\x99\x3c\x11\x6b\xe6\xc9\x39\xe1\x8d\x64\x72\xcc\xac\xd2\x43\x9e\x0d\x9f\x3c\x57\xcf\x13\x2b\x9c\xaf\x50\x62\x82\xa5\x29\x11\x1a\xb9\xc4\x1d\x1b\x2b\x71\x77\x01\x84\x6d\x2f\x51\xd8\xa3\xc4\x43\x51\x75\x2e\x88\x82\xfb\x8d\xfe\x19\xc1\x4e\x59\xf7\x4b\x85\xa7\xc5\x25\x66\x54\x97\xfb\x0b\x70\xe3\xf7\x1c\xa1\xf0\xac\xb7\x44\xe0\xbc\xc4\xca\xd0\xb7\xd0\xf4\x97\x58\x95\xbe\x77\x81\x47\xc3\x52\x36\xe9\x84\x1c\xf7\xfe\x0f\x8c\x5d\xe0\x81\x97\xfb\xeb\xdf\x54\xe6\xd0\xd4\x39\xa8\x0b\xf3\x87\x66\x24\xd0\x84\x25\xf2\xca\xa3\xdc\x5f\x5e\x8c\xa5\x94\xaa\x12\x7d\x48\x47\xf2\x42\xbf\xce\xf1\x3a\xcf\x03\x4b\xec\x7a\xa1\x70\x70\xe0\x41\x3f\xb5\xc4\xa1\xd8\x26\x2f\x1d\xcb\xfd\xf5\x01\x6d\x56\xe2\xa7\xa1\xc9\xcb\x3c\xc5\x50\xe8\x0e\x16\xd9\xd7\xee\x65\x57\x4c\xfb\xbd\x4f\xe6\x9e\xba\x4a\x9f\xe8\x21\xe0\x03\x24\x5c\x0a\x02\x7c\x4c\x81\x40\x09\xb0\xc3\xf5\x29\xf4\x53\x8a\xd4\xfb\x37\x14\xf1\x04\x95\x50\xe0\xbd\x9c\x53\x30\x2c\x3d\x80\x82\x2d\x48\x5f\xa3\x00\x41\x08\x4b\x50\x3b\x8c\xcd\x49\x31\x79\x25\xcc\xac\xb0\x3f\x05\x3a\xbd\xa8\xf0\xae\x85\xd6\xad\x00\x55\x9a\xe3\xc9\x82\x4c\x83\x51\x34\xaf\x95\x71\x93\xc4\xf1\x0a\xd6\xa1\x55\xff\xca\xc0\x39\x45\xad\x49\x28\xf4\x96\x8a\x02\x87\xda\x17\xb6\xb4\x73\xd8\xce\xb6\x90\xd8\xc2\xe5\x5a\x7a\xc0\x2d\xfa\x5f\x1c\x5a\x6c\x47\x66\x87\x41\x2f\x06\xce\x33\xd2\xdd\x60\x22\x8b\x65\xe1\x37\x04\xb1\xd8\x0a\x7d\x8b\x15\x0c\x8f\x20\x3f\x31\x15\x8e\x00\xf6\x2f\xb6\x1a\xc0\xa1\x29\x46\x0f\xab\x18\x6f\xc2\x8a\xd1\x0f\x06\x96\x99\x71\x7e\x77\xd6\x43\xd3\x14\xeb\x1c\xac\x33\x04\x2d\xc6\xeb\xcc\x42\xa1\x2c\xf7\xcf\x85\x9d\x18\xb8\x64\x52\x38\xe6\x8e\x46\x53\x10\x99\x14\x1e\x48\x96\x49\x8b\x59\x26\x44\x04\xd9\x13\x72\x33\x9f\xe8\x4f\xe2\xaf\x83\xd1\x32\x33\x21\x19\x7f\xde\xff\x09\x26\x9d\x8e\x05\x50\xc2\xee\xdf\x9e\x26\x30\x31\xbb\x10\x9e\xab\x50\xd9\xae\x67\x0b\xf5\xfe\x42\xe4\x57\xe3\x42\x1f\xec\x18\x72\x70\x0b\x6b\x5c\x61\x40\x8d\x60\xd0\x1a\x79\xe8\x5b\x63\x8f\x39\xd4\x38\x16\xc4\xb6\x6a\x1c\x9c\xb2\xde\x5f\xb3\x0b\xda\x5f\xac\xbc\x30\xc4\xc5\x63\xfb\x2a\xb0\x44\xf5\xfe\xe6\xa9\x4e\xa5\xe2\xaa\x72\x1a\x4b\x05\x7c\x52\xa9\xb7\x2b\xfc\x31\x64\x06\xc0\x1c\xac\xb8\xd8\xf8\x82\xfe\xa8\xbc\xe6\xa9\x90\xbe\xaa\xb2\x65\x94\xb0\xad\xde\xff\xc9\x8b\x09\xa6\x79\x8f\xd5\xe2\x92\x1c\xaa\x6d\x59\x5e\x31\x54\x83\x55\xa9\xf7\x0f\x99\xaf\x52\x3c\x2a\x83\xa3\xca\x73\xaf\x0a\x8f\xba\xda\xd0\xc4\x8a\x0b\xce\x47\xb5\x0b\xc4\xa8\xc6\x45\xcd\x4d\x42\x9d\x29\x86\x7a\xff\xa6\x2c\x28\xd9\xe9\x45\xf3\x20\xac\xd2\x07\xac\xb0\xf4\x80\xaf\x50\x27\xd1\xfb\x5b\xc0\xe5\x75\x0e\x4c\x68\xb1\x6b\x0f\xc6\x9b\x2b\xdb\xb4\x37\x24\x4f\xec\xc0\xe0\xa3\xda\x0a\x6b\x6d\xeb\xe2\xd8\xb5\x6d\xeb\x10\xcd\x36\x2c\x00\x01\x9f\x31\x4e\xb3\x74\x7f\x43\x91\x61\x4b\x50\x62\x06\xac\x10\x99\x96\x5c\x82\xa5\x11\x2f\x7c\x8f\xb9\x31\xcb\xd3\x4a\x4b\x3c\x44\x87\xe6\x07\xd3\x1a\x6d\x9b\x41\xa3\xd8\xae\xa0\x9b\xf1\x64\xc2\xd6\x39\xa2\x1d\x74\x41\x6d\x9d\x2f\xd9\xb1\xce\x68\x69\x27\x8c\xc7\xb4\x86\x68\xd0\x9e\x16\x2c\xc7\x60\x59\x20\x1c\x96\x0f\xa0\xcd\x32\xd8\x82\x57\x10\x3c\x98\xe6\x89\x9a\xe5\x0b\x44\xb1\xb2\x65\x3d\x2d\x18\x8c\xaf\xc1\x79\xb0\x86\x00\xd8\xda\x62\xc0\xfb\xa7\x01\x8f\xd6\xf8\x44\xc2\x96\x5f\xb9\xde\x58\xdc\x3f\x8d\x27\x23\xc6\x0b\x6d\x0b\xe6\x7f\x4c\xcb\x93\x39\x47\x92\xc3\xfd\xe3\x1b\xa2\x44\xaa\x4f\xc8\x2a\xaa\xe5\x19\x51\x71\x12\x67\x7e\xc2\x19\x34\x3f\x27\x68\x67\xbe\x8e\x18\xcd\xf5\x64\x5b\xea\x54\xc3\x36\xfd\xdf\x3a\x07\x36\xde\x51\x5b\x8f\x3c\xc5\xb4\x9e\x20\x5a\xd6\xe5\x85\xd1\x40\x0d\x8a\xa8\x0d\xaa\x09\x03\xcf\xda\xb5\x66\xbc\xc0\x02\xf7\xcf\x07\x37\xfe\x71\xbf\x4f\xe8\x0c\xfb\x5c\x13\xbe\xe0\x93\x37\x9e\xe0\x34\x9a\xc5\x16\x05\x73\x37\xc4\xe0\x35\x86\x06\x53\xd8\xe2\xfd\xee\x28\x7a\x46\x47\x2e\xf3\x8a\xad\xc5\x9c\x98\x83\x0e\x68\xf7\x57\xc6\x04\x8d\x97\x62\x2d\x66\x5b\x09\x88\xdd\x62\xc5\x2f\x66\xb4\xaa\xca\x4e\x95\x2e\x46\x8b\xf7\x7f\x3c\x9a\x6c\xb1\xdd\x5f\x80\x92\x01\xb9\xfd\x16\xff\xd1\x2d\x6d\x7c\x20\xd0\xa2\x33\x08\x6f\xd1\x65\x07\x54\x96\x19\xc6\xf4\x16\x39\x35\x70\xc5\xbc\xc7\x83\x79\xf6\xee\xec\x0d\xd5\xd3\xe2\xf2\xc3\x1a\xd8\xb7\x21\xe6\x0e\x2d\x2e\xa0\x28\xa0\x74\x34\x5e\x61\x35\x9e\x84\x34\x70\x70\x8b\x9f\x6c\x2f\x91\x57\xc7\x4d\x68\xb2\x1a\x58\x31\x22\x79\x20\xb3\x63\x77\x82\xa8\xa7\x51\xaf\x34\xd1\x2a\xa1\x49\xe6\x77\xde\x79\x7c\xd8\x24\x0b\xba\x64\x05\x07\x37\xc9\x59\x9e\x4c\x09\x20\xd4\x0d\xe6\xb3\x81\xf7\xd1\x6d\xdd\xfd\x35\x59\xd0\x50\xd4\x60\x34\x9a\xfc\x5b\x47\xb9\x6d\x2d\xc1\x61\x9f\x9b\xd0\x26\xb4\x75\x45\xd6\x84\xbe\x02\x22\xa3\xc4\x76\x99\x65\x45\xb9\x13\xe7\xf4\xde\x8d\xb3\x75\x02\xcc\x7e\x7f\x77\x58\xc1\x06\x8e\x83\x1f\xdb\xee\xef\x11\xb9\xba\xe1\xf7\x0f\xb4\x4d\x93\x17\x7e\x93\xb5\x3c\xae\x6b\x9a\x1e\x5c\xa0\x0a\x7e\x3b\x56\xa4\xf4\x2d\x9b\x72\x25\xfa\x84\xd7\xd8\x94\xa8\xd0\x6c\x60\x35\x2d\x4a\x9d\xb1\xb6\xa3\x15\x4e\x76\xd3\xca\xe6\x6b\x68\x08\x75\xd3\x86\x4f\x27\x8d\x94\x38\xd1\xce\x5b\xac\xc6\x7d\xd0\x5b\x6d\xba\xc8\xa2\x2f\xec\x20\xc7\x05\x2b\xc0\xe0\xe7\x27\x21\x86\xce\x02\x63\xdd\x32\x04\xa0\xd1\xc1\x6c\x79\x62\x6d\x99\xa6\xa3\xf1\xe2\xac\xc1\x35\x6d\x46\x5c\x52\x31\x35\x13\xb4\x31\xe9\x90\xbc\x66\x64\x77\xcb\x52\x01\x35\xad\x42\x48\x71\xb3\x0c\x76\xb1\x02\x2d\xd4\x8c\xa7\x37\x8d\xb3\x58\xc1\x46\xa8\x45\x9a\xf9\xd2\x17\x6d\xd9\xe8\x06\x91\x46\x65\x17\xd6\x76\x85\xfd\x6d\x06\x2d\xd8\x6c\xac\xd3\xde\x46\x81\x6e\x30\xd6\x8d\x17\x00\xcd\x25\xd9\x0b\xc9\x39\x89\x47\x97\xa2\x2c\x86\xda\x6c\x0e\xd5\xde\x5c\x2e\x96\x91\xa4\x7e\xbf\x6b\x82\x41\x6d\xae\x7f\x52\xe0\x0a\xf5\xde\xdc\xd0\x83\xaf\x74\x9a\x5b\x5a\x5d\x6d\x9f\xd4\x09\x6e\xa4\xa1\xdb\xc1\x87\x2e\xcd\xed\x74\x92\xd3\x0d\xcb\x74\x2b\x64\x1f\xa7\x8f\xd2\xdc\x1a\x67\x84\xb6\xe1\xa4\x53\x36\x70\xd1\xef\x96\xc9\x86\x33\x3d\x60\x5a\xda\x84\xa6\x6c\x70\x35\x90\xa1\x8e\xff\x53\xa7\x6d\xe6\x13\x99\x0c\x49\x9a\x99\x31\x4d\x9b\xb9\xb1\x06\x2b\x23\xbd\xf8\x4c\xa6\x81\x09\x33\x13\x64\x80\xe1\x09\x2e\x0b\x6d\xfa\xfd\x1d\xfe\x4d\x81\x17\xf1\x6f\x42\x0b\xfe\x9b\x52\x56\xc6\x85\x49\xb7\xf0\x6f\xd2\x6a\xc3\x31\x2f\xd0\xe8\x70\xba\x93\x20\x81\x9e\xf7\xfb\x8b\x77\x20\x1e\x37\x8d\x80\xf8\x5c\x94\xf3\xb8\x6b\x8a\x39\x38\x23\x04\xa2\xc3\x23\x28\xec\xeb\xbc\xcf\x11\x97\x06\xe7\xe1\x83\x23\x28\xdd\x99\x1b\x80\x9d\x35\x9d\x8d\x59\xf0\x09\xf0\x42\x96\x97\x9a\x2e\xff\x7b\x52\xe8\xf2\xf7\xda\xc0\x65\xbd\x6e\x71\xe1\x2b\x0e\x17\xbe\x62\x80\x29\x1c\x31\xf0\xc5\xc6\x0b\x95\xeb\x02\xd7\x25\xb9\x30\x3b\x08\x79\xbd\x07\x8d\xe9\xb2\xf3\x28\xd6\x65\x67\x0c\xe5\x72\x50\xfb\xb8\xac\xc3\x59\x97\xf5\x6a\xc7\xe5\x98\xa7\xa2\xfc\x84\xe4\x3b\x6f\x68\x5c\xce\x8c\x26\x27\x19\xcb\xe5\x71\x7f\xa3\x25\x84\x77\x1d\xc8\xd2\xb8\xb9\x64\xee\x49\xb2\x5c\x4c\x14\x6e\x88\x43\xcd\xb1\x61\xb6\x67\x70\xd2\xc1\x65\x45\x11\x3c\xdf\x77\xa9\x08\x77\x5d\x78\x68\xe4\xd4\x0b\x2e\x8d\x67\x03\x2e\x4d\x06\x4b\x9b\x71\xe6\x36\x34\x07\x97\x8e\x5f\x8a\x44\x47\x87\x42\x70\xe9\x4d\xd8\xa1\x2f\x38\x8b\x60\x89\x43\x1d\xd9\xc1\xa3\x2e\x47\xe4\xcd\xea\x59\x39\xe8\x75\x7f\x63\xa4\x8b\x8a\xc4\xe5\x33\x40\x77\x7a\xa0\xce\x74\xde\xef\xc3\x30\xef\x11\x09\x29\xa7\x47\x0c\x7e\xbf\x4f\x92\x54\x4f\x2c\x5b\x2b\x9f\x26\xb9\x2e\x6d\xcd\xd3\x68\xd7\x7f\x13\x72\xc3\x47\x33\xae\x03\xbb\x84\xea\xe1\x45\x8f\xf3\x9a\x0f\x92\x06\x00\xff\xc7\x6d\x5f\x10\x94\xb3\xf5\xba\xcd\x0d\xd4\xb4\xe7\xea\x01\x42\x19\x7d\x38\xb7\xd2\x58\x53\xf1\xc3\x3a\xe9\xc4\xb8\x35\x82\xd5\x04\xb3\xd2\xf7\x77\x63\x70\xeb\x7c\x0a\xe8\x73\xbb\xdf\x80\x58\x36\xbc\x45\x87\x88\x04\x9f\x24\x31\x4f\x01\x9c\x81\xa7\x2f\xbf\xde\xe1\x38\xf8\x44\x84\xeb\xb3\xb0\x53\xe3\x2b\x48\x9e\xb2\xfb\x1c\x68\xdb\x21\x27\xbb\x85\xce\x73\xd4\xce\x23\x9f\xce\xdb\x8d\x1e\x61\x1e\x7a\x3c\xe3\x0b\xd0\x57\xab\x1c\x01\xd6\x27\x16\xdb\x23\x44\xbd\xc7\x25\xea\x3d\xe6\xbf\xa4\xb3\xdd\x60\x83\xb9\x03\x5e\x1c\xad\x6c\xa8\xf8\x3b\xc1\xef\xb1\xd2\x1d\xea\xb1\x0a\x6b\x2b\x22\x94\x1e\x2b\x05\x87\xc7\xbc\x9d\x87\x15\x3d\x36\x00\xf8\x07\x3d\xfa\xce\x85\x47\x1f\x60\xe3\x1e\xfb\x60\x27\x3e\xa7\xe9\xbc\xe4\xe9\xf1\xc3\xf8\x3c\xa9\xff\xef\x38\xa8\x4b\x32\x00\xb0\x12\xd2\x11\x43\x97\x3d\x74\x39\x27\x96\x2f\xda\x43\xe7\x25\x7e\x97\x7c\xa1\xae\x20\x9e\xef\x52\x48\xcc\x4e\x26\xea\x52\xa1\x43\x79\x3f\x98\x99\x30\xb7\xfc\x9b\x2e\x4d\xd1\xe4\x1f\xcf\xaf\x3b\x70\x29\xae\x02\xb8\x30\xb3\x0e\x89\xbb\x74\x0a\x48\xff\x3b\x52\xea\xc2\xcc\xf8\x2b\xbc\x88\x52\xf9\x20\xc0\x4a\x15\xf6\xb8\xaf\xeb\xa2\xae\x70\xa7\xba\x9e\x58\x26\x2f\xae\xfb\xfd\xce\x11\x08\xd5\x0c\xf5\xdf\x35\x0b\x5f\x82\xf6\xb5\xea\xfb\x5d\x36\x63\xe3\xc2\x42\x87\x77\xd2\xb5\x0f\x18\xc4\xce\xe3\xa1\xae\x7c\xa6\xdc\x69\x3a\x3b\xbd\xff\x4e\xab\xd9\x2d\xe3\x17\x5b\x44\xb2\x93\xf8\x96\x79\x73\xdc\xef\x1f\xfa\x8a\xdd\x78\x29\xd7\x2d\xcf\x3f\x24\x1b\x0f\xc9\xbb\x55\x48\x42\xb7\xba\x5a\x55\x38\xc2\xdd\x2a\xa5\xa9\x1b\x47\x6c\x99\x3d\xd7\x6b\x81\xce\xab\x89\x6e\xbe\xee\x79\x3b\x0a\x91\xef\x8b\xc0\xf7\xcf\x20\x27\x4c\x04\x83\x7d\x6e\x40\xe3\xa4\x9d\xeb\x34\x44\x7d\xca\x89\x69\xe9\x89\xf6\xe5\x59\xf5\x15\xfa\xf6\x79\x38\x9b\x33\x3c\xea\x33\x2f\x26\xe1\x3d\x52\x9f\x70\xbf\x98\x92\x85\xe7\x32\xf0\x7d\x36\xaa\xb5\x3e\xf1\xed\x89\x5f\x7f\x63\xfa\xc9\x86\x9d\x63\x41\x93\x8d\xc8\x27\xea\x23\x6e\xd0\x18\x48\x73\x04\xbc\x7f\xc3\x58\x15\xd0\xe3\x7c\x0f\x3a\x22\xb6\x3c\xe8\x74\x8f\xb8\x4e\x1b\xd7\xeb\xc5\xb1\x84\x66\xc4\x42\x3b\x31\x62\x81\x84\x0f\x5a\xa1\x11\xeb\x1a\xb8\xa1\x5d\x03\x03\x8c\x08\x4e\x1b\xb1\xad\x4e\xff\xa6\xae\x41\x7c\x47\x9d\x0b\xbf\xa1\xe8\x46\xf4\x27\xd8\x6b\x44\xb7\x01\xe8\x18\xcf\x59\x32\x66\x7c\xa2\xf9\x64\xd9\x0b\x45\xb4\x5f\x43\xf8\xca\x65\xd0\x2d\x1e\x92\x30\xf2\xfd\x9d\xf8\x46\x66\xc8\x13\x6c\x30\xe4\x29\x0e\xa8\xcc\xa0\x85\xe4\xfb\xfb\x40\x24\x42\xce\x1a\x02\x65\x33\xd6\x63\x81\x21\x35\xbe\x00\x77\x76\xaa\x0b\x6a\x07\xec\xa8\x36\x5e\xbe\x21\x9c\xe0\xb6\x04\x18\x1f\xf7\xb7\xf3\xd9\xdd\x10\xaf\xd0\x58\x03\x2e\x2f\x7a\x76\xf6\xec\xc6\x35\xf6\x81\x20\x70\x08\x63\x91\x41\x81\x19\xf2\x0a\x43\xa1\xc4\x86\x6e\x93\x27\x6a\x43\xa5\x34\xe4\x29\xc4\x43\x79\xcd\x34\x14\xfc\x33\x14\xfa\x66\xe8\x93\x03\xf0\x02\x64\x28\xcf\x86\x07\x9c\x0a\xec\x0f\x7e\xd0\xe0\xa3\xaf\x01\xcb\x30\xee\x77\x83\x75\x19\xca\x21\xd9\xed\x6f\x16\xb2\xd6\xb8\xdf\x43\x56\xff\x01\xf5\x3b\x14\xb8\xb5\x45\x67\xdb\x18\xe9\x0f\x83\x62\x1d\x96\xb8\x43\xc3\x2c\x76\xa2\x3a\xf3\xb3\xb0\x92\x55\xe4\x11\x6b\x2c\x68\x12\x06\x5f\xb5\x8d\xfb\xc7\xe3\x47\x18\xc6\x30\x7f\x98\x17\x2a\x0f\x98\x48\x61\x9e\xa0\x09\x07\x73\xac\x85\xcf\x4c\x86\xf9\x98\x9c\xa6\xe3\x87\x3d\xf0\x6d\xd5\x80\xb3\x87\x9c\xc7\x8d\x7c\xea\xeb\x3e\x7e\xbd\x48\x1e\xff\xbb\x0b\x1c\x8e\x48\x72\xf0\xf6\x73\x78\x2c\xfc\x86\xbf\xb5\x4c\xf2\xf0\x08\xcf\x6e\x38\x5f\xdb\x0e\xbf\xbf\x37\xcb\x61\xc0\xbf\x45\xa9\x2c\x0c\xba\x54\x00\x6e\x08\x4e\xc0\x70\xdd\x26\x20\x87\x46\xb4\x30\x9c\xcf\xf8\x86\xeb\xac\x07\x0a\xed\x10\x26\x85\x95\xb4\x98\x83\xc6\x72\xf0\xe1\xea\x70\x38\xd5\xc3\x27\xcb\xf9\x4c\x75\xf8\x04\xf3\xcf\x6d\x5d\xeb\x8e\xb9\x59\x18\x93\x6f\x14\xc6\x84\xf9\x19\x34\x86\xe3\xfe\xad\x92\x99\x90\xb9\xa7\xf3\xf9\xe9\x98\xce\xd3\xc1\x31\xe1\x71\x0c\x3e\xaf\x9e\x1b\x23\xa5\xfb\x37\x33\x66\x9c\xd0\x72\x39\xcc\x65\xa5\xe8\x8a\xcc\xaa\x17\xe2\xb1\x30\x2b\x7e\x50\x8b\x0c\xb1\xa6\xd3\x09\x9d\xbe\x49\x98\xbe\xae\x7c\x27\x62\x2b\xfe\x0d\x64\xf6\xc9\xe7\x4a\xeb\xce\x69\x0e\xe3\xab\x8f\x79\xc5\x70\x21\x0c\xba\x62\x02\xcb\x5d\x91\x6f\xc2\x2e\x3e\xe4\xbf\x40\x85\x2b\x2a\x0b\xd6\xd1\xed\x15\xb3\x84\xeb\x2f\x7e\xbf\xf8\x6e\xea\xe2\xa3\x56\x94\x5d\x93\x2d\x4a\x83\x1f\x75\x45\x47\xc6\x95\x03\x91\x6d\x2f\x84\xc6\x97\x90\x15\xaf\x75\x59\x72\xc9\xe3\x7e\xf3\xc0\xef\x02\xd9\x24\x5c\xf2\x94\x57\xe0\x21\xd6\x25\x34\xfa\x97\x64\x43\x09\x56\x21\x7c\x11\x7b\x51\xb8\x2e\xa9\xc2\x81\x2a\xd7\x2a\x40\xcd\x45\xee\xbc\xa4\xce\x1e\x2e\xb6\xe4\xad\xf2\x25\xbe\x11\xee\x98\xc0\x85\xbd\xfd\x49\xc8\x25\xf9\x40\x63\x20\xe4\x52\x30\xdd\xa5\x1b\xb4\xf5\xc5\xa3\xa4\xeb\x7e\x27\x5e\x0c\x5d\x8a\x8e\xf7\x1b\x06\xe7\xd2\x1d\xd8\xbc\x14\x7e\x31\xef\xef\xa4\x87\x8b\x5e\xde\xa5\x19\x3f\xec\x40\x6b\x84\xd0\xf3\xc5\xd6\xa5\xf7\x7f\x90\x93\x4b\x2d\xdf\xef\x1a\x2e\x05\x61\x2f\x75\x20\x59\x7d\xcc\x3d\x5c\xda\x89\xca\x77\x67\xb0\xbe\x5c\xcd\x4b\x47\xe4\x09\xe0\xa5\x93\xdd\xaf\xf8\x02\x24\x6e\x14\x76\xfe\xd2\xcb\xc2\x65\x99\xf7\xa7\x97\x65\xba\xb3\x97\x65\x62\xc0\x1c\xcd\xe9\xd3\x5d\x08\xa7\x2f\x20\x93\xd6\xeb\x9a\x7c\x98\xf9\xc9\x0b\xec\x4f\xf8\xc7\x9f\x94\xa0\x4f\xe8\xd5\x4f\xde\x48\x7e\x42\x71\x7d\x42\x6b\x7c\x42\x6b\x7c\xda\x39\x3d\xbc\xe2\x01\x02\xbf\x78\xd4\xfa\x8a\x0d\x22\xf9\xe2\x1b\x85\x97\x55\x00\xe8\xfe\xd7\x2c\x00\xb0\xb5\xff\x1f\x00\x00\xff\xff\x11\x91\x1a\xde\x5b\x35\x00\x00") - -func keysWordsWordlistSpanishTxtBytes() ([]byte, error) { - return bindataRead( - _keysWordsWordlistSpanishTxt, - "keys/words/wordlist/spanish.txt", - ) -} - -func keysWordsWordlistSpanishTxt() (*asset, error) { - bytes, err := keysWordsWordlistSpanishTxtBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "keys/words/wordlist/spanish.txt", size: 13659, mode: os.FileMode(420), modTime: time.Unix(1523115814, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -// Asset loads and returns the asset for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func Asset(name string) ([]byte, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) - } - return a.bytes, nil - } - return nil, fmt.Errorf("Asset %s not found", name) -} - -// MustAsset is like Asset but panics when Asset would return an error. -// It simplifies safe initialization of global variables. -func MustAsset(name string) []byte { - a, err := Asset(name) - if err != nil { - panic("asset: Asset(" + name + "): " + err.Error()) - } - - return a -} - -// AssetInfo loads and returns the asset info for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func AssetInfo(name string) (os.FileInfo, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) - } - return a.info, nil - } - return nil, fmt.Errorf("AssetInfo %s not found", name) -} - -// AssetNames returns the names of the assets. -func AssetNames() []string { - names := make([]string, 0, len(_bindata)) - for name := range _bindata { - names = append(names, name) - } - return names -} - -// _bindata is a table, holding each asset generator, mapped to its name. -var _bindata = map[string]func() (*asset, error){ - "keys/words/wordlist/chinese_simplified.txt": keysWordsWordlistChinese_simplifiedTxt, - "keys/words/wordlist/english.txt": keysWordsWordlistEnglishTxt, - "keys/words/wordlist/japanese.txt": keysWordsWordlistJapaneseTxt, - "keys/words/wordlist/spanish.txt": keysWordsWordlistSpanishTxt, -} - -// AssetDir returns the file names below a certain -// directory embedded in the file by go-bindata. -// For example if you run go-bindata on data/... and data contains the -// following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png -// then AssetDir("data") would return []string{"foo.txt", "img"} -// AssetDir("data/img") would return []string{"a.png", "b.png"} -// AssetDir("foo.txt") and AssetDir("notexist") would return an error -// AssetDir("") will return []string{"data"}. -func AssetDir(name string) ([]string, error) { - node := _bintree - if len(name) != 0 { - cannonicalName := strings.Replace(name, "\\", "/", -1) - pathList := strings.Split(cannonicalName, "/") - for _, p := range pathList { - node = node.Children[p] - if node == nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - } - } - if node.Func != nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - rv := make([]string, 0, len(node.Children)) - for childName := range node.Children { - rv = append(rv, childName) - } - return rv, nil -} - -type bintree struct { - Func func() (*asset, error) - Children map[string]*bintree -} -var _bintree = &bintree{nil, map[string]*bintree{ - "keys": &bintree{nil, map[string]*bintree{ - "words": &bintree{nil, map[string]*bintree{ - "wordlist": &bintree{nil, map[string]*bintree{ - "chinese_simplified.txt": &bintree{keysWordsWordlistChinese_simplifiedTxt, map[string]*bintree{}}, - "english.txt": &bintree{keysWordsWordlistEnglishTxt, map[string]*bintree{}}, - "japanese.txt": &bintree{keysWordsWordlistJapaneseTxt, map[string]*bintree{}}, - "spanish.txt": &bintree{keysWordsWordlistSpanishTxt, map[string]*bintree{}}, - }}, - }}, - }}, -}} - -// RestoreAsset restores an asset under the given directory -func RestoreAsset(dir, name string) error { - data, err := Asset(name) - if err != nil { - return err - } - info, err := AssetInfo(name) - if err != nil { - return err - } - err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) - if err != nil { - return err - } - err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) - if err != nil { - return err - } - err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) - if err != nil { - return err - } - return nil -} - -// RestoreAssets restores an asset under the given directory recursively -func RestoreAssets(dir, name string) error { - children, err := AssetDir(name) - // File - if err != nil { - return RestoreAsset(dir, name) - } - // Dir - for _, child := range children { - err = RestoreAssets(dir, filepath.Join(name, child)) - if err != nil { - return err - } - } - return nil -} - -func _filePath(dir, name string) string { - cannonicalName := strings.Replace(name, "\\", "/", -1) - return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) -} - From a589e0eabd113cb6f788e8f24b75870c11816937 Mon Sep 17 00:00:00 2001 From: Liamsi Date: Wed, 20 Jun 2018 14:09:24 -0700 Subject: [PATCH 271/287] delete keys package - it will be moved to cosmos-sdk --- keys/bcrypt/base64.go | 35 ---- keys/bcrypt/bcrypt.go | 292 -------------------------- keys/bip39/wordcodec.go | 62 ------ keys/bip39/wordcodec_test.go | 15 -- keys/hd/fundraiser_test.go | 83 -------- keys/hd/hdpath.go | 168 --------------- keys/hd/hdpath_test.go | 73 ------- keys/hd/test.json | 1 - keys/keybase.go | 362 --------------------------------- keys/keybase_test.go | 383 ----------------------------------- keys/keys.go | 12 -- keys/keys.toml | 2 - keys/mintkey.go | 115 ----------- keys/types.go | 142 ------------- keys/wire.go | 16 -- 15 files changed, 1761 deletions(-) delete mode 100644 keys/bcrypt/base64.go delete mode 100644 keys/bcrypt/bcrypt.go delete mode 100644 keys/bip39/wordcodec.go delete mode 100644 keys/bip39/wordcodec_test.go delete mode 100644 keys/hd/fundraiser_test.go delete mode 100644 keys/hd/hdpath.go delete mode 100644 keys/hd/hdpath_test.go delete mode 100644 keys/hd/test.json delete mode 100644 keys/keybase.go delete mode 100644 keys/keybase_test.go delete mode 100644 keys/keys.go delete mode 100644 keys/keys.toml delete mode 100644 keys/mintkey.go delete mode 100644 keys/types.go delete mode 100644 keys/wire.go diff --git a/keys/bcrypt/base64.go b/keys/bcrypt/base64.go deleted file mode 100644 index fc3116090..000000000 --- a/keys/bcrypt/base64.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bcrypt - -import "encoding/base64" - -const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" - -var bcEncoding = base64.NewEncoding(alphabet) - -func base64Encode(src []byte) []byte { - n := bcEncoding.EncodedLen(len(src)) - dst := make([]byte, n) - bcEncoding.Encode(dst, src) - for dst[n-1] == '=' { - n-- - } - return dst[:n] -} - -func base64Decode(src []byte) ([]byte, error) { - numOfEquals := 4 - (len(src) % 4) - for i := 0; i < numOfEquals; i++ { - src = append(src, '=') - } - - dst := make([]byte, bcEncoding.DecodedLen(len(src))) - n, err := bcEncoding.Decode(dst, src) - if err != nil { - return nil, err - } - return dst[:n], nil -} diff --git a/keys/bcrypt/bcrypt.go b/keys/bcrypt/bcrypt.go deleted file mode 100644 index ce2b9f4bc..000000000 --- a/keys/bcrypt/bcrypt.go +++ /dev/null @@ -1,292 +0,0 @@ -package bcrypt - -// MODIFIED BY TENDERMINT TO EXPOSE NONCE -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package bcrypt implements Provos and Mazières's bcrypt adaptive hashing -// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf - -// The code is a port of Provos and Mazières's C implementation. -import ( - "crypto/subtle" - "errors" - "fmt" - "strconv" - - "golang.org/x/crypto/blowfish" -) - -const ( - MinCost int = 4 // the minimum allowable cost as passed in to GenerateFromPassword - MaxCost int = 31 // the maximum allowable cost as passed in to GenerateFromPassword - DefaultCost int = 10 // the cost that will actually be set if a cost below MinCost is passed into GenerateFromPassword -) - -// The error returned from CompareHashAndPassword when a password and hash do -// not match. -var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password") - -// The error returned from CompareHashAndPassword when a hash is too short to -// be a bcrypt hash. -var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password") - -// The error returned from CompareHashAndPassword when a hash was created with -// a bcrypt algorithm newer than this implementation. -type HashVersionTooNewError byte - -func (hv HashVersionTooNewError) Error() string { - return fmt.Sprintf("crypto/bcrypt: bcrypt algorithm version '%c' requested is newer than current version '%c'", byte(hv), majorVersion) -} - -// The error returned from CompareHashAndPassword when a hash starts with something other than '$' -type InvalidHashPrefixError byte - -func (ih InvalidHashPrefixError) Error() string { - return fmt.Sprintf("crypto/bcrypt: bcrypt hashes must start with '$', but hashedSecret started with '%c'", byte(ih)) -} - -type InvalidCostError int - -func (ic InvalidCostError) Error() string { - return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost)) // nolint: unconvert -} - -const ( - majorVersion = '2' - minorVersion = 'a' - maxSaltSize = 16 - maxCryptedHashSize = 23 - encodedSaltSize = 22 - encodedHashSize = 31 - minHashSize = 59 -) - -// magicCipherData is an IV for the 64 Blowfish encryption calls in -// bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes. -var magicCipherData = []byte{ - 0x4f, 0x72, 0x70, 0x68, - 0x65, 0x61, 0x6e, 0x42, - 0x65, 0x68, 0x6f, 0x6c, - 0x64, 0x65, 0x72, 0x53, - 0x63, 0x72, 0x79, 0x44, - 0x6f, 0x75, 0x62, 0x74, -} - -type hashed struct { - hash []byte - salt []byte - cost int // allowed range is MinCost to MaxCost - major byte - minor byte -} - -// GenerateFromPassword returns the bcrypt hash of the password at the given -// cost. If the cost given is less than MinCost, the cost will be set to -// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package, -// to compare the returned hashed password with its cleartext version. -func GenerateFromPassword(salt []byte, password []byte, cost int) ([]byte, error) { - if len(salt) != maxSaltSize { - return nil, fmt.Errorf("salt len must be %v", maxSaltSize) - } - p, err := newFromPassword(salt, password, cost) - if err != nil { - return nil, err - } - return p.Hash(), nil -} - -// CompareHashAndPassword compares a bcrypt hashed password with its possible -// plaintext equivalent. Returns nil on success, or an error on failure. -func CompareHashAndPassword(hashedPassword, password []byte) error { - p, err := newFromHash(hashedPassword) - if err != nil { - return err - } - - otherHash, err := bcrypt(password, p.cost, p.salt) - if err != nil { - return err - } - - otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor} - if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 { - return nil - } - - return ErrMismatchedHashAndPassword -} - -// Cost returns the hashing cost used to create the given hashed -// password. When, in the future, the hashing cost of a password system needs -// to be increased in order to adjust for greater computational power, this -// function allows one to establish which passwords need to be updated. -func Cost(hashedPassword []byte) (int, error) { - p, err := newFromHash(hashedPassword) - if err != nil { - return 0, err - } - return p.cost, nil -} - -func newFromPassword(salt []byte, password []byte, cost int) (*hashed, error) { - if cost < MinCost { - cost = DefaultCost - } - p := new(hashed) - p.major = majorVersion - p.minor = minorVersion - - err := checkCost(cost) - if err != nil { - return nil, err - } - p.cost = cost - - p.salt = base64Encode(salt) - hash, err := bcrypt(password, p.cost, p.salt) - if err != nil { - return nil, err - } - p.hash = hash - return p, err -} - -func newFromHash(hashedSecret []byte) (*hashed, error) { - if len(hashedSecret) < minHashSize { - return nil, ErrHashTooShort - } - p := new(hashed) - n, err := p.decodeVersion(hashedSecret) - if err != nil { - return nil, err - } - hashedSecret = hashedSecret[n:] - n, err = p.decodeCost(hashedSecret) - if err != nil { - return nil, err - } - hashedSecret = hashedSecret[n:] - - // The "+2" is here because we'll have to append at most 2 '=' to the salt - // when base64 decoding it in expensiveBlowfishSetup(). - p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2) - copy(p.salt, hashedSecret[:encodedSaltSize]) - - hashedSecret = hashedSecret[encodedSaltSize:] - p.hash = make([]byte, len(hashedSecret)) - copy(p.hash, hashedSecret) - - return p, nil -} - -func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) { - cipherData := make([]byte, len(magicCipherData)) - copy(cipherData, magicCipherData) - - c, err := expensiveBlowfishSetup(password, uint32(cost), salt) - if err != nil { - return nil, err - } - - for i := 0; i < 24; i += 8 { - for j := 0; j < 64; j++ { - c.Encrypt(cipherData[i:i+8], cipherData[i:i+8]) - } - } - - // Bug compatibility with C bcrypt implementations. We only encode 23 of - // the 24 bytes encrypted. - hsh := base64Encode(cipherData[:maxCryptedHashSize]) - return hsh, nil -} - -func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) { - - csalt, err := base64Decode(salt) - if err != nil { - return nil, err - } - - // Bug compatibility with C bcrypt implementations. They use the trailing - // NULL in the key string during expansion. - ckey := append(key, 0) - - c, err := blowfish.NewSaltedCipher(ckey, csalt) - if err != nil { - return nil, err - } - - var i, rounds uint64 - rounds = 1 << cost - for i = 0; i < rounds; i++ { - blowfish.ExpandKey(ckey, c) - blowfish.ExpandKey(csalt, c) - } - - return c, nil -} - -func (p *hashed) Hash() []byte { - arr := make([]byte, 60) - arr[0] = '$' - arr[1] = p.major - n := 2 - if p.minor != 0 { - arr[2] = p.minor - n = 3 - } - arr[n] = '$' - n += 1 - copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost))) - n += 2 - arr[n] = '$' - n += 1 - copy(arr[n:], p.salt) - n += encodedSaltSize - copy(arr[n:], p.hash) - n += encodedHashSize - return arr[:n] -} - -func (p *hashed) decodeVersion(sbytes []byte) (int, error) { - if sbytes[0] != '$' { - return -1, InvalidHashPrefixError(sbytes[0]) - } - if sbytes[1] > majorVersion { - return -1, HashVersionTooNewError(sbytes[1]) - } - p.major = sbytes[1] - n := 3 - if sbytes[2] != '$' { - p.minor = sbytes[2] - n++ - } - return n, nil -} - -// sbytes should begin where decodeVersion left off. -func (p *hashed) decodeCost(sbytes []byte) (int, error) { - cost, err := strconv.Atoi(string(sbytes[0:2])) - if err != nil { - return -1, err - } - err = checkCost(cost) - if err != nil { - return -1, err - } - p.cost = cost - return 3, nil -} - -func (p *hashed) String() string { - return fmt.Sprintf("&{hash: %#v, salt: %#v, cost: %d, major: %c, minor: %c}", string(p.hash), p.salt, p.cost, p.major, p.minor) -} - -func checkCost(cost int) error { - if cost < MinCost || cost > MaxCost { - return InvalidCostError(cost) - } - return nil -} diff --git a/keys/bip39/wordcodec.go b/keys/bip39/wordcodec.go deleted file mode 100644 index b0c23e629..000000000 --- a/keys/bip39/wordcodec.go +++ /dev/null @@ -1,62 +0,0 @@ -package bip39 - -import ( - "strings" - - "github.com/bartekn/go-bip39" -) - -// ValidSentenceLen defines the mnemonic sentence lengths supported by this BIP 39 library. -type ValidSentenceLen uint8 - -const ( - // FundRaiser is the sentence length used during the cosmos fundraiser (12 words). - FundRaiser ValidSentenceLen = 12 - // FreshKey is the sentence length used for newly created keys (24 words). - FreshKey ValidSentenceLen = 24 -) - -// NewMnemonic will return a string consisting of the mnemonic words for -// the given sentence length. -func NewMnemonic(len ValidSentenceLen) (words []string, err error) { - // len = (ENT + checksum) / 11 - var ENT int - switch len { - case FundRaiser: - ENT = 128 - case FreshKey: - ENT = 256 - } - var entropy []byte - entropy, err = bip39.NewEntropy(ENT) - if err != nil { - return - } - var mnemonic string - mnemonic, err = bip39.NewMnemonic(entropy) - if err != nil { - return - } - words = strings.Split(mnemonic, " ") - return -} - -// MnemonicToSeed creates a BIP 39 seed from the passed mnemonic (with an empty BIP 39 password). -// This method does not validate the mnemonics checksum. -func MnemonicToSeed(mne string) (seed []byte) { - // we do not checksum here... - seed = bip39.NewSeed(mne, "") - return -} - -// MnemonicToSeedWithErrChecking returns the same seed as MnemonicToSeed. -// It creates a BIP 39 seed from the passed mnemonic (with an empty BIP 39 password). -// -// Different from MnemonicToSeed it validates the checksum. -// For details on the checksum see the BIP 39 spec. -func MnemonicToSeedWithErrChecking(mne string) (seed []byte, err error) { - seed, err = bip39.NewSeedWithErrorChecking(mne, "") - return -} - - diff --git a/keys/bip39/wordcodec_test.go b/keys/bip39/wordcodec_test.go deleted file mode 100644 index dbc5c0d02..000000000 --- a/keys/bip39/wordcodec_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package bip39 - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestWordCodec_NewMnemonic(t *testing.T) { - _, err := NewMnemonic(FundRaiser) - assert.NoError(t, err, "unexpected error generating fundraiser mnemonic") - - _, err = NewMnemonic(FreshKey) - assert.NoError(t, err, "unexpected error generating new 24-word mnemonic") -} diff --git a/keys/hd/fundraiser_test.go b/keys/hd/fundraiser_test.go deleted file mode 100644 index 63607b0a5..000000000 --- a/keys/hd/fundraiser_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package hd - -import ( - "encoding/hex" - "encoding/json" - "fmt" - "io/ioutil" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/tyler-smith/go-bip39" - - "github.com/tendermint/go-crypto" -) - -type addrData struct { - Mnemonic string - Master string - Seed string - Priv string - Pub string - Addr string -} - - -func initFundraiserTestVectors(t *testing.T) []addrData { - // NOTE: atom fundraiser address - // var hdPath string = "m/44'/118'/0'/0/0" - var hdToAddrTable []addrData - - b, err := ioutil.ReadFile("test.json") - if err != nil { - t.Fatalf("could not read fundraiser test vector file (test.json): %s", err) - } - - err = json.Unmarshal(b, &hdToAddrTable) - if err != nil { - t.Fatalf("could not decode test vectors (test.json): %s", err) - } - return hdToAddrTable -} - -func TestFundraiserCompatibility(t *testing.T) { - hdToAddrTable := initFundraiserTestVectors(t) - - for i, d := range hdToAddrTable { - privB, _ := hex.DecodeString(d.Priv) - pubB, _ := hex.DecodeString(d.Pub) - addrB, _ := hex.DecodeString(d.Addr) - seedB, _ := hex.DecodeString(d.Seed) - masterB, _ := hex.DecodeString(d.Master) - - seed := bip39.NewSeed(d.Mnemonic, "") - - t.Log("================================") - t.Logf("ROUND: %d MNEMONIC: %s", i, d.Mnemonic) - - master, ch := ComputeMastersFromSeed(seed) - priv, err := DerivePrivateKeyForPath(master, ch, "44'/118'/0'/0/0") - assert.NoError(t, err) - pub := crypto.PrivKeySecp256k1(priv).PubKey() - - t.Log("\tNODEJS GOLANG\n") - t.Logf("SEED \t%X %X\n", seedB, seed) - t.Logf("MSTR \t%X %X\n", masterB, master) - t.Logf("PRIV \t%X %X\n", privB, priv) - t.Logf("PUB \t%X %X\n", pubB, pub) - - assert.Equal(t, seedB, seed) - assert.Equal(t, master[:], masterB, fmt.Sprintf("Expected masters to match for %d", i)) - assert.Equal(t, priv[:], privB, "Expected priv keys to match") - var pubBFixed [33]byte - copy(pubBFixed[:], pubB) - assert.Equal(t, pub, crypto.PubKeySecp256k1(pubBFixed), fmt.Sprintf("Expected pub keys to match for %d", i)) - - addr := pub.Address() - t.Logf("ADDR \t%X %X\n", addrB, addr) - assert.Equal(t, addr, crypto.Address(addrB), fmt.Sprintf("Expected addresses to match %d", i)) - - } -} - - diff --git a/keys/hd/hdpath.go b/keys/hd/hdpath.go deleted file mode 100644 index 00d0572cc..000000000 --- a/keys/hd/hdpath.go +++ /dev/null @@ -1,168 +0,0 @@ -// Package hd provides basic functionality Hierarchical Deterministic Wallets. -// -// The user must understand the overall concept of the BIP 32 and the BIP 44 specs: -// https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki -// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki -// -// In combination with the bip39 package in go-crypto this package provides the functionality for deriving keys using a -// BIP 44 HD path, or, more general, by passing a BIP 32 path. -// -// In particular, this package (together with bip39) provides all necessary functionality to derive keys from -// mnemonics generated during the cosmos fundraiser. -package hd - -import ( - "crypto/hmac" - "crypto/sha512" - "encoding/binary" - "errors" - "fmt" - "math/big" - "strconv" - "strings" - - "github.com/btcsuite/btcd/btcec" - "github.com/tendermint/go-crypto" -) - -// BIP44Prefix is the parts of the BIP32 HD path that are fixed by what we used during the fundraiser. -const ( - BIP44Prefix = "44'/118'/" - FullFundraiserPath = BIP44Prefix + "0'/0/0" -) - -// BIP44Params wraps BIP 44 params (5 level BIP 32 path). -// To receive a canonical string representation ala -// m / purpose' / coin_type' / account' / change / address_index -// call String() on a BIP44Params instance. -type BIP44Params struct { - purpose uint32 - coinType uint32 - account uint32 - change bool - addressIdx uint32 -} - -// NewParams creates a BIP 44 parameter object from the params: -// m / purpose' / coin_type' / account' / change / address_index -func NewParams(purpose, coinType, account uint32, change bool, addressIdx uint32) *BIP44Params { - return &BIP44Params{ - purpose: purpose, - coinType: coinType, - account: account, - change: change, - addressIdx: addressIdx, - } -} - -// NewFundraiserParams creates a BIP 44 parameter object from the params: -// m / 44' / 118' / account' / 0 / address_index -// The fixed parameters (purpose', coin_type', and change) are determined by what was used in the fundraiser. -func NewFundraiserParams(account uint32, addressIdx uint32) *BIP44Params { - return NewParams(44, 118, account, false, addressIdx) -} - -func (p BIP44Params) String() string { - var changeStr string - if p.change { - changeStr = "1" - } else { - changeStr = "0" - } - // m / purpose' / coin_type' / account' / change / address_index - return fmt.Sprintf("%d'/%d'/%d'/%s/%d", - p.purpose, - p.coinType, - p.account, - changeStr, - p.addressIdx) -} - -// ComputeMastersFromSeed returns the master public key, master secret, and chain code in hex. -func ComputeMastersFromSeed(seed []byte) (secret [32]byte, chainCode [32]byte) { - masterSecret := []byte("Bitcoin seed") - secret, chainCode = i64(masterSecret, seed) - - return -} - -// DerivePrivateKeyForPath derives the private key by following the BIP 32/44 path from privKeyBytes, -// using the given chainCode. -func DerivePrivateKeyForPath(privKeyBytes [32]byte, chainCode [32]byte, path string) ([32]byte, error) { - data := privKeyBytes - parts := strings.Split(path, "/") - for _, part := range parts { - // do we have an apostrophe? - harden := part[len(part)-1:] == "'" - // harden == private derivation, else public derivation: - if harden { - part = part[:len(part)-1] - } - idx, err := strconv.Atoi(part) - if err != nil { - return [32]byte{}, fmt.Errorf("invalid BIP 32 path: %s", err) - } - if idx < 0 { - return [32]byte{}, errors.New("invalid BIP 32 path: index negative ot too large") - } - data, chainCode = derivePrivateKey(data, chainCode, uint32(idx), harden) - } - var derivedKey [32]byte - n := copy(derivedKey[:], data[:]) - if n != 32 || len(data) != 32 { - return [32]byte{}, fmt.Errorf("expected a (secp256k1) key of length 32, got length: %v", len(data)) - } - - return derivedKey, nil -} - -// derivePrivateKey derives the private key with index and chainCode. -// If harden is true, the derivation is 'hardened'. -// It returns the new private key and new chain code. -// For more information on hardened keys see: -// - https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki -func derivePrivateKey(privKeyBytes [32]byte, chainCode [32]byte, index uint32, harden bool) ([32]byte, [32]byte) { - var data []byte - if harden { - index = index | 0x80000000 - data = append([]byte{byte(0)}, privKeyBytes[:]...) - } else { - // this can't return an error: - pubkey := crypto.PrivKeySecp256k1(privKeyBytes).PubKey() - - public := pubkey.(crypto.PubKeySecp256k1) - data = public[:] - } - data = append(data, uint32ToBytes(index)...) - data2, chainCode2 := i64(chainCode[:], data) - x := addScalars(privKeyBytes[:], data2[:]) - return x, chainCode2 -} - -// modular big endian addition -func addScalars(a []byte, b []byte) [32]byte { - aInt := new(big.Int).SetBytes(a) - bInt := new(big.Int).SetBytes(b) - sInt := new(big.Int).Add(aInt, bInt) - x := sInt.Mod(sInt, btcec.S256().N).Bytes() - x2 := [32]byte{} - copy(x2[32-len(x):], x) - return x2 -} - -func uint32ToBytes(i uint32) []byte { - b := [4]byte{} - binary.BigEndian.PutUint32(b[:], i) - return b[:] -} - -// i64 returns the two halfs of the SHA512 HMAC of key and data. -func i64(key []byte, data []byte) (IL [32]byte, IR [32]byte) { - mac := hmac.New(sha512.New, key) - // sha512 does not err - _, _ = mac.Write(data) - I := mac.Sum(nil) - copy(IL[:], I[:32]) - copy(IR[:], I[32:]) - return -} diff --git a/keys/hd/hdpath_test.go b/keys/hd/hdpath_test.go deleted file mode 100644 index b014ae804..000000000 --- a/keys/hd/hdpath_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package hd - -import ( - "encoding/hex" - "fmt" - "github.com/tendermint/go-crypto/keys/bip39" -) - -func ExampleStringifyPathParams() { - path := NewParams(44, 0, 0, false, 0) - fmt.Println(path.String()) - // Output: 44'/0'/0'/0/0 -} - -func ExampleSomeBIP32TestVecs() { - - seed := bip39.MnemonicToSeed("barrel original fuel morning among eternal " + - "filter ball stove pluck matrix mechanic") - master, ch := ComputeMastersFromSeed(seed) - fmt.Println("keys from fundraiser test-vector (cosmos, bitcoin, ether)") - fmt.Println() - // cosmos - priv, _ := DerivePrivateKeyForPath(master, ch, FullFundraiserPath) - fmt.Println(hex.EncodeToString(priv[:])) - // bitcoin - priv, _ = DerivePrivateKeyForPath(master, ch, "44'/0'/0'/0/0") - fmt.Println(hex.EncodeToString(priv[:])) - // ether - priv, _ = DerivePrivateKeyForPath(master, ch, "44'/60'/0'/0/0") - fmt.Println(hex.EncodeToString(priv[:])) - - fmt.Println() - fmt.Println("keys generated via https://coinomi.com/recovery-phrase-tool.html") - fmt.Println() - - seed = bip39.MnemonicToSeed( - "advice process birth april short trust crater change bacon monkey medal garment " + - "gorilla ranch hour rival razor call lunar mention taste vacant woman sister") - master, ch = ComputeMastersFromSeed(seed) - priv, _ = DerivePrivateKeyForPath(master, ch, "44'/1'/1'/0/4") - fmt.Println(hex.EncodeToString(priv[:])) - - seed = bip39.MnemonicToSeed("idea naive region square margin day captain habit " + - "gun second farm pact pulse someone armed") - master, ch = ComputeMastersFromSeed(seed) - priv, _ = DerivePrivateKeyForPath(master, ch, "44'/0'/0'/0/420") - fmt.Println(hex.EncodeToString(priv[:])) - - fmt.Println() - fmt.Println("BIP 32 example") - fmt.Println() - - // bip32 path: m/0/7 - seed = bip39.MnemonicToSeed("monitor flock loyal sick object grunt duty ride develop assault harsh history") - master, ch = ComputeMastersFromSeed(seed) - priv, _ = DerivePrivateKeyForPath(master, ch, "0/7") - fmt.Println(hex.EncodeToString(priv[:])) - - // Output: keys from fundraiser test-vector (cosmos, bitcoin, ether) - // - // bfcb217c058d8bbafd5e186eae936106ca3e943889b0b4a093ae13822fd3170c - // e77c3de76965ad89997451de97b95bb65ede23a6bf185a55d80363d92ee37c3d - // 7fc4d8a8146dea344ba04c593517d3f377fa6cded36cd55aee0a0bb968e651bc - // - // keys generated via https://coinomi.com/recovery-phrase-tool.html - // - // a61f10c5fecf40c084c94fa54273b6f5d7989386be4a37669e6d6f7b0169c163 - // 32c4599843de3ef161a629a461d12c60b009b676c35050be5f7ded3a3b23501f - // - // BIP 32 example - // - // c4c11d8c03625515905d7e89d25dfc66126fbc629ecca6db489a1a72fc4bda78 -} diff --git a/keys/hd/test.json b/keys/hd/test.json deleted file mode 100644 index fa9610999..000000000 --- a/keys/hd/test.json +++ /dev/null @@ -1 +0,0 @@ -[{"mnemonic":"measure slogan connect luggage stereo federal stuff stomach stumble security end differ","master":"c177fa4bd21420b6ba2246e4f7a43fbe76545d1204174cae942ffbd79a434d11","seed":"c237f7aa198c5bd560ac8daf5b8421d03855171465b2999b07159671e9186461e7d75dba6c7264b963108431f8674ac8d095b7a22878fa0ab8b582e5d6ea1986","priv":"91bba8805845210665d7a9c5aff63ef69f7604fbeddb485706d31f04458f572c","pub":"0210ddc89abc90bbcbec8c63f5a4ebb016b58063b9d1a77854502042bdfcac5e51","addr":"72e7d6e9cfa899043a0783752a4876423f8effb8"},{"mnemonic":"car taste absurd genius miracle toy earth true glare mobile pig forest","master":"d7e07c472b05a2d668328c148ca07264afb4b53e078a2e1c106470b51c6ef81c","seed":"fda7006f5e9b8d1c02404df6d4e4497ff5c2edf29c801180a046dc54fca2e019554da6e3dd2c26073a7871c5ac529ad465ccf77ec3608727cc47ef88f998ae2b","priv":"1122ac929a0a3b2947ef99c33c20b657cf7342ea09be92869c363cfc52118200","pub":"03d0b431b56ae65aeb5a572654445b3fc968fa9d73995d3b21243cb07ed1ef0067","addr":"63eba204c249c795cd9dbdad58561db56b1d0c9b"},{"mnemonic":"trophy crop coffee oppose pelican help sense note bar faint hen aunt","master":"d1baaea05c34a4bbdc6791ada5aad77fdb0e626642cb884e48d25cd4ef6c9bed","seed":"1cdcfda64cb0e4f5806a48ff374e9f5f7d2939815e7adcce3abd898a7a9204eec4a5822997ca556ad797b4610c4ae6accddc29d80fd651a33d5ed911892479f1","priv":"c4bbb8f1ec60271c1e4f9e019ea45f82ca0ee3c42d8ac268f898fdbdfc28cf48","pub":"03abff20397222f9cae536d6b6776ba48c9b51898f7527dea918058f986fbfad15","addr":"fb6abc72817a9d2c6c1a2fe652434999661e1178"},{"mnemonic":"embrace office author among dream island social gift ask drill polar festival","master":"8d58a57b66a08bc0bd8dde7a718432a01f7aff03cbf999aeb3830d7a1c3d0d54","seed":"65b81faccab573d4a4272ab7c46e5fcc7db66eceeab6796d6dd70d8c54d6c95c3b73a637210a96a95df5ef736f51eec1dd3af4ccca53e98fb7f16d4e22dc3f52","priv":"dec3ffc51d5c9eadfb11e11dcc640f8cb294a21cfbb4a230f164693d57851b3b","pub":"03ef202a875683203e9d9643a2943cb40ff5a69b6efb3b0dedfc8ab1c6928261d1","addr":"db1a5fd30abfe666a049f5c6689a0e3db3ebec1e"},{"mnemonic":"aware gospel lemon tomorrow east wheel member forest walnut virus shallow stick","master":"24075bca853e0066909a6ff06ff02f196d4d641c00677704a6472810b0e3263e","seed":"1a4419cb19e2e7686fe68187aa55a2d4fab8d655c505c5666963d61bc9e92cfb990402d8527f9463b2deb3e86894055e3c6b31cf9995ca5bdf9959db755c9e90","priv":"853665c8f66682e50db33fe699ee72dae036422bee03e37093ed95c871ae8309","pub":"02a4e19e61decd6006bec54fa9c7ada7ee63ca6df12640e9fcf4214faafce791e6","addr":"155dac0e19dc24880b5aed827ebabb05bb563b23"},{"mnemonic":"perfect chief lend clock bracket guard extend medal slice vague cheese child","master":"b594e8d22e4864bdf75ddf29de16b7b207b2bbbdf29132b859f9c71c919ff669","seed":"631fc64164825a9769c4cd376cd736d4dd4191b7728e70b1e84b46322cb8bfb01b5b33cc6707d59bed09f6e7c82335541cd7dfc51ebedfcc2786713a9d141663","priv":"eab18ec583e155fd4ece4a14248bda80c75a6f209a1e4a9b1801e1a707b4356e","pub":"0247995311612868a8d1f6927f18ae5163a9d64a41d8f4015f9dcbbdace9277ed3","addr":"1f42f6538f64d844cef39b941986465076da3d54"},{"mnemonic":"edge early ten vicious piece begin observe ripple neutral farm volume accident","master":"1d6462662cd27419936c1f5b579eb7ebbafe84a6b1a58906c37fc0c2aa612d22","seed":"fb9588a1e3a2d9c26dcdb3cb010b8f868b29c493c95f7fe16761b2a666a8b96ca62997646e8d2cea1ff8ec3b85bd2311741ee327076515ad075623853279b57e","priv":"081847ec4f11a7d54ddd78c6f0fb3cdc32508e4956da14e0d728ddd3862124ce","pub":"03533c9f60afc94de73a0abb7d3e98906fa72cd2aebb202fdac32e2014452779d1","addr":"bcab563beb9ead1a87ab5adabc708502dc4081de"},{"mnemonic":"escape crystal wrist method cave retire wedding unable fringe inhale vibrant inform","master":"8b8597cd8ca42fe10236cc933bf0adda507132be6c41451d6ddda615b4032798","seed":"84582da23a6c4cf3d8f75be55db0d2710e10e31e9d6cee8288d827ed17d6585f19d81831aac12aff8d2724ace9c4220924e7d778eaebb3ff7ac4976b5ee25cc9","priv":"d011566a0c3996c99cf02ee41aa3f24c3328b5773ad0c9ea23f1bda1967a7e2c","pub":"03dcb9dd25915f827965c2d64e258eed1e4cf55f9fa3a9a8b5b411cbccffb11de0","addr":"54eea7e51aec6be8eca7a556c0ba5abfb702b34f"},{"mnemonic":"alter buddy rival question bachelor expose unique menu east sample also fence","master":"0eff009e6a00061a23a9b26f365cc00b0189825fe2eec0a3e78928fbd9f4dd7b","seed":"afa260446549711688b754edf33e313ceaece5502d0dbd8d82bc3c797151741620e403575ba6b54b0071e7122c8ae54893ccf29a43de209c67f7a8c296e47c84","priv":"39be182557862e0b7cf6440fb23568e54772edf734b4710ef571b37a6c27d16c","pub":"032c0d9bdbb97f2b7041734968eae96b3283573b9eefcd3ea1ce286c872bc8df4b","addr":"cbc2321a8e91ea81a56150689921b65a402b5c63"},{"mnemonic":"jar toward train panic unhappy control artefact horse deposit liar minimum pink","master":"009a99faadbdaa139f7ad2297367fdf92103c75194097133b51e0dd57629d06f","seed":"75b28bd52420c950aad1b4270fea0f8816c240e1bb16ad7f35a4bcc234e1c0bce4642422ea359dfae0332417c188a10e1b7efda4a9129809d98a179e8ef618dc","priv":"fbb6c27c23346fb30aa1aca0004f3adff649067efcbcdd58f9e8ed1be9167624","pub":"02463386f13659d68ca10edbecafab3294fddfb989b8012dd8a306c1e716ea73bc","addr":"9aef504159fcefcce23e49b64fe73d64b652751a"},{"mnemonic":"wise undo month ugly case garbage cannon torch sight burst flock enter","master":"e8533102aa8baa896888094c49fd096151adde972cbdd46429095b6081226d88","seed":"c64eab45997b8f27af96667bb8b3e3b1f13cd1cae3f33d357ef8996e958a24f78c6fff1dd21a7aad45a236d02e93722a74827e723415f4c3d2e28b5755ce74bf","priv":"7b28255abe4b5dfc46dd3e4a78aff23fd519ee20d0fccf77fa1f08dc87d4c2a8","pub":"03666213b09e6838c37edd56d858361cc7252aff15c86d9cbb7fd2ffaab2797eff","addr":"8de416131b81c2b4fb347c619e162e5b9d8e9171"},{"mnemonic":"fever hotel cup cover lake cream hello drastic scrap appear device skill","master":"c0c7ae8be6467f73da04bf31893fed60a7d2874a1b8b40cf6b947d3e0c072fd8","seed":"ba8ccb1d6df012c48cd0e97e126aca7192fc49ffe58fe554f2f96b85f7c8ee842e582a7967e053c4ea26f5ee0730dd7b78212b397f5ad89c0691c151c5b649b2","priv":"2d28bdd1c56e6f0c953b97ea571d7ee13f4b53557e9de79de436faee8b984944","pub":"02d4ef64e150ee986d14953bb42d7da5a26e184ae00d33c648e552ec31cc81df62","addr":"1919c6f2d0c93447d4fb8f10b8af4c57a06ad235"},{"mnemonic":"camp pizza test idea attend urban pond gym solution denial coach oppose","master":"e85ce81ff0663a945753449ea5a53a72e429a7badc3c681d7c13bb1b75a4d2ed","seed":"2bc62e90ae9d83635b316ef55f4ada1652dea512da332474598f53f93268ee1e18802ba19e75df651cfe931049ccc7aba7b96d43b62182e0e5b0e21a1cc2f489","priv":"bbd3109cd6edfc583ad1fca84b3c32def7d41e36f1994ac40eb5fd9f72211a47","pub":"032a3e6b6d55ede0c25b78a2bb860adea7ec8b3dbaf7340197ad2d0c07e1673a1f","addr":"4f9ba3935c15ff8ce14f0b09ef498e50693c4c90"},{"mnemonic":"solution buffalo armor capital enter cat banana manage caution loan people gauge","master":"1d894a5d9932bc19f91fa92f0d03f25136a77b4eb961ddd742b74c54edad9332","seed":"b833db5ff34a1bddbbee895d96518261025bbc6a9be596d58435468f1547ff378f504062aab7add0c69763708238d0ab42a90f6af0b790caa1569d1cc089b605","priv":"4e26066e7ff8936e63fb011173f70b0206c1b6ecaa519fb252185e18dbc19705","pub":"03fd00f281ba6065cdc8f6a8cf17cdb22b2ccad62eeb535708381004b2a260837f","addr":"e6247dacab881ff882e412630350eaa6de14817a"},{"mnemonic":"power answer mixture choose course crop decline border carpet absorb long artwork","master":"1d74c0120756009f821899f220d3a9e77291e0549241481b657ddb84af1b66f8","seed":"cd9ac735fee9bbcf45bd79b31196138b3ca002513bd1fb973eae4bffd0c5732611cd67006af3f79dd127ce21532947a0c1355cc774faee82f58cdbef6f8bd7fa","priv":"45f7df4a90d4ed0f58c47ab4839220f50689cb2a5663acd9cbb359d6a23e465e","pub":"02697233abb54eeef1f03a371b0da9a97e85ffe404707b5b7ee3f0e3d2e2f0768f","addr":"0f5addad3faaad7ebaf37c3d3f2576a0a1a5e533"},{"mnemonic":"patrol room turtle cinnamon remain tank butter hazard expose winner rough pull","master":"91eb616d5be757e91052fe74042515b828e2bb14f5666370d7ec37c45018abbd","seed":"7e3b9d910c4b16b06e813b2b003d9c0e8c76ec520702be210d9ec2ef2406e7f473f09f41fda56b6a657c2f1000130e11a88362209c6b4b47362e786b7880916c","priv":"ffc2a31bf0371a095cadbad2e0b5adc5669ceb6faad08da818c3c64e4af53b44","pub":"03b50efecc97cc7d7f101fdcae02662d49d118a63f03180889d8321019f245f6aa","addr":"0c43cd72c09dee746c3af1691b495a8c02286612"},{"mnemonic":"bulb neglect chalk congress cattle found balcony easy tube sick journey quick","master":"a7c632878e900903d4e0e6bc57291f1e64981d703e27b82c2da00dec800d5570","seed":"aaa765dce33f6b289d37fff2e409a540a29f3830a7baa0526eba3317d559ef59e8936e8285b6ea8a62753ec72616163e24963e49d795f38df210836ffc7d8807","priv":"f8b281b658e9a584087e16eab0179747db5c38193cada4fc85364a8f743bfec9","pub":"0384df6f5de3f50793f62eee838d30334501d6339998a25889688ba305998d15cf","addr":"cfe9adc1e454387351d4ef2dfd086101a0012863"},{"mnemonic":"arm asthma voyage mansion hurdle alley ensure team coffee palm spice general","master":"48e37cc4961ff1234938ca5ad6ed22f668b29017067c283ebf2d9642cfc2e57b","seed":"6bec879e82e5d243a6bbd5a0a5dcd21a6403d450f0f498975d5205da7154f62350cf0afa034f921cfedd4dd4dde0b6e3e9cc118b16b6682686211040b3b80b6c","priv":"b0b487d336dbb594947dab6717a5f140056d998f9e8428307491d12b3f9e3883","pub":"039db2ffbad67e7e824bfd0cd9fd8798647390b8c9a583807995a9b49e252279c3","addr":"1353002776f22c179aa208bbdddeab3c369c51be"},{"mnemonic":"spread curtain furnace trim funny usual age floor crunch blue urge pistol","master":"3c44072b545e2e955892ee4e6e5949b748d17d47d3ebeda85fb50a341bda7668","seed":"05376e4a1725d48191bebb1e03bdf76880d82b033f597182becbdcf78f167b260bb5cd6b79681f7ecd7ec75c241f90cb40b2d57d108bcc1b7766a63002af1960","priv":"58285cb1f39d00c6aa84a32a69e0e108ca80e33e75b7b4890e182a7e19485a36","pub":"02e4194b7eab20702d498ee7eb7cc98c3ac8d8b2fc63aa66bc81aad93bb1aa3b71","addr":"9b8ded654ae3336405f0bdf768d4293c462ed51d"},{"mnemonic":"century outdoor world grunt member stuff holiday intact property race mutual vehicle","master":"9b9fcc1fedcf63ae9fd216f9a7253f85cdec90f9b1fdca0c36b03169a5860ff6","seed":"e39f8455cceaf542d4062d998b8de4d7e153e594224ef7d7069abc38acf479fd2485f0821fd9af2116c58180f0069af32d10f0b7222eaef6622de83741824999","priv":"e7b4c942473ebc56868904e588bea3342f761528ca90f2add423e17615ef80cd","pub":"02059867db3a2ab4307a5ff502e9f89c45837927eb2f2b75fe55f0dcf25df9e1ee","addr":"714b9aa6afc10a40d702076990a451dc3ee4fa4b"},{"mnemonic":"world trade divert sad unable plug stereo autumn father ankle biology clown","master":"dae1a9e15469905d0d20172bbaa768be4ea4900594080499a56a69d1ae6d0557","seed":"50169fc286de6432685d85b4352908b079ab4fd11f1d8c6a82093093a9161650c2e10d8407f65f8cd1cf4d9d557590f21f5c717a761e7918ef8ca9b73f410120","priv":"4cd8309f36881d1afbfba66b9fcfa09f948d544db0baa3d81d3bd4d2067950b7","pub":"02a86d26c5b309f49017d4778b13be315cdd1d7c3baceeb61fb91c78bfafda4447","addr":"36e8463e55df56e01fd08b8fafa3ec1704ca5480"},{"mnemonic":"observe minute art scheme pear lava search dove cube entry orbit worth","master":"b7ad8e5b587bf747fae6c42423fc4cafecde0db7c9443d48afe10115d95f9b93","seed":"f3ac2022097390a9a0ae0e47d7746e6bce017d15d97ab74b1f99f70ed1c1e9b3534bdafb69e2aba1a7fa2ad787e9ac6b408f2259259ed4f744054504b05c2001","priv":"63797b9d76fe914825f90664c4a109501be006ce9049d561b9f6798d5e518c33","pub":"028b851a2e41625548564242b16e4bfe07cbf685e2df45dfdaefb4aee9fcd607c9","addr":"16d7f83a219857fe095aff5c31e30333e06b329c"},{"mnemonic":"sphere diamond electric milk furnace uniform tomorrow fatigue mercy isolate judge arena","master":"f88c8bbcf7deb1636c5d96003a2bab945a518278d9d58782cc9e7c9fba4facbf","seed":"5660e5ac88a5c43cf14cdae6929c3894ea5aa3bccf3307f85f1162880562ca352153fc1955b21e8533ce844e79583ab95df0c4199b9bac4520ca1c2821ab4f18","priv":"700fd3176db1c0988d7c35d5ef2cd109c7f52b583ae665011f5d476e5a7b3ff5","pub":"022efb00f6c83d296a12f787239fb7905b7f0c27e4fbb62ae62fe43a91cffa9bf7","addr":"7e4a94be643599be266227f349d4797fb7befb89"},{"mnemonic":"syrup unfair confirm hunt flee armor limb travel hint ski mother credit","master":"01aa87dd513611771cfeee1a39986b13fff29760f0d4c7cfde678e70fd053909","seed":"0e54e0db6ff149c9c572a14c3902fdddd567c8ec361ba3bcccb3a407e3e5c6767ec71eaae2c75aa1fcebaaa95e14920e803d824ae4ce64b13413734dd4526836","priv":"72258e31f535c698fc029b953da4c0a89448e5633cccf27e3e6680bb895dfb99","pub":"02b9e8b06d6ef0ae29f911d48c7facd2528a45f432efb4f2c1f1eeb6056380de2b","addr":"90500208588f51b84399e4ba62ffb653d513cd43"},{"mnemonic":"embrace travel lake capital dream shaft focus kind card hood enjoy memory","master":"04e38c8074b77f3ae174593b3c69cf2f55bcbdc02bde68079691e2d8f4e26e6b","seed":"f9d883ef73a830ccfea41726a150e50c9c51b9acda9e4d022c0b8852a57f6df5d8f26542ef1bfaf83eddbe276b8f16cb7ef151fc512dbe005e473a64a5b84250","priv":"3c1b914b34fb0e5866ef082def1cc4fa589ac0d7be5813621d22fffe68b0d4eb","pub":"0381cc19aa68c4ce5bb656a1ac6d1f93375ae096826f99b46548b69c4a9d07e30e","addr":"2b82395c3c65dfe0c8a82928bb3a53e745e29d26"},{"mnemonic":"rabbit choose combine yellow permit raw puppy interest spring work wall humble","master":"04d834acb4020196f894564e1fe631420ce9e801b27bfdcf221c3068aecf3eef","seed":"1089688a78e4c6e35761aee10a12600d9f48eca57d239eb4573b4ccf28925cf72561c2921b31bdc5b00a222c537ef8c37773cedc7742f61633f1adcf94dee039","priv":"132eb740a216f2e92c7c5f96605ae61824ebcc4fbecddfd17689a1452fa174c0","pub":"03ad014b5a58c19ea616716e555dc7f30c67b5fe06bf77cd91e179f8218ddf89fa","addr":"8e05459a88d149b8473c0411a175c0b070423e05"},{"mnemonic":"bracket what unlock tooth melody wire chapter verb grow direct spin rescue","master":"f64c4e7a30ad534ca260cd280f1e8a6055e63f546d57e61071d5c7937273b4e6","seed":"56ad6c16f5bcdad95f566e8628fcceec9f00cedde68816077e0b6db1c106fc3203052ad334a0fa4b232157ba09983087d853240495fd010ee416a38cd3158108","priv":"37f99cd9868a0e44bf26a0a3180cb13f7e4fc0e379cb035b30bff23dac6518fa","pub":"0218c1d6b479b4a8ed804f62c84397d0ba8405a1a266c5318130f0c8473a60412b","addr":"224d710168a45dea667015231a3b8f910ba91191"},{"mnemonic":"position nation recipe recipe friend defense friend engine that leave match finish","master":"15aef2c47f684437bf88e44e9e518a5c517f16e163efa24f1ed8414d5e975933","seed":"15df2473af5b7147abb3b7d17da3d9668901d37ccc86ff652c9ebc75b596e8f3939e77ba39194276a659bd86947a50fef8ba147058db007232a4648e8c642ca9","priv":"59eaffd27a11231bdb4b39137e6667fe2c3ed81e6ead13818e4cd966729d558e","pub":"03865fbd6db962067b2547f69afd7effe57fb3dd3342bf5255ea6d5456dfea0842","addr":"0a0c1411a031ffc35f95c214e9a580ba4eae6c02"},{"mnemonic":"sight broken hockey empower hair never bean beyond glue small coil barely","master":"b6847c7371864fa8e19e57718425d640a027593b535d779b815e003098294910","seed":"3ad83d292efb99c2fcec6c12433c5fab6d250ae5895e0da6f1db3103bc12d82527be2853711532331280d3defa5f8bfe58fd325d11621c9a10b5c7712b02821b","priv":"9c3f71613d8ca92267a45b562e39e7e12305473be0a6498b3d2b9fa4c65b743d","pub":"02f9461c5bbb2e8ab8281f1384b5f0d412abb970b82e43ef0f1c44b9476319d87b","addr":"501b211909a1647afffe57f1ab7754d4c48940b4"},{"mnemonic":"pause usual cigar festival vanish direct amateur bone orchard cloud fall fat","master":"acdcc1f311b27f850eade92937a5d7a3a9ea1513e2ab5d08fbacba42ea267c30","seed":"cf00b72b84afc0e4b0e2480c6ae55ec1c5ef8eaa0bfa531432b3e9578fdd4ed5199cd24ab22e1cade76f0b763d901becebe686770f3409a8aafd2ee89f111b00","priv":"f0412e04a062aa3cb70cd68fcd327446121c76c33bc440ff93f63e05cd1aeea8","pub":"033708eb3564ba835b779fbce8ad6d64501333c05d0fd798c92f926256464149a4","addr":"92a06b244988b778f0986502d8ffe1804f78d10f"},{"mnemonic":"caution unusual response boost dose jaguar nice exhaust chunk tobacco cable toward","master":"7c584d3382f394a4d07684df15e04c482ba0dd3c8223a97c92c091bc95d2021f","seed":"17e49b743fda3aafe81ad205605dc7012a2096cef2475b7b12e79e54b625de459de8661ebdfacef620c851a11a0237c781ad2a84e7e30abe42f63d8da460267c","priv":"9666bc12bd5dbf4eb4bc1a8acfa021ba8f862e5551d16dd97e8e49381259196a","pub":"0314e1d0b675c88061db3d87de6bf4728ce8ec170bafc754f4fd846341ddad619e","addr":"9b695fc1b1429ec5f697df05a1f4c850489830c6"},{"mnemonic":"dream walk typical enroll knife gallery kingdom dynamic extend course shove power","master":"a0bef19259cafacafdb4854e37f36b332066b5c571538e970a7057ca0d97db1a","seed":"7d2bc8f37a8215149b75577f9efd29e0ada9f5db469e9125883804162dc7b100373f020667c06bebbcc593452dada790237ba11ef638573210d2fe67c7e7f205","priv":"370caa36a7e3a5aead2d4abb58d57b90299b4a65484613e5f39b0b7d1733e1ca","pub":"03bfddfb81e4058e08f3ee57b06065194c252e2a31b074acbb15cc7c5f6487368e","addr":"6299fc81f05eb71fa12dc69b2ca4ddfb6514af29"},{"mnemonic":"apology benefit donkey van target neutral success hen easy capable smart stuff","master":"dd96dfa3d46e0bf70df538f0da3b94cdbd7c20e170c8875032285ed7f6654ba2","seed":"c3e6214d2db9684e4c7022311861a013853761ae9900ea823fc4bc6d70bcb8de98f100664f0a04d32e18cceeba41539f9237e89400cf94e0017fc66622a902a8","priv":"3add5757d65ed58816a2b90411d2019d206b56692205724d6e412a26da88abe9","pub":"033607f86548d8e432cc23c8c995749dbb0bc0731121b90b952465fadec31df521","addr":"e2073969ad58513da3df1225e5266e03c0917e46"},{"mnemonic":"sing eagle hello october action alien equip tongue riot pave oyster fit","master":"03f58c7803af441682b522de573e37b218fdaeef55d9637c1ff8c58e01e57564","seed":"7b9cca7d24f97bf461619b101ecd343455f9b00146fec997ddf3e1c569c615e010cdac3b6643a6e9f4ec45be954bfde0b0320e86b0e869c121ca0adca7d11b5a","priv":"21f52146c31e0a6ab9016b717f0435b36847d5b72d83183b3719890171599068","pub":"02f391dc750aa937a7b89dffc9543f72e73d6939fda1c0d74dcf99f27140656307","addr":"7719d5badc862468acdaae65afef4e1e2ba5fd08"},{"mnemonic":"proof symptom trap diary biology tail cement interest fruit tobacco soccer prosper","master":"a0e4189e097622681654ff2b346e79bbffb8e4e7be139567fba8b2c6aa427096","seed":"557153d485c01cf29622ee3a2e1fdad38c815a7cfe72eb18c85605a96c30e38b16ab37d9a2be07cbee7a211e911bdaf460d47a07d83f385fdae9217eb70487e0","priv":"57a2ee34ff6e6cc2dcc3fe3b907cb44fcce0251013877d46b04e24c9aa20ab73","pub":"026172d3d801fb6e855e2eb0f1171de15e6823bb13002b4e9b01a41cd430da7f69","addr":"a1a953df8d8ff38614bbed7ea9f704ef98a37435"},{"mnemonic":"wire gorilla pupil since trust open amateur evil chicken razor minute science","master":"bb549a48f5610f28b23bff00b8b0de2c93bf4e093400989632c98feb3f45967e","seed":"b05c272f522ec2c53dc26679e207f2c16b6506de02e8fb231175265445218fd8617222a374beadfe1999ed617d5a1f89e0a93c85bc022eff6468c4646f3ea381","priv":"2e96c265f6cafb5912bb2748ff4e0d4b9e960d0b4fbc92967a73591c6d7f54c6","pub":"030d6aa64cba047b2ee2c5af2d3893e17004e66762696e6375b09e32e3675daa21","addr":"e065248114f65902b5cc3aefcc1bbbec4d7ed597"},{"mnemonic":"deer meat share below retire when crash original boy wide leaf blade","master":"47f23c913c2e53d34f7c5d869fccfc07a9a5a7a2e2e811abf9781c69aebb4ec4","seed":"7f1a2f19bab3b121415adf5ffc709749b009fdb90df35b6f3b7d17d8eeeae0d41e0f37565c5320b90edb50076d712aaa5e606a88a44460cea67cb686f1886984","priv":"dcb974cc926c246144d1e6c1c5b3babeb4de3be7dd24ad40d6fbbbc592f384ee","pub":"038d6fa489c22c5a8d95d6931144de5d61748be81076b8cc2f6a0c928065f098c7","addr":"4c8a5b45086b2514f8094d3579b2d420b36f7af4"},{"mnemonic":"accident symbol token cotton enough false cereal verify item army pulse sell","master":"70b049648afff7bafb6ac1d8f5a2e2d78bea9fa93c2924f0cba70d4aee27dde6","seed":"d58819c9862ce8078a2b4db0a25434f03631bac4143590f1a245eed73d41f68f0ab089753064eb879b2edf1a56ccb83d0fa88721cbe2ce05f2c46c040dbfe14c","priv":"ffccb427730c5e0b70f535e6ed079888f64b56b8ff51a7f5be1f1312ab63567a","pub":"03e4300d0181f901e200b71f607729f6db5b422c1dccc6facd28f7c694975d2bcd","addr":"66cff13f2cef89b9313377ef24b4a1fbe2851a64"},{"mnemonic":"modify monster ridge bullet lazy sweet output acid shove hire warrior broken","master":"014daa371dd0446424b0b8cbeacbf8209c5136f184cb97346e82ed155b535b58","seed":"a5c1919d9fab0049de70600a275930979ad0da3a3da6333feccbb1aa41ce461ff1bfc5fe0fa6db126fcd96887dfdc2f531a522fbb90741aea5cf2c7dbde8d585","priv":"b66d283958f01a72683b8c7637dbe3910575fa853c7cdfc395904dc73723fff3","pub":"0298afdd5257542bc7918449a8e22a85c5c6bee8311ebf6c712da73232252ac3bf","addr":"22a6f55327b02536e91a046e9a8347c38be6f111"},{"mnemonic":"economy relief sort silly pizza trick urge harbor coffee flash fantasy sorry","master":"f1ad3c0e0551b62d80ac54f85aa89c9f241f0601397b1b4e12206a67479443c5","seed":"d3abce93f99595d45d0e9eb84aa18cf836f0d7eef60345b8eb2a9d4c87a8eccb7a0304907adca904503d8211dd31ba96e076a4b2eaa91ae575d4d1f7c815e670","priv":"4aab4cc83a2acee81a99bf7fe4fea79cebf133b1a7f0fa3f583912efd60a8525","pub":"03b241333aa683b8319975cd9ab2b046cb7731459e79a0ee9facfafa85bf0a31ea","addr":"9ff29de09deaa15e5050b5156754f9168ddd6df8"},{"mnemonic":"wage thumb correct coffee salute rice trade middle monkey height hint plunge","master":"22c4ec2703eaaf2de49e585a5ac5b7e17340a07523aa46e35503176a3a53fe28","seed":"b93e4f76a12d3cf66af70b58b30a66d5d648918be7d5db33fc3d573d6ca546f39490d3101dd686185e61f4334f4880f1e52d94919b358806812057aeda57bef9","priv":"d5e46c667c3e8c08bec8c7f7dfb1dcff3a628cb39f1eb6b8e117ccfa96551354","pub":"03219d1b8b9d5562e550d0fdd5cb6227988622d664bdc48fcad2c07dc78b82f1a7","addr":"d8f9a7f71ad4a92a07ea0c53a54395895fac7134"},{"mnemonic":"miracle penalty base jeans inhale state roof size tent chair life afraid","master":"82e0e8ce42e1a391f362bd19a0959529139153e6102eb5c947a64ba6b8699c36","seed":"d43f307257db97baf0e458c06b0f509e5534aea2bf8e2972eeef0a5408b9fd52a13df5b73adeccad68ef61017d63243dedcd167185e10402e7a7c03c88087527","priv":"8a82fb302c3b5cf10e119ff3ab01a036e002e9e2d49f0db0a40d5b6828291bc4","pub":"0233cb5096a11a4c79e54cea37e42139a1198a1385cf4e0d37c704352aa3551a13","addr":"e019149a5036bbaadf18788e3be72fa5292a2bed"},{"mnemonic":"stumble army virtual virtual plunge until pudding universe suspect palace bacon dream","master":"32da9154b165c960e927f0b01be8435f2b6ace7dcecda4416a449a50aaa56774","seed":"72bd5c92a8ab4478fa1dad0761118bd3d9a1ce6322c00f81b527701a74e0c4aeea63238017e64d4acaa92bc61af2c41a734d90567799ddfd15deecefba60988b","priv":"63c7d3a6da6149655588c4fab367f187f940101e99618de1d01963aac0dc639b","pub":"03df276b793ee770816ffd90ce2c45b6f24558bb90cedeb19f17264beb53344b29","addr":"03c20b0d41439a374a8a84ed7f139382b6b012f7"},{"mnemonic":"label script force inside outer pulse style nut meadow design receive panel","master":"bb084bcc5df57ad10abb3342888508e399cf723415d35f5440d0eaf808a56d1e","seed":"07029905fd6a538b5ba773384b0084bd11b5ede855a98189b8ca1b3b0457add4b365f98bdc75874ccaf85882c5f1aa59f0f9b77b5a823178cacbb4ff72d0969c","priv":"91eaffd2ddcb6d055c1ab3c7c87e313ba520c263312a6f3d267d41018d7cdec0","pub":"035bbb055ca818cf974da73d5d87d7cc447ff5b9dcbdd39552fb28c925c2077636","addr":"baa25da619099b41aebbbf1282dc6af9dc268664"},{"mnemonic":"nest decorate update alcohol system panel cool grape mind ivory ski dance","master":"64666caf25c290b5f46e27737e61124c34cd428b0d1a09e88ec47cd059765729","seed":"8db4806ada7b82f0811b24aca3b0e11d087cfc27e3e83b77e29c7d5695a126f577304e443f71b3de9239ca743acd05563c1f08f071eca5de4a9961fec463c372","priv":"eadb5c2704fe1eec4f121714b3a6d655d9eb985fae7d535c6543df13214bbfaa","pub":"022bcbc7676ad7693e97a587886293b6190edea96a339e225adaf3f3d6c493851f","addr":"5310b04cdfc366f6268deaaec22d7c628dc4b1f2"},{"mnemonic":"section supreme grit scan arrow flower rebel trend film sting govern museum","master":"29616b872561d14ef56f4761a29da1c5dc768092cf7eeb4ac28aad39e35ab274","seed":"4b8d6961db3f7b123dd71ba5fdc1b7809a19d84dcf25bd1b443b610cdbe44e5d5391aaaa4374ae9d6ca988b5898dadaf5fb79fcc09859851538842cec7acd36e","priv":"da2a60ed2f49ed3b6c1ff78698e3eedb2d9cbe9a707dd91e047f8a17db4f8e92","pub":"0304262df894cfd35a5330eed4008630b6527971f58075282290a070906c0d69a8","addr":"656996e8dc55902fc01bd95e93edb12e1e7dc440"},{"mnemonic":"vacant peanut senior skill helmet absorb turtle regular inmate hidden captain street","master":"7c329d40208ae70f5ecfe8b3a5930adfd09a2f618098e549c972036bea9fa4e1","seed":"b7fb706e9e43c671d401c374984ba22ab5465e15d8572eef3c3302a3fdc77ec8b5cbe7b2a8e42fca582a74fbefe6b755e442e6389592a0845aadf56975a4b212","priv":"29ea2c32ecc076c6e25dd9cc06b9736d730a8306a007df2410143153ec0d7402","pub":"020ee0b300f1714f378676bb533ed50b8336bd288180f4b55a338bb1ada82e0054","addr":"dfba016ba98cae2160c861d8e5117b5afb76a50b"},{"mnemonic":"setup asset fan host pride decide museum fashion disorder coconut school cause","master":"53bdc111a1d4208f6d04234dcdb764ca24c2f42d7dd1de46cb69dd00594f9c67","seed":"0039f1f4e2000001b1af4c47f72dc1f8347a6b7c0559a9625881eb6f7492c2e1fd186b778fe30540ec9dae03de4b8e4ad414ff5692490a547e1127ab03dfadc8","priv":"899611b8bfbc35a6bbf5cb80c193463849fa665aaad680d576f910bec97dc8f4","pub":"031a099725389ba4d2fbe5509cdeb5893a14a7d743a6f87be7af37701e99be18d1","addr":"5d12852d8132e60b6ed5707c4a589107c7c40c72"},{"mnemonic":"debris bus thought unhappy coconut sing sign piano exact favorite zoo title","master":"c2d02edb9583033a0db1b44443769d5c7b9d545aca03ce9d1db0c90c97e648b7","seed":"411ae07dd870bb2c367b72b5d131853088b501476fe0e09896004271dec37068722bd8952aede6c4ea32371361842f9507c5854f7e95b6e1685d8315c4a635fb","priv":"91047f9554ccc47f0c641022c8779e064ccbdf969827d374dc3419fd462c9ca6","pub":"02a6a4280980aa2a570d54d10c295a94acc7d22040a2299c79b9e72808274dd0e1","addr":"f1c8da3f0438f82da710f6e2604b5adc033cc0d0"},{"mnemonic":"stove romance diet season ramp mango swear behave rotate steak alter parent","master":"039f8ff7fd7e498c643ebecc5cd54018fbe4aceb34a92877746471c3d9446517","seed":"2df95585063422c193cafab822373fbcebb38780acb2349ba1e3d5b98f3a5c63f1631fad81649fd22a5acb3673c3c1cc4c93c6fac5e28bf9ce2c2d25a8215543","priv":"251fc43c061854edae6e1bfd0748770965d44ba5c0ba1cd9784aaa07a17ebed1","pub":"035b5a07e862224a2324a8bf3af20fd4dba7157baefaae03124b51274c4b50b48f","addr":"14f3a5e955fe78fdd87fa3b0eb3ef3195b7bad3b"},{"mnemonic":"cruel equip glow protect trade clever charge gadget valid inspire canal unable","master":"e47ebf7c8d4b5f5b80555c25c8fc89bdcfe7eec0d39b2c18adabfc81c90b676d","seed":"5eb48012a0412a9911b697a3b838605813f73a885a967be55432e73870d703f8db4649a59483b1ba26b739fc39af73e4f3f12d78648e78215c98c08428e5cf15","priv":"fa28e24225703620c1dafbcc09015b04b3839f8dbf170e454a8f6216c01f7800","pub":"027b56b3e5859e3df96d60366bd54a5024ec84efbba102ab1b4c85383f34b61d48","addr":"23890ab09f410c91db179e68ea1d942d25bc0c34"},{"mnemonic":"nest wool midnight tragic exit enemy knock oil tenant survey opera sense","master":"7074c03dfebcb8ed77af28e9b01b77d803c6f2ac88b61a17ae902797c82cbab7","seed":"c4740919291e1af1c7986906a374b081f0386c40601e4f832cdd3f5c4a453a0dfafa1aaa02b00d98f49803a16baa8cb64bcb186c4cf045eb803d8ffab66fd54b","priv":"1f0dbcbe498866989dc0e0b55e6f4b83b93ed2191df2db3ccaddb3f789e434f9","pub":"0396454c50b1a4ce149ed251ebfc6ab07f0d4c42ae84a80c90ca1b64112bb3ca57","addr":"8198e949ce71c8a950f39a8a691f2ec180106997"},{"mnemonic":"brush sustain penalty chalk palace slab learn decide agent private pigeon then","master":"3acf99c19afbfe290a99911c085a656eec61af6f976623c9b6d2d1500e7033dd","seed":"38ed979eea68a00495e0e4c045cfdd1cbe5aabefe628538c35a6debec1be144d41745cecb2003dd870dd87c4246b64e6fa4662173078ad7a4fe471bbc14ab9e9","priv":"1424627b12902bbb162cef56ce5609ac356e68e3ada9005bd92541d0d8766559","pub":"036155ad03bacc613c9fbfb87294091a9bdb7845e58231f4d585603153871a8c3a","addr":"1792e857fca4355189ade1f45066dad9c986e7d6"},{"mnemonic":"autumn sudden learn laundry erode claim exchange jelly jaguar vault deal humble","master":"1a616c74e30a912dad799fe8d65d6ffa77245f89e81a367310fc02d08be13522","seed":"976e55f1fbcebbd1e448edbe90d68d407d80bd5ae197082bcd7ae8e7a640f3246e0057c65271e9e403297b3725a895f15c502284ab342ce1416f40c892bd73aa","priv":"701e7206d44ca9269e1bca00dca53d7287d55fc39214ed4c7e8f7201a68d6792","pub":"031a31e47cc6d75f0652de6698757b8fb2ed1ac181697158f0bd50ec6e7abdcf65","addr":"a73ac9e548e47d6f1f3ec200593a6693297a9143"},{"mnemonic":"priority dinner offer glimpse sudden light work absurd unknown process gas tooth","master":"d969ece198e95be043e46dd8ecb45cd2e5bcc09d8e6b00bfd7aeb59eabcb0ce2","seed":"aa9cc6daf79e31c5e3ed594dd896b1ca39161add5e5a7dba0159f4a8fe262c51d742e66a19f28cf01f32a90fafe5195b0b359e87f5a5a60e31d883ebca08d433","priv":"81d13a5954925641ace6c24f38c68954d782b094002a689500f015a401d5c6cd","pub":"029b1e4dfd01689451ea069e8a193de0b506d87faae6eabd9edf5dc49633c0a03e","addr":"bb2704f3f0270cab3a5fc918b58561bc1505f718"},{"mnemonic":"glide sadness text grunt burst balance ask hair include refuse mom advice","master":"5a105765bef30fb458b9cdc3d6758479f003f96bdfc1d0c21ea1e4987f768ccf","seed":"0131a60482c920093bf7b7375a70bea607a2015bd0bc9deb04e99d214a0c3a4966b21c3bac01544f816a8f4c3583920758e70f8991506cea52c9450c1972a9b7","priv":"41505f80b9b0941d93341815a72fb32dea916912e3dc1b7b7c763fdfb5c541f8","pub":"039df863578cf71fd48dccaed45c21d1cf176c924bd5ed8ec5fd8dc1bd6fcd1a46","addr":"396984e26d5b3a4cc3cf4a5a868ac88776541564"},{"mnemonic":"jealous subject gap april eagle goose double door dynamic robust impose ordinary","master":"ceef22480f535024fa3fc2a7cea96559f4fe8133e45301807d3213ff7e49e0d4","seed":"52d4a03cd2da0a541450a4530565a5901953d1f3ea0ee9440748c1796a5b8ec8ff674a8cf3ee2fda215a720f0fed119ccaa97619f6fe76b736b6ff804c2dc299","priv":"308bee98e778b1037cfd69c0691b6cce81b1935c776a8473a1b3a49bef313305","pub":"02ff9d7bab97fa367a753ded100c11ca4bee7173c04ddb242fd928502a58149587","addr":"7bc8cb221d4de586491bee3016d9129a42fe0527"},{"mnemonic":"panther camp coconut patch blanket census able melody bid sketch protect illness","master":"aa867cfcb578d828df3a6cc4ed1496f3af72f94635ea82574bedf2d88f9fb0ae","seed":"1bf0752a4872e6a4bdbf9f15dcda591184c8e1c61910d958642b376086cb9db6902d7ec0997afa3a0872ae3fa4fa7751605a4b3a3ccb3e4fb5a6afe26e2aafad","priv":"ce6de5f65b6a0cc1e9c4f7751230aec5f2b5401686e7e42b81f1d8eb55f77303","pub":"03f6c0da8154df0baeb15a7bccdd79252c38901ce2dc59e6e08d2d292bf6668a71","addr":"38a888c98b1f68797a879b64e5907b909f81c386"},{"mnemonic":"great history exit include clean have vague stick victory else iron trim","master":"6fce540ed685440130d194a3e8af78417f9b73df783721ccf184807b3973e384","seed":"2459cdc80eda19acec0c704f020082b617952f652b109c268035607139ba2710dcb8dfaf546257f09f5a1b19dce62e83f603f561d2cc2fefacdac6fc902d311d","priv":"26d08c2b95d15b5e1313aa62cc275b10544f0aad3c2ca677426551d5a039a551","pub":"02d165d97ddc4cb451d52895521d7c0cc217d1a004b9a760aa3eee40edcba4ca37","addr":"7bccaf7fc14e648667e8d7001f7b0777bef7813a"},{"mnemonic":"pause you skirt bundle opinion soap wall doctor head method tent lava","master":"b97cd03b20895737ec084f536ba06f459831e6bf2eab51fc4097ca943014f29f","seed":"b661487c12002df5c65a204ef12698be70837ec522fa1bf17d789d0d0cd0be443a819e4c6a494ad8d66a8ebe25ddd833d6ef7d9dd80e3e5e276ab94e0d572e5e","priv":"6860cbc7b6017128bff9c6d48abb20200aea06a7e8c9168d46f51260dd7125a9","pub":"03d7666fd2ac98121523262fa6695c719d3ea6fbf8abac8266b7c8550a498a55fc","addr":"6a2c9c329b85c35721b69d2885cb8ffa3006ef1c"},{"mnemonic":"senior liquid release beauty echo castle honey limb junk carry clarify high","master":"b3dd9a9379270f2bee11afa64bd9e49e4d9f44fd997c383d651fce6b54e8a82f","seed":"4caef4408f37ba86781693fb979534b9c9534972c7b866f74318930f180a2a36875960ceab41e8725ee4e25f56d160455f7d372a7d08282ddb5d7c1d24f14daf","priv":"6d9ad9c1011761fedce7f7947b5325622ffb1cd6283eeb22cf5cfa3cbf214e69","pub":"03f173aac293bdfd7a98b5055feef56e70d07d3e0549bf278bcc7fef559c0a413a","addr":"93ef2c58e7de60d861c0dc994add27a914477d20"},{"mnemonic":"scrub pupil rural fat taxi area example spring doctor ripple obscure asthma","master":"bf805260160dc14eb96077258ac64d1f67979f7702c99c411fa075a3813ad57d","seed":"ece2913f94e791b8c5c37dff29cd19f9725bbb0a1d84e7c3958eca1b646858de1b3188c8dfade823903a4b4fd12b892bf55e570ed68286741dd02aa4ccb08820","priv":"d158bf7adfec3d4d7f941fd9ffccc1c089075fea66fca2039dc4e2b2a7d1a000","pub":"02d5c76872253c3890a8e1276ec4df0c874fcd46d1f7b84462893776b6d14fe972","addr":"a98c98b13f7cfe6fea7de31de3fbd325648a9357"},{"mnemonic":"first shallow crawl asset vocal special rural bomb random pair shock live","master":"a0f6894a4375e267aae6dc2d23843375250b44bdccbc63d1436a2f172214f928","seed":"7518a5b622fa57389790c2484ad833c95e5cf2caa12f71ffb0fad4c9fe044854ff1f7e97b188545679ea936816217d2a26204a0bde6eb7335328dd0c86814bcb","priv":"027d54b7a844be318ea4442113e4cecd464455e239c0726236e2cbbd4c559fe3","pub":"03f5c6a2e2a82d331268c789527b5ae6d3f36e3fdcb344fdfd7e200d5243b075a3","addr":"bd4e60a76b171fde2684d4c7690e8feb7ad06854"},{"mnemonic":"famous vital monitor opera strike coffee shield throw emotion enlist east smart","master":"f1a0708b891c80724310e95b29183394390ec56c3a6828bb4ec394a39726c256","seed":"61f06f35b43abe9256e635720f4e74c8e3796ed4222c8d914c3ceb0f26e48d9ff772040475acfefda1a907f24c369190b48f50feb2fbebd3a84c0c9d3850ff14","priv":"8c2d6f4673846749f8d2e2f9902f28f66d33625d0ba04a11477335390f908552","pub":"03f8139b274b297d1d669fa505ab797a7caea82e76c5d7a3341c71133fe3dae164","addr":"bc940ec509f5275207ae9b086be155154aefa3ad"},{"mnemonic":"flat cushion trend region glove humor below edit ticket west multiply black","master":"2e72ddd445cd917369177b7060dfc92883b4b56e301dd6b0c7049517c102ac22","seed":"85ca476c295a5b708beeb6af45aad1eb6bb691fab82fae7c6d4dca48723f7819551d04395581ff769554ddb94e0d065f4c710afa7674f0c3480c1c2c4299591b","priv":"a57387ddae40887dbb0f99e8c84c092ac1fb8e245ddf3c9909e189ca2b70d52d","pub":"02d19eb0bd72884a3d753121d0d4489215a369aaab5ad3bbecf47f2246c5ebe928","addr":"84141ec76f71f2bb4dcfc9f81fb5333b9cd1ea8e"},{"mnemonic":"domain produce address tunnel burst emerge divorce health frog rare cook series","master":"983fc11c91dcbfcb3c1869da88972b03f7cc51f54db49533c012238ba89ea234","seed":"9d7cf4d9d3c664b8e51db516449d3dac01d290d774cafa90326e0464290faaa6ed6b780f792e80955ee5e6d7aa8ce0efdec13c20ea0fd88e5e40367f6df818a5","priv":"b96264f6b7f9d01e386ae43893c2a6b8683162394bbfc8048dedd4ce129e52cf","pub":"02ac9b86bcb1d8c6991572ce5044b58560ddfcc25a26dc4c74b12271c263e9f1e0","addr":"345821fe95bca3c777328a7148106d46afad6861"},{"mnemonic":"dutch oyster switch layer rapid fat prefer bamboo stereo staff spin midnight","master":"47d4c05e953b7636bdaa099a136986544444911d1fa720575872370f2aaec934","seed":"f120c319991b7564a6bf0086d918b39aef44877b361883f58db6f95551a66bfffd1f9708140c07135d40d624ab78bae8969883a2239b4cb6de5270aa5eef59d9","priv":"968356e312506427072e2e628a136e6e0104e3b9f74d8a00f384da0d62e58a30","pub":"03efbe8d47bd3c1c6ed07bbb357e6ade29f46d70d204f4af19e5ccba2dbec7c811","addr":"27bbceb99a49bc927eb0d6434b41c873ecdbe782"},{"mnemonic":"green claw tiny bring meadow tone improve advance federal talent drop fruit","master":"f0d9b5313bed52a853a177c338cdfa1080fca511d1a3157e3aafac06a6a753e7","seed":"8acbd6c36b27634ea9017b1ff25913a3b6aee3ba578272ea70d753dd1390ee31e9b0a7685c76aae5bd0e3cefb34fe6d077a7aa0a1da2fe3a2b4d8592907f7c9b","priv":"633d8cb5c8aac8d9e8f3e540ffae0f9a2fe54ec4b9f95c4378927be49f785bb5","pub":"03479063239cddb13d026158bb3519ecb95590d0be4abe036668f3bd134ce8b0b4","addr":"5a6321ea26d9fe346e9af87801f30f823cae4e5f"},{"mnemonic":"model famous make lawn wrist busy food envelope town menu hint dove","master":"034f244b9742152cc762f84ab5fcd03ea6020e30d766d209240f4a1a4bbf4859","seed":"79c41d550c0fa03c15114feb0492e362030a17a72d2e3d05064d459ff8a5ae877c2d94243615ea0f41bb82030e0401ea6a51eebef49c520cdf9bd923f9427e12","priv":"3dc937a202f6c5f20a3d57c657f16269b84f52a4701da93bb1786ea0711335b5","pub":"03e26c7ba82177671230c877902563ed09283148d9f83f400006e11c735620d94b","addr":"b4faab756175074173121e758b65bf2663b792c4"},{"mnemonic":"leisure buddy divert feature soda reward moon doctor fence neutral bomb truly","master":"9e8c30422c780174c05f3a5c333e116be6d54acdcfa666db96e0bc3587fa457a","seed":"728465a73b67017cff82a9e1d5b3cc77276f286e491e9621c21317485b78766fe8828fd0f03016ec67a9e9a42c355804c875874206b60d474c09e49e1eaec89c","priv":"90c91a0f640add78f765fa475ba8267e5e3533b0175d29150138b659397b0a47","pub":"02c0b78775eaf3515a49cf8ee65dd95e8fea30340601229dcdf2d2dcb3d39b3839","addr":"0c300d4bc57ff741c4c634a063c24823a18b1ac9"},{"mnemonic":"excite cargo radar baby paddle century average nature tackle blue rhythm garbage","master":"6a4cd79ab70b5555d3815424bbb8c232351a14511aaa3708dc4449ea80fa7330","seed":"7356daf4bbcbf682469878ee2a8e7a35d659d8f19095059e7b59fe14d9893c054559bc2beba994c527e8417f86c3f57a69b3f42954aa9a4647c91155fcbe2488","priv":"ae2aca6963de88ac0a4e709c4f84f5ebbc2d1a18f55be9c036e97fd46200ef48","pub":"0304f4343dc04ad6ea1c528296ac17c9d47a42cfb744e311f206bb154abab6ff59","addr":"ed8d1537a6fcf980fd7297ba56f1638935ae0fc9"},{"mnemonic":"must trophy era antique goddess local green rhythm gift van target island","master":"52e55a55dbb99a2b170c489c99d50811c47be205294704a2d6e7f234b2a938c6","seed":"9797425288539f83d965bea50c769e5a681c7fd6860502bc7d7d953a36fe16d8f0af0e6441a92b421cca44ff0fdc17d6118801dd17814308af5f6f1436a2e28c","priv":"8eacce7419f6f8b94e426adcae21818ce6525f0ba624bafdae44f0838d36676b","pub":"0244ae10f79e38d499c76996fd6ace738b1fc3dfa60042775f200315cb1e827855","addr":"15b8bec456e7346a6446c9679afb13a7e4e82079"},{"mnemonic":"day include route train grow number traffic across acoustic render save gadget","master":"553843ecb6e4e0383bea60a245b7f34c46d8d505806f4d900c7344b2dd4e1787","seed":"abdb30b82471a0c81df74e7d8f9fc2315b7ed04580689d5ad91f8947cffa9375ef2b6c315b695e642f43d08edcda3712afcd48e86583b00bdf5085d2920ddfcb","priv":"ea826d758734cf1965b67fe0133a2b78aecf582aef9efa46c96c61cb512ba593","pub":"0304501989badca08ee05c3984c8e299e5ecfc91feea52daf24cca7f236684ca81","addr":"9bd24b970d41b73640a86beb27f3533d2bf35c82"},{"mnemonic":"safe favorite ticket bus picture tomato unaware lucky spy creek upgrade duty","master":"8be9a1fc81f80c427683964bc29c2eeb135a3ddda8bad041399e63053cc37fac","seed":"3b7f10be92522ba2544356227f415046ba8b2faae9c3dbef1563aee039d00afe8b476743cce4495c264ed01fc095fdd09e3c2159b9b91ae01f49e5610f3dc375","priv":"114c0269408ee0ad873b847793743f06dee7be10da15d0db533fa682a644a017","pub":"03876eec35fcf39732629c5b3ea22c2309a28549335b9f221001ceb0097ee8565d","addr":"fc82a1a044603663dc758d6987b8b699d56af1fc"},{"mnemonic":"slam jar adult liberty small adjust right sheriff cover below space fiction","master":"75e789f7c7da1a83a34d2a2a9b54d4af6403292156cc775be81ade0edec4d566","seed":"ce1684c7045cbd4ee4c6c23d52ad78dca82e426256dcdb3a5f5fd9c635e0dafff12612e981dbe983e1ec5d88d6bc3294b84f8705cfb553923e397da5044b896a","priv":"bae08dd84c10433159fb11a08f8e3df9fdc503e5cd543a4e9231e96468094a4a","pub":"02269218f35c468c3fead430880577410b580b9dd979d68c94f6531adba7dab809","addr":"5e44c323c10036262a3b02974a6d69f953d0e359"},{"mnemonic":"real acid movie gadget duty hole apple inner essence confirm laptop duty","master":"132081c3acbf9bcedb0a237fbd41c882232976e1bf5467c067892a80f5d30691","seed":"495b41f5b0f22b227458857db55d2787c126b832dfae01384ad0213eb28d79baaadd13a365e63cc7c250504c5f9a2fc5bf38e174769c33ddb629a012219a38e2","priv":"44b3ef5a4c7005846196bd9b7987308ba1bb7923687749509cfb733b3aebc95a","pub":"022803c31147ee31f5fbcfbdb2313c5ef39b80b505cc21275cc01e0527dc6ed6de","addr":"063cf369f1f4122821f7ba400ba1e8248535fd44"},{"mnemonic":"banner indicate tell thing elbow mechanic express stairs robust rival shadow matrix","master":"6e76cc6fe8099d9232c107ffb8959c3c6a24badc35579975ffdc29316ecb2b5e","seed":"f1224c30cb0141c0da3f5cb31632ef8cbd88896e5ce98a5290ab708f5c0c084043fb19a4e360c17e161a3e6122e8fb9d3991c9ed7129dd5ee26bbb2388e9b7f0","priv":"215dad8e633e3ebbacdca2ba68a9747ec69de4d5bf794748500768272445d516","pub":"0259f48c2e291b1d0b29890c10ca516ae8e186d06bec8dd2d966d0b336b9a68a8c","addr":"7863b183b3f98f4ed5ca402c3f1bce45a9d58aee"},{"mnemonic":"boat minute dutch sadness globe congress color sort feature boost regret gallery","master":"6be1882f4d3812eb5cc92b5ec4ae762b565596a01b1c4216f16337663d33f85f","seed":"dbcdc6e305e0330f5fcaf159763664a8decb12dc27003831213b93c241d886ce26175c726b6f899e8de4f2b15aea6af2be816eda613f00a3f8bb3ef3c162027f","priv":"e30847af4ca7d0bf9f76d2c15906c955de0d89ce994abf7696ebbe0880171675","pub":"02a6f99d68bb927000aa3cb6847e349fc7f0412a75869cecbbcbf223707b7fe8c7","addr":"eaa5c8da5482c10d473be2c62206eb82312f3ac6"},{"mnemonic":"icon echo become average ramp undo actress sea water struggle interest trash","master":"d07e7e040dc9b1ce70fa78ff50d10345880fcabac783c380ed43885532d79ab5","seed":"9498c9409da005532ea8fa71aa658c9b160c6630498514e52aec48589ab60207f2770e4cf0f47a04a2d46a878b3b2a2f0f58c478d708ec9dc8f54b51ed1f0506","priv":"33a881e07441283721c695c58caadeb68e5576a526ae465ef48812b98d66bd9a","pub":"03226330049e98e5513799ded19923809dbed40226e958f9c36218e8eeb5cf47dd","addr":"b02c8d95cbc1417b891ba5d5c912a6e3b8cb6748"},{"mnemonic":"scan book mean egg situate dash chair water surge major sugar shield","master":"a50dba88cae4daa6db49e8cdbe710a305429ed2e4ff43c0b87cb0b88956f8f02","seed":"ca8bf187bbde692601b88a74c124c967cdd17810a5b4db55254a22278add4880b8360a66b5d91c0ce1c105f78873994361d2169a3d39bac0807a6ab7cb6b894b","priv":"4ecb295b77c3b1296fc214e554e77fb47df10cbfb22b980ba6e9436a2d884ab5","pub":"02c302c47bb2ead02062861ddb4c876b797607ed2a775317c7ad258c97139767bd","addr":"6f6f55426f790072f9752fd182a68710c2b3e72f"},{"mnemonic":"hint sign broom plate brown beauty figure song stumble setup polar road","master":"e4721371d82355bc7be6836a7915a19917d2efb313eab36abca855fc00f4cc7a","seed":"7f654f0582ce0c83d46e01477fafaecdaa7321d095ba1468ecd9fd6c04c67471a2e32187c02178522d11d9b9160de10c6cfd74eef79d6c50d013044a5e6562ed","priv":"612986c34ddfc5e93d93337f68645bcfaa2bdd37c8a6beeb7d58cab6e54ce3b7","pub":"0309c0b133a0af4f468285b0399a3c3cdaaf8c2b29ef61a4f8ef19d526b23eae6e","addr":"dbd39ec36261d32e313a82b4745c47489de5e955"},{"mnemonic":"eager item digital loop loud drill script ethics crystal tornado pride cattle","master":"1ed90fe65b73b2b50464a59268cc2a7a9bac67f2fb167c5b4714dfcb354a24ba","seed":"2e5bce8308d9ee56a168da570cfbe30f0dfa341df84cbd7674f198b4e419d48c65e1ec2b8600a2e7608bd148291c54ba29e5e7ed0a39d4418eb212ac6d7811bd","priv":"ab27d9960f7821dce58d2271652b42f8ddab5edbc87a23ce3177a0454b775167","pub":"02e1ed58d8c50877a6133c16e793fb6608515accbeb46ba07cbd3972c274534066","addr":"54b513aaef1aba872f8f521bd3b86c885563cde9"},{"mnemonic":"asset toilet hazard chief boy over trap session abandon jump wheat group","master":"43ca7686bc87728e62a5406222efe3ff40d4364a7904f7307437d1b2b13ced43","seed":"e04b7a46a47cf1c4a9382aacf36a32da16724eb1ba82f65a3c66679d793d410d3952fd7bb0c735bf96a089521acf7ec4e1f41b179b09dd75645b7bdeeb539292","priv":"e7295badc4984f21bc64f9ba723a92799ebb18acd8315686b5040feb603f03e4","pub":"02cda17b0a54b09d9389a06259a44004a569a7d862a9397d33f9fb598fe374bccd","addr":"f69a0e9ead6daf22623a1235062510360f0dc7fe"},{"mnemonic":"flat eagle owner ladder enlist chair next good solar drum service escape","master":"2de24f772282ea286aa716777f39a9233b38a5a8018dcd730b74bca33c5bcbdf","seed":"d571b7aca82b969fff273b5d4e876188c5b1124684d3ab8056f69bd521b1d030b617d201313ee42068f48dac836443ed6e8725ae2369a955133cf74682e6090a","priv":"232c2f9a62655637fc64e4173855506ddb4d3530807f4dd441a137981d636c11","pub":"025996bfa0d3593c05503476f4c340ff2bc32290affa52a130f2038b72deba930a","addr":"ea8a8d16976a6d922be30695d49a670027cc065b"},{"mnemonic":"hamster such legal analyst despair robot tumble embody coin taxi liquid cart","master":"f78ba19a1149f8dd5ff019f40fe5efaf8e0c5f9df5ef2a1b32df2b9a0cdaed8e","seed":"9d863569bb0a87d17b02c10eef8aa06edbd9ed37ecff427001f2e43cd4f101def938da306ecac02bc5ee83b886857e43f6248eca72e65e67828f243c625de0bc","priv":"5a2a5c105c9393cbec8cbdd79022c23407c556a503ede10645d744f20ec9ebce","pub":"03a14ba5b2261911010d2b2a7602b37dee944891b1e49d075b6729e62627a252b8","addr":"73ff0ff918c11d261453041ee18b38194d3aa57d"},{"mnemonic":"gun monitor turkey humble private essence limit member bike person cook ahead","master":"c3d138412cb4861effe93888a20e5072f887b2b3d3feac310fc8f40bb523f98b","seed":"6c79ddee8365c1c293e6424cd0c4ad5fa00256e9f8377e5692c3c60c1550cd4e00d3f08aa61441609b3954c271404888677aa4f7e075d7e93ada2f452984133a","priv":"865fdc61a6559f4ef787eb57210c09bcfd82ba9aa87a13a09e62746470eff4b1","pub":"03777c19e60200e1fd48d07f17c58c29bf6440aecefe503421bb13cd347bcd3e6c","addr":"a77712c1f028f11782d2805950c79e11d2229002"},{"mnemonic":"bargain doll comic scan fancy soap fragile benefit private sword share milk","master":"b26f239a994fc404b1aeb31ffd7f0bbcb625c881585dc57247cea88ed890b042","seed":"928a043d2007258b4cea3a478dd6b1cb133ca290142366af0ac60086f880cdec35541f080c8cc1d8d76cae811b5138d9de189557b37dc6726ac1df11ccc9ef92","priv":"ad650db8c2457981a143a3cf400ef1eadb5790368965a5fb8f28e8e0dae1991c","pub":"027ce8003309913c6f99fc6a5eb2020400118e3e253f618a418816e772b5008a75","addr":"67996609609bda5dfb179da0fe5e6c7614ffa922"},{"mnemonic":"father accident gaze obvious visa deal plug narrow shrimp motor pigeon sheriff","master":"643240ce9abd6d36e330c0cf47343823c3a3d4b533f6887aaac16d737c8a1a4a","seed":"9ebd83a564ca724a559e57e896940ac08d28a71613e9b414170539b29a5187a2ee91e3fd4bf258256e26ec5c41af2a57fd8dfd30f054403599cf9b4f45af5839","priv":"adc7eba12216571143e05626980ef0644521269bbe8870545b7cab11838537a8","pub":"023b065c65ef208f46ff43bd1051b494f60b1a395543952e14a3d53a6d1f347e96","addr":"7a7b0429f9706215b02ec49c205ec4710705a68f"},{"mnemonic":"reflect slab donkey village mushroom style brown pen mother pipe raccoon mass","master":"bfc2912b21b64143fa0c5a924573da251a9ca151aafc79a9038b96e21551dee4","seed":"fc21dffbf43c67a07c5333e57d238f07d0e1b987bf4f0ec763f1abce471a2e0fb27e733d5098fbeb81ed9cb2d4093ebc9c565b196c9900f39faf4da5448a2b15","priv":"d34fe09f482ae273ca07b2623d5b13180db5d14693025b57aadd6c7c51e640ce","pub":"0329edd6f8ab6a57ade9179889b4f54306a45f89b0007cf9843755b3aaab725586","addr":"c69fbd3b6e36a75ac8583713c1e3207253ec53de"},{"mnemonic":"lunch process rice hazard word vault surprise useful fiber trouble pride mean","master":"12caee441e7ec1c4109c53e42c8cad66704ca395108237f68953b137072d1aeb","seed":"19033ccf459d27009a9072905bae12152c877115e145eb5469f20ac8d763570d2d0ef57cfa6a482da6a1f2c38e7dd43fb6260a4826b54c0f03f0501df94e4132","priv":"4a2616ff7d529e66e3fb200e7531b4a08911a338e6a80c80182a0b98803eb14f","pub":"03e996278cd3c0374adb59287c00a526fa8a409a53a2606fb230748cedbed12f14","addr":"0f96e89ff4109143a838165bfaa158dd64603fa8"},{"mnemonic":"boring unaware cram sun mistake rule view rubber gravity humble detect zone","master":"23b29bcf96e849e44c0e8848e86596eb41908018dccdb91b9fd81b35cfe24523","seed":"25d1e2d98bbe47da86d732e8975f5c2ecdf2e107b641c6e9a259a49014dc35dcbb83ded97117bde45b0e78379ab0b7785aa8e45e2a628442be1ccc9a98e78a5c","priv":"d2c91726674b440f3aa7f105c17848c1e63d123bdc6ddaf88ecf0e6db40b7d1e","pub":"0367113b62388057da87fe1c781210074e0200b872a7243e05a8c9f39ced994acd","addr":"264fa5eeac6f6b37e249f8ba03168cd17aa7e258"},{"mnemonic":"extra hobby pond foil below injury light brief struggle gun visual recall","master":"80cfd73c33f507495340ad9370aa922b436b84d3f584d7f65cf6173b367331c2","seed":"d965ec811bf471bbdeb7aeb4c0fc43d710cb47fa63806f29661bc1aef4873455c6a97f85e675f6da0e975ffabb1356d310daaad51da951de68927933937e85be","priv":"67654951ada1ef3a6e15b3941d0eebbd1bcecb831bb084dac0d70d610ecac13b","pub":"02a1ad9bcf4e359f15d3a447b61b9f18bf2dfd56c52c20f267ae13b04bd60b0d25","addr":"13fe548ac9d9ecfd28e5c5b5d0b865b89b36e8a3"},{"mnemonic":"copy thank warfare visa else rally shuffle gauge method favorite dirt mushroom","master":"f76da13cf3b11641e547c33aed72ab423b7dbfed236da81ff3759d4ba3ba3aa0","seed":"24e7ebdd3792e56171fc46aa5112514874b67fce474a0ea4399b6cab23ead2dd6bc5201826f9127bae7419504de04342357c90a34884015edf094e52a7080d0b","priv":"0bd271e0b2adf4aa3f1b0ea862eb4efe72958d40ef2153e784ede4ffed2d4b51","pub":"03b42c815258c481e1e994ce430135aca9e8546585e82927066067a7f3eacf0223","addr":"95ee4a4c887ab69a23000fa3bb062d1bdd96371d"},{"mnemonic":"rude wolf aim frozen bargain false remember circle axis arrive virus echo","master":"98d35496c8e4f142a6be9c704611257b0520a14b328203fcc0b6b9419a71e366","seed":"ca47d7e6f88717ebac85734beded4a18c6a46e6775cb64b7ea5aa167559f90bb5d8eb9254599df6e09999d8dddc1e487c657c95eab703f756199ddc3196a5962","priv":"9dbde9c5f35f2fdd7bb33208c733021a8ed055af962137c23e06e252cb999456","pub":"02ed94e8e6ff816a2b053b959b261e7d8f8809f58bae0cfb84459d885da88355f3","addr":"38a0dc2d9bdffd96930010699ba2f39fd244c3d7"},{"mnemonic":"deputy among shuffle online fence mouse clutch joy away bean hybrid void","master":"e13cc05ed1c7f3415610c4011f994446c9c9c65df5e1568af347d42b31e36d30","seed":"f3b73f8483fd0cf17bba1032397207d4b593f54140391a91df47c5b8960fe5918b0160a18a1a2da8f3acc6585fccc19911c613424c91b47afab4eef5f06bb569","priv":"d323538934f97f44d23c78be6a5f6005a882126475ba4a7c953b19bec7678142","pub":"02e6c50799013ab284a676715c3c575be75806a5676281144cafd4c17481ea053c","addr":"788f0092868345453e40b0f38d44f4ff4af0f2a8"},{"mnemonic":"panda rule subway ceiling awake decorate forum cluster place club surge lunch","master":"f0aa8e87884a3e3462bd3a230081a29739fc62fafca9aadd9353986d27de4509","seed":"7ad436a119093e3862065629b195087e0162f2060d6e2a1e653be2e894cc9c3c4ddc2bae40f447ef87c0f3b2232420fd938c155938b4ff5fedb3fc7bd26e9eb6","priv":"9db3eddb02be190b266cd3bc93f5e45d126577bfdfb1df60ea9f2f3bc21cd2ce","pub":"03c4e1511881edd8d598fa65bfb4f9dfd93dc1f2f4944c790c2abc650492ce0a20","addr":"c61ee0480e8379e854a631caec02572b91c2b23a"},{"mnemonic":"addict foster exclude debris moral uphold couple surge reopen blind trash real","master":"9c7714714335b5d3bc2057f206da041c5b0e74213413c2cb9c98f521d2890209","seed":"4905780290404b998ba3ea764cf22ff5ee689aa9d783a7f6ccf57c9d2b4b27e4312941a2e4328232b6e0d2e7729cf30978b094dfa6ea369b34b6da35ee2ef73a","priv":"4e5be9010cf1a4ec010712d82bb0d18d5b1b1cd3095a56cced0ce00f430e81e1","pub":"02a18e4eb8623e1f0fc37434d1e18531ebf5e2dc9bf93af3f831cc72389cb3ed83","addr":"7acf8d7f9f6fe56e21ad77cc6e41b3b49bb542dc"},{"mnemonic":"bracket dragon until token cotton giant enter lyrics apart supreme pupil fashion","master":"dc8282dcc0f6d147d01f8ac326a3017380d56e242fe415fd17c0b6ea92dfca0a","seed":"b1a0043eff67b480d9b3b2c0b6676dc17da38225428cec06ca7884060b830ae243d50b659cba06166b6e8eae8d9c9d67a38554f5feee3315e90859b544833dc6","priv":"7c19323897d7640d225bbcab428731abe01c7b6160557476fc0bf97799f6cbc7","pub":"03f1a65a290bf4a7ad8585680304d187f5aeb3e51d44c9941443450270c457edb7","addr":"72caa875e043f9f2d3712a87317cf12c34980ace"},{"mnemonic":"catch unfair toy shadow hobby tuition remain leaf put blanket fall diagram","master":"611504571157c7451ce639658fb04945cbcfde1b2e487f9cb97ad430ad3c3801","seed":"b1b9002dcfec6d7bf1d7068a45615abb4aa076ad65e34f15d3f4006ec82384c3bb7d737fe7680e58089281ce9305ffc178bd1a23e95087c2fed495a20316ddcc","priv":"3fabb4604bf9163d245a293a4b50a4f844277afb9b260100ecf406fdb24a6d9c","pub":"032568275e2158b5b88f191d77cfc23742157a4c03863da61ccba04a29d6a5fc43","addr":"061151483994a2a2f420b081148754d5807cfe96"},{"mnemonic":"divert spot love tragic vast error crucial print snow filter fantasy forward","master":"817b4fb465a25b5dd9921ff72634202f30b98ac3040cd5006ca5e18fa851f4f6","seed":"824e5275f61c11ca6db812ffadec349e61afa0313d4d299c911eaba5ddd38ccbfa39a42d323f43aa4999bf95b997958a6ed0522930bff6968dc9cca2adaaa204","priv":"43919dba40cfbbdc53b2f8c097b6c66a6a391c28d9478fcfe23f29daa4f80194","pub":"02c32a7eec00f33e70c83aa4281d312bfba257bbe920f349dd3b674decf43e3aab","addr":"fb3e6b782cd14938a296f8986daefcb9c1424232"},{"mnemonic":"marble start nest primary author steel video science wire sister tonight invite","master":"8d62341b89e0c045322c270870d8c438ab41ca077b96681b9288ce2b04160b8f","seed":"ff79b45850f134169e1d12bc2c95c5f48933815e3062296a93644c8e88ec70f2faac59c5e0e20b1fe8799989509190442356a67596657156dd7b1eaaeb976adc","priv":"75adc55e735bce443ba38fa066c269d20c986d18d31b9c67a6f41215dc6205e2","pub":"0262ad481271c2b42b162d09eb549bf2e09ff953d78cc3b58f9633f0a2f0a1cb32","addr":"289c5796cb64589fc90d10c269093d9525249ae4"},{"mnemonic":"mesh rose keen want voyage net brave bargain session creek shoulder glimpse","master":"d3230ab8890910c45a3bf9d9d21b8c24a6a1aca2b87467b42c75cdb9204e1f2f","seed":"d61ef67df124c9b43132bf496bb3b18220a28c7c540247a11e25c2dff3ab8b7d0dabbfcd8125f03496a8fc4f888d6b8f8df9828ca406a3864881029e95578c2b","priv":"92d844eea97086fb63381e19e56e3b494af47e7cad3257a5ef1b46e21c4cc4ed","pub":"03be77c3a96734aed00ac4a0a18151670a213a911f3a9d78cf6f4e1fc33b7d0aca","addr":"e3a1325741de4de93501261a3850b374423ec97f"},{"mnemonic":"host increase panel pact gorilla alter cause cook voice ugly crop that","master":"22daa7841a31b77e2d006277ba1afd48ad7f066b4cc2b778926b4d4b8931271a","seed":"c1b9b9f1d4097d76288576869071b7efedc756fbc81bc62965c462fb0ac49ede2fba8110e4afaee3d9e187933fc28783aecfc9ceeaf87f63e75f4bc1eefc1860","priv":"2aedb3ffca9d76ee5070f107bf5c0dcb583bef571b1f498baa8708495f8f466c","pub":"027c929945ff29b6a5df3d4ad096849a270ae3052aa1dc74b7a14d4288421e47fc","addr":"97944948d7d679a5c9658168f6b1ea9772c49ce5"},{"mnemonic":"shy garage devote private degree cradle special fee plastic lonely legal agree","master":"b2150fb985a296a6548cd57d30f25bdb2a51c7163e96207353ad064ed0eba53d","seed":"474ce9dae1748e7f1c4096dc603c17696ec21f329b508083ead0651fe00dbd404a1703a7a90f0bd2f66553af28224c6abb93563527a6413732ec636f234b472d","priv":"2c079aefe8f9d45940fa7ca547243a229ac8aead5570a310ff0ea50e9579416b","pub":"03368684efade7cbe5d1017c8cb099718ee9b7ef52e7ec384d507117d1716faf3a","addr":"e0a6539483dfd061a878096e5cd0efd475b9318e"},{"mnemonic":"marine local subway mixed width zone palm lake sort radar matrix pumpkin","master":"5b1142363291deddd7fda0bd7775c7f2b1bdab5959d17d87830d96c3d07c15f6","seed":"c49978eee2d39326d8950c89a69ce6cfd4d51dd84973bdadb5dc517bb60185bb4354b3c5fca5dd0d10a9d8793c205304d1569af0b739bb796cc3f604edfd8959","priv":"84f09a48e36698ca0fa65597368284089059688c2cca84c72a22510f37989c85","pub":"0262798b5fba21efde82c22dd36df8261745c8f7046704e239996c634302efe8ff","addr":"6d81cb6953042af66fc1fa7755f48f3c3b529495"},{"mnemonic":"morning vast nut patrol owner body between neither earth always trouble mechanic","master":"abe0226f5383b2e40ac23a3cb7b486521f7b7af6b1108f24941fcdeef71edd81","seed":"14189de5d7d30504ea20b94fcdfa6054f70ff63f4378cb3a6715126216b571075879cd9fa1c1694ee16c656d8f8a2020adeef01f56dc814cf341aca1ee9e8e33","priv":"8da48fadffb800299535e930330f1c2f9dfeb45772c58764451079696ab3275f","pub":"0283e5b3d662399b88cac949cd41d65e33dac46101c6be4ab6718d7b7d4c1c2df8","addr":"bece5507c72c79ddee993158241c20ffeb20596d"},{"mnemonic":"weasel emerge sight shell cook develop entry truth era radar panther prepare","master":"2233dae87c1e1a6a98e1df4a573f6139dcfe49db3f2fc663b44503ee267b0c95","seed":"787e8fd15da3e7723f91521e3fe4b501b070ff5bbfbcd2b4af147a6067d751d5d1d992716519ad71b59a41ce329eb282a94cbd15bdef52567c8279c327651bf2","priv":"ef6ec780a7823965a871595f4f0c2e2e7ab07409f39ed825b1efafea19f39440","pub":"03a545388da649a8800ff9fff4bb33f70d94000e4b1a767ceec92f5c3f7b880783","addr":"57222240ca41ace976ea1ac308bb027ea4c64d36"},{"mnemonic":"switch sea bomb symbol foster flag grain bicycle case crystal august crazy","master":"32694a657bac54bb8b77e7d0d84014e41adafde6023723aa5779645c7c798d65","seed":"2719e5e2d4ea727d045817bb8cff56c62360b3c1c66522ee74d1b3e5c8d6ebd98700887d532f9d1f17a64bf683622b44df8dca30ac1bae5e296422cbb7741790","priv":"47b1b2ec336e0257687c8837c9aefdca2f45394bace57de882d7eba6c61da49b","pub":"034ad373c9e20284f233959b09432c82b0e7b430eb625c9edd1d5371a7038baba4","addr":"0900f4003360d4641626e75f3fedd19874b11671"},{"mnemonic":"asthma make clump clap tongue away used shift fiction siege tooth purchase","master":"0f28a391e22257fcc97aa8c229209ad0734e9d0ec8ecd67a203582f2c0ce7289","seed":"006b61f87ea0d6f9f87b0410ebb5bb54c9b8af72d3dc6283152b6e66a299b8ae0650ae528dea7b6fe5c6cf1652bd1b2c67b7e1c9ba5ccdd4111589216bdd02d7","priv":"6ad416539a8a969ee72e48e1b20e9502b90078dce0b5a4245d7cf12d4857eb5d","pub":"0274de9f743f31744d6e7ecf30c74ef56201c71b2ab56d03eb849f2adec2e3dbfd","addr":"67e73523c5eab9e70230fb7a806793419d28df99"},{"mnemonic":"nephew kick predict rotate maximum giant fit love float kitten embark another","master":"dd3cc8f83542c0fab49c660198ab42f48681db60661015e15fe4da87840b371a","seed":"5795b7fa476bc8f7b07738d313716d991a7bc2fb303fcd7012dc54e411bf7111d9c9159c9b28d74d5614b1f3a738bcdd63666b6b14b896311df18609521695ef","priv":"d84c0f29a4b95296e349bdc8bc9283367f5f68155fe92192a74f8a08e3c6e38f","pub":"02bc5af041b0710cedf1cb8895da55349d68ef4677670e89ce5da29f43bb063027","addr":"ad020570cc250019ba70e84f13a0b0c388443c08"},{"mnemonic":"filter vendor slice outside win urge welcome behave valley merge gun talent","master":"e20ace834dc8b88a259a3c6f983a8065ec612205e25da42103e40e968d1bbf98","seed":"1cedd43d959db14714c7e6f2f2caac10f548115f54bf7fb10ff4f178bb410530d8ade24d2dd770f92ccb459ba2dcf433d064c9c24f0d59137a2f808421e189d6","priv":"ca111d268b05839d504787ab4173f2d53cc459ea69c4965bc267db40b3499f18","pub":"0316b77b50cc08af7251303e190a4a12a96ce586631188d5f2ead491825db0b27f","addr":"c691a61bf6a5626bfa6b11f79a36c89e5f7efdf9"},{"mnemonic":"salt vote cook live accident leave define home section loop fiction sport","master":"30f08d7392ec4b37ec8fe00847aaaecc975ad1c98d64625b6e83525fd363b89d","seed":"85abff82357508cc583ff2c4cdfda7867467cc6889fb46caba56624f8c14e6141231c6b26ddd373b9e3504d90ce8b01da123ee72ae5a4db46aebf4ac7b8dda44","priv":"297a3c7969c15e6a3b4325ec6b4c768128aeb99e81dd4aa3cdbbd488e124b73f","pub":"02191258d0ce26b1e6adb0b84d19317fba6818f06993a46df1829a61a682a93185","addr":"a1082e1177f32b0b369429050324ae1c06461e44"},{"mnemonic":"model today toward awful apple actress hard reject discover type must member","master":"58168653609c2e12f079d799a7a344292edb46cfb7cf69a85f8a608acc6e47b0","seed":"bf3a70e5a322c0fad6db542bd4ffee2ed3ff85073e6d3ae01ddb7cf30773250c294529d69dc31f86ef390f30907c6da925cac78d10091d9df0fc97a6e48d9860","priv":"0a7c2b48dd3ec606816404246a0e28c36790c3b2f398531ddb7f1b7aa7e7d624","pub":"03f12f02b0cd5d3146eb28fe6a57eafcb542ac30833b7153e1a9121c3817d0854a","addr":"06eaa20c1fb4487be17eed4bcc57d49f1eeba446"},{"mnemonic":"popular among unable purchase matter athlete fever acquire mom install glance where","master":"fedb71f6c870bf049aa1355f4858675ca0c9a6268be575844d2313365df45382","seed":"be3448251aef8d22e97fa58862ff534bbe7a854eb0f1d574ebb49c4197328783c9f7a1b51202e5a37bf5b2410e3b6e11322977898c75241ed4806d1972102457","priv":"3f27d257bf6a625ea3dd1cc4ca9787c29027c105bda25d3fb44df992baa4ea45","pub":"026abcb82486454ef9ef70f5991f76cb263684624b040f9c7b1265569e65087036","addr":"197ff1aedd06d9015acb4712a4a3ed76b420be68"},{"mnemonic":"kiwi rail hen destroy path mistake protect carpet occur jewel pizza lazy","master":"7690775869756887b1866a93233ce2188202d12a4f0e01501e381b8aa120fd2b","seed":"82e3b78430fbad5184c4c7bcb1873d922de0758894d770edcc7a487ad5c10dd381345aee23f7d996dc8fbd44ed171b3e6e9b6dc19ba5c093925991aff3b303be","priv":"b0af5290094803ecbd0076266db8a65837d363be36738f267df6a5c37ea87b26","pub":"03a4b20c1179246419b5b5cd861ed440f3856b616c4bd5a04e0f9d45de91e25daf","addr":"ba2734783c80b277d6196850cfdbb7f1d599fd3e"},{"mnemonic":"cannon hill absorb ozone play derive duty quick unknown divorce history march","master":"668302ce757bac9a084220ac55e22027595a5bbf777dd344351fcfe668e58ff8","seed":"9282bc012e007bb31f889b9b284ed8dd02bcfe5b14528ffa0e128fe0b3d2bc27d3ce5240d14d581b5a530f66ba3c7146d891595a215b8faca2a0093287155171","priv":"82f9994e259551b52e63de92d93f21222b01c9f371c8cb0e9af15a6ac93b3fa9","pub":"030c0ca2aa6353264f3683210199ee7ebc1c051dc657a47f8ed9e95d50ecca2840","addr":"285debf5e963ce3fbd66a5fbb0841cb8d0a67745"},{"mnemonic":"wild saddle spring meadow spray lobster enroll album coconut chat marble follow","master":"14f5a8838df5b6546b7179704bcd40d5a168393bf9a65d0d5b80658e750b9cc4","seed":"565ab133d78d7fe7e8763fd73fd89ce7a5eeabe6841e5cdebb9a86f867c63f1ac7f3e1ea44029409bd48befc187f762480c3555d62fe9ab653ec2f8523b55516","priv":"229e28ae8746b90e772aa80afbe866cc08b0f49e40d4b1a512be21ea728ee0a5","pub":"026f08a2daea40b6a076b79c26de11bb1a5f74b9d127e79e1310d5a40675d5da0c","addr":"b262603b81f2f0ea718ee4fbcc9c807cb0317e70"},{"mnemonic":"firm mystery spoon brown rely mutual isolate degree stay brick brown abstract","master":"ffae4ec244b67e40036dceb4241614869beecad4e84fe6e41645159d3d5edb23","seed":"4e88efeeda99c5136e145dc0fc827d1a8edc96839311ae7c13e80443b4f8e7a907040d9a38be8d789200314110a91404119e33797e4ff5fdc790404322a7479f","priv":"be1343cf39f3758c560e38fb2b949c86225aa5a32af5328af3f476c94186e1c1","pub":"0379e9a16c9624525c15070ee3730fa02a9b8dac0d1847263789ce4df4ad22b533","addr":"2defd48b2cf9556c1bf6fde9307b17bad70018ab"},{"mnemonic":"shell open sing action exact cream scatter slim right sausage victory case","master":"d0bd4329ae716aebd1dbc4b75a06a4e6103540eb1185de24e180af67174cfc61","seed":"e55f447b58f363276a8f67672f8a4cd6a3bb014b5cda555f8d94e701dc775c4092e313e1aa102f36c98edc9f1c76d863afcec6dada643667f8dc612c43cba71a","priv":"31818b15c3b42238821b8a127a33e90100c6599d6c2ea10797f111b5a741860d","pub":"03c749cbf61f0e5b3cf815c454804486f64dc15e73c53b8957f4a1b0c1b3f36942","addr":"586fd2221b5f4dd31469ce689ba34160ecb002e1"},{"mnemonic":"mistake eye absorb midnight box nose bronze joy body trim give purchase","master":"8a97dbdb939254072731791791f1cb5f86bd61bee1b1a7b1c0220362b73f9048","seed":"ff955704f42fc8451d66092b720eee4153c1edfad5ac3b96bc87d0e1ff27a1655eb4c1127aba45906799197e1a92dfbb040304cc5acbb228f20c828d0f28689a","priv":"81b5ed5d49563e225a164180c53a55ee86432ee9e59ff5c6b1ba2dfdee8ecc87","pub":"0214a81bb7326df6f884b465b655f497c20bc68d2ac499d931945a56a20b21bab3","addr":"e4d30cd4f5b383401bdd02a01bdf1e7003ff9e7b"},{"mnemonic":"stadium blouse more trend reopen sick test trash glass bounce brain total","master":"a47cb7d914af1a75ca7ff6bc0192725a7b4b4daf386a039e9aefd8679f8a9f66","seed":"2a9aaff54cc77a16b4ab472b006768beb7403cbd11cc78aea80e19765ba685abadc03dc27c6444960bcffca5e206dc28f5564fdd05292f68ed825bb06ed6fe5a","priv":"7125901a72c60386b41bb65e8bb4aff64334ba8f2e032d2c032869b3b3a648a8","pub":"03a74cd7b3d21dd8698c7cfa4c30d81a454a55ce294171f30aa70f564f4ed71751","addr":"4a8f9540cb406aa75b0d68c2eb40869a8c25da92"},{"mnemonic":"fetch use target promote later more increase logic oxygen provide original high","master":"f06c1e5b33b4d18d65ca7e0b7627c23ae19da34a6aa55ccc8509fbe9fa25de3d","seed":"8ca3dcf901cddd77ad4f6db2a2e3a48fc1a00a81b372fde0dc926c4006c8cf81862013008d9e119d811512b9f98a84c7c655b071d28c295a5dd565491b961d45","priv":"44bff7bd7e57b709b5adfc54ec47d084d80ab9549479f4707a27e06a06083f2b","pub":"028d649230f94064c7837760706a615e7a714cae79a7b2363d493f9d4300b9a2e2","addr":"23b883cc57bdf88831c021ad62b2ae475e09d365"},{"mnemonic":"boat cause tooth danger box anxiety luggage panther engage human army language","master":"2c0c2474241d615780d2a1f34c4cda2a98e138c7bdfd13c97b341ddb8f5e87e6","seed":"98246a445ad873a5e8ac532ad64643c7e4d0ecabe60c7683996d58afbeea843c61cb9518461270cd2786453ce2ef39cac5818cb1aee0f336da3112be523349e6","priv":"f94665aaee7b5a07c328d74e3f5a51bdc0896f899c739c284bb9d882636c9b67","pub":"039f75b5dd06095b39778b0b5126907ad39a9c034dd5fc5e33f53cc00ecbecd8d3","addr":"af2307aaf8e07bc2feb04eaece0063867e64c4e5"},{"mnemonic":"much youth team what empty door language travel attitude rose furnace all","master":"df555390632d0ff6d8e472ef734e8e3f8f83061d5ddbbb2034f9370310356e35","seed":"f450c859e941b9d5e84126dd4710bd0113adabda8f962d383f8ba54bcc53d0e6e1da264d1841547ebd7c1bdfb8c29089a57ce05b64093653aa57e0ba51b0084e","priv":"89705fd7c86cbe5c18758ab9d4dcb7b1b6df12979c77a61c128ec13672b4433b","pub":"027949604d41872f518c8fabd333f8f351f16d68cd7e79e341f1b8368fe1b79842","addr":"36d1cbb6eb2510e0e3c2e76c2400dacfd9eae736"},{"mnemonic":"hamster adjust rally crew clinic skull private oval vast object school liar","master":"face99969ad94de93d7979a246a8e69e85dc6249bfc71f58ab6d774449e4f18b","seed":"ecc06609969bc31a47adc214324b7f7d81d09e0e3cb32eaf6b7be548f74eac5a9397300f0ff5650bff02ca895db55241d49b7037a54cf70e3fa62a3edd7206c4","priv":"c1d424295f77f3eb9f3a71c3f800d9a5292a2df311456daa694f5f6e12a7abad","pub":"0334e88812c848228b83e80283f709bd9827e991db6076a22f7497a3e73b641ee3","addr":"5f1a48e1eab155c3a698b69f11c0db64a556140d"},{"mnemonic":"dove grab grow giraffe pulp lift judge pluck dignity theme cigar annual","master":"3bb034fc63ce92269589e21c4fe89e16081e7cb3a29ec91f5ffb30bc077d914c","seed":"6f44f1782162a9d78af64e243dfe4d44c1ac521dbc8a00977e5260b6ea5d7aba6c205bc51b6c56b5139274d8b07bb31a728702df2dc2efd8f4f07c09bbff19b2","priv":"c2d5188d3db0a2dd9853104e3978c27d490eec8c3601259c4a4bf6e0fc30260a","pub":"03f7de67b6490d9cfe61818b22380450d5b5c815767c4efd821f3962ef4d430b58","addr":"0b5513fa903ae028a8bc3153b5f50b2df555a77d"},{"mnemonic":"wire silver blouse theme lumber modify muscle among orphan genius diary crystal","master":"28064c9af3e4436ebc8e71b424d749bdc6599b56f7ef1ead765606b4920d81cf","seed":"2a132c76e5b88181c24491f83f72b215b7963972f98c3d165c3a452f88165b459bb6e3756a511f40f9de0d47df6a030e91484a2fecb1648b9f194199143ce49b","priv":"232ec9cf0fce12247cc6335c9c8d54418a7db5aae86365558646d9d69b64af02","pub":"033e30397518d760b53821e3c0b3b43b324853c919b77a855250abe95d3924741f","addr":"dc7c6c94e8f7823485edd555741cbf224087f137"},{"mnemonic":"pattern syrup now tired gentle accuse rib cruel cluster wagon sting situate","master":"39f3af4487b768e1f9c7b04b0f713d4c56a5250994850ea4b20ec010a0879028","seed":"387138abf6c255b137a365dec7b8141ada4fe9fc55d75af013270f2df78328048981e69487873ee8740da3548ba611cc90f5a9315efafff651ec41df50732068","priv":"7270c0bd092550db36c7f5787dc20d17fd98edcf34d3d662085af7dfe604c8ec","pub":"026d65397b9ec78af76ec8a6ca1270cd0caded21aebef86160d4ea446b3dcc2f6c","addr":"35566b676261d80bd15792cbb348b79da3b10f56"},{"mnemonic":"blind force awesome radar law patch warfare defy device exist chuckle because","master":"b5eb133b2b7cdeb1bf5e6d3210f6a26b79b544ecf911f6f8cd838c7a6383e0ab","seed":"8a4539eb40090aa2cee32979ca6e8a23c1dcff202c935319db667cef1d2d49cd2a71f9cc54bdacbbed179b20feab254b932bc3c900d24216c089ac4f5c2cbac5","priv":"45e109f71861222311afe9d12b8a2a26d6f3fd0484b97a96bce464bec83346a0","pub":"03fd6c933a364638f867e6fa329d5cbf35aa9701061743ce5f1f6f6daa7137b3c1","addr":"dc3b76c2afeb877b256d7a9375618d0ec526fd6a"},{"mnemonic":"chef flock stem illegal later shadow tragic story tongue also fade core","master":"b7e82f75da29acb35a7714d3bf3aea45196e1857b5597a25b8a7ef6b69e9271f","seed":"7d02c419d5370133b6a0d0bda76a70b784e530c9a0b389cf2f6eebaa07ccaf946859cf4a7b2076814909f71c9c84ce3c0e45ee8caca9a753d5c2240029ca8847","priv":"555a830f9fc1f99debe0fbefcf34df402655484e5054c3fbd6c6a127e3356675","pub":"0238bc6cfb2c3c335b1564fe159e478d700a95ecc34ef23b7af3d571da8d136214","addr":"d3e9edf902c8dc5fabd17c17db492b15bdc33ae4"},{"mnemonic":"paddle appear actress output peace maid foam share afraid quick into erosion","master":"a3eb9cf3115d6b2f3cbe4bcc4f06e879b837d3b8960853a955f1231b8f95318e","seed":"a6b3ea2da0b83408010911cc091f9bb6d296fb13c1607cabb850824591ee5f69d0a2d4576a4361f3b368d34469f53282a1f9adadab3f8ab12956efa6d323cd5b","priv":"a37a2cf232918206e68593863c195d4319548c85d113456a0531b160b1c4509f","pub":"02a129fb596143418f94ec7bb1272aa1fda227e606c99f86cde12e8e7dd9b06755","addr":"69cfe226958b42832adcf69c7c84b734459af9f2"},{"mnemonic":"they garment wave wolf rubber firm toast hidden grit puzzle march rebel","master":"9c20ee12718c0fea98422c9ae0fa861da154552ffeb9e9991443edf224557309","seed":"99880bead4bf15beec406d9e980b46db9cfccd80473fe36d3471a0be1cce8f13bab732ace2e3589b1edbc5900c6641e088dc7a972bf11541ad475d97a66bd61c","priv":"b38db625f8ee7badcd89d159fa867b7d30ae946f199141f63af8e36c59750150","pub":"03ba880b842c952123b8bdb306fb0ec8c3c39e6bae28f2241242858c5c9c8c574a","addr":"24b75369a914827ee1e2697d5f591a58cf3f7be5"},{"mnemonic":"virus stand margin found heavy gadget depart idle guess siren mandate sock","master":"b6489aba56cfbac38041a70c7442bd298928cc37706dd01481fae719a2cc1222","seed":"fe240f7a830cd984b4b07cd77ba9a4f6b25e753cd2c981231e1458ed6775969a6b032be398838d2b5a706563d575177812361fa7cd35798e9a260b5454f3cc53","priv":"801663a31b3fa9f6788c826388b6d7272c53b0c331843c3ad19ab8f97eafb1b9","pub":"03067a334f5db13f9918aca85c5465042a8e994b835d6491604ea7c6b5d8a4403c","addr":"10cbc824bf4e61e2eb4091c0b1afe0f24ffec681"},{"mnemonic":"logic drip eternal frozen equal defense pudding prosper destroy chase faculty position","master":"df13ceb0854b9a18c97c8c972bc42e85231d26c4cdc87dfd3b8870b8ae0bda01","seed":"df990ef85f0d21de059f96b7037b905062b9e098a5f401afe29ae379a60c611a45cdd93f98f4994f231e549f739478566e71e7793fa750e92630aaa661b30e99","priv":"0395a33ce515a68172c9d8a324fdcb81073cd903f092581beb8ca73e8fd3016b","pub":"025a43eb1e0914d6f3c9269123280ec49ad469058d623230885b1f5dbb5f8dbcfa","addr":"6fa784b66d9a3c27073fc463e5a306916bd64374"},{"mnemonic":"nephew august wise enjoy age comfort hurdle cross feel depend south current","master":"9c01203e9921c9cbc2a05aff4cb90757f3d2e615ee6c6ef2d79100b48a48214d","seed":"19b2972d829bab57e706d21f00356d24cbbce556251aec246c36cd7a5243898371c92ef562ab2619244ab5e4854b9f76f76e2886b35cbf591a154a2e915a8a11","priv":"29af8262b1361dad291ed3e682a77a6bb09378c6503037da5c236b5eee1ccc69","pub":"02bc9c65596cc3f49aadad747651387a44d922de3f8b68a9876fb55e50372f1fd0","addr":"c4e1dd670e6c2ffb3a964315b0f7a51b2116126c"},{"mnemonic":"elder badge muscle tunnel sunny ring kite glide post slot injury crime","master":"e5dd0863b56bb3058b0aa457e17bed226f7f8afbc09c7ebf3cde93ac5912d22d","seed":"cd12f2dd94caf3a76292863e9528acd822c915385d8b84a09326b498ad5f1a60a1750686204b2c51093a3a3003ea558bd490cec607837675d2561a0b6f666a81","priv":"0f8717c113f78a6aaf7d57a93d5e7ec3a0326c119f792e8d16dee61b485beb16","pub":"02be9b54e62d1d26d08c1a2126c813a3a3a1a8d399440471491534dba209b3b8db","addr":"dde70795b05c51858f513bb59e2e0aa9d0330aa1"},{"mnemonic":"lunch cereal approve swing poet fresh sphere spray tower scale clerk main","master":"3c7e4e9876b819aad6e94d6decb42f615923873a72a2ca8b6df3b8b0ee1c77b5","seed":"0f9fb7102299f4b02874a785f60009c616ffc1e74e4386e78ab3abe2124257c7aec23b8926883dfd343f7260bad204f1261bb76cf0233dae8785c5e3dc9b015a","priv":"17b7b6f6184325c77195a60bcb15358b318a53ec2990dd46d8f60d0bf7e2e245","pub":"03eddd35bf621d1a943edeae5f5a5242687ee7f99f14be22f694653e449b77c177","addr":"06e8ee97a22bb6b2d458bc408bee7384749ada83"},{"mnemonic":"night law title fitness critic soap runway patrol carry drift damp state","master":"f7cc66a4812f3a394f9d52a0d83777f22eaf8fef4575561e26b0c636c4beff55","seed":"99acca4b65136a2b94c935892e265d125a1e8ef834e52efdb7b2ad09d973806dc318c43b0805924f5b239b74e6e516615ebf42d0379baee78ab63a2a24d03bb3","priv":"14506c9564b199203e8222c7508dac642fc6f15c981a7ed0fd21658c18660f04","pub":"0205f6b2c6ac7c0785d7f0c9aa85258167a314bacafa71f478c2577b5f9a3f9dc9","addr":"b380fefd78145bbe311a87e314ddf3b33d9bb34b"},{"mnemonic":"predict either bean grace myth scout number used void clown route member","master":"c7cba4de1441602a0b8ea2e11a4d72d7a21cae827db034ed4e43cbb38e608a51","seed":"8e80bededc4b64dac814dcb6e8dc5ce3acfb6f59988f13e24106fa7b3205c72eca6a16ee44ab51a54ab0a07d1e7d855fc75e3bcdd5d652e10a8fe33f623b15a1","priv":"6577584c26c25b3d6b11a1f669030008793f3d173721acc811f2dfd470d9e136","pub":"02e7f1c5213aded8dc3a44b14874cd9098a41e5cf0a7c83b7b3e045b8707d1d306","addr":"17614a88c0e044659cb6f99334fd1d8a83390df6"},{"mnemonic":"actual between river curve keep sing hollow bread theme corn mad easily","master":"e5498c15a99ef460088da7513360cc0e8ed3de095027783154425011575afd70","seed":"55fdc52505724e42ec76e0871860226daee30280de52f3d0538b8cbcc426ecd2d44287b4f1f11c01889ef63a6012896311a81f202c41e70725f3dff333f357c0","priv":"05b5a9a68afd24c6970b1686297582b3cb806729a277a056853f8918a706b0df","pub":"021a01e00670749567cd09de2ed8d0a66f0a0cb00cebb969ec43dcc9d6718da372","addr":"fb0c39ecab019c2d259baeba4819d924f8b9d97c"},{"mnemonic":"route aunt shed razor invite board ignore tower penalty claw absent solar","master":"c0f943565964df86bc140e8a8099ccb23417e7b86bf3c9f4d8aabdf7271cc721","seed":"111f3c5d234f0c02921ba5b30149d1913956a6c37e93fafaddbb3bf437b6709599bd623ad6ca97610717db77802f9c591ba352e7b08f4a06a4b897b9ac25c8ab","priv":"bba974522cb69e90b6b10ddd32f3b313bf5dfc129628bd2f10ad84a742a22cf8","pub":"0341c52f99a97637d09d68695b7b28f0c99d3fc5218d297e7bd95b267d2d7cac6c","addr":"5b4e4a18db22862daf7c43ec209bcb61ee139904"},{"mnemonic":"roof select rather approve must trumpet during more outside off owner blanket","master":"840894a95b0850e37a7424cdf10f73361387fffd96783a988a5d0e27012cb2cd","seed":"9eb1782d3ddbca4be52803a2dfdc85ef8ed55bc9b939246b9220dd911360c7323908996bfdcebf51b87c31c55cf2109c4792cf54b60374bff8f2c46bdfb97973","priv":"2db028d5651025a18a06e2c9bf77282f4bf35a8f54788624ffaadcb0caf34474","pub":"031c85b1faa9a2c9b3ad80328c54eb24cf27837d1418dba04fce05565f91e3344e","addr":"a7e4da90a801adcb7b3d9b947e760966fb4aadd6"},{"mnemonic":"album ball volume coffee motion cattle album wing unusual tornado bread stairs","master":"8bdb565fdd586d6aa72a53ecf88e2c81d48552034401bed5d130c862f179d159","seed":"aa0aeb0065b4c8e008fc9b1363fd4b32c0405359dd99f3a27670874bee96e8f1d76fdc807bd903289fb66b33138b92902ecb0d2c1627ef39353eb973b21b0003","priv":"54288cb0b5530aacba3ae1b16945a783e76ffde7e7c523c0c1e1293f00b5adc7","pub":"036974570620961a4e32d0329c851cb1e4218566056249c534ae92d77aabb73438","addr":"d7e65a2d95bb5d705ee894e16e4b6e4aea4821ec"},{"mnemonic":"start staff chalk volume emotion liar route lady sample mind casual involve","master":"aa479da35fc7c15a84e37a118102c41bb62012d872e34fb4f1317b67f9d7c452","seed":"70a8a8b15f77356e12438aef9fc97e6e6279be885fdcb28968db25d5c7bd2a3685aae1ee882d49658414af583c4339fc97f75f70f5b6ab23d184768cf12472b5","priv":"e1f12833fe2e792a0d959de815678a79e1e86342c7a092faba765979fde1d93f","pub":"02f127e13853937be361e47873d965fb8a6d602426c89389ffb45ee712e86e8231","addr":"4fdff2b288741e9f96b6595136c780d979403e2c"},{"mnemonic":"canvas fashion mandate will phrase spend galaxy good advance dismiss inhale holiday","master":"71707593bfe88f2751e6b381282fd71177be82bdc7b930c89c3f30606e0fd356","seed":"c0367432ce6b26e2d0b279b008b1d7d55e89b50b3dc55244360eb611d3af8c4e2dc6ee92f38e5e32309d4ca3b0b5c9eb9f8ba5edff66650dd052ac01f65ffc7c","priv":"0d53e4411bf7c498836412991515876c671967b55704e2928d87f3559a922911","pub":"03bccf2d3a8927babc9cdb6ae16addef1734739941071149122e780c9afd83877e","addr":"e1f22608018d5a6ad02dcac24a9ff28e065ce2c1"},{"mnemonic":"area thumb debate bracket unhappy muffin liar cute subject resource oppose nice","master":"416206edbc49f77c17405abe51397e5d5b547d300d296334b9848e4a844f355e","seed":"a08e97cf029eef0c4bcb3b2dca43e64b7a358199ced33a114c390ea81bdeef23aa7a4d6255993367426d051a56106e485d78f9b4057b4c50dc242d95484b39ba","priv":"9379dd5b24819205a9c7cc6a30ca2a416e6008af93817087b16778e9fa022fba","pub":"03e0796e8edc870070f179c669ef8acac6ba5d745c954762e5738e6db4d73317b4","addr":"ba2f7b307d6c8ba32f9f39174616def7551c4dc5"},{"mnemonic":"ahead face gloom dutch simple battle either hour abandon slush episode view","master":"5c953db2136db4be64531ea6556d5b93f1731332727eafa12630307dbc65c587","seed":"31d751f855507457129f25ecfa2ab8a50db37da0fb13b62ea4e232fdb8c7093c236502da769a0b3474a9436351b87df03a69c70b1b96c61f1675b8fec00f8ab1","priv":"aed4993762d4e8e31a12b500f8beecc1a3e747c2ff290c4e70141de4ed12be8b","pub":"02c922d80cccb9faa955b2ea0a90d3f72a88d8dd203a51e0aafb36c38af1f4c880","addr":"cb41fed3b24d89ef058d25d7264b6113e0481ce6"},{"mnemonic":"van custom clump rug floor what joy live art weekend unfold frame","master":"ab89a9c945f11e8ba88683d2a13cab657a9c938bd9014f19cf552bfd1db49bae","seed":"fffc2e2b6c4e1ff826e0d68ef4a2660417278cfce527ca55e48c5d3286d78ab4d6ca874514d70164e9040641281478b8c3b078bee6447d78262cc0556b463c4c","priv":"cfea30906faf51cc15f5ea6fd96ed92a40dc4bf80737a20ba37280e63ff1ddc0","pub":"020bcb8f7581415d4fe27dc7d0dcb25e4e4883d1290284f9d3028a6d0d618daa0d","addr":"57563ee5328ec10f7af2d0c44b95e5084afca64e"},{"mnemonic":"icon series document grass dutch green blossom report violin beauty window luggage","master":"9a203cb69ec2d8d19660947de9dd0b46ccbb07c9fcccb63da50fd3383c5f31e0","seed":"4acb08487e8a407ea10685ffa35b1c040e4dbdcb7e18a25c94a459bc7a2224246a00b66b88e6bea84948ed07f818e6e1a8fd4ebd102339773e704ce048a359ea","priv":"64d25c6a43d0aae389e2bc5b8f7d260098d85dd6a8ce929e42597490e5240ef8","pub":"03602214319ab01e65bda4711f9d03be60da39e092472d50492397e8f38d90f8fc","addr":"21fed5aa21ab9fdad79aa757d1408c0921d08cf0"},{"mnemonic":"upon legal wear defy path object fold security stem face question hint","master":"efa4834167d9f43a0807a950687e79ccf9327ec707fa4324ce8bdb40ed65e692","seed":"da5371985f4c48954726882bb278971512f9e4ee681645fea98415bd3ed4c7b049bfed3a3105f4d064b61de443500f53b4996c1fd7d2835d6b3e5b52cf67df5f","priv":"963ebebc47e1bf6c8f8cb515d7044f2095f61a8f77ecc2c7d5f8d1900af3b41e","pub":"0267d73ad34ba786e92207f5485f8aed4c634bccefe1a6c6a018dd30a9969bf1b9","addr":"f7b39221ff5352c17537d201c7d8422ea4c2f256"},{"mnemonic":"adjust symbol absorb winter dilemma reflect private all eager naive bundle lucky","master":"f8469edc4fc1bc6f3b934bc6ff8658f03fe2bae4d9be0b2689caea9f23d708e2","seed":"cfcf7299ef520c324a79db53e24326523e1d2346f173ecdd2bfdb38462a83c290cf80260353ceac5089efdfd9c819c3f0f15ed653ac3c4719b0ee6f0481335de","priv":"44025bd2acfbc6710d64d8b71eeec4934e054ab201419fbd553f6427e33d5197","pub":"02bbe2326c3d6c372c22c3aaf8118742442d237830428824160c5e703c268e06bc","addr":"81986a5c30d253a2b2ad8cec56dfd56ee3435772"},{"mnemonic":"fringe betray observe subway nation dignity stem omit topic lyrics index cause","master":"b8656cb35da2ecaf6b5189d8d252a08a15495afbf756ad1365ed757bcb46945b","seed":"cf0cce225311bc1fae42b654561de73cd2720d5a2e280cf39a1391cda8937fba9e69bb5b73b31e929d39a5f58f9505351f752d7666aa81211f69945ad81feba2","priv":"d55bc330b3ab7d09b0da10c1640c6fdf10909e5c6318801c3e7f877654b8576f","pub":"0222c2696c6480e840a7ff5d106f025d87309a0754a3638fcec93a6c7b8ab1f48e","addr":"2bbcd167f45d4f265075a2aac85d0ab7582d435e"},{"mnemonic":"ski labor urge doctor repair purity winter pond virtual salon number supreme","master":"283171546741970d2804029ce72b5848cc479f32f719b4f28670b00729c9ebf4","seed":"4aff8616a56b882083dc3f586afe1128f17aaae7b0c751bd24109094144c0f7aba69dd63cc4490301a72ac950e6a9c71959fd387629429a65178d1d4c7850322","priv":"2a0f5db45dca9a199102d2b920615cf2cd2c3a1d06d3fe72d5a64291fecfa116","pub":"0294a39a5a6f878929b7c18b0df75c7f42318864d84eaaaa68891f075f51906231","addr":"5173ecedd00d5de79bacab582a5b3de6f0534765"},{"mnemonic":"surge move forum tongue female cart foam coffee hole screen short clever","master":"57dd827d6deb98495732fbf12e0098970959ecdf113d441bbe6bd5064abc07f2","seed":"606c47f8d6984ce47270900cadf4cf5df3461f9293beeeaddc537c2e4b1d3ee7456ec7165c51e267d3c02a8cbbb5a2478626e475483f121ca5856005d0cccac3","priv":"3895a34ceb1de14e7e863759517cad044901cc7c8323e8565bbba98f5f3719b0","pub":"03a30052a8169da7d2342be9b0e2788df3e5ba7b4e6fef048662427476d875f537","addr":"9d9d8be022457576a9bf8a6a48f760fe346f22e1"},{"mnemonic":"ladder now flat food giraffe myth tattoo client party address tip avocado","master":"9986ab1b096cc4a635c2f99e7b191ee4d786b090cb1e00bed2cf18d6ff919aff","seed":"2bdf711ea898c4d62fc1c30a4a55dcec4928186c9d118befa4afd8c52d14291b3254ed926b1b1bbbcfe5ae775f74da99fe2112c7e2c64013b8f3b9de5adc18b2","priv":"cd0cf663053d6ac0d9785c3a56ae190fb8d0da670d6529e2f4572c1388dc6d8b","pub":"02ea2969ffa84be7d76fa55f4a897ecc63ebd61858b7561d41e179a38c7dbf8b79","addr":"a640cc723fd1d903e60a9de68e0a009b5e215812"},{"mnemonic":"change velvet mobile copy column cabin mountain shoe hub collect gym armed","master":"f80e68b799c63dd914912454f68a3c6ee5e01530bc48c130f1a4cfe46fdf2265","seed":"1bf846591febdca13c576bcdadd352b4b8b2ab8e346ab7db8213120d5b2f7a8031144adfe06a47f1d200f69c46bf9dd6dfae8e2d8dc94089b4974275960964d5","priv":"370af5ea565ec8725dbb8f63e141b12480bf43d39c219d612ff28e2a5fef031f","pub":"024f70c3096eeaa522240b50c1ad7347f1df1e764a305b8e618489788bf15865d7","addr":"e5226a6737202e5ea8d44f84620317f65fcd4ffe"},{"mnemonic":"crystal impose connect thing cement grow gospel reopen hand frame child shuffle","master":"a8d5b74cb00dc99c4fefff90a2f203b7e73daec3c7edfc71723894db050771f1","seed":"4e7c12a432766826d61cd07bec71147cd4282b2777b8ada1d09be5b873b9c51fb90ff4f4ea75739254fe7124e24696f66313d75289dcfb64ba5f5c8988b27ff8","priv":"7bae6919d134d0f150972cb0d96b0cbb3002d0d3b70efb2f9b03541c3830ae21","pub":"02daefc7677b5d77ec5fd27cead44fb3bd2d089be2b2e9744c1dcdc2e7def701e4","addr":"dd3ece1b6e903523289949e7aff1de580a536746"},{"mnemonic":"seek rain danger defy olive pluck people trumpet wide pave still cactus","master":"9d45b99a256e90347877aa27845d7ce7a259a8b50f7039852c60c16c372202c4","seed":"9c3f7dcb4aada2a8c204bef9a28c039dddd431f3daf5e70feb240be712cbb3dee3e5b65ed1e681255e9bb53bf762d82b95dad1bdedb27d0e18801ef1c5edd7bd","priv":"f43ce1484840f98f862f7d9c835bb3987fbc0413cf9121233bc29e829c779d45","pub":"02d82770b2af7ebb2a5eec49138178dd7899783a1ae1ea43ec3b2a13d6acd90c4c","addr":"49c6feff9794634c9fa66c76150375637f52ccc2"},{"mnemonic":"cat bid just hat diagram mimic field engine light elder resource render","master":"bf8a65e5cde0094db2ec4a5d776acfc944b0b482343bbe167a4bcb0a3492a9dc","seed":"780befda0890785a11f947a7da4280b897ddac841fa65e7cfbb01b09a46af665c25dba88abf759bac86e02d25d90c41347cd872f8abaedb158743dca746e87c7","priv":"b3f9f0ea5881318a1e011283a4e845ef6fa8e1ec5110bcdbb02cd37c4321c0b8","pub":"0214709b38a99a173a8b030bf9392534ae50d157e9e247f83d271be86872846336","addr":"9a7dc12f808fc5e599e2c03f73147317e381822e"},{"mnemonic":"eye thing material display own coral ankle spell hurry empty pitch sadness","master":"1a7c1facdec5151ca8d52af1f507f45c6614d12836d2604421138339c81dee2e","seed":"9c741558ad4c72086738a34898567312930af3221d13b160a39467d966862405a7f9b0b8718207bff6e26929cd33c578457b0d43e2e6358d488016c6ed7754bc","priv":"960704fe746bbf00a1c8d6bada8e500f2a7155af9f8328b7e4da7fc89fe079cf","pub":"0217e48b2a7ca750baac93ffa241b6fd3cd2422989096e0ff5eaf89f23277efcdd","addr":"13c55c8720eb51b5638331330ca19291213fdcfd"},{"mnemonic":"attend analyst stage network secret matter tackle safe stumble rifle lemon minimum","master":"e23dd8723b90971d4e03e21655e597b5f8110f0388392eff572e88db7f644cad","seed":"cfde90f605bace06583d24be20b13f73b3fd0acc60fcd93c2cb7d4eb6fcf70c885da2da7b709ba036ba20c275d99dd3a6af434b00932addbbd7b51a10cb5ddf4","priv":"ee54ee95a349da703f6d192fec6f776db6141a0cfa80372be04ef8b12ab65f82","pub":"020850e7d1011e08d7fd3ce20083b6c2658dcbdfdc067c979bea22d86403da9992","addr":"d834b0d108165f814c2616c91e18ba8b76a0ce92"},{"mnemonic":"student list element dilemma air faint eternal beach approve virtual fold large","master":"0dbc34013e5fddd9a1fc2d3e67a2d6d7445bc31e8343b4bf1a9c4941a24a2691","seed":"61b310aaa1875695f855a341f64b849774e3746db36303ada42eb60bbc91bc0fa7199c10f853e1def5fbf0a9ff2c38dcd803866d5473808a5b6340d88260cf57","priv":"ece1069e2cec7f5d270c3504e0cd9d8806eeb7ce8ce48a138c92d93d68fc9b7b","pub":"037989ae45a6a1f0ffcf9f73f1910a91bdb1ec39101810f3916d29a70b92232949","addr":"10c79559de51b7b96a7e0aa97f567289c41df1b7"},{"mnemonic":"ordinary fade chapter cheese patch injury better toddler rare manual rug opera","master":"ef81a17192ebb6e980676cacc7c9ace6af5d449a3c976d4f9a8a541dcef9d7a9","seed":"5a277523f2cd468b96db9dc30f8dec2d006035e388ef5348bb327eecd108d9e2815b3575b0f6d0da7560fdee6244194eefedb25edafd6f53019a91063478dca4","priv":"86e5fbe3136bcb11f0ed6dd97e3fc30afc0590d38b637fb19589947bd33f26a1","pub":"032fc8cd996500910443186db8432f24eddd6e04e00aac15db80cb5fcd73b7ec5e","addr":"db0aaf4c44693b2b93a8901640b940104d4931c4"},{"mnemonic":"leg easy evil ceiling candy okay afford apology around duck access ostrich","master":"098f864a847ca737aa5866f14fa96e9e5a6958758b56bc205d5c45f77b2f6fa5","seed":"7e6d013d39c652c2d57ccbec782fd0b9da7610d3c716b1c5f374daabf44f0a21726cf39b503850a5fe7daac263cd12dafe5c81a38b47e59b254027ceb298b520","priv":"1b5e814a954729ec4d4d25e01b52e6a48fc3beec84e43153cf9e5b4d5e61b852","pub":"0207214c051cc66259f234100e278a89b7ca3185ecf264d596ac8a4d3baddea28f","addr":"45cc1c7df7fb67a482dde6285b4dff7087857970"},{"mnemonic":"episode suspect cinnamon recall shell search allow hedgehog web avoid hero expand","master":"ede0db7b34ead2b35bd378d62d1b202ec206a389e27ba6d70813e3f98544f7ea","seed":"186c47e08e2fa1151bdafa4c8d16c5f6d8e9a61600a7ed76257cd3b41338a6d158d34ab84448c34c871243e211fc5082d3a6e199749ecf5bcc3fd8341e2b7784","priv":"d19884813f89a780962d2bdb40f36debddb81d132baa29795022b9498f04de0b","pub":"035f028dd1b126d6ea1b8091ac9dee9a3f44589a166d84a88ee982bc040c67d1eb","addr":"77b6f1f39bd0c5c636763b855396d1fcc5109778"},{"mnemonic":"safe run differ offer valve sing stomach table update base pitch pyramid","master":"1f6e07713ac34f997bbbfa0148cf2cfded624ee8eb4c89a66e2a88af2becaa6c","seed":"9c07c30f9b29fccb62670c57b8bc2210851ae9c80a3aee48c03e6bd35357626ebc6af1226f236508624fffbb52a8cc56fd21d8d2ab72a893a931c4891a33bc09","priv":"94c75ada800b2f73bc43625d569caf9f59f3afab6c2a8f9b023abf169c1a50e7","pub":"03263f919a4f79646ba17e1521c15f30d62c545d59c12344d4ce7d7561f8dd8428","addr":"17a63a29abe177f8bd93648ae4283b175b83c841"},{"mnemonic":"bubble bracket panda fury turkey decide obvious nest carpet defense side destroy","master":"d429dd03c2aac3ad66e8ea577ff48889d6ee006906f0d74be45d935c11f95c4e","seed":"d665e949ccba3afe3d3e14c8328f9d2eed1b3838e97a12d137bb188b4480b31f5f8ff388c4ea3aae961e6e98ae40177bd7ae075fe09aabfbab8140da075e8702","priv":"651abfb657e1b400e230b0fa3de8c022fc6fe33c2a80e425b13a3485aca1bef2","pub":"039d2e95484a02e3be5176e31ad41d9d38fd616aa37bc2f3032594f99b1d4225b7","addr":"cdd7ea2dfee41bc45d88e147ca87f15cf0278778"},{"mnemonic":"magnet setup unhappy slide human frequent notice unfold use ticket raccoon worry","master":"6a50fb7353ff7e3eff6054bee3ed8a156e3f4d65d712ef024ebbd58c11b16223","seed":"15195988c4a41524602465915d8c66b71acb07f8681a81bfcc77f5e8ae0071da3d900792c6666ed7f42e5362d1b22ec5de2856019e1d98d34f3bd977e5d6e712","priv":"e2e5997cea44fa966ed05107ee5347fe245ed436396a54dbd7bb0dcd45b02a5d","pub":"0251022b3f87060b140337f8a192c3037fa423b86f761c8e8b9abe13fdc7e954de","addr":"fb33e8b4227a4e31ee6d062f14129d86c190b864"},{"mnemonic":"extend expect crunch wear narrow crater opera dumb poet tone crunch eyebrow","master":"3a18fd4a5605d4a691097909a8fad033a9eacf3a8a6abbffbea184cb43bc4054","seed":"37661f80614a95188f9bf047b8b78201ba0512421b3fdbdb079d36cff88be9fcc6b2ee25a98495eec605c23eca528535adb4381b524ead9327671006a34d81e2","priv":"66b6e15ade42ef203b614a0d4db859263aab55cf9d98ae2118cbae7a2a8ba190","pub":"0318a0e61048878782f581429fdb2acfb382c59ede2a9c9f96112fc0a4dce78702","addr":"d3cbc69596f7f398a77be321ab4b306cad08798e"},{"mnemonic":"genius genius letter space share rich lava tenant drastic today vivid attract","master":"b1cf44f330ef51b5bfc09c224b83f3f678381b54328d6e407368f34f6b96a7f0","seed":"adbba0a0b7e15f2e7a8f95b0cc9e3b212fd3db246c0dd0b2dc41fe740c2d045aad24b9113dadc5b72d7e53d6c681fd702ae46b6bac877303e1ef4f9b1daa2822","priv":"4bc6a6a787283d7110cf4dd8e5f41b5abfbb302a5bd627cdc78cc419bd77ecf2","pub":"02fd610c024bf89e83940d0a5142c1b716786ae7c02e8779de11b72d3474b27260","addr":"f31609b8ee21b0da14e6d7ebab364b57230a8cc5"},{"mnemonic":"shadow ramp scan elbow cinnamon intact flash bulk squirrel pill zero tail","master":"46e4cc1975a8a363b8834ef06ff7a413a6158244a769ef15a9fcfe8981a0a6de","seed":"a8e143c8945640084294cee0afa09fbe4607059c8497259afe64dadc11b18b2d0eea33617b28b0f80419fed842afcb83fd1ab72c163c65e798bd1668cda9ba43","priv":"914a656705241622201d5ec8893d0d2484de7f4546847b3b2b2bc5afff743547","pub":"02f44993307ba52f2a927c5e7f7aa0baa6036a1e396d1d8593be5fecfd330e8d70","addr":"f966ac61247fc88e7d8a8eeaa2e682a669f17e81"},{"mnemonic":"wire list water over regret much ketchup slim capable proud then bike","master":"161946d516fc549a577b76ca6361f97b95ec58ec3bd2486dcef7f0d9ac9de062","seed":"c9af9f1c0f7fdcd56a69faf1274e563dc8ab739fad639e2032b4c0de10081544112b54ffb36fa1f6dc6419a7c073e0f3b4f2fc1a9ed95e4ee7dd300ea15d48c5","priv":"9f7f59143beb62116a592e3884d34d28a845c557be670278877c34f3749e74dd","pub":"027ab6afbdf54f5e952ac1d254cab364ffd91d49838354b02415a97421f9b9bdff","addr":"3824d1afbe44568f2ff4762157046e8f9bb561be"},{"mnemonic":"elder stereo hurt upon process furnace treat tool hole return base protect","master":"331d45143f0f94ba73de22ff235fec62132559735071ef806fb696e36f113352","seed":"4967f2af0a49298099ac49d75a3d99b99edf1165e3507c9055a9cb39a69aa05f6c07c192984e86f6abec6ab9b7fe8e66d22451aed158a6664ecd59b48932d9d2","priv":"7d547ee935de522967f92d0114dd40bb5c25d4f5aa2a1f70ad291601b7d0eaf3","pub":"03caf4c539853b640bf55c9db886e9906888e05fad3e18668f6c6d529434a73f32","addr":"816e255b2ca6837ba06d35fb834c3c246563d638"},{"mnemonic":"faith ski shell chest left entry admit smooth since hire pipe firm","master":"65f1eb6d72553cefc6fa5202583bb6db0af228fc0f008af45a3301cfbd279e05","seed":"2b778002d9097d84bb24e0dc577059a08e0dc24b47d401a37ece9b43c45585d49ccf9fdc6dfd87dfa2c4a70a226b9879f0927b0f3bf33b8f25573c1b6da98679","priv":"249dd8ddb06d455e6883a7126084aeccba0193a8ca0eadc6f924c16922ad891c","pub":"0390281dd22e02560114169d73fd72ae58ac7a83681a8d985cbf25fb39b485ba1e","addr":"9fb024edfc6a4e72e4fee5a4387c7bf09583eb1e"},{"mnemonic":"junior bracket pigeon swamp morning kitchen friend bike question emerge month faculty","master":"7a3d1634588a1d344986c5bdb8e5aade22a0fe74b5d234bce3591edfbc2279e9","seed":"4429c5b3dbd4db57f6ce8cf79533a746db6c28e1494de3610f225eeb00d2a6fef327aa17d68c75ae552c9c76b0dec4e06c583d531e45d6ab1f7d5dbcc259ae29","priv":"20b7253a740bf61bdee294c67b31aae21f90a41b2bd31a02267a773af049f983","pub":"03531e337b7ed416851867015996fe06b19a82bab432137ac32c914503fdf7ef58","addr":"e225e41ab3e0798b3631d71e753179bcd9226ede"},{"mnemonic":"farm frog apple capital foam behind grid project vague rural ugly sail","master":"22f4185158d434b8084c21d62c2fe3e653f9f1c5e2d592d72188bc36e9194e57","seed":"b92f9f3c0d496fc264acc1c04a42bca773f34137c92bb0f8fae52009166f48ed36d81c15be9e8eee8fe5f1ea2e7e0311a2d2b683285730cd6657ff862947ec4f","priv":"696f26ebb007bf4615ffedcb8a08ebc1b92be88955fb34eb5f08210970d566a0","pub":"03bb83731e190bdf7777058603180bc89a85f4bdd68fab3ecbd5c8a43f0e9bdc93","addr":"9c9f3d7c144c33f06ab476c752227c12149d9217"},{"mnemonic":"spare twenty above tape monster topple brush excuse squirrel pigeon maple fun","master":"a1ee9e1be2cb0f318e9cfca44f99ce405115ff3336d1678d94904efdb71f65c6","seed":"e90734515d14ab1b96bccb6f823abf76f21d47b450841ed1fe9ab7bec8a0e673828d09ee61b6a3f9bac0dfca778287abd21d70d45c596cd606261bd4baacc98e","priv":"d8239cc87c27ee5b6aa13d55505a8b0b2785392d26b0945976b575867b3aa068","pub":"0314db00f6e43e36e5f9e6a30cb2bb595cf4abc4cf26ada7d3bc7502b0e6be8919","addr":"fa50a1e20f2f4e490359a011ae4277ec61ca2a61"},{"mnemonic":"token cruel spot firm initial trouble slogan arrive steak inner champion affair","master":"4fd49883fd0f3b32564fa038cb60f762bcf4e65d3e297649cda474a6de9e16c1","seed":"c8b7b6807f2cef122125ddccd237435abeb2370a33db98f34336a28763996b81c336e7405e782d61f6b391b0ab2792b3788e27e67cf467127a50a6b2603820ad","priv":"e57e8f46f2eabf828cd024b4c7935126c95661bcbaf58488ddf7954b1a4486d2","pub":"03d959dd4d72e64be96260d31018ff3b3cc626ea3b80af1d6c3f9f8ed6452f9da6","addr":"e03c8d22c2e4513ffebefa5ed6e89245d36c1741"},{"mnemonic":"gentle whale exist height dress develop beef lounge apple gadget foil sea","master":"ed29987b8768b2f2636556eb1db2a69d48e6969f8b5ed455e39d6239ef376537","seed":"f4a08df5d89dd733e9b73df8a8518a0f3b632debdea655ea75b8b5b6afcc7c52d8bc0a2cf1337226c2e065ca0d71b6854109e360da8037b9c2a01156b2ca2b86","priv":"656e7a54258d7e2f4c493ae80e28c4eb08452175635cf0cf5a9111bdb6f76695","pub":"02f5f6c66a11efe81e76e7a5d440b9ca1b0dd73429426f4a27f3493f5dc7140927","addr":"e01072fa64ebf18099a46ee3799bffb49b990972"},{"mnemonic":"warm offer tattoo home elegant sausage sister cancel rocket struggle insane theme","master":"a58d8e3b8c25c182f6ba0e9e61b8aab35c04d846d1e44ccf3b305bbc03d839f7","seed":"ae94ef9d748fc2b348be876474f261458e3653cdd3f10448af8ee2caab848195cb802050f7d5d098e737672e331f1e48ee0e14c5924665f0aba855b89544f1a0","priv":"4534e2a9248df1bf1882da1a11ac8401b2db9cd92e5c3698d4610d120e6ff882","pub":"0246a4a61fd11a856a818f3726163b7f2f5f41b95f5ec513554f7237d8c85c867c","addr":"dbcf36e66ca99566f38ab8fb86930494c28405fe"},{"mnemonic":"ill orbit raise deliver fat age remind throw stomach country duck neglect","master":"9899f940702cfb78dbb9fe8d743301e2de5129f943c8dcfc4215e937c59280d8","seed":"789537517312103fd88f70345425c402bf0c665c34baf7d3e24c2c969162afae078adf365a0bc732de7abecda4ef5b12e213f4027a9e0ae621dbb6a16532ecd5","priv":"cb4acbee9d41eff9ef210ca73ed0ac71f353464210fc29b30c863a0c23214653","pub":"032779afee4e50503db9c67efc858d521ad8454cd691febc52540c4cf96ca92231","addr":"bc60e5da2c9e96698f32bbd087bf1b3b599a94d5"},{"mnemonic":"fold concert earth alley broom render ranch worry motor virtual industry bullet","master":"3eaddb6d4a2a73a1f0d094957901b9a53f4b36ef00451c9157a3dc159b523cb7","seed":"479d7ca92dade2e47b3f410fa563624cb9a7419921c687e93aba27d82af323bf1d0f04d12faa018732a476fc626df000f705525706a5e5958afe59891f10e43a","priv":"d0e151f6b58c2f48d0311fb2800e66db4fbd9ec14c92f84654907c5018f81c98","pub":"0372820ca8fc7a193815e924dc1e7fd405afd0b03e39ed8cd01a33bdcd35f899c6","addr":"90b134c6bb272ff804b6117fc1d6f3dba538e3d8"},{"mnemonic":"grid street boss erosion spike bunker indicate erase path mixture inflict group","master":"c5063e2bcf9fea3164cc8bacdac300a35b0b1dccef63e1de233ab39356249b9d","seed":"2c98b2b7703e3cc2fbf089d78184f2cdfcabc7bf269ba3b57e7b033629fd149263063e3f08c0d7fd3a785ceeab1f9b2f7e383fd2dffd7d9e982e7342ec90ee64","priv":"b6082dee45243a3fcf3313715ee9a644bb95d550cf8f275a99930372bf265e59","pub":"0282b6a0a9dfbbe648db6afcb9596fed1c02b8d7264925c88ba7007cd5cecc10c1","addr":"e9e9b9eb2c9d88b080af25d6c5fbf425e86c8f9b"},{"mnemonic":"flock entire rent cricket shadow inhale organ pioneer pottery faculty west umbrella","master":"e1beb66b50360f8bf5253b40e1fae368fe8ce267dd992a951b06896ec8e44404","seed":"267dd95caf4834b42cc69941de4dbeb3b37321af83548c865efda2b3cf9eb983c8244dbe65af863f0c88d2e0bb530d7580a0641d23a2bb98c4b64ac4b38d84c9","priv":"b35f776a36af618b48658829c0a914f8ee193070fd9b88ab34f3b4c35197ea97","pub":"03e030c12765cdf97520be291bd25d0a34aefb295f7749904b9aaef1ece99cb3aa","addr":"5c842dfe540f09579539e1fa6e961f929a5b7b60"},{"mnemonic":"all hurt survey laundry follow earn car music online reopen boring monkey","master":"56a9ee4a3e11b98885540ffd3e639369e2124f9d9b7108894cdfcb154279921c","seed":"ad2252df70bfa330e6a7c48da592336d202ff2f91d1654d34e9139ab644d54a04f88f3664822aecf8565453b58ab77a6785e81ecd7156bd7d560ddbfecd8a287","priv":"4181c26d8062eb8cdd8464524bbd2d82b56f423ee8aff8fe49385ccf98130a4d","pub":"0336b154ca3bca67a440c55add8c0ec34bdda413d57e8488ec58402a61eb93f861","addr":"2de1dd6ffa17618df2f9361a427dfc9689d7df99"},{"mnemonic":"obvious spot fuel leaf company birth drill baby lucky oven since fringe","master":"c75aa6398d3568764b147d2a951f2a93a38ca76f3e380e0574f35a6a69d0967d","seed":"d2793c736f85dac48f03f67c39b2b943b297744268dfad708ce9eddb74c649515632a25468a3d444bd07a0b9c4c9d650ae8676737e8373edd1b0f672206d7b72","priv":"cc9cbdf4b34dfcafad90d774b31313b08c6861e6409d659ee77afb75a1ebfb86","pub":"0251043d6ed5e0325ed3d7cf2caa3db8eec2a63c4c5472421a37831e96fc5a2bb3","addr":"9f75fc6e07b3935e5e8f3a39fadba8252e10cb41"},{"mnemonic":"funny online improve knife crumble critic grain vessel wood inspire venture ostrich","master":"83a4036503ba3499d266352b5d7736d5a16519870f9cac08d4706bb3a57e5d7e","seed":"23ab1c440ecfdba702427c5024503232b28aca8de6cba59d7ee1e070e84a4ce15cfa84e06c84c9907fb6bdc9d73c94abff5ce5c4828da89631cf77a3b091cb7e","priv":"e7cff4b876f286e6a8181763e453faac2d92582b0f9caa41b5aad8235f79ee86","pub":"03f2a9ed2bcd20f9ab0b50a3ed8f7ecca7c172997cbc877a896dc9ac740ebe03ea","addr":"ef1badd2e02541f774b7ccfccf8f550a0da31f48"},{"mnemonic":"elevator scan glimpse immense shoe buyer punch tomato chuckle art catalog coach","master":"ce00293fa3230ba3fff5f53d163acb0a06bcebc77606c6c22166f29d4f84d290","seed":"e06c12a0d1f8bb93596839e0c3c566b5b59421226c1523cb54f86e93e391883486e86807472313115c366495a9973d34b2c7cefd919f0023bf2039e95f22ba72","priv":"94e11d645e24aa3653caecfa6cafb3404a6b107c076fa2fc03d3a2d3127c8e95","pub":"036ff6332fa0db2db68b6a74a68ba0eba2cdff43f896de3d4b3b0d26ad1017b608","addr":"82ea6dd1ca5f8bd08633e5b69cffd8dacbdc3993"},{"mnemonic":"emotion super skull trade tell drum lake scrap alley reopen true prosper","master":"8bd8b2834c0aae5a8a207a40ece04ebf9fec51892b8c75dc7e4dfb256fba3b6e","seed":"6d9fa2ef59c1cd981a97e8d3e788b8bfb9738ebb23561d2eb72fd3bf3741e90eaca1c4e821e711756ad8adfb3c5d355f55fa8f7a41ddf260a85288416228d257","priv":"5adc84e56a3d3e6b43e1d42d01f2c7ab1bc340cbf8ce99c30cd94323e1107d9a","pub":"029aecdc08e10d442234814770ddd891241afabbb088e7dfe41f6ee0edc30a7581","addr":"19ce22a905e023e40b9a090b750870bb4d220d4a"},{"mnemonic":"federal math bicycle copy diary bind clap dose clown fabric hover draft","master":"05e5ae86313b56b4083a77339441c22cac4d675f18089028b841e12d0be35480","seed":"bfc46d250c423dfd4f123a91d8c7d556d484f1b8091132cc6e288fffb4b786d721a87d93414f71fb87457ef7b4f17d65d751fa43d7d67523d95997e357141ce0","priv":"760e1221ff1a283d14bc3fef817244affa4787036a46d3009d53911bb873dd4d","pub":"03286bd104bff54d0d01837e72b47e1bb582c13c78311a73a08dcffdf5d5e6bb42","addr":"d03ae88abf654c466a93dc167be85b7d1d172e38"},{"mnemonic":"parrot poem unique trim auto april under pear brown flag critic ship","master":"438ae7958c45b13e2f2d275f52ef71e6ce20d00545051101fdb5be7e235d49d2","seed":"85ca4c5faa1bd0c0a3b74b8a9f5afcc0849be00a0d1e67222a7b70a9f6343c0c637843756750852dd6247d311ae14f581b642e5c3c4cfea3b689dd1c9d4dd18a","priv":"f725a96177c31ae08f065255578e34f58145b921267c2a2e26f09a3fe0d58e61","pub":"02fb792c0736e01eff225a1cfc6f56ccb8ce70fbbb9c050da326ee5475fde784df","addr":"d096954bbd94038190e6aa959ebb8e6d4c5cafc7"},{"mnemonic":"expand enough goose wrestle title hamster purpose illegal peace patch moon spin","master":"fcd43f2a177b9c6f19b22a5864b41a30e9e4ff29cffad7663a6d5e5574910a2e","seed":"0dcfb2c19f6b6b6560db73bcc164ff84e117fac8a11027b0c8c2caf5c97256961e019dc1ae14752af47abd7290cddcb8400084eb59b8ebe5fe1b148806c422ac","priv":"645c6babf5d7abdf9a111ce1ef7a860466b73c47d2afc83d5091265dec741fcf","pub":"039d7f9485265190c0986c0ea74c065beefaf0b8a567c2502c122139f4f7d0f834","addr":"9de7c6791416a501bc1b3dfa5940e4ede894bca3"},{"mnemonic":"property grow toilet hollow slogan pioneer gate fresh still notable happy peanut","master":"9e289e0abc03cfab28e00b885be5328d88886a24e71d88c120cfcf697e1573ff","seed":"3deae69499f305108ec27c7ac5e844140b59316a354d08a9571e671d5f71ed8a35e060b084deb4ac2f55c3968184f7b625246c5635e8ae85cb511ed87582a712","priv":"3765a9eaffda6c370a95ca1c2ecd178a5a7799034fed7d051a37f658e1db0fab","pub":"039bbdd61b3e1570f585fe38ef1ff516a4d1ea27c9d9a2b11775f9f462b5e1e764","addr":"c0a75bc9853ea8ff8070b22b5e6b22c57ca2e820"},{"mnemonic":"grape arena buddy shrug foot fiscal move transfer beach else alone city","master":"903560571ef0d4cc0fc20d79ff830f6cd360a1ff387bcd893b436b8d8cc4a4c4","seed":"6b232fcb4175b92836ad60e8cb9bdc82856d663558adad2fd001fb71db4eecc55d0a9b0cb62c938c8e699f0bd55f3e773080cb3804d74e4c7503420b2f0640e6","priv":"b693be937db9f0aafcf2b68b9c3ad8dff86d250f4d7c7ce0bee4fec7cc164035","pub":"034178d1a76406edcea9b3e501aa11161cdd14d6760769cbd0070862148192ed81","addr":"91379f6876f01696ede09b112da349125ae3db9f"},{"mnemonic":"spirit march luxury planet review rhythm mother food orphan inhale dinosaur ginger","master":"88b72d270aaad97e466b4c6cc2d5376e0bd9d5d4389bf1c5e5fe3cd60eda1cdc","seed":"ae53ffbf1695fe13e7590e3c0d225621f392ba5885387cc5ba1ddbdff13f83051293be338369236cd2cefb39682019b257a4766eef632cb2f805c226a611d5c4","priv":"8cd4d3c8a6a6a18eef4b30056d4c23908d100a30566ee7ed486f96831be8657f","pub":"030dbc527c5e03ce3a6ba9caf81c44f0dd0c0b0374617efa819a71319879027fef","addr":"345000ace68ff89bef2f2c197da7f50329c739a9"},{"mnemonic":"cause enact push shove account orchard grunt sausage mosquito deny relief sun","master":"d66d0216c675ef09072623aa75fd8a9df788af3cf26b16d38091ba5ec8cc8cb8","seed":"07d83a41e284788319bc0e5b9b7b1849485b2bdb8cf408843184f09b1dededf8ca56160aff2f6ed2e0559e0c005f5f0dab7b3e36500db5e45c55612091818f60","priv":"bcd7f078131f5644373c0e0ced2f33822c116df476cfab34c39dc9a8d5b9aec2","pub":"026c0d381a709b557135d33bd1760de196b604b5d720269ba4e8d749b7737da2e9","addr":"7e268fec12b43d71998eba89c8e0df3205c094d6"},{"mnemonic":"faint jelly paper blush cute hope project giraffe muffin strike pistol blood","master":"3e2eece9505cdbdd0e44e237a90a023837b45c6305c01802fa278d6690afe9bc","seed":"7ff4975b81e3165068c8b861a748013e93614bd56c4af844080373a3c60d0e763d5c934ed4d4941f195e97eaad4257eb55ef4842d43ae648ebadfb82421d5b7c","priv":"d2e9c0441d876bc0c189a109a564404e00e3a7540cb2f84095da70e38321adc2","pub":"02a49b4d38662800e8aadabc72fc7fd3ff080c9c9aef5cc3c3970d6411ca92d2f3","addr":"b0bfe3ee05d361865a65678fa612cc64ba633789"},{"mnemonic":"jazz ten exchange horn junior frog surface blur color pill bonus science","master":"037073838661b05747c80ed9a91ef9fc07db4f4b9a89c56a26a517d74615a83d","seed":"92333a0fcd8cc74457ded4de145027c19de4d04d4e791c0418092ff599869c5a0f7f585692c0de272362e6ef3a8d31fd793e83701f1aaf41a0355a818ec061d1","priv":"04cb6c660a8006068ae929e97db3b29cf55093f52bb7292d212774db7b6544a9","pub":"034a39172b568cbecfe119e7c751086392e0a6b8c5ffc755453596ed74a75bd1c0","addr":"bde2747790882434b15deea070cd36c696c73bbc"},{"mnemonic":"chair practice neglect hawk panic sponsor ritual bid sick fiction vendor defy","master":"1f908e1559b37dc8ffde2f89ca0dbba2202260f6a848461d75cdc8791f53a1f5","seed":"0fcf390d0c757b52a520a2fc8c30dc740b0c481adf1e17a6e8d445f355c3c266bad1671bcdba99fba9c69e473a294c5e3f6ac51027a1048987cd3dc7a52dd3e8","priv":"6444a8b09434528113de487508dc7e30cd184c3a9f52ce20b30c7b6f40d5a031","pub":"0344d47049e125a655b9dff7de696e72689ee478b8b4f13a0bcdc71df4737689d1","addr":"3ad17b540fa37171f21fb9d4cf6cc061008ce652"},{"mnemonic":"dilemma main solar balcony differ bring close popular couple educate hobby mule","master":"2a9a19b24310a9019114beb8d3222df214ff8eef4ce190e7017bae4e45861092","seed":"ed8bd81a4515d1c43c24d69aca3ceb065d0552b79ad01db75ad19c2af3cd23a6a213163f9db3743d3b2fab6bc166954b2285bead616d1a50f036bf144856e762","priv":"1c8c89946f2dee6c92348f5d82506ddd9065f83b2eb8f8d173cf9642b971a0c4","pub":"02855f225d510b6b0d64fa5abfc9639488358272957b9003b1bc697d474577c45b","addr":"df365a12508a519bdf095aa5979b93acf59681c4"},{"mnemonic":"sudden cattle enough output make code tonight matter reduce enjoy file prison","master":"ab474b0afda779ae957963eb8643db33d1f2d879a5ebc2a79b5d8f2f9946223f","seed":"f732b62445528f4d96e0c95b58c4459e8ab7528d47ec2a925e3f5515e1459c952abbfa40fa5cd7f8b7c2f059e3df2c2a5a3813b4c37e322c9f2c8f55e66ce3cc","priv":"5d5af8bd1921fe03619088250bd74a2a1f58bcac8158230c0cc0e7ad304790e8","pub":"03ce0673f40df25344d5f2d85a374d6d40b6ab5b8bddeb5f9e2adc9120e2242c17","addr":"a9f1d96cfeeeeb011efc76ac43d3d121a2e7195e"},{"mnemonic":"oblige broccoli transfer midnight display talk jazz wall fit harsh kick ahead","master":"b5e760adc086f5be87b58aeabc63d74d018aaf2f673205620685c4ec32776769","seed":"3fd39274348d2cf5ea5ab4239dfa66dc65b33a7f4975b25e334d26b67e32ccb4865599f9b4fddfe8cf8a2630cd5787ef0188371d1563c8b9880b33201bf259a4","priv":"5e9b5b2a5628a5a57510469db849aea45ee2989c929bb1fc06918736f115edf8","pub":"039e5e293c463f16d26fd845e92d4503e551013864e5682e1c28bc21072589baeb","addr":"a784eadc4951c1e92e63a83204473dd467f5d558"},{"mnemonic":"prosper must remove pulse wink rabbit shadow harbor equal twenty air muscle","master":"ad8244b4d4221944b73939b681b275f280e1a8d42fe6583f63740865dc6483bb","seed":"a3258a6176d098bc96dced14718524f05669cc6c9f3ba5680a56c8c80b83bf50f32345843aab72e13df9bd8727408ec114bdc0099902857ff1889bd94a3a1388","priv":"32fde5f62df796263bd40267e1d1573f73d86d2fc98076008a5ea46092f8d01b","pub":"03ac2d243cf6580c8c0bdfc091c8ef1afffca6aede2ba5375e149efd2db54c23f4","addr":"504cf87560e4ccf69ce6f81aa5b0b3af45ec2899"},{"mnemonic":"harbor focus scare envelope slow margin boss giraffe daughter mouse hazard step","master":"28831264a522026221c9739fd286152e1123809699955d06149f34a0157a667c","seed":"bdb6f459beb7d6627a96b920ea39dd34b38b21cf45bafe88b66823c5ff02babd02b40ce25a9ce7b4d04696294910a967858fca74b18a5cb46f8afe294ff8d56c","priv":"4834d0601e457f6903e3dc08b3168411c351ed97df34a0932ba19f7bcecafc4b","pub":"03ba2538c15c37b3e0969adeabb0e5e1d093170f7e352ce0696aeb9e5e36150295","addr":"a259af3663c6ed69b149c94f73dddf22e4c91442"},{"mnemonic":"elite magic excite apology sleep cable refuse carpet ethics fortune assault hazard","master":"384338593c8198935c4bd0ced828784a7a26797b5e68212f7b142d25c5e8bef3","seed":"4ad678a061c1fa3351872cc3451c1410f5506919afce9ed62e5dfb05e9be36471fb80a5a94312ab603ec397cdb8ccf9acf8ce405fe7b834c9b14eddc570d5411","priv":"d07f63e9ed19bf7c7f89a598727dabde42bbe0e4cbdfc0dd889f8b5c4998a023","pub":"03d5199768e4a175f47831e46382232c217d58e94aa99f5cfcf7e85887865d4da9","addr":"427a4855b7d2222cc2d54dccc2de0b225b09c315"},{"mnemonic":"awake robust situate increase salmon tell roof agent grunt wear license kitchen","master":"c30d435feb0cf93a3cebc4584e94e00ff40ee2950cb3053ef2f7832799bab885","seed":"b49401408240429ba30ebfb5d9afd6fb74e79971be6b9f76e3810b83ab1993958f2d9f9fb5b75dee68607a2510ad621968d384873d16b4a194c939ff1358a67b","priv":"def35e61e636973967024d7cf9ee2ab0c232348c70fa25b945d6d4a6f220b9ba","pub":"032255b26a5ab86ade14eb9acd3c97e774aebd710b00e81719d04d7dfaad37251f","addr":"aafe58c581f30d3a55de219c15724e2b26dd2c5b"},{"mnemonic":"host proud little want shoulder guess acoustic spin since slight myth detail","master":"200f4964bac08715f0dc5bc750261c71ab2c5e5b70c6e20bf748aed10c4e6ae2","seed":"3fd02e2249ce332bd4f4bd3d9c0ab61e169d0f0c011a826d072153001c6f093e7fddebc437bfd7b9dd60093686147e069c4ff3806124cfeb02501b807205c47f","priv":"005e6a885009202c44f2dfd911fbd495214b9c53d2305b52c6bd7c1a2efbbb17","pub":"03a99eeec3b673289bf785c9482ee94fd906f992dbc11b6e0624e0c98c6b9ddefc","addr":"57a1472c9d2e1d80bad1e84b1a88356d973cac1f"},{"mnemonic":"chimney organ announce town worth finger donate hint vehicle sniff defense famous","master":"8059f2264cbba67a9868b20e25cd6ea7d5ac2c77a86b5f36b9890560b8ac9d42","seed":"a2317e376ede3b6bfc464a993815e5b32c7e2d896b462a3f636cad9e3837f7b454cfd3ce17e221a5f46a8b38a8eca74f6f1508d376ac9ebdbd92d6603178e8f9","priv":"e8e7e337feed5b08f418d6757b0cebc3cd2e037fddf8ecb51b42c1f71d83bce1","pub":"033ccaccdda15edadbe824e3340c73e27303df9c1e40037d0108bb2dea87e84235","addr":"13ae50b4bb386c1c5360404f5f43a2dfd95e1967"},{"mnemonic":"wolf found absurd device rare desk average water excite ring chest version","master":"5dec910d707536db8776b138103e97ed8a34d75e89d79c3657320ad9bd064d6b","seed":"421737ab059b231f6bac2f012f4472ec7215f94a5c9f5cafeeb43bb03d8b936c39afe6a712530fad6a5e4bac736b7ca12e488b3c377faf58476e9e8fe4897829","priv":"17e9344eade9c62a67b5d72af06616bc455ae6f9aa03dd48432efa2a242356e7","pub":"03776634e0508958ca0a9cf4f15b038f544a4d2d0497674ac7a1deef315d80ba81","addr":"63fde94bb741395136727075993a876ea1e59336"},{"mnemonic":"disorder improve say diamond present elegant evoke latin lonely muffin main resist","master":"e8e118fdfad2b3eaaecb31ccdb8ef3ef04e904c543245766a7bbc365dbe37174","seed":"c32d703d39d06d3c61464db0345ffe546f020678149496ee357acb0e93f9575d39ed2309f46917f89a2a299f1704958806f65404ad80aacb295242a91c0f6a53","priv":"947651ee70f613036de219df6d42b78dd5d1504af999c5c2ac7cccc656f578ce","pub":"02e0ca79766b0cdbe0cca0c4d4647e9d82740a6db151f0ad56df0881a0799e56b5","addr":"dd0179f1d538a9c67a42ca0fbc262edd506842db"},{"mnemonic":"define lion input friend used deny obvious basic fantasy initial grit jaguar","master":"e749606fd4eed5b54a718207b0c44af3dc32dafdc192d6f26744fe02b1cee804","seed":"2f67dd5c538358009d036e68d2205254ef898826613d01617abfdc83deca452603008226dcf4569f3faa21a18ba72e3f22ba0beedfc89888701ea2005be93912","priv":"59321cf870be317e697723d132c9f52b20ab43a84efa0f53d3af3b2e1bb075f9","pub":"02e681a3823e20e1482ae8888dd3fd54bf8b9843c1e480d36e72f6ec8f9311ef7a","addr":"c13389a74d1657b472efdd2fecfe736872952513"},{"mnemonic":"caution unable glue tissue toast august decide leisure foster session position match","master":"a0ae79723ea7b60a8234be8bae9acd64bad5472f789c7b8854d95862ffc441dd","seed":"9e1e3a5e11633be7f211cf442cf66b9350f2f4d84829ebe6da491e7749f2a9e6a3656feb5edd3584b723a9c4edbe1f2f530d4360f55bb1d32abe8a82d7383204","priv":"b2a560b474971b2ed48e47c0a27858b70c4485256ec288849a97be5d5eae26c5","pub":"03fe1ac82b75d9ce75fec2839d343954429207d4ffd7ad0e037c2bfe50d7f8c68f","addr":"85bf34297752337da3c79c124508daeab88faa11"},{"mnemonic":"pull drive tired success sorry raise top ship visual filter tag upon","master":"e5b018ed831659613748160d29f704367c0933b09ee12a8582f36ebac586ae78","seed":"1bcc9ff7923777f97fbcc49e5653ce6a7397668eb7b08aad407c77b5f7ddcc62323d8a566c15b51dd6032a57be69054c1273dd50e2c0698e42595258cdd05e7c","priv":"1a859101a7582121828f09eb02de30f34f6e1cda405cb36fda0279b25e1ffda7","pub":"028e0aafb274dcd1f7f8154bb6f1a6ee6207f69d8d7720c96a0d73e2fb2277f92b","addr":"ef934026abefbf19a96bab8f59b9f048ba4c14a1"},{"mnemonic":"grant enroll monster verb voice bench when certain kingdom nuclear save stem","master":"e8221f0b15c9ec7cac1bf373219481d9952b907ee29914d4506d079ae99ec17d","seed":"158737e586b7d0515efcf931d780a88fe0dbf150133a9f605bfa9c4f0df1b7d1c4f56f9745fe76b51640d45735b91e2a6391e3a53f1200824d58ea8cd9bf25ee","priv":"cb61489db37dc70695fdfd54887dcb61f17ba29925d6267f10999ef088acc11c","pub":"0272502a28dfa3e7ebef4c97ee7ee9817756e84733c1030a94820db6d25c82fb97","addr":"d941f06898ddb082c3f8dcdac5a455ba88be2dab"},{"mnemonic":"shrimp forward swarm olive laundry team fashion run tiger atom guitar blush","master":"e726598bbe78396d7d21a334ad1ddfb95285f72e5c6f015f6d76d7b018a8486f","seed":"7f59fa24106d19a2fc887bfdbd01f1f0c2e037869cdeddc6543354a29952785a31146ae4de6d7ceec9ea95df088dda0f195d491d8be3a6ff63bd427532a1d979","priv":"1bcf9039d65d76bac2b14698585db46cefc7de88f2724118dbf1b0597bea6960","pub":"021b8a68d6c12165a3c11dd81c93edcae4437c983751e8c2a4dc509f2e3bd4d400","addr":"9be822a10983a2c398dd72cb43eab3dcc2ee30f6"},{"mnemonic":"object lava wise decorate donate panther chicken enforce hood donkey lock better","master":"f2e88ff11892f72f22627d7cc7048909ff7403a121a23ebd9744a9017a013adb","seed":"9b7eef532cce30af1499362b675c2b6c3e6333f672c102d41459152f380661115461b1dee3613ee5be55beed081d1655b70d941e819754de304beed5269c5fc9","priv":"e19e47c990399d9bb11760b2b00847fe8b85d7a73c5c4fd99414ac37822b5ed6","pub":"02d0840b212aa20d204c8946877da8d6307b50c890a463a123d7eeaf877811f998","addr":"b85c15ec5abcbbb0991c18fbc788af88ff36e66d"},{"mnemonic":"blade reward angle predict text salad auto drum alert grace valve dove","master":"935ad9d81bdf740c8cec1414d56cba9a807d0d47d39b0d9169027cfa38491fd0","seed":"7888677a5dbd757788a5fa116a954610d3234aed529b85cce2bbc34413db5b7fa4b25ae8d9f4bbe367ac55b0dca61724399f70e5404e346506ea2e5708269639","priv":"a6f5a6d090cfb99f935d72d79e77d00c7eaac00b9d23ac1a4aacd6289fdd4604","pub":"0308cd34578b15b3f459d9c0507830af364ed359f27c1135ec0dce2fb9d256b65a","addr":"f05e198f7feacf7a2fdb37f598137f27dfbfafa3"},{"mnemonic":"icon aunt fiscal day never reflect rapid scatter exist fit prosper what","master":"9bf8057a5a94ecd164969fa719a846494e7fb8f40d6571ff0f021940bdb5567e","seed":"0532364343a12a5b821d7cb9c88317dbf802d8b3f24359b49ff32d79882f89f489a4f1f63e4c52ef1ba92a3789e971d56f056b39cc9b0821b3570ececeee9c3f","priv":"0b204e7b6e74dbf35602dd6914458af9860593d672f3409ceb133e431b3f6cc2","pub":"03d5efdd40e97200646f202db82895e2bbe0c16f2cb29bff1622169787433ffa56","addr":"472be066059dfe1d34abb3564037b0149137ff75"},{"mnemonic":"mass wing office match couch tent tumble rug beach mass october already","master":"1b63074ed73326c5629aa6bb9863f1a3cc2369f50f05aa1281d6b208a787adc5","seed":"8e96902f01dbbb458201370b5524fda040322026f83c8f77bc2e91e843ce6b63581b979f71368038e81aa627e3a10897692c1a215fe27a446ac914f043ff8f75","priv":"bf5a466ca37a2c297ba1ee4ff4ff26d62ff44b98b02a5713fc4b2f7427ce9e99","pub":"02827ec005329241a597b6c7faa5e92a0624179425549777ff922482d2a1f48d04","addr":"67f3445c15a8f34a0a5d374acfabc072c3fdf74b"},{"mnemonic":"lottery skull bleak sand drum domain rice eight card frown world much","master":"8a09b9b68f5f87795c60d6dc08146a2780f410f44560f4519194eb1dc6ed26be","seed":"f2dc56a6fc9f382d54b3d92785724815c9b78866ad586448cd9ca06e59d713dc136f41425b16b28d45ce094d3f817aed13bda99e73659a77c06064a1fc123d07","priv":"09b6ccac9c9109ada552b0982202838b3c1e53a816748176c2a3f6c04681300d","pub":"028211fce683bfffa2067cca19d0e003e9e86a066b40db4e16756723cbb525c042","addr":"9853d04f14981533312e56c75a32f10e98d543f8"},{"mnemonic":"advance poet beach endless idle castle inherit jaguar wife grief frequent wide","master":"c16f77a5a5931add45a26fb906cbffd87c7e5ef3d146b83df93e5a3d5b9ca9ef","seed":"26b3842ad77946bb585a05ef148b8ebde2994c800d30224adc7dc1110a4605c02a6651d30709f5f8c0a532c6976504344887bff1503e6afb6cb8b1ae0f909f66","priv":"58a69857570ddabf8a5454e97655e1a833194b64ec4421befe3e0d9e45ffe97a","pub":"033a877e03d2b871bb879b53196da3ca45459485eb38eac76e938c62979d23a1de","addr":"0bf6320bffe291c8f1c0676ed864232cc84b4e57"},{"mnemonic":"stove tennis wait major grass network mountain before inhale glare bird moon","master":"b1bb7df0cf5b8143e91787646825f92d175664fe68751c114824d5a374850672","seed":"73f5867400033e088b346620983d128294338a0988a8b4282999a2a960a26caa12686db680247520196fa9a1e34901841d999b4fdad40aee63834dab615cdf43","priv":"37af5d2736154cfef5c59e974f1954e541683331de3555976a9e9efffb7c960f","pub":"032c5fdf3604c6ef170e65007bdb75ded577aae6652f099ee41d4ecfd1020cc065","addr":"7ef3d9bcee0b3e3d131fab4dd7f79d6dad548889"},{"mnemonic":"sting nut gasp like spread sponsor march behave zoo vanish noble dirt","master":"9f74f4075e987922ac30b7f5f43bada33f0dd385a4a30a1ff42718fd43f76c93","seed":"4d6e6b8a41454924355067b754e619b663ea585f305482febb6db99d26d62fd1a1a5441b7fa1d02de242f0dd35c965ed62fb0d9bc7a857ba257dec94ce462a9c","priv":"53afc4f00fe2a5003c77e92b4d0837d7c8fc54b4ec1e76e0434ef38aa3712850","pub":"020f710a1596997eb3a95815ef79efb5a7204d3bc5fcff171e067f4c6b3692f5e1","addr":"f41ded9fb4ec7cae1a9e8aaaec7de6309644a2c8"},{"mnemonic":"tent trumpet jungle into loop target myth analyst symbol ask december rural","master":"3a8fc48e8e08afe8b32bc8e9c25ada84feb1b84922ea10135a590927eed2b3be","seed":"7c9d5d2681c85e71d49392aeb0502fee5643e8a6ed60c4b84bcc202a5bada19a99dad7f88e365abb6cce65985117d642ca1ae4733a0863e1cd15fad4edd1e8e0","priv":"56b266ef3f1a45b33ea1465c15dc6ec5779289522c8b2b6588c8cf2c182d2fbe","pub":"0206b8e7a5350358fd35bbf173d9ce5b0ec91ee8c710837b9198b5d5ef327a11e6","addr":"fb059b5167a4fb3bb07c0b3b3516bd6fc84f66c5"},{"mnemonic":"juice barely airport rigid miracle afraid funny combine address guard omit idle","master":"787086d46e0777b03c3774933f35e4fe65b4ff069de5ca9b09cb84caff915ddb","seed":"ed6db1f257a45468761be9dd26ce88f78ed7ed1c488e4affb3a8f8ff8550602848ba2fa284c930cd387188ec4f057c6865964ca93bd181bda40e4059c4fc4d28","priv":"9d6f46f7c329d6e57b2ae84150c23c983bab43e7e6ad7190bc95dbeac977c617","pub":"03ec60e506de8acf2a518ce07e3394421450db339cdb6b91ca52924b1e1c3afe22","addr":"0a4359701fca7026cfb2d196df28e34337a34960"},{"mnemonic":"uniform enter number remove obey arrive print version cake alcohol swallow mistake","master":"047c71cb3066ee3fc151a4dd961a06595d63b393c54e77c756966fbca8a749bb","seed":"3db076729af5e872e92581e3c8d8812b60dbe4ed85a59f034fed43c9c4e0015fc4363643dc8ee5ade53ddf68af54b3d63d6bd79457eba414f45bb0c809e90af7","priv":"557c62286ae6440a2a0b17ea98dbb4992333093a054b59a37345a61de1b871b8","pub":"03ad3f7e2e2279b486c88e7e12d2a97a3860aa31a3854987853a1d73cde6aa734d","addr":"ff0a8d5fca9824e71cdf434cd868c12957fc61c9"},{"mnemonic":"split lecture predict rich inflict flush bike sound credit girl pudding ridge","master":"12fb50c5a687fa1552f07cc9b56d6f5ecb7b68376c3cdae621190494ea279f9e","seed":"29d6e5b0c2cbb22e6048158990f14be89c6c2416b36761c2f4d4de70a3dee2c7f9e86bf6dcfb07e99ac1d15f66f7393fc48b00195b0981f0699652a9f3f0c340","priv":"b02635341dd14b0b5e701222337dce09c3426a6f80370b06dabc31c417d9cd2b","pub":"0365f2fe5611808dd6fcaea62ad335d9b992d1b8f91333d6dc7b96c0b3ac97b209","addr":"ee3da08bcfb0e2fd4331e8b1ea3c0905c6c2f005"},{"mnemonic":"fiscal deer minor dwarf measure goat enrich emerge act view cancel shrug","master":"4cb7b43c2efcc7f6e6d84d5b47ca352ff8aa3c1c44fd8d2de7dc75b3fcb310b5","seed":"f48a89c3f2dc87ad41069c06d0b8751881c993c5895cb548b06974194cb410122d1268a9f962790ca461e875148cba07c216439df21bb37a06600456f5bba35a","priv":"b77f4a13edd7f5ae33725c340b1f8982fd02829ba2756d70f4086dc4a38a5d21","pub":"029844babe3ab249b969895b2b0c6d3cf7a79104721e96ea3b24784a4593fcb7e1","addr":"20a6d611a9ea918d6697d2e09900cf4fc9f676c5"},{"mnemonic":"expect speak gasp outside word glue fluid neutral casual train left mountain","master":"a774f13c1b5a22667ed1d3954ef64f9ddf3f841890b894660bb291745f8c5d23","seed":"7e8078aab4d3b5d121cb17213ee1a06fe4b0ec7d95dbfccab17cd0cae6917151197385c2f75dfecc7221ad518d5899384c22d2641a66250dc581096ff5326a6c","priv":"663b4bbe218e2f6efaa30e02460985ec708e76abd845ca365de83d2bcf547680","pub":"02b78aee27b6c719f89f3f21c55e8c34b9b83e94864c894188a7e39c348622e5c2","addr":"1c716ff8774a14f48623598e80fed3877d974bed"},{"mnemonic":"grace clinic host vehicle drastic april sibling response laptop escape creek neglect","master":"0f2dd943aef0644bf150f38baddc31c3c2a95b813c1fd893ef936f36c6972aec","seed":"e21b62815782f3954ef2be4e9551f7ba47d6f471b566d3b9db6a07d29b42c2edd10e500c7e701ba60963315f21afc2a4ea0d4c187fe4e08f775d3439279572b1","priv":"df825cb149c95352cf0bb17fb8b12cb686ca246c76f7bdfd8ae4633fa18ec30c","pub":"029bb63c2664225dab9c6a93294891127728b77e7d9a9a8e187531f5f154ad36ac","addr":"55266b5a04683c1d61e2cbcf4180d7087550c9f1"},{"mnemonic":"neither help draw cup grief hood swing task okay wasp angle sweet","master":"5a89607cd2cdd7717fc0918d92e661dc7960b5f92a7083482079468afae827db","seed":"8a1d0d7f2799cf70744d682e734352e2330494cc309b2bf785cfe799f004b67c936f3987f75954e18f4eb3adece8e2a3c57ae24b3c8f747884f473cfdb671112","priv":"30a055fcbb2c88fd87963e2ed60117cdf5a82979a7829238f5093f0c27fd7380","pub":"02181e5dacd8408db30a736957d7b19448d5925417e4d38d487391dcdfb8ac4dab","addr":"9ee3469dbceacd60c741f1530646f7550b94be6c"},{"mnemonic":"fall laugh virtual service grit left clip betray wise correct walnut online","master":"7c11681ada91e9349c1e062d0036a29290bcf0bc1564428f7080ee0b81fc5a0c","seed":"c2ab87d2eab816dd1b81ae4acea81e034f2a7cd2cf7103ad3985e739d696248dc0cbc6ff2864e598ae736b58c6ac4f3898f1ddb7eff76413fa1383a63f6c7716","priv":"13edbf55d44ea6951f3825d67c2486a96030bc58ba15d282df4061a0d644a2a0","pub":"0386590dcb32fd11ada507c55069b5607182a1db6ec02c810c79668a27d60411be","addr":"71bdce836bd62d85f5a53f9fcfe2310d40bacc56"},{"mnemonic":"hedgehog light govern fruit season cousin shy tumble maple promote feature lonely","master":"f4575fea61d7539101b4f89674218bf8fb206563cd07d729a834bd7cd8e3cc62","seed":"147de64775c5b285b09b2f846212750577cd9cf77bdc64f198da75003dfbda9c9dc742bf9ef1de8390641ddf9b03db8958cea480e5b4660236e29ef5d2d6a6a1","priv":"9ce717cacb307400d04739f7431fbf02cdaa3ae9035e00e8a31d03d6cf7e193d","pub":"031b6e5958fd3a5883f0cff00cd6dd14ac6cd4d92611e97c4cdd751d76323ffe0c","addr":"775cfbe90a93b73c27172b699506e4b40020a47d"},{"mnemonic":"normal tuna cry human world wonder suit tribe company pink weird unable","master":"834e035154ca70f5719e0df0dea3581a2ea19c4f9c4f7e1348810e0a47eaaf81","seed":"c1682262a9bb26399355c5a226abf198db50fd6891e48afd60094127db569a3306b5e556fc166907a4ef90c80069d9c0027b74532491ca54560f7a85ee1c2934","priv":"035c6aa4e2ae3ca2d2a356112809945b068a21a4c3a448819d8b29ce406423f1","pub":"02a18ee68f4c04f7c9698d484b9e87a672f05ecb87d127746b67f3caa820406285","addr":"b6f3c63322c96f7cd1bc13195acd2a9485b45232"},{"mnemonic":"school kitten swap accuse vivid spirit team verb border write boss barely","master":"b97687333b05ee2da13ce7c5d488aa076a1cd16c8b21f43e38eb0606fa3887cc","seed":"7a770e511a21a4712fbb40f9cfbab467a97e5165e89f70b27dfc8bf5a6a69fcd8658bb6527d0203e93ac549a89dad65068f06e8699cc9748e6448eb8faafa2fd","priv":"de3f7ccc0001822d6320b5ccf27dd38dfdea7ba8fb5c73afe8b6f71982b06eb1","pub":"029d4b9f7e55bc7fa1e84f403a19bcff9eb9a9afb873476b082374e19d3e7c6589","addr":"2cff960c82af319d91e2b1fed8171fe04d47a491"},{"mnemonic":"banner lecture vacuum metal clutch return maid furnace beef armor excuse mother","master":"e944b1515fcab7dd33ccb6c027535d3e4d5db2798809fa6e9317587a1a9f8a07","seed":"6089209e2ba24a756beb9a5946df522adc87d9d98dab2c528d5469bb35ca2da36662d661b0daf50695322dab3578a5bc3cdd918a7097c0a10bca063568abe8a1","priv":"c0b5d1c2ba77450237956cccc68a162c2e32c62e662a0bcbc7e27f2ffa24743a","pub":"02b52a9589c4a631aeee16e8ce808a2c20c63134407bddd7986a517ecd46f6f1c7","addr":"d79746b3b45903cdefbfc4146489ea550bf9361d"},{"mnemonic":"lottery uncover blood that bench peace raccoon define scale fault erupt bean","master":"faee8490c1b9b5e79da43146bf8697b1aac582410ceccf66d1fa54a8b4e8c1aa","seed":"cb558b5816b5a3ec5d63468859b71f9d2b5c4b7ad07bc00e5e4e3dfeceb12fce337cf1acd97af6f5b8d9277cda0197dbac16c9700fd41df33d9d470cdb35e545","priv":"1f77e09b423c423043b8c41b93060c9e795b6b0e05ef0fe75eae4a53abdac019","pub":"022a4a7f860dc1ecb21faa1f827907b01b87a552f8cb0a085af3a6a0758d922390","addr":"7566766fb425c0d00ad475dcdca95e94b17faae6"},{"mnemonic":"bounce someone uniform blush plastic edge bachelor tenant office report lounge brick","master":"8766a5c2858ac393f9e73c6d842184953eb0806304fdcbccc43916ba70ce8924","seed":"cb6a680c6044a9bd171e97e38f4933a86f94a643a398e54ed042cb7d2039e11287876ec24794a0a078398e14cf471ec6357d02c83009eacbc377cf77385834a0","priv":"a5f252e60b69ac73744b617924ea8158b93d4dbdc2cba19db4506b86d413f6cc","pub":"038d3945d243fd90ab18ce1353e36b3c07143dcce74ae9670fc8e0ee12a2fd01a8","addr":"b184c47600390fb017cf60d2b5c89c28f72d64b1"},{"mnemonic":"alley wide siren matrix cigar paddle spin fame receive cave student tree","master":"2cacce92a105ed6a199a6d881ad7a43a7faa74f967b4e8330a55b263102fbd8e","seed":"c67bddd95507e4a9f9153f7da3de4e5951c53750a5842f11192328994742669c32cc61ed14139ddb72365ec7065436583b360ce6e2aee5c196beaab9b10e9991","priv":"f6dc107f30701827bf1f83113ea3853017e384d6995205dc9fd23176e802ef4d","pub":"02c3dc3ea3727f6f351a12d3f5b3fa52beb25ddcb5ec397042aea4e646d9aee6af","addr":"5ef50803371d9c915ddeee096f7131461323c489"},{"mnemonic":"pipe brisk focus nurse rare arrow seek spike guess enough unlock transfer","master":"ad585f1ab0b6e5f8d224fee37b6c3d1fdab1e6c757ea93a9df059a36b3f96646","seed":"5b76d0f7fa0ed23b52ec73d65d109d7026f7cc4c207988c6a003a142f3e6201fb1770f8e662fa8cf4acfc0f23e0620bf2f7b139fa9d8d71e5a3c5b5c2ab75e68","priv":"dfd55ba52a10f26aad26e7532f6631986acb0247fadb1b86c45ff9537924e42c","pub":"036bfbb102ab379a9dea1cc63dba5944b22d48a941a0d1e534170cca9a53d3fb0e","addr":"af337ff42bf6280f7e518df5f4f064a84fe209fe"},{"mnemonic":"coast opinion view orbit knife december pepper elbow boss junior wreck escape","master":"4eecc11aef13009bdfc444037aa185585c147be182442a33459b5a07b61aa555","seed":"f543bbe5ed92b75d06089c2335fd22db68f41e499634760dafaa6661e23178e7d075b2f8aa3630aa528ed77d85737601d041278d182458ae28c04420ddc25b5d","priv":"0fee3e3e025dc742e5a95f41f2e2c84d94bc8cf068bdc67db76e0378c1ff01af","pub":"03e58501a3f5052e4b7b1a4bb264c5f5a61d60c542a761a015606ffbf97f63c10d","addr":"c51fc7f607bb0e1cdba35f503f3e397346148784"},{"mnemonic":"indoor dinner fantasy cup move solve pride dust cross note raw balcony","master":"6346159218b27d00feda5a8fd63349956636147e058d9eafd60bd94bcd18efce","seed":"1c39176421e5c49e7fb6257ae70dd7d1ec60b3e2a1a4523bc4aec59b040708f0e48099520c0ae4de467da994082c82e0db6f1445c159f625559adefa55c7ce8d","priv":"74d7f00b88798ba5190b71e59dcc4bd7f2cb11e93669d7ba0372f4155308b947","pub":"03a07ad498d80dc84ce120f5518a541b5310e50bcbf0c669455c8ce2a0eb13e253","addr":"277346e420f814e9bb1a8ab16b11af318bd78d4a"},{"mnemonic":"please neither sister wrap comfort omit stamp roast lunch steel night report","master":"1f0fb7b99b38b57321f40b4327cc38f7c41c5688a478e4be908353df70477fcc","seed":"6d383d1ab8febb2334354e9e5261d6d4797bee2e6b9242521d59d22f982525ca87141e713b32cd60b6aea587caca213d8e0524c1d55cb209a6d06f607d7b74d2","priv":"95236694952fae12a92d15ca17c54cdfbd234109aadf6c295bf664115cc35a27","pub":"02f29a1a01ba6702e3a441386986ab5ef7227532704cbcfa08f2339c5273fe5f7e","addr":"048f26f774131d92ca52228106fe61d12e7d28c1"},{"mnemonic":"lawsuit trip betray slam tornado polar demise appear east dose produce market","master":"8e659f66e4dcd50dc7ba617e17e4dc45c75fe957b656039a73f3583944b16ac1","seed":"d982fe48080c3bee97fe1ae2ffdc0c5ff2445817d28b30bccd6f89bee138ef1e9828b04fd99cd70512cc8d0e58010ecd7c4460c0b2614211e7ebd8acd27d2061","priv":"4d053df57043c403659a370f486e8ebfd60fa2804430a6b97d95ecfde846d63c","pub":"035001c721d157c1af6dfa4d1de23852ba2d9be1133f30628588c5d9ec890a7662","addr":"bbd41b5af33ef8bd075e93a01f5377d486ddc475"},{"mnemonic":"hen build sand sister borrow victory syrup scrap rack aerobic shoot pole","master":"a4f3bc4a89dd86f38c5908d229f58a57c11f4a3d6872a0fd448043a6a214f938","seed":"3823745cd7589411813362179d13b2d2e1cb65bad1d53f34d512c349215e3cd5bef97ed86faf0096d2cfd5dd75556bdcbac1ac385c9caa9f928a19cb926082e3","priv":"5c14903308d7a83b6570ad2cbcffa3953b458572a72c3d5148a79a494fd90cf5","pub":"03b18bbcb61fe68f733542afa7c4c02214c8980ae4212caf818a8febce1166aeb2","addr":"fd5a9ed68124fee88f30a8d7f19e65e5ee47e681"},{"mnemonic":"chest hard axis own found relax skull bus frown distance gauge angle","master":"6eda34ed25b73c45cc0465aed51577fd35c45ef7e8d8e137c621c5bd6a726888","seed":"fd71ceb91c1c0c2176d7c75ef17010fca12beafc5a54feb3408a69461e1cbf1ad0421da9f31532aeb1f32ee6503899eb0e20fac3756d5c1d9fb23fa2738605c3","priv":"7ee2eab961362c9fb48f0cec5f63d1bfb0b38e819ae3fc1a4a3c6fe6d4d35725","pub":"03131e751282bed411e12a03c7b2ae4ba4c8f81fe5e62f3d40bba09ed7ff099509","addr":"f8a2d049f67222d673df66844d4355ca77a34db5"},{"mnemonic":"large merry tray craft fat clip album company nation tent increase armor","master":"c442b107b26f9c853ef65260fe813449152c2fc93d28774824153cfb4d67e1c2","seed":"bcdce56a81179b6fb0224a34b26583b1d1dc1d24a06bdeae60eb578df673d4d9ab5d8d639c494fcc024a945284be11ff55dd88d2470bb3740b3046155818a7ba","priv":"f359be0bbc26a121997cf2b6678b41c08d6815a5903c184c7743464e287e8557","pub":"032641e977e838507e61d0e85b1a2ff16f0b8d8a351f7958ea615bc2a8723cf1d0","addr":"924690289cc78854d75ddbcb2b06b241404fea7a"},{"mnemonic":"carry pipe make glory famous word shoot artwork ostrich slice blossom episode","master":"f6ad202d1f7acfe41ce8f97c809d0f8ab9c7959866c5a435faa9d551e98d921d","seed":"5b956478a0cf11e9e0bebfd97b3ca56a6cfd8499843d21f95a2ed58db8abb7b06c672e713a556c35258fba0533721cdeb38313565c8edbaedb17dbc1c8396a6b","priv":"0bf855554127bbd03b3779577449c37dfb82ca4457adaa0edf26f1e5e5d7ee27","pub":"03452b2268005ebdce5fb467e4ee5376624cb0dab31704c4725796dc68561b6f92","addr":"ce486d831a5c2e1b95a254c13393e50bea0cea66"},{"mnemonic":"inject more grid coach cause inner ordinary crucial mouse access attitude upgrade","master":"6556ec1bca4ce356846f9ad603e8b2e9a1ced7e2f875bb6330bac32baba3e820","seed":"c5248835bc868983d65e6009b983ec48b262a0da70dc66ba76cb167b9618730ff79b9da8e2321731b55ff63b8cfc8a2b59aa435146b5d2a21b8608bc14808bcb","priv":"3b783218c59cd664b88380619db7a4bfb4b3343fbf38d0a576849c60cb4eae41","pub":"038f88cb7546e49c3dec3d356b0bc70be0716a1b146c641447326aa077d91d055b","addr":"09e570c6a4c7439d6272bfd611dfe723d2fb632b"},{"mnemonic":"viable material flock borrow pear cup barrel fire exclude vintage economy force","master":"ed54a092853793849e78e0c42ef95242414a2dfaffc92d6b7c25efa46715e23a","seed":"013530be872ace250a72aabb73add7e4cc4568da3aac9447c094c49663be2cb6bbdc1fded3bffd41109eb14cf1e8ee48aa65da60166962aff17451bc86dc9bf9","priv":"669218899eadcca8823c6c10476cd25fe546f918495590051f8d45debeae3cf4","pub":"03f54a4a58259314bea899e9f6126305d13afc7e8de6b346e95934358b524a5b4b","addr":"b38f1873c88ab12cb5c839ab1e70639538b331a5"},{"mnemonic":"injury expose attend toward air brain carry neither amazing symptom number name","master":"769158e4432add662ca03b558828568f25369b5fff971076f7a303b8c89bb3f6","seed":"827d52b757b28ecee8ddbc402de54ed6911dfdf19abd00739766f70fb688f47575da03177ce2610263013c2d22e3ca7556c5aa134f74b8faf61dcfba1a4d5ee9","priv":"2d276c19d260ba43e8de8e4b982bb21e16f52b5c8e231cfb6bf71901a9137c62","pub":"0310fe6ba12f805a118c9052ba2cd3218418217e1e48da3daa5887bed6b2fe9bbf","addr":"0ca37f96efe4af7507cf85213a2aecd7dddfb51b"},{"mnemonic":"seat other color road pulse melody error hire scene lamp best analyst","master":"c4e172dcd2a54bbfd30fdea8363eb10b9f0bbdd0d1ff3d33ad3eb01e820d417b","seed":"32d43e6b794040093d6348fc46a452a8733e49a66a06cc8ed2045359c881630531e282ddd70a4d630a3ee69821764b45ab949650d4276a925cad0c3121c31074","priv":"828b3cddb3d902d31386264f84bc54d3574325f56df7d4e8e06b2145d60a0de1","pub":"0275e251466e97a728d0ab4527e04031e315de4d03d9cee50b5b52210fb697a9a9","addr":"c0e6ac260e64b92beed9f4370cb006e2697dea6b"},{"mnemonic":"tonight nature salute state carpet sad zero heart limit skill vehicle elephant","master":"7f116fc76af767fab661d90b8ce20b51cf5d0727ece353410e06409d79ebaea3","seed":"226457053ec313b3368e877c76f9f8a2cd5a7dbde6cfe91de075974f42f994d195f056d20802fef8bef78cdd49c6383e95933eb2517cde2bf353872a13d87da7","priv":"1f069518222310563fa736833f06041805cc0a9ada1ab2b704e85ad91b980ef5","pub":"0221fd13bb9d0177d081c7cc6b9012b0494ccc42ed79ffdcb2409c252f42b66b9f","addr":"401f8cd411f3c5475482430cd0c480ed383e8455"},{"mnemonic":"window awesome survey swear neutral tackle essence elephant weird emerge gesture click","master":"ffb27c19b7d6241a29a08c54605f0408d7de2af078a3eabde97ba6e973b9c31a","seed":"29aaedc60b8cdaeb799707830413942cac78b57c0fa1a4cae0542411a81efeb36d7e48e222f90b6d42bcae97202772d687c226a13143a9541b0d7a3bf7dbe600","priv":"68ab3dca6b53b32bfe8a1b2d428332415b6278cd258fecd927f9d8b371075789","pub":"0234cb69b2f76362ff4ff138f81499d5c2e0a1912fa47098c0d826f98f1be4facb","addr":"54637f8b0f2dad74bb46e7745d1957bb8b16f4fd"},{"mnemonic":"island pact measure trigger frost flee tape napkin wide kick select sense","master":"013a5ecc8a93bac063e18e79f5654cf0881e8c39fa43c467a8aad833b6a7ea76","seed":"19cee1ab2babcd2cc5cb4bc34acb350deaf24b997d603814a5509374a2f60ba133f498a20a9066cba31b4903a6c9da661dd459343004f69b2dc78ded2dde67d5","priv":"16b0960d535046bc5b95e335cd0326d0b0a902a3c81f70490453f75154a05e8a","pub":"03e6198bef79e7bbe034d1786e47f00fd53aa3132318ed99fef38b6f46bbdd9109","addr":"199fb6c909420f711c3b452df497d03da191911c"},{"mnemonic":"before shed sweet will sunset rapid color tattoo winter foil spring orchard","master":"29289b59bf6ad91e0f9b24900803f57d08b45194782e76102f5377c142c17f65","seed":"7b721e94ae18b7666bf293bdb8eaffd70c6bbd2c2ddc582a0939100f1f131009752be6759491e0006cfc424f88efd97868132fa2e6bee0b05a520c881c632951","priv":"f6d7fbb1fa8957d132b1d43414b0664cbc25020055c35635a5ae005e86e40767","pub":"0368c1403ed0df7c1f9faa90fcd60937094cc975d1ab5bc7a9eb03bdfe764dcb7e","addr":"6657bcebfa3816af66b1a0a92f8269cd3f515fe3"},{"mnemonic":"view forget toss steel right echo life candy fine unhappy document pulp","master":"5c6355a65617952bc05b16623992e81daf07695ee5cd3d9bb2b8fa600ffb2576","seed":"20909264d02b6b88a472678b6d457850ce4f67a228a4f6ad7f45be104029ecb68f25075f30680416e0e43469452ad903a1e7b0486932d0dea4b1c5f56b21406f","priv":"4495c90b188f706dbe1106966e49745c49676e5c54f78176eac166629a4c0815","pub":"03b828ccb3f9f1766cf1d1c1c57e8e5c9c96936adbcac4a8ea47b0a7e3139c5771","addr":"4a382d15c13a06adbf075cd847ae9e80dbdf4ca3"},{"mnemonic":"fetch planet injury lecture myth goat drill sea reflect tattoo story rival","master":"3725eab28e9f4275bf2dd2dd5a94aa550688b8d111798185383a58088d6f8b56","seed":"0d42a4096e20202bcaa4d1939ce86cc6975092d2e6081c149b374f3dbd6cda81188c442e1cc7b67032fee9effda37e20da0d809f0d969977ad2c547e9a075224","priv":"7abbbf9aa4375ec489d3ad3ef6041e9e371f4582eec1ed753f9d7de3b4fcb57a","pub":"0371b9cf4994f36ac2b5117a2daf84d7c072f63e51d9f7c5e547548bc2ce51a16f","addr":"d59315e071460c09d108bfa31e05cf37545b19d6"},{"mnemonic":"close raw empty danger educate metal vendor coil observe response scene army","master":"da1ffa0441ba19153f0f98af4092dbe68eb5ffc9d82823710dde6654684e8fec","seed":"f8ea358ea3a369cf72266a1f30e10c445817766080ba50991a2b10ae1f23d1fd3681ffd4cf4a7ac47b39ee9b04ea246cbf5337eb33e0d6e7c1da921d153e2cfa","priv":"5e3f256a55dbfbf2750e56067779fbc05503bea90e1a999c17a0bc27801a0bbb","pub":"02329640a5fbee753825fc310c06f9761cedfefb880d6e3dfb67eecc68ee269813","addr":"904c7b3d1cd8303fc3c8b0e3b0fd60fcb54807b7"},{"mnemonic":"ship puppy grab also merit doctor fine east venue resist loyal radar","master":"f7e49c26a890aa8deb888da48d82935a69730bfa0af67783b39d209ca803de9c","seed":"dd5c5df895a6663cea37b5e7c58c268420e290e4f20d7e0b7c98defa35fde4d372f52215b52bb2745481b8c63aa08c2ba163dd89f2a9e51a3bc92199be8d57ef","priv":"19a311da10e6f11ea3c91231a7e5bd22097701bb56c0248014958e6df186e596","pub":"023acf91dfb359e537f9183080ccd67f65b1b9efe314f682deebcbf718454d6bd4","addr":"618fb20184dd651d18d2e039ac0fa43e53feff61"},{"mnemonic":"beef hen spring repeat define hurry slab midnight liar either arch original","master":"85a6a3be23cc74b32c40f1dbe431584f8767f4116a98ace1a08c934956e8582e","seed":"cbe260dd75a3f8e7b7b9588f0a1325dd88b839a5536e39facf324cbbee3ae951903e2c17370ef673c770ff2e0fc3f1975a26f45d27c681a143f0e60fac8d18c8","priv":"42c6ccd133fbb7d3bd8bde8309f8202eb155c46829aaa558226b6e53abdb203e","pub":"02d1bd732a69043343e72e22432f7bc309e25e96d49b087572f021996297abba75","addr":"9eab0f06ec4e0a8058e4fde3ebd5a1b2f5ab043d"},{"mnemonic":"lend total guess ski divide diesel tumble heavy slight expose clump park","master":"6ad684d3e30778a46d5af816c3deaeaa0af5c4fc04cd74045dd80947faba053c","seed":"d63dd68a0b8296a41ff8698494d9823d18b4700b0564318f022b1bca641a8fd622ca403b48fb835c848f053557cb91fe4290f37ea9edc4f2428226983802e1cb","priv":"9625f841a7384f3fb64c643ee715ab0c5693d60132c4c9838c7f41e1c9163e1f","pub":"035e82a39dd7b61ad9f79ae31b0694af43378fe1b5cd6fa824ad2427da0834e00f","addr":"b88aca334f2bfafdb66c2e338a7d3b6c8be8bdcb"},{"mnemonic":"toss hand crystal buffalo during more laundry fantasy give dizzy bench want","master":"075697aef6de8c5b0b418fb3faa6038442349ded65421ae1089517423120ffac","seed":"4226da530678cd25633e2f87951c6f8f5bb4e3dda3172494dbc03ea15795b22d1042ba8265d67cfeddbc205b800ba7b7b05ed231845ad54cb3224c7ad0f9d8fe","priv":"8db99c4eb921431ead557ec1fc62bd6a9bc34eabb3516345a46bfe8c6106be6c","pub":"029eee00e90a02beca7c3813af59feaec320d26b585e5620de11efdc09a06d2c5d","addr":"e9a4a29d0e7267016b03bd23d6cc78b9eb1681be"},{"mnemonic":"camera gate trick sphere oven sick promote apology reason fiction item meadow","master":"7af52d41d0e35f2cad60fa2fb6c13d046f8aa4e0be104251dee489edce66a229","seed":"16ce2107f57bc5feff86b9dc81c98838cfb7b6274e835d6e35a46525d5870fd84c74cb528f6e2b87b0cef21bc6931793f472e5430b9582f036630c3b7c66df87","priv":"5f428e529d340883faceda659fdb36193f3cedbe2307dc4b8bee55a6845b9068","pub":"02c71ec0f9fc74db1da6d2a4a9d6a7f24980fa17e656c1d7f43a845a17625b2445","addr":"31dd6642a6d913d82b06c3793ae678670ea9bef1"},{"mnemonic":"slim guilt leader segment actor sick debate enough what rate fork rebuild","master":"674b90a421dab99750e982cd3c693668c45d7a39377cb82e3887552f047eadf8","seed":"115114f315f7af942dea64857c5bfe6a22c80031e6b1dd0c19a42a28526c0b9995b0eb39bf8e78ce849559eebdfa3c269783987bd4fd926e776984396a3c604e","priv":"2fdb1afdc8248d6afc69e387a698ef467dc0473323203445bf1dd5aaf5789936","pub":"03dd070062a8c3e65333572beea40f434d6f1b68e528ffefdfa8dd3d8b4c5a729c","addr":"8938c102cfbb8030cf69c660b04fee696a902f96"},{"mnemonic":"kind prefer arrow industry arrive cherry pupil arena strong tuition wide grunt","master":"c4b509d9b1e60d97cb8b862b96a2dfbf960b0553f0625af7430abd3951c59b2a","seed":"85ce840ce0f6625294d32cbd5f68b3c2abc3151db02b5a84b1d78ebd7c05ab24bd49a519a340cd19bdce6aee845ce59b6b5d2efd7a2b1640c7919177bed27b4f","priv":"ba8628565338b55d2a79b21fb9e47da978611095abcef86f305a0e2988e8128d","pub":"02bbbb0be37e3975749a095a9dcc025bd57368eee362cb896540c0dbebba42f0b9","addr":"4d8e97ff30d95baeb64ced528ab999c72aa4cbe1"},{"mnemonic":"slight bronze prevent civil junk van female movie vibrant soon grain suggest","master":"4d07291eea03d51cf9a3790ab0a77ebef383f2cdf184b0ebd872fdce93b0b889","seed":"4f770292818429f588226c4df9bf6053024a42f11a2499f0c2c5ce56f25d16489a2e554b99105c70fa57657b8d8b724d1879fabdfeea8aa43421d19849a0fad0","priv":"bc6ab78b16b831178cd9f2722bb8afb27664d1967cde464af0b951c3aea935b6","pub":"02673643c7fd4c12f47007a27a56537d152d607225a6d561fd0e18d30064752e38","addr":"3cd7ea7b1daecd3efdd14826508409791d8ce865"},{"mnemonic":"chief drill utility gauge tired alien bid deliver tooth amused busy run","master":"dbf20f3b945820a74898fd73218ed84a61ccbbb28d815d26dea7a7e9a9b0b430","seed":"93d2bcfeea8a87f021002ffadc33b664810eb8ed60342c8dd74a937cee64877d5823c45a4d34dddfb7d4381addeeff63e80a191b92dd7f1b4f0dbf5c5e8006a4","priv":"c38542f0dd692e74e8635dd784fe14d8c70ba931c354d6ea08f1e0b9080d74dc","pub":"0225dfa0e7d37e8903213d8d4900a2e56107e7dd02c66cdb7f86e9d9c0a05a835f","addr":"a94ac8358eca1fdb0ab8ded1cd80b492dda39dd6"},{"mnemonic":"large endless art unusual tornado loan planet excuse dolphin million reduce chair","master":"8f029c13f62099a1d280224f9af2d9458014903b3df1eb65647507e4a5262012","seed":"03d076444f817fb054603f746350c40c0551c3d155ded436620451c4f53ad1254d0b52bb0592197becf9e1fa14bdc65d04c7ab9c5bba7737841d800cb4f7c869","priv":"1cf63efe6800cfee972815f1fd71c68224594557d7894fe8902f56b40163ecd1","pub":"03cab792d05c87c205acd8d78771692507eab35d8c7bf729e2d36551ee0c7aac67","addr":"9f27d874704a788d3e3c3f63f9f1a42c27b83c18"},{"mnemonic":"recycle wine system erosion train make sting talent beauty decide beach pigeon","master":"d702a0785f59e080e2ec13280ec397e3af1c60a36bbf2c92c252da896caa7371","seed":"ffd0dd43668393be9b0949bb5872279ebd606be9ad58f8611ece8dd8b408c0714d5435c771ec87d23b83952af75a6853d94fb0ae88a9b9c1b506e3c0887f3bd6","priv":"d27a5cc824bc9e78ed2c991b8ca86498ed48775aec94dc79332057f2a36536db","pub":"02f85cda3ef9d19e68c4a3778ad99fe008904aa9a80c4dfa8d07355ffc840249a2","addr":"da42d3051e6dc70d85b5fa901e1a4c55ee12a47c"},{"mnemonic":"solve snake loyal grape island deputy monkey art pet candy enhance truck","master":"e866de4a10e7067fc8f6462938f3ea5fa7c88c93e2f630ca81dd07361c646fa6","seed":"82483d5e61c9eb2b0c588b438e24cb0a24922abc6cf0571cf3680474f1eb31496e387ae1c017d5a817c88e48020c5cc1298cfbd78d7175be0a1ebdfbf94853f9","priv":"919e4b231311f40772a47f03948b136879c13f5f0797c939e703b7082d65e637","pub":"0227c29a984f46d5a99c08f31355c3471eea9d231ad414286a25fb91bd8a3a6f92","addr":"e1ef4d05f41df82d47c287ad0347197e8deee0d6"},{"mnemonic":"energy buzz square deliver jaguar chapter analyst chat rare over bottom river","master":"3074c2d8f092896e7a197abaf388828f95eccde75986fd280c9b098586e18396","seed":"70be3c734ae665956abefaa3f94101b5863086c14d8c17ab288a3586bb69aadea314ff47dd19a4dd4295ecdab627a34d9bd56231180b20156b65660082e70d35","priv":"47ed2e3406d068624039f71e17f949c4b7865f4c8d006d6b4a635176b700bf2e","pub":"03786b91b237ba9c1c209d8386ab1fef86e0c667cf2a9a3cb25fbe06927ba3214e","addr":"67ba9f0de66103c6d6f1b799564ec38d4eb9f708"},{"mnemonic":"document move actress food guilt fence govern adjust supreme upon stay sibling","master":"6d110c56993597b6bd473eae083493e1a17b4cb971999b078e4c74c2a675f0d7","seed":"e6a300fc434aca28cb75f2113a8f7788778f2b9398290f82f8e5d989bd002659a645c18057ba64807f0d4ae3c064e56a2947d5aaeb83ff3c593e942fdd0542a3","priv":"fbf0d5b6e019bf7aa6745c4d95c0f9a428d0dd57b7af9e71eb2e39a6628b8d86","pub":"03725d6b7196d57cf1d3b193f1a6661613d02912981225beddd4e1db8de60682bb","addr":"9aad1b39fb3cd3fdef63130bb1a7c8d12bdcd866"},{"mnemonic":"express birth sweet kit special board rose sound place chimney awkward injury","master":"c60b7e5a1c89797d3ba7ce33ba487182144b4203379c04e51ec7ef4ee621f0f5","seed":"48274a66272c61abcdb72d36f16b6ae8a1853d299d9514516374096b443368656ec28f59c9f78f6707d1d1fd78c4aee00e046cbd3df66ee7b143b60e262ce162","priv":"972cf1431308c25e45efc26b86a87c85ade411bf3fe1cb6e88143684910dee6b","pub":"0243447732d68ec3287f154750f1b27df3ade846a0d4cda8e5e5f62f3875de6b86","addr":"c199f50b3c111205cc2c7309c9239393bc2c1e57"},{"mnemonic":"future desk scorpion enlist confirm favorite ill expire evidence cushion rapid staff","master":"0f15c9b1f3210c53c5c408329c3c028211660eaac42f27749a4e8901ee17dff5","seed":"c2db1a2615fb9b849717825a326e5bc2ffb8941755a529cf27903c0c3be806b4261cc3ed7afa8748d87d1ccdd36372fa02f92316f1adc28a354feeda7a0edaf0","priv":"39de89d88ac3f8b23ec57f82c83f9bf12a32762c2df4a612ad647ac9ba287c93","pub":"031abd39702f34958e3366a4d438a7285bb9d5ad5b8a29071ddf77ccea7f9c4358","addr":"a7bd49b9e2804e22072b1f336578334c53b6755a"},{"mnemonic":"interest judge only feel scissors illness quiz goddess transfer person position this","master":"f60677c75a51c5c9e8ebc4fc1320dbbc82e00a42507af218a71812d6f981344c","seed":"6e431ec0f7627bceab5dedf9165968ebfb03ca749aa8d021725338ca8e0e8ab3b00cd0395a68ab955068046c63daea7ba57117ebf7c99b242df8e63d01bfa625","priv":"41af5034dc87e11bb1cca3cca70f80fa057a5839b711927d3fab85048ff8620e","pub":"0321c6b392ae7a49201d0a7c89fc3541bf1c0c1287c051c405cf32a246df97c231","addr":"a71580dfa7773d8a2ce44c7dbbf03d285b46e56f"},{"mnemonic":"foil remember sample infant bread year evoke laptop buzz chuckle voyage gentle","master":"88ba5191913e778f76cbc28850f221e96f380724d29646f7cfd4fb6da20171c8","seed":"64485dc0ccee0c0b13c0bc76e44f8c3a26070a6c08fec558519503ed85769ce3f858978cdcd630b9c017a290ae4a7bdbeb0f66fa5e3fdf3ea227187a165ca654","priv":"117e2b0842cf25a1ee21eb2f244a2c1fcf2a3a6946b3b830707f7c96057616a9","pub":"02b349892030c73203e3fbadf870e1c8325ad0ba1747738706734f7a66e9c66ba7","addr":"1f6488347a7155806da3103c9a82954072a1abb7"},{"mnemonic":"pony super panther surround glow lounge kidney increase actual tray bulb device","master":"54c50d2520ae7023ffdd39740b46d029ae9e31211349193fef33cdaf373030a2","seed":"3d11ec99f173c1864ca6638a27554549c3f619a86e0099e5957972722b2937f5db767d86f5fa0c6b3e0a81d75a9aac5786cbf01f2245b51c9202cd4b4ea88a99","priv":"81741675b625a14760a1ee9e108a9ec6be183c480df05878cb31b45e0d0babcf","pub":"02b0bbfc4e33a79bec82682552fb4c0506528d121ef67a7a42d2ee26bd0b1661ae","addr":"8ec9b249788a123e1301100da2db3db71c913a78"},{"mnemonic":"achieve sail manual vibrant unhappy ripple aisle fossil pledge wrong cherry trim","master":"ca9ac46762b80571c25c2a9a6690181896f86ab3f728b4e372552fc9cf1f7e7a","seed":"4c1cf0279c8a29b8077b5797b6592397112b65e75e91b829a0a9f26b94803a53a02069ef774e7cb5c3cbb0a8e074c69b9afc5a4136e04913403b70046759471a","priv":"09503bd2da16f128b857cfc635cd90064446130c2477004a3870a0c5b1f1febe","pub":"022b34a4abc0a4288805719d72f0b64c3118d924d09a4dad4f26d39ed056349e00","addr":"ef2b6bfbe737261b45e770b5eb42d1950c556282"},{"mnemonic":"injury love grit wait junk bridge myself sister hidden dilemma gas paper","master":"b4781c7979c0b72d0c50c9889432fe2a54d6f08a4101778f88176dc661bb02a1","seed":"03bd824d7f4487af26d236950a69eef9c878361038f0e8be44145e558779d4accd58a8c5550bf5ea86ad169e5258947512c4b72f94bdf60b9135c28a4c779541","priv":"68354a2599b3be8ec6dd827b35290d9dfc068c267f1d89dd57851b22d69c95ea","pub":"028af1d826d45a920dcfcca8d9f86dad10d7356b3027d4051dd4c46ddaf32dc623","addr":"1f356a55f3d3fa48e5d5b36fa31f738bc8f83de3"},{"mnemonic":"domain congress cake cradle express despair devote swing meadow piece border cross","master":"a3ebb93b7fb0fac2b02408c0491f66800c220c7d47190c3c97023f3d6db86555","seed":"15494e78dec34f3fb759000cb0584e42addd40f1794bf2932c6bcbbba20e40a381bb9bc1b8dfd3a231d8e249aa3d51a257590a93188fbf116eed9321195a2267","priv":"1f1ae70c46a36ba70674c7b17e6cf0b8e08bda0a17473d8ae69bc54311239821","pub":"03d7d916b054c003413ac84402e59b976e5515f48bbc30ff8cb6bca7f4ee92c03e","addr":"54d0f98b9dad14550c844bbfce8a4031dd677a1a"},{"mnemonic":"pistol news assist poverty squirrel machine aisle sausage harbor garage truck type","master":"581d692fafd753f080fb83318856ccbf059b74a3f26ba22d4b93916e2165aec6","seed":"49abafbfd7b0c65ccf2e22eff01c78245c764d8ba7bd468fe1baf62a156aaa0a6af143c624241ac753ff8432712ea58f1df9e75cd969f905bea80c15b5fd84bf","priv":"f1d7e572b03a08cdf0ce00908c701053a5804fe566168436b90efd1302bd7f1b","pub":"03882ef7180679169f638a7da20a2b522c948b1979802cf4df83fe1b62581e4d4b","addr":"40bbf61a5ea5b704d02ae13d032f3dff4e597ba3"},{"mnemonic":"field tree license quality chase certain hedgehog alarm melt elbow screen pigeon","master":"dc22c189c264812f22664d39ea1fa2f7d986b981d59f1df2ec6f8582d640e196","seed":"37ab0888876ccb32b9ab73f144ba2a352b31b27fcf6b7f8fcc5a2d4802e7099a199242cd5f7f2a3c3a7d86e8c1abd871ca35881a6a47f605d04a063b589fb0b7","priv":"f82f484f92d1719d3e6832d49bbd493d5f7191acbc07872b345385c32f2d38ff","pub":"0390c62a3315cd02fa64216cfbcc1788d537818eab5cf932a24f9eafe6f4031f48","addr":"8933e5a789211fe61396f29fbc55be6ac7031550"},{"mnemonic":"wish vintage fiction false gap bonus abandon cloth usage hurry toss slender","master":"27f3a0c1791709a32f8ac4fc1e9c71eb24c06e2fcdd8dc959940cc1c8655a5ee","seed":"36932e48e1712c3d03261d432a17e940f1f21d730a3f22d37c1834ca0591b71b438d684c926ebdd51e6431502b8efba8e9c32cf457e68b71079864dcd0d1886a","priv":"bc0037a14a0297d3dd969b365a6d8dde9c6397dd3c8aeba6d701dfb1bc8b24f8","pub":"035ec8335e2f6ef0fa2dc6be7f3271b1117545ab02cf1c8cced03f9cfaaef7c602","addr":"5f64f8eccae09dd614ff9f7224a20eaad60c23d5"},{"mnemonic":"fatal strong idle grief present photo aware various april april card village","master":"ae83fc216ef4c81e2d128d90e91cba0b475be472d95ba77c2ab9cecaa511e308","seed":"3901e5518ac7cf29a42b94de334dc641e1db3b97b44a30d69f3865c050fdac8339dece5f9ed96a17e669d51d59ce856db902e918497ea8523e5ba49fbd06f621","priv":"1bef5a9ab2f2ebb16d9d08b958317a37f252f3de91a70b2c8b5b5ddc0a187ab5","pub":"0250e5876c37987b4189513c7a5dacb31a308c563bd09d7557f2584a3c86bc9d5d","addr":"bb82bd68b31663a75d0d007646e8575934991f43"},{"mnemonic":"error monkey argue fluid afraid hand cactus sand misery close laugh comfort","master":"1b4ea203fb592e2dad7f40b6cd4c8ab53c6a0a7656cb674f9e22d6a0e4e84efc","seed":"3c0544c9b9c32165fcaf9445e49518f8d0a2dc6ad672a01a15183ce1e2188f6fac026cebec0ac4ca58906d5599d781c18b2cd77d32992be9cfb01441d396faab","priv":"e0d0b452b3e1f760762f1bdc692225e7b14277d8227d619bda49bcc608658bb2","pub":"02e7a7156cd53cc7c8b4840772854e25b8c6c532c520770883da9d574c86551c7c","addr":"696d7a61a2ab18eb503cd724f0dd316340f96c90"},{"mnemonic":"demise know punch page upgrade gun smooth fruit machine long nominee radio","master":"b36ae5062ebe21f31bebf7b2078ec651ec579494eb764bedda7169095b73fce8","seed":"0f71fa966c1a56c3e11c54798052789cb0f450761a0227336ac50dc8206f032133937511e93fffd54103132d822b8e717ef15fcd4e68f391a398f14cc795cd76","priv":"6b9a3d2e63d666909216a0420709f127318f809549df2e99869fa70956e41dda","pub":"02d72eca95feaccd5a78567311e882d7b5eb2914d1d844e639b03c4cfa036155ab","addr":"9465a8f3afcc348d661bc198cf8220e74faa5895"},{"mnemonic":"install lawsuit guilt myself arena enable unable thumb domain lift feel object","master":"c033a48b64aff8d6c7fcabfab52087c0f7b9a4228837a7a21d8156358e5eb529","seed":"8075fb6cd8bfcc08f1678c005e9d2d0bcac710a6a62cfea46a1ccbf81747362a0e6a25cea2fa958fd320205e0f95eb8a5884c6f39cc3ad17d58fe49e43feb513","priv":"24e83fd857d2a0ef62052625d84e6aa37e96b14f2c8dbe5294107b647b369a7c","pub":"02d95869834be368c5bc37a45153135a1c4f003be6a44bb9af89e55485118826b7","addr":"631e72e50070f34e23ddd155ca0670c8c8db49d8"},{"mnemonic":"antique insect develop sheriff erosion appear easy fog kind apology stamp noodle","master":"72baea3e04811ee7447249a1140ba62e56bf473d5298b610235ec3178b388692","seed":"e751bd7ff01706f38b8d3a28ef3b1565f20a8ad221d521176347e7791d2cbcb9cecfbc8b51c2e36c303be55df280273711d94c416dd74a7e7a18ae52520cf89e","priv":"0ec2ef082498bbbf0a0686fd232a3b4bec66d867cca50bd0cb0e3221bc9223ad","pub":"03952fb023bb76ea74a6b5b9c4a035b193553a8adc1c0774f7ce4976ee2e8c7fae","addr":"9d63d52c57fd76c7036b882ed40f4a6714164c27"},{"mnemonic":"become tell dentist play light illegal work animal library dragon now gallery","master":"895a420763a2dd6fb934ef8d83762051b00235a83f621f57377a0d63b71bd43e","seed":"05975302d82f413289a1679cf6a69feaf8be733d7fd10deafe1470a08ed5796bfec454adde87e825ea80ff05586c12f5d0de69478cf72238b3e73851f691a3ed","priv":"f94266abb2a93d963a2505da57d66c36d37ea3f871654a0e4221ec911a6b507b","pub":"0256fe9203bb64e250fb0e68a7cd3b0d3c90cfa8f8db06c74524c63ebd66098ea2","addr":"4f73259b06b65db4afde238bf4b42a801178d92d"},{"mnemonic":"average anchor total witness carpet myth life admit gesture inject sustain valid","master":"aa36181d7a04a32433e6f4b1e4830d3e0796ea00b8b03d466087911931c16abc","seed":"e2bf601f15b7edaa2176e6a0e734c72f99ea63086ac463ba2dc317dd70466753fd1334cd27e28c382c99179db6a5b00003124f93a7a93da3a0018838b3b04595","priv":"235e293ad68581b4e24a554704eab59caf513b60b8af6b15fa5d8cfe4265e44b","pub":"03b9e9b4b67e3bd6500e6b0c3f0d0f69a15d0824f236553f7fa12a58111e5aee7e","addr":"3733ba0b6386f7534c7714e9e2382675e0dff54e"},{"mnemonic":"liberty cradle play vague cute borrow around that tongue wave solution share","master":"87869b74fcb6e5d4b0b5c5d53679737f275396d63cfceb1133e49458c9c74613","seed":"c60ac4201963706912996e289e5b6d886693f7277875b46ea166f4506bfc3a2652ae2fe5b466bc171c7c7f09f2920b8ecc6d9c7d2e0ba1ca2cb10b528119cfa8","priv":"a8cf8fb93cdc5c13402976952ddf2ba5c2b37d5756861536df21d02eb7d2c593","pub":"03c12a9f6ffe4d7b01364f266b835be4eda6515d601bd39399f6577c53b1289e12","addr":"cf72bf854dfe493a6c742d6941a4f22fbdabae1a"},{"mnemonic":"hip dose artefact tumble keen favorite truly stand accuse spin opera wire","master":"94ade552d985f2e8625e18360914a5046ad14b6cc5fa6abb4ada333de8973595","seed":"c1d9d325396486e588972df5ed2a281a1cef82184a90c7ed7ff1334e35ae92a15cbaec6d27c47742a28dd458474980dabcbc651d6a2eadcb97dcca08f295359c","priv":"9d3f309f684c2c61a0f05fc88e27894cfec51b738058bdb246f1a9fc65937fbe","pub":"02c1da3c5abf3dc4b52336b362614a1a7a24853759f72fae971b43940500badf86","addr":"cb143b40309bc078f3db3e24009ab54ec4741b9f"},{"mnemonic":"history team sight sibling art over pulse network sausage garbage october slogan","master":"2eacb1cbf92401aa2996b19c77a2f110faa835203cc6baa1c98204ad1740963f","seed":"70b0ab283cce0e7735ec8d05bad6178bbe5a19b747ca1d5d3f5a29c83fb634b43c39f621b11210a7d89ec988b94588b9d8b8f2f4c2a9ccb687cb807e230403ea","priv":"986837f4c2853f751c51e09e514d2d40b36d3995e9561b451474cec6ce431a5b","pub":"035ed85029803a151586b8b3da3f7b2208b257738dc43fd1af08c6f76798e82609","addr":"931b1e70776f50c1186cecec2dc8fcc917974e00"},{"mnemonic":"labor area outside toddler street now same obvious demise mammal puppy boost","master":"720c9f77cdac069406469500511e891b35f1a5782ed330f31ad1dde4bbdfe7e7","seed":"ddce9ca2ae36975072a321de56c51a6ba88b53c226d66006b81d4572af6c8c39303a5a8d56b1626510ad730d578105ee84ac079538118f9cf8e56b43e9da71e3","priv":"8182fafb8ffddf9b157f5a072e57d778e766f7fe5b1bf58ff6cf6bcef46e1d32","pub":"03399e5ef2e4a978be70fe20b7d44201b5130894588033d89e1c0b891576a7eccd","addr":"15a638bbd12f6cce559e0f03312fec99d8f5126a"},{"mnemonic":"coil room slice arrive lady world turkey huge point gorilla course oyster","master":"bf665f511652b19a5ba1b0a51137aa72e392a7149c2df6af31a0244dcdee4475","seed":"2abc97e164bca2a5f45001574f9781dd837304f949c28c102c9de3d713d8cb0443a3be55a324817e53d78b50f0a939346ad414eff0b6307cfabea6023c2258b0","priv":"dd27b678563eac5bd7565e130f6856fecfefe3b1364ee0afdace0408b5ac09a3","pub":"03ff0c0d776d27564be0a465e29923384215370508961a1a7c25c261d09115f8dd","addr":"c4e5450d737defbb8f4d406650c93d79b1820043"},{"mnemonic":"diamond empty network apple radio divide ritual flip correct phrase kidney say","master":"f451294347b6c2035d9cc0c635b777af0d1fa756e1a72c2e41863a753776bf49","seed":"9108fc851316d1f63bf92d68e1db688328b7ae4c5ddec9248d8b5012709dd14dda42ebfef74e61085ae56c64a9125e3a47184320e53ca82684074ea0d359e6d1","priv":"db4465c5493f98c16b002401e28422b630bfcfddf32f8112c10ba71787490e44","pub":"0370a09ad6af977beadc07793db44c7bbb94cdc060a12ab36949bd36a3aca9c776","addr":"b9a0c2f7fe9d2f416596b71538982206c70a38b6"},{"mnemonic":"cruel music theme kid pattern weather become same arch foot host region","master":"82dc215e8155458ad1f3c61deccef305932839a6087250839c41afc36a043f62","seed":"0bf672820da35a6601782bae8a773f4dc6381fda5fa60a3ded12cec851225042769cd147c614f0ad34515996bc1f90675c431a5517c2b5fed80552b2bba59d7c","priv":"a63537932e88d10143726eabb410b3fcf0baaa550892ec17fcef874a2df8b70c","pub":"03b01ab00751243c746766568875b948e12eb1b88e85dbbcf2b538cd65544b57c5","addr":"137ffba20e834d732918f15a7e8537f014d2f3e3"},{"mnemonic":"pass avocado year kick ticket chair pelican finish lamp eight latin hero","master":"5f0d43392033f39e4488d6d9ecf9cfc7cf358fd718c1534c30c67aac21ec94fe","seed":"577d6f62d28192b753fd00bfd3f5af506d7b9d1608eb31cad9f8b08019011dbd20aec03ad7ee731f74811ad060249113b9d2a4aaec0f9d3317a4e72745876822","priv":"5600cbd7c571ddf6d0493f88ea45ac92e33fca9e6644165365cd59f91e68eb21","pub":"036f3194e13694cb0cfa7af94b8a60cd641159d60130fd114cb496f5b828fc2132","addr":"d3b8b4027a87f928323589e9f5a85330a349b821"},{"mnemonic":"deny improve give spin carbon lobster shell lava romance jacket village canal","master":"8b58d86d8564a0f23f0d38e08f50c68ca12a7c55956ca8f34cf790b7260dfb60","seed":"1d5a8348a7c66d8d7f6b5b99f844a7ca23bfbd4558497c1eb72f6679df2e0a03404e99e97f68a3c0a47d56e8fbc0d565f4c1bd0f7da014845038466c7bd8386e","priv":"eacfcd11a571bcdfd73a64a8c0b935fa343b21c0044f8e4d9d2d882c75db1733","pub":"037fda0cd490d64febaebdf19a0236a1f7a1bc6d523d065cdb2626ca122e9d50a1","addr":"9dfc787aebcbfa396a0ac4fe9b1513ceb1cda121"},{"mnemonic":"target tunnel liar bargain bounce lesson silk lake artefact coin coffee degree","master":"86437b39d0a0db7f5b0a27f627146b1ba6ee9c2cfd4fc12663ec3a2fd06d6495","seed":"fe9740cbcde2cc458420431b44c8158a35c172637b748b4051b79dd1ac1d100ba0cc60d4928160ce8eb6cdd5232152f9b90439fa2f4a3aa40f1f884d79f0e520","priv":"5e56256b91d4e255d9a64d5e3fe5fd0cfc2eb558b683f2289d773d09008a41db","pub":"0273026ac3c43ee59dd6d703efc5fac4d31e6b6585e27820bd8d91185dc399cb36","addr":"a0d89229e673a6f6962045c70faffbfefb0764fd"},{"mnemonic":"rail ripple tuition once odor barrel winter antique woman merry nut offer","master":"33ed9b3e5babe3904c48a79769a0d8a8285fcd9b7c1154316429382876726bad","seed":"595dd0a7f36a71e38b37baf88967b9960baacf11b249edf1afa2f2bdcf68a96e867644b712a78173609202b7d8b7cf2a3cc82014ea28bb955ddc46027dd10f7c","priv":"de65d8250e9eba67bcc69a2840187c2ea7c64f44766c1b7ac0b648afa0f297c6","pub":"031a160d7d3b13d9190c2a0a684161bd00d7a3fd6f472368f5cc4bf5ef3f84cede","addr":"a0469ba7da8af387308cea748507999662a7f76e"},{"mnemonic":"mix you afford area also raw water fabric mother industry mystery victory","master":"d458f52e08056473bdc1a73f5ba148da38f58a53be4f7d5d8e5d2974da6474ef","seed":"fcfefea963149047cc195afa589c8a81189eb27bc30d6bdbcadc5a74495400eb12d7fbd3cede6ab7e67c42e308dbcb4f74cf2ba1335b873c8bdbd13ff19dde6c","priv":"d5ef3fde07814e0967f9ec90b44a749a1c2f4bae73f76af2e10a0f73681e58bf","pub":"03388e81cbddfdbad87b95d800bec6e1869bbae59b2098b51e083e97272ef82fe6","addr":"3570a61894c36414a607cc787e0eafa997ed0506"},{"mnemonic":"find fade drip oblige either deputy noodle trial hand clown athlete chapter","master":"1131d43aafe4c9a2314a3c41116a0ccc68080cfcc525fca0acc53d5a2d4c80fe","seed":"207bd6fc9c91ebe2521cb131c261de75c71aa28935feb420a2e9603659826c326e996074bdc78b7075bec54f4268c828ee8a62aafe993cd7cf481665a2303e29","priv":"22ca0a4c09e5d6a96ff37eae29507b62715a643d3ac24389217e35f4bea4d9cb","pub":"02ca3c47a5367b7c9d83057333cd716b44a429d7034bda65761ee1dc503038d520","addr":"64be7f76e0669905f362892b53491230aa4c6834"},{"mnemonic":"anger level recycle lemon material pear robust decide they hammer coyote fade","master":"0efa37efdf167ca18fe15ceace835d75ae94027d7cf4186b4ac7bb5b91d54fcd","seed":"8838fceccf5c30285bfff02ec64ee34d7518c30b9cd722ab8a732d1ced8135fe1919af7e3afab63a55f1551d43d4222f1f62d0349ec185e4d45076b849de8972","priv":"16f41120d317d7387aad821cd0374d715a1ec1049057268b3ee090210a00a6b2","pub":"02b13c5607cfd0675ec1f33f82a09a9cfd88ea6a212a84f9528fba9857d012f5fb","addr":"4cf25877cd8e38cf5a37a9dac81a9222e8cb5461"},{"mnemonic":"fall run bread slight rhythm flock pipe employ fault side kitchen position","master":"89394aaca338752755e33fde878862096328720570957a7c105ddb90599dd87c","seed":"a2fe89e4a22f8ff5dc458ff49870dfdd7be85afb9fdced1165efc1a2bc93ed44e4d0ea1be438f347f8bf7c9812ad6aa31f07c8eb3b5ec7cd40e37540876b12bc","priv":"c0c189d49e3735f5eb9c7007e1e0a841127998d7c462deaba60912a55c9f0de5","pub":"02199a2f84eab6e63c60f7aeaa56b5799c6013df61e51fd2b9e2be56e4d6e5b121","addr":"085ecfb2737f0ffc78f1ce0a15868b24d09fbda1"},{"mnemonic":"judge soccer grace train conduct duty arrest output roast candy total vacuum","master":"a5fe2db0c41ad910231deb8112f6e10998895d48655cd77b142ad9846fe62458","seed":"4ce2ea9a4984030e65ab6eaf3ce543a450881597d8585c79a66d324606c00cdcb2c3cba4fc83160f0426dfc5a89cd27a9c9d05f94e3a04e3bb550bf698076b0f","priv":"b9eceef7003d3258ec2bca498b34d3181b38aa493f8b3b1237588873751539e3","pub":"02bb8de097658d0e711f875089062c135df56e33fe97e2c828da5a5023ba634765","addr":"963bbc3ce38f6bcf2e15a3c300e7eef5cf2b648c"},{"mnemonic":"lumber lawsuit animal member stool claim know frown knock hotel noodle pulse","master":"fee5ba9a343f60a5f0f38b80c3208908e2db6f03c8a37dec5cf55d833e913fad","seed":"e1fbac7d494d3e1def8d193a71872395f24b8d62bc052ef2aa6a09220451ed59b1f74a2bd02ddc0fcc0ab0f4ad65bc17462497c431f2689d6bb9490573ce022d","priv":"8dfa11b3935e4e660e246fa935b438bf9aa9b5efded0e62db64f61cd678e71b3","pub":"036dc946490687b821115c280ff113002a160325f212b2ebde71628ebd27e418eb","addr":"3e6e6935d3d9715f525fc9a43eb1e7465a1178ee"},{"mnemonic":"city drastic advice adult taxi build local olive unknown leisure bounce umbrella","master":"0aecf2bf80c660dc6e9a987d260fd4f38daf6a00979e2e6ff0769907c6cbe893","seed":"f66f4fc74817a4edceed1cbfce8986d1cb9c9f77b23f5b33032616879c452e64b5b598518aad9216ff0b210b38cae0a6d417b7200df3fd7f2c8cac9cde2fb946","priv":"c8bb1e0db0df18c9a4254cac791a309045d9fbe6daee301d431ad9dfbdbfec38","pub":"0376d3fa96698c82b0ca3d704e8754838a80f05d01c6cc99894640da9aad067d47","addr":"9532ab7fb7493cf19a9d2e61a808fba45dea3ca8"},{"mnemonic":"assist obscure army approve salt tourist program raccoon coral economy connect around","master":"27262a815e351c2e583835dbcbb7fce7c5f96d7b8deec45a6325d02b095135f8","seed":"72315d5e5ae5936c29173566fe17da012160290050475356063fc678a8a41530edba5dafdc2404c410c4b5cebe8dfdf5cd0f6fd855d94a08ba7e856c984b7371","priv":"2849c2468ce054e94252fa34a7e704e04042dee4bda5fd82d6b38e17d2451c20","pub":"03a278a4623f9f8d32bc8198c694e961868709bb5f425f6000413e6be33cfab059","addr":"4bb9c78ec04e00e84fd3310d101f3af4949351d0"},{"mnemonic":"limb nerve equip power pyramid nest sure kitchen lady burst pig void","master":"47e667f4fa090bc0f8df1db86c5c7f835d7e43b8151b6ae51ea12b917d4b23c5","seed":"ee38177c8d3f2c0076cc84887f8ec20b9b6a874d67a0eed6dddb889c1c7af30ee9031215b6739d7858a3ec35253f0136217f888c20621b217b8aec2a900bbb1b","priv":"153335c0a20adc5347c99b869b1f1b2a30eebd4e1c71082b8f16a4641c88df14","pub":"02a2f7b5767ee89ba4aed85a5c198b9b7e62118433b61bed2f85c843576428683e","addr":"50c74e9486961c8b0bdf5b2289f5484ebd6554d7"},{"mnemonic":"toast fame primary broccoli valley fit chase critic life absent crucial chest","master":"f4a62f84c5ea1fd074494763e0a541015341f6e96d965b884fee68c0ef5e4f33","seed":"27302ff242190977db86f09e9399621c82a5f953e57dbc3a01a6c38ce8b5da4a61b0e6d5bb79bce239e5fe59f3dd12f62cb634f9347afddd89680b592872d348","priv":"7ebfe174b48e60f3809ee65cae852fbdbdc292fdb934d2dcd101f9f9be11f769","pub":"03b2b6586fe30ab7d00dd7a4da4bdc74c8092284f9d7a3e78eb9f298dc26b3b856","addr":"bfa414a410c1cbe1566a050fccc48c99a9b3c973"},{"mnemonic":"live mistake embrace other bar tell promote derive assist deposit stable chuckle","master":"d8dace20cfcf215f4cee2e55c6b9b8f65225291d629cc8f7e456778cb2f5b5df","seed":"0a5c716e273df360383a4e29cf2e2df63f47012be5f0acfac32d37241bc5580096e1538491b5daa0cb4929807a26b4225afa988057cd195d8180f5beae9a7b35","priv":"15330ed9be835c3ab25357f437b5809dad522ed0c5e1e19dc78ecbace52def0b","pub":"03b6ee1d8c8a1fe25b6982ae76008d65b5a1ee20a3537898d5c3ce528f55544315","addr":"b0a03a30af7c4a79cf777c64a86d66251d0b5b07"},{"mnemonic":"orbit recycle wedding rhythm write come apology plug blur pave job rice","master":"fc498e657b1ba22254ab35dc64173d6f9c790501b8cddd18f1edd625964c8f57","seed":"af14771135c60a6cea8c4790a008ba09c890d826c8606c94c5cc50bc8eb36f06bc8eb374fa18a67d738adab33cd849bf1d8bf744a7b33197055c75e924f8b1e8","priv":"94442c669d73ed4cfce1b2a87c76696f3954ff4fd3a867232c5f878f2fec1737","pub":"03db45a44b5dcd8b34b4a5125e54811b800879a45593af61a28a83180f75817a1e","addr":"20505c7aefd22f78b05bc45cecfae800fa1575bb"},{"mnemonic":"oppose brush collect swim cup age gate forward spirit boat century annual","master":"c156132e600a1d3c359813d2d3fab0cf5ff13d8713569cb3da35ec78a424e193","seed":"8a1ce5772eeba927d2f237acb22b9e86ed2fafc89c18e33d1fa040274d1dbce37bb2e93e1ec8e2dfbd32cb299fc966e43567f11bc0022811e6d43becb43e2e1c","priv":"f2c9a5337186920bd738336ee616ace6f7c21b68e731c8cd84dc023c89198525","pub":"021a7131768f1e6f03b1177153f36815503e411c54a6c33ee6a20281fa8bfbb8c0","addr":"50e772de1a2e1028fc46d8958f96ee5802d477c5"},{"mnemonic":"genre seminar green olive grow close siren sadness farm promote bottom few","master":"ce632e9a0596520a05d8c096928811ded1f9a09b461d2924f9e4ffaeadfed8c2","seed":"dba3b4f2981a61525481c49e34db737274b80b86ebd2eb6cc64b05d8e321f871a97938e56abadb178688373b8c29a7c752d7c53a55d7e26d660ca948c8ea76cf","priv":"14e58e498bf7d472247df7024c6465db0c2f7b390a65dd05028b42576a3d7678","pub":"02ab7825f84bb603bddf4325c2afd8f7497bd1d22b412576e8155f1fb91fb9b777","addr":"a2e64380682dcd5ba6a4a5e7347389da76ab39d1"},{"mnemonic":"radio minute vivid clean cost gadget ritual front tilt other valve now","master":"c1fc2d9a7484bbbf513ce72d4280d4d6f01ee0359c59f29a2910d44bd06b41fc","seed":"8d4a332dca82af94bdc825c3ab49b970c5a2263e8a07e848841392f4274b44cbbc57908d6522369b32a584de1d8fc012f8f7f763421cc309678386f593e2f819","priv":"fdb87e0dd6892d1b7e29e59dd43d7cc5bd7825329e569d5dad839836d551381c","pub":"0274c7216f289b5ace0f684dbd8f9360679909aee0244f5f16b65ae33b1f0d9737","addr":"ed20a72a5800b88c62873ded8f5e31bf0ae08944"},{"mnemonic":"clay verb soccer near actress august like venture goat rug brief scrap","master":"d888a8d4f3c351b37b6bf708f47ffa1f0d56dfa35f039d4c8c6e49531043c4f4","seed":"470399a3fdf3f7f113b6996468b4cd22524b05290e7e91dcedb0f8cb6d2fdd39ded069f3faa72799ed18d0692301a64a214fec0cab41b3bae69d121d06dfb2af","priv":"971aa66792510f25849cdc1a7ccfd7aa8fd82a0f42df4a947ab675fd96db7022","pub":"03f7c82b2ab42b8e221f661ee3eeebe6231f5d98ada0133431715db7302814d448","addr":"2d306db9a75411f5ee640e2778daeeac539b1a52"},{"mnemonic":"rose team vapor oyster embark shell six object rescue village rug retreat","master":"471f619784e65272a58248f67516ec85a69dbff66719eb5bd17948c4e2e27c94","seed":"39dc2669bc21baa81e45013e856e8289b858778d3b5ab601a26115beebacc708236e742bc105fbba968e364745e34a0c9fda0799b79b859c02efab3c3a4c7204","priv":"581e1940af1601b7ffc624a6465519cd6959234d112353d3a6f2ce4ab3c75711","pub":"02ba88784648b8476c55f9cc4be65140c478b835d79fa596abde69038f9b5a2b2f","addr":"bea24bf839a66b47497014c0f29f98bbd506e9c0"},{"mnemonic":"blossom turn knee oblige digital mail phrase fly soldier unaware corn journey","master":"d7f58c53d2b777e2f1162bf97573c03446afc51dc758bfaad0468c0edec615e4","seed":"f13ee4c99a6c39751bc6922c9be96321c7704c36ae6537f13146b4eda938fb8b2900e44e901223b2906db6392617d4e156554da83644731ff6e56b0b3fef24a2","priv":"c4231def1f2510c02388455fd0d5a2ccc80aacf2faefafb3534544f1b75630d6","pub":"02f0e5922755d841b79fb76f0f129ed3d10175ed4c377d02403cbfcc1c9ffd9c64","addr":"8c664b57dfede7168c0bde20acd37674a1922dcd"},{"mnemonic":"crisp joy brain treat actual later nice ensure village bind powder merit","master":"01058624d066cd1e0527da16937d9ad9bee8b7aeb76c279ea53f5c5d7e56f6d8","seed":"389060cdd3a98f5625f373a0a536f70f84cd0cc6a7d5bd8ee20fb94a2aab9652bdf61af9cc532ebcf217fb7d860c30ac1ccef4fa46b0478971653a42a1879811","priv":"7c0389b4564ae01f4c14da09842984f9b9720fca2d09fceb0244623db5cc07fb","pub":"03420010f464371dd52a34cc193d55de94a3ffb3e746c5566bf8a8e6bef686efec","addr":"c9ad4a84c23c753544d4c3972b0c3d2d86ae397f"},{"mnemonic":"three scare horse film rice divert frost gather photo weird nuclear hamster","master":"b5107f515bd7ce629e85b64264b2c9ec80595816d9bd47f04eaa6971dd565d8c","seed":"ee242699f11339f305818f44a171f79b174f45c09f2322f53ddf3094e830fddbf4e418bc3ade62f03164d8435036514791b936ccbf5f405defd33bf68984ca01","priv":"99513bf817cf2726237c70a70cf6bf5e2ffae1494b433e1d77c8b9c59a3e47e0","pub":"02641d322b89339dd17528573b100647bb082e91d7cf24bfc897e90b20f270f791","addr":"d8545d2e2a4ab61af14c04d40fcda9ad39bcaa33"},{"mnemonic":"circle pond sing route tribe grace exile leisure health cluster prevent year","master":"5cdab97cd5aecd22d671964282f6971ba4be01267c90677091d6db6b5adee0c9","seed":"929117b95286a76aa839e45e768b9f5cd23be5bfa73f929ab835df15cc1c96c2c57cad593b7e396296c0223d38c38b03a4ede097bf3b188a11631537dc6223a5","priv":"35fafc87a67c7547f256f7bffc5b19395349e1665e01a89f228f44af8086b118","pub":"03fee2e799ed5232ca3a29238e0140cfbe5f1bc6ed2c1429c0914c4000ad59fb3e","addr":"2bf9cf4c3f34de93078928aa8c6192450a29af02"},{"mnemonic":"rebuild address giggle city tired dice sorry danger onion cry cheap sock","master":"83df9579ad9f629ea3a09976302888929c52527620ec7041fc9d4e36380fa953","seed":"7cd7ab5cd9f450b45515985a2af469765286510461f42d4ee5258608aedb40b7f60365b685a706d0e0d82f775da38f0171bc8be56543113805227c5f9526e7bf","priv":"a1613406d358b4c1db8439a3e69a4d7072dbf78e06c8a8b72c37425761f874ae","pub":"0395d2c96136983d906c50caabd2f61d1c1b19a227549f7bfeea2ee327c5cea276","addr":"b51131cafeb358b0f90101072a0bd70fe5226726"},{"mnemonic":"toward turtle false distance spider plate aim daughter team jar case option","master":"229e0c7738aff8a44fa62ad310f3cb18f6b94610c83faca246c428c26f47ca18","seed":"405cc161455171571df109c3baa2b3ae25a8ab9b3c7affe9b09b32a755ea443ee590f722f9d2f3c39e9e828a2f276f46a6f9b65b024a11c6d9ae76929210ad23","priv":"095f70fb24f7f97994339cf37a6afc4e95f1a421d9b076cd714453ba2dfd29c4","pub":"037fee3b9ddecb153acb32358781fb541283c3a61ce2f25366b199f970a87057e7","addr":"f3e1bdca0ac89c2f4036f07cad45f65ecc94bd61"},{"mnemonic":"mind mirror athlete assume piece surface raccoon struggle inject horn body engage","master":"75156c7a3676b6a756cf4eba160d44d94ecbc6ae06457ca714f4313367e8493b","seed":"c754f1684d8944deeaec89ae5977458ea9843b4bfa0997a7c1213633c6203a154b65f2109e4e2746735c85ffb7dce803bcc57b38cd617b43345c2b486ce44ebd","priv":"c03717d4cef8ebc0e4bd6d78ab5ff3d5975da9919fab3cef3249d329d488fe28","pub":"02638868a04c039201022036284a8916939b6432f4a469c132748955f7e6dc468d","addr":"d7906686be6e6b9e1dc032c9e89d30ca8768c698"},{"mnemonic":"armed lottery garment beef manage knee subway market enough end clever edge","master":"08432ba7a4152d14119d22b52f8913f2e221237f125f58e4df5e5c87da81a74e","seed":"7660fa9d42eaee32aaba664593f1271cb60e092a5758bf3353c03a448360ccd74ef45b01612aae2637aeb86f8d9380bb8ce6b9eef5e0739c85736cc50b612d51","priv":"4f9e5ef095a07a939d5f3296b211fd938ca90d21f52640da2272ab812947127f","pub":"034c3bdf7e1bea7d629e2b1f82371d1d7d04bbce016317bff603a0cc2682544a93","addr":"8ecb13c1076cb132990cbd0efeb072e58fd3d1bc"},{"mnemonic":"city chest trip critic advance sign push patient choose pride lucky cage","master":"5069d7379310d03e01f740871ddb8043daa108e523ee5c2aaca252d079b9b99e","seed":"5459d94456d6fec414efec5630285ec7e05293d92c8290a07b1070b5a7fecb8f7356beffc82790b50da2fbfb28921bbdc64ac0d94e1d565f6ead799c1c04e7e6","priv":"6d334f7f362d2dfb4e7af20f7fe30887e3c91186954a8252078f215ca22e4b07","pub":"03fdb94e64855c4c973fee4157d3949bb9b840ead95906a672c1d08390e3be4883","addr":"bfa8840559e159b5cf6e7831c4696238202171cc"},{"mnemonic":"fuel derive exit magnet shallow salute clown prevent inmate hurry conduct series","master":"0c721f303dc4ba98877e76b3c36d82a82639ff6c02318dfd4547943b39d7fb36","seed":"877d16863699cca3246681de6e1b9f2c4b59ad600341c0ce16dd8c95c1f5cb1964bdafccff0af5d29eddaf9bb564552499234eee8e493549d0f6d2cea0a71695","priv":"b4f009ace3092938c51c2d7557b52900941c6dc437306883a89a51e29af04900","pub":"024cc003cb7be1724456fd703edfb7e339285883088e97247d83cc64e8283f796f","addr":"b2bfd256adb5be91b637eefc2c20efed75659f8e"},{"mnemonic":"soul junior garlic chunk eyebrow betray heart sunny average coast help champion","master":"7c420ff72c69dbc9006c4969beb830d7fbbac17dfedebbb7d7852430f17490b3","seed":"34ec95dad85e66b55bd9bde227e68b86298e4bb51b3b3514ff774298ade39fd769eea0f2433392a09578da35738cdaa31a0d71cf043204083006cbccb9ada2a5","priv":"719c2fbf2db0df066f36fb31275ab75a3905c52b04335f97f778c540e103a7fe","pub":"022333046c912253a37832140cd42243733ccded5a7a13f20ffd6e59cdf19443f2","addr":"048677f2e035a21eb91d40555f0c9ff53f335660"},{"mnemonic":"private outer service journey dry exact thank ability wheel destroy blade scout","master":"6d87dbea0c85b9ce5e67831bfab7e5118ea85d7e9103140842ed4b7aa46c2b87","seed":"d0fdad93d2b727475db3da1a5cee5a4dd8c9a0794a6a73b5c3d6078541df7e7717aaf0053edf1d4a670dbddb96a6085bee0b7bf0c4428f09bae98a46c93e139c","priv":"aea666b18ff888190a0119fd38604a711a66d235bdfd514378e6a52efe4067da","pub":"0275d06c981e89fc560ea25164baf2c238b6fe33bb65e78952e6912b9cf991a65b","addr":"32aa41676d1ab5e54575d0d13f673c352f0f99b6"},{"mnemonic":"diesel suspect urban fatal total motion other opera taste shock prize lesson","master":"6760aa56bdd6d9a29615c425d934b788ccd70b80066c85caa2091e3861a5508b","seed":"bb3df25ef6c4ac87b93991710c0b927a24c47bfe467cc3d057ae3cc5867bff989d6e8df8b790b52661ad3d310730dc55ba8fdbbda118d3fdf75a21750f2f8089","priv":"399d6d98eb0cef3674ce7d155b426638ea4679fddc624cc582e13b7f2927a8f8","pub":"03e6082570bd65f91edcdac9564f3d71efe75a4bbdedc379774ca9879fc8a57cf6","addr":"d3a69b264f967565d19aa3be68b6a20ed054da40"},{"mnemonic":"tide rain throw pink treat sphere soft season network good left potato","master":"a2f3cb3671d233a245fbbdc8b769089035cf13a9312a78826972dbb99eb4e619","seed":"0fa23be9b8c9a11dd03a5d6c1677ef78526ff2ce3e12de5195d2e1b40f2df6b90515bbb6eacfffc2e9b82ff66426fa1e3a86b51e98a733d054c4b58b6b5e7025","priv":"34fd376b792658501ede9f9f2726a94f8763151e20a3325d05eaa7e6b92b19a6","pub":"02f2f3b3ca1654334091af786f28f9b64dd599f188902cc24f2890edb62f0f7527","addr":"1f06acf38751a45fc0734766e3c794547a31434b"},{"mnemonic":"hold forest select elevator skull warm crater help sing liquid foil burden","master":"20bdfc70225db1ad0d9a1f53a1558efe992ceb7001f181a0ab5a0394851dc81c","seed":"8839e0268e51734574d033b2ac42d3de449819e0e6a916b9f59380d15be767f5a491076bb4e9c2c586cf92d07812f7338400962d28a06c2218a3674bffaf586a","priv":"8c1f88886e7ee663a9df9ad3b31871cb864bcc1ecac7e19bff14344423581796","pub":"022dc59925b511f1420f897805f13b684d9e91731c88672121dc59308ab4fd7c12","addr":"3911febb503ec0cfe4bb41bb6e9fd1924a027aca"},{"mnemonic":"power orange shoulder stove sunset during jungle buffalo funny enough immune skill","master":"51384a8d4d886c1f0a7b4b1938d798c0463e44fb0ef05f6392d5f0c3c0c1813d","seed":"ef0f86555bc2d06fb8b676196c8d046aecc752a61a95d4783f8e90cd0a3117e08c11171214fa63a8e86a8280ef98cf4cf780eb384eb78ece725b94a261770268","priv":"e644ce7c5f3541acf3649d8a44423d277301e519147f50be97dadd4ae1d629ee","pub":"0312f8f9435994bd6156ef158a80b721e73dbca17671aaac7f7d67cc847bda7ed4","addr":"82167c6542716e9c1a072228a6159af1b02f8893"},{"mnemonic":"black evoke reform inmate similar wall machine deliver gift photo axis mean","master":"2cd652f239c8ee231e516843dc9bfed097ad33378563e2cc50e07a48cf0bd28c","seed":"02da5a82f2f4a6ac1a4a962d5450899e949e702f96eee80f364faa7751b50a55b438c6e4f4fac1b6e495b06fc55f63ab9ec1d288df3d62f6644bd59dacbcea1f","priv":"f6566def1b32c210a1369b859cd8815efcf5565a2e1334afb0663115acbb5724","pub":"033055d70eb1aaa92d91e04edae35bdcf2dcaf4bd80cb2f798f2be9bfb6a6fcf3e","addr":"dbed2e50e81e7b093ccadb9cb1ec9ad86837ba09"},{"mnemonic":"sea snow child feature gadget oven this lake post entry essay alpha","master":"0ca6e7a0b4fa4522ed7b8ae0834949bf8a35f7fcfe099c237513d7ba59d82562","seed":"94a9ae63647a2b63121725f961c7e56c7c6b6985a169c43ae41434c3155ccc8244ce10d6376fcc473d7663189d51049b035e5e232834b470a404f24e286e88b0","priv":"9b029add6a255727c4cb80b868975e95086487b3a463cb35870a74414fc6c14c","pub":"028a44cde34153397149442c970964c1647e214fc15dcb345c4025cdc26cdbd3a8","addr":"a23cebeb59b458c97abd67a3e32387bbc56545e3"},{"mnemonic":"couple regret airport shy symptom shrug mom sail insane culture detail shrug","master":"37711c29531e793d6a5e2b4931b3aa0240ccef541c9b8408c29bc5b68eded038","seed":"9c054a9047e66665412432f402f94e0dc5f87d7cbc1a32f6486cd928bc2a9a0aa898ab91fd3aabb962af985da396eae7a0d00fd739650bffaf070c9af44721ad","priv":"b9f1026e086eeeac648193494b398770b7226d46221cfd7281e5519e81fd8fa5","pub":"02de158ec50efb1b8567d63331fd7aa66aaa59ff26a621a59a52ad9341330b028f","addr":"aafa96d9be89b09030494856cf6275b8e9eb387e"},{"mnemonic":"mechanic sadness easy credit eyebrow sample health pyramid bargain actor power glad","master":"68c40248a8f7049062f18ada91f3f2166b37865895d4fdc8000268dfe263ef9f","seed":"d28287812cbbf2cb8509eff491ac456ed199dd2dfc8cd3c93e05b0541c154850f09f686a573994d41f163884708db205b37afb02752a8f0b2b9785c6eff504b3","priv":"250d326d0c232bdf26b6eb8e349ae5b49e30b0507fcce0be1be3bce55b0f7645","pub":"02d5713f20005136dcf9d8653dbfd75bedca3f42b2682ec9918b92394f2b685b13","addr":"409ab6606687cf83eb6c2388d6ebe296b4799967"},{"mnemonic":"mercy spell despair dirt board clerk about symbol supply provide rigid evoke","master":"37a0b9c11386b995b71a8c8a5e150ff76d238779b8148a2137e5d4666fe9fba2","seed":"9e3ec2ab97061086be1e02cae7a0a30493c019247411a7e7271c0c5f7f40bf027ad3230a1f113580365c82549ae23c024ad85a8601a30b6f78276744ec803a35","priv":"0385392be6a34bae1ff02570948ce1217fd11700ac753bbbbd47a1ece41ba38b","pub":"03218315e18c8a5128f74186223d32ece9c3987a0427db95ef51eee9acda922c03","addr":"725139ec60574c941c133ad2e09e793c1cd32cf3"},{"mnemonic":"emotion exile anchor charge silent nose family tube view lottery neither razor","master":"d8e841a6199f937fa9bab3c3905db51899d456f9caa5d85d9d930f9981ba6ddf","seed":"c8610e5fa0b9d9a83610c4458129802434d7045fe44917de29366c6d900f123e5414fda889e21284405c4c64fe745a36966ee86fd6f61d1dce6f809e0e63624f","priv":"b567d59ec087a81214968756017868e483e62326bd7239fddb27586745412349","pub":"03182c009fea42d30f31f24b6a5d251b70e72c1262d22f25418653cee5a226bd15","addr":"9f5d2ece004dd9ddd79b164c4b51361eceaf077b"},{"mnemonic":"orphan attract pair execute fresh interest artefact shaft sail advice vanish moment","master":"b58a705076e0c5aeade31776d78d319529bb76ce748aacb266dc910595dcddf3","seed":"a156c3c4b6241c4e99bb63dc221b13fa77219f2419f7c33a7a7752b5dd89d5be2178b6c2de2225292bdd0bbcf3b90bbccceb93ea65deacc866a5a3da4944ab1d","priv":"857564d0b2bfda18ecf561ea17dccd6d1bec2100e79b6adc8a74997b55f53126","pub":"03eddc58dac77538639745d167c174b907a448072ea4ef9b14563217716fb606fa","addr":"b3a656fa40d9a7f6471cf6dbb00fa0e2687df914"},{"mnemonic":"guilt awesome champion wasp execute purchase better mirror such prevent stay actual","master":"ffd1b0b635383f57d0086c1e6e4925d82a9cb9b310d0757afa8d941a13a1d61f","seed":"c36560913942649932b4aa8027520c46155135b50d66b0c6b33a7f63272b3d531946fe3aa0efd22c6e91d5e19cbed5183ac2bc7a18c219ee3e47dfaf35ef15dc","priv":"d5d35667bd3f54b40858f3cb4c6f09feb889f11d6da386935fe8b42e3a37f58d","pub":"039cffe0fa0a30d9ab9b1ca354ace89b5c9cd21d2653eb5a7a8c5b66c03912bc8e","addr":"1f2543b17460c4f7c2d53369fce6383771c0f7d8"},{"mnemonic":"pyramid soul ahead tongue observe void whale sense keen feed today abuse","master":"272cd80e4846e16f0449c68c8ed4c78071613b57660b85206f716203014c9231","seed":"2f342928932ee8e588bb75ca7cdcd7cc61f32eb317401047cca5b4133e963776ad86474999f9013be1f6cd947cfd9cf4add3be93e686d467223864851ea71751","priv":"d52cf3cfd4e6b6310bf47db08d27ebf0109582f78419d369c4c5da596f22bdb6","pub":"038f855f837abe423fcea3ce81efeccc49da313c71630cb08089956afb73e96e95","addr":"c888d0e5e1840b29f6d85a64cd9704221fd3046c"},{"mnemonic":"speak mother wage grid column movie pluck deal bulb stem okay own","master":"60b4e8cd422ac64986d88f4412e0c694d77d09d4469b06bbc8b4d9146ca5e412","seed":"ecddae7245f9ceb3b2eb324a78421ba99d3b39819bf394be90309cea21d6275ee32a068aef8078fe3514cde61a69e31ebe091669392b5c8a442451b895591ad8","priv":"4695ad7f839e5997df9747bb6d4ceffbad85f6bb26d01c328e6c6e8f6e68800d","pub":"038e3e274ef62db04582bdf01f4c443fdc5b590da7d2c0f5f1d1d55abb0752d440","addr":"359c60c1bfe3a11711423effbacf7d857d39437f"},{"mnemonic":"unveil toast planet basic limit bubble lawsuit grunt lonely favorite inherit write","master":"32bd1431071e17e039819b0f3d9d959c5b88813cf49ca69c90fd547a4fedccea","seed":"d036fc1412c23cd5406860b96814ad9f54359e103834f5d9d1e5f79d52b2e0a8432c4ae705d2fffa9d87d4946dbed2c847a4589542f8051cf6e37689617964c3","priv":"93fac9e5a9e35c2138568864525be7a43492e11f715c097879033aa4019cd723","pub":"03b0e30e8c5bedab8f9ff703df5c9440855b96594e19a367f3c1da13aff1f606ce","addr":"0e70b83293cbdc8b5e3cbec03cf2d0602f221bb8"},{"mnemonic":"cereal forum again rail lawsuit mandate above vacuum hour tiny rain mad","master":"1bfbb49078074dcdc191bb798d3c02462d736f786d7e91461000fd644aff7cf8","seed":"2aef95fae13809c1689d4b5a6598ad4e642ec6373dc6a10b6f348718360e3397eee9a2ea24acd344260d4002b2e7857e71daa1e7111f943ba036d4d94deaa339","priv":"75d0ffb17edca54a389371ddfbeed3a930ff3ca88ef166a67101b9091636d7a8","pub":"03c1ab2904a55bcbd56d1f1b2840a4b09f665576e980cdf2fcd45db21c007fdf82","addr":"cedaa1fd49e697c467d8ce47a2d67ffbfcfe1d56"},{"mnemonic":"infant glad torch shoulder benefit pledge social indicate present deer glare hope","master":"fa580a50eb13d1df4efe98cd3e86a1927e4e9b8262a279f2e782d298641a7378","seed":"a3e088fc36097fcbb0286a2103e2b8f8c1b3e0f6d8521c82c2c93fe06a8c1b97748143b02d9196f095ec1be5044aa0d89b39bb131c4488858e549879cca4c8f4","priv":"61c933db24e871ee66fcce148c2ecc3fc85def76b1e6f8ea784001941deffca3","pub":"021922866e34e3d7e28c1f5778c70e7b8742c2c9151ca5559039949f32ff0854b2","addr":"e550531be6f31c18a90bc6add24c02895e444794"},{"mnemonic":"laptop vapor rotate chief frame trap duck satoshi obvious pen oblige bubble","master":"239c6fca9e52e705ba0d2d9190a08748408d3a53ba0d19bd51fef426b56e1ac1","seed":"15a573343b11562370b53ccc9f11be74e183b1a341ee922cdfeb8c84a4dc914d23ed6a7f58ab451cf57d5f610c8ed9f16e2072a71ab8edd82414fb9d24cacc3c","priv":"ac37a60d2ff77750624fdc0d41531ebc6dfc1786f681dcdb436ec920f91a34b0","pub":"025dd6a2cf772db80dbbe6957ad1606603cd5b065177ec93263ab0194505c420eb","addr":"5693d8a59358cd00f21dd8786248538bdfd0edc6"},{"mnemonic":"walk raven camp kingdom defy nice hero copper velvet lock era south","master":"b4292f1b198481120f507ff13017c2756208cbc9652c555807472d872a58b9bb","seed":"6d2f085ea9e128fb3652d78d9e14e38eaf793ef1aa8b455798556482a5c2f3dd43933c26ab9fc38fc4943c82cb85c8c5b027534f005d45b740b31f63c683b87a","priv":"ad8fc7544b1b79028e05e96c9889004d9c5cdeddbcdaf05bead09b2075dadbba","pub":"0285d2a820245c70d9f3cfc930d6c4e467585f3c831cb7bcd46f58d637bc827729","addr":"4c7c3cb79dffd93e81882b609f7424431e55d4a3"},{"mnemonic":"impulse certain olympic advice entry initial bean glimpse begin flip cotton mechanic","master":"b092aa1b7fa22bacb8915bfbee4018484dfa4313c5779142e71e6d80e334dac1","seed":"9dbec0ace8784d915fe1bd3cc88b7c774fdc4791ace38856dc0500927aa02975feac3d82cb9771bd69d5b2f8c11c663e887b27292e3ecb36ff33ef5b3b3a804f","priv":"19497a3611ce0f1fb43aa5c55325099b6fb18811c99ec1d38c743c3338ddf5a4","pub":"03ca79e260e5a06bd3717cd969610c06580f65aa158e770eb418653a95a52cd0f4","addr":"f83b4129ec37643eee9f5d262cfe80087c5c5841"},{"mnemonic":"trip brass eyebrow plug sibling couple tuition tired warm spoon october finish","master":"ba1d19fb67d08931e7fc46b55c02651d374c7edc6df6a3b89fdf9e28670de4ef","seed":"736522d275c19137d354d8899542497b76b304e33c348e8f446970cd77aea927e2fc1d493b5f8dcdbe48c0a535722ba4223ef52925a57db21065f92779ba66a8","priv":"5d7ece46202706ddb8db591c4e125403f9aadb33c96f259105a0648ca1e2acfa","pub":"03791637ee34fa2e798c0cd98ea21cd17a4c02c429f05a9df5197b852fb643216a","addr":"e46722ace3466a38d3b5f66d5f94786d4576390a"},{"mnemonic":"suspect brick cloud coin tomato guilt inflict type lesson panel right still","master":"56a2d9f123ae22001633fda68b5b6f1fce4959ef19dac2c2a88ca5f774cb7d71","seed":"bc3b42627e5dfb76f1808f75e8cce883afff811821dd615262fa62c98c00cc0e0fd97b213f3b386ac00dc38de399e6e56b9216e34e4deabd15d23d70ff94cfd5","priv":"0d2c63fef727f339b9563c1f8bda5edc3755029ed45010e99bff74bf805f187e","pub":"02742f8b32ff1cf54225fd667425daf286705a0852e554e3294d057f5b41bb737d","addr":"4ac1a9bbd5d9d9597587bb809db80b69485d7e47"},{"mnemonic":"innocent interest smoke fortune smoke nothing clutch dust ladder clutch property glad","master":"ef88eb840ba3b3a072860d726b16c5309b9959381db68debc03d9516a7a7205f","seed":"33a6441e74f21794565c5e219b98416a17316a7b9335f8a0f5a5ae45608b315539c9938740266b663f8410e773dbf361f67550e185c0d42fdd4b406fec4cecea","priv":"5360d32f6dad727cc98c0c1b0dea7bf59f89aad2e5127050294adb9d7b116788","pub":"02bb5f40466fe161d106ccbae569709217ce1da9764078d27d3c8375752d7d1f87","addr":"fbdf59b3297e67600290d6bbffbbd39fb6f460a6"},{"mnemonic":"employ ladder boil blossom level pitch vapor gain permit manage coin supply","master":"c550d7336d80488c81ee8f2a8c3fde04784b8f3079d63add93b1b8800f796024","seed":"a80406c58b6958a30c0bb15f3b6f9efcf7e0c8cd0f01114a72f9c446130801c539028c964321ed9ba511831aeb00dba1be82eb28977319f727de1a9f44b1a7a5","priv":"9233c90da7ccf973268310430efa073e4e070cc5b9dfa29612bcc9541ca3417a","pub":"03c070cf8379e2461ab6158755f45d881ab8fa7de1501bcf0530a871abcef79947","addr":"fcb4e5a3f2c568e0d513d1ad97c7b806a96debce"},{"mnemonic":"winter absorb stamp enroll brush paper spawn slide salad special front update","master":"ee7f947acde43c8fc5761af3ca28fd0e87d0883043ea4401f0d692ea818d5573","seed":"0f1b5f166616c83c129d6b2e0d1cf706d46fb56e60698beb77f9eb105bc0726fa7159a4a492b6de462517d692bf26a310528379ce47b4325879772f46ea0d82b","priv":"31f98cc2cdb0cc6d88d91f21960136650d3e7bca690a569edf2ddd6095026e38","pub":"039ad4a48de652c30e015c424c2ef3083f234e5df78791f112eaaab2f74deb71d8","addr":"68306083576ce37fb1bc653ef33e46ade3af0c7d"},{"mnemonic":"focus usual earn deputy execute climb broom save robust coral piece shell","master":"148c7f123552e1be3f696b2f8b0df4885de067d43f9c1e5c671ae6a3ba4dd361","seed":"a4f311017ce37d0f1199253671b0f615ebb09f92648cd33590c2292d4bbe1eb45d6f1a94e71e1438c5cc25974efb3b8ccd03272ea0218f171b01c7fde17adefe","priv":"587f36966f566888d5684aa983d86c124b4657ae02e7d540939c5265ca50ae59","pub":"03cc82a5871dbe05fc52fa3308bbde84a7744780a4c6344910989437b37b59a0c5","addr":"6fcc01f30a9e9733ae95a049ff8b3ae0ea8c97c0"},{"mnemonic":"twin over wire boy dragon drift erode human shy minor panther library","master":"1488ced839d3116ec99c8d4fef9208224ce28d270e4d3242999e8c3d1bcc1719","seed":"099d13da6ce761e666e6df0199a79e95e83d0c911279aebf8037196af6c7070dd08867dea0da8d9148dde2d14ac55864a7dfd09464282d93037aeda70520d664","priv":"1c2871733b9b2fc6224400612807d75387c37b87b925caae6486b777b0dc1e53","pub":"03496d39cdb3d666703b041d5bbb69482537addb552335c7f26d29e09d5ab8500d","addr":"7b89136f5fa6320f53c25a260b4b75eb5bee5774"},{"mnemonic":"potato lecture exit color target shell more push day catch entry erode","master":"a44668b008915d6eb656347398a007187c18cfe766ea167a89e855a77b9b9c37","seed":"815db5e7fd253567cffc54d938a3fd307968b45e95407617c55201d661f2ed581e92f86a1391154e6421bcf04487da1d3c098382a3587e8c5679704407812fab","priv":"de5ca4846103dca9d947e7867ed764c9094d40ce189cd2366befcb557325616f","pub":"0342ebbb943a1f8100441035ea11cf76c17dde7b7298d160ed56e3dc8fcdc7a8a6","addr":"68f2cf5a8b290409689d5e08f99cf1b882582e06"},{"mnemonic":"grit flavor pass apart swallow quick payment view weasel decline travel hat","master":"3a2d8a4e041357a246be12beaade6b6c36fdab6dfbcae0f8230106a09c5157ab","seed":"a69ea95da4c681f004cd5fa6d357c39e50594b66c73a42a93672c13d6dfea0ff0d741bc1b406851c36680895a8137086f6de132d2aaa47af5d4872fe08818171","priv":"502b2d14765f2f80f6ee0c10b98333e498dc7d33a46424555f8429488d57de1f","pub":"02aea2e315932b900ac7e31d5b6b82e9966e45b098dfec8990e2efbf4457e581b1","addr":"c6f8426ba017b6ac4fd45a95341e760f158f0e41"},{"mnemonic":"machine insane tomorrow island assault follow verify spatial pizza major cannon inquiry","master":"be46461a96c733b1add1465d664d74b8e1a28fc1bf25746b9e9d44ddef81ac4d","seed":"2a5d713bf4b71dcb40d0526767f8466c87f04ff5b2fe38ac17d5a7418f099b25761917cddec77d369471bc22a1f26d2d7f6fcfb00b3dbb28f08279ee0ac85f1a","priv":"097be27be2a0c6960b436acd651792cff207d877695acebd02c088e6f3617b9e","pub":"029cde9790e6e1b55d54aacbfc6d13f09fd6b5b04976d0ba5e01cf25da0a2c3976","addr":"06ffc6a5742544cb3a66bf443ec0d8894e5822d1"},{"mnemonic":"plate grid latin above champion demise idea urban raw exotic day diet","master":"9daa2224bd8c15a22941090eac1262e88dd2faeb708ecc00f404c88723bf617b","seed":"e07adaff2724a1af34ea6f3ef3e583086fa835ca126f731875f97b366322aafaa8d39b72a22dbe70bce68d8539f1ac109e3af03db42317f3807e91c35748438b","priv":"423d528c82af34cddc13f8873534984302e072e0aabc9f29b10c70335bd72a3b","pub":"03241547e0145dfbac8bbd5daca05314e2fddcc22aadaa8b49952e461fccce7d17","addr":"2c1ea451fe2233aa3d2120f2b836d11cba72905e"},{"mnemonic":"august quality apology more ring armed hamster raw gentle inhale angle dune","master":"90478d31095fcbbaa751055f7d9fc70a75a8dd34ff825f1b4547103e3367ff9c","seed":"0b944522c472688010098bad62a38a173e0184f64710bfc370e8ffd7a3e2383d630202f52b7ab9b8d41948f534b2bdd0e2664ba76f2e460fc62e73fd1684ff16","priv":"e8228b2ba4ccd5a22bddb4e0a3eaebe6a156ffef061779d264b905c90797826b","pub":"039fe65040d933902f33749f3d43cb924c6df298a969b05760bc4c8fdfb27df444","addr":"b0370814a3a0390cb3874600ff1dd48481725ce0"},{"mnemonic":"argue april pattern jungle favorite shed silk adult file cover benefit neutral","master":"3d5f13e3264550f14ba0edb8b693e7ccb5e74789359a7cf9b7f819654542acd2","seed":"f5fa70f943ebf5b941574820d4b91a1ce706fc5f9849219b7e2e0f9fb410c4bf81494beeb390383e1371817a39f2cc7a9552452d973ea8a15ab42b881c7cbebe","priv":"d0d2a3c92a4b1914064826c1a9205ce8bcb076109ab2524a2818d2ecaab08420","pub":"02040f9ca1b771a4692ff543df77d2fa8fbdd9dc5817789b1ac491a9e0908638e7","addr":"0fa135a93523a80e03603c609953a2f5c7b799ca"},{"mnemonic":"oppose describe defense consider long lesson better kit capable taste feature reward","master":"07ef0cb309577396089c024c1b48dd278d0575aed88e63ac99a44d531fc919f8","seed":"c6ab42822e1fc062f5bfa6e5d7d4049a28be293748858bb2062f4b9a3c20cd30dd02e7e86dbaca2c77bd2e1d837247cad63f8009f9f9410a0365ef7bbe647727","priv":"3b82e67931a96b68e6752ce67c1f971e23c317f8829e2573672edf1d80c68836","pub":"0248ad30caf9f25bf49bafb519ebb3d381ee9c95a6da6502e1cfc88a4a1aea3b37","addr":"17fe8e8d5f6a4a10a2b7f0323cb6ba3bdba9fb93"},{"mnemonic":"blouse patient surface urban stand clarify old pipe where spatial cargo shell","master":"8ea8f4837a7a4a3bc100595fb6dde65f319e8928e61f7da3eea2309169b9dde0","seed":"a7ae3795447825e6d51da632bbba6f8d9f5e141e593d2a78e05f7e0914ed063d629f1f84d3427e7803fd1e317ca0359654bf918724705f523e2a896077c39603","priv":"6fad450edfab3300ffdd65133f2973fd0be3daaf7864e2f357598b63416a01d0","pub":"0211cb5c4316de9b5c08e8764027f9dfa0cae026cd9ff9773dcf524c06f76c08df","addr":"2a51a4f2ba38e779b20b7a4bfba78e8267b6d6a2"},{"mnemonic":"moral penalty ladder step panther divorce bus adult math various speed rural","master":"9641e82d742f458ff81d48d486e38cbb8919a56b2a317d822674ab9e4887ea6d","seed":"8b4c57108bbc2c753be29e0b19ab43b06c7c81e2dda243535f74c08222b23789d3aee754e23ae936df99c8728b04cde066b6e6e512b54fcc1dac28f0b0763074","priv":"043dd7b6ec9ac7f52f1af6f3ff95cd99371c251680c04b3c847da42242d152ce","pub":"025f7dd3fc53ceb3ff87c2bfeaabdeac1d5f1c9b8a897bf4a28ac33b95562e4f79","addr":"9a61f1c15e55009122d52a1c3917a8459fa29238"},{"mnemonic":"pony liberty split enact quick arch mammal velvet cart wait arrest burden","master":"e5fbd41b38aaa3aa643a66aba1c3e8a01709b15f5e1e30d639db03dc87151065","seed":"b6a41b697611cccb9e117b5ce798d47bb37ce1e07341cfe972905a4b66c4b7f8596cd0e6c21e0cdd221be33de8c0a5854c5f8618df36f28d95dd1dfb0f31ea1f","priv":"7e98676864a3649911657e32afe07f6ca86dcac164f4a25e48e33cb147ca4401","pub":"03d61b29c9f5775c6d8fddd6babb2b8e77b65fddcfc14b8c8f6db262285f2d1832","addr":"36c7ac440660d8a8642d669022d621ec1e877680"},{"mnemonic":"summer envelope tumble six bar crazy forget very canvas sign inquiry copy","master":"4c8765857e92661d69dd8f64031d43df4e1043c786f1ad7593d9d6cd7967b9eb","seed":"662aadea06a5198cb230ab83449dff0514b2addd644ff618647ca788cadae3872e19becd5e8de5719e3397783cda6ab0e1496e8a204d3ea8ad524ea93a1b71a2","priv":"a1d833122e4bbf53a23695915b9f398fc8681f72cb68644ac78f5b0ed0b0839a","pub":"03620a954c07b3e3060414ee499f68a904a8afe2f7f3ada8a9db2e039302a1ac0d","addr":"9758f18ede0279601ed2cbabdc5a87e0858c0f01"},{"mnemonic":"robot lift decade april style rapid thought modify tenant wild pottery cool","master":"d43dea8679ea3ac6440623974b253ec2355e97697557c8d62b5a79eefbac54a7","seed":"bc1a90f5410aa2fe22248c19110d3bba802378c5fdf2f3a2eb379c767b3d222fc2ed5d4638876d51fc9b44816c229673694b3f3e8052257f574ea50fd6d7a73b","priv":"fa29d04ce0480d48e6793e227e142330aca85e4e91ee9488396b1b2af13aa160","pub":"0342e19701eeb5ce20b17397457db9105c092d00db7250968ba38a551fb47d3491","addr":"c8ae52e691ce5b507a152f47970456570aa6635e"},{"mnemonic":"invite pool cross silent empty jazz change smooth appear snack cloud lawsuit","master":"0ab641828b6b935da8bfd58e4910c6c3fe8cff9d18548f86bdcf7d501875aab5","seed":"4aca0bb1ece15e686bb9f08a0796eee1830b9d926b0daec50aa9e280ea8eb522f546c1668cc2e2a8beab636eeeb992569a8a8b50e2082b5cb6bdf3195a2e8376","priv":"621bb83e46364ea7bb3a1942dd857213f49077ebfd735ef33095843e11866388","pub":"036a6b24125e8cbb887c0e9806e5feb6555f3ad4042460f1ed85e8a5738a02cd54","addr":"24f1dc90e9321c1faa33d3b2fe82665b402d4e47"},{"mnemonic":"current exit average case novel nuclear recall unaware decrease maple bind acquire","master":"a0a9d482c7bddfd3a8bedc54779098ccb0c54829e7949b52969a76f4a67f1ee4","seed":"35f2474be8f9068d91047c19ea9f1471aef87eb868804c5c205692944bdd1a3ac62ab71e052047961946d9c371da2039e89cfd77aef881d23774f10b24c3e16e","priv":"75684bde10654605f673ba3f704edbc2329997c9b15128b5640b6c4e3ca366af","pub":"038617759898bdb797d411a87d1e55024fde8a1a65c6bc0391a8deda099f6f7fb8","addr":"5785b3440fbc82cef8b1fb97c8f8e62a590b1842"},{"mnemonic":"tone engine property lion used spring enhance need choose grid deliver sister","master":"a0b23f0ebfd072c71a27b964ac5ac2a58fd31fbb1b22c044631fae01b27a425e","seed":"e47ac6612dade3bab1613b016b271eae20948c7934b08d8ba5ad0d14da1417b27512550287853c6c71efbf023b8026d015b063696d562850b991664ea8bc29fe","priv":"bd8279824526377e70a20ab1ea2731f815ac8975ec7ba5dca90d54859143f409","pub":"02dc15779fe271cc197da7035bb0886d2b44026292c137f6cfa8c98624665b383b","addr":"8271679fe371b6ecd1e989a2fb2d7c8d981006f4"},{"mnemonic":"nut solve indicate dolphin crush bike puzzle outer mask bring dutch city","master":"0aa08b93b1e497f4e54d6caaccc4769e921cbf9cc155a5b8877beafc43884c5e","seed":"c7c692ed2dba467ca28d1249f4d39a5c0405a54131245312d05597ef2aa31af3bc6791850693123f18cb1c350fd79c1705e53ffee10a501b82d0cb237d256579","priv":"8f9835b154157f65bed179b6008a352b7ef7d5ce8e21227a22c461294a7410c4","pub":"02da01e33c91da079a39cf256db26b1254e132b894abb9f07bf01118b5b6edf486","addr":"3ca1fa508b336a46f89231ad841a5a14d026f5c6"},{"mnemonic":"inmate snap bullet curtain used blast fatal one join owner route absurd","master":"e4003c062456105b608885d8928bbf183aeef12a48d6e3510dc7f183514a5195","seed":"0402d1974747f32f00e4cc90795f28d6e07a12cba21f31e22e0eb269ad1dc5fc0ad5d6ed1b5d5268dc50e31fe78b7145546de0cc1fe7afec7f5e3831863e21c3","priv":"8e55c05a82e8fcfafdba94b07dc54940cb247eebd1c689b51170f4ed10628a82","pub":"03637d8eb1c87329d9367ac73d1f65e482bd13b072d791f5fc6c08fdf262afdc8c","addr":"23d0d3d1abcb6ec683851d8c21a1ccf5941f18d4"},{"mnemonic":"useful panda fold short about copy hurdle vibrant kingdom draft suit cat","master":"9c99df0058969798ccdfef6b053f61af2b6422e4c691213f1f0a59f4792156b4","seed":"4fa3755fab5aee41e0771c00362701451ac578a9d7f8b139d9fdc043b33fe3566576a7942b904047978bf6a6360181187d9f20bb3475c495985e39ac7fcb8987","priv":"2b65da5f7070729879787dea803a4f50e2df1ae69c39263525bad0b5c994f86c","pub":"03a457cb29097644eb4a8eb1713fdea43d3992b2b88dfd41fbb417845e2d373ce5","addr":"901ed83b7220c552c69c43d661dd468ed94ac9c0"},{"mnemonic":"intact pluck author dish garden frozen speed grit bar narrow across loop","master":"548d4844add02811ea1b60ea7a6c337883e818ead83782a7b5a652ac038310c1","seed":"6b3b40cfaf38ae1ef9938c621264cd373b7e15d196bf9c69ed6efe3f7a7a13900b3c89eb915fbc99457347832ef1b816da26cbdaf8bc48c2b8a634fdd8be2346","priv":"eacaee29cf8bae543732278774ef2244e4da49dac3d88fe11fd7ff50875ffe8d","pub":"03d4d894053c398cb5dacd431a03c673a4f883781d951254fb398a24de018c6110","addr":"0b0840f26af38181ca7f65b7fdc0a3309c28fc4a"},{"mnemonic":"equip energy remove soft alter mammal valid van ordinary motor follow buyer","master":"6110f719e36e14190eb39d4ae66ab2b35bd5c3fd2969145fa3881650556c5384","seed":"74163bcc1522e148a87a95c78072359a600b364eeb558d052b722e5db26b6b317a36219edab7558cfdbdaa6d62c7b078c691fcdf2acc493139a75cbd26ea3bd6","priv":"fea286b716369fef22c1c5ea7da50ad612868d81c50f5efdcbc2891e21328a7a","pub":"0269bb65b5d86befde40cd916410790f9a959c2f3aa3beb5efea2eb358eb5047d1","addr":"9ea73e16006fd30dcdfe1ecbfd2792d5001ff8a6"},{"mnemonic":"limb boring random already marriage team useless polar impact equip rely sunset","master":"20c34a5ae5b9f78bf032d7841469e27002583c800d4aee849860d58213210c39","seed":"848bed01605f3574c16480514ca0cac72c21412fb6ec38833f97fb744e4a975fd06135c4761aad05d73280bf2e1c8297769e5cb69299bcd99e638e4dd542c52a","priv":"59f09a8926377ef066a13627f032d2e700795976230ff2e58806d046af0450c6","pub":"026e3e1e7ff239b39eb4a77477b32d492f99cf1f611558885afc7363f3173a8a28","addr":"61dffa0563d51aabb1e2e585bd444f99cad8d54b"},{"mnemonic":"vapor reflect friend jazz chronic supply awkward tongue venue finger island brass","master":"4dff50c5a87bb1f9d2c0392ee7eee59977bceda605a40c0a111ebb46587a0ab8","seed":"e6f70f78b981254b4e3061270fa96d262d2fccaf8dafd752db2d0fb54f943ca99f49eac07d279b5875432dd7c0450a7bbb776e8852e5a5a82886c65803ec1698","priv":"50273043958c3d7cab07f41dba28080c507f460ff920c6b5b135d1c64dc85469","pub":"03ef40a81e58c08d1bcde1116e9e748eacc38906cec057f2984fd4bc91081492ac","addr":"a8aba313467ada95795757ab9a6661395adbbd33"},{"mnemonic":"top base town abuse shiver symptom green thing vast eagle steak warfare","master":"7ae7456584c905376b6e6f6732b8890baf4d768e82dbde95110effd229dabf9b","seed":"f88b915dc5753ee33855b3adfd292bc56f04e8aaca117023209877ac8cda5df3218c969f1491bd0eceba11ac433016a05a9aa68d6bf3fa59b51a5cbb224c902e","priv":"ea68890e0209f3444eb78727cd3f13dca20c886e8bcd6d31689dbba04d000a30","pub":"02030607d8a2bd18f8af9b67f99db31585b7a879d6f08588aafbd18dd95d1cdb7f","addr":"fa202ccc3db92eb55d45cc79891bd4be395fe4f4"},{"mnemonic":"picnic seek ivory unusual text become room artefact rigid unhappy wall harbor","master":"05638878665f27362c8165adf4b73fcba3cedc983be2f0897a333378f53377cd","seed":"8af253d6d848e9737c8b7807d37558e5a1f09d3a14eaf5794c83c9d4f2021166aab7faacb967eee25714553003cbbe0c0eed9487d4499bca430e709f0b8d219a","priv":"1357da6886941f1c50a19bc3b32a174acccb21a0415dd5a736e5d679fe505f0c","pub":"0333d6d3cbce04e1ac26ffc7c2d4323110a038dc33ce293e95d2d34d11bc1d4efb","addr":"c5aca5f8318f75bc143edda3eb89821e751ce0e7"},{"mnemonic":"faith box profit long entry that alley stereo wife nurse tiny assume","master":"67457c024bde2135b9493124ed03d0f5f30a66530c958693f02e463982362395","seed":"4e22fc62d0a60e2de3ac33de2db8d4a884905ef84071b190f8d43f57040686eb3476fff7a90d19b1bec66d8a2e62532501ac7914585ee5272c352197ee0f0ead","priv":"ba198f97576c66c34196a36a04172bde332ea3c6777ba1af203b68aeae3e23d1","pub":"026aefd0f79219acbe5377bb3578a38f71174dcc9f77fa4d1dde3f3aff35ad2f10","addr":"44c4ffa77990259e15f2b9dc59223c5807c85f54"},{"mnemonic":"brother bar food vessel shine object tape acid opinion brand indicate local","master":"23338d7c853f4e76208d97bf0c47db2dc317cd4501cf00c037e60461eb373353","seed":"e32c6c54ca4fef48630e4dd7927634ff1d21c60fc488e6f1b87755d3e79f4845a3d9f86ddfcf185136150b52dc2f721b04f2d61913d63461956764487fec24bc","priv":"3d410ce752789e05c5e02ba5e95c2765f77208c90cf32f289306204f82d6eb77","pub":"02a795076f39164eacecc80ce04d63e5336edb32d183c06dd81f50e330b6102c11","addr":"b2c8079676ea7d98e10b24d9a09e3d4519d32d74"},{"mnemonic":"broom together virus run require inside output spray day hour cruel witness","master":"3ec636201f4b0a0fc7226003f1744766875a0f8a76e19d69c6c352d86c672cb1","seed":"51bbd8710577f0a2eedac3e341727d975b0e79e2a0777766d43b0cad8b66e302d1dfeda04a6a5ae0683db18955692aebc554c4bcaffb5f9be9f4db079a550f78","priv":"9063c803e2075922b916efc668be57b734212ca8ffeaca221b587912426af4b7","pub":"02b66afbfc48ab4d97a0965e7c96582d2c4cdcae965f8aef72ec98f59b31d5eb7f","addr":"b18bf07d9f82f070da34d8a4e58fd6cc4125d51e"},{"mnemonic":"crash knee output divide essence fiber benefit pig recycle patient strategy already","master":"eb84eae9a804895edbc89020995755aca54a04a4e7b59adb96b2ad0a8b465a7d","seed":"4aab7e57401b6f2dd6502dec26ef36e36d712ce328b5190d73b9055a118c5ead12dd5f18829affbb488a71f18cec672093d58452bba1ec3775739c1169901e67","priv":"0d0ebcf8cd5c075d9b8a2d2e404d44701fc1a5dabfc5b3cb50cae523f3c4c149","pub":"0296e9cf1cfe73a4114a1afae2f05a6a92da168113764431fa57c25afe32258d8e","addr":"8aadd8961827385dfdda784993f8f135a6678a47"},{"mnemonic":"shock assist horror regular voyage gadget cook pipe hair boost release stamp","master":"74b514c25d4fa22f3ac95aae2e58824da6ea181962c52944256a8b80cf86e980","seed":"0a13bbed1d4d3d6128d1eb0bcc0595a4c72701c7e9b79ee6110a104e10e20656dbbaf2993a7a06381e9ac424c3db6b0e98be6d5c2817433660256becf295c70a","priv":"75da3f78a45cfc4e9318d5dcaaf6595002ed037605ca196282dcfc18c5e6eef2","pub":"037187c0d2d573d9c28cebed9214ac37fe20c55ac56ba565fbbf7dd79c4eeea519","addr":"4b79f08bc7daf43ea00b5ad88b7642c31fdbdb17"},{"mnemonic":"monitor artwork plug dream sniff sketch oblige prefer dentist rice degree trip","master":"e8211a763f0b7f2f0085047ec1687f9c37910d27d8580696ae843872a7cae0d9","seed":"0a48851384b8dd7f8c99bfdaee23b143479e589bcced7ea423f6fc5bee68bd5e5c45834e3f2a7a1fcb928781e37e2b3078d683c15dbcbb5032ca31d3425dadf1","priv":"8fc0e10b570558eac1349ca8ef4f47b2f6d3f148a07b94bb2f1040dcb9bf21d2","pub":"0341374d25e701d963aaef0316ca0b4f4c15283f6b8b6932d954cdb7d7af4d7bd7","addr":"9a4cc3bcd48d6998280db5cfe856f7ed85d6b4df"},{"mnemonic":"bus deputy eye shell isolate judge nominee later gift mouse leave square","master":"cf814d6a08c10f4f771f670120b52cb26b6265a5510c5035d5bab583bb7f314d","seed":"9974e3131ea54805d6e9cc124ffedf80b0ebf935cd0908c4d8d7a3b777220155c056f12a7cf3c0c6e58b7adef792215cd471c080e9f11ab6cd4776ad86df9544","priv":"ef857601132267606922590b016b10faf2405f7ff92e3d8dd73ee6843f0b3707","pub":"0317f408e6be956b15a8e9706287e6bed905a008e8d4705b6c9b6e7f478bbc57e6","addr":"70cbfc88189721a264c3d21bd01f2eeee8a245bc"},{"mnemonic":"toe present claw afford agent render direct december model skirt tape soon","master":"88f5eca5b3519ed612f9f7b15ced098565559b85db98cc57979dde0ed818bde9","seed":"d776e445d7541e997584381b5d2eb066b99644275814961daf748a76a84898c21942f23837851d387f0fb6557a0f693d98e4d23214ed34630bd74fa808b36668","priv":"6252b6cd338753e5cb6745e7ce92bb661fdd373e56796722d1766def72b93ab6","pub":"03dc54c14b80e91502c400d6a97562975ae0f967ee0a7cc5618ac0330855ebc688","addr":"afdf4a2de468ee8b2d47de70d52ad9a3239b3f42"},{"mnemonic":"save rich wage off orchard unfold call frown idea jungle boat oxygen","master":"dfff9a17815e298cd92e9a2c5d4ccce14d3df12af9b9c69c4aac7bd297639ec3","seed":"7d25dec6c87f92e685124b901b0ad423ca3554c31db8583d205ec4beb3f42c4a14777ff4fccf830f5641ff4c376c772a8a1273060d58c22b95a51f9daa812a2b","priv":"5e962f6e9e6e9ed76b0f3e3174ec9639996027fb2bec3fb47faed79e66c4fd6a","pub":"020b08249515846a566c2c9616894ddd6c2239c58077ccb2f2e7ec5a8a140ef293","addr":"dbcecdea56d7e5da2a6c96c1f36242e87416f221"},{"mnemonic":"claw ketchup mistake lesson drill crunch unaware captain perfect spell endless manage","master":"bc0c9ff880973352267788cd2e1882dbdf5613a8460414df0e570a099321bcbe","seed":"4b9cc68aaff0b0ad24c531e990f9a9b7d7076dda27cc2f21e8e75bce8f65f2daf1ce6228130bd2c8900fc677313ed4cce1c47eecf24fea0c119f70ad6d3d79c2","priv":"e36db8076b37e0d3785c550e47ccc91462388c8249d160df13391ff06f40a30c","pub":"03895e970001fb0b3566d8abcb1a3df46725daf591e6cf981c1f06a81eb202692d","addr":"6548f7cd7b619dcc8685e59456ecddb223c0bc45"},{"mnemonic":"canvas black between chunk wolf resist again joke club moral fix spawn","master":"374f2b9727601f87f72b70014fc10a38c5fea6cedb36246103e0fde2d356f7ab","seed":"217881b165a67d70c9ed44d81a1100cc829f00a0b3782d8ccd8429806b883eea17f900ed32927a7c8fb8df34d75d5264cb5704208d3dc336444c199b9cd4bd1d","priv":"7e6c83d4d58e7a55e9882e6160238c6fffebeaa89e86dc9785fb1626fd22e8e8","pub":"02795b9337e8dbaebd288d1f0d833d51a4969b0ff995ace05c329fb6d20ad82425","addr":"7618cb9305c15c8ba122949bc298b3d6daa43ef1"},{"mnemonic":"dismiss rubber stadium badge enable exercise collect globe another survey own hope","master":"9da347a5c2a00a44e9bd39e50d80c106a9f885f8c84f5c4d90a0a75dfa5d5508","seed":"7038ff726fcba91488e5fec28d436e7a2e7c462b06747769f79b785aac64164eba1ea5c125e6196b9430139d9e21af8cfe10b51a09577ed510453487cc1f39f2","priv":"86b04f6848114854a1b207b44d9475c216e63a9b051c44bdb7be3eea9d24988d","pub":"02c6e822bfe6255d841eae33f62987f9cbeca84eb8dd1dd02b2daf9c7de7f36371","addr":"bd2a4f087a519a3469cbdaed704221385a07acab"},{"mnemonic":"dignity tired drift feature file salmon vivid wife faith title direct toy","master":"ee03e61a429a846453557f202766fcdd8a3b408c00f3430f7b3a1c9bd88a7d11","seed":"baaeb3a06b419a7a9c49a99e712c11e87a7a4bb34b26700b1d57e95177dc9b6b2d590878111e14f6050e73e5c72239a1562062d1b8e4c8ce9ac158aac282c2ad","priv":"d1dc95b42024dd0c10e8b5f0aed5e5f7c9ad0d56636da91bfa910d6af2124969","pub":"02e1f4ba20c8383bf512073e335400e1a1b1a103cce9450864b9087203dbc0e027","addr":"3de51323a7d40ab752f2b0cda1c17d51cc477369"},{"mnemonic":"legal sword liquid clarify utility depend romance cement trash whisper endless parent","master":"7c61e0c0e85873e8bdf532ec5906b8be283a002114b8dd4b8d0154054b6f40b2","seed":"21ca62d84191c141f6b9890627d6d216d5373ee0819e7c618e4027e70395c2a4ea5702aeee5b844a99eee4fedb85bce72f7d5f57c3d670308e1fa484108c4862","priv":"d6ad713c9dc2cff3e55243729c56485fa34ce8a75c4e011f40762ee000dfdcf4","pub":"026c7a44022f2892f2b2b091bc1488e547b8b52c82c2a780dd6603f40261930d3b","addr":"c6c4dcf4763d9908a46ddde925afd86bbffd4719"},{"mnemonic":"tragic inform salon lamp tree deliver sugar robot torch collect choose nurse","master":"77e88aef57f8be3507ce43c1e47dfb86ce0fded4a6d9a5ed6a2c6711a0a83216","seed":"6670f6815a2865591e6f9ff5c1cb775eed9fd45d53d1ff3f65937425c6bb79403862a398b28c7aca032fdfb14f96b238174cf6353776321631bfe338029ac148","priv":"7907a31525b26f89eace8cc0b988a08f8feff4914dd8f692e24199c4134c6fa9","pub":"031af666b3e8d5da1684fe5d585b8638fe46cff1b1fa01bfde3b2b8e2ef2aa3a58","addr":"792001d0cd191121043ef1434855b85b583ecb09"},{"mnemonic":"common oxygen toward security mixture swim elite issue suit welcome ripple online","master":"f4b85ed364ae42dd7453f56df2731c194a203cc06a8bbf71a2498424d7687631","seed":"9f2217e5ef1a8691aa51e914411a5ef5bf70727cfc7d0a932e1a9f7d298a657db8f2f6eeabe881e8f4f4580a2bf1834ae888cf7b3bd32820448007769b310724","priv":"2f98bb40d987f7e50966b15d2bfc89befc72bb6934aaaa2293dbd9bb33923268","pub":"03b89c51d6a32cdc56e334997a0bbd57deb010778d62024f5012ced0ae184e2464","addr":"2ecc6f88d71e3b1344a7fdbbbbe4fa60b5e539eb"},{"mnemonic":"kite warrior idea engine trouble swing route main like burden divide drive","master":"8317ec95801550a748f5215d6e83cb12424635d5b2f6635a78a4a0311cacc56c","seed":"f406f2ef34c3a4bb64622dfc4496a0b6183f1b7c1f58bd28d3ad863ccaffe171bd6164044ff5e940650a6bef6c290279b41d80336cbd9592c1a3b326314d44f9","priv":"4fc699bea9f32362f74b1cb6e445b1a8f3df81dbf1d5333dabcc84305c355e9a","pub":"02f8b8958f9edce19f8c5a50371dd079ec4b4ad6f6a9746451d4024ccd266829c2","addr":"8fc3062dd0b1063eecaccb75e14faf5b06cbb939"},{"mnemonic":"toast health connect merry resemble slim address pioneer crop orphan keep dune","master":"07ff519f3c3fd08b9de16a26197914867d4e42b67222c9ce863ac6b176bb5909","seed":"5e80b7b4b8b388522fc283784f368f5f7875ff7b412af6c3e526ec1426ad4164e0f4921494ff28a258787beade935d472cbad9f48386c2d7e16f8ca76fce769a","priv":"1158d4b986fa7e05db824694ce3379b63f473161c965a39ca997a8e3f3e7664e","pub":"02a3a7b75a8532df2afd58bd2dd434603c21a0aa4081f8ef9798db401372e32bbd","addr":"24c8f405da27ad41be7b0c62db63f80226fd6b58"},{"mnemonic":"cube shaft clever hard fuel review enhance short nose again banana profit","master":"30f3fe7efee7a0c7eea064bdb63f509182f0dba45780dcbebc5f3374d1b878f1","seed":"93774eb188a6ef898e534aaf67c2ec9aba02f716eabc0d193bd5a035ed8e0eebb2e82fd3ae30bcc24c44d697d46296e5d307060420350a4294f3cb639a48e6e3","priv":"857bcd096012a98022b2d30cb926757f0afa9465058c103b70fc931554f2d360","pub":"02ccbe787178d64d347a4f146facea95d2d01cf353ba04cf7cf7325fba6fad3824","addr":"d3dc220b0c09ac018fffe2cfffb220410af0c0b1"},{"mnemonic":"weather surface use rotate entire foil female carbon once kit seek athlete","master":"68614cd2df975347ef5c7efce4e416821a1f1916ac54ba994f6d69f8f2860576","seed":"478f798d52999208d3c8c0feffa78c6d56406d59800a701c996b8c8a9b193494aef1881e2d1f8aee0a5973b722fc3bb3ba007187a377a64b13a81d0560cb090c","priv":"6671cf2b354b61f6410500e26cbc94afe78392d3feecefbecd6e60c6b1a33a31","pub":"032afb4d170e89e8c89c544ebb404678bc6470d26bf68dfaa1c034edaa85a9bb5d","addr":"2bf3d54106897da2427b1c4c85de761e4546564e"},{"mnemonic":"car rubber ocean miracle vault brave goat eager dolphin various infant receive","master":"fa86484b17c9b62008647587f406f4daa107c6b95e708487778865c76a31e330","seed":"ff824d733d160e50a156021b256e4663f9ebebea1530358d70c205da5e7703d64ca4f3d941043787a68fdade5143d993376b1ddc9fd6037a13520e8cfedb790f","priv":"bad6b6ee0a3aa898466552b2e5df05bccd7d0861e3368f206d8cbfd2ec8e47ad","pub":"02ae2706cc6a96f31da9cd46d544ab142a26ebc6259e5e807065fccc251b26c603","addr":"a6ddada02b29a165a86a8bf4a01e783640e5638f"},{"mnemonic":"segment nothing burden boss obvious find kiss join science dinner clip wrong","master":"64a4c932d3cf62f9bcfe86c3b709ead38ada505e944322b93e14022c3ed26e18","seed":"71966dfe2434f4dcb2cd1bec9090ebd20bbeac2ed54dd8d081a548ce7eb57f1b17cee242581cc893292ff9ae4e5526bf9e11034688299753a6d0bab024ae9126","priv":"44ddd6571ce3582ae17ca9c74ed41811a760c7059dfa7ee88f9ef76960e30328","pub":"0288341429320e6e7cc35df266cf3929e93e843e911f8ae0ebb2634132de1a6f49","addr":"4f32c063b84f9895d4411ece5ba0c9d2e94631ed"},{"mnemonic":"cake volume physical initial phrase false pear poverty bonus steak rebel ketchup","master":"8200ce644e28680726ffeaa7d949e23feef136634b58d504e34cf8b2bbaea439","seed":"8f6577cfd936a64de1c2be553f66b8e5991e2cf30c42181c0f7eb527105c19221268e3268aa243f740733748dea3c0ac16320305c401aef7cd0986f3dc6ed978","priv":"ae37947a92ab4e9ab9b4e24b5f26f710725ecf848f0412b583b8701dce4b7730","pub":"02ba33804bdd8733fb5ae1ce1758ca55c8bd9e15245d646e8f737da2d61758ebf2","addr":"1f3833c0eefb3d46c693b0476470d97abf02a792"},{"mnemonic":"outer meadow velvet fetch claim forget token fee gadget alert post pelican","master":"a991420cafd20f348c847780fcc2128888771f4771cc6ea137099616c617b1e7","seed":"35cd93e8d9c4651799471d4cdf2a2fbf083088b93f1c1bce6ba4394ab6239d05c0bfbf8d7f8976be68042e1c8267dfa7ab3008c967f8d1ae0793190c77077fa0","priv":"e4fb166f29590fb4a5c5484729f038a62aba50fef189f1e3769fa290e1800790","pub":"02e123798016f5eb1f79f633588051def8b59c27fd3973a7f2012db1a8fa508ad1","addr":"45a62d3353b39439d002c307c8789ac70adb69ba"},{"mnemonic":"flip expect rule wrap cousin fade example ugly crowd monitor cattle cable","master":"d5c2521cf1c8f3dbbf955477a993552cf7f6f0ce452bb789806daa0a4dcf192a","seed":"b08a8f7dde39c9680c07ec31ffe80377ea915de328fd38b81525e4f694ef0ceb630e7ccc19bd28a03b7061b194f2b7758f802945a7e556d526f25bf2b4d5fb90","priv":"21a41b9d3ca21569e3b8638188633a7be8e9b54397964a65bfeabc3425d5e4bb","pub":"03cacee92e7116a6012c2b3002fe67d00dd062e937393895703e010d5ada98b4cd","addr":"b3a4f2cdb4cdcb64f1434f3f1e4c20bb8b952116"},{"mnemonic":"alone absent senior wisdom sheriff siege harvest coast van skull want quick","master":"74109213fcb3350c4ebe081116bc7570d00bf49cc7cbb90cf3b09f5d532a3d97","seed":"7d111179778ce63cc39879ae303814acc25afca8eff930d3ddfdc640d7b3d8c1140429a75c6db52db96564aba0bf0c8d9e4cf78fcfd703c1d219c09a70d8569b","priv":"96c3356e90906a9b3c523a3ba61d66ec63d9bad5ccd23edf923e3c5e4c995774","pub":"021736b932aa1eb90716bd8bcf3cffaae73392a37ec114b34628367f8ecf1b35b7","addr":"e8951735e9840492e0589a885968f12b044067de"},{"mnemonic":"fall any bamboo energy ripple flag rich arctic argue decline auto pottery","master":"4b3fa55e01aec7bc6d41a890d8aae2d69e617bab49f8529beb38aaf835d15a69","seed":"aea9842051221d0eced61932fd18a5f3e1ed8479159c40d16e886699a0f923807b91df0763a5d9869fe9a159ae0453f8d651302a186bea4ffc120c2902012d3e","priv":"ca5c56fd1b4e7e7bf623032e17a186e20b22fdd49a4d29d9bed5edff206bf26f","pub":"03a8fd0ffee636d66a64cdcc6032214efd1c069491085053808d03c1ae83b9fe96","addr":"ced9d32eea230544e0f8095b39b0a4e18b59937f"},{"mnemonic":"over exhibit wait carpet pencil record post duck gossip vocal all wife","master":"6fbad4c20428a892a365ee50dc66f8eca7773dbc5ecc34f85619fbf1a73822b7","seed":"f998a57ed4eab4d8425d4a71bb1fa451d7a79c8dcad33e18f90d6a4506f93b2adffbf3eb887adda7669c0108e444548a3566306264a76dd4b0955af27cb9dfda","priv":"bdfaebff9d0fc673539d8be5e59907647d0050a9241dcc4aa24c5c26eda0fa60","pub":"02d32a22a05926844a6b0f2f677520bda4c54e6b2c9269ac91127b626159a9dde9","addr":"60862548d4e283f62ff8aeabec3f25891808a439"},{"mnemonic":"spell illness engine habit bike able chimney spoil know nice tunnel weekend","master":"ac366b29da09441f12742ab837cab2a4636e1b50f11680c4e1adb7d337dfd8da","seed":"59e69d46ac9f2a9edd9b1909b1e5ad4b9fd2b401d48e95eb43a0f4f2bec0e6c60bd2a263e58bec77dac6f6ba45db1345cf9d74593c6e0b5ebe3fdc7c5f24014b","priv":"05d077b8eb1163a1fe2e5eb3729ffc7c1327435d4ac48db86c6db5238d5af45a","pub":"0364973fff68be7b91de7858fb35869decac0273ccadd7ccb45b057ad7d7e9baa7","addr":"c59c857a493b2b81957f4769dd9b7b5a934acfc4"},{"mnemonic":"thunder fabric basket stumble file sudden effort congress process essay excuse practice","master":"6c3de9715b71139a3a352a1d0b272aa0152402db4b8429c32654755430623ec5","seed":"eb8d579bad88d416336e6ed882bd8a57474cc5ba30d4a20e426c29a78bcb27255f6a6cb50b6430fcf905111f9b9fe4e3d4920d563887dbba69ec74856ce4b79e","priv":"a38f2fdb79ac8a1d64f613dfb3cad99c9f06554cb05f39b6f60c52eb7ad888d4","pub":"03d548248b4afab15ed5e91699d6e13fc4401d6779ce97b3bbc833c690302d0049","addr":"fd60d97532ce397f4ae9accfa99ac5ed9f5a77d7"},{"mnemonic":"twenty fan benefit benefit life orange crystal matter index drip mobile matter","master":"08a9533038e137f0149a965d12c1c90d7f6846107dd626027164146406c86fc1","seed":"d3f6d9f156c814e0f77fb7e9aba06ac2c9c3ee171b2d0759e2d91fb5d383f862aee8b7dff8c62cf61286d8f7f374ce3aeae7ab36d551f802523dbeb80673e0f3","priv":"08bd659717169756d9d66e79aa2b51d2b539f5c453ac8abadcfce3d29df49e7a","pub":"02e3885a7d4343012cc76314876fe67729e434202a28525bf69ce27a9167a46385","addr":"f3181c18f63bd74c4ddb37a4c32d0985e0af010f"},{"mnemonic":"scissors foil oven finish exercise typical catch dentist lens dolphin flag warfare","master":"9db47325d363c87e509aa52701131ad236317ea04515f4e24ba4f87cf99b2327","seed":"0246e8cd14b6b8f01d35aac9c09f8e526bf9f05393c5e1e77ddec53477275dbef74add79ebeeca7d081e58272f4a1bf1fa8621894a8165dbc681b967d84ed10a","priv":"6e7e4b51346f8d1997d81f63dbb7fc7bf4f022bb3b5ccda9e5d84c4a5c97849c","pub":"029edfb5c989c002795c283f445ef4d673101736c25617500f8fe655e043ab55ed","addr":"2a98038648503b442fd77f4d05a338da2062cc69"},{"mnemonic":"monitor vehicle bench chaos stable cereal acquire shock image purchase sadness hundred","master":"bf5d7680d5ad260a89229451e6ebcf3c45988a83df6740fff9b557eb3afec827","seed":"5bec19e9219360a8de56fa85d593f5330ddb158205d25d00d8a2307f6b420f11916311e104dcadacb638f5434e98efc8551d768586a0d8d9baf2ceb0759ffa98","priv":"470256a6d68f8de27b0aba26684cea4c075f384bcdf8a68bf5418dee37f08dbf","pub":"03a1193ff722ba3b4bf7d257aca5c184fc776540fb139dd9a404d3743d31030971","addr":"5b4796167bc701e5182f16e2119d7e9d491881fb"},{"mnemonic":"never dentist blame parent sell income parent bullet eternal random seven urge","master":"665961de4995f001085ce2f1058422bfe5ba0132cfc5725f0c5c9d827020663c","seed":"79a95f522e50cb551c7fa70d54c0aafa5b794512be4e91de2fe1a2e9c17d76bd55087621a606107f3fb19486f15dffec5947cf16405304914f511dc43844ce97","priv":"88db51c0d63c95730fad0c616e4d4fde5a631dc3d315fc74db688ea1a7ceb5b5","pub":"020ebca88011035818999fdf69ccbf691d93cbb6bda65c68c0f2ca10757d23abe2","addr":"9de8cf2beaffcd389ea6dcd264444aae075a1590"},{"mnemonic":"noble shallow label region age proof remind panda useful session poverty open","master":"a8e1a3cf36520d5ae852890951b03cef3902f9ca168cf53c4ec6289dd802ad8f","seed":"0cf4cdddf1605c5c895c1b81fd523ee83239d42feb4a130105c2d5d1fa371e00cf34030cf02ef51aa53596253e264da2c3ec220b97885202dd73a7b5824b982d","priv":"5ddfdf68cf41919145c9c8624c245ce9d6d8c380f5d0153b6155e92b253b1b22","pub":"037943f2b34206bfcfc1fe236c77f6e844d98cef04671431a12883e23846e8e7a7","addr":"559839fa53e5b7408f3dbd00ae5e80f56042417e"},{"mnemonic":"hope inherit quantum text sadness dizzy glimpse cheap expand legend kiss once","master":"c307e0a3f22db3e59a7b28b931c1ba0daa0a8e8d743660c48b6babb4b9563702","seed":"6fa72118b297f2bcefab29f19ad4b701791f72cad287681e2af3e92595ec6b9f7a15b08771917d1754053d1e74aa1a254fc3d6e27deb78b7b55f35a5154964e0","priv":"1a6b9948bf4b717756a11e43847be38ae87b0f42d718dcfbded3bca1a8852aa8","pub":"02dc42929ebaebe447d089cc702bd8e29457a2619047a1d7c80cc4f2639a82246d","addr":"bdd0fc12beaef99e0ee5b07c9c2f41bd90163bf6"},{"mnemonic":"smile odor upgrade deer mistake bomb friend ability then segment orient nerve","master":"17c87ed5d20e5089408ac7fa68024124053d46bfe32fc04ba06801c45b6e19e7","seed":"f620d852a56ab0eb7d55d271034b767eded17ed740ada7f8330fe6d9affd8d88e44489de06d6d3f7b84b294a847334ea051ca63f0be4742667ccffc79031b5d7","priv":"8f90608bd45f866e9fad2a6a316fed6bb6342815ed79c967c3eb1be727ab8aee","pub":"03b6b746569b0ce4b97c3035634a2b30a519ec23a78402137c7ec395d35c4eedeb","addr":"179277829c7cabca8286a52ce3cb591ab22fc72d"},{"mnemonic":"black ghost quit birth dial helmet custom brain diamond rally local season","master":"8a6f8c836e3e83ba6ed94a9de24e1133d4b04fc436827d810c23ee1ec9406fa4","seed":"6488a47cd4123eddce9bd31a0982eb0ce8208ed5e331081dc18256dc8b5a1718807bfa267ae6a75bf1601b99c784542c3d981a9350f7f268d2666af3bb8e3680","priv":"1e7100a43845319b4bad268d111eb3746f09c9a005e023c45fd1da984d37e49f","pub":"035ed8c0324e4956ef2fd2b5141260cb6dbc0943708b0f83c0bca0e7297a27daa4","addr":"d2d9e9b6ea946a61082fe98d9b0a808f5f0879e7"},{"mnemonic":"advice uncle change position drastic leopard praise rack match toward paper faculty","master":"9583a2771931234cdf27fc8a96d06766d4c76b4bd25247596639dd21da4c95f2","seed":"8fa5760f5f2d36734e05cedd78260e9ec7f837bf5b7edeeaa8f4f3ecab9a1f82ca557fa8d75d7d779e47a29eb7c974264d98d12fe7af6a22a87a70bf0031cecf","priv":"3a69d90701054f78204f1d3c959f128dbfaecf4ff0cf6c29fe5ada13c96186eb","pub":"038241211180ec347d2459f2c22c01b50fcafd8ec1ebb51b4ba648fe291bd71104","addr":"f9c6730eeb7a00027b3deb720d6c541bc6b0aa89"},{"mnemonic":"carry enter invite orphan file grain pact glance ahead grace action mistake","master":"b6b8bb3d43f27c84f1e3fb1ea462c9a88d8544b18b22d9b9c13379954a3546bb","seed":"a0078d2fa9187ecae2b8ad3d4121e2567695c1cf26bcd441536ce95a6e04b4feb41c1ceacb86ae9ea26db4eeeefaac7e0477eab711b22d5390be3eb3daaf97b3","priv":"7503c22dd0cad622d4337dbd7e0bea66a2e8b52427cbda01a9c5959ebe8b5a73","pub":"032c577bb5610ae703c54444865932db4edef3b8c84f88c71a25731a85515eb69b","addr":"f268151a05642b378f8738ec00b2e486e60e284e"},{"mnemonic":"taxi betray parent equip margin snack spell agent talk possible portion lunar","master":"5bba6a340254e9803fb2889beb84d4bc63454beaba3f10cb992d5823b23472cd","seed":"a8b970f56b960fb9888f03013542e90b547f7d60aa91218105808e595a561ed37c13f259692d3dea5d324d0c4142b30e39cdc2e60697ddb5f52a5459469fb31d","priv":"ae63f7802417743bb8bca410ec64380a407373900e0af51e6acd65ec9d54a0f4","pub":"027410f719925fc55875ccb78092d5e6c31b8543e115ff39bdfb9a26f97fca8859","addr":"da9b8ea1879e13bb49e7b9d179e5b56cf6de6537"},{"mnemonic":"sheriff marble regret shrug shoot tornado coast that obscure sense duck noise","master":"e97a0a9cfbcc28b909f7a5a617af10289965c6901fb06af76a6fada22e41876c","seed":"7a231c5b3b91408a19de9571bcd820f17451562063ad2daa85a1164a952aeaf8d6a3c703909a76aa1e1a2818f8fc36d8dee3c87184b59d6340201402384fb7d3","priv":"d3fbcac181c592367cc527d8f09b54e1a31d3b2c3fb5c1cf4f2ea897c483f5a7","pub":"02b3e3765ad7c3c020c6a166b0113b87279e66a53859ccbb9d214181e2be30ca01","addr":"517212232acd318b376fcface8544506a8f76c18"},{"mnemonic":"connect drum once first trip dust trigger duty situate burger toilet half","master":"073fb31a2785afedaea95e67ac7a3219f2f910aa01b054022a5185c5ac99c35d","seed":"fe3d1ba2740ca127dfc5bc22ab6fdbcc930b957185a0b16b1919e4fd5e637c053b3d356b12152cda6d07f7088f16195319075d0b3533e5082b45f1bbdb7d5a74","priv":"6a19f33e357328d40aeaab5323764bf9e12df8b476100baee9d398a0fdbe3970","pub":"03f639ddf3dae4ec84bdbda49149d2fc3461b2309d043c89eea46bd99762b54a0d","addr":"c8a8a454a5aad713670e936b63c519c843874b3f"},{"mnemonic":"shock later journey twelve any ripple soup climb globe impact poem auto","master":"382a7bfaaf7df9ac5cf8ad1f574bcfdb98e185847a92cc36d272b74a14228259","seed":"aa3bbf8521133a0fba514e54147daa2c6fe294b1af8bee3a6fe46ecd480983d72635520db97bc3631d9bdd55787b07e45d81b052522fb7330f4e0f6aa24fca8c","priv":"dabfdd6c702d104e4c17dfea719ed870c783dfbcc66e8987bccee888658bff76","pub":"02efcce52d6c7ae70900d892e1b24ed5af6012c38c15864f2d15067457a2c55f2d","addr":"fb3af390f0137dcf7d98e2630021061d0fbc9e06"},{"mnemonic":"news book language depend fine fabric idle curious depend plate fold sustain","master":"4c28a9f9d854290f4655fde6a91500dacb684417d8dcaa69435e1ab4b8f04e3c","seed":"2839463d79148eacc1d367f9ed0a2ab8ad939643f439c276bb47f0fbdb4cfe8795001ea2e5c24a6a6da9d35cc6759c37e50ce49f34498ea61a74dd11b14a6421","priv":"d6ec69e742e0146c9811de01cfcb07b3de56594fd4e374722ccf81dd143e9a12","pub":"020f5c54b785c5ca65547b2ba32138a47b8b5b462b304e0cd3ef981b407ee73b87","addr":"2850f467f64992626b23e03d366f34f4e6760807"},{"mnemonic":"equal energy inquiry frequent aim wide exotic tail vintage toy marble spice","master":"0fae6d570fbeb343eaad5bcd272d8554fe27a9cde389685263ca1020e65d4a1c","seed":"62aa467a7dd73249fcad8432d188e64a1d0f1591c66912f906eed133ca0c1e99eb068dbcc8ec37947cc846b1ad4f439821324c61bbb385fd91b2e440d6a86e41","priv":"1a254e7f18b0836975e187a72d0cf1d1b69225067167f44dad6aaed6065e60ea","pub":"02ce2f7840d3f69580538517852dfcb2932285caaab4d11adb98ccf335430fa50c","addr":"53117f2a5d41d6e727db2975c9dabb1d28708d19"},{"mnemonic":"recipe prize resource define enact basic glimpse chalk box prison approve fossil","master":"ee8a619974bcf5cfa95af842bb003ce4f5236abac96eacd51ec8f797bed520a8","seed":"b2d4c119da7c72c24542998b036b2e1c501b0fb990154d1b5abba4c5ab9233c4caf1a427948faa62aa862002f43d115f2e4d715b8c9ea3eb662b2514ea06390e","priv":"0d896d53aeb3f2fbe634ed280225bdbfd10116e18651b3c801a3cbebb0f75ed8","pub":"0320fd7d4c9c548c28d08e587f45836902f14c7380cfc9f8119e0b6e36089369d6","addr":"949025151f752888794030aa47854ff5ee407e09"},{"mnemonic":"hunt carbon lady smile luxury old empower pretty memory gentle public pottery","master":"e9542dc3733e40f7c1e5f540e241dde57a09f76d28e889f69dba48d63f0b6445","seed":"ee0dcfd61e0fe95e1e0428f29c78076f302cc5a55db61c13f9e6d84811bb0d57ba3dc109d4d98fc30c1d2e5b25bab1c646623fbb00e5b3719e4bfc58005fcea9","priv":"e846c35be2eb1e3781e8078d8433a9816d8f8701131e69873290689940617de9","pub":"03aed0cae3a1054d184c820d9dcd5118630febfc450d4972b4963e56de2b1005ca","addr":"af41527e26ef2ed7e1692f2897fc48bbf792c8e6"},{"mnemonic":"captain disagree filter crane chef cousin one cherry able scout tip magic","master":"bf4a3d4839793f7d502e24a4ef4e99bb39fb2aaebc53149eb004ffaca0256af7","seed":"3fbd2b4e5c614a29cfe82ff906e94be976849cfffc6831d67fc47bf2dea68ca06fea30de70ea546adebad96d3fa106950545350e0925425f22a0ba1a0abfa3d7","priv":"046eff73ff79adecbc208e64dd7bfdca16c4593a1780261377ee48e44ea06d57","pub":"0374f44a020872df00e0101f61fb61e76038f6fa8a7d50a89757db14b2c95b76f1","addr":"130a585f378df286341fa93925eb5d630adda295"},{"mnemonic":"inform measure recipe evoke make recall volcano girl obtain flash soap prison","master":"3bcbc5c191d8f5fd59988894fb749ec333a07e909b3c22108500fe08cf7edb53","seed":"cedd1141a4c9a1e349435e247349994c909811dee5770ba3642768518cdebbe7d7e5ab0776af835bcee0913fa1bb4b72205e9d38b637196a624f031238bd2bf6","priv":"9c070a30d5ad6301d73ece1e6e71790327c6922521f93d6e8b7c69391a12d37c","pub":"036ebf4e4d5349613dd3c7375703a1025896ec4377a9635e9ddea2a2dc1e7bef22","addr":"74a413291b799fc2866fc7c7ed2d2becee9f15be"},{"mnemonic":"carpet poem piece silent boost trim famous coin fish rule leader oil","master":"ab7b210126590431eb1c09ead09bef99b689a429cd86be65681debd5deeb1ef4","seed":"133b317aa1f56e79697425b4c94aa52d5b7a95c3fa5ab6d437bb1b310bae6baafdc91ebd812c76b721fb45835f3ef0f61730320a8ca6e7cc18291b84af5ed68c","priv":"1863a0b1d15847102e3198549a59921488a67002e38af1cce7ab2c0e055eb498","pub":"03dfd8ee8642ccb78642d0e373ce9b15ce9384d12b36086d2c64601ae8d18325d5","addr":"b70aef2f2dd6e42f909a5840a6cc7e08fffff26a"},{"mnemonic":"liar hold orphan include gravity nothing erosion offer average now ability purity","master":"71b19fdcc0d8e082eea3d92a5e6d36512273095251da9177b7cbd0bc2e5843d9","seed":"e58ade95c1063890ab5296e5d8a07e20ac80a159afeb88c74dcc6bfa8fcff6c85a2f19af8404d3e457492c560e4f04becb6446e290ec1a376564be64ce1c7ec4","priv":"2bdde1157be2917e98549af370aedc6a98fc5d6df99db71650ef29407512912f","pub":"020a188651de8022da9d74bd298d324c54c88e35268eca0907a5f6366f9ceb3287","addr":"9c4c3c19a81d424ffd69bd29802ff155f52e219a"},{"mnemonic":"crisp security increase topple put engine wheel apology north tent front minimum","master":"77288b3b65bd31029a3791d357521172af895f1085c1996668a1a689f4473a93","seed":"af74884da27f1ce251a75244ac945052c4df5fbb59e3b12eaea5e28c8fc26b8ec95bdccbdf5481eba4b74680e642e5e7ab2b0f6a4d0eb41db3c08c01162520ca","priv":"4d1df90eb70f94aede9dc63cd951a30730364379bf9a0f339d59d5970095eb65","pub":"023f2f6cf79a65e2d25fbff8c422ff519603c2e400c5d3b6523a6db06b969c071e","addr":"42bc49b12a7eaf46695fb1ed32db0d32e8e661b9"},{"mnemonic":"switch shy kid child occur salt cage local top blade cheese width","master":"5755daab29ff030dc4b255171f77523530a659fdd70bb5fddb69d150d4e7e1f3","seed":"dab58ef3ea14f3041588a5411f22cd426ead10057616df799cf53907536819056a21faced7e56aacd120181734640821c082daa86fa8ea4b39ddc40b5bc02aad","priv":"e5c1ebc0e3428c9ca42dfe809495dcf7ce2abf2b149664031b5f5a9d5d2f8b4c","pub":"03fc64577364f254c6f919e1a9262740987217fa2c66ea490ee6d3dca1787114f5","addr":"1b83078e35972e3ce3b1bb062b3924665a6e5c5d"},{"mnemonic":"rival notable exhaust climb disorder enemy desk owner again twelve mystery devote","master":"5daf52423aaf7b7ac4d8ff4bad65d81f7e3b15021222d3d9ec788a2d35d074aa","seed":"709afe1cde759d12cdf4fc3a68793b35490cf0261397754a62dd5d40fe528424e8deef620f89337dbab01bf57cf241a6664bb3696bd76c886c57a405170a7b74","priv":"b171a7ea63d6e1b8aeffbb63ce5179edc656e17eaf85609ab0d2680e35a3d64b","pub":"02cffc5dff2f9896d995c9f9b6d11c1cab3e0d40a25dfb9da5aa010b703c80be0d","addr":"cc673e6d2578bda7d7054d2d53b841c26e15dec4"},{"mnemonic":"defy prison walk thrive enforce match turtle venture margin quote must cute","master":"9d747975a6889f2bab69fecae39db2a10df1545ae418596d97152de0e7cce077","seed":"183b5f3d963036b0e22eca9717769422bc515977c0a7fab66d716318de12d41a01f5ce101bb47ce44501f0908f8c1255f8c3078fd2c2084aac32624c20647806","priv":"a871082f9cd061e39987c76e516a7086f82eedc06a20081161e13dcada541f61","pub":"02726bfeeefc2d5ef521c3800ebc7700e11aba3cec88f8be5c9cf3275f4ab254ab","addr":"6d793f4478d2e4980a140b724cc8012b44097446"},{"mnemonic":"lyrics goose draw review manage recall snow lucky mirror swear fish rhythm","master":"b69e9a8960d5cf2b8f457e6a037654bcc72ec1d26e4753ad34512a877cc329af","seed":"47054d3ca54f6038ae500dd6a7f8b5fa3265e87b384c16a4e68560f56dc9f7945d599d6a71b2020618c9f7bab46bc6817062751f19b46c2e05eab7831fda1cb8","priv":"5c0efe877506f2f46bf345c71c8dc31239f9e23a543193d5ac894faf0aea9ddb","pub":"022b90c4806ce022e81c706555ba3cf9597861a3d7e28b9aef6bdf36211eba916f","addr":"a3ebb9a579f22150fd9b7cf62a5f52369fce28f1"},{"mnemonic":"coach silk assist potato gesture hire bullet piece document outdoor husband panda","master":"541e3f3e4e4e9803da42f2264efdce5b9338d410b16b0e7b66611e5dec5bf896","seed":"4368a638c45b7ba4d2f1953eac650631f1a1e3c23c72b545dafe466fcda597a0b97dc3302072e50a298989f94ea255290d3963ada9e42e064ae300173531f273","priv":"b9462f51e3c20b3d805b54adc6b27c669ba07d5a5c97edb0a8cc6199d772097f","pub":"02dc7826d790d013e76765b03447d2dc92a945268e42611c51080b7ae207906bcd","addr":"e59101c16f77cdba771eaac3ecf416232f6dd1cd"},{"mnemonic":"wet problem raven barrel explain long call civil pact swear luxury expire","master":"1e2704a2365215a83dda9aefb1093e095c0c06623f060c2741e8bcb8480c4165","seed":"fd81b59cb8a4abf789c2fd55e2d9366051f8f64f54a3e08d117d344b633f2ffd63c1a6bce7a4bcbb01261b6e41f6330ac5d0b151c36649ad59c0cca7e4b3a820","priv":"bf9f0440cd63148ea0771d0f892efd3cc0638330c428a50436fd048aeedd7ee3","pub":"03d807ec07f4f6eb00f9e3ec69dadafb3201cdca3e878367ce4245af65b8e4490a","addr":"e43aabb2d20275ff60d591dae8d83b938a0138c7"},{"mnemonic":"unique mobile gospel cost genius symbol online rack round canyon front again","master":"ff441298736365bf07856cae35a9dfc2612a9d015592d5326980225c4d4e4e21","seed":"e05899b5a5a94c860cca584b6065284e961625486b1ce1c80340721fe4f89fac7afb7b665464de68b5c5813e48896210a90d44eaf013ec4fa90ace43e3153d3e","priv":"45513cc23e8ad7f7b5932988637cd6aa85f19a481cdd20c220f0407afc69c688","pub":"036080589a5268143509bba4c4f26ae8a3ad7b12ef7295c9ef416cff53b66b39a7","addr":"68456ee838f224959e5c29649f41eed02b56c3a3"},{"mnemonic":"street bleak prison artefact pupil armed blouse pipe eye brother man aim","master":"6e0891146585834da8d83d0e221c88d53770f3c56f68429565d011ac697238aa","seed":"8af79a74ad501d308be613981a1a25342791288f14f05b7cf3b81131ba2146ea63e01ccfd150c4d2bfc42d64adc899158383d82f3bed0eb772851fdab4f901c7","priv":"86c09e2544c86b883e8de233ee297fa704c39bba463e5a8742c4fefc9ebc109c","pub":"03d8cd38cd2311a0360c84cecc58787fa3916c6c2adb5b2baf12a880549a572f7a","addr":"68c1770edaf76cabcf93c6d94f4510162fd36924"},{"mnemonic":"love wear kidney math magnet share mango also dial fabric near destroy","master":"e500e6d3a103eb11414e5ebc9e27eb96456c48e9567155c6250aeb83920df860","seed":"704e740c6f437a9e8b7e8d7e2321ce81d9132c9a6df7a45fdda99cc66a09c9d73350305aceabc0fcbb589bf44911917be71e9f399c401f86246d0aebd4b467f3","priv":"07c906988f937dc841918a7c3092f5df0cc0a6ce4487631774cf3f703e9c2713","pub":"02d131982bdf285fe3a37370ae0175438094cfe3d6fda273bf24320008fbdeb5cd","addr":"df31d832d2d23502cd0198c5947e8297e6f73eff"},{"mnemonic":"nominee connect useless dutch double vehicle rocket exist mango floor educate absurd","master":"0a66acfa6ac891a588255bef6fb1a845f2756ff0a7dee8d2ff33a19a7b22f18f","seed":"4c4e362fbf0dee5928b21652552815edf27a4ba5a11a09dfd83f3b53a44cdcb6acff4c39b16d2cb9ea3250af3743baddbf6ce90ce1e492fc6bb53f79d646a4ea","priv":"e81668360f562929af7e40c5970bc685ef5aaa7d390c1bbe005b028460c79ff9","pub":"020a16c5a1098493bf1f7242de71bed03779c4eab8f35a1c6859035111514284d7","addr":"c8a841f39aced64bbdebf2f8f834ee02ca33a8a1"},{"mnemonic":"sweet leopard loyal problem pupil perfect power flock thumb wage person secret","master":"6fb555e482a1987c2c0f129ffc040fab9c4eeaa3c23a3370db7b4a5ebfd2cdd1","seed":"b20837f8580aebb15a7a4b035639bc04e27bf33e1f600069ba1378a5dfdeff3e95545e6828f339dfc30eaa449c78b046c21fd99b24d819c735e050f6992f898e","priv":"9d06cb0fa2cd01675e038897a14e6b7719ae84ca6002ed6620a557877ec373ee","pub":"03f49f50e673851d74da1fe24aaaeb75c2cedd25116c003fb4a810025192c3186c","addr":"7f61e30a20df85042cfcda5163867bea46b98702"},{"mnemonic":"slender tilt tell faint dumb seminar cycle tongue bundle case swamp author","master":"444b57e7f846dadf73a0bf77fe918e8716454416501c84a48bd78dacfa87b885","seed":"4345b114d1f3a78c5582ec5469430a8cde3a1a866e64b3c3606b84f62ff48bbff48826cee928374a01aac080b79269f89751a11aa086fc1fcfe74cf05674ee04","priv":"7c6d51ee5199457807c66f22e8d9b7a703a4e61a84cc791efc3cdf5f7038d28a","pub":"028b09c16923224208b6ea2ed777a2e4aa2bca5674eb8f0021e9bfc4e9d3fa0a69","addr":"2486b9fb36e8849e09b147749e445fb515591197"},{"mnemonic":"alone oak satoshi diary artefact virus muffin quarter identify car whisper topic","master":"b4c37472c7fec6dc3f3452d4aaa7c306cb65ff940052b0aed224c12104296648","seed":"4dca6ca310d5028c4cff946edda516d55c7de81309109e6e3586927a8fc2c4095215ce471774df2795f04fa01cc2cc528c44a5968320ede4016d68c24e4bbacd","priv":"fde405fb9a8f0e98feed3f4e996b3fb90193800c571a89a2c681c0fb4917afc0","pub":"034bbb553a8525daf361bf0c831c756a56ec476c0c9a52b0c74dd9eef35177a776","addr":"c890e1e83daa169e0295ff2844edc5ca2a7ff346"},{"mnemonic":"noodle hour inquiry know sort review oxygen observe exotic script mimic march","master":"3be52af1a8430ba7c4610dd4bb1ad67d978d40ff7530d712cb5728bc961edd3c","seed":"e803e685c85a1a0a4a382d1358f5fecdb8821564545d8573f3708a01f0f0bc1da54544ca2338cb988e7d6239d18c32bedd38e1cb9bdf1bbb6dc8cbb323055510","priv":"defabd99910867339a4af3a425caaffad76ccd47a43b05a13ad86f3d23887b03","pub":"02609b9ff36c966dff6399576fec7efa83cf0fdb66bade72334ce2ba69161768b7","addr":"abef04d453ccc6d443cd60d6f964d008eb5f08e4"},{"mnemonic":"crumble loan economy dragon vague library slush ticket flip mixed accuse switch","master":"f085484747a4bf869f38da6e6f56b9ed2be60b137536a2333f2c6818d76fcc68","seed":"b0ed9b4d75a17a53b33a73223fb158d79999548d13919599ae7eb71cfe2fcfc06cedc8f94cdcdfb05ea043069c426d2b78e2f67260644109c42a6d9b3f7d5134","priv":"a64c537c561fc49e504e870eb3608e69afdb2cee4c6f177c63fd1ce170a67192","pub":"034f7f99f2699604d3f9869dacf1e6ddb387bce4e0d13fce3f4aa85713c7976048","addr":"4b51a7f925c0e1b428b1ec75dafcb0e4d9852620"},{"mnemonic":"rifle swing confirm response name void scan shoulder lake oxygen uncle south","master":"3560f172b5c2ad665da648cf0809604522eeff5fbb2b1e0ec50e7197bf711dac","seed":"85386f49048f371171ac3ed2bb4f358b7e22ae406a7f2c9b3f494f2f7eade96f2b6f96fe48bff1754894b8b2586013393f0b9f0365c6996cd251e668ee90071b","priv":"c79860b8ae43fa4dfc570b2d20549b457ebc6e18d38865ec9cb1ba571409bf12","pub":"0253d92439ae131722981eb16924b26fe01421e4222152cfd0505744278f963dec","addr":"ace153f8d13e8cee51a2c08fba9f445f50e818c2"},{"mnemonic":"air floor random smile mechanic exile run auction avoid truck expect old","master":"a7cf0d4043dccdf5cdc835419f5bf2665c8c10e7affeaa2d8cb42e3787bcec00","seed":"e4d315f6daa11eeaea17d513f8d6df6ff2dc13dbd2e09158af03f847ee6cdcac2d6b88906ae62e84355d9a0c0956ed465b3f8081837d45eb01cf785223404306","priv":"5f1f737625360db311accae8b8ceca9d4f2aecf15d6e4b91db4c407bf75345bd","pub":"02f467c86cba2d8d6fa258d16e9b4543006b81c61bd357a2b1d79b9010fa30437a","addr":"458f265c275940d726dd9714413a56efb7f8c4e9"},{"mnemonic":"assist right street define hurry section tide museum faculty glance power aunt","master":"49eeea0b9687360576a3f93cb31eaf0edd3521d2cfcfaa37434d6d51a2f3b5f6","seed":"9371c5276808cbae376bf529372c88e6c5c6178a9b469ef25a7558ad68fd6200a8fcfb2c117b7d99e9c7db907bdb8c69632e7ec058f2b8a4ea16518fed9dab82","priv":"936dff8ec25f22522bec8ddf52535a4320327697a581e9304e62240e5d2f4922","pub":"029c518dc7e8261f2a64104ac846ca90439959f4467e69dddc7c902dfd41fc2177","addr":"5a6600220c96af511e6c89dd9c8c80f1a1b0a893"},{"mnemonic":"glare earth tuition dish elevator mom remind arctic enlist excuse vacuum little","master":"a251df0c9b6925fa78489dc803a34839d90aa10dd35216360fef92173e0bea80","seed":"4a543a76deb55a8df2a58d0fdca3ef32e3f3ca74be97789cf004d1b69608763f8d311c6cccfa76bb6c7b04ff8d7ce20ee064d78ce4e2c05d894053e8a5309349","priv":"0aba88dc12cda2d2f267dbd19ebf0eb390483c7384895b6b7669ba821b73953e","pub":"033ca852e0b43e2ed4c7258c43bcc5be47e621bbe6e0bd570176940aa9b371adce","addr":"983a92fccb0350a8371cb5d5effae7125615316b"},{"mnemonic":"tornado group bring crack need pigeon scene quarter affair purse three mule","master":"b4d54df22150e28595aa5e1f6717ec764ffd8d2cc6338e264dbbb46e9155dbc3","seed":"85c281d21f25c14304aeb5402e717b52bcc0e5dbeaf2d155e11913717c545baf79d4d965670d7645bf093ff79f4793d136d794616905c2e24a8c72ba1af44ba8","priv":"c45a9afa0dcbfabbec916a9fba6bbd9cabc1a65b4ae3358e29943dee9d19ef9f","pub":"0272882ee11e688d04b89252ca1000456fa743b5931ae03e1d29934f79980baa41","addr":"860b69d255bf12d5f725e286203f91bdbdd29bfc"},{"mnemonic":"toddler bamboo tornado season total battle urban mule oval steel field case","master":"af9ea8f11f6fa83dbbd4ef32dedeb88070b3fa9fd98d27e1d9b43e66da7d3df7","seed":"4b95b55884e008f340660a6c9ed4f2b23f45a5e45535fb263e880ad8842e845a62e66720b75d94fad7f47fb494bd32ee70b7a339de5b07bb13c7f0533e8cec57","priv":"643eb65f5c87407a18be41f6c660d4d1ae610c9305833c570d785006b92ae354","pub":"03d1c423839d02f40abf0632a36f9739c6ba59622ea56e1085d2ed54504762b43b","addr":"05625426a47e8c11f27fc55a53121bf748c2d05b"},{"mnemonic":"meat endorse bike truth avoid measure injury polar rely water rocket zero","master":"23b56abfa50026840bf19105ea9a02569d1881e2cc447a582b08a6bf6304a33b","seed":"d8de461e4f04d4657de6b5adf8730bdbb85fd175326671886017c09d8081ddb7dac0b8262fb01f2dde477b3e2bd97653a700d373fa29ec7db2161dcbe418627d","priv":"f409c92079cbcbd9f96b2bf0d84f86d495bd8e6bb4859fff2d62c29558a551c1","pub":"0247908ec215a561a41e2da6ce05e0ad08158bffbef9fdf7bae729592e4d17b45f","addr":"e4cb61da62a6176483f967aad232c0fe89a9f16b"},{"mnemonic":"few transfer upon helmet property draw strategy talent awful goose index lesson","master":"c0e538e1e0b819660c63ff668869a81595107458fdad44459f6ec22b251d46e0","seed":"fad56235bc5f3a7dfa666c85e5782871e7c202bc4363da62fe3771d71b36a9a1502d550d668db69264daedefd7375862b891d4193cf958b6d8af9b39a9fb0e3f","priv":"51c8264448b81467c2c86c003765322f7c763e0854903230a4ff3557fb7afc31","pub":"03bd00d092d311add8fbf191abccf181bb5fbf83e26d6e29fb6f4d70055ad5e7fd","addr":"270429d79b582d835fff0b15b0eb21ba1c98b2fb"},{"mnemonic":"can warm add shell obscure ability mushroom discover destroy useless split blush","master":"611e2b107ee76d6f7b415776c7b0c6f03859366c342a56618850c6e3cdcf46c5","seed":"c9f4b2663f8abc8c8872842c41fe06b5911b412fdaa875ba59366d7a18734aa795092d220793867ed43afd1d79882ffefde417ca68c9ed61a9f52437d7e45a53","priv":"af975acc3008d742a37bd6917f4a5c6e9a5e0fcacdf1e74ec489e675905dd9c5","pub":"021152804b2ac5099446aa5e8cf1fff850cab08e225922e3865ae5b280a230ddf0","addr":"d4baf915a1108fabeaee47ba0b03cb241a12e1bb"},{"mnemonic":"critic length shine mimic gorilla rebuild bike security price differ spice average","master":"418d3fa386032d0a22a3b4553ec662d52ca416af47d0963e288a1bd08ad50d20","seed":"c44a2f7e56ffc9850454a03c40be79555c340b8bb2a7559a664a8e295fb34fe1a38074101b431038c207baa219181046805a67977022d61bff2270c1e27b80b9","priv":"117d57d4f3dd6db8a718e025f4fe5009949139f2a41aebd682ab49f96ed152dc","pub":"034af1a0205014cf22dcf328aa9308e255355dfff65a7185aeb180061aeece5084","addr":"f7af8cdd0592983c065c322efc64bf7c25769e2a"},{"mnemonic":"vast resist ticket hedgehog around fatigue rocket rack carry run protect icon","master":"c434c6e478fbf7edaf97e2c90c38369de3033a98696b1ffc793aa349849c629a","seed":"720f1afc198446db8a107105c7398d3bba7675fe0d01de12f933e2eef7d12effea0e9d93099e0256b9e494607bf45d855fefd68543d9beb4b92f3d7779a8616e","priv":"497b2409c651a41ed36e58e977611292bd665e273847d4d413291c386d0d65c4","pub":"03ba0869f55efde74895a6905dd149bfe140fb2ee4e3eb19c959195d93adaed2f7","addr":"2242ceef764c76680a768594f804e218154ae3e0"},{"mnemonic":"neither bunker use enrich liquid borrow time feed mixed clock submit scorpion","master":"a9c4646a10078a9ca6b218b7da25745a76cd7dd9e38d803d8e840863c9b97449","seed":"22cc85d4e408d0a751b854f16e00fd16b018fc26f95aa7d82323084ebd7d7bf3fc2370c1a5e38f88584e8a17977f17987d75e447f704603c2d71b3ccf806afd0","priv":"9801ad0243910e04b7322f493540801628da575ab5eb18a5e0b20b0ffa498e5f","pub":"02c3f726202db7040a250647799f5791d4013b38da6053e44f502d0c8a064124f7","addr":"fb0ef77563764b393003c137da2dd1ee21d92904"},{"mnemonic":"letter violin disagree arch crumble amount car inherit wasp vintage disease orchard","master":"a24fad07da3e4a04fecb2674abf8b4260ae5dd71f003622bbc4a00292dec3cf2","seed":"890b94a33cb176c697b9ca49281c053f88a8e8bb6f52af5f0fab57ce621145ea59624fd9f17bc4d7ff820bd2998cd1d4a2dcf8f89738c150aabe7af5f87a6b1a","priv":"499b6d6e741483ddccb35f917752e51970c5999900b48e18b2d1edb85927b7e6","pub":"03354167051ad5a01e056f7bb655de9af430fb0b3756e1cbbe6dd0cca65d43ff18","addr":"efbe8995bfb51a94b21826bb93937616c5807d94"},{"mnemonic":"elephant shoe quality dutch pepper math between lemon wood below strong grace","master":"7890fde1f36829461985465e7a7ba26ef80bc9908e5cd849517a999f04b02ef9","seed":"077fbcc3c57bca394c393e9852c3b837ab555cfcc5dd0097c058136bf088fea569d18fe0d447a8bbe53b5f22961de7c5cd0000274930db60ef18f049aaba4741","priv":"0af39cbaff322b7b7298b2605fc762bcfa69ff84a50dbb121502ed1e8db963ca","pub":"0221dd6d3d3c597b982093f5ddc4b8403b3d16d0e084aef37db3526f050c9b66d7","addr":"81ee7b181a5d1902b6aaf42ad0225edfbf669498"},{"mnemonic":"powder marine skate good skull correct catalog parade car length fold clown","master":"dca44cfd6a67d213ff365e5dd6bfab6fe63ffbc999c9d38e48b9c8d32d32f914","seed":"91dda0ed96be1b82432b76bb7dac1e80ed0a1c5413096d4a22437081834cc29f6355dc3e79d7ee00cb6bbe50a83fdd3b652259937beccdf11b844ff023269e76","priv":"25ef3009323160687cc6651338320311894b8260596834e6cd05c1b921c7254d","pub":"024b805e8c768c8914ad8c55d8e1898490b9c71fa68ef43d07f3db496f03db11e7","addr":"57c28bc9cb2f4fea177c34e581c95832256090eb"},{"mnemonic":"client wagon legal favorite donor tag describe object camp network tornado immense","master":"4b916d7a10502f4e2ecf295d826a3248fe9bc45a13f1332a46586833b2f1dc05","seed":"e2726352ef940a7cfccbe95172c1fb07c8c25ddfd7ebf5ed532f27abfd33e81041e816e34aff02530525596654111ab3186fd71bf65dd3dddcbc6efa7944c347","priv":"131de6e55bf3b614153557b35c839f0c869cb10d62b8c34c15fa2cf7c32bf97e","pub":"026a3afcb9ce79972ef910d6272613580b199f90a00035ecca637b09397f0624bc","addr":"b2ac8314ecf16da855c5d7b9ae3aa12854ae4a05"},{"mnemonic":"someone tip green vague sudden element beach people route lawn vehicle female","master":"2f7b9ecb854a851e308e944e6a8b39811a286e718b4ebb9a36e8c8570cfa7890","seed":"7653cad23c600649423fd68b0c7d002feb0327551521059362b3914a63f6ca6adcb1409f7f7f1b01f5c489237b25d0dd9b0aa121a60b1af33cccf739d05e32b8","priv":"4b3d50735f027be5ce5a85a739227b4e86590765e34b3608338497fe318cdfc8","pub":"03b47e6036447632c8ee3d2d1e3b177b51ea73bddd30893818c81059cfd3ec6c5e","addr":"10d976ebd58061a7c6ebe2ccbfc85adc617db2ee"},{"mnemonic":"version borrow decade family away zebra one course paper promote man gravity","master":"ca2995d4590ccdfa716b0f27a3e5e93d084df7039116b06ce5b4c5f2bdb18ef1","seed":"97a3f0fd0c7150526375d5cd1ea192dc0f04ed096e5c4895e0a15a6d491b206b59d52800c2c31ac6b512664788ac79663135f450b5198f358dcfdf1e9cc26e12","priv":"cbf04fb7c5c97ab9980cf82625a612919a85e72c0524cd49c0a237c25940b563","pub":"031f04b34f157a07b6bf50fd54ff972b8441a72d6a5d4fe1e54a1867d07fb61cac","addr":"57488105d27e808a39fdd571c895dd06264d3357"},{"mnemonic":"truck zebra tobacco hair monkey pool label produce leader hope misery cost","master":"b42e61efff413779403a9d5ddfad5230412788de3c0c7da4b020c73a72a77569","seed":"1b9c99349d6388e5f7dcbb8d5b87951a614ae7f803b69b30783035ed016cbcab3c42714246d05039bc6121dba51fbb722c13d2f6ca0cda79a0d816bf7e568cb0","priv":"52dad4ba927ba056a1f0a07515f044c3c9dc712c2019879029ee0b37c7f51b64","pub":"020e6af559d2e1115d8ab76e908e3ae778451dfca6250b996c42d4f3044f0f1a27","addr":"1a3e87568d2f20d4480c153cdd82af21382fdf9b"},{"mnemonic":"dizzy capable mutual cage uncover frozen exhibit awake teach grocery juice reveal","master":"54d15b84b003dd74581cc49909d3bd7ad07e00e745f4113aba6facfdb305aa2e","seed":"c4ae35b24c55af14bf590df97843ce1c9bbb324b845f9d2a08f0ead0d0292f6092e261711aae504feeae862bedd7558a092271455d89a5d1629be8ca43710e84","priv":"d5d476790ed6e46ce12e1573a9fedddada0413d5750d1d18e408c125e43c7923","pub":"02f3b58f6cf3533f3731e5ccc6cf094815d52467e39151d517b9f6a425f8743601","addr":"249ffe5709370cbe54520c162a4a7c8db2b28bba"},{"mnemonic":"menu damage flee oven blame vanish olympic scale pretty valid toy write","master":"91c79127f19318ce4594f4f1045f0f2efc8ecb6a3ee9177ea2cbfcc890a781b8","seed":"fc4b72ba3587fc4b35637186959e3f02460262bbb330c3b18e561faf4cb2ea29ae9f92f011d9d78231746dfae33f57d75ed85f96680a6a3f309a3f81cf59831a","priv":"cc7b3e962031f93079b4d6a9152a85bf927ddd2fdb9f84465220e2cc3ccf9ab7","pub":"03eb09eb7f21c9e411e3660fb49907bc9a23e04bbe75151ec732e066e4e0487118","addr":"20bbafa15fe38bfda08c18ed7a65c52daad01614"},{"mnemonic":"remember hamster power document detail pave inspire tongue rookie monkey board tourist","master":"dd1970c96e30be347b4ec8fe789b4cfc29ee073162d4a2e5dbe5c78c80944af2","seed":"561682af8f69fc045f09d43db4f71a3c7706615ac142078d6aaea287bff00b0bc3213537dd50b783d7f5293b4c2d2a1f6f9bfcd5fdf17f19cb10ecc05f854b1e","priv":"79c341d4178a7a8e1fd364d8a847d97b06ee94d9906a269499fafa63730d04bf","pub":"020540cda9e4957f9480aaedcb38379f2ba60648ae487b741c629a45a5b34870a3","addr":"cef7f07d4ae1da5fe3cdbb37d95bed5bbe53e838"},{"mnemonic":"endorse rescue traffic vapor chef movie symbol scene slide eagle youth tide","master":"8e54dbce9b2fba91209dcbbf6bd272d524762ba3ef2ed05297b01f440e6ed597","seed":"2a0ff0a70d82f948b866090a4e77ddc360a2f52b6abded17f13dd66e79e845bccd2c55ada4d4ed3dfb33d5d10700628bee551ea775c7f3342f6d7a0c3005194f","priv":"c58ed547be839e99eefae49479b3b6345fd7c6ddf390104a544b79f5f677016c","pub":"02d795bd4c26b14dd2aa3c04633f5e0ef787533b3ada72e7c83bffdfd4cbdbbc5e","addr":"ee25d8e4187f6a6214662cc4872b7f7cf7204c45"},{"mnemonic":"humble glove resemble slide rib focus naive false snow north strong attitude","master":"e8b826c5d90453d1af3082a0d5f6a625207bef96bf7e168ddc4091d7f865d51e","seed":"b9bc139c6e97339489cab328b3a362546cc19d0cc060e5c5b969206024aff86f1579d230b4b8b3983b33cba32a58d6dbab5f078704f0efc65d6476062c1d41bf","priv":"4085b496b9a18f4ee5a1d79974be1b1729f51d3c63ce347420d08833d2c793a2","pub":"0251ff80d2e90a37efec614d9fe65b6192179941b772a9468440a2380845996846","addr":"4fc115087277fd7dfcea23e089f5a3a6d7e3bcbd"},{"mnemonic":"fiscal truly seat deal crash train labor trigger kangaroo angry today minimum","master":"1770627ca13a66d0fcfdb474a3eef708abbf9d23d211970395308dd6758bf8e7","seed":"a19680de56046e31637ce714778881f1ec6bc08abe9357804062cb881838c2f8387b52f714377b89b6faa07c4e5b6294324081b7dc521190cd43f75f91029c22","priv":"131dc8ce3551842aebd863eb61e07e6d2de40d548dcd28ab0ed6380e469b5d92","pub":"039ac0eeaf7600231c75fc72dac0b2f58418e1f187aefb3491934120b4fc779d18","addr":"fce14c8cded6d2711301a780a58297c68761dd52"},{"mnemonic":"good dust code sell element tilt host valley climb genre asthma bench","master":"106ae0e9582e9db67ff88c1098d3ef651efeef30d44ff60de30bc0c447217ff6","seed":"1b307d8ffce13f7944bfeee6d6b97de257cd31608ef9059bcbe2cef8bdfded91722fcbf325788d48a5072b9f915670d345211006102e5535f7e2a1dd86bfdfd2","priv":"a78bb63f0cf56b81e228b801cfab1706afb073bc2deb8ce1c8c56f2ab564f1a7","pub":"03fb2144ca5e9dc753c2aa46f94806b35f201d942286571a44bbbb879d2e9e3adf","addr":"5d68a2c8fd5486ba93dc18cfb6a04698250a424e"},{"mnemonic":"buzz prevent cover list flock meat that slab crumble melt prison treat","master":"d620abf2e72b47f061594137194e41c33bd6789799d67b712179c5c9e0dccf4f","seed":"331fe2ce10eb19e2ea13c0ff7abac9b49d43de8d937963e8498da172a46e0c4dcf3e9d276d1e4c7dff5926609936f253e59c814bd4c061429cf1408c45d6e5a4","priv":"8e3b30ec2427f34c463f83a500842d4fb73575e261022720276b3fdeeb20f075","pub":"039ed714c28facded3af8fbd8497b17818cee93d26732aa7258ea61c6f8cf542d6","addr":"74b44edf7f993c72dfa53fbcbcc836c99578769f"},{"mnemonic":"domain tone insane visa much reason tip truck travel head finish grow","master":"3b00a9417e07cbca1d0b80b108cce99089c726e49c267b2e5a2a1d3965c7c99d","seed":"3e2c842cb5d267a2ca3fda4c20d674d048873ca2cfe89e02558a0b585475796979e4bef6e835b17593c53a75f5a4b37dacad0977a6b6fd6589d26502db47a048","priv":"cba9d951fdead64920a36afac46d82241c6084b46681902ad37eed1928135db3","pub":"0321db6f62dd27416d94cc22ebd3abe7ccb66d5e5f57641f79de3d9a1c49f8d0e7","addr":"17d65bc69345ab94e3817738981ea5f9289b81a8"},{"mnemonic":"bone earth country lemon great ridge glue neutral vibrant age doctor income","master":"ddaa76dc4405bdd779045a0b113133f51af43c14ac12281260ea2281a21d4704","seed":"c7edb1f4572aaf510b4b79f18cb68a7464d20babe170b3bcebfa7902f2df2a47d404baf1489922bbe2edb46a2a8ab798a99cb5dfc162b315e4e0a83ddcc5614f","priv":"cae3b56916c64b7303c038294cb1a9c15719e3cb8ac0cb2476e5688b6bbdbf50","pub":"03c9565910b4120ab6a62c275ca0127b717116e773f57eb93d1852ba3d0f2b431c","addr":"81b61de28566c226e0153b1e3afd53697c6591e4"},{"mnemonic":"rotate agree figure style cereal best corn box corn actress toy deposit","master":"ddb3592dc43e595f968e906c72be97c03beb78325f00969311f167e7748bfaec","seed":"cebd7cfb74b2ac03a29e6f4d3dba84d6b47730b478d0ec92f90c9a0ca575d17c581e1f3959b4e0ef5d5f51d43a0fa186ea54420cccc8c2fec8a25f36af549e6f","priv":"b3a7e3147640f66d7be8028a23dceeade18f23bead07774fa5d176014627dbec","pub":"020e2c9e9484acdf5f8a574e9fe912cbf6bf9198579107a48b976da5e4dca2ca0f","addr":"eba352793c5a7ed663a5eb33ef9c44ceb0388677"},{"mnemonic":"kit age click judge decade enable trash noble first grit crop decline","master":"bb39f1d6570a42b31a6b1093d6c1d3d469df3d565ceb2064863e50c540cfd986","seed":"9c8471f0ada1f4e4c4b863811b36036e72818432b8e441ef8234ea29446d2978195da3d63aea71aa5d1a7c4e71e131a90e2db598bc4ca2bad1dfccebeacf963e","priv":"83a532c37858e36cbbb325481e7be10beb2166ddb16b7ea19328e8dd712ac178","pub":"0215f7cac31b44b05f1fac2742ed8a0d6353fbecd06a3abe7946e2dad1feb089c2","addr":"a10254f23fb959df76231ea3061cdde854aee99c"},{"mnemonic":"jeans broom faith border sign decline choose black depend camp nest song","master":"01dc6326bc635da075e100217be8553c30be5c3ee66bd4cb8dc0768777b5826e","seed":"5e7d44489c45338978dcb69035addb83625389d15a5a2284ac888682e7499e8b07aca6ccba965201512ecf7da5a5ef6e22d561583e15f4507eb79ca60e525da4","priv":"07e07f2a2d9eaae6ec9ea7f676124dd14e2f29e43095cc8574b67fe5a8de1fc1","pub":"0295a431168b265c62a8885186b7719298c5791a0d73cb5b6e55cdd7200b5dda38","addr":"9328f2fcffe4db6cc6c8c2a5b0e7f78cac1854d5"},{"mnemonic":"narrow federal feature ignore damp sun brave cram blood crash glory cargo","master":"7e5ad0d0325b2bfc0ac8a2d32b13d758b308fad36c5aa4c497ee3fad4c999fa0","seed":"e680df5400ad6c1f8b097a39a4ce9d9c3c48ea4c21b71795fa499ed641137b50b58f78603bcb2bddae78ff5f96079d48fadd175050ff95784092bc93557d0c13","priv":"eb443a6e96330c1d3c2213e9e345b4cd0e4b2562d6bf13bdf9366f0974d0a98a","pub":"02843de6f3e02767908c2692c091df22867fa783f858a39aa7f6dc786ad5b5d2d0","addr":"5a53f850027b3f303ade321198c74d108e24f699"},{"mnemonic":"fringe fault blind lock wreck one kite ozone system come spring amazing","master":"dc2916fd303a02d0d7ce5d5e0ca55b8c504063c3b54d006f0926a89c52e413c9","seed":"ce52cb29528f78b85c003f5bee65b2d3145ba93963fc4ebc023183618cede1c0add4fbeda85df76e8887004fa526769752808977726bfcc838fe9fcbf4019df0","priv":"5b6302f3548c8a8ca594bf67bbfd44ca98ca84b2df134b0d1edf4b28ccac4340","pub":"03846f7ead64dacb85b25d5279681074dfb9a8c363fc48acc6565c6e142380ae3b","addr":"b32324b0f48ace5119e6d6616b9e613438d92184"},{"mnemonic":"rapid donkey deliver soccer between antique pipe youth science angle erupt leave","master":"3ba5a3b9f7badb433f4235e89359801dbc87b6948e74a61e8555b11dd2f6b491","seed":"eae34a8427228c93f754a3a5ead6241684af42b34047f98b12cb7339f3b7390ca9ebd4373a89ef512e75126de78cb72501d2deb575d356d6ba9d64a8d50951a7","priv":"61a6843aba8ade001ff479a2b768008ff5ef996a5a8576956328815755008c06","pub":"020bb75350f98f845d5ae99ad8720b025d7176c00b6a92a9ea7ac14818a7ae6a73","addr":"2cfb35c09a2a5a458519e036d21555571b88fde1"},{"mnemonic":"juice riot brand example type sign crucial warm bread describe rain slab","master":"9de3651516a0c991dac2dcfa0f95265a6100b6ca605a0d577bc9221151306b18","seed":"5ad029a5964c27c295502b40fba611bafb9b9e626cc8f8df5a98394060d16e53ce41ea46421a615c5a3b5b61c20138466dad1a0b9541d57e8ccf7813ef6d9327","priv":"a54d64cedd5e3b3cfddb182a513a13bfa1cd64627db1fcf5c91f398330010741","pub":"03840dfc1f9d210a632dd38f45fec096c9dad11de2a8523adcc79f4f520faab8a4","addr":"1151a84a341b5b24b687abd2083e7fd150ae937c"},{"mnemonic":"air ill huge miss empty force indoor inside young ball wear blind","master":"76dd3f042a76e88b7d63422086fe0b5242a80775c92ba4dc31b31333c6cf367a","seed":"0df5fefa4beba8bcbdc1e6d4b906c91ca66c14261b543280b31be5e1a37b7a91baf9f34e17143a3e3451d3da18534996a4edcfadeec0971b5b7db225d6056fc5","priv":"90ad41d7cdd253fb10da90c1eb6f9c75120553db484c6e1e2d61aa4ca679d5a3","pub":"0229419c442507c123f161277de5a9beb43fd91556f6cbbf194e26bcf4bcbbd4a3","addr":"68ca6d2e8330de386a3dff8acc4f9be6aed6facd"},{"mnemonic":"electric grape tomato average idea shrug slim certain caught know rather poem","master":"4770c9846aaef6f78e326f3aa72fe236564251b0187e3d8cf2dc95187fe348ce","seed":"d054638cfeac9ab3a2150a49d6854c9fad983e7fc91ccba17d6bc210c976b20336c33fb5f8eaa6e54bd6480487491a1f8150d074b29ece6164c2c99c5427d7c1","priv":"0bbedbc6807a1c2b81f7c1f8b9a8380e27d19a0905eb505630156639d0ea4097","pub":"02be715af6a8583fcbc51f4cfed7e78d93313d7fdd047b198abcdb6d0d2271bca8","addr":"0535e0d51a9f99ed22fbb713b2812e4f2fbc680f"},{"mnemonic":"boat tourist proof point giant horse error trash abandon transfer poet legal","master":"5c366956c526671c4e6f9011872b24d76adcd95de54187d81e3c7c2edc749023","seed":"7455f7f31ee2c7729f7a05b4223bb2b335a0ba5b8ca1ee3f632e04e752294a1f0081e94cbb6763391132562a8f8323b0b05cf00961a2d9a4993ef5ff69d52e2d","priv":"ea1f442448650bf1445c5aa13107210280293e9cbe1b1e432327339db7b68624","pub":"03a80a35d7d599be28524a427dc9b3fb593bd12c7cbef3982bc67523ae6c202455","addr":"c12318aa7559ef40d3b56856a2cfcf89d5f5def8"},{"mnemonic":"number oval section onion aspect surprise romance paddle oval reveal business pudding","master":"2b2fb49728bef8d8301af63af35716b2375071a75b1e2e8d4162afe068e6a7b4","seed":"384e57c3ddb0691d55be1d667dac88873719ba4260fb3d26c263d75d8f5cd12b444255daba423821916bd188df5007ad31c6388b0730de258f543c23fcf74923","priv":"26c77883d1bd7a257d55ff87b562a41408544fb727dd98a7aac093b4a70f75a2","pub":"020ee3bed4cfcfcd28ff8d41c96a1b7851ea3ec4f81fee00ef8ed05def21d37e51","addr":"e8447d8d97950c9a15d3d181a3cb00b0541941b4"},{"mnemonic":"shell lunar fragile unveil dinosaur napkin mountain fresh annual jealous check jump","master":"0bc353301fc1edfb08d3ac53efcfcd96699ffae3174bdc83876df3f9a5fb1a90","seed":"4c8a46510fff2ac0d666176cf77fdde3f2dcfee550260e43bef7f9e6127ad807ed335fccbeb49426aefa8c0f1268e5f602124c2487653160f575cad5ad68a571","priv":"2e783a6c7e1e74645f99752d342aa3b6de689af33c5a80e3abf28f7e1ac0c6e4","pub":"03fead7454b48e2bb68c8fbeb1c807dd4a7d05c6c4c9153d4c516b05967ec56853","addr":"0ff9f27bd866673fb10bf741a221cc8cb4a4f95c"},{"mnemonic":"sniff rule decorate expand siege boat people choose resource topple produce coconut","master":"03c9712b2dc0ed358c17478acf1b3b9c8ea9106c01f0e52056856ed212d4b9d2","seed":"a689100267375fcea1ea18ca798c803fbb6e4b9d82f9f4fc96b3a0873f41b7553589c605b021b4dd4a2db9d3dc5b239053ea5a48ed227fd6db264299fc8d0e96","priv":"8eb04249c00506425b0e414b131ee80dbd8db4f5a873be04a0b1d293203544dc","pub":"031e448ffa6e72016fbcdaa4c2790c8e57145ff051de1d99b69cac4df1f8ccfd0e","addr":"edff4f402b7525e5707a9ebb5b13b2bd03d12ee8"},{"mnemonic":"crumble coach clock opinion net churn cinnamon seminar slot upgrade always nose","master":"8af370254a2887d6d8d00364fc824b6565ef750d3b19fca98078281b040f9244","seed":"1c6241635fcbabb70bdd30d827f602169ddd82e36333aa50a7f7f2de4bbc9a581d6f7718cc94c0d63779f38363a8c45042b76b89610f9b3c2e785de234ba5818","priv":"23dc380f4557ecb1cb779d128309012c409c544c906865b06244e49be877db3d","pub":"03261b2261da80af3a33ca8252aeb21edc608b337761a6aa8160721dc202e65b29","addr":"fe0cb66348437ea5dbf8ca79de9db63f0ff51528"},{"mnemonic":"mind fat sort buddy gap glimpse hunt ready library invite mammal repair","master":"01979edaa3aacf38e619e05cd78ac50eb2729d6ca2d8ca5b476677d30a4414f1","seed":"7fe831aaaacfd5895fd3746b45c0cff02d52923fc3ef55842fdabd02de07bb6bbd07dab7f1db1318f97fdb6141e5ab0142d7d06ae92c020d2be760e08f99661c","priv":"10d3729902b4a8c26b88c84ddfd6201048250294f18a2ff0ab4248a5b4085992","pub":"026cc54074748e623153f3bd4b735d0c7df21cd21fc59cac3ba43292cf0ec3230e","addr":"0b7932471403f4769cfaafe834488587349525e0"},{"mnemonic":"area switch resource vibrant prepare write genius danger extra alcohol section company","master":"dc841ed2cf4ceadffcc8f8f6fbc50dc3385e2b438ba5f985f33dc5c68190c69b","seed":"cc2ee2baa8b309ef7e76fbc14a343a2435d6ce0f7da46d1f9a84782c77e84fd7cc40c503db71f75380cd7e2236c9dd0579b528d84b7deb89b0d4a4926c66a360","priv":"b2fb735d798aec932964121a2a00cfee6184f03bc0d7885a84507ffb1a8f97c7","pub":"024cd279a8812efb672200639f718ef89d9996a6bcd6ae9d50c1548da744bdee7a","addr":"4c56a50381b8edb7e02124e205e170979879ac05"},{"mnemonic":"twenty shift viable behind victory napkin cry gasp own dance primary glow","master":"4519e4b46f8279cefb8b261568638b514f8591a60617fd9ef4c0f03c193b345b","seed":"393b214e7d24adf4912b8b6dab2c779c2896816b1f001d80a702a7dd2c44b5a1efbc85e2554e2586eac150a1a2bf1fe12e08735dbab0ca65a746259bf953846a","priv":"a187f775899244b9a57da9a173614ef2992ce1bd2ad6333eea6e796f04ca446e","pub":"02735247ce372948d922ef85da71f424580a46fcb453cc889411722f8984f301e1","addr":"c055c01a09dfa7b360a99d784d05e715dfb1eb37"},{"mnemonic":"jump end chest decline act capital text puppy empty input possible goose","master":"5e8250d4fb78cdfa191efa589fccb98d2a635d091df8352a0aab57fa13be007d","seed":"fe6e62ac192f7f101fca767a1a24421acda2c23d1c232ccc19221eaae7697d9eb0cdf7350272d93ca37d7e10b3deb739ff0b05ee723a4acc754bb6994d2a5b78","priv":"f400703afc057875c9dd11e046fa53c0edee27c78e2905425a74139f3329c1be","pub":"02c98ed539a5905393750276488e60d851163ea5dbccd25e6fbeccf119b22f88e3","addr":"81473d441525a6374665b98ff30f75b43157b29f"},{"mnemonic":"spend course nephew spot nothing girl wink flight wine hotel harsh better","master":"6d62643bea35847c1ec3b6a7273c42a24832d28092402c2dab4df1004df249cb","seed":"5cca26006b3c22da1622ffd07f0478988c9c97c5f128f78b89fe6b89314ad8c37627f02eb630f376574a38c243a3069c5a34dc59a709d5264f42cb1f80740adb","priv":"dce7ae54553f89302b0aa63a500cee7472a4a33967aa8a1ee18e16aa0e78d2af","pub":"036052be2df30dd8ad7bbc35055a4e60bf520fe962d9c7158d1c5e2b45c4c4f841","addr":"1ac0320f22683aa7d67416e24bf59098933a7e4d"},{"mnemonic":"coast grass horn front broccoli artefact also history screen bleak thunder example","master":"c49a459ec914359418504d3d471fde7fb1a82257347a4bd95997df53da47b2ee","seed":"2f528e97791aad4a82a7af1a68007871a2b4917fa238d69137fb93f64ef1f7af2dc036079ec220b8be11365d62ca11be66e83ba0d829671a55a319c441f6c8c9","priv":"06fea4c71f85b7b161ec6edf5ea0b90cb95a410fda9fee0a603fa350f289ef43","pub":"022756af9a6df41e36de4300027a8a6a6a8f6bc7c2b31252153f3d915299a8129e","addr":"6203a9699c5d1b6bb64d1dae86cc741896792266"},{"mnemonic":"shield liberty wash park absurd inherit suit resist garlic cycle ecology mass","master":"a35a147cfb59e738ea4eaf9e6bcf1102c7d4c15e3e59458aaac528a0635d5316","seed":"fdf1adaddf7f8bec833c3054d079be7a240f98fbf08d051892a02c4b1e1392ffabf84422606d7ef333f99773bb8d51f01175c568a94f5317cf8b225991d7a528","priv":"581e1227a6f32dd51a3bf36e7c4f1504b00a528312f3025f3f7fbecb37b88b7c","pub":"03c0e2eb1d83e266c1c25cabbc6a9d46b0d955f70ee83b78ef0348e44fd6e8162e","addr":"18573866de437d48c044002b20fc5b886cd1dff0"},{"mnemonic":"spider cake process model elder electric mosquito rather choice insect crunch pizza","master":"1c95e3db98b4194020be93e3d4791b9aaa2c7eb1c83b02d7f3bdb07183f4c3fa","seed":"d25f0954443b2c18507a0c71923aaa31857d03187b08a649156ab634c20f29a444ae505cc80515e30feb69c05cd4e133f38b18659ae6189ea27b442705b9089b","priv":"5b9cff23b6a19a67864ec0973e3004da548b5b97400f9fdf2dde3db2469b776c","pub":"03829d931e59a87c6ffb4f8d512374ae7981ccf2c08a30acd787b77c628b727d8f","addr":"aa95e7e0c4fc203ea639873f05503a2d5e98b70e"},{"mnemonic":"include yellow off random knife video person monitor height virtual oven derive","master":"92cc90784cb9a58deb578aafd5b6bddf5195bac720c1b27ad575bddb1fe19487","seed":"7e090c19e128ee76d95f7334361fe7eef356bec53a06902c6c5bde0cfbbc7a7adc540eab3fbaf7d1e4c6ef38f4c29054767c115e6160e6825868a91297e2d5d9","priv":"076608b84151c535a295ccafdd1301e8eb82f779fb4aacad5bc2a1f0a699364e","pub":"03581ea3f2b7ec38ad8ad9717b22cf43192a637eb4d4db0b051f2085ccb43d9e5e","addr":"a68d0470048127c2234f1ce4a70f9f04c72c4dc6"},{"mnemonic":"chuckle hybrid seed portion dress move settle pool erupt segment annual demand","master":"fbad7924603e902337c9f58086a9334562d6f3866c798dece4c1761af9914d3c","seed":"ed3ee02d4b90299b11fbdf6fc7698613aca89749352bb2ecdbd5cf0e0436e0ef702a615ad041bd97bddd4e892582ed9037028002e2bd5c58ae7730c47a44e20f","priv":"77c0167a4fbcf6dc7105af046e2978eddf6366e945d8456c28e13c8f3ae4de57","pub":"039a672d56a39e6aa1bf2d51aa0c3525692117ef33a92ff903dc9611f86550b96b","addr":"d4fcea5b95282e1286e412122701e9bf49bab344"},{"mnemonic":"portion upper maid dash where control nuclear post run manual mushroom bleak","master":"66c9b9ac9c75057c18fa94eeb0f75cc73b90c08eaa3aecb1a83577062be3f6fb","seed":"06d6d3e53986a879befffbf87dcfd6b7570321a071e22092e1c88de34bd44d7ec72c76323fa0a7ca040a7ed90ccd686d13ea027ebb06f8c66154a838de229f2e","priv":"f5141661ead9339621deb48ffa15c4569cb2da05467de78a2eb631a327f5a68c","pub":"029a18777158d04ba09a941ac8ae89366a50dc8253319b71647fc1c6e93dab01c2","addr":"f1fa2abc32e5e9aaa843cb07c37dcd549b76485e"},{"mnemonic":"fatal lend tortoise urge topic sweet spend antenna stock nothing doll face","master":"2d03a7cd457dc67949321ed16a2893792e5210cd4bc0f5ac86af83897094507f","seed":"f48146154da92dab72fc0fbe1f6c7524178301502d72ae7c404b67f8b7e102306bc03f339424b011eb22d15977a0f12ad0b25e7adef5661d65b06dd0b5184dcf","priv":"d5908635bebc92518047b79599b90b1048fc2bf2d3eb36a2bfa5a894927675e2","pub":"02309e322a1c103c44ed7195044842250cd757b061430c55bf1fc8f7f10d660bb6","addr":"946728094cdfcc601a6a496ef5dcafd3de9a6488"},{"mnemonic":"blame margin glass dinner worth right require unknown wine settle make aware","master":"7297101c31d8168aee1fcb025bf1ebcd747ca6d5ba19d2bd28514fe3b0e0be18","seed":"e97413449360a70d3d202dc63ca0670a98aafecbec1de44d8c11f1ae90099bca926813685a429d4cefb6f0e29e207732f29e962aef7b6ae82ea3cf2d7617acd0","priv":"b144f77a520ba1ecd94b1fed5f362cc1fdd7ba9bdc355e9d520c2f39c0a20f7a","pub":"021c6773d45e549503e3bd6983655510a46a873e793c6cdc989356f657f3e5bf20","addr":"f259947fedfbb0ac039a44936e901f3622b9323b"},{"mnemonic":"gate make bird oak brave hole elevator tuna gauge type school disease","master":"1c1407749a31dca67aff767e4b78eca5351ab6792dca8aaa3b31a766147207bc","seed":"e079a04be32619bb57910662e11a006f27b02743e4440136ba02d7915502d0fe1590667a555fa76313452747a1384596950affa367c4a3e6f5b179e750018a7a","priv":"4319abffdaef48761ea2bcac50eaf80551baa1404b27b48fa379172f2fe8e1f4","pub":"0229358636cc2b80f63c7256eeb51b9e0bd3e1df0cb5e69ce87f15d71e16fa4a8a","addr":"d0134881f0c1f11cf9938920472f3d37e9365565"},{"mnemonic":"crumble danger tell frozen define mixture sadness strategy village mass junior kiwi","master":"0dc426f3c99fc31a73cd91f5c261fad7b70e2a7738e6312325686c95dd9df2b2","seed":"773955324075bed8d11f971096456a8557f8cf76750e48fa4423bf5e604943b5ad17788fda1afb47f03cbe208c79c8b6c38105538d6028b1ff4359e7f5a122e7","priv":"86f1207640ee12c8175e9b34cdc6fbdf2c200be9e03697fa82f8cf43dd8a6cc6","pub":"022ff8d5a67f1235242e9e143736bb950d391bfebc29173cdee50fd6826ca895f5","addr":"49fb80faca4a0537aab1d0b7ce5674d4490ff8b7"},{"mnemonic":"reflect mass fall habit mountain winner logic box cook between drift donor","master":"350db5a525a544ff7d82978817ce35f33ebb6c148b9ff6a9bdbd357a16373e97","seed":"4511bc8cd2b64472dbd108250e8d0efd825e763790bdbd44f4ab700c5038ab129e417ee574716e1b895cd660c72f9bc4f1a6a2846e7b09c635db2a51c22356c1","priv":"f2e5782037ff1ae1678ca2baebce674b973aec58caf7aa1aff830b372a6d6436","pub":"035d54ecb4a48285dc13346fe46cadd907e443c03e91339363b81c3d1988b09a38","addr":"6e8114f26eb00d95ea09ddc7d4d5cc104bd3ec41"},{"mnemonic":"enrich corn rose chest can figure canoe used pattern margin usage increase","master":"d38a5d82ce728c441f707cbced8d7b08d896ef9f37d0b563476d5500ca0008ef","seed":"ea926f98f2efb3af7bcc514969bdae01680e237424554b732cb37257e0b9f0ca1303af09dad82b0c967ce189ac8173901937ff42d0163310e5fcadfac1710c56","priv":"880b645884e27fd9205d82ad44c18fbfef02f205455ef818fd3beec79ab08e5c","pub":"0229eb380ec659c8964ca2d19196eb59804855b0d4226fbfc48f2373466380e1ad","addr":"ba2ea36646e0806378faea7ae0d1a691d91b54e4"},{"mnemonic":"coffee labor involve dragon upgrade route south guitar uncover enable soup sustain","master":"0dd39ec2f51c819042ad3fed701d1f982f599383049b38ca36da842bf5d3663e","seed":"f81aca2d700fedcc07990f1b9ecbaf194c0df5dbfd240437c06728bebf0022aac77b8b44f7863b13613b4bc5752f0f19e2a21617e5e0578e53f9198c2ae853cc","priv":"12c7b8c875fa9d0117b53e2e539584c9c524fe1519414a13062edb33eb712408","pub":"029b8bea854aa1d99e6564e5f4c9627a95d1fbda000a59ad3049baba92a474a5ee","addr":"eea20101f17d14b6bef65b393a49b9c558f5b87f"},{"mnemonic":"dash clutch smoke chapter lobster quote fat negative desert labor rent basket","master":"a6dae26374b6e165be90ae4f1759fff4dc4da104493a21c4e062d42a50ce1b48","seed":"2c4d251fa5b3a634ddafccb16393730cbdf1a1f20b44ddfa0a25ba2e5b6a48e8338e5e5a8a0b65bafe30ae629126789264c98a4b02ba96da5eb3b15fe5a296a0","priv":"5f7246020bfb4ab5146674df950ccadb3b014cb8956e4bcc3b575f710b4cc4f5","pub":"03f2712cae90744dfdec3a37990221e86063620b7298778ef4cbac6f438764acaa","addr":"7d8dbcba23c0e04ae21d250c585f511ebb825ff1"},{"mnemonic":"toddler juice raise depth club rebel weird portion void minimum game typical","master":"d56bc0aa70e0e583c13ea0edd4df5dd6f3b02a9a0434b0614f5fd9c2ec029b58","seed":"373286db33542c525710b01bb881158a7a1c723512596414370f1547edc08a11738d855569109b2249f927839c53361c8e0c8c468a62421c998b97fee5dab6e6","priv":"3db2ff05ae17ae227e78096b9803281f9332857f555dec941153805377f38520","pub":"031a9ef5c0a80f32c99f8c3af49b8fc51b3902ed13832ffcbd0f9527e057c0d56f","addr":"e5b70525b5b3c325b9a2a044ef05452ea0dd6821"},{"mnemonic":"legal lizard easily dream push business village network bread solve predict surprise","master":"4495fed7ff0239ac3a3ce75f1ec1e81fd3c8f7ac2c3a2a9d94f0f82a31042796","seed":"a709e3741759029624f534c66e8d8e56bb03fd8df960fa4776daee1c61810b96c495bbc3dcff634ebf140dcec9f7da9151e09856ee16ba5106cd7c1088032ebb","priv":"5e3e0925e33311aacc94b1d29f359f449d443cbe618e0a689d0c40cab692af21","pub":"03e2b6a2f99cf742f7c1fd356a6948df231a75fafb3cc471f9ca4ad00ddfad8c2f","addr":"c0980871c3f7b15830fa514167c90999279d496f"},{"mnemonic":"draw boat debris humble cactus method duck ask author soul busy assist","master":"8bbae4af997d4735d14c988cba637bc041b4b0907c5c53ecccc1456b43ea79b3","seed":"f05a91da4ef94c81e0bdd30ed6d9cd09cbff7013c693d6e8261bf2eb3cec9568fd3934551344ca8c768bdfdc44fd1b30a082bffa2c1611654320948883785e05","priv":"659c3413372935b99cc972629253f37305d258459c1a92b7fa81883ceb6dbb54","pub":"025a5af583aa8bf4459c72c9665cac772cad9fd49518b9080f635a4de283542588","addr":"36d01ca7b9f3c37ccd529033c15b1c089b877d8d"},{"mnemonic":"between equal crush suggest spoon material poverty diagram forget click company call","master":"3f2d83ceff7b98467d9cb2523820f55d22abd1700651f4b71ad6856c029ada7f","seed":"34e2764bed365dc73de440475c23b18cd69750977a4197a2efe374ef552a9c56eadd6ccad970c422730cd51e5ab4e051e4c86ef4db2284256186fdfa0ba92434","priv":"62febeb0325ae75eb0c71c4a3ae889a4a274f4ccc361cf0829743d5add3b084f","pub":"026e528216c24173250fb71c73019ac45e6171dd4f9d8fd97b0933fa964b966ac8","addr":"22aeb188b3a21507a27b35d860b583d9d844cb91"},{"mnemonic":"cram palace round input disorder armed wool cram over abuse order grow","master":"5c040bed4bfa8520ccdeaae710403b3ee7b77e069536bd87babd93c09177f9c8","seed":"df3911a2a01087b8826327ae368abf4dfac62258a1a7a91cd4ac64067d926b3ab89deda5a0e5539d8c0071d14815e2aebbb913e2e506c6574ad973f950049d91","priv":"87a97c3f977b1ce0b9dea5f2ca8671ab6830f9dd4b3da8195e603b7549f529cf","pub":"029722cdb8ceb0be8456ce4dcb24a4fafb1028ebb4d35b4af757bf22e8539de367","addr":"eff0f2517523745b0b404f688dc048fee89815de"},{"mnemonic":"donate view volume faculty anxiety degree brother cheap film eternal hurry debris","master":"762647d305701dbcce0a5bb079077eb514ad72981fc8489c6cdbd71991d24179","seed":"566c1fbaf6ce9a0c7352e903069b332aafb438ff086eaeccd1207b6fb8a9f0a0a4279307fa987a905ece60a04a52a59b3db45ec15892ba76b2308cf9db8e36ac","priv":"c0092fbde92e9ad29a52c825b8187f40fc5e4ca7a586f4b5b4a8805f0554a0b7","pub":"0340718652a6d3d2b791e79fa91e96f60eef740d10e3db8c8b206457f31b1a0aee","addr":"315ac67c85646a6ff00192c6752301f11e19e409"},{"mnemonic":"pattern much pilot choose prosper spot shaft camera unknown target wing movie","master":"1d04a744f4e0ca2b180f5f20ed34bfc800d0c874d232b5eee1018142fa612b15","seed":"2e1bed0a31e13e8f13a85a35ec1531a93ef433c96338f3e6533dd13d5bdae15bacdbeb954f9613fd4dfb6a941357fbcb5908520096502ab4f6edbf0c93e6f559","priv":"ec42f7fcebafba29c6d692ba732e8060d7050d7c57ef67c0c9d8ea152494a804","pub":"0295575d1d162b7599175bbb5b213ec3e79d6b632f5e50b6ba84e6a2ca15d70939","addr":"ddaffeebad79dfb4df2e2e35d9b6928900d38179"},{"mnemonic":"cruel tooth rescue step entry shock uncle crash possible inform inmate such","master":"f02e38437185794196a7822f0e4badce8644354fcb5d03e337ecee7ca0241df6","seed":"6dc6d27c01e91879638ef2281c904f2b3b0df18b0231c16f1518b63b39ce53c59335cb858b692f50decbe6fce2617434c927cc09d428a98820563438cda13c50","priv":"339120a922594b577d1f64af46c9dddbe0239a1ebe0187569c4302c035df4996","pub":"023e91521223a9a95c1df315c36ae543e606f426e1dc0b4938b374af5fa4967fff","addr":"c5711e1ffa2cca8f18b9be910c4c31330b8d60d6"},{"mnemonic":"evil height seek edge session require obscure begin skin outer foster able","master":"71495c08143478276d1107b9a496ca0befb1663524e46ae824b65e979b14b22a","seed":"2d209c72dd757b948bae9ac1d69014bda27b76dc890be357f542d994ee79329ea51114a1f721d17751152a1bbdd5c5e836771902ec6113c716fa016e30309a31","priv":"862d6335c9d39a65655c3fb644d71f9e4a902f085741ea4df75cd36afb94b0f5","pub":"03004f2c4133b0ffd92bdb3fef5eedd75bf04b6e7e18c0dea3204989476ad3762c","addr":"5d422b55f2091fa9e350655b2e550d209489318c"},{"mnemonic":"gravity sustain speed quit clock cage cupboard radar injury unlock sheriff alone","master":"44e4470967f781784b98f1e33d8fdd16568d1d43b1de044541a8e0821715060e","seed":"6c58333728b07bcf95ec884cb2ccdae5ec12dd67c3442044f7680a87c47da325429bb280727efbd848ee7f8c5fcdd433da0e9de39b21acb66938427ef6ac47df","priv":"37a9522e106495f859db94f5b6efd4e98d49e352b4e82cb3fd6ccf03bbec4b90","pub":"024b03123748ed0b4fdd8f6a351d1ab6a7167396fdd583aafc15233f5e79e3134e","addr":"62994a9de9dc8b9c9269287b63d847e90f519d59"},{"mnemonic":"fetch uncover sibling unfair brass explain sorry wheat talk web news exotic","master":"1ef8d0946b982a3233328040bb94e8e8cd0d5fc24b345f55535a8e7a92c22b67","seed":"f5b3db4d9c5686aff4eef0b0eee3cf88c4ffecde0e9b1c6772d9071fa433d5ccc9173f2f9e95114b27a37a1d91869227f8cb46b3ba26323e237bdc7a2365761e","priv":"cbb0527d80293daa1ccbf26c5e8f117123a63c0adf772bb80700e2334690ae61","pub":"0271bce67767a922d141970501f7341e7ef0f5d877df908c0c06e66000b94810da","addr":"368f8cd8319772499a4f2f109d440c2e1ea55038"},{"mnemonic":"follow actor noise creek afraid normal exchange universe swap draft cake forward","master":"7a443b3ca6069d981559e8cb1db37aded7d3e25d06f2f5ad35867c2086ae4cbd","seed":"3189fb459fb30288ea67a8cb2a46eecd8854db40b7f5b828254997301dae372d05b3eef58b0c670b510abe11ef7fa506b74a4280be94ebc55dc891776599fa3f","priv":"17ea39b63689ae32dbddaa2bae52e8fbd79d725a6a2ec0b56c432a90a1036bbf","pub":"02c3460e957acd5e228400055e9e1b22fc5fba87b16212382ec78b6131d05060b3","addr":"4e981e57f9e23760cadf381d28eb56d225f8b785"},{"mnemonic":"pulp fire pulp salmon finish question aim unusual casino super label soul","master":"3041f6724fc8fd54913ceac5487cf0b2a1c95e1d2cc65272f99d1d0918d73c20","seed":"424b5c69d42e95405b4d78c60f8c4541fdfe0600214623631154e144cd2ffcb3d6996fdf8838a07947a6b08d9792e6e883820399429d2427eaf4ca3cf2311e89","priv":"19026cc4be5629f8580b7cc5f01e36cea0cdb35a933d9871324b53eb9e4d62cb","pub":"0355a17ad503b793fd459e58e7cd85e13724e155ad487d9bbca7e49f939a89d514","addr":"e26908acb2f197f61f0036aef79f9c2b8e67cbd7"},{"mnemonic":"draft clap afraid census image debate pizza display sweet square today floor","master":"146c029ef74c9c9d00538cb03e70ffded59641ff8cd695e44abcbd71dca0aea0","seed":"a000df2590dc0b74a6b1bdc868079ff3172fcb9f758f7f61e9963aa49bb9ef1715985f3b88b0d1b22fbe5d30b2fa0dc489c19ab2fa42c5e62734585b6b35f212","priv":"4e39817ee6a106cd3b58666b9bd419c246caacd755c302c5440f7ff8b59a3e20","pub":"03532d53d02bdc71b0ffab4f5dd3222bdd8b49117ea8c10eed11882a21d604c72f","addr":"4ca53567a3b12f8bdc8cd66b1338c3760cd9def6"},{"mnemonic":"virtual search upset mushroom bundle vicious soul fine decade reflect basic nurse","master":"1e7e15314e1cac1584fc5d6fc5609db315a3a63c1baa96afa57475c7e05b77c7","seed":"183399406bee3c1b8c11ec94a8528e0c26a7c22926f286e320461809f84976cf31900b436022acf4635066c55bb793659254c75d4f18d692a07e20026d409986","priv":"8a07be43ff390d981394dfb29638f2464bded05d5daeb3bb54a93ee949f2da36","pub":"0336378e1b67b1588c6d5e279fc3fe58115cc24dee0cabb5f728acecc8ac6be8cc","addr":"e12910be135809fb5a6314212975564422d98445"},{"mnemonic":"venture wrong wheat oyster buzz cluster abandon rescue alter frequent way scheme","master":"15d4683cb037b61ab1fc64adbff7bea44f515683352cdc3b7e8c6d97700d66c1","seed":"0ea9eba247cce6f936ca4958c64cd6f8f19c3f68914018ad61ef9042a4fcea4058f32017ecd0f672cc8ace9af4d06b59bf2064983fb4615edf912f73343a734c","priv":"47006c978ed707415ac9da1eba861546e6a6150170db9699b585648dda4c863c","pub":"02dc09d31bdae4560008e82db56cd81fe95b6a6dbb87020117a98ea071753659d6","addr":"4a5c5ff9661ef26136b09a8e6af9d6aae0188e2b"},{"mnemonic":"consider sorry keep source session simple solar acoustic crater model hurdle champion","master":"2c3331a974819d6f38071aa2c790c42ad7e97111f5092b00f972859867cfbc5a","seed":"e4f33149ee0eda7a52f5f64d1c8ea945058b2f3b2cd0a0d8a85fdfaa2aa0b559bec8bdcbdb5703dcf2ac54ba7066f4d6c95b03140680b1f1d30a6305e4cd0b7f","priv":"3030acea65637e530cc39df608f467b4df6a47aba4e241c7579a608d8d53f12f","pub":"0340b77aae056f3e3e7e7bcd670c05a3c8975efed4e7efa0c0932a48031a242778","addr":"5dce4e49e053ec6443fdc36f11f1f9f233644cb4"},{"mnemonic":"salmon allow rebel eyebrow siren remind mango round task ritual exist course","master":"7393e3b637917023a724ff52b1f651f39da8a0d860bf20cb810eb635ca348eff","seed":"657dd9b458793c826944ce50c00f6cb97877543ed7dd6b113cafaa7971704a8ca5896fdb5118aa09c52cfd6b28bced9446a86258cf432339549e31b3abe0e279","priv":"46c0e6f6d527a46ca2b44d0d6892dc6c816bc0f1240b10ab2ec9f33050e35666","pub":"02cc668b114070164065c79990db45a64e4bcc5052ab0ca65a68f0dd3c107e6937","addr":"0da2a43e892435f79c2af7d62cc823adfce0355d"},{"mnemonic":"camera casino cigar harvest prepare satoshi close ill suffer chest parent urban","master":"1f6eeefc59b6600a739364a6606ac2c3a151b4234f1edb6efb97da193865402a","seed":"44388f05937f5cb3b47893b75aaac78ae919e4aba29f0a6934ef15d6c7d1df6e5afe36743320856181b5f0a8bc02e731ca83fec8dd501c9c845a1f0325d74a20","priv":"e6492972ca82c2cd62006bafe541c0ad5c6bbb01257600e8168702de496f3e37","pub":"0219ea8444509e7894ca706edc46a522244acdd643bb09d3856db3d9fb1c9821f2","addr":"593e42b50fa2f4491c831039dc1b4489333531c8"},{"mnemonic":"staff myth increase tornado student scare awesome fever promote vault write head","master":"5ce65c1772d4ee171fc0e843ee7b6124868d25c2cee48eddc73e92b805ea2239","seed":"88c5df5805a91765a045019ad39767a4aae836e8c0f53542c661934c3791f94b9d35cb9b1fdc865deaa6f749e583176ef9f114774fb0b59c0637d1e66dd6694c","priv":"066f7c65cb33bac2ef5229764c316ed587710752d456881dab54bae2b1ae55f5","pub":"0263f5acf96f7e6c02dcf040fa765db8fef8ff317400344cc92fa3f5d58f19755a","addr":"fc00f9a09aa3316fb67dba9e08c66d8569f055e9"},{"mnemonic":"during smooth snow please surprise winter measure weapon bench possible write night","master":"0af6eee6b3acb361f5743fec61f7377ca5db5e90a303484e7f877ade8da1e0ab","seed":"104ab4eb787b2da19876c47e1372bef860de1535ed30deec9887075d8f2c56213647f0e8d6b472b23f5ab6dcdc1f97cc32ed2842a0745589c196883967f2fbc4","priv":"0eab899fad8229fc681fb7c86d8102d4074c68e6503c644790125bee07669d76","pub":"02d13bfe147b234f2a81e3e2ae0e630f6be4bd56fe44dbf59b2336c689024b771a","addr":"86a7e52857c14411ec4bbb6c850822b7bfc8b7bb"},{"mnemonic":"equip clarify march rhythm supply attract dress sell clean galaxy index river","master":"aaa85635e77e16d5393f4ff5c73b5556b36ddea446f41c5cc3fd4cf6da2f324b","seed":"519f319e5c87b49923ef60a172b731c50da1da2eca2dc130ec732beaed5dcf161c2c4c98ec20b539259862456a7ab2c5f63d7789da98dbcf01ed23a3be7c00a7","priv":"b42830645c0a8c5fb59994bb7588e8fa80b6a3b95ec223d459a6652a9f3bd641","pub":"030b9ba15ca8ae95d10eeabb8b203b6253c0d08489c02dbe255221c42b16ecd043","addr":"5ac5bec20480d7b9007c9bd184d064ab6b1c9c75"},{"mnemonic":"session hint oppose damage illness metal combine bomb cargo unaware gun artwork","master":"d6322887157ca3852f75204cb3eb60ff3eec39450913387b03ac973f5ff09ab5","seed":"09900b51d5c10504fe63272bebdec8c2fde49190039916839b106af4b7340595cd5ce7a6be9866df28d0a40618b23d09a6f04bb963b05ff1b7e272bd0f0beced","priv":"3f012cc4faabdba2abbb64b9313d0a574b8b31c1d22f403f1d344d87ba3246c6","pub":"03b4a66483e09364f2fe2d905fe5d0d897ca32752df20ddbed0206e383bbd68810","addr":"0bc20be767a401a01d697c5afbf331fd7b3f4acb"},{"mnemonic":"gate credit cage whale razor come opera net speed dinosaur fold witness","master":"8e48eb7d42fbc6c30601ab45da446ae6c0ac2e9b709ac428fe1f98b5c8adcd28","seed":"be8b77e358eefcb5610dae1b36380d25983f1aa458c208e75a9117b507fed28975787d4531cf87edf366c29798a4a6d8b44d6dbd090da8eefbf6d97477b64ae7","priv":"24ef322d8877b9f5f352f8063498527685de6b7d056ca7776dfb1ee34c0696fa","pub":"03389070a550617f89cf46c1df8269a154bd4811ea7d519445ac1e7e3e3f9ecbf9","addr":"45d1a0a5f79d849577106135f7065782e972ade8"},{"mnemonic":"belt girl tribe accident machine library verb link host wire hurt elbow","master":"d604893e69b68ec73d7abee4d15303863ae766b867400eb6cc0c771e8eaa4a16","seed":"ed3677dc17838f9720d5c574a6c70e80c185a5df1faebf07c63bd64a3cbb43818f7337469d48142df4e6d0254fa73e8a8105c6306568bd8e3a1fffd2c9d85885","priv":"cc6d78f6b72176d96a3425cab46866499fc57a8de3a49d5b30030378982911b2","pub":"02926ca73be56e04b363daa330ad51514595250d48d8983ddf29f74749c1a81797","addr":"00cc426c8061740249ff1219b322f104f548449c"},{"mnemonic":"kitten monster sugar game word lion census purpose defy rich either distance","master":"d697b6319c74c77415f784aaa6b341a84ec08eaac0a3bbe094d5cef9be94f673","seed":"f6bcaac87b81723ee589e635ff4e5a5606cd28113eab6846f1e7d5bcad758c1af1c8c77c111ba1cb502f33418f1436220a0a080ee81c5dfd012be5dfb0bec360","priv":"cdc283846e3c5be0b327e48a83fc72d85521bf51321697f281333b6eb7fa83cf","pub":"03711ad3d292efc08729a820344bdd1efb9cd87b083d0ffd65b49f998d1808e520","addr":"71f678f7808db66273dcaf51fe4875fb4c47c80f"},{"mnemonic":"fury tackle glory welcome gauge rely spice profit east science nominee expose","master":"b04bb080a9192b41dd7ee5f9bbfca1396970ba10c54faa1b7a511950b2ac85f0","seed":"5c6ecf5aec8669d62d5db9e39a5c94167bdb21e9380f8efbfc967420a71e0be1d72553a2b84bac9b8fedcbfaca522b82b7b80b531615b9658379c236cc4bc5bc","priv":"05fd2f8cd2ea1cd0ddfe2acd25e498ebd81b902d51935ad3a094a2f2c9c62ca0","pub":"02c4730d47f1976f2a6412681ae6cceb97b899c4fc514b67b9070bf236e906bdde","addr":"bf3e06c5713080e1eb287d2eadf49de120aae6a6"},{"mnemonic":"young chaos must mom ginger hard symptom ethics father rain join time","master":"d9e68439465f5375de6e132498239c9d0f67f7caf16cede036da3fd1c3905522","seed":"4101de8d7cb1dc3176ac0781e94594a37b894ebccdb9d934bac104d7b22bf68d863fae68df1734ab10302025e53357b33ceec095e59505a1461aa751ca77e5b6","priv":"e8512f2fdfbf6bc1e125323de28f9f35931ab760bfbb2a736f750e3bf116bba1","pub":"032f51ba96193a6e24dffa85d748ed2b86e3677112b22da1d6dd5e2d98f987f0c5","addr":"7adb4deb8d4ee9aeca2dcc4dfcd5d1dffd3a2cf6"},{"mnemonic":"dash ridge ten when erode certain game rural canal race surface envelope","master":"fa20b9bbbaf883069a6a282b30870bbb02c8aeed3c611dd3c931bc217326c210","seed":"276e9b97f203454480976e1d86d4abca6072d05e4bd5b1eb972fba03cd6698afb7212e5fd77ff84bb8e68d45c641063550bc8ca208c00604f609a5770fd69b15","priv":"1d2ddfd078682c4d3950ec841b8555fb37981313d0ef69a7bff16c110171f71e","pub":"03f0d1613f82a900455d6834f6a02e037e3d6d7fbe08b1f3a278b2a5958bd13490","addr":"b190466866cfab3ed499547c88af1372f84ab61a"},{"mnemonic":"spend echo addict brave reason tell valve emotion gaze seminar entire game","master":"3d139abc58b8022d8fb2f0c622531874064a80fb4ad795b024226420f30f8ff5","seed":"d9d04d4207827877636a1a077468d2396dcba6ecd3398cdda7d4c15c1365518a5131fa12caef14a2b23702957b282903dfd96df19419e4ecdccf7c38487a0c9d","priv":"cd5f726ece1eb6653950ae42c9fecb053274b692ce6a58a5f630716fc9cc172b","pub":"03e79f46caaa31bca56700d91cb366428839fb09d027d13001ae723461e8575bb9","addr":"35c04d25b3205e9cdb5283b94f328792466ecbd8"},{"mnemonic":"moon argue laugh point unhappy long bridge water naive suffer curve duty","master":"72c22a1d7ffb152045afab5ab7831efd0910c0a4796b20fe9b741e2a06a0562b","seed":"c77d143d6a040b08fdd3a085c9fa097508137cd801e480752dfc55f776179dddf01199050893ca833af63f6595fd60b4d14944e31cdea626ee30777b681ebb66","priv":"af0e3a2476271d7a31943b44dbe9affb5c04690c2f9e1a559674f028a8cdb9ee","pub":"038beb9938f2f7bd600f8b0b48d85ddb9a09054534ccab4e5a3cfc36523dfbdf74","addr":"a7799a4603c1cad8209f6de4cff709ffb5ad240d"},{"mnemonic":"ceiling mother twice mask pelican glue such giggle session absent sauce copy","master":"1ab59e2748679caf59d4646f51b8cd7cf27c9e62160bce71a2da081d57e90a53","seed":"f46d771930a5a1f69674aa4459b0120ffc52f961d7f05a4f0629e580e3027e9112b81c582a74f92a63a0235d275be17a3ea24e8f3d86d2f460142cc3c075f352","priv":"2dbe6c2f1f3389a29271ed7ddb5d5b6aeb44cd3d762b9c5949f981f130c096d6","pub":"03da1b7e3745edb58ea53dda791d7dabd4945343d471f41b706ef2159f4895b234","addr":"14a8aeb393e7a99b53cc3661717b6a550f4ca30e"},{"mnemonic":"siege welcome clarify bread decline educate off snap canal north glance flash","master":"fd57e9d99aae7bddc7bf2218267db21683280d1c1fcbf1d0713d35c872dab359","seed":"d1771068274d476b8e3953ae1dbbac392157fe72dc01d9c1cb66936f26b07fe9de52c257f1f8a89ad5677a786a32b231bd4415a7fd6dc18ebc70d53c16d91f9d","priv":"8d0c094475b505e3c32bba7ad6817460ac20c5e75e4d5d0899d96fb2dbd8f43d","pub":"02bb4a1051ab8df516ba2b5bf42a99dc1a153127312a81f93b16121d2c60dbba1d","addr":"43b7281f4f0495f6ffcc129e1fe90cf772cdbb00"},{"mnemonic":"total wood brief sail top stomach phone silk soon flag beauty equip","master":"2d3e2c155708e47a76ee013fd8bd3d62b17b467fda08869fa5b474cd622c7e87","seed":"98cb2c832f8a2e59601b5dd85c1321251fa576f5e8b9ac250d18e45dfea7a492c80918d864f32d1fe0f3dc24fa1b8eec3cda8bfc526d4826e94a7ac352edc705","priv":"5de85e11fa81b39f6cbd36182259fa33ecbdcf309e2256a1ce91500a1c28fe91","pub":"02dc14302285378aa1783d6395e45b37aeec4456845bb90dd2436a15c601abf050","addr":"bfac65e04a1d9f0905e0d0cf87ba1531bb49bbf2"},{"mnemonic":"junior side human tomato army twin tired mammal sing evoke tape fall","master":"0a491a1d250b31b44ecf38584c65a733e785d65082d693847ebff6f7b749aadd","seed":"65c7faabd749b66f9f16b234142acf734fdeb1fe7c9170355471c008a3224c40c5c2b77aaf516f91fcf17e73f2905f021354561e56ccf08a9eedbe51ce8e8fc2","priv":"40dc50171a806155da73f7c5cab57f7db270e225c33eaf0665c0067e1d2f7743","pub":"037325819201f9eea88ab9e6856d2e60f02c41d3a07c09fb7161c42e05b9db824a","addr":"9acab1c1329b243a5959cf716dc5f29ff1a9bf33"},{"mnemonic":"fitness wire sun minimum novel scare response ten profit breeze equal wealth","master":"0292d1ccab93ad054ee3ff95f3fde715cbfb9b896894b56193003861f4403763","seed":"ab34f068d14286ef45af4f3339ac19d8704d84a3f4af2c00092f431f919252487759c7aa09511271336b3a40f446087e7a63d1cd5603244124fb746160ffe872","priv":"39ef24672e90e29f268369bdab5aaf09786efd7360b535bb4846035b12d1aa27","pub":"03db46d9a6c338affda7db18355bf17ddeb8519a59e193bfaeab4fa522b4124288","addr":"c3cad6c638d4f7d0a75dbbf9fb2d170f79f1cbf5"},{"mnemonic":"quit present half acoustic uphold buyer measure matrix uniform black play vacant","master":"6f8c86f53dab7d379e621daa00a25f6123d43ef2452ee6b7c20e43dff1379409","seed":"bee800b88e86d04b9e755c63669dd4d324c0640e1c121427cd08d1bff6897fe622320644844fd06bc16fd9bd7b981e473cca7cadebf7f50ebe3f917c0721b988","priv":"6070835567461840e0b216338b4a08313cbc3d8e805cd694f379fa0112975523","pub":"0296271e75096d7bfb7393b449318613c522774e7b2d4e0eed6161e80a9376bb91","addr":"3885ad9e25c274d8e461f4b685ec921aeea25b80"},{"mnemonic":"endless blade swallow bird faculty group rookie betray crucial amused gesture pupil","master":"f62cc9bd1a5d26309ff51867edac4548f63e30630afce94a59d94d77f6df34ee","seed":"f4100b5b36d63b0a87ffc828277c8eb2f0055d2ef500b402572d30cc23418960b831c84566153155d33eeb8ce65ac191882810a1281e87c7748bfb592103582d","priv":"14125462458c4e981d9dd963e67965ee70eaf50af376daefbd7f89a3d0cafffe","pub":"03b64c625b503104cb0f9e8de837c741c4952140348cc5d7d1ff379e35ae37df6c","addr":"64d529a1cc4a11c305c8ccbe24217f52be17a69e"},{"mnemonic":"evil lend heart deposit index prosper mammal vendor expose sun arrow school","master":"d3402de3b79b24291822c2737da8e7d760267adcbcff5af52fa7c33ecf199acf","seed":"5062aebf0c68ec4ae51b8f9bebe4cdca4a07989ed9a96888205a84d749ca90f8d9f2c992862f7fdb4bfc3fb2c590431c5fec415abd9a2d4ad04f7504b90a9081","priv":"ff7fa17496fad3c29afa98d427186cd43fa9aee71e2a81d2640fec87ebca2ffa","pub":"037eb47194d9fb1e61a65e399d06bc7044d02097a0e5939581fa9b15346eea38ea","addr":"8e9b1eef983e035d41aa63ec276454a075c52db7"},{"mnemonic":"various cruel sunny human sponsor seminar stumble romance hire cabin blast rich","master":"25f93ffcc752c263058f195fa4b2f80c46aaa057b399de9241c0fa8cc2d3ec8d","seed":"89ee6d4b8a328ec819556eb043c769007e332ec4ae0309c6b6f82ed70b725e9ac8d64cf1309ce0ebb0053ba515f6e42d1273ac4d0d1b9008b9375844a9e1ed24","priv":"4aa30facb3367721c7e39c3052e7221f0a926a00d00898699c483cbeff39e407","pub":"0312c6e2800eb33da7459a510d02e0fc5c91778c115c535eb429c2c5797675e2a4","addr":"9178f5d44bc450a7a1fc5746d17440670fa0eda8"},{"mnemonic":"kitten rabbit warrior replace dolphin banana aerobic arena elbow leisure slogan panel","master":"28b0f611c4fa230cb47936546853fb9f0e13bd6a4417b5bdfba9c85eb80313a5","seed":"88a78a4f882820e729d42557ec5db0984aad2aa40f535ea33416b0b89d25511fe4b6e37cefd23acf1ab65eed77b0c6ed2e453a2c7e8d509311cd802eb267200f","priv":"3af577c50bf57b6f44686af34c65b683c305496d1799c7c0d9febf9dacecade8","pub":"025901819b5c97d505616f3d1b5be0923564d5aa627885851bbef7b4efbac4f95f","addr":"9898d22edfe40425e714b877a5edf2d9ab5d7172"},{"mnemonic":"shy abstract heavy silly excite response figure math travel use cram dress","master":"558875deb7ade8202aa21350c8a98aa64d383c4b8dc6315a5bc149823398c8f4","seed":"256d310717830704992b0767827ce796310b3f561f5faa152b97c6bd9ca1bd10505049005da5026e64377dfc9b9a23b8f71b2dd8e4ae0644055a04b650a721b0","priv":"80c1b4808495fc23f7fba2bf9ff39a4b084371807c61ffa6f6b60cc863bc8fa8","pub":"02268631554db3ae0b7ac58b2437556d91aee4c2ff2eaac5e4a3fd6ca6d96eb960","addr":"e1b0517748e58df2cde812d45c251492008ae499"},{"mnemonic":"tag aisle unit arrow neck knee border plug order decrease corn hint","master":"67412592e636701931c0b0723451ee325db3b1b7d63938c83ab9b4aa5630be4a","seed":"590e676b0362db643cdac3687e67274fc7f67a2f3a6f274da3e8629893b1f474fc608eb2928fa2be01b9760807055ba11a7ca4b52a28b2f66e05bef7f09845f2","priv":"1cd36df351f7dd9b4746bee1d59c42f12b21ce84b9979e39b3b810ba95d13e56","pub":"0217468adf9b7f74d88b312883787e6baadeacf6436986573371bf19c359ce047c","addr":"a719fcec68779b1f0f92460e511739e3bc704be5"},{"mnemonic":"urge order bomb glance dream diamond cute quit napkin swarm oil taxi","master":"e7c99156c46a51a308bb59a9be9cec9d45a55a8f10908f2294b4a35734c24cdf","seed":"a31e29edd9da883053ab020e2058d482cf2a63b39a7d99f47a5972820820d5558f24bd4d86470f1b8f6d1707c059e2353c65ee69e0e2924376f84f36e77571e0","priv":"e204a5c8377829edb3a8866e028294d6fa34c6dcd76d10cbd857afe41f9f6852","pub":"03de7949f7a90aa8f21731e2979b684c6424537283dd15881f31541f14a0837042","addr":"fa9f6d11bf1fe75282dc336ac24f790086794ca7"},{"mnemonic":"drink combine way human stamp code chaos honey decline reopen candy stumble","master":"902a5423ff40734c67ef9ef008e63a232d1c0e30a8b8b75d911a5e5c31be5725","seed":"c5ee4ef92fab9bdfab9e859bd603a9b293509ae3b99427a3db2b3eccbeca2b2d717ff5d5ce010db0cafcf261e6addc949bc3c0187a121e303a0246125ffc249a","priv":"59e235dd2d86967f6690fe2171eee062c5e786ea6a0060069fab9dcdea5bdeb7","pub":"039c4adb01d0bffdd50a34a458ee58e19ed81d3f22f740af2414594e42447c9de8","addr":"3ae7c41fe8a65e527a850a44a5124597f5e43f6a"},{"mnemonic":"will confirm boy glare draft hospital grit marriage hen radio coach cram","master":"cd54fa9f850f2e90ead19946218c1c03ba1491d1273f6e2e59816e50ad80137c","seed":"1ac5cdf381522c28ff90b993d3a3612e0f91c08b89b11c83315ed78b7d89e7a342621344ed75a7bb1d996487da8b60ffaa75ba3ef504814636471fa017f76b06","priv":"c63babfa6c2e301910bb8cb846259aa0062e25ac8523dee9449354e9f44ab49f","pub":"0272029d11d7a1998e79230a4e82aceadfbe29925639f6ca6dffd237b7c12a6867","addr":"eba6a2907bdcd422c68a04093fc5127ef2945cc8"},{"mnemonic":"sister mouse nose morning remain bike wreck reject flee depend foam oil","master":"480c68e256ac710a18ff386a76b2a3ca50ab4214a23d2e162fd473f40e48ef88","seed":"267c7df08090f9d95d26c130af19c37adeffeb28644cb449a39fdc2038a5a87341fc9fb78a91c9d19b8a4843146e79e57cae43b9d1d65042cdbdc8f97c22f02b","priv":"d6d76df9474b038eb47c93ce8bdee2163ed5906475bfe0d40b31bc19a501a2a8","pub":"02a70a232ec5b59daa30873a4c11a65848d6d90b5775e488b87d8829a368fcd2e5","addr":"dfdf9f283fb3e21240437a994ccf124089782718"},{"mnemonic":"mule parent ritual earn swallow visit jelly give sun family scatter lend","master":"946aee32749e7c2527a9d7066df275f6a58b4d979778f565e87db434a4d82ec0","seed":"919d5d8ecbf7c9ee555aec51c4079aa8a97ba7c6207be27a119b307ecf5433e0e44856f21808b1a7c65ccd7efff25eaccb445cdd3d45c682aaea9d8358fd398b","priv":"1ff4a74557f15dc78cbe8c3fe3b760c23c19c2ffa12e6fcb0c452fac97a8c1c7","pub":"02b880cd243da4622fd4084c0779a34c117cac73c193de6691cfb9783c23a13751","addr":"5157180c3b43d1127614fcee3c772b45f438a73c"},{"mnemonic":"modify puppy army pull trust icon suit submit fade game near machine","master":"5b3dd4912f293341f8e62b55d25a7f01debaafa1a8ae6d7d9e34afce8d534c7b","seed":"e73259b5532099bfdcf2196ba80baa86886343ed2a5a7dc081128e5d94232b52d3914a8fb9ee17fcbbdd0d2199b2febc3ee1fb430729a376f8106439d45718e5","priv":"5a502a6484aa0eb1f7d963d950574d1cc348f3f64b1064f0d6ae8526293b9f89","pub":"0279d6b5231ca7729c450b055d51f350ef370544b83d10e80501ff5063961ec425","addr":"54a6fb03ba980c6efeb0e4e6eefa8d5c06f68dcb"},{"mnemonic":"beauty fetch title weird machine section remove better kind unfold candy risk","master":"b9c854671b0922cd1c27f876e2bb2748e74d7e5c56f71b7bb24e0f121c312c51","seed":"223ad6102e7f9e49ae732fd584519ebb6c139fd5cba630b78d2e5872be280c5c68eb6ed3b5b09fedfde8cbf6dcc1624f3380ae464f1d30c2abcd8d8ff5157e32","priv":"9c0c7cb874257ee95038077d5fb1be111685c5a54c7eae74da353fc2d476766f","pub":"02be94467d1120e497f16254d1840c431ef8254eb6a0b1f8b6e63b9f482ae37981","addr":"1c3965d6dce5a86ed7e176420079ebd2f475871d"},{"mnemonic":"broccoli ring road spell bubble slush cable column boil wisdom glide again","master":"dfe7a6221acf8d8f8b29530792efa9ac33b94e352f64ed3244062651596b0b1b","seed":"518f8503f16e8e5810486d1ea5b70951fe6f17427cec5e7f68584d7c7f101d6670ca755f81501146f3969f1869faf5efc6aa639ce47cf1d337367ff2d5336358","priv":"b7c6e7af8ffb55f9282d13c51736270a9b488191d8e9a4999a2735d5dc27ae5b","pub":"02ad6e0ed23179b9a12019db3afda6555fb3e088f2cb91eaf53db823bb284e7681","addr":"cc65b77303a5d3d42de2ef404a05ffd8b0fb73aa"},{"mnemonic":"settle jar tag talent bridge onion jazz vote certain job high lounge","master":"fd3df0c73c84b19831fb4fef9b6e8dc4eec01c845c38276f369ae73805cd5bbc","seed":"6944f80e097b237b7eb501d2d6d735c644c7d9fe0de4a1d12665b27a1567d3d619d41a9a469622c57f2e7998af4f8784dc1bf30b715b6c867d61902103ffefff","priv":"93d91fee61fa1f6704da23dbd1ee4b5513399d1d7ad52c3a632d5e3ad5884895","pub":"0331248b1a2b3ac8919c5654220fd21a10d2f700b2bca6a16d94ab25cbf60631e6","addr":"8219e185c9dc66aa8ecef927a93e884494251762"},{"mnemonic":"say unhappy visit follow rocket bind capable lunar age erupt depart leisure","master":"bb776f6f57d90a587b76509d6788c1afc54b7a35a06ace60d7d627605e462d9f","seed":"e20ebb6b86a37149a20e0f07a637de61af6d37f76d9bd84c210c8c06f92d23e167acd0098be525e943e2c4e7378903f8b4572190ba1c6b37ed40fc023b355e93","priv":"0bb90cdd4f552b15991e6e9c1546d78b4445af65e60d6cc850b7d4f64a6406d5","pub":"0342b5a2ce673cbf8610f049dba20a0c7d92091b7df857951aca402e56acda8a8b","addr":"1af59207b0004314be04dd208cc2154e06476ed4"},{"mnemonic":"next broccoli cluster someone just you crouch monitor crack tribe slim cloth","master":"87d2484fa935339252c8b0db3b4604f42e12a48ea00d22abccfc8a4ae9afd60d","seed":"abe12329f69d107732e3a3eb4ca9bd693b1ad465a042530031d0cf79e4d32a42185677250418809d0cf7fe7e47e0deeb76c321a8b82060666d36f8a79d68d2b1","priv":"9fe6b21141e8035d253dd8fb9e6009ef14f1680f58629dc880b50fec649bc00e","pub":"03af8824d512a243566015275cc2a8af24fae7acc538fc292806c2c95688797e9b","addr":"02f4e6e52415b7e25431c0af1f43f7dce05b08b7"},{"mnemonic":"scorpion artist craft enough whale maze copy ring search sugar rhythm few","master":"8700b2c3bc7b441f6600850cdfa90caa3fa8e4aa6c3091d9850c42644187c053","seed":"cecd5fef8caf60fdbab007cdcfa920867c0057d0c65b55ee569577427914e0e3227ab8cea26f50c1596fcf79a88a521721257f43dd84ef1d81e2ae4a8b73ebae","priv":"8dbc85572bf9b0f91c5e4f1516f3056c6a3608fd78e6b37e7dad0a0a5e4f6c2b","pub":"02947910def2d55c81ae2fc03727c62440713b0cfbaa854f3c7e9cc5b8f245a2fa","addr":"a77f593385c2e978d99f0a6a3d06e427f01f1c7a"},{"mnemonic":"improve help region hamster then raven eyebrow account sleep cliff copy pull","master":"e479782ba4b1b4f605fe2e892c6449a91a03aa8438668e22df211275a5644c92","seed":"bd788f3b47b98d37521fb5d51e35d42489fb83e21dc4f0fcf55dde6c2e1b561b63ef22f51cff2c190ef8b18cfab7af33df8e83d14d066c6b114404ba809869c5","priv":"a2deecc348654217762f8e5a422b3ab8aeb07738a75c49de9a1aea6ec767f4a6","pub":"025ee0f9bd4bfb85e42f918e91294fd9023831385e73ed06aabbbb7234d1707def","addr":"b80dcc0683ebdefb2a30398b0ba1478de6742050"},{"mnemonic":"bronze fix prison velvet sponsor woman vessel crunch forward sunset similar wedding","master":"608887c856e38875ce02b2bb7e6899698cd395db9ca1e19ebdaa0dea5dbdc1c9","seed":"66a0fc313ac72cc89a85bd4144b69061ca1e65f7d1968824f0cffe10b10380278428af5b6a114d6ce2a88e3626dfae38133acb02096d0b6ba7b9761a8c4a0eac","priv":"47de7838c74b2b1ceb138fdf96d455deaf8fc2550246a479ff98aa706b1d0211","pub":"02202887af1c72f72abe2754b6022a163b2abe5ee9f288126dfd1756067b03b5d7","addr":"8756dc9521ce9ad5e22d2612657e552ced185071"},{"mnemonic":"fame answer typical zoo key rail state chest snap stove urge collect","master":"377482e11aac4f724c3a1f94c8abef488f1807e3ad1a92821d7dc3f6377a2c3d","seed":"ffb372372dce3d525e923ba290828f0b5d12f65b241d5e3c36d431c1e1b3ef737f666abffc9d7e60aac3645a8f385262f2295b05c42a4c2f8bcbc3aba9edf5a7","priv":"bad40853765d64cdc729c94aa5e114fae54ee014517dc5231be8321bf7d93266","pub":"025d64a940c5b4dabfe233b552e43239b69dba164eac66b48a36f4e06915539575","addr":"f67fd1e04384628a47a01b88c399b30df8e5b226"},{"mnemonic":"expand machine nice damage roast slam example resemble tonight enforce salon benefit","master":"2e9614bf212cb179d91a224f1cc36fd4dc0a5be13eb5ef3ec614cd3f5db5be18","seed":"97c59f53a69f280fcf28110dd05e7510fad1d00e26d30847bd1dda99324ea2efa8550e5504f2f2648fef7f9c03ec58b2666b94269b3b5bbef1577f17af22ad1a","priv":"bf9962586c0636a20519a0eac17870ed0fd09862d4ebb563b3f445a179873551","pub":"027eb40d841c1028b75f21d593300ef57c3defdc258d17511ab086988240619261","addr":"d107cca0ed49d72efdde4b9369855d188f37a65c"},{"mnemonic":"debris scatter erosion dad quantum almost zone off bless tuition garden phone","master":"706940b567f1ab966a5f2db1d3e5eb832cb827a89c5bf2d17e9f3628ac6f88ba","seed":"b5caeb5e19c5c3e1e7a1074c3e4f366431d57f5ee5208aad341020fd33b2be38c2a228201949b6812513b28523cd82594a2db67177bbee6472bc5528a0fc01eb","priv":"671bab5dd3060bc813898cbc63828aacf50819c35981793fa9dcbe26c3427dc4","pub":"0283689f70b17659b51e2a5f345ae95e3a23fcc69941a5a842e992167dd958ab7f","addr":"aabde1e66f358e648444fa2a10be7404f1d6094d"},{"mnemonic":"expand fence want silk inhale web seed slide pitch fever online puppy","master":"2f3f69643bf40d05ff4be223ad7f05f0942166b629b6bddfe022df650b52a235","seed":"025608f609aa5f6662cea4323e4a4fdb4115f68d8cfd903886fbd561bf9bea74ec1e0c5d871ba46a1821efc769b2447c6b8d8f242fa0dfec8546c814f97cd120","priv":"26b51c99c8bbd84af26776dfb9a244114a66929f24fb782f195267fa7b35bf89","pub":"028d38aafd513f554facaf66eca4907f01ca8c48807898b6e142b609e93c3521cd","addr":"f5d92901099f9516401d963a0693f4d173cc2138"},{"mnemonic":"pudding mean volcano leader grain general because hockey mask solve frozen canoe","master":"a7a2aa088f904b0c44d1a307a17be86554cd9862f47b08f58205a7f73f93a011","seed":"d4e9852e81f9162b8fd6d1ce152e96a52b70d59289cbb8382cdb7bcbea5e5c5b6649aa6a2d138343092886474816c8e9c9f8c198d77986d2d6f7e1476f1499a1","priv":"31535d53290a02faa05f04894d6381b6edddcb7a374b19f8940d4581f9582cbd","pub":"03f89337767bf64bdbbca6a53184c126fca28f7613f2668a77119f62124f52a0b4","addr":"bd54d3175097fc470fefd66c7e5e63e7aa28cb70"},{"mnemonic":"make protect hungry coach tail female capable swamp alley one nerve nothing","master":"f171811d3c1b278279379244f480bdc165f5b645521749b2bf7b5bccb91e64a6","seed":"f8ebb80407da43b794542cca52f76b053175290dbc00751dfcb4539101bcf34369f76f686642c46728aef4b93f91f5ed2896b2a102aa3cd45e54591fcd0dd919","priv":"ea4ce4340c0eb740a33fec8198c22ec0064d72dcd74f85405f6d7efd1b1d0538","pub":"03e06202e127c7996f8367bcd0b28f779207cf222ec3d5d4190abae78fee5ed57f","addr":"54ef6f20caf4216e10a99ed446c842e3e9d90ed8"},{"mnemonic":"royal behave retreat force stable law cabbage home episode valid similar amused","master":"b2d8324833e37ae4f1a9a70dc33d070223b6313fe60e31a0c240b03f644ab78d","seed":"2448c418181d981fa42c83da24dab9d73b6a89dc0f86f624992ec9a982ab04e84989ff541364f4a289969d458364eabb08d51249c55ea16c29c6b65b5b95d7c7","priv":"473b6c4e1192b52fda7e64be4c34ee0197604c0e4c918d2a61e98f35fbd3f9e0","pub":"023bdc3332835493ed0258dad839d90c8503cd7a2a7097893170c6498dfaa2d534","addr":"d77a39d95f6204755a78c3b996c7bd84d1dc6a42"},{"mnemonic":"major dentist hurt task dinner exhibit soccer disease bullet knife hair nest","master":"9202dd767a3b88e0162803d54fb1e251ae14be8337829efc06770dc83aefa0b6","seed":"4c2d56edca18105e69c59b683d76034ad69006170a595c5648c84237ef0568862d5f95873334769be9937b83c5c96881569f232dec873e3947bdeca6831b1952","priv":"4db6777136a67a8279bfca36d0531a93bdc9e6eac4496fc20acbf78268e35d69","pub":"02d35a568677e4be8cfa051c190e54af69f8124daf5f39a288bd7a0baf1b1b4b13","addr":"6b8223d76a499b98d5bed2b146768569eaa7ab64"},{"mnemonic":"ketchup urban occur rain cheese bean need august autumn clarify kite chuckle","master":"8aa0b8b32ccae13b15ea9c808fe3b1185026c52a9f3b39546b355aab66d7f9a3","seed":"c910c33e6e009667a3d64ef0d10ce9738ff80aef32326d27b8f82bee0abf523e2940fc9ac6dcc27d10ed602fb60a99409688142fc18a9fab36fdadb6d76f1693","priv":"4541e2bafa8a4b3fcd1c9b49f646b3950292e0e18c2f1accda6d53197aca0d02","pub":"0336ad51e9c8d24af44291449aa86d4cb798181b2bdc9a2a6ae6a7c857a5d72c4e","addr":"9a37a2e3c1b6763a580a3b2aea95cf237bddbc68"},{"mnemonic":"shift anger harbor behave icon boring zebra sketch kid human nature learn","master":"139db45e5f8cbe86f23952b1558df3924dc55126119abcab216158285a645f61","seed":"1cea92117d8c90c554ae3ff517be704caa5c0d16369f68eb061154d59fb42ab9a6ea7ddcc62325df2c63ba0349e73a50c291edc1ceb0184012b71f2f5892a4c2","priv":"638fc2fa201498e1d76356acb3f4c5b42984c2c4b8619b0138426183daffb725","pub":"02272782c09fd51800d483c408ade4509c5cb83573293b873663a8492c1bf6711a","addr":"020ca2c2be203a95c0f7eade606d9c27bb572835"},{"mnemonic":"chat grain wisdom yellow rough swap notice range collect maple actor genre","master":"57363529ed9e9ae59ed408390581f344a7b974d130b23fc1da952983604e2cc1","seed":"d4b51a786cceb10f907941092f90be911c3ae2eca9924dade05aec85218baadc6b8137e86f4723b7500189529bc1da0b4cc95d1a8553cada6beceb71b12acaae","priv":"6245ecb65a10ed313dfc02843ac8e848a17aa37f6c3aa64007ff0b54b591e37f","pub":"032c33f1bc81371f8e599fa64736879a9fab286469e271d2fcff6f97b1b4829e46","addr":"4e076a5900d2016f08628257ae798a102c007e94"},{"mnemonic":"feed good spring pulse avocado smile surface conduct copper chaos dizzy describe","master":"003488e5bb876fb831b5ced5126e5c85ff6f98203dce52820acb139e31859ad0","seed":"e71271c88e445005f5bab28a4ed6c9d46f41adc6b646870c4097252e6f01d51ff9720d2960c61b9839cf29b559232b086ee5694252bd1fd73d601a27d78f8787","priv":"7702987362194e4b70c66b9d0d330a383e2710cdf863e5bb472c31815b6d9fef","pub":"02b790b42543e16b9c30a23baa39da3ed1d48402e51920187eaaa6796767ebe49b","addr":"778d3554fd4323ae321b6fdd0d907d28a4f0a886"},{"mnemonic":"brick wool tired another milk slight owner year electric later because response","master":"473c6a0dade946ed832babc01cac18b33ed7ea2303a362dfe6671202448a1f2c","seed":"ef22617d9f1ed62a89eb986d9addcb33c98d3da5e205c4cdca8c9b99f6267e0122d86be0b5f60c46d8c9f4c569c3ebade2376b04901bf8bfee5de83f6f818a21","priv":"7df1f72c7a5cf60268e760c29246e6e43f8168ab56b9c83d23df9923a3e51380","pub":"03de70b3833b9be36c88018dc6296feed7ae17d995af5b6942a67bd39689129498","addr":"27f48112f2be720f42706681bf2e97de964a009b"},{"mnemonic":"poem rifle october destroy castle scrub yellow brown soon this share radio","master":"bd39615405d3b2c25d023095975e07405228878f004b48be0a32fba278394020","seed":"578f2a69d418ed6bbe4a7639c6094396821dff23d1c26ef1a5452e91164e142fdcea44d63ec2eaa8d491f7b3757147f371ddb624fe10d6f7bae502e062671100","priv":"7cb45a918ecb28afef642f002cb9627381e1986ad90cbbe54aebb118724f1417","pub":"02ad197d4780b28d57ca50799d59fcc6956b2bdb24c8e2c2a221d5cf65007d2536","addr":"09c81b6b7dc3d57d239ca18573720e063144916a"},{"mnemonic":"hedgehog october thunder frown game aware reflect art favorite elite urge pluck","master":"0f2082a1d92a2d2ebdd605f33eb470568c7d82d0edf73e2be8a766d060dd61ad","seed":"9ecc3fc4516a37cafa09405c306bf19f53b085088a1d1cb0c54bacab3f21d4edf4adcabfa616137753a427c2269d3b3334a952cc5f4531980034433e4bbeeb9b","priv":"d3e3e9ee84d32091f08d7fed384fe3ec0465ec460f90a2749c69883dde03ec65","pub":"03b5af12849876b7c9c0e64833ea79c5b58f4450e4d67a99a90b3c9ab4ec3c8155","addr":"c5a46d31f9e363e348dc4ce803d44a676ce811de"},{"mnemonic":"goddess wear mail poverty exist pole advice blouse famous inform wrist pelican","master":"8c09d67d7e8691a66d2271093d7f74f5eb37729df23bf98525874b6d600158b5","seed":"093b6596b4986195e484e2d8977c8bdc20529c58527d9181c4d4e993495bba922fad305d8d4f13d9b5ba20c5e375dde147fda5aea8accf634d522e488d163c88","priv":"b028bdd6652a16380c61134fcbb095d372e63a117421fbedc46754266edaf916","pub":"03bb1f45e672d983a8856631fa8193422820747e3f8706e55d761d94bf091d7d6b","addr":"528f7468425b08f67e90058778cfb1efc46182ee"},{"mnemonic":"increase debate symbol swap raccoon crucial noble benefit kingdom prosper proud medal","master":"eb8bfa1409b9b28fb7c826f884d7eebaa6203e7bccecbe133e55df59db2ab8f7","seed":"5521921a26a36b06e62a681e2accb9a1577b6342085e9c9498f5693ce6b79fae98b9addd2da01df263445b5e45d2b4db45621517f96b86cd43b0ed00f7797fe6","priv":"e1927e2b0769daec6f1e7af012f1a14d82d52b89bc83a2fb9d007be1a51be4bc","pub":"02d41fc73e6624af22813b072d72a1d31fd628a66ae61e5d191c374be419c4a586","addr":"cc942c7413a8ea0db73c6cd3e2bd4c5e46ceb395"},{"mnemonic":"upset dutch damage thing maple ramp marine leave audit ugly walnut cricket","master":"012beaf52cd1e042c96753770315d25444e18cc63446a4207d57c2287d6ae028","seed":"dccb359dc9c2c2000e0fc23e100ad2ffcaaa0ea9bc1cf036b14c9c1f1542a4f9747097994ec5dc4071ea6863c01b2a5bfd6f747faea05dae4c3fa03eb2716b14","priv":"391710f6f67f54bb50abc86e349b889d0163a4c91dd1727dd3a6ae0912defc72","pub":"02bdbcdee705f81a4764a8e62de4bf6cd26f748be843fa36acad975980c5ab1b58","addr":"888ac8af30c1372d6c243363f6a8d97d3874eb31"},{"mnemonic":"truck stairs excite range van electric alarm sing provide mesh jazz cloth","master":"ef39accf9d3261de50dc985194a30b1cea9a861e2e48bcb47b8ba4542f855259","seed":"088e1bc0f701ada0c35c77f0d17ac9cdc3fee9747410407a1748b2c7e72bb37f2a9382e1108bcbaac1fa2db5aba2bf34574f47fe46450aaffa7712e5fefdd40b","priv":"e2e2d2973b52c1da6098e31018dd238b02ecc1d22236e631ff9d3009572ab1e7","pub":"03bd54aaf28542c6d155ebd24c032dde7341005e69a5ef67c3de5138b546d9f462","addr":"246b883c299597436993fcc8b22d9154db9d8f1b"},{"mnemonic":"admit penalty clarify isolate decrease draw virtual rhythm trim brief vocal box","master":"4df1d8bb85983df8abb7af56086dd76becdde81861462889c5a0809a470125cd","seed":"4340047ec19d4f318596cbe510ec11f233193b72214487cf3e8dd90c11f1466004810ba433261962b9c412b22c98655b06421b3bfe73ecfb1bd95aae30142cef","priv":"965f07d8304bab4719f071d1e3b656165a70eb31fb57d5cbc27e03780416d304","pub":"02e3a67f5d360f10b1786406cd2f1dab2abbf606fa014502ac9a7bb56616597776","addr":"90c64758c772184848b10adb3f841f14c86096da"},{"mnemonic":"citizen fire fetch luxury tumble analyst pitch van sketch measure effort danger","master":"e3469c68ff7e9f4e68af468ae8be59df246ae039ab8ecbfafc9677d6fa0b3d5e","seed":"bcd37194bce09d9704926235b5c83323ca7a71ca1b3b257c5436267a1e14b7b37fb44ad7fae1b818189240e9006cbd920b36aeb204ac00f98faf9e1b1c2b7034","priv":"d3f4ebbfa161b543e250ef0b52c027e49548d5a36a8bcbd8cecfddf0f1ecf92d","pub":"038f2c2418d2a68827be4807f06bc9c59ca291b34ee5284e860abdeff90197d40a","addr":"a44c929bb81a0dffc76e8659a44f85873578c005"},{"mnemonic":"claw stage toy keep crisp memory donor surround bullet ball innocent faint","master":"1025d24a465ea26b933c44575b283057daa066d0f5f0e12c9411ebaaec29d26d","seed":"effa6fca939b041aeb89550f138159090189a0ab3c96fb9151bd3ef69d29b457946695331804e437353d134f0d069b28092f122f35e74eda8a2d643c3d1a0f31","priv":"a81c4bc682ef7609d7ea9bd370703eef25006557166b9e04e589083bd7cd65c9","pub":"03b4d5e3abb4a6eff0409b20d8a1a88088e591a6ac3e6e25fb66f172303f55e590","addr":"09e4b6c1a32ed0e0b671e0f241708806a46fcd71"},{"mnemonic":"rigid neither track gesture effort venue vital bike spend unlock special swallow","master":"33fb6294ade198c457bb6d318b2eae4d2757977af36b988e042f1c3bb42afb7b","seed":"58b191573da33c6a4d94b8589fb32f8c5af326f5f40ced92973c352295e71d7a07251c8b42355b0360fe3ee2cc42b3217fedb914ebc61faae8a0f8cfe579fa98","priv":"db272ba1dc7e8aef500e29a4acf750dcc6fd92e4ee2f2e4235e7f82034a1857a","pub":"039d506e2c16bffda4127fc073a6e1b43b2c0ec68cd6d86bcffe0f0c4663b5033d","addr":"5485fe5a806040bf059c1e0d90822b49d14a51f2"},{"mnemonic":"sun ankle door drift sustain task home retreat light say wash pretty","master":"b0a3d174b40c1f2a723e3a62f878c1d4d19673c632a19fbea460d4d0c35d14a1","seed":"63e84de6c5f71a4b9dd5fe8998f00d0f8d0f2bf6da159d82bc8fe30475d0e909a939d7498936ac183e8220acdf104aa5dd0f721e65eb06e99baa27e81314a2b2","priv":"7e2d6c88823a8effdb5266c8fe605968ce231150169e0174e140643780bbbfa8","pub":"0280cf1699ed3cd91a57b8520c1173c8e8ff036cf759d4e076df031115c67e62f7","addr":"c31630d1643d32f652d89791c5de3a4b671773a8"},{"mnemonic":"ball symptom nephew dwarf mango crowd radio shift degree envelope science job","master":"449cdf41d10e6dc749aa52839a9c23a74c41cc7be85bd76f7ef0ea8347a76db1","seed":"303c978ed8b692e5e334bd1dfd0ece8615af24457129e7127e2ddc69f783628cc48d0d31ab522ffb6e70761dafb755f5878b45579911d52157c37c1b14b900f5","priv":"f6d3c4eaf86ce6c5c8d640edd4a67ff7dc852b6fcf36918f2b9e36df710b2049","pub":"03b3e239dc04042dc6c83a8ee1973917cacbe375786c73aae74a6b46cddba54773","addr":"f0eabf6d01285343afba4b7005268ed3af052d90"},{"mnemonic":"cactus trend empower board street stick animal replace media unveil recall proud","master":"17b6f0a996810ab534ac366a8890f7618f372ce0168b00655740f9698cb8595e","seed":"6ecace1a5b927d3058a08f1a59bb8943d214ce5e48e3627be8995814640782de30243f5a552e5600a3e1c62b3a46edb558434ac56bd105e4fe23aef8a1c0e4f5","priv":"69bbc1e6bf17262180141a0b00e6c410c3ae5b10b69b20d6321aa3893250cd6b","pub":"03bdb7edf4aa8f5e6bcc5bfd6a898671b0fd687bdfd9f8101f4ca840a183ffb226","addr":"c5fbfa7d4e0356d88cbb5e5bf47a67e877c1b1a6"},{"mnemonic":"source note bundle laptop pistol business only dust bright govern illegal melt","master":"9e7f939a19be0a48a3d9a740d8082b968fbd41065b1f5d425cd20d73d327097a","seed":"22b6512400907bd050684ea2ef220c4bcfd35d59de2c4c5dc3527436c417b68cec186640ea1be40dd00ff27b13884cfe7146c84ee3d568b8f74272f0edd91574","priv":"3f378db3f2004722591ed742f0d802e6c4eb51f357c1d77180a777d083b2ce35","pub":"034c05a98ebddfc54812ccfb797a99f3cc09e525759b7f40746513d58ce8577177","addr":"d920c5b1bd40b6a0c3835e5d32a8c8d5897a18ee"},{"mnemonic":"pride mobile flock dash second emerge seminar theme lift motor pave grant","master":"786638e9248b3b0ed4196533a1a437e1db7c2a83908c71823e9a8cf720b71975","seed":"59bf3e8f03faf407d8427e9b53093cb3708192de0c979c2e0a572a905af89d5ac43c2d1c2480cad58c63e3dcab5b5679a4bc12a4341cc618836d15f27c2ca623","priv":"f7ca55ff74a0f55f08cd8efc515ecc69d9cc6bf2ca389a3116f906d641de1f2b","pub":"03f538159091c45fadcfe4ada5d2a1a3827206bb4fcb756b9573ddd381b39621fc","addr":"14a320df092aafa1fd0a5207b6408daf532072c5"},{"mnemonic":"obvious man chaos alarm symbol novel accident label engine noodle inject empty","master":"df206751043497e26c74fde7e068376bdc0771e3e06a1e8bf17209bb9e1880b5","seed":"2178b8972916ccef4040e2c50cc9dc039a6ef7f799f2287d8d16aae3edb6ec0a20bcc4798299d2569cf6183d7aedcb426dbfca1971aaa31dc4c202f40c906a55","priv":"ab864f86be6e1970df2fa336835986e60fb7040a2edf05a196eed2ea9ff42627","pub":"02c8db2bfc3c7377ba3ec38f9aa7bb1be7d70ed6b15d76d3d5980f983552ef6fdb","addr":"c595c4572aa4b833719c935db03afefc56c0edc2"},{"mnemonic":"client increase remember size asthma source evil venture column truly risk clerk","master":"a0f072fd237c6f30dfa920940d04657e19ebe30e3fee5b0ad8e63cfbb6256d86","seed":"0ecdd247615ecba50ea404632b4f8e2a6babe067cf7d395b038935bcab013f0581c69f2d07ad330cb6c7660feafe8b21af062b474dba193f1121a65f83b71b99","priv":"4b54d2f02c43241d7a45efacbd48616f6293629fc0b539487865dbef626c6789","pub":"0336182aab2751a5399b14e0ac2a856143cc679405fa55141606ec3b2a09c3b1dc","addr":"48d6d2441e609507ca554f8f79e4340f257565b6"},{"mnemonic":"latin scrub oval capable drink common hundred ghost candy avocado stool dial","master":"3c8762364ca16a70f174584f1f276df1c432e0b315e08cffb0d5874760e8c587","seed":"40991c77f0fe52213ce2ccf4844ee6587b3595aee4e79f34cb00ccd0813f78f0955ab8e40a5f369522f7ae3ba0290db31fa1b224baa6ec5a91b57da8ad2b479c","priv":"5242eb4e71fc9715ce4ebf1ce08fd81d362fec9dad2be045ee0d6687e1662df3","pub":"02344bbc8ab1313883fee563a175cf98ba192e8570963fb7c99bd0dbf6368fb656","addr":"3db9be587f22ebc28ae33b4cfa2c86124f450440"},{"mnemonic":"envelope van become minimum electric inflict denial thrive congress visa jelly play","master":"e94c4ca894e31aa091dfb2ef9d7733fbc67f1dd45e5db389a037816e4ae9ebef","seed":"01a5a19c5f75ec7ebc2cf0d96b7665c4c79efa0cd0b7dd5e21c2cf8954f5dc5b1d23daae831a6e18e5157c200a603fb2ffc87a068d1dbfae1d4443eee76a1f53","priv":"7ed896005729b7de5c6c56a19d37f5352ad6329e948c256f11eeefbe8c0c7dd3","pub":"02025c5b38b96fa00b506cb0360cadcfade6aebc6eddddb71dd6efad382b0f6b3f","addr":"1b7ef9f1184a0da787b1231a0f44eaf4035c3ab7"},{"mnemonic":"grocery embody emotion wisdom picnic modify opera lounge impose junk scare ocean","master":"8091cf08fd5f50de4ef91fbd4b9eaaafe8f1c17624fec94cd47de656ce0444ab","seed":"ced20dfaf3a902a7b71ae459781e5013d215567a617a2300b49dac4d3473e624885ba0ca8df6f13c91dfaa9829aaf06c4ffa9ea22f6f17826a1629a597519507","priv":"f0ace0c797c7f3a93bf1f9ae64dae516fad77d18b11c0e32b5d0781d7a231f02","pub":"023c38bcace9489242f81a74168475ec29531c58523f476bd068195d18044f80ce","addr":"859850c7548250084438b5829b4255ebf5fdbe6f"},{"mnemonic":"oil inch eight notice okay gravity dynamic trend neglect bag earth predict","master":"b235b5a4e01f0e64d68b063f09a878c8b0785b84c5106431f4bf9250874e9d38","seed":"96096619deaf5792701545255d539f120ebc2ab8c23ee72de058874b6413e51774b7c2b61be1b1197784fb63fa7e509374449d4c812e7c8f8bccc711c73ba703","priv":"7d05f98b2cfedcb506c68d426b298b3450445a1ac89a3407f4ccef1ddff8def2","pub":"02274745f11a0de371600f1ab8b5ddfab91372f044ceda14c968b7e5bd953dad37","addr":"098fced832e9cc1c962630fdd2dbfe262728f018"},{"mnemonic":"oyster ceiling cupboard quit today neutral repair genius pretty gospel dress rent","master":"e669becb784c8ef38698f778cd27cf0b55ebebb5828531b65330d51ea2b1acc4","seed":"af8030276cfdf70d129e66467a09321eccd9505f662865a4776e1f5a05ba1ff6614b37b54583333e3ce931c9d44378f636efddf5189284f5fa566d8db01801b8","priv":"c0ddfbada817464834555e46ed3eb3d50c1023454f42826463e71754b9e6051d","pub":"039f5c467338b3cf8ac16e6677c8242a67caf89f1201f0f22d99ca1e7beb9f1a32","addr":"53ff0701507c25f97dd1e6721b218184dea2e3d7"},{"mnemonic":"utility angle dynamic fire canal current level trash chase praise witness mix","master":"54ef0de540f88777efd1f3c37929789620eff87bbf98e61f9b2e0783d75450cd","seed":"8701d5ac962b68ab8c34092b44210cb9c11c2332515815223537fcab99909b44a0394436074e60285c7b306917c1165a2f281bca911798b23832723abaf18971","priv":"bb5602644b1af5bfa019f2f81ed0d2475c1492661e55c8e65d8d5e94ddb33e52","pub":"0314f5e5d817f2235e3a6fdc0e86f231825165777c69314de63bd88738e7e7ab46","addr":"6d596a5fa6b1818895ee6fac51915a489da283a0"},{"mnemonic":"cabbage sauce filter identify potato coil bicycle river observe candy maid monster","master":"4e834379e58e480e0cde698f9f8e47b3b6e698b4c1325a995504980e43689706","seed":"a441b8fed73bf3bf06a27aaac9355a79d645f0c7d5d47ec216a8d42d6edf97e6a00dc48de9d9ad9d52279ef26f34990581caaba9d15342935ffe857c10456382","priv":"40e878ef025dc6424f2822e38c7a906b3bc39940e8db21262e6bb99ef3de98a2","pub":"030e41c103c49d2e54e5ba6e40b1dbf04245dca7da0738ce9048d0391da872365c","addr":"9d4e8dd66b5e16369be39000c11b03fd5054e0f8"},{"mnemonic":"method surge demand ginger pigeon chunk because wisdom stadium salad excite stool","master":"b8f4a0a87e42871e927b2d5775fd212dbf911351c525b92f5742ba15650aba63","seed":"3844f4bc75163d8dc39c53cdd0e9ff31182a87ad2d630286897b35b39a14afc5e5ecd3be988c9754ef31f14452290ff04c84faddfd195a3eaea076e48bde47c5","priv":"db0bbe779583c012d78f9b60d6648b72d699c2e6b5e9eb90d293852553649a91","pub":"02bb40395d5649363ec19874f2fdc122bddd8748234c1c1ccb37e38468c6e9da4b","addr":"bf52f59b2e4f01f23b32f502acddf96bda564682"},{"mnemonic":"stuff extra hair depth angry jar drastic jazz diet olympic choose legal","master":"5e09c2cd0aa6504c4a2e8bea31e0dcb7f0b82f040567b681271493e35ca910ec","seed":"ce48715916de04f9c4f9a84e4ca25900ca0292de3a7217a42497c0bab2253693ee8b5425c40ffb2700a65a772e98989a2adf4329a93596a4d6695f6c7f236e64","priv":"7f06d4f3cac1e4b2a7e0951a55f78ba85aa6e6b03872dbc0c930086b8e8e25c4","pub":"02b4ba9df766e58ae8a5164b4be48159901f421b8e8f396593b66dd3a715f268c6","addr":"fb2f7eb9e28187a7b68b02b7f55b5dd46fe9ff49"},{"mnemonic":"leader now arrow loan eternal prosper myself lift limit capital aim twist","master":"8a4e78bbca5c37b40feccb9bf053a24ffd6d0809fc2b89440d467bc903c03244","seed":"25f1e8641b6095446cb3d7f94bdd7d81d92d78ef808b18c48050985564543efcb99f28b94e2e935d31d973a848666b95bd183e05860bd0950cdf0ee8d7e04da7","priv":"a2fdc724702230d79b0c564c34fc4e68e8a10c336ca053278cb3be419313e07e","pub":"02e2206433e526fd4fff47b58ef262eb558e79870c0aad14290d40e912ecde8213","addr":"3389c22a794df27093c11dc80b6096dc3ed0d175"},{"mnemonic":"increase month viable teach spice pause safe mouse allow sound access grace","master":"919d9b6fd918d7f223acf91ea5abd831a1a3568d60fd2e43f0d97e000ec77f47","seed":"f4cec05a2bf6a00a7079213c03c36d765e49914166f497d6e38a522b1cb43fe24260008dbbad00a10d998f7963dc8dc09fd539570f157c9bcff8248987d38626","priv":"f145657458462f994a4e972cbd42ef4de683da47b5b6f95b14ea417b39e702ab","pub":"0289419eb27318299a51fce4f0e65827d0426d72543fa2f05d0c5f21bef86effbe","addr":"cbe298ebb714dd583e7c4d541ec9b38c56710226"},{"mnemonic":"move catch empty dilemma only online ginger rapid enough turtle flee retire","master":"39d365c85d0ae4f31811c665217b718bdb90a4f2d328587bdf430ff622d019e9","seed":"402b62437898f76f87f3e080c3f33f1c6b8ebbb848efd467ee4ae5d3303768c57a15fb1cb03a6befe486b0c02733c5c892ed9878ea7713cefc58b7a616d7b286","priv":"7e54e61877b8413d06251167b239c1a6213ed23e79c1ec8da7408e23928d47a7","pub":"03d25f230b5d12ba142046fa80c23e51198987254bf7f7f8a009b712783d9311aa","addr":"173f71a2ef94e964185c474eb310a363241c4621"},{"mnemonic":"audit energy setup mimic dilemma amateur evoke tornado machine artefact shed artwork","master":"40bd9cc381e632be6f25b822bb13bc7cb5c9697b09d7ec725aa21e13cd3eeff3","seed":"721de71ee0b84620bff8de317edf7c4ddadcc2dfbf19f3cbbbf61bf26157fa07c46119cd2f8387d67fb0cfbb98f62a3e711053a308496a0ccddb944ce517d90b","priv":"825587d79a33405a3c7cbb8a25e89cf1b3975de3763e1928e02c3f4d0cc8d44e","pub":"036ea297692c5bbd85ac06ca8ca238bad6db83d1acdd02fc012325a1369df4447d","addr":"5e45e1683f7c34754771340ecd629014297b72ba"},{"mnemonic":"vast noodle pumpkin sugar time iron screen begin among orphan glimpse deal","master":"cdd2cba6ca23c96a7967d3f3f5739009f2fca93bda0a36b85bf7a1cbe0d8af8b","seed":"6288319e4e2c7471be7088e9b50db78741c1da423892da1bfa289bbc62d4a014a6d9b7cce396cc3471531342a61d92345a3b043224dd271ba46cd716a0952af4","priv":"1a746edca60363f3bb4118e316ac549be3161be28c4151c9fb9cd63728abede8","pub":"03cfc321906acb176564624dbf1855f00188f563b14f07075b1d5c7e4dc25b4419","addr":"5007b4c128af77e8dfcdd85a925044438def1159"},{"mnemonic":"evidence element stereo crunch romance trigger ten ceiling cigar wire first frame","master":"9aa2f09eb1b6094ab52e39873444f04cc682e60305e9fd4f485af27d7c6e85b8","seed":"9adc22bf0cd328df0f54c6da7f5e43e9abb4e9a607aa02c312de24c12d9a18f38945da0188834e149aaa5798c8594fbaa9109d47363deb53e17553f2edfcdd2c","priv":"281e729635633787eb40b08d43d806a5e2ce178abe659b37c91c6c073e720448","pub":"039e0c68668af7289a7ab4c7f9b24347f10d38eca095e991207cd9ee55bf61f0b3","addr":"49b25bd31b9fed1ca7e2c32d663bd414d6c3705c"},{"mnemonic":"labor capable alpha robust suit trial media bottom pig hundred verb hotel","master":"b3e4d6c6bd059bc9548d33f6ce0aa6674160ce38bb231fe354950aab11651403","seed":"e1470e44481471f4c947976fdd4fc9119619571cbcc90d0d419f4a8c4e1102f84246da2c2fd0c02bccb34a23708cb6bfc25b23972c03fb6a70f5018ecc5dd2dd","priv":"9a9501487f7f9844ba521b3ef949b12b30046e927bbd8054c831434a4309131f","pub":"02b25d30e144102b7500d57f3c501093f4dc8708afa3ee2c9d772d5672802bb9fc","addr":"49bc8135a631475412f0b4bb0db7d437ef226243"},{"mnemonic":"resource pencil other subway knee small shield excite forget such annual opera","master":"955fe71377d76742d6bd94d49457e6cb768e57517ed010648edc058f65d6ccd5","seed":"28a7a3080633dd2485cd88b9c1ffe92889eda9d33be7fab5b8aae3448170282decf20587d613cf06f0d3a7da6acaeaf5c9918616b4d22f8f23bb6a17c67bbde8","priv":"ddc57bfd0d27c98a1d088272ab481407ba95f8556f5603245466f4f2d83c3168","pub":"03065ce8033103d6fb42bb382a59053797beb33214c9d16f2b4ec3634cddf857c3","addr":"b0ca9d5f91fa03b1350a40e4ffa84e99167e4115"},{"mnemonic":"dinner tone antique away vivid lesson frame floor rent field monkey race","master":"21cde220eeac2883dbddcc6927f73423af840e675eca3a6cc82bde4a5cfdfa39","seed":"16c220be97967c5fa8ff2176a9e0d748e0aad37c8ad32e590c5a35ba08247e2176369a3561c5eb0cc4ebc9a3d65bd132e31c2640968eea822ae76c6c34d17373","priv":"13366b2855dee63a394c4ba89378a35b75ee07853c78765dd1c5c8927e52d4a6","pub":"03cea336f71a793319bbb298bb3c546046e69b6abdec405302739345047cde8355","addr":"251a5f4b01da75091e938d782ab116e0e4ac37e0"},{"mnemonic":"peanut potato artist define merry brass nose brief dinosaur planet year blame","master":"87c46a1f19cc7d1e59887f445dab57aa835bf116db621e9df97c5f3090517e7a","seed":"f8b6aa2a59e9384933e0a88c76c5fa889ad82238ee7173a41a57638bbc82e51e7d89c97bf3cd2f6031e65edbeafdcad5760cc6d37a527eb0372b03281e7806ad","priv":"a7e43f8b98838fcc06ba6257cc64086fd1b6d0eef12eddf9910181bc6c0ff204","pub":"02db3f433577482b62d057404b61d9d10f25df66b0742c2a3471d2e80380355cda","addr":"571a2abcef5e4f690174e2d81d9ca035742e17af"},{"mnemonic":"orbit have attract dove horn liquid social maximum penalty slight mind mountain","master":"5da625838972cb1684ff4e45326b14bc1d73164f82527934fdf8b7a03b9891c2","seed":"abd2d4cdfc5b8330f58b7757efd4fece7854e461e22c71be5aadd735c144a954594fd8da84df6b8db3ea14c5db03a6952f093346ae94b6495a8635e72e4a38a1","priv":"cfb3afed34d7e53d459cad8623401f0d6071d77f70a96c75baa511179ca59cb3","pub":"02e9e07cdc8d57e321593919431bbb6c0761910d00e4a242ecd85d0b99e9ad3f36","addr":"78099b6cef2d14ad8f3ba7db73bdc9538e382464"},{"mnemonic":"squirrel motion glue best prevent fault goose evolve shoot decrease panic very","master":"2fc7364fc6537a38839ddc9dd41e0e58b2e972072e92ab8ec9fda67360f2a042","seed":"78718bcb53ba532316fc641cbe2027fdf4ea649563b36ae94a95415b5923397585b4d10b1026cfc8a00069cdc02c7ea8c1ebe04364bd68066195c748331104b4","priv":"7d9073ba21f72f91ca39d1f13c05108dc75b56d3b09bd08b7b8843137fba91b2","pub":"027827c957ea1c98f76a076bcb75ab8faf534dbed44beb234ebe9f60086fcee393","addr":"10440fcf67f5b2b6f4e81a0b6fe267941b437811"},{"mnemonic":"pudding tooth market kiss exhaust donor tattoo olympic uncle child bean nominee","master":"34f62b6ae3c01c03d64e0041bd50a9cf7027fbbc0b0fa7d13d08908422f72520","seed":"4f02768404f6da2b7654bef1e4d35a42386bcdbf167d09212194e20a93070030eb0a471945248a36a8d062e80130008cc16a001ecc3c05a27db0aab0f04c6411","priv":"1601556ec13ac16d4b38ee73080065756ef276473e7649c713ea1ce69367c087","pub":"03382cbb99d17b144dec0eaacaa33d1cd2041bd30cb658fb97ef2654e24addbaa4","addr":"e2bdf4c0101d49df4d8aa0782c4a1fc354fdbfaa"},{"mnemonic":"earn shock finish ritual segment post then note dizzy diesel jelly horn","master":"309b4a016a064d4bbbbc220c0fb0727114b0b83b600db73aeb4347a04ce52873","seed":"bee7d3de1274abc8fc05afc839de0b14166b86f1ea0a1f2a6b6484f40654aaa7cc4574a14996812974b905da6eed437576eb7f8fea704afdaca3b146b761f0b8","priv":"a269a409951e783c280a5d8afb0bc232f303618b4d83328ee1196cf86f2d8f04","pub":"03b79d6727f3d6a0c289f2efac4938caa94ee57a36a3ac70e3f8e5f85f7e4f52e3","addr":"8ed4fb10d7b8d66f4244e83d7e6cc89fc75460e3"},{"mnemonic":"venture bitter tongue learn whip palm race pioneer satoshi wait hub genre","master":"e01f7f5ad0a782b56a034b68230df72cc8440f6e4cad89ea0bb9b81a71b430bc","seed":"b6da5129dcad44188c654c9c50ea640543b66c0c98edb29099770eb6d89ff197f5e9fbb7725ada5b3b0191a9cea89ebd8f35698d5ffadcf3ec43f6b92795c1c3","priv":"e3ca3c8028c514ecacde54c73338ef5fc78e0ab05ed8260d4a70553c68390bfd","pub":"03913989f1771a015b6594b60de23017fb31b96a740507873cee53770684fdd5a6","addr":"db8e914a36120702031b4498a27d6bcb8c64da8b"},{"mnemonic":"opera wear actual virus pause topple leave video garden guard obey item","master":"8fa7f1c161b47e625e351c775c662eef0d5cf9d9c229a780ce0adee5fb045ccf","seed":"be4f43f613da6e02ae174310181afc71462ec108601eab58d369f452c4133d14bcbdd05462676d872b7aabae01e7e6e22ad38261ce70a2f107ff9f42ace4411e","priv":"506a98b80534c824f67233bd1840ea968886a57ab500fc0521da20fa4f24fce5","pub":"030a5a585b4db663ea11944e5be0bbb630b6b1f436989c8e7128784f7f59676370","addr":"5ad5c8981762b720bf74b376205f69a91c6f3cfb"},{"mnemonic":"captain tray course secret betray bag disagree boring umbrella liquid door memory","master":"b7974cd18de7e9e6abe2280e567fc51efaf3e80986c98901ae2ab7378eefa08c","seed":"3a3c2b0e7b237e37e7c92c12960ae5b8856a8a5795386d243c6d9eb7dae1b98170489c47b197a794e8f9ed0c323bbd722ca052f76d3cf1ac04db5f7ef6bf5b26","priv":"a13d741052c66e487ee376cd392096d9e56db28d64001cdd807427678b765016","pub":"02fac937135a8b0593c50d06a7b113c372d8c9d02a338673e3e07f267725536417","addr":"e5d9166b331f86253444f3198f707a495055b768"},{"mnemonic":"dizzy guard goddess trouble absorb pupil stove mirror nose couch diamond must","master":"d3bdf420266d0c5824a621cd631ba014a8ea614b85c628cf64bc3a77cd3be3da","seed":"485d06d18708ced0c344c4025d93cc194f7c63e2aaa1d19970a96db8dbd7e2f802d39d319338b0a92faffc2af408f69f1522481fbefdcbd3842ede957c663b0a","priv":"abebb4b15d2d9e3a3dac2afd4423d5da2b2260da49bc45d44d014e8d740ba064","pub":"02e39342b82a9b4bd73b165ea9b309e20b0cf9c8d5ee93756cf82ebad0b00e0cda","addr":"19f6fda807d1a0f99fb730923277d4f36601e2d5"},{"mnemonic":"rescue drink absorb brief unhappy rocket subject receive green echo marriage cactus","master":"a6ce8546f2cb2a62c573b3bb5b1e7437f70a44b7cddd7171a41d2c4c3dccd641","seed":"0605b45920c5894d2d351c091c7c31af1b6f0d77576f73716ac96dd7a22dddbf42155aa19bbc3c2cef3c757ff25c3e7998d0ca536b696a498c9a206bc53e8ee0","priv":"00a6e55ef1853ba31f2b7e76acc7e04649a1a2037a9bc33c74cf82261e956ceb","pub":"03de1a877576f6e77bc06a53e7b2c56afe7b58c460341b74c469e344d2b87f2e62","addr":"a4014c9bd6c662a6d4b20cbfc0524e125a5963a2"},{"mnemonic":"destroy naive mother audit tackle coral crater sponsor viable clump bomb bargain","master":"c0cc3cb63a702200dd06ba3355314b332385c3a0e1ba73bf428243278825a6e5","seed":"fdb9a430d0fce5ee93e6b0ec23506f65e76cae8be1f773605af71687d2f9fc14a9a1bbbb769a5c38f654398024159b48de392cc4a88e29030f4b7699a3ed6824","priv":"8b73cf6e42c216a7978f63a28abf839d0e2174cb10ac2abef6870c9a8b938462","pub":"033257c04174083656be1bee39ddf01b34aaceb538ee86c7df35a9ea4b3a3c282e","addr":"5ced7fca93a8e097cf58cffaf7c89141cc00697c"},{"mnemonic":"paddle image cash sadness barely sport employ slab keen riot solution switch","master":"be10364b52d5cdc0b8eb51215301e8468c82498f0d7b2de44013d382c0441e80","seed":"138194b9dbb5c35fc66755736c385e12ea8783c3208d85c58bc140a5edbbd709779d4b42a2c56b94d82b5edbb9de212f2eb315edeb20a5725f3c24a39ca50f51","priv":"06b0b15085f8af9cb90eb081a7b73d4f8b781467926c2dae68a0d300f2d62a71","pub":"0286afa72dc5ce3416e8996392d0cbd63a0f9b9d60701561d3596a1c9d5fa18499","addr":"bbda492cb736571a6bd62d8f5d8836b0e0c761c9"},{"mnemonic":"gossip choice orbit insane honey hobby split exchange uncle wash tower lyrics","master":"7b39b437bb8d0b66c3989df6debf35846dac9fb69d2f570c4738afe92a57d708","seed":"d0897a14b1958fa31a898e38fc95b6dbb2a9a5019175bf8e503149f9d1ee4958edce3f1f570c3e015b797b475f5eee882ce54f68c7f64e310571e0fc6296da62","priv":"816f5cd94acd51821291561d6aa30951d89221027418ca697aa2b621f733b2ac","pub":"03d4081dc8446919e4a949c323b4c8d6b76282325cc7f35c18791a57200577f082","addr":"fc5a9ef94fc8de5ba7407669ce04d8190864252f"},{"mnemonic":"ceiling shed aim oven emerge year sock achieve ask melt endless lecture","master":"ff1480b11529ec8240e79bd9e35275e1805a3e117a60f9b6b22f66715b4258e7","seed":"1aa288b6bac68936d8d2a89396f5be1659a12fc91a9d7edfbb45446de8bb39327044b6ed7451e820317882f162560fcbb134449e85d517a7f0eace2da2cec272","priv":"216833b820c607646ae504dfa7fe28b364741509047b89eeff48545fee07c11f","pub":"03b3c3ce98ff9d2340849c220a5127d8ebe2bfd320c9db41e94f57b4e067eccf0c","addr":"78e3043b376112452a22ce49f6647a0b1d20180d"},{"mnemonic":"deer defy door jungle sauce summer sea globe crane abstract minimum diet","master":"f7440871bbff95cea261708c1cd06220a5aadae4a86c00f53b6f510a50e8ad56","seed":"a1868d8a30b498e1d397838821bf762c5f448d3d8fb68bf12cb0e2e26cc69f95be698efb101e76ad6ab84447c0c2b2170fb2b201315f5e5023bed35490f43986","priv":"b64d5f61a5503b366e7296a5b060e42d5db420e4bb8c4d0248c07ac25d2a0b60","pub":"02f4e32b1b8f2ed1b75ea26def62a6e69c7cce521788bdc182663ccabe4c1da4e1","addr":"32a90701856a1d942f58f41f6cbad21a64494658"},{"mnemonic":"position course virtual distance fashion oval slice round rely key spawn shy","master":"255409af8fb802395b9433c062310fda250cf8f9df7d79bd16381a7ec7b4d27d","seed":"1dcf6512b003b07fc299098ad2b8d4ab3eb1be11cb8949636ff2dd0baa0081ba78a9fc117ac65666c0854387ce0adbb903b482b85a20b9e591f0ff156a59d30c","priv":"a9157f3dc6ce3889c4d8dd4d2434f0e080090e4a0c0c75cf58bc03b41ea507a8","pub":"021b68e6fc74dbc45d326f9d2c7efe9c718e7c3c1a084e92c1f384c273b2d41513","addr":"21101638d066b561f8c43f6e9061f3959e3f89ef"},{"mnemonic":"model absorb cart athlete helmet next hen indoor involve ladder engine tone","master":"4221074ff1f662276f167017a5d43611b1d6e666c0c5592a35c81d2f5389c93f","seed":"dc9672d8e648fb4da6a5de519d08fb677c0d583a988701f2ac57e1fff273c3c832d31c036fa36d33b029fe0e92e8bbae350c6b96eaec463588f1ee04209add53","priv":"c4662a26101f0dd36e56ab0528a3861547015022b9e8a30ffde845d6207ae8c8","pub":"0285c5ad35fd9063e8cea4d034628244e790261977eb0225d4da90c5a2d11ac25c","addr":"8fc4bfc728a5e5fe2423b8c380aed1f2fcf4d2c4"},{"mnemonic":"armor happy become inner fossil exhaust upon under offer sheriff coach huge","master":"154c74bbf5601f7fd35c183e77ba32c03eadb2fea62563d2221199cc694a5fe2","seed":"db7910b6fb6f406f146f857b5c116033356cda61099165a7b1f782b2201878f9a4104efa15c2bad266db1802f9d15719fdb9953eaf3e245f0aaf9f5b0ff8d296","priv":"ee1d3af46fafe868bc1a89394c068dfe05cfcf7578c10bd57750511276e829db","pub":"03db053e44816be4562be9df13d8ee1853c1336aff0d13cc516b0681521d96a9af","addr":"fa65a0099684906c758eecf10f7a2b6dda7c5767"},{"mnemonic":"long output ketchup question hurt drama bamboo globe manual chest luxury abuse","master":"b180100cbc124ed4a9812ab4ff3c632bd7df77209598d4b26af9d31fdb8bbc28","seed":"61b7b436746323085cda66fb4c0e21079e849bc4d2bcc67cbcfacc97008abeb7ee57c2ce751e5c63fdb676f0cfec68442277d4a0e5db1ecf82236bb2f2c9380c","priv":"1ed983d1024d453e2dfbed2278c3c8ea3abda96836db2462da4738f20ba1d772","pub":"02f9d9ceb9a27e4626d09331f645d40464c99975ab0b7344be3f6cece6cc0de8c9","addr":"d092b8b49065f0698b483e416f4b1b032b416dab"},{"mnemonic":"ecology over output enact system curious want oil denial ivory hamster approve","master":"f304cd809c371db0fc37fca212810e75134773494e5c1d20cd22753399ee6433","seed":"6693bbddb7e758825bc3c2096108aecca0414cd1b523460a14c8dd80c15b27f5f37cf4589e710a39fe663392874a6b17892fbf473da8d00d86af17aa19ab0cb4","priv":"8b13913b6f590abf399aafa87fec44961218fe45ece0f9ee8b22810839c46e5a","pub":"034738f122cf61a102148156d40aeb129bc4c54fc55c5b85462917f4013d7e3024","addr":"1657b328a5f1ddef43968178fd8034c685e9e312"},{"mnemonic":"uncover climb join country march border rack ridge track true master useful","master":"b1f2471d8e6e712e20343f06220f847caef645d9cd9972ed17684b3a44b25de9","seed":"431e56eae671e0f1ae12aeba623fd4ed4c7d3ed102588d3b39b3c0e20c104aa24a435b9ca504799214f95b7639e208dfae17fd866b2f58c0d916cd744b7e5424","priv":"1b0e22bfd60db8880827761411390dec4799efba98348052400deec1838b04d4","pub":"03c6d27aa4dae3b3e5754cb3bf8c4638576f113876cea4da0d915964cdff0cf7c8","addr":"0056ae65805ceceb8c17c3c1246c5f70dde2be6c"},{"mnemonic":"rally cool artwork leopard skate battle shine text ritual rookie sun way","master":"72c5b3c5022b033d71c7abea54feea3d3b37dbeadeea5db4c8847a7cd0e20d3e","seed":"d7fdcb354a8946fc3449107361e4bb3bfc569c0d3617b450484e5a7fcfd5c690cde3a511415e08be23672789d090a3c679a06be36a2a20204172e1d61433268b","priv":"dd57130e658e43c9adde730ca57aa6d43d31efc3697a752075a7cb491a7ff390","pub":"03b7cd7259877064b403af9a65ebce47f210141356a67efee77ce456d46d948db3","addr":"a8db1e5ce299462e4943d0eb05c146591fcc3297"},{"mnemonic":"room vapor anchor forum stage corn credit jelly level cat detail auction","master":"fd531ed5d65637f6031aa02ce031cdb366bc8a07b00fce1104675d1a653e7995","seed":"f42ae529e339d9b204165f2b5556c1637395d9598cf5a59717d048d7d5abf831e60abdd457f3432ed2ced4c13a5a73625f716f235d51bd7892cc16c294925cd4","priv":"c2342924a2792e7c4bb8523045faaac7a669fdd00b2621bd38077f58a32bb0f6","pub":"02df2b027f4597da0a2e8f46932929044dbefbcd5c5ee38c2147dc1ea061dbcf8c","addr":"642b32cbc358915bcb802eb30690951710f597bb"},{"mnemonic":"have offer number egg canvas uphold memory snow know orchard cause wife","master":"8ff4d3e7e6ff972e24682d1f1116c7b83bb94ca8cffed1db9ddb4adf89e2bcb1","seed":"14cc60691b49b9036c0bb64ed24da69478e01deb36184f58049d694ccaabc41d95b1e6734d9d06e7009c394d54d80fbd65cde6ea49165879dc306c0125b44681","priv":"c57093fcc3c593fec4002a9040d90485016346a9f4f7d896a105ac268face5ae","pub":"0252fef0dc82142ec121c4b01275b254d6a78b4600f417dd0f09639fd94a23c0af","addr":"af5cea50c72de4e54216fdcb9334a5f5a8a0393a"},{"mnemonic":"garden nature witness stable over move among pledge woman cotton worry behind","master":"48d57d0dc1abbb7142aad3371d68c41ebf078970c5fdd4bfd7294fb6f8d32b45","seed":"bdca43aa42eb2a34dccfa4fd48202cdc386454683850a12e7eb7eaf9998ebcf57a01a6fb1a6b9cd8aaf2910b160038fa6adb42daaa914c7628e27f912687e52a","priv":"63dfb6b77a4286875868db4877a3d0f3f0ae8c2766b9c5d9225f48071421d832","pub":"031e57ffbf90b85823505710bfe5be2200f1d880171e8480494b50a04462b98795","addr":"a7619c6704a7341472229bb7ace1709b88ddf175"},{"mnemonic":"pizza sting refuse olive final hungry kiss abuse nature junior opera tired","master":"397240e78b72dea36dd17ea2ef3a15f18f8fe64c9e31a30687d2fb013e1ac6ab","seed":"1dfb236c6bbfdaa74b02300a0da7b2d57a2fc2f736a5144186cc89b6f20a23d74ae59338fc04367a27e976e41f1d1bfd4232a3f386cbf74220c9d0c6fc5c7077","priv":"ae5a8c5bfb71adfb89055f61e82a6ef5258f6bae9056313c360ea454bc30c052","pub":"02756acc7cd398fda3d485f6aaa15e7e4e558be8725d9766119e570b2b64486372","addr":"c4c6e359acc30099a524b67223da51dfb6557de3"},{"mnemonic":"deer easily marine thrive author despair puzzle super agent life rebuild soup","master":"7efbef221b4d50acacbd20a10c1197727e9fbef29bf2418f51141fb8a5368618","seed":"2ad829ff702c19a138945f61d1449c32d6b16ebdfa34350dd434bca3899b6eec3f66a3dc8de7243539f7d6d07f85689a66b0e9f6481a4767a5630c2c693c3ec5","priv":"b6321fb4900455eb1986073f5f705d088e795d26ec53c09b6eedadf439fdcb6d","pub":"02e9c7d430122627396412df161a58813327f436bdaba34f3e855263044e1fcc77","addr":"47f0fa963518339112a65e54948c5df8c23daa72"},{"mnemonic":"gate calm appear symbol make can alone wonder cherry couch loan firm","master":"9a727a9574790f29c890079fc9e83b0bfeab84d9e79ae6b273ea8266f4a754e8","seed":"f37c4b52afedefc86a24bf4edadf6a2f151aa9d503fdb3da440d53134fb040f7ed60c29407e4b74a0714f5fde8d650b93d71da52568d0e9b2056412092125c76","priv":"41e13797f2f7c41a44db247f9da73e8d7893c2be4a689fe558145f2bbb88feec","pub":"0242c6981834d9c7a14b96c39c6f902ab0a076e4a7ed29fd7ea559aeba3727da4c","addr":"dad747d0295dfdf151b6267e701f8d889770b4ca"},{"mnemonic":"opinion spare hurt three insane sick place sphere ugly sad mobile icon","master":"e6b6704a86504c2552e7db9928c6333372fa5630983e5a9aff32b0ecf56c8fc8","seed":"bbf2fa3760c82ac61467265053828c9cac4bdfd8aa43ff860ce50a094bdc448468fc6d0e6c53368e42b95aabe4f0098f9af46018595badb4f8cbac787d5c00a5","priv":"496c6fc85e550d78a931b51e6807dbfe843599401dae033db98e308430939d34","pub":"037ed7cca0717526969db9101c62cfa151cf97544ae66408317fd798d705a30138","addr":"a1fc3fc66094cabe3f7edf5b630003a524bdcff7"},{"mnemonic":"include relax onion depend animal stock essence basket local result rocket panic","master":"5830b22230ba22060e22bc4ee3323c8b1e02e5f53caeaf90759f4e846720b3e2","seed":"8fc74e989ab5b4ae04472887a59bf89b501e1813e687cd27a06bbef858c9a63b35531864b177d27841abe4999a7b1901d95303a395f5614a176667abe8aefab4","priv":"99a7444212b0176324718171a318f74fa5721fa46ed18b3677934408b30218b2","pub":"0213e7320395ca9eae0bd4f550f7f5f65a801066c12d95c3f9b443556011b13944","addr":"a4087ec7d05b08362bab9c8fd9406ab3bd88354c"},{"mnemonic":"cushion hover joke lottery gym muscle drop scare purpose share food strike","master":"dcc4792ae42c425fe278db48211f6bf54551f9dc58268282a5a61cd620832d4b","seed":"0bb05d59704318da60a1697d09562a05e4133fbb8f5a4750f378f65a5f0d6b9c0fc668dfe08673d6b10bfc4557250759c9f70aff9df1a5418821756f4017dcd4","priv":"741dcf7d371948cb17723b1b58759d8a0520a341a29d581abd12274014e945cf","pub":"022dd390a8c2d4a826ba8e725f54f5ba65438c97519537701001bd7a68eaef91ff","addr":"931f12464c90ac2bb3b25fc00f13c56ba1c49679"},{"mnemonic":"point action veteran fragile outdoor vote timber cattle cube deer fade razor","master":"ed95f0d3557ecabcc04fa2160560dde68517d4fe7ebf88584d0993a1a861c6ed","seed":"886bd48b9c9e337480538f1119148ac4f0a8d00cc3ba17a34cd7076bfbe85ba2a1a8f410ca44f210d9cbf6751c10bf15b6f52a725979e613f4294813bdf173b8","priv":"c489a82eeab534dac53396b71dfcccdd6880bd441b89386baf9700589d92f169","pub":"03e2e7deb2c03412bb42d4b32cae6591e4e0db745681900436999ee51ef422cd35","addr":"f9f93bbebed5d2859f83fefb58bbfa5f93032837"},{"mnemonic":"ozone pulse whisper cry ordinary benefit enrich cry name bargain muffin case","master":"ddea83ac1fba7d6c79dd073d29c913a767315bbae6c3648617b7fee73a04595f","seed":"ee93e7ea1bfe194ffdf6b0f70c2d5b5759c223620c01647fabdd1e2a94575a61b211b301cd6d4e979761febf15336c9bd1301406e338c9f6c0b8b938863c1cb8","priv":"d344fa49eee22f5cabe1362f36a026bba1b0419c126da13c6cf335759a962d36","pub":"028bb9fefe8418dbf0fca6857526f286d9db3321d12c6a88ffe8e2bab7004b4a29","addr":"b9bbd7d328f0947669fd1c81cf8a842a721206c6"},{"mnemonic":"huge afraid venue bid visit decade hurry put swarm couch gadget book","master":"8755848478c71a1c3345cc855a10962382a6c27e6c639c4a4ed245bf32bbb2d8","seed":"b04392d13e629b759aec3c28ac4cd7eb0b7b846f1e241eb79f862d6c30e79f3a5cf5ed26abcad0dce95ed6d639e8088c169e49bc20df609b5555b0bc3f3e5e6f","priv":"f3ab0ed871c3feb01ee18fd374568aa378651815b6903a2b42eb43dd70edb9d3","pub":"022d2a9a829f992b3d16f9374b6a6946649630bf553c8eb11208a68acd03ec3c7e","addr":"c61f53c2b19de0ef11583048fd19404473065bdf"},{"mnemonic":"update ring situate blade term enough evoke balance absorb pupil wealth era","master":"fc22f89a860ffe871a7a45557fda9f38369f99103e02a2a97066517190d10e0e","seed":"d18f179ae9c4767501a8238182d3fef3f24fa3259d41a07b601179f67fdebb6b47a78ddbb056170c0bddd3e5f5a884a3d4046964c0f4ffbf7b37c3e6debeddbb","priv":"32a6d9270cc30fb5bb11411313af52a3359249c1b5b38b753a83ebf516a1d21c","pub":"03a579f47d1d57202e02e7f445d68d6915a3304b256cc37c5d474e699405deb613","addr":"8501c773ed9240be9fb0f83ac2af1bda6511b1ad"},{"mnemonic":"horn coconut protect box cargo switch ghost among energy easy deposit fly","master":"df4a2a6d35731478a3dfdc0e1595486bcc245f83214a974b31bc20e2c0e637c8","seed":"454ec603e16c8c5c522192885768d941316f0736929046aacda1a93ad1a658e70c21a7e924974583d63567acf26ac15725b1148a75522c6bb26b37d9f92fec22","priv":"447e4c3e530ee519973a63c6ddc63b9e5a474761eae12e8c1fdc6d0cea806604","pub":"0359c72dce4c6c9edd2774af06545c8996e4832ae35cde19fab2f7dde55316de1d","addr":"5a49f88b1672cd9102caa80ce55454030cdaafd7"},{"mnemonic":"price envelope myself under helmet dove uncle below extend gadget limit mammal","master":"abe0fdd5148a6b93ff8b281d084e4bc92277848c964e3698a48e5d50d6503d54","seed":"f8c27b37871dd5aea7f7bf5fef1c561beae9d029b3fd937a961ad39fd09100993efe7b84699f7abadd49b81d16382e0677563d28daeeb08eecbdaed50b27eed2","priv":"8ac79807c2a1bac4cedddb4768fe92b7a51e0cdab5cb79758f5876511a9b09e1","pub":"023277dccb7b0e017b461bf483c2d3a63273e83f3acc4688733776ee3ac0f649ef","addr":"0ad65e63beb8258df8ab0f17ce28afe3bf19a96d"},{"mnemonic":"toy grain guide crisp error then group clock coin civil space paddle","master":"7c02340aafc6a15a7c6accc312960631cb3a92c4a7c6d98c43897a1c4c55e59d","seed":"a08642010ea9779615e7a55b973f014ae8bd492630f9fc134159501e53a12d402842899978c75f553cc78c061b59210ecdb20648a1187ea55d85b7ef1b206c6a","priv":"83ab8e2ebe208b1f32ece9530ddf03e0727d3313903ef13b2d09a3952dded8fc","pub":"028582791e93e6e6b4270353aac091a58922c0067fa440a645dbb4673858e9bf81","addr":"4f37f8c3b16183c245ff4a101bc290c3ea9eafa2"},{"mnemonic":"atom border bubble lift day soft rich rely gather ensure that arrive","master":"e6936ec3f9876ca2c44973ee13fc02a08739655b71a9880b0c7959f9c5c12286","seed":"00fcb87f619a1033adf5c9311bced58ebd5fe56a70b69f65b61228732337ac46cefc48b1e53ed5a6b0ef658b002fc162ce686529120a486230f3845250ca7f70","priv":"4e527b2fbf28914ffc78f84031c462f3b33ad8d2b62357ac816bc4c06c0767d4","pub":"02b77c89d89bc757872025a0933d39ee65f5ae037031359cc1e692dcda3a290c90","addr":"8c8ed73961a3055cbaf4ca0b5ab0b0f56bfbc32f"},{"mnemonic":"require panda tackle valid tenant treat boss oppose where thunder zone rude","master":"fa9c61113d7c7ad38850ebccbdc2301c451ad272d86a7b6ac7b384c4560fbba8","seed":"936d1b0d443630cdbe8c98731761ce80f980728cdb122b95753ca3549670dda6663bd93d03a5cf601edbeb0b835ba3e152f940706aab856682b9de0a772e219b","priv":"9ca97c10d757f03eec5165df506d1809850b1d8f9369a89b0bb118d1ddff91cf","pub":"0368a22ead8cf1ca5b0bd3b6b4a680d47de8342b47d7205f4ed41e85299d2f9260","addr":"f03eaec270d04d368df8a3a5408b9c010f283b8e"},{"mnemonic":"thing gorilla large fog mutual hair gorilla soft venue ahead neck remain","master":"4b3929a08e30aed05400a3a7fcb91fafa085de08402ab546258c10346a21c14b","seed":"af471c7488c0046d2eb29429369a14b2b3bd6de6e89036285dcc9a121389323bdedfd7072ef9bccfc1ea472bf8a9d3f938bce5ff58b303f9c0b24dfe8185d917","priv":"13d5e5fc0f6c184e4dad19c4537603b811186a3a5aaaf272762ee236bc826367","pub":"02ecb5330e932bc89bfaaa8682e044f6a1c64823887aab000b2409b467fa94da4d","addr":"c6d1e41d9fc95706c276d85b5d93d657d59c045b"},{"mnemonic":"ketchup blade myth tackle neck gossip obtain write script grace mountain glass","master":"3d2d55b2b706361eab66a2724609c1ae6e7bde50f3ca78dfa72be5e784798ac4","seed":"ca3ff2b26ce97cdf280654a05e388ba2ce5ff909e3bf253b35c66c4b9f8d630a81c6367537039ad09d05ad7fca337c479db1b34544c26331c5fb860eef84f953","priv":"968bf9c285110ba33def9cfc3f47c82ff8050b854568cee2ac509191885c4c7f","pub":"02d8719b0bf9e5296ff70bd88c8eea612b5161e80be5315a9cbd4ba84eff6dc788","addr":"868855cc81bfbc80fccbe3f1fd2d526db7cfe298"},{"mnemonic":"violin toy phrase advance banana timber viable half nuclear friend bundle injury","master":"494774c8eec7a45b2e54e69d4ca64766ada0b90ab1d2f6913690b7b43f489b52","seed":"d11d7a22d020dd5e4ce9a9c162637f47223a4162d5b1920d7ac83d99d73c40ee6b67fad2c534f8100d2529afbdaedf7d2a8cae2e921e8c6e02e3bb8d7417205c","priv":"57827aa1804ff699ea31602eca3ecdef41b722bc2d321187b48c5780962c0f73","pub":"037fd67f44683a2613f7b049a87f47cdc7710d0a834658091675497600d07b485b","addr":"6b13a26e1a545c77cedafc8592e55363742b55fa"},{"mnemonic":"forest unfold spy harsh pitch alter bottom album renew siren find bomb","master":"f19401a9aea13a1daaec39107b9b860d4159b8c66118bf13bca736937eed4e61","seed":"606f8fd5651b2b7cd9e5d9974ca44c8dbee170e6c60ca3d7a4764bd2a1a31ba79b60d0c32b40f2998a3fbe784edc40f93a917f726d2d0a3a07a3871358bc4f7e","priv":"40bee09d892253ebaaa28579840239123740d952da7bb782e66410998405c2f4","pub":"0310455b5a6e7c5d4d09a3ea71e2dc7aac95e8457e6db3bcd605010e6e8f96fa7b","addr":"5d40749e1f1e8aaf38b91c12907f561668f3c691"},{"mnemonic":"goddess isolate speak arrange tumble ivory give message palm wrist slide drill","master":"424c0dd576d73827d765d558616a5c5abc92ff548c82cd6e5a277a5a316e0245","seed":"36d58066ea3378f1851c1e762f36697248c2799dd98b19d74e69aee16e497e4014244f62f696f34dbca202f78f7b6e21585f91531bfb8c3576f910eaaa64b524","priv":"f0c0691851dc50e5ec0897cb29a8e05032b7d02afd774aad6904ff44088f2850","pub":"031bd47b8bd9a56d24874a1df5c15834ccd5bf553e7858e2cc1df2c045966d5ea6","addr":"eb4f13a437254adfcf46d5cf7fafd4b2a059a99b"},{"mnemonic":"penalty trigger panel ring menu toy behind forget tunnel various giant melody","master":"770d401afbd35db8afb7a1864b794ea5a59f2c65127457d4675128b039638e73","seed":"81256b9fb40b02feaf3228eb300d1b002f9a8c0ef03a2b0db187b265b09baa4fa28ae7992c1ffa893381e572331a5016e6fddcf3871d1d836e92ba94a44d92ab","priv":"380085bbd1a2e2f50eedff2c758fb63f981adfe46a25db54ce7f1d7a68b6b7a5","pub":"0367f233e57390fb166e45ad792a054ba908fdbebf11c20a3c199ddb134244b7d9","addr":"ca1e2a50753d833d16c10ac03551839734b5e3c7"},{"mnemonic":"usage real inform betray ridge call coin warm meadow gossip river predict","master":"8aa38fef2d5a72f6e97cc57244f0baf53b976ab7263373dceef0b46ea52651e7","seed":"9b806b194b9afe0f5f46b4b40c4658198445b53462b6aafb2b1e82e1c98fd29731d193681ee43f3d9d70547a5f512344809e02d15ae441916725da5e63cb3791","priv":"10835079af496655bc2dd80c40c0b10f18788fbb9350a7c3f2abfa3e00ccbb2d","pub":"02a3077b5796d8cab9a90186be1c1456d75b3076760f2720225bf4f38eae7c0e1b","addr":"f7deda6ddbba1cb091c8091d2e43c01408fe0d8a"},{"mnemonic":"mechanic share spawn limit panda quiz glance dinosaur gold skill initial replace","master":"0a84289f0c2aad1de0e750a0312a2a362f99b8f0c7a15b1e11dadab1df18593d","seed":"c45a8faf2b5af3ddf883837378d03bf6566c6369005df0c7995ecc9718e2e1482fd42d3411b58bb4a94a637c41f310a8faa0209117031ffe993c0f04b2878935","priv":"10bb410b31a37b51b19165dba5171d33e826e06f83b8c590a23b9b2c8bf11b45","pub":"0331188abce7c6fc99ddee0d7335e872b7cb2f48a7ba7dcbd9ef093c30fa16a5a6","addr":"d3bd3dd9d928d4bdeaeefedd058ccf7047fe82ef"},{"mnemonic":"velvet renew spread mercy volcano always snap column loyal possible ordinary sock","master":"a2fa675336bc532f8e1c253861eccca1909a195238dd202e45f2f38ff421e721","seed":"89c8378d8a7c2a2ef02bbcbd2da9e39f6ef138db1d02e32cfb492c09a132e726c69268f9743e464a8421fcc0d5a0bbdbd00dad61798736c673df81515330ac17","priv":"ed486dbbabe3def74d052685a75e65d25970d8d134724968941a6b8e94fa2352","pub":"03a06dfdfe1fcdbc8e9ae8d6c55ac974ef4075c8aa0a5783bc87f9d9c2d66fd5b2","addr":"00c4fc7760ae8f7986f35efc66d18401bd352978"},{"mnemonic":"secret weekend fatigue anxiety second ramp tribe employ quality yellow game choice","master":"0f326ef21360ac2929e4f8becc2e8320cb49970ed229f987f15b9f58ad383d96","seed":"a29c1dcb8899cd716ced74d2d81cbfbf81eb8b7ca7ae0214ba270be71e8f4a77d235a607079897f6ba6c5aef44da1005f3ba8195775a562e7d243b2428ea288d","priv":"db24d2fa242ff540009bc15ace40783c1535812bd0c79cb145187e4d648627b3","pub":"02ebf506214798f631572bf5f45321adf084d457de1425c929059bbbc328948c5f","addr":"27b810c5c8307a20b949b3945b82c0ef594bf192"},{"mnemonic":"crouch gentle hip then measure brand enroll camp vibrant lunar still action","master":"f10577e0eeb7b2385b797acad2bb4e4028bf1ae52cd59f0f53ccb6eda0727166","seed":"955eeb623726361c94806c10334bf9b1df08737c2b09fc3bca332d9f8008c5f357dc69e07251fa2cb1330c1099352e76ab445f824361533a8e30175cace06812","priv":"2e0602e9dafe830a4fe783c1b53f9c9b2f7dc0b69a52fe701f0bc6f88beac1ea","pub":"02ca1fad1e6ee189fb124863445fed2a9a923d7ec23348771d3789978d30a275c0","addr":"51cdfbd7d00e618d63a64bc662cacbc183fb2b9a"},{"mnemonic":"cluster slice enlist shift world satoshi mesh disease season ready can strong","master":"74d52d1a33a53a722c7319883ee0f47f2f76f39ff17e26b77ade53d45df83a5e","seed":"cf8c965548281a449796c37a12dfacdbf395e474b5336073985e5d7e794d80ad0ff5059a3df31381d9eade948dbbb898f4fb7ff697d2f398655573170b416329","priv":"5b8824e9f9a0cb0c0fc19f4d06921b32a76e1baf98c249dcf01c77bff2ae59af","pub":"0309e87c2c54481db5cb4f7802d2488872f07fe08dfc3a984b932246155dafb6c8","addr":"dd84fe8fef92aedb045bbf091b93c7abf4f34352"},{"mnemonic":"series element media flight next blur fox impact joke review token emerge","master":"1841af9c8f47747ac1819c178e62673e51e2957292ee608557fa38e2ece61d6c","seed":"02de6354734c96841c8fdff0806fc5a0237d621ac98acb7eabdcfc94e458bd2e7d71a9de2f5107e188e153946798775450aac5c62cc293adda42a03e0f50edb8","priv":"a118a4e3a22a82e48a4847a644c452794946169a39d8919c02f131dc177b4c8c","pub":"037b3f5d214185886313379351ac7e6ed054a7db85b9f5aab74e2bb78abb519a2f","addr":"f70fa3d5dc91e442851e6cbcc827fee336bf267d"},{"mnemonic":"engine surge protect goose warm bottom frozen menu royal fox escape sword","master":"9ed672fb3cc919f26c925be30c6dce07dc101af5baad5b6dc2264f5580819b3e","seed":"21bec398901ec8b5b4bcbae5aa2e261f96190a3e9350c03a0e23da3755a4d36ba0532ac17fb7a41266905e76f2d72e90b577e86bd6b8f7ab62a4b835292a94be","priv":"0c386e0854877e7a34bd8a9c9794f107ac2114e05130861f77353406fe9db555","pub":"03a3740fa2bf35d6248bbb7be20d6c264dc526f382f72696a6c1c28ecd2bf25944","addr":"d59ee54eca22ff7873b68b429be08245b836141d"},{"mnemonic":"dignity almost rebuild habit visit come carry deposit stone page soda room","master":"f4eedac55ceae98a3bb706c442d3ceea7caadde17ea5a2d0c81cefae9af754a0","seed":"5ec26bdfbc0d587473ceea390a99616a9c8c4a03527627983cfc9cca8f7779d1ef7c08abfa0969eab1da7c8128cfe536b6d2d5a07c99cd1afac0052e8a753d7f","priv":"4ecd8b9d596eda21b65ed39c8f53dc6ef2e19726d6eaec60da340095aaa3be91","pub":"0392dd87d441269c56e78939eaef320b6a9c0f0ddf5758e57663f9f268dffccb8b","addr":"eb71c884b8e3c1b215445ca2ab5d5b51a6bc0be5"},{"mnemonic":"input sound bacon tower fun evolve song pear various laugh code sausage","master":"b0cbb2481cc2a131867c6514b194146b937a6e46e497d6b4c329d6146433b13c","seed":"1276370b1081d2b48f45f8df73af1eddececf2076f8425fb0b593557392f3853e5298ab5a55f0e367a578932f8daf640d40d8465ffd33ab4bb6c41fc9a4ec9f4","priv":"c358f0d976f10618d3d0a600c0ae754fb2d0a2a97a385091436178ef4bfa332f","pub":"02b2e45327f09ab88143f72f6bcf5f4fdcab9101d55e015022a5f7b63bc13b1a6c","addr":"ea33c880b7f4cbb849c551f61ba630c4d9b97155"},{"mnemonic":"tool lens message country slim wide fresh front merit science argue cupboard","master":"17e462a6a8c9e854a6a7443f0f903749ab8967d8fb3a42af27ba3c2819d0c750","seed":"506cf27425374254890839b40a5a05218cb5e8d7c143523058f74d2f955c5cfdde30cf034589fb7846b9ba3194bfa9fc1eedbdf2b706b75c9b51719cf7bbc663","priv":"995d94dac98165acbec37aa586c52d9c7f0a65394027e3350338eeb69a801155","pub":"022f8ae9595f1f48654fb99985148c5c041dd4a1da396ed59cfdee3f09d7166e93","addr":"23f909e775cadd631b1b3c75df7027382b702167"},{"mnemonic":"beauty fury random thrive grab merit powder wreck affair bitter style girl","master":"2b5ebd0f07795968a7fe8ba12da106195f1fe540d417190ddaf4b11527e5f2be","seed":"c2df6f955aa168424697c97325016298ad6361c3a197ea9b446e790d0b2e877f03692a86dbba512e4afaaaa975484969c14cf0034cbc3f5571374ade85e6e714","priv":"ba6c8ef770c6258ddf7a395670a13cbf661deccc4edf5601e70bf44d1d40d63b","pub":"032f8907f58fa7592e6a8ac556f605a981b7cc80c94431e78bdd20ba086b22c2d0","addr":"9fc0563bf0185e0e99f266af339220588c655280"},{"mnemonic":"code aerobic tent hero install segment truck foot employ manual dice time","master":"bb99c30775706beb704fb7a7416c778c295b82d93c8919d521ee915468143401","seed":"bbf14d684a22d95920436c3133dcd0748dc6e3a133fc61cd78e9f1bc9aff37c473f0ced555265f961d4b7e70b6151c9c7aedfe6930e6a352d2da531275833a4e","priv":"6b766aad48cd0ac49d4ea1cb1bd9961d0c0d2f38f241c1b1ac2f1a8b1f7f86f7","pub":"038450b54d2d0dff23c557b3c66613605dff4df0afd3a5b22dc1c93711c9718d01","addr":"e50e364ca287feaaafc0a6b1cb1bc8f3f1410a02"},{"mnemonic":"media custom wolf spider bitter require blouse soldier barely pause upon inspire","master":"83ebfa6de22ec8362e519d5430a1479c2185bd44749be80f3f5381cc7051d125","seed":"ec99f944a7043eb3da146ecf22086de374cb1b55c64f436f9489b7f4f1e0ac6adb0f937080bb20405a4b225bad173729abf5517e92c3bb75aeebb516893d54b7","priv":"0771719a4060245c49152ce121c01ca8fefd04eb559a610a5a084a772741141d","pub":"03b17977e89ee44c699e018352461bb244a783c4e2187ed49fdea72a479969e745","addr":"493f3d15f460402da46eea1dbe4b767273eb15a8"},{"mnemonic":"build key hope learn place romance parrot ask spy whale input chimney","master":"d3734ac55147344c1aa411a2a161f42710308a5463ed2183b9cb561a8f1a92bf","seed":"5065c3b0a1b3273acb090c991269ff667513cf41e34a11cb802b8880591fb5f9e89ef614306261b0ae2148e5747649b6d5a375ada3749e75e084c3b28faaae4f","priv":"ed51941c62cb63e1e232dc903894fd4c8797d69f501f41f85e1763745ea7247a","pub":"038ddc7d19d6bee458f791b34d2acdbadbec78a228066a4bd5434ae538597689c3","addr":"ee83ae098ae348e6c5464eff4d177c04e97862c2"},{"mnemonic":"habit pill guard artist void crystal various owner shadow inspire plunge price","master":"c0a23d72eacc59b5a382bbe6b59d4541f5c65abf8840a16255a1610ac56df1f2","seed":"d7d1bc83db47fd6215a4e193f654c8246957f7f62b6f8b4766ce867ee58d69b01e749abebb2de94f607e2c442554047a65570c4ef1e764c56295a8326fefc232","priv":"f2cdd0461e210bbc69f810f796189167a71aef2fdd769487c772135924d35060","pub":"03a0ff432ff63da4b30ad757931bf41927c0311f632715aaffc41f1a39dad92208","addr":"a9fadf07acb53dc1003c0de03f40f73767cf84bc"},{"mnemonic":"miracle chest bind idle bachelor science catch scatter current argue fiction ethics","master":"fb1730aadf636789c12f30bebf66b5c9b7ec1138e126b9280491f61013e094b3","seed":"2139c6cd3f1788ca6f91147c60d14498295daebfcb65f0732d3c2d327a1ec8e01cfa011e840503f5c49c89e9092ac88e5d688d0fa945b604a851fe4f4b48e404","priv":"a4d77dc6678d78fab38419b72857914e5848c4daa7bc8e47e960a74708fc30c1","pub":"03b946212019343e657dd0821422044234507602641f389ce1698256054e6b194e","addr":"c67df9937478387372ada7cde57712ed05e6cfde"},{"mnemonic":"garden box bus under chat pen connect access police mom crunch elder","master":"c49d46b19d0078803cadb2a63572295a9cea729fb31112b48cdddc9311ce874a","seed":"fab44285c884dcb44b1adc9823cc021c0560a92bb9ebe23ddc25a08c68935e64733aa1f7b7a4ed30494d8f74cd8373a77e114884f74e6804696cf94a6b0012f1","priv":"79ea8bec554ff6ad0f20806224d7f0402a07fcac87db0b4f5a6cf84221cec17e","pub":"02492778ff035fab9ee383b424a90d694121df7cab7ca984aa8a665693c44cf726","addr":"2a899dd4387375c42068e42fb90793e5f689d413"},{"mnemonic":"morning street camp meadow moral chalk pluck winner light same grape drill","master":"e5a773479add64869e28f1d1a01fd6200de25fd53debfb000504a6231d2ab263","seed":"5e24f51f1676b996b470c01db9db032958f58e1d22bd7efb2bffc55baf73700d948c5f82eae0f6b82f0b9158141b173187ffbf4fc792e43af194c992884d41cb","priv":"4794fe7f9410adf7f567728f98daed1eeda0248d7d0607e57c4ec184bafd8504","pub":"026145b6582ac105e06921c3856db99ac7ff518621d984214cf34f5c155f0c8736","addr":"f263e7676644a577d7b535df98f7eb6d3f45fcbe"},{"mnemonic":"annual very slight slush tomorrow stage mother girl forget castle emotion move","master":"53725daf3dc76a16b54a2086106ea4eec394802f70741e2895a06655ffb4ad34","seed":"fc6f22026780d6255cc7a21746c7ff48fc773a350784471350837ca92d9131e9bccaf78ddc60a5bd8dfa9838755dca0c22e6efaaa757a5bc4b2ad341e4cf5d15","priv":"5296ceed1517058d022c8fa5c8e076851745b98465e0fbbc834a0aa872222bbb","pub":"028250ee9798cccbba647bf41f7b338ab4d15f7e5dedfea1857213e125fc8795f3","addr":"82e76dc9270c795c2316a618abe828dc2f09c1c8"},{"mnemonic":"novel swap prevent funny lyrics erode wool pilot kite junior alley inner","master":"dd900d54ceda698e6ade447839e3eb3f64cdaf8f006d41ee8e1a2f3b66b55754","seed":"8b6b71539ed5ce60bf33745f1172fe3de811affd5a494050c4672f2acda9b4af9aa57fece9b8981c94b1b9701eb27da0f67b8dd216418ddacfc5b84f0c835c03","priv":"4fa69bc81f76265d4df75bc208294244c5191ba7c8d6350bbbf4445e90b9b4ec","pub":"0281946e059cd4dbf81328a3b01ea285e106a390ec6a1b938327a26b85b3e2432f","addr":"12e1ca832d7826ea5c85db514ca80723f83a59ab"},{"mnemonic":"film erode thank mobile file ball inner wasp unhappy borrow polar mass","master":"61b10af9d2c25aac6bf1b1d4fb2e0899c86e40b5b3aab8a29986d241aaf6d414","seed":"f1be2b5ead5055a4446bf8d608c754f4b112f25780aefc7859e9697954910d827969b8ab2d78582ee6f91985c7f740e3d5d5ad08a7f3db9e265aa977d4ccac58","priv":"816f805d3076c855f114b1f8fbe1a1476fc02a71b7b800d6c5fb9d3b1094adf1","pub":"03f08001ebfdcac89f9d4d4cd52f8529b957a6e1ab500d541edfa086ffaf219054","addr":"ed2fc0f401d326f2ea61375272ab741d648b690e"},{"mnemonic":"aim owner direct pizza enhance range need raven divert marriage gap hair","master":"6ebc5c412f961584572008b5d531c275d45e403f3e3672c12457fcdedab52be6","seed":"b07c83efb4979dc2978756f0457d7a4574f5ca3c06c133f2b9cae206f12282c29b8fee9430b22a347aabca5fa91ba9a742901aa4ffbf2a1fd5a30b7a258e0566","priv":"16e205a55aa370cc54cd05ea3805858561f4213c315a4cc91450097d3bf75d45","pub":"0309613fee96c3c5bd9af994d9805aef90ec3b4da315a2e7731f6aa1c25c28fdc9","addr":"ae3778cc1c0df866034a0ba6fd3e4d9308ed4429"},{"mnemonic":"base effort water actor slush space three tuna walk people proof siege","master":"96ed3fbe9c3d5647a24b899dbb2c67d69a629fde37f4973c6032555a48de4706","seed":"1dfbfe4c352e01a0d72fcbb4cc82645a81e02946ffdebeb465d424f92719dcde887566f784be14784742eafec3925160e87c4861663ac1ff722b554e2b1cbd37","priv":"7abe37156bddcd043fba717f9be6ebe3f9894f6b814390d0556053be00566e84","pub":"035621b9ff867ef93278aa007087ebb30bf8a045ea4bde45d14969bef6054e806f","addr":"b8ac9814855c57ddf5d9dd367af8d74bd7740f67"},{"mnemonic":"violin naive wrap margin glare sustain suffer nasty whip loan tuition car","master":"df6afd71e01d947df8fac4730e6569a23002ddeb2ab53ddc23c35349cfd55fb6","seed":"ad8e656352e03c098c0ddd1a5d9556b92f013ef9853264189968677656f0b12d6afff540bb8b548671ec2ed60a5bd61204c463a80c10e5d44380db05fc9cc4d7","priv":"607de82b3e17947b94b43b0dfef04eebe28acd497e6d5b7773feb983c0067b6f","pub":"02dd39ee3d3456e77be05aead5a1d0b71b03237929a8f085760d2e1496c3914286","addr":"2063185bcca6c0602cefec61b752ca5cd47982af"},{"mnemonic":"rug pulse coconut equal coconut soon helmet trim peace fall please robust","master":"a47a965d564ace3708293df5216eeb7b963ef1c814805acf55f76a9f44372ef5","seed":"e099210b6d5259379dfab4cbddaa188fd5d61cc9bf9354f6546db1eec25eba33a34ff535fa3adf285e7460aac8d724dd5208d08207064ff6d2f794f34c514747","priv":"c8cc7b2a9f01d89708fbebd824fcaf1251fdbe0dd4953f43a9079947cddaa2e1","pub":"030361dd18f40d337500a32de0adcc92a2044481876e17562863dc32412c8b9fae","addr":"90165eae1989ce6ab3edbb2d8d35cf843138eed3"},{"mnemonic":"expire company bean basket weather apology lottery energy column used goose advance","master":"66e2f9149b1c2ac8f5f9b139a52567d1284f8484d9cf338b016c4d361dbeac5d","seed":"a4218fc8ca69a1661bd0cd9d9a458c996c48502cfbfd72b0b018f7432ef41c8431f70cde82e7bed983e49ae7c01bae7de6d7bcc590677e166456e5a6e4ccc137","priv":"d7377837e6f73b9093b13741c27c8b25a0a323aa7046483b3f13e9ebf4d436f0","pub":"0368018fbe6931afeda06980639c2f5b532245eade554f5c2ec73f3a532d056718","addr":"a41364a6daca7cc6536aceb4a32e657f3ad22a84"},{"mnemonic":"track essay chase camp denial ski worth retire expire amused paddle ivory","master":"d764799a1d97bd937a1b9dbf4a0f7cc91bcd06c6d7c1a1dd3d25e2dc8d63b0a9","seed":"e3e62475c7d13f79f2005f61abd2f674bbb1613587b3e694c70f24f6403f0299140b68567608420af5a7d540a3707eb1817fef98aacc3e861c17172e3a6eaf53","priv":"b2369fb324c5ef9e7e7313a87470984de6ada9dbef59def90c594c374cecce93","pub":"036ecd0c3e3312f15b3ad399ca5281546366e33368c00d7066bcc371919df9aa40","addr":"42a6d89451dbd00904633f43389133bf199a090d"},{"mnemonic":"mean hello inhale jungle brown cause curtain arch orphan spy aware deer","master":"a66b0528350e9aab8e3f7985a658d50bc31d3cc88d145817f77f889de8afcd3f","seed":"3e240baee99e3e3c0030af994981ee7c10311faabbdd685cb41b971b647aabda05df165b31954506c1dcbda0d15bc9dfb3837d8561e8b346439d059431552c00","priv":"f516389c1d667c77455bf3ea25789d8fe6cbc52c62fdb54849f857fcd35d7f88","pub":"03fc762324c6a0ad341118a95cae96d737eb0194e05272b92160ad3412482d6fb4","addr":"0ee6e446b5713f87b9a8384c3fe356e45a4d6e49"},{"mnemonic":"clog just stomach title gauge park couch coast fault demise march smoke","master":"f964ec3cea5791c86c3740626bd8316bf3373dc874af01e2ee844c0eab7b9ccd","seed":"8175672d9e9e2c8e9182f0d6520eb1b0ce82a17a56d51019acd5edb9eba0c9abe7ba77a895717eae9bd565ff0312c65209c250ea48965be46292a4cf7c1ec7bc","priv":"445d84baed03c168e29c5167e6257198fb2f7fd6893b4323e692bf3514364719","pub":"03b43255f28016c8961fd0cf5dc49e427105f290b7025b6138ec444491e80e9be3","addr":"633349488a087a2789bd2a99feb62554bb35a4d2"},{"mnemonic":"silent burden donkey napkin churn equip artwork lyrics wage enemy fade sunny","master":"754eecf77fe825d148dd76b15601f36ea3c1a23b1535ebbff1be9695fe293bb3","seed":"c61d6da1ddb2a00797ec94d1bfe43df5d012c75bbb916e0ce42672f043a979e8cbbc4187867ae36edeec02c5526eb540f1ea4b9778c2a0b534d0b0e9d8a42286","priv":"530591f5c65acab37d4a98df46cd6c8ac259dd019dfb9c97fc34b1c9269cb42a","pub":"030e423006cf8ee7ac079b31591ffcd73f6d63b8e26e765a4b9f3dbe1022b2af22","addr":"e4da6fc6965990f17c8c827af0b0c2a2d9d87867"},{"mnemonic":"quick toast trim image exit clinic then leopard slice recipe acoustic meat","master":"068b8703650bc546dfe41908b04a7cc430add80d2c247784d41b4241a321b339","seed":"73126b2fcde7ca4509ee115803d5bcb22162748ba465c71767e32d5b271ac53c63168d2a16032947c1dc87d5e78e5117c0171abb1bcb4912de0331d7a7d7b171","priv":"a9251969a43a62c2b25f10aa0ee4d621cc1d5aac612b6027fab2a505a5dfa0d1","pub":"035a135e39da761bac2346f7b896ee0d2cbceac71d9679a201bf2b75e00ed047f3","addr":"f7f4f03d57d3726337478e5216c680c4543ca9fb"},{"mnemonic":"innocent struggle abuse math try bright craft lucky excuse fly nation include","master":"631066b05d71d61539a24b7cb2aa659f1a8d0e3dc76c5ea28d4702b18546bd71","seed":"6ab66876fdb7658a98dcd39fbaadac319ca73e280cc471ae3954e6899997f35576a4b7a506ce3c2b447ccca6203092a2c47f1018ba6d75ff58c416a3ae693f57","priv":"4c6c4c01ea2511f4ec731546f35cb469d424fe6af5dbd8ef3f4d27b7013e014a","pub":"021d951f161be476c1795f1987deea93eed12181b8b1a251107d83efe2d96c3a01","addr":"eb09dac4658f82aa173e5388281877403b124b85"},{"mnemonic":"weather fine valley envelope convince cheese primary scheme invest rely science pitch","master":"ea23ee8d99adbc168bbc367b10cec018bcc7f15717b19fbd05de7ab502701ff7","seed":"0c485f94abbe0e9ee91dd661eb2c6670588c712d7790e9d6357eb7dcc1f2bced5d0c8db8dd0b7aea72a6a057ac97a12980d753ebba11c2fb627163e729a74a8c","priv":"272a773d44247e0d0579731593d568c31017567d6dc29ee9cb2324598d1d7a6e","pub":"0305d1ee431078056588a2d2e503c40d1ec6070e3b06a78b2deb04c6de9f4b00c2","addr":"bbb37db4d3d3f8cc16178fa777ac23200c05d78e"},{"mnemonic":"portion visual market hurry enroll stuff upper pistol tired question barely surround","master":"997415f4d0711a371b522baa2a003fb6485f4979e170492c3104a18e7fb90cde","seed":"51a7489d52481c5fd36a703c9e832550f10bdf24b06f9ff023bec374c5089de64e6d06d61ecd509fb44972a92094b4cbe1dc13fc1ce1fa6ba04b03ce803305ec","priv":"8c8acc19030ae9e9ede5111a41637a7f69e624be9f098660247cf0154579018f","pub":"02ae3bf3047431b9d799b99d56bead936c5459039b965a612673a70ab9209e87df","addr":"a2d63ec58cafd042ffac57128bf9ed704d9735b5"},{"mnemonic":"intact elder sign valid party enjoy trophy mix hood bachelor near sadness","master":"fd40da840f8bc5eb4fe8e83611c5ffc897dc315583daf95a9e255bb8441e8605","seed":"e9f3376502c9e4506568876341ab89527694bd9f0184650c3f30fed6fe8b8b8705860e0c63276f0d92db398bfc2cdb4b816d58dc48a5b8ce9325139c1b96d682","priv":"bcc54e226725e41f96f81587653d60b736a8da21af6b24d9306bd6b94d1959e5","pub":"023828cc58f153451683a39c3cef165e8f3a5499eefe018f945b63062fe05dc82e","addr":"cbb390ec8ede1eaee76a40100c1b551872eed89a"},{"mnemonic":"unknown order purpose spice master small inch isolate loop frown page nurse","master":"b8b282b74a246171e39a795778958bfed4fce9aa6040c3e9013b1afc712ccb40","seed":"403e11937a99ae4a4aa3ba4e0f682c158dab10cc5cdd3b79be276e5283b0f91fb7478b6b33e30841b356cedd2091417a1fa09925e40c1ed23a9cf54484883129","priv":"c22ff234c4bb00b72005e1e88909dbbfbba148c90305eb81de0671a5d28da59e","pub":"024bfbef04401d5a5938c64619a6c566011b3cde0c1418f2b62c3a921f3d3f14ba","addr":"f0fe3107cd932d601abf273b7547be623bce653e"},{"mnemonic":"angle blouse weapon upgrade enhance frost fine pear install method duck okay","master":"aad7d48511dac2782ad61a97e3ca94352ad24590f1ffca0e9efc3c6ee69297e6","seed":"8651c2d20d4af238121b528fa601c290efc255a569c8db892ca8f77d634fc02f7098efb7a9a45262c7e86d3d71cd92c7239fe4bb780e69ded7782c00b1ee0ca1","priv":"4b8f93833d5896f673ed59c0bd75a34917a61d521cb8b8bdb22814a0da0eef19","pub":"02e17e65c69b471a9fdb75515aadcbba673dac78c0f34df920aa46ad65623400eb","addr":"c404a9b79ebfa5ed9066e06aca8e091c488bb740"},{"mnemonic":"trust huge gauge culture garlic fluid type drop arch camera true claw","master":"b74303ffd6d878d1ed69a0e406741b51bc725887df08a1c8efac15a959b8d0c3","seed":"715486a3cf1e3db172fce32a23868a832fe7d5ac2844990fc14e951a9a357f16e2b5bdc669e415a40efc7ad14020991497496e980395639a68c6c7b037690cb9","priv":"2c0d6847313ed5c928480a302bf3fa0bd9918a5debc3ddff43cbb4c9e3f12802","pub":"02f79fa697f78fbc6b154d7b14a3b28dedb6b746b9de88c0e9982a54904ef124d7","addr":"c15d6b60ea16407697665acca000d5f792fdd3b3"},{"mnemonic":"shadow sister evoke wing radar what trust main improve moment flee erode","master":"cb1d183803a2de896f83834d19c3e1ef518c3fb6382dd68ab310696bd1d69b7f","seed":"444b9c8d29447c024f11e3c6c1618e767d908dbcf380125a062ce18a552f39fa108361fd18561406eea36e63415d286eabe5d5a5fbd23ae5bfa846a3e8bbaecf","priv":"dd1acc9e8972c3bf4363b3411ed96f41477724b4353e514b339baebbb03a65bd","pub":"028658232d2a075b2c68a519c47d2d74636fbdacb8bb31c9af70a967682816ca14","addr":"f8db02ece9c267f8f5b7de9c801432e694e22731"},{"mnemonic":"guess beauty gift repeat desert oblige pistol pottery lemon clutch discover dragon","master":"67ae574f5ec3766b3a0e1699dfc188f0ec78b51e69faaba76dbb08cd3a9e6382","seed":"395674e7b70cdf97f6072be527bd79a6fcbfffcb4322786f8d17611a3bf87947a87fd59146a59e7143a427c4065759ed6973a00f6aa522e6b13058382eb8b080","priv":"170df49f85c0a741bd5a6647d33410f944619de34e9ebbe7387fe8785b470960","pub":"03dbaec7aec40764a0365a6b2b00384c7966e9b2c97432273abbdfd089c519fa4b","addr":"af3c030ae37cd0ce5d3c41012b904738c7905887"},{"mnemonic":"fire duty baby kidney coyote arena bonus convince soft party blossom brave","master":"2054fc16a8c8b5955c76150c43fe447fe7a6d083b323eba70784687f94780a75","seed":"c16d9aa8d945a01871a46a92881c10ffafeebc0b1183e97812169d8f6e4f094e70f82576947917f3f6e551a9b9dec573478180053f6e0d71c5c48eeee95b54af","priv":"fe7f533210200354ea9c5c972cd0a4445fdd8a2e6e6e830cb541fc894e2e0ddb","pub":"02f9fa53e71e4a2a180d6daba5ae9806ed5e338aa680e2bac8fe25ff1a1a151d0f","addr":"2f028ee2adcec5023013e7a3756fe18c9a87b669"},{"mnemonic":"poverty inhale unfold strategy insane usage festival dizzy drop divert august head","master":"148e592f2c22b1db9d693e3777470b27ed0fcb2de1c0ec2d1f9f47421ff98cd9","seed":"412368afe4a71e2a37b1f87b7ce82f64dbef5579b16a6c189fa2ca29759e410b7c1e13a7b591711fb3d5bc8fdcb3292b3c828e52a2c1cd20aa55c830b8506a39","priv":"7e070b5f714cc7e0e031be68dd03e6b3e18673b5966d9c17616554df4e0f3288","pub":"037227c68b192bd6ed034570d5b5d532354dc47891acae0815d0acbd8d0346ac2a","addr":"439c830a56e6f8299c4d859c2cd5fd4a821e6dc7"},{"mnemonic":"gossip quarter proof require develop about olive boss fiction quarter rely build","master":"8b7580ddbbb3b766cd08088792cde2429c003b8b0fa5a9165747275685223a9e","seed":"a3c24f6f125702480e2d8856095a96f3e6d596678f15817414631ffa525472a01bceb58a0790e1df38dbcceefd73dd9b6bbc5bab841503daba8d73033494c254","priv":"5bb1bd6cee64ee4cc9b08f27b34dfd3da9ea263cd7fe7b4d3fc8a6a2db4e0ec2","pub":"03bcbabf0702cd56f459b8cde03db89d3c953faa3c108e90b75c65eca10485b5a4","addr":"c3ba63ce6c961c11bb3f7cfbe7667ef2c1ff19ad"},{"mnemonic":"dash small ensure soda crime wheat future style guide repair diet panda","master":"468770a80bd9e0190ae3a7a695da6a7bf30ac9bede3805c7d1dd4f6052e4d7c4","seed":"59eeaf79145cd625c266dce31faddd42eea93d15e64be3a430b9fbefdabc85cc3366115a07d819bb5ee026e118ddce46a2d906680b59917ff7adcb3314d6b077","priv":"99813e574552f35d2ae337f8754afb37d8387129c5e714461a0b72cdb30d0bd2","pub":"039e8088eabbbe966cfe54264bd1335697ca335eb55d56a89ae6a2af0bcbe2fd60","addr":"b3926244d741397940f6218c6db7a7c71cc012af"},{"mnemonic":"profit brush exist mobile diesel keep oval guitar cover maximum media file","master":"f402407479104621247ca60a34f75391ddffac32511b61e83324d85d873f0da8","seed":"6d538602ce7d97d7cb5469aede489a9a4f8af829d76712c13e7851d9e63077dcea3233ad51a7c311d367d4d982bf963c016c23fe39604cdc3d1dfe25baf1f515","priv":"cadfc276bea3a62afe66fbb5a4d117aaaca562b272aca37a0ddbd5f5a20c95da","pub":"036aaa723e425f879d4b2e731fda45dd95294608daf9d553a40f59fc4cdc37c996","addr":"0b6a4c2a542c624ee95719f53c99e3f6c6f7df19"},{"mnemonic":"oyster twin legend bubble bacon wisdom affair bar search just daring teach","master":"722c8eada15c60706ea1a9fa5aa6225142a623d6f5bd946589b22b3c9e69f56c","seed":"2f3967f0ef31b8d1bfe4b125678ab07328ada854f5bb589b5fd2c5479c3306eba54233f3386409e4b68f95be7f4b20c054f7930ab022f720979c847bbac99b80","priv":"73b2d8daa926db7e9072d4576dfbd511017e1ca7876bfb453112c8308ce70fef","pub":"030a96a78ec8dbcc9d62b9a8ce221b0f740358e75ed7ead277b56a2c56bd93a468","addr":"0ab19ff6566e8294c16e734306415bed696791d0"},{"mnemonic":"say poem daring wild toast force fall bread cup crane next patient","master":"89a87aafde53a9a8fea6b38549b6bfccfc950dacacda40f83b613a6322299164","seed":"b86bdd449d73412f10419a9534fc545a5f062d615ae197b6ce5143a1b00ac838b09e9db2cebd5cb556f469a4eaf883b8d9683b222f9b8843314134bd718b0887","priv":"60b1a4533e8afb1ac5eb5448db1540b859fd3650dd4e7c52b8b1a98ad3eac169","pub":"0255161266504a58a273b413e75fba8ae3c49046a3bf8334b2bf4a203f837ed383","addr":"2c390e3e85f391607962fff3ef9c3a7ca4ab5704"},{"mnemonic":"bone path relax awesome planet exercise road reflect life ability device frozen","master":"fd23233c87545130d43a46064fa11deef11d56a3cbb0a2e52be1aa21eed24f58","seed":"c72634cdc1fb47955eb7d9fd2391b3098d407bb5da35c0a88fcb38746c4d673ea113a96707828b18549271af8cd0f9be51f5caa9718ba31d783a3b26d450e7d4","priv":"d946ac6ec053521443b3d8d2dad6e947dd544b58912fa7b87b0b7b55f8570981","pub":"028b9c6677d3fce87d4b324ad336e486d382f7b56c2a1c8723d993d247ac1e1caa","addr":"6ed322bd71b762e44bf4554937122492e039380e"},{"mnemonic":"true solution afraid clip year symbol burst alcohol orbit village arrest balance","master":"3cdf923de0656e5340979c614d12ca869b97bcb476f8ddac3c10162cd23ceaa9","seed":"13c3eb909b83529db1d166eca7cad6b918e1f58c6be120aae8b7fd2a2c848d29550551ba3d710cb4d4a8597485e20535d6e65a941d206c69774cbdb04113ac17","priv":"1432f702f33b6c318f79d2655da268dfba6075126108cab3c8d88f4de2a6a0e1","pub":"03d100bcb7a2b81bd8e49af05a92c9a874f4aadcc836be590d63ffe8a08b63a0a7","addr":"3527160f146f542703309ee02b4ef783416fc9e6"},{"mnemonic":"family trumpet pact beef stand naive book escape ensure puppy envelope dune","master":"ecc1fb248992b1402eafb7d3120569255268dfa5ace3d04fad48b1917a42c3bb","seed":"f0f55ed35029e7f123dd153df36cfc9bc97c633b9b8752264bbbc2c33bb5932ffbd1d657bad87f8ffd7d4d9a9355226d2155fff92109adfe573ec67a18657f3c","priv":"8cd151b71c1f1424e2f53a35af5d427965f453572a211d8b4315894d370184b6","pub":"022ec5ca227ab19d758ac5941b9e7e7e13a06ee9a59c94d42dd6d013ee7c3d1cf8","addr":"93f08bbc6109187bcba87f2b6bf86e73eef60483"},{"mnemonic":"feel grocery tone drastic clap great pizza artist current true diary suit","master":"cf0614735905c88cc0f2236dbf71fc61accb6fcba39fabbac4ba1275a1ce6e9c","seed":"75bee915c2f3216cd023b878d06aa4d45241a49d10085b851303bacf82c36b392e01478359e59b54c77882948aae3026539d687298b85c3517f31ec0dd80e213","priv":"03e47eec1c8f7d3ddd3bf1997bdec4802a5b997e80a9a9fdaa8ed93f2641b146","pub":"024adba9bba7c596189ff4b057a2329740e03166cf6416612676d68a6df32c56ae","addr":"ee63795d783ab1a27ba8fa2a64665c6a563134f9"},{"mnemonic":"health across rare laptop broccoli verb course bacon offer hockey vendor venue","master":"a80307838f0014f827d55ec51e5384722d7a6a24703d757aabde32dca9f6dcd0","seed":"5fb4a16684f338f15b5fa6ea48975ababb129b3c01c726493abbfea837757fd27ff0a70bcbe2d08a7174fb7848169f7e22f483b8976adb0a4b2600657c9eb912","priv":"255717f5e26bd51d607b059c9a7ddd153d9bab0e832596df648fa671d8535d5b","pub":"03ca70b2fe6fd3def827767c0b26b25534bfe22ac74f77c0c4c05051154a08ea69","addr":"c4029c4186f3e762228f4d43b4d8fe19753b99b5"},{"mnemonic":"begin step squirrel window liar lock endless maze health galaxy swift scrap","master":"53ce62b273658f9ee3ef5b78a4e9d8b9a84f383053492d86825cd9d360763406","seed":"93d7f29ea325b084210dec914666f70ed46b83b7818d2dbd1614352134dcb021d539acfb2f4d916fa5ea48babd11d95f12eee97860c19db1bc2f369c6cc96b93","priv":"50455038499b153d77f388654037cdf614bb85ba5470d8937fb108a123241521","pub":"03f1f12d396494513c14a7508a9ad1dfeb1577af519a250b48798ff59f5efde3c4","addr":"5c46de48e642722b4325afe8446608a60e7ea89d"},{"mnemonic":"snack fall math great upon wing casual acid clown despair cage heavy","master":"c40433c68e968ff1081d3ffdd47249f1bb3cff2214f4e0f19227442f8e7be4ee","seed":"6962c13ba9d9b79b31480c117cd1613f6bb9dd6613e42b17b7434547694c96059026355a2c58b682ebccddc5f84f50c05b60b517e27eb693f1eeff24a038eb0a","priv":"972881fe79c997d86f11440cefc6c52a46a1b3b9953a255da6488e7ac278299d","pub":"0276ddb2041eef2c3b487a4afb36de7cc5ce5ee693461aff375131177dc4d28b40","addr":"17ed4db6f0bd80e929e048d526dc55a74ad58eae"},{"mnemonic":"vibrant valid carbon wish bicycle adult hobby lawsuit problem toast clever lock","master":"903e9b75fb472ad89da3b1bc74937415e877c1973910cb9ddbc85fbb465c18e1","seed":"b175935f86b62ceb93ed1bc1d2f3aee77a628aca7def8f6761df8b624a29d495a150b373d12a5cceec7d394aa91d0e68c5e2464a99820ac5add276d655be28d7","priv":"dd46bb3b1342a5a3c3844ef7fb4bcb247f9a81a48e20722faa1e03ba59808191","pub":"02bacfbf1b8b6d4a6e8a36b913d61831668cdd3dc74710c0ae0851b87c65789edc","addr":"e0520de38f2d2c2d3e461b1e2fd3076af5b9e927"},{"mnemonic":"obscure false outer neglect transfer other index debris bread crawl morning scout","master":"601edf66610cd4b9467bd73418a3dac8b937ef2d08c09ecbc89110443c3c8869","seed":"9d6168c1331c952ba5c2b19a0894bddbcd3d6a0960ccd5fe685db487ab8caab4109e2dda7c487d6161427895a9803ef3fa857fa2106e48083587032c6d30a217","priv":"2389d4e6527d9190a9ad8720debd487a00d47d6ad6228d643e1307aa727d1757","pub":"03bc72643c1c9a13f31de0a61815f950aae5e186328d07bfddf8e1dfe952fa8b49","addr":"add81ed8c06032c52445dea0db02a9f56b738742"},{"mnemonic":"minimum coast chronic damage page antique mechanic material worry alley nose tray","master":"d7f00c2baf2037008e9d1fbc1acee85127db59ce939491aa5cc19033f55f51f0","seed":"0ce817dd3a344f8dcce47336d3bff28da5cb9f5a71fd26e54c4229e9c0bf943077826d72c68e7570804b1992646641d79f8ac1b0fe157b7e12c70413d9625e22","priv":"76e0ffd8727768a428fef6d1e4186459d6b3664fec801ec542608c955dd8974c","pub":"02c0fb2dacc13de0d29fa26144d0974f90b97ed706c16ccdfac02eafbadf9e4e0e","addr":"e28e2564870c7fd74244b111e188dc82c27755da"},{"mnemonic":"evoke example emotion suggest apology uniform giant empower future surround pizza scout","master":"ae3bdaf7acb6660fd151ed30d5d299f82556bae13873f6cd9e65111d991b4d00","seed":"840044591bf305fed33beea796f2c5a8ef72a5005797762ceb8528e1c0343696c02012ef81a8e964548af3293454fc6e3329059e40a95e9225fa254fa901f3fd","priv":"2ae6395640b6827f7b3af5d2a4a0f0df46d4c6c5bf28528eb3a896d60c80e0f3","pub":"0378059ff10a1d3e0ba1876622e9d45a9b75f01216bf14737a68b48138920e7adf","addr":"c1333d4372eb2dea3311829c10c6d12f17437cb9"},{"mnemonic":"endless come happy cause skate short list laugh amount marine glad pear","master":"c1643f331f86b0cbf7297eca946e44d0d1a1b3e704b6dfce6d53d9e9c6eeecfc","seed":"f3901b079e9987dffb0378a76f099e39349cd6abb9c59c23ac3f1cf90b988e82b71bcb3466b7a2f9e04e0b5b27bc945a3b4b714e0272184cb64e9b4f8d6a638b","priv":"e80f64abaa7b55214d94b2bea74d25a45bd6385bb2447fc53adc4be4820edffa","pub":"036d7029b6f83bbbd1238bfe9a2b8ee654ebc1b2ea9d00494345783342705ef7ae","addr":"56fc7b9a42b8dcf74932b92934321f2568606240"},{"mnemonic":"boring math photo park connect wash captain drum kingdom replace exist beef","master":"4853a21045f669f43eddd0df88100e473320d2f76641ce5f9d010d654f4896c9","seed":"65e6412f40852556186217c0ffddd4291b77651f8568d97434f1ce3bafd4784642d9eda0c401f9ec57ffc80c161832afd43ab89080fecdb8d6a2570b27b2f0a1","priv":"67f6f9aed318eaecf6e80b3a89748900f3dad77502893e133024616c15418799","pub":"02b0f15eaa2f0b9c09a03280c9689aad73e3e60e6c971ada22b9352cf381d9a7ea","addr":"741b1795cdbffea0b144b22ead2d466413bc232e"},{"mnemonic":"true also hockey holiday increase humor main lonely invest modify penalty soft","master":"c1716c4c6563885c995c00990cedcf3c90734ec9cd0bcfa327b19349762d1bd1","seed":"e192cb10ec4d6813342e8ae74c60ecba75c8f9f23cd60a92c8abc44211fbabe82f4f11e30bf68bd447c8f0147be7ff9ee9b64cb8c44ac8697f2bd1ba886f8427","priv":"f72b0a757b8ceb4bb80b47704eefcb5e0448a9bcfb7385fa3b6492628c36f2a8","pub":"020584eefaf032c19e853bdaad1d1bb8cea4001b8d5bc919d888b1cd55f6e88b04","addr":"98ff8a4e963a8e8cb4a09e10a83cfb704abf92f7"},{"mnemonic":"inmate mistake detail main sugar find maximum crack soup tumble helmet caught","master":"9b6e9657a31f9baf6f303b2df638d84e549fc35e23f4cd7b8b96ba608c474657","seed":"fea14199acf507de04127191e47dc5d20d60ff473d5aa600ab697b7854a7351bddfc24d99057671273b62111990d5bb6f0088af026b38448609d3a4ac8f58b74","priv":"2800c0aa8490524c5add4d3a2def895d8d54e9608a05fd21a7bb5373f594999e","pub":"03d49899c17ac5c0a8c3720c1a9593950d2a8a591c8a8fc24812d198ec1931b5a9","addr":"e198b4a329be8be7f67e4c7d63bdeedf9ad5b45b"},{"mnemonic":"embody ocean catalog shrug valve extra potato subway casino father denial oven","master":"a24ea5416ed8d137670224056db9656e8c1a70f8e602bf6a49cd2f7e6968fc5a","seed":"447121225f8095e806b284e249c1625d925999fed396dcd7c36d9fbff5339659530fe2df0760a9d1d15dad32e1a4c1577c518bbb378272b305434d138e748831","priv":"548afb052cd083e9504a6d602614d085c7a20f37556030550d13619cc39241c8","pub":"0370f25b9cfe827ca110760fd13eea09082573b534411d1719a12fbc9867982e4b","addr":"e6abb5bdb479ce55759bbe1d0331db6046f1aabc"},{"mnemonic":"brisk present attend rib envelope keen mosquito athlete guess ginger budget interest","master":"8e34652bc5848d8fa141e06899c93928c5bcbfac5e1daa60c77af837d7771b96","seed":"4305389939cf757a57a7ecdcdfcc09f7699c315704a3d23243968932386f01dfc8666b7dcfee1d7ae26a747907c85a949843ffc91c9abf3f98007d394b1ba2ca","priv":"65e554264f67ab679321ab7fa516b5988e6049847de929d6e1949032adf1452a","pub":"0358503d0c6dc10689a3705838741f20b83bd5496c4befd2403f69760533f7b28a","addr":"80b6d095ea92c035fdd56adbc4d38f209de13000"},{"mnemonic":"never gravity problem draw arena very panic patient clutch trick calm topple","master":"a6cf02c1407405402557a745a96019f2516fd7ed03677871da922282358b23ab","seed":"ea44a019240e09c4c642351a7aa04625c309102032b9f77ecefb4d33c25f31179fc52c300b4a2e57603c08b5ecb77600bf9f4f9fbdb07cb0dc7e822f709ba7f6","priv":"38ac40ab37d588c0b7ed4a6f4adb378c9e1a6d8a3cb220853dd56abd7327df4b","pub":"039f5f8a5513c74284314c5c5775ed39c77ec9081b978a3b096af6670630046730","addr":"c6a7dfac1a85311dfb3a3c6191a6124ce8ba39dc"},{"mnemonic":"aerobic slush coffee volcano tip speak across evolve nothing deputy limb arrive","master":"d0b24358e5a1e4cb2fcfbb10d9b32330e02be92f3397e70c8a81b04f065958b8","seed":"927a69f86c0f796ef2a6f89698ebcc6c7d2df24672d1c597c10f2b3dac8123808b46cd63e726eb6f1699b0790f14da3a82d9da2cf0fdd32a9b936c1763db0522","priv":"1d736f96fb08caa2ee8c9d4c1506bbdf235cd3ce076a976f8a7be2bd621e5a23","pub":"03f6d508014c45fedbd92677a8dc94a72a7ada2c893d0e2d508c4c9be4fbc669e0","addr":"7ccbeb5e8927c714b3d4c1047e66757bea289bf9"},{"mnemonic":"aspect glue bronze steel idea trend win collect ceiling puppy gas flat","master":"6320f492fc27070bdd7b99436ebfdb25f462b588f50915e5c79578613b53e41a","seed":"e0c9803520833b770aa6febcf2a0aaaeaafa6d39400141908c6577d99ff4ff26062451a4f1b2ed4dd91eafa345f7efa1d565fa101cf0ded88188e9d07ce62e5f","priv":"f87d3a46e925d395a8c4539469e0474cfc0bbed8005b50d539a28c85e3a44a28","pub":"03343c7d2cf83e568ea0c9b92e766c6e021d4a95ccf169c2c9d085693490d66f0d","addr":"6dba7380eb165ea86e2b07e30c5fe1022e046da7"},{"mnemonic":"curve better narrow reopen vocal gossip fall tornado fossil scrap goddess direct","master":"3fed34f65702bb4cd41a309cf81ae4a8c13b569e1de5420103bea9cb264a0ff5","seed":"c3f0c08138f32640b3fa1e6d9fde51163aab66318a7709933339874fe8bad22e75f6c19004af5196fe84348a1f3eaa37add1b645a320acf8a1fda40fd788b428","priv":"c99eb1a2f56c8ccc3ee2d2bdd3d849b6a60e1e82200f72e55d236ef1b0a9fcc6","pub":"028c3c8e1902ee965f55211362b5277748a5da54b43f0807a216581e6d686158df","addr":"507e551fa72ce7e9da2b19f4258c2ae79793aa2c"},{"mnemonic":"insane screen heavy sphere turn drink direct exhibit turn pattern series pitch","master":"b060bffb238a046de32305be06a806093f62fd0d52d1ff5b44b70ad45f502996","seed":"0f75c0f282ec504aefabcc1cdfea3e4166b4f6d4782771a905683e26b05dd5603178cc3fde6fe4febba6542350b15a3c393927ef1e371ec450af6ae6f4ed5a5d","priv":"3f590738a71a45fb5f111181747b44e342212ad15350db1d3ca475b9ef4914f5","pub":"02e50487e89882de6fe3ff87c7b12542a8a6a8a8cd2b4a08be5071aab04b2d461b","addr":"66284b62f4b7f506c6aa0f935d034b00f35fe66d"},{"mnemonic":"answer mobile swim shrimp jewel smile security shy decade sign physical width","master":"64cb57bff4e190f89d2d7564be94cfd1efa0014ef403cedc6946eb52a4a78813","seed":"3f645e90cbdf7eb6aed9afb802fa22f1c0baf57a79c813fe21478a7f2d658dc83c3498c75b0ee4e01a02cb11609473782065c7656083d7986df7bcb320603691","priv":"12c7e6691ffe251287754234d7b98747f12183b5535be6c886f86268b28e9175","pub":"0375b4071b801b389cbc66de9443623ea5b86d310297369305d869e885e187a0c4","addr":"b6fee98515f241c4ac41fd1382a1d7211dff3af0"},{"mnemonic":"match car rice essence try reopen wrist party choice creek inner comic","master":"60b8c48a8c8cb2d68a92559d1ead30a2cac313df4f5a84f94d0b64a3d5569047","seed":"17a91ddd485e6becbb822434a723c5143a11aaedbe9275b36080f92303fb3ef4d934abc5d36bc51b35946a4a683f932373e4a3276feb0393c499a961b78fc18e","priv":"1d9e0692e0c3e8d06606423fd6fe3d336b893c13b38ae3339aa3d7635e2c0046","pub":"039de765de0080a12871f7a278fd27a21ff6052d864f36a01aab4895a3e20d13ef","addr":"6a1216c843cdbe2010e5f024e265b31aa01592bb"},{"mnemonic":"leopard garlic permit menu opinion kick clinic upper start vote truth okay","master":"9db65a69d3ee0bc07c5ee34244faa0f6e8008c51c5372ccad6b9d54497c27f94","seed":"f125a9285412d9aab52baf0045d628d41e870814cc1ee92746d0cd0fe955bd30e3f5519521c6c7d172d07d53f318cacfc5b9d4b0a4e508f9a1056526df594283","priv":"da4acc9d2c281a03f904b42962e021401602b65c815b9659bc4a344f6f35e934","pub":"02744a41865188a5b3a37032369fa4ef214dd2ad836a35dc738b501736806b6606","addr":"fd86381be60f3ed78fc53abf84a8652b3c84b7b8"},{"mnemonic":"vote divert tower history staff finish lyrics empty bless alien walnut hub","master":"10f25de189ec007f9caa97230456a55ae87a807178e8cf23e84f761ec7c69cb1","seed":"ec42f0f2043a01fa768a6c5e889bdc706747abae60609511755f21b7798b7e3c476d38d0b2894f2519f2fad6e279d77a04e1ffa864c9059697da274b32bf3b88","priv":"4073cbb35009f9e7ad4bb18a0c3c7178ece1b9e07c9df1d595f5142c51a92bb4","pub":"0340a0d2e43896e6cfc4d0a7ff49afb1ac28a5ba112af2882f86510865f84bb8ca","addr":"21e3b66a23dbeb25b3b0e2372e2fc7b64364ccee"},{"mnemonic":"debate between rent foster stove powder truth remain cancel pupil object romance","master":"aeb2d34623bef5822150858dfbc2c0c53986c363297e9c3fe1ea64613c6701c2","seed":"c95a64fd29b7b9f15d9077e6a67a8f754bfa55bb952ee35ab94ca001caaec42b45ea2ae7223fd10492dfb02604fbb87de28b4202c49f72be52b7c55db0c8edf3","priv":"aaa218916efc3fd6ad5b948ffa4a3239984b06592c3e7809df3bce89b7c50465","pub":"0221a21829f0dbd3043b9a7645c182e835cd14c95ce9931c1e17284b9172b77130","addr":"853104a703410c5faf86381d5d2adb4f3254abee"},{"mnemonic":"dismiss fire ghost eyebrow salt report pupil include case east blind filter","master":"636ab989611298c004b6ceca6cf887c25d44df49260a8f755cc159d74fa971a3","seed":"5ac06b4e40354a95bcf97270de3db0ac2c9bcd44d1a83c40e9f2557490cf794dc8ec43e71d3dcf3f13e6a7202d84b835c124405a2dc79119288ebfd6352a1d1c","priv":"ce591b790083433d60e3678d5ae488f6033c8327b494789f457a4a137a99bb33","pub":"02607f14149c2272136dfac3ba34476203424fb3eab4282fa6e81c0bce0357e81e","addr":"9b38671825a0fa55e15833ac583fdaf3fcce3800"},{"mnemonic":"awkward slot wrestle sudden core clutch again pepper private reveal shift baby","master":"868dc5c7376cb2ccca274744e97e1b6f8390c1f2fb669862cb624fda1e8d9408","seed":"065aa8d9dbe5769799f29e7a99e663a6e622f0463c6b8093486728d2ff2e8dfe2d9d30e357ac6416515f043b9c96267f3b0de08f3b88c6bbe9486c3c78cdc44e","priv":"e6d6be1b041e0d52d576fa52f4987cc2c8490d86a49184a231703ca0f3d1fc16","pub":"0375e417a16b94bbb1e8cc1789535fac4abb78b466d2a354045da76405ceb8c35f","addr":"280ab94c67d7bddc3ee6a83571a2941b06c83676"},{"mnemonic":"whip tired like merge crush bird venture verify grow fiction provide coffee","master":"1a1a931d51b74af1b4ba19a4ad97b2d5d8c79396cac5d7dd7883d83d79fa81ae","seed":"a03ee9671bd73e717e93830e97dce58b4b5786321989e9f446daf96a6f328d70f5d5dcc4c40d21b7dd4b27aa6809be2a3aece2f3c2469923b8e3d112c899e3c6","priv":"8bc19d1e811c334e4417013c3c85a2040cea8a3b61c18bec0c7520bab9dc082d","pub":"0224c968015439332e83d1737b7429c7bcece458a00a94cc83aff758c5386e3878","addr":"a069c8ae758f12a39e86b2858865d95e953afc67"},{"mnemonic":"prefer benefit sound knock exact pull clutch cabbage local burden small report","master":"9d8ac0f2bbe4caafc11f2cbd9e644e62ec5f54003701453e9c08ebb5b252aa10","seed":"a6d48540efcd54706017c3a5c47773a4dbade3044bf445f8e811b2b2a1a584230d070c296fec26c59deeef37a7487926783fc96fc593c270e90d7da08766ed38","priv":"bb6d7a3a4717541b7e33146b75789999b5d763d14f0962fc43ac30193e711b38","pub":"0288eee81a2e81977eb56b163ea601470d99b9024b5b99db2af88228842fc6d4db","addr":"62c96ec870a47a2cd540758e27fb19fedb11d9da"},{"mnemonic":"case choice castle monkey awkward kid submit layer bargain reward ahead type","master":"c3da04cb84f0f98ea8723f2b6d7e6a3c83b30e5ab8e0ef75bff51ca0b4a00707","seed":"c65366f8af99f805aad4f87c4f73c074d1c99e69fe65bd2bb0ac6a1062bf9595051133c32d5abf4910cda20b9e8a8cd76e22e692e31c02f9327eb703602a9ff6","priv":"71a0279874cd44a61fffb0e65d7fcfa0f4f7c24db912f18f587d6393f8fc1154","pub":"0265ace29b8dffee0f31e6bb3e42f91d90eceb13357e6d324ee2cbc41528ec1c4c","addr":"cd772b14963185ed989f1085142b2b0ae2e5f980"},{"mnemonic":"educate meadow confirm subject tube urge guess black friend later cement spirit","master":"28cd56e6a857ac35c617c4665c143583e0626dffdd7a5e0ea55ed75215bc45e4","seed":"bec29b984cb4df491eb1154fb2717662606fa63742febe91e10d19057c9134b4d4b8677ae23e006b450d6d485a67ae09a9c34fcf8cee5b22be821dab855cfba9","priv":"fc3c5da684c39ac6ae5a91a3b94f50680f6562187b5a138551d20149113d03f0","pub":"032eda5239cb98993519d44e7838c971f9bd8ef140da2fa4a95a70a2488f78f1ad","addr":"5a9adf7df64dd7f7e9e0d29b9fb90069e8230090"},{"mnemonic":"way butter chimney fantasy rebuild delay shoot toy ugly festival resemble promote","master":"599622e23b3db7ee9a6f8f95f5e39b2562170fbc4dc0d84b6869224b9304f134","seed":"a5e0489af660e70db67649c03622aa66b1a6c57d2593204cea859a146b1676893c94f4390740021a51a3a076b27239c7870db78ab7eea48da0a0177a10b8e16b","priv":"e16a619f8355c4cc276583b67fb2b2616d23d09557539fefbe915c6922e80ae4","pub":"021e6f57790a3250f24b6323cda9f648cd0b1907e5c7a81369d022748af8a9b0d1","addr":"9c7b9192469e256207f7758a906d0ab3c50e4fa2"},{"mnemonic":"sniff rely wine book guitar repeat civil elevator olympic wasp dumb often","master":"43a2904bc971e275f33f12109c2067877acb6b00cec32e3913725114b48bb2d1","seed":"cdb3853a0160f7ff9f3b6a9d10192c11ba3f74d45f4bdd4366c9153728105cee7e117de9e8b13be65d3a284fed6866ef4850898c9c2ac4821f55a9c6415f7e16","priv":"970e0aa6e521b0d938c41143fdd75983f5a315ab51fe0e2c79f5c37053e7dd70","pub":"0378b468aa83eb47cceddd2ec8eca4004a9e99ccca959ede92d9b03ce3e38d5099","addr":"9b285c714fbf2d0d9e39395b08d07e3eb87ed87d"},{"mnemonic":"salad print drop winner chicken despair bleak warm misery buyer clip glory","master":"77c5e3581d686b79e863b82f41e563fa5a487e11a782f609b4559ff5c52fa091","seed":"494e915c3897e9bbce29c8af192e7360865be489b38efb5f6484955a525d7120d7637921f7ce7cfe820fcc996c9d9d0edd76f8376a48549057267fc7193cd66e","priv":"a7e988c4a3e661ec230fb359e8f6f7b9593ef5bf33b9086c1460fabacd162600","pub":"02f91a2b6f0545a45ee7d50d6899de984dc0d29ebe6f75cdb3dd169c696daaa9ff","addr":"8bbb9c4b435d0f42ae033e2819a600ab49f3a21d"},{"mnemonic":"inside alone salt borrow fuel stereo toast hotel want arm happy marine","master":"0bbbbf5948912d5e7243baff26886acf316b6ce9f450ee0d60d262b568200400","seed":"afbec9326da69fa938e71403cac67aece539c5fe1156d34ec737531b6ca38b68e60529d589f887ae24899ed8ae53b9f8329f64d84fb62c95a7cfcad45e83f6c1","priv":"8e2532f0440ecb83316645940e29d0b522adc421fb9aa49a8016b6bb1ad34e16","pub":"030de4b35fe61c0fc2fb4fd295a9352e98c7080cc99a6f70d6f64229745c161be1","addr":"519f731ed0412ac24588381879f050bfa9b01591"},{"mnemonic":"cousin drip gap gift ozone omit road parent square lawn crucial color","master":"742d494238d59034ac2026b9a94ad7cf75df5e1b481de734c440a8507e2236a8","seed":"82a0149396a6cadb670d7286506e1a0fbdd771751b39562eee0531d1a2353d29229940395cfb0e00fa1a6d26c9d117039d2a1738ffc93b34161e29de73ee41ca","priv":"aa04e7953be44feea3ddf077d01644f5b4f1eb85fa89521dafe85c341896104d","pub":"02f0d80a4cef0f71606ef476aa04ccd34182bc12b0c45708b0aac49fc2781fdd35","addr":"4a2358c67e4faad28e0d50066a9da25912c1cc57"},{"mnemonic":"list power fresh cricket must expire globe noble park eternal tongue thought","master":"c5210503dee7e7530a84ebb0ca5ca9f15670dcf987e82d67ab2213ae76275b95","seed":"7e482fcbe082d1e9520fa44c8ad117f4d2fad839c8556ea3aa4096a7b940009021611938b4cd2cd82434f5ea37afb4dfdc3548af496f0afad91bfab3117b241b","priv":"c14825a7bf41e5daf44cd9917f33c682da9fce939bab16421bd7dca1e04644a9","pub":"029a20080d20312ead4612ee0e9cb5a2d641ab929865cfb19c3234c838e6f75c44","addr":"750b5d9c00adb243177506688d9bf4943a3ff666"},{"mnemonic":"bless goat worth boil street wing quality visit honey couple upon sheriff","master":"c66453fb857a3deb4ff276dafe0437ba6dcecdcfa67b095053a060f9d5e67c26","seed":"b29cfcf2aaa980c88ae8e0b151601e40ccd6dceda39b4ae324d6d906bdd3342db7ab0f20ae75c1f1b424bac7b679b252532b4d5990d36d91f7612120a5c22b25","priv":"dd96f23418a459bfe23f676db88839e63d1bce7ab58b76d28e494abb1da9616b","pub":"027f81c68bec50476477e5d5524919b7e40509818a16da7724c62de26f23fc2d65","addr":"8856e5d456716486cc794be572454bf41f013404"},{"mnemonic":"slogan outside park during produce key meadow cricket glow choose pass tree","master":"4d6772450ecb47b86c562d5accee0f78c09b182ffe324fe0078fd324474f94f8","seed":"a050602af53f0857804abe575f05a664c292abe43782589fbee0aafbb9654988b6a46ac26d93ba14166d9c6f887dcc1693c2aab5a782f4277c0f153e3572936d","priv":"92918d979c61e8c6a256548502714cdb0094ab6fbc364891bc094bdee708357c","pub":"03dddebad5131d93de5078fad3a380a717f2d2dcb65743f05a84dcf7f29a26f9c4","addr":"0c34fd5317283be4b9ae5a953f539028a5f201ba"},{"mnemonic":"coil burger alpha grow lyrics check page spirit sea mention course fame","master":"9b4a2e05f533427551d7e44ccef49057b2fa0ea57a5890480133a8cad67319fa","seed":"013af1c7f10ada279b632bcaf0211006d13e62165646ad3af69da3b60f044ce62e9bdc7c1c6758da037664f18f1a1189683db16fc2ed39192a7737154984f417","priv":"1a9a114d594bfc3e41c3f507114ef3b872b70563fba390dae992317f67fa0241","pub":"03c5ce908d87792e067ca19d4fdfc15e3abda1993f3ad1f1c8bc5168c58c3c4e93","addr":"cb513df0682dc11374466aea70d7cd9a45d4fd44"},{"mnemonic":"napkin mystery powder birth crowd fun disorder bike lucky core dance punch","master":"8fb55d8de947c13497a83c9631a4fe9b0b491cca2743a6a056214c1daf5cd87d","seed":"f8c5fa5fb7581ae597edbf214a2755ac2bdd58dda03927c21c983b545674de67d69e258a196ef36e3f3e319863a54b521ee1e23807df9f2432b5004b563c2509","priv":"3846cab8eaa4af163f79dc83e5968ce0a59b7cc2f6f725767f70fc1780c00599","pub":"0399eacd20a2a7426a0946fba205891d22fbc041d264372c6bc981c3e7200995ab","addr":"3fc8f92413e731f59ea2768ca40393a92aa8dbca"},{"mnemonic":"sock real audit mind page price rocket home economy glove water rubber","master":"205d5de977b27ef90aa092c70456b516aedb62bd164fac4e4ff638be56d9b9cc","seed":"129afead267c2a9556c3cd3618a29b659e98d651f52259acb1eb4ffbdd6e61d87ecc487123994fe4eec4f65808d9cab6228f8054f8ba68c59a6de8a1997bf420","priv":"94f20ab0cca31de6ed426a818e8cf11299b8112905d0bbdbed79de137337983c","pub":"02ebd561df3cbc137540c7b9bc0c919021d4c4765a9f602078b028e469dbae397a","addr":"0103fbf9c8f122fd4ac6635f9178154d66b619ad"},{"mnemonic":"option faculty depart orchard foam orient seminar detail castle warm pink pen","master":"90dc715ea43f91c4777eda4e9c1dfc9f909c2cc811b55575410d21c0a9fddf4d","seed":"94c306f3e3aa6e991b0f9a8d42af67d058bd2ef0ee233467ba0d23936bb0e982029a887e6b1f9bb9e537ace50e2235a9976dd79b03555cad90da5e73aa0516ea","priv":"ff6cdb1cd48968c64608ac08be92e28f9808fbaccda86c1f5fd6d905d49dcb5e","pub":"035162c7e9506539401c3a0c181643ca621f5abda005f6aa14792fbaf44b862edb","addr":"d724d1f5b4a987109f0c84cda0ed290d88e7c668"},{"mnemonic":"jacket goat equal source proof congress potato solution rival lend finish bulk","master":"cdef2991efb462f091fd3c4e092f8926a4f5e18d6013c5545224d3ecd8e61821","seed":"01e84e54b7faf2374a4b4bb4e56f07d8b13f0dbb0191c23fd41b4520c8123f26b526a463404ce264283c0f3d41c5927681b6fa388d9a91274fd693fa265fab69","priv":"feebee90172106d859d545187adc06732e188580754c96311d9acd825c1ec9f4","pub":"0305697df9f3fb6796d40145316d8f90ded12e8ca18a5956651ee96ab26e69001d","addr":"d0955fef013a29bc7666f1a4696eed57441e2633"},{"mnemonic":"canoe tiny raw account weasel fork still mechanic cricket address squirrel void","master":"9382c4fa09665993b8803f3cc92913c5564be40b63b1c19c81f8f9dd415ba83a","seed":"5c12270e9fa3ca2a008729b1d5fc1a8dfd52dcc6461969ae71d2f3fe04a7c59dae4faec17f84567afd7bab3c5934382ef3d8bc6dd6879fd3af22bbf30fa84486","priv":"9f1d4cffae3c7ce9fce5f987e1439167273c83b6b2dacf1a11ed66c6053c2091","pub":"030a2c97fc8aa57c7fcf7d21c29fbe00ca0866e58f64fa56a85cba811445e0ff78","addr":"48b6bf075dffc6f03e77c67b3f2f573cad8e28e9"},{"mnemonic":"topple recipe surround useless elephant fan gentle wall since street enough harvest","master":"353c700ba61c0b56bd7a3a65d29d53e17bf99abeec68fb79c747ab006592c331","seed":"9fcd29b6b00decb8c8e2a14d5695941854cb391bc25351d7030587a09f64e92bb409c4bb7429329504c19c7619212c731216fd5568dad8e2a1330fbe6efebc7f","priv":"c900c7134a5b92a2a0d3bb0c117c08dbd67f47f7562cf330d619aa3c64b7ab6e","pub":"03e60ac1d0a9ea441a821a780d894ccae6ffacc207ab39ff905122d435acb17a31","addr":"4202687424a7c883cb1dd96353e7dc4697f35f3d"},{"mnemonic":"any myself dizzy magnet hand drift garbage reopen fiber great stuff burger","master":"74aeb0c2e7a7655668238f6a090ce3657def8df96d7af744ddc52d4900451a6e","seed":"0e0a18cbadc5ab76ef4194f7eb069f266ae34c854933b3fa9603b4fa39dedcf219d73e3b283e08a067fc994d46bc59e1c42c18a6a5609111b8fa690edbcf5d01","priv":"f426009813fdcee2b4cd38966e6214f9559426705621ca8b862d2a4cacbbcd4b","pub":"03b75491e3a05b32aff6972e720bd694ef496f6a753ae309cabf4e9b5adc2fa6f9","addr":"5e8c4290a5ab9cb6af1addd261ef37ebd0e6bdf5"},{"mnemonic":"spirit draft dilemma cause main admit thank slide barely diary humble enroll","master":"cd538c907349401ba6605eb1ca7923df44a30a049d5cb9d5a42f0f66a5cc5f29","seed":"baab841c07bf90c8b1bb82c56e355fd6de5a2c93e86f0f804a897ff9c391712d2ec5281582ec15337aadf1f0e835a8c98c42e86a4869e0e1ec47c063fd19f04d","priv":"cacbe0003d96c8263f09f328663ab1b5c74cd6635504b778ebf2d7d30dbe524c","pub":"03e71d9a3ca15f3d481ceeccafe14e6ce1214cf854aa245bdbe28e2b27d2d40353","addr":"f4b073ca68bc00077027a2793e7d6a24dc4b9434"},{"mnemonic":"state subway clip baby novel broken stand soldier among fringe track wrap","master":"0fc4edec9e5891d61e74dd1ee6b52f9601010cbf2bb8949c1d38339ec428bc88","seed":"46ff0c2553e5494666b6de0fd8fe734a8bf523bf6953dbe8622c66c7e9645670624f85a3ef2e9d090e9b153cb5923460cc1975c481a5c2868e51cddd15a9ca35","priv":"4f92a517fe46051132e74178a69f94a2dcd9a1120a54e09188e7d243bc97db67","pub":"034c0b78b452dd0fe61464dd0a44facac7ba28f126fc2a60b82f82efb8cd153349","addr":"2da2b5a6ccff13b5281582aec90f4c9ef28293b2"},{"mnemonic":"nation shuffle siege easy birth motor also family infant siren upon warrior","master":"506af6e687482c47562e38ac6a41e46e2291d777fa0f7abe53ab698065f03f17","seed":"6a4cfce60d546e03f17f6d977ce6d9dec6f4cf8b6a85dfa3070a34ceaca022c5ca4c6f187f1c23d720078c41d540fd04c56bd5061efd027eafa9dd8e650e745a","priv":"b9354ed6da16a0cc9b4404d3226de88048b546f5a01375466aae09c53af3cbf6","pub":"034c3ef56d2471b16f17ecc3e1d8695e0b44057fc8ccf76625a271487781c735ef","addr":"41b9aff0432990ba791b76ebc13af27c634d4a51"},{"mnemonic":"snake manage joy opera creek dwarf wreck merge oval rule elite coin","master":"02a8c9db54ea6d54186726806f81935dcbf6b5fcb9e91d03ad618fbc9f9d3879","seed":"7d6db7e19c66ac1f54395a5a4f7d878e19c24e0cb720ab2a146e2502b4c6832efca2edc2d3f1351cdeefb53a53d66fe64455790fb687234381c017fcbf692265","priv":"76d273285aceb1d4686167749496ae591df991af93a8c29bd627747bb2dd811a","pub":"0208492167c3478e65f8a31f051961d2ac809faf7777dfa7296c54cc3639de71ff","addr":"b18dde1cccf8095ae14353ff4ea995b5beb01dc5"},{"mnemonic":"edge aspect sleep design jelly vapor car blame dad pizza own possible","master":"7d938db55ab464a9ca1e9bf65fb4de0e25addf0ee2e0faff2fcdccaf209de40e","seed":"2d2530b934297fdab1c193d6aa9b93eaa1ea353e776a8b89118b31273f93c2ae78d7b98f02ce1cdfb8465fec0a97b29b563764409813bb4b893a3683dc9d9bba","priv":"c183cb66c406d72e64eee84dcf330e61514028a82d56c56490c4aa09e26dd987","pub":"03e7b33c7123aea9ee99d349eec2603ec7c32c2863034fcb87df8399b73885c97a","addr":"2e8c251e27ee90d6b8f05fdb2c7c51f92b277f1b"},{"mnemonic":"cancel confirm rent key glow confirm indoor chaos flag curtain indoor float","master":"0b49f5cae01e50cc4c05bc466ad91d84ea13896d93d468f951666726de9ccf1a","seed":"aa4561254b44e01ec6b00048e4346754b6626000cfe8e566180a99cdf8739c0c76e16729ee4c73b055e7c59f5ad30abed0ecbc1499fed87ee75cf0cc89f9a087","priv":"7c4e98bcc55251dee796fe3960a8b842322c51da57fe5cbbccb997714392016b","pub":"02ffec93ac53e470bbdc2dfa89c2389a1db404ae6e57e2586b5e638e1397a85f00","addr":"c69d4ef8ebc35e8a418b00c7263295052191763c"},{"mnemonic":"become search judge nation inherit short history resist luxury moon garlic protect","master":"72a0a669e55a3058f1d20be19571673ad281e965667c6bb7afe83e3e89f0f30b","seed":"75518eca5861396c14bce066dadee8eb5f9a74e7099cde11cc9b0f1cb1fab1df87b5fbdfb675761868c81dc7dfc805bd2e425678b0a562447a6684160eaa6264","priv":"276b9a47745eb9266100e62f8ed8f8fa2ee3e42e36ef8e010109acbfb667c1ea","pub":"03a596424477e9bd2500b20cbd0290feb0d30b755562561c52973edf826bae3324","addr":"933df39b013756091a3455104d61244fd16085eb"},{"mnemonic":"profit execute broom clever wing noise crew purity steak assume april leaf","master":"bc7e3bda0564fd300d6f0033fd13d75f7bec7464ef692bc96f83e7ee9427c6ff","seed":"353344a63ebd9a6e78ded4cbf52a5f29a64cb7c1d90b001d764f5f4fa419f569181c07f8bcca22117c970f65d6f9c06b44e934ad21257e0f1bb500f8a26db987","priv":"9120e0b2f502a6b5b5804fb4eece7754ed92a59fe482a7a1b4190213dfb60457","pub":"025f809c0f6a054c4b875c7bce8791f23cc9daa6a85558d6cd48818f29d6b978aa","addr":"f25a6479cee5506bb53b4b06fb326a508ca77abf"},{"mnemonic":"menu library ten glass coral taxi prevent learn pelican garden magic busy","master":"7f4687dad9ba781a99edc31d78a2c68875f40afced8adc8a66d55efd3f68c169","seed":"607827fdd6fb239229b116e73be3993a6596a09cabfd19dfb9b03482d052568c5443f4572393b0e9d460a05832c5fc41e811311d9bb501c43ec75e234c61785d","priv":"5605ca7fee44c088165aa3474327c53dcc13ffc73d8b4787a8b0dcdcd7fdbf3d","pub":"024d754ca81f064cf6dae96fd1344cab8e917e46ec639f677eea33a21bb34462c9","addr":"663ae3370a5b68058dfb1b2efa62f4a2222b3a89"},{"mnemonic":"green useful pair bulk excuse mixed train talk genre inspire much eyebrow","master":"318169a8d80848ddaaff93bd0fc68b1282aa8f5e6f058044de6ff82c62446005","seed":"2095e4cf4ec5ea142d9300cf431e47c6ad401ab1693a6518d5cf7950d1d5d7e0c6feede5a29b3721924074ccb527cb962ddc5745b46b794dddb4ccfdf31ff1fc","priv":"e9c336d9e59b1f4c822899ec39d256174521097060db24f305e3d4c3b12c35c4","pub":"03f44d7d4269f3aa14466483d80ad483af1307387170f563222e843c554f215b00","addr":"359955417cbda69e538cc001d5aca0bc59a077f2"},{"mnemonic":"follow half desert universe canal guide pony two fuel nuclear pull tag","master":"1f3ffb60e2293ecf146f414b28ca6a81dc6768c34450f2907eeca2851ebd92b8","seed":"e692e2810049aeeb25672c3d07a411940a7a7308e9a2fed2a67210d14dbc1de2258edba62437cdef1f913cbc65cc8040bd52f601c2edc51cc7d4744dc1781147","priv":"3534e3fc0a973dc314ff3610ff02c07a1a9e5f2a2003f8ce754c691acf172565","pub":"03e7f0b65a215a8d78831f05f10db86874dd0d900059bcbd64d83d08b05d8a5f7a","addr":"dd74030f9d82c0c40d2798e731b7c5eec61a0213"},{"mnemonic":"enjoy chief later rebel avoid emotion kid reward find patrol leopard destroy","master":"0c8eadc9ddd4cfe9b2c1759ed1372c513bd5226c1aa4afea02c8273d226182c5","seed":"d522815571acf5953d4bf6894c9bb5274e876a5ecb13310dc3db73f2d55544174d744cbc7d63a6ea07c8b7bf8bdcbcfe161ac57dc0ee488ed9fbe0d21a070d95","priv":"92e9da2b0ffdfca29c83f64a685f6f512eb291b5b130c4c5c506bf713016859e","pub":"036161fd5b9ff9bafb22e61860d1d3130e007839939eb3f609352bc73376552d17","addr":"015b10da504e82eaa290f2f5057a2581db032f51"},{"mnemonic":"giggle medal hat isolate congress else guitar below chase federal absent photo","master":"eb8a28df4360243f9dac597fa92de914aae4133af8f3a18c2506f2fcdaf4945b","seed":"95e8d77d1709418b4ac0b8cbafa302e2019644eedfbe52233ba988b55f5451781583ecaa8b1be51ae18e17ee5bbb35d3826302701588555dfc8c851844161acc","priv":"35da7e9dd8200ed89f461c484e63ff3ab68a9b1cb162bbc3331394f4f2ab8793","pub":"02bb24e03a89e6a6a7d318effa8ab645c46e5dcc4f25c3e4d75308144b5d2a29c2","addr":"2c271833daadd196147eea05df28dc41314a27ff"},{"mnemonic":"use protect bag nut fault off absurd involve ramp cereal symptom biology","master":"0f5a77192d1a941ac59a41773ea7d6b4e87295f4f82fb0f43c5f12d605afd56f","seed":"7d74703c2442bef350254d3dce2303a8a56fe4c96e4ff80ed57756dd7b8266e566ea2cbc3abba9c724deb9c45fe4cbd6a8c8bcc4bcfea2665e5193b781aea933","priv":"18c64949d8fb6fd392fb4846c119eb71a6021cc1c22991706fb776e8843a381b","pub":"02b94512126ed2d6412873f61bf16592f02df176cdd4c29fcd70085fe3d03127f9","addr":"15e94aeca2bbd591e337d57152663e25bc094747"},{"mnemonic":"tool twist jaguar excite borrow social sustain normal echo fork alley hybrid","master":"d6c9dbbbe44afa97a5f6365066a11a8fff48793d4c6720ecc419bfbb81329202","seed":"164785fe64846a802a9c134d094447035eaaa6cef2eec9d5fea9aa74d333ab31433c7cfe4b712b6a3b04048d239101a8dae5cb4ed37699658725bc2186ffbe41","priv":"cc5c6aba1301195af2626001e3d19660043377c75e7990063aa45ebbd30ab266","pub":"02ed0554dd8861043aab2105d7dbc83809193c59952e829421f7b9b6e9e56d6f0e","addr":"7db5745b47c147e40ea9fa2cf54488974d0bbc4b"},{"mnemonic":"approve bright target voice relax control knife again special future anchor crystal","master":"332ed66acc5c24c6a19c450775329c946197872435d77b0ea594d4632adb04eb","seed":"da2c0f3433cdb37ff151465470bad3b227114c46ddb025542133b4c10d942bce6cd34726c85e638fa82c4295d8fe93959069d35253ee528fb1724be1d95447f1","priv":"41a2cdb57b5cf352256bf9c2b155016160c7eeeaaa5a3ab2f06cd1df3e4bd695","pub":"02e76d02ff3fc76c21a995add6962e08bddec4abe23994668770d6cfd02cb82f42","addr":"39dcdc76bbd5c2ad8821cc5df8e816c7293a82b3"},{"mnemonic":"like wet pig pause steak name tornado else limb february secret subject","master":"e7dea9fa8e88520065302d4227d84a3d4226aac4b7c04bc78dc7e68efed73002","seed":"3926c7749d953ea66414c369fbe3f26a7a3f442ca98a277dfb362eb74432cbee32e44a6174f1e3fd16aead63e798c894d88ef260747de219c1e8631d800c13c1","priv":"804cc7215bdd8073b9c7f8e1ea2648724ec3e2593f1c2213875b6e4022513ae7","pub":"02770a43f589045b52ee29065b2cbae37ff65a0ace98c88531b4cf88c94c3f977d","addr":"cf82c749e61e9961ab72a76cbd3f71e0c5a46221"},{"mnemonic":"memory core ice box board flee ivory apology acid warm sugar resist","master":"4ae1d18a2c3cdc0c4b383d20846866f1a2ecb799e7d2c5c125e81c30856a2bfd","seed":"5922aa04496cda9a17e2f474805f095fa2bb70cce0857dcf92acc7737af2978145cdad0aefcf201fcb5aa2666a136b2eeffddb5476d9d49c0cf0d76d14bb332b","priv":"fde667c98a06017967b9169dc380a7393797486d07bba6575629f0661465a67a","pub":"03f8e990fabeba27ea70082b69628f95e5b86cedc033578426995bc1358949466c","addr":"efcaf3eebd6ec30c44fef92eb59327758eee3334"},{"mnemonic":"vintage rocket today version chair avoid mean play decade sport frequent magnet","master":"d167f9af9105ff115790c4d31ca48e4ce5cb3b571b4596b8ee78be5a6290e3c8","seed":"af58c0eb0e62201b926ab4c04d67b942f6ff40147ccdccc02a3df295fe69ca661b2a23fd2cc0f9148c4e92165ca9725014ff0abe5cb7acaeb513cdda359dced1","priv":"33b248b4a292ff6f26455859924eeb646290cd54a2cf587c5527e2f432fcd6d4","pub":"039802bdb2bedaabe4201344c1e9276d1981f403151e2cf179e4cd13861a54d568","addr":"c9ed9bc2778a33e5712b90843f1b0f0252c5c3d6"},{"mnemonic":"crash lazy cruel match youth note deal rack gym robot work pioneer","master":"13a82f0a499ea45154151ad95d52c3f15d84436c21d734b5ea105c902f85559c","seed":"c10e386ea97bef67bd97e59c5da37442ffc968893fb80ade82097b87a76dec5ae128962a4d69737a31eba4f1606e030d4c85df6733dcbb03e209a4b7931660c2","priv":"eac145103c713225ce05ffb862cb921797f9f88d48628321162798117e37494d","pub":"0260d3fc9e0ef5e8c38e3de4da944d59cc575aa530dce9fe8d95fb8eb68d6a4bd6","addr":"07aa44afcad33d8abe6e83da72d6d556a3720924"},{"mnemonic":"distance desert squeeze eyebrow episode enough sorry gym still label mansion thunder","master":"0f686b29302ac0d5532794598b98cfba275e4fa3dd0bef15c0b0866bfa0c9c0c","seed":"9fb57b9bb255323d11b7479bc34dc706e42e6ae8bb3f3af212b0807ebc9fe56a90a36c92bd17eda435fd0ce87a0465cd10a371b44dfb2e1531c14c29cf8ba466","priv":"7a140972fd7e2499dab8e22a52b0cf79c33ef58d1c5df578e30515e627f044a7","pub":"02332ac4729e52ba3ff4344ca262726bb58595670057aa967451302bd19579e8e7","addr":"f7c0cab3704f9ba669e318d17e33b1b5a7b3ac3f"},{"mnemonic":"zebra useless blue insect radar century lumber clock daughter slight quote stadium","master":"1168c3de22b717bd3e840b4ac6334ea707764d25bbf7ac14cd5d63ab127fe2a5","seed":"df9f562a972569f8dde2ba35e53c97c536ca3bffbbdc990df8cdbca812747887904a4f983d661035de0b3a85677d0092edad32ef528c926bf31541ba63b8e019","priv":"282da5f2191001a4bdcdccbd0000317ce62b09c0a48626b4fc2b45da6d7873be","pub":"02790696da42d2b21cb031e9b77bf855e2f5a214f80cd05618181433eec02fefb7","addr":"68f483b9d998b9250d320c43278e423d0394e8cc"},{"mnemonic":"laptop pepper arrest tribe glad keep behind gravity ketchup scrub bottom parade","master":"06a978fb60c517a506d2d8fa17956f144d1a5d57c0c9567320d1b21b8e7871eb","seed":"38c05886932cf2bca3cb7732e92b4086ca0575db2deaa241a0c9295eb79d50765a4bd92a03b76255144f71bf6f197c4b5eb6e3de8dd6e6ddf6d15ad18c90de35","priv":"62c37a4349e0d4edeb293e50adfac737ce73e3e0370439c561d117bd4ef23f19","pub":"027d978c9355669fab1ac4db17cf12a103f7501ca2011e022110d5b4398810039a","addr":"6e0cc4997d42b970855685f8c9a196b97b2d5ace"},{"mnemonic":"alpha slogan usage lemon cancel cruise rice crazy laptop donate city fade","master":"e3bed02bc801909cdfb1c65b6648f4df19b8927199e3d0f069f6713b13f10123","seed":"9b73467192fc857c552d60dc0223e3c4b604cb1cd50adcb61c9aa723d245e3ad44cba7f99f0f24fddd0c78b1bea41a86e682c9c482b115d575b9e3aa27f5650b","priv":"7b8d2c22c398e4a046da94656232cc75cfd6fc0e0f8191b673414383901b724c","pub":"0279989cb1f22fc08f871d023632a379d038bd9fa902a6e46f8bf0a780637b4efa","addr":"a4d3a5579aecfd9790dafc6b4e89972933c46d1e"},{"mnemonic":"chief runway cloth craft depth firm task ready credit multiply program smart","master":"d5d076659b0e0bb061736956cef361aa1a6a0ad6a337a6ccbf4b76a40184f405","seed":"8e60f22168de4f2a6c9db805a6485379d2facd7c99dc36981d0e209746766233d5d5012b03f8556195737bd71b88fc54eaea0f68e4fae4afc19c133f2ca5fba8","priv":"adee70b6b1dfc264606e0b1c848f7b5deb46de4af91c5eea9eac962dd085bb3c","pub":"0226458b01eb1e4f0d7901841662b2046f17e0945230a3b1b2d8a65aaf5ebdbe8c","addr":"c9d9042f15ecfb29595ed4769b1c858d1f627468"},{"mnemonic":"invest glory debris naive pill detail sister cattle physical favorite squeeze rice","master":"2ffaac06321f9aa3783155de5197448783583c027d8aa9d9b787d2a07b7a4c2a","seed":"3016cd4934eca835d3246cd7c05ff35a0ca5e3e0c4b74bc70aa31582a6da334c0f7e91458bc049ba3469a8aa7f216d27d44ec8ca4cc5f376ea366a38106c7fab","priv":"cfa4b9f12156ae24e632f318be54072149006db7a4a611403afa97c978351900","pub":"029e3e54ae265087ab8066bbb7e935af291b3ef5120b00f44019d9dfccec8a4e9b","addr":"3de09d0c1ee046365da74449b6c98ce3205e20e7"},{"mnemonic":"private alcohol loyal depend force sand twist couch beach report miracle abuse","master":"8354e18ddc5b38a6e26f9cfefbfd4b27ce3f65c91174c88143d947104ba91faa","seed":"507df1232f5cddcbee60de019cdba03e9337896ae2fa0b26855d48c34a9a2cdd1e93f2b66e965cf7666bf7c7ad11f00b1ff764b675a5c3df8a1a17b253cb9e54","priv":"d486cc9a23d56e1dd8d865ba042aa5cb9f8ba06107988e1a0d999b14da3b667b","pub":"03b75ef54ae8faa3f3565fd6301ba7a70114ddd184eefc74e716fa2e3c2df6c2af","addr":"2c82b93644c227bc66fc06c922ec1566c3e11c9f"},{"mnemonic":"memory achieve vault hip prevent category cactus aware venue dutch raccoon fresh","master":"16bffabbf3a08959dc9c1780781133e6aa096cef9d9542606c52e8ca2ea0230b","seed":"a4824f3efa0c730e3669acb08b1cadc25f3f63943983bc4f4f1505cba5c85959ec16c2cab98008d10e22f3ed6239e3182bd9b603ae1536755d222fc60f91419e","priv":"7c2b66b79e2e99ef0f794147aa93d3da8e62ebab7ebaad7813b586ea5db28f9e","pub":"03298a67eb59a27d636c2aff41d73ec658c87b136ea53a534ace18fabb76486dd7","addr":"89d5007339cb57fdb72ec629027583b8f3aaa5da"},{"mnemonic":"alien floor comfort six demand helmet light actor distance success buddy burden","master":"36ed5350c3672be815eb365f61ef0d0d42870b178aa34fa5c5b7397cbb7ddcf9","seed":"ff46b78794944b4372affad3f096339f8d9c03631335d9eaf4e4fe68a8fd9d58a6d6f37ba31cc06bf57c5b66aaad6ba64ed28ae4188195227fa07bfa587f2f1e","priv":"3bb1328f115390ade3c08de4f9672ae96bc3d5b783bd9d26d7e4ec12d5818b8f","pub":"02b37bccbe6c7173937b3af482d4a92280b670d715e2619fb1fc906973bcdd4d7e","addr":"935788847e1517096b9f31ccc2ac48c2e5a738ec"},{"mnemonic":"soul upgrade rebel wash hour gain lady side own double immense merry","master":"039c6373307aad9366dbaf9bc17e70ec1b5fedbe382b9bddc55ff606baadc0ae","seed":"37f9cc349c21182a3b34c66ae099de84bdcf30ed20160c7251f43f831279834dccb95745207defbae856c0a38dda3d7bb251b97cd2150c155ec64c680c82ba73","priv":"377f589beeb549285eee37d34e5ca85f4e00af8483027afb655e47ae05d1089d","pub":"0266f715310d9fee40c5c95da1b6a9a9aa51648df99326e29399b10e9cbcc51f7e","addr":"89a2ac362b8804981ecb6043bbea65587c997f97"},{"mnemonic":"stove pyramid vintage defy belt high have leave comic brass online caught","master":"eb9be6fc059732dd9eff612f2e4ed7121093f07889b87e8c66e103b83724e1f1","seed":"2537a9ac9dfe5c31c0f40c69c9fbf6a8ea186d2cd6c6d2134aea2f3ec2f28f5339fe623ff593da08857ee84193c54e204049009f8c86ded026a4cdca633b2b9a","priv":"a8f4ea6ba49c421a7d310b83bec05902cf2f2629a3845e390261c3917af3a17f","pub":"038a6d8d8947723f80f65dee0ef8579dea5678b67bd258ca591d0ce5d2ec060bb6","addr":"38d61629cc3e3ce7a614825cefb125ddec897b59"},{"mnemonic":"uncle seat rate acid ketchup frame marble limit demand exile wealth dinner","master":"fb1b8ac2f5bb56231fc93615bd8e25720818819d3df4ffcaf63dba0e7e7a0815","seed":"8e0bad11dc7784f19715ab90e8846e84155680027997fa0314fe32efdb3c026ae2918740d362744dff754e75b1d54050f5f02237cc4e15aad165ba10cc7b046f","priv":"cd20e39179c66285edeb6df646de54f3510f166bc1821349d779fcc103f13839","pub":"031a9529a2b5da261bb540f43b860b540490262b10aa09d419dc3b96d2e9aacc75","addr":"d1b6e238bc4a7e63e0a15f034deaf1a5b5161928"},{"mnemonic":"human benefit idea stone hospital misery warfare door goose unhappy crowd stadium","master":"b8b5781ae12ea6db767cc01d644cc52179363b72a7b67ee8d7d20fe8ffe4f41f","seed":"fc3f6e420f688e8553a2cf8d3a6a7198c5523aa6e3b00b3e1e4bc352288f0390951bcf698bafc12334522e04979fbcfb36f12fa789a85dada9909304de559193","priv":"ca41478acdd4f0413a843cec85b2abff69aa53b4f900da10918810b89127faa9","pub":"026096644513086624a2ba26daf7da0e4f5c7455bf852336416737fb72dc1137fc","addr":"e57448e2edf9d63574db45ae06510a521bd80522"},{"mnemonic":"violin cave ask subway session gaze settle pledge decorate alley swing evidence","master":"4c099f1692bd7137bf8b50e51d2f6fef0236f88bacfc4c87f83fcdd43a3a1aa8","seed":"2c3cb4cd88a4de52badeb41b1e3e1d61daf61369d5badc36601c4baad611eec459a0a1edb4046cc21ff50f396688ba6bd37fedf24b17ae447b6f7ce4b0a7e81e","priv":"5f1d6278c5d244334eb10d71e4e642017c7d3d63076507b7efc9c63c8c7e5df6","pub":"02c26860be7973c41ef183ad6ffb901d07bac225b5fae444df8abdc605c7a1efa0","addr":"fa055b86c6a1da4666ea4345e9d98ea32198805b"},{"mnemonic":"dance hip come square bread reduce ask riot shift twenty scrub derive","master":"964f2b5fb6c3f11f33ee1bc9db915d820834cb1ddf9cd35c17effe93ab3e3e14","seed":"bd4b3ee7b0042661b560cf39f8a9f8fdb70bb75c7482b09b296cf660e2b6360b52263cc38a1c546d0f935f0a156a36089975a7fd5a65ddbc960e4b6418e1d337","priv":"6f9b31f5247941f3a0e3954b05f77d68c469aaf25f0755293b1fdb17bcba6478","pub":"03a3cffd72d5e6360090e4a0bfc8e1c691add6690614ee5fcc7867780d686259de","addr":"95ed911acfc3d1332ecd9c8b93a4372a27911cb2"},{"mnemonic":"excess route notice shadow post business cram kind ripple odor enhance future","master":"ab1d6e993bb9b533e854f15591af9e8a74bd29d000d5c8e77b98e3e34e96fcd9","seed":"4ab45c5fa427c0c81853c3b5c2754ab1f54873b0bba3710204fe40ac69c13d21ae011fe9c835566db313947749dba53496f84709b71f4dba08a7db209922ee4a","priv":"98e0136920ca7d3844e7fe1cff54db7229be2412de8de831b94235e8ddc2696f","pub":"03714b295b752de7f1cefd195578fa7257d5dd8b47a39e584fc4d2637a8f730d1c","addr":"9019db50e3ad4d56ece94e7d5067b27a33400a4e"},{"mnemonic":"flag maid oil survey first force grant equal brick dog where strike","master":"85c3230463b78c924cb57ca637b5af3f5910d962861ead4b16af5de1b4be274b","seed":"6203eede1ed8164b3ab32049def751b55d82ba6807d97b3eb094b4e6327ce732a54de31a9fc6178266a4fa7e6452b004d89875694ec13ad05475d7ad86ec3241","priv":"1aff198e964909f87d5b15c1693e5d191b9444109a7ea4bb58952752623e77f2","pub":"03921265a585b1ec932828f58cbaea6ae709c7f2af0691ba3f2f0636286119bcca","addr":"7f38e5412e9011a5ca91fdae448bb8b15a6bc4bc"},{"mnemonic":"jaguar panic thought mimic voyage able inch pole vacuum twist velvet pulse","master":"f7ded49975e280cc791687730225a70a89c79f5245ca72a7e538295aac1ac710","seed":"52f058e84e0809ac44c37485ce9da088c1617f05e92553a073378a0a0b3c9cc95aabb6d1dd2c99d084b03afb98024f9381d958f6ee5f516baef2db97c493009c","priv":"615bd1f706f7a88d9816200f4c3085ee2c748f9a42b25b444393f8cf2b46191c","pub":"02635816dcc956bbd8d9d2ebe94fb117ca20907a238c99245a9635287404d30e78","addr":"78105acfd135889bff6f0f70c92c38e0eaad72dd"},{"mnemonic":"pond stairs still avocado rapid peasant direct debris spice cupboard pledge budget","master":"6b5a25d678b4fb67cfa80ca3ab21cd6bd554e5434c4fd362ddb01cb46bdbaff1","seed":"69d5e57322a46cecbfe1f895c1b22e9bf17d418a06b73d49e3fc83012ca2649818bce2310f1b195c5b4873d31d6e797c5edecb8f30377f5e638ba1b4ce2f3823","priv":"9aea611859425145441b6455a0ee206327c2de06e2d26974197873f2ae9366fb","pub":"0236498052412d5c5dc3ef0d195a2a537359fc44246fd9c8fb39478caf29e668cf","addr":"faeac1dc66f281714303d637666c09606504a227"},{"mnemonic":"december cram web moral spell comic tag lawn since helmet moment act","master":"ee67281243cf2f77274bdc4b91a2ff1e660197bbca2fb42d5aee60e6f55ab4ba","seed":"8052120f630a33ce44aba16f1807236b1330ffa6170f985c630532fdd2713aef0e1d681699c4f67a9b9a72fb0432335c243828bea29489c92d1b01d016257ef0","priv":"a98bf3a99fff927ec2b0f208bd8a3a586ccc2571fc6333c57f2f1b7c22d2c8f8","pub":"02743cd05cb536e2384da4e0f110fa4f807abdba3e5e25e426e32fc4b5c65f761e","addr":"a1f0b4bba0be62c6b2497826612303892ed77b05"},{"mnemonic":"basket tool pink steak antenna process accuse brown walk pretty only check","master":"ce30c7daae3e0a5293ece548d66f07852003afcc80874474f5a94eac4a00c928","seed":"9572350a5a22b4c0f95fb2ce61c1f5e5846a3c2fd6e4cdfb2aba0d05e04e5b67f0fb394521b73836bcd4555cdda44acf0ab7ba43b475795868a6056295967822","priv":"edcff07e74dc83738075605d76a0c6923dc475ab122da2789b5a195a421c354d","pub":"02c03e024e6f53a1676dccd7850cbb2bc1f6a9a85b1da7cf0ecbf1c653a60dae1e","addr":"ac3c8907bc31fe66155a47a37306ff7b75905133"},{"mnemonic":"since equal mobile pond island before crew boat clean behave climb good","master":"1d1eca07fe5058a9dd7b26d1afbf2f4f71acf1420dc4ce9d2e3959734c442f36","seed":"4167279cfd447453ee7f46328bc40b4961f814229cd72762af278cf56a8efb18211420cdba43ccb06dfdb207716390df9205fa880cc647bb48455f437ec8e4da","priv":"60622d64880831974cf62d8f65be9e4d89e6579e6e0f1e5351a10b7574f3615a","pub":"03ba031ce6dd8976cfb72a2121165ea4bc0a8cdb14082504a05a917de09bccda29","addr":"50203affa88d87f3b104e237058807366f33c1f2"},{"mnemonic":"inspire immune poet penalty remind mule crawl drill rare fork track creek","master":"7c581d1907fb46fc46e6e9b81d83fbae02a75a2ee50a8d723e24700b530ce917","seed":"3822ac35fca2e3b5904e3284deb5c178b7c64ada6d7dd31347ea302e76ecb46d4bf926158016b76106ca61ae068fdc594808a56aae5e39da7893592310c33d2f","priv":"6f87d364a299b42c40a641d121a255228b62884d6f2d09068a384f7c6b515831","pub":"03f217a49a2068b2807a4f0500a08dbc7bcba6ffd60b0fe3e4f381a089b74506f5","addr":"c4a20e80863522069f8059e91bb1a162a7af7356"},{"mnemonic":"inquiry exile okay attend enroll author forget essence script conduct apology rather","master":"609da212416c631e8701b1fcfda5c412e0758270daa7bc796ac1492045a93a5c","seed":"4a75975cb2852f8dea2ef90535307e0a0063985a1c2347db1edc25bb96dffbd880ae88e8e5a21e91b6c26cdc98673effdf0ca84f416a45950cbb0ec74cb7fbed","priv":"c2e4db33ed61ed9f7a2b1452515b971a1bb20dce3b07efeb9437fe6ed481c9b8","pub":"03fb6407710ca5408d137faa85f2837879c4b0f4df59182a3d5f002e49c34c3bc3","addr":"c5217c9cd9af8ceff8235b2d127ef1cea8e94e35"},{"mnemonic":"entire diary route emerge moment only lounge situate expose hurry hip mosquito","master":"a919ae0bb832affae8e5269efc47936b6bf3e487740f8bbd2c286866a2224762","seed":"e97e0456756e343a7d56b1edf7468419f8b431c6c850299b382d3d957fff7c48f86114eb5640aee13d245c2a34d390850ec43c427bfec555d40a489397376340","priv":"eff22ef90183b533c5267d9c19f29f7a6fc2c44b45dcfd4b440181b977087585","pub":"030cb4259aefba8429f5e3ab0009e080674e887748e51ba2e0a055d2df3bc17589","addr":"d5db282d076f9d474651970abe5d2e3fece873ed"},{"mnemonic":"ginger glad purity aware siege tornado seek orbit sniff spawn process surround","master":"5498d52a17868a0fb5f1d2416277fa1a4220ac3a498f18f15e750d1140c57f86","seed":"3674479b527c4f27b578f0609f800de86a46591eccef6d40d3ac4436ac8c92ff12659e1e404af552f1058e9f17e90efc160903fd985f5b8069c66c9f6708abc0","priv":"5fcf38e09f4a3665256644715fd606ab60d9cd62f4c22962ec94b6fc5fccdfc2","pub":"03da1b1b03fde4241b05adc19515eda3ea96febdd5ea0e8f82dcc7cd98f1b74029","addr":"1186fc924724531d8ccc9f9ffd49701e62056c52"},{"mnemonic":"laundry reform post update crime page snack another boil pet cement primary","master":"3b1c3ee0d63328bab055d691bd29179ce5abb933759fcf83912adb41ff1bd9c9","seed":"60771d2e964301990d7ce6de87becd62e65852a4da9b819ce3fe28d72ab0e4619445d934172c1fc9361d2176f4ccc8d5b9175f4e933fd5e9681d8e8b177fadf6","priv":"755dcf792c67ba8a9d8b0694d21fbd33c51fb7aea67f05d2c8b0f38093ffa7ef","pub":"037118c561ac7773ab212b899b57f5527b77577a39a4f413232c8e7c6a33f9091a","addr":"bc2e19256932b58fdbbe5ad809e30a3ab2b2685a"},{"mnemonic":"pool bean dilemma foster reveal renew exist bar sick spot bulb trim","master":"4d1399a0181de627ea555f388952dd5d2c7a7b83e1a618fe8b07b03c1bed18e3","seed":"d788888f57bc052bf0d35abf7be1175152aa607b901d1040f4a28c8cef343f0fed2031e3bc9e1eff77eeef4e024234466a55f70150388824d6fa10051133a464","priv":"00b7f71d77cf0d4e13e51403c92aa66ba543e9cfaecd810049d17794a4c0ded9","pub":"02319a6d654cb42a231f7d021e2cb7c9ea7624c37d6ee32b218d5ef79a31eaeb46","addr":"f6d78ff49d6f12b82e24bdd77bebb536566a39eb"},{"mnemonic":"poem leaf scrub bag bomb palace discover pear rhythm treat negative system","master":"4bbecc45fde87cb80a4cad7a4b08068265eb8c12d4ed36d1c9a9a7e5e73c39ac","seed":"efb6bca601760ffb2b183bd4cd2e84a864eda3bb4b8b1369095d3df69fa7ead0b8bfdf5a097f37bb4b1ccc452cb8935baa165f7ab039342af64e9e50bfd51b36","priv":"c4988f397df2821ee196f98e62e4a1542e53ca1e46f966a4d13c4e3e389d8937","pub":"038c8e4571f8f411827ba778340beb7bbc29fb47af998a852da29b4f1583d5c600","addr":"67b94e1d532cd8e42e5a74cbf20f7d079f42055f"},{"mnemonic":"punch twin village ostrich frame goose dance history valid mountain volume high","master":"f9ba8580f4d53e34d9bfd3b6a2e17c5d8987c879945df9bd20407d3f8144b108","seed":"07d40cd18ec6abbc351aa23172dfa6582ed83d5bb24d5cd830d7cefd23d8a2ea6272efc6686606e61507d5a793b7fa06f83bf73504a072e32a002750f5f240d0","priv":"10222b81cc386d25eaf5037fb8fbfa9c401c1d192fb715397f6636dd94e9db3d","pub":"038b04836ce19b454a0af260bc1271ec73f1a0998d8659e9cffe38fa5e4d696a77","addr":"55bd4a574aaa1be2c02aa2eb40254f8cdda7a682"},{"mnemonic":"ready embrace photo find orange curious essay pulse frozen earn wild travel","master":"361e9e44283fe7d3bab83395ecb8373dff5d0a4d60274695637cb02955523741","seed":"ab50c5ab74b1ebae85811108c372651ca8d275e7c2b5d0fec9f261966395482f311a76dd297f2d2997c6c59247807506ed20f524a32dff90637956cb7868aaed","priv":"1ffdff9fd05b67d22f10076595e0025800a8d60f022f2bd99ceeba93681372f4","pub":"03b168906d5b255a896509c8ecaac4a8141d22ebe005e6dfb2892f6f12970dba2f","addr":"a7d30e12ff906b2ca0c6df3fc68274e7e30725e1"},{"mnemonic":"pass paper cable blanket meadow talk govern admit busy base hold broccoli","master":"db0e45010140df4a4514284d7ba78ac7a5771ee15820856afb1d15a4e3b0af7a","seed":"521ec955279d92fae9dd8dd43162ee216798f4a0276a2c98b29dec8dec9bb26f17e6a49ce999ec55e061379166f25116c01b8cb48ded23c3b3087dbafbfc5371","priv":"b5bf00005304278d5e4aa792de142a6cb46bd6283ab02222de50cc2f01009e09","pub":"03c188a8581f09d9eb14252f8d1f5cebf1de8189526992889115c6edb1cd180090","addr":"0f8fe4fac4fd85d649d7e19d1773897aa6e75f43"},{"mnemonic":"weekend infant spin powder hurdle pupil disorder always excess unhappy price decide","master":"b1bec76f3cb15f82e5c9c65aa23d0871ec06a590a3823285a412ec9a243b1c1e","seed":"5a8d16dbd0586561cc81273ee320c6c3d51bd90bdf08119ec81596fcab24335193b33fdd621800daefb49e038ee079184e569b941ef5d839987dc1e24f578039","priv":"90ffc2ec625f528045a432ddae8d20017c9b1a883ed22ed403783e10801077e4","pub":"027d4213cf485f4eaf3ea06c61057f92ae8fde8362c3b2f4b167639b74153db673","addr":"c9b1073f122b5ebd155d4904cbc32da4281bed6d"},{"mnemonic":"agent seven dry cheese rhythm raise junior sorry spoil tag opera bench","master":"8cd8ddb8ad3f12fa347780c4614e38198a51c00bc61ecb572616382d6f8388ed","seed":"ad6641ad541b411261101e5f76036fcddd8af62de1966a3b9a1122edd1e6057e38fb5e129c86427a68590c87cf9410fc14ec08dff184742a54461c205018f43a","priv":"f15efc08c8a578f7035a672fb51c2f6929e169e5ff37802ae8b50f1664c025a4","pub":"039926cc43000431dab0f0f4818fa024ddcec0ffe9c483f8ec294cc863f5133574","addr":"89846353e3a3becad919620dae0a2d22d0533559"},{"mnemonic":"floor sting insane slice pistol blush follow muffin acid coral aim make","master":"f65fa0d49225f5f373eed6d7d6f9f8f73f80840c6027c3871645679e51f2dc81","seed":"8782d6395c27d8b9a3b0fe29e44093e5150c9b82bfcb6344e6134e954c1240cb33fe8c9489b3ad3117f5c112f02f0eecb0e30efa36db18b27003df5e542face0","priv":"de11f15f7cfb0038dc07ea2007019c17747e5138cd83b37ad30621c9f41b1799","pub":"02b662800bbc56c144f6b39773bfb4d496c9f1442900b59641aa94c6b50a783fa0","addr":"70b1ee56807b9191f77b1d18ddfd181677e91654"},{"mnemonic":"canal today stadium spell accuse cream chuckle method unfair regret sibling old","master":"90c0af3882fac84793812f44eacb1d4cf13b56863c70ccfd6866bbde1195036e","seed":"c1b4ea5bc074259d2f25ad7338b423c5ccd2083b60f0ecce88f7c5d4cb39806f2da873c05cd52729ee07512cba3af26f21354a3769350d5bdd10868ff46d8e28","priv":"9ff9156b1f137d20b486ea125515fd7a2f057145fa8313203606ead961ebed84","pub":"0225998b8535e9f2e269e86caeca1ed90a86414d8c449011ea2fd9a488b7097528","addr":"40f33af234da7de748b02a01687a5e60429ee07d"},{"mnemonic":"object sure already seat attitude great winner session cool addict direct popular","master":"86a35c7ab59d48a897f6b4a78221c8acd0850010a063ceb912488352fa19048f","seed":"fae4348ff7c42cb1ff8542bd19721823917037d1cb017ffaf64547be8ad4b296212d6e952b2af66db8541c7e881136aa76e17e4fed926064bd5edad8f25e0dcf","priv":"2df0f9c67615ca9370f8ab957db6ad6cbcff1b5353f745dd24125ad36d7c77c3","pub":"0367582dda754c5345514b2618d0844e83f8fb49ca39a70d00537c70c86b6519b9","addr":"128a4f8786a46bb7815e59abbcd85bffb526e953"},{"mnemonic":"sudden more spawn have pig observe embody title collect junior sing bronze","master":"c71aeb48c73d6ecef04597f248dfef9ebaab37e9df625a483db1e883a972a36f","seed":"eb1dcdc3ecd77652223ccccacb85a255f350028a843bed72ff96d4e3de5566f667af1d5fd48aed32d2e580f625bd258cdcf6760d1089ee3f9653375bb1139f9c","priv":"455da9b7df9d00ce53973439b23a26a75463c9ce0bdd73eb16a39e019d7786ae","pub":"0327c673e375a95e13ab6a940c18a35874331db2c0abb283736890b0ed1a09b79e","addr":"d173a47de381e714e3873d1e0ac05ef526b0eeec"},{"mnemonic":"world gown final mind dinosaur stamp unaware apology foot flavor hockey bamboo","master":"040827137019c4a9d29c1d65849cbac940ca0dcdac2ba8def0421c990c90e2e2","seed":"48c5532c17475f0a4d63d76daefe7cf21681b32cbbf4ad8cbb62b6fa872411fd2b8821f8f2ea97cd9004fe4585e5ecfa27ee6c46caab89145c3b0b4b7ef5c073","priv":"d66195156c08032f912a71128635b25750335aab186aec63ec9a83e9b24c55a6","pub":"022d8790106436a60a3b74d10fb07e06cb48b2b13ebfb81a608039d80e9d7c1e64","addr":"fa08eb0d89958302d67d4de8b99fe0c53ddebae7"},{"mnemonic":"bag bridge trip improve blanket machine asset boat mask flash vicious pig","master":"21df138f80902d1ee79948ca3836ecc29a0f9093b06a240b29ac7c3aab89750a","seed":"99cead310304d8ef58b23fd2b9ce7fb71386111ffda2f609898bd59289862b6f464ba261855b1bdbfad8f7ea25e43adce10f7386cb6cbb744ee05772b883d176","priv":"c82490739f0d969706299c3ecd89e4f47d0247471ad2d3f7ebba531b8d6804d4","pub":"03dfb5455095553fe24c1474c5a5dc0fb69aba612b79568486345f73fe27d36205","addr":"020c6ac4996d1c91b2b2894c426dc8e32b083fb2"},{"mnemonic":"auction okay cousin sick accuse steel limb staff tube gold hero add","master":"5bc8d22635bf6ce1494c820527e26a94c57f6987d6cdf6d40825138c3283e6c2","seed":"c7df0872664b4b4b0a7deeb3c26545380bc61fa3734a20a82c96e73707ae975b76b12f31da65e863040b2215c34a4e9f525ef38e555757a9e8a42a20af2f78de","priv":"0bc4a9bd3b88ad78c34a309183da9a0efe4d8e27d098282e3bb248cb960e018e","pub":"0200d5e1fe0707ff11dca2c30a0ac83bfa40ebbb7e51197993c6910312fe91d75c","addr":"72ada6e822ffed23ac5ff5147a22537b984bfca3"},{"mnemonic":"trip below tourist offer burden hungry later grain quantum universe service group","master":"7990e7b10c0c6bc95f45933e8f5be1e758e7b7b2ee39b8caa00e8ca50cc66855","seed":"a96ab2ab3fa2bc2547cb20cdb3e39eab2ce9dedb053277c7802bc0bdc4ba9d08a3860b48325c662de187c935419211bb64ca07448988f903cde04eea9f0f6e68","priv":"6d922bc8eef11400f93de7ce47b55d3e862ffece29fa666ba05c778ffde8d91f","pub":"032567a2ff9a50d1c4e6cc525dfb96da1edefa91fc09c32ddac3ad446056f1ad7c","addr":"abaf696230fd241bfed2c76a0452456bb608c17f"},{"mnemonic":"bacon together open trust hood detail liberty bean spread awkward antique minor","master":"b96abff8fade8664e35d68c78f7609f1c8553a02b80c81857583df0134513370","seed":"772590bec2194f5b552ffdb2eaad756555b22e979ef0463222af6711c53d77623ad9c34abe48b7389e67b10e56aae448e9d064e4be58c5d45c4de16ad56599e1","priv":"532a98d8be2812f88057a91510a20ed4e7fdcad022162e3d3dc14a34104859ce","pub":"020020a4aa457c2944b3c333141e9dccf1c500bb277b846d85a77141f69332a315","addr":"3b5c6eb43438c07d8591e7c4aabe8d4540490bd7"},{"mnemonic":"bulb jewel comic drop copy wreck unit engage meadow hurry acid thrive","master":"c0755ca5e91d4ec8f6dc7b2582d65dc70786a3ea67cd40dd68462ce13535ed61","seed":"e808525cb5c66bf4080ace7b3ff7d6454d07723ec23fa16fc0b3a346d7fdbf71dfe5f383c13d68de5b5f04cae47503ff352ae340700bcb75f2ed6f0eac3b7c5a","priv":"4f592a1d10867d00b28197be6207977e13c9fc551449d05be284642c43597132","pub":"035ec6120eeb601d6b3b444e066252a4c917cefda62c49c0ecd6384c1ca4db826e","addr":"35f84051b0a02090acd509fc801b21864c45ce91"},{"mnemonic":"devote guitar planet kick now above act sponsor account blouse divide horror","master":"1d5329254a9cffc9de60eaedb1735bc8b25c77142a9ea2098e8227ad289b967b","seed":"462b9b3d13f1b1e9e802525e3bd5e22f97a31b352240c9457c1f6d5f194c6e7b7bc37a4fd2607a27adbb77dd837b9114606c8dfc54d78a1a4c8f703889a2e50f","priv":"d5a648822e5c20ee1c56ac5b08a54e561a392d540d3e964499a5a970362c3829","pub":"0381ee04ec2cd440ee26d5a37c3775047e0215b2919736e092c2aaa7152ae448fa","addr":"daf4d242b80955a2269006d530ff6826f718fca8"},{"mnemonic":"youth error panic brisk panel hobby mimic nasty address little original sense","master":"57a151782b47da723e7bc39b13200bb9ee0c3621e839e179a92f99ced03d15ac","seed":"600441626b7035ce2b4e1a90a872ae2279cda57d8f8f44ae3c99edfd0e23ed4afb3e1f4e9b01eb5cba5cafff6a650f2d586d1f0ad85254cc99caa47abab30b4f","priv":"08030c2dd269b5b60f12ee6bb27aad68d3490ef128ca704f390e283ab608203e","pub":"03a38f69571f6187ce334833b798fc0d32065fef197f5812e4c392de54fce4bab1","addr":"02bbd2f05a3c4979db5ac72246d7e620e3edb769"},{"mnemonic":"age excuse wall torch dove enter movie almost build shock blame object","master":"cb4958fe22c8250f41998f6e869eb6cff240550af2db41d0b92e9bb64041469f","seed":"bd585927d17cba54ff5b2b63f2a98267d197ef07caf6a82b3dadc45bc5348d99dc7dac59e45561e55c3513a62ad1942ae2763168562c74ed808f1a59b32a64e3","priv":"7923cba208f6bc84ba7eb134836b96b69bf1f75330caea0be218df31885cbfb1","pub":"0369f14dcd228c164170d5187c21d092b4238386e0c8231a132cbe41e4ba315df1","addr":"93a1e4c78f24c08c48572169fa949001049a6528"},{"mnemonic":"expand shine stairs delay calm soldier deny volume whisper island topple cross","master":"0467b91a321c4326fec8f39cecfbb2d273e628837044815cab899f8debb66376","seed":"0597787fa9ed69ce29f6bfaddfbda091c7b35b6dfec6bcec23957e6a547819c320504afb3ed7a7c5636e4496271d2681891ecafcb9a93ec71bb7b5d9dd06c710","priv":"ab2422cc32992afafc497d2aaf8e4ffb193aa02a5574b0be59cca80566ae8a91","pub":"02348311d8c7310491aaa1f3bfba7945844cff5573ac8b5788872f594e20746830","addr":"a1d27d518ffacde5dcc9a10ade764cff42399996"},{"mnemonic":"sense palace seek enhance hold exotic sense pyramid program fuel deliver heart","master":"715d3a14fdee63848d94f9269d97fa562301f6899487a5ccc9d987c8eccad3ed","seed":"e80766a81744ba87d4faa9199a2b6d1b829256aadfc46f3b647be1788cdf324f8a4ec4ef52af07bef0d60ee090d3c2f45ebad582eb326b688366ebd7390df61a","priv":"7cd5560b3928e4048efe644e39bcc1eaa9e8b783c0f3f0ef5904e030bb6d63bb","pub":"03c7759ec461940a6a3f90b4380286aff6307c2ff6acc234df44aff978fdd7430c","addr":"0d43f6bbde0c5687561d8f5d457bfa78581b407e"},{"mnemonic":"poverty defy mistake begin dizzy behind annual olympic glad behave coin rhythm","master":"eb342d1dc891e285f0d1822af5e00ce3472b869c73102f87c008f73099448ab8","seed":"710a0f8ebbefb347f83eaf54d2977cd64e1f90d4f8de33c8ff041f807d64e5444707432877ffb4697e2e554d1e5bec48ff7428d13ed83433c4200b7aa6bd7c22","priv":"6c36c88b1168a478325ad77e220a77f10a2c8933fd72a2babbc918cd683cb265","pub":"027934c90cc3c75daf4971ccfc56f672fbe33f86c852f648afaf260989961be283","addr":"d60c6edc1bb9b47b0f2baeddeba2723e61aae00a"},{"mnemonic":"artefact vanish security tooth rail claim drive black push ocean special uphold","master":"08d1f1528ad6dd4424ca11825ac1b47111969f21b0285b3bfca9a2e28aef095b","seed":"add463ba53586dcf678b32e6285d40dc5502f91c3dd1128351380f52a28d08b9ba747c28aa85164b342e95b44c1ee03ce9c0d9029979f346ab6d9dc3a614f7bc","priv":"e22dff0eb96c0599766b81a0399e62589bf6e734003e45bbea048ac37c8c9bda","pub":"029954b4e87d373729575ca9b1606c566108753e12080de2739f64ea0a9b881ed7","addr":"0c670a5b8b1fe0a5e43d7efe0a905f67c5ae47c9"},{"mnemonic":"supreme correct virtual guess funny grocery assume dash blush rubber wage chaos","master":"09eb5b5fab562805b57ed0f1a96e66d56b8e132d885f39cc5d76094a4e169d91","seed":"994fbf31e1213b7c113ba0b47563afe37de2acab7bd17ee071c04b1616c6cb50d853bcd5203a9a635fab9dcaa07f0d9d4168a7303fdb53ef41cf5ff15db83704","priv":"1b56d4fd8c5fc994f22d4c7fc856aa18814f269c0f43fe65b52c914a186ec265","pub":"03941aa1d30a3122695e69b6a7f8c94edf030255255a33d82484f90c491dc77f1b","addr":"ebb17b37332f0079728e9de0f2b40951a233a9ac"},{"mnemonic":"pyramid insane eternal man arrange earth predict panther atom fashion claw present","master":"25ad3023a8597a1960b1e6411d75a821d86000ccb3e92a66646017f56dfe65b8","seed":"56231905c46f23f005085a4618005b1851055dc3f639f6b1169189c9bedf1bec6efa219631c333f0cc488e06a0b5babbd781071b7327dd8667bba0467b6630cf","priv":"0a4413be4769217c1f03bddca1fa921ec7935b473e9f13ab78f2b377c08198b6","pub":"02f4e8d8f9f165017e917b9128160fcc8232e03a7d4905583e60a76d3e532bcccf","addr":"d7356ce66dd427267edffbc7d90b1499edb2fb61"},{"mnemonic":"enlist pelican teach loyal like false property ski salon kite thunder gossip","master":"4b0285f521bf09632466c22873be5543b1c228edfdeb25838a3100d72c9bab6b","seed":"9c0e2337f5f02183d2dccc181372e47f8d89c3ba580e144fd6bbcc4d852e49d4f3f093eb1e29e9c0a58f84c6339033b800af15f212b01e7c60f8b89c3525f180","priv":"63a88432a7998b7af6962bff643d46a1d8fd7d4076923eb4a0f76a3038a7f26e","pub":"0284e4cfc7f7513515d97a68efd241f25c47d0b88f57b5308e508141b27b9ef2eb","addr":"2ae41ce0a0a995d865357c09749d94564f91ad65"},{"mnemonic":"congress like unhappy run unusual citizen flush force welcome arena clean student","master":"478229d977380296130a0a3d61be2ed2f8423ee7021544c32372beedf9e8c955","seed":"ee65535652c8733c881553f9ee7b9312a5ffe999ab40e12fe5a7b54101bdf8bc078de75d8dbee815604ebe1fce0eaa7104114780e074d4907297d29c1eeebbbf","priv":"caf650347982b40bd75eaa1830cb5d0089bfc011156c927ddec0fd90b333f590","pub":"037d33ba4e7bafde02969dabfbfe3397bd6744f1552da1313ce129f49eae410396","addr":"a00609d65a4753b3888416518cbd4c25282f355d"},{"mnemonic":"science reject slim wife shove laptop pull hundred genuine method canoe globe","master":"c011d8e6c42749fe6f7d1aea4b04b0d6e618650b0253710c717ece6d31005d05","seed":"40209df29de5baf4dd6b82df091404ec2f1b61f47bfa5e9a23e6d030848d8bd958138192458d82dc60c6c46ec01bf77b5c447e7b2ed0dace4c668d08c86719e3","priv":"058091efb05990cc436342cc3ef6efb2d0f02fed6380370d60255d37a2844939","pub":"034048a3e9bc89ed545de8f2131437838e7fd9477a7c3fba98032e2305732cead0","addr":"dba1207953cdf07ef09213624b99ae24780e8051"},{"mnemonic":"hint where immense cactus sugar entire stool accuse suspect cinnamon pipe car","master":"620259cc620b3b806fec360f2e9b84c4c5b94f9ad34c53b40debd1181e2da675","seed":"3332bd304e7a5b1120a80ce1fb74c1e0554c2fc5d3c007fa58af862c4c2450d9a1fd12c90ca6be5dbf9b69131eac8804fbe0e45ff433bf4d2f634b527319458d","priv":"536ffb48ba8ba6872cd9065c0d76b511a522a7e3b38c84ae16bc3eda2ef49e6f","pub":"038d3d8f70aa9ea108a19076d0e90cdde8d302b709aca1129eaf9ec281672b8aba","addr":"0fcf72bdee5071ce4f241e3c908ab5b0b969a37c"},{"mnemonic":"load loan mail real squirrel gossip fluid wrong amazing own post exclude","master":"c1cfa046473eee67b03ab8be8519a26c8cc72c01324d6a7e6108f3993a76d937","seed":"0f20d1b5e5e93bdb2031411be4c5590f977ca1ccc4550d7c8d8211a62221e6a5c6f34f7f99edf1f785811703a3540bd2f3dcadb15947cd4181b6e80fa988996c","priv":"b0dd0c8d5a07124f574ed87b406f4d51a77491d78f05ff5e80569741c8f044b9","pub":"03c403433ad539d2bfc212628180632b8d860172c6ce4ad46a3e94ddb1657ae889","addr":"145995cd3905204ca68f23c3203d5fb6d6eb8fb7"},{"mnemonic":"attack zoo topic note remind direct inside budget section outside permit inform","master":"ffc2f55b2c123430dc29c09fb431b125b5a3f321ed0ab5f64b179fd3358b0e02","seed":"693b14c3a0b6c0854971fdb5edfe2b5e5d3d37e524a96186d15fb0ab23f6d250b250f5c23a44d28ef9b94210df582d85c17208ce468d09029039ac5dcbd1222a","priv":"76f689bf1d6faf5456946bca3b048cfdefe39b74eb3e0e9d85c2da386db80d26","pub":"021e00bf6a0a71e0a37a8ffac002c5d5cc6350fee3dae6fd197a18ec880309fef1","addr":"7249de82b9250af13b7c309d32688ff19e7ed001"},{"mnemonic":"practice hard harvest gift bracket panic weather crucial have play reveal athlete","master":"cbce18216889b4dd4d2887fc924e98ccb5aae1e9b5d7433c120c79ec3ecc0aea","seed":"02bb9503765066c4e711e1a78be25e7b49689e107f58a2acb252b1c16dbb259db566a06213848fab833a32e34ce565788d7af30f584c21a21f02ef30dd2878e8","priv":"e6e7cedca2c3b1306cb06addcd2a861d04bc383c1579ba9d044a5c752b1b38af","pub":"02b11ef0b566fd9f429f88385507d63575094bd21caf8d3653a8b829c394de0920","addr":"8c0edef9f59b632305c72112f160e9c3616e3ebf"},{"mnemonic":"frown mix normal orient tower hero attend occur blur ship ball motor","master":"87c9a61c0fe1e8760393b18cc556b8f6d1d4bef0355444aabda127b342865d67","seed":"8e35626433f0913c1799adec7b23de7cf6d0689822d3a2f8d1bfb6ab041c80db3e5703c96aa09ed0db4e4f72097cb652e6d01d065bb6ab86f19e498793fb44cc","priv":"47b7699713fc59ddd67a556639c3f1ec0783a3dc3424cdeae4335707a549181f","pub":"0281ee7c3669207a68e189aca625e1b6eaabc909ae611a6eb2072f51a6f26d545b","addr":"ddd6d8013e5c4f99900cb22184075afb7842acdc"},{"mnemonic":"beef apple unable rocket balcony tag tooth spin sunny innocent clinic dice","master":"6b08fb53a185b5da79434bff6de9b10c558fae63beaf5f487c36760da44cb28d","seed":"f06397170fc337caa0278b2324f05095d587887217f5f10b13b04e1286158e4fe6a15da54c7dca729744e268255f4d04530763580ac7d660b323a8e8fe163753","priv":"923e63fa8400088c1f464357746b9e95560c23a755427d792aaffbb73551fbd1","pub":"03046ea68a2e1930e531b00376a4254da2a1ff0ed278aa800af2fa17cac40021d4","addr":"3ed4b79d2755b7d95fe1626d26a2b674a927b3be"},{"mnemonic":"sadness frown tape chase swear cushion eight funny sight dad solar civil","master":"af805962cf1c7bd97d0e4e981d3157834a17d3dce23a426c299b128685f28bec","seed":"a6292e7e8f3a502c4eefa0cdc94fda1d528642e084f45b30840e2ae9e7be636bbf2d67156e3bd352d1bb0750fa4df04dc5b8b6479c7c98c116c05ad5fe2d4d83","priv":"0bc87cd2cbddab83294a804fca193a6bbcaa3a07583bb2dd35619f325b70b7e4","pub":"025811f4948be5336572285ce58c97da84e5a4b7c542180933a1f4b6200ee4ebe6","addr":"9c6867cf41071e1f7d84ace3d2802ee46a1c08ec"},{"mnemonic":"bulk topple anger gift matter soft dune hotel dutch guard cycle close","master":"816ece50d6fbbee470de36fbcf646a83d224dabf5ca206786202f59ee7be8831","seed":"4980fcc86c5112625b63300e007a26287fec1b2a9cac0e254a8f43c91d897c03a3663fee0b351fd877171ce708b3fa471ba67290d6ad32075f0f6be6d3f70ec6","priv":"51cb46ea5db7c500388df8310bc5c8db7bdfb7c797030aa8f4a262b53f82a904","pub":"034e93f88a8da10122de23e2b25eeaf19aa1df514293b1e8fbdae2ad9fc2782779","addr":"c81ba2724c2e99a7168bd74cc79e222dd845187c"},{"mnemonic":"account lobster inhale champion relief scrub poverty tornado romance build amount exile","master":"202f11a0730b769f90d0fa68b81e9fdd78be483e38a9a39c447e8315d8f9fba3","seed":"001ce5c310547070fc2169bf0cb7353b90e824c051ea9f285eca426cb7f2527cca995865b0466c86a0fb3e208dc1ded076d2b985c8557dc7a94af7c6631bdd93","priv":"d142d2616dfe9e3aa43634a94a05707a8f0fa58ae0186bb565ecb87c96f648a2","pub":"02ca5eb73da42320161564c42520ab1a4b5823805bdb4dcb44a4abd88a235c6b2b","addr":"4481e257f1cb7d8105823e54a1b8d0254745874b"},{"mnemonic":"defense knock simple usage cook shoulder alcohol muscle pigeon balance become sister","master":"26df035303f63f356b451e829e154cac27e3f0c1686679c784d405455adfe5a4","seed":"44955b360a1622c1a69d20315b5fbc982502903b45736acea4f146c2cf69632a99630195b1166be96e4c90449abe1cddfacb3be63ff2b7fed02846b0d9244022","priv":"b9dbdb8952ce34d5f575b8b012a5e3041521efb893004f45eef2c01eb4f5fad6","pub":"02e9a6d02ce5cc1c14421c3d6db53d16a048e0421128f1ecc1e3e41d7df9d4e609","addr":"4e78dfe3fc045b8f65760a337ba354e01851d82d"},{"mnemonic":"bonus surface unlock noodle genuine stumble juice purchase grass table call piano","master":"16474b5955a793884279a9936804299a953427a38d5bead30553ec709bf42c74","seed":"da8eae0d3aa27a6ef6637dd17d57fe98e75619837c3dac48b3b546152d5fb1dcc4c59a86f65e8716c82e3014ccde5779e6e33c2a2658c71424f4ff9ea6ca0065","priv":"c9bdbc26bc788147d12c4bc3b13ff3774a7aad1ac66ce45e742c7a96eafa2a5e","pub":"0398102ae1bffc71eaf086b652c9bb847dace83d0b3f87d91ddacfb1702762cbe0","addr":"f0ead6caf66523b7e655b4ffd26a8b35f0b09eb3"},{"mnemonic":"envelope scheme knife muscle museum town valley until quote interest film keep","master":"bc01f4cbe286c6ad87553e0ece0e142f49984c2676ed1fc5142abb75637d47af","seed":"89867eca31ccd75983b064d62a1b4061d1f64c1731e25e08c65259139590490827869749ec30e8218e593e2ecbd4303984dfdb7b15775a487ba0eba84953a940","priv":"b5c899498ecb94655e622f999bd7ef9a2c4d26c3f555ee6888e5b4e1abbce1e9","pub":"0316d5c61149c0f83944192a788b5b64b9e6b1ce49f2604db67e8e4f16416ae153","addr":"b2a48800c35e6592ebe5003a46883a00360e2b44"},{"mnemonic":"also genre defense valid point smile hybrid radar lesson sniff one recipe","master":"3cc6fb6c4ddaa98e3daa2e984189417c55c1bfec4089397855f809659f9316cc","seed":"e962b4cbed0c3d5232f75595e7aa3cb33f1b2e093bcf9a21a4f8c6dd9677aba42161fd8eafe38fd12ca0ce3cb58d4d26fb7d349b1a160bf7f6f6b6c56284ac6f","priv":"420f0121df8cbc367e966344fa28d913bd1c3a1032efe5a3627d94039281e98c","pub":"03a61034ea8ffde7a239db255e414008c8e913a1405a34d9a606108f1943a7fa86","addr":"5976e21c1f85766c535011aac79e8a5f8b0f08a6"},{"mnemonic":"flavor spy elevator parent theme become slender recipe media pudding suspect melt","master":"4ce14ced0d4121d342d2c514755ba73b17eda70cefb20efa5aea71ec27ee47d6","seed":"0040263c29e5d965556054dbe7a738ea35b46775bea5859bc2e5b3872c89574e4f18de3f6fa36df65f47b13417763dc8c020b498ed3e9f11f46f019815bcf9a2","priv":"d2a1436a12fc9e4f2acce77564b8ddd67c1107d525eb6128c1eda078d3d8d845","pub":"03246bd048416493a970d97130d54db7e263af82dff75cc9fd0cf1e061f5d3f8b1","addr":"7eecbc8b6082d62d5fe28846a8ddc20b16e6a9c2"},{"mnemonic":"path number useless federal birth such peanut rate swarm flee current grief","master":"01d57fdf15aae5c1d45349fcb7bda6ab271c15be88429ebd1122336b91937540","seed":"061d0906c096a3338ac0877a102b4bb3b375ec5b34809838dfb47b186051a0a66c98e0d4a4dfac2c02b86266c4574c141f7a7c9365a57449ade60e28aecdbca4","priv":"9eb30cd9489297f0c4793df375a4a497162c5b75c36feb0a979da41000cc842e","pub":"03e036866bb847db7570ce0e2459d009dd1a89eea3fea8c3ce4f1f47c4781e32f1","addr":"139b3c7e7cb476da573548067d0a29b5abc111db"},{"mnemonic":"observe layer grab few fiscal omit clinic manual climb cloud song million","master":"cdaa9864952fa51a5a10de9210ea9e0199875459304876fdce150f042a415583","seed":"fa2c9dc476532ac66ec8e219c69883cb9645129765b4698b7f2010cb4b86b2d25ebd45e6c582a9f886c5fba4cd4d7488e81d705e63508e67c1698b77b8e6a676","priv":"238ae189645958242ffc9b3b868d78bad1be7d1351573298aac47ee78a5dac41","pub":"02ba7dec8131970a8f4a837bc225fe1e8fe20ef90b6363c058946930fe6b8cf629","addr":"4aad44c69095bad1588eacbffcb5ec324dff7563"},{"mnemonic":"solid business era limit engine fringe recycle harbor organ like tiger avocado","master":"afb951280a835f1ed21d00d478a644451e254310701d8a8025f5c716a5843731","seed":"2692dff98bb318f1f583e4f5d87a453b9e1472781b38f3b6a19784f8fd3e9b156ac6a292f8ab56e1da0967e159438b87b73042cbaf3e9886ee2641e7e97dc821","priv":"4b4bb7fa92a26e738da657b31ae57c52f057540f1371066b2570fb247b2862dc","pub":"023ecdde05d734b6ac286c9b14e1577f691f114b6554d0f1b389fdc37e05af9a55","addr":"5402fb7a4751cb34b261a2a2be940d7bdd3608ff"},{"mnemonic":"convince thing assume midnight debate end best cause laugh sweet unusual present","master":"7cf2f1baf94a8487a364a742db15bef15d1d1a7583ea26dc575b0181357e31dc","seed":"1e267ef4dc1099a438a346c7ca4c546149d6a57dc4cc6623ee160677711144583245125cfdbe45629160f3da711fbc57171564c4cbc771b1fd2a21236751eea4","priv":"9eea5ab5b8b22018197fd3c9256cd21be7dc26a111c60bc3d853bd977a19c90c","pub":"03e17aadccfc20dc41e65f7256717c54f9eb3898fe335395f25a65d4a96cbd93c6","addr":"85d9c9992d5351d84d40790e65c29b52b929f7bd"},{"mnemonic":"property youth river offer mention cloth mention pride opera repeat hidden orphan","master":"7e0faa6a216e4ae162547f5c9639530abfd56ff2026b4f18219d1c82934ab2ff","seed":"dd9faf30c2ddece69bb5d937c9ee58172564ec51d760fbdfdebe4dd445f1819bd6cc21a2a4cb70fa94a0d941d994d3ff58331be94f57a16589cd7a93c19ff10c","priv":"fa343044822d07308bc523eaf778bf697302cf8b88a3431bb5a0a51974a43199","pub":"0383e1d8186c1b3d0c567c91966a5c7aee8a1492feba372be735f9a612c1910ed3","addr":"efb2221453dfd951ba456f1c5ac164d3faf08032"},{"mnemonic":"awake virus civil cash clump equal phone wet friend attitude ask act","master":"87a61b5729fc2e294da66541b79085aa3f67c03a3eec40559111e68fe5a80412","seed":"8fa5a84240149f39dd60a5477ac59586aa05d6809adffb8184e4154dad74c2ab9a446f296098c44fac8c839d3405e0a2c1edfc26ba3aad9665e6b6984d320fbd","priv":"726210437d3054875e785b12d1aa23a8cab85a0a809593cafa9c63c62e6e3c55","pub":"025494819085e1d08d8ee2d421e4ca873682c69446ec5a412d7c7a7520900397af","addr":"e26e023a2aa67a3bb5e5988be46ff266722c0153"},{"mnemonic":"snap control problem flip minute huge lady elbow plate fall cabin trouble","master":"931052717250728c04dc605a8cfcc6a49a4c520f9fc343607fce57f5ae7a9e66","seed":"f55dcbed51a9db2ddd39d1164a81049af71116896e79ced722a387e878d00633830ab8cbfe7ee8e16ee612e1e047fa3d3c2a0fe230adc6a84f0178fef6aedc61","priv":"72aedd9eca0a5f17b3c20866d6d1e98bf01a1b8b9225bfb1d93f93c594726ee0","pub":"03c07579c66433d1b676630a0ddd343167fe91419a14a7859092b6b7f81341dcc2","addr":"37b2d898f165d5cca507de65f103231ea5128788"},{"mnemonic":"wine foam depth wise faith parade tuition search demise skill boat survey","master":"5001f6ff67ae2a32088e0ad93a227206bd66f5ccc7be991a27b2809354050b03","seed":"d889ec2bfbc930c78f9a3fc356e0dcef9d636766af361c8492189df1779bf76f4890d738106132cc5202ee97b849c9928a8934fd0b40d610a38f514953e3b02b","priv":"c19f1ce95ac35938d19d41e45d7122e8faa102e219188d681559d4db3f6aa66e","pub":"02331368ed143ec22cb1af2794bea8dd5e5661b9c6b1407bfbbdf1c1a151250b7c","addr":"a70e3677cb94b449a400c870159dbfa448e137cb"},{"mnemonic":"picnic basic you priority gown town oppose penalty various half follow nut","master":"59f5a86a5f6cf3254607f5e9846c7725d7cda493ac9850042de3bc7e8902583a","seed":"85645734c0caad6d0f3be793f71f08f2b87cc92b515e75abf94a202941c45aa78f663b455c91b6d51de40284d9c26a5336d444346b408bc12d8690e541a43583","priv":"17efc82e851c2938c22527638f4f3ccc2ff16ab95c24429c583b6f68d79ac948","pub":"02e534acf511fc86761ccde5eed25d793831cca6069f09694467a3b7434cb3fc95","addr":"d75b0c916f2329006221b040901933b2bc309838"},{"mnemonic":"enroll shaft young ramp moon message echo piano advice time blame mandate","master":"02f99e44bafc4e61bc3afff77696bd72af71ef05c86dffb2bb3bc241dd60861b","seed":"6e1cccef229d10e15ac6f1d2b2a579146ce011411a6e807cd227f3215c32aa394428f9a11900fe21699ecfd09d5ae6e4e1a30f2778bbdc15fe30927e32e1fa5c","priv":"8300a73d51449f909e8d0dfd843aa4cbcc055259f7deb54f40bfcc41acbcbe2a","pub":"0251fabe51d7eaeb45a7c82ee6cdd100f338692d796e7f1effe6a705cfeb21cb71","addr":"ada0f17f1854fcec548021ce617ea90a05a2fc8e"},{"mnemonic":"remind lizard alert mercy badge sustain judge van spike obscure account twice","master":"50a01f4e2adc48491e54c26a8c30c38f451de1d2d8195661eb50f6e5ad6e68ec","seed":"1194a8c42df528afd1b1eb41b2721a9b05f9456b09d042f15884d136c1713788ed8a32dc2153f01b560ad904c93327855450bb93ca8db384cda230eaec68ecbe","priv":"b78c8076bc4378ef0ea80af91addee35557f0fb059c1b434c254ae6c76716ff4","pub":"0251109362a0885fa59ad162e24c8f55cf4895bde354cfdbac7278d69124f77022","addr":"6655b6a665acc146984fd188c3c260668fdeef65"},{"mnemonic":"chief report afraid nation silent tower defy display suspect dice switch finger","master":"472175c2f86fa94d913108eb3842ff03fad950e4c7714cab8ce0c46e8e674968","seed":"c3656bac565a87cf18a1cfd8d488905e4b18436f93d0cf1d61572741b6e0ddfa794ce94a8b05e7796a6c9757edfecc6212e8b0ffba1e71064f67c340829b36e4","priv":"f16f039577d1fd9d6bbc18dc26c03cb37ad303ee1b85468df3de138ad927d098","pub":"024fcbc106c0b515838ce4d32c50ca1ef6134c314668d98a3ee30bf27e18e2fad1","addr":"a88574f43c1bbc38c2db68fae3f73f4244973b3c"},{"mnemonic":"now renew same wolf host minor obvious tape install barrel retreat cash","master":"a75fa702bcff39de09bcdc8f55cd1110c396ffca982d7c48f6d3d2f98ae29938","seed":"6d62aa254ec89ab960c04b4f72b5fd9acc135ad79ce4c9b3fcf25e0caca06ccf05e63d2aa47630b6c7fd3dc274dea540ceb4808eea2032ec3373d8a77b336338","priv":"dd211f6c5037d095da723423be7c1ead08f09d44fe01ffc0b2c0b83cccba6ab8","pub":"02ee58e7d2d8abd00c101024aff3da181d54ab84165e0b5c02e9d53dc336f0d11f","addr":"d9c4235d8222253cf41236382326190cc8f3983c"},{"mnemonic":"bonus message butter logic disease coast transfer explain away swim taste draft","master":"ac79c0b183965a1d918ec19217ce40c6ac1d84e3d57c8d0dd7a0c6ded35f057e","seed":"3fd63c9c7e1745a0f2526a70de96f251f1f61db25e808e3a6ba500e1a1c8e0693b888837cb9ddc1e8d09acc296e908eddb9386b97859bacb10561d12e46056dc","priv":"842e49ff7bc56dc113d532e7d7b4fd4d721f4600af0e67088b6ebbd491dcd4fb","pub":"03176edc37f7b671f46248531479b45b2b6ec77edb92001b46c64c7b88e7e588be","addr":"8170b83efdeca9e923de156cb5da2e3110852c0c"},{"mnemonic":"quit culture vintage misery pilot cheap wealth buzz false donate edit lemon","master":"b2fb8551d9d84f229e26e7874d1ed77ae8066ae80e04abae48ea84f96ae448f2","seed":"2cad64c36d24dc0cb94a2b2dac3ceec1498860ef0faedb78f702efada34c350f6b7f7760b14efc177893797160a838ead20f5a890ab05c477ee70cfa0a5a6c8e","priv":"38d5623053b64b8df44950a9f305288e3af0c411238ae3a89ea45f28f8375c54","pub":"02963af6b3f4add138a3b45b5b8f01bae5e6ba0434d558bed64fff01c6750ac053","addr":"9aecc7332529b0982d8ec14350594438ff5562ac"},{"mnemonic":"paddle mountain rent siege length essence negative amazing soap pitch blame sorry","master":"f179f7a22dd44ee96dc443f7fdccadeef1afaf9deefc8819cf254a554a3332a5","seed":"b408f67dbcdb8089f6ef0b241f026f6cccf85753ae137888e80c47b3267f58902e791675cae2854f556b067915821516fa04e00bfec6cd8e474d29639972741b","priv":"1fd4e1444a9c49ab77235d823e24d70d18b5d37cf9feb550c1e0763c7f9980b2","pub":"02bde455cf78c59409eaa2d98a105b537c9aee34c53486a4247299af90be3cdf38","addr":"46269ed379006a40bd873c79a9526ef076260eeb"},{"mnemonic":"abuse office gather ginger member carbon trash detect mammal shield like wink","master":"bde4ba63249cf7e6ea92a5724ae2f34477e42a8303fbf5c100c85c3d3ab8fc6f","seed":"ca4615dceb4adac1b16195899d537faa0d6e66a243c30accbe4902d26e77004da08873b0899ba21e4233d048c2d171cc8f9e657971f2ba0dc87b843f782ac619","priv":"05d5ce699cfc49b676ee843c9f85e1510f27cd65a76ba4d46eb6db36fc033c47","pub":"03c465fdcfd7441ab8d34244970daacd29a30c0d972b92a961559906f736d4cfb0","addr":"e60e2b02b46ff358acaeba84fadce61d7361f482"},{"mnemonic":"rude depth finger strategy wagon cherry mixed assume sense aim diesel urban","master":"ac83ffb8b0b9bc49758a81e567d179fe060301062d332bb40e353b788bd986ce","seed":"368f7051cfe851c638722e3691048292a1f2a94a83f44ac9e7d6d5a882c822e75ed5116cb059f0a91550b8b2237d32b9a0bfe556217455044b3b44962f4f162c","priv":"4af19a58ee5ea6c6cbaed88cd83c13a57da1c8002b816c833fdda7388adf8662","pub":"021ba0422b1fab7261983106fcaa20a43d8629633c95948e42aee12777181c1efe","addr":"aaccb6d212ff003c8754147b89b0718a58c002c9"},{"mnemonic":"mountain bitter treat hour purity swim panda damp notable beyond rough spider","master":"e48be94ec031c9cc4361550d88facfffaffc67fc0fc5adf495aa18e17c431007","seed":"fce2cfd110d408ed37c75fd0a88fd7513a09a8dc577b38176150f7d2835959f8170438903a78a5d84b32923bbdec6d5069c532621df387c65bbc2a879fe162a7","priv":"dfe58c17756a93be86fd81d3c874bf4ff6c45cbfcf049bbdf999a8e798e448c4","pub":"020d3913b431030aba9c57920708c5648ecdba1fb0111ffcf44f91f67ae92bf176","addr":"1ed6bca6d4080f039a12e3b0e772052231818121"},{"mnemonic":"protect chalk chapter dream icon boost layer couch soccer tool taste congress","master":"c5d0b996ee26e80cd48849482caa435956d87476d3fc5087a900a7e666ef3bdb","seed":"e40c57922c038fbfeb1ea7dce70c0807a55a2c62f58f947d8f05cb66ea7b26131e8b2b81ba9add4185bb8fb72176922190ba2e15de9caf3b4749ad7840ff1acd","priv":"850e9d1840b28dcea6088c9a4837effa1254f48af181d63f660d18f5062964f4","pub":"037859452c974613068cb16147826addb72f11101db03017612d1eed3e5352d010","addr":"3b58443eca15b2061bd5d7b3240b93e012424579"},{"mnemonic":"rubber twelve wire exile shrug will alter violin crucial border drill pattern","master":"15c68b495a571a78a09687a86495141f94b2c015f4c51a9dfbdad96e68c6d871","seed":"ecb81c59dc0464e8ff470db36c567301543b2bd1bdeb94512db63bdfe6632d9c88c1aef02bbbe04176ac7a0789c9579431e732adfbf038c89aca077d14582a8d","priv":"00ec93d9115439212ee358244b5128b48a67645a4f5bf94fdcbff2c8e93cffa2","pub":"02e68bb8dcc584b4e54da27ca229a66d6a222dbce0e187a9330b1740713addb417","addr":"14f8f956d84c53acad6e5eb43e8fd7362d341363"},{"mnemonic":"loud ski diet extra rely melody space canvas humble rain park fossil","master":"1e09a38b1538e950b8ba8472c07b619334973f9075e41732851606645e318d51","seed":"a2d3ffc96f020904af3760c11e9a9e87e8824c1093b07c92a8e6d98c6aec16adaa8ce6995d5d6b58a04824a765d0232ff995183ac38a5cc2bac14f734ca8496c","priv":"18e45a61f9e6ec29019df10abca1878045553d9b924c859fe57621f212133edf","pub":"02a0053e91ce99b2c401fc40cc2892023b30c2db914403ea0da794bb77f69e93e3","addr":"bedc6716f1649fc2ae412516cb0a1d68ec2868e4"},{"mnemonic":"potato tackle almost kiss unveil spring smoke nature agent carbon swallow final","master":"5917e819604fceb3e7c11bfdf6b85809f509f89b3bad6ec7069e8e29258df791","seed":"76d3089d7214660adbbc748f9690b70f7787e9e028fb429086caba19c3b412f931b2768a843ddbdfbb6b6bfdc6349aa0fce1168d124a13d8eda61fe37b407f37","priv":"13c35356aea2324ac57e4c2d605c45020adcd4be336e097dde0b23059499e947","pub":"02e9c1615b710594269b4e86436bae98e4e9c00e7ca0405b89be47c02060705ae1","addr":"e9699c41d2da37635fe657c557f54f51d8e4a503"},{"mnemonic":"innocent cousin jungle elephant speak rent arrow maple danger menu misery breeze","master":"c2dd7273c7f703e2c66974dfd25a1e7091d83a7e6f8ef64954c8b61cfe4e84c5","seed":"32f96dc9661f448f82e2100afa787fa09afe19d90171a3e2d7b5a007316690198a3da22adeb22a2fdea43c3ee98a6ee2bd33baf1e84034d559e6019a30c2e87c","priv":"1e9f48b65f2c57f6af4797a41afba8b017de41ccf6be00bb2a6dad09a72df167","pub":"0268e685815391e6956df39750aa3e9ad8e4e558cba04ed4c136785e2bf82478db","addr":"3ecb6cf97afb26e1e0272df4fbad2e38be15287b"},{"mnemonic":"shoulder lock swamp goddess length trend tongue razor heart donate curious social","master":"c71c518c4d97855fbba7c0d7df9ea8f4e6211962ca9f5378b493c6c1d3b6afc4","seed":"e575bae2e1ee08815052f98f5c4bfb9873f171b0dedf4385e378348310c5c7f6d1cb021696e5913aac6b631ea1951bb977b3bcb548579458807cd565771945a9","priv":"2fea7aaea02fd5d5a5918ebd643bdab939edd18ef406ac5163714fd731e1157a","pub":"0363e2499272df247aa216ab8b274e146fe677bb18e706fc5377f8c921ff1c782a","addr":"de719e1abeaaf11712931d05ee39990e1331055c"},{"mnemonic":"bitter yellow post enable knee tag spend base blur gossip lucky lucky","master":"1af25d9330946339620183b1f1209c4d1ffc0aae754b82d71268400b934ea426","seed":"9e07914810a7e2d91a3ff6d4efb0686c14e59506dd9dd3c357dd5a30925a3f57c0a4983589ff113833abdb7d5cf7dbf79c08172888539126dc286848c1e49ab8","priv":"6e1ca5a3a31b7f805e412f0bcde7f82bb3fd984661a58c07b7967e327e664e47","pub":"03cc8ddeed92731c6b475a964c885865c5a11bf59ba24295d1e1117feb7f1f3e5f","addr":"8b516445842b755f23d0e671f10a5c0b1c2e48f5"},{"mnemonic":"forget organ violin inch panic sword report clean garage sauce math man","master":"29156bb726af212233cbc6c191e59a96d7ce44b6821538ea03053f36d51a919e","seed":"66c639ef4de2dec82b99ad4ab7bc73c0a4fa79d28d06ee393ccdbcc27ee375e9dae7672055dbf6d0d5ed67f2e99d4840614223d85aec64dd35607aa9b266d9da","priv":"f5e49029f7141b33f51703add1f4495e04715674fb62ad2d781f8c66269fd32c","pub":"034132d2bc71934628f435b93a9d161a3ce242e7d82dcda0a3a8c2f304e3057500","addr":"cb0a4d79fadb82d7b947889b26f8515db8fe46e6"},{"mnemonic":"under depend door lens retire faith scheme dolphin orange maid carry disease","master":"62ecf318e91f233b59acdb4000665338c8d61539b7b079716c85ceadcbd6300a","seed":"30ec1c26fb1dd7e41c5959ef7a3615e6d4e5bc21fd8af5efe1f8c0634e765f63462d7017d5a62c1e992bbb626ffcaed002208ac5f8867a97e454c1bf0bcad8ce","priv":"2babdc8642c9c9beeeafb728e948bc8531dd066679b85a9b58676c0b4247cd89","pub":"037f9e2241008d25844a96272632255802c7cd3866c5a83bffb3e2f724eb59d385","addr":"10eba132bdc71c162058500af51c53074ea1947f"},{"mnemonic":"swim topic sunny exist exhibit nurse ozone guitar trend page machine pitch","master":"5a30155bbaea42d54e9a27fa7587c712a19ad6c1c31052f68418f235b7bd5de9","seed":"673d936ed3502149d68172a22785c2aa2bbb3707d319fb692fdc6a4ace39ec3596fc406b60720ab5993af07227f42608b5a43e8e732c72d8ddfc82e680428925","priv":"e6759f20947caed563dad40d46206c67599d4d622502e46199fde1e17dc3d76e","pub":"02dd5474a52b623514948319697c646b519ac6e63581d27b01f0780af8af085e66","addr":"85fb1118593dd8c12acb0c2104438faba5dc236d"},{"mnemonic":"dragon square define chronic round romance scrub gaze powder visa please symbol","master":"1f1a35ac699063a47220536ddc3e988c055cee5e08303b867fdc16d5488861fe","seed":"dc2037120b143c919a3f0d71c6822f29b9b0ea098d286f8d4e40b3240bc9d19d4f45da3bdb983f49c304c083f534c7a26471296211845c13b49df97be61055a4","priv":"d99a6b75adef1455ff85fc94e8a4ad400a326662e01e9c0152c797b842c060e7","pub":"02eb2aa36f19bb90fca43f34316a18bb80053faeaa909cd6222128286af6c18bac","addr":"d24f7932d14e493a54a5384dcba3682e3d6c55be"},{"mnemonic":"first knife erode dice talk coconut act example sudden garment scene income","master":"1214f622b52ddf15c146c74bb0843b653117459901214a8a198a0eb59b4153ae","seed":"eebdecdd33e9ed6dd2e825c12a73e4325593aa14a7faecaea48d6764e6ee6d9d4140ed9e105247b2ccc0a1bda976fe7fc7ef8483c58f465cf393c4f833e86d94","priv":"ad3894b4f558a2e7fe5f0685e4ccd63f57aead98863617b081ac620cd25ffc4f","pub":"039de7903629baa0b6ef2cfa85dbdcb51af3fc9218b01bc57bb1f7eeba5267a858","addr":"fe6dde2516232383dc3382a75e86be3b82d2d8c9"},{"mnemonic":"danger expand toe talk course mask quit virtual reflect vital address artwork","master":"54c66d5d95de00c23ccdbe2defb6cfe78d809d55e457a0b35407ca74ed33eda0","seed":"060b5853c7f3bbd7bfc7b5d532f39b74137c2b6273a30682f768ad62800744e1c6a1db920d151d7e553553cd908b2878a31fc6c682caa05af62eace45a897b19","priv":"0ab2d63d607a2c56041fd953d9be60f5f7ff5e50f3c3a606dbf54bd799e64190","pub":"03f8b555aa7005be93d03e98b6f2a8870b9cd4ef654299be64b13b89ad839038b8","addr":"526ec814ef1712329c1cd43244e92d3c1d5aef91"},{"mnemonic":"custom flock clock grain absorb danger universe achieve decade habit phrase together","master":"ffc14bb5a243dc703a5afb1f904f8aa4f21790b470c9e05fc21cf872bdfce41c","seed":"71a82a4221bf48e1e97c8e144de80e80a9dc5808d579da185e75f6b88bb81038d88210c252921a2d72dd38c5bcb4edd442d2b481dc1d857965012d9249f77477","priv":"d9bab16080df04ffe43c57fa80c441a65b4e49a4425a0db06f52d6db77595d38","pub":"021f074f1e14552ea091e14e680814661b1a75148f8bd149fb8f6a13f6f5e7ffdc","addr":"d63213b298b92b726178855680001d79ece9271d"},{"mnemonic":"spare absurd book liar green humor alarm income sadness shoot radio indoor","master":"f9056445390a09170334e8a225d62719fb259a0c159685c29ec39e348b742510","seed":"a023662c39608142068683c030ad51321ecae6bf954b72465dfa8feb34f1e8ace0d46a072b855e33f7c5e8be70420a4f3baf7ec3ba370e975da88890d4cbb2fb","priv":"e5b8369724ab9aafb2bb44a1d3cceb2568fb0350b45f123a7cd0f26a27e70b2a","pub":"03b9196b842ae4db2b2409389a0747407baef8b19d502156a809ae02161cb0de38","addr":"658f62b688afb4773a0dc4c81925d7914dad5d22"},{"mnemonic":"anxiety salon have exclude build airport decrease unable measure reunion monkey private","master":"4f708611377bee900ca76817926b905bbca28bccced3ad0e211c7609c0562fef","seed":"cdabd5c6b9a64c302fdde1e7cc5e6ca15811e52e432e7019a81945264b3e52d89456171be0e24d4dffea0136a12a6204f2958c303f8c61af84f4b5ed135685cb","priv":"7086136c92846f7deeafe05dddd8461028edf62e947fda55b4f1ac584a78c5be","pub":"03227f8b0d42ee20d3c5cb4524686d19ed43bfa5595debe2ac4840eeeb92f3a411","addr":"6d11946752473bad3a3d593f85e97bb4664c2984"},{"mnemonic":"frog youth swear now annual mushroom stuff business excuse frost cause athlete","master":"0390c3c986b8d724d344395860504caf17a7a347d10aed2f4a0ae7ebc0e07f13","seed":"25b6bc7a888b35e1246bf8c7a289a79ba589cbd949047ba6690b47bbcb12d8c87a4d14d585fc0721217891396ce0b0f75852187a9fea4feacf320f9ae4eba3b5","priv":"ccd3755ba9b7638c2ad6815d34a03869650bc1c35b75c8e1a1cc9c2ad71d983e","pub":"0284806c57cb6013ca5ac1027a07784d05b23bfc4e6facaef108bc5af7ec20e026","addr":"d512ff91fe37ab6bfc605cf5470ff684d6dad743"},{"mnemonic":"bridge rate pen range tip web bunker magnet blue rocket dune evoke","master":"38d760387d07ffba1ebd6ef9fa9737eabb311bead38560cc464c7585b90d6915","seed":"953c78a493fa99014a542b2740b5eb2623f0fbaa765a5aa79e61a5344867dade60e05c4293df4076e218ad61c66b1112f54aaf7bdc6000b059b2c88558f582b9","priv":"d6d617aacf6ac20090788e43a7eeb58d1b44c36ecd4fbdc9ba287c8bc7f3b24c","pub":"03ee39cb612e75ef609467ed6250b602b90ee94b25ae43be9593d2cf34b3cdb938","addr":"dcfbe07630e2a9156f0787ad4e96de1bec09b3f9"},{"mnemonic":"volcano exact weapon couple logic cactus carpet raccoon state rigid ball tent","master":"8c60a1a859b5684bc6aa996738801f47adb8392ca3f92865b2f2b3a48c69425c","seed":"fc6ede285bb6e6fad778234a5f6c5bfdc23dffa2975667dda6c5470c70122f8aca9c63bd77c8811c43b4d4b2ab4ca55db7b4d457f393436ca1626ae6fbde03e2","priv":"74a1b74d0f11c8297f0d315f9556a96ec5e880bc59fecaa1283ec2a693cd9ef6","pub":"03f62cef4ff1147df7ca38cf1231c48632c4c4b2618e6c7d2bd001e10509f68f05","addr":"8b8e006c70eba973ef8945d89e33b6a5422e5742"},{"mnemonic":"match quote pet worry pizza stock flee tip kidney tomorrow giant ship","master":"02f8e676d2c4dec8e6a8430c22f8adeaf3b25054c8d22dded7e2bb6af5327a63","seed":"4d29deced03c572a5fddf55539a735228b59cbcfa80381a54c5a69dae73f56484318e511fcf46123dd8f390e2527de882252f3c0b69f49b9dc83c7059e876767","priv":"049f7fa5733f1c674a29721a025d410bf35891984608ce1eebc7ab48626ec3d0","pub":"026912ef70835b247c3fee238937842fefebdebf046b7f2afdd4f350152765fd26","addr":"4d221f1336ccedb6b2a9850a15bbd13c62ce0fd5"},{"mnemonic":"swap amateur unaware glove biology frown vintage dream prison bulk gauge bacon","master":"8c370390691fe152f7d6f5220704c9fe6b27009c1218a07d529768f40fac692f","seed":"5e3c155797cecf5509151218e30101e33da6058dad04f89dcbeaba0d1d2310482b278dc747298284bbf7e29a71cf4a869e0c2755f6144cd2a5f58fd581551b48","priv":"708a814272dd4efdf60665c491730ddb73d3d5eae3d74ba8ae632183ed014569","pub":"02e06b607086808b325b7629a95ba7b945e611c3062f967402f04966bf87111a23","addr":"d343acd452e5118b6e4c1a83cb08a521735f2a39"},{"mnemonic":"shallow chapter special riot dial sweet armed imitate rotate south cliff shoot","master":"bbd697f9078e47816c986596fd2af08818e0e84f3c2bf52ff52cf72974add88f","seed":"bd24f3a066e4a994bbd613d12f88268d16d2439f9331932a9b30da17c7fee4fbf5aba4f2f333103c6bc1d0bb600be1c86db54e323b6e9e9394b93eee35a65359","priv":"1ff3375c7c35230fdb97b8b8a2401a59278b383c355dfc1773024fe38acb4a42","pub":"02d3fa09d1e5929fa37218d16448800c9eec188e31614396648b65f3303bb3ce80","addr":"8c3027c978b9be60970e98790b073f62cd3615da"},{"mnemonic":"illegal hospital witness leader wagon appear trick mixture refuse kidney total lizard","master":"9fdb13cb834e01260d56ad2bb7c8db55b768bd0e76464d52dccb77ab806a1258","seed":"a96e21fc0177a251d86cb6ffa4057890112cafd32a7c270e782616b407cda51dcd914ba2bda90c80acebf8969825e8044ec77965e264e085ee6ce78fcc698f61","priv":"17804874b6872c2df6c5da2ae45830f752a159dd03ab0b2ef22c64018e91c14a","pub":"0221388d8dfb7416ae88426999f1e07d41aca9668b10262e995cce20448e315e54","addr":"4feb63cb3ca2d1f6b0add8ce1bb2db5661dbdeb1"},{"mnemonic":"unknown update couple lunch demise sick brisk market area kid service again","master":"26f5f1d04e6f20ae2a9cf5631a1fda6f119e3c14dfb35ff75ced5091ddd072ac","seed":"72e5f09a5c9e56832ae400cc69b98932067a81edc9c0bd0d97d385b0cd7b04f70e51f496054c7d28af2853064982c9625a4fe745ccfe8bf4d690ffe9368867c4","priv":"e59d9190fa1f4f5b37842807ec8c886c9850c7946520f6fc764c232222500f9f","pub":"03da97ef93bfdd16433aad5ae6cde252c062a9875063fa3b7ed2615077e4446c34","addr":"4302a5c24f1ef5cbcc1e286f498140769f3fd667"},{"mnemonic":"leg damp bulb final remain off lion fold run buyer help safe","master":"4b64059f74a801c81a66d7ab2e25597a3f3c97fffe760d5ca70a8857fcc5fa55","seed":"24141973b3a7aae69d48656fc4e535d1a2e094d9ae5d6325f54d6288827dd32602b128ef414240fd88c9a72f790f8fef560efc023a6695f133d8b46eed51cb1c","priv":"13e840acfed4b533303974eb1223a9d4fd400902041be3994101ca517aedeb6b","pub":"03ed7c577c28dd6936bff7eba4569d681abf5bd59fb97ba5d793a3f65ad54f8d21","addr":"3e404c844010458e56726cf7d0881a1c4047ffa0"},{"mnemonic":"observe budget library column blade soldier apart panda express frame version coast","master":"dfb6154ae9a50d8853f5fb0fac07d98cdbdf00fc4511f6f940490e48ec1858da","seed":"a16b567cc1e2c96ef202c9d49b9d14cb5ff14c7c514c8e2bfb214a9e6371fb6f4eff3dbee51e7de2e781dbd815d1e76af525d9766504208949475866abe29766","priv":"b16e831a50e39788755684d0b96f9e4f11b9e637d9e43c27cdd5242091c0a8ac","pub":"030ee1b1e2c7afccfe7f667ba52dcef130de06b35655deeb33291ce6118eb0a31a","addr":"c72adab4e3d6d5d8a9a72e36bd2614d0b4b6e78b"},{"mnemonic":"exit pulse poverty scrap relax umbrella rug clump cruise biology magnet area","master":"0d00e0698a0958ab8ac891db675471b3f7a998f4947115313bdbfb189a8d2308","seed":"a2831c38659377da9fcb2b76d62b76a7f23d59083f33f8c6778eabd804331d46f2f0f4e167b013e16b2b6ce066816641b2bcf47dce75522cd3d1e6d9fffdb28b","priv":"d0c7f92739b274899883175525b6443c265c288e0835233428b97f6f912263c4","pub":"03740d02a36387dc52d66d96357240ec0e185007bbb4457b3598d96680de6309ac","addr":"c4dcba01a757bdf253ed47a41a49c996657d7f16"},{"mnemonic":"impact random cancel imitate base purity devote panel vintage group pool twist","master":"ae715a39fbf43bf9d848024d3eb93d9ca4313c384374fbeb3508077a29017462","seed":"da887f0a16dbc3fed38134acb53466bf1c1d18d179c2f857573fd4a43b8e52b16e598306dc199fa2414700b350174ffcbf4508951c765680f4b3dc7255270efd","priv":"512494ad5290d4dbb69d9247e563188a8705dbeab8dc319db39743c319389535","pub":"03a4eb5469006a29621ea5321f35e8ed8d839a9be99be7efb9caf5e5389dc708e6","addr":"4ab6b8d6bdce81c88b093698870645e7a1f92370"},{"mnemonic":"egg usual identify trap involve winter card eternal subject unknown obscure scrub","master":"6b54ed0110635ad73c4439e189e594cadb02f22d84bdbc7b94027edef2658a83","seed":"f23aee9d83ccd474ac819ce7dc8a57cc57ce082f8032c242511ccd96a395ba8c769d07a7115d25b53cee1d12d6a703f1c0204ee152bedaec1b8c15d5d5b78edd","priv":"0f1f52768a3bc3ce2810109ad40da0126ca5527c494b226048382a9513e11be1","pub":"031d08dd21c95576d1a1a028ba2938537d1c604679fc6e59cd13ef08e62e566a4b","addr":"a0c1e6d5d63341a8707be1673a0dc34fc054a14d"},{"mnemonic":"crunch drive cereal switch sketch gym hint fortune install approve device gesture","master":"4b4f8682bfb429ef36e7ea355276981be015fb78b90c50c19665b6804f7954ef","seed":"6ca97b6725834344247fe5dd5fa0d2a20c31130d6b9c60047578181867650f8e734cafab2158f57b64a92c3f77672352dd71d9df03dd6d592a137cd19e67f3c5","priv":"fac29029531fdccaf85476aae13bb3c3c9f0083265fe6d5e6e612386f3be3ec5","pub":"03683e7d7472d8fe91cc67bea096aac18dd00ae858b8912ca9b172207b89639b80","addr":"aced36c9dad879576f5904d67f504e704726a21a"},{"mnemonic":"congress nurse found frog crane toy pact write manual version repair embark","master":"157ac37c0bbc0732a71858377479fe8bb236664322016fdfd62786ae716f9ef1","seed":"8f8269a5211027a2c6480e9a9d910c385c2e772e12cb756802931b169b602d0eb7da4c603b901f55d4f5c5cb67d7fded0b71f5f9120ee1ce08e74c3bee1f745d","priv":"ae12502606695e34c1a97dbf15b70e1637c4d537cdb0a21896cbdb17277181ab","pub":"031077cb5bd6bea01a470524322478cb5997c06fc77d7154c92f3b7273a36c739b","addr":"6ef29aad62d003f9927be9daea218167fe14822f"},{"mnemonic":"verify service fashion camera deposit expect snack memory proud opera flower casual","master":"7df339fc4837633a008a512dfd0ebe4f9a1236f048839025d33c574c4af0cc42","seed":"151551954b5b4719de472d6a96d5222c1eb688c476f190bc263d7370baebd0740e58f2c3fa00e3cb4615389bd306ed994d3da60808d1d08dd005c5292d3038d0","priv":"771fbf2a2c24130bb356f2490ca67799ea8be2d37b3f291323d5e9b079681cbc","pub":"02f6c6d95852798faa803021107d6a12d56bedcfbccb8110fee698b800931aa2dd","addr":"00b958acb44eb87590ec60f63bf352ec8248fecb"},{"mnemonic":"artist gaze ginger just pride royal strong absent wash figure adapt decide","master":"ddebae65962a513c384bd902b230fdb48f6315d6645a947d79b63c4d45cb6023","seed":"8f7914ef479cab13a658b773db99f56a3ebc267675e1a91a3b595c2f0616f2793cb862cf6038858d363576f994c28c630eaa54299480f168f05d7564261a2693","priv":"b416f93bfe3495ae2ea2dfcae8e587bf19650ee08194962b43ff97deb85c1bcd","pub":"03c12fd1c2e653e3990d15b59d64cd3c34f3f248fc2f1d52946fb218d3e94912cc","addr":"06c7ac564ab51a452c3fe76c0cab37541ae1b3ab"},{"mnemonic":"case mandate call napkin cash test ripple bounce page dilemma usage stay","master":"101248d364cc296423da1839cc3d0774ed090bd9e73f55f355963272129cc184","seed":"b5aa29ba3342da94663315038e9b6c2d61acde2e4cd7d08971d79576224d12af8478abe891de819771a6ddee37269a71b13c825f8ea056f7596d301b00a9c0c5","priv":"4b97318dbb30a0b86d6497a97f3138db00d268ac6165a0fb80f5b8e5d714e619","pub":"022487dbfb8e3061c3a342d75ceb25ad9a6acc6b8df0b224f3f521c8105a4036ab","addr":"984ecec7727a1f812b63b6a6899979b36bff2e9e"},{"mnemonic":"neither divorce grocery stadium narrow electric observe that six diagram hero toss","master":"59cb4dd0ccefad583b8c79c8dc1c5e1d1d77149cac9fb26674076287105a0936","seed":"9c5e31547f43116891fba52294c90c80a583c0375ed100d69e2b72e1453b591b1072ac402d24e011ffacfecd2c8fea1c2b1cf93a435996df42e1c8b19aaa3fb2","priv":"f490ea8e2e8011d7f9b9c57d9143606d470ff00bd51ca69a44c2107d7de7123a","pub":"03fe9d9451c9505075629309bca9b361edb59483e417f07a2759aad704143ad778","addr":"65b28d0f6e78c0743903e41e915de6231603eb5d"},{"mnemonic":"van lucky present hobby property front toy document report switch strong say","master":"5517d9a3e2996bdc9e317a447f0506c33dc20c3c36e6565dd8af76ac2a0158e0","seed":"779e44dd0d1401cdd9d84061044158fa4036d66192c5059bb7f33810e776de434e24518477bd4092a0c775bf7801887a72fd94f0d6bb46757ecc3764f8e17e93","priv":"bbb4c89a597315ac9524df42b17498d334d93b8d48f19188f5ed2327fc2800b5","pub":"022e2a217432ce25ef42196530550d177aff02cdf91332e4a86c8d1fc4f34b07e1","addr":"ad5ea6aa0d47a084f1d01c547165eb51d067871b"},{"mnemonic":"swing shell april silk tenant swim clown beyond under tool envelope private","master":"bee0c171d74d809a83d0a7f70ec1d8ef320efd80541127c9e3b2dca85e344ece","seed":"da69d4582287e64756d8bc49979952716991ebc878764f7c8f93649f5b721c35f5496e7e81f5f21cc987315f53a747911363a58790eade4c43c7c24911cf8b89","priv":"a6c35d6f727685419b4c3717f0dc31d33340536319963186c64f18932bb3d921","pub":"023465c95f48753fd4546f6be7b3c5959ac2de74445c2352e14d0c57b058ab0ae6","addr":"7959735517d011fc100b56f25b6115982d2299e3"},{"mnemonic":"carpet sketch depart tenant immense sock because caught close canoe insect crack","master":"ab35e8379ede1615b44bf8b1a8dbcc3ce88b6d6d0980cd63ea4f783340a1c372","seed":"379373dd202ad95fca8046f17a5f989268cbacd2697a02ee5efc2f022f9019580e7fc452c551d97c9aa2247c566313e454768e38d6585ad9561a09710a279ef2","priv":"a7165228a05945d4b01a1ad12911666504f8fea8c8819df414995bc1eaa9068f","pub":"025a7afe792c05bb3d94c7996bf5ce1fbb02bbf716593b2049f6e42a0328311f2b","addr":"1fe2d6a254c104cc38f1466355501890d370b30b"},{"mnemonic":"world sweet evolve club speed desk double verify gentle account youth column","master":"b2309b5c1e0a5c590859c5ec3bad4b94aaee3e2e7ef21080cfe0780617eff220","seed":"efa3dba671c0c4e35072d8958b4d7af280d8e20d3b6752b34a6b1e561d0f44bfa7829a5d540b52e02dc1b06735dfe18b2073a784aa307253dad71b9146024bda","priv":"a2a6288f9feff9b408fd6b056309dcde5cbc40489afb85413202443d7c283466","pub":"0307429d4171f929f79c8532cec5970c17d6f92ae014e14d99fb1f8fbc0637c9e5","addr":"1ae1b848027b0d1276a85ec2946bb7096755017a"},{"mnemonic":"patch cave blush omit calm habit autumn load focus tobacco barely switch","master":"972320ebeadc9ce9da0a447dd469c95bdcbbda09e6887f64dc9c6fcb8d6c91ac","seed":"dedd6610c32b2e5a3fb93de12f758d92041b0d1aee0bb2626dc0e6e8cebb8ecfdf87e25dcdc4f9646f2e37fcc071ff4137d914df7133a6e22fe8669ccfa7cbb7","priv":"17cfca7dd65152e0a3c77a2bf4a15b0a99b7e889dda49174acefc06d390bb255","pub":"0286d1e4ac0c7df1e1e6ebbe1b7aea5f0e0cef8ff3336a1c2f61c80d135a382234","addr":"b184ce8d18aa006e93ce901fbe879d3d8d6e6417"},{"mnemonic":"extend install wolf token genuine mother swift pencil scrub annual wealth hip","master":"4ef0a071d94253f9a60bffa7443918f43865f131a579ccf93d2ee16a518af2b8","seed":"f66926e6837305237316d7a69fbe18911f73a4f98278a2f6e6b1a8e06adfc1d189875ca401387b74c0198741619030187368c2a58e6b844aacd45fe89fcb6a93","priv":"f4c00a2ce7e9217e5e5e3f5398114cfde57f25833e920f14989e450645087bc1","pub":"02fb09ad3c161919060141c50b70c144cb991a553a57b25b2688e56ad163c3bcb1","addr":"556ed45bf7463ad502fc2fc07ac05fc073badbec"},{"mnemonic":"canal pink undo modify apart bachelor movie coach december exclude scale despair","master":"ebef42622df1bc744290f0c5d930aeefe2764dca7efba491b78ec958a5acc171","seed":"056347f396399c75761136da001671c6097fe21adcc920952db079afa5debb60d1c3612742d96af16de34a44c792da1ad995757e6a25e62953116d3016639c86","priv":"6a83065d2777eb4674e19f33a08b46c44753cce58902a41cdc3b8e3f0883050b","pub":"03a928c2c2aafeedb59d1588a86c42428b70171eed39b94f68f2097d9cdaa4c283","addr":"28053af43e4d7e35b32f9d174bd205206f94028a"},{"mnemonic":"brisk clip brass tunnel credit hip clock deputy dial hole song soda","master":"965fc6288cf02a8aa3081de292a513fd7b23fd010d373045e2a5cb37f38b2393","seed":"553cbc6a6599410913b6304461c1cc8b4a2c09c8bc1091c231d7167d27892ffb84b89c3c001ad40d4740d97224062c974ab01ea2dedfe1a3322f1a041964fb46","priv":"c9fe5b03317f7e7496f8824f24b782c09b5b801b3ba7a08d5bab508005f88aea","pub":"02ecf7641a4b3436c91ff3fe5b9f700cecf8cc3769945c665ff6129f6a60e77a7c","addr":"e578b715e9e84da6beac28486ed9492bea16435f"},{"mnemonic":"senior example flock banner pumpkin salt silk soda funny input puzzle ready","master":"7b0b3ad8cec24080ad6fcb9b1ba4b745820543666d362a188f4aafa52cddbfad","seed":"367a466ca4069c50df5571db657cf4394e843973e5801db4d7072c51453ce04b574b01e07ee8ef0836448f7fa220863e6cc7e6180618efaa3868e78b807b4b74","priv":"31f5e11528a372d7948cbdfb0519f974168d568128e441a5840a02c1ebc71f50","pub":"03b507120d46abde399656100fb664c736a2476a588f2c893d4be9a5f9acb0460a","addr":"941deb14e567c6d60446fe5767a0bb780be7fd0b"},{"mnemonic":"say leg next pelican brand topple blame plate snow month van cherry","master":"82a9d68ae21ace7c2e5d7d8ff58e4f0cc3c7e5db8031d4f83008d06088c477dc","seed":"69956cc226c79bca915b24c65112962205eeb161b79f66246b493d53eb7e1dc56f9dbe475d9650c0e72d7befc0b899f75f7bb3b3c100f7d6128b21cb4cd88396","priv":"cc512c35a0edcc0efc15ca9659bb536b3957420f00b32cd9e3a0d0e1cad5360a","pub":"03c4c82df36b093deca7eabe03ede5c5ed3639dd37ce8598ab8a6342b86142b07a","addr":"d0ae8f85e8c95b4906de99ed528331173f251e85"},{"mnemonic":"develop odor front thank mobile subject then cupboard human high crumble rabbit","master":"73704bde13f4867719c71fac5b37f16f30b69581a53e7f09118ed1368610b1c9","seed":"88f30341bc3ab214f1aaf379a8fbe498825029793d4ed2b50d12ef666fe45f06e39f68583c4cea8ca6a88e5ea62d8aacb499da4814fe346e020a78bc636a3cbb","priv":"53f91608a0b1825b05ae68992f97fbec8dd7adf877c085d1f30981d6f5262653","pub":"025f5e6339f5b651038512ddb5073eaf10c962f6e82bd2bd94c117cd4cf4de4fc6","addr":"d24cd460bc42f5222b18d5632d53163b648c982c"},{"mnemonic":"toward weasel copper blush mammal window weekend exhibit pizza element impulse valley","master":"3fba4e4716bc0b0f99f44a2bc7df34bdf60bbc5c1e2b76ff4295f21428465dd4","seed":"8051dd06bf13a9b79d82138ee3e5cd3e417c6d203ad0f6ceb81f38890d4c18b56d29c93ba76591c499c9cbcce1bdd205b26ab792d506d4903d90104a226422e2","priv":"0379555ca3e00311dc6949659afba1cf6019ab5690f14fe8368f0fd07b90a44d","pub":"032446f977ee3324c946b0d6409a4b7401becffbfcb868827e6639cb686bb2140f","addr":"87bf7d0cff36c282a9140657a4420f67b7b7433e"},{"mnemonic":"lift piece elevator remain horse virtual fragile dynamic whip lecture perfect fine","master":"bd16309fe9a58eb87ddf1b8338ad0ffe4b39706c4d568cfdf6f5ddb79064ecdf","seed":"8433dee7ff8aa73f785d23b09d8ce7f4e1e5cbcc7c20133d81f87c1d47b94f733631d5406c01f756ba7bbfbdca900eb2fa03f6b0a0bc1f06b9f3c3c9ea4d6d61","priv":"c4ce940b7e5cc0606f023daa3dd724d773e886d48af58c785fef7605b2524a16","pub":"03c89852febcb140ba3d5e9c95ba6ee843666ccaa69492ede61dec94e4e6f73949","addr":"3c04769875dca7cb3c6faddbf1960e1738118d7e"},{"mnemonic":"dash output lesson topic butter run ancient claw enlist approve chief observe","master":"8d37dc9da62db3dab7a0f209d8997dab75793704d6c18056f02b6768db414121","seed":"6ca57fc186a6eddbb0e8ac6dea4c1eb5d8361ca08d7b909a8e863284b38180cf8ddd2d9590f7611a5cb80bf1abcb679adde5646e69f62208557ab1a37e80394c","priv":"db5742d8734235964645a018fc4cead9402a113a60de0d7f55ab3816c9780e8e","pub":"03710b31603eef3e10abe51c57c62818ae65fc7f0aa4a91cba5f178a0cbdb313cb","addr":"742d17ad66f51524f28deadb3366859f14cf02ff"},{"mnemonic":"blouse maid inflict jungle yellow believe arrange cruise seat dust endless benefit","master":"d13daac6580c68186cb049fbb63c05bf2282919865c4018acd8446828dbf07fd","seed":"5b4132806e12b669813f1ab295ec58fc472fdb46769ea7181faf6e6b48f3cf4d8280e8ed5951306ed71b40d016afa3ecb71476a23f455ab6e41233ec2929ff0e","priv":"a8b701c1abda145e723d92fb246b692e44693704b52198ba33128267bba63155","pub":"032c532be31e8394d98571f3623372abafce8bdd0ef02c198544d0dc6a6fbc3cf4","addr":"4675d51ea6dddfd9b296532f3f2c101229cee094"},{"mnemonic":"only enlist indicate practice safe romance orient gallery cousin silk eager what","master":"2bee5e0de945af3aed16b2a06423d3447dc0c91af3ab8fb20b4fc0dfdd74bad6","seed":"92a6a62d9b145dfac6f66b7dbdc7bcd7b9ac10163541cb95e18e77742e3f2ce1773d74b0b290e40ecda2aff147bf81fa8997eb02668891a68912cf42cc666fc4","priv":"6a8e812a13716f00c5139220f1afc9a7ac584ed7553fbe8a13c50add54e5446c","pub":"0341a641547fc87d6a44abe879aef7b9f7c36e3491f221f667d10c568eee0fe99f","addr":"0fbd95b59a63b2a4238d6703ff49746a5950db8b"},{"mnemonic":"oppose fan kit prosper message pass fiction machine duty antenna planet ribbon","master":"6464d66007d3609d21971ad05877316fd8fc73a4b61d971676fcbdd32eec832f","seed":"36f65f329a478fc6cf1c9be171f9de9255affd1434ccc3420660a156b6cc0a85a10d5eb1547bdb5849325f5972b332afea7973449dee8a72db256479301337d4","priv":"94c741202799e22867b197c900c11e25855196e9e10e2f74f1939aefb7ddb233","pub":"020b86916271d84b2ea8f8b83ffded3b8f2bfbcb4ac17da7fd59c9ede27c00926a","addr":"d26eefcc75de9069e99c2e98699823b45effa9d9"},{"mnemonic":"acid summer coach step inform jewel secret tornado abuse kit shell guide","master":"4a10d5e6783e00d6f3453d8948dc5b39776de5690775aaa0a8429b2f11679ea0","seed":"46c698780417975feae4b6607e7728a00600e0e8e225d5d8f36ca076521238761c5b910759f70498e7dbda012d4325f3fe81011ca762c2eaa06649a18b79fc74","priv":"7d6a286693fdf1e51c26a64e5e5f8763b328934540b18001898537afa49e8b1c","pub":"0319013f6935be2eea7cdfe0544145708d24ffe9742a64b1a2d22f24bc5e380bf0","addr":"d53d22924ffcad0359a177345c32723e6260c7c4"},{"mnemonic":"general shed quick sea amused piece air infant jeans page eternal lens","master":"7b435a6cead581f339c1008061cadc687c40156312a8201c823158a6028cdb93","seed":"0843ac840c79c9c7dd85cadcea3496bc7a376592b07d233c35bdcfdd09725eff59f0ebc1d0cf255035ab5c7344adc3581dc543b134a5e70eca410b46596ee8c5","priv":"e61236f6e4557b45a6e39058b8606b7e3041de297cb0d39ad06c2e5414199d78","pub":"0241be261330b87c2388ab4077fbd4fab3a66e7d039d3ce4faad319c42b8e886e6","addr":"29777a50646b5f08eb7a428805a9778851d3116d"},{"mnemonic":"view hood trigger weapon dress roast load artefact dumb biology sadness receive","master":"a619455307c5edc87edfda01059cfdbb6c356e9f639b16b80b78e2421f1989c0","seed":"d89adefef230e418d7462194e5e1a817a0ade01435763ac5030ffe94fcf4b1f9d8a06090ff8a742d22d7a78e4a6392e35e8c318f5d0e495d0f8773ff126ab56c","priv":"1f9c2085c35b5fbf1a096174e7f11537b4f6d6327018dbf3b3311488865e5135","pub":"0208e02b8410833b43ab7674e25efd7081d6516aada029588f72a5478fa5c0aa20","addr":"cf4138b64094d8a9f58cb9068305a69ac50c4f0a"},{"mnemonic":"salon diary era brain chat panel design lawsuit behind practice please budget","master":"fce0a096c14774cc4bb44a4e9c65cf075a2ef5eebf96f08cb684455218f4dbe1","seed":"b154f70e78908ca26852b659a6f6252d83f3bbc4261cb1b9faa4ea80dbf1feb27958164163bf7ad82de0ff8b1af07c60f23b376910a24608c8af4b88aa0065ec","priv":"156d45c8db9bb83613334020e9b9486eafe16c1341aa05f4ed2095ff5a11dd66","pub":"0389bab1175f1cdd60a54828f8684c99c603d6b877597d1ab0349ce6a974fb9e68","addr":"f60cdc064ba139ed5ddcb6cfdf6c89ebdc378962"},{"mnemonic":"text horror panda eight mention victory wonder orange error few you illegal","master":"fd6c8375c6c3458be159f4c2fea8d25688163c7d306e17aa2dc32951eec2342d","seed":"ff314a8722d3291744c0ba07d569373771357795f72307366b0ee0c84b71ebd60a54d6f1c1c974bad1150e85415658f5d30fe76062d80468786fcc20ee8ee903","priv":"943fb32cbdd79c2e34ea72a9c31cddc3ebfb1a353808e471b77f54cd108f487c","pub":"02d17d74fcab59fac7d1cbea2838d5db3ecb1c24219b0b086ea1ea69559b8c2099","addr":"996916a8fe8dd544c1906a0afe4b48df43abb409"},{"mnemonic":"apart beach sibling debris chat hope toy happy bean same auction brother","master":"9eb93023f619ad35b6aba1051b791dbde9618bb74059632813b4e0f72b16c773","seed":"4fa270abbc1443fe7f593af42da0b40c17773eb7b9efc09c621b59424f84be65ed1ac755b88d71632a5a384c6dd679887c021dd91aa06fd9547f5c52bac8618f","priv":"3adc47b4297474a18744bf61f18e3030bbf58d68eccd4b0f9a207fc513edb851","pub":"037f6fe821009e2e043e66b167e7708d9534a543391b3ea17abf449f2807931462","addr":"6b9668671f23172dd08382e8db996dc9df687f80"},{"mnemonic":"tag bright bitter hedgehog stable level outside alter uncle hold have voice","master":"63157c3bb0a525d611de7539718f3b8de9f4f7a61bc9884d2f03ae0d30e7c5e7","seed":"e40b20a383e582f304c7feb315ae1bb405e9a5e12797706042d82918a19cada05fd28ca8615d929dfe7ea331d588ae3506cc3cae09f560bc13d544607e075ba9","priv":"8675ee046186c61b46576c02a8a7e5dea1d307667ceba7f6a56bca72fcd5452a","pub":"03654985961e5509210a31d1f54b15b37ff975717ef1f5ea7c2aafc76ced1b6326","addr":"972e9f2582e7ed35767b1b23ee73af4daeaf0b3e"},{"mnemonic":"wave fiction coral polar enough gauge whale magnet science second squirrel answer","master":"e2f288c51ea9bb3befc3245bc0739998db6199615869b4f27db9b613aa443549","seed":"2d9a178a3292c3f3987c35d44a3fdef2d849630ff49343bc5c3456a6701310c56cb0688d7a4bb7c3d58c40472d8a71121fb54f0108f6d682c648694f9ee85aa8","priv":"4a4d6db92c8cae67cb80b4f8fc7e63c94d3ce9ea67026c2544325c7c14c8318a","pub":"023cca73403af0fa0a0faba0545c21472996381917db6e481de9fc0de210dd4458","addr":"fdf8fbd1473714cc6dbac873822a7e0c7ffee153"},{"mnemonic":"process visa stuff pulse shop ability test aspect royal pipe protect fiscal","master":"742d13461d14c18707e2828f69b8deae3e13a9d6c90895993a788bf51f5f8eff","seed":"fc0ffaec77037a17923401aea05d7e37f09d2e7d35e9ad26a5dfa3de6e5da7c4b8c1d16e5ff6ca18570b069e1e8e49ef9ef475665e00cf189eef652e40d3553c","priv":"ef5da20d14c6d948536faf4ebfec5f11e430795986086371afb5a239befc3410","pub":"03a03b2dfd694a9d95ce1fd0f9c97f3db35c02aa001d26dc313c269f8a97bc1688","addr":"0d76c54b8af88721dcc4968dbe47607d7040d3cf"},{"mnemonic":"jar draft slab quarter during hawk grass monkey mandate prosper hour fortune","master":"98e2ccbe3470de355e090d69247d6506ee9bf82473d83fb98c20506543dc4fa7","seed":"e6bae0e46c8e66bbaedd465ed2669f9ca5b2bb68d829d237a1846763129932588a1aa4e69979a4eb3f73010d7c093b20a542efa2fddeaa00032abb847cc7bffd","priv":"9d1e402404867001cb24a3f501b676effb69865045e6ac2b0fcfdc34f9df494e","pub":"03f0bc42295a11b4ccf18b44659cb6d0e0eca3d2034c98f485f5ae43e07a82d90d","addr":"e1c21227bfe3c09188066ae189c7d499d855a600"},{"mnemonic":"camp vocal absent ostrich sleep version puzzle afraid execute clog eyebrow tissue","master":"fdabda4c563e3d7caec47b62f4f06ca53015f98b498676116e7b3df18a4b4412","seed":"b752500a4695f6cd66edb640021b2f590e85f4df2af298388f042cf7b665f0d6e643827bf705d3d1d9786e64bb5e184fb16e270ebffe0ce4ff7f37c285d28db0","priv":"32ade388afcf551e5b9195941ee3d290a39ab041dc9a2b748cc36c53cd43061e","pub":"0346e927eeb5549f8f38fa6280c0932947ef78f63b55410e872e0bf6988e64d03a","addr":"462344dcf5eb679f62d6470927d227365b208524"},{"mnemonic":"kite slogan all win burden staff actual oak cave bamboo advance uniform","master":"43888096d253b010da1f0369f75bc0d6a3b5f14dfbe5bccf7c8fe9bd78242205","seed":"b770074f2868e3aa42bfb76b444f782e4a109f2ed51677a79a69bda83dbdbff3a64b9ee163c57859f143a726d10aa73b223f0cdcdde6497fb95e0fc4a810f583","priv":"26533617dd8d7399f399d59f0f8a50c798668f04f44b52bf50728f20959c68e1","pub":"035ce21f82a71a8580d4bff49e520ab9815ac4d5b6cdcf6eaafefa4457dd9dea27","addr":"178918f829f9cd67d701c9a64b5bfba373a7c820"},{"mnemonic":"bind fire final soon dilemma analyst train ecology say drive slot bacon","master":"9aaeaa7f7a7deb8a976783f523695466b78117462804405e200ad1677e547125","seed":"155349996ca5a6fadb151c9ec425ca1e39df10509a8577f6e63096681c13b3980285777e515176feb7e4aba096b4d9d81a26b4d3477409432629a862669bef40","priv":"a890f151c33c87340a9021d3186c4df062822a3088fb7447bb419bbe5dbeb53f","pub":"0253d42cb2ab28f7fcdb2011e547dc88902e1e4d588e9261aff0869b118bcd4dc1","addr":"19b05c71780f27ec2e44ecab4c426108ea5a0f6c"},{"mnemonic":"image wool rug little visa embark poverty shop shield parent odor farm","master":"c68aae9896977ce21f5f547a4d0ea9995c9641c2a5f2cf89fd5a804485ec0e23","seed":"5c6885f90dfc1286f17b0079ed90dfc3974ce6b60d4193784b9668ec93725328ee5c0d027df1d551541a62fe2d87cc19cbdeed9a235a4510b738930dd3eb4eaf","priv":"d807cdd58fa84e4bda7fa998c8bbea12b7ecb5147c5edf841dcbce2c8663be43","pub":"0259b24a008d6ff4ce4d589e081ff100c28c3f8eb5440c8643257881f10da3658b","addr":"a20d7d609e6b2c855b9da18dea5f7ab3d091aee8"},{"mnemonic":"enrich soup all neither easily combine police ordinary review room keep swarm","master":"8265329602cac11df40567d54c8d4759bd9013c7a325c3d628b81640e95af3ce","seed":"3998bb700715a777bab05afae33a6e6553af17bf8c35eb67c7d4afcc38d6f35875c12f8602f381f797157102334f9c01c483f8fb41abb5f439ebefb76fe260c7","priv":"8956ffbb87e45ba0ac8f4142e179e6f934ca9b88d754fd5347c340a598878088","pub":"02af92f546047de11b15fb4a4c13c77ec6034248b84835f421826a44a68477fec6","addr":"7a6dbb8c88319d3076eb0b387dd2a9e4209b3229"},{"mnemonic":"tribe unfair track nephew erosion spike machine exist wine banner horn document","master":"c8e67f2accc6f9d543e1619dfda891664d349f11eae5617d32a9132c015b964a","seed":"ee1bddbc1eded07dbaf52feac014380400de9e006bbbb74f0c12095b381ba01a696ee3c3f62eaf4324e49b397755cef44667762ec46321f5762ef0e269dc9cc2","priv":"4caaf1ce46e2a6bf8e058fbf063da8683aaea07af831456522ae501d4d09d517","pub":"03df708621a45e5d5fa1108caebb51c513ed1616529aa6f89e3442a840aa37d73a","addr":"4d5e8ec1737a693fb2820994f4dd69291c5224d9"},{"mnemonic":"assume wet effort damp similar original salon aunt grant peasant fatal toast","master":"ea31d3203ecc33935024caac7c319223ff0f4b694cf011538521b318716cbdb3","seed":"11b227c8cf099bde463f72b505add695254eb9fc4714231e09e337f1499791ee2441bd5a148862265b6b5414d47f767398fa97a392a82a0c70648b4a52c1c2a7","priv":"f96a9c148945df0490611dfd06ca16f485a153e96857d746de0f2817cd2412c9","pub":"02b7b1c5e504b37104fd92465cdfda7261a60aad61b7b19b040d074fd07ec8ea39","addr":"036687e670428aab8b8057483c02ca0ea8dcc8eb"},{"mnemonic":"celery inspire ritual apart bring pause sugar monkey leaf tunnel minute alarm","master":"fd42c88307af74bce721f71af73cdc15eba0a186923fb9ff122d86597c1578ee","seed":"46042a350e5932c11cf735b60382d9a331a21f199cc484cdb9df4d8b9be0400c94d58ba1bc4d41826e605c625c7301bbc61e71f3da650d2928e83e07de6a9097","priv":"23c351e14d35d01f62da3cab73dacdc1c0ca052a76a41b58ae9d5c0a242e5fed","pub":"027ef3a78f366db4396cf1da6d124e31b254e90ad0c517267fb5a20a0f4034fc93","addr":"64a202ed14304b5f143d5d10a08167decc68fc53"},{"mnemonic":"text blanket lake damp doll guilt select torch midnight tumble toast dove","master":"c9653205120cceaf6cc768674a6389ee961403a4364e96220134acceed105299","seed":"79d5619f5dfeedd623bfdcd7d201f58ba55a2fbfd0424f32b9a220b4a39cd048e5cc82686e578b420cc35924e8fa31f1a4a29307dcedb35a4c69567da300b07f","priv":"7a7205d096a658f41be1d4d6b8a8644bf370c34a10a55f4a63ce1117d71715e6","pub":"029b2f32b98281d644232c4d603aaf89a98083edbc75b61f8aa5ad2c7ca910079d","addr":"ee416c1d1471a6d06b755fc92535f0bf1a2e3f4b"},{"mnemonic":"crime level shadow chronic rotate era reunion fossil boat shrug patient artefact","master":"fe8df8e3413387b50476e0ae97fe9f3851d5645f90b0bcf0b47b18d16387c057","seed":"0be8bda7509b72cc2d39c38609510fee439dc03600883e39f596cfc30cc2f48dbf14860ca33b7b7dd6f5f41f3d2fa71d20fe3995a698599605c5ea23b95917ce","priv":"4462e7a144223c97450b5d6728c6d017ed953490f7e762563993fa309152ddb0","pub":"0278a9fcb45bb02944c9cff032c013168943c6e0193c6ba6299af4397e8113a340","addr":"a925672e895976c8783d48180cedd09b2edd6108"},{"mnemonic":"chest flat tissue cousin defense ramp burst once rocket time super retreat","master":"7a8c847ca8357ab65fe99b5cca5d0b70bc8da05adc747c4c2f201fa1e22d753b","seed":"96003a7547f32ae6d8e5ce1bfbd5e580cc8c81d3eca4397e5e1453824b672a6d966d97fdd462ee8c0553d832c28c42fe61e78f01d056b2952a6589273ad57514","priv":"e4847fb09c9438d765da59b51c3dd825726ade929294007f9ccab300c100a2a6","pub":"032ebdaeaa817d8b8bd206839e18d17a85bc44ff4d7f0a5367c4f48098b511b43d","addr":"449402b089274c0b78b40e6f45e8297badfc1bc1"},{"mnemonic":"elegant dune all subject country diet flag universe gap ability hello torch","master":"fba87eced090b1d991c077467db81d22e2691f9b15ea2e8ccf03a51a556ee13e","seed":"1f1cd5b090411b96728a6959a4639e3b2bd68d4ea5c6ceb801a5849af109650237d2a6727ac80e7b317c625faa593d7a8caefae3ffbb55f110bd66672cf516e5","priv":"31cf4c4c7e75e35e16e01071e2db66a51758c8cc2b5df3377462046e4d87f3d2","pub":"03722bc559c95cdd7baf08a6965a47a7762fb974a854d290295bd853f6be0a83cb","addr":"b7f0dfb1c5136bd9bc267e9c7b33c047d6a1429e"},{"mnemonic":"give citizen chief eagle horse alien below flip vanish eye sniff bus","master":"c3dc631ea1b0226bfa3572fe9b95d72d08bd160cdd5fbc2fc96866adaa49a431","seed":"196d5c0aa7839623842c51f2e5593695ddb596bcd839c70af2940e8d00f31dd68b45876ae7aeefc6032e8b939b4feb8114ce9c403e4b83e28a49ea69a97360ca","priv":"9fbb966c19808bb2b7d07c420f4aa59f7a41cce08499c4da2bc216d857ce86d0","pub":"02650905aba484a16f7c1a2b1bcd0ed4f16f45d1770cce32ed127bc046d5f2c3e0","addr":"1441b38310ffb1135c2c48269746894accf627a0"},{"mnemonic":"gym term crawl benefit kite various pepper noble into slim try then","master":"e5826174e32bce315c7baa21ca97c613b4eb095d74651867671afd3848343668","seed":"198b6d6de96c726477cf8cdde784fc43a89dd46ee8fea27933ab8daf09826ad0d7bdaa0c50f8d5c574f6f2e6ef7adabd9c2382feaae061c9cb10a3ba22c5dcac","priv":"ec23afe15c13d5f0c86a47b18ca81761976442cd7c07975c88d6ad475771694f","pub":"0331ddb4db50ff58ac1709986111cbacada08344bab6210da4a2f23b0c3208e100","addr":"625e5b098af6c98677a9a2cba960e84c11dfcee1"},{"mnemonic":"pause web there legal eight plug wheat convince adapt radar rely inquiry","master":"b13d46f4a0c6ef2cac56cb9c522dc35b8d02f4ed4f09f524d206e9ea6e6e6082","seed":"5f34196fb26a7bf0a9063284f702d934c03eb2ac10f3dc230a999e9566d3561b9dc0a61d199e7d9642b06474c08f9e12e618ac5cc1d805ec9cb9489d460f377f","priv":"b410cd330abf2a25f36b24fcbf72f73e5c62786cb5c0c24fdbc3cdf6ceb892f6","pub":"03755fa255c3f111f778c270f991a5cc0fc24c0068d78355ce340258aa7a3b81ce","addr":"170438465b203b844f98cf54b49cdf17094afd80"},{"mnemonic":"thought morning dad seat payment ball club goat man urge forget remain","master":"af52a1f224909be5cd5e7be0b960a995c1d25652cc0c6791060b98e1aab4ca9e","seed":"1e9bd47b5411fcdb8145b9eb1e7092eb218774c85da6efa3756e9a55e5ddc2153eeb568139c638af44cfe6cdc2a570451ed68c801dc2ff726b45ed43e8fd0691","priv":"5e42b1c08965620e1e647e89fe87c9079060121f5a0b65a5ca8cc462fdd13b20","pub":"03a7ca8e9445a67a6884f58e0e79b1571b34b90dad6df4c0b8dfd103e500bcb20d","addr":"f44393294c3f1369012836ab432386f1af2cce44"},{"mnemonic":"twenty memory ten own runway grocery polar dog curious program gap country","master":"f08104e81f54a7bdb17ee647c06009667d4d1ac6efe286495bcf2327c229adcd","seed":"10d3111f871ce9bda4a790e148657f6dae8586d0d80379d40e56cbf180876ef7ea5f2a66f006a8a8a46c7de99a4e4f8f5fa4cd1a3756a38a71971298af917d21","priv":"db3cc8657599d42858ee1f1a7480e68ee8cfecc0fbcca01556c1fe5e8f3a0025","pub":"02add58efeceddf43db9f3d12b54dcc1f1369f152d427a7ad5e3c8de5de23a16e3","addr":"eb30fff2557ca87addcffc02d3a237fd28511799"},{"mnemonic":"elevator sock worry budget skull bitter faith taste skill physical mass heavy","master":"bb2b406a20bc8b38709251d1cabf4631428e2ac053154db69e2f1c6d236c4716","seed":"71fd4f050ec95c4147aed32ea34bc065e67635315b1077a0e9453d883b0a4519015ebd5de2ad0f2a628c20881567532f3b679541e23892eca14d5ebf4456a8b0","priv":"ae56d8b12dd0cc788ec4d5eed7153b108aad7606d2f3653ba5c61bae06dd1cf2","pub":"0347f3d0ed7552ac8d667036f4403911b7a98f71cc1730223e74fee4194d0aeebf","addr":"98198786f5e46f72ac47e88168ede1378404ee70"},{"mnemonic":"message power uncle glimpse repair coin wasp flower alpha claim federal tourist","master":"28f596f188bfd9a0f1ba2729260fc20ecc1c1b67a20bc8a4f7bc0e810a625ec5","seed":"5a23114eb877a016fcbc82146957d2b9880ac79582776fecad126fd6b5aa81343cdc69c46f29ad17e19411f0f4e78817338a9fd39a72efcbad31ab965f8782ea","priv":"1376caa21630e355fe38924afbacded452c9552eafbd5b60dbf090fedae3d793","pub":"02713f022ea80f4807af048cd254ed4dc5a1276c21e4a7436306f83731843a5402","addr":"8a1cdab91bb44b089a51f0a736e914a37cdf20e0"},{"mnemonic":"infant walk right wave helmet punch alone path since output fashion isolate","master":"0de852a741c097122fccfc397d9ec55223ec1a6ef395c1848097a45aa6a4f0c5","seed":"d1fbf777f64ac5ab0375876dab5e934794782c73e84dfcb19a291a6a083d6aa6d0d3de7e8c804a8c02875ea5fa54a06159538f98f9174bc6cf69ec94e3bc682c","priv":"0fa223b1f217baf7a296e483ded5e6ee97facd5841fb85c78b5ecc4db7681838","pub":"0276da67ef9f098a2ee3a3a18d4ca17705448694f895c6ffc97959fd6507e904cc","addr":"02aacee8fb5e56f4b39fcbf7253b7a1302b0d8d6"},{"mnemonic":"type squeeze vocal monkey baby scale behind knife cherry luggage struggle what","master":"1e156273aae1d8c0b58558726d2f19924b1d06659adbe3539134f58a8a1ff82a","seed":"333847666190d4b5c9535920c47a6f68c586aa3f587cb7349542c0a30950f7208b3467ed437cd815007b11a4326f20b34f45335ba64cf9bcf17ef71aa10b9b86","priv":"c307afbc58b3561c7d276502e1b81de8b01c196bbdc1ccbde5855e00707f58ca","pub":"031a16f0dfd054f5d97233ce07cf647ad598a84177baa82d2f89a7f23cd0f2a0d7","addr":"3b1d109cab9545dbbe82631dd4f903b43cd79bcd"},{"mnemonic":"elder shallow catch anchor slice hundred kangaroo stereo myth proud clarify open","master":"babfd17c1c9647175a7b2739eb700c3385be4948f97d1dcd50cd17fbd605d6d2","seed":"eeb063599bfcd2520f7f07b3eb885cb83953ef9931926db8d1e76b689954ca902c6edb785af6d579ffe89f9253f5864cf21d3f7373986a6c1259e4bd0bd16437","priv":"652f38771bbddf64d2040c1300c317c42739f50839b604cc8f34e050b4590a95","pub":"02608acfabfda5579dae5d9efd4a191925864aa656e55b039da9736a874d46b8cc","addr":"f14a9e2a34c1cd6b95fdd473ddd799429fc03def"},{"mnemonic":"screen slim squirrel fox stairs still close club day satisfy either sentence","master":"a0101753f4e05c8ab9bfb6224120ef9c1f99ebaebc31c5aae114f68387676f5a","seed":"c1ec85f49b1928ed7ac6dc781703a66ef39692ba39f5296d9da33f93fd68cd85b0eb57cfb6ea115ceba67df15e4d835d813e3bbeea0363ef513220b98768316e","priv":"91af59d9bb62c2a2f0bf1b5c8729f2be88cc82e141fa045e59748f2b156b9a03","pub":"03a76d83455b42964c021906265a4e006d2c81555c8591a641ac0c495cd0d05cdf","addr":"093ad2a9be7153222002d94eefadef04ca7ea811"},{"mnemonic":"insect deer physical dog aunt metal super soda antenna broken undo athlete","master":"d3a4a655aafd0dd18e196b2f4e57bd4b1d27fe521f9312104ab75ac92ad92e62","seed":"9975a73239f3e2543108bec6d75c5c9a24261c9b2ffd0e088f6bc8369804b70ce99ddbced3c4cc2e1cd955be824f5d881af09e5ed403d7da2a533c73d9d82df8","priv":"0a313ab091f7fda44e92ba2482b8fe1294646bc9d27865bfb34ccd702376328e","pub":"02ff6999ead46c520026b1faa27004851fe1b2295e5f8b79ee1e87b330c45216d5","addr":"e3ba9de7fc81b75eaf4c6ff126b434dfda0a5008"},{"mnemonic":"layer embody trade slice odor deny please small clerk device ceiling right","master":"2b39b4a5aa164609c2734c00c1029534c5d7f3bc6b94268758acb506bb139608","seed":"1bd10cd1d50db3dd8f9e76ecf39b846d3a2aa44be383868921b155c03ed3485d52236c49783f5334c60e473458be3b3f588b9ac3e814d144128d96fbc002393a","priv":"5953e09dbaa56a12eb5e69231835924c0e38d5c322a43c354152a0333f26756a","pub":"02254c4d6976965f7c6122efdd52f65ee9e25b87549789499b72bf5d7213829d04","addr":"603d5b893cc41223eff641fc1a374a3ce97138a7"},{"mnemonic":"token heavy lazy little dry glass riot hobby keen blur wise okay","master":"7d84cf25bd5f7dabbdb7beae83d1fd128390b3a0fbf2d56b44fd34a7e0d11539","seed":"8f144bce2e5c73f44e5dd62ef4695c6e3457ddc37f64d1552e5b46a771120ccac23cd592b27a135c3593f8f21eff22625ca7bae8581f4f8ed223e813f5d98a6d","priv":"37d2c3993b275606241307c7b2339e304180555df260f18f524abcc75abfb0f3","pub":"02aa996bf4d889c9b37aacbd07d8ac3ea69e535c065a4b4258844b10c2a08eab8d","addr":"4a3860dc280c75a00382f3d8f11cfa01fda90188"},{"mnemonic":"tray drink color across armor spawn vast skin debate huge surround play","master":"e0cb1eb09b82bcd37fa63260e49222cf13b0b07cc1568aeb8849b538bda65a1f","seed":"faab52fca3060d1903e861706b57ca50ca71befd2d5363031128235cbb80e53ec943362f2288fcd1c850e94cf4e7c38029dff1880dc3f8c8bd440b14ed15fd01","priv":"747aaf84f110aefb34026ca0492894ccb8e0d1b34c5b0f9a9027320289914b52","pub":"022d3e35a5f51a6be1d0aff686e66e2fe282e42a51044ddca65b8a7659b6386f3c","addr":"43057d3d99231163cca42fe248b9d350ad7ae146"},{"mnemonic":"ring act drill burden sunny someone riot spawn uncover sauce today jeans","master":"676a5a20f35054b4f7ceb22d38226df0b2fa192b6bbdce9a96fba2b51845322d","seed":"979a3caac9130fab128a59243447f5add05251ad385f0c0ecca60920cc954ec516479aaf4def728770606db840088242a8bd5c3758f1ecfa7d3f8d54beb5cd6e","priv":"0e3f2306a70147cb332877343ff260e18c37d807d1ada3db3545dc21cb7adf71","pub":"03374f7d18335d1677902e2fb7c7afb6c3646ab18bc76d12793b86e0097d2b79fe","addr":"4f65a8364edc65cc430f4916af41cbf339c34a4f"},{"mnemonic":"title reopen welcome pottery stand safe scrap little razor rate oval rabbit","master":"600c330dca29a426ecae0e5e6dfcb13e004efcfcab0fcecab676e42462caded3","seed":"7554d02d091605c47acf117773dfb96821e28c551c2c5e855803f79f7ec9b9e5a4a7273c605c2a53771e045bcada466d3b4a88d03a7fcc1644d990a8dcb21ff8","priv":"79621755dac86e6026853bcd0d4c032b48b7c5eabf81cbf8ca4e9d056fcec5a8","pub":"03f63693949fdc2b62cabc47059e8b1d9ba748800bf08a30001e19aee33627d189","addr":"ae0c6ad31b94b29d502a846e1e371356a96a4f2d"},{"mnemonic":"hat stereo gold maple advance wreck poet dawn excite midnight kind type","master":"661d8b63856089b6f3d6bb37558d4deba395c7ea7797d022db398c3224696316","seed":"b13cc53d42e9726cdd9fda4279a660d987dc3d302409a0ccc844731ae1b138495200bd1ddee3912124dbe826e62567a9b9fb57a33b638cbc4a56f8b55df3182f","priv":"548da8b9469029522189b9d4e30f6b58c75f234f18b99d4f4dffd027b6e022ed","pub":"032df4ae6e9e3ed444bc1fe3eba670f2d877de7e579309fe3e7a8ea3b5176999e1","addr":"f94c66a0851fbdb52cb7b6774c736cfe4f99edae"},{"mnemonic":"image wolf among domain where post bicycle perfect cloth october bonus plug","master":"1751c464935d8be5b1f43188a61f14d0f509cbe289d5e586f1c5057299c05d56","seed":"80bc37cd3dacb7020735655be8a001ea26bd8a5a74d950a5ba3f31603bd929531d6da39d06499927e5acaaef4845b3403e73e3bbc7a43434242dd2b432f17529","priv":"38db8c107323379d07ec59fa7b76ceb436a5430468562fbabdecf4bd0a06d58a","pub":"02c5e7d3d224db89285ff2f71c27a68b267f9fd799f05ee334084edd4b91d4071c","addr":"40551f9071d46824a15fba194d98425698145795"},{"mnemonic":"squirrel grit cross witness wagon defense marriage tonight absurd organ load sing","master":"d5739288f3d99e1759690e2d68e5ba543151cd58a0d55d0be52f0a4cfcdc2a3d","seed":"a3e09aa4755d4a4c48f4611a7a8c22040feca1694415b2a6976d2ce161102557f5e855d5195b0132c9e7f23e01b825465eaa10b19ed323647ea5beac8a635e75","priv":"055f00180e4bf6548ba7b525236f63444808c0052fabc4eb14cdad2debf499a7","pub":"03f9831a1213aedf436bdd9e898f1d571ed6a7858f0168d60afce7ac389dc27d86","addr":"8a1289c49f8d83275e4c2201c87ded060ab38a36"},{"mnemonic":"cloth diamond test stay also risk music unit beauty escape trip draw","master":"6d16a7ccf9577b8948afab2ac83cb12ea124e9cf86506e6d08f3fd685ba97a71","seed":"d67dbc3d1e00b7703a7a44b91ddb891d89128f59d2f298b2a48f464aaea9852b97fd3002569d9e4b8a1cebf0d7eef3b708a944b1cb745844fc01b71829bbb2ac","priv":"d52b78224b5e2b9d074b4141dba1956b33f66ec7e8e271a20786d04136d1755a","pub":"020fd792486b8d8777b9910bcb1c28c52fdbaf239e07885b94ebf85edca05f3609","addr":"f571651ea3de2e84b53da4af619b1c51acdf9c13"},{"mnemonic":"vanish slush budget question demise bargain inner push weasel clay project project","master":"11828853c3e89d3515ac8c838d2a5107079c93695c430e2d5383fff8a0a98de2","seed":"9f838e1b4140cefd6857ecda55690fdf36bf4bf0247833801a481130844a89d0483b05e9cd1042a855714f67298a3f9d8cc093e6bf9e86b4c7bf16223f4f89d8","priv":"2e5945a384de4ed1030a299e8dddd2c9ca20aff939641e3cdbb00f5619b186f0","pub":"03a52a0f153c92a5fcde0f004c4ab3166f040b6e7e609afee6c2d0e494c18e7a75","addr":"09e3386e3636e365d8bfd15e822b0cb50136b5ba"},{"mnemonic":"blind desk mobile debate orchard nerve crack tower little scrub twist fantasy","master":"4d677a558cc1d0911ccea1c14c817b8fea57668f9a81af43ed036a1bbbd8b6ba","seed":"eb67d96512b6136ce060c7b7800fe48a8fc2ebf50a6051f4be4255a5e974fa0443f0c5ce1efb0b0a87f227b0da5d740452313d86561a42262e5681864b529054","priv":"d54dea50a4dbc94530ed3c04771c6f4c71487cf3562e89b79684fd6ab7843846","pub":"032622eaf55666e30dc53d73a88517f24a08f6ad703f02db30e87368c5344cbb17","addr":"eaf15d884294d6b72b618c55206db3685e1b0532"},{"mnemonic":"thumb nurse there alcohol legal agent abandon sight pill street speed catalog","master":"1a041414d1258b30a589e61e6d8ba19a34ca2b2e8bca68962c0c9dad5863f5a4","seed":"1b539679974f7355ee02c9d6609640acdae476ea23bc7d5982604e20009bf3ec153f9ec82fcae5de92570d2bf94672047557a36b3ad3f3ec03b910038658b816","priv":"5ee3c0258920c32da893a0fa051593544fd3547c6e37123ef9d6edaea940dfc3","pub":"03e8714f4d3e9c3e342dae646deb62c31cf3a4bda119a820b0ff6810b8e3d85383","addr":"a3eeef1bfc965df2fe15abf7cbf19b381a458478"},{"mnemonic":"crew venture wall front gesture jaguar often arm fly scare lunar guide","master":"656a72d27ab1a5fb50e27fb598037dc2ebf60b1b9f0bf7612a8490c1efed6b39","seed":"1cd2a5e644dfe51e367da6784848ec64ab3c4965818dd3529f00efdc102388b02dedb2207052bfaabb32a4039f76594b006aec871dbe9856f2b71fe6f426d75b","priv":"67cc3ba8f7d83c6d08737e1b56dfe469c21500f20fac09e8bc096a091682ae73","pub":"03ca0d6eac7a2663451d29012c25bcf469d12c556f30a57a34fe6d66d27d506db4","addr":"5acc54542938330e6961c6ee770760c135ede717"},{"mnemonic":"survey never crew section reward cotton praise ketchup treat suit knock text","master":"7175659726fd0ffbbd37fd2c7e309589d32b271672ca5459b7e1daf5f2daa105","seed":"a5a37f251e3c745169bed474c8ae6599da847ea473da32b8ff922f2c710a3c31034dfc45dee514af90246bbb1317e21669ccaa0666d3c88c8f729fddfb95d240","priv":"fdd98704f53d7ad0e43ae71437626048fe23f71c24a67f31b9491b60c4db3c9e","pub":"026936de280e31c060bcbc777bf28ed1ccd0128be0c25f9d074378f72db1de0f4a","addr":"997434efd190bbf98541832fc48283ff736a067e"},{"mnemonic":"lonely physical plastic final cool beef cloth chaos dizzy enough whale farm","master":"79842f02a7d39d8f19373fb1ca3c73f1961c916628279a00c96a980cdeade871","seed":"f957d8197386bd4ed6c5000bbbd02f70d6b4b76953dc6a3e36f021d488cec54293198f64fe6d46c52041bd34efbceb1e6cce3184a42c8fd37903b924112ba2f6","priv":"d58df19dab225b29ea77bfbcda84c2f1982ccb6e1eb79011bde7adcc03b95050","pub":"024ed971b9763ad9aa8be27d9b75d9ff2f443594da5e3e0b7a598c71f6c2e0d759","addr":"f4d72185f769724b50be932caf960a1a3951ea84"},{"mnemonic":"can three trend breeze spatial puzzle stool cherry raccoon sauce bounce balcony","master":"e76d9d768fe3ead9a6c1b561649b292d8659a6778442f9451a8fdd52e35637d7","seed":"85aae0e7a3e2efd67741cb0d752a078b250deb53927bea3f384d72661889409389188f267d7be61629c6a85aa7dc5b2607a066f32ac39a2c5efc4720b4a72e7e","priv":"57a934f4fdbb619a40394cda13acd1fc61ed9f17e4b4fcbcac2248b5703eb71e","pub":"02004c3736772a2cb507231b7ab75bfc7c1d35ca9e49523f1076e7d0925acce8ce","addr":"859915a9f70f142a41b0d169e7ec342061fbebdf"},{"mnemonic":"gaze example quote much tourist pitch victory common lazy message random glad","master":"6fdb41e8f54d6f123c75856c1c13caccb01bbd7e84b1c3385fb5fdb885f72f09","seed":"bdb5196003c1d1d272367b12affaa4d0cb37fb3aeea88bde6992dfd3519af34e94729ebc9e8057b9e462c064292a7cac18eeb838ec0f71b082cfd66bece3c5e4","priv":"1f264f1e86de3b28ea8f4827dee679787e60e34e81271139a8e74870518bce27","pub":"035e75a0beff3188c9d5aea7a760b879413ef712d98354b702aedc3385d58c903d","addr":"67c21921fa2c47c5657ae2434c29f447511fbab2"},{"mnemonic":"taste panda wreck guard trend blush armor giant innocent palm trouble silly","master":"8f3c32829998fdb3355b3a88caf484eaf7d67122c991c2402d77eb3e5e4f8416","seed":"fcf9f308ac99d81e74329f60787fd311848a2e56384202c37c025bafeb7022e4b47ca24a680d07d073566c487f39c8c0dc4bf43569b73f30ba4a2c260ce98e28","priv":"463194496ba851f6455e8298a0d4c118341bb0183c73c2d7739ef2c5bee38e0e","pub":"034a87ade739d3da37c8f15928db9b064bd1d1af0c10ffbb9f2027f42061c9bdf2","addr":"b0afd62cbf962672d092732872a6ab2795c9132c"},{"mnemonic":"tragic enter actress believe nominee floor vehicle dinner bulb useful case bamboo","master":"66f8cb0425dd278236de1352e9b2e47fbb8662d1de9d31227c4f18873b6aaf4d","seed":"5f0f5113b93be9036f009972fc49d9fa444c0dc4f89ad2e5d590f33b2aee250194494bfff047f8c9cc0261208d0d842f4c8a320d68f852c0938b6dd472a9c819","priv":"3fcea63ea530b9539af1ea66f5ceca1acc508fcf21a0d5ac21a378af5aabfb37","pub":"0256ac4246f19dbd12af232b2fe00efd158624ea48728b3a647c8237b7b9c1fe56","addr":"13804f3f5f0ba3c8f769b2e3428962f4ae88e4b0"},{"mnemonic":"between grocery tool polar already roast cash budget fatigue museum obvious notable","master":"c13b5bb1840f804c9b1da51fdb788f9262fad64b4c576370ede2d9c4001de2fe","seed":"1e5a866e10ee3ed7e727f59673328eae03808cfdb1bd3c9f155a1ce8f7c9bee61fd8d68d6b995588c0264400780467313ba92a9c359edc48ca59dcfff62567c4","priv":"08d7d4fa44f89fddc836ea265b71e9985363cf4e9ba0cb5b1ef0bfcbd00e0aa4","pub":"03514e8e0c990a6a60b1138351255827c7c46e15c3bc25f55946276b5fc56d9068","addr":"0c759c31f5f142dac57e712c7a09c99a3a0875ba"},{"mnemonic":"combine unique pig mind pair area chase idea abstract grow into result","master":"e7d06819461fbfccd1e05b6d63507b179854fd75fe7fcce2cd04ad6eb89fd11d","seed":"a1863842b2a6d82dca20ece807c12c58f6c4d2d1fcfc2577baa368a3a45a7ccb0650009ab558bc8350b77f9a03f6155e8c35f76ebf9b30133dc732ef5abe69cb","priv":"a545f01810112491c613a35c829157cc6a3dbd30b4b51f1d1eaa53fefb61e09b","pub":"02008752e98ab20e0fc8c9859884f97423c2315f5f35d1d757907b0affda7da9de","addr":"353ac98ae22d3161ce81bed93d7a0d77abd9e11a"},{"mnemonic":"bonus voyage inject they glory wreck soldier anchor also job cattle random","master":"cc5593732d2681a1aed33672cfe74f24238443d1b118235550834e14bc720235","seed":"ae6175dae17f8ab7481092eac1ee7d4c08d9ffeb69850745a1507c63426aaee1ef3bc6ae7fad3152d9bcb58e77a14a9570a4c550078c963991b215db64a2e9eb","priv":"45118b84fd5c7802b71fead3d78e5953e1841ccb4d4cddc20aa154e9fbfcf467","pub":"02a0378a67714f50eb383b47f7ab67b32c2adc2b8376b12da9e656ef11da9172c7","addr":"aa4e5ff5d78486413eef80525d20fc0a46befd5c"},{"mnemonic":"axis grace advance retreat fence prison traffic shield visual evoke upper they","master":"b0f1e554c9c4c38355939ec8641548df255dc8260ee2beb02eea8436359731fe","seed":"42d47d86e0eba00ac90f92e464cb034b25e3e261618ccb7893524e6103b8ab8edac9262e7417ca55cec0e5b90f0405d6b43b920317597d8b67c34f909b308ad9","priv":"0e986b99de5e1403218a3d6e64eda2c6e980002fc9345795464c6e100c4d214f","pub":"028193d72358fde04b71d553794171a3f6800d2d20d1d4821c2d411d9dcab044f0","addr":"68ef0232b6199e173a31b522f73b8740807e7991"},{"mnemonic":"speed advice script dynamic company foam mimic conduct wasp soft stick insane","master":"b0f61b56e248b14dc116231490779949a829920a9caf582fe25df4459e65108d","seed":"7b8b72a1bff2551f2e704e68f364b8d578e24bd6c51fead9805c2c33bf463dd462c793f73b88ca6353e8385a5baeba2c91e4efd6ccc2b80351cfed9d9a6d7738","priv":"32e5a08edf79a3192b221f978e209fee7f7d64f83c28ff57f47ff5757b727b14","pub":"02fa4ba71ba618ce2f1508b0386ceb0e09e202722353d9724a597cd680130c53e3","addr":"713ae3fbba6df605c843147183dfbf3a3fdd86c4"},{"mnemonic":"punch fame nasty actual betray melt find wink cross hobby double there","master":"a7bb2a4a7cc93d7dc12efe29071329febba1c999c4e7766172d9e53fe29cb0c8","seed":"6876d29989880fd1bae26463cd01cb148c68ea842603822657d0bdc708a8987cd33453087febfeda2f3ea53f2fcd65ee1c5f89b0cfd8aefefee2c81ed32c91e0","priv":"731b30c783b7cfeb7458db1e0c0db2586216b6ba661f1adff761977c782d24ef","pub":"03ee75f400c95ecc4b852cd1ea2b434f5cbdd2f6eb8a881f0f24a3d1098a6ce778","addr":"96ce0c791931f867dc4fddd2f091a552f1e57d26"},{"mnemonic":"feed session repair glad envelope pepper faculty earn hour slender cost boat","master":"d8507e0bbacaa494dd65a38d82c02f00d168ec8bdff9991f78ed5fc13ba81d38","seed":"aa9ac398fd8c94bef20e9b9a94bdb81fcafaec2453efaa2929730145528495515d7632de9cf558313a35d50c0428a15f01efc831379a696f632705bba7394ce8","priv":"ef95d3d563a0e774c8d486adeb2d22f4fcf4cddd80cd2a05471b691c12cfe0fd","pub":"026b711c8ed8ea414276c9d7c7a92739a350cbf01372d41c2160c046e1459223be","addr":"72da6e869b7d435ff2507e658acb26e0a50e6303"},{"mnemonic":"person affair gesture cherry intact day wrestle crew okay express throw large","master":"84a10e3f12a6d24e76cd66e934116f9478d8b1bf912fc61c9e00058f7c489f6a","seed":"5dbd3c2fe715a4dd9ca5129df8fddac1f699429636a58bcc2379791af11dcd77bd9b84f3d62539bf5eb41eb8fc966304cf334cc46133b7e42104a18733514777","priv":"337a826c33caf41a74b465c6981986d629c13a71aeef4c0e7c2b78fc3dff613b","pub":"03edadf784d13c4e22b33b61222e20348cc68e245d8b143dde09d37963e9e01eef","addr":"916fd4d732155d78fd412b4cd78abb49bac56c19"},{"mnemonic":"nose talent woman drip regular endless bar resemble friend mean frog cage","master":"1beb38f144a90141600a34813e98ac3cca43009e23c542b3009f3e22988b9705","seed":"aa324508ec3951c30fa4b32ca7a4ea48773c572652076a2a7e6aadec3faee23c3388663002b086483f39a1b08fd50ff233ddefded05f583211686d0323dd4d64","priv":"67109cb296022e46fbd12569cbbaeecec1843479bc716f7ed07ff996561f8196","pub":"03239409138ec1b5a60e5d72f894e95d599be18978d9f43bf201c85bc20210b473","addr":"580cdfe5a38f37a644204cd1d4b0094dffb982d6"},{"mnemonic":"undo thrive relax ancient menu milk sand race bargain evidence steak tomorrow","master":"1db1b33c9f26783cf9743ec719022a1280c8257ba11b2b03f35455cdfeb10ddb","seed":"b9905331927ef09ae2dbf5bec382cf3f18bd9cc03bbd4d21e8f63cbde32cd22abf07bdea578a201558f2a1f09f2fec8e3c7557f731a57439f1e348bd7530d9f3","priv":"c91c34d1a5218ecbfb63990b636d8bcbf6d7ba4723b70c960597f1b4ffb2854b","pub":"03c7d4b726c2ef316d8e60f0941e2af09c0cc1a9967aed825c322b629f74ebbab0","addr":"cbc5acf5001cb4d88fe88404cf3d1a919b127aa5"},{"mnemonic":"relax owner update nice speak office assault pottery uphold clump since ball","master":"5540b4c874952470d93f8a94689bd58c03c8bff373c74890e70b63caf9b5fe48","seed":"c3e8c04ce0d472761c468cdc13d04cd8fee5333a806259657923aad79d9bab8333329353e69cd3fc67833a7041a2c49f3c2b0654a4d243415f3f2761a4f7fa29","priv":"882ea08c9157b6bbfd686007ad668de373f34dbeb08e5d983a447a12c9efad3e","pub":"022f8b50589f2413d294e33de8fcac751c4c6ae54b359ba428c4a1ae28cd2ff57f","addr":"6ec1ae2736cb2a9e1dae6b5d5c7d408347db2dce"},{"mnemonic":"immune find story sadness depend debris popular swallow egg gauge firm drop","master":"fa46f28a8f32770393d3a3fd934141823d48ae561d8952ef3ac87839867840c7","seed":"6b5234df2c1b9ecb85d8493849e66186f98a828287e133cffc210140d63bee412ec58ede1968c2999485ef80710a83a99e7ffe205c404c5bda7346369c16f6fa","priv":"77cc4d765ee74267ea50ce3637ff9916370802a4940bffc8f7b76aac869ef80d","pub":"037d1e64685d2229c9b49baf2245511b3dc26733e1275c36f60555e2eeee32aead","addr":"80d9e410145ca65c65f143804e7e13f0572693af"},{"mnemonic":"airport refuse lake shuffle borrow depend agree oven huge hen brand reward","master":"b21a47b26023f1ed1963f81a2ec424c88520055cb2d69c329c76e6a354cccf91","seed":"7ae802a81c37abaf146f9c7606409640c53a3502da921347dbc260fc4fa5a164ec458480038ac10a3dc2c5ec15c600e72e011392413e13b9daeea82c2e9ef611","priv":"748f3e6cb6caafe5a188d528557ec1c1e817f990394bea8a011e3cbf6d00a3ec","pub":"029f0f4e5bf957c569e9cbb814295acaa1bb8bbdd549844246f86656ab700cd35f","addr":"005b3c2696248d3e45b43c88e258b2dee69ae542"},{"mnemonic":"slim trap alone fetch people skate middle since yard frown during smile","master":"1db54486ad20e5fd82e7c5bcab652cd01632014d66ccf0f7d6c39bc0a337fd77","seed":"30c3948e518b8ca06625fd7a1318984997ff587aa865207b54d5c9c469386e66e06656fe020665501a1f0a07636a250ddf5c127d5bd9ec497052b9e4ff2dc37d","priv":"0ce3645a3f7a1ae02535852fbfee9c59609eeb226a975ae24c94b7a13acb4d85","pub":"03b3f40812780bd4f8a596c0131ced87b9b981e4950f5217f44de7f777b4d29b35","addr":"7777090b6e5ae18d4a146a0c9c17a1a34cde74da"},{"mnemonic":"vague melody fine buffalo spread nation reduce spirit humor fruit spin diary","master":"7a5951d167793eb5d42307c68a3997fec7c34d56562dcab752c2559b97507e3c","seed":"aeb4a2ee7a25712bb76b26c654f5a79b4e92c25689799de2a11283a668aabc3d967d111e2bd98691dc2b72adb66188888999e0ce03ab2bf1b18e8d5d7f8c528d","priv":"d2dd273a93786422dc68e61e67dc0c48402af5964f85d5d785476bbcc68e99c5","pub":"0347a23bf9c802d6d826367a34219ff155a720b068bb0cc4f9c679d350f35a978a","addr":"88679cd2c43e562c21738ba5ffc8bff82575bc6d"},{"mnemonic":"ahead glad fame hip era kite pyramid endless sponsor tissue winner kite","master":"eafe3d2af7a63b644668dfd23b7f0868a1d6527b630860f79838fc520896e64e","seed":"91f06eed5517fa2367c272a18362085775cc9d8f13b2358ab32d0c626abd87aefb8ffdd1f37712d4c39fb625ff4aa56cfe06a3054e162bb62fb03755a19f970a","priv":"c8d580087355904e691ad5292775989853e59ce1d41d224f97d2d4b96f8514d1","pub":"0342c4be0ea075609aa181fb83ffa189ec9744c2a7c54f7d3fa2273ba01ae127e8","addr":"ebd946e96a89c8932ec788d66f3fe8c482622831"},{"mnemonic":"clump earth diary ostrich section column practice rapid hotel mom client adjust","master":"c6be4ea8b2810f07731b7258f2a2cf4a4bd0722e43081957bd74ccb5955bed55","seed":"04c2178510fe5f7afe60cf8718bc5240da95cc2a79d28fb2bce756a2fb0995f25c5921addae1932dcc4b62ee68b330d3abfe190f212f809816ee7c6d5b816095","priv":"d2ecfc9fffd24c8299647fc2f23a16a2e5b35ec6092563ae731d4737159ce03d","pub":"027c615b33b69f5599cb800a85073582bb2180f20bedd1bb3e8384bada13ab8f92","addr":"df913518315ba257805f9ea9f78c859428d101d9"},{"mnemonic":"teach salt dinner dinner escape cheap gate major bind armor dash gallery","master":"954d52c8574645c888e4eea6ca661fd1ca4764ca9e4243bc75610571a24ec5ac","seed":"7c3753fb498e2a48af89e5a39153382eb9591eb8a5bb2cc5b8bf690bb6d1365162bccfbc9d5e3688f48352f1f8915c376dfacc3c3cad9315fa60cb303161ac77","priv":"c3a850ce632a7ab061e378596cb4c66a6880d41f6b09b0868d8c7e96bde490fe","pub":"02a615c68dd2bb66d3cc9d7e46a0fa00510542471a19b1d48fe05355acf38903b6","addr":"db50721f5b6e0907490990182793ae796756bc7b"},{"mnemonic":"cement casino erupt clever gasp benefit response invest diet banner month hill","master":"97c777e73bebf40d39c4efe8fb74db3cedcf2e1ebd366520515ee2823a9c4d28","seed":"9344a709e0d53322b928e3128d1bc707216eb0e1ebb137f74fbde6cd066f88b86088793a5794df8cfbd6efb12c843399e8ccb958446fa558573b013d33236436","priv":"96464373c492c388bc4a2c421ed0f5017fb426ac95e55f0f322703b28012cf90","pub":"03e71c89b2629c032b6c9a35b46d572dd0db3dde47bd5919bed8457885553148b1","addr":"493af641ce946561f6cb3116a135fe6e6b1b0f13"},{"mnemonic":"supreme news pyramid sheriff attract volume zone innocent hat grunt gorilla mango","master":"2ba0cd68329e2b19d5c24c1d3fca44513151fc4a634e52756290967989883b52","seed":"efbf7e16af697b4dd62a876f62f08698e29531c05018bb6da7ce441340b0278353d5d08a88cb93c4fd9bdb14fb85ab857ea3e8ef13b49dabb20beae2f13af3fa","priv":"15b89635f69b28cee0aa00d0609b99f1a1dd3c83e3bd57032987146cd47cebb8","pub":"021ae715a05c4849519acbe8dbf7ff4031d18f57de1bcf9cb1a06d50e5ebdbf661","addr":"e3087b309db8490b23629cbe4d113c1ea5bb525e"},{"mnemonic":"way chat van put negative minute tail dress spawn crunch beef moment","master":"e0dff85e10808c3ac560957a46f5f86abbfc62251c8fd4c61cb5e089a0841e7a","seed":"eb14b38f90886c1a1d47ac42205b564a649a0cf6edbd88cda1c488ee700aae8b735d7e947efc5711e2cc02b2254690ff4a69d149d2e13affd6d9a3915ac9dceb","priv":"7fb5464c8bc2e1583105d34c6850fb332a578fea35dff9528422c8b7f3156242","pub":"02745f0fbe0b23688e9691f9c4a088bf1342100fe3b9f7e405df79bddd57f8e6e1","addr":"66d90273421fadbab93fb9b05ea6e572f8af7050"},{"mnemonic":"tattoo strong tool weapon blue cricket kick holiday medal club stage reason","master":"bc82d196675dbad1c24d78f4e400a8956297c6113d4004356963ca88617597b3","seed":"9cf6193178f1a6391105c79cc6d3d2e2a4fe97f44738f8f716fb5b17a3eacd4061f9bb7f0411b08d77dc10b16b9599e45e8ffa55ff7f8e5c9274bab71bfe120f","priv":"5925547ee089b4638743f0fabe33f925780772a65b87b8315acf7f523d044482","pub":"03bba775f325b1ad28ec0adf66c8e15f90d70368fa021be5db199a5188c0621eb4","addr":"1f63ff4af01b5b5f33e60b82646a39917b6a7305"},{"mnemonic":"rug diagram spend zebra occur neglect choose relax face when spell stem","master":"d7932ffb8f6b751543caed7158318a05f4686646e636b5725b9b0419fb66912b","seed":"b73957a412d9e4c677edef4cb3a376c7355f78bba347a61f44c85f76b2c8a3d8ac2bd6c3b70643bf19b8487dcdce3055aaf86921e29e5e6f89700e0e2bf00546","priv":"c827dfe5f1880d9c462985b915ff78a1ab615ff0840f3f125f618cef25e14a5c","pub":"031bfd2158660168795f38f980951921f6fa1d522ad460ac5f93dfc4a2eac91f7d","addr":"b866f1e9b5b7b00fbb6076915a0a2931cba6e029"},{"mnemonic":"faith bless there mountain stand cannon sick abstract fiscal theory begin easy","master":"9af948584294b3951e6c664423a12fdfe29a31d41546b911f3fcdf664399aa48","seed":"17b6451f4b9765fdc3ed280fb5a6141b8003c8c9d8c73afce3192e15012fd18431850ebcaa07fa08da2c648f0f97f45e33ebdea6c99f2f23a9e244a297596499","priv":"e759b35d18e8b60726e882a11ea830e30ddff6752a19bec6983fdecf655726b0","pub":"03151da31179657f296184543a1360bcb92983a12788b268db0c20d895e6c449b1","addr":"54ec389ea177e1a4fe2f98cd83f27cce218b9081"},{"mnemonic":"combine fine crowd enter check mule toward damage fortune bless topple source","master":"b831b7a1b85edf1945c892dd332419e7f3a5125229cdfe1c73cc0e964abb4b5c","seed":"d9456b80f01787607d9c3adecdd6fa299132d748ae4fab843b3802c798ea1bc0395f9a1dc29e1badccc742f3c4fa081bdd7b6f9ca8980009b75c892438020b9f","priv":"d9d037b9baf0796d8a151935c172b1f775c1875b3811bcfd6c3f477e74c5c54e","pub":"03c720f00c921ab13307d3790f742f0a40436fad9d999087c267107ce50f8fe2b9","addr":"4b5a1c53f8442c375e9af35937ff0471155c0bee"},{"mnemonic":"shift nut floor scorpion property sun either total follow glide special apology","master":"1a4520e80df55ad59d95fca8dfab5f09753f6e26f7f38f654f32e4fa6f3ff963","seed":"a9df829ec832270d1ef0b0b04542e351ab9145baf086231fbe9636120c18c8d545ed138c37c0612d296c915340f982b1d83bd408301de79c08e4580ce0ce8fdd","priv":"27b1742305c3921c0cc041dc79d6e3c83112828f3fd49e18f31cb0b422bc1c80","pub":"032b322eedf502edf5e6c24ad80ad4bde37e04de012b9bf9c8caa41151a9ccf74f","addr":"2ce4a3aeb7e0fc52c31121651346959d1cfcc1be"}] diff --git a/keys/keybase.go b/keys/keybase.go deleted file mode 100644 index b55658d2f..000000000 --- a/keys/keybase.go +++ /dev/null @@ -1,362 +0,0 @@ -package keys - -import ( - "bufio" - "fmt" - "os" - "strings" - - "github.com/pkg/errors" - "github.com/tendermint/go-crypto" - "github.com/tendermint/go-crypto/keys/bip39" - "github.com/tendermint/go-crypto/keys/hd" - dbm "github.com/tendermint/tmlibs/db" -) - -var _ Keybase = dbKeybase{} - -// Language is a language to create the BIP 39 mnemonic in. -// Currently, only english is supported though. -// Find a list of all supported languages in the BIP 39 spec (word lists). -type Language int - -const ( - // English is the default language to create a mnemonic. - // It is the only supported language by this package. - English Language = iota + 1 - // Japanese is currently not supported. - Japanese - // Korean is currently not supported. - Korean - // Spanish is currently not supported. - Spanish - // ChineseSimplified is currently not supported. - ChineseSimplified - // ChineseTraditional is currently not supported. - ChineseTraditional - // French is currently not supported. - French - // Italian is currently not supported. - Italian -) - -var ( - // ErrUnsupportedSigningAlgo is raised when the caller tries to use a different signing scheme than secp256k1. - ErrUnsupportedSigningAlgo = errors.New("unsupported signing algo: only secp256k1 is supported") - // ErrUnsupportedLanguage is raised when the caller tries to use a different language than english for creating - // a mnemonic sentence. - ErrUnsupportedLanguage = errors.New("unsupported language: only english is supported") -) - -// dbKeybase combines encryption and storage implementation to provide -// a full-featured key manager -type dbKeybase struct { - db dbm.DB -} - -// New creates a new keybase instance using the passed DB for reading and writing keys. -func New(db dbm.DB) Keybase { - return dbKeybase{ - db: db, - } -} - -// CreateMnemonic generates a new key and persists it to storage, encrypted -// using the provided password. -// It returns the generated mnemonic and the key Info. -// It returns an error if it fails to -// generate a key for the given algo type, or if another key is -// already stored under the same name. -func (kb dbKeybase) CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, mnemonic string, err error) { - if language != English { - return nil, "", ErrUnsupportedLanguage - } - if algo != Secp256k1 { - err = ErrUnsupportedSigningAlgo - return - } - - // default number of words (24): - mnemonicS, err := bip39.NewMnemonic(bip39.FreshKey) - if err != nil { - return - } - mnemonic = strings.Join(mnemonicS, " ") - seed := bip39.MnemonicToSeed(mnemonic) - info, err = kb.persistDerivedKey(seed, passwd, name, hd.FullFundraiserPath) - return -} - -// CreateFundraiserKey converts a mnemonic to a private key and persists it, -// encrypted with the given password. -// TODO(ismail) -func (kb dbKeybase) CreateFundraiserKey(name, mnemonic, passwd string) (info Info, err error) { - words := strings.Split(mnemonic, " ") - if len(words) != 12 { - err = fmt.Errorf("recovering only works with 12 word (fundraiser) mnemonics, got: %v words", len(words)) - return - } - seed, err := bip39.MnemonicToSeedWithErrChecking(mnemonic) - if err != nil { - return - } - info, err = kb.persistDerivedKey(seed, passwd, name, hd.FullFundraiserPath) - return -} - -func (kb dbKeybase) Derive(name, mnemonic, passwd string, params hd.BIP44Params) (info Info, err error) { - seed, err := bip39.MnemonicToSeedWithErrChecking(mnemonic) - if err != nil { - return - } - info, err = kb.persistDerivedKey(seed, passwd, name, params.String()) - - return -} -// CreateLedger creates a new locally-stored reference to a Ledger keypair -// It returns the created key info and an error if the Ledger could not be queried -func (kb dbKeybase) CreateLedger(name string, path crypto.DerivationPath, algo SigningAlgo) (Info, error) { - if algo != Secp256k1 { - return nil, ErrUnsupportedSigningAlgo - } - priv, err := crypto.NewPrivKeyLedgerSecp256k1(path) - if err != nil { - return nil, err - } - pub := priv.PubKey() - return kb.writeLedgerKey(pub, path, name), nil -} - -// CreateOffline creates a new reference to an offline keypair -// It returns the created key info -func (kb dbKeybase) CreateOffline(name string, pub crypto.PubKey) (Info, error) { - return kb.writeOfflineKey(pub, name), nil -} - - -func (kb *dbKeybase) persistDerivedKey(seed []byte, passwd, name, fullHdPath string) (info Info, err error) { - // create master key and derive first key: - masterPriv, ch := hd.ComputeMastersFromSeed(seed) - derivedPriv, err := hd.DerivePrivateKeyForPath(masterPriv, ch, fullHdPath) - if err != nil { - return - } - - // if we have a password, use it to encrypt the private key and store it - // else store the public key only - if passwd != "" { - info = kb.writeLocalKey(crypto.PrivKeySecp256k1(derivedPriv), name, passwd) - } else { - pubk := crypto.PrivKeySecp256k1(derivedPriv).PubKey() - info = kb.writeOfflineKey(pubk, name) - } - return -} - -// List returns the keys from storage in alphabetical order. -func (kb dbKeybase) List() ([]Info, error) { - var res []Info - iter := kb.db.Iterator(nil, nil) - defer iter.Close() - for ; iter.Valid(); iter.Next() { - info, err := readInfo(iter.Value()) - if err != nil { - return nil, err - } - res = append(res, info) - } - return res, nil -} - -// Get returns the public information about one key. -func (kb dbKeybase) Get(name string) (Info, error) { - bs := kb.db.Get(infoKey(name)) - return readInfo(bs) -} - -// Sign signs the msg with the named key. -// It returns an error if the key doesn't exist or the decryption fails. -func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signature, pub crypto.PubKey, err error) { - info, err := kb.Get(name) - if err != nil { - return - } - var priv crypto.PrivKey - switch info.(type) { - case localInfo: - linfo := info.(localInfo) - if linfo.PrivKeyArmor == "" { - err = fmt.Errorf("private key not available") - return - } - priv, err = unarmorDecryptPrivKey(linfo.PrivKeyArmor, passphrase) - if err != nil { - return nil, nil, err - } - case ledgerInfo: - linfo := info.(ledgerInfo) - priv, err = crypto.NewPrivKeyLedgerSecp256k1(linfo.Path) - if err != nil { - return - } - case offlineInfo: - linfo := info.(offlineInfo) - fmt.Printf("Bytes to sign:\n%s", msg) - buf := bufio.NewReader(os.Stdin) - fmt.Printf("\nEnter Amino-encoded signature:\n") - // Will block until user inputs the signature - signed, err := buf.ReadString('\n') - if err != nil { - return nil, nil, err - } - cdc.MustUnmarshalBinary([]byte(signed), sig) - return sig, linfo.GetPubKey(), nil - } - sig, err = priv.Sign(msg) - if err != nil { - return nil, nil, err - } - pub = priv.PubKey() - return sig, pub, nil -} - -func (kb dbKeybase) Export(name string) (armor string, err error) { - bz := kb.db.Get(infoKey(name)) - if bz == nil { - return "", fmt.Errorf("no key to export with name %s", name) - } - return armorInfoBytes(bz), nil -} - -// ExportPubKey returns public keys in ASCII armored format. -// Retrieve a Info object by its name and return the public key in -// a portable format. -func (kb dbKeybase) ExportPubKey(name string) (armor string, err error) { - bz := kb.db.Get(infoKey(name)) - if bz == nil { - return "", fmt.Errorf("no key to export with name %s", name) - } - info, err := readInfo(bz) - if err != nil { - return - } - return armorPubKeyBytes(info.GetPubKey().Bytes()), nil -} - -func (kb dbKeybase) Import(name string, armor string) (err error) { - bz := kb.db.Get(infoKey(name)) - if len(bz) > 0 { - return errors.New("Cannot overwrite data for name " + name) - } - infoBytes, err := unarmorInfoBytes(armor) - if err != nil { - return - } - kb.db.Set(infoKey(name), infoBytes) - return nil -} - -// ImportPubKey imports ASCII-armored public keys. -// Store a new Info object holding a public key only, i.e. it will -// not be possible to sign with it as it lacks the secret key. -func (kb dbKeybase) ImportPubKey(name string, armor string) (err error) { - bz := kb.db.Get(infoKey(name)) - if len(bz) > 0 { - return errors.New("Cannot overwrite data for name " + name) - } - pubBytes, err := unarmorPubKeyBytes(armor) - if err != nil { - return - } - pubKey, err := crypto.PubKeyFromBytes(pubBytes) - if err != nil { - return - } - kb.writeOfflineKey(pubKey, name) - return -} - -// Delete removes key forever, but we must present the -// proper passphrase before deleting it (for security). -// A passphrase of 'yes' is used to delete stored -// references to offline and Ledger / HW wallet keys -func (kb dbKeybase) Delete(name, passphrase string) error { - // verify we have the proper password before deleting - info, err := kb.Get(name) - if err != nil { - return err - } - switch info.(type) { - case localInfo: - linfo := info.(localInfo) - _, err = unarmorDecryptPrivKey(linfo.PrivKeyArmor, passphrase) - if err != nil { - return err - } - kb.db.DeleteSync(infoKey(name)) - return nil - case ledgerInfo: - case offlineInfo: - if passphrase != "yes" { - return fmt.Errorf("enter exactly 'yes' to delete the key") - } - kb.db.DeleteSync(infoKey(name)) - return nil - } - return nil -} - -// Update changes the passphrase with which an already stored key is -// encrypted. -// -// oldpass must be the current passphrase used for encryption, -// newpass will be the only valid passphrase from this time forward. -func (kb dbKeybase) Update(name, oldpass, newpass string) error { - info, err := kb.Get(name) - if err != nil { - return err - } - switch info.(type) { - case localInfo: - linfo := info.(localInfo) - key, err := unarmorDecryptPrivKey(linfo.PrivKeyArmor, oldpass) - if err != nil { - return err - } - kb.writeLocalKey(key, name, newpass) - return nil - default: - return fmt.Errorf("locally stored key required") - } -} - -func (kb dbKeybase) writeLocalKey(priv crypto.PrivKey, name, passphrase string) Info { - // encrypt private key using passphrase - privArmor := encryptArmorPrivKey(priv, passphrase) - // make Info - pub := priv.PubKey() - info := newLocalInfo(name, pub, privArmor) - kb.writeInfo(info, name) - return info -} - -func (kb dbKeybase) writeLedgerKey(pub crypto.PubKey, path crypto.DerivationPath, name string) Info { - info := newLedgerInfo(name, pub, path) - kb.writeInfo(info, name) - return info -} - -func (kb dbKeybase) writeOfflineKey(pub crypto.PubKey, name string) Info { - info := newOfflineInfo(name, pub) - kb.writeInfo(info, name) - return info -} - -func (kb dbKeybase) writeInfo(info Info, name string) { - // write the info by key - kb.db.SetSync(infoKey(name), writeInfo(info)) -} - -func infoKey(name string) []byte { - return []byte(fmt.Sprintf("%s.info", name)) -} diff --git a/keys/keybase_test.go b/keys/keybase_test.go deleted file mode 100644 index a3957f8e9..000000000 --- a/keys/keybase_test.go +++ /dev/null @@ -1,383 +0,0 @@ -package keys_test - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/tendermint/go-crypto" - "github.com/tendermint/go-crypto/keys" - "github.com/tendermint/go-crypto/keys/hd" - - dbm "github.com/tendermint/tmlibs/db" -) - -// TestKeyManagement makes sure we can manipulate these keys well -func TestKeyManagement(t *testing.T) { - // make the storage with reasonable defaults - cstore := keys.New( - dbm.NewMemDB(), - ) - - algo := keys.Secp256k1 - n1, n2, n3 := "personal", "business", "other" - p1, p2 := "1234", "really-secure!@#$" - - // Check empty state - l, err := cstore.List() - require.Nil(t, err) - assert.Empty(t, l) - - _, _, err = cstore.CreateMnemonic(n1, keys.English, p1, keys.Ed25519) - assert.Error(t, err, "ed25519 keys are currently not supported by keybase") - - // create some keys - _, err = cstore.Get(n1) - assert.Error(t, err) - i, _, err := cstore.CreateMnemonic(n1, keys.English, p1, algo) - - require.NoError(t, err) - require.Equal(t, n1, i.GetName()) - _, _, err = cstore.CreateMnemonic(n2, keys.English, p2, algo) - require.NoError(t, err) - - // we can get these keys - i2, err := cstore.Get(n2) - assert.NoError(t, err) - _, err = cstore.Get(n3) - assert.NotNil(t, err) - - // list shows them in order - keyS, err := cstore.List() - require.NoError(t, err) - require.Equal(t, 2, len(keyS)) - // note these are in alphabetical order - assert.Equal(t, n2, keyS[0].GetName()) - assert.Equal(t, n1, keyS[1].GetName()) - assert.Equal(t, i2.GetPubKey(), keyS[0].GetPubKey()) - - // deleting a key removes it - err = cstore.Delete("bad name", "foo") - require.NotNil(t, err) - err = cstore.Delete(n1, p1) - require.NoError(t, err) - keyS, err = cstore.List() - require.NoError(t, err) - assert.Equal(t, 1, len(keyS)) - _, err = cstore.Get(n1) - assert.Error(t, err) - - // create an offline key - o1 := "offline" - priv1 := crypto.GenPrivKeyEd25519() - pub1 := priv1.PubKey() - i, err = cstore.CreateOffline(o1, pub1) - require.Nil(t, err) - require.Equal(t, pub1, i.GetPubKey()) - require.Equal(t, o1, i.GetName()) - keyS, err = cstore.List() - require.NoError(t, err) - require.Equal(t, 2, len(keyS)) - - // delete the offline key - err = cstore.Delete(o1, "no") - require.NotNil(t, err) - err = cstore.Delete(o1, "yes") - require.NoError(t, err) - keyS, err = cstore.List() - require.NoError(t, err) - require.Equal(t, 1, len(keyS)) -} - -// TestSignVerify does some detailed checks on how we sign and validate -// signatures -func TestSignVerify(t *testing.T) { - cstore := keys.New( - dbm.NewMemDB(), - ) - algo := keys.Secp256k1 - - n1, n2, n3 := "some dude", "a dudette", "dude-ish" - p1, p2, p3 := "1234", "foobar", "foobar" - - // create two users and get their info - i1, _, err := cstore.CreateMnemonic(n1, keys.English, p1, algo) - require.Nil(t, err) - - i2, _, err := cstore.CreateMnemonic(n2, keys.English, p2, algo) - require.Nil(t, err) - - // Import a public key - armor, err := cstore.ExportPubKey(n2) - require.Nil(t, err) - cstore.ImportPubKey(n3, armor) - i3, err := cstore.Get(n3) - require.NoError(t, err) - require.Equal(t, i3.GetName(), n3) - - - // let's try to sign some messages - d1 := []byte("my first message") - d2 := []byte("some other important info!") - d3 := []byte("feels like I forgot something...") - - // try signing both data with both keys... - s11, pub1, err := cstore.Sign(n1, p1, d1) - require.Nil(t, err) - require.Equal(t, i1.GetPubKey(), pub1) - - s12, pub1, err := cstore.Sign(n1, p1, d2) - require.Nil(t, err) - require.Equal(t, i1.GetPubKey(), pub1) - - s21, pub2, err := cstore.Sign(n2, p2, d1) - require.Nil(t, err) - require.Equal(t, i2.GetPubKey(), pub2) - - s22, pub2, err := cstore.Sign(n2, p2, d2) - require.Nil(t, err) - require.Equal(t, i2.GetPubKey(), pub2) - - // let's try to validate and make sure it only works when everything is proper - cases := []struct { - key crypto.PubKey - data []byte - sig crypto.Signature - valid bool - }{ - // proper matches - {i1.GetPubKey(), d1, s11, true}, - // change data, pubkey, or signature leads to fail - {i1.GetPubKey(), d2, s11, false}, - {i2.GetPubKey(), d1, s11, false}, - {i1.GetPubKey(), d1, s21, false}, - // make sure other successes - {i1.GetPubKey(), d2, s12, true}, - {i2.GetPubKey(), d1, s21, true}, - {i2.GetPubKey(), d2, s22, true}, - } - - for i, tc := range cases { - valid := tc.key.VerifyBytes(tc.data, tc.sig) - assert.Equal(t, tc.valid, valid, "%d", i) - } - - // Now try to sign data with a secret-less key - _, _, err = cstore.Sign(n3, p3, d3) - assert.NotNil(t, err) -} - -func assertPassword(t *testing.T, cstore keys.Keybase, name, pass, badpass string) { - err := cstore.Update(name, badpass, pass) - assert.NotNil(t, err) - err = cstore.Update(name, pass, pass) - assert.Nil(t, err, "%+v", err) -} - -// TestExportImport tests exporting and importing keys. -func TestExportImport(t *testing.T) { - - // make the storage with reasonable defaults - db := dbm.NewMemDB() - cstore := keys.New( - db, - ) - - info, _, err := cstore.CreateMnemonic("john", keys.English,"secretcpw", keys.Secp256k1) - assert.NoError(t, err) - assert.Equal(t, info.GetName(), "john") - - john, err := cstore.Get("john") - assert.NoError(t, err) - assert.Equal(t, info.GetName(), "john") - johnAddr := info.GetPubKey().Address() - - armor, err := cstore.Export("john") - assert.NoError(t, err) - - err = cstore.Import("john2", armor) - assert.NoError(t, err) - - john2, err := cstore.Get("john2") - assert.NoError(t, err) - - assert.Equal(t, john.GetPubKey().Address(), johnAddr) - assert.Equal(t, john.GetName(), "john") - assert.Equal(t, john, john2) -} -// -func TestExportImportPubKey(t *testing.T) { - // make the storage with reasonable defaults - db := dbm.NewMemDB() - cstore := keys.New( - db, - ) - - // CreateMnemonic a private-public key pair and ensure consistency - notPasswd := "n9y25ah7" - info, _, err := cstore.CreateMnemonic("john", keys.English, notPasswd, keys.Secp256k1) - assert.Nil(t, err) - assert.NotEqual(t, info, "") - assert.Equal(t, info.GetName(), "john") - addr := info.GetPubKey().Address() - john, err := cstore.Get("john") - assert.NoError(t, err) - assert.Equal(t, john.GetName(), "john") - assert.Equal(t, john.GetPubKey().Address(), addr) - - // Export the public key only - armor, err := cstore.ExportPubKey("john") - assert.NoError(t, err) - // Import it under a different name - err = cstore.ImportPubKey("john-pubkey-only", armor) - assert.NoError(t, err) - // Ensure consistency - john2, err := cstore.Get("john-pubkey-only") - assert.NoError(t, err) - // Compare the public keys - assert.True(t, john.GetPubKey().Equals(john2.GetPubKey())) - // Ensure the original key hasn't changed - john, err = cstore.Get("john") - assert.NoError(t, err) - assert.Equal(t, john.GetPubKey().Address(), addr) - assert.Equal(t, john.GetName(), "john") - - // Ensure keys cannot be overwritten - err = cstore.ImportPubKey("john-pubkey-only", armor) - assert.NotNil(t, err) -} - -// TestAdvancedKeyManagement verifies update, import, export functionality -func TestAdvancedKeyManagement(t *testing.T) { - - // make the storage with reasonable defaults - cstore := keys.New( - dbm.NewMemDB(), - ) - - algo := keys.Secp256k1 - n1, n2 := "old-name", "new name" - p1, p2 := "1234", "foobar" - - // make sure key works with initial password - _, _, err := cstore.CreateMnemonic(n1, keys.English, p1, algo) - require.Nil(t, err, "%+v", err) - assertPassword(t, cstore, n1, p1, p2) - - // update password requires the existing password - err = cstore.Update(n1, "jkkgkg", p2) - assert.NotNil(t, err) - assertPassword(t, cstore, n1, p1, p2) - - // then it changes the password when correct - err = cstore.Update(n1, p1, p2) - assert.NoError(t, err) - // p2 is now the proper one! - assertPassword(t, cstore, n1, p2, p1) - - // exporting requires the proper name and passphrase - _, err = cstore.Export(n1 + ".notreal") - assert.NotNil(t, err) - _, err = cstore.Export(" " + n1) - assert.NotNil(t, err) - _, err = cstore.Export(n1 + " ") - assert.NotNil(t, err) - _, err = cstore.Export("") - assert.NotNil(t, err) - exported, err := cstore.Export(n1) - require.Nil(t, err, "%+v", err) - - // import succeeds - err = cstore.Import(n2, exported) - assert.NoError(t, err) - - // second import fails - err = cstore.Import(n2, exported) - assert.NotNil(t, err) -} - -// TestSeedPhrase verifies restoring from a seed phrase -func TestSeedPhrase(t *testing.T) { - - // make the storage with reasonable defaults - cstore := keys.New( - dbm.NewMemDB(), - ) - - algo := keys.Secp256k1 - n1, n2 := "lost-key", "found-again" - p1, p2 := "1234", "foobar" - - // make sure key works with initial password - info, mnemonic, err := cstore.CreateMnemonic(n1, keys.English, p1, algo) - require.Nil(t, err, "%+v", err) - assert.Equal(t, n1, info.GetName()) - assert.NotEmpty(t, mnemonic) - - // now, let us delete this key - err = cstore.Delete(n1, p1) - require.Nil(t, err, "%+v", err) - _, err = cstore.Get(n1) - require.NotNil(t, err) - - // let us re-create it from the mnemonic-phrase - params := *hd.NewFundraiserParams(0 ,0 ) - newInfo, err := cstore.Derive(n2,mnemonic, p2, params) - require.NoError(t, err) - assert.Equal(t, n2, newInfo.GetName()) - assert.Equal(t, info.GetPubKey().Address(), newInfo.GetPubKey().Address()) - assert.Equal(t, info.GetPubKey(), newInfo.GetPubKey()) -} - -func ExampleNew() { - // Select the encryption and storage for your cryptostore - cstore := keys.New( - dbm.NewMemDB(), - ) - - sec := keys.Secp256k1 - - // Add keys and see they return in alphabetical order - bob, _, err := cstore.CreateMnemonic("Bob", keys.English, "friend", sec) - if err != nil { - // this should never happen - fmt.Println(err) - } else { - // return info here just like in List - fmt.Println(bob.GetName()) - } - cstore.CreateMnemonic("Alice", keys.English, "secret", sec) - cstore.CreateMnemonic("Carl", keys.English, "mitm", sec) - info, _ := cstore.List() - for _, i := range info { - fmt.Println(i.GetName()) - } - - // We need to use passphrase to generate a signature - tx := []byte("deadbeef") - sig, pub, err := cstore.Sign("Bob", "friend", tx) - if err != nil { - fmt.Println("don't accept real passphrase") - } - - // and we can validate the signature with publicly available info - binfo, _ := cstore.Get("Bob") - if !binfo.GetPubKey().Equals(bob.GetPubKey()) { - fmt.Println("Get and Create return different keys") - } - - if pub.Equals(binfo.GetPubKey()) { - fmt.Println("signed by Bob") - } - if !pub.VerifyBytes(tx, sig) { - fmt.Println("invalid signature") - } - - // Output: - // Bob - // Alice - // Bob - // Carl - // signed by Bob -} diff --git a/keys/keys.go b/keys/keys.go deleted file mode 100644 index b3fad70f3..000000000 --- a/keys/keys.go +++ /dev/null @@ -1,12 +0,0 @@ -package keys - -// SigningAlgo defines an algorithm to derive key-pairs which can be used for cryptographic signing. -type SigningAlgo string - -const ( - // Secp256k1 uses the Bitcoin secp256k1 ECDSA parameters. - Secp256k1 = SigningAlgo("secp256k1") - // Ed25519 represents the Ed25519 signature system. - // It is currently not supported for end-user keys (wallets/ledgers). - Ed25519 = SigningAlgo("ed25519") -) \ No newline at end of file diff --git a/keys/keys.toml b/keys/keys.toml deleted file mode 100644 index f9eb95e1c..000000000 --- a/keys/keys.toml +++ /dev/null @@ -1,2 +0,0 @@ -output = "text" -keydir = ".mykeys" diff --git a/keys/mintkey.go b/keys/mintkey.go deleted file mode 100644 index 264a9747d..000000000 --- a/keys/mintkey.go +++ /dev/null @@ -1,115 +0,0 @@ -package keys - -import ( - "encoding/hex" - "fmt" - - cmn "github.com/tendermint/tmlibs/common" - - "github.com/tendermint/go-crypto" - "github.com/tendermint/go-crypto/keys/bcrypt" -) - -const ( - blockTypePrivKey = "TENDERMINT PRIVATE KEY" - blockTypeKeyInfo = "TENDERMINT KEY INFO" - blockTypePubKey = "TENDERMINT PUBLIC KEY" -) - -func armorInfoBytes(bz []byte) string { - return armorBytes(bz, blockTypeKeyInfo) -} - -func armorPubKeyBytes(bz []byte) string { - return armorBytes(bz, blockTypePubKey) -} - -func armorBytes(bz []byte, blockType string) string { - header := map[string]string{ - "type": "Info", - "version": "0.0.0", - } - return crypto.EncodeArmor(blockType, header, bz) -} - -func unarmorInfoBytes(armorStr string) (bz []byte, err error) { - return unarmorBytes(armorStr, blockTypeKeyInfo) -} - -func unarmorPubKeyBytes(armorStr string) (bz []byte, err error) { - return unarmorBytes(armorStr, blockTypePubKey) -} - -func unarmorBytes(armorStr, blockType string) (bz []byte, err error) { - bType, header, bz, err := crypto.DecodeArmor(armorStr) - if err != nil { - return - } - if bType != blockType { - err = fmt.Errorf("Unrecognized armor type %q, expected: %q", bType, blockType) - return - } - if header["version"] != "0.0.0" { - err = fmt.Errorf("Unrecognized version: %v", header["version"]) - return - } - return -} - -func encryptArmorPrivKey(privKey crypto.PrivKey, passphrase string) string { - saltBytes, encBytes := encryptPrivKey(privKey, passphrase) - header := map[string]string{ - "kdf": "bcrypt", - "salt": fmt.Sprintf("%X", saltBytes), - } - armorStr := crypto.EncodeArmor(blockTypePrivKey, header, encBytes) - return armorStr -} - -func unarmorDecryptPrivKey(armorStr string, passphrase string) (crypto.PrivKey, error) { - var privKey crypto.PrivKey - blockType, header, encBytes, err := crypto.DecodeArmor(armorStr) - if err != nil { - return privKey, err - } - if blockType != blockTypePrivKey { - return privKey, fmt.Errorf("Unrecognized armor type: %v", blockType) - } - if header["kdf"] != "bcrypt" { - return privKey, fmt.Errorf("Unrecognized KDF type: %v", header["KDF"]) - } - if header["salt"] == "" { - return privKey, fmt.Errorf("Missing salt bytes") - } - saltBytes, err := hex.DecodeString(header["salt"]) - if err != nil { - return privKey, fmt.Errorf("Error decoding salt: %v", err.Error()) - } - privKey, err = decryptPrivKey(saltBytes, encBytes, passphrase) - return privKey, err -} - -func encryptPrivKey(privKey crypto.PrivKey, passphrase string) (saltBytes []byte, encBytes []byte) { - saltBytes = crypto.CRandBytes(16) - key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 12) // TODO parameterize. 12 is good today (2016) - if err != nil { - cmn.Exit("Error generating bcrypt key from passphrase: " + err.Error()) - } - key = crypto.Sha256(key) // Get 32 bytes - privKeyBytes := privKey.Bytes() - return saltBytes, crypto.EncryptSymmetric(privKeyBytes, key) -} - -func decryptPrivKey(saltBytes []byte, encBytes []byte, passphrase string) (privKey crypto.PrivKey, err error) { - key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 12) // TODO parameterize. 12 is good today (2016) - if err != nil { - cmn.Exit("Error generating bcrypt key from passphrase: " + err.Error()) - } - key = crypto.Sha256(key) // Get 32 bytes - privKeyBytes, err := crypto.DecryptSymmetric(encBytes, key) - if err != nil { - return privKey, err - } - privKey, err = crypto.PrivKeyFromBytes(privKeyBytes) - return privKey, err -} diff --git a/keys/types.go b/keys/types.go deleted file mode 100644 index 09fbb399e..000000000 --- a/keys/types.go +++ /dev/null @@ -1,142 +0,0 @@ -package keys - -import ( - crypto "github.com/tendermint/go-crypto" - "github.com/tendermint/go-crypto/keys/hd" -) - -// Keybase exposes operations on a generic keystore -type Keybase interface { - - // CRUD on the keystore - List() ([]Info, error) - Get(name string) (Info, error) - Delete(name, passphrase string) error - - // Sign some bytes, looking up the private key to use - Sign(name, passphrase string, msg []byte) (crypto.Signature, crypto.PubKey, error) - - // CreateMnemonic creates a new mnemonic, and derives a hierarchical deterministic - // key from that. - CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, seed string, err error) - // CreateFundraiserKey takes a mnemonic and derives, a password - CreateFundraiserKey(name, mnemonic, passwd string) (info Info, err error) - // Derive derives a key from the passed mnemonic using a BIP44 path. - Derive(name, mnemonic, passwd string, params hd.BIP44Params) (Info, error) - // Create, store, and return a new Ledger key reference - CreateLedger(name string, path crypto.DerivationPath, algo SigningAlgo) (info Info, err error) - - // Create, store, and return a new offline key reference - CreateOffline(name string, pubkey crypto.PubKey) (info Info, err error) - - // The following operations will *only* work on locally-stored keys - Update(name, oldpass, newpass string) error - Import(name string, armor string) (err error) - ImportPubKey(name string, armor string) (err error) - Export(name string) (armor string, err error) - ExportPubKey(name string) (armor string, err error) -} - -// Info is the publicly exposed information about a keypair -type Info interface { - // Human-readable type for key listing - GetType() string - // Name of the key - GetName() string - // Public key - GetPubKey() crypto.PubKey -} - -var _ Info = &localInfo{} -var _ Info = &ledgerInfo{} -var _ Info = &offlineInfo{} - -// localInfo is the public information about a locally stored key -type localInfo struct { - Name string `json:"name"` - PubKey crypto.PubKey `json:"pubkey"` - PrivKeyArmor string `json:"privkey.armor"` -} - -func newLocalInfo(name string, pub crypto.PubKey, privArmor string) Info { - return &localInfo{ - Name: name, - PubKey: pub, - PrivKeyArmor: privArmor, - } -} - -func (i localInfo) GetType() string { - return "local" -} - -func (i localInfo) GetName() string { - return i.Name -} - -func (i localInfo) GetPubKey() crypto.PubKey { - return i.PubKey -} - -// ledgerInfo is the public information about a Ledger key -type ledgerInfo struct { - Name string `json:"name"` - PubKey crypto.PubKey `json:"pubkey"` - Path crypto.DerivationPath `json:"path"` -} - -func newLedgerInfo(name string, pub crypto.PubKey, path crypto.DerivationPath) Info { - return &ledgerInfo{ - Name: name, - PubKey: pub, - Path: path, - } -} - -func (i ledgerInfo) GetType() string { - return "ledger" -} - -func (i ledgerInfo) GetName() string { - return i.Name -} - -func (i ledgerInfo) GetPubKey() crypto.PubKey { - return i.PubKey -} - -// offlineInfo is the public information about an offline key -type offlineInfo struct { - Name string `json:"name"` - PubKey crypto.PubKey `json:"pubkey"` -} - -func newOfflineInfo(name string, pub crypto.PubKey) Info { - return &offlineInfo{ - Name: name, - PubKey: pub, - } -} - -func (i offlineInfo) GetType() string { - return "offline" -} - -func (i offlineInfo) GetName() string { - return i.Name -} - -func (i offlineInfo) GetPubKey() crypto.PubKey { - return i.PubKey -} - -// encoding info -func writeInfo(i Info) []byte { - return cdc.MustMarshalBinary(i) -} - -// decoding info -func readInfo(bz []byte) (info Info, err error) { - err = cdc.UnmarshalBinary(bz, &info) - return -} diff --git a/keys/wire.go b/keys/wire.go deleted file mode 100644 index 7cde0dd45..000000000 --- a/keys/wire.go +++ /dev/null @@ -1,16 +0,0 @@ -package keys - -import ( - amino "github.com/tendermint/go-amino" - crypto "github.com/tendermint/go-crypto" -) - -var cdc = amino.NewCodec() - -func init() { - crypto.RegisterAmino(cdc) - cdc.RegisterInterface((*Info)(nil), nil) - cdc.RegisterConcrete(localInfo{}, "crypto/keys/localInfo", nil) - cdc.RegisterConcrete(ledgerInfo{}, "crypto/keys/ledgerInfo", nil) - cdc.RegisterConcrete(offlineInfo{}, "crypto/keys/offlineInfo", nil) -} From 7ebc7c08e7de58540762d6ab2fc688677bef80c9 Mon Sep 17 00:00:00 2001 From: Liamsi Date: Wed, 20 Jun 2018 14:30:57 -0700 Subject: [PATCH 272/287] delete keys package - also delete ledger code and deps (thx cwgoes) Signed-off-by: Liamsi --- Gopkg.toml | 12 ----- Makefile | 2 +- amino.go | 2 - encode_test.go | 1 - ledger_common.go | 19 ------- ledger_secp256k1.go | 124 -------------------------------------------- ledger_test.go | 63 ---------------------- 7 files changed, 1 insertion(+), 222 deletions(-) delete mode 100644 ledger_common.go delete mode 100644 ledger_secp256k1.go delete mode 100644 ledger_test.go diff --git a/Gopkg.toml b/Gopkg.toml index 92bfecacd..a614df866 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -28,10 +28,6 @@ name = "github.com/btcsuite/btcutil" branch = "master" -[[constraint]] - name = "github.com/pkg/errors" - version = "0.8.0" - [[constraint]] name = "github.com/stretchr/testify" version = "1.2.1" @@ -48,14 +44,6 @@ name = "github.com/tendermint/tmlibs" version = "0.8.1" -[[constraint]] - name = "github.com/tyler-smith/go-bip39" - branch = "master" - -[[constraint]] - name = "github.com/zondax/ledger-goclient" - revision = "065cbf938a16f20335c40cfe180f9cd4955c6a5a" - [prune] go-tests = true unused-packages = true diff --git a/Makefile b/Makefile index 96f4ae06d..a4fd3c37f 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ get_vendor_deps: ### Testing test: - go test -p 1 $(shell go list ./... | grep -v vendor) + CGO_ENABLED=0 go test -p 1 $(shell go list ./... | grep -v vendor) ######################################## ### Formatting, linting, and vetting diff --git a/amino.go b/amino.go index 63e4c4ac3..2a57afdee 100644 --- a/amino.go +++ b/amino.go @@ -28,8 +28,6 @@ func RegisterAmino(cdc *amino.Codec) { "tendermint/PrivKeyEd25519", nil) cdc.RegisterConcrete(PrivKeySecp256k1{}, "tendermint/PrivKeySecp256k1", nil) - cdc.RegisterConcrete(PrivKeyLedgerSecp256k1{}, - "tendermint/PrivKeyLedgerSecp256k1", nil) cdc.RegisterInterface((*Signature)(nil), nil) cdc.RegisterConcrete(SignatureEd25519{}, diff --git a/encode_test.go b/encode_test.go index 025b09c80..a122f20e2 100644 --- a/encode_test.go +++ b/encode_test.go @@ -50,7 +50,6 @@ func ExamplePrintRegisteredTypes() { //| PubKeySecp256k1 | tendermint/PubKeySecp256k1 | 0xEB5AE987 | 0x21 | | //| PrivKeyEd25519 | tendermint/PrivKeyEd25519 | 0xA3288910 | 0x40 | | //| PrivKeySecp256k1 | tendermint/PrivKeySecp256k1 | 0xE1B0F79B | 0x20 | | - //| PrivKeyLedgerSecp256k1 | tendermint/PrivKeyLedgerSecp256k1 | 0x10CAB393 | variable | | //| SignatureEd25519 | tendermint/SignatureEd25519 | 0x2031EA53 | 0x40 | | //| SignatureSecp256k1 | tendermint/SignatureSecp256k1 | 0x7FC4A495 | variable | | } diff --git a/ledger_common.go b/ledger_common.go deleted file mode 100644 index 39f15464a..000000000 --- a/ledger_common.go +++ /dev/null @@ -1,19 +0,0 @@ -package crypto - -import ( - ledger "github.com/zondax/ledger-goclient" -) - -var device *ledger.Ledger - -// Ledger derivation path -type DerivationPath = []uint32 - -// getLedger gets a copy of the device, and caches it -func getLedger() (*ledger.Ledger, error) { - var err error - if device == nil { - device, err = ledger.FindLedger() - } - return device, err -} diff --git a/ledger_secp256k1.go b/ledger_secp256k1.go deleted file mode 100644 index 21dfbb8b5..000000000 --- a/ledger_secp256k1.go +++ /dev/null @@ -1,124 +0,0 @@ -package crypto - -import ( - "fmt" - - secp256k1 "github.com/btcsuite/btcd/btcec" - ledger "github.com/zondax/ledger-goclient" -) - -func pubkeyLedgerSecp256k1(device *ledger.Ledger, path DerivationPath) (pub PubKey, err error) { - key, err := device.GetPublicKeySECP256K1(path) - if err != nil { - return nil, fmt.Errorf("error fetching public key: %v", err) - } - var p PubKeySecp256k1 - // Reserialize in the 33-byte compressed format - cmp, err := secp256k1.ParsePubKey(key[:], secp256k1.S256()) - copy(p[:], cmp.SerializeCompressed()) - pub = p - return -} - -func signLedgerSecp256k1(device *ledger.Ledger, path DerivationPath, msg []byte) (sig Signature, err error) { - bsig, err := device.SignSECP256K1(path, msg) - if err != nil { - return sig, err - } - sig = SignatureSecp256k1FromBytes(bsig) - return -} - -// PrivKeyLedgerSecp256k1 implements PrivKey, calling the ledger nano -// we cache the PubKey from the first call to use it later -type PrivKeyLedgerSecp256k1 struct { - // PubKey should be private, but we want to encode it via go-amino - // so we can view the address later, even without having the ledger - // attached - CachedPubKey PubKey - Path DerivationPath -} - -// NewPrivKeyLedgerSecp256k1 will generate a new key and store the -// public key for later use. -func NewPrivKeyLedgerSecp256k1(path DerivationPath) (PrivKey, error) { - var pk PrivKeyLedgerSecp256k1 - pk.Path = path - // cache the pubkey for later use - pubKey, err := pk.getPubKey() - if err != nil { - return nil, err - } - pk.CachedPubKey = pubKey - return &pk, err -} - -// ValidateKey allows us to verify the sanity of a key -// after loading it from disk -func (pk PrivKeyLedgerSecp256k1) ValidateKey() error { - // getPubKey will return an error if the ledger is not - pub, err := pk.getPubKey() - if err != nil { - return err - } - // verify this matches cached address - if !pub.Equals(pk.CachedPubKey) { - return fmt.Errorf("cached key does not match retrieved key") - } - return nil -} - -// AssertIsPrivKeyInner fulfils PrivKey Interface -func (pk *PrivKeyLedgerSecp256k1) AssertIsPrivKeyInner() {} - -// Bytes fulfils PrivKey Interface - but it stores the cached pubkey so we can verify -// the same key when we reconnect to a ledger -func (pk PrivKeyLedgerSecp256k1) Bytes() []byte { - return cdc.MustMarshalBinaryBare(pk) -} - -// Sign calls the ledger and stores the PubKey for future use -// -// Communication is checked on NewPrivKeyLedger and PrivKeyFromBytes, -// returning an error, so this should only trigger if the privkey is held -// in memory for a while before use. -func (pk PrivKeyLedgerSecp256k1) Sign(msg []byte) (Signature, error) { - dev, err := getLedger() - if err != nil { - return nil, err - } - sig, err := signLedgerSecp256k1(dev, pk.Path, msg) - if err != nil { - return nil, err - } - return sig, nil -} - -// PubKey returns the stored PubKey -func (pk PrivKeyLedgerSecp256k1) PubKey() PubKey { - return pk.CachedPubKey -} - -// getPubKey reads the pubkey the ledger itself -// since this involves IO, it may return an error, which is not exposed -// in the PubKey interface, so this function allows better error handling -func (pk PrivKeyLedgerSecp256k1) getPubKey() (key PubKey, err error) { - dev, err := getLedger() - if err != nil { - return key, fmt.Errorf("cannot connect to Ledger device - error: %v", err) - } - key, err = pubkeyLedgerSecp256k1(dev, pk.Path) - if err != nil { - return key, fmt.Errorf("please open Cosmos app on the Ledger device - error: %v", err) - } - return key, err -} - -// Equals fulfils PrivKey Interface - makes sure both keys refer to the -// same -func (pk PrivKeyLedgerSecp256k1) Equals(other PrivKey) bool { - if ledger, ok := other.(*PrivKeyLedgerSecp256k1); ok { - return pk.CachedPubKey.Equals(ledger.CachedPubKey) - } - return false -} diff --git a/ledger_test.go b/ledger_test.go deleted file mode 100644 index 83390cc36..000000000 --- a/ledger_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package crypto - -import ( - "os" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestRealLedgerSecp256k1(t *testing.T) { - - if os.Getenv("WITH_LEDGER") == "" { - t.Skip("Set WITH_LEDGER to run code on real ledger") - } - msg := []byte("kuhehfeohg") - - path := DerivationPath{44, 60, 0, 0, 0} - - priv, err := NewPrivKeyLedgerSecp256k1(path) - require.Nil(t, err, "%+v", err) - pub := priv.PubKey() - sig, err := priv.Sign(msg) - require.Nil(t, err) - - valid := pub.VerifyBytes(msg, sig) - assert.True(t, valid) - - // now, let's serialize the key and make sure it still works - bs := priv.Bytes() - priv2, err := PrivKeyFromBytes(bs) - require.Nil(t, err, "%+v", err) - - // make sure we get the same pubkey when we load from disk - pub2 := priv2.PubKey() - require.Equal(t, pub, pub2) - - // signing with the loaded key should match the original pubkey - sig, err = priv2.Sign(msg) - require.Nil(t, err) - valid = pub.VerifyBytes(msg, sig) - assert.True(t, valid) - - // make sure pubkeys serialize properly as well - bs = pub.Bytes() - bpub, err := PubKeyFromBytes(bs) - require.NoError(t, err) - assert.Equal(t, pub, bpub) -} - -// TestRealLedgerErrorHandling calls. These tests assume -// the ledger is not plugged in.... -func TestRealLedgerErrorHandling(t *testing.T) { - if os.Getenv("WITH_LEDGER") != "" { - t.Skip("Skipping on WITH_LEDGER as it tests unplugged cases") - } - - // first, try to generate a key, must return an error - // (no panic) - path := DerivationPath{44, 60, 0, 0, 0} - _, err := NewPrivKeyLedgerSecp256k1(path) - require.Error(t, err) -} From c7a842a4e2c339aa5dd812735211ffbcc25bce24 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 20 Jun 2018 23:31:57 +0200 Subject: [PATCH 273/287] Update Gopkg.lock --- Gopkg.lock | 67 +++++------------------------------------------------- 1 file changed, 6 insertions(+), 61 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 83fe33bd7..7dbe6ae72 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1,18 +1,6 @@ # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. -[[projects]] - branch = "master" - name = "github.com/bartekn/go-bip39" - packages = ["."] - revision = "a05967ea095d81c8fe4833776774cfaff8e5036c" - -[[projects]] - branch = "master" - name = "github.com/brejski/hid" - packages = ["."] - revision = "06112dcfcc50a7e0e4fd06e17f9791e788fdaafc" - [[projects]] branch = "master" name = "github.com/btcsuite/btcd" @@ -63,18 +51,6 @@ revision = "1adfc126b41513cc696b209667c8656ea7aac67c" version = "v1.0.0" -[[projects]] - branch = "master" - name = "github.com/golang/snappy" - packages = ["."] - revision = "2e65f85255dbc3072edf28d6b5b8efc472979f5a" - -[[projects]] - branch = "master" - name = "github.com/jmhodges/levigo" - packages = ["."] - revision = "c42d9e0ca023e2198120196f842701bb4c55d7b9" - [[projects]] branch = "master" name = "github.com/kr/logfmt" @@ -102,25 +78,6 @@ revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686" version = "v1.2.2" -[[projects]] - branch = "master" - name = "github.com/syndtr/goleveldb" - packages = [ - "leveldb", - "leveldb/cache", - "leveldb/comparer", - "leveldb/errors", - "leveldb/filter", - "leveldb/iterator", - "leveldb/journal", - "leveldb/memdb", - "leveldb/opt", - "leveldb/storage", - "leveldb/table", - "leveldb/util" - ] - revision = "e2150783cd35f5b607daca48afd8c57ec54cc995" - [[projects]] branch = "master" name = "github.com/tendermint/ed25519" @@ -134,31 +91,19 @@ [[projects]] name = "github.com/tendermint/go-amino" packages = ["."] - revision = "1715b7b78c65d6adcc5937315be4710234cefe09" - version = "0.10.0-rc2" + revision = "2106ca61d91029c931fd54968c2bb02dc96b1412" + version = "0.10.1" [[projects]] name = "github.com/tendermint/tmlibs" packages = [ "common", - "db", "log", "test" ] revision = "692f1d86a6e2c0efa698fd1e4541b68c74ffaf38" version = "v0.8.4" -[[projects]] - branch = "master" - name = "github.com/tyler-smith/go-bip39" - packages = ["."] - revision = "8e7a99b3e716f36d3b080a9a70f9eb45abe4edcc" - -[[projects]] - name = "github.com/zondax/ledger-goclient" - packages = ["."] - revision = "065cbf938a16f20335c40cfe180f9cd4955c6a5a" - [[projects]] branch = "master" name = "golang.org/x/crypto" @@ -168,25 +113,25 @@ "chacha20poly1305", "hkdf", "internal/chacha20", + "internal/subtle", "nacl/secretbox", "openpgp/armor", "openpgp/errors", - "pbkdf2", "poly1305", "ripemd160", "salsa20/salsa" ] - revision = "8ac0e0d97ce45cd83d1d7243c060cb8461dda5e9" + revision = "7f39a6fea4fe9364fb61e1def6a268a51b4f3a06" [[projects]] branch = "master" name = "golang.org/x/sys" packages = ["cpu"] - revision = "a9e25c09b96b8870693763211309e213c6ef299d" + revision = "ad87a3a340fa7f3bed189293fbfa7a9b7e021ae1" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "684746f2b651a722ee32eae056b437baf7a2213d68ddbfcefe04a1c3df27c93b" + inputs-digest = "027b22b86396a971d5d5c1d298947f531f39743975d65a22e98601140aa1b1a1" solver-name = "gps-cdcl" solver-version = 1 From 96a3502126561f500ddfcfc98f2455a64ba3caba Mon Sep 17 00:00:00 2001 From: Liamsi Date: Wed, 20 Jun 2018 15:19:08 -0700 Subject: [PATCH 274/287] delete everything --- CHANGELOG.md | 868 --------- CODE_OF_CONDUCT.md | 56 - CONTRIBUTING.md | 117 -- DOCKER/.gitignore | 1 - DOCKER/Dockerfile | 39 - DOCKER/Dockerfile.develop | 35 - DOCKER/Dockerfile.testing | 18 - DOCKER/Makefile | 16 - DOCKER/README.md | 67 - DOCKER/build.sh | 20 - DOCKER/push.sh | 22 - Gopkg.lock | 431 ----- Gopkg.toml | 103 - LICENSE | 204 -- Makefile | 236 --- README.md | 138 -- ROADMAP.md | 23 - SECURITY.md | 71 - Vagrantfile | 58 - appveyor.yml | 13 - benchmarks/atomic_test.go | 29 - benchmarks/blockchain/.gitignore | 2 - benchmarks/blockchain/localsync.sh | 80 - benchmarks/chan_test.go | 19 - benchmarks/codec_test.go | 129 -- benchmarks/empty.go | 1 - benchmarks/map_test.go | 35 - benchmarks/os_test.go | 33 - benchmarks/proto/README | 2 - benchmarks/proto/test.pb.go | 1456 -------------- benchmarks/proto/test.proto | 29 - benchmarks/simu/counter.go | 47 - blockchain/pool.go | 587 ------ blockchain/pool_test.go | 148 -- blockchain/reactor.go | 405 ---- blockchain/reactor_test.go | 208 -- blockchain/store.go | 247 --- blockchain/store_test.go | 383 ---- blockchain/wire.go | 13 - cmd/priv_val_server/main.go | 53 - cmd/tendermint/commands/gen_node_key.go | 32 - cmd/tendermint/commands/gen_validator.go | 27 - cmd/tendermint/commands/init.go | 70 - cmd/tendermint/commands/lite.go | 87 - cmd/tendermint/commands/probe_upnp.go | 31 - cmd/tendermint/commands/replay.go | 26 - .../commands/reset_priv_validator.go | 69 - cmd/tendermint/commands/root.go | 63 - cmd/tendermint/commands/root_test.go | 176 -- cmd/tendermint/commands/run_node.go | 72 - cmd/tendermint/commands/show_node_id.go | 27 - cmd/tendermint/commands/show_validator.go | 22 - cmd/tendermint/commands/testnet.go | 183 -- cmd/tendermint/commands/version.go | 18 - cmd/tendermint/commands/wire.go | 12 - cmd/tendermint/main.go | 48 - codecov.yml | 23 - config/config.go | 632 ------- config/config_test.go | 28 - config/toml.go | 324 ---- config/toml_test.go | 94 - consensus/README.md | 1 - consensus/byzantine_test.go | 267 --- consensus/common_test.go | 495 ----- consensus/mempool_test.go | 232 --- consensus/metrics.go | 133 -- consensus/reactor.go | 1459 -------------- consensus/reactor_test.go | 538 ------ consensus/replay.go | 469 ----- consensus/replay_file.go | 321 ---- consensus/replay_test.go | 687 ------- consensus/state.go | 1673 ----------------- consensus/state_test.go | 1099 ----------- consensus/test_data/many_blocks.cswal | Bin 11137 -> 0 bytes consensus/ticker.go | 134 -- consensus/types/height_vote_set.go | 261 --- consensus/types/height_vote_set_test.go | 69 - consensus/types/peer_round_state.go | 57 - consensus/types/round_state.go | 164 -- consensus/types/round_state_test.go | 95 - consensus/types/wire.go | 12 - consensus/version.go | 13 - consensus/wal.go | 323 ---- consensus/wal_fuzz.go | 31 - consensus/wal_generator.go | 205 -- consensus/wal_test.go | 133 -- consensus/wire.go | 14 - docker-compose.yml | 68 - docs/.python-version | 1 - docs/Makefile | 23 - docs/README.md | 14 - docs/_static/custom_collapsible_code.css | 17 - docs/_static/custom_collapsible_code.js | 10 - docs/_templates/layout.html | 20 - docs/abci-cli.md | 329 ---- docs/app-architecture.md | 50 - docs/app-development.md | 527 ------ docs/architecture/README.md | 5 - docs/architecture/adr-001-logging.md | 216 --- .../adr-002-event-subscription.md | 90 - docs/architecture/adr-003-abci-app-rpc.md | 34 - .../adr-004-historical-validators.md | 38 - docs/architecture/adr-005-consensus-params.md | 86 - docs/architecture/adr-006-trust-metric.md | 238 --- .../adr-007-trust-metric-usage.md | 103 - docs/architecture/adr-008-priv-validator.md | 29 - docs/architecture/adr-011-monitoring.md | 116 -- docs/architecture/adr-template.md | 16 - docs/architecture/img/formula1.png | Bin 9833 -> 0 bytes docs/architecture/img/formula2.png | Bin 5942 -> 0 bytes docs/architecture/img/tags1.png | Bin 10446 -> 0 bytes docs/assets/a_plus_t.png | Bin 13830 -> 0 bytes docs/assets/abci.png | Bin 44405 -> 0 bytes docs/assets/consensus_logic.png | Bin 105454 -> 0 bytes docs/assets/tm-application-example.png | Bin 26691 -> 0 bytes docs/assets/tm-transaction-flow.png | Bin 2488459 -> 0 bytes docs/assets/tmint-logo-blue.png | Bin 53596 -> 0 bytes docs/conf.py | 206 -- docs/deploy-testnets.md | 68 - docs/determinism.md | 5 - docs/ecosystem.md | 21 - docs/examples/getting-started.md | 149 -- docs/examples/init_testnet.sh | 69 - docs/examples/install_tendermint.sh | 32 - docs/examples/node0/config/config.toml | 166 -- docs/examples/node0/config/genesis.json | 39 - docs/examples/node0/config/node_key.json | 1 - .../examples/node0/config/priv_validator.json | 14 - docs/examples/node1/config/config.toml | 166 -- docs/examples/node1/config/genesis.json | 39 - docs/examples/node1/config/node_key.json | 1 - .../examples/node1/config/priv_validator.json | 14 - docs/examples/node2/config/config.toml | 166 -- docs/examples/node2/config/genesis.json | 39 - docs/examples/node2/config/node_key.json | 1 - .../examples/node2/config/priv_validator.json | 14 - docs/examples/node3/config/config.toml | 166 -- docs/examples/node3/config/genesis.json | 39 - docs/examples/node3/config/node_key.json | 1 - .../examples/node3/config/priv_validator.json | 14 - docs/getting-started.md | 265 --- docs/how-to-read-logs.md | 130 -- docs/images/tmint-logo-blue.png | Bin 53596 -> 0 bytes docs/index.rst | 73 - docs/indexing-transactions.md | 89 - docs/install.md | 76 - docs/introduction.md | 331 ---- docs/metrics.md | 40 - docs/requirements.txt | 4 - docs/running-in-production.md | 206 -- docs/spec/README.md | 80 - docs/spec/blockchain/blockchain.md | 431 ----- docs/spec/blockchain/encoding.md | 274 --- docs/spec/blockchain/state.md | 80 - docs/spec/consensus/abci.md | 1 - docs/spec/consensus/bft-time.md | 56 - docs/spec/consensus/consensus.md | 9 - docs/spec/consensus/light-client.md | 114 -- docs/spec/consensus/wal.md | 1 - docs/spec/p2p/config.md | 38 - docs/spec/p2p/connection.md | 110 -- docs/spec/p2p/node.md | 65 - docs/spec/p2p/peer.md | 112 -- .../reactors/block_sync/img/bc-reactor.png | Bin 44211 -> 0 bytes docs/spec/reactors/block_sync/impl.md | 46 - docs/spec/reactors/block_sync/reactor.md | 307 --- .../reactors/consensus/consensus-reactor.md | 352 ---- docs/spec/reactors/consensus/consensus.md | 212 --- .../reactors/consensus/proposer-selection.md | 46 - docs/spec/reactors/evidence/reactor.md | 10 - docs/spec/reactors/mempool/concurrency.md | 8 - docs/spec/reactors/mempool/config.md | 59 - docs/spec/reactors/mempool/functionality.md | 37 - docs/spec/reactors/mempool/messages.md | 61 - docs/spec/reactors/mempool/reactor.md | 14 - docs/spec/reactors/pex/pex.md | 123 -- docs/spec/reactors/pex/reactor.md | 12 - docs/spec/scripts/crypto.go | 125 -- docs/spec/software/abci.md | 192 -- docs/spec/software/wal.md | 33 - docs/specification.rst | 21 - docs/specification/block-structure.rst | 220 --- .../byzantine-consensus-algorithm.rst | 349 ---- docs/specification/configuration.md | 200 -- docs/specification/corruption.rst | 70 - docs/specification/fast-sync.rst | 34 - docs/specification/genesis.rst | 71 - docs/specification/light-client-protocol.rst | 33 - docs/specification/merkle.rst | 88 - docs/specification/new-spec/README.md | 1 - docs/specification/rpc.md | 3 - docs/specification/secure-p2p.rst | 78 - docs/specification/validators.rst | 44 - docs/specification/wire-protocol.rst | 172 -- docs/subscribing-to-events-via-websocket.md | 26 - docs/terraform-and-ansible.md | 168 -- docs/transactional-semantics.md | 25 - docs/using-tendermint.md | 420 ----- evidence/pool.go | 152 -- evidence/pool_test.go | 79 - evidence/reactor.go | 227 --- evidence/reactor_test.go | 182 -- evidence/store.go | 190 -- evidence/store_test.go | 109 -- evidence/wire.go | 25 - libs/events/Makefile | 9 - libs/events/README.md | 175 -- libs/events/event_cache.go | 37 - libs/events/event_cache_test.go | 35 - libs/events/events.go | 220 --- libs/events/events_test.go | 380 ---- libs/pubsub/example_test.go | 28 - libs/pubsub/pubsub.go | 351 ---- libs/pubsub/pubsub_test.go | 253 --- libs/pubsub/query/Makefile | 11 - libs/pubsub/query/empty.go | 16 - libs/pubsub/query/empty_test.go | 18 - libs/pubsub/query/fuzz_test/main.go | 30 - libs/pubsub/query/parser_test.go | 92 - libs/pubsub/query/query.go | 339 ---- libs/pubsub/query/query.peg | 33 - libs/pubsub/query/query.peg.go | 1553 --------------- libs/pubsub/query/query_test.go | 87 - lite/client/main_test.go | 25 - lite/client/provider.go | 141 -- lite/client/provider_test.go | 63 - lite/commit.go | 99 - lite/doc.go | 133 -- lite/dynamic_certifier.go | 96 - lite/dynamic_certifier_test.go | 130 -- lite/errors/errors.go | 92 - lite/errors/errors_test.go | 18 - lite/files/commit.go | 93 - lite/files/commit_test.go | 66 - lite/files/provider.go | 139 -- lite/files/provider_test.go | 96 - lite/files/wire.go | 12 - lite/helpers.go | 153 -- lite/inquiring_certifier.go | 163 -- lite/inquiring_certifier_test.go | 173 -- lite/memprovider.go | 152 -- lite/performance_test.go | 365 ---- lite/provider.go | 103 - lite/provider_test.go | 149 -- lite/proxy/block.go | 49 - lite/proxy/certifier.go | 35 - lite/proxy/errors.go | 22 - lite/proxy/errors_test.go | 17 - lite/proxy/proxy.go | 77 - lite/proxy/query.go | 152 -- lite/proxy/query_test.go | 139 -- lite/proxy/validate_test.go | 218 --- lite/proxy/wrapper.go | 187 -- lite/static_certifier.go | 73 - lite/static_certifier_test.go | 59 - mempool/mempool.go | 524 ------ mempool/mempool_test.go | 286 --- mempool/metrics.go | 34 - mempool/reactor.go | 188 -- mempool/reactor_test.go | 157 -- mempool/wire.go | 11 - networks/local/Makefile | 7 - networks/local/README.md | 79 - networks/local/localnode/Dockerfile | 16 - networks/local/localnode/wrapper.sh | 35 - networks/remote/README.md | 3 - networks/remote/ansible/.gitignore | 1 - networks/remote/ansible/ansible.cfg | 4 - networks/remote/ansible/config.yml | 18 - networks/remote/ansible/install.yml | 11 - networks/remote/ansible/inventory/COPYING | 675 ------- .../ansible/inventory/digital_ocean.ini | 34 - .../remote/ansible/inventory/digital_ocean.py | 471 ----- networks/remote/ansible/logzio.yml | 14 - networks/remote/ansible/reset.yml | 14 - networks/remote/ansible/restart.yml | 12 - .../ansible/roles/config/tasks/main.yml | 17 - .../ansible/roles/install/handlers/main.yml | 5 - .../ansible/roles/install/tasks/main.yml | 15 - .../install/templates/systemd.service.j2 | 17 - .../roles/logzio/files/journalbeat.service | 15 - .../ansible/roles/logzio/handlers/main.yml | 8 - .../ansible/roles/logzio/tasks/main.yml | 27 - .../roles/logzio/templates/journalbeat.yml.j2 | 342 ---- .../remote/ansible/roles/start/tasks/main.yml | 5 - .../ansible/roles/status/tasks/main.yml | 10 - .../remote/ansible/roles/stop/tasks/main.yml | 5 - .../ansible/roles/unsafe_reset/tasks/main.yml | 4 - networks/remote/ansible/start.yml | 11 - networks/remote/ansible/status.yml | 11 - networks/remote/ansible/stop.yml | 11 - networks/remote/integration.sh | 132 -- networks/remote/terraform/.gitignore | 4 - networks/remote/terraform/cluster/main.tf | 28 - networks/remote/terraform/cluster/outputs.tf | 15 - .../remote/terraform/cluster/variables.tf | 25 - networks/remote/terraform/main.tf | 37 - node/id.go | 35 - node/node.go | 730 ------- node/node_test.go | 48 - node/wire.go | 12 - p2p/README.md | 11 - p2p/base_reactor.go | 53 - p2p/conn/conn_go110.go | 15 - p2p/conn/conn_notgo110.go | 32 - p2p/conn/connection.go | 784 -------- p2p/conn/connection_test.go | 500 ----- p2p/conn/secret_connection.go | 348 ---- p2p/conn/secret_connection_test.go | 250 --- p2p/conn/wire.go | 13 - p2p/dummy/peer.go | 80 - p2p/errors.go | 76 - p2p/fuzz.go | 152 -- p2p/key.go | 111 -- p2p/key_test.go | 50 - p2p/listener.go | 226 --- p2p/listener_test.go | 47 - p2p/metrics.go | 33 - p2p/netaddress.go | 317 ---- p2p/netaddress_test.go | 148 -- p2p/node_info.go | 164 -- p2p/peer.go | 431 ----- p2p/peer_set.go | 143 -- p2p/peer_set_test.go | 172 -- p2p/peer_test.go | 175 -- p2p/pex/addrbook.go | 813 -------- p2p/pex/addrbook_test.go | 356 ---- p2p/pex/errors.go | 32 - p2p/pex/file.go | 83 - p2p/pex/known_address.go | 141 -- p2p/pex/params.go | 55 - p2p/pex/pex_reactor.go | 700 ------- p2p/pex/pex_reactor_test.go | 459 ----- p2p/pex/wire.go | 11 - p2p/switch.go | 662 ------- p2p/switch_test.go | 428 ----- p2p/test_util.go | 156 -- p2p/trust/config.go | 55 - p2p/trust/metric.go | 411 ---- p2p/trust/metric_test.go | 100 - p2p/trust/store.go | 207 -- p2p/trust/store_test.go | 152 -- p2p/trust/ticker.go | 62 - p2p/types.go | 8 - p2p/upnp/probe.go | 112 -- p2p/upnp/upnp.go | 393 ---- p2p/version.go | 3 - p2p/wire.go | 12 - privval/priv_validator.go | 345 ---- privval/priv_validator_test.go | 251 --- privval/socket.go | 538 ------ privval/socket_tcp.go | 66 - privval/socket_tcp_test.go | 64 - privval/socket_test.go | 282 --- privval/wire.go | 13 - proxy/app_conn.go | 144 -- proxy/app_conn_test.go | 152 -- proxy/client.go | 81 - proxy/multi_app_conn.go | 112 -- rpc/client/event_test.go | 149 -- rpc/client/helpers.go | 80 - rpc/client/helpers_test.go | 76 - rpc/client/httpclient.go | 373 ---- rpc/client/interface.go | 95 - rpc/client/localclient.go | 145 -- rpc/client/main_test.go | 24 - rpc/client/mock/abci.go | 202 -- rpc/client/mock/abci_test.go | 181 -- rpc/client/mock/client.go | 135 -- rpc/client/mock/status.go | 52 - rpc/client/mock/status_test.go | 48 - rpc/client/rpc_test.go | 366 ---- rpc/client/types.go | 12 - rpc/core/README.md | 20 - rpc/core/abci.go | 95 - rpc/core/blocks.go | 364 ---- rpc/core/consensus.go | 261 --- rpc/core/dev.go | 51 - rpc/core/doc.go | 109 -- rpc/core/doc_template.txt | 8 - rpc/core/events.go | 188 -- rpc/core/health.go | 31 - rpc/core/mempool.go | 276 --- rpc/core/net.go | 127 -- rpc/core/pipe.go | 147 -- rpc/core/pipe_test.go | 69 - rpc/core/routes.go | 52 - rpc/core/status.go | 133 -- rpc/core/tx.go | 219 --- rpc/core/types/responses.go | 210 --- rpc/core/types/responses_test.go | 39 - rpc/core/types/wire.go | 13 - rpc/core/version.go | 5 - rpc/grpc/api.go | 36 - rpc/grpc/client_server.go | 44 - rpc/grpc/compile.sh | 3 - rpc/grpc/grpc_test.go | 33 - rpc/grpc/types.pb.go | 230 --- rpc/grpc/types.proto | 36 - rpc/lib/client/args_test.go | 43 - rpc/lib/client/http_client.go | 219 --- rpc/lib/client/integration_test.go | 66 - rpc/lib/client/ws_client.go | 494 ----- rpc/lib/client/ws_client_test.go | 224 --- rpc/lib/doc.go | 103 - rpc/lib/rpc_test.go | 378 ---- rpc/lib/server/handlers.go | 794 -------- rpc/lib/server/handlers_test.go | 159 -- rpc/lib/server/http_params.go | 90 - rpc/lib/server/http_server.go | 156 -- rpc/lib/server/parse_test.go | 176 -- rpc/lib/test/data.json | 9 - rpc/lib/test/integration_test.sh | 95 - rpc/lib/test/main.go | 40 - rpc/lib/types/types.go | 187 -- rpc/lib/types/types_test.go | 51 - rpc/lib/version.go | 7 - rpc/test/helpers.go | 132 -- scripts/README.md | 1 - scripts/dep_utils/parse.sh | 14 - scripts/dist.sh | 81 - scripts/install/install_tendermint_bsd.sh | 54 - scripts/install/install_tendermint_ubuntu.sh | 49 - scripts/install_abci_apps.sh | 12 - scripts/publish.sh | 20 - scripts/release.sh | 53 - scripts/slate.sh | 77 - scripts/txs/random.sh | 19 - scripts/wal2json/main.go | 59 - scripts/wire2amino.go | 181 -- state/errors.go | 79 - state/execution.go | 398 ---- state/execution_test.go | 232 --- state/services.go | 86 - state/state.go | 187 -- state/state_test.go | 489 ----- state/store.go | 282 --- state/txindex/indexer.go | 58 - state/txindex/indexer_service.go | 73 - state/txindex/kv/kv.go | 437 ----- state/txindex/kv/kv_test.go | 239 --- state/txindex/kv/wire.go | 10 - state/txindex/null/null.go | 33 - state/validation.go | 125 -- state/validation_test.go | 68 - state/wire.go | 12 - test/README.md | 21 - test/app/clean.sh | 3 - test/app/counter_test.sh | 141 -- test/app/grpc_client.go | 42 - test/app/kvstore_test.sh | 84 - test/app/test.sh | 129 -- test/docker/Dockerfile | 38 - test/docker/build.sh | 3 - test/p2p/README.md | 54 - test/p2p/atomic_broadcast/test.sh | 75 - test/p2p/basic/test.sh | 74 - test/p2p/circleci.sh | 35 - test/p2p/client.sh | 19 - test/p2p/data/mach1/core/config/genesis.json | 39 - test/p2p/data/mach1/core/config/node_key.json | 6 - .../mach1/core/config/priv_validator.json | 14 - test/p2p/data/mach2/core/config/genesis.json | 39 - test/p2p/data/mach2/core/config/node_key.json | 6 - .../mach2/core/config/priv_validator.json | 14 - test/p2p/data/mach3/core/config/genesis.json | 39 - test/p2p/data/mach3/core/config/node_key.json | 6 - .../mach3/core/config/priv_validator.json | 14 - test/p2p/data/mach4/core/config/genesis.json | 39 - test/p2p/data/mach4/core/config/node_key.json | 6 - .../mach4/core/config/priv_validator.json | 14 - test/p2p/fast_sync/check_peer.sh | 43 - test/p2p/fast_sync/test.sh | 16 - test/p2p/fast_sync/test_peer.sh | 38 - test/p2p/ip.sh | 5 - test/p2p/ip_plus_id.sh | 7 - test/p2p/kill_all/check_peers.sh | 49 - test/p2p/kill_all/test.sh | 32 - test/p2p/local_testnet_start.sh | 24 - test/p2p/local_testnet_stop.sh | 12 - test/p2p/peer.sh | 27 - test/p2p/persistent_peers.sh | 13 - test/p2p/pex/check_peer.sh | 17 - test/p2p/pex/dial_peers.sh | 23 - test/p2p/pex/test.sh | 15 - test/p2p/pex/test_addrbook.sh | 57 - test/p2p/pex/test_dial_peers.sh | 39 - test/p2p/test.sh | 38 - test/persist/test_failure_indices.sh | 124 -- test/persist/test_simple.sh | 70 - test/persist/txs.sh | 23 - test/test_cover.sh | 14 - types/block.go | 577 ------ types/block_meta.go | 15 - types/block_test.go | 88 - types/canonical_json.go | 115 -- types/event_buffer.go | 50 - types/event_buffer_test.go | 21 - types/event_bus.go | 167 -- types/event_bus_test.go | 171 -- types/events.go | 154 -- types/evidence.go | 212 --- types/evidence_test.go | 74 - types/genesis.go | 123 -- types/genesis_test.go | 61 - types/heartbeat.go | 52 - types/heartbeat_test.go | 51 - types/keys.go | 7 - types/nop_event_bus.go | 77 - types/params.go | 155 -- types/params_test.go | 88 - types/part_set.go | 281 --- types/part_set_test.go | 90 - types/priv_validator.go | 95 - types/proposal.go | 58 - types/proposal_test.go | 98 - types/protobuf.go | 221 --- types/protobuf_test.go | 69 - types/results.go | 70 - types/results_test.go | 43 - types/signable.go | 11 - types/test_util.go | 37 - types/tx.go | 128 -- types/tx_test.go | 125 -- types/validator.go | 98 - types/validator_set.go | 517 ----- types/validator_set_test.go | 370 ---- types/vote.go | 117 -- types/vote_set.go | 603 ------ types/vote_set_test.go | 508 ----- types/vote_test.go | 121 -- types/wire.go | 12 - version/version.go | 23 - 533 files changed, 70350 deletions(-) delete mode 100644 CHANGELOG.md delete mode 100644 CODE_OF_CONDUCT.md delete mode 100644 CONTRIBUTING.md delete mode 100644 DOCKER/.gitignore delete mode 100644 DOCKER/Dockerfile delete mode 100644 DOCKER/Dockerfile.develop delete mode 100644 DOCKER/Dockerfile.testing delete mode 100644 DOCKER/Makefile delete mode 100644 DOCKER/README.md delete mode 100755 DOCKER/build.sh delete mode 100755 DOCKER/push.sh delete mode 100644 Gopkg.lock delete mode 100644 Gopkg.toml delete mode 100644 LICENSE delete mode 100755 Makefile delete mode 100644 README.md delete mode 100644 ROADMAP.md delete mode 100644 SECURITY.md delete mode 100644 Vagrantfile delete mode 100644 appveyor.yml delete mode 100644 benchmarks/atomic_test.go delete mode 100644 benchmarks/blockchain/.gitignore delete mode 100755 benchmarks/blockchain/localsync.sh delete mode 100644 benchmarks/chan_test.go delete mode 100644 benchmarks/codec_test.go delete mode 100644 benchmarks/empty.go delete mode 100644 benchmarks/map_test.go delete mode 100644 benchmarks/os_test.go delete mode 100644 benchmarks/proto/README delete mode 100644 benchmarks/proto/test.pb.go delete mode 100644 benchmarks/proto/test.proto delete mode 100644 benchmarks/simu/counter.go delete mode 100644 blockchain/pool.go delete mode 100644 blockchain/pool_test.go delete mode 100644 blockchain/reactor.go delete mode 100644 blockchain/reactor_test.go delete mode 100644 blockchain/store.go delete mode 100644 blockchain/store_test.go delete mode 100644 blockchain/wire.go delete mode 100644 cmd/priv_val_server/main.go delete mode 100644 cmd/tendermint/commands/gen_node_key.go delete mode 100644 cmd/tendermint/commands/gen_validator.go delete mode 100644 cmd/tendermint/commands/init.go delete mode 100644 cmd/tendermint/commands/lite.go delete mode 100644 cmd/tendermint/commands/probe_upnp.go delete mode 100644 cmd/tendermint/commands/replay.go delete mode 100644 cmd/tendermint/commands/reset_priv_validator.go delete mode 100644 cmd/tendermint/commands/root.go delete mode 100644 cmd/tendermint/commands/root_test.go delete mode 100644 cmd/tendermint/commands/run_node.go delete mode 100644 cmd/tendermint/commands/show_node_id.go delete mode 100644 cmd/tendermint/commands/show_validator.go delete mode 100644 cmd/tendermint/commands/testnet.go delete mode 100644 cmd/tendermint/commands/version.go delete mode 100644 cmd/tendermint/commands/wire.go delete mode 100644 cmd/tendermint/main.go delete mode 100644 codecov.yml delete mode 100644 config/config.go delete mode 100644 config/config_test.go delete mode 100644 config/toml.go delete mode 100644 config/toml_test.go delete mode 100644 consensus/README.md delete mode 100644 consensus/byzantine_test.go delete mode 100644 consensus/common_test.go delete mode 100644 consensus/mempool_test.go delete mode 100644 consensus/metrics.go delete mode 100644 consensus/reactor.go delete mode 100644 consensus/reactor_test.go delete mode 100644 consensus/replay.go delete mode 100644 consensus/replay_file.go delete mode 100644 consensus/replay_test.go delete mode 100644 consensus/state.go delete mode 100644 consensus/state_test.go delete mode 100644 consensus/test_data/many_blocks.cswal delete mode 100644 consensus/ticker.go delete mode 100644 consensus/types/height_vote_set.go delete mode 100644 consensus/types/height_vote_set_test.go delete mode 100644 consensus/types/peer_round_state.go delete mode 100644 consensus/types/round_state.go delete mode 100644 consensus/types/round_state_test.go delete mode 100644 consensus/types/wire.go delete mode 100644 consensus/version.go delete mode 100644 consensus/wal.go delete mode 100644 consensus/wal_fuzz.go delete mode 100644 consensus/wal_generator.go delete mode 100644 consensus/wal_test.go delete mode 100644 consensus/wire.go delete mode 100644 docker-compose.yml delete mode 100644 docs/.python-version delete mode 100644 docs/Makefile delete mode 100644 docs/README.md delete mode 100644 docs/_static/custom_collapsible_code.css delete mode 100644 docs/_static/custom_collapsible_code.js delete mode 100644 docs/_templates/layout.html delete mode 100644 docs/abci-cli.md delete mode 100644 docs/app-architecture.md delete mode 100644 docs/app-development.md delete mode 100644 docs/architecture/README.md delete mode 100644 docs/architecture/adr-001-logging.md delete mode 100644 docs/architecture/adr-002-event-subscription.md delete mode 100644 docs/architecture/adr-003-abci-app-rpc.md delete mode 100644 docs/architecture/adr-004-historical-validators.md delete mode 100644 docs/architecture/adr-005-consensus-params.md delete mode 100644 docs/architecture/adr-006-trust-metric.md delete mode 100644 docs/architecture/adr-007-trust-metric-usage.md delete mode 100644 docs/architecture/adr-008-priv-validator.md delete mode 100644 docs/architecture/adr-011-monitoring.md delete mode 100644 docs/architecture/adr-template.md delete mode 100644 docs/architecture/img/formula1.png delete mode 100644 docs/architecture/img/formula2.png delete mode 100644 docs/architecture/img/tags1.png delete mode 100644 docs/assets/a_plus_t.png delete mode 100644 docs/assets/abci.png delete mode 100644 docs/assets/consensus_logic.png delete mode 100644 docs/assets/tm-application-example.png delete mode 100644 docs/assets/tm-transaction-flow.png delete mode 100644 docs/assets/tmint-logo-blue.png delete mode 100644 docs/conf.py delete mode 100644 docs/deploy-testnets.md delete mode 100644 docs/determinism.md delete mode 100644 docs/ecosystem.md delete mode 100644 docs/examples/getting-started.md delete mode 100644 docs/examples/init_testnet.sh delete mode 100644 docs/examples/install_tendermint.sh delete mode 100644 docs/examples/node0/config/config.toml delete mode 100644 docs/examples/node0/config/genesis.json delete mode 100644 docs/examples/node0/config/node_key.json delete mode 100644 docs/examples/node0/config/priv_validator.json delete mode 100644 docs/examples/node1/config/config.toml delete mode 100644 docs/examples/node1/config/genesis.json delete mode 100644 docs/examples/node1/config/node_key.json delete mode 100644 docs/examples/node1/config/priv_validator.json delete mode 100644 docs/examples/node2/config/config.toml delete mode 100644 docs/examples/node2/config/genesis.json delete mode 100644 docs/examples/node2/config/node_key.json delete mode 100644 docs/examples/node2/config/priv_validator.json delete mode 100644 docs/examples/node3/config/config.toml delete mode 100644 docs/examples/node3/config/genesis.json delete mode 100644 docs/examples/node3/config/node_key.json delete mode 100644 docs/examples/node3/config/priv_validator.json delete mode 100644 docs/getting-started.md delete mode 100644 docs/how-to-read-logs.md delete mode 100644 docs/images/tmint-logo-blue.png delete mode 100644 docs/index.rst delete mode 100644 docs/indexing-transactions.md delete mode 100644 docs/install.md delete mode 100644 docs/introduction.md delete mode 100644 docs/metrics.md delete mode 100644 docs/requirements.txt delete mode 100644 docs/running-in-production.md delete mode 100644 docs/spec/README.md delete mode 100644 docs/spec/blockchain/blockchain.md delete mode 100644 docs/spec/blockchain/encoding.md delete mode 100644 docs/spec/blockchain/state.md delete mode 100644 docs/spec/consensus/abci.md delete mode 100644 docs/spec/consensus/bft-time.md delete mode 100644 docs/spec/consensus/consensus.md delete mode 100644 docs/spec/consensus/light-client.md delete mode 100644 docs/spec/consensus/wal.md delete mode 100644 docs/spec/p2p/config.md delete mode 100644 docs/spec/p2p/connection.md delete mode 100644 docs/spec/p2p/node.md delete mode 100644 docs/spec/p2p/peer.md delete mode 100644 docs/spec/reactors/block_sync/img/bc-reactor.png delete mode 100644 docs/spec/reactors/block_sync/impl.md delete mode 100644 docs/spec/reactors/block_sync/reactor.md delete mode 100644 docs/spec/reactors/consensus/consensus-reactor.md delete mode 100644 docs/spec/reactors/consensus/consensus.md delete mode 100644 docs/spec/reactors/consensus/proposer-selection.md delete mode 100644 docs/spec/reactors/evidence/reactor.md delete mode 100644 docs/spec/reactors/mempool/concurrency.md delete mode 100644 docs/spec/reactors/mempool/config.md delete mode 100644 docs/spec/reactors/mempool/functionality.md delete mode 100644 docs/spec/reactors/mempool/messages.md delete mode 100644 docs/spec/reactors/mempool/reactor.md delete mode 100644 docs/spec/reactors/pex/pex.md delete mode 100644 docs/spec/reactors/pex/reactor.md delete mode 100644 docs/spec/scripts/crypto.go delete mode 100644 docs/spec/software/abci.md delete mode 100644 docs/spec/software/wal.md delete mode 100644 docs/specification.rst delete mode 100644 docs/specification/block-structure.rst delete mode 100644 docs/specification/byzantine-consensus-algorithm.rst delete mode 100644 docs/specification/configuration.md delete mode 100644 docs/specification/corruption.rst delete mode 100644 docs/specification/fast-sync.rst delete mode 100644 docs/specification/genesis.rst delete mode 100644 docs/specification/light-client-protocol.rst delete mode 100644 docs/specification/merkle.rst delete mode 100644 docs/specification/new-spec/README.md delete mode 100644 docs/specification/rpc.md delete mode 100644 docs/specification/secure-p2p.rst delete mode 100644 docs/specification/validators.rst delete mode 100644 docs/specification/wire-protocol.rst delete mode 100644 docs/subscribing-to-events-via-websocket.md delete mode 100644 docs/terraform-and-ansible.md delete mode 100644 docs/transactional-semantics.md delete mode 100644 docs/using-tendermint.md delete mode 100644 evidence/pool.go delete mode 100644 evidence/pool_test.go delete mode 100644 evidence/reactor.go delete mode 100644 evidence/reactor_test.go delete mode 100644 evidence/store.go delete mode 100644 evidence/store_test.go delete mode 100644 evidence/wire.go delete mode 100644 libs/events/Makefile delete mode 100644 libs/events/README.md delete mode 100644 libs/events/event_cache.go delete mode 100644 libs/events/event_cache_test.go delete mode 100644 libs/events/events.go delete mode 100644 libs/events/events_test.go delete mode 100644 libs/pubsub/example_test.go delete mode 100644 libs/pubsub/pubsub.go delete mode 100644 libs/pubsub/pubsub_test.go delete mode 100644 libs/pubsub/query/Makefile delete mode 100644 libs/pubsub/query/empty.go delete mode 100644 libs/pubsub/query/empty_test.go delete mode 100644 libs/pubsub/query/fuzz_test/main.go delete mode 100644 libs/pubsub/query/parser_test.go delete mode 100644 libs/pubsub/query/query.go delete mode 100644 libs/pubsub/query/query.peg delete mode 100644 libs/pubsub/query/query.peg.go delete mode 100644 libs/pubsub/query/query_test.go delete mode 100644 lite/client/main_test.go delete mode 100644 lite/client/provider.go delete mode 100644 lite/client/provider_test.go delete mode 100644 lite/commit.go delete mode 100644 lite/doc.go delete mode 100644 lite/dynamic_certifier.go delete mode 100644 lite/dynamic_certifier_test.go delete mode 100644 lite/errors/errors.go delete mode 100644 lite/errors/errors_test.go delete mode 100644 lite/files/commit.go delete mode 100644 lite/files/commit_test.go delete mode 100644 lite/files/provider.go delete mode 100644 lite/files/provider_test.go delete mode 100644 lite/files/wire.go delete mode 100644 lite/helpers.go delete mode 100644 lite/inquiring_certifier.go delete mode 100644 lite/inquiring_certifier_test.go delete mode 100644 lite/memprovider.go delete mode 100644 lite/performance_test.go delete mode 100644 lite/provider.go delete mode 100644 lite/provider_test.go delete mode 100644 lite/proxy/block.go delete mode 100644 lite/proxy/certifier.go delete mode 100644 lite/proxy/errors.go delete mode 100644 lite/proxy/errors_test.go delete mode 100644 lite/proxy/proxy.go delete mode 100644 lite/proxy/query.go delete mode 100644 lite/proxy/query_test.go delete mode 100644 lite/proxy/validate_test.go delete mode 100644 lite/proxy/wrapper.go delete mode 100644 lite/static_certifier.go delete mode 100644 lite/static_certifier_test.go delete mode 100644 mempool/mempool.go delete mode 100644 mempool/mempool_test.go delete mode 100644 mempool/metrics.go delete mode 100644 mempool/reactor.go delete mode 100644 mempool/reactor_test.go delete mode 100644 mempool/wire.go delete mode 100644 networks/local/Makefile delete mode 100644 networks/local/README.md delete mode 100644 networks/local/localnode/Dockerfile delete mode 100755 networks/local/localnode/wrapper.sh delete mode 100644 networks/remote/README.md delete mode 100644 networks/remote/ansible/.gitignore delete mode 100644 networks/remote/ansible/ansible.cfg delete mode 100644 networks/remote/ansible/config.yml delete mode 100644 networks/remote/ansible/install.yml delete mode 100644 networks/remote/ansible/inventory/COPYING delete mode 100644 networks/remote/ansible/inventory/digital_ocean.ini delete mode 100755 networks/remote/ansible/inventory/digital_ocean.py delete mode 100644 networks/remote/ansible/logzio.yml delete mode 100644 networks/remote/ansible/reset.yml delete mode 100644 networks/remote/ansible/restart.yml delete mode 100644 networks/remote/ansible/roles/config/tasks/main.yml delete mode 100644 networks/remote/ansible/roles/install/handlers/main.yml delete mode 100644 networks/remote/ansible/roles/install/tasks/main.yml delete mode 100644 networks/remote/ansible/roles/install/templates/systemd.service.j2 delete mode 100644 networks/remote/ansible/roles/logzio/files/journalbeat.service delete mode 100644 networks/remote/ansible/roles/logzio/handlers/main.yml delete mode 100644 networks/remote/ansible/roles/logzio/tasks/main.yml delete mode 100644 networks/remote/ansible/roles/logzio/templates/journalbeat.yml.j2 delete mode 100644 networks/remote/ansible/roles/start/tasks/main.yml delete mode 100644 networks/remote/ansible/roles/status/tasks/main.yml delete mode 100644 networks/remote/ansible/roles/stop/tasks/main.yml delete mode 100644 networks/remote/ansible/roles/unsafe_reset/tasks/main.yml delete mode 100644 networks/remote/ansible/start.yml delete mode 100644 networks/remote/ansible/status.yml delete mode 100644 networks/remote/ansible/stop.yml delete mode 100644 networks/remote/integration.sh delete mode 100644 networks/remote/terraform/.gitignore delete mode 100644 networks/remote/terraform/cluster/main.tf delete mode 100644 networks/remote/terraform/cluster/outputs.tf delete mode 100644 networks/remote/terraform/cluster/variables.tf delete mode 100644 networks/remote/terraform/main.tf delete mode 100644 node/id.go delete mode 100644 node/node.go delete mode 100644 node/node_test.go delete mode 100644 node/wire.go delete mode 100644 p2p/README.md delete mode 100644 p2p/base_reactor.go delete mode 100644 p2p/conn/conn_go110.go delete mode 100644 p2p/conn/conn_notgo110.go delete mode 100644 p2p/conn/connection.go delete mode 100644 p2p/conn/connection_test.go delete mode 100644 p2p/conn/secret_connection.go delete mode 100644 p2p/conn/secret_connection_test.go delete mode 100644 p2p/conn/wire.go delete mode 100644 p2p/dummy/peer.go delete mode 100644 p2p/errors.go delete mode 100644 p2p/fuzz.go delete mode 100644 p2p/key.go delete mode 100644 p2p/key_test.go delete mode 100644 p2p/listener.go delete mode 100644 p2p/listener_test.go delete mode 100644 p2p/metrics.go delete mode 100644 p2p/netaddress.go delete mode 100644 p2p/netaddress_test.go delete mode 100644 p2p/node_info.go delete mode 100644 p2p/peer.go delete mode 100644 p2p/peer_set.go delete mode 100644 p2p/peer_set_test.go delete mode 100644 p2p/peer_test.go delete mode 100644 p2p/pex/addrbook.go delete mode 100644 p2p/pex/addrbook_test.go delete mode 100644 p2p/pex/errors.go delete mode 100644 p2p/pex/file.go delete mode 100644 p2p/pex/known_address.go delete mode 100644 p2p/pex/params.go delete mode 100644 p2p/pex/pex_reactor.go delete mode 100644 p2p/pex/pex_reactor_test.go delete mode 100644 p2p/pex/wire.go delete mode 100644 p2p/switch.go delete mode 100644 p2p/switch_test.go delete mode 100644 p2p/test_util.go delete mode 100644 p2p/trust/config.go delete mode 100644 p2p/trust/metric.go delete mode 100644 p2p/trust/metric_test.go delete mode 100644 p2p/trust/store.go delete mode 100644 p2p/trust/store_test.go delete mode 100644 p2p/trust/ticker.go delete mode 100644 p2p/types.go delete mode 100644 p2p/upnp/probe.go delete mode 100644 p2p/upnp/upnp.go delete mode 100644 p2p/version.go delete mode 100644 p2p/wire.go delete mode 100644 privval/priv_validator.go delete mode 100644 privval/priv_validator_test.go delete mode 100644 privval/socket.go delete mode 100644 privval/socket_tcp.go delete mode 100644 privval/socket_tcp_test.go delete mode 100644 privval/socket_test.go delete mode 100644 privval/wire.go delete mode 100644 proxy/app_conn.go delete mode 100644 proxy/app_conn_test.go delete mode 100644 proxy/client.go delete mode 100644 proxy/multi_app_conn.go delete mode 100644 rpc/client/event_test.go delete mode 100644 rpc/client/helpers.go delete mode 100644 rpc/client/helpers_test.go delete mode 100644 rpc/client/httpclient.go delete mode 100644 rpc/client/interface.go delete mode 100644 rpc/client/localclient.go delete mode 100644 rpc/client/main_test.go delete mode 100644 rpc/client/mock/abci.go delete mode 100644 rpc/client/mock/abci_test.go delete mode 100644 rpc/client/mock/client.go delete mode 100644 rpc/client/mock/status.go delete mode 100644 rpc/client/mock/status_test.go delete mode 100644 rpc/client/rpc_test.go delete mode 100644 rpc/client/types.go delete mode 100644 rpc/core/README.md delete mode 100644 rpc/core/abci.go delete mode 100644 rpc/core/blocks.go delete mode 100644 rpc/core/consensus.go delete mode 100644 rpc/core/dev.go delete mode 100644 rpc/core/doc.go delete mode 100644 rpc/core/doc_template.txt delete mode 100644 rpc/core/events.go delete mode 100644 rpc/core/health.go delete mode 100644 rpc/core/mempool.go delete mode 100644 rpc/core/net.go delete mode 100644 rpc/core/pipe.go delete mode 100644 rpc/core/pipe_test.go delete mode 100644 rpc/core/routes.go delete mode 100644 rpc/core/status.go delete mode 100644 rpc/core/tx.go delete mode 100644 rpc/core/types/responses.go delete mode 100644 rpc/core/types/responses_test.go delete mode 100644 rpc/core/types/wire.go delete mode 100644 rpc/core/version.go delete mode 100644 rpc/grpc/api.go delete mode 100644 rpc/grpc/client_server.go delete mode 100644 rpc/grpc/compile.sh delete mode 100644 rpc/grpc/grpc_test.go delete mode 100644 rpc/grpc/types.pb.go delete mode 100644 rpc/grpc/types.proto delete mode 100644 rpc/lib/client/args_test.go delete mode 100644 rpc/lib/client/http_client.go delete mode 100644 rpc/lib/client/integration_test.go delete mode 100644 rpc/lib/client/ws_client.go delete mode 100644 rpc/lib/client/ws_client_test.go delete mode 100644 rpc/lib/doc.go delete mode 100644 rpc/lib/rpc_test.go delete mode 100644 rpc/lib/server/handlers.go delete mode 100644 rpc/lib/server/handlers_test.go delete mode 100644 rpc/lib/server/http_params.go delete mode 100644 rpc/lib/server/http_server.go delete mode 100644 rpc/lib/server/parse_test.go delete mode 100644 rpc/lib/test/data.json delete mode 100755 rpc/lib/test/integration_test.sh delete mode 100644 rpc/lib/test/main.go delete mode 100644 rpc/lib/types/types.go delete mode 100644 rpc/lib/types/types_test.go delete mode 100644 rpc/lib/version.go delete mode 100644 rpc/test/helpers.go delete mode 100644 scripts/README.md delete mode 100644 scripts/dep_utils/parse.sh delete mode 100755 scripts/dist.sh delete mode 100644 scripts/install/install_tendermint_bsd.sh delete mode 100644 scripts/install/install_tendermint_ubuntu.sh delete mode 100644 scripts/install_abci_apps.sh delete mode 100755 scripts/publish.sh delete mode 100755 scripts/release.sh delete mode 100644 scripts/slate.sh delete mode 100644 scripts/txs/random.sh delete mode 100644 scripts/wal2json/main.go delete mode 100644 scripts/wire2amino.go delete mode 100644 state/errors.go delete mode 100644 state/execution.go delete mode 100644 state/execution_test.go delete mode 100644 state/services.go delete mode 100644 state/state.go delete mode 100644 state/state_test.go delete mode 100644 state/store.go delete mode 100644 state/txindex/indexer.go delete mode 100644 state/txindex/indexer_service.go delete mode 100644 state/txindex/kv/kv.go delete mode 100644 state/txindex/kv/kv_test.go delete mode 100644 state/txindex/kv/wire.go delete mode 100644 state/txindex/null/null.go delete mode 100644 state/validation.go delete mode 100644 state/validation_test.go delete mode 100644 state/wire.go delete mode 100644 test/README.md delete mode 100755 test/app/clean.sh delete mode 100755 test/app/counter_test.sh delete mode 100644 test/app/grpc_client.go delete mode 100755 test/app/kvstore_test.sh delete mode 100755 test/app/test.sh delete mode 100644 test/docker/Dockerfile delete mode 100644 test/docker/build.sh delete mode 100644 test/p2p/README.md delete mode 100644 test/p2p/atomic_broadcast/test.sh delete mode 100755 test/p2p/basic/test.sh delete mode 100644 test/p2p/circleci.sh delete mode 100644 test/p2p/client.sh delete mode 100644 test/p2p/data/mach1/core/config/genesis.json delete mode 100644 test/p2p/data/mach1/core/config/node_key.json delete mode 100644 test/p2p/data/mach1/core/config/priv_validator.json delete mode 100644 test/p2p/data/mach2/core/config/genesis.json delete mode 100644 test/p2p/data/mach2/core/config/node_key.json delete mode 100644 test/p2p/data/mach2/core/config/priv_validator.json delete mode 100644 test/p2p/data/mach3/core/config/genesis.json delete mode 100644 test/p2p/data/mach3/core/config/node_key.json delete mode 100644 test/p2p/data/mach3/core/config/priv_validator.json delete mode 100644 test/p2p/data/mach4/core/config/genesis.json delete mode 100644 test/p2p/data/mach4/core/config/node_key.json delete mode 100644 test/p2p/data/mach4/core/config/priv_validator.json delete mode 100644 test/p2p/fast_sync/check_peer.sh delete mode 100644 test/p2p/fast_sync/test.sh delete mode 100644 test/p2p/fast_sync/test_peer.sh delete mode 100755 test/p2p/ip.sh delete mode 100755 test/p2p/ip_plus_id.sh delete mode 100644 test/p2p/kill_all/check_peers.sh delete mode 100644 test/p2p/kill_all/test.sh delete mode 100644 test/p2p/local_testnet_start.sh delete mode 100644 test/p2p/local_testnet_stop.sh delete mode 100644 test/p2p/peer.sh delete mode 100644 test/p2p/persistent_peers.sh delete mode 100644 test/p2p/pex/check_peer.sh delete mode 100644 test/p2p/pex/dial_peers.sh delete mode 100644 test/p2p/pex/test.sh delete mode 100644 test/p2p/pex/test_addrbook.sh delete mode 100644 test/p2p/pex/test_dial_peers.sh delete mode 100644 test/p2p/test.sh delete mode 100644 test/persist/test_failure_indices.sh delete mode 100644 test/persist/test_simple.sh delete mode 100644 test/persist/txs.sh delete mode 100644 test/test_cover.sh delete mode 100644 types/block.go delete mode 100644 types/block_meta.go delete mode 100644 types/block_test.go delete mode 100644 types/canonical_json.go delete mode 100644 types/event_buffer.go delete mode 100644 types/event_buffer_test.go delete mode 100644 types/event_bus.go delete mode 100644 types/event_bus_test.go delete mode 100644 types/events.go delete mode 100644 types/evidence.go delete mode 100644 types/evidence_test.go delete mode 100644 types/genesis.go delete mode 100644 types/genesis_test.go delete mode 100644 types/heartbeat.go delete mode 100644 types/heartbeat_test.go delete mode 100644 types/keys.go delete mode 100644 types/nop_event_bus.go delete mode 100644 types/params.go delete mode 100644 types/params_test.go delete mode 100644 types/part_set.go delete mode 100644 types/part_set_test.go delete mode 100644 types/priv_validator.go delete mode 100644 types/proposal.go delete mode 100644 types/proposal_test.go delete mode 100644 types/protobuf.go delete mode 100644 types/protobuf_test.go delete mode 100644 types/results.go delete mode 100644 types/results_test.go delete mode 100644 types/signable.go delete mode 100644 types/test_util.go delete mode 100644 types/tx.go delete mode 100644 types/tx_test.go delete mode 100644 types/validator.go delete mode 100644 types/validator_set.go delete mode 100644 types/validator_set_test.go delete mode 100644 types/vote.go delete mode 100644 types/vote_set.go delete mode 100644 types/vote_set_test.go delete mode 100644 types/vote_test.go delete mode 100644 types/wire.go delete mode 100644 version/version.go diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index f69127d5b..000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,868 +0,0 @@ -# Changelog - -## TBD - -FEATURES: -- [node] added metrics (served under /metrics using a Prometheus client; disabled by default) - -## 0.20.1 - -BUG FIXES: - -- [rpc] fix memory leak in Websocket (when using `/subscribe` method) - -## 0.20.0 - -*June 6th, 2018* - -This is the first in a series of breaking releases coming to Tendermint after -soliciting developer feedback and conducting security audits. - -This release does not break any blockchain data structures or -protocols other than the ABCI messages between Tendermint and the application. - -Applications that upgrade for ABCI v0.11.0 should be able to continue running Tendermint -v0.20.0 on blockchains created with v0.19.X - -BREAKING CHANGES - -- [abci] Upgrade to - [v0.11.0](https://github.com/tendermint/abci/blob/master/CHANGELOG.md#0110) -- [abci] Change Query path for filtering peers by node ID from - `p2p/filter/pubkey/` to `p2p/filter/id/` - -## 0.19.9 - -*June 5th, 2018* - -BREAKING CHANGES - -- [types/priv_validator] Moved to top level `privval` package - -FEATURES - -- [config] Collapse PeerConfig into P2PConfig -- [docs] Add quick-install script -- [docs/spec] Add table of Amino prefixes - -BUG FIXES - -- [rpc] Return 404 for unknown endpoints -- [consensus] Flush WAL on stop -- [evidence] Don't send evidence to peers that are behind -- [p2p] Fix memory leak on peer disconnects -- [rpc] Fix panic when `per_page=0` - -## 0.19.8 - -*June 4th, 2018* - -BREAKING: - -- [p2p] Remove `auth_enc` config option, peer connections are always auth - encrypted. Technically a breaking change but seems no one was using it and - arguably a bug fix :) - -BUG FIXES - -- [mempool] Fix deadlock under high load when `skip_timeout_commit=true` and - `create_empty_blocks=false` - -## 0.19.7 - -*May 31st, 2018* - -BREAKING: - -- [libs/pubsub] TagMap#Get returns a string value -- [libs/pubsub] NewTagMap accepts a map of strings - -FEATURES - -- [rpc] the RPC documentation is now published to https://tendermint.github.io/slate -- [p2p] AllowDuplicateIP config option to refuse connections from same IP. - - true by default for now, false by default in next breaking release -- [docs] Add docs for query, tx indexing, events, pubsub -- [docs] Add some notes about running Tendermint in production - -IMPROVEMENTS: - -- [consensus] Consensus reactor now receives events from a separate synchronous event bus, - which is not dependant on external RPC load -- [consensus/wal] do not look for height in older files if we've seen height - 1 -- [docs] Various cleanup and link fixes - -## 0.19.6 - -*May 29th, 2018* - -BUG FIXES - -- [blockchain] Fix fast-sync deadlock during high peer turnover - -BUG FIX: - -- [evidence] Dont send peers evidence from heights they haven't synced to yet -- [p2p] Refuse connections to more than one peer with the same IP -- [docs] Various fixes - -## 0.19.5 - -*May 20th, 2018* - -BREAKING CHANGES - -- [rpc/client] TxSearch and UnconfirmedTxs have new arguments (see below) -- [rpc/client] TxSearch returns ResultTxSearch -- [version] Breaking changes to Go APIs will not be reflected in breaking - version change, but will be included in changelog. - -FEATURES - -- [rpc] `/tx_search` takes `page` (starts at 1) and `per_page` (max 100, default 30) args to paginate results -- [rpc] `/unconfirmed_txs` takes `limit` (max 100, default 30) arg to limit the output -- [config] `mempool.size` and `mempool.cache_size` options - -IMPROVEMENTS - -- [docs] Lots of updates -- [consensus] Only Fsync() the WAL before executing msgs from ourselves - -BUG FIXES - -- [mempool] Enforce upper bound on number of transactions - -## 0.19.4 (May 17th, 2018) - -IMPROVEMENTS - -- [state] Improve tx indexing by using batches -- [consensus, state] Improve logging (more consensus logs, fewer tx logs) -- [spec] Moved to `docs/spec` (TODO cleanup the rest of the docs ...) - -BUG FIXES - -- [consensus] Fix issue #1575 where a late proposer can get stuck - -## 0.19.3 (May 14th, 2018) - -FEATURES - -- [rpc] New `/consensus_state` returns just the votes seen at the current height - -IMPROVEMENTS - -- [rpc] Add stringified votes and fraction of power voted to `/dump_consensus_state` -- [rpc] Add PeerStateStats to `/dump_consensus_state` - -BUG FIXES - -- [cmd] Set GenesisTime during `tendermint init` -- [consensus] fix ValidBlock rules - -## 0.19.2 (April 30th, 2018) - -FEATURES: - -- [p2p] Allow peers with different Minor versions to connect -- [rpc] `/net_info` includes `n_peers` - -IMPROVEMENTS: - -- [p2p] Various code comments, cleanup, error types -- [p2p] Change some Error logs to Debug - -BUG FIXES: - -- [p2p] Fix reconnect to persistent peer when first dial fails -- [p2p] Validate NodeInfo.ListenAddr -- [p2p] Only allow (MaxNumPeers - MaxNumOutboundPeers) inbound peers -- [p2p/pex] Limit max msg size to 64kB -- [p2p] Fix panic when pex=false -- [p2p] Allow multiple IPs per ID in AddrBook -- [p2p] Fix before/after bugs in addrbook isBad() - -## 0.19.1 (April 27th, 2018) - -Note this release includes some small breaking changes in the RPC and one in the -config that are really bug fixes. v0.19.1 will work with existing chains, and make Tendermint -easier to use and debug. With <3 - -BREAKING (MINOR) - -- [config] Removed `wal_light` setting. If you really needed this, let us know - -FEATURES: - -- [networks] moved in tooling from devops repo: terraform and ansible scripts for deploying testnets ! -- [cmd] Added `gen_node_key` command - -BUG FIXES - -Some of these are breaking in the RPC response, but they're really bugs! - -- [spec] Document address format and pubkey encoding pre and post Amino -- [rpc] Lower case JSON field names -- [rpc] Fix missing entries, improve, and lower case the fields in `/dump_consensus_state` -- [rpc] Fix NodeInfo.Channels format to hex -- [rpc] Add Validator address to `/status` -- [rpc] Fix `prove` in ABCIQuery -- [cmd] MarshalJSONIndent on init - -## 0.19.0 (April 13th, 2018) - -BREAKING: -- [cmd] improved `testnet` command; now it can fill in `persistent_peers` for you in the config file and much more (see `tendermint testnet --help` for details) -- [cmd] `show_node_id` now returns an error if there is no node key -- [rpc]: changed the output format for the `/status` endpoint (see https://godoc.org/github.com/tendermint/tendermint/rpc/core#Status) - -Upgrade from go-wire to go-amino. This is a sweeping change that breaks everything that is -serialized to disk or over the network. - -See github.com/tendermint/go-amino for details on the new format. - -See `scripts/wire2amino.go` for a tool to upgrade -genesis/priv_validator/node_key JSON files. - -FEATURES - -- [test] docker-compose for local testnet setup (thanks Greg!) - -## 0.18.0 (April 6th, 2018) - -BREAKING: - -- [types] Merkle tree uses different encoding for varints (see tmlibs v0.8.0) -- [types] ValidtorSet.GetByAddress returns -1 if no validator found -- [p2p] require all addresses come with an ID no matter what -- [rpc] Listening address must contain tcp:// or unix:// prefix - -FEATURES: - -- [rpc] StartHTTPAndTLSServer (not used yet) -- [rpc] Include validator's voting power in `/status` -- [rpc] `/tx` and `/tx_search` responses now include the transaction hash -- [rpc] Include peer NodeIDs in `/net_info` - -IMPROVEMENTS: -- [config] trim whitespace from elements of lists (like `persistent_peers`) -- [rpc] `/tx_search` results are sorted by height -- [p2p] do not try to connect to ourselves (ok, maybe only once) -- [p2p] seeds respond with a bias towards good peers - -BUG FIXES: -- [rpc] fix subscribing using an abci.ResponseDeliverTx tag -- [rpc] fix tx_indexers matchRange -- [rpc] fix unsubscribing (see tmlibs v0.8.0) - -## 0.17.1 (March 27th, 2018) - -BUG FIXES: -- [types] Actually support `app_state` in genesis as `AppStateJSON` - -## 0.17.0 (March 27th, 2018) - -BREAKING: -- [types] WriteSignBytes -> SignBytes - -IMPROVEMENTS: -- [all] renamed `dummy` (`persistent_dummy`) to `kvstore` (`persistent_kvstore`) (name "dummy" is deprecated and will not work in the next breaking release) -- [docs] note on determinism (docs/determinism.rst) -- [genesis] `app_options` field is deprecated. please rename it to `app_state` in your genesis file(s). `app_options` will not work in the next breaking release -- [p2p] dial seeds directly without potential peers -- [p2p] exponential backoff for addrs in the address book -- [p2p] mark peer as good if it contributed enough votes or block parts -- [p2p] stop peer if it sends incorrect data, msg to unknown channel, msg we did not expect -- [p2p] when `auth_enc` is true, all dialed peers must have a node ID in their address -- [spec] various improvements -- switched from glide to dep internally for package management -- [wire] prep work for upgrading to new go-wire (which is now called go-amino) - -FEATURES: -- [config] exposed `auth_enc` flag to enable/disable encryption -- [config] added the `--p2p.private_peer_ids` flag and `PrivatePeerIDs` config variable (see config for description) -- [rpc] added `/health` endpoint, which returns empty result for now -- [types/priv_validator] new format and socket client, allowing for remote signing - -BUG FIXES: -- [consensus] fix liveness bug by introducing ValidBlock mechanism - -## 0.16.0 (February 20th, 2018) - -BREAKING CHANGES: -- [config] use $TMHOME/config for all config and json files -- [p2p] old `--p2p.seeds` is now `--p2p.persistent_peers` (persistent peers to which TM will always connect to) -- [p2p] now `--p2p.seeds` only used for getting addresses (if addrbook is empty; not persistent) -- [p2p] NodeInfo: remove RemoteAddr and add Channels - - we must have at least one overlapping channel with peer - - we only send msgs for channels the peer advertised -- [p2p/conn] pong timeout -- [lite] comment out IAVL related code - -FEATURES: -- [p2p] added new `/dial_peers&persistent=_` **unsafe** endpoint -- [p2p] persistent node key in `$THMHOME/config/node_key.json` -- [p2p] introduce peer ID and authenticate peers by ID using addresses like `ID@IP:PORT` -- [p2p/pex] new seed mode crawls the network and serves as a seed. -- [config] MempoolConfig.CacheSize -- [config] P2P.SeedMode (`--p2p.seed_mode`) - -IMPROVEMENT: -- [p2p/pex] stricter rules in the PEX reactor for better handling of abuse -- [p2p] various improvements to code structure including subpackages for `pex` and `conn` -- [docs] new spec! -- [all] speed up the tests! - -BUG FIX: -- [blockchain] StopPeerForError on timeout -- [consensus] StopPeerForError on a bad Maj23 message -- [state] flush mempool conn before calling commit -- [types] fix priv val signing things that only differ by timestamp -- [mempool] fix memory leak causing zombie peers -- [p2p/conn] fix potential deadlock - -## 0.15.0 (December 29, 2017) - -BREAKING CHANGES: -- [p2p] enable the Peer Exchange reactor by default -- [types] add Timestamp field to Proposal/Vote -- [types] add new fields to Header: TotalTxs, ConsensusParamsHash, LastResultsHash, EvidenceHash -- [types] add Evidence to Block -- [types] simplify ValidateBasic -- [state] updates to support changes to the header -- [state] Enforce <1/3 of validator set can change at a time - -FEATURES: -- [state] Send indices of absent validators and addresses of byzantine validators in BeginBlock -- [state] Historical ConsensusParams and ABCIResponses -- [docs] Specification for the base Tendermint data structures. -- [evidence] New evidence reactor for gossiping and managing evidence -- [rpc] `/block_results?height=X` returns the DeliverTx results for a given height. - -IMPROVEMENTS: -- [consensus] Better handling of corrupt WAL file - -BUG FIXES: -- [lite] fix race -- [state] validate block.Header.ValidatorsHash -- [p2p] allow seed addresses to be prefixed with eg. `tcp://` -- [p2p] use consistent key to refer to peers so we dont try to connect to existing peers -- [cmd] fix `tendermint init` to ignore files that are there and generate files that aren't. - -## 0.14.0 (December 11, 2017) - -BREAKING CHANGES: -- consensus/wal: removed separator -- rpc/client: changed Subscribe/Unsubscribe/UnsubscribeAll funcs signatures to be identical to event bus. - -FEATURES: -- new `tendermint lite` command (and `lite/proxy` pkg) for running a light-client RPC proxy. - NOTE it is currently insecure and its APIs are not yet covered by semver - -IMPROVEMENTS: -- rpc/client: can act as event bus subscriber (See https://github.com/tendermint/tendermint/issues/945). -- p2p: use exponential backoff from seconds to hours when attempting to reconnect to persistent peer -- config: moniker defaults to the machine's hostname instead of "anonymous" - -BUG FIXES: -- p2p: no longer exit if one of the seed addresses is incorrect - -## 0.13.0 (December 6, 2017) - -BREAKING CHANGES: -- abci: update to v0.8 using gogo/protobuf; includes tx tags, vote info in RequestBeginBlock, data.Bytes everywhere, use int64, etc. -- types: block heights are now `int64` everywhere -- types & node: EventSwitch and EventCache have been replaced by EventBus and EventBuffer; event types have been overhauled -- node: EventSwitch methods now refer to EventBus -- rpc/lib/types: RPCResponse is no longer a pointer; WSRPCConnection interface has been modified -- rpc/client: WaitForOneEvent takes an EventsClient instead of types.EventSwitch -- rpc/client: Add/RemoveListenerForEvent are now Subscribe/Unsubscribe -- rpc/core/types: ResultABCIQuery wraps an abci.ResponseQuery -- rpc: `/subscribe` and `/unsubscribe` take `query` arg instead of `event` -- rpc: `/status` returns the LatestBlockTime in human readable form instead of in nanoseconds -- mempool: cached transactions return an error instead of an ABCI response with BadNonce - -FEATURES: -- rpc: new `/unsubscribe_all` WebSocket RPC endpoint -- rpc: new `/tx_search` endpoint for filtering transactions by more complex queries -- p2p/trust: new trust metric for tracking peers. See ADR-006 -- config: TxIndexConfig allows to set what DeliverTx tags to index - -IMPROVEMENTS: -- New asynchronous events system using `tmlibs/pubsub` -- logging: Various small improvements -- consensus: Graceful shutdown when app crashes -- tests: Fix various non-deterministic errors -- p2p: more defensive programming - -BUG FIXES: -- consensus: fix panic where prs.ProposalBlockParts is not initialized -- p2p: fix panic on bad channel - -## 0.12.1 (November 27, 2017) - -BUG FIXES: -- upgrade tmlibs dependency to enable Windows builds for Tendermint - -## 0.12.0 (October 27, 2017) - -BREAKING CHANGES: - - rpc/client: websocket ResultsCh and ErrorsCh unified in ResponsesCh. - - rpc/client: ABCIQuery no longer takes `prove` - - state: remove GenesisDoc from state. - - consensus: new binary WAL format provides efficiency and uses checksums to detect corruption - - use scripts/wal2json to convert to json for debugging - -FEATURES: - - new `certifiers` pkg contains the tendermint light-client library (name subject to change)! - - rpc: `/genesis` includes the `app_options` . - - rpc: `/abci_query` takes an additional `height` parameter to support historical queries. - - rpc/client: new ABCIQueryWithOptions supports options like `trusted` (set false to get a proof) and `height` to query a historical height. - -IMPROVEMENTS: - - rpc: `/genesis` result includes `app_options` - - rpc/lib/client: add jitter to reconnects. - - rpc/lib/types: `RPCError` satisfies the `error` interface. - -BUG FIXES: - - rpc/client: fix ws deadlock after stopping - - blockchain: fix panic on AddBlock when peer is nil - - mempool: fix sending on TxsAvailable when a tx has been invalidated - - consensus: dont run WAL catchup if we fast synced - -## 0.11.1 (October 10, 2017) - -IMPROVEMENTS: - - blockchain/reactor: respondWithNoResponseMessage for missing height - -BUG FIXES: - - rpc: fixed client WebSocket timeout - - rpc: client now resubscribes on reconnection - - rpc: fix panics on missing params - - rpc: fix `/dump_consensus_state` to have normal json output (NOTE: technically breaking, but worth a bug fix label) - - types: fixed out of range error in VoteSet.addVote - - consensus: fix wal autofile via https://github.com/tendermint/tmlibs/blob/master/CHANGELOG.md#032-october-2-2017 - -## 0.11.0 (September 22, 2017) - -BREAKING: - - genesis file: validator `amount` is now `power` - - abci: Info, BeginBlock, InitChain all take structs - - rpc: various changes to match JSONRPC spec (http://www.jsonrpc.org/specification), including breaking ones: - - requests that previously returned HTTP code 4XX now return 200 with an error code in the JSONRPC. - - `rpctypes.RPCResponse` uses new `RPCError` type instead of `string`. - - - cmd: if there is no genesis, exit immediately instead of waiting around for one to show. - - types: `Signer.Sign` returns an error. - - state: every validator set change is persisted to disk, which required some changes to the `State` structure. - - p2p: new `p2p.Peer` interface used for all reactor methods (instead of `*p2p.Peer` struct). - -FEATURES: - - rpc: `/validators?height=X` allows querying of validators at previous heights. - - rpc: Leaving the `height` param empty for `/block`, `/validators`, and `/commit` will return the value for the latest height. - -IMPROVEMENTS: - - docs: Moved all docs from the website and tools repo in, converted to `.rst`, and cleaned up for presentation on `tendermint.readthedocs.io` - -BUG FIXES: - - fix WAL openning issue on Windows - -## 0.10.4 (September 5, 2017) - -IMPROVEMENTS: -- docs: Added Slate docs to each rpc function (see rpc/core) -- docs: Ported all website docs to Read The Docs -- config: expose some p2p params to tweak performance: RecvRate, SendRate, and MaxMsgPacketPayloadSize -- rpc: Upgrade the websocket client and server, including improved auto reconnect, and proper ping/pong - -BUG FIXES: -- consensus: fix panic on getVoteBitArray -- consensus: hang instead of panicking on byzantine consensus failures -- cmd: dont load config for version command - -## 0.10.3 (August 10, 2017) - -FEATURES: -- control over empty block production: - - new flag, `--consensus.create_empty_blocks`; when set to false, blocks are only created when there are txs or when the AppHash changes. - - new config option, `consensus.create_empty_blocks_interval`; an empty block is created after this many seconds. - - in normal operation, `create_empty_blocks = true` and `create_empty_blocks_interval = 0`, so blocks are being created all the time (as in all previous versions of tendermint). The number of empty blocks can be reduced by increasing `create_empty_blocks_interval` or by setting `create_empty_blocks = false`. - - new `TxsAvailable()` method added to Mempool that returns a channel which fires when txs are available. - - new heartbeat message added to consensus reactor to notify peers that a node is waiting for txs before entering propose step. -- rpc: Add `syncing` field to response returned by `/status`. Is `true` while in fast-sync mode. - -IMPROVEMENTS: -- various improvements to documentation and code comments - -BUG FIXES: -- mempool: pass height into constructor so it doesn't always start at 0 - -## 0.10.2 (July 10, 2017) - -FEATURES: -- Enable lower latency block commits by adding consensus reactor sleep durations and p2p flush throttle timeout to the config - -IMPROVEMENTS: -- More detailed logging in the consensus reactor and state machine -- More in-code documentation for many exposed functions, especially in consensus/reactor.go and p2p/switch.go -- Improved readability for some function definitions and code blocks with long lines - -## 0.10.1 (June 28, 2017) - -FEATURES: -- Use `--trace` to get stack traces for logged errors -- types: GenesisDoc.ValidatorHash returns the hash of the genesis validator set -- types: GenesisDocFromFile parses a GenesiDoc from a JSON file - -IMPROVEMENTS: -- Add a Code of Conduct -- Variety of improvements as suggested by `megacheck` tool -- rpc: deduplicate tests between rpc/client and rpc/tests -- rpc: addresses without a protocol prefix default to `tcp://`. `http://` is also accepted as an alias for `tcp://` -- cmd: commands are more easily reuseable from other tools -- DOCKER: automate build/push - -BUG FIXES: -- Fix log statements using keys with spaces (logger does not currently support spaces) -- rpc: set logger on websocket connection -- rpc: fix ws connection stability by setting write deadline on pings - -## 0.10.0 (June 2, 2017) - -Includes major updates to configuration, logging, and json serialization. -Also includes the Grand Repo-Merge of 2017. - -BREAKING CHANGES: - -- Config and Flags: - - The `config` map is replaced with a [`Config` struct](https://github.com/tendermint/tendermint/blob/master/config/config.go#L11), -containing substructs: `BaseConfig`, `P2PConfig`, `MempoolConfig`, `ConsensusConfig`, `RPCConfig` - - This affects the following flags: - - `--seeds` is now `--p2p.seeds` - - `--node_laddr` is now `--p2p.laddr` - - `--pex` is now `--p2p.pex` - - `--skip_upnp` is now `--p2p.skip_upnp` - - `--rpc_laddr` is now `--rpc.laddr` - - `--grpc_laddr` is now `--rpc.grpc_laddr` - - Any configuration option now within a substract must come under that heading in the `config.toml`, for instance: - ``` - [p2p] - laddr="tcp://1.2.3.4:46656" - - [consensus] - timeout_propose=1000 - ``` - - Use viper and `DefaultConfig() / TestConfig()` functions to handle defaults, and remove `config/tendermint` and `config/tendermint_test` - - Change some function and method signatures to - - Change some [function and method signatures](https://gist.github.com/ebuchman/640d5fc6c2605f73497992fe107ebe0b) accomodate new config - -- Logger - - Replace static `log15` logger with a simple interface, and provide a new implementation using `go-kit`. -See our new [logging library](https://github.com/tendermint/tmlibs/log) and [blog post](https://tendermint.com/blog/abstracting-the-logger-interface-in-go) for more details - - Levels `warn` and `notice` are removed (you may need to change them in your `config.toml`!) - - Change some [function and method signatures](https://gist.github.com/ebuchman/640d5fc6c2605f73497992fe107ebe0b) to accept a logger - -- JSON serialization: - - Replace `[TypeByte, Xxx]` with `{"type": "some-type", "data": Xxx}` in RPC and all `.json` files by using `go-wire/data`. For instance, a public key is now: - ``` - "pub_key": { - "type": "ed25519", - "data": "83DDF8775937A4A12A2704269E2729FCFCD491B933C4B0A7FFE37FE41D7760D0" - } - ``` - - Remove type information about RPC responses, so `[TypeByte, {"jsonrpc": "2.0", ... }]` is now just `{"jsonrpc": "2.0", ... }` - - Change `[]byte` to `data.Bytes` in all serialized types (for hex encoding) - - Lowercase the JSON tags in `ValidatorSet` fields - - Introduce `EventDataInner` for serializing events - -- Other: - - Send InitChain message in handshake if `appBlockHeight == 0` - - Do not include the `Accum` field when computing the validator hash. This makes the ValidatorSetHash unique for a given validator set, rather than changing with every block (as the Accum changes) - - Unsafe RPC calls are not enabled by default. This includes `/dial_seeds`, and all calls prefixed with `unsafe`. Use the `--rpc.unsafe` flag to enable. - - -FEATURES: - -- Per-module log levels. For instance, the new default is `state:info,*:error`, which means the `state` package logs at `info` level, and everything else logs at `error` level -- Log if a node is validator or not in every consensus round -- Use ldflags to set git hash as part of the version -- Ignore `address` and `pub_key` fields in `priv_validator.json` and overwrite them with the values derrived from the `priv_key` - -IMPROVEMENTS: - -- Merge `tendermint/go-p2p -> tendermint/tendermint/p2p` and `tendermint/go-rpc -> tendermint/tendermint/rpc/lib` -- Update paths for grand repo merge: - - `go-common -> tmlibs/common` - - `go-data -> go-wire/data` - - All other `go-` libs, except `go-crypto` and `go-wire`, are merged under `tmlibs` -- No global loggers (loggers are passed into constructors, or preferably set with a SetLogger method) -- Return HTTP status codes with errors for RPC responses -- Limit `/blockchain_info` call to return a maximum of 20 blocks -- Use `.Wrap()` and `.Unwrap()` instead of eg. `PubKeyS` for `go-crypto` types -- RPC JSON responses use pretty printing (via `json.MarshalIndent`) -- Color code different instances of the consensus for tests -- Isolate viper to `cmd/tendermint/commands` and do not read config from file for tests - - -## 0.9.2 (April 26, 2017) - -BUG FIXES: - -- Fix bug in `ResetPrivValidator` where we were using the global config and log (causing external consumers, eg. basecoin, to fail). - -## 0.9.1 (April 21, 2017) - -FEATURES: - -- Transaction indexing - txs are indexed by their hash using a simple key-value store; easily extended to more advanced indexers -- New `/tx?hash=X` endpoint to query for transactions and their DeliverTx result by hash. Optionally returns a proof of the tx's inclusion in the block -- `tendermint testnet` command initializes files for a testnet - -IMPROVEMENTS: - -- CLI now uses Cobra framework -- TMROOT is now TMHOME (TMROOT will stop working in 0.10.0) -- `/broadcast_tx_XXX` also returns the Hash (can be used to query for the tx) -- `/broadcast_tx_commit` also returns the height the block was committed in -- ABCIResponses struct persisted to disk before calling Commit; makes handshake replay much cleaner -- WAL uses #ENDHEIGHT instead of #HEIGHT (#HEIGHT will stop working in 0.10.0) -- Peers included via `--seeds`, under `seeds` in the config, or in `/dial_seeds` are now persistent, and will be reconnected to if the connection breaks - -BUG FIXES: - -- Fix bug in fast-sync where we stop syncing after a peer is removed, even if they're re-added later -- Fix handshake replay to handle validator set changes and results of DeliverTx when we crash after app.Commit but before state.Save() - -## 0.9.0 (March 6, 2017) - -BREAKING CHANGES: - -- Update ABCI to v0.4.0, where Query is now `Query(RequestQuery) ResponseQuery`, enabling precise proofs at particular heights: - -``` -message RequestQuery{ - bytes data = 1; - string path = 2; - uint64 height = 3; - bool prove = 4; -} - -message ResponseQuery{ - CodeType code = 1; - int64 index = 2; - bytes key = 3; - bytes value = 4; - bytes proof = 5; - uint64 height = 6; - string log = 7; -} -``` - - -- `BlockMeta` data type unifies its Hash and PartSetHash under a `BlockID`: - -``` -type BlockMeta struct { - BlockID BlockID `json:"block_id"` // the block hash and partsethash - Header *Header `json:"header"` // The block's Header -} -``` - -- `ValidatorSet.Proposer` is exposed as a field and persisted with the `State`. Use `GetProposer()` to initialize or update after validator-set changes. - -- `tendermint gen_validator` command output is now pure JSON - -FEATURES: - -- New RPC endpoint `/commit?height=X` returns header and commit for block at height `X` -- Client API for each endpoint, including mocks for testing - -IMPROVEMENTS: - -- `Node` is now a `BaseService` -- Simplified starting Tendermint in-process from another application -- Better organized Makefile -- Scripts for auto-building binaries across platforms -- Docker image improved, slimmed down (using Alpine), and changed from tendermint/tmbase to tendermint/tendermint -- New repo files: `CONTRIBUTING.md`, Github `ISSUE_TEMPLATE`, `CHANGELOG.md` -- Improvements on CircleCI for managing build/test artifacts -- Handshake replay is doen through the consensus package, possibly using a mockApp -- Graceful shutdown of RPC listeners -- Tests for the PEX reactor and DialSeeds - -BUG FIXES: - -- Check peer.Send for failure before updating PeerState in consensus -- Fix panic in `/dial_seeds` with invalid addresses -- Fix proposer selection logic in ValidatorSet by taking the address into account in the `accumComparable` -- Fix inconcistencies with `ValidatorSet.Proposer` across restarts by persisting it in the `State` - - -## 0.8.0 (January 13, 2017) - -BREAKING CHANGES: - -- New data type `BlockID` to represent blocks: - -``` -type BlockID struct { - Hash []byte `json:"hash"` - PartsHeader PartSetHeader `json:"parts"` -} -``` - -- `Vote` data type now includes validator address and index: - -``` -type Vote struct { - ValidatorAddress []byte `json:"validator_address"` - ValidatorIndex int `json:"validator_index"` - Height int `json:"height"` - Round int `json:"round"` - Type byte `json:"type"` - BlockID BlockID `json:"block_id"` // zero if vote is nil. - Signature crypto.Signature `json:"signature"` -} -``` - -- Update TMSP to v0.3.0, where it is now called ABCI and AppendTx is DeliverTx -- Hex strings in the RPC are now "0x" prefixed - - -FEATURES: - -- New message type on the ConsensusReactor, `Maj23Msg`, for peers to alert others they've seen a Maj23, -in order to track and handle conflicting votes intelligently to prevent Byzantine faults from causing halts: - -``` -type VoteSetMaj23Message struct { - Height int - Round int - Type byte - BlockID types.BlockID -} -``` - -- Configurable block part set size -- Validator set changes -- Optionally skip TimeoutCommit if we have all the votes -- Handshake between Tendermint and App on startup to sync latest state and ensure consistent recovery from crashes -- GRPC server for BroadcastTx endpoint - -IMPROVEMENTS: - -- Less verbose logging -- Better test coverage (37% -> 49%) -- Canonical SignBytes for signable types -- Write-Ahead Log for Mempool and Consensus via tmlibs/autofile -- Better in-process testing for the consensus reactor and byzantine faults -- Better crash/restart testing for individual nodes at preset failure points, and of networks at arbitrary points -- Better abstraction over timeout mechanics - -BUG FIXES: - -- Fix memory leak in mempool peer -- Fix panic on POLRound=-1 -- Actually set the CommitTime -- Actually send BeginBlock message -- Fix a liveness issues caused by Byzantine proposals/votes. Uses the new `Maj23Msg`. - - -## 0.7.4 (December 14, 2016) - -FEATURES: - -- Enable the Peer Exchange reactor with the `--pex` flag for more resilient gossip network (feature still in development, beware dragons) - -IMPROVEMENTS: - -- Remove restrictions on RPC endpoint `/dial_seeds` to enable manual network configuration - -## 0.7.3 (October 20, 2016) - -IMPROVEMENTS: - -- Type safe FireEvent -- More WAL/replay tests -- Cleanup some docs - -BUG FIXES: - -- Fix deadlock in mempool for synchronous apps -- Replay handles non-empty blocks -- Fix race condition in HeightVoteSet - -## 0.7.2 (September 11, 2016) - -BUG FIXES: - -- Set mustConnect=false so tendermint will retry connecting to the app - -## 0.7.1 (September 10, 2016) - -FEATURES: - -- New TMSP connection for Query/Info -- New RPC endpoints: - - `tmsp_query` - - `tmsp_info` -- Allow application to filter peers through Query (off by default) - -IMPROVEMENTS: - -- TMSP connection type enforced at compile time -- All listen/client urls use a "tcp://" or "unix://" prefix - -BUG FIXES: - -- Save LastSignature/LastSignBytes to `priv_validator.json` for recovery -- Fix event unsubscribe -- Fix fastsync/blockchain reactor - -## 0.7.0 (August 7, 2016) - -BREAKING CHANGES: - -- Strict SemVer starting now! -- Update to ABCI v0.2.0 -- Validation types now called Commit -- NewBlock event only returns the block header - - -FEATURES: - -- TMSP and RPC support TCP and UNIX sockets -- Addition config options including block size and consensus parameters -- New WAL mode `cswal_light`; logs only the validator's own votes -- New RPC endpoints: - - for starting/stopping profilers, and for updating config - - `/broadcast_tx_commit`, returns when tx is included in a block, else an error - - `/unsafe_flush_mempool`, empties the mempool - - -IMPROVEMENTS: - -- Various optimizations -- Remove bad or invalidated transactions from the mempool cache (allows later duplicates) -- More elaborate testing using CircleCI including benchmarking throughput on 4 digitalocean droplets - -BUG FIXES: - -- Various fixes to WAL and replay logic -- Various race conditions - -## PreHistory - -Strict versioning only began with the release of v0.7.0, in late summer 2016. -The project itself began in early summer 2014 and was workable decentralized cryptocurrency software by the end of that year. -Through the course of 2015, in collaboration with Eris Industries (now Monax Indsutries), -many additional features were integrated, including an implementation from scratch of the Ethereum Virtual Machine. -That implementation now forms the heart of [Burrow](https://github.com/hyperledger/burrow). -In the later half of 2015, the consensus algorithm was upgraded with a more asynchronous design and a more deterministic and robust implementation. - -By late 2015, frustration with the difficulty of forking a large monolithic stack to create alternative cryptocurrency designs led to the -invention of the Application Blockchain Interface (ABCI), then called the Tendermint Socket Protocol (TMSP). -The Ethereum Virtual Machine and various other transaction features were removed, and Tendermint was whittled down to a core consensus engine -driving an application running in another process. -The ABCI interface and implementation were iterated on and improved over the course of 2016, -until versioned history kicked in with v0.7.0. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index d47c0f15e..000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,56 +0,0 @@ -# The Tendermint Code of Conduct -This code of conduct applies to all projects run by the Tendermint/COSMOS team and hence to tendermint. - - ----- - - -# Conduct -## Contact: adrian@tendermint.com - -* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic. - -* On Slack, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all. - -* Please be kind and courteous. There’s no need to be mean or rude. - -* Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer. - -* Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works. - -* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behaviour. We interpret the term “harassment” as including the definition in the [Citizen Code of Conduct](http://citizencodeofconduct.org/); if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don’t tolerate behavior that excludes people in socially marginalized groups. - -* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel admins or the person mentioned above immediately. Whether you’re a regular contributor or a newcomer, we care about making this community a safe place for you and we’ve got your back. - -* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behaviour is not welcome. - - ----- - - -# Moderation -These are the policies for upholding our community’s standards of conduct. If you feel that a thread needs moderation, please contact the above mentioned person. - -1. Remarks that violate the Tendermint/COSMOS standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.) - -2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed. - -3. Moderators will first respond to such remarks with a warning. - -4. If the warning is unheeded, the user will be “kicked,” i.e., kicked out of the communication channel to cool off. - -5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded. - -6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology. - -7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, in private. Complaints about bans in-channel are not allowed. - -8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others. - -In the Tendermint/COSMOS community we strive to go the extra step to look out for each other. Don’t just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they’re off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely. - -And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could’ve communicated better — remember that it’s your responsibility to make your fellow Cosmonauts comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust. - -The enforcement policies listed above apply to all official Tendermint/COSMOS venues.For other projects adopting the Tendermint/COSMOS Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion. - -*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling), the [Contributor Covenant v1.3.0](http://contributor-covenant.org/version/1/3/0/) and the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 5fd2d982f..000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,117 +0,0 @@ -# Contributing - -Thank you for considering making contributions to Tendermint and related repositories! Start by taking a look at the [coding repo](https://github.com/tendermint/coding) for overall information on repository workflow and standards. - -Please follow standard github best practices: fork the repo, branch from the tip of develop, make some commits, and submit a pull request to develop. See the [open issues](https://github.com/tendermint/tendermint/issues) for things we need help with! - -Please make sure to use `gofmt` before every commit - the easiest way to do this is have your editor run it for you upon saving a file. - -## Forking - -Please note that Go requires code to live under absolute paths, which complicates forking. -While my fork lives at `https://github.com/ebuchman/tendermint`, -the code should never exist at `$GOPATH/src/github.com/ebuchman/tendermint`. -Instead, we use `git remote` to add the fork as a new remote for the original repo, -`$GOPATH/src/github.com/tendermint/tendermint `, and do all the work there. - -For instance, to create a fork and work on a branch of it, I would: - - * Create the fork on github, using the fork button. - * Go to the original repo checked out locally (ie. `$GOPATH/src/github.com/tendermint/tendermint`) - * `git remote rename origin upstream` - * `git remote add origin git@github.com:ebuchman/basecoin.git` - -Now `origin` refers to my fork and `upstream` refers to the tendermint version. -So I can `git push -u origin master` to update my fork, and make pull requests to tendermint from there. -Of course, replace `ebuchman` with your git handle. - -To pull in updates from the origin repo, run - - * `git fetch upstream` - * `git rebase upstream/master` (or whatever branch you want) - -Please don't make Pull Requests to `master`. - -## Dependencies - -We use [dep](https://github.com/golang/dep) to manage dependencies. - -That said, the master branch of every Tendermint repository should just build -with `go get`, which means they should be kept up-to-date with their -dependencies so we can get away with telling people they can just `go get` our -software. - -Since some dependencies are not under our control, a third party may break our -build, in which case we can fall back on `dep ensure` (or `make -get_vendor_deps`). Even for dependencies under our control, dep helps us to -keep multiple repos in sync as they evolve. Anything with an executable, such -as apps, tools, and the core, should use dep. - -Run `dep status` to get a list of vendored dependencies that may not be -up-to-date. - -## Vagrant - -If you are a [Vagrant](https://www.vagrantup.com/) user, you can get started -hacking Tendermint with the commands below. - -NOTE: In case you installed Vagrant in 2017, you might need to run -`vagrant box update` to upgrade to the latest `ubuntu/xenial64`. - -``` -vagrant up -vagrant ssh -make test -``` - -## Testing - -All repos should be hooked up to [CircleCI](https://circleci.com/). - -If they have `.go` files in the root directory, they will be automatically -tested by circle using `go test -v -race ./...`. If not, they will need a -`circle.yml`. Ideally, every repo has a `Makefile` that defines `make test` and -includes its continuous integration status using a badge in the `README.md`. - -## Branching Model and Release - -User-facing repos should adhere to the branching model: http://nvie.com/posts/a-successful-git-branching-model/. -That is, these repos should be well versioned, and any merge to master requires a version bump and tagged release. - -Libraries need not follow the model strictly, but would be wise to, -especially `go-p2p` and `go-rpc`, as their versions are referenced in tendermint core. - -### Development Procedure: -- the latest state of development is on `develop` -- `develop` must never fail `make test` -- no --force onto `develop` (except when reverting a broken commit, which should seldom happen) -- create a development branch either on github.com/tendermint/tendermint, or your fork (using `git add origin`) -- before submitting a pull request, begin `git rebase` on top of `develop` - -### Pull Merge Procedure: -- ensure pull branch is rebased on develop -- run `make test` to ensure that all tests pass -- merge pull request -- the `unstable` branch may be used to aggregate pull merges before testing once -- push master may request that pull requests be rebased on top of `unstable` - -### Release Procedure: -- start on `develop` -- run integration tests (see `test_integrations` in Makefile) -- prepare changelog/release issue -- bump versions -- push to release-vX.X.X to run the extended integration tests on the CI -- merge to master -- merge master back to develop - -### Hotfix Procedure: -- start on `master` -- checkout a new branch named hotfix-vX.X.X -- make the required changes - - these changes should be small and an absolute necessity - - add a note to CHANGELOG.md -- bumb versions -- push to hotfix-vX.X.X to run the extended integration tests on the CI -- merge hotfix-vX.X.X to master -- merge hotfix-vX.X.X to develop -- delete the hotfix-vX.X.X branch diff --git a/DOCKER/.gitignore b/DOCKER/.gitignore deleted file mode 100644 index 9059c6848..000000000 --- a/DOCKER/.gitignore +++ /dev/null @@ -1 +0,0 @@ -tendermint diff --git a/DOCKER/Dockerfile b/DOCKER/Dockerfile deleted file mode 100644 index 4a855f425..000000000 --- a/DOCKER/Dockerfile +++ /dev/null @@ -1,39 +0,0 @@ -FROM alpine:3.7 -MAINTAINER Greg Szabo - -# Tendermint will be looking for the genesis file in /tendermint/config/genesis.json -# (unless you change `genesis_file` in config.toml). You can put your config.toml and -# private validator file into /tendermint/config. -# -# The /tendermint/data dir is used by tendermint to store state. -ENV TMHOME /tendermint - -# OS environment setup -# Set user right away for determinism, create directory for persistence and give our user ownership -# jq and curl used for extracting `pub_key` from private validator while -# deploying tendermint with Kubernetes. It is nice to have bash so the users -# could execute bash commands. -RUN apk update && \ - apk upgrade && \ - apk --no-cache add curl jq bash && \ - addgroup tmuser && \ - adduser -S -G tmuser tmuser -h "$TMHOME" - -# Run the container with tmuser by default. (UID=100, GID=1000) -USER tmuser - -# Expose the data directory as a volume since there's mutable state in there -VOLUME [ $TMHOME ] - -WORKDIR $TMHOME - -# p2p and rpc port -EXPOSE 26656 26657 - -ENTRYPOINT ["/usr/bin/tendermint"] -CMD ["node", "--moniker=`hostname`"] -STOPSIGNAL SIGTERM - -ARG BINARY=tendermint -COPY $BINARY /usr/bin/tendermint - diff --git a/DOCKER/Dockerfile.develop b/DOCKER/Dockerfile.develop deleted file mode 100644 index 5759e7658..000000000 --- a/DOCKER/Dockerfile.develop +++ /dev/null @@ -1,35 +0,0 @@ -FROM alpine:3.7 - -ENV DATA_ROOT /tendermint -ENV TMHOME $DATA_ROOT - -RUN addgroup tmuser && \ - adduser -S -G tmuser tmuser - -RUN mkdir -p $DATA_ROOT && \ - chown -R tmuser:tmuser $DATA_ROOT - -RUN apk add --no-cache bash curl jq - -ENV GOPATH /go -ENV PATH "$PATH:/go/bin" -RUN mkdir -p /go/src/github.com/tendermint/tendermint && \ - apk add --no-cache go build-base git && \ - cd /go/src/github.com/tendermint/tendermint && \ - git clone https://github.com/tendermint/tendermint . && \ - git checkout develop && \ - make get_tools && \ - make get_vendor_deps && \ - make install && \ - cd - && \ - rm -rf /go/src/github.com/tendermint/tendermint && \ - apk del go build-base git - -VOLUME $DATA_ROOT - -EXPOSE 26656 -EXPOSE 26657 - -ENTRYPOINT ["tendermint"] - -CMD ["node", "--moniker=`hostname`", "--proxy_app=kvstore"] diff --git a/DOCKER/Dockerfile.testing b/DOCKER/Dockerfile.testing deleted file mode 100644 index b82afe2a8..000000000 --- a/DOCKER/Dockerfile.testing +++ /dev/null @@ -1,18 +0,0 @@ -FROM golang:1.10.1 - - -# Grab deps (jq, hexdump, xxd, killall) -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - jq bsdmainutils vim-common psmisc netcat - -# Add testing deps for curl -RUN echo 'deb http://httpredir.debian.org/debian testing main non-free contrib' >> /etc/apt/sources.list && \ - apt-get update && \ - apt-get install -y --no-install-recommends curl - -VOLUME /go - -EXPOSE 26656 -EXPOSE 26657 - diff --git a/DOCKER/Makefile b/DOCKER/Makefile deleted file mode 100644 index 32510ebbb..000000000 --- a/DOCKER/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -build: - @sh -c "'$(CURDIR)/build.sh'" - -push: - @sh -c "'$(CURDIR)/push.sh'" - -build_develop: - docker build -t "tendermint/tendermint:develop" -f Dockerfile.develop . - -build_testing: - docker build --tag tendermint/testing -f ./Dockerfile.testing . - -push_develop: - docker push "tendermint/tendermint:develop" - -.PHONY: build build_develop push push_develop diff --git a/DOCKER/README.md b/DOCKER/README.md deleted file mode 100644 index 43edce0fc..000000000 --- a/DOCKER/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# Docker - -## Supported tags and respective `Dockerfile` links - -- `0.17.1`, `latest` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/208ac32fa266657bd6c304e84ec828aa252bb0b8/DOCKER/Dockerfile) -- `0.15.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/170777300ea92dc21a8aec1abc16cb51812513a4/DOCKER/Dockerfile) -- `0.13.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/a28b3fff49dce2fb31f90abb2fc693834e0029c2/DOCKER/Dockerfile) -- `0.12.1` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/457c688346b565e90735431619ca3ca597ef9007/DOCKER/Dockerfile) -- `0.12.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/70d8afa6e952e24c573ece345560a5971bf2cc0e/DOCKER/Dockerfile) -- `0.11.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/9177cc1f64ca88a4a0243c5d1773d10fba67e201/DOCKER/Dockerfile) -- `0.10.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/e5342f4054ab784b2cd6150e14f01053d7c8deb2/DOCKER/Dockerfile) -- `0.9.1`, `0.9`, [(Dockerfile)](https://github.com/tendermint/tendermint/blob/809e0e8c5933604ba8b2d096803ada7c5ec4dfd3/DOCKER/Dockerfile) -- `0.9.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/d474baeeea6c22b289e7402449572f7c89ee21da/DOCKER/Dockerfile) -- `0.8.0`, `0.8` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/bf64dd21fdb193e54d8addaaaa2ecf7ac371de8c/DOCKER/Dockerfile) -- `develop` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/master/DOCKER/Dockerfile.develop) - -`develop` tag points to the [develop](https://github.com/tendermint/tendermint/tree/develop) branch. - -## Quick reference - -* **Where to get help:** - https://cosmos.network/community - -* **Where to file issues:** - https://github.com/tendermint/tendermint/issues - -* **Supported Docker versions:** - [the latest release](https://github.com/moby/moby/releases) (down to 1.6 on a best-effort basis) - -## Tendermint - -Tendermint Core is Byzantine Fault Tolerant (BFT) middleware that takes a state transition machine, written in any programming language, and securely replicates it on many machines. - -For more background, see the [introduction](https://tendermint.readthedocs.io/en/master/introduction.html). - -To get started developing applications, see the [application developers guide](https://tendermint.readthedocs.io/en/master/getting-started.html). - -## How to use this image - -### Start one instance of the Tendermint core with the `kvstore` app - -A quick example of a built-in app and Tendermint core in one container. - -``` -docker run -it --rm -v "/tmp:/tendermint" tendermint/tendermint init -docker run -it --rm -v "/tmp:/tendermint" tendermint/tendermint node --proxy_app=kvstore -``` - -## Local cluster - -To run a 4-node network, see the `Makefile` in the root of [the repo](https://github.com/tendermint/tendermint/master/Makefile) and run: - -``` -make build-linux -make build-docker-localnode -make localnet-start -``` - -Note that this will build and use a different image than the ones provided here. - -## License - -- Tendermint's license is [Apache 2.0](https://github.com/tendermint/tendermint/master/LICENSE). - -## Contributing - -Contributions are most welcome! See the [contributing file](https://github.com/tendermint/tendermint/blob/master/CONTRIBUTING.md) for more information. diff --git a/DOCKER/build.sh b/DOCKER/build.sh deleted file mode 100755 index ee617cc63..000000000 --- a/DOCKER/build.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -set -e - -# Get the tag from the version, or try to figure it out. -if [ -z "$TAG" ]; then - TAG=$(awk -F\" '/Version =/ { print $2; exit }' < ../version/version.go) -fi -if [ -z "$TAG" ]; then - echo "Please specify a tag." - exit 1 -fi - -TAG_NO_PATCH=${TAG%.*} - -read -p "==> Build 3 docker images with the following tags (latest, $TAG, $TAG_NO_PATCH)? y/n" -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]] -then - docker build -t "tendermint/tendermint" -t "tendermint/tendermint:$TAG" -t "tendermint/tendermint:$TAG_NO_PATCH" . -fi diff --git a/DOCKER/push.sh b/DOCKER/push.sh deleted file mode 100755 index 32741dce8..000000000 --- a/DOCKER/push.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -set -e - -# Get the tag from the version, or try to figure it out. -if [ -z "$TAG" ]; then - TAG=$(awk -F\" '/Version =/ { print $2; exit }' < ../version/version.go) -fi -if [ -z "$TAG" ]; then - echo "Please specify a tag." - exit 1 -fi - -TAG_NO_PATCH=${TAG%.*} - -read -p "==> Push 3 docker images with the following tags (latest, $TAG, $TAG_NO_PATCH)? y/n" -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]] -then - docker push "tendermint/tendermint:latest" - docker push "tendermint/tendermint:$TAG" - docker push "tendermint/tendermint:$TAG_NO_PATCH" -fi diff --git a/Gopkg.lock b/Gopkg.lock deleted file mode 100644 index e45b84d13..000000000 --- a/Gopkg.lock +++ /dev/null @@ -1,431 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - branch = "master" - name = "github.com/beorn7/perks" - packages = ["quantile"] - revision = "3a771d992973f24aa725d07868b467d1ddfceafb" - -[[projects]] - branch = "master" - name = "github.com/btcsuite/btcd" - packages = ["btcec"] - revision = "86fed781132ac890ee03e906e4ecd5d6fa180c64" - -[[projects]] - name = "github.com/davecgh/go-spew" - packages = ["spew"] - revision = "346938d642f2ec3594ed81d874461961cd0faa76" - version = "v1.1.0" - -[[projects]] - branch = "master" - name = "github.com/ebuchman/fail-test" - packages = ["."] - revision = "95f809107225be108efcf10a3509e4ea6ceef3c4" - -[[projects]] - name = "github.com/fortytw2/leaktest" - packages = ["."] - revision = "a5ef70473c97b71626b9abeda80ee92ba2a7de9e" - version = "v1.2.0" - -[[projects]] - name = "github.com/fsnotify/fsnotify" - packages = ["."] - revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9" - version = "v1.4.7" - -[[projects]] - name = "github.com/go-kit/kit" - packages = [ - "log", - "log/level", - "log/term", - "metrics", - "metrics/discard", - "metrics/internal/lv", - "metrics/prometheus" - ] - revision = "4dc7be5d2d12881735283bcab7352178e190fc71" - version = "v0.6.0" - -[[projects]] - name = "github.com/go-logfmt/logfmt" - packages = ["."] - revision = "390ab7935ee28ec6b286364bba9b4dd6410cb3d5" - version = "v0.3.0" - -[[projects]] - name = "github.com/go-stack/stack" - packages = ["."] - revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc" - version = "v1.7.0" - -[[projects]] - name = "github.com/gogo/protobuf" - packages = [ - "gogoproto", - "jsonpb", - "proto", - "protoc-gen-gogo/descriptor", - "sortkeys", - "types" - ] - revision = "1adfc126b41513cc696b209667c8656ea7aac67c" - version = "v1.0.0" - -[[projects]] - name = "github.com/golang/protobuf" - packages = [ - "proto", - "ptypes", - "ptypes/any", - "ptypes/duration", - "ptypes/timestamp" - ] - revision = "925541529c1fa6821df4e44ce2723319eb2be768" - version = "v1.0.0" - -[[projects]] - branch = "master" - name = "github.com/golang/snappy" - packages = ["."] - revision = "2e65f85255dbc3072edf28d6b5b8efc472979f5a" - -[[projects]] - name = "github.com/gorilla/websocket" - packages = ["."] - revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b" - version = "v1.2.0" - -[[projects]] - branch = "master" - name = "github.com/hashicorp/hcl" - packages = [ - ".", - "hcl/ast", - "hcl/parser", - "hcl/printer", - "hcl/scanner", - "hcl/strconv", - "hcl/token", - "json/parser", - "json/scanner", - "json/token" - ] - revision = "ef8a98b0bbce4a65b5aa4c368430a80ddc533168" - -[[projects]] - name = "github.com/inconshreveable/mousetrap" - packages = ["."] - revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" - version = "v1.0" - -[[projects]] - branch = "master" - name = "github.com/jmhodges/levigo" - packages = ["."] - revision = "c42d9e0ca023e2198120196f842701bb4c55d7b9" - -[[projects]] - branch = "master" - name = "github.com/kr/logfmt" - packages = ["."] - revision = "b84e30acd515aadc4b783ad4ff83aff3299bdfe0" - -[[projects]] - name = "github.com/magiconair/properties" - packages = ["."] - revision = "c2353362d570a7bfa228149c62842019201cfb71" - version = "v1.8.0" - -[[projects]] - name = "github.com/matttproud/golang_protobuf_extensions" - packages = ["pbutil"] - revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c" - version = "v1.0.1" - -[[projects]] - branch = "master" - name = "github.com/mitchellh/mapstructure" - packages = ["."] - revision = "bb74f1db0675b241733089d5a1faa5dd8b0ef57b" - -[[projects]] - name = "github.com/pelletier/go-toml" - packages = ["."] - revision = "c01d1270ff3e442a8a57cddc1c92dc1138598194" - version = "v1.2.0" - -[[projects]] - name = "github.com/pkg/errors" - packages = ["."] - revision = "645ef00459ed84a119197bfb8d8205042c6df63d" - version = "v0.8.0" - -[[projects]] - name = "github.com/pmezard/go-difflib" - packages = ["difflib"] - revision = "792786c7400a136282c1664665ae0a8db921c6c2" - version = "v1.0.0" - -[[projects]] - name = "github.com/prometheus/client_golang" - packages = [ - "prometheus", - "prometheus/promhttp" - ] - revision = "c5b7fccd204277076155f10851dad72b76a49317" - version = "v0.8.0" - -[[projects]] - branch = "master" - name = "github.com/prometheus/client_model" - packages = ["go"] - revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c" - -[[projects]] - branch = "master" - name = "github.com/prometheus/common" - packages = [ - "expfmt", - "internal/bitbucket.org/ww/goautoneg", - "model" - ] - revision = "7600349dcfe1abd18d72d3a1770870d9800a7801" - -[[projects]] - branch = "master" - name = "github.com/prometheus/procfs" - packages = [ - ".", - "internal/util", - "nfs", - "xfs" - ] - revision = "94663424ae5ae9856b40a9f170762b4197024661" - -[[projects]] - branch = "master" - name = "github.com/rcrowley/go-metrics" - packages = ["."] - revision = "e2704e165165ec55d062f5919b4b29494e9fa790" - -[[projects]] - name = "github.com/spf13/afero" - packages = [ - ".", - "mem" - ] - revision = "787d034dfe70e44075ccc060d346146ef53270ad" - version = "v1.1.1" - -[[projects]] - name = "github.com/spf13/cast" - packages = ["."] - revision = "8965335b8c7107321228e3e3702cab9832751bac" - version = "v1.2.0" - -[[projects]] - name = "github.com/spf13/cobra" - packages = ["."] - revision = "ef82de70bb3f60c65fb8eebacbb2d122ef517385" - version = "v0.0.3" - -[[projects]] - branch = "master" - name = "github.com/spf13/jwalterweatherman" - packages = ["."] - revision = "7c0cea34c8ece3fbeb2b27ab9b59511d360fb394" - -[[projects]] - name = "github.com/spf13/pflag" - packages = ["."] - revision = "583c0c0531f06d5278b7d917446061adc344b5cd" - version = "v1.0.1" - -[[projects]] - name = "github.com/spf13/viper" - packages = ["."] - revision = "b5e8006cbee93ec955a89ab31e0e3ce3204f3736" - version = "v1.0.2" - -[[projects]] - name = "github.com/stretchr/testify" - packages = [ - "assert", - "require" - ] - revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686" - version = "v1.2.2" - -[[projects]] - branch = "master" - name = "github.com/syndtr/goleveldb" - packages = [ - "leveldb", - "leveldb/cache", - "leveldb/comparer", - "leveldb/errors", - "leveldb/filter", - "leveldb/iterator", - "leveldb/journal", - "leveldb/memdb", - "leveldb/opt", - "leveldb/storage", - "leveldb/table", - "leveldb/util" - ] - revision = "e2150783cd35f5b607daca48afd8c57ec54cc995" - -[[projects]] - name = "github.com/tendermint/abci" - packages = [ - "client", - "example/code", - "example/counter", - "example/kvstore", - "server", - "types" - ] - revision = "198dccf0ddfd1bb176f87657e3286a05a6ed9540" - version = "v0.12.0" - -[[projects]] - branch = "master" - name = "github.com/tendermint/ed25519" - packages = [ - ".", - "edwards25519", - "extra25519" - ] - revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057" - -[[projects]] - name = "github.com/tendermint/go-amino" - packages = ["."] - revision = "ed62928576cfcaf887209dc96142cd79cdfff389" - version = "0.9.9" - -[[projects]] - name = "github.com/tendermint/go-crypto" - packages = ["."] - revision = "915416979bf70efa4bcbf1c6cd5d64c5fff9fc19" - version = "v0.6.2" - -[[projects]] - name = "github.com/tendermint/tmlibs" - packages = [ - "autofile", - "cli", - "cli/flags", - "clist", - "common", - "db", - "flowrate", - "log", - "merkle", - "test" - ] - revision = "692f1d86a6e2c0efa698fd1e4541b68c74ffaf38" - version = "v0.8.4" - -[[projects]] - branch = "master" - name = "golang.org/x/crypto" - packages = [ - "curve25519", - "nacl/box", - "nacl/secretbox", - "openpgp/armor", - "openpgp/errors", - "poly1305", - "ripemd160", - "salsa20/salsa" - ] - revision = "8ac0e0d97ce45cd83d1d7243c060cb8461dda5e9" - -[[projects]] - branch = "master" - name = "golang.org/x/net" - packages = [ - "context", - "http/httpguts", - "http2", - "http2/hpack", - "idna", - "internal/timeseries", - "trace" - ] - revision = "db08ff08e8622530d9ed3a0e8ac279f6d4c02196" - -[[projects]] - branch = "master" - name = "golang.org/x/sys" - packages = ["unix"] - revision = "a9e25c09b96b8870693763211309e213c6ef299d" - -[[projects]] - name = "golang.org/x/text" - packages = [ - "collate", - "collate/build", - "internal/colltab", - "internal/gen", - "internal/tag", - "internal/triegen", - "internal/ucd", - "language", - "secure/bidirule", - "transform", - "unicode/bidi", - "unicode/cldr", - "unicode/norm", - "unicode/rangetable" - ] - revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" - version = "v0.3.0" - -[[projects]] - name = "google.golang.org/genproto" - packages = ["googleapis/rpc/status"] - revision = "7fd901a49ba6a7f87732eb344f6e3c5b19d1b200" - -[[projects]] - name = "google.golang.org/grpc" - packages = [ - ".", - "balancer", - "codes", - "connectivity", - "credentials", - "grpclb/grpc_lb_v1/messages", - "grpclog", - "internal", - "keepalive", - "metadata", - "naming", - "peer", - "resolver", - "stats", - "status", - "tap", - "transport" - ] - revision = "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" - version = "v1.7.5" - -[[projects]] - name = "gopkg.in/yaml.v2" - packages = ["."] - revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" - version = "v2.2.1" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "3bd388e520a08cd0aa14df2d6f5ecb46449d7c36fd80cf52eb775798e6accbaa" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml deleted file mode 100644 index 13339e550..000000000 --- a/Gopkg.toml +++ /dev/null @@ -1,103 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - - -[[constraint]] - name = "github.com/ebuchman/fail-test" - branch = "master" - -[[constraint]] - name = "github.com/fortytw2/leaktest" - branch = "master" - -[[constraint]] - name = "github.com/go-kit/kit" - version = "~0.6.0" - -[[constraint]] - name = "github.com/gogo/protobuf" - version = "~1.0.0" - -[[constraint]] - name = "github.com/golang/protobuf" - version = "~1.0.0" - -[[constraint]] - name = "github.com/gorilla/websocket" - version = "~1.2.0" - -[[constraint]] - name = "github.com/pkg/errors" - version = "~0.8.0" - -[[constraint]] - name = "github.com/rcrowley/go-metrics" - branch = "master" - -[[constraint]] - name = "github.com/spf13/cobra" - version = "~0.0.1" - -[[constraint]] - name = "github.com/spf13/viper" - version = "~1.0.0" - -[[constraint]] - name = "github.com/stretchr/testify" - version = "~1.2.1" - -[[constraint]] - name = "github.com/tendermint/abci" - version = "~0.12.0" - -[[constraint]] - name = "github.com/tendermint/go-crypto" - version = "~0.6.2" - -[[constraint]] - name = "github.com/tendermint/go-amino" - version = "=0.9.9" - -[[override]] - name = "github.com/tendermint/tmlibs" - version = "~0.8.4" - -[[constraint]] - name = "google.golang.org/grpc" - version = "~1.7.3" - -# this got updated and broke, so locked to an old working commit ... -[[override]] - name = "google.golang.org/genproto" - revision = "7fd901a49ba6a7f87732eb344f6e3c5b19d1b200" - -[prune] - go-tests = true - unused-packages = true - -[[constraint]] - name = "github.com/prometheus/client_golang" - version = "0.8.0" diff --git a/LICENSE b/LICENSE deleted file mode 100644 index bb66bb350..000000000 --- a/LICENSE +++ /dev/null @@ -1,204 +0,0 @@ -Tendermint Core -License: Apache2.0 - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016 All in Bits, Inc - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Makefile b/Makefile deleted file mode 100755 index 079c58f90..000000000 --- a/Makefile +++ /dev/null @@ -1,236 +0,0 @@ -GOTOOLS = \ - github.com/golang/dep/cmd/dep \ - gopkg.in/alecthomas/gometalinter.v2 -PACKAGES=$(shell go list ./... | grep -v '/vendor/') -BUILD_TAGS?=tendermint -BUILD_FLAGS = -ldflags "-X github.com/tendermint/tendermint/version.GitCommit=`git rev-parse --short=8 HEAD`" - -all: check build test install - -check: check_tools ensure_deps - - -######################################## -### Build - -build: - CGO_ENABLED=0 go build $(BUILD_FLAGS) -tags '$(BUILD_TAGS)' -o build/tendermint ./cmd/tendermint/ - -build_race: - CGO_ENABLED=0 go build -race $(BUILD_FLAGS) -tags '$(BUILD_TAGS)' -o build/tendermint ./cmd/tendermint - -install: - CGO_ENABLED=0 go install $(BUILD_FLAGS) -tags '$(BUILD_TAGS)' ./cmd/tendermint - -######################################## -### Distribution - -# dist builds binaries for all platforms and packages them for distribution -dist: - @BUILD_TAGS='$(BUILD_TAGS)' sh -c "'$(CURDIR)/scripts/dist.sh'" - -######################################## -### Tools & dependencies - -check_tools: - @# https://stackoverflow.com/a/25668869 - @echo "Found tools: $(foreach tool,$(notdir $(GOTOOLS)),\ - $(if $(shell which $(tool)),$(tool),$(error "No $(tool) in PATH")))" - -get_tools: - @echo "--> Installing tools" - go get -u -v $(GOTOOLS) - @gometalinter.v2 --install - -update_tools: - @echo "--> Updating tools" - @go get -u $(GOTOOLS) - -#Run this from CI -get_vendor_deps: - @rm -rf vendor/ - @echo "--> Running dep" - @dep ensure -vendor-only - - -#Run this locally. -ensure_deps: - @rm -rf vendor/ - @echo "--> Running dep" - @dep ensure - -draw_deps: - @# requires brew install graphviz or apt-get install graphviz - go get github.com/RobotsAndPencils/goviz - @goviz -i github.com/tendermint/tendermint/cmd/tendermint -d 3 | dot -Tpng -o dependency-graph.png - -get_deps_bin_size: - @# Copy of build recipe with additional flags to perform binary size analysis - $(eval $(shell go build -work -a $(BUILD_FLAGS) -tags '$(BUILD_TAGS)' -o build/tendermint ./cmd/tendermint/ 2>&1)) - @find $(WORK) -type f -name "*.a" | xargs -I{} du -hxs "{}" | sort -rh | sed -e s:${WORK}/::g > deps_bin_size.log - @echo "Results can be found here: $(CURDIR)/deps_bin_size.log" - -######################################## -### Testing - -## required to be run first by most tests -build_docker_test_image: - docker build -t tester -f ./test/docker/Dockerfile . - -### coverage, app, persistence, and libs tests -test_cover: - # run the go unit tests with coverage - bash test/test_cover.sh - -test_apps: - # run the app tests using bash - # requires `abci-cli` and `tendermint` binaries installed - bash test/app/test.sh - -test_persistence: - # run the persistence tests using bash - # requires `abci-cli` installed - docker run --name run_persistence -t tester bash test/persist/test_failure_indices.sh - - # TODO undockerize - # bash test/persist/test_failure_indices.sh - -test_p2p: - docker rm -f rsyslog || true - rm -rf test/logs || true - mkdir test/logs - cd test/ - docker run -d -v "logs:/var/log/" -p 127.0.0.1:5514:514/udp --name rsyslog voxxit/rsyslog - cd .. - # requires 'tester' the image from above - bash test/p2p/test.sh tester - -need_abci: - bash scripts/install_abci_apps.sh - -test_integrations: - make build_docker_test_image - make get_tools - make get_vendor_deps - make install - make need_abci - make test_cover - make test_apps - make test_persistence - make test_p2p - -test_release: - @go test -tags release $(PACKAGES) - -test100: - @for i in {1..100}; do make test; done - -vagrant_test: - vagrant up - vagrant ssh -c 'make test_integrations' - -### go tests -test: - @echo "--> Running go test" - @go test $(PACKAGES) - -test_race: - @echo "--> Running go test --race" - @go test -v -race $(PACKAGES) - - -######################################## -### Formatting, linting, and vetting - -fmt: - @go fmt ./... - -metalinter: - @echo "--> Running linter" - @gometalinter.v2 --vendor --deadline=600s --disable-all \ - --enable=deadcode \ - --enable=gosimple \ - --enable=misspell \ - --enable=safesql \ - ./... - #--enable=gas \ - #--enable=maligned \ - #--enable=dupl \ - #--enable=errcheck \ - #--enable=goconst \ - #--enable=gocyclo \ - #--enable=goimports \ - #--enable=golint \ <== comments on anything exported - #--enable=gotype \ - #--enable=ineffassign \ - #--enable=interfacer \ - #--enable=megacheck \ - #--enable=staticcheck \ - #--enable=structcheck \ - #--enable=unconvert \ - #--enable=unparam \ - #--enable=unused \ - #--enable=varcheck \ - #--enable=vet \ - #--enable=vetshadow \ - -metalinter_all: - @echo "--> Running linter (all)" - gometalinter.v2 --vendor --deadline=600s --enable-all --disable=lll ./... - -########################################################### -### Docker image - -build-docker: - cp build/tendermint DOCKER/tendermint - docker build --label=tendermint --tag="tendermint/tendermint" DOCKER - rm -rf DOCKER/tendermint - -########################################################### -### Local testnet using docker - -# Build linux binary on other platforms -build-linux: - GOOS=linux GOARCH=amd64 $(MAKE) build - -build-docker-localnode: - cd networks/local - make - -# Run a 4-node testnet locally -localnet-start: localnet-stop - @if ! [ -f build/node0/config/genesis.json ]; then docker run --rm -v $(CURDIR)/build:/tendermint:Z tendermint/localnode testnet --v 4 --o . --populate-persistent-peers --starting-ip-address 192.167.10.2 ; fi - docker-compose up - -# Stop testnet -localnet-stop: - docker-compose down - -########################################################### -### Remote full-nodes (sentry) using terraform and ansible - -# Server management -sentry-start: - @if [ -z "$(DO_API_TOKEN)" ]; then echo "DO_API_TOKEN environment variable not set." ; false ; fi - @if ! [ -f $(HOME)/.ssh/id_rsa.pub ]; then ssh-keygen ; fi - cd networks/remote/terraform && terraform init && terraform apply -var DO_API_TOKEN="$(DO_API_TOKEN)" -var SSH_KEY_FILE="$(HOME)/.ssh/id_rsa.pub" - @if ! [ -f $(CURDIR)/build/node0/config/genesis.json ]; then docker run --rm -v $(CURDIR)/build:/tendermint:Z tendermint/localnode testnet --v 0 --n 4 --o . ; fi - cd networks/remote/ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory/digital_ocean.py -l sentrynet install.yml - @echo "Next step: Add your validator setup in the genesis.json and config.tml files and run \"make sentry-config\". (Public key of validator, chain ID, peer IP and node ID.)" - -# Configuration management -sentry-config: - cd networks/remote/ansible && ansible-playbook -i inventory/digital_ocean.py -l sentrynet config.yml -e BINARY=$(CURDIR)/build/tendermint -e CONFIGDIR=$(CURDIR)/build - -sentry-stop: - @if [ -z "$(DO_API_TOKEN)" ]; then echo "DO_API_TOKEN environment variable not set." ; false ; fi - cd networks/remote/terraform && terraform destroy -var DO_API_TOKEN="$(DO_API_TOKEN)" -var SSH_KEY_FILE="$(HOME)/.ssh/id_rsa.pub" - -# meant for the CI, inspect script & adapt accordingly -build-slate: - bash scripts/slate.sh - -# To avoid unintended conflicts with file names, always add to .PHONY -# unless there is a reason not to. -# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html -.PHONY: check build build_race dist install check_tools get_tools update_tools get_vendor_deps draw_deps test_cover test_apps test_persistence test_p2p test test_race test_integrations test_release test100 vagrant_test fmt build-linux localnet-start localnet-stop build-docker build-docker-localnode sentry-start sentry-config sentry-stop build-slate diff --git a/README.md b/README.md deleted file mode 100644 index 52e93a7cd..000000000 --- a/README.md +++ /dev/null @@ -1,138 +0,0 @@ -# Tendermint - -[Byzantine-Fault Tolerant](https://en.wikipedia.org/wiki/Byzantine_fault_tolerance) -[State Machine Replication](https://en.wikipedia.org/wiki/State_machine_replication). -Or [Blockchain](https://en.wikipedia.org/wiki/Blockchain_(database)) for short. - -[![version](https://img.shields.io/github/tag/tendermint/tendermint.svg)](https://github.com/tendermint/tendermint/releases/latest) -[![API Reference]( -https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f676f6c616e672f6764646f3f7374617475732e737667 -)](https://godoc.org/github.com/tendermint/tendermint) -[![Go version](https://img.shields.io/badge/go-1.9.2-blue.svg)](https://github.com/moovweb/gvm) -[![riot.im](https://img.shields.io/badge/riot.im-JOIN%20CHAT-green.svg)](https://riot.im/app/#/room/#tendermint:matrix.org) -[![license](https://img.shields.io/github/license/tendermint/tendermint.svg)](https://github.com/tendermint/tendermint/blob/master/LICENSE) -[![](https://tokei.rs/b1/github/tendermint/tendermint?category=lines)](https://github.com/tendermint/tendermint) - - -Branch | Tests | Coverage -----------|-------|---------- -master | [![CircleCI](https://circleci.com/gh/tendermint/tendermint/tree/master.svg?style=shield)](https://circleci.com/gh/tendermint/tendermint/tree/master) | [![codecov](https://codecov.io/gh/tendermint/tendermint/branch/master/graph/badge.svg)](https://codecov.io/gh/tendermint/tendermint) -develop | [![CircleCI](https://circleci.com/gh/tendermint/tendermint/tree/develop.svg?style=shield)](https://circleci.com/gh/tendermint/tendermint/tree/develop) | [![codecov](https://codecov.io/gh/tendermint/tendermint/branch/develop/graph/badge.svg)](https://codecov.io/gh/tendermint/tendermint) - -Tendermint Core is Byzantine Fault Tolerant (BFT) middleware that takes a state transition machine - written in any programming language - -and securely replicates it on many machines. - -For protocol details, see [the specification](/docs/spec). - -## A Note on Production Readiness - -While Tendermint is being used in production in private, permissioned -environments, we are still working actively to harden and audit it in preparation -for use in public blockchains, such as the [Cosmos Network](https://cosmos.network/). -We are also still making breaking changes to the protocol and the APIs. -Thus we tag the releases as *alpha software*. - -In any case, if you intend to run Tendermint in production, -please [contact us](https://riot.im/app/#/room/#tendermint:matrix.org) :) - -## Security - -To report a security vulnerability, see our [bug bounty -program](https://tendermint.com/security). - -For examples of the kinds of bugs we're looking for, see [SECURITY.md](SECURITY.md) - -## Minimum requirements - -Requirement|Notes ----|--- -Go version | Go1.9 or higher - -## Install - -See the [install instructions](/docs/install.rst) - -## Quick Start - -- [Single node](/docs/using-tendermint.rst) -- [Local cluster using docker-compose](/networks/local) -- [Remote cluster using terraform and ansible](/docs/terraform-and-ansible.rst) -- [Join the public testnet](https://cosmos.network/testnet) - -## Resources - -### Tendermint Core - -For details about the blockchain data structures and the p2p protocols, see the -the [Tendermint specification](/docs/spec). - -For details on using the software, [Read The Docs](https://tendermint.readthedocs.io/en/master/). -Additional information about some - and eventually all - of the sub-projects below, can be found at Read The Docs. - - -### Sub-projects - -* [ABCI](http://github.com/tendermint/abci), the Application Blockchain Interface -* [Go-Wire](http://github.com/tendermint/go-wire), a deterministic serialization library -* [Go-Crypto](http://github.com/tendermint/go-crypto), an elliptic curve cryptography library -* [TmLibs](http://github.com/tendermint/tmlibs), an assortment of Go libraries used internally -* [IAVL](http://github.com/tendermint/iavl), Merkleized IAVL+ Tree implementation - -### Tools -* [Deployment, Benchmarking, and Monitoring](http://tendermint.readthedocs.io/projects/tools/en/develop/index.html#tendermint-tools) - -### Applications - -* [Cosmos SDK](http://github.com/cosmos/cosmos-sdk); a cryptocurrency application framework -* [Ethermint](http://github.com/tendermint/ethermint); Ethereum on Tendermint -* [Many more](https://tendermint.readthedocs.io/en/master/ecosystem.html#abci-applications) - -### More - -* [Master's Thesis on Tendermint](https://atrium.lib.uoguelph.ca/xmlui/handle/10214/9769) -* [Original Whitepaper](https://tendermint.com/static/docs/tendermint.pdf) -* [Tendermint Blog](https://blog.cosmos.network/tendermint/home) -* [Cosmos Blog](https://blog.cosmos.network) - -## Contributing - -Yay open source! Please see our [contributing guidelines](CONTRIBUTING.md). - -## Versioning - -### SemVer - -Tendermint uses [SemVer](http://semver.org/) to determine when and how the version changes. -According to SemVer, anything in the public API can change at any time before version 1.0.0 - -To provide some stability to Tendermint users in these 0.X.X days, the MINOR version is used -to signal breaking changes across a subset of the total public API. This subset includes all -interfaces exposed to other processes (cli, rpc, p2p, etc.), but does not -include the in-process Go APIs. - -That said, breaking changes in the following packages will be documented in the -CHANGELOG even if they don't lead to MINOR version bumps: - -- types -- rpc/client -- config -- node - -Exported objects in these packages that are not covered by the versioning scheme -are explicitly marked by `// UNSTABLE` in their go doc comment and may change at any time. -Functions, types, and values in any other package may also change at any time. - -### Upgrades - -In an effort to avoid accumulating technical debt prior to 1.0.0, -we do not guarantee that breaking changes (ie. bumps in the MINOR version) -will work with existing tendermint blockchains. In these cases you will -have to start a new blockchain, or write something custom to get the old -data into the new chain. - -However, any bump in the PATCH version should be compatible with existing histories -(if not please open an [issue](https://github.com/tendermint/tendermint/issues)). - -## Code of Conduct - -Please read, understand and adhere to our [code of conduct](CODE_OF_CONDUCT.md). diff --git a/ROADMAP.md b/ROADMAP.md deleted file mode 100644 index 60c284333..000000000 --- a/ROADMAP.md +++ /dev/null @@ -1,23 +0,0 @@ -# Roadmap - -BREAKING CHANGES: -- Better support for injecting randomness -- Upgrade consensus for more real-time use of evidence - -FEATURES: -- Use the chain as its own CA for nodes and validators -- Tooling to run multiple blockchains/apps, possibly in a single process -- State syncing (without transaction replay) -- Add authentication and rate-limitting to the RPC - -IMPROVEMENTS: -- Improve subtleties around mempool caching and logic -- Consensus optimizations: - - cache block parts for faster agreement after round changes - - propagate block parts rarest first -- Better testing of the consensus state machine (ie. use a DSL) -- Auto compiled serialization/deserialization code instead of go-wire reflection - -BUG FIXES: -- Graceful handling/recovery for apps that have non-determinism or fail to halt -- Graceful handling/recovery for violations of safety, or liveness diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index 8b9793782..000000000 --- a/SECURITY.md +++ /dev/null @@ -1,71 +0,0 @@ -# Security - -As part of our [Coordinated Vulnerability Disclosure -Policy](https://tendermint.com/security), we operate a bug bounty. -See the policy for more details on submissions and rewards. - -Here is a list of examples of the kinds of bugs we're most interested in: - -## Specification - -- Conceptual flaws -- Ambiguities, inconsistencies, or incorrect statements -- Mis-match between specification and implementation of any component - -## Consensus - -Assuming less than 1/3 of the voting power is Byzantine (malicious): - -- Validation of blockchain data structures, including blocks, block parts, - votes, and so on -- Execution of blocks -- Validator set changes -- Proposer round robin -- Two nodes committing conflicting blocks for the same height (safety failure) -- A correct node signing conflicting votes -- A node halting (liveness failure) -- Syncing new and old nodes - -## Networking - -- Authenticated encryption (MITM, information leakage) -- Eclipse attacks -- Sybil attacks -- Long-range attacks -- Denial-of-Service - -## RPC - -- Write-access to anything besides sending transactions -- Denial-of-Service -- Leakage of secrets - -## Denial-of-Service - -Attacks may come through the P2P network or the RPC: - -- Amplification attacks -- Resource abuse -- Deadlocks and race conditions -- Panics and unhandled errors - -## Libraries - -- Serialization (Amino) -- Reading/Writing files and databases -- Logging and monitoring - -## Cryptography - -- Elliptic curves for validator signatures -- Hash algorithms and Merkle trees for block validation -- Authenticated encryption for P2P connections - -## Light Client - -- Validation of blockchain data structures -- Correctly validating an incorrect proof -- Incorrectly validating a correct proof -- Syncing validator set changes - - diff --git a/Vagrantfile b/Vagrantfile deleted file mode 100644 index 095a6b061..000000000 --- a/Vagrantfile +++ /dev/null @@ -1,58 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -Vagrant.configure("2") do |config| - config.vm.box = "ubuntu/xenial64" - - config.vm.provider "virtualbox" do |v| - v.memory = 4096 - v.cpus = 2 - end - - config.vm.provision "shell", inline: <<-SHELL - apt-get update - - # install base requirements - apt-get install -y --no-install-recommends wget curl jq zip \ - make shellcheck bsdmainutils psmisc - apt-get install -y language-pack-en - - # install docker - apt-get install -y --no-install-recommends apt-transport-https \ - ca-certificates curl software-properties-common - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - - add-apt-repository \ - "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ - $(lsb_release -cs) \ - stable" - apt-get install -y docker-ce - usermod -a -G docker vagrant - - # install go - wget -q https://dl.google.com/go/go1.10.1.linux-amd64.tar.gz - tar -xvf go1.10.1.linux-amd64.tar.gz - mv go /usr/local - rm -f go1.10.1.linux-amd64.tar.gz - - # cleanup - apt-get autoremove -y - - # set env variables - echo 'export GOROOT=/usr/local/go' >> /home/vagrant/.bash_profile - echo 'export GOPATH=/home/vagrant/go' >> /home/vagrant/.bash_profile - echo 'export PATH=$PATH:$GOROOT/bin:$GOPATH/bin' >> /home/vagrant/.bash_profile - echo 'export LC_ALL=en_US.UTF-8' >> /home/vagrant/.bash_profile - echo 'cd go/src/github.com/tendermint/tendermint' >> /home/vagrant/.bash_profile - - mkdir -p /home/vagrant/go/bin - mkdir -p /home/vagrant/go/src/github.com/tendermint - ln -s /vagrant /home/vagrant/go/src/github.com/tendermint/tendermint - - chown -R vagrant:vagrant /home/vagrant/go - chown vagrant:vagrant /home/vagrant/.bash_profile - - # get all deps and tools, ready to install/test - su - vagrant -c 'source /home/vagrant/.bash_profile' - su - vagrant -c 'cd /home/vagrant/go/src/github.com/tendermint/tendermint && make get_tools && make get_vendor_deps' - SHELL -end diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 1ddf8fdd2..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,13 +0,0 @@ -version: 1.0.{build} -configuration: Release -platform: -- x64 -- x86 -clone_folder: c:\go\path\src\github.com\tendermint\tendermint -before_build: -- cmd: set GOPATH=%GOROOT%\path -- cmd: set PATH=%GOPATH%\bin;%PATH% -- cmd: make get_vendor_deps -build_script: -- cmd: make test -test: off diff --git a/benchmarks/atomic_test.go b/benchmarks/atomic_test.go deleted file mode 100644 index 5fe4832df..000000000 --- a/benchmarks/atomic_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package benchmarks - -import ( - "sync/atomic" - "testing" - "unsafe" -) - -func BenchmarkAtomicUintPtr(b *testing.B) { - b.StopTimer() - pointers := make([]uintptr, 1000) - b.Log(unsafe.Sizeof(pointers[0])) - b.StartTimer() - - for j := 0; j < b.N; j++ { - atomic.StoreUintptr(&pointers[j%1000], uintptr(j)) - } -} - -func BenchmarkAtomicPointer(b *testing.B) { - b.StopTimer() - pointers := make([]unsafe.Pointer, 1000) - b.Log(unsafe.Sizeof(pointers[0])) - b.StartTimer() - - for j := 0; j < b.N; j++ { - atomic.StorePointer(&pointers[j%1000], unsafe.Pointer(uintptr(j))) - } -} diff --git a/benchmarks/blockchain/.gitignore b/benchmarks/blockchain/.gitignore deleted file mode 100644 index 9e67bd47d..000000000 --- a/benchmarks/blockchain/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -data - diff --git a/benchmarks/blockchain/localsync.sh b/benchmarks/blockchain/localsync.sh deleted file mode 100755 index 2dc3e49c0..000000000 --- a/benchmarks/blockchain/localsync.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -DATA=$GOPATH/src/github.com/tendermint/tendermint/benchmarks/blockchain/data -if [ ! -d $DATA ]; then - echo "no data found, generating a chain... (this only has to happen once)" - - tendermint init --home $DATA - cp $DATA/config.toml $DATA/config2.toml - echo " - [consensus] - timeout_commit = 0 - " >> $DATA/config.toml - - echo "starting node" - tendermint node \ - --home $DATA \ - --proxy_app kvstore \ - --p2p.laddr tcp://127.0.0.1:56656 \ - --rpc.laddr tcp://127.0.0.1:56657 \ - --log_level error & - - echo "making blocks for 60s" - sleep 60 - - mv $DATA/config2.toml $DATA/config.toml - - kill %1 - - echo "done generating chain." -fi - -# validator node -HOME1=$TMPDIR$RANDOM$RANDOM -cp -R $DATA $HOME1 -echo "starting validator node" -tendermint node \ - --home $HOME1 \ - --proxy_app kvstore \ - --p2p.laddr tcp://127.0.0.1:56656 \ - --rpc.laddr tcp://127.0.0.1:56657 \ - --log_level error & -sleep 1 - -# downloader node -HOME2=$TMPDIR$RANDOM$RANDOM -tendermint init --home $HOME2 -cp $HOME1/genesis.json $HOME2 -printf "starting downloader node" -tendermint node \ - --home $HOME2 \ - --proxy_app kvstore \ - --p2p.laddr tcp://127.0.0.1:56666 \ - --rpc.laddr tcp://127.0.0.1:56667 \ - --p2p.persistent_peers 127.0.0.1:56656 \ - --log_level error & - -# wait for node to start up so we only count time where we are actually syncing -sleep 0.5 -while curl localhost:56667/status 2> /dev/null | grep "\"latest_block_height\": 0," > /dev/null -do - printf '.' - sleep 0.2 -done -echo - -echo "syncing blockchain for 10s" -for i in {1..10} -do - sleep 1 - HEIGHT="$(curl localhost:56667/status 2> /dev/null \ - | grep 'latest_block_height' \ - | grep -o ' [0-9]*' \ - | xargs)" - let 'RATE = HEIGHT / i' - echo "height: $HEIGHT, blocks/sec: $RATE" -done - -kill %1 -kill %2 -rm -rf $HOME1 $HOME2 diff --git a/benchmarks/chan_test.go b/benchmarks/chan_test.go deleted file mode 100644 index 78b70c9be..000000000 --- a/benchmarks/chan_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package benchmarks - -import ( - "testing" -) - -func BenchmarkChanMakeClose(b *testing.B) { - b.StopTimer() - b.StartTimer() - - for j := 0; j < b.N; j++ { - foo := make(chan struct{}) - close(foo) - something, ok := <-foo - if ok { - b.Error(something, ok) - } - } -} diff --git a/benchmarks/codec_test.go b/benchmarks/codec_test.go deleted file mode 100644 index 9acafce71..000000000 --- a/benchmarks/codec_test.go +++ /dev/null @@ -1,129 +0,0 @@ -package benchmarks - -import ( - "testing" - "time" - - "github.com/tendermint/go-amino" - "github.com/tendermint/go-crypto" - - proto "github.com/tendermint/tendermint/benchmarks/proto" - "github.com/tendermint/tendermint/p2p" - ctypes "github.com/tendermint/tendermint/rpc/core/types" -) - -func BenchmarkEncodeStatusWire(b *testing.B) { - b.StopTimer() - cdc := amino.NewCodec() - ctypes.RegisterAmino(cdc) - nodeKey := p2p.NodeKey{PrivKey: crypto.GenPrivKeyEd25519()} - status := &ctypes.ResultStatus{ - NodeInfo: p2p.NodeInfo{ - ID: nodeKey.ID(), - Moniker: "SOMENAME", - Network: "SOMENAME", - ListenAddr: "SOMEADDR", - Version: "SOMEVER", - Other: []string{"SOMESTRING", "OTHERSTRING"}, - }, - SyncInfo: ctypes.SyncInfo{ - LatestBlockHash: []byte("SOMEBYTES"), - LatestBlockHeight: 123, - LatestBlockTime: time.Unix(0, 1234), - }, - ValidatorInfo: ctypes.ValidatorInfo{ - PubKey: nodeKey.PubKey(), - }, - } - b.StartTimer() - - counter := 0 - for i := 0; i < b.N; i++ { - jsonBytes, err := cdc.MarshalJSON(status) - if err != nil { - panic(err) - } - counter += len(jsonBytes) - } - -} - -func BenchmarkEncodeNodeInfoWire(b *testing.B) { - b.StopTimer() - cdc := amino.NewCodec() - ctypes.RegisterAmino(cdc) - nodeKey := p2p.NodeKey{PrivKey: crypto.GenPrivKeyEd25519()} - nodeInfo := p2p.NodeInfo{ - ID: nodeKey.ID(), - Moniker: "SOMENAME", - Network: "SOMENAME", - ListenAddr: "SOMEADDR", - Version: "SOMEVER", - Other: []string{"SOMESTRING", "OTHERSTRING"}, - } - b.StartTimer() - - counter := 0 - for i := 0; i < b.N; i++ { - jsonBytes, err := cdc.MarshalJSON(nodeInfo) - if err != nil { - panic(err) - } - counter += len(jsonBytes) - } -} - -func BenchmarkEncodeNodeInfoBinary(b *testing.B) { - b.StopTimer() - cdc := amino.NewCodec() - ctypes.RegisterAmino(cdc) - nodeKey := p2p.NodeKey{PrivKey: crypto.GenPrivKeyEd25519()} - nodeInfo := p2p.NodeInfo{ - ID: nodeKey.ID(), - Moniker: "SOMENAME", - Network: "SOMENAME", - ListenAddr: "SOMEADDR", - Version: "SOMEVER", - Other: []string{"SOMESTRING", "OTHERSTRING"}, - } - b.StartTimer() - - counter := 0 - for i := 0; i < b.N; i++ { - jsonBytes := cdc.MustMarshalBinaryBare(nodeInfo) - counter += len(jsonBytes) - } - -} - -func BenchmarkEncodeNodeInfoProto(b *testing.B) { - b.StopTimer() - nodeKey := p2p.NodeKey{PrivKey: crypto.GenPrivKeyEd25519()} - nodeID := string(nodeKey.ID()) - someName := "SOMENAME" - someAddr := "SOMEADDR" - someVer := "SOMEVER" - someString := "SOMESTRING" - otherString := "OTHERSTRING" - nodeInfo := proto.NodeInfo{ - Id: &proto.ID{Id: &nodeID}, - Moniker: &someName, - Network: &someName, - ListenAddr: &someAddr, - Version: &someVer, - Other: []string{someString, otherString}, - } - b.StartTimer() - - counter := 0 - for i := 0; i < b.N; i++ { - bytes, err := nodeInfo.Marshal() - if err != nil { - b.Fatal(err) - return - } - //jsonBytes := wire.JSONBytes(nodeInfo) - counter += len(bytes) - } - -} diff --git a/benchmarks/empty.go b/benchmarks/empty.go deleted file mode 100644 index 20f08f14b..000000000 --- a/benchmarks/empty.go +++ /dev/null @@ -1 +0,0 @@ -package benchmarks diff --git a/benchmarks/map_test.go b/benchmarks/map_test.go deleted file mode 100644 index 2d9789026..000000000 --- a/benchmarks/map_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package benchmarks - -import ( - "testing" - - cmn "github.com/tendermint/tmlibs/common" -) - -func BenchmarkSomething(b *testing.B) { - b.StopTimer() - numItems := 100000 - numChecks := 100000 - keys := make([]string, numItems) - for i := 0; i < numItems; i++ { - keys[i] = cmn.RandStr(100) - } - txs := make([]string, numChecks) - for i := 0; i < numChecks; i++ { - txs[i] = cmn.RandStr(100) - } - b.StartTimer() - - counter := 0 - for j := 0; j < b.N; j++ { - foo := make(map[string]string) - for _, key := range keys { - foo[key] = key - } - for _, tx := range txs { - if _, ok := foo[tx]; ok { - counter++ - } - } - } -} diff --git a/benchmarks/os_test.go b/benchmarks/os_test.go deleted file mode 100644 index dfadc3128..000000000 --- a/benchmarks/os_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package benchmarks - -import ( - "os" - "testing" - - cmn "github.com/tendermint/tmlibs/common" -) - -func BenchmarkFileWrite(b *testing.B) { - b.StopTimer() - file, err := os.OpenFile("benchmark_file_write.out", - os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600) - if err != nil { - b.Error(err) - } - testString := cmn.RandStr(200) + "\n" - b.StartTimer() - - for i := 0; i < b.N; i++ { - _, err := file.Write([]byte(testString)) - if err != nil { - b.Error(err) - } - } - - if err := file.Close(); err != nil { - b.Error(err) - } - if err := os.Remove("benchmark_file_write.out"); err != nil { - b.Error(err) - } -} diff --git a/benchmarks/proto/README b/benchmarks/proto/README deleted file mode 100644 index 87ece2576..000000000 --- a/benchmarks/proto/README +++ /dev/null @@ -1,2 +0,0 @@ -Doing some protobuf tests here. -Using gogoprotobuf. diff --git a/benchmarks/proto/test.pb.go b/benchmarks/proto/test.pb.go deleted file mode 100644 index d430eeb08..000000000 --- a/benchmarks/proto/test.pb.go +++ /dev/null @@ -1,1456 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: test.proto - -/* - Package test is a generated protocol buffer package. - - It is generated from these files: - test.proto - - It has these top-level messages: - ResultStatus - NodeInfo - ID - PubKey - PubKeyEd25519 -*/ -package test - -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" - -import io "io" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package - -type ResultStatus struct { - NodeInfo *NodeInfo `protobuf:"bytes,1,opt,name=nodeInfo" json:"nodeInfo,omitempty"` - PubKey *PubKey `protobuf:"bytes,2,req,name=pubKey" json:"pubKey,omitempty"` - LatestBlockHash []byte `protobuf:"bytes,3,req,name=latestBlockHash" json:"latestBlockHash,omitempty"` - LatestBlockHeight *int64 `protobuf:"varint,4,req,name=latestBlockHeight" json:"latestBlockHeight,omitempty"` - LatestBlocktime *int64 `protobuf:"varint,5,req,name=latestBlocktime" json:"latestBlocktime,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *ResultStatus) Reset() { *m = ResultStatus{} } -func (m *ResultStatus) String() string { return proto.CompactTextString(m) } -func (*ResultStatus) ProtoMessage() {} -func (*ResultStatus) Descriptor() ([]byte, []int) { return fileDescriptorTest, []int{0} } - -func (m *ResultStatus) GetNodeInfo() *NodeInfo { - if m != nil { - return m.NodeInfo - } - return nil -} - -func (m *ResultStatus) GetPubKey() *PubKey { - if m != nil { - return m.PubKey - } - return nil -} - -func (m *ResultStatus) GetLatestBlockHash() []byte { - if m != nil { - return m.LatestBlockHash - } - return nil -} - -func (m *ResultStatus) GetLatestBlockHeight() int64 { - if m != nil && m.LatestBlockHeight != nil { - return *m.LatestBlockHeight - } - return 0 -} - -func (m *ResultStatus) GetLatestBlocktime() int64 { - if m != nil && m.LatestBlocktime != nil { - return *m.LatestBlocktime - } - return 0 -} - -type NodeInfo struct { - Id *ID `protobuf:"bytes,1,req,name=id" json:"id,omitempty"` - Moniker *string `protobuf:"bytes,2,req,name=moniker" json:"moniker,omitempty"` - Network *string `protobuf:"bytes,3,req,name=network" json:"network,omitempty"` - RemoteAddr *string `protobuf:"bytes,4,req,name=remoteAddr" json:"remoteAddr,omitempty"` - ListenAddr *string `protobuf:"bytes,5,req,name=listenAddr" json:"listenAddr,omitempty"` - Version *string `protobuf:"bytes,6,req,name=version" json:"version,omitempty"` - Other []string `protobuf:"bytes,7,rep,name=other" json:"other,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *NodeInfo) Reset() { *m = NodeInfo{} } -func (m *NodeInfo) String() string { return proto.CompactTextString(m) } -func (*NodeInfo) ProtoMessage() {} -func (*NodeInfo) Descriptor() ([]byte, []int) { return fileDescriptorTest, []int{1} } - -func (m *NodeInfo) GetId() *ID { - if m != nil { - return m.Id - } - return nil -} - -func (m *NodeInfo) GetMoniker() string { - if m != nil && m.Moniker != nil { - return *m.Moniker - } - return "" -} - -func (m *NodeInfo) GetNetwork() string { - if m != nil && m.Network != nil { - return *m.Network - } - return "" -} - -func (m *NodeInfo) GetRemoteAddr() string { - if m != nil && m.RemoteAddr != nil { - return *m.RemoteAddr - } - return "" -} - -func (m *NodeInfo) GetListenAddr() string { - if m != nil && m.ListenAddr != nil { - return *m.ListenAddr - } - return "" -} - -func (m *NodeInfo) GetVersion() string { - if m != nil && m.Version != nil { - return *m.Version - } - return "" -} - -func (m *NodeInfo) GetOther() []string { - if m != nil { - return m.Other - } - return nil -} - -type ID struct { - Id *string `protobuf:"bytes,1,req,name=id" json:"id,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *ID) Reset() { *m = ID{} } -func (m *ID) String() string { return proto.CompactTextString(m) } -func (*ID) ProtoMessage() {} -func (*ID) Descriptor() ([]byte, []int) { return fileDescriptorTest, []int{2} } - -func (m *ID) GetId() string { - if m != nil && m.Id != nil { - return *m.Id - } - return "" -} - -type PubKey struct { - Ed25519 *PubKeyEd25519 `protobuf:"bytes,1,opt,name=ed25519" json:"ed25519,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *PubKey) Reset() { *m = PubKey{} } -func (m *PubKey) String() string { return proto.CompactTextString(m) } -func (*PubKey) ProtoMessage() {} -func (*PubKey) Descriptor() ([]byte, []int) { return fileDescriptorTest, []int{3} } - -func (m *PubKey) GetEd25519() *PubKeyEd25519 { - if m != nil { - return m.Ed25519 - } - return nil -} - -type PubKeyEd25519 struct { - Bytes []byte `protobuf:"bytes,1,req,name=bytes" json:"bytes,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *PubKeyEd25519) Reset() { *m = PubKeyEd25519{} } -func (m *PubKeyEd25519) String() string { return proto.CompactTextString(m) } -func (*PubKeyEd25519) ProtoMessage() {} -func (*PubKeyEd25519) Descriptor() ([]byte, []int) { return fileDescriptorTest, []int{4} } - -func (m *PubKeyEd25519) GetBytes() []byte { - if m != nil { - return m.Bytes - } - return nil -} - -func init() { - proto.RegisterType((*ResultStatus)(nil), "ResultStatus") - proto.RegisterType((*NodeInfo)(nil), "NodeInfo") - proto.RegisterType((*ID)(nil), "ID") - proto.RegisterType((*PubKey)(nil), "PubKey") - proto.RegisterType((*PubKeyEd25519)(nil), "PubKeyEd25519") -} -func (m *ResultStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResultStatus) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.NodeInfo != nil { - dAtA[i] = 0xa - i++ - i = encodeVarintTest(dAtA, i, uint64(m.NodeInfo.Size())) - n1, err := m.NodeInfo.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n1 - } - if m.PubKey == nil { - return 0, proto.NewRequiredNotSetError("pubKey") - } else { - dAtA[i] = 0x12 - i++ - i = encodeVarintTest(dAtA, i, uint64(m.PubKey.Size())) - n2, err := m.PubKey.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n2 - } - if m.LatestBlockHash == nil { - return 0, proto.NewRequiredNotSetError("latestBlockHash") - } else { - dAtA[i] = 0x1a - i++ - i = encodeVarintTest(dAtA, i, uint64(len(m.LatestBlockHash))) - i += copy(dAtA[i:], m.LatestBlockHash) - } - if m.LatestBlockHeight == nil { - return 0, proto.NewRequiredNotSetError("latestBlockHeight") - } else { - dAtA[i] = 0x20 - i++ - i = encodeVarintTest(dAtA, i, uint64(*m.LatestBlockHeight)) - } - if m.LatestBlocktime == nil { - return 0, proto.NewRequiredNotSetError("latestBlocktime") - } else { - dAtA[i] = 0x28 - i++ - i = encodeVarintTest(dAtA, i, uint64(*m.LatestBlocktime)) - } - if m.XXX_unrecognized != nil { - i += copy(dAtA[i:], m.XXX_unrecognized) - } - return i, nil -} - -func (m *NodeInfo) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *NodeInfo) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Id == nil { - return 0, proto.NewRequiredNotSetError("id") - } else { - dAtA[i] = 0xa - i++ - i = encodeVarintTest(dAtA, i, uint64(m.Id.Size())) - n3, err := m.Id.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n3 - } - if m.Moniker == nil { - return 0, proto.NewRequiredNotSetError("moniker") - } else { - dAtA[i] = 0x12 - i++ - i = encodeVarintTest(dAtA, i, uint64(len(*m.Moniker))) - i += copy(dAtA[i:], *m.Moniker) - } - if m.Network == nil { - return 0, proto.NewRequiredNotSetError("network") - } else { - dAtA[i] = 0x1a - i++ - i = encodeVarintTest(dAtA, i, uint64(len(*m.Network))) - i += copy(dAtA[i:], *m.Network) - } - if m.RemoteAddr == nil { - return 0, proto.NewRequiredNotSetError("remoteAddr") - } else { - dAtA[i] = 0x22 - i++ - i = encodeVarintTest(dAtA, i, uint64(len(*m.RemoteAddr))) - i += copy(dAtA[i:], *m.RemoteAddr) - } - if m.ListenAddr == nil { - return 0, proto.NewRequiredNotSetError("listenAddr") - } else { - dAtA[i] = 0x2a - i++ - i = encodeVarintTest(dAtA, i, uint64(len(*m.ListenAddr))) - i += copy(dAtA[i:], *m.ListenAddr) - } - if m.Version == nil { - return 0, proto.NewRequiredNotSetError("version") - } else { - dAtA[i] = 0x32 - i++ - i = encodeVarintTest(dAtA, i, uint64(len(*m.Version))) - i += copy(dAtA[i:], *m.Version) - } - if len(m.Other) > 0 { - for _, s := range m.Other { - dAtA[i] = 0x3a - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - if m.XXX_unrecognized != nil { - i += copy(dAtA[i:], m.XXX_unrecognized) - } - return i, nil -} - -func (m *ID) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ID) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Id == nil { - return 0, proto.NewRequiredNotSetError("id") - } else { - dAtA[i] = 0xa - i++ - i = encodeVarintTest(dAtA, i, uint64(len(*m.Id))) - i += copy(dAtA[i:], *m.Id) - } - if m.XXX_unrecognized != nil { - i += copy(dAtA[i:], m.XXX_unrecognized) - } - return i, nil -} - -func (m *PubKey) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PubKey) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Ed25519 != nil { - dAtA[i] = 0xa - i++ - i = encodeVarintTest(dAtA, i, uint64(m.Ed25519.Size())) - n4, err := m.Ed25519.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n4 - } - if m.XXX_unrecognized != nil { - i += copy(dAtA[i:], m.XXX_unrecognized) - } - return i, nil -} - -func (m *PubKeyEd25519) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PubKeyEd25519) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Bytes == nil { - return 0, proto.NewRequiredNotSetError("bytes") - } else { - dAtA[i] = 0xa - i++ - i = encodeVarintTest(dAtA, i, uint64(len(m.Bytes))) - i += copy(dAtA[i:], m.Bytes) - } - if m.XXX_unrecognized != nil { - i += copy(dAtA[i:], m.XXX_unrecognized) - } - return i, nil -} - -func encodeVarintTest(dAtA []byte, offset int, v uint64) int { - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return offset + 1 -} -func (m *ResultStatus) Size() (n int) { - var l int - _ = l - if m.NodeInfo != nil { - l = m.NodeInfo.Size() - n += 1 + l + sovTest(uint64(l)) - } - if m.PubKey != nil { - l = m.PubKey.Size() - n += 1 + l + sovTest(uint64(l)) - } - if m.LatestBlockHash != nil { - l = len(m.LatestBlockHash) - n += 1 + l + sovTest(uint64(l)) - } - if m.LatestBlockHeight != nil { - n += 1 + sovTest(uint64(*m.LatestBlockHeight)) - } - if m.LatestBlocktime != nil { - n += 1 + sovTest(uint64(*m.LatestBlocktime)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func (m *NodeInfo) Size() (n int) { - var l int - _ = l - if m.Id != nil { - l = m.Id.Size() - n += 1 + l + sovTest(uint64(l)) - } - if m.Moniker != nil { - l = len(*m.Moniker) - n += 1 + l + sovTest(uint64(l)) - } - if m.Network != nil { - l = len(*m.Network) - n += 1 + l + sovTest(uint64(l)) - } - if m.RemoteAddr != nil { - l = len(*m.RemoteAddr) - n += 1 + l + sovTest(uint64(l)) - } - if m.ListenAddr != nil { - l = len(*m.ListenAddr) - n += 1 + l + sovTest(uint64(l)) - } - if m.Version != nil { - l = len(*m.Version) - n += 1 + l + sovTest(uint64(l)) - } - if len(m.Other) > 0 { - for _, s := range m.Other { - l = len(s) - n += 1 + l + sovTest(uint64(l)) - } - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func (m *ID) Size() (n int) { - var l int - _ = l - if m.Id != nil { - l = len(*m.Id) - n += 1 + l + sovTest(uint64(l)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func (m *PubKey) Size() (n int) { - var l int - _ = l - if m.Ed25519 != nil { - l = m.Ed25519.Size() - n += 1 + l + sovTest(uint64(l)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func (m *PubKeyEd25519) Size() (n int) { - var l int - _ = l - if m.Bytes != nil { - l = len(m.Bytes) - n += 1 + l + sovTest(uint64(l)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func sovTest(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break - } - } - return n -} - -func (m *ResultStatus) Unmarshal(dAtA []byte) error { - var hasFields [1]uint64 - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResultStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResultStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NodeInfo", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.NodeInfo == nil { - m.NodeInfo = &NodeInfo{} - } - if err := m.NodeInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PubKey", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.PubKey == nil { - m.PubKey = &PubKey{} - } - if err := m.PubKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - hasFields[0] |= uint64(0x00000001) - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LatestBlockHash", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + byteLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.LatestBlockHash = append(m.LatestBlockHash[:0], dAtA[iNdEx:postIndex]...) - if m.LatestBlockHash == nil { - m.LatestBlockHash = []byte{} - } - iNdEx = postIndex - hasFields[0] |= uint64(0x00000002) - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LatestBlockHeight", wireType) - } - var v int64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.LatestBlockHeight = &v - hasFields[0] |= uint64(0x00000004) - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LatestBlocktime", wireType) - } - var v int64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.LatestBlocktime = &v - hasFields[0] |= uint64(0x00000008) - default: - iNdEx = preIndex - skippy, err := skipTest(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthTest - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - if hasFields[0]&uint64(0x00000001) == 0 { - return proto.NewRequiredNotSetError("pubKey") - } - if hasFields[0]&uint64(0x00000002) == 0 { - return proto.NewRequiredNotSetError("latestBlockHash") - } - if hasFields[0]&uint64(0x00000004) == 0 { - return proto.NewRequiredNotSetError("latestBlockHeight") - } - if hasFields[0]&uint64(0x00000008) == 0 { - return proto.NewRequiredNotSetError("latestBlocktime") - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *NodeInfo) Unmarshal(dAtA []byte) error { - var hasFields [1]uint64 - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: NodeInfo: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: NodeInfo: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Id == nil { - m.Id = &ID{} - } - if err := m.Id.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - hasFields[0] |= uint64(0x00000001) - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Moniker", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.Moniker = &s - iNdEx = postIndex - hasFields[0] |= uint64(0x00000002) - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Network", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.Network = &s - iNdEx = postIndex - hasFields[0] |= uint64(0x00000004) - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RemoteAddr", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.RemoteAddr = &s - iNdEx = postIndex - hasFields[0] |= uint64(0x00000008) - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListenAddr", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.ListenAddr = &s - iNdEx = postIndex - hasFields[0] |= uint64(0x00000010) - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.Version = &s - iNdEx = postIndex - hasFields[0] |= uint64(0x00000020) - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Other", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Other = append(m.Other, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTest(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthTest - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - if hasFields[0]&uint64(0x00000001) == 0 { - return proto.NewRequiredNotSetError("id") - } - if hasFields[0]&uint64(0x00000002) == 0 { - return proto.NewRequiredNotSetError("moniker") - } - if hasFields[0]&uint64(0x00000004) == 0 { - return proto.NewRequiredNotSetError("network") - } - if hasFields[0]&uint64(0x00000008) == 0 { - return proto.NewRequiredNotSetError("remoteAddr") - } - if hasFields[0]&uint64(0x00000010) == 0 { - return proto.NewRequiredNotSetError("listenAddr") - } - if hasFields[0]&uint64(0x00000020) == 0 { - return proto.NewRequiredNotSetError("version") - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ID) Unmarshal(dAtA []byte) error { - var hasFields [1]uint64 - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ID: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ID: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.Id = &s - iNdEx = postIndex - hasFields[0] |= uint64(0x00000001) - default: - iNdEx = preIndex - skippy, err := skipTest(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthTest - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - if hasFields[0]&uint64(0x00000001) == 0 { - return proto.NewRequiredNotSetError("id") - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PubKey) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PubKey: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PubKey: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ed25519", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Ed25519 == nil { - m.Ed25519 = &PubKeyEd25519{} - } - if err := m.Ed25519.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTest(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthTest - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PubKeyEd25519) Unmarshal(dAtA []byte) error { - var hasFields [1]uint64 - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PubKeyEd25519: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PubKeyEd25519: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Bytes", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + byteLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Bytes = append(m.Bytes[:0], dAtA[iNdEx:postIndex]...) - if m.Bytes == nil { - m.Bytes = []byte{} - } - iNdEx = postIndex - hasFields[0] |= uint64(0x00000001) - default: - iNdEx = preIndex - skippy, err := skipTest(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthTest - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - if hasFields[0]&uint64(0x00000001) == 0 { - return proto.NewRequiredNotSetError("bytes") - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipTest(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTest - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTest - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - return iNdEx, nil - case 1: - iNdEx += 8 - return iNdEx, nil - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTest - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - iNdEx += length - if length < 0 { - return 0, ErrInvalidLengthTest - } - return iNdEx, nil - case 3: - for { - var innerWire uint64 - var start int = iNdEx - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTest - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - innerWire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - innerWireType := int(innerWire & 0x7) - if innerWireType == 4 { - break - } - next, err := skipTest(dAtA[start:]) - if err != nil { - return 0, err - } - iNdEx = start + next - } - return iNdEx, nil - case 4: - return iNdEx, nil - case 5: - iNdEx += 4 - return iNdEx, nil - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - } - panic("unreachable") -} - -var ( - ErrInvalidLengthTest = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowTest = fmt.Errorf("proto: integer overflow") -) - -func init() { proto.RegisterFile("test.proto", fileDescriptorTest) } - -var fileDescriptorTest = []byte{ - // 342 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x91, 0x41, 0x4b, 0xf3, 0x30, - 0x1c, 0xc6, 0x49, 0xfb, 0x6e, 0x5d, 0xff, 0xeb, 0x3b, 0x31, 0xee, 0x90, 0x53, 0x2d, 0x85, 0x41, - 0x0f, 0x52, 0xb0, 0xb0, 0x83, 0x47, 0xc7, 0x04, 0x87, 0x20, 0x23, 0x7e, 0x82, 0xcd, 0xfe, 0x75, - 0x65, 0x5d, 0x33, 0x92, 0x4c, 0xd9, 0xe7, 0xf3, 0xe2, 0xd1, 0xa3, 0x47, 0xd9, 0x27, 0x91, 0xa6, - 0xed, 0x9c, 0xf3, 0xf8, 0xfc, 0x7e, 0xe5, 0xc9, 0xd3, 0x04, 0x40, 0xa3, 0xd2, 0xf1, 0x5a, 0x0a, - 0x2d, 0xc2, 0x4f, 0x02, 0x1e, 0x47, 0xb5, 0xc9, 0xf5, 0x83, 0x9e, 0xe9, 0x8d, 0xa2, 0x03, 0xe8, - 0x14, 0x22, 0xc5, 0x49, 0xf1, 0x24, 0x18, 0x09, 0x48, 0xd4, 0x4d, 0xdc, 0xf8, 0xbe, 0x06, 0x7c, - 0xaf, 0xe8, 0x39, 0xb4, 0xd7, 0x9b, 0xf9, 0x1d, 0x6e, 0x99, 0x15, 0x58, 0x51, 0x37, 0x71, 0xe2, - 0xa9, 0x89, 0xbc, 0xc6, 0x34, 0x82, 0x93, 0x7c, 0x56, 0x1e, 0x34, 0xca, 0xc5, 0xe3, 0xf2, 0x76, - 0xa6, 0x16, 0xcc, 0x0e, 0xac, 0xc8, 0xe3, 0xc7, 0x98, 0x5e, 0xc0, 0xe9, 0x21, 0xc2, 0xec, 0x79, - 0xa1, 0xd9, 0xbf, 0xc0, 0x8a, 0x6c, 0xfe, 0x57, 0x1c, 0xf5, 0xea, 0x6c, 0x85, 0xac, 0x65, 0xbe, - 0x3d, 0xc6, 0xe1, 0x1b, 0x81, 0x4e, 0xb3, 0x9c, 0x9e, 0x81, 0x95, 0xa5, 0x8c, 0x98, 0xad, 0x76, - 0x3c, 0x19, 0x73, 0x2b, 0x4b, 0x29, 0x03, 0x67, 0x25, 0x8a, 0x6c, 0x89, 0xd2, 0xfc, 0x85, 0xcb, - 0x9b, 0x58, 0x9a, 0x02, 0xf5, 0xab, 0x90, 0x4b, 0xb3, 0xda, 0xe5, 0x4d, 0xa4, 0x3e, 0x80, 0xc4, - 0x95, 0xd0, 0x78, 0x9d, 0xa6, 0xd2, 0xcc, 0x74, 0xf9, 0x01, 0x29, 0x7d, 0x9e, 0x29, 0x8d, 0x85, - 0xf1, 0xad, 0xca, 0xff, 0x90, 0xb2, 0xf9, 0x05, 0xa5, 0xca, 0x44, 0xc1, 0xda, 0x55, 0x73, 0x1d, - 0x69, 0x1f, 0x5a, 0x42, 0x2f, 0x50, 0x32, 0x27, 0xb0, 0x23, 0x97, 0x57, 0x21, 0xec, 0x83, 0x35, - 0x19, 0xd3, 0xde, 0x7e, 0xbe, 0x5b, 0x2e, 0x0f, 0x13, 0x68, 0x4f, 0x9b, 0x7b, 0x76, 0x30, 0x4d, - 0x86, 0xc3, 0xcb, 0xab, 0xfa, 0xb9, 0x7a, 0xf5, 0x4b, 0xdc, 0x54, 0x94, 0x37, 0x3a, 0x1c, 0xc0, - 0xff, 0x5f, 0xa6, 0x3c, 0x70, 0xbe, 0xd5, 0xa8, 0x4c, 0xaf, 0xc7, 0xab, 0x30, 0xf2, 0xde, 0x77, - 0x3e, 0xf9, 0xd8, 0xf9, 0xe4, 0x6b, 0xe7, 0x93, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb1, 0xee, - 0x6b, 0xdd, 0x2c, 0x02, 0x00, 0x00, -} diff --git a/benchmarks/proto/test.proto b/benchmarks/proto/test.proto deleted file mode 100644 index 6d770d98a..000000000 --- a/benchmarks/proto/test.proto +++ /dev/null @@ -1,29 +0,0 @@ -message ResultStatus { - optional NodeInfo nodeInfo = 1; - required PubKey pubKey = 2; - required bytes latestBlockHash = 3; - required int64 latestBlockHeight = 4; - required int64 latestBlocktime = 5; -} - -message NodeInfo { - required ID id = 1; - required string moniker = 2; - required string network = 3; - required string remoteAddr = 4; - required string listenAddr = 5; - required string version = 6; - repeated string other = 7; -} - -message ID { - required string id = 1; -} - -message PubKey { - optional PubKeyEd25519 ed25519 = 1; -} - -message PubKeyEd25519 { - required bytes bytes = 1; -} diff --git a/benchmarks/simu/counter.go b/benchmarks/simu/counter.go deleted file mode 100644 index dd00408cb..000000000 --- a/benchmarks/simu/counter.go +++ /dev/null @@ -1,47 +0,0 @@ -package main - -import ( - "context" - "encoding/binary" - "fmt" - "time" - - rpcclient "github.com/tendermint/tendermint/rpc/lib/client" - cmn "github.com/tendermint/tmlibs/common" -) - -func main() { - wsc := rpcclient.NewWSClient("127.0.0.1:26657", "/websocket") - err := wsc.Start() - if err != nil { - cmn.Exit(err.Error()) - } - defer wsc.Stop() - - // Read a bunch of responses - go func() { - for { - _, ok := <-wsc.ResponsesCh - if !ok { - break - } - //fmt.Println("Received response", string(wire.JSONBytes(res))) - } - }() - - // Make a bunch of requests - buf := make([]byte, 32) - for i := 0; ; i++ { - binary.BigEndian.PutUint64(buf, uint64(i)) - //txBytes := hex.EncodeToString(buf[:n]) - fmt.Print(".") - err = wsc.Call(context.TODO(), "broadcast_tx", map[string]interface{}{"tx": buf[:8]}) - if err != nil { - cmn.Exit(err.Error()) - } - if i%1000 == 0 { - fmt.Println(i) - } - time.Sleep(time.Microsecond * 1000) - } -} diff --git a/blockchain/pool.go b/blockchain/pool.go deleted file mode 100644 index 8b964e81a..000000000 --- a/blockchain/pool.go +++ /dev/null @@ -1,587 +0,0 @@ -package blockchain - -import ( - "errors" - "fmt" - "math" - "sync" - "sync/atomic" - "time" - - cmn "github.com/tendermint/tmlibs/common" - flow "github.com/tendermint/tmlibs/flowrate" - "github.com/tendermint/tmlibs/log" - - "github.com/tendermint/tendermint/p2p" - "github.com/tendermint/tendermint/types" -) - -/* -eg, L = latency = 0.1s - P = num peers = 10 - FN = num full nodes - BS = 1kB block size - CB = 1 Mbit/s = 128 kB/s - CB/P = 12.8 kB - B/S = CB/P/BS = 12.8 blocks/s - - 12.8 * 0.1 = 1.28 blocks on conn -*/ - -const ( - requestIntervalMS = 100 - maxTotalRequesters = 1000 - maxPendingRequests = maxTotalRequesters - maxPendingRequestsPerPeer = 50 - - // Minimum recv rate to ensure we're receiving blocks from a peer fast - // enough. If a peer is not sending us data at at least that rate, we - // consider them to have timedout and we disconnect. - // - // Assuming a DSL connection (not a good choice) 128 Kbps (upload) ~ 15 KB/s, - // sending data across atlantic ~ 7.5 KB/s. - minRecvRate = 7680 - - // Maximum difference between current and new block's height. - maxDiffBetweenCurrentAndReceivedBlockHeight = 100 -) - -var peerTimeout = 15 * time.Second // not const so we can override with tests - -/* - Peers self report their heights when we join the block pool. - Starting from our latest pool.height, we request blocks - in sequence from peers that reported higher heights than ours. - Every so often we ask peers what height they're on so we can keep going. - - Requests are continuously made for blocks of higher heights until - the limit is reached. If most of the requests have no available peers, and we - are not at peer limits, we can probably switch to consensus reactor -*/ - -type BlockPool struct { - cmn.BaseService - startTime time.Time - - mtx sync.Mutex - // block requests - requesters map[int64]*bpRequester - height int64 // the lowest key in requesters. - // peers - peers map[p2p.ID]*bpPeer - maxPeerHeight int64 - - // atomic - numPending int32 // number of requests pending assignment or block response - - requestsCh chan<- BlockRequest - errorsCh chan<- peerError -} - -func NewBlockPool(start int64, requestsCh chan<- BlockRequest, errorsCh chan<- peerError) *BlockPool { - bp := &BlockPool{ - peers: make(map[p2p.ID]*bpPeer), - - requesters: make(map[int64]*bpRequester), - height: start, - numPending: 0, - - requestsCh: requestsCh, - errorsCh: errorsCh, - } - bp.BaseService = *cmn.NewBaseService(nil, "BlockPool", bp) - return bp -} - -func (pool *BlockPool) OnStart() error { - go pool.makeRequestersRoutine() - pool.startTime = time.Now() - return nil -} - -func (pool *BlockPool) OnStop() {} - -// Run spawns requesters as needed. -func (pool *BlockPool) makeRequestersRoutine() { - for { - if !pool.IsRunning() { - break - } - - _, numPending, lenRequesters := pool.GetStatus() - if numPending >= maxPendingRequests { - // sleep for a bit. - time.Sleep(requestIntervalMS * time.Millisecond) - // check for timed out peers - pool.removeTimedoutPeers() - } else if lenRequesters >= maxTotalRequesters { - // sleep for a bit. - time.Sleep(requestIntervalMS * time.Millisecond) - // check for timed out peers - pool.removeTimedoutPeers() - } else { - // request for more blocks. - pool.makeNextRequester() - } - } -} - -func (pool *BlockPool) removeTimedoutPeers() { - pool.mtx.Lock() - defer pool.mtx.Unlock() - - for _, peer := range pool.peers { - if !peer.didTimeout && peer.numPending > 0 { - curRate := peer.recvMonitor.Status().CurRate - // curRate can be 0 on start - if curRate != 0 && curRate < minRecvRate { - err := errors.New("peer is not sending us data fast enough") - pool.sendError(err, peer.id) - pool.Logger.Error("SendTimeout", "peer", peer.id, - "reason", err, - "curRate", fmt.Sprintf("%d KB/s", curRate/1024), - "minRate", fmt.Sprintf("%d KB/s", minRecvRate/1024)) - peer.didTimeout = true - } - } - if peer.didTimeout { - pool.removePeer(peer.id) - } - } -} - -func (pool *BlockPool) GetStatus() (height int64, numPending int32, lenRequesters int) { - pool.mtx.Lock() - defer pool.mtx.Unlock() - - return pool.height, atomic.LoadInt32(&pool.numPending), len(pool.requesters) -} - -// TODO: relax conditions, prevent abuse. -func (pool *BlockPool) IsCaughtUp() bool { - pool.mtx.Lock() - defer pool.mtx.Unlock() - - // Need at least 1 peer to be considered caught up. - if len(pool.peers) == 0 { - pool.Logger.Debug("Blockpool has no peers") - return false - } - - // some conditions to determine if we're caught up - receivedBlockOrTimedOut := (pool.height > 0 || time.Since(pool.startTime) > 5*time.Second) - ourChainIsLongestAmongPeers := pool.maxPeerHeight == 0 || pool.height >= pool.maxPeerHeight - isCaughtUp := receivedBlockOrTimedOut && ourChainIsLongestAmongPeers - return isCaughtUp -} - -// We need to see the second block's Commit to validate the first block. -// So we peek two blocks at a time. -// The caller will verify the commit. -func (pool *BlockPool) PeekTwoBlocks() (first *types.Block, second *types.Block) { - pool.mtx.Lock() - defer pool.mtx.Unlock() - - if r := pool.requesters[pool.height]; r != nil { - first = r.getBlock() - } - if r := pool.requesters[pool.height+1]; r != nil { - second = r.getBlock() - } - return -} - -// Pop the first block at pool.height -// It must have been validated by 'second'.Commit from PeekTwoBlocks(). -func (pool *BlockPool) PopRequest() { - pool.mtx.Lock() - defer pool.mtx.Unlock() - - if r := pool.requesters[pool.height]; r != nil { - /* The block can disappear at any time, due to removePeer(). - if r := pool.requesters[pool.height]; r == nil || r.block == nil { - PanicSanity("PopRequest() requires a valid block") - } - */ - r.Stop() - delete(pool.requesters, pool.height) - pool.height++ - } else { - panic(fmt.Sprintf("Expected requester to pop, got nothing at height %v", pool.height)) - } -} - -// Invalidates the block at pool.height, -// Remove the peer and redo request from others. -// Returns the ID of the removed peer. -func (pool *BlockPool) RedoRequest(height int64) p2p.ID { - pool.mtx.Lock() - defer pool.mtx.Unlock() - - request := pool.requesters[height] - - if request.block == nil { - panic("Expected block to be non-nil") - } - - // RemovePeer will redo all requesters associated with this peer. - pool.removePeer(request.peerID) - return request.peerID -} - -// TODO: ensure that blocks come in order for each peer. -func (pool *BlockPool) AddBlock(peerID p2p.ID, block *types.Block, blockSize int) { - pool.mtx.Lock() - defer pool.mtx.Unlock() - - requester := pool.requesters[block.Height] - if requester == nil { - pool.Logger.Info("peer sent us a block we didn't expect", "peer", peerID, "curHeight", pool.height, "blockHeight", block.Height) - diff := pool.height - block.Height - if diff < 0 { - diff *= -1 - } - if diff > maxDiffBetweenCurrentAndReceivedBlockHeight { - pool.sendError(errors.New("peer sent us a block we didn't expect with a height too far ahead/behind"), peerID) - } - return - } - - if requester.setBlock(block, peerID) { - atomic.AddInt32(&pool.numPending, -1) - peer := pool.peers[peerID] - if peer != nil { - peer.decrPending(blockSize) - } - } else { - // Bad peer? - } -} - -// MaxPeerHeight returns the highest height reported by a peer. -func (pool *BlockPool) MaxPeerHeight() int64 { - pool.mtx.Lock() - defer pool.mtx.Unlock() - return pool.maxPeerHeight -} - -// Sets the peer's alleged blockchain height. -func (pool *BlockPool) SetPeerHeight(peerID p2p.ID, height int64) { - pool.mtx.Lock() - defer pool.mtx.Unlock() - - peer := pool.peers[peerID] - if peer != nil { - peer.height = height - } else { - peer = newBPPeer(pool, peerID, height) - peer.setLogger(pool.Logger.With("peer", peerID)) - pool.peers[peerID] = peer - } - - if height > pool.maxPeerHeight { - pool.maxPeerHeight = height - } -} - -func (pool *BlockPool) RemovePeer(peerID p2p.ID) { - pool.mtx.Lock() - defer pool.mtx.Unlock() - - pool.removePeer(peerID) -} - -func (pool *BlockPool) removePeer(peerID p2p.ID) { - for _, requester := range pool.requesters { - if requester.getPeerID() == peerID { - requester.redo() - } - } - delete(pool.peers, peerID) -} - -// Pick an available peer with at least the given minHeight. -// If no peers are available, returns nil. -func (pool *BlockPool) pickIncrAvailablePeer(minHeight int64) *bpPeer { - pool.mtx.Lock() - defer pool.mtx.Unlock() - - for _, peer := range pool.peers { - if peer.didTimeout { - pool.removePeer(peer.id) - continue - } - if peer.numPending >= maxPendingRequestsPerPeer { - continue - } - if peer.height < minHeight { - continue - } - peer.incrPending() - return peer - } - return nil -} - -func (pool *BlockPool) makeNextRequester() { - pool.mtx.Lock() - defer pool.mtx.Unlock() - - nextHeight := pool.height + pool.requestersLen() - request := newBPRequester(pool, nextHeight) - // request.SetLogger(pool.Logger.With("height", nextHeight)) - - pool.requesters[nextHeight] = request - atomic.AddInt32(&pool.numPending, 1) - - err := request.Start() - if err != nil { - request.Logger.Error("Error starting request", "err", err) - } -} - -func (pool *BlockPool) requestersLen() int64 { - return int64(len(pool.requesters)) -} - -func (pool *BlockPool) sendRequest(height int64, peerID p2p.ID) { - if !pool.IsRunning() { - return - } - pool.requestsCh <- BlockRequest{height, peerID} -} - -func (pool *BlockPool) sendError(err error, peerID p2p.ID) { - if !pool.IsRunning() { - return - } - pool.errorsCh <- peerError{err, peerID} -} - -// unused by tendermint; left for debugging purposes -func (pool *BlockPool) debug() string { - pool.mtx.Lock() - defer pool.mtx.Unlock() - - str := "" - nextHeight := pool.height + pool.requestersLen() - for h := pool.height; h < nextHeight; h++ { - if pool.requesters[h] == nil { - str += cmn.Fmt("H(%v):X ", h) - } else { - str += cmn.Fmt("H(%v):", h) - str += cmn.Fmt("B?(%v) ", pool.requesters[h].block != nil) - } - } - return str -} - -//------------------------------------- - -type bpPeer struct { - pool *BlockPool - id p2p.ID - recvMonitor *flow.Monitor - - height int64 - numPending int32 - timeout *time.Timer - didTimeout bool - - logger log.Logger -} - -func newBPPeer(pool *BlockPool, peerID p2p.ID, height int64) *bpPeer { - peer := &bpPeer{ - pool: pool, - id: peerID, - height: height, - numPending: 0, - logger: log.NewNopLogger(), - } - return peer -} - -func (peer *bpPeer) setLogger(l log.Logger) { - peer.logger = l -} - -func (peer *bpPeer) resetMonitor() { - peer.recvMonitor = flow.New(time.Second, time.Second*40) - initialValue := float64(minRecvRate) * math.E - peer.recvMonitor.SetREMA(initialValue) -} - -func (peer *bpPeer) resetTimeout() { - if peer.timeout == nil { - peer.timeout = time.AfterFunc(peerTimeout, peer.onTimeout) - } else { - peer.timeout.Reset(peerTimeout) - } -} - -func (peer *bpPeer) incrPending() { - if peer.numPending == 0 { - peer.resetMonitor() - peer.resetTimeout() - } - peer.numPending++ -} - -func (peer *bpPeer) decrPending(recvSize int) { - peer.numPending-- - if peer.numPending == 0 { - peer.timeout.Stop() - } else { - peer.recvMonitor.Update(recvSize) - peer.resetTimeout() - } -} - -func (peer *bpPeer) onTimeout() { - peer.pool.mtx.Lock() - defer peer.pool.mtx.Unlock() - - err := errors.New("peer did not send us anything") - peer.pool.sendError(err, peer.id) - peer.logger.Error("SendTimeout", "reason", err, "timeout", peerTimeout) - peer.didTimeout = true -} - -//------------------------------------- - -type bpRequester struct { - cmn.BaseService - pool *BlockPool - height int64 - gotBlockCh chan struct{} - redoCh chan struct{} - - mtx sync.Mutex - peerID p2p.ID - block *types.Block -} - -func newBPRequester(pool *BlockPool, height int64) *bpRequester { - bpr := &bpRequester{ - pool: pool, - height: height, - gotBlockCh: make(chan struct{}, 1), - redoCh: make(chan struct{}, 1), - - peerID: "", - block: nil, - } - bpr.BaseService = *cmn.NewBaseService(nil, "bpRequester", bpr) - return bpr -} - -func (bpr *bpRequester) OnStart() error { - go bpr.requestRoutine() - return nil -} - -// Returns true if the peer matches and block doesn't already exist. -func (bpr *bpRequester) setBlock(block *types.Block, peerID p2p.ID) bool { - bpr.mtx.Lock() - if bpr.block != nil || bpr.peerID != peerID { - bpr.mtx.Unlock() - return false - } - bpr.block = block - bpr.mtx.Unlock() - - select { - case bpr.gotBlockCh <- struct{}{}: - default: - } - return true -} - -func (bpr *bpRequester) getBlock() *types.Block { - bpr.mtx.Lock() - defer bpr.mtx.Unlock() - return bpr.block -} - -func (bpr *bpRequester) getPeerID() p2p.ID { - bpr.mtx.Lock() - defer bpr.mtx.Unlock() - return bpr.peerID -} - -// This is called from the requestRoutine, upon redo(). -func (bpr *bpRequester) reset() { - bpr.mtx.Lock() - defer bpr.mtx.Unlock() - - if bpr.block != nil { - atomic.AddInt32(&bpr.pool.numPending, 1) - } - - bpr.peerID = "" - bpr.block = nil -} - -// Tells bpRequester to pick another peer and try again. -// NOTE: Nonblocking, and does nothing if another redo -// was already requested. -func (bpr *bpRequester) redo() { - select { - case bpr.redoCh <- struct{}{}: - default: - } -} - -// Responsible for making more requests as necessary -// Returns only when a block is found (e.g. AddBlock() is called) -func (bpr *bpRequester) requestRoutine() { -OUTER_LOOP: - for { - // Pick a peer to send request to. - var peer *bpPeer - PICK_PEER_LOOP: - for { - if !bpr.IsRunning() || !bpr.pool.IsRunning() { - return - } - peer = bpr.pool.pickIncrAvailablePeer(bpr.height) - if peer == nil { - //log.Info("No peers available", "height", height) - time.Sleep(requestIntervalMS * time.Millisecond) - continue PICK_PEER_LOOP - } - break PICK_PEER_LOOP - } - bpr.mtx.Lock() - bpr.peerID = peer.id - bpr.mtx.Unlock() - - // Send request and wait. - bpr.pool.sendRequest(bpr.height, peer.id) - WAIT_LOOP: - for { - select { - case <-bpr.pool.Quit(): - bpr.Stop() - return - case <-bpr.Quit(): - return - case <-bpr.redoCh: - bpr.reset() - continue OUTER_LOOP - case <-bpr.gotBlockCh: - // We got a block! - // Continue the for-loop and wait til Quit. - continue WAIT_LOOP - } - } - } -} - -//------------------------------------- - -type BlockRequest struct { - Height int64 - PeerID p2p.ID -} diff --git a/blockchain/pool_test.go b/blockchain/pool_test.go deleted file mode 100644 index 82120eaef..000000000 --- a/blockchain/pool_test.go +++ /dev/null @@ -1,148 +0,0 @@ -package blockchain - -import ( - "math/rand" - "testing" - "time" - - cmn "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/log" - - "github.com/tendermint/tendermint/p2p" - "github.com/tendermint/tendermint/types" -) - -func init() { - peerTimeout = 2 * time.Second -} - -type testPeer struct { - id p2p.ID - height int64 -} - -func makePeers(numPeers int, minHeight, maxHeight int64) map[p2p.ID]testPeer { - peers := make(map[p2p.ID]testPeer, numPeers) - for i := 0; i < numPeers; i++ { - peerID := p2p.ID(cmn.RandStr(12)) - height := minHeight + rand.Int63n(maxHeight-minHeight) - peers[peerID] = testPeer{peerID, height} - } - return peers -} - -func TestBasic(t *testing.T) { - start := int64(42) - peers := makePeers(10, start+1, 1000) - errorsCh := make(chan peerError, 1000) - requestsCh := make(chan BlockRequest, 1000) - pool := NewBlockPool(start, requestsCh, errorsCh) - pool.SetLogger(log.TestingLogger()) - - err := pool.Start() - if err != nil { - t.Error(err) - } - - defer pool.Stop() - - // Introduce each peer. - go func() { - for _, peer := range peers { - pool.SetPeerHeight(peer.id, peer.height) - } - }() - - // Start a goroutine to pull blocks - go func() { - for { - if !pool.IsRunning() { - return - } - first, second := pool.PeekTwoBlocks() - if first != nil && second != nil { - pool.PopRequest() - } else { - time.Sleep(1 * time.Second) - } - } - }() - - // Pull from channels - for { - select { - case err := <-errorsCh: - t.Error(err) - case request := <-requestsCh: - t.Logf("Pulled new BlockRequest %v", request) - if request.Height == 300 { - return // Done! - } - // Request desired, pretend like we got the block immediately. - go func() { - block := &types.Block{Header: &types.Header{Height: request.Height}} - pool.AddBlock(request.PeerID, block, 123) - t.Logf("Added block from peer %v (height: %v)", request.PeerID, request.Height) - }() - } - } -} - -func TestTimeout(t *testing.T) { - start := int64(42) - peers := makePeers(10, start+1, 1000) - errorsCh := make(chan peerError, 1000) - requestsCh := make(chan BlockRequest, 1000) - pool := NewBlockPool(start, requestsCh, errorsCh) - pool.SetLogger(log.TestingLogger()) - err := pool.Start() - if err != nil { - t.Error(err) - } - defer pool.Stop() - - for _, peer := range peers { - t.Logf("Peer %v", peer.id) - } - - // Introduce each peer. - go func() { - for _, peer := range peers { - pool.SetPeerHeight(peer.id, peer.height) - } - }() - - // Start a goroutine to pull blocks - go func() { - for { - if !pool.IsRunning() { - return - } - first, second := pool.PeekTwoBlocks() - if first != nil && second != nil { - pool.PopRequest() - } else { - time.Sleep(1 * time.Second) - } - } - }() - - // Pull from channels - counter := 0 - timedOut := map[p2p.ID]struct{}{} - for { - select { - case err := <-errorsCh: - t.Log(err) - // consider error to be always timeout here - if _, ok := timedOut[err.peerID]; !ok { - counter++ - if counter == len(peers) { - return // Done! - } - } - case request := <-requestsCh: - t.Logf("Pulled new BlockRequest %+v", request) - } - } -} diff --git a/blockchain/reactor.go b/blockchain/reactor.go deleted file mode 100644 index 33dfdd288..000000000 --- a/blockchain/reactor.go +++ /dev/null @@ -1,405 +0,0 @@ -package blockchain - -import ( - "fmt" - "reflect" - "time" - - "github.com/tendermint/go-amino" - "github.com/tendermint/tendermint/p2p" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/log" -) - -const ( - // BlockchainChannel is a channel for blocks and status updates (`BlockStore` height) - BlockchainChannel = byte(0x40) - - trySyncIntervalMS = 50 - // stop syncing when last block's time is - // within this much of the system time. - // stopSyncingDurationMinutes = 10 - - // ask for best height every 10s - statusUpdateIntervalSeconds = 10 - // check if we should switch to consensus reactor - switchToConsensusIntervalSeconds = 1 - - // NOTE: keep up to date with bcBlockResponseMessage - bcBlockResponseMessagePrefixSize = 4 - bcBlockResponseMessageFieldKeySize = 1 - maxMsgSize = types.MaxBlockSizeBytes + - bcBlockResponseMessagePrefixSize + - bcBlockResponseMessageFieldKeySize -) - -type consensusReactor interface { - // for when we switch from blockchain reactor and fast sync to - // the consensus machine - SwitchToConsensus(sm.State, int) -} - -type peerError struct { - err error - peerID p2p.ID -} - -func (e peerError) Error() string { - return fmt.Sprintf("error with peer %v: %s", e.peerID, e.err.Error()) -} - -// BlockchainReactor handles long-term catchup syncing. -type BlockchainReactor struct { - p2p.BaseReactor - - // immutable - initialState sm.State - - blockExec *sm.BlockExecutor - store *BlockStore - pool *BlockPool - fastSync bool - - requestsCh <-chan BlockRequest - errorsCh <-chan peerError -} - -// NewBlockchainReactor returns new reactor instance. -func NewBlockchainReactor(state sm.State, blockExec *sm.BlockExecutor, store *BlockStore, - fastSync bool) *BlockchainReactor { - - if state.LastBlockHeight != store.Height() { - panic(fmt.Sprintf("state (%v) and store (%v) height mismatch", state.LastBlockHeight, - store.Height())) - } - - const capacity = 1000 // must be bigger than peers count - requestsCh := make(chan BlockRequest, capacity) - errorsCh := make(chan peerError, capacity) // so we don't block in #Receive#pool.AddBlock - - pool := NewBlockPool( - store.Height()+1, - requestsCh, - errorsCh, - ) - - bcR := &BlockchainReactor{ - initialState: state, - blockExec: blockExec, - store: store, - pool: pool, - fastSync: fastSync, - requestsCh: requestsCh, - errorsCh: errorsCh, - } - bcR.BaseReactor = *p2p.NewBaseReactor("BlockchainReactor", bcR) - return bcR -} - -// SetLogger implements cmn.Service by setting the logger on reactor and pool. -func (bcR *BlockchainReactor) SetLogger(l log.Logger) { - bcR.BaseService.Logger = l - bcR.pool.Logger = l -} - -// OnStart implements cmn.Service. -func (bcR *BlockchainReactor) OnStart() error { - if err := bcR.BaseReactor.OnStart(); err != nil { - return err - } - if bcR.fastSync { - err := bcR.pool.Start() - if err != nil { - return err - } - go bcR.poolRoutine() - } - return nil -} - -// OnStop implements cmn.Service. -func (bcR *BlockchainReactor) OnStop() { - bcR.BaseReactor.OnStop() - bcR.pool.Stop() -} - -// GetChannels implements Reactor -func (bcR *BlockchainReactor) GetChannels() []*p2p.ChannelDescriptor { - return []*p2p.ChannelDescriptor{ - { - ID: BlockchainChannel, - Priority: 10, - SendQueueCapacity: 1000, - RecvBufferCapacity: 50 * 4096, - RecvMessageCapacity: maxMsgSize, - }, - } -} - -// AddPeer implements Reactor by sending our state to peer. -func (bcR *BlockchainReactor) AddPeer(peer p2p.Peer) { - msgBytes := cdc.MustMarshalBinaryBare(&bcStatusResponseMessage{bcR.store.Height()}) - if !peer.Send(BlockchainChannel, msgBytes) { - // doing nothing, will try later in `poolRoutine` - } - // peer is added to the pool once we receive the first - // bcStatusResponseMessage from the peer and call pool.SetPeerHeight -} - -// RemovePeer implements Reactor by removing peer from the pool. -func (bcR *BlockchainReactor) RemovePeer(peer p2p.Peer, reason interface{}) { - bcR.pool.RemovePeer(peer.ID()) -} - -// respondToPeer loads a block and sends it to the requesting peer, -// if we have it. Otherwise, we'll respond saying we don't have it. -// According to the Tendermint spec, if all nodes are honest, -// no node should be requesting for a block that's non-existent. -func (bcR *BlockchainReactor) respondToPeer(msg *bcBlockRequestMessage, - src p2p.Peer) (queued bool) { - - block := bcR.store.LoadBlock(msg.Height) - if block != nil { - msgBytes := cdc.MustMarshalBinaryBare(&bcBlockResponseMessage{Block: block}) - return src.TrySend(BlockchainChannel, msgBytes) - } - - bcR.Logger.Info("Peer asking for a block we don't have", "src", src, "height", msg.Height) - - msgBytes := cdc.MustMarshalBinaryBare(&bcNoBlockResponseMessage{Height: msg.Height}) - return src.TrySend(BlockchainChannel, msgBytes) -} - -// Receive implements Reactor by handling 4 types of messages (look below). -func (bcR *BlockchainReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) { - msg, err := DecodeMessage(msgBytes) - if err != nil { - bcR.Logger.Error("Error decoding message", "src", src, "chId", chID, "msg", msg, "err", err, "bytes", msgBytes) - bcR.Switch.StopPeerForError(src, err) - return - } - - bcR.Logger.Debug("Receive", "src", src, "chID", chID, "msg", msg) - - switch msg := msg.(type) { - case *bcBlockRequestMessage: - if queued := bcR.respondToPeer(msg, src); !queued { - // Unfortunately not queued since the queue is full. - } - case *bcBlockResponseMessage: - // Got a block. - bcR.pool.AddBlock(src.ID(), msg.Block, len(msgBytes)) - case *bcStatusRequestMessage: - // Send peer our state. - msgBytes := cdc.MustMarshalBinaryBare(&bcStatusResponseMessage{bcR.store.Height()}) - queued := src.TrySend(BlockchainChannel, msgBytes) - if !queued { - // sorry - } - case *bcStatusResponseMessage: - // Got a peer status. Unverified. - bcR.pool.SetPeerHeight(src.ID(), msg.Height) - default: - bcR.Logger.Error(cmn.Fmt("Unknown message type %v", reflect.TypeOf(msg))) - } -} - -// Handle messages from the poolReactor telling the reactor what to do. -// NOTE: Don't sleep in the FOR_LOOP or otherwise slow it down! -// (Except for the SYNC_LOOP, which is the primary purpose and must be synchronous.) -func (bcR *BlockchainReactor) poolRoutine() { - - trySyncTicker := time.NewTicker(trySyncIntervalMS * time.Millisecond) - statusUpdateTicker := time.NewTicker(statusUpdateIntervalSeconds * time.Second) - switchToConsensusTicker := time.NewTicker(switchToConsensusIntervalSeconds * time.Second) - - blocksSynced := 0 - - chainID := bcR.initialState.ChainID - state := bcR.initialState - - lastHundred := time.Now() - lastRate := 0.0 - -FOR_LOOP: - for { - select { - case request := <-bcR.requestsCh: - peer := bcR.Switch.Peers().Get(request.PeerID) - if peer == nil { - continue FOR_LOOP // Peer has since been disconnected. - } - msgBytes := cdc.MustMarshalBinaryBare(&bcBlockRequestMessage{request.Height}) - queued := peer.TrySend(BlockchainChannel, msgBytes) - if !queued { - // We couldn't make the request, send-queue full. - // The pool handles timeouts, just let it go. - continue FOR_LOOP - } - case err := <-bcR.errorsCh: - peer := bcR.Switch.Peers().Get(err.peerID) - if peer != nil { - bcR.Switch.StopPeerForError(peer, err) - } - case <-statusUpdateTicker.C: - // ask for status updates - go bcR.BroadcastStatusRequest() // nolint: errcheck - case <-switchToConsensusTicker.C: - height, numPending, lenRequesters := bcR.pool.GetStatus() - outbound, inbound, _ := bcR.Switch.NumPeers() - bcR.Logger.Debug("Consensus ticker", "numPending", numPending, "total", lenRequesters, - "outbound", outbound, "inbound", inbound) - if bcR.pool.IsCaughtUp() { - bcR.Logger.Info("Time to switch to consensus reactor!", "height", height) - bcR.pool.Stop() - - conR := bcR.Switch.Reactor("CONSENSUS").(consensusReactor) - conR.SwitchToConsensus(state, blocksSynced) - - break FOR_LOOP - } - case <-trySyncTicker.C: // chan time - // This loop can be slow as long as it's doing syncing work. - SYNC_LOOP: - for i := 0; i < 10; i++ { - // See if there are any blocks to sync. - first, second := bcR.pool.PeekTwoBlocks() - //bcR.Logger.Info("TrySync peeked", "first", first, "second", second) - if first == nil || second == nil { - // We need both to sync the first block. - break SYNC_LOOP - } - firstParts := first.MakePartSet(state.ConsensusParams.BlockPartSizeBytes) - firstPartsHeader := firstParts.Header() - firstID := types.BlockID{first.Hash(), firstPartsHeader} - // Finally, verify the first block using the second's commit - // NOTE: we can probably make this more efficient, but note that calling - // first.Hash() doesn't verify the tx contents, so MakePartSet() is - // currently necessary. - err := state.Validators.VerifyCommit( - chainID, firstID, first.Height, second.LastCommit) - if err != nil { - bcR.Logger.Error("Error in validation", "err", err) - peerID := bcR.pool.RedoRequest(first.Height) - peer := bcR.Switch.Peers().Get(peerID) - if peer != nil { - bcR.Switch.StopPeerForError(peer, fmt.Errorf("BlockchainReactor validation error: %v", err)) - } - break SYNC_LOOP - } else { - bcR.pool.PopRequest() - - // TODO: batch saves so we dont persist to disk every block - bcR.store.SaveBlock(first, firstParts, second.LastCommit) - - // TODO: same thing for app - but we would need a way to - // get the hash without persisting the state - var err error - state, err = bcR.blockExec.ApplyBlock(state, firstID, first) - if err != nil { - // TODO This is bad, are we zombie? - cmn.PanicQ(cmn.Fmt("Failed to process committed block (%d:%X): %v", - first.Height, first.Hash(), err)) - } - blocksSynced++ - - if blocksSynced%100 == 0 { - lastRate = 0.9*lastRate + 0.1*(100/time.Since(lastHundred).Seconds()) - bcR.Logger.Info("Fast Sync Rate", "height", bcR.pool.height, - "max_peer_height", bcR.pool.MaxPeerHeight(), "blocks/s", lastRate) - lastHundred = time.Now() - } - } - } - continue FOR_LOOP - case <-bcR.Quit(): - break FOR_LOOP - } - } -} - -// BroadcastStatusRequest broadcasts `BlockStore` height. -func (bcR *BlockchainReactor) BroadcastStatusRequest() error { - msgBytes := cdc.MustMarshalBinaryBare(&bcStatusRequestMessage{bcR.store.Height()}) - bcR.Switch.Broadcast(BlockchainChannel, msgBytes) - return nil -} - -//----------------------------------------------------------------------------- -// Messages - -// BlockchainMessage is a generic message for this reactor. -type BlockchainMessage interface{} - -func RegisterBlockchainMessages(cdc *amino.Codec) { - cdc.RegisterInterface((*BlockchainMessage)(nil), nil) - cdc.RegisterConcrete(&bcBlockRequestMessage{}, "tendermint/mempool/BlockRequest", nil) - cdc.RegisterConcrete(&bcBlockResponseMessage{}, "tendermint/mempool/BlockResponse", nil) - cdc.RegisterConcrete(&bcNoBlockResponseMessage{}, "tendermint/mempool/NoBlockResponse", nil) - cdc.RegisterConcrete(&bcStatusResponseMessage{}, "tendermint/mempool/StatusResponse", nil) - cdc.RegisterConcrete(&bcStatusRequestMessage{}, "tendermint/mempool/StatusRequest", nil) -} - -// DecodeMessage decodes BlockchainMessage. -// TODO: ensure that bz is completely read. -func DecodeMessage(bz []byte) (msg BlockchainMessage, err error) { - if len(bz) > maxMsgSize { - return msg, fmt.Errorf("Msg exceeds max size (%d > %d)", - len(bz), maxMsgSize) - } - err = cdc.UnmarshalBinaryBare(bz, &msg) - if err != nil { - err = cmn.ErrorWrap(err, "DecodeMessage() had bytes left over") - } - return -} - -//------------------------------------- - -type bcBlockRequestMessage struct { - Height int64 -} - -func (m *bcBlockRequestMessage) String() string { - return cmn.Fmt("[bcBlockRequestMessage %v]", m.Height) -} - -type bcNoBlockResponseMessage struct { - Height int64 -} - -func (brm *bcNoBlockResponseMessage) String() string { - return cmn.Fmt("[bcNoBlockResponseMessage %d]", brm.Height) -} - -//------------------------------------- - -type bcBlockResponseMessage struct { - Block *types.Block -} - -func (m *bcBlockResponseMessage) String() string { - return cmn.Fmt("[bcBlockResponseMessage %v]", m.Block.Height) -} - -//------------------------------------- - -type bcStatusRequestMessage struct { - Height int64 -} - -func (m *bcStatusRequestMessage) String() string { - return cmn.Fmt("[bcStatusRequestMessage %v]", m.Height) -} - -//------------------------------------- - -type bcStatusResponseMessage struct { - Height int64 -} - -func (m *bcStatusResponseMessage) String() string { - return cmn.Fmt("[bcStatusResponseMessage %v]", m.Height) -} diff --git a/blockchain/reactor_test.go b/blockchain/reactor_test.go deleted file mode 100644 index c7f7e9afd..000000000 --- a/blockchain/reactor_test.go +++ /dev/null @@ -1,208 +0,0 @@ -package blockchain - -import ( - "net" - "testing" - - cmn "github.com/tendermint/tmlibs/common" - dbm "github.com/tendermint/tmlibs/db" - "github.com/tendermint/tmlibs/log" - - cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/p2p" - "github.com/tendermint/tendermint/proxy" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" -) - -func makeStateAndBlockStore(logger log.Logger) (sm.State, *BlockStore) { - config := cfg.ResetTestRoot("blockchain_reactor_test") - // blockDB := dbm.NewDebugDB("blockDB", dbm.NewMemDB()) - // stateDB := dbm.NewDebugDB("stateDB", dbm.NewMemDB()) - blockDB := dbm.NewMemDB() - stateDB := dbm.NewMemDB() - blockStore := NewBlockStore(blockDB) - state, err := sm.LoadStateFromDBOrGenesisFile(stateDB, config.GenesisFile()) - if err != nil { - panic(cmn.ErrorWrap(err, "error constructing state from genesis file")) - } - return state, blockStore -} - -func newBlockchainReactor(logger log.Logger, maxBlockHeight int64) *BlockchainReactor { - state, blockStore := makeStateAndBlockStore(logger) - - // Make the blockchainReactor itself - fastSync := true - var nilApp proxy.AppConnConsensus - blockExec := sm.NewBlockExecutor(dbm.NewMemDB(), log.TestingLogger(), nilApp, - sm.MockMempool{}, sm.MockEvidencePool{}) - - bcReactor := NewBlockchainReactor(state.Copy(), blockExec, blockStore, fastSync) - bcReactor.SetLogger(logger.With("module", "blockchain")) - - // Next: we need to set a switch in order for peers to be added in - bcReactor.Switch = p2p.NewSwitch(cfg.DefaultP2PConfig()) - - // Lastly: let's add some blocks in - for blockHeight := int64(1); blockHeight <= maxBlockHeight; blockHeight++ { - firstBlock := makeBlock(blockHeight, state) - secondBlock := makeBlock(blockHeight+1, state) - firstParts := firstBlock.MakePartSet(state.ConsensusParams.BlockGossip.BlockPartSizeBytes) - blockStore.SaveBlock(firstBlock, firstParts, secondBlock.LastCommit) - } - - return bcReactor -} - -func TestNoBlockResponse(t *testing.T) { - maxBlockHeight := int64(20) - - bcr := newBlockchainReactor(log.TestingLogger(), maxBlockHeight) - bcr.Start() - defer bcr.Stop() - - // Add some peers in - peer := newbcrTestPeer(p2p.ID(cmn.RandStr(12))) - bcr.AddPeer(peer) - - chID := byte(0x01) - - tests := []struct { - height int64 - existent bool - }{ - {maxBlockHeight + 2, false}, - {10, true}, - {1, true}, - {100, false}, - } - - // receive a request message from peer, - // wait for our response to be received on the peer - for _, tt := range tests { - reqBlockMsg := &bcBlockRequestMessage{tt.height} - reqBlockBytes := cdc.MustMarshalBinaryBare(reqBlockMsg) - bcr.Receive(chID, peer, reqBlockBytes) - msg := peer.lastBlockchainMessage() - - if tt.existent { - if blockMsg, ok := msg.(*bcBlockResponseMessage); !ok { - t.Fatalf("Expected to receive a block response for height %d", tt.height) - } else if blockMsg.Block.Height != tt.height { - t.Fatalf("Expected response to be for height %d, got %d", tt.height, blockMsg.Block.Height) - } - } else { - if noBlockMsg, ok := msg.(*bcNoBlockResponseMessage); !ok { - t.Fatalf("Expected to receive a no block response for height %d", tt.height) - } else if noBlockMsg.Height != tt.height { - t.Fatalf("Expected response to be for height %d, got %d", tt.height, noBlockMsg.Height) - } - } - } -} - -/* -// NOTE: This is too hard to test without -// an easy way to add test peer to switch -// or without significant refactoring of the module. -// Alternatively we could actually dial a TCP conn but -// that seems extreme. -func TestBadBlockStopsPeer(t *testing.T) { - maxBlockHeight := int64(20) - - bcr := newBlockchainReactor(log.TestingLogger(), maxBlockHeight) - bcr.Start() - defer bcr.Stop() - - // Add some peers in - peer := newbcrTestPeer(p2p.ID(cmn.RandStr(12))) - - // XXX: This doesn't add the peer to anything, - // so it's hard to check that it's later removed - bcr.AddPeer(peer) - assert.True(t, bcr.Switch.Peers().Size() > 0) - - // send a bad block from the peer - // default blocks already dont have commits, so should fail - block := bcr.store.LoadBlock(3) - msg := &bcBlockResponseMessage{Block: block} - peer.Send(BlockchainChannel, struct{ BlockchainMessage }{msg}) - - ticker := time.NewTicker(time.Millisecond * 10) - timer := time.NewTimer(time.Second * 2) -LOOP: - for { - select { - case <-ticker.C: - if bcr.Switch.Peers().Size() == 0 { - break LOOP - } - case <-timer.C: - t.Fatal("Timed out waiting to disconnect peer") - } - } -} -*/ - -//---------------------------------------------- -// utility funcs - -func makeTxs(height int64) (txs []types.Tx) { - for i := 0; i < 10; i++ { - txs = append(txs, types.Tx([]byte{byte(height), byte(i)})) - } - return txs -} - -func makeBlock(height int64, state sm.State) *types.Block { - block, _ := state.MakeBlock(height, makeTxs(height), new(types.Commit)) - return block -} - -// The Test peer -type bcrTestPeer struct { - cmn.BaseService - id p2p.ID - ch chan interface{} -} - -var _ p2p.Peer = (*bcrTestPeer)(nil) - -func newbcrTestPeer(id p2p.ID) *bcrTestPeer { - bcr := &bcrTestPeer{ - id: id, - ch: make(chan interface{}, 2), - } - bcr.BaseService = *cmn.NewBaseService(nil, "bcrTestPeer", bcr) - return bcr -} - -func (tp *bcrTestPeer) lastBlockchainMessage() interface{} { return <-tp.ch } - -func (tp *bcrTestPeer) TrySend(chID byte, msgBytes []byte) bool { - var msg BlockchainMessage - err := cdc.UnmarshalBinaryBare(msgBytes, &msg) - if err != nil { - panic(cmn.ErrorWrap(err, "Error while trying to parse a BlockchainMessage")) - } - if _, ok := msg.(*bcStatusResponseMessage); ok { - // Discard status response messages since they skew our results - // We only want to deal with: - // + bcBlockResponseMessage - // + bcNoBlockResponseMessage - } else { - tp.ch <- msg - } - return true -} - -func (tp *bcrTestPeer) Send(chID byte, msgBytes []byte) bool { return tp.TrySend(chID, msgBytes) } -func (tp *bcrTestPeer) NodeInfo() p2p.NodeInfo { return p2p.NodeInfo{} } -func (tp *bcrTestPeer) Status() p2p.ConnectionStatus { return p2p.ConnectionStatus{} } -func (tp *bcrTestPeer) ID() p2p.ID { return tp.id } -func (tp *bcrTestPeer) IsOutbound() bool { return false } -func (tp *bcrTestPeer) IsPersistent() bool { return true } -func (tp *bcrTestPeer) Get(s string) interface{} { return s } -func (tp *bcrTestPeer) Set(string, interface{}) {} -func (tp *bcrTestPeer) RemoteIP() net.IP { return []byte{127, 0, 0, 1} } diff --git a/blockchain/store.go b/blockchain/store.go deleted file mode 100644 index e7608b2cc..000000000 --- a/blockchain/store.go +++ /dev/null @@ -1,247 +0,0 @@ -package blockchain - -import ( - "fmt" - "sync" - - cmn "github.com/tendermint/tmlibs/common" - dbm "github.com/tendermint/tmlibs/db" - - "github.com/tendermint/tendermint/types" -) - -/* -BlockStore is a simple low level store for blocks. - -There are three types of information stored: - - BlockMeta: Meta information about each block - - Block part: Parts of each block, aggregated w/ PartSet - - Commit: The commit part of each block, for gossiping precommit votes - -Currently the precommit signatures are duplicated in the Block parts as -well as the Commit. In the future this may change, perhaps by moving -the Commit data outside the Block. (TODO) - -// NOTE: BlockStore methods will panic if they encounter errors -// deserializing loaded data, indicating probable corruption on disk. -*/ -type BlockStore struct { - db dbm.DB - - mtx sync.RWMutex - height int64 -} - -// NewBlockStore returns a new BlockStore with the given DB, -// initialized to the last height that was committed to the DB. -func NewBlockStore(db dbm.DB) *BlockStore { - bsjson := LoadBlockStoreStateJSON(db) - return &BlockStore{ - height: bsjson.Height, - db: db, - } -} - -// Height returns the last known contiguous block height. -func (bs *BlockStore) Height() int64 { - bs.mtx.RLock() - defer bs.mtx.RUnlock() - return bs.height -} - -// LoadBlock returns the block with the given height. -// If no block is found for that height, it returns nil. -func (bs *BlockStore) LoadBlock(height int64) *types.Block { - var blockMeta = bs.LoadBlockMeta(height) - if blockMeta == nil { - return nil - } - - var block = new(types.Block) - buf := []byte{} - for i := 0; i < blockMeta.BlockID.PartsHeader.Total; i++ { - part := bs.LoadBlockPart(height, i) - buf = append(buf, part.Bytes...) - } - err := cdc.UnmarshalBinary(buf, block) - if err != nil { - // NOTE: The existence of meta should imply the existence of the - // block. So, make sure meta is only saved after blocks are saved. - panic(cmn.ErrorWrap(err, "Error reading block")) - } - return block -} - -// LoadBlockPart returns the Part at the given index -// from the block at the given height. -// If no part is found for the given height and index, it returns nil. -func (bs *BlockStore) LoadBlockPart(height int64, index int) *types.Part { - var part = new(types.Part) - bz := bs.db.Get(calcBlockPartKey(height, index)) - if len(bz) == 0 { - return nil - } - err := cdc.UnmarshalBinaryBare(bz, part) - if err != nil { - panic(cmn.ErrorWrap(err, "Error reading block part")) - } - return part -} - -// LoadBlockMeta returns the BlockMeta for the given height. -// If no block is found for the given height, it returns nil. -func (bs *BlockStore) LoadBlockMeta(height int64) *types.BlockMeta { - var blockMeta = new(types.BlockMeta) - bz := bs.db.Get(calcBlockMetaKey(height)) - if len(bz) == 0 { - return nil - } - err := cdc.UnmarshalBinaryBare(bz, blockMeta) - if err != nil { - panic(cmn.ErrorWrap(err, "Error reading block meta")) - } - return blockMeta -} - -// LoadBlockCommit returns the Commit for the given height. -// This commit consists of the +2/3 and other Precommit-votes for block at `height`, -// and it comes from the block.LastCommit for `height+1`. -// If no commit is found for the given height, it returns nil. -func (bs *BlockStore) LoadBlockCommit(height int64) *types.Commit { - var commit = new(types.Commit) - bz := bs.db.Get(calcBlockCommitKey(height)) - if len(bz) == 0 { - return nil - } - err := cdc.UnmarshalBinaryBare(bz, commit) - if err != nil { - panic(cmn.ErrorWrap(err, "Error reading block commit")) - } - return commit -} - -// LoadSeenCommit returns the locally seen Commit for the given height. -// This is useful when we've seen a commit, but there has not yet been -// a new block at `height + 1` that includes this commit in its block.LastCommit. -func (bs *BlockStore) LoadSeenCommit(height int64) *types.Commit { - var commit = new(types.Commit) - bz := bs.db.Get(calcSeenCommitKey(height)) - if len(bz) == 0 { - return nil - } - err := cdc.UnmarshalBinaryBare(bz, commit) - if err != nil { - panic(cmn.ErrorWrap(err, "Error reading block seen commit")) - } - return commit -} - -// SaveBlock persists the given block, blockParts, and seenCommit to the underlying db. -// blockParts: Must be parts of the block -// seenCommit: The +2/3 precommits that were seen which committed at height. -// If all the nodes restart after committing a block, -// we need this to reload the precommits to catch-up nodes to the -// most recent height. Otherwise they'd stall at H-1. -func (bs *BlockStore) SaveBlock(block *types.Block, blockParts *types.PartSet, seenCommit *types.Commit) { - if block == nil { - cmn.PanicSanity("BlockStore can only save a non-nil block") - } - height := block.Height - if g, w := height, bs.Height()+1; g != w { - cmn.PanicSanity(cmn.Fmt("BlockStore can only save contiguous blocks. Wanted %v, got %v", w, g)) - } - if !blockParts.IsComplete() { - cmn.PanicSanity(cmn.Fmt("BlockStore can only save complete block part sets")) - } - - // Save block meta - blockMeta := types.NewBlockMeta(block, blockParts) - metaBytes := cdc.MustMarshalBinaryBare(blockMeta) - bs.db.Set(calcBlockMetaKey(height), metaBytes) - - // Save block parts - for i := 0; i < blockParts.Total(); i++ { - part := blockParts.GetPart(i) - bs.saveBlockPart(height, i, part) - } - - // Save block commit (duplicate and separate from the Block) - blockCommitBytes := cdc.MustMarshalBinaryBare(block.LastCommit) - bs.db.Set(calcBlockCommitKey(height-1), blockCommitBytes) - - // Save seen commit (seen +2/3 precommits for block) - // NOTE: we can delete this at a later height - seenCommitBytes := cdc.MustMarshalBinaryBare(seenCommit) - bs.db.Set(calcSeenCommitKey(height), seenCommitBytes) - - // Save new BlockStoreStateJSON descriptor - BlockStoreStateJSON{Height: height}.Save(bs.db) - - // Done! - bs.mtx.Lock() - bs.height = height - bs.mtx.Unlock() - - // Flush - bs.db.SetSync(nil, nil) -} - -func (bs *BlockStore) saveBlockPart(height int64, index int, part *types.Part) { - if height != bs.Height()+1 { - cmn.PanicSanity(cmn.Fmt("BlockStore can only save contiguous blocks. Wanted %v, got %v", bs.Height()+1, height)) - } - partBytes := cdc.MustMarshalBinaryBare(part) - bs.db.Set(calcBlockPartKey(height, index), partBytes) -} - -//----------------------------------------------------------------------------- - -func calcBlockMetaKey(height int64) []byte { - return []byte(fmt.Sprintf("H:%v", height)) -} - -func calcBlockPartKey(height int64, partIndex int) []byte { - return []byte(fmt.Sprintf("P:%v:%v", height, partIndex)) -} - -func calcBlockCommitKey(height int64) []byte { - return []byte(fmt.Sprintf("C:%v", height)) -} - -func calcSeenCommitKey(height int64) []byte { - return []byte(fmt.Sprintf("SC:%v", height)) -} - -//----------------------------------------------------------------------------- - -var blockStoreKey = []byte("blockStore") - -type BlockStoreStateJSON struct { - Height int64 `json:"height"` -} - -// Save persists the blockStore state to the database as JSON. -func (bsj BlockStoreStateJSON) Save(db dbm.DB) { - bytes, err := cdc.MarshalJSON(bsj) - if err != nil { - cmn.PanicSanity(cmn.Fmt("Could not marshal state bytes: %v", err)) - } - db.SetSync(blockStoreKey, bytes) -} - -// LoadBlockStoreStateJSON returns the BlockStoreStateJSON as loaded from disk. -// If no BlockStoreStateJSON was previously persisted, it returns the zero value. -func LoadBlockStoreStateJSON(db dbm.DB) BlockStoreStateJSON { - bytes := db.Get(blockStoreKey) - if len(bytes) == 0 { - return BlockStoreStateJSON{ - Height: 0, - } - } - bsj := BlockStoreStateJSON{} - err := cdc.UnmarshalJSON(bytes, &bsj) - if err != nil { - panic(fmt.Sprintf("Could not unmarshal bytes: %X", bytes)) - } - return bsj -} diff --git a/blockchain/store_test.go b/blockchain/store_test.go deleted file mode 100644 index a1bd0fd5d..000000000 --- a/blockchain/store_test.go +++ /dev/null @@ -1,383 +0,0 @@ -package blockchain - -import ( - "bytes" - "fmt" - "runtime/debug" - "strings" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/tendermint/tmlibs/db" - "github.com/tendermint/tmlibs/log" - - "github.com/tendermint/tendermint/types" -) - -func TestLoadBlockStoreStateJSON(t *testing.T) { - db := db.NewMemDB() - - bsj := &BlockStoreStateJSON{Height: 1000} - bsj.Save(db) - - retrBSJ := LoadBlockStoreStateJSON(db) - - assert.Equal(t, *bsj, retrBSJ, "expected the retrieved DBs to match") -} - -func TestNewBlockStore(t *testing.T) { - db := db.NewMemDB() - db.Set(blockStoreKey, []byte(`{"height": 10000}`)) - bs := NewBlockStore(db) - require.Equal(t, int64(10000), bs.Height(), "failed to properly parse blockstore") - - panicCausers := []struct { - data []byte - wantErr string - }{ - {[]byte("artful-doger"), "not unmarshal bytes"}, - {[]byte(" "), "unmarshal bytes"}, - } - - for i, tt := range panicCausers { - // Expecting a panic here on trying to parse an invalid blockStore - _, _, panicErr := doFn(func() (interface{}, error) { - db.Set(blockStoreKey, tt.data) - _ = NewBlockStore(db) - return nil, nil - }) - require.NotNil(t, panicErr, "#%d panicCauser: %q expected a panic", i, tt.data) - assert.Contains(t, panicErr.Error(), tt.wantErr, "#%d data: %q", i, tt.data) - } - - db.Set(blockStoreKey, nil) - bs = NewBlockStore(db) - assert.Equal(t, bs.Height(), int64(0), "expecting nil bytes to be unmarshaled alright") -} - -func freshBlockStore() (*BlockStore, db.DB) { - db := db.NewMemDB() - return NewBlockStore(db), db -} - -var ( - state, _ = makeStateAndBlockStore(log.NewTMLogger(new(bytes.Buffer))) - - block = makeBlock(1, state) - partSet = block.MakePartSet(2) - part1 = partSet.GetPart(0) - part2 = partSet.GetPart(1) - seenCommit1 = &types.Commit{Precommits: []*types.Vote{{Height: 10, - Timestamp: time.Now().UTC()}}} -) - -// TODO: This test should be simplified ... - -func TestBlockStoreSaveLoadBlock(t *testing.T) { - state, bs := makeStateAndBlockStore(log.NewTMLogger(new(bytes.Buffer))) - require.Equal(t, bs.Height(), int64(0), "initially the height should be zero") - - // check there are no blocks at various heights - noBlockHeights := []int64{0, -1, 100, 1000, 2} - for i, height := range noBlockHeights { - if g := bs.LoadBlock(height); g != nil { - t.Errorf("#%d: height(%d) got a block; want nil", i, height) - } - } - - // save a block - block := makeBlock(bs.Height()+1, state) - validPartSet := block.MakePartSet(2) - seenCommit := &types.Commit{Precommits: []*types.Vote{{Height: 10, - Timestamp: time.Now().UTC()}}} - bs.SaveBlock(block, partSet, seenCommit) - require.Equal(t, bs.Height(), block.Header.Height, "expecting the new height to be changed") - - incompletePartSet := types.NewPartSetFromHeader(types.PartSetHeader{Total: 2}) - uncontiguousPartSet := types.NewPartSetFromHeader(types.PartSetHeader{Total: 0}) - uncontiguousPartSet.AddPart(part2) - - header1 := types.Header{ - Height: 1, - NumTxs: 100, - ChainID: "block_test", - Time: time.Now(), - } - header2 := header1 - header2.Height = 4 - - // End of setup, test data - - commitAtH10 := &types.Commit{Precommits: []*types.Vote{{Height: 10, - Timestamp: time.Now().UTC()}}} - tuples := []struct { - block *types.Block - parts *types.PartSet - seenCommit *types.Commit - wantErr bool - wantPanic string - - corruptBlockInDB bool - corruptCommitInDB bool - corruptSeenCommitInDB bool - eraseCommitInDB bool - eraseSeenCommitInDB bool - }{ - { - block: newBlock(&header1, commitAtH10), - parts: validPartSet, - seenCommit: seenCommit1, - }, - - { - block: nil, - wantPanic: "only save a non-nil block", - }, - - { - block: newBlock(&header2, commitAtH10), - parts: uncontiguousPartSet, - wantPanic: "only save contiguous blocks", // and incomplete and uncontiguous parts - }, - - { - block: newBlock(&header1, commitAtH10), - parts: incompletePartSet, - wantPanic: "only save complete block", // incomplete parts - }, - - { - block: newBlock(&header1, commitAtH10), - parts: validPartSet, - seenCommit: seenCommit1, - corruptCommitInDB: true, // Corrupt the DB's commit entry - wantPanic: "Error reading block commit", - }, - - { - block: newBlock(&header1, commitAtH10), - parts: validPartSet, - seenCommit: seenCommit1, - wantPanic: "Error reading block", - corruptBlockInDB: true, // Corrupt the DB's block entry - }, - - { - block: newBlock(&header1, commitAtH10), - parts: validPartSet, - seenCommit: seenCommit1, - - // Expecting no error and we want a nil back - eraseSeenCommitInDB: true, - }, - - { - block: newBlock(&header1, commitAtH10), - parts: validPartSet, - seenCommit: seenCommit1, - - corruptSeenCommitInDB: true, - wantPanic: "Error reading block seen commit", - }, - - { - block: newBlock(&header1, commitAtH10), - parts: validPartSet, - seenCommit: seenCommit1, - - // Expecting no error and we want a nil back - eraseCommitInDB: true, - }, - } - - type quad struct { - block *types.Block - commit *types.Commit - meta *types.BlockMeta - - seenCommit *types.Commit - } - - for i, tuple := range tuples { - bs, db := freshBlockStore() - // SaveBlock - res, err, panicErr := doFn(func() (interface{}, error) { - bs.SaveBlock(tuple.block, tuple.parts, tuple.seenCommit) - if tuple.block == nil { - return nil, nil - } - - if tuple.corruptBlockInDB { - db.Set(calcBlockMetaKey(tuple.block.Height), []byte("block-bogus")) - } - bBlock := bs.LoadBlock(tuple.block.Height) - bBlockMeta := bs.LoadBlockMeta(tuple.block.Height) - - if tuple.eraseSeenCommitInDB { - db.Delete(calcSeenCommitKey(tuple.block.Height)) - } - if tuple.corruptSeenCommitInDB { - db.Set(calcSeenCommitKey(tuple.block.Height), []byte("bogus-seen-commit")) - } - bSeenCommit := bs.LoadSeenCommit(tuple.block.Height) - - commitHeight := tuple.block.Height - 1 - if tuple.eraseCommitInDB { - db.Delete(calcBlockCommitKey(commitHeight)) - } - if tuple.corruptCommitInDB { - db.Set(calcBlockCommitKey(commitHeight), []byte("foo-bogus")) - } - bCommit := bs.LoadBlockCommit(commitHeight) - return &quad{block: bBlock, seenCommit: bSeenCommit, commit: bCommit, - meta: bBlockMeta}, nil - }) - - if subStr := tuple.wantPanic; subStr != "" { - if panicErr == nil { - t.Errorf("#%d: want a non-nil panic", i) - } else if got := panicErr.Error(); !strings.Contains(got, subStr) { - t.Errorf("#%d:\n\tgotErr: %q\nwant substring: %q", i, got, subStr) - } - continue - } - - if tuple.wantErr { - if err == nil { - t.Errorf("#%d: got nil error", i) - } - continue - } - - assert.Nil(t, panicErr, "#%d: unexpected panic", i) - assert.Nil(t, err, "#%d: expecting a non-nil error", i) - qua, ok := res.(*quad) - if !ok || qua == nil { - t.Errorf("#%d: got nil quad back; gotType=%T", i, res) - continue - } - if tuple.eraseSeenCommitInDB { - assert.Nil(t, qua.seenCommit, - "erased the seenCommit in the DB hence we should get back a nil seenCommit") - } - if tuple.eraseCommitInDB { - assert.Nil(t, qua.commit, - "erased the commit in the DB hence we should get back a nil commit") - } - } -} - -func TestLoadBlockPart(t *testing.T) { - bs, db := freshBlockStore() - height, index := int64(10), 1 - loadPart := func() (interface{}, error) { - part := bs.LoadBlockPart(height, index) - return part, nil - } - - // Initially no contents. - // 1. Requesting for a non-existent block shouldn't fail - res, _, panicErr := doFn(loadPart) - require.Nil(t, panicErr, "a non-existent block part shouldn't cause a panic") - require.Nil(t, res, "a non-existent block part should return nil") - - // 2. Next save a corrupted block then try to load it - db.Set(calcBlockPartKey(height, index), []byte("Tendermint")) - res, _, panicErr = doFn(loadPart) - require.NotNil(t, panicErr, "expecting a non-nil panic") - require.Contains(t, panicErr.Error(), "Error reading block part") - - // 3. A good block serialized and saved to the DB should be retrievable - db.Set(calcBlockPartKey(height, index), cdc.MustMarshalBinaryBare(part1)) - gotPart, _, panicErr := doFn(loadPart) - require.Nil(t, panicErr, "an existent and proper block should not panic") - require.Nil(t, res, "a properly saved block should return a proper block") - require.Equal(t, gotPart.(*types.Part).Hash(), part1.Hash(), - "expecting successful retrieval of previously saved block") -} - -func TestLoadBlockMeta(t *testing.T) { - bs, db := freshBlockStore() - height := int64(10) - loadMeta := func() (interface{}, error) { - meta := bs.LoadBlockMeta(height) - return meta, nil - } - - // Initially no contents. - // 1. Requesting for a non-existent blockMeta shouldn't fail - res, _, panicErr := doFn(loadMeta) - require.Nil(t, panicErr, "a non-existent blockMeta shouldn't cause a panic") - require.Nil(t, res, "a non-existent blockMeta should return nil") - - // 2. Next save a corrupted blockMeta then try to load it - db.Set(calcBlockMetaKey(height), []byte("Tendermint-Meta")) - res, _, panicErr = doFn(loadMeta) - require.NotNil(t, panicErr, "expecting a non-nil panic") - require.Contains(t, panicErr.Error(), "Error reading block meta") - - // 3. A good blockMeta serialized and saved to the DB should be retrievable - meta := &types.BlockMeta{} - db.Set(calcBlockMetaKey(height), cdc.MustMarshalBinaryBare(meta)) - gotMeta, _, panicErr := doFn(loadMeta) - require.Nil(t, panicErr, "an existent and proper block should not panic") - require.Nil(t, res, "a properly saved blockMeta should return a proper blocMeta ") - require.Equal(t, cdc.MustMarshalBinaryBare(meta), cdc.MustMarshalBinaryBare(gotMeta), - "expecting successful retrieval of previously saved blockMeta") -} - -func TestBlockFetchAtHeight(t *testing.T) { - state, bs := makeStateAndBlockStore(log.NewTMLogger(new(bytes.Buffer))) - require.Equal(t, bs.Height(), int64(0), "initially the height should be zero") - block := makeBlock(bs.Height()+1, state) - - partSet := block.MakePartSet(2) - seenCommit := &types.Commit{Precommits: []*types.Vote{{Height: 10, - Timestamp: time.Now().UTC()}}} - - bs.SaveBlock(block, partSet, seenCommit) - require.Equal(t, bs.Height(), block.Header.Height, "expecting the new height to be changed") - - blockAtHeight := bs.LoadBlock(bs.Height()) - bz1 := cdc.MustMarshalBinaryBare(block) - bz2 := cdc.MustMarshalBinaryBare(blockAtHeight) - require.Equal(t, bz1, bz2) - require.Equal(t, block.Hash(), blockAtHeight.Hash(), - "expecting a successful load of the last saved block") - - blockAtHeightPlus1 := bs.LoadBlock(bs.Height() + 1) - require.Nil(t, blockAtHeightPlus1, "expecting an unsuccessful load of Height()+1") - blockAtHeightPlus2 := bs.LoadBlock(bs.Height() + 2) - require.Nil(t, blockAtHeightPlus2, "expecting an unsuccessful load of Height()+2") -} - -func doFn(fn func() (interface{}, error)) (res interface{}, err error, panicErr error) { - defer func() { - if r := recover(); r != nil { - switch e := r.(type) { - case error: - panicErr = e - case string: - panicErr = fmt.Errorf("%s", e) - default: - if st, ok := r.(fmt.Stringer); ok { - panicErr = fmt.Errorf("%s", st) - } else { - panicErr = fmt.Errorf("%s", debug.Stack()) - } - } - } - }() - - res, err = fn() - return res, err, panicErr -} - -func newBlock(hdr *types.Header, lastCommit *types.Commit) *types.Block { - return &types.Block{ - Header: hdr, - LastCommit: lastCommit, - } -} diff --git a/blockchain/wire.go b/blockchain/wire.go deleted file mode 100644 index 55b4e60ae..000000000 --- a/blockchain/wire.go +++ /dev/null @@ -1,13 +0,0 @@ -package blockchain - -import ( - "github.com/tendermint/go-amino" - "github.com/tendermint/go-crypto" -) - -var cdc = amino.NewCodec() - -func init() { - RegisterBlockchainMessages(cdc) - crypto.RegisterAmino(cdc) -} diff --git a/cmd/priv_val_server/main.go b/cmd/priv_val_server/main.go deleted file mode 100644 index c78adeb82..000000000 --- a/cmd/priv_val_server/main.go +++ /dev/null @@ -1,53 +0,0 @@ -package main - -import ( - "flag" - "os" - - crypto "github.com/tendermint/go-crypto" - cmn "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/log" - - "github.com/tendermint/tendermint/privval" -) - -func main() { - var ( - addr = flag.String("addr", ":26659", "Address of client to connect to") - chainID = flag.String("chain-id", "mychain", "chain id") - privValPath = flag.String("priv", "", "priv val file path") - - logger = log.NewTMLogger( - log.NewSyncWriter(os.Stdout), - ).With("module", "priv_val") - ) - flag.Parse() - - logger.Info( - "Starting private validator", - "addr", *addr, - "chainID", *chainID, - "privPath", *privValPath, - ) - - pv := privval.LoadFilePV(*privValPath) - - rs := privval.NewRemoteSigner( - logger, - *chainID, - *addr, - pv, - crypto.GenPrivKeyEd25519(), - ) - err := rs.Start() - if err != nil { - panic(err) - } - - cmn.TrapSignal(func() { - err := rs.Stop() - if err != nil { - panic(err) - } - }) -} diff --git a/cmd/tendermint/commands/gen_node_key.go b/cmd/tendermint/commands/gen_node_key.go deleted file mode 100644 index 4990be477..000000000 --- a/cmd/tendermint/commands/gen_node_key.go +++ /dev/null @@ -1,32 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/spf13/cobra" - - "github.com/tendermint/tendermint/p2p" - cmn "github.com/tendermint/tmlibs/common" -) - -// GenNodeKeyCmd allows the generation of a node key. It prints node's ID to -// the standard output. -var GenNodeKeyCmd = &cobra.Command{ - Use: "gen_node_key", - Short: "Generate a node key for this node and print its ID", - RunE: genNodeKey, -} - -func genNodeKey(cmd *cobra.Command, args []string) error { - nodeKeyFile := config.NodeKeyFile() - if cmn.FileExists(nodeKeyFile) { - return fmt.Errorf("node key at %s already exists", nodeKeyFile) - } - - nodeKey, err := p2p.LoadOrGenNodeKey(nodeKeyFile) - if err != nil { - return err - } - fmt.Println(nodeKey.ID()) - return nil -} diff --git a/cmd/tendermint/commands/gen_validator.go b/cmd/tendermint/commands/gen_validator.go deleted file mode 100644 index 20d43d4dd..000000000 --- a/cmd/tendermint/commands/gen_validator.go +++ /dev/null @@ -1,27 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/spf13/cobra" - - "github.com/tendermint/tendermint/privval" -) - -// GenValidatorCmd allows the generation of a keypair for a -// validator. -var GenValidatorCmd = &cobra.Command{ - Use: "gen_validator", - Short: "Generate new validator keypair", - Run: genValidator, -} - -func genValidator(cmd *cobra.Command, args []string) { - pv := privval.GenFilePV("") - jsbz, err := cdc.MarshalJSON(pv) - if err != nil { - panic(err) - } - fmt.Printf(`%v -`, string(jsbz)) -} diff --git a/cmd/tendermint/commands/init.go b/cmd/tendermint/commands/init.go deleted file mode 100644 index 45812b9ed..000000000 --- a/cmd/tendermint/commands/init.go +++ /dev/null @@ -1,70 +0,0 @@ -package commands - -import ( - "time" - - "github.com/spf13/cobra" - - cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/p2p" - "github.com/tendermint/tendermint/privval" - "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tmlibs/common" -) - -// InitFilesCmd initialises a fresh Tendermint Core instance. -var InitFilesCmd = &cobra.Command{ - Use: "init", - Short: "Initialize Tendermint", - RunE: initFiles, -} - -func initFiles(cmd *cobra.Command, args []string) error { - return initFilesWithConfig(config) -} - -func initFilesWithConfig(config *cfg.Config) error { - // private validator - privValFile := config.PrivValidatorFile() - var pv *privval.FilePV - if cmn.FileExists(privValFile) { - pv = privval.LoadFilePV(privValFile) - logger.Info("Found private validator", "path", privValFile) - } else { - pv = privval.GenFilePV(privValFile) - pv.Save() - logger.Info("Generated private validator", "path", privValFile) - } - - nodeKeyFile := config.NodeKeyFile() - if cmn.FileExists(nodeKeyFile) { - logger.Info("Found node key", "path", nodeKeyFile) - } else { - if _, err := p2p.LoadOrGenNodeKey(nodeKeyFile); err != nil { - return err - } - logger.Info("Generated node key", "path", nodeKeyFile) - } - - // genesis file - genFile := config.GenesisFile() - if cmn.FileExists(genFile) { - logger.Info("Found genesis file", "path", genFile) - } else { - genDoc := types.GenesisDoc{ - ChainID: cmn.Fmt("test-chain-%v", cmn.RandStr(6)), - GenesisTime: time.Now(), - } - genDoc.Validators = []types.GenesisValidator{{ - PubKey: pv.GetPubKey(), - Power: 10, - }} - - if err := genDoc.SaveAs(genFile); err != nil { - return err - } - logger.Info("Generated genesis file", "path", genFile) - } - - return nil -} diff --git a/cmd/tendermint/commands/lite.go b/cmd/tendermint/commands/lite.go deleted file mode 100644 index 6987b7f19..000000000 --- a/cmd/tendermint/commands/lite.go +++ /dev/null @@ -1,87 +0,0 @@ -package commands - -import ( - "fmt" - "net/url" - - "github.com/spf13/cobra" - - cmn "github.com/tendermint/tmlibs/common" - - "github.com/tendermint/tendermint/lite/proxy" - rpcclient "github.com/tendermint/tendermint/rpc/client" -) - -// LiteCmd represents the base command when called without any subcommands -var LiteCmd = &cobra.Command{ - Use: "lite", - Short: "Run lite-client proxy server, verifying tendermint rpc", - Long: `This node will run a secure proxy to a tendermint rpc server. - -All calls that can be tracked back to a block header by a proof -will be verified before passing them back to the caller. Other that -that it will present the same interface as a full tendermint node, -just with added trust and running locally.`, - RunE: runProxy, - SilenceUsage: true, -} - -var ( - listenAddr string - nodeAddr string - chainID string - home string -) - -func init() { - LiteCmd.Flags().StringVar(&listenAddr, "laddr", "tcp://localhost:8888", "Serve the proxy on the given address") - LiteCmd.Flags().StringVar(&nodeAddr, "node", "tcp://localhost:26657", "Connect to a Tendermint node at this address") - LiteCmd.Flags().StringVar(&chainID, "chain-id", "tendermint", "Specify the Tendermint chain ID") - LiteCmd.Flags().StringVar(&home, "home-dir", ".tendermint-lite", "Specify the home directory") -} - -func ensureAddrHasSchemeOrDefaultToTCP(addr string) (string, error) { - u, err := url.Parse(addr) - if err != nil { - return "", err - } - switch u.Scheme { - case "tcp", "unix": - case "": - u.Scheme = "tcp" - default: - return "", fmt.Errorf("unknown scheme %q, use either tcp or unix", u.Scheme) - } - return u.String(), nil -} - -func runProxy(cmd *cobra.Command, args []string) error { - nodeAddr, err := ensureAddrHasSchemeOrDefaultToTCP(nodeAddr) - if err != nil { - return err - } - listenAddr, err := ensureAddrHasSchemeOrDefaultToTCP(listenAddr) - if err != nil { - return err - } - - // First, connect a client - node := rpcclient.NewHTTP(nodeAddr, "/websocket") - - cert, err := proxy.GetCertifier(chainID, home, nodeAddr) - if err != nil { - return err - } - sc := proxy.SecureClient(node, cert) - - err = proxy.StartProxy(sc, listenAddr, logger) - if err != nil { - return err - } - - cmn.TrapSignal(func() { - // TODO: close up shop - }) - - return nil -} diff --git a/cmd/tendermint/commands/probe_upnp.go b/cmd/tendermint/commands/probe_upnp.go deleted file mode 100644 index 35c3c354d..000000000 --- a/cmd/tendermint/commands/probe_upnp.go +++ /dev/null @@ -1,31 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/spf13/cobra" - - "github.com/tendermint/tendermint/p2p/upnp" -) - -// ProbeUpnpCmd adds capabilities to test the UPnP functionality. -var ProbeUpnpCmd = &cobra.Command{ - Use: "probe_upnp", - Short: "Test UPnP functionality", - RunE: probeUpnp, -} - -func probeUpnp(cmd *cobra.Command, args []string) error { - capabilities, err := upnp.Probe(logger) - if err != nil { - fmt.Println("Probe failed: ", err) - } else { - fmt.Println("Probe success!") - jsonBytes, err := cdc.MarshalJSON(capabilities) - if err != nil { - return err - } - fmt.Println(string(jsonBytes)) - } - return nil -} diff --git a/cmd/tendermint/commands/replay.go b/cmd/tendermint/commands/replay.go deleted file mode 100644 index 303ccba6b..000000000 --- a/cmd/tendermint/commands/replay.go +++ /dev/null @@ -1,26 +0,0 @@ -package commands - -import ( - "github.com/spf13/cobra" - - "github.com/tendermint/tendermint/consensus" -) - -// ReplayCmd allows replaying of messages from the WAL. -var ReplayCmd = &cobra.Command{ - Use: "replay", - Short: "Replay messages from WAL", - Run: func(cmd *cobra.Command, args []string) { - consensus.RunReplayFile(config.BaseConfig, config.Consensus, false) - }, -} - -// ReplayConsoleCmd allows replaying of messages from the WAL in a -// console. -var ReplayConsoleCmd = &cobra.Command{ - Use: "replay_console", - Short: "Replay messages from WAL in a console", - Run: func(cmd *cobra.Command, args []string) { - consensus.RunReplayFile(config.BaseConfig, config.Consensus, true) - }, -} diff --git a/cmd/tendermint/commands/reset_priv_validator.go b/cmd/tendermint/commands/reset_priv_validator.go deleted file mode 100644 index 32d7b1433..000000000 --- a/cmd/tendermint/commands/reset_priv_validator.go +++ /dev/null @@ -1,69 +0,0 @@ -package commands - -import ( - "os" - - "github.com/spf13/cobra" - - "github.com/tendermint/tendermint/privval" - "github.com/tendermint/tmlibs/log" -) - -// ResetAllCmd removes the database of this Tendermint core -// instance. -var ResetAllCmd = &cobra.Command{ - Use: "unsafe_reset_all", - Short: "(unsafe) Remove all the data and WAL, reset this node's validator to genesis state", - Run: resetAll, -} - -// ResetPrivValidatorCmd resets the private validator files. -var ResetPrivValidatorCmd = &cobra.Command{ - Use: "unsafe_reset_priv_validator", - Short: "(unsafe) Reset this node's validator to genesis state", - Run: resetPrivValidator, -} - -// XXX: this is totally unsafe. -// it's only suitable for testnets. -func resetAll(cmd *cobra.Command, args []string) { - ResetAll(config.DBDir(), config.P2P.AddrBookFile(), config.PrivValidatorFile(), logger) -} - -// XXX: this is totally unsafe. -// it's only suitable for testnets. -func resetPrivValidator(cmd *cobra.Command, args []string) { - resetFilePV(config.PrivValidatorFile(), logger) -} - -// ResetAll removes the privValidator and address book files plus all data. -// Exported so other CLI tools can use it. -func ResetAll(dbDir, addrBookFile, privValFile string, logger log.Logger) { - resetFilePV(privValFile, logger) - removeAddrBook(addrBookFile, logger) - if err := os.RemoveAll(dbDir); err == nil { - logger.Info("Removed all blockchain history", "dir", dbDir) - } else { - logger.Error("Error removing all blockchain history", "dir", dbDir, "err", err) - } -} - -func resetFilePV(privValFile string, logger log.Logger) { - if _, err := os.Stat(privValFile); err == nil { - pv := privval.LoadFilePV(privValFile) - pv.Reset() - logger.Info("Reset private validator file to genesis state", "file", privValFile) - } else { - pv := privval.GenFilePV(privValFile) - pv.Save() - logger.Info("Generated private validator file", "file", privValFile) - } -} - -func removeAddrBook(addrBookFile string, logger log.Logger) { - if err := os.Remove(addrBookFile); err == nil { - logger.Info("Removed existing address book", "file", addrBookFile) - } else if !os.IsNotExist(err) { - logger.Info("Error removing address book", "file", addrBookFile, "err", err) - } -} diff --git a/cmd/tendermint/commands/root.go b/cmd/tendermint/commands/root.go deleted file mode 100644 index f229a7889..000000000 --- a/cmd/tendermint/commands/root.go +++ /dev/null @@ -1,63 +0,0 @@ -package commands - -import ( - "os" - - "github.com/spf13/cobra" - "github.com/spf13/viper" - - cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tmlibs/cli" - tmflags "github.com/tendermint/tmlibs/cli/flags" - "github.com/tendermint/tmlibs/log" -) - -var ( - config = cfg.DefaultConfig() - logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) -) - -func init() { - registerFlagsRootCmd(RootCmd) -} - -func registerFlagsRootCmd(cmd *cobra.Command) { - cmd.PersistentFlags().String("log_level", config.LogLevel, "Log level") -} - -// ParseConfig retrieves the default environment configuration, -// sets up the Tendermint root and ensures that the root exists -func ParseConfig() (*cfg.Config, error) { - conf := cfg.DefaultConfig() - err := viper.Unmarshal(conf) - if err != nil { - return nil, err - } - conf.SetRoot(conf.RootDir) - cfg.EnsureRoot(conf.RootDir) - return conf, err -} - -// RootCmd is the root command for Tendermint core. -var RootCmd = &cobra.Command{ - Use: "tendermint", - Short: "Tendermint Core (BFT Consensus) in Go", - PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) { - if cmd.Name() == VersionCmd.Name() { - return nil - } - config, err = ParseConfig() - if err != nil { - return err - } - logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultLogLevel()) - if err != nil { - return err - } - if viper.GetBool(cli.TraceFlag) { - logger = log.NewTracingLogger(logger) - } - logger = logger.With("module", "main") - return nil - }, -} diff --git a/cmd/tendermint/commands/root_test.go b/cmd/tendermint/commands/root_test.go deleted file mode 100644 index 59d258af7..000000000 --- a/cmd/tendermint/commands/root_test.go +++ /dev/null @@ -1,176 +0,0 @@ -package commands - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strconv" - "testing" - - "github.com/spf13/cobra" - "github.com/spf13/viper" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tmlibs/cli" - cmn "github.com/tendermint/tmlibs/common" -) - -var ( - defaultRoot = os.ExpandEnv("$HOME/.some/test/dir") -) - -const ( - rootName = "root" -) - -// clearConfig clears env vars, the given root dir, and resets viper. -func clearConfig(dir string) { - if err := os.Unsetenv("TMHOME"); err != nil { - panic(err) - } - if err := os.Unsetenv("TM_HOME"); err != nil { - panic(err) - } - - if err := os.RemoveAll(dir); err != nil { - panic(err) - } - viper.Reset() - config = cfg.DefaultConfig() -} - -// prepare new rootCmd -func testRootCmd() *cobra.Command { - rootCmd := &cobra.Command{ - Use: RootCmd.Use, - PersistentPreRunE: RootCmd.PersistentPreRunE, - Run: func(cmd *cobra.Command, args []string) {}, - } - registerFlagsRootCmd(rootCmd) - var l string - rootCmd.PersistentFlags().String("log", l, "Log") - return rootCmd -} - -func testSetup(rootDir string, args []string, env map[string]string) error { - clearConfig(defaultRoot) - - rootCmd := testRootCmd() - cmd := cli.PrepareBaseCmd(rootCmd, "TM", defaultRoot) - - // run with the args and env - args = append([]string{rootCmd.Use}, args...) - return cli.RunWithArgs(cmd, args, env) -} - -func TestRootHome(t *testing.T) { - newRoot := filepath.Join(defaultRoot, "something-else") - cases := []struct { - args []string - env map[string]string - root string - }{ - {nil, nil, defaultRoot}, - {[]string{"--home", newRoot}, nil, newRoot}, - {nil, map[string]string{"TMHOME": newRoot}, newRoot}, - } - - for i, tc := range cases { - idxString := strconv.Itoa(i) - - err := testSetup(defaultRoot, tc.args, tc.env) - require.Nil(t, err, idxString) - - assert.Equal(t, tc.root, config.RootDir, idxString) - assert.Equal(t, tc.root, config.P2P.RootDir, idxString) - assert.Equal(t, tc.root, config.Consensus.RootDir, idxString) - assert.Equal(t, tc.root, config.Mempool.RootDir, idxString) - } -} - -func TestRootFlagsEnv(t *testing.T) { - - // defaults - defaults := cfg.DefaultConfig() - defaultLogLvl := defaults.LogLevel - - cases := []struct { - args []string - env map[string]string - logLevel string - }{ - {[]string{"--log", "debug"}, nil, defaultLogLvl}, // wrong flag - {[]string{"--log_level", "debug"}, nil, "debug"}, // right flag - {nil, map[string]string{"TM_LOW": "debug"}, defaultLogLvl}, // wrong env flag - {nil, map[string]string{"MT_LOG_LEVEL": "debug"}, defaultLogLvl}, // wrong env prefix - {nil, map[string]string{"TM_LOG_LEVEL": "debug"}, "debug"}, // right env - } - - for i, tc := range cases { - idxString := strconv.Itoa(i) - - err := testSetup(defaultRoot, tc.args, tc.env) - require.Nil(t, err, idxString) - - assert.Equal(t, tc.logLevel, config.LogLevel, idxString) - } -} - -func TestRootConfig(t *testing.T) { - - // write non-default config - nonDefaultLogLvl := "abc:debug" - cvals := map[string]string{ - "log_level": nonDefaultLogLvl, - } - - cases := []struct { - args []string - env map[string]string - - logLvl string - }{ - {nil, nil, nonDefaultLogLvl}, // should load config - {[]string{"--log_level=abc:info"}, nil, "abc:info"}, // flag over rides - {nil, map[string]string{"TM_LOG_LEVEL": "abc:info"}, "abc:info"}, // env over rides - } - - for i, tc := range cases { - idxString := strconv.Itoa(i) - clearConfig(defaultRoot) - - // XXX: path must match cfg.defaultConfigPath - configFilePath := filepath.Join(defaultRoot, "config") - err := cmn.EnsureDir(configFilePath, 0700) - require.Nil(t, err) - - // write the non-defaults to a different path - // TODO: support writing sub configs so we can test that too - err = WriteConfigVals(configFilePath, cvals) - require.Nil(t, err) - - rootCmd := testRootCmd() - cmd := cli.PrepareBaseCmd(rootCmd, "TM", defaultRoot) - - // run with the args and env - tc.args = append([]string{rootCmd.Use}, tc.args...) - err = cli.RunWithArgs(cmd, tc.args, tc.env) - require.Nil(t, err, idxString) - - assert.Equal(t, tc.logLvl, config.LogLevel, idxString) - } -} - -// WriteConfigVals writes a toml file with the given values. -// It returns an error if writing was impossible. -func WriteConfigVals(dir string, vals map[string]string) error { - data := "" - for k, v := range vals { - data = data + fmt.Sprintf("%s = \"%s\"\n", k, v) - } - cfile := filepath.Join(dir, "config.toml") - return ioutil.WriteFile(cfile, []byte(data), 0666) -} diff --git a/cmd/tendermint/commands/run_node.go b/cmd/tendermint/commands/run_node.go deleted file mode 100644 index 0d50f9e4b..000000000 --- a/cmd/tendermint/commands/run_node.go +++ /dev/null @@ -1,72 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/spf13/cobra" - - nm "github.com/tendermint/tendermint/node" -) - -// AddNodeFlags exposes some common configuration options on the command-line -// These are exposed for convenience of commands embedding a tendermint node -func AddNodeFlags(cmd *cobra.Command) { - // bind flags - cmd.Flags().String("moniker", config.Moniker, "Node Name") - - // priv val flags - cmd.Flags().String("priv_validator_laddr", config.PrivValidatorListenAddr, "Socket address to listen on for connections from external priv_validator process") - - // node flags - cmd.Flags().Bool("fast_sync", config.FastSync, "Fast blockchain syncing") - - // abci flags - cmd.Flags().String("proxy_app", config.ProxyApp, "Proxy app address, or 'nilapp' or 'kvstore' for local testing.") - cmd.Flags().String("abci", config.ABCI, "Specify abci transport (socket | grpc)") - - // rpc flags - cmd.Flags().String("rpc.laddr", config.RPC.ListenAddress, "RPC listen address. Port required") - cmd.Flags().String("rpc.grpc_laddr", config.RPC.GRPCListenAddress, "GRPC listen address (BroadcastTx only). Port required") - cmd.Flags().Bool("rpc.unsafe", config.RPC.Unsafe, "Enabled unsafe rpc methods") - - // p2p flags - cmd.Flags().String("p2p.laddr", config.P2P.ListenAddress, "Node listen address. (0.0.0.0:0 means any interface, any port)") - cmd.Flags().String("p2p.seeds", config.P2P.Seeds, "Comma-delimited ID@host:port seed nodes") - cmd.Flags().String("p2p.persistent_peers", config.P2P.PersistentPeers, "Comma-delimited ID@host:port persistent peers") - cmd.Flags().Bool("p2p.skip_upnp", config.P2P.SkipUPNP, "Skip UPNP configuration") - cmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "Enable/disable Peer-Exchange") - cmd.Flags().Bool("p2p.seed_mode", config.P2P.SeedMode, "Enable/disable seed mode") - cmd.Flags().String("p2p.private_peer_ids", config.P2P.PrivatePeerIDs, "Comma-delimited private peer IDs") - - // consensus flags - cmd.Flags().Bool("consensus.create_empty_blocks", config.Consensus.CreateEmptyBlocks, "Set this to false to only produce blocks when there are txs or when the AppHash changes") -} - -// NewRunNodeCmd returns the command that allows the CLI to start a node. -// It can be used with a custom PrivValidator and in-process ABCI application. -func NewRunNodeCmd(nodeProvider nm.NodeProvider) *cobra.Command { - cmd := &cobra.Command{ - Use: "node", - Short: "Run the tendermint node", - RunE: func(cmd *cobra.Command, args []string) error { - // Create & start node - n, err := nodeProvider(config, logger) - if err != nil { - return fmt.Errorf("Failed to create node: %v", err) - } - - if err := n.Start(); err != nil { - return fmt.Errorf("Failed to start node: %v", err) - } - logger.Info("Started node", "nodeInfo", n.Switch().NodeInfo()) - - // Trap signal, run forever. - n.RunForever() - - return nil - }, - } - - AddNodeFlags(cmd) - return cmd -} diff --git a/cmd/tendermint/commands/show_node_id.go b/cmd/tendermint/commands/show_node_id.go deleted file mode 100644 index 02ab1a9bb..000000000 --- a/cmd/tendermint/commands/show_node_id.go +++ /dev/null @@ -1,27 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/spf13/cobra" - - "github.com/tendermint/tendermint/p2p" -) - -// ShowNodeIDCmd dumps node's ID to the standard output. -var ShowNodeIDCmd = &cobra.Command{ - Use: "show_node_id", - Short: "Show this node's ID", - RunE: showNodeID, -} - -func showNodeID(cmd *cobra.Command, args []string) error { - - nodeKey, err := p2p.LoadNodeKey(config.NodeKeyFile()) - if err != nil { - return err - } - fmt.Println(nodeKey.ID()) - - return nil -} diff --git a/cmd/tendermint/commands/show_validator.go b/cmd/tendermint/commands/show_validator.go deleted file mode 100644 index 54765164b..000000000 --- a/cmd/tendermint/commands/show_validator.go +++ /dev/null @@ -1,22 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/spf13/cobra" - - "github.com/tendermint/tendermint/privval" -) - -// ShowValidatorCmd adds capabilities for showing the validator info. -var ShowValidatorCmd = &cobra.Command{ - Use: "show_validator", - Short: "Show this node's validator info", - Run: showValidator, -} - -func showValidator(cmd *cobra.Command, args []string) { - privValidator := privval.LoadOrGenFilePV(config.PrivValidatorFile()) - pubKeyJSONBytes, _ := cdc.MarshalJSON(privValidator.GetPubKey()) - fmt.Println(string(pubKeyJSONBytes)) -} diff --git a/cmd/tendermint/commands/testnet.go b/cmd/tendermint/commands/testnet.go deleted file mode 100644 index 29d29502e..000000000 --- a/cmd/tendermint/commands/testnet.go +++ /dev/null @@ -1,183 +0,0 @@ -package commands - -import ( - "fmt" - "net" - "os" - "path/filepath" - "strings" - "time" - - "github.com/spf13/cobra" - - cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/p2p" - "github.com/tendermint/tendermint/privval" - "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tmlibs/common" -) - -var ( - nValidators int - nNonValidators int - outputDir string - nodeDirPrefix string - - populatePersistentPeers bool - hostnamePrefix string - startingIPAddress string - p2pPort int -) - -const ( - nodeDirPerm = 0755 -) - -func init() { - TestnetFilesCmd.Flags().IntVar(&nValidators, "v", 4, - "Number of validators to initialize the testnet with") - TestnetFilesCmd.Flags().IntVar(&nNonValidators, "n", 0, - "Number of non-validators to initialize the testnet with") - TestnetFilesCmd.Flags().StringVar(&outputDir, "o", "./mytestnet", - "Directory to store initialization data for the testnet") - TestnetFilesCmd.Flags().StringVar(&nodeDirPrefix, "node-dir-prefix", "node", - "Prefix the directory name for each node with (node results in node0, node1, ...)") - - TestnetFilesCmd.Flags().BoolVar(&populatePersistentPeers, "populate-persistent-peers", true, - "Update config of each node with the list of persistent peers build using either hostname-prefix or starting-ip-address") - TestnetFilesCmd.Flags().StringVar(&hostnamePrefix, "hostname-prefix", "node", - "Hostname prefix (node results in persistent peers list ID0@node0:26656, ID1@node1:26656, ...)") - TestnetFilesCmd.Flags().StringVar(&startingIPAddress, "starting-ip-address", "", - "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:26656, ID1@192.168.0.2:26656, ...)") - TestnetFilesCmd.Flags().IntVar(&p2pPort, "p2p-port", 26656, - "P2P Port") -} - -// TestnetFilesCmd allows initialisation of files for a Tendermint testnet. -var TestnetFilesCmd = &cobra.Command{ - Use: "testnet", - Short: "Initialize files for a Tendermint testnet", - Long: `testnet will create "v" + "n" number of directories and populate each with -necessary files (private validator, genesis, config, etc.). - -Note, strict routability for addresses is turned off in the config file. - -Optionally, it will fill in persistent_peers list in config file using either hostnames or IPs. - -Example: - - tendermint testnet --v 4 --o ./output --populate-persistent-peers --starting-ip-address 192.168.10.2 - `, - RunE: testnetFiles, -} - -func testnetFiles(cmd *cobra.Command, args []string) error { - config := cfg.DefaultConfig() - genVals := make([]types.GenesisValidator, nValidators) - - for i := 0; i < nValidators; i++ { - nodeDirName := cmn.Fmt("%s%d", nodeDirPrefix, i) - nodeDir := filepath.Join(outputDir, nodeDirName) - config.SetRoot(nodeDir) - - err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm) - if err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - initFilesWithConfig(config) - - pvFile := filepath.Join(nodeDir, config.BaseConfig.PrivValidator) - pv := privval.LoadFilePV(pvFile) - genVals[i] = types.GenesisValidator{ - PubKey: pv.GetPubKey(), - Power: 1, - Name: nodeDirName, - } - } - - for i := 0; i < nNonValidators; i++ { - nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i+nValidators)) - config.SetRoot(nodeDir) - - err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm) - if err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - initFilesWithConfig(config) - } - - // Generate genesis doc from generated validators - genDoc := &types.GenesisDoc{ - GenesisTime: time.Now(), - ChainID: "chain-" + cmn.RandStr(6), - Validators: genVals, - } - - // Write genesis file. - for i := 0; i < nValidators+nNonValidators; i++ { - nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i)) - if err := genDoc.SaveAs(filepath.Join(nodeDir, config.BaseConfig.Genesis)); err != nil { - _ = os.RemoveAll(outputDir) - return err - } - } - - if populatePersistentPeers { - err := populatePersistentPeersInConfigAndWriteIt(config) - if err != nil { - _ = os.RemoveAll(outputDir) - return err - } - } - - fmt.Printf("Successfully initialized %v node directories\n", nValidators+nNonValidators) - return nil -} - -func hostnameOrIP(i int) string { - if startingIPAddress != "" { - ip := net.ParseIP(startingIPAddress) - ip = ip.To4() - if ip == nil { - fmt.Printf("%v: non ipv4 address\n", startingIPAddress) - os.Exit(1) - } - - for j := 0; j < i; j++ { - ip[3]++ - } - return ip.String() - } - - return fmt.Sprintf("%s%d", hostnamePrefix, i) -} - -func populatePersistentPeersInConfigAndWriteIt(config *cfg.Config) error { - persistentPeers := make([]string, nValidators+nNonValidators) - for i := 0; i < nValidators+nNonValidators; i++ { - nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i)) - config.SetRoot(nodeDir) - nodeKey, err := p2p.LoadNodeKey(config.NodeKeyFile()) - if err != nil { - return err - } - persistentPeers[i] = p2p.IDAddressString(nodeKey.ID(), fmt.Sprintf("%s:%d", hostnameOrIP(i), p2pPort)) - } - persistentPeersList := strings.Join(persistentPeers, ",") - - for i := 0; i < nValidators+nNonValidators; i++ { - nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i)) - config.SetRoot(nodeDir) - config.P2P.PersistentPeers = persistentPeersList - config.P2P.AddrBookStrict = false - - // overwrite default config - cfg.WriteConfigFile(filepath.Join(nodeDir, "config", "config.toml"), config) - } - - return nil -} diff --git a/cmd/tendermint/commands/version.go b/cmd/tendermint/commands/version.go deleted file mode 100644 index f9f545e59..000000000 --- a/cmd/tendermint/commands/version.go +++ /dev/null @@ -1,18 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/spf13/cobra" - - "github.com/tendermint/tendermint/version" -) - -// VersionCmd ... -var VersionCmd = &cobra.Command{ - Use: "version", - Short: "Show version info", - Run: func(cmd *cobra.Command, args []string) { - fmt.Println(version.Version) - }, -} diff --git a/cmd/tendermint/commands/wire.go b/cmd/tendermint/commands/wire.go deleted file mode 100644 index 4c133a8c5..000000000 --- a/cmd/tendermint/commands/wire.go +++ /dev/null @@ -1,12 +0,0 @@ -package commands - -import ( - "github.com/tendermint/go-amino" - "github.com/tendermint/go-crypto" -) - -var cdc = amino.NewCodec() - -func init() { - crypto.RegisterAmino(cdc) -} diff --git a/cmd/tendermint/main.go b/cmd/tendermint/main.go deleted file mode 100644 index 8c7f0cd17..000000000 --- a/cmd/tendermint/main.go +++ /dev/null @@ -1,48 +0,0 @@ -package main - -import ( - "os" - "path/filepath" - - "github.com/tendermint/tmlibs/cli" - - cmd "github.com/tendermint/tendermint/cmd/tendermint/commands" - cfg "github.com/tendermint/tendermint/config" - nm "github.com/tendermint/tendermint/node" -) - -func main() { - rootCmd := cmd.RootCmd - rootCmd.AddCommand( - cmd.GenValidatorCmd, - cmd.InitFilesCmd, - cmd.ProbeUpnpCmd, - cmd.LiteCmd, - cmd.ReplayCmd, - cmd.ReplayConsoleCmd, - cmd.ResetAllCmd, - cmd.ResetPrivValidatorCmd, - cmd.ShowValidatorCmd, - cmd.TestnetFilesCmd, - cmd.ShowNodeIDCmd, - cmd.GenNodeKeyCmd, - cmd.VersionCmd) - - // NOTE: - // Users wishing to: - // * Use an external signer for their validators - // * Supply an in-proc abci app - // * Supply a genesis doc file from another source - // * Provide their own DB implementation - // can copy this file and use something other than the - // DefaultNewNode function - nodeFunc := nm.DefaultNewNode - - // Create & start node - rootCmd.AddCommand(cmd.NewRunNodeCmd(nodeFunc)) - - cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv(filepath.Join("$HOME", cfg.DefaultTendermintDir))) - if err := cmd.Execute(); err != nil { - panic(err) - } -} diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index b190853de..000000000 --- a/codecov.yml +++ /dev/null @@ -1,23 +0,0 @@ -coverage: - precision: 2 - round: down - range: "70...100" - - status: - project: - default: - threshold: 1% - patch: on - changes: off - -comment: - layout: "diff, files" - behavior: default - require_changes: no - require_base: no - require_head: yes - -ignore: - - "docs" - - "DOCKER" - - "scripts" diff --git a/config/config.go b/config/config.go deleted file mode 100644 index 6a283a82c..000000000 --- a/config/config.go +++ /dev/null @@ -1,632 +0,0 @@ -package config - -import ( - "fmt" - "os" - "path/filepath" - "time" -) - -const ( - // FuzzModeDrop is a mode in which we randomly drop reads/writes, connections or sleep - FuzzModeDrop = iota - // FuzzModeDelay is a mode in which we randomly sleep - FuzzModeDelay -) - -// NOTE: Most of the structs & relevant comments + the -// default configuration options were used to manually -// generate the config.toml. Please reflect any changes -// made here in the defaultConfigTemplate constant in -// config/toml.go -// NOTE: tmlibs/cli must know to look in the config dir! -var ( - DefaultTendermintDir = ".tendermint" - defaultConfigDir = "config" - defaultDataDir = "data" - - defaultConfigFileName = "config.toml" - defaultGenesisJSONName = "genesis.json" - - defaultPrivValName = "priv_validator.json" - defaultNodeKeyName = "node_key.json" - defaultAddrBookName = "addrbook.json" - - defaultConfigFilePath = filepath.Join(defaultConfigDir, defaultConfigFileName) - defaultGenesisJSONPath = filepath.Join(defaultConfigDir, defaultGenesisJSONName) - defaultPrivValPath = filepath.Join(defaultConfigDir, defaultPrivValName) - defaultNodeKeyPath = filepath.Join(defaultConfigDir, defaultNodeKeyName) - defaultAddrBookPath = filepath.Join(defaultConfigDir, defaultAddrBookName) -) - -// Config defines the top level configuration for a Tendermint node -type Config struct { - // Top level options use an anonymous struct - BaseConfig `mapstructure:",squash"` - - // Options for services - RPC *RPCConfig `mapstructure:"rpc"` - P2P *P2PConfig `mapstructure:"p2p"` - Mempool *MempoolConfig `mapstructure:"mempool"` - Consensus *ConsensusConfig `mapstructure:"consensus"` - TxIndex *TxIndexConfig `mapstructure:"tx_index"` - Instrumentation *InstrumentationConfig `mapstructure:"instrumentation"` -} - -// DefaultConfig returns a default configuration for a Tendermint node -func DefaultConfig() *Config { - return &Config{ - BaseConfig: DefaultBaseConfig(), - RPC: DefaultRPCConfig(), - P2P: DefaultP2PConfig(), - Mempool: DefaultMempoolConfig(), - Consensus: DefaultConsensusConfig(), - TxIndex: DefaultTxIndexConfig(), - Instrumentation: DefaultInstrumentationConfig(), - } -} - -// TestConfig returns a configuration that can be used for testing -func TestConfig() *Config { - return &Config{ - BaseConfig: TestBaseConfig(), - RPC: TestRPCConfig(), - P2P: TestP2PConfig(), - Mempool: TestMempoolConfig(), - Consensus: TestConsensusConfig(), - TxIndex: TestTxIndexConfig(), - Instrumentation: TestInstrumentationConfig(), - } -} - -// SetRoot sets the RootDir for all Config structs -func (cfg *Config) SetRoot(root string) *Config { - cfg.BaseConfig.RootDir = root - cfg.RPC.RootDir = root - cfg.P2P.RootDir = root - cfg.Mempool.RootDir = root - cfg.Consensus.RootDir = root - return cfg -} - -//----------------------------------------------------------------------------- -// BaseConfig - -// BaseConfig defines the base configuration for a Tendermint node -type BaseConfig struct { - - // chainID is unexposed and immutable but here for convenience - chainID string - - // The root directory for all data. - // This should be set in viper so it can unmarshal into this struct - RootDir string `mapstructure:"home"` - - // Path to the JSON file containing the initial validator set and other meta data - Genesis string `mapstructure:"genesis_file"` - - // Path to the JSON file containing the private key to use as a validator in the consensus protocol - PrivValidator string `mapstructure:"priv_validator_file"` - - // A JSON file containing the private key to use for p2p authenticated encryption - NodeKey string `mapstructure:"node_key_file"` - - // A custom human readable name for this node - Moniker string `mapstructure:"moniker"` - - // TCP or UNIX socket address for Tendermint to listen on for - // connections from an external PrivValidator process - PrivValidatorListenAddr string `mapstructure:"priv_validator_laddr"` - - // TCP or UNIX socket address of the ABCI application, - // or the name of an ABCI application compiled in with the Tendermint binary - ProxyApp string `mapstructure:"proxy_app"` - - // Mechanism to connect to the ABCI application: socket | grpc - ABCI string `mapstructure:"abci"` - - // Output level for logging - LogLevel string `mapstructure:"log_level"` - - // TCP or UNIX socket address for the profiling server to listen on - ProfListenAddress string `mapstructure:"prof_laddr"` - - // If this node is many blocks behind the tip of the chain, FastSync - // allows them to catchup quickly by downloading blocks in parallel - // and verifying their commits - FastSync bool `mapstructure:"fast_sync"` - - // If true, query the ABCI app on connecting to a new peer - // so the app can decide if we should keep the connection or not - FilterPeers bool `mapstructure:"filter_peers"` // false - - // Database backend: leveldb | memdb - DBBackend string `mapstructure:"db_backend"` - - // Database directory - DBPath string `mapstructure:"db_dir"` -} - -// DefaultBaseConfig returns a default base configuration for a Tendermint node -func DefaultBaseConfig() BaseConfig { - return BaseConfig{ - Genesis: defaultGenesisJSONPath, - PrivValidator: defaultPrivValPath, - NodeKey: defaultNodeKeyPath, - Moniker: defaultMoniker, - ProxyApp: "tcp://127.0.0.1:26658", - ABCI: "socket", - LogLevel: DefaultPackageLogLevels(), - ProfListenAddress: "", - FastSync: true, - FilterPeers: false, - DBBackend: "leveldb", - DBPath: "data", - } -} - -// TestBaseConfig returns a base configuration for testing a Tendermint node -func TestBaseConfig() BaseConfig { - cfg := DefaultBaseConfig() - cfg.chainID = "tendermint_test" - cfg.ProxyApp = "kvstore" - cfg.FastSync = false - cfg.DBBackend = "memdb" - return cfg -} - -func (cfg BaseConfig) ChainID() string { - return cfg.chainID -} - -// GenesisFile returns the full path to the genesis.json file -func (cfg BaseConfig) GenesisFile() string { - return rootify(cfg.Genesis, cfg.RootDir) -} - -// PrivValidatorFile returns the full path to the priv_validator.json file -func (cfg BaseConfig) PrivValidatorFile() string { - return rootify(cfg.PrivValidator, cfg.RootDir) -} - -// NodeKeyFile returns the full path to the node_key.json file -func (cfg BaseConfig) NodeKeyFile() string { - return rootify(cfg.NodeKey, cfg.RootDir) -} - -// DBDir returns the full path to the database directory -func (cfg BaseConfig) DBDir() string { - return rootify(cfg.DBPath, cfg.RootDir) -} - -// DefaultLogLevel returns a default log level of "error" -func DefaultLogLevel() string { - return "error" -} - -// DefaultPackageLogLevels returns a default log level setting so all packages -// log at "error", while the `state` and `main` packages log at "info" -func DefaultPackageLogLevels() string { - return fmt.Sprintf("main:info,state:info,*:%s", DefaultLogLevel()) -} - -//----------------------------------------------------------------------------- -// RPCConfig - -// RPCConfig defines the configuration options for the Tendermint RPC server -type RPCConfig struct { - RootDir string `mapstructure:"home"` - - // TCP or UNIX socket address for the RPC server to listen on - ListenAddress string `mapstructure:"laddr"` - - // TCP or UNIX socket address for the gRPC server to listen on - // NOTE: This server only supports /broadcast_tx_commit - GRPCListenAddress string `mapstructure:"grpc_laddr"` - - // Activate unsafe RPC commands like /dial_persistent_peers and /unsafe_flush_mempool - Unsafe bool `mapstructure:"unsafe"` -} - -// DefaultRPCConfig returns a default configuration for the RPC server -func DefaultRPCConfig() *RPCConfig { - return &RPCConfig{ - ListenAddress: "tcp://0.0.0.0:26657", - GRPCListenAddress: "", - Unsafe: false, - } -} - -// TestRPCConfig returns a configuration for testing the RPC server -func TestRPCConfig() *RPCConfig { - cfg := DefaultRPCConfig() - cfg.ListenAddress = "tcp://0.0.0.0:36657" - cfg.GRPCListenAddress = "tcp://0.0.0.0:36658" - cfg.Unsafe = true - return cfg -} - -//----------------------------------------------------------------------------- -// P2PConfig - -// P2PConfig defines the configuration options for the Tendermint peer-to-peer networking layer -type P2PConfig struct { - RootDir string `mapstructure:"home"` - - // Address to listen for incoming connections - ListenAddress string `mapstructure:"laddr"` - - // Comma separated list of seed nodes to connect to - // We only use these if we can’t connect to peers in the addrbook - Seeds string `mapstructure:"seeds"` - - // Comma separated list of nodes to keep persistent connections to - // Do not add private peers to this list if you don't want them advertised - PersistentPeers string `mapstructure:"persistent_peers"` - - // Skip UPNP port forwarding - SkipUPNP bool `mapstructure:"skip_upnp"` - - // Path to address book - AddrBook string `mapstructure:"addr_book_file"` - - // Set true for strict address routability rules - AddrBookStrict bool `mapstructure:"addr_book_strict"` - - // Maximum number of peers to connect to - MaxNumPeers int `mapstructure:"max_num_peers"` - - // Time to wait before flushing messages out on the connection, in ms - FlushThrottleTimeout int `mapstructure:"flush_throttle_timeout"` - - // Maximum size of a message packet payload, in bytes - MaxPacketMsgPayloadSize int `mapstructure:"max_packet_msg_payload_size"` - - // Rate at which packets can be sent, in bytes/second - SendRate int64 `mapstructure:"send_rate"` - - // Rate at which packets can be received, in bytes/second - RecvRate int64 `mapstructure:"recv_rate"` - - // Set true to enable the peer-exchange reactor - PexReactor bool `mapstructure:"pex"` - - // Seed mode, in which node constantly crawls the network and looks for - // peers. If another node asks it for addresses, it responds and disconnects. - // - // Does not work if the peer-exchange reactor is disabled. - SeedMode bool `mapstructure:"seed_mode"` - - // Comma separated list of peer IDs to keep private (will not be gossiped to - // other peers) - PrivatePeerIDs string `mapstructure:"private_peer_ids"` - - // Toggle to disable guard against peers connecting from the same ip. - AllowDuplicateIP bool `mapstructure:"allow_duplicate_ip"` - - // Peer connection configuration. - HandshakeTimeout time.Duration `mapstructure:"handshake_timeout"` - DialTimeout time.Duration `mapstructure:"dial_timeout"` - - // Testing params. - // Force dial to fail - TestDialFail bool `mapstructure:"test_dial_fail"` - // FUzz connection - TestFuzz bool `mapstructure:"test_fuzz"` - TestFuzzConfig *FuzzConnConfig `mapstructure:"test_fuzz_config"` -} - -// DefaultP2PConfig returns a default configuration for the peer-to-peer layer -func DefaultP2PConfig() *P2PConfig { - return &P2PConfig{ - ListenAddress: "tcp://0.0.0.0:26656", - AddrBook: defaultAddrBookPath, - AddrBookStrict: true, - MaxNumPeers: 50, - FlushThrottleTimeout: 100, - MaxPacketMsgPayloadSize: 1024, // 1 kB - SendRate: 512000, // 500 kB/s - RecvRate: 512000, // 500 kB/s - PexReactor: true, - SeedMode: false, - AllowDuplicateIP: true, // so non-breaking yet - HandshakeTimeout: 20 * time.Second, - DialTimeout: 3 * time.Second, - TestDialFail: false, - TestFuzz: false, - TestFuzzConfig: DefaultFuzzConnConfig(), - } -} - -// TestP2PConfig returns a configuration for testing the peer-to-peer layer -func TestP2PConfig() *P2PConfig { - cfg := DefaultP2PConfig() - cfg.ListenAddress = "tcp://0.0.0.0:36656" - cfg.SkipUPNP = true - cfg.FlushThrottleTimeout = 10 - cfg.AllowDuplicateIP = true - return cfg -} - -// AddrBookFile returns the full path to the address book -func (cfg *P2PConfig) AddrBookFile() string { - return rootify(cfg.AddrBook, cfg.RootDir) -} - -// FuzzConnConfig is a FuzzedConnection configuration. -type FuzzConnConfig struct { - Mode int - MaxDelay time.Duration - ProbDropRW float64 - ProbDropConn float64 - ProbSleep float64 -} - -// DefaultFuzzConnConfig returns the default config. -func DefaultFuzzConnConfig() *FuzzConnConfig { - return &FuzzConnConfig{ - Mode: FuzzModeDrop, - MaxDelay: 3 * time.Second, - ProbDropRW: 0.2, - ProbDropConn: 0.00, - ProbSleep: 0.00, - } -} - -//----------------------------------------------------------------------------- -// MempoolConfig - -// MempoolConfig defines the configuration options for the Tendermint mempool -type MempoolConfig struct { - RootDir string `mapstructure:"home"` - Recheck bool `mapstructure:"recheck"` - RecheckEmpty bool `mapstructure:"recheck_empty"` - Broadcast bool `mapstructure:"broadcast"` - WalPath string `mapstructure:"wal_dir"` - Size int `mapstructure:"size"` - CacheSize int `mapstructure:"cache_size"` -} - -// DefaultMempoolConfig returns a default configuration for the Tendermint mempool -func DefaultMempoolConfig() *MempoolConfig { - return &MempoolConfig{ - Recheck: true, - RecheckEmpty: true, - Broadcast: true, - WalPath: filepath.Join(defaultDataDir, "mempool.wal"), - Size: 100000, - CacheSize: 100000, - } -} - -// TestMempoolConfig returns a configuration for testing the Tendermint mempool -func TestMempoolConfig() *MempoolConfig { - cfg := DefaultMempoolConfig() - cfg.CacheSize = 1000 - return cfg -} - -// WalDir returns the full path to the mempool's write-ahead log -func (cfg *MempoolConfig) WalDir() string { - return rootify(cfg.WalPath, cfg.RootDir) -} - -//----------------------------------------------------------------------------- -// ConsensusConfig - -// ConsensusConfig defines the configuration for the Tendermint consensus service, -// including timeouts and details about the WAL and the block structure. -type ConsensusConfig struct { - RootDir string `mapstructure:"home"` - WalPath string `mapstructure:"wal_file"` - walFile string // overrides WalPath if set - - // All timeouts are in milliseconds - TimeoutPropose int `mapstructure:"timeout_propose"` - TimeoutProposeDelta int `mapstructure:"timeout_propose_delta"` - TimeoutPrevote int `mapstructure:"timeout_prevote"` - TimeoutPrevoteDelta int `mapstructure:"timeout_prevote_delta"` - TimeoutPrecommit int `mapstructure:"timeout_precommit"` - TimeoutPrecommitDelta int `mapstructure:"timeout_precommit_delta"` - TimeoutCommit int `mapstructure:"timeout_commit"` - - // Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) - SkipTimeoutCommit bool `mapstructure:"skip_timeout_commit"` - - // BlockSize - MaxBlockSizeTxs int `mapstructure:"max_block_size_txs"` - MaxBlockSizeBytes int `mapstructure:"max_block_size_bytes"` - - // EmptyBlocks mode and possible interval between empty blocks in seconds - CreateEmptyBlocks bool `mapstructure:"create_empty_blocks"` - CreateEmptyBlocksInterval int `mapstructure:"create_empty_blocks_interval"` - - // Reactor sleep duration parameters are in milliseconds - PeerGossipSleepDuration int `mapstructure:"peer_gossip_sleep_duration"` - PeerQueryMaj23SleepDuration int `mapstructure:"peer_query_maj23_sleep_duration"` -} - -// DefaultConsensusConfig returns a default configuration for the consensus service -func DefaultConsensusConfig() *ConsensusConfig { - return &ConsensusConfig{ - WalPath: filepath.Join(defaultDataDir, "cs.wal", "wal"), - TimeoutPropose: 3000, - TimeoutProposeDelta: 500, - TimeoutPrevote: 1000, - TimeoutPrevoteDelta: 500, - TimeoutPrecommit: 1000, - TimeoutPrecommitDelta: 500, - TimeoutCommit: 1000, - SkipTimeoutCommit: false, - MaxBlockSizeTxs: 10000, - MaxBlockSizeBytes: 1, // TODO - CreateEmptyBlocks: true, - CreateEmptyBlocksInterval: 0, - PeerGossipSleepDuration: 100, - PeerQueryMaj23SleepDuration: 2000, - } -} - -// TestConsensusConfig returns a configuration for testing the consensus service -func TestConsensusConfig() *ConsensusConfig { - cfg := DefaultConsensusConfig() - cfg.TimeoutPropose = 100 - cfg.TimeoutProposeDelta = 1 - cfg.TimeoutPrevote = 10 - cfg.TimeoutPrevoteDelta = 1 - cfg.TimeoutPrecommit = 10 - cfg.TimeoutPrecommitDelta = 1 - cfg.TimeoutCommit = 10 - cfg.SkipTimeoutCommit = true - cfg.PeerGossipSleepDuration = 5 - cfg.PeerQueryMaj23SleepDuration = 250 - return cfg -} - -// WaitForTxs returns true if the consensus should wait for transactions before entering the propose step -func (cfg *ConsensusConfig) WaitForTxs() bool { - return !cfg.CreateEmptyBlocks || cfg.CreateEmptyBlocksInterval > 0 -} - -// EmptyBlocks returns the amount of time to wait before proposing an empty block or starting the propose timer if there are no txs available -func (cfg *ConsensusConfig) EmptyBlocksInterval() time.Duration { - return time.Duration(cfg.CreateEmptyBlocksInterval) * time.Second -} - -// Propose returns the amount of time to wait for a proposal -func (cfg *ConsensusConfig) Propose(round int) time.Duration { - return time.Duration(cfg.TimeoutPropose+cfg.TimeoutProposeDelta*round) * time.Millisecond -} - -// Prevote returns the amount of time to wait for straggler votes after receiving any +2/3 prevotes -func (cfg *ConsensusConfig) Prevote(round int) time.Duration { - return time.Duration(cfg.TimeoutPrevote+cfg.TimeoutPrevoteDelta*round) * time.Millisecond -} - -// Precommit returns the amount of time to wait for straggler votes after receiving any +2/3 precommits -func (cfg *ConsensusConfig) Precommit(round int) time.Duration { - return time.Duration(cfg.TimeoutPrecommit+cfg.TimeoutPrecommitDelta*round) * time.Millisecond -} - -// Commit returns the amount of time to wait for straggler votes after receiving +2/3 precommits for a single block (ie. a commit). -func (cfg *ConsensusConfig) Commit(t time.Time) time.Time { - return t.Add(time.Duration(cfg.TimeoutCommit) * time.Millisecond) -} - -// PeerGossipSleep returns the amount of time to sleep if there is nothing to send from the ConsensusReactor -func (cfg *ConsensusConfig) PeerGossipSleep() time.Duration { - return time.Duration(cfg.PeerGossipSleepDuration) * time.Millisecond -} - -// PeerQueryMaj23Sleep returns the amount of time to sleep after each VoteSetMaj23Message is sent in the ConsensusReactor -func (cfg *ConsensusConfig) PeerQueryMaj23Sleep() time.Duration { - return time.Duration(cfg.PeerQueryMaj23SleepDuration) * time.Millisecond -} - -// WalFile returns the full path to the write-ahead log file -func (cfg *ConsensusConfig) WalFile() string { - if cfg.walFile != "" { - return cfg.walFile - } - return rootify(cfg.WalPath, cfg.RootDir) -} - -// SetWalFile sets the path to the write-ahead log file -func (cfg *ConsensusConfig) SetWalFile(walFile string) { - cfg.walFile = walFile -} - -//----------------------------------------------------------------------------- -// TxIndexConfig - -// TxIndexConfig defines the configuration for the transaction -// indexer, including tags to index. -type TxIndexConfig struct { - // What indexer to use for transactions - // - // Options: - // 1) "null" - // 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). - Indexer string `mapstructure:"indexer"` - - // Comma-separated list of tags to index (by default the only tag is tx hash) - // - // It's recommended to index only a subset of tags due to possible memory - // bloat. This is, of course, depends on the indexer's DB and the volume of - // transactions. - IndexTags string `mapstructure:"index_tags"` - - // When set to true, tells indexer to index all tags. Note this may be not - // desirable (see the comment above). IndexTags has a precedence over - // IndexAllTags (i.e. when given both, IndexTags will be indexed). - IndexAllTags bool `mapstructure:"index_all_tags"` -} - -// DefaultTxIndexConfig returns a default configuration for the transaction indexer. -func DefaultTxIndexConfig() *TxIndexConfig { - return &TxIndexConfig{ - Indexer: "kv", - IndexTags: "", - IndexAllTags: false, - } -} - -// TestTxIndexConfig returns a default configuration for the transaction indexer. -func TestTxIndexConfig() *TxIndexConfig { - return DefaultTxIndexConfig() -} - -//----------------------------------------------------------------------------- -// InstrumentationConfig - -// InstrumentationConfig defines the configuration for metrics reporting. -type InstrumentationConfig struct { - // When true, Prometheus metrics are served under /metrics on - // PrometheusListenAddr. - // Check out the documentation for the list of available metrics. - Prometheus bool `mapstructure:"prometheus"` - - // Address to listen for Prometheus collector(s) connections. - PrometheusListenAddr string `mapstructure:"prometheus_listen_addr"` -} - -// DefaultInstrumentationConfig returns a default configuration for metrics -// reporting. -func DefaultInstrumentationConfig() *InstrumentationConfig { - return &InstrumentationConfig{ - Prometheus: false, - PrometheusListenAddr: ":26660", - } -} - -// TestInstrumentationConfig returns a default configuration for metrics -// reporting. -func TestInstrumentationConfig() *InstrumentationConfig { - return DefaultInstrumentationConfig() -} - -//----------------------------------------------------------------------------- -// Utils - -// helper function to make config creation independent of root dir -func rootify(path, root string) string { - if filepath.IsAbs(path) { - return path - } - return filepath.Join(root, path) -} - -//----------------------------------------------------------------------------- -// Moniker - -var defaultMoniker = getDefaultMoniker() - -// getDefaultMoniker returns a default moniker, which is the host name. If runtime -// fails to get the host name, "anonymous" will be returned. -func getDefaultMoniker() string { - moniker, err := os.Hostname() - if err != nil { - moniker = "anonymous" - } - return moniker -} diff --git a/config/config_test.go b/config/config_test.go deleted file mode 100644 index 6379960fa..000000000 --- a/config/config_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package config - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestDefaultConfig(t *testing.T) { - assert := assert.New(t) - - // set up some defaults - cfg := DefaultConfig() - assert.NotNil(cfg.P2P) - assert.NotNil(cfg.Mempool) - assert.NotNil(cfg.Consensus) - - // check the root dir stuff... - cfg.SetRoot("/foo") - cfg.Genesis = "bar" - cfg.DBPath = "/opt/data" - cfg.Mempool.WalPath = "wal/mem/" - - assert.Equal("/foo/bar", cfg.GenesisFile()) - assert.Equal("/opt/data", cfg.DBDir()) - assert.Equal("/foo/wal/mem", cfg.Mempool.WalDir()) - -} diff --git a/config/toml.go b/config/toml.go deleted file mode 100644 index c3d41a9b7..000000000 --- a/config/toml.go +++ /dev/null @@ -1,324 +0,0 @@ -package config - -import ( - "bytes" - "os" - "path/filepath" - "text/template" - - cmn "github.com/tendermint/tmlibs/common" -) - -var configTemplate *template.Template - -func init() { - var err error - if configTemplate, err = template.New("configFileTemplate").Parse(defaultConfigTemplate); err != nil { - panic(err) - } -} - -/****** these are for production settings ***********/ - -// EnsureRoot creates the root, config, and data directories if they don't exist, -// and panics if it fails. -func EnsureRoot(rootDir string) { - if err := cmn.EnsureDir(rootDir, 0700); err != nil { - cmn.PanicSanity(err.Error()) - } - if err := cmn.EnsureDir(filepath.Join(rootDir, defaultConfigDir), 0700); err != nil { - cmn.PanicSanity(err.Error()) - } - if err := cmn.EnsureDir(filepath.Join(rootDir, defaultDataDir), 0700); err != nil { - cmn.PanicSanity(err.Error()) - } - - configFilePath := filepath.Join(rootDir, defaultConfigFilePath) - - // Write default config file if missing. - if !cmn.FileExists(configFilePath) { - writeDefaultConfigFile(configFilePath) - } -} - -// XXX: this func should probably be called by cmd/tendermint/commands/init.go -// alongside the writing of the genesis.json and priv_validator.json -func writeDefaultConfigFile(configFilePath string) { - WriteConfigFile(configFilePath, DefaultConfig()) -} - -// WriteConfigFile renders config using the template and writes it to configFilePath. -func WriteConfigFile(configFilePath string, config *Config) { - var buffer bytes.Buffer - - if err := configTemplate.Execute(&buffer, config); err != nil { - panic(err) - } - - cmn.MustWriteFile(configFilePath, buffer.Bytes(), 0644) -} - -// Note: any changes to the comments/variables/mapstructure -// must be reflected in the appropriate struct in config/config.go -const defaultConfigTemplate = `# This is a TOML config file. -# For more information, see https://github.com/toml-lang/toml - -##### main base config options ##### - -# TCP or UNIX socket address of the ABCI application, -# or the name of an ABCI application compiled in with the Tendermint binary -proxy_app = "{{ .BaseConfig.ProxyApp }}" - -# A custom human readable name for this node -moniker = "{{ .BaseConfig.Moniker }}" - -# If this node is many blocks behind the tip of the chain, FastSync -# allows them to catchup quickly by downloading blocks in parallel -# and verifying their commits -fast_sync = {{ .BaseConfig.FastSync }} - -# Database backend: leveldb | memdb -db_backend = "{{ .BaseConfig.DBBackend }}" - -# Database directory -db_path = "{{ js .BaseConfig.DBPath }}" - -# Output level for logging, including package level options -log_level = "{{ .BaseConfig.LogLevel }}" - -##### additional base config options ##### - -# Path to the JSON file containing the initial validator set and other meta data -genesis_file = "{{ js .BaseConfig.Genesis }}" - -# Path to the JSON file containing the private key to use as a validator in the consensus protocol -priv_validator_file = "{{ js .BaseConfig.PrivValidator }}" - -# Path to the JSON file containing the private key to use for node authentication in the p2p protocol -node_key_file = "{{ js .BaseConfig.NodeKey}}" - -# Mechanism to connect to the ABCI application: socket | grpc -abci = "{{ .BaseConfig.ABCI }}" - -# TCP or UNIX socket address for the profiling server to listen on -prof_laddr = "{{ .BaseConfig.ProfListenAddress }}" - -# If true, query the ABCI app on connecting to a new peer -# so the app can decide if we should keep the connection or not -filter_peers = {{ .BaseConfig.FilterPeers }} - -##### advanced configuration options ##### - -##### rpc server configuration options ##### -[rpc] - -# TCP or UNIX socket address for the RPC server to listen on -laddr = "{{ .RPC.ListenAddress }}" - -# TCP or UNIX socket address for the gRPC server to listen on -# NOTE: This server only supports /broadcast_tx_commit -grpc_laddr = "{{ .RPC.GRPCListenAddress }}" - -# Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool -unsafe = {{ .RPC.Unsafe }} - -##### peer to peer configuration options ##### -[p2p] - -# Address to listen for incoming connections -laddr = "{{ .P2P.ListenAddress }}" - -# Comma separated list of seed nodes to connect to -seeds = "{{ .P2P.Seeds }}" - -# Comma separated list of nodes to keep persistent connections to -# Do not add private peers to this list if you don't want them advertised -persistent_peers = "{{ .P2P.PersistentPeers }}" - -# Path to address book -addr_book_file = "{{ js .P2P.AddrBook }}" - -# Set true for strict address routability rules -addr_book_strict = {{ .P2P.AddrBookStrict }} - -# Time to wait before flushing messages out on the connection, in ms -flush_throttle_timeout = {{ .P2P.FlushThrottleTimeout }} - -# Maximum number of peers to connect to -max_num_peers = {{ .P2P.MaxNumPeers }} - -# Maximum size of a message packet payload, in bytes -max_packet_msg_payload_size = {{ .P2P.MaxPacketMsgPayloadSize }} - -# Rate at which packets can be sent, in bytes/second -send_rate = {{ .P2P.SendRate }} - -# Rate at which packets can be received, in bytes/second -recv_rate = {{ .P2P.RecvRate }} - -# Set true to enable the peer-exchange reactor -pex = {{ .P2P.PexReactor }} - -# Seed mode, in which node constantly crawls the network and looks for -# peers. If another node asks it for addresses, it responds and disconnects. -# -# Does not work if the peer-exchange reactor is disabled. -seed_mode = {{ .P2P.SeedMode }} - -# Comma separated list of peer IDs to keep private (will not be gossiped to other peers) -private_peer_ids = "{{ .P2P.PrivatePeerIDs }}" - -##### mempool configuration options ##### -[mempool] - -recheck = {{ .Mempool.Recheck }} -recheck_empty = {{ .Mempool.RecheckEmpty }} -broadcast = {{ .Mempool.Broadcast }} -wal_dir = "{{ js .Mempool.WalPath }}" - -# size of the mempool -size = {{ .Mempool.Size }} - -# size of the cache (used to filter transactions we saw earlier) -cache_size = {{ .Mempool.CacheSize }} - -##### consensus configuration options ##### -[consensus] - -wal_file = "{{ js .Consensus.WalPath }}" - -# All timeouts are in milliseconds -timeout_propose = {{ .Consensus.TimeoutPropose }} -timeout_propose_delta = {{ .Consensus.TimeoutProposeDelta }} -timeout_prevote = {{ .Consensus.TimeoutPrevote }} -timeout_prevote_delta = {{ .Consensus.TimeoutPrevoteDelta }} -timeout_precommit = {{ .Consensus.TimeoutPrecommit }} -timeout_precommit_delta = {{ .Consensus.TimeoutPrecommitDelta }} -timeout_commit = {{ .Consensus.TimeoutCommit }} - -# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) -skip_timeout_commit = {{ .Consensus.SkipTimeoutCommit }} - -# BlockSize -max_block_size_txs = {{ .Consensus.MaxBlockSizeTxs }} -max_block_size_bytes = {{ .Consensus.MaxBlockSizeBytes }} - -# EmptyBlocks mode and possible interval between empty blocks in seconds -create_empty_blocks = {{ .Consensus.CreateEmptyBlocks }} -create_empty_blocks_interval = {{ .Consensus.CreateEmptyBlocksInterval }} - -# Reactor sleep duration parameters are in milliseconds -peer_gossip_sleep_duration = {{ .Consensus.PeerGossipSleepDuration }} -peer_query_maj23_sleep_duration = {{ .Consensus.PeerQueryMaj23SleepDuration }} - -##### transactions indexer configuration options ##### -[tx_index] - -# What indexer to use for transactions -# -# Options: -# 1) "null" (default) -# 2) "kv" - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). -indexer = "{{ .TxIndex.Indexer }}" - -# Comma-separated list of tags to index (by default the only tag is tx hash) -# -# It's recommended to index only a subset of tags due to possible memory -# bloat. This is, of course, depends on the indexer's DB and the volume of -# transactions. -index_tags = "{{ .TxIndex.IndexTags }}" - -# When set to true, tells indexer to index all tags. Note this may be not -# desirable (see the comment above). IndexTags has a precedence over -# IndexAllTags (i.e. when given both, IndexTags will be indexed). -index_all_tags = {{ .TxIndex.IndexAllTags }} - -##### instrumentation configuration options ##### -[instrumentation] - -# When true, Prometheus metrics are served under /metrics on -# PrometheusListenAddr. -# Check out the documentation for the list of available metrics. -prometheus = {{ .Instrumentation.Prometheus }} - -# Address to listen for Prometheus collector(s) connections -prometheus_listen_addr = "{{ .Instrumentation.PrometheusListenAddr }}" -` - -/****** these are for test settings ***********/ - -func ResetTestRoot(testName string) *Config { - rootDir := os.ExpandEnv("$HOME/.tendermint_test") - rootDir = filepath.Join(rootDir, testName) - // Remove ~/.tendermint_test_bak - if cmn.FileExists(rootDir + "_bak") { - if err := os.RemoveAll(rootDir + "_bak"); err != nil { - cmn.PanicSanity(err.Error()) - } - } - // Move ~/.tendermint_test to ~/.tendermint_test_bak - if cmn.FileExists(rootDir) { - if err := os.Rename(rootDir, rootDir+"_bak"); err != nil { - cmn.PanicSanity(err.Error()) - } - } - // Create new dir - if err := cmn.EnsureDir(rootDir, 0700); err != nil { - cmn.PanicSanity(err.Error()) - } - if err := cmn.EnsureDir(filepath.Join(rootDir, defaultConfigDir), 0700); err != nil { - cmn.PanicSanity(err.Error()) - } - if err := cmn.EnsureDir(filepath.Join(rootDir, defaultDataDir), 0700); err != nil { - cmn.PanicSanity(err.Error()) - } - - baseConfig := DefaultBaseConfig() - configFilePath := filepath.Join(rootDir, defaultConfigFilePath) - genesisFilePath := filepath.Join(rootDir, baseConfig.Genesis) - privFilePath := filepath.Join(rootDir, baseConfig.PrivValidator) - - // Write default config file if missing. - if !cmn.FileExists(configFilePath) { - writeDefaultConfigFile(configFilePath) - } - if !cmn.FileExists(genesisFilePath) { - cmn.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644) - } - // we always overwrite the priv val - cmn.MustWriteFile(privFilePath, []byte(testPrivValidator), 0644) - - config := TestConfig().SetRoot(rootDir) - return config -} - -var testGenesis = `{ - "genesis_time": "0001-01-01T00:00:00.000Z", - "chain_id": "tendermint_test", - "validators": [ - { - "pub_key": { - "type": "AC26791624DE60", - "value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE=" - }, - "power": 10, - "name": "" - } - ], - "app_hash": "" -}` - -var testPrivValidator = `{ - "address": "849CB2C877F87A20925F35D00AE6688342D25B47", - "pub_key": { - "type": "AC26791624DE60", - "value": "AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE=" - }, - "priv_key": { - "type": "954568A3288910", - "value": "EVkqJO/jIXp3rkASXfh9YnyToYXRXhBr6g9cQVxPFnQBP/5povV4HTjvsy530kybxKHwEi85iU8YL0qQhSYVoQ==" - }, - "last_height": 0, - "last_round": 0, - "last_step": 0 -}` diff --git a/config/toml_test.go b/config/toml_test.go deleted file mode 100644 index a1637f671..000000000 --- a/config/toml_test.go +++ /dev/null @@ -1,94 +0,0 @@ -package config - -import ( - "io/ioutil" - "os" - "path/filepath" - "strings" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func ensureFiles(t *testing.T, rootDir string, files ...string) { - for _, f := range files { - p := rootify(rootDir, f) - _, err := os.Stat(p) - assert.Nil(t, err, p) - } -} - -func TestEnsureRoot(t *testing.T) { - require := require.New(t) - - // setup temp dir for test - tmpDir, err := ioutil.TempDir("", "config-test") - require.Nil(err) - defer os.RemoveAll(tmpDir) // nolint: errcheck - - // create root dir - EnsureRoot(tmpDir) - - // make sure config is set properly - data, err := ioutil.ReadFile(filepath.Join(tmpDir, defaultConfigFilePath)) - require.Nil(err) - - if !checkConfig(string(data)) { - t.Fatalf("config file missing some information") - } - - ensureFiles(t, tmpDir, "data") -} - -func TestEnsureTestRoot(t *testing.T) { - require := require.New(t) - - testName := "ensureTestRoot" - - // create root dir - cfg := ResetTestRoot(testName) - rootDir := cfg.RootDir - - // make sure config is set properly - data, err := ioutil.ReadFile(filepath.Join(rootDir, defaultConfigFilePath)) - require.Nil(err) - - if !checkConfig(string(data)) { - t.Fatalf("config file missing some information") - } - - // TODO: make sure the cfg returned and testconfig are the same! - baseConfig := DefaultBaseConfig() - ensureFiles(t, rootDir, defaultDataDir, baseConfig.Genesis, baseConfig.PrivValidator) -} - -func checkConfig(configFile string) bool { - var valid bool - - // list of words we expect in the config - var elems = []string{ - "moniker", - "seeds", - "proxy_app", - "fast_sync", - "create_empty_blocks", - "peer", - "timeout", - "broadcast", - "send", - "addr", - "wal", - "propose", - "max", - "genesis", - } - for _, e := range elems { - if !strings.Contains(configFile, e) { - valid = false - } else { - valid = true - } - } - return valid -} diff --git a/consensus/README.md b/consensus/README.md deleted file mode 100644 index 1111317d5..000000000 --- a/consensus/README.md +++ /dev/null @@ -1 +0,0 @@ -See the [consensus spec](https://github.com/tendermint/tendermint/tree/master/docs/spec/consensus) and the [reactor consensus spec](https://github.com/tendermint/tendermint/tree/master/docs/spec/reactors/consensus) for more information. diff --git a/consensus/byzantine_test.go b/consensus/byzantine_test.go deleted file mode 100644 index d3be8c358..000000000 --- a/consensus/byzantine_test.go +++ /dev/null @@ -1,267 +0,0 @@ -package consensus - -import ( - "context" - "sync" - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/p2p" - "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tmlibs/common" -) - -func init() { - config = ResetConfig("consensus_byzantine_test") -} - -//---------------------------------------------- -// byzantine failures - -// 4 validators. 1 is byzantine. The other three are partitioned into A (1 val) and B (2 vals). -// byzantine validator sends conflicting proposals into A and B, -// and prevotes/precommits on both of them. -// B sees a commit, A doesn't. -// Byzantine validator refuses to prevote. -// Heal partition and ensure A sees the commit -func TestByzantine(t *testing.T) { - N := 4 - logger := consensusLogger().With("test", "byzantine") - css := randConsensusNet(N, "consensus_byzantine_test", newMockTickerFunc(false), newCounter) - - // give the byzantine validator a normal ticker - ticker := NewTimeoutTicker() - ticker.SetLogger(css[0].Logger) - css[0].SetTimeoutTicker(ticker) - - switches := make([]*p2p.Switch, N) - p2pLogger := logger.With("module", "p2p") - for i := 0; i < N; i++ { - switches[i] = p2p.NewSwitch(config.P2P) - switches[i].SetLogger(p2pLogger.With("validator", i)) - } - - eventChans := make([]chan interface{}, N) - reactors := make([]p2p.Reactor, N) - for i := 0; i < N; i++ { - // make first val byzantine - if i == 0 { - // NOTE: Now, test validators are MockPV, which by default doesn't - // do any safety checks. - css[i].privValidator.(*types.MockPV).DisableChecks() - css[i].decideProposal = func(j int) func(int64, int) { - return func(height int64, round int) { - byzantineDecideProposalFunc(t, height, round, css[j], switches[j]) - } - }(i) - css[i].doPrevote = func(height int64, round int) {} - } - - eventBus := css[i].eventBus - eventBus.SetLogger(logger.With("module", "events", "validator", i)) - - eventChans[i] = make(chan interface{}, 1) - err := eventBus.Subscribe(context.Background(), testSubscriber, types.EventQueryNewBlock, eventChans[i]) - require.NoError(t, err) - - conR := NewConsensusReactor(css[i], true) // so we dont start the consensus states - conR.SetLogger(logger.With("validator", i)) - conR.SetEventBus(eventBus) - - var conRI p2p.Reactor // nolint: gotype, gosimple - conRI = conR - - // make first val byzantine - if i == 0 { - conRI = NewByzantineReactor(conR) - } - - reactors[i] = conRI - } - - defer func() { - for _, r := range reactors { - if rr, ok := r.(*ByzantineReactor); ok { - rr.reactor.Switch.Stop() - } else { - r.(*ConsensusReactor).Switch.Stop() - } - } - }() - - p2p.MakeConnectedSwitches(config.P2P, N, func(i int, s *p2p.Switch) *p2p.Switch { - // ignore new switch s, we already made ours - switches[i].AddReactor("CONSENSUS", reactors[i]) - return switches[i] - }, func(sws []*p2p.Switch, i, j int) { - // the network starts partitioned with globally active adversary - if i != 0 { - return - } - p2p.Connect2Switches(sws, i, j) - }) - - // start the non-byz state machines. - // note these must be started before the byz - for i := 1; i < N; i++ { - cr := reactors[i].(*ConsensusReactor) - cr.SwitchToConsensus(cr.conS.GetState(), 0) - } - - // start the byzantine state machine - byzR := reactors[0].(*ByzantineReactor) - s := byzR.reactor.conS.GetState() - byzR.reactor.SwitchToConsensus(s, 0) - - // byz proposer sends one block to peers[0] - // and the other block to peers[1] and peers[2]. - // note peers and switches order don't match. - peers := switches[0].Peers().List() - - // partition A - ind0 := getSwitchIndex(switches, peers[0]) - - // partition B - ind1 := getSwitchIndex(switches, peers[1]) - ind2 := getSwitchIndex(switches, peers[2]) - p2p.Connect2Switches(switches, ind1, ind2) - - // wait for someone in the big partition (B) to make a block - <-eventChans[ind2] - - t.Log("A block has been committed. Healing partition") - p2p.Connect2Switches(switches, ind0, ind1) - p2p.Connect2Switches(switches, ind0, ind2) - - // wait till everyone makes the first new block - // (one of them already has) - wg := new(sync.WaitGroup) - wg.Add(2) - for i := 1; i < N-1; i++ { - go func(j int) { - <-eventChans[j] - wg.Done() - }(i) - } - - done := make(chan struct{}) - go func() { - wg.Wait() - close(done) - }() - - tick := time.NewTicker(time.Second * 10) - select { - case <-done: - case <-tick.C: - for i, reactor := range reactors { - t.Log(cmn.Fmt("Consensus Reactor %v", i)) - t.Log(cmn.Fmt("%v", reactor)) - } - t.Fatalf("Timed out waiting for all validators to commit first block") - } -} - -//------------------------------- -// byzantine consensus functions - -func byzantineDecideProposalFunc(t *testing.T, height int64, round int, cs *ConsensusState, sw *p2p.Switch) { - // byzantine user should create two proposals and try to split the vote. - // Avoid sending on internalMsgQueue and running consensus state. - - // Create a new proposal block from state/txs from the mempool. - block1, blockParts1 := cs.createProposalBlock() - polRound, polBlockID := cs.Votes.POLInfo() - proposal1 := types.NewProposal(height, round, blockParts1.Header(), polRound, polBlockID) - if err := cs.privValidator.SignProposal(cs.state.ChainID, proposal1); err != nil { - t.Error(err) - } - - // Create a new proposal block from state/txs from the mempool. - block2, blockParts2 := cs.createProposalBlock() - polRound, polBlockID = cs.Votes.POLInfo() - proposal2 := types.NewProposal(height, round, blockParts2.Header(), polRound, polBlockID) - if err := cs.privValidator.SignProposal(cs.state.ChainID, proposal2); err != nil { - t.Error(err) - } - - block1Hash := block1.Hash() - block2Hash := block2.Hash() - - // broadcast conflicting proposals/block parts to peers - peers := sw.Peers().List() - t.Logf("Byzantine: broadcasting conflicting proposals to %d peers", len(peers)) - for i, peer := range peers { - if i < len(peers)/2 { - go sendProposalAndParts(height, round, cs, peer, proposal1, block1Hash, blockParts1) - } else { - go sendProposalAndParts(height, round, cs, peer, proposal2, block2Hash, blockParts2) - } - } -} - -func sendProposalAndParts(height int64, round int, cs *ConsensusState, peer p2p.Peer, proposal *types.Proposal, blockHash []byte, parts *types.PartSet) { - // proposal - msg := &ProposalMessage{Proposal: proposal} - peer.Send(DataChannel, cdc.MustMarshalBinaryBare(msg)) - - // parts - for i := 0; i < parts.Total(); i++ { - part := parts.GetPart(i) - msg := &BlockPartMessage{ - Height: height, // This tells peer that this part applies to us. - Round: round, // This tells peer that this part applies to us. - Part: part, - } - peer.Send(DataChannel, cdc.MustMarshalBinaryBare(msg)) - } - - // votes - cs.mtx.Lock() - prevote, _ := cs.signVote(types.VoteTypePrevote, blockHash, parts.Header()) - precommit, _ := cs.signVote(types.VoteTypePrecommit, blockHash, parts.Header()) - cs.mtx.Unlock() - - peer.Send(VoteChannel, cdc.MustMarshalBinaryBare(&VoteMessage{prevote})) - peer.Send(VoteChannel, cdc.MustMarshalBinaryBare(&VoteMessage{precommit})) -} - -//---------------------------------------- -// byzantine consensus reactor - -type ByzantineReactor struct { - cmn.Service - reactor *ConsensusReactor -} - -func NewByzantineReactor(conR *ConsensusReactor) *ByzantineReactor { - return &ByzantineReactor{ - Service: conR, - reactor: conR, - } -} - -func (br *ByzantineReactor) SetSwitch(s *p2p.Switch) { br.reactor.SetSwitch(s) } -func (br *ByzantineReactor) GetChannels() []*p2p.ChannelDescriptor { return br.reactor.GetChannels() } -func (br *ByzantineReactor) AddPeer(peer p2p.Peer) { - if !br.reactor.IsRunning() { - return - } - - // Create peerState for peer - peerState := NewPeerState(peer).SetLogger(br.reactor.Logger) - peer.Set(types.PeerStateKey, peerState) - - // Send our state to peer. - // If we're fast_syncing, broadcast a RoundStepMessage later upon SwitchToConsensus(). - if !br.reactor.fastSync { - br.reactor.sendNewRoundStepMessages(peer) - } -} -func (br *ByzantineReactor) RemovePeer(peer p2p.Peer, reason interface{}) { - br.reactor.RemovePeer(peer, reason) -} -func (br *ByzantineReactor) Receive(chID byte, peer p2p.Peer, msgBytes []byte) { - br.reactor.Receive(chID, peer, msgBytes) -} diff --git a/consensus/common_test.go b/consensus/common_test.go deleted file mode 100644 index f50e57699..000000000 --- a/consensus/common_test.go +++ /dev/null @@ -1,495 +0,0 @@ -package consensus - -import ( - "bytes" - "context" - "fmt" - "io/ioutil" - "os" - "path" - "sort" - "sync" - "testing" - "time" - - abcicli "github.com/tendermint/abci/client" - abci "github.com/tendermint/abci/types" - bc "github.com/tendermint/tendermint/blockchain" - cfg "github.com/tendermint/tendermint/config" - cstypes "github.com/tendermint/tendermint/consensus/types" - mempl "github.com/tendermint/tendermint/mempool" - "github.com/tendermint/tendermint/p2p" - "github.com/tendermint/tendermint/privval" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tmlibs/common" - dbm "github.com/tendermint/tmlibs/db" - "github.com/tendermint/tmlibs/log" - - "github.com/tendermint/abci/example/counter" - "github.com/tendermint/abci/example/kvstore" - - "github.com/go-kit/kit/log/term" -) - -const ( - testSubscriber = "test-client" -) - -// genesis, chain_id, priv_val -var config *cfg.Config // NOTE: must be reset for each _test.go file -var ensureTimeout = time.Second * 1 // must be in seconds because CreateEmptyBlocksInterval is - -func ensureDir(dir string, mode os.FileMode) { - if err := cmn.EnsureDir(dir, mode); err != nil { - panic(err) - } -} - -func ResetConfig(name string) *cfg.Config { - return cfg.ResetTestRoot(name) -} - -//------------------------------------------------------------------------------- -// validator stub (a kvstore consensus peer we control) - -type validatorStub struct { - Index int // Validator index. NOTE: we don't assume validator set changes. - Height int64 - Round int - types.PrivValidator -} - -var testMinPower int64 = 10 - -func NewValidatorStub(privValidator types.PrivValidator, valIndex int) *validatorStub { - return &validatorStub{ - Index: valIndex, - PrivValidator: privValidator, - } -} - -func (vs *validatorStub) signVote(voteType byte, hash []byte, header types.PartSetHeader) (*types.Vote, error) { - vote := &types.Vote{ - ValidatorIndex: vs.Index, - ValidatorAddress: vs.PrivValidator.GetAddress(), - Height: vs.Height, - Round: vs.Round, - Timestamp: time.Now().UTC(), - Type: voteType, - BlockID: types.BlockID{hash, header}, - } - err := vs.PrivValidator.SignVote(config.ChainID(), vote) - return vote, err -} - -// Sign vote for type/hash/header -func signVote(vs *validatorStub, voteType byte, hash []byte, header types.PartSetHeader) *types.Vote { - v, err := vs.signVote(voteType, hash, header) - if err != nil { - panic(fmt.Errorf("failed to sign vote: %v", err)) - } - return v -} - -func signVotes(voteType byte, hash []byte, header types.PartSetHeader, vss ...*validatorStub) []*types.Vote { - votes := make([]*types.Vote, len(vss)) - for i, vs := range vss { - votes[i] = signVote(vs, voteType, hash, header) - } - return votes -} - -func incrementHeight(vss ...*validatorStub) { - for _, vs := range vss { - vs.Height++ - } -} - -func incrementRound(vss ...*validatorStub) { - for _, vs := range vss { - vs.Round++ - } -} - -//------------------------------------------------------------------------------- -// Functions for transitioning the consensus state - -func startTestRound(cs *ConsensusState, height int64, round int) { - cs.enterNewRound(height, round) - cs.startRoutines(0) -} - -// Create proposal block from cs1 but sign it with vs -func decideProposal(cs1 *ConsensusState, vs *validatorStub, height int64, round int) (proposal *types.Proposal, block *types.Block) { - block, blockParts := cs1.createProposalBlock() - if block == nil { // on error - panic("error creating proposal block") - } - - // Make proposal - polRound, polBlockID := cs1.Votes.POLInfo() - proposal = types.NewProposal(height, round, blockParts.Header(), polRound, polBlockID) - if err := vs.SignProposal(cs1.state.ChainID, proposal); err != nil { - panic(err) - } - return -} - -func addVotes(to *ConsensusState, votes ...*types.Vote) { - for _, vote := range votes { - to.peerMsgQueue <- msgInfo{Msg: &VoteMessage{vote}} - } -} - -func signAddVotes(to *ConsensusState, voteType byte, hash []byte, header types.PartSetHeader, vss ...*validatorStub) { - votes := signVotes(voteType, hash, header, vss...) - addVotes(to, votes...) -} - -func validatePrevote(t *testing.T, cs *ConsensusState, round int, privVal *validatorStub, blockHash []byte) { - prevotes := cs.Votes.Prevotes(round) - var vote *types.Vote - if vote = prevotes.GetByAddress(privVal.GetAddress()); vote == nil { - panic("Failed to find prevote from validator") - } - if blockHash == nil { - if vote.BlockID.Hash != nil { - panic(fmt.Sprintf("Expected prevote to be for nil, got %X", vote.BlockID.Hash)) - } - } else { - if !bytes.Equal(vote.BlockID.Hash, blockHash) { - panic(fmt.Sprintf("Expected prevote to be for %X, got %X", blockHash, vote.BlockID.Hash)) - } - } -} - -func validateLastPrecommit(t *testing.T, cs *ConsensusState, privVal *validatorStub, blockHash []byte) { - votes := cs.LastCommit - var vote *types.Vote - if vote = votes.GetByAddress(privVal.GetAddress()); vote == nil { - panic("Failed to find precommit from validator") - } - if !bytes.Equal(vote.BlockID.Hash, blockHash) { - panic(fmt.Sprintf("Expected precommit to be for %X, got %X", blockHash, vote.BlockID.Hash)) - } -} - -func validatePrecommit(t *testing.T, cs *ConsensusState, thisRound, lockRound int, privVal *validatorStub, votedBlockHash, lockedBlockHash []byte) { - precommits := cs.Votes.Precommits(thisRound) - var vote *types.Vote - if vote = precommits.GetByAddress(privVal.GetAddress()); vote == nil { - panic("Failed to find precommit from validator") - } - - if votedBlockHash == nil { - if vote.BlockID.Hash != nil { - panic("Expected precommit to be for nil") - } - } else { - if !bytes.Equal(vote.BlockID.Hash, votedBlockHash) { - panic("Expected precommit to be for proposal block") - } - } - - if lockedBlockHash == nil { - if cs.LockedRound != lockRound || cs.LockedBlock != nil { - panic(fmt.Sprintf("Expected to be locked on nil at round %d. Got locked at round %d with block %v", lockRound, cs.LockedRound, cs.LockedBlock)) - } - } else { - if cs.LockedRound != lockRound || !bytes.Equal(cs.LockedBlock.Hash(), lockedBlockHash) { - panic(fmt.Sprintf("Expected block to be locked on round %d, got %d. Got locked block %X, expected %X", lockRound, cs.LockedRound, cs.LockedBlock.Hash(), lockedBlockHash)) - } - } - -} - -func validatePrevoteAndPrecommit(t *testing.T, cs *ConsensusState, thisRound, lockRound int, privVal *validatorStub, votedBlockHash, lockedBlockHash []byte) { - // verify the prevote - validatePrevote(t, cs, thisRound, privVal, votedBlockHash) - // verify precommit - cs.mtx.Lock() - validatePrecommit(t, cs, thisRound, lockRound, privVal, votedBlockHash, lockedBlockHash) - cs.mtx.Unlock() -} - -// genesis -func subscribeToVoter(cs *ConsensusState, addr []byte) chan interface{} { - voteCh0 := make(chan interface{}) - err := cs.eventBus.Subscribe(context.Background(), testSubscriber, types.EventQueryVote, voteCh0) - if err != nil { - panic(fmt.Sprintf("failed to subscribe %s to %v", testSubscriber, types.EventQueryVote)) - } - voteCh := make(chan interface{}) - go func() { - for v := range voteCh0 { - vote := v.(types.EventDataVote) - // we only fire for our own votes - if bytes.Equal(addr, vote.Vote.ValidatorAddress) { - voteCh <- v - } - } - }() - return voteCh -} - -//------------------------------------------------------------------------------- -// consensus states - -func newConsensusState(state sm.State, pv types.PrivValidator, app abci.Application) *ConsensusState { - return newConsensusStateWithConfig(config, state, pv, app) -} - -func newConsensusStateWithConfig(thisConfig *cfg.Config, state sm.State, pv types.PrivValidator, app abci.Application) *ConsensusState { - blockDB := dbm.NewMemDB() - return newConsensusStateWithConfigAndBlockStore(thisConfig, state, pv, app, blockDB) -} - -func newConsensusStateWithConfigAndBlockStore(thisConfig *cfg.Config, state sm.State, pv types.PrivValidator, app abci.Application, blockDB dbm.DB) *ConsensusState { - // Get BlockStore - blockStore := bc.NewBlockStore(blockDB) - - // one for mempool, one for consensus - mtx := new(sync.Mutex) - proxyAppConnMem := abcicli.NewLocalClient(mtx, app) - proxyAppConnCon := abcicli.NewLocalClient(mtx, app) - - // Make Mempool - mempool := mempl.NewMempool(thisConfig.Mempool, proxyAppConnMem, 0) - mempool.SetLogger(log.TestingLogger().With("module", "mempool")) - if thisConfig.Consensus.WaitForTxs() { - mempool.EnableTxsAvailable() - } - - // mock the evidence pool - evpool := sm.MockEvidencePool{} - - // Make ConsensusState - stateDB := dbm.NewMemDB() - blockExec := sm.NewBlockExecutor(stateDB, log.TestingLogger(), proxyAppConnCon, mempool, evpool) - cs := NewConsensusState(thisConfig.Consensus, state, blockExec, blockStore, mempool, evpool) - cs.SetLogger(log.TestingLogger().With("module", "consensus")) - cs.SetPrivValidator(pv) - - eventBus := types.NewEventBus() - eventBus.SetLogger(log.TestingLogger().With("module", "events")) - eventBus.Start() - cs.SetEventBus(eventBus) - return cs -} - -func loadPrivValidator(config *cfg.Config) *privval.FilePV { - privValidatorFile := config.PrivValidatorFile() - ensureDir(path.Dir(privValidatorFile), 0700) - privValidator := privval.LoadOrGenFilePV(privValidatorFile) - privValidator.Reset() - return privValidator -} - -func randConsensusState(nValidators int) (*ConsensusState, []*validatorStub) { - // Get State - state, privVals := randGenesisState(nValidators, false, 10) - - vss := make([]*validatorStub, nValidators) - - cs := newConsensusState(state, privVals[0], counter.NewCounterApplication(true)) - - for i := 0; i < nValidators; i++ { - vss[i] = NewValidatorStub(privVals[i], i) - } - // since cs1 starts at 1 - incrementHeight(vss[1:]...) - - return cs, vss -} - -//------------------------------------------------------------------------------- - -func ensureNoNewStep(stepCh <-chan interface{}) { - timer := time.NewTimer(ensureTimeout) - select { - case <-timer.C: - break - case <-stepCh: - panic("We should be stuck waiting, not moving to the next step") - } -} - -func ensureNewStep(stepCh <-chan interface{}) { - timer := time.NewTimer(ensureTimeout) - select { - case <-timer.C: - panic("We shouldnt be stuck waiting") - case <-stepCh: - break - } -} - -//------------------------------------------------------------------------------- -// consensus nets - -// consensusLogger is a TestingLogger which uses a different -// color for each validator ("validator" key must exist). -func consensusLogger() log.Logger { - return log.TestingLoggerWithColorFn(func(keyvals ...interface{}) term.FgBgColor { - for i := 0; i < len(keyvals)-1; i += 2 { - if keyvals[i] == "validator" { - return term.FgBgColor{Fg: term.Color(uint8(keyvals[i+1].(int) + 1))} - } - } - return term.FgBgColor{} - }).With("module", "consensus") -} - -func randConsensusNet(nValidators int, testName string, tickerFunc func() TimeoutTicker, appFunc func() abci.Application, configOpts ...func(*cfg.Config)) []*ConsensusState { - genDoc, privVals := randGenesisDoc(nValidators, false, 30) - css := make([]*ConsensusState, nValidators) - logger := consensusLogger() - for i := 0; i < nValidators; i++ { - stateDB := dbm.NewMemDB() // each state needs its own db - state, _ := sm.LoadStateFromDBOrGenesisDoc(stateDB, genDoc) - thisConfig := ResetConfig(cmn.Fmt("%s_%d", testName, i)) - for _, opt := range configOpts { - opt(thisConfig) - } - ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal - app := appFunc() - vals := types.TM2PB.Validators(state.Validators) - app.InitChain(abci.RequestInitChain{Validators: vals}) - - css[i] = newConsensusStateWithConfig(thisConfig, state, privVals[i], app) - css[i].SetTimeoutTicker(tickerFunc()) - css[i].SetLogger(logger.With("validator", i, "module", "consensus")) - } - return css -} - -// nPeers = nValidators + nNotValidator -func randConsensusNetWithPeers(nValidators, nPeers int, testName string, tickerFunc func() TimeoutTicker, appFunc func() abci.Application) []*ConsensusState { - genDoc, privVals := randGenesisDoc(nValidators, false, testMinPower) - css := make([]*ConsensusState, nPeers) - logger := consensusLogger() - for i := 0; i < nPeers; i++ { - stateDB := dbm.NewMemDB() // each state needs its own db - state, _ := sm.LoadStateFromDBOrGenesisDoc(stateDB, genDoc) - thisConfig := ResetConfig(cmn.Fmt("%s_%d", testName, i)) - ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal - var privVal types.PrivValidator - if i < nValidators { - privVal = privVals[i] - } else { - _, tempFilePath := cmn.Tempfile("priv_validator_") - privVal = privval.GenFilePV(tempFilePath) - } - - app := appFunc() - vals := types.TM2PB.Validators(state.Validators) - app.InitChain(abci.RequestInitChain{Validators: vals}) - - css[i] = newConsensusStateWithConfig(thisConfig, state, privVal, app) - css[i].SetTimeoutTicker(tickerFunc()) - css[i].SetLogger(logger.With("validator", i, "module", "consensus")) - } - return css -} - -func getSwitchIndex(switches []*p2p.Switch, peer p2p.Peer) int { - for i, s := range switches { - if peer.NodeInfo().ID == s.NodeInfo().ID { - return i - } - } - panic("didnt find peer in switches") - return -1 -} - -//------------------------------------------------------------------------------- -// genesis - -func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.GenesisDoc, []types.PrivValidator) { - validators := make([]types.GenesisValidator, numValidators) - privValidators := make([]types.PrivValidator, numValidators) - for i := 0; i < numValidators; i++ { - val, privVal := types.RandValidator(randPower, minPower) - validators[i] = types.GenesisValidator{ - PubKey: val.PubKey, - Power: val.VotingPower, - } - privValidators[i] = privVal - } - sort.Sort(types.PrivValidatorsByAddress(privValidators)) - - return &types.GenesisDoc{ - GenesisTime: time.Now(), - ChainID: config.ChainID(), - Validators: validators, - }, privValidators -} - -func randGenesisState(numValidators int, randPower bool, minPower int64) (sm.State, []types.PrivValidator) { - genDoc, privValidators := randGenesisDoc(numValidators, randPower, minPower) - s0, _ := sm.MakeGenesisState(genDoc) - db := dbm.NewMemDB() - sm.SaveState(db, s0) - return s0, privValidators -} - -//------------------------------------ -// mock ticker - -func newMockTickerFunc(onlyOnce bool) func() TimeoutTicker { - return func() TimeoutTicker { - return &mockTicker{ - c: make(chan timeoutInfo, 10), - onlyOnce: onlyOnce, - } - } -} - -// mock ticker only fires on RoundStepNewHeight -// and only once if onlyOnce=true -type mockTicker struct { - c chan timeoutInfo - - mtx sync.Mutex - onlyOnce bool - fired bool -} - -func (m *mockTicker) Start() error { - return nil -} - -func (m *mockTicker) Stop() error { - return nil -} - -func (m *mockTicker) ScheduleTimeout(ti timeoutInfo) { - m.mtx.Lock() - defer m.mtx.Unlock() - if m.onlyOnce && m.fired { - return - } - if ti.Step == cstypes.RoundStepNewHeight { - m.c <- ti - m.fired = true - } -} - -func (m *mockTicker) Chan() <-chan timeoutInfo { - return m.c -} - -func (mockTicker) SetLogger(log.Logger) { -} - -//------------------------------------ - -func newCounter() abci.Application { - return counter.NewCounterApplication(true) -} - -func newPersistentKVStore() abci.Application { - dir, _ := ioutil.TempDir("/tmp", "persistent-kvstore") - return kvstore.NewPersistentKVStoreApplication(dir) -} diff --git a/consensus/mempool_test.go b/consensus/mempool_test.go deleted file mode 100644 index 3c8180060..000000000 --- a/consensus/mempool_test.go +++ /dev/null @@ -1,232 +0,0 @@ -package consensus - -import ( - "encoding/binary" - "fmt" - "testing" - "time" - - "github.com/stretchr/testify/assert" - - "github.com/tendermint/abci/example/code" - abci "github.com/tendermint/abci/types" - cmn "github.com/tendermint/tmlibs/common" - - "github.com/tendermint/tendermint/types" -) - -func init() { - config = ResetConfig("consensus_mempool_test") -} - -func TestMempoolNoProgressUntilTxsAvailable(t *testing.T) { - config := ResetConfig("consensus_mempool_txs_available_test") - config.Consensus.CreateEmptyBlocks = false - state, privVals := randGenesisState(1, false, 10) - cs := newConsensusStateWithConfig(config, state, privVals[0], NewCounterApplication()) - cs.mempool.EnableTxsAvailable() - height, round := cs.Height, cs.Round - newBlockCh := subscribe(cs.eventBus, types.EventQueryNewBlock) - startTestRound(cs, height, round) - - ensureNewStep(newBlockCh) // first block gets committed - ensureNoNewStep(newBlockCh) - deliverTxsRange(cs, 0, 1) - ensureNewStep(newBlockCh) // commit txs - ensureNewStep(newBlockCh) // commit updated app hash - ensureNoNewStep(newBlockCh) -} - -func TestMempoolProgressAfterCreateEmptyBlocksInterval(t *testing.T) { - config := ResetConfig("consensus_mempool_txs_available_test") - config.Consensus.CreateEmptyBlocksInterval = int(ensureTimeout.Seconds()) - state, privVals := randGenesisState(1, false, 10) - cs := newConsensusStateWithConfig(config, state, privVals[0], NewCounterApplication()) - cs.mempool.EnableTxsAvailable() - height, round := cs.Height, cs.Round - newBlockCh := subscribe(cs.eventBus, types.EventQueryNewBlock) - startTestRound(cs, height, round) - - ensureNewStep(newBlockCh) // first block gets committed - ensureNoNewStep(newBlockCh) // then we dont make a block ... - ensureNewStep(newBlockCh) // until the CreateEmptyBlocksInterval has passed -} - -func TestMempoolProgressInHigherRound(t *testing.T) { - config := ResetConfig("consensus_mempool_txs_available_test") - config.Consensus.CreateEmptyBlocks = false - state, privVals := randGenesisState(1, false, 10) - cs := newConsensusStateWithConfig(config, state, privVals[0], NewCounterApplication()) - cs.mempool.EnableTxsAvailable() - height, round := cs.Height, cs.Round - newBlockCh := subscribe(cs.eventBus, types.EventQueryNewBlock) - newRoundCh := subscribe(cs.eventBus, types.EventQueryNewRound) - timeoutCh := subscribe(cs.eventBus, types.EventQueryTimeoutPropose) - cs.setProposal = func(proposal *types.Proposal) error { - if cs.Height == 2 && cs.Round == 0 { - // dont set the proposal in round 0 so we timeout and - // go to next round - cs.Logger.Info("Ignoring set proposal at height 2, round 0") - return nil - } - return cs.defaultSetProposal(proposal) - } - startTestRound(cs, height, round) - - ensureNewStep(newRoundCh) // first round at first height - ensureNewStep(newBlockCh) // first block gets committed - ensureNewStep(newRoundCh) // first round at next height - deliverTxsRange(cs, 0, 1) // we deliver txs, but dont set a proposal so we get the next round - <-timeoutCh - ensureNewStep(newRoundCh) // wait for the next round - ensureNewStep(newBlockCh) // now we can commit the block -} - -func deliverTxsRange(cs *ConsensusState, start, end int) { - // Deliver some txs. - for i := start; i < end; i++ { - txBytes := make([]byte, 8) - binary.BigEndian.PutUint64(txBytes, uint64(i)) - err := cs.mempool.CheckTx(txBytes, nil) - if err != nil { - panic(cmn.Fmt("Error after CheckTx: %v", err)) - } - } -} - -func TestMempoolTxConcurrentWithCommit(t *testing.T) { - state, privVals := randGenesisState(1, false, 10) - cs := newConsensusState(state, privVals[0], NewCounterApplication()) - height, round := cs.Height, cs.Round - newBlockCh := subscribe(cs.eventBus, types.EventQueryNewBlock) - - NTxs := 10000 - go deliverTxsRange(cs, 0, NTxs) - - startTestRound(cs, height, round) - for nTxs := 0; nTxs < NTxs; { - ticker := time.NewTicker(time.Second * 30) - select { - case b := <-newBlockCh: - evt := b.(types.EventDataNewBlock) - nTxs += int(evt.Block.Header.NumTxs) - case <-ticker.C: - panic("Timed out waiting to commit blocks with transactions") - } - } -} - -func TestMempoolRmBadTx(t *testing.T) { - state, privVals := randGenesisState(1, false, 10) - app := NewCounterApplication() - cs := newConsensusState(state, privVals[0], app) - - // increment the counter by 1 - txBytes := make([]byte, 8) - binary.BigEndian.PutUint64(txBytes, uint64(0)) - - resDeliver := app.DeliverTx(txBytes) - assert.False(t, resDeliver.IsErr(), cmn.Fmt("expected no error. got %v", resDeliver)) - - resCommit := app.Commit() - assert.True(t, len(resCommit.Data) > 0) - - emptyMempoolCh := make(chan struct{}) - checkTxRespCh := make(chan struct{}) - go func() { - // Try to send the tx through the mempool. - // CheckTx should not err, but the app should return a bad abci code - // and the tx should get removed from the pool - err := cs.mempool.CheckTx(txBytes, func(r *abci.Response) { - if r.GetCheckTx().Code != code.CodeTypeBadNonce { - t.Fatalf("expected checktx to return bad nonce, got %v", r) - } - checkTxRespCh <- struct{}{} - }) - if err != nil { - t.Fatalf("Error after CheckTx: %v", err) - } - - // check for the tx - for { - txs := cs.mempool.Reap(1) - if len(txs) == 0 { - emptyMempoolCh <- struct{}{} - return - } - time.Sleep(10 * time.Millisecond) - } - }() - - // Wait until the tx returns - ticker := time.After(time.Second * 5) - select { - case <-checkTxRespCh: - // success - case <-ticker: - t.Fatalf("Timed out waiting for tx to return") - } - - // Wait until the tx is removed - ticker = time.After(time.Second * 5) - select { - case <-emptyMempoolCh: - // success - case <-ticker: - t.Fatalf("Timed out waiting for tx to be removed") - } -} - -// CounterApplication that maintains a mempool state and resets it upon commit -type CounterApplication struct { - abci.BaseApplication - - txCount int - mempoolTxCount int -} - -func NewCounterApplication() *CounterApplication { - return &CounterApplication{} -} - -func (app *CounterApplication) Info(req abci.RequestInfo) abci.ResponseInfo { - return abci.ResponseInfo{Data: cmn.Fmt("txs:%v", app.txCount)} -} - -func (app *CounterApplication) DeliverTx(tx []byte) abci.ResponseDeliverTx { - txValue := txAsUint64(tx) - if txValue != uint64(app.txCount) { - return abci.ResponseDeliverTx{ - Code: code.CodeTypeBadNonce, - Log: fmt.Sprintf("Invalid nonce. Expected %v, got %v", app.txCount, txValue)} - } - app.txCount++ - return abci.ResponseDeliverTx{Code: code.CodeTypeOK} -} - -func (app *CounterApplication) CheckTx(tx []byte) abci.ResponseCheckTx { - txValue := txAsUint64(tx) - if txValue != uint64(app.mempoolTxCount) { - return abci.ResponseCheckTx{ - Code: code.CodeTypeBadNonce, - Log: fmt.Sprintf("Invalid nonce. Expected %v, got %v", app.mempoolTxCount, txValue)} - } - app.mempoolTxCount++ - return abci.ResponseCheckTx{Code: code.CodeTypeOK} -} - -func txAsUint64(tx []byte) uint64 { - tx8 := make([]byte, 8) - copy(tx8[len(tx8)-len(tx):], tx) - return binary.BigEndian.Uint64(tx8) -} - -func (app *CounterApplication) Commit() abci.ResponseCommit { - app.mempoolTxCount = app.txCount - if app.txCount == 0 { - return abci.ResponseCommit{} - } - hash := make([]byte, 8) - binary.BigEndian.PutUint64(hash, uint64(app.txCount)) - return abci.ResponseCommit{Data: hash} -} diff --git a/consensus/metrics.go b/consensus/metrics.go deleted file mode 100644 index 253880e84..000000000 --- a/consensus/metrics.go +++ /dev/null @@ -1,133 +0,0 @@ -package consensus - -import ( - "github.com/go-kit/kit/metrics" - "github.com/go-kit/kit/metrics/discard" - - prometheus "github.com/go-kit/kit/metrics/prometheus" - stdprometheus "github.com/prometheus/client_golang/prometheus" -) - -// Metrics contains metrics exposed by this package. -type Metrics struct { - // Height of the chain. - Height metrics.Gauge - - // Number of rounds. - Rounds metrics.Gauge - - // Number of validators. - Validators metrics.Gauge - // Total power of all validators. - ValidatorsPower metrics.Gauge - // Number of validators who did not sign. - MissingValidators metrics.Gauge - // Total power of the missing validators. - MissingValidatorsPower metrics.Gauge - // Number of validators who tried to double sign. - ByzantineValidators metrics.Gauge - // Total power of the byzantine validators. - ByzantineValidatorsPower metrics.Gauge - - // Time between this and the last block. - BlockIntervalSeconds metrics.Histogram - - // Number of transactions. - NumTxs metrics.Gauge - // Size of the block. - BlockSizeBytes metrics.Gauge - // Total number of transactions. - TotalTxs metrics.Gauge -} - -// PrometheusMetrics returns Metrics build using Prometheus client library. -func PrometheusMetrics() *Metrics { - return &Metrics{ - Height: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Subsystem: "consensus", - Name: "height", - Help: "Height of the chain.", - }, []string{}), - Rounds: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Subsystem: "consensus", - Name: "rounds", - Help: "Number of rounds.", - }, []string{}), - - Validators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Subsystem: "consensus", - Name: "validators", - Help: "Number of validators.", - }, []string{}), - ValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Subsystem: "consensus", - Name: "validators_power", - Help: "Total power of all validators.", - }, []string{}), - MissingValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Subsystem: "consensus", - Name: "missing_validators", - Help: "Number of validators who did not sign.", - }, []string{}), - MissingValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Subsystem: "consensus", - Name: "missing_validators_power", - Help: "Total power of the missing validators.", - }, []string{}), - ByzantineValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Subsystem: "consensus", - Name: "byzantine_validators", - Help: "Number of validators who tried to double sign.", - }, []string{}), - ByzantineValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Subsystem: "consensus", - Name: "byzantine_validators_power", - Help: "Total power of the byzantine validators.", - }, []string{}), - - BlockIntervalSeconds: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ - Subsystem: "consensus", - Name: "block_interval_seconds", - Help: "Time between this and the last block.", - Buckets: []float64{1, 2.5, 5, 10, 60}, - }, []string{}), - - NumTxs: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Subsystem: "consensus", - Name: "num_txs", - Help: "Number of transactions.", - }, []string{}), - BlockSizeBytes: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Subsystem: "consensus", - Name: "block_size_bytes", - Help: "Size of the block.", - }, []string{}), - TotalTxs: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Subsystem: "consensus", - Name: "total_txs", - Help: "Total number of transactions.", - }, []string{}), - } -} - -// NopMetrics returns no-op Metrics. -func NopMetrics() *Metrics { - return &Metrics{ - Height: discard.NewGauge(), - - Rounds: discard.NewGauge(), - - Validators: discard.NewGauge(), - ValidatorsPower: discard.NewGauge(), - MissingValidators: discard.NewGauge(), - MissingValidatorsPower: discard.NewGauge(), - ByzantineValidators: discard.NewGauge(), - ByzantineValidatorsPower: discard.NewGauge(), - - BlockIntervalSeconds: discard.NewHistogram(), - - NumTxs: discard.NewGauge(), - BlockSizeBytes: discard.NewGauge(), - TotalTxs: discard.NewGauge(), - } -} diff --git a/consensus/reactor.go b/consensus/reactor.go deleted file mode 100644 index 2034ad344..000000000 --- a/consensus/reactor.go +++ /dev/null @@ -1,1459 +0,0 @@ -package consensus - -import ( - "fmt" - "reflect" - "sync" - "time" - - "github.com/pkg/errors" - - amino "github.com/tendermint/go-amino" - cmn "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/log" - - cstypes "github.com/tendermint/tendermint/consensus/types" - tmevents "github.com/tendermint/tendermint/libs/events" - "github.com/tendermint/tendermint/p2p" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" -) - -const ( - StateChannel = byte(0x20) - DataChannel = byte(0x21) - VoteChannel = byte(0x22) - VoteSetBitsChannel = byte(0x23) - - maxMsgSize = 1048576 // 1MB; NOTE/TODO: keep in sync with types.PartSet sizes. - - blocksToContributeToBecomeGoodPeer = 10000 -) - -//----------------------------------------------------------------------------- - -// ConsensusReactor defines a reactor for the consensus service. -type ConsensusReactor struct { - p2p.BaseReactor // BaseService + p2p.Switch - - conS *ConsensusState - - mtx sync.RWMutex - fastSync bool - eventBus *types.EventBus -} - -// NewConsensusReactor returns a new ConsensusReactor with the given -// consensusState. -func NewConsensusReactor(consensusState *ConsensusState, fastSync bool) *ConsensusReactor { - conR := &ConsensusReactor{ - conS: consensusState, - fastSync: fastSync, - } - conR.BaseReactor = *p2p.NewBaseReactor("ConsensusReactor", conR) - return conR -} - -// OnStart implements BaseService by subscribing to events, which later will be -// broadcasted to other peers and starting state if we're not in fast sync. -func (conR *ConsensusReactor) OnStart() error { - conR.Logger.Info("ConsensusReactor ", "fastSync", conR.FastSync()) - if err := conR.BaseReactor.OnStart(); err != nil { - return err - } - - conR.subscribeToBroadcastEvents() - - if !conR.FastSync() { - err := conR.conS.Start() - if err != nil { - return err - } - } - - return nil -} - -// OnStop implements BaseService by unsubscribing from events and stopping -// state. -func (conR *ConsensusReactor) OnStop() { - conR.BaseReactor.OnStop() - conR.unsubscribeFromBroadcastEvents() - conR.conS.Stop() -} - -// SwitchToConsensus switches from fast_sync mode to consensus mode. -// It resets the state, turns off fast_sync, and starts the consensus state-machine -func (conR *ConsensusReactor) SwitchToConsensus(state sm.State, blocksSynced int) { - conR.Logger.Info("SwitchToConsensus") - conR.conS.reconstructLastCommit(state) - // NOTE: The line below causes broadcastNewRoundStepRoutine() to - // broadcast a NewRoundStepMessage. - conR.conS.updateToState(state) - - conR.mtx.Lock() - conR.fastSync = false - conR.mtx.Unlock() - - if blocksSynced > 0 { - // dont bother with the WAL if we fast synced - conR.conS.doWALCatchup = false - } - err := conR.conS.Start() - if err != nil { - conR.Logger.Error("Error starting conS", "err", err) - return - } -} - -// GetChannels implements Reactor -func (conR *ConsensusReactor) GetChannels() []*p2p.ChannelDescriptor { - // TODO optimize - return []*p2p.ChannelDescriptor{ - { - ID: StateChannel, - Priority: 5, - SendQueueCapacity: 100, - RecvMessageCapacity: maxMsgSize, - }, - { - ID: DataChannel, // maybe split between gossiping current block and catchup stuff - Priority: 10, // once we gossip the whole block there's nothing left to send until next height or round - SendQueueCapacity: 100, - RecvBufferCapacity: 50 * 4096, - RecvMessageCapacity: maxMsgSize, - }, - { - ID: VoteChannel, - Priority: 5, - SendQueueCapacity: 100, - RecvBufferCapacity: 100 * 100, - RecvMessageCapacity: maxMsgSize, - }, - { - ID: VoteSetBitsChannel, - Priority: 1, - SendQueueCapacity: 2, - RecvBufferCapacity: 1024, - RecvMessageCapacity: maxMsgSize, - }, - } -} - -// AddPeer implements Reactor -func (conR *ConsensusReactor) AddPeer(peer p2p.Peer) { - if !conR.IsRunning() { - return - } - - // Create peerState for peer - peerState := NewPeerState(peer).SetLogger(conR.Logger) - peer.Set(types.PeerStateKey, peerState) - - // Begin routines for this peer. - go conR.gossipDataRoutine(peer, peerState) - go conR.gossipVotesRoutine(peer, peerState) - go conR.queryMaj23Routine(peer, peerState) - - // Send our state to peer. - // If we're fast_syncing, broadcast a RoundStepMessage later upon SwitchToConsensus(). - if !conR.FastSync() { - conR.sendNewRoundStepMessages(peer) - } -} - -// RemovePeer implements Reactor -func (conR *ConsensusReactor) RemovePeer(peer p2p.Peer, reason interface{}) { - if !conR.IsRunning() { - return - } - // TODO - //peer.Get(PeerStateKey).(*PeerState).Disconnect() -} - -// Receive implements Reactor -// NOTE: We process these messages even when we're fast_syncing. -// Messages affect either a peer state or the consensus state. -// Peer state updates can happen in parallel, but processing of -// proposals, block parts, and votes are ordered by the receiveRoutine -// NOTE: blocks on consensus state for proposals, block parts, and votes -func (conR *ConsensusReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) { - if !conR.IsRunning() { - conR.Logger.Debug("Receive", "src", src, "chId", chID, "bytes", msgBytes) - return - } - - msg, err := DecodeMessage(msgBytes) - if err != nil { - conR.Logger.Error("Error decoding message", "src", src, "chId", chID, "msg", msg, "err", err, "bytes", msgBytes) - conR.Switch.StopPeerForError(src, err) - return - } - conR.Logger.Debug("Receive", "src", src, "chId", chID, "msg", msg) - - // Get peer states - ps := src.Get(types.PeerStateKey).(*PeerState) - - switch chID { - case StateChannel: - switch msg := msg.(type) { - case *NewRoundStepMessage: - ps.ApplyNewRoundStepMessage(msg) - case *CommitStepMessage: - ps.ApplyCommitStepMessage(msg) - case *HasVoteMessage: - ps.ApplyHasVoteMessage(msg) - case *VoteSetMaj23Message: - cs := conR.conS - cs.mtx.Lock() - height, votes := cs.Height, cs.Votes - cs.mtx.Unlock() - if height != msg.Height { - return - } - // Peer claims to have a maj23 for some BlockID at H,R,S, - err := votes.SetPeerMaj23(msg.Round, msg.Type, ps.peer.ID(), msg.BlockID) - if err != nil { - conR.Switch.StopPeerForError(src, err) - return - } - // Respond with a VoteSetBitsMessage showing which votes we have. - // (and consequently shows which we don't have) - var ourVotes *cmn.BitArray - switch msg.Type { - case types.VoteTypePrevote: - ourVotes = votes.Prevotes(msg.Round).BitArrayByBlockID(msg.BlockID) - case types.VoteTypePrecommit: - ourVotes = votes.Precommits(msg.Round).BitArrayByBlockID(msg.BlockID) - default: - conR.Logger.Error("Bad VoteSetBitsMessage field Type") - return - } - src.TrySend(VoteSetBitsChannel, cdc.MustMarshalBinaryBare(&VoteSetBitsMessage{ - Height: msg.Height, - Round: msg.Round, - Type: msg.Type, - BlockID: msg.BlockID, - Votes: ourVotes, - })) - case *ProposalHeartbeatMessage: - hb := msg.Heartbeat - conR.Logger.Debug("Received proposal heartbeat message", - "height", hb.Height, "round", hb.Round, "sequence", hb.Sequence, - "valIdx", hb.ValidatorIndex, "valAddr", hb.ValidatorAddress) - default: - conR.Logger.Error(cmn.Fmt("Unknown message type %v", reflect.TypeOf(msg))) - } - - case DataChannel: - if conR.FastSync() { - conR.Logger.Info("Ignoring message received during fastSync", "msg", msg) - return - } - switch msg := msg.(type) { - case *ProposalMessage: - ps.SetHasProposal(msg.Proposal) - conR.conS.peerMsgQueue <- msgInfo{msg, src.ID()} - case *ProposalPOLMessage: - ps.ApplyProposalPOLMessage(msg) - case *BlockPartMessage: - ps.SetHasProposalBlockPart(msg.Height, msg.Round, msg.Part.Index) - if numBlocks := ps.RecordBlockPart(msg); numBlocks%blocksToContributeToBecomeGoodPeer == 0 { - conR.Switch.MarkPeerAsGood(src) - } - conR.conS.peerMsgQueue <- msgInfo{msg, src.ID()} - default: - conR.Logger.Error(cmn.Fmt("Unknown message type %v", reflect.TypeOf(msg))) - } - - case VoteChannel: - if conR.FastSync() { - conR.Logger.Info("Ignoring message received during fastSync", "msg", msg) - return - } - switch msg := msg.(type) { - case *VoteMessage: - cs := conR.conS - cs.mtx.Lock() - height, valSize, lastCommitSize := cs.Height, cs.Validators.Size(), cs.LastCommit.Size() - cs.mtx.Unlock() - ps.EnsureVoteBitArrays(height, valSize) - ps.EnsureVoteBitArrays(height-1, lastCommitSize) - ps.SetHasVote(msg.Vote) - if blocks := ps.RecordVote(msg.Vote); blocks%blocksToContributeToBecomeGoodPeer == 0 { - conR.Switch.MarkPeerAsGood(src) - } - - cs.peerMsgQueue <- msgInfo{msg, src.ID()} - - default: - // don't punish (leave room for soft upgrades) - conR.Logger.Error(cmn.Fmt("Unknown message type %v", reflect.TypeOf(msg))) - } - - case VoteSetBitsChannel: - if conR.FastSync() { - conR.Logger.Info("Ignoring message received during fastSync", "msg", msg) - return - } - switch msg := msg.(type) { - case *VoteSetBitsMessage: - cs := conR.conS - cs.mtx.Lock() - height, votes := cs.Height, cs.Votes - cs.mtx.Unlock() - - if height == msg.Height { - var ourVotes *cmn.BitArray - switch msg.Type { - case types.VoteTypePrevote: - ourVotes = votes.Prevotes(msg.Round).BitArrayByBlockID(msg.BlockID) - case types.VoteTypePrecommit: - ourVotes = votes.Precommits(msg.Round).BitArrayByBlockID(msg.BlockID) - default: - conR.Logger.Error("Bad VoteSetBitsMessage field Type") - return - } - ps.ApplyVoteSetBitsMessage(msg, ourVotes) - } else { - ps.ApplyVoteSetBitsMessage(msg, nil) - } - default: - // don't punish (leave room for soft upgrades) - conR.Logger.Error(cmn.Fmt("Unknown message type %v", reflect.TypeOf(msg))) - } - - default: - conR.Logger.Error(cmn.Fmt("Unknown chId %X", chID)) - } - - if err != nil { - conR.Logger.Error("Error in Receive()", "err", err) - } -} - -// SetEventBus sets event bus. -func (conR *ConsensusReactor) SetEventBus(b *types.EventBus) { - conR.eventBus = b - conR.conS.SetEventBus(b) -} - -// FastSync returns whether the consensus reactor is in fast-sync mode. -func (conR *ConsensusReactor) FastSync() bool { - conR.mtx.RLock() - defer conR.mtx.RUnlock() - return conR.fastSync -} - -//-------------------------------------- - -// subscribeToBroadcastEvents subscribes for new round steps, votes and -// proposal heartbeats using internal pubsub defined on state to broadcast -// them to peers upon receiving. -func (conR *ConsensusReactor) subscribeToBroadcastEvents() { - const subscriber = "consensus-reactor" - conR.conS.evsw.AddListenerForEvent(subscriber, types.EventNewRoundStep, - func(data tmevents.EventData) { - conR.broadcastNewRoundStepMessages(data.(*cstypes.RoundState)) - }) - - conR.conS.evsw.AddListenerForEvent(subscriber, types.EventVote, - func(data tmevents.EventData) { - conR.broadcastHasVoteMessage(data.(*types.Vote)) - }) - - conR.conS.evsw.AddListenerForEvent(subscriber, types.EventProposalHeartbeat, - func(data tmevents.EventData) { - conR.broadcastProposalHeartbeatMessage(data.(*types.Heartbeat)) - }) -} - -func (conR *ConsensusReactor) unsubscribeFromBroadcastEvents() { - const subscriber = "consensus-reactor" - conR.conS.evsw.RemoveListener(subscriber) -} - -func (conR *ConsensusReactor) broadcastProposalHeartbeatMessage(hb *types.Heartbeat) { - conR.Logger.Debug("Broadcasting proposal heartbeat message", - "height", hb.Height, "round", hb.Round, "sequence", hb.Sequence) - msg := &ProposalHeartbeatMessage{hb} - conR.Switch.Broadcast(StateChannel, cdc.MustMarshalBinaryBare(msg)) -} - -func (conR *ConsensusReactor) broadcastNewRoundStepMessages(rs *cstypes.RoundState) { - nrsMsg, csMsg := makeRoundStepMessages(rs) - if nrsMsg != nil { - conR.Switch.Broadcast(StateChannel, cdc.MustMarshalBinaryBare(nrsMsg)) - } - if csMsg != nil { - conR.Switch.Broadcast(StateChannel, cdc.MustMarshalBinaryBare(csMsg)) - } -} - -// Broadcasts HasVoteMessage to peers that care. -func (conR *ConsensusReactor) broadcastHasVoteMessage(vote *types.Vote) { - msg := &HasVoteMessage{ - Height: vote.Height, - Round: vote.Round, - Type: vote.Type, - Index: vote.ValidatorIndex, - } - conR.Switch.Broadcast(StateChannel, cdc.MustMarshalBinaryBare(msg)) - /* - // TODO: Make this broadcast more selective. - for _, peer := range conR.Switch.Peers().List() { - ps := peer.Get(PeerStateKey).(*PeerState) - prs := ps.GetRoundState() - if prs.Height == vote.Height { - // TODO: Also filter on round? - peer.TrySend(StateChannel, struct{ ConsensusMessage }{msg}) - } else { - // Height doesn't match - // TODO: check a field, maybe CatchupCommitRound? - // TODO: But that requires changing the struct field comment. - } - } - */ -} - -func makeRoundStepMessages(rs *cstypes.RoundState) (nrsMsg *NewRoundStepMessage, csMsg *CommitStepMessage) { - nrsMsg = &NewRoundStepMessage{ - Height: rs.Height, - Round: rs.Round, - Step: rs.Step, - SecondsSinceStartTime: int(time.Since(rs.StartTime).Seconds()), - LastCommitRound: rs.LastCommit.Round(), - } - if rs.Step == cstypes.RoundStepCommit { - csMsg = &CommitStepMessage{ - Height: rs.Height, - BlockPartsHeader: rs.ProposalBlockParts.Header(), - BlockParts: rs.ProposalBlockParts.BitArray(), - } - } - return -} - -func (conR *ConsensusReactor) sendNewRoundStepMessages(peer p2p.Peer) { - rs := conR.conS.GetRoundState() - nrsMsg, csMsg := makeRoundStepMessages(rs) - if nrsMsg != nil { - peer.Send(StateChannel, cdc.MustMarshalBinaryBare(nrsMsg)) - } - if csMsg != nil { - peer.Send(StateChannel, cdc.MustMarshalBinaryBare(csMsg)) - } -} - -func (conR *ConsensusReactor) gossipDataRoutine(peer p2p.Peer, ps *PeerState) { - logger := conR.Logger.With("peer", peer) - -OUTER_LOOP: - for { - // Manage disconnects from self or peer. - if !peer.IsRunning() || !conR.IsRunning() { - logger.Info("Stopping gossipDataRoutine for peer") - return - } - rs := conR.conS.GetRoundState() - prs := ps.GetRoundState() - - // Send proposal Block parts? - if rs.ProposalBlockParts.HasHeader(prs.ProposalBlockPartsHeader) { - if index, ok := rs.ProposalBlockParts.BitArray().Sub(prs.ProposalBlockParts.Copy()).PickRandom(); ok { - part := rs.ProposalBlockParts.GetPart(index) - msg := &BlockPartMessage{ - Height: rs.Height, // This tells peer that this part applies to us. - Round: rs.Round, // This tells peer that this part applies to us. - Part: part, - } - logger.Debug("Sending block part", "height", prs.Height, "round", prs.Round) - if peer.Send(DataChannel, cdc.MustMarshalBinaryBare(msg)) { - ps.SetHasProposalBlockPart(prs.Height, prs.Round, index) - } - continue OUTER_LOOP - } - } - - // If the peer is on a previous height, help catch up. - if (0 < prs.Height) && (prs.Height < rs.Height) { - heightLogger := logger.With("height", prs.Height) - - // if we never received the commit message from the peer, the block parts wont be initialized - if prs.ProposalBlockParts == nil { - blockMeta := conR.conS.blockStore.LoadBlockMeta(prs.Height) - if blockMeta == nil { - cmn.PanicCrisis(cmn.Fmt("Failed to load block %d when blockStore is at %d", - prs.Height, conR.conS.blockStore.Height())) - } - ps.InitProposalBlockParts(blockMeta.BlockID.PartsHeader) - // continue the loop since prs is a copy and not effected by this initialization - continue OUTER_LOOP - } - conR.gossipDataForCatchup(heightLogger, rs, prs, ps, peer) - continue OUTER_LOOP - } - - // If height and round don't match, sleep. - if (rs.Height != prs.Height) || (rs.Round != prs.Round) { - //logger.Info("Peer Height|Round mismatch, sleeping", "peerHeight", prs.Height, "peerRound", prs.Round, "peer", peer) - time.Sleep(conR.conS.config.PeerGossipSleep()) - continue OUTER_LOOP - } - - // By here, height and round match. - // Proposal block parts were already matched and sent if any were wanted. - // (These can match on hash so the round doesn't matter) - // Now consider sending other things, like the Proposal itself. - - // Send Proposal && ProposalPOL BitArray? - if rs.Proposal != nil && !prs.Proposal { - // Proposal: share the proposal metadata with peer. - { - msg := &ProposalMessage{Proposal: rs.Proposal} - logger.Debug("Sending proposal", "height", prs.Height, "round", prs.Round) - if peer.Send(DataChannel, cdc.MustMarshalBinaryBare(msg)) { - ps.SetHasProposal(rs.Proposal) - } - } - // ProposalPOL: lets peer know which POL votes we have so far. - // Peer must receive ProposalMessage first. - // rs.Proposal was validated, so rs.Proposal.POLRound <= rs.Round, - // so we definitely have rs.Votes.Prevotes(rs.Proposal.POLRound). - if 0 <= rs.Proposal.POLRound { - msg := &ProposalPOLMessage{ - Height: rs.Height, - ProposalPOLRound: rs.Proposal.POLRound, - ProposalPOL: rs.Votes.Prevotes(rs.Proposal.POLRound).BitArray(), - } - logger.Debug("Sending POL", "height", prs.Height, "round", prs.Round) - peer.Send(DataChannel, cdc.MustMarshalBinaryBare(msg)) - } - continue OUTER_LOOP - } - - // Nothing to do. Sleep. - time.Sleep(conR.conS.config.PeerGossipSleep()) - continue OUTER_LOOP - } -} - -func (conR *ConsensusReactor) gossipDataForCatchup(logger log.Logger, rs *cstypes.RoundState, - prs *cstypes.PeerRoundState, ps *PeerState, peer p2p.Peer) { - - if index, ok := prs.ProposalBlockParts.Not().PickRandom(); ok { - // Ensure that the peer's PartSetHeader is correct - blockMeta := conR.conS.blockStore.LoadBlockMeta(prs.Height) - if blockMeta == nil { - logger.Error("Failed to load block meta", - "ourHeight", rs.Height, "blockstoreHeight", conR.conS.blockStore.Height()) - time.Sleep(conR.conS.config.PeerGossipSleep()) - return - } else if !blockMeta.BlockID.PartsHeader.Equals(prs.ProposalBlockPartsHeader) { - logger.Info("Peer ProposalBlockPartsHeader mismatch, sleeping", - "blockPartsHeader", blockMeta.BlockID.PartsHeader, "peerBlockPartsHeader", prs.ProposalBlockPartsHeader) - time.Sleep(conR.conS.config.PeerGossipSleep()) - return - } - // Load the part - part := conR.conS.blockStore.LoadBlockPart(prs.Height, index) - if part == nil { - logger.Error("Could not load part", "index", index, - "blockPartsHeader", blockMeta.BlockID.PartsHeader, "peerBlockPartsHeader", prs.ProposalBlockPartsHeader) - time.Sleep(conR.conS.config.PeerGossipSleep()) - return - } - // Send the part - msg := &BlockPartMessage{ - Height: prs.Height, // Not our height, so it doesn't matter. - Round: prs.Round, // Not our height, so it doesn't matter. - Part: part, - } - logger.Debug("Sending block part for catchup", "round", prs.Round, "index", index) - if peer.Send(DataChannel, cdc.MustMarshalBinaryBare(msg)) { - ps.SetHasProposalBlockPart(prs.Height, prs.Round, index) - } else { - logger.Debug("Sending block part for catchup failed") - } - return - } - //logger.Info("No parts to send in catch-up, sleeping") - time.Sleep(conR.conS.config.PeerGossipSleep()) -} - -func (conR *ConsensusReactor) gossipVotesRoutine(peer p2p.Peer, ps *PeerState) { - logger := conR.Logger.With("peer", peer) - - // Simple hack to throttle logs upon sleep. - var sleeping = 0 - -OUTER_LOOP: - for { - // Manage disconnects from self or peer. - if !peer.IsRunning() || !conR.IsRunning() { - logger.Info("Stopping gossipVotesRoutine for peer") - return - } - rs := conR.conS.GetRoundState() - prs := ps.GetRoundState() - - switch sleeping { - case 1: // First sleep - sleeping = 2 - case 2: // No more sleep - sleeping = 0 - } - - //logger.Debug("gossipVotesRoutine", "rsHeight", rs.Height, "rsRound", rs.Round, - // "prsHeight", prs.Height, "prsRound", prs.Round, "prsStep", prs.Step) - - // If height matches, then send LastCommit, Prevotes, Precommits. - if rs.Height == prs.Height { - heightLogger := logger.With("height", prs.Height) - if conR.gossipVotesForHeight(heightLogger, rs, prs, ps) { - continue OUTER_LOOP - } - } - - // Special catchup logic. - // If peer is lagging by height 1, send LastCommit. - if prs.Height != 0 && rs.Height == prs.Height+1 { - if ps.PickSendVote(rs.LastCommit) { - logger.Debug("Picked rs.LastCommit to send", "height", prs.Height) - continue OUTER_LOOP - } - } - - // Catchup logic - // If peer is lagging by more than 1, send Commit. - if prs.Height != 0 && rs.Height >= prs.Height+2 { - // Load the block commit for prs.Height, - // which contains precommit signatures for prs.Height. - commit := conR.conS.blockStore.LoadBlockCommit(prs.Height) - if ps.PickSendVote(commit) { - logger.Debug("Picked Catchup commit to send", "height", prs.Height) - continue OUTER_LOOP - } - } - - if sleeping == 0 { - // We sent nothing. Sleep... - sleeping = 1 - logger.Debug("No votes to send, sleeping", "rs.Height", rs.Height, "prs.Height", prs.Height, - "localPV", rs.Votes.Prevotes(rs.Round).BitArray(), "peerPV", prs.Prevotes, - "localPC", rs.Votes.Precommits(rs.Round).BitArray(), "peerPC", prs.Precommits) - } else if sleeping == 2 { - // Continued sleep... - sleeping = 1 - } - - time.Sleep(conR.conS.config.PeerGossipSleep()) - continue OUTER_LOOP - } -} - -func (conR *ConsensusReactor) gossipVotesForHeight(logger log.Logger, rs *cstypes.RoundState, prs *cstypes.PeerRoundState, ps *PeerState) bool { - - // If there are lastCommits to send... - if prs.Step == cstypes.RoundStepNewHeight { - if ps.PickSendVote(rs.LastCommit) { - logger.Debug("Picked rs.LastCommit to send") - return true - } - } - // If there are POL prevotes to send... - if prs.Step <= cstypes.RoundStepPropose && prs.Round != -1 && prs.Round <= rs.Round && prs.ProposalPOLRound != -1 { - if polPrevotes := rs.Votes.Prevotes(prs.ProposalPOLRound); polPrevotes != nil { - if ps.PickSendVote(polPrevotes) { - logger.Debug("Picked rs.Prevotes(prs.ProposalPOLRound) to send", - "round", prs.ProposalPOLRound) - return true - } - } - } - // If there are prevotes to send... - if prs.Step <= cstypes.RoundStepPrevoteWait && prs.Round != -1 && prs.Round <= rs.Round { - if ps.PickSendVote(rs.Votes.Prevotes(prs.Round)) { - logger.Debug("Picked rs.Prevotes(prs.Round) to send", "round", prs.Round) - return true - } - } - // If there are precommits to send... - if prs.Step <= cstypes.RoundStepPrecommitWait && prs.Round != -1 && prs.Round <= rs.Round { - if ps.PickSendVote(rs.Votes.Precommits(prs.Round)) { - logger.Debug("Picked rs.Precommits(prs.Round) to send", "round", prs.Round) - return true - } - } - // If there are prevotes to send...Needed because of validBlock mechanism - if prs.Round != -1 && prs.Round <= rs.Round { - if ps.PickSendVote(rs.Votes.Prevotes(prs.Round)) { - logger.Debug("Picked rs.Prevotes(prs.Round) to send", "round", prs.Round) - return true - } - } - // If there are POLPrevotes to send... - if prs.ProposalPOLRound != -1 { - if polPrevotes := rs.Votes.Prevotes(prs.ProposalPOLRound); polPrevotes != nil { - if ps.PickSendVote(polPrevotes) { - logger.Debug("Picked rs.Prevotes(prs.ProposalPOLRound) to send", - "round", prs.ProposalPOLRound) - return true - } - } - } - - return false -} - -// NOTE: `queryMaj23Routine` has a simple crude design since it only comes -// into play for liveness when there's a signature DDoS attack happening. -func (conR *ConsensusReactor) queryMaj23Routine(peer p2p.Peer, ps *PeerState) { - logger := conR.Logger.With("peer", peer) - -OUTER_LOOP: - for { - // Manage disconnects from self or peer. - if !peer.IsRunning() || !conR.IsRunning() { - logger.Info("Stopping queryMaj23Routine for peer") - return - } - - // Maybe send Height/Round/Prevotes - { - rs := conR.conS.GetRoundState() - prs := ps.GetRoundState() - if rs.Height == prs.Height { - if maj23, ok := rs.Votes.Prevotes(prs.Round).TwoThirdsMajority(); ok { - peer.TrySend(StateChannel, cdc.MustMarshalBinaryBare(&VoteSetMaj23Message{ - Height: prs.Height, - Round: prs.Round, - Type: types.VoteTypePrevote, - BlockID: maj23, - })) - time.Sleep(conR.conS.config.PeerQueryMaj23Sleep()) - } - } - } - - // Maybe send Height/Round/Precommits - { - rs := conR.conS.GetRoundState() - prs := ps.GetRoundState() - if rs.Height == prs.Height { - if maj23, ok := rs.Votes.Precommits(prs.Round).TwoThirdsMajority(); ok { - peer.TrySend(StateChannel, cdc.MustMarshalBinaryBare(&VoteSetMaj23Message{ - Height: prs.Height, - Round: prs.Round, - Type: types.VoteTypePrecommit, - BlockID: maj23, - })) - time.Sleep(conR.conS.config.PeerQueryMaj23Sleep()) - } - } - } - - // Maybe send Height/Round/ProposalPOL - { - rs := conR.conS.GetRoundState() - prs := ps.GetRoundState() - if rs.Height == prs.Height && prs.ProposalPOLRound >= 0 { - if maj23, ok := rs.Votes.Prevotes(prs.ProposalPOLRound).TwoThirdsMajority(); ok { - peer.TrySend(StateChannel, cdc.MustMarshalBinaryBare(&VoteSetMaj23Message{ - Height: prs.Height, - Round: prs.ProposalPOLRound, - Type: types.VoteTypePrevote, - BlockID: maj23, - })) - time.Sleep(conR.conS.config.PeerQueryMaj23Sleep()) - } - } - } - - // Little point sending LastCommitRound/LastCommit, - // These are fleeting and non-blocking. - - // Maybe send Height/CatchupCommitRound/CatchupCommit. - { - prs := ps.GetRoundState() - if prs.CatchupCommitRound != -1 && 0 < prs.Height && prs.Height <= conR.conS.blockStore.Height() { - commit := conR.conS.LoadCommit(prs.Height) - peer.TrySend(StateChannel, cdc.MustMarshalBinaryBare(&VoteSetMaj23Message{ - Height: prs.Height, - Round: commit.Round(), - Type: types.VoteTypePrecommit, - BlockID: commit.BlockID, - })) - time.Sleep(conR.conS.config.PeerQueryMaj23Sleep()) - } - } - - time.Sleep(conR.conS.config.PeerQueryMaj23Sleep()) - - continue OUTER_LOOP - } -} - -// String returns a string representation of the ConsensusReactor. -// NOTE: For now, it is just a hard-coded string to avoid accessing unprotected shared variables. -// TODO: improve! -func (conR *ConsensusReactor) String() string { - // better not to access shared variables - return "ConsensusReactor" // conR.StringIndented("") -} - -// StringIndented returns an indented string representation of the ConsensusReactor -func (conR *ConsensusReactor) StringIndented(indent string) string { - s := "ConsensusReactor{\n" - s += indent + " " + conR.conS.StringIndented(indent+" ") + "\n" - for _, peer := range conR.Switch.Peers().List() { - ps := peer.Get(types.PeerStateKey).(*PeerState) - s += indent + " " + ps.StringIndented(indent+" ") + "\n" - } - s += indent + "}" - return s -} - -//----------------------------------------------------------------------------- - -var ( - ErrPeerStateHeightRegression = errors.New("Error peer state height regression") - ErrPeerStateInvalidStartTime = errors.New("Error peer state invalid startTime") -) - -// PeerState contains the known state of a peer, including its connection and -// threadsafe access to its PeerRoundState. -// NOTE: THIS GETS DUMPED WITH rpc/core/consensus.go. -// Be mindful of what you Expose. -type PeerState struct { - peer p2p.Peer - logger log.Logger - - mtx sync.Mutex `json:"-"` // NOTE: Modify below using setters, never directly. - PRS cstypes.PeerRoundState `json:"round_state"` // Exposed. - Stats *peerStateStats `json:"stats"` // Exposed. -} - -// peerStateStats holds internal statistics for a peer. -type peerStateStats struct { - LastVoteHeight int64 `json:"last_vote_height"` - Votes int `json:"votes"` - LastBlockPartHeight int64 `json:"last_block_part_height"` - BlockParts int `json:"block_parts"` -} - -func (pss peerStateStats) String() string { - return fmt.Sprintf("peerStateStats{lvh: %d, votes: %d, lbph: %d, blockParts: %d}", - pss.LastVoteHeight, pss.Votes, pss.LastBlockPartHeight, pss.BlockParts) -} - -// NewPeerState returns a new PeerState for the given Peer -func NewPeerState(peer p2p.Peer) *PeerState { - return &PeerState{ - peer: peer, - logger: log.NewNopLogger(), - PRS: cstypes.PeerRoundState{ - Round: -1, - ProposalPOLRound: -1, - LastCommitRound: -1, - CatchupCommitRound: -1, - }, - Stats: &peerStateStats{}, - } -} - -// SetLogger allows to set a logger on the peer state. Returns the peer state -// itself. -func (ps *PeerState) SetLogger(logger log.Logger) *PeerState { - ps.logger = logger - return ps -} - -// GetRoundState returns an shallow copy of the PeerRoundState. -// There's no point in mutating it since it won't change PeerState. -func (ps *PeerState) GetRoundState() *cstypes.PeerRoundState { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - prs := ps.PRS // copy - return &prs -} - -// ToJSON returns a json of PeerState, marshalled using go-amino. -func (ps *PeerState) ToJSON() ([]byte, error) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - return cdc.MarshalJSON(ps) -} - -// GetHeight returns an atomic snapshot of the PeerRoundState's height -// used by the mempool to ensure peers are caught up before broadcasting new txs -func (ps *PeerState) GetHeight() int64 { - ps.mtx.Lock() - defer ps.mtx.Unlock() - return ps.PRS.Height -} - -// SetHasProposal sets the given proposal as known for the peer. -func (ps *PeerState) SetHasProposal(proposal *types.Proposal) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.PRS.Height != proposal.Height || ps.PRS.Round != proposal.Round { - return - } - if ps.PRS.Proposal { - return - } - - ps.PRS.Proposal = true - ps.PRS.ProposalBlockPartsHeader = proposal.BlockPartsHeader - ps.PRS.ProposalBlockParts = cmn.NewBitArray(proposal.BlockPartsHeader.Total) - ps.PRS.ProposalPOLRound = proposal.POLRound - ps.PRS.ProposalPOL = nil // Nil until ProposalPOLMessage received. -} - -// InitProposalBlockParts initializes the peer's proposal block parts header and bit array. -func (ps *PeerState) InitProposalBlockParts(partsHeader types.PartSetHeader) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.PRS.ProposalBlockParts != nil { - return - } - - ps.PRS.ProposalBlockPartsHeader = partsHeader - ps.PRS.ProposalBlockParts = cmn.NewBitArray(partsHeader.Total) -} - -// SetHasProposalBlockPart sets the given block part index as known for the peer. -func (ps *PeerState) SetHasProposalBlockPart(height int64, round int, index int) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.PRS.Height != height || ps.PRS.Round != round { - return - } - - ps.PRS.ProposalBlockParts.SetIndex(index, true) -} - -// PickSendVote picks a vote and sends it to the peer. -// Returns true if vote was sent. -func (ps *PeerState) PickSendVote(votes types.VoteSetReader) bool { - if vote, ok := ps.PickVoteToSend(votes); ok { - msg := &VoteMessage{vote} - ps.logger.Debug("Sending vote message", "ps", ps, "vote", vote) - return ps.peer.Send(VoteChannel, cdc.MustMarshalBinaryBare(msg)) - } - return false -} - -// PickVoteToSend picks a vote to send to the peer. -// Returns true if a vote was picked. -// NOTE: `votes` must be the correct Size() for the Height(). -func (ps *PeerState) PickVoteToSend(votes types.VoteSetReader) (vote *types.Vote, ok bool) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if votes.Size() == 0 { - return nil, false - } - - height, round, type_, size := votes.Height(), votes.Round(), votes.Type(), votes.Size() - - // Lazily set data using 'votes'. - if votes.IsCommit() { - ps.ensureCatchupCommitRound(height, round, size) - } - ps.ensureVoteBitArrays(height, size) - - psVotes := ps.getVoteBitArray(height, round, type_) - if psVotes == nil { - return nil, false // Not something worth sending - } - if index, ok := votes.BitArray().Sub(psVotes).PickRandom(); ok { - ps.setHasVote(height, round, type_, index) - return votes.GetByIndex(index), true - } - return nil, false -} - -func (ps *PeerState) getVoteBitArray(height int64, round int, type_ byte) *cmn.BitArray { - if !types.IsVoteTypeValid(type_) { - return nil - } - - if ps.PRS.Height == height { - if ps.PRS.Round == round { - switch type_ { - case types.VoteTypePrevote: - return ps.PRS.Prevotes - case types.VoteTypePrecommit: - return ps.PRS.Precommits - } - } - if ps.PRS.CatchupCommitRound == round { - switch type_ { - case types.VoteTypePrevote: - return nil - case types.VoteTypePrecommit: - return ps.PRS.CatchupCommit - } - } - if ps.PRS.ProposalPOLRound == round { - switch type_ { - case types.VoteTypePrevote: - return ps.PRS.ProposalPOL - case types.VoteTypePrecommit: - return nil - } - } - return nil - } - if ps.PRS.Height == height+1 { - if ps.PRS.LastCommitRound == round { - switch type_ { - case types.VoteTypePrevote: - return nil - case types.VoteTypePrecommit: - return ps.PRS.LastCommit - } - } - return nil - } - return nil -} - -// 'round': A round for which we have a +2/3 commit. -func (ps *PeerState) ensureCatchupCommitRound(height int64, round int, numValidators int) { - if ps.PRS.Height != height { - return - } - /* - NOTE: This is wrong, 'round' could change. - e.g. if orig round is not the same as block LastCommit round. - if ps.CatchupCommitRound != -1 && ps.CatchupCommitRound != round { - cmn.PanicSanity(cmn.Fmt("Conflicting CatchupCommitRound. Height: %v, Orig: %v, New: %v", height, ps.CatchupCommitRound, round)) - } - */ - if ps.PRS.CatchupCommitRound == round { - return // Nothing to do! - } - ps.PRS.CatchupCommitRound = round - if round == ps.PRS.Round { - ps.PRS.CatchupCommit = ps.PRS.Precommits - } else { - ps.PRS.CatchupCommit = cmn.NewBitArray(numValidators) - } -} - -// EnsureVoteBitArrays ensures the bit-arrays have been allocated for tracking -// what votes this peer has received. -// NOTE: It's important to make sure that numValidators actually matches -// what the node sees as the number of validators for height. -func (ps *PeerState) EnsureVoteBitArrays(height int64, numValidators int) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - ps.ensureVoteBitArrays(height, numValidators) -} - -func (ps *PeerState) ensureVoteBitArrays(height int64, numValidators int) { - if ps.PRS.Height == height { - if ps.PRS.Prevotes == nil { - ps.PRS.Prevotes = cmn.NewBitArray(numValidators) - } - if ps.PRS.Precommits == nil { - ps.PRS.Precommits = cmn.NewBitArray(numValidators) - } - if ps.PRS.CatchupCommit == nil { - ps.PRS.CatchupCommit = cmn.NewBitArray(numValidators) - } - if ps.PRS.ProposalPOL == nil { - ps.PRS.ProposalPOL = cmn.NewBitArray(numValidators) - } - } else if ps.PRS.Height == height+1 { - if ps.PRS.LastCommit == nil { - ps.PRS.LastCommit = cmn.NewBitArray(numValidators) - } - } -} - -// RecordVote updates internal statistics for this peer by recording the vote. -// It returns the total number of votes (1 per block). This essentially means -// the number of blocks for which peer has been sending us votes. -func (ps *PeerState) RecordVote(vote *types.Vote) int { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.Stats.LastVoteHeight >= vote.Height { - return ps.Stats.Votes - } - ps.Stats.LastVoteHeight = vote.Height - ps.Stats.Votes++ - return ps.Stats.Votes -} - -// VotesSent returns the number of blocks for which peer has been sending us -// votes. -func (ps *PeerState) VotesSent() int { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - return ps.Stats.Votes -} - -// RecordBlockPart updates internal statistics for this peer by recording the -// block part. It returns the total number of block parts (1 per block). This -// essentially means the number of blocks for which peer has been sending us -// block parts. -func (ps *PeerState) RecordBlockPart(bp *BlockPartMessage) int { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.Stats.LastBlockPartHeight >= bp.Height { - return ps.Stats.BlockParts - } - - ps.Stats.LastBlockPartHeight = bp.Height - ps.Stats.BlockParts++ - return ps.Stats.BlockParts -} - -// BlockPartsSent returns the number of blocks for which peer has been sending -// us block parts. -func (ps *PeerState) BlockPartsSent() int { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - return ps.Stats.BlockParts -} - -// SetHasVote sets the given vote as known by the peer -func (ps *PeerState) SetHasVote(vote *types.Vote) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - ps.setHasVote(vote.Height, vote.Round, vote.Type, vote.ValidatorIndex) -} - -func (ps *PeerState) setHasVote(height int64, round int, type_ byte, index int) { - logger := ps.logger.With("peerH/R", cmn.Fmt("%d/%d", ps.PRS.Height, ps.PRS.Round), "H/R", cmn.Fmt("%d/%d", height, round)) - logger.Debug("setHasVote", "type", type_, "index", index) - - // NOTE: some may be nil BitArrays -> no side effects. - psVotes := ps.getVoteBitArray(height, round, type_) - if psVotes != nil { - psVotes.SetIndex(index, true) - } -} - -// ApplyNewRoundStepMessage updates the peer state for the new round. -func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - // Ignore duplicates or decreases - if CompareHRS(msg.Height, msg.Round, msg.Step, ps.PRS.Height, ps.PRS.Round, ps.PRS.Step) <= 0 { - return - } - - // Just remember these values. - psHeight := ps.PRS.Height - psRound := ps.PRS.Round - //psStep := ps.PRS.Step - psCatchupCommitRound := ps.PRS.CatchupCommitRound - psCatchupCommit := ps.PRS.CatchupCommit - - startTime := time.Now().Add(-1 * time.Duration(msg.SecondsSinceStartTime) * time.Second) - ps.PRS.Height = msg.Height - ps.PRS.Round = msg.Round - ps.PRS.Step = msg.Step - ps.PRS.StartTime = startTime - if psHeight != msg.Height || psRound != msg.Round { - ps.PRS.Proposal = false - ps.PRS.ProposalBlockPartsHeader = types.PartSetHeader{} - ps.PRS.ProposalBlockParts = nil - ps.PRS.ProposalPOLRound = -1 - ps.PRS.ProposalPOL = nil - // We'll update the BitArray capacity later. - ps.PRS.Prevotes = nil - ps.PRS.Precommits = nil - } - if psHeight == msg.Height && psRound != msg.Round && msg.Round == psCatchupCommitRound { - // Peer caught up to CatchupCommitRound. - // Preserve psCatchupCommit! - // NOTE: We prefer to use prs.Precommits if - // pr.Round matches pr.CatchupCommitRound. - ps.PRS.Precommits = psCatchupCommit - } - if psHeight != msg.Height { - // Shift Precommits to LastCommit. - if psHeight+1 == msg.Height && psRound == msg.LastCommitRound { - ps.PRS.LastCommitRound = msg.LastCommitRound - ps.PRS.LastCommit = ps.PRS.Precommits - } else { - ps.PRS.LastCommitRound = msg.LastCommitRound - ps.PRS.LastCommit = nil - } - // We'll update the BitArray capacity later. - ps.PRS.CatchupCommitRound = -1 - ps.PRS.CatchupCommit = nil - } -} - -// ApplyCommitStepMessage updates the peer state for the new commit. -func (ps *PeerState) ApplyCommitStepMessage(msg *CommitStepMessage) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.PRS.Height != msg.Height { - return - } - - ps.PRS.ProposalBlockPartsHeader = msg.BlockPartsHeader - ps.PRS.ProposalBlockParts = msg.BlockParts -} - -// ApplyProposalPOLMessage updates the peer state for the new proposal POL. -func (ps *PeerState) ApplyProposalPOLMessage(msg *ProposalPOLMessage) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.PRS.Height != msg.Height { - return - } - if ps.PRS.ProposalPOLRound != msg.ProposalPOLRound { - return - } - - // TODO: Merge onto existing ps.PRS.ProposalPOL? - // We might have sent some prevotes in the meantime. - ps.PRS.ProposalPOL = msg.ProposalPOL -} - -// ApplyHasVoteMessage updates the peer state for the new vote. -func (ps *PeerState) ApplyHasVoteMessage(msg *HasVoteMessage) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.PRS.Height != msg.Height { - return - } - - ps.setHasVote(msg.Height, msg.Round, msg.Type, msg.Index) -} - -// ApplyVoteSetBitsMessage updates the peer state for the bit-array of votes -// it claims to have for the corresponding BlockID. -// `ourVotes` is a BitArray of votes we have for msg.BlockID -// NOTE: if ourVotes is nil (e.g. msg.Height < rs.Height), -// we conservatively overwrite ps's votes w/ msg.Votes. -func (ps *PeerState) ApplyVoteSetBitsMessage(msg *VoteSetBitsMessage, ourVotes *cmn.BitArray) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - votes := ps.getVoteBitArray(msg.Height, msg.Round, msg.Type) - if votes != nil { - if ourVotes == nil { - votes.Update(msg.Votes) - } else { - otherVotes := votes.Sub(ourVotes) - hasVotes := otherVotes.Or(msg.Votes) - votes.Update(hasVotes) - } - } -} - -// String returns a string representation of the PeerState -func (ps *PeerState) String() string { - return ps.StringIndented("") -} - -// StringIndented returns a string representation of the PeerState -func (ps *PeerState) StringIndented(indent string) string { - ps.mtx.Lock() - defer ps.mtx.Unlock() - return fmt.Sprintf(`PeerState{ -%s Key %v -%s RoundState %v -%s Stats %v -%s}`, - indent, ps.peer.ID(), - indent, ps.PRS.StringIndented(indent+" "), - indent, ps.Stats, - indent) -} - -//----------------------------------------------------------------------------- -// Messages - -// ConsensusMessage is a message that can be sent and received on the ConsensusReactor -type ConsensusMessage interface{} - -func RegisterConsensusMessages(cdc *amino.Codec) { - cdc.RegisterInterface((*ConsensusMessage)(nil), nil) - cdc.RegisterConcrete(&NewRoundStepMessage{}, "tendermint/NewRoundStepMessage", nil) - cdc.RegisterConcrete(&CommitStepMessage{}, "tendermint/CommitStep", nil) - cdc.RegisterConcrete(&ProposalMessage{}, "tendermint/Proposal", nil) - cdc.RegisterConcrete(&ProposalPOLMessage{}, "tendermint/ProposalPOL", nil) - cdc.RegisterConcrete(&BlockPartMessage{}, "tendermint/BlockPart", nil) - cdc.RegisterConcrete(&VoteMessage{}, "tendermint/Vote", nil) - cdc.RegisterConcrete(&HasVoteMessage{}, "tendermint/HasVote", nil) - cdc.RegisterConcrete(&VoteSetMaj23Message{}, "tendermint/VoteSetMaj23", nil) - cdc.RegisterConcrete(&VoteSetBitsMessage{}, "tendermint/VoteSetBits", nil) - cdc.RegisterConcrete(&ProposalHeartbeatMessage{}, "tendermint/ProposalHeartbeat", nil) -} - -// DecodeMessage decodes the given bytes into a ConsensusMessage. -func DecodeMessage(bz []byte) (msg ConsensusMessage, err error) { - if len(bz) > maxMsgSize { - return msg, fmt.Errorf("Msg exceeds max size (%d > %d)", - len(bz), maxMsgSize) - } - err = cdc.UnmarshalBinaryBare(bz, &msg) - return -} - -//------------------------------------- - -// NewRoundStepMessage is sent for every step taken in the ConsensusState. -// For every height/round/step transition -type NewRoundStepMessage struct { - Height int64 - Round int - Step cstypes.RoundStepType - SecondsSinceStartTime int - LastCommitRound int -} - -// String returns a string representation. -func (m *NewRoundStepMessage) String() string { - return fmt.Sprintf("[NewRoundStep H:%v R:%v S:%v LCR:%v]", - m.Height, m.Round, m.Step, m.LastCommitRound) -} - -//------------------------------------- - -// CommitStepMessage is sent when a block is committed. -type CommitStepMessage struct { - Height int64 - BlockPartsHeader types.PartSetHeader - BlockParts *cmn.BitArray -} - -// String returns a string representation. -func (m *CommitStepMessage) String() string { - return fmt.Sprintf("[CommitStep H:%v BP:%v BA:%v]", m.Height, m.BlockPartsHeader, m.BlockParts) -} - -//------------------------------------- - -// ProposalMessage is sent when a new block is proposed. -type ProposalMessage struct { - Proposal *types.Proposal -} - -// String returns a string representation. -func (m *ProposalMessage) String() string { - return fmt.Sprintf("[Proposal %v]", m.Proposal) -} - -//------------------------------------- - -// ProposalPOLMessage is sent when a previous proposal is re-proposed. -type ProposalPOLMessage struct { - Height int64 - ProposalPOLRound int - ProposalPOL *cmn.BitArray -} - -// String returns a string representation. -func (m *ProposalPOLMessage) String() string { - return fmt.Sprintf("[ProposalPOL H:%v POLR:%v POL:%v]", m.Height, m.ProposalPOLRound, m.ProposalPOL) -} - -//------------------------------------- - -// BlockPartMessage is sent when gossipping a piece of the proposed block. -type BlockPartMessage struct { - Height int64 - Round int - Part *types.Part -} - -// String returns a string representation. -func (m *BlockPartMessage) String() string { - return fmt.Sprintf("[BlockPart H:%v R:%v P:%v]", m.Height, m.Round, m.Part) -} - -//------------------------------------- - -// VoteMessage is sent when voting for a proposal (or lack thereof). -type VoteMessage struct { - Vote *types.Vote -} - -// String returns a string representation. -func (m *VoteMessage) String() string { - return fmt.Sprintf("[Vote %v]", m.Vote) -} - -//------------------------------------- - -// HasVoteMessage is sent to indicate that a particular vote has been received. -type HasVoteMessage struct { - Height int64 - Round int - Type byte - Index int -} - -// String returns a string representation. -func (m *HasVoteMessage) String() string { - return fmt.Sprintf("[HasVote VI:%v V:{%v/%02d/%v}]", m.Index, m.Height, m.Round, m.Type) -} - -//------------------------------------- - -// VoteSetMaj23Message is sent to indicate that a given BlockID has seen +2/3 votes. -type VoteSetMaj23Message struct { - Height int64 - Round int - Type byte - BlockID types.BlockID -} - -// String returns a string representation. -func (m *VoteSetMaj23Message) String() string { - return fmt.Sprintf("[VSM23 %v/%02d/%v %v]", m.Height, m.Round, m.Type, m.BlockID) -} - -//------------------------------------- - -// VoteSetBitsMessage is sent to communicate the bit-array of votes seen for the BlockID. -type VoteSetBitsMessage struct { - Height int64 - Round int - Type byte - BlockID types.BlockID - Votes *cmn.BitArray -} - -// String returns a string representation. -func (m *VoteSetBitsMessage) String() string { - return fmt.Sprintf("[VSB %v/%02d/%v %v %v]", m.Height, m.Round, m.Type, m.BlockID, m.Votes) -} - -//------------------------------------- - -// ProposalHeartbeatMessage is sent to signal that a node is alive and waiting for transactions for a proposal. -type ProposalHeartbeatMessage struct { - Heartbeat *types.Heartbeat -} - -// String returns a string representation. -func (m *ProposalHeartbeatMessage) String() string { - return fmt.Sprintf("[HEARTBEAT %v]", m.Heartbeat) -} diff --git a/consensus/reactor_test.go b/consensus/reactor_test.go deleted file mode 100644 index 0d9971192..000000000 --- a/consensus/reactor_test.go +++ /dev/null @@ -1,538 +0,0 @@ -package consensus - -import ( - "context" - "fmt" - "os" - "runtime" - "runtime/pprof" - "sync" - "testing" - "time" - - "github.com/tendermint/abci/example/kvstore" - cmn "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/log" - - cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/p2p" - p2pdummy "github.com/tendermint/tendermint/p2p/dummy" - "github.com/tendermint/tendermint/types" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func init() { - config = ResetConfig("consensus_reactor_test") -} - -//---------------------------------------------- -// in-process testnets - -func startConsensusNet(t *testing.T, css []*ConsensusState, N int) ([]*ConsensusReactor, []chan interface{}, []*types.EventBus) { - reactors := make([]*ConsensusReactor, N) - eventChans := make([]chan interface{}, N) - eventBuses := make([]*types.EventBus, N) - for i := 0; i < N; i++ { - /*logger, err := tmflags.ParseLogLevel("consensus:info,*:error", logger, "info") - if err != nil { t.Fatal(err)}*/ - reactors[i] = NewConsensusReactor(css[i], true) // so we dont start the consensus states - reactors[i].SetLogger(css[i].Logger) - - // eventBus is already started with the cs - eventBuses[i] = css[i].eventBus - reactors[i].SetEventBus(eventBuses[i]) - - eventChans[i] = make(chan interface{}, 1) - err := eventBuses[i].Subscribe(context.Background(), testSubscriber, types.EventQueryNewBlock, eventChans[i]) - require.NoError(t, err) - } - // make connected switches and start all reactors - p2p.MakeConnectedSwitches(config.P2P, N, func(i int, s *p2p.Switch) *p2p.Switch { - s.AddReactor("CONSENSUS", reactors[i]) - s.SetLogger(reactors[i].conS.Logger.With("module", "p2p")) - return s - }, p2p.Connect2Switches) - - // now that everyone is connected, start the state machines - // If we started the state machines before everyone was connected, - // we'd block when the cs fires NewBlockEvent and the peers are trying to start their reactors - // TODO: is this still true with new pubsub? - for i := 0; i < N; i++ { - s := reactors[i].conS.GetState() - reactors[i].SwitchToConsensus(s, 0) - } - return reactors, eventChans, eventBuses -} - -func stopConsensusNet(logger log.Logger, reactors []*ConsensusReactor, eventBuses []*types.EventBus) { - logger.Info("stopConsensusNet", "n", len(reactors)) - for i, r := range reactors { - logger.Info("stopConsensusNet: Stopping ConsensusReactor", "i", i) - r.Switch.Stop() - } - for i, b := range eventBuses { - logger.Info("stopConsensusNet: Stopping eventBus", "i", i) - b.Stop() - } - logger.Info("stopConsensusNet: DONE", "n", len(reactors)) -} - -// Ensure a testnet makes blocks -func TestReactorBasic(t *testing.T) { - N := 4 - css := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newCounter) - reactors, eventChans, eventBuses := startConsensusNet(t, css, N) - defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses) - // wait till everyone makes the first new block - timeoutWaitGroup(t, N, func(j int) { - <-eventChans[j] - }, css) -} - -// Ensure a testnet sends proposal heartbeats and makes blocks when there are txs -func TestReactorProposalHeartbeats(t *testing.T) { - N := 4 - css := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newCounter, - func(c *cfg.Config) { - c.Consensus.CreateEmptyBlocks = false - }) - reactors, eventChans, eventBuses := startConsensusNet(t, css, N) - defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses) - heartbeatChans := make([]chan interface{}, N) - var err error - for i := 0; i < N; i++ { - heartbeatChans[i] = make(chan interface{}, 1) - err = eventBuses[i].Subscribe(context.Background(), testSubscriber, types.EventQueryProposalHeartbeat, heartbeatChans[i]) - require.NoError(t, err) - } - // wait till everyone sends a proposal heartbeat - timeoutWaitGroup(t, N, func(j int) { - <-heartbeatChans[j] - }, css) - - // send a tx - if err := css[3].mempool.CheckTx([]byte{1, 2, 3}, nil); err != nil { - //t.Fatal(err) - } - - // wait till everyone makes the first new block - timeoutWaitGroup(t, N, func(j int) { - <-eventChans[j] - }, css) -} - -// Test we record block parts from other peers -func TestReactorRecordsBlockParts(t *testing.T) { - // create dummy peer - peer := p2pdummy.NewPeer() - ps := NewPeerState(peer).SetLogger(log.TestingLogger()) - peer.Set(types.PeerStateKey, ps) - - // create reactor - css := randConsensusNet(1, "consensus_reactor_records_block_parts_test", newMockTickerFunc(true), newPersistentKVStore) - reactor := NewConsensusReactor(css[0], false) // so we dont start the consensus states - reactor.SetEventBus(css[0].eventBus) - reactor.SetLogger(log.TestingLogger()) - sw := p2p.MakeSwitch(cfg.DefaultP2PConfig(), 1, "testing", "123.123.123", func(i int, sw *p2p.Switch) *p2p.Switch { return sw }) - reactor.SetSwitch(sw) - err := reactor.Start() - require.NoError(t, err) - defer reactor.Stop() - - // 1) new block part - parts := types.NewPartSetFromData(cmn.RandBytes(100), 10) - msg := &BlockPartMessage{ - Height: 2, - Round: 0, - Part: parts.GetPart(0), - } - bz, err := cdc.MarshalBinaryBare(msg) - require.NoError(t, err) - - reactor.Receive(DataChannel, peer, bz) - require.Equal(t, 1, ps.BlockPartsSent(), "number of block parts sent should have increased by 1") - - // 2) block part with the same height, but different round - msg.Round = 1 - - bz, err = cdc.MarshalBinaryBare(msg) - require.NoError(t, err) - - reactor.Receive(DataChannel, peer, bz) - require.Equal(t, 1, ps.BlockPartsSent(), "number of block parts sent should stay the same") - - // 3) block part from earlier height - msg.Height = 1 - msg.Round = 0 - - bz, err = cdc.MarshalBinaryBare(msg) - require.NoError(t, err) - - reactor.Receive(DataChannel, peer, bz) - require.Equal(t, 1, ps.BlockPartsSent(), "number of block parts sent should stay the same") -} - -// Test we record votes from other peers -func TestReactorRecordsVotes(t *testing.T) { - // create dummy peer - peer := p2pdummy.NewPeer() - ps := NewPeerState(peer).SetLogger(log.TestingLogger()) - peer.Set(types.PeerStateKey, ps) - - // create reactor - css := randConsensusNet(1, "consensus_reactor_records_votes_test", newMockTickerFunc(true), newPersistentKVStore) - reactor := NewConsensusReactor(css[0], false) // so we dont start the consensus states - reactor.SetEventBus(css[0].eventBus) - reactor.SetLogger(log.TestingLogger()) - sw := p2p.MakeSwitch(cfg.DefaultP2PConfig(), 1, "testing", "123.123.123", func(i int, sw *p2p.Switch) *p2p.Switch { return sw }) - reactor.SetSwitch(sw) - err := reactor.Start() - require.NoError(t, err) - defer reactor.Stop() - _, val := css[0].state.Validators.GetByIndex(0) - - // 1) new vote - vote := &types.Vote{ - ValidatorIndex: 0, - ValidatorAddress: val.Address, - Height: 2, - Round: 0, - Timestamp: time.Now().UTC(), - Type: types.VoteTypePrevote, - BlockID: types.BlockID{}, - } - bz, err := cdc.MarshalBinaryBare(&VoteMessage{vote}) - require.NoError(t, err) - - reactor.Receive(VoteChannel, peer, bz) - assert.Equal(t, 1, ps.VotesSent(), "number of votes sent should have increased by 1") - - // 2) vote with the same height, but different round - vote.Round = 1 - - bz, err = cdc.MarshalBinaryBare(&VoteMessage{vote}) - require.NoError(t, err) - - reactor.Receive(VoteChannel, peer, bz) - assert.Equal(t, 1, ps.VotesSent(), "number of votes sent should stay the same") - - // 3) vote from earlier height - vote.Height = 1 - vote.Round = 0 - - bz, err = cdc.MarshalBinaryBare(&VoteMessage{vote}) - require.NoError(t, err) - - reactor.Receive(VoteChannel, peer, bz) - assert.Equal(t, 1, ps.VotesSent(), "number of votes sent should stay the same") -} - -//------------------------------------------------------------- -// ensure we can make blocks despite cycling a validator set - -func TestReactorVotingPowerChange(t *testing.T) { - nVals := 4 - logger := log.TestingLogger() - css := randConsensusNet(nVals, "consensus_voting_power_changes_test", newMockTickerFunc(true), newPersistentKVStore) - reactors, eventChans, eventBuses := startConsensusNet(t, css, nVals) - defer stopConsensusNet(logger, reactors, eventBuses) - - // map of active validators - activeVals := make(map[string]struct{}) - for i := 0; i < nVals; i++ { - activeVals[string(css[i].privValidator.GetAddress())] = struct{}{} - } - - // wait till everyone makes block 1 - timeoutWaitGroup(t, nVals, func(j int) { - <-eventChans[j] - }, css) - - //--------------------------------------------------------------------------- - logger.Debug("---------------------------- Testing changing the voting power of one validator a few times") - - val1PubKey := css[0].privValidator.GetPubKey() - val1PubKeyABCI := types.TM2PB.PubKey(val1PubKey) - updateValidatorTx := kvstore.MakeValSetChangeTx(val1PubKeyABCI, 25) - previousTotalVotingPower := css[0].GetRoundState().LastValidators.TotalVotingPower() - - waitForAndValidateBlock(t, nVals, activeVals, eventChans, css, updateValidatorTx) - waitForAndValidateBlockWithTx(t, nVals, activeVals, eventChans, css, updateValidatorTx) - waitForAndValidateBlock(t, nVals, activeVals, eventChans, css) - waitForAndValidateBlock(t, nVals, activeVals, eventChans, css) - - if css[0].GetRoundState().LastValidators.TotalVotingPower() == previousTotalVotingPower { - t.Fatalf("expected voting power to change (before: %d, after: %d)", previousTotalVotingPower, css[0].GetRoundState().LastValidators.TotalVotingPower()) - } - - updateValidatorTx = kvstore.MakeValSetChangeTx(val1PubKeyABCI, 2) - previousTotalVotingPower = css[0].GetRoundState().LastValidators.TotalVotingPower() - - waitForAndValidateBlock(t, nVals, activeVals, eventChans, css, updateValidatorTx) - waitForAndValidateBlockWithTx(t, nVals, activeVals, eventChans, css, updateValidatorTx) - waitForAndValidateBlock(t, nVals, activeVals, eventChans, css) - waitForAndValidateBlock(t, nVals, activeVals, eventChans, css) - - if css[0].GetRoundState().LastValidators.TotalVotingPower() == previousTotalVotingPower { - t.Fatalf("expected voting power to change (before: %d, after: %d)", previousTotalVotingPower, css[0].GetRoundState().LastValidators.TotalVotingPower()) - } - - updateValidatorTx = kvstore.MakeValSetChangeTx(val1PubKeyABCI, 26) - previousTotalVotingPower = css[0].GetRoundState().LastValidators.TotalVotingPower() - - waitForAndValidateBlock(t, nVals, activeVals, eventChans, css, updateValidatorTx) - waitForAndValidateBlockWithTx(t, nVals, activeVals, eventChans, css, updateValidatorTx) - waitForAndValidateBlock(t, nVals, activeVals, eventChans, css) - waitForAndValidateBlock(t, nVals, activeVals, eventChans, css) - - if css[0].GetRoundState().LastValidators.TotalVotingPower() == previousTotalVotingPower { - t.Fatalf("expected voting power to change (before: %d, after: %d)", previousTotalVotingPower, css[0].GetRoundState().LastValidators.TotalVotingPower()) - } -} - -func TestReactorValidatorSetChanges(t *testing.T) { - nPeers := 7 - nVals := 4 - css := randConsensusNetWithPeers(nVals, nPeers, "consensus_val_set_changes_test", newMockTickerFunc(true), newPersistentKVStore) - - logger := log.TestingLogger() - - reactors, eventChans, eventBuses := startConsensusNet(t, css, nPeers) - defer stopConsensusNet(logger, reactors, eventBuses) - - // map of active validators - activeVals := make(map[string]struct{}) - for i := 0; i < nVals; i++ { - activeVals[string(css[i].privValidator.GetAddress())] = struct{}{} - } - - // wait till everyone makes block 1 - timeoutWaitGroup(t, nPeers, func(j int) { - <-eventChans[j] - }, css) - - //--------------------------------------------------------------------------- - logger.Info("---------------------------- Testing adding one validator") - - newValidatorPubKey1 := css[nVals].privValidator.GetPubKey() - valPubKey1ABCI := types.TM2PB.PubKey(newValidatorPubKey1) - newValidatorTx1 := kvstore.MakeValSetChangeTx(valPubKey1ABCI, testMinPower) - - // wait till everyone makes block 2 - // ensure the commit includes all validators - // send newValTx to change vals in block 3 - waitForAndValidateBlock(t, nPeers, activeVals, eventChans, css, newValidatorTx1) - - // wait till everyone makes block 3. - // it includes the commit for block 2, which is by the original validator set - waitForAndValidateBlockWithTx(t, nPeers, activeVals, eventChans, css, newValidatorTx1) - - // wait till everyone makes block 4. - // it includes the commit for block 3, which is by the original validator set - waitForAndValidateBlock(t, nPeers, activeVals, eventChans, css) - - // the commits for block 4 should be with the updated validator set - activeVals[string(newValidatorPubKey1.Address())] = struct{}{} - - // wait till everyone makes block 5 - // it includes the commit for block 4, which should have the updated validator set - waitForBlockWithUpdatedValsAndValidateIt(t, nPeers, activeVals, eventChans, css) - - //--------------------------------------------------------------------------- - logger.Info("---------------------------- Testing changing the voting power of one validator") - - updateValidatorPubKey1 := css[nVals].privValidator.GetPubKey() - updatePubKey1ABCI := types.TM2PB.PubKey(updateValidatorPubKey1) - updateValidatorTx1 := kvstore.MakeValSetChangeTx(updatePubKey1ABCI, 25) - previousTotalVotingPower := css[nVals].GetRoundState().LastValidators.TotalVotingPower() - - waitForAndValidateBlock(t, nPeers, activeVals, eventChans, css, updateValidatorTx1) - waitForAndValidateBlockWithTx(t, nPeers, activeVals, eventChans, css, updateValidatorTx1) - waitForAndValidateBlock(t, nPeers, activeVals, eventChans, css) - waitForBlockWithUpdatedValsAndValidateIt(t, nPeers, activeVals, eventChans, css) - - if css[nVals].GetRoundState().LastValidators.TotalVotingPower() == previousTotalVotingPower { - t.Errorf("expected voting power to change (before: %d, after: %d)", previousTotalVotingPower, css[nVals].GetRoundState().LastValidators.TotalVotingPower()) - } - - //--------------------------------------------------------------------------- - logger.Info("---------------------------- Testing adding two validators at once") - - newValidatorPubKey2 := css[nVals+1].privValidator.GetPubKey() - newVal2ABCI := types.TM2PB.PubKey(newValidatorPubKey2) - newValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, testMinPower) - - newValidatorPubKey3 := css[nVals+2].privValidator.GetPubKey() - newVal3ABCI := types.TM2PB.PubKey(newValidatorPubKey3) - newValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, testMinPower) - - waitForAndValidateBlock(t, nPeers, activeVals, eventChans, css, newValidatorTx2, newValidatorTx3) - waitForAndValidateBlockWithTx(t, nPeers, activeVals, eventChans, css, newValidatorTx2, newValidatorTx3) - waitForAndValidateBlock(t, nPeers, activeVals, eventChans, css) - activeVals[string(newValidatorPubKey2.Address())] = struct{}{} - activeVals[string(newValidatorPubKey3.Address())] = struct{}{} - waitForBlockWithUpdatedValsAndValidateIt(t, nPeers, activeVals, eventChans, css) - - //--------------------------------------------------------------------------- - logger.Info("---------------------------- Testing removing two validators at once") - - removeValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, 0) - removeValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, 0) - - waitForAndValidateBlock(t, nPeers, activeVals, eventChans, css, removeValidatorTx2, removeValidatorTx3) - waitForAndValidateBlockWithTx(t, nPeers, activeVals, eventChans, css, removeValidatorTx2, removeValidatorTx3) - waitForAndValidateBlock(t, nPeers, activeVals, eventChans, css) - delete(activeVals, string(newValidatorPubKey2.Address())) - delete(activeVals, string(newValidatorPubKey3.Address())) - waitForBlockWithUpdatedValsAndValidateIt(t, nPeers, activeVals, eventChans, css) -} - -// Check we can make blocks with skip_timeout_commit=false -func TestReactorWithTimeoutCommit(t *testing.T) { - N := 4 - css := randConsensusNet(N, "consensus_reactor_with_timeout_commit_test", newMockTickerFunc(false), newCounter) - // override default SkipTimeoutCommit == true for tests - for i := 0; i < N; i++ { - css[i].config.SkipTimeoutCommit = false - } - - reactors, eventChans, eventBuses := startConsensusNet(t, css, N-1) - defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses) - - // wait till everyone makes the first new block - timeoutWaitGroup(t, N-1, func(j int) { - <-eventChans[j] - }, css) -} - -func waitForAndValidateBlock(t *testing.T, n int, activeVals map[string]struct{}, eventChans []chan interface{}, css []*ConsensusState, txs ...[]byte) { - timeoutWaitGroup(t, n, func(j int) { - css[j].Logger.Debug("waitForAndValidateBlock") - newBlockI, ok := <-eventChans[j] - if !ok { - return - } - newBlock := newBlockI.(types.EventDataNewBlock).Block - css[j].Logger.Debug("waitForAndValidateBlock: Got block", "height", newBlock.Height) - err := validateBlock(newBlock, activeVals) - assert.Nil(t, err) - for _, tx := range txs { - css[j].mempool.CheckTx(tx, nil) - assert.Nil(t, err) - } - }, css) -} - -func waitForAndValidateBlockWithTx(t *testing.T, n int, activeVals map[string]struct{}, eventChans []chan interface{}, css []*ConsensusState, txs ...[]byte) { - timeoutWaitGroup(t, n, func(j int) { - ntxs := 0 - BLOCK_TX_LOOP: - for { - css[j].Logger.Debug("waitForAndValidateBlockWithTx", "ntxs", ntxs) - newBlockI, ok := <-eventChans[j] - if !ok { - return - } - newBlock := newBlockI.(types.EventDataNewBlock).Block - css[j].Logger.Debug("waitForAndValidateBlockWithTx: Got block", "height", newBlock.Height) - err := validateBlock(newBlock, activeVals) - assert.Nil(t, err) - - // check that txs match the txs we're waiting for. - // note they could be spread over multiple blocks, - // but they should be in order. - for _, tx := range newBlock.Data.Txs { - assert.EqualValues(t, txs[ntxs], tx) - ntxs++ - } - - if ntxs == len(txs) { - break BLOCK_TX_LOOP - } - } - - }, css) -} - -func waitForBlockWithUpdatedValsAndValidateIt(t *testing.T, n int, updatedVals map[string]struct{}, eventChans []chan interface{}, css []*ConsensusState) { - timeoutWaitGroup(t, n, func(j int) { - - var newBlock *types.Block - LOOP: - for { - css[j].Logger.Debug("waitForBlockWithUpdatedValsAndValidateIt") - newBlockI, ok := <-eventChans[j] - if !ok { - return - } - newBlock = newBlockI.(types.EventDataNewBlock).Block - if newBlock.LastCommit.Size() == len(updatedVals) { - css[j].Logger.Debug("waitForBlockWithUpdatedValsAndValidateIt: Got block", "height", newBlock.Height) - break LOOP - } else { - css[j].Logger.Debug("waitForBlockWithUpdatedValsAndValidateIt: Got block with no new validators. Skipping", "height", newBlock.Height) - } - } - - err := validateBlock(newBlock, updatedVals) - assert.Nil(t, err) - }, css) -} - -// expects high synchrony! -func validateBlock(block *types.Block, activeVals map[string]struct{}) error { - if block.LastCommit.Size() != len(activeVals) { - return fmt.Errorf("Commit size doesn't match number of active validators. Got %d, expected %d", block.LastCommit.Size(), len(activeVals)) - } - - for _, vote := range block.LastCommit.Precommits { - if _, ok := activeVals[string(vote.ValidatorAddress)]; !ok { - return fmt.Errorf("Found vote for unactive validator %X", vote.ValidatorAddress) - } - } - return nil -} - -func timeoutWaitGroup(t *testing.T, n int, f func(int), css []*ConsensusState) { - wg := new(sync.WaitGroup) - wg.Add(n) - for i := 0; i < n; i++ { - go func(j int) { - f(j) - wg.Done() - }(i) - } - - done := make(chan struct{}) - go func() { - wg.Wait() - close(done) - }() - - // we're running many nodes in-process, possibly in in a virtual machine, - // and spewing debug messages - making a block could take a while, - timeout := time.Second * 300 - - select { - case <-done: - case <-time.After(timeout): - for i, cs := range css { - t.Log("#################") - t.Log("Validator", i) - t.Log(cs.GetRoundState()) - t.Log("") - } - os.Stdout.Write([]byte("pprof.Lookup('goroutine'):\n")) - pprof.Lookup("goroutine").WriteTo(os.Stdout, 1) - capture() - panic("Timed out waiting for all validators to commit a block") - } -} - -func capture() { - trace := make([]byte, 10240000) - count := runtime.Stack(trace, true) - fmt.Printf("Stack of %d bytes: %s\n", count, trace) -} diff --git a/consensus/replay.go b/consensus/replay.go deleted file mode 100644 index 13ec9e403..000000000 --- a/consensus/replay.go +++ /dev/null @@ -1,469 +0,0 @@ -package consensus - -import ( - "bytes" - "fmt" - "hash/crc32" - "io" - "reflect" - //"strconv" - //"strings" - "time" - - abci "github.com/tendermint/abci/types" - //auto "github.com/tendermint/tmlibs/autofile" - cmn "github.com/tendermint/tmlibs/common" - dbm "github.com/tendermint/tmlibs/db" - "github.com/tendermint/tmlibs/log" - - "github.com/tendermint/tendermint/proxy" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/version" -) - -var crc32c = crc32.MakeTable(crc32.Castagnoli) - -// Functionality to replay blocks and messages on recovery from a crash. -// There are two general failure scenarios: -// -// 1. failure during consensus -// 2. failure while applying the block -// -// The former is handled by the WAL, the latter by the proxyApp Handshake on -// restart, which ultimately hands off the work to the WAL. - -//----------------------------------------- -// 1. Recover from failure during consensus -// (by replaying messages from the WAL) -//----------------------------------------- - -// Unmarshal and apply a single message to the consensus state as if it were -// received in receiveRoutine. Lines that start with "#" are ignored. -// NOTE: receiveRoutine should not be running. -func (cs *ConsensusState) readReplayMessage(msg *TimedWALMessage, newStepCh chan interface{}) error { - // Skip meta messages which exist for demarcating boundaries. - if _, ok := msg.Msg.(EndHeightMessage); ok { - return nil - } - - // for logging - switch m := msg.Msg.(type) { - case types.EventDataRoundState: - cs.Logger.Info("Replay: New Step", "height", m.Height, "round", m.Round, "step", m.Step) - // these are playback checks - ticker := time.After(time.Second * 2) - if newStepCh != nil { - select { - case mi := <-newStepCh: - m2 := mi.(types.EventDataRoundState) - if m.Height != m2.Height || m.Round != m2.Round || m.Step != m2.Step { - return fmt.Errorf("RoundState mismatch. Got %v; Expected %v", m2, m) - } - case <-ticker: - return fmt.Errorf("Failed to read off newStepCh") - } - } - case msgInfo: - peerID := m.PeerID - if peerID == "" { - peerID = "local" - } - switch msg := m.Msg.(type) { - case *ProposalMessage: - p := msg.Proposal - cs.Logger.Info("Replay: Proposal", "height", p.Height, "round", p.Round, "header", - p.BlockPartsHeader, "pol", p.POLRound, "peer", peerID) - case *BlockPartMessage: - cs.Logger.Info("Replay: BlockPart", "height", msg.Height, "round", msg.Round, "peer", peerID) - case *VoteMessage: - v := msg.Vote - cs.Logger.Info("Replay: Vote", "height", v.Height, "round", v.Round, "type", v.Type, - "blockID", v.BlockID, "peer", peerID) - } - - cs.handleMsg(m) - case timeoutInfo: - cs.Logger.Info("Replay: Timeout", "height", m.Height, "round", m.Round, "step", m.Step, "dur", m.Duration) - cs.handleTimeout(m, cs.RoundState) - default: - return fmt.Errorf("Replay: Unknown TimedWALMessage type: %v", reflect.TypeOf(msg.Msg)) - } - return nil -} - -// Replay only those messages since the last block. `timeoutRoutine` should -// run concurrently to read off tickChan. -func (cs *ConsensusState) catchupReplay(csHeight int64) error { - - // Set replayMode to true so we don't log signing errors. - cs.replayMode = true - defer func() { cs.replayMode = false }() - - // Ensure that #ENDHEIGHT for this height doesn't exist. - // NOTE: This is just a sanity check. As far as we know things work fine - // without it, and Handshake could reuse ConsensusState if it weren't for - // this check (since we can crash after writing #ENDHEIGHT). - // - // Ignore data corruption errors since this is a sanity check. - gr, found, err := cs.wal.SearchForEndHeight(csHeight, &WALSearchOptions{IgnoreDataCorruptionErrors: true}) - if err != nil { - return err - } - if gr != nil { - if err := gr.Close(); err != nil { - return err - } - } - if found { - return fmt.Errorf("WAL should not contain #ENDHEIGHT %d", csHeight) - } - - // Search for last height marker. - // - // Ignore data corruption errors in previous heights because we only care about last height - gr, found, err = cs.wal.SearchForEndHeight(csHeight-1, &WALSearchOptions{IgnoreDataCorruptionErrors: true}) - if err == io.EOF { - cs.Logger.Error("Replay: wal.group.Search returned EOF", "#ENDHEIGHT", csHeight-1) - } else if err != nil { - return err - } - if !found { - return fmt.Errorf("Cannot replay height %d. WAL does not contain #ENDHEIGHT for %d", csHeight, csHeight-1) - } - defer gr.Close() // nolint: errcheck - - cs.Logger.Info("Catchup by replaying consensus messages", "height", csHeight) - - var msg *TimedWALMessage - dec := WALDecoder{gr} - - for { - msg, err = dec.Decode() - if err == io.EOF { - break - } else if IsDataCorruptionError(err) { - cs.Logger.Debug("data has been corrupted in last height of consensus WAL", "err", err, "height", csHeight) - panic(fmt.Sprintf("data has been corrupted (%v) in last height %d of consensus WAL", err, csHeight)) - } else if err != nil { - return err - } - - // NOTE: since the priv key is set when the msgs are received - // it will attempt to eg double sign but we can just ignore it - // since the votes will be replayed and we'll get to the next step - if err := cs.readReplayMessage(msg, nil); err != nil { - return err - } - } - cs.Logger.Info("Replay: Done") - return nil -} - -//-------------------------------------------------------------------------------- - -// Parses marker lines of the form: -// #ENDHEIGHT: 12345 -/* -func makeHeightSearchFunc(height int64) auto.SearchFunc { - return func(line string) (int, error) { - line = strings.TrimRight(line, "\n") - parts := strings.Split(line, " ") - if len(parts) != 2 { - return -1, errors.New("Line did not have 2 parts") - } - i, err := strconv.Atoi(parts[1]) - if err != nil { - return -1, errors.New("Failed to parse INFO: " + err.Error()) - } - if height < i { - return 1, nil - } else if height == i { - return 0, nil - } else { - return -1, nil - } - } -}*/ - -//--------------------------------------------------- -// 2. Recover from failure while applying the block. -// (by handshaking with the app to figure out where -// we were last, and using the WAL to recover there.) -//--------------------------------------------------- - -type Handshaker struct { - stateDB dbm.DB - initialState sm.State - store sm.BlockStore - genDoc *types.GenesisDoc - logger log.Logger - - nBlocks int // number of blocks applied to the state -} - -func NewHandshaker(stateDB dbm.DB, state sm.State, - store sm.BlockStore, genDoc *types.GenesisDoc) *Handshaker { - - return &Handshaker{ - stateDB: stateDB, - initialState: state, - store: store, - genDoc: genDoc, - logger: log.NewNopLogger(), - nBlocks: 0, - } -} - -func (h *Handshaker) SetLogger(l log.Logger) { - h.logger = l -} - -func (h *Handshaker) NBlocks() int { - return h.nBlocks -} - -// TODO: retry the handshake/replay if it fails ? -func (h *Handshaker) Handshake(proxyApp proxy.AppConns) error { - - // Handshake is done via ABCI Info on the query conn. - res, err := proxyApp.Query().InfoSync(abci.RequestInfo{version.Version}) - if err != nil { - return fmt.Errorf("Error calling Info: %v", err) - } - - blockHeight := int64(res.LastBlockHeight) - if blockHeight < 0 { - return fmt.Errorf("Got a negative last block height (%d) from the app", blockHeight) - } - appHash := res.LastBlockAppHash - - h.logger.Info("ABCI Handshake", "appHeight", blockHeight, "appHash", fmt.Sprintf("%X", appHash)) - - // TODO: check app version. - - // Replay blocks up to the latest in the blockstore. - _, err = h.ReplayBlocks(h.initialState, appHash, blockHeight, proxyApp) - if err != nil { - return fmt.Errorf("Error on replay: %v", err) - } - - h.logger.Info("Completed ABCI Handshake - Tendermint and App are synced", - "appHeight", blockHeight, "appHash", fmt.Sprintf("%X", appHash)) - - // TODO: (on restart) replay mempool - - return nil -} - -// Replay all blocks since appBlockHeight and ensure the result matches the current state. -// Returns the final AppHash or an error. -func (h *Handshaker) ReplayBlocks(state sm.State, appHash []byte, appBlockHeight int64, proxyApp proxy.AppConns) ([]byte, error) { - - storeBlockHeight := h.store.Height() - stateBlockHeight := state.LastBlockHeight - h.logger.Info("ABCI Replay Blocks", "appHeight", appBlockHeight, "storeHeight", storeBlockHeight, "stateHeight", stateBlockHeight) - - // If appBlockHeight == 0 it means that we are at genesis and hence should send InitChain - if appBlockHeight == 0 { - validators := types.TM2PB.Validators(state.Validators) - csParams := types.TM2PB.ConsensusParams(h.genDoc.ConsensusParams) - req := abci.RequestInitChain{ - Time: h.genDoc.GenesisTime.Unix(), // TODO - ChainId: h.genDoc.ChainID, - ConsensusParams: csParams, - Validators: validators, - AppStateBytes: h.genDoc.AppStateJSON, - } - res, err := proxyApp.Consensus().InitChainSync(req) - if err != nil { - return nil, err - } - - // if the app returned validators - // or consensus params, update the state - // with the them - if len(res.Validators) > 0 { - vals, err := types.PB2TM.Validators(res.Validators) - if err != nil { - return nil, err - } - state.Validators = types.NewValidatorSet(vals) - } - if res.ConsensusParams != nil { - state.ConsensusParams = types.PB2TM.ConsensusParams(res.ConsensusParams) - } - sm.SaveState(h.stateDB, state) - } - - // First handle edge cases and constraints on the storeBlockHeight - if storeBlockHeight == 0 { - return appHash, checkAppHash(state, appHash) - - } else if storeBlockHeight < appBlockHeight { - // the app should never be ahead of the store (but this is under app's control) - return appHash, sm.ErrAppBlockHeightTooHigh{storeBlockHeight, appBlockHeight} - - } else if storeBlockHeight < stateBlockHeight { - // the state should never be ahead of the store (this is under tendermint's control) - cmn.PanicSanity(cmn.Fmt("StateBlockHeight (%d) > StoreBlockHeight (%d)", stateBlockHeight, storeBlockHeight)) - - } else if storeBlockHeight > stateBlockHeight+1 { - // store should be at most one ahead of the state (this is under tendermint's control) - cmn.PanicSanity(cmn.Fmt("StoreBlockHeight (%d) > StateBlockHeight + 1 (%d)", storeBlockHeight, stateBlockHeight+1)) - } - - var err error - // Now either store is equal to state, or one ahead. - // For each, consider all cases of where the app could be, given app <= store - if storeBlockHeight == stateBlockHeight { - // Tendermint ran Commit and saved the state. - // Either the app is asking for replay, or we're all synced up. - if appBlockHeight < storeBlockHeight { - // the app is behind, so replay blocks, but no need to go through WAL (state is already synced to store) - return h.replayBlocks(state, proxyApp, appBlockHeight, storeBlockHeight, false) - - } else if appBlockHeight == storeBlockHeight { - // We're good! - return appHash, checkAppHash(state, appHash) - } - - } else if storeBlockHeight == stateBlockHeight+1 { - // We saved the block in the store but haven't updated the state, - // so we'll need to replay a block using the WAL. - if appBlockHeight < stateBlockHeight { - // the app is further behind than it should be, so replay blocks - // but leave the last block to go through the WAL - return h.replayBlocks(state, proxyApp, appBlockHeight, storeBlockHeight, true) - - } else if appBlockHeight == stateBlockHeight { - // We haven't run Commit (both the state and app are one block behind), - // so replayBlock with the real app. - // NOTE: We could instead use the cs.WAL on cs.Start, - // but we'd have to allow the WAL to replay a block that wrote it's #ENDHEIGHT - h.logger.Info("Replay last block using real app") - state, err = h.replayBlock(state, storeBlockHeight, proxyApp.Consensus()) - return state.AppHash, err - - } else if appBlockHeight == storeBlockHeight { - // We ran Commit, but didn't save the state, so replayBlock with mock app - abciResponses, err := sm.LoadABCIResponses(h.stateDB, storeBlockHeight) - if err != nil { - return nil, err - } - mockApp := newMockProxyApp(appHash, abciResponses) - h.logger.Info("Replay last block using mock app") - state, err = h.replayBlock(state, storeBlockHeight, mockApp) - return state.AppHash, err - } - - } - - cmn.PanicSanity("Should never happen") - return nil, nil -} - -func (h *Handshaker) replayBlocks(state sm.State, proxyApp proxy.AppConns, appBlockHeight, storeBlockHeight int64, mutateState bool) ([]byte, error) { - // App is further behind than it should be, so we need to replay blocks. - // We replay all blocks from appBlockHeight+1. - // - // Note that we don't have an old version of the state, - // so we by-pass state validation/mutation using sm.ExecCommitBlock. - // This also means we won't be saving validator sets if they change during this period. - // TODO: Load the historical information to fix this and just use state.ApplyBlock - // - // If mutateState == true, the final block is replayed with h.replayBlock() - - var appHash []byte - var err error - finalBlock := storeBlockHeight - if mutateState { - finalBlock-- - } - for i := appBlockHeight + 1; i <= finalBlock; i++ { - h.logger.Info("Applying block", "height", i) - block := h.store.LoadBlock(i) - appHash, err = sm.ExecCommitBlock(proxyApp.Consensus(), block, h.logger, state.LastValidators, h.stateDB) - if err != nil { - return nil, err - } - - h.nBlocks++ - } - - if mutateState { - // sync the final block - state, err = h.replayBlock(state, storeBlockHeight, proxyApp.Consensus()) - if err != nil { - return nil, err - } - appHash = state.AppHash - } - - return appHash, checkAppHash(state, appHash) -} - -// ApplyBlock on the proxyApp with the last block. -func (h *Handshaker) replayBlock(state sm.State, height int64, proxyApp proxy.AppConnConsensus) (sm.State, error) { - block := h.store.LoadBlock(height) - meta := h.store.LoadBlockMeta(height) - - blockExec := sm.NewBlockExecutor(h.stateDB, h.logger, proxyApp, sm.MockMempool{}, sm.MockEvidencePool{}) - - var err error - state, err = blockExec.ApplyBlock(state, meta.BlockID, block) - if err != nil { - return sm.State{}, err - } - - h.nBlocks++ - - return state, nil -} - -func checkAppHash(state sm.State, appHash []byte) error { - if !bytes.Equal(state.AppHash, appHash) { - panic(fmt.Errorf("Tendermint state.AppHash does not match AppHash after replay. Got %X, expected %X", appHash, state.AppHash).Error()) - } - return nil -} - -//-------------------------------------------------------------------------------- -// mockProxyApp uses ABCIResponses to give the right results -// Useful because we don't want to call Commit() twice for the same block on the real app. - -func newMockProxyApp(appHash []byte, abciResponses *sm.ABCIResponses) proxy.AppConnConsensus { - clientCreator := proxy.NewLocalClientCreator(&mockProxyApp{ - appHash: appHash, - abciResponses: abciResponses, - }) - cli, _ := clientCreator.NewABCIClient() - err := cli.Start() - if err != nil { - panic(err) - } - return proxy.NewAppConnConsensus(cli) -} - -type mockProxyApp struct { - abci.BaseApplication - - appHash []byte - txCount int - abciResponses *sm.ABCIResponses -} - -func (mock *mockProxyApp) DeliverTx(tx []byte) abci.ResponseDeliverTx { - r := mock.abciResponses.DeliverTx[mock.txCount] - mock.txCount++ - return *r -} - -func (mock *mockProxyApp) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock { - mock.txCount = 0 - return *mock.abciResponses.EndBlock -} - -func (mock *mockProxyApp) Commit() abci.ResponseCommit { - return abci.ResponseCommit{Data: mock.appHash} -} diff --git a/consensus/replay_file.go b/consensus/replay_file.go deleted file mode 100644 index 57204b01a..000000000 --- a/consensus/replay_file.go +++ /dev/null @@ -1,321 +0,0 @@ -package consensus - -import ( - "bufio" - "context" - "fmt" - "io" - "os" - "strconv" - "strings" - - "github.com/pkg/errors" - - bc "github.com/tendermint/tendermint/blockchain" - cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/proxy" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tmlibs/common" - dbm "github.com/tendermint/tmlibs/db" - "github.com/tendermint/tmlibs/log" -) - -const ( - // event bus subscriber - subscriber = "replay-file" -) - -//-------------------------------------------------------- -// replay messages interactively or all at once - -// replay the wal file -func RunReplayFile(config cfg.BaseConfig, csConfig *cfg.ConsensusConfig, console bool) { - consensusState := newConsensusStateForReplay(config, csConfig) - - if err := consensusState.ReplayFile(csConfig.WalFile(), console); err != nil { - cmn.Exit(cmn.Fmt("Error during consensus replay: %v", err)) - } -} - -// Replay msgs in file or start the console -func (cs *ConsensusState) ReplayFile(file string, console bool) error { - - if cs.IsRunning() { - return errors.New("cs is already running, cannot replay") - } - if cs.wal != nil { - return errors.New("cs wal is open, cannot replay") - } - - cs.startForReplay() - - // ensure all new step events are regenerated as expected - newStepCh := make(chan interface{}, 1) - - ctx := context.Background() - err := cs.eventBus.Subscribe(ctx, subscriber, types.EventQueryNewRoundStep, newStepCh) - if err != nil { - return errors.Errorf("failed to subscribe %s to %v", subscriber, types.EventQueryNewRoundStep) - } - defer cs.eventBus.Unsubscribe(ctx, subscriber, types.EventQueryNewRoundStep) - - // just open the file for reading, no need to use wal - fp, err := os.OpenFile(file, os.O_RDONLY, 0600) - if err != nil { - return err - } - - pb := newPlayback(file, fp, cs, cs.state.Copy()) - defer pb.fp.Close() // nolint: errcheck - - var nextN int // apply N msgs in a row - var msg *TimedWALMessage - for { - if nextN == 0 && console { - nextN = pb.replayConsoleLoop() - } - - msg, err = pb.dec.Decode() - if err == io.EOF { - return nil - } else if err != nil { - return err - } - - if err := pb.cs.readReplayMessage(msg, newStepCh); err != nil { - return err - } - - if nextN > 0 { - nextN-- - } - pb.count++ - } - return nil -} - -//------------------------------------------------ -// playback manager - -type playback struct { - cs *ConsensusState - - fp *os.File - dec *WALDecoder - count int // how many lines/msgs into the file are we - - // replays can be reset to beginning - fileName string // so we can close/reopen the file - genesisState sm.State // so the replay session knows where to restart from -} - -func newPlayback(fileName string, fp *os.File, cs *ConsensusState, genState sm.State) *playback { - return &playback{ - cs: cs, - fp: fp, - fileName: fileName, - genesisState: genState, - dec: NewWALDecoder(fp), - } -} - -// go back count steps by resetting the state and running (pb.count - count) steps -func (pb *playback) replayReset(count int, newStepCh chan interface{}) error { - pb.cs.Stop() - pb.cs.Wait() - - newCS := NewConsensusState(pb.cs.config, pb.genesisState.Copy(), pb.cs.blockExec, - pb.cs.blockStore, pb.cs.mempool, pb.cs.evpool) - newCS.SetEventBus(pb.cs.eventBus) - newCS.startForReplay() - - if err := pb.fp.Close(); err != nil { - return err - } - fp, err := os.OpenFile(pb.fileName, os.O_RDONLY, 0600) - if err != nil { - return err - } - pb.fp = fp - pb.dec = NewWALDecoder(fp) - count = pb.count - count - fmt.Printf("Reseting from %d to %d\n", pb.count, count) - pb.count = 0 - pb.cs = newCS - var msg *TimedWALMessage - for i := 0; i < count; i++ { - msg, err = pb.dec.Decode() - if err == io.EOF { - return nil - } else if err != nil { - return err - } - if err := pb.cs.readReplayMessage(msg, newStepCh); err != nil { - return err - } - pb.count++ - } - return nil -} - -func (cs *ConsensusState) startForReplay() { - cs.Logger.Error("Replay commands are disabled until someone updates them and writes tests") - /* TODO:! - // since we replay tocks we just ignore ticks - go func() { - for { - select { - case <-cs.tickChan: - case <-cs.Quit: - return - } - } - }()*/ -} - -// console function for parsing input and running commands -func (pb *playback) replayConsoleLoop() int { - for { - fmt.Printf("> ") - bufReader := bufio.NewReader(os.Stdin) - line, more, err := bufReader.ReadLine() - if more { - cmn.Exit("input is too long") - } else if err != nil { - cmn.Exit(err.Error()) - } - - tokens := strings.Split(string(line), " ") - if len(tokens) == 0 { - continue - } - - switch tokens[0] { - case "next": - // "next" -> replay next message - // "next N" -> replay next N messages - - if len(tokens) == 1 { - return 0 - } - i, err := strconv.Atoi(tokens[1]) - if err != nil { - fmt.Println("next takes an integer argument") - } else { - return i - } - - case "back": - // "back" -> go back one message - // "back N" -> go back N messages - - // NOTE: "back" is not supported in the state machine design, - // so we restart and replay up to - - ctx := context.Background() - // ensure all new step events are regenerated as expected - newStepCh := make(chan interface{}, 1) - - err := pb.cs.eventBus.Subscribe(ctx, subscriber, types.EventQueryNewRoundStep, newStepCh) - if err != nil { - cmn.Exit(fmt.Sprintf("failed to subscribe %s to %v", subscriber, types.EventQueryNewRoundStep)) - } - defer pb.cs.eventBus.Unsubscribe(ctx, subscriber, types.EventQueryNewRoundStep) - - if len(tokens) == 1 { - if err := pb.replayReset(1, newStepCh); err != nil { - pb.cs.Logger.Error("Replay reset error", "err", err) - } - } else { - i, err := strconv.Atoi(tokens[1]) - if err != nil { - fmt.Println("back takes an integer argument") - } else if i > pb.count { - fmt.Printf("argument to back must not be larger than the current count (%d)\n", pb.count) - } else { - if err := pb.replayReset(i, newStepCh); err != nil { - pb.cs.Logger.Error("Replay reset error", "err", err) - } - } - } - - case "rs": - // "rs" -> print entire round state - // "rs short" -> print height/round/step - // "rs " -> print another field of the round state - - rs := pb.cs.RoundState - if len(tokens) == 1 { - fmt.Println(rs) - } else { - switch tokens[1] { - case "short": - fmt.Printf("%v/%v/%v\n", rs.Height, rs.Round, rs.Step) - case "validators": - fmt.Println(rs.Validators) - case "proposal": - fmt.Println(rs.Proposal) - case "proposal_block": - fmt.Printf("%v %v\n", rs.ProposalBlockParts.StringShort(), rs.ProposalBlock.StringShort()) - case "locked_round": - fmt.Println(rs.LockedRound) - case "locked_block": - fmt.Printf("%v %v\n", rs.LockedBlockParts.StringShort(), rs.LockedBlock.StringShort()) - case "votes": - fmt.Println(rs.Votes.StringIndented(" ")) - - default: - fmt.Println("Unknown option", tokens[1]) - } - } - case "n": - fmt.Println(pb.count) - } - } - return 0 -} - -//-------------------------------------------------------------------------------- - -// convenience for replay mode -func newConsensusStateForReplay(config cfg.BaseConfig, csConfig *cfg.ConsensusConfig) *ConsensusState { - dbType := dbm.DBBackendType(config.DBBackend) - // Get BlockStore - blockStoreDB := dbm.NewDB("blockstore", dbType, config.DBDir()) - blockStore := bc.NewBlockStore(blockStoreDB) - - // Get State - stateDB := dbm.NewDB("state", dbType, config.DBDir()) - gdoc, err := sm.MakeGenesisDocFromFile(config.GenesisFile()) - if err != nil { - cmn.Exit(err.Error()) - } - state, err := sm.MakeGenesisState(gdoc) - if err != nil { - cmn.Exit(err.Error()) - } - - // Create proxyAppConn connection (consensus, mempool, query) - clientCreator := proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()) - proxyApp := proxy.NewAppConns(clientCreator, - NewHandshaker(stateDB, state, blockStore, gdoc)) - err = proxyApp.Start() - if err != nil { - cmn.Exit(cmn.Fmt("Error starting proxy app conns: %v", err)) - } - - eventBus := types.NewEventBus() - if err := eventBus.Start(); err != nil { - cmn.Exit(cmn.Fmt("Failed to start event bus: %v", err)) - } - - mempool, evpool := sm.MockMempool{}, sm.MockEvidencePool{} - blockExec := sm.NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(), mempool, evpool) - - consensusState := NewConsensusState(csConfig, state.Copy(), blockExec, - blockStore, mempool, evpool) - - consensusState.SetEventBus(eventBus) - return consensusState -} diff --git a/consensus/replay_test.go b/consensus/replay_test.go deleted file mode 100644 index 725568ed5..000000000 --- a/consensus/replay_test.go +++ /dev/null @@ -1,687 +0,0 @@ -package consensus - -import ( - "bytes" - "context" - "errors" - "fmt" - "io" - "io/ioutil" - "os" - "path" - "runtime" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/tendermint/abci/example/kvstore" - abci "github.com/tendermint/abci/types" - crypto "github.com/tendermint/go-crypto" - auto "github.com/tendermint/tmlibs/autofile" - cmn "github.com/tendermint/tmlibs/common" - dbm "github.com/tendermint/tmlibs/db" - - cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/privval" - "github.com/tendermint/tendermint/proxy" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tmlibs/log" -) - -var consensusReplayConfig *cfg.Config - -func init() { - consensusReplayConfig = ResetConfig("consensus_replay_test") -} - -// These tests ensure we can always recover from failure at any part of the consensus process. -// There are two general failure scenarios: failure during consensus, and failure while applying the block. -// Only the latter interacts with the app and store, -// but the former has to deal with restrictions on re-use of priv_validator keys. -// The `WAL Tests` are for failures during the consensus; -// the `Handshake Tests` are for failures in applying the block. -// With the help of the WAL, we can recover from it all! - -//------------------------------------------------------------------------------------------ -// WAL Tests - -// TODO: It would be better to verify explicitly which states we can recover from without the wal -// and which ones we need the wal for - then we'd also be able to only flush the -// wal writer when we need to, instead of with every message. - -func startNewConsensusStateAndWaitForBlock(t *testing.T, lastBlockHeight int64, blockDB dbm.DB, stateDB dbm.DB) { - logger := log.TestingLogger() - state, _ := sm.LoadStateFromDBOrGenesisFile(stateDB, consensusReplayConfig.GenesisFile()) - privValidator := loadPrivValidator(consensusReplayConfig) - cs := newConsensusStateWithConfigAndBlockStore(consensusReplayConfig, state, privValidator, kvstore.NewKVStoreApplication(), blockDB) - cs.SetLogger(logger) - - bytes, _ := ioutil.ReadFile(cs.config.WalFile()) - // fmt.Printf("====== WAL: \n\r%s\n", bytes) - t.Logf("====== WAL: \n\r%X\n", bytes) - - err := cs.Start() - require.NoError(t, err) - defer cs.Stop() - - // This is just a signal that we haven't halted; its not something contained - // in the WAL itself. Assuming the consensus state is running, replay of any - // WAL, including the empty one, should eventually be followed by a new - // block, or else something is wrong. - newBlockCh := make(chan interface{}, 1) - err = cs.eventBus.Subscribe(context.Background(), testSubscriber, types.EventQueryNewBlock, newBlockCh) - require.NoError(t, err) - select { - case <-newBlockCh: - case <-time.After(60 * time.Second): - t.Fatalf("Timed out waiting for new block (see trace above)") - } -} - -func sendTxs(cs *ConsensusState, ctx context.Context) { - for i := 0; i < 256; i++ { - select { - case <-ctx.Done(): - return - default: - tx := []byte{byte(i)} - cs.mempool.CheckTx(tx, nil) - i++ - } - } -} - -// TestWALCrash uses crashing WAL to test we can recover from any WAL failure. -func TestWALCrash(t *testing.T) { - testCases := []struct { - name string - initFn func(dbm.DB, *ConsensusState, context.Context) - heightToStop int64 - }{ - {"empty block", - func(stateDB dbm.DB, cs *ConsensusState, ctx context.Context) {}, - 1}, - {"block with a smaller part size", - func(stateDB dbm.DB, cs *ConsensusState, ctx context.Context) { - // XXX: is there a better way to change BlockPartSizeBytes? - cs.state.ConsensusParams.BlockPartSizeBytes = 512 - sm.SaveState(stateDB, cs.state) - go sendTxs(cs, ctx) - }, - 1}, - {"many non-empty blocks", - func(stateDB dbm.DB, cs *ConsensusState, ctx context.Context) { - go sendTxs(cs, ctx) - }, - 3}, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - crashWALandCheckLiveness(t, tc.initFn, tc.heightToStop) - }) - } -} - -func crashWALandCheckLiveness(t *testing.T, initFn func(dbm.DB, *ConsensusState, context.Context), heightToStop int64) { - walPaniced := make(chan error) - crashingWal := &crashingWAL{panicCh: walPaniced, heightToStop: heightToStop} - - i := 1 -LOOP: - for { - // fmt.Printf("====== LOOP %d\n", i) - t.Logf("====== LOOP %d\n", i) - - // create consensus state from a clean slate - logger := log.NewNopLogger() - stateDB := dbm.NewMemDB() - state, _ := sm.MakeGenesisStateFromFile(consensusReplayConfig.GenesisFile()) - privValidator := loadPrivValidator(consensusReplayConfig) - blockDB := dbm.NewMemDB() - cs := newConsensusStateWithConfigAndBlockStore(consensusReplayConfig, state, privValidator, kvstore.NewKVStoreApplication(), blockDB) - cs.SetLogger(logger) - - // start sending transactions - ctx, cancel := context.WithCancel(context.Background()) - initFn(stateDB, cs, ctx) - - // clean up WAL file from the previous iteration - walFile := cs.config.WalFile() - os.Remove(walFile) - - // set crashing WAL - csWal, err := cs.OpenWAL(walFile) - require.NoError(t, err) - crashingWal.next = csWal - // reset the message counter - crashingWal.msgIndex = 1 - cs.wal = crashingWal - - // start consensus state - err = cs.Start() - require.NoError(t, err) - - i++ - - select { - case err := <-walPaniced: - t.Logf("WAL paniced: %v", err) - - // make sure we can make blocks after a crash - startNewConsensusStateAndWaitForBlock(t, cs.Height, blockDB, stateDB) - - // stop consensus state and transactions sender (initFn) - cs.Stop() - cancel() - - // if we reached the required height, exit - if _, ok := err.(ReachedHeightToStopError); ok { - break LOOP - } - case <-time.After(10 * time.Second): - t.Fatal("WAL did not panic for 10 seconds (check the log)") - } - } -} - -// crashingWAL is a WAL which crashes or rather simulates a crash during Save -// (before and after). It remembers a message for which we last panicked -// (lastPanicedForMsgIndex), so we don't panic for it in subsequent iterations. -type crashingWAL struct { - next WAL - panicCh chan error - heightToStop int64 - - msgIndex int // current message index - lastPanicedForMsgIndex int // last message for which we panicked -} - -// WALWriteError indicates a WAL crash. -type WALWriteError struct { - msg string -} - -func (e WALWriteError) Error() string { - return e.msg -} - -// ReachedHeightToStopError indicates we've reached the required consensus -// height and may exit. -type ReachedHeightToStopError struct { - height int64 -} - -func (e ReachedHeightToStopError) Error() string { - return fmt.Sprintf("reached height to stop %d", e.height) -} - -// Write simulate WAL's crashing by sending an error to the panicCh and then -// exiting the cs.receiveRoutine. -func (w *crashingWAL) Write(m WALMessage) { - if endMsg, ok := m.(EndHeightMessage); ok { - if endMsg.Height == w.heightToStop { - w.panicCh <- ReachedHeightToStopError{endMsg.Height} - runtime.Goexit() - } else { - w.next.Write(m) - } - return - } - - if w.msgIndex > w.lastPanicedForMsgIndex { - w.lastPanicedForMsgIndex = w.msgIndex - _, file, line, _ := runtime.Caller(1) - w.panicCh <- WALWriteError{fmt.Sprintf("failed to write %T to WAL (fileline: %s:%d)", m, file, line)} - runtime.Goexit() - } else { - w.msgIndex++ - w.next.Write(m) - } -} - -func (w *crashingWAL) WriteSync(m WALMessage) { - w.Write(m) -} - -func (w *crashingWAL) Group() *auto.Group { return w.next.Group() } -func (w *crashingWAL) SearchForEndHeight(height int64, options *WALSearchOptions) (gr *auto.GroupReader, found bool, err error) { - return w.next.SearchForEndHeight(height, options) -} - -func (w *crashingWAL) Start() error { return w.next.Start() } -func (w *crashingWAL) Stop() error { return w.next.Stop() } -func (w *crashingWAL) Wait() { w.next.Wait() } - -//------------------------------------------------------------------------------------------ -// Handshake Tests - -const ( - NUM_BLOCKS = 6 -) - -var ( - mempool = sm.MockMempool{} - evpool = sm.MockEvidencePool{} -) - -//--------------------------------------- -// Test handshake/replay - -// 0 - all synced up -// 1 - saved block but app and state are behind -// 2 - save block and committed but state is behind -var modes = []uint{0, 1, 2} - -// Sync from scratch -func TestHandshakeReplayAll(t *testing.T) { - for _, m := range modes { - testHandshakeReplay(t, 0, m) - } -} - -// Sync many, not from scratch -func TestHandshakeReplaySome(t *testing.T) { - for _, m := range modes { - testHandshakeReplay(t, 1, m) - } -} - -// Sync from lagging by one -func TestHandshakeReplayOne(t *testing.T) { - for _, m := range modes { - testHandshakeReplay(t, NUM_BLOCKS-1, m) - } -} - -// Sync from caught up -func TestHandshakeReplayNone(t *testing.T) { - for _, m := range modes { - testHandshakeReplay(t, NUM_BLOCKS, m) - } -} - -func tempWALWithData(data []byte) string { - walFile, err := ioutil.TempFile("", "wal") - if err != nil { - panic(fmt.Errorf("failed to create temp WAL file: %v", err)) - } - _, err = walFile.Write(data) - if err != nil { - panic(fmt.Errorf("failed to write to temp WAL file: %v", err)) - } - if err := walFile.Close(); err != nil { - panic(fmt.Errorf("failed to close temp WAL file: %v", err)) - } - return walFile.Name() -} - -// Make some blocks. Start a fresh app and apply nBlocks blocks. Then restart the app and sync it up with the remaining blocks -func testHandshakeReplay(t *testing.T, nBlocks int, mode uint) { - config := ResetConfig("proxy_test_") - - walBody, err := WALWithNBlocks(NUM_BLOCKS) - if err != nil { - t.Fatal(err) - } - walFile := tempWALWithData(walBody) - config.Consensus.SetWalFile(walFile) - - privVal := privval.LoadFilePV(config.PrivValidatorFile()) - - wal, err := NewWAL(walFile) - if err != nil { - t.Fatal(err) - } - wal.SetLogger(log.TestingLogger()) - if err := wal.Start(); err != nil { - t.Fatal(err) - } - defer wal.Stop() - - chain, commits, err := makeBlockchainFromWAL(wal) - if err != nil { - t.Fatalf(err.Error()) - } - - stateDB, state, store := stateAndStore(config, privVal.GetPubKey()) - store.chain = chain - store.commits = commits - - // run the chain through state.ApplyBlock to build up the tendermint state - state = buildTMStateFromChain(config, stateDB, state, chain, mode) - latestAppHash := state.AppHash - - // make a new client creator - kvstoreApp := kvstore.NewPersistentKVStoreApplication(path.Join(config.DBDir(), "2")) - clientCreator2 := proxy.NewLocalClientCreator(kvstoreApp) - if nBlocks > 0 { - // run nBlocks against a new client to build up the app state. - // use a throwaway tendermint state - proxyApp := proxy.NewAppConns(clientCreator2, nil) - stateDB, state, _ := stateAndStore(config, privVal.GetPubKey()) - buildAppStateFromChain(proxyApp, stateDB, state, chain, nBlocks, mode) - } - - // now start the app using the handshake - it should sync - genDoc, _ := sm.MakeGenesisDocFromFile(config.GenesisFile()) - handshaker := NewHandshaker(stateDB, state, store, genDoc) - proxyApp := proxy.NewAppConns(clientCreator2, handshaker) - if err := proxyApp.Start(); err != nil { - t.Fatalf("Error starting proxy app connections: %v", err) - } - defer proxyApp.Stop() - - // get the latest app hash from the app - res, err := proxyApp.Query().InfoSync(abci.RequestInfo{""}) - if err != nil { - t.Fatal(err) - } - - // the app hash should be synced up - if !bytes.Equal(latestAppHash, res.LastBlockAppHash) { - t.Fatalf("Expected app hashes to match after handshake/replay. got %X, expected %X", res.LastBlockAppHash, latestAppHash) - } - - expectedBlocksToSync := NUM_BLOCKS - nBlocks - if nBlocks == NUM_BLOCKS && mode > 0 { - expectedBlocksToSync++ - } else if nBlocks > 0 && mode == 1 { - expectedBlocksToSync++ - } - - if handshaker.NBlocks() != expectedBlocksToSync { - t.Fatalf("Expected handshake to sync %d blocks, got %d", expectedBlocksToSync, handshaker.NBlocks()) - } -} - -func applyBlock(stateDB dbm.DB, st sm.State, blk *types.Block, proxyApp proxy.AppConns) sm.State { - testPartSize := st.ConsensusParams.BlockPartSizeBytes - blockExec := sm.NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(), mempool, evpool) - - blkID := types.BlockID{blk.Hash(), blk.MakePartSet(testPartSize).Header()} - newState, err := blockExec.ApplyBlock(st, blkID, blk) - if err != nil { - panic(err) - } - return newState -} - -func buildAppStateFromChain(proxyApp proxy.AppConns, stateDB dbm.DB, - state sm.State, chain []*types.Block, nBlocks int, mode uint) { - // start a new app without handshake, play nBlocks blocks - if err := proxyApp.Start(); err != nil { - panic(err) - } - defer proxyApp.Stop() - - validators := types.TM2PB.Validators(state.Validators) - if _, err := proxyApp.Consensus().InitChainSync(abci.RequestInitChain{ - Validators: validators, - }); err != nil { - panic(err) - } - - switch mode { - case 0: - for i := 0; i < nBlocks; i++ { - block := chain[i] - state = applyBlock(stateDB, state, block, proxyApp) - } - case 1, 2: - for i := 0; i < nBlocks-1; i++ { - block := chain[i] - state = applyBlock(stateDB, state, block, proxyApp) - } - - if mode == 2 { - // update the kvstore height and apphash - // as if we ran commit but not - state = applyBlock(stateDB, state, chain[nBlocks-1], proxyApp) - } - } - -} - -func buildTMStateFromChain(config *cfg.Config, stateDB dbm.DB, state sm.State, chain []*types.Block, mode uint) sm.State { - // run the whole chain against this client to build up the tendermint state - clientCreator := proxy.NewLocalClientCreator(kvstore.NewPersistentKVStoreApplication(path.Join(config.DBDir(), "1"))) - proxyApp := proxy.NewAppConns(clientCreator, nil) // sm.NewHandshaker(config, state, store, ReplayLastBlock)) - if err := proxyApp.Start(); err != nil { - panic(err) - } - defer proxyApp.Stop() - - validators := types.TM2PB.Validators(state.Validators) - if _, err := proxyApp.Consensus().InitChainSync(abci.RequestInitChain{ - Validators: validators, - }); err != nil { - panic(err) - } - - switch mode { - case 0: - // sync right up - for _, block := range chain { - state = applyBlock(stateDB, state, block, proxyApp) - } - - case 1, 2: - // sync up to the penultimate as if we stored the block. - // whether we commit or not depends on the appHash - for _, block := range chain[:len(chain)-1] { - state = applyBlock(stateDB, state, block, proxyApp) - } - - // apply the final block to a state copy so we can - // get the right next appHash but keep the state back - applyBlock(stateDB, state, chain[len(chain)-1], proxyApp) - } - - return state -} - -//-------------------------- -// utils for making blocks - -func makeBlockchainFromWAL(wal WAL) ([]*types.Block, []*types.Commit, error) { - // Search for height marker - gr, found, err := wal.SearchForEndHeight(0, &WALSearchOptions{}) - if err != nil { - return nil, nil, err - } - if !found { - return nil, nil, errors.New(cmn.Fmt("WAL does not contain height %d.", 1)) - } - defer gr.Close() // nolint: errcheck - - // log.Notice("Build a blockchain by reading from the WAL") - - var blocks []*types.Block - var commits []*types.Commit - - var thisBlockParts *types.PartSet - var thisBlockCommit *types.Commit - var height int64 - - dec := NewWALDecoder(gr) - for { - msg, err := dec.Decode() - if err == io.EOF { - break - } else if err != nil { - return nil, nil, err - } - - piece := readPieceFromWAL(msg) - if piece == nil { - continue - } - - switch p := piece.(type) { - case EndHeightMessage: - // if its not the first one, we have a full block - if thisBlockParts != nil { - var block = new(types.Block) - _, err = cdc.UnmarshalBinaryReader(thisBlockParts.GetReader(), block, 0) - if err != nil { - panic(err) - } - if block.Height != height+1 { - panic(cmn.Fmt("read bad block from wal. got height %d, expected %d", block.Height, height+1)) - } - commitHeight := thisBlockCommit.Precommits[0].Height - if commitHeight != height+1 { - panic(cmn.Fmt("commit doesnt match. got height %d, expected %d", commitHeight, height+1)) - } - blocks = append(blocks, block) - commits = append(commits, thisBlockCommit) - height++ - } - case *types.PartSetHeader: - thisBlockParts = types.NewPartSetFromHeader(*p) - case *types.Part: - _, err := thisBlockParts.AddPart(p) - if err != nil { - return nil, nil, err - } - case *types.Vote: - if p.Type == types.VoteTypePrecommit { - thisBlockCommit = &types.Commit{ - BlockID: p.BlockID, - Precommits: []*types.Vote{p}, - } - } - } - } - // grab the last block too - var block = new(types.Block) - _, err = cdc.UnmarshalBinaryReader(thisBlockParts.GetReader(), block, 0) - if err != nil { - panic(err) - } - if block.Height != height+1 { - panic(cmn.Fmt("read bad block from wal. got height %d, expected %d", block.Height, height+1)) - } - commitHeight := thisBlockCommit.Precommits[0].Height - if commitHeight != height+1 { - panic(cmn.Fmt("commit doesnt match. got height %d, expected %d", commitHeight, height+1)) - } - blocks = append(blocks, block) - commits = append(commits, thisBlockCommit) - return blocks, commits, nil -} - -func readPieceFromWAL(msg *TimedWALMessage) interface{} { - // for logging - switch m := msg.Msg.(type) { - case msgInfo: - switch msg := m.Msg.(type) { - case *ProposalMessage: - return &msg.Proposal.BlockPartsHeader - case *BlockPartMessage: - return msg.Part - case *VoteMessage: - return msg.Vote - } - case EndHeightMessage: - return m - } - - return nil -} - -// fresh state and mock store -func stateAndStore(config *cfg.Config, pubKey crypto.PubKey) (dbm.DB, sm.State, *mockBlockStore) { - stateDB := dbm.NewMemDB() - state, _ := sm.MakeGenesisStateFromFile(config.GenesisFile()) - store := NewMockBlockStore(config, state.ConsensusParams) - return stateDB, state, store -} - -//---------------------------------- -// mock block store - -type mockBlockStore struct { - config *cfg.Config - params types.ConsensusParams - chain []*types.Block - commits []*types.Commit -} - -// TODO: NewBlockStore(db.NewMemDB) ... -func NewMockBlockStore(config *cfg.Config, params types.ConsensusParams) *mockBlockStore { - return &mockBlockStore{config, params, nil, nil} -} - -func (bs *mockBlockStore) Height() int64 { return int64(len(bs.chain)) } -func (bs *mockBlockStore) LoadBlock(height int64) *types.Block { return bs.chain[height-1] } -func (bs *mockBlockStore) LoadBlockMeta(height int64) *types.BlockMeta { - block := bs.chain[height-1] - return &types.BlockMeta{ - BlockID: types.BlockID{block.Hash(), block.MakePartSet(bs.params.BlockPartSizeBytes).Header()}, - Header: block.Header, - } -} -func (bs *mockBlockStore) LoadBlockPart(height int64, index int) *types.Part { return nil } -func (bs *mockBlockStore) SaveBlock(block *types.Block, blockParts *types.PartSet, seenCommit *types.Commit) { -} -func (bs *mockBlockStore) LoadBlockCommit(height int64) *types.Commit { - return bs.commits[height-1] -} -func (bs *mockBlockStore) LoadSeenCommit(height int64) *types.Commit { - return bs.commits[height-1] -} - -//---------------------------------------- - -func TestInitChainUpdateValidators(t *testing.T) { - val, _ := types.RandValidator(true, 10) - vals := types.NewValidatorSet([]*types.Validator{val}) - app := &initChainApp{vals: types.TM2PB.Validators(vals)} - clientCreator := proxy.NewLocalClientCreator(app) - - config := ResetConfig("proxy_test_") - privVal := privval.LoadFilePV(config.PrivValidatorFile()) - stateDB, state, store := stateAndStore(config, privVal.GetPubKey()) - - oldValAddr := state.Validators.Validators[0].Address - - // now start the app using the handshake - it should sync - genDoc, _ := sm.MakeGenesisDocFromFile(config.GenesisFile()) - handshaker := NewHandshaker(stateDB, state, store, genDoc) - proxyApp := proxy.NewAppConns(clientCreator, handshaker) - if err := proxyApp.Start(); err != nil { - t.Fatalf("Error starting proxy app connections: %v", err) - } - defer proxyApp.Stop() - - // reload the state, check the validator set was updated - state = sm.LoadState(stateDB) - - newValAddr := state.Validators.Validators[0].Address - expectValAddr := val.Address - assert.NotEqual(t, oldValAddr, newValAddr) - assert.Equal(t, newValAddr, expectValAddr) -} - -func newInitChainApp(vals []abci.Validator) *initChainApp { - return &initChainApp{ - vals: vals, - } -} - -// returns the vals on InitChain -type initChainApp struct { - abci.BaseApplication - vals []abci.Validator -} - -func (ica *initChainApp) InitChain(req abci.RequestInitChain) abci.ResponseInitChain { - return abci.ResponseInitChain{ - Validators: ica.vals, - } -} diff --git a/consensus/state.go b/consensus/state.go deleted file mode 100644 index aab822969..000000000 --- a/consensus/state.go +++ /dev/null @@ -1,1673 +0,0 @@ -package consensus - -import ( - "bytes" - "errors" - "fmt" - "reflect" - "runtime/debug" - "sync" - "time" - - fail "github.com/ebuchman/fail-test" - cmn "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/log" - - cfg "github.com/tendermint/tendermint/config" - cstypes "github.com/tendermint/tendermint/consensus/types" - tmevents "github.com/tendermint/tendermint/libs/events" - "github.com/tendermint/tendermint/p2p" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" -) - -//----------------------------------------------------------------------------- -// Config - -const ( - proposalHeartbeatIntervalSeconds = 2 -) - -//----------------------------------------------------------------------------- -// Errors - -var ( - ErrInvalidProposalSignature = errors.New("Error invalid proposal signature") - ErrInvalidProposalPOLRound = errors.New("Error invalid proposal POL round") - ErrAddingVote = errors.New("Error adding vote") - ErrVoteHeightMismatch = errors.New("Error vote height mismatch") -) - -//----------------------------------------------------------------------------- - -var ( - msgQueueSize = 1000 -) - -// msgs from the reactor which may update the state -type msgInfo struct { - Msg ConsensusMessage `json:"msg"` - PeerID p2p.ID `json:"peer_key"` -} - -// internally generated messages which may update the state -type timeoutInfo struct { - Duration time.Duration `json:"duration"` - Height int64 `json:"height"` - Round int `json:"round"` - Step cstypes.RoundStepType `json:"step"` -} - -func (ti *timeoutInfo) String() string { - return fmt.Sprintf("%v ; %d/%d %v", ti.Duration, ti.Height, ti.Round, ti.Step) -} - -// ConsensusState handles execution of the consensus algorithm. -// It processes votes and proposals, and upon reaching agreement, -// commits blocks to the chain and executes them against the application. -// The internal state machine receives input from peers, the internal validator, and from a timer. -type ConsensusState struct { - cmn.BaseService - - // config details - config *cfg.ConsensusConfig - privValidator types.PrivValidator // for signing votes - - // services for creating and executing blocks - // TODO: encapsulate all of this in one "BlockManager" - blockExec *sm.BlockExecutor - blockStore sm.BlockStore - mempool sm.Mempool - evpool sm.EvidencePool - - // internal state - mtx sync.Mutex - cstypes.RoundState - state sm.State // State until height-1. - - // state changes may be triggered by: msgs from peers, - // msgs from ourself, or by timeouts - peerMsgQueue chan msgInfo - internalMsgQueue chan msgInfo - timeoutTicker TimeoutTicker - - // we use eventBus to trigger msg broadcasts in the reactor, - // and to notify external subscribers, eg. through a websocket - eventBus *types.EventBus - - // a Write-Ahead Log ensures we can recover from any kind of crash - // and helps us avoid signing conflicting votes - wal WAL - replayMode bool // so we don't log signing errors during replay - doWALCatchup bool // determines if we even try to do the catchup - - // for tests where we want to limit the number of transitions the state makes - nSteps int - - // some functions can be overwritten for testing - decideProposal func(height int64, round int) - doPrevote func(height int64, round int) - setProposal func(proposal *types.Proposal) error - - // closed when we finish shutting down - done chan struct{} - - // synchronous pubsub between consensus state and reactor. - // state only emits EventNewRoundStep, EventVote and EventProposalHeartbeat - evsw tmevents.EventSwitch - - // for reporting metrics - metrics *Metrics -} - -// CSOption sets an optional parameter on the ConsensusState. -type CSOption func(*ConsensusState) - -// NewConsensusState returns a new ConsensusState. -func NewConsensusState( - config *cfg.ConsensusConfig, - state sm.State, - blockExec *sm.BlockExecutor, - blockStore sm.BlockStore, - mempool sm.Mempool, - evpool sm.EvidencePool, - options ...CSOption, -) *ConsensusState { - cs := &ConsensusState{ - config: config, - blockExec: blockExec, - blockStore: blockStore, - mempool: mempool, - peerMsgQueue: make(chan msgInfo, msgQueueSize), - internalMsgQueue: make(chan msgInfo, msgQueueSize), - timeoutTicker: NewTimeoutTicker(), - done: make(chan struct{}), - doWALCatchup: true, - wal: nilWAL{}, - evpool: evpool, - evsw: tmevents.NewEventSwitch(), - metrics: NopMetrics(), - } - // set function defaults (may be overwritten before calling Start) - cs.decideProposal = cs.defaultDecideProposal - cs.doPrevote = cs.defaultDoPrevote - cs.setProposal = cs.defaultSetProposal - - cs.updateToState(state) - // Don't call scheduleRound0 yet. - // We do that upon Start(). - cs.reconstructLastCommit(state) - cs.BaseService = *cmn.NewBaseService(nil, "ConsensusState", cs) - for _, option := range options { - option(cs) - } - return cs -} - -//---------------------------------------- -// Public interface - -// SetLogger implements Service. -func (cs *ConsensusState) SetLogger(l log.Logger) { - cs.BaseService.Logger = l - cs.timeoutTicker.SetLogger(l) -} - -// SetEventBus sets event bus. -func (cs *ConsensusState) SetEventBus(b *types.EventBus) { - cs.eventBus = b - cs.blockExec.SetEventBus(b) -} - -// WithMetrics sets the metrics. -func WithMetrics(metrics *Metrics) CSOption { - return func(cs *ConsensusState) { cs.metrics = metrics } -} - -// String returns a string. -func (cs *ConsensusState) String() string { - // better not to access shared variables - return cmn.Fmt("ConsensusState") //(H:%v R:%v S:%v", cs.Height, cs.Round, cs.Step) -} - -// GetState returns a copy of the chain state. -func (cs *ConsensusState) GetState() sm.State { - cs.mtx.Lock() - defer cs.mtx.Unlock() - return cs.state.Copy() -} - -// GetRoundState returns a shallow copy of the internal consensus state. -func (cs *ConsensusState) GetRoundState() *cstypes.RoundState { - cs.mtx.Lock() - defer cs.mtx.Unlock() - - rs := cs.RoundState // copy - return &rs -} - -// GetRoundStateJSON returns a json of RoundState, marshalled using go-amino. -func (cs *ConsensusState) GetRoundStateJSON() ([]byte, error) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - - return cdc.MarshalJSON(cs.RoundState) -} - -// GetRoundStateSimpleJSON returns a json of RoundStateSimple, marshalled using go-amino. -func (cs *ConsensusState) GetRoundStateSimpleJSON() ([]byte, error) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - - return cdc.MarshalJSON(cs.RoundState.RoundStateSimple()) -} - -// GetValidators returns a copy of the current validators. -func (cs *ConsensusState) GetValidators() (int64, []*types.Validator) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - return cs.state.LastBlockHeight, cs.state.Validators.Copy().Validators -} - -// SetPrivValidator sets the private validator account for signing votes. -func (cs *ConsensusState) SetPrivValidator(priv types.PrivValidator) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - cs.privValidator = priv -} - -// SetTimeoutTicker sets the local timer. It may be useful to overwrite for testing. -func (cs *ConsensusState) SetTimeoutTicker(timeoutTicker TimeoutTicker) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - cs.timeoutTicker = timeoutTicker -} - -// LoadCommit loads the commit for a given height. -func (cs *ConsensusState) LoadCommit(height int64) *types.Commit { - cs.mtx.Lock() - defer cs.mtx.Unlock() - if height == cs.blockStore.Height() { - return cs.blockStore.LoadSeenCommit(height) - } - return cs.blockStore.LoadBlockCommit(height) -} - -// OnStart implements cmn.Service. -// It loads the latest state via the WAL, and starts the timeout and receive routines. -func (cs *ConsensusState) OnStart() error { - if err := cs.evsw.Start(); err != nil { - return err - } - - // we may set the WAL in testing before calling Start, - // so only OpenWAL if its still the nilWAL - if _, ok := cs.wal.(nilWAL); ok { - walFile := cs.config.WalFile() - wal, err := cs.OpenWAL(walFile) - if err != nil { - cs.Logger.Error("Error loading ConsensusState wal", "err", err.Error()) - return err - } - cs.wal = wal - } - - // we need the timeoutRoutine for replay so - // we don't block on the tick chan. - // NOTE: we will get a build up of garbage go routines - // firing on the tockChan until the receiveRoutine is started - // to deal with them (by that point, at most one will be valid) - if err := cs.timeoutTicker.Start(); err != nil { - return err - } - - // we may have lost some votes if the process crashed - // reload from consensus log to catchup - if cs.doWALCatchup { - if err := cs.catchupReplay(cs.Height); err != nil { - cs.Logger.Error("Error on catchup replay. Proceeding to start ConsensusState anyway", "err", err.Error()) - // NOTE: if we ever do return an error here, - // make sure to stop the timeoutTicker - } - } - - // now start the receiveRoutine - go cs.receiveRoutine(0) - - // schedule the first round! - // use GetRoundState so we don't race the receiveRoutine for access - cs.scheduleRound0(cs.GetRoundState()) - - return nil -} - -// timeoutRoutine: receive requests for timeouts on tickChan and fire timeouts on tockChan -// receiveRoutine: serializes processing of proposoals, block parts, votes; coordinates state transitions -func (cs *ConsensusState) startRoutines(maxSteps int) { - err := cs.timeoutTicker.Start() - if err != nil { - cs.Logger.Error("Error starting timeout ticker", "err", err) - return - } - go cs.receiveRoutine(maxSteps) -} - -// OnStop implements cmn.Service. It stops all routines and waits for the WAL to finish. -func (cs *ConsensusState) OnStop() { - cs.BaseService.OnStop() - - cs.evsw.Stop() - - cs.timeoutTicker.Stop() - - // Make BaseService.Wait() wait until cs.wal.Wait() - if cs.IsRunning() { - cs.wal.Wait() - } -} - -// Wait waits for the the main routine to return. -// NOTE: be sure to Stop() the event switch and drain -// any event channels or this may deadlock -func (cs *ConsensusState) Wait() { - <-cs.done -} - -// OpenWAL opens a file to log all consensus messages and timeouts for deterministic accountability -func (cs *ConsensusState) OpenWAL(walFile string) (WAL, error) { - wal, err := NewWAL(walFile) - if err != nil { - cs.Logger.Error("Failed to open WAL for consensus state", "wal", walFile, "err", err) - return nil, err - } - wal.SetLogger(cs.Logger.With("wal", walFile)) - if err := wal.Start(); err != nil { - return nil, err - } - return wal, nil -} - -//------------------------------------------------------------ -// Public interface for passing messages into the consensus state, possibly causing a state transition. -// If peerID == "", the msg is considered internal. -// Messages are added to the appropriate queue (peer or internal). -// If the queue is full, the function may block. -// TODO: should these return anything or let callers just use events? - -// AddVote inputs a vote. -func (cs *ConsensusState) AddVote(vote *types.Vote, peerID p2p.ID) (added bool, err error) { - if peerID == "" { - cs.internalMsgQueue <- msgInfo{&VoteMessage{vote}, ""} - } else { - cs.peerMsgQueue <- msgInfo{&VoteMessage{vote}, peerID} - } - - // TODO: wait for event?! - return false, nil -} - -// SetProposal inputs a proposal. -func (cs *ConsensusState) SetProposal(proposal *types.Proposal, peerID p2p.ID) error { - - if peerID == "" { - cs.internalMsgQueue <- msgInfo{&ProposalMessage{proposal}, ""} - } else { - cs.peerMsgQueue <- msgInfo{&ProposalMessage{proposal}, peerID} - } - - // TODO: wait for event?! - return nil -} - -// AddProposalBlockPart inputs a part of the proposal block. -func (cs *ConsensusState) AddProposalBlockPart(height int64, round int, part *types.Part, peerID p2p.ID) error { - - if peerID == "" { - cs.internalMsgQueue <- msgInfo{&BlockPartMessage{height, round, part}, ""} - } else { - cs.peerMsgQueue <- msgInfo{&BlockPartMessage{height, round, part}, peerID} - } - - // TODO: wait for event?! - return nil -} - -// SetProposalAndBlock inputs the proposal and all block parts. -func (cs *ConsensusState) SetProposalAndBlock(proposal *types.Proposal, block *types.Block, parts *types.PartSet, peerID p2p.ID) error { - if err := cs.SetProposal(proposal, peerID); err != nil { - return err - } - for i := 0; i < parts.Total(); i++ { - part := parts.GetPart(i) - if err := cs.AddProposalBlockPart(proposal.Height, proposal.Round, part, peerID); err != nil { - return err - } - } - return nil -} - -//------------------------------------------------------------ -// internal functions for managing the state - -func (cs *ConsensusState) updateHeight(height int64) { - cs.metrics.Height.Set(float64(height)) - cs.Height = height -} - -func (cs *ConsensusState) updateRoundStep(round int, step cstypes.RoundStepType) { - cs.Round = round - cs.Step = step -} - -// enterNewRound(height, 0) at cs.StartTime. -func (cs *ConsensusState) scheduleRound0(rs *cstypes.RoundState) { - //cs.Logger.Info("scheduleRound0", "now", time.Now(), "startTime", cs.StartTime) - sleepDuration := rs.StartTime.Sub(time.Now()) // nolint: gotype, gosimple - cs.scheduleTimeout(sleepDuration, rs.Height, 0, cstypes.RoundStepNewHeight) -} - -// Attempt to schedule a timeout (by sending timeoutInfo on the tickChan) -func (cs *ConsensusState) scheduleTimeout(duration time.Duration, height int64, round int, step cstypes.RoundStepType) { - cs.timeoutTicker.ScheduleTimeout(timeoutInfo{duration, height, round, step}) -} - -// send a msg into the receiveRoutine regarding our own proposal, block part, or vote -func (cs *ConsensusState) sendInternalMessage(mi msgInfo) { - select { - case cs.internalMsgQueue <- mi: - default: - // NOTE: using the go-routine means our votes can - // be processed out of order. - // TODO: use CList here for strict determinism and - // attempt push to internalMsgQueue in receiveRoutine - cs.Logger.Info("Internal msg queue is full. Using a go-routine") - go func() { cs.internalMsgQueue <- mi }() - } -} - -// Reconstruct LastCommit from SeenCommit, which we saved along with the block, -// (which happens even before saving the state) -func (cs *ConsensusState) reconstructLastCommit(state sm.State) { - if state.LastBlockHeight == 0 { - return - } - seenCommit := cs.blockStore.LoadSeenCommit(state.LastBlockHeight) - lastPrecommits := types.NewVoteSet(state.ChainID, state.LastBlockHeight, seenCommit.Round(), types.VoteTypePrecommit, state.LastValidators) - for _, precommit := range seenCommit.Precommits { - if precommit == nil { - continue - } - added, err := lastPrecommits.AddVote(precommit) - if !added || err != nil { - cmn.PanicCrisis(cmn.Fmt("Failed to reconstruct LastCommit: %v", err)) - } - } - if !lastPrecommits.HasTwoThirdsMajority() { - cmn.PanicSanity("Failed to reconstruct LastCommit: Does not have +2/3 maj") - } - cs.LastCommit = lastPrecommits -} - -// Updates ConsensusState and increments height to match that of state. -// The round becomes 0 and cs.Step becomes cstypes.RoundStepNewHeight. -func (cs *ConsensusState) updateToState(state sm.State) { - if cs.CommitRound > -1 && 0 < cs.Height && cs.Height != state.LastBlockHeight { - cmn.PanicSanity(cmn.Fmt("updateToState() expected state height of %v but found %v", - cs.Height, state.LastBlockHeight)) - } - if !cs.state.IsEmpty() && cs.state.LastBlockHeight+1 != cs.Height { - // This might happen when someone else is mutating cs.state. - // Someone forgot to pass in state.Copy() somewhere?! - cmn.PanicSanity(cmn.Fmt("Inconsistent cs.state.LastBlockHeight+1 %v vs cs.Height %v", - cs.state.LastBlockHeight+1, cs.Height)) - } - - // If state isn't further out than cs.state, just ignore. - // This happens when SwitchToConsensus() is called in the reactor. - // We don't want to reset e.g. the Votes. - if !cs.state.IsEmpty() && (state.LastBlockHeight <= cs.state.LastBlockHeight) { - cs.Logger.Info("Ignoring updateToState()", "newHeight", state.LastBlockHeight+1, "oldHeight", cs.state.LastBlockHeight+1) - return - } - - // Reset fields based on state. - validators := state.Validators - lastPrecommits := (*types.VoteSet)(nil) - if cs.CommitRound > -1 && cs.Votes != nil { - if !cs.Votes.Precommits(cs.CommitRound).HasTwoThirdsMajority() { - cmn.PanicSanity("updateToState(state) called but last Precommit round didn't have +2/3") - } - lastPrecommits = cs.Votes.Precommits(cs.CommitRound) - } - - // Next desired block height - height := state.LastBlockHeight + 1 - - // RoundState fields - cs.updateHeight(height) - cs.updateRoundStep(0, cstypes.RoundStepNewHeight) - if cs.CommitTime.IsZero() { - // "Now" makes it easier to sync up dev nodes. - // We add timeoutCommit to allow transactions - // to be gathered for the first block. - // And alternative solution that relies on clocks: - // cs.StartTime = state.LastBlockTime.Add(timeoutCommit) - cs.StartTime = cs.config.Commit(time.Now()) - } else { - cs.StartTime = cs.config.Commit(cs.CommitTime) - } - cs.Validators = validators - cs.Proposal = nil - cs.ProposalBlock = nil - cs.ProposalBlockParts = nil - cs.LockedRound = 0 - cs.LockedBlock = nil - cs.LockedBlockParts = nil - cs.ValidRound = 0 - cs.ValidBlock = nil - cs.ValidBlockParts = nil - cs.Votes = cstypes.NewHeightVoteSet(state.ChainID, height, validators) - cs.CommitRound = -1 - cs.LastCommit = lastPrecommits - cs.LastValidators = state.LastValidators - - cs.state = state - - // Finally, broadcast RoundState - cs.newStep() -} - -func (cs *ConsensusState) newStep() { - rs := cs.RoundStateEvent() - cs.wal.Write(rs) - cs.nSteps++ - // newStep is called by updateToStep in NewConsensusState before the eventBus is set! - if cs.eventBus != nil { - cs.eventBus.PublishEventNewRoundStep(rs) - cs.evsw.FireEvent(types.EventNewRoundStep, &cs.RoundState) - } -} - -//----------------------------------------- -// the main go routines - -// receiveRoutine handles messages which may cause state transitions. -// it's argument (n) is the number of messages to process before exiting - use 0 to run forever -// It keeps the RoundState and is the only thing that updates it. -// Updates (state transitions) happen on timeouts, complete proposals, and 2/3 majorities. -// ConsensusState must be locked before any internal state is updated. -func (cs *ConsensusState) receiveRoutine(maxSteps int) { - defer func() { - if r := recover(); r != nil { - cs.Logger.Error("CONSENSUS FAILURE!!!", "err", r, "stack", string(debug.Stack())) - } - }() - - for { - if maxSteps > 0 { - if cs.nSteps >= maxSteps { - cs.Logger.Info("reached max steps. exiting receive routine") - cs.nSteps = 0 - return - } - } - rs := cs.RoundState - var mi msgInfo - - select { - case height := <-cs.mempool.TxsAvailable(): - cs.handleTxsAvailable(height) - case mi = <-cs.peerMsgQueue: - cs.wal.Write(mi) - // handles proposals, block parts, votes - // may generate internal events (votes, complete proposals, 2/3 majorities) - cs.handleMsg(mi) - case mi = <-cs.internalMsgQueue: - cs.wal.WriteSync(mi) // NOTE: fsync - // handles proposals, block parts, votes - cs.handleMsg(mi) - case ti := <-cs.timeoutTicker.Chan(): // tockChan: - cs.wal.Write(ti) - // if the timeout is relevant to the rs - // go to the next step - cs.handleTimeout(ti, rs) - case <-cs.Quit(): - - // NOTE: the internalMsgQueue may have signed messages from our - // priv_val that haven't hit the WAL, but its ok because - // priv_val tracks LastSig - - // close wal now that we're done writing to it - cs.wal.Stop() - - close(cs.done) - return - } - } -} - -// state transitions on complete-proposal, 2/3-any, 2/3-one -func (cs *ConsensusState) handleMsg(mi msgInfo) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - - var err error - msg, peerID := mi.Msg, mi.PeerID - switch msg := msg.(type) { - case *ProposalMessage: - // will not cause transition. - // once proposal is set, we can receive block parts - err = cs.setProposal(msg.Proposal) - case *BlockPartMessage: - // if the proposal is complete, we'll enterPrevote or tryFinalizeCommit - _, err = cs.addProposalBlockPart(msg.Height, msg.Part) - if err != nil && msg.Round != cs.Round { - cs.Logger.Debug("Received block part from wrong round", "height", cs.Height, "csRound", cs.Round, "blockRound", msg.Round) - err = nil - } - case *VoteMessage: - // attempt to add the vote and dupeout the validator if its a duplicate signature - // if the vote gives us a 2/3-any or 2/3-one, we transition - err := cs.tryAddVote(msg.Vote, peerID) - if err == ErrAddingVote { - // TODO: punish peer - // We probably don't want to stop the peer here. The vote does not - // necessarily comes from a malicious peer but can be just broadcasted by - // a typical peer. - // https://github.com/tendermint/tendermint/issues/1281 - } - - // NOTE: the vote is broadcast to peers by the reactor listening - // for vote events - - // TODO: If rs.Height == vote.Height && rs.Round < vote.Round, - // the peer is sending us CatchupCommit precommits. - // We could make note of this and help filter in broadcastHasVoteMessage(). - default: - cs.Logger.Error("Unknown msg type", reflect.TypeOf(msg)) - } - if err != nil { - cs.Logger.Error("Error with msg", "height", cs.Height, "round", cs.Round, "type", reflect.TypeOf(msg), "peer", peerID, "err", err, "msg", msg) - } -} - -func (cs *ConsensusState) handleTimeout(ti timeoutInfo, rs cstypes.RoundState) { - cs.Logger.Debug("Received tock", "timeout", ti.Duration, "height", ti.Height, "round", ti.Round, "step", ti.Step) - - // timeouts must be for current height, round, step - if ti.Height != rs.Height || ti.Round < rs.Round || (ti.Round == rs.Round && ti.Step < rs.Step) { - cs.Logger.Debug("Ignoring tock because we're ahead", "height", rs.Height, "round", rs.Round, "step", rs.Step) - return - } - - // the timeout will now cause a state transition - cs.mtx.Lock() - defer cs.mtx.Unlock() - - switch ti.Step { - case cstypes.RoundStepNewHeight: - // NewRound event fired from enterNewRound. - // XXX: should we fire timeout here (for timeout commit)? - cs.enterNewRound(ti.Height, 0) - case cstypes.RoundStepNewRound: - cs.enterPropose(ti.Height, 0) - case cstypes.RoundStepPropose: - cs.eventBus.PublishEventTimeoutPropose(cs.RoundStateEvent()) - cs.enterPrevote(ti.Height, ti.Round) - case cstypes.RoundStepPrevoteWait: - cs.eventBus.PublishEventTimeoutWait(cs.RoundStateEvent()) - cs.enterPrecommit(ti.Height, ti.Round) - case cstypes.RoundStepPrecommitWait: - cs.eventBus.PublishEventTimeoutWait(cs.RoundStateEvent()) - cs.enterNewRound(ti.Height, ti.Round+1) - default: - panic(cmn.Fmt("Invalid timeout step: %v", ti.Step)) - } - -} - -func (cs *ConsensusState) handleTxsAvailable(height int64) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - // we only need to do this for round 0 - cs.enterPropose(height, 0) -} - -//----------------------------------------------------------------------------- -// State functions -// Used internally by handleTimeout and handleMsg to make state transitions - -// Enter: `timeoutNewHeight` by startTime (commitTime+timeoutCommit), -// or, if SkipTimeout==true, after receiving all precommits from (height,round-1) -// Enter: `timeoutPrecommits` after any +2/3 precommits from (height,round-1) -// Enter: +2/3 precommits for nil at (height,round-1) -// Enter: +2/3 prevotes any or +2/3 precommits for block or any from (height, round) -// NOTE: cs.StartTime was already set for height. -func (cs *ConsensusState) enterNewRound(height int64, round int) { - logger := cs.Logger.With("height", height, "round", round) - - if cs.Height != height || round < cs.Round || (cs.Round == round && cs.Step != cstypes.RoundStepNewHeight) { - logger.Debug(cmn.Fmt("enterNewRound(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - - if now := time.Now(); cs.StartTime.After(now) { - logger.Info("Need to set a buffer and log message here for sanity.", "startTime", cs.StartTime, "now", now) - } - - logger.Info(cmn.Fmt("enterNewRound(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - // Increment validators if necessary - validators := cs.Validators - if cs.Round < round { - validators = validators.Copy() - validators.IncrementAccum(round - cs.Round) - } - - // Setup new round - // we don't fire newStep for this step, - // but we fire an event, so update the round step first - cs.updateRoundStep(round, cstypes.RoundStepNewRound) - cs.Validators = validators - if round == 0 { - // We've already reset these upon new height, - // and meanwhile we might have received a proposal - // for round 0. - } else { - logger.Info("Resetting Proposal info") - cs.Proposal = nil - cs.ProposalBlock = nil - cs.ProposalBlockParts = nil - } - cs.Votes.SetRound(round + 1) // also track next round (round+1) to allow round-skipping - - cs.eventBus.PublishEventNewRound(cs.RoundStateEvent()) - cs.metrics.Rounds.Set(float64(round)) - - // Wait for txs to be available in the mempool - // before we enterPropose in round 0. If the last block changed the app hash, - // we may need an empty "proof" block, and enterPropose immediately. - waitForTxs := cs.config.WaitForTxs() && round == 0 && !cs.needProofBlock(height) - if waitForTxs { - if cs.config.CreateEmptyBlocksInterval > 0 { - cs.scheduleTimeout(cs.config.EmptyBlocksInterval(), height, round, cstypes.RoundStepNewRound) - } - go cs.proposalHeartbeat(height, round) - } else { - cs.enterPropose(height, round) - } -} - -// needProofBlock returns true on the first height (so the genesis app hash is signed right away) -// and where the last block (height-1) caused the app hash to change -func (cs *ConsensusState) needProofBlock(height int64) bool { - if height == 1 { - return true - } - - lastBlockMeta := cs.blockStore.LoadBlockMeta(height - 1) - return !bytes.Equal(cs.state.AppHash, lastBlockMeta.Header.AppHash) -} - -func (cs *ConsensusState) proposalHeartbeat(height int64, round int) { - counter := 0 - addr := cs.privValidator.GetAddress() - valIndex, _ := cs.Validators.GetByAddress(addr) - chainID := cs.state.ChainID - for { - rs := cs.GetRoundState() - // if we've already moved on, no need to send more heartbeats - if rs.Step > cstypes.RoundStepNewRound || rs.Round > round || rs.Height > height { - return - } - heartbeat := &types.Heartbeat{ - Height: rs.Height, - Round: rs.Round, - Sequence: counter, - ValidatorAddress: addr, - ValidatorIndex: valIndex, - } - cs.privValidator.SignHeartbeat(chainID, heartbeat) - cs.eventBus.PublishEventProposalHeartbeat(types.EventDataProposalHeartbeat{heartbeat}) - cs.evsw.FireEvent(types.EventProposalHeartbeat, heartbeat) - counter++ - time.Sleep(proposalHeartbeatIntervalSeconds * time.Second) - } -} - -// Enter (CreateEmptyBlocks): from enterNewRound(height,round) -// Enter (CreateEmptyBlocks, CreateEmptyBlocksInterval > 0 ): after enterNewRound(height,round), after timeout of CreateEmptyBlocksInterval -// Enter (!CreateEmptyBlocks) : after enterNewRound(height,round), once txs are in the mempool -func (cs *ConsensusState) enterPropose(height int64, round int) { - logger := cs.Logger.With("height", height, "round", round) - - if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPropose <= cs.Step) { - logger.Debug(cmn.Fmt("enterPropose(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - logger.Info(cmn.Fmt("enterPropose(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - defer func() { - // Done enterPropose: - cs.updateRoundStep(round, cstypes.RoundStepPropose) - cs.newStep() - - // If we have the whole proposal + POL, then goto Prevote now. - // else, we'll enterPrevote when the rest of the proposal is received (in AddProposalBlockPart), - // or else after timeoutPropose - if cs.isProposalComplete() { - cs.enterPrevote(height, cs.Round) - } - }() - - // If we don't get the proposal and all block parts quick enough, enterPrevote - cs.scheduleTimeout(cs.config.Propose(round), height, round, cstypes.RoundStepPropose) - - // Nothing more to do if we're not a validator - if cs.privValidator == nil { - logger.Debug("This node is not a validator") - return - } - - // if not a validator, we're done - if !cs.Validators.HasAddress(cs.privValidator.GetAddress()) { - logger.Debug("This node is not a validator", "addr", cs.privValidator.GetAddress(), "vals", cs.Validators) - return - } - logger.Debug("This node is a validator") - - if cs.isProposer() { - logger.Info("enterPropose: Our turn to propose", "proposer", cs.Validators.GetProposer().Address, "privValidator", cs.privValidator) - cs.decideProposal(height, round) - } else { - logger.Info("enterPropose: Not our turn to propose", "proposer", cs.Validators.GetProposer().Address, "privValidator", cs.privValidator) - } -} - -func (cs *ConsensusState) isProposer() bool { - return bytes.Equal(cs.Validators.GetProposer().Address, cs.privValidator.GetAddress()) -} - -func (cs *ConsensusState) defaultDecideProposal(height int64, round int) { - var block *types.Block - var blockParts *types.PartSet - - // Decide on block - if cs.LockedBlock != nil { - // If we're locked onto a block, just choose that. - block, blockParts = cs.LockedBlock, cs.LockedBlockParts - } else if cs.ValidBlock != nil { - // If there is valid block, choose that. - block, blockParts = cs.ValidBlock, cs.ValidBlockParts - } else { - // Create a new proposal block from state/txs from the mempool. - block, blockParts = cs.createProposalBlock() - if block == nil { // on error - return - } - } - - // Make proposal - polRound, polBlockID := cs.Votes.POLInfo() - proposal := types.NewProposal(height, round, blockParts.Header(), polRound, polBlockID) - if err := cs.privValidator.SignProposal(cs.state.ChainID, proposal); err == nil { - // Set fields - /* fields set by setProposal and addBlockPart - cs.Proposal = proposal - cs.ProposalBlock = block - cs.ProposalBlockParts = blockParts - */ - - // send proposal and block parts on internal msg queue - cs.sendInternalMessage(msgInfo{&ProposalMessage{proposal}, ""}) - for i := 0; i < blockParts.Total(); i++ { - part := blockParts.GetPart(i) - cs.sendInternalMessage(msgInfo{&BlockPartMessage{cs.Height, cs.Round, part}, ""}) - } - cs.Logger.Info("Signed proposal", "height", height, "round", round, "proposal", proposal) - cs.Logger.Debug(cmn.Fmt("Signed proposal block: %v", block)) - } else { - if !cs.replayMode { - cs.Logger.Error("enterPropose: Error signing proposal", "height", height, "round", round, "err", err) - } - } -} - -// Returns true if the proposal block is complete && -// (if POLRound was proposed, we have +2/3 prevotes from there). -func (cs *ConsensusState) isProposalComplete() bool { - if cs.Proposal == nil || cs.ProposalBlock == nil { - return false - } - // we have the proposal. if there's a POLRound, - // make sure we have the prevotes from it too - if cs.Proposal.POLRound < 0 { - return true - } - // if this is false the proposer is lying or we haven't received the POL yet - return cs.Votes.Prevotes(cs.Proposal.POLRound).HasTwoThirdsMajority() - -} - -// Create the next block to propose and return it. -// Returns nil block upon error. -// NOTE: keep it side-effect free for clarity. -func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts *types.PartSet) { - var commit *types.Commit - if cs.Height == 1 { - // We're creating a proposal for the first block. - // The commit is empty, but not nil. - commit = &types.Commit{} - } else if cs.LastCommit.HasTwoThirdsMajority() { - // Make the commit from LastCommit - commit = cs.LastCommit.MakeCommit() - } else { - // This shouldn't happen. - cs.Logger.Error("enterPropose: Cannot propose anything: No commit for the previous block.") - return - } - - // Mempool validated transactions - txs := cs.mempool.Reap(cs.config.MaxBlockSizeTxs) - block, parts := cs.state.MakeBlock(cs.Height, txs, commit) - evidence := cs.evpool.PendingEvidence() - block.AddEvidence(evidence) - return block, parts -} - -// Enter: `timeoutPropose` after entering Propose. -// Enter: proposal block and POL is ready. -// Enter: any +2/3 prevotes for future round. -// Prevote for LockedBlock if we're locked, or ProposalBlock if valid. -// Otherwise vote nil. -func (cs *ConsensusState) enterPrevote(height int64, round int) { - if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrevote <= cs.Step) { - cs.Logger.Debug(cmn.Fmt("enterPrevote(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - - defer func() { - // Done enterPrevote: - cs.updateRoundStep(round, cstypes.RoundStepPrevote) - cs.newStep() - }() - - // fire event for how we got here - if cs.isProposalComplete() { - cs.eventBus.PublishEventCompleteProposal(cs.RoundStateEvent()) - } else { - // we received +2/3 prevotes for a future round - // TODO: catchup event? - } - - cs.Logger.Info(cmn.Fmt("enterPrevote(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - // Sign and broadcast vote as necessary - cs.doPrevote(height, round) - - // Once `addVote` hits any +2/3 prevotes, we will go to PrevoteWait - // (so we have more time to try and collect +2/3 prevotes for a single block) -} - -func (cs *ConsensusState) defaultDoPrevote(height int64, round int) { - logger := cs.Logger.With("height", height, "round", round) - // If a block is locked, prevote that. - if cs.LockedBlock != nil { - logger.Info("enterPrevote: Block was locked") - cs.signAddVote(types.VoteTypePrevote, cs.LockedBlock.Hash(), cs.LockedBlockParts.Header()) - return - } - - // If ProposalBlock is nil, prevote nil. - if cs.ProposalBlock == nil { - logger.Info("enterPrevote: ProposalBlock is nil") - cs.signAddVote(types.VoteTypePrevote, nil, types.PartSetHeader{}) - return - } - - // Validate proposal block - err := cs.blockExec.ValidateBlock(cs.state, cs.ProposalBlock) - if err != nil { - // ProposalBlock is invalid, prevote nil. - logger.Error("enterPrevote: ProposalBlock is invalid", "err", err) - cs.signAddVote(types.VoteTypePrevote, nil, types.PartSetHeader{}) - return - } - - // Prevote cs.ProposalBlock - // NOTE: the proposal signature is validated when it is received, - // and the proposal block parts are validated as they are received (against the merkle hash in the proposal) - logger.Info("enterPrevote: ProposalBlock is valid") - cs.signAddVote(types.VoteTypePrevote, cs.ProposalBlock.Hash(), cs.ProposalBlockParts.Header()) -} - -// Enter: any +2/3 prevotes at next round. -func (cs *ConsensusState) enterPrevoteWait(height int64, round int) { - logger := cs.Logger.With("height", height, "round", round) - - if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrevoteWait <= cs.Step) { - logger.Debug(cmn.Fmt("enterPrevoteWait(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - if !cs.Votes.Prevotes(round).HasTwoThirdsAny() { - cmn.PanicSanity(cmn.Fmt("enterPrevoteWait(%v/%v), but Prevotes does not have any +2/3 votes", height, round)) - } - logger.Info(cmn.Fmt("enterPrevoteWait(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - defer func() { - // Done enterPrevoteWait: - cs.updateRoundStep(round, cstypes.RoundStepPrevoteWait) - cs.newStep() - }() - - // Wait for some more prevotes; enterPrecommit - cs.scheduleTimeout(cs.config.Prevote(round), height, round, cstypes.RoundStepPrevoteWait) -} - -// Enter: `timeoutPrevote` after any +2/3 prevotes. -// Enter: +2/3 precomits for block or nil. -// Enter: any +2/3 precommits for next round. -// Lock & precommit the ProposalBlock if we have enough prevotes for it (a POL in this round) -// else, unlock an existing lock and precommit nil if +2/3 of prevotes were nil, -// else, precommit nil otherwise. -func (cs *ConsensusState) enterPrecommit(height int64, round int) { - logger := cs.Logger.With("height", height, "round", round) - - if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrecommit <= cs.Step) { - logger.Debug(cmn.Fmt("enterPrecommit(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - - logger.Info(cmn.Fmt("enterPrecommit(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - defer func() { - // Done enterPrecommit: - cs.updateRoundStep(round, cstypes.RoundStepPrecommit) - cs.newStep() - }() - - // check for a polka - blockID, ok := cs.Votes.Prevotes(round).TwoThirdsMajority() - - // If we don't have a polka, we must precommit nil. - if !ok { - if cs.LockedBlock != nil { - logger.Info("enterPrecommit: No +2/3 prevotes during enterPrecommit while we're locked. Precommitting nil") - } else { - logger.Info("enterPrecommit: No +2/3 prevotes during enterPrecommit. Precommitting nil.") - } - cs.signAddVote(types.VoteTypePrecommit, nil, types.PartSetHeader{}) - return - } - - // At this point +2/3 prevoted for a particular block or nil. - cs.eventBus.PublishEventPolka(cs.RoundStateEvent()) - - // the latest POLRound should be this round. - polRound, _ := cs.Votes.POLInfo() - if polRound < round { - cmn.PanicSanity(cmn.Fmt("This POLRound should be %v but got %", round, polRound)) - } - - // +2/3 prevoted nil. Unlock and precommit nil. - if len(blockID.Hash) == 0 { - if cs.LockedBlock == nil { - logger.Info("enterPrecommit: +2/3 prevoted for nil.") - } else { - logger.Info("enterPrecommit: +2/3 prevoted for nil. Unlocking") - cs.LockedRound = 0 - cs.LockedBlock = nil - cs.LockedBlockParts = nil - cs.eventBus.PublishEventUnlock(cs.RoundStateEvent()) - } - cs.signAddVote(types.VoteTypePrecommit, nil, types.PartSetHeader{}) - return - } - - // At this point, +2/3 prevoted for a particular block. - - // If we're already locked on that block, precommit it, and update the LockedRound - if cs.LockedBlock.HashesTo(blockID.Hash) { - logger.Info("enterPrecommit: +2/3 prevoted locked block. Relocking") - cs.LockedRound = round - cs.eventBus.PublishEventRelock(cs.RoundStateEvent()) - cs.signAddVote(types.VoteTypePrecommit, blockID.Hash, blockID.PartsHeader) - return - } - - // If +2/3 prevoted for proposal block, stage and precommit it - if cs.ProposalBlock.HashesTo(blockID.Hash) { - logger.Info("enterPrecommit: +2/3 prevoted proposal block. Locking", "hash", blockID.Hash) - // Validate the block. - if err := cs.blockExec.ValidateBlock(cs.state, cs.ProposalBlock); err != nil { - cmn.PanicConsensus(cmn.Fmt("enterPrecommit: +2/3 prevoted for an invalid block: %v", err)) - } - cs.LockedRound = round - cs.LockedBlock = cs.ProposalBlock - cs.LockedBlockParts = cs.ProposalBlockParts - cs.eventBus.PublishEventLock(cs.RoundStateEvent()) - cs.signAddVote(types.VoteTypePrecommit, blockID.Hash, blockID.PartsHeader) - return - } - - // There was a polka in this round for a block we don't have. - // Fetch that block, unlock, and precommit nil. - // The +2/3 prevotes for this round is the POL for our unlock. - // TODO: In the future save the POL prevotes for justification. - cs.LockedRound = 0 - cs.LockedBlock = nil - cs.LockedBlockParts = nil - if !cs.ProposalBlockParts.HasHeader(blockID.PartsHeader) { - cs.ProposalBlock = nil - cs.ProposalBlockParts = types.NewPartSetFromHeader(blockID.PartsHeader) - } - cs.eventBus.PublishEventUnlock(cs.RoundStateEvent()) - cs.signAddVote(types.VoteTypePrecommit, nil, types.PartSetHeader{}) -} - -// Enter: any +2/3 precommits for next round. -func (cs *ConsensusState) enterPrecommitWait(height int64, round int) { - logger := cs.Logger.With("height", height, "round", round) - - if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrecommitWait <= cs.Step) { - logger.Debug(cmn.Fmt("enterPrecommitWait(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - if !cs.Votes.Precommits(round).HasTwoThirdsAny() { - cmn.PanicSanity(cmn.Fmt("enterPrecommitWait(%v/%v), but Precommits does not have any +2/3 votes", height, round)) - } - logger.Info(cmn.Fmt("enterPrecommitWait(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - defer func() { - // Done enterPrecommitWait: - cs.updateRoundStep(round, cstypes.RoundStepPrecommitWait) - cs.newStep() - }() - - // Wait for some more precommits; enterNewRound - cs.scheduleTimeout(cs.config.Precommit(round), height, round, cstypes.RoundStepPrecommitWait) - -} - -// Enter: +2/3 precommits for block -func (cs *ConsensusState) enterCommit(height int64, commitRound int) { - logger := cs.Logger.With("height", height, "commitRound", commitRound) - - if cs.Height != height || cstypes.RoundStepCommit <= cs.Step { - logger.Debug(cmn.Fmt("enterCommit(%v/%v): Invalid args. Current step: %v/%v/%v", height, commitRound, cs.Height, cs.Round, cs.Step)) - return - } - logger.Info(cmn.Fmt("enterCommit(%v/%v). Current: %v/%v/%v", height, commitRound, cs.Height, cs.Round, cs.Step)) - - defer func() { - // Done enterCommit: - // keep cs.Round the same, commitRound points to the right Precommits set. - cs.updateRoundStep(cs.Round, cstypes.RoundStepCommit) - cs.CommitRound = commitRound - cs.CommitTime = time.Now() - cs.newStep() - - // Maybe finalize immediately. - cs.tryFinalizeCommit(height) - }() - - blockID, ok := cs.Votes.Precommits(commitRound).TwoThirdsMajority() - if !ok { - cmn.PanicSanity("RunActionCommit() expects +2/3 precommits") - } - - // The Locked* fields no longer matter. - // Move them over to ProposalBlock if they match the commit hash, - // otherwise they'll be cleared in updateToState. - if cs.LockedBlock.HashesTo(blockID.Hash) { - logger.Info("Commit is for locked block. Set ProposalBlock=LockedBlock", "blockHash", blockID.Hash) - cs.ProposalBlock = cs.LockedBlock - cs.ProposalBlockParts = cs.LockedBlockParts - } - - // If we don't have the block being committed, set up to get it. - if !cs.ProposalBlock.HashesTo(blockID.Hash) { - if !cs.ProposalBlockParts.HasHeader(blockID.PartsHeader) { - logger.Info("Commit is for a block we don't know about. Set ProposalBlock=nil", "proposal", cs.ProposalBlock.Hash(), "commit", blockID.Hash) - // We're getting the wrong block. - // Set up ProposalBlockParts and keep waiting. - cs.ProposalBlock = nil - cs.ProposalBlockParts = types.NewPartSetFromHeader(blockID.PartsHeader) - } else { - // We just need to keep waiting. - } - } -} - -// If we have the block AND +2/3 commits for it, finalize. -func (cs *ConsensusState) tryFinalizeCommit(height int64) { - logger := cs.Logger.With("height", height) - - if cs.Height != height { - cmn.PanicSanity(cmn.Fmt("tryFinalizeCommit() cs.Height: %v vs height: %v", cs.Height, height)) - } - - blockID, ok := cs.Votes.Precommits(cs.CommitRound).TwoThirdsMajority() - if !ok || len(blockID.Hash) == 0 { - logger.Error("Attempt to finalize failed. There was no +2/3 majority, or +2/3 was for .") - return - } - if !cs.ProposalBlock.HashesTo(blockID.Hash) { - // TODO: this happens every time if we're not a validator (ugly logs) - // TODO: ^^ wait, why does it matter that we're a validator? - logger.Info("Attempt to finalize failed. We don't have the commit block.", "proposal-block", cs.ProposalBlock.Hash(), "commit-block", blockID.Hash) - return - } - - // go - cs.finalizeCommit(height) -} - -// Increment height and goto cstypes.RoundStepNewHeight -func (cs *ConsensusState) finalizeCommit(height int64) { - if cs.Height != height || cs.Step != cstypes.RoundStepCommit { - cs.Logger.Debug(cmn.Fmt("finalizeCommit(%v): Invalid args. Current step: %v/%v/%v", height, cs.Height, cs.Round, cs.Step)) - return - } - - blockID, ok := cs.Votes.Precommits(cs.CommitRound).TwoThirdsMajority() - block, blockParts := cs.ProposalBlock, cs.ProposalBlockParts - - if !ok { - cmn.PanicSanity(cmn.Fmt("Cannot finalizeCommit, commit does not have two thirds majority")) - } - if !blockParts.HasHeader(blockID.PartsHeader) { - cmn.PanicSanity(cmn.Fmt("Expected ProposalBlockParts header to be commit header")) - } - if !block.HashesTo(blockID.Hash) { - cmn.PanicSanity(cmn.Fmt("Cannot finalizeCommit, ProposalBlock does not hash to commit hash")) - } - if err := cs.blockExec.ValidateBlock(cs.state, block); err != nil { - cmn.PanicConsensus(cmn.Fmt("+2/3 committed an invalid block: %v", err)) - } - - cs.Logger.Info(cmn.Fmt("Finalizing commit of block with %d txs", block.NumTxs), - "height", block.Height, "hash", block.Hash(), "root", block.AppHash) - cs.Logger.Info(cmn.Fmt("%v", block)) - - fail.Fail() // XXX - - // Save to blockStore. - if cs.blockStore.Height() < block.Height { - // NOTE: the seenCommit is local justification to commit this block, - // but may differ from the LastCommit included in the next block - precommits := cs.Votes.Precommits(cs.CommitRound) - seenCommit := precommits.MakeCommit() - cs.blockStore.SaveBlock(block, blockParts, seenCommit) - } else { - // Happens during replay if we already saved the block but didn't commit - cs.Logger.Info("Calling finalizeCommit on already stored block", "height", block.Height) - } - - fail.Fail() // XXX - - // Write EndHeightMessage{} for this height, implying that the blockstore - // has saved the block. - // - // If we crash before writing this EndHeightMessage{}, we will recover by - // running ApplyBlock during the ABCI handshake when we restart. If we - // didn't save the block to the blockstore before writing - // EndHeightMessage{}, we'd have to change WAL replay -- currently it - // complains about replaying for heights where an #ENDHEIGHT entry already - // exists. - // - // Either way, the ConsensusState should not be resumed until we - // successfully call ApplyBlock (ie. later here, or in Handshake after - // restart). - cs.wal.WriteSync(EndHeightMessage{height}) // NOTE: fsync - - fail.Fail() // XXX - - // Create a copy of the state for staging and an event cache for txs. - stateCopy := cs.state.Copy() - - // Execute and commit the block, update and save the state, and update the mempool. - // NOTE The block.AppHash wont reflect these txs until the next block. - var err error - stateCopy, err = cs.blockExec.ApplyBlock(stateCopy, types.BlockID{block.Hash(), blockParts.Header()}, block) - if err != nil { - cs.Logger.Error("Error on ApplyBlock. Did the application crash? Please restart tendermint", "err", err) - err := cmn.Kill() - if err != nil { - cs.Logger.Error("Failed to kill this process - please do so manually", "err", err) - } - return - } - - fail.Fail() // XXX - - // must be called before we update state - cs.recordMetrics(height, block) - - // NewHeightStep! - cs.updateToState(stateCopy) - - fail.Fail() // XXX - - // cs.StartTime is already set. - // Schedule Round0 to start soon. - cs.scheduleRound0(&cs.RoundState) - - // By here, - // * cs.Height has been increment to height+1 - // * cs.Step is now cstypes.RoundStepNewHeight - // * cs.StartTime is set to when we will start round0. -} - -func (cs *ConsensusState) recordMetrics(height int64, block *types.Block) { - cs.metrics.Validators.Set(float64(cs.Validators.Size())) - cs.metrics.ValidatorsPower.Set(float64(cs.Validators.TotalVotingPower())) - missingValidators := 0 - missingValidatorsPower := int64(0) - for i, val := range cs.Validators.Validators { - var vote *types.Vote - if i < len(block.LastCommit.Precommits) { - vote = block.LastCommit.Precommits[i] - } - if vote == nil { - missingValidators++ - missingValidatorsPower += val.VotingPower - } - } - cs.metrics.MissingValidators.Set(float64(missingValidators)) - cs.metrics.MissingValidatorsPower.Set(float64(missingValidatorsPower)) - cs.metrics.ByzantineValidators.Set(float64(len(block.Evidence.Evidence))) - byzantineValidatorsPower := int64(0) - for _, ev := range block.Evidence.Evidence { - if _, val := cs.Validators.GetByAddress(ev.Address()); val != nil { - byzantineValidatorsPower += val.VotingPower - } - } - cs.metrics.ByzantineValidatorsPower.Set(float64(byzantineValidatorsPower)) - - if height > 1 { - lastBlockMeta := cs.blockStore.LoadBlockMeta(height - 1) - cs.metrics.BlockIntervalSeconds.Observe( - block.Time.Sub(lastBlockMeta.Header.Time).Seconds(), - ) - } - - cs.metrics.NumTxs.Set(float64(block.NumTxs)) - cs.metrics.BlockSizeBytes.Set(float64(block.Size())) - cs.metrics.TotalTxs.Set(float64(block.TotalTxs)) -} - -//----------------------------------------------------------------------------- - -func (cs *ConsensusState) defaultSetProposal(proposal *types.Proposal) error { - // Already have one - // TODO: possibly catch double proposals - if cs.Proposal != nil { - return nil - } - - // Does not apply - if proposal.Height != cs.Height || proposal.Round != cs.Round { - return nil - } - - // We don't care about the proposal if we're already in cstypes.RoundStepCommit. - if cstypes.RoundStepCommit <= cs.Step { - return nil - } - - // Verify POLRound, which must be -1 or between 0 and proposal.Round exclusive. - if proposal.POLRound != -1 && - (proposal.POLRound < 0 || proposal.Round <= proposal.POLRound) { - return ErrInvalidProposalPOLRound - } - - // Verify signature - if !cs.Validators.GetProposer().PubKey.VerifyBytes(proposal.SignBytes(cs.state.ChainID), proposal.Signature) { - return ErrInvalidProposalSignature - } - - cs.Proposal = proposal - cs.ProposalBlockParts = types.NewPartSetFromHeader(proposal.BlockPartsHeader) - cs.Logger.Info("Received proposal", "proposal", proposal) - return nil -} - -// NOTE: block is not necessarily valid. -// Asynchronously triggers either enterPrevote (before we timeout of propose) or tryFinalizeCommit, once we have the full block. -func (cs *ConsensusState) addProposalBlockPart(height int64, part *types.Part) (added bool, err error) { - // Blocks might be reused, so round mismatch is OK - if cs.Height != height { - cs.Logger.Debug("Received block part from wrong height", "height", height) - return false, nil - } - - // We're not expecting a block part. - if cs.ProposalBlockParts == nil { - cs.Logger.Info("Received a block part when we're not expecting any", "height", height) - return false, nil // TODO: bad peer? Return error? - } - - added, err = cs.ProposalBlockParts.AddPart(part) - if err != nil { - return added, err - } - if added && cs.ProposalBlockParts.IsComplete() { - // Added and completed! - _, err = cdc.UnmarshalBinaryReader(cs.ProposalBlockParts.GetReader(), &cs.ProposalBlock, int64(cs.state.ConsensusParams.BlockSize.MaxBytes)) - if err != nil { - return true, err - } - // NOTE: it's possible to receive complete proposal blocks for future rounds without having the proposal - cs.Logger.Info("Received complete proposal block", "height", cs.ProposalBlock.Height, "hash", cs.ProposalBlock.Hash()) - - // Update Valid* if we can. - prevotes := cs.Votes.Prevotes(cs.Round) - blockID, hasTwoThirds := prevotes.TwoThirdsMajority() - if hasTwoThirds && !blockID.IsZero() && (cs.ValidRound < cs.Round) { - if cs.ProposalBlock.HashesTo(blockID.Hash) { - cs.Logger.Info("Updating valid block to new proposal block", - "valid-round", cs.Round, "valid-block-hash", cs.ProposalBlock.Hash()) - cs.ValidRound = cs.Round - cs.ValidBlock = cs.ProposalBlock - cs.ValidBlockParts = cs.ProposalBlockParts - } - // TODO: In case there is +2/3 majority in Prevotes set for some - // block and cs.ProposalBlock contains different block, either - // proposer is faulty or voting power of faulty processes is more - // than 1/3. We should trigger in the future accountability - // procedure at this point. - } - - if cs.Step == cstypes.RoundStepPropose && cs.isProposalComplete() { - // Move onto the next step - cs.enterPrevote(height, cs.Round) - } else if cs.Step == cstypes.RoundStepCommit { - // If we're waiting on the proposal block... - cs.tryFinalizeCommit(height) - } - return true, nil - } - return added, nil -} - -// Attempt to add the vote. if its a duplicate signature, dupeout the validator -func (cs *ConsensusState) tryAddVote(vote *types.Vote, peerID p2p.ID) error { - _, err := cs.addVote(vote, peerID) - if err != nil { - // If the vote height is off, we'll just ignore it, - // But if it's a conflicting sig, add it to the cs.evpool. - // If it's otherwise invalid, punish peer. - if err == ErrVoteHeightMismatch { - return err - } else if voteErr, ok := err.(*types.ErrVoteConflictingVotes); ok { - if bytes.Equal(vote.ValidatorAddress, cs.privValidator.GetAddress()) { - cs.Logger.Error("Found conflicting vote from ourselves. Did you unsafe_reset a validator?", "height", vote.Height, "round", vote.Round, "type", vote.Type) - return err - } - cs.evpool.AddEvidence(voteErr.DuplicateVoteEvidence) - return err - } else { - // Probably an invalid signature / Bad peer. - // Seems this can also err sometimes with "Unexpected step" - perhaps not from a bad peer ? - cs.Logger.Error("Error attempting to add vote", "err", err) - return ErrAddingVote - } - } - return nil -} - -//----------------------------------------------------------------------------- - -func (cs *ConsensusState) addVote(vote *types.Vote, peerID p2p.ID) (added bool, err error) { - cs.Logger.Debug("addVote", "voteHeight", vote.Height, "voteType", vote.Type, "valIndex", vote.ValidatorIndex, "csHeight", cs.Height) - - // A precommit for the previous height? - // These come in while we wait timeoutCommit - if vote.Height+1 == cs.Height { - if !(cs.Step == cstypes.RoundStepNewHeight && vote.Type == types.VoteTypePrecommit) { - // TODO: give the reason .. - // fmt.Errorf("tryAddVote: Wrong height, not a LastCommit straggler commit.") - return added, ErrVoteHeightMismatch - } - added, err = cs.LastCommit.AddVote(vote) - if !added { - return added, err - } - - cs.Logger.Info(cmn.Fmt("Added to lastPrecommits: %v", cs.LastCommit.StringShort())) - cs.eventBus.PublishEventVote(types.EventDataVote{vote}) - cs.evsw.FireEvent(types.EventVote, vote) - - // if we can skip timeoutCommit and have all the votes now, - if cs.config.SkipTimeoutCommit && cs.LastCommit.HasAll() { - // go straight to new round (skip timeout commit) - // cs.scheduleTimeout(time.Duration(0), cs.Height, 0, cstypes.RoundStepNewHeight) - cs.enterNewRound(cs.Height, 0) - } - - return - } - - // Height mismatch is ignored. - // Not necessarily a bad peer, but not favourable behaviour. - if vote.Height != cs.Height { - err = ErrVoteHeightMismatch - cs.Logger.Info("Vote ignored and not added", "voteHeight", vote.Height, "csHeight", cs.Height, "err", err) - return - } - - height := cs.Height - added, err = cs.Votes.AddVote(vote, peerID) - if !added { - // Either duplicate, or error upon cs.Votes.AddByIndex() - return - } - - cs.eventBus.PublishEventVote(types.EventDataVote{vote}) - cs.evsw.FireEvent(types.EventVote, vote) - - switch vote.Type { - case types.VoteTypePrevote: - prevotes := cs.Votes.Prevotes(vote.Round) - cs.Logger.Info("Added to prevote", "vote", vote, "prevotes", prevotes.StringShort()) - - // If +2/3 prevotes for a block or nil for *any* round: - if blockID, ok := prevotes.TwoThirdsMajority(); ok { - - // There was a polka! - // If we're locked but this is a recent polka, unlock. - // If it matches our ProposalBlock, update the ValidBlock - - // Unlock if `cs.LockedRound < vote.Round <= cs.Round` - // NOTE: If vote.Round > cs.Round, we'll deal with it when we get to vote.Round - if (cs.LockedBlock != nil) && - (cs.LockedRound < vote.Round) && - (vote.Round <= cs.Round) && - !cs.LockedBlock.HashesTo(blockID.Hash) { - - cs.Logger.Info("Unlocking because of POL.", "lockedRound", cs.LockedRound, "POLRound", vote.Round) - cs.LockedRound = 0 - cs.LockedBlock = nil - cs.LockedBlockParts = nil - cs.eventBus.PublishEventUnlock(cs.RoundStateEvent()) - } - - // Update Valid* if we can. - // NOTE: our proposal block may be nil or not what received a polka.. - // TODO: we may want to still update the ValidBlock and obtain it via gossipping - if !blockID.IsZero() && - (cs.ValidRound < vote.Round) && - (vote.Round <= cs.Round) && - cs.ProposalBlock.HashesTo(blockID.Hash) { - - cs.Logger.Info("Updating ValidBlock because of POL.", "validRound", cs.ValidRound, "POLRound", vote.Round) - cs.ValidRound = vote.Round - cs.ValidBlock = cs.ProposalBlock - cs.ValidBlockParts = cs.ProposalBlockParts - } - } - - // If +2/3 prevotes for *anything* for this or future round: - if cs.Round <= vote.Round && prevotes.HasTwoThirdsAny() { - // Round-skip over to PrevoteWait or goto Precommit. - cs.enterNewRound(height, vote.Round) // if the vote is ahead of us - if prevotes.HasTwoThirdsMajority() { - cs.enterPrecommit(height, vote.Round) - } else { - cs.enterPrevote(height, vote.Round) // if the vote is ahead of us - cs.enterPrevoteWait(height, vote.Round) - } - } else if cs.Proposal != nil && 0 <= cs.Proposal.POLRound && cs.Proposal.POLRound == vote.Round { - // If the proposal is now complete, enter prevote of cs.Round. - if cs.isProposalComplete() { - cs.enterPrevote(height, cs.Round) - } - } - - case types.VoteTypePrecommit: - precommits := cs.Votes.Precommits(vote.Round) - cs.Logger.Info("Added to precommit", "vote", vote, "precommits", precommits.StringShort()) - blockID, ok := precommits.TwoThirdsMajority() - if ok { - if len(blockID.Hash) == 0 { - cs.enterNewRound(height, vote.Round+1) - } else { - cs.enterNewRound(height, vote.Round) - cs.enterPrecommit(height, vote.Round) - cs.enterCommit(height, vote.Round) - - if cs.config.SkipTimeoutCommit && precommits.HasAll() { - // if we have all the votes now, - // go straight to new round (skip timeout commit) - // cs.scheduleTimeout(time.Duration(0), cs.Height, 0, cstypes.RoundStepNewHeight) - cs.enterNewRound(cs.Height, 0) - } - - } - } else if cs.Round <= vote.Round && precommits.HasTwoThirdsAny() { - cs.enterNewRound(height, vote.Round) - cs.enterPrecommit(height, vote.Round) - cs.enterPrecommitWait(height, vote.Round) - } - default: - panic(cmn.Fmt("Unexpected vote type %X", vote.Type)) // go-wire should prevent this. - } - - return -} - -func (cs *ConsensusState) signVote(type_ byte, hash []byte, header types.PartSetHeader) (*types.Vote, error) { - addr := cs.privValidator.GetAddress() - valIndex, _ := cs.Validators.GetByAddress(addr) - vote := &types.Vote{ - ValidatorAddress: addr, - ValidatorIndex: valIndex, - Height: cs.Height, - Round: cs.Round, - Timestamp: time.Now().UTC(), - Type: type_, - BlockID: types.BlockID{hash, header}, - } - err := cs.privValidator.SignVote(cs.state.ChainID, vote) - return vote, err -} - -// sign the vote and publish on internalMsgQueue -func (cs *ConsensusState) signAddVote(type_ byte, hash []byte, header types.PartSetHeader) *types.Vote { - // if we don't have a key or we're not in the validator set, do nothing - if cs.privValidator == nil || !cs.Validators.HasAddress(cs.privValidator.GetAddress()) { - return nil - } - vote, err := cs.signVote(type_, hash, header) - if err == nil { - cs.sendInternalMessage(msgInfo{&VoteMessage{vote}, ""}) - cs.Logger.Info("Signed and pushed vote", "height", cs.Height, "round", cs.Round, "vote", vote, "err", err) - return vote - } - //if !cs.replayMode { - cs.Logger.Error("Error signing vote", "height", cs.Height, "round", cs.Round, "vote", vote, "err", err) - //} - return nil -} - -//--------------------------------------------------------- - -func CompareHRS(h1 int64, r1 int, s1 cstypes.RoundStepType, h2 int64, r2 int, s2 cstypes.RoundStepType) int { - if h1 < h2 { - return -1 - } else if h1 > h2 { - return 1 - } - if r1 < r2 { - return -1 - } else if r1 > r2 { - return 1 - } - if s1 < s2 { - return -1 - } else if s1 > s2 { - return 1 - } - return 0 -} diff --git a/consensus/state_test.go b/consensus/state_test.go deleted file mode 100644 index d0def6309..000000000 --- a/consensus/state_test.go +++ /dev/null @@ -1,1099 +0,0 @@ -package consensus - -import ( - "bytes" - "context" - "fmt" - "testing" - "time" - - cstypes "github.com/tendermint/tendermint/consensus/types" - tmpubsub "github.com/tendermint/tendermint/libs/pubsub" - "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/log" -) - -func init() { - config = ResetConfig("consensus_state_test") -} - -func ensureProposeTimeout(timeoutPropose int) time.Duration { - return time.Duration(timeoutPropose*2) * time.Millisecond -} - -/* - -ProposeSuite -x * TestProposerSelection0 - round robin ordering, round 0 -x * TestProposerSelection2 - round robin ordering, round 2++ -x * TestEnterProposeNoValidator - timeout into prevote round -x * TestEnterPropose - finish propose without timing out (we have the proposal) -x * TestBadProposal - 2 vals, bad proposal (bad block state hash), should prevote and precommit nil -FullRoundSuite -x * TestFullRound1 - 1 val, full successful round -x * TestFullRoundNil - 1 val, full round of nil -x * TestFullRound2 - 2 vals, both required for full round -LockSuite -x * TestLockNoPOL - 2 vals, 4 rounds. one val locked, precommits nil every round except first. -x * TestLockPOLRelock - 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka -x * TestLockPOLUnlock - 4 vals, one precommits, other 3 polka nil at next round, so we unlock and precomit nil -x * TestLockPOLSafety1 - 4 vals. We shouldn't change lock based on polka at earlier round -x * TestLockPOLSafety2 - 4 vals. After unlocking, we shouldn't relock based on polka at earlier round - * TestNetworkLock - once +1/3 precommits, network should be locked - * TestNetworkLockPOL - once +1/3 precommits, the block with more recent polka is committed -SlashingSuite -x * TestSlashingPrevotes - a validator prevoting twice in a round gets slashed -x * TestSlashingPrecommits - a validator precomitting twice in a round gets slashed -CatchupSuite - * TestCatchup - if we might be behind and we've seen any 2/3 prevotes, round skip to new round, precommit, or prevote -HaltSuite -x * TestHalt1 - if we see +2/3 precommits after timing out into new round, we should still commit - -*/ - -//---------------------------------------------------------------------------------------------------- -// ProposeSuite - -func TestStateProposerSelection0(t *testing.T) { - cs1, vss := randConsensusState(4) - height, round := cs1.Height, cs1.Round - - newRoundCh := subscribe(cs1.eventBus, types.EventQueryNewRound) - proposalCh := subscribe(cs1.eventBus, types.EventQueryCompleteProposal) - - startTestRound(cs1, height, round) - - // wait for new round so proposer is set - <-newRoundCh - - // lets commit a block and ensure proposer for the next height is correct - prop := cs1.GetRoundState().Validators.GetProposer() - if !bytes.Equal(prop.Address, cs1.privValidator.GetAddress()) { - t.Fatalf("expected proposer to be validator %d. Got %X", 0, prop.Address) - } - - // wait for complete proposal - <-proposalCh - - rs := cs1.GetRoundState() - signAddVotes(cs1, types.VoteTypePrecommit, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), vss[1:]...) - - // wait for new round so next validator is set - <-newRoundCh - - prop = cs1.GetRoundState().Validators.GetProposer() - if !bytes.Equal(prop.Address, vss[1].GetAddress()) { - panic(cmn.Fmt("expected proposer to be validator %d. Got %X", 1, prop.Address)) - } -} - -// Now let's do it all again, but starting from round 2 instead of 0 -func TestStateProposerSelection2(t *testing.T) { - cs1, vss := randConsensusState(4) // test needs more work for more than 3 validators - - newRoundCh := subscribe(cs1.eventBus, types.EventQueryNewRound) - - // this time we jump in at round 2 - incrementRound(vss[1:]...) - incrementRound(vss[1:]...) - startTestRound(cs1, cs1.Height, 2) - - <-newRoundCh // wait for the new round - - // everyone just votes nil. we get a new proposer each round - for i := 0; i < len(vss); i++ { - prop := cs1.GetRoundState().Validators.GetProposer() - if !bytes.Equal(prop.Address, vss[(i+2)%len(vss)].GetAddress()) { - panic(cmn.Fmt("expected proposer to be validator %d. Got %X", (i+2)%len(vss), prop.Address)) - } - - rs := cs1.GetRoundState() - signAddVotes(cs1, types.VoteTypePrecommit, nil, rs.ProposalBlockParts.Header(), vss[1:]...) - <-newRoundCh // wait for the new round event each round - - incrementRound(vss[1:]...) - } - -} - -// a non-validator should timeout into the prevote round -func TestStateEnterProposeNoPrivValidator(t *testing.T) { - cs, _ := randConsensusState(1) - cs.SetPrivValidator(nil) - height, round := cs.Height, cs.Round - - // Listen for propose timeout event - timeoutCh := subscribe(cs.eventBus, types.EventQueryTimeoutPropose) - - startTestRound(cs, height, round) - - // if we're not a validator, EnterPropose should timeout - ticker := time.NewTicker(ensureProposeTimeout(cs.config.TimeoutPropose)) - select { - case <-timeoutCh: - case <-ticker.C: - panic("Expected EnterPropose to timeout") - - } - - if cs.GetRoundState().Proposal != nil { - t.Error("Expected to make no proposal, since no privValidator") - } -} - -// a validator should not timeout of the prevote round (TODO: unless the block is really big!) -func TestStateEnterProposeYesPrivValidator(t *testing.T) { - cs, _ := randConsensusState(1) - height, round := cs.Height, cs.Round - - // Listen for propose timeout event - - timeoutCh := subscribe(cs.eventBus, types.EventQueryTimeoutPropose) - proposalCh := subscribe(cs.eventBus, types.EventQueryCompleteProposal) - - cs.enterNewRound(height, round) - cs.startRoutines(3) - - <-proposalCh - - // Check that Proposal, ProposalBlock, ProposalBlockParts are set. - rs := cs.GetRoundState() - if rs.Proposal == nil { - t.Error("rs.Proposal should be set") - } - if rs.ProposalBlock == nil { - t.Error("rs.ProposalBlock should be set") - } - if rs.ProposalBlockParts.Total() == 0 { - t.Error("rs.ProposalBlockParts should be set") - } - - // if we're a validator, enterPropose should not timeout - ticker := time.NewTicker(ensureProposeTimeout(cs.config.TimeoutPropose)) - select { - case <-timeoutCh: - panic("Expected EnterPropose not to timeout") - case <-ticker.C: - - } -} - -func TestStateBadProposal(t *testing.T) { - cs1, vss := randConsensusState(2) - height, round := cs1.Height, cs1.Round - vs2 := vss[1] - - partSize := cs1.state.ConsensusParams.BlockPartSizeBytes - - proposalCh := subscribe(cs1.eventBus, types.EventQueryCompleteProposal) - voteCh := subscribe(cs1.eventBus, types.EventQueryVote) - - propBlock, _ := cs1.createProposalBlock() //changeProposer(t, cs1, vs2) - - // make the second validator the proposer by incrementing round - round = round + 1 - incrementRound(vss[1:]...) - - // make the block bad by tampering with statehash - stateHash := propBlock.AppHash - if len(stateHash) == 0 { - stateHash = make([]byte, 32) - } - stateHash[0] = byte((stateHash[0] + 1) % 255) - propBlock.AppHash = stateHash - propBlockParts := propBlock.MakePartSet(partSize) - proposal := types.NewProposal(vs2.Height, round, propBlockParts.Header(), -1, types.BlockID{}) - if err := vs2.SignProposal(config.ChainID(), proposal); err != nil { - t.Fatal("failed to sign bad proposal", err) - } - - // set the proposal block - if err := cs1.SetProposalAndBlock(proposal, propBlock, propBlockParts, "some peer"); err != nil { - t.Fatal(err) - } - - // start the machine - startTestRound(cs1, height, round) - - // wait for proposal - <-proposalCh - - // wait for prevote - <-voteCh - - validatePrevote(t, cs1, round, vss[0], nil) - - // add bad prevote from vs2 and wait for it - signAddVotes(cs1, types.VoteTypePrevote, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) - <-voteCh - - // wait for precommit - <-voteCh - - validatePrecommit(t, cs1, round, 0, vss[0], nil, nil) - signAddVotes(cs1, types.VoteTypePrecommit, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) -} - -//---------------------------------------------------------------------------------------------------- -// FullRoundSuite - -// propose, prevote, and precommit a block -func TestStateFullRound1(t *testing.T) { - cs, vss := randConsensusState(1) - height, round := cs.Height, cs.Round - - // NOTE: buffer capacity of 0 ensures we can validate prevote and last commit - // before consensus can move to the next height (and cause a race condition) - cs.eventBus.Stop() - eventBus := types.NewEventBusWithBufferCapacity(0) - eventBus.SetLogger(log.TestingLogger().With("module", "events")) - cs.SetEventBus(eventBus) - eventBus.Start() - - voteCh := subscribe(cs.eventBus, types.EventQueryVote) - propCh := subscribe(cs.eventBus, types.EventQueryCompleteProposal) - newRoundCh := subscribe(cs.eventBus, types.EventQueryNewRound) - - startTestRound(cs, height, round) - - <-newRoundCh - - // grab proposal - re := <-propCh - propBlockHash := re.(types.EventDataRoundState).RoundState.(*cstypes.RoundState).ProposalBlock.Hash() - - <-voteCh // wait for prevote - validatePrevote(t, cs, round, vss[0], propBlockHash) - - <-voteCh // wait for precommit - - // we're going to roll right into new height - <-newRoundCh - - validateLastPrecommit(t, cs, vss[0], propBlockHash) -} - -// nil is proposed, so prevote and precommit nil -func TestStateFullRoundNil(t *testing.T) { - cs, vss := randConsensusState(1) - height, round := cs.Height, cs.Round - - voteCh := subscribe(cs.eventBus, types.EventQueryVote) - - cs.enterPrevote(height, round) - cs.startRoutines(4) - - <-voteCh // prevote - <-voteCh // precommit - - // should prevote and precommit nil - validatePrevoteAndPrecommit(t, cs, round, 0, vss[0], nil, nil) -} - -// run through propose, prevote, precommit commit with two validators -// where the first validator has to wait for votes from the second -func TestStateFullRound2(t *testing.T) { - cs1, vss := randConsensusState(2) - vs2 := vss[1] - height, round := cs1.Height, cs1.Round - - voteCh := subscribe(cs1.eventBus, types.EventQueryVote) - newBlockCh := subscribe(cs1.eventBus, types.EventQueryNewBlock) - - // start round and wait for propose and prevote - startTestRound(cs1, height, round) - - <-voteCh // prevote - - // we should be stuck in limbo waiting for more prevotes - rs := cs1.GetRoundState() - propBlockHash, propPartsHeader := rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header() - - // prevote arrives from vs2: - signAddVotes(cs1, types.VoteTypePrevote, propBlockHash, propPartsHeader, vs2) - <-voteCh - - <-voteCh //precommit - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], propBlockHash, propBlockHash) - - // we should be stuck in limbo waiting for more precommits - - // precommit arrives from vs2: - signAddVotes(cs1, types.VoteTypePrecommit, propBlockHash, propPartsHeader, vs2) - <-voteCh - - // wait to finish commit, propose in next height - <-newBlockCh -} - -//------------------------------------------------------------------------------------------ -// LockSuite - -// two validators, 4 rounds. -// two vals take turns proposing. val1 locks on first one, precommits nil on everything else -func TestStateLockNoPOL(t *testing.T) { - cs1, vss := randConsensusState(2) - vs2 := vss[1] - height := cs1.Height - - partSize := cs1.state.ConsensusParams.BlockPartSizeBytes - - timeoutProposeCh := subscribe(cs1.eventBus, types.EventQueryTimeoutPropose) - timeoutWaitCh := subscribe(cs1.eventBus, types.EventQueryTimeoutWait) - voteCh := subscribe(cs1.eventBus, types.EventQueryVote) - proposalCh := subscribe(cs1.eventBus, types.EventQueryCompleteProposal) - newRoundCh := subscribe(cs1.eventBus, types.EventQueryNewRound) - - /* - Round1 (cs1, B) // B B // B B2 - */ - - // start round and wait for prevote - cs1.enterNewRound(height, 0) - cs1.startRoutines(0) - - re := <-proposalCh - rs := re.(types.EventDataRoundState).RoundState.(*cstypes.RoundState) - theBlockHash := rs.ProposalBlock.Hash() - - <-voteCh // prevote - - // we should now be stuck in limbo forever, waiting for more prevotes - // prevote arrives from vs2: - signAddVotes(cs1, types.VoteTypePrevote, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), vs2) - <-voteCh // prevote - - <-voteCh // precommit - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash) - - // we should now be stuck in limbo forever, waiting for more precommits - // lets add one for a different block - // NOTE: in practice we should never get to a point where there are precommits for different blocks at the same round - hash := make([]byte, len(theBlockHash)) - copy(hash, theBlockHash) - hash[0] = byte((hash[0] + 1) % 255) - signAddVotes(cs1, types.VoteTypePrecommit, hash, rs.ProposalBlock.MakePartSet(partSize).Header(), vs2) - <-voteCh // precommit - - // (note we're entering precommit for a second time this round) - // but with invalid args. then we enterPrecommitWait, and the timeout to new round - <-timeoutWaitCh - - /// - - <-newRoundCh - t.Log("#### ONTO ROUND 1") - /* - Round2 (cs1, B) // B B2 - */ - - incrementRound(vs2) - - // now we're on a new round and not the proposer, so wait for timeout - re = <-timeoutProposeCh - rs = re.(types.EventDataRoundState).RoundState.(*cstypes.RoundState) - - if rs.ProposalBlock != nil { - panic("Expected proposal block to be nil") - } - - // wait to finish prevote - <-voteCh - - // we should have prevoted our locked block - validatePrevote(t, cs1, 1, vss[0], rs.LockedBlock.Hash()) - - // add a conflicting prevote from the other validator - signAddVotes(cs1, types.VoteTypePrevote, hash, rs.LockedBlock.MakePartSet(partSize).Header(), vs2) - <-voteCh - - // now we're going to enter prevote again, but with invalid args - // and then prevote wait, which should timeout. then wait for precommit - <-timeoutWaitCh - - <-voteCh // precommit - - // the proposed block should still be locked and our precommit added - // we should precommit nil and be locked on the proposal - validatePrecommit(t, cs1, 1, 0, vss[0], nil, theBlockHash) - - // add conflicting precommit from vs2 - // NOTE: in practice we should never get to a point where there are precommits for different blocks at the same round - signAddVotes(cs1, types.VoteTypePrecommit, hash, rs.LockedBlock.MakePartSet(partSize).Header(), vs2) - <-voteCh - - // (note we're entering precommit for a second time this round, but with invalid args - // then we enterPrecommitWait and timeout into NewRound - <-timeoutWaitCh - - <-newRoundCh - t.Log("#### ONTO ROUND 2") - /* - Round3 (vs2, _) // B, B2 - */ - - incrementRound(vs2) - - re = <-proposalCh - rs = re.(types.EventDataRoundState).RoundState.(*cstypes.RoundState) - - // now we're on a new round and are the proposer - if !bytes.Equal(rs.ProposalBlock.Hash(), rs.LockedBlock.Hash()) { - panic(cmn.Fmt("Expected proposal block to be locked block. Got %v, Expected %v", rs.ProposalBlock, rs.LockedBlock)) - } - - <-voteCh // prevote - - validatePrevote(t, cs1, 2, vss[0], rs.LockedBlock.Hash()) - - signAddVotes(cs1, types.VoteTypePrevote, hash, rs.ProposalBlock.MakePartSet(partSize).Header(), vs2) - <-voteCh - - <-timeoutWaitCh // prevote wait - <-voteCh // precommit - - validatePrecommit(t, cs1, 2, 0, vss[0], nil, theBlockHash) // precommit nil but be locked on proposal - - signAddVotes(cs1, types.VoteTypePrecommit, hash, rs.ProposalBlock.MakePartSet(partSize).Header(), vs2) // NOTE: conflicting precommits at same height - <-voteCh - - <-timeoutWaitCh - - // before we time out into new round, set next proposal block - prop, propBlock := decideProposal(cs1, vs2, vs2.Height, vs2.Round+1) - if prop == nil || propBlock == nil { - t.Fatal("Failed to create proposal block with vs2") - } - - incrementRound(vs2) - - <-newRoundCh - t.Log("#### ONTO ROUND 3") - /* - Round4 (vs2, C) // B C // B C - */ - - // now we're on a new round and not the proposer - // so set the proposal block - if err := cs1.SetProposalAndBlock(prop, propBlock, propBlock.MakePartSet(partSize), ""); err != nil { - t.Fatal(err) - } - - <-proposalCh - <-voteCh // prevote - - // prevote for locked block (not proposal) - validatePrevote(t, cs1, 0, vss[0], cs1.LockedBlock.Hash()) - - signAddVotes(cs1, types.VoteTypePrevote, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) - <-voteCh - - <-timeoutWaitCh - <-voteCh - - validatePrecommit(t, cs1, 2, 0, vss[0], nil, theBlockHash) // precommit nil but locked on proposal - - signAddVotes(cs1, types.VoteTypePrecommit, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) // NOTE: conflicting precommits at same height - <-voteCh -} - -// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka -func TestStateLockPOLRelock(t *testing.T) { - cs1, vss := randConsensusState(4) - vs2, vs3, vs4 := vss[1], vss[2], vss[3] - - partSize := cs1.state.ConsensusParams.BlockPartSizeBytes - - timeoutProposeCh := subscribe(cs1.eventBus, types.EventQueryTimeoutPropose) - timeoutWaitCh := subscribe(cs1.eventBus, types.EventQueryTimeoutWait) - proposalCh := subscribe(cs1.eventBus, types.EventQueryCompleteProposal) - voteCh := subscribe(cs1.eventBus, types.EventQueryVote) - newRoundCh := subscribe(cs1.eventBus, types.EventQueryNewRound) - newBlockCh := subscribe(cs1.eventBus, types.EventQueryNewBlockHeader) - - // everything done from perspective of cs1 - - /* - Round1 (cs1, B) // B B B B// B nil B nil - - eg. vs2 and vs4 didn't see the 2/3 prevotes - */ - - // start round and wait for propose and prevote - startTestRound(cs1, cs1.Height, 0) - - <-newRoundCh - re := <-proposalCh - rs := re.(types.EventDataRoundState).RoundState.(*cstypes.RoundState) - theBlockHash := rs.ProposalBlock.Hash() - - <-voteCh // prevote - - signAddVotes(cs1, types.VoteTypePrevote, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), vs2, vs3, vs4) - // prevotes - discardFromChan(voteCh, 3) - - <-voteCh // our precommit - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash) - - // add precommits from the rest - signAddVotes(cs1, types.VoteTypePrecommit, nil, types.PartSetHeader{}, vs2, vs4) - signAddVotes(cs1, types.VoteTypePrecommit, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), vs3) - // precommites - discardFromChan(voteCh, 3) - - // before we timeout to the new round set the new proposal - prop, propBlock := decideProposal(cs1, vs2, vs2.Height, vs2.Round+1) - propBlockParts := propBlock.MakePartSet(partSize) - propBlockHash := propBlock.Hash() - - incrementRound(vs2, vs3, vs4) - - // timeout to new round - <-timeoutWaitCh - - //XXX: this isnt guaranteed to get there before the timeoutPropose ... - if err := cs1.SetProposalAndBlock(prop, propBlock, propBlockParts, "some peer"); err != nil { - t.Fatal(err) - } - - <-newRoundCh - t.Log("### ONTO ROUND 1") - - /* - Round2 (vs2, C) // B C C C // C C C _) - - cs1 changes lock! - */ - - // now we're on a new round and not the proposer - // but we should receive the proposal - select { - case <-proposalCh: - case <-timeoutProposeCh: - <-proposalCh - } - - // go to prevote, prevote for locked block (not proposal), move on - <-voteCh - validatePrevote(t, cs1, 0, vss[0], theBlockHash) - - // now lets add prevotes from everyone else for the new block - signAddVotes(cs1, types.VoteTypePrevote, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) - // prevotes - discardFromChan(voteCh, 3) - - // now either we go to PrevoteWait or Precommit - select { - case <-timeoutWaitCh: // we're in PrevoteWait, go to Precommit - // XXX: there's no guarantee we see the polka, this might be a precommit for nil, - // in which case the test fails! - <-voteCh - case <-voteCh: // we went straight to Precommit - } - - // we should have unlocked and locked on the new block - validatePrecommit(t, cs1, 1, 1, vss[0], propBlockHash, propBlockHash) - - signAddVotes(cs1, types.VoteTypePrecommit, propBlockHash, propBlockParts.Header(), vs2, vs3) - discardFromChan(voteCh, 2) - - be := <-newBlockCh - b := be.(types.EventDataNewBlockHeader) - re = <-newRoundCh - rs = re.(types.EventDataRoundState).RoundState.(*cstypes.RoundState) - if rs.Height != 2 { - panic("Expected height to increment") - } - - if !bytes.Equal(b.Header.Hash(), propBlockHash) { - panic("Expected new block to be proposal block") - } -} - -// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka -func TestStateLockPOLUnlock(t *testing.T) { - cs1, vss := randConsensusState(4) - vs2, vs3, vs4 := vss[1], vss[2], vss[3] - - partSize := cs1.state.ConsensusParams.BlockPartSizeBytes - - proposalCh := subscribe(cs1.eventBus, types.EventQueryCompleteProposal) - timeoutProposeCh := subscribe(cs1.eventBus, types.EventQueryTimeoutPropose) - timeoutWaitCh := subscribe(cs1.eventBus, types.EventQueryTimeoutWait) - newRoundCh := subscribe(cs1.eventBus, types.EventQueryNewRound) - unlockCh := subscribe(cs1.eventBus, types.EventQueryUnlock) - voteCh := subscribeToVoter(cs1, cs1.privValidator.GetAddress()) - - // everything done from perspective of cs1 - - /* - Round1 (cs1, B) // B B B B // B nil B nil - - eg. didn't see the 2/3 prevotes - */ - - // start round and wait for propose and prevote - startTestRound(cs1, cs1.Height, 0) - <-newRoundCh - re := <-proposalCh - rs := re.(types.EventDataRoundState).RoundState.(*cstypes.RoundState) - theBlockHash := rs.ProposalBlock.Hash() - - <-voteCh // prevote - - signAddVotes(cs1, types.VoteTypePrevote, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), vs2, vs3, vs4) - - <-voteCh //precommit - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash) - - rs = cs1.GetRoundState() - - // add precommits from the rest - signAddVotes(cs1, types.VoteTypePrecommit, nil, types.PartSetHeader{}, vs2, vs4) - signAddVotes(cs1, types.VoteTypePrecommit, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), vs3) - - // before we time out into new round, set next proposal block - prop, propBlock := decideProposal(cs1, vs2, vs2.Height, vs2.Round+1) - propBlockParts := propBlock.MakePartSet(partSize) - - incrementRound(vs2, vs3, vs4) - - // timeout to new round - re = <-timeoutWaitCh - rs = re.(types.EventDataRoundState).RoundState.(*cstypes.RoundState) - lockedBlockHash := rs.LockedBlock.Hash() - - //XXX: this isnt guaranteed to get there before the timeoutPropose ... - if err := cs1.SetProposalAndBlock(prop, propBlock, propBlockParts, "some peer"); err != nil { - t.Fatal(err) - } - - <-newRoundCh - t.Log("#### ONTO ROUND 1") - /* - Round2 (vs2, C) // B nil nil nil // nil nil nil _ - - cs1 unlocks! - */ - - // now we're on a new round and not the proposer, - // but we should receive the proposal - select { - case <-proposalCh: - case <-timeoutProposeCh: - <-proposalCh - } - - // go to prevote, prevote for locked block (not proposal) - <-voteCh - validatePrevote(t, cs1, 0, vss[0], lockedBlockHash) - // now lets add prevotes from everyone else for nil (a polka!) - signAddVotes(cs1, types.VoteTypePrevote, nil, types.PartSetHeader{}, vs2, vs3, vs4) - - // the polka makes us unlock and precommit nil - <-unlockCh - <-voteCh // precommit - - // we should have unlocked and committed nil - // NOTE: since we don't relock on nil, the lock round is 0 - validatePrecommit(t, cs1, 1, 0, vss[0], nil, nil) - - signAddVotes(cs1, types.VoteTypePrecommit, nil, types.PartSetHeader{}, vs2, vs3) - <-newRoundCh -} - -// 4 vals -// a polka at round 1 but we miss it -// then a polka at round 2 that we lock on -// then we see the polka from round 1 but shouldn't unlock -func TestStateLockPOLSafety1(t *testing.T) { - cs1, vss := randConsensusState(4) - vs2, vs3, vs4 := vss[1], vss[2], vss[3] - - partSize := cs1.state.ConsensusParams.BlockPartSizeBytes - - proposalCh := subscribe(cs1.eventBus, types.EventQueryCompleteProposal) - timeoutProposeCh := subscribe(cs1.eventBus, types.EventQueryTimeoutPropose) - timeoutWaitCh := subscribe(cs1.eventBus, types.EventQueryTimeoutWait) - newRoundCh := subscribe(cs1.eventBus, types.EventQueryNewRound) - voteCh := subscribeToVoter(cs1, cs1.privValidator.GetAddress()) - - // start round and wait for propose and prevote - startTestRound(cs1, cs1.Height, 0) - <-newRoundCh - re := <-proposalCh - rs := re.(types.EventDataRoundState).RoundState.(*cstypes.RoundState) - propBlock := rs.ProposalBlock - - <-voteCh // prevote - - validatePrevote(t, cs1, 0, vss[0], propBlock.Hash()) - - // the others sign a polka but we don't see it - prevotes := signVotes(types.VoteTypePrevote, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2, vs3, vs4) - - // before we time out into new round, set next proposer - // and next proposal block - /* - _, v1 := cs1.Validators.GetByAddress(vss[0].Address) - v1.VotingPower = 1 - if updated := cs1.Validators.Update(v1); !updated { - panic("failed to update validator") - }*/ - - t.Logf("old prop hash %v", fmt.Sprintf("%X", propBlock.Hash())) - - // we do see them precommit nil - signAddVotes(cs1, types.VoteTypePrecommit, nil, types.PartSetHeader{}, vs2, vs3, vs4) - - prop, propBlock := decideProposal(cs1, vs2, vs2.Height, vs2.Round+1) - propBlockHash := propBlock.Hash() - propBlockParts := propBlock.MakePartSet(partSize) - - incrementRound(vs2, vs3, vs4) - - //XXX: this isnt guaranteed to get there before the timeoutPropose ... - if err := cs1.SetProposalAndBlock(prop, propBlock, propBlockParts, "some peer"); err != nil { - t.Fatal(err) - } - - <-newRoundCh - t.Log("### ONTO ROUND 1") - /*Round2 - // we timeout and prevote our lock - // a polka happened but we didn't see it! - */ - - // now we're on a new round and not the proposer, - // but we should receive the proposal - select { - case re = <-proposalCh: - case <-timeoutProposeCh: - re = <-proposalCh - } - - rs = re.(types.EventDataRoundState).RoundState.(*cstypes.RoundState) - - if rs.LockedBlock != nil { - panic("we should not be locked!") - } - t.Logf("new prop hash %v", fmt.Sprintf("%X", propBlockHash)) - // go to prevote, prevote for proposal block - <-voteCh - validatePrevote(t, cs1, 1, vss[0], propBlockHash) - - // now we see the others prevote for it, so we should lock on it - signAddVotes(cs1, types.VoteTypePrevote, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) - - <-voteCh // precommit - - // we should have precommitted - validatePrecommit(t, cs1, 1, 1, vss[0], propBlockHash, propBlockHash) - - signAddVotes(cs1, types.VoteTypePrecommit, nil, types.PartSetHeader{}, vs2, vs3) - - <-timeoutWaitCh - - incrementRound(vs2, vs3, vs4) - - <-newRoundCh - - t.Log("### ONTO ROUND 2") - /*Round3 - we see the polka from round 1 but we shouldn't unlock! - */ - - // timeout of propose - <-timeoutProposeCh - - // finish prevote - <-voteCh - - // we should prevote what we're locked on - validatePrevote(t, cs1, 2, vss[0], propBlockHash) - - newStepCh := subscribe(cs1.eventBus, types.EventQueryNewRoundStep) - - // add prevotes from the earlier round - addVotes(cs1, prevotes...) - - t.Log("Done adding prevotes!") - - ensureNoNewStep(newStepCh) -} - -// 4 vals. -// polka P0 at R0, P1 at R1, and P2 at R2, -// we lock on P0 at R0, don't see P1, and unlock using P2 at R2 -// then we should make sure we don't lock using P1 - -// What we want: -// dont see P0, lock on P1 at R1, dont unlock using P0 at R2 -func TestStateLockPOLSafety2(t *testing.T) { - cs1, vss := randConsensusState(4) - vs2, vs3, vs4 := vss[1], vss[2], vss[3] - - partSize := cs1.state.ConsensusParams.BlockPartSizeBytes - - proposalCh := subscribe(cs1.eventBus, types.EventQueryCompleteProposal) - timeoutProposeCh := subscribe(cs1.eventBus, types.EventQueryTimeoutPropose) - timeoutWaitCh := subscribe(cs1.eventBus, types.EventQueryTimeoutWait) - newRoundCh := subscribe(cs1.eventBus, types.EventQueryNewRound) - unlockCh := subscribe(cs1.eventBus, types.EventQueryUnlock) - voteCh := subscribeToVoter(cs1, cs1.privValidator.GetAddress()) - - // the block for R0: gets polkad but we miss it - // (even though we signed it, shhh) - _, propBlock0 := decideProposal(cs1, vss[0], cs1.Height, cs1.Round) - propBlockHash0 := propBlock0.Hash() - propBlockParts0 := propBlock0.MakePartSet(partSize) - - // the others sign a polka but we don't see it - prevotes := signVotes(types.VoteTypePrevote, propBlockHash0, propBlockParts0.Header(), vs2, vs3, vs4) - - // the block for round 1 - prop1, propBlock1 := decideProposal(cs1, vs2, vs2.Height, vs2.Round+1) - propBlockHash1 := propBlock1.Hash() - propBlockParts1 := propBlock1.MakePartSet(partSize) - propBlockID1 := types.BlockID{propBlockHash1, propBlockParts1.Header()} - - incrementRound(vs2, vs3, vs4) - - cs1.updateRoundStep(0, cstypes.RoundStepPrecommitWait) - - t.Log("### ONTO Round 1") - // jump in at round 1 - height := cs1.Height - startTestRound(cs1, height, 1) - <-newRoundCh - - if err := cs1.SetProposalAndBlock(prop1, propBlock1, propBlockParts1, "some peer"); err != nil { - t.Fatal(err) - } - <-proposalCh - - <-voteCh // prevote - - signAddVotes(cs1, types.VoteTypePrevote, propBlockHash1, propBlockParts1.Header(), vs2, vs3, vs4) - - <-voteCh // precommit - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 1, 1, vss[0], propBlockHash1, propBlockHash1) - - // add precommits from the rest - signAddVotes(cs1, types.VoteTypePrecommit, nil, types.PartSetHeader{}, vs2, vs4) - signAddVotes(cs1, types.VoteTypePrecommit, propBlockHash1, propBlockParts1.Header(), vs3) - - incrementRound(vs2, vs3, vs4) - - // timeout of precommit wait to new round - <-timeoutWaitCh - - // in round 2 we see the polkad block from round 0 - newProp := types.NewProposal(height, 2, propBlockParts0.Header(), 0, propBlockID1) - if err := vs3.SignProposal(config.ChainID(), newProp); err != nil { - t.Fatal(err) - } - if err := cs1.SetProposalAndBlock(newProp, propBlock0, propBlockParts0, "some peer"); err != nil { - t.Fatal(err) - } - - // Add the pol votes - addVotes(cs1, prevotes...) - - <-newRoundCh - t.Log("### ONTO Round 2") - /*Round2 - // now we see the polka from round 1, but we shouldnt unlock - */ - - select { - case <-timeoutProposeCh: - <-proposalCh - case <-proposalCh: - } - - select { - case <-unlockCh: - panic("validator unlocked using an old polka") - case <-voteCh: - // prevote our locked block - } - validatePrevote(t, cs1, 2, vss[0], propBlockHash1) - -} - -//------------------------------------------------------------------------------------------ -// SlashingSuite -// TODO: Slashing - -/* -func TestStateSlashingPrevotes(t *testing.T) { - cs1, vss := randConsensusState(2) - vs2 := vss[1] - - - proposalCh := subscribe(cs1.eventBus, types.EventQueryCompleteProposal) - timeoutWaitCh := subscribe(cs1.eventBus, types.EventQueryTimeoutWait) - newRoundCh := subscribe(cs1.eventBus, types.EventQueryNewRound) - voteCh := subscribeToVoter(cs1, cs1.privValidator.GetAddress()) - - // start round and wait for propose and prevote - startTestRound(cs1, cs1.Height, 0) - <-newRoundCh - re := <-proposalCh - <-voteCh // prevote - - rs := re.(types.EventDataRoundState).RoundState.(*cstypes.RoundState) - - // we should now be stuck in limbo forever, waiting for more prevotes - // add one for a different block should cause us to go into prevote wait - hash := rs.ProposalBlock.Hash() - hash[0] = byte(hash[0]+1) % 255 - signAddVotes(cs1, types.VoteTypePrevote, hash, rs.ProposalBlockParts.Header(), vs2) - - <-timeoutWaitCh - - // NOTE: we have to send the vote for different block first so we don't just go into precommit round right - // away and ignore more prevotes (and thus fail to slash!) - - // add the conflicting vote - signAddVotes(cs1, types.VoteTypePrevote, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), vs2) - - // XXX: Check for existence of Dupeout info -} - -func TestStateSlashingPrecommits(t *testing.T) { - cs1, vss := randConsensusState(2) - vs2 := vss[1] - - - proposalCh := subscribe(cs1.eventBus, types.EventQueryCompleteProposal) - timeoutWaitCh := subscribe(cs1.eventBus, types.EventQueryTimeoutWait) - newRoundCh := subscribe(cs1.eventBus, types.EventQueryNewRound) - voteCh := subscribeToVoter(cs1, cs1.privValidator.GetAddress()) - - // start round and wait for propose and prevote - startTestRound(cs1, cs1.Height, 0) - <-newRoundCh - re := <-proposalCh - <-voteCh // prevote - - // add prevote from vs2 - signAddVotes(cs1, types.VoteTypePrevote, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), vs2) - - <-voteCh // precommit - - // we should now be stuck in limbo forever, waiting for more prevotes - // add one for a different block should cause us to go into prevote wait - hash := rs.ProposalBlock.Hash() - hash[0] = byte(hash[0]+1) % 255 - signAddVotes(cs1, types.VoteTypePrecommit, hash, rs.ProposalBlockParts.Header(), vs2) - - // NOTE: we have to send the vote for different block first so we don't just go into precommit round right - // away and ignore more prevotes (and thus fail to slash!) - - // add precommit from vs2 - signAddVotes(cs1, types.VoteTypePrecommit, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), vs2) - - // XXX: Check for existence of Dupeout info -} -*/ - -//------------------------------------------------------------------------------------------ -// CatchupSuite - -//------------------------------------------------------------------------------------------ -// HaltSuite - -// 4 vals. -// we receive a final precommit after going into next round, but others might have gone to commit already! -func TestStateHalt1(t *testing.T) { - cs1, vss := randConsensusState(4) - vs2, vs3, vs4 := vss[1], vss[2], vss[3] - - partSize := cs1.state.ConsensusParams.BlockPartSizeBytes - - proposalCh := subscribe(cs1.eventBus, types.EventQueryCompleteProposal) - timeoutWaitCh := subscribe(cs1.eventBus, types.EventQueryTimeoutWait) - newRoundCh := subscribe(cs1.eventBus, types.EventQueryNewRound) - newBlockCh := subscribe(cs1.eventBus, types.EventQueryNewBlock) - voteCh := subscribeToVoter(cs1, cs1.privValidator.GetAddress()) - - // start round and wait for propose and prevote - startTestRound(cs1, cs1.Height, 0) - <-newRoundCh - re := <-proposalCh - rs := re.(types.EventDataRoundState).RoundState.(*cstypes.RoundState) - propBlock := rs.ProposalBlock - propBlockParts := propBlock.MakePartSet(partSize) - - <-voteCh // prevote - - signAddVotes(cs1, types.VoteTypePrevote, propBlock.Hash(), propBlockParts.Header(), vs3, vs4) - <-voteCh // precommit - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], propBlock.Hash(), propBlock.Hash()) - - // add precommits from the rest - signAddVotes(cs1, types.VoteTypePrecommit, nil, types.PartSetHeader{}, vs2) // didnt receive proposal - signAddVotes(cs1, types.VoteTypePrecommit, propBlock.Hash(), propBlockParts.Header(), vs3) - // we receive this later, but vs3 might receive it earlier and with ours will go to commit! - precommit4 := signVote(vs4, types.VoteTypePrecommit, propBlock.Hash(), propBlockParts.Header()) - - incrementRound(vs2, vs3, vs4) - - // timeout to new round - <-timeoutWaitCh - re = <-newRoundCh - rs = re.(types.EventDataRoundState).RoundState.(*cstypes.RoundState) - - t.Log("### ONTO ROUND 1") - /*Round2 - // we timeout and prevote our lock - // a polka happened but we didn't see it! - */ - - // go to prevote, prevote for locked block - <-voteCh // prevote - validatePrevote(t, cs1, 0, vss[0], rs.LockedBlock.Hash()) - - // now we receive the precommit from the previous round - addVotes(cs1, precommit4) - - // receiving that precommit should take us straight to commit - <-newBlockCh - re = <-newRoundCh - rs = re.(types.EventDataRoundState).RoundState.(*cstypes.RoundState) - - if rs.Height != 2 { - panic("expected height to increment") - } -} - -// subscribe subscribes test client to the given query and returns a channel with cap = 1. -func subscribe(eventBus *types.EventBus, q tmpubsub.Query) <-chan interface{} { - out := make(chan interface{}, 1) - err := eventBus.Subscribe(context.Background(), testSubscriber, q, out) - if err != nil { - panic(fmt.Sprintf("failed to subscribe %s to %v", testSubscriber, q)) - } - return out -} - -// discardFromChan reads n values from the channel. -func discardFromChan(ch <-chan interface{}, n int) { - for i := 0; i < n; i++ { - <-ch - } -} diff --git a/consensus/test_data/many_blocks.cswal b/consensus/test_data/many_blocks.cswal deleted file mode 100644 index d443fff78eab4ee086c5c5b3783eba7df00522f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11137 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 diff --git a/consensus/ticker.go b/consensus/ticker.go deleted file mode 100644 index b37b7c495..000000000 --- a/consensus/ticker.go +++ /dev/null @@ -1,134 +0,0 @@ -package consensus - -import ( - "time" - - cmn "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/log" -) - -var ( - tickTockBufferSize = 10 -) - -// TimeoutTicker is a timer that schedules timeouts -// conditional on the height/round/step in the timeoutInfo. -// The timeoutInfo.Duration may be non-positive. -type TimeoutTicker interface { - Start() error - Stop() error - Chan() <-chan timeoutInfo // on which to receive a timeout - ScheduleTimeout(ti timeoutInfo) // reset the timer - - SetLogger(log.Logger) -} - -// timeoutTicker wraps time.Timer, -// scheduling timeouts only for greater height/round/step -// than what it's already seen. -// Timeouts are scheduled along the tickChan, -// and fired on the tockChan. -type timeoutTicker struct { - cmn.BaseService - - timer *time.Timer - tickChan chan timeoutInfo // for scheduling timeouts - tockChan chan timeoutInfo // for notifying about them -} - -// NewTimeoutTicker returns a new TimeoutTicker. -func NewTimeoutTicker() TimeoutTicker { - tt := &timeoutTicker{ - timer: time.NewTimer(0), - tickChan: make(chan timeoutInfo, tickTockBufferSize), - tockChan: make(chan timeoutInfo, tickTockBufferSize), - } - tt.BaseService = *cmn.NewBaseService(nil, "TimeoutTicker", tt) - tt.stopTimer() // don't want to fire until the first scheduled timeout - return tt -} - -// OnStart implements cmn.Service. It starts the timeout routine. -func (t *timeoutTicker) OnStart() error { - - go t.timeoutRoutine() - - return nil -} - -// OnStop implements cmn.Service. It stops the timeout routine. -func (t *timeoutTicker) OnStop() { - t.BaseService.OnStop() - t.stopTimer() -} - -// Chan returns a channel on which timeouts are sent. -func (t *timeoutTicker) Chan() <-chan timeoutInfo { - return t.tockChan -} - -// ScheduleTimeout schedules a new timeout by sending on the internal tickChan. -// The timeoutRoutine is always available to read from tickChan, so this won't block. -// The scheduling may fail if the timeoutRoutine has already scheduled a timeout for a later height/round/step. -func (t *timeoutTicker) ScheduleTimeout(ti timeoutInfo) { - t.tickChan <- ti -} - -//------------------------------------------------------------- - -// stop the timer and drain if necessary -func (t *timeoutTicker) stopTimer() { - // Stop() returns false if it was already fired or was stopped - if !t.timer.Stop() { - select { - case <-t.timer.C: - default: - t.Logger.Debug("Timer already stopped") - } - } -} - -// send on tickChan to start a new timer. -// timers are interupted and replaced by new ticks from later steps -// timeouts of 0 on the tickChan will be immediately relayed to the tockChan -func (t *timeoutTicker) timeoutRoutine() { - t.Logger.Debug("Starting timeout routine") - var ti timeoutInfo - for { - select { - case newti := <-t.tickChan: - t.Logger.Debug("Received tick", "old_ti", ti, "new_ti", newti) - - // ignore tickers for old height/round/step - if newti.Height < ti.Height { - continue - } else if newti.Height == ti.Height { - if newti.Round < ti.Round { - continue - } else if newti.Round == ti.Round { - if ti.Step > 0 && newti.Step <= ti.Step { - continue - } - } - } - - // stop the last timer - t.stopTimer() - - // update timeoutInfo and reset timer - // NOTE time.Timer allows duration to be non-positive - ti = newti - t.timer.Reset(ti.Duration) - t.Logger.Debug("Scheduled timeout", "dur", ti.Duration, "height", ti.Height, "round", ti.Round, "step", ti.Step) - case <-t.timer.C: - t.Logger.Info("Timed out", "dur", ti.Duration, "height", ti.Height, "round", ti.Round, "step", ti.Step) - // go routine here guarantees timeoutRoutine doesn't block. - // Determinism comes from playback in the receiveRoutine. - // We can eliminate it by merging the timeoutRoutine into receiveRoutine - // and managing the timeouts ourselves with a millisecond ticker - go func(toi timeoutInfo) { t.tockChan <- toi }(ti) - case <-t.Quit(): - return - } - } -} diff --git a/consensus/types/height_vote_set.go b/consensus/types/height_vote_set.go deleted file mode 100644 index 3c9867940..000000000 --- a/consensus/types/height_vote_set.go +++ /dev/null @@ -1,261 +0,0 @@ -package types - -import ( - "errors" - "fmt" - "strings" - "sync" - - "github.com/tendermint/tendermint/p2p" - "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tmlibs/common" -) - -type RoundVoteSet struct { - Prevotes *types.VoteSet - Precommits *types.VoteSet -} - -var ( - GotVoteFromUnwantedRoundError = errors.New("Peer has sent a vote that does not match our round for more than one round") -) - -/* -Keeps track of all VoteSets from round 0 to round 'round'. - -Also keeps track of up to one RoundVoteSet greater than -'round' from each peer, to facilitate catchup syncing of commits. - -A commit is +2/3 precommits for a block at a round, -but which round is not known in advance, so when a peer -provides a precommit for a round greater than mtx.round, -we create a new entry in roundVoteSets but also remember the -peer to prevent abuse. -We let each peer provide us with up to 2 unexpected "catchup" rounds. -One for their LastCommit round, and another for the official commit round. -*/ -type HeightVoteSet struct { - chainID string - height int64 - valSet *types.ValidatorSet - - mtx sync.Mutex - round int // max tracked round - roundVoteSets map[int]RoundVoteSet // keys: [0...round] - peerCatchupRounds map[p2p.ID][]int // keys: peer.ID; values: at most 2 rounds -} - -func NewHeightVoteSet(chainID string, height int64, valSet *types.ValidatorSet) *HeightVoteSet { - hvs := &HeightVoteSet{ - chainID: chainID, - } - hvs.Reset(height, valSet) - return hvs -} - -func (hvs *HeightVoteSet) Reset(height int64, valSet *types.ValidatorSet) { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - - hvs.height = height - hvs.valSet = valSet - hvs.roundVoteSets = make(map[int]RoundVoteSet) - hvs.peerCatchupRounds = make(map[p2p.ID][]int) - - hvs.addRound(0) - hvs.round = 0 -} - -func (hvs *HeightVoteSet) Height() int64 { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - return hvs.height -} - -func (hvs *HeightVoteSet) Round() int { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - return hvs.round -} - -// Create more RoundVoteSets up to round. -func (hvs *HeightVoteSet) SetRound(round int) { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - if hvs.round != 0 && (round < hvs.round+1) { - cmn.PanicSanity("SetRound() must increment hvs.round") - } - for r := hvs.round + 1; r <= round; r++ { - if _, ok := hvs.roundVoteSets[r]; ok { - continue // Already exists because peerCatchupRounds. - } - hvs.addRound(r) - } - hvs.round = round -} - -func (hvs *HeightVoteSet) addRound(round int) { - if _, ok := hvs.roundVoteSets[round]; ok { - cmn.PanicSanity("addRound() for an existing round") - } - // log.Debug("addRound(round)", "round", round) - prevotes := types.NewVoteSet(hvs.chainID, hvs.height, round, types.VoteTypePrevote, hvs.valSet) - precommits := types.NewVoteSet(hvs.chainID, hvs.height, round, types.VoteTypePrecommit, hvs.valSet) - hvs.roundVoteSets[round] = RoundVoteSet{ - Prevotes: prevotes, - Precommits: precommits, - } -} - -// Duplicate votes return added=false, err=nil. -// By convention, peerID is "" if origin is self. -func (hvs *HeightVoteSet) AddVote(vote *types.Vote, peerID p2p.ID) (added bool, err error) { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - if !types.IsVoteTypeValid(vote.Type) { - return - } - voteSet := hvs.getVoteSet(vote.Round, vote.Type) - if voteSet == nil { - if rndz := hvs.peerCatchupRounds[peerID]; len(rndz) < 2 { - hvs.addRound(vote.Round) - voteSet = hvs.getVoteSet(vote.Round, vote.Type) - hvs.peerCatchupRounds[peerID] = append(rndz, vote.Round) - } else { - // punish peer - err = GotVoteFromUnwantedRoundError - return - } - } - added, err = voteSet.AddVote(vote) - return -} - -func (hvs *HeightVoteSet) Prevotes(round int) *types.VoteSet { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - return hvs.getVoteSet(round, types.VoteTypePrevote) -} - -func (hvs *HeightVoteSet) Precommits(round int) *types.VoteSet { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - return hvs.getVoteSet(round, types.VoteTypePrecommit) -} - -// Last round and blockID that has +2/3 prevotes for a particular block or nil. -// Returns -1 if no such round exists. -func (hvs *HeightVoteSet) POLInfo() (polRound int, polBlockID types.BlockID) { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - for r := hvs.round; r >= 0; r-- { - rvs := hvs.getVoteSet(r, types.VoteTypePrevote) - polBlockID, ok := rvs.TwoThirdsMajority() - if ok { - return r, polBlockID - } - } - return -1, types.BlockID{} -} - -func (hvs *HeightVoteSet) getVoteSet(round int, type_ byte) *types.VoteSet { - rvs, ok := hvs.roundVoteSets[round] - if !ok { - return nil - } - switch type_ { - case types.VoteTypePrevote: - return rvs.Prevotes - case types.VoteTypePrecommit: - return rvs.Precommits - default: - cmn.PanicSanity(cmn.Fmt("Unexpected vote type %X", type_)) - return nil - } -} - -// If a peer claims that it has 2/3 majority for given blockKey, call this. -// NOTE: if there are too many peers, or too much peer churn, -// this can cause memory issues. -// TODO: implement ability to remove peers too -func (hvs *HeightVoteSet) SetPeerMaj23(round int, type_ byte, peerID p2p.ID, blockID types.BlockID) error { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - if !types.IsVoteTypeValid(type_) { - return fmt.Errorf("SetPeerMaj23: Invalid vote type %v", type_) - } - voteSet := hvs.getVoteSet(round, type_) - if voteSet == nil { - return nil // something we don't know about yet - } - return voteSet.SetPeerMaj23(types.P2PID(peerID), blockID) -} - -//--------------------------------------------------------- -// string and json - -func (hvs *HeightVoteSet) String() string { - return hvs.StringIndented("") -} - -func (hvs *HeightVoteSet) StringIndented(indent string) string { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - vsStrings := make([]string, 0, (len(hvs.roundVoteSets)+1)*2) - // rounds 0 ~ hvs.round inclusive - for round := 0; round <= hvs.round; round++ { - voteSetString := hvs.roundVoteSets[round].Prevotes.StringShort() - vsStrings = append(vsStrings, voteSetString) - voteSetString = hvs.roundVoteSets[round].Precommits.StringShort() - vsStrings = append(vsStrings, voteSetString) - } - // all other peer catchup rounds - for round, roundVoteSet := range hvs.roundVoteSets { - if round <= hvs.round { - continue - } - voteSetString := roundVoteSet.Prevotes.StringShort() - vsStrings = append(vsStrings, voteSetString) - voteSetString = roundVoteSet.Precommits.StringShort() - vsStrings = append(vsStrings, voteSetString) - } - return cmn.Fmt(`HeightVoteSet{H:%v R:0~%v -%s %v -%s}`, - hvs.height, hvs.round, - indent, strings.Join(vsStrings, "\n"+indent+" "), - indent) -} - -func (hvs *HeightVoteSet) MarshalJSON() ([]byte, error) { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - - allVotes := hvs.toAllRoundVotes() - return cdc.MarshalJSON(allVotes) -} - -func (hvs *HeightVoteSet) toAllRoundVotes() []roundVotes { - totalRounds := hvs.round + 1 - allVotes := make([]roundVotes, totalRounds) - // rounds 0 ~ hvs.round inclusive - for round := 0; round < totalRounds; round++ { - allVotes[round] = roundVotes{ - Round: round, - Prevotes: hvs.roundVoteSets[round].Prevotes.VoteStrings(), - PrevotesBitArray: hvs.roundVoteSets[round].Prevotes.BitArrayString(), - Precommits: hvs.roundVoteSets[round].Precommits.VoteStrings(), - PrecommitsBitArray: hvs.roundVoteSets[round].Precommits.BitArrayString(), - } - } - // TODO: all other peer catchup rounds - return allVotes -} - -type roundVotes struct { - Round int `json:"round"` - Prevotes []string `json:"prevotes"` - PrevotesBitArray string `json:"prevotes_bit_array"` - Precommits []string `json:"precommits"` - PrecommitsBitArray string `json:"precommits_bit_array"` -} diff --git a/consensus/types/height_vote_set_test.go b/consensus/types/height_vote_set_test.go deleted file mode 100644 index 678d34759..000000000 --- a/consensus/types/height_vote_set_test.go +++ /dev/null @@ -1,69 +0,0 @@ -package types - -import ( - "testing" - "time" - - cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tmlibs/common" -) - -var config *cfg.Config // NOTE: must be reset for each _test.go file - -func init() { - config = cfg.ResetTestRoot("consensus_height_vote_set_test") -} - -func TestPeerCatchupRounds(t *testing.T) { - valSet, privVals := types.RandValidatorSet(10, 1) - - hvs := NewHeightVoteSet(config.ChainID(), 1, valSet) - - vote999_0 := makeVoteHR(t, 1, 999, privVals, 0) - added, err := hvs.AddVote(vote999_0, "peer1") - if !added || err != nil { - t.Error("Expected to successfully add vote from peer", added, err) - } - - vote1000_0 := makeVoteHR(t, 1, 1000, privVals, 0) - added, err = hvs.AddVote(vote1000_0, "peer1") - if !added || err != nil { - t.Error("Expected to successfully add vote from peer", added, err) - } - - vote1001_0 := makeVoteHR(t, 1, 1001, privVals, 0) - added, err = hvs.AddVote(vote1001_0, "peer1") - if err != GotVoteFromUnwantedRoundError { - t.Errorf("Expected GotVoteFromUnwantedRoundError, but got %v", err) - } - if added { - t.Error("Expected to *not* add vote from peer, too many catchup rounds.") - } - - added, err = hvs.AddVote(vote1001_0, "peer2") - if !added || err != nil { - t.Error("Expected to successfully add vote from another peer") - } - -} - -func makeVoteHR(t *testing.T, height int64, round int, privVals []types.PrivValidator, valIndex int) *types.Vote { - privVal := privVals[valIndex] - vote := &types.Vote{ - ValidatorAddress: privVal.GetAddress(), - ValidatorIndex: valIndex, - Height: height, - Round: round, - Timestamp: time.Now().UTC(), - Type: types.VoteTypePrecommit, - BlockID: types.BlockID{[]byte("fakehash"), types.PartSetHeader{}}, - } - chainID := config.ChainID() - err := privVal.SignVote(chainID, vote) - if err != nil { - panic(cmn.Fmt("Error signing vote: %v", err)) - return nil - } - return vote -} diff --git a/consensus/types/peer_round_state.go b/consensus/types/peer_round_state.go deleted file mode 100644 index dcb6c8e02..000000000 --- a/consensus/types/peer_round_state.go +++ /dev/null @@ -1,57 +0,0 @@ -package types - -import ( - "fmt" - "time" - - "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tmlibs/common" -) - -//----------------------------------------------------------------------------- - -// PeerRoundState contains the known state of a peer. -// NOTE: Read-only when returned by PeerState.GetRoundState(). -type PeerRoundState struct { - Height int64 `json:"height"` // Height peer is at - Round int `json:"round"` // Round peer is at, -1 if unknown. - Step RoundStepType `json:"step"` // Step peer is at - StartTime time.Time `json:"start_time"` // Estimated start of round 0 at this height - Proposal bool `json:"proposal"` // True if peer has proposal for this round - ProposalBlockPartsHeader types.PartSetHeader `json:"proposal_block_parts_header"` // - ProposalBlockParts *cmn.BitArray `json:"proposal_block_parts"` // - ProposalPOLRound int `json:"proposal_pol_round"` // Proposal's POL round. -1 if none. - ProposalPOL *cmn.BitArray `json:"proposal_pol"` // nil until ProposalPOLMessage received. - Prevotes *cmn.BitArray `json:"prevotes"` // All votes peer has for this round - Precommits *cmn.BitArray `json:"precommits"` // All precommits peer has for this round - LastCommitRound int `json:"last_commit_round"` // Round of commit for last height. -1 if none. - LastCommit *cmn.BitArray `json:"last_commit"` // All commit precommits of commit for last height. - CatchupCommitRound int `json:"catchup_commit_round"` // Round that we have commit for. Not necessarily unique. -1 if none. - CatchupCommit *cmn.BitArray `json:"catchup_commit"` // All commit precommits peer has for this height & CatchupCommitRound -} - -// String returns a string representation of the PeerRoundState -func (prs PeerRoundState) String() string { - return prs.StringIndented("") -} - -// StringIndented returns a string representation of the PeerRoundState -func (prs PeerRoundState) StringIndented(indent string) string { - return fmt.Sprintf(`PeerRoundState{ -%s %v/%v/%v @%v -%s Proposal %v -> %v -%s POL %v (round %v) -%s Prevotes %v -%s Precommits %v -%s LastCommit %v (round %v) -%s Catchup %v (round %v) -%s}`, - indent, prs.Height, prs.Round, prs.Step, prs.StartTime, - indent, prs.ProposalBlockPartsHeader, prs.ProposalBlockParts, - indent, prs.ProposalPOL, prs.ProposalPOLRound, - indent, prs.Prevotes, - indent, prs.Precommits, - indent, prs.LastCommit, prs.LastCommitRound, - indent, prs.CatchupCommit, prs.CatchupCommitRound, - indent) -} diff --git a/consensus/types/round_state.go b/consensus/types/round_state.go deleted file mode 100644 index 14da1f149..000000000 --- a/consensus/types/round_state.go +++ /dev/null @@ -1,164 +0,0 @@ -package types - -import ( - "encoding/json" - "fmt" - "time" - - "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tmlibs/common" -) - -//----------------------------------------------------------------------------- -// RoundStepType enum type - -// RoundStepType enumerates the state of the consensus state machine -type RoundStepType uint8 // These must be numeric, ordered. - -// RoundStepType -const ( - RoundStepNewHeight = RoundStepType(0x01) // Wait til CommitTime + timeoutCommit - RoundStepNewRound = RoundStepType(0x02) // Setup new round and go to RoundStepPropose - RoundStepPropose = RoundStepType(0x03) // Did propose, gossip proposal - RoundStepPrevote = RoundStepType(0x04) // Did prevote, gossip prevotes - RoundStepPrevoteWait = RoundStepType(0x05) // Did receive any +2/3 prevotes, start timeout - RoundStepPrecommit = RoundStepType(0x06) // Did precommit, gossip precommits - RoundStepPrecommitWait = RoundStepType(0x07) // Did receive any +2/3 precommits, start timeout - RoundStepCommit = RoundStepType(0x08) // Entered commit state machine - // NOTE: RoundStepNewHeight acts as RoundStepCommitWait. -) - -// String returns a string -func (rs RoundStepType) String() string { - switch rs { - case RoundStepNewHeight: - return "RoundStepNewHeight" - case RoundStepNewRound: - return "RoundStepNewRound" - case RoundStepPropose: - return "RoundStepPropose" - case RoundStepPrevote: - return "RoundStepPrevote" - case RoundStepPrevoteWait: - return "RoundStepPrevoteWait" - case RoundStepPrecommit: - return "RoundStepPrecommit" - case RoundStepPrecommitWait: - return "RoundStepPrecommitWait" - case RoundStepCommit: - return "RoundStepCommit" - default: - return "RoundStepUnknown" // Cannot panic. - } -} - -//----------------------------------------------------------------------------- - -// RoundState defines the internal consensus state. -// NOTE: Not thread safe. Should only be manipulated by functions downstream -// of the cs.receiveRoutine -type RoundState struct { - Height int64 `json:"height"` // Height we are working on - Round int `json:"round"` - Step RoundStepType `json:"step"` - StartTime time.Time `json:"start_time"` - CommitTime time.Time `json:"commit_time"` // Subjective time when +2/3 precommits for Block at Round were found - Validators *types.ValidatorSet `json:"validators"` - Proposal *types.Proposal `json:"proposal"` - ProposalBlock *types.Block `json:"proposal_block"` - ProposalBlockParts *types.PartSet `json:"proposal_block_parts"` - LockedRound int `json:"locked_round"` - LockedBlock *types.Block `json:"locked_block"` - LockedBlockParts *types.PartSet `json:"locked_block_parts"` - ValidRound int `json:"valid_round"` // Last known round with POL for non-nil valid block. - ValidBlock *types.Block `json:"valid_block"` // Last known block of POL mentioned above. - ValidBlockParts *types.PartSet `json:"valid_block_parts"` // Last known block parts of POL metnioned above. - Votes *HeightVoteSet `json:"votes"` - CommitRound int `json:"commit_round"` // - LastCommit *types.VoteSet `json:"last_commit"` // Last precommits at Height-1 - LastValidators *types.ValidatorSet `json:"last_validators"` -} - -// Compressed version of the RoundState for use in RPC -type RoundStateSimple struct { - HeightRoundStep string `json:"height/round/step"` - StartTime time.Time `json:"start_time"` - ProposalBlockHash cmn.HexBytes `json:"proposal_block_hash"` - LockedBlockHash cmn.HexBytes `json:"locked_block_hash"` - ValidBlockHash cmn.HexBytes `json:"valid_block_hash"` - Votes json.RawMessage `json:"height_vote_set"` -} - -// Compress the RoundState to RoundStateSimple -func (rs *RoundState) RoundStateSimple() RoundStateSimple { - votesJSON, err := rs.Votes.MarshalJSON() - if err != nil { - panic(err) - } - return RoundStateSimple{ - HeightRoundStep: fmt.Sprintf("%d/%d/%d", rs.Height, rs.Round, rs.Step), - StartTime: rs.StartTime, - ProposalBlockHash: rs.ProposalBlock.Hash(), - LockedBlockHash: rs.LockedBlock.Hash(), - ValidBlockHash: rs.ValidBlock.Hash(), - Votes: votesJSON, - } -} - -// RoundStateEvent returns the H/R/S of the RoundState as an event. -func (rs *RoundState) RoundStateEvent() types.EventDataRoundState { - // XXX: copy the RoundState - // if we want to avoid this, we may need synchronous events after all - rsCopy := *rs - edrs := types.EventDataRoundState{ - Height: rs.Height, - Round: rs.Round, - Step: rs.Step.String(), - RoundState: &rsCopy, - } - return edrs -} - -// String returns a string -func (rs *RoundState) String() string { - return rs.StringIndented("") -} - -// StringIndented returns a string -func (rs *RoundState) StringIndented(indent string) string { - return fmt.Sprintf(`RoundState{ -%s H:%v R:%v S:%v -%s StartTime: %v -%s CommitTime: %v -%s Validators: %v -%s Proposal: %v -%s ProposalBlock: %v %v -%s LockedRound: %v -%s LockedBlock: %v %v -%s ValidRound: %v -%s ValidBlock: %v %v -%s Votes: %v -%s LastCommit: %v -%s LastValidators:%v -%s}`, - indent, rs.Height, rs.Round, rs.Step, - indent, rs.StartTime, - indent, rs.CommitTime, - indent, rs.Validators.StringIndented(indent+" "), - indent, rs.Proposal, - indent, rs.ProposalBlockParts.StringShort(), rs.ProposalBlock.StringShort(), - indent, rs.LockedRound, - indent, rs.LockedBlockParts.StringShort(), rs.LockedBlock.StringShort(), - indent, rs.ValidRound, - indent, rs.ValidBlockParts.StringShort(), rs.ValidBlock.StringShort(), - indent, rs.Votes.StringIndented(indent+" "), - indent, rs.LastCommit.StringShort(), - indent, rs.LastValidators.StringIndented(indent+" "), - indent) -} - -// StringShort returns a string -func (rs *RoundState) StringShort() string { - return fmt.Sprintf(`RoundState{H:%v R:%v S:%v ST:%v}`, - rs.Height, rs.Round, rs.Step, rs.StartTime) -} diff --git a/consensus/types/round_state_test.go b/consensus/types/round_state_test.go deleted file mode 100644 index dc88c3a13..000000000 --- a/consensus/types/round_state_test.go +++ /dev/null @@ -1,95 +0,0 @@ -package types - -import ( - "testing" - "time" - - "github.com/tendermint/go-amino" - "github.com/tendermint/go-crypto" - "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tmlibs/common" -) - -func BenchmarkRoundStateDeepCopy(b *testing.B) { - b.StopTimer() - - // Random validators - nval, ntxs := 100, 100 - vset, _ := types.RandValidatorSet(nval, 1) - precommits := make([]*types.Vote, nval) - blockID := types.BlockID{ - Hash: cmn.RandBytes(20), - PartsHeader: types.PartSetHeader{ - Hash: cmn.RandBytes(20), - }, - } - sig := crypto.SignatureEd25519{} - for i := 0; i < nval; i++ { - precommits[i] = &types.Vote{ - ValidatorAddress: types.Address(cmn.RandBytes(20)), - Timestamp: time.Now(), - BlockID: blockID, - Signature: sig, - } - } - txs := make([]types.Tx, ntxs) - for i := 0; i < ntxs; i++ { - txs[i] = cmn.RandBytes(100) - } - // Random block - block := &types.Block{ - Header: &types.Header{ - ChainID: cmn.RandStr(12), - Time: time.Now(), - LastBlockID: blockID, - LastCommitHash: cmn.RandBytes(20), - DataHash: cmn.RandBytes(20), - ValidatorsHash: cmn.RandBytes(20), - ConsensusHash: cmn.RandBytes(20), - AppHash: cmn.RandBytes(20), - LastResultsHash: cmn.RandBytes(20), - EvidenceHash: cmn.RandBytes(20), - }, - Data: &types.Data{ - Txs: txs, - }, - Evidence: types.EvidenceData{}, - LastCommit: &types.Commit{ - BlockID: blockID, - Precommits: precommits, - }, - } - parts := block.MakePartSet(4096) - // Random Proposal - proposal := &types.Proposal{ - Timestamp: time.Now(), - BlockPartsHeader: types.PartSetHeader{ - Hash: cmn.RandBytes(20), - }, - POLBlockID: blockID, - Signature: sig, - } - // Random HeightVoteSet - // TODO: hvs := - - rs := &RoundState{ - StartTime: time.Now(), - CommitTime: time.Now(), - Validators: vset, - Proposal: proposal, - ProposalBlock: block, - ProposalBlockParts: parts, - LockedBlock: block, - LockedBlockParts: parts, - ValidBlock: block, - ValidBlockParts: parts, - Votes: nil, // TODO - LastCommit: nil, // TODO - LastValidators: vset, - } - b.StartTimer() - - for i := 0; i < b.N; i++ { - amino.DeepCopy(rs) - } -} diff --git a/consensus/types/wire.go b/consensus/types/wire.go deleted file mode 100644 index bd5c4497d..000000000 --- a/consensus/types/wire.go +++ /dev/null @@ -1,12 +0,0 @@ -package types - -import ( - "github.com/tendermint/go-amino" - "github.com/tendermint/go-crypto" -) - -var cdc = amino.NewCodec() - -func init() { - crypto.RegisterAmino(cdc) -} diff --git a/consensus/version.go b/consensus/version.go deleted file mode 100644 index 2c137bf7f..000000000 --- a/consensus/version.go +++ /dev/null @@ -1,13 +0,0 @@ -package consensus - -import ( - cmn "github.com/tendermint/tmlibs/common" -) - -// kind of arbitrary -var Spec = "1" // async -var Major = "0" // -var Minor = "2" // replay refactor -var Revision = "2" // validation -> commit - -var Version = cmn.Fmt("v%s/%s.%s.%s", Spec, Major, Minor, Revision) diff --git a/consensus/wal.go b/consensus/wal.go deleted file mode 100644 index 3d9bf8afc..000000000 --- a/consensus/wal.go +++ /dev/null @@ -1,323 +0,0 @@ -package consensus - -import ( - "encoding/binary" - "fmt" - "hash/crc32" - "io" - "path/filepath" - "time" - - "github.com/pkg/errors" - - amino "github.com/tendermint/go-amino" - "github.com/tendermint/tendermint/types" - auto "github.com/tendermint/tmlibs/autofile" - cmn "github.com/tendermint/tmlibs/common" -) - -const ( - // must be greater than params.BlockGossip.BlockPartSizeBytes + a few bytes - maxMsgSizeBytes = 1024 * 1024 // 1MB -) - -//-------------------------------------------------------- -// types and functions for savings consensus messages - -type TimedWALMessage struct { - Time time.Time `json:"time"` // for debugging purposes - Msg WALMessage `json:"msg"` -} - -// EndHeightMessage marks the end of the given height inside WAL. -// @internal used by scripts/wal2json util. -type EndHeightMessage struct { - Height int64 `json:"height"` -} - -type WALMessage interface{} - -func RegisterWALMessages(cdc *amino.Codec) { - cdc.RegisterInterface((*WALMessage)(nil), nil) - cdc.RegisterConcrete(types.EventDataRoundState{}, "tendermint/wal/EventDataRoundState", nil) - cdc.RegisterConcrete(msgInfo{}, "tendermint/wal/MsgInfo", nil) - cdc.RegisterConcrete(timeoutInfo{}, "tendermint/wal/TimeoutInfo", nil) - cdc.RegisterConcrete(EndHeightMessage{}, "tendermint/wal/EndHeightMessage", nil) -} - -//-------------------------------------------------------- -// Simple write-ahead logger - -// WAL is an interface for any write-ahead logger. -type WAL interface { - Write(WALMessage) - WriteSync(WALMessage) - Group() *auto.Group - SearchForEndHeight(height int64, options *WALSearchOptions) (gr *auto.GroupReader, found bool, err error) - - Start() error - Stop() error - Wait() -} - -// Write ahead logger writes msgs to disk before they are processed. -// Can be used for crash-recovery and deterministic replay -// TODO: currently the wal is overwritten during replay catchup -// give it a mode so it's either reading or appending - must read to end to start appending again -type baseWAL struct { - cmn.BaseService - - group *auto.Group - - enc *WALEncoder -} - -func NewWAL(walFile string) (*baseWAL, error) { - err := cmn.EnsureDir(filepath.Dir(walFile), 0700) - if err != nil { - return nil, errors.Wrap(err, "failed to ensure WAL directory is in place") - } - - group, err := auto.OpenGroup(walFile) - if err != nil { - return nil, err - } - wal := &baseWAL{ - group: group, - enc: NewWALEncoder(group), - } - wal.BaseService = *cmn.NewBaseService(nil, "baseWAL", wal) - return wal, nil -} - -func (wal *baseWAL) Group() *auto.Group { - return wal.group -} - -func (wal *baseWAL) OnStart() error { - size, err := wal.group.Head.Size() - if err != nil { - return err - } else if size == 0 { - wal.WriteSync(EndHeightMessage{0}) - } - err = wal.group.Start() - return err -} - -func (wal *baseWAL) OnStop() { - wal.group.Stop() - wal.group.Close() -} - -// Write is called in newStep and for each receive on the -// peerMsgQueue and the timeoutTicker. -// NOTE: does not call fsync() -func (wal *baseWAL) Write(msg WALMessage) { - if wal == nil { - return - } - - // Write the wal message - if err := wal.enc.Encode(&TimedWALMessage{time.Now(), msg}); err != nil { - panic(cmn.Fmt("Error writing msg to consensus wal: %v \n\nMessage: %v", err, msg)) - } -} - -// WriteSync is called when we receive a msg from ourselves -// so that we write to disk before sending signed messages. -// NOTE: calls fsync() -func (wal *baseWAL) WriteSync(msg WALMessage) { - if wal == nil { - return - } - - wal.Write(msg) - if err := wal.group.Flush(); err != nil { - panic(cmn.Fmt("Error flushing consensus wal buf to file. Error: %v \n", err)) - } -} - -// WALSearchOptions are optional arguments to SearchForEndHeight. -type WALSearchOptions struct { - // IgnoreDataCorruptionErrors set to true will result in skipping data corruption errors. - IgnoreDataCorruptionErrors bool -} - -// SearchForEndHeight searches for the EndHeightMessage with the given height -// and returns an auto.GroupReader, whenever it was found or not and an error. -// Group reader will be nil if found equals false. -// -// CONTRACT: caller must close group reader. -func (wal *baseWAL) SearchForEndHeight(height int64, options *WALSearchOptions) (gr *auto.GroupReader, found bool, err error) { - var msg *TimedWALMessage - lastHeightFound := int64(-1) - - // NOTE: starting from the last file in the group because we're usually - // searching for the last height. See replay.go - min, max := wal.group.MinIndex(), wal.group.MaxIndex() - wal.Logger.Debug("Searching for height", "height", height, "min", min, "max", max) - for index := max; index >= min; index-- { - gr, err = wal.group.NewReader(index) - if err != nil { - return nil, false, err - } - - dec := NewWALDecoder(gr) - for { - msg, err = dec.Decode() - if err == io.EOF { - // OPTIMISATION: no need to look for height in older files if we've seen h < height - if lastHeightFound > 0 && lastHeightFound < height { - gr.Close() - return nil, false, nil - } - // check next file - break - } - if options.IgnoreDataCorruptionErrors && IsDataCorruptionError(err) { - wal.Logger.Debug("Corrupted entry. Skipping...", "err", err) - // do nothing - continue - } else if err != nil { - gr.Close() - return nil, false, err - } - - if m, ok := msg.Msg.(EndHeightMessage); ok { - lastHeightFound = m.Height - if m.Height == height { // found - wal.Logger.Debug("Found", "height", height, "index", index) - return gr, true, nil - } - } - } - gr.Close() - } - - return nil, false, nil -} - -/////////////////////////////////////////////////////////////////////////////// - -// A WALEncoder writes custom-encoded WAL messages to an output stream. -// -// Format: 4 bytes CRC sum + 4 bytes length + arbitrary-length value (go-amino encoded) -type WALEncoder struct { - wr io.Writer -} - -// NewWALEncoder returns a new encoder that writes to wr. -func NewWALEncoder(wr io.Writer) *WALEncoder { - return &WALEncoder{wr} -} - -// Encode writes the custom encoding of v to the stream. -func (enc *WALEncoder) Encode(v *TimedWALMessage) error { - data := cdc.MustMarshalBinaryBare(v) - - crc := crc32.Checksum(data, crc32c) - length := uint32(len(data)) - totalLength := 8 + int(length) - - msg := make([]byte, totalLength) - binary.BigEndian.PutUint32(msg[0:4], crc) - binary.BigEndian.PutUint32(msg[4:8], length) - copy(msg[8:], data) - - _, err := enc.wr.Write(msg) - - return err -} - -/////////////////////////////////////////////////////////////////////////////// - -// IsDataCorruptionError returns true if data has been corrupted inside WAL. -func IsDataCorruptionError(err error) bool { - _, ok := err.(DataCorruptionError) - return ok -} - -// DataCorruptionError is an error that occures if data on disk was corrupted. -type DataCorruptionError struct { - cause error -} - -func (e DataCorruptionError) Error() string { - return fmt.Sprintf("DataCorruptionError[%v]", e.cause) -} - -func (e DataCorruptionError) Cause() error { - return e.cause -} - -// A WALDecoder reads and decodes custom-encoded WAL messages from an input -// stream. See WALEncoder for the format used. -// -// It will also compare the checksums and make sure data size is equal to the -// length from the header. If that is not the case, error will be returned. -type WALDecoder struct { - rd io.Reader -} - -// NewWALDecoder returns a new decoder that reads from rd. -func NewWALDecoder(rd io.Reader) *WALDecoder { - return &WALDecoder{rd} -} - -// Decode reads the next custom-encoded value from its reader and returns it. -func (dec *WALDecoder) Decode() (*TimedWALMessage, error) { - b := make([]byte, 4) - - _, err := dec.rd.Read(b) - if err == io.EOF { - return nil, err - } - if err != nil { - return nil, fmt.Errorf("failed to read checksum: %v", err) - } - crc := binary.BigEndian.Uint32(b) - - b = make([]byte, 4) - _, err = dec.rd.Read(b) - if err != nil { - return nil, fmt.Errorf("failed to read length: %v", err) - } - length := binary.BigEndian.Uint32(b) - - if length > maxMsgSizeBytes { - return nil, fmt.Errorf("length %d exceeded maximum possible value of %d bytes", length, maxMsgSizeBytes) - } - - data := make([]byte, length) - _, err = dec.rd.Read(data) - if err != nil { - return nil, fmt.Errorf("failed to read data: %v", err) - } - - // check checksum before decoding data - actualCRC := crc32.Checksum(data, crc32c) - if actualCRC != crc { - return nil, DataCorruptionError{fmt.Errorf("checksums do not match: (read: %v, actual: %v)", crc, actualCRC)} - } - - var res = new(TimedWALMessage) // nolint: gosimple - err = cdc.UnmarshalBinaryBare(data, res) - if err != nil { - return nil, DataCorruptionError{fmt.Errorf("failed to decode data: %v", err)} - } - - return res, err -} - -type nilWAL struct{} - -func (nilWAL) Write(m WALMessage) {} -func (nilWAL) WriteSync(m WALMessage) {} -func (nilWAL) Group() *auto.Group { return nil } -func (nilWAL) SearchForEndHeight(height int64, options *WALSearchOptions) (gr *auto.GroupReader, found bool, err error) { - return nil, false, nil -} -func (nilWAL) Start() error { return nil } -func (nilWAL) Stop() error { return nil } -func (nilWAL) Wait() {} diff --git a/consensus/wal_fuzz.go b/consensus/wal_fuzz.go deleted file mode 100644 index e15097c30..000000000 --- a/consensus/wal_fuzz.go +++ /dev/null @@ -1,31 +0,0 @@ -// +build gofuzz - -package consensus - -import ( - "bytes" - "io" -) - -func Fuzz(data []byte) int { - dec := NewWALDecoder(bytes.NewReader(data)) - for { - msg, err := dec.Decode() - if err == io.EOF { - break - } - if err != nil { - if msg != nil { - panic("msg != nil on error") - } - return 0 - } - var w bytes.Buffer - enc := NewWALEncoder(&w) - err = enc.Encode(msg) - if err != nil { - panic(err) - } - } - return 1 -} diff --git a/consensus/wal_generator.go b/consensus/wal_generator.go deleted file mode 100644 index f61af15f5..000000000 --- a/consensus/wal_generator.go +++ /dev/null @@ -1,205 +0,0 @@ -package consensus - -import ( - "bufio" - "bytes" - "fmt" - "os" - "path/filepath" - "strings" - "time" - - "github.com/pkg/errors" - "github.com/tendermint/abci/example/kvstore" - bc "github.com/tendermint/tendermint/blockchain" - cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/privval" - "github.com/tendermint/tendermint/proxy" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" - auto "github.com/tendermint/tmlibs/autofile" - cmn "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/db" - "github.com/tendermint/tmlibs/log" -) - -// WALWithNBlocks generates a consensus WAL. It does this by spining up a -// stripped down version of node (proxy app, event bus, consensus state) with a -// persistent kvstore application and special consensus wal instance -// (byteBufferWAL) and waits until numBlocks are created. Then it returns a WAL -// content. -func WALWithNBlocks(numBlocks int) (data []byte, err error) { - config := getConfig() - - app := kvstore.NewPersistentKVStoreApplication(filepath.Join(config.DBDir(), "wal_generator")) - - logger := log.TestingLogger().With("wal_generator", "wal_generator") - logger.Info("generating WAL (last height msg excluded)", "numBlocks", numBlocks) - - ///////////////////////////////////////////////////////////////////////////// - // COPY PASTE FROM node.go WITH A FEW MODIFICATIONS - // NOTE: we can't import node package because of circular dependency - privValidatorFile := config.PrivValidatorFile() - privValidator := privval.LoadOrGenFilePV(privValidatorFile) - genDoc, err := types.GenesisDocFromFile(config.GenesisFile()) - if err != nil { - return nil, errors.Wrap(err, "failed to read genesis file") - } - stateDB := db.NewMemDB() - blockStoreDB := db.NewMemDB() - state, err := sm.MakeGenesisState(genDoc) - if err != nil { - return nil, errors.Wrap(err, "failed to make genesis state") - } - blockStore := bc.NewBlockStore(blockStoreDB) - handshaker := NewHandshaker(stateDB, state, blockStore, genDoc) - proxyApp := proxy.NewAppConns(proxy.NewLocalClientCreator(app), handshaker) - proxyApp.SetLogger(logger.With("module", "proxy")) - if err := proxyApp.Start(); err != nil { - return nil, errors.Wrap(err, "failed to start proxy app connections") - } - defer proxyApp.Stop() - eventBus := types.NewEventBus() - eventBus.SetLogger(logger.With("module", "events")) - if err := eventBus.Start(); err != nil { - return nil, errors.Wrap(err, "failed to start event bus") - } - defer eventBus.Stop() - mempool := sm.MockMempool{} - evpool := sm.MockEvidencePool{} - blockExec := sm.NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(), mempool, evpool) - consensusState := NewConsensusState(config.Consensus, state.Copy(), blockExec, blockStore, mempool, evpool) - consensusState.SetLogger(logger) - consensusState.SetEventBus(eventBus) - if privValidator != nil { - consensusState.SetPrivValidator(privValidator) - } - // END OF COPY PASTE - ///////////////////////////////////////////////////////////////////////////// - - // set consensus wal to buffered WAL, which will write all incoming msgs to buffer - var b bytes.Buffer - wr := bufio.NewWriter(&b) - numBlocksWritten := make(chan struct{}) - wal := newByteBufferWAL(logger, NewWALEncoder(wr), int64(numBlocks), numBlocksWritten) - // see wal.go#103 - wal.Write(EndHeightMessage{0}) - consensusState.wal = wal - - if err := consensusState.Start(); err != nil { - return nil, errors.Wrap(err, "failed to start consensus state") - } - defer consensusState.Stop() - - select { - case <-numBlocksWritten: - wr.Flush() - return b.Bytes(), nil - case <-time.After(1 * time.Minute): - wr.Flush() - return b.Bytes(), fmt.Errorf("waited too long for tendermint to produce %d blocks (grep logs for `wal_generator`)", numBlocks) - } -} - -// f**ing long, but unique for each test -func makePathname() string { - // get path - p, err := os.Getwd() - if err != nil { - panic(err) - } - // fmt.Println(p) - sep := string(filepath.Separator) - return strings.Replace(p, sep, "_", -1) -} - -func randPort() int { - // returns between base and base + spread - base, spread := 20000, 20000 - return base + cmn.RandIntn(spread) -} - -func makeAddrs() (string, string, string) { - start := randPort() - return fmt.Sprintf("tcp://0.0.0.0:%d", start), - fmt.Sprintf("tcp://0.0.0.0:%d", start+1), - fmt.Sprintf("tcp://0.0.0.0:%d", start+2) -} - -// getConfig returns a config for test cases -func getConfig() *cfg.Config { - pathname := makePathname() - c := cfg.ResetTestRoot(fmt.Sprintf("%s_%d", pathname, cmn.RandInt())) - - // and we use random ports to run in parallel - tm, rpc, grpc := makeAddrs() - c.P2P.ListenAddress = tm - c.RPC.ListenAddress = rpc - c.RPC.GRPCListenAddress = grpc - return c -} - -// byteBufferWAL is a WAL which writes all msgs to a byte buffer. Writing stops -// when the heightToStop is reached. Client will be notified via -// signalWhenStopsTo channel. -type byteBufferWAL struct { - enc *WALEncoder - stopped bool - heightToStop int64 - signalWhenStopsTo chan<- struct{} - - logger log.Logger -} - -// needed for determinism -var fixedTime, _ = time.Parse(time.RFC3339, "2017-01-02T15:04:05Z") - -func newByteBufferWAL(logger log.Logger, enc *WALEncoder, nBlocks int64, signalStop chan<- struct{}) *byteBufferWAL { - return &byteBufferWAL{ - enc: enc, - heightToStop: nBlocks, - signalWhenStopsTo: signalStop, - logger: logger, - } -} - -// Save writes message to the internal buffer except when heightToStop is -// reached, in which case it will signal the caller via signalWhenStopsTo and -// skip writing. -func (w *byteBufferWAL) Write(m WALMessage) { - if w.stopped { - w.logger.Debug("WAL already stopped. Not writing message", "msg", m) - return - } - - if endMsg, ok := m.(EndHeightMessage); ok { - w.logger.Debug("WAL write end height message", "height", endMsg.Height, "stopHeight", w.heightToStop) - if endMsg.Height == w.heightToStop { - w.logger.Debug("Stopping WAL at height", "height", endMsg.Height) - w.signalWhenStopsTo <- struct{}{} - w.stopped = true - return - } - } - - w.logger.Debug("WAL Write Message", "msg", m) - err := w.enc.Encode(&TimedWALMessage{fixedTime, m}) - if err != nil { - panic(fmt.Sprintf("failed to encode the msg %v", m)) - } -} - -func (w *byteBufferWAL) WriteSync(m WALMessage) { - w.Write(m) -} - -func (w *byteBufferWAL) Group() *auto.Group { - panic("not implemented") -} -func (w *byteBufferWAL) SearchForEndHeight(height int64, options *WALSearchOptions) (gr *auto.GroupReader, found bool, err error) { - return nil, false, nil -} - -func (w *byteBufferWAL) Start() error { return nil } -func (w *byteBufferWAL) Stop() error { return nil } -func (w *byteBufferWAL) Wait() {} diff --git a/consensus/wal_test.go b/consensus/wal_test.go deleted file mode 100644 index eebbc85a2..000000000 --- a/consensus/wal_test.go +++ /dev/null @@ -1,133 +0,0 @@ -package consensus - -import ( - "bytes" - "crypto/rand" - // "sync" - "testing" - "time" - - "github.com/tendermint/tendermint/consensus/types" - tmtypes "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tmlibs/common" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestWALEncoderDecoder(t *testing.T) { - now := time.Now() - msgs := []TimedWALMessage{ - TimedWALMessage{Time: now, Msg: EndHeightMessage{0}}, - TimedWALMessage{Time: now, Msg: timeoutInfo{Duration: time.Second, Height: 1, Round: 1, Step: types.RoundStepPropose}}, - } - - b := new(bytes.Buffer) - - for _, msg := range msgs { - b.Reset() - - enc := NewWALEncoder(b) - err := enc.Encode(&msg) - require.NoError(t, err) - - dec := NewWALDecoder(b) - decoded, err := dec.Decode() - require.NoError(t, err) - - assert.Equal(t, msg.Time.UTC(), decoded.Time) - assert.Equal(t, msg.Msg, decoded.Msg) - } -} - -func TestWALSearchForEndHeight(t *testing.T) { - walBody, err := WALWithNBlocks(6) - if err != nil { - t.Fatal(err) - } - walFile := tempWALWithData(walBody) - - wal, err := NewWAL(walFile) - if err != nil { - t.Fatal(err) - } - - h := int64(3) - gr, found, err := wal.SearchForEndHeight(h, &WALSearchOptions{}) - assert.NoError(t, err, cmn.Fmt("expected not to err on height %d", h)) - assert.True(t, found, cmn.Fmt("expected to find end height for %d", h)) - assert.NotNil(t, gr, "expected group not to be nil") - defer gr.Close() - - dec := NewWALDecoder(gr) - msg, err := dec.Decode() - assert.NoError(t, err, "expected to decode a message") - rs, ok := msg.Msg.(tmtypes.EventDataRoundState) - assert.True(t, ok, "expected message of type EventDataRoundState") - assert.Equal(t, rs.Height, h+1, cmn.Fmt("wrong height")) -} - -/* -var initOnce sync.Once - -func registerInterfacesOnce() { - initOnce.Do(func() { - var _ = wire.RegisterInterface( - struct{ WALMessage }{}, - wire.ConcreteType{[]byte{}, 0x10}, - ) - }) -} -*/ - -func nBytes(n int) []byte { - buf := make([]byte, n) - n, _ = rand.Read(buf) - return buf[:n] -} - -func benchmarkWalDecode(b *testing.B, n int) { - // registerInterfacesOnce() - - buf := new(bytes.Buffer) - enc := NewWALEncoder(buf) - - data := nBytes(n) - enc.Encode(&TimedWALMessage{Msg: data, Time: time.Now().Round(time.Second)}) - - encoded := buf.Bytes() - - b.ResetTimer() - for i := 0; i < b.N; i++ { - buf.Reset() - buf.Write(encoded) - dec := NewWALDecoder(buf) - if _, err := dec.Decode(); err != nil { - b.Fatal(err) - } - } - b.ReportAllocs() -} - -func BenchmarkWalDecode512B(b *testing.B) { - benchmarkWalDecode(b, 512) -} - -func BenchmarkWalDecode10KB(b *testing.B) { - benchmarkWalDecode(b, 10*1024) -} -func BenchmarkWalDecode100KB(b *testing.B) { - benchmarkWalDecode(b, 100*1024) -} -func BenchmarkWalDecode1MB(b *testing.B) { - benchmarkWalDecode(b, 1024*1024) -} -func BenchmarkWalDecode10MB(b *testing.B) { - benchmarkWalDecode(b, 10*1024*1024) -} -func BenchmarkWalDecode100MB(b *testing.B) { - benchmarkWalDecode(b, 100*1024*1024) -} -func BenchmarkWalDecode1GB(b *testing.B) { - benchmarkWalDecode(b, 1024*1024*1024) -} diff --git a/consensus/wire.go b/consensus/wire.go deleted file mode 100644 index 81223c689..000000000 --- a/consensus/wire.go +++ /dev/null @@ -1,14 +0,0 @@ -package consensus - -import ( - "github.com/tendermint/go-amino" - "github.com/tendermint/go-crypto" -) - -var cdc = amino.NewCodec() - -func init() { - RegisterConsensusMessages(cdc) - RegisterWALMessages(cdc) - crypto.RegisterAmino(cdc) -} diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 61862e5c1..000000000 --- a/docker-compose.yml +++ /dev/null @@ -1,68 +0,0 @@ -version: '3' - -services: - node0: - container_name: node0 - image: "tendermint/localnode" - ports: - - "26656-26657:26656-26657" - environment: - - ID=0 - - LOG=$${LOG:-tendermint.log} - volumes: - - ./build:/tendermint:Z - networks: - localnet: - ipv4_address: 192.167.10.2 - - node1: - container_name: node1 - image: "tendermint/localnode" - ports: - - "26659-26660:26656-26657" - environment: - - ID=1 - - LOG=$${LOG:-tendermint.log} - volumes: - - ./build:/tendermint:Z - networks: - localnet: - ipv4_address: 192.167.10.3 - - node2: - container_name: node2 - image: "tendermint/localnode" - environment: - - ID=2 - - LOG=$${LOG:-tendermint.log} - ports: - - "26661-26662:26656-26657" - volumes: - - ./build:/tendermint:Z - networks: - localnet: - ipv4_address: 192.167.10.4 - - node3: - container_name: node3 - image: "tendermint/localnode" - environment: - - ID=3 - - LOG=$${LOG:-tendermint.log} - ports: - - "26663-26664:26656-26657" - volumes: - - ./build:/tendermint:Z - networks: - localnet: - ipv4_address: 192.167.10.5 - -networks: - localnet: - driver: bridge - ipam: - driver: default - config: - - - subnet: 192.167.10.0/16 - diff --git a/docs/.python-version b/docs/.python-version deleted file mode 100644 index 9bbf49249..000000000 --- a/docs/.python-version +++ /dev/null @@ -1 +0,0 @@ -2.7.14 diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 442c9be65..000000000 --- a/docs/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = python -msphinx -SPHINXPROJ = Tendermint -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -install: - @pip install -r requirements.txt - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 180acdcb9..000000000 --- a/docs/README.md +++ /dev/null @@ -1,14 +0,0 @@ -Here lies our documentation. After making edits, run: - -``` -pip install -r requirements.txt -make html -``` - -to build the docs locally then open the file `_build/html/index.html` in your browser. - -**WARNING:** This documentation is intended to be viewed at: - -https://tendermint.readthedocs.io - -and may contain broken internal links when viewed from Github. diff --git a/docs/_static/custom_collapsible_code.css b/docs/_static/custom_collapsible_code.css deleted file mode 100644 index 695268a83..000000000 --- a/docs/_static/custom_collapsible_code.css +++ /dev/null @@ -1,17 +0,0 @@ -.toggle { - padding-bottom: 1em ; -} - -.toggle .header { - display: block; - clear: both; - cursor: pointer; -} - -.toggle .header:after { - content: " ▼"; -} - -.toggle .header.open:after { - content: " ▲"; -} \ No newline at end of file diff --git a/docs/_static/custom_collapsible_code.js b/docs/_static/custom_collapsible_code.js deleted file mode 100644 index f4ff22adc..000000000 --- a/docs/_static/custom_collapsible_code.js +++ /dev/null @@ -1,10 +0,0 @@ -let makeCodeBlocksCollapsible = function() { - $(".toggle > *").hide(); - $(".toggle .header").show(); - $(".toggle .header").click(function() { - $(this).parent().children().not(".header").toggle({"duration": 400}); - $(this).parent().children(".header").toggleClass("open"); - }); -}; -// we could use the }(); way if we would have access to jQuery in HEAD, i.e. we would need to force the theme -// to load jQuery before our custom scripts diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html deleted file mode 100644 index 736460bc0..000000000 --- a/docs/_templates/layout.html +++ /dev/null @@ -1,20 +0,0 @@ -{% extends "!layout.html" %} - -{% set css_files = css_files + ["_static/custom_collapsible_code.css"] %} - -# sadly, I didn't find a css style way to add custom JS to a list that is automagically added to head like CSS (above) #} -{% block extrahead %} - -{% endblock %} - -{% block footer %} - -{% endblock %} - - diff --git a/docs/abci-cli.md b/docs/abci-cli.md deleted file mode 100644 index 14095d162..000000000 --- a/docs/abci-cli.md +++ /dev/null @@ -1,329 +0,0 @@ -# Using ABCI-CLI - -To facilitate testing and debugging of ABCI servers and simple apps, we -built a CLI, the `abci-cli`, for sending ABCI messages from the command -line. - -## Install - -Make sure you [have Go installed](https://golang.org/doc/install). - -Next, install the `abci-cli` tool and example applications: - - go get -u github.com/tendermint/abci/cmd/abci-cli - -If this fails, you may need to use [dep](https://github.com/golang/dep) -to get vendored dependencies: - - cd $GOPATH/src/github.com/tendermint/abci - make get_tools - make get_vendor_deps - make install - -Now run `abci-cli` to see the list of commands: - - Usage: - abci-cli [command] - - Available Commands: - batch Run a batch of abci commands against an application - check_tx Validate a tx - commit Commit the application state and return the Merkle root hash - console Start an interactive abci console for multiple commands - counter ABCI demo example - deliver_tx Deliver a new tx to the application - kvstore ABCI demo example - echo Have the application echo a message - help Help about any command - info Get some info about the application - query Query the application state - set_option Set an options on the application - - Flags: - --abci string socket or grpc (default "socket") - --address string address of application socket (default "tcp://127.0.0.1:26658") - -h, --help help for abci-cli - -v, --verbose print the command and results as if it were a console session - - Use "abci-cli [command] --help" for more information about a command. - -## KVStore - First Example - -The `abci-cli` tool lets us send ABCI messages to our application, to -help build and debug them. - -The most important messages are `deliver_tx`, `check_tx`, and `commit`, -but there are others for convenience, configuration, and information -purposes. - -We'll start a kvstore application, which was installed at the same time -as `abci-cli` above. The kvstore just stores transactions in a merkle -tree. - -Its code can be found -[here](https://github.com/tendermint/abci/blob/master/cmd/abci-cli/abci-cli.go) -and looks like: - - func cmdKVStore(cmd *cobra.Command, args []string) error { - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) - - // Create the application - in memory or persisted to disk - var app types.Application - if flagPersist == "" { - app = kvstore.NewKVStoreApplication() - } else { - app = kvstore.NewPersistentKVStoreApplication(flagPersist) - app.(*kvstore.PersistentKVStoreApplication).SetLogger(logger.With("module", "kvstore")) - } - - // Start the listener - srv, err := server.NewServer(flagAddrD, flagAbci, app) - if err != nil { - return err - } - srv.SetLogger(logger.With("module", "abci-server")) - if err := srv.Start(); err != nil { - return err - } - - // Wait forever - cmn.TrapSignal(func() { - // Cleanup - srv.Stop() - }) - return nil - } - -Start by running: - - abci-cli kvstore - -And in another terminal, run - - abci-cli echo hello - abci-cli info - -You'll see something like: - - -> data: hello - -> data.hex: 68656C6C6F - -and: - - -> data: {"size":0} - -> data.hex: 7B2273697A65223A307D - -An ABCI application must provide two things: - -- a socket server -- a handler for ABCI messages - -When we run the `abci-cli` tool we open a new connection to the -application's socket server, send the given ABCI message, and wait for a -response. - -The server may be generic for a particular language, and we provide a -[reference implementation in -Golang](https://github.com/tendermint/abci/tree/master/server). See the -[list of other ABCI implementations](./ecosystem.html) for servers in -other languages. - -The handler is specific to the application, and may be arbitrary, so -long as it is deterministic and conforms to the ABCI interface -specification. - -So when we run `abci-cli info`, we open a new connection to the ABCI -server, which calls the `Info()` method on the application, which tells -us the number of transactions in our Merkle tree. - -Now, since every command opens a new connection, we provide the -`abci-cli console` and `abci-cli batch` commands, to allow multiple ABCI -messages to be sent over a single connection. - -Running `abci-cli console` should drop you in an interactive console for -speaking ABCI messages to your application. - -Try running these commands: - - > echo hello - -> code: OK - -> data: hello - -> data.hex: 0x68656C6C6F - - > info - -> code: OK - -> data: {"size":0} - -> data.hex: 0x7B2273697A65223A307D - - > commit - -> code: OK - -> data.hex: 0x0000000000000000 - - > deliver_tx "abc" - -> code: OK - - > info - -> code: OK - -> data: {"size":1} - -> data.hex: 0x7B2273697A65223A317D - - > commit - -> code: OK - -> data.hex: 0x0200000000000000 - - > query "abc" - -> code: OK - -> log: exists - -> height: 0 - -> value: abc - -> value.hex: 616263 - - > deliver_tx "def=xyz" - -> code: OK - - > commit - -> code: OK - -> data.hex: 0x0400000000000000 - - > query "def" - -> code: OK - -> log: exists - -> height: 0 - -> value: xyz - -> value.hex: 78797A - -Note that if we do `deliver_tx "abc"` it will store `(abc, abc)`, but if -we do `deliver_tx "abc=efg"` it will store `(abc, efg)`. - -Similarly, you could put the commands in a file and run -`abci-cli --verbose batch < myfile`. - -## Counter - Another Example - -Now that we've got the hang of it, let's try another application, the -"counter" app. - -Like the kvstore app, its code can be found -[here](https://github.com/tendermint/abci/blob/master/cmd/abci-cli/abci-cli.go) -and looks like: - - func cmdCounter(cmd *cobra.Command, args []string) error { - - app := counter.NewCounterApplication(flagSerial) - - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) - - // Start the listener - srv, err := server.NewServer(flagAddrC, flagAbci, app) - if err != nil { - return err - } - srv.SetLogger(logger.With("module", "abci-server")) - if err := srv.Start(); err != nil { - return err - } - - // Wait forever - cmn.TrapSignal(func() { - // Cleanup - srv.Stop() - }) - return nil - } - -The counter app doesn't use a Merkle tree, it just counts how many times -we've sent a transaction, asked for a hash, or committed the state. The -result of `commit` is just the number of transactions sent. - -This application has two modes: `serial=off` and `serial=on`. - -When `serial=on`, transactions must be a big-endian encoded incrementing -integer, starting at 0. - -If `serial=off`, there are no restrictions on transactions. - -We can toggle the value of `serial` using the `set_option` ABCI message. - -When `serial=on`, some transactions are invalid. In a live blockchain, -transactions collect in memory before they are committed into blocks. To -avoid wasting resources on invalid transactions, ABCI provides the -`check_tx` message, which application developers can use to accept or -reject transactions, before they are stored in memory or gossipped to -other peers. - -In this instance of the counter app, `check_tx` only allows transactions -whose integer is greater than the last committed one. - -Let's kill the console and the kvstore application, and start the -counter app: - - abci-cli counter - -In another window, start the `abci-cli console`: - - > set_option serial on - -> code: OK - -> log: OK (SetOption doesn't return anything.) - - > check_tx 0x00 - -> code: OK - - > check_tx 0xff - -> code: OK - - > deliver_tx 0x00 - -> code: OK - - > check_tx 0x00 - -> code: BadNonce - -> log: Invalid nonce. Expected >= 1, got 0 - - > deliver_tx 0x01 - -> code: OK - - > deliver_tx 0x04 - -> code: BadNonce - -> log: Invalid nonce. Expected 2, got 4 - - > info - -> code: OK - -> data: {"hashes":0,"txs":2} - -> data.hex: 0x7B22686173686573223A302C22747873223A327D - -This is a very simple application, but between `counter` and `kvstore`, -its easy to see how you can build out arbitrary application states on -top of the ABCI. [Hyperledger's -Burrow](https://github.com/hyperledger/burrow) also runs atop ABCI, -bringing with it Ethereum-like accounts, the Ethereum virtual-machine, -Monax's permissioning scheme, and native contracts extensions. - -But the ultimate flexibility comes from being able to write the -application easily in any language. - -We have implemented the counter in a number of languages [see the -example directory](https://github.com/tendermint/abci/tree/master/example). - -To run the Node JS version, `cd` to `example/js` and run - - node app.js - -(you'll have to kill the other counter application process). In another -window, run the console and those previous ABCI commands. You should get -the same results as for the Go version. - -## Bounties - -Want to write the counter app in your favorite language?! We'd be happy -to add you to our [ecosystem](https://tendermint.com/ecosystem)! We're -also offering [bounties](https://hackerone.com/tendermint/) for -implementations in new languages! - -The `abci-cli` is designed strictly for testing and debugging. In a real -deployment, the role of sending messages is taken by Tendermint, which -connects to the app using three separate connections, each with its own -pattern of messages. - -For more information, see the [application developers -guide](./app-development.html). For examples of running an ABCI app with -Tendermint, see the [getting started guide](./getting-started.html). -Next is the ABCI specification. diff --git a/docs/app-architecture.md b/docs/app-architecture.md deleted file mode 100644 index 64b1a3794..000000000 --- a/docs/app-architecture.md +++ /dev/null @@ -1,50 +0,0 @@ -# Application Architecture Guide - -Here we provide a brief guide on the recommended architecture of a -Tendermint blockchain application. - -The following diagram provides a superb example: - - - -The end-user application here is the Cosmos Voyager, at the bottom left. -Voyager communicates with a REST API exposed by a local Light-Client -Daemon. The Light-Client Daemon is an application specific program that -communicates with Tendermint nodes and verifies Tendermint light-client -proofs through the Tendermint Core RPC. The Tendermint Core process -communicates with a local ABCI application, where the user query or -transaction is actually processed. - -The ABCI application must be a deterministic result of the Tendermint -consensus - any external influence on the application state that didn't -come through Tendermint could cause a consensus failure. Thus *nothing* -should communicate with the application except Tendermint via ABCI. - -If the application is written in Go, it can be compiled into the -Tendermint binary. Otherwise, it should use a unix socket to communicate -with Tendermint. If it's necessary to use TCP, extra care must be taken -to encrypt and authenticate the connection. - -All reads from the app happen through the Tendermint `/abci_query` -endpoint. All writes to the app happen through the Tendermint -`/broadcast_tx_*` endpoints. - -The Light-Client Daemon is what provides light clients (end users) with -nearly all the security of a full node. It formats and broadcasts -transactions, and verifies proofs of queries and transaction results. -Note that it need not be a daemon - the Light-Client logic could instead -be implemented in the same process as the end-user application. - -Note for those ABCI applications with weaker security requirements, the -functionality of the Light-Client Daemon can be moved into the ABCI -application process itself. That said, exposing the application process -to anything besides Tendermint over ABCI requires extreme caution, as -all transactions, and possibly all queries, should still pass through -Tendermint. - -See the following for more extensive documentation: -- [Interchain Standard for the Light-Client REST API](https://github.com/cosmos/cosmos-sdk/pull/1028) -- [Tendermint RPC Docs](https://tendermint.github.io/slate/) -- [Tendermint in Production](https://github.com/tendermint/tendermint/pull/1618) -- [Tendermint Basics](https://tendermint.readthedocs.io/en/master/using-tendermint.html) -- [ABCI spec](https://github.com/tendermint/abci/blob/develop/specification.md) diff --git a/docs/app-development.md b/docs/app-development.md deleted file mode 100644 index 488657670..000000000 --- a/docs/app-development.md +++ /dev/null @@ -1,527 +0,0 @@ -# Application Development Guide - -## ABCI Design - -The purpose of ABCI is to provide a clean interface between state -transition machines on one computer and the mechanics of their -replication across multiple computers. The former we call 'application -logic' and the latter the 'consensus engine'. Application logic -validates transactions and optionally executes transactions against some -persistent state. A consensus engine ensures all transactions are -replicated in the same order on every machine. We call each machine in a -consensus engine a 'validator', and each validator runs the same -transactions through the same application logic. In particular, we are -interested in blockchain-style consensus engines, where transactions are -committed in hash-linked blocks. - -The ABCI design has a few distinct components: - -- message protocol - - pairs of request and response messages - - consensus makes requests, application responds - - defined using protobuf -- server/client - - consensus engine runs the client - - application runs the server - - two implementations: - - async raw bytes - - grpc -- blockchain protocol - - abci is connection oriented - - Tendermint Core maintains three connections: - - [mempool connection](#mempool-connection): for checking if - transactions should be relayed before they are committed; - only uses `CheckTx` - - [consensus connection](#consensus-connection): for executing - transactions that have been committed. Message sequence is - -for every block - -`BeginBlock, [DeliverTx, ...], EndBlock, Commit` - - [query connection](#query-connection): for querying the - application state; only uses Query and Info - -The mempool and consensus logic act as clients, and each maintains an -open ABCI connection with the application, which hosts an ABCI server. -Shown are the request and response types sent on each connection. - -## Message Protocol - -The message protocol consists of pairs of requests and responses. Some -messages have no fields, while others may include byte-arrays, strings, -or integers. See the `message Request` and `message Response` -definitions in [the protobuf definition -file](https://github.com/tendermint/abci/blob/master/types/types.proto), -and the [protobuf -documentation](https://developers.google.com/protocol-buffers/docs/overview) -for more details. - -For each request, a server should respond with the corresponding -response, where order of requests is preserved in the order of -responses. - -## Server - -To use ABCI in your programming language of choice, there must be a ABCI -server in that language. Tendermint supports two kinds of implementation -of the server: - -- Asynchronous, raw socket server (Tendermint Socket Protocol, also - known as TSP or Teaspoon) -- GRPC - -Both can be tested using the `abci-cli` by setting the `--abci` flag -appropriately (ie. to `socket` or `grpc`). - -See examples, in various stages of maintenance, in -[Go](https://github.com/tendermint/abci/tree/master/server), -[JavaScript](https://github.com/tendermint/js-abci), -[Python](https://github.com/tendermint/abci/tree/master/example/python3/abci), -[C++](https://github.com/mdyring/cpp-tmsp), and -[Java](https://github.com/jTendermint/jabci). - -### GRPC - -If GRPC is available in your language, this is the easiest approach, -though it will have significant performance overhead. - -To get started with GRPC, copy in the [protobuf -file](https://github.com/tendermint/abci/blob/master/types/types.proto) -and compile it using the GRPC plugin for your language. For instance, -for golang, the command is `protoc --go_out=plugins=grpc:. types.proto`. -See the [grpc documentation for more details](http://www.grpc.io/docs/). -`protoc` will autogenerate all the necessary code for ABCI client and -server in your language, including whatever interface your application -must satisfy to be used by the ABCI server for handling requests. - -### TSP - -If GRPC is not available in your language, or you require higher -performance, or otherwise enjoy programming, you may implement your own -ABCI server using the Tendermint Socket Protocol, known affectionately -as Teaspoon. The first step is still to auto-generate the relevant data -types and codec in your language using `protoc`. Messages coming over -the socket are Protobuf3 encoded, but additionally length-prefixed to -facilitate use as a streaming protocol. Protobuf3 doesn't have an -official length-prefix standard, so we use our own. The first byte in -the prefix represents the length of the Big Endian encoded length. The -remaining bytes in the prefix are the Big Endian encoded length. - -For example, if the Protobuf3 encoded ABCI message is 0xDEADBEEF (4 -bytes), the length-prefixed message is 0x0104DEADBEEF. If the Protobuf3 -encoded ABCI message is 65535 bytes long, the length-prefixed message -would be like 0x02FFFF.... - -Note this prefixing does not apply for grpc. - -An ABCI server must also be able to support multiple connections, as -Tendermint uses three connections. - -## Client - -There are currently two use-cases for an ABCI client. One is a testing -tool, as in the `abci-cli`, which allows ABCI requests to be sent via -command line. The other is a consensus engine, such as Tendermint Core, -which makes requests to the application every time a new transaction is -received or a block is committed. - -It is unlikely that you will need to implement a client. For details of -our client, see -[here](https://github.com/tendermint/abci/tree/master/client). - -Most of the examples below are from [kvstore -application](https://github.com/tendermint/abci/blob/master/example/kvstore/kvstore.go), -which is a part of the abci repo. [persistent_kvstore -application](https://github.com/tendermint/abci/blob/master/example/kvstore/persistent_kvstore.go) -is used to show `BeginBlock`, `EndBlock` and `InitChain` example -implementations. - -## Blockchain Protocol - -In ABCI, a transaction is simply an arbitrary length byte-array. It is -the application's responsibility to define the transaction codec as they -please, and to use it for both CheckTx and DeliverTx. - -Note that there are two distinct means for running transactions, -corresponding to stages of 'awareness' of the transaction in the -network. The first stage is when a transaction is received by a -validator from a client into the so-called mempool or transaction pool --this is where we use CheckTx. The second is when the transaction is -successfully committed on more than 2/3 of validators - where we use -DeliverTx. In the former case, it may not be necessary to run all the -state transitions associated with the transaction, as the transaction -may not ultimately be committed until some much later time, when the -result of its execution will be different. For instance, an Ethereum -ABCI app would check signatures and amounts in CheckTx, but would not -actually execute any contract code until the DeliverTx, so as to avoid -executing state transitions that have not been finalized. - -To formalize the distinction further, two explicit ABCI connections are -made between Tendermint Core and the application: the mempool connection -and the consensus connection. We also make a third connection, the query -connection, to query the local state of the app. - -### Mempool Connection - -The mempool connection is used *only* for CheckTx requests. Transactions -are run using CheckTx in the same order they were received by the -validator. If the CheckTx returns `OK`, the transaction is kept in -memory and relayed to other peers in the same order it was received. -Otherwise, it is discarded. - -CheckTx requests run concurrently with block processing; so they should -run against a copy of the main application state which is reset after -every block. This copy is necessary to track transitions made by a -sequence of CheckTx requests before they are included in a block. When a -block is committed, the application must ensure to reset the mempool -state to the latest committed state. Tendermint Core will then filter -through all transactions in the mempool, removing any that were included -in the block, and re-run the rest using CheckTx against the post-Commit -mempool state (this behaviour can be turned off with -`[mempool] recheck = false`). - -In go: - - func (app *KVStoreApplication) CheckTx(tx []byte) types.Result { - return types.OK - } - -In Java: - - ResponseCheckTx requestCheckTx(RequestCheckTx req) { - byte[] transaction = req.getTx().toByteArray(); - - // validate transaction - - if (notValid) { - return ResponseCheckTx.newBuilder().setCode(CodeType.BadNonce).setLog("invalid tx").build(); - } else { - return ResponseCheckTx.newBuilder().setCode(CodeType.OK).build(); - } - } - -### Replay Protection - -To prevent old transactions from being replayed, CheckTx must implement -replay protection. - -Tendermint provides the first defence layer by keeping a lightweight -in-memory cache of 100k (`[mempool] cache_size`) last transactions in -the mempool. If Tendermint is just started or the clients sent more than -100k transactions, old transactions may be sent to the application. So -it is important CheckTx implements some logic to handle them. - -There are cases where a transaction will (or may) become valid in some -future state, in which case you probably want to disable Tendermint's -cache. You can do that by setting `[mempool] cache_size = 0` in the -config. - -### Consensus Connection - -The consensus connection is used only when a new block is committed, and -communicates all information from the block in a series of requests: -`BeginBlock, [DeliverTx, ...], EndBlock, Commit`. That is, when a block -is committed in the consensus, we send a list of DeliverTx requests (one -for each transaction) sandwiched by BeginBlock and EndBlock requests, -and followed by a Commit. - -### DeliverTx - -DeliverTx is the workhorse of the blockchain. Tendermint sends the -DeliverTx requests asynchronously but in order, and relies on the -underlying socket protocol (ie. TCP) to ensure they are received by the -app in order. They have already been ordered in the global consensus by -the Tendermint protocol. - -DeliverTx returns a abci.Result, which includes a Code, Data, and Log. -The code may be non-zero (non-OK), meaning the corresponding transaction -should have been rejected by the mempool, but may have been included in -a block by a Byzantine proposer. - -The block header will be updated (TODO) to include some commitment to -the results of DeliverTx, be it a bitarray of non-OK transactions, or a -merkle root of the data returned by the DeliverTx requests, or both. - -In go: - - // tx is either "key=value" or just arbitrary bytes - func (app *KVStoreApplication) DeliverTx(tx []byte) types.Result { - parts := strings.Split(string(tx), "=") - if len(parts) == 2 { - app.state.Set([]byte(parts[0]), []byte(parts[1])) - } else { - app.state.Set(tx, tx) - } - return types.OK - } - -In Java: - - /** - * Using Protobuf types from the protoc compiler, we always start with a byte[] - */ - ResponseDeliverTx deliverTx(RequestDeliverTx request) { - byte[] transaction = request.getTx().toByteArray(); - - // validate your transaction - - if (notValid) { - return ResponseDeliverTx.newBuilder().setCode(CodeType.BadNonce).setLog("transaction was invalid").build(); - } else { - ResponseDeliverTx.newBuilder().setCode(CodeType.OK).build(); - } - - } - -### Commit - -Once all processing of the block is complete, Tendermint sends the -Commit request and blocks waiting for a response. While the mempool may -run concurrently with block processing (the BeginBlock, DeliverTxs, and -EndBlock), it is locked for the Commit request so that its state can be -safely reset during Commit. This means the app *MUST NOT* do any -blocking communication with the mempool (ie. broadcast\_tx) during -Commit, or there will be deadlock. Note also that all remaining -transactions in the mempool are replayed on the mempool connection -(CheckTx) following a commit. - -The app should respond to the Commit request with a byte array, which is -the deterministic state root of the application. It is included in the -header of the next block. It can be used to provide easily verified -Merkle-proofs of the state of the application. - -It is expected that the app will persist state to disk on Commit. The -option to have all transactions replayed from some previous block is the -job of the [Handshake](#handshake). - -In go: - - func (app *KVStoreApplication) Commit() types.Result { - hash := app.state.Hash() - return types.NewResultOK(hash, "") - } - -In Java: - - ResponseCommit requestCommit(RequestCommit requestCommit) { - - // update the internal app-state - byte[] newAppState = calculateAppState(); - - // and return it to the node - return ResponseCommit.newBuilder().setCode(CodeType.OK).setData(ByteString.copyFrom(newAppState)).build(); - } - -### BeginBlock - -The BeginBlock request can be used to run some code at the beginning of -every block. It also allows Tendermint to send the current block hash -and header to the application, before it sends any of the transactions. - -The app should remember the latest height and header (ie. from which it -has run a successful Commit) so that it can tell Tendermint where to -pick up from when it restarts. See information on the Handshake, below. - -In go: - - // Track the block hash and header information - func (app *PersistentKVStoreApplication) BeginBlock(params types.RequestBeginBlock) { - // update latest block info - app.blockHeader = params.Header - - // reset valset changes - app.changes = make([]*types.Validator, 0) - } - -In Java: - - /* - * all types come from protobuf definition - */ - ResponseBeginBlock requestBeginBlock(RequestBeginBlock req) { - - Header header = req.getHeader(); - byte[] prevAppHash = header.getAppHash().toByteArray(); - long prevHeight = header.getHeight(); - long numTxs = header.getNumTxs(); - - // run your pre-block logic. Maybe prepare a state snapshot, message components, etc - - return ResponseBeginBlock.newBuilder().build(); - } - -### EndBlock - -The EndBlock request can be used to run some code at the end of every -block. Additionally, the response may contain a list of validators, -which can be used to update the validator set. To add a new validator or -update an existing one, simply include them in the list returned in the -EndBlock response. To remove one, include it in the list with a `power` -equal to `0`. Tendermint core will take care of updating the validator -set. Note the change in voting power must be strictly less than 1/3 per -block if you want a light client to be able to prove the transition -externally. See the [light client -docs](https://godoc.org/github.com/tendermint/tendermint/lite#hdr-How_We_Track_Validators) -for details on how it tracks validators. - -In go: - - // Update the validator set - func (app *PersistentKVStoreApplication) EndBlock(req types.RequestEndBlock) types.ResponseEndBlock { - return types.ResponseEndBlock{ValidatorUpdates: app.ValUpdates} - } - -In Java: - - /* - * Assume that one validator changes. The new validator has a power of 10 - */ - ResponseEndBlock requestEndBlock(RequestEndBlock req) { - final long currentHeight = req.getHeight(); - final byte[] validatorPubKey = getValPubKey(); - - ResponseEndBlock.Builder builder = ResponseEndBlock.newBuilder(); - builder.addDiffs(1, Types.Validator.newBuilder().setPower(10L).setPubKey(ByteString.copyFrom(validatorPubKey)).build()); - - return builder.build(); - } - -### Query Connection - -This connection is used to query the application without engaging -consensus. It's exposed over the tendermint core rpc, so clients can -query the app without exposing a server on the app itself, but they must -serialize each query as a single byte array. Additionally, certain -"standardized" queries may be used to inform local decisions, for -instance about which peers to connect to. - -Tendermint Core currently uses the Query connection to filter peers upon -connecting, according to IP address or public key. For instance, -returning non-OK ABCI response to either of the following queries will -cause Tendermint to not connect to the corresponding peer: - -- `p2p/filter/addr/`, where `` is an IP address. -- `p2p/filter/pubkey/`, where `` is the hex-encoded - ED25519 key of the node (not it's validator key) - -Note: these query formats are subject to change! - -In go: - - func (app *KVStoreApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) { - if reqQuery.Prove { - value, proof, exists := app.state.Proof(reqQuery.Data) - resQuery.Index = -1 // TODO make Proof return index - resQuery.Key = reqQuery.Data - resQuery.Value = value - resQuery.Proof = proof - if exists { - resQuery.Log = "exists" - } else { - resQuery.Log = "does not exist" - } - return - } else { - index, value, exists := app.state.Get(reqQuery.Data) - resQuery.Index = int64(index) - resQuery.Value = value - if exists { - resQuery.Log = "exists" - } else { - resQuery.Log = "does not exist" - } - return - } - } - -In Java: - - ResponseQuery requestQuery(RequestQuery req) { - final boolean isProveQuery = req.getProve(); - final ResponseQuery.Builder responseBuilder = ResponseQuery.newBuilder(); - - if (isProveQuery) { - com.app.example.ProofResult proofResult = generateProof(req.getData().toByteArray()); - final byte[] proofAsByteArray = proofResult.getAsByteArray(); - - responseBuilder.setProof(ByteString.copyFrom(proofAsByteArray)); - responseBuilder.setKey(req.getData()); - responseBuilder.setValue(ByteString.copyFrom(proofResult.getData())); - responseBuilder.setLog(result.getLogValue()); - } else { - byte[] queryData = req.getData().toByteArray(); - - final com.app.example.QueryResult result = generateQueryResult(queryData); - - responseBuilder.setIndex(result.getIndex()); - responseBuilder.setValue(ByteString.copyFrom(result.getValue())); - responseBuilder.setLog(result.getLogValue()); - } - - return responseBuilder.build(); - } - -### Handshake - -When the app or tendermint restarts, they need to sync to a common -height. When an ABCI connection is first established, Tendermint will -call `Info` on the Query connection. The response should contain the -LastBlockHeight and LastBlockAppHash - the former is the last block for -which the app ran Commit successfully, the latter is the response from -that Commit. - -Using this information, Tendermint will determine what needs to be -replayed, if anything, against the app, to ensure both Tendermint and -the app are synced to the latest block height. - -If the app returns a LastBlockHeight of 0, Tendermint will just replay -all blocks. - -In go: - - func (app *KVStoreApplication) Info(req types.RequestInfo) (resInfo types.ResponseInfo) { - return types.ResponseInfo{Data: cmn.Fmt("{\"size\":%v}", app.state.Size())} - } - -In Java: - - ResponseInfo requestInfo(RequestInfo req) { - final byte[] lastAppHash = getLastAppHash(); - final long lastHeight = getLastHeight(); - return ResponseInfo.newBuilder().setLastBlockAppHash(ByteString.copyFrom(lastAppHash)).setLastBlockHeight(lastHeight).build(); - } - -### Genesis - -`InitChain` will be called once upon the genesis. `params` includes the -initial validator set. Later on, it may be extended to take parts of the -consensus params. - -In go: - - // Save the validators in the merkle tree - func (app *PersistentKVStoreApplication) InitChain(params types.RequestInitChain) { - for _, v := range params.Validators { - r := app.updateValidator(v) - if r.IsErr() { - app.logger.Error("Error updating validators", "r", r) - } - } - } - -In Java: - - /* - * all types come from protobuf definition - */ - ResponseInitChain requestInitChain(RequestInitChain req) { - final int validatorsCount = req.getValidatorsCount(); - final List validatorsList = req.getValidatorsList(); - - validatorsList.forEach((validator) -> { - long power = validator.getPower(); - byte[] validatorPubKey = validator.getPubKey().toByteArray(); - - // do somehing for validator setup in app - }); - - return ResponseInitChain.newBuilder().build(); - } diff --git a/docs/architecture/README.md b/docs/architecture/README.md deleted file mode 100644 index 9e41d3064..000000000 --- a/docs/architecture/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Architecture Decision Records - -This is a location to record all high-level architecture decisions in the tendermint project. Not the implementation details, but the reasoning that happened. This should be refered to for guidance of the "right way" to extend the application. And if we notice that the original decisions were lacking, we should have another open discussion, record the new decisions here, and then modify the code to match. - -Read up on the concept in this [blog post](https://product.reverb.com/documenting-architecture-decisions-the-reverb-way-a3563bb24bd0#.78xhdix6t). diff --git a/docs/architecture/adr-001-logging.md b/docs/architecture/adr-001-logging.md deleted file mode 100644 index a11a49e14..000000000 --- a/docs/architecture/adr-001-logging.md +++ /dev/null @@ -1,216 +0,0 @@ -# ADR 1: Logging - -## Context - -Current logging system in Tendermint is very static and not flexible enough. - -Issues: [358](https://github.com/tendermint/tendermint/issues/358), [375](https://github.com/tendermint/tendermint/issues/375). - -What we want from the new system: - -- per package dynamic log levels -- dynamic logger setting (logger tied to the processing struct) -- conventions -- be more visually appealing - -"dynamic" here means the ability to set smth in runtime. - -## Decision - -### 1) An interface - -First, we will need an interface for all of our libraries (`tmlibs`, Tendermint, etc.). My personal preference is go-kit `Logger` interface (see Appendix A.), but that is too much a bigger change. Plus we will still need levels. - -```go -# log.go -type Logger interface { - Debug(msg string, keyvals ...interface{}) error - Info(msg string, keyvals ...interface{}) error - Error(msg string, keyvals ...interface{}) error - - With(keyvals ...interface{}) Logger -} -``` - -On a side note: difference between `Info` and `Notice` is subtle. We probably -could do without `Notice`. Don't think we need `Panic` or `Fatal` as a part of -the interface. These funcs could be implemented as helpers. In fact, we already -have some in `tmlibs/common`. - -- `Debug` - extended output for devs -- `Info` - all that is useful for a user -- `Error` - errors - -`Notice` should become `Info`, `Warn` either `Error` or `Debug` depending on the message, `Crit` -> `Error`. - -This interface should go into `tmlibs/log`. All libraries which are part of the core (tendermint/tendermint) should obey it. - -### 2) Logger with our current formatting - -On top of this interface, we will need to implement a stdout logger, which will be used when Tendermint is configured to output logs to STDOUT. - -Many people say that they like the current output, so let's stick with it. - -``` -NOTE[04-25|14:45:08] ABCI Replay Blocks module=consensus appHeight=0 storeHeight=0 stateHeight=0 -``` - -Couple of minor changes: - -``` -I[04-25|14:45:08.322] ABCI Replay Blocks module=consensus appHeight=0 storeHeight=0 stateHeight=0 -``` - -Notice the level is encoded using only one char plus milliseconds. - -Note: there are many other formats out there like [logfmt](https://brandur.org/logfmt). - -This logger could be implemented using any logger - [logrus](https://github.com/sirupsen/logrus), [go-kit/log](https://github.com/go-kit/kit/tree/master/log), [zap](https://github.com/uber-go/zap), log15 so far as it - -a) supports coloring output
-b) is moderately fast (buffering)
-c) conforms to the new interface or adapter could be written for it
-d) is somewhat configurable
- -go-kit is my favorite so far. Check out how easy it is to color errors in red https://github.com/go-kit/kit/blob/master/log/term/example_test.go#L12. Although, coloring could only be applied to the whole string :( - -``` -go-kit +: flexible, modular -go-kit “-”: logfmt format https://brandur.org/logfmt - -logrus +: popular, feature rich (hooks), API and output is more like what we want -logrus -: not so flexible -``` - -```go -# tm_logger.go -// NewTmLogger returns a logger that encodes keyvals to the Writer in -// tm format. -func NewTmLogger(w io.Writer) Logger { - return &tmLogger{kitlog.NewLogfmtLogger(w)} -} - -func (l tmLogger) SetLevel(level string() { - switch (level) { - case "debug": - l.sourceLogger = level.NewFilter(l.sourceLogger, level.AllowDebug()) - } -} - -func (l tmLogger) Info(msg string, keyvals ...interface{}) error { - l.sourceLogger.Log("msg", msg, keyvals...) -} - -# log.go -func With(logger Logger, keyvals ...interface{}) Logger { - kitlog.With(logger.sourceLogger, keyvals...) -} -``` - -Usage: - -```go -logger := log.NewTmLogger(os.Stdout) -logger.SetLevel(config.GetString("log_level")) -node.SetLogger(log.With(logger, "node", Name)) -``` - -**Other log formatters** - -In the future, we may want other formatters like JSONFormatter. - -``` -{ "level": "notice", "time": "2017-04-25 14:45:08.562471297 -0400 EDT", "module": "consensus", "msg": "ABCI Replay Blocks", "appHeight": 0, "storeHeight": 0, "stateHeight": 0 } -``` - -### 3) Dynamic logger setting - -https://dave.cheney.net/2017/01/23/the-package-level-logger-anti-pattern - -This is the hardest part and where the most work will be done. logger should be tied to the processing struct, or the context if it adds some fields to the logger. - -```go -type BaseService struct { - log log15.Logger - name string - started uint32 // atomic - stopped uint32 // atomic -... -} -``` - -BaseService already contains `log` field, so most of the structs embedding it should be fine. We should rename it to `logger`. - -The only thing missing is the ability to set logger: - -``` -func (bs *BaseService) SetLogger(l log.Logger) { - bs.logger = l -} -``` - -### 4) Conventions - -Important keyvals should go first. Example: - -``` -correct -I[04-25|14:45:08.322] ABCI Replay Blocks module=consensus instance=1 appHeight=0 storeHeight=0 stateHeight=0 -``` - -not - -``` -wrong -I[04-25|14:45:08.322] ABCI Replay Blocks module=consensus appHeight=0 storeHeight=0 stateHeight=0 instance=1 -``` - -for that in most cases you'll need to add `instance` field to a logger upon creating, not when u log a particular message: - -```go -colorFn := func(keyvals ...interface{}) term.FgBgColor { - for i := 1; i < len(keyvals); i += 2 { - if keyvals[i] == "instance" && keyvals[i+1] == "1" { - return term.FgBgColor{Fg: term.Blue} - } else if keyvals[i] == "instance" && keyvals[i+1] == "1" { - return term.FgBgColor{Fg: term.Red} - } - } - return term.FgBgColor{} - } -logger := term.NewLogger(os.Stdout, log.NewTmLogger, colorFn) - -c1 := NewConsensusReactor(...) -c1.SetLogger(log.With(logger, "instance", 1)) - -c2 := NewConsensusReactor(...) -c2.SetLogger(log.With(logger, "instance", 2)) -``` - -## Status - -proposed - -## Consequences - -### Positive - -Dynamic logger, which could be turned off for some modules at runtime. Public interface for other projects using Tendermint libraries. - -### Negative - -We may loose the ability to color keys in keyvalue pairs. go-kit allow you to easily change foreground / background colors of the whole string, but not its parts. - -### Neutral - -## Appendix A. - -I really like a minimalistic approach go-kit took with his logger https://github.com/go-kit/kit/tree/master/log: - -``` -type Logger interface { - Log(keyvals ...interface{}) error -} -``` - -See [The Hunt for a Logger Interface](https://go-talks.appspot.com/github.com/ChrisHines/talks/structured-logging/structured-logging.slide). The advantage is greater composability (check out how go-kit defines colored logging or log-leveled logging on top of this interface https://github.com/go-kit/kit/tree/master/log). diff --git a/docs/architecture/adr-002-event-subscription.md b/docs/architecture/adr-002-event-subscription.md deleted file mode 100644 index cc207c4af..000000000 --- a/docs/architecture/adr-002-event-subscription.md +++ /dev/null @@ -1,90 +0,0 @@ -# ADR 2: Event Subscription - -## Context - -In the light client (or any other client), the user may want to **subscribe to -a subset of transactions** (rather than all of them) using `/subscribe?event=X`. For -example, I want to subscribe for all transactions associated with a particular -account. Same for fetching. The user may want to **fetch transactions based on -some filter** (rather than fetching all the blocks). For example, I want to get -all transactions for a particular account in the last two weeks (`tx's block -time >= '2017-06-05'`). - -Now you can't even subscribe to "all txs" in Tendermint. - -The goal is a simple and easy to use API for doing that. - -![Tx Send Flow Diagram](img/tags1.png) - -## Decision - -ABCI app return tags with a `DeliverTx` response inside the `data` field (_for -now, later we may create a separate field_). Tags is a list of key-value pairs, -protobuf encoded. - -Example data: - -```json -{ - "abci.account.name": "Igor", - "abci.account.address": "0xdeadbeef", - "tx.gas": 7 -} -``` - -### Subscribing for transactions events - -If the user wants to receive only a subset of transactions, ABCI-app must -return a list of tags with a `DeliverTx` response. These tags will be parsed and -matched with the current queries (subscribers). If the query matches the tags, -subscriber will get the transaction event. - -``` -/subscribe?query="tm.event = Tx AND tx.hash = AB0023433CF0334223212243BDD AND abci.account.invoice.number = 22" -``` - -A new package must be developed to replace the current `events` package. It -will allow clients to subscribe to a different types of events in the future: - -``` -/subscribe?query="abci.account.invoice.number = 22" -/subscribe?query="abci.account.invoice.owner CONTAINS Igor" -``` - -### Fetching transactions - -This is a bit tricky because a) we want to support a number of indexers, all of -which have a different API b) we don't know whenever tags will be sufficient -for the most apps (I guess we'll see). - -``` -/txs/search?query="tx.hash = AB0023433CF0334223212243BDD AND abci.account.owner CONTAINS Igor" -/txs/search?query="abci.account.owner = Igor" -``` - -For historic queries we will need a indexing storage (Postgres, SQLite, ...). - -### Issues - -- https://github.com/tendermint/basecoin/issues/91 -- https://github.com/tendermint/tendermint/issues/376 -- https://github.com/tendermint/tendermint/issues/287 -- https://github.com/tendermint/tendermint/issues/525 (related) - -## Status - -proposed - -## Consequences - -### Positive - -- same format for event notifications and search APIs -- powerful enough query - -### Negative - -- performance of the `match` function (where we have too many queries / subscribers) -- there is an issue where there are too many txs in the DB - -### Neutral diff --git a/docs/architecture/adr-003-abci-app-rpc.md b/docs/architecture/adr-003-abci-app-rpc.md deleted file mode 100644 index 2775db077..000000000 --- a/docs/architecture/adr-003-abci-app-rpc.md +++ /dev/null @@ -1,34 +0,0 @@ -# ADR 3: Must an ABCI-app have an RPC server? - -## Context - -ABCI-server could expose its own RPC-server and act as a proxy to Tendermint. - -The idea was for the Tendermint RPC to just be a transparent proxy to the app. -Clients need to talk to Tendermint for proofs, unless we burden all app devs -with exposing Tendermint proof stuff. Also seems less complex to lock down one -server than two, but granted it makes querying a bit more kludgy since it needs -to be passed as a `Query`. Also, **having a very standard rpc interface means -the light-client can work with all apps and handle proofs**. The only -app-specific logic is decoding the binary data to a more readable form (eg. -json). This is a huge advantage for code-reuse and standardization. - -## Decision - -We dont expose an RPC server on any of our ABCI-apps. - -## Status - -accepted - -## Consequences - -### Positive - -- Unified interface for all apps - -### Negative - -- `Query` interface - -### Neutral diff --git a/docs/architecture/adr-004-historical-validators.md b/docs/architecture/adr-004-historical-validators.md deleted file mode 100644 index be0de22c1..000000000 --- a/docs/architecture/adr-004-historical-validators.md +++ /dev/null @@ -1,38 +0,0 @@ -# ADR 004: Historical Validators - -## Context - -Right now, we can query the present validator set, but there is no history. -If you were offline for a long time, there is no way to reconstruct past validators. This is needed for the light client and we agreed needs enhancement of the API. - -## Decision - -For every block, store a new structure that contains either the latest validator set, -or the height of the last block for which the validator set changed. Note this is not -the height of the block which returned the validator set change itself, but the next block, -ie. the first block it comes into effect for. - -Storing the validators will be handled by the `state` package. - -At some point in the future, we may consider more efficient storage in the case where the validators -are updated frequently - for instance by only saving the diffs, rather than the whole set. - -An alternative approach suggested keeping the validator set, or diffs of it, in a merkle IAVL tree. -While it might afford cheaper proofs that a validator set has not changed, it would be more complex, -and likely less efficient. - -## Status - -Accepted. - -## Consequences - -### Positive - -- Can query old validator sets, with proof. - -### Negative - -- Writes an extra structure to disk with every block. - -### Neutral diff --git a/docs/architecture/adr-005-consensus-params.md b/docs/architecture/adr-005-consensus-params.md deleted file mode 100644 index 6656d35b2..000000000 --- a/docs/architecture/adr-005-consensus-params.md +++ /dev/null @@ -1,86 +0,0 @@ -# ADR 005: Consensus Params - -## Context - -Consensus critical parameters controlling blockchain capacity have until now been hard coded, loaded from a local config, or neglected. -Since they may be need to be different in different networks, and potentially to evolve over time within -networks, we seek to initialize them in a genesis file, and expose them through the ABCI. - -While we have some specific parameters now, like maximum block and transaction size, we expect to have more in the future, -such as a period over which evidence is valid, or the frequency of checkpoints. - -## Decision - -### ConsensusParams - -No consensus critical parameters should ever be found in the `config.toml`. - -A new `ConsensusParams` is optionally included in the `genesis.json` file, -and loaded into the `State`. Any items not included are set to their default value. -A value of 0 is undefined (see ABCI, below). A value of -1 is used to indicate the parameter does not apply. -The parameters are used to determine the validity of a block (and tx) via the union of all relevant parameters. - -``` -type ConsensusParams struct { - BlockSize - TxSize - BlockGossip -} - -type BlockSize struct { - MaxBytes int - MaxTxs int - MaxGas int -} - -type TxSize struct { - MaxBytes int - MaxGas int -} - -type BlockGossip struct { - BlockPartSizeBytes int -} -``` - -The `ConsensusParams` can evolve over time by adding new structs that cover different aspects of the consensus rules. - -The `BlockPartSizeBytes` and the `BlockSize.MaxBytes` are enforced to be greater than 0. -The former because we need a part size, the latter so that we always have at least some sanity check over the size of blocks. - -### ABCI - -#### InitChain - -InitChain currently takes the initial validator set. It should be extended to also take parts of the ConsensusParams. -There is some case to be made for it to take the entire Genesis, except there may be things in the genesis, -like the BlockPartSize, that the app shouldn't really know about. - -#### EndBlock - -The EndBlock response includes a `ConsensusParams`, which includes BlockSize and TxSize, but not BlockGossip. -Other param struct can be added to `ConsensusParams` in the future. -The `0` value is used to denote no change. -Any other value will update that parameter in the `State.ConsensusParams`, to be applied for the next block. -Tendermint should have hard-coded upper limits as sanity checks. - -## Status - -Proposed. - -## Consequences - -### Positive - -- Alternative capacity limits and consensus parameters can be specified without re-compiling the software. -- They can also change over time under the control of the application - -### Negative - -- More exposed parameters is more complexity -- Different rules at different heights in the blockchain complicates fast sync - -### Neutral - -- The TxSize, which checks validity, may be in conflict with the config's `max_block_size_tx`, which determines proposal sizes - diff --git a/docs/architecture/adr-006-trust-metric.md b/docs/architecture/adr-006-trust-metric.md deleted file mode 100644 index ec8a0cce7..000000000 --- a/docs/architecture/adr-006-trust-metric.md +++ /dev/null @@ -1,238 +0,0 @@ -# ADR 006: Trust Metric Design - -## Context - -The proposed trust metric will allow Tendermint to maintain local trust rankings for peers it has directly interacted with, which can then be used to implement soft security controls. The calculations were obtained from the [TrustGuard](https://dl.acm.org/citation.cfm?id=1060808) project. - -### Background - -The Tendermint Core project developers would like to improve Tendermint security and reliability by keeping track of the level of trustworthiness peers have demonstrated within the peer-to-peer network. This way, undesirable outcomes from peers will not immediately result in them being dropped from the network (potentially causing drastic changes to take place). Instead, peers behavior can be monitored with appropriate metrics and be removed from the network once Tendermint Core is certain the peer is a threat. For example, when the PEXReactor makes a request for peers network addresses from a already known peer, and the returned network addresses are unreachable, this untrustworthy behavior should be tracked. Returning a few bad network addresses probably shouldn’t cause a peer to be dropped, while excessive amounts of this behavior does qualify the peer being dropped. - -Trust metrics can be circumvented by malicious nodes through the use of strategic oscillation techniques, which adapts the malicious node’s behavior pattern in order to maximize its goals. For instance, if the malicious node learns that the time interval of the Tendermint trust metric is *X* hours, then it could wait *X* hours in-between malicious activities. We could try to combat this issue by increasing the interval length, yet this will make the system less adaptive to recent events. - -Instead, having shorter intervals, but keeping a history of interval values, will give our metric the flexibility needed in order to keep the network stable, while also making it resilient against a strategic malicious node in the Tendermint peer-to-peer network. Also, the metric can access trust data over a rather long period of time while not greatly increasing its history size by aggregating older history values over a larger number of intervals, and at the same time, maintain great precision for the recent intervals. This approach is referred to as fading memories, and closely resembles the way human beings remember their experiences. The trade-off to using history data is that the interval values should be preserved in-between executions of the node. - -### References - -S. Mudhakar, L. Xiong, and L. Liu, “TrustGuard: Countering Vulnerabilities in Reputation Management for Decentralized Overlay Networks,” in *Proceedings of the 14th international conference on World Wide Web, pp. 422-431*, May 2005. - -## Decision - -The proposed trust metric will allow a developer to inform the trust metric store of all good and bad events relevant to a peer's behavior, and at any time, the metric can be queried for a peer's current trust ranking. - -The three subsections below will cover the process being considered for calculating the trust ranking, the concept of the trust metric store, and the interface for the trust metric. - -### Proposed Process - -The proposed trust metric will count good and bad events relevant to the object, and calculate the percent of counters that are good over an interval with a predefined duration. This is the procedure that will continue for the life of the trust metric. When the trust metric is queried for the current **trust value**, a resilient equation will be utilized to perform the calculation. - -The equation being proposed resembles a Proportional-Integral-Derivative (PID) controller used in control systems. The proportional component allows us to be sensitive to the value of the most recent interval, while the integral component allows us to incorporate trust values stored in the history data, and the derivative component allows us to give weight to sudden changes in the behavior of a peer. We compute the trust value of a peer in interval i based on its current trust ranking, its trust rating history prior to interval *i* (over the past *maxH* number of intervals) and its trust ranking fluctuation. We will break up the equation into the three components. - -```math -(1) Proportional Value = a * R[i] -``` - -where *R*[*i*] denotes the raw trust value at time interval *i* (where *i* == 0 being current time) and *a* is the weight applied to the contribution of the current reports. The next component of our equation uses a weighted sum over the last *maxH* intervals to calculate the history value for time *i*: - - -`H[i] = ` ![formula1](img/formula1.png "Weighted Sum Formula") - - -The weights can be chosen either optimistically or pessimistically. An optimistic weight creates larger weights for newer history data values, while the the pessimistic weight creates larger weights for time intervals with lower scores. The default weights used during the calculation of the history value are optimistic and calculated as *Wk* = 0.8^*k*, for time interval *k*. With the history value available, we can now finish calculating the integral value: - -```math -(2) Integral Value = b * H[i] -``` - -Where *H*[*i*] denotes the history value at time interval *i* and *b* is the weight applied to the contribution of past performance for the object being measured. The derivative component will be calculated as follows: - -```math -D[i] = R[i] – H[i] - -(3) Derivative Value = c(D[i]) * D[i] -``` - -Where the value of *c* is selected based on the *D*[*i*] value relative to zero. The default selection process makes *c* equal to 0 unless *D*[*i*] is a negative value, in which case c is equal to 1. The result is that the maximum penalty is applied when current behavior is lower than previously experienced behavior. If the current behavior is better than the previously experienced behavior, then the Derivative Value has no impact on the trust value. With the three components brought together, our trust value equation is calculated as follows: - -```math -TrustValue[i] = a * R[i] + b * H[i] + c(D[i]) * D[i] -``` - -As a performance optimization that will keep the amount of raw interval data being saved to a reasonable size of *m*, while allowing us to represent 2^*m* - 1 history intervals, we can employ the fading memories technique that will trade space and time complexity for the precision of the history data values by summarizing larger quantities of less recent values. While our equation above attempts to access up to *maxH* (which can be 2^*m* - 1), we will map those requests down to *m* values using equation 4 below: - -```math -(4) j = index, where index > 0 -``` - -Where *j* is one of *(0, 1, 2, … , m – 1)* indices used to access history interval data. Now we can access the raw intervals using the following calculations: - -```math -R[0] = raw data for current time interval -``` - -`R[j] = ` ![formula2](img/formula2.png "Fading Memories Formula") - -### Trust Metric Store - -Similar to the P2P subsystem AddrBook, the trust metric store will maintain information relevant to Tendermint peers. Additionally, the trust metric store will ensure that trust metrics will only be active for peers that a node is currently and directly engaged with. - -Reactors will provide a peer key to the trust metric store in order to retrieve the associated trust metric. The trust metric can then record new positive and negative events experienced by the reactor, as well as provided the current trust score calculated by the metric. - -When the node is shutting down, the trust metric store will save history data for trust metrics associated with all known peers. This saved information allows experiences with a peer to be preserved across node executions, which can span a tracking windows of days or weeks. The trust history data is loaded automatically during OnStart. - -### Interface Detailed Design - -Each trust metric allows for the recording of positive/negative events, querying the current trust value/score, and the stopping/pausing of tracking over time intervals. This can be seen below: - - -```go - -// TrustMetric - keeps track of peer reliability -type TrustMetric struct { - // Private elements. -} - -// Pause tells the metric to pause recording data over time intervals. -// All method calls that indicate events will unpause the metric -func (tm *TrustMetric) Pause() {} - -// Stop tells the metric to stop recording data over time intervals -func (tm *TrustMetric) Stop() {} - -// BadEvents indicates that an undesirable event(s) took place -func (tm *TrustMetric) BadEvents(num int) {} - -// GoodEvents indicates that a desirable event(s) took place -func (tm *TrustMetric) GoodEvents(num int) {} - -// TrustValue gets the dependable trust value; always between 0 and 1 -func (tm *TrustMetric) TrustValue() float64 {} - -// TrustScore gets a score based on the trust value always between 0 and 100 -func (tm *TrustMetric) TrustScore() int {} - -// NewMetric returns a trust metric with the default configuration -func NewMetric() *TrustMetric {} - -//------------------------------------------------------------------------------------------------ -// For example - -tm := NewMetric() - -tm.BadEvents(1) -score := tm.TrustScore() - -tm.Stop() - -``` - -Some of the trust metric parameters can be configured. The weight values should probably be left alone in more cases, yet the time durations for the tracking window and individual time interval should be considered. - -```go - -// TrustMetricConfig - Configures the weight functions and time intervals for the metric -type TrustMetricConfig struct { - // Determines the percentage given to current behavior - ProportionalWeight float64 - - // Determines the percentage given to prior behavior - IntegralWeight float64 - - // The window of time that the trust metric will track events across. - // This can be set to cover many days without issue - TrackingWindow time.Duration - - // Each interval should be short for adapability. - // Less than 30 seconds is too sensitive, - // and greater than 5 minutes will make the metric numb - IntervalLength time.Duration -} - -// DefaultConfig returns a config with values that have been tested and produce desirable results -func DefaultConfig() TrustMetricConfig {} - -// NewMetricWithConfig returns a trust metric with a custom configuration -func NewMetricWithConfig(tmc TrustMetricConfig) *TrustMetric {} - -//------------------------------------------------------------------------------------------------ -// For example - -config := TrustMetricConfig{ - TrackingWindow: time.Minute * 60 * 24, // one day - IntervalLength: time.Minute * 2, -} - -tm := NewMetricWithConfig(config) - -tm.BadEvents(10) -tm.Pause() -tm.GoodEvents(1) // becomes active again - -``` - -A trust metric store should be created with a DB that has persistent storage so it can save history data across node executions. All trust metrics instantiated by the store will be created with the provided TrustMetricConfig configuration. - -When you attempt to fetch the trust metric for a peer, and an entry does not exist in the trust metric store, a new metric is automatically created and the entry made within the store. - -In additional to the fetching method, GetPeerTrustMetric, the trust metric store provides a method to call when a peer has disconnected from the node. This is so the metric can be paused (history data will not be saved) for periods of time when the node is not having direct experiences with the peer. - -```go - -// TrustMetricStore - Manages all trust metrics for peers -type TrustMetricStore struct { - cmn.BaseService - - // Private elements -} - -// OnStart implements Service -func (tms *TrustMetricStore) OnStart() error {} - -// OnStop implements Service -func (tms *TrustMetricStore) OnStop() {} - -// NewTrustMetricStore returns a store that saves data to the DB -// and uses the config when creating new trust metrics -func NewTrustMetricStore(db dbm.DB, tmc TrustMetricConfig) *TrustMetricStore {} - -// Size returns the number of entries in the trust metric store -func (tms *TrustMetricStore) Size() int {} - -// GetPeerTrustMetric returns a trust metric by peer key -func (tms *TrustMetricStore) GetPeerTrustMetric(key string) *TrustMetric {} - -// PeerDisconnected pauses the trust metric associated with the peer identified by the key -func (tms *TrustMetricStore) PeerDisconnected(key string) {} - -//------------------------------------------------------------------------------------------------ -// For example - -db := dbm.NewDB("trusthistory", "goleveldb", dirPathStr) -tms := NewTrustMetricStore(db, DefaultConfig()) - -tm := tms.GetPeerTrustMetric(key) -tm.BadEvents(1) - -tms.PeerDisconnected(key) - -``` - -## Status - -Approved. - -## Consequences - -### Positive - -- The trust metric will allow Tendermint to make non-binary security and reliability decisions -- Will help Tendermint implement deterrents that provide soft security controls, yet avoids disruption on the network -- Will provide useful profiling information when analyzing performance over time related to peer interaction - -### Negative - -- Requires saving the trust metric history data across node executions - -### Neutral - -- Keep in mind that, good events need to be recorded just as bad events do using this implementation diff --git a/docs/architecture/adr-007-trust-metric-usage.md b/docs/architecture/adr-007-trust-metric-usage.md deleted file mode 100644 index 4d833a69f..000000000 --- a/docs/architecture/adr-007-trust-metric-usage.md +++ /dev/null @@ -1,103 +0,0 @@ -# ADR 007: Trust Metric Usage Guide - -## Context - -Tendermint is required to monitor peer quality in order to inform its peer dialing and peer exchange strategies. - -When a node first connects to the network, it is important that it can quickly find good peers. -Thus, while a node has fewer connections, it should prioritize connecting to higher quality peers. -As the node becomes well connected to the rest of the network, it can dial lesser known or lesser -quality peers and help assess their quality. Similarly, when queried for peers, a node should make -sure they dont return low quality peers. - -Peer quality can be tracked using a trust metric that flags certain behaviours as good or bad. When enough -bad behaviour accumulates, we can mark the peer as bad and disconnect. -For example, when the PEXReactor makes a request for peers network addresses from an already known peer, and the returned network addresses are unreachable, this undesirable behavior should be tracked. Returning a few bad network addresses probably shouldn’t cause a peer to be dropped, while excessive amounts of this behavior does qualify the peer for removal. The originally proposed approach and design document for the trust metric can be found in the [ADR 006](adr-006-trust-metric.md) document. - -The trust metric implementation allows a developer to obtain a peer's trust metric from a trust metric store, and track good and bad events relevant to a peer's behavior, and at any time, the peer's metric can be queried for a current trust value. The current trust value is calculated with a formula that utilizes current behavior, previous behavior, and change between the two. Current behavior is calculated as the percentage of good behavior within a time interval. The time interval is short; probably set between 30 seconds and 5 minutes. On the other hand, the historic data can estimate a peer's behavior over days worth of tracking. At the end of a time interval, the current behavior becomes part of the historic data, and a new time interval begins with the good and bad counters reset to zero. - -These are some important things to keep in mind regarding how the trust metrics handle time intervals and scoring: -- Each new time interval begins with a perfect score -- Bad events quickly bring the score down and good events cause the score to slowly rise -- When the time interval is over, the percentage of good events becomes historic data. - -Some useful information about the inner workings of the trust metric: -- When a trust metric is first instantiated, a timer (ticker) periodically fires in order to handle transitions between trust metric time intervals -- If a peer is disconnected from a node, the timer should be paused, since the node is no longer connected to that peer -- The ability to pause the metric is supported with the store **PeerDisconnected** method and the metric **Pause** method -- After a pause, if a good or bad event method is called on a metric, it automatically becomes unpaused and begins a new time interval. - -## Decision - -The trust metric capability is now available, yet, it still leaves the question of how should it be applied throughout Tendermint in order to properly track the quality of peers? - -### Proposed Process - -Peers are managed using an address book and a trust metric: - -- The address book keeps a record of peers and provides selection methods -- The trust metric tracks the quality of the peers - -#### Presence in Address Book - -Outbound peers are added to the address book before they are dialed, -and inbound peers are added once the peer connection is set up. -Peers are also added to the address book when they are received in response to -a pexRequestMessage. - -While a node has less than `needAddressThreshold`, it will periodically request more, -via pexRequestMessage, from randomly selected peers and from newly dialed outbound peers. - -When a new address is added to an address book that has more than `0.5*needAddressThreshold` addresses, -then with some low probability, a randomly chosen low quality peer is removed. - -#### Outbound Peers - -Peers attempt to maintain a minimum number of outbound connections by -repeatedly querying the address book for peers to connect to. -While a node has few to no outbound connections, the address book is biased to return -higher quality peers. As the node increases the number of outbound connections, -the address book is biased to return less-vetted or lower-quality peers. - -#### Inbound Peers - -Peers also maintain a maximum number of total connections, MaxNumPeers. -If a peer has MaxNumPeers, new incoming connections will be accepted with low probability. -When such a new connection is accepted, the peer disconnects from a probabilistically chosen low ranking peer -so it does not exceed MaxNumPeers. - -#### Peer Exchange - -When a peer receives a pexRequestMessage, it returns a random sample of high quality peers from the address book. Peers with no score or low score should not be inclided in a response to pexRequestMessage. - -#### Peer Quality - -Peer quality is tracked in the connection and across the reactors by storing the TrustMetric in the peer's -thread safe Data store. - -Peer behaviour is then defined as one of the following: -- Fatal - something outright malicious that causes us to disconnect the peer and ban it from the address book for some amount of time -- Bad - Any kind of timeout, messages that don't unmarshal, fail other validity checks, or messages we didn't ask for or aren't expecting (usually worth one bad event) -- Neutral - Unknown channels/message types/version upgrades (no good or bad events recorded) -- Correct - Normal correct behavior (worth one good event) -- Good - some random majority of peers per reactor sending us useful messages (worth more than one good event). - -Note that Fatal behaviour causes us to remove the peer, and neutral behaviour does not affect the score. - -## Status - -Proposed. - -## Consequences - -### Positive - -- Bringing the address book and trust metric store together will cause the network to be built in a way that encourages greater security and reliability. - -### Negative - -- TBD - -### Neutral - -- Keep in mind that, good events need to be recorded just as bad events do using this implementation. diff --git a/docs/architecture/adr-008-priv-validator.md b/docs/architecture/adr-008-priv-validator.md deleted file mode 100644 index 4c1d87bed..000000000 --- a/docs/architecture/adr-008-priv-validator.md +++ /dev/null @@ -1,29 +0,0 @@ -# ADR 008: SocketPV - -Tendermint node's should support only two in-process PrivValidator -implementations: - -- FilePV uses an unencrypted private key in a "priv_validator.json" file - no - configuration required (just `tendermint init`). -- SocketPV uses a socket to send signing requests to another process - user is - responsible for starting that process themselves. - -The SocketPV address can be provided via flags at the command line - doing so -will cause Tendermint to ignore any "priv_validator.json" file and to listen on -the given address for incoming connections from an external priv_validator -process. It will halt any operation until at least one external process -succesfully connected. - -The external priv_validator process will dial the address to connect to -Tendermint, and then Tendermint will send requests on the ensuing connection to -sign votes and proposals. Thus the external process initiates the connection, -but the Tendermint process makes all requests. In a later stage we're going to -support multiple validators for fault tolerance. To prevent double signing they -need to be synced, which is deferred to an external solution (see #1185). - -In addition, Tendermint will provide implementations that can be run in that -external process. These include: - -- FilePV will encrypt the private key, and the user must enter password to - decrypt key when process is started. -- LedgerPV uses a Ledger Nano S to handle all signing. diff --git a/docs/architecture/adr-011-monitoring.md b/docs/architecture/adr-011-monitoring.md deleted file mode 100644 index ca16a9a1c..000000000 --- a/docs/architecture/adr-011-monitoring.md +++ /dev/null @@ -1,116 +0,0 @@ -# ADR 011: Monitoring - -## Changelog - -08-06-2018: Initial draft -11-06-2018: Reorg after @xla comments -13-06-2018: Clarification about usage of labels - -## Context - -In order to bring more visibility into Tendermint, we would like it to report -metrics and, maybe later, traces of transactions and RPC queries. See -https://github.com/tendermint/tendermint/issues/986. - -A few solutions were considered: - -1. [Prometheus](https://prometheus.io) - a) Prometheus API - b) [go-kit metrics package](https://github.com/go-kit/kit/tree/master/metrics) as an interface plus Prometheus - c) [telegraf](https://github.com/influxdata/telegraf) - d) new service, which will listen to events emitted by pubsub and report metrics -5. [OpenCensus](https://opencensus.io/go/index.html) - -### 1. Prometheus - -Prometheus seems to be the most popular product out there for monitoring. It has -a Go client library, powerful queries, alerts. - -**a) Prometheus API** - -We can commit to using Prometheus in Tendermint, but I think Tendermint users -should be free to choose whatever monitoring tool they feel will better suit -their needs (if they don't have existing one already). So we should try to -abstract interface enough so people can switch between Prometheus and other -similar tools. - -**b) go-kit metrics package as an interface** - -metrics package provides a set of uniform interfaces for service -instrumentation and offers adapters to popular metrics packages: - -https://godoc.org/github.com/go-kit/kit/metrics#pkg-subdirectories - -Comparing to Prometheus API, we're losing customisability and control, but gaining -freedom in choosing any instrument from the above list given we will extract -metrics creation into a separate function (see "providers" in node/node.go). - -**c) telegraf** - -Unlike already discussed options, telegraf does not require modifying Tendermint -source code. You create something called an input plugin, which polls -Tendermint RPC every second and calculates the metrics itself. - -While it may sound good, but some metrics we want to report are not exposed via -RPC or pubsub, therefore can't be accessed externally. - -**d) service, listening to pubsub** - -Same issue as the above. - -### 2. opencensus - -opencensus provides both metrics and tracing, which may be important in the -future. It's API looks different from go-kit and Prometheus, but looks like it -covers everything we need. - -Unfortunately, OpenCensus go client does not define any -interfaces, so if we want to abstract away metrics we -will need to write interfaces ourselves. - -### List of metrics - -| | Name | Type | Description | -| - | --------------------------------------- | ------- | ----------------------------------------------------------------------------- | -| A | consensus_height | Gauge | | -| A | consensus_validators | Gauge | Number of validators who signed | -| A | consensus_validators_power | Gauge | Total voting power of all validators | -| A | consensus_missing_validators | Gauge | Number of validators who did not sign | -| A | consensus_missing_validators_power | Gauge | Total voting power of the missing validators | -| A | consensus_byzantine_validators | Gauge | Number of validators who tried to double sign | -| A | consensus_byzantine_validators_power | Gauge | Total voting power of the byzantine validators | -| A | consensus_block_interval | Timing | Time between this and last block (Block.Header.Time) | -| | consensus_block_time | Timing | Time to create a block (from creating a proposal to commit) | -| | consensus_time_between_blocks | Timing | Time between committing last block and (receiving proposal creating proposal) | -| A | consensus_rounds | Gauge | Number of rounds | -| | consensus_prevotes | Gauge | | -| | consensus_precommits | Gauge | | -| | consensus_prevotes_total_power | Gauge | | -| | consensus_precommits_total_power | Gauge | | -| A | consensus_num_txs | Gauge | | -| A | mempool_size | Gauge | | -| A | consensus_total_txs | Gauge | | -| A | consensus_block_size | Gauge | In bytes | -| A | p2p_peers | Gauge | Number of peers node's connected to | - -`A` - will be implemented in the fist place. - -**Proposed solution** - -## Status - -Proposed. - -## Consequences - -### Positive - -Better visibility, support of variety of monitoring backends - -### Negative - -One more library to audit, messing metrics reporting code with business domain. - -### Neutral - -- diff --git a/docs/architecture/adr-template.md b/docs/architecture/adr-template.md deleted file mode 100644 index 2303490ad..000000000 --- a/docs/architecture/adr-template.md +++ /dev/null @@ -1,16 +0,0 @@ -# ADR 000: Template for an ADR - -## Context - -## Decision - -## Status - - -## Consequences - -### Positive - -### Negative - -### Neutral diff --git a/docs/architecture/img/formula1.png b/docs/architecture/img/formula1.png deleted file mode 100644 index 447ee30f5734f1b562a26664f16025cd69265b97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9833 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 pKwu+9vx2t#M;`x6DG$FvU4vE19d12Dwb)i}B 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 TrGQ6-8x16{CRZh6@!@{}Sksjb diff --git a/docs/architecture/img/tags1.png b/docs/architecture/img/tags1.png deleted file mode 100644 index a6bc64e81568566d13c87996f2e86a41bcaa055a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10446 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 diff --git a/docs/assets/a_plus_t.png b/docs/assets/a_plus_t.png deleted file mode 100644 index 8f5bc5e950cb4ee31a0983f004f780aeb398c6ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13830 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�&D^D;U> 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 diff --git a/docs/assets/consensus_logic.png b/docs/assets/consensus_logic.png deleted file mode 100644 index 22b70b265711b04c5555b1a1ce982d32bc8aeaec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105454 zcmbTcWm{ZL6D~S<2p&RkNw5$!!QCOaySooMxO*VDI|LGJaCe8`K7+di28Y3A^StNm zKd}4Dx>j|`T~*z+r0a*WqBPc9lD7Z=088e(gem}l1_1z2eBU6wQgm8Et6wk3R-y`` z06pg<2sIczk$#d3n~+(XsidusXgrTG(x(r~UN&yf(i1^7QgMUWSl}Xu6;m zeswib(DQQt{Pgl7At4SsJnZl9Uz}PF3JO{rTU#7o4ko8zVPW38x}VDHl)}M(dAx5~ zzpSGF`gHvm+hNTk$FMrF?LY8ueRfMno_=;_rVu35(9n=O>k0${?{06ClM-=JP(D+U zHYOBwUF0A*NwtwMl6i}SY@4>;xphZU?&24{Kn4u>7u)VbV zvbDxS|A`165R&h&AIxYA>S-u13@@7-8*02K;%8^&CMP~WIG-#Z zAfx+GC9Xlr#IGzZx^i|0?AT-ErEHwr1DfclE6HVkVr&=F%$YqQqM{QO;HfUoe<@6T z0T;Z*B^=0Y9^8dbH;x)KZU^~*(p+Wz{^+F)IrJ|68{$=x;-xs*JZ7PPuj(MM*gku9 zdOB3mefaOx)yjCYu_V}$x3#KtePC&CckiIRvV8F@$49-DM|@00*3ZRuqqAP{GmSJ2 zp@E-7zO*_e{yY8;*c}D+v6P>$pc5>@N|Gk-hhtU&O&dzwU;Cs)oPQ0@YN^DI!5kRb zUSR)p7-^FPr2ES?ZFQ7giK!y36rJ?hEak+*YfaCmhJFi5kB^N0re%Tl&&GxN7iXvX z=t@|KeQn59CP7D&GGKSjRA-=MQuRveh}BCD6zytnuM1c5ET5TgtKsIfhyz*%v+;IL zFZ+v#%rqH9M8%fGgeI!Un8#I5Z5(E1W{L8;RvQ^KXJ_qAuM;G+uMKsLmlss@Operp z8;rkmtC;o~Yn=>s6j&N(__~x=2 zT}MM2PFJD(@$6Ejm~%O+^t!wLpNBGX7Aa{~E($>VxrkEZS~j6$B%vOuTXp%3g3^(L zrx3u{E8>v;H@za}0)nxO-+lVtw`FWBR3Lv%iQ19a|PL4~_CGLs+0Uv9>g;pYUm#G`P&L5D) zlzT(q)RTAsrij(}lZT7ClRiQZK{-J6l?D_9(9S7?y=sphmt8rMDt-)Br1qB|Ks*P; zpO!^fY>;+bM0*#&C_%4AI}cm20p)5S1GK>Q2Y=$*b0%CIK)EVB@_)8gJ;?zsFgEok zldV@Q0dEY1uT~I5I*)!Dq52Dub^-o>IH0mh7$Ba%_~S&}F0nxP%hjCg8^GP!;T{WX z&G{(*;(`u;X(+)%n)+{-+Qz!gFyz0k^Pnekdx~6tri!Sz;)oCQ$lChf#O6uawFD2n zwZFSV*AE94gvydN6?UzcF)*s*%aqzN+flXxLUWR4Z21{K2O!W^v~;DygLM|OrTfnMYP zgHCAAPhMtJ<^G!PS@ClMwS9n#7RVp~e|Yfbca;`Q(h1JV+voo;4DGMpYjCh=&^BNm zFiB@E4=Rccg{AX7jmg#%rK>UbXb$y&Z^ljKfNtO8W>(g~7^A%eCLHxv9oE#W#QC29 z7afp6Ue_Uf6#lCP4C51FDX)aNYCYL@cviZR8xOjNjuw;TT=cs2BAycj{IV*$hknu& zauz zx6enTW5vHZVkngBW~=ycnQwiI-gL5_H&E-C$(GoYv}=r6KCKNO?zv4ky9aR5eRXQD zp(W*N1EPmYRjdJp|FCz=VB!Ae037|D0AQ6#4GLiDYLmw3@A?AX^P&1z8d7~#-GtI@ zr_sgw0^st`_$MN(G4W6qdj{BPIBb2+9KXeV)cQ*Ku1dDff=i$~9T-~1?XNsvSQ!y! z?(vl2zsa5^ezr~?ej|#zaaYzg`|a#iiHvsSp43QQbIoTg5#VcVSbyw~&W{IEW?&g{ z+hJ2Rz2Z9O+M?f6{VT0Ms5Bbhgw`FYWTG*1NvRJnftdu|3Jz)Hk%F^WZyv$CeW1YU z*LB?@NB_-bJsfz-q0Mas9Qz-gxZE(7a>2{{KQg;^)sI_t+i)15PD{}I=~u^JFliMj zn6wgU3|MBdAx-&kt@=I7-e8O4iN@slu=l;FEXV} z44HSVLf|Nogz5bFXJ03nIMJq>xOSz$DiEJOpLVR;H6Z6U<9gO={B?vSdyWp&hAXS% zc^txFV03xk-)nn@3S-5BR$$^xQKBg}w8$mHUAW6Ud}v_DiiOEC}$bDki3YDzQuUT!Z+Hj zg!!E#20||cA)xke1x@JPOr$m85+108RaQD(e>aO( z0CM#=v<01Roct~fHOdg4!Q~bkkr@GO}70c~k?S1Mfvsz5pYg>&R!7!FC6Mzw!@ z*IzZ8sc2A;Mvh+QHuryiaS<5htr>`PXOg6MXllPi`Gk z0X1<)t6bAUz}Q|SNv`p4XOotKZJr&;1P?zfzgeG#n)tB_t>&)SD?Ds7;hqw;7oGty z%DshQivutjh!3@nBMtse>-kQrREdAHPNoSy^p}U|I=|mQY&z{U;U4kl&S0a= z(+|kLxZon~LZ+-h6W(k+Q>;WP6Vih84ZsebAjTQD?)#lN<7F_eB&5^xVR(cMtK%#@ zZ$=Hq;+XaC9XCA`K_ibIwz&mA@(=LKEJ(2+{cY*K@zg$NFYo7-RmtCQvcuOMZK;jw zZx7iPKV5tR`Zfxcc@-~v)_Ul*hS@bQ=J+99_p;!2?akfy(?gH9F-q=zbx!|V?N}_1 zc34f#+zT5OS`fI6hJJ(4c?yi6Ydx@RG6l{i#hN0`rSI5)mey?|x4b&2st)&+q?kZZ{-e0*}-TI$)E+4KnEdYI%j0JF5A7ba3lKsIbs?@L!GxPn}z=uARU#n0M~LL;DKLpOE<;^T@iT z)tR9u2#_`UqUz~yRW6$HYYj9K!0T*10}lby1dcS+HutaW^iQ9J{jvSgpP$db>#tAn z{r!&*;sOQL#(CG4hNwc)i6~n)QFS7|7S48KlH_2hZNu`vJnu&^B&`jW_NP}#=xS|U z>D!}K;vP;ke!v6MZLY89Y?)()*u0kOcG_fspZ`}F8pfzMGyk~1M`Lry(<*^ z^F>JD>iJk4yC~yj)WlC2K7V}w9D!prnBo^CH-v2=Xz<&iv?%~ zI#3dTLYsWXy)stObO5zF3)vpLQjkX8TIr`n`mCx#UGC7Q6_#**;AcxSkkU-kwpNv6b?s z1x;pY=uthdzZ^e0$}cvpGsA`sR@y&L&5s@x8$#;PK@Buh(^_2ye_qORH6NR=1Fk3b zITM(px6vK;M5+FK5EV0?i8B=V82m}#Q@eqCuspLWtysDO@(TccFeMmIdMc${2a~1G zJ~{YPGfB0V9w|2q+6qTqV$;FEl}Kw=DP_~)T5Z{!cIuj5E^FM4e2S)_Ja|%Y-+z*K zFlpw^lJjL`0>GN^$z!intIPQAwA)n2N5@>}G84w zz+um?)*g6wKP)1uvm>dCKi=SJp0+U-{;9WhFGa~Ir`D!KZQ{#Ik#u3b*XQ3tOzu46 z9yeeEIX`uOf0iuH8}VbYR?ey;LMXodqe6BeGb)nwJZ-eXfj9=fZiBhQ* zQ$!R`f36_(6Y-t2+WJ`V;-3&;TqxbBPe=)+*6Qh zRhmf~`t8DKmy&O>%8zVR)>KgFn{{qC0mz0-rx14&zy3NwBY-9C z;m?zT_5mGvUDrf~*&j*l(Kipeg(gN)MBJBg5y1P$hJ8kej9`|bN9X~U&bPd&I#hI1 zJN*cFaP$N3!*ObO;60oo)$~Bl~(Lv;f zZ>m#fHK&3CMOkAP?O~Furt=(Husof&T2pz_;D`d-RUy0N5BeyWSEIDB1(dsr+43o5 zsRSo=I2Z`uM!*ALrwdkUM%A5W4nkL!(AvS|iC0kf%}B=Ld~ z_Wd7Fi3~$YDrdOZO{Mrh|Gc9;69p7RaMdrvD(Stm;t}Yav7fy;Z`yH%M-t=bE_|@G zOTZB(3|(57cRvt5@kLt+ukE}vRdcyAcka>M8Qf?jJlQ0UbKmx>>*@J?+efl`eLV12 zOjMt(ATeW)BQ~2{>tsr*12Qa8;5<8Y-BxgRoD}SS-5@p4`LkKDc{^>@ zjGga@>NWWs1U04qK`3J$AF@vyWlGn#@8X0}z~{m`a1?$w zBukOVkS{V?ZUF>=+vMD}b+1+-0LSXFnn#~ui++NQi>d%1F^t?kirQ{Eii=+0?Kp3T z?`n38EhBB59jpHuDui=XpT^2I{;LMAf?x;187IM6$O`$2+~@fW@r^ZKn?Omt_u5{} zPRqCu2h3Bi-d4kn5B5crkZ(eS&9omVXh+7Eo6*R1nsR5T-KhUi+Ds`8wD1Hy7c90& z1?a3;fvZXwQ6AcReKwi%1Kyzk1R8>Tgt(fv{quhISn_|4zgUVLWCceEnB=UwbKn{N z)!jUd8m=p+i|dUOJi_s{poWnD>&SX z;0)>el-l3x5q(7=bQS*3ffow`?g$WCua(oTky|;}Hhtd9GRrq~wM-^prNO$I>joEp zlDC3??-vDaDSQSnXvk_!=?Hlv`Hs;sbiX%u?A0hrN52i3Uo0z)-3*(>JR#p!9{t zxDW|Noc5qrp+#tUvdO8Y&0kyRj@2TXZYjtg|WlarspUT~6I=&RN{D6Cxu*l80 zS=zt(30>ENmOit~bp`R83U|;%k$;8tKH1Y?w6AJE!lS3v+)(+j@Pbp~@JB{!9?5yLZj)gik%4(xZgr&< z`h-r@yw_1r8Nm^M%{1%vQQJq#nodiJu_uYrM*Z^=yk}rMUUtY$W_(b+068C{j=fu) zh`Tb|mA_wQ#F5xXR{{e?u`{V6&55~bJIXiUn~Kq3P)%&fb8be{b6LDWzgrj%9R$TE zo-h-3hN$hKX6q4y`H5F(+d6MDDx-&B#n1Z9lG&?DTqi$th>wKki)g^l?+V!&@3iwa z!d)-!wXI?fc@a*FarAR9wG8?5oDsVjc*zN>JFS&W_8aiDT7H_D8Zw<3rxsILPijTx zTn`ax{}VZKeM;kOISGch+5~dr#XMgIjvmkcn_?z!!F1mluX)bKM1=fKpB^Tpg$!*u~o|upXkab@D=uZh;(k|*xmc)OBB7d4RCx= zwO>=K4X(M;UV#Rd^=b3TPY`F?8YRBVz`duLw$+bAx;e=;CNU#v+fDC`U-H~T0}KP+ z8H1XrWd_f&lM7=PrU+oSx%elF!$nah*Qby{_(6E$nc9927}Vax;_wcp7IR3co!^QM z>ajC+7t;wN?ND9+?ES)3c|>}`iIDA9A5Y%6D2fR~T0D9!zvb6Lmka2^bbDaOw=nOt zRvgUsVO}#ejb=WcYwsG@R`A)JEN5??+LINYP%NfBuNU68i#8e`O#XiqmuLQg*WoZ0 z?NdA!9!7}Otvsb!#~~hUO!-N>TX{WD@%)N?3enHh;#vvlAG}`hM&;qeExLT|#B3uE z=@=bqP|dQvJtN*A+*6dBDS4QLJLnzRoLeN^!h#ZiD9~yZO}fPIx4&%-p(^bg%U}D> z<2yi@yZ7z_$y%m~F~x8!z60@cQB?l00&8p4yZ46a$(Z&h2tCGC^aD2<*e*$Dor5_w zh3ib}*FpEVemdWv$oN~5d+<4@XOl2%gG?KT4V%eosnBs?8R%PrxzMzk@18Ehs-j}3$ zmJo_ihW9x}B2vPz(D#OTHCzIb)o6D9L+(=e88qlNokF@-;G3iU&N% zCJPLDe1j;vqWQ(K?ajmxCs|D*ImsAMxXz||pQ1+q?U$-~h=f4JU+Kz8+`00qo?<@P z?&xQQonWTN=beojCi5x+~8E|yvhMJV;_Wg=bKp`;v>?Ao(vuL&PR0n zvZfeT)upj-f5xqEk+h#N-fmPO-3((2;UDJ$tAgQFtm2KcjV(Hx! zaiX?5D9P6cLCMc_jOvOAH^Pj1&;szraM)zrgCaEcZUXH-kYyy~H)t z+!L9s`$lib3t~}{>pzUHBFe`*nRwx`&9j$9{;c`t1m;+nswqozd`j3?F}B1hF+zK% zHypBsIUcAXgf&?Rr(}PTLPvKhYpccI(3A^wGj(*bh1%~U(6t@yqwL|;W>hMr6xlY- zY07C-T&~jqOS@zb@8@|zLfLk|RmW-7V<^>69lP;yzKK|*uhfAi3i~B0m#0>CgC)OV zeI59N%h5z<%#za`r@Ls`6=HDx5p?!J;5@&^QEV~l-ya3WPe?65qul2MoSP2y_W429Hf_}B_%JrCy|)AA-xUFyBsuW~ zJ!S1o|1DlV6is_hT<5#&%uF$JUT^ zX;0TW2$a>0oZ)h6#icDD+nzD^_@nf=_C-bXhfq`069nK6tE{6}BF#g8Xd?L{vZZ-% zop{0;ukTU1g}|QJ{5)Ht9k68H5byo_xXsdMq>@feq2^6e7Eek`1Z?-sr~nicThu8E z#}~v{PvuFzy#c&?HX&)Qz5He% zdm8aP07sMR`6b}>-#mLC^T)$=GOxxf>zH+6z~Ret$Oq!^&$o07cOUq#0*S>~O+v`$ zno2u=Yl`)8`PUS*MCaeb7brtM{N{b&@G1-7%kur0sqv21f{?K7?g>|nCLfVn-Q$$@ z&E|cn_RA5r<5jg`H!6RLk(!^KUugJFE4jKAtr^xrZIK>L5>8g(rb~5A<@|H*o2ahV z#(!o*L{PkTUkP^RGde&?2Fhj|OIcpj)g-V`v-pI({eYhookIp)%`ZBEq|bR3yNpt$ zjMU`$y?OgHw?m~cJ;-{+G#&K5?zZ>$v1YO2s-b+NBUvMynHhZ9zmIh)2QH{});2n1 zb|SyhK0g~}ZhFK*`+_?;+D)4Kr(bm$bC@(!DHrzh(4lWvtYRFhn@vy@Vwlqhs=f_T zE(*K8#$k1c{y{JKK6((5OP^Pfg#Pin_CD!RH)v{bO9P|Jp1;&IeUO!l!^7DV_whHw zr4fg7C3{&@r_I#1Eo31Q^vllB<7DPTh#+V+|3W0+sI`KkxTbo-r>i|kf_qAe&vQ^7 zo+dtR)~4SSddQ)FGC|g6xuk#k9sc_E?cAFc1G0+q*&;MLPG63kG#C%hn1ALXf(bZb zH)AhJbX~*-hV00A*J~cMtv5--*BR#hW=j?Oc0ZsJ3ueP+e@48_B^(Nxbc|zUg@LS$ z`up_~`zc<_VhhajDB$DZf{%5!K;wArTUc%_hMJfA*rAL zoqQaK^|$Z`;mSA{MM{slU+rntrw(++ww_TlHXotwVs%{7YTMhZT^Vr2PkXoOPW=faGOc`&CnHCWL zV_oi7ne$&Ayjd&uq*&4jZ}9$AbsP+wd-qjJKa_qi`<4Dwz(yd3`KG3};BbPeU3l>n-*W%u(8gJz8o%Vg%>{fN>F>>> z&Q2o47C2AR&DAsC!p1NDrAhnF-%`H|p)zDC+Myf=k5MZRze$ZMHzi1VFz$gf2mkYQ zQs)2d1;DBYEkxO=k{;RXb-+}WXVUs>F=kn`6&G^LwIfz|c1CHN?6I}tLY0b~O9s3@ z;%I3f6JTvmF=!G+$RJTi*&N6vr6iV)Un6oa7!kkdVGtO3jD?%g(V??i5S9eN<$oH@ zWGjy(5^0ldPqGa0;7PxA22R9rDmqwHAwfkeKmyH3xps0fMqulct;iSs zP(~G1GVB{AXG~vFi%S7OI^F+5zBO&Qts#nJ1N9;2Typ>MBCFW`(bYt5R+0#4YOolu z)Sx}&f|bHBIWgk#McdRs8+Fa<$k4dB@ekhuEFZX)6Pz1^7hgkAxhw{1tN~g(J3tbx zzM%4R&$oFXtJX}srSuX&{(^^^pFJmN0`U2cTM!OcUvP7qZ3+VUt0je$is3P-kVls> z&NT3ED2M}?^1!#Y*76eHm3cU|V7hGu0ERvUKZpzN|XGMpbv zMwC<(6!n_Llv0bDX@_kh?c^34KdcAuD|*yEy7sqODY=s#P3Ez^JV@0LeSw600jM5? z#nF%_=bYC6fa}b6JDRSRrw6{3?`P>8N_`)7>1jhIYbQ8ojLfJvQ8)ANCtpl29wVQJ zT_bg8{ASE98;vy!BE^-qG>!?mO-*izwiW9px9w5_27w#at|zJ&F#lSv`>P=Tlglba z8NbJ%1(=&9rt85tP5Fkq)k+;4&A|6X=NMgL=)PE^rt;R8e08nWh!cTVQjC*2tAks$ zu#?u~d%q#|M8F?S4d#QnnprHl1GW`BR@Aa~3LaNEo9arbE-Sn0*qu7Y>DYI$5@%7w zCcEhnq`yXJ4V@Zm*|B#B_dBhU>cZS?W*r3*G}rz@i!vp7z8?|}h6gFIe!z=RH+~8y zr`5+^_U_x!3PSwI2Viu6JTnLPM`Pdf<(XCwGvl~wc*hFR`QAL@Rc8gdd&WUeZTbd{I`$#&B%|_ zzow`KgTT3m)&6ra`G}a_32c(mV}SJKaocLxjeE5nbSkcmlR+r-e!}xG^{sDxa@9a< z7aqiw0LI|Aq#ptD)Ae7vB68HWN#)-nL_KA+=*RllL@qYaH?zOyEojbC04?zn#Wm1I zUIhvb!p#Cvtv~5E{W#p`Dngct?f};u zA@;I)7=7C985FPqDeWr$O*Mnx-g`iZdE{Kq+1;S_y6{e{r>mo#gcLnNnzW2)zc;wp z?%m4H+S~O8))4a0J~pPR1kdvKDbQHtukO)`Zi+Ss)oB2%DVk;={yejDj~s2;gJ&9t z5(U;2Sa7OiS*ax-+W}cs5`=|#nDvV}D zgN{=Q6{=@eS@_)BGJdVb=8aL}uQwjC2mTa7?%EXnd@|gZrt|xw#qO#&l5rpt51&@# zCV5_M1t+;OAtPFz+M!*DSGEB?;ge49{Dw^7AFdnZ^c)v)f< z5^<6A0630dBSf42z06yaSd-tYQ9|Y{ER)~syA+F z%nyCvi_ZFJm^7JA6GZ`>mLsY8J}$Y;V@9Mu5`L3x% zR}Ar%Tn1XBMUb(9&ex}=Ab2frT;o?5)6C7L#s_tofh6V5on84 z5Vyl2I`tRPJYDSzN!FO-GsHsznBvBlAPu=9WJ#ilJvq_@5@wyx-?xBnHDh0NnlkkD82+xDlC{jS3ZLJ_s|-Jh1SR9r8q6E`~vzog(^Xn!gIk@HX&c8<8)Hc>87GlbJ6; zOQ;D|`ieTx^bjmgxz(rvOgZ%X;I3De+E$L^=x5{?@jd0tC<1ja<61xa+HcMhQ;tD1*ct?sYjiNa5WmDM`D9$Nwg8Ce zZ%y7%n#Ty99Nff=kD|GM#r=$0NJbQ`Lc}i!O2$&g5BS*9jxjB`J#tR)L&t+!V6A#( zof|eHH=Z?q@t}g8y{yi}2H8>Bj#({pgHwsHaoa!aq`EeXRcM0+2UocyyVECTyU4%@ z&CP0#C>{BKp0nH|_gj5;l!~ZvJpBc4vih$1(km+Y{~YGg8(~ni6PZCk;3}{gGy!sy zl$vKh$}pK;P~QM8v0ahz@krK688n&Vyc|mm+7VT-UT4Evq6&WQqh{o?Uyb4Zr&nLK zX}R|>F2YQ+CO^5q5!= zO`ZhXxcr?qT_DMA_kmsUeq#D(-s396Dd_+cFn>r{}ki|>l=)?u5lIJ2!=8_m!q z%-dD7YsL%t3V-EHh`M)|!oaJ(YZ^qTVW9r2rH2&nwvWMWm2O=*dC--D9Jcq`-({c< znr=D10Gvv^8s9$qnagVEy7#?VU#_D?qP4Es}tVMcCY78DWr3@hn1N2_VOC%@eINN+^05US0LdumARNd)UgJu(w< z@6vi7-gAw#?Rs{G<{|!w76KmMl52oejImA5*4`oi7^-C%9sfwSh7Dzd`bq3Hw%q??SE0&n+j>#u zR=rU-c%L3pbHcn>PP2e|`fIEFacA#dPza#8q2j8PjylQX{`>u-w>AE?b&1a;!eHzA zPUmPVQ}$2)H<~;WiCF;xt?A2J zBosuvPl00JQ#^!_iwvbkv)vTco=@v0-h8TJBO8fBR!N|@GZ##XV@&A!;@)-M2jG$Z zWPkGZln5icfTP`UWxU9ijW)FPenDxv)uECtgGN0pphy=7#&bk5o%^RU7xie8M$^Qx zeoFl3&)MG>iU$K?n%H7;{eFuj3;Jp=CcP@M%y)ZuGYTJFkIp49;KJJ@gYv`Gyv<;H zzu`i<7-_O!x;@V=-JM%MEjl1yMnY96&6YmL4w^@UF}~8169bnCr#+o$93wu@6Wok1 zC{gzw3CRg@P+$|lBG@d1XWgQ~XnX#eM{qUu-!%j1W1ub(>9wazl#?OeQ9gW$+V6*| zR@u%dEX_IkU&)#E&`)}3>M^&eaEid@r->@7MH zP#ZPJX8xM~vGA^VZ8^l~|M%HrFd78#D3*(ENtS-QoxeYEo8Mu%>b<#`u5O@%t&nV^ zm_l5YeV%1*Ae{T1RccU5Gpq0Z!yca}eu)SNf`mJ%to^ta<_K*y`}CnZtfB9Ss@PoB-%!3LI<`h zdHdbK^E&z~-0V;4)@!wjJ|qcCc(yvE6zOVA?0mi(oBDB3sBS9tk!swXYw zaArY{v_#Wzt8T7(L4#Yn+WUxz7VNb*?!H>ub`T^YX(HG>jH%6S`lYn3ot(3)W2erFsqX1#8(uv6tXhEC$Hb+oUoW|JQLSJ0 zThxK#B-(s+FWI0V98B&hGhLOA3b4NntYVuq@2EKHm1~d%v1lFExLa^&Fq@b&csfUD zGvm2vJjN_x;NSejDt_ zc50q;5zB0WCsAWlr5TB8JB_NduVI#s-noOaY-Y=J%VsO)8hRriQ<(ol0pU&)VzJj| zv(v~|{|;*Bg2ACo5QS>8O`1d@dC=jfOj z+|0Xa%?r*hyO$rBQo(u~)*20r$ZeNe2X)w9QK`6=aB}lSyvaoB7P^VN&*2{ZJksDU zl`ug)iUB0%4*DT5`sIb>?k|5PR!*5KUw=YuB`<*Lz8CEajTz z)sBZvWiHcE|7o`(^d{d0n| zEDXsw%hk;b!8i=*xu;oTYzz!A^VFd~9{@$^asayZ1C%zx@)$jgPNyvW5cR2e2?6P_Q}p&TSCrxC+1oWSB~3tM zCd_(@kLy+RJq@os(v>;N2KOG{C)uHJpUq8h4&~$#sH2bLC`;Ijwt{pF2>|0AYK0( z6uSN4^dm<6OgEVAr+{Z>9v%m`5dGiKOv*^(O0YoG(DKHR;mhdxW#+sjLzu1Xr`!4$#+FZPCYwW5S72cJ*jOBcRI}3UIQE9 zU_yW2&O-mA_S?`#-&w$alFgQ`pYYL@7L4kXrR8MRIP+7tWx&taW?M%|{@rL6Zpy;$ zmMgV{S9r740W3AIaARCt&R%A5apg)E6G)7(+SnZ5iZ{??V< z-f-`5PgtrRXF5nN_4rr^KABH(&`AVYO1d#Z#o^X+YXob!HOal+rUU&Vl40#Eqq6FN9Eq@;6Qoh3LZJx6A7bEoMF z-n5Ur#pxwp(ZDc+tqEgJwT(P$MQQ%h`9rXV+dP;5mZP_?EnR zPq?6&g+zB#At;ttBOi}~;(I}+lh1XID_Ipf%P~(#+Tz<-d{2+Fb>A7qPYF<uGLP z0xGgEwc%%_O$n6R;kN~N6viKj)@jIeH?cO;)}&bKFwe!Q1prY$2y*qgk;)j#M5td+ zklTywX-TSR9uh33)*)$HLMpmi2qc>bmc67HFNqeokx-G2!Eb;!TY@oX0AKW>;crR( z2*|x4^1zG*Q>qy2l3~O*jUY_~Dh}ZpcEYfV%WV3IlI;dBjwv@>jZc#Vw! z#tpLqU)1haRAV?xl{5cY!q7zQc}cz=UH?mp*+IM?uXxB@Ph`N{#f!Ta0x zITjfqDb9_GHsr<>=~76zscB~VIWzYH0;JoARoWi{y&Q5v(5c>^GE`vf&6ZTSPGbS| z(Bk{JeuH|BVwUbH$`RR4c?aToUrl(4+8D4^N!jPn8v*u$KDq+f&$4G)jn`Z{#@|!0 zvd$itATRKVcp9qe5{~7aF5OE*B-Gj&knNa4K24+1Q+u5;I$5|UO_fl)t_DdO zyEAoT+W$w5;BTCW`uBG7%mfA?aVfTmow;8T*z+cB#1=E5`7f1!>RHk^%VCt-xc20G zAp)PeF(1#8|Fh1<3&DgC@dZ{O{rk)Eih8B9^%-NdprL}b4s(Go5cog!Lwb$Rsk_|} zgje52Fl1q-UW0Hhd-7^f;DV>Zt5;2xmBN;s)u307qKp63UZ;~qSA?(`UaatS|2%s2 zXmorYbRumt#<+H%g0yCVlAhuq3k&udg>xYpOHnmq=QEyuu86kab%JX#p)_K@T6Syv z{2Eh2x*=28E4cmvwO4+fgJnMUk^k8--QfKVszKI*+B8Qc*Karf_;=>c*4woP%C2YN zPjJoFbz_9Po;uxs*i=*}NBbJ&+;u;b2}n{ah>T zm3y`xsl{QWv_NFJv*PV8iuiKyaeLn!)=DB+Vx~Gi1US@+~yHg9&cj3 z)9>Lri=bCVE1H(L>mRi0<>5Z*CuQ=q;7XSB%gSSL(2l|JBTd@pjAnfJmrA5J()63^ zFgg}%1{1maDF*DPt>cS+~D&=F*{A57&FGF%ms-5k#3i43kR!q*M9O-!SwSBff?-U##qf?wG z_3gfUKJ?_I>hKgDRvt~5#r@G|{H)d(u8UVuiO}ZJXWIno_@Qeah!4#hLffZjaJ4oh zKh+N~C1Cp~!efh3>_q<0fg-1ZbO$|W6s8X3GO7Ml$?a6PEJGq)+*TTsqaR>Mp3AK^ z=nV2D_nZ<$dn0YKSyV+0FJ!+IFnOx|tx(FC&P>S#BNguiqT4-UU(~&y}-*?qTtLqxR!2QYU zZj*y2m*n<6RW?u9Z1u`KT4&{HcgwHiN};p=L(^5qMb$lh1Sx4LX%Oj>hNVOVLo>PR~u@!cV-o#rf#!l&&O_-U{# zKYb zA2Q_(_r@5YN=2k7-V1o%HUjvg$#XwAPqT}?934x(+_?m~33dpsD|m8i)I@%;gh$Tn zn|f1?HYytLSQQZlWm0~}NC-Awzs6o7!(O7|CQY{HJ5S$&6{CyIoD~2_l8hdF%phas; z<%TBO!rfuGFlB42!k^A00?nqTSUA`fsXI$LF7}ct8K}uA&A4Uhw+jCNIVIoc0m^RC zq*v)h~PiC#3@$met6|q+4kpqRK@QH@6y&4V})MJ3m?a4 zuDr&_z+&-QC$S06n#8TRb%U^X-qtu9Oo}nCRQAb$bFkCB#5&Ety%UMSVHs&Qx|*0Y zP6lNV1zvq+;Mt7bF8*;hH*t`H{tLZ}h?Ba4yLn(<3fl?tO)L00nPz-My24Pywd+kv zoL~&kOE^O|5te+7b4!zbQuWgcNqK1vv#o||ftCL6=MjbrTgfukua#1FP}V;ZDhDtvjmE=^G!qs?x6N(WJ$Z#)Utp^V|2;`HgjP#JtljThS6oIaVe zS6vqpa#^8Q>Jco|(pRS`{~8p9POUjk3jl1b)(1LEV?$XIK9V6LGinzDW`#FdCUpzD z&NsCPbENn6@KC#)ELg3>FFHA@LUk5AyK67_VlW7mL%JBIaprNdGFwA}Nw`Kgp!}yvy=3jpqo%J4* zsLcMi`XAauL4CSmCSe-@`gGP%bz@qexjR)*sGxM41$*R#Q_fXHOXnVc)QeuEAF96S z$3YCH->_>~vX$Ajg=%22{m)B6yqd^oUE^WhPA0#FXARgxa_mBukbX&=;`}MZD<=|O z9-CU^l7Os%k05O0#U|Fy99UCJ+My^e(jq~jaXT1spS5FFyc*MgIazCjzwN(r=3MSp; z&l=rU^N&>am6+D3L5V`l^jpuD0>i}uLY({1KMr7XnhxPp-wDt?7zspS60Fs(?kQuS zVJynbsQVin78d)r9T3f*W~r|Px*HyDkIjTiW&HI#yhdEXgTw6b*h7CVoI4Kmkv6U@ zOwu(kMAD>TgWs^y%&vR-Hzg3_pSe@D9|b@{(tLXJgU*k;NnIuB%Hg?%^2Za-+DS{T z6i4`l++18c9_PrOXe-i2{h+joCxa`M00Rh{(TFiyNXhu)≧1Aed5Ns;#T_5JQzsix- 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 H?9cxINgZ4^ diff --git a/docs/assets/tm-transaction-flow.png b/docs/assets/tm-transaction-flow.png deleted file mode 100644 index ea49080037774b407a06323bf63a83785bbd5f58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2488459 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ķ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࿡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
2qNdJx5h1 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 ^6D_G!q7=b4;K;x5 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

Ht{;jhteer&n*hq}VzC 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≻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

d=nB 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 Fd((P-a?9JZ*}U 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 T{O)??GJ|&$%IZ{SUV%S_GS0p_0 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

yKu9S3A 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

R1PbBt-4*=JZ8jWq8Q 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≧15Y=#~#v^jHOsEsaQg-rZ#itg_? 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 =#gd`D)p8& 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

1S52qXNK;bqnbx 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


6)F7ua8RG$An{lkAQ%FxFm=baoNw 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
  • tKuIqi4)|;B8K~e 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

    R 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

  • ?f#hJu#RCtH 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

    YY9h9ZNVec2$jFj?ox)`c9}!9AV_38eaWC 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 yW-#CdV1I%p# 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

  • Kljt) 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⩔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

    `Eu6R=P^1SF0T##=GS{ln?J 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