-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy paththmult.c
149 lines (129 loc) · 5.04 KB
/
thmult.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <sodium.h>
#include <stdint.h>
#include <string.h>
#include "matrices.h"
#include "toprf.h"
typedef struct {
uint8_t index;
uint8_t value[crypto_core_ristretto255_SCALARBYTES];
} __attribute((packed)) TOPRF_Share;
int toprf_mpc_mul_start(const uint8_t _a[TOPRF_Share_BYTES],
const uint8_t _b[TOPRF_Share_BYTES],
const uint8_t peers, const uint8_t threshold,
uint8_t shares[peers][TOPRF_Share_BYTES]) {
const TOPRF_Share *a=(TOPRF_Share*) _a;
const TOPRF_Share *b=(TOPRF_Share*) _b;
if(a->index!=b->index ||
peers<threshold ||
threshold == 0) return 1;
uint8_t ab[crypto_core_ristretto255_SCALARBYTES];
crypto_core_ristretto255_scalar_mul(ab, a->value, b->value);
//dump(ab, sizeof ab, "ab");
toprf_create_shares(ab, peers, threshold, shares);
//for(unsigned j=0;j<peers;j++)
//dump(shares[j], TOPRF_Share_BYTES, "mulshare");
return 0;
}
void toprf_mpc_mul_finish(const uint8_t peers, const uint8_t indexes[peers],
const uint8_t peer,
const uint8_t shares[peers][TOPRF_Share_BYTES],
uint8_t _share[TOPRF_Share_BYTES]) {
TOPRF_Share *share=(TOPRF_Share*) _share;
// pre-calculate inverted vandermonde matrix of the indexes of the peers
uint8_t vdm[peers][peers][crypto_core_ristretto255_SCALARBYTES];
genVDMmatrix(indexes, peers, vdm);
uint8_t inverted[peers][peers][crypto_core_ristretto255_SCALARBYTES];
invert(peers, vdm, inverted);
// execute step 2 of simple mult
// H(j) = sum(lambda[i] * h[i](j) for i in 1..2t+1)
memset(share,0,TOPRF_Share_BYTES);
share->index=peer;
uint8_t tmp[crypto_core_ristretto255_SCALARBYTES];
for(unsigned i=0;i<peers;i++) {
crypto_core_ristretto255_scalar_mul(tmp, shares[i]+1, inverted[0][i]);
//dump(shares[i], TOPRF_Share_BYTES, "mulshare[i][j]");
crypto_core_ristretto255_scalar_add(share->value, share->value, tmp);
}
//dump(share->value, sizeof share->value, "share");
}
#ifdef UNIT_TEST
#include <stdio.h>
#include "utils.h"
//static void print_matrix(const uint8_t size, const uint8_t matrix[size][size][crypto_core_ristretto255_SCALARBYTES]) {
// int i = 0;
// for(int j=0;j<size;j++) {
// uint8_t len=crypto_core_ristretto255_SCALARBYTES-1;
// for(; matrix[i][j][len]==0; len--);
// dump(matrix[i][j],len+1,"");
// fprintf(stderr, " ");
// }
// fprintf(stderr, "\n");
//}
int main(void) {
const unsigned threshold = 2, peers = (threshold*2) + 1;
// share value k0
uint8_t k0[crypto_core_ristretto255_SCALARBYTES];
crypto_core_ristretto255_scalar_random(k0);
//debian_rng(k0);
//dump(k0, sizeof k0, "k0");
// split k into shares
uint8_t shares0[peers][TOPRF_Share_BYTES];
toprf_create_shares(k0, peers, threshold, shares0);
//for(unsigned j=0;j<peers;j++)
// dump(shares0[j], TOPRF_Share_BYTES, "shares0");
//printf("\n");
// share value k1
uint8_t k1[crypto_core_ristretto255_SCALARBYTES];
crypto_core_ristretto255_scalar_random(k1);
//debian_rng(k1);
//dump(k1, sizeof k1, "k1");
// split k into shares
uint8_t shares1[peers][TOPRF_Share_BYTES];
toprf_create_shares(k1, peers, threshold, shares1);
//for(unsigned j=0;j<peers;j++)
// dump(shares1[j], TOPRF_Share_BYTES, "shares1");
//printf("\n");
// each shareholder multiplies their k0,k1 shares
// and creates a sharing of this product
uint8_t mulshares[peers][peers][TOPRF_Share_BYTES];
for(unsigned i=0;i<peers;i++) {
if( toprf_mpc_mul_start(shares0[i], shares1[i], peers, threshold, mulshares[i])) return 1;
}
uint8_t indexes[peers];
for(unsigned i=0; i<peers; i++) indexes[i]=i+1;
uint8_t sharesP[peers][TOPRF_Share_BYTES];
//memset(sharesP,0,sizeof sharesP);
for(unsigned i=0;i<peers;i++) {
uint8_t shares[peers][TOPRF_Share_BYTES];
for(unsigned j=0; j<peers;j++) {
memcpy(shares[j], mulshares[j][i], TOPRF_Share_BYTES);
//dump(mulshares[j][i], TOPRF_Share_BYTES, "mulsharesx");
//dump(shares[i], TOPRF_Share_BYTES, "sharesx");
}
toprf_mpc_mul_finish(peers, indexes, i+1, shares, sharesP[i]);
}
// verify
uint8_t k0k1[crypto_core_ristretto255_SCALARBYTES];
crypto_core_ristretto255_scalar_mul(k0k1, k0, k1);
uint8_t r[crypto_core_ristretto255_SCALARBYTES];
crypto_core_ristretto255_scalar_random(r);
//debian_rng(r);
uint8_t gr[crypto_core_ristretto255_BYTES];
crypto_scalarmult_ristretto255_base(gr, r);
uint8_t verifier[crypto_core_ristretto255_BYTES];
if(crypto_scalarmult_ristretto255(verifier, k0k1, gr)) return 1;
uint8_t sharesP2[2][TOPRF_Share_BYTES];
if(crypto_scalarmult_ristretto255(sharesP2[0]+1, sharesP[0]+1, gr)) return 1;
sharesP2[0][0]=1;
if(crypto_scalarmult_ristretto255(sharesP2[1]+1, sharesP[2]+1, gr)) return 1;
sharesP2[1][0]=3;
uint8_t result[crypto_core_ristretto255_BYTES];
if(toprf_thresholdmult(2, sharesP2, result)) return 1;
if(memcmp(result,verifier,crypto_core_ristretto255_BYTES)!=0) {
printf("humiliating failure /o\\n");
return 1;
}
printf("great success!!5!\n");
return 0;
}
#endif // UNIT_TEST