triptico.com

Un naufragio personal

GPG Cheat Sheet

This is a very basic guide to use GPG (GNU Privacy Guard), the free software version of the classic PGP (Pretty Good Privacy) tool for signing, encrypting and verifying information. It can be handy if your Email client does not directly support it. This guide explicitly do not explain creating and maintaining keys and keyrings.

For this tutorial we have the following two individuals: Angel, with email address angel@triptico.com and Johannes, with email address johannes@comam.es. They both have GPG installed on their systems and have valid keys. Additionally, each user have another one's public key installed in ther keyrings.

Also, there is a two line message they want to share:

 I am the voice of Mother Earth,
 from whence all horrors have their birth.

Signing

Angel wants to send the creepy message to Johannes. Also, he wants to be sure that Johannes can check that he is who really sent the message. So he runs the following command in its terminal:

 gpg -s --clearsign

GPG politely says the following:

 You need a passphrase to unlock the secret key for
 user: "Angel <angel@triptico.com>"
 1024-bit DSA key, ID 70C9B100, created 2012-11-07
 Enter passphrase:

This operation implies the use of Angel's private key, that is password-protected inside his keyring. If the password is correctly entered, GPG waits silently for text from its standard input. Angel pastes the message and GPG dumps the following:

 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 I am the voice of Mother Earth,
 from whence all horrors have their birth.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 iEYEARECAAYFAlvrxGIACgkQ5CXHVHDJsQBOagCfQAFQoZyFfegGZUa8oWwn/srg
 1RwAoMFcDABbLpqaqpwIVqv5U4pYvdVb
 =q64b
 -----END PGP SIGNATURE-----

This piece of text (including the BEGIN... and END... lines) can be pasted to the email body of a message sent to Johannes. Please note that you can write whatever you want outside the PGP boundaries and the message will still be considered valid when the signature is checked. So this can be the full email body:

 Hey, Johannes. This is what he said:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 I am the voice of Mother Earth,
 from whence all horrors have their birth.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 iEYEARECAAYFAlvrxGIACgkQ5CXHVHDJsQBOagCfQAFQoZyFfegGZUa8oWwn/srg
 1RwAoMFcDABbLpqaqpwIVqv5U4pYvdVb
 =q64b
 -----END PGP SIGNATURE-----
 Best regards, Angel

Of course, the surrounding text must not be considered signed text. This is a common mistake.

Checking signatures

Johannes receives the message in his Inbox. He's absolutely unsure if it's really Angel who quoted the eerie text; so, he just calls GPG with no arguments:

 gpg

And gets the following reply:

 gpg: Go ahead and type your message ...

Johannes selects and copies the full message body and pastes it into GPG's standard input. Then the program replies:

 I am the voice of Mother Earth,
 from whence all horrors have their birth.
 gpg: Signature made Tue Nov 13 15:02:38 2018 CET using DSA key ID 70C9B100
 gpg: Good signature from "Angel <angel@triptico.com>"

So Johannes can be confident than Angel really sent the two-line message (the rest of the text is considered irrelevant and is ignored). GPG does not need any password to check the signature: all it needs is Angel's public key that it's stored in Johannes' keyring but not protected in any way (Angel's public key can be shown in his web home page or printed and glued on the street lamps of the town if he wants, as it's not sensible information).

Please note that, though GPG apparently mixed the message and its own information, the first one is sent to the standard output stream and the second one to its standard error/status stream; Johannes only sees them together because of the way his terminal shows these channels by default.

Tampering detection

Let's suppose some evil being tries to feed its dirty lies to Johannes, trying to take advantage of the confidence between both and impersonating as Angel. So it somehow obtains a copy of the message and does some subtle changes:

 Hey, Johannes. This is what he said:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 I am the voice of Mother Moon,
 from whence all horrors have their doom.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 iEYEARECAAYFAlvrxGIACgkQ5CXHVHDJsQBOagCfQAFQoZyFfegGZUa8oWwn/srg
 1RwAoMFcDABbLpqaqpwIVqv5U4pYvdVb
 =q64b
 -----END PGP SIGNATURE-----
 Best regards, Angel

Johannes repeats the previous operation but gets the following output instead:

 I am the voice of Mother Moon,
 from whence all horrors have their doom.
 gpg: Signature made Tue Nov 13 15:02:38 2018 CET using DSA key ID 70C9B100
 gpg: BAD signature from "Angel <angel@triptico.com>"

That "BAD signature..." thing should trigger all kind of alarms.

The GPG tool also returns different output values for valid and invalid operations that can be useful in scripts and programs. If you are not a programmer nor a sysadmin, you can ignore this.

