您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

153 行
4.3 KiB

  1. #include <stdint.h>
  2. #include "xmss_commons.h"
  3. #include "hash.h"
  4. #include "wots.h"
  5. #include "hash_address.h"
  6. #include "params.h"
  7. /**
  8. * Helper method for pseudorandom key generation
  9. * Expands an n-byte array into a len*n byte array
  10. * this is done using PRF
  11. */
  12. static void expand_seed(const xmss_params *params,
  13. unsigned char *outseeds, const unsigned char *inseed)
  14. {
  15. uint32_t i;
  16. unsigned char ctr[32];
  17. for (i = 0; i < params->wots_len; i++) {
  18. to_byte(ctr, i, 32);
  19. prf(params, outseeds + i*params->n, ctr, inseed, params->n);
  20. }
  21. }
  22. /**
  23. * Computes the chaining function.
  24. * out and in have to be n-byte arrays
  25. *
  26. * interpretes in as start-th value of the chain
  27. * addr has to contain the address of the chain
  28. */
  29. static void gen_chain(const xmss_params *params,
  30. unsigned char *out, const unsigned char *in,
  31. unsigned int start, unsigned int steps,
  32. const unsigned char *pub_seed, uint32_t addr[8])
  33. {
  34. uint32_t i;
  35. for (i = 0; i < params->n; i++) {
  36. out[i] = in[i];
  37. }
  38. for (i = start; i < (start+steps) && i < params->wots_w; i++) {
  39. set_hash_addr(addr, i);
  40. hash_f(params, out, out, pub_seed, addr);
  41. }
  42. }
  43. /**
  44. * base_w algorithm as described in draft.
  45. */
  46. static void base_w(const xmss_params *params,
  47. int *output, const int out_len, const unsigned char *input)
  48. {
  49. int in = 0;
  50. int out = 0;
  51. uint8_t total = 0;
  52. int bits = 0;
  53. int i;
  54. for (i = 0; i < out_len; i++) {
  55. if (bits == 0) {
  56. total = input[in];
  57. in++;
  58. bits += 8;
  59. }
  60. bits -= params->wots_log_w;
  61. output[out] = (total >> bits) & (params->wots_w - 1);
  62. out++;
  63. }
  64. }
  65. void wots_pkgen(const xmss_params *params,
  66. unsigned char *pk, const unsigned char *sk,
  67. const unsigned char *pub_seed, uint32_t addr[8])
  68. {
  69. uint32_t i;
  70. expand_seed(params, pk, sk);
  71. for (i = 0; i < params->wots_len; i++) {
  72. set_chain_addr(addr, i);
  73. gen_chain(params, pk + i*params->n, pk + i*params->n,
  74. 0, params->wots_w-1, pub_seed, addr);
  75. }
  76. }
  77. void wots_sign(const xmss_params *params,
  78. unsigned char *sig, const unsigned char *msg,
  79. const unsigned char *sk, const unsigned char *pub_seed,
  80. uint32_t addr[8])
  81. {
  82. int basew[params->wots_len];
  83. int csum = 0;
  84. unsigned char csum_bytes[((params->wots_len2 * params->wots_log_w) + 7) / 8];
  85. int csum_basew[params->wots_len2];
  86. uint32_t i;
  87. base_w(params, basew, params->wots_len1, msg);
  88. for (i = 0; i < params->wots_len1; i++) {
  89. csum += params->wots_w - 1 - basew[i];
  90. }
  91. csum = csum << (8 - ((params->wots_len2 * params->wots_log_w) % 8));
  92. to_byte(csum_bytes, csum, ((params->wots_len2 * params->wots_log_w) + 7) / 8);
  93. base_w(params, csum_basew, params->wots_len2, csum_bytes);
  94. for (i = 0; i < params->wots_len2; i++) {
  95. basew[params->wots_len1 + i] = csum_basew[i];
  96. }
  97. expand_seed(params, sig, sk);
  98. for (i = 0; i < params->wots_len; i++) {
  99. set_chain_addr(addr, i);
  100. gen_chain(params, sig + i*params->n, sig + i*params->n,
  101. 0, basew[i], pub_seed, addr);
  102. }
  103. }
  104. void wots_pk_from_sig(const xmss_params *params, unsigned char *pk,
  105. const unsigned char *sig, const unsigned char *msg,
  106. const unsigned char *pub_seed, uint32_t addr[8])
  107. {
  108. int basew[params->wots_len];
  109. int csum = 0;
  110. unsigned char csum_bytes[((params->wots_len2 * params->wots_log_w) + 7) / 8];
  111. int csum_basew[params->wots_len2];
  112. uint32_t i = 0;
  113. base_w(params, basew, params->wots_len1, msg);
  114. for (i=0; i < params->wots_len1; i++) {
  115. csum += params->wots_w - 1 - basew[i];
  116. }
  117. csum = csum << (8 - ((params->wots_len2 * params->wots_log_w) % 8));
  118. to_byte(csum_bytes, csum, ((params->wots_len2 * params->wots_log_w) + 7) / 8);
  119. base_w(params, csum_basew, params->wots_len2, csum_bytes);
  120. for (i = 0; i < params->wots_len2; i++) {
  121. basew[params->wots_len1 + i] = csum_basew[i];
  122. }
  123. for (i=0; i < params->wots_len; i++) {
  124. set_chain_addr(addr, i);
  125. gen_chain(params, pk + i*params->n, sig + i*params->n,
  126. basew[i], params->wots_w-1-basew[i], pub_seed, addr);
  127. }
  128. }