upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/test_btfchan.cpp
diff options
context:
space:
mode:
authorbitflash-coin <bookofshamers@outlook.com>2026-08-04 06:34:32 -0700
committerbitflash-coin <bookofshamers@outlook.com>2026-08-04 06:34:32 -0700
commit5ce650382352c1503f40abf08129ada69402af55 (patch)
tree6a18198901f1e2c4933f1ac53c9365eec512bf63 /src/test_btfchan.cpp
parentf34113291da7e5e3dc7d2468d4f9c212c05c584b (diff)
public commit
Diffstat (limited to 'src/test_btfchan.cpp')
-rw-r--r--src/test_btfchan.cpp83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/test_btfchan.cpp b/src/test_btfchan.cpp
new file mode 100644
index 0000000..5a66560
--- /dev/null
+++ b/src/test_btfchan.cpp
@@ -0,0 +1,83 @@
1// Standalone tests for btfchan (ported from Itzal echan.rs behavior).
2// Build (UCRT64):
3// g++ -std=gnu++14 test_btfchan.cpp btfchan.cpp -lsodium -o test_btfchan.exe
4
5#include "btfchan.h"
6#include <cstdio>
7#include <cstring>
8#include <string>
9#include <vector>
10
11using namespace btf;
12static int g_fail = 0;
13#define CHECK(cond, name) do { \
14 if (cond) { printf(" ok %s\n", name); } \
15 else { printf(" FAIL %s\n", name); g_fail++; } } while(0)
16
17int main()
18{
19 if (!ChanInit()) { printf("sodium init failed\n"); return 2; }
20
21 // Endpoint (service) has a static keypair; client only knows the static pub.
22 unsigned char ep_pk[32], ep_sk[32];
23 ChanKeypair(ep_pk, ep_sk);
24
25 printf("handshake_derives_same_key\n");
26 unsigned char eph_pub[32], k_client[32], k_endpoint[32];
27 CHECK(ChanClientHandshake(ep_pk, eph_pub, k_client), "client handshake ok");
28 CHECK(ChanEndpointHandshake(eph_pub, ep_sk, k_endpoint), "endpoint handshake ok");
29 CHECK(memcmp(k_client, k_endpoint, 32) == 0, "both sides derive the SAME shared key");
30
31 printf("encrypt_decrypt_roundtrip\n");
32 {
33 std::string msg = "one CPU one vote -- blinded over the wire";
34 std::vector<unsigned char> frame = ChanEncryptFrame(k_client,
35 (const unsigned char*)msg.data(), msg.size());
36 // frame = [len:4][nonce:24][ct||tag]
37 size_t bodylen = (frame[0]<<24)|(frame[1]<<16)|(frame[2]<<8)|frame[3];
38 CHECK(bodylen == frame.size() - 4, "length prefix correct");
39 std::vector<unsigned char> pt;
40 CHECK(ChanDecryptBody(k_endpoint, &frame[4], bodylen, pt), "endpoint decrypts");
41 CHECK(pt.size() == msg.size() && memcmp(pt.data(), msg.data(), msg.size()) == 0, "plaintext matches");
42 }
43
44 printf("tampered_ciphertext_fails\n");
45 {
46 std::string msg = "secret block";
47 std::vector<unsigned char> frame = ChanEncryptFrame(k_client,
48 (const unsigned char*)msg.data(), msg.size());
49 size_t bodylen = frame.size() - 4;
50 frame[frame.size()-1] ^= 0x01; // flip a bit in the tag/ciphertext
51 std::vector<unsigned char> pt;
52 CHECK(!ChanDecryptBody(k_endpoint, &frame[4], bodylen, pt), "tampered frame rejected");
53 }
54
55 printf("wrong_key_fails\n");
56 {
57 unsigned char other_pk[32], other_sk[32];
58 ChanKeypair(other_pk, other_sk);
59 unsigned char eph2[32], kbad[32];
60 ChanClientHandshake(other_pk, eph2, kbad); // box to a DIFFERENT endpoint
61 std::string msg = "for someone else";
62 std::vector<unsigned char> frame = ChanEncryptFrame(kbad,
63 (const unsigned char*)msg.data(), msg.size());
64 size_t bodylen = frame.size() - 4;
65 std::vector<unsigned char> pt;
66 CHECK(!ChanDecryptBody(k_endpoint, &frame[4], bodylen, pt), "our endpoint can't open someone else's box");
67 }
68
69 printf("empty_and_large_payloads\n");
70 {
71 std::vector<unsigned char> empty;
72 std::vector<unsigned char> f0 = ChanEncryptFrame(k_client, NULL, 0);
73 std::vector<unsigned char> o0;
74 CHECK(ChanDecryptBody(k_endpoint, &f0[4], f0.size()-4, o0) && o0.empty(), "empty payload roundtrips");
75 std::vector<unsigned char> big(200000, 0xAB);
76 std::vector<unsigned char> fb = ChanEncryptFrame(k_client, big.data(), big.size());
77 std::vector<unsigned char> ob;
78 CHECK(ChanDecryptBody(k_endpoint, &fb[4], fb.size()-4, ob) && ob == big, "200KB payload roundtrips");
79 }
80
81 printf("\n%s (%d failures)\n", g_fail == 0 ? "ALL TESTS PASSED" : "TESTS FAILED", g_fail);
82 return g_fail == 0 ? 0 : 1;
83}