Un reto con el criptógrafo de Wheatstone con clave homofónica

Imagen de tokamak
Enviado por tokamak en

Foros: 

Por tokamak

Os voy a presentar un reto de medios vuelos, apto para las tórridas tardes veraniegas. El asunto está basado en el criptógrafo de Wheatstone, inventado por Sir Charles Wheatstone, o más bien reinventado pues parece que estaba basado en otro diseño anterior, de un militar americano: Decius Wartword.

El aparato en cuestión es un mecanismo simplísimo, pues básicamente consta de dos agujas, una mayor y otra más pequeña, dispuestas sobre una esfera de reloj, engranadas de tal manera que ambas se separan una posición, una letra, en cada revolución completa. El mecanismo para hacer tal cosa consiste tan sólo en dos engranajes de diámetro diferente unidos entre sí.

En la parte exterior de la esfera se dispone un alfabeto ordenado de 26 letras, además del espacio colocado en la posición de las 12, en tanto que en la parte interior tenemos un alfabeto perturbado de 26 letras, sin el espacio, que, junto a la combinación de partida de las dos agujas, constituye la clave del invento.

Para cifrar vamos buscando cada letra del texto en claro con la manecilla larga, incluyendo espacios, siempre en el sentido de las agujas del reloj. Al hacer esto, siempre que cifremos un espacio o una letra alfabéticamente menor que que la última, provocaremos un cambio de alfabeto al obligarnos a efectuar una revolución completa con la aguja grande. Es notable que pueda llevarse a cabo un cifrado polialfabético en un mecanismo provisto tan sólo de dos engranajes.

Hay algo más de información en este artículo (pdf) de Germán Fco. Martínez Navarro, de donde provienen las imágenes de este reto.

En la imagen 1 vemos un ejemplar del criptógrafo, mostrando las agujas y los dos alfabetos. El alfabeto interior tenía las letras desmontables, para cambiar la clave con facilidad. Otros sistemas empleaban para tal efecto un disco de papel, con la clave del día impresa.

Podemos seguir el ejemplo que nos proporciona el autor del citado artículo, a partir de la posición del criptógrafo que muestra la figura 2. El alfabeto interior, que no se lee bien, es:

FBKSYRDLTZAGMUNHOVCIPWEJQX

Si ciframos

CHICO FELIZ

el resultado será

TUNZWLUUPCZ

, en tanto que

CHICA FELIZ

nos dará

TUNZTTNNWIA

Para simular este dispositivo de cifra, podéis usar este pequeño script VB para Excel:

Function cifrar(aguja_grande, aguja_pequeña, texto, alfabetoP)
 
a1 = alfabetoP
 
a0 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
M = aguja_grande
N = aguja_pequeña
 
x = InStr(a0, M)
y = InStr(a1, N)
 
    zz = (y - x + 26) Mod 26 + 1
    a2 = Right(alfabetoP, 26 - zz + 1) & Left(alfabetoP, zz - 1)
 
For i = 1 To Len(texto)
 
  letra = Mid(texto, i, 1)
  x = InStr(1, a0, letra)
  y = x
  If x = 0 Then y = 26
  If x < antes Then a2 = Right(a2, 25) & Left(a2, 1)
 
 
  lc = Mid(a2, y, 1)
 
  cif = cif & lc
  antes = x
 
Next i
 
cifrar = cif
 
End Function
 
Function descifrar(aguja_grande, aguja_pequeña, texto, alfabetoP)
a1 = alfabetoP
 
a0 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
M = aguja_grande
N = aguja_pequeña
 
x = InStr(a0, M)
y = InStr(a1, N)
 
 
    zz = (y - x + 26) Mod 26 + 1
    a2 = Right(alfabetoP, 26 - zz + 1) & Left(alfabetoP, zz - 1)
 
For i = 1 To Len(texto)
 
  letra = Mid(texto, i, 1)
  x = InStr(1, a2, letra)
  y = x
 
 
  If y <= antes Then
    a2 = Right(a2, 25) & Left(a2, 1)
    x = InStr(1, a2, letra)
    y = x
    If x = 26 Then y = 0
  End If
 
  If y = 0 Then lc = "_" Else lc = Mid(a0, y, 1)
 
  cif = cif & lc
 
  antes = y
 
Next i
descifrar = cif
 
End Function

El problema es que este criptosistema estaba obsoleto en el momento de su invención, pues ya eran conocidas las técnicas estadísticas de ataque a los cifrados polialfabéticos, como el método Kasiski, de manera que me hice la pregunta de si sería posible mejorarlo un poco, pero eso sí: sin perder nada de su maravillosa simplicidad. Además el criptógrafo de Wheatstone fue utilizado por el bando nacional durante la Guerra Civil (Clave Norte) y siguió en uso (me imagino que para regocijo de los servicios secretos extranjeros) hasta mediados de los años 50.

Por otra parte, resulta que el método de cifra oficial del Ejército durante el final del XIX hasta la Guerra Civil, por lo menos, fue el criptógrafo de cinta, básicamente una tabla de homófonos, donde cada letra del alfabeto se codifica utilizando varias cifras diferentes, entre el 0 y el 99, así que se me ocurrió combinar este método con la máquina de Wheatstone, disponiendo los números del 01 al 99, desordenados, en el disco interior, mientras que en el exterior se colocarían, ordenadas, las letras del alfabeto, repitiendo todas varias veces, tanto más cuanto mayor sea su frecuencia de aparición en español.

Además echaremos mano de un útil recurso utilizado desde el Renacimiento, los nulos,insertando el nulo en la posición de las 12, prescindiendo, por tanto, del espacio habitual en todas estas máquinas.

Cuando ciframos, por ejemplo una "A", ponemos la aguja en una cualquiera de las posiciones consecutivas de la "A", siete en total, lo que permite reducir la fatiga del cifrador, que tendía, a la larga, a repetir los mismos homófonos para la misma letra. Además con el sistema de Wheatstone hay que cifrar con otra letra, por ejemplo la "Q", los dígrafos como "LL" o "RR", en tanto que con mi sistema basta con elegir una posición homofónica distinta para cada letra, si resulta que es igual que la anterior (el script que proporciono lo hace automáticamente).

La corona exterior tendría el siguiente alfabeto:

/AAAAAAABBBCCCCDDDDEEEEEEFFFGGGHHHIIIIIJJJKKKLLLLMMMMNNNNNOOOOOOPPPQQQRRRRRSSSSSTTTTUU
UUVVVXXXYYYZZZ

Se ha prescindido de la Ñ, reemplazable por N, y de la W, que se puede substituir por dos uves.

Para cifrar un texto cualquiera, por ejemplo:

 EN_UN_LUGAR_DE_LA_MANCHA_DE_CUYO_NOMBRE_NO_PUEDO_ACORDARME_NO_HACE_MUCHO_TIEMPO_QUE_
VIVIA_UN_HIDALGO_DE_LOS_DE_LANZA_EN_ASTILLERO_GALGO_CORREDOR

Lo primero quitamos los espacios:

ENUNLUGARDELAMANCHADECUYONOMBRENOPUEDOACORDARMENOHACEMUCHOTIEMPOQUEVIVIAUNHIDALGOD
ELOSDELANZAENASTILLEROGALGOCORREDOR

Y a continuación pintamos de vez en cuando una raya vertical al tuntún; serán los nulos:

ENUN/LUGARD/ELAMA/NCHADEC/UYONOMB/RENOPUE/DOACORD/ARMENOHAC/EMUCH/OTIEMPOQUEV/IVIAUNHIDA
/LG/ODELOSD/EL/ANZAENAST/ILLE/ROGAL/GOCORREDOR

Y ya podemos cifrar, utlizaramos la siguiente clave homofónica en el disco interior:

010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525
354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899

Con la posición de agujas (grande, pequeña)

A,  08

Obtenemos el cifrado:

3060 9364 0957 9638 1784 2713 3258 2063 1816 7030 4921 3540 3120 0817 8177 8075 3325 9745 8288 9014 4928 4691
3542 9204 4831 3306 8155 8994 6542 4836 5785 2350 6938 0219 7461 9007 0311 2965 3343 8032 8047 3003 7983 6352 5095 7952 1171 7601 1730 7255 7604 5660 1454 6480 1561 3842 5993 0606 8262 3622 9466 1266 9626 8027 4039 8885 2945

En grupos de a dos, como manda la tradición española para las claves homofónicas.

Este sistema podría darse por bueno si emisor y receptor pudiesen cruzar unos 20 mensajes entre ellos, con la misma clave. Si cada mensaje tuviese de media unos 200 caracteres, al lacónico estilo militar, esto nos da unos 4000 caracteres. Yo os proporciono un reto con unos 5 Kbytes, y valor y al toro, que sin duda se puede descifrar.

Reto cifrado

