Beispiel #1
0
void wots_sign(unsigned char sig[WOTS_L*HASH_BYTES], const unsigned char msg[HASH_BYTES], const unsigned char sk[SEED_BYTES], const unsigned char masks[(WOTS_W-1)*HASH_BYTES])
{
  int basew[WOTS_L],i,c=0;

#if WOTS_W != 16
#error "Implementation specialized for WOTS_W == 16"
#endif

  for(i=0;i<WOTS_L1;i+=2)
  {
    basew[i]   = msg[i/2] & 0xf;
    basew[i+1] = msg[i/2] >> 4;
    c += WOTS_W - 1 - basew[i];
    c += WOTS_W - 1 - basew[i+1];
  }

  for( ;i<WOTS_L;i++)
  {
    basew[i] = c & 0xf;
    c >>= 4;
  }
  
  expand_seed(sig, sk);
  /*
  for(i=0;i<WOTS_L;i++)
    gen_chain(sig+i*HASH_BYTES, sig+i*HASH_BYTES, masks, basew[i]);
  */
  gen_partialchains(sig,sig,masks,basew);
}
Beispiel #2
0
void wots_pkgen(unsigned char pk[WOTS_L*HASH_BYTES], const unsigned char sk[SEED_BYTES], const unsigned char masks[(WOTS_W-1)*HASH_BYTES])
{
  expand_seed(pk, sk);
  gen_fullchains(pk, masks);
}
Beispiel #3
0
int horst_sign(unsigned char *sig, unsigned char pk[HASH_BYTES], unsigned long long *sigbytes, 
               const unsigned char *m, unsigned long long mlen, 
               const unsigned char seed[SEED_BYTES], 
               const unsigned char masks[2*HORST_LOGT*HASH_BYTES], 
               const unsigned char m_hash[MSGHASH_BYTES])
{
  unsigned char sk[HORST_T*HORST_SKBYTES];
  unsigned int idx;
  int i,j,k;
  int sigpos = 0;

  unsigned char tree[(2*HORST_T-1)*HASH_BYTES]; /* replace by something more memory-efficient? */

  expand_seed(sk, seed);

  // Build the whole tree and save it
#if HORST_SKBYTES != HASH_BYTES
#error "Need to have HORST_SKBYTES == HASH_BYTES"
#endif

  // Generate pk leaves non parallel
  //for(i=0;i<HORST_T;i++)
  //  hash_n_n(tree+(HORST_T-1+i)*HASH_BYTES, sk+i*HORST_SKBYTES);

  // Generate pk leaves parallel
  for(i=0;i<HORST_T;i+=8)
    hash_n_n_8x(tree+(HORST_T-1+i)*HASH_BYTES, sk+i*HORST_SKBYTES);

  // Build tree
  // Hash from level 0 to 1
  loop_hash_2n_n_mask_8x(tree+(32767)*HASH_BYTES,tree+(65535)*HASH_BYTES,4096,masks);
  // Hash from level 1 to 2
  loop_hash_2n_n_mask_8x(tree+(16383)*HASH_BYTES,tree+(32767)*HASH_BYTES,2048,masks+2*HASH_BYTES);
  // Hash from level 2 to 3
  loop_hash_2n_n_mask_8x(tree+(8191)*HASH_BYTES,tree+(16383)*HASH_BYTES,1024,masks+4*HASH_BYTES);
  // Hash from level 3 to 4
  loop_hash_2n_n_mask_8x(tree+(4095)*HASH_BYTES,tree+(8191)*HASH_BYTES,512,masks+6*HASH_BYTES);
  // Hash from level 4 to 5
  loop_hash_2n_n_mask_8x(tree+(2047)*HASH_BYTES,tree+(4095)*HASH_BYTES,256,masks+8*HASH_BYTES);
  // Hash from level 5 to 6
  loop_hash_2n_n_mask_8x(tree+(1023)*HASH_BYTES,tree+(2047)*HASH_BYTES,128,masks+10*HASH_BYTES);
  // Hash from level 6 to 7
  loop_hash_2n_n_mask_8x(tree+(511)*HASH_BYTES,tree+(1023)*HASH_BYTES,64,masks+12*HASH_BYTES);
  // Hash from level 7 to 8
  loop_hash_2n_n_mask_8x(tree+(255)*HASH_BYTES,tree+(511)*HASH_BYTES,32,masks+14*HASH_BYTES);
  // Hash from level 8 to 9
  loop_hash_2n_n_mask_8x(tree+(127)*HASH_BYTES,tree+(255)*HASH_BYTES,16,masks+16*HASH_BYTES);
  // Hash from level 9 to 10
  loop_hash_2n_n_mask_8x(tree+(63)*HASH_BYTES,tree+(127)*HASH_BYTES,8,masks+18*HASH_BYTES);
  // Hash from level 10 to 11
  loop_hash_2n_n_mask_8x(tree+(31)*HASH_BYTES,tree+(63)*HASH_BYTES,4,masks+20*HASH_BYTES);
  // Hash from level 11 to 12
  loop_hash_2n_n_mask_8x(tree+(15)*HASH_BYTES,tree+(31)*HASH_BYTES,2,masks+22*HASH_BYTES);
  // Hash from level 12 to 13
  loop_hash_2n_n_mask_8x(tree+(7)*HASH_BYTES,tree+(15)*HASH_BYTES,1,masks+24*HASH_BYTES);
  // Hash from level 13 to 14
  for(j=0;j<4;j++)
    hash_2n_n_mask(tree+(3+j)*HASH_BYTES,tree+(7+2*j)*HASH_BYTES,masks+26*HASH_BYTES);
  // Hash from level 14 to 15
  for(j=0;j<2;j++)
      hash_2n_n_mask(tree+(1+j)*HASH_BYTES,tree+(3+2*j)*HASH_BYTES,masks+28*HASH_BYTES);
  // Hash from level 15 to 16
  hash_2n_n_mask(tree+0*HASH_BYTES,tree+1*HASH_BYTES,masks+30*HASH_BYTES);


#if HORST_K != (MSGHASH_BYTES/2)
#error "Need to have HORST_K == (MSGHASH_BYTES/2)"
#endif

  // First write 64 hashes from level 10 to the signature
  for(j=63*HASH_BYTES;j<127*HASH_BYTES;j++)
    sig[sigpos++] = tree[j];

  // Signature consists of HORST_K parts; each part of secret key and HORST_LOGT-4 auth-path hashes
  for(i=0;i<HORST_K;i++)
  {
    idx = m_hash[2*i] + (m_hash[2*i+1]<<8);

    for(k=0;k<HORST_SKBYTES;k++)
      sig[sigpos++] = sk[idx*HORST_SKBYTES+k];

    idx += (HORST_T-1);
    for(j=0;j<HORST_LOGT-6;j++)
    {
      idx = (idx&1)?idx+1:idx-1; // neighbor node
      for(k=0;k<HASH_BYTES;k++)
        sig[sigpos++] = tree[idx*HASH_BYTES+k];
      idx = (idx-1)/2; // parent node
    }
  }
 
  for(i=0;i<HASH_BYTES;i++)
    pk[i] = tree[i];
  
  *sigbytes = HORST_SIGBYTES;
  return 0;
}