2026-08-10 16:05:10 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Main.mqh |
|
|
|
|
|
//| Copyright 2026, Niquel Mendoza |
|
|
|
|
|
//| https://www.mql5.com |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#property copyright "Copyright 2026, Niquel Mendoza"
|
|
|
|
|
#property link "https://www.mql5.com"
|
|
|
|
|
#property strict
|
|
|
|
|
|
2026-08-10 16:09:46 -05:00
|
|
|
#ifndef CRYPTOBYLEO_SRC_MAC_HMAC_MAIN_MQH
|
|
|
|
|
#define CRYPTOBYLEO_SRC_MAC_HMAC_MAIN_MQH
|
2026-08-10 16:05:10 -05:00
|
|
|
|
2026-08-12 18:18:45 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#include "Def.mqh"
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
/*
|
|
|
|
|
HMAC(K,m)=H((K′⊕opad)∥H((K′⊕ipad)∥m))
|
2026-08-13 09:05:49 -05:00
|
|
|
---
|
|
|
|
|
Notas:
|
|
|
|
|
- Si pasasis un ENUM invalido, dara invalid pointer de fncion...
|
|
|
|
|
Nota tampoco que no hay veriicaiones ni last err ni nad... tu eres respobiel de hacer
|
|
|
|
|
las cosas bien
|
2026-08-12 18:18:45 -05:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2026-08-10 16:05:10 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
namespace TSN
|
|
|
|
|
{
|
2026-08-12 18:18:45 -05:00
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
class CHMac
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
// clave
|
|
|
|
|
uchar m_key[];
|
|
|
|
|
int m_key_s;
|
2026-08-13 09:05:49 -05:00
|
|
|
int m_key_r;
|
|
|
|
|
// (Se peude cambiar la clave interna)
|
2026-08-12 18:18:45 -05:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// funcion hasher
|
2026-08-13 18:48:30 -05:00
|
|
|
CCryptoHashMeta::TsnCryptoByLeoHashFuncFixed m_func_haser;
|
2026-08-13 09:05:49 -05:00
|
|
|
int m_out_hash_size; // tamaño en bytes del hash de salida
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
int m_block_size_internal; // tamaño del bloque que procesa HMAC (depede del haser)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//--- interno del algoritmo
|
|
|
|
|
// tamaño = msi (tamaño del dato) + (tamaño del bloque)
|
|
|
|
|
uchar m_ipad[];
|
|
|
|
|
int m_ipad_r;
|
|
|
|
|
|
|
|
|
|
// tamaño = block_size + out h size
|
|
|
|
|
int m_opad_r;
|
|
|
|
|
uchar m_opad[];
|
|
|
|
|
|
|
|
|
|
// kout (k'prima)
|
|
|
|
|
uchar m_kout[];
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
//--- La salida es publicxa tambien para logeo
|
|
|
|
|
uchar m_out[]; // HMAC actual
|
2026-08-13 16:13:23 -05:00
|
|
|
// tamaño es igual a outhsize
|
2026-08-12 18:18:45 -05:00
|
|
|
|
|
|
|
|
public:
|
2026-08-13 18:48:30 -05:00
|
|
|
CHMac(const uchar& key[], const uchar& data[], CCryptoHashMeta::ENUM_TSN_CRYPTO_HASH f);
|
2026-08-13 09:05:49 -05:00
|
|
|
CHMac(void);
|
2026-08-12 18:18:45 -05:00
|
|
|
~CHMac(void) {}
|
|
|
|
|
|
2026-08-13 09:05:49 -05:00
|
|
|
|
|
|
|
|
//--- Funcion base
|
|
|
|
|
// Nota esto solo resetea el estado interno... es como un set (Acutlizar)
|
|
|
|
|
// NO STREAMING..
|
|
|
|
|
void Update(const uchar &data[]);
|
|
|
|
|
// No hay funcion para setear key dado qeu es publica
|
|
|
|
|
|
|
|
|
|
//--- Cuando se actulize KEY
|
|
|
|
|
void OnKeyUpdate();
|
|
|
|
|
|
2026-08-13 16:13:23 -05:00
|
|
|
|
|
|
|
|
//--- Comparacion
|
|
|
|
|
// comparacion RAW (no compara con fomrato espeicifo si no bytes TAL CUAl raw como se meciona)
|
2026-08-13 17:28:04 -05:00
|
|
|
// Si quieres ocmprar ocn hex conveirtelo
|
2026-08-13 16:13:23 -05:00
|
|
|
bool CompareRaw(const string& hmac);
|
|
|
|
|
bool CompareRaw(const uchar& hmac[]);
|
|
|
|
|
|
2026-08-13 09:05:49 -05:00
|
|
|
//--- Getter \ Setter generales
|
|
|
|
|
// Funciones hasher
|
2026-08-13 18:48:30 -05:00
|
|
|
CCryptoHashMeta::TsnCryptoByLeoHashFuncFixed HashFunc() { return m_func_haser; }
|
|
|
|
|
void HashFunc(CCryptoHashMeta::ENUM_TSN_CRYPTO_HASH f);
|
2026-08-13 09:05:49 -05:00
|
|
|
|
|
|
|
|
//--- getter
|
|
|
|
|
__forceinline int BlockSize() const { return m_block_size_internal; }
|
|
|
|
|
__forceinline int OutHashSize() const { return m_out_hash_size; }
|
2026-08-12 18:18:45 -05:00
|
|
|
};
|
|
|
|
|
|
2026-08-10 16:05:10 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-08-13 09:05:49 -05:00
|
|
|
CHMac::CHMac(void)
|
|
|
|
|
: m_ipad_r(512), m_block_size_internal(0), m_out_hash_size(0),
|
|
|
|
|
m_func_haser(NULL), m_key_s(0), m_key_r(128), m_opad_r(512)
|
|
|
|
|
{
|
|
|
|
|
ArrayResize(m_opad, m_opad_r, m_opad_r);
|
|
|
|
|
ArrayResize(m_ipad, m_ipad_r, m_ipad_r);
|
|
|
|
|
ArrayResize(m_key, m_key_r, m_key_r);
|
|
|
|
|
}
|
2026-08-11 18:30:23 -05:00
|
|
|
|
2026-08-10 16:05:10 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-08-13 18:48:30 -05:00
|
|
|
CHMac::CHMac(const uchar &key[], const uchar &data[], CCryptoHashMeta::ENUM_TSN_CRYPTO_HASH f)
|
2026-08-13 09:05:49 -05:00
|
|
|
: m_ipad_r(ArraySize(data)), m_block_size_internal(0), m_out_hash_size(0),
|
|
|
|
|
m_func_haser(NULL), m_key_s(ArraySize(key)), m_opad_r(0)
|
2026-08-10 16:05:10 -05:00
|
|
|
{
|
2026-08-13 09:05:49 -05:00
|
|
|
//--- Llamamaos a la funcion f
|
|
|
|
|
HashFunc(f);
|
|
|
|
|
|
|
|
|
|
//--- Ipad
|
|
|
|
|
m_ipad_r += m_block_size_internal;
|
|
|
|
|
ArrayResize(m_ipad, m_ipad_r, m_ipad_r); // inicialemte tamaño del blouqe
|
|
|
|
|
|
|
|
|
|
//--- key
|
|
|
|
|
m_key_r = m_key_s << 1;
|
|
|
|
|
ArrayResize(m_key, m_key_r, m_key_r);
|
|
|
|
|
for(int i = 0; i < m_key_s; i++)
|
|
|
|
|
m_key[i] = key[i]; // copiamos los datos
|
2026-08-10 16:05:10 -05:00
|
|
|
|
|
|
|
|
//---
|
2026-08-13 09:05:49 -05:00
|
|
|
OnKeyUpdate();
|
2026-08-10 16:05:10 -05:00
|
|
|
|
2026-08-13 09:05:49 -05:00
|
|
|
//--- Actulizamos el estado interno
|
|
|
|
|
Update(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-08-13 18:48:30 -05:00
|
|
|
void CHMac::HashFunc(CCryptoHashMeta::ENUM_TSN_CRYPTO_HASH f)
|
2026-08-13 09:05:49 -05:00
|
|
|
{
|
2026-08-13 18:48:30 -05:00
|
|
|
//--- Check validez
|
|
|
|
|
if(f >= CRYPTOBYLEO_HASHFUNC_TOTAL_FIXED || f < 0)
|
|
|
|
|
return; // invalid range
|
|
|
|
|
|
2026-08-13 09:05:49 -05:00
|
|
|
//---
|
2026-08-13 18:48:30 -05:00
|
|
|
m_out_hash_size = TSN::CCryptoHashMeta::g_crytpo_hash_meta[f].outl;
|
|
|
|
|
m_block_size_internal = TSN::CCryptoHashMeta::g_crytpo_hash_meta[f].blocksize;
|
|
|
|
|
m_func_haser = TSN::CCryptoHashMeta::g_crypto_fhash_fixed[f];
|
2026-08-13 09:05:49 -05:00
|
|
|
|
|
|
|
|
//--- opad
|
|
|
|
|
const int n = m_block_size_internal + m_out_hash_size;
|
|
|
|
|
if(n > m_opad_r)
|
|
|
|
|
{
|
|
|
|
|
m_opad_r += n << 1;
|
|
|
|
|
ArrayResize(m_opad, m_opad_r, m_opad_r); // tamaño de blocksize + outhsize
|
2026-08-10 16:05:10 -05:00
|
|
|
}
|
|
|
|
|
|
2026-08-13 09:05:49 -05:00
|
|
|
//--- Kout
|
|
|
|
|
ArrayResize(m_kout, m_block_size_internal, m_block_size_internal); // tamaño del bloque como tal
|
2026-08-10 16:05:10 -05:00
|
|
|
|
2026-08-13 09:05:49 -05:00
|
|
|
//--- Out
|
|
|
|
|
ArrayResize(m_out, m_out_hash_size); // tamaño final
|
|
|
|
|
}
|
2026-08-10 16:05:10 -05:00
|
|
|
|
2026-08-13 09:05:49 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
void CHMac::OnKeyUpdate(void)
|
|
|
|
|
{
|
|
|
|
|
//--- Parte del algoritmo hmac
|
|
|
|
|
if(m_key_s > m_block_size_internal) // mayor
|
|
|
|
|
{
|
|
|
|
|
// entoncesd comprimirmos
|
|
|
|
|
m_func_haser(m_key, m_key_s, m_kout);
|
|
|
|
|
// itermoas desdel el inico del fin
|
|
|
|
|
for(int i = m_out_hash_size; i < m_block_size_internal; i++)
|
|
|
|
|
m_kout[i] = 0; // 0
|
|
|
|
|
}
|
|
|
|
|
else
|
2026-08-10 16:05:10 -05:00
|
|
|
{
|
2026-08-13 09:05:49 -05:00
|
|
|
// Ahora aqui
|
|
|
|
|
for(int i = 0; i < m_key_s; i++)
|
|
|
|
|
m_kout[i] = m_key[i];
|
|
|
|
|
// sobrante
|
|
|
|
|
for(int i = m_key_s; i < m_block_size_internal; i++)
|
|
|
|
|
m_kout[i] = 0; // 0
|
2026-08-10 16:05:10 -05:00
|
|
|
}
|
|
|
|
|
|
2026-08-13 09:05:49 -05:00
|
|
|
//--- Ipad y Opad
|
|
|
|
|
for(int i = 0; i < m_block_size_internal; i++)
|
|
|
|
|
{
|
|
|
|
|
m_opad[i] = m_kout[i] ^ 0x5c;
|
|
|
|
|
m_ipad[i] = m_kout[i] ^ 0x36;
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-10 16:05:10 -05:00
|
|
|
|
|
|
|
|
|
2026-08-13 09:05:49 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
void CHMac::Update(const uchar &data[])
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
const int msi = ArraySize(data);
|
|
|
|
|
int n = msi + m_block_size_internal;
|
|
|
|
|
if(n > m_ipad_r)
|
|
|
|
|
{
|
|
|
|
|
m_ipad_r += n << 1;
|
|
|
|
|
ArrayResize(m_ipad, m_ipad_r, m_ipad_r);
|
|
|
|
|
}
|
2026-08-10 16:05:10 -05:00
|
|
|
|
2026-08-13 09:05:49 -05:00
|
|
|
//---reutilizaps ipad
|
|
|
|
|
// ahora copiamos los datos de data a ipad+blocksize
|
|
|
|
|
// ArrayCopy(ipad, data, TSNTABLES_HMAC_BLOCKSIZE, 0, msi);
|
|
|
|
|
for(int i = 0; i < msi; i++)
|
|
|
|
|
m_ipad[m_block_size_internal + i] = data[i];
|
|
|
|
|
/*
|
|
|
|
|
uchar iner_out[TSNTABLES_SHA256_OUT];
|
|
|
|
|
if(CryptEncode(CRYPT_HASH_SHA256, ipad, empty, iner_out) != TSNTABLES_SHA256_OUT)
|
|
|
|
|
return false;
|
|
|
|
|
*/ // Encryptamos lo qeu tenemos
|
|
|
|
|
m_func_haser(m_ipad, n, m_out); // ahora esta en m_out el resultado
|
|
|
|
|
|
|
|
|
|
// reutkliar mout (envez de iner out)
|
|
|
|
|
// ArrayCopy(opad, iner_out, TSNTABLES_HMAC_BLOCKSIZE, 0, TSNTABLES_SHA256_OUT);
|
|
|
|
|
for(int i = 0; i < m_out_hash_size; i++)
|
|
|
|
|
m_opad[m_block_size_internal + i] = m_out[i];
|
|
|
|
|
|
|
|
|
|
//--- utlima fase
|
|
|
|
|
// return CryptEncode(CRYPT_HASH_SHA256, opad, empty, res) == TSNTABLES_SHA256_OUT;
|
|
|
|
|
n = m_out_hash_size + m_block_size_internal;
|
|
|
|
|
m_func_haser(m_opad, n, m_out); // finalizamos
|
2026-08-10 16:05:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2026-08-13 16:13:23 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CHMac::CompareRaw(const uchar &hmac[])
|
|
|
|
|
{
|
|
|
|
|
const int t = ArraySize(hmac);
|
|
|
|
|
if(t != m_out_hash_size)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
uchar v = 0;
|
|
|
|
|
for(int i = 0; i < t; i++)
|
|
|
|
|
{
|
|
|
|
|
// si son iguales = 0 (la idea es que sean todos iguales y asi todo 0 or y 0 fnal)
|
|
|
|
|
// si no son iguales (pero 1 \0) = 1 aqui ya con el primero que no se giual |1
|
|
|
|
|
// asi que no encajaria
|
|
|
|
|
v |= hmac[i] ^ m_out[i];
|
|
|
|
|
}
|
|
|
|
|
// Basandome en los comapore safe de otros lengaujes, usan esto para evita "ataque" de timing
|
|
|
|
|
// sincamtne no se como fucinoar eso infiero que perfilaran cuanto tarda el programa y en base a eso podria
|
|
|
|
|
// hacer stats.. de ir probadno varias clavez de varios len para ver primero que len usa y adiviar el algortimo
|
|
|
|
|
// algo ais.. la verdad es que son supociones ...
|
|
|
|
|
// Asi que para evitart eso si hacemos el tiempo de compracion constante ya eso para N entradas
|
|
|
|
|
// da el mismo resultado.
|
|
|
|
|
return v == 0; // 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CHMac::CompareRaw(const string &hmac)
|
|
|
|
|
{
|
|
|
|
|
const int t = StringLen(hmac);
|
|
|
|
|
if(t != m_out_hash_size)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
uchar v = 0;
|
|
|
|
|
for(int i = 0; i < t; i++)
|
|
|
|
|
{
|
|
|
|
|
v |= (uchar)hmac[i] ^ m_out[i];
|
|
|
|
|
}
|
|
|
|
|
return v == 0; // 0
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-13 09:05:49 -05:00
|
|
|
//--- namespace
|
|
|
|
|
}
|
2026-08-10 16:09:46 -05:00
|
|
|
#endif // CRYPTOBYLEO_SRC_MAC_HMAC_MAIN_MQH
|