dkg.c
1 #include <string.h> 2 #include "dkg.h" 3 #include "toprf.h" 4 #include "utils.h" 5 6 extern int liboprf_debug; 7 8 typedef struct { 9 uint8_t index; 10 uint8_t value[crypto_core_ristretto255_BYTES]; 11 } __attribute((packed)) TOPRF_Part; 12 13 static void topart(TOPRF_Part *r, const TOPRF_Share *s) { 14 r->index=s->index; 15 crypto_scalarmult_ristretto255_base(r->value, s->value); 16 } 17 18 static int test_dkg_start(const uint8_t n, 19 const uint8_t a[crypto_core_ristretto255_SCALARBYTES], 20 const TOPRF_Share shares[n]) { 21 const size_t response_len = 3; 22 uint8_t responses[response_len][TOPRF_Part_BYTES]; 23 uint8_t result[crypto_scalarmult_ristretto255_BYTES]; 24 uint8_t v[crypto_scalarmult_ristretto255_BYTES]; 25 26 topart((TOPRF_Part *) responses[0], &shares[4]); 27 topart((TOPRF_Part *) responses[1], &shares[2]); 28 topart((TOPRF_Part *) responses[2], &shares[0]); 29 30 if(toprf_thresholdmult(response_len, responses, result)) return 1; 31 32 crypto_scalarmult_ristretto255_base(v, a); 33 34 if(memcmp(v,result,sizeof v)!=0) { 35 fprintf(stderr,"\e[0;31mmeh!\e[0m\n"); 36 dump(v,sizeof v, "v"); 37 dump(result,sizeof v, "r"); 38 return 1; 39 } 40 return 0; 41 } 42 43 static int test_dkg_finish(const uint8_t n, const TOPRF_Share shares[n]) { 44 const size_t response_len = 3; 45 uint8_t responses[response_len][TOPRF_Part_BYTES]; 46 uint8_t v0[crypto_scalarmult_ristretto255_BYTES]={0}; 47 uint8_t v1[crypto_scalarmult_ristretto255_BYTES]={0}; 48 49 //dump((uint8_t*) &shares[4], sizeof(TOPRF_Share), "&shares[4][0] "); 50 topart((TOPRF_Part *) responses[0], &shares[4]); 51 topart((TOPRF_Part *) responses[1], &shares[2]); 52 topart((TOPRF_Part *) responses[2], &shares[0]); 53 //topart((TOPRF_Part *) responses[3], &shares[1][0]); 54 //topart((TOPRF_Part *) responses[4], &shares[3][0]); 55 if(toprf_thresholdmult(response_len, responses, v0)) return 1; 56 dump(v0,sizeof v0, "v0 "); 57 58 topart((TOPRF_Part *) responses[0], &shares[3]); 59 topart((TOPRF_Part *) responses[1], &shares[1]); 60 topart((TOPRF_Part *) responses[2], &shares[0]); 61 //topart((TOPRF_Part *) responses[3], &shares[2][0]); 62 //topart((TOPRF_Part *) responses[4], &shares[4][0]); 63 if(toprf_thresholdmult(response_len, responses, v1)) return 1; 64 dump(v1,sizeof v1, "v1 "); 65 66 if(memcmp(v0,v1,sizeof v1)!=0) { 67 fprintf(stderr,"\e[0;31mfailed to verify shares from dkg_finish!\e[0m\n"); 68 return 1; 69 } 70 return 0; 71 } 72 73 int main(void) { 74 liboprf_debug = 1; 75 uint8_t n=5, threshold=3; 76 uint8_t commitments[n][threshold][crypto_core_ristretto255_BYTES]; 77 TOPRF_Share shares[n][n]; 78 79 for(int i=0;i<n;i++) { 80 if(dkg_start(n, threshold, commitments[i], shares[i])) { 81 return 1; 82 } 83 if(liboprf_debug) { 84 for(int j=0;j<n;j++) { 85 dump((uint8_t*) &shares[i][j], sizeof(TOPRF_Share), "s[%d,%d] ", i+1, j+1); 86 } 87 fprintf(stderr,"\n"); 88 } 89 } 90 91 // each Pi sends s_ij, and s'_ij to Pj 92 // basically we are transposing here the shares matrix above 93 TOPRF_Share sent_shares[n]; 94 TOPRF_Share final_shares[n]; 95 96 for(int i=0;i<n;i++) { 97 for(int j=0;j<n;j++) { 98 memcpy(&sent_shares[j], &shares[j][i], sizeof(TOPRF_Share)); 99 if(liboprf_debug) { 100 fprintf(stderr, "\nsent to peer %d\n",i+1); 101 dump((uint8_t*) &sent_shares[j], sizeof(TOPRF_Share), "s[%d,%d] ", i+1, j+1); 102 } 103 } 104 105 uint8_t fails[n]; 106 memset(fails, 0, sizeof fails); 107 uint8_t fails_len=0; 108 109 // verify step (2) 110 if(dkg_verify_commitments(n,threshold,i+1, commitments, 111 sent_shares, fails, &fails_len)) { 112 for(int j=0;j<fails_len;j++) { 113 fprintf(stderr,"\e[0;31m[%d] failed to verify commitments from %d!\e[0m\n", i+1, fails[j]); 114 } 115 return 1; 116 } 117 118 fprintf(stderr, "\e[0;32mP_%d stage 1 correct!\e[0m\n", i); 119 120 final_shares[i].index=i+1; 121 // finalize dkg (3) 122 dkg_finish(n,sent_shares,i+1,&final_shares[i]); 123 } 124 125 for(int i=0;i<n;i++) { 126 dump((uint8_t*) &final_shares[i], sizeof(TOPRF_Share), "final_shares[%d]", i+1); 127 } 128 129 if(test_dkg_finish(n, final_shares)) return 1; 130 131 // x = sum(a[0]) == 0x28 if debian_rng_scalar is used 132 uint8_t x[crypto_core_ristretto255_BYTES]={0x28}; 133 if(test_dkg_start(n, x, final_shares)) return 1; 134 135 uint8_t v[crypto_core_ristretto255_BYTES]; 136 dkg_reconstruct(threshold, final_shares, v); 137 if(memcmp(v,x,sizeof v)!=0) { 138 fprintf(stderr,"\e[0;31mfailed to verify reconstruction of generated x from final shares!\e[0m\n"); 139 dump(x,sizeof x, "x "); 140 dump(v,sizeof v, "v "); 141 return 1; 142 } 143 144 fprintf(stderr, "\e[0;32meverything correct!\e[0m\n"); 145 return 0; 146 }