Skip to content

Commit 6e7e900

Browse files
add rust md5, aes repos
1 parent 8b37790 commit 6e7e900

File tree

6 files changed

+876
-0
lines changed

6 files changed

+876
-0
lines changed

rust/aes/Cargo.toml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[package]
2+
name = "aes"
3+
version = "0.1.0"
4+
authors = ["Alanscut <[email protected]>"]
5+
edition = "2018"
6+
7+
[lib]
8+
crate-type = ["cdylib", "rlib"]
9+
10+
[features]
11+
default = ["console_error_panic_hook"]
12+
13+
[dependencies]
14+
wasm-bindgen = "0.2.63"
15+
16+
# The `console_error_panic_hook` crate provides better debugging of panics by
17+
# logging them with `console.error`. This is great for development, but requires
18+
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
19+
# code size when deploying.
20+
console_error_panic_hook = { version = "0.1.6", optional = true }
21+
22+
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
23+
# compared to the default allocator's ~10K. It is slower than the default
24+
# allocator, however.
25+
#
26+
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
27+
wee_alloc = { version = "0.4.5", optional = true }
28+
29+
[dev-dependencies]
30+
wasm-bindgen-test = "0.3.13"
31+
32+
[profile.release]
33+
lto=true
34+
opt-level = 3