Encrypting

But Angel may occasionally consider that proving his authorship is not enough; he wants the message to be absolutely hidden to anyone but Johannes. So he opts for PGP/GPG encryption, invoking the command

 gpg -e -a -r johannes@comam.es

and pasting the two-lines message into GPG's standard input. GPG barfs the following wall of text:

 -----BEGIN PGP MESSAGE-----
 Version: GnuPG v1
 hQQOA6n6KzujHJfZEBAAkrlIZp/8IpWhw/H4pjCCzl1GgDvpLiqAvw4b1x9SXcPO
 bH+yp9M8K34+Slp7QIsBWWp+Z49ZAWeendMSW32iMoxakqt4K2PV27S8qgKAqqPk
 bWjCFmJ7ERIy1XSxarSUJaRzvWhwXI/9NVecei6boogSlowxce1GMvranzMJKR3J
 RrMR5AsfHWpnjyvcOjNV+o/OGrE6avPitW4ieWX0PzrLdgXS6tkwFUu9pOeB6OF+
 YRgVQKwtcEoPk92PHBGlvfahvT3KbWaso6OOa7mQHI+YgjbA3g2pCDobcsm30wED
 2Sw2XbU17KQWKU5YUm/RMNhsvYFrYnBA/jiHzqmsw4YeJrImu2MfkjScTgiAdL3S
 hIqGz3+AEBH+lTLHKPF3spQV9GDkn2es6DpRmxVF5TOEsb1toUznAqsADwz0Edlb
 3FEzeN7Kizui8UJ+HR6al+UiDm0X5v03r1tCMjxmZnq4fkmDG5/tH+j1319s33G7
 xDf/upUw1W5XLd+zBgdiTHD1ADxT4fWFiRH6by+CLTdFwt62mREmd1lW6YxwhMEV
 RGGZQzyLp3uVOg1z4jT2q7bz4MOBEPxY1L44zOENkH54yIITQ46Ambiwc572iJQQ
 /vP23oFRDJQdvHndxjlbFA2hJMSRavzTn3VzUYJzPGbnB2JzULUyqOH/obL4TMYP
 /2oxdkJjqQu8Z4xtZOPne5r7q4Ml8mIPtb+h2TbC0hHLi1DDqOQyLJcMmeSKMr3T
 XAOphMzbaHJYBODJB5w86Qxw6wAah1/+j6525NeHYYLPGACb9n8ujnXQP3l/Kpf6
 9/a2+0g3uRCi8GoriLHQN2slEg0hAgSI8t217HTC0fWeNtkVqInd7qUcE04RNa/e
 0nhVXDdbhTRMBkLfSRc/3wELVxrevo0K+bEwPUrJgX/9UROiP0lWJoSE0ezWhdCF
 4XK/K6RQr+WZE6GjpfzTuqDZNjQdphcV2xnTKM5DnauQNOX3+p2T+Ri/8JmnF+xx
 z3MGIxtNWIq1u71ykZZbaNVMRniGQ3QRwJiP7/DN2N08Sz4QO3cjqseK6TeCz+Av
 3vWGP339NUVKS/QHORwmoOQHm9AKwgqQedtgHn/u2hQpLLE35pCZOv5/GgAeJl4d
 /w8Qd7xNKDSVZEN82cYb5LJsY/Z0vVaqII66bm+iZQgdaa+uuNGtVITU3lgRMAJP
 Z0SBbzmNYE/4iLe/B79JK+057KjGlnpswtaYOwe0jS4RB9XRcgE7KBryo4o6h9E9
 udt0WF2h05iHzK7i1ewMJif7WszadnFXG8DifsFiteeEARmetLi89WiSVYdSiFsI
 xRhqIzGA0nz3XWuEBNw00UAl0vtkvDlhGEtSAW19MScc0oAB0TFPswUkicX36SN3
 8kZHiLCmIbucq33h+3TgEtiFjXj+pWFjlz4mTTRAvnr+nYn7FDTgblFMF/NJOXZq
 lSZNeF6PkngjK1+hZTogMBN5OL1iFP1D+IP+7ANydQdQL56V6yaU4YOtJv++l2F4
 ghA5wgMRlC9MNWRzptK2qZJmdQ==
 =NXsq
 -----END PGP MESSAGE-----

Given that GPG has everything it needs to encrypt a message to Johannes (i.e. his public key), no password nor any more information is requested.

Note that, when the message is encrypted, Angel has no way of decrypting it because he does not have Johannes' private key. There is no other way of decrypting this message than using that key.

