#include #include #include #include #include "../xmss.h" #include "../params.h" #include "../randombytes.h" #define XMSS_MLEN 32 #ifndef XMSS_SIGNATURES #define XMSS_SIGNATURES 16 #endif #ifdef XMSSMT #define XMSS_PARSE_OID xmssmt_parse_oid #define XMSS_STR_TO_OID xmssmt_str_to_oid #define XMSS_KEYPAIR xmssmt_keypair #define XMSS_SIGN xmssmt_sign #define XMSS_SIGN_OPEN xmssmt_sign_open #define XMSS_VARIANT "XMSSMT-SHA2_20/2_256" #else #define XMSS_PARSE_OID xmss_parse_oid #define XMSS_STR_TO_OID xmss_str_to_oid #define XMSS_KEYPAIR xmss_keypair #define XMSS_SIGN xmss_sign #define XMSS_SIGN_OPEN xmss_sign_open #define XMSS_VARIANT "XMSS-SHA2_10_256" #endif int main() { xmss_params params; uint32_t oid; int i; // TODO test more different variants XMSS_STR_TO_OID(&oid, XMSS_VARIANT); XMSS_PARSE_OID(¶ms, oid); unsigned char pk[XMSS_OID_LEN + params.pk_bytes]; unsigned char sk[XMSS_OID_LEN + params.sk_bytes]; unsigned char *m = malloc(XMSS_MLEN); unsigned char *sm = malloc(params.sig_bytes + XMSS_MLEN); unsigned char *mout = malloc(params.sig_bytes + XMSS_MLEN); unsigned long long smlen; unsigned long long mlen; randombytes(m, XMSS_MLEN); XMSS_KEYPAIR(pk, sk, oid); printf("Testing %d %s signatures.. \n", XMSS_SIGNATURES, XMSS_VARIANT); for (i = 0; i < XMSS_SIGNATURES; i++) { printf(" - iteration #%d:\n", i); XMSS_SIGN(sk, sm, &smlen, m, XMSS_MLEN); if (smlen != params.sig_bytes + XMSS_MLEN) { printf(" X smlen incorrect [%llu != %u]!\n", smlen, params.sig_bytes); } else { printf(" smlen as expected [%llu].\n", smlen); } /* Test if signature is valid. */ if (XMSS_SIGN_OPEN(mout, &mlen, sm, smlen, pk)) { printf(" X verification failed!\n"); } else { printf(" verification succeeded.\n"); } /* Test if the correct message was recovered. */ if (mlen != XMSS_MLEN) { printf(" X mlen incorrect [%llu != %u]!\n", mlen, XMSS_MLEN); } else { printf(" mlen as expected [%llu].\n", mlen); } if (memcmp(m, mout, XMSS_MLEN)) { printf(" X output message incorrect!\n"); } else { printf(" output message as expected.\n"); } /* Test if flipping bits invalidates the signature (it should). */ /* Flip the first bit of the message. Should invalidate. */ sm[smlen - 1] ^= 1; if (!XMSS_SIGN_OPEN(mout, &mlen, sm, smlen, pk)) { printf(" X flipping a bit of m DID NOT invalidate signature!\n"); } else { printf(" flipping a bit of m invalidates signature.\n"); } sm[smlen - 1] ^= 1; #ifdef XMSS_TEST_INVALIDSIG int j; /* Flip one bit per hash; the signature is almost entirely hashes. This also flips a bit in the index, which is also a useful test. */ for (j = 0; j < (int)(smlen - XMSS_MLEN); j += params.n) { sm[j] ^= 1; if (!XMSS_SIGN_OPEN(mout, &mlen, sm, smlen, pk)) { printf(" X flipping bit %d DID NOT invalidate sig + m!\n", j); sm[j] ^= 1; break; } sm[j] ^= 1; } if (j >= (int)(smlen - XMSS_MLEN)) { printf(" changing any signature hash invalidates signature.\n"); } #endif } free(m); free(sm); free(mout); return 0; }