]> git.za3k.com Git - cryptopals.git/commitdiff
Add all set problems
authorZachary Vance <za3k@za3k.com>
Sun, 14 May 2017 09:18:51 +0000 (02:18 -0700)
committerZachary Vance <za3k@za3k.com>
Sun, 14 May 2017 09:18:51 +0000 (02:18 -0700)
72 files changed:
problems/set-1/1.html [moved from problems/set1/1.html with 100% similarity]
problems/set-1/2.html [moved from problems/set1/2.html with 100% similarity]
problems/set-1/3.html [moved from problems/set1/3.html with 100% similarity]
problems/set-1/4.html [moved from problems/set1/4.html with 100% similarity]
problems/set-1/4.txt [moved from problems/set1/4.txt with 100% similarity]
problems/set-1/5.html [moved from problems/set1/5.html with 100% similarity]
problems/set-1/6.html [moved from problems/set1/6.html with 100% similarity]
problems/set-1/6.txt [moved from problems/set1/6.txt with 100% similarity]
problems/set-1/7.html [moved from problems/set1/7.html with 100% similarity]
problems/set-1/7.txt [moved from problems/set1/7.txt with 100% similarity]
problems/set-1/8.html [moved from problems/set1/8.html with 100% similarity]
problems/set-1/8.txt [moved from problems/set1/8.txt with 100% similarity]
problems/set-1/index.html [moved from problems/set1/index.html with 85% similarity]
problems/set-2/10.html [new file with mode: 0644]
problems/set-2/10.txt [new file with mode: 0644]
problems/set-2/11.html [new file with mode: 0644]
problems/set-2/12.html [new file with mode: 0644]
problems/set-2/13.html [new file with mode: 0644]
problems/set-2/14.html [new file with mode: 0644]
problems/set-2/15.html [new file with mode: 0644]
problems/set-2/16.html [new file with mode: 0644]
problems/set-2/9.html [new file with mode: 0644]
problems/set-2/index.html [new file with mode: 0644]
problems/set-3/17.html [new file with mode: 0644]
problems/set-3/18.html [new file with mode: 0644]
problems/set-3/19.html [new file with mode: 0644]
problems/set-3/20.html [new file with mode: 0644]
problems/set-3/20.txt [new file with mode: 0644]
problems/set-3/21.html [new file with mode: 0644]
problems/set-3/22.html [new file with mode: 0644]
problems/set-3/23.html [new file with mode: 0644]
problems/set-3/24.html [new file with mode: 0644]
problems/set-3/3.html [new file with mode: 0644]
problems/set-4/25.html [new file with mode: 0644]
problems/set-4/25.txt [new file with mode: 0644]
problems/set-4/26.html [new file with mode: 0644]
problems/set-4/27.html [new file with mode: 0644]
problems/set-4/28.html [new file with mode: 0644]
problems/set-4/29.html [new file with mode: 0644]
problems/set-4/30.html [new file with mode: 0644]
problems/set-4/31.html [new file with mode: 0644]
problems/set-4/32.html [new file with mode: 0644]
problems/set-4/index.html [new file with mode: 0644]
problems/set-5/33.html [new file with mode: 0644]
problems/set-5/34.html [new file with mode: 0644]
problems/set-5/35.html [new file with mode: 0644]
problems/set-5/36.html [new file with mode: 0644]
problems/set-5/37.html [new file with mode: 0644]
problems/set-5/38.html [new file with mode: 0644]
problems/set-5/39.html [new file with mode: 0644]
problems/set-5/40.html [new file with mode: 0644]
problems/set-5/index.html [new file with mode: 0644]
problems/set-6/41.html [new file with mode: 0644]
problems/set-6/42.html [new file with mode: 0644]
problems/set-6/43.html [new file with mode: 0644]
problems/set-6/44.html [new file with mode: 0644]
problems/set-6/44.txt [new file with mode: 0644]
problems/set-6/45.html [new file with mode: 0644]
problems/set-6/46.html [new file with mode: 0644]
problems/set-6/47.html [new file with mode: 0644]
problems/set-6/48.html [new file with mode: 0644]
problems/set-6/index.html [new file with mode: 0644]
problems/set-7/49.html [new file with mode: 0644]
problems/set-7/50.html [new file with mode: 0644]
problems/set-7/51.html [new file with mode: 0644]
problems/set-7/52.html [new file with mode: 0644]
problems/set-7/53.html [new file with mode: 0644]
problems/set-7/54.html [new file with mode: 0644]
problems/set-7/55.html [new file with mode: 0644]
problems/set-7/56.html [new file with mode: 0644]
problems/set-7/index.html [new file with mode: 0644]
problems/set-8/index.html [new file with mode: 0644]

similarity index 100%
rename from problems/set1/1.html
rename to problems/set-1/1.html
similarity index 100%
rename from problems/set1/2.html
rename to problems/set-1/2.html
similarity index 100%
rename from problems/set1/3.html
rename to problems/set-1/3.html
similarity index 100%
rename from problems/set1/4.html
rename to problems/set-1/4.html
similarity index 100%
rename from problems/set1/4.txt
rename to problems/set-1/4.txt
similarity index 100%
rename from problems/set1/5.html
rename to problems/set-1/5.html
similarity index 100%
rename from problems/set1/6.html
rename to problems/set-1/6.html
similarity index 100%
rename from problems/set1/6.txt
rename to problems/set-1/6.txt
similarity index 100%
rename from problems/set1/7.html
rename to problems/set-1/7.html
similarity index 100%
rename from problems/set1/7.txt
rename to problems/set-1/7.txt
similarity index 100%
rename from problems/set1/8.html
rename to problems/set-1/8.html
similarity index 100%
rename from problems/set1/8.txt
rename to problems/set-1/8.txt
similarity index 85%
rename from problems/set1/index.html
rename to problems/set-1/index.html
index 90a982d63b1af42046ca63fa19560bbd7c3842e9..602b21ae77cf8ada539d16f12eed23d8f95b5598 100644 (file)
 </p>
 <ol>
   <li>
-    <a href='/sets/1/challenges/1'>Convert hex to base64</a>
+    <a href='1.html'>Convert hex to base64</a>
   </li>
   <li>
-    <a href='/sets/1/challenges/2'>Fixed XOR</a>
+    <a href='2.html'>Fixed XOR</a>
   </li>
   <li>
-    <a href='/sets/1/challenges/3'>Single-byte XOR cipher</a>
+    <a href='3.html'>Single-byte XOR cipher</a>
   </li>
   <li>
-    <a href='/sets/1/challenges/4'>Detect single-character XOR</a>
+    <a href='4.html'>Detect single-character XOR</a>
   </li>
   <li>
-    <a href='/sets/1/challenges/5'>Implement repeating-key XOR</a>
+    <a href='5.html'>Implement repeating-key XOR</a>
   </li>
   <li>
-    <a href='/sets/1/challenges/6'>Break repeating-key XOR</a>
+    <a href='6.html'>Break repeating-key XOR</a>
   </li>
   <li>
-    <a href='/sets/1/challenges/7'>AES in ECB mode</a>
+    <a href='7.html'>AES in ECB mode</a>
   </li>
   <li>
-    <a href='/sets/1/challenges/8'>Detect AES in ECB mode</a>
+    <a href='8.html'>Detect AES in ECB mode</a>
   </li>
 </ol>
 
@@ -95,4 +95,4 @@
       var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
     })();*/
   </script>
