Skip to content
This repository was archived by the owner on Feb 18, 2022. It is now read-only.

Commit 8fa8851

Browse files
committed
Fetched recent aes spec changes and added fips202
1 parent 5bbd2b7 commit 8fa8851

File tree

2 files changed

+223
-5
lines changed

2 files changed

+223
-5
lines changed

tests/ui/hacspec/aes.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const RCON: RCon = RCon(secret_bytes!([
4949

5050
fn sub_bytes(state: Block) -> Block {
5151
let mut st = state;
52-
for i in 0..16 {
52+
for i in 0..BLOCKSIZE {
5353
st[i] = SBOX[U8::declassify(state[i])];
5454
}
5555
st
@@ -105,7 +105,7 @@ fn mix_columns(state: Block) -> Block {
105105

106106
fn add_round_key(state: Block, key: Key) -> Block {
107107
let mut out = state;
108-
for i in 0..16 {
108+
for i in 0..BLOCKSIZE {
109109
out[i] ^= key[i];
110110
}
111111
out
@@ -126,7 +126,7 @@ fn aes_enc_last(state: Block, round_key: Key) -> Block {
126126

127127
fn rounds(state: Block, key: Bytes144) -> Block {
128128
let mut out = state;
129-
for key_block in key.chunks(16) {
129+
for (_, key_block) in key.chunks(BLOCKSIZE) {
130130
out = aes_enc(out, Key::from(key_block));
131131
}
132132
out
@@ -211,7 +211,7 @@ pub(crate) fn xor_block(block: Block, keyblock: Block) -> Block {
211211
fn aes128_counter_mode(key: Key, nonce: Nonce, counter: U32, msg: ByteSeq) -> ByteSeq {
212212
let mut ctr = counter;
213213
let mut blocks_out = ByteSeq::new(msg.len());
214-
for msg_block in msg.chunks(BLOCKSIZE) {
214+
for (block_len, msg_block) in msg.chunks(BLOCKSIZE) {
215215
if msg_block.len() == BLOCKSIZE {
216216
let key_block = aes128_ctr_keyblock(key, nonce, ctr);
217217
blocks_out = blocks_out.push(
@@ -222,7 +222,7 @@ fn aes128_counter_mode(key: Key, nonce: Nonce, counter: U32, msg: ByteSeq) -> By
222222
// Last block that needs padding
223223
let keyblock = aes128_ctr_keyblock(key, nonce, ctr);
224224
let last_block = Block::from(msg_block);
225-
blocks_out = blocks_out.push_sub(xor_block(last_block, keyblock), 0, msg_block.len());
225+
blocks_out = blocks_out.push_sub(xor_block(last_block, keyblock), 0, block_len);
226226
}
227227
}
228228
blocks_out

tests/ui/hacspec/fips202.rs

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
#![allow(clippy::all)]
2+
#![deny(clippy::hacspec)]
3+
4+
extern crate hacspec;
5+
extern crate rand;
6+
7+
// Import hacspec and all needed definitions.
8+
use hacspec::prelude::*;
9+
10+
const ROUNDS:usize = 24;
11+
pub const SHA3224_RATE:usize = 144;
12+
pub const SHA3256_RATE:usize = 136;
13+
pub const SHA3384_RATE:usize = 104;
14+
pub const SHA3512_RATE:usize = 72;
15+
pub const SHAKE128_RATE:usize = 168;
16+
pub const SHAKE256_RATE:usize = 136;
17+
18+
pub enum ShaRate{
19+
Sha3224Rate = 144,
20+
Sha3256Rate = 136,
21+
Sha3384Rate = 104,
22+
Sha3512Rate = 72,
23+
}
24+
25+
array!(State, 25, U64);
26+
array!(Row, 5, U64);
27+
bytes!(Digest224, 28);
28+
bytes!(Digest256, 32);
29+
bytes!(Digest384, 48);
30+
bytes!(Digest512, 64);
31+
32+
const ROUNDCONSTANTS:[u64;ROUNDS] = [
33+
0x0000_0000_0000_0001, 0x0000_0000_0000_8082, 0x8000_0000_0000_808a, 0x8000_0000_8000_8000,
34+
0x0000_0000_0000_808b, 0x0000_0000_8000_0001, 0x8000_0000_8000_8081, 0x8000_0000_0000_8009,
35+
0x0000_0000_0000_008a, 0x0000_0000_0000_0088, 0x0000_0000_8000_8009, 0x0000_0000_8000_000a,
36+
0x0000_0000_8000_808b, 0x8000_0000_0000_008b, 0x8000_0000_0000_8089, 0x8000_0000_0000_8003,
37+
0x8000_0000_0000_8002, 0x8000_0000_0000_0080, 0x0000_0000_0000_800a, 0x8000_0000_8000_000a,
38+
0x8000_0000_8000_8081, 0x8000_0000_0000_8080, 0x0000_0000_8000_0001, 0x8000_0000_8000_8008
39+
];
40+
41+
const ROTC:[u32;25] = [
42+
0, 1, 62, 28, 27, 36, 44, 6, 55, 20, 3, 10, 43, 25, 39, 41, 45, 15, 21, 8, 18, 2, 61, 56, 14,
43+
];
44+
45+
const PI:[usize;25] = [
46+
0, 6, 12, 18, 24, 3, 9, 10, 16, 22, 1, 7, 13, 19, 20, 4, 5, 11, 17, 23, 2, 8, 14, 15, 21
47+
];
48+
49+
50+
fn theta(s: State) -> State {
51+
let mut s = s;
52+
let mut b = Row::new();
53+
for i in 0..5 {
54+
b[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20];
55+
}
56+
for i in 0..5 {
57+
let u:U64 = b[(i + 1) % 5];
58+
let t = b[(i + 4) % 5] ^ u.rotate_left(1);
59+
for j in 0..5 {
60+
s[5 * j + i] ^= t;
61+
}
62+
}
63+
s
64+
}
65+
66+
fn rho(s: State) -> State {
67+
let mut s = s;
68+
for i in 0..25 {
69+
let u:U64 = s[i];
70+
s[i] = u.rotate_left(ROTC[i]);
71+
}
72+
s
73+
}
74+
75+
fn pi(s: State) -> State {
76+
let mut v = State::new();
77+
for i in 0..25 {
78+
v[i] = s[PI[i]];
79+
}
80+
v
81+
}
82+
83+
fn chi(s: State) -> State {
84+
let mut s = s;
85+
let mut b = Row::new();
86+
for i in 0..5 {
87+
for j in 0..5 {
88+
b[j] = s[5*i+j];
89+
}
90+
for j in 0..5 {
91+
let u:U64 = b[(j + 1) % 5];
92+
s[5*i+j] ^= (!u) & b[(j + 2) % 5];
93+
}
94+
}
95+
s
96+
}
97+
98+
fn iota(s: State, rndconst: u64) -> State {
99+
let mut s = s;
100+
s[0] ^= U64::classify(rndconst);
101+
s
102+
}
103+
104+
fn keccakf1600(s: State) -> State {
105+
let mut s = s;
106+
for i in 0..ROUNDS{
107+
s = theta(s);
108+
s = rho(s);
109+
s = pi(s);
110+
s = chi(s);
111+
s = iota(s, ROUNDCONSTANTS[i]);
112+
}
113+
s
114+
}
115+
116+
fn absorb_block(s: State, block: ByteSeq) -> State {
117+
let mut s = s;
118+
for (i, b) in block.iter().enumerate() {
119+
let w = i >> 3;
120+
let o = 8*((i & 7) as u32);
121+
s[w] ^= U64::from(*b) << o;
122+
}
123+
keccakf1600(s)
124+
}
125+
126+
fn squeeze(s: State, nbytes: usize, rate: usize) -> ByteSeq {
127+
let mut s = s;
128+
let mut out = ByteSeq::new(nbytes);
129+
for i in 0..nbytes {
130+
let pos = i % rate;
131+
let w = pos >> 3;
132+
let o = 8*((pos & 7) as u32);
133+
let b = (s[w] >> o) & U64::classify(0xffu64);
134+
out[i] = b.into();
135+
if ((i+1) % rate) == 0 {
136+
s = keccakf1600(s);
137+
}
138+
}
139+
out
140+
}
141+
142+
fn keccak(rate: usize, data: ByteSeq, p: u8, outbytes: usize) -> ByteSeq {
143+
let mut buf = ByteSeq::new(rate);
144+
let mut s = State::new();
145+
146+
for (block_len, block) in data.chunks(rate) {
147+
if block_len == rate {
148+
s = absorb_block(s, block);
149+
}
150+
else {
151+
buf = buf.push(block);
152+
}
153+
}
154+
buf = buf.push(ByteSeq::from_array(&[U8::classify(p)]));
155+
buf[rate-1] |= U8::classify(128);
156+
s = absorb_block(s, buf);
157+
158+
squeeze(s, outbytes, rate)
159+
}
160+
161+
pub fn sha3224(data: ByteSeq) -> Digest224 {
162+
let t = keccak(SHA3224_RATE, data, 0x06, 28);
163+
Digest224::from(t)
164+
}
165+
166+
pub fn sha3256(data: ByteSeq) -> Digest256 {
167+
let t = keccak(SHA3256_RATE, data, 0x06, 32);
168+
Digest256::from(t)
169+
}
170+
171+
pub fn sha3384(data: ByteSeq) -> Digest384 {
172+
let t = keccak(SHA3384_RATE, data, 0x06, 48);
173+
Digest384::from(t)
174+
}
175+
176+
pub fn sha3512(data: ByteSeq) -> Digest512 {
177+
let t = keccak(SHA3512_RATE, data, 0x06, 64);
178+
Digest512::from(t)
179+
}
180+
181+
pub fn shake128(data: ByteSeq, outlen: usize) -> ByteSeq {
182+
keccak(SHAKE128_RATE, data, 0x1f, outlen)
183+
}
184+
185+
pub fn shake256(data: ByteSeq, outlen: usize) -> ByteSeq {
186+
keccak(SHAKE256_RATE, data, 0x1f, outlen)
187+
}
188+
189+
190+
#[test]
191+
fn test_keccakf1600() {
192+
let s:State = State(secret_array!(U64,[
193+
0x5ba446eba89b9b78, 0x6ef6eb8a586fb342, 0x85cb3d1fcec58036, 0xa59848fabf68003d,
194+
0x35fdce49db45e6c1, 0x0cf8fad4b3c5a04c, 0x9afa06a9884be9bc, 0x1ff35d85c227b2e0,
195+
0x09ec8487110fc092, 0xcdea358a32c0fafb, 0x74241ac11e48073a, 0x72f921a900982d03,
196+
0x676616072102dbbc, 0x2638caacb8a3a5de, 0xc603972154aa5dd8, 0x68b2fefc9b5075e3,
197+
0x8373f072f138bdee, 0xdff378a39b99a1a0, 0x0b4bc139e9140556, 0x19195e7735eb1c0a,
198+
0x056b896a9884cb04, 0x68e821e02963121f, 0xce7c280b9563ae2c, 0xc88f8da33e4311d6,
199+
0xc67829e549219318]));
200+
201+
let c:State = State(secret_array!(U64,[
202+
0x95bef5e1cff30a77, 0x91857a255e178abd, 0xbf8f4cef4c33fbe9, 0xa40655d779ecdc92,
203+
0xb17af41f3c6a6d09, 0x9f4e56cfd932c0c7, 0x8dedfc2eb4c43a69, 0x92e3a4f9f54bf903,
204+
0x51eca70f0657a075, 0x690f9af199489ab5, 0x718748b08fba9389, 0x2d7349b2fd3c5cbe,
205+
0xc8e1c9f8a9b002aa, 0x272dfd58ff1304ec, 0x665d945446962fe5, 0xdabb2fbc07dc0b57,
206+
0xc49e2cecb193b592, 0x63c1c463f370e7a5, 0xc643a20b2ffb0e52, 0xee9f85afed7d708c,
207+
0xb031433c85642b6c, 0xfbe4f94ffc73ddbe, 0xfa2a02bb934e7bb3, 0x38025c926f7136f5,
208+
0xf83d27a7f7ec241e]));
209+
let v = keccakf1600(s);
210+
211+
assert_secret_array_eq!(c,v,U64);
212+
}
213+
214+
215+
216+
fn main() {
217+
218+
}

0 commit comments

Comments
 (0)