Wednesday, December 16, 2009

Who Says You Can't Access Free Variables Outside the Closure?

1 Introduction

I'm working through Paul Graham's excellent 1993 book, On Lisp.

In one sections he discusses how to make recursive calls to closures. As the Wiki entry says: "In computer science, a closure is a first-class function with free variables that are bound in the lexical environment."

This is exactly correct. I guess I've known about closures for at least 15 years, maybe longer. Thus, when reading Graham's discussion of closures in Lisp, I didn't figure that I'd learn much new, but was certainly looking forward to the discussion from a Lisp perspective.

His first example caught me off-guard:

(defun list+ (lst n)
  (mapcar #’(lambda (x) (+ x n))
          lst))

He writes: "If we look closely at the function which is passed to mapcar within list+, it’s actually a closure. The instance of n is free, and its binding comes from the surrounding environment. Under lexical scope, every such use of a mapping function causes the creation of a closure." (p.18)

I'd never thought the nature of the lambda expression when using mapcar in a lexical scope. I wouldn't have called it closure. Probably because the lambda expression is created and destroyed within the lexical scope of the enclosed variable.

Graham's definition was forcing me to call something a closure, before the lexical scope had been destroyed.

I was introduced to closures through Perl and blessed pointers. Anonymous functions were created, closed around my variables (free lexical variables in perl are my variables) and their reference returned. With the lexical environment destroyed upon that return, the variable entry removed from the symbol table, there was no way to get to it, unless you could manipulate it through calls to the closure. (Hello object oriented programming.)

Graham's presentation made me question whether or not the value of the enclosed variable could be changed after the function had been instantiated, but before the lexical scope was destroyed.

What if I played with the enclosed variable before the lexical scope vanished?

Of course the question is really this: does the closure have the address or the value of n?

I felt like I knew the answer, even though my brain kept repeating, "you cannot access variables contained in closures, you cannot access variables contained in closures, warning, warning."

But I knew I could. I became a mad scientist, or at least like Gene Wilder's interpretation of one: "It could work!"

