const std = @import("std"); const c = @cImport({ @cInclude("openssl/aes.h"); @cInclude("openssl/err.h"); }); const stdout = std.io.getStdOut().writer(); fn print(comptime str: []const u8, args: anytype) void { stdout.print(str, args) catch unreachable; } fn println(comptime str: []const u8, args: anytype) void { print(str ++ "\n", args); } pub fn main() !void { var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); defer arena.deinit(); var alloc = arena.allocator(); const args = try std.process.argsAlloc(alloc); const base_text = "6CEA122F3B42975BDBBEB7F2C6EFAF9FD5A54FDD6233276C55358F4FBCB7A9492D0451B7019C69FAEF5FD23103FF7EC521FBBC6516CA2CB2CA663D5DBFF86BCF"; var text = try alloc.alloc(u8, base_text.len); defer alloc.free(text); std.mem.copyForwards(u8, text, base_text); if (args.len == 2) { if (args[1].len != 128) { println("Invalid args", .{}); return; } text = args[1]; std.mem.copyForwards(u8, text, args[1]); println("Using cipher={s}", .{text}); } var cipher = try alloc.alloc(u8, text.len / 2); var chs = try alloc.alloc(u8, text.len / 2); for (0..(text.len / 2)) |_i| { var i = _i * 2; var e = i + 2; var r = try std.fmt.parseInt(u8, text[i..e], 16); cipher[_i] = r; chs[_i] = r; } var plain = "Please meet me at Guildford Station: 7:00 be prompt!"; var plair = " 8 3 "; var number_of_blocks = text.len / 2 / 16; println("blocks:", .{}); for (0..number_of_blocks) |i| { var start = i * 16; var end = start + 16; if (end > plain.len) { end = plain.len; } println("{}: {s}", .{ i + 1, plain[start..end] }); println(" {s}", .{plair[start..end]}); } var changes = std.ArrayList(usize).init(alloc); defer changes.deinit(); for (plair, 0..) |char, i| { if (char != ' ') { try changes.append(i); } } for (changes.items) |a| { println("Change on pos: {} '{c}'(0x{x:0>2}) -> '{c}'(0x{x:0>2})", .{ a + 1, plain[a], plain[a], plair[a], plair[a] }); println("This will update on block {} at pos {}", .{ 1 + (a - 16) / 16, 1 + (a - 16) % 16 }); println("Current cypher 0x{x:0>2}", .{cipher[a - 16]}); var after_aes = cipher[a - 16] ^ plain[a]; println("Value after aes func curent ^ plain = 0x{x:0>2}", .{after_aes}); var new_value = after_aes ^ plair[a]; println("New value after_aes ^ to_replace = 0x{x:0>2}", .{new_value}); println("Update cypher 0x{x:0>2} -> 0x{x:0>2}", .{ cipher[a - 16], new_value }); chs[a - 16] = new_value; println("\n\n\n\n", .{}); } print("Old cipher {}: ", .{cipher.len}); for (cipher, chs) |item, is_change| { if (item != is_change) { print("{c}[1m", .{std.ascii.control_code.esc}); } print("{x:0>2}", .{item}); if (item != is_change) { print("{c}[0m", .{std.ascii.control_code.esc}); } } println("", .{}); print(" ", .{}); for (cipher, chs) |item, is_change| { if (item != is_change) { print("\\/", .{}); } else { print(" ", .{}); } } println("", .{}); print("New cipher {}: ", .{cipher.len}); for (cipher, chs) |item, is_change| { if (item != is_change) { print("{c}[1m", .{std.ascii.control_code.esc}); } print("{x:0>2}", .{is_change}); if (item != is_change) { print("{c}[0m", .{std.ascii.control_code.esc}); } } println("", .{}); }