README.md (2119B)
1 sphincs+ inspired data signing library 2 3 Rough idea: 4 5 4 bits of the original hash per tree layer 6 original hash = tree path 7 8 pre-image input = <N-seed><layer><masked-org-hash> 9 pre-image source = shake256, get 32*32=1024 bytes 10 11 each layer = cat( h(pre-image[i], current[i]) ) 12 pubkey of leaf = h(cat(h(pre-image[i], 256))) 13 14 next layer = sign(cat(pubkeys of all leafs)) // 16 leafs per layer -- 4 bits 15 16 Pseudocode: 17 18 ```c 19 20 char *seed = "supersecret"; 21 char *org = h(message); 22 char *current = org; 23 24 char ** pre_img( char *seed, int mask, char *org_hash ) { 25 char * pre_input = concat( seed, mask/4, cidr(org_hash, mask) ); 26 char * pre_source = shake_init(pre_input); 27 28 char *output[32]; 29 for(int i=0; i<32; i++) { 30 output[i] = hash(pre_source.shake(32)); 31 } 32 33 return output; 34 } 35 36 char ** sign( char **pre_image, char *current_hash ) { 37 char *output[32]; 38 for(int n=0; n<32; n++) { 39 output[i] = hash(pre_image[i], current_hash[i]); 40 } 41 return output; 42 } 43 44 char * pubkey_for( char **pre_image ) { 45 char *output[32] = calloc(1, 32*32); 46 memcpy(output, pre_image, 32*32); 47 for(int n=0; n<32; n++) { 48 for(int i=0; i<256; i++) { 49 output[n] = hash(output[n]); 50 } 51 } 52 return hash(concat(output)); 53 } 54 55 // The full signing cycle 56 char *org = hash(message); 57 char *current = org; 58 char *msg; 59 60 for ( int mask=256; mask>=0; mask-=4 ) { 61 62 // Provide pre-image proof of current leaf 63 char **pre = pre_img( seed, mask, org ); 64 char **proof = sign(pre, current); 65 append_preimage(out, proof); 66 67 // Provide neighbours if not root 68 if ( mask > 0 ) { 69 int self = bitbuffer_get_i4(current, mask-4); 70 char *base = cidr(current, mask-4); 71 72 msg = ""; 73 74 for(int i=0 ; i<16; i++) { 75 bitbuffer_put_i4( org, mask-4, i); 76 char *pub_neighbour = pubkey_for(pre_img( seed, mask, org )) 77 append_pubkey(msg, pub_neighbour); 78 if (i == self) continue; 79 append_pubkey(out, pub_neighbour); 80 } 81 82 current = hash(msg); 83 } 84 85 } 86 ``` 87