Book Read Free

The Boy Who Could Change the World

Page 11

by Aaron Swartz


  1. Even with the rule, there will be invalid documents. Someone will write some code, test it, see that it works and move on. One day the code will be given data that trips one of XML’s exceptions (AT&T is a common example—XML requires it be written AT&T) and an invalid document will be created.

  2. XML apps compete for users. Users want to read these documents, even if they’re broken. Users will switch to apps that read these documents and the rule will be useless, since folks will likely test with those apps. The only way we can keep the rule in effect is by getting everyone who writes an app to act against the wishes of their users, which seems like a bad idea.

  3. Essentially the same effect can be achieved by having a validation display (like iCab or Straw’s smiley face that frowns on invalid documents) and an easy-to-use validator.

  This is not to say that all apps should have to process invalid documents, or that they should work hard to guess what the author meant, or that we should encourage or tolerate invalid documents. We should still try to get rid of invalid documents, but taking things out on the users is the wrong way to do it.

  The creators of XML were wrong. Postel’s Law has no exceptions.

  Squaring the Triangle: Secure, Decentralized, Human-Readable Names

  http://www.aaronsw.com/weblog/squarezooko

  January 6, 2011

  Age 24

  When using computers, we like to refer to things with names. For example, this website is known as “www.aaronsw.com.” You can type that into your browser and read these words. There are three big properties we might want from such names:

  •secure: that when you type the name in you actually get my website and not the website of an imposter

  •decentralized: that no central authority controls all the names

  •human-readable: that the name is something you can actually remember instead of some long string of randomness

  In a classic paper, my friend Zooko argued that you can get at most two of these properties at any one time.

  Recently, DNS legend Dan Kaminsky used this to argue that since electronic cash was pretty much the same as naming, Zooko’s triangle applied to it as well. He used this to argue that Bitcoin, the secure, decentralized, human-meaningful electronic cash system was impossible. I have my problems with Bitcoin, but it’s manifestly not impossible, so I just assumed Kaminsky had gone wrong somewhere.

  But tonight I realized that you can indeed use Bitcoin to square Zooko’s triangle. Here’s how it works:

  Let there be a document called the scroll. The scroll consists of a series of lines and each line consists of a tuple (name, key, nonce) such that the first N bits of the hash of the scroll from the beginning to the end of a line are all zero. As a result, to add a line to the scroll, you need to do enough computation to discover an appropriate nonce that causes the bits of the hash to be zero.

  To look up a name, you ask everyone you know for the scroll, trust whichever scroll is the longest, and then start from the beginning and take the key for the first line with the name you’re looking up. To publish a name, you find an appropriate nonce and then send the new line to everyone you know.

  OK, let’s pause there for a second. How do you steal names in such a system? First, you need to calculate a new nonce for the line you want to steal and every subsequent line. Second, you need to get your replacement scroll to the user. The first is difficult, but perhaps not impossible, depending on how many lines ago the name you want to steal is. It requires having some large multiple of the rest of the network’s combined CPU power. This seems like a fairly strong constraint to me, but apparently not to Dan. Luckily, we’re saved by the second question.

  Let there be a group of machines called the network. Each remembers the last scroll it trusted. When a new valid line is created it’s sent to everyone in the network and they add it to their scroll.* Now stealing an old name is impossible, since machines in the network only add new names, they don’t accept replacements for old ones.

  What happens if two people create a new line at the same time? The debate should be resolved by the creation of the next new line—whichever line is previous in its scroll is the one to trust.

  That’s fine for machines already in the network, but how do you join? Well, as a physical law, to join a network you need the identity of at least one machine already in the network. Now when you join, that machine can give you a fabricated scroll where they’ve stolen all the names. I don’t think there’s any way to avoid this—if you don’t know anyone willing to tell you the correct answer, you can’t will the correct answer out of thin air. Even a centralized system depends on knowing at least one honest root.

  You can ameliorate this problem by knowing several nodes when you connect and asking each of them for their scroll. It seems like the best theoretically possible case would be requiring only one node to be honest. That would correspond to trusting whichever node had the longest scroll. But this would leave you vulnerable to an attacker who (a) has enough CPU power to fabricate the longest scroll, and (b) can co-opt at least one of your initial nodes. The alternative is to trust only scrolls you receive from a majority of your list of nodes. This leaves you vulnerable to an attacker who can co-opt a majority of your initial nodes. Which trade-off you pick presumably depends on how much you trust your initial nodes.

  Publishing a false scroll is equivalent to fragmenting the namespace and starting a separate network. (We can enforce this by requiring nodes to sign each latest scroll and publish their signature to be considered members in good standing of the network. Any node that attempts to sign two contradictory scrolls is obviously duplicitous and can be discounted.) So another way of describing scenario (b) is to say that to join a network, you need a list of nodes where at least a majority are actually nodes in the network. This doesn’t seem like an overly strenuous requirement.

  And we’re actually slightly safer than that, since the majority needs a fair amount of CPU to stay plausible. If we assume that you hear new names from some out-of-band source, for them to work on the attacker’s network the attacker must have enough CPU to generate lines for each name you might use. Otherwise you realize that the names you type in on your computer are returning 404s while they work on other people’s computers, and begin to realize you’ve been had by an attacker.

  So there you have it. The names are secure: they’re identifiable by a key of arbitrary length and cannot be stolen. They’re human-meaningful: the name can be whatever string you like. And they’re decentralized: no centralized authority determines who gets what name and yet they’re available to everyone in the network.

  Zooko’s triangle has been squared.

  Release Late, Release Rarely

  http://www.aaronsw.com/weblog/rlrr

  July 5, 2006

  Age 19

  When you look at something you’re working on, no matter what it is, you can’t help but see past the actual thing to the ideas that inspired it, your plans for extending it, the emotions you’ve tied to it. But when others look at it, all they see is a piece of junk.

  You only get one chance to make a first impression; why have it be “junk”? Once that’s associated with your name or project, it’s tough to scrape off. Even people who didn’t see it themselves may have heard about it secondhand. And once they hear about it, they’re not likely to see for themselves. Life’s too short to waste it on junk.

  But when you release late, after everything has been carefully polished, you can share something of genuine quality. Apple, for example, sometimes releases stupid stuff, but it always looks good. Even when they flub, people give them the benefit of the doubt. “Well, it looks great but I don’t really like it” is a lot better then “It’s a piece of junk.”

  Still, you can do better. Releasing means showing it to the world. There’s nothing wrong with showing it to friends or experts or even random people in a coffee shop. The friends will give you the emotional support you would have gotten from actual u
