mirror of
https://github.com/SChernykh/p2pool.git
synced 2024-12-22 11:29:23 +00:00
Added sha256
This commit is contained in:
parent
d5a9fb8d0e
commit
da45871f0b
6 changed files with 256 additions and 3 deletions
|
@ -64,6 +64,7 @@ endif()
|
|||
include(cmake/flags.cmake)
|
||||
|
||||
set(HEADERS
|
||||
external/src/crypto/sha256.h
|
||||
external/src/cryptonote/crypto-ops.h
|
||||
external/src/hardforks/hardforks.h
|
||||
src/block_cache.h
|
||||
|
@ -94,6 +95,7 @@ set(HEADERS
|
|||
)
|
||||
|
||||
set(SOURCES
|
||||
external/src/crypto/sha256.c
|
||||
external/src/cryptonote/crypto-ops-data.c
|
||||
external/src/cryptonote/crypto-ops.c
|
||||
external/src/hardforks/hardforks.cpp
|
||||
|
|
169
external/src/crypto/sha256.c
vendored
Normal file
169
external/src/crypto/sha256.c
vendored
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*********************************************************************
|
||||
* Filename: sha256.c
|
||||
* Author: Brad Conte (brad AT bradconte.com)
|
||||
* Copyright:
|
||||
* Disclaimer: This code is presented "as is" without any guarantees.
|
||||
* Details: Implementation of the SHA-256 hashing algorithm.
|
||||
SHA-256 is one of the three algorithms in the SHA2
|
||||
specification. The others, SHA-384 and SHA-512, are not
|
||||
offered in this implementation.
|
||||
Algorithm specification can be found here:
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
|
||||
This implementation uses little endian byte order.
|
||||
*********************************************************************/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4668)
|
||||
#endif
|
||||
|
||||
/*************************** HEADER FILES ***************************/
|
||||
#include "sha256.h"
|
||||
#include <memory.h>
|
||||
|
||||
/****************************** MACROS ******************************/
|
||||
#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b))))
|
||||
#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b))))
|
||||
|
||||
#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
|
||||
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
|
||||
#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
|
||||
#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
|
||||
#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
|
||||
|
||||
/**************************** VARIABLES *****************************/
|
||||
static const uint32_t k[64] = {
|
||||
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
|
||||
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
|
||||
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
|
||||
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
|
||||
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
|
||||
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
|
||||
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
|
||||
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
|
||||
};
|
||||
|
||||
/*********************** FUNCTION DEFINITIONS ***********************/
|
||||
static void sha256_transform(SHA256_CTX *ctx, const uint8_t* data)
|
||||
{
|
||||
uint32_t a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
|
||||
|
||||
for (i = 0, j = 0; i < 16; ++i, j += 4)
|
||||
m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
|
||||
for ( ; i < 64; ++i)
|
||||
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
|
||||
|
||||
a = ctx->state[0];
|
||||
b = ctx->state[1];
|
||||
c = ctx->state[2];
|
||||
d = ctx->state[3];
|
||||
e = ctx->state[4];
|
||||
f = ctx->state[5];
|
||||
g = ctx->state[6];
|
||||
h = ctx->state[7];
|
||||
|
||||
for (i = 0; i < 64; ++i) {
|
||||
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
|
||||
t2 = EP0(a) + MAJ(a,b,c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
}
|
||||
|
||||
ctx->state[0] += a;
|
||||
ctx->state[1] += b;
|
||||
ctx->state[2] += c;
|
||||
ctx->state[3] += d;
|
||||
ctx->state[4] += e;
|
||||
ctx->state[5] += f;
|
||||
ctx->state[6] += g;
|
||||
ctx->state[7] += h;
|
||||
}
|
||||
|
||||
void sha256_init(SHA256_CTX *ctx)
|
||||
{
|
||||
ctx->datalen = 0;
|
||||
ctx->bitlen = 0;
|
||||
ctx->state[0] = 0x6a09e667;
|
||||
ctx->state[1] = 0xbb67ae85;
|
||||
ctx->state[2] = 0x3c6ef372;
|
||||
ctx->state[3] = 0xa54ff53a;
|
||||
ctx->state[4] = 0x510e527f;
|
||||
ctx->state[5] = 0x9b05688c;
|
||||
ctx->state[6] = 0x1f83d9ab;
|
||||
ctx->state[7] = 0x5be0cd19;
|
||||
}
|
||||
|
||||
void sha256_update(SHA256_CTX *ctx, const uint8_t* data, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
ctx->data[ctx->datalen] = data[i];
|
||||
ctx->datalen++;
|
||||
if (ctx->datalen == 64) {
|
||||
sha256_transform(ctx, ctx->data);
|
||||
ctx->bitlen += 512;
|
||||
ctx->datalen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sha256_final(SHA256_CTX *ctx, uint8_t* hash)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
i = ctx->datalen;
|
||||
|
||||
// Pad whatever data is left in the buffer.
|
||||
if (ctx->datalen < 56) {
|
||||
ctx->data[i++] = 0x80;
|
||||
while (i < 56)
|
||||
ctx->data[i++] = 0x00;
|
||||
}
|
||||
else {
|
||||
ctx->data[i++] = 0x80;
|
||||
while (i < 64)
|
||||
ctx->data[i++] = 0x00;
|
||||
sha256_transform(ctx, ctx->data);
|
||||
memset(ctx->data, 0, 56);
|
||||
}
|
||||
|
||||
// Append to the padding the total message's length in bits and transform.
|
||||
ctx->bitlen += ctx->datalen * 8;
|
||||
ctx->data[63] = (uint8_t)(ctx->bitlen);
|
||||
ctx->data[62] = (uint8_t)(ctx->bitlen >> 8);
|
||||
ctx->data[61] = (uint8_t)(ctx->bitlen >> 16);
|
||||
ctx->data[60] = (uint8_t)(ctx->bitlen >> 24);
|
||||
ctx->data[59] = (uint8_t)(ctx->bitlen >> 32);
|
||||
ctx->data[58] = (uint8_t)(ctx->bitlen >> 40);
|
||||
ctx->data[57] = (uint8_t)(ctx->bitlen >> 48);
|
||||
ctx->data[56] = (uint8_t)(ctx->bitlen >> 56);
|
||||
sha256_transform(ctx, ctx->data);
|
||||
|
||||
// Since this implementation uses little endian byte ordering and SHA uses big endian,
|
||||
// reverse all the bytes when copying the final state to the output hash.
|
||||
for (i = 0; i < 4; ++i) {
|
||||
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
|
||||
}
|
||||
}
|
||||
|
||||
void sha256(const void* data, uint32_t len, uint8_t* hash)
|
||||
{
|
||||
SHA256_CTX ctx;
|
||||
sha256_init(&ctx);
|
||||
sha256_update(&ctx, data, len);
|
||||
sha256_final(&ctx, hash);
|
||||
}
|
33
external/src/crypto/sha256.h
vendored
Normal file
33
external/src/crypto/sha256.h
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*********************************************************************
|
||||
* Filename: sha256.h
|
||||
* Author: Brad Conte (brad AT bradconte.com)
|
||||
* Copyright:
|
||||
* Disclaimer: This code is presented "as is" without any guarantees.
|
||||
* Details: Defines the API for the corresponding SHA1 implementation.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef SHA256_H
|
||||
#define SHA256_H
|
||||
|
||||
/*************************** HEADER FILES ***************************/
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************** MACROS ******************************/
|
||||
#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest
|
||||
|
||||
typedef struct {
|
||||
uint8_t data[64];
|
||||
uint32_t datalen;
|
||||
uint32_t padding;
|
||||
uint64_t bitlen;
|
||||
uint32_t state[8];
|
||||
} SHA256_CTX;
|
||||
|
||||
/*********************** FUNCTION DECLARATIONS **********************/
|
||||
void sha256_init(SHA256_CTX *ctx);
|
||||
void sha256_update(SHA256_CTX *ctx, const uint8_t* data, uint32_t len);
|
||||
void sha256_final(SHA256_CTX *ctx, uint8_t* hash);
|
||||
|
||||
void sha256(const void* data, uint32_t len, uint8_t* hash);
|
||||
|
||||
#endif // SHA256_H
|
|
@ -37,8 +37,10 @@ set(SOURCES
|
|||
src/log_tests.cpp
|
||||
src/main.cpp
|
||||
src/pool_block_tests.cpp
|
||||
src/sha256_tests.cpp
|
||||
src/util_tests.cpp
|
||||
src/wallet_tests.cpp
|
||||
../external/src/crypto/sha256.c
|
||||
../external/src/cryptonote/crypto-ops-data.c
|
||||
../external/src/cryptonote/crypto-ops.c
|
||||
../external/src/hardforks/hardforks.cpp
|
||||
|
@ -87,6 +89,7 @@ endif()
|
|||
|
||||
include_directories(../src)
|
||||
include_directories(../external/src)
|
||||
include_directories(../external/src/crypto)
|
||||
include_directories(../external/src/cryptonote)
|
||||
include_directories(${UV_INCLUDE_DIR})
|
||||
include_directories(../external/src/cppzmq)
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
namespace p2pool {
|
||||
|
||||
TEST(merkle, root_hash)
|
||||
TEST(merkle, tree)
|
||||
{
|
||||
hash input[10];
|
||||
uint8_t data[] = "data 0";
|
||||
|
@ -80,8 +80,8 @@ TEST(merkle, root_hash)
|
|||
std::vector<hash> proof2;
|
||||
proof2.reserve(proof.size());
|
||||
|
||||
for (const auto& i : proof) {
|
||||
proof2.emplace_back(i.second);
|
||||
for (const auto& p : proof) {
|
||||
proof2.emplace_back(p.second);
|
||||
}
|
||||
|
||||
ASSERT_TRUE(verify_merkle_proof(h, proof2, i, n, root));
|
||||
|
|
46
tests/src/sha256_tests.cpp
Normal file
46
tests/src/sha256_tests.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
|
||||
* Copyright (c) 2021-2023 SChernykh <https://github.com/SChernykh>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
extern "C" {
|
||||
#include "sha256.h"
|
||||
}
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
TEST(sha256, hashing)
|
||||
{
|
||||
auto check = [](const char* input, const char* output) {
|
||||
hash h;
|
||||
sha256(input, strlen(input), h.h);
|
||||
|
||||
char buf[128];
|
||||
log::Stream s(buf);
|
||||
s << h << '\0';
|
||||
|
||||
ASSERT_EQ(std::string(buf), std::string(output));
|
||||
};
|
||||
|
||||
check("", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
|
||||
check("test", "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08");
|
||||
check("The quick brown fox jumps over the lazy dog", "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592");
|
||||
check("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "2d8c2f6d978ca21712b5f6de36c9d31fa8e96a4fa5d8ff8b0188dfb9e7c171bb");
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue