mirror of
https://github.com/Neo-Desktop/WindowsXPKg
synced 2026-11-12 03:26:23 +02:00
SSE2/AVX dynamic support + progress (#195)
This commit is contained in:
1 parent
569f4b59f0
commit
769a3dfe23
18 files changed
+855
-122
No files matched your search
@@ -149,6 +149,8 @@ set(UMSKT_SOURCES
|
||||
src/cli.cpp
|
||||
src/windows/json.cpp
|
||||
${UMSKT_KEYS_EMBED}
|
||||
src/crypto/cpu_features.cpp
|
||||
src/crypto/bn_kernels_scalar.cpp
|
||||
src/crypto/mini_bn.cpp
|
||||
src/crypto/mini_ec.cpp
|
||||
src/crypto/mini_rand.cpp
|
||||
@@ -255,6 +257,62 @@ if (UMSKT_FREESTANDING)
|
||||
endif()
|
||||
target_link_libraries(umskt PRIVATE kernel32)
|
||||
|
||||
if (UMSKT_WIN_X86)
|
||||
add_library(umskt_bn_kernels_sse2 OBJECT src/crypto/bn_kernels_sse2.cpp)
|
||||
target_include_directories(umskt_bn_kernels_sse2 PRIVATE "${CMAKE_SOURCE_DIR}/src/crypto")
|
||||
target_compile_definitions(umskt_bn_kernels_sse2 PRIVATE
|
||||
UMSKT_FREESTANDING
|
||||
UMSKT_HAVE_SSE2_KERNELS
|
||||
NDEBUG
|
||||
)
|
||||
target_compile_options(umskt_bn_kernels_sse2 PRIVATE
|
||||
-m32
|
||||
-O2
|
||||
-ffreestanding
|
||||
-fno-exceptions
|
||||
-fno-rtti
|
||||
-fno-threadsafe-statics
|
||||
-fno-use-cxa-atexit
|
||||
-fno-stack-protector
|
||||
-fno-unwind-tables
|
||||
-fno-asynchronous-unwind-tables
|
||||
-msse2
|
||||
-mfpmath=sse
|
||||
)
|
||||
target_compile_definitions(umskt PRIVATE UMSKT_HAVE_SSE2_KERNELS)
|
||||
target_link_libraries(umskt PRIVATE umskt_bn_kernels_sse2)
|
||||
message(STATUS "[UMSKT] SSE2 BN kernels enabled with runtime CPU/OS dispatch")
|
||||
endif()
|
||||
|
||||
add_library(umskt_bn_kernels_avx2 OBJECT src/crypto/bn_kernels_avx2.cpp)
|
||||
target_include_directories(umskt_bn_kernels_avx2 PRIVATE "${CMAKE_SOURCE_DIR}/src/crypto")
|
||||
target_compile_definitions(umskt_bn_kernels_avx2 PRIVATE
|
||||
UMSKT_FREESTANDING
|
||||
UMSKT_HAVE_AVX2_KERNELS
|
||||
NDEBUG
|
||||
)
|
||||
set(UMSKT_AVX2_FLAGS
|
||||
-O2
|
||||
-ffreestanding
|
||||
-fno-exceptions
|
||||
-fno-rtti
|
||||
-fno-threadsafe-statics
|
||||
-fno-use-cxa-atexit
|
||||
-fno-stack-protector
|
||||
-fno-unwind-tables
|
||||
-fno-asynchronous-unwind-tables
|
||||
-mavx2
|
||||
)
|
||||
if (UMSKT_WIN_X86)
|
||||
list(APPEND UMSKT_AVX2_FLAGS -m32)
|
||||
else()
|
||||
list(APPEND UMSKT_AVX2_FLAGS -m64)
|
||||
endif()
|
||||
target_compile_options(umskt_bn_kernels_avx2 PRIVATE ${UMSKT_AVX2_FLAGS})
|
||||
target_compile_definitions(umskt PRIVATE UMSKT_HAVE_AVX2_KERNELS)
|
||||
target_link_libraries(umskt PRIVATE umskt_bn_kernels_avx2)
|
||||
message(STATUS "[UMSKT] AVX2 BN kernels enabled with runtime CPU/OS dispatch")
|
||||
|
||||
get_filename_component(UMSKT_GCC_BIN "${CMAKE_CXX_COMPILER}" DIRECTORY)
|
||||
find_program(UMSKT_OBJDUMP NAMES objdump HINTS "${UMSKT_GCC_BIN}")
|
||||
if (UMSKT_OBJDUMP)
|
||||
|
||||
@@ -55,11 +55,12 @@ In light of the recent exponential interest in this project I've decided to put
|
||||
* Any DOS-based version of Windows
|
||||
* Windows NT 4.0 or later (via NTVDM)
|
||||
#### Windows (x86)
|
||||
* Pentium processor or better
|
||||
* Pentium processor or better (Pentium 4 recommended, Haswell or equivalent best)
|
||||
* Windows 98 First Edition or later
|
||||
* Windows NT 4.0 SP6a or later
|
||||
* Windows NT 4.0 or later
|
||||
#### Windows (x64)
|
||||
* Windows MT 5.2 (Windows XP x64, Windows Server 2003) or later
|
||||
* Windows NT 5.2 (Windows XP x64, Windows Server 2003) or later
|
||||
* Haswell or equivalent recommended
|
||||
#### Windows (ARM64)
|
||||
* Winodws 11 21H2 or later
|
||||
#### macOS
|
||||
|
||||
+202
-1
@@ -57,6 +57,7 @@ struct Options {
|
||||
int nonewlines;
|
||||
int overrideVersion;
|
||||
int nodashes;
|
||||
int progress;
|
||||
int instidFromStdin;
|
||||
MODE applicationMode;
|
||||
ACTIVATION_ALGORITHM activationMode;
|
||||
@@ -88,6 +89,144 @@ static void outf(const char *fmt, ...) {
|
||||
out_text(buffer);
|
||||
}
|
||||
|
||||
static void err_text(const char *text) {
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
#ifdef UMSKT_FREESTANDING
|
||||
uint32_t wrote = 0;
|
||||
void *handle = GetStdHandle(UMSKT_STD_ERROR_HANDLE);
|
||||
if (handle == NULL || handle == UMSKT_INVALID_HANDLE) {
|
||||
return;
|
||||
}
|
||||
WriteFile(handle, text, (uint32_t)strlen(text), &wrote, NULL);
|
||||
#else
|
||||
fputs(text, stderr);
|
||||
fflush(stderr);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct ProgressCtx {
|
||||
unsigned key_index;
|
||||
unsigned key_count;
|
||||
int last_percent;
|
||||
int last_phase;
|
||||
int active;
|
||||
int verbose_layout;
|
||||
int line_open;
|
||||
};
|
||||
|
||||
static ProgressCtx g_progress_ctx;
|
||||
static const unsigned PROGRESS_LINE_WIDTH = 72;
|
||||
|
||||
static void progress_write_padded(const char *body) {
|
||||
char line[80];
|
||||
unsigned i;
|
||||
unsigned len = 0;
|
||||
line[0] = '\r';
|
||||
while (body[len] && len < PROGRESS_LINE_WIDTH) {
|
||||
line[1 + len] = body[len];
|
||||
len++;
|
||||
}
|
||||
for (i = len; i < PROGRESS_LINE_WIDTH; i++) {
|
||||
line[1 + i] = ' ';
|
||||
}
|
||||
line[1 + PROGRESS_LINE_WIDTH] = 0;
|
||||
err_text(line);
|
||||
g_progress_ctx.line_open = 1;
|
||||
}
|
||||
|
||||
static void progress_clear_line(void) {
|
||||
if (g_progress_ctx.line_open) {
|
||||
progress_write_padded("");
|
||||
err_text("\r");
|
||||
g_progress_ctx.line_open = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void progress_break_line(void) {
|
||||
if (g_progress_ctx.line_open) {
|
||||
progress_write_padded("");
|
||||
err_text("\n");
|
||||
g_progress_ctx.line_open = 0;
|
||||
}
|
||||
g_progress_ctx.last_phase = -1;
|
||||
g_progress_ctx.last_percent = -1;
|
||||
}
|
||||
|
||||
static const char *progress_phase_label(int phase) {
|
||||
const char *op = UMSKT::getProgressLabel();
|
||||
if (g_progress_ctx.verbose_layout && op && op[0]) {
|
||||
return op;
|
||||
}
|
||||
if (phase == UMSKT_PROGRESS_GEN) {
|
||||
return "Generating key";
|
||||
}
|
||||
if (phase == UMSKT_PROGRESS_VERIFY) {
|
||||
return "Validating key";
|
||||
}
|
||||
return "Multiplying elliptic curve";
|
||||
}
|
||||
|
||||
static void progress_draw_bar(int phase, unsigned current, unsigned total) {
|
||||
char body[80];
|
||||
unsigned percent;
|
||||
unsigned filled;
|
||||
unsigned i;
|
||||
const unsigned width = 24;
|
||||
const char *label;
|
||||
if (total == 0) {
|
||||
return;
|
||||
}
|
||||
if (current > total) {
|
||||
current = total;
|
||||
}
|
||||
percent = (current * 100u) / total;
|
||||
if (g_progress_ctx.last_phase == phase &&
|
||||
(int)percent == g_progress_ctx.last_percent &&
|
||||
current != total &&
|
||||
current != 0 &&
|
||||
current != 1) {
|
||||
return;
|
||||
}
|
||||
g_progress_ctx.last_phase = phase;
|
||||
g_progress_ctx.last_percent = (int)percent;
|
||||
filled = (current * width) / total;
|
||||
body[0] = '[';
|
||||
for (i = 0; i < width; i++) {
|
||||
body[1 + i] = (i < filled) ? '#' : '-';
|
||||
}
|
||||
label = progress_phase_label(phase);
|
||||
if (g_progress_ctx.key_count > 1) {
|
||||
snprintf(body + 1 + width, sizeof(body) - (1 + width),
|
||||
"] %3u%% %s (%u/%u)",
|
||||
percent, label, g_progress_ctx.key_index + 1, g_progress_ctx.key_count);
|
||||
} else {
|
||||
snprintf(body + 1 + width, sizeof(body) - (1 + width),
|
||||
"] %3u%% %s", percent, label);
|
||||
}
|
||||
progress_write_padded(body);
|
||||
}
|
||||
|
||||
static void progress_callback(int phase, unsigned current, unsigned total, void *user) {
|
||||
ProgressCtx *ctx = (ProgressCtx *)user;
|
||||
if (!ctx || !ctx->active) {
|
||||
return;
|
||||
}
|
||||
if (phase == UMSKT_PROGRESS_BREAK) {
|
||||
progress_break_line();
|
||||
return;
|
||||
}
|
||||
if (ctx->verbose_layout && ctx->last_phase != -1 && ctx->last_phase != phase) {
|
||||
progress_break_line();
|
||||
}
|
||||
if (phase == UMSKT_PROGRESS_MUL ||
|
||||
phase == UMSKT_PROGRESS_GEN ||
|
||||
phase == UMSKT_PROGRESS_VERIFY) {
|
||||
progress_draw_bar(phase, current, total);
|
||||
}
|
||||
}
|
||||
|
||||
static int streq(const char *a, const char *b) {
|
||||
return strcmp(a, b) == 0;
|
||||
}
|
||||
@@ -315,7 +454,8 @@ static void show_help(char *argv[]) {
|
||||
out_text("\t-V --validate\tproduct key to validate signature\n");
|
||||
out_text("\t-N --nonewlines\tdisables newlines (for easier embedding in other apps)\n");
|
||||
out_text("\t-o --override\tDisables version check for confirmation IDs, if you need this send an issue on GitHub\n");
|
||||
out_text("\t-D --nodashes\tDisables dashes in product keys and confirmation IDs (for easier copy-pasting)");
|
||||
out_text("\t-D --nodashes\tDisables dashes in product keys and confirmation IDs (for easier copy-pasting)\n");
|
||||
out_text("\t-P --progress\tDisplays progress bar (for long-running operations)\n");
|
||||
out_text("\n");
|
||||
}
|
||||
|
||||
@@ -445,6 +585,8 @@ static int parse_command_line(int argc, char *argv[], Options *options) {
|
||||
options->overrideVersion = 1;
|
||||
} else if (streq(arg, "-D") || streq(arg, "--nodashes")) {
|
||||
options->nodashes = 1;
|
||||
} else if (streq(arg, "-P") || streq(arg, "--progress")) {
|
||||
options->progress = 1;
|
||||
} else {
|
||||
options->error = 1;
|
||||
}
|
||||
@@ -691,10 +833,34 @@ static int run_keys(Options *options, const char *json, int length) {
|
||||
print_id(&nRaw);
|
||||
}
|
||||
BN_sub(privateKey, genOrder, privateKey);
|
||||
if (options->progress) {
|
||||
g_progress_ctx.key_index = 0;
|
||||
g_progress_ctx.key_count = (unsigned)options->numKeys;
|
||||
g_progress_ctx.last_percent = -1;
|
||||
g_progress_ctx.last_phase = -1;
|
||||
g_progress_ctx.active = 1;
|
||||
g_progress_ctx.verbose_layout = options->verbose;
|
||||
g_progress_ctx.line_open = 0;
|
||||
UMSKT::setProgress(progress_callback, &g_progress_ctx);
|
||||
}
|
||||
for (i = 0; i < total; i++) {
|
||||
int valid;
|
||||
if (options->progress) {
|
||||
g_progress_ctx.key_index = (unsigned)count;
|
||||
g_progress_ctx.last_percent = -1;
|
||||
g_progress_ctx.last_phase = -1;
|
||||
}
|
||||
PIDGEN3::BINK1998::Generate(eCurve, genPoint, genOrder, privateKey, nRaw, options->upgrade, pKey);
|
||||
if (options->progress) {
|
||||
UMSKT::setEcProgressPhase(UMSKT_PROGRESS_VERIFY);
|
||||
UMSKT::setMulProgress(1);
|
||||
}
|
||||
valid = PIDGEN3::BINK1998::Verify(eCurve, genPoint, pubPoint, pKey);
|
||||
if (options->progress) {
|
||||
UMSKT::setMulProgress(0);
|
||||
UMSKT::setProgressLabel(NULL);
|
||||
progress_clear_line();
|
||||
}
|
||||
if (valid) {
|
||||
print_key(pKey, options->nodashes);
|
||||
if (i < total - 1 || options->verbose) {
|
||||
@@ -716,10 +882,24 @@ static int run_keys(Options *options, const char *json, int length) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options->progress) {
|
||||
UMSKT::setProgress(NULL, NULL);
|
||||
g_progress_ctx.active = 0;
|
||||
}
|
||||
} else if (options->applicationMode == MODE_BINK2002_GENERATE) {
|
||||
if (options->verbose) {
|
||||
outf("> Channel ID: %03d\n", options->channelID);
|
||||
}
|
||||
if (options->progress) {
|
||||
g_progress_ctx.key_index = 0;
|
||||
g_progress_ctx.key_count = (unsigned)options->numKeys;
|
||||
g_progress_ctx.last_percent = -1;
|
||||
g_progress_ctx.last_phase = -1;
|
||||
g_progress_ctx.active = 1;
|
||||
g_progress_ctx.verbose_layout = options->verbose;
|
||||
g_progress_ctx.line_open = 0;
|
||||
UMSKT::setProgress(progress_callback, &g_progress_ctx);
|
||||
}
|
||||
for (i = 0; i < total; i++) {
|
||||
DWORD pAuthInfo = 0;
|
||||
int valid;
|
||||
@@ -728,8 +908,22 @@ static int run_keys(Options *options, const char *json, int length) {
|
||||
if (options->verbose) {
|
||||
outf("> AuthInfo: %u\n", pAuthInfo);
|
||||
}
|
||||
if (options->progress) {
|
||||
g_progress_ctx.key_index = (unsigned)count;
|
||||
g_progress_ctx.last_percent = -1;
|
||||
g_progress_ctx.last_phase = -1;
|
||||
}
|
||||
PIDGEN3::BINK2002::Generate(eCurve, genPoint, genOrder, privateKey, (DWORD)options->channelID, pAuthInfo, options->upgrade, (DWORD)options->serialMin, (DWORD)options->serialMax, pKey);
|
||||
if (options->progress) {
|
||||
UMSKT::setEcProgressPhase(UMSKT_PROGRESS_VERIFY);
|
||||
UMSKT::setMulProgress(1);
|
||||
}
|
||||
valid = PIDGEN3::BINK2002::Verify(eCurve, genPoint, pubPoint, NULL, pKey);
|
||||
if (options->progress) {
|
||||
UMSKT::setMulProgress(0);
|
||||
UMSKT::setProgressLabel(NULL);
|
||||
progress_clear_line();
|
||||
}
|
||||
if (valid) {
|
||||
print_key(pKey, options->nodashes);
|
||||
if (i < total - 1 || options->verbose) {
|
||||
@@ -751,6 +945,10 @@ static int run_keys(Options *options, const char *json, int length) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options->progress) {
|
||||
UMSKT::setProgress(NULL, NULL);
|
||||
g_progress_ctx.active = 0;
|
||||
}
|
||||
} else if (options->applicationMode == MODE_BINK1998_VALIDATE || options->applicationMode == MODE_BINK2002_VALIDATE) {
|
||||
char product_key[PK_LENGTH + NULL_TERMINATOR];
|
||||
memset(product_key, 0, sizeof(product_key));
|
||||
@@ -798,6 +996,9 @@ static int run_keys(Options *options, const char *json, int length) {
|
||||
}
|
||||
|
||||
if (gaveUp || count < options->numKeys) {
|
||||
if (options->progress) {
|
||||
progress_clear_line();
|
||||
}
|
||||
out_text("ERROR: failed to generate a valid product key\n");
|
||||
curve_free(&curve);
|
||||
BN_free(privateKey);
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/* This file is a part of the UMSKT Project.
|
||||
*
|
||||
* Copyleft (C) 2019-2026 UMSKT Contributors (et.al.)
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef UMSKT_BN_KERNELS_H
|
||||
#define UMSKT_BN_KERNELS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void umskt_mont_mul_scalar(uint32_t *r, const uint32_t *a, const uint32_t *b, const uint32_t *n, uint32_t n0, int nw);
|
||||
void umskt_bn_mul_limbs_scalar(uint32_t *r, const uint32_t *a, int an, const uint32_t *b, int bn);
|
||||
|
||||
#if defined(UMSKT_HAVE_SSE2_KERNELS)
|
||||
void umskt_mont_mul_sse2(uint32_t *r, const uint32_t *a, const uint32_t *b, const uint32_t *n, uint32_t n0, int nw);
|
||||
void umskt_bn_mul_limbs_sse2(uint32_t *r, const uint32_t *a, int an, const uint32_t *b, int bn);
|
||||
#endif
|
||||
|
||||
#if defined(UMSKT_HAVE_AVX2_KERNELS)
|
||||
void umskt_mont_mul_avx2(uint32_t *r, const uint32_t *a, const uint32_t *b, const uint32_t *n, uint32_t n0, int nw);
|
||||
void umskt_bn_mul_limbs_avx2(uint32_t *r, const uint32_t *a, int an, const uint32_t *b, int bn);
|
||||
#endif
|
||||
|
||||
void umskt_bn_dispatch_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,100 @@
|
||||
/* This file is a part of the UMSKT Project.
|
||||
*
|
||||
* Copyleft (C) 2019-2026 UMSKT Contributors (et.al.)
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BN_KERNEL_SUFFIX
|
||||
#error "BN_KERNEL_SUFFIX must be defined before including bn_kernels.inc.cpp"
|
||||
#endif
|
||||
|
||||
#define BN_KERNEL_PASTE2(a, b) a##_##b
|
||||
#define BN_KERNEL_PASTE(a, b) BN_KERNEL_PASTE2(a, b)
|
||||
#define BN_KERNEL_FN(name) BN_KERNEL_PASTE(name, BN_KERNEL_SUFFIX)
|
||||
|
||||
void BN_KERNEL_FN(umskt_mont_mul)(uint32_t *r, const uint32_t *a, const uint32_t *b, const uint32_t *n, uint32_t n0, int nw) {
|
||||
uint32_t tmp[34];
|
||||
int i;
|
||||
int j;
|
||||
int ge;
|
||||
for (i = 0; i < nw + 2; i++) {
|
||||
tmp[i] = 0;
|
||||
}
|
||||
for (i = 0; i < nw; i++) {
|
||||
uint64_t carry = 0;
|
||||
uint32_t m;
|
||||
for (j = 0; j < nw; j++) {
|
||||
carry += (uint64_t)tmp[j] + (uint64_t)a[j] * b[i];
|
||||
tmp[j] = (uint32_t)carry;
|
||||
carry >>= 32;
|
||||
}
|
||||
carry += tmp[nw];
|
||||
tmp[nw] = (uint32_t)carry;
|
||||
tmp[nw + 1] = (uint32_t)(carry >> 32);
|
||||
m = tmp[0] * n0;
|
||||
carry = 0;
|
||||
for (j = 0; j < nw; j++) {
|
||||
carry += (uint64_t)tmp[j] + (uint64_t)m * n[j];
|
||||
tmp[j] = (uint32_t)carry;
|
||||
carry >>= 32;
|
||||
}
|
||||
carry += tmp[nw];
|
||||
tmp[nw] = (uint32_t)carry;
|
||||
tmp[nw + 1] += (uint32_t)(carry >> 32);
|
||||
for (j = 0; j <= nw; j++) {
|
||||
tmp[j] = tmp[j + 1];
|
||||
}
|
||||
tmp[nw + 1] = 0;
|
||||
}
|
||||
ge = tmp[nw] != 0;
|
||||
if (!ge) {
|
||||
for (i = nw - 1; i >= 0; i--) {
|
||||
if (tmp[i] != n[i]) {
|
||||
ge = tmp[i] > n[i];
|
||||
break;
|
||||
}
|
||||
if (i == 0) {
|
||||
ge = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ge) {
|
||||
uint32_t borrow = 0;
|
||||
for (i = 0; i < nw; i++) {
|
||||
uint64_t sub = (uint64_t)n[i] + borrow;
|
||||
r[i] = (uint32_t)((uint64_t)tmp[i] - sub);
|
||||
borrow = (uint64_t)tmp[i] < sub;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < nw; i++) {
|
||||
r[i] = tmp[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BN_KERNEL_FN(umskt_bn_mul_limbs)(uint32_t *r, const uint32_t *a, int an, const uint32_t *b, int bn) {
|
||||
int i;
|
||||
int j;
|
||||
int top = an + bn;
|
||||
for (i = 0; i < top + 1; i++) {
|
||||
r[i] = 0;
|
||||
}
|
||||
for (i = 0; i < an; i++) {
|
||||
uint32_t carry = 0;
|
||||
for (j = 0; j < bn; j++) {
|
||||
union {
|
||||
uint64_t v;
|
||||
uint32_t p[2];
|
||||
} acc;
|
||||
acc.v = (uint64_t)a[i] * b[j] + r[i + j] + carry;
|
||||
r[i + j] = acc.p[0];
|
||||
carry = acc.p[1];
|
||||
}
|
||||
r[i + bn] = carry;
|
||||
}
|
||||
}
|
||||
|
||||
#undef BN_KERNEL_FN
|
||||
#undef BN_KERNEL_PASTE
|
||||
#undef BN_KERNEL_PASTE2
|
||||
@@ -0,0 +1,11 @@
|
||||
/* This file is a part of the UMSKT Project.
|
||||
*
|
||||
* Copyleft (C) 2019-2026 UMSKT Contributors (et.al.)
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "bn_kernels.h"
|
||||
|
||||
#define BN_KERNEL_SUFFIX avx2
|
||||
#include "bn_kernels.inc.cpp"
|
||||
#undef BN_KERNEL_SUFFIX
|
||||
@@ -0,0 +1,11 @@
|
||||
/* This file is a part of the UMSKT Project.
|
||||
*
|
||||
* Copyleft (C) 2019-2026 UMSKT Contributors (et.al.)
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "bn_kernels.h"
|
||||
|
||||
#define BN_KERNEL_SUFFIX scalar
|
||||
#include "bn_kernels.inc.cpp"
|
||||
#undef BN_KERNEL_SUFFIX
|
||||
@@ -0,0 +1,11 @@
|
||||
/* This file is a part of the UMSKT Project.
|
||||
*
|
||||
* Copyleft (C) 2019-2026 UMSKT Contributors (et.al.)
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "bn_kernels.h"
|
||||
|
||||
#define BN_KERNEL_SUFFIX sse2
|
||||
#include "bn_kernels.inc.cpp"
|
||||
#undef BN_KERNEL_SUFFIX
|
||||
@@ -0,0 +1,189 @@
|
||||
/* This file is a part of the UMSKT Project.
|
||||
*
|
||||
* Copyleft (C) 2019-2026 UMSKT Contributors (et.al.)
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "cpu_features.h"
|
||||
|
||||
#if defined(UMSKT_FREESTANDING) || defined(_WIN32)
|
||||
#ifndef WINVER
|
||||
#define WINVER 0x0400
|
||||
#endif
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#ifndef PF_XMMI64_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10
|
||||
#endif
|
||||
#ifndef PF_AVX2_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_AVX2_INSTRUCTIONS_AVAILABLE 40
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int g_cpu_ready = 0;
|
||||
static int g_has_sse2 = 0;
|
||||
static int g_has_avx2 = 0;
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
static int cpuid_supported(void) {
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
return 1;
|
||||
#else
|
||||
unsigned int original;
|
||||
unsigned int modified;
|
||||
__asm__ __volatile__(
|
||||
"pushfl\n\t"
|
||||
"popl %0\n\t"
|
||||
"movl %0, %1\n\t"
|
||||
"xorl $0x200000, %0\n\t"
|
||||
"pushl %0\n\t"
|
||||
"popfl\n\t"
|
||||
"pushfl\n\t"
|
||||
"popl %0\n\t"
|
||||
"pushl %1\n\t"
|
||||
"popfl\n\t"
|
||||
: "=&r"(modified), "=&r"(original)
|
||||
:
|
||||
: "cc");
|
||||
return ((original ^ modified) & 0x200000u) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void do_cpuid(unsigned int leaf, unsigned int subleaf, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) {
|
||||
__asm__ __volatile__(
|
||||
"cpuid"
|
||||
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
|
||||
: "a"(leaf), "c"(subleaf));
|
||||
}
|
||||
|
||||
static unsigned long long do_xgetbv(unsigned int index) {
|
||||
unsigned int eax;
|
||||
unsigned int edx;
|
||||
__asm__ __volatile__(
|
||||
".byte 0x0f, 0x01, 0xd0"
|
||||
: "=a"(eax), "=d"(edx)
|
||||
: "c"(index));
|
||||
return ((unsigned long long)edx << 32) | eax;
|
||||
}
|
||||
#else
|
||||
static int cpuid_supported(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void do_cpuid(unsigned int leaf, unsigned int subleaf, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) {
|
||||
(void)leaf;
|
||||
(void)subleaf;
|
||||
*eax = *ebx = *ecx = *edx = 0;
|
||||
}
|
||||
|
||||
static unsigned long long do_xgetbv(unsigned int index) {
|
||||
(void)index;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cpu_has_sse2_bit(void) {
|
||||
unsigned int eax = 0;
|
||||
unsigned int ebx = 0;
|
||||
unsigned int ecx = 0;
|
||||
unsigned int edx = 0;
|
||||
if (!cpuid_supported()) {
|
||||
return 0;
|
||||
}
|
||||
do_cpuid(0, 0, &eax, &ebx, &ecx, &edx);
|
||||
if (eax < 1) {
|
||||
return 0;
|
||||
}
|
||||
do_cpuid(1, 0, &eax, &ebx, &ecx, &edx);
|
||||
return (edx & (1u << 26)) != 0;
|
||||
}
|
||||
|
||||
static int cpu_has_avx2_bits(void) {
|
||||
unsigned int eax = 0;
|
||||
unsigned int ebx = 0;
|
||||
unsigned int ecx = 0;
|
||||
unsigned int edx = 0;
|
||||
unsigned long long xcr0;
|
||||
if (!cpuid_supported()) {
|
||||
return 0;
|
||||
}
|
||||
do_cpuid(0, 0, &eax, &ebx, &ecx, &edx);
|
||||
if (eax < 1) {
|
||||
return 0;
|
||||
}
|
||||
do_cpuid(1, 0, &eax, &ebx, &ecx, &edx);
|
||||
/* OSXSAVE (27) and AVX (28) */
|
||||
if ((ecx & ((1u << 27) | (1u << 28))) != ((1u << 27) | (1u << 28))) {
|
||||
return 0;
|
||||
}
|
||||
xcr0 = do_xgetbv(0);
|
||||
/* XMM (bit 1) and YMM (bit 2) state must be enabled by the OS. */
|
||||
if ((xcr0 & 0x6ull) != 0x6ull) {
|
||||
return 0;
|
||||
}
|
||||
do_cpuid(0, 0, &eax, &ebx, &ecx, &edx);
|
||||
if (eax < 7) {
|
||||
return 0;
|
||||
}
|
||||
do_cpuid(7, 0, &eax, &ebx, &ecx, &edx);
|
||||
return (ebx & (1u << 5)) != 0;
|
||||
}
|
||||
|
||||
static int os_supports_sse2(void) {
|
||||
#if defined(UMSKT_FREESTANDING) || defined(_WIN32)
|
||||
return IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE) ? 1 : 0;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int os_supports_avx2(void) {
|
||||
#if defined(UMSKT_FREESTANDING) || defined(_WIN32)
|
||||
return IsProcessorFeaturePresent(PF_AVX2_INSTRUCTIONS_AVAILABLE) ? 1 : 0;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int cpu_has_sse2_bit(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpu_has_avx2_bits(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int os_supports_sse2(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int os_supports_avx2(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void umskt_cpu_init(void) {
|
||||
if (g_cpu_ready) {
|
||||
return;
|
||||
}
|
||||
g_has_sse2 = cpu_has_sse2_bit() && os_supports_sse2();
|
||||
g_has_avx2 = cpu_has_avx2_bits() && os_supports_avx2();
|
||||
g_cpu_ready = 1;
|
||||
}
|
||||
|
||||
int umskt_cpu_has_sse2(void) {
|
||||
umskt_cpu_init();
|
||||
return g_has_sse2;
|
||||
}
|
||||
|
||||
int umskt_cpu_has_avx2(void) {
|
||||
umskt_cpu_init();
|
||||
return g_has_avx2;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/* This file is a part of the UMSKT Project.
|
||||
*
|
||||
* Copyleft (C) 2019-2026 UMSKT Contributors (et.al.)
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef UMSKT_CPU_FEATURES_H
|
||||
#define UMSKT_CPU_FEATURES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void umskt_cpu_init(void);
|
||||
int umskt_cpu_has_sse2(void);
|
||||
int umskt_cpu_has_avx2(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+42
-75
@@ -9,10 +9,48 @@
|
||||
*/
|
||||
|
||||
#include "mini_openssl.h"
|
||||
#include "bn_kernels.h"
|
||||
#include "cpu_features.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef void (*umskt_mont_mul_fn)(uint32_t *r, const uint32_t *a, const uint32_t *b, const uint32_t *n, uint32_t n0, int nw);
|
||||
typedef void (*umskt_bn_mul_limbs_fn)(uint32_t *r, const uint32_t *a, int an, const uint32_t *b, int bn);
|
||||
|
||||
static umskt_mont_mul_fn g_mont_mul = umskt_mont_mul_scalar;
|
||||
static umskt_bn_mul_limbs_fn g_bn_mul_limbs = umskt_bn_mul_limbs_scalar;
|
||||
static int g_bn_dispatch_ready = 0;
|
||||
|
||||
void umskt_bn_dispatch_init(void) {
|
||||
if (g_bn_dispatch_ready) {
|
||||
return;
|
||||
}
|
||||
umskt_cpu_init();
|
||||
#if defined(UMSKT_HAVE_AVX2_KERNELS)
|
||||
if (umskt_cpu_has_avx2()) {
|
||||
g_mont_mul = umskt_mont_mul_avx2;
|
||||
g_bn_mul_limbs = umskt_bn_mul_limbs_avx2;
|
||||
} else
|
||||
#endif
|
||||
#if defined(UMSKT_HAVE_SSE2_KERNELS)
|
||||
if (umskt_cpu_has_sse2()) {
|
||||
g_mont_mul = umskt_mont_mul_sse2;
|
||||
g_bn_mul_limbs = umskt_bn_mul_limbs_sse2;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
(void)0;
|
||||
}
|
||||
g_bn_dispatch_ready = 1;
|
||||
}
|
||||
|
||||
static void bn_dispatch_ensure(void) {
|
||||
if (!g_bn_dispatch_ready) {
|
||||
umskt_bn_dispatch_init();
|
||||
}
|
||||
}
|
||||
|
||||
struct bignum_st {
|
||||
uint32_t *d;
|
||||
int top;
|
||||
@@ -505,8 +543,6 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) {
|
||||
}
|
||||
|
||||
static int bn_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
int i;
|
||||
int j;
|
||||
int top = a->top + b->top;
|
||||
if (a->top == 0 || b->top == 0) {
|
||||
return BN_zero(r);
|
||||
@@ -514,22 +550,8 @@ static int bn_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
if (!bn_wexpand(r, top + 1)) {
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < top + 1; i++) {
|
||||
r->d[i] = 0;
|
||||
}
|
||||
for (i = 0; i < a->top; i++) {
|
||||
uint32_t carry = 0;
|
||||
for (j = 0; j < b->top; j++) {
|
||||
union {
|
||||
uint64_t v;
|
||||
uint32_t p[2];
|
||||
} acc;
|
||||
acc.v = (uint64_t)a->d[i] * b->d[j] + r->d[i + j] + carry;
|
||||
r->d[i + j] = acc.p[0];
|
||||
carry = acc.p[1];
|
||||
}
|
||||
r->d[i + b->top] = carry;
|
||||
}
|
||||
bn_dispatch_ensure();
|
||||
g_bn_mul_limbs(r->d, a->d, a->top, b->d, b->top);
|
||||
r->top = top;
|
||||
r->neg = (a->neg ^ b->neg) && 1;
|
||||
bn_fix_top(r);
|
||||
@@ -728,63 +750,8 @@ static void mont_load(uint32_t *dst, const BIGNUM *src, int nw) {
|
||||
}
|
||||
|
||||
static void mont_mul(uint32_t *r, const uint32_t *a, const uint32_t *b, const uint32_t *n, uint32_t n0, int nw) {
|
||||
uint32_t tmp[34];
|
||||
int i;
|
||||
int j;
|
||||
int ge;
|
||||
for (i = 0; i < nw + 2; i++) {
|
||||
tmp[i] = 0;
|
||||
}
|
||||
for (i = 0; i < nw; i++) {
|
||||
uint64_t carry = 0;
|
||||
uint32_t m;
|
||||
for (j = 0; j < nw; j++) {
|
||||
carry += (uint64_t)tmp[j] + (uint64_t)a[j] * b[i];
|
||||
tmp[j] = (uint32_t)carry;
|
||||
carry >>= 32;
|
||||
}
|
||||
carry += tmp[nw];
|
||||
tmp[nw] = (uint32_t)carry;
|
||||
tmp[nw + 1] = (uint32_t)(carry >> 32);
|
||||
m = tmp[0] * n0;
|
||||
carry = 0;
|
||||
for (j = 0; j < nw; j++) {
|
||||
carry += (uint64_t)tmp[j] + (uint64_t)m * n[j];
|
||||
tmp[j] = (uint32_t)carry;
|
||||
carry >>= 32;
|
||||
}
|
||||
carry += tmp[nw];
|
||||
tmp[nw] = (uint32_t)carry;
|
||||
tmp[nw + 1] += (uint32_t)(carry >> 32);
|
||||
for (j = 0; j <= nw; j++) {
|
||||
tmp[j] = tmp[j + 1];
|
||||
}
|
||||
tmp[nw + 1] = 0;
|
||||
}
|
||||
ge = tmp[nw] != 0;
|
||||
if (!ge) {
|
||||
for (i = nw - 1; i >= 0; i--) {
|
||||
if (tmp[i] != n[i]) {
|
||||
ge = tmp[i] > n[i];
|
||||
break;
|
||||
}
|
||||
if (i == 0) {
|
||||
ge = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ge) {
|
||||
uint32_t borrow = 0;
|
||||
for (i = 0; i < nw; i++) {
|
||||
uint64_t sub = (uint64_t)n[i] + borrow;
|
||||
r[i] = (uint32_t)((uint64_t)tmp[i] - sub);
|
||||
borrow = (uint64_t)tmp[i] < sub;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < nw; i++) {
|
||||
r[i] = tmp[i];
|
||||
}
|
||||
}
|
||||
bn_dispatch_ensure();
|
||||
g_mont_mul(r, a, b, n, n0, nw);
|
||||
}
|
||||
|
||||
static int bn_to_mont_rr(BIGNUM *rr, const BIGNUM *m, int nw) {
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
extern "C" int umskt_mul_progress_enabled(void);
|
||||
extern "C" int umskt_ec_progress_phase(void);
|
||||
extern "C" void umskt_report_progress(int phase, unsigned current, unsigned total);
|
||||
|
||||
struct ec_group_st {
|
||||
BIGNUM *p;
|
||||
BIGNUM *a;
|
||||
@@ -421,6 +425,9 @@ int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_P
|
||||
if (ok && BN_is_bit_set(m, i)) {
|
||||
ok = jadd_mixed(group, &acc, q);
|
||||
}
|
||||
if (ok && umskt_mul_progress_enabled() && bits > 0) {
|
||||
umskt_report_progress(umskt_ec_progress_phase(), (unsigned)(bits - i), (unsigned)bits);
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
ok = jto_affine(group, r, &acc);
|
||||
|
||||
@@ -22,6 +22,69 @@
|
||||
|
||||
#include "libumskt.h"
|
||||
|
||||
static UMSKT::ProgressFn g_progress_fn = NULL;
|
||||
static void *g_progress_user = NULL;
|
||||
static int g_mul_progress = 0;
|
||||
static int g_ec_progress_phase = UMSKT_PROGRESS_MUL;
|
||||
static int g_progress_suspended = 0;
|
||||
static char g_progress_label[24];
|
||||
|
||||
void UMSKT::setProgress(ProgressFn fn, void *user) {
|
||||
g_progress_fn = fn;
|
||||
g_progress_user = user;
|
||||
}
|
||||
|
||||
void UMSKT::setMulProgress(int on) {
|
||||
g_mul_progress = on ? 1 : 0;
|
||||
}
|
||||
|
||||
void UMSKT::setEcProgressPhase(int phase) {
|
||||
g_ec_progress_phase = phase;
|
||||
}
|
||||
|
||||
void UMSKT::setProgressLabel(const char *label) {
|
||||
size_t i = 0;
|
||||
if (!label) {
|
||||
g_progress_label[0] = 0;
|
||||
return;
|
||||
}
|
||||
while (label[i] && i + 1 < sizeof(g_progress_label)) {
|
||||
g_progress_label[i] = label[i];
|
||||
i++;
|
||||
}
|
||||
g_progress_label[i] = 0;
|
||||
}
|
||||
|
||||
const char *UMSKT::getProgressLabel(void) {
|
||||
return g_progress_label;
|
||||
}
|
||||
|
||||
extern "C" int umskt_mul_progress_enabled(void) {
|
||||
return g_mul_progress && g_progress_fn != NULL;
|
||||
}
|
||||
|
||||
extern "C" int umskt_ec_progress_phase(void) {
|
||||
return g_ec_progress_phase;
|
||||
}
|
||||
|
||||
extern "C" void umskt_report_progress(int phase, unsigned current, unsigned total) {
|
||||
UMSKT::reportProgress(phase, current, total);
|
||||
}
|
||||
|
||||
void UMSKT::suspendProgressLine(void) {
|
||||
if (g_progress_fn && !g_progress_suspended) {
|
||||
g_progress_fn(UMSKT_PROGRESS_BREAK, 0, 0, g_progress_user);
|
||||
g_progress_suspended = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void UMSKT::reportProgress(int phase, unsigned current, unsigned total) {
|
||||
if (g_progress_fn) {
|
||||
g_progress_suspended = 0;
|
||||
g_progress_fn(phase, current, total, g_progress_user);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UMSKT_FREESTANDING
|
||||
#include "../windows/win32_min.h"
|
||||
|
||||
@@ -38,6 +101,7 @@ void UMSKT::debugf(const char *fmt, ...) {
|
||||
if (!debug_on || !fmt) {
|
||||
return;
|
||||
}
|
||||
suspendProgressLine();
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buffer, sizeof(buffer), fmt, ap);
|
||||
va_end(ap);
|
||||
@@ -61,6 +125,7 @@ void UMSKT::debugf(const char *fmt, ...) {
|
||||
if (!debug || !fmt) {
|
||||
return;
|
||||
}
|
||||
suspendProgressLine();
|
||||
va_start(ap, fmt);
|
||||
vfprintf(debug, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
@@ -52,12 +52,21 @@
|
||||
#define BYDWORD(n) (DWORD)(*((n) + 0) | *((n) + 1) << 8 | *((n) + 2) << 16 | *((n) + 3) << 24)
|
||||
#define BITMASK(n) ((1ULL << (n)) - 1)
|
||||
|
||||
enum {
|
||||
UMSKT_PROGRESS_BREAK = 0,
|
||||
UMSKT_PROGRESS_MUL = 1,
|
||||
UMSKT_PROGRESS_GEN = 2,
|
||||
UMSKT_PROGRESS_VERIFY = 3
|
||||
};
|
||||
|
||||
class UMSKT {
|
||||
public:
|
||||
class PIDGEN2;
|
||||
class PIDGEN3;
|
||||
class ConfigurationID;
|
||||
|
||||
typedef void (*ProgressFn)(int phase, unsigned current, unsigned total, void *user);
|
||||
|
||||
#ifdef UMSKT_FREESTANDING
|
||||
static int debug_on;
|
||||
#else
|
||||
@@ -65,6 +74,13 @@ public:
|
||||
#endif
|
||||
static void setDebug(int on);
|
||||
static void debugf(const char *fmt, ...);
|
||||
static void setProgress(ProgressFn fn, void *user);
|
||||
static void setMulProgress(int on);
|
||||
static void setEcProgressPhase(int phase);
|
||||
static void setProgressLabel(const char *label);
|
||||
static const char *getProgressLabel(void);
|
||||
static void suspendProgressLine(void);
|
||||
static void reportProgress(int phase, unsigned current, unsigned total);
|
||||
|
||||
// RNG utility functions
|
||||
static int umskt_rand_bytes(unsigned char *buf, int num);
|
||||
|
||||
@@ -128,10 +128,14 @@ bool PIDGEN3::BINK1998::Verify(
|
||||
EC_POINT *p = EC_POINT_new(eCurve);
|
||||
|
||||
// t = sG
|
||||
UMSKT::setProgressLabel("s*G");
|
||||
UMSKT::setEcProgressPhase(UMSKT_PROGRESS_VERIFY);
|
||||
EC_POINT_mul(eCurve, t, nullptr, basePoint, s, numContext);
|
||||
|
||||
// P = eK
|
||||
UMSKT::setProgressLabel("e*K");
|
||||
EC_POINT_mul(eCurve, p, nullptr, publicKey, e, numContext);
|
||||
UMSKT::setProgressLabel(NULL);
|
||||
|
||||
// P += t
|
||||
EC_POINT_add(eCurve, p, t, p, numContext);
|
||||
@@ -202,10 +206,23 @@ void PIDGEN3::BINK1998::Generate(
|
||||
// attempt adds G instead of multiplying the curve again. About 1 in 512
|
||||
// signatures fit in 55 bits, and a 386 cannot afford hundreds of multiplications.
|
||||
EC_POINT *r = EC_POINT_new(eCurve);
|
||||
unsigned mul_bits;
|
||||
UMSKT::umskt_bn_rand(c, FIELD_BITS, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY);
|
||||
mul_bits = (unsigned)BN_num_bits(c);
|
||||
if (mul_bits == 0) {
|
||||
mul_bits = 1;
|
||||
}
|
||||
UMSKT::setProgressLabel("R=c*G");
|
||||
UMSKT::setEcProgressPhase(UMSKT_PROGRESS_MUL);
|
||||
UMSKT::reportProgress(UMSKT_PROGRESS_MUL, 0, mul_bits);
|
||||
UMSKT::setMulProgress(1);
|
||||
EC_POINT_mul(eCurve, r, nullptr, basePoint, c, numContext);
|
||||
UMSKT::setMulProgress(0);
|
||||
UMSKT::setProgressLabel(NULL);
|
||||
UMSKT::reportProgress(UMSKT_PROGRESS_GEN, 0, 4096u);
|
||||
|
||||
do {
|
||||
UMSKT::reportProgress(UMSKT_PROGRESS_GEN, (unsigned)tries + 1u, 4096u);
|
||||
// x = R.x; y = R.y;
|
||||
EC_POINT_get_affine_coordinates(eCurve, r, x, y, numContext);
|
||||
|
||||
@@ -262,18 +279,19 @@ void PIDGEN3::BINK1998::Generate(
|
||||
pSignature = 0;
|
||||
BN_bn2lebinpad(s, (BYTE *)&pSignature, (int)sizeof(pSignature));
|
||||
tries++;
|
||||
UMSKT::reportProgress(UMSKT_PROGRESS_GEN, (unsigned)tries, 4096u);
|
||||
|
||||
// Pack product key.
|
||||
Pack(pRaw, pUpgrade, pSerial, pHash, pSignature);
|
||||
|
||||
UMSKT::debugf("Generation results:\n");
|
||||
UMSKT::debugf(" Upgrade: 0x%08x\n", (unsigned)pUpgrade);
|
||||
UMSKT::debugf(" Serial: 0x%08x\n", (unsigned)pSerial);
|
||||
UMSKT::debugf(" Hash: 0x%08x\n", (unsigned)pHash);
|
||||
UMSKT::debugf(" Signature: 0x%08llx\n", (unsigned long long)pSignature);
|
||||
UMSKT::debugf("\n");
|
||||
|
||||
if (tries < 4096 && pSignature > BITMASK(55)) {
|
||||
if (!(tries < 4096 && pSignature > BITMASK(55))) {
|
||||
UMSKT::debugf("Generation results:\n");
|
||||
UMSKT::debugf(" Upgrade: 0x%08x\n", (unsigned)pUpgrade);
|
||||
UMSKT::debugf(" Serial: 0x%08x\n", (unsigned)pSerial);
|
||||
UMSKT::debugf(" Hash: 0x%08x\n", (unsigned)pHash);
|
||||
UMSKT::debugf(" Signature: 0x%08llx\n", (unsigned long long)pSignature);
|
||||
UMSKT::debugf("\n");
|
||||
} else {
|
||||
EC_POINT_add(eCurve, r, r, basePoint, numContext);
|
||||
BN_add_word(c, 1);
|
||||
}
|
||||
|
||||
@@ -151,16 +151,21 @@ bool PIDGEN3::BINK2002::Verify(
|
||||
EC_POINT *t = EC_POINT_new(eCurve);
|
||||
|
||||
// t = sG
|
||||
UMSKT::setProgressLabel("s*G");
|
||||
UMSKT::setEcProgressPhase(UMSKT_PROGRESS_VERIFY);
|
||||
EC_POINT_mul(eCurve, t, nullptr, basePoint, s, context);
|
||||
|
||||
// p = eK
|
||||
UMSKT::setProgressLabel("e*K");
|
||||
EC_POINT_mul(eCurve, p, nullptr, publicKey, e, context);
|
||||
|
||||
// p += t
|
||||
EC_POINT_add(eCurve, p, t, p, context);
|
||||
|
||||
// p *= s
|
||||
UMSKT::setProgressLabel("s*P");
|
||||
EC_POINT_mul(eCurve, p, nullptr, p, s, context);
|
||||
UMSKT::setProgressLabel(NULL);
|
||||
|
||||
// x = p.x; y = p.y;
|
||||
EC_POINT_get_affine_coordinates(eCurve, p, x, y, context);
|
||||
@@ -245,10 +250,23 @@ void PIDGEN3::BINK2002::Generate(
|
||||
// One random scalar. Further candidates are c+1, c+2, ... so each extra
|
||||
// attempt adds G instead of multiplying the curve again.
|
||||
EC_POINT *r = EC_POINT_new(eCurve);
|
||||
unsigned mul_bits;
|
||||
UMSKT::umskt_bn_rand(c, FIELD_BITS_2003, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY);
|
||||
mul_bits = (unsigned)BN_num_bits(c);
|
||||
if (mul_bits == 0) {
|
||||
mul_bits = 1;
|
||||
}
|
||||
UMSKT::setProgressLabel("R=c*G");
|
||||
UMSKT::setEcProgressPhase(UMSKT_PROGRESS_MUL);
|
||||
UMSKT::reportProgress(UMSKT_PROGRESS_MUL, 0, mul_bits);
|
||||
UMSKT::setMulProgress(1);
|
||||
EC_POINT_mul(eCurve, r, nullptr, basePoint, c, numContext);
|
||||
UMSKT::setMulProgress(0);
|
||||
UMSKT::setProgressLabel(NULL);
|
||||
UMSKT::reportProgress(UMSKT_PROGRESS_GEN, 0, 4096u);
|
||||
|
||||
do {
|
||||
UMSKT::reportProgress(UMSKT_PROGRESS_GEN, (unsigned)tries + 1u, 4096u);
|
||||
// x = R.x; y = R.y;
|
||||
EC_POINT_get_affine_coordinates(eCurve, r, x, y, numContext);
|
||||
|
||||
@@ -280,6 +298,7 @@ void PIDGEN3::BINK2002::Generate(
|
||||
if (!serialInRange) {
|
||||
noSquare = true;
|
||||
tries++;
|
||||
UMSKT::reportProgress(UMSKT_PROGRESS_GEN, (unsigned)tries, 4096u);
|
||||
if (tries < 4096) {
|
||||
EC_POINT_add(eCurve, r, r, basePoint, numContext);
|
||||
BN_add_word(c, 1);
|
||||
@@ -383,20 +402,21 @@ void PIDGEN3::BINK2002::Generate(
|
||||
pSignature = 0;
|
||||
BN_bn2lebinpad(s, (BYTE *)&pSignature, (int)sizeof(pSignature));
|
||||
tries++;
|
||||
UMSKT::reportProgress(UMSKT_PROGRESS_GEN, (unsigned)tries, 4096u);
|
||||
|
||||
// Pack product key.
|
||||
Pack(pRaw, pUpgrade, pChannelID, pHash, pSignature, pAuthInfo);
|
||||
|
||||
UMSKT::debugf("Generation results:\n");
|
||||
UMSKT::debugf(" Upgrade: 0x%08x\n", (unsigned)pUpgrade);
|
||||
UMSKT::debugf("Channel ID: 0x%08x\n", (unsigned)pChannelID);
|
||||
UMSKT::debugf(" Hash: 0x%08x\n", (unsigned)pHash);
|
||||
UMSKT::debugf(" Signature: 0x%08llx\n", (unsigned long long)pSignature);
|
||||
UMSKT::debugf(" AuthInfo: 0x%08x\n", (unsigned)pAuthInfo);
|
||||
UMSKT::debugf(" Serial: %06u\n", (unsigned)serial);
|
||||
UMSKT::debugf("\n");
|
||||
|
||||
if (tries < 4096 && (pSignature > BITMASK(62) || noSquare || !serialInRange)) {
|
||||
if (!(tries < 4096 && (pSignature > BITMASK(62) || noSquare || !serialInRange))) {
|
||||
UMSKT::debugf("Generation results:\n");
|
||||
UMSKT::debugf(" Upgrade: 0x%08x\n", (unsigned)pUpgrade);
|
||||
UMSKT::debugf("Channel ID: 0x%08x\n", (unsigned)pChannelID);
|
||||
UMSKT::debugf(" Hash: 0x%08x\n", (unsigned)pHash);
|
||||
UMSKT::debugf(" Signature: 0x%08llx\n", (unsigned long long)pSignature);
|
||||
UMSKT::debugf(" AuthInfo: 0x%08x\n", (unsigned)pAuthInfo);
|
||||
UMSKT::debugf(" Serial: %06u\n", (unsigned)serial);
|
||||
UMSKT::debugf("\n");
|
||||
} else {
|
||||
EC_POINT_add(eCurve, r, r, basePoint, numContext);
|
||||
BN_add_word(c, 1);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
extern int main(int argc, char **argv);
|
||||
|
||||
extern "C" void umskt_bn_dispatch_init(void);
|
||||
|
||||
typedef void (*umskt_ctor)(void);
|
||||
|
||||
extern "C" umskt_ctor __init_array_start[] __attribute__((weak));
|
||||
@@ -680,6 +682,7 @@ extern "C" void mainCRTStartup(void) {
|
||||
HANDLE heap = GetProcessHeap();
|
||||
|
||||
__main();
|
||||
umskt_bn_dispatch_init();
|
||||
if (!command) {
|
||||
command = (char *)"";
|
||||
}
|
||||
|
||||
@@ -134,34 +134,32 @@ if ($importHits.Count -gt 0) {
|
||||
Fail "imports outside kernel32, or APIs missing on Windows 98 / NT 4: $shown"
|
||||
}
|
||||
|
||||
if ($Arch -eq "x86") {
|
||||
$badMnemonic = "(?i)^(cmov[a-z]*|fcmov[a-z]*|emms|nopl|nopw|fcomi|fcomip|fucomi|fucomip|movaps|movups|movapd|movupd|movdqa|movdqu|movss|movhps|movlps|movlhps|movhlps|xorps|xorpd|andps|andpd|orps|orpd|addps|addpd|addss|addsd|subps|subpd|subss|subsd|mulps|mulpd|mulss|mulsd|divps|divpd|divss|divsd|cvtsi2ss|cvtsi2sd|cvttss2si|cvttsd2si|cvtss2si|cvtsd2si|pshufd|pshuflw|pshufhw|pshufw|punpck[a-z]+|packss[a-z]+|packus[a-z]+|pcmp[a-z]+|padd[bwdq]|psub[bwdq]|pmullw|pmulhw|pmulhuw|pmaddwd|pavgb|pavgw|pextrw|pinsrw|pmovmskb|prefetch[a-z]*|sfence|mfence|lfence|maskmovq|movntq|movntps|lddqu|pause)\b"
|
||||
$badRegister = "(?i)%(mm|xmm|ymm|zmm)[0-9]"
|
||||
$insnHits = New-Object System.Collections.Generic.List[string]
|
||||
$disasm = & $Objdump -d -M att -- $Exe 2>&1
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Fail "objdump -d failed"
|
||||
$badMnemonic = "(?i)^(vfmadd132pd|vfmadd213pd|vfmadd231pd|v4fmadd|v4fnmadd|vp4dpw|vpopcntd|vpopcntq|vbroadcasti32x|vbroadcasti64x|vbroadcastf32x|vbroadcastf64x|vinserti32x|vinserti64x|vextracti32x|vextracti64x|vpermi2|vpermt2|vpcompress|vpexpand|vpgather[dq][dq]|vpscatter|vgatherpf|vscatterpf)\b"
|
||||
$badRegister = "(?i)%zmm[0-9]"
|
||||
$insnHits = New-Object System.Collections.Generic.List[string]
|
||||
$disasm = & $Objdump -d -M att -- $Exe 2>&1
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Fail "objdump -d failed"
|
||||
}
|
||||
foreach ($line in $disasm) {
|
||||
$text = [string]$line
|
||||
$insn = $null
|
||||
if ($text.Contains("`t")) {
|
||||
$parts = $text.Split("`t")
|
||||
$insn = $parts[$parts.Length - 1].Trim()
|
||||
}
|
||||
foreach ($line in $disasm) {
|
||||
$text = [string]$line
|
||||
$insn = $null
|
||||
if ($text.Contains("`t")) {
|
||||
$parts = $text.Split("`t")
|
||||
$insn = $parts[$parts.Length - 1].Trim()
|
||||
}
|
||||
if (-not $insn) {
|
||||
continue
|
||||
}
|
||||
if ($insn -match $badMnemonic -or $insn -match $badRegister) {
|
||||
$insnHits.Add($text.Trim())
|
||||
if ($insnHits.Count -ge 20) {
|
||||
break
|
||||
}
|
||||
if (-not $insn) {
|
||||
continue
|
||||
}
|
||||
if ($insn -match $badMnemonic -or $insn -match $badRegister) {
|
||||
$insnHits.Add($text.Trim())
|
||||
if ($insnHits.Count -ge 20) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if ($insnHits.Count -gt 0) {
|
||||
Fail ("forbidden instructions:`n" + ($insnHits -join "`n"))
|
||||
}
|
||||
}
|
||||
if ($insnHits.Count -gt 0) {
|
||||
Fail ("forbidden instructions:`n" + ($insnHits -join "`n"))
|
||||
}
|
||||
|
||||
Write-Host "Windows baseline check passed ($Arch, kernel32 only): $Exe"
|
||||
|
||||
Reference in new issue
Block a user