<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Noah Moroze on Medium]]></title>
        <description><![CDATA[Stories by Noah Moroze on Medium]]></description>
        <link>https://medium.com/@noahmoroze?source=rss-187b19d04a29------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*DXNy3Kd7On-YODFJvfDnxQ.jpeg</url>
            <title>Stories by Noah Moroze on Medium</title>
            <link>https://medium.com/@noahmoroze?source=rss-187b19d04a29------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Tue, 07 Apr 2026 04:06:26 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@noahmoroze/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Experiments with the CM1K Neural Net Chip]]></title>
            <link>https://medium.com/data-science/experiments-with-the-cm1k-neural-net-chip-32b2d5ca723b?source=rss-187b19d04a29------2</link>
            <guid isPermaLink="false">https://medium.com/p/32b2d5ca723b</guid>
            <category><![CDATA[towards-data-science]]></category>
            <category><![CDATA[pattern-recognition]]></category>
            <category><![CDATA[raspberry-pi]]></category>
            <category><![CDATA[cm1k]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[Noah Moroze]]></dc:creator>
            <pubDate>Sun, 23 Jul 2017 19:36:20 GMT</pubDate>
            <atom:updated>2017-07-25T11:10:34.476Z</atom:updated>
            <content:encoded><![CDATA[<p>In March 2017 I received funding from the <a href="https://sandbox.mit.edu/">MIT Sandbox</a> program to build a product using the <a href="http://www.cognimem.com/products/chips-and-modules/CM1K-Chip/index.html">CM1K neural network chip</a>. The CM1K is an integrated circuit that implements <a href="https://en.wikipedia.org/wiki/Radial_basis_function_network">RBF</a> and <a href="https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm">KNN</a> classifiers in hardware, which supposedly gives much better performance than implementing these algorithms in software. I proposed to use this chip as the basis for a breakout board that could interface with popular hobbyist electronics platforms (such as the <a href="https://www.raspberrypi.org/">Raspberry Pi</a> or the <a href="https://www.arduino.cc/">Arduino</a>). All code and schematics can be found on this project’s <a href="https://github.com/nmoroze/cm1k">Github</a> page.</p><h3>Prior Work</h3><p>I was inspired to begin this project after randomly searching Google to find out if a chip like the CM1K existed — I wanted to know if anyone had developed an ASIC that implemented machine learning algorithms in hardware. I stumbled upon the CM1K very quickly, but project examples were few and far between.</p><p>I did discover the <a href="https://www.indiegogo.com/projects/braincard-pattern-recognition-for-all#/">Braincard</a>, a failed Indiegogo campaign for a breakout board incorporating the CM1K. It was extremely similar to what I intended to develop, claiming to interface the CM1K with the Pi, Arduino, and Intel Edison. Despite its failure, I didn’t lose confidence in my idea — Braincard seemed to lack the documentation and visibility within the hobbyist community necessary to be successful, which doesn’t necessarily say anything bad about the CM1K itself.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tOPH5Zsu2xEsFZGHCZWWKA.png" /><figcaption>Sad reacts only :(</figcaption></figure><p>An interesting note is that the Braincard campaign is actually <a href="http://www.general-vision.com/hardware/braincard/">affiliated with Cognimem</a>. After digging a bit, I discovered multiple companies that all appear to be affiliated: <a href="http://www.cognimem.com/products/chips-and-modules/CM1K-Chip/index.html">Cognimem</a>, <a href="http://www.general-vision.com/hardware/cm1k/">General Vision</a>, and <a href="https://www.crunchbase.com/organization/neuromem#/entity">Neuromem</a>, among others. They all appear to be tied together by the inventor of the technology in this chip — <a href="https://www.linkedin.com/in/guy-paillet-7a4a488">Guy Paillet</a>. If you wanna go down the rabbit hole, take a look at his LinkedIn profile… In any case, my best guess is that the Braincard was an attempt by General Vision to grow demand for the CM1K among the hobbyist market.</p><p>I found even fewer examples of third parties using the CM1K. The few references I dug up were this simple <a href="https://www.openhardware.io/view/208/CM1k-Breakout-Board-Neuromorphic-Chip">breakout board</a> and this <a href="http://tf.llu.lv/conference/proceedings2016/Papers/N204.pdf">research paper</a>. Unfortunately, both of these sources lack any clear documentation demonstrating real-life application of the CM1K.</p><p>It was hard to find examples of the CM1K being put to the test. With Cognimem claiming “<a href="http://www.cognimem.com/_docs/Presentations/PR_CM1K_introduction.pdf">endless possibilities</a>,” I was motivated to build a breakout board and evaluate the CM1K for myself.</p><h3>Developing the Breakout Board</h3><p>I initially planned to complete a couple versions of a breakout board in the spring. The first would be a fairly minimalistic breakout board consisting of:</p><ul><li>the CM1K itself</li><li>a 3.3v and 1.2v regulator to power the chip</li><li>a 27 MHz oscillator to provide a clock signal</li><li>pull up resistors and filter caps where required</li><li>a power LED</li><li>headers to break out every single line on the IC</li></ul><p>This board could then be hooked up to whatever platform I wanted, and once I developed software and was able to evaluate the best way to use the chip, I could design a second board with the extra bells and whistles needed to make it interface nicely with my platform of choice.</p><p>Due to time constraints, I never got close to working on this second design. In any case, it turned out there was little need for it in the experiments I was running: it was super simple to interface the first rev board with the Raspberry Pi over I2C.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4D6ht3rdiY0X1WJzRAJ-6g.png" /><figcaption>Schematic!</figcaption></figure><p>I began designing the breakout board in <a href="http://www.altium.com/">Altium</a>. Drawing up the schematic was fairly straightforward, but the layout took me a while. I settled on trying to fit everything into 2 square inches, which didn’t give me much room to play with. I lined the headers around the edge of the board, and placed the IC in the center. I initially thought I could do the board in two layers, but after two attempts I couldn’t fully lay it out nicely. My biggest pain point was trying to cleanly distribute the 1.2v and 3.3v lines to all of the scattered power pins on the IC. After three redesign attempts, I settled on a four layer design, with the third layer being split into 1.2v and 3.3v power planes. The 1.2v plane was located directly under the IC, so all pins requiring a 1.2v input were routed backwards with a via going straight down to the 1.2v plane. The 3.3v power pins could then be routed forwards with vias going down to the plane. Since all the peripherals use 3.3v, this made it easy to provide 3.3v to the rest of the board.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/662/1*1nRfFk8KDKvrw41K-96ZtA.png" /><figcaption>Routing complete!</figcaption></figure><p>After the board was designed, I needed to send it out for fab. The last time I had done this was a few years ago when I got something made at <a href="https://oshpark.com/">OSH Park</a> for my high school robotics team. At this point, I needed the board much faster than a batching service could provide, so I ended up going with <a href="http://4pcb.com">4pcb.com</a>, using the <a href="http://66each.com">66each</a> deal to get two of my boards fabbed at $66 each. As a student I was able to have the minimum order quantity waived, which was pretty awesome.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*a1lKi5gWmr29IXLNKOxm8Q.jpeg" /><figcaption>My breakout board straight from the fab in all its glory.</figcaption></figure><p>Once my board and all the components arrived, it was time for assembly. I brought it in to <a href="http://miters.mit.edu/">MITERS</a> and got to work soldering everything up using a hot air gun. Every component went down super easily… except for the IC, which took a bit of work to get right. I began with that, and buzzed all the breakout pins to make sure it was tacked down right. After many iterations of buzzing and wicking and trying to carefully apply more solder, it seemed alright.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dMvKNTXl8Y3PDKfzit5FSg.jpeg" /><figcaption>All populated!</figcaption></figure><p>Once I finished soldering, I brought the board over to a power supply and plugged it in. The moment of truth passed uneventfully: the power light turned on and the board did not start smoking or heating up. Next up, I decided to try and use an oscilloscope for the first time to check the output of the oscillator. The output seemed to really suck at first, but after being unable to find a fault in my board, I realized I just didn’t have any clue how to set up the oscilloscope. After some Google searching and some calibrating, I got an output that at least matched the frequency I was going for (even if it wasn’t totally clean). Oh well, things seemed to work out fine anyways.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Jx_hvwExtz_tvhN4ISAtog.jpeg" /><figcaption>The moment of truth!</figcaption></figure><p>With this initial battery of tests completed, it was time to wire up the breakout board and get coding!</p><h3>Developing the Software</h3><p>I started off by hooking up the breakout board to a 3.3v <a href="https://store.arduino.cc/usa/arduino-micro">Arduino Micro</a> I had lying around, chosen because it was the only Arduino I had with a 3.3v logic level. The wiring was easy: I just hooked up the two I2C lines and tied a few configuration pins to GND as necessary to get I2C working. I then wrote a function that successfully read from the CM1K’s NCOUNT register. After generalizing that to a function that could read/write to any arbitrary register, I was able to validate that the CM1K’s hardware seemed to be working as specified in the datasheet.</p><p>Once the hardware was validated, I spoke to a friend of mine who suggested I try benchmarking the chip against the <a href="http://yann.lecun.com/exdb/mnist/">MNIST</a> dataset. I decided this was a worthy goal, and set out to use the CM1K to implement KNN classification on MNIST.</p><p>I decided I didn’t want to have to worry about fitting the MNIST training data set onto my Arduino, so I picked up a Raspberry Pi Zero W along with some peripherals to make wiring easier. I wired it up just like I had with the Arduino, and got to work!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oLsiJT3UTx_Im9C3-5B0PQ.jpeg" /><figcaption>The Raspi Setup in all its glory.</figcaption></figure><p>I decided to write all my code in Python, using the smbus module to talk to the CM1K over I2C. I started off by writing a simple test script based on some pseudocode found in the CM1K Hardware Manual. The script uses a test register, TESTCAT, that writes the same value as the category of every single neuron. It then iterates over each neuron and checks to make sure that its stored category matches the value written to TESTCAT. This script worked, so I decided it was finally time for the dirty work.</p><p>The first step was to downsample the MNIST images. Each image is a tiny 28x28 pixel image to start with, but the CM1K stores data in each neuron as a length 256 vector storing byte values. Therefore, using a single byte to represent the color value of each pixel, I had to squeeze each image into 16x16 pixels so that I could fit one image into each vector. This was easy enough: I used <a href="https://pypi.python.org/pypi/python-mnist/">python-mnist</a> as a lazy way to get the training data, and then used <a href="https://python-pillow.org/">Pillow</a> and Numpy to resample the images. Along with downsampling to 16x16, my code also flattened each image into a single length 256 vector that could be fed to the CM1K.</p><p>Since a single CM1K can only fit 1,024 vectors, I wrote the code to choose a random 1,024 images from the training set to actually use. Given that the full training set uses a total of 60,000 images, I was worried that this would introduce a huge limitation in the performance of the chip.</p><p>The training procedure simply involved writing each of these images into the CM1K. I used the chip’s save-and-restore mode, which is supposed to speed up the process a bit by allowing you to write a vector directly into each neuron’s memory, without them adjusting their activation functions (which are relevant when the chip is running in RBF mode, but not KNN).</p><p>The test procedure then ran a configurable number of test images against the CM1K. I began by simply taking the closest neighbor (k=1), but got terrible results this way (unfortunately, I was doing Bad Science™ and didn’t record these results). However… after quickly implementing majority voting between the closest neighbors (so I could have arbitrary k≥1), my luck changed! Without further ado —</p><h3>Results</h3><p>— it turns out I could get pretty good results after all! My best overall (not pictured here) was an accuracy of 89% testing on 100 samples with k=5.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PYdmCH79E11pJlkeEZI4HA.png" /><figcaption>Results! Sexy progress bar courtesy of <a href="https://github.com/tqdm/tqdm">tqdm</a>.</figcaption></figure><p>This level of accuracy made me pretty happy. Not quite state-of-the-art according to Yann Le-Cun’s website, but a solid B+ (A- if you round up). However, what was somewhat frustrating for me was how slow the script was, especially considering that one of the big promises of using this neural net hardware was that it would be relatively fast. However, it trained and tested at less than 5 samples/second, which I found a bit disappointing.</p><p>I was able to remedy this a little bit by changing the I2C clock speed on the Pi to 400kbps, the theoretical limit of the CM1K. This gave me slightly better results, bumping speeds up to around 7 samples/second across the board.</p><h3>Conclusion</h3><p>Running a KNN on the CM1K, I was able to successfully classify 100 randomly chosen images from the MNIST dataset with 89% accuracy, achieving testing and training speeds of about 7 samples/second. This doesn’t seem too bad, but an important question to ask is whether or not this is actually better than just running a KNN algorithm on the Raspberry Pi itself in software.</p><p>The closest I came to answering this question was by running a modified version of my own code on a <a href="https://github.com/kebwi/CM1K_emulator">CM1K emulator</a> I found on GitHub. Given that emulating the CM1K is obviously not the fastest way to implement a KNN algorithm on the Raspberry Pi, this test doesn’t really demonstrate all that much. However, I was curious to compare performance.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qGmAE5yL9PJRaEyF0luCxQ.png" /></figure><p>As you can see, accuracy and speed suffers when compared to running my code on the actual chip. This is a bit strange, although pretty heartening to see, in some ways. However, I would take this with a grain of salt since I couldn’t really expect much of the emulator code.</p><p>My hunch is that a software KNN would have better performance than the CM1K if implemented in nicely written C code, for example. That being said, there are many ways I could have optimized using the CM1K as well. I believe this is true especially given that the CM1K theoretically, as calculated by the clock speed and cycle counts given in the data sheet, should be able to load a whole vector in around 10 microseconds. Running at this theoretical max, it should be able to train 1000 samples/second, meaning that there is a lot of overhead in my current method.</p><p>Optimization ideas include:</p><ul><li>Rewrite the code in C, to eliminate overhead in Python interpretation</li><li>Use the parallel data bus on the CM1K instead of I2C, which may involve some hardware redesign (possibly use of a shift register) given the limits of the Raspberry Pi GPIO</li></ul><p>Even if the CM1K could run KNN faster than the Pi could run KNN in software, the next question that comes up is whether there is a need to run machine learning algorithms offline anyways. In most applications, it seems more viable to offload this sort of computation to a server. As more and more embedded devices become connected to the Internet (it’s enough of a trend it has its own buzzword now!), embedded offline pattern recognition seems like it will become less and less useful. However, it still is something fun to play with.</p><p>I’m going to shelve this project for now to work on other stuff. However, I do have lots of ideas for how to continue going forward:</p><ul><li>Wire up another breakout board and daisy chain two CM1K’s together: this should allow me to get even better performance without sacrificing speed</li><li>Perform the optimizations described above to milk more speed out of my current setup</li><li>Experiment with the CM1K’s RBF mode (versus KNN mode)</li><li>Write/find a decent KNN implementation for the Pi to do a side-by-side comparison with KNN on the CM1K</li><li>Revisit using the Arduino as the master device, using an SD card module to store training data</li><li>Develop some sort of example application using the CM1K. My top idea at this point is to develop a mobile robot that navigates based on voice commands or brainwaves</li></ul><p>A final note is that General Vision/Cognimem’s technology is now built into the processor on the <a href="http://www.general-vision.com/software/curieneurons/">Arduino 101 chip</a>. This may help bring their technology to the mainstream hobbyist market, although I never found many examples of people using this feature of the chip.</p><p>That’s all for now folks! It was a lot of fun to experiment with the CM1K and try and develop for a chip that is almost unknown to the broader hobbyist community. Hopefully this blog posts sheds a little light on this mysterious little guy! Feel free to get in touch with me via <a href="mailto:me@noahmoroze.com">email</a> if you have any comments or questions.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=32b2d5ca723b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/experiments-with-the-cm1k-neural-net-chip-32b2d5ca723b">Experiments with the CM1K Neural Net Chip</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Time-Traveling in the Puzzlelorean: The HackMIT 2017 Puzzle Guide]]></title>
            <link>https://medium.com/hackmit-stories/time-traveling-in-the-puzzlelorean-the-hackmit-2017-puzzle-guide-40ee4fe797f1?source=rss-187b19d04a29------2</link>
            <guid isPermaLink="false">https://medium.com/p/40ee4fe797f1</guid>
            <category><![CDATA[delorean]]></category>
            <category><![CDATA[hackmit]]></category>
            <category><![CDATA[puzzle]]></category>
            <category><![CDATA[hackathons]]></category>
            <dc:creator><![CDATA[Noah Moroze]]></dc:creator>
            <pubDate>Tue, 18 Jul 2017 16:30:59 GMT</pubDate>
            <atom:updated>2017-07-18T16:30:59.323Z</atom:updated>
            <content:encoded><![CDATA[<p><em>Part 1 of </em><a href="https://medium.com/hackmit-stories/time-traveling-in-the-puzzlorean-the-hackmit-2017-puzzle-guide-40ee4fe797f1"><em>1</em></a><em>, </em><a href="https://medium.com/hackmit-stories/time-traveling-in-the-puzzlorean-the-hackmit-2017-puzzle-guide-pt-2-eb6b26e8f08d"><em>2</em></a></p><p>On July 1st, 2017, HackMIT released our fourth (!!!!) annual puzzle. Past years brought us <a href="https://medium.com/@kt_seagull/joining-the-fancycat-club-hackmit-14-puzzle-guide-6f4ebef5b69">memes</a>, more <a href="https://medium.com/hackmit-stories/such-confuse-hackmit-puzzle-guide-2015-1-4-49dc960f0321">memes</a>, and <a href="https://medium.com/hackmit-stories/the-hackmit-2016-puzzle-3b7f9c97455b">webcomics</a>, but this year we’re going all the way <em>hack to the future</em> (along with the entire hackathon itself — <a href="https://hackmit.org">check it out</a>)!</p><p>A huge shout-out to all the puzzle makers and Slackers this year: <a href="https://github.com/patins">Pat</a>, <a href="https://github.com/revalo">Shreyas</a>, <a href="https://github.com/moinnadeem">Moin</a>, <a href="https://github.com/turbomaze">Anthony</a>, <a href="https://github.com/cmnord">Claire</a> and <a href="https://github.com/Detry322">Jack</a>!</p><p>But first, if you haven’t seen the puzzle yet, we recommend you dial in to July 1st and try it out at <a href="https://hackmit.org">hackmit.org</a>! Come back later after you’re thoroughly stumped 😵</p><h3>Entry</h3><p><em>(</em><a href="https://hackmit.org"><em>Website</em></a><em>, </em><a href="https://github.com/techx/hackmit-splash-2017"><em>GitHub</em></a><em>)</em></p><p>As is tradition, the entry point to the puzzle was hidden on our humble <a href="https://hackmit.org">splash page</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*7dPigzeS6Ev8ShI5." /></figure><p>At first everything appeared normal, but by clicking and dragging on the dial hackers noticed something strange…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/0*BaKT-apE6gDdDajG." /></figure><p>… they began to jump ahead into the future, towards the date of HackMIT itself 😮</p><p>Empty the dial completely, and they were quickly warped to <a href="http://delorean.codes">delorean.codes</a>, the home of our command center!</p><h3>Command Center</h3><p><em>(</em><a href="https://delorean.codes/"><em>Website</em></a><em>)</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*s6pZ2wk45LXriFTh." /></figure><p>This year’s command center used the same backend from previous years. Puzzlers could log in with their GitHub and look at the URLs for all the puzzles in sequence.</p><p>We made it look like the <a href="http://artistmyth.com/wp-content/uploads/2015/10/delorean-control-panel-1024x644.jpg">inside of the DeLorean</a> from <em>Back to the Future</em>, with two time displays. The present time showed a deterministic value as a function of the current puzzle, which could be selected from the knob.</p><p>All puzzle answers were formatted as dates and were deterministic as a function of the puzzler’s GitHub username. Puzzlers could enter their answers in the destination time panel using the keypad.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/595/0*uzk3wO20z_USEv_i." /></figure><p>It was particularly fun making some of the assets of the command center. A handful of the labels, the metallic Puzzlelorean logo, and the flickering neon lights at the entry point were done in <a href="https://www.blender.org/">Blender</a>, an open source 3D modeling software and <a href="http://www.luxrender.net">LuxRender</a>, a raytracing renderer. Some of the buttons used were pictures of control panel buttons Shreyas found in his box of old buttons from Adafruit.</p><h3>Warp</h3><p><em>(</em><a href="https://warp.delorean.codes/u/medium"><em>Website</em></a><em>, </em><a href="https://github.com/techx/hackmit-puzzle-2017-timewarp"><em>GitHub</em></a><em>)</em></p><p>The first puzzle was meant to introduce the puzzlers to the puzzle workflow and mechanics. They were presented with something <em>mostly</em> familiar: a version of our main website in a <a href="https://fontzone.net/font-details/alien-language">curious alien font</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*wF58i6m01DWkZ9ae." /></figure><p>Peeking into the source of the page unmasked the alien font and gave the puzzler a bit more familiar of an alphabet. However, things still didn’t seem particularly intelligible… 🤔</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*wxRYsnO2vizy5LcX." /></figure><p>A closer look revealed that the text on the page was encoded with a Caesar cipher, shifting all the letters of the alphabet by a fixed amount. Many puzzlers successfully decoded the page and found some fun stuff going down during our futuristic HackMIT, but not necessarily anything that brought them closer to solving the puzzle.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/454/0*IzO5PndGpJIBC0zJ." /></figure><p>However, after looking a little closer puzzlers found a link on the page pointed to:</p><pre>/suchsecret/f745616181c5fd11149a82562da4529440d585aff6ef51f3198c6681607463a9.jar</pre><p>This linked to a JAR file that when executed, gave the following output:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/828/0*GDRkYxUXFBx-YvGW." /></figure><p>Digging further into the JAR using any Java decompilation tool (<a href="http://jd.benow.ca/">JD-GUI</a> shown here) revealed the source code of the app.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/963/0*3e-5RhxEACPFIoth." /></figure><p>The source makes it clear that turning the user’s system clock back to the START_EPOCH timestamp would reveal the actual answer.</p><p>Some puzzlers simply modified the JAR and removed the if statement to bypass the check. This puzzle was a reverse engineering task to get our puzzlers started before they delved into the more involved puzzles.</p><h3>HackStore</h3><p><em>(</em><a href="https://store.delorean.codes/u/medium"><em>Website</em></a><em>, </em><a href="https://github.com/techx/hackmit-puzzle-2017-hack-store"><em>GitHub</em></a><em>)</em></p><p>This puzzle confused many in the beginning. When users first arrived they were presented with a login page. The user field was a dropdown that contained two choices and the password field was empty.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*Ooo7zQv2KtNU9jxn." /></figure><p>Many puzzlers attempted injection attacks on the password field (possibly inspired by last year’s <a href="https://medium.com/hackmit-stories/the-hackmit-2016-puzzle-3b7f9c97455b">Bobby Tables puzzle</a>), manipulating the value of the username field, and even attempted to attack the session cookie. None of these attempts were effective. After some internal discussion, we added hints and modified the implementation.</p><p>The key insight to getting past the login page of this puzzle is that a timing attack is feasible on the password field. The string comparison function looks something like this:</p><pre>for i in range(min(map(len, [a,b]))):<br>    if a[i] != b[i]:<br>        return false<br>    return len(a) == len(b)</pre><p>This means that each correct character will add some delay to the request.</p><p>Consider a naive brute force strategy. We allow uppercase and lowercase letters as well as digits. This means we have 62 possible characters. We also specify password length to be between 6 and 12 characters. Now even if we only considered 6-character passwords, there would be 62⁶ possible passwords (~10¹⁰ combinations). Making this many requests would be infeasible. The number of requests grows O(k^n)<em>,</em> where k<em> </em>is the number of characters and n<em> </em>is the length of the password.</p><p>Now consider a strategy informed by the amount time a request takes. For each character slot in the password we have to try 62 possible characters. Assuming we’re 100% certain that this character is the true password character, we can continue on to the next character. This means that the number of requests we have to make grows in O(kn). Since the time it takes to verify each character slot grows with the size of the password, the total time it takes grows in O(kn²). In order to speed up this process it’s possible to make the per-character requests in parallel.</p><p>This puzzle requires significant per-character delay and low response time variance. We exaggerated per-character delay to half a second. This makes the time difference very clear regardless of request latency. We attempted to decrease response time variance by making sure we had the capacity to handle a large number of concurrent requests. (after all requests can last up to 6 seconds) To do this we took advantage of gevent’s event loop, so we didn’t waste time <em>time.sleep</em>ing when we could’ve been been answering requests.</p><p>To make response times more obvious we also added a response header X-Upstream-Response-Time. This header was designed to just look like something nginx had attached, but in reality the number that it output was calculated by the puzzle app.</p><p>Once puzzlers had logged in they were presented with this page:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*9GubI-eeexzgjupk." /></figure><p>At this point it seemed that the obvious course of action was manipulating the session cookie or transfer field; however neither of these worked. This phase required another time-themed attack: <a href="https://en.wikipedia.org/wiki/Race_condition#Software">race conditions</a>.</p><p>Bank transfer operations are classic academic examples of race conditions. These vulnerabilities are particularly hard to find because concurrency is hard to wrap one’s mind around <a href="https://sakurity.com/blog/2015/05/21/starbucks.html">in</a> <a href="http://josipfranjkovic.blogspot.com/2015/04/race-conditions-on-facebook.html">large</a> <a href="https://www.josipfranjkovic.com/blog/race-conditions-on-web">applications</a>. Once you logged in to both users’ accounts (sorry for people who found the password <em>by hand</em><strong> 😬</strong>) you could initiate n transfers concurrently from one account to the other. The transfer function looked something like this:</p><pre>x = get(marty)<br>y = get(biff)<br>set(biff, x+y)<br>set(marty, 0)</pre><p>This made it possible to break the invariant <em>marty</em> + <em>biff</em> = <em>constant</em> and create money. We added a delay in between the set operations, so much so that this attack was possible to execute by creating two tabs in your browser and Ctrl-Tab-ing quickly between them.</p><p>Something interesting: it’s possible to race in the “wrong direction”. If you race by calling transfer on the same account, you create money. However, if you race by calling transfer on different accounts, the final operation sets both balances to 0, effectively removing all of your funds and making the puzzle impossible to solve.</p><p>To prevent this we do an additional check to make sure that the sum of your balances isn’t 0 (this check is also not atomic 😉).</p><p>A huge thanks to Shreyas and Patrick for writing up the solutions to these puzzles! Warp ahead into <a href="https://medium.com/hackmit-stories/time-traveling-in-the-puzzlorean-the-hackmit-2017-puzzle-guide-pt-2-eb6b26e8f08d">part 2</a> to see things get really interesting…</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=40ee4fe797f1" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hackmit-stories/time-traveling-in-the-puzzlelorean-the-hackmit-2017-puzzle-guide-40ee4fe797f1">Time-Traveling in the Puzzlelorean: The HackMIT 2017 Puzzle Guide</a> was originally published in <a href="https://medium.com/hackmit-stories">HackMIT Stories</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>