mirror of
https://github.com/Neo-Desktop/WindowsXPKg
synced 2024-12-22 20:40:16 +02:00
QWORD upgrade, abstract NEXTNBITS()
This commit is contained in:
parent
1c5f93b687
commit
799fee5a68
@ -39,7 +39,8 @@
|
|||||||
#define FIELD_BITS_2003 512
|
#define FIELD_BITS_2003 512
|
||||||
#define FIELD_BYTES_2003 64
|
#define FIELD_BYTES_2003 64
|
||||||
|
|
||||||
#define FIRSTNBITS(field, n) ((field) & ((1ULL << (n)) - 1))
|
#define NEXTNBITS(field, n, offset) (((QWORD)field >> offset) & ((1ULL << (n)) - 1))
|
||||||
|
#define FIRSTNBITS(field, n) NEXTNBITS(field, n, 0)
|
||||||
|
|
||||||
// Confirmation ID generator constants
|
// Confirmation ID generator constants
|
||||||
#define SUCCESS 0
|
#define SUCCESS 0
|
||||||
|
15
src/main.cpp
15
src/main.cpp
@ -124,15 +124,18 @@ int main(int argc, char *argv[]) {
|
|||||||
// generate a key
|
// generate a key
|
||||||
BN_sub(privateKey, genOrder, privateKey);
|
BN_sub(privateKey, genOrder, privateKey);
|
||||||
nRaw <<= 1;
|
nRaw <<= 1;
|
||||||
|
int count = 0, total = 1000;
|
||||||
|
|
||||||
generateXPKey(eCurve, genPoint, genOrder, privateKey, nRaw, pKey);
|
for (int i = 0; i < total; i++) {
|
||||||
print_product_key(pKey);
|
generateXPKey(eCurve, genPoint, genOrder, privateKey, nRaw, pKey);
|
||||||
std::cout << std::endl << std::endl;
|
print_product_key(pKey);
|
||||||
|
std::cout << std::endl << std::endl;
|
||||||
|
|
||||||
// verify the key
|
// verify the key
|
||||||
if (!verifyXPKey(eCurve, genPoint, pubPoint, pKey)) {
|
count += verifyXPKey(eCurve, genPoint, pubPoint, pKey);
|
||||||
std::cout << "Fail! Key is invalid." << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << "Success count: " << std::dec << count << "/" << total << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
26
src/xp.cpp
26
src/xp.cpp
@ -18,7 +18,7 @@
|
|||||||
#include "header.h"
|
#include "header.h"
|
||||||
|
|
||||||
/* Unpacks the Windows XP Product Key. */
|
/* Unpacks the Windows XP Product Key. */
|
||||||
void unpackXP(DWORD (&pRaw)[4], DWORD &pSerial, DWORD &pHash, QWORD &pSignature) {
|
void unpackXP(QWORD (&pRaw)[2], DWORD &pSerial, DWORD &pHash, QWORD &pSignature) {
|
||||||
|
|
||||||
// We're assuming that the quantity of information within the product key is at most 114 bits.
|
// We're assuming that the quantity of information within the product key is at most 114 bits.
|
||||||
// log2(24^25) = 114.
|
// log2(24^25) = 114.
|
||||||
@ -27,18 +27,18 @@ void unpackXP(DWORD (&pRaw)[4], DWORD &pSerial, DWORD &pHash, QWORD &pSignature)
|
|||||||
pSerial = FIRSTNBITS(pRaw[0], 31);
|
pSerial = FIRSTNBITS(pRaw[0], 31);
|
||||||
|
|
||||||
// Hash (e) = Bits [31..58] -> 28 bits
|
// Hash (e) = Bits [31..58] -> 28 bits
|
||||||
pHash = FIRSTNBITS(pRaw[1] << 1 | pRaw[0] >> 31, 28);
|
pHash = NEXTNBITS(pRaw[0], 28, 31);
|
||||||
|
|
||||||
// Signature (s) = Bits [59..113] -> 55 bits
|
// Signature (s) = Bits [59..113] -> 55 bits
|
||||||
pSignature = (QWORD)pRaw[3] << (5 + 8 * sizeof(DWORD)) | (QWORD)pRaw[2] << 5 | pRaw[1] >> 27;
|
pSignature = FIRSTNBITS(pRaw[1], 51) << 5 | NEXTNBITS(pRaw[0], 5, 59);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Packs the Windows XP Product Key. */
|
/* Packs the Windows XP Product Key. */
|
||||||
void packXP(DWORD (&pRaw)[4], DWORD pSerial, DWORD pHash, QWORD pSignature) {
|
void packXP(QWORD (&pRaw)[2], DWORD pSerial, DWORD pHash, QWORD pSignature) {
|
||||||
pRaw[0] = pSerial | FIRSTNBITS(pHash, 1) << 31;
|
pRaw[0] = FIRSTNBITS(pSignature, 5) << 59 | FIRSTNBITS(pHash, 28) << 31 | pSerial;
|
||||||
pRaw[1] = FIRSTNBITS(pSignature, 5) << 27 | pHash >> 1;
|
|
||||||
pRaw[2] = (DWORD)(pSignature >> 5);
|
// sig is 56 bits long, 5 of them are used -> 51 bits remaining
|
||||||
pRaw[3] = (DWORD)(pSignature >> (5 + 8 * sizeof(DWORD)));
|
pRaw[1] = NEXTNBITS(pSignature, 51, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Verify Product Key */
|
/* Verify Product Key */
|
||||||
@ -46,7 +46,7 @@ bool verifyXPKey(EC_GROUP *eCurve, EC_POINT *generator, EC_POINT *publicKey, cha
|
|||||||
BN_CTX *context = BN_CTX_new();
|
BN_CTX *context = BN_CTX_new();
|
||||||
|
|
||||||
// Convert Base24 CD-key to bytecode.
|
// Convert Base24 CD-key to bytecode.
|
||||||
DWORD bKey[4]{};
|
QWORD bKey[2]{};
|
||||||
DWORD pID, checkHash;
|
DWORD pID, checkHash;
|
||||||
|
|
||||||
QWORD sig = 0;
|
QWORD sig = 0;
|
||||||
@ -156,13 +156,13 @@ void generateXPKey(EC_GROUP *eCurve, EC_POINT *generator, BIGNUM *order, BIGNUM
|
|||||||
BIGNUM *x = BN_new();
|
BIGNUM *x = BN_new();
|
||||||
BIGNUM *y = BN_new();
|
BIGNUM *y = BN_new();
|
||||||
|
|
||||||
DWORD bKey[4]{};
|
QWORD bKey[2]{};
|
||||||
|
|
||||||
do {
|
do {
|
||||||
DWORD hash = 0;
|
DWORD hash = 0;
|
||||||
QWORD sig = 0;
|
QWORD sig = 0;
|
||||||
|
|
||||||
memset(bKey, 0, 4);
|
memset(bKey, 0, 2 * sizeof(QWORD));
|
||||||
|
|
||||||
// Generate a random number c consisting of 384 bits without any constraints.
|
// Generate a random number c consisting of 384 bits without any constraints.
|
||||||
BN_rand(c, FIELD_BITS, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY);
|
BN_rand(c, FIELD_BITS, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY);
|
||||||
@ -235,9 +235,9 @@ void generateXPKey(EC_GROUP *eCurve, EC_POINT *generator, BIGNUM *order, BIGNUM
|
|||||||
<< " Sig: " << std::hex << std::setw(8) << std::setfill('0') << sig << std::endl
|
<< " Sig: " << std::hex << std::setw(8) << std::setfill('0') << sig << std::endl
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
} while (bKey[3] >= 0x40000);
|
} while (bKey[1] >= (1ULL << 50));
|
||||||
// ↑ ↑ ↑
|
// ↑ ↑ ↑
|
||||||
// bKey[3] can't be longer than 18 bits, else the signature part will make
|
// bKey[1] can't be longer than 50 bits, else the signature part will make
|
||||||
// the CD-key longer than 25 characters.
|
// the CD-key longer than 25 characters.
|
||||||
|
|
||||||
// Convert the key to Base24.
|
// Convert the key to Base24.
|
||||||
|
Loading…
Reference in New Issue
Block a user