As with signing, any text can be written surrounding the PGP boundaries. Also, it should not be trusted, as it's not really part of the message.

Decrypting

Johannes receives the block of garbage and proceeds the same as with the signed message:

 gpg

But like every time a private key is involved, GPG asks for the password to the Johannes' keyring:

 You need a passphrase to unlock the secret key for
 user: "Johannes <johannes@comam.es>"
 4096-bit ELG-E key, ID A31C97D9, created 2012-11-07 (main key ID 70C9B100)
Enter passphrase:

If it's entered correctly, GPG waits for text from its standard input. Johannes copies the full message into it and GPG dumps the omen from Mother Earth with some additional information:

 gpg: encrypted with 4096-bit ELG-E key, ID A31C97D9, created 2012-11-07
      "Johannes <johannes@comam.es>"
 I am the voice of Mother Earth,
 from whence all horrors have their birth.

If the encrypted message is garbled someway, GPG will complain about the data block integrity:

 gpg: CRC error; C73B95 - 357B2A

Encrypting and signing

For complete paranoia, a message can be encrypted AND signed. This is how it's done from Angel's view:

 gpg -es -a -r johannes@comam.es

As it needs Angel's private key for signing, the passphrase for his keyring is requested. After pasting the two-line message into GPG's standard input, The response is another scary block of garbage:

 -----BEGIN PGP MESSAGE-----
 Version: GnuPG v1
 hQQOA6n6KzujHJfZEA/8CkbHeZ5Q3VBpsGia90kKJgWcI3/Wbphi5JoSEpm8ezSl
 ffUhxoiO4NKM5hcJM+v+dqq7Wo0C4P2YxVnsUPIf9xk/aF6KmZttFU8H3o5/8+48
 KYQtp2ZBHlSzuDTIwsQyvXAIgg9CyXUTmdALPGaO6X8Yj+UphHghVu6vF1LwQw0k
 G9EfnjRmyEWzb+C4Rzvh6Sf0g+OMvuFtFf9fuSMfzAnwv8+U8diyJYusiuPUrNz7
 Q0b7be5MBhVlTyTfqpnD3zOsqt5EP1NewZgFn9HSxjmHMOGeaR3ahKEQVDyRglqK
 49SsPz402meJf3WrU3HUVsjen5I1q8CrJ+La+uxjodF4JAKhIX1qYJ6hySJI1P+w
 SjGP66VYNFwsYOSkMMlGsehCPNcaNhxZs3UATjd2RsnSNbcs50l+jEQj35EOXApx
 fUaCjUisXfTNz4PPl5slkfkQRTJ1nC8IVboOBk1REFmgJ3KhER+MXhsqqH4gMOH8
 VuGPh4p8nxX5I1WfFGOCtuXCRLCh2kMLdbVG5oDYEr2vPyfaL5EDDIIgao8v+k8E
 mLsWrLOGnSrg14IJ6NZR5zWx9ZC9s9ICPBfIgzKCgqb0wpjLiEP453Ymfl4/MRVr
 L5eXdttOfHHcJIultQcmF4FBlC2pHLXUKyJqkPhnHDnqWCtIwOuZHTS9LY6U5TQP
 /2Moh6TXe+aJTt0k6k4q9/xhCSIWpeOGq24gLQVS5DPTm+tYLSLm6x8nccPmwB2P
 FRXa7BQnDZ4PnOOS1lpo3kapZsmwY5upeZJ6ArI1c8hzHEVrducRPHQC2BrQ9/yj
 cKL7vpQNlHAtaSwI1oYhd+HqQLYUfzpDVxYY3ndk1OEWoNfwLFFcCj4jAMJTwD2J
 JJFhA7nY4CPggkTAr+8xIhzFbkWRexI+g/hfSH0oMKOidMmqCEsfZZStqwM0pfUW
 Ufc28AN+9r6n/6c7qOyZ+HWpbETceLfrUuYwLZ8ExzirJvqILWpMEZduYywDrLko
 8wH73JGHue+bdhW62MNoF45hOaSTBwB7ZZ9LmjqaADPeBVipZUUJPUpTuRg5k+o5
 JfDD6KbbIVl8cqKnLsBRfW5kDov7qKjxZjrbZ88KIa9qk0jrgXc1d0E74Cv/Lvdv
 L7q1Odd1Wsviug0Rdt5YzENXHqZrlCx0BkxBQWdoWhTurdloNITkWir2rxt50tCs
 AJlisig+zGQXkfzoiMMagS4MK2K8slyatT7KpbW9Tr0ueMrHN0Rm1kklw+b7/vnp
 3x8HHJq2Ia8WU3BoaO5cbD8l2d6st/Nhxgf2e+TxBGN87LSpZPzlSOoUISc1pSPB
 RdmACYkrPH+6OaaWjY9uzeSygWbVz3p+lBTL6ZICtQvz0sASAU9lY41R3ZsoTWUv
 /E/fTb4U3y4fTsR4G06Y4gyexh4Yyejh/s2mBc3VG4TCkZyubQilXy8mrhM3NJpj
 DEG6zZQEMtndp1Wq5z+qcvrJ2AF+j5R4nm7zNdt4XjrXOA+3zfzeD+avnfCjKAhT
 Jw0kzUrCzj34xc3iScQmwrdLEETk+66Ypv30ZEcdlzTrQUgcXW1WAqfJfaL8CJf1
 69oTyoWRAAXkpyJGZoIafzS+Cvjupneybqab1+sL8qajpptQBglCaatioFJrZWnk
 qt4LUBgD
 =G+4J
 -----END PGP MESSAGE-----

