bitbashing

Wed, 13 Dec 2006

Market-Based Resource Allocation

In 1988 Mark Miller (of E and Xanadu) and K. Eric Drexler (author of Engines of Creation) propsed what they called the 'agoric model' for resource allocation. For instance, each process can bid in auctions in order to purchase CPU time on which to run (or, for that matter, resell). Having recently read several pieces of Singularity-oriented fiction (Accelerando and After Life being the better of them), these concepts seemed particularly on target.

It's already fairly common to 'rent' CPU time and memory (in the form of virtual private servers and remote storage), but right now all companies offering such services only sell large blocks, at more or less fixed rates. My suspicion would be that this gives a larger income per client, but at the cost of utilization. Would it be more profitable to use a fine grained model, renting disk at, say, 10^-7 pennies per kilobyte-hour?

It was also interesting to consider these papers in the context of E, smart contracts, financial cryptography, and a half a dozen other concepts. Still a lot of things to learn...

The Agoric Papers, and a related Wired article from 1996.

posted 2006/12/13 04:52 [category: bitbashing / programming]

Sun, 05 Nov 2006

C++ Networking

In an earlier post, I lamented the dearth of really solid C++ networking libraries. Someone on the Monotone list mentioned a networking library, Asio that I'm getting warm fuzzies about. The interface reminds me a bit of Python's Twisted (which I have beeen carrying around in my head as an ideal for some time now), is actively maintained, fairly portable, and seems to have a bright future - it's being included in the next release of Boost, and it looks likely that it will be included in C++ TR2 (meaning there is a very strong chance that something derived from Asio will be included in the next version of the C++ standard, due out in a year or two).

The normal synchronous interface is very simple and easy to use, though it also isn't anything particularly special; OO wrappers to Berkeley sockets abound. The real prize is an asynchronous interface based on the Proactor pattern [Asio = asynchronous I/O]. I'm still having some trouble really wrapping my head around the proactor, but I've got good feelings about the design and implementation, so I'm going to keep playing around with it.

Right now Asio is mostly focused on networking, but in principle should be extendable to file access, windowing event loops, audio input and output, and all kinds of other interesting things.

posted 2006/11/05 03:13 [category: bitbashing / programming]

Wed, 01 Nov 2006

Algorithmic Complexity Attacks on Allocators

A few years back some researchers presented the concept of performing denial of service through algorithmic complexity attacks, which essentially cause pathological behavior in data structures like hash tables through carefully chosen inputs. Of course the general concept was well known; Introduction to Algorithms, more or less the standard algorithms textbook, begins the section on universal hashing with "If a malicious adversary chooses the keys to be hashed, then he can choose n keys that all hash to the same slot, yielding an average retrieval time of O(n)". In the case of data structures, the typical response is randomization, which is simple enough in the case of hash tables. Universal hashing is the theoretically clean way, but even something very crude, like initializing a CRC feedback register with a randomly chosen value, will often be more than sufficient.

There have been a small number of papers over the years which present memory allocation in game-theoretic terms - one side being an application, the other being the allocator. Each "turn" of the game involves the application making an allocation or deallocation request, and the allocator must respond in an online fashion (that is, it can't batch together requests and reply all at once - it's only context for requests are those which have already completed, and has no knowledge of future requests). This form of analysis doesn't seem particularly useful in the common case; applications tend to have very regular patterns of dynamic memory use, and an allocator which had no pathological cases might well perform much worse on average, compared to a general purpose allocator with some obscure pathological case that never came up in common workloads. However, it does seem very valuable from the perspective of analyzing complexity attacks.

Can these attacks be carried out against memory allocators in practice? How strongly can an attacker affect the memory allocation patterns of an application (especially fat targets like servers and OS kernels?). What pathological cases exist within common memory allocator implementations, and how serious are they?

Are there any known designs for randomized memory allocators? I have done a literature search and haven't been able to find anything along these lines.

posted 2006/11/01 23:46 [category: bitbashing / security]

