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;