The difference is that, when Johannes tries to check the message as he usually do:

 gpg

The following is shown:

 You need a passphrase to unlock the secret key for
 user: "Johannes <johannes@comam.es>"
 4096-bit ELG-E key, ID A31C97D9, created 2012-11-07 (main key ID 70C9B100)
Enter passphrase:

This should be expected, as it's a message for Johannes' eyes only. The output is a bit different, though:

 gpg: encrypted with 4096-bit ELG-E key, ID A31C97D9, created 2012-11-07
      "Johannes <johannes@comam.es>"
 I am the voice of Mother Earth,
 from whence all horrors have their birth.
 gpg: Signature made Tue Nov 13 16:03:20 2018 CET using DSA key ID 70C9B100
 gpg: Good signature from "Angel <angel@triptico.com>"

GPG dumps information about the key the message was encrypted for, the message itself and the results of the validation test.

Signing binary files

Sometimes Angel may want to sign a binary file (a zip package, an image, etc.), for the purpose of helping people know that the file he has and the one they have has the same content. But adding PGP/GPG crap to this kind of files cannot be done because it corrupts them; so, you have to use a detached signature. Suppose you have the file

 abraham_lincoln_nude.jpg

Then you can sign it by executing

 gpg -ab abraham_lincoln_nude.jpg

A familiar prompt from GPG will be shown:

 You need a passphrase to unlock the secret key for
 user: "Angel <angel@triptico.com>"
 1024-bit DSA key, ID 70C9B100, created 2012-11-07
Enter passphrase:

After a successful password GPG creates a file with the same name as the signed one, but with the .asc extension appended, and that looks like:

 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 iEYEABECAAYFAlvr2GAACgkQ5CXHVHDJsQCeagCfTn72ZUBeVlWwTMvTMcGIbZsL
 9q4An0ZDXwAaMb5cyHUsybXoXZ/yjw8U
 =R3uI
 -----END PGP SIGNATURE-----

Both the file and the signature can now be made available to others.

Validating signed binary files

Johannes can validate that the binary file and Angel's signature on it match by calling

 gpg abraham_lincoln_nude.jpg.asc

