Giter Site home page Giter Site logo

sha256's Introduction

SystemGlitch

I am a passionate developer and architect, always looking for improvement. I believe open-source software is a fantastic way of benefiting from the skills and experience of each individual in order to produce better, faster and stronger code. Everything must be documented, tested and linted!

Golang Typescript Vue.js Visual Studio Code

sha256's People

Contributors

lambourl avatar lestahl avatar qubka avatar system-glitch avatar thexxturboxx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

sha256's Issues

inline smaller functions to avoid calling overhead

Hello,

I noticed some functions in this SHA256 implementation aren't inlined (where they possibly can be inlined). These are rotr(), choose(), majority(), sig0(), and sig1(). Compiler by itself will not perform these smaller inlines (without specifying special parameters). This will remove the possible overhead of calling those functions and thus can improve performance.

How's it going?

Some good implementations are out there. This one looks pretty clean.

I was just going over Sha256 because I am trying out a Merkle Tree in C++. For that, I decided that to implement it with a list of hashes to take the place of tail duplication on the levels with odd number entries. Seems like a good idea that you could tie the root to a shared (Perhaps in some sort of Byzantine style of sharing) hash list.

But, for all the Sha256 implementations, a lot of them are cumbersome or a little out of date. Or I am missing something about some current issues.

Here is something that I am looking for. (Will put the same note there - likely.)

https://github.com/noloader/SHA-Intrinsics

Not sure if that is fully debugged.

Here is CUDA: https://gist.github.com/allanmac/8745837

How good is that? There is plenty of talk about fixing the bottleneck between the CPU and the GPU. But, those GPUs may be outside of most people's price range. It would be better if the GPU has intrinsics and then we could write a Merkle tree implementation in CUDA.

More work is going on: copiou-world

Error while executing.

/home/zD9b9O/ccqObZn7.o: In function SHA256::transform()': prog.cpp:(.text+0x25a): undefined reference to SHA256::K'
collect2: error: ld returned 1 exit status

I am using c++14, with main function:

`int main() {

std::string s = "hello world";
SHA256 sha;
sha.update(s);
uint8_t * digest = sha.digest();

std::cout << SHA256::toString(digest) << std::endl;

delete[] digest; 

return EXIT_SUCCESS;

}

`

