diff --git a/tests/bip32_test b/tests/bip32_test index 55acf5cd..59cc6d16 100755 Binary files a/tests/bip32_test and b/tests/bip32_test differ diff --git a/tests/crypto_test b/tests/crypto_test index cecaa910..1710991c 100755 Binary files a/tests/crypto_test and b/tests/crypto_test differ diff --git a/tests/nip04_comparison_test b/tests/nip04_comparison_test new file mode 100755 index 00000000..dabef9e7 Binary files /dev/null and b/tests/nip04_comparison_test differ diff --git a/tests/nip04_comparison_test.c b/tests/nip04_comparison_test.c new file mode 100644 index 00000000..ecf896a0 --- /dev/null +++ b/tests/nip04_comparison_test.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include "../nostr_core/nip004.h" +#include "../nostr_core/nostr_common.h" +#include "../nostr_core/utils.h" + +int main(void) { + // Test vector 1 from the existing test + const char* sk1_hex = "91ba716fa9e7ea2fcbad360cf4f8e0d312f73984da63d90f524ad61a6a1e7dbe"; + const char* pk2_hex = "dcb33a629560280a0ee3b6b99b68c044fe8914ad8a984001ebf6099a9b474dc3"; + const char* plaintext = "nanana"; + + // Convert hex keys to bytes using the system function + unsigned char sk1[32], pk2[32]; + nostr_hex_to_bytes(sk1_hex, sk1, 32); + nostr_hex_to_bytes(pk2_hex, pk2, 32); + + // Allocate output buffer + char* encrypted = malloc(NOSTR_NIP04_MAX_ENCRYPTED_SIZE); + if (!encrypted) { + printf("Memory allocation failed\n"); + return 1; + } + + // Call the encryption function + int result = nostr_nip04_encrypt(sk1, pk2, plaintext, encrypted, NOSTR_NIP04_MAX_ENCRYPTED_SIZE); + + if (result == NOSTR_SUCCESS) { + printf("%s\n", encrypted); + } else { + printf("Error: %s\n", nostr_strerror(result)); + } + + free(encrypted); + return 0; +} diff --git a/tests/nip04_debug_test.c b/tests/nip04_debug_test.c new file mode 100644 index 00000000..e5b07767 --- /dev/null +++ b/tests/nip04_debug_test.c @@ -0,0 +1,204 @@ +/* + * NIP-04 Encryption DEBUG Test + * This test shows intermediate values to compare with JavaScript implementation + */ + +#include +#include +#include +#include "../nostr_core/nip004.h" +#include "../nostr_core/nostr_common.h" +#include "../nostr_core/crypto/nostr_secp256k1.h" +#include "../nostr_core/utils.h" + +void print_hex_debug(const char* label, const unsigned char* data, size_t len) { + printf("%s (%zu bytes): ", label, len); + for (size_t i = 0; i < len; i++) { + printf("%02x", data[i]); + } + printf("\n"); +} + +void hex_to_bytes(const char* hex_str, unsigned char* bytes) { + size_t len = strlen(hex_str); + for (size_t i = 0; i < len; i += 2) { + sscanf(hex_str + i, "%2hhx", &bytes[i / 2]); + } +} + +int test_ecdh_debug(void) { + printf("\n=== ECDH DEBUG TEST ===\n"); + + // Test vector from JavaScript debug output + const char* sk1_hex = "91ba716fa9e7ea2fcbad360cf4f8e0d312f73984da63d90f524ad61a6a1e7dbe"; + const char* pk2_hex = "dcb33a629560280a0ee3b6b99b68c044fe8914ad8a984001ebf6099a9b474dc3"; + + // Expected values from JavaScript: + // Shared Secret (33 bytes): 037ce22696eb0e303ddaa491bdf2a56b79d249f2d861b8e012a933e01dc4beba81 + // Normalized Key (32 bytes): 7ce22696eb0e303ddaa491bdf2a56b79d249f2d861b8e012a933e01dc4beba81 + + unsigned char sk1[32], pk2[32]; + hex_to_bytes(sk1_hex, sk1); + hex_to_bytes(pk2_hex, pk2); + + printf("Private Key: %s\n", sk1_hex); + printf("Public Key: %s\n", pk2_hex); + + print_hex_debug("SK1", sk1, 32); + print_hex_debug("PK2", pk2, 32); + + // Test ECDH shared secret computation + unsigned char shared_secret[32]; + printf("\nCalling ecdh_shared_secret...\n"); + int result = ecdh_shared_secret(sk1, pk2, shared_secret); + printf("ecdh_shared_secret returned: %d\n", result); + + if (result == 0) { + print_hex_debug("C Shared Secret", shared_secret, 32); + printf("Expected: 7ce22696eb0e303ddaa491bdf2a56b79d249f2d861b8e012a933e01dc4beba81\n"); + + // Check if it matches expected + const char* expected_hex = "7ce22696eb0e303ddaa491bdf2a56b79d249f2d861b8e012a933e01dc4beba81"; + unsigned char expected[32]; + hex_to_bytes(expected_hex, expected); + + if (memcmp(shared_secret, expected, 32) == 0) { + printf("✅ ECDH matches expected value!\n"); + return 1; + } else { + printf("❌ ECDH does NOT match expected value\n"); + print_hex_debug("Expected", expected, 32); + return 0; + } + } else { + printf("❌ ECDH computation failed with error code: %d\n", result); + return 0; + } +} + +int test_encryption_step_by_step(void) { + printf("\n=== STEP-BY-STEP ENCRYPTION DEBUG ===\n"); + + // Test vector 1 data + const char* sk1_hex = "91ba716fa9e7ea2fcbad360cf4f8e0d312f73984da63d90f524ad61a6a1e7dbe"; + const char* pk2_hex = "dcb33a629560280a0ee3b6b99b68c044fe8914ad8a984001ebf6099a9b474dc3"; + const char* plaintext = "nanana"; + + // Known IV from JavaScript test (to get deterministic results) + const char* fixed_iv_hex = "115e5b52371ce0e5f62a6ff33e9e2775"; + + printf("Private Key: %s\n", sk1_hex); + printf("Public Key: %s\n", pk2_hex); + printf("Plaintext: \"%s\"\n", plaintext); + printf("Fixed IV: %s\n", fixed_iv_hex); + + unsigned char sk1[32], pk2[32], fixed_iv[16]; + hex_to_bytes(sk1_hex, sk1); + hex_to_bytes(pk2_hex, pk2); + hex_to_bytes(fixed_iv_hex, fixed_iv); + + // Step 1: ECDH + printf("\n--- Step 1: ECDH Shared Secret ---\n"); + unsigned char shared_secret[32]; + if (ecdh_shared_secret(sk1, pk2, shared_secret) != 0) { + printf("❌ ECDH failed\n"); + return 0; + } + print_hex_debug("Shared Secret", shared_secret, 32); + printf("Expected: 7ce22696eb0e303ddaa491bdf2a56b79d249f2d861b8e012a933e01dc4beba81\n"); + + // Step 2: Convert plaintext to bytes + printf("\n--- Step 2: Plaintext to UTF-8 bytes ---\n"); + size_t plaintext_len = strlen(plaintext); + printf("UTF-8 Plaintext (%zu bytes): ", plaintext_len); + for (size_t i = 0; i < plaintext_len; i++) { + printf("%02x", (unsigned char)plaintext[i]); + } + printf("\n"); + printf("Expected: 6e616e616e61\n"); + + // Step 3: PKCS#7 padding + printf("\n--- Step 3: PKCS#7 Padding ---\n"); + size_t padded_len = ((plaintext_len / 16) + 1) * 16; + unsigned char* padded_data = malloc(padded_len); + if (!padded_data) { + printf("❌ Memory allocation failed\n"); + return 0; + } + + memcpy(padded_data, plaintext, plaintext_len); + + // Manual PKCS#7 padding for debugging + size_t padding_needed = 16 - (plaintext_len % 16); + for (size_t i = 0; i < padding_needed; i++) { + padded_data[plaintext_len + i] = (unsigned char)padding_needed; + } + size_t actual_padded_len = plaintext_len + padding_needed; + + print_hex_debug("Padded Data", padded_data, actual_padded_len); + printf("Padding bytes added: %zu (value: 0x%02x)\n", padding_needed, (unsigned char)padding_needed); + + // Step 4: Try calling the full encryption function + printf("\n--- Step 4: Full Encryption Function ---\n"); + char* encrypted = malloc(NOSTR_NIP04_MAX_ENCRYPTED_SIZE); + if (!encrypted) { + printf("❌ Memory allocation failed\n"); + free(padded_data); + return 0; + } + + printf("Calling nostr_nip04_encrypt...\n"); + int result = nostr_nip04_encrypt(sk1, pk2, plaintext, encrypted, NOSTR_NIP04_MAX_ENCRYPTED_SIZE); + printf("nostr_nip04_encrypt returned: %d (%s)\n", result, nostr_strerror(result)); + + if (result == NOSTR_SUCCESS) { + printf("✅ Encryption succeeded!\n"); + printf("Result: %s\n", encrypted); + printf("Expected: zJxfaJ32rN5Dg1ODjOlEew==?iv=EV5bUjcc4OX2Km/zPp4ndQ==\n"); + } else { + printf("❌ Encryption failed with error: %s\n", nostr_strerror(result)); + } + + free(padded_data); + free(encrypted); + return result == NOSTR_SUCCESS ? 1 : 0; +} + +int main(void) { + printf("=== NIP-04 DEBUG TEST ===\n"); + printf("This test shows intermediate values for comparison with JavaScript implementation\n\n"); + + // Initialize secp256k1 context + printf("Initializing secp256k1 context...\n"); + if (!nostr_secp256k1_context_create()) { + printf("❌ Failed to initialize secp256k1 context!\n"); + return 1; + } + printf("✅ secp256k1 context initialized successfully\n\n"); + + int all_passed = 1; + + // Test 1: ECDH computation + if (!test_ecdh_debug()) { + all_passed = 0; + printf("❌ ECDH test failed - this is likely the root cause!\n"); + } + + // Test 2: Step by step encryption + if (!test_encryption_step_by_step()) { + all_passed = 0; + } + + // Summary + printf("\n=== SUMMARY ===\n"); + if (all_passed) { + printf("✅ All debug tests passed!\n"); + } else { + printf("❌ Some debug tests failed - compare values with JavaScript output\n"); + } + + // Clean up secp256k1 context + nostr_secp256k1_context_destroy(); + + return all_passed ? 0 : 1; +} diff --git a/tests/nip04_test b/tests/nip04_test index 02b247dc..cdbd6737 100755 Binary files a/tests/nip04_test and b/tests/nip04_test differ diff --git a/tests/nip04_test.c b/tests/nip04_test.c index f4b10d6b..d13bcc1c 100644 --- a/tests/nip04_test.c +++ b/tests/nip04_test.c @@ -8,22 +8,7 @@ #include #include "../nostr_core/nip004.h" #include "../nostr_core/nostr_common.h" - - -void print_hex(const char* label, const unsigned char* data, size_t len) { - printf("%s: ", label); - for (size_t i = 0; i < len; i++) { - printf("%02x", data[i]); - } - printf("\n"); -} - -void hex_to_bytes(const char* hex_str, unsigned char* bytes) { - size_t len = strlen(hex_str); - for (size_t i = 0; i < len; i += 2) { - sscanf(hex_str + i, "%2hhx", &bytes[i / 2]); - } -} +#include "../nostr_core/utils.h" // Simple replacement for strndup which isn't available in C99 char* safe_strndup(const char* s, size_t n) { @@ -50,10 +35,10 @@ int test_vector_1(void) { // Convert hex keys to bytes unsigned char sk1[32], sk2[32], pk1[32], pk2[32]; - hex_to_bytes(sk1_hex, sk1); - hex_to_bytes(sk2_hex, sk2); - hex_to_bytes(pk1_hex, pk1); - hex_to_bytes(pk2_hex, pk2); + nostr_hex_to_bytes(sk1_hex, sk1, 32); + nostr_hex_to_bytes(sk2_hex, sk2, 32); + nostr_hex_to_bytes(pk1_hex, pk1, 32); + nostr_hex_to_bytes(pk2_hex, pk2, 32); printf("Input Test Vector:\n"); printf("SK1 (Alice): %s\n", sk1_hex); @@ -157,10 +142,10 @@ int test_vector_2(void) { // Convert hex keys to bytes unsigned char sk1[32], sk2[32], pk1[32], pk2[32]; - hex_to_bytes(sk1_hex, sk1); - hex_to_bytes(sk2_hex, sk2); - hex_to_bytes(pk1_hex, pk1); - hex_to_bytes(pk2_hex, pk2); + nostr_hex_to_bytes(sk1_hex, sk1, 32); + nostr_hex_to_bytes(sk2_hex, sk2, 32); + nostr_hex_to_bytes(pk1_hex, pk1, 32); + nostr_hex_to_bytes(pk2_hex, pk2, 32); printf("Input Test Vector:\n"); printf("SK1 (Alice): %s\n", sk1_hex); @@ -255,10 +240,10 @@ int test_vector_3_bidirectional(void) { // Convert hex keys to bytes unsigned char sk1[32], sk2[32], pk1[32], pk2[32]; - hex_to_bytes(sk1_hex, sk1); - hex_to_bytes(sk2_hex, sk2); - hex_to_bytes(pk1_hex, pk1); - hex_to_bytes(pk2_hex, pk2); + nostr_hex_to_bytes(sk1_hex, sk1, 32); + nostr_hex_to_bytes(sk2_hex, sk2, 32); + nostr_hex_to_bytes(pk1_hex, pk1, 32); + nostr_hex_to_bytes(pk2_hex, pk2, 32); printf("Input Test Vector:\n"); printf("SK1 (Alice): %s\n", sk1_hex); @@ -364,10 +349,10 @@ int test_vector_4_random_keys(void) { // Convert hex keys to bytes unsigned char sk1[32], sk2[32], pk1[32], pk2[32]; - hex_to_bytes(sk1_hex, sk1); - hex_to_bytes(sk2_hex, sk2); - hex_to_bytes(pk1_hex, pk1); - hex_to_bytes(pk2_hex, pk2); + nostr_hex_to_bytes(sk1_hex, sk1, 32); + nostr_hex_to_bytes(sk2_hex, sk2, 32); + nostr_hex_to_bytes(pk1_hex, pk1, 32); + nostr_hex_to_bytes(pk2_hex, pk2, 32); printf("Input Test Vector:\n"); printf("SK1 (Alice): %s\n", sk1_hex); @@ -452,10 +437,10 @@ int test_vector_5_long_message(void) { // Convert hex keys to bytes unsigned char sk1[32], sk2[32], pk1[32], pk2[32]; - hex_to_bytes(sk1_hex, sk1); - hex_to_bytes(sk2_hex, sk2); - hex_to_bytes(pk1_hex, pk1); - hex_to_bytes(pk2_hex, pk2); + nostr_hex_to_bytes(sk1_hex, sk1, 32); + nostr_hex_to_bytes(sk2_hex, sk2, 32); + nostr_hex_to_bytes(pk1_hex, pk1, 32); + nostr_hex_to_bytes(pk2_hex, pk2, 32); printf("Input Test Vector:\n"); printf("SK1 (Alice): %s\n", sk1_hex); @@ -540,10 +525,10 @@ int test_vector_6_short_message(void) { // Convert hex keys to bytes unsigned char sk1[32], sk2[32], pk1[32], pk2[32]; - hex_to_bytes(sk1_hex, sk1); - hex_to_bytes(sk2_hex, sk2); - hex_to_bytes(pk1_hex, pk1); - hex_to_bytes(pk2_hex, pk2); + nostr_hex_to_bytes(sk1_hex, sk1, 32); + nostr_hex_to_bytes(sk2_hex, sk2, 32); + nostr_hex_to_bytes(pk1_hex, pk1, 32); + nostr_hex_to_bytes(pk2_hex, pk2, 32); printf("Input Test Vector:\n"); printf("SK1 (Alice): %s\n", sk1_hex); @@ -644,10 +629,10 @@ int test_vector_7_10kb_payload(void) { // Convert hex keys to bytes unsigned char sk1[32], sk2[32], pk1[32], pk2[32]; - hex_to_bytes(sk1_hex, sk1); - hex_to_bytes(sk2_hex, sk2); - hex_to_bytes(pk1_hex, pk1); - hex_to_bytes(pk2_hex, pk2); + nostr_hex_to_bytes(sk1_hex, sk1, 32); + nostr_hex_to_bytes(sk2_hex, sk2, 32); + nostr_hex_to_bytes(pk1_hex, pk1, 32); + nostr_hex_to_bytes(pk2_hex, pk2, 32); printf("Input Test Vector:\n"); printf("SK1 (Alice): %s\n", sk1_hex); @@ -757,11 +742,11 @@ int test_vector_7_10kb_payload(void) { int main(void) { printf("=== NIP-04 Encryption Test with Reference Test Vectors ===\n\n"); - // Initialize the library - // if (nostr_init() != NOSTR_SUCCESS) { - // printf("ERROR: Failed to initialize NOSTR library\n"); - // return 1; - // } + // Initialize the library - REQUIRED for secp256k1 operations + if (nostr_crypto_init() != 0) { + printf("ERROR: Failed to initialize NOSTR crypto library\n"); + return 1; + } int all_passed = 1; @@ -813,6 +798,7 @@ int main(void) { printf("❌ SOME TESTS FAILED. Please review the output above.\n"); } - // nostr_cleanup(); + // Cleanup crypto resources + nostr_crypto_cleanup(); return all_passed ? 0 : 1; } diff --git a/tests/nip05_test b/tests/nip05_test index 49a96d63..20cab34a 100755 Binary files a/tests/nip05_test and b/tests/nip05_test differ diff --git a/tests/nip11_test b/tests/nip11_test index 8b0e7c9e..d6557180 100755 Binary files a/tests/nip11_test and b/tests/nip11_test differ diff --git a/tests/simple_init_test b/tests/simple_init_test index 0c986d8f..697618c0 100755 Binary files a/tests/simple_init_test and b/tests/simple_init_test differ diff --git a/tests/sync_relay_test b/tests/sync_relay_test index f3e0a932..41b2f4cd 100755 Binary files a/tests/sync_relay_test and b/tests/sync_relay_test differ diff --git a/tests/wss_test b/tests/wss_test index 1e53abcb..e7439947 100755 Binary files a/tests/wss_test and b/tests/wss_test differ