Tue, 31 Oct 2006

Wildly Expensive Toys

I came across Magma, a company that builds PCI enclosures. Insert a PCI-E card to your host machine and connect it over to a secondary box with 4 to 13 PCI or PCI-X slots. However, the cost is sufficiently high that it would be cheaper to just buy a second machine. Shame, since I could actually use this, if the price was reasonable.

posted 2006/10/31 15:01 [category: bitbashing / hardware]

Mon, 25 Sep 2006

Some C++ Libraries Worth Looking At

C++ is a horribly schizophrenic language. The infamous Stroustrup quote that "In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg" goes a long way towards describing the issue - C++ is a language of surprising expressive power, but most of the time that power is aimed at feet. But when it's used well, it leads to some rather lovely pieces of code. Here's my rundown of some favorite C++ libraries. All of these libraries are freely usable in both open source and commercial applications; while that wasn't a precondition, it is a very nice bonus.

Boost

Boost is probably going to be on every list of C++ libraries worth using. While I haven't used all of the libraries in Boost, I can say that Boost.Python and the function/bind library are quite lovely to use.

Building it from source is a good reminder of how slow GCC can be, though. Install binaries if you can.

SOCI

SOCI provides a very reasonable interface to relational databases, with plugins for SQLite, Postgres, and various databases I never use and don't much care about (Oracle and MySQL). A quick example.


sql << "select phone from phonebook where name = :name",
       into(phone), use(name);

Downsides include the build system, which is less than enlightened, and the fact that some ways of using the library seem to leave applications open to SQL injection attacks.

OTL is another C++ database/SQL library. It seems interesting, though SOCI's syntax feels more natural to me, and OTL's database support is heavily biased towards Oracle and MS SQL; again, nothing against either of these databases, I just don't see myself using them often. Or ever, for that matter. Others are supported through ODBC, but are apparently somewhat beta-ish.

GTKmm

GTKmm is the first C++ GUI toolkit I've seen that I would actually want to program in. Partially, this is due to GTKmm's advantage over other libraries, which are typically much older and developed their own string/vector/assocarray/etc classes; which, of course, doesn't play very well with the rest of your STL-using code. One could drink the full glass of Kool-Aid and use the GUI toolkit types in all your code, but the idea of tying my entire application to the interface code doesn't give me good feelings. In contrast, GTKmm plays nicely with the STL, is cleanly designed, and seems significantly more extensible than I'll ever need. Support for Aqua would be really nice, but then again, I don't own a Mac, so what do I care?

Botan

Sheesh, what do you expect? I wrote the stupid thing. Anyway, I feel like the design is quite nice, much less due to my own brilliant coding ability (hah!) than my willingness to steal good ideas wherever and whenever possible. To provide some redeeming social value to this section, I'll mention that Crypto++ is the "other" C++ crypto library. They're very different in terms of style, so if you're looking for something in this niche I'd recommend trying them both and deciding which one feels more natural to your programming style.

Blitz++ and POOMA are often considered among the Tier 1 C++ libraries, but as I don't have much interest (or ability) in hydrodynamics, they have little practical use for me. On the other hand, work on these libraries has produced a number of interesting papers and new techniques - as a source of inspiration for writing high-performance C++ code, they can certainly be worth examining.

You might have noted a distinct lack of network libraries on this list. There are literally dozens out there, the best of which seems to be Netxx, which, aside from the fact that it's not maintained anymore, seems quite decent. It's not entirely perfect (perfect being defined as "how I would do it"), but having gone down that rabbithole once (see above), I'm willing to settle for a solid 98%. I'm not sure if I'm willing to settle for "maintain it yourself", though. A much heavier alternative is ACE, but the more I look at ACE the leerier I become of it. ACE is in much the same state as Qt; a good, interesting, solid state-of-the-art-in-1994-or-so design that hasn't been updated in a decade due to compatibility concerns. Right now I'm thinking of it more as a source of ideas than of code.

