BigNumberByLeo/Src/Utils/DER.mqh
Nique_372 6f503a8fc7
2026-08-30 15:27:01 -05:00

119 lines
4.4 KiB
MQL5

//+------------------------------------------------------------------+
//| DER.mqh |
//| Copyright 2026, Niquel Mendoza |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Niquel Mendoza"
#property link "https://www.mql5.com"
#property strict
#ifndef BIGNUMBERSBYLEO_SRC_UTILS_DER_MQH
#define BIGNUMBERSBYLEO_SRC_UTILS_DER_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include <TSN\\Crypto\\ASN1.mqh>
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CNumberDERUtils
{
public:
CNumberDERUtils(void) {}
~CNumberDERUtils(void) {}
//---
template <typename TNumber>
static int DEREstimateLen(const TNumber value, int& k, bool& is_high_encendido, uchar& number_len_size);
//---
template <typename TNumber>
static int DERRead(const uchar& buf[], int r, TNumber& value);
};
//+------------------------------------------------------------------+
//| Formado DER esta pensado en si |
//| Para usarse con DerEstimateLen, normalemnte en RSA, etc para |
//| ASN1 donde se reuqiere (recursion) para el TLV |
//+------------------------------------------------------------------+
// TNumber como maximo peude tener para no mparse de 127
// 126 bytes de tamaño (mas que sobra para long\ulong y hasta structs..)
//+------------------------------------------------------------------+
// devuelve tres cosas
// k=desde donde empiza a escibir
// is_high_encendido=si el alto esta encneido (para el 0x00)
// number_len_size=para ponerlo como valor uchar
template <typename TNumber>
static int CNumberDERUtils::DEREstimateLen(const TNumber value, int& k, bool& is_high_encendido, uchar& number_len_size)
{
const int clz = CBitTricks::CLZ(value);
k = (((sizeof(TNumber) << 3) - 1) - clz) >> 3; // posicion del byte mas alto con valor
// calculamos directo el high.. en vez de callear una funcion
is_high_encendido = (uchar(value >> (k << 3)) & 0x80) != 0;
// + 1 para normlzliar
number_len_size = uchar(is_high_encendido + k + 1); //
// +1 = tag
// +1 = lensize (Shoft format)
return number_len_size + 1 + 1;
}
//+------------------------------------------------------------------+
// buf= buffer final
// w= indice de escritura
// lenw= salida de DERTotalBytes (lenw uchar)
// total= salida final total de DERTotalBytes
#define NUMBERUTILS_DER_WRITE_NUMBER(buf, w, VALUE, ttype, is_high_encendido, k, lenw, total) \
{ \
buf[w++] = CBL_ASN1_TAG_INTEGER; \
CBL_ASN1_U_WRITELEN(buf, w, lenw, total) \
TsnValToBytes<ttype> rp; \
rp.value=VALUE; \
if(is_high_encendido) \
buf[w++] = 0x00; \
for(int i = k; i >= 0; i--) \
buf[w++] = rp.bytes[i]; \
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template <typename TNumber>
static int CNumberDERUtils::DERRead(const uchar& buf[], int r, TNumber& value)
{
//---
if(buf[r++] != CBL_ASN1_TAG_INTEGER)
return -1;
//---
int t = buf[r++];
if((t & CBL_ASN1_MASK_BYTEALTO) != 0)
return -1; // sool short format
//---
const int fr = r + t;
r = fr - 1;
// aqui no chekamso si la info es buena o mala
// se supone que ah de coincidor (En caso que no )
// digmoas t=2, buf=3, entonces requiere 4.. por lo qeu se pasa y da fuera de rango
// si resulta neceisto se pdora aqui mteer un if
if(r >= ArraySize(buf)) // invalido
return -1;
//---
value = 0;
for(int j = 0; j < (t << 3); j += 8)
value |= TNumber(buf[r--]) << j;
//---
return fr;
}
//---
}
#endif // BIGNUMBERSBYLEO_SRC_UTILS_DER_MQH