zk-poly.c (7127B)
1 /* Editor's note: a hacky implementation of the "Non-Interactive Zero-Knowledge 2 * of a Polynomial" scheme described in https://doi.org/10.48550/arXiv.1906.07221 3 * Written during late October 2020. 4 */ 5 6 #include <pthread.h> 7 #include <sys/types.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <sys/socket.h> 12 #include <arpa/inet.h> 13 #include <netinet/in.h> 14 #include <string.h> 15 #include <math.h> 16 #include <time.h> 17 #include <gmp.h> 18 19 #define PORT 5000 20 #define BUFSIZE 1024 21 #define EPSILON 0.000001 22 23 void* start_verifier(void* args) 24 { 25 // Intialize socket with AF_INET IP family and SOCK_DGRAM datagram service, exit if failed 26 int s; 27 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 28 exit(1); 29 } 30 // Establish sockaddr_in struct to pass into bind function 31 struct sockaddr_in addr; 32 memset((char *)&addr, 0, sizeof(addr)); 33 addr.sin_family = AF_INET; // Specify address family. 34 addr.sin_addr.s_addr = htonl(INADDR_ANY); // INADDR_ANY just 0.0.0.0, machine IP address 35 addr.sin_port = htons(PORT); // Specify port. 36 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 37 exit(1); 38 } 39 40 // IP address of client 41 struct sockaddr_in remaddr; 42 socklen_t addrlen = sizeof(remaddr); 43 int recvlen; 44 unsigned char buf[BUFSIZE]; 45 46 int connections = 0; 47 int clients[500]; 48 int unproven = 1; 49 int g = 6; 50 int degree = 3; 51 int n = 17; 52 int s_1; 53 int a; 54 mpz_t bigs; 55 mpz_init_set_ui(bigs, s_1); 56 mpz_t biga; 57 mpz_init_set_ui(biga, a); 58 mpz_t bigg; 59 mpz_init_set_ui(bigg, g); 60 mpz_t bign; 61 mpz_init_set_ui(bign, n); 62 mpz_t t; 63 while (unproven) { 64 recvlen = recvfrom(s, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen); 65 if (recvlen > BUFSIZE) { 66 sendto(s, "ERR: Too long.", 14, 0, (struct sockaddr *) &remaddr, addrlen); 67 } 68 else if (recvlen > 0) { 69 void* msg = 0x0; 70 buf[recvlen] = 0; 71 printf(" VERIFIER │ Received %d-byte message from %i: \"%s\"\n", 72 recvlen, remaddr.sin_port, buf); 73 if (recvlen==8) { 74 clients[connections] = remaddr.sin_port; 75 connections++; 76 srand(time(0)); 77 s_1 = rand() % 500; 78 a = rand() % 500; 79 mpz_init_set_ui(t, (s_1-((int*)buf)[0])*(s_1-((int*)buf)[1])); 80 printf(" VERIFIER │ Chose s = %d and a = %d\n", s_1, a); 81 mpz_t* enc_s = malloc(sizeof(mpz_t)*(degree+1)*2); 82 for (int i = 0; i <= degree; i++) { 83 mpz_init(enc_s[i]); 84 mpz_t temp1; 85 86 mpz_init_set_ui(temp1, (int)pow(s_1, i)); 87 mpz_powm_sec(enc_s[i], bigg, temp1, bign); 88 mpz_init(enc_s[degree+1+i]); 89 mpz_t temp2; 90 mpz_init_set_ui(temp2, (int)a*pow(s_1, i)); 91 mpz_powm_sec(enc_s[i+1+degree], bigg, temp2, bign); 92 } 93 msg = enc_s; 94 } else if (recvlen == sizeof(mpz_t)*3) { 95 mpz_t tmp1; 96 mpz_init(tmp1); 97 mpz_t tmp2; 98 mpz_init(tmp2); 99 mpz_powm_sec(tmp1, ((mpz_t*)buf)[2], t, bign); 100 mpz_t tmp3; 101 mpz_init(tmp3); 102 mpz_div(tmp3, ((mpz_t*)buf)[0], tmp1); 103 mpz_abs(tmp3, tmp3); 104 mpz_ui_sub(tmp3, 1, tmp3); 105 //gmp_printf("%Fe %Fe (diff %Fe)\n", ((mpz_t*)buf)[0], tmp1, tmp3); 106 if (mpz_cmp_d(tmp3, EPSILON) == -1) printf(" VERIFIER │ Valid roots!\n"); 107 else printf(" VERIFIER │ ERR: Invalid roots!\n"); 108 mpz_powm_sec(tmp2, ((mpz_t*)buf)[0], biga, bign); 109 mpz_t tmp4; 110 mpz_init(tmp4); 111 mpz_div(tmp4, ((mpz_t*)buf)[1], tmp2); 112 mpz_abs(tmp4, tmp4); 113 mpz_ui_sub(tmp4, 1, tmp4); 114 //gmp_printf("%Fe %Fe (diff %Fe)\n", ((mpz_t*)buf)[1], tmp2, tmp4); 115 if (mpz_cmp_d(tmp4, EPSILON) == -1) printf(" VERIFIER │ Valid form!\n"); 116 else printf(" VERIFIER │ ERR: Invalid form!\n"); 117 } 118 if (msg != 0x0) { 119 sendto(s, msg, sizeof(mpz_t)*(degree+1)*2, 0, (struct sockaddr *) &remaddr, addrlen); 120 } 121 } 122 } 123 124 return 0x0; 125 } 126 127 void* start_prover(void* args) 128 { 129 // Same socket is needed on client end so initialize all over again. 130 int s; 131 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 132 printf("\n Error : Socket Failed \n"); 133 } 134 struct sockaddr_in addr; 135 memset((char *)&addr, 0, sizeof(addr)); 136 addr.sin_family = AF_INET; // Specify address family. 137 addr.sin_addr.s_addr = htonl(INADDR_ANY); // INADDR_ANY just 0.0.0.0, machine IP address 138 addr.sin_port = htons(PORT); // Specify port. 139 // Connect to server 140 if(connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 141 printf("ERR: Connect failed.\n"); 142 return 0x0; 143 } 144 // NOTE This can and will not work if flag argument set to 1 145 int roots[2] = {-1,-2}; 146 sendto(s, roots, 8, 0, (struct sockaddr*)NULL, sizeof(addr)); 147 printf(" Prover │ Informed server of existence.\n"); 148 char buf[BUFSIZE]; 149 int recvlen; 150 socklen_t len = sizeof(addr); 151 int phase = 0; 152 int constants[4] = {0, 2, 3, 1}; 153 int degree = 3; 154 int delta = rand() % 100; 155 while (1==1) { 156 recvlen = recvfrom(s, buf, BUFSIZE, 0, (struct sockaddr *) &addr, &len); 157 if (recvlen > 0) { 158 buf[recvlen] = 0; 159 printf(" Prover │ Received %d-byte message from server: \"%s\"\n", recvlen, buf); 160 mpz_t* enc_ph = malloc(sizeof(mpz_t)*3); 161 mpz_init_set_ui(enc_ph[0], 1); 162 mpz_init_set_ui(enc_ph[1], 1); 163 mpz_init(enc_ph[2]); 164 for (int i = 0; i < degree+1; i++) { 165 mpz_pow_ui(((mpz_t*)buf)[i], ((mpz_t*)buf)[i], abs(constants[i])); 166 mpz_mul(enc_ph[0], enc_ph[0], ((mpz_t*)buf)[i]); 167 mpz_mul(enc_ph[1], enc_ph[1], ((mpz_t*)buf)[i+1+degree]); 168 } 169 mpz_t tmp1; 170 mpz_init(tmp1); 171 mpz_pow_ui(tmp1, ((mpz_t*)buf)[0], -roots[0]); 172 mpz_mul(tmp1, tmp1, ((mpz_t*)buf)[1]); 173 mpz_t tmp2; 174 mpz_init(tmp2); 175 mpz_pow_ui(tmp1, ((mpz_t*)buf)[0], -roots[1]); 176 mpz_mul(tmp1, tmp1, ((mpz_t*)buf)[1]); 177 mpz_t denom; 178 mpz_init(denom); 179 mpz_mul(denom, tmp1, tmp2); 180 mpz_div(enc_ph[2], enc_ph[0], denom); 181 for (int i = 0; i < 3; i++) mpz_pow_ui(enc_ph[i], enc_ph[i], delta); 182 sendto(s, enc_ph, sizeof(mpz_t)*3, 0, (struct sockaddr*)NULL, sizeof(addr)); 183 } 184 } 185 return 0x0; 186 } 187 188 int main() 189 { 190 pthread_t verifier; 191 pthread_create(&verifier, NULL, start_verifier, 0x0); 192 pthread_t prover; 193 pthread_create(&prover, NULL, start_prover, 0x0); 194 pthread_join(verifier, NULL); 195 }