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 }