2722 4384 6271 3673 6290 9829 3369 2128 5170 3732 0670 2503 4569 6709 9049 9540 2818 2316 5636 3092 3251 4452
5252 3575 7931 8046 1136 6301 9028 8106 7992 6712 7969 0160 4477 4693 4433 1747 5576 0774 3544 4223 1299 6270 2027 4996 5748 5638 1041 9504 7345 2726 6167 0403 5477 5528 5978 6686 3694 8785 8611 2936 3094 6086 3741 1232 8281 2447 5724 4041 0884 3737 8730 6324 7711 3317 9704 1699 0597 6484 4908 9906 9384 0220 2383 2351 4575 6764 7209 6583 8537 3358 1853 5181 5556 6962 0712 4788 2512 5428 7610 8638 4673 5739 2412 2027 6238 0315 7919 9894 9869 5251 1137 8149 4473 3675 4679 6821 9109 7353 2802 7512 5876 1307 6905 5231 5489 5896 8889 5122 5868 9007 7817 0452 5453 6237 4406 9801 7994 0964 9939 6625 3536 2311 8731 1151 0487 9152 9765 8699 0973 3305 6023 5027 9298 0602 7950 1346 1592 5393 3493 9234 4253 4226 3150 1917 8104 0797 4805 7397 4198 2486 6289 3927 6065 7404 8505 7766 9060 2099 5215 3696 2057 5175 8371 4056 5912 3275 6031 5562 5019 9865 4540 2182 6944 6479 8294 3064 5625 3756 6369 8018 3683 5428 3328 9163 4956 8824 1565 6296 5977 2219 5734 2851 2816 1976 7358 3463 5051 8592 2064 9215 7919 3870 2618 2471 9001 3303 7628 6927 6112 8695 1066 8988 6557 1336 0316 0205 5718 2199 3023 9239 8907 9754 1784 7202 9802 5861 8909 8414 8229 7694 8520 8261 8131 4662 8416 4874 0499 5124 6574 3975 6349 7912 2721 5311 4164 3639 1841 9822 2108 6229 7969 8524 2645 1687 9406 4536 2375 0260 9086 2015 3728 2403 4325 8360 9560 7210 6466 0849 4397 2390 7514 5739 7217 6254 4182 3735 9596 1464 3411 7942 2618 6994 1255 7939 2313 5461 1106 5575 1942 0829 2278 3352 8732 5155 0449 7351 6979 7299 2568 9280 0876 8798 3930 3577 4955 7371 5524 6644 2317 7889 0392 6733 0131 9105 7755 1438 4928 6335 7851 3950 4570 0502 3388 1880 9490 3540 1253 5716 9843 2214 4417 5788 3971 2079 4206 2755 9515 5106 2370 6502 9066 0663 4712 6385 2487 7202 6640 3442 9933 0205 3548 5398 5240 6386 4592 9695 3778 4765 2767 5267 8578 4615 6999 9576 6639 1981 5035 5512 8592 8245 2021 3495 2227 4880 5106 6435 4398 1151 3918 4149 6504 4307 1180 6061 5404 7204 2928 2414 8543 5257 6668 7758 4025 0832 7224 1741 4885 3062 3745 9148 2635 2968 5746 3305 0473 6046 0108 6168 3166 6744 5279 1102 6389 8356 1457 1411 3690 0562 1191 3520 0483 6893 9231 8664 1161 5593 3094 0746 9403 8785 7628 2866 9985 6630 9566 5631 7097 2207 2025 4430 3748 9151 3280 4081 5576 2246 3578 5046 6285 5293 2568 1595 3023 8302 8111 0775 4121 1889 7953 3292 0364 4773 2127 5944 5376 1115 5455 6674 5601 5480 2255 5980 4697 1861 1999 6276 4117 4520 4870 9641 3217 8455 9198 7056 6684 2769 6370 2835 7156 5341 0650 6824 0280 5352 5776 7781 1236 9558 6250 9410 3125 3405 8178 4450 5613 8178 0390 6044 7369 1676 2899 6489 4792 1933 4571 1752 6383 5462 1492 5157 9277 0511 2317 4728 0434 1127 2692 1267 5802 4302 1365 4798 7657 8342 1026 3673 7114 3414 9161 0193 8095 4310 0462 0148 0332 1709 0716 5277 9255 7943 5770 2570 3841 4730 4438 9510 2989 1451 4146 0302 8184 8848 3840 1037 6586 6482 6483 6319 2166 6102 7747 9638 6774 2604 7835 0308 7507 5569 9187 9330 0413 1941 6196 5813 8320 3974 4254 7618 1815 3084 7426 4578 0321 3939 5170 5507 9680 4822 8226 8091 8424 1734 2414 4820 3221 1364 9983 0883 2781 0282 3628 1881 3978 2418 7254 9479 8214 5631 3932 8842 9721 1416 2178 1286 7401 0461 8275 7667 2099 2170 1935 1963 9543 8498 0873 1096 3465 0598 1214 7012 4118 5965 1745 6375 2720 8338 6751 4870 8069 1353 7380 8019 8730 2943 7245 5039 5431 1035 4904 6409 3248 8877 5905 8911 7988 7935 0864 9240 6052 4929 4943 0269 9995 0639 6291 5949 3674 8853 1270 9718 3972 6181 3144 3450 5740 1335 3351 4886 5001 0371 9387 3170 2769 2936 2284 4778 5199 6888 7788 1055 2717 6661 7187 7690 6242 4079 7358 5073 7449 4813 1828 0826 9118 2667 6416 2493 2866 3293 7374 7302 7640 3262 2575 6740 1489 3770 8271 2905 4505 6341 2196 9826 8084 2773 6541 9167 9468 8401 4398 0176 7116 7435 1001 0273 2059 5236 4211 1934 5401 2305 5027 2634 2270 7879 1541 3529 4449 1928 8420 5314 6742 1976 2607 4838 0932 9593 9683 7918 8763 0397 1133 4991 4256 0569 1318 4666 2345 3654 0749 5997 2988 2223 2274 6169 6175 7022 3416 2574 5764 6365 6448 5350 0958 0555 8669 8231 2801 5651 2185 3973 7760 5397 5257 3329 1234 6876 4229 1763 2378 4521 5148 6053 2965 8627 9847 8268 6692 6790 1230 2007 8069 1014 6995 4360 5294 0703 1972 8366 4699 9805 9446 7646 1566 0463 7491 0653 7246 0976 1761 5026 9276 4511 7364 5095 2814 1086 9632 8517 1232 3782 3310 1304 3305 6115 3986 6444 8003 6662 1696 8729 5967 0395 7148 6786 7534 2078 7681 3247 4633 2833 4582 7279 6071 2993 1133 5769 0564 5108 5623 9487 3623 3097 1686 7578 6619 0730 4021 1187 3142 1031 8341 0950 5743 6793 0336 8154 8468 0347 3027 4824 3899 9217 0244 8965 2557 4332 1223 8481 7366 2275 1793 3870 1307 0730 4078 7226 0706 7136 0378 4606 9473 3125 6536 4710 5931 6719 9740 0881 3540 0597 8783 6548 6036 3646 0706 5139 3830 0341 3399 2635 8439 0861 5243 4758 2366 0707 5315 2506 2318 1172 2552 2503 7491 0995 8610 0477 1753 6764 2651 8557 3344 3663 4217 4598 4750 8928 9756 3261 7345 0435 2575 6441 6888 7808 3447 1490 2133 9911 6690 4099 3937 5297 0821 1254 8371 0582 0722 9619 5396 5780 6893 6095 5752 6418 8166 0488 4218 5635 9043 6886 2248 6099 9910 6614 9568 4583 3380 4380 0573 2070 4981 3226 3213 0978 2588 8775 1128 6968 5786 3917 8461 6474 5302 7176 5807 2802 9596 8835 1445 7651 0906 5790 0114 9191 5197 4941 2345 6031 3499 6755 8597 3131 0494 7050 6484 6614 9168 3110 0831 9848 5701 4279 1865 7174 0133 4952 4490 6144 0288 0939 8630 0812 9873 8661 8709 5016 8466 4219 6601 0367 6424 1133 4241 0184 6965 2434 6173 3392 0543 5655 6947 5226 4036 2758 8537 8046 0724 5745 3142 5811 5148 4801 4627 9843 9691 1769 2684 3974 7799 5966 7037 3015 0163 5708 9190 8424 8145 9589 2363 4469 1632 7940 1142 0398 1326 2924 9106 7988 3703 6849 6016 7718 4647 9098 3039 8836 9876 2488 9252 9759 8943 7824 8207 2045 5366 6878 9175 3141 9291 3920 4705 9270 9891 3746 9770 2773 5676 2650 2870 2918 6594 5285 4144 1979 8878 1785 0145 8020 0677 6292 5330 5555 9392 6653 6006 6909 4374 8567 9429 5668 3388 5230 3672 1506 8164 4590 9424 6297 7087 2337 7031 6627 7360 3459 9282 0876 0686 5922 2742 7388 5817 4686 3575 0157 6292 8396 4898 1564 0391 9348 8737 5128 2030 7328 2556 3055 3449 9957 6852 2345 8861 1597 4316 1984 7155 8086 4853 1308 1113 2182 1390 0647 8666 9906 1050 4368 7846 8716 0343 4054 8492 5890 6973 1088 3948 5775 3505 0989 8505 2158 7533 9065 1284 2740 0904 6148 4692 7784 7634 3747 2350 0831 7656 8515 1312 8580 0785 4214 7080 0780 8525 0160 1286 2707 2852 3321 2385 9582 6810 8436 0715 3070 1905 3603 3614 2637 0175 4230 9646 3743 3317 7840 2441 9980 8689 9397 9677 1573 6177 3495 7265 6872 0855 4212 6745 9358 9776 6376 5494 7675 4185 6916 8287 6976 7475 6123 8143 1518 9199 8587 8147 5312 3454 9917 0779 5710 8495 3326 2235 7129 1041 0413 3336 8634 7598 3113 1847 9501 4341 0250 8736 8798 8437 0604 2895 2931 6424 6294 9626 6347 2132 1154 9058 6563 6880 3187 7812 4634 3992 3288 7062 6779 2969 0204 1514 3084 1807 4436 4198 5591 6865 9613 2310 3990 1933 2287 9527 4378 0253 8106 8367 0255 8653 0967 6606 7018 6344 4760 5142 7042 6114 4542 5137 5522 1986 7152 8619 9861 6337 7170 5549 0454 9150 4392 7278 4666 2522 9540 6548 0726 4564 7278 6407 1778 4564 6711 4462 1664 2398 6082 9899 8569 3769 1110 7479 6943 5638 2217 5993 2230 5443 7323 0946 6252 0855 5112 9140 4309 4009 8926 2479 3498 1405 1161 4128 2006 3768 4746 5936 8320 9556 7160 2406 3972 3696 2270 1315 2171 5949 1291 8078 3075 3679 9434 7412 7370 4685 2122 4007 0914 3583 9647 9631 8921 6111 7437 1101 4837 0156 0537 9468 9679 1554 3955 1287 8957 5070 1838 8472 8702 8548 3915 9983 1656 4307 5106 8281 3886 5912 8910 8352 0184 7918 4544 6914 8446 3715 1015 3219 3398 3578 5931 8305 4783 3572 9885 2140 1827 1785 8713 2293 3399 0827 7855 2724 2759 5437 3080 0151 5716 9722 4885 3089 3958 8518 6479 3440 0346 1992 7160 8785 1668 7671 9928 0883 5743 9584 1375 1469 1053 1159 0650 2129 3620 5390 8721 1578 6702 2136 3991 6044 5955 6573 4695 1335 6709 2048 5882 4206 5962 8880 3654 2765 5283 5505 7534 3077 2550 3903 8725 7326 7908 8647 4350 2049 1632 6941 3605 8132 6748 9578 3178 0141 8449 9684 4498 3169 4050 7711 1138 9006 0459 4876 7036 7221 5907 0207 7888 3098 8812 8875 1702 1883 1904 1734 1004 2954 4847 1811 3368 7433 2628 2939 2361 3796 5257 2401 2241 8212 4475 8149 9450 3817 5551 5121 6418 9270 9610 2675 0894 0723 2789 4707 7124 4805 9147 5217 8089 2135 0179 8351 0758 9612 9004 7555 5760 8358 4146 5692 4663 4636 5970 9302 1776 0275 8632 5694 6191 1294 9541 1893 9189 2079 0408 0160 2307 4099 0453 5923 9568 4953 5315 0962 1645 8511 9728 5058 1949 1140 5620 4885 4109 2657 1641 7264 4110 0184 7883 1830 3147 8377 5190 5302 1856 8945 6408 7529 2299 0440 7848 4650 1912 0231 5345 8817 6404 7014 0810 8284 9817 5693 3509 0169 6668 3347 6808 6191 0880 2253 5015 8804 8928 6758 2066 2212 3810 1203 9305 5905 6337 0997 4995 6054 6469 6709 0524 0887 2220 6605 4302 6148 2772 4196 1831 8864 4032 3631 4256 6811 0107 7895 7882 1955 0235 8076 6069 7546 5022 3485 8716 6910 5714 5824 9025 3195 3817 8991 9455 3260 6391 8279 6023 2203 4550 1622 3968 0366 2270 2047 1752 4461 2184 2909 3356 4836 9716 2688 5851 8815 3521 1498 8695 0155 8580 8336 4140 6777 7883 1589 4266 7702 3621 8826 8372 7412 8450 9484 4070 7269 8324 6456 7198 9804 0513 5530 3766 5473 8147 5637 8740 8803 9207 0882 0773 2632 5962 1250 8389 4557 9763 5871 3485 4336 9216 7826 8567 2631 4030 9524 8433 2895 4522 5881 8636 8658 2408 2210 5999 5015 6515 9232 7899 5340 0801 7892 3468 3426 5597 2831 6025 1806 8854 6363 5229 2814 0143 8414 5171 1607 5470 2518 0814 0749 9017 9559 5585 4704 2750 3925 1502 5144 2184 1353 0261 3359 8517 9903 2536 9542 7789 7311 9124 7225 8289 4191 6497 7890 8873 5183 4443 5181 4693 7290 2860 2238 9772 4481 8305 8351 3712 7675 8663 0660 3814 5146 9325 9357 5543 0935 7654 3345 8556 5875 5492 3124 8188 3710 0540 4475 8973 8150 6224 7847 9454 1434 2678 1621 3948 4119 1860 3878 6046 7561 8626 8927 6171 6764 7810 4902 3071 3561 8191 5392 5261 9515 7580 9565 1213 0883 3215 6757 9027 0134 7838 3908 8658 6247 4467 3830 3555 8553 0327 1170 3588 1190 2471 4129 9656 2392 7340 1679 0889 2704 5803 5464 6333 9202 1553 5183 3014 3816 5286 6288 1693 7943 5732 7321 4867 7925 9771 8953 9691 9840 1967 3321 2350 8985 8747 9193 0208 6753 2006 2822 7281 8359 0193 8518 0796 5882 0290 2427 8988 2202 9920 7451 8799 8172 3031 1439 4854 1952 6552 8137 7357 8126 8241 8063 5742 4852 7139 7943 1747 9287 9386 0509 7782 2976 9314 1274 8852 6198 5595 1454 0651 6753 8989 9990 7771 5326 9783 8043 8184 6274 9213 9369 0609 4184 9150 0269 2854 5494 8780 9568 6314 8912 3495 5565 8537 2401 1604 6339 9955 8966 3907 3969 7750 4310 7249 6126 9916 2818 6561 5278 2764 7282 2507 5563 3545 9879 1584 4493 6130 4984 4456 7774 0443 9019 2326 7158 5801 2940 5902 5097 5765 8255 4041 3598 3379 8396 2960 4710 2731 2625 3318 7813 0751 4716 2279 0799 1316 2365 2979 4052 5208 1230 7758 2671 0508 3840 7834 7420 2688 3860 3854 2641 1036 4087 4369 9955 5480 5724 7325 4195 3790 7689 3389 7489 8578 0971 5966 9359 5583 2664 2392 6206 2655 6724 6976 7690 5084 2024 8365 3156 2545 6387 9904 6522 3752 2781 3320 0438 8077 5123 4405 3509 2044 9818 0235 2429 9288 8190 7960 7973 8157 7390 3548 2822 4118 5291 9403 0184 5393 4633 1402 2343 7013 8550 8519 5436 7048 6719 9683 0545 1853 4575 9170 9627 9518 1234 9282 8433 3198 3423 5138 0218 3986 5438 7497 5808 5303 5153 9129 8188 8389 3050 1097 2866 8468 6394 6674 4270 1473 7538 7732 4379 4674 5652 5297 3024 6435 3357 7384 6036 4362 5690 7685 0232 4642 6445 4245 8135 8102 4966 5453 6247 5364 1646 3393 0407 6407 4274 3901 9485 1469 8074 4807 9013 4201 3380 6703 2705 6095 5549 9498 3329 6070 7672 3872 1330 0611 3071 5047 7275 7375 5115 0464 6148 9171 4518 0703 7537 9637 2506 5365 0699 0507 5272 0883 2855 0576 7919 4958 8597 8392 1976 2063 0212 3917 4081 4183 1722 9135 0568 1493 0426 7441 5637 2445 2388 8388 5254 8285 3412 7915 8172 4058 4093 8213 3455 7028 1609 0526 1668 8326 2730 9077 8166 8828 3667 1056 2552 1054 8295 4745 1234 3216 6326 1390 0563 2949 8448 0645 9296 9237 0147 9579 1767 2050 9885 7747 5776 0429 1810 2067 3553 9068 6554 3220 7321 0496 2080 4779 0189 4286 1281 6453 1970 5055 8244 2130 1385 3330 7952 2928 9728 7795 3011 0641 0248 0309 8832 2466 8474 6469 0327 8542 3898 9715 0109 6476 3481 4514 8473 1946 8162 9295 8738 9479 8251 5718 9337 5469 4179 2647 4573 0359 0628 2230 7353 0742 9857 0217 4532 2932 6652 8175 6302 1496 4875 1547 0583 2113 9765 3048 7628 8166 7487 4393 2112 5233 4659 2169 2435 9285 1107 3197 6168 2071 2842 0704 4528 1967 7664 4975 7928 4696 5813 4691 5646 1890 0387 2484 5845 9884 5838 7332 6314 4487 4281 3187 0406 4811 1242 3701 8151 2404 2285 0476 0755 8534 4666 2184 6285 4349 4459 3752 6758 9606 4506 2042 5891 0881 8823 4819 8641 4082 9569 8780 8927 6996 0334 2111 8254 2445 0197 3915 3852 2907 6087 1925 4629 9731 9035 7473 7634 0384 8383 2295 8107 2779 5157 5608 1896 7433 3663 3648 3757 5854 6207 2313 1777 4662 41

También os proporciono los scripts para cifrar con homófonos

Function cifrar(aguja_grande, aguja_pequeña, texto, alfabetoP)
 
Randomize
 
alfabetoP = Replace(alfabetoP, " ", "")
a1 = ""
For i = 1 To 198 Step 2
 homofono = Val(Mid(alfabetoP, i, 2)) + 39
 a1 = a1 & Chr(homofono)
Next i
 
 
a0 = "AAAAAAABBBCCCCDDDDEEEEEEFFFGGGHHHIIIIIJJJKKKLLLLMMMMNNNNNOOOOOOPPPQQQRRRRRSSSSSTTTTUU
UUVVVXXXYYYZZZ"
numeros = "777777733344444444666666333333333555553333334444444455555666666333333555555555544444444333333333333"
 
M = aguja_grande
N = Chr(Val(aguja_pequeña) + 39)
 
x = InStr(a0, M)
y = InStr(a1, N)
 
 
    zz = (y - x + 99) Mod 99 + 1
    a2 = Right(a1, 99 - zz + 1) & Left(a1, zz - 1)
 