So what is missing from our box of C++ libraries? Most C++ applications could benefit from judicious use of the STL and the Boost libraries. GTKmm seems a solid choice for GUIs (assuming you don't just wrap your low-level code using Boost.Python or SWIG and then write the GUI in Python or Ruby). Networking is a bit of a hole, though you've certainly have a number of options there; there just doesn't seem to be a compelling choice right now.

I'd like to see an embedded language (ideally of a Scheme/Lisp flavor) that really got along well with C++ code. A decent P2P library (perhaps something interoperating with JXTA or OpenDHT) would be delightful.

For another perspective on some of this, I'd recommend this post by Graydon Hoare, which while somewhat dated (2004) is very much worth reading (I'm willing to attest that he is both smarter and a better programmer than I am - though I'm not sure how much that opinion is worth to anyone).

posted 2006/09/25 10:47 [category: bitbashing / programming]

Wed, 30 Aug 2006

Finding Equivalences of Boolean Function

A fairly common class of functions in crypto are functions mapping {0,1}3 onto {0,1}. In particular, these show up a lot in hash functions derived from MD4, including MD5, SHA-1, RIPEMD, and SHA-512. These range in complexity from simple three-term expressions like "(A xor B xor C)" to functions like "((A and B) or (C and (A or B)))". One interesting and important difference between these two functions becomes very important when you consider how to implement these functions on an x86 (or x86-64) processor. The x86 uses two-operand instructions, and has very few registers, so computing something like "(A and B) xor (not(A) and C)", which requires two temporaries (one to hold A and B, the other (not(A) and C)) might require you to spill values to the stack. Often, that means a major performance hit. Finding an alternate form for this function that only requires fewer temporary registers could be a major benefit. Obviously finding these equivalences could be done by hand, but having a computer do it seemed both faster and more interesting.

I ended up implementing the equivalence finder in Common Lisp. I like Lisp, as a language, quite well; unfortunately its qualities as an overall application platform leave something to be desired. But in this case that wasn't an issue. After a few false starts, I came up with a working (if inefficient and ugly) design. Each piece of the the function was represented by a closure over the expression that it contains. For example, the function for "and the current expression with the X variable" is


(defun andx (next)
  #'(lambda (x y z) (and x (funcall next x y z))))

And so on for the various other useful expressions. At the bottom there are some kernels, which do not contain any additional expressions, but just a single variable reference. For example:

(defun kernelz (x y z) z)

So (xory (andx kernelz)) is function taking three arguments and computing (Y xor (X and Z)).

We then perform a depth-first search on all possible expressions until we find ones that evaluate the same as our target function. Why depth-first? Mostly because it was simple to program; after we hit a preset depth, we back out of that path and go upwards. Since an equivalent to our target with a hundred terms in it wouldn't be terribly useful (remember, we're looking for ways to optimize code), dropping out of the search after the expression has reached 5 or 6 terms should be fine.

The first test was ((A and B) or ((not A) and C)), which is a function used in the SHA-1 hash. This has a known simpler version, discovered some years ago by Colin Plumb. And it was indeed able to find that (C xor (A and (B xor C))) is an equivalent. It was also able to find an equivalent for a related function in SHA-256.

Some useful enhancements will be pruning expressions that are equivalent, and performing the search breadth-first to ensure we always find the shortest possible expression. Eventually I'm planning on using this code for searching for more efficient versions of the Serpent Sboxes, which are described as 4-bit to 4-bit boolean functions. In particular, it might be interesting to try and find versions that are well-suited for implementation on SSE2, IA-64, or other "exotic" targets (most versions so far have been optimized for x86 or general RISC targets like PowerPC and SPARC).

posted 2006/08/30 01:39 [category: bitbashing / security]

Sun, 13 Aug 2006

Fun with assembly

"If you can explain how you do something, then you're very very bad at it." -- John Hopfield

The Monotone folks have been doing some profiling and performance work of late. One thing that came out of that was the finding that Botan's SHA-1 implementation was causing a bottleneck; because Monotone identifies everything via hashes, there are times where it needs to hash many (many) megabytes of source data, and the faster that happens, the better. Since low-level C++ wasn't cutting it, I felt that it was time to try my hand at x86 assembly again.

Initially, I simply followed the flow of the existing, and fairly well optimized, C++ code. Since that code is quite low level, it was fairly easy to map; many statements in the source corresponded directly to a single x86 machine instruction. The algorithm fits the machine well - the 5 chaining variables went into %eax, %ebx, %ecx, %edx, and %esi, leaving %edi to point to the (expanded) message and %ebp as a temporary. This let almost all operations run out of registers, with the exception of the boolean function in the third round. The majority function, (B & C) | (B & D) | (C & D), can be reduced a bit, down to ((B & C) | ((B | C) & D)), but it still requires two independent variables - you have to have both B & C and ((B | C) & D)) computed before you can OR them together, and that means two temp variables. I ended up stealing a (previously used) word out of the expanded message array to hold (B | C), which was serviceable if hackish.

