Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
xbuild
.vscode
.idea
cmake-build-*
52 changes: 52 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
cmake_minimum_required(VERSION 3.8)

project (tenhard)
set(CMAKE_CXX_STANDARD 17)

#cmake_policy(SET CMP0063 NEW)
#set(CMAKE_CXX_VISIBILITY_PRESET hidden)
#set(CMAKE_C_VISIBILITY_PRESET hidden)
#set(CMAKE_VISIBILITY_INLINES_HIDDEN hidden)
#set(TENHARD_TARGET_TYPE SHARED)
#set(TENHARD_TARGET_TYPE STATIC)

#set(CMAKE_INSTALL_PREFIX /Users/gggin/workspace/tenhard)
#set(CMAKE_PREFIX_PATH f:/Program\ Files/easy_profiler/lib/cmake/easy_profiler)
#find_package(easy_profiler REQUIRED)

set(TARGET_NAME sha1)


add_executable(
${TARGET_NAME}
sha1.h
sha1.cc
sse.cc
)

add_executable(
aes
aes/matrix.cc
aes/matrix.h
aes/sbox.cc
aes/sbox.h
aes/aes_ctr.cc
aes/aes_ctr.h
aes/aes.cc
aes/aes.h)

add_library(
catch_test_main
STATIC
catch_main.cc
)

target_link_libraries(aes catch_test_main)

if(MSVC)
target_compile_options(${TARGET_NAME} PRIVATE /W4 /WX)
else(MSVC)
target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic -Werror)
endif(MSVC)

#target_link_libraries(sha1 easy_profiler)
65 changes: 65 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,68 @@
# encryption_algorithms

Study some common encryption algos.

List some algorithms to implement
- [x] SHA-1
- [ ] SHA-256
- [ ] AES-128-ecb
- [ ] AES-256-ecb
- [ ] AES-128-cfb
- [x] AES-128-ctr
- [ ] AES-256-cfb

Todos:
- [ ] Base test cases

Currently the aes-128-ctr algorithm is working good. but it's still in **experimental**. Be careful for usage.

The project is built in C++17 and will compile on Windows, Mac, Ios, Android. Just cpp codes.

This project is not focus on speed, but study. And I want to use this project by myself later, so it'll be easy to integration later.

```cpp
#include "aes_ctr.h"

uint8_t iv[16] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};

uint8_t key[] = {
0xC4, 0xCA, 0x42, 0x38, 0xA0, 0xB9, 0x23, 0x82,
0x0D, 0xCC, 0x50, 0x9A, 0x6F, 0x75, 0x84, 0x9B,
};

uint8_t out[16];

unsigned char input[] = {0x2b, 0x41, 0x5d, 0x44, 0x59, 0x6e, 0x3a, 0x28,
0xe5, 0x08, 0xaf, 0x0b, 0x13, 0xb4, 0x00, 0xc2,

0x49, 0x6f, 0x23, 0x95, 0xb6, 0x88, 0xe0, 0x41,
0x17, 0x44, 0x64, 0x4b, 0x96, 0x37, 0x92, 0xc3};

CTR ctr(iv, key);
// Do every block for ctr, and ctr support all 0xff iv, and iv will go to all
// 0x00 from one.
ctr.Do(input, out);

printf("msg:\n");
for (int i = 0; i < 4; i++) {
printf("%02x%02x%02x%02x ", out[4 * i + 0], out[4 * i + 1], out[4 * i + 2],
out[4 * i + 3]);
}
puts("");

ctr.Do(input + 16, out);

printf("msg:\n");
for (int i = 0; i < 4; i++) {
printf("%02x%02x%02x%02x ", out[4 * i + 0], out[4 * i + 1], out[4 * i + 2],
out[4 * i + 3]);
}
puts("");
```

# Relate
Inspired from this repo.
https://github.com/dhuertas/AES
143 changes: 143 additions & 0 deletions aes/aes.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
//
// Created by Gin Liu on 2018/11/21.
//

#include "aes.h"
#include "matrix.h"
#include "sbox.h"
#include <vector>

namespace {
int Nb = 4;
}
/*
* Transformation in the Cipher that processes the State by cyclically
* shifting the last three rows of the State by different offsets.
*/
void shift_rows(uint8_t *state) {

uint8_t i, k, s, tmp;

for (i = 1; i < 4; i++) {
// shift(1,4)=1; shift(2,4)=2; shift(3,4)=3
// shift(r, 4) = r;
s = 0;
while (s < i) {
tmp = state[Nb * i + 0];

for (k = 1; k < Nb; k++) {
state[Nb * i + k - 1] = state[Nb * i + k];
}

state[Nb * i + Nb - 1] = tmp;
s++;
}
}
}

