#if 0 Shamir Sharing Warning!! We use the stock random number generator. You must replace it if you really want to keep a secret!! Consider the finite field GF(256). We want to produce k(<256) versions of a secret so that we may reconstruct the message when q (0 and libraries in some systems claiming to be ANSI C! #endif #define md 0 // md is a performance option. clang and x86 prefer 0 today for speed. // md=1 saves 64Kb of space. #define N 256 #include #include #include typedef unsigned int ui /* 32 bits */; typedef unsigned char uc; static ui const irp = 27; #if md typedef struct{ui q; ui r;} PR; ui pmul(ui a, ui b){ui sm=0; while(b) {if(b&1) sm ^= a; a = a<<1; b>>=1;} return sm;} static int High(ui x){int y=0; // position of most significant bit. {int k=4; while(k--) {int p = 1<>= p; y += p;}}} return y;} static PR pqr(ui n, ui d){if(!d) exit(printf("foss\n")); // synthetic division int hn = High(n), hd = High(d); ui a=0; int k = hn-hd; while(k>=0) {if(n&(1L<<(hn--))) {n ^= d<>31)&irp):(a&ts?irp:0)); b>>=1;} return sm&(N-1);} #if md static uc Mt(uc j, uc k){return 0? // 1 is performance option. 1 wins today. mt[(j&(256-16))|(k>>4)] ^ mt[256|(j&(256-16))|(k&15)] ^ mt[256|((j&15)<<4)|(k>>4)] ^ mt[512|((j&15)<<4)|(k&15)] : fmul(j, k);} void it(void){for(int j=0; j<16; ++j) for(int k=0; k<16; ++k) { mt[(j<<4)|k] = fmul(j<<4, k<<4); mt[256+((j<<4)|k)] = fmul(j<<4, k); mt[512+((j<<4)|k)] = fmul(j, k);} if(1) for(int j=0; j<16; ++j) for(int k=0; k<16; ++k) if (fmul(j, k<<4) ^ mt[256+((j<<4)|k)]) exit(printf("failA %d %d\n", j, k)); for(int j=0; j<256; ++j) dt[j] = finv(j); if(1) for(int j=1; j<256; ++j) if(Mt(j, dt[j]) ^ 1) exit(printf("failB %x\n", j)); if(1) for(int j=0; j<256; ++j) for(int k=0; k<256; ++k) if(fmul(j, k) ^ Mt(j, k)){ exit(printf("FailC %d %d\n", j, k));}} #else static uc Mt(uc j, uc k){return mt[j][k];} void it(void){for(int i=0; i dis || dis >= N) exit(printf("Quorum size (%d) must not exceed distribution (%d) and " "distribution must be less than %d\n", quor, dis, N)); uc a[4]; {int j=4; while(j--) {a[j] = sec&255; sec >>= 8;}} for(int k = 0; k<4; ++k) {uc coef[quor]; coef[0] = a[k]; for(int m = 1; m=0; --m) q = coef[m] ^ Mt(q, n); w[n-1][k] = q;}}} static void sj(int d, int Q, int q[Q]) {ui sec = 123456789; uc dx[d][4]; split(sec, Q, d, dx); printf("%d shares; quorum = {", d); for(int j=0; j int main(){it(); assert((char)-1 < 0); // lest fmul fail on machines with unsigned char's. if(0){uc z = 190; // peform for(int j=0; j<8; ++j) z = Mt(z, z); printf("z = %x\n", z); } else { // function {int q[] = {1}; sj(2, 1, q);} {int q[] = {2, 3}; sj(3, 2, q);} {int q[] = {8, 3, 5, 1}; sj(8, 4, q);} {int q[] = {7, 3, 4, 1}; sj(8, 4, q);} {int q[] = {8, 3, 5, 3}; sj(8, 4, q);} // fails for duplicate shares. {int q[] = {8, 3, 5, 1, 6}; sj(8, 5, q);} {int q[] = {8, 3, 5, 1}; sj(9, 4, q);}} return 0;}