The loop to perform the message expansion was partially unrolled (four times, about as big as could be done and not spill any registers); this change made for a noticeable (10%) speed increase. The loop that read in the actual input and byte swapped it was also unrolled; I'm not certain that this made much of an impact on performance, but it was easy enough to do, and will perhaps help hide the latency of the bswap operation (7 cycles on some versions of the Intel P4!)

The code at this stage was not particularly efficient, and I knew it, but it still managed to run around 20% faster than the code produced by GCC with full optimizations. Botan's benchmark system came in very useful here, as it allowed me to directly compare the performance of the C++ code, the assembly, and of OpenSSL's implementation (all benchmarks used the hardware time stamp counter and randomly generated inputs). While my 90 Mib/sec looked great in comparison to the C++, it didn't fare so well against OpenSSL's assembly, chewing up 130 megabytes every second. And the disparity on a P4-M was even larger.

I was already using the C macro preprocessor for simple looping constructs and so forth, but to improve readability, and make it easier to work with the code, I converted everything to macro calls. This also got rid of the AT&T syntax weirdness of having the output operand last, which I found troublesome when visually comparing C and assembly. As a final bonus, it means that, at least in theory, I'll be able to use the code with Intel assemblers by simply swapping out a header file of macro definitions. Here's a sample of how it looks, for the curious.


   ZEROIZE(ESI)

START_LOOP(.LOAD_INPUT)
   ADD_IMM(ESI, 1)
   ASSIGN(EAX, ARRAY4(EBP, 0))
   ADD_IMM(EBP, 4)
   BSWAP(EAX)
   ASSIGN(ARRAY4_INDIRECT(EDI,ESI,0), EAX)
LOOP_UNTIL(ESI, IMM(16), .LOAD_INPUT)

This is certainly not the best or most complete assembly macro language out there, but by adding macros as I needed them, I ended up with a fairly reasonable system; I eventually used this same set of macro calls to implement MD4 and MD5. And using the C preprocessor rather than something specialized, like M4 or a yacc/lex-based language, made it easy to fit the code into Botan's build environment.

After "rewriting" the code into macros, I went through and reordered various instructions in an attempt to break dependency chains and hide latencies as much as possible. In particular, I found that moving loads well before use (4 or 5 cycles) made a very substantial difference. While I knew that the latency of a L2 cache read could run into dozens of processor cycles, I had assumed the out of order execution cores of the Athlon and P4 would handle this detail for me. But, it seems, hand-tweaking of instruction ordering is still necessary for the best possible performance. All told, these changes pushed the speed to just over a 100 megabytes a second.

At this point I felt pretty well stuck; I couldn't figure out how I could squeeze any more performance out of the code, but OpenSSL was still running 30% faster than me - obviously the hardware was capable of more, but how? I had no idea.

So I checked everything into the repository, and sat down to read for a while. Specifically, I picked up my copy of the Intel Pentium 4/Pentium M optimization manual, and came up with some neat (if almost entirely unoriginal) tricks. I'll write about those later on, those who wish to read ahead can check out sha1core.S in the latest version of Botan.

