Merge remote-tracking branch 'origin/mk-arrows' into mk-arrows
This commit is contained in:
commit
93ca0ce061
21
LS47.scad
21
LS47.scad
|
@ -2,12 +2,9 @@
|
|||
// No license, but send me a hello if you use this for some good purpose.
|
||||
// -- Mirek Kratochvil <exa.exa@gmail.com>
|
||||
|
||||
//TODO: round corners?
|
||||
font = "FiraMono";
|
||||
|
||||
font = "Consolas"; //URW Bookman L looks nicely here as well
|
||||
font2 = "Droid Sans Mono";
|
||||
|
||||
alphabet = "en";
|
||||
alphabet = "ru";
|
||||
|
||||
//inch-sized tiles look imperial.
|
||||
tilesize=25.4;
|
||||
|
@ -22,11 +19,13 @@ corner=tileheight*2;
|
|||
|
||||
//accomodate for Ё
|
||||
if (alphabet=="ru") {
|
||||
fontheight=fontheight*0.9;
|
||||
fontheight=fontheight*0.9;
|
||||
}
|
||||
|
||||
module arrow(n) {
|
||||
if (n>=1) for(i=[0:n-1]) translate([i-(n-1)/2,0,0]) polygon([[0.45,0],[0,0.7],[-0.45,0]]);
|
||||
if (n>=1)
|
||||
for(i=[0:n-1]) translate([i-(n-1)/2,0,0])
|
||||
polygon([[0.45,0],[0,0.7],[-0.45,0]]);
|
||||
}
|
||||
|
||||
//this produces one tile
|
||||
|
@ -49,7 +48,7 @@ module tilec(letter, x, y, c) {
|
|||
color("white") {
|
||||
translate([tilesize*(0.5-dx*0.13),tilesize*(0.275-dy*0.13),tileheight*.51])
|
||||
linear_extrude (height=tileheight/2)
|
||||
text(letter, font=font, size=tilesize*.45,
|
||||
text(letter, font=font, size=tilesize*.48,
|
||||
halign="center", valign="baseline");
|
||||
}
|
||||
color("white")
|
||||
|
@ -81,13 +80,13 @@ module tiles(letters) {
|
|||
if (alphabet=="en") {
|
||||
// latin variant of tiles
|
||||
tiles(
|
||||
["□", "A", "B", "C", "D", "E", "F",
|
||||
["□", "A", "B", "C", "D", "E", "F",
|
||||
"G", "H", "I", "J", "K", "L", "M",
|
||||
"N", "O", "P", "Q", "R", "S", "T",
|
||||
"U", "V", "W", "X", "Y", "Z", ".",
|
||||
"/", ":", "?", "!", "'", "(", ")",
|
||||
",", ":", "?", "!", "'", "(", ")",
|
||||
"0", "1", "2", "3", "4", "5", "6",
|
||||
"7", "8", "9", ",", "-", "+", "*"]
|
||||
"7", "8", "9", "+", "-", "*", "/"]
|
||||
);
|
||||
} else if (alphabet=="ru") {
|
||||
// variant of tiles thanks to Stas Bushuev
|
||||
|
|
181
README.md
181
README.md
|
@ -32,30 +32,30 @@ We have added some real punctuation, basic stuff for writing expressions,
|
|||
punctuation and quotes. The letters of the board now look like this:
|
||||
|
||||
```
|
||||
_ a b c d e f
|
||||
g h i j k l m
|
||||
n o p q r s t
|
||||
u v w x y z .
|
||||
/ : ? ! ' ( )
|
||||
_ A B C D E F
|
||||
G H I J K L M
|
||||
N O P Q R S T
|
||||
U V W X Y Z .
|
||||
, : ? ! ' ( )
|
||||
0 1 2 3 4 5 6
|
||||
7 8 9 , - + *
|
||||
7 8 9 + - * /
|
||||
```
|
||||
|
||||
Zoomed in, it's very practical to have extra position information written on
|
||||
the tiles:
|
||||
The cipher works with position changes. Zoomed in; it's very practical to also
|
||||
have the shift information written on the tiles as arrows:
|
||||
|
||||
```
|
||||
/-----\ /-----\ /-----\ /-----\ /-----\
|
||||
| | | | | | | | | |
|
||||
| _ 0| | a 1| | b 2| | c 3| | d 4| ...
|
||||
| 0 | | 0 | | 0 | | 0 | | 0 |
|
||||
\-----/ \-----/ \-----/ \-----/ \-----/
|
||||
.-----. .-----. .-----. .-----. .-----.
|
||||
| | | >| | >| | >| |< |
|
||||
| _ | | A | | B >| | C >| |< D | ...
|
||||
| | | | | | | >| |< |
|
||||
'-----' '-----' '-----' '-----' '-----'
|
||||
|
||||
/-----\ /-----\
|
||||
| | | |
|
||||
| g 0| | h 1| ...
|
||||
| 1 | | 1 |
|
||||
\-----/ \-----/
|
||||
.-----. .-----.
|
||||
| | | >|
|
||||
| G | | H >| ...
|
||||
|v | |v |
|
||||
'-----' '-----'
|
||||
. .
|
||||
. .
|
||||
. .
|
||||
|
@ -67,42 +67,43 @@ trash).
|
|||
|
||||
## How-To
|
||||
|
||||
You may as well see the paper [1], there are also pictures. This is somewhat more concentrated:
|
||||
You may as well see the paper [1], there are also pictures. This is somewhat
|
||||
more concentrated:
|
||||
|
||||
### Encryption
|
||||
|
||||
1. The symmetric key is the initial state of the board. Arrange your tiles to 7x7 square according to the key.
|
||||
2. Put the marker on (0,0).
|
||||
3. Find the next letter you want to encrypt on the board, its position is `P`.
|
||||
4. Look at the marker; numbers written on the marked tile are coordinates `M`.
|
||||
5. Compute position of the ciphertext as `C := P + M mod (7,7)`. Output the letter found on position `C` as ciphertext.
|
||||
6. Rotate the row that contains the plaintext letter one position to the right, but do not carry the marker if present (it should stay on the same coordinates).
|
||||
7. Rotate the column that now (after the first rotation) contains the ciphertext letter one position down, also not carrying the marker.
|
||||
8. Update the position of the marker: `M := M + C' mod (7,7)` where `C'` are the numbers written on the ciphertext tile.
|
||||
2. Put the marker on the tile in the upper left corner.
|
||||
3. Find the next letter you want to encrypt on the board (call it `P`).
|
||||
4. Look at the marker; let's call the tile under the marker `M`.
|
||||
5. The marked tile `M` has arrows drawn on it. Put a finger on tile `P` and move it to next tiles according to arrows on `M` -- e.g., if it has 2 arrows to the right and one to up, you jump 2 tiles to the right and one up. In case you hit the corner of the board, do a "wraparound" and continue on the other side. After the jumps, your finger rests on the ciphertext tile; mark it `C`. This letter is now encrypted and you can "transmit" it.
|
||||
6. Shift the row that contains the plaintext letter one position to the right. The tile on the right will get out of the board; so do a "wraparound" again and put it to the empty spot on the left. (Let's call this "rotation"). If the marker is present on any of the affected tiles, DO NOT CARRY IT with the tiles (it should stay on the same coordinates).
|
||||
7. In a similar fashion, rotate the column that now (after the first rotation) contains the ciphertext tile `C` one position down, again doing the wraparound and preserving the marker position.
|
||||
8. Update the position of the marker: Look at the arrow directions on the ciphertext tile `C` and move the marker according to the directions (just like previously with finding the ciphertext).
|
||||
9. Repeat from 3 as many times as needed to encrypt the whole plaintext.
|
||||
|
||||
#### Encryption example with ascii images!
|
||||
|
||||
```
|
||||
1,2. Symmetric key with 3,4. We want to encrypt 'y'.
|
||||
marker put on 'e' Look at the marked tile:
|
||||
1,2. Symmetric key with 3,4. We want to encrypt 'Y'.
|
||||
marker put on 'E': Look at the marked tile first:
|
||||
|
||||
[e]f _ a b c d /-----\
|
||||
l m g h i j k | |
|
||||
( ) / : ? ! ' | e 5|
|
||||
s t n o p q r | 0 |
|
||||
z . u v w x y \-----/
|
||||
[E]F _ A B C D /-----\
|
||||
L M G H I J K |< |
|
||||
( ) / : ? ! ' |< E |
|
||||
S T N O P Q R | |
|
||||
Z . U V W X Y \-----/
|
||||
5 6 0 1 2 3 4
|
||||
+ * 7 8 9 , -
|
||||
|
||||
5. Ciphertext is 'w' 6. Rotate the plaintext 1 position
|
||||
(='y' moved by (5,0)) right, keep marker coordinates.
|
||||
5. Ciphertext is 'W' 6. Rotate the plaintext 1 position
|
||||
(='Y' moved to <<) right, keep marker coordinates.
|
||||
|
||||
[e]f _ a b c d [e]f _ a b c d
|
||||
Output 'w'! l m g h i j k l m g h i j k
|
||||
[E]F _ A B C D [E]F _ A B C D
|
||||
Output 'U'! L M G H I J K L M G H I J K
|
||||
( ) / : ? ! ' ( ) / : ? ! '
|
||||
s t n o p q r s t n o p q r
|
||||
z . u v w x y >> y z . u v w x
|
||||
S T N O P Q R S T N O P Q R
|
||||
Z . U V W X Y >> Y Z . U V W X
|
||||
5 6 0 1 2 3 4 5 6 0 1 2 3 4
|
||||
+ * 7 8 9 , - + * 7 8 9 , -
|
||||
|
||||
|
@ -110,24 +111,24 @@ You may as well see the paper [1], there are also pictures. This is somewhat mor
|
|||
7. Rotate the ciphertext 1 Now look at the ciphertext tile:
|
||||
position down.
|
||||
|
||||
[e]f _ a b , d /-----\
|
||||
l m g h i c k | |
|
||||
( ) / : ? j ' | w 2|
|
||||
s t n o p ! r | 3 |
|
||||
y z . u v q x \-----/
|
||||
5 6 0 1 2 w 4
|
||||
[E]F _ A B , D /-----\
|
||||
L M G H I C K | >|
|
||||
( ) / : ? J ' | W >|
|
||||
S T N O P ! R |vvv |
|
||||
Y Z . U V Q X \-----/
|
||||
5 6 0 1 2 W 4
|
||||
+ * 7 8 9 3 -
|
||||
|
||||
8. Update the marker position 9. GOTO 3.
|
||||
by ciphertext offset (2,3).
|
||||
by ciphertext arrows (vvv>>)
|
||||
|
||||
|
||||
e f _ a b , d
|
||||
l m g h i c k
|
||||
( ) / : ? j '
|
||||
s t[n]o p ! r
|
||||
y z . u v q x
|
||||
5 6 0 1 2 w 4
|
||||
E F _ A B , D
|
||||
L M G H I C K
|
||||
( ) / : ? J '
|
||||
S T[N]O P ! R
|
||||
Y Z . U V Q X
|
||||
5 6 0 1 2 W 4
|
||||
+ * 7 8 9 3 -
|
||||
|
||||
|
||||
|
@ -136,13 +137,13 @@ You may as well see the paper [1], there are also pictures. This is somewhat mor
|
|||
### Decryption
|
||||
|
||||
Decryption procedure is basically the same, except that in step 5 you know `C`
|
||||
and `M`, and need to produce `P` by subtraction: `P := C - M mod (7,7)`.
|
||||
Otherwise (except that you input ciphertext and output plaintext) everything
|
||||
stays the same.
|
||||
and `M`, and need to produce `P` by going back to it from `C`. Simply take the
|
||||
arrows on the marked tile and use them in reverse direction starting from `C`.
|
||||
|
||||
### Key generation
|
||||
|
||||
Grab a bag full of tiles and randomly draw them one by one. Key is the 49-item permutation of them.
|
||||
Grab a bag full of tiles and randomly draw them one by one. Key is the 49-item
|
||||
permutation of them.
|
||||
|
||||
## Modifications
|
||||
|
||||
|
@ -167,17 +168,21 @@ expand the passwords before each encryption/decryption.
|
|||
|
||||
The actual expansion can be as simple as this:
|
||||
|
||||
1. initialize `I:=0`, put the tiles on the board sorted by their numbers (i.e. as on the picture above)
|
||||
2. Take the first letter of the password and see the numbers on its tile; mark them `Px, Py`.
|
||||
3. Rotate `I`-th row `Px` positions right
|
||||
4. Rotate `I`th column `Py` positions down
|
||||
5. `I := I + 1 mod 7`, repeat from 2 with next letter of the password.
|
||||
6. Resulting tile positions are the expanded key
|
||||
1. Put the tiles on the board in a fixed "initial" position,
|
||||
e.g. as on the character board picture above, sorted by the arrow offsets.
|
||||
2. Find the first letter of the password. Rotate it first horizontally, then
|
||||
vertically, according to the number of arrows on the tile.
|
||||
3. Find the tile below right (`v>` in arrows) of the new position of the
|
||||
password letter (possibly wrapping around the board), and rotate it
|
||||
horizontally and vertically according to what its arrows say -- just as with
|
||||
the password letter before.
|
||||
4. Repeat as needed from step 2 for the whole password.
|
||||
5. Final tile positions are the expanded key.
|
||||
|
||||
### Undistinguishable ciphertexts
|
||||
|
||||
To get a different ciphertext even if the same plaintext is encrypted
|
||||
repeatedly; prepend it with a nonce. A nonce is a completely random sequence of
|
||||
repeatedly, prepend it with a nonce. A nonce is a completely random sequence of
|
||||
letters of a pre-negotiated length (e.g. N tiles drawn randomly from a bag,
|
||||
adviseable value of N is at least 10).
|
||||
|
||||
|
@ -209,13 +214,13 @@ use of playing cards could be more innocuous and easily explainable to a
|
|||
suddenly appearing adversary. Playing cards is sure less suspicious than
|
||||
playing some peculiarly numbered tiles! :] )
|
||||
|
||||
To simplify things a bit, we will use the following layout:
|
||||
To simplify things a bit, we shall use the following layout:
|
||||
|
||||
```
|
||||
a b c d e f g
|
||||
h i j k l m n
|
||||
o p q r s t u
|
||||
v w x y z _ .
|
||||
A B C D E F G
|
||||
H I J K L M N
|
||||
O P Q R S T U
|
||||
V W X Y Z _ .
|
||||
, - + * / : ?
|
||||
! ' ( ) 1 2 3
|
||||
4 5 6 7 8 9 0
|
||||
|
@ -225,19 +230,19 @@ This maps nicely to the playing card suits:
|
|||
|
||||
| Card value | ♦ | ♣ | ♥ | ♠ |
|
||||
|------------|---|---|---|---|
|
||||
| A | a | n | _ | 1 |
|
||||
| 2 | b | o | . | 2 |
|
||||
| 3 | c | p | , | 3 |
|
||||
| 4 | d | q | - | 4 |
|
||||
| 5 | e | r | + | 5 |
|
||||
| 6 | f | s | * | 6 |
|
||||
| 7 | g | t | / | 7 |
|
||||
| 8 | h | u | : | 8 |
|
||||
| 9 | i | v | ? | 9 |
|
||||
| 10 | j | w | ! | 0 |
|
||||
| J | k | x | ' | |
|
||||
| Q | l | y | ( | |
|
||||
| K | m | z | ) | |
|
||||
| A | A | N | _ | 1 |
|
||||
| 2 | B | O | . | 2 |
|
||||
| 3 | C | P | , | 3 |
|
||||
| 4 | D | Q | - | 4 |
|
||||
| 5 | E | R | + | 5 |
|
||||
| 6 | F | S | * | 6 |
|
||||
| 7 | G | T | / | 7 |
|
||||
| 8 | H | U | : | 8 |
|
||||
| 9 | I | V | ? | 9 |
|
||||
| 10 | J | W | ! | 0 |
|
||||
| J | K | X | ' | |
|
||||
| Q | L | Y | ( | |
|
||||
| K | M | Z | ) | |
|
||||
|
||||
The last 3 cards are not used. (Actually, you are free to use the suits in
|
||||
whatever order you like and discard the last 3 of the suit you like the least.)
|
||||
|
@ -253,10 +258,10 @@ The result may look like this:
|
|||

|
||||
|
||||
In this example, the marker is on J♣ (at the top left), and we want to encrypt
|
||||
the plaintext character `e`. The image includes the character, index, and
|
||||
the plaintext character `E`. The image includes the character, index, and
|
||||
offsets for the relevant cards.
|
||||
|
||||
1. From the card mapping, `e` maps to 5♦ (letters `a` through `m` map to
|
||||
1. From the card mapping, `E` maps to 5♦ (letters `A` through `M` map to
|
||||
Tiles), which is on the second row.
|
||||
2. The marker card, J♣, has:
|
||||
- an index of 24 (Clubs are suit 1, and the Jack is the 11th card in the
|
||||
|
@ -282,11 +287,11 @@ For the original LC4, you need just 3 suits, modifying the board to "align" to
|
|||
the suits e.g. as follows:
|
||||
|
||||
```
|
||||
a b c d e f
|
||||
g h i j k l
|
||||
m n o p q r
|
||||
s t u v w x
|
||||
y z _ 2 3 4
|
||||
A B C D E F
|
||||
G H I J K L
|
||||
M N O P Q R
|
||||
S T U V W X
|
||||
Y Z _ 2 3 4
|
||||
5 6 7 8 9 #
|
||||
```
|
||||
|
||||
|
|
2
lc4.py
2
lc4.py
|
@ -56,7 +56,7 @@ version = "v2.8.1 (2018-07-24)"
|
|||
# define alphabet
|
||||
letters6 = "#_23456789abcdefghijklmnopqrstuvwxyz"
|
||||
letters6card = "abcdefghijklmnopqrstuvwxyz_23456789#"
|
||||
letters7 = "_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()"
|
||||
letters7 = "_abcdefghijklmnopqrstuvwxyz.,:?!'()0123456789+-*/"
|
||||
letters7card = "abcdefghijklmnopqrstuvwxyz_.,-+*/:?!'()1234567890"
|
||||
|
||||
|
||||
|
|
18
ls47.py
18
ls47.py
|
@ -8,7 +8,7 @@
|
|||
|
||||
import random
|
||||
|
||||
letters = "_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()"
|
||||
letters = "_abcdefghijklmnopqrstuvwxyz.,:?!'()0123456789+-*/"
|
||||
tiles = list(zip(letters, map(lambda x: (x // 7, x % 7), range(7 * 7))))
|
||||
padding_size = 10
|
||||
|
||||
|
@ -85,12 +85,18 @@ def rotate_marker_down(m, col, n):
|
|||
|
||||
|
||||
def derive_key(password):
|
||||
i = 0
|
||||
k = letters
|
||||
for c in password:
|
||||
(row, col) = find_ix(c)
|
||||
k = rotate_down(rotate_right(k, i, col), i, row)
|
||||
i = (i + 1) % 7
|
||||
(crow, ccol) = find_pos(k, c)
|
||||
(rows1, cols1) = find_ix(c)
|
||||
k = rotate_right(k, crow, cols1)
|
||||
(crow, ccol) = add_pos((crow, ccol), (0, cols1))
|
||||
k = rotate_down(k, ccol, rows1)
|
||||
(crow, ccol) = add_pos((crow, ccol), (rows1+1, 1))
|
||||
(rows2, cols2) = find_ix(find_at_pos(k, (crow, ccol)))
|
||||
k = rotate_right(k, crow, cols2)
|
||||
(crow, ccol) = add_pos((crow,ccol), (0, cols2))
|
||||
k = rotate_down(k, ccol, rows2)
|
||||
return k
|
||||
|
||||
|
||||
|
@ -154,7 +160,7 @@ if __name__ == '__main__':
|
|||
print(letters)
|
||||
# print('tiles positions: ' + str(tiles))
|
||||
|
||||
key = derive_key('s3cret_p4ssw0rd/31337')
|
||||
key = derive_key('a')
|
||||
print('test key: ' + key)
|
||||
enc = encrypt_pad(key, 'conflagrate_the_rose_bush_at_six!',
|
||||
'peace-vector-3')
|
||||
|
|
Loading…
Reference in a new issue