CryptoByLeo/Src/Hash/SHA512.mqh

743 行
26 KiB
MQL5

2026-08-13 14:01:20 -05:00
//+------------------------------------------------------------------+
//| SHA512.mqh |
//| Copyright 2026, Niquel Mendoza |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Niquel Mendoza"
#property link "https://www.mql5.com"
#property strict
#ifndef CRYPTOBYLEO_SRC_HASH_SHA512_MQH
#define CRYPTOBYLEO_SRC_HASH_SHA512_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include "Base.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-08-26 09:31:56 -05:00
#define CRYPTOBYLEO_SHA512_SIZET_FHASH (64)
#define CRYPTOBYLEO_SHA512_224_SIZET_FHASH (28)
#define CRYPTOBYLEO_SHA512_256_SIZET_FHASH (32)
#define CRYPTOBYLEO_SHA384_SIZET_FHASH (48)
2026-08-13 17:24:10 -05:00
//---
2026-08-13 14:01:20 -05:00
#define CRYPTOBYLEO_SHA512_SIZET_U64HASH (8)
// versiones simplificadoas de la original
// en ch
// 11
// base = (x AND y) XOR (NOT x AND z)
// el not es baicmante x XOR 1
// dado qeu si x = 0 0 XOR 1 = 1 y 1 XOR 1 = 0 (ahi esta flip volteado... )
// asi qeu quedaria (x AND y) XOR ((x XOR 1) AND z) AND tiene mayor precendecia, asi que podemos distirbyuir
// (x AND y) XOR ((x AND z) XOR (1 and Z))) (1 ANd x siempre da x comoresultado)
// (x AND y) XOR ((x AND z) Xor z)
// Desnetolalmos x AND y xor x AND z xor z , hay comunes facotiruzamos
// (x AND ((Y XOR Z)) XOR Z queda asi x and tiene mas priodiad que xor
// nuevo = z XOR (x AND (y XOR z)) reducico en 3 operaciones..
2026-08-13 17:24:10 -05:00
#define CRYPTOBYLEO_SHA2H_CH(x,y,z) ((z)^((x)&((y)^(z))))
2026-08-20 11:04:12 -05:00
#define CRYPTOBYLEO_SHA2H_MAJ ((a & b) ^ (a & c) ^ (b & c))
2026-08-13 14:01:20 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
/*
const uint32_t g_cryptbyleo_sha256_hinicial[CRYPTOBYLEO_SHA256_SIZET_U32HASH] =
{
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
};
*/
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-08-13 17:24:10 -05:00
const ulong g_cryptbyleo_sha2h_k[80] =
2026-08-13 14:01:20 -05:00
{
0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
};
//+------------------------------------------------------------------+
2026-08-13 17:24:10 -05:00
#define TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, b) ((v>>b) | (v <<(64 - b)))
2026-08-13 14:01:20 -05:00
2026-08-20 11:04:12 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#define SHA512_LOAD64(i) \
2026-08-20 17:10:56 -05:00
palabras[i] = uint64_t(inp[ip++]) << 56 | \
uint64_t(inp[ip++]) << 48 | \
uint64_t(inp[ip++]) << 40 | \
uint64_t(inp[ip++]) << 32 | \
uint64_t(inp[ip++]) << 24 | \
uint64_t(inp[ip++]) << 16 | \
uint64_t(inp[ip++]) << 8 | \
uint64_t(inp[ip++]);
2026-08-20 11:04:12 -05:00
//+------------------------------------------------------------------+
#define SHA512_LOAD64_X(i) \
palabras[i] = uint64_t(last_chunk[ip++]) << 56 | \
uint64_t(last_chunk[ip++]) << 48 | \
uint64_t(last_chunk[ip++]) << 40 | \
uint64_t(last_chunk[ip++]) << 32 | \
uint64_t(last_chunk[ip++]) << 24 | \
uint64_t(last_chunk[ip++]) << 16 | \
uint64_t(last_chunk[ip++]) << 8 | \
uint64_t(last_chunk[ip++]);
2026-08-13 14:01:20 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-08-20 17:10:56 -05:00
static void CCryptoHash::SHA2_HIGH(ulong &h[], const uchar &inp[], int ins)
2026-08-13 14:01:20 -05:00
{
//---------
// Base
uint64_t palabras[80];
2026-08-20 11:04:12 -05:00
// Procesamiento de chunks exactos de 128
int ip = 0;
while(ins - ip >= 128)
2026-08-13 14:01:20 -05:00
{
2026-08-13 18:48:30 -05:00
//---- Unrolled (Tomamos 128 bytes a 16 words)
2026-08-13 14:01:20 -05:00
SHA512_LOAD64(0)
SHA512_LOAD64(1)
SHA512_LOAD64(2)
SHA512_LOAD64(3)
SHA512_LOAD64(4)
SHA512_LOAD64(5)
SHA512_LOAD64(6)
SHA512_LOAD64(7)
SHA512_LOAD64(8)
SHA512_LOAD64(9)
SHA512_LOAD64(10)
SHA512_LOAD64(11)
SHA512_LOAD64(12)
SHA512_LOAD64(13)
SHA512_LOAD64(14)
SHA512_LOAD64(15)
2026-08-20 11:04:12 -05:00
//------------------------------------------------------------------------ start
2026-08-13 14:01:20 -05:00
//---
for(int i = 16; i < 80; i += 4)
{
uint64_t v, s0, s1;
v = palabras[i - 15];
2026-08-13 17:24:10 -05:00
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 1) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 8) ^ (v >> 7);
2026-08-13 14:01:20 -05:00
v = palabras[i - 2];
2026-08-13 17:24:10 -05:00
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 19) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 61) ^ (v >> 6);
2026-08-13 14:01:20 -05:00
palabras[i] = palabras[i - 16] + s0 + palabras[i - 7] + s1;
v = palabras[i - 14];
2026-08-13 17:24:10 -05:00
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 1) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 8) ^ (v >> 7);
2026-08-13 14:01:20 -05:00
v = palabras[i - 1];
2026-08-13 17:24:10 -05:00
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 19) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 61) ^ (v >> 6);
2026-08-13 14:01:20 -05:00
palabras[i + 1] = palabras[i - 15] + s0 + palabras[i - 6] + s1;
v = palabras[i - 13];
2026-08-13 17:24:10 -05:00
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 1) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 8) ^ (v >> 7);
2026-08-13 14:01:20 -05:00
v = palabras[i];
2026-08-13 17:24:10 -05:00
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 19) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 61) ^ (v >> 6);
2026-08-13 14:01:20 -05:00
palabras[i + 2] = palabras[i - 14] + s0 + palabras[i - 5] + s1;
v = palabras[i - 12];
2026-08-13 17:24:10 -05:00
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 1) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 8) ^ (v >> 7);
2026-08-13 14:01:20 -05:00
v = palabras[i + 1];
2026-08-13 17:24:10 -05:00
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 19) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 61) ^ (v >> 6);
2026-08-13 14:01:20 -05:00
palabras[i + 3] = palabras[i - 13] + s0 + palabras[i - 4] + s1;
}
2026-08-20 11:04:12 -05:00
uint64_t a = h[0], b = h[1], c = h[2], d = h[3];
uint64_t e = h[4], f = h[5], g = h[6], hh = h[7];
//---
// unrolled 8
for(int i = 0; i < 80; i += 8)
{
uint64_t t1, t2, s1, s0;
// ronda 0
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
// ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i] + palabras[i];
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
// maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
// ronda 1
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
//ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i + 1] + palabras[i + 1];
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
// maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
// ronda 2
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
// ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i + 2] + palabras[i + 2];
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
// maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
// ronda 3
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
// ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i + 3] + palabras[i + 3];
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
// maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
// ronda 4
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
//ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i + 4] + palabras[i + 4];
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
// maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
// ronda 5
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
// ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i + 5] + palabras[i + 5];
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
// maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
// ronda 6
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
//ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i + 6] + palabras[i + 6];
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
//maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
// ronda 7
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
// ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i + 7] + palabras[i + 7];
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
// maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
//---
h[0] += a;
h[1] += b;
h[2] += c;
h[3] += d;
h[4] += e;
h[5] += f;
h[6] += g;
h[7] += hh;
//------------------------------------------------------------------------ end
}
//--- Sobrante padding
uchar last_chunk[256];
//--- Ahora si
// layout:
/*[ mensaje original ][ 0x80 ][ ceros de relleno ][ longitud en 128 bits, Big Endian - 16 bytes ]*/
2026-08-20 11:04:12 -05:00
const int longitud_with_m = ins + 1 + 16;
const ulong bits_len_mes = (ulong)ins << 3ULL;
2026-08-13 14:01:20 -05:00
2026-08-20 11:04:12 -05:00
// %64 = &63
const int relleno_con_zeros = (128 - (longitud_with_m & 127)) & 127;
// longitud_with_m aqui lo podemos reintrepsta rcomo 1 extra y 8 de longitd fional BE
//--- Cuantos nos queda
ins -= ip;
2026-08-20 11:04:12 -05:00
// Copiamos los datos
for(int i = 0; i < ins; i++)
2026-08-20 17:10:56 -05:00
last_chunk[i] = inp[ip + i];
2026-08-20 11:04:12 -05:00
//--- sobrante
// Primero
last_chunk[ins++] = 0x80;
// Ahora los ceros
const int final_s = ins + relleno_con_zeros + 8; // final (+8 zeros extra, dado qeu la parte alta del len casi no se usa asi qeu..)
2026-08-20 11:04:12 -05:00
for(; ins < final_s; ins++)
{
last_chunk[ins] = 0; // zeros
}
// ins apunta ahora mismo luego del padding.. toca campo final
2026-08-20 11:04:12 -05:00
// Ahora si los ultimos
const int longitud_final = final_s + 8; //
2026-08-25 20:10:08 -05:00
ins = longitud_final - 1; //
2026-08-20 11:04:12 -05:00
//--- longitud en BE
2026-08-20 11:04:12 -05:00
for(int k = 0; ins >= final_s; ins--, k += 8)
{
// BE
// La idea es ir esribiendo lo que podmas aqui traemos los 8 bajos.
last_chunk[ins] = uint8_t(bits_len_mes >> k); // zeros
}
//--- procemos lastchunk
ip = 0;
for(; ip < longitud_final;)
{
//----
SHA512_LOAD64_X(0)
SHA512_LOAD64_X(1)
SHA512_LOAD64_X(2)
SHA512_LOAD64_X(3)
SHA512_LOAD64_X(4)
SHA512_LOAD64_X(5)
SHA512_LOAD64_X(6)
SHA512_LOAD64_X(7)
SHA512_LOAD64_X(8)
SHA512_LOAD64_X(9)
SHA512_LOAD64_X(10)
SHA512_LOAD64_X(11)
SHA512_LOAD64_X(12)
SHA512_LOAD64_X(13)
SHA512_LOAD64_X(14)
SHA512_LOAD64_X(15)
//------------------------------------------------------------------------ start
2026-08-13 14:01:20 -05:00
//---
2026-08-20 11:04:12 -05:00
for(int i = 16; i < 80; i += 4)
{
uint64_t v, s0, s1;
v = palabras[i - 15];
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 1) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 8) ^ (v >> 7);
v = palabras[i - 2];
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 19) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 61) ^ (v >> 6);
palabras[i] = palabras[i - 16] + s0 + palabras[i - 7] + s1;
v = palabras[i - 14];
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 1) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 8) ^ (v >> 7);
v = palabras[i - 1];
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 19) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 61) ^ (v >> 6);
palabras[i + 1] = palabras[i - 15] + s0 + palabras[i - 6] + s1;
v = palabras[i - 13];
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 1) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 8) ^ (v >> 7);
v = palabras[i];
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 19) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 61) ^ (v >> 6);
palabras[i + 2] = palabras[i - 14] + s0 + palabras[i - 5] + s1;
v = palabras[i - 12];
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 1) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 8) ^ (v >> 7);
v = palabras[i + 1];
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 19) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, 61) ^ (v >> 6);
palabras[i + 3] = palabras[i - 13] + s0 + palabras[i - 4] + s1;
}
2026-08-13 14:01:20 -05:00
uint64_t a = h[0], b = h[1], c = h[2], d = h[3];
uint64_t e = h[4], f = h[5], g = h[6], hh = h[7];
//---
// unrolled 8
for(int i = 0; i < 80; i += 8)
{
2026-08-20 11:04:12 -05:00
uint64_t t1, t2, s1, s0;
2026-08-13 14:01:20 -05:00
// ronda 0
2026-08-13 17:24:10 -05:00
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
2026-08-20 11:04:12 -05:00
// ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i] + palabras[i];
2026-08-13 17:24:10 -05:00
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
2026-08-20 11:04:12 -05:00
// maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
2026-08-13 14:01:20 -05:00
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
// ronda 1
2026-08-13 17:24:10 -05:00
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
2026-08-20 11:04:12 -05:00
//ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i + 1] + palabras[i + 1];
2026-08-13 17:24:10 -05:00
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
2026-08-20 11:04:12 -05:00
// maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
2026-08-13 14:01:20 -05:00
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
// ronda 2
2026-08-13 17:24:10 -05:00
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
2026-08-20 11:04:12 -05:00
// ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i + 2] + palabras[i + 2];
2026-08-13 17:24:10 -05:00
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
2026-08-20 11:04:12 -05:00
// maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
2026-08-13 14:01:20 -05:00
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
// ronda 3
2026-08-13 17:24:10 -05:00
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
2026-08-20 11:04:12 -05:00
// ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i + 3] + palabras[i + 3];
2026-08-13 17:24:10 -05:00
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
2026-08-20 11:04:12 -05:00
// maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
2026-08-13 14:01:20 -05:00
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
// ronda 4
2026-08-13 17:24:10 -05:00
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
2026-08-20 11:04:12 -05:00
//ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i + 4] + palabras[i + 4];
2026-08-13 17:24:10 -05:00
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
2026-08-20 11:04:12 -05:00
// maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
2026-08-13 14:01:20 -05:00
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
// ronda 5
2026-08-13 17:24:10 -05:00
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
2026-08-20 11:04:12 -05:00
// ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i + 5] + palabras[i + 5];
2026-08-13 17:24:10 -05:00
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
2026-08-20 11:04:12 -05:00
// maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
2026-08-13 14:01:20 -05:00
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
// ronda 6
2026-08-13 17:24:10 -05:00
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
2026-08-20 11:04:12 -05:00
//ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i + 6] + palabras[i + 6];
2026-08-13 17:24:10 -05:00
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
2026-08-20 11:04:12 -05:00
//maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
2026-08-13 14:01:20 -05:00
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
// ronda 7
2026-08-13 17:24:10 -05:00
s1 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 14) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 18) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(e, 41);
2026-08-20 11:04:12 -05:00
// ch = CRYPTOBYLEO_SHA2H_CH(e, f, g);
t1 = hh + s1 + CRYPTOBYLEO_SHA2H_CH(e, f, g) + g_cryptbyleo_sha2h_k[i + 7] + palabras[i + 7];
2026-08-13 17:24:10 -05:00
s0 = TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 28) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 34) ^ TSN_CRYPTBYLEO_SHA2H_ROT_DER(a, 39);
2026-08-20 11:04:12 -05:00
// maj = CRYPTOBYLEO_SHA2H_MAJ;
t2 = s0 + CRYPTOBYLEO_SHA2H_MAJ;
2026-08-13 14:01:20 -05:00
hh = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
//---
h[0] += a;
h[1] += b;
h[2] += c;
h[3] += d;
h[4] += e;
h[5] += f;
h[6] += g;
h[7] += hh;
2026-08-20 11:04:12 -05:00
//------------------------------------------------------------------------ end
2026-08-13 14:01:20 -05:00
}
2026-08-13 17:24:10 -05:00
}
2026-08-13 14:01:20 -05:00
2026-08-13 17:24:10 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-08-13 14:01:20 -05:00
//---
#define CRYPTOHASHBYLEO_HASH_ASSING64(INDEX) \
2026-08-20 17:10:56 -05:00
out[o_s+INDEX] = uint8_t(t >> 56); \
out[o_s+INDEX+1] = uint8_t(t >> 48); \
out[o_s+INDEX+2] = uint8_t(t >> 40); \
out[o_s+INDEX+3] = uint8_t(t >> 32); \
out[o_s+INDEX+4] = uint8_t(t >> 24); \
out[o_s+INDEX+5] = uint8_t(t >> 16); \
out[o_s+INDEX+6] = uint8_t(t >> 8); \
out[o_s+INDEX+7] = uint8_t(t);
2026-08-13 14:01:20 -05:00
2026-08-13 17:24:10 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-08-20 17:10:56 -05:00
static void CCryptoHash::SHA512(const uchar &inp[], int ins, uchar& out[], const int o_s)
2026-08-13 17:24:10 -05:00
{
//--- iv iniical
uint64_t h[8] =
{
0x6a09e667f3bcc908,
0xbb67ae8584caa73b,
0x3c6ef372fe94f82b,
0xa54ff53a5f1d36f1,
0x510e527fade682d1,
0x9b05688c2b3e6c1f,
0x1f83d9abfb41bd6b,
0x5be0cd19137e2179
};
//---
2026-08-20 17:10:56 -05:00
SHA2_HIGH(h, inp, ins);
2026-08-13 17:24:10 -05:00
2026-08-13 14:01:20 -05:00
//---
uint64_t t = h[0];
CRYPTOHASHBYLEO_HASH_ASSING64(0)
t = h[1];
CRYPTOHASHBYLEO_HASH_ASSING64(8)
t = h[2];
CRYPTOHASHBYLEO_HASH_ASSING64(16)
t = h[3];
CRYPTOHASHBYLEO_HASH_ASSING64(24)
t = h[4];
CRYPTOHASHBYLEO_HASH_ASSING64(32)
t = h[5];
CRYPTOHASHBYLEO_HASH_ASSING64(40)
t = h[6];
CRYPTOHASHBYLEO_HASH_ASSING64(48)
t = h[7];
CRYPTOHASHBYLEO_HASH_ASSING64(56)
2026-08-13 17:24:10 -05:00
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-08-20 17:10:56 -05:00
static void CCryptoHash::SHA384(const uchar &inp[], int ins, uchar &out[], const int o_s)
2026-08-13 17:24:10 -05:00
{
//--- iv iniical
uint64_t h[8] =
{
0xcbbb9d5dc1059ed8,
0x629a292a367cd507,
0x9159015a3070dd17,
0x152fecd8f70e5939,
0x67332667ffc00b31,
0x8eb44a8768581511,
0xdb0c2e0d64f98fa7,
0x47b5481dbefa4fa4
};
2026-08-13 14:01:20 -05:00
//---
2026-08-20 17:10:56 -05:00
SHA2_HIGH(h, inp, ins);
2026-08-13 17:24:10 -05:00
//---
uint64_t t = h[0];
CRYPTOHASHBYLEO_HASH_ASSING64(0)
t = h[1];
CRYPTOHASHBYLEO_HASH_ASSING64(8)
t = h[2];
CRYPTOHASHBYLEO_HASH_ASSING64(16)
t = h[3];
CRYPTOHASHBYLEO_HASH_ASSING64(24)
t = h[4];
CRYPTOHASHBYLEO_HASH_ASSING64(32)
t = h[5];
CRYPTOHASHBYLEO_HASH_ASSING64(40)
2026-08-13 14:01:20 -05:00
}
2026-08-25 20:10:08 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
static void CCryptoHash::SHA512_256(const uchar &inp[], int ins, uchar& out[], const int o_s)
{
//--- iv inicial (FIPS 180-4 §5.3.6.2)
uint64_t h[8] =
{
0x22312194fc2bf72c,
0x9f555fa3c84c64c2,
0x2393b86b6f53b151,
0x963877195940eabd,
0x96283ee2a88effe3,
0xbe5e1e2553863992,
0x2b0199fc2c85b8aa,
0x0eb72ddc81c52ca2
};
//---
SHA2_HIGH(h, inp, ins);
//---
uint64_t t = h[0];
CRYPTOHASHBYLEO_HASH_ASSING64(0)
t = h[1];
CRYPTOHASHBYLEO_HASH_ASSING64(8)
t = h[2];
CRYPTOHASHBYLEO_HASH_ASSING64(16)
t = h[3];
CRYPTOHASHBYLEO_HASH_ASSING64(24)
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#define CRYPTOHASHBYLEO_HASH_ASSING32HI(INDEX) \
out[o_s+INDEX] = uint8_t(t >> 56); \
out[o_s+INDEX+1] = uint8_t(t >> 48); \
out[o_s+INDEX+2] = uint8_t(t >> 40); \
out[o_s+INDEX+3] = uint8_t(t >> 32);
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
static void CCryptoHash::SHA512_224(const uchar &inp[], int ins, uchar& out[], const int o_s)
{
//--- iv inicial (FIPS 180-4 §5.3.6.1)
uint64_t h[8] =
{
0x8c3d37c819544da2,
0x73e1996689dcd4d6,
0x1dfab7ae32ff9c82,
0x679dd514582f9fcf,
0x0f6d2b697bd44da8,
0x77e36f7304c48942,
0x3f9d85a86a1d36c8,
0x1112e6ad91d692a1
};
//---
SHA2_HIGH(h, inp, ins);
//---
uint64_t t = h[0];
CRYPTOHASHBYLEO_HASH_ASSING64(0)
t = h[1];
CRYPTOHASHBYLEO_HASH_ASSING64(8)
t = h[2];
CRYPTOHASHBYLEO_HASH_ASSING64(16)
t = h[3];
CRYPTOHASHBYLEO_HASH_ASSING32HI(24) // solo los 4 bytes altos, out queda en 28 bytes totales
}
2026-08-13 14:01:20 -05:00
//--- Namepsace TSN
}
#endif // CRYPTOBYLEO_SRC_HASH_SHA512_MQH