You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.6 KiB

  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include "../xmss.h"
  6. #include "../params.h"
  7. #include "../randombytes.h"
  8. #define XMSS_MLEN 32
  9. #ifndef XMSS_SIGNATURES
  10. #define XMSS_SIGNATURES 16
  11. #endif
  12. #ifdef XMSSMT
  13. #define XMSS_PARSE_OID xmssmt_parse_oid
  14. #define XMSS_STR_TO_OID xmssmt_str_to_oid
  15. #define XMSS_KEYPAIR xmssmt_keypair
  16. #define XMSS_SIGN xmssmt_sign
  17. #define XMSS_SIGN_OPEN xmssmt_sign_open
  18. #define XMSS_VARIANT "XMSSMT-SHA2_20/2_256"
  19. #else
  20. #define XMSS_PARSE_OID xmss_parse_oid
  21. #define XMSS_STR_TO_OID xmss_str_to_oid
  22. #define XMSS_KEYPAIR xmss_keypair
  23. #define XMSS_SIGN xmss_sign
  24. #define XMSS_SIGN_OPEN xmss_sign_open
  25. #define XMSS_VARIANT "XMSS-SHA2_10_256"
  26. #endif
  27. int main()
  28. {
  29. xmss_params params;
  30. uint32_t oid;
  31. int i;
  32. // TODO test more different variants
  33. XMSS_STR_TO_OID(&oid, XMSS_VARIANT);
  34. XMSS_PARSE_OID(&params, oid);
  35. unsigned char pk[XMSS_OID_LEN + params.pk_bytes];
  36. unsigned char sk[XMSS_OID_LEN + params.sk_bytes];
  37. unsigned char *m = malloc(XMSS_MLEN);
  38. unsigned char *sm = malloc(params.sig_bytes + XMSS_MLEN);
  39. unsigned char *mout = malloc(params.sig_bytes + XMSS_MLEN);
  40. unsigned long long smlen;
  41. unsigned long long mlen;
  42. randombytes(m, XMSS_MLEN);
  43. XMSS_KEYPAIR(pk, sk, oid);
  44. printf("Testing %d %s signatures.. \n", XMSS_SIGNATURES, XMSS_VARIANT);
  45. for (i = 0; i < XMSS_SIGNATURES; i++) {
  46. printf(" - iteration #%d:\n", i);
  47. XMSS_SIGN(sk, sm, &smlen, m, XMSS_MLEN);
  48. if (smlen != params.sig_bytes + XMSS_MLEN) {
  49. printf(" X smlen incorrect [%llu != %u]!\n",
  50. smlen, params.sig_bytes);
  51. }
  52. else {
  53. printf(" smlen as expected [%llu].\n", smlen);
  54. }
  55. /* Test if signature is valid. */
  56. if (XMSS_SIGN_OPEN(mout, &mlen, sm, smlen, pk)) {
  57. printf(" X verification failed!\n");
  58. }
  59. else {
  60. printf(" verification succeeded.\n");
  61. }
  62. /* Test if the correct message was recovered. */
  63. if (mlen != XMSS_MLEN) {
  64. printf(" X mlen incorrect [%llu != %u]!\n", mlen, XMSS_MLEN);
  65. }
  66. else {
  67. printf(" mlen as expected [%llu].\n", mlen);
  68. }
  69. if (memcmp(m, mout, XMSS_MLEN)) {
  70. printf(" X output message incorrect!\n");
  71. }
  72. else {
  73. printf(" output message as expected.\n");
  74. }
  75. /* Test if flipping bits invalidates the signature (it should). */
  76. /* Flip the first bit of the message. Should invalidate. */
  77. sm[smlen - 1] ^= 1;
  78. if (!XMSS_SIGN_OPEN(mout, &mlen, sm, smlen, pk)) {
  79. printf(" X flipping a bit of m DID NOT invalidate signature!\n");
  80. }
  81. else {
  82. printf(" flipping a bit of m invalidates signature.\n");
  83. }
  84. sm[smlen - 1] ^= 1;
  85. #ifdef XMSS_TEST_INVALIDSIG
  86. int j;
  87. /* Flip one bit per hash; the signature is almost entirely hashes.
  88. This also flips a bit in the index, which is also a useful test. */
  89. for (j = 0; j < (int)(smlen - XMSS_MLEN); j += params.n) {
  90. sm[j] ^= 1;
  91. if (!XMSS_SIGN_OPEN(mout, &mlen, sm, smlen, pk)) {
  92. printf(" X flipping bit %d DID NOT invalidate sig + m!\n", j);
  93. sm[j] ^= 1;
  94. break;
  95. }
  96. sm[j] ^= 1;
  97. }
  98. if (j >= (int)(smlen - XMSS_MLEN)) {
  99. printf(" changing any signature hash invalidates signature.\n");
  100. }
  101. #endif
  102. }
  103. free(m);
  104. free(sm);
  105. free(mout);
  106. return 0;
  107. }