The Museum of HP Calculators

HP-48{S|SX|G|G+|GX}: Vigenere Encryption

Copyleft (C) 2003 Glen Kilpatrick

Distributed under GNU General Public License

This program is supplied without representation or warranty of any kind. The author and The Museum of HP Calculators therefore assume no responsibility and shall have no liability, consequential or otherwise, of any kind arising from the use of this program material or any part thereof.


Theory first: The ONLY completely secure way to encrypt plaintext is with an exclusive XOR, plaintext against a random key of equal length (and we're not even going to Go There, discuss the inherent impossibility of a deterministic state machine producing randomness). The methodology of an XOR with an almost random string, or even totally random byte stream, has been done before and continues to be done today (I recently heard about a startup that plans to sell such a totally random byte stream over the Internet, customers presumably synchronously tap whatever they need from a fire hose of randomness, and there's then no need to send or synchronize that key). The problem, of course, is the secure transmission of that random key; if you can do that securely, why not just send the plaintext message instead, and forget all about encryption?

You can rely upon a secret "codebook" to pass the random key(s), or even hide your codebook in plain sight (The Key to Rebecca comes to mind). If you read science fiction, look for Vernor Vinge's A Fire Upon the Deep, where a certain merchant's cargo is a one-third XOR of a one-time pad; all three thirds XOR'd with each other could produce a pad that end users would use just once, guaranteed privacy in a paranoid galaxy :). But what about a method that lessens the burden of key size and memorability (you still may have to worry about secure key transmission when you're sending encrypted text elsewhere)?

What this program does is XOR the \->STR'd plaintext & key but where the two are of unequal length; from a limited foray into cryptographic literature, this is known as a Vigenere scheme. The shorter is merely repeated until it is the longer, and then truncated back to match. Presumably you'll be wanting an easy-to-remember key, so that's the shorter one. This is NOT secure; there exist methods to take advantage of the repetition, and anyway, will you really be wanting to remember a random key? Use of your Significant Other's birthday will presumably involve use of only alphanumerics, further ease the cracking of the encrypted text. So this is an "OK" encryption, one suitable for privatizing something on your 48 box when that 32 KB just won't allow you to port PGP over, and you're worried about whoever might just lift your toy, what they might find. But don't expect to be able to keep the NSA in the dark for very long....

BTW, one feature of XOR encryption is that it's a symmetrical operation. To encrypt you XOR with the key, to decrypt you XOR with the key, it's the same execution.


The 48 is my absolute favorite programming machine, RPL my absolute favorite programming language. I feel about it the way that I read some do about the 41 series. Oh, a color, backlit LCD would be mighty fine to have, but the basic box contains more goodies than I'll ever use, and not a few baddies as well (my limited enthusiasm for the LS-ENTER EQUATION editor won't ring any bells). However, many of my "programs" are merely automation "one-shot's", not of general interest.

Note that this will probably work on an HP-49G, but another will have to confirm....

And finally, Simone Rapisarda's coder13 (ZIP files here and also here ) provides the same functionality, and publication-wise predates mine by several years (I of course don't know which was written first, I'm not even sure when I wrote mine, only that these two were independently created). And as it's entirely stack based (mine uses local variables), it's also smaller and faster. However, I'll lay claim that mine may be easier to understand, and thus to modify (a characteristic tradeoff of stack based vs. local variable based is that stack manipulations are faster and more compact, whereas local variables let one attach names to objects).


To execute, supply a plaintext and a key (either first, order does not matter as whichever's shorter gets multiplied out then truncated appropriately), e.g.:

"Hello, World" "xyzzy" Vigenere ---> "0****TY-***"

Note that what I have portrayed as "*" is one of those small, solid and centered squares that the 48 uses to indicate an "undisplayable" character. You may or may not be able to edit this string; the computed presence of one NULL character (0 CHR will create this) defeats the EDIT function; this is a design feature from HP. But EDITing it will in any event most likely be meaningless.

To decrypt, just reapply the same function with the same key against the encrypted string. If it's in Level 1, then you do:

"xyzzy" Vigenere                ---> "Hello, World"

The reason for the { OBJ\-> } TMENU at the end of the program is that I will frequently encrypt other than strings. Only strings may be XOR'd for this encryption (and Vigenere automatically \->STR's both plaintext and key just in case), so having a (Temporary) TMENU function to translate the decrypted string back to its original TYPE may prove useful.

Program Listing

\<< "Vigenere" 1 DISP
  \<< SWAP
  \>> IFT DUP \-> pt ky
k\Sigma SIZE >
    REPEAT k\Sigma ky +
'k\Sigma' STO
    END pt k\Sigma 1 pt
\>> 'Vigenere' STO
'Vigenere' RCL BYTES                   ---> # 26870d & 191

Note that k\Sigma is just a variable name, a lowercase k followed by a RS-TAN.

Resources Used

Variable Vigenere; two arguments eaten from the stack, one argument returned.

Go back to the software library
Go back to the main exhibit hall