posted 2006/08/13 16:10 [category: bitbashing / programming]

Fri, 11 Aug 2006

Object-Capabilities in C++

I've been slowly working my way through Mark Miller's recent PhD thesis on object-capability systems and distributed computing, particularly in relation to E.

The type system of C and C++ can best be described as advisory in nature - if you want to cast an integer to a pointer, no compiler or run-time loader will stand in your way. For this reason, C++ cannot act in a fully object-capability manner; if untrusted code executes within your address space, it can forge a reference to any other object and send messages to it.

Miller describes the very interesting caretaker and membrane patterns, which allow for the creation of a revocable capability. The caretaker simply wraps around the object itself, while the membrane also creates caretakers for each object which is passed in either direction. The caretakers can all be toggled to "shut", preventing any access at a later time. With membranes, an object can let two other objects communicate but do so in a way that, after the membrane is closed, they cannot communicate at all. Unfortunately, due to the limitations of C++, the membrane pattern cannot work (colluding objects can always "hide" a reference in data), and the caretaker must be implemented on a per-object basis (using a preprocessor seems like a promising method). This would not be necessary if it were possible to override the . operator, or if the -> operator could take an argument, but both of these avenues are forbidden by the language. As the caretaker would be, at best, of an advisory nature, this is probably not much of a loss.

Despite the myriad limitations of the language, I think a capability-based discipline may still be of interest in C++. In particular it would address the problem of The Confused Deputy, where non-malicious code is "tricked" into using authority in a way that was not intended. I'll be writing more on this topic later on.

posted 2006/08/11 02:37 [category: bitbashing / security]

Thu, 10 Aug 2006

Distributed Computing and the War on Drugs

Most of the botnets that are out there right now seem to be used for spamming, denial of service attacks, and ad fraud. These are areas which (seemingly) produce solid revenue streams for the owners of the net, but don't seem very interesting from a technical perspective.

I recent finished read PiHKAL, by Alexander and Ann Shulgin, a combination novel/autobiography about their experimentation with psychedelic drugs, which contains, towards the end, descriptions and instructions for preparation of 179 different phenethylamines. While Dr. Shulgin (at the time) had a DEA Schedule I license, allowing him nearly unfettered access to any chemicals he might have needed, he notes that he was careful to ensure that all the precursors he describes in PiHKAL were legally available. However, PiHKAL was written 14 years ago, and it seems very likely that many of the precursors he uses are now on watch lists, or have been banned entirely.

It's my understanding that a great deal of supercomputer time is spent doing chemistry, particularly biologically related chemistry. I have to wonder if a botnet could do the same; in this case searching for new methods of creating known illicit drugs from widely available legal precursors. I suspect the computational load for chemical simulations of this nature are substantial, and the low node reliability and high communications latency would complicate things further. However, given that the computations can be done "for free", it might end up being a very profitable project for someone. I never took much chemistry in college, so I'm not really in a position to investigate this too closely.

posted 2006/08/10 12:18 [category: bitbashing / programming]

UAV-Based Sensor Platforms

I've been thinking about all of the challenges related to building an autonomous UAV-based sensor platform. It feels like this is a project that contains a number of tough problems, and I am not helping that by giving my project a very expansive scope right from the start. This post is essentially just to outline the high-level goals as I see them now.

My use-case run something like this. Several UAVs with heterogeneous payloads launch, ideally under software control without human intervention. Once in the air, they form an encrypted network over RF links. This network would probably include one or more ground stations, since the amount of computing power you can get into the air is limited by weight and power restrictions. Potentially at some point I could use a larger commercial UAV with a gas engine as the computational center, making the system entirely mobile. Then, based on mission objectives (which could be set pre-launch, or modified once in the air), they would collate and share sensor data, using any previous findings to direct future sensor use across the entire platform. For example, say that one UAV has an IR camera, while another has a visible light camera. Upon detecting something that the system considers to be "of interest" with the IR camera (say, someone moving within a particular area), the UAV with the visible light sensors then examines the same area in attempt to confirm. Perhaps then a ground station would use its horsepower to combine the two image sets and attempt facial/gait recognition, lip reading, read license plates and look them up in the public DMV databases, or other craziness, send alerts, and so on. And they should do all this while flying autonomously. Simple enough, huh?

