Files
n_signer/tests/test_mnemonic.c

102 lines
3.9 KiB
C

#include "../src/mnemonic.h"
#include <stdio.h>
#include <string.h>
static int g_failures = 0;
/* Print PASS/FAIL and track failures. */
static void check_condition(const char *name, int condition) {
if (condition) {
printf("PASS: %s\n", name);
} else {
printf("FAIL: %s\n", name);
g_failures++;
}
}
/* Build a deterministic 25-word invalid mnemonic in `out`. */
static void build_25_word_phrase(char *out, size_t out_size) {
size_t used = 0;
int i;
if (out == NULL || out_size == 0) {
return;
}
out[0] = '\0';
for (i = 0; i < 25; ++i) {
const char *word = "abandon";
int wrote;
wrote = snprintf(out + used, out_size - used, "%s%s", (i == 0) ? "" : " ", word);
if (wrote < 0 || (size_t)wrote >= out_size - used) {
/* Truncate safely and stop if buffer is insufficient. */
out[out_size - 1] = '\0';
return;
}
used += (size_t)wrote;
}
}
int main(void) {
mnemonic_state_t state;
const char *valid_12 = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
const char *invalid_11 = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
char invalid_25[MNEMONIC_MAX_LEN];
const char *loaded_phrase;
char generated_12[MNEMONIC_MAX_LEN];
char generated_24[MNEMONIC_MAX_LEN];
int rc;
mnemonic_init(&state);
check_condition("state initially unloaded", mnemonic_is_loaded(&state) == 0);
rc = mnemonic_load(&state, valid_12);
check_condition("load valid 12-word mnemonic returns 0", rc == 0);
check_condition("state loaded after valid load", mnemonic_is_loaded(&state) == 1);
check_condition("word_count == 12", state.word_count == 12);
loaded_phrase = mnemonic_get_phrase(&state);
check_condition("mnemonic_get_phrase non-NULL when loaded", loaded_phrase != NULL);
check_condition("mnemonic_get_phrase matches input", loaded_phrase != NULL && strcmp(loaded_phrase, valid_12) == 0);
mnemonic_unload(&state);
check_condition("state unloaded after mnemonic_unload", mnemonic_is_loaded(&state) == 0);
check_condition("mnemonic_get_phrase NULL after unload", mnemonic_get_phrase(&state) == NULL);
rc = mnemonic_load(&state, invalid_11);
check_condition("reject invalid 11-word mnemonic", rc == -1);
check_condition("state remains unloaded after invalid 11-word load", mnemonic_is_loaded(&state) == 0);
build_25_word_phrase(invalid_25, sizeof(invalid_25));
rc = mnemonic_load(&state, invalid_25);
check_condition("reject invalid 25-word mnemonic", rc == -1);
check_condition("state remains unloaded after invalid 25-word load", mnemonic_is_loaded(&state) == 0);
rc = mnemonic_generate(12, generated_12, sizeof(generated_12));
check_condition("mnemonic_generate(12) returns 0", rc == 0);
check_condition("mnemonic_generate(12) output non-empty", rc == 0 && generated_12[0] != '\0');
check_condition("load generated 12-word mnemonic", rc == 0 && mnemonic_load(&state, generated_12) == 0);
check_condition("generated 12 word_count == 12", mnemonic_is_loaded(&state) && state.word_count == 12);
mnemonic_unload(&state);
rc = mnemonic_generate(24, generated_24, sizeof(generated_24));
check_condition("mnemonic_generate(24) returns 0", rc == 0);
check_condition("mnemonic_generate(24) output non-empty", rc == 0 && generated_24[0] != '\0');
check_condition("load generated 24-word mnemonic", rc == 0 && mnemonic_load(&state, generated_24) == 0);
check_condition("generated 24 word_count == 24", mnemonic_is_loaded(&state) && state.word_count == 24);
mnemonic_unload(&state);
check_condition("two generated mnemonics differ", strcmp(generated_12, generated_24) != 0);
if (g_failures == 0) {
printf("ALL TESTS PASSED\n");
return 0;
}
printf("TESTS FAILED: %d\n", g_failures);
return 1;
}