Full code:
`
#include
#include
#include
#include
#include
#include
#include
#include

class SHA256 {

public:
SHA256();
void update(const uint8_t * data, size_t length);
void update(const std::string &data);
uint8_t * digest();

static std::string toString(const uint8_t * digest);

private:
uint8_t m_data[64];
uint32_t m_blocklen;
uint64_t m_bitlen;
uint32_t m_state[8]; //A, B, C, D, E, F, G, H

static constexpr std::array<uint32_t, 64> K = {
	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
};

static uint32_t rotr(uint32_t x, uint32_t n);
static uint32_t choose(uint32_t e, uint32_t f, uint32_t g);
static uint32_t majority(uint32_t a, uint32_t b, uint32_t c);
static uint32_t sig0(uint32_t x);
static uint32_t sig1(uint32_t x);
void transform();
void pad();
void revert(uint8_t * hash);

};

SHA256::SHA256(): m_blocklen(0), m_bitlen(0) {
m_state[0] = 0x6a09e667;
m_state[1] = 0xbb67ae85;
m_state[2] = 0x3c6ef372;
m_state[3] = 0xa54ff53a;
m_state[4] = 0x510e527f;
m_state[5] = 0x9b05688c;
m_state[6] = 0x1f83d9ab;
m_state[7] = 0x5be0cd19;
}

void SHA256::update(const uint8_t * data, size_t length) {
for (size_t i = 0 ; i < length ; i++) {
m_data[m_blocklen++] = data[i];
if (m_blocklen == 64) {
transform();

		// End of the block
		m_bitlen += 512;
		m_blocklen = 0;
	}
}

}

void SHA256::update(const std::string &data) {
update(reinterpret_cast<const uint8_t*> (data.c_str()), data.size());
}

uint8_t * SHA256::digest() {
uint8_t * hash = new uint8_t[32];

pad();
revert(hash);

return hash;

}

uint32_t SHA256::rotr(uint32_t x, uint32_t n) {
return (x >> n) | (x << (32 - n));
}

uint32_t SHA256::choose(uint32_t e, uint32_t f, uint32_t g) {
return (e & f) ^ (~e & g);
}

uint32_t SHA256::majority(uint32_t a, uint32_t b, uint32_t c) {
return (a & (b | c)) | (b & c);
}

uint32_t SHA256::sig0(uint32_t x) {
return SHA256::rotr(x, 7) ^ SHA256::rotr(x, 18) ^ (x >> 3);
}

uint32_t SHA256::sig1(uint32_t x) {
return SHA256::rotr(x, 17) ^ SHA256::rotr(x, 19) ^ (x >> 10);
}

void SHA256::transform() {
uint32_t maj, xorA, ch, xorE, sum, newA, newE, m[64];
uint32_t state[8];

for (uint8_t i = 0, j = 0; i < 16; i++, j += 4) { // Split data in 32 bit blocks for the 16 first words
	m[i] = (m_data[j] << 24) | (m_data[j + 1] << 16) | (m_data[j + 2] << 8) | (m_data[j + 3]);
}

for (uint8_t k = 16 ; k < 64; k++) { // Remaining 48 blocks
	m[k] = SHA256::sig1(m[k - 2]) + m[k - 7] + SHA256::sig0(m[k - 15]) + m[k - 16];
}

for(uint8_t i = 0 ; i < 8 ; i++) {
	state[i] = m_state[i];
}

for (uint8_t i = 0; i < 64; i++) {
	maj   = SHA256::majority(state[0], state[1], state[2]);
	xorA  = SHA256::rotr(state[0], 2) ^ SHA256::rotr(state[0], 13) ^ SHA256::rotr(state[0], 22);

	ch = choose(state[4], state[5], state[6]);

	xorE  = SHA256::rotr(state[4], 6) ^ SHA256::rotr(state[4], 11) ^ SHA256::rotr(state[4], 25);

	sum  = m[i] + K[i] + state[7] + ch + xorE;
	newA = xorA + maj + sum;
	newE = state[3] + sum;

	state[7] = state[6];
	state[6] = state[5];
	state[5] = state[4];
	state[4] = newE;
	state[3] = state[2];
	state[2] = state[1];
	state[1] = state[0];
	state[0] = newA;
}

for(uint8_t i = 0 ; i < 8 ; i++) {
	m_state[i] += state[i];
}

}

void SHA256::pad() {

uint64_t i = m_blocklen;
uint8_t end = m_blocklen < 56 ? 56 : 64;

m_data[i++] = 0x80; // Append a bit 1
while (i < end) {
	m_data[i++] = 0x00; // Pad with zeros
}

if(m_blocklen >= 56) {
	transform();
	memset(m_data, 0, 56);
}

// Append to the padding the total message's length in bits and transform.
m_bitlen += m_blocklen * 8;
m_data[63] = m_bitlen;
m_data[62] = m_bitlen >> 8;
m_data[61] = m_bitlen >> 16;
m_data[60] = m_bitlen >> 24;
m_data[59] = m_bitlen >> 32;
m_data[58] = m_bitlen >> 40;
m_data[57] = m_bitlen >> 48;
m_data[56] = m_bitlen >> 56;
transform();

}

void SHA256::revert(uint8_t * hash) {
// SHA uses big endian byte ordering
// Revert all bytes
for (uint8_t i = 0 ; i < 4 ; i++) {
for(uint8_t j = 0 ; j < 8 ; j++) {
hash[i + (j * 4)] = (m_state[j] >> (24 - i * 8)) & 0x000000ff;
}
}
}

std::string SHA256::toString(const uint8_t * digest) {
std::stringstream s;
s << std::setfill('0') << std::hex;

for(uint8_t i = 0 ; i < 32 ; i++) {
	s << std::setw(2) << (unsigned int) digest[i];
}

return s.str();

}

int main() {

std::string s = "hello world";
SHA256 sha;
sha.update(s);
uint8_t * digest = sha.digest();

std::cout << SHA256::toString(digest) << std::endl;

delete[] digest; 

return EXIT_SUCCESS;

}

`

I am running it on codechef ide.

I get array out of bounds error in void SHA256::update

void SHA256::update(const uint8_t* data, size_t length) {
    for (size_t i = 0; i < length; i++) {
        m_data[m_blocklen++] = data[i]; // ERROR HERE
        if (m_blocklen == 64) {
            transform();

            // End of the block
            m_bitlen += 512;
            m_blocklen = 0;
        }
    }
}

Here's how I use it:
static constexpr size_t HASH_SIZE = 32;

struct Block {
uint8_t hash[HASH_SIZE] = {};
uint8_t prev_hash[HASH_SIZE] = {};
std::vector<uint8_t> data = {};

void gen_hash()
{
    SHA256 hasher {};
    hasher.update(prev_hash, sizeof(prev_hash));
    hasher.update(data.data(), data.size());
    uint8_t* digest = hasher.digest();
    memcpy(hash, digest, sizeof(hash));
    delete[] digest;
}

}

I am not sure if I am using it correct, so sorry if problem's just me. (though I don't get this problem in rust for the same code using sha2 crate's SHA256 struct as a hasher, so that's why I decided to submit this issue, I will keep experimenting with the code and close the issue if it was my fault).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.