sfinx

sphincs+ inspired signing utility
git clone git://git.finwo.net/app/sfinx
Log | Files | Refs | README

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