/* * main.c * This file is part of lib-gpu-verify. * * lib-gpu-verify is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * lib-gpu-verify is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Created by Cedric Zwahlen * */ #include #include #include #include #include #include #include #define NEED_LIBGCRYPT_VERSION "1.10.1" void gpuv_prepare_gcry(void) { gcry_control (GCRYCTL_SET_THREAD_CBS, 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); } static unsigned long n = 0; void *signatures_for_key(void *vargp) { int *id = (int *)vargp; FILE *pkfile; FILE *msfile; char pk_name[128]; char ms_name[128]; sprintf(pk_name, "frag_publickey_%i.txt",*id); sprintf(ms_name, "frag_msgsig_%i.txt",*id); pkfile = fopen(pk_name, "w"); msfile = fopen(ms_name, "w"); // make a key char *template = "(genkey(rsa(nbits 4:2048)))"; gcry_sexp_t parms; gcry_sexp_new(&parms, template, strlen(template), 1); gcry_sexp_t key; gcry_pk_genkey(&key,parms); gcry_mpi_t n_mpi; gcry_mpi_t e_mpi; gcry_sexp_extract_param(key,NULL,"n e",&n_mpi, &e_mpi, NULL); // e & n contain information about the public key, needed to verify the signatues later size_t n_len = 0; size_t e_len = 0; // that is a bit much unsigned char *nn = malloc(1028); unsigned char *ee = malloc(1028); memset(nn, 0, 1028); memset(ee, 0, 1028); gcry_mpi_print(GCRYMPI_FMT_HEX,nn,1028,&n_len,n_mpi); gcry_mpi_print(GCRYMPI_FMT_HEX,ee,1028,&e_len,e_mpi); fprintf(pkfile, "%s\n",nn); fprintf(pkfile, "%s\n",ee); fprintf(pkfile, "%lu\n",((*id + 1) * n) - 1); // this key is used for the signatures up to the index described by this number free(nn); free(ee); gcry_mpi_release(n_mpi); gcry_mpi_release(e_mpi); int len = 8; int i; for (i = 0; i < n; i++) { char buf[len]; gcry_mpi_t m_mpi; gcry_create_nonce(buf, len); gcry_mpi_scan(&m_mpi, GCRYMPI_FMT_STD, buf, len, NULL); gcry_mpi_abs(m_mpi); gcry_sexp_t toSign; size_t errOff = 0; char *dataformat = "(data (flags raw) (value %m))"; gcry_sexp_build(&toSign,&errOff,dataformat,m_mpi); gcry_sexp_t resSign; gcry_pk_sign(&resSign, toSign, key); gcry_mpi_t s_mpi; gcry_sexp_extract_param(resSign,NULL,"s",&s_mpi, NULL); // m_mpi contains the message, and s_mpi it's signature size_t m_len = 0; size_t s_len = 0; // that is a bit much unsigned char *mm = malloc(1028); unsigned char *ss = malloc(1028); memset(mm, 0, 1028); memset(ss, 0, 1028); gcry_mpi_print(GCRYMPI_FMT_HEX,mm,1028,&m_len,m_mpi); gcry_mpi_print(GCRYMPI_FMT_HEX,ss,1028,&s_len,s_mpi); fprintf(msfile, "%s\n",mm); fprintf(msfile, "%s\n",ss); free(mm); free(ss); gcry_mpi_release(s_mpi); gcry_mpi_release(m_mpi); gcry_sexp_release(toSign); gcry_sexp_release(resSign); } fclose(pkfile); fclose(msfile); gcry_sexp_release(parms); gcry_sexp_release(key); return NULL; } #define INCREMENT 8 int main(int argc, const char * argv[]) { // the first argument says how many signatures we should create per public key, if there is no argument, let's say we make.. 4? n = 0; int pks = 1; // no arg if (argc == 1) { n = 4; // a number is expected } else if (argc == 2) { n = atoi(argv[1]); } else if (argc == 3) { n = atoi(argv[1]); pks = atoi(argv[2]); } if (n == 0 || pks == 0) { printf("invalid parameters"); abort(); } if (pks == 1) { printf("generating %lu signatures with the same key.\n",n); } else { pks = pks - (pks % INCREMENT); printf("generating %lu signatures with %i keys.\n",n * pks, pks); } gpuv_prepare_gcry(); pthread_t *tid = malloc(pks * sizeof(pthread_t)); // not the best, but it is safe int ids[pks]; FILE *pkfile; FILE *msfile; pkfile = fopen("publickey.txt", "w"); msfile = fopen("msgsig.txt", "w"); int total = 0; for (int x = 0; x < (pks / INCREMENT); x++) { for (int i = total; i < (total + INCREMENT); i++) { ids[i] = i; int err = pthread_create(&tid[i], NULL, signatures_for_key, (void *)&ids[i]); if ( err != 0 ) printf("Error creating threads"); } for (int j = total; j < (total + INCREMENT); j++) { int err = pthread_join(tid[j], NULL); if ( err != 0 ) printf("Error joining threads"); } for (int k = total; k < (total + INCREMENT); k++) { struct stat pk_st, ms_st; char pk_name[128]; char ms_name[128]; sprintf(pk_name, "frag_publickey_%i.txt",k); sprintf(ms_name, "frag_msgsig_%i.txt",k); stat(pk_name, &pk_st); stat(ms_name, &ms_st); FILE * pk_fd = fopen(pk_name, "r"); FILE * ms_fd = fopen(ms_name, "r"); void *pk_buf = malloc(pk_st.st_size + 1); void *ms_buf = malloc(ms_st.st_size + 1); //char pk_buf[pk_st.st_size + 1]; //char ms_buf[ms_st.st_size + 1]; memset(pk_buf, 0, pk_st.st_size + 1); memset(ms_buf, 0, ms_st.st_size + 1); fread(pk_buf, 1, pk_st.st_size, pk_fd); fread(ms_buf, 1, ms_st.st_size, ms_fd); fprintf(pkfile, "%s",(char *)pk_buf); fprintf(msfile, "%s",(char *)ms_buf); free(pk_buf); free(ms_buf); unlink(pk_name); unlink(ms_name); fclose(pk_fd); fclose(ms_fd); } total += INCREMENT; } fclose(pkfile); fclose(msfile); free(tid); return 0; }