summaryrefslogtreecommitdiff
path: root/readme.mkd
blob: 68102407d1cb1a6a4c5edd7d057a951d763ec4f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
The Solitaire Cipher (#1)

  Cryptologist Bruce Schneier designed the hand cipher "Solitaire" for
  Neal Stephenson's book "Cryptonomicon". Created to be the first truly
  secure hand cipher, Solitaire requires only a deck of cards for the
  encryption and decryption of messages.

  While it's true that Solitaire is easily completed by hand given ample
  time, using a computer is much quicker and easier. Because of that,
  Solitaire conversion routines are available in many languages, though
  I've not yet run across one in Ruby.

  This week's quiz is to write a Ruby script that does the encryption and
  decryption of messages using the Solitaire cipher.

  Let's look at the steps of encrypting a message with Solitaire.

  1. Discard any non A to Z characters, and uppercase all remaining
  letters. Split the message into five character groups, using Xs to
  pad the last group, if needed. If we begin with the message "Code in
  Ruby, live longer!", for example, we would now have:

  CODEI NRUBY LIVEL ONGER

  2. Use Solitaire to generate a keystream letter for each letter in
  the message. This step is detailed below, but for the sake of
  example let's just say we get:

  DWJXH YRFDG TMSHP UURXJ

  3. Convert the message from step 1 into numbers, A = 1, B = 2, etc:

  3 15 4 5 9 14 18 21 2 25 12 9 22 5 12 15 14 7 5 18

  4. Convert the keystream letters from step 2 using the same method:

  4 23 10 24 8 25 18 6 4 7 20 13 19 8 16 21 21 18 24 10

  5. Add the message numbers from step 3 to the keystream
  numbers from step 4 and subtract 26 from the result if it
  is greater than 26. For example, 6 + 10 = 16 as expected,
  but 26 + 1 = 1 (27 - 26):

    7 12 14 3 17 13 10 1 6 6 6 22 15 13 2 10 9 25 3 2

    6. Convert the numbers from step 5 back to letters:

    GLNCQ MJAFF FVOMB JIYCB

    That took a while to break down, but it's really a very
    simple process. Decrypting with Solitaire is even easier,
    so let's look at those steps now. We'll work backwards
    with our example now, decrypting "GLNCQ MJAFF FVOMB
    JIYCB".

    1. Use Solitaire to generate a keystream letter for each
    letter in the message to be decoded. Again, I detail
    this process below, but sender and receiver use the
    same key and will get the same letters:

    DWJXH YRFDG TMSHP UURXJ

    2. Convert the message to be decoded to numbers:

    7 12 14 3 17 13 10 1 6 6 6 22 15 13 2 10 9 25 3 2

    3. Convert the keystream letters from step 1 to
    numbers:

    4 23 10 24 8 25 18 6 4 7 20 13 19 8 16 21 21 18 24
    10

    4. Subtract the keystream numbers from step 3 from
    the message numbers from step 2. If the message
    number is less than or equal to the keystream
    number, add 26 to the message number before
    subtracting. For example, 22 - 1 = 21 as
    expected, but 1 - 22 = 5 (27 - 22):

      3 15 4 5 9 14 18 21 2 25 12 9 22 5 12 15 14 7 5 18

      5. Convert the numbers from step 4 back to letters:

      CODEI NRUBY LIVEL ONGER

      Transforming messages is that simple.
      Finally, let's look at the missing piece of
      the puzzle, generating the keystream letters.

      First, let's talk a little about the deck of
      cards. Solitaire needs a full deck of 52
      cards and the two jokers. The jokers need to
      be visually distinct and I'll refer to them
      below as A and B. Some steps involve
      assigning a value to the cards. In those
      cases, use the cards face value as a base,
      Ace = 1, 2 = 2... 10 = 10, Jack = 11, Queen =
      12, King = 13. Then modify the base by the
      bridge ordering of suits, Clubs is simply the
      base value, Diamonds is base value + 13,
      Hearts is base value + 26, and Spades is base
      value + 39. Either joker values at 53. When
      the cards must represent a letter Clubs and
      Diamonds values are taken to be the number of
      the letter (1 to 26), as are Hearts and
      Spades after subtracting 26 from their value
      (27 to 52 drops to 1 to 26). Now let's make
      sense of all that by putting it to use.

      1. Key the deck. This is the critical step in
      the actual operation of the cipher and the
      heart of it's security. There are many
      methods to go about this, such as
      shuffling a deck and then arranging the
      receiving deck in the same order or
      tracking a bridge column in the paper and
      using that to order the cards. Because we
      want to be able to test our answers
      though, we'll use an unkeyed deck, cards
      in order of value. That is, from top to
      bottom, we'll always start with the deck:

      Ace of Clubs
      ...to...
      King of Clubs
      Ace of Diamonds
      ...to...
      King of Diamonds
      Ace of Hearts
      ...to...
      King of Hearts
      Ace of Spades
      ...to...
      King of Spades
      "A" Joker
      "B" Joker

      2. Move the A joker down one card. If the
      joker is at the bottom of the deck,
      move it to just below the first card.
      (Consider the deck to be circular.) The
      first time we do this, the deck will go
      from:

      1 2 3 ... 52 A B

      To:

      1 2 3 ... 52 B A

      3. Move the B joker down two cards. If
      the joker is the bottom card, move
      it just below the second card. If
      the joker is the just above the
      bottom card, move it below the top
      card. (Again, consider the deck to be circular.) This changes our example deck to:

      1 B 2 3 4 ... 52 A

      4. Perform a triple cut around the
      two jokers. All cards above the
      top joker move to below the
      bottom joker and vice versa. The
      jokers and the cards between them
      do not move. This gives us:

      B 2 3 4 ... 52 A 1

      5. Perform a count cut using the
      value of the bottom card. Cut
      the bottom card's value in
      cards off the top of the deck
      and reinsert them just above
      the bottom card. This changes
      our deck to:

      2 3 4 ... 52 A B 1 (the 1
          tells us to move just the B)

      6. Find the output letter.
      Convert the top card to
      it's value and count down
      that many cards from the
      top of the deck, with the
      top card itself being card
      number one. Look at the
      card immediately after your
      count and convert it to a
      letter. This is the next
      letter in the keystream. If
      the output card is a joker,
      no letter is generated this
      sequence. This step does
      not alter the deck. For our
      example, the output letter
      is:

      D (the 2 tells us to count
          down to the 4, which is a
          D)

      7. Return to step 2, if
      more letters are needed.

      For the sake of testing,
      the first ten output
      letters for an unkeyed
      deck are:

  D (4) W (49) J (10) Skip Joker (53) X (24) H (8)
  Y (51) R (44) F (6) D (4) G (33)

  That's all there is to
  Solitaire, finally. It's
  really longer to explain
  than it is to code up.

  Solutions to this quiz
  should accept a message
  as a command line
  argument and encrypt or
  decrypt is as needed. It
  should be easy to tell
  which is needed by the
  pattern of the message,
  but you can use a switch
  if you prefer.

  All the examples for
  this quiz assume an
  unkeyed deck, but your
  script can provide a way
  to key the deck, if
  desired. (A real script would require this, of course.)

  Here's a couple of
  messages to test your
  work with. You'll know
  when you have them
  right:

  CLEPK HHNIY CFPWH FDFEH

  ABVAW LWZSY OORYK DUPVH

  Quiz Summary

  YOURC IPHER ISWOR KINGX

  WELCO METOR UBYQU IZXXX

  That's what you should
  have seen, if you ran a
  working Solitaire cipher
  decryption script over
  the last two lines of
  the quiz. All the
  submitted solutions did
  just that in my tests,
  though some needed a
  tiny tweak here or
  there.