<?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>Brandon Sterne &#187; Programming</title>
	<atom:link href="http://brandon.sternefamily.net/posts/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://brandon.sternefamily.net/posts</link>
	<description>The Whole Brevity Thing</description>
	<lastBuildDate>Mon, 14 Mar 2011 22:52:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Moving to GitHub</title>
		<link>http://brandon.sternefamily.net/posts/2011/03/moving-to-github/</link>
		<comments>http://brandon.sternefamily.net/posts/2011/03/moving-to-github/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 21:24:35 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=483</guid>
		<description><![CDATA[GitHub is an amazing tool which holds a lot of promise for pushing open source software development forward. I say that because they make the process of forking someone else&#8217;s repository and then merging your changes (with their permission, of course) back into the master repo as simple as a few mouse clicks. I, for [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://github.com/">GitHub</a> is an amazing tool which holds a lot of promise for pushing open source software development forward.  I say that because they make the process of <a href="http://help.github.com/fork-a-repo/">forking</a> someone else&#8217;s repository and then <a href="http://help.github.com/pull-requests/">merging</a> your changes (with their permission, of course) back into the master repo as simple as a few mouse clicks.  I, for example, contributed a <a href="https://github.com/bsterne/jquery/commit/064060326c38b5f8593f97087c0ab65f098ace03">patch</a> that made jQuery <a href="https://developer.mozilla.org/en/Introducing_Content_Security_Policy">CSP</a>-compatible which was later pulled into the jQuery trunk.</p>
<p>Since GitHub has become the industry standard for sharing code, I&#8217;ve started the process of moving all of my open source tools to a <a href="https://github.com/bsterne/bsterne-tools">repository there</a>.  So far, I have only moved my <a href="http://brandon.sternefamily.net/posts/2007/12/python-cidr-block-converter/">Python CIDR block converter</a>, but the rest should follow soon!</p>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2011/03/moving-to-github/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Productivity music for work</title>
		<link>http://brandon.sternefamily.net/posts/2010/09/productivity-music-for-work/</link>
		<comments>http://brandon.sternefamily.net/posts/2010/09/productivity-music-for-work/#comments</comments>
		<pubDate>Wed, 08 Sep 2010 19:09:32 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=404</guid>
		<description><![CDATA[There are times at work when I like to put on my headphones and play some music (usually instrumental) or white noise to avoid distraction while I write code or do some other task that requires concentration. I never thought to do both at the same time&#8230; until now! Next time you want a nice [...]]]></description>
			<content:encoded><![CDATA[<p>There are times at work when I like to put on my headphones and play some <a href="http://www.pandora.com">music</a> (usually instrumental) or <a href="http://simplynoise.com/">white noise</a> to avoid distraction while I write code or do some other task that requires concentration.  I never thought to do both at the same time&#8230; until now!</p>
<p>Next time you want a nice anti-distraction music cocoon try opening in separate tabs:</p>
<ol>
<li>A nice <a href="http://www.pandora.com/stations/9f7394cb50f726dbdcd93d3cacefaa6e9d65bae90eaced8a">Jazz Piano</a> or <a href="http://www.pandora.com/stations/51c0d4684795ba6f71128bd1e22b7606ee56ad17f84d5fe3">Classical</a> station</li>
<li>A pleasant <a href="http://www.rainymood.com/">rainfall soundtrack</a></li>
</ol>
<p>If you are still distracted after that Google has <a href="https://health.google.com/health/ref/Attention+deficit+hyperactivity+disorder+(ADHD)">some information</a> that might help you.</p>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2010/09/productivity-music-for-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jetpack: Unread Messages in Gmail App Tab</title>
		<link>http://brandon.sternefamily.net/posts/2010/08/jetpack-unread-gmail-favicon/</link>
		<comments>http://brandon.sternefamily.net/posts/2010/08/jetpack-unread-gmail-favicon/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 18:20:05 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=395</guid>
		<description><![CDATA[One of the new features in Firefox 4 is the App Tab which lets users persist a tab that they use continuously. Firefox shrinks the tab down to just the favicon and places it in a special area for these tabs which generally aren&#8217;t closed by the user. The feature is great, but one of [...]]]></description>
			<content:encoded><![CDATA[<p>One of the new features in <a href="http://www.mozilla.com/en-US/firefox/beta/">Firefox 4</a> is the <a href="http://blog.mozilla.com/faaborg/2010/07/28/app-tabs-in-firefox-4-beta-2/">App Tab</a> which lets users persist a tab that they use continuously.  Firefox shrinks the tab down to just the favicon and places it in a special area for these tabs which generally aren&#8217;t closed by the user.  The feature is great, but one of the side effects is that Gmail App Tabs don&#8217;t show anymore the part of the <code>&lt;title></code> that indicates unread messages.</p>
<p>That&#8217;s where my new <a href="https://jetpack.mozillalabs.com/">Jetpack</a> (a cool new, lightweight (and secure!) way to write <a href="https://addons.mozilla.org/">Add-ons</a>) comes in.</p>
<p>Go install <a href="https://addons.mozilla.org/en-US/firefox/addon/216008/">Unread Gmail Favicon</a> from AMO and the favicon for that tab will indicate the number of unread messages when you have them like so:</p>
<p class="center"><a href="https://addons.mozilla.org/en-US/firefox/addon/216008/"><img src="http://brandon.sternefamily.net/posts/wp-content/uploads/2010/08/app-tab-closeup.png" alt="" title="Gmail Unread Favicon" width="185" height="139" class="aligncenter size-full wp-image-394" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2010/08/jetpack-unread-gmail-favicon/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Hacked my DEF CON 18 badge</title>
		<link>http://brandon.sternefamily.net/posts/2010/07/hacked-my-def-con-18-badge/</link>
		<comments>http://brandon.sternefamily.net/posts/2010/07/hacked-my-def-con-18-badge/#comments</comments>
		<pubDate>Sat, 31 Jul 2010 00:11:40 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=366</guid>
		<description><![CDATA[I was only able willing to stay for part of the first day of DEF CON this year, but I&#8217;m glad I did. One of the things they&#8217;ve done for the last five years or so is put microcontrollers in the badges, and put in little Easter eggs for people to search for. This year&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>I was only <del datetime="2010-07-30T23:36:03+00:00">able</del> willing to stay for part of the first day of <a href="http://www.defcon.org/html/defcon-18/dc-18-index.html">DEF CON</a> this year, but I&#8217;m glad I did.  One of the things they&#8217;ve done for the last five years or so is put microcontrollers in the badges, and put in little Easter eggs for people to search for.  This year&#8217;s had a Ninja Party mode which was locked by default, but you could unlock it by placing a series of 15 tumblers in the correct position.</p>
<p>They published the source code for the badges on the CD they gave out at registration (so perhaps I&#8217;m stupid for loading the CD on my laptop rather than smart for reverse engineering the badge).  I opened up DC18_Badge.c and, searching for &#8220;Ninja&#8221; (the code was commented nicely), quickly found the following two C functions:</p>
<pre class="brush: cpp; gutter: false">
/**************************************************************/
/* NINJA ROUTINES
/**************************************************************/

int dc18_ninja_validate(uint32_t val)
{
    uint16_t a, b;

    a = (uint16_t)(val &#038; 0xfff);
    b = (uint16_t)(val >> 12);

    if((a ^ b) == 0x916)
    {
        return 1;
    }
    return 0;
}

// encode tumbler states into 24-bit value
uint32_t dc18_encode_tumblers(tumbler_state_type *tumblers)
{
    uint32_t x = 0, j = 1;
    uint16_t i;

    for(i = 0; i < TUMBLERS_PER_IMAGE; i++)
    {
        x += tumblers[i] * j;
        j *= 3;
    }

    return x;
}
</pre>
<p>So the trick was to find the number that made <code>(a ^ b) == 0x916</code> and then figure out the tumbler positions to represent that number.  I wrote two small Python functions to automate those tasks.  To find the number that would unlock Ninja Mode, I wrote this loop.  I added a print statement to show how far into the search we were, thinking it might take some time to find it, but it popped out 6423 in no time at all:
<pre class="brush: python; gutter: false">while 1:
	a = i &#038; 0xfff
	b = i >> 12
	if i % 10000 == 0:
		print "# a: %d, b: %d, i: %d" % (a, b, i)
	if a ^ b == 0x916:
		print "DONE: %d" % (i)
		break
	i += 1

DONE: 6423
</pre>
<p>Now all that was left was to figure out the tumbler positions to represent 6423.  Clearly, <code>dc18_encode_tumblers</code> tells us how to do that.  I whipped up this little function to convert the tumbler positions to a decimal number:</p>
<pre class="brush: python; gutter: false">def enc_tumblers(tum):
	x = 0; j = 1;
	for i in range(15):
		x += tum[i] * j
		j *= 3
	return x

>>> enc_tumblers([1,1,1,1,1,2,2,2,0,0,0,0,0,0,0])
6439
</pre>
<p>I was going to write another loop to increment the tumbler array I was passing to <code>enc_tumblers</code>, but my first guess was so close that I just manually entered the settings until I found the winning configuration:</p>
<pre class="brush: python; gutter: false">>>> enc_tumblers([0,2,2,0,1,2,2,2,0,0,0,0,0,0,0])
6423
</pre>
<p>Once I had the configuration, I put the tumblers in the appropriate positions: 0 - up, 1 - middle, 2 - down.  After that, well, I guess I'm a ninja now:</p>
<p><a href="http://brandon.sternefamily.net/posts/wp-content/uploads/2010/07/def-con.jpg"><img src="http://brandon.sternefamily.net/posts/wp-content/uploads/2010/07/def-con.jpg" alt="" title="Ninja Party Unlocked" width="80%" class="aligncenter size-full wp-image-380" /></a><br />
<script type="text/javascript" src="/posts/syntax/src/shCore.js"></script><br />
<script type="text/javascript" src="/posts/syntax/scripts/shBrushCpp.js"></script><br />
<script type="text/javascript" src="/posts/syntax/scripts/shBrushPython.js"></script></p>
<link rel="stylesheet" type="text/css" href="/posts/syntax/styles/shCore.css" />
<link type="text/css" rel="Stylesheet" href="/posts/syntax/styles/shThemeDefault.css"/>
<script type="text/javascript">SyntaxHighlighter.all()</script></p>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2010/07/hacked-my-def-con-18-badge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sharing Links</title>
		<link>http://brandon.sternefamily.net/posts/2010/05/sharing-links/</link>
		<comments>http://brandon.sternefamily.net/posts/2010/05/sharing-links/#comments</comments>
		<pubDate>Fri, 28 May 2010 16:23:50 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=320</guid>
		<description><![CDATA[Sometimes I make a tool that I use for a while and then wonder if it&#8217;s something others will find useful too. Here&#8217;s one of them&#8230; For a while I was sharing links on my home page by linking to the feed of stories I&#8217;ve upvoted on Reddit, but that has become less satisfying as [...]]]></description>
			<content:encoded><![CDATA[<style type="text/css">
a.bookmarklet {
  text-decoration: none;
  border: 1px solid #bbb;
  margin: 1em;
  padding: .5em;
  -moz-border-radius: .5em;
  -webkit-border-radius: .5em;
}
</style>
<p style="margin:0 2em"><em>Sometimes I make a tool that I use for a while and then wonder if it&#8217;s something others will find useful too.  Here&#8217;s one of them&#8230;</em></p>
<p>For a while I was sharing links on my home page by linking to the feed of stories I&#8217;ve <a href="http://www.reddit.com/user/jackthecoiner/liked/">upvoted on Reddit</a>, but that has become less satisfying as Reddit dumbs itself down each day (the same thing that happened to Digg a few years earlier).  I decided to make my own link-sharing program that I could use by just clicking a <a href="http://en.wikipedia.org/wiki/Bookmarklet">bookmarklet</a> whenever I was on a page I wanted to share.</p>
<p>It is a very simple program that stores the links in a flat text file and uses <a href="http://www.w3.org/TR/cors/#access-control-allow-origin-response-hea">CORS</a> to allow the bookmarklet to POST data to it from across domains.  You can put the files in a directory on your server and use this simple bookmarklet to share links:</p>
<p style="margin:1em; font-size:80%">Drag this to your bookmarks toolbar: <a href='javascript:var shareUrl = "http://your.server/share/index.php"; var pw = "p@ssword";  function createXHR() {   if (window.XMLHttpRequest) {     return new XMLHttpRequest();   }   else if (window.ActiveXObject) {     return new ActiveXObject("Microsoft.XMLHTTP");   }   else {     return null;   } }  function handleResponse() {   if (http.readyState == 4 &#038;&#038; http.status == 200) {     var response = http.responseText;     if (response.length)       alert(response);   } }  var text = prompt("Enter Link Text", document.title);  if (text != "" &#038;&#038; text != null) {   var url = window.location.href;   var params = "text=" + escape(text) + "&#038;url=" + escape(url) + "&#038;pw=" + pw;    var http = createXHR();   http.open("POST", shareUrl, true);   http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");   http.onreadystatechange = handleResponse;   http.send(params); }' class="bookmarklet">Share This</a></p>
<div class="middleBlock">
<p>You can check out the <a href="/files/share/index.txt">server code</a> or the <a href="/files/share/bookmarklet.js">bookmarklet source</a>, or you can download the <a href="/files/share.zip">zip archive</a> and extract the files on your server.</p>
</div>
<p>When you fetch the server script with GET you get back a <a href="/share/index.php?format=json">JSON</a> or <a href="/share/index.php?format=rss">RSS</a> feed depending on the <code>format</code> parameter you pass.</p>
<p>Make sure the password in the bookmarklet stays synced with the password in the server file and change them to something secure.</p>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2010/05/sharing-links/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A-Star (A*) Algorithm in Python &#8211; Update</title>
		<link>http://brandon.sternefamily.net/posts/2010/01/a-star-a-algorithm-in-python-update/</link>
		<comments>http://brandon.sternefamily.net/posts/2010/01/a-star-a-algorithm-in-python-update/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 17:04:38 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=160</guid>
		<description><![CDATA[Since there have been many requests over the years for the source code referenced in my A-Star (A*) Algorithm post, I decided to share it. I did a bit of refactoring too, as I have learned some neat things about Python in the years since I wrote that post, like list comprehensions. A cautionary note [...]]]></description>
			<content:encoded><![CDATA[<p>Since there have been many requests over the years for the source code referenced in my <a href="/posts/2005/02/a-star-algorithm-in-python/">A-Star (A*) Algorithm</a> post, I decided to share it.  I did a bit of refactoring too, as I have learned some <a href="/posts/2006/11/8-reasons-why-python-rocks/">neat things about Python</a> in the years since I wrote that post, like <a href="http://docs.python.org/tutorial/datastructures.html#list-comprehensions">list comprehensions</a>.</p>
<p>A cautionary note to undergrad CS students (who I can only assume are the requestors): CS professors are pretty good at catching cheaters, so learn from others&#8217; code, but write your own.</p>
<div class="middleBlock center">
<p>Source: <a href="/files/astar.txt">astar.py</a></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2010/01/a-star-a-algorithm-in-python-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python AES Implementation &#8211; Update</title>
		<link>http://brandon.sternefamily.net/posts/2009/04/python-aes-update/</link>
		<comments>http://brandon.sternefamily.net/posts/2009/04/python-aes-update/#comments</comments>
		<pubDate>Sat, 04 Apr 2009 15:55:16 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=115</guid>
		<description><![CDATA[I fixed two bugs in my AES implementation. The first was a padding bug which resulted in the loss of up to a block of data when decrypting certain ciphertexts. The second bug was a more serious security problem caused by the use of a static initialization vector.]]></description>
			<content:encoded><![CDATA[<p>I fixed two bugs  in my <a href="/posts/2007/06/aes-tutorial-python-implementation/">AES implementation</a>.  The first was a padding bug which resulted in the loss of up to a block of data when decrypting certain ciphertexts.  The second bug was a more serious security problem caused by the use of a static initialization vector.</p>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2009/04/python-aes-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python CIDR Block Converter</title>
		<link>http://brandon.sternefamily.net/posts/2007/12/python-cidr-block-converter/</link>
		<comments>http://brandon.sternefamily.net/posts/2007/12/python-cidr-block-converter/#comments</comments>
		<pubDate>Fri, 14 Dec 2007 15:26:40 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=103</guid>
		<description><![CDATA[I wrote a <a href="/posts/2007/12/python-cidr-block-converter/">Python script that converts a CIDR Block</a> into a list of individual IP addresses, one-per-line.]]></description>
			<content:encoded><![CDATA[<p>I wrote a Python script that converts a <a href="http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing">CIDR Block</a> into a list of individual IP addresses, one-per-line.  I found that I needed to repeat some network-related tasks across an entire subnet, and this script provides an easy way to automate these kinds of tasks in a <a href="http://en.wikipedia.org/wiki/Shell_%28computing%29">shell environment</a>.  The source code and sample usage for the script follow:</p>
<div style="border:1px dashed #000; background-color:rgb(240,240,240); padding:5px; width:90%; margin:1em auto;">
<p><b>Source Code: </b><a href="https://github.com/bsterne/bsterne-tools/blob/master/cidr/cidr.py">cidr.py</a></p>
<p><b>Sample Usage:</b></p>
<pre class="brush: bash; gutter: false">brandon@zodiac ~ $ cidr 192.168.1.5/30
192.168.1.4
192.168.1.5
192.168.1.6
192.168.1.7</pre>
</div>
<p>One item to note is a key difference between the way this program computes a CIDR block and others I have seen.  The lazy way to convert a CIDR block to a list of IPs is to calculate the number of IP addresses in the subnet, <span class="code">(2^(32 &#8211; $subnetSize))</span>, and simply increment the base IP address that number of times.  This method is deficient because, as in the example usage above, the base IP address that is specified may fall somewhere in the middle of the range of IP addresses (not necessarily at the beginning).</p>
<p>In my script, I calculate the CIDR block members the correct way.  I am converting the base IP address to its binary form, zeroing-out the number of least significant bits as specified in the subnet size, and starting the enumeration of IP addresses at the bottom of that range.</p>
<p><script type="text/javascript" src="/posts/syntax/src/shCore.js"></script><br />
<script type="text/javascript" src="/posts/syntax/scripts/shBrushBash.js"></script></p>
<link rel="stylesheet" type="text/css" href="/posts/syntax/styles/shCore.css" />
<link type="text/css" rel="Stylesheet" href="/posts/syntax/styles/shThemeDefault.css"/>
<script type="text/javascript">SyntaxHighlighter.all()</script></p>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2007/12/python-cidr-block-converter/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>AES Tutorial / Python Implementation</title>
		<link>http://brandon.sternefamily.net/posts/2007/06/aes-tutorial-python-implementation/</link>
		<comments>http://brandon.sternefamily.net/posts/2007/06/aes-tutorial-python-implementation/#comments</comments>
		<pubDate>Mon, 11 Jun 2007 04:51:50 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=91</guid>
		<description><![CDATA[I put together a series of slides as well as a <a href="/posts/2007/06/aes-tutorial-python-implementation/" title="AES Tutorial">Python implementation of AES</a>, the symmetric-key cryptosystem.]]></description>
			<content:encoded><![CDATA[<style type="text/css">
p.title {
	margin-top:0;
	text-align:center;
	font-weight:600;
	width: 100%;
	color:white;
	background-color:rgb(0,0,128);
}
.middleblock li {
	margin-bottom:.5em
}
ul li.indent0 {
	margin-left:0;
	margin-bottom:.5em
}
ul li.indent1 {
	margin-left:1em;
	list-style:circle;
	margin-bottom:.5em
}
ul li.indent2 {
	margin-left:1.5em;
	list-style:disc;
	margin-bottom:.5em
}
ul li.indent3 {
	margin-left:2em;
	list-style:none;
	margin-bottom:.5em
}
ol li.indent0 {
	margin:0;
	margin-bottom:.5em
}
.code {
	font-family:monospace;
	white-space:pre;
}
</style>
<div class="middleBlock">
<p><b>Update: 04-Apr-2009</b></p>
<p>I fixed two bugs in my AES implementation pointed out to me by <a href="http://www.ics.uci.edu/~jcarlson/">Josiah Carlson</a>.  First, I was failing to pad properly files whose length was an even multiple of the block size.  In those cases, bytes would be lost upon decrypting the file.  Josiah also pointed out that I was using a static <a href="http://en.wikipedia.org/wiki/Initialization_vector">IV</a>, which leaks information about messages which share common prefixes.  This is a serious security bug and I was glad to have it pointed out.</p>
<p>Feel free to check out the <a href="/files/pyAES_patch">changes</a> I made or simply download the <a href="/files/pyAES.txt">updated script</a>.</p>
</div>
<p>I&#8217;ve put together a series of slides as well as a Python implementation of AES, the symmetric-key cryptosystem.</p>
<div style="border: 1px dashed #000; background-color:rgb(240,240,240); padding:10px; margin:auto;">
<p style="text-align:center"><b>Source:</b> <a href="/files/pyAES.txt">pyAES.py</a></p>
<p><b>Sample Usage:</b> (color added for clarity)</p>
<p class="code" style="text-align:left">[brandon@zodiac pyAES]$ cat > testfile.txt<br />
<span style="color:#00b000">The sky was the color of television tuned to a dead channel.</span><br />
[brandon@zodiac pyAES]$ ./pyAES.py -e testfile.txt -o testfile_encrypted.txt<br />
Password:<br />
Encrypting file: testfile.txt<br />
Encryption complete.<br />
[brandon@zodiac pyAES]$ ./pyAES.py -d testfile_encrypted.txt -o testfile_decrypted.txt<br />
Password:<br />
Decrypting file: testfile_encrypted.txt<br />
Decryption complete.<br />
[brandon@zodiac pyAES]$ cat testfile_decrypted.txt<br />
<span style="color:#00b000">The sky was the color of television tuned to a dead channel.</span><br />
[brandon@zodiac pyAES]$ md5sum *<br />
19725cef7495fd55540728759a6262c8  pyAES.py<br />
<span style="color:#00b000">2fffc9072a7c09f4f97862c0bceb6021  testfile_decrypted.txt</span><br />
<span style="color:#b00000">3e57070eaf1b4adf7f43b38e1c5ee631  testfile_encrypted.txt</span><br />
<span style="color:#00b000">2fffc9072a7c09f4f97862c0bceb6021  testfile.txt</span>
</p>
</div>
<p>					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">Symmetric Key Cryptography</p>
<ul>
<li class="indent0">Identical keys used to encrypt/decrypt messages</li>
<li class="indent0">Can be implemented as block ciphers or stream ciphers</li>
</ul>
<p>					<b>Strengths:</b></p>
<ul>
<li class="indent0">Speed</li>
<li class="indent1">Much less computationally intensive than public-key crypto</li>
<li class="indent0">Easy to implement in hardware as well as software</li>
</ul>
<p>					<b>Weaknesses:</b></p>
<ul>
<li class="indent0">Key Management</li>
<li class="indent1"><em>n</em> users require <em>n</em>(<em>n</em>-1)/2 keys for all to communicate</li>
<li class="indent1">secure key distribution is a challenge</li>
<li class="indent0">Cannot be used (directly) for authentication or non-repudiation</li>
</ul></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES &#8211; The Advanced Encryption Standard</p>
<ul>
<li class="indent0">Rijndael algorithm invented by Joan Daemen and Vincent Rijmen and selected as AES winner by NIST in 2001</li>
<li class="indent0">AES uses fixed block size of 128-bits and key sizes of 128, 192 or 256 bits (though Rijndael specification allows for variable block and key sizes)</li>
<li class="indent0">Most of the calculations in AES are performed within a finite field</li>
<li class="indent1">There are a finite number of elements within the field and all operations on those elements result in an element also contained in the field</li>
</ul></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES Operations</p>
<ul>
<li class="indent0">AES operates on a 4&#215;4 matrix referred to as the <em>state</em></li>
<li class="indent1">16 bytes == 128 bits == block size</li>
<li class="indent0">All operations in a round of AES are invertible</li>
<li class="indent1">AddRoundKey &#8211; each byte of the round key is combined with the corresponding byte in the state using XOR</li>
<li class="indent1">SubBytes &#8211; each byte in the state is replaced with a different byte according to the S-Box lookup table</li>
<li class="indent1">ShiftRows &#8211; each row in the state table is shifted by a varying number of bytes</li>
<li class="indent1">MixColumns &#8211; each column in the state table is multiplied with a fixed polynomial</li>
</ul></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES Operation &#8211; AddRoundKey</p>
<ul>
<li class="indent0">Each byte of the round key is XORed with the corresponding byte in the state table</li>
<li class="indent0">Inverse operation is identical since XOR a second time returns the original values</li>
</ul>
<pre class="brush: python; gutter: false"># XOR each byte of the roundKey with the state table
def addRoundKey(state, roundKey):
    for i in range(len(state)):
        state[i] = state[i] ^ roundKey[i]</pre>
</p></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES Operation &#8211; SubBytes</p>
<ul>
<li class="indent0">Each byte of the state table is substituted with the value in the S-Box whose index is the value of the state table byte</li>
<li class="indent0">Provides non-linearity (algorithm not equal to the sum of its parts)</li>
<li class="indent0">Inverse operation is performed using the inverted S-Box</li>
</ul>
<pre class="brush: python; gutter: false"># do sbox transform on each of the values in the state table
def subBytes(state):
    for i in range(len(state)):
        state[i] = sbox[state[i]]

# sbox transformations are invertible
>>> sbox[237]
85
>>> sboxInv[85]
237
>>> sbox[55]
154
>>> sbox[154]
184
>>> sboxInv[184]
154
>>> sboxInv[154]
55</pre>
</p></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES Operation &#8211; ShiftRows</p>
<ul>
<li class="indent0">Each row in the state table is shifted left by the number of bytes represented by the row number</li>
<li class="indent0">Inverse operation simply shifts each row to the right by the number of bytes as the row number</li>
</ul>
<pre class="brush: python; gutter: false"># returns a copy of the word shifted n bytes (chars) positive
# values for n shift bytes left, negative values shift right
def rotate(word, n):
    return word[n:]+word[0:n]

# iterate over each "virtual" row in the state table
# and shift the bytes to the LEFT by the appropriate
# offset
def shiftRows(state):
    for i in range(4):
        state[i*4:i*4+4] = rotate(state[i*4:i*4+4],i)</pre>
</p></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES Operation &#8211; MixColumns</p>
<ul>
<li class="indent0">MixColumns is performed by multiplying each column (within the <a href="http://en.wikipedia.org/wiki/Rijndael_Galois_field">Galois finite field</a>) by the following matrix:</li>
</ul>
<p>					<img src="images/aes_mix_columns_matrix.png" alt="" /></p>
<ul>
<li class="indent0">The inverse operation is performed by multiplying each column by the following inverse matrix:</li>
</ul>
<p>					<img src="images/aes_mix_columns_inv_matrix.png" alt="" /></p>
<pre class="brush: python; gutter: false"># Galois Multiplication
def galoisMult(a, b):
    p = 0
    hiBitSet = 0
    for i in range(8):
        if b &amp; 1 == 1:
            p ^= a
        hiBitSet = a &amp; 0x80
        a &lt;&lt;= 1
        if hiBitSet == 0x80:
            a ^= 0x1b
        b &gt;&gt;= 1
    return p % 256

# mixColumn does Galois multiplication on a state column
def mixColumn(column):
    temp = copy(column)
    column[0] = galoisMult(temp[0],2) ^ galoisMult(temp[3],1) ^ \
                galoisMult(temp[2],1) ^ galoisMult(temp[1],3)
    column[1] = galoisMult(temp[1],2) ^ galoisMult(temp[0],1) ^ \
                galoisMult(temp[3],1) ^ galoisMult(temp[2],3)
    column[2] = galoisMult(temp[2],2) ^ galoisMult(temp[1],1) ^ \
                galoisMult(temp[0],1) ^ galoisMult(temp[3],3)
    column[3] = galoisMult(temp[3],2) ^ galoisMult(temp[2],1) ^ \
                galoisMult(temp[1],1) ^ galoisMult(temp[0],3)</pre>
</p></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES &#8211; Pulling It All Together</p>
<p>					The AES Cipher operates using a varying <b>number of rounds</b>, based on the size of the <b>cipher key</b>.</p>
<ul>
<li class="indent0">A <b>round</b> of AES consists of the four operations performed in succession: AddRoundKey, SubBytes, ShiftRows, and MixColumns (MixColumns is omitted in the final round)</li>
<li class="indent0">128-bit key &rarr; rounds, 192-bit key &rarr; 12 rounds, 256-bit key &rarr; 14 rounds</li>
<li class="indent0">The AES cipher key is expanded according to the Rijndael key schedule and a different part of the expanded key is used for each round of AES</li>
<li class="indent1">The expanded key will be of length <b>(block size * num rounds+1)</b></li>
<li class="indent1">128-bit cipher key expands to 176-byte key</li>
<li class="indent1">192-bit cipher key expands to 208-byte key</li>
<li class="indent1">256-bit cipher key expands to 240-byte key</li>
</ul></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES &#8211; Key Expansion Operations</p>
<p>					AES key expansion consists of several primitive operations:</p>
<ol>
<li class="indent0">Rotate &#8211; takes a 4-byte word and rotates everything one byte to the left, e.g. <span style="code">rotate([1,2,3,4]) &rarr; [2, 3, 4, 1]</span></li>
<li class="indent0">SubBytes &#8211; each byte of a word is substituted with the value in the S-Box whose index is the value of the original byte</li>
<li class="indent0">Rcon &#8211; the first byte of a word is XORed with the <b>round constant</b>.  Each value of the Rcon table is a member of the Rinjdael finite field.</li>
</ol>
<pre class="brush: python; gutter: false"># takes 4-byte word and iteration number
def keyScheduleCore(word, i):
    # rotate word 1 byte to the left
    word = rotate(word, 1)
    newWord = []
    # apply sbox substitution on all bytes of word
    for byte in word:
        newWord.append(sbox[byte])
    # XOR the output of the rcon[i] transformation with the first part
    # of the word
    newWord[0] = newWord[0]^rcon[i]
    return newWord</pre>
</p></div>
<p>					<!-- end Slide --></p>
<p>					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES &#8211; Key Expansion Algorithm (256-bit)</p>
<p>					Pseudo-code for AES Key Expansion:</p>
<ol>
<li class="indent0 code"><b>expandedKey</b>[0:32] &rarr; <b>cipherKey</b>[0:32]  # copy first 32 bytes of cipher key to expanded key</li>
<li class="indent0 code"><b>i</b> &rarr; 1  # Rcon iterator</li>
<li class="indent0 code"><b>temp</b> = byte[4]  # 4-byte container for temp storage</li>
<li class="indent0 code">while size(<b>expandedKey</b>) &lt; 240<br />
    <b>temp</b> &rarr; last 4 bytes of <b>expandedKey</b></p>
<p>    # every 32 bytes apply core schedule to temp<br />
    if size(<b>expandedKey</b>)%32 == 0<br />
        <b>temp</b> = keyScheduleCore(<b>temp</b>, <b>i</b>)<br />
        <b>i</b> &rarr; <b>i</b> + 1<br />
    # since 256-bit key -> add an extra sbox transformation to each new byte<br />
    for <b>j</b> in range(4):<br />
        <b>temp</b>[<b>j</b>] = <b>sbox</b>[<b>temp</b>[<b>j</b>]]<br />
    # XOR temp with the 4-byte block 32 bytes before the end of the current expanded key.<br />
    # These 4 bytes become the next bytes in the expanded key<br />
    <b>expandedKey</b>.append( <b>temp</b> XOR <b>expandedKey</b>[size(<b>expandedKey</b>)-32:size(<b>expandedKey</b>)-28]</li>
</ol>
<p>					Another function to note&#8230;</p>
<pre class="brush: python; gutter: false"># returns a 16-byte round key based on an expanded key and round number
def createRoundKey(expandedKey, n):
    return expandedKey[(n*16):(n*16+16)]</pre>
</p></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES &#8211; Encrypting a Single Block</p>
<ol>
<li class="indent0"><b>state</b> &rarr; block of plaintext    # 16 bytes of plaintext are copied into the state</li>
<li class="indent0"><b>expandedKey</b> = expandKey(<b>cipherKey</b>)    # create 240-bytes of key material to be used as round keys</li>
<li class="indent0"><b>roundNum</b> &rarr; 0    # counter for which round number we are in</li>
<li class="indent0"><b>roundKey</b> &rarr; createRoundKey(<b>expandedKey</b>, <b>roundNum</b>)</li>
<li class="indent0">addRoundKey(<b>state</b>, <b>roundKey</b>)    # each byte of state is XORed with the present roundKey</li>
<li class="indent0">while <b>roundNum</b> &lt; 14   # 14 rounds in AES-256<br />
    <b>roundKey</b> &rarr; createRoundKey(<b>expandedKey</b>, <b>roundNum</b>)<br />
    # round of AES consists of 1. subBytes, 2. shiftRows, 3. mixColumns, and 4. addRoundKey<br />
    aesRound(<b>state</b>, <b>roundKey</b>)<br />
    <b>roundNum</b> &rarr; <b>roundNum</b> + 1</li>
<li class="indent0"># for the last round leave out the mixColumns operation<br />
    <b>roundKey</b> = createRoundKey(<b>expandedKey</b>, <b>roundNum</b>)<br />
    subBytes(<b>state</b>)<br />
    shiftRows(<b>state</b>)<br />
    addRoundKey(<b>state</b>)</li>
<li class="indent0">return <b>state</b> as block of ciphertext</li>
</ol></div>
<p>					<!-- end Slide --><br />
					<!-- begin Slide --></p>
<div class="middleBlock">
<p class="title">AES &#8211; Encrypting a Single Block (Demo)</p>
<pre class="brush: python; gutter: false">
>>> key = passwordToKey("s0m3_p@ssw0rD")
>>> key
[62, 142, 78, 2, 164, 231, 18, 196, 148, 177, 82, 186, 240, 44, 136, 242,
23, 13, 20, 169, 248, 69, 163, 79, 13, 155, 97, 200, 241, 15, 76, 15]
>>> plaintext = textToBlock("Hiro Protagonist")
>>> plaintext
[72, 105, 114, 111, 32, 80, 114, 111, 116, 97, 103, 111, 110, 105, 115, 116]
>>> blockToText(plaintext)
'Hiro Protagonist'
>>> ciphertext = aesEncrypt(plaintext, key)

*** aesMain ***
initial state:
[72, 105, 114, 111, 32, 80, 114, 111, 116, 97, 103, 111, 110, 105, 115, 116]
state after adding roundKey0:
[118, 231, 60, 109, 132, 183, 96, 171, 224, 208, 53, 213, 158, 69, 251, 134]

*** AES Round1 ***
state after subBytes:
[56, 148, 235, 60, 95, 169, 208, 98, 225, 112, 150, 3, 11, 110, 15, 68]
state after shiftRows:
[56, 148, 235, 60, 169, 208, 98, 95, 150, 3, 225, 112, 68, 11, 110, 15]
state after mixColumns:
[66, 80, 228, 230, 148, 33, 121, 29, 106, 95, 226, 146, 255, 98, 121, 117]
state after addRoundKey:
[85, 93, 240, 79, 108, 100, 218, 82, 103, 196, 131, 90, 14, 109, 53, 122]

&lt;-- SNIP --&gt;

*** AES Round 14 (final) ***
state after subBytes:
[0, 229, 171, 70, 93, 137, 135, 251, 99, 182, 88, 166, 228, 229, 251, 97]
state after shiftRows:
[0, 229, 171, 70, 137, 135, 251, 93, 88, 166, 99, 182, 97, 228, 229, 251]
state after addRoundKey:
[195, 123, 205, 183, 213, 202, 50, 223, 223, 164, 99, 86, 126, 34, 107, 142]

>>> ciphertext
[195, 123, 205, 183, 213, 202, 50, 223, 223, 164, 99, 86, 126, 34, 107, 142]

>>> blockToText(ciphertext)
'\xc3{\xcd\xb7\xd5\xca2\xdf\xdf\xa4cV~"k\x8e'
>>> cleartext = aesDecrypt(ciphertext, key)

*** aesMainInv ***
initial state:
[195, 123, 205, 183, 213, 202, 50, 223, 223, 164, 99, 86, 126, 34, 107, 142]

*** AES Round 14 ***
state after addRoundKey:
[0, 229, 171, 70, 137, 135, 251, 93, 88, 166, 99, 182, 97, 228, 229, 251]
state after shiftRowsInv:
[0, 229, 171, 70, 93, 137, 135, 251, 99, 182, 88, 166, 228, 229, 251, 97]
state after subBytesInv:
[82, 42, 14, 152, 141, 242, 234, 99, 0, 121, 94, 197, 174, 42, 99, 216]

&lt;-- SNIP --&gt;

*** AES Round 0 (final) ***
state after adding roundKey0:
[72, 105, 114, 111, 32, 80, 114, 111, 116, 97, 103, 111, 110, 105, 115, 116]
>>> cleartext
[72, 105, 114, 111, 32, 80, 114, 111, 116, 97, 103, 111, 110, 105, 115, 116]
>>> blockToText(cleartext)
'Hiro Protagonist'</pre>
</p></div>
<p>					<!-- end Slide --></p>
<p><script type="text/javascript" src="/posts/syntax/src/shCore.js"></script><br />
<script type="text/javascript" src="/posts/syntax/scripts/shBrushPython.js"></script></p>
<link rel="stylesheet" type="text/css" href="/posts/syntax/styles/shCore.css" />
<link type="text/css" rel="Stylesheet" href="/posts/syntax/styles/shThemeDefault.css"/>
<script type="text/javascript">SyntaxHighlighter.all()</script></p>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2007/06/aes-tutorial-python-implementation/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Programming Skills Test</title>
		<link>http://brandon.sternefamily.net/posts/2007/04/programming-skills-test/</link>
		<comments>http://brandon.sternefamily.net/posts/2007/04/programming-skills-test/#comments</comments>
		<pubDate>Tue, 17 Apr 2007 04:44:43 +0000</pubDate>
		<dc:creator>bsterne</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://brandon.sternefamily.net/posts/?p=88</guid>
		<description><![CDATA[This site is not of my creation but it is the type of website I&#8217;ve wished for for quite a while and have considered creating more than once. Project Euler hosts a series of math / computer programming problems that let a coder test his or her skills. As of 4/16/07, I&#8217;ve completed the first [...]]]></description>
			<content:encoded><![CDATA[<p>This site is not of my creation but it is the type of website I&#8217;ve wished for for quite a while and have considered creating more than once.  <a href="http://www.projecteuler.net/">Project Euler</a> hosts a series of math / computer programming problems that let a coder test his or her skills.  As of 4/16/07, I&#8217;ve completed the first 14 problems.</p>
]]></content:encoded>
			<wfw:commentRss>http://brandon.sternefamily.net/posts/2007/04/programming-skills-test/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