The bandwidth that will be available seems pretty small, I've been looking at products like the xBee-Pro, which offers (ideal best case) around 32 kilobytes per second, with a range of up to a mile. Which will certainly put a cramp on how much off-UAV analysis can be performed, simply because not that much data can be sent, but I suppose that fits well with starting small. By the time I know enough about computer vision that I can do the interesting stuff, WiMax will make it fairly easy to create a long-range high bandwidth mesh network.

Some other hardware I've been looking at is the Gumstix line of embedded computers, and the hardware info from the Paparazzi UAV Project's Wiki.

My first iteration may be a helium blimp, since I can test that indoors and get a better feel for some of the issues I'm up against (and a blimp is in some senses an ideal long-loiter sensor platform). However in any case it may be a while before I hit the phyiscal hardware stage; I feel like there are a lot of areas of math, aerodynamics, navigation, computer vision, etc, that I need to learn more about first, at least to the point where I can "know what I don't know". This will probably include learning Verilog and FPGA synthesis; hardware support seems key to getting the necessary computational juice.

posted 2006/08/10 08:15 [category: bitbashing / programming]

Thu, 03 Aug 2006

PGP's CEO seems to be misinformed

"Neither signing nor verification is a part of the OpenPGP specification. Surprisingly, some very well-known encryption products also lack this key functionality." - an "interesting" statement from the company blog of Phillip Dunkelberger, current President/CEO of PGP. Time to fire the fact checker, I guess...

posted 2006/08/03 03:14 [category: bitbashing / security]

Into the tunnels...

Under Bolshaya Pirogovskaya Street the Diggers discovered a deserted laboratory with an old telephone, chemical-protection suits hanging on the walls, and old-fashioned respiration masks. The room appeared to have been abandoned in a hurry. In adjacent rooms there were huge flasks, and the floor was covered with crystals.

Someone recently pointed me towards an old (1997) but fascinating article published in the Bulletin of Atomic Scientists about a group of people, the "Diggers of the Underground Planet", who have been exploring the tunnels and passages underneath Moscow for decades.

I'm not convinced that they really have found all of the abandoned laboratories, torture chambers and old murder sites that they claim, but I very much like the idea of it all. And it makes me wonder what is going on underneath DC...

posted 2006/08/03 03:14 [category: bitbashing / misc]

Why doesn't del.icio.us do data analysis?

I am hoping that with the recent Yahoo acquisition, del.icio.us will begin to develop some more interesting data analysis tools. Considering the amount of rich, machine-usable data which is sitting in their database (urls, domains, tags, descriptions, all generated by actual humans), I don't see how they could justify not using it. I assume they have some analysis engines internally, but I would love to see a service that gave you an RSS feed of what people who bookmark the same sorts of things as you are bookmarking now. Might even be able to make some money that way.

While I've found some pretty cool stuff using "show related links" on del.icio.us, it is (as far as I can tell) only taking into account that particular URL, rather than the complete bookmark history of the people who made them. If you want that, you have to do your analysis manually, it seems.

posted 2006/08/03 03:14 [category: bitbashing / programming]

Review: C++ Network Programming Volume 1

I picked up C++ NPv1, partially to familiarize myself a bit with the ACE framework, but also in the hopes of gaining a deeper understanding of good C++ design and of useful patterns for networking code. As I am getting a little work in on my SSL implementation again, I thought it would be beneficial to see what has been done before.

