2026-08-11 10:06:33 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Blake2b.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_BLACK2B_MQH
|
|
|
|
|
#define CRYPTOBYLEO_SRC_HASH_BLACK2B_MQH
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#include "Base.mqh"
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#define BLAKE2B_G(v,a,bb,c,d,x,y) \
|
|
|
|
|
v[a] = v[a] + v[bb] + x; \
|
|
|
|
|
{ulong _t = v[d]^v[a]; v[d] = (_t >> 32) | (_t << 32);} \
|
|
|
|
|
v[c] = v[c] + v[d]; \
|
|
|
|
|
{ulong _t = v[bb]^v[c]; v[bb] = (_t >> 24) | (_t << 40);} \
|
|
|
|
|
v[a] = v[a] + v[bb] + y; \
|
|
|
|
|
{ulong _t = v[d]^v[a]; v[d] = (_t >> 16) | (_t << 48);} \
|
|
|
|
|
v[c] = v[c] + v[d]; \
|
|
|
|
|
{ulong _t = v[bb]^v[c]; v[bb] = (_t >> 63) | (_t << 1);}
|
|
|
|
|
#define BLAKE2B_BLOCKBYTES (128)
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
namespace TSN
|
|
|
|
|
{
|
|
|
|
|
static void CCryptoHash::BLAKE2B(const uchar &in[], int ins, uchar &out[], int outl = 64)
|
|
|
|
|
{
|
|
|
|
|
//-- base
|
|
|
|
|
// modificable (state final) esto luego lo pasrmeos a out
|
|
|
|
|
ulong h[8] =
|
|
|
|
|
{
|
|
|
|
|
0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
|
|
|
|
|
0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
|
|
|
|
|
0x510e527fade682d1, 0x9b05688c2b3e6c1f,
|
|
|
|
|
0x1f83d9abfb41bd6b, 0x5be0cd19137e2179
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// tabla 2 (como un uni)
|
|
|
|
|
static const uchar SIGMA[192] =
|
|
|
|
|
{
|
|
|
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
|
|
|
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3,
|
|
|
|
|
11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4,
|
|
|
|
|
7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8,
|
|
|
|
|
9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13,
|
|
|
|
|
2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9,
|
|
|
|
|
12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11,
|
|
|
|
|
13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10,
|
|
|
|
|
6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5,
|
|
|
|
|
10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0,
|
|
|
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
|
|
|
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//----
|
|
|
|
|
h[0] ^= (ulong)0x01010000 | (ulong)outl; // key_len=0, fanout=1, depth=1
|
|
|
|
|
|
|
|
|
|
//----
|
|
|
|
|
ulong t0 = 0, t1 = 0;
|
|
|
|
|
|
|
|
|
|
//--- numero de bloques a procesar
|
|
|
|
|
int blocks = (ins + 127) >> 7; // / 128;
|
|
|
|
|
if(blocks == 0)
|
|
|
|
|
blocks = 1;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
ulong v[16]; // vector de trabaajo v
|
2026-08-12 16:03:47 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
union u64_u8_block
|
|
|
|
|
{
|
|
|
|
|
ulong palabras[16]; // palabras (m)
|
|
|
|
|
uchar block[BLAKE2B_BLOCKBYTES]; // chunk que se procesa
|
|
|
|
|
} w;
|
2026-08-11 10:06:33 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
for(int b = 0; b < blocks; b++)
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
const int off = b << 7; // * BLAKE2B_BLOCKBYTES;
|
|
|
|
|
const bool is_l = (b == blocks - 1);
|
|
|
|
|
int chunk = ins - off;
|
|
|
|
|
if(chunk > BLAKE2B_BLOCKBYTES)
|
|
|
|
|
chunk = BLAKE2B_BLOCKBYTES;
|
2026-08-12 16:03:47 -05:00
|
|
|
else
|
|
|
|
|
if(chunk < 0)
|
|
|
|
|
chunk = 0;
|
2026-08-11 10:06:33 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
for(int i = chunk; i < BLAKE2B_BLOCKBYTES; i++)
|
2026-08-12 16:03:47 -05:00
|
|
|
w.block[i] = 0;
|
2026-08-11 10:06:33 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
for(int i = 0; i < chunk; i++)
|
2026-08-12 16:03:47 -05:00
|
|
|
w.block[i] = in[off + i];
|
2026-08-11 10:06:33 -05:00
|
|
|
|
|
|
|
|
//--- Contadores..
|
|
|
|
|
const ulong inc = is_l ? (ulong)chunk : 128ULL;
|
|
|
|
|
t0 += inc;
|
|
|
|
|
t1 += (t0 < inc);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
// Comprirmimos. a 16 parnas en LE
|
2026-08-13 17:24:10 -05:00
|
|
|
// Ya no es necasrio solo reinterepretamos
|
|
|
|
|
/* for(int i = 0; i < 16; i++)
|
|
|
|
|
{
|
|
|
|
|
const int p = i << 3;
|
|
|
|
|
palabras[i] = (ulong)block[p] | ((ulong)block[p + 1] << 8) |
|
|
|
|
|
((ulong)block[p + 2] << 16) | ((ulong)block[p + 3] << 24) |
|
|
|
|
|
((ulong)block[p + 4] << 32) | ((ulong)block[p + 5] << 40) |
|
|
|
|
|
((ulong)block[p + 6] << 48) | ((ulong)block[p + 7] << 56);
|
|
|
|
|
}
|
|
|
|
|
*/
|
2026-08-11 10:06:33 -05:00
|
|
|
//---
|
|
|
|
|
/* for(int i = 0; i < 8; i++)
|
|
|
|
|
{
|
|
|
|
|
v[i] = h[i];
|
|
|
|
|
v[i + 8] = iv[i];
|
|
|
|
|
}*/
|
|
|
|
|
// Desenrollado
|
|
|
|
|
// Parte 1
|
|
|
|
|
v[0] = h[0];
|
|
|
|
|
v[1] = h[1];
|
|
|
|
|
v[2] = h[2];
|
|
|
|
|
v[3] = h[3];
|
|
|
|
|
v[4] = h[4];
|
|
|
|
|
v[5] = h[5];
|
|
|
|
|
v[6] = h[6];
|
|
|
|
|
v[7] = h[7];
|
|
|
|
|
|
2026-08-13 17:24:10 -05:00
|
|
|
//--- iv base
|
|
|
|
|
/*
|
|
|
|
|
const ulong iv[8] =
|
|
|
|
|
{
|
|
|
|
|
0x6a09e667f3bcc908,
|
|
|
|
|
0xbb67ae8584caa73b,
|
|
|
|
|
0x3c6ef372fe94f82b,
|
|
|
|
|
0xa54ff53a5f1d36f1,
|
|
|
|
|
0x510e527fade682d1,
|
|
|
|
|
0x9b05688c2b3e6c1f,
|
|
|
|
|
0x1f83d9abfb41bd6b,
|
|
|
|
|
0x5be0cd19137e2179
|
|
|
|
|
};
|
|
|
|
|
*/
|
|
|
|
|
|
2026-08-11 10:06:33 -05:00
|
|
|
// Parte 2
|
2026-08-13 17:24:10 -05:00
|
|
|
v[8] = 0x6a09e667f3bcc908; // iv[0];
|
|
|
|
|
v[9] = 0xbb67ae8584caa73b; // iv[1];
|
|
|
|
|
v[10] = 0x3c6ef372fe94f82b; // iv[2];
|
|
|
|
|
v[11] = 0xa54ff53a5f1d36f1; // iv[3];
|
|
|
|
|
v[12] = 0x510e527fade682d1 ^ t0;
|
|
|
|
|
v[13] = 0x9b05688c2b3e6c1f ^ t1;
|
2026-08-11 10:06:33 -05:00
|
|
|
/*
|
|
|
|
|
if(is_l)
|
|
|
|
|
v[14] = ~v[14];
|
|
|
|
|
*/
|
2026-08-13 17:24:10 -05:00
|
|
|
v[14] = 0x1f83d9abfb41bd6b ^ (is_l ? ~0ULL : 0ULL);
|
|
|
|
|
v[15] = 0x5be0cd19137e2179; // iv[7];
|
2026-08-11 10:06:33 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//--- Compresion Rondas finales (funcion F)
|
|
|
|
|
for(int r = 0; r < 12; r++)
|
|
|
|
|
{
|
|
|
|
|
//--- Ronda
|
|
|
|
|
const int base = r << 4;
|
2026-08-12 16:03:47 -05:00
|
|
|
BLAKE2B_G(v, 0, 4, 8, 12, w.palabras[SIGMA[base + 0]], w.palabras[SIGMA[base + 1]]);
|
|
|
|
|
BLAKE2B_G(v, 1, 5, 9, 13, w.palabras[SIGMA[base + 2]], w.palabras[SIGMA[base + 3]]);
|
|
|
|
|
BLAKE2B_G(v, 2, 6, 10, 14, w.palabras[SIGMA[base + 4]], w.palabras[SIGMA[base + 5]]);
|
|
|
|
|
BLAKE2B_G(v, 3, 7, 11, 15, w.palabras[SIGMA[base + 6]], w.palabras[SIGMA[base + 7]]);
|
|
|
|
|
BLAKE2B_G(v, 0, 5, 10, 15, w.palabras[SIGMA[base + 8]], w.palabras[SIGMA[base + 9]]);
|
|
|
|
|
BLAKE2B_G(v, 1, 6, 11, 12, w.palabras[SIGMA[base + 10]], w.palabras[SIGMA[base + 11]]);
|
|
|
|
|
BLAKE2B_G(v, 2, 7, 8, 13, w.palabras[SIGMA[base + 12]], w.palabras[SIGMA[base + 13]]);
|
|
|
|
|
BLAKE2B_G(v, 3, 4, 9, 14, w.palabras[SIGMA[base + 14]], w.palabras[SIGMA[base + 15]]);
|
2026-08-11 10:06:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Add
|
|
|
|
|
h[0] ^= v[0] ^ v[8];
|
|
|
|
|
h[1] ^= v[1] ^ v[9];
|
|
|
|
|
h[2] ^= v[2] ^ v[10];
|
|
|
|
|
h[3] ^= v[3] ^ v[11];
|
|
|
|
|
h[4] ^= v[4] ^ v[12];
|
|
|
|
|
h[5] ^= v[5] ^ v[13];
|
|
|
|
|
h[6] ^= v[6] ^ v[14];
|
|
|
|
|
h[7] ^= v[7] ^ v[15];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int tw = outl >> 3; // cuántas palabras de 64 bits caben completas
|
|
|
|
|
const int rw = outl & 7; // bytes sueltos de la última palabra parcial
|
|
|
|
|
|
|
|
|
|
//----
|
|
|
|
|
int pos = 0;
|
|
|
|
|
for(int i = 0; i < tw; i++)
|
|
|
|
|
{
|
|
|
|
|
const ulong val = h[i];
|
|
|
|
|
out[pos++] = (uchar)(val);
|
|
|
|
|
out[pos++] = (uchar)(val >> 8);
|
|
|
|
|
out[pos++] = (uchar)(val >> 16);
|
|
|
|
|
out[pos++] = (uchar)(val >> 24);
|
|
|
|
|
out[pos++] = (uchar)(val >> 32);
|
|
|
|
|
out[pos++] = (uchar)(val >> 40);
|
|
|
|
|
out[pos++] = (uchar)(val >> 48);
|
|
|
|
|
out[pos++] = (uchar)(val >> 56);
|
|
|
|
|
}
|
|
|
|
|
//----
|
|
|
|
|
if(rw > 0)
|
|
|
|
|
{
|
|
|
|
|
const ulong val = h[tw];
|
|
|
|
|
for(int j = 0; j < rw; j++)
|
|
|
|
|
out[pos++] = (uchar)(val >> (j << 3));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#endif // CRYPTOBYLEO_SRC_HASH_BLACK2B_MQH
|