(defun test (n)
  (let ((x 0))
    (setq x #'(lambda () (setq n (1+ n))))
    (setq n 33)
    x))

Then: (setq x (test 1) and (funcall x)

What's the value returned by the funcall?

That's what got me. My brain kept repeating that enclosed variables could not be changed, therefore the value 2 must be returned. After all, n is enclosed.

But then comes the realization that the lexical scope of n had not vanished after the instantiation of the closure into x. The variable n is still very much accessible outside the closure for one brief, fleeting, s-expression, (setq n 33).

Of course the value 34 is returned. It's obvious.

2 More

Graham follows up with another problem:

"a function defined in a lambda-expression doesn’t have a name and therefore has no way of referring to itself. This means that in Common Lisp we can’t use lambda to define a recursive function." (p. 21)

This means that one of the most common idiom's in Lisp (recursion, the sine qua non of Lisp, it would seem) is not available when using another common idiom mapcar.

Of course,there is a way around this using labels. On page 22 he gives the following example:

(defun count-instances (obj lsts)
 (labels ((instances-in (lst)
           (if (consp lst)
             (+ (if (eq (car lst) obj) 1 0)
                (instances-in (cdr lst)))
             0)))
          (mapcar #’instances-in lsts)))


This function works as follows:

> (count-instances ’a ’((a b c) (d a r p a) (d a r) (a a)))
(1 2 1 2)

This illustrates recursion, but I don't like the function.

If the list is something like:

> (count-instances ’a ’((((a)) b c) (d (a r p a)) ((d a) r) (((a)) a)))

Then the result is: (0 0 0 1)

I don't think that's as interesting as returning the number of first level grouped objects, no matter how deeply embedded in the tree, or in this case: (1 2 1 2).

I decided to try and modify it to suit me. Fortunately it's pretty easy to do:

(defun count-instances-new (obj lsts)
  (labels ((instances-in (lst)
             (if (consp lst)
                 (if (consp (car lst)) 
                     (+ (instances-in (car lst))
                        (instances-in (cdr lst)))
                     (+ (if (eq (car lst) obj) 1 0)
                        (instances-in (cdr lst))))
                 (if (eq  lst obj) 1 0))))
    (mapcar #'instances-in lsts)))


3 Conclusion

Learn Lisp. You'll be a better programmer!

Tuesday, December 8, 2009

Get Another DNS

1 Introduction

For whatever reason, after I upgraded to Ubuntu's Karmic Koala (9.10) (review here and here) browsing was very slow. Or rather it was slow when my laptop was hooked into one network, but not another.

It seemed to be caused by the DNS nameserver configuration.

I did some research and found that changing DNS nameservers is a piece of cake.

What's is DNS and how does it work? Read this Wiki entry for the details. The short answer is that DNS is the Internet's phonebook. DNS nameservers convert names (like LinuxDoe.blogspot.com ) into IP addresses, just like the traditional phone book converts names into telephone numbers.

There at least three DNS nameservers that you can choose from, right now. You can pick the one you want.

Not only could this affect the speed at which you cruise the Internet, but a DNS nameserver might provide a phishing filter, domain blocking, and typo correction.

2 What DNS Nameserver Am I Using Right Now?

The DNS nameserver that you're currently using is in the file /etc/resolv.conf/

kes@Cyclone:~$ cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 8.8.8.8
nameserver 8.8.8.4
kes@Cyclone:~$ 

The first namserver listed is the primary and the second is the secondary.(8.8.8.8 and 8.8.8.4, for those in the know are the Google DNS nameservers. More about that later.)

For the next section, you'll also need the name of your network interface.

kes@Cyclone:/etc/modprobe.d$ ifconfig -s # netstat -i works too
kes@Cyclone:/etc/modprobe.d$ ifconfig -s #netstat -i works too
Iface   MTU Met   RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0       1500 0    187707      0      0 0        126029      0      0      0 BMRU
lo        16436 0       102      0      0 0           102      0      0      0 LRU

3 Change To Another DNS

The easiest way to do this is to edit /etc/resolv.conf. And then bounce the interface (you'll have to use the name of your interface).

kes@Cyclone:~$ sudo cp /etc/resolv.conf /etc/resolv.conf.bak
kes@Cyclone:~$ sudo vim /etc/resolv.conf
kes@Cyclone:~$ sudo ifconfig eth0 down && ifconfig eth0 up # You Iface may not be eth0

But this won't work if you're using DHCP (you probably are), because it will overwrite your /etc/resolv.conf file.

In that case, modify =/etc/dhcp3/dhclient.conf

# Configuration file for /sbin/dhclient, which is included in Debian's
#       dhcp3-client package.
#
# This is a sample configuration file for dhclient. See dhclient.conf's
#       man page for more information about the syntax of this file
#       and a more comprehensive list of the parameters understood by
#       dhclient.
#
# Normally, if the DHCP server provides reasonable information and does
#       not leave anything out (like the domain name, for example), then
#       few changes must be made to this file, if any.
# 

option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;

send host-name "<hostname>";
#send dhcp-client-identifier 1:0:a0:24:ab:fb:9c;
#send dhcp-lease-time 3600;
#supersede domain-name "fugue.com home.vix.com";
#prepend domain-name-servers 127.0.0.1;

See the last line? Modify it so it looks like this: prepend domain-name-servers 8.8.8.8,8.8.4.4;

The IP addresses 8.8.8.8,8.8.4.4 are the Google Public DNS nameservers.

Don't forget to bounce your interface.

kes@Cyclone:~$ sudo ifconfig eth0 down && ifconfig eth0 up # You Iface may not be eth0

The above is pretty good, but if you're using DHCP, you'll end up with a /etc/resolv.conf that looks like this.

kes@Cyclone:/etc/dhcp3$ cat ../resolv.conf
# Generated by NetworkManager
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 10.1.10.1

Which is not altogether bad.

Another way to modify your nameservers is as follows:

  1. System menu => Preferences, => Network Connections.
  2. Select the network interface. (Perhaps called eth0)
  3. Edit => IPv4 Settings.
  4. In the dropdown, select Automatic (DHCP) addresses only.
  5. In the DNS servers field, enter "8.8.8.8 8.8.4.4" (without the double quotes and don't forget the space).
  6. Click Apply

In the above, number 4 means that you are going to use DHCP, but DHCP should not automatically get the address of the DNS nameservers. This allows you to specify the DNS nameserves in the DNS servers field.

And now the resolv.conf looks like this:

kes@Cyclone:/etc/dhcp3$ cat ../resolv.conf
# Generated by NetworkManager
nameserver 8.8.8.8
nameserver 8.8.4.4

4 Other DNS Nameservers

Here are two (you can find lots others, I'm sure).

  1. Google Public DNS is available here.
  2. OpenDNS is here.

5 Conclusion

Congratulations! You have just learned how to configure your DNS nameservers!

Sunday, December 6, 2009

Emacs Fiddling Stick


1 Introduction

One of the primary reasons for using is emacs is that it gives you the ability to fiddle. If you don't want to fiddle, then you may as well use Vim.

But fiddling can be hard, and if you're just staring out, you have no idea where to begin. It's like you've lost your fiddling stick.

Sort of makes me think of that child's poem that has the line: "my master's lost his fiddling stick and knows not what to do."

Fiddling in emacs starts with learning how to get some of the information that is just waiting for you.

2 Getting Information: keybindings, functions, variables

This is really basic, but if you don't know this no progress can be made towards fiddling with emacs. The true emacs fiddler must know these key strokes cold.

And by the way, getting information about emacs, its functions and variables, key-bindings and everything else is a little like drinking from a fire hydrant. It can be overwhelming, but don't worry. Go at your own pace, get what you need, following what you think is interesting, don't get bogged down. Just learn a little bit at a time. Soon you'll know a lot.

Note: ALL of this information is available to you by typing C-h ?. Here I'm presenting only a bite size amount.

Emacs has a lot of keybindings. A keybinding is emacs speak for the association of a key combination with a Lisp function. Sometimes, it is really helpful to get information about these keybindings. There are four important ways to get documentation about a keybinding:

  1. C-h c KEY: displays the name of the command that KEY is bound to. For example, if you type, C-h k, followed by C-h k, in the minibuffer you'ss see: "C-h c runs the command describe-key-briefly" (without the quotes, of course).
  2. C-h k KEY: sort of like the above, but displays the documentation string (i.e., documentation that is embedded in the Lisp function) of the command as well as it's name, in another window. Try it now. Type C-h k C-h c. You should see:
    C-h c runs the command describe-key-briefly, which is an interactive compiled
    Lisp function.
    
    It is bound to C-h c, <f1> c, <help> c.
    
    (describe-key-briefly &optional key insert untranslated)
    
    Print the name of the function key invokes.  key is a string.
    If insert (the prefix arg) is non-nil, insert the message in the buffer.
    If non-nil, untranslated is a vector of the untranslated events.
    It can also be a number in which case the untranslated events from
    the last key hit are used.
    
    If key is a menu item or a tool-bar button that is disabled, this command
    temporarily enables it to allow getting help on disabled items and buttons.
    
    [back]
    
  3. C-h K KEY: Takes you into the comprehensive Info documentation system and will tell you everything you could possible want or need to know about KEY. Very helpful. As above, try it now. Type C-h K C-h c.
  4. You can get a list of the entire key-to-function bindings by typing C-h b. In this list is displayed the associated function. Clicking on the function will give you the function's documentation string. Here's a sample of the output from C-h b.
    C-@             set-mark-command
    C-a             move-beginning-of-line
    C-b             backward-char
    C-c             mode-specific-command-prefix
    C-d             delete-char
    C-e             move-end-of-line
    C-f             forward-char
    C-g             keyboard-quit
    C-h             help-command
    C-j             newline-and-indent
    C-k             kill-line
    C-l             recenter-top-bottom
    RET             newline
    C-n             next-line
    C-o             open-line
    ...
    ...
    ...
    

And you can also get information about functions and variables that emacs knows about:

  1. C-h f FUNCTION: this displays the documentation for a Lisp function. (Note: if the function is bound to a key sequence, then this is exactly the same as C-h k KEY.)
  2. C-h v VARIABLE: This is the describe variable command.

3 The Motherlode: Info

Typing C-h i takes you into the Info system.

(dir)Top

The Info Directory
******************

The Info Directory is the top-level menu of major Info topics.
Type "d" in Info to return to the Info Directory.  Type "q" to exit Info.
Type "?" for a list of Info commands, or "h" to visit an Info tutorial.
Type "m" to choose a menu item--for instance,
"mEmacs<Return>" visits the Emacs manual.
In Emacs Info, you can click mouse button 2 on a menu item
or cross reference to follow it to its target.
Each menu line that starts with a * is a topic you can select with "m".
Every third topic has a red * to help pick the right number to type.

* Menu:

* Info: (info).                    How to use the documentation browsing system.

Emacs
* Auth-source: (auth).                     The Emacs auth-source library.
* D-Bus: (dbus).                   Using D-Bus in Emacs.
* EasyPG Assistant: (epa).         An Emacs user interface to GNU Privacy Guard.
* Emacs: (emacs).                  The extensible self-documenting text editor.
* Emacs FAQ: (efaq).       Frequently Asked Questions about Emacs.

I have no idea how long it would take you to read all of it. I wouldn't want to try.

4 Conclusion

Congratulations! You have just learned how to get some of the basic information that is available to you in emacs.

Saturday, December 5, 2009

Big-Endian or Little-Endian?

1 Big-endian or Little-endian?

Computers store multibyte values in either big-endian or little-endian order.

What does this mean?

Suppose we are on a machine that has two-byte integers. And we do the following:

  int main()
  {
    int i; 
    i = 1;

    ...
    ...
    ...
}

How is the value 1 (or 00000000 00000001) stored in memory?

In what order are the bytes stored?
Memory LocationValue
000Ax00000000
000Bx00000001

Or

This is different
Memory LocationValue
000Ax00000001
000Bx00000000

Little-endian refers to the idea that the least significant byte (that's LSB) is stored in the lower memory location. (Mnemonic: Least-Low-Little)

Big-endian refers to the idea that the most significant byte (that's MSB) is stored in the lower memory location. (Mnemonic: Most-Low-Big)

Can you look at the tables above and identify which is big-endian and which is little-endian?

The first table shows a computer architecture that is big-endian, the second table, little-endian.

2 Determining Endedness

Determining whether or not we are big- or little-endian is not that hard, but your first guess of how to do it, may be wrong. Here's some code.

#include <stdio.h>
int main()
{
  int i, j;
  char *ptr;

  /* Will shifting work? */

  i = 1;
  j = i >> 1;

  if (j == 0){
    printf("Big-endian\n");
  }else{
    printf("Little-endian\n");
  }
/* This tells Big-endian --- but read on! */

  /* Casting gets us to the byte we want */
  i = 1;
  ptr = (char *) &i;

  /* ptr now points to the lower memory address */
  if (*ptr == 1){
    printf("Little-endian\n");
  }else{
    printf("Big-endian\n");
  }
  /* Prints 'Little-endian' --- that's correct */

}

The first attempt didn't work. That's because the shift operators work in a logical fashion, according to a logical representation of bit patterns.

As such, it's impossible to get to the actual layout of the hardware using them.

But by casting the integer to a char, we can get the first byte, and it becomes possible to determine if the machine is big- or little-endian.

Friday, December 4, 2009

PGP: Pretty Good Privacy is a Pretty Good Idea

1 Email

In the world of data transmission on the Internet, email is about as secure as your house would be if you removed the front door, the back door, and all the windows. It's not secure at all, and anybody with a network sniffer can see the data packets as they travel on the network. Most people have a vague idea about this, but they don't know the half of it.

Never send any sensitive information using email.

Sensitive information is defined as anything that you don't want prying eyes to see. It certainly includes things like bank account numbers, credit card numbers, and social security numbers, and the password to your online stock brokerage account. We'd never think of sending this information in email.

But what about other stuff? Stuff that is personal and potentially embarrassing? Innocent things that we might say in email, about sick kids, mother-in-laws, and the doctor putting you on blood pressure pills are all things we might not want others to know. Or may be you hold strong political views about any number of current issues: abortion, gay marriage, the war. All of these is potentially personally embarrassing, maybe even professionally harmful. Whatever, it's nobody else's business, is it?

And yet despite the insecure nature of email, we use email almost daily to communicate about all sorts of personal things that we'd rather others didn't know. Some do it because they don't know any better. Others because it's the easiest and most readily available means of dashing off the quick note. Whatever the reason, the temptation is too great. After all, who hasn't sent sensitive information in email?

Is there an easy way to make email secure.

Happily there is.

PGP (Pretty Good Privacy) was created by Philip Zimmermann in 1991. It is used for both privacy and authentication. An implementation of Zimmermann's algorithm has been developed by Gnu, called gpg.

The basic idea of PGP is to encrypt data with one key and then to decrypt it with another. Let's call one key public, because everybody has access to it, and the other private, because it's secret and only the owner has it.

How might we use a public and private key encryption-decryption system?

2 Private Communication

Suppose that you want to send a private email to Mary Jo. Only Mary Jo should be able to see the contents. Fortunately, just like you, Mary Jo uses gpg. She has created a public/private key pair. You have access to Mary Jo's public key (just like everybody else).

You encrypt your message to Mary Jo using her public key.

Now the message looks like a string of random characters, gibberish, and nobody else can read the message.

You send the encrypted message to Mary Jo via email.

Mary Jo gets the encrypted message. She decrypts it using her private key. Nobody else has Mary Jo's private key. She reads the message.

Suppose Mary Jo wants to respond back to you privately. She writes a message to you and she uses your public key (openly available to everybody) and the process repeats. You'll get the encrypted message from her and decrypt it with your private key.

This scenario has shown us that we can use PGP for secure, private, communication.

3 Authenticated Communication

There's another way to use PGP, and that's for authenticated communication.

Suppose you want to send an email to Mary Jo, but Mary Jo needs to be assured that the email is actually from you, or to put it another way, that it's authentic.

Here's how it works. You write your message and then sign it, not with Mary Jo's public key, but with your private key.

Mary Jo receives the message, but how can she know that it really came from you? She tests the signature with your public key. Only your public key authenticates the message, because that message was signed by you with your private key.

This scenario has shown us that we can use PGP for authenticated communication.

4 Using GPG: an implementation of PGP

Your Linux distribution probably already has a PGP implementation called gpg.

On my system, running Ubuntu 9.10 (karmac), I can grep for gpg from the list of packages and get the following:

dpkg -l | grep gpg
ii  gpgv                                           1.4.9-4ubuntu7                             GNU privacy guard - signature verification t

If you don't have it, you can either install the package, or download from the GnuPGP website.

5 Creating a Private/Public Key Pair

We're going to assume that Mary Jo wants to receive secure communication from Sam. Here's how she sets it up.

First step is for Mary Joe to generate her key:

mjj@example.com:~$ gpg --gen-key

In order to generate the key, gpg will ask Mary Jo a series of questions:

gpg (GnuPG) 1.4.9; Copyright (C) 2008 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
(1) DSA and Elgamal (default)
(2) DSA (sign only)
(5) RSA (sign only)
Your selection? 

Mary Jo simple selects the default.

DSA keypair will have 1024 bits.
ELG-E keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 

And again, she accepts the default.

Please specify how long the key should be valid.
     0 = key does not expire
  <n>  = key expires in n days
  <n>w = key expires in n weeks
  <n>m = key expires in n months
  <n>y = key expires in n years
Key is valid for? (0) 

This is an interesting question. How long should the key be valid? If the key never expires, and the key becomes compromised (i.e., Mary Jo loses her private key), then anything encrypted with it will be compromised. On the other hand, if the key expires in 1 day, she'll constantly be creating new keys. A reasonable compromise? I'd say six months to one year.

Key is valid for? (0) 6m
Key expires at Wed 02 Jun 2010 01:29:22 PM PDT
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
       "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: 

Now Mary Jo is asked to fill in identifying information.

Real name: Mary Jo Jones
Email address: mjj@example.com
Comment: 
You selected this USER-ID:
"Mary Jo Jones <mjj@example.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.

Enter passphrase: 

The passphrase is a long string that only Mary Jo knows. What's appropriate here? Something long with lowercase and uppercase letters, numbers and punctuation. And something she won't have to write down to remember.

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

.+++++.+++++.+++++++++++++++.++++++++++.+++++++++++++++.++++++++++.+++++.+++++..
+++++++++++++++++++++++++.++++++++++.++++++++++++++++++++++++++++++..>+++++.....
............................................+++++
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
+++++.++++++++++++++++++++++++++++++++++++++++.+++++..+++++++++++++++...+++++..+++
++..+++++..++++++++++.++++++++++.++++++++++++++++++++...+++++..+++++++++++++++..++
+++>++++++++++>+++++>+++++.................................>+++++.................
..........................................................+++++^^^
gpg: key 8888BBD4 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u
gpg: next trustdb check due at 2010-06-02
pub   1024D/8888BBD4 2009-12-04 [expires: 2010-06-02]
Key fingerprint = C61E 14EC 8078 AC8C 59A6  D909 7B07 6A08 8888 BBD4
uid                  Mary Jo Jones <mjj@example.com>
sub   2048g/092F4D36 2009-12-04 [expires: 2010-06-02]

That's it! Mary Jo has created a public and private key.

Now she needs to share her public key with others. It doesn't matter who knows the public key. Public keys are, after all, meant to be public. But her point in doing this is that she wants Sam to have it, so that Sam can send her private messages.

Mary Jo must export the public key.

mjj@example.com:~$ gpg --armor --export "Mary Jo Jones"
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.9 (GNU/Linux)

mQGiBEsZcSIRBACmAct8gJeyp84JaZw7mkvx3rVwlkaYMkG4whQ9kVutYHlgzr+8
GhQVB1XEnXfAZdqO2/7vTIZJW3cbjMYkDXFhknXMbIQMUMyEt6N97gpQfw38mXaq
7eYppwjQiiw1vIKmtQl0AkMVhvK6MQVmwwk7U4kAN9o5XG8vLJubG0uFvwCgrw+K
a9k/mEYRjKsS6Zidxrd5s0MD/jvIt6aSdE4nXv2lAx76l/mdvXFvHoJD8N1+zQ04
WM9RA8C7lo96JiBLsqwRR8r9JaoinwSFKegMCR5p/KWjp8MxyBaKHqd4pt5X1Axp
myIm4tbIyq434cvVMVAtHPnPNFowql9FKXjLZ9QK1TgK/2DRElwD1WQrSZT+aJGf
6RnyA/9lUwOG9q41ByEpWZx2iCrIjNL9pkjrSGCQWM88xg81a5VCgBQhZEcDDcFe
W0oElFknUUASElz0vYImA4gf8hsZ7dVMnETzo9DflnlGB3b83Czxd1ys3QeUhJhM
roXWeh3qD9U6fBbdoLOIWPJ0xNLhPx4nqv47SX5WnnYEgfnNzrQfTWFyeSBKbyBK
b25lcyA8bWpqQGV4YW1wbGUuY29tPohmBBMRAgAmBQJLGXEiAhsDBQkA7U4ABgsJ
CAcDAgQVAggDBBYCAwECHgECF4AACgkQewdqCIiIu9SZsQCfej7huito5s4fiLsZ
A7LbDiZEacsAnjbDTlxqfFJgr017vmhSYxgAZiUIuQINBEsZcSIQCACR/Ggqhcle
1FPAGlr29rhEPekFXTXlpezXaWIoMctUmyrHMzzjGwP6cI8B0N/SX6bFGYfyJVk1
FueFTV87dcA791Am/h3d+6Vg4jeizsWzKPkpPRuSycAftz3Nv5jqxfgMTwSvTq92
qRPZmWPTraNJXLqESJKUe0/6CzX7h5oijTDAA8Yq2IvdQp5lkDac3lDC60DbGalb
vas7R4CckfdyMtc9ZOSgrGZ+P5LEq5ivMmi6zv/+ijzjQ7oNpdsAIIobeeX89mDh
2C9RnkGHtx52zqgNCrhzDkyvdWhcjAYpKPDzFwZyzyruYausLQ3pq4x9BBzCe2Jv
xGhPD0YCZxe7AAMFB/9pcLD08sR/1EpvUjDNLGLprQrulXL39tPGixxEhie8E0Pw
jfMckPSUcaXoOMvXDqgqGh/4ITIsA7fg5mQp3bgFxZWxm0JyJq7UQAxzMfhtG2GV
Y8rnmuinPdRpTXMkjswoDqTNvJsVvLcjyqaZjZaXVMgdN+ayqsYI7pLFErkdP1s9
h3Cp874226iSiBzwjxKZuCqmgbt/0RdpCVz+sQwoqXTJcJthGtk4ZFYv9P82CXMi
3N+AwScx7a3zZasH30n4o4Pr/FvDTByQfZempxX+PdGCS8jH31RLGImz9UHLp+52
E0LiMU54V3A8aasViQco2gNpjKjPJprpYTOmUKjSiE8EGBECAA8FAksZcSICGwwF
CQDtTgAACgkQewdqCIiIu9ReSgCgqObqN6FkRwk+9KP01EcpMc9BP4IAoJmKd6xA
wjNXz+WB4+hUzPX7lahQ
=TN4y
-----END PGP PUBLIC KEY BLOCK-----

Now Mary Jo cuts and pastes this into an email to Sam. Sam will then import this key into his keyring. Let's assume that Sam puts the key into a file called key.

sam@example.com:~$ ls
key
sam@example.com:~$ gpg --import key
gpg: directory `/home/sam/.gnupg' created
gpg: new configuration file `/home/sam/.gnupg/gpg.conf' created
gpg: WARNING: options in `/home/sam/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/home/sam/.gnupg/secring.gpg' created
gpg: keyring `/home/sam/.gnupg/pubring.gpg' created
gpg: /home/sam/.gnupg/trustdb.gpg: trustdb created
gpg: key 8888BBD4: public key "Mary Jo Jones <mjj@example.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1

6 Using the Public/Private Keys for Privacy

Everything has been set up for Sam to send encrypted messages to Mary Jo.

So, how does he do it?

First he creates a message

sam@example.com:~$ cat message
Let's meet mom and dad for lunch.

Now, he encrypts it.

sam@example:~$ gpg --armor --encrypt message
You did not specify a user ID. (you may use "-r")

Current recipients:

Enter the user ID.  End with an empty line: Mary Jo
gpg: 092F4D36: There is no assurance this key belongs to the named user

pub  2048g/092F4D36 2009-12-04 Mary Jo Jones <mjj@example.com>
Primary key fingerprint: C61E 14EC 8078 AC8C 59A6  D909 7B07 6A08 8888 BBD4
Subkey fingerprint: 130D A4AF 9366 42CE F7D7  272E 06FE EC0C 092F 4D36

It is NOT certain that the key belongs to the person named
in the user ID.  If you *really* know what you are doing,
you may answer the next question with yes.

Use this key anyway? (y/N) y

Current recipients:
2048g/092F4D36 2009-12-04 "Mary Jo Jones <mjj@example.com>"

Enter the user ID.  End with an empty line: 
sam@example.com:~$ ls
key  message  message.asc

The message.asc is the encrypted message. Let's see what's in it.

sam@example.com:~$ cat message.asc
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.4.9 (GNU/Linux)

hQIOAwb+7AwJL002EAf9FggZeDtS9OB9cuXtM/TRsNlKHCtuKMd+aMr2h1m/CpoO
cWpXG3NOBT/0UW5iYntW1N6Ofhjykr1gkJBFvsdCa1dg5rc8Kl2Js6DZh6Y7eNEA
Osto+AvzZDI8dvH4FJjEw8hnSTqpQfnkQEGX0uo0cJdZX8EEeUV0iMmN7UB6r4St
vQdpJYyamoqZaWYx40YUdXZFB+fYQ5xvMS3QDy4es/gTHaNppaGqZitmPK71bZwZ
1VZt2nNemRivvnxWaKgSWW7gTmfDruVaTLfyXfn97jFyAQAdZq/rjWKipZiZuMAl
gXV8yta5z2TmyCmHOBQSA5LeBAg1dyvmATzn2OHmoAf/bIqpLj7lSSmGeffh45Rn
fMatNflNMPaDeHc5aq4kjP9qQELDH8+KIiDXY7o701h4ICtzIZuKepkJNfxEklu5
l25lvEA3Cri75yLIDDphJqsf/NdWyrUnFVSvh+q85nhE8qjCkVsmPFCGAub7mmHL
W7jb4moYWRdpPLgL46zR84wAO5Tu7KAcNAateMi6OEmoGxMExX4uB2vk+GAG7FVR
p9bWKXeH9r++RNke29/rsLHPH9h4gAVLmb8VILzhXep5mXaQOh/yb4oeEZod3HiD
g/JkU2C8y4mXrEkXw0DyxbRw36Sh5r7dFHalUZiG4d8zA0ViS7TFEGCSXVaVESMK
FNJkAS239J/YxWky1b12rkuaY4yEw0vC0MH4DlFa2kQptzneA87XZ6JmQLT/D822
tglvIaVT/0IM8g6fZWnjy6LSdvYBagB6L5mYOuuoxcLmSCe6E49biuctVo7hgqn2
lIu1Ygf9Rg==
=iA+4
-----END PGP MESSAGE-----

So, Sam puts this message (encrypted with Mary Jo's public key) into an email. The only way that this message can be decrypted is with Mary Jo's private key. Let's see how she does it.

mjj@example.com:~$ gpg --decrypt message.asc

You need a passphrase to unlock the secret key for
user: "Mary Jo Jones <mjj@example.com>"
2048-bit ELG-E key, ID 092F4D36, created 2009-12-04 (main key ID 8888BBD4)

gpg: encrypted with 2048-bit ELG-E key, ID 092F4D36, created 2009-12-04
"Mary Jo Jones <mjj@example.com>"
Let's meet mom and dad for lunch.

7 Using the Public/Private Keys for Authentication

Suppose Sam needs to be sure that a public unencrypted message that claims to be from Mary Jo really is. That is, that the message is authentic.

PGP can do this too.

This is called signing the message.

Mary Jo creates a message and puts it into the file called message.

mjj@example.com:~$ cat message
I can meet mom and dad for lunch. See you at 1:00!

Now she signs the message with the following:

mjj@example.com:~$ gpg --clearsign  message.signed

You need a passphrase to unlock the secret key for
user: "Mary Jo Jones <mjj@example.com>"
1024-bit DSA key, ID 8888BBD4, created 2009-12-04

Enter passphrase: 

After entering the passphrase, a file called message.signed is created. It contains the signed text.

mjj@example.com:~$ cat message.signed
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I can meet mom and dad for lunch. See you at 1:00!
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAksZiN4ACgkQewdqCIiIu9RazQCgjJh11+H5M92ss5qRIj4+FamJ
rRQAniieQI8jIC2t4RN/omrYcV7j6sFN
=hKjl
-----END PGP SIGNATURE-----

Sam gets the message from Mary Jo. Now he wants to verify it.

sam@example.com:~$ gpg --verify message.signed
gpg: Signature made Fri 04 Dec 2009 02:10:38 PM PST using DSA key ID 8888BBD4
gpg: Good signature from "Mary Jo Jones <mjj@example.com>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: C61E 14EC 8078 AC8C 59A6  D909 7B07 6A08 8888 BBD4

So you see that the signature is good. Sam is assured that this message has come from Mary Jo.

For a test let's change the text in message.signed to this:

sam@example.com:~$ cat message.signed
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I can meet mom and dad for lunch. See you at 2:00!
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAksZiN4ACgkQewdqCIiIu9RazQCgjJh11+H5M92ss5qRIj4+FamJ
rRQAniieQI8jIC2t4RN/omrYcV7j6sFN
=hKjl
-----END PGP SIGNATURE-----

The time has been changed from 1:00 to 2:00. What happens when Sam tries to verify the message now?

sam@example.com:~$ gpg --verify message.signed
gpg: Signature made Fri 04 Dec 2009 02:10:38 PM PST using DSA key ID 8888BBD4
gpg: BAD signature from "Mary Jo Jones <mjj@example.com>"

As you can see the signature is now bad. This message did not come from Mary Jo.

8 Conclusion

There's more. Like putting your public key on a key server, and setting up you mail reader to automagically use gpg.

That will come later.

For now work through practicing with gpg.