<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>LAMBDAPHONE &#187; security</title>
	<atom:link href="http://coder.bsimmons.name/blog/tag/security/feed/" rel="self" type="application/rss+xml" />
	<link>http://coder.bsimmons.name/blog</link>
	<description>fragmentary ideas  ䷿  intellectual what-nots  ䷷  and haskell programming  ䷴</description>
	<lastBuildDate>Tue, 27 Jul 2010 16:58:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Cracking a Lock in Haskell with the De Bruijn sequence, pt. 1</title>
		<link>http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-1/</link>
		<comments>http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-1/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 04:14:59 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[Array]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[sequences]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=215</guid>
		<description><![CDATA[<p><em>Update: a more efficient variation is implemented in <a href="http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-2/">Part 2</a>.</em></p>
<p>A <a href="http://en.wikipedia.org/wiki/De_Bruijn_sequence">De Bruijn sequence</a> is (for example) a cyclical list of characters such that every word of a given length appears once and only once in the sequence.&#8230; <a href="http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-1/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p><em>Update: a more efficient variation is implemented in <a href="http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-2/">Part 2</a>.</em></p>
<p>A <a href="http://en.wikipedia.org/wiki/De_Bruijn_sequence">De Bruijn sequence</a> is (for example) a cyclical list of characters such that every word of a given length appears once and only once in the sequence. Instead of using letters, you can have a De Bruijn sequence of bits. For example here is one possibility for a sequence in which every 3-bit word appears somewhere (you have to wrap around from the end for the final &#8220;words&#8221;):</p>
<blockquote><p>00011101</p></blockquote>
<p>In a sense we compress a dictionary of 2^3 = 8 3-bit words (or 24 bits) to a sequence of only 2^3 = 8 bits. There are some very simple algorithms for generating these kinds of sequences of bits, and I will implement two here: the &#8220;<strong>prefer one</strong>&#8221; algorithm and a subtle variation called &#8220;<strong><a href="http://people.clarkson.edu/~aalhakim/Mypapers/PreferOpposite.pdf">prefer opposite</a>[PDF] by Alhakim</strong>&#8220;. Here is the author&#8217;s excellent description of the traditional Prefer One algorithm from the linked paper:</p>
<blockquote><p>&#8221; The prefer-one algorithm is a very simple method amazingly capable of generating a full cycle. For any positive integer n ≥ 1, the algorithm puts n zeroes, and proceeds after this by proposing 1 for the next bit and accepting it when the word formed by the last n bits has not been encountered previously in the sequence, otherwise 0 is placed. The algorithm stops when both 0 and 1 do not bring a new word.&#8221;</p></blockquote>
<p>And here is my haskell implementation. It works by creating a lazy array which we build from a list being generated by searching the earlier portions of the array that already have been defined. It&#8217;s very similar to the method I used in modeling the <a href="http://coder.bsimmons.name/blog/2009/06/fun-with-lazy-arrays-the-lz77-algorithm/">LZ77 algorithm</a>.:</p>
<p><blockquote class="vimblock"><br>
<span class="Type">module</span>&nbsp;Main<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span><br>
<br>
<span class="PreProc">import</span>&nbsp;Data.Array<br>
<span class="PreProc">import</span>&nbsp;Data.List(isInfixOf)<br>
<br>
<br>
<span class="Type">type</span>&nbsp;Bit&nbsp;<span class="Statement">=</span>&nbsp;<span class="Type">Bool</span><br>
<br>
preferOne&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">Int</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;[&nbsp;Bit&nbsp;]<br>
preferOne&nbsp;n&nbsp;<span class="Statement">=</span>&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">let</span>&nbsp;upB&nbsp;<span class="Statement">=</span>&nbsp;<span class="Constant">2</span><span class="Statement">^</span>n<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arr&nbsp;<span class="Statement">=</span>&nbsp;&nbsp;listArray&nbsp;(<span class="Constant">1</span>,&nbsp;upB)&nbsp;(<span class="Identifier">replicate</span>&nbsp;n&nbsp;<span class="Constant">False</span>&nbsp;<span class="Statement">++</span>&nbsp;rest)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- since we use Bool for bits, we can say (not.alreadySeen):</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rest&nbsp;&nbsp;<span class="Statement">=</span>&nbsp;&nbsp;<span class="Identifier">map</span>&nbsp;(<span class="Identifier">not</span>&nbsp;<span class="Statement">.</span>&nbsp;alreadySeen)&nbsp;[n<span class="Statement">+</span><span class="Constant">1</span>&nbsp;<span class="Statement">..</span>&nbsp;upB]<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alreadySeen&nbsp;i&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">or</span>&nbsp;<span class="Statement">$</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">do</span>&nbsp;<span class="Statement">let</span>&nbsp;range&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;arr<span class="Statement">!</span>i' <span class="Statement">|</span>&nbsp;i' <span class="Statement">&lt;-</span>&nbsp;[i<span class="Statement">-</span>n<span class="Statement">+</span><span class="Constant">1</span>&nbsp;<span class="Statement">..</span>&nbsp;i<span class="Statement">-</span><span class="Constant">1</span>]]&nbsp;<span class="Statement">++</span>&nbsp;[<span class="Constant">True</span>]&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i1&nbsp;<span class="Statement">&lt;-</span>&nbsp;[<span class="Constant">1</span><span class="Statement">..</span>i<span class="Statement">-</span>n]&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">let</span>&nbsp;rangeP&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;arr<span class="Statement">!</span>i' <span class="Statement">|</span>&nbsp;i' <span class="Statement">&lt;-</span>&nbsp;[i1&nbsp;<span class="Statement">..</span>&nbsp;i1<span class="Statement">+</span>n<span class="Statement">-</span><span class="Constant">1</span>]&nbsp;]<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Identifier">return</span>&nbsp;(range&nbsp;<span class="Statement">==</span>&nbsp;rangeP)<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- an infinite stream is returned... because I can:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">in</span>&nbsp;<span class="Identifier">cycle</span>&nbsp;(elems&nbsp;arr)<br>
<br></blockquote></p>
<p>The Prefer Opposite algorithm works on the same principle, but with a couple twists. In my words it is as follows:</p>
<blockquote><p>Start with n zeros. Search for successive bits as follows:</p>
<p>propose to place the bit that is different from the previous bit: if the word formed by this bit has not been seen already, then choose it, else choose the same bit as the last. When 2^3-1 bit have been written, write a 1 for the final bit. and you&#8217;re done. (you can also keep track of how long a string of ones has been written; the sequence will always end with <code>n</code> ones)</p></blockquote>
<p>Here is my implementation:</p>
<p><blockquote class="vimblock"><br>
preferOpposite&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">Int</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;[&nbsp;Bit&nbsp;]<br>
preferOpposite&nbsp;n&nbsp;<span class="Statement">=</span>&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">let</span>&nbsp;upB&nbsp;<span class="Statement">=</span>&nbsp;<span class="Constant">2</span><span class="Statement">^</span>n<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arr&nbsp;<span class="Statement">=</span>&nbsp;&nbsp;array&nbsp;(<span class="Constant">1</span>,&nbsp;upB)&nbsp;(final&nbsp;<span class="Statement">:</span>&nbsp;inits&nbsp;<span class="Statement">++</span>&nbsp;rest)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- we must specify the very last element of the sequence</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- which will always be a One:</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;final&nbsp;<span class="Statement">=</span>&nbsp;(upB,<span class="Constant">True</span>)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inits&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;(i,<span class="Constant">False</span>)&nbsp;<span class="Statement">|</span>&nbsp;i<span class="Statement">&lt;-</span>[<span class="Constant">1</span><span class="Statement">..</span>n]&nbsp;]<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rest&nbsp;&nbsp;<span class="Statement">=</span>&nbsp;&nbsp;<span class="Identifier">map</span>&nbsp;seqBit&nbsp;[n<span class="Statement">+</span><span class="Constant">1</span>&nbsp;<span class="Statement">..</span>&nbsp;upB<span class="Statement">-</span><span class="Constant">1</span>]<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- if the word generated by making the current bit the opposite</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- of the previous has already been seen, we make the bit the</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- same as the previous:</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seqBit&nbsp;i&nbsp;<span class="Statement">=</span>&nbsp;&nbsp;(i,&nbsp;nextB)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span>&nbsp;bP&nbsp;<span class="Statement">=</span>&nbsp;arr<span class="Statement">!</span>(i<span class="Statement">-</span><span class="Constant">1</span>)&nbsp;&nbsp;<span class="Comment">--previous bit</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nextB&nbsp;<span class="Statement">|</span>&nbsp;<span class="Identifier">or</span>&nbsp;(alreadySeen&nbsp;i&nbsp;bP)&nbsp;<span class="Statement">=</span>&nbsp;bP&nbsp;<span class="Comment">--same as previous</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;<span class="Identifier">otherwise</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;<span class="Identifier">not</span>&nbsp;bP&nbsp;<span class="Comment">--choose opposite </span><br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">--checks if the n-length string we would form by choosing the</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">--opposite for the next bit is already present in the array:</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alreadySeen&nbsp;i&nbsp;bP&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">do</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">let</span>&nbsp;range&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;arr<span class="Statement">!</span>i' <span class="Statement">|</span>&nbsp;i' <span class="Statement">&lt;-</span>&nbsp;[i<span class="Statement">-</span>n<span class="Statement">+</span><span class="Constant">1</span>&nbsp;<span class="Statement">..</span>&nbsp;i<span class="Statement">-</span><span class="Constant">1</span>]]&nbsp;<span class="Statement">++</span>&nbsp;[<span class="Identifier">not</span>&nbsp;bP]&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i1&nbsp;<span class="Statement">&lt;-</span>&nbsp;[<span class="Constant">1</span><span class="Statement">..</span>i<span class="Statement">-</span>n]&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">let</span>&nbsp;rangeP&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;arr<span class="Statement">!</span>i' <span class="Statement">|</span>&nbsp;i' <span class="Statement">&lt;-</span>&nbsp;[i1&nbsp;<span class="Statement">..</span>&nbsp;i1<span class="Statement">+</span>n<span class="Statement">-</span><span class="Constant">1</span>]&nbsp;]<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Identifier">return</span>&nbsp;(range&nbsp;<span class="Statement">==</span>&nbsp;rangeP)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">in</span>&nbsp;<span class="Identifier">cycle</span>&nbsp;(elems&nbsp;arr)<br>
<br></blockquote></p>
<p>Enough code for now, let&#8217;s talk about applications of the sequence. The most easily-approachable and interesting application to me applies to those keyed entry systems, such as electronic door locks, which accept a stream of keys (i.e. they unlock as soon as the correct key sequence is input, without any need to press an &#8220;enter&#8221; key). These mechanisms are very susceptible to attack with a De Bruijn sequence of key presses.</p>
<p>Since the above algorithms use a binary alphabet, as opposed to say a decimal one found on electronic keypads (check out <a href="http://alicebobandmallory.com/articles/2009/09/23/why-you-should-use-four-different-digits-for-keypad-locks">Jonas Elfström&#8217;s blog post</a> dealing with keypads with worn out letters for more on that), I will choose as my target an old-fashined garage door opener.</p>
<p>An old-style garage door opener remote has 8 binary <a href="http://en.wikipedia.org/wiki/Dip_switch">DIP switches</a> allowing 256 different code combinations. We will imagine the garage door is susceptible to a stream-based attack like the electronic lock we described.</p>
<p>We can model the garage door receiver as follows:</p>
<p><blockquote class="vimblock"><br>
<span class="Type">type</span>&nbsp;Combo&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;Bit&nbsp;]<br>
<span class="Type">type</span>&nbsp;Receiver&nbsp;<span class="Statement">=</span>&nbsp;Combo&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Type">Bool</span><br>
<br>
<span class="Comment">-- True means access granted</span><br>
programReceiver&nbsp;<span class="Statement">::</span>&nbsp;Combo&nbsp;<span class="Statement">-&gt;</span>&nbsp;Receiver<br>
programReceiver&nbsp;<span class="Statement">=</span>&nbsp;isInfixOf&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
<br></blockquote></p>
<p>Now let&#8217;s test out our model with this <code>main</code> function:</p>
<p><blockquote class="vimblock"><br>
main&nbsp;<span class="Statement">=</span>&nbsp;&nbsp;<span class="Statement">let</span>&nbsp;secretCode&nbsp;<span class="Statement">=</span>&nbsp;[<span class="Constant">False</span>,<span class="Constant">False</span>,<span class="Constant">True</span>,<span class="Constant">False</span>,<span class="Constant">True</span>,<span class="Constant">False</span>,<span class="Constant">True</span>,<span class="Constant">True</span>]<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;receiver&nbsp;<span class="Statement">=</span>&nbsp;programReceiver&nbsp;secretCode<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;crackingStream&nbsp;<span class="Statement">=</span>&nbsp;preferOne&nbsp;<span class="Constant">8</span><br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">in</span>&nbsp;<span class="Statement">if</span>&nbsp;receiver&nbsp;crackingStream<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">then</span>&nbsp;<span class="Identifier">print</span>&nbsp;<span class="Constant">&quot;WE'RE IN!&quot;</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">else</span>&nbsp;<span class="Identifier">print</span>&nbsp;<span class="Constant">&quot;...bugs&quot;</span><br>
<br></blockquote></p>
<p>Looks good!:</p>
<blockquote><p>
*Main> :main<br />
&#8220;WE&#8217;RE IN!&#8221;</p></blockquote>
<p>In the next couple posts I&#8217;ll explore improvements to the performance of these algorithms and maybe a few other things. </p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