Overall, I was let down. The book felt too broken up in focus, between C++ techniques, portability, patterns, and of course ACE itself. And the book is not that long to start with, so each individual topic was not given nearly the coverage it deserved. In the end the total amount of new knowledge I gained (excepting the parts directly related to using ACE) would probably sum to a few pages at best. Partially this disappointment stems from my high hopes - what I have seen of ACE is very impressive, and I started reading with the expectation that Schmidt would have some deep insights into C++-specific network programming techniques for me.

posted 2006/08/03 03:14 [category: bitbashing / books]

Initial Impressions of C#

For the last month or so, I've been spending some time on a C# application to perform vulnerability analysis of PHP and ASP code. The language was imposed on me by external constraints, but it turns out to be a very reasonable choice for this sort of problem. I'm not doing anything particularly groundbreaking or clever, so it ends up that having really good libraries and a reasonably expressive language is more useful, in terms of immediate productivity, than having a really powerful language and half-assed library support (see: Common Lisp).

I'm sure there are people who scoff at properties as being purely syntactical sugar, but I found judicious use of them can really improve readability without introducing any new dangers to class invariance properties. I was recently tried (again) to tackle a design problem that I've been struggling with in Botan for some time, and realized that properties would be very useful for me. Unfortunately, it doesn't seem possible to emulate them in C++ without paying severe penalties in source code complexity (writing a lot of boilerplate code, or using macros to generate said boilerplate).

The standard library seems fairly good, but is also deeply limited in much the same way that the Java class library is. The support for XML processing, GUI programming, and so forth has all been fairly pleasant and easy to learn. But at the same time, obviously useful utilities such as option parsing and filename wildcarding are nonexistent. You can find several implementations floating around for both of these, most of which are limited, buggy, or just plain bad - one would think that would be hint enough that it should be built in. It's as if nobody at Microsoft ever wrote a nontrivial command-line application in C#.

And would it kill anyone to include parser and lexer generators in the toolset? It's rather sad that in many ways the best language support environment is still for C. While searching for one I could use, I checked the Mono code - and found that it generates the C# parser with a parser generator from the late 80s written in K&R C. Go figure. I ended up using CsLex, which despite not being updated for over six years turned out to work fairly well.

Nits aside, I'd say I'm overall fairly happy with C# as a development environment. Without a doubt there are problems for which it is totally inappropriate, but I can't imagine that I'll ever write Java again (not that I ever wrote much code in Java, anyway). And while Mono's current (beta) implementation of Windows.Forms is horrifically buggy, slow, and visually ugly, the GTK bindings mean that I'll probably never follow through with my original plan of learning GTKmm.

posted 2006/08/03 03:13 [category: bitbashing / programming]

Elegance in Design

It occurred to me this morning that Zippo lighters are, at least for me, the penultimate in design. They always work well, are completely user-serviceable, and nearly anyone can take one apart and see how it works. I think a lot of those same qualities apply to Lisp, which may explain why I like that language so much.

posted 2006/08/03 03:13 [category: bitbashing / programming]

An idea for wireless text messaging

This is one of those things that probably isn't that useful in practice, but I figure I'll never do anything with it so I might as well blog about it. A week or so ago I was spending an evening hanging out and talking about some crypto stuff with Nash Foster, and something we came up during our conversation (I can't remember now who came up with the seed of the idea) was a interesting update model for text messaging.

Right now, as far as I know, when you're putting a message into your Crackberry or phone, the message only exists on your local device, up until the point where you finally hit send. If instead your client were to periodically sync the contents of the text buffer to the remote side (using deltas to minimize network traffic), you could get a screen-like capability for your device. Ideally, this would tie in with your regular email system, so, for example, you could start writing a message on your mobile device, pause it, and then resume writing it in your normal email client once you're at a computer. This would also make the final send fast, as the client would only have to signal to the server that the message has been completed and should be sent; the entire buffer contents would already exist on the other end.

I don't know enough about mobile messaging to know if this is a worthwhile idea, if it has already been tried, or even if this is something that is currently in use. If nothing else, I'm sure someone has patented it by now.

posted 2006/08/03 03:13 [category: bitbashing / programming]