CryptoByLeo/Src/RSA/Keys/Gen.mqh
Nique_372 f5e497c05c
2026-08-26 13:35:15 -05:00

162 lines
5.1 KiB
MQL5

//+------------------------------------------------------------------+
//| Gen.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_RSA_KEYS_GEN_MQH
#define CRYPTOBYLEO_SRC_RSA_KEYS_GEN_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include "H.mqh"
#include "..\\..\\Imports\\Main.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CRsa
{
public:
CRsa(void) {}
~CRsa(void) {}
//---
template <typename TRandomGen>
static bool GenerateKeyData(int public_exponent, int key_size_bits,
int rounds_test_primo, int t_attemps, CRsaPublicKey& pub, CRsaPrivateKey& priv);
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template <typename TRandomGen>
static bool CRsa::GenerateKeyData(int public_exponent, int key_size_bits,
int rounds_test_primo, int t_attemps, CRsaPublicKey& pub, CRsaPrivateKey& priv)
{
//
//---
/* En esta funcion creamos
- p (primo grande)
- q (primero grande)
- n (producto de p y q)
- d (se deriva de lo publico)
*/
//---
/*
1. Fijar e = 65537 (dado, no se "elige" en tiempo de generación)
2. Generar candidato p:
a. Sacar un número aleatorio impar de 1024 bits
b. Testear primalidad (Miller-Rabin / Fermat)
c. Si no es primo → volver a (a)
d. Si es primo → verificar gcd(e, p-1) == 1
e. Si NO es coprimo con e → descartar p entero, volver a (a)
3. Repetir todo el paso 2 para generar q (con la condición extra p ≠ q)
4. n = p × q
5. φ(n) = (p-1)(q-1)
6. d = e⁻¹ mod φ(n) (Euclides extendido) | e * d = 1 mod φ(n) (ed es como ax en formula)
*/
//----
const int keyss_limbs = BIGNUMERBYLEO_BITS_TO_LIMBS(key_size_bits);
BigUInteger p(TSN::BigUInteger::EMPTY_INT_ARR, keyss_limbs);
BigUInteger q(TSN::BigUInteger::EMPTY_INT_ARR, keyss_limbs);
//--- P
while(true)
{
if(--t_attemps < 0)
return false;
// La idea aqui es primeramente generar un nuermo alaeatorio
// generamos
p.FillRandom<TRandomGen>();
// BCryptGenRandom(0, p.m_v, sizeof(ulong) * keyss_limbs, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
p.m_v[0] |= 1; // foramozas a que sea impar
// Ahora formzaos que el alto este activado
// La idea es que neceistos garnaizasr qeu este numero sea de key_size_bits
// Por que peude que en la generacion los altos esten apgados asi qeu teoramte no seria un numero de esos bit
// asi que lo forzamos activand el mas alto
p.m_v[keyss_limbs - 1] |= (1ULL << 63);
//--- ahora le pasamos
if(!p.IsProbablePrime(rounds_test_primo))
continue;
// restamos 1
p -= 1;
// Buscamos que sean coprimos (con el public exponent)
if(p.Gdc(public_exponent) == 1)
break;
}
//---
p += 1;
//--- q
while(true)
{
if(--t_attemps < 0)
return false;
q.FillRandom<TRandomGen>();
q.m_v[0] |= 1; // foramozas a que sea impar
q.m_v[keyss_limbs - 1] |= (1ULL << 63);
//---
if(p == q)
continue; // deben de ser diferentes
//--- ahora le pasamos
if(!q.IsProbablePrime(rounds_test_primo))
continue;
q -= 1; // restamos 1
// Buscamos que sean coprimos (con el public exponent)
if(q.Gdc(public_exponent) == 1)
break;
}
//---
BigUInteger phi_n = (p - 1) * q; // q ya es q-1
// Ahora d = e⁻¹ mod φ(n)
// public_exponent * x = 1 (mod phi(n))
// primero converitmos a e a un big integer.. usando contructo exacto
const BigUInteger bige(TSN::BigUInteger::EMPTY_NUMBER_EXACT, public_exponent);
// ahora si calculamos..
BigUInteger d = bige.GdcExtendedRetX(phi_n);
//--- Calculo de crt
// (dq)
BigUInteger dq = d % q;
// (dp)
BigUInteger dp = d % (p - 1);
// qinv
BigUInteger qinv = q.GdcExtendedRetX(p);
//--- N final
q += 1;
BigUInteger n = p * q;
BigUInteger ncopy = n;
//---
pub = CRsaPublicKey(n, public_exponent);
return true;
}
//+------------------------------------------------------------------+
}
#endif // CRYPTOBYLEO_SRC_RSA_KEYS_GEN_MQH
//+------------------------------------------------------------------+