For i = 1 To Len(texto)
 
  letra = Mid(texto, i, 1)
  x = InStr(1, a0, letra)
  numero = 0
  If x > 0 Then numero = Val(Mid(numeros, x, 1))
  Do
     If x = 0 Then rango = 0 Else rango = Int((Rnd * numero))
  Loop Until Not (x + rango = antes)
  x = x + rango
 
  y = x
  If x = 0 Then y = 99
  If x < antes Then a2 = Right(a2, 98) & Left(a2, 1)
 
  lc = Mid(a2, y, 1)
  homofono = Asc(lc) - 39
 
  cif = cif & Format(homofono, "00") & flag
  If flag = "" Then flag = " " Else flag = ""
  antes = x
Next i
 
cifrar = cif
 
End Function
 
Function descifrar(aguja_grande, aguja_pequeña, texto, alfabetoP)
 
alfabetoP = Replace(alfabetoP, " ", "")
a1 = ""
For i = 1 To 198 Step 2
 homofono = Val(Mid(alfabetoP, i, 2)) + 39
 a1 = a1 & Chr(homofono)
Next i
 
texto = Replace(texto, " ", "")
For i = 1 To Len(texto) Step 2
 homofono = Val(Mid(texto, i, 2)) + 39
 textop = textop & Chr(homofono)
Next i
 
a0 = "AAAAAAABBBCCCCDDDDEEEEEEFFFGGGHHHIIIIIJJJKKKLLLLMMMMNNNNNOOOOOOPPPQQQRRRRRSSSSSTTTTUU
UUVVVXXXYYYZZZ"
 
 
M = aguja_grande
N = Chr(Val(aguja_pequeña) + 39)
 
x = InStr(a0, M)
y = InStr(a1, N)
 
 
    zz = (y - x + 99) Mod 99 + 1
    a2 = Right(a1, 99 - zz + 1) & Left(a1, zz - 1)
 
For i = 1 To Len(textop)
 
  letra = Mid(textop, i, 1)
  x = InStr(1, a2, letra)
  y = x
 
 
  If y <= antes Then
    a2 = Right(a2, 98) & Left(a2, 1)
    x = InStr(1, a2, letra)
    y = x
    If x = 99 Then y = 0
  End If
 
  If y = 0 Then lc = "/" Else lc = Mid(a0, y, 1)
 
  cif = cif & lc
 
  antes = y
 
Next i
 
descifrar = cif
 
 
End Function

Imágenes: 

Imagen 1. Criptógrafo de Wheatstone
Imagen2. Esfera del criptógrafo de Wheatstone

Buen aporte

"Hay algo más de información en este artículo (pdf) de Germán Fco. Martínez Navarro, de donde provienen las imágenes de este reto" ¡Bien! por fin un enlace externo a Kryptopolis en español. Por cierto, buen aporte, pero no le veo mucho sentido puesto que con un simple análisis, se puede descifrar.

Esmerada y digna estética para un reto excelente

Muchísimas gracias, tokamak, me parece un reto excelente: muy bien presentado y con una estética digna del mejor arte criptográfico clásico y analógico.

Aunque lamento no llegar al nivel necesario en la parte que atañe al análisis criptológico del asunto; creo que tiene mucho mérito porque, además de presentar admirablemente esta tecnología para muchos totalmente desconocida, también proporciona una asequible implementación digital para poder jugar con ella e intentar comprenderlo todo -tanto la implentación digital como el mecanismo analógico- mucho mejor.

Así que no me extrañaría que, con el tiempo, se convierta en todo un clásico en Kriptópolis tal como ya lo es el Curso básico de criptografía clásica.

Saludos cordiales,

Pedro Fernández
--

P.S. Si, como a mí me ha ocurrido hoy, no funcionase el enlace a nationalgeographic.es proporcionado arriba al facilitarnos el pseudocódigo del descifrado que queda en la variable D -y que alguien acabará implementando en uno u otro lenguaje de programación-; aquí hay archivada una versión del martes 16 de julio de 2013 que también puede servir como breve introducción a estas sorprendentes observaciones del biólogo evolutivo checo Jaroslav Flegr sobre el Toxoplasma.

Disculpas

Debo disculparme por no haber entrado a tu reto. Al principio tuve alguna dificultad en la implementación, y luego he pasado por aun período de apatía o de incapacidad intelectual -mayor de lo habitual-.

Un cordial saludo.

Primeras observaciones (o cómo intentar salir del letargo)

Estoy intentando salir del aletargamiento que me invade, que ya es mucho tiempo el que llevo así y ya va siendo hora de volver a la acción. ¿Y qué mejor manera de hacerlo que atacando a una de las criaturas que campan tan tranquilas por estos lares?. Aprovecharé que estoy de vacaciones a ver si salgo de este aletargamiento. Y si no, al menos escribo algo, que hace tiempo que no escribo ná de ná.

Aunque no he roto el cifrario, sí que he visto algunas cosas que quizá ayuden a romperlo.

Empezaremos viendo el cifrario Wheatstone original antes de meternos con el de Tokamak. Esto nos dará pistas para poder atacar el cifrario de Tokamak.

El cifrario original es casi equivalente a un Vigenère con alfabeto desordenado y cuya clave se genera a partir del texto a cifrar. En el ejemplo dado por Tokamak, podemos establecer la siguiente tabla de Vigenère (el espacio cuenta como un carácter del alfabeto ordenado; lo escribo como un subguión):

  _ABCDEFGHIJKLMNOPQRSTUVWXYZ
-----------------------------
_|FBKSYRDLTZAGMUNHOVCIPWEJQXF
A|BKSYRDLTZAGMUNHOVCIPWEJQXFB
B|KSYRDLTZAGMUNHOVCIPWEJQXFBK
C|SYRDLTZAGMUNHOVCIPWEJQXFBKS
D|YRDLTZAGMUNHOVCIPWEJQXFBKSY
E|RDLTZAGMUNHOVCIPWEJQXFBKSYR
F|DLTZAGMUNHOVCIPWEJQXFBKSYRD
G|LTZAGMUNHOVCIPWEJQXFBKSYRDL
H|TZAGMUNHOVCIPWEJQXFBKSYRDLT
I|ZAGMUNHOVCIPWEJQXFBKSYRDLTZ
J|AGMUNHOVCIPWEJQXFBKSYRDLTZA
K|GMUNHOVCIPWEJQXFBKSYRDLTZAG
L|MUNHOVCIPWEJQXFBKSYRDLTZAGM
M|UNHOVCIPWEJQXFBKSYRDLTZAGMU
N|NHOVCIPWEJQXFBKSYRDLTZAGMUN
O|HOVCIPWEJQXFBKSYRDLTZAGMUNH
P|OVCIPWEJQXFBKSYRDLTZAGMUNHO
Q|VCIPWEJQXFBKSYRDLTZAGMUNHOV
R|CIPWEJQXFBKSYRDLTZAGMUNHOVC
S|IPWEJQXFBKSYRDLTZAGMUNHOVCI
T|PWEJQXFBKSYRDLTZAGMUNHOVCIP
U|WEJQXFBKSYRDLTZAGMUNHOVCIPW
V|EJQXFBKSYRDLTZAGMUNHOVCIPWE
W|JQXFBKSYRDLTZAGMUNHOVCIPWEJ
X|QXFBKSYRDLTZAGMUNHOVCIPWEJQ
Y|XFBKSYRDLTZAGMUNHOVCIPWEJQX
Z|FBKSYRDLTZAGMUNHOVCIPWEJQXF

Es "casi" equivalente, y no "completamente" equivalente, por dos motivos. El primero, es que la última letra del alfabeto desordenado en cada una de las filas es la misma que la primera letra en dicha fila. Esto es porque el alfabeto desordenado tiene un carácter menos que el alfabeto ordenado, y se nos presenta el problema de cómo cifrar la "Z" del alfabeto ordenado. En este caso, volveríamos al comienzo del alfabeto desordenado de la fila en la que estamos. Esto se ve más fácil con el siguiente ejemplo. Basta escribir el alfabeto ordenado y debajo el desordenado, para ver cómo encajan las letras:

_ABCDEFGHIJKLMNOPQRSTUVWXYZ_ABCDEFGHIJKLMNOPQRSTUVWXYZ_ABCDEFGHIJKLMNOPQRSTUVWXYZ...
FBKSYRDLTZAGMUNHOVCIPWEJQXFBKSYRDLTZAGMUNHOVCIPWEJQXFBKSYRDLTZAGMUNHOVCIPWEJQXFBK...

Basta fijarse en los caracteres "_" y "Z" en los alfabetos ordenados, y debajo de esas letras se ve que los caracteres de los alfabetos desordenados son los mismos.

El segundo motivo es parecido al primero. Si observamos la tabla de Vigenère, la última fila, la correspondiente a la letra de la clave "Z", es idéntica a la primera fila, la correspondiente a la letra de la clave "_". El motivo es el mismo que antes, que el alfabeto desordenado tiene una letra menos que el ordenado, y en este punto se repetirá por tal motivo. Pero aquí es donde cambia todo, pues no se aplicaría la propiedad cíclica del cifrario de Vigenère clásico en el que para pasar a la siguiente fila se pasa a la primera, sino que la siguiente fila que habría debajo de la "Z" no sería la que hay en "_", sino la que hay en "A". Esto es porque la siguiente fila obtendría desplazando una posición a la izquierda el alfabeto desordenado, y este nuevo alfabeto desordenado es el que ahora hay en la fila correspondiente a la letra "A". Pero la letra de la clave no sería la "A", sino "_", y por eso habría que cambiar las letras de la clave moviéndolas una posición abajo, en forma cíclica. O sea, que si alcanzamos la fila de la "Z", sustituiríamos la anterior tabla por ésta:

  _ABCDEFGHIJKLMNOPQRSTUVWXYZ
-----------------------------
Z|FBKSYRDLTZAGMUNHOVCIPWEJQXF
_|BKSYRDLTZAGMUNHOVCIPWEJQXFB
A|KSYRDLTZAGMUNHOVCIPWEJQXFBK
B|SYRDLTZAGMUNHOVCIPWEJQXFBKS
C|YRDLTZAGMUNHOVCIPWEJQXFBKSY
D|RDLTZAGMUNHOVCIPWEJQXFBKSYR
E|DLTZAGMUNHOVCIPWEJQXFBKSYRD
F|LTZAGMUNHOVCIPWEJQXFBKSYRDL
G|TZAGMUNHOVCIPWEJQXFBKSYRDLT
H|ZAGMUNHOVCIPWEJQXFBKSYRDLTZ
I|AGMUNHOVCIPWEJQXFBKSYRDLTZA
J|GMUNHOVCIPWEJQXFBKSYRDLTZAG
K|MUNHOVCIPWEJQXFBKSYRDLTZAGM
L|UNHOVCIPWEJQXFBKSYRDLTZAGMU
M|NHOVCIPWEJQXFBKSYRDLTZAGMUN
N|HOVCIPWEJQXFBKSYRDLTZAGMUNH
O|OVCIPWEJQXFBKSYRDLTZAGMUNHO
P|VCIPWEJQXFBKSYRDLTZAGMUNHOV
Q|CIPWEJQXFBKSYRDLTZAGMUNHOVC
R|IPWEJQXFBKSYRDLTZAGMUNHOVCI
S|PWEJQXFBKSYRDLTZAGMUNHOVCIP
T|WEJQXFBKSYRDLTZAGMUNHOVCIPW
U|EJQXFBKSYRDLTZAGMUNHOVCIPWE
V|JQXFBKSYRDLTZAGMUNHOVCIPWEJ
W|QXFBKSYRDLTZAGMUNHOVCIPWEJQ
X|XFBKSYRDLTZAGMUNHOVCIPWEJQX
Y|FBKSYRDLTZAGMUNHOVCIPWEJQXF

Y nos situaríamos en la primera fila de esta nueva tabla, puesto que estamos en la fila de la "Z", y ahora esta fila es la primera de la tabla. Se ve que las filas son las mismas que antes, pero las letras de la clave (la columna de la izquierda con las letras de la clave) se han movido una posición abajo, situándose la "Z" arriba por la propiedad cíclica. Visto de otra forma, esta tabla Vigenère es en realidad la concatenación de las filas del alfabeto desordenado, de forma indefinida, junto con las letras de la clave. Sería algo así como:

  _ABCDEFGHIJKLMNOPQRSTUVWXYZ
-----------------------------
_|FBKSYRDLTZAGMUNHOVCIPWEJQXF
A|BKSYRDLTZAGMUNHOVCIPWEJQXFB
B|KSYRDLTZAGMUNHOVCIPWEJQXFBK
C|SYRDLTZAGMUNHOVCIPWEJQXFBKS
.............................
X|QXFBKSYRDLTZAGMUNHOVCIPWEJQ
Y|XFBKSYRDLTZAGMUNHOVCIPWEJQX
Z|FBKSYRDLTZAGMUNHOVCIPWEJQXF
_|BKSYRDLTZAGMUNHOVCIPWEJQXFB
A|KSYRDLTZAGMUNHOVCIPWEJQXFBK
B|SYRDLTZAGMUNHOVCIPWEJQXFBKS
C|YRDLTZAGMUNHOVCIPWEJQXFBKSY
.............................
W|QXFBKSYRDLTZAGMUNHOVCIPWEJQ
X|XFBKSYRDLTZAGMUNHOVCIPWEJQX
Y|FBKSYRDLTZAGMUNHOVCIPWEJQXF
Z|KSYRDLTZAGMUNHOVCIPWEJQXFBK
_|SYRDLTZAGMUNHOVCIPWEJQXFBKS
A|YRDLTZAGMUNHOVCIPWEJQXFBKSY
.............................

Y las letras de la clave sólo pueden elegirse en la misma fila, o la de debajo, nunca la de encima. Se verá todo esto más claro a continuación, cuando se explique más esta "casi" equivalencia entre el cifrario de Wheatstone con el de Vigenère.

Ahora veamos cuál sería la clave Vigenère asociada al criptograma que se genera.

La clave del cifrario Wheatstone consta del alfabeto desordenado y las posiciones de inicio de la aguja grande y la pequeña. Estas posiciones se pueden interpretar, en el cifrario Vigenère (casi) equivalente, como: la aguja pequeña nos dice el carácter con que se codifica el carácter apuntado por la aguja grande. En el ejemplo de Tokamak, la aguja grande señala la "A", y la pequeña la "D". Así, en la tabla de Vigenère, basta localizar la columna donde está la "A", y buscar hacia abajo la letra "D". Cuando la encontremos, basta mirar la letra de la clave asociada a la fila donde hemos encontrado la "D", es decir, a la izquierda, la columna de las letras de la clave. En este caso, la letra de la fila es la "E". Todavía no hemos cifrado nada, simplemente hemos encontrado la letra de la clave que cifra la letra señalada por la aguja grande, y será la letra de partida a partir de la que se localizarán las siguientes letras de la clave.