rust/aes/src/lib.rs

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
mod utils;
2+
3+
use wasm_bindgen::prelude::*;
4+
use crate::utils::{getSbox, getInvSbox, getSubMix0, getSubMix1, getSubMix2, getSubMix3, getInvSubMix0, getInvSubMix1, getInvSubMix2, getInvSubMix3, getKeySchedules, getInvKeySchedules};
5+
6+
#[wasm_bindgen]
7+
extern "C" {}
8+
9+
#[wasm_bindgen]
10+
pub fn getKeySchedule(keySize: u32, keyWords: &[u32]) -> Vec<u32> {
11+
let keySchedule = getKeySchedules(keySize, keyWords);
12+
keySchedule
13+
}
14+
15+
#[wasm_bindgen]
16+
pub fn getInvKeySchedule(keySize: u32, keyWords: &[u32]) -> Vec<u32> {
17+
let keySchedule = getKeySchedules(keySize, keyWords);
18+
let invKeySchedule = getInvKeySchedules(keySize, keyWords, keySchedule);
19+
invKeySchedule
20+
}
21+
22+
#[wasm_bindgen]
23+
pub fn doEncrypt(mode: &str, nRounds: usize, nWordsReady: usize, blockSize: usize, iv: &[u32], dataWords: &mut [u32], keySchedule: &[u32]) {
24+
if nWordsReady > 0 {
25+
let mut offset: usize = 0;
26+
match mode.to_lowercase().as_str() {
27+
"cbc" => {
28+
let mut prevBlock = iv[0..blockSize].to_vec();
29+
while offset < nWordsReady {
30+
xorBlock(blockSize, prevBlock, dataWords, offset);
31+
encryptBlock(nRounds, dataWords, offset, keySchedule);
32+
prevBlock = dataWords[offset..offset + blockSize].to_vec();
33+
offset += blockSize;
34+
}
35+
}
36+
"ecb" => {
37+
while offset < nWordsReady {
38+
encryptBlock(nRounds, dataWords, offset, keySchedule);
39+
offset += blockSize;
40+
}
41+
}
42+
"cfb" => {
43+
let mut prevBlock = iv[0..blockSize].to_vec();
44+
while offset < nWordsReady {
45+
let mut keystream = prevBlock;
46+
encryptBlock(nRounds, &mut keystream, 0, keySchedule);
47+
xorBlock(blockSize, keystream.to_owned(), dataWords, offset);
48+
prevBlock = dataWords[offset..offset + blockSize].to_vec();
49+
offset += blockSize;
50+
}
51+
}
52+
"ofb" => {
53+
let mut keystream = iv[0..blockSize].to_vec();
54+
while offset < nWordsReady {
55+
encryptBlock(nRounds, &mut keystream, 0, keySchedule);
56+
xorBlock(blockSize, keystream.to_owned(), dataWords, offset);
57+
offset += blockSize;
58+
}
59+
}
60+
"ctr" => {
61+
let mut counter = iv[0..blockSize].to_vec();
62+
let mut keystream;
63+
while offset < nWordsReady {
64+
keystream = counter.clone();
65+
encryptBlock(nRounds, &mut keystream, 0, keySchedule);
66+
// Increment counter
67+
counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0;
68+
xorBlock(blockSize, keystream.to_owned(), dataWords, offset);
69+
offset += blockSize;
70+
}
71+
}
72+
_ => {}
73+
}
74+
}
75+
}
76+
77+
#[wasm_bindgen]
78+
pub fn doDecrypt(mode: &str, nRounds: usize, nWordsReady: usize, blockSize: usize, iv: &[u32], dataWords: &mut [u32], keySchedule: &[u32], invKeySchedule: &[u32]) {
79+
if nWordsReady > 0 {
80+
let mut offset: usize = 0;
81+
match mode.to_lowercase().as_str() {
82+
"cbc" => {
83+
let mut prevBlock = iv[0..blockSize].to_vec();
84+
while offset < nWordsReady {
85+
let thisBlock = dataWords[offset..offset + blockSize].to_vec();
86+
decryptBlock(nRounds, dataWords, offset, invKeySchedule);
87+
xorBlock(blockSize, prevBlock, dataWords, offset);
88+
prevBlock = thisBlock;
89+
offset += blockSize;
90+
}
91+
}
92+
"ecb" => {
93+
while offset < nWordsReady {
94+
decryptBlock(nRounds, dataWords, offset, invKeySchedule);
95+
offset += blockSize;
96+
}
97+
}
98+
"cfb" => {
99+
let mut prevBlock = iv[0..blockSize].to_vec();
100+
while offset < nWordsReady {
101+
let thisBlock = dataWords[offset..offset + blockSize].to_vec();
102+
let keystream = &mut prevBlock;
103+
encryptBlock(nRounds, keystream, 0, keySchedule);
104+
xorBlock(blockSize, keystream.to_owned(), dataWords, offset);
105+
prevBlock = thisBlock;
106+
offset += blockSize;
107+
}
108+
}
109+
"ofb" => {
110+
let mut keystream = iv[0..blockSize].to_vec();
111+
while offset < nWordsReady {
112+
encryptBlock(nRounds, &mut keystream, 0, keySchedule);
113+
xorBlock(blockSize, keystream.to_owned(), dataWords, offset);
114+
offset += blockSize;
115+
}
116+
}
117+
"ctr" => {
118+
let mut counter = iv[0..blockSize].to_vec();
119+
let mut keystream;
120+
while offset < nWordsReady {
121+
keystream = counter.clone();
122+
encryptBlock(nRounds, &mut keystream, 0, keySchedule);
123+
// Increment counter
124+
counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0;
125+
xorBlock(blockSize, keystream.to_owned(), dataWords, offset);
126+
offset += blockSize;
127+
}
128+
}
129+
_ => {}
130+
}
131+
}
132+
}
133+
134+
fn xorBlock(blockSize: usize, block: Vec<u32>, words: &mut [u32], offset: usize) {
135+
// XOR blocks
136+
for i in 0..blockSize {
137+
words[offset + i] ^= &block[i];
138+
}
139+
}
140+
141+
fn encryptBlock(nRounds: usize, dataWords: &mut [u32], offset: usize, keySchedule: &[u32]) {
142+
let SUB_MIX_0 = &getSubMix0();
143+
let SUB_MIX_1 = &getSubMix1();
144+
let SUB_MIX_2 = &getSubMix2();
145+
let SUB_MIX_3 = &getSubMix3();
146+
let SBOX = &getSbox();
147+
148+
doCryptBlock(nRounds, dataWords, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);
149+
}
150+
151+
fn decryptBlock(nRounds: usize, dataWords: &mut [u32], offset: usize, invKeySchedule: &[u32]) {
152+
// Swap 2nd and 4th rows
153+
let mut t = dataWords[offset + 1];
154+
dataWords[offset + 1] = dataWords[offset + 3];
155+
dataWords[offset + 3] = t;
156+
157+
let INV_SUB_MIX_0 = &getInvSubMix0();
158+
let INV_SUB_MIX_1 = &getInvSubMix1();
159+
let INV_SUB_MIX_2 = &getInvSubMix2();
160+
let INV_SUB_MIX_3 = &getInvSubMix3();
161+
let INV_SBOX = &getInvSbox();
162+
163+
doCryptBlock(nRounds, dataWords, offset, invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);
164+
165+
// Inv swap 2nd and 4th rows
166+
t = dataWords[offset + 1];
167+
dataWords[offset + 1] = dataWords[offset + 3];
168+
dataWords[offset + 3] = t;
169+
}
170+
171+
fn doCryptBlock(nRounds: usize, dataWords: &mut [u32], offset: usize, keySchedule: &[u32], SUB_MIX_0: &[u32], SUB_MIX_1: &[u32], SUB_MIX_2: &[u32], SUB_MIX_3: &[u32], SBOX: &[u32]) {
172+
// Get input, add round key
173+
let mut s0 = dataWords[offset] ^ keySchedule[0];
174+
let mut s1 = dataWords[offset + 1] ^ keySchedule[1];
175+
let mut s2 = dataWords[offset + 2] ^ keySchedule[2];
176+
let mut s3 = dataWords[offset + 3] ^ keySchedule[3];
177+
178+
// Key schedule row counter
179+
let mut ksRow = 4;
180+
181+
// Rounds
182+
for round in 1..nRounds {
183+
// Shift rows, sub bytes, mix columns, add round key
184+
let t0 = SUB_MIX_0[(s0 >> 24) as usize] ^ SUB_MIX_1[((s1 >> 16) & 0xff) as usize] ^ SUB_MIX_2[((s2 >> 8) & 0xff) as usize] ^ SUB_MIX_3[(s3 & 0xff) as usize] ^ keySchedule[ksRow];
185+
ksRow += 1;
186+
let t1 = SUB_MIX_0[(s1 >> 24) as usize] ^ SUB_MIX_1[((s2 >> 16) & 0xff) as usize] ^ SUB_MIX_2[((s3 >> 8) & 0xff) as usize] ^ SUB_MIX_3[(s0 & 0xff) as usize] ^ keySchedule[ksRow];
187+
ksRow += 1;
188+
let t2 = SUB_MIX_0[(s2 >> 24) as usize] ^ SUB_MIX_1[((s3 >> 16) & 0xff) as usize] ^ SUB_MIX_2[((s0 >> 8) & 0xff) as usize] ^ SUB_MIX_3[(s1 & 0xff) as usize] ^ keySchedule[ksRow];
189+
ksRow += 1;
190+
let t3 = SUB_MIX_0[(s3 >> 24) as usize] ^ SUB_MIX_1[((s0 >> 16) & 0xff) as usize] ^ SUB_MIX_2[((s1 >> 8) & 0xff) as usize] ^ SUB_MIX_3[(s2 & 0xff) as usize] ^ keySchedule[ksRow];
191+
ksRow += 1;
192+
193+
// Update state
194+
s0 = t0;
195+
s1 = t1;
196+
s2 = t2;
197+
s3 = t3;
198+
}
199+
200+
// Shift rows, sub bytes, add round key
201+
let t0 = ((SBOX[(s0 >> 24) as usize] << 24) | (SBOX[((s1 >> 16) & 0xff) as usize] << 16) | (SBOX[((s2 >> 8) & 0xff) as usize] << 8) | SBOX[(s3 & 0xff) as usize]) ^ keySchedule[ksRow];
202+
ksRow += 1;
203+
let t1 = ((SBOX[(s1 >> 24) as usize] << 24) | (SBOX[((s2 >> 16) & 0xff) as usize] << 16) | (SBOX[((s3 >> 8) & 0xff) as usize] << 8) | SBOX[(s0 & 0xff) as usize]) ^ keySchedule[ksRow];
204+
ksRow += 1;
205+
let t2 = ((SBOX[(s2 >> 24) as usize] << 24) | (SBOX[((s3 >> 16) & 0xff) as usize] << 16) | (SBOX[((s0 >> 8) & 0xff) as usize] << 8) | SBOX[(s1 & 0xff) as usize]) ^ keySchedule[ksRow];
206+
ksRow += 1;
207+
let t3 = ((SBOX[(s3 >> 24) as usize] << 24) | (SBOX[((s0 >> 16) & 0xff) as usize] << 16) | (SBOX[((s1 >> 8) & 0xff) as usize] << 8) | SBOX[(s2 & 0xff) as usize]) ^ keySchedule[ksRow];
208+
ksRow += 1;
209+
210+
// Set output
211+
dataWords[offset] = t0;
212+
dataWords[offset + 1] = t1;
213+
dataWords[offset + 2] = t2;
214+
dataWords[offset + 3] = t3;
215+
}

0 commit comments

Comments
 (0)