diff --git a/nostr_core/nip004.c b/nostr_core/nip004.c index 3ce84311..46144b7f 100644 --- a/nostr_core/nip004.c +++ b/nostr_core/nip004.c @@ -107,18 +107,13 @@ int nostr_nip04_encrypt(const unsigned char* sender_private_key, const char* plaintext, char* output, size_t output_size) { - printf("[DEBUG] nostr_nip04_encrypt: Starting encryption\n"); - if (!sender_private_key || !recipient_public_key || !plaintext || !output) { - printf("[DEBUG] nostr_nip04_encrypt: Invalid input - null pointer detected\n"); return NOSTR_ERROR_INVALID_INPUT; } size_t plaintext_len = strlen(plaintext); - printf("[DEBUG] nostr_nip04_encrypt: Plaintext length = %zu\n", plaintext_len); if (plaintext_len > NOSTR_NIP04_MAX_PLAINTEXT_SIZE) { - printf("[DEBUG] nostr_nip04_encrypt: Plaintext too large (%zu > %d)\n", plaintext_len, NOSTR_NIP04_MAX_PLAINTEXT_SIZE); return NOSTR_ERROR_NIP04_BUFFER_TOO_SMALL; } @@ -130,64 +125,46 @@ int nostr_nip04_encrypt(const unsigned char* sender_private_key, size_t iv_b64_max = ((16 + 2) / 3) * 4 + 1; // Always 25 bytes size_t estimated_result_len = ciphertext_b64_max + 4 + iv_b64_max; // +4 for "?iv=" - printf("[DEBUG] nostr_nip04_encrypt: Size calculations - padded_len=%zu, ciphertext_b64_max=%zu, estimated_result_len=%zu, output_size=%zu\n", - padded_len, ciphertext_b64_max, estimated_result_len, output_size); - // FIX: Check output buffer size BEFORE doing any work if (estimated_result_len > output_size) { - printf("[DEBUG] nostr_nip04_encrypt: Output buffer too small (%zu > %zu)\n", estimated_result_len, output_size); return NOSTR_ERROR_NIP04_BUFFER_TOO_SMALL; } // Step 1: Compute ECDH shared secret - printf("[DEBUG] nostr_nip04_encrypt: Computing ECDH shared secret\n"); unsigned char shared_secret[32]; if (ecdh_shared_secret(sender_private_key, recipient_public_key, shared_secret) != 0) { - printf("[DEBUG] nostr_nip04_encrypt: ECDH shared secret computation failed\n"); return NOSTR_ERROR_CRYPTO_FAILED; } - printf("[DEBUG] nostr_nip04_encrypt: ECDH shared secret computed successfully\n"); // Step 2: Generate random IV (16 bytes) - printf("[DEBUG] nostr_nip04_encrypt: Generating random IV\n"); unsigned char iv[16]; if (nostr_secp256k1_get_random_bytes(iv, 16) != 1) { - printf("[DEBUG] nostr_nip04_encrypt: Failed to generate random IV\n"); return NOSTR_ERROR_CRYPTO_FAILED; } - printf("[DEBUG] nostr_nip04_encrypt: IV generated successfully\n"); // Step 3: Pad plaintext using PKCS#7 - printf("[DEBUG] nostr_nip04_encrypt: Padding plaintext with PKCS#7\n"); unsigned char* padded_data = malloc(padded_len); if (!padded_data) { - printf("[DEBUG] nostr_nip04_encrypt: Failed to allocate memory for padded data\n"); return NOSTR_ERROR_MEMORY_FAILED; } memcpy(padded_data, plaintext, plaintext_len); size_t actual_padded_len = pkcs7_pad(padded_data, plaintext_len, 16); - printf("[DEBUG] nostr_nip04_encrypt: PKCS#7 padding completed - actual_padded_len=%zu\n", actual_padded_len); // Step 4: Encrypt using AES-256-CBC - printf("[DEBUG] nostr_nip04_encrypt: Encrypting with AES-256-CBC\n"); unsigned char* ciphertext = malloc(padded_len); if (!ciphertext) { - printf("[DEBUG] nostr_nip04_encrypt: Failed to allocate memory for ciphertext\n"); free(padded_data); return NOSTR_ERROR_MEMORY_FAILED; } if (aes_cbc_encrypt(shared_secret, iv, padded_data, actual_padded_len, ciphertext) != 0) { - printf("[DEBUG] nostr_nip04_encrypt: AES-256-CBC encryption failed\n"); free(padded_data); free(ciphertext); return NOSTR_ERROR_CRYPTO_FAILED; } - printf("[DEBUG] nostr_nip04_encrypt: AES-256-CBC encryption completed successfully\n"); // Step 5: Base64 encode ciphertext and IV - printf("[DEBUG] nostr_nip04_encrypt: Base64 encoding ciphertext and IV\n"); size_t ciphertext_b64_len = ((actual_padded_len + 2) / 3) * 4 + 1; size_t iv_b64_len = ((16 + 2) / 3) * 4 + 1; @@ -195,7 +172,6 @@ int nostr_nip04_encrypt(const unsigned char* sender_private_key, char* iv_b64 = malloc(iv_b64_len); if (!ciphertext_b64 || !iv_b64) { - printf("[DEBUG] nostr_nip04_encrypt: Failed to allocate memory for base64 buffers\n"); free(padded_data); free(ciphertext); free(ciphertext_b64); @@ -207,11 +183,8 @@ int nostr_nip04_encrypt(const unsigned char* sender_private_key, size_t ct_b64_len = base64_encode(ciphertext, actual_padded_len, ciphertext_b64, ciphertext_b64_len); size_t iv_b64_len_actual = base64_encode(iv, 16, iv_b64, iv_b64_len); - printf("[DEBUG] nostr_nip04_encrypt: Base64 encoding results - ct_b64_len=%zu, iv_b64_len_actual=%zu\n", ct_b64_len, iv_b64_len_actual); - // FIX: Check if encoding succeeded if (ct_b64_len == 0 || iv_b64_len_actual == 0) { - printf("[DEBUG] nostr_nip04_encrypt: Base64 encoding failed\n"); free(padded_data); free(ciphertext); free(ciphertext_b64); @@ -219,16 +192,11 @@ int nostr_nip04_encrypt(const unsigned char* sender_private_key, memory_clear(shared_secret, 32); return NOSTR_ERROR_CRYPTO_FAILED; } - printf("[DEBUG] nostr_nip04_encrypt: Base64 encoding completed successfully\n"); // Step 6: Format as "ciphertext?iv=iv_base64" - size check moved earlier, now guaranteed to fit - printf("[DEBUG] nostr_nip04_encrypt: Formatting final output string\n"); size_t result_len = ct_b64_len + 4 + iv_b64_len_actual + 1; // +4 for "?iv=", +1 for null - printf("[DEBUG] nostr_nip04_encrypt: Final size check - result_len=%zu, output_size=%zu\n", result_len, output_size); - if (result_len > output_size) { - printf("[DEBUG] nostr_nip04_encrypt: Final output buffer too small (%zu > %zu)\n", result_len, output_size); free(padded_data); free(ciphertext); free(ciphertext_b64); @@ -238,8 +206,6 @@ int nostr_nip04_encrypt(const unsigned char* sender_private_key, } snprintf(output, output_size, "%s?iv=%s", ciphertext_b64, iv_b64); - printf("[DEBUG] nostr_nip04_encrypt: Formatted output successfully\n"); - printf("[DEBUG] nostr_nip04_encrypt: Encryption completed successfully - returning NOSTR_SUCCESS\n"); // Cleanup memory_clear(shared_secret, 32); diff --git a/nostr_core/nip044.c b/nostr_core/nip044.c index 90018944..3bf2a7aa 100644 --- a/nostr_core/nip044.c +++ b/nostr_core/nip044.c @@ -27,6 +27,7 @@ static void memory_clear(const void *p, size_t len) { } } + // ============================================================================= // NIP-44 UTILITY FUNCTIONS // ============================================================================= @@ -85,13 +86,8 @@ static char* unpad_plaintext(const unsigned char* padded, size_t padded_len) { size_t unpadded_len = (padded[0] << 8) | padded[1]; size_t expected_padded_len = calc_padded_len(unpadded_len); - printf("--- unpad_plaintext DEBUG ---\n"); - printf("padded_len: %zu\n", padded_len); - printf("unpadded_len: %zu\n", unpadded_len); - printf("expected_padded_len: %zu\n", expected_padded_len); - printf("--- end unpad_plaintext DEBUG ---\n"); - if (padded_len != expected_padded_len) { + if (padded_len != expected_padded_len + 2) { return NULL; } @@ -130,6 +126,7 @@ int nostr_nip44_encrypt_with_nonce(const unsigned char* sender_private_key, return NOSTR_ERROR_NIP44_BUFFER_TOO_SMALL; } + // Step 1: Compute ECDH shared secret unsigned char shared_secret[32]; if (ecdh_shared_secret(sender_private_key, recipient_public_key, shared_secret) != 0) { @@ -150,6 +147,7 @@ int nostr_nip44_encrypt_with_nonce(const unsigned char* sender_private_key, unsigned char nonce_copy[32]; memcpy(nonce_copy, nonce, 32); + // Step 4: Derive message keys (HKDF-expand with nonce as info) unsigned char message_keys[76]; // 32 chacha_key + 12 chacha_nonce + 32 hmac_key if (nostr_hkdf_expand(conversation_key, 32, nonce_copy, 32, message_keys, 76) != 0) { @@ -163,6 +161,7 @@ int nostr_nip44_encrypt_with_nonce(const unsigned char* sender_private_key, unsigned char* chacha_nonce = message_keys + 32; unsigned char* hmac_key = message_keys + 44; + // Step 5: Pad plaintext according to NIP-44 spec size_t padded_len; unsigned char* padded_plaintext = pad_plaintext(plaintext, &padded_len); diff --git a/nostr_core/utils.c b/nostr_core/utils.c index 6e8d8a2a..3069c003 100644 --- a/nostr_core/utils.c +++ b/nostr_core/utils.c @@ -174,14 +174,12 @@ int ecdh_shared_secret(const unsigned char* private_key, * nostr_cleanup(); */ - printf("[DEBUG] ecdh_shared_secret: Starting ECDH computation\n"); + if (!private_key || !public_key_x || !shared_secret) { - printf("[DEBUG] ecdh_shared_secret: Invalid input - null pointer detected\n"); return -1; } - printf("[DEBUG] ecdh_shared_secret: Input validation passed\n"); // NIP-04 ECDH: The key insight from the specification is that NOSTR requires // "only the X coordinate of the shared point is used as the secret and it is NOT hashed" @@ -196,21 +194,11 @@ int ecdh_shared_secret(const unsigned char* private_key, compressed_pubkey[0] = 0x02; memcpy(compressed_pubkey + 1, public_key_x, 32); - printf("[DEBUG] ecdh_shared_secret: Trying 0x02 prefix (even y)\n"); - if (nostr_secp256k1_ec_pubkey_parse(&pubkey, compressed_pubkey, 33) == 1) { - printf("[DEBUG] ecdh_shared_secret: 0x02 prefix worked, public key parsed successfully\n"); - // Perform ECDH with our custom hash function that copies the X coordinate - printf("[DEBUG] ecdh_shared_secret: Performing ECDH operation with 0x02 prefix\n"); if (nostr_secp256k1_ecdh(shared_secret, &pubkey, private_key, ecdh_hash_function_copy_x, NULL) == 1) { - printf("[DEBUG] ecdh_shared_secret: ECDH operation completed successfully\n"); return 0; - } else { - printf("[DEBUG] ecdh_shared_secret: ECDH operation failed with 0x02 prefix\n"); } - } else { - printf("[DEBUG] ecdh_shared_secret: 0x02 prefix failed, trying 0x03 prefix (odd y)\n"); } // Try with 0x03 prefix (odd y-coordinate) @@ -218,21 +206,12 @@ int ecdh_shared_secret(const unsigned char* private_key, // public_key_x is already copied above if (nostr_secp256k1_ec_pubkey_parse(&pubkey, compressed_pubkey, 33) == 1) { - printf("[DEBUG] ecdh_shared_secret: 0x03 prefix worked, public key parsed successfully\n"); - // Perform ECDH with our custom hash function that copies the X coordinate - printf("[DEBUG] ecdh_shared_secret: Performing ECDH operation with 0x03 prefix\n"); if (nostr_secp256k1_ecdh(shared_secret, &pubkey, private_key, ecdh_hash_function_copy_x, NULL) == 1) { - printf("[DEBUG] ecdh_shared_secret: ECDH operation completed successfully\n"); return 0; - } else { - printf("[DEBUG] ecdh_shared_secret: ECDH operation failed with 0x03 prefix\n"); } - } else { - printf("[DEBUG] ecdh_shared_secret: Both 0x02 and 0x03 prefixes failed - invalid public key\n"); } - - printf("[DEBUG] ecdh_shared_secret: All attempts failed\n"); + return -1; } diff --git a/tests/bip32_test b/tests/bip32_test index 59cc6d16..007fec5a 100755 Binary files a/tests/bip32_test and b/tests/bip32_test differ diff --git a/tests/crypto_test b/tests/crypto_test index 1710991c..c58db587 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 index 94c3acdc..478135af 100755 Binary files a/tests/nip04_comparison_test and b/tests/nip04_comparison_test differ diff --git a/tests/nip04_test b/tests/nip04_test index 9fde4302..75636781 100755 Binary files a/tests/nip04_test and b/tests/nip04_test differ diff --git a/tests/nip05_test b/tests/nip05_test index 20cab34a..57877996 100755 Binary files a/tests/nip05_test and b/tests/nip05_test differ diff --git a/tests/nip11_test b/tests/nip11_test index d6557180..e552eb12 100755 Binary files a/tests/nip11_test and b/tests/nip11_test differ diff --git a/tests/nip44_test b/tests/nip44_test index 53a7d859..6ad9207c 100755 Binary files a/tests/nip44_test and b/tests/nip44_test differ diff --git a/tests/nip44_test.c b/tests/nip44_test.c index 526f6618..553cc8b9 100644 --- a/tests/nip44_test.c +++ b/tests/nip44_test.c @@ -83,12 +83,6 @@ static int hex_to_bytes(const char* hex, unsigned char* bytes, size_t len) { return 0; } -static void bytes_to_hex(const unsigned char* bytes, size_t len, char* hex) { - for (size_t i = 0; i < len; i++) { - sprintf(hex + i * 2, "%02x", bytes[i]); - } - hex[len * 2] = '\0'; -} static int test_nip44_round_trip(const nip44_test_vector_t* tv) { printf("Test: %s\n", tv->name); @@ -364,31 +358,39 @@ int main() { size_t num_vectors = sizeof(test_vectors) / sizeof(test_vectors[0]); for (size_t i = 0; i < num_vectors; i++) { total_tests++; + printf("Test #%d\n", total_tests); if (test_nip44_round_trip(&test_vectors[i]) == 0) { passed_tests++; } + printf("\n"); } // Test decryption vectors (cross-compatibility) size_t num_decryption_vectors = sizeof(decryption_test_vectors) / sizeof(decryption_test_vectors[0]); for (size_t i = 0; i < num_decryption_vectors; i++) { total_tests++; + printf("Test #%d\n", total_tests); if (test_nip44_decryption_vector(&decryption_test_vectors[i]) == 0) { passed_tests++; } + printf("\n"); } // Test encryption variability (NIP-44 non-deterministic behavior) total_tests++; + printf("Test #%d\n", total_tests); if (test_nip44_encryption_variability() == 0) { passed_tests++; } + printf("\n"); // Test error conditions total_tests++; + printf("Test #%d\n", total_tests); if (test_nip44_error_conditions() == 0) { passed_tests++; } + printf("\n"); // Final results printf("\nTest Results: %d/%d passed\n", passed_tests, total_tests); diff --git a/tests/simple_init_test b/tests/simple_init_test index 697618c0..97f425c8 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 41b2f4cd..ab19d9e6 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 e7439947..dd641486 100755 Binary files a/tests/wss_test and b/tests/wss_test differ