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.

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