Skip to content

Instantly share code, notes, and snippets.

@notcancername
Created July 29, 2024 14:28
Show Gist options
  • Save notcancername/d2be6177934b0598d71954f3e4ec20e1 to your computer and use it in GitHub Desktop.
Save notcancername/d2be6177934b0598d71954f3e4ec20e1 to your computer and use it in GitHub Desktop.
random RC4 implementation I wrote at some point
pub const Rc4 = struct {
s: [256]u8 = undefined,
i: u8 = 0,
j: u8 = 0,
pub fn init(key: []const u8) Rc4 {
var self = Rc4{};
for(&self.s, 0..) |*c, i| c.* = @intCast(i);
{
var i: u16 = 0;
var j: u8 = 0;
while(i < 255) : (i += 1) {
j = j +% self.s[i] +% key[i % key.len];
std.mem.swap(u8, &self.s[i], &self.s[j]);
}
}
return self;
}
pub fn get(self: *Rc4) u8 {
self.i +%= 1;
self.j +%= self.s[self.i];
std.mem.swap(u8, &self.s[self.i], &self.s[self.j]);
return self.s[self.s[self.i] +% self.s[self.j]];
}
pub fn deinit(self: *Rc4) void {
std.crypto.utils.secureZero(u8, &self.s);
self.j = 0;
self.i = 0;
}
pub fn process(self: *Rc4, ciphertext: []u8, plaintext: []const u8) void {
for(plaintext, 0..) |c, i| ciphertext[i] = c ^ self.get();
}
};
test "Rc4" {
var state = Rc4.init("Key");
defer state.deinit();
const plain = "Plaintext";
var dst: [plain.len]u8 = undefined;
state.process(&dst, plain);
try std.testing.expectEqual([_]u8{0xbb,0xf3,0x16,0xe8,0xd9,0x40,0xaf,0x0a,0xd3}, dst);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment