2026-08-12 08:29:06 -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
|
| | |
|
| | | #ifndef CRYPTOBYLEO_SRC_SIMETRIC_CHACHA20_MAIN_MQH
|
| | | #define CRYPTOBYLEO_SRC_SIMETRIC_CHACHA20_MAIN_MQH
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | #include "Def.mqh"
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | namespace TSN
|
| | | {
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | class CChaCha20
|
| | | {
|
| | | public:
|
2026-08-12 13:31:16 -05:00 | | | uint32_t m_state[CHACHA20_STATE_S];
|
| | |
|
| | | public:
|
| | | CChaCha20(void);
|
2026-08-12 08:29:06 -05:00 | | | ~CChaCha20(void) {}
|
2026-08-12 13:31:16 -05:00 | | |
|
| | | //---
|
| | | // key = clave de 32 bytes
|
| | | // iv = nonce aleatorio por cada bloque a cifrar (tamaño de 12 bytes)
|
| | | // inicia el estado del cifrador
|
| | | // Nota que no se veriica nada, se asume que el usuario pasa todo correcto
|
| | | void Init(const uchar& key[], const uchar& iv[], uint32_t counter = 0);
|
| | |
|
| | | //---
|
| | | void XProcces(uchar &in[], int ins);
|
| | |
|
| | | //--- Extra
|
| | | void ResetCounter(uint32_t counter = 0) { m_state[CHACHA20_STATE_IDX_CNT] = counter; }
|
2026-08-12 08:29:06 -05:00 | | | };
|
2026-08-12 13:31:16 -05:00 | | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | CChaCha20::CChaCha20()
|
| | | {
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | void CChaCha20::Init(const uchar &key[], const uchar &iv[], uint32_t counter = 0)
|
| | | {
|
| | | //--- constnes iniciales
|
| | | m_state[0] = 0x61707865;
|
| | | m_state[1] = 0x3320646e;
|
| | | m_state[2] = 0x79622d32;
|
| | | m_state[3] = 0x6b206574;
|
| | |
|
| | | //--- los siuientes 8 vamos cargo 4 bytes de la calve en un uint
|
| | | for(int i = 0; i < 8; i++)
|
| | | {
|
| | | const int s = i << 2; // Empiza ahi
|
| | | m_state[4 + i] = (uint32_t)key[s] | (uint32_t)key[s + 1] << 8 | (uint32_t)key[s + 2] << 16 | (uint32_t)key[s + 3] << 24;
|
| | | }
|
| | |
|
| | | //--- contador
|
| | | m_state[CHACHA20_STATE_IDX_CNT] = counter;
|
| | |
|
| | | //---- iv
|
| | | //for(int i = 0; i < 3; i++)
|
| | | // unrrolled
|
| | | m_state[13] = (uint32_t)iv[0] | (uint32_t)iv[1] << 8 | (uint32_t)iv[2] << 16 | (uint32_t)iv[3] << 24;
|
| | | m_state[14] = (uint32_t)iv[4] | (uint32_t)iv[5] << 8 | (uint32_t)iv[6] << 16 | (uint32_t)iv[7] << 24;
|
| | | m_state[15] = (uint32_t)iv[8] | (uint32_t)iv[9] << 8 | (uint32_t)iv[10] << 16 | (uint32_t)iv[11] << 24;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | void CChaCha20::XProcces(uchar &in[], int ins)
|
| | | {
|
| | | //----
|
| | | union U32_8
|
| | | {
|
| | | uint32_t u32[CHACHA20_KEYSTREAM_SIZE_U32];
|
| | | uchar u8[CHACHA20_KEYSTREAM_SIZEB];
|
| | | } keystream;
|
| | |
|
| | |
|
| | | //---
|
| | | const int s = ins - CHACHA20_KEYSTREAM_SIZEB;
|
| | | int pos = 0;
|
| | | while(pos < s)
|
| | | {
|
| | | //--- Algoritmo base para un ks
|
| | | // Contruiimos el bloque de 16 (keysteam)
|
| | | // aqwui instaicniasmpo temporales.
|
| | | uint32_t x0 = m_state[0], x1 = m_state[1], x2 = m_state[2], x3 = m_state[3];
|
| | | uint32_t x4 = m_state[4], x5 = m_state[5], x6 = m_state[6], x7 = m_state[7];
|
| | | uint32_t x8 = m_state[8], x9 = m_state[9], x10 = m_state[10], x11 = m_state[11];
|
| | | uint32_t x12 = m_state[12], x13 = m_state[13], x14 = m_state[14], x15 = m_state[15];
|
| | |
|
| | | // bueno ahora aplicamos las rnodnas con la funcion Qr
|
| | | // 10 unrroled rondas para un total de 10 rondas
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | |
|
| | | // Ahora aplicamos al finall
|
| | | // unrroled (16) suma + escritura
|
| | | keystream.u32[0] = x0 + m_state[0];
|
| | | keystream.u32[1] = x1 + m_state[1];
|
| | | keystream.u32[2] = x2 + m_state[2];
|
| | | keystream.u32[3] = x3 + m_state[3];
|
| | | keystream.u32[4] = x4 + m_state[4];
|
| | | keystream.u32[5] = x5 + m_state[5];
|
| | | keystream.u32[6] = x6 + m_state[6];
|
| | | keystream.u32[7] = x7 + m_state[7];
|
| | | keystream.u32[8] = x8 + m_state[8];
|
| | | keystream.u32[9] = x9 + m_state[9];
|
| | | keystream.u32[10] = x10 + m_state[10];
|
| | | keystream.u32[11] = x11 + m_state[11];
|
| | | keystream.u32[12] = x12 + m_state[12];
|
| | | keystream.u32[13] = x13 + m_state[13];
|
| | | keystream.u32[14] = x14 + m_state[14];
|
| | | keystream.u32[15] = x15 + m_state[15];
|
| | |
|
| | | // Aumentamos el confaodr
|
| | | m_state[CHACHA20_STATE_IDX_CNT]++;
|
| | |
|
| | |
|
| | | //--- Next ahora aplicamos... escritura ffinal
|
| | | for(int i = 0; i < CHACHA20_KEYSTREAM_SIZEB; i++)
|
| | | {
|
| | | in[pos + i] ^= keystream.u8[i];
|
| | | }
|
| | |
|
| | | //---
|
| | | pos += CHACHA20_KEYSTREAM_SIZEB;
|
| | | }
|
| | |
|
| | | //--- bytes finales
|
| | | if(pos < ins)
|
| | | {
|
| | | //--- Algoritmo base para un ks
|
| | | // Contruiimos el bloque de 16 (keysteam)
|
| | | // aqwui instaicniasmpo temporales.
|
| | | uint32_t x0 = m_state[0], x1 = m_state[1], x2 = m_state[2], x3 = m_state[3];
|
| | | uint32_t x4 = m_state[4], x5 = m_state[5], x6 = m_state[6], x7 = m_state[7];
|
| | | uint32_t x8 = m_state[8], x9 = m_state[9], x10 = m_state[10], x11 = m_state[11];
|
| | | uint32_t x12 = m_state[12], x13 = m_state[13], x14 = m_state[14], x15 = m_state[15];
|
| | |
|
| | | // bueno ahora aplicamos las rnodnas con la funcion Qr
|
| | | // 10 unrroled rondas para un total de 10 rondas
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | | CHACHA20_DOUBLE_ROUND
|
| | |
|
| | | // Ahora aplicamos al finall
|
| | | // unrroled (16) suma + escritura
|
| | | keystream.u32[0] = x0 + m_state[0];
|
| | | keystream.u32[1] = x1 + m_state[1];
|
| | | keystream.u32[2] = x2 + m_state[2];
|
| | | keystream.u32[3] = x3 + m_state[3];
|
| | | keystream.u32[4] = x4 + m_state[4];
|
| | | keystream.u32[5] = x5 + m_state[5];
|
| | | keystream.u32[6] = x6 + m_state[6];
|
| | | keystream.u32[7] = x7 + m_state[7];
|
| | | keystream.u32[8] = x8 + m_state[8];
|
| | | keystream.u32[9] = x9 + m_state[9];
|
| | | keystream.u32[10] = x10 + m_state[10];
|
| | | keystream.u32[11] = x11 + m_state[11];
|
| | | keystream.u32[12] = x12 + m_state[12];
|
| | | keystream.u32[13] = x13 + m_state[13];
|
| | | keystream.u32[14] = x14 + m_state[14];
|
| | | keystream.u32[15] = x15 + m_state[15];
|
| | |
|
| | | // Aumentamos el confaodr
|
| | | m_state[CHACHA20_STATE_IDX_CNT]++;
|
| | |
|
| | | //---
|
| | | const int f = ins - pos;
|
| | | for(int i = 0; i < f; i++)
|
| | | {
|
2026-08-26 08:21:19 -05:00 | | | in[pos++] ^= keystream.u8[i];
|
2026-08-12 13:31:16 -05:00 | | | }
|
| | | }
|
| | | }
|
| | |
|
| | | //---
|
2026-08-12 08:29:06 -05:00 | | | }
|
| | | //+------------------------------------------------------------------+
|
2026-08-12 13:31:16 -05:00 | | | #endif // CRYPTOBYLEO_SRC_SIMETRIC_CHACHA20_MAIN_MQH
|
| | |
|
| | | /*
|
| | | Por lo que esrtuve enindeod creo que es mas ismple que AEs
|
| | | primero incializ un estado con una key 4 consatnes y un once (aleatorios)
|
| | | Luego vas procsenados chunks de 64 bytes.
|
| | | -
|
| | | Tomar el estado actuliza lo instiaca luego vas aplicando sumas, xor, rotaciones a ese "x"
|
| | | temporalce (Copia de state) por 20 rondas...
|
| | | terminana esas rondas aplicas denueo al estaod (se lo sumas) todos esos temporales
|
| | | bien emepzlaos, y aumentas el condaor (12)
|
| | |
|
| | | -
|
| | | Ahora luego tomas ese aray key stream y aplica un xor en el buffer de salida del cifrado
|
| | | y luego lo copias al buffer de salia (aqui pasas uint32 a uchar)
|
| | |
|
| | | //----
|
| | | Bueno el algoritmo no es tan complejo a decir verdad... mas faicl que AES
|
| | |
|
| | | Este como tal es el algoritmo puro sin poly.. que se le agrega
|
| | |
|
| | | */
|
| | | //+------------------------------------------------------------------+
|