Skip to content

Commit a545127

Browse files
committed
Squashed 'src/crypto/ctaes/' content from commit cd3c3ac
git-subtree-dir: src/crypto/ctaes git-subtree-split: cd3c3ac31fac41cc253bf5780b55ecd8d7368545
0 parents  commit a545127

File tree

6 files changed

+939
-0
lines changed

6 files changed

+939
-0
lines changed

COPYING

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2016 Pieter Wuille
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
ctaes
2+
=====
3+
4+
Simple C module for constant-time AES encryption and decryption.
5+
6+
Features:
7+
* Simple, pure C code without any dependencies.
8+
* No tables or data-dependent branches whatsoever, but using bit sliced approach from https://eprint.iacr.org/2009/129.pdf.
9+
* Very small object code: slightly over 4k of executable code when compiled with -Os.
10+
* Slower than implementations based on precomputed tables or specialized instructions, but can do ~15 MB/s on modern CPUs.
11+
12+
Performance
13+
-----------
14+
15+
Compiled with GCC 5.3.1 with -O3, on an Intel(R) Core(TM) i7-4800MQ CPU, numbers in CPU cycles:
16+
17+
| Algorithm | Key schedule | Encryption per byte | Decryption per byte |
18+
| --------- | ------------:| -------------------:| -------------------:|
19+
| AES-128 | 2.8k | 154 | 161 |
20+
| AES-192 | 3.1k | 169 | 181 |
21+
| AES-256 | 4.0k | 191 | 203 |
22+
23+
Build steps
24+
-----------
25+
26+
Object code:
27+
28+
$ gcc -O3 ctaes.c -c -o ctaes.o
29+
30+
Tests:
31+
32+
$ gcc -O3 ctaes.c test.c -o test
33+
34+
Benchmark:
35+
36+
$ gcc -O3 ctaes.c bench.c -o bench
37+
38+
Review
39+
------
40+
41+
Results of a formal review of the code can be found in http://bitcoin.sipa.be/ctaes/review.zip

