aboutsummaryrefslogtreecommitdiff
path: root/tests/test.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test.c')
-rw-r--r--tests/test.c170
1 files changed, 170 insertions, 0 deletions
diff --git a/tests/test.c b/tests/test.c
new file mode 100644
index 0000000..499ef50
--- /dev/null
+++ b/tests/test.c
@@ -0,0 +1,170 @@
+/*
+* Copyright (c) 2024 Vaughn Nugent
+*
+* Library: noscrypt
+* Package: noscrypt
+* File: test.c
+*
+* noscrypt is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published
+* by the Free Software Foundation, either version 2 of the License,
+* or (at your option) any later version.
+*
+* noscrypt is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with noscrypt. If not, see http://www.gnu.org/licenses/.
+*/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "../src/noscrypt.h"
+#include "../include/mbedtls/sha256.h"
+
+#if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32)
+ #define IS_WINDOWS
+#endif
+
+#ifdef IS_WINDOWS
+
+ #include <windows.h>
+ #include <wincrypt.h>
+
+ //Prints a string literal to the console
+ #define PRINTL(x) printf(x); printf("\r\n");
+ #define TEST(x) printf("Testing %s\n", #x); if(!(x)) { printf("Test failed!\n"); return 1; } else { printf("Test passed\n\n"); }
+ #define TASSERT(x) if(!(x)) { printf("ERROR! Internal test assumption failed: %s.\n Aborting tests...\n", #x); ExitProcess(1); }
+#else
+ #include <stdlib.h>
+
+ //Prints a string literal to the console
+ #define PRINTL(x) printf(x); printf("\n");
+ #define TEST(x) printf("Testing %s\n", #x); if(!(x)) { printf("Test failed!\n"); return 1; } else { printf("Test passed\n\n"); }
+ #define TASSERT(x) if(!(x)) { printf("Internal assumption failed: %s\n", #x); exit(1); }
+#endif
+
+static void FillRandomData(uint8_t* pbBuffer, size_t length);
+static int TestEcdsa(NCContext* context);
+
+int main(char* argv[], int argc)
+{
+ NCContext ctx;
+ uint8_t ctxRandom[32];
+
+ PRINTL("Begining basic noscrypt tests\n")
+
+ FillRandomData(ctxRandom, 32);
+
+ //Context struct size should aways match the size of the struct returned by NCGetContextStructSize
+ TEST(NCGetContextStructSize() == sizeof(NCContext))
+
+ TEST(NCInitContext(&ctx, ctxRandom) == NC_SUCCESS)
+
+ if (TestEcdsa(&ctx) != 0)
+ {
+ return 1;
+ }
+
+ PRINTL("ECDSA tests passed\n")
+
+ TEST(NCDestroyContext(&ctx) == NC_SUCCESS)
+
+ return 0;
+}
+
+static void _sha256(const uint8_t* data, size_t length, uint8_t digest[32])
+{
+ mbedtls_sha256_context sha256;
+ mbedtls_sha256_init(&sha256);
+ TASSERT(0 == mbedtls_sha256_starts(&sha256, 0))
+ TASSERT(0 == mbedtls_sha256_update(&sha256, data, length))
+ TASSERT(0 == mbedtls_sha256_finish(&sha256, digest))
+ mbedtls_sha256_free(&sha256);
+}
+
+static const char* message = "Test message to sign";
+
+static int TestEcdsa(NCContext* context)
+{
+ uint8_t digestToSign[32];
+ uint8_t secretKey[NC_SEC_KEY_SIZE];
+ uint8_t publicKey[NC_PUBKEY_SIZE];
+ uint8_t sigEntropy[32];
+ uint8_t invalidSig[64];
+ NCSecretKey* secKey;
+ NCPublicKey* pubKey;
+
+ PRINTL("Begining basic Nostr ECDSA tests")
+
+ //Convert to internal key structs
+ secKey = NCToSecKey(secretKey);
+ pubKey = NCToPubKey(publicKey);
+
+ TEST((&secKey->key) == &secretKey);
+
+ //Init a new secret key with random data
+ FillRandomData(secretKey, sizeof(secretKey));
+ FillRandomData(invalidSig, sizeof(invalidSig));
+ FillRandomData(sigEntropy, sizeof(sigEntropy));
+
+ //Verify that the secret key is valid for the curve
+ TEST(NCValidateSecretKey(context, secKey) == NC_SUCCESS);
+
+ //Generate a public key from the secret key
+ TEST(NCGetPublicKey(context, secKey, pubKey) == NC_SUCCESS);
+
+ //Sign and verify digest
+ {
+ uint8_t sig[64];
+
+ //compute sha256 of the test string
+ _sha256((uint8_t*)message, strlen(message), digestToSign);
+
+ TEST(NCSignDigest(context, secKey, sigEntropy, digestToSign, sig) == NC_SUCCESS);
+ TEST(NCVerifyDigest(context, pubKey, digestToSign, sig) == NC_SUCCESS);
+ }
+
+ //Sign and verify raw data
+ {
+ uint8_t sig[64];
+ TEST(NCSignData(context, secKey, sigEntropy, (uint8_t*)message, strlen(message), sig) == NC_SUCCESS);
+ TEST(NCVerifyData(context, pubKey, (uint8_t*)message, strlen(message), sig) == NC_SUCCESS);
+ }
+
+ //test verification of invalid signature
+ {
+ TEST(NCVerifyDigest(context, pubKey, digestToSign, invalidSig) == E_INVALID_ARG);
+ }
+
+ return 0;
+}
+
+static const char* encMessage = "Test message to encrypt";
+
+static int TestEcdh(NCContext* ctx)
+{
+ PRINTL("Begining basic Nostr Encryption tests")
+}
+
+static void FillRandomData(uint8_t* pbBuffer, size_t length)
+{
+
+#ifdef IS_WINDOWS
+
+ HCRYPTPROV hCryptProv;
+
+ TASSERT(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0));
+ TASSERT(CryptGenRandom(hCryptProv, (DWORD)length, pbBuffer))
+ TASSERT(CryptReleaseContext(hCryptProv, 0));
+#else
+ FILE* f = fopen("/dev/urandom", "rb");
+ TASSERT(f != NULL);
+ TASSERT(fread(pbBuffer, 1, length, f) == length);
+ fclose(f);
+#endif
+} \ No newline at end of file