gpuvt-test.c (9976B)
1 /* 2 * gpuvt-test.h 3 * This file is part of lib-gpu-verify. 4 * 5 * lib-gpu-verify is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * lib-gpu-verify is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * Created by Cedric Zwahlen 16 * 17 */ 18 19 #include "gpuvt-test.h" 20 21 #define ORDER -1 // I think we need to do this, because we want to write it in the 'wrong' way 22 #define END 0 23 24 #define BITS 64 25 26 // sizes are always the same 32 units for all, except exp_buf 27 void gpuvt_read_files(enum GPUV_VARIANT variant, 28 void *n_buf, 29 void *msg_buf, 30 void *exp_buf, 31 void *s_buf, 32 unsigned long *pks, unsigned long *n) { 33 34 FILE * pk; 35 FILE * ms; 36 37 pk = fopen("../lib-gpu-generate/publickey.txt", "r"); 38 ms = fopen("../lib-gpu-generate/msgsig.txt", "r"); 39 40 if (pk == NULL || ms == NULL) { 41 printf("Auxiliary files not found."); 42 abort(); 43 } 44 45 fseek (ms, 0, SEEK_END); 46 long ms_l = ftell(ms); 47 fseek (ms, 0, SEEK_SET); 48 char *ms_ptr = malloc(ms_l); 49 char *ms_ptr_rest = ms_ptr; 50 if (ms_ptr || ms_ptr_rest) 51 { 52 fread (ms_ptr, 1, ms_l, ms); 53 memcpy(ms_ptr_rest, ms_ptr, ms_l); 54 } 55 fclose (ms); 56 57 fseek (pk, 0, SEEK_END); 58 long pk_l = ftell(pk); 59 fseek (pk, 0, SEEK_SET); 60 char *pk_ptr = malloc(pk_l); 61 char *pk_ptr_rest = pk_ptr; 62 if (pk_ptr && pk_ptr_rest) 63 { 64 fread (pk_ptr, 1, pk_l, pk); 65 memcpy(pk_ptr_rest, pk_ptr, pk_l); 66 } 67 fclose (pk); 68 69 char *n_buf_t = n_buf; 70 char *msg_buf_t = msg_buf; 71 char *s_buf_t = s_buf; 72 char *exp_buf_t = exp_buf; 73 74 int len; 75 76 switch (variant) { 77 case GPUV_GPU_REGULAR: 78 len = (GPUV_BIT_LENGTH_2048 / 8) / sizeof(DIGIT_T); 79 break; 80 default: 81 len = (GPUV_BIT_LENGTH_2048 / 8) / sizeof(gpu_register); 82 break; 83 } 84 85 char* message = strtok_r(ms_ptr, "\n", &ms_ptr_rest); 86 char* signature = strtok_r(0, "\n", &ms_ptr_rest); 87 char* modulus = strtok_r(pk_ptr, "\n", &pk_ptr_rest); 88 char* exponent = strtok_r(0, "\n", &pk_ptr_rest); 89 char* offs = strtok_r(0, "\n", &pk_ptr_rest); 90 91 int i = 0; 92 int j = 0; 93 94 mpz_t e,mod,msg,s; 95 96 mpz_init(e); 97 mpz_init(mod); 98 mpz_init(msg); 99 mpz_init(s); 100 101 while (message != NULL && signature != NULL) { 102 103 if (i == 0 || pks[j - 1] < i) { 104 105 mpz_set_str(mod,modulus,16); 106 mpz_set_str(e,exponent,16); 107 108 pks[j] = atoi(offs); 109 110 modulus = strtok_r(0, "\n", &pk_ptr_rest); 111 exponent = strtok_r(0, "\n", &pk_ptr_rest); 112 offs = strtok_r(0, "\n", &pk_ptr_rest); 113 114 switch (variant) { 115 case GPUV_GPU_REGULAR: 116 mpz_export(&n_buf_t[len * j * sizeof(DIGIT_T)], NULL, ORDER, sizeof(DIGIT_T), END, 0, mod); 117 mpz_export(&exp_buf_t[j * sizeof(uint32_t)], NULL, ORDER, sizeof(uint32_t), END, 0, e); 118 break; 119 default: 120 mpz_export(&n_buf_t[len * j* sizeof(gpu_register)], NULL, ORDER, sizeof(gpu_register), END, 0, mod); 121 mpz_export(&exp_buf_t[j * sizeof(unsigned long)], NULL, ORDER, sizeof(unsigned long), END, 0, e); 122 break; 123 } 124 125 126 127 128 j++; 129 130 } 131 132 mpz_set_str(msg,message,16); 133 mpz_set_str(s,signature,16); 134 135 message = strtok_r(0, "\n",&ms_ptr_rest); 136 signature = strtok_r(0, "\n",&ms_ptr_rest); 137 138 switch (variant) { 139 case GPUV_GPU_REGULAR: 140 mpz_export(&msg_buf_t[len * i * sizeof(DIGIT_T)], NULL, ORDER, sizeof(DIGIT_T), END, 0, msg); 141 mpz_export(&s_buf_t[len * i * sizeof(DIGIT_T)], NULL, ORDER, sizeof(DIGIT_T), END, 0, s); 142 break; 143 default: 144 mpz_export(&msg_buf_t[len * i * sizeof(gpu_register)], NULL, ORDER, sizeof(gpu_register), END, 0, msg); 145 mpz_export(&s_buf_t[len * i * sizeof(gpu_register)], NULL, ORDER, sizeof(gpu_register), END, 0, s); 146 break; 147 } 148 149 i++; 150 } 151 152 mpz_clear(e); 153 mpz_clear(mod); 154 mpz_clear(msg); 155 mpz_clear(s); 156 157 free(ms_ptr); 158 free(pk_ptr); 159 160 161 *n = i; 162 163 } 164 165 166 167 168 /* 169 The user would define their own behaviour here 170 171 This closure is called after the kernel has executed - it should be possible to call gpuv_start(...) from here, 172 however, calling other gpuv functions may lead to undefined behaviour 173 174 maybe pass the time it took here as well, it is also in the state object 175 */ 176 177 // pass void * cls als ertses argument 178 179 static volatile bool finished = 0; 180 181 void gpuvt_finally(void *cls, int valid, struct timespec time, unsigned long len, uint32_t *res) { 182 183 if (valid) { 184 fprintf(stderr,"Verdict: OK\n"); 185 } else { 186 fprintf(stderr,"Verdict: NOT OK\n"); 187 } 188 189 fprintf(stderr,"\nVerification took %ld.%06ld s\n",time.tv_sec, time.tv_nsec); 190 191 *((int*)cls) = !valid; 192 193 finished = 1; 194 } 195 196 197 int gpuvt_test(enum GPUV_VARIANT variant) { 198 199 finished = 0; 200 201 unsigned long pairs = gpuvt_estimate_pairs(); // returns an estimation of pairs 202 203 unsigned long digit_sz = (GPUV_BIT_LENGTH_2048 / 8) * pairs; 204 205 unsigned long arr_sz = pairs * sizeof(unsigned long); 206 207 char *n_buf = malloc(digit_sz); 208 char *msg_buf = malloc(digit_sz); 209 char *s_buf = malloc(digit_sz); 210 char *exp_buf = malloc(pairs * sizeof(unsigned long)); 211 212 memset(n_buf, 0, digit_sz); 213 memset(msg_buf, 0, digit_sz); 214 memset(s_buf, 0, digit_sz); 215 memset(exp_buf, 0, pairs * sizeof(unsigned long)); 216 217 unsigned long *pks = malloc(arr_sz); 218 memset(pks, 0, arr_sz); 219 220 // printf("Reading Test Keys...\n"); 221 222 gpuvt_read_files(variant, 223 n_buf, 224 msg_buf, 225 exp_buf, 226 s_buf, 227 pks, &pairs); 228 229 fprintf(stderr, "Verifying %lu signatures...\n", pairs); 230 231 unsigned long pubks = 0; 232 233 while (1) { 234 if (pks[pubks] + 1 >= pairs) 235 break; 236 pubks++; 237 } 238 239 pubks += 1; 240 241 struct gpuv_batch * batch = gpuv_prepare_batch(); 242 243 int len; 244 245 switch (variant) { 246 case GPUV_GPU_REGULAR: 247 len = (GPUV_BIT_LENGTH_2048 / 8) / sizeof(DIGIT_T); 248 break; 249 default: 250 len = (GPUV_BIT_LENGTH_2048 / 8) / sizeof(gpu_register); 251 break; 252 } 253 254 int x = 0; 255 256 for (int i = 0; i < pubks; i++) { 257 258 unsigned long range = (pks[i] + 1) - (i == 0 ? 0 : (pks[i - 1] + 1)); 259 260 size_t i_t; 261 262 struct gpuv_public_key * pub_key; 263 264 switch (variant) { 265 case GPUV_GPU_REGULAR: 266 i_t = i * sizeof(DIGIT_T); 267 pub_key = gpuv_prepare_pubkey(((uint32_t *)exp_buf)[i], len, &n_buf[len * i_t]); 268 break; 269 default: 270 i_t = i * sizeof(gpu_register); 271 pub_key = gpuv_prepare_pubkey(((unsigned long *)exp_buf)[i], len, &n_buf[len * i_t]); 272 break; 273 } 274 275 for (int j = 0; j < range; j++) { 276 277 size_t o; 278 279 switch (variant) { 280 case GPUV_GPU_REGULAR: 281 o = sizeof(DIGIT_T); 282 break; 283 default: 284 o = sizeof(gpu_register); 285 break; 286 } 287 288 struct gpuv_signature_message * sig_msg = gpuv_prepare_sig_msg(pub_key); 289 290 gpuv_add_message(sig_msg, len, &msg_buf[len * (j + x) * o]); 291 gpuv_add_signature(sig_msg, len, &s_buf[len * (j + x) * o]); 292 293 gpuv_add_to_batch(batch, sig_msg); 294 295 free(sig_msg); // sig_msg may be destroyed after adding it to the batch – public keys will be destroyed by freeing the state object 296 } 297 298 x+= range; 299 300 } 301 302 struct gpuv_info *info; 303 304 // sets everything up... 305 info = gpuv_init(variant, GPUV_BIT_LENGTH_2048); 306 307 // every object represents a batch of data that should be processed on the GPU. 308 struct gpuv_state *state; 309 310 state = gpuv_prepare(info, batch); 311 312 int valid = 0; 313 314 fprintf(stderr, "Kernel is running...\n"); 315 316 // A kernel always runs to completion – it can't be cancelled. But it is non-blocking, so the program can be terminated at any time. 317 gpuv_start(state, &gpuvt_finally, &valid, batch); 318 319 // wait for the job to finish 320 while (!finished) { sleep(1); } 321 322 gpuv_free_batch(batch); // destroy public keys here 323 324 gpuv_free_state(state); 325 326 gpuv_finish(info); 327 328 free(n_buf); 329 free(msg_buf); 330 free(s_buf); 331 free(exp_buf); 332 333 free(pks); 334 335 return valid; 336 } 337 338 339 340 341 int 342 main (int argc, char**argv) 343 { 344 345 int valid = 0; 346 347 gpuv_prepare_gcry (); 348 349 printf("--- MONTGOMERY (GPU) ---\n"); 350 valid |= gpuvt_test (GPUV_GPU_MONTGOMERY); 351 352 printf("\n--- NON-MONTGOMERY KERNEL (GPU) ---\n"); 353 valid |= gpuvt_test (GPUV_GPU_REGULAR); 354 355 printf("\n--- CPU ---\n"); 356 valid |= gpuvt_test (GPUV_CPU); 357 358 359 return valid; 360 }