[{"data":1,"prerenderedAt":566},["ShallowReactive",2],{"navigation_docs":3,"-ciphers-triple-des":156,"-ciphers-triple-des-surround":561},[4,36],{"title":5,"path":6,"stem":7,"children":8,"icon":35},"Guide","\u002Fguide","1.guide\u002F01.index",[9,11,15,19,23,27,31],{"title":10,"path":6,"stem":7},"Getting Started",{"title":12,"path":13,"stem":14},"Encode and decode","\u002Fguide\u002Ftransform","1.guide\u002F02.transform",{"title":16,"path":17,"stem":18},"Analysis","\u002Fguide\u002Fanalysis","1.guide\u002F03.analysis",{"title":20,"path":21,"stem":22},"CLI","\u002Fguide\u002Fcli","1.guide\u002F04.cli",{"title":24,"path":25,"stem":26},"Agents","\u002Fguide\u002Fagents","1.guide\u002F05.agents",{"title":28,"path":29,"stem":30},"Custom ciphers","\u002Fguide\u002Fcustom","1.guide\u002F06.custom",{"title":32,"path":33,"stem":34},"Playground","\u002Fguide\u002Fplayground","1.guide\u002F07.playground","i-solar-book-2-linear",{"title":37,"path":38,"stem":39,"children":40,"icon":155},"Ciphers","\u002Fciphers","2.ciphers\u002F00.index",[41,43,47,51,55,59,63,67,71,75,79,83,87,91,95,99,103,107,111,115,119,123,127,131,135,139,143,147,151],{"title":42,"path":38,"stem":39},"Overview",{"title":44,"path":45,"stem":46},"Caesar","\u002Fciphers\u002Fcaesar","2.ciphers\u002F01.caesar",{"title":48,"path":49,"stem":50},"ROT-13","\u002Fciphers\u002Frot13","2.ciphers\u002F02.rot13",{"title":52,"path":53,"stem":54},"ROT-47","\u002Fciphers\u002Frot47","2.ciphers\u002F03.rot47",{"title":56,"path":57,"stem":58},"Atbash","\u002Fciphers\u002Fatbash","2.ciphers\u002F04.atbash",{"title":60,"path":61,"stem":62},"Affine","\u002Fciphers\u002Faffine","2.ciphers\u002F05.affine",{"title":64,"path":65,"stem":66},"Vigenère","\u002Fciphers\u002Fvigenere","2.ciphers\u002F06.vigenere",{"title":68,"path":69,"stem":70},"Trithemius","\u002Fciphers\u002Ftrithemius","2.ciphers\u002F07.trithemius",{"title":72,"path":73,"stem":74},"Alberti","\u002Fciphers\u002Falberti","2.ciphers\u002F08.alberti",{"title":76,"path":77,"stem":78},"Playfair","\u002Fciphers\u002Fplayfair","2.ciphers\u002F09.playfair",{"title":80,"path":81,"stem":82},"Polybius square","\u002Fciphers\u002Fpolybius","2.ciphers\u002F10.polybius",{"title":84,"path":85,"stem":86},"Morse code","\u002Fciphers\u002Fmorse","2.ciphers\u002F11.morse",{"title":88,"path":89,"stem":90},"Bacon's cipher","\u002Fciphers\u002Fbacon","2.ciphers\u002F12.bacon",{"title":92,"path":93,"stem":94},"Tap code","\u002Fciphers\u002Ftap-code","2.ciphers\u002F13.tap-code",{"title":96,"path":97,"stem":98},"ADFGVX","\u002Fciphers\u002Fadfgvx","2.ciphers\u002F14.adfgvx",{"title":100,"path":101,"stem":102},"Bifid","\u002Fciphers\u002Fbifid","2.ciphers\u002F15.bifid",{"title":104,"path":105,"stem":106},"Rail fence","\u002Fciphers\u002Frail-fence","2.ciphers\u002F16.rail-fence",{"title":108,"path":109,"stem":110},"Columnar transposition","\u002Fciphers\u002Fcolumnar","2.ciphers\u002F17.columnar",{"title":112,"path":113,"stem":114},"Enigma M3","\u002Fciphers\u002Fenigma","2.ciphers\u002F18.enigma",{"title":116,"path":117,"stem":118},"Beaufort","\u002Fciphers\u002Fbeaufort","2.ciphers\u002F19.beaufort",{"title":120,"path":121,"stem":122},"Autokey","\u002Fciphers\u002Fautokey","2.ciphers\u002F20.autokey",{"title":124,"path":125,"stem":126},"AES (ECB)","\u002Fciphers\u002Faes","2.ciphers\u002F21.aes",{"title":128,"path":129,"stem":130},"Triple DES (ECB)","\u002Fciphers\u002Ftriple-des","2.ciphers\u002F22.triple-des",{"title":132,"path":133,"stem":134},"AES (LRW)","\u002Fciphers\u002Faes-lrw","2.ciphers\u002F23.aes-lrw",{"title":136,"path":137,"stem":138},"AES (CBC)","\u002Fciphers\u002Faes-cbc","2.ciphers\u002F24.aes-cbc",{"title":140,"path":141,"stem":142},"AES (CFB)","\u002Fciphers\u002Faes-cfb","2.ciphers\u002F25.aes-cfb",{"title":144,"path":145,"stem":146},"AES (CTR)","\u002Fciphers\u002Faes-ctr","2.ciphers\u002F26.aes-ctr",{"title":148,"path":149,"stem":150},"AES (CCM)","\u002Fciphers\u002Faes-ccm","2.ciphers\u002F27.aes-ccm",{"title":152,"path":153,"stem":154},"AES (OFB)","\u002Fciphers\u002Faes-ofb","2.ciphers\u002F28.aes-ofb","i-solar-library-linear",{"id":157,"title":128,"body":158,"description":554,"extension":555,"links":556,"meta":557,"navigation":558,"path":129,"seo":559,"stem":130,"__hash__":560},"docs\u002F2.ciphers\u002F22.triple-des.md",{"type":159,"value":160,"toc":550},"minimark",[161,165,169,182,318,329,380,383,388,391,452,462,466,473,519,522,543,546],[162,163],"cipher-facts",{"name":164},"triple-des",[166,167,168],"p",{},"Triple DES, also 3DES or TDEA, from NIST SP 800-67. Each 8-byte block is encrypted with DES under K1, decrypted under K2, then encrypted again under K3. The key is hex. 48 digits are three keys. 32 digits are two, and K3 is K1 again. Case doesn't matter and spaces are ignored. The last bit of every key byte is a parity bit in DES. Nothing checks it. Keys that differ only there encrypt the same way.",[166,170,171,172,176,177,181],{},"Text goes in as UTF-8 with PKCS#7 padding, ciphertext comes out as lowercase hex, and ",[173,174,175],"code",{},"decode"," wants hex back. The mode is ECB, same as ",[178,179,180],"a",{"href":125},"AES",".",[183,184,189],"pre",{"className":185,"code":186,"language":187,"meta":188,"style":188},"language-ts shiki shiki-themes github-light github-light poimandres","const tdes = create(\"triple-des\");\nconst key = \"0123456789abcdef23456789abcdef01456789abcdef0123\";\ntdes.encode(\"ATTACK AT DAWN\", { key }).text; \u002F\u002F \"a1a3679052607883b30ef4b95156ff29\"\ntdes.decode(\"a1a3679052607883b30ef4b95156ff29\", { key }).text; \u002F\u002F \"ATTACK AT DAWN\"\n","ts","",[173,190,191,227,248,287],{"__ignoreMap":188},[192,193,196,200,204,207,211,215,219,222,224],"span",{"class":194,"line":195},"line",1,[192,197,199],{"class":198},"s1TYA","const",[192,201,203],{"class":202},"saoiD"," tdes",[192,205,206],{"class":198}," =",[192,208,210],{"class":209},"sULi6"," create",[192,212,214],{"class":213},"sKlNE","(",[192,216,218],{"class":217},"scVjq","\"",[192,220,164],{"class":221},"sQ7BG",[192,223,218],{"class":217},[192,225,226],{"class":213},");\n",[192,228,230,232,235,237,240,243,245],{"class":194,"line":229},2,[192,231,199],{"class":198},[192,233,234],{"class":202}," key",[192,236,206],{"class":198},[192,238,239],{"class":217}," \"",[192,241,242],{"class":221},"0123456789abcdef23456789abcdef01456789abcdef0123",[192,244,218],{"class":217},[192,246,247],{"class":213},";\n",[192,249,251,255,257,260,262,264,267,269,272,274,277,280,283],{"class":194,"line":250},3,[192,252,254],{"class":253},"spVlQ","tdes",[192,256,181],{"class":213},[192,258,259],{"class":209},"encode",[192,261,214],{"class":213},[192,263,218],{"class":217},[192,265,266],{"class":221},"ATTACK AT DAWN",[192,268,218],{"class":217},[192,270,271],{"class":213},", {",[192,273,234],{"class":253},[192,275,276],{"class":213}," }).",[192,278,279],{"class":253},"text",[192,281,282],{"class":213},"; ",[192,284,286],{"class":285},"sjhu3","\u002F\u002F \"a1a3679052607883b30ef4b95156ff29\"\n",[192,288,290,292,294,296,298,300,303,305,307,309,311,313,315],{"class":194,"line":289},4,[192,291,254],{"class":253},[192,293,181],{"class":213},[192,295,175],{"class":209},[192,297,214],{"class":213},[192,299,218],{"class":217},[192,301,302],{"class":221},"a1a3679052607883b30ef4b95156ff29",[192,304,218],{"class":217},[192,306,271],{"class":213},[192,308,234],{"class":253},[192,310,276],{"class":213},[192,312,279],{"class":253},[192,314,282],{"class":213},[192,316,317],{"class":285},"\u002F\u002F \"ATTACK AT DAWN\"\n",[166,319,320,321,324,325,328],{},"OpenSSL agrees. ",[173,322,323],{},"-des-ede3-ecb"," takes the 48-digit key, ",[173,326,327],{},"-des-ede-ecb"," the 32-digit one:",[183,330,334],{"className":331,"code":332,"language":333,"meta":188,"style":188},"language-bash shiki shiki-themes github-light github-light poimandres","printf %s \"ATTACK AT DAWN\" | openssl enc -des-ede3-ecb -K 0123456789abcdef23456789abcdef01456789abcdef0123 | xxd -p\n","bash",[173,335,336],{"__ignoreMap":188},[192,337,338,342,346,348,350,352,355,359,362,366,369,372,374,377],{"class":194,"line":195},[192,339,341],{"class":340},"s39Ir","printf",[192,343,345],{"class":344},"sX7Zv"," %s",[192,347,239],{"class":217},[192,349,266],{"class":221},[192,351,218],{"class":217},[192,353,354],{"class":198}," |",[192,356,358],{"class":357},"sseY5"," openssl",[192,360,361],{"class":344}," enc",[192,363,365],{"class":364},"sqT1Y"," -des-ede3-ecb",[192,367,368],{"class":364}," -K",[192,370,371],{"class":344}," 0123456789abcdef23456789abcdef01456789abcdef0123",[192,373,354],{"class":198},[192,375,376],{"class":357}," xxd",[192,378,379],{"class":364}," -p\n",[166,381,382],{},"The tests start from three outside sources. The example in SP 800-67, three blocks long. The known-answer tables of NIST SP 800-17. And the DES walkthrough from J. Orlin Grabbe's \"The DES Algorithm Illustrated\".",[384,385,387],"h2",{"id":386},"three-equal-keys-make-one-des","Three equal keys make one DES",[166,389,390],{},"Why decrypt in the middle? So that K1 = K2 = K3 cancels out. The first encryption and the decryption undo each other, and what's left is plain single DES. Take Grabbe's key three times:",[183,392,394],{"className":185,"code":393,"language":187,"meta":188,"style":188},"tdes.encode(\"ATTACK AT DAWN\", { key: \"133457799bbcdff1\".repeat(3) }).text;\n\u002F\u002F \"1739739759a5caa5b6544c0af3cad197\"\n",[173,395,396,447],{"__ignoreMap":188},[192,397,398,400,402,404,406,408,410,412,414,417,420,422,425,427,429,432,434,438,441,443,445],{"class":194,"line":195},[192,399,254],{"class":253},[192,401,181],{"class":213},[192,403,259],{"class":209},[192,405,214],{"class":213},[192,407,218],{"class":217},[192,409,266],{"class":221},[192,411,218],{"class":217},[192,413,271],{"class":213},[192,415,234],{"class":416},"snHMy",[192,418,419],{"class":213},":",[192,421,239],{"class":217},[192,423,424],{"class":221},"133457799bbcdff1",[192,426,218],{"class":217},[192,428,181],{"class":213},[192,430,431],{"class":209},"repeat",[192,433,214],{"class":213},[192,435,437],{"class":436},"siHFe","3",[192,439,440],{"class":213},")",[192,442,276],{"class":213},[192,444,279],{"class":253},[192,446,247],{"class":213},[192,448,449],{"class":194,"line":229},[192,450,451],{"class":285},"\u002F\u002F \"1739739759a5caa5b6544c0af3cad197\"\n",[166,453,454,455,457,458,461],{},"That is DES with ",[173,456,424],{}," and nothing more, 56 bits of key. ",[173,459,460],{},"openssl enc -des-ecb -provider legacy -K 133457799bbcdff1"," prints the same bytes. It's the whole point of the EDE order: one Triple DES implementation still speaks plain DES.",[384,463,465],{"id":464},"why-ecb-leaks","Why ECB leaks",[166,467,468,469,472],{},"8-byte blocks make it easy to see. Sixteen ",[173,470,471],{},"A","s are two equal blocks, and they come out as two equal blocks:",[183,474,476],{"className":185,"code":475,"language":187,"meta":188,"style":188},"tdes.encode(\"A\".repeat(16), { key }).text;\n\u002F\u002F 9f6ca443ceebf424 9f6ca443ceebf424 832846b52f9e213d\n",[173,477,478,514],{"__ignoreMap":188},[192,479,480,482,484,486,488,490,492,494,496,498,500,503,506,508,510,512],{"class":194,"line":195},[192,481,254],{"class":253},[192,483,181],{"class":213},[192,485,259],{"class":209},[192,487,214],{"class":213},[192,489,218],{"class":217},[192,491,471],{"class":221},[192,493,218],{"class":217},[192,495,181],{"class":213},[192,497,431],{"class":209},[192,499,214],{"class":213},[192,501,502],{"class":436},"16",[192,504,505],{"class":213},"), {",[192,507,234],{"class":253},[192,509,276],{"class":213},[192,511,279],{"class":253},[192,513,247],{"class":213},[192,515,516],{"class":194,"line":229},[192,517,518],{"class":285},"\u002F\u002F 9f6ca443ceebf424 9f6ca443ceebf424 832846b52f9e213d\n",[166,520,521],{},"Spaces added to show the blocks. The last one is only padding.",[166,523,524,525,528,529,532,533,535,536,539,540,542],{},"A key that isn't 32 or 48 hex digits is an ",[173,526,527],{},"InvalidOptionError",", a missing one a ",[173,530,531],{},"MissingOptionError",". On ",[173,534,175],{},", ciphertext that isn't whole 8-byte blocks of hex is a ",[173,537,538],{},"CipherError",". A wrong key almost always breaks the padding, and that's a ",[173,541,538],{}," too. So are decrypted bytes that aren't UTF-8.",[166,544,545],{},"NIST disallowed Triple DES for encryption after 2023. Its 64-bit block is too small for a lot of data under one key. This one is plain TypeScript over bit arrays, slow and not constant time. It's here for puzzles and for learning how a Feistel network works. Don't protect anything real with it.",[547,548,549],"style",{},"html pre.shiki code .s1TYA, html code.shiki .s1TYA{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#91B4D5}html pre.shiki code .saoiD, html code.shiki .saoiD{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#E4F0FB}html pre.shiki code .sULi6, html code.shiki .sULi6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#E4F0FBD0}html pre.shiki code .sKlNE, html code.shiki .sKlNE{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#A6ACCD}html pre.shiki code .scVjq, html code.shiki .scVjq{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#A6ACCD}html pre.shiki code .sQ7BG, html code.shiki .sQ7BG{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#5DE4C7}html pre.shiki code .spVlQ, html code.shiki .spVlQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E4F0FB}html pre.shiki code .sjhu3, html code.shiki .sjhu3{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#767C9DB0;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s39Ir, html code.shiki .s39Ir{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#91B4D5}html pre.shiki code .sX7Zv, html code.shiki .sX7Zv{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#ADD7FF}html pre.shiki code .sseY5, html code.shiki .sseY5{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#91B4D5}html pre.shiki code .sqT1Y, html code.shiki .sqT1Y{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#ADD7FF}html pre.shiki code .snHMy, html code.shiki .snHMy{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#ADD7FF}html pre.shiki code .siHFe, html code.shiki .siHFe{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#5DE4C7}",{"title":188,"searchDepth":229,"depth":229,"links":551},[552,553],{"id":386,"depth":229,"text":387},{"id":464,"depth":229,"text":465},"DES three times, encrypt, decrypt and encrypt again. UTF-8 text in, hex out, and every 8-byte block encrypted on its own.","md",null,{},true,{"title":128,"description":554},"CyC3jnend8kuZ4lZb6zt_e0djQ7rwoj5NV6mJJzVBfk",[562,564],{"title":124,"path":125,"stem":126,"description":563,"children":-1},"The standard block cipher in its simplest mode. UTF-8 text in, hex out, and every 16-byte block encrypted on its own, so repeats show through.",{"title":132,"path":133,"stem":134,"description":565,"children":-1},"AES with a tweak. Every 16-byte block is masked by its own position, so equal blocks stop looking equal. UTF-8 text in, hex out.",1790272611447]