mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Added arcfour crypto.
This commit is contained in:
2
lib/std/crypto/crypto.c3
Normal file
2
lib/std/crypto/crypto.c3
Normal file
@@ -0,0 +1,2 @@
|
||||
module std::crypto;
|
||||
|
||||
65
lib/std/crypto/rc4.c3
Normal file
65
lib/std/crypto/rc4.c3
Normal 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 = {};
|
||||
}
|
||||
16
test/unit/stdlib/crypto/rc4.c3
Normal file
16
test/unit/stdlib/crypto/rc4.c3
Normal 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]);
|
||||
}
|
||||
Reference in New Issue
Block a user