/*
* Transformation in the Inverse Cipher that is the inverse of
* ShiftRows().
*/
void inv_shift_rows(uint8_t *state) {

uint8_t i, k, s, tmp;

for (i = 1; i < 4; i++) {
s = 0;
while (s < i) {
tmp = state[Nb * i + Nb - 1];

for (k = Nb - 1; k > 0; k--) {
state[Nb * i + k] = state[Nb * i + k - 1];
}

state[Nb * i + 0] = tmp;
s++;
}
}
}

std::vector<uint8_t> mixMatrix = {
2, 3, 1, 1, 1, 2, 3, 1, 1, 1, 2, 3, 3, 1, 1, 2,
};

std::vector<uint8_t> mixMatrixInverse = {0xe, 0xb, 0xd, 0x9, 0x9, 0xe,
0xb, 0xd, 0xd, 0x9, 0xe, 0xb,
0xb, 0xd, 0x9, 0xe};

void mix_columns_inner(uint8_t *state,
const std::vector<uint8_t> &matrix_data) {
Matrix<4, 4, uint8_t> x;
Matrix<4, 4, uint8_t> m;
memcpy(x.data, matrix_data.data(), decltype(x)::byte_count);
MatrixConvert(m, state, [&x](decltype(m) &mm) {
mm = Mul<4, 4, 4, uint8_t, AddOp, MulOp>(x, mm);
});
}

void mix_columns(uint8_t *state) { mix_columns_inner(state, mixMatrix); }

void inv_mix_columns(uint8_t *state) {
mix_columns_inner(state, mixMatrixInverse);
}

void sub_bytes(uint8_t *state) {
Matrix<4, 4, uint8_t> m;
MatrixConvert(m, state, [](decltype(m) &m) { SboxTr(m); });
}

void inv_sub_bytes(uint8_t *state) {
Matrix<4, 4, uint8_t> m;
MatrixConvert(m, state, [](decltype(m) &m) { SboxInverseTr(m); });
}

/*
* Generates the round constant Rcon[i]
*/
namespace {
uint8_t R[] = {0x02, 0x00, 0x00, 0x00};
std::vector<uint8_t> cache;
std::vector<bool> flags;
auto xx = ([]() -> int {
cache.resize(4 * (15 + 1), 0);
flags.resize(4 * (15 + 1), false);
return 0;
})();
} // namespace

uint8_t *Rcon(uint8_t i) {
//if (!flags[i]) { //TODO(Gin) cache has bug
if (i == 1) {
R[0] = 0x01; // x^(1-1) = x^0 = 1
} else if (i > 1) {
R[0] = 0x02;
i--;
while (i - 1 > 0) {
R[0] = gmult(R[0], 0x02);
i--;
}
}
cache[i] = R[0];
flags[i] = true;
//} else {
// R[0] = cache[i];
//}
// printf("R: %d [end]", R[0]);
return R;
}

void sub_word(uint8_t *w) {
uint8_t i;
Matrix<4, 1, uint8_t> m;
MatrixConvert(m, w, [](decltype(m) &m) { SboxTr(m); });
}

void add_round_key(uint8_t *state, uint8_t *w, uint8_t r) {
Matrix<4, 4, uint8_t> m, wm;
memcpy(m.data, state, decltype(m)::byte_count);
memcpy(wm.data, w + 4 * 4 * r, decltype(wm)::byte_count);
MatrixTranspose(wm);
m = Add<4, 4, uint8_t, AddOp>(m, wm);
memcpy(state, m.data, decltype(m)::byte_count);
}
50 changes: 50 additions & 0 deletions aes/aes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// Created by Gin Liu on 2018/11/21.
//

#ifndef TENHARD_AES_H
#define TENHARD_AES_H
#include "matrix.h"
#include <cstdint>

void shift_rows(uint8_t *state);
void inv_shift_rows(uint8_t *state);

void mix_columns(uint8_t *state);
void inv_mix_columns(uint8_t *state);

void sub_bytes(uint8_t *state);
void inv_sub_bytes(uint8_t *state);

uint8_t *Rcon(uint8_t i);
/*
* Function used in the Key Expansion routine that takes a four-byte
* word and performs a cyclic permutation.
*/
inline void rot_word(uint8_t *w) {

uint8_t tmp;
uint8_t i;

tmp = w[0];

for (i = 0; i < 3; i++) {
w[i] = w[i + 1];
}

w[3] = tmp;
}
/*
* Function used in the Key Expansion routine that takes a four-byte
* input word and applies an S-box to each of the four bytes to
* produce an output word.
*/
void sub_word(uint8_t *w);
/*
* Transformation in the Cipher and Inverse Cipher in which a Round
* Key is added to the State using an XOR operation. The length of a
* Round Key equals the size of the State (i.e., for Nb = 4, the Round
* Key length equals 128 bits/16 bytes).
*/
void add_round_key(uint8_t *state, uint8_t *w, uint8_t r);
#endif // TENHARD_AES_H
Loading