First commit on a late git install

This commit is contained in:
2025-08-09 10:23:28 -04:00
commit ca6b4754f9
88 changed files with 18219 additions and 0 deletions

393
tests/nip44_test.c Normal file
View File

@@ -0,0 +1,393 @@
/*
* NIP-44 Encryption/Decryption Test
*
* Test suite for NIP-44 versioned encryption functionality
* Uses known test vectors and cross-implementation compatibility tests
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "../nostr_core/nostr_core.h"
// Test vectors for NIP-44 with proper key pairs
typedef struct {
const char* name;
const char* sender_private_key_hex;
const char* recipient_private_key_hex; // FIX: Need proper private key, not public key
const char* plaintext;
const char* expected_encrypted; // Optional - for known test vectors
} nip44_test_vector_t;
// Known test vectors from nostr-tools nip44.vectors.json
static nip44_test_vector_t known_test_vectors[] = {
{
"Known vector: single char 'a'",
"0000000000000000000000000000000000000000000000000000000000000001", // sec1
"0000000000000000000000000000000000000000000000000000000000000002", // sec2
"a",
"AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABee0G5VSK0/9YypIObAtDKfYEAjD35uVkHyB0F4DwrcNaCXlCWZKaArsGrY6M9wnuTMxWfp1RTN9Xga8no+kF5Vsb"
},
{
"Known vector: emoji",
"0000000000000000000000000000000000000000000000000000000000000002", // sec1
"0000000000000000000000000000000000000000000000000000000000000001", // sec2
"🍕🫃",
"AvAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAAAPSKSK6is9ngkX2+cSq85Th16oRTISAOfhStnixqZziKMDvB0QQzgFZdjLTPicCJaV8nDITO+QfaQ61+KbWQIOO2Yj"
},
{
"Known vector: wide unicode",
"5c0c523f52a5b6fad39ed2403092df8cebc36318b39383bca6c00808626fab3a", // sec1
"4b22aa260e4acb7021e32f38a6cdf4b673c6a277755bfce287e370c924dc936d", // sec2
"表ポあA鷗Œé逍Üߪąñ丂㐀𠀀",
"ArY1I2xC2yDwIbuNHN/1ynXdGgzHLqdCrXUPMwELJPc7s7JqlCMJBAIIjfkpHReBPXeoMCyuClwgbT419jUWU1PwaNl4FEQYKCDKVJz+97Mp3K+Q2YGa77B6gpxB/lr1QgoqpDf7wDVrDmOqGoiPjWDqy8KzLueKDcm9BVP8xeTJIxs="
}
};
// Round-trip test vectors with proper key pairs
static nip44_test_vector_t test_vectors[] = {
{
"Basic short message",
"91ba716fa9e7ea2fcbad360cf4f8e0d312f73984da63d90f524ad61a6a1e7dbe", // Working keys from simple_nip44_test
"96f6fa197aa07477ab88f6981118466ae3a982faab8ad5db9d5426870c73d220",
"Hello, NIP-44!",
NULL
},
{
"Unicode message",
"1111111111111111111111111111111111111111111111111111111111111111",
"2222222222222222222222222222222222222222222222222222222222222222",
"Hello 🌍 World! 🚀",
NULL
},
{
"Empty message",
"3333333333333333333333333333333333333333333333333333333333333333",
"4444444444444444444444444444444444444444444444444444444444444444",
"",
NULL
}
};
static int hex_to_bytes(const char* hex, unsigned char* bytes, size_t len) {
if (strlen(hex) != len * 2) return -1;
for (size_t i = 0; i < len; i++) {
if (sscanf(hex + i * 2, "%2hhx", &bytes[i]) != 1) {
return -1;
}
}
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("Testing: %s\n", tv->name);
// Parse keys - both private keys
unsigned char sender_private_key[32];
unsigned char recipient_private_key[32];
if (hex_to_bytes(tv->sender_private_key_hex, sender_private_key, 32) != 0) {
printf(" ❌ Failed to parse sender private key\n");
return -1;
}
if (hex_to_bytes(tv->recipient_private_key_hex, recipient_private_key, 32) != 0) {
printf(" ❌ Failed to parse recipient private key\n");
return -1;
}
// Generate the public keys from the private keys
unsigned char sender_public_key[32];
unsigned char recipient_public_key[32];
if (nostr_ec_public_key_from_private_key(sender_private_key, sender_public_key) != 0) {
printf(" ❌ Failed to derive sender public key\n");
return -1;
}
if (nostr_ec_public_key_from_private_key(recipient_private_key, recipient_public_key) != 0) {
printf(" ❌ Failed to derive recipient public key\n");
return -1;
}
// Test encryption
char encrypted[8192]; // Large buffer for encrypted data
int encrypt_result = nostr_nip44_encrypt(
sender_private_key,
recipient_public_key,
tv->plaintext,
encrypted,
sizeof(encrypted)
);
if (encrypt_result != NOSTR_SUCCESS) {
printf(" ❌ Encryption failed with error: %d\n", encrypt_result);
return -1;
}
printf(" ✅ Encryption successful\n");
printf(" 📦 Encrypted length: %zu bytes\n", strlen(encrypted));
// Test decryption - use recipient private key + sender public key
char decrypted[8192]; // Large buffer for decrypted data
int decrypt_result = nostr_nip44_decrypt(
recipient_private_key,
sender_public_key,
encrypted,
decrypted,
sizeof(decrypted)
);
if (decrypt_result != NOSTR_SUCCESS) {
printf(" ❌ Decryption failed with error: %d\n", decrypt_result);
return -1;
}
// Verify round-trip
if (strcmp(tv->plaintext, decrypted) != 0) {
printf(" ❌ Round-trip failed!\n");
printf(" 📝 Original: \"%s\"\n", tv->plaintext);
printf(" 📝 Decrypted: \"%s\"\n", decrypted);
return -1;
}
printf(" ✅ Round-trip successful!\n");
printf(" 📝 Message: \"%s\"\n", tv->plaintext);
printf("\n");
return 0;
}
static int test_nip44_error_conditions() {
printf("Testing NIP-44 error conditions:\n");
// Use proper valid secp256k1 private keys
unsigned char valid_sender_key[32];
unsigned char valid_recipient_key[32];
unsigned char valid_recipient_pubkey[32];
hex_to_bytes("0000000000000000000000000000000000000000000000000000000000000001", valid_sender_key, 32);
hex_to_bytes("0000000000000000000000000000000000000000000000000000000000000002", valid_recipient_key, 32);
// Generate the recipient's public key
if (nostr_ec_public_key_from_private_key(valid_recipient_key, valid_recipient_pubkey) != 0) {
printf(" ❌ Failed to generate recipient public key\n");
return -1;
}
char output[1024];
// Test NULL parameters
int result = nostr_nip44_encrypt(NULL, valid_recipient_pubkey, "test", output, sizeof(output));
if (result != NOSTR_ERROR_INVALID_INPUT) {
printf(" ❌ Should reject NULL sender key\n");
return -1;
}
result = nostr_nip44_encrypt(valid_sender_key, NULL, "test", output, sizeof(output));
if (result != NOSTR_ERROR_INVALID_INPUT) {
printf(" ❌ Should reject NULL recipient key\n");
return -1;
}
result = nostr_nip44_encrypt(valid_sender_key, valid_recipient_pubkey, NULL, output, sizeof(output));
if (result != NOSTR_ERROR_INVALID_INPUT) {
printf(" ❌ Should reject NULL plaintext\n");
return -1;
}
result = nostr_nip44_encrypt(valid_sender_key, valid_recipient_pubkey, "test", NULL, sizeof(output));
if (result != NOSTR_ERROR_INVALID_INPUT) {
printf(" ❌ Should reject NULL output buffer\n");
return -1;
}
// Test buffer too small
char small_buffer[10];
result = nostr_nip44_encrypt(valid_sender_key, valid_recipient_pubkey, "test message", small_buffer, sizeof(small_buffer));
if (result != NOSTR_ERROR_NIP44_BUFFER_TOO_SMALL) {
printf(" ❌ Should detect buffer too small, got error: %d\n", result);
return -1;
}
printf(" ✅ All error conditions handled correctly\n\n");
return 0;
}
static int test_nip44_known_vector(const nip44_test_vector_t* tv) {
printf("Testing known vector: %s\n", tv->name);
// Parse keys
unsigned char sender_private_key[32];
unsigned char recipient_private_key[32];
if (hex_to_bytes(tv->sender_private_key_hex, sender_private_key, 32) != 0) {
printf(" ❌ Failed to parse sender private key\n");
return -1;
}
if (hex_to_bytes(tv->recipient_private_key_hex, recipient_private_key, 32) != 0) {
printf(" ❌ Failed to parse recipient private key\n");
return -1;
}
// Generate the public keys from the private keys
unsigned char sender_public_key[32];
if (nostr_ec_public_key_from_private_key(sender_private_key, sender_public_key) != 0) {
printf(" ❌ Failed to derive sender public key\n");
return -1;
}
// Test decryption of known vector
char decrypted[8192];
int decrypt_result = nostr_nip44_decrypt(
recipient_private_key,
sender_public_key,
tv->expected_encrypted,
decrypted,
sizeof(decrypted)
);
if (decrypt_result != NOSTR_SUCCESS) {
printf(" ❌ Decryption of known vector failed with error: %d\n", decrypt_result);
printf(" 📦 Expected payload: %.80s...\n", tv->expected_encrypted);
return -1;
}
// Verify decrypted plaintext matches expected
if (strcmp(tv->plaintext, decrypted) != 0) {
printf(" ❌ Decrypted plaintext doesn't match!\n");
printf(" 📝 Expected: \"%s\"\n", tv->plaintext);
printf(" 📝 Got: \"%s\"\n", decrypted);
return -1;
}
printf(" ✅ Known vector decryption successful!\n");
printf(" 📝 Message: \"%s\"\n", tv->plaintext);
printf("\n");
return 0;
}
static int test_nip44_vs_nip04_comparison() {
printf("Testing NIP-44 vs NIP-04 comparison:\n");
const char* test_message = "This is a test message for comparing NIP-04 and NIP-44 encryption methods.";
unsigned char sender_key[32], recipient_key[32];
memset(sender_key, 0x11, 32);
memset(recipient_key, 0x22, 32);
// Generate proper public keys
unsigned char sender_pubkey[32], recipient_pubkey[32];
if (nostr_ec_public_key_from_private_key(sender_key, sender_pubkey) != 0 ||
nostr_ec_public_key_from_private_key(recipient_key, recipient_pubkey) != 0) {
printf(" ❌ Failed to generate public keys\n");
return -1;
}
// Test NIP-04 encryption
char nip04_encrypted[8192];
int nip04_result = nostr_nip04_encrypt(sender_key, recipient_pubkey,
test_message, nip04_encrypted, sizeof(nip04_encrypted));
// Test NIP-44 encryption
char nip44_encrypted[8192];
int nip44_result = nostr_nip44_encrypt(sender_key, recipient_pubkey,
test_message, nip44_encrypted, sizeof(nip44_encrypted));
if (nip04_result == NOSTR_SUCCESS && nip44_result == NOSTR_SUCCESS) {
printf(" ✅ Both NIP-04 and NIP-44 encryption successful\n");
printf(" 📊 NIP-04 output length: %zu bytes\n", strlen(nip04_encrypted));
printf(" 📊 NIP-44 output length: %zu bytes\n", strlen(nip44_encrypted));
printf(" 📊 Size difference: %+ld bytes\n",
(long)strlen(nip44_encrypted) - (long)strlen(nip04_encrypted));
// Verify they produce different outputs (they use different algorithms)
if (strcmp(nip04_encrypted, nip44_encrypted) == 0) {
printf(" ⚠️ Warning: NIP-04 and NIP-44 produced identical output (unexpected)\n");
} else {
printf(" ✅ NIP-04 and NIP-44 produce different outputs (expected)\n");
}
} else {
if (nip04_result != NOSTR_SUCCESS) {
printf(" ❌ NIP-04 encryption failed: %d\n", nip04_result);
}
if (nip44_result != NOSTR_SUCCESS) {
printf(" ❌ NIP-44 encryption failed: %d\n", nip44_result);
}
return -1;
}
printf("\n");
return 0;
}
int main() {
printf("🧪 NIP-44 Encryption Test Suite\n");
printf("================================\n\n");
// Initialize the library
if (nostr_init() != NOSTR_SUCCESS) {
printf("❌ Failed to initialize NOSTR library\n");
return 1;
}
int total_tests = 0;
int passed_tests = 0;
// Test all vectors
size_t num_vectors = sizeof(test_vectors) / sizeof(test_vectors[0]);
for (size_t i = 0; i < num_vectors; i++) {
total_tests++;
if (test_nip44_round_trip(&test_vectors[i]) == 0) {
passed_tests++;
}
}
// Test known vectors
size_t num_known_vectors = sizeof(known_test_vectors) / sizeof(known_test_vectors[0]);
for (size_t i = 0; i < num_known_vectors; i++) {
total_tests++;
if (test_nip44_known_vector(&known_test_vectors[i]) == 0) {
passed_tests++;
}
}
// Test error conditions
total_tests++;
if (test_nip44_error_conditions() == 0) {
passed_tests++;
}
// Test comparison with NIP-04
total_tests++;
if (test_nip44_vs_nip04_comparison() == 0) {
passed_tests++;
}
// Final results
printf("🏁 Test Results:\n");
printf("================\n");
printf("Tests passed: %d/%d\n", passed_tests, total_tests);
if (passed_tests == total_tests) {
printf("✅ All NIP-44 tests PASSED! 🎉\n");
nostr_cleanup();
return 0;
} else {
printf("❌ Some tests FAILED! 😞\n");
nostr_cleanup();
return 1;
}
}