mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
64 lines
1.3 KiB
C
64 lines
1.3 KiB
C
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 [in] key "The key to use"
|
|
* @require key.len > 0 "The key must be at least 1 byte long"
|
|
**/
|
|
fn void Rc4.init(&self, char[] key)
|
|
{
|
|
// Init the state matrix
|
|
foreach (char i, &c : self.state) *c = i;
|
|
for (int i = 0, int j = 0; i < 256; i++)
|
|
{
|
|
j = (j + self.state[i] + key[i % key.len]) & 0xFF;
|
|
@swap(self.state[i], self.state[j]);
|
|
}
|
|
self.i = 0;
|
|
self.j = 0;
|
|
}
|
|
|
|
/**
|
|
* Encrypt or decrypt a sequence of bytes.
|
|
*
|
|
* @param [in] in "The input"
|
|
* @param [out] out "The output"
|
|
* @require in.len <= out.len "Output would overflow"
|
|
**/
|
|
fn void Rc4.crypt(&self, char[] in, char[] out)
|
|
{
|
|
uint i = self.i;
|
|
uint j = self.j;
|
|
char* state = &self.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];
|
|
}
|
|
self.i = i;
|
|
self.j = j;
|
|
}
|
|
|
|
/**
|
|
* Clear the rc4 state.
|
|
*
|
|
* @param [&out] self "The RC4 State"
|
|
**/
|
|
fn void Rc4.destroy(&self)
|
|
{
|
|
*self = {};
|
|
}
|