### Complete SPHINCS+ Sign and Verify Example in C Source: https://context7.com/sphincs/sphincsplus/llms.txt This C code demonstrates the full signing and verification process using SPHINCS+. It includes key generation, message signing, signature verification, and checks for message integrity. It also includes a test for tampering detection. ```c #include #include #include #include "api.h" #include "params.h" #include "randombytes.h" #define MESSAGE_LEN 1024 int main(void) { int ret = 0; /* Allocate key buffers */ unsigned char pk[SPX_PK_BYTES]; unsigned char sk[SPX_SK_BYTES]; /* Allocate message buffers */ unsigned char *message = malloc(MESSAGE_LEN); unsigned char *sm = malloc(SPX_BYTES + MESSAGE_LEN); unsigned char *mout = malloc(SPX_BYTES + MESSAGE_LEN); unsigned long long smlen, mlen; if (!message || !sm || !mout) { printf("Memory allocation failed!\n"); ret = -1; goto cleanup; } /* Generate random message */ randombytes(message, MESSAGE_LEN); printf("Generated %d byte random message.\n", MESSAGE_LEN); /* Step 1: Generate key pair */ printf("Generating SPHINCS+ key pair...\n"); if (crypto_sign_keypair(pk, sk) != 0) { printf("ERROR: Key generation failed!\n"); ret = -1; goto cleanup; } printf(" Public key: %d bytes\n", SPX_PK_BYTES); printf(" Secret key: %d bytes\n", SPX_SK_BYTES); /* Step 2: Sign the message */ printf("Signing message...\n"); if (crypto_sign(sm, &smlen, message, MESSAGE_LEN, sk) != 0) { printf("ERROR: Signing failed!\n"); ret = -1; goto cleanup; } printf(" Signature: %d bytes\n", SPX_BYTES); printf(" Total output: %llu bytes (sig + msg)\n", smlen); /* Step 3: Verify signature and extract message */ printf("Verifying signature...\n"); if (crypto_sign_open(mout, &mlen, sm, smlen, pk) != 0) { printf("ERROR: Verification failed!\n"); ret = -1; goto cleanup; } /* Step 4: Confirm extracted message matches original */ if (mlen != MESSAGE_LEN || memcmp(message, mout, MESSAGE_LEN) != 0) { printf("ERROR: Message mismatch!\n"); ret = -1; goto cleanup; } printf("SUCCESS: Signature verified, message recovered correctly.\n"); /* Test tampering detection */ printf("\nTesting tampering detection...\n"); sm[SPX_BYTES / 2] ^= 0xFF; /* Corrupt middle of signature */ if (crypto_sign_open(mout, &mlen, sm, smlen, pk) == 0) { printf("ERROR: Tampered signature was incorrectly accepted!\n"); ret = -1; } else { printf("SUCCESS: Tampered signature correctly rejected.\n"); } cleanup: free(message); free(sm); free(mout); return ret; } ``` -------------------------------- ### Build Reference Implementation with Haraka Source: https://context7.com/sphincs/sphincsplus/llms.txt Compile the reference implementation with Haraka, 192-bit security, and the fast signing variant. Ensure you are in the 'ref' directory and run 'make clean' before building. ```bash make clean make PARAMS=sphincs-haraka-192f test/spx ./test/spx ``` -------------------------------- ### Run Benchmark for Reference Implementation Source: https://context7.com/sphincs/sphincsplus/llms.txt Build and execute the benchmark for the reference implementation using the SHA-256, 128-bit security, fast variant. This measures key generation, signing, and verification performance. ```bash cd ref make PARAMS=sphincs-sha2-128f test/benchmark ./test/benchmark ``` -------------------------------- ### Build Reference Implementation with SHA-256 Source: https://context7.com/sphincs/sphincsplus/llms.txt Compile the reference implementation with SHA-256, 128-bit security, and the fast signing variant. Ensure you are in the 'ref' directory and run 'make clean' before building. ```bash cd ref make clean make PARAMS=sphincs-sha2-128f test/spx ./test/spx ``` -------------------------------- ### Build Reference Implementation with SHAKE256 Source: https://context7.com/sphincs/sphincsplus/llms.txt Compile the reference implementation with SHAKE256, 256-bit security, and small signatures. Ensure you are in the 'ref' directory and run 'make clean' before building. ```bash make clean make PARAMS=sphincs-shake-256s test/spx ./test/spx ``` -------------------------------- ### Run Benchmark for AVX2-Optimized Implementation Source: https://context7.com/sphincs/sphincsplus/llms.txt Build and execute the benchmark for the AVX2-optimized SHA-256 implementation with the fast signing variant. This measures key generation, signing, and verification performance. ```bash cd ../sha2-avx2 make PARAMS=sphincs-sha2-256f test/benchmark ./test/benchmark ``` -------------------------------- ### Build Haraka with AES-NI Acceleration Source: https://context7.com/sphincs/sphincsplus/llms.txt Compile the Haraka implementation with AES-NI acceleration, using the 256-bit security small signatures variant. Navigate to the 'haraka-aesni' directory and run 'make clean' before building. ```bash cd ../haraka-aesni make clean make PARAMS=sphincs-haraka-256s test/spx ./test/spx ``` -------------------------------- ### Build Optimized AVX2 SHA-256 Implementation Source: https://context7.com/sphincs/sphincsplus/llms.txt Compile the optimized AVX2 SHA-256 implementation with the fast signing variant. Navigate to the 'sha2-avx2' directory and run 'make clean' before building. ```bash cd ../sha2-avx2 make clean make PARAMS=sphincs-sha2-256f test/spx ./test/spx ``` -------------------------------- ### Build Optimized AVX2 SHAKE Implementation Source: https://context7.com/sphincs/sphincsplus/llms.txt Compile the optimized AVX2 SHAKE implementation with the 128-bit security fast signing variant. Navigate to the 'shake-avx2' directory and run 'make clean' before building. ```bash cd ../shake-avx2 make clean make PARAMS=sphincs-shake-128f test/spx ./test/spx ``` -------------------------------- ### Generate Known Answer Tests (KAT) for Reference Implementation Source: https://context7.com/sphincs/sphincsplus/llms.txt Build the KAT generator for the reference implementation with SHA-256, 128-bit security, fast variant. This requires OpenSSL for a deterministic random number generator and produces test vector files. ```bash cd ref make PARAMS=sphincs-sha2-128f PQCgenKAT_sign ./PQCgenKAT_sign ``` -------------------------------- ### Sign Message (Combined Signature + Message) Source: https://context7.com/sphincs/sphincsplus/llms.txt Creates a signature for a message and combines it with the original message into a single output buffer. The output format is signature followed by the message. Requires allocating sufficient buffer space for both. ```c #include #include #include #include "api.h" #include "params.h" #include "randombytes.h" int main(void) { unsigned char pk[SPX_PK_BYTES]; unsigned char sk[SPX_SK_BYTES]; /* Message to sign */ unsigned char message[] = "Hello, post-quantum world!"; unsigned long long mlen = sizeof(message) - 1; /* Allocate buffer for signature + message */ unsigned char *sm = malloc(SPX_BYTES + mlen); unsigned long long smlen; /* Generate keys */ crypto_sign_keypair(pk, sk); /* Sign the message - output is signature || message */ if (crypto_sign(sm, &smlen, message, mlen, sk) != 0) { printf("Signing failed!\n"); free(sm); return -1; } printf("Message signed successfully.\n"); printf("Original message length: %llu bytes\n", mlen); printf("Signed message length: %llu bytes\n", smlen); printf("Signature size: %d bytes (%.2f KiB)\n", SPX_BYTES, SPX_BYTES / 1024.0); /* Output (for sphincs-sha2-128f): * Message signed successfully. * Original message length: 26 bytes * Signed message length: 17114 bytes * Signature size: 17088 bytes (16.69 KiB) */ free(sm); return 0; } ``` -------------------------------- ### Verify SHA256 Checksums for KAT Files Source: https://context7.com/sphincs/sphincsplus/llms.txt Verify the SHA256 checksums of the generated KAT files against known good values. This command should be run from the directory containing the SHA256SUMS file. ```bash cd .. sha256sum -c SHA256SUMS ``` -------------------------------- ### Deterministic Key Generation from Seed Source: https://context7.com/sphincs/sphincsplus/llms.txt Generates a SPHINCS+ key pair deterministically from a provided seed. The seed must be 3*SPX_N bytes long. This ensures reproducible key generation. ```c #include #include "api.h" #include "params.h" int main(void) { unsigned char pk[SPX_PK_BYTES]; unsigned char sk[SPX_SK_BYTES]; unsigned char seed[CRYPTO_SEEDBYTES]; /* 3 * SPX_N bytes */ /* Initialize seed with deterministic values (in practice, use secure random) */ memset(seed, 0x42, CRYPTO_SEEDBYTES); /* Generate key pair from seed - same seed always produces same keys */ if (crypto_sign_seed_keypair(pk, sk, seed) != 0) { return -1; } printf("Deterministic key pair generated from seed.\n"); printf("Seed size: %llu bytes\n", crypto_sign_seedbytes()); /* Output: * Deterministic key pair generated from seed. * Seed size: 48 bytes (for 128-bit security) */ return 0; } ``` -------------------------------- ### Query SPHINCS+ Parameter Sizes Source: https://context7.com/sphincs/sphincsplus/llms.txt Retrieves the byte sizes for SPHINCS+ cryptographic parameters like secret key, public key, and signature at runtime. This is essential for correct buffer allocation. ```c #include #include "api.h" int main(void) { printf("SPHINCS+ Parameter Sizes:\n"); printf("========================\n"); printf("Secret key: %llu bytes\n", crypto_sign_secretkeybytes()); printf("Public key: %llu bytes\n", crypto_sign_publickeybytes()); printf("Signature: %llu bytes\n", crypto_sign_bytes()); printf("Seed: %llu bytes\n", crypto_sign_seedbytes()); /* Output (for sphincs-sha2-128f): * SPHINCS+ Parameter Sizes: * ======================== * Secret key: 64 bytes * Public key: 32 bytes * Signature: 17088 bytes * Seed: 48 bytes * * Output (for sphincs-sha2-256s): * Secret key: 128 bytes * Public key: 64 bytes * Signature: 29792 bytes * Seed: 96 bytes */ return 0; } ``` -------------------------------- ### Generate SPHINCS+ Key Pair Source: https://context7.com/sphincs/sphincsplus/llms.txt Generates a random SPHINCS+ public and secret key pair. The secret key includes SK_SEED, SK_PRF, PUB_SEED, and root, while the public key contains PUB_SEED and root. ```c #include #include #include "api.h" #include "params.h" #include "randombytes.h" int main(void) { unsigned char pk[SPX_PK_BYTES]; /* Public key buffer */ unsigned char sk[SPX_SK_BYTES]; /* Secret key buffer */ /* Generate a random SPHINCS+ key pair */ if (crypto_sign_keypair(pk, sk) != 0) { printf("Key generation failed!\n"); return -1; } printf("Key pair generated successfully.\n"); printf("Public key size: %d bytes\n", SPX_PK_BYTES); printf("Secret key size: %d bytes\n", SPX_SK_BYTES); /* Output: * Key pair generated successfully. * Public key size: 32 bytes (for 128-bit security) * Secret key size: 64 bytes (for 128-bit security) */ return 0; } ``` -------------------------------- ### Create Detached SPHINCS+ Signature Source: https://context7.com/sphincs/sphincsplus/llms.txt Generates a detached signature for a given message using a private key. The signature can be stored or transmitted separately from the message. Ensure necessary headers are included. ```c #include #include #include "api.h" #include "params.h" #include "randombytes.h" int main(void) { unsigned char pk[SPX_PK_BYTES]; unsigned char sk[SPX_SK_BYTES]; unsigned char sig[SPX_BYTES]; /* Detached signature buffer */ size_t siglen; /* Message to sign */ unsigned char message[] = "Sign this document"; size_t mlen = sizeof(message) - 1; /* Generate keys */ crypto_sign_keypair(pk, sk); /* Create detached signature */ if (crypto_sign_signature(sig, &siglen, message, mlen, sk) != 0) { printf("Signature generation failed!\n"); return -1; } printf("Detached signature created.\n"); printf("Signature length: %zu bytes\n", siglen); printf("Message and signature can be transmitted separately.\n"); /* Output: * Detached signature created. * Signature length: 17088 bytes (for sphincs-sha2-128f) * Message and signature can be transmitted separately. */ return 0; } ``` -------------------------------- ### Verify and Extract Message from Combined SPHINCS+ Signature Source: https://context7.com/sphincs/sphincsplus/llms.txt Verifies a combined signature-message buffer and extracts the original message. This is useful when the signature and message are transmitted together. It also includes a test for invalid signatures. ```c #include #include #include #include "api.h" #include "params.h" #include "randombytes.h" int main(void) { unsigned char pk[SPX_PK_BYTES]; unsigned char sk[SPX_SK_BYTES]; unsigned char message[] = "Important document content"; unsigned long long mlen = sizeof(message) - 1; unsigned char *sm = malloc(SPX_BYTES + mlen); unsigned char *mout = malloc(SPX_BYTES + mlen); /* Buffer for extracted message */ unsigned long long smlen, moutlen; /* Generate keys and sign */ crypto_sign_keypair(pk, sk); crypto_sign(sm, &smlen, message, mlen, sk); /* Verify and extract message */ if (crypto_sign_open(mout, &moutlen, sm, smlen, pk) != 0) { printf("Verification failed!\n"); free(sm); free(mout); return -1; } printf("Signature verified and message extracted.\n"); printf("Extracted message length: %llu bytes\n", moutlen); printf("Message matches original: %s\n", (memcmp(message, mout, mlen) == 0) ? "YES" : "NO"); /* Test invalid signature */ sm[0] ^= 1; /* Flip one bit in signature */ if (crypto_sign_open(mout, &moutlen, sm, smlen, pk) != 0) { printf("Invalid signature correctly rejected.\n"); } /* Output: * Signature verified and message extracted. * Extracted message length: 26 bytes * Message matches original: YES * Invalid signature correctly rejected. */ free(sm); free(mout); return 0; } ``` -------------------------------- ### Verify Detached SPHINCS+ Signature Source: https://context7.com/sphincs/sphincsplus/llms.txt Verifies a detached signature against a message using a public key. This function checks the integrity of the signature and the message. It also demonstrates rejection of tampered messages. ```c #include #include "api.h" #include "params.h" #include "randombytes.h" int main(void) { unsigned char pk[SPX_PK_BYTES]; unsigned char sk[SPX_SK_BYTES]; unsigned char sig[SPX_BYTES]; size_t siglen; unsigned char message[] = "Verify this message"; size_t mlen = sizeof(message) - 1; /* Generate keys and sign */ crypto_sign_keypair(pk, sk); crypto_sign_signature(sig, &siglen, message, mlen, sk); /* Verify the detached signature */ if (crypto_sign_verify(sig, siglen, message, mlen, pk) != 0) { printf("Signature verification FAILED!\n"); return -1; } printf("Signature verified successfully.\n"); /* Test with tampered message */ unsigned char tampered[] = "Verify this messag!"; /* Changed last char */ if (crypto_sign_verify(sig, siglen, tampered, mlen, pk) != 0) { printf("Tampered message correctly rejected.\n"); } /* Output: * Signature verified successfully. * Tampered message correctly rejected. */ return 0; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.