sers, without the stress. The experts will point out most of the errors the world would have found, without the insults. And random people will not only give you most of the complaints the public would, they’ll also tell you why the public gave up even before bothering to complain.

  This is why “release early, release often” works in open source: you’re releasing to a community of insiders. Programmers know what it’s like to write programs and they don’t mind using things that are unpolished. They can see what you’re going to do next and maybe help you get there.

  The public isn’t like that. Don’t treat them like they are.

  Bake, Don’t Fry

  http://www.aaronsw.com/weblog/000404

  July 9, 2002

  Age 15

  I really got started with this whole web mess with the ArsDigita Prize where I learned how to build database-backed websites by building one myself. However, it was always assumed that these sites would be built by having a bunch of code on the server which generated pages for the user on demand by calling the database. That was simply how such sites were built, I never questioned it.

  Now, a number of tools are challenging that assumption. Movable Type, the program that runs this weblog, has a series of Perl scripts which are used to build your webpage, but the end result is a bunch of static pages which are served to the public. All the content here is plain old web pages, served up by Apache. Tinderbox uses a similar system, drawing from your database of notes to produce a bunch of static pages. My book collection pages are done this way. Radio UserLand statically generates the pages on your local computer and then “upstreams” them to your website.

  Finally, while researching Webmake, the Perl CMS that generates pages like Jmason’s Weblog and SpamAssassin, I found a good bit of terminology for this. Some websites, the documentation explains, are fried up for the user every time. But others are baked once and served up again and again.

  Why bake your pages instead of frying? Well, as you might guess, it’s healthier, but at the expense of not tasting quite as good. Baked pages are easy to serve. You can almost always switch servers and software and they’ll still work. Plus, you get to take advantage of the great features built into your web server, like content negotiation, caching, ETags, etc. You don’t get the bells and whistles like providing a personalized greeting on every page, but those are things that aren’t very good for you anyway.

  The one problem with the “bake” philosophy is dependencies. It’s difficult to keep track of which pages depend on which others and regenerate them correctly when they change. Movable Type handles this in the obvious cases, but when you do anything other than creating or editing an entry, it makes you manually rebuild the corrector portions of the site. Tinderbox, a speedy C++ program, seems to regenerate the whole site every time. It seems that for this philosophy of database-backed static pages to take off, we’d need a really good dependency system to back it. Has anyone built such a system?

  Let me know.

  Update: Some people seem to think that I want to bake because of performance. Honestly, I don’t care about performance. I don’t care about performance! I care about not having to maintain cranky AOLserver, Postgres, and Oracle installs. I care about being able to back things up with scp. I care about not having to do any installation or configuration to move my site to a new server. I care about being platform and server independent. I care about full-featured HTTP implementations, including ETags, content negotiation, and If-Modified-Since. (And I know that nobody else will care about it enough to actually implement it in a frying solution.) I hope that clarifies things.

  If you liked this article, also check out the sequel, Building Baked Sites.

  Building Baked Sites

  http://www.aaronsw.com/weblog/000406

  July 10, 2002

  Age 15

  Bake, Don’t Fry has been one of my more successful blog entries. I wonder if this was because of style or content (or both?). Anyway, since people seem interested in it, I thought I’d sketch out my views on how to make baked sites work.

  First, let me clarify that using static web pages for your site does not preclude things that people generally associate with dynamic sites (like templates, newsboxes, stock tickers, etc.). Nor does it mean that your site can’t have any interaction or collaboration (comments, boards, polls). While these things obviously won’t work if you move platforms or server software, at least the content already on your site won’t die. The key is to keep a strict separation between input (which needs dynamic code to be processed) and output (which can usually be baked).

  So how would this work? You’d need a dependency tracking system (good old GNU Make might even do the job) that would allow you to add new content to the system (something tricky with Make alone—is this what Automake does?) or modify old content and would then rebuild the dependent pages or create new ones as necessary. As an example, a new blog entry should create a new page for the entry, rebuild the previous entry page, rebuild the day/week/month’s pages, and rebuild the home page. It would also have to add all the dependencies for the new page (to the template, to the previous entry, to that entry, to the category name) and add a dependency to the previous entry page.

  Current systems (like OpenACS) could even be hoodwinked into doing this with little or no modification. The dependency information could be layered on top and then the system could simply call the dynamic scripts when that page needed to be regenerated. Of course, a purebred system would probably be better since it would give a chance for URL structure to be designed more sensibly.

  Baking doesn’t do everything, though. Input systems, like the code that accepts comments, would still need to be dynamic. This is a limitation of web servers which I doubt will ever be solved in a standard way. Dynamic tools (like homepage generators and search software) will either have to be fried, or use client-side technologies like SVG, Java(Script), Flash (ick!). There’s no way around that.

  If you’re interested in helping build a system to help with baking sites, please let me know.

  A Brief History of Ajax

  http://www.aaronsw.com/weblog/ajaxhistory

  December 22, 2005

  Age 19

  New technology quickly becomes so pervasive that it’s sometimes hard to remember what things were like before it. The latest example of this in miniature is the technique known as Ajax, which has become so widespread that it’s often thought that the technique has been around practically forever.

  In some ways it has. During the first big stretch of browser innovation, Netscape added a feature known as LiveScript, which allowed people to put small scripts in web pages so that they could continue to do things after you’d downloaded them. One early example was the Netscape form system, which would tell you if you’d entered an invalid value for a field as soon as you entered it, instead of after you tried to submit the form to the server.

  LiveScript became JavaScript and grew more powerful, leading to a technique known as Dynamic HTML, which was typically used to make things fly around the screen and change around in response to user input. Doing anything serious with Dynamic HTML was painful, however, because all the major browsers implemented its pieces slightly differently.

  Shortly before web development died out, in early versions of Mozilla, Netscape showed a new kind of technique. I don’t think it ever had a name, but we could call it Dynamic XML. The most vivid example I remember seeing was a mockup of an Amazon.com search result. The web page looked just like a typical Amazon.com search result page, but instead of being written in HTML, it was a piece of XML data which was then rendered for the user by a piece of JavaScript. The cool part was that this meant the rendering could be changed on the fly—there were a bunch of buttons that would allow you to sort the books in different ways and have them display using different schemes.

  Shortly thereafter the bubble burst and web development crashed. Not, however, before Microsoft added a little-known function call named XMLHttpRequest to I