-</html>
\ No newline at end of file
+</html>
diff --git a/problems/set-2/10.html b/problems/set-2/10.html
new file mode 100644 (file)
index 0000000..9b646fc
--- /dev/null
@@ -0,0 +1,98 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 10 Set 2 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/2'>Set 2</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/2/challenges/10'>Challenge 10</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Implement CBC mode</h3>
+          <p>
+  CBC mode is a block cipher mode that allows us to encrypt irregularly-sized
+  messages, despite the fact that a block cipher natively only transforms
+  individual blocks.
+</p>
+<p>
+  In CBC mode, each ciphertext block is added to the next plaintext
+  block before the next call to the cipher core.
+</p>
+<p>
+  The first plaintext block, which has no associated previous ciphertext
+  block, is added to a "fake 0th ciphertext block" called the <i>initialization vector</i>, or IV.
+</p>
+<p>
+  Implement CBC mode by hand by taking the ECB function you  wrote earlier,
+  making it <i>encrypt</i> instead of <i>decrypt</i> (verify this by decrypting
+  whatever you encrypt to test), and using your XOR function from
+  the previous exercise to combine them.
+</p>
+<p>
+  <a href='/static/challenge-data/10.txt'>The file here</a>
+  is intelligible (somewhat) when CBC decrypted against "YELLOW
+  SUBMARINE" with an IV of all ASCII 0 (\x00\x00\x00 &c)
+</p>
+<div class='panel panel-danger'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Don't cheat.</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      Do not use OpenSSL's CBC code to do CBC mode, even to verify your
+      results. What's the point of even doing this stuff if you aren't going
+      to learn from it?
+    </p>
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-2/10.txt b/problems/set-2/10.txt
new file mode 100644 (file)
index 0000000..f0802a5
--- /dev/null
@@ -0,0 +1,64 @@
+CRIwqt4+szDbqkNY+I0qbNXPg1XLaCM5etQ5Bt9DRFV/xIN2k8Go7jtArLIy
+P605b071DL8C+FPYSHOXPkMMMFPAKm+Nsu0nCBMQVt9mlluHbVE/yl6VaBCj
+NuOGvHZ9WYvt51uR/lklZZ0ObqD5UaC1rupZwCEK4pIWf6JQ4pTyPjyiPtKX
+g54FNQvbVIHeotUG2kHEvHGS/w2Tt4E42xEwVfi29J3yp0O/TcL7aoRZIcJj
+MV4qxY/uvZLGsjo1/IyhtQp3vY0nSzJjGgaLYXpvRn8TaAcEtH3cqZenBoox
+BH3MxNjD/TVf3NastEWGnqeGp+0D9bQx/3L0+xTf+k2VjBDrV9HPXNELRgPN
+0MlNo79p2gEwWjfTbx2KbF6htgsbGgCMZ6/iCshy3R8/abxkl8eK/VfCGfA6
+bQQkqs91bgsT0RgxXSWzjjvh4eXTSl8xYoMDCGa2opN/b6Q2MdfvW7rEvp5m
+wJOfQFDtkv4M5cFEO3sjmU9MReRnCpvalG3ark0XC589rm+42jC4/oFWUdwv
+kzGkSeoabAJdEJCifhvtGosYgvQDARUoNTQAO1+CbnwdKnA/WbQ59S9MU61Q
+KcYSuk+jK5nAMDot2dPmvxZIeqbB6ax1IH0cdVx7qB/Z2FlJ/U927xGmC/RU
+FwoXQDRqL05L22wEiF85HKx2XRVB0F7keglwX/kl4gga5rk3YrZ7VbInPpxU
+zgEaE4+BDoEqbv/rYMuaeOuBIkVchmzXwlpPORwbN0/RUL89xwOJKCQQZM8B
+1YsYOqeL3HGxKfpFo7kmArXSRKRHToXuBgDq07KS/jxaS1a1Paz/tvYHjLxw
+Y0Ot3kS+cnBeq/FGSNL/fFV3J2a8eVvydsKat3XZS3WKcNNjY2ZEY1rHgcGL
+5bhVHs67bxb/IGQleyY+EwLuv5eUwS3wljJkGcWeFhlqxNXQ6NDTzRNlBS0W
+4CkNiDBMegCcOlPKC2ZLGw2ejgr2utoNfmRtehr+3LAhLMVjLyPSRQ/zDhHj
+Xu+Kmt4elmTmqLgAUskiOiLYpr0zI7Pb4xsEkcxRFX9rKy5WV7NhJ1lR7BKy
+alO94jWIL4kJmh4GoUEhO+vDCNtW49PEgQkundV8vmzxKarUHZ0xr4feL1ZJ
+THinyUs/KUAJAZSAQ1Zx/S4dNj1HuchZzDDm/nE/Y3DeDhhNUwpggmesLDxF
+tqJJ/BRn8cgwM6/SMFDWUnhkX/t8qJrHphcxBjAmIdIWxDi2d78LA6xhEPUw
+NdPPhUrJcu5hvhDVXcceZLa+rJEmn4aftHm6/Q06WH7dq4RaaJePP6WHvQDp
+zZJOIMSEisApfh3QvHqdbiybZdyErz+yXjPXlKWG90kOz6fx+GbvGcHqibb/
+HUfcDosYA7lY4xY17llY5sibvWM91ohFN5jyDlHtngi7nWQgFcDNfSh77TDT
+zltUp9NnSJSgNOOwoSSNWadm6+AgbXfQNX6oJFaU4LQiAsRNa7vX/9jRfi65
+5uvujM4ob199CZVxEls10UI9pIemAQQ8z/3rgQ3eyL+fViyztUPg/2IvxOHv
+eexE4owH4Fo/bRlhZK0mYIamVxsRADBuBlGqx1b0OuF4AoZZgUM4d8v3iyUu
+feh0QQqOkvJK/svkYHn3mf4JlUb2MTgtRQNYdZKDRgF3Q0IJaZuMyPWFsSNT
+YauWjMVqnj0AEDHh6QUMF8bXLM0jGwANP+r4yPdKJNsoZMpuVoUBJYWnDTV+
+8Ive6ZgBi4EEbPbMLXuqDMpDi4XcLE0UUPJ8VnmO5fAHMQkA64esY2QqldZ+
+5gEhjigueZjEf0917/X53ZYWJIRiICnmYPoM0GSYJRE0k3ycdlzZzljIGk+P
+Q7WgeJhthisEBDbgTuppqKNXLbNZZG/VaTdbpW1ylBv0eqamFOmyrTyh1APS
+Gn37comTI3fmN6/wmVnmV4/FblvVwLuDvGgSCGPOF8i6FVfKvdESs+yr+1AE
+DJXfp6h0eNEUsM3gXaJCknGhnt3awtg1fSUiwpYfDKZxwpPOYUuer8Wi+VCD
+sWsUpkMxhhRqOBKaQaBDQG+kVJu6aPFlnSPQQTi1hxLwi0l0Rr38xkr+lHU7
+ix8LeJVgNsQdtxbovE3i7z3ZcTFY7uJkI9j9E0muDN9x8y/YN25rm6zULYaO
+jUoP/7FQZsSgxPIUvUiXkEq+FU2h0FqAC7H18cr3Za5x5dpw5nwawMArKoqG
+9qlhqc34lXV0ZYwULu58EImFIS8+kITFuu7jOeSXbBgbhx8zGPqavRXeiu0t
+bJd0gWs+YgMLzXtQIbQuVZENMxJSZB4aw5lPA4vr1fFBsiU4unjOEo/XAgwr
+Tc0w0UndJFPvXRr3Ir5rFoIEOdRo+6os5DSlk82SBnUjwbje7BWsxWMkVhYO
+6bOGUm4VxcKWXu2jU66TxQVIHy7WHktMjioVlWJdZC5Hq0g1LHg1nWSmjPY2
+c/odZqN+dBBC51dCt4oi5UKmKtU5gjZsRSTcTlfhGUd6DY4Tp3CZhHjQRH4l
+Zhg0bF/ooPTxIjLKK4r0+yR0lyRjqIYEY27HJMhZDXFDxBQQ1UkUIhAvXacD
+WB2pb3YyeSQjt8j/WSbQY6TzdLq8SreZiuMWcXmQk4EH3xu8bPsHlcvRI+B3
+gxKeLnwrVJqVLkf3m2cSGnWQhSLGbnAtgQPA6z7u3gGbBmRtP0KnAHWSK7q6
+onMoYTH+b5iFjCiVRqzUBVzRRKjAL4rcL2nYeV6Ec3PlnboRzJwZIjD6i7WC
+dcxERr4WVOjOBX4fhhKUiVvlmlcu8CkIiSnZENHZCpI41ypoVqVarHpqh2aP
+/PS624yfxx2N3C2ci7VIuH3DcSYcaTXEKhz/PRLJXkRgVlWxn7QuaJJzDvpB
+oFndoRu1+XCsup/AtkLidsSXMFTo/2Ka739+BgYDuRt1mE9EyuYyCMoxO/27
+sn1QWMMd1jtcv8Ze42MaM4y/PhAMp2RfCoVZALUS2K7XrOLl3s9LDFOdSrfD
+8GeMciBbfLGoXDvv5Oqq0S/OvjdID94UMcadpnSNsist/kcJJV0wtRGfALG2
++UKYzEj/2TOiN75UlRvA5XgwfqajOvmIIXybbdhxpjnSB04X3iY82TNSYTmL
+LAzZlX2vmV9IKRRimZ2SpzNpvLKeB8lDhIyGzGXdiynQjFMNcVjZlmWHsH7e
+ItAKWmCwNkeuAfFwir4TTGrgG1pMje7XA7kMT821cYbLSiPAwtlC0wm77F0T
+a7jdMrLjMO29+1958CEzWPdzdfqKzlfBzsba0+dS6mcW/YTHaB4bDyXechZB
+k/35fUg+4geMj6PBTqLNNWXBX93dFC7fNyda+Lt9cVJnlhIi/61fr0KzxOeX
+NKgePKOC3Rz+fWw7Bm58FlYTgRgN63yFWSKl4sMfzihaQq0R8NMQIOjzuMl3
+Ie5ozSa+y9g4z52RRc69l4n4qzf0aErV/BEe7FrzRyWh4PkDj5wy5ECaRbfO
+7rbs1EHlshFvXfGlLdEfP2kKpT9U32NKZ4h+Gr9ymqZ6isb1KfNov1rw0KSq
+YNP+EyWCyLRJ3EcOYdvVwVb+vIiyzxnRdugB3vNzaNljHG5ypEJQaTLphIQn
+lP02xcBpMNJN69bijVtnASN/TLV5ocYvtnWPTBKu3OyOkcflMaHCEUgHPW0f
+mGfld4i9Tu35zrKvTDzfxkJX7+KJ72d/V+ksNKWvwn/wvMOZsa2EEOfdCidm
+oql027IS5XvSHynQtvFmw0HTk9UXt8HdVNTqcdy/jUFmXpXNP2Wvn8PrU2Dh
+kkIzWhQ5Rxd/vnM2QQr9Cxa2J9GXEV3kGDiZV90+PCDSVGY4VgF8y7GedI1h
diff --git a/problems/set-2/11.html b/problems/set-2/11.html
new file mode 100644 (file)
index 0000000..7755882
--- /dev/null
@@ -0,0 +1,94 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 11 Set 2 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/2'>Set 2</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/2/challenges/11'>Challenge 11</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>An ECB/CBC detection oracle</h3>
+          <p>
+  Now that you have ECB and CBC working:
+</p>
+<p>
+  Write a function to generate a random AES key; that's just 16 random
+  bytes.
+</p>
+<p>
+  Write a function that encrypts data under an unknown key --- that is,
+  a function that generates a random key and encrypts under it.
+</p>
+<p>
+  The function should look like:
+</p>
+<pre>encryption_oracle(your-input)
+=> [MEANINGLESS JIBBER JABBER]</pre>
+<p>
+  Under the hood, have the function <i>append</i> 5-10 bytes (count chosen
+  randomly) <i>before</i> the plaintext and 5-10 bytes <i>after</i> the plaintext.
+</p>
+<p>
+  Now, have the function choose to encrypt under ECB 1/2 the time, and
+  under CBC the other half (just use random IVs each time for CBC). Use
+  rand(2) to decide which to use.
+</p>
+<p>
+  Detect the block cipher mode the function is using each time. You should end
+  up with a piece of code that, pointed at a block box that might be encrypting
+  ECB or CBC, tells you which one is happening.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-2/12.html b/problems/set-2/12.html
new file mode 100644 (file)
index 0000000..346f914
--- /dev/null
@@ -0,0 +1,150 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 12 Set 2 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/2'>Set 2</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/2/challenges/12'>Challenge 12</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Byte-at-a-time ECB decryption (Simple)</h3>
+          <p>
+  Copy your oracle function to a new function that encrypts buffers
+  under ECB mode using a <i>consistent</i> but <i>unknown</i> key (for instance,
+  assign a single random key, once, to a global variable).
+</p>
+<p>
+  Now take that same function and have it append to the plaintext,
+  BEFORE ENCRYPTING, the following string:
+</p>
+<pre>Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg
+aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq
+dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg
+YnkK</pre>
+<div class='panel panel-danger'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Spoiler alert.</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      Do not decode this string now. Don't do it.
+    </p>
+  </div>
+</div>
+<p>
+  Base64 decode the string before appending it. <i>Do not base64 decode the
+  string by hand; make your code do it</i>. The point is that you don't know
+  its contents.
+</p>
+<p>
+  What you have now is a function that produces:
+</p>
+<pre>AES-128-ECB(your-string || unknown-string, random-key)</pre>
+<p>
+  It turns out: you can decrypt "unknown-string" with repeated calls to the oracle
+  function!
+</p>
+<p>
+  Here's roughly how:
+</p>
+<style>
+  li { padding-top: 1em; }
+</style>
+<ol>
+  <li>
+    Feed identical bytes of your-string to the function 1 at a time ---
+    start with 1 byte ("A"), then "AA", then "AAA" and so on. Discover the
+    block size of the cipher. You know it, but do this step anyway.
+  </li>
+  <li>
+    Detect that the function is using ECB. You already know, but do
+    this step anyways.
+  </li>
+  <li>
+    Knowing the block size, craft an input block that is exactly 1 byte
+    short (for instance, if the block size is 8 bytes, make
+    "AAAAAAA"). Think about what the oracle function is going to put in
+    that last byte position.
+  </li>
+  <li>
+    Make a dictionary of every possible last byte by feeding different
+    strings to the oracle; for instance, "AAAAAAAA", "AAAAAAAB",
+    "AAAAAAAC", remembering the first block of each invocation.
+  </li>
+  <li>
+    Match the output of the one-byte-short input to one of the entries
+    in your dictionary. You've now discovered the first byte of
+    unknown-string.
+  </li>
+  <li>
+    Repeat for the next byte.
+  </li>
+</ol>
+<div class='panel panel-info'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Congratulations.</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      This is the first challenge we've given you whose solution will break real crypto.
+      Lots of people know that when you encrypt something in ECB mode, you can see penguins
+      through it. Not so many of them can <i>decrypt the contents of those ciphertexts</i>,
+      and now you can. If our experience is any guideline, this attack will get you code
+      execution in security tests about once a year.
+    </p>
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-2/13.html b/problems/set-2/13.html
new file mode 100644 (file)
index 0000000..b2d9983
--- /dev/null
@@ -0,0 +1,114 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 13 Set 2 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/2'>Set 2</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/2/challenges/13'>Challenge 13</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>ECB cut-and-paste</h3>
+          <p>
+  Write a k=v parsing routine, as if for a structured cookie. The
+  routine should take:
+</p>
+<pre>foo=bar&baz=qux&zap=zazzle</pre>
+<p>
+  ... and produce:
+</p>
+<pre>{
+  foo: 'bar',
+  baz: 'qux',
+  zap: 'zazzle'
+}</pre>
+<p>
+  (you know, the object; I don't care if you convert it to JSON).
+</p>
+<p>
+  Now write a function that encodes a user profile in that format, given
+  an email address. You should have something like:
+</p>
+<pre>profile_for("foo@bar.com")</pre>
+<p>
+  ... and it should produce:
+</p>
+<pre>{
+  email: 'foo@bar.com',
+  uid: 10,
+  role: 'user'
+}</pre>
+<p>
+  ... encoded as:
+</p>
+<pre>email=foo@bar.com&uid=10&role=user</pre>
+<p>
+  Your "profile_for" function should <i>not</i> allow encoding metacharacters
+  (& and =). Eat them, quote them, whatever you want to do, but don't
+  let people set their email address to "foo@bar.com&role=admin".
+</p>
+<p>
+  Now, two more easy functions. Generate a random AES key, then:
+</p>
+<ol type='A'>
+  <li>Encrypt the encoded user profile under the key; "provide" that to the "attacker".</li>
+  <li>Decrypt the encoded user profile and parse it.</li>
+</ol>
+<p>
+  Using only the user input to profile_for() (as an oracle to generate
+  "valid" ciphertexts) and the ciphertexts themselves, make a role=admin
+  profile.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-2/14.html b/problems/set-2/14.html
new file mode 100644 (file)
index 0000000..18112d4
--- /dev/null
@@ -0,0 +1,89 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 14 Set 2 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/2'>Set 2</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/2/challenges/14'>Challenge 14</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Byte-at-a-time ECB decryption (Harder)</h3>
+          <p>
+  Take your oracle function
+  <a href='/sets/2/challenges/12'>from #12.</a>
+  Now generate a random count of
+  random bytes and prepend this string to every plaintext. You are now
+  doing:
+</p>
+<pre>AES-128-ECB(random-prefix || attacker-controlled || target-bytes, random-key)</pre>
+<p>
+  Same goal: decrypt the target-bytes.
+</p>
+<div class='panel panel-warning'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Stop and think for a second.</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      What's harder than challenge #12 about doing this? How would you overcome that obstacle?
+      The hint is: you're using all the tools you already have; no crazy math is required.
+    </p>
+    <p>
+      Think "STIMULUS" and "RESPONSE".
+    </p>
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-2/15.html b/problems/set-2/15.html
new file mode 100644 (file)
index 0000000..c37a2b1
--- /dev/null
@@ -0,0 +1,82 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 15 Set 2 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/2'>Set 2</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/2/challenges/15'>Challenge 15</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>PKCS#7 padding validation</h3>
+          <p>
+  Write a function that takes a plaintext, determines if it has valid
+  PKCS#7 padding, and strips the padding off.
+</p>
+<p>The string:</p>
+<pre>"ICE ICE BABY\x04\x04\x04\x04"</pre>
+<p>... has valid padding, and produces the result "ICE ICE BABY".</p>
+<p>The string:</p>
+<pre>"ICE ICE BABY\x05\x05\x05\x05"</pre>
+<p>... does not have valid padding, nor does:</p>
+<pre>"ICE ICE BABY\x01\x02\x03\x04"</pre>
+<p>
+  If you are writing in a language with exceptions, like Python or Ruby,
+  make your function throw an exception on bad padding.
+</p>
+<p>
+  Crypto nerds know where we're going with this. Bear with us.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-2/16.html b/problems/set-2/16.html
new file mode 100644 (file)
index 0000000..eee5150
--- /dev/null
@@ -0,0 +1,117 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 16 Set 2 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/2'>Set 2</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/2/challenges/16'>Challenge 16</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>CBC bitflipping attacks</h3>
+          <p>
+  Generate a random AES key.
+</p>
+<p>
+  Combine your padding code and CBC code to write two functions.
+</p>
+<p>
+  The first function should take an arbitrary input string, prepend the
+  string:
+</p>
+<pre>"comment1=cooking%20MCs;userdata="</pre>
+<p>.. and append the string:</p>
+<pre>";comment2=%20like%20a%20pound%20of%20bacon"</pre>
+<p>The function should quote out the ";" and "=" characters.</p>
+<p>
+  The function should then pad out the input to the 16-byte AES block
+  length and encrypt it under the random AES key.
+</p>
+<p>
+  The second function should decrypt the string and look for the
+  characters ";admin=true;" (or, equivalently, decrypt, split the string
+  on ";", convert each resulting string into 2-tuples, and look for the
+  "admin" tuple).
+</p>
+<p>Return true or false based on whether the string exists.</p>
+<p>
+  If you've written the first function properly, it should <i>not</i> be
+  possible to provide user input to it that will generate the string the
+  second function is looking for. We'll have to break the crypto to do that.
+</p>
+<p>
+  Instead, modify the ciphertext (without knowledge of the AES key) to
+  accomplish this.
+</p>
+<p>
+  You're relying on the fact that in CBC mode, a 1-bit error in a
+  ciphertext block:
+</p>
+<ul>
+  <li>Completely scrambles the block the error occurs in</li>
+  <li>Produces the identical 1-bit error(/edit) in the next ciphertext block.</li>
+</ul>
+<div class='panel panel-warning'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Stop and think for a second.</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      Before you implement this attack, answer this question: why does CBC
+      mode have this property?
+    </p>
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-2/9.html b/problems/set-2/9.html
new file mode 100644 (file)
index 0000000..0a6ee66
--- /dev/null
@@ -0,0 +1,83 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 9 Set 2 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/2'>Set 2</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/2/challenges/9'>Challenge 9</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Implement PKCS#7 padding</h3>
+          <p>
+  A block cipher transforms a fixed-sized block (usually 8 or 16 bytes) of plaintext
+  into ciphertext. But we almost never want to transform a single block; we encrypt
+  irregularly-sized messages.
+</p>
+<p>
+  One way we account for irregularly-sized messages is by padding, creating a plaintext
+  that is an even multiple of the blocksize. The most popular padding scheme is called
+  PKCS#7.
+</p>
+<p>
+  So: pad any block to a specific block length, by appending the number of
+  bytes of padding to the end of the block. For instance,
+</p>
+<pre>"YELLOW SUBMARINE"</pre>
+<p>
+  ... padded to 20 bytes would be:
+</p>
+<pre>"YELLOW SUBMARINE\x04\x04\x04\x04"</pre>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-2/index.html b/problems/set-2/index.html
new file mode 100644 (file)
index 0000000..60056db
--- /dev/null
@@ -0,0 +1,97 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Set 2 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/'>Set 2</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Crypto Challenge Set 2</h3>
+          <p>
+  This is the first of several sets on <b>block cipher cryptography</b>. This is bread-and-butter crypto,
+  the kind you'll see implemented in most web software that does crypto.
+</p>
+<p>
+  This set is <b>relatively easy</b>. People that clear set 1 tend to clear set 2 somewhat quickly.
+</p>
+<p>
+  Three of the challenges in this set are extremely valuable in breaking real-world crypto; one allows you
+  to decrypt messages encrypted in the default mode of AES, and the other two allow you to rewrite messages
+  encrypted in the most popular modes of AES.
+</p>
+<ol start='9'>
+  <li>
+    <a href='/sets/2/challenges/9'>Implement PKCS#7 padding</a>
+  </li>
+  <li>
+    <a href='/sets/2/challenges/10'>Implement CBC mode</a>
+  </li>
+  <li>
+    <a href='/sets/2/challenges/11'>An ECB/CBC detection oracle</a>
+  </li>
+  <li>
+    <a href='/sets/2/challenges/12'>Byte-at-a-time ECB decryption (Simple)</a>
+  </li>
+  <li>
+    <a href='/sets/2/challenges/13'>ECB cut-and-paste</a>
+  </li>
+  <li>
+    <a href='/sets/2/challenges/14'>Byte-at-a-time ECB decryption (Harder)</a>
+  </li>
+  <li>
+    <a href='/sets/2/challenges/15'>PKCS#7 padding validation</a>
+  </li>
+  <li>
+    <a href='/sets/2/challenges/16'>CBC bitflipping attacks</a>
+  </li>
+</ol>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-3/17.html b/problems/set-3/17.html
new file mode 100644 (file)
index 0000000..f1e8181
--- /dev/null
@@ -0,0 +1,142 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 17 Set 3 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/3'>Set 3</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/3/challenges/17'>Challenge 17</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>The CBC padding oracle</h3>
+          <p>
+  This is the best-known attack on modern block-cipher cryptography.
+</p>
+<p>
+  Combine your padding code and your CBC code to write two functions.
+</p>
+<p>
+  The first function should select at random one of the following 10
+  strings:
+</p>
+<pre>MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=
+MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=
+MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==
+MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==
+MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl
+MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==
+MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==
+MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=
+MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=
+MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93</pre>
+<p>
+  ... generate a random AES key (which it should save for all future
+  encryptions), pad the string out to the 16-byte AES block size and
+  CBC-encrypt it under that key, providing the caller the ciphertext and
+  IV.
+</p>
+<p>
+  The second function should consume the ciphertext produced by the
+  first function, decrypt it, check its padding, and return true or
+  false depending on whether the padding is valid.
+</p>
+<div class='panel panel-warning'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>What you're doing here.</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      This pair of functions approximates AES-CBC encryption as its deployed
+      serverside in web applications; the second function models the
+      server's consumption of an encrypted session token, as if it was a
+      cookie.
+    </p>
+  </div>
+</div>
+<p>
+  It turns out that it's possible to decrypt the ciphertexts provided by
+  the first function.
+</p>
+<p>
+  The decryption here depends on a side-channel leak by the decryption
+  function. The leak is the error message that the padding is valid or not.
+</p>
+<p>
+  You can find 100 web pages on how this attack works, so I won't
+  re-explain it. What I'll say is this:
+</p>
+<p>
+  The fundamental insight behind this attack is that the byte 01h is
+  valid padding, and occur in 1/256 trials of "randomized" plaintexts
+  produced by decrypting a tampered ciphertext.
+</p>
+<p>02h in isolation is <i>not</i> valid padding.</p>
+<p>
+  02h 02h <i>is</i> valid padding, but is much less likely to occur randomly
+  than 01h.
+</p>
+<p>03h 03h 03h is even less likely.</p>
+<p>
+  So you can assume that if you corrupt a decryption AND it had valid
+  padding, you know what that padding byte is.
+</p>
+<p>
+  It is easy to get tripped up on the fact that CBC plaintexts are
+  "padded". <i>Padding oracles have nothing to do with the actual padding
+  on a CBC plaintext.</i> It's an attack that targets a specific bit of code
+  that handles decryption. You can mount a padding oracle on <i>any CBC
+  block</i>, whether it's padded or not.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-3/18.html b/problems/set-3/18.html
new file mode 100644 (file)
index 0000000..8f4ffeb
--- /dev/null
@@ -0,0 +1,122 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 18 Set 3 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/3'>Set 3</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/3/challenges/18'>Challenge 18</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Implement CTR, the stream cipher mode</h3>
+          <p>The string:</p>
+<pre>L77na/nrFsKvynd6HzOoG7GHTLXsTVu9qvY/2syLXzhPweyyMTJULu/6/kXX0KSvoOLSFQ==</pre>
+<p>
+  ... decrypts to something approximating English in CTR mode, which is an
+  AES block cipher mode that turns AES into a stream cipher, with the
+  following parameters:
+</p>
+<pre>      key=YELLOW SUBMARINE
+      nonce=0
+      format=64 bit unsigned little endian nonce,
+             64 bit little endian block count (byte count / 16)</pre>
+<p>CTR mode is very simple.</p>
+<p>
+  Instead of encrypting the plaintext, CTR mode encrypts a running
+  counter, producing a 16 byte block of keystream, which is XOR'd
+  against the plaintext.
+</p>
+<p>
+  For instance, for the first 16 bytes of a message with these
+  parameters:
+</p>
+<pre>keystream = AES("YELLOW SUBMARINE",
+                "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")</pre>
+<p>
+  ... for the next 16 bytes:
+</p>
+<pre>keystream = AES("YELLOW SUBMARINE",
+                "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00")</pre>
+<p>
+  ... and then:
+</p>
+<pre>keystream = AES("YELLOW SUBMARINE",
+                "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00")</pre>
+<p>
+  CTR mode does not require padding; when you run out of plaintext, you
+  just stop XOR'ing keystream and stop generating keystream.
+</p>
+<p>
+  Decryption is identical to encryption. Generate the same keystream,
+  XOR, and recover the plaintext.
+</p>
+<p>
+  Decrypt the string at the top of this function, then use your CTR
+  function to encrypt and decrypt other things.
+</p>
+<div class='panel panel-warning'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>This is the only block cipher mode that matters in good code.</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      Most modern cryptography relies on CTR mode to adapt block ciphers into stream ciphers,
+      because most of what we want to encrypt is better described as a stream than as a sequence
+      of blocks. Daniel Bernstein once quipped to Phil Rogaway that good cryptosystems don't need the
+      "decrypt" transforms. Constructions like CTR are what he was talking about.
+    </p>
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-3/19.html b/problems/set-3/19.html
new file mode 100644 (file)
index 0000000..5e0d525
--- /dev/null
@@ -0,0 +1,144 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 19 Set 3 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/3'>Set 3</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/3/challenges/19'>Challenge 19</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Break fixed-nonce CTR mode using substitutions</h3>
+          <p>
+  Take your CTR encrypt/decrypt function and fix its nonce value to
+  0. Generate a random AES key.
+</p>
+<p>
+  In <i>successive encryptions</i> (<i>not</i> in one big running CTR stream), encrypt
+  each line of the base64 decodes of the following,
+  producing multiple independent ciphertexts:
+</p>
+<pre>SSBoYXZlIG1ldCB0aGVtIGF0IGNsb3NlIG9mIGRheQ==
+Q29taW5nIHdpdGggdml2aWQgZmFjZXM=
+RnJvbSBjb3VudGVyIG9yIGRlc2sgYW1vbmcgZ3JleQ==
+RWlnaHRlZW50aC1jZW50dXJ5IGhvdXNlcy4=
+SSBoYXZlIHBhc3NlZCB3aXRoIGEgbm9kIG9mIHRoZSBoZWFk
+T3IgcG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA==
+T3IgaGF2ZSBsaW5nZXJlZCBhd2hpbGUgYW5kIHNhaWQ=
+UG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA==
+QW5kIHRob3VnaHQgYmVmb3JlIEkgaGFkIGRvbmU=
+T2YgYSBtb2NraW5nIHRhbGUgb3IgYSBnaWJl
+VG8gcGxlYXNlIGEgY29tcGFuaW9u
+QXJvdW5kIHRoZSBmaXJlIGF0IHRoZSBjbHViLA==
+QmVpbmcgY2VydGFpbiB0aGF0IHRoZXkgYW5kIEk=
+QnV0IGxpdmVkIHdoZXJlIG1vdGxleSBpcyB3b3JuOg==
+QWxsIGNoYW5nZWQsIGNoYW5nZWQgdXR0ZXJseTo=
+QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=
+VGhhdCB3b21hbidzIGRheXMgd2VyZSBzcGVudA==
+SW4gaWdub3JhbnQgZ29vZCB3aWxsLA==
+SGVyIG5pZ2h0cyBpbiBhcmd1bWVudA==
+VW50aWwgaGVyIHZvaWNlIGdyZXcgc2hyaWxsLg==
+V2hhdCB2b2ljZSBtb3JlIHN3ZWV0IHRoYW4gaGVycw==
+V2hlbiB5b3VuZyBhbmQgYmVhdXRpZnVsLA==
+U2hlIHJvZGUgdG8gaGFycmllcnM/
+VGhpcyBtYW4gaGFkIGtlcHQgYSBzY2hvb2w=
+QW5kIHJvZGUgb3VyIHdpbmdlZCBob3JzZS4=
+VGhpcyBvdGhlciBoaXMgaGVscGVyIGFuZCBmcmllbmQ=
+V2FzIGNvbWluZyBpbnRvIGhpcyBmb3JjZTs=
+SGUgbWlnaHQgaGF2ZSB3b24gZmFtZSBpbiB0aGUgZW5kLA==
+U28gc2Vuc2l0aXZlIGhpcyBuYXR1cmUgc2VlbWVkLA==
+U28gZGFyaW5nIGFuZCBzd2VldCBoaXMgdGhvdWdodC4=
+VGhpcyBvdGhlciBtYW4gSSBoYWQgZHJlYW1lZA==
+QSBkcnVua2VuLCB2YWluLWdsb3Jpb3VzIGxvdXQu
+SGUgaGFkIGRvbmUgbW9zdCBiaXR0ZXIgd3Jvbmc=
+VG8gc29tZSB3aG8gYXJlIG5lYXIgbXkgaGVhcnQs
+WWV0IEkgbnVtYmVyIGhpbSBpbiB0aGUgc29uZzs=
+SGUsIHRvbywgaGFzIHJlc2lnbmVkIGhpcyBwYXJ0
+SW4gdGhlIGNhc3VhbCBjb21lZHk7
+SGUsIHRvbywgaGFzIGJlZW4gY2hhbmdlZCBpbiBoaXMgdHVybiw=
+VHJhbnNmb3JtZWQgdXR0ZXJseTo=
+QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=</pre>
+<p>(This should produce 40 short CTR-encrypted ciphertexts).</p>
+<p>
+  Because the CTR nonce wasn't randomized for each encryption, each
+  ciphertext has been encrypted against the same keystream. This is very
+  bad.
+</p>
+<p>
+  Understanding that, like most stream ciphers (including RC4, and
+  obviously any block cipher run in CTR mode), the actual "encryption"
+  of a byte of data boils down to a single XOR operation, it should be
+  plain that:
+</p>
+<pre>CIPHERTEXT-BYTE XOR PLAINTEXT-BYTE = KEYSTREAM-BYTE</pre>
+<p>And since the keystream is the same for every ciphertext:</p>
+<pre>CIPHERTEXT-BYTE XOR KEYSTREAM-BYTE = PLAINTEXT-BYTE (ie, "you don't
+say!")</pre>
+<p>
+  Attack this cryptosystem piecemeal: guess letters, use expected
+  English language frequence to validate guesses, catch common English
+  trigrams, and so on.
+</p>
+<div class='panel panel-warning'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Don't overthink it.</h3>
+  </div>
+  <div class='panel-body'>
+    Points for automating this, but part of the
+    reason I'm having you do this is that I think this approach is
+    suboptimal.
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-3/20.html b/problems/set-3/20.html
new file mode 100644 (file)
index 0000000..00db3c3
--- /dev/null
@@ -0,0 +1,87 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 20 Set 3 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/3'>Set 3</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/3/challenges/20'>Challenge 20</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Break fixed-nonce CTR statistically</h3>
+          <p>
+  <a href='/static/challenge-data/20.txt'>In this file</a>
+  find a similar set of Base64'd plaintext. Do with them exactly
+  what you did with the first, but solve the problem differently.
+</p>
+<p>
+  Instead of making spot guesses at to known plaintext, treat the
+  collection of ciphertexts the same way you would repeating-key
+  XOR.
+</p>
+<p>
+  Obviously, CTR encryption appears different from repeated-key XOR,
+  <i>but with a fixed nonce they are effectively the same thing.</i>
+</p>
+<p>
+  To exploit this: take your collection of ciphertexts and truncate
+  them to a common length (the length of the smallest ciphertext will
+  work).
+</p>
+<p>
+  Solve the resulting concatenation of ciphertexts as if for repeating-
+  key XOR, with a key size of the length of the ciphertext you XOR'd.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-3/20.txt b/problems/set-3/20.txt
new file mode 100644 (file)
index 0000000..d601f0b
--- /dev/null
@@ -0,0 +1,60 @@
+SSdtIHJhdGVkICJSIi4uLnRoaXMgaXMgYSB3YXJuaW5nLCB5YSBiZXR0ZXIgdm9pZCAvIFBvZXRzIGFyZSBwYXJhbm9pZCwgREoncyBELXN0cm95ZWQ=
+Q3V6IEkgY2FtZSBiYWNrIHRvIGF0dGFjayBvdGhlcnMgaW4gc3BpdGUtIC8gU3RyaWtlIGxpa2UgbGlnaHRuaW4nLCBJdCdzIHF1aXRlIGZyaWdodGVuaW4nIQ==
+QnV0IGRvbid0IGJlIGFmcmFpZCBpbiB0aGUgZGFyaywgaW4gYSBwYXJrIC8gTm90IGEgc2NyZWFtIG9yIGEgY3J5LCBvciBhIGJhcmssIG1vcmUgbGlrZSBhIHNwYXJrOw==
+WWEgdHJlbWJsZSBsaWtlIGEgYWxjb2hvbGljLCBtdXNjbGVzIHRpZ2h0ZW4gdXAgLyBXaGF0J3MgdGhhdCwgbGlnaHRlbiB1cCEgWW91IHNlZSBhIHNpZ2h0IGJ1dA==
+U3VkZGVubHkgeW91IGZlZWwgbGlrZSB5b3VyIGluIGEgaG9ycm9yIGZsaWNrIC8gWW91IGdyYWIgeW91ciBoZWFydCB0aGVuIHdpc2ggZm9yIHRvbW9ycm93IHF1aWNrIQ==
+TXVzaWMncyB0aGUgY2x1ZSwgd2hlbiBJIGNvbWUgeW91ciB3YXJuZWQgLyBBcG9jYWx5cHNlIE5vdywgd2hlbiBJJ20gZG9uZSwgeWEgZ29uZSE=
+SGF2ZW4ndCB5b3UgZXZlciBoZWFyZCBvZiBhIE1DLW11cmRlcmVyPyAvIFRoaXMgaXMgdGhlIGRlYXRoIHBlbmFsdHksYW5kIEknbSBzZXJ2aW4nIGE=
+RGVhdGggd2lzaCwgc28gY29tZSBvbiwgc3RlcCB0byB0aGlzIC8gSHlzdGVyaWNhbCBpZGVhIGZvciBhIGx5cmljYWwgcHJvZmVzc2lvbmlzdCE=
+RnJpZGF5IHRoZSB0aGlydGVlbnRoLCB3YWxraW5nIGRvd24gRWxtIFN0cmVldCAvIFlvdSBjb21lIGluIG15IHJlYWxtIHlhIGdldCBiZWF0IQ==
+VGhpcyBpcyBvZmYgbGltaXRzLCBzbyB5b3VyIHZpc2lvbnMgYXJlIGJsdXJyeSAvIEFsbCB5YSBzZWUgaXMgdGhlIG1ldGVycyBhdCBhIHZvbHVtZQ==
+VGVycm9yIGluIHRoZSBzdHlsZXMsIG5ldmVyIGVycm9yLWZpbGVzIC8gSW5kZWVkIEknbSBrbm93bi15b3VyIGV4aWxlZCE=
+Rm9yIHRob3NlIHRoYXQgb3Bwb3NlIHRvIGJlIGxldmVsIG9yIG5leHQgdG8gdGhpcyAvIEkgYWluJ3QgYSBkZXZpbCBhbmQgdGhpcyBhaW4ndCB0aGUgRXhvcmNpc3Qh
+V29yc2UgdGhhbiBhIG5pZ2h0bWFyZSwgeW91IGRvbid0IGhhdmUgdG8gc2xlZXAgYSB3aW5rIC8gVGhlIHBhaW4ncyBhIG1pZ3JhaW5lIGV2ZXJ5IHRpbWUgeWEgdGhpbms=
+Rmxhc2hiYWNrcyBpbnRlcmZlcmUsIHlhIHN0YXJ0IHRvIGhlYXI6IC8gVGhlIFItQS1LLUktTSBpbiB5b3VyIGVhcjs=
+VGhlbiB0aGUgYmVhdCBpcyBoeXN0ZXJpY2FsIC8gVGhhdCBtYWtlcyBFcmljIGdvIGdldCBhIGF4IGFuZCBjaG9wcyB0aGUgd2Fjaw==
+U29vbiB0aGUgbHlyaWNhbCBmb3JtYXQgaXMgc3VwZXJpb3IgLyBGYWNlcyBvZiBkZWF0aCByZW1haW4=
+TUMncyBkZWNheWluZywgY3V6IHRoZXkgbmV2ZXIgc3RheWVkIC8gVGhlIHNjZW5lIG9mIGEgY3JpbWUgZXZlcnkgbmlnaHQgYXQgdGhlIHNob3c=
+VGhlIGZpZW5kIG9mIGEgcmh5bWUgb24gdGhlIG1pYyB0aGF0IHlvdSBrbm93IC8gSXQncyBvbmx5IG9uZSBjYXBhYmxlLCBicmVha3MtdGhlIHVuYnJlYWthYmxl
+TWVsb2RpZXMtdW5tYWthYmxlLCBwYXR0ZXJuLXVuZXNjYXBhYmxlIC8gQSBob3JuIGlmIHdhbnQgdGhlIHN0eWxlIEkgcG9zc2Vz
+SSBibGVzcyB0aGUgY2hpbGQsIHRoZSBlYXJ0aCwgdGhlIGdvZHMgYW5kIGJvbWIgdGhlIHJlc3QgLyBGb3IgdGhvc2UgdGhhdCBlbnZ5IGEgTUMgaXQgY2FuIGJl
+SGF6YXJkb3VzIHRvIHlvdXIgaGVhbHRoIHNvIGJlIGZyaWVuZGx5IC8gQSBtYXR0ZXIgb2YgbGlmZSBhbmQgZGVhdGgsIGp1c3QgbGlrZSBhIGV0Y2gtYS1za2V0Y2g=
+U2hha2UgJ3RpbGwgeW91ciBjbGVhciwgbWFrZSBpdCBkaXNhcHBlYXIsIG1ha2UgdGhlIG5leHQgLyBBZnRlciB0aGUgY2VyZW1vbnksIGxldCB0aGUgcmh5bWUgcmVzdCBpbiBwZWFjZQ==
+SWYgbm90LCBteSBzb3VsJ2xsIHJlbGVhc2UhIC8gVGhlIHNjZW5lIGlzIHJlY3JlYXRlZCwgcmVpbmNhcm5hdGVkLCB1cGRhdGVkLCBJJ20gZ2xhZCB5b3UgbWFkZSBpdA==
+Q3V6IHlvdXIgYWJvdXQgdG8gc2VlIGEgZGlzYXN0cm91cyBzaWdodCAvIEEgcGVyZm9ybWFuY2UgbmV2ZXIgYWdhaW4gcGVyZm9ybWVkIG9uIGEgbWljOg==
+THlyaWNzIG9mIGZ1cnkhIEEgZmVhcmlmaWVkIGZyZWVzdHlsZSEgLyBUaGUgIlIiIGlzIGluIHRoZSBob3VzZS10b28gbXVjaCB0ZW5zaW9uIQ==
+TWFrZSBzdXJlIHRoZSBzeXN0ZW0ncyBsb3VkIHdoZW4gSSBtZW50aW9uIC8gUGhyYXNlcyB0aGF0J3MgZmVhcnNvbWU=
+WW91IHdhbnQgdG8gaGVhciBzb21lIHNvdW5kcyB0aGF0IG5vdCBvbmx5IHBvdW5kcyBidXQgcGxlYXNlIHlvdXIgZWFyZHJ1bXM7IC8gSSBzaXQgYmFjayBhbmQgb2JzZXJ2ZSB0aGUgd2hvbGUgc2NlbmVyeQ==
+VGhlbiBub25jaGFsYW50bHkgdGVsbCB5b3Ugd2hhdCBpdCBtZWFuIHRvIG1lIC8gU3RyaWN0bHkgYnVzaW5lc3MgSSdtIHF1aWNrbHkgaW4gdGhpcyBtb29k
+QW5kIEkgZG9uJ3QgY2FyZSBpZiB0aGUgd2hvbGUgY3Jvd2QncyBhIHdpdG5lc3MhIC8gSSdtIGEgdGVhciB5b3UgYXBhcnQgYnV0IEknbSBhIHNwYXJlIHlvdSBhIGhlYXJ0
+UHJvZ3JhbSBpbnRvIHRoZSBzcGVlZCBvZiB0aGUgcmh5bWUsIHByZXBhcmUgdG8gc3RhcnQgLyBSaHl0aG0ncyBvdXQgb2YgdGhlIHJhZGl1cywgaW5zYW5lIGFzIHRoZSBjcmF6aWVzdA==
+TXVzaWNhbCBtYWRuZXNzIE1DIGV2ZXIgbWFkZSwgc2VlIGl0J3MgLyBOb3cgYW4gZW1lcmdlbmN5LCBvcGVuLWhlYXJ0IHN1cmdlcnk=
+T3BlbiB5b3VyIG1pbmQsIHlvdSB3aWxsIGZpbmQgZXZlcnkgd29yZCdsbCBiZSAvIEZ1cmllciB0aGFuIGV2ZXIsIEkgcmVtYWluIHRoZSBmdXJ0dXJl
+QmF0dGxlJ3MgdGVtcHRpbmcuLi53aGF0ZXZlciBzdWl0cyB5YSEgLyBGb3Igd29yZHMgdGhlIHNlbnRlbmNlLCB0aGVyZSdzIG5vIHJlc2VtYmxhbmNl
+WW91IHRoaW5rIHlvdSdyZSBydWZmZXIsIHRoZW4gc3VmZmVyIHRoZSBjb25zZXF1ZW5jZXMhIC8gSSdtIG5ldmVyIGR5aW5nLXRlcnJpZnlpbmcgcmVzdWx0cw==
+SSB3YWtlIHlhIHdpdGggaHVuZHJlZHMgb2YgdGhvdXNhbmRzIG9mIHZvbHRzIC8gTWljLXRvLW1vdXRoIHJlc3VzY2l0YXRpb24sIHJoeXRobSB3aXRoIHJhZGlhdGlvbg==
+Tm92b2NhaW4gZWFzZSB0aGUgcGFpbiBpdCBtaWdodCBzYXZlIGhpbSAvIElmIG5vdCwgRXJpYyBCLidzIHRoZSBqdWRnZSwgdGhlIGNyb3dkJ3MgdGhlIGp1cnk=
+WW8gUmFraW0sIHdoYXQncyB1cD8gLyBZbywgSSdtIGRvaW5nIHRoZSBrbm93bGVkZ2UsIEUuLCBtYW4gSSdtIHRyeWluZyB0byBnZXQgcGFpZCBpbiBmdWxs
+V2VsbCwgY2hlY2sgdGhpcyBvdXQsIHNpbmNlIE5vcmJ5IFdhbHRlcnMgaXMgb3VyIGFnZW5jeSwgcmlnaHQ/IC8gVHJ1ZQ==
+S2FyYSBMZXdpcyBpcyBvdXIgYWdlbnQsIHdvcmQgdXAgLyBaYWtpYSBhbmQgNHRoIGFuZCBCcm9hZHdheSBpcyBvdXIgcmVjb3JkIGNvbXBhbnksIGluZGVlZA==
+T2theSwgc28gd2hvIHdlIHJvbGxpbicgd2l0aCB0aGVuPyBXZSByb2xsaW4nIHdpdGggUnVzaCAvIE9mIFJ1c2h0b3duIE1hbmFnZW1lbnQ=
+Q2hlY2sgdGhpcyBvdXQsIHNpbmNlIHdlIHRhbGtpbmcgb3ZlciAvIFRoaXMgZGVmIGJlYXQgcmlnaHQgaGVyZSB0aGF0IEkgcHV0IHRvZ2V0aGVy
+SSB3YW5uYSBoZWFyIHNvbWUgb2YgdGhlbSBkZWYgcmh5bWVzLCB5b3Uga25vdyB3aGF0IEknbSBzYXlpbic/IC8gQW5kIHRvZ2V0aGVyLCB3ZSBjYW4gZ2V0IHBhaWQgaW4gZnVsbA==
+VGhpbmtpbicgb2YgYSBtYXN0ZXIgcGxhbiAvICdDdXogYWluJ3QgbnV0aGluJyBidXQgc3dlYXQgaW5zaWRlIG15IGhhbmQ=
+U28gSSBkaWcgaW50byBteSBwb2NrZXQsIGFsbCBteSBtb25leSBpcyBzcGVudCAvIFNvIEkgZGlnIGRlZXBlciBidXQgc3RpbGwgY29taW4nIHVwIHdpdGggbGludA==
+U28gSSBzdGFydCBteSBtaXNzaW9uLCBsZWF2ZSBteSByZXNpZGVuY2UgLyBUaGlua2luJyBob3cgY291bGQgSSBnZXQgc29tZSBkZWFkIHByZXNpZGVudHM=
+SSBuZWVkIG1vbmV5LCBJIHVzZWQgdG8gYmUgYSBzdGljay11cCBraWQgLyBTbyBJIHRoaW5rIG9mIGFsbCB0aGUgZGV2aW91cyB0aGluZ3MgSSBkaWQ=
+SSB1c2VkIHRvIHJvbGwgdXAsIHRoaXMgaXMgYSBob2xkIHVwLCBhaW4ndCBudXRoaW4nIGZ1bm55IC8gU3RvcCBzbWlsaW5nLCBiZSBzdGlsbCwgZG9uJ3QgbnV0aGluJyBtb3ZlIGJ1dCB0aGUgbW9uZXk=
+QnV0IG5vdyBJIGxlYXJuZWQgdG8gZWFybiAnY3V6IEknbSByaWdodGVvdXMgLyBJIGZlZWwgZ3JlYXQsIHNvIG1heWJlIEkgbWlnaHQganVzdA==
+U2VhcmNoIGZvciBhIG5pbmUgdG8gZml2ZSwgaWYgSSBzdHJpdmUgLyBUaGVuIG1heWJlIEknbGwgc3RheSBhbGl2ZQ==
+U28gSSB3YWxrIHVwIHRoZSBzdHJlZXQgd2hpc3RsaW4nIHRoaXMgLyBGZWVsaW4nIG91dCBvZiBwbGFjZSAnY3V6LCBtYW4sIGRvIEkgbWlzcw==
+QSBwZW4gYW5kIGEgcGFwZXIsIGEgc3RlcmVvLCBhIHRhcGUgb2YgLyBNZSBhbmQgRXJpYyBCLCBhbmQgYSBuaWNlIGJpZyBwbGF0ZSBvZg==
+RmlzaCwgd2hpY2ggaXMgbXkgZmF2b3JpdGUgZGlzaCAvIEJ1dCB3aXRob3V0IG5vIG1vbmV5IGl0J3Mgc3RpbGwgYSB3aXNo
+J0N1eiBJIGRvbid0IGxpa2UgdG8gZHJlYW0gYWJvdXQgZ2V0dGluJyBwYWlkIC8gU28gSSBkaWcgaW50byB0aGUgYm9va3Mgb2YgdGhlIHJoeW1lcyB0aGF0IEkgbWFkZQ==
+U28gbm93IHRvIHRlc3QgdG8gc2VlIGlmIEkgZ290IHB1bGwgLyBIaXQgdGhlIHN0dWRpbywgJ2N1eiBJJ20gcGFpZCBpbiBmdWxs
+UmFraW0sIGNoZWNrIHRoaXMgb3V0LCB5byAvIFlvdSBnbyB0byB5b3VyIGdpcmwgaG91c2UgYW5kIEknbGwgZ28gdG8gbWluZQ==
+J0NhdXNlIG15IGdpcmwgaXMgZGVmaW5pdGVseSBtYWQgLyAnQ2F1c2UgaXQgdG9vayB1cyB0b28gbG9uZyB0byBkbyB0aGlzIGFsYnVt
+WW8sIEkgaGVhciB3aGF0IHlvdSdyZSBzYXlpbmcgLyBTbyBsZXQncyBqdXN0IHB1bXAgdGhlIG11c2ljIHVw
+QW5kIGNvdW50IG91ciBtb25leSAvIFlvLCB3ZWxsIGNoZWNrIHRoaXMgb3V0LCB5byBFbGk=
+VHVybiBkb3duIHRoZSBiYXNzIGRvd24gLyBBbmQgbGV0IHRoZSBiZWF0IGp1c3Qga2VlcCBvbiByb2NraW4n
+QW5kIHdlIG91dHRhIGhlcmUgLyBZbywgd2hhdCBoYXBwZW5lZCB0byBwZWFjZT8gLyBQZWFjZQ==
diff --git a/problems/set-3/21.html b/problems/set-3/21.html
new file mode 100644 (file)
index 0000000..af76924
--- /dev/null
@@ -0,0 +1,73 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 21 Set 3 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/3'>Set 3</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/3/challenges/21'>Challenge 21</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Implement the MT19937 Mersenne Twister RNG</h3>
+          <p>
+  You can get the psuedocode for this from Wikipedia.
+</p>
+<p>
+  If you're writing
+  in Python, Ruby, or (gah) PHP, your language is probably already
+  giving you MT19937 as "rand()"; <b>don't use rand()</b>. Write the RNG
+  yourself.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-3/22.html b/problems/set-3/22.html
new file mode 100644 (file)
index 0000000..074b6ef
--- /dev/null
@@ -0,0 +1,85 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 22 Set 3 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/3'>Set 3</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/3/challenges/22'>Challenge 22</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Crack an MT19937 seed</h3>
+          <p>
+  Make sure your MT19937 accepts an integer seed value. Test it (verify
+  that you're getting the same sequence of outputs given a seed).
+</p>
+<p>
+  Write a routine that performs the following operation:
+</p>
+<ul>
+  <li>Wait a random number of seconds between, I don't know, 40 and 1000.</li>
+  <li>Seeds the RNG with the current Unix timestamp</li>
+  <li>Waits a random number of seconds again.</li>
+  <li>Returns the first 32 bit output of the RNG.</li>
+</ul>
+<p>
+  You get the idea. Go get coffee while it runs. Or just simulate the
+  passage of time, although you're missing some of the fun of this
+  exercise if you do that.
+</p>
+<p>
+  From the 32 bit RNG output, discover the seed.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-3/23.html b/problems/set-3/23.html
new file mode 100644 (file)
index 0000000..906985b
--- /dev/null
@@ -0,0 +1,108 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 23 Set 3 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/3'>Set 3</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/3/challenges/23'>Challenge 23</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Clone an MT19937 RNG from its output</h3>
+          <p>
+  The internal state of MT19937 consists of 624 32 bit integers.
+</p>
+<p>
+  For each batch of 624 outputs, MT permutes that internal state. By
+  permuting state regularly, MT19937 achieves a period of 2**19937,
+  which is Big.
+</p>
+<p>
+  Each time MT19937 is tapped, an element of its internal state is
+  subjected to a tempering function that diffuses bits through the
+  result.
+</p>
+<p>
+  The tempering function is invertible; you can write an "untemper"
+  function that takes an MT19937 output and transforms it back into the
+  corresponding element of the MT19937 state array.
+</p>
+<p>
+  To invert the temper transform, apply the inverse of each of the
+  operations in the temper transform in reverse order. There are two
+  kinds of operations in the temper transform each applied twice; one is
+  an XOR against a right-shifted value, and the other is an XOR against
+  a left-shifted value AND'd with a magic number. So you'll need code to
+  invert the "right" and the "left" operation.
+</p>
+<p>
+  Once you have "untemper" working, create a new MT19937 generator, tap
+  it for 624 outputs, untemper each of them to recreate the state of the
+  generator, and splice that state into a new instance of the MT19937
+  generator.
+</p>
+<p>
+  The new "spliced" generator should predict the values of the original.
+</p>
+<div class='panel panel-warning'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Stop and think for a second.</h3>
+  </div>
+  <div class='panel-body'>
+    How would you modify MT19937 to make this attack hard? What would
+    happen if you subjected each tempered output to a cryptographic hash?
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-3/24.html b/problems/set-3/24.html
new file mode 100644 (file)
index 0000000..0b4111b
--- /dev/null
@@ -0,0 +1,90 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 24 Set 3 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/3'>Set 3</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/3/challenges/24'>Challenge 24</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Create the MT19937 stream cipher and break it</h3>
+          <p>
+  You can create a trivial stream cipher out of any PRNG; use it to
+  generate a sequence of 8 bit outputs and call those outputs a
+  keystream. XOR each byte of plaintext with each successive byte of
+  keystream.
+</p>
+<p>
+  Write the function that does this for MT19937 using a 16-bit
+  seed. Verify that you can encrypt and decrypt properly. This code
+  should look similar to your CTR code.
+</p>
+<p>
+  Use your function to encrypt a known plaintext (say, 14 consecutive
+  'A' characters) prefixed by a random number of random characters.
+</p>
+<p>
+  From the ciphertext, recover the "key" (the 16 bit seed).
+</p>
+<p>
+  Use the same idea to generate a random "password reset token" using
+  MT19937 seeded from the current time.
+</p>
+<p>
+  Write a function to check if any given password token is actually
+  the product of an MT19937 PRNG seeded with the current time.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-3/3.html b/problems/set-3/3.html
new file mode 100644 (file)
index 0000000..9520518
--- /dev/null
@@ -0,0 +1,97 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Set 3 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/'>Set 3</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Crypto Challenge Set 3</h3>
+          <p>
+  This is the next set of <b>block cipher cryptography</b> challenges (even the randomness stuff here
+  plays into block cipher crypto).
+</p>
+<p>
+  This set is <b>moderately difficult</b>. It includes a famous attack against CBC mode, and a "cloning"
+  attack on a popular RNG that can be annoying to get right.
+</p>
+<p>
+  We've also reached a point in the crypto challenges where all the challenges, with one possible exception,
+  are valuable in breaking real-world crypto.
+</p>
+<ol start='17'>
+  <li>
+    <a href='/sets/3/challenges/17'>The CBC padding oracle</a>
+  </li>
+  <li>
+    <a href='/sets/3/challenges/18'>Implement CTR, the stream cipher mode</a>
+  </li>
+  <li>
+    <a href='/sets/3/challenges/19'>Break fixed-nonce CTR mode using substitutions</a>
+  </li>
+  <li>
+    <a href='/sets/3/challenges/20'>Break fixed-nonce CTR statistically</a>
+  </li>
+  <li>
+    <a href='/sets/3/challenges/21'>Implement the MT19937 Mersenne Twister RNG</a>
+  </li>
+  <li>
+    <a href='/sets/3/challenges/22'>Crack an MT19937 seed</a>
+  </li>
+  <li>
+    <a href='/sets/3/challenges/23'>Clone an MT19937 RNG from its output</a>
+  </li>
+  <li>
+    <a href='/sets/3/challenges/24'>Create the MT19937 stream cipher and break it</a>
+  </li>
+</ol>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-4/25.html b/problems/set-4/25.html
new file mode 100644 (file)
index 0000000..fbccc21
--- /dev/null
@@ -0,0 +1,96 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 25 Set 4 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/4'>Set 4</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/4/challenges/25'>Challenge 25</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Break "random access read/write" AES CTR</h3>
+          <p>
+  Back to CTR. Encrypt the recovered plaintext from
+  <a href='/static/challenge-data/25.txt'>this file</a>
+  (the ECB exercise) under CTR with a random key (for this exercise the
+  key should be unknown to you, but hold on to it).
+</p>
+<p>
+  Now, write the code that allows you to "seek" into the ciphertext,
+  decrypt, and re-encrypt with different plaintext. Expose this as a
+  function, like, <i>"edit(ciphertext, key, offset, newtext)"</i>.
+</p>
+<p>
+  Imagine the "edit" function was exposed to attackers by means of an
+  API call that didn't reveal the key or the original plaintext; the
+  attacker has the ciphertext and controls the offset and "new text".
+</p>
+<p>
+  Recover the original plaintext.
+</p>
+<div class='panel panel-warning'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Food for thought.</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      A folkloric supposed benefit of CTR mode is the ability to easily
+      "seek forward" into the ciphertext; to access byte N of the ciphertext,
+      all you need to be able to do is generate byte N of the keystream.
+      Imagine if you'd relied on that advice to, say, encrypt a disk.
+    </p>
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-4/25.txt b/problems/set-4/25.txt
new file mode 100644 (file)
index 0000000..c02ff8a
--- /dev/null
@@ -0,0 +1,64 @@
+CRIwqt4+szDbqkNY+I0qbDe3LQz0wiw0SuxBQtAM5TDdMbjCMD/venUDW9BL
+PEXODbk6a48oMbAY6DDZsuLbc0uR9cp9hQ0QQGATyyCESq2NSsvhx5zKlLtz
+dsnfK5ED5srKjK7Fz4Q38/ttd+stL/9WnDzlJvAo7WBsjI5YJc2gmAYayNfm
+CW2lhZE/ZLG0CBD2aPw0W417QYb4cAIOW92jYRiJ4PTsBBHDe8o4JwqaUac6
+rqdi833kbyAOV/Y2RMbN0oDb9Rq8uRHvbrqQJaJieaswEtMkgUt3P5Ttgeh7
+J+hE6TR0uHot8WzHyAKNbUWHoi/5zcRCUipvVOYLoBZXlNu4qnwoCZRSBgvC
+wTdz3Cbsp/P2wXB8tiz6l9rL2bLhBt13Qxyhhu0H0+JKj6soSeX5ZD1Rpilp
+9ncR1tHW8+uurQKyXN4xKeGjaKLOejr2xDIw+aWF7GszU4qJhXBnXTIUUNUf
+RlwEpS6FZcsMzemQF30ezSJHfpW7DVHzwiLyeiTJRKoVUwo43PXupnJXDmUy
+sCa2nQz/iEwyor6kPekLv1csm1Pa2LZmbA9Ujzz8zb/gFXtQqBAN4zA8/wt0
+VfoOsEZwcsaLOWUPtF/Ry3VhlKwXE7gGH/bbShAIKQqMqqUkEucZ3HPHAVp7
+ZCn3Ox6+c5QJ3Uv8V7L7SprofPFN6F+kfDM4zAc59do5twgDoClCbxxG0L19
+TBGHiYP3CygeY1HLMrX6KqypJfFJW5O9wNIF0qfOC2lWFgwayOwq41xdFSCW
+0/EBSc7cJw3N06WThrW5LimAOt5L9c7Ik4YIxu0K9JZwAxfcU4ShYu6euYmW
+LP98+qvRnIrXkePugS9TSOJOHzKUoOcb1/KYd9NZFHEcp58Df6rXFiz9DSq8
+0rR5Kfs+M+Vuq5Z6zY98/SP0A6URIr9NFu+Cs9/gf+q4TRwsOzRMjMQzJL8f
+7TXPEHH2+qEcpDKz/5pE0cvrgHr63XKu4XbzLCOBz0DoFAw3vkuxGwJq4Cpx
+kt+eCtxSKUzNtXMn/mbPqPl4NZNJ8yzMqTFSODS4bYTBaN/uQYcOAF3NBYFd
+5x9TzIAoW6ai13a8h/s9i5FlVRJDe2cetQhArrIVBquF0L0mUXMWNPFKkaQE
+BsxpMCYh7pp7YlyCNode12k5jY1/lc8jQLQJ+EJHdCdM5t3emRzkPgND4a7O
+NhoIkUUS2R1oEV1toDj9iDzGVFwOvWyt4GzA9XdxT333JU/n8m+N6hs23MBc
+Z086kp9rJGVxZ5f80jRz3ZcjU6zWjR9ucRyjbsuVn1t4EJEm6A7KaHm13m0v
+wN/O4KYTiiY3aO3siayjNrrNBpn1OeLv9UUneLSCdxcUqjRvOrdA5NYv25Hb
+4wkFCIhC/Y2ze/kNyis6FrXtStcjKC1w9Kg8O25VXB1Fmpu+4nzpbNdJ9LXa
+hF7wjOPXN6dixVKpzwTYjEFDSMaMhaTOTCaqJig97624wv79URbCgsyzwaC7
+YXRtbTstbFuEFBee3uW7B3xXw72mymM2BS2uPQ5NIwmacbhta8aCRQEGqIZ0
+78YrrOlZIjar3lbTCo5o6nbbDq9bvilirWG/SgWINuc3pWl5CscRcgQQNp7o
+LBgrSkQkv9AjZYcvisnr89TxjoxBO0Y93jgp4T14LnVwWQVx3l3d6S1wlsci
+dVeaM24E/JtS8k9XAvgSoKCjyiqsawBMzScXCIRCk6nqX8ZaJU3rZ0LeOMTU
+w6MC4dC+aY9SrCvNQub19mBdtJUwOBOqGdfd5IoqQkaL6DfOkmpnsCs5PuLb
+GZBVhah5L87IY7r6TB1V7KboXH8PZIYc1zlemMZGU0o7+etxZWHgpdeX6JbJ
+Is3ilAzYqw/Hz65no7eUxcDg1aOaxemuPqnYRGhW6PvjZbwAtfQPlofhB0jT
+Ht5bRlzF17rn9q/6wzlc1ssp2xmeFzXoxffpELABV6+yj3gfQ/bxIB9NWjdZ
+K08RX9rjm9CcBlRQeTZrD67SYQWqRpT5t7zcVDnx1s7ZffLBWm/vXLfPzMaQ
+YEJ4EfoduSutjshXvR+VQRPs2TWcF7OsaE4csedKUGFuo9DYfFIHFDNg+1Py
+rlWJ0J/X0PduAuCZ+uQSsM/ex/vfXp6Z39ngq4exUXoPtAIqafrDMd8SuAty
+EZhyY9V9Lp2qNQDbl6JI39bDz+6pDmjJ2jlnpMCezRK89cG11IqiUWvIPxHj
+oiT1guH1uk4sQ2Pc1J4zjJNsZgoJDcPBbfss4kAqUJvQyFbzWshhtVeAv3dm
+gwUENIhNK/erjpgw2BIRayzYw001jAIF5c7rYg38o6x3YdAtU3d3QpuwG5xD
+fODxzfL3yEKQr48C/KqxI87uGwyg6H5gc2AcLU9JYt5QoDFoC7PFxcE3RVqc
+7/Um9Js9X9UyriEjftWt86/tEyG7F9tWGxGNEZo3MOydwX/7jtwoxQE5ybFj
+WndqLp8DV3naLQsh/Fz8JnTYHvOR72vuiw/x5D5PFuXV0aSVvmw5Wnb09q/B
+owS14WzoHH6ekaWbh78xlypn/L/M+nIIEX1Ol3TaVOqIxvXZ2sjm86xRz0Ed
+oHFfupSekdBULCqptxpFpBshZFvauUH8Ez7wA7wjL65GVlZ0f74U7MJVu9Sw
+sZdgsLmnsQvr5n2ojNNBEv+qKG2wpUYTmWRaRc5EClUNfhzh8iDdHIsl6edO
+ewORRrNiBay1NCzlfz1cj6VlYYQUM9bDEyqrwO400XQNpoFOxo4fxUdd+AHm
+CBhHbyCR81/C6LQTG2JQBvjykG4pmoqnYPxDyeiCEG+JFHmP1IL+jggdjWhL
+WQatslrWxuESEl3PEsrAkMF7gt0dBLgnWsc1cmzntG1rlXVi/Hs2TAU3RxEm
+MSWDFubSivLWSqZj/XfGWwVpP6fsnsfxpY3d3h/fTxDu7U8GddaFRQhJ+0ZO
+dx6nRJUW3u6xnhH3mYVRk88EMtpEpKrSIWfXphgDUPZ0f4agRzehkn9vtzCm
+NjFnQb0/shnqTh4Mo/8oommbsBTUKPYS7/1oQCi12QABjJDt+LyUan+4iwvC
+i0k0IUIHvk21381vC0ixYDZxzY64+xx/RNID+iplgzq9PDZgjc8L7jMg+2+m
+rxPS56e71m5E2zufZ4d+nFjIg+dHD/ShNPzVpXizRVUERztLuak8Asah3/yv
+wOrH1mKEMMGC1/6qfvZUgFLJH5V0Ep0n2K/Fbs0VljENIN8cjkCKdG8aBnef
+EhITdV7CVjXcivQ6efkbOQCfkfcwWpaBFC8tD/zebXFE+JshW16D4EWXMnSm
+/9HcGwHvtlAj04rwrZ5tRvAgf1IR83kqqiTvqfENcj7ddCFwtNZrQK7EJhgB
+5Tr1tBFcb9InPRtS3KYteYHl3HWR9t8E2YGE8IGrS1sQibxaK/C0kKbqIrKp
+npwtoOLsZPNbPw6K2jpko9NeZAx7PYFmamR4D50KtzgELQcaEsi5aCztMg7f
+p1mK6ijyMKIRKwNKIYHagRRVLNgQLg/WTKzGVbWwq6kQaQyArwQCUXo4uRty
+zGMaKbTG4dns1OFB1g7NCiPb6s1lv0/lHFAF6HwoYV/FPSL/pirxyDSBb/FR
+RA3PIfmvGfMUGFVWlyS7+O73l5oIJHxuaJrR4EenzAu4Avpa5d+VuiYbM10a
+LaVegVPvFn4pCP4U/Nbbw4OTCFX2HKmWEiVBB0O3J9xwXWpxN1Vr5CDi75Fq
+NhxYCjgSJzWOUD34Y1dAfcj57VINmQVEWyc8Tch8vg9MnHGCOfOjRqp0VGyA
+S15AVD2QS1V6fhRimJSVyT6QuGb8tKRsl2N+a2Xze36vgMhw7XK7zh//jC2H
diff --git a/problems/set-4/26.html b/problems/set-4/26.html
new file mode 100644 (file)
index 0000000..bc0f096
--- /dev/null
@@ -0,0 +1,73 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 26 Set 4 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/4'>Set 4</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/4/challenges/26'>Challenge 26</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>CTR bitflipping</h3>
+          <p>
+  There are people in the world that believe that CTR resists
+  bit flipping attacks of the kind to which CBC mode is susceptible.
+</p>
+<p>
+  Re-implement
+  <a href='/sets/2/challenges/16'>the CBC bitflipping exercise from earlier</a>
+  to use CTR mode instead of CBC mode. Inject an "admin=true" token.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-4/27.html b/problems/set-4/27.html
new file mode 100644 (file)
index 0000000..60b1eb4
--- /dev/null
@@ -0,0 +1,105 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 27 Set 4 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/4'>Set 4</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/4/challenges/27'>Challenge 27</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Recover the key from CBC with IV=Key</h3>
+          <p>
+  Take your code from
+  <a href='/sets/2/challenges/16'>the CBC exercise</a>
+  and modify it so that it
+  repurposes the key for CBC encryption as the IV.
+</p>
+<p>
+  Applications
+  sometimes use the key as an IV on the auspices that both the sender
+  and the receiver have to know the key already, and can save some space
+  by using it as both a key and an IV.
+</p>
+<p>
+  Using the key as an IV is insecure; an attacker that can modify
+  ciphertext in flight can get the receiver to decrypt a value that will
+  reveal the key.
+</p>
+<p>
+  The CBC code from exercise 16 encrypts a URL string. Verify each byte
+  of the plaintext for ASCII compliance (ie, look for high-ASCII
+  values). Noncompliant messages should raise an exception or return an
+  error that includes the decrypted plaintext (this happens all the time
+  in real systems, for what it's worth).
+</p>
+<p>
+  Use your code to encrypt a message that is at least 3 blocks long:
+</p>
+<pre>AES-CBC(P_1, P_2, P_3) -> C_1, C_2, C_3</pre>
+<p>
+  Modify the message (you are now the attacker):
+</p>
+<pre>C_1, C_2, C_3 -> C_1, 0, C_1</pre>
+<p>
+  Decrypt the message (you are now the receiver) and raise the
+  appropriate error if high-ASCII is found.
+</p>
+<p>
+  As the attacker, recovering the plaintext from the error, extract the
+  key:
+</p>
+<pre>P'_1 XOR P'_3</pre>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-4/28.html b/problems/set-4/28.html
new file mode 100644 (file)
index 0000000..439a6c2
--- /dev/null
@@ -0,0 +1,88 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 28 Set 4 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/4'>Set 4</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/4/challenges/28'>Challenge 28</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Implement a SHA-1 keyed MAC</h3>
+          <p>
+  Find a SHA-1 implementation in the language you code in.
+</p>
+<div class='panel panel-warning'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Don't cheat. It won't work.</h3>
+  </div>
+  <div class='panel-body'>
+    Do not use
+    the SHA-1 implementation your language already provides (for instance,
+    don't use the "Digest" library in Ruby, or call OpenSSL; in Ruby,
+    you'd want a pure-Ruby SHA-1).
+  </div>
+</div>
+<p>
+  Write a function to authenticate a message under a secret key by using
+  a secret-prefix MAC, which is simply:
+</p>
+<pre>SHA1(key || message)</pre>
+<p>
+  Verify that you cannot tamper with the message without breaking the
+  MAC you've produced, and that you can't produce a new MAC without
+  knowing the secret key.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-4/29.html b/problems/set-4/29.html
new file mode 100644 (file)
index 0000000..3d9d375
--- /dev/null
@@ -0,0 +1,132 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 29 Set 4 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/4'>Set 4</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/4/challenges/29'>Challenge 29</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Break a SHA-1 keyed MAC using length extension</h3>
+          <p>
+  Secret-prefix SHA-1 MACs are trivially breakable.
+</p>
+<p>
+  The attack on secret-prefix SHA1 relies on the fact that you can take
+  the ouput of SHA-1 and use it as a new starting point for SHA-1, thus
+  taking an arbitrary SHA-1 hash and "feeding it more data".
+</p>
+<p>
+  Since the key precedes the data in secret-prefix, any additional data
+  you feed the SHA-1 hash in this fashion will appear to have been
+  hashed with the secret key.
+</p>
+<p>
+  To carry out the attack, you'll need to account for the fact that
+  SHA-1 is "padded" with the bit-length of the message; your forged
+  message will need to include that padding. We call this "glue
+  padding". The final message you actually forge will be:
+</p>
+<pre>SHA1(key || original-message || glue-padding || new-message)</pre>
+<p>
+  (where the final padding on the whole constructed message is implied)
+</p>
+<p>
+  Note that to generate the glue padding, you'll need to know the
+  original bit length of the message; the message itself is known to the
+  attacker, but the secret key isn't, so you'll need to guess at it.
+</p>
+<p>
+  This sounds more complicated than it is in practice.
+</p>
+<p>
+  To implement the attack, first write the function that computes the MD
+  padding of an arbitrary message and verify that you're generating the
+  same padding that your SHA-1 implementation is using. This should take
+  you 5-10 minutes.
+</p>
+<p>
+  Now, take the SHA-1 secret-prefix MAC of the message you want to forge
+  --- this is just a SHA-1 hash --- and break it into 32 bit SHA-1
+  registers (SHA-1 calls them "a", "b", "c", &c).
+</p>
+<p>
+  Modify your SHA-1 implementation so that callers can pass in new
+  values for "a", "b", "c" &c (they normally start at magic
+  numbers). With the registers "fixated", hash the additional data you
+  want to forge.
+</p>
+<p>
+  Using this attack, generate a secret-prefix MAC under a secret key
+  (choose a random word from /usr/share/dict/words or something) of the
+  string:
+</p>
+<pre>"comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon"</pre>
+<p>
+  Forge a variant of this message that ends with ";admin=true".
+</p>
+<div class='panel panel-info'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>This is a very useful attack.</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      For instance: Thai Duong and Juliano Rizzo, who got to this attack before we did, used it to break
+      the Flickr API.
+    </p>
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-4/30.html b/problems/set-4/30.html
new file mode 100644 (file)
index 0000000..b946707
--- /dev/null
@@ -0,0 +1,82 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 30 Set 4 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/4'>Set 4</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/4/challenges/30'>Challenge 30</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Break an MD4 keyed MAC using length extension</h3>
+          <p>
+  Second verse, same as the first, but use MD4 instead of SHA-1. Having
+  done this attack once against SHA-1, the MD4 variant should take much
+  less time; mostly just the time you'll spend Googling for an
+  implementation of MD4.
+</p>
+<div class='panel panel-warning'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>You're thinking, why did we bother with this?</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      Blame Stripe. In their second CTF game, the second-to-last challenge involved
+      breaking an H(k, m) MAC with SHA1. Which meant that SHA1 code was floating all
+      over the Internet. MD4 code, not so much.
+    </p>
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-4/31.html b/problems/set-4/31.html
new file mode 100644 (file)
index 0000000..be30c7d
--- /dev/null
@@ -0,0 +1,111 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 31 Set 4 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/4'>Set 4</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/4/challenges/31'>Challenge 31</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Implement and break HMAC-SHA1 with an artificial timing leak</h3>
+          <p>
+  The psuedocode on Wikipedia should be enough. HMAC is very easy.
+</p>
+<p>
+  Using the web framework of your choosing (Sinatra, web.py, whatever),
+  write a tiny application that has a URL that takes a "file" argument
+  and a "signature" argument, like so:
+</p>
+<pre>http://localhost:9000/test?file=foo&signature=46b4ec586117154dacd49d664e5d63fdc88efb51</pre>
+<p>
+  Have the server generate an HMAC key, and then verify that the
+  "signature" on incoming requests is valid for "file", using the "=="
+  operator to compare the valid MAC for a file with the "signature"
+  parameter (in other words, verify the HMAC the way any normal
+  programmer would verify it).
+</p>
+<p>
+  Write a function, call it "insecure_compare", that implements the ==
+  operation by doing byte-at-a-time comparisons with early exit (ie,
+  return false at the first non-matching byte).
+</p>
+<p>
+  In the loop for "insecure_compare", add a 50ms sleep (sleep 50ms after
+  each byte).
+</p>
+<p>
+  Use your "insecure_compare" function to verify the HMACs on incoming
+  requests, and test that the whole contraption works. Return a 500 if
+  the MAC is invalid, and a 200 if it's OK.
+</p>
+<p>
+  Using the timing leak in this application, write a program that
+  discovers the valid MAC for any file.
+</p>
+<div class='panel panel-warning'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Why artificial delays?</h3>
+  </div>
+  <div class='panel-body'>
+    Early-exit string compares are probably the most common source of cryptographic
+    timing leaks, but they aren't especially easy to exploit. In fact, many timing leaks
+    (for instance, any in C, C++, Ruby, or Python) probably aren't exploitable over
+    a wide-area network at all. To play with attacking real-world timing leaks, you
+    have to start writing low-level timing code. We're keeping things cryptographic
+    in these challenges.
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-4/32.html b/problems/set-4/32.html
new file mode 100644 (file)
index 0000000..e5b0488
--- /dev/null
@@ -0,0 +1,71 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 32 Set 4 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/4'>Set 4</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/4/challenges/32'>Challenge 32</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Break HMAC-SHA1 with a slightly less artificial timing leak</h3>
+          <p>
+  Reduce the sleep in your "insecure_compare" until your previous
+  solution breaks. (Try 5ms to start.)
+</p>
+<p>
+  Now break it again.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-4/index.html b/problems/set-4/index.html
new file mode 100644 (file)
index 0000000..ccca38b
--- /dev/null
@@ -0,0 +1,97 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Set 4 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/'>Set 4</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Crypto Challenge Set 4</h3>
+          <p>
+  This is the last set of <b>block cipher cryptography</b> challenges, and also our coverage
+  of message authentication.
+</p>
+<p>
+  This set is <b>much easier</b> than the last set. We introduce some new concepts, but the
+  attacks themselves involve less code than, say, the CBC padding oracle.
+</p>
+<p>
+  Things get significantly trickier in the next two sets. A lot of people drop off after
+  set 4.
+</p>
+<ol start='25'>
+  <li>
+    <a href='/sets/4/challenges/25'>Break "random access read/write" AES CTR</a>
+  </li>
+  <li>
+    <a href='/sets/4/challenges/26'>CTR bitflipping</a>
+  </li>
+  <li>
+    <a href='/sets/4/challenges/27'>Recover the key from CBC with IV=Key</a>
+  </li>
+  <li>
+    <a href='/sets/4/challenges/28'>Implement a SHA-1 keyed MAC</a>
+  </li>
+  <li>
+    <a href='/sets/4/challenges/29'>Break a SHA-1 keyed MAC using length extension</a>
+  </li>
+  <li>
+    <a href='/sets/4/challenges/30'>Break an MD4 keyed MAC using length extension</a>
+  </li>
+  <li>
+    <a href='/sets/4/challenges/31'>Implement and break HMAC-SHA1 with an artificial timing leak</a>
+  </li>
+  <li>
+    <a href='/sets/4/challenges/32'>Break HMAC-SHA1 with a slightly less artificial timing leak</a>
+  </li>
+</ol>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-5/33.html b/problems/set-5/33.html
new file mode 100644 (file)
index 0000000..e98b01a
--- /dev/null
@@ -0,0 +1,117 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 33 Set 5 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/5'>Set 5</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/5/challenges/33'>Challenge 33</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Implement Diffie-Hellman</h3>
+          <p>
+  For one of the most important algorithms in cryptography this exercise
+  couldn't be a whole lot easier.
+</p>
+<p>
+  Set a variable "p" to 37 and "g" to 5. This algorithm is so easy I'm not even
+  going to explain it. Just do what I do.
+</p>
+<p>
+  Generate "a", a random number mod 37. Now generate "A", which is "g"
+  raised to the "a" power mode 37 --- A = (g**a) % p.
+</p>
+<p>
+  Do the same for "b" and "B".
+</p>
+<p>
+  "A" and "B" are public keys. Generate a session key with them; set
+  "s" to "B" raised to the "a" power mod 37 --- s = (B**a) % p.
+</p>
+<p>
+  Do the same with A**b, check that you come up with the same "s".
+</p>
+<p>
+  To turn "s" into a key, you can just hash it to create 128 bits of
+  key material (or SHA256 it to create a key for encrypting and a key
+  for a MAC).
+</p>
+<p>
+  Ok,  that was fun, now repeat the exercise with bignums like in the real
+  world. Here are parameters NIST likes:
+</p>
+<pre>p:
+ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024
+e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd
+3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec
+6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f
+24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361
+c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552
+bb9ed529077096966d670c354e4abc9804f1746c08ca237327fff
+fffffffffffff
+g: 2</pre>
+<p>
+  This is very easy to do in Python or Ruby or other high-level
+  languages that auto-promote fixnums to bignums, but it isn't "hard"
+  anywhere.
+</p>
+<p>
+  Note that you'll need to write your own modexp (this is blackboard
+  math, don't freak out), because you'll blow out your bignum library
+  raising "a" to the 1024-bit-numberth power. You can find modexp
+  routines on Rosetta Code for most languages.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-5/34.html b/problems/set-5/34.html
new file mode 100644 (file)
index 0000000..d986e3a
--- /dev/null
@@ -0,0 +1,128 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 34 Set 5 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/5'>Set 5</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/5/challenges/34'>Challenge 34</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Implement a MITM key-fixing attack on Diffie-Hellman with parameter injection</h3>
+          <p>
+  Use the code you just worked out to build a protocol and an
+  "echo" bot. You don't actually have to do the network part of this
+  if you don't want; just simulate that. The protocol is:
+</p>
+<dl>
+  <dt>
+    A->B
+  </dt>
+  <dd>Send "p", "g", "A"</dd>
+  <dt>
+    B->A
+  </dt>
+  <dd>Send "B"</dd>
+  <dt>
+    A->B
+  </dt>
+  <dd>Send AES-CBC(SHA1(s)[0:16], iv=random(16), msg) + iv</dd>
+  <dt>
+    B->A
+  </dt>
+  <dd>Send AES-CBC(SHA1(s)[0:16], iv=random(16), A's msg) + iv</dd>
+</dl>
+<p>
+  (In other words, derive an AES key from DH with SHA1, use it in both
+  directions, and do CBC with random IVs appended or prepended to the
+  message).
+</p>
+<p>
+  Now implement the following MITM attack:
+</p>
+<dl>
+  <dt>A->M</dt>
+  <dd>Send "p", "g", "A"</dd>
+  <dt>M->B</dt>
+  <dd>Send "p", "g", "p"</dd>
+  <dt>B->M</dt>
+  <dd>Send "B"</dd>
+  <dt>M->A</dt>
+  <dd>Send "p"</dd>
+  <dt>A->M</dt>
+  <dd>Send AES-CBC(SHA1(s)[0:16], iv=random(16), msg) + iv</dd>
+  <dt>M->B</dt>
+  <dd>Relay that to B</dd>
+  <dt>B->M</dt>
+  <dd>Send AES-CBC(SHA1(s)[0:16], iv=random(16), A's msg) + iv</dd>
+  <dt>M->A</dt>
+  <dd>Relay that to A</dd>
+</dl>
+<p>
+  M should be able to decrypt the messages. "A" and "B" in the protocol
+  --- the public keys, over the wire --- have been swapped out with "p".
+  Do the DH math on this quickly to see what that does to the
+  predictability of the key.
+</p>
+<p>
+  Decrypt the messages from M's vantage point as they go by.
+</p>
+<p>
+  Note that you don't actually have to inject bogus parameters to make
+  this attack work; you could just generate Ma, MA, Mb, and MB as valid
+  DH parameters to do a generic MITM attack. But do the parameter
+  injection attack; it's going to come up again.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-5/35.html b/problems/set-5/35.html
new file mode 100644 (file)
index 0000000..c9851ad
--- /dev/null
@@ -0,0 +1,97 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 35 Set 5 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/5'>Set 5</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/5/challenges/35'>Challenge 35</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Implement DH with negotiated groups, and break with malicious "g" parameters</h3>
+          <dl>
+  <dt>A->B</dt>
+  <dd>Send "p", "g"</dd>
+  <dt>B->A</dt>
+  <dd>Send ACK</dd>
+  <dt>A->B</dt>
+  <dd>Send "A"</dd>
+  <dt>B->A</dt>
+  <dd>Send "B"</dd>
+  <dt>A->B</dt>
+  <dd>Send AES-CBC(SHA1(s)[0:16], iv=random(16), msg) + iv</dd>
+  <dt>B->A</dt>
+  <dd>Send AES-CBC(SHA1(s)[0:16], iv=random(16), A's msg) + iv</dd>
+</dl>
+<p>
+  Do the MITM attack again, but play with "g". What happens with:
+</p>
+<pre>    g = 1
+    g = p
+    g = p - 1</pre>
+<p>
+  Write attacks for each.
+</p>
+<div class='panel panel-warning'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>When does this ever happen?</h3>
+  </div>
+  <div class='panel-body'>
+    Honestly, not that often in real-world systems. If you can mess with "g", chances are
+    you can mess with something worse. Most systems pre-agree on a static DH group. But
+    the same construction exists in Elliptic Curve Diffie-Hellman, and this becomes more
+    relevant there.
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-5/36.html b/problems/set-5/36.html
new file mode 100644 (file)
index 0000000..b1a288b
--- /dev/null
@@ -0,0 +1,127 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 36 Set 5 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/5'>Set 5</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/5/challenges/36'>Challenge 36</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Implement Secure Remote Password (SRP)</h3>
+          <p>
+  To understand SRP, look at how you generate an AES key from DH; now,
+  just observe you can do the "opposite" operation an generate a numeric
+  parameter from a hash. Then:
+</p>
+<p>
+  Replace A and B with C and S (client & server)
+</p>
+<dt>C & S</dt>
+<dd>Agree on N=[NIST Prime], g=2, k=3, I (email), P (password)</dd>
+<dt>S</dt>
+<dd>
+  <ol>
+    <li>Generate salt as random integer</li>
+    <li>Generate string xH=SHA256(salt|password)</li>
+    <li>Convert xH to integer x somehow (put 0x on hexdigest)</li>
+    <li>Generate v=g**x % N</li>
+    <li>Save everything but x, xH</li>
+  </ol>
+</dd>
+<dt>C->S</dt>
+<dd>Send I, A=g**a % N (a la Diffie Hellman)</dd>
+<dt>S->C</dt>
+<dd>Send salt, B=kv + g**b % N</dd>
+<dt>S, C</dt>
+<dd>Compute string uH = SHA256(A|B), u = integer of uH</dd>
+<dt>C</dt>
+<dd>
+  <ol>
+    <li>Generate string xH=SHA256(salt|password)</li>
+    <li>Convert xH to integer x somehow (put 0x on hexdigest)</li>
+    <li>Generate S = (B - k * g**x)**(a + u * x) % N</li>
+    <li>Generate K = SHA256(S)</li>
+  </ol>
+</dd>
+<dt>S</dt>
+<dd>
+  <ol>
+    <li>Generate S = (A * v**u) ** b % N</li>
+    <li>Generate K = SHA256(S)</li>
+  </ol>
+</dd>
+<dt>C->S</dt>
+<dd>Send HMAC-SHA256(K, salt)</dd>
+<dt>S->C</dt>
+<dd>Send "OK" if HMAC-SHA256(K, salt) validates</dd>
+<p></p>
+<p>
+  You're going to want to do this at a REPL of some sort; it may take a
+  couple tries.
+</p>
+<p>
+  It doesn't matter how you go from integer to string or string to
+  integer (where things are going in or out of SHA256) as long as you do
+  it consistently. I tested by using the ASCII decimal representation of
+  integers as input to SHA256, and by converting the hexdigest to an
+  integer when processing its output.
+</p>
+<p>
+  This is basically Diffie Hellman with a tweak of mixing the password
+  into the public keys. The server also takes an extra step to avoid storing
+  an easily crackable password-equivalent.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-5/37.html b/problems/set-5/37.html
new file mode 100644 (file)
index 0000000..def8b0c
--- /dev/null
@@ -0,0 +1,88 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 37 Set 5 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/5'>Set 5</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/5/challenges/37'>Challenge 37</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Break SRP with a zero key</h3>
+          <p>
+  Get your SRP working in an actual client-server setting. "Log in" with
+  a valid password using the protocol.
+</p>
+<p>
+  Now log in without your password by having the client send 0 as its
+  "A" value. What does this to the "S" value that both sides compute?
+</p>
+<p>
+  Now log in without your password by having the client send N, N*2, &c.
+</p>
+<div class='panel panel-info'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Cryptanalytic MVP award</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      Trevor Perrin and Nate Lawson taught us this attack 7 years ago. It is <i>excellent</i>.
+      Attacks on DH are tricky to "operationalize". But this attack uses the same concepts, and
+      results in auth bypass. Almost every implementation of SRP we've ever seen has this flaw;
+      if you see a new one, go look for this bug.
+    </p>
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-5/38.html b/problems/set-5/38.html
new file mode 100644 (file)
index 0000000..a1912f0
--- /dev/null
@@ -0,0 +1,143 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 38 Set 5 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/5'>Set 5</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/5/challenges/38'>Challenge 38</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Offline dictionary attack on simplified SRP</h3>
+          <div class='row'>
+  <div class='col-md-2'>
+    S
+  </div>
+  <div class='col-md-8'>
+    <pre>x = SHA256(salt|password)
+    v = g**x % n</pre>
+  </div>
+</div>
+<div class='row'>
+  <div class='col-md-2'>
+    C->S
+  </div>
+  <div class='col-md-8'>
+    <pre>I, A = g**a % n</pre>
+  </div>
+</div>
+<div class='row'>
+  <div class='col-md-2'>
+    S->C
+  </div>
+  <div class='col-md-8'>
+    <pre>salt, B = g**b % n, u = 128 bit random number</pre>
+  </div>
+</div>
+<div class='row'>
+  <div class='col-md-2'>
+    C
+  </div>
+  <div class='col-md-8'>
+    <pre>x = SHA256(salt|password)
+    S = B**(a + ux) % n
+    K = SHA256(S)</pre>
+  </div>
+</div>
+<div class='row'>
+  <div class='col-md-2'>
+    S
+  </div>
+  <div class='col-md-8'>
+    <pre>S = (A * v ** u)**b % n
+    K = SHA256(S)</pre>
+  </div>
+</div>
+<div class='row'>
+  <div class='col-md-2'>
+    C->S
+  </div>
+  <div class='col-md-8'>
+    Send HMAC-SHA256(K, salt)
+  </div>
+</div>
+<div class='row'>
+  <div class='col-md-2'>
+    S->C
+  </div>
+  <div class='col-md-8'>
+    Send "OK" if HMAC-SHA256(K, salt) validates
+  </div>
+</div>
+<div class='row'>
+  <div class='col-md-2'></div>
+        <div class='col-md-10'>
+    <p>
+      Note that in this protocol, the server's "B" parameter doesn't depend
+      on the password (it's just a Diffie Hellman public key).
+    </p>
+    <p>
+      Make sure the protocol works given a valid password.
+    </p>
+    <p>
+      Now, run the protocol as a MITM attacker: pose as the server and use
+      arbitrary values for b, B, u, and salt.
+    </p>
+    <p>
+      Crack the password from A's HMAC-SHA256(K, salt).
+    </p>
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-5/39.html b/problems/set-5/39.html
new file mode 100644 (file)
index 0000000..3907ffc
--- /dev/null
@@ -0,0 +1,123 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 39 Set 5 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/5'>Set 5</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/5/challenges/39'>Challenge 39</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Implement RSA</h3>
+          <p>
+  There are two annoying things about implementing RSA. Both of them
+  involve key generation; the actual encryption/decryption in RSA is
+  trivial.
+</p>
+<p>
+  First, you need to generate random primes. You can't just agree on a
+  prime ahead of time, like you do in DH. You can write this algorithm
+  yourself, but I just cheat and use OpenSSL's BN library to do the
+  work.
+</p>
+<p>
+  The second is that you need an "invmod" operation (the multiplicative
+  inverse), which is not an operation that is wired into your
+  language. The algorithm is just a couple lines, but I always lose an
+  hour getting it to work.
+</p>
+<p>
+  I recommend you not bother with primegen, but do take the time to get
+  your own EGCD and invmod algorithm working.
+</p>
+<p>
+  Now:
+</p>
+<ul>
+  <li>
+    Generate 2 random primes. We'll use small numbers to start, so you
+    can just pick them out of a prime table. Call them "p" and "q".
+  </li>
+  <li>
+    Let n be p * q. Your RSA math is modulo n.
+  </li>
+  <li>
+    Let et be (p-1)*(q-1) (the "totient"). You need this value only for
+    keygen.
+  </li>
+  <li>
+    Let e be 3.
+  </li>
+  <li>
+    Compute d = invmod(e, et). invmod(17, 3120) is 2753.
+  </li>
+  <li>
+    Your public key is [e, n]. Your private key is [d, n].
+  </li>
+  <li>
+    To encrypt: c = m**e%n. To decrypt: m = c**d%n
+  </li>
+  <li>
+    Test this out with a number, like "42".
+  </li>
+  <li>
+    Repeat with bignum primes (keep e=3).
+  </li>
+</ul>
+<p>
+  Finally, to encrypt a string, do something cheesy, like convert the
+  string to hex and put "0x" on the front of it to turn it into a
+  number. The math cares not how stupidly you feed it strings.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-5/40.html b/problems/set-5/40.html
new file mode 100644 (file)
index 0000000..41e7599
--- /dev/null
@@ -0,0 +1,108 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 40 Set 5 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/5'>Set 5</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/5/challenges/40'>Challenge 40</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Implement an E=3 RSA Broadcast attack</h3>
+          <p>
+  Assume you're a Javascript programmer. That is, you're using a
+  naive handrolled RSA to encrypt without padding.
+</p>
+<p>
+  Assume you can be coerced into encrypting the same plaintext
+  three times, under three different public keys. You can; it's
+  happened.
+</p>
+<p>
+  Then an attacker can trivially decrypt your message, by:
+</p>
+<ol>
+  <li>Capturing any 3 of the ciphertexts and their corresponding pubkeys</li>
+  <li>
+    Using the CRT to solve for the number represented by the three
+    ciphertexts (which are residues mod their respective pubkeys)
+  </li>
+  <li>Taking the cube root of the resulting number</li>
+</ol>
+<p>
+  The CRT says you can take any number and represent it as the
+  combination of a series of residues mod a series of moduli. In the
+  three-residue case, you have:
+</p>
+<pre>result =
+  (c_0 * m_s_0 * invmod(m_s_0, n_0)) +
+  (c_1 * m_s_1 * invmod(m_s_1, n_1)) +
+  (c_2 * m_s_2 * invmod(m_s_2, n_2)) mod N_012</pre>
+<p>
+  where:
+</p>
+<pre> c_0, c_1, c_2 are the three respective residues mod
+ n_0, n_1, n_2
+
+ m_s_n (for n in 0, 1, 2) are the product of the moduli
+ EXCEPT n_n --- ie, m_s_1 is n_0 * n_2
+
+ N_012 is the product of all three moduli</pre>
+<p>
+  To decrypt RSA using a simple cube root, leave off the
+  final modulus operation; just take the raw accumulated result and
+  cube-root it.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-5/index.html b/problems/set-5/index.html
new file mode 100644 (file)
index 0000000..d96371b
--- /dev/null
@@ -0,0 +1,97 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Set 5 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/'>Set 5</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Crypto Challenge Set 5</h3>
+          <p>
+  This is the first set of <b>number-theoretic cryptography</b> challenges, and also our coverage
+  of message authentication.
+</p>
+<p>
+  This set is <b>significantly harder</b> than the last set. The concepts are new, the attacks
+  bear no resemblance to those of the previous sets, and... math.
+</p>
+<p>
+  On the other hand, <b>our favorite cryptanalytic attack ever</b> is in this set (you'll see
+  it soon). We're happy with this set. Don't wimp out here. You're almost done!
+</p>
+<ol start='33'>
+  <li>
+    <a href='/sets/5/challenges/33'>Implement Diffie-Hellman</a>
+  </li>
+  <li>
+    <a href='/sets/5/challenges/34'>Implement a MITM key-fixing attack on Diffie-Hellman with parameter injection</a>
+  </li>
+  <li>
+    <a href='/sets/5/challenges/35'>Implement DH with negotiated groups, and break with malicious "g" parameters</a>
+  </li>
+  <li>
+    <a href='/sets/5/challenges/36'>Implement Secure Remote Password (SRP)</a>
+  </li>
+  <li>
+    <a href='/sets/5/challenges/37'>Break SRP with a zero key</a>
+  </li>
+  <li>
+    <a href='/sets/5/challenges/38'>Offline dictionary attack on simplified SRP</a>
+  </li>
+  <li>
+    <a href='/sets/5/challenges/39'>Implement RSA</a>
+  </li>
+  <li>
+    <a href='/sets/5/challenges/40'>Implement an E=3 RSA Broadcast attack</a>
+  </li>
+</ol>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-6/41.html b/problems/set-6/41.html
new file mode 100644 (file)
index 0000000..ba2fdc4
--- /dev/null
@@ -0,0 +1,126 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 41 Set 6 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/6'>Set 6</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/6/challenges/41'>Challenge 41</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Implement unpadded message recovery oracle</h3>
+          <p>
+  Nate Lawson says we should stop calling it "RSA padding" and start
+  calling it "RSA armoring". Here's why.
+</p>
+<p>
+  Imagine a web application, again with the Javascript encryption,
+  taking RSA-encrypted messages which (again: Javascript) aren't padded
+  before encryption at all.
+</p>
+<p>
+  You can submit an arbitrary RSA blob and the server will return
+  plaintext. But you can't submit the same message twice: let's say the
+  server keeps hashes of previous messages for some liveness interval,
+  and that the message has an embedded timestamp:
+</p>
+<pre>{
+  time: 1356304276,
+  social: '555-55-5555',
+}</pre>
+<p>
+  You'd like to capture other people's messages and use the server to
+  decrypt them. But when you try, the server takes the hash of the
+  ciphertext and uses it to reject the request. Any bit you flip in the
+  ciphertext irrevocably scrambles the decryption.
+</p>
+<p>
+  This turns out to be trivially breakable:
+</p>
+<ul>
+  <li>Capture the ciphertext C</li>
+  <li>Let N and E be the public modulus and exponent respectively</li>
+  <li>Let S be a random number > 1 mod N. Doesn't matter what.</li>
+  <li>
+    Now:
+    <pre>C' = ((S**E mod N) C) mod N</pre>
+  </li>
+  <li>
+    Submit C', which appears totally different from C, to the server,
+    recovering P', which appears totally different from P
+  </li>
+  <li>
+    Now:
+    <pre>          P'
+    P = -----  mod N
+          S</pre>
+  </li>
+</ul>
+<p>
+  Oops!
+</p>
+<p>
+  Implement that attack.
+</p>
+<div class='panel panel-warning'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Careful about division in cyclic groups.</h3>
+  </div>
+  <div class='panel-body'>
+    Remember: you don't simply divide mod N; you multiply by the
+    multiplicative inverse mod N. So you'll need a modinv() function.
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-6/42.html b/problems/set-6/42.html
new file mode 100644 (file)
index 0000000..e988ec1
--- /dev/null
@@ -0,0 +1,146 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 42 Set 6 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/6'>Set 6</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/6/challenges/42'>Challenge 42</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Bleichenbacher's e=3 RSA Attack</h3>
+          <div class='panel panel-info'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Crypto-tourism informational placard.</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      This attack broke Firefox's TLS certificate validation several
+      years ago. You could write a Python script to fake an RSA signature
+      for any certificate. We find new instances of it every other year
+      or so.
+    </p>
+  </div>
+</div>
+<p>
+  RSA with an encrypting exponent of 3 is popular, because it makes the
+  RSA math faster.
+</p>
+<p>
+  With e=3 RSA, encryption is just cubing a number mod the public
+  encryption modulus:
+</p>
+<pre> c = m ** 3 % n</pre>
+<p>
+  e=3 is secure as long as we can make assumptions about the message
+  blocks we're encrypting. The worry with low-exponent RSA is that the
+  message blocks we process won't be large enough to wrap the modulus
+  after being cubed. The block 00:02 (imagine sufficient zero-padding)
+  can be "encrypted" in e=3 RSA; it is simply 00:08.
+</p>
+<p>
+  When RSA is used to sign, rather than encrypt, the operations are
+  reversed; the verifier "decrypts" the message by cubing it. This
+  produces a "plaintext" which the verifier checks for validity.
+</p>
+<p>
+  When you use RSA to sign a message, you supply it a block input that
+  contains a message digest. The PKCS1.5 standard formats that block as:
+</p>
+<pre>00h 01h ffh ffh ... ffh ffh 00h ASN.1 GOOP HASH</pre>
+<p>
+  As intended, the ffh bytes in that block expand to fill the whole
+  block, producing a "right-justified" hash (the last byte of the hash
+  is the last byte of the message).
+</p>
+<p>
+  There was, 7 years ago, a common implementation flaw with RSA
+  verifiers: they'd verify signatures by "decrypting" them (cubing them
+  modulo the public exponent) and then "parsing" them by looking for
+  00h 01h ... ffh 00h ASN.1 HASH.
+</p>
+<p>
+  This is a bug because it implies the verifier isn't checking all the
+  padding. If you don't check the padding, you leave open the
+  possibility that instead of hundreds of ffh bytes, you have only a
+  few, which if you think about it means there could be squizzilions of
+  possible numbers that could produce a valid-looking signature.
+</p>
+<p>
+  How to find such a block? Find a number that when cubed (a) doesn't
+  wrap the modulus (thus bypassing the key entirely) and (b) produces a
+  block that starts "00h 01h ffh ... 00h ASN.1 HASH".
+</p>
+<p>
+  There are two ways to approach this problem:
+</p>
+<ul>
+  <li>
+    You can work from Hal Finney's writeup, available on Google, of how
+    Bleichenbacher explained the math "so that you can do it by hand
+    with a pencil".
+  </li>
+  <li>
+    You can implement an integer cube root in your language, format the
+    message block you want to forge, leaving sufficient trailing zeros
+    at the end to fill with garbage, then take the cube-root of that
+    block.
+  </li>
+</ul>
+<p>
+  Forge a 1024-bit RSA signature for the string "hi mom". Make sure your
+  implementation actually accepts the signature!
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-6/43.html b/problems/set-6/43.html
new file mode 100644 (file)
index 0000000..50177bd
--- /dev/null
@@ -0,0 +1,150 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 43 Set 6 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/6'>Set 6</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/6/challenges/43'>Challenge 43</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>DSA key recovery from nonce</h3>
+          <p>
+  <b>Step 1</b>: Relocate so that you are out of easy travel distance of us.
+</p>
+<p>
+  <b>Step 2</b>: Implement DSA, up to signing and verifying, including
+  parameter generation.
+</p>
+<p>
+  <i>Hah-hah you're too far away to come punch us.
+  </i>
+</p>
+<p>
+  <i>Just kidding</i> you can skip the parameter generation part if you
+  want; if you do, use these params:
+</p>
+<pre> p = 800000000000000089e1855218a0e7dac38136ffafa72eda7
+     859f2171e25e65eac698c1702578b07dc2a1076da241c76c6
+     2d374d8389ea5aeffd3226a0530cc565f3bf6b50929139ebe
+     ac04f48c3c84afb796d61e5a4f9a8fda812ab59494232c7d2
+     b4deb50aa18ee9e132bfa85ac4374d7f9091abc3d015efc87
+     1a584471bb1
+ q = f4f47f05794b256174bba6e9b396a7707e563c5b
+ g = 5958c9d3898b224b12672c0b98e06c60df923cb8bc999d119
+     458fef538b8fa4046c8db53039db620c094c9fa077ef389b5
+     322a559946a71903f990f1f7e0e025e2d7f7cf494aff1a047
+     0f5b64c36b625a097f1651fe775323556fe00b3608c887892
+     878480e99041be601a62166ca6894bdd41a7054ec89f756ba
+     9fc95302291</pre>
+<p>
+  ("But I want smaller params!" Then generate them yourself.)
+</p>
+<p>
+  The DSA signing operation generates a random subkey "k". You know this
+  because you implemented the DSA sign operation.
+</p>
+<p>
+  This is the first and easier of two challenges regarding the DSA "k"
+  subkey.
+</p>
+<p>
+  Given a known "k", it's trivial to recover the DSA private key "x":
+</p>
+<pre>          (s * k) - H(msg)
+      x = ----------------  mod q
+                  r</pre>
+<p>
+  Do this a couple times to prove to yourself that you grok it. Capture
+  it in a function of some sort.
+</p>
+<p>
+  Now then. I used the parameters above. I generated a keypair. My
+  pubkey is:
+</p>
+<pre>  y = 84ad4719d044495496a3201c8ff484feb45b962e7302e56a392aee4
+      abab3e4bdebf2955b4736012f21a08084056b19bcd7fee56048e004
+      e44984e2f411788efdc837a0d2e5abb7b555039fd243ac01f0fb2ed
+      1dec568280ce678e931868d23eb095fde9d3779191b8c0299d6e07b
+      bb283e6633451e535c45513b2d33c99ea17</pre>
+<p>
+  I signed
+</p>
+<pre>For those that envy a MC it can be hazardous to your health
+So be friendly, a matter of life and death, just like a etch-a-sketch</pre>
+<p>
+  (My SHA1 for this string was <i>d2d0714f014a9784047eaeccf956520045c45265</i>;
+  I don't know what NIST wants you to do, but when I convert that hash
+  to an integer I get: <i>0xd2d0714f014a9784047eaeccf956520045c45265</i>).
+</p>
+<p>
+  I get:
+</p>
+<pre>  r = 548099063082341131477253921760299949438196259240
+  s = 857042759984254168557880549501802188789837994940</pre>
+<p>
+  I signed this string with a broken implemention of DSA that generated
+  "k" values between 0 and 2^16. What's my private key?
+</p>
+<p>
+  Its SHA-1 fingerprint (after being converted to hex) is:
+</p>
+<pre>0954edd5e0afe5542a4adf012611a91912a3ec16</pre>
+<p>
+  Obviously, it also generates the same signature for that string.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-6/44.html b/problems/set-6/44.html
new file mode 100644 (file)
index 0000000..f685565
--- /dev/null
@@ -0,0 +1,123 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 44 Set 6 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/6'>Set 6</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/6/challenges/44'>Challenge 44</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>DSA nonce recovery from repeated nonce</h3>
+          <div class='panel panel-info'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Cryptanalytic MVP award.</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      This attack (in an elliptic curve group) broke the PS3. It is a great, great attack.
+    </p>
+  </div>
+</div>
+<p>
+  <a href='/static/challenge-data/44.txt'>In this file find a collection of DSA-signed messages.</a>
+  (NB: each msg has a trailing space.)
+</p>
+<p>
+  These were signed under the following pubkey:
+</p>
+<pre>y = 2d026f4bf30195ede3a088da85e398ef869611d0f68f07
+    13d51c9c1a3a26c95105d915e2d8cdf26d056b86b8a7b8
+    5519b1c23cc3ecdc6062650462e3063bd179c2a6581519
+    f674a61f1d89a1fff27171ebc1b93d4dc57bceb7ae2430
+    f98a6a4d83d8279ee65d71c1203d2c96d65ebbf7cce9d3
+    2971c3de5084cce04a2e147821</pre>
+<p>
+  (using the same domain parameters as the previous exercise)
+</p>
+<p>
+  It should not be hard to find the messages for which we have
+  accidentally used a repeated "k". Given a pair of such messages, you
+  can discover the "k" we used with the following formula:
+</p>
+<pre>         (m1 - m2)
+     k = --------- mod q
+         (s1 - s2)</pre>
+<div class='panel panel-warning'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>9th Grade Math: Study It!</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      If you want to demystify this, work out that equation from the original DSA equations.
+    </p>
+  </div>
+</div>
+<div class='panel panel-danger'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Basic cyclic group math operations want to screw you</h3>
+  </div>
+  <div class='panel-body'>
+    Remember all this math is mod q; s2 may be larger than s1, for
+    instance, which isn't a problem if you're doing the subtraction mod
+    q. If you're like me, you'll definitely lose an hour to forgetting a
+    paren or a mod q. (And don't forget that modular inverse function!)
+  </div>
+</div>
+<p>
+  What's my private key? Its SHA-1 (from hex) is:
+</p>
+<pre>   ca8f6f7c66fa362d40760d135b763eb8527d3d52</pre>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-6/44.txt b/problems/set-6/44.txt
new file mode 100644 (file)
index 0000000..3eea46b
--- /dev/null
@@ -0,0 +1,44 @@
+msg: Listen for me, you better listen for me now. 
+s: 1267396447369736888040262262183731677867615804316
+r: 1105520928110492191417703162650245113664610474875
+m: a4db3de27e2db3e5ef085ced2bced91b82e0df19
+msg: Listen for me, you better listen for me now. 
+s: 29097472083055673620219739525237952924429516683
+r: 51241962016175933742870323080382366896234169532
+m: a4db3de27e2db3e5ef085ced2bced91b82e0df19
+msg: When me rockin' the microphone me rock on steady, 
+s: 277954141006005142760672187124679727147013405915
+r: 228998983350752111397582948403934722619745721541
+m: 21194f72fe39a80c9c20689b8cf6ce9b0e7e52d4
+msg: Yes a Daddy me Snow me are de article dan. 
+s: 1013310051748123261520038320957902085950122277350
+r: 1099349585689717635654222811555852075108857446485
+m: 1d7aaaa05d2dee2f7dabdc6fa70b6ddab9c051c5
+msg: But in a in an' a out de dance em 
+s: 203941148183364719753516612269608665183595279549
+r: 425320991325990345751346113277224109611205133736
+m: 6bc188db6e9e6c7d796f7fdd7fa411776d7a9ff
+msg: Aye say where you come from a, 
+s: 502033987625712840101435170279955665681605114553
+r: 486260321619055468276539425880393574698069264007
+m: 5ff4d4e8be2f8aae8a5bfaabf7408bd7628f43c9
+msg: People em say ya come from Jamaica, 
+s: 1133410958677785175751131958546453870649059955513
+r: 537050122560927032962561247064393639163940220795
+m: 7d9abd18bbecdaa93650ecc4da1b9fcae911412
+msg: But me born an' raised in the ghetto that I want yas to know, 
+s: 559339368782867010304266546527989050544914568162
+r: 826843595826780327326695197394862356805575316699
+m: 88b9e184393408b133efef59fcef85576d69e249
+msg: Pure black people mon is all I mon know. 
+s: 1021643638653719618255840562522049391608552714967
+r: 1105520928110492191417703162650245113664610474875
+m: d22804c4899b522b23eda34d2137cd8cc22b9ce8
+msg: Yeah me shoes a an tear up an' now me toes is a show a 
+s: 506591325247687166499867321330657300306462367256
+r: 51241962016175933742870323080382366896234169532
+m: bc7ec371d951977cba10381da08fe934dea80314
+msg: Where me a born in are de one Toronto, so 
+s: 458429062067186207052865988429747640462282138703
+r: 228998983350752111397582948403934722619745721541
+m: d6340bfcda59b6b75b59ca634813d572de800e8f
\ No newline at end of file
diff --git a/problems/set-6/45.html b/problems/set-6/45.html
new file mode 100644 (file)
index 0000000..7ac5b40
--- /dev/null
@@ -0,0 +1,93 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 45 Set 6 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/6'>Set 6</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/6/challenges/45'>Challenge 45</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>DSA parameter tampering</h3>
+          <p>
+  Take your DSA code from the previous exercise. Imagine it as part of
+  an algorithm in which the client was allowed to propose domain
+  parameters (the p and q moduli, and the g generator).
+</p>
+<p>
+  This would be bad, because attackers could trick victims into accepting
+  bad parameters. Vaudenay gave two examples of bad generator
+  parameters: generators that were 0 mod p, and generators that were 1
+  mod p.
+</p>
+<p>
+  Use the parameters from the previous exercise, but substitute 0 for
+  "g". Generate a signature. You will notice something bad. Verify the
+  signature. Now verify any other signature, for any other string.
+</p>
+<p>
+  Now, try (p+1) as "g". With this "g", you can generate a magic
+  signature s, r for any DSA public key that will validate against any
+  string. For arbitrary z:
+</p>
+<pre>  r = ((y**z) % p) % q
+
+        r
+  s =  --- % q
+        z</pre>
+<p>
+  Sign "Hello, world". And "Goodbye, world".
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-6/46.html b/problems/set-6/46.html
new file mode 100644 (file)
index 0000000..0dd7d38
--- /dev/null
@@ -0,0 +1,141 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 46 Set 6 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/6'>Set 6</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/6/challenges/46'>Challenge 46</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>RSA parity oracle</h3>
+          <div class='panel panel-warning'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>When does this ever happen?</h3>
+  </div>
+  <div class='panel-body'>
+    This is a bit of a toy problem, but it's very helpful for
+    understanding what RSA is doing (and also for why pure
+    number-theoretic encryption is terrifying). Trust us, you
+    want to do this before trying the next challenge. Also,
+    it's fun.
+  </div>
+</div>
+<p>
+  Generate a 1024 bit RSA key pair.
+</p>
+<p>
+  Write an oracle function that uses the private key to answer the
+  question "is the plaintext of this message even or odd" (is the last
+  bit of the message 0 or 1). Imagine for instance a server that
+  accepted RSA-encrypted messages and checked the parity of their
+  decryption to validate them, and spat out an error if they were of the
+  wrong parity.
+</p>
+<p>
+  Anyways: function returning true or false based on whether the
+  decrypted plaintext was even or odd, and nothing else.
+</p>
+<p>
+  Take the following string and un-Base64 it in your code (without
+  looking at it!) and encrypt it to the public key, creating a
+  ciphertext:
+</p>
+<pre>VGhhdCdzIHdoeSBJIGZvdW5kIHlvdSBkb24ndCBwbGF5IGFyb3VuZCB3aXRoIHRoZSBGdW5reSBDb2xkIE1lZGluYQ==</pre>
+<p>
+  With your oracle function, you can trivially decrypt the message.
+</p>
+<p>
+  Here's why:
+</p>
+<ul>
+  <li>
+    RSA ciphertexts are just numbers. You can do trivial math on
+    them. You can for instance multiply a ciphertext by the
+    RSA-encryption of another number; the corresponding plaintext will
+    be the product of those two numbers.
+  </li>
+  <li>
+    If you double a ciphertext (multiply it by (2**e)%n), the resulting
+    plaintext will (obviously) be either even or odd.
+  </li>
+  <li>
+    If the plaintext after doubling is even, doubling the plaintext
+    <i>didn't wrap the modulus</i> --- the modulus is a prime number. That
+    means the plaintext is less than half the modulus.
+  </li>
+</ul>
+<p>
+  You can repeatedly apply this heuristic, once per bit of the message,
+  checking your oracle function each time.
+</p>
+<p>
+  Your decryption function starts with bounds for the plaintext of [0,n].
+</p>
+<p>
+  Each iteration of the decryption cuts the bounds in half; either the
+  upper bound is reduced by half, or the lower bound is.
+</p>
+<p>
+  After log2(n) iterations, you have the decryption of the message.
+</p>
+<p>
+  Print the upper bound of the message as a string at each iteration;
+  you'll see the message decrypt "hollywood style".
+</p>
+<p>
+  Decrypt the string (after encrypting it to a hidden private key) above.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-6/47.html b/problems/set-6/47.html
new file mode 100644 (file)
index 0000000..a58653e
--- /dev/null
@@ -0,0 +1,165 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 47 Set 6 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/6'>Set 6</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/6/challenges/47'>Challenge 47</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Bleichenbacher's PKCS 1.5 Padding Oracle (Simple Case)</h3>
+          <div class='panel panel-danger'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Degree of difficulty: moderate</h3>
+  </div>
+  <div class='panel-body'>
+    These next two challenges are the hardest in the entire set.
+  </div>
+</div>
+<p>
+  Let us Google this for you:
+  <a href='http://lmgtfy.com/?q=%22Chosen+ciphertext+attacks+against+protocols+based+on+the+RSA+encryption+standard%22'>
+    "Chosen ciphertext attacks against protocols based on the RSA encryption standard"
+  </a>
+</p>
+<p>
+  This is Bleichenbacher from CRYPTO '98; I get a bunch of .ps versions
+  on the first search page.
+</p>
+<p>
+  Read the paper. It describes a padding oracle attack on
+  PKCS#1v1.5. The attack is similar in spirit to the CBC padding oracle
+  you built earlier; it's an "adaptive chosen ciphertext attack", which
+  means you start with a valid ciphertext and repeatedly corrupt it,
+  bouncing the adulterated ciphertexts off the target to learn things
+  about the original.
+</p>
+<p>
+  This is a common flaw even in modern cryptosystems that use RSA.
+</p>
+<p>
+  It's also the most fun you can have building a crypto attack. It
+  involves 9th grade math, but also has you implementing an algorithm
+  that is complex on par with finding a minimum cost spanning tree.
+</p>
+<p>
+  The setup:
+</p>
+<ul>
+  <li>
+    Build an oracle function, just like you did in the last exercise, but
+    have it check for plaintext[0] == 0 and plaintext[1] == 2.
+  </li>
+  <li>
+    Generate a 256 bit keypair (that is, p and q will each be 128 bit
+    primes), [n, e, d].
+  </li>
+  <li>Plug d and n into your oracle function.</li>
+  <li>
+    PKCS1.5-pad a short message, like "kick it, CC", and call it
+    "m". Encrypt to to get "c".
+  </li>
+  <li>
+    Decrypt "c" using your padding oracle.
+  </li>
+</ul>
+<p>
+  For this challenge, we've used an untenably small RSA modulus (you
+  could factor this keypair instantly). That's because this exercise
+  targets a specific step in the Bleichenbacher paper --- Step 2c, which
+  implements a fast, nearly O(log n) search for the plaintext.
+</p>
+<p>
+  Things you want to keep in mind as you read the paper:
+</p>
+<ul>
+  <li>RSA ciphertexts are just numbers.</li>
+  <li>
+    RSA is "homomorphic" with respect to multiplication, which means you
+    can multiply c * RSA(2) to get a c' that will decrypt to plaintext
+    * 2. This is mindbending but easy to see if you play with it in
+    code --- try multiplying ciphertexts with the RSA encryptions of
+    numbers so you know you grok it.
+  </li>
+  <li>
+    What you need to grok for this challenge is that Bleichenbacher uses
+    multiplication on ciphertexts the way the CBC oracle uses
+    XORs of random blocks.
+  </li>
+  <li>
+    A PKCS#1v1.5 conformant plaintext, one that starts with 00:02, must be
+    a number between 02:00:00...00 and 02:FF:FF..FF --- in other
+    words, 2B and 3B-1, where B is the bit size of the modulus
+    minus the first 16 bits. When you see 2B and 3B, that's the
+    idea the paper is playing with.
+  </li>
+</ul>
+<p>
+  To decrypt "c", you'll need Step 2a from the paper (the search for the
+  first "s" that, when encrypted and multiplied with the ciphertext,
+  produces a conformant plaintext), Step 2c, the fast O(log n) search,
+  and Step 3.
+</p>
+<p>
+  Your Step 3 code is probably not going to need to handle multiple
+  ranges.
+</p>
+<p>
+  We recommend you just use the raw math from paper (check, check,
+  double check your translation to code) and not spend too much time
+  trying to grok how the math works.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-6/48.html b/problems/set-6/48.html
new file mode 100644 (file)
index 0000000..dd5dd1c
--- /dev/null
@@ -0,0 +1,131 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 48 Set 6 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/6'>Set 6</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/6/challenges/48'>Challenge 48</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Bleichenbacher's PKCS 1.5 Padding Oracle (Complete Case)</h3>
+          <div class='panel panel-info'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Cryptanalytic MVP award</h3>
+  </div>
+  <div class='panel-body'>
+    This is an extraordinarily useful attack. PKCS#1v15 padding, despite being
+    totally insecure, <i>is the default padding used by RSA implementations</i>.
+    The OAEP standard that replaces it is not widely implemented. This attack
+    routinely breaks SSL/TLS.
+  </div>
+</div>
+<p>
+  This is a continuation of challenge #47; it implements the complete
+  BB'98 attack.
+</p>
+<p>
+  Set yourself up the way you did in #47, but this time generate a 768
+  bit modulus.
+</p>
+<p>
+  To make the attack work with a realistic RSA keypair, you need to
+  reproduce step 2b from the paper, and your implementation of Step 3
+  needs to handle multiple ranges.
+</p>
+<p>
+  The full Bleichenbacher attack works basically like this:
+</p>
+<ul>
+  <li>
+    Starting from the smallest 's' that could possibly produce
+    a plaintext bigger than 2B, iteratively search for an 's' that
+    produces a conformant plaintext.
+  </li>
+  <li>
+    For our known 's1' and 'n', solve m1=m0s1-rn (again: just a
+    definition of modular multiplication) for 'r', the number of
+    times we've wrapped the modulus.
+  </li>
+  <li>
+    'm0' and 'm1' are unknowns, but we know both are conformant
+    PKCS#1v1.5 plaintexts, and so are between [2B,3B].
+  </li>
+  <li>
+    We substitute the known bounds for both, leaving only 'r'
+    free, and solve for a range of possible 'r'  values. This
+    range should be small!
+  </li>
+  <li>
+    Solve m1=m0s1-rn again but this time for 'm0', plugging in
+    each value of 'r' we generated in the last step. This gives
+    us new intervals to work with. Rule out any interval that
+    is outside 2B,3B.
+  </li>
+  <li>
+    Repeat the process for successively higher values of 's'.
+    Eventually, this process will get us down to just one
+    interval, whereupon we're back to exercise #47.
+  </li>
+</ul>
+<p>
+  What happens when we get down to one interval is, we stop blindly
+  incrementing 's'; instead, we start rapidly growing 'r' and backing it
+  out to 's' values by solving m1=m0s1-rn for 's' instead of 'r' or
+  'm0'. So much algebra! Make your teenage son do it for you! *Note:
+  does not work well in practice*
+</p>
+<iframe width="420" height="315" src="//www.youtube.com/embed/SBCw4_XgouA" frameborder="0" allowfullscreen></iframe>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-6/index.html b/problems/set-6/index.html
new file mode 100644 (file)
index 0000000..e9192e0
--- /dev/null
@@ -0,0 +1,101 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Set 6 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/'>Set 6</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Crypto Challenge Set 6</h3>
+          <p>
+  This is <b>the last of our original crypto challenges</b>.
+</p>
+<p>
+  This set exclusively covers <b>number-theoretic cryptography</b>, and, in particular,
+  RSA and DSA.
+</p>
+<p>
+  This set is <b>hard</b>. The concepts are again new. The attacks involve some
+  math --- but nothing you didn't learn in 9th grade --- and a significant amount
+  of programming.
+</p>
+<p>
+  But <b>they're worth it</b>. Two of these attacks in particular are among the most
+  valuable in real-world cryptography.
+</p>
+<ol start='41'>
+  <li>
+    <a href='/sets/6/challenges/41'>Implement unpadded message recovery oracle</a>
+  </li>
+  <li>
+    <a href='/sets/6/challenges/42'>Bleichenbacher's e=3 RSA Attack</a>
+  </li>
+  <li>
+    <a href='/sets/6/challenges/43'>DSA key recovery from nonce</a>
+  </li>
+  <li>
+    <a href='/sets/6/challenges/44'>DSA nonce recovery from repeated nonce</a>
+  </li>
+  <li>
+    <a href='/sets/6/challenges/45'>DSA parameter tampering</a>
+  </li>
+  <li>
+    <a href='/sets/6/challenges/46'>RSA parity oracle</a>
+  </li>
+  <li>
+    <a href='/sets/6/challenges/47'>Bleichenbacher's PKCS 1.5 Padding Oracle (Simple Case)</a>
+  </li>
+  <li>
+    <a href='/sets/6/challenges/48'>Bleichenbacher's PKCS 1.5 Padding Oracle (Complete Case)</a>
+  </li>
+</ol>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-7/49.html b/problems/set-7/49.html
new file mode 100644 (file)
index 0000000..0d41945
--- /dev/null
@@ -0,0 +1,188 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 49 Set 7 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/7'>Set 7</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/7/challenges/49'>Challenge 49</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>CBC-MAC Message Forgery</h3>
+          <p>
+  Let's talk about CBC-MAC.
+</p>
+<p>
+  CBC-MAC is like this:
+</p>
+<ol>
+  <li>Take the plaintext P.</li>
+  <li>Encrypt P under CBC with key K, yielding ciphertext C.</li>
+  <li>Chuck all of C but the last block C[n].</li>
+  <li>C[n] is the MAC.</li>
+</ol>
+<p>
+  Suppose there's an online banking application, and it carries out user
+  requests by talking to an API server over the network. Each request
+  looks like this:
+</p>
+<pre>message || IV || MAC</pre>
+<p>
+  The message looks like this:
+</p>
+<pre>from=#{from_id}&to=#{to_id}&amount=#{amount}</pre>
+<p>
+  Now, write an API server and a web frontend for it. (NOTE: No need to
+  get ambitious and write actual servers and web apps. Totally fine to
+  go lo-fi on this one.) The client and server should share a secret key
+  K to sign and verify messages.
+</p>
+<p>
+  The API server should accept messages, verify signatures, and carry
+  out each transaction if the MAC is valid. It's also publicly exposed -
+  the attacker can submit messages freely assuming he can forge the
+  right MAC.
+</p>
+<p>
+  The web client should allow the attacker to generate valid messages
+  for accounts he controls. (Feel free to sanitize params if you're
+  feeling anal-retentive.) Assume the attacker is in a position to
+  capture and inspect messages from the client to the API server.
+</p>
+<p>
+  One thing we haven't discussed is the IV. Assume the client generates
+  a per-message IV and sends it along with the MAC. That's how CBC
+  works, right?
+</p>
+<p>
+  Wrong.
+</p>
+<p>
+  For messages signed under CBC-MAC, an attacker-controlled IV is a
+  liability. Why? Because it yields full control over the first block of
+  the message.
+</p>
+<p>
+  Use this fact to generate a message transferring 1M spacebucks from a
+  target victim's account into your account.
+</p>
+<p>
+  I'll wait. Just let me know when you're done.
+</p>
+<p>
+  ... waiting
+</p>
+<p>
+  ... waiting
+</p>
+<p>
+  ... waiting
+</p>
+<p>
+  All done? Great - I knew you could do it!
+</p>
+<p>
+  Now let's tune up that protocol a little bit.
+</p>
+<p>
+  As we now know, you're supposed to use a fixed IV with CBC-MAC, so
+  let's do that. We'll set ours at 0 for simplicity. This means the IV
+  comes out of the protocol:
+</p>
+<pre>message || MAC</pre>
+<p>
+  Pretty simple, but we'll also adjust the message. For the purposes of
+  efficiency, the bank wants to be able to process multiple transactions
+  in a single request. So the message now looks like this:
+</p>
+<pre>from=#{from_id}&tx_list=#{transactions}</pre>
+<p>
+  With the transaction list formatted like:
+</p>
+<pre>to:amount(;to:amount)*</pre>
+<p>
+  There's still a weakness here: the MAC is vulnerable to length
+  extension attacks. How?
+</p>
+<p>
+  Well, the output of CBC-MAC is a valid IV for a new message.
+</p>
+<p>
+  <i>"But we don't control the IV anymore!"</i>
+</p>
+<p>
+  With sufficient mastery of CBC, we can fake it.
+</p>
+<p>
+  Your mission: capture a valid message from your target user. Use
+  length extension to add a transaction paying the attacker's account 1M
+  spacebucks.
+</p>
+<div class='panel panel-info'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Hint!</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      This would be a lot easier if you had full control over the first
+      block of your message, huh? Maybe you can simulate that.
+    </p>
+  </div>
+</div>
+<p>
+  Food for thought:
+  <i>How would you modify the protocol to prevent this?</i>
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-7/50.html b/problems/set-7/50.html
new file mode 100644 (file)
index 0000000..23f4fa6
--- /dev/null
@@ -0,0 +1,108 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 50 Set 7 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/7'>Set 7</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/7/challenges/50'>Challenge 50</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Hashing with CBC-MAC</h3>
+          <p>
+  Sometimes people try to use CBC-MAC as a hash function.
+</p>
+<p>
+  This is a bad idea. Matt Green explains:
+</p>
+<blockquote>
+  To make a long story short: cryptographic hash functions are public
+  functions (i.e., no secret key) that have the property of
+  collision-resistance (it's hard to find two messages with the same
+  hash). MACs are keyed functions that (typically) provide message
+  unforgeability -- a very different property. Moreover, they
+  guarantee this only when the key is secret.
+</blockquote>
+<p>
+  Let's try a simple exercise.
+</p>
+<p>
+  Hash functions are often used for code verification. This snippet of
+  JavaScript (with newline):
+</p>
+<pre>alert('MZA who was that?');</pre>
+<p>
+  Hashes to
+  <i>296b8d7cb78a243dda4d0a61d33bbdd1</i>
+  under CBC-MAC with a key of
+  <i>"YELLOW SUBMARINE"</i>
+  and a 0 IV.
+</p>
+<p>
+  Forge a valid snippet of JavaScript that alerts "Ayo, the Wu is back!"
+  and hashes to the same value. Ensure that it runs in a browser.
+</p>
+<div class='panel panel-info'>
+  <div class='panel-heading'>
+    <h3 class='panel-title'>Extra Credit</h3>
+  </div>
+  <div class='panel-body'>
+    <p>
+      Write JavaScript code that downloads your file, checks its CBC-MAC,
+      and inserts it into the DOM iff it matches the expected hash.
+    </p>
+  </div>
+</div>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-7/51.html b/problems/set-7/51.html
new file mode 100644 (file)
index 0000000..fea6dec
--- /dev/null
@@ -0,0 +1,155 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 51 Set 7 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/7'>Set 7</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/7/challenges/51'>Challenge 51</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Compression Ratio Side-Channel Attacks</h3>
+          <p>
+  Internet traffic is often compressed to save bandwidth. Until
+  recently, this included HTTPS headers, and it still includes the
+  contents of responses.
+</p>
+<p>
+  Why does that matter?
+</p>
+<p>
+  Well, if you're an attacker with:
+</p>
+<ol>
+  <li>Partial plaintext knowledge <i>and</i></li>
+  <li>Partial plaintext control <i>and</i></li>
+  <li>Access to a compression oracle</li>
+</ol>
+<p>
+  You've got a pretty good chance to recover any additional unknown
+  plaintext.
+</p>
+<p>
+  What's a compression oracle? You give it some input and it tells you
+  how well the full message compresses, i.e. the length of the resultant
+  output.
+</p>
+<p>
+  This is somewhat similar to the timing attacks we did way back in set
+  4 in that we're taking advantage of incidental side channels rather
+  than attacking the cryptographic mechanisms themselves.
+</p>
+<p>
+  Scenario: you are running a MITM attack with an eye towards stealing
+  secure session cookies. You've injected malicious content allowing you
+  to spawn arbitrary requests and observe them in flight. (The
+  particulars aren't terribly important, just roll with it.)
+</p>
+<p>
+  So! Write this oracle:
+</p>
+<pre>oracle(P) -> length(encrypt(compress(format_request(P))))</pre>
+<p>
+  Format the request like this:
+</p>
+<pre>POST / HTTP/1.1
+Host: hapless.com
+Cookie: sessionid=TmV2ZXIgcmV2ZWFsIHRoZSBXdS1UYW5nIFNlY3JldCE=
+Content-Length: ((len(P)))
+((P))</pre>
+<p>
+  (Pretend you can't see that session id. You're the attacker.)
+</p>
+<p>
+  Compress using zlib or whatever.
+</p>
+<p>
+  Encryption... is actually kind of irrelevant for our purposes, but be
+  a sport. Just use some stream cipher. Dealer's choice. Random key/IV
+  on every call to the oracle.
+</p>
+<p>
+  And then just return the length in bytes.
+</p>
+<p>
+  Now, the idea here is to leak information using the compression
+  library. A payload of "sessionid=T" should compress just a little bit
+  better than, say, "sessionid=S".
+</p>
+<p>
+  There is one complicating factor. The DEFLATE algorithm operates in
+  terms of individual bits, but the final message length will be in
+  bytes. Even if you do find a better compression, the difference may
+  not cross a byte boundary. So that's a problem.
+</p>
+<p>
+  You may also get some incidental false positives.
+</p>
+<p>
+  But don't worry! I have full confidence in you.
+</p>
+<p>
+  Use the compression oracle to recover the session id.
+</p>
+<p>
+  I'll wait.
+</p>
+<p>
+  Got it? Great.
+</p>
+<p>
+  Now swap out your stream cipher for CBC and do it again.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-7/52.html b/problems/set-7/52.html
new file mode 100644 (file)
index 0000000..38c2088
--- /dev/null
@@ -0,0 +1,166 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 52 Set 7 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/7'>Set 7</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/7/challenges/52'>Challenge 52</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Iterated Hash Function Multicollisions</h3>
+          <p>
+  While we're on the topic of hash functions...
+</p>
+<p>
+  The major feature you want in your hash function is
+  collision-resistance. That is, it should be hard to generate
+  collisions, and it should be <i>really</i> hard to generate a collision for a
+  given hash (<i>aka</i> preimage).
+</p>
+<p>
+  Iterated hash functions have a problem: the effort to generate <i>lots</i> of
+  collisions scales sublinearly.
+</p>
+<p>
+  What's an iterated hash function? For all intents and purposes, we're
+  talking about the Merkle-Damgard construction. It looks like this:
+</p>
+<pre>function MD(M, H, C):
+  for M[i] in pad(M):
+    H := C(M[i], H)
+  return H</pre>
+<p>
+  For message M, initial state H, and compression function C.
+</p>
+<p>
+  This should look really familiar, because SHA-1 and MD4 are both in
+  this category. What's cool is you can use this formula to build a
+  makeshift hash function out of some spare crypto primitives you have
+  lying around (e.g. C = AES-128).
+</p>
+<p>
+  Back on task: the cost of collisions scales sublinearly. What does
+  that mean? If it's feasible to find one collision, it's probably
+  feasible to find a lot.
+</p>
+<p>
+  How? For a given state H, find two blocks that collide. Now take the
+  resulting hash from this collision as your new H and repeat. Recognize
+  that with each iteration you can actually double your collisions by
+  subbing in either of the two blocks for that slot.
+</p>
+<p>
+  This means that if finding two colliding messages takes 2^(b/2) work
+  (where b is the bit-size of the hash function), then finding 2^n
+  colliding messages only takes n*2^(b/2) work.
+</p>
+<p>
+  Let's test it. First, build your own MD hash function. We're going to
+  be generating a LOT of collisions, so don't knock yourself out. In
+  fact, go out of your way to make it bad. Here's one way:
+</p>
+<ol>
+  <li>Take a fast block cipher and use it as C.</li>
+  <li>
+    Make H pretty small. I won't look down on you if it's only 16
+    bits. Pick some initial H.
+  </li>
+  <li>
+    H is going to be the input key and the output block from C. That
+    means you'll need to pad it on the way in and drop bits on the
+    way out.
+  </li>
+</ol>
+<p>
+  Now write the function f(n) that will generate 2^n collisions in this
+  hash function.
+</p>
+<p>
+  Why does this matter? Well, one reason is that people have tried to
+  strengthen hash functions by cascading them together. Here's what I
+  mean:
+</p>
+<ol>
+  <li>Take hash functions f and g.</li>
+  <li>Build h such that h(x) = f(x) || g(x).</li>
+</ol>
+<p>
+  The idea is that if collisions in f cost 2^(b1/2) and collisions in g
+  cost 2^(b2/2), collisions in h should come to the princely sum of
+  2^((b1+b2)/2).
+</p>
+<p>
+  But now we know that's not true!
+</p>
+<p>
+  Here's the idea:
+</p>
+<ol>
+  <li>Pick the "cheaper" hash function. Suppose it's f.</li>
+  <li>Generate 2^(b2/2) colliding messages in f.</li>
+  <li>There's a good chance your message pool has a collision in g.</li>
+  <li>Find it.</li>
+</ol>
+<p>
+  And if it doesn't, keep generating cheap collisions until you find it.
+</p>
+<p>
+  Prove this out by building a more expensive (but not <i>too</i> expensive)
+  hash function to pair with the one you just used. Find a pair of
+  messages that collide under both functions. Measure the total number
+  of calls to the collision function.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-7/53.html b/problems/set-7/53.html
new file mode 100644 (file)
index 0000000..fb1ec9a
--- /dev/null
@@ -0,0 +1,149 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 53 Set 7 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/7'>Set 7</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/7/challenges/53'>Challenge 53</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Kelsey and Schneier's Expandable Messages</h3>
+          <p>
+  One of the basic yardsticks we use to judge a cryptographic hash
+  function is its resistance to second preimage attacks. That means that
+  if I give you x and y such that H(x) = y, you should have a tough time
+  finding x' such that H(x') = H(x) = y.
+</p>
+<p>
+  How tough? Brute-force tough. For a 2^b hash function, we want second
+  preimage attacks to cost 2^b operations.
+</p>
+<p>
+  This turns out not to be the case for very long messages.
+</p>
+<p>
+  Consider the problem we're trying to solve: we want to find a message
+  that will collide with H(x) in the very last block. But there are a
+  ton of intermediate blocks, each with its own intermediate hash
+  state.
+</p>
+<p>
+  What if we could collide into one of those? We could then append all
+  the following blocks from the original message to produce the original
+  H(x). Almost.
+</p>
+<p>
+  We can't do this exactly because the padding will mess things up.
+</p>
+<p>
+  What we need are <i>expandable messages.</i>
+</p>
+<p>
+  In the last problem we used multicollisions to produce 2^n colliding
+  messages for n*2^(b/2) effort. We can use the same principles to
+  produce a set of messages of length (k, k + 2^k - 1) for a given k.
+</p>
+<p>
+  Here's how:
+</p>
+<ul>
+  <li>
+    Starting from the hash function's initial state, find a collision
+    between a single-block message and a message of 2^(k-1)+1 blocks. DO
+    NOT hash the entire long message each time. Choose 2^(k-1) dummy
+    blocks, hash those, then focus on the last block.
+  </li>
+  <li>
+    Take the output state from the first step. Use this as your new
+    initial state and find another collision between a single-block
+    message and a message of 2^(k-2)+1 blocks.
+  </li>
+  <li>
+    Repeat this process k total times. Your last collision should be
+    between a single-block message and a message of 2^0+1 = 2 blocks.
+  </li>
+</ul>
+<p>
+  Now you can make a message of any length in (k, k + 2^k - 1) blocks by
+  choosing the appropriate message (short or long) from each pair.
+</p>
+<p>
+  Now we're ready to attack a long message M of 2^k blocks.
+</p>
+<ol>
+  <li>
+    Generate an expandable message of length (k, k + 2^k - 1) using
+    the strategy outlined above.
+  </li>
+  <li>
+    Hash M and generate a map of intermediate hash states to the
+    block indices that they correspond to.
+  </li>
+  <li>
+    From your expandable message's final state, find a single-block
+    "bridge" to intermediate state in your map. Note the index i it
+    maps to.
+  </li>
+  <li>
+    Use your expandable message to generate a prefix of the right
+    length such that <i>len(prefix || bridge || M[i..])</i> = <i>len(M)</i>.
+  </li>
+</ol>
+<p>
+  The padding in the final block should now be correct, and your forgery
+  should hash to the same value as M.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-7/54.html b/problems/set-7/54.html
new file mode 100644 (file)
index 0000000..50db497
--- /dev/null
@@ -0,0 +1,152 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 54 Set 7 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/7'>Set 7</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/7/challenges/54'>Challenge 54</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Kelsey and Kohno's Nostradamus Attack</h3>
+          <p>
+  Hash functions are sometimes used as proof of a secret prediction.
+</p>
+<p>
+  For example, suppose you wanted to predict the score of every Major
+  League Baseball game in a season. (2,430 in all.) You might be
+  concerned that publishing your predictions would affect the
+  outcomes.
+</p>
+<p>
+  So instead you write down all the scores, hash the document, and
+  publish the hash. Once the season is over, you publish the
+  document. Everyone can then hash the document to verify your
+  soothsaying prowess.
+</p>
+<p>
+  But what if you can't accurately predict the scores of 2.4k baseball
+  games? Have no fear - forging a prediction under this scheme reduces
+  to another second preimage attack.
+</p>
+<p>
+  We could apply the long message attack from the previous problem, but
+  it would look pretty shady. Would you trust someone whose predicted
+  message turned out to be 2^50 bytes long?
+</p>
+<p>
+  It turns out we can run a successful attack with a much shorter
+  suffix. Check the method:
+</p>
+<ol>
+  <li>
+    Generate a large number of initial hash states. Say, 2^k.
+  </li>
+  <li>
+    Pair them up and generate single-block collisions. Now you have
+    2^k hash states that collide into 2^(k-1) states.
+  </li>
+  <li>
+    Repeat the process. Pair up the 2^(k-1) states and generate
+    collisions. Now you have 2^(k-2) states.
+  </li>
+  <li>
+    Keep doing this until you have one state. This is your
+    prediction.
+  </li>
+  <li>
+    Well, sort of. You need to commit to some length to encode in the
+    padding. Make sure it's long enough to accommodate your actual
+    message, this suffix, and a little bit of glue to join them
+    up. Hash this padding block using the state from step 4 - THIS is
+    your prediction.
+  </li>
+</ol>
+<p>
+  What did you just build? It's basically a funnel mapping many initial
+  states into a common final state. What's critical is we now have a big
+  field of 2^k states we can try to collide into, but the actual suffix
+  will only be k+1 blocks long.
+</p>
+<p>
+  The rest is trivial:
+</p>
+<ol>
+  <li>
+    Wait for the end of the baseball season. (This may take some
+    time.)
+  </li>
+  <li>
+    Write down the game results. Or, you know, anything else. I'm not
+    too particular.
+  </li>
+  <li>
+    Generate enough glue blocks to get your message length right. The
+    last block should collide into one of the leaves in your
+    tree.
+  </li>
+  <li>
+    Follow the path from the leaf all the way up to the root node and
+    build your suffix using the message blocks along the way.
+  </li>
+</ol>
+<p>
+  The difficulty here will be around 2^(b-k). By increasing or
+  decreasing k in the tree generation phase, you can tune the difficulty
+  of this step. It probably makes sense to do more work up-front, since
+  people will be waiting on you to supply your message once the event
+  passes. Happy prognosticating!
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-7/55.html b/problems/set-7/55.html
new file mode 100644 (file)
index 0000000..f303f17
--- /dev/null
@@ -0,0 +1,124 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 55 Set 7 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/7'>Set 7</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/7/challenges/55'>Challenge 55</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>MD4 Collisions</h3>
+          <p>
+  MD4 is a 128-bit cryptographic hash function, meaning it should take a
+  work factor of roughly 2^64 to find collisions.
+</p>
+<p>
+  It turns out we can do much better.
+</p>
+<p>
+  The paper
+  <a href='https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;ved=0CCAQFjAA&amp;url=http%3A%2F%2Fwww.infosec.sdu.edu.cn%2Fuploadfile%2Fpapers%2FCryptanalysis%2520of%2520the%2520Hash%2520Functions%2520MD4%2520and%2520RIPEMD.pdf&amp;ei=kb8IVPGQNajksATw1YLoCA&amp;usg=AFQjCNHSIOZ1uUKTO3N5Hi33D3ZeoOyTUg&amp;sig2=-C-5Woy1HJtk7KJJwLLp-A&amp;bvm=bv.74649129,d.cWc'>
+    "Cryptanalysis of the Hash Functions MD4 and RIPEMD"
+  </a>
+  by Wang
+  et al details a cryptanalytic attack that lets us find collisions in
+  2^8 or less.
+</p>
+<p>
+  Given a message block M, Wang outlines a strategy for finding a sister
+  message block M', differing only in a few bits, that will collide with
+  it. Just so long as a short set of conditions holds true for M.
+</p>
+<p>
+  What sort of conditions? Simple bitwise equalities within the
+  intermediate hash function state, e.g. a[1][6] = b[0][6]. This should
+  be read as: "the sixth bit (zero-indexed) of a[1] (i.e. the first
+  update to 'a') should equal the sixth bit of b[0] (i.e. the initial
+  value of 'b')".
+</p>
+<p>
+  It turns out that a lot of these conditions are trivial to enforce. To
+  see why, take a look at the first (of three) rounds in the MD4
+  compression function. In this round, we iterate over each word in the
+  message block sequentially and mix it into the state. So we can make
+  sure all our first-round conditions hold by doing this:
+</p>
+<pre># calculate the new value for a[1] in the normal fashion
+a[1] = (a[0] + f(b[0], c[0], d[0]) + m[0]).lrot(3)
+
+# correct the erroneous bit
+a[1] ^= ((a[1][6] ^ b[0][6]) << 6)
+
+# use algebra to correct the first message block
+m[0] = a[1].rrot(3) - a[0] - f(b[0], c[0], d[0])</pre>
+<p>
+  Simply ensuring all the first round conditions puts us well within the
+  range to generate collisions, but we can do better by correcting some
+  additional conditions in the second round. This is a bit trickier, as
+  we need to take care not to stomp on any of the first-round
+  conditions.
+</p>
+<p>
+  Once you've adequately massaged M, you can simply generate M' by
+  flipping a few bits and test for a collision. A collision is not
+  guaranteed as we didn't ensure every condition. But hopefully we got
+  enough that we can find a suitable (M, M') pair without too much
+  effort.
+</p>
+<p>
+  Implement Wang's attack.
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-7/56.html b/problems/set-7/56.html
new file mode 100644 (file)
index 0000000..63951bf
--- /dev/null
@@ -0,0 +1,150 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Challenge 56 Set 7 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/sets/7'>Set 7</a>
+            </li>
+            <li class='active'>
+              <a href='/sets/7/challenges/56'>Challenge 56</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>RC4 Single-Byte Biases</h3>
+          <p>
+  RC4 is popular stream cipher notable for its usage in protocols like
+  TLS, WPA, RDP, &c.
+</p>
+<p>
+  It's also susceptible to significant single-byte biases, especially
+  early in the keystream. What does this mean?
+</p>
+<p>
+  Simply: for a given position in the keystream, certain bytes are more
+  (or less) likely to pop up than others. Given enough encryptions of a
+  given plaintext, an attacker can use these biases to recover the
+  entire plaintext.
+</p>
+<p>
+  Now, search online for
+  <a href='http://lmgtfy.com/?q=On+the+Security+of+RC4+in+TLS+and+WPA'>
+    "On the Security of RC4 in TLS and WPA".
+  </a>
+  This
+  site is your one-stop shop for RC4 information.
+</p>
+<p>
+  Click through to "RC4 biases" on the right.
+</p>
+<p>
+  These are graphs of each single-byte bias (one per page). Notice in
+  particular the monster spikes on z16, z32, z48, etc. (Note: these are
+  one-indexed, so z16 = keystream[15].)
+</p>
+<p>
+  How useful are these biases?
+</p>
+<p>
+  Click through to the research paper and scroll down to the simulation
+  results. (Incidentally, the whole paper is a good read if you have
+  some spare time.) We start out with clear spikes at 2^26 iterations,
+  but our chances for recovering each of the first 256 bytes approaches
+  1 as we get up towards 2^32.
+</p>
+<p>
+  There are two ways to take advantage of these biases. The first method
+  is really simple:
+</p>
+<ol>
+  <li>Gain exhaustive knowledge of the keystream biases.</li>
+  <li>Encrypt the unknown plaintext 2^30+ times under different keys.</li>
+  <li>Compare the ciphertext biases against the keystream biases.</li>
+</ol>
+<p>
+  Doing this requires deep knowledge of the biases for each byte of the
+  keystream. But it turns out we can do pretty well with just a few
+  useful biases - if we have some control over the plaintext.
+</p>
+<p>
+  How? By using knowledge of a single bias as a peephole into the
+  plaintext.
+</p>
+<p>
+  Decode this secret:
+</p>
+<pre>QkUgU1VSRSBUTyBEUklOSyBZT1VSIE9WQUxUSU5F</pre>
+<p>
+  And call it a cookie. No peeking!
+</p>
+<p>
+  Now use it to build this encryption oracle:
+</p>
+<pre>RC4(your-request || cookie, random-key)</pre>
+<p>
+  Use a fresh 128-bit key on every invocation.
+</p>
+<p>
+  Picture this scenario: you want to steal a user's secure cookie. You
+  can spawn arbitrary requests (from a malicious plugin or somesuch) and
+  monitor network traffic. (Ok, this is unrealistic - the cookie
+  wouldn't be right at the beginning of the request like that - this is
+  just an example!)
+</p>
+<p>
+  You can control the position of the cookie by requesting "/", "/A",
+  "/AA", and so on.
+</p>
+<p>
+  Build bias maps for a couple chosen indices (z16 and z32 are good) and
+  decrypt the cookie.
+</p>
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-7/index.html b/problems/set-7/index.html
new file mode 100644 (file)
index 0000000..b7ab762
--- /dev/null
@@ -0,0 +1,98 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Set 7 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/'>Set 7</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Crypto Challenge Set 7</h3>
+          <p>
+  This is <b>the first of two sets we generated after the original 6</b>.
+</p>
+<p>
+  Unlike the last few sets, <b>this set is a hodge-podge</b>. It also includes
+  some of the few challenges we have that probably aren't useful against
+  real targets (they were fun enough to include anyways). On the other
+  hand, we also include a challenge that models the CRIME attack on TLS.
+</p>
+<p>
+  This set is <b>hard</b>. There's a significant amount of programming,
+  and Wang's attack in particular is as difficult as anything we've done.
+</p>
+<ol start='49'>
+  <li>
+    <a href='/sets/7/challenges/49'>CBC-MAC Message Forgery</a>
+  </li>
+  <li>
+    <a href='/sets/7/challenges/50'>Hashing with CBC-MAC</a>
+  </li>
+  <li>
+    <a href='/sets/7/challenges/51'>Compression Ratio Side-Channel Attacks</a>
+  </li>
+  <li>
+    <a href='/sets/7/challenges/52'>Iterated Hash Function Multicollisions</a>
+  </li>
+  <li>
+    <a href='/sets/7/challenges/53'>Kelsey and Schneier's Expandable Messages</a>
+  </li>
+  <li>
+    <a href='/sets/7/challenges/54'>Kelsey and Kohno's Nostradamus Attack</a>
+  </li>
+  <li>
+    <a href='/sets/7/challenges/55'>MD4 Collisions</a>
+  </li>
+  <li>
+    <a href='/sets/7/challenges/56'>RC4 Single-Byte Biases</a>
+  </li>
+</ol>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file
diff --git a/problems/set-8/index.html b/problems/set-8/index.html
new file mode 100644 (file)
index 0000000..d521a37
--- /dev/null
@@ -0,0 +1,84 @@
+<html>
+  <head>
+    <meta content='text/html; charset=utf-8' http-equiv='content-type'>
+    <meta content='Thomas Ptacek, Sean Devlin, and Alex Balducci' name='author'>
+    <title>Set 8 - The Cryptopals Crypto Challenges</title>
+    <link href='/static/bootstrap.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='/static/app.css' media='all' rel='stylesheet' type='text/css'>
+    <link href='//cloud.typography.com/6817512/661724/css/fonts.css' rel='stylesheet' type='text/css'>
+    <link href='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.css' rel='stylesheet' type='text/css'>
+    <script src='//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js'></script>
+    <style>
+      body { 
+        padding: 20px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class='container'>
+      <div class='row'>
+        <div class='col-md-12'>
+          <h3>
+            <a href='/'>the cryptopals crypto challenges</a>
+          </h3>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-12'>
+          <ul class='breadcrumb'>
+            <li>
+              <a href='/'>Challenges</a>
+            </li>
+            <li>
+              <a href='/'>Set 8</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class='row'>
+        <div class='col-md-2'></div>
+        <div class='col-md-10'>
+          <h3>Crypto Challenge Set 8</h3>
+          <p>
+  This is <b>the second of two sets we generated after the original 6</b>.
+</p>
+<p>
+  This set focuses on abstract algebra, including DH, GCM, and (most
+  importantly) elliptic curve cryptography.
+
+  Fair warning - it's really tough! There's a ton of content here, and
+  it's more demanding than anything we've released so far. By the time
+  you're done, you will have written an ad hoc, informally-specified,
+  bug-ridden, slow implementation of one percent of SageMath.
+</p>
+<ol start='57'>
+  <li>Diffie-Hellman Revisited: Small Subgroup Confinement</li>
+  <li>Pollard's Method for Catching Kangaroos</li>
+  <li>Elliptic Curve Diffie-Hellman and Invalid-Curve Attacks</li>
+  <li>Single-Coordinate Ladders and Insecure Twists</li>
+  <li>Duplicate-Signature Key Selection in ECDSA (and RSA)</li>
+  <li>Key-Recovery Attacks on ECDSA with Biased Nonces</li>
+  <li>Key-Recovery Attacks on GCM with Repeated Nonces</li>
+  <li>Key-Recovery Attacks on GCM with a Truncated MAC</li>
+</ol>
+<p>
+  But wait, where are the actual challenges?! You'll need to mail in for them, just like in the original cryptopals. Send a mail to set#.cryptopals@gmail.com and make the subject "Crazy Flamboyant for the Rap Enjoyment".  BUT replace the # with the number of the set you want. Which would be 8. So replace it with 8.  
+</p>
+
+        </div>
+      </div>
+   </div>
+   <div style="text-align:center"><a href="https://cryptoservices.github.io/">Cryptography Services</a> | <a href="https://www.nccgroup.trust/us/">NCC Group</a></div>
+  </body>
+  <script>
+    /*var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-68682-6']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();*/
+  </script>
+</html>
\ No newline at end of file