commit 6de36dce671c293d9b3471bbfbd9c5b5242a03f7
parent 5ae7582d89b9e556c0b6c80fc3e023bdb5380c17
Author: Christian Grothoff <christian@grothoff.org>
Date: Wed, 17 Jan 2024 13:38:31 +0100
more hints
Diffstat:
| M | README.md | | | 9 | +++++++-- |
| M | source/util.c | | | 775 | +++++++++++++++++++++++++++++++++++++++++++------------------------------------ |
2 files changed, 428 insertions(+), 356 deletions(-)
diff --git a/README.md b/README.md
@@ -16,7 +16,12 @@ libgcrypt is required for cryptographic operations:
https://www.gnupg.org/software/libgcrypt/index.html
The gmp library is required for calculations on very large integers:
-apt install libgmp3-dev
+# apt install libgmp3-dev
OpenCL drivers & headers:
-apt install ocl-icd-opencl-dev
+# apt install ocl-icd-opencl-dev
+
+For Nvidia, you also need to:
+
+# apt install nvidia-opencl-icd
+
diff --git a/source/util.c b/source/util.c
@@ -18,52 +18,58 @@
#include "util.h"
-unsigned long gpuvt_estimate_pairs(void) {
-
- struct stat ss;
-
- int msfile = open("../lib-gpu-generate/msgsig.txt", O_RDONLY);
-
- if (-1 == msfile)
- {
- fprintf (stderr,
- "Failed to open: err %s\n",
- strerror (errno));
- exit (1);
- }
-
- fstat(msfile, &ss);
-
- unsigned long len_f = ss.st_size;
- unsigned long len_sig = (GPUV_BIT_LENGTH_2048 / 8) * 2 + 1; // this is the size of a 2048 bit signature in the file
-
- unsigned long n_min = len_f / (len_sig + 3); // if each message was only one character, then this would be the maximum amount of signatures that could be in the file – use this estimate to allocate storage for the signatures
-
- close(msfile);
-
- return n_min == 0 ? 1 : n_min;
+unsigned long
+gpuvt_estimate_pairs (void)
+{
+
+ struct stat ss;
+
+ int msfile = open ("../lib-gpu-generate/msgsig.txt", O_RDONLY);
+
+ if (-1 == msfile)
+ {
+ fprintf (stderr,
+ "Failed to open: err %s\n",
+ strerror (errno));
+ exit (1);
+ }
+
+ fstat (msfile, &ss);
+
+ unsigned long len_f = ss.st_size;
+ unsigned long len_sig = (GPUV_BIT_LENGTH_2048 / 8) * 2 + 1; // this is the size of a 2048 bit signature in the file
+
+ unsigned long n_min = len_f / (len_sig + 3); // if each message was only one character, then this would be the maximum amount of signatures that could be in the file – use this estimate to allocate storage for the signatures
+
+ close (msfile);
+
+ return n_min == 0 ? 1 : n_min;
}
-void gpuv_prepare_gcry(void) {
+void
+gpuv_prepare_gcry (void)
+{
- /* Version check should be the very first call because it
- makes sure that important subsystems are initialized.
- #define NEED_LIBGCRYPT_VERSION to the minimum required version. */
- if (!gcry_check_version (NEED_LIBGCRYPT_VERSION))
- {
- fprintf (stderr, "libgcrypt is too old (need %s, have %s)\n",
- NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL));
- exit (2); }
- /* Disable secure memory. */
- gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
- /* ... If required, other initialization goes here. */
- /* Tell Libgcrypt that initialization has completed. */
- gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ /* Version check should be the very first call because it
+ makes sure that important subsystems are initialized.
+ #define NEED_LIBGCRYPT_VERSION to the minimum required version. */
+ if (! gcry_check_version (NEED_LIBGCRYPT_VERSION))
+ {
+ fprintf (stderr, "libgcrypt is too old (need %s, have %s)\n",
+ NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL));
+ exit (2);
+ }
+ /* Disable secure memory. */
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ /* ... If required, other initialization goes here. */
+ /* Tell Libgcrypt that initialization has completed. */
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
}
+
cl_platform_id
select_platform (unsigned int offset,
bool print_platforms)
@@ -79,7 +85,7 @@ select_platform (unsigned int offset,
if (CL_SUCCESS != rplat)
{
fprintf (stderr,
- "Error: Failed to lookup platforms! (%d)\n",
+ "Error: Failed to lookup platforms! Maybe install $VENDOR-opencl-icd package? (Error #%d)\n",
rplat);
exit (1);
}
@@ -194,6 +200,7 @@ select_device (cl_platform_id platform)
return device_id;
}
+
void
logger (const char *errinfo,
const void *private_info,
@@ -205,6 +212,7 @@ logger (const char *errinfo,
errinfo);
}
+
cl_context
create_compute_context (cl_device_id device_id)
{
@@ -226,6 +234,7 @@ create_compute_context (cl_device_id device_id)
return context;
}
+
cl_command_queue
create_command_queue (cl_device_id device_id,
cl_context context)
@@ -247,6 +256,7 @@ create_command_queue (cl_device_id device_id,
return commands;
}
+
cl_program
compile_program (cl_device_id device_id,
cl_context context,
@@ -341,6 +351,7 @@ compile_program (cl_device_id device_id,
return program;
}
+
cl_kernel
create_kernel (cl_program program,
const char *name)
@@ -362,350 +373,406 @@ create_kernel (cl_program program,
return kernel;
}
+
// implementations of functions used by universal, but they themselves should not be exposed
/*
called after results has been copied from the gpu. releases many of the state variables, and invalidates the object
calls the users closure
*/
-void CL_CALLBACK callback_result(cl_event event, cl_int event_command_status, void *user_data) {
-
- //clReleaseEvent(event);
-
- struct gpuv_state *state = (struct gpuv_state *)user_data;
-
- // finish calculating results, and release memory
-
- clReleaseMemObject(state->x_mem);
- clReleaseMemObject(state->m_mem);
- clReleaseMemObject(state->n_mem);
- clReleaseMemObject(state->ni_mem);
- clReleaseMemObject(state->exp_mem);
- clReleaseMemObject(state->msg_mem);
- clReleaseMemObject(state->pks_indices);
-
- clReleaseCommandQueue(state->queue);
-
- state->stale = 1;
-
- struct timespec p1 = state->t;
-
- clock_gettime(CLOCK_REALTIME, &state->t);
-
- state->t.tv_sec = ( state->t.tv_nsec < p1.tv_nsec ? state->t.tv_sec - (p1.tv_sec + 1) : state->t.tv_sec - p1.tv_sec );
- state->t.tv_nsec = ( state->t.tv_nsec < p1.tv_nsec ? ((999999999 - p1.tv_nsec) + state->t.tv_nsec) : (state->t.tv_nsec - p1.tv_nsec) ) / 1000;
-
- // the user could check this themselves, but I give them a boolean field valid, that says whether there is a faulty signature in the batch or not
-
- int ret = 1;
-
- unsigned long partial = state->sig_count / (sizeof(uint32_t) * 8);
-
- for(int i = 0; i < state->results_len; i++) {
-
- uint32_t mask = 0;
-
- if (i >= partial) {
- int remaining = state->sig_count % (sizeof(uint32_t) * 8);
-
- for (int x = 0; x < remaining; x++) { mask |= 1 << x; }
-
- } else {
- mask = UINT32_MAX;
- }
-
- if (state->results[i] != mask) {
- ret = 0;
- }
+void CL_CALLBACK
+callback_result (cl_event event, cl_int event_command_status, void *user_data)
+{
+
+ // clReleaseEvent(event);
+
+ struct gpuv_state *state = (struct gpuv_state *) user_data;
+
+ // finish calculating results, and release memory
+
+ clReleaseMemObject (state->x_mem);
+ clReleaseMemObject (state->m_mem);
+ clReleaseMemObject (state->n_mem);
+ clReleaseMemObject (state->ni_mem);
+ clReleaseMemObject (state->exp_mem);
+ clReleaseMemObject (state->msg_mem);
+ clReleaseMemObject (state->pks_indices);
+
+ clReleaseCommandQueue (state->queue);
+
+ state->stale = 1;
+
+ struct timespec p1 = state->t;
+
+ clock_gettime (CLOCK_REALTIME, &state->t);
+
+ state->t.tv_sec = (state->t.tv_nsec < p1.tv_nsec ? state->t.tv_sec
+ - (p1.tv_sec + 1) : state->t.tv_sec - p1.tv_sec);
+ state->t.tv_nsec = (state->t.tv_nsec < p1.tv_nsec ? ((999999999
+ - p1.tv_nsec)
+ + state->t.tv_nsec) :
+ (state->t.tv_nsec - p1.tv_nsec) ) / 1000;
+
+ // the user could check this themselves, but I give them a boolean field valid, that says whether there is a faulty signature in the batch or not
+
+ int ret = 1;
+
+ unsigned long partial = state->sig_count / (sizeof(uint32_t) * 8);
+
+ for (int i = 0; i < state->results_len; i++)
+ {
+
+ uint32_t mask = 0;
+
+ if (i >= partial)
+ {
+ int remaining = state->sig_count % (sizeof(uint32_t) * 8);
+
+ for (int x = 0; x < remaining; x++)
+ {
+ mask |= 1 << x;
+ }
+
}
-
- state->info->in_progress = 0;
- state->valid = ret;
-
- // pass results to user
- state->cls(state->arg, state->valid, state->t, state->results_len, state->results);
-
+ else
+ {
+ mask = UINT32_MAX;
+ }
+
+ if (state->results[i] != mask)
+ {
+ ret = 0;
+ }
+ }
+
+ state->info->in_progress = 0;
+ state->valid = ret;
+
+ // pass results to user
+ state->cls (state->arg, state->valid, state->t, state->results_len,
+ state->results);
+
}
+
/*
called after kernel finishes. launches another async process to copy the results from gpu memory
*/
-void CL_CALLBACK callback_kernel(cl_event event, cl_int event_command_status, void *user_data) {
-
- //clReleaseEvent(event); // only call here if we wait for completion
-
- struct gpuv_state *state = (struct gpuv_state *)user_data;
-
- //MARK: no expensive operations here
-
- unsigned long res_len = state->results_len;
- unsigned long res_len_bytes = res_len * sizeof(uint32_t);
-
- int err = 0;
-
- cl_event e = clCreateUserEvent(state->info->context, NULL);
-
- // Read back the results from the device to verify the output
- err = clEnqueueReadBuffer(state->queue, state->res_mem, CL_TRUE, 0, res_len_bytes, state->results, 0, NULL, &e);
- if (err != CL_SUCCESS)
- {
- printf("Error: Failed to read output array! %d\n", err);
- exit(1);
- }
-
- clSetEventCallback(e, CL_COMPLETE, callback_result, state);
- clReleaseEvent(e);
-}
+void CL_CALLBACK
+callback_kernel (cl_event event, cl_int event_command_status, void *user_data)
+{
+
+ // clReleaseEvent(event); // only call here if we wait for completion
+
+ struct gpuv_state *state = (struct gpuv_state *) user_data;
+
+ // MARK: no expensive operations here
+
+ unsigned long res_len = state->results_len;
+ unsigned long res_len_bytes = res_len * sizeof(uint32_t);
+
+ int err = 0;
+
+ cl_event e = clCreateUserEvent (state->info->context, NULL);
+
+ // Read back the results from the device to verify the output
+ err = clEnqueueReadBuffer (state->queue, state->res_mem, CL_TRUE, 0,
+ res_len_bytes, state->results, 0, NULL, &e);
+ if (err != CL_SUCCESS)
+ {
+ printf ("Error: Failed to read output array! %d\n", err);
+ exit (1);
+ }
+ clSetEventCallback (e, CL_COMPLETE, callback_result, state);
+ clReleaseEvent (e);
+}
#define ORDER -1 // I think we need to do this, because we want to write it in the 'wrong' way
#define END 0
-//#define GPUV_BIT_LENGTH 2048
+// #define GPUV_BIT_LENGTH 2048
#define BITS 64
-void pk_to_mont(struct gpuv_public_key * pk) {
-
- if (pk->prepared) return;
-
- gpu_register *ni_buf = malloc(pk->len_n * sizeof(gpu_register));
- memset(ni_buf, 0, pk->len_n * sizeof(gpu_register));
- gpu_register *r_1_buf = malloc(pk->len_n * sizeof(gpu_register));
- memset(r_1_buf, 0, pk->len_n * sizeof(gpu_register));
-
- mpz_t mod, r, r_1, ni;
-
- mpz_init(r);
- mpz_init(r_1);
- mpz_init(ni);
- mpz_init(mod);
-
- mpz_t one; // helper variable
- mpz_init_set_si(one,1);
-
- mpz_set_si(one, 1);
- mpz_mul_2exp(r,one,GPUV_BIT_LENGTH_2048); // r
-
- mpz_import(mod, pk->len_n, ORDER, sizeof(gpu_register), END, 0, pk->n);
-
- mpz_gcdext(one, r_1, ni, r, mod); // set r_1 and ni
-
- int sgn = mpz_sgn(r_1);
-
- mpz_abs(r_1, r_1);
- mpz_abs(ni, ni);
-
- if (sgn == -1) {
- mpz_sub(ni, r, ni);
- mpz_sub(r_1, mod, r_1);
- }
-
- mpz_export(ni_buf, NULL, ORDER, sizeof(gpu_register), END, 0, ni);
- mpz_export(r_1_buf, NULL, ORDER, sizeof(gpu_register), END, 0, r_1);
-
- pk->ni = (char *)ni_buf;
- pk->len_ni = pk->len_n; // has to be the same length as n
- pk->r_1 = (char *)r_1_buf;
- pk->len_r_1 = pk->len_n;
-
- mpz_clear(r);
- mpz_clear(r_1);
- mpz_clear(ni);
- mpz_clear(one);
- mpz_clear(mod);
-
- pk->prepared = 1;
-
+void
+pk_to_mont (struct gpuv_public_key *pk)
+{
+
+ if (pk->prepared)
+ return;
+
+ gpu_register *ni_buf = malloc (pk->len_n * sizeof(gpu_register));
+ memset (ni_buf, 0, pk->len_n * sizeof(gpu_register));
+ gpu_register *r_1_buf = malloc (pk->len_n * sizeof(gpu_register));
+ memset (r_1_buf, 0, pk->len_n * sizeof(gpu_register));
+
+ mpz_t mod, r, r_1, ni;
+
+ mpz_init (r);
+ mpz_init (r_1);
+ mpz_init (ni);
+ mpz_init (mod);
+
+ mpz_t one; // helper variable
+ mpz_init_set_si (one,1);
+
+ mpz_set_si (one, 1);
+ mpz_mul_2exp (r,one,GPUV_BIT_LENGTH_2048); // r
+
+ mpz_import (mod, pk->len_n, ORDER, sizeof(gpu_register), END, 0, pk->n);
+
+ mpz_gcdext (one, r_1, ni, r, mod); // set r_1 and ni
+
+ int sgn = mpz_sgn (r_1);
+
+ mpz_abs (r_1, r_1);
+ mpz_abs (ni, ni);
+
+ if (sgn == -1)
+ {
+ mpz_sub (ni, r, ni);
+ mpz_sub (r_1, mod, r_1);
+ }
+
+ mpz_export (ni_buf, NULL, ORDER, sizeof(gpu_register), END, 0, ni);
+ mpz_export (r_1_buf, NULL, ORDER, sizeof(gpu_register), END, 0, r_1);
+
+ pk->ni = (char *) ni_buf;
+ pk->len_ni = pk->len_n; // has to be the same length as n
+ pk->r_1 = (char *) r_1_buf;
+ pk->len_r_1 = pk->len_n;
+
+ mpz_clear (r);
+ mpz_clear (r_1);
+ mpz_clear (ni);
+ mpz_clear (one);
+ mpz_clear (mod);
+
+ pk->prepared = 1;
+
}
-void sig_msg_to_mont(struct gpuv_signature_message * sig_msg) {
-
- if (sig_msg->prepared)
- {
-
- return;
- }
-
- gpu_register *x_buf = malloc(sig_msg->pubkey->len_n * sizeof(gpu_register));
- memset(x_buf, 0, sig_msg->pubkey->len_n * sizeof(gpu_register));
- gpu_register *M_buf = malloc(sig_msg->pubkey->len_n * sizeof(gpu_register));
- memset(M_buf, 0, sig_msg->pubkey->len_n * sizeof(gpu_register));
-
-
- mpz_t mod, sig;
- mpz_init(sig);
- mpz_init(mod);
-
- mpz_t M, x, r;
-
- mpz_init(M);
- mpz_init(x);
- mpz_init(r);
-
- mpz_t one; // helper variable
- mpz_init_set_si(one,1);
-
- mpz_set_si(one, 1);
- mpz_mul_2exp(r,one,GPUV_BIT_LENGTH_2048); // r
-
- mpz_import(mod, sig_msg->pubkey->len_n, ORDER, sizeof(gpu_register), END, 0, sig_msg->pubkey->n);
-
- mpz_import(sig, sig_msg->len_s, ORDER, sizeof(gpu_register), END, 0, sig_msg->s);
-
- // set x (the number to 'square' (multiply by itself))
- mpz_mul(M, sig, r);
- mpz_mod(M, M, mod);
-
- mpz_mod(x, r, mod);
-
- mpz_export(x_buf, NULL, ORDER, sizeof(gpu_register), END, 0, x);
- mpz_export(M_buf, NULL, ORDER, sizeof(gpu_register), END, 0, M);
-
- mpz_clear(sig);
- mpz_clear(mod);
- mpz_clear(r);
- mpz_clear(one);
- mpz_clear(M);
- mpz_clear(x);
-
- sig_msg->x = (char *)x_buf;
- sig_msg->len_x = sig_msg->pubkey->len_n;
- sig_msg->M = (char *)M_buf;
- sig_msg->len_M = sig_msg->pubkey->len_n;
-
- sig_msg->prepared = 1;
-
+
+void
+sig_msg_to_mont (struct gpuv_signature_message *sig_msg)
+{
+
+ if (sig_msg->prepared)
+ {
+
+ return;
+ }
+
+ gpu_register *x_buf = malloc (sig_msg->pubkey->len_n * sizeof(gpu_register));
+ memset (x_buf, 0, sig_msg->pubkey->len_n * sizeof(gpu_register));
+ gpu_register *M_buf = malloc (sig_msg->pubkey->len_n * sizeof(gpu_register));
+ memset (M_buf, 0, sig_msg->pubkey->len_n * sizeof(gpu_register));
+
+
+ mpz_t mod, sig;
+ mpz_init (sig);
+ mpz_init (mod);
+
+ mpz_t M, x, r;
+
+ mpz_init (M);
+ mpz_init (x);
+ mpz_init (r);
+
+ mpz_t one; // helper variable
+ mpz_init_set_si (one,1);
+
+ mpz_set_si (one, 1);
+ mpz_mul_2exp (r,one,GPUV_BIT_LENGTH_2048); // r
+
+ mpz_import (mod, sig_msg->pubkey->len_n, ORDER, sizeof(gpu_register), END, 0,
+ sig_msg->pubkey->n);
+
+ mpz_import (sig, sig_msg->len_s, ORDER, sizeof(gpu_register), END, 0,
+ sig_msg->s);
+
+ // set x (the number to 'square' (multiply by itself))
+ mpz_mul (M, sig, r);
+ mpz_mod (M, M, mod);
+
+ mpz_mod (x, r, mod);
+
+ mpz_export (x_buf, NULL, ORDER, sizeof(gpu_register), END, 0, x);
+ mpz_export (M_buf, NULL, ORDER, sizeof(gpu_register), END, 0, M);
+
+ mpz_clear (sig);
+ mpz_clear (mod);
+ mpz_clear (r);
+ mpz_clear (one);
+ mpz_clear (M);
+ mpz_clear (x);
+
+ sig_msg->x = (char *) x_buf;
+ sig_msg->len_x = sig_msg->pubkey->len_n;
+ sig_msg->M = (char *) M_buf;
+ sig_msg->len_M = sig_msg->pubkey->len_n;
+
+ sig_msg->prepared = 1;
+
}
-gcry_sexp_t *sexp_from_string(char* str, const char *format) {
-
- gcry_sexp_t *sexp = malloc(sizeof(gcry_sexp_t));
-
- gcry_mpi_t mpi;
-
- char * str_buf = malloc((GPUV_BIT_LENGTH_2048 / 8) * 2 + 8);
-
- mpz_t m;
- mpz_init(m);
-
- mpz_import(m, 32, ORDER, sizeof(gpu_register), END, 0, str);
-
- mpz_get_str(str_buf, 16, m);
-
-
- gcry_mpi_scan(&mpi, GCRYMPI_FMT_HEX, str_buf, 0, NULL);
-
- size_t errOff = 0;
- gcry_sexp_build(sexp,&errOff,format,mpi);
-
- gcry_mpi_release(mpi);
- free(str_buf);
-
- mpz_clear(m);
-
- return sexp;
+
+gcry_sexp_t *
+sexp_from_string (char*str, const char *format)
+{
+
+ gcry_sexp_t *sexp = malloc (sizeof(gcry_sexp_t));
+
+ gcry_mpi_t mpi;
+
+ char *str_buf = malloc ((GPUV_BIT_LENGTH_2048 / 8) * 2 + 8);
+
+ mpz_t m;
+ mpz_init (m);
+
+ mpz_import (m, 32, ORDER, sizeof(gpu_register), END, 0, str);
+
+ mpz_get_str (str_buf, 16, m);
+
+
+ gcry_mpi_scan (&mpi, GCRYMPI_FMT_HEX, str_buf, 0, NULL);
+
+ size_t errOff = 0;
+ gcry_sexp_build (sexp,&errOff,format,mpi);
+
+ gcry_mpi_release (mpi);
+ free (str_buf);
+
+ mpz_clear (m);
+
+ return sexp;
}
-gcry_sexp_t *sexp_from_string_key(char* str_1, char* str_1_buf, unsigned long str_2, const char *format) {
-
- gcry_sexp_t *sexp = malloc(sizeof(gcry_sexp_t));
-
- gcry_mpi_t mpi_1;
-
-
- mpz_t m;
- mpz_init(m);
-
- mpz_import(m, 32, ORDER, sizeof(gpu_register), END, 0, str_1);
-
- mpz_get_str(str_1_buf, 16, m);
-
- gcry_mpi_scan(&mpi_1, GCRYMPI_FMT_HEX, str_1_buf, 0, NULL);
-
- gcry_mpi_t mpi_2 = gcry_mpi_set_ui(NULL, str_2);
-
- size_t errOff = 0;
- gcry_sexp_build(sexp,&errOff,format,mpi_1,mpi_2);
-
- gcry_mpi_release(mpi_1);
- gcry_mpi_release(mpi_2);
-
- mpz_clear(m);
-
- return sexp;
+
+gcry_sexp_t *
+sexp_from_string_key (char*str_1, char*str_1_buf, unsigned long str_2, const
+ char *format)
+{
+
+ gcry_sexp_t *sexp = malloc (sizeof(gcry_sexp_t));
+
+ gcry_mpi_t mpi_1;
+
+
+ mpz_t m;
+ mpz_init (m);
+
+ mpz_import (m, 32, ORDER, sizeof(gpu_register), END, 0, str_1);
+
+ mpz_get_str (str_1_buf, 16, m);
+
+ gcry_mpi_scan (&mpi_1, GCRYMPI_FMT_HEX, str_1_buf, 0, NULL);
+
+ gcry_mpi_t mpi_2 = gcry_mpi_set_ui (NULL, str_2);
+
+ size_t errOff = 0;
+ gcry_sexp_build (sexp,&errOff,format,mpi_1,mpi_2);
+
+ gcry_mpi_release (mpi_1);
+ gcry_mpi_release (mpi_2);
+
+ mpz_clear (m);
+
+ return sexp;
}
-void cpu_verify(struct gpuv_batch *batch, struct gpuv_state *state) {
-
- struct timespec p1, p2;
-
- clock_gettime(CLOCK_REALTIME, &p1);
-
- for (int j = 0; j < batch->current; j++) {
-
- struct gpuv_public_key * p = batch->pairs[ j ].pubkey;
-
- char * str_key_buf = malloc((GPUV_BIT_LENGTH_2048 / 8) * 2 + 8);
-
- gcry_sexp_t * key_sexp = sexp_from_string_key(p->n, str_key_buf, p->e, "(public-key (rsa (n %m) (e %m)))" ); // pub key data
-
- gcry_sexp_t *m_sexp = sexp_from_string(batch->pairs[j].m, "(data (flags raw) (value %m))"); // message format (for comparison)
-
- gcry_sexp_t *s_sexp = sexp_from_string(batch->pairs[j].s, "(sig-val (rsa (s %m)))"); // signature format
-
- if ( gcry_pk_verify(*s_sexp, *m_sexp, *key_sexp) == 0 ) {
-
- uint32_t out_offset = j / (sizeof(uint32_t) * 8); // 32 bit
-
- uint32_t mv = 1 << j;
-
- state->results[out_offset] |= mv;
-
- }
-
- gcry_sexp_release(*m_sexp);
- gcry_sexp_release(*s_sexp);
- gcry_sexp_release(*key_sexp);
-
- free(str_key_buf);
-
+
+void
+cpu_verify (struct gpuv_batch *batch, struct gpuv_state *state)
+{
+
+ struct timespec p1, p2;
+
+ clock_gettime (CLOCK_REALTIME, &p1);
+
+ for (int j = 0; j < batch->current; j++)
+ {
+
+ struct gpuv_public_key *p = batch->pairs[ j ].pubkey;
+
+ char *str_key_buf = malloc ((GPUV_BIT_LENGTH_2048 / 8) * 2 + 8);
+
+ gcry_sexp_t *key_sexp = sexp_from_string_key (p->n, str_key_buf, p->e,
+ "(public-key (rsa (n %m) (e %m)))"); // pub key data
+
+ gcry_sexp_t *m_sexp = sexp_from_string (batch->pairs[j].m,
+ "(data (flags raw) (value %m))"); // message format (for comparison)
+
+ gcry_sexp_t *s_sexp = sexp_from_string (batch->pairs[j].s,
+ "(sig-val (rsa (s %m)))"); // signature format
+
+ if (gcry_pk_verify (*s_sexp, *m_sexp, *key_sexp) == 0)
+ {
+
+ uint32_t out_offset = j / (sizeof(uint32_t) * 8); // 32 bit
+
+ uint32_t mv = 1 << j;
+
+ state->results[out_offset] |= mv;
+
}
-
- state->stale = 1;
-
- int ret = 1;
-
- unsigned long partial = state->sig_count / (sizeof(uint32_t) * 8);
-
- for(int i = 0; i < state->results_len; i++) {
-
- uint32_t mask = 0;
-
- if (i >= partial) {
- int remaining = state->sig_count % (sizeof(uint32_t) * 8);
-
- for (int x = 0; x < remaining; x++) { mask |= 1 << x; }
-
- } else {
- mask = UINT32_MAX;
- }
-
- if (state->results[i] != mask) {
- ret = 0;
- }
+
+ gcry_sexp_release (*m_sexp);
+ gcry_sexp_release (*s_sexp);
+ gcry_sexp_release (*key_sexp);
+
+ free (str_key_buf);
+
+ }
+
+ state->stale = 1;
+
+ int ret = 1;
+
+ unsigned long partial = state->sig_count / (sizeof(uint32_t) * 8);
+
+ for (int i = 0; i < state->results_len; i++)
+ {
+
+ uint32_t mask = 0;
+
+ if (i >= partial)
+ {
+ int remaining = state->sig_count % (sizeof(uint32_t) * 8);
+
+ for (int x = 0; x < remaining; x++)
+ {
+ mask |= 1 << x;
+ }
+
+ }
+ else
+ {
+ mask = UINT32_MAX;
+ }
+
+ if (state->results[i] != mask)
+ {
+ ret = 0;
}
-
- state->info->in_progress = 0;
- state->valid = ret;
-
- clock_gettime(CLOCK_REALTIME, &p2);
-
- state->t.tv_sec = ( p2.tv_nsec < p1.tv_nsec ? p2.tv_sec - (p1.tv_sec + 1) : p2.tv_sec - p1.tv_sec );
- state->t.tv_nsec = ( p2.tv_nsec < p1.tv_nsec ? ((999999999 - p1.tv_nsec) + p2.tv_nsec) : (p2.tv_nsec - p1.tv_nsec) ) / 1000;
-
- // pass results to user
- state->cls(state->arg, state->valid, state->t, state->results_len, state->results);
-
+ }
+
+ state->info->in_progress = 0;
+ state->valid = ret;
+
+ clock_gettime (CLOCK_REALTIME, &p2);
+
+ state->t.tv_sec = (p2.tv_nsec < p1.tv_nsec ? p2.tv_sec - (p1.tv_sec + 1) :
+ p2.tv_sec - p1.tv_sec);
+ state->t.tv_nsec = (p2.tv_nsec < p1.tv_nsec ? ((999999999 - p1.tv_nsec)
+ + p2.tv_nsec) : (p2.tv_nsec
+ - p1.tv_nsec) )
+ / 1000;
+
+ // pass results to user
+ state->cls (state->arg, state->valid, state->t, state->results_len,
+ state->results);
+
}