151 lines
4.6 KiB
C
151 lines
4.6 KiB
C
|
#include "sha3.h"
|
||
|
#include "obtc.h"
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void CSHA3_256_Write(CSHA3_256 *p, const unsigned char* data, size_t len) {
|
||
|
sha3_update(&p->context, data, len);
|
||
|
//return *this;
|
||
|
}
|
||
|
|
||
|
void CSHA3_256_Finalize(CSHA3_256 *p, unsigned char hash[OUTPUT_SIZE]) {
|
||
|
sha3_final(hash, &p->context);
|
||
|
}
|
||
|
|
||
|
/*void CSHA3_256_Reset(Obtc_t *Obtc, CSHA3_256 *p) {
|
||
|
sha3_init(Obtc,&p->context, OUTPUT_SIZE);
|
||
|
//return *this;
|
||
|
}*/
|
||
|
|
||
|
void CSHA3_256_init(Obtc_t *Obtc, CSHA3_256 *p) {
|
||
|
|
||
|
sha3_init(Obtc, &p->context, OUTPUT_SIZE);
|
||
|
|
||
|
p->Write = CSHA3_256_Write;
|
||
|
p->Finalize = CSHA3_256_Finalize;
|
||
|
//p->Reset = CSHA3_256_Reset;
|
||
|
}
|
||
|
|
||
|
void CSHA3_256_CSHA3_256(Obtc_t *Obtc,CSHA3_256 *p) {
|
||
|
sha3_init(Obtc,&p->context, OUTPUT_SIZE);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void CHeavyHash_Write(CHeavyHash *p, const unsigned char* data, size_t len) {
|
||
|
p->hasher.Write(&p->hasher,data, len);
|
||
|
//sha3_update(&CSHA3_256_p.context, data, len);
|
||
|
//CSHA3_256_Write(&CSHA3_256_p, data, OUTPUT_SIZE);
|
||
|
}
|
||
|
|
||
|
void CHeavyHash_Finalize(Obtc_t *Obtc, CHeavyHash *p, unsigned char hash[OUTPUT_SIZE]) {
|
||
|
uint256 hash_first;
|
||
|
uint8_t a[32];
|
||
|
|
||
|
p->hasher.Finalize(&p->hasher,&Obtc->g_hash_first.bb.data[0]);
|
||
|
memcpy(a,&Obtc->g_hash_first.bb.data[0],32);
|
||
|
|
||
|
uint256 product = MultiplyUsing4bitPrecision(p->matrix, Obtc->g_hash_first);
|
||
|
|
||
|
uint256 hash_xored;
|
||
|
for (size_t i = 0; i < OUTPUT_SIZE; ++i) {
|
||
|
//hash_xored.begin()[i] = hash_first.begin()[i] ^ product.begin()[i];
|
||
|
hash_xored.bb.data[i] = Obtc->g_hash_first.bb.data[i] ^ product.bb.data[i];
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
uint8_t temp[200]={
|
||
|
0x16,0x19,0x32,0x7d,0x10,0xb9,0xda,0x35,0x54,0x9a,0xe0,0x31,0x2f,0x9f,0xc6,0x15,0x92,0xbb,0x39,0x9d,
|
||
|
0xb5,0x29,0x0c,0x0a,0x47,0xc3,0x9f,0x67,0x51,0x12,0xc2,0x2e,0xc7,0x76,0xc5,0x04,0x84,0x81,0xb9,0x57,
|
||
|
0xb9,0x92,0xf2,0xd3,0x7b,0x34,0xca,0x58,0xea,0x8f,0xdb,0x80,0xba,0xc4,0x6d,0x39,0x7e,0x8f,0x1d,0xb1,
|
||
|
0x77,0x65,0xcc,0x07,0x87,0xe9,0x61,0xb0,0x36,0xbc,0x94,0x16,0x77,0x4c,0x86,0x83,0x54,0x34,0xf2,0xb0,
|
||
|
0x4e,0xf7,0x4b,0x3a,0x99,0xcd,0xb0,0x44,0x2e,0xc6,0x5b,0xd3,0x56,0x24,0x93,0xe4,0x6c,0x6b,0x7d,0x01,
|
||
|
0xa7,0x69,0xcc,0x3d,0xd3,0x1f,0x4c,0xc3,0x54,0xc1,0x8c,0x3f,0xf4,0x31,0xc0,0x5d,0xd0,0xa9,0xa2,0x26,
|
||
|
0xa0,0xbc,0xaa,0x9f,0x79,0x2a,0x3d,0x0c,0x80,0x39,0xf9,0xa6,0x0d,0xcf,0x6a,0x48,0x5e,0x21,0x90,0x40,
|
||
|
0x25,0x0f,0xc4,0x62,0xc1,0x00,0xff,0x2a,0x93,0x89,0x35,0xba,0x72,0xc7,0xd8,0x2e,0x14,0xf3,0x40,0x69,
|
||
|
0xe7,0x20,0xe0,0xdf,0x44,0xee,0xce,0xde,0x11,0xa7,0x5f,0x4c,0x80,0x05,0x64,0x98,0x7a,0x14,0xff,0x48,
|
||
|
0x16,0xc7,0xf8,0xee,0x79,0x62,0x9b,0x0e,0x2f,0x9f,0x42,0x16,0x3a,0xd7,0x4c,0x52,0xb2,0x24,0x85,0x09,
|
||
|
};
|
||
|
for(int i = 0 ;i< 200 ;i++)Obtc->const_data[i] = temp[i];
|
||
|
|
||
|
// CSHA3_256().Write(hash_xored.begin(), OUTPUT_SIZE).Finalize(hash);
|
||
|
|
||
|
CSHA3_256_CSHA3_256(Obtc, &p->hasher);
|
||
|
CSHA3_256_Write(&p->hasher, &hash_xored.bb.data[0], OUTPUT_SIZE);
|
||
|
CSHA3_256_Finalize(&p->hasher, hash) ;
|
||
|
}
|
||
|
|
||
|
void CHeavyHash_Reset(CHeavyHash *p, uint64_t matrix_[64*64]) {
|
||
|
for (int i = 0; i < 64*64; ++i)
|
||
|
p->matrix[i] = matrix_[i];
|
||
|
}
|
||
|
|
||
|
void CHeavyHash_init(Obtc_t *Obtc, CHeavyHash *p, uint64_t matrix_[64*64]){
|
||
|
|
||
|
p->Write = CHeavyHash_Write;
|
||
|
p->Finalize = CHeavyHash_Finalize;
|
||
|
p->Reset = CHeavyHash_Reset;
|
||
|
|
||
|
p->hasher.Write = CSHA3_256_Write;
|
||
|
p->hasher.Finalize = CSHA3_256_Finalize;
|
||
|
//p->hasher.Reset = CSHA3_256_Reset;
|
||
|
|
||
|
sha3_init(Obtc, &p->hasher.context, OUTPUT_SIZE);
|
||
|
|
||
|
for (int i = 0; i < 64*64; ++i)
|
||
|
p->matrix[i] = matrix_[i];
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void MultiplyMatrices(uint64_t matrix[64*64], uint64_t vector[64], uint64_t product[64]){
|
||
|
for (int i = 0; i < 64; ++i) {
|
||
|
for (int j = 0; j < 64; ++j) {
|
||
|
product[i] += matrix[64*i + j]*vector[j];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint256 MultiplyUsing4bitPrecision(uint64_t matrix[64*64], const uint256 hash) {
|
||
|
// conversion to matrix with 4 bit values
|
||
|
uint64_t vector[64] = {0};
|
||
|
ConvertTo4BitPrecisionVector(hash, vector);
|
||
|
|
||
|
// perform matrix multiplication
|
||
|
uint64_t product[64] = {0};
|
||
|
MultiplyMatrices(matrix, vector, product);
|
||
|
for (int i = 0; i < 64; ++i) {
|
||
|
product[i] >>= 10;
|
||
|
}
|
||
|
return Convert4bitVectorToUint(product);
|
||
|
}
|
||
|
|
||
|
void ConvertTo4BitPrecisionVector(uint256 bit_sequence, uint64_t vector[64]) {
|
||
|
int index = 0;
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < WIDTH; i++) {
|
||
|
|
||
|
vector[index] = bit_sequence.bb.data[i] >> 4;
|
||
|
vector[index+1] = bit_sequence.bb.data[i] & 0xF;
|
||
|
index += 2;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint256 Convert4bitVectorToUint(const uint64_t x[64]) {
|
||
|
uint256 bit_sequence;
|
||
|
int index = 0;
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < WIDTH; i++) {
|
||
|
bit_sequence.bb.data[i] = ( x[index] << 4) | x[index+1];
|
||
|
index += 2;
|
||
|
}
|
||
|
|
||
|
return bit_sequence;
|
||
|
}
|