2026-08-23 13:57:28 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| Not.mqh |
|
| | | //| Copyright 2026, Niquel Mendoza |
|
| | | //| https://www.mql5.com |
|
| | | //+------------------------------------------------------------------+
|
| | | #property copyright "Copyright 2026, Niquel Mendoza"
|
| | | #property link "https://www.mql5.com"
|
| | | #property strict
|
| | |
|
| | |
|
| | | /*
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | |
|
2026-09-09 20:01:20 -05:00 | | | Unca congruencia modular se define como:
|
2026-08-23 13:57:28 -05:00 | | | a = b (mod N)
|
2026-09-09 20:01:20 -05:00 | | |
|
2026-08-23 13:57:28 -05:00 | | | Lo que quiere decir que:
|
| | | si divbises a y b por separod entre N sus residuos (modulo) son iguales
|
| | |
|
| | | Por lo tnato
|
| | | si restas a-b los reidus se anulan por loq eu divir N entre a-b da una division exacta
|
2026-09-09 20:01:20 -05:00 | | | con residuo 0
|
2026-08-23 13:57:28 -05:00 | | |
|
| | | A su vez al dar una division exacta, se cumple que, hay un numero K qeu si lo multiplcamos con
|
2026-09-09 20:01:20 -05:00 | | | N es igual a (a-b)
|
2026-08-23 13:57:28 -05:00 | | | digmoas:
|
| | | c = (a-b)
|
| | | entonces
|
2026-09-09 20:01:20 -05:00 | | | c / n = k (k=cociente) y r=0
|
| | |
|
| | | por lo que
|
| | |
|
| | | c = n*k+0 osea c=n*k
|
2026-08-23 13:57:28 -05:00 | | |
|
| | | Ahora todo esto es una intruddccion vamos con lo de verdad RSA
|
| | | en RSA se usa mucho esto.. diria que giura en todo a esto
|
| | |
|
| | |
|
| | | Aparte hay una propiedad interesnate que luego se usa para obtener el "d" priuvado
|
| | | apartir de lo publico
|
| | |
|
| | | El invesro modular (inveso multiplcativo
|
| | | numero x que si multicpls con y da 1) dice qeu si tenemos un numero a y queremos buscar su inverso muñltiplciatvio.
|
| | | en el sitema normzal R por ejemplo
|
| | |
|
| | | se busca un numero qeu si lo multiplcaos con a da 1
|
2026-09-09 20:01:20 -05:00 | | |
|
| | | a * x = 1
|
2026-08-23 13:57:28 -05:00 | | | entonces
|
| | | x = 1/a facil
|
2026-09-09 20:01:20 -05:00 | | |
|
| | | El tema es que en aritmem modular solo existen enteros no fraciones
|
2026-08-23 13:57:28 -05:00 | | | Tampoco es que las pdoamso represtar dado que nuestro Z esta actoac a N (valor del modulo) valores
|
| | | Ni mas ni mesno
|
2026-09-09 20:01:20 -05:00 | | |
|
2026-08-23 13:57:28 -05:00 | | | Asi qeu ahi va masmoes igual solo que:
|
| | |
|
2026-09-09 20:01:20 -05:00 | | | a*x = 1 (mod N)
|
2026-08-23 13:57:28 -05:00 | | |
|
2026-09-09 20:01:20 -05:00 | | | Dice x cuimple qeu si lo mutlcionas por a y divos todo eso por N obtner un resto de 1...
|
2026-08-23 13:57:28 -05:00 | | | Esto se usa como dije para el cauclo de d (pero con N = phi(n))
|
| | | Ademas para que exista x se cumple qeu
|
| | |
|
| | | gdc(a, n) = 1 (son coprimos)
|
2026-09-09 20:01:20 -05:00 | | |
|
2026-08-23 13:57:28 -05:00 | | | Esto se demuesta como:
|
2026-09-09 20:01:20 -05:00 | | | supongoamos que d = gdc(a, n) = d > 1 osea a o n son compuestos
|
2026-08-23 13:57:28 -05:00 | | | entonces:
|
2026-09-09 20:01:20 -05:00 | | | a | d y n | d
|
| | |
|
| | | Por contradicion digmoas que si existe un inversox que cumpla es decir
|
| | |
|
2026-08-23 13:57:28 -05:00 | | | a*x = 1 (mod N)
|
2026-09-09 20:01:20 -05:00 | | |
|
| | | Usando una propeida que meicone antes eso quere deicr que
|
| | |
|
2026-08-23 13:57:28 -05:00 | | | (ax-1) / n da una division exacta
|
2026-09-09 20:01:20 -05:00 | | |
|
2026-08-23 13:57:28 -05:00 | | | por lo que (usando la deinficno de division)
|
2026-09-09 20:01:20 -05:00 | | |
|
2026-08-23 13:57:28 -05:00 | | | (ax-1) = n * y (donde y es un entero)
|
2026-09-09 20:01:20 -05:00 | | |
|
2026-08-23 13:57:28 -05:00 | | | rescribiendo:
|
2026-09-09 20:01:20 -05:00 | | |
|
2026-08-23 13:57:28 -05:00 | | | ax-ny=1
|
2026-09-09 20:01:20 -05:00 | | |
|
| | | pero tambein = a = d * k y n = d * z
|
| | |
|
2026-08-23 13:57:28 -05:00 | | | (dk)x - (dz)y = 1
|
2026-09-09 20:01:20 -05:00 | | |
|
2026-08-23 13:57:28 -05:00 | | | d(kx - zy) = 1
|
2026-09-09 20:01:20 -05:00 | | |
|
| | | o
|
| | |
|
2026-08-23 13:57:28 -05:00 | | | d * j = 1
|
2026-09-09 20:01:20 -05:00 | | |
|
2026-08-23 13:57:28 -05:00 | | | eso quiere decir qeu si multoapcl d por un numero J nos da 1..
|
| | | pero dijisqmos que D > 1
|
| | | enotnces no eixtne ningun numero en este sistema que si lo multpcloas por d nos de 1
|
| | | por ejemplo si d fuera 2 * x = 1 x debria de ser 1/2 pero dijismos que eso no eixte
|
| | | en este sitema
|
2026-09-09 20:01:20 -05:00 | | |
|
| | | Aparte ioncialete dijismoq que para que d¨*j sea vlaidao para en caso exista
|
| | | dicho inverso neceisaria d=1
|
2026-08-23 13:57:28 -05:00 | | | lo cual unciamte se cumple para coprimos..
|
2026-09-09 20:01:20 -05:00 | | |
|
2026-08-24 09:56:46 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | // Inverso modular
|
| | | // En aritmaetica modular que luego se usa en RSA por jemeplo
|
| | | // Neceistmoas un inverso x que se deifne como
|
| | | // (x*a) = 1 (MOD n)
|
| | | // Osea un numero x que al multiplcarlo por 1 y esto lo dividmos por n
|
| | | // su resto sea 1
|
| | | // para esto se cumple que gdc(n,a)=1 osea n y a son coprimos
|
| | | // Ahora para encontralo usaremos un teroema del gdc:
|
| | | // tal que:
|
| | | // gdc(a,b) = ax+by
|
| | | // En nuestro caso como defines qeu el gdc=1
|
| | | // entonces:
|
| | | // ax+by=1
|
| | | // ahora:
|
| | | // a=this, b=n (mod)
|
| | | // si lo ecrimos como un mod
|
| | | // ax+by = 1 (MOD n)
|
| | | // pero
|
| | | // this * x + n * y = 1 (mod n) ny es multiplo de N
|
| | | // por loq ue n * y no afecta en esta operacion (es como que da una veulta completa)
|
| | | // asi que this * x = 1 (mod n) justo lo qeu buscamosm incialete
|
2026-09-09 20:01:20 -05:00 | | | // entonces esta funcino retorna dicho x
|
| | |
|
| | |
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | El gdc ext, como lo he llegado a comprender en su forma simple, es basicamnte lo mismo que el gdc bin normal
|
| | | solo que en vez de llevar dos varaibles u\v, llevas A\B\C\D los coeficintes de las dos ecuaciones
|
| | | ll A = 1, B = 0; u = A*a0 + B*b0
|
| | | ll C = 0, D = 1; v = C*a0 + D*b0
|
| | |
|
| | | La idea, es la misma que el bin pero trabajmos como si lo estiamso hacienco con una ecuacion como la que se muestra
|
| | | osea que en los pasos como u-=v esa resta se hace "a nivel" de ecuacion tal que
|
| | |
|
2026-09-11 09:36:42 -05:00 | | | u-v = A*a0 + B*b0 - C*a0 + D*b0
|
2026-09-09 20:01:20 -05:00 | | |
|
| | | Y asi... en la parte de ">> 1" donde volvemos impar a U aplica lo mismo. tenermos que ir acutlziando los coeficinestes
|
| | | ahora la pregunta? por que A\B\C\D basicamnte por que el gdc bin devolvimaos el "resto previo" pero
|
| | | ahora se nos pide esto: ax+by osea como una euccion con dos varialbes x\y y es basicamnte el sistema
|
| | | en el que estamos trabajando... por eso al final del bucle
|
| | |
|
| | | X e Y temrinadn ciendo C\D los coeficientes que recontruyen v... basiamtne esos coefiintges nos dicen
|
| | | el numero de veces que mulpacio el a y b orignal y sumado ambos procuocts nos da el v actua...
|
| | | y como el gdc es ese mismo v.. enotnces justo ahi tenemos la respeusta dado que tenemos su forma de reoncutrirslo
|
| | |
|
| | | en resumen trabajsmo igual qeu el bin pero como "ecuiaciones" con sus coeficinete
|
| | | sluego esos mismo coeficintes seran el x\y final que devolveremos
|
| | |
|
| | | tambien podemos verlo como un sistema de eucaicon matricial
|
| | | (
|
| | | u,
|
| | | v
|
| | | )
|
| | |
|
| | | y la matriz de coeficientes
|
| | | (
|
| | | a b
|
| | | c d
|
| | | )
|
| | | pero baimante es eso en vez de u\v piensacol como lo mismo pero trabajcon con una euccion
|
| | | entonces cada cosa que hagmos con u\v tendremos que ir acutlizaion los coeifinces que nos dan la respuesta
|
| | |
|
| | |
|
| | | en c:
|
| | |
|
| | | ll euclides_extendido_binario(ll a, ll b, ll *x, ll *y)
|
| | | {
|
| | | if(a == 0)
|
| | | {
|
| | | *x = 0;
|
| | | *y = 1;
|
| | | return b;
|
| | | }
|
| | | if(b == 0)
|
| | | {
|
| | | *x = 1;
|
| | | *y = 0;
|
| | | return a;
|
| | | }
|
| | |
|
| | | int negA = a < 0, negB = b < 0;
|
| | | if(negA)
|
| | | a = -a;
|
| | | if(negB)
|
| | | b = -b;
|
| | |
|
| | |
|
| | | int shift = 0;
|
| | | while(es_par(a) && es_par(b))
|
| | | {
|
| | | a >>= 1;
|
| | | b >>= 1;
|
| | | shift++;
|
| | | }
|
| | |
|
| | | ll a0 = a, b0 = b;
|
| | | ll u = a, v = b;
|
| | | ll A = 1, B = 0;
|
| | | ll C = 0, D = 1;
|
| | |
|
| | | while(u != 0)
|
| | | {
|
| | | while(es_par(u))
|
| | | {
|
| | | u >>= 1;
|
| | | if(es_par(A) && es_par(B))
|
| | | {
|
| | | A >>= 1;
|
| | | B >>= 1;
|
| | | }
|
| | | else
|
| | | {
|
| | | A = (A + b0) >> 1;
|
| | | B = (B - a0) >> 1;
|
| | | }
|
| | | }
|
| | |
|
| | | while(es_par(v))
|
| | | {
|
| | | v >>= 1;
|
| | | if(es_par(C) && es_par(D))
|
| | | {
|
| | | C >>= 1;
|
| | | D >>= 1;
|
| | | }
|
| | | else
|
| | | {
|
| | | C = (C + b0) >> 1;
|
| | | D = (D - a0) >> 1;
|
| | | }
|
| | | }
|
| | |
|
| | | if(u >= v)
|
| | | {
|
| | | u -= v;
|
| | | A -= C;
|
| | | B -= D;
|
| | | }
|
| | | else
|
| | | {
|
| | | v -= u;
|
| | | C -= A;
|
| | | D -= B;
|
| | | }
|
| | | }
|
| | |
|
| | | ll gcd = v << shift;
|
| | |
|
| | | *x = negA ? -C : C;
|
| | | *y = negB ? -D : D;
|
| | | return gcd;
|
| | | }
|
| | |
|
2026-08-23 13:57:28 -05:00 | | |
|
2026-09-10 07:16:18 -05:00 | | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | /*
|
| | | El metodo dos parte de interpeteat a:
|
| | | a*b
|
| | | como dos polinomios
|
| | | a=a1*x^m+a0
|
| | | b=b1*x^m+b0
|
| | |
|
| | | donde:
|
| | | a1=parte alta
|
| | | a0=parte baja
|
| | | x=base
|
| | | m=(numero de digitos del numero en si entre 2)
|
| | |
|
| | | Esto es posible dado que expresamos el numero como dos partes (tipo) notacion
|
| | | cientiica una base elevado a la mitad de digitiso*valorbajo + valor ato ejemplo
|
| | | 120000 ()
|
| | | x=10
|
| | | m=3 (6/2)
|
| | | a=120*10^3+0=120000
|
| | |
|
| | | Ahora si mulltiplacas estos dos polinomios tal que:
|
| | | a*b= (a1*x^m+a0) * (b1*x^m+b0)
|
| | | =
|
| | | (a1*x^m+a0) *
|
| | | (b1*x^m+b0)
|
| | | --------------------
|
| | | = (a1*x^m)(b1*x^m)+a0(b1*x^m)+b0(a1x^m)+(a0b0)
|
| | | Ahora reordenamos
|
| | |
|
| | | a1b1x^m2+a0(b1*x^m)+b0(a1x^m)+(a0b0)
|
| | |
|
| | | Podemos sacar a x^m como factor comun ahi
|
| | | x^m(a0b1+b0a1)
|
| | |
|
| | | Queda:
|
| | |
|
| | | a1b1x^m2+x^m(a0b1+b0a1)+a0b0
|
| | |
|
| | | Ahora la idea por lo qeu entendi es que ahora mismo estasmo ejecutnado una multiplacion de toda la vida
|
| | | ahora la idea es simplificar
|
| | | para eso (a0b1+b0a1) esto que podemos verlo como (ab+cd) tenemos aqui 4 terminos..
|
| | | diferentes por lo qeu no podemos factoriuzalo lo qeu si es que podemos aprovechar
|
| | | algo interesante:
|
| | | (a+b)(c+d) = ac+ad+bc+bd
|
| | | Esto es multiplacion de binomios..
|
| | | la idea e sque si interpatmaos ese a0b1+b0a1 como eso nos da:
|
| | |
|
| | | (a0+a1)(b0+b1) =
|
| | | a0b0+a0b1+a1b0+a1b1
|
| | |
|
| | | Nota que eligmos esa convinacion para poder aplicar el truco que usaremos ahora
|
| | | Esto si te das cuenta ciertas partes ya las tenemos... a0b0 y b1a1 ya los tenemso calculados
|
| | | entonces renombrando:
|
| | |
|
| | | (a0+a1)(b0+b1) = z0 + a0b1+a1b0 + z2
|
| | |
|
| | | donde:
|
| | | z2 = b1a1
|
| | | z0 = a0b0
|
| | | reordenmoas la parte izq:
|
| | |
|
| | | = (a0b1+a1b0) + z0 + z2 (no imprta el orden dado que es suma propiedad comutativa)
|
| | |
|
| | | ahora pasamos al otro lado
|
| | |
|
| | | z2 - z0 - (a0+a1)(b0+b1) = a0b1+a1b0
|
| | |
|
| | | o tambien:
|
| | |
|
| | | a0b1+a1b0 = (a0+a1)(b0+b1) - z0 - z2
|
| | |
|
| | | bueno entonces con eso ya podemos calucalr lo que nos falta para tener z1 con 3 multiplaciones
|
| | | (z0, z2 y la de ()()) en vez de 4...
|
| | |
|
| | |
|
| | | entcones la funcion seira algo asi
|
| | |
|
| | | primero calcullkos z0 y z2 primero eso y luego z1 (a0b1+a1b0)
|
| | | sale claucalos = (a0+a1)(b0+b1) - z0 - z2
|
| | |
|
| | | luego de eso aplicas el x^m
|
| | |
|
| | | Ejemplo multipllacar
|
| | |
|
| | | 10
|
| | | 45
|
| | |
|
| | | x=10
|
| | | m=1
|
| | |
|
| | |
|
| | | a = 1*10^1+0 , osea que a1=1, a0=0
|
| | | b = 4*10^1+5 , osea que b1=4, b0=5
|
| | |
|
| | | calculomoes z0 (b1a1 ) y z2 (a0b0)
|
| | |
|
| | | z0=1*4=4
|
| | | z2=0*5=0
|
| | |
|
| | | ahora z1
|
| | |
|
| | | z1=(a0+a1)(b0+b1) - z0 - z2
|
| | |
|
| | | remplazando:
|
| | |
|
| | | (0+1)(5+4) - 0 - 4
|
| | | (1)(9) - 0 - 4
|
| | | 9 - 0 - 4
|
| | | 9 - 4
|
| | | z1=5
|
| | |
|
| | | final remplzamos en:
|
| | |
|
| | |
|
| | |
|
| | | z0x^m2+x^mz1+z2 = 4*100+10*5+0= 400 + 50 + 0 = 450
|
| | | */
|
| | |
|
2026-09-09 20:01:20 -05:00 | | |
|
2026-08-23 13:57:28 -05:00 | | | */
|
| | | //+------------------------------------------------------------------+
|