Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

320 řádky
10 KiB

  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <stdint.h>
  4. #include "hash.h"
  5. #include "hash_address.h"
  6. #include "params.h"
  7. #include "wots.h"
  8. #include "xmss_commons.h"
  9. /**
  10. * Converts the value of 'in' to 'outlen' bytes in big-endian byte order.
  11. */
  12. void ull_to_bytes(unsigned char *out, unsigned long long outlen,
  13. unsigned long long in)
  14. {
  15. int i;
  16. /* Iterate over out in decreasing order, for big-endianness. */
  17. for (i = outlen - 1; i >= 0; i--) {
  18. out[i] = in & 0xff;
  19. in = in >> 8;
  20. }
  21. }
  22. /**
  23. * Computes the leaf at a given address. First generates the WOTS key pair,
  24. * then computes leaf using l_tree. As this happens position independent, we
  25. * only require that addr encodes the right ltree-address.
  26. */
  27. void gen_leaf_wots(const xmss_params *params, unsigned char *leaf,
  28. const unsigned char *sk_seed, const unsigned char *pub_seed,
  29. uint32_t ltree_addr[8], uint32_t ots_addr[8])
  30. {
  31. unsigned char seed[params->n];
  32. unsigned char pk[params->wots_keysize];
  33. get_seed(params, seed, sk_seed, ots_addr);
  34. wots_pkgen(params, pk, seed, pub_seed, ots_addr);
  35. l_tree(params, leaf, pk, pub_seed, ltree_addr);
  36. }
  37. /**
  38. * Used for pseudo-random key generation.
  39. * Generates the seed for the WOTS key pair at address 'addr'.
  40. *
  41. * Takes n-byte sk_seed and returns n-byte seed using 32 byte address 'addr'.
  42. */
  43. void get_seed(const xmss_params *params, unsigned char *seed,
  44. const unsigned char *sk_seed, uint32_t addr[8])
  45. {
  46. unsigned char bytes[32];
  47. /* Make sure that chain addr, hash addr, and key bit are zeroed. */
  48. set_chain_addr(addr, 0);
  49. set_hash_addr(addr, 0);
  50. set_key_and_mask(addr, 0);
  51. /* Generate seed. */
  52. addr_to_bytes(bytes, addr);
  53. prf(params, seed, bytes, sk_seed, params->n);
  54. }
  55. /**
  56. * Computes a leaf node from a WOTS public key using an L-tree.
  57. * Note that this destroys the used WOTS public key.
  58. */
  59. void l_tree(const xmss_params *params,
  60. unsigned char *leaf, unsigned char *wots_pk,
  61. const unsigned char *pub_seed, uint32_t addr[8])
  62. {
  63. unsigned int l = params->wots_len;
  64. unsigned int parent_nodes;
  65. uint32_t i;
  66. uint32_t height = 0;
  67. set_tree_height(addr, height);
  68. while (l > 1) {
  69. parent_nodes = l >> 1;
  70. for (i = 0; i < parent_nodes; i++) {
  71. set_tree_index(addr, i);
  72. /* Hashes the nodes at (i*2)*params->n and (i*2)*params->n + 1 */
  73. hash_h(params, wots_pk + i*params->n, wots_pk + (i*2)*params->n, pub_seed, addr);
  74. }
  75. /* If the row contained an odd number of nodes, the last node was not hashed.
  76. Instead, we pull it up to the next layer. */
  77. if (l & 1) {
  78. memcpy(wots_pk + (l >> 1)*params->n, wots_pk + (l - 1)*params->n, params->n);
  79. l = (l >> 1) + 1;
  80. }
  81. else {
  82. l = l >> 1;
  83. }
  84. height++;
  85. set_tree_height(addr, height);
  86. }
  87. memcpy(leaf, wots_pk, params->n);
  88. }
  89. /**
  90. * Computes a root node given a leaf and an auth path
  91. */
  92. static void validate_authpath(const xmss_params *params, unsigned char *root,
  93. const unsigned char *leaf, unsigned long leafidx,
  94. const unsigned char *authpath,
  95. const unsigned char *pub_seed, uint32_t addr[8])
  96. {
  97. uint32_t i, j;
  98. unsigned char buffer[2*params->n];
  99. /* If leafidx is odd (last bit = 1), current path element is a right child
  100. and authpath has to go left. Otherwise it is the other way around. */
  101. if (leafidx & 1) {
  102. for (j = 0; j < params->n; j++) {
  103. buffer[params->n + j] = leaf[j];
  104. buffer[j] = authpath[j];
  105. }
  106. }
  107. else {
  108. for (j = 0; j < params->n; j++) {
  109. buffer[j] = leaf[j];
  110. buffer[params->n + j] = authpath[j];
  111. }
  112. }
  113. authpath += params->n;
  114. for (i = 0; i < params->tree_height-1; i++) {
  115. set_tree_height(addr, i);
  116. leafidx >>= 1;
  117. set_tree_index(addr, leafidx);
  118. /* Pick the right or left neighbor, depending on parity of the node. */
  119. if (leafidx & 1) {
  120. hash_h(params, buffer + params->n, buffer, pub_seed, addr);
  121. for (j = 0; j < params->n; j++) {
  122. buffer[j] = authpath[j];
  123. }
  124. }
  125. else {
  126. hash_h(params, buffer, buffer, pub_seed, addr);
  127. for (j = 0; j < params->n; j++) {
  128. buffer[j + params->n] = authpath[j];
  129. }
  130. }
  131. authpath += params->n;
  132. }
  133. set_tree_height(addr, params->tree_height - 1);
  134. leafidx >>= 1;
  135. set_tree_index(addr, leafidx);
  136. hash_h(params, root, buffer, pub_seed, addr);
  137. }
  138. /**
  139. * Verifies a given message signature pair under a given public key.
  140. * Note that this assumes a pk without an OID, i.e. [root || PUB_SEED]
  141. */
  142. int xmss_core_sign_open(const xmss_params *params,
  143. unsigned char *m, unsigned long long *mlen,
  144. const unsigned char *sm, unsigned long long smlen,
  145. const unsigned char *pk)
  146. {
  147. unsigned long long i;
  148. unsigned long idx = 0;
  149. unsigned char wots_pk[params->wots_keysize];
  150. unsigned char pkhash[params->n];
  151. unsigned char root[params->n];
  152. unsigned char msg_h[params->n];
  153. unsigned char hash_key[3*params->n];
  154. unsigned char pub_seed[params->n];
  155. memcpy(pub_seed, pk + params->n, params->n);
  156. uint32_t ots_addr[8] = {0};
  157. uint32_t ltree_addr[8] = {0};
  158. uint32_t node_addr[8] = {0};
  159. set_type(ots_addr, 0);
  160. set_type(ltree_addr, 1);
  161. set_type(node_addr, 2);
  162. *mlen = smlen - params->bytes;
  163. /* Convert the index bytes from the signature to an integer. */
  164. for (i = 0; i < params->index_len; i++) {
  165. idx |= ((unsigned long long)sm[i]) << (8*(params->index_len - 1 - i));
  166. }
  167. /* Prepare the hash key, of the form [R || root || idx]. */
  168. memcpy(hash_key, sm + params->index_len, params->n);
  169. memcpy(hash_key + params->n, pk, params->n);
  170. ull_to_bytes(hash_key + 2*params->n, params->n, idx);
  171. /* Compute the message hash. */
  172. h_msg(params, msg_h, sm + params->bytes, *mlen, hash_key, 3*params->n);
  173. sm += params->index_len + params->n;
  174. /* The WOTS public key is only correct if the signature was correct. */
  175. set_ots_addr(ots_addr, idx);
  176. wots_pk_from_sig(params, wots_pk, sm, msg_h, pub_seed, ots_addr);
  177. sm += params->wots_keysize;
  178. /* Compute the leaf node using the WOTS public key. */
  179. set_ltree_addr(ltree_addr, idx);
  180. l_tree(params, pkhash, wots_pk, pub_seed, ltree_addr);
  181. /* Compute the root node. */
  182. validate_authpath(params, root, pkhash, idx, sm, pub_seed, node_addr);
  183. sm += params->tree_height*params->n;
  184. /* Check if the root node equals the root node in the public key. */
  185. for (i = 0; i < params->n; i++) {
  186. if (root[i] != pk[i]) {
  187. for (i = 0; i < *mlen; i++) {
  188. m[i] = 0;
  189. }
  190. *mlen = -1;
  191. return -1;
  192. }
  193. }
  194. /* If verification was successful, copy the message from the signature. */
  195. for (i = 0; i < *mlen; i++) {
  196. m[i] = sm[i];
  197. }
  198. return 0;
  199. }
  200. /**
  201. * Verifies a given message signature pair under a given public key.
  202. * Note that this assumes a pk without an OID, i.e. [root || PUB_SEED]
  203. */
  204. int xmssmt_core_sign_open(const xmss_params *params,
  205. unsigned char *m, unsigned long long *mlen,
  206. const unsigned char *sm, unsigned long long smlen,
  207. const unsigned char *pk)
  208. {
  209. uint32_t idx_leaf;
  210. unsigned long long i;
  211. unsigned long long idx = 0;
  212. unsigned char wots_pk[params->wots_keysize];
  213. unsigned char pkhash[params->n];
  214. unsigned char root[params->n];
  215. unsigned char *msg_h = root;
  216. unsigned char hash_key[3*params->n];
  217. const unsigned char *pub_seed = pk + params->n;
  218. uint32_t ots_addr[8] = {0};
  219. uint32_t ltree_addr[8] = {0};
  220. uint32_t node_addr[8] = {0};
  221. set_type(ots_addr, 0);
  222. set_type(ltree_addr, 1);
  223. set_type(node_addr, 2);
  224. *mlen = smlen - params->bytes;
  225. /* Convert the index bytes from the signature to an integer. */
  226. for (i = 0; i < params->index_len; i++) {
  227. idx |= ((unsigned long long)sm[i]) << (8*(params->index_len - 1 - i));
  228. }
  229. /* Prepare the hash key, of the form [R || root || idx]. */
  230. memcpy(hash_key, sm + params->index_len, params->n);
  231. memcpy(hash_key + params->n, pk, params->n);
  232. ull_to_bytes(hash_key + 2*params->n, params->n, idx);
  233. /* Compute the message hash. */
  234. h_msg(params, msg_h, sm + params->bytes, *mlen, hash_key, 3*params->n);
  235. sm += params->index_len + params->n;
  236. /* For each subtree.. */
  237. for (i = 0; i < params->d; i++) {
  238. idx_leaf = (idx & ((1 << params->tree_height)-1));
  239. idx = idx >> params->tree_height;
  240. set_layer_addr(ots_addr, i);
  241. set_layer_addr(ltree_addr, i);
  242. set_layer_addr(node_addr, i);
  243. set_tree_addr(ltree_addr, idx);
  244. set_tree_addr(ots_addr, idx);
  245. set_tree_addr(node_addr, idx);
  246. /* The WOTS public key is only correct if the signature was correct. */
  247. set_ots_addr(ots_addr, idx_leaf);
  248. /* Initially, root = msg_h, but on subsequent iterations it is the root
  249. of the subtree below the currently processed subtree. */
  250. wots_pk_from_sig(params, wots_pk, sm, root, pub_seed, ots_addr);
  251. sm += params->wots_keysize;
  252. /* Compute the leaf node using the WOTS public key. */
  253. set_ltree_addr(ltree_addr, idx_leaf);
  254. l_tree(params, pkhash, wots_pk, pub_seed, ltree_addr);
  255. /* Compute the root node of this subtree. */
  256. validate_authpath(params, root, pkhash, idx_leaf, sm, pub_seed, node_addr);
  257. sm += params->tree_height*params->n;
  258. }
  259. /* Check if the final root node equals the root node in the public key. */
  260. for (i = 0; i < params->n; i++) {
  261. if (root[i] != pk[i]) {
  262. for (i = 0; i < *mlen; i++) {
  263. m[i] = 0;
  264. }
  265. *mlen = -1;
  266. return -1;
  267. }
  268. }
  269. /* If verification was successful, copy the message from the signature. */
  270. for (i = 0; i < *mlen; i++) {
  271. m[i] = sm[i];
  272. }
  273. return 0;
  274. }