Ahora, para cifrar la siguiente letra, basta ver si es una letra a la derecha de la última letra cifrada o no, en el alfabeto ordenado. Si la letra está a la derecha en el alfabeto ordenado, la siguiente letra de la clave equivalente es la misma. Si no, es la siguiente. Esto es lo mismo que decir que si la letra está a la derecha de la última cifrada en el alfabeto ordenado, seguimos en la misma fila de la tabla de Vigenère para cifrar, y si no, pasamos a la siguiente fila. Si llegáramos a la última fila (la que tiene la letra de la clave "Z"), aplicaríamos lo visto antes, es decir, que iríamos a la primera fila de la tabla, y las letras de la clave se modificarían para desplazarlas una posición abajo, para que ahora la primera fila tenga asociada la letra de la clave "Z", que es en donde estamos en realidad. Es decir, obtendríamos la siguiente tabla Vigenère y trabajaríamos sobre ella. Este cambio de tabla se haría cada vez que llegáramos a la última fila de la tabla (que ahora sería la que tiene la letra de la clave "Y", en la siguiente vuelta sería la "X", y así sucesivamente).

Consideremos el ejemplo dado por Tokamak, de la frase "CHICO_FELIZ". Empezamos trabajando con la primera tabla Vigenère. Hemos encontrado que la clave para la letra "A" apuntada por la aguja grande es "E", que codifica la letra "D", que está apuntada por la aguja pequeña. Ahora vamos a cifrar la letra "C", la primera del mensaje. Como "C" está a la derecha de la "A" (la letra señalada por la aguja grande) en el alfabeto ordenado, seguimos en la misma fila donde encontramos esa "A", es decir, que la siguiente letra de la clave es nuevamente "E", y tenemos ya las primeras dos letras de la clave: "EE". La codificación que nos da el cifrario de Vigenère para este caso es "T".

La siguiente letra del mensaje es "H", que está a la derecha de "C" en el alfabeto ordenado, por lo que nuevamente seguimos en la misma fila, y por tanto, la siguiente letra de la clave será nuevamente "E" (así, las 3 primeras letras de la clave son "EEE"). La codificación de esta "H" por Vigenère es "U". Pasamos a la siguiente letra del mensaje, que es "I". Como está a la derecha de "H" en el alfabeto ordenado, seguimos en la misma fila, por lo que la siguiente letra de la clave es de nuevo "E", y la codificación de la "I" es "N". Así, tenemos para la clave "EEEE", y para el criptograma "DTUN" (clave "EEE" y criptograma "TUN", si no incluímos la letra apuntada por la aguja grande).

Ahora tenemos la letra "C", que está a la izquierda de "I" en el alfabeto ordenado, la última letra codificada. Así que pasamos a la siguiente fila, y la letra de la clave para esa fila es la siguiente, la "F". La codificación de la "C" es, en esta nueva fila, "Z". Tenemos ya la clave equivalente "EEEEF", y el criptograma "DTUNZ". Podemos seguir así, codificando más letras y obteniendo la clave equivalente, avanzando una fila cada vez que encontremos una letra a la izquierda, o en la misma posición, de la última cifrada, en el alfabeto ordenado. Al final, para este ejemplo, tenemos la clave equivalente "EEEEFFGGHHII" y el criptograma "DTUNZWLUUPCZ". Si no contamos la letra señalada por la aguja grande, obtenemos la clave equivalente "EEEFFGGHHII" y el criptograma "TUNZWLUUPCZ", el proporcionado por el cifrario de Wheatstone.

Aclarada la "casi" equivalencia entre el cifrario de Vigenère y el cifrario de Wheatstone, podemos empezar a buscar fallos y vulnerabilidades.

Si nos fijamos en la tabla Vigenère, vemos que por cada fila que bajamos, el alfabeto desordenado se desplaza una posición a la izquierda, de forma cíclica (salvo el caso especial de la última letra). Si a esto añadimos que saltamos una fila cuando la letra a cifrar no está a la derecha de la última cifrada en el alfabeto ordenado, llegamos a la conclusión de que la codificación de una letra sólo puede repetirse con la codificación de otra letra (o la misma letra) si saltamos a una fila inferior (salvo el caso especial de "_" y "Z", en el que "Z" se codifica igual que "_" en la misma fila). En particular, dos letras cifradas consecutivas sólo pueden estar repetidas si las letras que codifican son letras consecutivas del alfabeto ordenado, en orden inverso (o si es la combinación de letras "_Z").

Para ver esto, fijémonos en el ejemplo de Tokamak, comparando el texto con su criptograma:

CHICO_FELIZ
TUNZWLUUPCZ

Observamos que aparecen las letras "UU", que codifican el par de letras "FE". Como podemos ver, "E" y "F" son letras consecutivas en el alfabeto ordenado, y vemos que en el texto original están escritas en orden inverso, "FE". El hecho de que se codifiquen con la misma letra se ve fácilmente si codificamos con la tabla Vigenère. La letra "F" se codifica como "U". La letra "E", como no está a la derecha de "F" en el alfabeto ordenado, hace que bajemos una fila, que contiene el mismo alfabeto desordenado, pero desplazado una posición a la izquierda. Puesto que "E" está una posición a la izquierda de "F", y la letra "U" del alfabeto desordenado justamente se ha desplazado una posición a la izquierda, ahora está en la posición que codificará a la letra "E" en la nueva fila en la que estamos. Es decir, que ahora la "E" se va a codificar igualmente como "U".

Esta observación nos dará pistas. Cada vez que en el criptograma encontremos 2 o más letras consecutivas repetidas, sabemos que serán tantas letras del alfabeto ordenado consecutivas en el texto claro, en orden inverso. Esto nos puede dar pistas de la palabra que están codificando. Se pueden suponer ciertas palabras buscando combinaciones de 2 o más letras consecutivas en orden inverso en las palabras del lenguaje en el que está escrito el criptograma. Habrá combinaciones que no se presenten (por ejemplo, "QP") salvo casos especiales, otras serán poco frecuentes, y otras serán muy frecuentes. Cuantas más letras se repitan en el criptograma, más pistas dará el criptograma de la palabra que se está codificando (por ejemplo, "PON" (puede ser de la palabra "PONIENTE", o "ARPON", "CORRESPONDENCIA", etc), será codificado como 3 letras iguales al ser 3 letras consecutivas en el alfabeto ordenado y en orden inverso; "PONM" son 4 letras consecutivas (pueden ser de la palabra "PONME", por ejemplo)). Esto nos da pistas porque la presencia de 2 o más letras seguidas, consecutivas en el alfabeto, y en orden alfabético inverso, no es tan frecuente como el resto de casos en los que no se da esto, y es tanto más infrecuente cuantas más letras sean la consecutivas. Esta propiedad se comporta como si fuera cíclica en el alfabeto ordenado, aunque el motivo no es que sea realmente cíclica en el sentido de que se repita el mismo fenómeno. Esto es por el caso especial de la "Z", que se codifica igual que "_" en la misma fila. Por ejemplo, si encontramos algo como "CORTABA_ZARZAS", tenemos que "BA_Z" son letras consecutivas en orden inverso si consideramos el alfabeto ordenado de forma cíclica. Lo primero que se nos viene a la cabeza es que la "Z" está a la derecha de "_" y no pasamos a la siguiente fila, que es la condición para que esta propiedad se cumpla. Pero como hemos visto, la "Z" se codifica igual que "_", así que aunque no pasemos a la siguiente fila, el resultado va a ser el mismo, y las 4 letras se codificarán con el mismo carácter. O lo que es lo mismo, "_Z" se codificará como dos letras iguales, y se comporta como dos letras consecutivas del alfabeto ordenado, en orden inverso, lo que le da al alfabeto ordenado, respecto a este comportamiento, un comportamiento como si fuera cíclico.

Un caso de especial interés es el siguiente. El segundo ejemplo que dió Tokamak es:

CHICA_FELIZ
TUNZTTNNWIA

Como antes, el par de letras "FE" se codifica con la misma letra, en este caso "NN". Pero vemos otro par de letras codificado con la misma letra, que es "A_", codificado como "TT". En este caso, como "_" y "A" son letras consecutivas en el alfabeto ordenado, cuando encontremos la combinación "A_" encontraremos un par de letras iguales. Esto significa que si una palabra acaba en "A" (y hay muchas y con relativa frecuencia), estará seguida de un espacio y esto se codificará con un par de letras repetidas, lo que dará pistas de dónde pueden terminar algunas palabras.

Hay que tener presente que aunque encontremos el mismo par de letras consecutivas en el texto en claro, eso no significa que se codifiquen siempre igual, ya que se va modificando la clave Vigenère equivalente a medida que se codifica el texto. Por tanto, si deducimos que por ejemplo, en el criptograma el par "TT" es el par "A_", eso no significa que el siguiente par "TT" que encontremos en el criptograma vuelva a codificar el par "A_".

Veamos ahora otra observación. Como vimos antes, mientras estemos en la misma fila de la tabla Vigenère, no se repetirán letras. Así, sabemos que si en el criptograma encontramos una letra, y volvemos a encontrar esa misma letra más adelante, sabemos que en el intervalo que separa ambas letras repetidas se ha avanzado al menos una fila en la tabla de Vigenère.

Volviendo al ejemplo:

CHICO_FELIZ
TUNZWLUUPCZ

Vemos que la "Z" está repetida en el criptograma, en el intervalo "ZWLUUPCZ", por lo que tenemos la seguridad de que en algún momento de ese intervalo se ha cambiado de fila en la tabla de Vigenère (el caso extremo es el de las letras repetidas "UU", explicado antes, y que nos indica que de una letra a la otra se ha cambiado de fila).

Esta observación no parece ayudarnos mucho. Pero veamos cuándo cambiamos de fila. Sabemos que si la letra a codificar está a la derecha de la última codificada en el alfabeto ordenado, permaneceremos en la misma fila en la tabla Vigenère. Esto significa que la única manera de permanecer en la misma fila después de codificar una letra es eligiendo una letra a su derecha en el alfabeto ordenado. Así, tarde o temprano tendremos que cambiar de fila, ya que en el mejor de los casos, tendremos que coger la siguiente letra en el alfabeto ordenado, lo que hará que al final no queden más letras que coger a la derecha, y esto nos obligue a cambiar de fila. Por otro lado, en un texto normal, elegida una letra, no va a haber muchas letras a continuación que estén a su derecha en el alfabeto ordenado. Es decir, que el número de letras consecutivas que estén en orden alfabético serán pocas, o lo que es lo mismo, se cambiará frecuentemente de fila en la tabla de Vigenère.

Se puede hacer una estadística del tamaño de los bloques de texto que tienen las letras en orden alfabético, junto con su tamaño, en un texto estándar. Con esto, cuando encontramos dos letras repetidas en un criptograma, podemos hacer una estimación estadística del número de veces que se habrá cambiado de fila (el paso de un bloque de texto con letras ordenadas al siguiente bloque de texto con letras ordenadas supone un cambio de fila en la tabla Vigenère). Conocido esto, podremos hacer una estimación de la distancia que hay, en el alfabeto ordenado, entre las letras que codifican. Así, si logramos descifrar una de las letras, podemos buscar en el alfabeto ordenado la otra a la distancia estimada, ajustando si es necesario. Esta estimación es más inexacta cuanto más alejadas estén las letras repetidas en el criptograma. Para que se entienda cómo se obtienen estos bloques, veamos los ejemplos de Tokamak. Tenemos:

Texto: CHICO_FELIZ
Bloques: {CHI}, {CO}, {_F}, {EL}, {IZ}
 
Texto: CHICA_FELIZ
Bloques: {CHI}, {C}, {A}, {_F}, {EL}, {IZ}

Es decir, un bloque es el máximo conjunto de letras consecutivas en orden alfabético. El final de un bloque se encuentra en la letra que está en orden inverso, o es la misma, que la siguiente, y la siguiente letra es el comienzo del siguiente bloque.

Haciendo este procedimiento para "La Regenta", tenemos las siguientes estadísticas (eliminados signos de puntuación, dobles espacios, transformadas las letras con tildes a sus equivalentes sin tildes, etc; se tienen 1678173 caracteres en total):

Bloques de 1 caracteres ordenados: 240146 (p=240146*1/1678173=240146/1678173=0.1431~14.31%)
Bloques de 2 caracteres ordenados: 341097 (p=341097*2/1678173=682194/1678173=0.4065~40.65%)
Bloques de 3 caracteres ordenados: 181113 (p=181113*3/1678173=543339/1678173=0.3238~32.38%)
Bloques de 4 caracteres ordenados: 44344 (p=44344*4/1678173=177376/1678173=0.1057~10.57%)
Bloques de 5 caracteres ordenados: 6049 (p=6049*5/1678173=30245/1678173=0.0180~1.80%)
Bloques de 6 caracteres ordenados: 734 (p=734*6/1678173=4404/1678173=0.0026~0.26%)
Bloques de 7 caracteres ordenados: 67 (p=67*7/1678173=469/1678173=0.0003~0.03%)

Los valores de las "p" a la derecha son las probabilidades de que un carácter elegido al azar en el texto de "La Regenta" pertenezca a un bloque de caracteres ordenados del tamaño indicado.

Con estos datos, podemos calcular la proporción de bloques de texto de caracteres ordenados en un texto de un determinado tamaño:

Bloques de 1 caracteres ordenados: 240146/1678173=0.1431
Bloques de 2 caracteres ordenados: 341097/1678173=0.2033
Bloques de 3 caracteres ordenados: 181113/1678173=0.1079
Bloques de 4 caracteres ordenados: 44344/1678173=0.0264
Bloques de 5 caracteres ordenados: 6049/1678173=0.0036
Bloques de 6 caracteres ordenados: 734/1678173=0.0004
Bloques de 7 caracteres ordenados: 67/1678173=0.0000

Esto son proporciones de bloques de un determinado tamaño en el texto. Si sumamos estas proporciones, obtendremos la proporción de bloques de todos los tamaños en un texto. Tenemos:

0.1431+0.2033+0.1079+0.0264+0.0036+0.0004+0.0000=0.4847