Note that both the file and the signature must be on the same folder. GPG shall return the following:

 gpg: assuming signed data in `abraham_lincoln_nude.jpg'
 gpg: Signature made Wed Nov 14 09:10:08 2018 CET using DSA key ID 70C9B100
 gpg: Good signature from "Angel <angel@triptico.com>"

Summary

For signing text (will ask for sender's passphrase):

 gpg -s --clearsign < msg.txt > msg.signed.txt

For checking a signed text (no passphrase needd):

 gpg < msg.signed.txt

For encrypting text (no passphrase needed):

 gpg -e -a -r user@destination < msg.txt > msg.encrypted.txt

For decrypting an encrypted text (will ask for receiver's passphrase):

 gpg < msg.encrypted.txt

For encrypting and signing text (will ask for sender's passphrase):

 gpg -e -a -r user@destination < msg.txt > msg.both.txt

For decrypting and checking text (will ask for receiver's passphrase):

 gpg < msg.both.txt

For signing binary files (will ask for sender's passphrase):

 gpg -ab binary_file

For checking signed binary files (no passphrase needed):

 gpg binary_file.asc

End notes

Harry can sleep peacefully because he always encrypt and sign his email messages.

Though the examples here are given using GPG version 1, you should really use version 2 (the executable is called gpg2 in those systems that deploy both versions). I've used the older version because one of the features of version 2 is that it includes an agent that asks for passwords in GUI dialogs (if a GUI is available) and retains them for reasonable periods of time. This is of course convenient, but it may make less clear the cases where a passphrase to the keyring is needed.


Ángel Ortega <angel@triptico.com>

A simple pseudorandom number generator

Recently, a member of a game development mailing list asked me what random number algorithm I used in the Space Plumber game. This small document describes it.

First, I want to remember everyone that real random numbers are impossible to create on a computer because computing is deterministic BLAH BLAH BLAH I JUST WANT THE FUCKING CODE.

Ok, here it is:

 unsigned int sp_random(unsigned int *seed, unsigned int range)
 /* Space Plumber's random */
 {
     *seed = (*seed * 58321) + 11113;
     return (*seed >> 16) % range;
 }

It accepts two arguments:

seed
a pointer to an integer containing the random seed. If you only need one, you can use a global value. As a start fill it with the output of time() or something like that.
range
The maximum value to return, plus 1. The maximum range is 65535.

The sp_ in the name, unsurprisingly, comes from Space Plumber. It's not written exactly this way there, though.

The output value will be an integer from 0 to range-1, sufficiently unexpected to be used as a random number in games and such (don't make me laugh about cryptographically-secure values).

It's based on the wrapping of the 32 bit multiplying operation, so it won't work with floating point arithmetic.

From C to C++: A quick reference for aging programmers

So you were a great system programmer, back in the old days; your low level programs were celebrated by clever people, you loved C pointers and some days even considered Assembler as an option. You were happy and self-confident. But somehow you screwed something, got trapped in a time vortex and you ended today, trying to maintain or develop a program using that pesky Object Oriented Programming model in something called C++. I understand you; follow this guide and learn a bunch of things that will put you out of your misery and understand this brave new world.

More...

Artemus 5 Templating Language Overview

Artemus is a template toolkit. It filters text files, parsing, compiling and executing code surrounded by special marks (leaving the rest untouched) and concatenating everything as output. Its main purpose is to filter HTML files, but it can be used for any scripting need related to text filtering and substitution.

More...

MPSL Function Library Reference

This reference documents version 2.2.0 of the MPSL Function Library.

More...

MPSL Overview

MPSL (Minimum Profit Scripting Language) is a programming language concieved as a scripting engine for the Minimum Profit Text Editor, though it can also be used as a general-purpose programming tool.

More...

Minimum Profit character encoding support

This document describes the character encodings supported by the Minimum Profit text editor and the performed autodetection tests.

More...

Minimum Profit Keycodes

Table with Minimum Profit's keycodes and their default assigned actions.

More...

Una amistosa introdución a la codificación de vídeo, parte 3: sonido con pérdida

Por Mark Pilgrim, traducción de Ángel Ortega. Artículo original: http://diveintomark.org/archives/2008/12/30/give-part-3-lossy-audio-codecs

More...

LWN: Btrfs apunta a su inclusión

Por Jonathan Corbet, traducción de Ángel Ortega. Artículo original: http://lwn.net/Articles/313682/

More...

Una amistosa introdución a la codificación de vídeo, parte 2: vídeo con pérdida

Por Mark Pilgrim, traducción de Ángel Ortega. Artículo original: http://diveintomark.org/archives/2008/12/19/give-part-2-lossy-video-codecs

More...

LWN: Btrfs, ¿incorporarlo al núcleo principal?

Por Jake Edge, traducción de Ángel Ortega. Artículo original: http://lwn.net/Articles/302251/

More...

Una amistosa introdución a la codificación de vídeo, parte 1: contenedores

Por Mark Pilgrim, traducción de Ángel Ortega. Artículo original: http://diveintomark.org/archives/2008/12/18/give-part-1-container-formats

More...

El algoritmo Diffie-Hellman

El algoritmo Diffie-Hellman permite que dos partes, comunicándose mediante un canal no cifrado, se pongan de acuerdo en un valor numérico sin que un tercero, que tiene acceso completo a la conversación, pueda conocerlo o calcularlo, al menos en un tiempo práctico.

More...

Gruta FAQ

This is a list of Frequently Asked Questions about the Gruta web content management system.

More...

Gruta Installation Guide

This document contains a brief guide for the installation of Gruta, the web content management system.

More...

Gruta - command line tool

Manipulates Gruta sources directly.

More...

Minimum Profit Action Reference

Minimum Profit actions are editor commands that can be directly bound to the menu or a key.

More...

MPSL internals

This document describes some internal details of this MPSL implementation.

More...

MPSL C API

This reference documents version 2.2.0 of the C API.

More...