diff --git a/.gitignore b/.gitignore index 81cf465..974afb8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target /.vscode +keys.json diff --git a/Cargo.lock b/Cargo.lock index 015dce4..872cbbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -57,6 +57,18 @@ version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "bitflags" version = "1.3.2" @@ -72,6 +84,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "cc" version = "1.0.79" @@ -132,6 +153,63 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "cpufeatures" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +dependencies = [ + "base16ct", + "crypto-bigint", + "ff", + "generic-array", + "group", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "errno" version = "0.3.1" @@ -154,19 +232,47 @@ dependencies = [ ] [[package]] -name = "foreign-types" -version = "0.3.2" +name = "ff" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "foreign-types-shared", + "rand_core", + "subtle", ] [[package]] -name = "foreign-types-shared" -version = "0.1.1" +name = "generic-array" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] [[package]] name = "heck" @@ -227,6 +333,50 @@ version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +[[package]] +name = "mskey" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "log", + "serde", + "serde_json", + "simple_logger", + "umskt", +] + +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", + "rand", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + [[package]] name = "once_cell" version = "1.18.0" @@ -234,45 +384,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] -name = "openssl" -version = "0.10.55" -source = "git+https://github.com/sfackler/rust-openssl#9d180ec94a92d2d08d6463ad047d9d7e7a8d9561" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "git+https://github.com/sfackler/rust-openssl#9d180ec94a92d2d08d6463ad047d9d7e7a8d9561" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-sys" -version = "0.9.90" -source = "git+https://github.com/sfackler/rust-openssl#9d180ec94a92d2d08d6463ad047d9d7e7a8d9561" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "pkg-config" -version = "0.3.27" +name = "ppv-lite86" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" @@ -292,6 +407,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "rustix" version = "0.37.20" @@ -343,6 +488,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "simple_logger" version = "4.2.0" @@ -359,6 +515,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + [[package]] name = "syn" version = "2.0.21" @@ -390,14 +552,25 @@ dependencies = [ "syn", ] +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + [[package]] name = "umskt" version = "0.1.0" dependencies = [ "anyhow", "bitreader", - "openssl", + "elliptic-curve", + "num-bigint", + "num-integer", + "num-traits", + "rand", "serde_json", + "sha1", "thiserror", ] @@ -414,10 +587,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] -name = "vcpkg" -version = "0.2.15" +name = "version_check" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "windows-sys" @@ -543,14 +722,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] -name = "xpkey" -version = "0.1.0" -dependencies = [ - "anyhow", - "clap", - "log", - "serde", - "serde_json", - "simple_logger", - "umskt", -] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/Cargo.toml b/Cargo.toml index cd188fb..31a9228 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,15 @@ [workspace] +resolver = "2" members = [ "umskt", - "xpkey", + "mskey", ] + +[profile.release] +lto = true + +[profile.release.package.mskey] +strip = true +opt-level = "z" +codegen-units = 1 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1ce8758 --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are 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. + + 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. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + 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 Affero 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. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + 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 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 work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero 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 Affero 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 Affero 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 Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..0bd7a37 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# Universal MS Key Toolkit (UMSKT) Rust Edition + +This is an unofficial Rust port of the [UMSKT project](https://github.com/UMSKT/UMSKT/). It is a pure Rust implementation rather than a binding, so it does not require any C or C++ dependencies and can be built for any platform supported by Rust and std. + +It does not include the required keys.json file used by UMSKT. That needs to be found elsewhere, most likely in the UMSKT codebase. + +## Credits +These contributors helped create the UMSKT project that this codebase was based on: +* z22 +* MSKey +* sk00ter +* diamondggg +* pottzman +* Endermanch +* Neo-Desktop +* WitherOrNot +* TheTank20 + +## Development Requirements +* [The Rust toolchain](https://rustup.rs/) + +## Build Steps +1. `cargo build` \ No newline at end of file diff --git a/keys.json b/keys.json deleted file mode 100644 index 6c174f7..0000000 --- a/keys.json +++ /dev/null @@ -1,1571 +0,0 @@ -{ - "Products": { - "Windows CE Platform Builder 3": { - "BINK": ["00", "01", "0E", "0D", "0F"] - }, - "Windows CE .Net Platform Builder 4": { - "BINK": ["00", "01"] - }, - "Windows 98 (all)": { - "BINK": ["02","03"] - }, - "Office 2000": { - "BINK": ["04", "05"] - }, - "Internet Security and Acceleration (ISA) Server 2004": { - "BINK": ["06", "07"] - }, - "PLUS! for Windows XP": { - "BINK": ["08", "09"] - }, - "Windows 2000 Server (all)": { - "BINK": ["0A", "13"] - }, - "Office Communicator 2007": { - "BINK": ["0C", "0D"] - }, - "Windows Embedded POSReady 2009": { - "BINK": ["0D", "0D"] - }, - "Windows CE .Net Platform Builder 5": { - "BINK": ["0D", "0D"] - }, - "Commerce Server 2002": { - "BINK": ["0E", "0F"] - }, - "Windows 2000 Professional": { - "BINK": ["12", "13"] - }, - "Office for Mac 2004 / 2008": { - "BINK": ["18", "19"] - }, - "Windows ME": { - "BINK": ["1C", "1D"] - }, - "Office XP Applications": { - "BINK": ["20", "21"] - }, - "Office XP": { - "BINK": ["22", "23"] - }, - "Visual Studio .Net / .Net 2003": { - "BINK": ["24", "25"] - }, - "Windows XP Professional Evaluation": { - "BINK": ["28", "29"] - }, - "Windows XP Home": { - "BINK": ["2A", "2B"] - }, - "Windows XP Pro": { - "BINK": ["2C", "2D"] - }, - "Windows XP Pro IA-64": { - "BINK": ["2C", "2D"] - }, - "Windows XP Pro VLK": { - "BINK": ["2E", "2F"] - }, - "Windows XP Fundamentals for Legacy PCs": { - "BINK": ["2E", "2F"] - }, - "Windows XP Professional K": { - "BINK": ["30", "31"] - }, - "Windows XP Starter Edition": { - "BINK": ["32", "33"] - }, - "Windows Longhorn (6.0.3683.0 -> 6.0.4029.0)": { - "BINK": ["40", "41"] - }, - "Halo: Combat Evolved": { - "BINK": ["50", "51"] - }, - "Halo: Custom Edition": { - "BINK": ["50", "51"] - }, - "Visual Studio 2005": { - "BINK": ["52", "53"] - }, - "Plus! Digital Media Edition for Windows XP": { - "BINK": ["52", "53"] - }, - "Windows Longhorn (6.0.4033.0)": { - "BINK": ["54", "55"] - }, - "Windows Server 2003": { - "BINK": ["54", "55", "58", "59"] - }, - "Windows Server 2003 VLK": { - "BINK": ["5A", "5B"] - }, - "Windows XP Pro 64 Bit Edition VLK": { - "BINK": ["64", "65"] - }, - "Windows XP Pro 64 Bit Edition": { - "BINK": ["66", "67"] - }, - "Windows Server 2003 64 Bit": { - "BINK": ["68", "69", "6C", "6D"] - }, - "Windows Server 2003 64 Bit VLK": { - "BINK": ["68", "69", "6C", "6D"] - }, - "Office 2003 Applications": { - "BINK": ["6E", "6F"] - }, - "Office 2003 Small Business": { - "BINK": ["70", "71"] - }, - "Office 2003 Professional": { - "BINK": ["72", "73"] - }, - "Windows Longhorn (6.0.4039.0 -> Pre PIDGENX)": { - "BINK": ["74", "75"] - }, - "Identity Lifecycle Manager 2007": { - "BINK": ["78", "79"] - }, - "Visual Studio 2008": { - "BINK": ["78", "79"] - }, - "Office 2007 Applications": { - "BINK": ["7E", "7F"] - }, - "Office 2007 Basic / Small Business": { - "BINK": ["80", "81"] - }, - "Office 2007 Standard / Professional / Ultimate / Enterprise": { - "BINK": ["82", "83"] - }, - "Office 2007 Home & Student": { - "BINK": ["88", "89"] - } - }, - "BINK": { - "00": { - "a": "1", - "b": "0", - "g": { - "x": "2331577204679600027736694662072998192243212592890122053374825500297155761496269562314159428299171097610055218913705", - "y": "3954018412338623664837114504916044126050878678856973124996251286784490174941479836757650135598751723409532967160444" - }, - "n": "42464065991425877", - "p": "22771656396649042914677651938348976006738044330885828909690000917475479649330897416453073715484777125675617411561753", - "priv": "38647306188807670", - "pub": { - "x": "19001842596799889735847089805697287001733951474617682470323383968715961244343387245639296624260576737647372909452518", - "y": "5073995932966536731583795294253584537145351666788650220967374102582334986751283480528872642160868858730405130413714" - } - }, - "01": { - "a": "1", - "b": "0", - "g": { - "x": "10673454940574675734218426124215696222570049943204897295660707733776259469307290746763087579272352204477426359456983", - "y": "12266547372348718976150807658375668076642952085819513623587674808420656632476917449122499280756388746447098580732795" - }, - "n": "45451421528219701", - "p": "21690482571471944131858536333908058782272452491831771308020961342630740764170913541267450561542337158596383516743897", - "priv": "17403239656857625", - "pub": { - "x": "3614099199023017971148876036659975837782690680728273254586906030102722523955367121942849829253953580887060503496633", - "y": "13800594939586205538166670892278369176641441651504986605158220586834603467688335741155616241506048203605969931767808" - } - }, - "02": { - "a": "1", - "b": "0", - "g": { - "x": "12945521200488607599028656523227600834645282385529945429027333942356897353457141653432411062448887162429396839725905", - "y": "28848503114551943942613290154239739502710619007562434518751494790901286961962988591861282401800949710517326509814280" - }, - "n": "71314261946000873", - "p": "37392568050767930319799988287205396758117017539972057881598316494924185591542182483195697473804013824755052059608001", - "priv": "29126373822686368", - "pub": { - "x": "32203872504800826193860578257942098817761632037322936149898772567823772721868451723895290957871284796960470523979193", - "y": "29602813656567751793759332218082879597530452170215742929397002601119577441784146888237119786583675093403524212008308" - } - }, - "03": { - "a": "1", - "b": "0", - "g": { - "x": "27994076808475229758326263133362929272220571606747122907327470869596018889793463129645972572266834489354416647381824", - "y": "25905505044642050008028336652499541922197718613122256210203673259353739613110582288166640021538525466499440893496683" - }, - "n": "65153636961774397", - "p": "36344353935396613718356487407699793893725869238821772569108732609306670398289558080400955729328602471783395378286633", - "priv": "12823911728474639", - "pub": { - "x": "5989795792720183232357308397328552120890832370159249479102017870689050146843974909018077446828100022809937759037457", - "y": "4076499043434397184167747716536775685672659730989741811348214546850688174088048243849389563176846351391019790440130" - } - }, - "04": { - "a": "1", - "b": "0", - "g": { - "x": "22606687668269298114625240207522873142726269014052537843427518017813300084818537975263731248330029611849165060179698", - "y": "22487350102024832247251097934408529105395697460802052344875349874950231881440810299529934247574539849802290200440206" - }, - "n": "67537375118463713", - "p": "25066384285441205903273832649434882702712612496016407378135255151484493899841608613787340526409623217340548154752257", - "priv": "11635865700012297", - "pub": { - "x": "22021752605428965357178777617015527233578373960385071831838131873160197100814268130275797060808542178604912347883389", - "y": "23866939163753826944639218415544304773298439266931849491790315194143842918793955304612855324679875974365253172635470" - } - }, - "05": { - "a": "1", - "b": "0", - "g": { - "x": "781819923528843818061353484618984968876099407238823837591984121830775798915631450542772051465612287365705364064998", - "y": "13219048869966217368618050570644487166158059065919396407529689500553101289292505577394593103284384706085687130679914" - }, - "n": "50339060180106073", - "p": "20540151207176407610392811638129548448205144944910278982948996576713892299586270552571422734441315161712142945629849", - "priv": "40228399726161800", - "pub": { - "x": "5617828531306429109131542402145641940634218296626854652746172963700888272248450563965281635311417296472764855113753", - "y": "15121413581491496478205098277793818091231295981171324129530352426474092038164705306631251374991917540506560457042695" - } - }, - "06": { - "a": "1", - "b": "0", - "g": { - "x": "20290983142717519792261408686352487989649211887922216833203504479698185603590002277493991836124831075173569580204477", - "y": "15613576728870816857160584481855675933338821085093804510572444643308874185251477239943066930147632556638070636441432" - }, - "n": "36577089244984073", - "p": "37990732850765540949258158252123434514839333303742675794943500457245740454631544112729007639103771574156034280604393", - "priv": "16765165806610496", - "pub": { - "x": "29299800775213565057549529503711254775854333861363066212479678551229808304583729940632334835601591770453319125573966", - "y": "14861466094377865190522653191120791841827985989676034034282703670486520993005899046766857612407262012243607466617974" - } - }, - "07": { - "a": "1", - "b": "0", - "g": { - "x": "3022230212861852143926252523215574239971355724885382805476990984159935367480775746448786270204099464042384143262546", - "y": "22692252008411764842293588588620353137409487094887514780285609890843172954491503687225347309851119975391662003184206" - }, - "n": "42711093252530077", - "p": "34025505520977025383797421109353705207329755039923206461385189688570023154971691983118444196840659984974006014915457", - "priv": "28625914362170518", - "pub": { - "x": "9352001430116070356229866278421266037881922229432783428504987997385316307975037351847840858083283066347881190861984", - "y": "13660483978543810828797076254776611318256965559421711578116057132999910591236081024558566808003705887292790181522400" - } - }, - "08": { - "a": "1", - "b": "0", - "g": { - "x": "20546520481953678154188673002497673317951351005548515253692962760894884550885667364279279675317349577557539360814123", - "y": "9690423372408868664356492113196121928041525311419829379643952572628949982787595259238649512191063658749129235349599" - }, - "n": "57764213524659997", - "p": "37296045993145557762887615869529446066927464675046163533740890434147377036252939859599505430619316010543536008593953", - "priv": "42940447838889445", - "pub": { - "x": "24333724270092143621713826802597896628928936454919800951047900078926973110794950428837308243267285488795216606840974", - "y": "14020134285706927331676614030279900017291016148631271055361689697974801145765941432183225698727390866903667219687969" - } - }, - "09": { - "a": "1", - "b": "0", - "g": { - "x": "17272533675023793624680016937607161394427776688401278127884215858369066406365237833207419170117031265147050748737186", - "y": "10897684556651576571671151674586120690608236542740270859915076272932083320838022698730208293779451126638581586588925" - }, - "n": "44682719955829289", - "p": "31123778862031392435299439090755153401162704597024288571183830527113563344679315725116915983118187065183839828632113", - "priv": "30177475288172038", - "pub": { - "x": "10584120526089473026246191383792758367144927589909587205278073830223938861208553884400816982485323081066790399437204", - "y": "19710761542152200618172612283139324015316083022563473705358032993141026289202915973780473937312193485361804450068338" - } - }, - "0A": { - "a": "1", - "b": "0", - "g": { - "x": "23948165163161423827781659252187464228156720755142058092673382257634334615418008758683925938170704019069504769068767", - "y": "29262124142683887534232736126380966649037190576572850117401576509403154245303113352176870318970330981025925802076215" - }, - "n": "48764835656345441", - "p": "37184132387158636185823166107076967114138479407440093455278818158072422008561996049871236605258164895216434405941633", - "priv": "7983635268050735", - "pub": { - "x": "16148631041299144072435534784738008519949841221985024060408677162532254304915141767288991659528028804911680226440414", - "y": "11647588982042777999933885074728841323429055317640349743317690400085264609368266409172384083304384956740124856614996" - } - }, - "0B": { - "a": "1", - "b": "0", - "g": { - "x": "17272533675023793624680016937607161394427776688401278127884215858369066406365237833207419170117031265147050748737186", - "y": "10897684556651576571671151674586120690608236542740270859915076272932083320838022698730208293779451126638581586588925" - }, - "n": "44682719955829289", - "p": "31123778862031392435299439090755153401162704597024288571183830527113563344679315725116915983118187065183839828632113", - "priv": "30177475288172038", - "pub": { - "x": "10584120526089473026246191383792758367144927589909587205278073830223938861208553884400816982485323081066790399437204", - "y": "19710761542152200618172612283139324015316083022563473705358032993141026289202915973780473937312193485361804450068338" - } - }, - "0C": { - "a": "1", - "b": "0", - "g": { - "x": "32366559100369318283806949847668006966372576295512713108321085041414300654732780440477281124875100457132910713385392", - "y": "36277066295525832825357611949223811038289235173317865340414967683326061355424351588874247387096082012795578150665609" - }, - "n": "59338206178439857", - "p": "36883284215161242563310145090645358935159680728419347578246433941874667246014425073058641415639952085274328207007361", - "priv": "40581906428014757", - "pub": { - "x": "27897587677206802935272072179740121173143753076733201426736721660648622269207410244820576154042145772129856483317918", - "y": "13615609806169825354266127137741977194548952863339923138634202769645906429284217242635558548859194566413379013960503" - } - }, - "0D": { - "a": "1", - "b": "0", - "g": { - "x": "6645465708298979297645218319744955265667580573078366866240130998337156417559279947807138605379710836345182353956566", - "y": "9122261325743960629676061760923709333528687205500940401556553622283598790250115820669732772373561034819836006012285" - }, - "n": "54718482591717193", - "p": "21262683770905544338571543505453061536845396135304775106786244478927459953699178453429809049886663583535515332608417", - "priv": "47335405173668092", - "pub": { - "x": "17901813509704147483830835266370702882674023911261162322131513567769351494873007879644402037648391915282581963897955", - "y": "3627746470775852993311378053985025489205823505060996524650056711113522565534673713290725146394961076678997021207516" - } - }, - "0E": { - "a": "1", - "b": "0", - "g": { - "x": "27747752307286592687012373511047845159334654229150694584737865727671140019146915126658619381536913889340121429777176", - "y": "3432951149395499007263552055243423973930620822599982913138822382764310200465584292869885640731380391181334006544903" - }, - "n": "69347892008216533", - "p": "36347478437802048537119868924527781602382983008254976074874612889097641729112752259090095081683689659920202493703297", - "priv": "7092493664915888", - "pub": { - "x": "21652922522868334895657043827148412844567405193561740682190228631524297662741918392809167788290748819278548343887903", - "y": "3417364464298334389588552458831357703430726188539039648711355435080336809889862010595330876621524473130281045660871" - } - }, - "0F": { - "a": "1", - "b": "0", - "g": { - "x": "31776059432192763776169381921670178722866221070834058273282940403000440589856847475502258046219835656769351443888388", - "y": "14915954572069018210816473452568747806301836720199982203742875487860683708009757250677784429672784879759557934677295" - }, - "n": "60306638703816809", - "p": "37861187394286237954223210768267876485159987135721389001525364888539928951972506513033460251773122312456256755333769", - "priv": "43529410493479903", - "pub": { - "x": "36937113900362437545657429676722225709769818478521942542158699404492483695089143602302938076641123916321507892090940", - "y": "12300711937755714474221683340048792628817501853269187222732097530965245794898485391792926982501341822327927281168157" - } - }, - "12": { - "a": "1", - "b": "0", - "g": { - "x": "11119482656822991700792578907460492227713548578133058475037279114658452606556520469737149880517581700365327698611081", - "y": "5312392362047363949252475376883941023428136467239031118254622461615317640729075312800894148424589785499630341506080" - }, - "n": "61468465254706841", - "p": "20622394400536669015009109445778032002575716997347454488103759663466131824487696837925141032629668839547983981006673", - "priv": "60745091089001069", - "pub": { - "x": "8302386161994476463882352663800987677857025296941809689065347673056316489123420195107324646013409722355145362105695", - "y": "13363649414286723252942106921229466872616885916170044867152681460547108642096237962603450424133488992957379857797813" - } - }, - "13": { - "a": "1", - "b": "0", - "g": { - "x": "27454888227856505533387855329956788267030560228130237843019128731561479441383843643211794715596006608164303047382767", - "y": "25734101585617196914691138807004701507679801292492905532148885152767040438129871790752711796217529957350537646074954" - }, - "n": "38771992745198197", - "p": "32512713267117547802229004817342438100721689377119915617511876448957214358251584089752707605032440065201094448831881", - "priv": "15976728344674105", - "pub": { - "x": "3691704687927058819591076394169677514664333662183974274461082367921506972751896092475629328058011790588662903256832", - "y": "26484003440265260647575762004113995465586854417593253320671406420252567198975995448928227659791539037587765978967255" - } - }, - "18": { - "a": "1", - "b": "0", - "g": { - "x": "6310475814662352568971560182310231839329343724408624519389068728320329025974637390988828335460419687090810096444671", - "y": "14975740609692212121466982863362652836149004779446935330110884359582284319436292141410425119946675031763769510936013" - }, - "n": "54695987280141397", - "p": "20382341820853234423840825688329019101101189275426194204365984074203757959383616959383036631061239138112927267520089", - "priv": "34992317936760591", - "pub": { - "x": "8706389485534845673163734064079119714439476595416111663093903895319551340520311271066830871273781861930387023628095", - "y": "4443601879949176681910035950062822482896269563744604779691014779955561545862216697926657333283397354995534927843775" - } - }, - "19": { - "a": "1", - "b": "0", - "g": { - "x": "7584514146265657723682589467472480210708798127771966639002925072279390565944732637329803708869161392955456901683208", - "y": "5764283675033599948981599061678875106928092179619498039027173635003240679699166287323607856795584908008068710374623" - }, - "n": "45247533306073321", - "p": "29904458140618354476427451017550930593422131725263169701409831912303561396966291922475820357156233696613726793819113", - "priv": "29657152842312895", - "pub": { - "x": "17576167019544040155390616697334398449082456265796782458191155901005030032653815532964116263462127482133737258864700", - "y": "1125407055820070498649143362555264611724476175583265219055685553252038666319259789915739639733545886876232604191242" - } - }, - "1C": { - "a": "1", - "b": "0", - "g": { - "x": "22855249491408577399314114410491415950517593355478182149672442878739161291712677791480806227311388739667949116186643", - "y": "10090748700447563344768464967976982814599035434371109678353441279762990928564733098705170129446589067321569664285856" - }, - "n": "48327092680035149", - "p": "37198856165827359239624523956448360398873513822648810088561724187860467287854220885995282969477483102943902841369153", - "priv": "16619186003963700", - "pub": { - "x": "23301265649040637976531382749590463952316720099647572298097775954000521920517815910803570872646950167923329601997134", - "y": "28939329175037377801073962070204861485644082671743919066988639734312772338759696891645523206570996463742438828645000" - } - }, - "1D": { - "a": "1", - "b": "0", - "g": { - "x": "21485907255093637178082315005177275537228742177931509431249056347300555552172888693235406942297454493676702531931655", - "y": "7637085415458452555331445043889178137700055152197196242022245472314658145011526482426816376681157002338341647989098" - }, - "n": "71650264922603869", - "p": "27845658323610558342493324384410335947445989111503711636352684588775122083872122365066007826271926755322572707136313", - "priv": "26815466003754626", - "pub": { - "x": "4876696263453032445338210618537086689338971119926272787904035176296725481867195547017440481622297580256815541015926", - "y": "15853826468148827809563406431189387397493981509673040194341328851566636137415804518532176226406586339241644224217344" - } - }, - "20": { - "a": "1", - "b": "0", - "g": { - "x": "6686321999622051178591311822099609521208473884691575834761183821695369178088927429575696614600592264838083653551328", - "y": "8708660980615804987290390922286202932010531171713457714232968437316481186496784893214865780968004644609012939569295" - }, - "n": "57001816492288169", - "p": "29147266190978487142724331180857761358464152478756370901789788622663454507157070029841119463934333045189074823748017", - "priv": "24105224018429147", - "pub": { - "x": "3079838111989033565943043999904330598009631832293766291336987193469067925154485617252460140233911286520214631295235", - "y": "27466153539310732778202127946739473894168326873113036251235314475869642331462095667900277662828596833955915872259873" - } - }, - "21": { - "a": "1", - "b": "0", - "g": { - "x": "7218781427120785178725623901975299305634810332201168561903403409664405857829655009079413595609453155845412233075193", - "y": "19449453204585732846377914924665821314567408072899635427679464303538225464188449754928687947160116118731610122451971" - }, - "n": "70641998984652317", - "p": "32354709286228852182518787575716369018376048992530369544020867305267989998685044938366506455565414707817181388680633", - "priv": "38341712192133441", - "pub": { - "x": "14023824446142707343565167755394444040059760284563816029377229622588770661846541780333029942315327565958606208771106", - "y": "30604751698189796066091989007727114877131638436543785875345552646965733337783659422892989188358702333653008106463265" - } - }, - "22": { - "a": "1", - "b": "0", - "g": { - "x": "12259358487924366608305813282440364085684395756994923636191629847503895994037183295786380452071239418106026509150804", - "y": "14853676372788121804436447106529209167572424731944959299344702242030301728072117127341066233856180747847416655851934" - }, - "n": "69284057899286401", - "p": "31648573662208007208411279340972174081655191771220726603117102285639562723584318781472781870749438532939445789762497", - "priv": "13576107630579530", - "pub": { - "x": "5871898692465293699950936882527671235864759453647136933264801904900692020319864572178035453433020771524967155028662", - "y": "7797169826989892215278245730061461386927964876868463824394796499325209401088175936040551790551876059967923119137155" - } - }, - "23": { - "a": "1", - "b": "0", - "g": { - "x": "18986140368912686946766824672798319264943410511951605590295624458023663413315771550412808116691709592493884174247323", - "y": "35582835919011558986825813010572858416130195540793539052310817770750293516630582064601225899492793739318461290416459" - }, - "n": "49636728679305421", - "p": "36972713617917281884750914540945557203256304584341577847131541606985792593160647528404736364994609090002393518365297", - "priv": "7621238846312565", - "pub": { - "x": "5474861534966667085906840131133038788933705655580507041430931765582606146380837172308924465130409686699600787594543", - "y": "11326043172398492374226759220878127907308526789869115594345877455697735198293097656639000464933130127615502362106702" - } - }, - "24": { - "a": "1", - "b": "0", - "g": { - "x": "4492318878195287028641969069300774407040103059932532535110576316170354692927817610666693376859152036186857275361391", - "y": "1694746079656212098005835261250868391807480551771588137885173193876219104438889416288917386204684992492306399883336" - }, - "n": "51239258040959909", - "p": "23971312951249835125727253564197976328111252475442288537785054438561546287783425046926796895043478372563040474056649", - "priv": "1184680163675018", - "pub": { - "x": "7469701811829692791542904030466988831653197363045152552888543494171712537634067299840014762722678773980197367532093", - "y": "21442244090949131497466966127353491267322103670986664241259520242511672755523936797064703693562596797394045432190546" - } - }, - "25": { - "a": "1", - "b": "0", - "g": { - "x": "11926898248241239748997351957173960056057407886149788887758062574272894012644073661378923746287542171374583361479761", - "y": "35419490850545970758577819248219444638250772547354989411487568475288779473681482073873703451548747635418769420793286" - }, - "n": "65954858530398437", - "p": "38505005783574214474412480744393764780948137723283702040743108245361618646062618204011087438273094275540438104519273", - "priv": "26941797169371159", - "pub": { - "x": "35533456553226765761636011384686492624398611798034646981562720601482557741905776634955456778290492506576434423681065", - "y": "31327464208115609033515355290240501419723636369785092263794133094830273012773664815395736769013183396740555644058707" - } - }, - "28": { - "a": "1", - "b": "0", - "g": { - "x": "6625455131255616498288897401740387586936919298398630888817069955271802346063065950505620943020700795501030354951483", - "y": "25533652931145206810096025009180082955369059200957488574448993391838671019475012100931337253442582998280032435349351" - }, - "n": "57483349306202381", - "p": "31180364593374161260541214644085545950368042282359256671297134949278949227610474415915698419926523326596302438006769", - "priv": "13136214442180721", - "pub": { - "x": "5104925930512638672819053368212255937573137611150786858226532094853360078971757032168938988793670627337813923036767", - "y": "28137487828227178563350402753881014405678533666094621586427542674382206038438535788143080548493760349515756182012498" - } - }, - "29": { - "a": "1", - "b": "0", - "g": { - "x": "6855965928974656223860567398557704088817997034038651863138515626385009760954658000974356371150696139484451845926600", - "y": "1801238159270279246169147737509397655357290457453559970603838885439270588090298720450362006989715720109206491245093" - }, - "n": "67647193402298473", - "p": "20943044253804132319169216830228672625270249954489249987858922604701634645918538145031729465712318342252126112985153", - "priv": "58908212650039669", - "pub": { - "x": "19589519046601397260809955269083626795503130334091451763896601804243999018446108131405408867157069655563420193230043", - "y": "979397535273986461157952793344176191317009812589408140414741804758681355998002007487306586139600254357725560998472" - } - }, - "2A": { - "a": "1", - "b": "0", - "g": { - "x": "6491087841214587051264545986557683007600933910896314457162076997479104680607524492579346483250057819719574751118546", - "y": "28889674849416975039297975655960492533273983902836344528214812450760488908413247697351485992563586277899237970177501" - }, - "n": "55490915388926201", - "p": "30609238151955025112052355607151891160055473451727463357136290171496228014314319402618394255507642663056173045397961", - "priv": "28356164640468958", - "pub": { - "x": "7429934306150060362220520167219696196103387398223657500784703159452793671818880169418653109022945805967279598841058", - "y": "16695949431099551936765494864197903910720045366223287633678257137673564581472696006269235457344268044769517631487706" - } - }, - "2B": { - "a": "1", - "b": "0", - "g": { - "x": "8915903858502646066418182633057705652008082145832256923615728473200101206132031281584883906271118970991755030551416", - "y": "20464678754304824937079694961279040773502428396767671213114450862571235656842986110419159780072381959022618240357492" - }, - "n": "52255053939691037", - "p": "23565722542837335065074829499441916969523862484272548221564258250579409483831082603756318140516261012072179955607649", - "priv": "49376872296925867", - "pub": { - "x": "5208399005152010558700017443262304096033307781594722582754654119839186077071380964884760370919282614223655552449192", - "y": "22357703575020535444907398820227602869440920600838658819039554416206966784231890678810435029947588971910074121002504" - } - }, - "2C": { - "a": "1", - "b": "0", - "g": { - "x": "21673361717619259910600499419800485528178801849923454062050055236231939594233283543796077751210469045350919066368895", - "y": "5232476492611604888729825305639232005017822876108144652169892952989580351454246958886421453535493897842819359154864" - }, - "n": "55681564377333977", - "p": "24412280675538104642884792561502783185577987209710041026341163083973933860854736635268965257725055809364646140091249", - "priv": "30951839223306173", - "pub": { - "x": "21551722775458524408480112576069559265917312687549112053580919391285918530584174752292844347621326558272739603979057", - "y": "13463977158522661542654520438933687107907187215503371589980428235633526671841388652148099285621876350916055100879930" - } - }, - "2D": { - "a": "1", - "b": "0", - "g": { - "x": "27781912721787993763805837568064263711340931435239060864256539635990160352746069412406130189835503935411239757870741", - "y": "27364922370114990533080625336285288934681289975914886077419119101693257916498416164024544331981480303244517347734251" - }, - "n": "46591021859161649", - "p": "34434335923751399698518505516722285557281631663360135021571830978812886664047949565106992641249608613800031755822209", - "priv": "11012852810209962", - "pub": { - "x": "4799183354431172708437474398228298037089681042678881469855476704311534306845199897373322889867450051628647190714371", - "y": "14871217001746100747746722676908590963712532469411562675056088017233265734517784273850861476487467117022794466227739" - } - }, - "2E": { - "a": "1", - "b": "0", - "g": { - "x": "10910744922206512781156913169071750153028386884676208947062808346072531411270489432930252839559606812441712224597826", - "y": "19170993669917204517491618000619818679152109690172641868349612889930480365274675096509477191800826190959228181870174" - }, - "n": "61760995553426173", - "p": "22604814143135632990679956684344311209819952803216271952472204855524756275151440456421260165232069708317717961315241", - "priv": "37454031876727861", - "pub": { - "x": "14399230353963643339712940015954061581064239835926823517419716769613937039346822269422480779920783799484349086780408", - "y": "5484731395987446993229594927733430043632089703338918322171291299699820472711849119800714736923107362018017833200634" - } - }, - "2F": { - "a": "1", - "b": "0", - "g": { - "x": "25904051482675514500669093529301214170223884490017250779967799045498125858161801278923249219988634101342134538786052", - "y": "17368622637199623459370355450886727695380052458605518871156173742379499927409697901891660320010128728180182665357867" - }, - "n": "62443961168019161", - "p": "27407396338439569164955230033365569790027808547807104696365020660004821507019814717465116357974159702372050777059873", - "priv": "29662783944176267", - "pub": { - "x": "10041352286586128940778441134697140947437132522963541282603223909964089228202203447893168630967079559592385624545192", - "y": "9292360790888709163192008500642345429180999836863864477254342335185874973743595440806854122467192796977299364198680" - } - }, - "30": { - "a": "1", - "b": "0", - "g": { - "x": "31574409824570705964544367030368440543791401849426544831850080936306689199101549482866255489086770161031315565401331", - "y": "2822872309792998318093862348825391297607820893228186010000901024593413215493811572635496939163111762266343070301811" - }, - "n": "48959934415612973", - "p": "32009921376317960221576065562805166480546341594240230869485042707378974118124593731053232945497329129143547457317801", - "priv": "45906145109462193", - "pub": { - "x": "25897134114588480425265684642921204121884326347274237065932995903818740612744847914045450349302340709998384364312297", - "y": "1605304482344202101863265512591091746499168916267043520577629617693396956565214733104594178622005304907093890699566" - } - }, - "31": { - "a": "1", - "b": "0", - "g": { - "x": "11188104450577873458911701429695026887774021239954257546409604848401278693592131834788763813758435930816382003958104", - "y": "24490951733272171720884693434505468532109494775176376686967265901204761001801843130321166548162318419048087471035800" - }, - "n": "66874636907653541", - "p": "25481707350880489563331220397252197864427149004368996522335270121024731904125866347924725777243159725371357561236729", - "priv": "52925767743678469", - "pub": { - "x": "1667247963417966237212807096289668964696884414761513558217414317572656739670183406633077067724180311299088421164173", - "y": "16748564218264747164349322762189378329328804080520961090155095866935688174130443939169605936102924753154349010438361" - } - }, - "32": { - "a": "1", - "b": "0", - "g": { - "x": "12726461294499926560068151670755648381327270933570408046980855499993821725946986709210217963523130634525797609551100", - "y": "19727466362747241639614430182283134406657859985308135285523481410218197736089464247591813328077488945200498871246573" - }, - "n": "65794461159063457", - "p": "21055788153165092719902120162764441840863916414168155711589396355396184787671893056148679610453574714946317283911601", - "priv": "36261933107303189", - "pub": { - "x": "20951918253348273252420340105342001337430637214876028091851180291652873950025505424806224449373381285608077226552471", - "y": "9574918363679101910324218403815091089131481132701762206865487974994855351639447295943340460718678168318117194195752" - } - }, - "33": { - "a": "1", - "b": "0", - "g": { - "x": "1794865730835385436163427753723234719911851797686636255721756602521630801773080869578590362010786910928772822065072", - "y": "30644486003529828103888328722673972171730735334350555137971150233266085818806168194592552532099145733381090086026739" - }, - "n": "39030245206593181", - "p": "32570677563636890576365869186469870364879811420628282404959348810134494363087895710691433232743794272463480085754961", - "priv": "34481221421628229", - "pub": { - "x": "907296736569259468480041782855281364952562359519792244665824534285751872123373034165077452334975888459663148242736", - "y": "16927761660112078837951464089861279221188811999337390492625539371026015626584250804363204864186060157462161862017016" - } - }, - "40": { - "a": "1", - "b": "0", - "g": { - "x": "4059949146365219555765942623881117805902135583342215173483403715338700834444334843734013438929948804356102673557995327491778895286621343661027886194229423", - "y": "2666176389066415236284652473344297039725375670348031203453175504900403049498614310424697925683808910311136608699171612232668547550268382836372320506920106" - }, - "n": "5433982808887507657", - "p": "8593089364081001067462414866654031030011369860377686076521185730682021902004001446804904031667686514463236003668466017626568697473954285995216040950902881", - "priv": "449278429561237525", - "pub": { - "x": "7559615723586709586458106004507017059372166711271777511283228857051909257718309123926479472096584643986638698351587465542509690715985335205369481790178546", - "y": "7080073383749624161526624872543179425900008718862030231798273629479785989924538511939628398505421596500162321954578945975993952938126069166218024480096454" - } - }, - "41": { - "a": "1", - "b": "0", - "g": { - "x": "9791458979524371820932506373340791347147485287286801025025747008476002029861528741424050864358137516255664108423493779065350932029808518858376062167004536", - "y": "9932434466111647561557538581748799870403761251980691823240328064662070366553827221038647353473056891319938111493174855021955908965618290167703383083703662" - }, - "n": "4927638009777311293", - "p": "10165754444795254057389422393400930472583053728543041642319024171930216155078184719345890697917311487018908539453332431395199632756711975301609704092843793", - "priv": "3476326144393184330", - "pub": { - "x": "4462922298422522788711301077640671149487080987386610884077317356313747587278274922553055511229554308642911107087728929458238030390328053305039156712425692", - "y": "4166331361209663080277908775030002767045551689443380649904104094047767422069625957190676222747168197864341871814070164924686453916110248521040648287862677" - } - }, - "50": { - "a": "1", - "b": "0", - "g": { - "x": "3526841193795042475472706746149302104479319317991814716511154371943217402619533559013289199455018742151609469798530459011064934359290058269305005770852147", - "y": "6717176849269195704898319671657351738994934261460853058693785103888428006927584989649644563176787348070595227750218564079606740227129140124956981993714338" - }, - "n": "4807115327383806869", - "p": "11685037692629544436418522744508054167282745075683333963951114538336503311896091970659888174669185217769701714376736146487719134933981559784973709552957801", - "priv": "4040249819685480161", - "pub": { - "x": "1466527626291203642492493441827733692299414093298124725156614801731872416353976088094297810392380176144498426351645671333471717057206065528475943181211237", - "y": "6552417402671779327103814822554640695446837969767667482775077050206682335288863224018601262504683488603938304696807511771370029474264413197914158855338659" - } - }, - "51": { - "a": "1", - "b": "0", - "g": { - "x": "3267199711920916068382989896497476773626172933101820659737975395054177436610723611881044090850152653690217799193954704381970206244579237161200895449914309", - "y": "1801172663046216945616504560716718964873245692895029091693186427056304450272172483757301760952623806485351084272296014098491704676025054216449233661159465" - }, - "n": "4951776012238716889", - "p": "11971564937725142819283405343102452394219517439200754177998125173838273140006904866009097341514436842653399766350815005672865218078609842575520666728570201", - "priv": "2697332072748954056", - "pub": { - "x": "8029055570922781997068925861526172224421716783639627816091029975112069739370649863950940149054934973985391614557927450496740677679026308718830752438909007", - "y": "1602626801939716053837744749626887002577837581116068515054873921829954905161054352599862173139179466561314851772116951576800443217651935171703906272161567" - } - }, - "52": { - "a": "1", - "b": "0", - "g": { - "x": "7622412265904735790820724331145536880745869825302538676187160201387756396703356170295759091096405122096528698138948171749042031919696117032628083107811310", - "y": "3538375182189891751042048643308526629143293454794797073670319319588710166560996649992384714763805806154167398467726209193990040912148556093458840915181768" - }, - "n": "5216282502541235641", - "p": "7925879388779818270822108768038895267533535400819446253716123243519501003959374444666474060360457012670942180897278261140356687371434584564816524729756569", - "priv": "4227382804860771752", - "pub": { - "x": "6623556837430211176716056285998438105129944636206613041325109163453346309568154499263565700497812782312007627435399691032717221155535887685349983547725754", - "y": "5143784137008935243415940746877546954904928787927831202191636787181715337470635194144636469817455076012295951914913996004499369538889959671269557189749708" - } - }, - "53": { - "a": "1", - "b": "0", - "g": { - "x": "9952482702654268996410178765652497590105592800065574407952582838585534879676909122255372769768497901699832734933374032257806046204765452502338245789575378", - "y": "2089340264888419262996854021383298637761210445052455642799587750065248165559506120835367654357551061138377729286193320086948280413270555247250470924892526" - }, - "n": "5068632114228449537", - "p": "11157014936597533577019045418547240616925175420814360521608554171517236939326924856555251208920173226882496853458122801623011764787655866100297968178218817", - "priv": "190541113341533176", - "pub": { - "x": "2564907221347665920571154160633426030926627289520132946090180496419693396052978749696275133983838854756474194181054881535849242976180540032615757743858664", - "y": "11135232968162438329449039042851302679976903318047276891184960732245822185866013956710495287987401311857788873227422869430044705095334454666338599981024663" - } - }, - "54": { - "a": "1", - "b": "0", - "g": { - "x": "8059057663701168311917532277618827622978515614146963913097592614451721430413021070395782723330339842826599481063797559797462512297834269467666807971588275", - "y": "12239303830174753191779705979220378623394732267536997115625979632402312087683644927405756146495100825573682155171145924668759419114616275413724686284123408" - }, - "n": "5622613991231344109", - "p": "12509642519697332596114311053544618620747009389814652225369521188710171926174976419995384745134703589248167610052719613586668754176591418831031596093374569", - "priv": "1285511085175426271", - "pub": { - "x": "4895832170509729140211911021638266775170167022247175324972987673313207244495397975379010973250279668424167408883454560376269866102669741515127286188717976", - "y": "5846013328426281815512452704859777850382010968846722453046994319336479079120767834777937190955827245502389471872759584209649693396095099112777776298051208" - } - }, - "55": { - "a": "1", - "b": "0", - "g": { - "x": "6137653643168830977493573210341261465614717541921335765523372705609926302508920096270972687072207085694032599882927761142125488149401308120243169594511831", - "y": "1116692611626831133742848724362766578952477258876677112469932772196188227734342324552510753173867142780554261113662225363186253941732748039097098530448548" - }, - "n": "5444298836290678541", - "p": "10473306979012881681599188179078055086202328584566380482326833033628842931201028832804536290696826411363117488736195190074394651481452738323121603833156393", - "priv": "1269736890689062509", - "pub": { - "x": "4650623170875348523909607503639087653206390152378362042092258123447605461422798509945586046401058248503903342542527529157200711973543052628162388803719398", - "y": "10209840516991854949532155766444249093210770154167393071821363853671352167675606988017873164695500762694003816658318382717995295698876071542519382319020114" - } - }, - "56": { - "a": "1", - "b": "0", - "g": { - "x": "4960509721617945458368580642866379390847536765961244922015383420768869132040210857829564768752090908952758141412640500615309020011921449898795150440454796", - "y": "6595393361357022586831971492865283914342750798336886829280323806253981918924718005172662662919610648909340269043560986140467143959921319064176595716361953" - }, - "n": "5333056788847795741", - "p": "10131932795474437184505182928744955517005086247201546618805324424467046107439626954231777165370159951509101835472273379651227025599794671329418251258101177", - "priv": "4434249883815855329", - "pub": { - "x": "1172770485180406289548438805489238172938652458752801449695182972933434007863981252403269566933414708278679500279281603984809027281250560419216232488166837", - "y": "2561988328479962443364330380985679276129147386565252171129571526691430613594881953076301762095577025575119091407014535610035223707698926746396065558904243" - } - }, - "57": { - "a": "1", - "b": "0", - "g": { - "x": "11541681997138096947059640626217256335590010810015558957838660670384501046708958294153446537000814645116210425008185588458637119407531965013915606791038597", - "y": "6005368336897383946053712133547710077829544935400386694181822584125711921969692732827743950232469716934494993598230897850139950250192220599418378965235256" - }, - "n": "5399439303627927989", - "p": "12102796718467692453393852465930884217844007320684812308884617565201361577388880939207166958041434281709858488170378000563611988660191912455690313966830713", - "priv": "3340382106648491124", - "pub": { - "x": "11217839428734439950250846502958285418796433074755015191025889840499179348300718532677999032425018956425097909824357545605039703229610248933943518855035381", - "y": "12045087024656444440025664129912564518274343657610388544448667822205267635282339158360860157892456851041737779849075210151838188206611223153390103433592663" - } - }, - "58": { - "a": "1", - "b": "0", - "g": { - "x": "8742479617325365073355572723061403277705878162662090085419647857915432034380838884182331045627427771471661809818973217557626908626797243120105686889125887", - "y": "4235951710044065849027617251773612939317435651015789506741050253822884117093183010776485855057169964517447282572222470621911735555961845433658291584164463" - }, - "n": "5632003721094665569", - "p": "9794454636358384240729895767279977229411020075953528253025660757706495888891542340141549687900056461171671162700846411279434700622389478268943659614689001", - "priv": "4569149016723904366", - "pub": { - "x": "861387136531853706537023734435981260159262410289774525420990873996987761730100044660206239430883455266388013756147063972578354965346307128057844416149200", - "y": "7006975557159329326301638217355249420579171811475090662347327881973009565148150044573008668075655637434737840171901021724381960376666293775087295388354880" - } - }, - "59": { - "a": "1", - "b": "0", - "g": { - "x": "1417663295731126013909990880111775495435125111962536211264999815422597907850488587287793516589211844302299750292063269100350848366980318854013463075751378", - "y": "935248870941618189769759304588309714371580820510747066022529761211554467706919006457613365052383069887808165157692794593847449611638544294811063776773382" - }, - "n": "5086902831860639641", - "p": "8587416972080439597425167287409941311633017835994180185338278272235877764956176312565471862127626538620260312442279353344585250964695020388211173631645601", - "priv": "940892107441227231", - "pub": { - "x": "3770883299109421757733272865094182741004210105753514356630891710708138803345092633429903953978023199657510055248381198176379339445968801566102784221151673", - "y": "2743718531534495353553394212022116390060244446562081283155315109219186360933136452397969294839568512107603607659541951259553946359620734065504870586958773" - } - }, - "5A": { - "a": "1", - "b": "0", - "g": { - "x": "7001153264502603531568809091006890066238093206490706740054133060198019760090859987689015805782317128823647585142349315457499198272662472818714043462452903", - "y": "5379780378477219053711555876878459214243674711784518156355184015695786277532464885846858297098947964642836892714492422913471742703229817151186461774623684" - }, - "n": "5532044755580494717", - "p": "10562920556476600174223203553624763158759224241690200395609486946570543757980521851146458516500451409335864053457189473296570712977858859585999979839497081", - "priv": "2739897280441110808", - "pub": { - "x": "7581054250900465100241221249174490036171686256743764922844514529943814922537182958165791392786846977936233032863941877071806567396668766127251287523822606", - "y": "5631831699091940711241625425017356833183657380411816572111689187965538416134562629982530928101557014697032032310481274355673900378431834102530761513288622" - } - }, - "5B": { - "a": "1", - "b": "0", - "g": { - "x": "1158043681401850645625830922140272354187157644535098167256945413239268444756596404093980140597684812224718936498179974083785242935482636867615430907732743", - "y": "2935477974787981099457948141594849481501751203602641415314751811824686325001189713561611058862042518908337169145979490701235192442660449822820835501173361" - }, - "n": "4755964586330124773", - "p": "8786359934102436514978633891417766562160259052658042986450624118174984340932692337605038359551515406656318478331505297030190099751606005463323705066383041", - "priv": "174180799641457829", - "pub": { - "x": "3598207233336049755728485345402267878548216656271945302547031834697509569776838327330257694878049026614613051734265251666816782052063705326654727444817062", - "y": "2046662222697320726880876892159943082141709985523330392915545357354983340067789200377920213063865545819123049344758385363747768261733207129824387682384210" - } - }, - "64": { - "a": "1", - "b": "0", - "g": { - "x": "6836914148383934523146386368854061694482882241590572738072281748520254317069250149078544973771604009318755611825773273277880011366390637667689995875645091", - "y": "1869210086814446552295647709671922572129135014994039637664273303812520716058868595903455367090271437468416294440316278321798763366666170148258617435501026" - }, - "n": "4710798293276956193", - "p": "11140292070079840223478293553825852579756307272457526758455407348073991859638132039548754407195116517701496420375917235366272153337274234749677181046479241", - "priv": "11731326262766101", - "pub": { - "x": "1989960177638374390878377737764297057685259206834686428253479199374616869742150776410973898745805799780071536831208959469038333664656928533078897351495263", - "y": "8459798924827836228274277115421121276552682139164077587322715687363649243379655204356110674973206099056049071356775561545965708750027069182848722760722623" - } - }, - "65": { - "a": "1", - "b": "0", - "g": { - "x": "3184985093531815189317401154768914988172000526379795240743456474818808085243678222504237337033350058066494144434504516171465736405092312932621770172533416", - "y": "6559725745443744013022481558427427919849356820887924942341545986134010594115539133944463128758999861888489753226817866803330838230286140442843910395787000" - }, - "n": "5152953887135671777", - "p": "8746268412104364122590401256189368799957614918213941010980730641301654439417858210084651300822541590941125736513089898460381962115196275652326003031278753", - "priv": "1583498175279647618", - "pub": { - "x": "1352684437800180652923489312266978423036610385565765573158589347735420725101578006349602521095214805062717085612934589919983819276662150493306485984087932", - "y": "3751555619099816469086075504660083932492953973123328559493047041891340985823410815291323694826579254584425441385194091897267373260401958534526116601202095" - } - }, - "66": { - "a": "1", - "b": "0", - "g": { - "x": "4248750365494621170867411070192250347558099282208077123309800561812392890309089650248112667099674539292841781223825841114353470559078798216015628807800405", - "y": "2363135147862625100780290668425392162931578480024321108046638130495288318114859598161763977525672580224389087872093793892799021710732333336562239007404331" - }, - "n": "5470028972637037037", - "p": "7414450614060932787248839197458070896684910960804177158392134961003575366268790629245141903395927609515264078025359653122837316120017343739991702588044217", - "priv": "822304248535969741", - "pub": { - "x": "2533341772295393491400808023462145665845043632064869971512603543404657302513574864471005505089780300953060578102587786092252155788924277962864392102891310", - "y": "2853142146312045946205021435741931506513454835730828192678723851241580545655918715491324159683420265904946172614320824838207026955146237265100158801292103" - } - }, - "67": { - "a": "1", - "b": "0", - "g": { - "x": "7273571546843413099993191994471155206649636421268389195048812757571665656628711965470673099293494650775090608549703675296316887753017258939382696588767431", - "y": "3529068830277582088596828423990199939817342479929127252014627303069162247307070606247527579307935679046819531543049464667736359244475241042487530444236684" - }, - "n": "5092684937889775537", - "p": "8245498483844445086274997696534494324318871629323439587180432555305925857658196874670618312457436840885370130522487176480691396150486059031119600012524801", - "priv": "219689077615411230", - "pub": { - "x": "4722272800064252767454697391320635537092623053473493936821919057777751250795528775893773028180225310055317957128183947713166125210509990475635070787240674", - "y": "1531615552769437372403026851115800774961251901795490190286680044124146107960174759313522242631208697837075037127449543341158979848323485793132900943144563" - } - }, - "68": { - "a": "1", - "b": "0", - "g": { - "x": "5314815905585889296798694589942539626853861931198694818603038996528084849226860592659970116239143301533686664128842093994835269693920687751688904127888779", - "y": "10414790044180029072298701038447244079242758942849978521692070049764442685692432822170776283556203601227171463278884193414648621672635573015724449767555202" - }, - "n": "5725875683522971721", - "p": "12826772525868542995993863552630880658950068926652633231964092210337092764237251131994848166209877304480048932720132480186262823567355089380901269920285577", - "priv": "1068281577452339154", - "pub": { - "x": "12033418992548426346178523393578748081768559116860151229166249264538780301962627440762898922271298713141461639555947553862212449547395648972547457272406904", - "y": "4032882174174859318365824908716254483866659322383072417928411611598186762680107569672924388718908325415355049452875792560066378636581873850483566463440639" - } - }, - "69": { - "a": "1", - "b": "0", - "g": { - "x": "7173096084863451615574458983860544861871291843691257280899194149874765254047059142205262441857301868057882685920836271904169877920201774602904928493082466", - "y": "3685411334779977585663385448619770855951447093889245910985895498674988632379639227046444801656846750232784910161110782562016802517178353986707750695901040" - }, - "n": "5293859400497927137", - "p": "8380779820034448265154966159054835477696357572828327273565364892590557383123266250688404613890842142510687380806967918444847122708322525769781340041557697", - "priv": "4697401303693971213", - "pub": { - "x": "7654344525783880004912076071251050310876900359019139489057007158425701076455194924956926865732209623315247611882280988142426301468375261779854585638959095", - "y": "2205301557007321522756388509630157773456414780456128615321524979273286030768187976057798339743808057683824812565389382337153729181012589332286276647781278" - } - }, - "6A": { - "a": "1", - "b": "0", - "g": { - "x": "2744957132896381114963945891295215205203728671990014493925705047714121178217838853986058119398256240023016028334778647494011445381032260909481773595313104", - "y": "9242294195628493222617132679668272569113830601983068223311165579910885820963605132189116485762422714509194310323531771573215902015458871867031718940322344" - }, - "n": "4995269645533546733", - "p": "9569004333820764429459736949042280192002465065550168669273101643623459218410127778464060806179272357200390786174505285650425094011167595140853477499705177", - "priv": "4930017689226852173", - "pub": { - "x": "6042785424053265014481463288895667418403822173143764604162744788488127048207530937717313691222743805388834807415369489831117511798799943397780120043080908", - "y": "8129822965024161524487640831481569019315716746596951562838078884933023842144211446024042763464925599297764137258130591164153784795671822215714895806126168" - } - }, - "6B": { - "a": "1", - "b": "0", - "g": { - "x": "4771924757248908953392581157041419562561060722669620884301556722064119360748361829387460466124743194153082874058153191937600246773960768487475418732779735", - "y": "1921088418563710749755929251575116022515200070039168455631128090489988043052648808257919406392722204985860080786583613334755486454530724103143500609853540" - }, - "n": "5620476801810334777", - "p": "9200460722050362824128880874816963846428402133419587821922476691953499459138143260210705158151240733355428926202827167169183937677184899240672757880666481", - "priv": "3057923709521373326", - "pub": { - "x": "795969145680176830672700542020303991843545662981440678625855632938066599249164534703534071679426766547821556534491022316762303140598446657621887094211373", - "y": "6398709334040441212263545262049174071760680380022912073125188594335767745140265265998221067666818011052441785423830100964850376745023039032296345317686072" - } - }, - "6C": { - "a": "1", - "b": "0", - "g": { - "x": "3193924578749149973349715439708853249371533674866738373146929732320027236261541739595179638552708548249437080416228471131201918968064263764697554111530165", - "y": "4888965687615736901315989550371141796747021791887255081237624800145952769028792494595799455118213679617455373330584340380954501271445892269198650215048525" - }, - "n": "5716362938854350473", - "p": "6772644826114336975395521564093976272857924418773374298215345596476892260493496637686700145278269579146144605357425079537260056407908058166728104826706641", - "priv": "2077245658215532950", - "pub": { - "x": "268695446123955264077019637228932681884538989037732941099747311674045562360739358379871180345850032196900336613323005578507597779076899979732110092466639", - "y": "679259663772569453698820219709022062154214038591908789527736008819910024904428464410413122647073108532832895523045487629004791793096766249438993506680831" - } - }, - "6D": { - "a": "1", - "b": "0", - "g": { - "x": "3298099620604059787834899492662174917598027267355370357344802081588599421345170581026563084037203023916968294761623560693756892912943381721305999449177880", - "y": "660070182381517254140291291235766825707865896406148611965367756543311281179754720142572450841218027728395896039015649326406436127710908614699312486011632" - }, - "n": "4729400334442529957", - "p": "10949181517511926903567022348751201958461013848233333337252284131793670496593568885605542253013440341224349881301674089289841680074611115257051662616691737", - "priv": "1917167729222184576", - "pub": { - "x": "6148303559806694802720175134063952680971862197161214387714553406366855716527344657113993997849223962074971349265039287455185887671146559993479377577325902", - "y": "4457002224085552970249907174802329661250245161967874670366390075435589489905320422633893787965164168305287264752277411705970075802880020100425352544173375" - } - }, - "6E": { - "a": "1", - "b": "0", - "g": { - "x": "6293451262500559701813798043459260113430548053466045470854903125080057224919401031898266214307842807651009391720013648728979854789012991495464126126839422", - "y": "5836148613114464303352123889645136044752294410204542326732877451461536676115565327431869868290307347722144018551412081044468151899437337237630579635928057" - }, - "n": "4984104923219751073", - "p": "7383829322181609420717643550498284301822762121957563996751494118335844678856686816650259340126344543602329395690543893002632342847390262528563101453631249", - "priv": "3869546352939126828", - "pub": { - "x": "6720998227678997862056065758423468898696765396061103319165320094892123609873436621956927659616430754429175531680314970144575484170937282114734236995059907", - "y": "2003255176718186448340845419020045861110144816399942495121761020685163741410813659523959485182952080618589282628742821716456883221758277320065970072749767" - } - }, - "6F": { - "a": "1", - "b": "0", - "g": { - "x": "6464843717418133735350547053515475778344693639024297083670152453169368890450323923057570219956033906732739260071296584266078403106097888400759227671538840", - "y": "9802365608931776066980581236074358226130081342122326693663228810170194081027404376238454288409068520245842376896956013827181454200170072948973188347655629" - }, - "n": "5064326794500099449", - "p": "13069794699791756704189283477531321752185768325109229180654706539216914049959643607566051851562718277740945064072928161942644694593905061043501953558640041", - "priv": "2856600130016981227", - "pub": { - "x": "3608891578799420548064242341130979159300986828365903896199916298549555232779496232070487208987261916927986279752225486510247880917695587207797815410800112", - "y": "2722176554008414613022470486740120254761973593863438540172205830504544349495719796772982904061412103055237821871522377038358032426309577871539448197288775" - } - }, - "70": { - "a": "1", - "b": "0", - "g": { - "x": "5389546399497383505643339185027973574488379777748198998812201639710214387213898471104888496236804736102752583569918015964707826425506327644196688351201929", - "y": "7956467826288064895206371560357238846741050185295208711880364013302186161614207664511000208569082078103634173071766883312441579579905542193148845869579143" - }, - "n": "5339903025552992597", - "p": "11383820622080743851306029214182718080855563154181355541498743853491046043538336594620813164814051012924415120005823675884185274830944198875192726828265297", - "priv": "396641423549071325", - "pub": { - "x": "4695611003072950439490860811715007879669129845556910215314788110597779740229935282258327560673417982491463260121432416602363485729459649143131110127087045", - "y": "6335169977515592223387188318936371046908706559452644346462225122927979415760150745168231518170807631192680472992856055225104388051689747313878588197029948" - } - }, - "71": { - "a": "1", - "b": "0", - "g": { - "x": "1636919066913746052919832040843210318286730178861423234687788099864972104581671124532507524370547980246596016229405683487682026261642777380617823294738580", - "y": "8466487901883777715027363848813212395026109558207810686428710627247536647256020781313531181797195083740547935858952610950914373644884995559569903061264334" - }, - "n": "5306514456935955013", - "p": "10647285162554269224437695647724644839843119123293152705260470723048638640392450736229016524149520637767470359801248882235773639225623705965188263473055241", - "priv": "5088986700518482765", - "pub": { - "x": "4444462983853636224300903512995958460050188507254806791191791256055298236823091859729120712412864370200152404614754508787290867455001456826342902700637917", - "y": "8115568718161189589702153176147580377339781121652509698822568933276726613008898585419859020450085118727653691169373824943918335361045551596156823965167303" - } - }, - "72": { - "a": "1", - "b": "0", - "g": { - "x": "514688672916436233994161866794460347921004624445336466549889111949979570458430209143298647816567735934205299740808658859954412673965256662874089964210056", - "y": "9995294546745646065496072326685156090339741118925319171191813074822132326973469946137404060320500451170644477034799477341018109266479655922066570452247716" - }, - "n": "4681756002846077489", - "p": "11576556656529186012421026869176068822191939852961823815901517714210326929093532615739621005695997271266436050043753102374986996342830833622067589326388969", - "priv": "4510257164279549783", - "pub": { - "x": "3478231313569920458772498793879691471856552727322308910628099351215228445389873416888062579522801351494016192730153657655217477112588905554343210299716517", - "y": "6500875161578073640589890408192252366627924611095176220733269377679556071604406317317453082550115855496867392114150628212712970033976710932220030432101519" - } - }, - "73": { - "a": "1", - "b": "0", - "g": { - "x": "7493988628096968862823664823307296783957265442603866618618110868279206014282889488854546016472649128814479181728346833784499947792274520912736638959612599", - "y": "1237214294261592141546045842651756310953944913968748462046491328891515990492280751925199446437305837893595738492220539506515635435706714684897596147387195" - }, - "n": "5086946079577016329", - "p": "9343318003498310132807380534256947890601710761353122442766185787711033046735551269634576058634285039774281723160183108444844064019859933049793739915179009", - "priv": "914281843730176555", - "pub": { - "x": "3382203590685547085271879633172121833516414567880372264838009362757659475490298146019913769048698446555922621211732738922717856485380323106216905509276817", - "y": "1000610561129594778538440123955424526230678540958926156884965335647173683312264329023675614706609625010744931986109897483719101576592262078903431731273705" - } - }, - "74": { - "a": "1", - "b": "0", - "g": { - "x": "520282615406607935808830413235837609227529008118239433194891765554084261177667142590192616462797266047427714603514505726507565809100858610756034340614180", - "y": "4557046395510954851157569206449480560848332315791566919607580280750304632075435589109908909351625686398512699199297926705742962219032991805095344264722444" - }, - "n": "4633201844252750473", - "p": "7181106593102322766813520532476531209871483588988471009176871145241389568314039093657656718839885029493125387894856821599452867350054864568294961595970889", - "priv": "4329540238250287790", - "pub": { - "x": "1748427561645745685508888890965804844329037567281415535239953290167653001827496844268667372126127464466687812723744919132659150838866693283679107969476861", - "y": "6808711632346399211426562555523956018872055718394662707289722207520029794097689415773036615424757895159410496488301598927496012713658489637493990459415502" - } - }, - "75": { - "a": "1", - "b": "0", - "g": { - "x": "3970421503592305806162067723385709415592786314716896691566248833585082875504539058115488199826473702792925925118152558094421770503793167297677060024718927", - "y": "5554883105100816924956214909142063182467429753687518086358166201697075386873889702658647183787469227480685699761636254567290136343644815706400210445911313" - }, - "n": "4969620768775003333", - "p": "9367329192536614353969825571614784746581688133872824941332015624935819730507282545479782208538086552891932718692035451653750509854673642536729217033200809", - "priv": "1900542198084112697", - "pub": { - "x": "4353876892698321681359683809542869088530852337838122569824839215556706068138042362107206144376439479309074833553075054210218907784959548685449627846808344", - "y": "8262695428675693411183184536456322786716473350154493786858023121139149995844800363332075756178523197170309252869968129569021002560420175757226928859306184" - } - }, - "76": { - "a": "1", - "b": "0", - "g": { - "x": "6326551563910718268860528254182327162091771902430601493531451083387374814208793911917707468796597151101927661333905356946188279766917640124582958309860223", - "y": "1070939833770515876953738253775279333650953871522614246378730556569847770415087819663060576674895214837309111371821715690161251734047871162684076823994031" - }, - "n": "5163299747175235373", - "p": "12708432680338950663024943793859785104581558550873132176922502140944191572407504723280648344247213496510204818459572682343834733112791489996438713040722713", - "priv": "2660955595284853684", - "pub": { - "x": "6242149072335025632559475868177651014561453894178094117010887245677593679241492483284846487839452047063166275673350473977054088557780944863637669565510554", - "y": "3760738618343905447289077838842452118273372656125827633914088045601193318654337590272033382460648605110939282289108926234152882071866300411987249966508392" - } - }, - "77": { - "a": "1", - "b": "0", - "g": { - "x": "3441050911814020300444749192946516202643066958085679688027527635336078902570565357794034613670626857779733628280400414152126780414764787508880467081860230", - "y": "5189320347313561973406198020606711527037020787040344747711023973754680065919420169373815221081012403792484634209797912175185428156757190356384386028903758" - }, - "n": "5636379957395702917", - "p": "6808067327080679111966513889587167521833452796360394631731514300074163927499269804607689186677289253368624547532395593132495277053846962051715214181067049", - "priv": "4770366445246647919", - "pub": { - "x": "3784836821009804623908562657454067031620663920795503120922284803393053289924770294999614270091654880731937397954708819499104008236108939544584465970575657", - "y": "2548919863312637994982110323128716593443554585384998865096038925317491021809963517729332500037065987812015306586164359013687108554846531794456419424978166" - } - }, - "78": { - "a": "1", - "b": "0", - "g": { - "x": "6088849103151287598200503614952681450041235940107949935585195235760674294068839175308064812005993699240723781065167790033914861747640550740417495607524878", - "y": "6437044994712923133562556419973977745775332692424042838255481451539737092550676452397324770744709191355968135868892506010949492147308988716192132134358758" - }, - "n": "5665947320131757957", - "p": "11487665893367899222355107344421070168598636715559742001518755192280067788122295545642125078713810151473262732817187528724738814802926117239350729502549313", - "priv": "1638384434777494607", - "pub": { - "x": "6817164663422195178935018212244470984673598663732878715315353947093076546158158779927934784011339749197794005942254786198555667040118869215996525225725756", - "y": "479405963135164984275171241854667955936410731405160278776735030096152430051382537471685764957967298232387289150592192840276297820432357414249749375873921" - } - }, - "79": { - "a": "1", - "b": "0", - "g": { - "x": "4168032131084289399335071645344208509979609398979750639892803067976802982383377642994794290997664281252255327088446719315748049734788709518142590431805660", - "y": "1656209550366422132691297571615381854289591319278684544108854043570071112749978525132034103704697219285285628389328976303066367524722775405286718455955564" - }, - "n": "4960271072399676893", - "p": "10021555678719333461534229671415111186370042343731278260845563503712408730714909065839911647708728633864627592037548672867112257016466864674007767253922097", - "priv": "2358235241063744504", - "pub": { - "x": "6268444080236314304093021923163692883947231122425324957435993511331396945928289709553768144715272511191776892202607956944672817602546659847392056974920413", - "y": "4521790106135273903362564196182573571911305322710028936326839181289858330729925650095457264860694569235728467176857352508520633869306739331785585988490424" - } - }, - "7C": { - "a": "1", - "b": "0", - "g": { - "x": "12595907217201908356295407841191662128058183862583575051215311157290088461747744112833552590366680246352682673545573818921176626985849350979877835633501977", - "y": "4081991768131203059718114067775041458907360041704484571923047903596118063845158964417046054534517243002541376413074492688094692161600554230539596132297166" - }, - "n": "4713366068048639461", - "p": "12740026520322163229338101893927031288254298898961140709601703660346758023771809107598270422219922815511074525617226446729563727652140299854867827057762097", - "priv": "3645140886299655136", - "pub": { - "x": "4170165600612835816072752153717064792837383941694916018487245065025874460597138155904045581814180291752254925515125393268789405330284361917814339072483163", - "y": "4283440682806037636477705431155033208671204005459162418818595162913967275642251903764442509383091895637321243673549727387249130320635242869060716707502660" - } - }, - "7D": { - "a": "1", - "b": "0", - "g": { - "x": "1590489240729454536846927296249670028298807614755534958905007219831873392287176796614856253574534913794562411622281212983602673653939841066950081049752496", - "y": "11517876747503444279939611612149114290500110474847041028675128176427946481265362028336760831240812613962174827348163472218433846119323659870013646187498844" - }, - "n": "5294246881599156289", - "p": "11605813619242976573270030739417432742386383152135543814151806150509223544935055861898978057855680549288259905678657401053040643579124366975449696646547113", - "priv": "3382444905344124117", - "pub": { - "x": "7139013373449136481922723685952126978522016553107297658292982499195579631402843387844844515956102856833439560057624352734539807208111600469232003834742726", - "y": "11564220690727719123783272341292762734247468339612099884983311964463919067661268492589581551223830761015103439215183156282987937329176448399493410863081658" - } - }, - "7E": { - "a": "1", - "b": "0", - "g": { - "x": "1575309437054948209501943095287709278853331993476275043905717126838899378449873652295206985577659276472511880241134171582107274631299115230531386131157999", - "y": "6650274808069442841806032562188313712099529938370090595758338521093982842067346153375754672029991541735693798661861664375806224952650375004336458985666606" - }, - "n": "4969253191813446413", - "p": "9069158124012783386919261859891326104095932201604665726925475589116835230298742553224266302713449742557574534803913789744550176999999570003705214704390217", - "priv": "633440952939337400", - "pub": { - "x": "6737291019107330377138239698781147037798498698085590227826737297136831202209658011712450579352335182691931564512305715765043903899386154655983121712134496", - "y": "6478740397369612151863528145504753617290168688973289065350048115368485718043346919007738307138223600887324712066864911651041752553131216074853313955876490" - } - }, - "7F": { - "a": "1", - "b": "0", - "g": { - "x": "10741485864258239198808785058735575359552883054178990682157071986056378748243908275065774911693686879557176115248830467599801081049714644498962624953002215", - "y": "11478849728134996491513678201481114137233934272403186543739198184491575177652244835264134301889794968575917067111000421718189993813699108582748277627331424" - }, - "n": "4717216669495499909", - "p": "11629054801211706004419443560137925342280675682563984850356336001042892658038876793698258083522548784740766252109524130264962268004130304432618675290754433", - "priv": "1978738820593283754", - "pub": { - "x": "10365357351159597511691869898607967487759410765693427025769355019639442762848113011873038330791205382321415453886281547469084230058652569483640290427689765", - "y": "3630424016244283654991032347706596357280799286722217672143586671366363275733536816197706717283628695319640288198134598259206639481908864297539186688658667" - } - }, - "80": { - "a": "1", - "b": "0", - "g": { - "x": "8580403238882100235051542355383721701957907551038579039606823679429370998618477107998272205809779979070424836909055332203760134183582196032565738191416290", - "y": "8089518457353381291703015153167928502980155426796939360253964740120600669024761032460910890439561234792725982282867894017503793419414413700802430009921348" - }, - "n": "5749430925149106037", - "p": "10346760583571096176856644232540829964140154551711351621271787144406751946103364695457404414101548368379536264694684184927538790127181041198956087282638713", - "priv": "1645776849061114653", - "pub": { - "x": "2693318663394724629536224434719920577877813174957928953548110650108753626458451559742749689181138903486875892329303418974795190532736471941235039052866017", - "y": "9731351279101954720322874114402530628478997829499955147172294887000756356675120252590103495090489444217180061611275014585059693660157883498077947452829308" - } - }, - "81": { - "a": "1", - "b": "0", - "g": { - "x": "7437963515044744382041063003990186061951963674556830147184970263069293479283937679956030294774873724521466287595837030336839893434007328816593628527951139", - "y": "8119523013457518610939772676897260374300215324174888451710880106546482206568332630653184281728054177911608701029171061542711266521921027618944809700269020" - }, - "n": "4664659198522599761", - "p": "8803652642367490686800500812152951141533039658262067265584900306384497036408043913960439010879485280456295963028944969684231373465236681815575854801801537", - "priv": "679507843451681370", - "pub": { - "x": "5985625186844163955999843168360558757526930565271797482532035434301622557557888304828323051687996364196567917002859433230045770986014082720007536379232286", - "y": "5095137563952044397893925476372801628807819070844068253860097589794304444869339214045112157290439689311317894679583840560004967976871983537219500930078926" - } - }, - "82": { - "a": "1", - "b": "0", - "g": { - "x": "5227772111321015780185186378724461401389838650015203302651549706092755180467439665164380531103769615828715419899860401082742849422956824981581313597347874", - "y": "1151126907155345114356142690744246053451710101245891176496132941203621694723865469418399701772737205845553807980389383148927963646671033999895601474687519" - }, - "n": "5054413088652069853", - "p": "7296578671400180846340488819765224221032599696154274327503058673792604932489024645402035468500749839406774778822529582585837048996841112334675208148008273", - "priv": "1518752543107066987", - "pub": { - "x": "4943135394525378761513066941942646996630904108674369673596779077435853058745531048405707407834162897708884740422690900167561316611219129119275902078074219", - "y": "6735462303321596804740537199356216806938426989646803957550767635543166255178877986982448754493882586721252959635808383783210872383900712878226874328425289" - } - }, - "83": { - "a": "1", - "b": "0", - "g": { - "x": "5695095101976550933576792098222206444121927711857099953946493227368612976937692219148904832759052785374432508483206550560670798020904713813215695847589801", - "y": "4784422034620378423461700755190489419946091495999011373191971887281563234726587597967924056781298693580929934196186459792215137044322902158637883848206160" - }, - "n": "5606861943932384357", - "p": "11870235722842965793915717289164026915525574991697293904376629205435775162253052338892386378423782853838596832972630793988864239781894306253881693229739449", - "priv": "2827273490206920704", - "pub": { - "x": "5798013553367225625398424944951648719498151375103154272402146280858925589444004802702185901348087197531033136089765892317962373259242520894688005737863471", - "y": "9951766927130077074693523962049666695328886664964251829029028233627647859185002333988456603917629184050956057303841353135661823086259678507339936694140074" - } - }, - "84": { - "a": "1", - "b": "0", - "g": { - "x": "5560427793695630869020488047042192811305372437924695179205785948174621879035697162554246234811767536148226584483155664003903180522305522332791117231929666", - "y": "8363507240870059025148603462375399778510363881280730362369926390337468582944357036539945658952697391101011344937374311682301614715537178578854285685197751" - }, - "n": "5278662156374609929", - "p": "8510236036207253068508614967428092266661773054007334596390902004993409037244437599270481895235147192065946981872962110815581510080900322230030613433609929", - "priv": "1460840063674431942", - "pub": { - "x": "1596613556377662160548714309781670944367097433768876984270422914199277552144598881727442116643470093788384843191285815571989032391323299101906136701074247", - "y": "6779226255898830514962686943250906557829410143670351051280134459463818406443572593281528353692074367536339902467178858221068918742809756956394043773888481" - } - }, - "85": { - "a": "1", - "b": "0", - "g": { - "x": "7505394603001954455294446586132986541793661313187851848400138712640114877635087676739162227532381665370139572899712018167266674761334262252602951266506818", - "y": "1680934674915492204617657824564571651266351348781478568848386763197847836921805135275742806664744209970767209281144265127261059782147782754056266540269863" - }, - "n": "5570981815749140209", - "p": "8732795211981967719223853752484420568831774283007885254650070724992722784292199925344685033347762258503637529768918721006025869309189556401554954935365617", - "priv": "3812804900780147318", - "pub": { - "x": "4198091971144571806535249777589229216025698044556471495675027203140959357482044604829990385570926652328279194279219793976552272247701255490650281936560485", - "y": "7376523713920169817088204303475736190857293501666832093768268558780265806170011129510363866615123592937684499422116009654937439554855961356059515891735709" - } - }, - "86": { - "a": "1", - "b": "0", - "g": { - "x": "6703694613653843120011692431117258849910799069682325777498755184030060953999731560412255683835043874631157157087206805847404428652396182573664804587133112", - "y": "5277626791685622402975349130840409135234562392945730176174183499747960262261554444679677984020548127978314810292949910774355538747468714862507226400578050" - }, - "n": "4965203940861890461", - "p": "6920390285079512273302696404582911972264578475868268336762086064690280720220547446570404290836148341928470331899722422605152853844455708186803401682318609", - "priv": "3630631387672505590", - "pub": { - "x": "3478488282863377607849104510962918772905907619241086883516775385578422433058222721622377015359616954614527499756095170836870833349744894938045767729374604", - "y": "6516229707236511212709386515668071803217486988049002197368773083245438043750468395538828485641993141409937876246800956189497344080209589752539139161857067" - } - }, - "87": { - "a": "1", - "b": "0", - "g": { - "x": "8492237021199611805216211235692828503490134263808640227201471417783835722620711359672191414279197757339092746832374771649463193205606483563070732207239103", - "y": "9066857546008909834699517292838576515096976755324771652036838427393784614802721995536572813787704837591635506894617712897267720603865495180642056286777930" - }, - "n": "5395913001602193001", - "p": "12003791098642037621560892862199749337206731482824811053973184067477553933302251555963517648909225129426028229957803674277229810351232349352687771411098657", - "priv": "3700906348658367772", - "pub": { - "x": "5775825242226756571502583787399598340972935199546526848543059173637629885244704205615625248092598199469055373643573971908421374152957312277973710643538365", - "y": "10911683546275695747340854250863118879557596394002273165043521944703658224362918974724490418230578464274815505046139470607624648137251847635946257817835207" - } - }, - "88": { - "a": "1", - "b": "0", - "g": { - "x": "4613903814166119429696577406821167971645163774499019682043327030213494538193533493049691578856679354333108466765986838529606605477163191099856754482133624", - "y": "3521468031000279806241876387398981937866053227587991515566136905082530906473751110192089214709190433958327882109862961460387650131889271308175622463720393" - }, - "n": "5128048066639829053", - "p": "9639141353904923039979046809026012240224510644742503259454894126544223802678735442941322199545077147700061934760834787308248101230365644459023150446592073", - "priv": "4304573455044199124", - "pub": { - "x": "9115943070793793803217108546177493293013456009143806171877810710292493847846923418474866643754633777121093635194496777485003447640027563970977306732858130", - "y": "299091567560127519026074100988936504880710957160222942376926725629153626609589321204043645296136878702192317324679172359631365142213939438050305091264565" - } - }, - "89": { - "a": "1", - "b": "0", - "g": { - "x": "6294301350876969072049859821523351247996356876707594294091972829683736926378761574970824207105787060479701683177802567747400920435316295166884106436372464", - "y": "7865276036147040765315639393821914531861795557520800252404014078372729976880891252631787770100036988799613474283906061454839256755579930624307713972233136" - }, - "n": "5260598915664139109", - "p": "9788455676437959684897980727280589939325587387415117741017124676835427061115080584919771672642444455807393540858421196568448000473956486045538255860564609", - "priv": "3166676722827298860", - "pub": { - "x": "7054010135762396846749770891818718069638437011522328604158065395187521207404324203344826428948442924552015830577386735751163813940938294977917580839175333", - "y": "6907491873002602436260770112009167552099295226221829271071772648575964850189443824766022140586160426909373840561095003562834548795561414117018465995425960" - } - }, - "FE": { - "a": "1", - "b": "0", - "g": { - "x": "10692194187797070010417373067833672857716423048889432566885309624149667762706899929433420143814127803064297378514651", - "y": "14587399915883137990539191966406864676102477026583239850923355829082059124877792299572208431243410905713755917185109" - }, - "n": "629063109922370885449", - "p": "21782971228112002125810473336838725345308036616026120243639513697227789232461459408261967852943809534324870610618161", - "priv": "153862071918555979944", - "pub": { - "x": "3917395608307488535457389605368226854270150445881753750395461980792533894109091921400661704941484971683063487980768", - "y": "8858262671783403684463979458475735219807686373661776500155868309933327116988404547349319879900761946444470688332645" - } - }, - "FF": { - "a": "1", - "b": "0", - "g": { - "x": "18999816458520350299014628291870504329073391058325678653840191278128672378485029664052827205905352913351648904170809", - "y": "7233699725243644729688547165924232430035643592445942846958231777803539836627943189850381859836033366776176689124317" - }, - "n": "675048016158598417213", - "p": "28688293616765795404141427476803815352899912533728694325464374376776313457785622361119232589082131818578591461837297", - "priv": "100266970209474387075", - "pub": { - "x": "7147768390112741602848314103078506234267895391544114241891627778383312460777957307647946308927283757886117119137500", - "y": "20525272195909974311677173484301099561025532568381820845650748498800315498040161314197178524020516408371544778243934" - } - } - }, - "Activation": { - "Windowws XP": { - "p": "102011604035381881", - "x": { - "0": "0", - "1": "9433814980383617", - "2": "19168316694801104", - "3": "90078616228674308", - "4": "90078616228674308", - "5": "1" - }, - "mul": "65537", - "priv": "1315384396487572637498562978064321", - "iid_key": "1791516372" - }, - "Windows XP Plus! Digital Media Edition": { - "p": "101996933280717187", - "x": { - "0": "14442243999705614", - "1": "88154401999011195", - "2": "86996763276881336", - "3": "95455813375647760", - "4": "6252462837094107", - "5": "1" - }, - "mul": "65537", - "priv": "2752030625102368166730185283969067", - "iid_key": "1791516372" - }, - "Office XP / Office 2003": { - "p": "103099955908255721", - "x": { - "0": "0", - "1": "64728167274549202", - "2": "4488766805843809", - "3": "70698430483539942", - "4": "64728167274549202", - "5": "1" - }, - "mul": "65537", - "priv": "10294349293510589382098112327865153", - "iid_key": "1513142771" - } - } -} \ No newline at end of file diff --git a/xpkey/Cargo.toml b/mskey/Cargo.toml similarity index 77% rename from xpkey/Cargo.toml rename to mskey/Cargo.toml index 16d7f27..7f5325a 100644 --- a/xpkey/Cargo.toml +++ b/mskey/Cargo.toml @@ -1,14 +1,8 @@ [package] -name = "xpkey" +name = "mskey" version = "0.1.0" edition = "2021" -[profile.release] -strip = true -opt-level = "z" -lto = true -codegen-units = 1 - [dependencies] umskt = { path = "../umskt" } anyhow = "1.0.71" diff --git a/xpkey/src/cli.rs b/mskey/src/cli.rs similarity index 100% rename from xpkey/src/cli.rs rename to mskey/src/cli.rs diff --git a/xpkey/src/keys.rs b/mskey/src/keys.rs similarity index 100% rename from xpkey/src/keys.rs rename to mskey/src/keys.rs diff --git a/xpkey/src/main.rs b/mskey/src/main.rs similarity index 98% rename from xpkey/src/main.rs rename to mskey/src/main.rs index f9e709e..600b8fd 100644 --- a/xpkey/src/main.rs +++ b/mskey/src/main.rs @@ -102,7 +102,6 @@ fn validate(args: &ValidateArgs) -> Result<()> { fn initialize_curve(bink: &Bink, bink_id: &str) -> Result { let p = &bink.p; let a = &bink.a; - let b = &bink.b; let gx = &bink.g.x; let gy = &bink.g.y; let kx = &bink.public.x; @@ -110,7 +109,7 @@ fn initialize_curve(bink: &Bink, bink_id: &str) -> Result { log::info!("Elliptic curve parameters for BINK ID {bink_id}:\n{bink}"); - EllipticCurve::new(p, a, b, gx, gy, kx, ky) + EllipticCurve::new(p, a, gx, gy, kx, ky) } fn bink1998_generate( diff --git a/umskt/Cargo.toml b/umskt/Cargo.toml index 701f790..0957c9a 100644 --- a/umskt/Cargo.toml +++ b/umskt/Cargo.toml @@ -6,7 +6,12 @@ edition = "2021" [dependencies] anyhow = "1.0.71" bitreader = "0.3.7" -openssl = { git = "https://github.com/sfackler/rust-openssl" } +elliptic-curve = "0.13.5" +num-bigint = { version = "0.4.3", features = ["rand"] } +num-integer = "0.1.45" +num-traits = "0.2.15" +rand = "0.8.5" +sha1 = "0.10.5" thiserror = "1.0.40" [dev-dependencies] diff --git a/umskt/src/bink1998.rs b/umskt/src/bink1998.rs index cd8556a..67cd059 100644 --- a/umskt/src/bink1998.rs +++ b/umskt/src/bink1998.rs @@ -1,20 +1,24 @@ -use std::fmt::{Display, Formatter}; +//! Structs to deal with older BINK (< `0x40`) product keys +use std::{ + cmp::Ordering, + fmt::{Display, Formatter}, +}; use anyhow::{bail, Result}; use bitreader::BitReader; -use openssl::{ - bn::{BigNum, BigNumContext, MsbOption}, - ec::{EcGroup, EcPoint}, - sha::sha1, -}; +use num_bigint::{BigInt, BigUint, RandomBits}; +use num_integer::Integer; +use num_traits::{FromPrimitive, ToPrimitive}; +use rand::Rng; +use sha1::{Digest, Sha1}; use crate::{ - crypto::{EllipticCurve, PrivateKey}, + crypto::{EllipticCurve, Point, PrivateKey}, key::{base24_decode, base24_encode, strip_key}, math::bitmask, }; -const FIELD_BITS: i32 = 384; +const FIELD_BITS: u64 = 384; const FIELD_BYTES: usize = 48; const SHA_MSG_LENGTH: usize = 4 + 2 * FIELD_BYTES; @@ -23,6 +27,9 @@ const SERIAL_LENGTH_BITS: u8 = 30; const UPGRADE_LENGTH_BITS: u8 = 1; const EVERYTHING_ELSE: u8 = HASH_LENGTH_BITS + SERIAL_LENGTH_BITS + UPGRADE_LENGTH_BITS; +/// A product key for a BINK ID less than `0x40` +/// +/// Every `ProductKey` contains a valid key for its given parameters. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct ProductKey { upgrade: bool, @@ -33,6 +40,9 @@ pub struct ProductKey { } impl ProductKey { + /// Generates a new product key for the given parameters. + /// + /// The key is verified to be valid before being returned. pub fn new( curve: &EllipticCurve, private_key: &PrivateKey, @@ -44,101 +54,117 @@ impl ProductKey { let sequence = match sequence { Some(serial) => serial, None => { - let mut bn_rand = BigNum::new()?; - bn_rand.rand(19, MsbOption::MAYBE_ZERO, false)?; - let o_raw = u32::from_be_bytes(bn_rand.to_vec_padded(4)?.try_into().unwrap()); - o_raw % 999999 + let mut rng = rand::thread_rng(); + let random: BigInt = rng.sample(RandomBits::new(32)); + let raw = u32::from_be_bytes(random.to_bytes_be().1[0..4].try_into().unwrap()); + raw % 999999 } }; // Default to upgrade=false let upgrade = upgrade.unwrap_or(false); + let private = &private_key.gen_order - &private_key.private_key; + // Generate a new random key let product_key = Self::generate( - &curve.curve, + curve, &curve.gen_point, &private_key.gen_order, - &private_key.private_key, + &private, channel_id, sequence, upgrade, )?; // Make sure the key is valid - product_key.verify(&curve.curve, &curve.gen_point, &curve.pub_point)?; + product_key.verify(curve, &curve.gen_point, &curve.pub_point)?; // Ship it Ok(product_key) } + /// Validates an existing product key string and tried to create a new `ProductKey` from it. + /// + /// # Arguments + /// + /// * `curve` - The elliptic curve to use for verification. + /// * `key` - Should be 25 characters long, not including the (optional) hyphens. pub fn from_key(curve: &EllipticCurve, key: &str) -> Result { let key = strip_key(key)?; let Ok(packed_key) = base24_decode(&key) else { bail!("Product key is in an incorrect format!") }; let product_key = Self::from_packed(&packed_key)?; - product_key.verify(&curve.curve, &curve.gen_point, &curve.pub_point)?; + product_key.verify(curve, &curve.gen_point, &curve.pub_point)?; Ok(product_key) } fn generate( - e_curve: &EcGroup, - base_point: &EcPoint, - gen_order: &BigNum, - private_key: &BigNum, + e_curve: &EllipticCurve, + base_point: &Point, + gen_order: &BigInt, + private_key: &BigInt, channel_id: u32, sequence: u32, upgrade: bool, ) -> Result { - let mut num_context = BigNumContext::new().unwrap(); - - let mut c = BigNum::new()?; - let mut s = BigNum::new()?; - let mut x = BigNum::new()?; - let mut y = BigNum::new()?; - - let mut ek: BigNum; - let serial = channel_id * 1_000_000 + sequence; let data = serial << 1 | upgrade as u32; + let mut rng = rand::thread_rng(); + let product_key = loop { - let mut r = EcPoint::new(e_curve)?; + let c: BigUint = rng.sample(RandomBits::new(FIELD_BITS)); + let c: BigInt = c.into(); - // Generate a random number c consisting of 384 bits without any constraints. - c.rand(FIELD_BITS, MsbOption::MAYBE_ZERO, false)?; + let r = e_curve.multiply_point(&c, base_point); - // Pick a random derivative of the base point on the elliptic curve. - // R = cG; - r.mul(e_curve, base_point, &c, &num_context)?; - - // Acquire its coordinates. - // x = R.x; y = R.y; - r.affine_coordinates(e_curve, &mut x, &mut y, &mut num_context)?; + let (x, y) = match r { + Point::Point { x, y } => (x, y), + Point::Infinity => bail!("Point at infinity!"), + }; let mut msg_buffer: [u8; SHA_MSG_LENGTH] = [0; SHA_MSG_LENGTH]; - let mut x_bin = x.to_vec_padded(FIELD_BYTES as i32)?; - x_bin.reverse(); - let mut y_bin = y.to_vec_padded(FIELD_BYTES as i32)?; - y_bin.reverse(); + let x_bin = x.to_bytes_le().1; + let x_bin = match x_bin.len().cmp(&FIELD_BYTES) { + Ordering::Less => (0..FIELD_BYTES - x_bin.len()) + .map(|_| 0) + .chain(x_bin.into_iter()) + .collect(), + Ordering::Greater => continue, + Ordering::Equal => x_bin, + }; + let y_bin = y.to_bytes_le().1; + let y_bin = match y_bin.len().cmp(&FIELD_BYTES) { + Ordering::Less => (0..FIELD_BYTES - y_bin.len()) + .map(|_| 0) + .chain(y_bin.into_iter()) + .collect(), + Ordering::Greater => continue, + Ordering::Equal => y_bin, + }; msg_buffer[0..4].copy_from_slice(&data.to_le_bytes()); msg_buffer[4..4 + FIELD_BYTES].copy_from_slice(&x_bin); msg_buffer[4 + FIELD_BYTES..4 + FIELD_BYTES * 2].copy_from_slice(&y_bin); - let msg_digest = sha1(&msg_buffer); + let msg_digest = { + let mut hasher = Sha1::new(); + hasher.update(msg_buffer); + hasher.finalize() + }; let hash: u32 = u32::from_le_bytes(msg_digest[0..4].try_into().unwrap()) >> 4 & bitmask(28) as u32; - ek = (*private_key).to_owned()?; - ek.mul_word(hash)?; + let mut ek = private_key.clone(); + ek *= hash; - s.mod_add(&ek, &c, gen_order, &mut num_context)?; + let s = (ek + c).mod_floor(gen_order); - let signature = u64::from_be_bytes(s.to_vec_padded(8)?.try_into().unwrap()); + let signature = s.to_u64().unwrap_or(0); if signature <= bitmask(55) { break Self { @@ -156,36 +182,43 @@ impl ProductKey { fn verify( &self, - e_curve: &EcGroup, - base_point: &EcPoint, - public_key: &EcPoint, + e_curve: &EllipticCurve, + base_point: &Point, + public_key: &Point, ) -> Result { - let mut ctx = BigNumContext::new()?; + let e = BigInt::from_u32(self.hash).unwrap(); + let s = BigInt::from_u64(self.signature).unwrap(); - let e = BigNum::from_u32(self.hash)?; - let s = BigNum::from_slice(&self.signature.to_be_bytes())?; - let mut x = BigNum::new()?; - let mut y = BigNum::new()?; + let t = e_curve.multiply_point(&s, base_point); + let mut p = e_curve.multiply_point(&e, public_key); - let mut t = EcPoint::new(e_curve)?; - let mut p = EcPoint::new(e_curve)?; + p = e_curve.add_points(&p, &t); - t.mul(e_curve, base_point, &s, &ctx)?; - p.mul(e_curve, public_key, &e, &ctx)?; - - { - let p_copy = p.to_owned(e_curve)?; - p.add(e_curve, &t, &p_copy, &mut ctx)?; - } - - p.affine_coordinates(e_curve, &mut x, &mut y, &mut ctx)?; + let (x, y) = match p { + Point::Point { x, y } => (x, y), + Point::Infinity => bail!("Point at infinity!"), + }; let mut msg_buffer: [u8; SHA_MSG_LENGTH] = [0; SHA_MSG_LENGTH]; - let mut x_bin = x.to_vec_padded(FIELD_BYTES as i32)?; - x_bin.reverse(); - let mut y_bin = y.to_vec_padded(FIELD_BYTES as i32)?; - y_bin.reverse(); + let x_bin = x.to_bytes_le().1; + let x_bin = if x_bin.len() < FIELD_BYTES { + (0..FIELD_BYTES - x_bin.len()) + .map(|_| 0) + .chain(x_bin.into_iter()) + .collect() + } else { + x_bin + }; + let y_bin = y.to_bytes_le().1; + let y_bin = if y_bin.len() < FIELD_BYTES { + (0..FIELD_BYTES - y_bin.len()) + .map(|_| 0) + .chain(y_bin.into_iter()) + .collect() + } else { + y_bin + }; let serial = self.channel_id * 1_000_000 + self.sequence; let data = serial << 1 | self.upgrade as u32; @@ -194,7 +227,11 @@ impl ProductKey { msg_buffer[4..4 + FIELD_BYTES].copy_from_slice(&x_bin); msg_buffer[4 + FIELD_BYTES..4 + FIELD_BYTES * 2].copy_from_slice(&y_bin); - let msg_digest = sha1(&msg_buffer); + let msg_digest = { + let mut hasher = Sha1::new(); + hasher.update(msg_buffer); + hasher.finalize() + }; let hash: u32 = u32::from_le_bytes(msg_digest[0..4].try_into().unwrap()) >> 4 & bitmask(28) as u32; @@ -265,7 +302,7 @@ mod tests { use serde_json::from_reader; - use crate::crypto::EllipticCurve; + use crate::{bink1998, crypto::EllipticCurve}; #[test] fn verify_test() { @@ -283,16 +320,15 @@ mod tests { let p = bink["p"].as_str().unwrap(); let a = bink["a"].as_str().unwrap(); - let b = bink["b"].as_str().unwrap(); let gx = bink["g"]["x"].as_str().unwrap(); let gy = bink["g"]["y"].as_str().unwrap(); let kx = bink["pub"]["x"].as_str().unwrap(); let ky = bink["pub"]["y"].as_str().unwrap(); - let curve = EllipticCurve::new(p, a, b, gx, gy, kx, ky).unwrap(); + let curve = EllipticCurve::new(p, a, gx, gy, kx, ky).unwrap(); - assert!(super::ProductKey::from_key(&curve, product_key).is_ok()); - assert!(super::ProductKey::from_key(&curve, "11111-R6BG2-39J83-RYKHF-W47TT").is_err()); + assert!(bink1998::ProductKey::from_key(&curve, product_key).is_ok()); + assert!(bink1998::ProductKey::from_key(&curve, "11111-R6BG2-39J83-RYKHF-W47TT").is_err()); } #[test] diff --git a/umskt/src/bink2002.rs b/umskt/src/bink2002.rs index 96e37fb..924ad25 100644 --- a/umskt/src/bink2002.rs +++ b/umskt/src/bink2002.rs @@ -1,21 +1,24 @@ -use std::fmt::{Display, Formatter}; +//! Structs to deal with newer BINK (>= `0x40`) product keys +use std::{ + cmp::Ordering, + fmt::{Display, Formatter}, +}; use anyhow::{bail, Result}; use bitreader::BitReader; -use openssl::{ - bn::{BigNum, BigNumContext, MsbOption}, - ec::{EcGroup, EcPoint}, - rand::rand_bytes, - sha::sha1, -}; +use num_bigint::{BigInt, BigUint, RandomBits}; +use num_integer::Integer; +use num_traits::ToPrimitive; +use rand::Rng; +use sha1::{Digest, Sha1}; use crate::{ - crypto::{EllipticCurve, PrivateKey}, + crypto::{mod_sqrt, EllipticCurve, Point, PrivateKey}, key::{base24_decode, base24_encode, strip_key}, math::{bitmask, by_dword, next_sn_bits}, }; -const FIELD_BITS: i32 = 512; +const FIELD_BITS: u64 = 512; const FIELD_BYTES: usize = 64; const SHA_MSG_LENGTH: usize = 3 + 2 * FIELD_BYTES; @@ -26,6 +29,9 @@ const UPGRADE_LENGTH_BITS: u8 = 1; const EVERYTHING_ELSE: u8 = SIGNATURE_LENGTH_BITS + HASH_LENGTH_BITS + CHANNEL_ID_LENGTH_BITS + UPGRADE_LENGTH_BITS; +/// A product key for a BINK ID `0x40` or higher +/// +/// Every `ProductKey` contains a valid key for its given parameters. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct ProductKey { upgrade: bool, @@ -36,6 +42,9 @@ pub struct ProductKey { } impl ProductKey { + /// Generates a new product key for the given parameters. + /// + /// The key is verified to be valid before being returned. pub fn new( curve: &EllipticCurve, private_key: &PrivateKey, @@ -47,9 +56,10 @@ impl ProductKey { let auth_info = match auth_info { Some(auth_info) => auth_info, None => { - let mut auth_info_bytes = [0_u8; 4]; - rand_bytes(&mut auth_info_bytes)?; - u32::from_ne_bytes(auth_info_bytes) & ((1 << 10) - 1) + let mut rng = rand::thread_rng(); + let random: BigInt = rng.sample(RandomBits::new(32)); + let raw = u32::from_be_bytes(random.to_bytes_be().1[0..4].try_into().unwrap()); + raw % (bitmask(10) as u32) } }; @@ -58,7 +68,7 @@ impl ProductKey { // Generate a new random key let product_key = Self::generate( - &curve.curve, + curve, &curve.gen_point, &private_key.gen_order, &private_key.private_key, @@ -68,19 +78,25 @@ impl ProductKey { )?; // Make sure the key is valid - product_key.verify(&curve.curve, &curve.gen_point, &curve.pub_point)?; + product_key.verify(curve, &curve.gen_point, &curve.pub_point)?; // Ship it Ok(product_key) } + /// Validates an existing product key string and tried to create a new `ProductKey` from it. + /// + /// # Arguments + /// + /// * `curve` - The elliptic curve to use for verification. + /// * `key` - Should be 25 characters long, not including the (optional) hyphens. pub fn from_key(curve: &EllipticCurve, key: &str) -> Result { let key = strip_key(key)?; let Ok(packed_key) = base24_decode(&key) else { bail!("Product key is in an incorrect format!") }; let product_key = Self::from_packed(&packed_key)?; - let verified = product_key.verify(&curve.curve, &curve.gen_point, &curve.pub_point)?; + let verified = product_key.verify(curve, &curve.gen_point, &curve.pub_point)?; if !verified { bail!("Product key is invalid! Wrong BINK ID?"); } @@ -88,38 +104,50 @@ impl ProductKey { } fn generate( - e_curve: &EcGroup, - base_point: &EcPoint, - gen_order: &BigNum, - private_key: &BigNum, + e_curve: &EllipticCurve, + base_point: &Point, + gen_order: &BigInt, + private_key: &BigInt, channel_id: u32, auth_info: u32, upgrade: bool, ) -> Result { - let mut num_context = BigNumContext::new().unwrap(); - - let mut c = BigNum::new()?; - let mut x = BigNum::new()?; - let mut y = BigNum::new()?; - let data = channel_id << 1 | upgrade as u32; + let mut rng = rand::thread_rng(); + let mut no_square = false; let key = loop { - let mut r = EcPoint::new(e_curve)?; + let c: BigUint = rng.sample(RandomBits::new(FIELD_BITS)); + let mut c: BigInt = c.into(); - c.rand(FIELD_BITS, MsbOption::MAYBE_ZERO, false)?; + let r = e_curve.multiply_point(&c, base_point); - r.mul(e_curve, base_point, &c, &num_context)?; - - r.affine_coordinates(e_curve, &mut x, &mut y, &mut num_context)?; + let (x, y) = match r { + Point::Point { x, y } => (x, y), + Point::Infinity => bail!("Point at infinity!"), + }; let mut msg_buffer: [u8; SHA_MSG_LENGTH] = [0; SHA_MSG_LENGTH]; - let mut x_bin = x.to_vec_padded(FIELD_BYTES as i32)?; - x_bin.reverse(); - let mut y_bin = y.to_vec_padded(FIELD_BYTES as i32)?; - y_bin.reverse(); + let x_bin = x.to_bytes_le().1; + let x_bin = match x_bin.len().cmp(&FIELD_BYTES) { + Ordering::Less => (0..FIELD_BYTES - x_bin.len()) + .map(|_| 0) + .chain(x_bin.into_iter()) + .collect(), + Ordering::Greater => continue, + Ordering::Equal => x_bin, + }; + let y_bin = y.to_bytes_le().1; + let y_bin = match y_bin.len().cmp(&FIELD_BYTES) { + Ordering::Less => (0..FIELD_BYTES - y_bin.len()) + .map(|_| 0) + .chain(y_bin.into_iter()) + .collect(), + Ordering::Greater => continue, + Ordering::Equal => y_bin, + }; msg_buffer[0x00] = 0x79; msg_buffer[0x01] = (data & 0x00FF) as u8; @@ -128,7 +156,11 @@ impl ProductKey { msg_buffer[3..3 + FIELD_BYTES].copy_from_slice(&x_bin); msg_buffer[3 + FIELD_BYTES..3 + FIELD_BYTES * 2].copy_from_slice(&y_bin); - let msg_digest = sha1(&msg_buffer); + let msg_digest = { + let mut hasher = Sha1::new(); + hasher.update(msg_buffer); + hasher.finalize() + }; let hash: u32 = by_dword(&msg_digest[0..4]) & bitmask(31) as u32; @@ -144,42 +176,43 @@ impl ProductKey { msg_buffer[0x09] = 0x00; msg_buffer[0x0A] = 0x00; - let msg_digest = sha1(&msg_buffer[..=0x0A]); + let msg_digest = { + let mut hasher = Sha1::new(); + hasher.update(&msg_buffer[..=0x0A]); + hasher.finalize() + }; let i_signature = next_sn_bits(by_dword(&msg_digest[4..8]) as u64, 30, 2) << 32 | by_dword(&msg_digest[0..4]) as u64; - let mut e = BigNum::from_slice(&i_signature.to_be_bytes())?; + let mut e = BigInt::from(i_signature); - let e_2 = e.to_owned()?; - e.mod_mul(&e_2, private_key, gen_order, &mut num_context)?; + e = (e * private_key).mod_floor(gen_order); - let mut s = e.to_owned()?; + let mut s = e.clone(); - let s_2 = s.to_owned()?; - s.mod_sqr(&s_2, gen_order, &mut num_context)?; + s = (&s * &s).mod_floor(gen_order); - let c_2 = c.to_owned()?; - c.lshift(&c_2, 2)?; + c <<= 2; s = &s + &c; - let s_2 = s.to_owned()?; - if s.mod_sqrt(&s_2, gen_order, &mut num_context).is_err() { - no_square = true; - }; + match mod_sqrt(&s, gen_order) { + Some(res) => s = res, + None => { + no_square = true; + } + } - let s_2 = s.to_owned()?; - s.mod_sub(&s_2, &e, gen_order, &mut num_context)?; + s = (s - e).mod_floor(gen_order); - if s.is_bit_set(0) { + if s.is_odd() { s = &s + gen_order; } - let s_2 = s.to_owned()?; - s.rshift1(&s_2)?; + s >>= 1; - let signature = u64::from_be_bytes(s.to_vec_padded(8)?.try_into().unwrap()); + let signature = s.to_u64().unwrap_or(0); let product_key = Self { upgrade, @@ -201,12 +234,10 @@ impl ProductKey { fn verify( &self, - e_curve: &EcGroup, - base_point: &EcPoint, - public_key: &EcPoint, + e_curve: &EllipticCurve, + base_point: &Point, + public_key: &Point, ) -> Result { - let mut num_context = BigNumContext::new()?; - let data = self.channel_id << 1 | self.upgrade as u32; let mut msg_buffer: [u8; SHA_MSG_LENGTH] = [0; SHA_MSG_LENGTH]; @@ -223,39 +254,47 @@ impl ProductKey { msg_buffer[0x09] = 0x00; msg_buffer[0x0A] = 0x00; - let msg_digest = sha1(&msg_buffer[..=0x0A]); + let msg_digest = { + let mut hasher = Sha1::new(); + hasher.update(&msg_buffer[..=0x0A]); + hasher.finalize() + }; let i_signature = next_sn_bits(by_dword(&msg_digest[4..8]) as u64, 30, 2) << 32 | by_dword(&msg_digest[0..4]) as u64; - let e = BigNum::from_slice(&i_signature.to_be_bytes())?; - let s = BigNum::from_slice(&self.signature.to_be_bytes())?; + let e = BigInt::from(i_signature); + let s = BigInt::from(self.signature); - let mut x = BigNum::new()?; - let mut y = BigNum::new()?; + let t = e_curve.multiply_point(&s, base_point); + let mut p = e_curve.multiply_point(&e, public_key); - let mut p = EcPoint::new(e_curve)?; - let mut t = EcPoint::new(e_curve)?; + p = e_curve.add_points(&t, &p); + p = e_curve.multiply_point(&s, &p); - t.mul(e_curve, base_point, &s, &num_context)?; - p.mul(e_curve, public_key, &e, &num_context)?; + let (x, y) = match p { + Point::Point { x, y } => (x, y), + Point::Infinity => bail!("Point at infinity!"), + }; - { - let p_2 = p.to_owned(e_curve)?; - p.add(e_curve, &t, &p_2, &mut num_context)?; - } - - { - let p_2 = p.to_owned(e_curve)?; - p.mul(e_curve, &p_2, &s, &num_context)?; - } - - p.affine_coordinates(e_curve, &mut x, &mut y, &mut num_context)?; - - let mut x_bin = x.to_vec_padded(FIELD_BYTES as i32)?; - x_bin.reverse(); - let mut y_bin = y.to_vec_padded(FIELD_BYTES as i32)?; - y_bin.reverse(); + let x_bin = x.to_bytes_le().1; + let x_bin = if x_bin.len() < FIELD_BYTES { + (0..FIELD_BYTES - x_bin.len()) + .map(|_| 0) + .chain(x_bin.into_iter()) + .collect() + } else { + x_bin + }; + let y_bin = y.to_bytes_le().1; + let y_bin = if y_bin.len() < FIELD_BYTES { + (0..FIELD_BYTES - y_bin.len()) + .map(|_| 0) + .chain(y_bin.into_iter()) + .collect() + } else { + y_bin + }; msg_buffer[0x00] = 0x79; msg_buffer[0x01] = (data & 0x00FF) as u8; @@ -264,7 +303,11 @@ impl ProductKey { msg_buffer[3..3 + FIELD_BYTES].copy_from_slice(&x_bin); msg_buffer[3 + FIELD_BYTES..3 + FIELD_BYTES * 2].copy_from_slice(&y_bin); - let msg_digest = sha1(&msg_buffer); + let msg_digest = { + let mut hasher = Sha1::new(); + hasher.update(msg_buffer); + hasher.finalize() + }; let hash: u32 = by_dword(&msg_digest[0..4]) & bitmask(31) as u32; @@ -353,13 +396,12 @@ mod tests { let p = bink["p"].as_str().unwrap(); let a = bink["a"].as_str().unwrap(); - let b = bink["b"].as_str().unwrap(); let gx = bink["g"]["x"].as_str().unwrap(); let gy = bink["g"]["y"].as_str().unwrap(); let kx = bink["pub"]["x"].as_str().unwrap(); let ky = bink["pub"]["y"].as_str().unwrap(); - let curve = EllipticCurve::new(p, a, b, gx, gy, kx, ky).unwrap(); + let curve = EllipticCurve::new(p, a, gx, gy, kx, ky).unwrap(); assert!(super::ProductKey::from_key(&curve, product_key).is_ok()); assert!(super::ProductKey::from_key(&curve, "11111-YRGC8-4KYTG-C3FCC-JCFDY").is_err()); diff --git a/umskt/src/confid/black_box.rs b/umskt/src/confid/black_box.rs index 688552d..17351c0 100644 --- a/umskt/src/confid/black_box.rs +++ b/umskt/src/confid/black_box.rs @@ -1,49 +1,26 @@ -use std::{ffi::c_void, ptr}; +use std::mem::{size_of, swap}; #[derive(Copy, Clone)] -#[repr(C)] struct TDivisor { u: [u64; 2], v: [u64; 2], } + #[derive(Copy, Clone)] -#[repr(C)] -struct C2RustUnnamed { - encoded: [u32; 4], -} -#[derive(Copy, Clone)] -#[repr(C)] -union C2RustUnnamed0 { - c2rust_unnamed: C2RustUnnamed1, - c2rust_unnamed_0: C2RustUnnamed, -} -#[derive(Copy, Clone)] -#[repr(C)] -struct C2RustUnnamed1 { +struct Encoded { encoded_lo: u64, encoded_hi: u64, } + #[derive(Copy, Clone)] -#[repr(C)] -struct C2RustUnnamed2 { - lo: u64, - hi: u64, -} -#[derive(Copy, Clone)] -#[repr(C)] -union C2RustUnnamed3 { - buffer: [u8; 14], - c2rust_unnamed: C2RustUnnamed2, -} -#[derive(Copy, Clone)] -#[repr(C, packed)] -struct C2RustUnnamed4 { +struct ParsedInstallationId { hardware_id: u64, product_id_low: u64, product_id_high: u8, key_sha1: u16, } -static mut F: [u64; 6] = [ + +static F: [u64; 6] = [ 0, 0x21840136c85381, 0x44197b83892ad0, @@ -201,7 +178,7 @@ fn residue_sqrt(what: u64) -> u64 { x } -unsafe fn find_divisor_v(d: *mut TDivisor) -> i32 { +fn find_divisor_v(d: &mut TDivisor) -> i32 { // u | v^2 - f // u = u0 + u1*x + x^2 // f%u = f0 + f1*x @@ -212,8 +189,8 @@ unsafe fn find_divisor_v(d: *mut TDivisor) -> i32 { f2[i as usize] = F[i as usize]; i += 1; } - let u0: u64 = (*d).u[0_i32 as usize]; - let u1: u64 = (*d).u[1_i32 as usize]; + let u0: u64 = d.u[0_i32 as usize]; + let u1: u64 = d.u[1_i32 as usize]; let mut j: i32 = 4_i32; loop { let fresh0 = j; @@ -281,18 +258,18 @@ unsafe fn find_divisor_v(d: *mut TDivisor) -> i32 { residue_add(f1, residue_mul(u1, residue_mul(v1, v1))), residue_inv(residue_add(v1, v1)), ); - (*d).v[0_i32 as usize] = v0; - (*d).v[1_i32 as usize] = v1; + d.v[0_i32 as usize] = v0; + d.v[1_i32 as usize] = v1; 1_i32 } -unsafe fn polynomial_mul( +fn polynomial_mul( adeg: i32, - a: *const u64, + a: &[u64], bdeg: i32, - b: *const u64, + b: &[u64], mut resultprevdeg: i32, - result: *mut u64, + result: &mut [u64], ) -> i32 { // generic short slow code if adeg < 0_i32 || bdeg < 0_i32 { @@ -300,7 +277,7 @@ unsafe fn polynomial_mul( } let mut i = resultprevdeg + 1_i32; while i <= adeg + bdeg { - *result.offset(i as isize) = 0_i32 as u64; + result[i as usize] = 0_i32 as u64; i += 1; } resultprevdeg = i - 1_i32; @@ -308,86 +285,79 @@ unsafe fn polynomial_mul( while i <= adeg { let mut j = 0_i32; while j <= bdeg { - *result.offset((i + j) as isize) = residue_add( - *result.offset((i + j) as isize), - residue_mul(*a.offset(i as isize), *b.offset(j as isize)), + result[(i + j) as usize] = residue_add( + result[(i + j) as usize], + residue_mul(a[i as usize], b[j as usize]), ); j += 1; } i += 1; } - while resultprevdeg >= 0_i32 && *result.offset(resultprevdeg as isize) == 0_i32 as u64 { + while resultprevdeg >= 0_i32 && result[resultprevdeg as usize] == 0_i32 as u64 { resultprevdeg -= 1; } resultprevdeg } -unsafe fn polynomial_div_monic( +fn polynomial_div_monic( adeg: i32, - a: *mut u64, + a: &mut [u64], bdeg: i32, - b: *const u64, - quotient: *mut u64, + b: &[u64], + mut quotient: Option<&mut [u64]>, ) -> i32 { let mut i = adeg - bdeg; while i >= 0_i32 { - let q: u64 = *a.offset((i + bdeg) as isize); - if !quotient.is_null() { - *quotient.offset(i as isize) = q; + let q: u64 = a[(i + bdeg) as usize]; + if let Some(ref mut quotient) = quotient { + quotient[i as usize] = q; } let mut j = 0_i32; while j < bdeg { - *a.offset((i + j) as isize) = residue_sub( - *a.offset((i + j) as isize), - residue_mul(q, *b.offset(j as isize)), - ); + a[(i + j) as usize] = residue_sub(a[(i + j) as usize], residue_mul(q, b[j as usize])); j += 1; } - *a.offset((i + j) as isize) = 0_i32 as u64; + a[(i + j) as usize] = 0_i32 as u64; i -= 1; } i += bdeg; - while i >= 0_i32 && *a.offset(i as isize) == 0_i32 as u64 { + while i >= 0_i32 && a[i as usize] == 0_i32 as u64 { i -= 1; } i } #[allow(clippy::too_many_arguments)] -unsafe fn polynomial_xgcd( +fn polynomial_xgcd( adeg: i32, - a: *const u64, + a: &[u64], bdeg: i32, - b: *const u64, - pgcddeg: *mut i32, - gcd: *mut u64, - pmult1deg: *mut i32, - mult1: *mut u64, - pmult2deg: *mut i32, - mult2: *mut u64, + b: &[u64], + pgcddeg: &mut i32, + gcd: &mut [u64], + pmult1deg: &mut i32, + mult1: &mut [u64], + pmult2deg: &mut i32, + mult2: &mut [u64], ) { let mut sdeg: i32 = -1_i32; let mut s: [u64; 3] = [0_i32 as u64, 0_i32 as u64, 0_i32 as u64]; let mut mult1deg: i32 = 0_i32; - *mult1.offset(0_i32 as isize) = 1_i32 as u64; - *mult1.offset(1_i32 as isize) = 0_i32 as u64; - *mult1.offset(2_i32 as isize) = 0_i32 as u64; + mult1[0] = 1_i32 as u64; + mult1[1] = 0_i32 as u64; + mult1[2] = 0_i32 as u64; let mut tdeg: i32 = 0_i32; let mut t: [u64; 3] = [1_i32 as u64, 0_i32 as u64, 0_i32 as u64]; let mut mult2deg: i32 = -1_i32; - *mult2.offset(0_i32 as isize) = 0_i32 as u64; - *mult2.offset(1_i32 as isize) = 0_i32 as u64; - *mult2.offset(2_i32 as isize) = 0_i32 as u64; + mult2[0] = 0_i32 as u64; + mult2[1] = 0_i32 as u64; + mult2[2] = 0_i32 as u64; let mut rdeg: i32 = bdeg; - let mut r: [u64; 3] = [ - *b.offset(0_i32 as isize), - *b.offset(1_i32 as isize), - *b.offset(2_i32 as isize), - ]; + let mut r: [u64; 3] = [b[0], b[1], b[2]]; let mut gcddeg: i32 = adeg; - *gcd.offset(0_i32 as isize) = *a.offset(0_i32 as isize); - *gcd.offset(1_i32 as isize) = *a.offset(1_i32 as isize); - *gcd.offset(2_i32 as isize) = *a.offset(2_i32 as isize); + gcd[0] = a[0]; + gcd[1] = a[1]; + gcd[2] = a[2]; // s*u1 + t*u2 = r // mult1*u1 + mult2*u2 = gcd while rdeg >= 0_i32 { @@ -395,55 +365,34 @@ unsafe fn polynomial_xgcd( let tmp = rdeg as u32; rdeg = gcddeg; gcddeg = tmp as i32; - std::mem::swap(&mut sdeg, &mut mult1deg); - std::mem::swap(&mut tdeg, &mut mult2deg); - let mut tmp2 = r[0_i32 as usize]; - r[0_i32 as usize] = *gcd.offset(0_i32 as isize); - *gcd.offset(0_i32 as isize) = tmp2; - tmp2 = r[1_i32 as usize]; - r[1_i32 as usize] = *gcd.offset(1_i32 as isize); - *gcd.offset(1_i32 as isize) = tmp2; - tmp2 = r[2_i32 as usize]; - r[2_i32 as usize] = *gcd.offset(2_i32 as isize); - *gcd.offset(2_i32 as isize) = tmp2; - tmp2 = s[0_i32 as usize]; - s[0_i32 as usize] = *mult1.offset(0_i32 as isize); - *mult1.offset(0_i32 as isize) = tmp2; - tmp2 = s[1_i32 as usize]; - s[1_i32 as usize] = *mult1.offset(1_i32 as isize); - *mult1.offset(1_i32 as isize) = tmp2; - tmp2 = s[2_i32 as usize]; - s[2_i32 as usize] = *mult1.offset(2_i32 as isize); - *mult1.offset(2_i32 as isize) = tmp2; - tmp2 = t[0_i32 as usize]; - t[0_i32 as usize] = *mult2.offset(0_i32 as isize); - *mult2.offset(0_i32 as isize) = tmp2; - tmp2 = t[1_i32 as usize]; - t[1_i32 as usize] = *mult2.offset(1_i32 as isize); - *mult2.offset(1_i32 as isize) = tmp2; - tmp2 = t[2_i32 as usize]; - t[2_i32 as usize] = *mult2.offset(2_i32 as isize); - *mult2.offset(2_i32 as isize) = tmp2; + swap(&mut sdeg, &mut mult1deg); + swap(&mut tdeg, &mut mult2deg); + swap(&mut r[0], &mut gcd[0]); + swap(&mut r[1], &mut gcd[1]); + swap(&mut r[2], &mut gcd[2]); + swap(&mut s[0], &mut mult1[0]); + swap(&mut s[1], &mut mult1[1]); + swap(&mut s[2], &mut mult1[2]); + swap(&mut t[0], &mut mult2[0]); + swap(&mut t[1], &mut mult2[1]); + swap(&mut t[2], &mut mult2[2]); } else { let delta: i32 = gcddeg - rdeg; - let mult: u64 = - residue_mul(*gcd.offset(gcddeg as isize), residue_inv(r[rdeg as usize])); + let mult: u64 = residue_mul(gcd[gcddeg as usize], residue_inv(r[rdeg as usize])); // quotient = mult * x**delta let mut i: i32 = 0_i32; while i <= rdeg { - *gcd.offset((i + delta) as isize) = residue_sub( - *gcd.offset((i + delta) as isize), - residue_mul(mult, r[i as usize]), - ); + gcd[(i + delta) as usize] = + residue_sub(gcd[(i + delta) as usize], residue_mul(mult, r[i as usize])); i += 1; } - while gcddeg >= 0_i32 && *gcd.offset(gcddeg as isize) == 0_i32 as u64 { + while gcddeg >= 0_i32 && gcd[gcddeg as usize] == 0_i32 as u64 { gcddeg -= 1; } let mut i_0: i32 = 0_i32; while i_0 <= sdeg { - *mult1.offset((i_0 + delta) as isize) = residue_sub( - *mult1.offset((i_0 + delta) as isize), + mult1[(i_0 + delta) as usize] = residue_sub( + mult1[(i_0 + delta) as usize], residue_mul(mult, s[i_0 as usize]), ); i_0 += 1; @@ -451,13 +400,13 @@ unsafe fn polynomial_xgcd( if mult1deg < sdeg + delta { mult1deg = sdeg + delta; } - while mult1deg >= 0_i32 && *mult1.offset(mult1deg as isize) == 0_i32 as u64 { + while mult1deg >= 0_i32 && mult1[mult1deg as usize] == 0_i32 as u64 { mult1deg -= 1; } let mut i_1: i32 = 0_i32; while i_1 <= tdeg { - *mult2.offset((i_1 + delta) as isize) = residue_sub( - *mult2.offset((i_1 + delta) as isize), + mult2[(i_1 + delta) as usize] = residue_sub( + mult2[(i_1 + delta) as usize], residue_mul(mult, t[i_1 as usize]), ); i_1 += 1; @@ -465,7 +414,7 @@ unsafe fn polynomial_xgcd( if mult2deg < tdeg + delta { mult2deg = tdeg + delta; } - while mult2deg >= 0_i32 && *mult2.offset(mult2deg as isize) == 0_i32 as u64 { + while mult2deg >= 0_i32 && mult2[mult2deg as usize] == 0_i32 as u64 { mult2deg -= 1; } } @@ -476,35 +425,35 @@ unsafe fn polynomial_xgcd( *pmult2deg = mult2deg; } -unsafe fn u2poly(src: *const TDivisor, polyu: *mut u64, polyv: *mut u64) -> i32 { - if (*src).u[1_i32 as usize] != BAD { - *polyu.offset(0_i32 as isize) = (*src).u[0_i32 as usize]; - *polyu.offset(1_i32 as isize) = (*src).u[1_i32 as usize]; - *polyu.offset(2_i32 as isize) = 1_i32 as u64; - *polyv.offset(0_i32 as isize) = (*src).v[0_i32 as usize]; - *polyv.offset(1_i32 as isize) = (*src).v[1_i32 as usize]; +fn u2poly(src: &TDivisor, polyu: &mut [u64], polyv: &mut [u64]) -> i32 { + if src.u[1_i32 as usize] != BAD { + polyu[0_i32 as usize] = src.u[0_i32 as usize]; + polyu[1_i32 as usize] = src.u[1_i32 as usize]; + polyu[2_i32 as usize] = 1_i32 as u64; + polyv[0_i32 as usize] = src.v[0_i32 as usize]; + polyv[1_i32 as usize] = src.v[1_i32 as usize]; return 2_i32; } - if (*src).u[0_i32 as usize] != BAD { - *polyu.offset(0_i32 as isize) = (*src).u[0_i32 as usize]; - *polyu.offset(1_i32 as isize) = 1_i32 as u64; - *polyv.offset(0_i32 as isize) = (*src).v[0_i32 as usize]; - *polyv.offset(1_i32 as isize) = 0_i32 as u64; + if src.u[0_i32 as usize] != BAD { + polyu[0_i32 as usize] = src.u[0_i32 as usize]; + polyu[1_i32 as usize] = 1_i32 as u64; + polyv[0_i32 as usize] = src.v[0_i32 as usize]; + polyv[1_i32 as usize] = 0_i32 as u64; return 1_i32; } - *polyu.offset(0_i32 as isize) = 1_i32 as u64; - *polyv.offset(0_i32 as isize) = 0_i32 as u64; - *polyv.offset(1_i32 as isize) = 0_i32 as u64; + polyu[0_i32 as usize] = 1_i32 as u64; + polyv[0_i32 as usize] = 0_i32 as u64; + polyv[1_i32 as usize] = 0_i32 as u64; 0_i32 } -unsafe fn divisor_add(src1: *const TDivisor, src2: *const TDivisor, dst: *mut TDivisor) { +fn divisor_add(src1: &TDivisor, src2: &TDivisor, dst: &mut TDivisor) { let mut u1: [u64; 3] = [0; 3]; let mut u2: [u64; 3] = [0; 3]; let mut v1: [u64; 2] = [0; 2]; let mut v2: [u64; 2] = [0; 2]; - let u1deg: i32 = u2poly(src1, u1.as_mut_ptr(), v1.as_mut_ptr()); - let u2deg: i32 = u2poly(src2, u2.as_mut_ptr(), v2.as_mut_ptr()); + let u1deg: i32 = u2poly(src1, &mut u1, &mut v1); + let u2deg: i32 = u2poly(src2, &mut u2, &mut v2); // extended gcd: d1 = gcd(u1, u2) = e1*u1 + e2*u2 let mut d1deg: i32 = 0; let mut e1deg: i32 = 0; @@ -513,19 +462,10 @@ unsafe fn divisor_add(src1: *const TDivisor, src2: *const TDivisor, dst: *mut TD let mut e1: [u64; 3] = [0; 3]; let mut e2: [u64; 3] = [0; 3]; polynomial_xgcd( - u1deg, - u1.as_mut_ptr() as *const u64, - u2deg, - u2.as_mut_ptr() as *const u64, - &mut d1deg, - d1.as_mut_ptr(), - &mut e1deg, - e1.as_mut_ptr(), - &mut e2deg, - e2.as_mut_ptr(), + u1deg, &u1, u2deg, &u2, &mut d1deg, &mut d1, &mut e1deg, &mut e1, &mut e2deg, &mut e2, ); // extended gcd again: d = gcd(d1, v1+v2) = c1*d1 + c2*(v1+v2) - let mut b: [u64; 3] = [ + let b: [u64; 3] = [ residue_add(v1[0_i32 as usize], v2[0_i32 as usize]), residue_add(v1[1_i32 as usize], v2[1_i32 as usize]), 0_i32 as u64, @@ -546,16 +486,7 @@ unsafe fn divisor_add(src1: *const TDivisor, src2: *const TDivisor, dst: *mut TD let mut c1: [u64; 3] = [0; 3]; let mut c2: [u64; 3] = [0; 3]; polynomial_xgcd( - d1deg, - d1.as_mut_ptr() as *const u64, - bdeg, - b.as_mut_ptr() as *const u64, - &mut ddeg, - d.as_mut_ptr(), - &mut c1deg, - c1.as_mut_ptr(), - &mut c2deg, - c2.as_mut_ptr(), + d1deg, &d1, bdeg, &b, &mut ddeg, &mut d, &mut c1deg, &mut c1, &mut c2deg, &mut c2, ); let dmult: u64 = residue_inv(d[ddeg as usize]); let mut i = 0_i32; @@ -575,14 +506,7 @@ unsafe fn divisor_add(src1: *const TDivisor, src2: *const TDivisor, dst: *mut TD i += 1; } let mut u: [u64; 5] = [0; 5]; - let mut udeg: i32 = polynomial_mul( - u1deg, - u1.as_mut_ptr() as *const u64, - u2deg, - u2.as_mut_ptr() as *const u64, - -1_i32, - u.as_mut_ptr(), - ); + let mut udeg: i32 = polynomial_mul(u1deg, &u1, u2deg, &u2, -1_i32, &mut u); // u is monic let mut v: [u64; 7] = [0; 7]; let mut tmp: [u64; 7] = [0; 7]; @@ -590,30 +514,9 @@ unsafe fn divisor_add(src1: *const TDivisor, src2: *const TDivisor, dst: *mut TD // c1*(e1*u1*(v2-v1) + d1*v1) + c2*(v1*v2 + f) v[0_i32 as usize] = residue_sub(v2[0_i32 as usize], v1[0_i32 as usize]); v[1_i32 as usize] = residue_sub(v2[1_i32 as usize], v1[1_i32 as usize]); - let mut tmpdeg = polynomial_mul( - e1deg, - e1.as_mut_ptr() as *const u64, - 1_i32, - v.as_mut_ptr() as *const u64, - -1_i32, - tmp.as_mut_ptr(), - ); - let mut vdeg = polynomial_mul( - u1deg, - u1.as_mut_ptr() as *const u64, - tmpdeg, - tmp.as_mut_ptr() as *const u64, - -1_i32, - v.as_mut_ptr(), - ); - vdeg = polynomial_mul( - d1deg, - d1.as_mut_ptr() as *const u64, - 1_i32, - v1.as_mut_ptr() as *const u64, - vdeg, - v.as_mut_ptr(), - ); + let mut tmpdeg = polynomial_mul(e1deg, &e1, 1_i32, &v, -1_i32, &mut tmp); + let mut vdeg = polynomial_mul(u1deg, &u1, tmpdeg, &tmp, -1_i32, &mut v); + vdeg = polynomial_mul(d1deg, &d1, 1_i32, &v1, vdeg, &mut v); i = 0_i32; while i <= vdeg { v[i as usize] = residue_mul(v[i as usize], c1[0_i32 as usize]); @@ -626,71 +529,26 @@ unsafe fn divisor_add(src1: *const TDivisor, src2: *const TDivisor, dst: *mut TD tmp[4] = F[4]; tmp[5] = F[5]; tmpdeg = 5_i32; - tmpdeg = polynomial_mul( - 1_i32, - v1.as_mut_ptr() as *const u64, - 1_i32, - v2.as_mut_ptr() as *const u64, - tmpdeg, - tmp.as_mut_ptr(), - ); - vdeg = polynomial_mul( - c2deg, - c2.as_mut_ptr() as *const u64, - tmpdeg, - tmp.as_mut_ptr() as *const u64, - vdeg, - v.as_mut_ptr(), - ); + tmpdeg = polynomial_mul(1_i32, &v1, 1_i32, &v2, tmpdeg, &mut tmp); + vdeg = polynomial_mul(c2deg, &c2, tmpdeg, &tmp, vdeg, &mut v); if ddeg > 0_i32 { let mut udiv: [u64; 5] = [0; 5]; - polynomial_div_monic( - udeg, - u.as_mut_ptr(), - ddeg, - d.as_mut_ptr() as *const u64, - udiv.as_mut_ptr(), - ); + polynomial_div_monic(udeg, &mut u, ddeg, &d, Some(&mut udiv)); udeg -= ddeg; - polynomial_div_monic( - udeg, - udiv.as_mut_ptr(), - ddeg, - d.as_mut_ptr() as *const u64, - u.as_mut_ptr(), - ); + polynomial_div_monic(udeg, &mut udiv, ddeg, &d, Some(&mut u)); udeg -= ddeg; if vdeg >= 0_i32 { - polynomial_div_monic( - vdeg, - v.as_mut_ptr(), - ddeg, - d.as_mut_ptr() as *const u64, - udiv.as_mut_ptr(), - ); + polynomial_div_monic(vdeg, &mut v, ddeg, &d, Some(&mut udiv)); vdeg -= ddeg; for i in 0..=vdeg { v[i as usize] = udiv[i as usize]; } } } - vdeg = polynomial_div_monic( - vdeg, - v.as_mut_ptr(), - udeg, - u.as_mut_ptr() as *const u64, - std::ptr::null_mut::(), - ); + vdeg = polynomial_div_monic(vdeg, &mut v, udeg, &u, None); while udeg > 2_i32 { // u' = monic((f-v^2)/u), v'=-v mod u' - tmpdeg = polynomial_mul( - vdeg, - v.as_mut_ptr() as *const u64, - vdeg, - v.as_mut_ptr() as *const u64, - -1_i32, - tmp.as_mut_ptr(), - ); + tmpdeg = polynomial_mul(vdeg, &v, vdeg, &v, -1_i32, &mut tmp); i = 0_i32; while i <= tmpdeg && i <= 5_i32 { tmp[i as usize] = residue_sub(F[i as usize], tmp[i as usize]); @@ -706,13 +564,7 @@ unsafe fn divisor_add(src1: *const TDivisor, src2: *const TDivisor, dst: *mut TD } tmpdeg = i - 1_i32; let mut udiv_0: [u64; 5] = [0; 5]; - polynomial_div_monic( - tmpdeg, - tmp.as_mut_ptr(), - udeg, - u.as_mut_ptr() as *const u64, - udiv_0.as_mut_ptr(), - ); + polynomial_div_monic(tmpdeg, &mut tmp, udeg, &u, Some(&mut udiv_0)); udeg = tmpdeg - udeg; let mult: u64 = residue_inv(udiv_0[udeg as usize]); i = 0_i32; @@ -726,60 +578,52 @@ unsafe fn divisor_add(src1: *const TDivisor, src2: *const TDivisor, dst: *mut TD v[i as usize] = residue_sub(0_i32 as u64, v[i as usize]); i += 1; } - vdeg = polynomial_div_monic( - vdeg, - v.as_mut_ptr(), - udeg, - u.as_mut_ptr() as *const u64, - std::ptr::null_mut::(), - ); + vdeg = polynomial_div_monic(vdeg, &mut v, udeg, &u, None); } if udeg == 2_i32 { - (*dst).u[0_i32 as usize] = u[0_i32 as usize]; - (*dst).u[1_i32 as usize] = u[1_i32 as usize]; - (*dst).v[0_i32 as usize] = if vdeg >= 0_i32 { + dst.u[0_i32 as usize] = u[0_i32 as usize]; + dst.u[1_i32 as usize] = u[1_i32 as usize]; + dst.v[0_i32 as usize] = if vdeg >= 0_i32 { v[0_i32 as usize] } else { 0_i32 as u64 }; - (*dst).v[1_i32 as usize] = if vdeg >= 1_i32 { + dst.v[1_i32 as usize] = if vdeg >= 1_i32 { v[1_i32 as usize] } else { 0_i32 as u64 }; } else if udeg == 1_i32 { - (*dst).u[0_i32 as usize] = u[0_i32 as usize]; - (*dst).u[1_i32 as usize] = BAD; - (*dst).v[0_i32 as usize] = if vdeg >= 0_i32 { + dst.u[0_i32 as usize] = u[0_i32 as usize]; + dst.u[1_i32 as usize] = BAD; + dst.v[0_i32 as usize] = if vdeg >= 0_i32 { v[0_i32 as usize] } else { 0_i32 as u64 }; - (*dst).v[1_i32 as usize] = BAD; + dst.v[1_i32 as usize] = BAD; } else { - (*dst).u[0_i32 as usize] = BAD; - (*dst).u[1_i32 as usize] = BAD; - (*dst).v[0_i32 as usize] = BAD; - (*dst).v[1_i32 as usize] = BAD; + dst.u[0_i32 as usize] = BAD; + dst.u[1_i32 as usize] = BAD; + dst.v[0_i32 as usize] = BAD; + dst.v[1_i32 as usize] = BAD; }; } -unsafe fn divisor_mul128( - src: *const TDivisor, - mut mult_lo: u64, - mut mult_hi: u64, - dst: *mut TDivisor, -) { +fn divisor_mul128(src: &TDivisor, mut mult_lo: u64, mut mult_hi: u64, dst: &mut TDivisor) { if mult_lo == 0_i32 as u64 && mult_hi == 0_i32 as u64 { - (*dst).u[0_i32 as usize] = BAD; - (*dst).u[1_i32 as usize] = BAD; - (*dst).v[0_i32 as usize] = BAD; - (*dst).v[1_i32 as usize] = BAD; + dst.u[0_i32 as usize] = BAD; + dst.u[1_i32 as usize] = BAD; + dst.v[0_i32 as usize] = BAD; + dst.v[1_i32 as usize] = BAD; return; } let mut cur: TDivisor = *src; while mult_lo & 1_i32 as u64 == 0 { - divisor_add(&cur, &cur, &mut cur); + { + let tmp = cur; + divisor_add(&tmp, &tmp, &mut cur); + } mult_lo >>= 1_i32; if mult_hi & 1_i32 as u64 != 0 { mult_lo |= 1_u64 << 63_i32; @@ -796,9 +640,12 @@ unsafe fn divisor_mul128( if mult_lo == 0_i32 as u64 && mult_hi == 0_i32 as u64 { break; } - divisor_add(&cur, &cur, &mut cur); + { + let tmp = cur; + divisor_add(&tmp, &tmp, &mut cur); + } if mult_lo & 1_i32 as u64 != 0 { - divisor_add(dst, &cur, dst); + divisor_add(&(dst.clone()), &cur, dst); } } } @@ -807,7 +654,7 @@ fn rol(x: u32, shift: i32) -> u32 { x << shift | x >> (32_i32 - shift) } -unsafe fn sha1_single_block(input: *mut u8, output: *mut u8) { +fn sha1_single_block(input: &[u8], output: &mut [u8]) { let mut a = 0x67452301_i32 as u32; let mut b = 0xefcdab89_u32; let mut c = 0x98badcfe_u32; @@ -816,10 +663,10 @@ unsafe fn sha1_single_block(input: *mut u8, output: *mut u8) { let mut w: [u32; 80] = [0; 80]; let mut i = 0_i32 as usize; while i < 16 { - w[i] = ((*input.add(4_usize.wrapping_mul(i)) as i32) << 24_i32 - | (*input.add(4_usize.wrapping_mul(i).wrapping_add(1)) as i32) << 16_i32 - | (*input.add(4_usize.wrapping_mul(i).wrapping_add(2)) as i32) << 8_i32 - | *input.add(4_usize.wrapping_mul(i).wrapping_add(3)) as i32) as u32; + w[i] = ((input[4_usize.wrapping_mul(i)] as i32) << 24_i32 + | (input[4_usize.wrapping_mul(i).wrapping_add(1)] as i32) << 16_i32 + | (input[4_usize.wrapping_mul(i).wrapping_add(2)] as i32) << 8_i32 + | input[4_usize.wrapping_mul(i).wrapping_add(3)] as i32) as u32; i = i.wrapping_add(1); } i = 16_i32 as usize; @@ -894,29 +741,29 @@ unsafe fn sha1_single_block(input: *mut u8, output: *mut u8) { c = c.wrapping_add(0x98badcfe_u32); d = d.wrapping_add(0x10325476_i32 as u32); e = e.wrapping_add(0xc3d2e1f0_u32); - *output.offset(0_i32 as isize) = (a >> 24_i32) as u8; - *output.offset(1_i32 as isize) = (a >> 16_i32) as u8; - *output.offset(2_i32 as isize) = (a >> 8_i32) as u8; - *output.offset(3_i32 as isize) = a as u8; - *output.offset(4_i32 as isize) = (b >> 24_i32) as u8; - *output.offset(5_i32 as isize) = (b >> 16_i32) as u8; - *output.offset(6_i32 as isize) = (b >> 8_i32) as u8; - *output.offset(7_i32 as isize) = b as u8; - *output.offset(8_i32 as isize) = (c >> 24_i32) as u8; - *output.offset(9_i32 as isize) = (c >> 16_i32) as u8; - *output.offset(10_i32 as isize) = (c >> 8_i32) as u8; - *output.offset(11_i32 as isize) = c as u8; - *output.offset(12_i32 as isize) = (d >> 24_i32) as u8; - *output.offset(13_i32 as isize) = (d >> 16_i32) as u8; - *output.offset(14_i32 as isize) = (d >> 8_i32) as u8; - *output.offset(15_i32 as isize) = d as u8; - *output.offset(16_i32 as isize) = (e >> 24_i32) as u8; - *output.offset(17_i32 as isize) = (e >> 16_i32) as u8; - *output.offset(18_i32 as isize) = (e >> 8_i32) as u8; - *output.offset(19_i32 as isize) = e as u8; + output[0] = (a >> 24_i32) as u8; + output[1] = (a >> 16_i32) as u8; + output[2] = (a >> 8_i32) as u8; + output[3] = a as u8; + output[4] = (b >> 24_i32) as u8; + output[5] = (b >> 16_i32) as u8; + output[6] = (b >> 8_i32) as u8; + output[7] = b as u8; + output[8] = (c >> 24_i32) as u8; + output[9] = (c >> 16_i32) as u8; + output[10] = (c >> 8_i32) as u8; + output[11] = c as u8; + output[12] = (d >> 24_i32) as u8; + output[13] = (d >> 16_i32) as u8; + output[14] = (d >> 8_i32) as u8; + output[15] = d as u8; + output[16] = (e >> 24_i32) as u8; + output[17] = (e >> 16_i32) as u8; + output[18] = (e >> 8_i32) as u8; + output[19] = e as u8; } -unsafe fn mix(buffer: *mut u8, buf_size: usize, key: *const u8, key_size: usize) { +fn mix(buffer: &mut [u8], buf_size: usize, key: &[u8], key_size: usize) { let mut sha1_input: [u8; 64] = [0; 64]; let mut sha1_result: [u8; 20] = [0; 20]; let half: usize = buf_size.wrapping_div(2); @@ -925,22 +772,16 @@ unsafe fn mix(buffer: *mut u8, buf_size: usize, key: *const u8, key_size: usize) for n in &mut sha1_input { *n = 0; } - ptr::copy_nonoverlapping(buffer.add(half), sha1_input.as_mut_ptr(), half); - ptr::copy_nonoverlapping( - key as *const c_void, - sha1_input.as_mut_ptr().add(half) as *mut c_void, - key_size, - ); + sha1_input[..half].copy_from_slice(&buffer[half..]); + sha1_input[half..half.wrapping_add(key_size)].copy_from_slice(key); sha1_input[half.wrapping_add(key_size)] = 0x80_i32 as u8; - sha1_input - [(::std::mem::size_of::<[u8; 64]>() as u64).wrapping_sub(1_i32 as u64) as usize] = + sha1_input[(size_of::<[u8; 64]>() as u64).wrapping_sub(1_i32 as u64) as usize] = half.wrapping_add(key_size).wrapping_mul(8) as u8; - sha1_input - [(::std::mem::size_of::<[u8; 64]>() as u64).wrapping_sub(2_i32 as u64) as usize] = + sha1_input[(size_of::<[u8; 64]>() as u64).wrapping_sub(2_i32 as u64) as usize] = half.wrapping_add(key_size) .wrapping_mul(8) .wrapping_div(0x100) as u8; - sha1_single_block(sha1_input.as_mut_ptr(), sha1_result.as_mut_ptr()); + sha1_single_block(&sha1_input, &mut sha1_result); let mut i = half & !3; while i < half { sha1_result[i] = sha1_result[i.wrapping_add(4).wrapping_sub(half & 3)]; @@ -948,17 +789,16 @@ unsafe fn mix(buffer: *mut u8, buf_size: usize, key: *const u8, key_size: usize) } i = 0_i32 as usize; while i < half { - let tmp: u8 = *buffer.add(i.wrapping_add(half)); - *buffer.add(i.wrapping_add(half)) = - (*buffer.add(i) as i32 ^ sha1_result[i] as i32) as u8; - *buffer.add(i) = tmp; + let tmp: u8 = buffer[i.wrapping_add(half)]; + buffer[i.wrapping_add(half)] = (buffer[i] as i32 ^ sha1_result[i] as i32) as u8; + buffer[i] = tmp; i = i.wrapping_add(1); } external_counter += 1; } } -unsafe fn unmix(buffer: *mut u8, buf_size: usize, key: *const u8, key_size: usize) { +fn unmix(buffer: &mut [u8], buf_size: usize, key: &[u8], key_size: usize) { let mut sha1_input: [u8; 64] = [0; 64]; let mut sha1_result: [u8; 20] = [0; 20]; let half: usize = buf_size.wrapping_div(2); @@ -967,18 +807,16 @@ unsafe fn unmix(buffer: *mut u8, buf_size: usize, key: *const u8, key_size: usiz for n in &mut sha1_input { *n = 0; } - ptr::copy_nonoverlapping(buffer, sha1_input.as_mut_ptr(), half); - ptr::copy_nonoverlapping(key, sha1_input.as_mut_ptr().add(half), key_size); + sha1_input[..half].copy_from_slice(&buffer[..half]); + sha1_input[half..half.wrapping_add(key_size)].copy_from_slice(key); sha1_input[half.wrapping_add(key_size)] = 0x80_i32 as u8; - sha1_input - [(::std::mem::size_of::<[u8; 64]>() as u64).wrapping_sub(1_i32 as u64) as usize] = + sha1_input[(size_of::<[u8; 64]>() as u64).wrapping_sub(1_i32 as u64) as usize] = half.wrapping_add(key_size).wrapping_mul(8) as u8; - sha1_input - [(::std::mem::size_of::<[u8; 64]>() as u64).wrapping_sub(2_i32 as u64) as usize] = + sha1_input[(size_of::<[u8; 64]>() as u64).wrapping_sub(2_i32 as u64) as usize] = half.wrapping_add(key_size) .wrapping_mul(8) .wrapping_div(0x100) as u8; - sha1_single_block(sha1_input.as_mut_ptr(), sha1_result.as_mut_ptr()); + sha1_single_block(&sha1_input, &mut sha1_result); let mut i = half & !3; while i < half { sha1_result[i] = sha1_result[i.wrapping_add(4).wrapping_sub(half & 3)]; @@ -986,33 +824,29 @@ unsafe fn unmix(buffer: *mut u8, buf_size: usize, key: *const u8, key_size: usiz } i = 0_i32 as usize; while i < half { - let tmp: u8 = *buffer.add(i); - *buffer.add(i) = - (*buffer.add(i.wrapping_add(half)) as i32 ^ sha1_result[i] as i32) as u8; - *buffer.add(i.wrapping_add(half)) = tmp; + let tmp: u8 = buffer[i]; + buffer[i] = (buffer[i.wrapping_add(half)] as i32 ^ sha1_result[i] as i32) as u8; + buffer[i.wrapping_add(half)] = tmp; i = i.wrapping_add(1); } external_counter += 1; } } -pub unsafe fn generate(installation_id_str: *const i8, confirmation_id: *mut i8) -> i32 { +pub fn generate(installation_id_str: &[u8], confirmation_id: &mut [u8]) -> i32 { let mut installation_id: [u8; 19] = [0; 19]; // 10**45 < 256**19 let mut installation_id_len: usize = 0_i32 as usize; - let mut p: *const i8 = installation_id_str; let mut count: usize = 0_i32 as usize; let mut total_count: usize = 0_i32 as usize; let mut check: u32 = 0_i32 as u32; - while *p != 0 { - if !(*p as i32 == ' ' as i32 || *p as i32 == '-' as i32) { - let d: i32 = *p as i32 - '0' as i32; + for p in installation_id_str.iter() { + let p_curr = *p as i8; + if !(p_curr as i32 == ' ' as i32 || p_curr as i32 == '-' as i32) { + let d: i32 = p_curr as i32 - '0' as i32; if !(0_i32..=9_i32).contains(&d) { return 3_i32; } - if count == 5 || *p.offset(1_i32 as isize) as i32 == 0_i32 { - if count == 0 { - return if total_count == 45 { 2_i32 } else { 1_i32 }; - } + if count == 5 { if d as u32 != check.wrapping_rem(7_i32 as u32) { return if count < 5 { 1_i32 } else { 4_i32 }; } @@ -1046,12 +880,11 @@ pub unsafe fn generate(installation_id_str: *const i8, confirmation_id: *mut i8) } } } - p = p.offset(1); } if total_count != 41 && total_count < 45 { return 1_i32; } - while installation_id_len < ::std::mem::size_of::<[u8; 19]>() { + while installation_id_len < size_of::<[u8; 19]>() { installation_id[installation_id_len] = 0_i32 as u8; installation_id_len = installation_id_len.wrapping_add(1); } @@ -1062,25 +895,32 @@ pub unsafe fn generate(installation_id_str: *const i8, confirmation_id: *mut i8) 0xd4_i32 as u8, ]; unmix( - installation_id.as_mut_ptr(), + &mut installation_id, (if total_count == 41 { 17_i32 } else { 19_i32 }) as usize, - IID_KEY.as_ptr(), + &IID_KEY, 4_i32 as usize, ); if installation_id[18_i32 as usize] as i32 >= 0x10_i32 { return 5_i32; } - let mut parsed: C2RustUnnamed4 = C2RustUnnamed4 { + let mut parsed = ParsedInstallationId { hardware_id: 0, product_id_low: 0, product_id_high: 0, key_sha1: 0, }; - ptr::copy_nonoverlapping( - installation_id.as_mut_ptr() as *const c_void, - &mut parsed as *mut C2RustUnnamed4 as *mut c_void, - std::mem::size_of::(), - ); + + let hardware_id_bytes: [u8; 8] = installation_id[0..8].try_into().unwrap(); + parsed.hardware_id = u64::from_le_bytes(hardware_id_bytes); + + let product_id_low_bytes: [u8; 8] = installation_id[8..16].try_into().unwrap(); + parsed.product_id_low = u64::from_le_bytes(product_id_low_bytes); + + parsed.product_id_high = installation_id[16]; + + let key_sha1_bytes: [u8; 2] = installation_id[17..19].try_into().unwrap(); + parsed.key_sha1 = u16::from_le_bytes(key_sha1_bytes); + let product_id_1: u32 = (parsed.product_id_low & ((1_i32 << 17_i32) - 1_i32) as u64) as u32; let product_id_2: u32 = (parsed.product_id_low >> 17_i32 & ((1_i32 << 10_i32) - 1_i32) as u64) as u32; @@ -1093,39 +933,33 @@ pub unsafe fn generate(installation_id_str: *const i8, confirmation_id: *mut i8) return 5_i32; } let mut keybuf: [u8; 16] = [0; 16]; - let mut hardware_id = parsed.hardware_id; - ptr::copy_nonoverlapping( - &mut hardware_id as *mut u64 as *const c_void, - keybuf.as_mut_ptr() as *mut c_void, - 8, - ); - let mut product_id_mixed: u64 = (product_id_1 as u64) << 41_i32 + keybuf[..8].copy_from_slice(&parsed.hardware_id.to_le_bytes()[..8]); + let product_id_mixed: u64 = (product_id_1 as u64) << 41_i32 | (product_id_2 as u64) << 58_i32 | (product_id_3 as u64) << 17_i32 | product_id_4 as u64; - ptr::copy_nonoverlapping( - &mut product_id_mixed as *mut u64 as *const c_void, - keybuf.as_mut_ptr().offset(8) as *mut c_void, - 8, - ); + keybuf[8..16].copy_from_slice(&product_id_mixed.to_le_bytes()[..8]); let mut d_0: TDivisor = TDivisor { u: [0; 2], v: [0; 2], }; let mut attempt = 0_i32 as u8; while attempt as i32 <= 0x80_i32 { - let mut u: C2RustUnnamed3 = C2RustUnnamed3 { buffer: [0; 14] }; - u.c2rust_unnamed.lo = 0_i32 as u64; - u.c2rust_unnamed.hi = 0_i32 as u64; - u.buffer[7_i32 as usize] = attempt; - mix( - (u.buffer).as_mut_ptr(), - 14_i32 as usize, - keybuf.as_mut_ptr(), - 16_i32 as usize, + let mut u: [u8; 14] = [0; 14]; + u[7_i32 as usize] = attempt; + mix(&mut u, 14_i32 as usize, &keybuf, 16_i32 as usize); + let u_lo = u64::from_le_bytes(u[0..8].try_into().unwrap()); + let u_hi = u64::from_le_bytes( + u[8..14] + .iter() + .chain([0, 0].iter()) + .cloned() + .collect::>()[..] + .try_into() + .unwrap(), ); - let mut x2: u64 = ui128_quotient_mod(u.c2rust_unnamed.lo, u.c2rust_unnamed.hi); - let x1: u64 = u.c2rust_unnamed.lo.wrapping_sub(x2.wrapping_mul(MOD)); + let mut x2: u64 = ui128_quotient_mod(u_lo, u_hi); + let x1: u64 = u_lo.wrapping_sub(x2.wrapping_mul(MOD)); x2 = x2.wrapping_add(1); d_0.u[0_i32 as usize] = residue_sub( residue_mul(x1, x1), @@ -1141,35 +975,28 @@ pub unsafe fn generate(installation_id_str: *const i8, confirmation_id: *mut i8) return 6_i32; } divisor_mul128( - &d_0, + &(d_0.clone()), 0x4e21b9d10f127c1_i64 as u64, 0x40da7c36d44c_i64 as u64, &mut d_0, ); - let mut e: C2RustUnnamed0 = C2RustUnnamed0 { - c2rust_unnamed: C2RustUnnamed1 { - encoded_lo: 0, - encoded_hi: 0, - }, + let mut e = Encoded { + encoded_lo: 0, + encoded_hi: 0, }; if d_0.u[0_i32 as usize] == BAD { // we can not get the zero divisor, actually... - e.c2rust_unnamed.encoded_lo = umul128( - MOD.wrapping_add(2_i32 as u64), - MOD, - &mut e.c2rust_unnamed.encoded_hi, - ); + e.encoded_lo = umul128(MOD.wrapping_add(2_i32 as u64), MOD, &mut e.encoded_hi); } else if d_0.u[1_i32 as usize] == BAD { - e.c2rust_unnamed.encoded_lo = umul128( + e.encoded_lo = umul128( MOD.wrapping_add(1_i32 as u64), d_0.u[0_i32 as usize], - &mut e.c2rust_unnamed.encoded_hi, + &mut e.encoded_hi, ); - e.c2rust_unnamed.encoded_lo = e.c2rust_unnamed.encoded_lo.wrapping_add(MOD); - e.c2rust_unnamed.encoded_hi = e - .c2rust_unnamed + e.encoded_lo = e.encoded_lo.wrapping_add(MOD); + e.encoded_hi = e .encoded_hi - .wrapping_add((e.c2rust_unnamed.encoded_lo < MOD) as i32 as u64); + .wrapping_add((e.encoded_lo < MOD) as i32 as u64); } else { let x1_0: u64 = (if d_0.u[1_i32 as usize] as i32 % 2_i32 != 0 { d_0.u[1_i32 as usize].wrapping_add(MOD) @@ -1181,16 +1008,15 @@ pub unsafe fn generate(installation_id_str: *const i8, confirmation_id: *mut i8) let mut x2_0: u64 = residue_sqrt(x2sqr); if x2_0 == BAD { x2_0 = residue_sqrt(residue_mul(x2sqr, residue_inv(43_i32 as u64))); - e.c2rust_unnamed.encoded_lo = umul128( + e.encoded_lo = umul128( MOD.wrapping_add(1_i32 as u64), MOD.wrapping_add(x2_0), - &mut e.c2rust_unnamed.encoded_hi, + &mut e.encoded_hi, ); - e.c2rust_unnamed.encoded_lo = e.c2rust_unnamed.encoded_lo.wrapping_add(x1_0); - e.c2rust_unnamed.encoded_hi = e - .c2rust_unnamed + e.encoded_lo = e.encoded_lo.wrapping_add(x1_0); + e.encoded_hi = e .encoded_hi - .wrapping_add((e.c2rust_unnamed.encoded_lo < x1_0) as i32 as u64); + .wrapping_add((e.encoded_lo < x1_0) as i32 as u64); } else { // points (-x1+x2, v(-x1+x2)) and (-x1-x2, v(-x1-x2)) let mut x1a: u64 = residue_sub(x1_0, x2_0); @@ -1204,72 +1030,67 @@ pub unsafe fn generate(installation_id_str: *const i8, confirmation_id: *mut i8) residue_mul(d_0.v[1_i32 as usize], x2a), ); if x1a > x2a { - std::mem::swap(&mut x1a, &mut x2a); + swap(&mut x1a, &mut x2a); } if (y1 ^ y2) & 1_i32 as u64 != 0 { - std::mem::swap(&mut x1a, &mut x2a); + swap(&mut x1a, &mut x2a); } - e.c2rust_unnamed.encoded_lo = umul128( - MOD.wrapping_add(1_i32 as u64), - x1a, - &mut e.c2rust_unnamed.encoded_hi, - ); - e.c2rust_unnamed.encoded_lo = e.c2rust_unnamed.encoded_lo.wrapping_add(x2a); - e.c2rust_unnamed.encoded_hi = e - .c2rust_unnamed + e.encoded_lo = umul128(MOD.wrapping_add(1_i32 as u64), x1a, &mut e.encoded_hi); + e.encoded_lo = e.encoded_lo.wrapping_add(x2a); + e.encoded_hi = e .encoded_hi - .wrapping_add((e.c2rust_unnamed.encoded_lo < x2a) as i32 as u64); + .wrapping_add((e.encoded_lo < x2a) as i32 as u64); } } + let mut e_2 = [ + u32::from_le_bytes(e.encoded_lo.to_le_bytes()[0..4].try_into().unwrap()), + u32::from_le_bytes(e.encoded_lo.to_le_bytes()[4..].try_into().unwrap()), + u32::from_le_bytes(e.encoded_hi.to_le_bytes()[0..4].try_into().unwrap()), + u32::from_le_bytes(e.encoded_hi.to_le_bytes()[4..].try_into().unwrap()), + ]; let mut decimal: [u8; 35] = [0; 35]; let mut i = 0_i32 as usize; while i < 35 { - let c: u32 = (e.c2rust_unnamed_0.encoded[3_i32 as usize]).wrapping_rem(10_i32 as u32); - e.c2rust_unnamed_0.encoded[3_i32 as usize] = - e.c2rust_unnamed_0.encoded[3_i32 as usize].wrapping_div(10_i32 as u32); - let c2: u32 = ((c as u64) << 32_i32 | e.c2rust_unnamed_0.encoded[2_i32 as usize] as u64) - .wrapping_rem(10_i32 as u64) as u32; - e.c2rust_unnamed_0.encoded[2_i32 as usize] = - ((c as u64) << 32_i32 | e.c2rust_unnamed_0.encoded[2_i32 as usize] as u64) - .wrapping_div(10_i32 as u64) as u32; - let c3: u32 = ((c2 as u64) << 32_i32 | e.c2rust_unnamed_0.encoded[1_i32 as usize] as u64) - .wrapping_rem(10_i32 as u64) as u32; - e.c2rust_unnamed_0.encoded[1_i32 as usize] = - ((c2 as u64) << 32_i32 | e.c2rust_unnamed_0.encoded[1_i32 as usize] as u64) - .wrapping_div(10_i32 as u64) as u32; - let c4: u32 = ((c3 as u64) << 32_i32 | e.c2rust_unnamed_0.encoded[0_i32 as usize] as u64) - .wrapping_rem(10_i32 as u64) as u32; - e.c2rust_unnamed_0.encoded[0_i32 as usize] = - ((c3 as u64) << 32_i32 | e.c2rust_unnamed_0.encoded[0_i32 as usize] as u64) - .wrapping_div(10_i32 as u64) as u32; + let c: u32 = (e_2[3_i32 as usize]).wrapping_rem(10_i32 as u32); + e_2[3_i32 as usize] = e_2[3_i32 as usize].wrapping_div(10_i32 as u32); + let c2: u32 = + ((c as u64) << 32_i32 | e_2[2_i32 as usize] as u64).wrapping_rem(10_i32 as u64) as u32; + e_2[2_i32 as usize] = + ((c as u64) << 32_i32 | e_2[2_i32 as usize] as u64).wrapping_div(10_i32 as u64) as u32; + let c3: u32 = + ((c2 as u64) << 32_i32 | e_2[1_i32 as usize] as u64).wrapping_rem(10_i32 as u64) as u32; + e_2[1_i32 as usize] = + ((c2 as u64) << 32_i32 | e_2[1_i32 as usize] as u64).wrapping_div(10_i32 as u64) as u32; + let c4: u32 = + ((c3 as u64) << 32_i32 | e_2[0_i32 as usize] as u64).wrapping_rem(10_i32 as u64) as u32; + e_2[0_i32 as usize] = + ((c3 as u64) << 32_i32 | e_2[0_i32 as usize] as u64).wrapping_div(10_i32 as u64) as u32; decimal[34_usize.wrapping_sub(i)] = c4 as u8; i = i.wrapping_add(1); } - let mut q: *mut i8 = confirmation_id; - i = 0_i32 as usize; + let q = confirmation_id; + let mut i: usize = 0; + let mut q_i = 0; while i < 7 { if i != 0 { - let fresh2 = q; - q = q.offset(1); - *fresh2 = '-' as i32 as i8; + q[q_i] = b'-'; + q_i += 1; } - let p_0: *mut u8 = decimal.as_mut_ptr().add(i.wrapping_mul(5)); - *q.offset(0_i32 as isize) = (*p_0.offset(0_i32 as isize) as i32 + '0' as i32) as i8; - *q.offset(1_i32 as isize) = (*p_0.offset(1_i32 as isize) as i32 + '0' as i32) as i8; - *q.offset(2_i32 as isize) = (*p_0.offset(2_i32 as isize) as i32 + '0' as i32) as i8; - *q.offset(3_i32 as isize) = (*p_0.offset(3_i32 as isize) as i32 + '0' as i32) as i8; - *q.offset(4_i32 as isize) = (*p_0.offset(4_i32 as isize) as i32 + '0' as i32) as i8; - *q.offset(5_i32 as isize) = ((*p_0.offset(0_i32 as isize) as i32 - + *p_0.offset(1_i32 as isize) as i32 * 2_i32 - + *p_0.offset(2_i32 as isize) as i32 - + *p_0.offset(3_i32 as isize) as i32 * 2_i32 - + *p_0.offset(4_i32 as isize) as i32) + let p_0: &mut [u8] = &mut decimal[i.wrapping_mul(5)..]; + q[q_i] = (p_0[0] as i32 + '0' as i32) as u8; + q[q_i + 1] = (p_0[1] as i32 + '0' as i32) as u8; + q[q_i + 2] = (p_0[2] as i32 + '0' as i32) as u8; + q[q_i + 3] = (p_0[3] as i32 + '0' as i32) as u8; + q[q_i + 4] = (p_0[4] as i32 + '0' as i32) as u8; + q[q_i + 5] = ((p_0[0] as i32 + + p_0[1] as i32 * 2_i32 + + p_0[2] as i32 + + p_0[3] as i32 * 2_i32 + + p_0[4] as i32) % 7_i32 - + '0' as i32) as i8; - q = q.offset(6_i32 as isize); + + '0' as i32) as u8; + q_i = q_i.wrapping_add(6); i = i.wrapping_add(1); } - let fresh3 = q.offset(1); - *fresh3 = 0_i32 as i8; 0_i32 } diff --git a/umskt/src/confid/mod.rs b/umskt/src/confid/mod.rs index 077c2f5..4b81a92 100644 --- a/umskt/src/confid/mod.rs +++ b/umskt/src/confid/mod.rs @@ -1,5 +1,13 @@ -use std::ffi::{CStr, CString}; - +//! Code to generate a Confirmation ID for a given Installation ID +//! +//! ## History +//! The algorithm this uses was originally provided to the UMSKT project by diamondggg. +//! The history provided by diamondggg is that they are the originator of the code +//! and was created in tandem with an acquaintance who knows number theory. +//! The file dates suggest this code was written sometime in 2017/2018. +//! +//! The Rust version of the code was created by running the original through C2Rust +//! and then manually fixing up the result. use thiserror::Error; mod black_box; @@ -20,6 +28,10 @@ pub enum ConfirmationIdError { Unlucky, } +/// Generates a confirmation ID from the given installation ID +/// +/// # Arguments +/// * `installation_id` - A string with 7 groups of 6 digits, with or without hyphens pub fn generate(installation_id: &str) -> Result { if installation_id.len() < 54 { return Err(ConfirmationIdError::TooShort); @@ -27,9 +39,9 @@ pub fn generate(installation_id: &str) -> Result { if installation_id.len() > 54 { return Err(ConfirmationIdError::TooLarge); } - let inst_id = CString::new(installation_id).unwrap(); - let conf_id = [0u8; 49]; - let result = unsafe { black_box::generate(inst_id.as_ptr(), conf_id.as_ptr() as *mut i8) }; + let inst_id = installation_id.as_bytes(); + let mut conf_id = [0u8; 48]; + let result = black_box::generate(inst_id, &mut conf_id); match result { 0 => {} 1 => return Err(ConfirmationIdError::TooShort), @@ -40,12 +52,7 @@ pub fn generate(installation_id: &str) -> Result { 6 => return Err(ConfirmationIdError::Unlucky), _ => panic!("Unknown error code: {}", result), } - unsafe { - Ok(CStr::from_ptr(conf_id.as_ptr() as *const i8) - .to_str() - .unwrap() - .to_string()) - } + Ok(String::from_utf8_lossy(&conf_id).into()) } #[cfg(test)] diff --git a/umskt/src/crypto.rs b/umskt/src/crypto.rs index 831971a..5ad2491 100644 --- a/umskt/src/crypto.rs +++ b/umskt/src/crypto.rs @@ -1,24 +1,42 @@ +//! Code that deals with elliptic curve cryptography use anyhow::Result; -use openssl::{ - bn::{BigNum, BigNumContext}, - ec::{EcGroup, EcPoint}, -}; +use num_bigint::BigInt; +use num_integer::Integer; +use num_traits::{Num, One, Zero}; -pub struct EllipticCurve { - pub curve: EcGroup, - pub gen_point: EcPoint, - pub pub_point: EcPoint, +/// Represents a point (possibly) on an elliptic curve. +/// +/// This is either the point at infinity, or a point with affine coordinates `x` and `y`. +/// It is not guaranteed to be on the curve. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Point { + Infinity, + Point { x: BigInt, y: BigInt }, } +/// Represents an elliptic curve of the form `y^2 = x^3 + ax + b (mod p)` +/// +/// `b` is not used in any of the calculations, so is not stored. +/// +/// This implements all the necessary elliptic curve arithmetic for verifying and generating +/// product keys. +pub struct EllipticCurve { + a: BigInt, + p: BigInt, + pub gen_point: Point, + pub pub_point: Point, +} + +/// Stores the additional data necessary to generate product keys. pub struct PrivateKey { - pub gen_order: BigNum, - pub private_key: BigNum, + pub gen_order: BigInt, + pub private_key: BigInt, } impl PrivateKey { pub fn new(gen_order: &str, private_key: &str) -> Result { - let gen_order = BigNum::from_dec_str(gen_order)?; - let private_key = &gen_order - &BigNum::from_dec_str(private_key)?; + let gen_order = BigInt::from_str_radix(gen_order, 10)?; + let private_key = BigInt::from_str_radix(private_key, 10)?; Ok(Self { gen_order, private_key, @@ -27,37 +45,179 @@ impl PrivateKey { } impl EllipticCurve { + /// Creates a new elliptic curve from the given parameters. `b` is not necessary. pub fn new( p: &str, a: &str, - b: &str, generator_x: &str, generator_y: &str, public_key_x: &str, public_key_y: &str, ) -> Result { - let mut context = BigNumContext::new()?; + let p = BigInt::from_str_radix(p, 10)?; + let a = BigInt::from_str_radix(a, 10)?; + let generator_x = BigInt::from_str_radix(generator_x, 10)?; + let generator_y = BigInt::from_str_radix(generator_y, 10)?; + let public_key_x = BigInt::from_str_radix(public_key_x, 10)?; + let public_key_y = BigInt::from_str_radix(public_key_y, 10)?; - let p = BigNum::from_dec_str(p)?; - let a = BigNum::from_dec_str(a)?; - let b = BigNum::from_dec_str(b)?; - let generator_x = BigNum::from_dec_str(generator_x)?; - let generator_y = BigNum::from_dec_str(generator_y)?; - let public_key_x = BigNum::from_dec_str(public_key_x)?; - let public_key_y = BigNum::from_dec_str(public_key_y)?; + let gen_point = Point::Point { + x: generator_x, + y: generator_y, + }; - let curve = EcGroup::from_components(p, a, b, &mut context)?; - - let mut gen_point = EcPoint::new(&curve)?; - gen_point.set_affine_coordinates_gfp(&curve, &generator_x, &generator_y, &mut context)?; - - let mut pub_point = EcPoint::new(&curve)?; - pub_point.set_affine_coordinates_gfp(&curve, &public_key_x, &public_key_y, &mut context)?; + let pub_point = Point::Point { + x: public_key_x, + y: public_key_y, + }; Ok(Self { - curve, + a, + p, gen_point, pub_point, }) } + + fn mod_inverse(a: &BigInt, p: &BigInt) -> BigInt { + let egcd = a.extended_gcd(p); + egcd.x.mod_floor(p) + } + + fn double_point(&self, point: &Point) -> Point { + match point { + Point::Point { x, y } => { + if y.is_zero() { + Point::Infinity + } else { + let three = BigInt::from(3); + let two = BigInt::from(2); + + let lambda = (three * x * x + &self.a) * Self::mod_inverse(&(two * y), &self.p); + let lamba_sqr = (&lambda * &lambda).mod_floor(&self.p); + let x3 = (&lamba_sqr - x - x).mod_floor(&self.p); + let y3 = (&lambda * (x - &x3) - y).mod_floor(&self.p); + + Point::Point { x: x3, y: y3 } + } + } + Point::Infinity => Point::Infinity, + } + } + + /// Adds two points on the curve together. + /// + /// If the points are the same, it doubles the point. + /// + /// If one of the points is the point at infinity, it returns the other point. + /// + /// If both points are the point at infinity, it returns the point at infinity. + pub(crate) fn add_points(&self, point1: &Point, point2: &Point) -> Point { + match (point1, point2) { + (Point::Point { x: x1, y: y1 }, Point::Point { x: x2, y: y2 }) => { + if point1 == point2 { + self.double_point(point1) + } else { + let lambda = (y2 - y1) * Self::mod_inverse(&(x2 - x1), &self.p); + let x3 = ((&lambda * &lambda) - x1 - x2).mod_floor(&self.p); + let y3: BigInt = ((&lambda * (x1 - &x3)) - y1).mod_floor(&self.p); + + Point::Point { x: x3, y: y3 } + } + } + (Point::Point { x, y }, Point::Infinity) | (Point::Infinity, Point::Point { x, y }) => { + Point::Point { + x: x.clone(), + y: y.clone(), + } + } + (Point::Infinity, Point::Infinity) => Point::Infinity, + } + } + + /// Multiplies a point by a scalar. + /// + /// Uses the double-and-add algorithm. + pub(crate) fn multiply_point(&self, s: &BigInt, point: &Point) -> Point { + let mut res = Point::Infinity; + let mut temp = point.clone(); + + let mut s = s.clone(); + + while s > BigInt::zero() { + if (&s % BigInt::from(2)) == BigInt::one() { + res = self.add_points(&res, &temp); + } + temp = self.double_point(&temp); + + s >>= 1; + } + + res + } +} + +/// Calculates the legendre symbol of `p`: `1`, `0`, or `-1 mod p` +fn ls(a: &BigInt, p: &BigInt) -> BigInt { + let exp = (p - BigInt::one()) / BigInt::from(2); + a.modpow(&exp, p) +} + +/// Calculates the modular square root of `n` such that `result^2 = n (mod p)` +/// using the Tonelli-Shanks algorithm. Returns `None` if `p` is not prime. +/// +/// # Arguments +/// +/// * `n` - The number to find the square root of +/// * `p` - The prime modulus (_must_ be prime) +pub(crate) fn mod_sqrt(n: &BigInt, p: &BigInt) -> Option { + if !ls(n, p).is_one() { + return None; + } + + let mut q = p - 1; + let mut s = BigInt::zero(); + while (&q & &BigInt::one()).is_zero() { + s += 1; + q >>= 1 + } + + if s.is_one() { + let exp = (p + 1) / 4; + let r1 = n.modpow(&exp, p); + return Some(p - &r1); + } + + let mut z = BigInt::from(2); + while ls(&z, p) != p - 1 { + z += 1 + } + let mut c = z.modpow(&q, p); + + let mut r = n.modpow(&((&q + 1) / 2), p); + let mut t = n.modpow(&q, p); + let mut m = s; + + loop { + if t.is_one() { + return Some(p - &r); + } + + let mut i = BigInt::zero(); + let mut z = t.clone(); + let mut b = c.clone(); + while !z.is_one() && i < &m - 1 { + z = &z * &z % p; + i += 1; + } + let mut e = &m - &i - 1; + while e > BigInt::zero() { + b = &b * &b % p; + e -= 1; + } + r = &r * &b % p; + c = &b * &b % p; + t = &t * &c % p; + m = i; + } } diff --git a/umskt/src/key.rs b/umskt/src/key.rs index 562a8a2..4dd8b2d 100644 --- a/umskt/src/key.rs +++ b/umskt/src/key.rs @@ -1,7 +1,9 @@ use std::collections::VecDeque; use anyhow::{anyhow, Result}; -use openssl::bn::BigNum; +use num_bigint::{BigInt, Sign}; +use num_integer::Integer; +use num_traits::{ToPrimitive, Zero}; const PK_LENGTH: usize = 25; @@ -17,20 +19,24 @@ pub(crate) fn base24_decode(cd_key: &str) -> Result> { .filter_map(|c| KEY_CHARSET.iter().position(|&x| x == c).map(|i| i as u8)) .collect(); - let mut y = BigNum::from_u32(0).unwrap(); + let mut y = BigInt::zero(); for i in decoded_key { - y.mul_word((PK_LENGTH - 1) as u32).unwrap(); - y.add_word(i.into()).unwrap(); + y *= PK_LENGTH - 1; + y += i as u32; } - Ok(y.to_vec()) + Ok(y.to_bytes_be().1) } pub(crate) fn base24_encode(byte_seq: &[u8]) -> Result { - let mut z = BigNum::from_slice(byte_seq).unwrap(); + let mut z = BigInt::from_bytes_be(Sign::Plus, byte_seq); let mut out: VecDeque = VecDeque::new(); - (0..=24).for_each(|_| out.push_front(KEY_CHARSET[z.div_word(24).unwrap() as usize])); + (0..=24).for_each(|_| { + let (quo, rem) = z.div_rem(&BigInt::from(24)); + z = quo; + out.push_front(KEY_CHARSET[rem.to_u32().unwrap() as usize]); + }); Ok(out.iter().collect()) } diff --git a/umskt/src/lib.rs b/umskt/src/lib.rs index 2910152..1a1a8ca 100644 --- a/umskt/src/lib.rs +++ b/umskt/src/lib.rs @@ -1,3 +1,13 @@ +//! # Universal MS Key Toolkit (UMSKT) Rust Edition Rust Edition +//! +//! This is an unofficial Rust port of the [UMSKT project](https://github.com/UMSKT/UMSKT/). +//! It is a pure Rust implementation rather than a binding, so it does not require any C or +//! C++ dependencies and can be built for any platform supported by Rust and `std`. +//! +//! It does not include the required `keys.json` file used by UMSKT. That needs to be found elsewhere. +//! +//! See `README.md` for more information. +//! pub mod bink1998; pub mod bink2002; pub mod confid;