lib/reticulum/src/properties/ifac.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const hypothesis = @import("hypothesis");
3 const reticulum = @import("reticulum");
4
5 const ifac = reticulum.interface.ifac;
6 const round_trip_seed: u64 = 0x5235_4349_4641_4301;
7 const totality_seed: u64 = 0x5235_4349_4641_4302;
8
9 fn settings(seed: u64) hypothesis.Settings {
10 return hypothesis.Settings.quick()
11 .withSeed(seed)
12 .withDatabase("zig-out/hypothesis-failures/reticulum");
13 }
14
15 fn drawSize(data: *hypothesis.ConjectureData) !ifac.Size {
16 const value: u8 = @intCast(try data.drawInteger(1, 64, 16));
17 return ifac.Size.fromByte(value) orelse unreachable;
18 }
19
20 const RoundTrip = struct {
21 pub fn property(data: *hypothesis.ConjectureData, _: std.mem.Allocator) !void {
22 const key_input = try data.drawBytes(ifac.key_bytes, ifac.key_bytes);
23 var key: ifac.Key = key_input[0..ifac.key_bytes].*;
24 defer std.crypto.secureZero(u8, &key);
25 const raw_length: usize = @intCast(try data.drawInteger(2, reticulum.wire.mtu, 2));
26 const raw_input = try data.drawBytes(raw_length, raw_length);
27 var raw_storage: [reticulum.wire.mtu]u8 = undefined;
28 @memcpy(raw_storage[0..raw_length], raw_input);
29 raw_storage[0] &= 0x7f;
30 const raw = raw_storage[0..raw_length];
31 const size = try drawSize(data);
32 var masked_storage: [ifac.max_frame_bytes]u8 = undefined;
33 const masked = try ifac.apply(&key, size, raw, &masked_storage);
34 var stripped_storage: [reticulum.wire.mtu]u8 = undefined;
35 const stripped = try ifac.strip(&key, size, masked, &stripped_storage);
36 try std.testing.expectEqualSlices(u8, raw, stripped);
37 }
38 };
39
40 const TotalStrip = struct {
41 pub fn property(data: *hypothesis.ConjectureData, _: std.mem.Allocator) !void {
42 const key_input = try data.drawBytes(ifac.key_bytes, ifac.key_bytes);
43 var key: ifac.Key = key_input[0..ifac.key_bytes].*;
44 defer std.crypto.secureZero(u8, &key);
45 const size = try drawSize(data);
46 const masked = try data.drawBytes(0, ifac.max_frame_bytes + 64);
47 var raw_storage: [reticulum.wire.mtu]u8 = undefined;
48 _ = ifac.strip(&key, size, masked, &raw_storage) catch return;
49 }
50 };
51
52 test "property: Reticulum@1.5.0 RNS/Transport.py:1244-1687 IFAC round trip" {
53 try hypothesis.checkNamed(
54 RoundTrip,
55 "reticulum-ifac-round-trip",
56 settings(round_trip_seed),
57 );
58 }
59
60 test "property: Reticulum@1.5.0 RNS/Transport.py:1636-1687 IFAC strip is total" {
61 try hypothesis.checkNamed(
62 TotalStrip,
63 "reticulum-ifac-strip-total",
64 settings(totality_seed),
65 );
66 }