bench.c

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
#include <stdio.h>
2+
#include <math.h>
3+
#include "sys/time.h"
4+
5+
#include "ctaes.h"
6+
7+
static double gettimedouble(void) {
8+
struct timeval tv;
9+
gettimeofday(&tv, NULL);
10+
return tv.tv_usec * 0.000001 + tv.tv_sec;
11+
}
12+
13+
static void print_number(double x) {
14+
double y = x;
15+
int c = 0;
16+
if (y < 0.0) {
17+
y = -y;
18+
}
19+
while (y < 100.0) {
20+
y *= 10.0;
21+
c++;
22+
}
23+
printf("%.*f", c, x);
24+
}
25+
26+
static void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) {
27+
int i;
28+
double min = HUGE_VAL;
29+
double sum = 0.0;
30+
double max = 0.0;
31+
for (i = 0; i < count; i++) {
32+
double begin, total;
33+
if (setup != NULL) {
34+
setup(data);
35+
}
36+
begin = gettimedouble();
37+
benchmark(data);
38+
total = gettimedouble() - begin;
39+
if (teardown != NULL) {
40+
teardown(data);
41+
}
42+
if (total < min) {
43+
min = total;
44+
}
45+
if (total > max) {
46+
max = total;
47+
}
48+
sum += total;
49+
}
50+
printf("%s: min ", name);
51+
print_number(min * 1000000000.0 / iter);
52+
printf("ns / avg ");
53+
print_number((sum / count) * 1000000000.0 / iter);
54+
printf("ns / max ");
55+
print_number(max * 1000000000.0 / iter);
56+
printf("ns\n");
57+
}
58+
59+
static void bench_AES128_init(void* data) {
60+
AES128_ctx* ctx = (AES128_ctx*)data;
61+
int i;
62+
for (i = 0; i < 50000; i++) {
63+
AES128_init(ctx, (unsigned char*)ctx);
64+
}
65+
}
66+
67+
static void bench_AES128_encrypt_setup(void* data) {
68+
AES128_ctx* ctx = (AES128_ctx*)data;
69+
static const unsigned char key[16] = {0};
70+
AES128_init(ctx, key);
71+
}
72+
73+
static void bench_AES128_encrypt(void* data) {
74+
const AES128_ctx* ctx = (const AES128_ctx*)data;
75+
unsigned char scratch[16] = {0};
76+
int i;
77+
for (i = 0; i < 4000000 / 16; i++) {
78+
AES128_encrypt(ctx, 1, scratch, scratch);
79+
}
80+
}
81+
82+
static void bench_AES128_decrypt(void* data) {
83+
const AES128_ctx* ctx = (const AES128_ctx*)data;
84+
unsigned char scratch[16] = {0};
85+
int i;
86+
for (i = 0; i < 4000000 / 16; i++) {
87+
AES128_decrypt(ctx, 1, scratch, scratch);
88+
}
89+
}
90+
91+
static void bench_AES192_init(void* data) {
92+
AES192_ctx* ctx = (AES192_ctx*)data;
93+
int i;
94+
for (i = 0; i < 50000; i++) {
95+
AES192_init(ctx, (unsigned char*)ctx);
96+
}
97+
}
98+
99+
static void bench_AES192_encrypt_setup(void* data) {
100+
AES192_ctx* ctx = (AES192_ctx*)data;
101+
static const unsigned char key[16] = {0};
102+
AES192_init(ctx, key);
103+
}
104+
105+
static void bench_AES192_encrypt(void* data) {
106+
const AES192_ctx* ctx = (const AES192_ctx*)data;
107+
unsigned char scratch[16] = {0};
108+
int i;
109+
for (i = 0; i < 4000000 / 16; i++) {
110+
AES192_encrypt(ctx, 1, scratch, scratch);
111+
}
112+
}
113+
114+
static void bench_AES192_decrypt(void* data) {
115+
const AES192_ctx* ctx = (const AES192_ctx*)data;
116+
unsigned char scratch[16] = {0};
117+
int i;
118+
for (i = 0; i < 4000000 / 16; i++) {
119+
AES192_decrypt(ctx, 1, scratch, scratch);
120+
}
121+
}
122+
123+
static void bench_AES256_init(void* data) {
124+
AES256_ctx* ctx = (AES256_ctx*)data;
125+
int i;
126+
for (i = 0; i < 50000; i++) {
127+
AES256_init(ctx, (unsigned char*)ctx);
128+
}
129+
}
130+
131+
132+
static void bench_AES256_encrypt_setup(void* data) {
133+
AES256_ctx* ctx = (AES256_ctx*)data;
134+
static const unsigned char key[16] = {0};
135+
AES256_init(ctx, key);
136+
}
137+
138+
static void bench_AES256_encrypt(void* data) {
139+
const AES256_ctx* ctx = (const AES256_ctx*)data;
140+
unsigned char scratch[16] = {0};
141+
int i;
142+
for (i = 0; i < 4000000 / 16; i++) {
143+
AES256_encrypt(ctx, 1, scratch, scratch);
144+
}
145+
}
146+
147+
static void bench_AES256_decrypt(void* data) {
148+
const AES256_ctx* ctx = (const AES256_ctx*)data;
149+
unsigned char scratch[16] = {0};
150+
int i;
151+
for (i = 0; i < 4000000 / 16; i++) {
152+
AES256_decrypt(ctx, 1, scratch, scratch);
153+
}
154+
}
155+
156+
int main(void) {
157+
AES128_ctx ctx128;
158+
AES192_ctx ctx192;
159+
AES256_ctx ctx256;
160+
run_benchmark("aes128_init", bench_AES128_init, NULL, NULL, &ctx128, 20, 50000);
161+
run_benchmark("aes128_encrypt_byte", bench_AES128_encrypt, bench_AES128_encrypt_setup, NULL, &ctx128, 20, 4000000);
162+
run_benchmark("aes128_decrypt_byte", bench_AES128_decrypt, bench_AES128_encrypt_setup, NULL, &ctx128, 20, 4000000);
163+
run_benchmark("aes192_init", bench_AES192_init, NULL, NULL, &ctx192, 20, 50000);
164+
run_benchmark("aes192_encrypt_byte", bench_AES192_encrypt, bench_AES192_encrypt_setup, NULL, &ctx192, 20, 4000000);
165+
run_benchmark("aes192_decrypt_byte", bench_AES192_decrypt, bench_AES192_encrypt_setup, NULL, &ctx192, 20, 4000000);
166+
run_benchmark("aes256_init", bench_AES256_init, NULL, NULL, &ctx256, 20, 50000);
167+
run_benchmark("aes256_encrypt_byte", bench_AES256_encrypt, bench_AES256_encrypt_setup, NULL, &ctx256, 20, 4000000);
168+
run_benchmark("aes256_decrypt_byte", bench_AES256_decrypt, bench_AES256_encrypt_setup, NULL, &ctx256, 20, 4000000);
169+
return 0;
170+
}

0 commit comments

Comments
 (0)