Skip to content

Commit

Permalink
Update base64/hash/signature impl
Browse files Browse the repository at this point in the history
  • Loading branch information
MizukiSonoko committed Jun 13, 2017
1 parent 663195c commit 658deab
Show file tree
Hide file tree
Showing 6 changed files with 310 additions and 133 deletions.
16 changes: 16 additions & 0 deletions core/crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

# Base64
ADD_LIBRARY(base64 STATIC base64.cpp)

# Signature
ADD_LIBRARY(signature STATIC signature.cpp)
target_link_libraries(signature
ed25519
base64
)

# Hash
ADD_LIBRARY(hash STATIC hash.cpp)
target_link_libraries(hash
keccak
)
214 changes: 108 additions & 106 deletions core/crypto/base64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,150 +16,152 @@ limitations under the License.
#include <crypto/base64.hpp>

namespace crypto {
namespace base64 {

namespace vendor {
/*
base64.cpp and base64.h
namespace vendor {
/*
base64.cpp and base64.h
Copyright (C) 2004-2008 René Nyffenegger
Copyright (C) 2004-2008 René Nyffenegger
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
3. This notice may not be removed or altered from any source distribution.
René Nyffenegger [email protected]
René Nyffenegger [email protected]
*/
*/

static const char *base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static const char *base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";

static const size_t base64_chars_len = strlen(base64_chars);
static const size_t base64_chars_len = strlen(base64_chars);


static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}

std::string base64_encode(unsigned char const *bytes_to_encode,
unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];

while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] =
((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] =
((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;

for (i = 0; (i < 4); i++) ret += base64_chars[char_array_4[i]];
i = 0;
}
}

if (i) {
for (j = i; j < 3; j++) char_array_3[j] = '\0';

std::string base64_encode(unsigned char const *bytes_to_encode,
unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];

while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] =
((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] =
((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;

for (i = 0; (i < 4); i++) ret += base64_chars[char_array_4[i]];
i = 0;
}
}

if (i) {
for (j = i; j < 3; j++) char_array_3[j] = '\0';
for (j = 0; (j < i + 1); j++) ret += base64_chars[char_array_4[j]];

char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] =
((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] =
((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
while ((i++ < 3)) ret += '=';
}

for (j = 0; (j < i + 1); j++) ret += base64_chars[char_array_4[j]];
return ret;
}

while ((i++ < 3)) ret += '=';
// add find function instead of string's find()
inline int base64_chars_find(char c) {
for (size_t i = 0; i < base64_chars_len; i++) {
if (c == base64_chars[i]) return i;
}
return -1;
}

return ret;
}
std::vector<unsigned char> base64_decode(std::string const &encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::vector<unsigned char> ret;
// changes capacity, not size
// push_back becomes O(1)
ret.reserve(encoded_string.size());

while (in_len-- && (encoded_string[in_] != '=') &&
is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_];
in_++;
if (i == 4) {
for (i = 0; i < 4; i++)
char_array_4[i] = base64_chars_find(char_array_4[i]);

char_array_3[0] =
(char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] =
((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (i = 0; (i < 3); i++) ret.push_back(char_array_3[i]);
i = 0;
}
}

// add find function instead of string's find()
inline int base64_chars_find(char c) {
for (size_t i = 0; i < base64_chars_len; i++) {
if (c == base64_chars[i]) return i;
}
return -1;
}
if (i) {
for (j = i; j < 4; j++) char_array_4[j] = 0;

std::vector<unsigned char> base64_decode(std::string const &encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::vector<unsigned char> ret;
// changes capacity, not size
// push_back becomes O(1)
ret.reserve(encoded_string.size());

while (in_len-- && (encoded_string[in_] != '=') &&
is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_];
in_++;
if (i == 4) {
for (i = 0; i < 4; i++)
char_array_4[i] = base64_chars_find(char_array_4[i]);

char_array_3[0] =
(char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
for (j = 0; j < 4; j++)
char_array_4[j] = base64_chars_find(char_array_4[j]);

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] =
((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (i = 0; (i < 3); i++) ret.push_back(char_array_3[i]);
i = 0;
for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]);
}
}

if (i) {
for (j = i; j < 4; j++) char_array_4[j] = 0;

for (j = 0; j < 4; j++)
char_array_4[j] = base64_chars_find(char_array_4[j]);

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] =
((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]);
return ret;
}
} // namespace vendor

return ret;
const std::string encode(const std::vector<unsigned char> &message) {
return vendor::base64_encode(message.data(), message.size());
}
} // namespace vendor

const std::string encode(const std::vector<unsigned char> &message) {
return vendor::base64_encode(message.data(), message.size());
}
std::vector<unsigned char> decode(const std::string &enc) {
return vendor::base64_decode(enc);
}

std::vector<unsigned char> decode(const std::string &enc) {
return vendor::base64_decode(enc);
}

} // namespace crypto
7 changes: 5 additions & 2 deletions core/crypto/base64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ limitations under the License.
#pragma once

#include <string>
#include <string.h>
#include <vector>

namespace crypto {
const std::string encode(const std::vector<unsigned char> &message);
std::vector<unsigned char> decode(const std::string &encoded);
namespace base64 {
const std::string encode(const std::vector<unsigned char> &message);
std::vector<unsigned char> decode(const std::string &encoded);
}
};
68 changes: 68 additions & 0 deletions core/crypto/hash.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
Copyright Soramitsu Co., Ltd. 2016 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
extern "C" {
#include <SimpleFIPS202.h>
}
#include <crypto/hash.hpp>
#include <vector>

namespace hash {

static inline std::string digest_to_hexdigest(const unsigned char *digest,
size_t size) {
char code[] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
std::string res = "";
unsigned char front, back;
for (unsigned int i = 0; i < size; i++) {
front = (digest[i] & 0xF0) >> 4;
back = digest[i] & 0xF;
res += code[front];
res += code[back];
}
return res;
}

std::string sha3_256_hex(std::string message) {
const int sha256_size = 32; // bytes
unsigned char digest[sha256_size];

SHA3_256(digest, reinterpret_cast<const unsigned char *>(message.c_str()),
message.size());

return digest_to_hexdigest(digest, sha256_size);
}

std::string sha3_256_hex(std::vector<uint8_t> message) {
const int sha256_size = 32; // bytes
unsigned char digest[sha256_size];

SHA3_256(digest, message.data(), message.size());

return digest_to_hexdigest(digest, sha256_size);
}

std::string sha3_512_hex(std::string message) {
const int sha512_size = 64; // bytes
unsigned char digest[sha512_size];

SHA3_512(digest, reinterpret_cast<const unsigned char *>(message.c_str()),
message.size());

return digest_to_hexdigest(digest, sha512_size);
}

} // namespace hash
Loading

0 comments on commit 658deab

Please sign in to comment.