From 1216dc2282f4bed843e04b207d4ebb372e7cb885 Mon Sep 17 00:00:00 2001 From: "Gu://em_" Date: Fri, 3 Jul 2026 21:58:29 +0200 Subject: [PATCH] Refactored (again) the packet module, added the identity and destination modules --- build.zig | 1 + src/destination.zig | 37 ++++++--- src/identity.zig | 48 ++++++++++++ src/packet.zig | 186 +++++++++++++++++++++++--------------------- src/root.zig | 6 +- 5 files changed, 178 insertions(+), 100 deletions(-) create mode 100644 src/identity.zig diff --git a/build.zig b/build.zig index cac537c..3576b66 100644 --- a/build.zig +++ b/build.zig @@ -49,6 +49,7 @@ pub fn build(b: *std.Build) void { ctx.addTestModule(root_module); ctx.addTestFile("src/packet.zig"); + ctx.addTestFile("src/identity.zig"); } diff --git a/src/destination.zig b/src/destination.zig index 77ea87a..e62749c 100644 --- a/src/destination.zig +++ b/src/destination.zig @@ -5,13 +5,14 @@ // pub const Type = enum(u2) { - single = 0x00, - group = 0x01, - plain = 0x02, - link = 0x03, + single = 0b0, + group = 0b01, + plain = 0b10, + link = 0b11, }; -pub const ProofStrategy = enum(u2) { +// From the reference implementation, seems weird +pub const ProofStrategy = enum(u8) { prove_none = 0x21, prove_app = 0x22, prove_all = 0x23, @@ -28,13 +29,31 @@ pub const Direction = enum(u2) { out = 0x12, }; -///////////////// Functions +///////////////// Enums // -//////// Helper functions -// +const Destination = struct { + + name: []const u8, + aspects: [][]const u8, + direction: Direction, + type: Type, -//////// Public functions + //////// Public functions + // + + // TODO + pub fn hash(self: *Destination, destination_buffer: [128]u8) !void { + _ = self; + _ = destination_buffer; + } + + // TODO + pub fn announce() !void {} +}; + + +///////////////// Helper functions // ///////////////// Tests diff --git a/src/identity.zig b/src/identity.zig new file mode 100644 index 0000000..dee9100 --- /dev/null +++ b/src/identity.zig @@ -0,0 +1,48 @@ +///////////////// Imports +// + +const CryptoEngine = @import("crypto.zig").Engine; + +///////////////// Constants +// + +///////////////// Enums +// + +///////////////// Structs +// + +// TODO +pub fn Identity(comptime crypto_engine: CryptoEngine) type { + _ = crypto_engine; + + return struct { + + //////// Fields + // + publicKey: []const u8, + privateKey: []const u8, + signature: []const u8, + hash: []const u8, + + //////// Functions + // + pub fn generate() !Identity { + return .{ + // .privateKey = crypto_engine.ed25519.generateKey(...), + // .signature = crypto_engine.x25519. + }; + } + }; +} + + +///////////////// Helper functions +// + +///////////////// Tests +// + +const std = @import("std"); + +const expect = std.testing.expect; diff --git a/src/packet.zig b/src/packet.zig index a38294e..7b465c4 100644 --- a/src/packet.zig +++ b/src/packet.zig @@ -1,13 +1,8 @@ -///////////////// Module +///////////////// Imports // -const Self = @This(); - -header: PacketHeader, -address1: [ADDRESS_SIZE]u8, -address2: [ADDRESS_SIZE]u8, -context: PacketContext, -data: []u8, +const CryptoEngine = @import("crypto.zig").Engine; +const Destination = @import("destination.zig"); ///////////////// Constants @@ -37,13 +32,6 @@ pub const PropagationType = enum(u1) { transport = 1 }; -pub const DestinationType = enum(u2) { - single = 0b0, - group = 0b01, - plain = 0b10, - link = 0b11, -}; - pub const PacketType = enum(u2) { data = 0b0, announce = 0b01, @@ -83,15 +71,89 @@ pub const PacketHeader = packed struct { header: HeaderType, context: ContextFlag, propagation: PropagationType, - destination: DestinationType, + destination: Destination.Type, packet: PacketType, hops: u8, }; -///////////////// Functions + +///////////////// Structs // -//////// Helper functions +const Packet = struct { + + const Self = @This(); + + ///////////////// Fields + // + + header: PacketHeader, + address1: [ADDRESS_SIZE]u8, + address2: [ADDRESS_SIZE]u8, + context: PacketContext, + data: []u8, + + + ///////////////// Public functions + // + + pub fn serialize(packet: *const Self, output_buffer: []u8) !usize { + const has_two_addresses = packet.header.header == HeaderType.type2; + + const target_size = getPacketSize(packet.data.len, has_two_addresses); + + if (output_buffer.len < target_size) { + return error.BufferTooShort; + } + + // Write buffer + var offset: usize = 0; + + @memcpy(output_buffer[offset .. offset + @sizeOf(PacketHeader)], asBytes(&packet.header)); + offset += @sizeOf(PacketHeader); + + @memcpy(output_buffer[offset .. offset + ADDRESS_SIZE], asBytes(&packet.address1)); + offset += ADDRESS_SIZE; + if (has_two_addresses) { + @memcpy(output_buffer[offset .. offset + ADDRESS_SIZE], asBytes(&packet.address2)); + offset += ADDRESS_SIZE; + } + + @memcpy(output_buffer[offset .. offset + @sizeOf(PacketContext)], asBytes(&packet.context)); + offset += @sizeOf(PacketContext); + + @memcpy(output_buffer[offset .. offset + packet.data.len], packet.data); + offset += packet.data.len; + + if (target_size != offset) { + return error.InternalError; + } + + return offset; + } + + // Reads the message buffer and builds the corresponding packet struct inside dest_packet + pub fn deserialize(packet: *Self, message_buffer: []u8) !void { + var offset: usize = 0; + + offset = try copyToPacket(&packet.header, message_buffer, offset, @sizeOf(PacketHeader)); + offset = try copyToPacket(&packet.address1, message_buffer, offset, ADDRESS_SIZE); + const has_two_addresses = packet.header.header == HeaderType.type2; + if (has_two_addresses) { + offset = try copyToPacket(&packet.address2, message_buffer, offset, ADDRESS_SIZE); + } + offset = try copyToPacket(&packet.context, message_buffer, offset, @sizeOf(PacketContext)); + offset = try copyToPacket(packet.data, message_buffer, offset, message_buffer.len - offset); + } + +}; + +// pub fn Packet(comptime crypto_engine: CryptoEngine) type { +// return struct {}; +// } + + +///////////////// Helper functions // // Copies serialized data (as a byte array) into any structure type @@ -116,58 +178,6 @@ fn getPacketSize(data_size: usize, has_two_addresses: bool) usize { return res; } -//////// Public functions -// - -pub fn serialize(packet: *const Self, output_buffer: []u8) !usize { - const has_two_addresses = packet.header.header == HeaderType.type2; - - const target_size = getPacketSize(packet.data.len, has_two_addresses); - - if (output_buffer.len < target_size) { - return error.BufferTooShort; - } - - // Write buffer - var offset: usize = 0; - - @memcpy(output_buffer[offset .. offset + @sizeOf(PacketHeader)], asBytes(&packet.header)); - offset += @sizeOf(PacketHeader); - - @memcpy(output_buffer[offset .. offset + ADDRESS_SIZE], asBytes(&packet.address1)); - offset += ADDRESS_SIZE; - if (has_two_addresses) { - @memcpy(output_buffer[offset .. offset + ADDRESS_SIZE], asBytes(&packet.address2)); - offset += ADDRESS_SIZE; - } - - @memcpy(output_buffer[offset .. offset + @sizeOf(PacketContext)], asBytes(&packet.context)); - offset += @sizeOf(PacketContext); - - @memcpy(output_buffer[offset .. offset + packet.data.len], packet.data); - offset += packet.data.len; - - if (target_size != offset) { - return error.InternalError; - } - - return offset; -} - -// Reads the message buffer and builds the corresponding packet struct inside dest_packet -pub fn deserialize(packet: *Self, message_buffer: []u8) !void { - var offset: usize = 0; - - offset = try copyToPacket(&packet.header, message_buffer, offset, @sizeOf(PacketHeader)); - offset = try copyToPacket(&packet.address1, message_buffer, offset, ADDRESS_SIZE); - const has_two_addresses = packet.header.header == HeaderType.type2; - if (has_two_addresses) { - offset = try copyToPacket(&packet.address2, message_buffer, offset, ADDRESS_SIZE); - } - offset = try copyToPacket(&packet.context, message_buffer, offset, @sizeOf(PacketContext)); - offset = try copyToPacket(packet.data, message_buffer, offset, message_buffer.len - offset); -} - ///////////////// Tests // @@ -181,8 +191,8 @@ const asBytes = std.mem.asBytes; // // Serializes the given packet and makes sure the output is correct -fn testPacketSerialization(packet: *const Self) !void { - const buf_size = comptime @sizeOf(Self) + MAX_DATA_SIZE; +fn testPacketSerialization(packet: *const Packet) !void { + const buf_size = comptime @sizeOf(Packet) + MAX_DATA_SIZE; var buf: [buf_size]u8 = undefined; const res: usize = try packet.serialize(&buf); const has_second_address = packet.header.header == HeaderType.type2; @@ -220,7 +230,7 @@ fn headersEql(h1: *const PacketHeader, h2: *const PacketHeader) bool { and h1.hops == h2.hops; } -fn packetsEql(p1: *const Self, p2: *const Self) bool { +fn packetsEql(p1: *const Packet, p2: *const Packet) bool { return headersEql(&p1.header, &p2.header) and memeql(u8, &p1.address1, &p2.address1) and memeql(u8, &p1.address2, &p2.address2) @@ -242,7 +252,7 @@ test "Basic serialization: header type 1, max data size" { .header = HeaderType.type1, .context = ContextFlag.set, .propagation = PropagationType.transport, - .destination = DestinationType.single, + .destination = Destination.Type.single, .packet = PacketType.announce, .hops = 0, }; @@ -250,7 +260,7 @@ test "Basic serialization: header type 1, max data size" { const data_size = MAX_DATA_SIZE; var data: [data_size]u8 = undefined; - const packet: Self = .{ + const packet: Packet = .{ .header = header, .address1 = undefined, .address2 = undefined, @@ -258,7 +268,7 @@ test "Basic serialization: header type 1, max data size" { .data = &data, }; - try packet.testPacketSerialization(); + try testPacketSerialization(&packet); } test "Basic serialization: header type 2, max data size" { @@ -267,7 +277,7 @@ test "Basic serialization: header type 2, max data size" { .header = HeaderType.type2, .context = ContextFlag.set, .propagation = PropagationType.transport, - .destination = DestinationType.single, + .destination = Destination.Type.single, .packet = PacketType.announce, .hops = 0, }; @@ -275,7 +285,7 @@ test "Basic serialization: header type 2, max data size" { const data_size = MAX_DATA_SIZE; var data: [data_size]u8 = undefined; - const packet: Self = .{ + const packet: Packet = .{ .header = header, .address1 = undefined, .address2 = undefined, @@ -283,7 +293,7 @@ test "Basic serialization: header type 2, max data size" { .data = &data, }; - try packet.testPacketSerialization(); + try testPacketSerialization(&packet); } test "Basic serialization: header type 1, medium data size" { @@ -292,7 +302,7 @@ test "Basic serialization: header type 1, medium data size" { .header = HeaderType.type1, .context = ContextFlag.set, .propagation = PropagationType.transport, - .destination = DestinationType.single, + .destination = Destination.Type.single, .packet = PacketType.announce, .hops = 0, }; @@ -300,7 +310,7 @@ test "Basic serialization: header type 1, medium data size" { const data_size = MAX_DATA_SIZE / 2 + 3; var data: [data_size]u8 = undefined; - const packet: Self = .{ + const packet: Packet = .{ .header = header, .address1 = undefined, .address2 = undefined, @@ -308,7 +318,7 @@ test "Basic serialization: header type 1, medium data size" { .data = &data, }; - try packet.testPacketSerialization(); + try testPacketSerialization(&packet); } test "Basic serialization: header type 2, medium data size" { @@ -317,7 +327,7 @@ test "Basic serialization: header type 2, medium data size" { .header = HeaderType.type2, .context = ContextFlag.set, .propagation = PropagationType.transport, - .destination = DestinationType.single, + .destination = Destination.Type.single, .packet = PacketType.announce, .hops = 0, }; @@ -325,7 +335,7 @@ test "Basic serialization: header type 2, medium data size" { const data_size = MAX_DATA_SIZE / 2 + 3; var data: [data_size]u8 = undefined; - const packet: Self = .{ + const packet: Packet = .{ .header = header, .address1 = undefined, .address2 = undefined, @@ -333,7 +343,7 @@ test "Basic serialization: header type 2, medium data size" { .data = &data, }; - try packet.testPacketSerialization(); + try testPacketSerialization(&packet); } test "Serialize / Deserialize Packet: Header type2, Medium data size" { @@ -342,7 +352,7 @@ test "Serialize / Deserialize Packet: Header type2, Medium data size" { .header = HeaderType.type2, .context = ContextFlag.set, .propagation = PropagationType.transport, - .destination = DestinationType.single, + .destination = Destination.Type.single, .packet = PacketType.announce, .hops = 0, }; @@ -350,7 +360,7 @@ test "Serialize / Deserialize Packet: Header type2, Medium data size" { const data_size = MAX_DATA_SIZE / 2 + 3; var data: [data_size]u8 = undefined; - const packet: Self = .{ + const packet: Packet = .{ .header = header, .address1 = undefined, .address2 = undefined, @@ -360,7 +370,7 @@ test "Serialize / Deserialize Packet: Header type2, Medium data size" { const buf_size = comptime @sizeOf(PacketHeader) + 2*ADDRESS_SIZE + @sizeOf(PacketContext) + data_size; var buf: [buf_size]u8 = undefined; - var res_packet: Self = undefined; + var res_packet: Packet = undefined; var res_data: [data_size]u8 = undefined; res_packet.data = &res_data; _ = try packet.serialize(&buf); diff --git a/src/root.zig b/src/root.zig index 9ab6784..0dc2d60 100644 --- a/src/root.zig +++ b/src/root.zig @@ -4,10 +4,10 @@ const crypto = @import("crypto.zig"); // You can pass your own cryptographic functions to take advantage of your // platform or use the library's software implementations for compatibility // Use its return value to access the library modules -pub fn RnsZero(comptime cryptoProvider: crypto.PartialEngine) type { - const cryptoEngine = crypto.resolveEngine(cryptoProvider); - _ = cryptoEngine; +pub fn RnsZero(comptime crypto_provider: crypto.PartialEngine) type { + const crypto_engine = crypto.resolveEngine(crypto_provider); return struct { pub const packet = @import("packet.zig"); + pub const identity = @import("identity.zig").Identity(crypto_engine); }; }