Es decir, que si tenemos un texto de tamaño T, el número de bloques ordenados en total, de cualquier tamaño, será aproximadamente de T*0.4847. Es prácticamente T/2. En los ejemplos de Tokamak, "CHICO_FELIZ" tiene 11 letras, por lo que el número de bloques estimado será 11*0.4847=5.3317. Es decir, entre 5 y 6, siendo más probable que tenga 5. Vemos que tiene 5 bloques. En el otro ejemplo, "CHICA_FELIZ", cuya estimación es la misma al tener el mismo número de letras, vemos que tiene 6 bloques.

Visto esto, podemos ver ahora el ejemplo de las "Z" repetidas. Teníamos: "ZWLUUPCZ". Son 8 caracteres, por lo que el número de bloques estimado de caracteres ordenados será 8*0.4847=3.8776, es decir, entre 3 y 4, siendo más probable que sean 4. Podemos ver que en este caso es así, aunque en un caso real no lo sabríamos, y deberíamos establecer una variabilidad en esta estimación. Sabemos que el paso de un bloque ordenado a otro supone un cambio en la fila, por lo que el número de cambios de fila entre la primera "Z" y la segunda "Z" será el número de veces que cambiemos de bloque de caracteres ordenados. En este caso, tenemos 4 bloques, pero el número de cambios de bloques será de 3 (uno menos) porque la primera "Z" está ya dentro de un bloque, que es el que se descuenta en estos cambios. Esto se ve mejor con este ejemplo, donde se numeran los cambios de bloque:

{CO}-1-{_F}-2-{EL}-3-{IZ}

Por tanto, estimamos que la segunda "Z" está a una distancia de 3 caracteres de la primera, hacia la izquierda en el alfabeto ordenado. En un caso real, las posibilidades de codificación de las letras con distancia estimada de 3 serían: D-A, E-B, F-C, ..., Z-W, _-X, A-Y, B-Z, C-_.

Si lo comprobamos en el texto claro, veremos que la primera "Z" codifica la letra "C", y la segunda codifica la "Z". Pero este caso no aparece en la anterior lista. Si escribimos las letras en el alfabeto: "Z_ABC", vemos que la distancia es 4 y no 3. El fallo se debe a la excepción que supone la letra "Z" en esta particular forma de Vigenère, ya que la "Z" se codifica igual que "_" en la fila en la que estamos. A la hora de hacer estimaciones, hay que tener en cuenta este particular comportamiento. En un caso real, tendríamos las posibilidades para la codificación Z-Z a distancia 3: D-A, E-B, F-C, etc. En el caso de asociar el espacio, habrá que asociar a la misma letra que el espacio la "Z". Es decir, en el caso que nos ocupa, tendríamos C-_, pero como es un caso especial, tendríamos que añadir C-Z como otra posibilidad.

Queda todavía otra observación en este cifrario de Wheatstone. Sabemos que cada vez que encontramos una letra que no está a la derecha en el alfabeto ordenado de la última cifrada, pasamos a la siguiente línea de la tabla Vigenère. Llegará un momento en que volvamos a la primera fila de la tabla (se repite la fila). Cuando esto ocurre, la codificación de las letras será la misma que la codificación de letras anteriores que se codificaron en la misma línea.

Vimos anteriormente que la proporción de bloques de letras ordenadas era de 0.4847. Para que se repita de nuevo la línea de la tabla de Vigenère tendremos que hacer tantos saltos de línea como letras tenga el alfabeto desordenado (que tiene una letra menos que el alfabeto ordenado). En este ejemplo, el alfabeto ordenado tiene 27 letras y, por tanto, el desordenado tendrá 26. El número de letras estimadas necesarias para realizar estos 26 saltos de línea será, por tanto, 26/0.4847=53.64~54 letras. Es decir, que aproximadamente cada 54 letras se volverá a repetir el alfabeto en la codificación. En textos grandes, ésta es una frecuencia relativamente elevada, y quizá se pueda aplicar el método Kasiski para buscar subcadenas iguales de tamaño significativo. Si las encontramos, sabremos que la distancia entre esas cadenas es un múltiplo de la longitud del alfabeto desordenado. Podremos estimar aproximadamente el tamaño de los bloques entre ambas cadenas que producen una rotación completa del alfabeto desordenado.

Para esta estimación, se intentará buscar los caracteres más frecuentes, que en este caso serían los espacios. Espacios codificados en dos bloques de la misma manera estarán en posiciones relativas aproximadas en ambos bloques, lo que nos puede ayudar a alinear los bloques. Pero pueden interferir otros caracteres. Con lo visto anteriormente, quizá se pueda deducir algo que nos permita este alineamiento de los bloques, y quizá deducir palabras.

El siguiente objetivo, si logramos esta alineación, sería determinar el orden de las letras en el alfabeto desordenado. Si hemos identificado una letra del alfabeto ordenado en dos posiciones a una determinada distancia dentro de un bloque, los códigos con que están codificadas estarán distanciados, en el alfabeto desordenado, tantas posiciones como saltos de línea se hayan dado entre ambas letras. Incluso si la letra identificada está codificada en bloques diferentes, con la ayuda de sus posiciones relativas se puede estimar la distancia a la que están los códigos con que están codificadas en el alfabeto desordenado.

Por ejemplo, y siguiendo el mismo ejemplo de antes:

CHICO_FELIZ
TUNZWLUUPCZ

Supongamos que hemos identificado la "I" en las 2 posiciones en las que se encuentra. Esta "I" está codificada como "N" y "C". El tamaño del texto que contiene estas dos "I" es de 8. Aplicando la estimación de antes, estimamos que hay 8*0.4847=3.8776, es decir, entre 3 y 4 bloqes, siendo más probale 4 bloques, por lo que se habrán avanzado 3 líneas en la tabla Vigenère, y deducimos que las letras "N" y "C" están a una distancia de 3 caracteres en el alfabeto desordenado, es decir, que podemos estimar que en el alfabeto desordenado aparecerán como "N??C" (en este caso, la primera letra codificada está antes que la segunda, ya que permaneciendo siempre la "I" del alfabeto ordenado en la misma columna de la tabla Vigenère, y desplazándose el alfabeto desordenado una posición a la izquierda en cada avance de fila, la "C" sólo puede aparecer después de la "N" si está a su derecha en el criptograma). Si observamos el alfabeto desordenado:

FBKSYRDLTZAGMUNHOVCIPWEJQXF

Tenemos "NHOVC", a distancia de 4. Nos hemos acercado. Por eso, a estas estimaciones hay que darles un grado de variabilidad. Pero si logramos encontrar más casos para este par de letras, seguramente podamos mejorar la estimación.

Esto se puede generalizar a cualquier par de letras que conozcamos que estén a una determinada distancia. Es decir, si hemos determinado las las letras "H" y "L" del texto claro, y sus codificaciones son "U" y "P", procederemos igual que antes. Estimamos que hay 4 bloques de caracteres de la misma manera que se hizo en el ejemplo anterior, con lo que estimamos que hay 3 saltos de líneas en la tabla de Vigenère. Esta sería la distancia estimada si las letras del texto claro fueran iguales. Como no lo son, le sumamos a esta distancia la distancia entre estas letras en el alfabeto ordenado. Esta distancia será la posición, en el alfabeto ordenado, de la segunda letra conocida del texto claro (en este caso la "L") menos la posición, en el alfabeto ordenado, de la primera letra conocida del texto claro (en este caso la "H"). Así, para este ejemplo, la "L" está en la posición 12, y la "H" en la posición 8. 12-8=4. Así que en el alfabeto desordenado, "U" y "P" están a una distancia estimada de 4+3=7, es decir, que estarán de la forma "U??????P" (el orden de estas letras sigue las mismas reglas explicadas en el ejemplo anterior). Si observamos el alfabeto desordenado, tenemos "UNHOVCIP", que en este caso, sí se cumple la distancia estimada. En caso de que la primera letra conocida hubiera sido "L", y la segunda "H", entonces la distancia calculada hubiera sido de 8-12=-4. Al sumarle el valor 3 estimado antes, tendríamos 3+(-4)=-1, y hubiéramos estimado que las letras desordenadas del alfabeto serían "UP" (suponiendo la misma codificación que antes, es decir, la "L" codificada como "U", y la "H" codificada como "P") (Nota: "U" está a una distancia de -1 de "P", por lo que debe aparecer antes, de ahí que no aparezca esta combinación como "PU", que es lo que hubiera pasado si el resultado hubiera sido positivo).

Hasta aquí todo lo que he podido determinar del cifrario de Wheatstone. Y como ha sido tan largo y lioso, ya sabéis, si algo no entendéis, preguntad. Ahora me pondré con el cifrario de Tokamak, que de momento, como he dicho antes, no he podido romper (tampoco me he puesto a ello, pues he estado sacando estas observaciones), así que dejaré escrito lo que pueda sacar y, junto con ésto, quizá le dé a alguien alguna idea para atacarlo.
----------
Reeditado: Los datos de los bloques de "La Regenta", y los cálculos derivados de los mismos, ya se han corregido (espero no haberme vuelto a equivocar)

Gracias a tí por este reto. A

Gracias a tí por este reto. A decir verdad, no se me había ocurrido nada desde que lo pusiste hasta hace unas semanas. Tampoco me entretuve demasiado en él, debido al aletargamiento que gradualmente me hizo ir reduciendo gradualmente mi participación aquí.

Y respecto a si este cifrario resistiría el análisis en tiempos de la WWII, pues no te sabría decir. Los criptógrafos de esa época eran muy hábiles. Aparte, y por lo que he tengo entendido, muchos de sus éxitos fueron debidos a un mal uso del cifrario, a filtraciones de información, etc. Para éste, ya veremos si logramos sacar algo

Por cierto, ya aprovecho a preguntarte. Proporcionas el código del cifrador, y veo la línea:

If x < antes Then a2 = Right(a2, 25) & Left(a2, 1)

Con esta línea de código, entiendo que se puede codificar la misma letra (no me refiero al mismo homófono, sino a la misma letra física del alfabeto ordenado) sin girar la aguja grande una vuelta, o en términos de cifrario de Vigenère, se puede codificar la misma letra sin pasar a la siguiente línea. Y no sé si es así correcto, o si deberías haber escrito:

If x <= antes Then a2 = Right(a2, 25) & Left(a2, 1)

Pero como estoy tan oxidado, lo mismo es correcto así, se gira la aguja grande en caso de letra repetida, y no me he dado cuenta

Un error

Parece que el aletargamiento me ha oxidado un poco. Los datos que doy de "La Regenta" están equivocados. Cambié el código con el que los obtenía, y me comí la parte que comprobaba que el texto se había transformado correctamente, y se han hecho los cálculos con caracteres que no se han transformado a caracteres del alfabeto (se obtiene para todos los caracteres que no se han transformado la posición -1 en el alfabeto). Mañana lo corrijo, junto con los cálculos, y avisaré cuando lo haya corregido. A primera vista, parece que los resultados van a variar poco, pero ya veremos
----------
Reedición: Ya he corregido los datos de "La Regenta" y los cálculos asociados. Esperemos que ahora sí sean correctos

Bienvenido de vuelta

A ver si terminamos con la estivación (hibernación veraniega) del sitio, al menos en cuanto a tratamiento de retos. Yo sigo con mi trabajo de zapa con MPE donde, si te apetece, tus aportaciones serán mucho más que bienvenidas cuando acabes de masticar a Wheatstone.

Bien hallado

Todavía ando desperezándome, pues este letargo me ha dejado un poco adormilado. Tendré que mirar de nuevo MPE, que ya no me acuerdo cómo iba. Sí sé que no entré a atacarlo porque no entendía cómo era el proceso de cifrado/descifrado. Aunque he visto que al final los que habéis entrado a atacarlo sí que lo habéis entendido. Tendré que revisar todos los comentarios, a ver si lo acabo de entender

Más observaciones

Visto ya el cifrario de Wheatstone, ahora vamos a ver el de Tokamak. Lo primero que vamos a hacer es recalcular las estadísticas de los bloques de caracteres ordenados, ya que en este cifrario se han suprimido los espacios, y esto va a alterar estas estadísticas. Tenemos, para este cifrario (se tienen 1374161 caracteres en total):

Bloques de 1 caracteres ordenados: 182679 (182679*1/1374161=182679/1374161=0.1329~13.29%)
Bloques de 2 caracteres ordenados: 298964 (298964*2/1374161=597928/1374161=0.4351~43.51%)
Bloques de 3 caracteres ordenados: 131922 (131922*3/1374161=395766/1374161=0.2880~28.80%)
Bloques de 4 caracteres ordenados: 37818  (37818*4/1374161=151272/1374161=0.1101~11.01%)
Bloques de 5 caracteres ordenados: 7824   (7824*5/1374161=39120/1374161=0.0285~2.85%)
Bloques de 6 caracteres ordenados: 1050   (1050*6/1374161=6300/1374161=0.0046~0.46%)
Bloques de 7 caracteres ordenados: 139    (139*7/1374161=973/1374161=0.0007~0.07%)
Bloques de 8 caracteres ordenados: 12     (12*8/1374161=96/1374161=0.0001~0.01%)
Bloques de 9 caracteres ordenados: 3      (3*9/1374161=27/1374161=0.0000~0.00%)

La proporción de bloques de cada tamaño será:

Bloques de 1 caracteres ordenados: 182679/1374161=0.1329
Bloques de 2 caracteres ordenados: 298964/1374161=0.2176
Bloques de 3 caracteres ordenados: 131922/1374161=0.0960
Bloques de 4 caracteres ordenados: 37818/1374161=0.0275
Bloques de 5 caracteres ordenados: 7824/1374161=0.0057
Bloques de 6 caracteres ordenados: 1050/1374161=0.0008
Bloques de 7 caracteres ordenados: 139/1374161=0.0001
Bloques de 8 caracteres ordenados: 12/1374161=0.0000
Bloques de 9 caracteres ordenados: 3/1374161=0.0000

Y la proporción de bloques totales será:

0.1329+0.2176+0.0960+0.0275+0.0057+0.0008+0.0001+0.0000+0.0000=0.4806

Esta proporción es ligeramente menor que cuando se dejan los espacios (con espacios, queda la proporción 0.4847 que vimos en los cálculos en el cifrario de Wheatstone).

