libgpuverify

Signature verification on GPUs (WiP)
Log | Files | Refs | README | LICENSE

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 }