//+------------------------------------------------------------------+ //| 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" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #define CRYPTOBYLEO_SHA512_SIZET_FHASH (64) #define CRYPTOBYLEO_SHA384_SIZET_FHASH (48) //--- #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.. #define CRYPTOBYLEO_SHA2H_CH(x,y,z) ((z)^((x)&((y)^(z)))) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ /* const uint32_t g_cryptbyleo_sha256_hinicial[CRYPTOBYLEO_SHA256_SIZET_U32HASH] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; */ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ const ulong g_cryptbyleo_sha2h_k[80] = { 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 }; //+------------------------------------------------------------------+ #define TSN_CRYPTBYLEO_SHA2H_ROT_DER(v, b) ((v>>b) | (v <<(64 - b))) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ namespace TSN { //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void CCryptoHash::SHA2_HIGH(ulong &h[], const uchar &inp[], int ins) { //--- Pase inical tema de padding int longitud_with_m = ins + 1 + 16; const ulong bits_len_mes = (ulong)ins << 3ULL; // %64 = &63 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 uchar in[]; ArrayResize(in, (longitud_with_m + relleno_con_zeros)); // ArrayInitialize(in,0); // Copiamos los datos for(int i = 0; i < ins; i++) { in[i] = inp[i]; } // Primero in[ins++] = 0x80; // Ahora los ceros const int final_s = ins + relleno_con_zeros; // final for(; ins < final_s; ins++) { in[ins] = 0; // zeros } // Ahora si los ultimos const int longitud_final = final_s + 16; // ins = longitud_final - 1; // + 7 por que (+ 8 -1 8 para el final y -1 empza en el utlimo el) for(int k = 0; ins >= final_s; ins--, k += 8) { // BE // La idea es ir esribiendo lo que podmas aqui traemos los 8 bajos. in[ins] = uint8_t(bits_len_mes >> k); // zeros } //--------- // Base uint64_t palabras[80]; // Algoritmo en si for(int ip = 0; ip < longitud_final;) { //--- /* // pasamos a palabras de 32 (primante 16) for(int i = 0; i < 16; i++) { } */ //---- Unrolled (Tomamos 128 bytes a 16 words) #define SHA512_LOAD64(i) \ palabras[i] = uint64_t(in[ip++]) << 56 | \ uint64_t(in[ip++]) << 48 | \ uint64_t(in[ip++]) << 40 | \ uint64_t(in[ip++]) << 32 | \ uint64_t(in[ip++]) << 24 | \ uint64_t(in[ip++]) << 16 | \ uint64_t(in[ip++]) << 8 | \ uint64_t(in[ip++]); //--- 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) //--- // Ahora las expandimos 16 a 80 palarbras (para nuestro bloque final) for(int i = 16; i < 80; i += 4) { uint64_t v, s0, s1; //--- ronda 1 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; //--- ronda 2 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; //--- ronda 3 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; //--- ronda 4 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; } //--- // Ahora comprimirmos... 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, ch, maj; // 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 + ch + 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 = (a & b) ^ (a & c) ^ (b & c); t2 = s0 + 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 + ch + 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 = (a & b) ^ (a & c) ^ (b & c); t2 = s0 + 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 + ch + 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 = (a & b) ^ (a & c) ^ (b & c); t2 = s0 + 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 + ch + 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 = (a & b) ^ (a & c) ^ (b & c); t2 = s0 + 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 + ch + 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 = (a & b) ^ (a & c) ^ (b & c); t2 = s0 + 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 + ch + 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 = (a & b) ^ (a & c) ^ (b & c); t2 = s0 + 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 + ch + 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 = (a & b) ^ (a & c) ^ (b & c); t2 = s0 + 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 + ch + 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 = (a & b) ^ (a & c) ^ (b & c); t2 = s0 + 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; //--- Sigueinte bloque //ip += 64; } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //--- #define CRYPTOHASHBYLEO_HASH_ASSING64(INDEX) \ out[INDEX] = uint8_t(t >> 56); \ out[INDEX+1] = uint8_t(t >> 48); \ out[INDEX+2] = uint8_t(t >> 40); \ out[INDEX+3] = uint8_t(t >> 32); \ out[INDEX+4] = uint8_t(t >> 24); \ out[INDEX+5] = uint8_t(t >> 16); \ out[INDEX+6] = uint8_t(t >> 8); \ out[INDEX+7] = uint8_t(t); //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void CCryptoHash::SHA512(const uchar &inp[], int ins, uchar& out[]) { //--- iv iniical uint64_t h[8] = { 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179 }; //--- 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) 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) } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void CCryptoHash::SHA384(const uchar &inp[], int ins, uchar &out[]) { //--- iv iniical uint64_t h[8] = { 0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939, 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4 }; //--- 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) t = h[4]; CRYPTOHASHBYLEO_HASH_ASSING64(32) t = h[5]; CRYPTOHASHBYLEO_HASH_ASSING64(40) } //--- Namepsace TSN } #endif // CRYPTOBYLEO_SRC_HASH_SHA512_MQH