Bueno, esto no es del todo correcto. En el cifrario de Tokamak se añaden nulos de forma aleatoria en el texto claro, de forma que estas estadísticas se verán afectadas. Cada vez que se añade un nulo, pueden ocurrir dos cosas. La primera es que se añada dentro de un bloque de caracteres ordenados, de forma que se divide este bloque en dos bloques, uno desde el comienzo del bloque hasta el carácter a la izquierda del nulo, y otro desde el nulo hasta el final del bloque. Esto hace que aumente el número de bloques y que disminuya su tamaño promedio. Por ejemplo:

{ABCDEFG} ---> {ABC}{/DEFG}

Antes de añadir el nulo teníamos un bloque de 7 caracteres, por lo que su tamaño promedio es 7/1=7. Después de añadir el nulo, tenemos dos bloques, uno de tamaño 3 y otro de tamaño 5, por lo que el tamaño promedio es (3+5)/2=4. Ha aumentado el número de bloques y ha disminuído su tamaño promedio. Para generalizar este caso, supongamos que el bloque original tiene tamaño "t". Supongamos también que al añadir el nulo, el bloque de la izquierda tiene tamaño "k". El bloque de la derecha tendrá tamaño t-k+1. Este "+1" es el carácter nulo que se le añade. El promedio de tamaño de estos bloques será, entonces, (k+(t-k+1))/2=(t+1)/2. Es decir, que este promedio es independiente de dónde se añada el nulo, y se reduce a la mitad del tamaño original del bloque más 0.5.

Lo otro que puede pasar es que el nulo se añada entre dos bloques de caracteres ordenados. Esto no altera el bloque a la izquierda del nulo, pero el bloque a la derecha incorpora este nulo, incrementando en 1 su tamaño. Esto no afecta al número de bloques, pero sí aumenta el tamaño promedio de los mismos. Por ejemplo:

{ABCD}{CEFG} ---> {ABCD}{/CEFG}

Antes de añadir el nulo teníamos dos bloques de 4 caracteres cada uno, por lo que el tamaño promedio era de (4+4)/2=4. Después de añadir el nulo, seguimos teniendo dos bloques, pero ahora uno es de 4 caracteres y el otro es de 5 caracteres, por lo que el tamaño promedio es de (4+5)/2=4.5. El número de bloques se mantiene, y su tamaño promedio ha aumentado. Si generalizamos, supongamos que el tamaño del primer bloque es "t1", y el del segundo es "t2". Cuando añadimos el nulo, tenemos los nuevos tamaños de bloque t1 y (t2+1), y su promedio de tamaño será (t1+t2+1)/2=(t1+t2)/2+1/2. Es decir, que el tamaño promedio es 0.5 mayor que antes de añadir el nulo.

Puesto que el número de bloques aumenta en el primer caso, y en el segundo caso se mantiene, esto hará que la proporción de bloques aumente (o, en el caso más improbable, se mantenga), tanto más cuantos más nulos se añadan. Respecto al tamaño promedio de los bloques, en un caso vemos que aumenta, y en el otro disminuye. Vemos que el aumento es sólo de 0.5, y la disminución es a la mitad del tamaño del bloque más 0.5. En bloques de tamaño 2, la disminución de uno compensa exactamente el aumento del otro (el aumento sería +0.5. La disminución pasaría de 2 a 1+0.5=1.5=2-0.5). Para bloques de tamaño mayor, esta disminución del tamaño promedio de un caso es mayor que el aumento del otro caso.

Pero que la disminución del tamaño promedio sea mayor que el aumento no basta. Para ver si el tamaño promedio aumenta o disminuye al añadir nulos, hay que ver también la probabilidad de que al añadir un nulo, éste acabe entre dos bloques (de forma que el tamaño promedio aumenta), o si acaba en medio de un bloque (de forma que el tamaño promedio disminuye). La probabilidad de añadir un nulo entre bloques será, precisamente, 0.4806, ya que es la inversa del tamaño promedio de los bloques, y esto coincide con la proporción de bloques (el tamaño promedio es 1/0.4806, y su inversa es, de nuevo, 0.4806). Así, hay más probabilidad de añadir un nulo en medio de un bloque que entre bloques, por lo que el tamaño promedio de los bloques tiende a reducirse a medida que se añaden más nulos.

De todas formas, como no sabemos la frecuencia de aparición de los nulos, tendremos que trabajar con los datos calculados al principio como límites máximos o mínimos, según corresponda.

Podemos ahora calcular el número promedio de caracteres que debemos tener para dar una vuelta completa al alfabeto desordenado. Lo haremos suponiendo que no hay nulos. Recordemos que en este alfabeto tenemos 100 caracteres para el alfabeto ordenado, y 99 para el desordenado. Para dar una vuelta completa al alfabeto desordenado, necesitaremos en promedio 99/0.4806=205.9925~206 caracteres. Este es un límite máximo. Si consideramos los nulos, este valor será más pequeño, pero no sabemos cuanto más pequeño será. Depende de la frecuencia de aparición de los nulos. Recordemos que cuando aparece un nulo, por ser el primer carácter del alfabeto ordenado, se pasa a la siguiente línea en la tabla Vigenère equivalente. Si no fuera por los nulos, los mensajes de tamaño 200 que comentaba Tokamak tendrían una probabilidad más bien pequeña de que dieran una vuelta al alfabeto desordenado, aunque se quedarían cerca. Para el reto, que dispone de 5000 caracteres, el número de vueltas estimado que daría el alfabeto desordenado si no hubiera nulos sería de 5000/206=24.2718~24. Gracias a la presencia de los nulos, este valor será mayor, lo que puede ser una ventaja para el ataque (aunque veremos más adelante que no será mucho mayor).

Veamos ahora qué se puede aplicar de lo visto en el cifrario de Wheatstone.

Y hablando del cifrario de Wheatstone. Me he dado cuenta de que permite aplicar Kasiski con patrones. Así, si tenemos un grupo de caracteres relativamente grande, y más adelante encontramos otro grupo de caracteres del mismo tamaño con el mismo patrón, es probable que ambos grupos de caracteres codifiquen el mismo texto claro, tanto más probable cuanto mayor sea el tamaño del bloque coincidente. Esto es porque no importa en qué línea de la tabla Vigenère estemos, el esquema seguido en el avance de líneas es el mismo, y el mismo texto generará el mismo patrón, es decir, si colocamos ambos criptogramas uno encima del otro, veremos que si dos caracteres en un criptograma son diferentes, en el otro los correspondientes caracteres serán también diferentes, y de la misma forma, si en un criptograma esos caracteres están repetidos, en el otro también estarán repetidos. Esto incluye también el caso especial de la "Z", que se codifica igual que "_" en la línea en la que está. Sea cual sea la línea en la que estemos, esta coincidencia en la codificación de "Z" y "_" en la misma línea se cumple para todas las líneas, por lo que el patrón, en caso de darse la codificación de la "Z", seguirá siendo el mismo.

Esta observación es aplicable incluso para codificaciones del mismo mensaje con clave diferente (alfabeto desordenado diferente, y valores diferentes para las agujas).

Lamentablemente para los que atacamos el cifrario, esto se ve dificultado en el cifrario de Tokamak. Los nulos introducidos de forma aleatoria hace que sea muy poco probable que encontremos patrones iguales, y si los encontramos, seguramente no codifiquen el mismo texto, sino que simplemente sea una coincidencia. Es poco probable que los nulos coincidan en los mismos lugares, tanto menos probable cuanto mayor sea el bloque coincidente. Aunque esto depende también de la frecuencia de aparición de los nulos.

Vamos a suponer que no hubiera nulos, para ver hasta qué punto es aplicable el método de Kasiski con patrones al cifrario de Tokamak. En este caso, es posible encontrar dos bloques de criptograma con el mismo patrón, y de encontrarlo, probablemente serían codificaciones del mismo texto, tanto más probable cuanto mayor sea el tamaño del bloque codificado. Sin embargo, el uso de homófonos puede hacer que, en un bloque, una letra repetida en el texto en claro (separada por 1 o más caracteres, pues no se permiten caracteres repetidos) se codifique con el mismo carácter del alfabeto desordenado (por lo que se vió en el caso de Wheatstone), y en el otro se codifique con distintos caracteres del alfabeto desordenado. Esto se ve más claramente con un ejemplo. Supongamos la palabra ENEMIGO, que la hemos encontrado en dos lugares distintos. La letra "E" está repetida. En el alfabeto ordenado podemos elegir cualquier homófono "E" del grupo de homófonos "E" que tenemos:

/AAAAAAABBBCCCCDDDD -->EEEEEE<-- FFFGGGHHHIIIIIJJJKKKLLLLMMMMNNNNNOOOOOOPPPQQQRRRRRSSSSSTTTTUUUUVVVXXXYYYZZZ

Tenemos 6 homófonos "E" para elegir en el alfabeto ordenado. Para la primera palabra "ENEMIGO", podemos elegir, por ejemplo, el que está en la posición 21 para codificar la primera "E", y el que está en la posición 20 para la segunda "E". Al codificar, vemos los bloques:

{EN}, {EM}, {I}, {GO}

Tenemos un salto de línea del bloque {EN} al bloque {EM}, y el segundo homófono "E" que hemos elegido es consecutivo al primer homófono "E", y en orden inverso, lo que significa que ambos homófonos "E" se codificarán con el mismo código, como vimos en las observaciones del cifrario Wheatstone.

Ahora, estando en la segunda palabra "ENEMIGO", podríamos elegir, por ejemplo, primero el homófono "E" que está en la posición 22, y el segundo homófono "E" en la posición 24, en el alfabeto ordenado. En este caso, ya no se codificarían de la misma manera, y el patrón del criptograma de la primera palabra "ENEMIGO" no coincidiría con el patrón del criptograma de la segunda palabra, pues la primera tiene un patrón en el que se repiten dos caracteres que no se repiten en el segundo patrón. Por supuesto, podría ocurrir que la elección de los homófonos sea la misma, o al menos que en el segundo caso sean consecutivos en orden inverso, pero la probabilidad de que esto ocurra es relativamente baja.

Podemos calcular las probabilidades de que 2 letras se codifiquen con el mismo carácter del alfabeto desordenado (es decir, que los homófonos con los que se codifican sean consecutivos y en orden inverso) o no (que los homófonos con los que se codifican no sean consecutivos, o que sean consecutivos, pero en orden directo). Veamos el ejemplo con un bloque de 3 caracteres. Tenemos varias posibilidades. La primera es que elijamos el mismo homófono del alfabeto ordenado para las dos letras que vamos a codificar. En este caso, la forma de elegirlo sería:

(12)xx
x(12)x
xx(12)
(21)xx
x(21)x
xx(21)

Aquí, (12) significa que hemos elegido el mismo homófono para ambos caracteres, primero el primer carácter y luego el segundo. (21) significa lo mismo, pero cogiendo primero el segundo carácter y luego el primero. En todo caso, tenemos 3 homófonos para elegir, y se ha elegido el mismo para los dos caracteres a codificar en cada caso.

Aclarado esto, generalicemos este caso. Vemos que obtener el total de casos consiste en ir eligiendo cada homófono del grupo de homófonos. Así, para un bloque de homófonos de tamaño "t", vemos que el caso "(12)" tiene en total "t" posibilidades, y el caso "(21)" también "t" posibilidades. Por tanto, para este caso tenemos en total "2*t" posibilidades.

La siguiente forma es elegir dos homófonos consecutivos en orden inverso. Tenemos:

21x
x21

Si generalizamos este caso, vemos que un grupo de 2 homófonos se va colocando en diferentes posiciones, como si fuera un único homófono. Tenemos, pues, t-1 posiciones que puede ocupar para un bloque de tamaño "t", así que este caso tiene "t-1" posibilidades en total.

La tercera es elegir los homófonos consecutivos en orden directo:

12x
x12

Este caso es idéntico al anterior, sólo que hemos cambiado el orden en que elegimos los homófonos. Por tanto, este caso tendrá también "t-1" posibilidades en total.

La cuarta y última es cogerlos de forma no consecutiva:

1x2
2x1

Este caso no se ve muy claro con el tamaño que hemos elegido. Usemos un tamaño de 4 homófonos:

1x2x
1xx2
x1x2
2x1x
2xx1
x2x1

Podemos ver más claro este caso si incluimos los dos anteriores casos, y luego los eliminamos. Tenemos:

12xx
1x2x
1xx2
x12x
x1x2
xx12
21xx
2x1x
2xx1
x21x
x2x1
xx21

Vemos que hay una simetría cuando escribimos "12" y cuando escribimos "21", así que eliminamos los casos "21" (luego multiplicaremos el resultado por 2), quedando:

12xx
1x2x
1xx2
x12x
x1x2
xx12

Si tomamos como referencia el "1", vemos que el "2" ocupa todas las posiciones disponibles a la derecha del "1". Cuando el "1" ocupa la posición 1, el "2" ocupa todas las posiciones desde la 2 hasta la "t". Esto son t-1 casos. Cuando el "1" ocupa la posición 2, el "2" ocupa las posiciones desde la 3 hasta la "t". Esto son t-2 casos. Y así sucesivamente, hasta que el "1" ocupa la posición "t-1". Así, el número total de casos será la suma de cada uno de estos casos parciales, es decir, (t-1)+(t-2)+...+3+2+1, o lo que es lo mismo, la suma de los primeros enteros desde 1 hasta "t-1". Esta suma vale t*(t-1)/2. Este es el número de casos para el ejemplo que hemos visto. Como habíamos eliminado el caso "21", que es idéntico a éste, basta multiplicar este resultado por 2 para obtener el número de casos para "12" y "21". Nos queda t*(t-1) casos. Ahora tenemos que eliminar los casos en los que "1" y "2" son consecutivos en orden directo y en orden inverso, pues esos casos los hemos tratado antes aparte. Vimos que estos casos eran "t-1", en ambos. Así que al final, para este caso, nos queda t*(t-1)-2*(t-1)=(t-1)*(t-2).

Ahora podemos obtener el total de casos para poder obtener las probabilidades. El total de casos será la suma de todos los casos anteriores:

2*t+(t-1)+(t-1)+(t*(t-1)-2*(t-1))=t*(t+1)

Como los tamaños de los bloques de homófonos están comprendidos entre 3 y 7, tenemos:

Casos para bloques de 3 caracteres: total=12, caso 1=6, caso 2=2, caso 3=2, caso 4=2
Casos para bloques de 4 caracteres: total=20, caso 1=8, caso 2=3, caso 3=3, caso 4=6
Casos para bloques de 5 caracteres: total=30, caso 1=10, caso 2=4, caso 3=4, caso 4=12
Casos para bloques de 6 caracteres: total=42, caso 1=12, caso 2=5, caso 3=5, caso 4=20
Casos para bloques de 7 caracteres: total=56, caso 1=14, caso 2=6, caso 3=6, caso 4=30