E5. Mozilla quickly followed suit and, while nobody I know used it, the function stayed there, just waiting to be taken advantage of.

  XMLHttpRequest allowed the JavaScript inside web pages to do something they could never really do before: get more data.* Before, all the data had to be sent with the web page. If you wanted more data or new data, you had to grab another web page. The JavaScript inside web pages couldn’t talk to the outside world. XMLHttpRequest changed that, allowing web pages to get more data from the server whenever they pleased.

  As my commenters point out—and as I well knew, but momentarily forgot—this isn’t really true. Before XMLHttpRequest, people used a trick of not closing the connection to the server. The server would keep adding more and more to the page, never saying it had finished downloading. Ka-Ping Yee used this technique to make a real-time chat system based on an animated GIF. And the ill-fated startup KnowNow used a similar technique with JavaScript to allow for live-updating pages.

  Google was apparently the first to realize what a sea change this was. With Gmail and Google Maps, they built applications that took advantage of this to provide a user interface that was much more like a web application. (The start-up Oddpost, bought by Yahoo, actually predated this, but their software was for-pay and so they didn’t receive as much attention.)

  With Gmail, for example, the application is continually asking the server if there’s new email. If there is, then it live updates the page; it doesn’t make you download a new one. And Google Maps lets you drag a map around and, as you do so, automatically downloads the parts of it you want to look at inline, without making you wait for a whole new page to download.

  Jesse James Garrett of Adaptive Path described this new tactic as Ajax (Asynchronous Javascript And XML) in an essay, and the term immediately took off. Everyone began using the technique in their own software and JavaScript tool kits sprung up to make doing so even easier.

 

‹ Prev