Update README.md

This commit is contained in:
WitherOrNot 2023-06-28 01:38:46 -04:00 committed by GitHub
parent c4f4965e96
commit b8820e1161
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 19 additions and 17 deletions

View File

@ -72,20 +72,22 @@ Note that in many cases, $q'(x)$ will be an irreducible (non-factorable) polynom
## Mumford representation ## Mumford representation
The Mumford representation of a semi-reduced divisor $D=\sum c_i(x_i,y_i)$ is the pair of polynomials $u(x)$ and $v(x)$: The Mumford representation of a semi-reduced divisor $D=\sum c_i(x_i,y_i)$ is the unique pair of polynomials $u(x)$ and $v(x)$ where:
$$ u(x) = \prod_{i=1}^{n} (x-x_i)^{c_i} $$ $$ u(x) = \prod_{i=1}^{n} (x-x_i)^{c_i} $$
$$ v^2 \equiv F \pmod {u} $$ $$ v^2 \equiv F \pmod {u}$$
$$\mathrm{deg}(v) \lt \mathrm{deg}(u)$$
With this, the divisor can now be re-defined as $D=\langle u(x), v(x) \rangle$. With this, the divisor can now be re-defined as $D=\langle u(x), v(x) \rangle$.
From the previous observations, it can be seen that $u$ and $v$ in this representation exactly the polynomials $u$ and $v$ from the reduction steps above. Therefore, the reduction algorithm is much more concise using the Mumford representation. From the previous observations, it can be seen that $u$ and $v$ in this representation are exactly the polynomials $u$ and $v$ from the reduction steps above. Therefore, the reduction algorithm is much more concise using the Mumford representation.
Reduction algorithm for $D=\langle u,v \rangle$: Reduction algorithm for $D=\langle u,v \rangle$:
1. Let $u' = \frac{F-v^2}{u}$ 1. Let $u' = \frac{F-v^2}{u}$
2. Let $v' = -u \bmod p$ 2. Let $v' = -v \bmod u'$
3. If $deg(u') \leq g$, then stop. $E = \left\langle u', v' \right\rangle$ is the reduction of $D$. Otherwise, let $u=u'$ and $v=v'$ and start from step 1. 3. If $\mathrm{deg}(u') \leq g$, then stop. $E = \left\langle u', v' \right\rangle$ is the reduction of $D$. Otherwise, let $u=u'$ and $v=v'$ and start from step 1.
With the Mumford representation and reduction defined, we are ready to state the central problem of hyperelliptic curve cryptography. With the Mumford representation and reduction defined, we are ready to state the central problem of hyperelliptic curve cryptography.
@ -204,16 +206,16 @@ function decrypt_feistel(data, key):
The decrypted IID data is either 17 or 19 bytes, with the following structure: The decrypted IID data is either 17 or 19 bytes, with the following structure:
``` ```c++
struct DecryptedIID { struct DecryptedIID {
byte hwid[8]; byte hwid[8];
// The following values correspond to the product code // The following values correspond to the product code
// rpc-chid-seq-last // rpc-chid-seq-last
uint last : 17 bits; uint last : 17;
uint version : 3 bits; // 4 for XP RTM, 5 for XP SP1+ uint version : 3; // 4 for XP RTM, 5 for XP SP1+
uint seq : 24 bits; uint seq : 24;
uint chid : 10 bits; uint chid : 10;
uint rpc : 9 bits; uint rpc : 9;
ushort key_hash; // Only in SP1+, contains 12 bits of product key hash ushort key_hash; // Only in SP1+, contains 12 bits of product key hash
} }
``` ```
@ -228,13 +230,13 @@ Finally, the value $D_E$ from the previous section is converted to little endian
The structure of the decrypted CID data is as follows: The structure of the decrypted CID data is as follows:
``` ```c++
struct DecryptedCID { struct DecryptedCID {
byte key_hash[6]; // Genuine CIDs have bytes of the product key hash stored here, but they're usually not checked byte key_hash[6]; // Genuine CIDs have bytes of the product key hash stored here, but they're usually not checked
bool check_hash; // key_hash is checked only if this byte is true bool check_hash; // key_hash is checked only if this byte is true
byte attempt; // When generating CIDs, this byte is incremented for each generation attempt, maximum of 0x80 times byte attempt; // When generating CIDs, this byte is incremented for each generation attempt, maximum of 0x80 times
byte zero[6]; // Must be zeroes byte zero[6]; // Must be zeroes
} };
``` ```
# Parameter Extraction # Parameter Extraction
@ -255,7 +257,7 @@ The parameters for confirmation ID generation are stored in `licdll.dll` (Window
An example when run on Windows XP SP3's `licdll.dll` with IDA is provided below. An example when run on Windows XP SP3's `licdll.dll` with IDA is provided below.
``` ```c
int __stdcall sub_6107FAF4(int a1) int __stdcall sub_6107FAF4(int a1)
{ {
int v1; // edi int v1; // edi
@ -289,12 +291,12 @@ int __stdcall sub_6107FAF4(int a1)
The variable `a1` is a pointer to a `WPAHyperellipticParams` struct with the following layout: The variable `a1` is a pointer to a `WPAHyperellipticParams` struct with the following layout:
``` ```c
// BigInts are stored as 2 DWORDs in little endian order // BigInts are stored as 2 DWORDs in little endian order
struct BigInt { struct BigInt {
uint low; uint low;
uint high; uint high;
} };
struct WPAHyperellipticParams { struct WPAHyperellipticParams {
uint genus; // Genus of the curve, almost always 2 uint genus; // Genus of the curve, almost always 2
@ -303,7 +305,7 @@ struct WPAHyperellipticParams {
uint public_multiplier; // Value multiplied by initial divisor to verify CID uint public_multiplier; // Value multiplied by initial divisor to verify CID
uint modulus[modulus_size]; // Prime modulus of curve uint modulus[modulus_size]; // Prime modulus of curve
BigInt coefficients[6]; // Coefficients of F(x) in order of lowest to highest degree BigInt coefficients[6]; // Coefficients of F(x) in order of lowest to highest degree
} };
``` ```
Then, download the private key solver from [here](https://github.com/UMSKT/XPCIDSolver). Edit solve.py to include the parameters from the DLL, run `Install.sh`, then run `solve.py`. The solver will then output the private key for the curve, which can then be used to generate confirmation IDs. Then, download the private key solver from [here](https://github.com/UMSKT/XPCIDSolver). Edit solve.py to include the parameters from the DLL, run `Install.sh`, then run `solve.py`. The solver will then output the private key for the curve, which can then be used to generate confirmation IDs.