Ahora ya podemos calcular probabilidades. Queremos ver qué probabilidades hay de que el patrón de dos letras iguales en el alfabeto ordenado coincida con el patrón de otras dos letras iguales. Se supone que se eligen los homófonos del alfabeto ordenado de forma aleatoria. Así, tenemos dos casos. El primero, que las dos primeras letras se codifiquen con la misma letra del alfabeto desordenado, y las otras dos también. Esto es el caso 2. La probabilidad será el producto de las probabilidades de ambos casos, que es:

(t-1)/(t*(t+1))*(t-1)/(t*(t+1))=(t-1)^2/(t*(t+1))^2

Para los diferentes bloques, tenemos:

Probabilidad para bloques de 3 caracteres: (3-1)^2/(3*(3+1))^2=2^2/12^2=0.0278~2.78%
Probabilidad para bloques de 4 caracteres: (4-1)^2/(4*(4+1))^2=3^2/20^2=0.0225~2.25%
Probabilidad para bloques de 5 caracteres: (5-1)^2/(5*(5+1))^2=4^2/30^2=0.0178~1.78%
Probabilidad para bloques de 6 caracteres: (6-1)^2/(6*(6+1))^2=5^2/42^2=0.0142~1.42%
Probabilidad para bloques de 7 caracteres: (7-1)^2/(7*(7+1))^2=6^2/56^2=0.0115~1.15%

La probabilidad de que ocurra esto es muy pequeña.

Veamos ahora el resto de casos, es decir, que las letras no sean consecutivas en orden inverso, por lo que se codificarán con diferentes caracteres del alfabeto desordenado. La probabilidad de que ocurra el resto de los casos para el primer par de letras será la suma de los casos 1, 3 y 4. Para calcular la probabilidad de que ocurra en los dos pares de letras, habrá que calcular el producto de la probabilidad de elegir dos homófonos no consecutivos, o consecutivos en orden directo, para el primer par de letras, y multiplicado por la misma probabilidad, que será para el segundo par de letras. Veamos cuánto vale la probabilidad del primer par de letras (que es igual que la del segundo par de letras):

((2*t)+(t-1)+(t*(t-1)-2*(t-1)))/(t*(t+1))=(t^2+1)/(t*(t+1))

La probabilidad de que ocurra con ambos pares de letras será el cuadrado del anterior cálculo: (t^2+1)^2/(t*(t+1))^2. Tenemos, pues:

Probabilidad para bloques de 3 caracteres: (3^2+1)^2/(3*(3+1))^2=10^2/12^2=0.6944~69.44%
Probabilidad para bloques de 4 caracteres: (4^2+1)^2/(4*(4+1))^2=17^2/20^2=0.7225~72.25%
Probabilidad para bloques de 5 caracteres: (5^2+1)^2/(5*(5+1))^2=26^2/30^2=0.7511~75.11%
Probabilidad para bloques de 6 caracteres: (6^2+1)^2/(6*(6+1))^2=37^2/42^2=0.7761~77.61%
Probabilidad para bloques de 7 caracteres: (7^2+1)^2/(7*(7+1))^2=50^2/56^2=0.7972~79.72%

Se observa que hay una probabilidad aceptable para que el patrón se repita. A estas probabilidades hay que sumarles las anteriores para determinar la probabilidad total de que el patrón del primer par de letras coincida con el del segundo par de letras. Nos quedan las probabilidades finales:

Probabilidad para bloques de 3 caracteres: 2.78%+69.44%=72.22%
Probabilidad para bloques de 4 caracteres: 2.25%+72.25%=74.50%
Probabilidad para bloques de 5 caracteres: 1.78%+75.11%=76.89%
Probabilidad para bloques de 6 caracteres: 1.42%+77.61%=79.03%
Probabilidad para bloques de 7 caracteres: 1.15%+79.72%=80.87%

Curiosamente, a medida que el número de homófonos aumenta para una letra, la probabilidad de que un par de esas letras, elegidas aleatoriamente en el bloque de homófonos, codificadas, tengan el mismo patrón que otro par de letras iguales, elegidas igualmente de forma aleatoria en el bloque de homófonos, codificadas, aumenta también. Esto se ve fácilmente teniendo en cuenta que para que no coincidan los patrones, un par de homófonos debe ser elegido de forma consecutiva en orden inverso en el bloque de homófonos, y el otro par no. La probabilidad de elegir estos dos homófonos consecutivos en orden inverso disminuye a medida que aumenta el tamaño del bloque de homófonos. Eso sí, si partimos de que uno de los pares de homófonos ha sido elegido así, la probabilidad de que el otro par sea elegido como homófonos consecutivas en orden inverso es pequeña, y tanto menor cuanto mayor sea el bloque de homófonos.

Con estos resultados, quizá sería factible aplicar el método de Kasiski con patrones para encontrar bloques de texto iguales (todo esto, claro está, suponiendo que no me haya equivocado en los cálculos). Pero hay que tener en cuenta que estos resultados sólo son válidos si no se han introducido nulos. Además, estas probabilidades sólo son para dos pares de letras. Las probabilidades globales de que dos bloques de texto idénticos tengan el mismo patrón en el criptograma serían menores. Aunque esto no es aplicable al reto, lo dejo porque me parece interesante y, como siempre, puede darle a alguien alguna idea para atacarlo.

Visto esto, veamos ahora qué se puede aplicar a este cifrario de lo visto en el cifrario de Wheatstone.

Como hemos visto ya, dos letras consecutivas en el alfabeto ordenado en orden inverso se codificarán igual, aunque sean homófonos. Sin embargo, como se ha dicho que no se permiten letras repetidas, esto no ocurrirá en homófonos. Así, si en el criptograma vemos dos letras iguales seguidas, sabemos que hay dos letras diferentes, pero consecutivas, del alfabeto ordenado. Además, sabemos que la primera letra del criptograma codifica la primera letra de un bloque de homófonos, y la segunda letra del criptograma codifica la última letra del anterior bloque de homófonos. Veamos el ejemplo de la frase "CHICO_FELIZ", y supongamos que se ha codificado con este sistema igual que en el ejemplo dado cuando se vio el cifrario Wheatstone:

CHICO_FELIZ
TUNZWLUUPCZ

Para las letras "UU", tendríamos las siguientes posibilidades de codificación (se encierran entre corchetes las posibles letras; la primera "U" correspondería a la codificación de la letra de la derecha de las encerradas en el corchete, y la segunda "U" a la de la izquierda; se ha añadido el caso especial "[/Z]" al final, que es otra posibilidad (en este caso especial, el orden de codificación es al revés, es decir, la primera "U" codifica a "/", y la segunda "U" codifica a "Z")):

[/A]AAAAA[AB]B[BC]CC[CD]DD[DE]EEEE[EF]F[FG]G[GH]H[HI]III[IJ]J[JK]K[KL]LL[LM]MM[MN]NNN[NO]OOOO[OP]P[PQ]Q[QR]RRR[RS]SSS[ST]TT[TU]UU[UV]V[VX]X[XY]Y[YZ]Z+[/Z]

Dado que los homófonos se eligen al azar, no siempre la combinación "FE" se codificará con dos letras iguales. La probabilidad de que esto ocurra será 1/t1*1/t2=1/(t1*t2), donde "t1" y "t2" son los tamaños de los bloques de homófonos, consecutivos. Así, para el mejor caso (bloques de tamaño 3 consecutivos), tenemos una probabilidad de 1/(3*3)=0.1111~11.11%, y en el peor caso, tenemos una probabilidad de 1/(5*6)=0.0333~3.33% (bloques NNNNN y OOOOOO). Así, la probabilidad de encontrar estos pares de letras repetidos es más bien pequeña.

Hay un caso especial, que es el bloque de texto claro "A/Z", que se codificaría como 3 letras iguales. Es el único caso posible de 3 letras, gracias a que no se permiten caracteres repetidos y a que no hay homófonos para el nulo. Así, si en el criptograma encontramos 3 letras iguales, sabemos que corresponden al texto claro "A/Z", pero no sólo eso, sino que sabemos que las letras cifradas en este bloque son la primera letra del bloque de homófonos "AAAAAAA" del alfabeto claro, el nulo, y la última letra del bloque de homófonos de "ZZZ", cada una después de hacer un salto de línea en la tabla Vigenère equivalente. Una vez localizado uno de estos bloques, podemos controlar si aparece de nuevo esta letra del criptograma que codifica ese bloque, en las proximidades de ese bloque, para estimar los saltos dados en la tabla de Vigenère e intentar deducir otras codificaciones, ya que si sabemos los saltos dados, sabemos cuántas letras del alfabeto ordenado se ha movido ese carácter, y podemos determinar el carácter que codifica. Como el número de saltos sólo lo podemos estimar, esta codificación será también una estimación. Pero puede darnos pistas sobre el texto claro que se está codificando.

Aparte de este bloque de 3 letras iguales, no vamos a encontrar bloques de más de 2 letras iguales en el criptograma, ya que todos los caracteres, menos el nulo, están en bloques de 3 o más homófonos, y la única manera de que se obtuviese un bloque de 3 o más caracteres repetidos en el criptograma sería repitiendo alguna letra, y esto no está permitido.

Otra de las observaciones que se hizo en el cifrario de Wheatstone y que también aplica a éste es el caso de encontrar dos letras repetidas en el criptograma, separadas una cierta distancia. Con estimaciones puede saberse más o menos cuántos saltos se han dado en las líneas de la tabla de Vigenère equivalente, o lo que es lo mismo, la distancia estimada que hay entre las letras del alfabeto ordenado que se codifican como esas letras repetidas. Igualmente aplica el caso general de dos letras cualesquiera de texto claro que conozcamos su codificación en el criptograma.

Si la frecuencia de los nulos es suficiente, otra de las observaciones del cifrario de Wheatstone también es aplicable, y es la de alinear bloques que dan la vuelta al alfabeto desordenado, bloques de tamaño menor de 206 caracteres, tal como se estimó anteriormente, tanto menores cuanto mayor sea la frecuencia de los nulos. Como no sabemos qué caracteres del criptograma codifican nulos, lo único que se me ocurre que se puede hacer es intentar localizar caracteres del primer bloque en posiciones aproximadamente iguales en el segundo, ya que una vez dada la vuelta al alfabeto desordenado, la codificación de los caracteres se vuelve a repetir. Por otro lado, si en el primer bloque localizamos dos nulos, y también en el segundo, con la misma codificación el primero del primer bloque con el primero del segundo bloque, y lo mismo con los segundos nulos, entonces sabemos que el número de saltos de líneas en la tabla Vigenère equivalente entre los nulos del primer bloque es el mismo que entre los nulos del segundo bloque (en realidad, existe la remota posibilidad de que se haya dado una vuelta al alfabeto (99 saltos) o más, entre dichos nulos, pero sólo sería posible si la distancia entre nulos es suficientemente grande, lo que no sería el caso aquí), por lo que la estimación combinada de los saltos en ambos bloques nos puede dar una estimación más aproximada al número real de saltos. En este caso, nos ayuda bastante que los nulos no tengan homófonos, de forma que si se encuentra un nulo en el texto claro, sólo puede haber una codificación para el mismo, por lo que si se codifica en una línea de la tabla de Vigenère, si después se vuelve a codificar en la misma línea, el código obtenido será el mismo, a diferencia del resto de caracteres, que gracias a los homófonos, podrían codificarse de distinta manera. Así, en el alineamiento de bloques que mencionamos, los nulos de un bloque que se codifiquen en una línea de la tabla Vigenère se codificarán igual en el segundo bloque si se codifican en la misma línea. Además, esto garantiza lo dicho antes, que si entre dos nulos de un bloque hay un determinado número de saltos de línea, en el segundo bloque, dos nulos codificados de la misma manera que en el primero tendrán el mismo número de saltos de líneas.

Si logramos la alineación de dos nulos (lo visto antes, es decir, dos nulos codificados de la misma manera en el criptograma), podemos hacer una estimación de la frecuencia de aparición de los nulos con lo visto al principio. La distancia entre dichos nulos nos dará el tamaño de superbloque, que deberá ser parecido al promedio (para distinguir entre los bloques de caracteres ordenados y el conjunto de dichos bloques, llamaré "superbloque" a ese conjunto de bloques). Encontrar dos nulos codificados de la misma manera en el criptograma nos dice que entre nulo y nulo hay 99 saltos de líneas en la tabla Vigenère equivalente (el tamaño del alfabeto desordenado). El tamaño estimado del superbloque es de 206 si no hay nulos. Como vimos antes, cuando se añade un nulo puede añadirse entre dos bloques, o dentro de un bloque. Si se añade entre dos bloques el número de saltos de líneas en la tabla Vigenère no varía, ya que este nulo se añade al bloque a su derecha, y el tamaño del superbloque de 206 caracteres aumentaría en 1, a 207. Si el nulo se añade dentro de un bloque, se añade un salto de líneas (se crea un nuevo bloque), y por tanto, hemos aumentado en 1 el número de saltos, por lo que tenemos que eliminar el último bloque del superbloque de 206 caracteres (ahora 207 caracteres) para seguir teniendo 99 saltos. Además, se ha añadido un carácter al superbloque.

Lo que pretendemos ahora es estimar la frecuencia de aparición de los nulos conociendo el tamaño de uno, o varios, si es posible, superbloques.

Empecemos viendo lo obvio. La frecuencia puede estar comprendida entre el 0% (no hay nulos) y el 50%. Este límite del 50% es debido a que no pueden repetirse nulos, pues los caracteres repetidos no están permitidos en este cifrario. Así, en este caso, lo más que podríamos tener en el texto "CHICO_FELIZ" es "C/H/I/C/O/F/E/L/I/Z" (en realidad, podríamos tener un poquito más del 50% si escribimos "/C/H/I/C/O/F/E/L/I/Z/", en el que hay un carácter nulo más que letras, pero esto se ve minimizado en textos grandes, aparte que no se dará una proporción del 50% de nulos). Por otro lado, podrían aparecer todos los caracteres del alfabeto ordenado consecutivos en orden inverso (si se permitieran las repeticiones), de tal forma que el tamaño del superbloque sería de 99, pues cada carácter supone un salto de línea. Pero esto tampoco se va a dar.

