[{"data":1,"prerenderedAt":551},["ShallowReactive",2],{"navigation_docs":3,"-ciphers-mars":204,"-ciphers-mars-surround":546},[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":203},"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,155,159,163,167,171,175,179,183,187,191,195,199],{"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",{"title":156,"path":157,"stem":158},"AES (OCB)","\u002Fciphers\u002Faes-ocb","2.ciphers\u002F29.aes-ocb",{"title":160,"path":161,"stem":162},"Triple DES (CBC)","\u002Fciphers\u002Ftriple-des-cbc","2.ciphers\u002F30.triple-des-cbc",{"title":164,"path":165,"stem":166},"Rijndael (ECB)","\u002Fciphers\u002Frijndael","2.ciphers\u002F31.rijndael",{"title":168,"path":169,"stem":170},"AES (XTS)","\u002Fciphers\u002Faes-xts","2.ciphers\u002F32.aes-xts",{"title":172,"path":173,"stem":174},"AES (CBC-MAC)","\u002Fciphers\u002Faes-cbc-mac","2.ciphers\u002F33.aes-cbc-mac",{"title":176,"path":177,"stem":178},"Blowfish (ECB)","\u002Fciphers\u002Fblowfish","2.ciphers\u002F34.blowfish",{"title":180,"path":181,"stem":182},"DES (ECB)","\u002Fciphers\u002Fdes","2.ciphers\u002F35.des",{"title":184,"path":185,"stem":186},"DESX (ECB)","\u002Fciphers\u002Fdesx","2.ciphers\u002F36.desx",{"title":188,"path":189,"stem":190},"IDEA (ECB)","\u002Fciphers\u002Fidea","2.ciphers\u002F37.idea",{"title":192,"path":193,"stem":194},"Lucifer (ECB)","\u002Fciphers\u002Flucifer","2.ciphers\u002F38.lucifer",{"title":196,"path":197,"stem":198},"MARS (ECB)","\u002Fciphers\u002Fmars","2.ciphers\u002F39.mars",{"title":200,"path":201,"stem":202},"Serpent (ECB)","\u002Fciphers\u002Fserpent","2.ciphers\u002F40.serpent","i-solar-library-linear",{"id":205,"title":196,"body":206,"description":539,"extension":540,"links":541,"meta":542,"navigation":543,"path":197,"seo":544,"stem":198,"__hash__":545},"docs\u002F2.ciphers\u002F39.mars.md",{"type":207,"value":208,"toc":533},"minimark",[209,213,217,220,233,241,253,388,393,420,423,426,430,436,440,443,446,450,457,505,508,529],[210,211],"cipher-facts",{"name":212},"mars",[214,215,216],"p",{},"MARS is what IBM sent to the AES competition in 1998. Don Coppersmith was on the team, the same Coppersmith who had worked on DES more than twenty years before. It made the final five, got a tweak to its key schedule in August 1999, and lost to Rijndael in 2000 like everybody else.",[214,218,219],{},"The block is 16 bytes, read as four 32-bit words. Where Rijndael does everything with bytes, MARS mixes all the operations a 1998 CPU was good at: addition, subtraction, XOR, table lookups, multiplication and rotations by an amount that depends on the data. Thirty-two rounds in three layers:",[221,222,223,227,230],"ul",{},[224,225,226],"li",{},"the key gets added to the four words, then eight forward mixing rounds run S-box lookups with no key at all,",[224,228,229],{},"sixteen core rounds do the real work, each one with two key words, a multiplication and those data-dependent rotations,",[224,231,232],{},"eight backwards mixing rounds mirror the first eight, and the last key words get subtracted.",[214,234,235,236,240],{},"In every round one word changes the other three and then all four rotate one place. The paper calls it a type-3 Feistel network, so it's filed under ",[237,238,239],"code",{},"feistel"," here. The unkeyed layers on both ends are there so an attack has to peel them off first before it even sees the core.",[214,242,243,244,247,248,252],{},"The key is 32 to 112 hex digits in steps of 8, so 4 to 14 words, 128 to 448 bits. Words are little-endian, in the key and in the block, as in IBM's test vectors. Case doesn't matter and spaces are ignored. Text goes in as UTF-8 with PKCS#7 padding, ciphertext comes out as lowercase hex, and ",[237,245,246],{},"decode"," wants hex back. The mode is ECB, over 16-byte blocks like ",[249,250,251],"a",{"href":125},"AES",".",[254,255,260],"pre",{"className":256,"code":257,"language":258,"meta":259,"style":259},"language-ts shiki shiki-themes github-light github-light poimandres","const mars = create(\"mars\");\nconst key = \"0123456789abcdeffedcba9876543210\";\nmars.encode(\"ATTACK AT DAWN\", { key }).text; \u002F\u002F \"de839bee915b8cd4fc0243d93c4cae4b\"\nmars.decode(\"de839bee915b8cd4fc0243d93c4cae4b\", { key }).text; \u002F\u002F \"ATTACK AT DAWN\"\n","ts","",[237,261,262,298,319,357],{"__ignoreMap":259},[263,264,267,271,275,278,282,286,290,293,295],"span",{"class":265,"line":266},"line",1,[263,268,270],{"class":269},"s1TYA","const",[263,272,274],{"class":273},"saoiD"," mars",[263,276,277],{"class":269}," =",[263,279,281],{"class":280},"sULi6"," create",[263,283,285],{"class":284},"sKlNE","(",[263,287,289],{"class":288},"scVjq","\"",[263,291,212],{"class":292},"sQ7BG",[263,294,289],{"class":288},[263,296,297],{"class":284},");\n",[263,299,301,303,306,308,311,314,316],{"class":265,"line":300},2,[263,302,270],{"class":269},[263,304,305],{"class":273}," key",[263,307,277],{"class":269},[263,309,310],{"class":288}," \"",[263,312,313],{"class":292},"0123456789abcdeffedcba9876543210",[263,315,289],{"class":288},[263,317,318],{"class":284},";\n",[263,320,322,325,327,330,332,334,337,339,342,344,347,350,353],{"class":265,"line":321},3,[263,323,212],{"class":324},"spVlQ",[263,326,252],{"class":284},[263,328,329],{"class":280},"encode",[263,331,285],{"class":284},[263,333,289],{"class":288},[263,335,336],{"class":292},"ATTACK AT DAWN",[263,338,289],{"class":288},[263,340,341],{"class":284},", {",[263,343,305],{"class":324},[263,345,346],{"class":284}," }).",[263,348,349],{"class":324},"text",[263,351,352],{"class":284},"; ",[263,354,356],{"class":355},"sjhu3","\u002F\u002F \"de839bee915b8cd4fc0243d93c4cae4b\"\n",[263,358,360,362,364,366,368,370,373,375,377,379,381,383,385],{"class":265,"line":359},4,[263,361,212],{"class":324},[263,363,252],{"class":284},[263,365,246],{"class":280},[263,367,285],{"class":284},[263,369,289],{"class":288},[263,371,372],{"class":292},"de839bee915b8cd4fc0243d93c4cae4b",[263,374,289],{"class":288},[263,376,341],{"class":284},[263,378,305],{"class":324},[263,380,346],{"class":284},[263,382,349],{"class":324},[263,384,352],{"class":284},[263,386,387],{"class":355},"\u002F\u002F \"ATTACK AT DAWN\"\n",[389,390,392],"h2",{"id":391},"where-the-s-box-comes-from","Where the S-box comes from",[214,394,395,396,399,400,403,404,407,408,411,412,415,416,419],{},"The S-box has 512 words, and nobody typed them in. Entry ",[237,397,398],{},"5i + j"," is word ",[237,401,402],{},"j"," of SHA-1 over four words: ",[237,405,406],{},"5i",", then ",[237,409,410],{},"0xb7e15162"," and ",[237,413,414],{},"0x243f6a88",", which are the fraction digits of e and pi, then ",[237,417,418],{},"0x02917d59",". That last one is the only picked constant. IBM ran through about 2^26 candidates for a week and kept the one that gave the best S-box.",[214,421,422],{},"One more step, though. Any two entries in the same half that XOR to two or more zero bytes are too alike. So the first one of the pair gets multiplied by 3. It happens to nine entries.",[214,424,425],{},"That's how this package builds the table too, once, with its own small SHA-1, instead of shipping 4096 hex digits. The tests run IBM's table chains, 40 encryptions per key size fed into each other, and between them they touch every entry.",[389,427,429],{"id":428},"checked-against","Checked against",[214,431,432,433,252],{},"IBM's known answers for the tweaked key schedule, the ones Crypto++ ships, cover 128, 192 and 256-bit keys. Crypto++ also takes 320, 384 and 448 bits. For 160 and 416, which Crypto++ refuses, the vectors come from CycloneCRYPTO, and the two agree everywhere else. Whole texts with padding are checked against Crypto++'s ",[237,434,435],{},"ECB_Mode\u003CMARS>",[389,437,439],{"id":438},"how-strong-is-it","How strong is it",[214,441,442],{},"Nobody broke the full thing. The best attack in print is Kelsey and Schneier's \"MARS Attacks!\" from 2000. It keeps the mixing layers whole and cuts the core down to five rounds, 21 out of 32, and even that takes around 2^232 work. Sixteen core rounds are a long way off.",[214,444,445],{},"The block is 128 bits, so the Sweet32 collisions that hit Blowfish and Triple DES aren't a problem here.",[389,447,449],{"id":448},"why-ecb-leaks","Why ECB leaks",[214,451,452,453,456],{},"Same as every ECB here. Thirty-two ",[237,454,455],{},"A","s are two equal blocks, and they come out as two equal blocks:",[254,458,460],{"className":256,"code":459,"language":258,"meta":259,"style":259},"mars.encode(\"A\".repeat(32), { key }).text;\n\u002F\u002F 5ad31428f5ee9d935898dfa24bc60047 5ad31428f5ee9d935898dfa24bc60047 8d521a3c918480273dd03bf203d294d4\n",[237,461,462,500],{"__ignoreMap":259},[263,463,464,466,468,470,472,474,476,478,480,483,485,489,492,494,496,498],{"class":265,"line":266},[263,465,212],{"class":324},[263,467,252],{"class":284},[263,469,329],{"class":280},[263,471,285],{"class":284},[263,473,289],{"class":288},[263,475,455],{"class":292},[263,477,289],{"class":288},[263,479,252],{"class":284},[263,481,482],{"class":280},"repeat",[263,484,285],{"class":284},[263,486,488],{"class":487},"siHFe","32",[263,490,491],{"class":284},"), {",[263,493,305],{"class":324},[263,495,346],{"class":284},[263,497,349],{"class":324},[263,499,318],{"class":284},[263,501,502],{"class":265,"line":300},[263,503,504],{"class":355},"\u002F\u002F 5ad31428f5ee9d935898dfa24bc60047 5ad31428f5ee9d935898dfa24bc60047 8d521a3c918480273dd03bf203d294d4\n",[214,506,507],{},"Spaces added to show the blocks. The last one is only padding.",[214,509,510,511,514,515,518,519,521,522,525,526,528],{},"A key that isn't 4 to 14 words of hex is an ",[237,512,513],{},"InvalidOptionError",", a missing one a ",[237,516,517],{},"MissingOptionError",". On ",[237,520,246],{},", ciphertext that isn't whole 16-byte blocks of hex is a ",[237,523,524],{},"CipherError",". A wrong key almost always breaks the padding, and that's a ",[237,527,524],{}," too. So are decrypted bytes that aren't UTF-8. It's a teaching implementation, not constant time. Puzzles and learning, not secrets.",[530,531,532],"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 .siHFe, html code.shiki .siHFe{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#5DE4C7}",{"title":259,"searchDepth":300,"depth":300,"links":534},[535,536,537,538],{"id":391,"depth":300,"text":392},{"id":428,"depth":300,"text":429},{"id":438,"depth":300,"text":439},{"id":448,"depth":300,"text":449},"IBM's AES finalist from 1998. Thirty-two rounds on four 32-bit words, a 512-word S-box grown from SHA-1, keys of 128 to 448 bits. UTF-8 text in, hex out.","md",null,{},true,{"title":196,"description":539},"lOao3bw-3kbxxMVtuU85nEy9kPrb5f4eVMhDCCRRss0",[547,549],{"title":192,"path":193,"stem":194,"description":548,"children":-1},"The IBM cipher DES was cut down from, as Arthur Sorkin published it in 1984. Sixteen Feistel rounds, two 4-bit S-boxes, 128-bit blocks and keys. UTF-8 text in, hex out.",{"title":200,"path":201,"stem":202,"description":550,"children":-1},"Anderson, Biham and Knudsen's AES finalist from 1998. Thirty-two rounds of 4-bit S-boxes on 16-byte blocks, keys of 128, 192 or 256 bits. UTF-8 text in, hex out.",1790337935648]