lib/reticulum/src/properties/announce.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 const hypothesis = @import("hypothesis");
 3 const reticulum = @import("reticulum");
 4 
 5 const announce = reticulum.destination.announce;
 6 const identity = reticulum.identity;
 7 const seed: u64 = 0x5245_5449_4355_4c55;
 8 
 9 const Rebuild = struct {
10     pub fn property(data: *hypothesis.ConjectureData, _: std.mem.Allocator) !void {
11         const key_input = try data.drawBytes(identity.key_bytes, identity.key_bytes);
12         const name_input = try data.drawBytes(10, 10);
13         const random_input = try data.drawBytes(10, 10);
14         const rotating_input = try data.drawBytes(32, 32);
15         const use_rotating = try data.drawInteger(0, 1, 0) == 1;
16         const app_length: usize = @intCast(try data.drawInteger(0, 128, 0));
17         const app_data = try data.drawBytes(app_length, app_length);
18         var private = identity.Private.fromBytes(key_input[0..identity.key_bytes].*);
19         defer private.zero();
20 
21         const name_hash = name_input[0..10].*;
22         var destination_hasher = reticulum.hash.Hasher.init();
23         destination_hasher.update(&name_hash);
24         destination_hasher.update(&private.hash());
25         const destination_hash = destination_hasher.finalTruncated();
26         var output: [announce.payload_bytes_max]u8 = undefined;
27         const payload = try announce.build(.{
28             .destination_hash = destination_hash,
29             .name_hash = name_hash,
30             .random_hash = random_input[0..10].*,
31             .rotating_public_key = if (use_rotating) rotating_input[0..32].* else null,
32             .app_data = app_data,
33         }, &private, &output);
34         const context_flag: u1 = if (use_rotating) 1 else 0;
35         const decoded = try announce.validate(destination_hash, .one, context_flag, payload);
36         try std.testing.expectEqualSlices(u8, app_data, decoded.app_data);
37     }
38 };
39 
40 const Total = struct {
41     pub fn property(data: *hypothesis.ConjectureData, _: std.mem.Allocator) !void {
42         const payload_length: usize = @intCast(try data.drawInteger(0, 500, 0));
43         const payload = try data.drawBytes(payload_length, payload_length);
44         const hash_input = try data.drawBytes(16, 16);
45         const context_flag: u1 = @intCast(try data.drawInteger(0, 1, 0));
46         const header: reticulum.wire.HeaderType = if (try data.drawBoolean()) .two else .one;
47         const hash = hash_input[0..16].*;
48         if (announce.validate(hash, header, context_flag, payload)) |_| {} else |_| {}
49     }
50 };
51 
52 fn settings() hypothesis.Settings {
53     return hypothesis.Settings.quick()
54         .withSeed(seed)
55         .withDatabase("zig-out/hypothesis-failures/reticulum");
56 }
57 
58 test "property: Reticulum@1.5.0 rebuilt announces validate" {
59     try hypothesis.checkNamed(Rebuild, "reticulum-announce-rebuild", settings());
60 }
61 
62 test "property: Reticulum@1.5.0 announce validation is total" {
63     try hypothesis.checkNamed(Total, "reticulum-announce-total", settings());
64 }