Visto esto, vamos a hacer cálculos que nos den una mejor aproximación. Queremos calcular la proporción "p" de nulos conociendo el tamaño del superbloque que contiene los nulos que hemos alineado, que tiene 99 saltos de línea de la tabla Vigenère equivalente.

Para entender los cálculos que vienen, vamos a imaginar la situación. Suponemos que tenemos un superbloque con 206 caracteres, y 99 saltos de línea de la tabla equivalente de Vigenère, y sin nulos. Es decir, lo que cabría esperar si no se hubieran añadido los nulos. Ahora vamos a añadir a este superbloque, de forma aleatoria, "k" nulos. La forma de hacerlo, para simplificar los cálculos, es establecer las posiciones donde se añadirán (entre qué caracteres del superbloque se añadirán), y luego añadirlos en una única operación. Esto simplifica los cálculos, ya que si vamos añadiéndolos uno detrás de otro, las probabilidades de añadirlos a posiciones entre bloques, o dentro de bloques, varía a medida que se van añadiendo. El resultado final es el mismo (debería ser el mismo), pero de la forma en que lo hacemos simplifica los cálculos.

Una vez añadidos los "k" nulos, tenemos un superbloque de tamaño 206+k. La probabilidad de encontrar un nulo en este superbloque (o la proporción de nulos) será de p=k/(206+k). Ahora tendremos diferente número de saltos de líneas en este superbloque. Vamos a suponer que podemos encontrar dos nulos entre los cuales hay 99 saltos de líneas, que es, al fin y al cabo, lo que tenemos cuando encontramos dos nulos con la misma codificación en el criptograma. Entre estos nulos habrá "t" caracteres, dato que conocemos (la distancia entre los nulos, que la conocemos cuando los hemos alineado).

En este nuevo superbloque de "t" caracteres, la proporción de nulos es la misma que la del superbloque de 206+k caracteres. Así, en este nuevo superbloque tendremos aproximadamente p*t nulos. El resto de caracteres serán letras del alfabeto desordenado, y en total serán t-p*t=(1-p)*t. Es decir, en el nuevo superbloque de "t" caracteres tendremos aproximadamente p*t nulos, y aproximadamente (1-p)*t caracteres que no son nulos.

Entre todos los nulos que tenemos, unos habrán acabado entre bloques de caracteres ordenados, y otros dentro de bloques de caracteres. Las probabilidades de que caigan en un caso u otro las conocemos. Para el caso de que caigan entre bloques de caracteres ordenados, la probabilidad es de 0.4806. Así, de los nulos que tenemos, 0.4806*p*t habrán caído entre bloques de caracteres ordenados. Estos nulos no añaden saltos de líneas en la tabla equivalente de Vigenère, como vimos anteriormente. Simplemente se incorporan al bloque que tienen a su derecha. El resto, que será 0.5194*p*t (0.5194=1-0.4806, es decir, los que no caigan entre dos bloques de caracteres, caerán dentro de un bloque de caracteres), serán nulos que hayan caído dentro de un bloque de caracteres. Estos nulos han añadido un salto más al superbloque de 206+k caracteres, y es un salto que hay que contabilizar en el nuevo superbloque de "t" caracteres. Por otro lado, hay que tener en cuenta que el número de saltos de líneas debidos a caracteres no nulos se mantiene. Es decir, que cuando añadimos un nulo, el número de saltos de líneas no disminuye. Se mantiene o se incrementa en 1. Así, conocido el número de caracteres no nulos en el superbloque de tamaño "t", podemos estimar el número de saltos de líneas (o de bloques) debidos a estos caracteres no nulos. Sabemos que la proporción de bloques en un grupo de "x" caracteres es de 0.4806, como vimos anteriormente. Así, para este caso en el que tenemos (1-p)*t caracteres, el número de bloques que habría si no hubiera nulos sería de 0.4806*(1-p)*t.

Ya tenemos todo lo necesario para calcular "p". El número saltos de líneas debidos a los caracteres no nulos es de 0.4806*(1-p)*t, y el número de saltos debido a caracteres nulos es de 0.5194*p*t. El total de saltos es, por tanto, de 0.4806*(1-p)*t+0.5194*p*t=(0.0388*p+0.4806)*t. Como el número de saltos es 99, tenemos la ecuación (0.0388*p+0.4806)*t=99, cuya incógnita, "p", es la proporción de los nulos, y es la que queremos determinar. Así que podemos calcular esta proporción despejando la incógita: p=(99/t-0.4806)/0.0388.

Esta proporción "p" debe valer entre 0 y 1, por lo que podemos calcular los límites entre los que estará "t" resolviendo las inecuaciones:

0<=(99/t-0.4806)/0.0388 ---> t<=205.9925~206
1>=(99/t-0.4806)/0.0388 ---> t>=190.6045~191

Es decir, que el tamaño de superbloques estará aproximadamente entre 191 y 206, lo cual es un margen muy pequeño, y nos dará más bien poca precisión en la proporción de nulos si logramos alinear dos de ellos y aplicar la anterior fórmula.

En caso de que no encontremos dos nulos con la misma codificación, pero que sí encontremos dos caracteres de los que conozcamos el número de saltos de líneas de la tabla equivalente de Vigenère, si "n" es este número de saltos, la anterior fórmula puede aplicarse sustituyendo el "99" por "n": p=(n/t-0.4806)/0.0388.

Y hasta aquí lo que he podido sacar de este cifrario. No sé si se entiende bien o no, pero me da que más bien no :) . Quizá está un poco lioso. Por otro lado, espero no haberme equivocado en lo expuesto (seguramente haya más de un error). Pero bueno, hecho esto, ahora es hora de atacarlo. Tendré que mirar cómo aplicar todo esto, y ver si se me ocurre algo más. A ver si esto también le da alguna idea a alguien para atacarlo.

Pequeño despiste corregido

Lo de cifrar un texto conocido para comprobar las probabilidades es algo que no se me había ocurrido hacer. De todas formas no tenía implementado el algoritmo (precisamente porque todavía no tenía pensado usarlo, hasta que tuviera algo con lo que empezar).

Y hablando de implementar el algoritmo, estuve intentando implementar la parte que descifra, y estuve rompiéndome la cabeza, porque no me funcionaba. Me puse a escribir lo que me pasaba para consultarte, cuando me dí cuenta del problema, y era que las posiciones en el algoritmo se refieren a posiciones que empiezan a contar desde 1, y yo lo tenía para que empezaran a contar desde 0 (cosas de Java, que no me dí cuenta al pasar de Visual Basic a este lenguaje). Ha sido uno de esos despistes tontos que hace que no funcione nada. Corregido ya este pequeño error, a ver si miro a ver cómo ataco a la bestia. Todavía me queda implementar la parte que cifra para poder hacer las pruebas. Aunque creo que primeramente miraré el criptograma en busca de pistas. Iré informando de lo que vaya viendo.

Me gustaría participar

Me gustaría participar, aunque a la vista de los desmesurados ataques de LlamameX y de sqrmatrix, sería como si me apuntara a correr el Tour de Francia con una bici con ruedines. Pero ni siquiera puedo intentarlo porque -vergüenza para mí- aún no he conseguido entender bien el algoritmo, y por ello no he podido implementarlo. En mis tiempos de creador de monstruos naïfs me preocupaba por detallar cada pequeño paso del proceso, pero en los tiempos modernos los participantes son más inteligentes y con pocas palabras se entienden. Así que me dirijo al autor, cuyas amables explicaciones con pseudocódigo siguen siendo para mí insuficientes. Me explico:

1. Entiendo que el alfabeto utilizado (rueda exterior) en el cifrado ejemplo es:

/AAAAAAABBBCCCCDDDDEEEEEEFFFGGGHHHIIIIIJJJKKKLLLLMMMMNNNNNOOOOOOPPPQQQRRRRRSSSSSTTTTUUUUVVVXXXYYYZZZ

Pero entonces, cunando se dice en el pseudocódigo
"Poner en X la posición de L en A0"
¿Cómo se realiza esta operación?, ya que si la letra a cifrar es una A, como hay varias en el alfabeto ¿qué posición se le asigna?

2. Creo deducir -aunque no estoy seguro de nada- que en el cifrado-problema se han alterado tanto el alfabeto -la esfera exterior- como los números de la interior. Pero ¿como se ha alterado el alfabeto? ¿Una permutación de todos sus elementos al tresbolillo, o se han mantenido juntos los grupos homófonos AAA..., BBB..., etc?

¡Oh zozobra!

Si os causa hilaridad mi pregunta tened en cuenta que al Haloperidol es un medicamento terrible.

P.S.
Ocioso es decir que no me he adentrado en los scripts para tratar de averiguarlo

Ruedines

Gracias por tu respuesta

"Ruedines" es la forma de uso cotidiano. La RAE no tiene autoridad para cambiar eso.

Has contestado a una parte de mi pregunta, pero sigo sin entender cómo se determina la posición de una letra del texto claro en el alfabeto homofónico.

Vale

Vale,

escogiendo aleatoriamente una dentro de su grupo,

Pero entonces, hará falta un generador p-aleatorio, conocido por el destinatario. De otro modo ¿cómo podría realizarse la operación de descifrado?

Soy consciente de que el algoritmo debe estar clarísimo, al menos para LlamameX y sqrmatrix, pero yo no lo pillo. Reconozco que estoy muy espeso, totalmente desentrenado, aparte de la burricie congénita.

De todas maneras, no te preocupes demasiado. Aunque pudiera implementarlo, me considero incapaz de diseñar un ataque.

Así es

Menos mal que en la hora de patio nos dejan jugar a la petanca con bolas de goma.

De todas formas, creo que ahora lo he pillado, gracias a tu paciencia. Mi problema era que por alguna razón pensé que la idea era enviar un texto cifrado con "letras", como se muestra en los ejemplos del principio. Si el destinatario recibe el cifrado en números, como en efecto ocurre en el reto propuesto, no hay problema. Mis disculpas.

Bloques de códigos repetidos

He encontrado un bloque de 3 códigos repetidos:

{52,52,52}: posición: 43

Curiosamente, es el bloque que se ve, en el reto, al final de la primera línea y comienzo de la segunda. Era un salto de línea un poco raro, sin aparente justificación. ¿Una pista oculta, quizá?. En todo caso, sabemos que ese bloque de 3 letras codifica el texto claro "A/Z", si no me he equivocado en lo que expuse. La "A" es la primera del bloque de homófonos de dicha letra, y la "Z" el último de su bloque. Lamentablemente no hay más bloques de 3 letras. He encontrado bloques de 2 códigos repetidos que, recordemos, codifican letras consecutivas del alfabeto, y en el alfabeto de homófonos, estas letras son de bloques consecutivos de homófonos, en orden inverso. Estos bloques son:

{37,37}: posición: 142
{28,28}: posición: 905
{18,18}: posición: 1219
{39,39}: posición: 1230
{80,80}: posición: 1345
{07,07}: posición: 1869
{36,36}: posición: 1909
{07,07}: posición: 1934
{99,99}: posición: 2047
{91,91}: posición: 2110
{31,31}: posición: 2126
{48,48}: posición: 2225
{55,55}: posición: 2366
{11,11}: posición: 3221
{51,51}: posición: 3291
{53,53}: posición: 3385
{98,98}: posición: 3667
{63,63}: posición: 3768
{89,89}: posición: 4154
{54,54}: posición: 4183
{58,58}: posición: 4261
{52,52}: posición: 4309
{76,76}: posición: 4379
{52,52}: posición: 4537
{83,83}: posición: 5096

Las posiciones comienzan a contar desde 0 (por llevar un poco la contraria).

Ahora, con esto, a ver qué se puede hacer

Eso sólo se cumple si al

Eso sólo se cumple si al codificar el texto, al elegir los homófonos, coincide el primer homófono de las "A" y el último de las "Z", es decir, del alfabeto ordenado, si se codifica con las letras entre corchetes:

...YYYZZ[Z/A]AAAAAABBB...

O sea, que la existencia de la cadena "A/Z" no garantiza que se codifique con 3 códigos iguales en el criptograma, porque es necesario que se codifiquen con los homófonos que he indicado. Pero si en el criptograma encontramos 3 códigos iguales, eso nos garantiza que codifican la cadena "A/Z", y que dio la casualidad, cuando se codificó, que se eligieron esos homófonos que indico

Iba a hacer lo mismo,

Iba a hacer lo mismo, reeditar para decirte que intentes forzar, en la codificación, cuando codifiques la "A", que elija siempre el primer homófono de las "A", y cuando codifiques la "Z", que elija siempre el último homófono de las "Z". Deberían salirte 3 códigos iguales cuando codifique la cadena "A/Z". Si no, es que algo hice mal cuando deduje esto, y tendría que repasar en busca del fallo

Cuando dices que has cogido

Cuando dices que has cogido el primer homófono de cada grupo, ¿también has cogido el primér homófomo de las "Z"?. Porque para las "Z" tienes que coger el último homófono. Es decir, hay que coger el primer homófono de las "A" y el último de las "Z", para que se repitan los tres códigos en la cadena "A/Z"
------------
Reedición
Si te fijas en los caracteres repetidos, y como el alfabeto desordenado está, en este ejemplo, ordenado, tenemos {13,13,11}. Este "11" es el primer homófono de la "Z", Como hay 3 homófonos para la "Z", el último sería, precisamente, el "13", y ya tendríamos el grupo de 3 códigos repetidos

Creo que no entendí bien el

Creo que no entendí bien el cifrario. La única manera de que se repitan 3 códigos en el criptograma es, aparte de la cadena "A/Z", repitiendo al menos dos letras en el texto claro. Yo había entendido que eso no se permitía en el cifrario, pero por lo que me comentas, parece que sí. Entonces, para aclararme, si tenemos la frase "BUSCA_A_ALGUIEN", al eliminar espacios queda "BUSCAAALGUIEN", y esas tres "A" podrían quedar así a la hora de cifrarlas, si da la casualidad de que no se les inserta ningún nulo, ¿no?

Páginas

opinar

Texto puro

  • No se permiten etiquetas HTML.
  • Saltos automáticos de líneas y de párrafos.
Imágenes
Puedes añadir hasta 10 imágenes explicativas a tus comentarios (pantallazos, etc).
Los archivos deben ser menores que 8 MB.
Tipos de archivo permitidos: png gif jpg jpeg.
By submitting this form, you accept the Mollom privacy policy.