Added arcfour crypto.

This commit is contained in:
Christoffer Lerno
2022-12-30 16:34:31 +01:00
parent 23a78a9ae5
commit f8a505754d
3 changed files with 83 additions and 0 deletions

2
lib/std/crypto/crypto.c3 Normal file
View File

@@ -0,0 +1,2 @@
module std::crypto;

65
lib/std/crypto/rc4.c3 Normal file
View File

@@ -0,0 +1,65 @@
module std::crypto::rc4;
// Copyright (c) 2021 Christoffer Lerno. All rights reserved.
// Use of this source code is governed by the MIT license
// a copy of which can be found in the LICENSE_STDLIB file.
struct Rc4
{
uint i, j;
char[256] state;
}
/**
* Initialize the RC4 state.
*
* @param [inout] this "The RC4 state"
* @param [in] key "The key to use"
* @require key.len > 0 "The key must be at least 1 byte long"
**/
fn void Rc4.init(Rc4* this, char[] key)
{
// Init the state matrix
foreach (char i, &c : this.state) *c = i;
for (int i = 0, int j = 0; i < 256; i++)
{
j = (j + this.state[i] + key[i % key.len]) & 0xFF;
@swap(this.state[i], this.state[j]);
}
this.i = 0;
this.j = 0;
}
/**
* Encrypt or decrypt a sequence of bytes.
*
* @param [inout] this "The RC4 State"
* @param [in] in "The input"
* @param [out] out "The output"
* @require in.len <= out.len "Output would overflow"
**/
fn void Rc4.crypt(Rc4* this, char[] in, char[] out)
{
uint i = this.i;
uint j = this.j;
char* state = &this.state;
isz len = in.len;
foreach (idx, c : in)
{
i = (i + 1) & 0xFF;
j = (j + state[i]) & 0xFF;
@swap(state[i], state[j]);
out[idx] = in[idx] ^ state[(state[i] + state[j]) & 0xFF];
}
this.i = i;
this.j = j;
}
/**
* Clear the rc4 state.
*
* @param [out] this "The RC4 State"
**/
fn void Rc4.destroy(Rc4* this)
{
*this = {};
}

View File

@@ -0,0 +1,16 @@
import std::crypto;
import std::io;
fn void! rc_crypt() @test
{
Rc4 rc;
rc.init(&&x"63727970746969");
char[200] x;
char[] text = "The quick brown fox jumps over the lazy dog.";
rc.crypt(text, &x);
char[*] res = x"2ac2fecdd8fbb84638e3a4
820eb205cc8e29c28b9d5d
6b2ef974f311964971c90e
8b9ca16467ef2dc6fc3520";
assert(res[:text.len] == x[:text.len]);
}