Skip to content

Instantly share code, notes, and snippets.

@cyril
Last active June 27, 2018 08:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cyril/9279846 to your computer and use it in GitHub Desktop.
Save cyril/9279846 to your computer and use it in GitHub Desktop.
Draft of cryptographic hash functions
=begin
* 4 substitution box (6x4-bit)
* Copyright (c) 2008 Cyril Kato
* Code licensed under the BSD License:
http://www.opensource.org/licenses/bsd-license.php
* version: 1
=end
SBOX = [
[
[
2, 1, 15, 11, 3, 14, 4, 13, 6, 0, 5, 9, 8, 12, 10, 7
], [
10, 4, 9, 5, 11, 8, 0, 2, 14, 13, 12, 7, 3, 1, 15, 6
], [
6, 3, 15, 9, 5, 14, 13, 11, 7, 2, 8, 12, 0, 1, 10, 4
], [
11, 14, 6, 10, 8, 12, 3, 2, 15, 4, 7, 5, 0, 1, 13, 9
]
], [
[
9, 4, 1, 7, 0, 15, 8, 12, 3, 2, 10, 14, 5, 6, 13, 11
], [
6, 13, 4, 14, 5, 2, 11, 9, 7, 8, 12, 1, 0, 3, 15, 10
], [
9, 6, 12, 14, 2, 10, 7, 0, 8, 3, 15, 5, 13, 11, 1, 4
], [
8, 6, 1, 12, 10, 4, 7, 11, 2, 5, 14, 13, 3, 0, 9, 15
]
], [
[
14, 11, 1, 3, 10, 15, 6, 9, 13, 4, 12, 7, 8, 2, 0, 5
], [
12, 7, 1, 0, 8, 14, 3, 2, 13, 11, 15, 6, 5, 4, 10, 9
], [
4, 10, 5, 12, 2, 15, 0, 14, 11, 8, 6, 9, 7, 13, 1, 3
], [
6, 14, 10, 15, 2, 5, 9, 3, 11, 7, 0, 1, 8, 4, 13, 12
]
], [
[
5, 12, 15, 9, 2, 4, 14, 13, 6, 3, 8, 0, 1, 7, 10, 11
], [
9, 12, 15, 7, 2, 4, 11, 3, 14, 1, 8, 13, 5, 0, 6, 10
], [
0, 2, 6, 10, 1, 12, 8, 13, 9, 7, 5, 3, 14, 4, 15, 11
], [
0, 3, 8, 15, 6, 13, 11, 2, 1, 14, 4, 5, 12, 9, 10, 7
]
]
]
=begin
* 64 substitution box (6x4-bit)
* Copyright (c) 2008 Cyril Kato
* Code licensed under the BSD License:
http://www.opensource.org/licenses/bsd-license.php
* version: 1
=end
SBOX = [
[
[
2, 1, 15, 11, 3, 14, 4, 13, 6, 0, 5, 9, 8, 12, 10, 7
], [
10, 4, 9, 5, 11, 8, 0, 2, 14, 13, 12, 7, 3, 1, 15, 6
], [
6, 3, 15, 9, 5, 14, 13, 11, 7, 2, 8, 12, 0, 1, 10, 4
], [
11, 14, 6, 10, 8, 12, 3, 2, 15, 4, 7, 5, 0, 1, 13, 9
]
], [
[
9, 4, 1, 7, 0, 15, 8, 12, 3, 2, 10, 14, 5, 6, 13, 11
], [
6, 13, 4, 14, 5, 2, 11, 9, 7, 8, 12, 1, 0, 3, 15, 10
], [
9, 6, 12, 14, 2, 10, 7, 0, 8, 3, 15, 5, 13, 11, 1, 4
], [
8, 6, 1, 12, 10, 4, 7, 11, 2, 5, 14, 13, 3, 0, 9, 15
]
], [
[
14, 11, 1, 3, 10, 15, 6, 9, 13, 4, 12, 7, 8, 2, 0, 5
], [
12, 7, 1, 0, 8, 14, 3, 2, 13, 11, 15, 6, 5, 4, 10, 9
], [
4, 10, 5, 12, 2, 15, 0, 14, 11, 8, 6, 9, 7, 13, 1, 3
], [
6, 14, 10, 15, 2, 5, 9, 3, 11, 7, 0, 1, 8, 4, 13, 12
]
], [
[
5, 12, 15, 9, 2, 4, 14, 13, 6, 3, 8, 0, 1, 7, 10, 11
], [
9, 12, 15, 7, 2, 4, 11, 3, 14, 1, 8, 13, 5, 0, 6, 10
], [
0, 2, 6, 10, 1, 12, 8, 13, 9, 7, 5, 3, 14, 4, 15, 11
], [
0, 3, 8, 15, 6, 13, 11, 2, 1, 14, 4, 5, 12, 9, 10, 7
]
], [
[
15, 7, 5, 14, 9, 13, 2, 11, 4, 12, 6, 1, 0, 8, 3, 10
], [
3, 1, 8, 12, 0, 4, 7, 2, 13, 5, 10, 6, 11, 9, 14, 15
], [
5, 15, 8, 0, 12, 4, 9, 6, 10, 13, 3, 11, 7, 14, 2, 1
], [
5, 1, 0, 8, 7, 4, 10, 13, 12, 6, 9, 3, 2, 11, 14, 15
]
], [
[
7, 3, 12, 11, 1, 13, 6, 5, 4, 9, 10, 2, 14, 0, 8, 15
], [
15, 13, 6, 7, 0, 14, 9, 12, 2, 10, 3, 8, 11, 5, 4, 1
], [
12, 3, 14, 1, 2, 5, 4, 15, 8, 9, 13, 7, 0, 6, 10, 11
], [
14, 7, 2, 9, 6, 1, 3, 0, 11, 8, 13, 10, 4, 15, 12, 5
]
], [
[
1, 6, 15, 2, 7, 8, 0, 10, 3, 14, 12, 5, 4, 13, 11, 9
], [
5, 1, 0, 11, 4, 14, 15, 9, 3, 8, 7, 6, 10, 12, 2, 13
], [
5, 7, 14, 2, 9, 8, 15, 3, 13, 10, 12, 0, 4, 11, 1, 6
], [
9, 10, 14, 13, 7, 8, 2, 15, 1, 11, 3, 5, 4, 0, 6, 12
]
], [
[
1, 11, 4, 14, 7, 13, 0, 5, 15, 3, 9, 8, 10, 2, 6, 12
], [
7, 4, 15, 5, 9, 13, 3, 10, 12, 14, 1, 6, 2, 8, 11, 0
], [
2, 0, 1, 14, 3, 15, 4, 7, 10, 9, 8, 6, 13, 12, 5, 11
], [
1, 14, 12, 7, 2, 9, 8, 0, 3, 4, 5, 6, 10, 13, 11, 15
]
], [
[
2, 11, 4, 15, 1, 6, 13, 8, 5, 9, 10, 12, 0, 14, 3, 7
], [
1, 9, 6, 3, 8, 14, 7, 11, 12, 5, 10, 4, 15, 13, 0, 2
], [
1, 14, 6, 11, 0, 15, 10, 13, 9, 4, 5, 2, 12, 8, 7, 3
], [
13, 14, 6, 15, 0, 4, 8, 5, 11, 3, 10, 2, 12, 9, 1, 7
]
], [
[
8, 14, 11, 15, 2, 3, 12, 9, 4, 1, 7, 6, 0, 5, 13, 10
], [
4, 0, 15, 14, 9, 11, 6, 10, 7, 8, 12, 2, 13, 3, 5, 1
], [
3, 14, 4, 0, 5, 15, 13, 2, 1, 9, 12, 6, 10, 11, 7, 8
], [
10, 0, 8, 7, 4, 13, 15, 12, 5, 11, 14, 9, 1, 2, 3, 6
]
], [
[
15, 0, 6, 1, 4, 10, 11, 8, 5, 3, 12, 7, 9, 2, 14, 13
], [
4, 13, 14, 12, 7, 0, 3, 2, 5, 11, 8, 9, 15, 1, 6, 10
], [
5, 14, 2, 8, 1, 11, 3, 10, 13, 15, 7, 0, 12, 6, 9, 4
], [
3, 14, 15, 11, 6, 9, 8, 0, 5, 12, 7, 2, 1, 10, 13, 4
]
], [
[
15, 1, 0, 5, 4, 9, 11, 2, 14, 6, 7, 10, 8, 3, 13, 12
], [
10, 4, 14, 9, 5, 7, 8, 3, 0, 11, 6, 12, 2, 15, 1, 13
], [
9, 11, 12, 14, 8, 7, 15, 13, 6, 4, 0, 5, 10, 2, 3, 1
], [
15, 13, 11, 6, 2, 14, 10, 0, 3, 1, 12, 5, 7, 8, 4, 9
]
], [
[
5, 11, 7, 2, 15, 4, 3, 1, 13, 12, 10, 14, 8, 6, 9, 0
], [
15, 7, 10, 11, 4, 2, 8, 5, 14, 13, 1, 12, 9, 3, 6, 0
], [
11, 15, 2, 14, 9, 10, 4, 8, 13, 3, 12, 1, 5, 0, 7, 6
], [
7, 3, 10, 9, 1, 13, 14, 11, 5, 15, 2, 8, 6, 4, 0, 12
]
], [
[
2, 11, 6, 8, 12, 4, 15, 9, 1, 10, 14, 3, 7, 0, 13, 5
], [
13, 0, 7, 2, 6, 10, 5, 15, 8, 3, 1, 12, 11, 4, 14, 9
], [
2, 13, 12, 8, 4, 6, 0, 10, 5, 3, 11, 1, 7, 9, 14, 15
], [
1, 15, 8, 13, 6, 4, 2, 14, 7, 12, 11, 9, 5, 0, 3, 10
]
], [
[
0, 10, 11, 14, 3, 5, 2, 15, 9, 12, 6, 13, 8, 4, 1, 7
], [
15, 11, 6, 1, 2, 7, 9, 4, 0, 5, 3, 10, 14, 8, 13, 12
], [
4, 9, 8, 14, 2, 15, 13, 12, 5, 10, 7, 11, 6, 0, 1, 3
], [
1, 13, 10, 0, 7, 8, 9, 15, 6, 11, 12, 14, 4, 3, 2, 5
]
], [
[
14, 15, 9, 12, 7, 3, 8, 10, 11, 1, 0, 2, 6, 4, 13, 5
], [
14, 7, 9, 12, 4, 8, 2, 13, 1, 15, 10, 6, 11, 3, 0, 5
], [
12, 2, 9, 1, 8, 7, 10, 13, 0, 4, 14, 3, 5, 15, 11, 6
], [
3, 4, 0, 6, 14, 11, 9, 5, 10, 7, 15, 8, 12, 1, 2, 13
]
], [
[
5, 4, 7, 0, 12, 15, 11, 1, 2, 13, 9, 6, 10, 14, 8, 3
], [
0, 5, 10, 1, 14, 7, 2, 6, 9, 8, 11, 3, 15, 4, 12, 13
], [
0, 11, 10, 15, 12, 5, 1, 13, 2, 4, 8, 6, 3, 14, 9, 7
], [
2, 5, 11, 12, 9, 6, 4, 10, 1, 14, 15, 0, 3, 8, 7, 13
]
], [
[
9, 7, 1, 13, 14, 2, 3, 10, 11, 15, 6, 8, 0, 12, 4, 5
], [
15, 4, 0, 7, 12, 10, 3, 1, 14, 6, 9, 8, 13, 11, 2, 5
], [
15, 6, 13, 8, 12, 11, 1, 9, 3, 5, 7, 14, 2, 10, 0, 4
], [
5, 1, 2, 14, 12, 4, 15, 13, 9, 11, 10, 3, 7, 0, 6, 8
]
], [
[
13, 5, 12, 2, 1, 10, 15, 9, 7, 14, 4, 0, 11, 3, 8, 6
], [
4, 15, 14, 6, 1, 10, 8, 11, 3, 5, 13, 7, 2, 9, 0, 12
], [
10, 14, 3, 12, 7, 5, 8, 4, 0, 9, 13, 15, 2, 11, 1, 6
], [
4, 1, 14, 9, 13, 15, 0, 12, 7, 10, 6, 3, 8, 11, 5, 2
]
], [
[
13, 12, 1, 14, 3, 6, 2, 4, 9, 7, 10, 15, 0, 5, 8, 11
], [
1, 5, 13, 9, 12, 3, 11, 0, 6, 14, 15, 2, 4, 8, 10, 7
], [
10, 2, 12, 0, 1, 9, 4, 5, 8, 6, 11, 15, 7, 3, 13, 14
], [
0, 14, 4, 3, 6, 12, 11, 8, 7, 15, 9, 2, 10, 5, 13, 1
]
], [
[
15, 4, 8, 11, 13, 0, 7, 6, 12, 1, 2, 9, 10, 14, 5, 3
], [
7, 9, 1, 14, 10, 6, 12, 11, 2, 13, 15, 4, 3, 0, 8, 5
], [
4, 15, 13, 2, 11, 8, 5, 10, 9, 7, 12, 14, 3, 6, 0, 1
], [
10, 11, 13, 0, 9, 3, 2, 7, 12, 5, 6, 4, 1, 14, 8, 15
]
], [
[
15, 5, 8, 10, 3, 9, 13, 1, 0, 4, 12, 6, 14, 2, 7, 11
], [
2, 13, 0, 6, 4, 14, 1, 3, 12, 11, 7, 10, 8, 9, 5, 15
], [
11, 14, 13, 12, 1, 2, 9, 0, 7, 4, 5, 6, 10, 8, 15, 3
], [
7, 1, 12, 6, 2, 11, 10, 5, 14, 4, 9, 15, 8, 3, 0, 13
]
], [
[
1, 15, 9, 5, 14, 0, 12, 10, 7, 4, 2, 13, 8, 3, 6, 11
], [
3, 11, 10, 2, 12, 4, 13, 6, 8, 5, 7, 14, 9, 0, 15, 1
], [
14, 15, 13, 5, 12, 10, 4, 3, 6, 7, 2, 0, 8, 11, 9, 1
], [
7, 15, 8, 12, 0, 3, 1, 4, 2, 14, 11, 9, 6, 13, 5, 10
]
], [
[
5, 10, 12, 7, 6, 9, 4, 8, 0, 2, 13, 1, 14, 15, 11, 3
], [
1, 8, 7, 9, 12, 6, 10, 14, 2, 5, 0, 4, 11, 15, 13, 3
], [
0, 4, 12, 3, 7, 8, 9, 10, 11, 15, 6, 1, 5, 13, 2, 14
], [
14, 5, 0, 7, 4, 13, 6, 10, 2, 15, 12, 8, 1, 9, 3, 11
]
], [
[
6, 13, 15, 0, 5, 10, 9, 7, 14, 4, 12, 2, 1, 8, 3, 11
], [
14, 12, 13, 10, 0, 1, 6, 9, 15, 4, 2, 11, 3, 8, 7, 5
], [
1, 15, 10, 14, 7, 8, 3, 2, 13, 12, 6, 0, 5, 9, 4, 11
], [
1, 3, 15, 5, 14, 12, 0, 11, 7, 10, 9, 4, 2, 6, 13, 8
]
], [
[
5, 3, 7, 15, 13, 14, 10, 4, 2, 0, 12, 6, 8, 1, 9, 11
], [
11, 0, 1, 3, 4, 12, 8, 5, 2, 10, 13, 9, 14, 15, 6, 7
], [
4, 15, 0, 1, 12, 11, 7, 2, 8, 13, 3, 6, 9, 5, 14, 10
], [
4, 15, 3, 0, 12, 5, 11, 2, 6, 8, 13, 1, 7, 14, 10, 9
]
], [
[
0, 7, 10, 9, 14, 12, 13, 8, 15, 6, 3, 5, 1, 4, 11, 2
], [
0, 12, 3, 1, 6, 4, 15, 13, 2, 7, 14, 8, 11, 5, 10, 9
], [
2, 0, 4, 3, 1, 6, 9, 11, 12, 15, 14, 13, 8, 7, 5, 10
], [
2, 11, 10, 3, 14, 4, 1, 5, 13, 0, 7, 9, 15, 6, 12, 8
]
], [
[
15, 5, 12, 9, 13, 6, 7, 0, 3, 1, 2, 14, 4, 10, 8, 11
], [
9, 14, 12, 5, 13, 7, 3, 0, 2, 6, 4, 10, 8, 15, 11, 1
], [
15, 2, 7, 6, 8, 13, 14, 12, 11, 9, 4, 5, 1, 0, 3, 10
], [
10, 5, 7, 6, 1, 4, 8, 0, 9, 14, 3, 11, 12, 15, 2, 13
]
], [
[
8, 7, 6, 13, 14, 0, 9, 5, 4, 11, 10, 12, 1, 3, 15, 2
], [
6, 4, 0, 3, 15, 12, 10, 9, 11, 7, 5, 14, 2, 1, 13, 8
], [
1, 15, 12, 8, 13, 6, 0, 7, 9, 4, 3, 10, 14, 5, 11, 2
], [
4, 7, 9, 5, 13, 1, 6, 8, 15, 2, 0, 12, 14, 10, 11, 3
]
], [
[
7, 5, 14, 0, 8, 12, 9, 15, 2, 1, 3, 11, 4, 13, 10, 6
], [
4, 0, 13, 2, 1, 6, 12, 3, 15, 11, 5, 10, 9, 14, 8, 7
], [
13, 9, 0, 10, 3, 11, 2, 12, 1, 15, 5, 14, 7, 8, 4, 6
], [
11, 3, 6, 5, 12, 7, 15, 14, 2, 8, 13, 9, 1, 10, 4, 0
]
], [
[
4, 8, 6, 14, 9, 5, 0, 12, 13, 11, 15, 3, 2, 7, 1, 10
], [
4, 10, 3, 14, 12, 1, 0, 15, 5, 8, 11, 9, 2, 7, 13, 6
], [
1, 7, 5, 0, 15, 2, 10, 14, 3, 12, 13, 6, 9, 8, 4, 11
], [
2, 10, 13, 3, 9, 11, 5, 15, 6, 1, 8, 14, 4, 0, 12, 7
]
], [
[
4, 15, 14, 9, 11, 1, 13, 8, 12, 3, 6, 10, 7, 0, 5, 2
], [
4, 15, 12, 6, 10, 1, 0, 3, 13, 14, 11, 2, 7, 5, 9, 8
], [
9, 3, 6, 15, 12, 2, 14, 8, 4, 5, 10, 13, 1, 0, 7, 11
], [
15, 3, 11, 13, 12, 6, 2, 0, 5, 9, 4, 1, 7, 10, 14, 8
]
], [
[
11, 5, 2, 15, 12, 6, 13, 14, 9, 4, 1, 7, 3, 10, 0, 8
], [
3, 8, 11, 9, 1, 13, 5, 6, 4, 12, 14, 0, 10, 15, 7, 2
], [
0, 7, 10, 1, 3, 11, 9, 8, 2, 12, 13, 4, 5, 14, 6, 15
], [
1, 9, 6, 7, 14, 11, 5, 0, 12, 2, 8, 4, 10, 15, 3, 13
]
], [
[
15, 7, 12, 3, 4, 2, 14, 13, 1, 11, 9, 8, 5, 6, 10, 0
], [
8, 7, 3, 11, 12, 15, 0, 5, 10, 6, 1, 4, 9, 13, 14, 2
], [
11, 15, 14, 9, 4, 13, 0, 12, 7, 8, 3, 5, 10, 6, 1, 2
], [
4, 13, 5, 8, 7, 11, 14, 10, 3, 1, 15, 2, 9, 6, 12, 0
]
], [
[
12, 3, 1, 14, 5, 0, 7, 2, 9, 4, 8, 13, 11, 6, 15, 10
], [
4, 7, 2, 10, 3, 15, 11, 6, 12, 1, 9, 0, 14, 13, 5, 8
], [
15, 2, 0, 10, 14, 11, 7, 4, 13, 1, 5, 12, 3, 8, 6, 9
], [
12, 10, 3, 14, 2, 5, 9, 6, 0, 11, 7, 13, 8, 1, 4, 15
]
], [
[
2, 1, 11, 8, 13, 9, 5, 7, 15, 14, 12, 6, 3, 10, 0, 4
], [
15, 11, 10, 2, 4, 3, 5, 8, 9, 0, 7, 14, 1, 12, 6, 13
], [
10, 9, 8, 1, 6, 0, 13, 5, 12, 2, 14, 7, 11, 4, 15, 3
], [
0, 1, 3, 8, 10, 5, 9, 11, 14, 2, 4, 13, 12, 7, 15, 6
]
], [
[
7, 8, 11, 3, 4, 0, 14, 15, 10, 9, 5, 2, 13, 1, 6, 12
], [
10, 4, 12, 11, 6, 0, 1, 14, 3, 7, 15, 2, 9, 13, 5, 8
], [
15, 7, 14, 3, 11, 6, 13, 9, 4, 8, 1, 0, 12, 5, 2, 10
], [
3, 5, 1, 8, 15, 6, 4, 13, 2, 10, 11, 12, 9, 7, 14, 0
]
], [
[
0, 4, 12, 1, 8, 11, 10, 7, 15, 5, 6, 2, 9, 3, 13, 14
], [
13, 14, 11, 4, 8, 3, 2, 5, 15, 9, 12, 0, 1, 7, 10, 6
], [
11, 13, 3, 4, 10, 8, 9, 7, 2, 1, 0, 15, 14, 12, 6, 5
], [
15, 14, 3, 13, 11, 8, 0, 6, 4, 1, 9, 10, 2, 5, 12, 7
]
], [
[
1, 10, 4, 15, 6, 9, 14, 11, 8, 2, 5, 7, 12, 0, 13, 3
], [
11, 0, 10, 9, 4, 1, 12, 2, 15, 8, 14, 5, 6, 13, 3, 7
], [
13, 2, 3, 14, 11, 15, 8, 1, 4, 0, 7, 10, 5, 12, 6, 9
], [
9, 2, 14, 13, 11, 5, 8, 4, 10, 1, 12, 7, 3, 0, 6, 15
]
], [
[
0, 7, 3, 2, 5, 4, 9, 14, 8, 1, 15, 10, 11, 6, 12, 13
], [
8, 4, 3, 9, 13, 2, 15, 0, 11, 7, 10, 5, 14, 1, 6, 12
], [
13, 1, 6, 12, 2, 5, 8, 14, 11, 15, 4, 0, 7, 10, 9, 3
], [
0, 14, 11, 5, 13, 1, 12, 2, 7, 6, 4, 10, 9, 3, 15, 8
]
], [
[
4, 0, 6, 1, 10, 7, 12, 15, 2, 14, 3, 5, 8, 11, 13, 9
], [
0, 8, 12, 13, 7, 14, 6, 4, 5, 2, 3, 9, 1, 11, 15, 10
], [
2, 7, 13, 8, 1, 15, 6, 14, 4, 0, 10, 11, 12, 5, 3, 9
], [
5, 11, 14, 9, 13, 10, 3, 1, 12, 8, 2, 0, 4, 7, 15, 6
]
], [
[
2, 11, 8, 0, 9, 15, 14, 1, 13, 5, 4, 7, 6, 3, 12, 10
], [
5, 12, 7, 3, 10, 4, 0, 8, 9, 13, 6, 1, 11, 15, 14, 2
], [
11, 0, 8, 10, 3, 9, 12, 14, 2, 13, 7, 1, 5, 4, 6, 15
], [
6, 12, 13, 7, 2, 1, 5, 0, 8, 15, 11, 14, 10, 9, 4, 3
]
], [
[
4, 5, 7, 12, 9, 3, 14, 1, 13, 15, 0, 10, 6, 2, 8, 11
], [
11, 1, 7, 3, 4, 12, 2, 0, 10, 9, 13, 15, 6, 8, 14, 5
], [
10, 5, 14, 2, 1, 6, 4, 7, 0, 13, 11, 3, 15, 12, 8, 9
], [
12, 7, 1, 6, 3, 9, 11, 5, 0, 2, 4, 13, 14, 10, 15, 8
]
], [
[
5, 6, 2, 14, 13, 9, 8, 10, 11, 3, 1, 7, 0, 12, 15, 4
], [
7, 1, 6, 4, 3, 9, 0, 15, 14, 5, 10, 13, 2, 12, 8, 11
], [
2, 0, 5, 11, 1, 3, 7, 4, 15, 6, 14, 9, 12, 8, 10, 13
], [
8, 0, 14, 6, 11, 5, 3, 1, 9, 7, 12, 15, 13, 10, 2, 4
]
], [
[
15, 0, 1, 12, 8, 2, 14, 13, 3, 10, 4, 9, 6, 5, 7, 11
], [
1, 14, 6, 0, 7, 4, 12, 3, 8, 13, 9, 5, 10, 15, 11, 2
], [
6, 8, 7, 2, 4, 15, 0, 10, 9, 11, 12, 5, 3, 13, 1, 14
], [
5, 15, 3, 11, 10, 8, 2, 12, 6, 4, 7, 0, 13, 1, 9, 14
]
], [
[
6, 9, 3, 8, 13, 7, 1, 5, 14, 15, 0, 11, 12, 10, 2, 4
], [
3, 1, 0, 10, 2, 7, 13, 8, 14, 15, 4, 9, 12, 11, 5, 6
], [
3, 7, 14, 6, 10, 12, 2, 1, 8, 13, 9, 0, 5, 11, 4, 15
], [
13, 7, 3, 1, 14, 0, 5, 2, 6, 11, 9, 4, 15, 8, 10, 12
]
], [
[
2, 9, 7, 6, 0, 15, 4, 10, 11, 13, 8, 5, 1, 14, 12, 3
], [
1, 5, 7, 15, 0, 12, 14, 3, 13, 6, 9, 11, 2, 10, 8, 4
], [
6, 8, 5, 2, 9, 11, 12, 0, 1, 10, 13, 7, 14, 4, 15, 3
], [
3, 6, 1, 9, 13, 12, 15, 4, 8, 2, 10, 0, 7, 5, 11, 14
]
], [
[
6, 13, 5, 15, 3, 12, 11, 8, 4, 9, 2, 0, 7, 10, 1, 14
], [
15, 1, 2, 8, 12, 7, 13, 9, 14, 3, 11, 10, 6, 5, 0, 4
], [
13, 9, 1, 2, 12, 3, 0, 6, 10, 14, 4, 7, 8, 15, 5, 11
], [
15, 2, 11, 5, 9, 13, 1, 14, 12, 4, 0, 7, 3, 8, 6, 10
]
], [
[
9, 7, 8, 2, 14, 12, 0, 3, 11, 6, 15, 5, 10, 1, 13, 4
], [
8, 0, 9, 5, 3, 14, 1, 15, 13, 7, 10, 6, 12, 2, 4, 11
], [
1, 11, 12, 2, 5, 3, 14, 15, 9, 6, 8, 10, 0, 4, 13, 7
], [
1, 15, 14, 0, 6, 2, 3, 10, 5, 9, 12, 13, 7, 11, 8, 4
]
], [
[
10, 5, 6, 12, 13, 2, 14, 11, 8, 9, 7, 15, 4, 3, 1, 0
], [
8, 3, 7, 5, 13, 10, 14, 2, 9, 15, 11, 6, 1, 0, 12, 4
], [
8, 13, 14, 10, 15, 2, 5, 9, 4, 12, 6, 7, 3, 11, 1, 0
], [
0, 15, 3, 12, 10, 9, 7, 13, 4, 5, 6, 2, 14, 8, 1, 11
]
], [
[
13, 8, 1, 3, 14, 12, 4, 10, 2, 11, 9, 7, 5, 0, 6, 15
], [
11, 7, 12, 3, 13, 6, 0, 2, 14, 8, 9, 10, 15, 5, 1, 4
], [
4, 2, 5, 1, 0, 13, 6, 7, 12, 15, 14, 9, 3, 11, 10, 8
], [
0, 3, 2, 4, 12, 10, 13, 11, 1, 14, 15, 5, 6, 9, 8, 7
]
], [
[
10, 14, 2, 4, 7, 11, 12, 0, 8, 1, 9, 5, 6, 13, 3, 15
], [
8, 3, 1, 13, 6, 7, 5, 11, 9, 15, 0, 4, 12, 14, 2, 10
], [
1, 10, 6, 11, 9, 0, 7, 5, 3, 13, 4, 8, 2, 12, 14, 15
], [
0, 14, 11, 13, 4, 6, 12, 8, 3, 10, 2, 7, 5, 9, 1, 15
]
], [
[
6, 2, 5, 15, 9, 4, 14, 3, 13, 7, 8, 1, 0, 11, 10, 12
], [
14, 7, 13, 8, 2, 9, 0, 11, 1, 12, 5, 15, 3, 4, 10, 6
], [
13, 2, 12, 3, 14, 1, 15, 7, 0, 6, 10, 5, 11, 4, 9, 8
], [
15, 3, 12, 2, 6, 11, 4, 7, 1, 14, 13, 10, 5, 0, 9, 8
]
], [
[
8, 1, 0, 15, 13, 9, 5, 14, 12, 10, 4, 3, 6, 2, 7, 11
], [
4, 10, 14, 2, 12, 7, 9, 8, 1, 5, 13, 15, 0, 6, 11, 3
], [
15, 8, 12, 4, 13, 0, 7, 1, 2, 11, 6, 14, 9, 3, 10, 5
], [
5, 11, 0, 9, 13, 8, 14, 3, 4, 7, 6, 10, 1, 12, 15, 2
]
], [
[
0, 6, 13, 10, 3, 7, 4, 12, 2, 11, 1, 9, 14, 8, 5, 15
], [
15, 13, 0, 2, 9, 10, 4, 12, 5, 11, 7, 8, 14, 3, 6, 1
], [
8, 15, 3, 4, 12, 14, 5, 10, 0, 11, 1, 6, 2, 7, 9, 13
], [
3, 0, 6, 11, 10, 13, 8, 5, 1, 2, 15, 4, 9, 12, 7, 14
]
], [
[
14, 11, 15, 12, 5, 9, 0, 2, 8, 1, 13, 7, 4, 3, 10, 6
], [
2, 4, 7, 13, 6, 10, 11, 0, 9, 12, 8, 14, 3, 5, 15, 1
], [
14, 6, 11, 15, 8, 7, 4, 13, 5, 12, 10, 0, 3, 1, 2, 9
], [
5, 15, 6, 11, 12, 9, 0, 8, 13, 10, 4, 7, 1, 2, 14, 3
]
], [
[
15, 6, 10, 2, 3, 12, 7, 4, 8, 0, 1, 9, 5, 14, 13, 11
], [
6, 11, 4, 3, 13, 0, 12, 7, 8, 10, 5, 1, 14, 2, 15, 9
], [
0, 11, 14, 2, 13, 12, 8, 6, 10, 15, 5, 3, 4, 1, 7, 9
], [
4, 3, 14, 9, 10, 15, 2, 13, 12, 7, 1, 6, 0, 8, 5, 11
]
], [
[
8, 10, 12, 0, 4, 13, 9, 6, 14, 15, 3, 2, 5, 7, 1, 11
], [
12, 7, 10, 9, 0, 13, 11, 14, 2, 6, 4, 1, 3, 15, 8, 5
], [
4, 10, 2, 13, 12, 11, 15, 1, 9, 7, 5, 6, 14, 3, 8, 0
], [
12, 10, 13, 14, 9, 8, 2, 15, 0, 11, 6, 3, 5, 7, 4, 1
]
], [
[
1, 3, 7, 6, 13, 10, 4, 15, 5, 2, 9, 12, 14, 8, 11, 0
], [
3, 15, 7, 6, 12, 4, 11, 14, 8, 10, 13, 9, 5, 1, 2, 0
], [
12, 6, 2, 4, 1, 0, 13, 7, 9, 11, 5, 10, 3, 14, 8, 15
], [
6, 5, 1, 11, 8, 0, 13, 15, 2, 7, 12, 4, 3, 10, 14, 9
]
], [
[
15, 8, 5, 1, 14, 4, 7, 13, 3, 6, 9, 11, 10, 0, 2, 12
], [
6, 14, 11, 15, 3, 13, 7, 0, 2, 1, 9, 4, 12, 5, 8, 10
], [
0, 9, 8, 11, 3, 10, 6, 2, 12, 5, 7, 14, 4, 13, 1, 15
], [
5, 1, 14, 11, 9, 7, 2, 12, 3, 0, 15, 13, 6, 8, 10, 4
]
], [
[
12, 3, 8, 10, 15, 0, 13, 1, 7, 9, 6, 11, 5, 2, 14, 4
], [
2, 13, 0, 10, 9, 6, 11, 7, 3, 15, 8, 14, 1, 5, 12, 4
], [
2, 12, 1, 11, 14, 9, 5, 4, 10, 6, 7, 13, 8, 15, 3, 0
], [
13, 8, 6, 7, 9, 2, 3, 15, 10, 1, 4, 11, 14, 0, 5, 12
]
], [
[
14, 9, 11, 12, 5, 13, 1, 3, 4, 10, 2, 6, 8, 15, 7, 0
], [
9, 7, 1, 15, 0, 6, 3, 11, 10, 12, 4, 14, 5, 8, 2, 13
], [
5, 6, 4, 11, 10, 3, 12, 15, 8, 13, 1, 0, 9, 7, 14, 2
], [
3, 11, 4, 12, 14, 6, 15, 0, 2, 13, 8, 1, 10, 5, 9, 7
]
], [
[
6, 12, 9, 1, 15, 0, 7, 5, 11, 14, 4, 13, 2, 3, 10, 8
], [
9, 15, 13, 10, 14, 5, 4, 6, 3, 0, 1, 11, 7, 12, 2, 8
], [
11, 3, 2, 14, 15, 1, 10, 12, 7, 5, 9, 0, 4, 13, 8, 6
], [
0, 12, 15, 10, 13, 7, 5, 4, 6, 9, 8, 14, 1, 11, 2, 3
]
], [
[
6, 0, 10, 14, 4, 11, 1, 13, 2, 15, 5, 9, 7, 8, 12, 3
], [
1, 12, 9, 10, 14, 2, 8, 7, 3, 6, 5, 15, 0, 4, 13, 11
], [
10, 3, 13, 4, 12, 6, 0, 5, 1, 11, 15, 8, 2, 14, 7, 9
], [
9, 14, 2, 1, 0, 8, 12, 10, 5, 11, 15, 3, 4, 13, 7, 6
]
]
]

Crypsh Search Page

Several drafted cryptographic hash functions are listed on this page. All are implemented in Ruby.

Warning! All these drafts are particularly weak. However, it could attract curious minds.

License

Crypsh is released under the open source BSD license, which gives you the possibility to use it and modify it in every circumstance.

=begin
* General binary methods library
* Copyright (c) 2008 Cyril Kato
* Code licensed under the BSD License:
http://www.opensource.org/licenses/bsd-license.php
* version: 0.1
=end
module BinaryMethods
def str2bin(str)
str.unpack('c*').collect { |x| sprintf('%02x', x) }.to_s.hex.to_s(2)
end
def bin2str(bin)
bin.scan(/.{8}/).map { |x| x.to_i(2) }.pack('C*')
end
def padding_block(bin, length)
while (bin.length < length)
bin = '0' + bin
end
bin
end
def cut(bin, length)
if bin.length > length:
bin = bin[(bin.length - length), length]
end
bin
end
def bitmask(bits)
( 1 << bits ) - 1
end
def shift_left_width(value, register_width, bits)
( value << bits ) & bitmask(register_width)
end
def circular_shift_right(value, register_width, bits)
remaining_bits = register_width - bits
top = shift_left_width(value, register_width, remaining_bits)
bottom = value >> bits
top | bottom
end
def circular_shift_left(value, register_width, bits)
remaining_bits = register_width - bits
top = shift_left_width(value, register_width, bits)
bottom = value >> remaining_bits
top | bottom
end
VERSION = 0.1
end
=begin
* General binary methods library
* Copyright (c) 2008 Cyril Kato
* Code licensed under the BSD License:
http://www.opensource.org/licenses/bsd-license.php
* version: 0.2
=end
module BinaryMethods
def str2bin(str)
str.unpack('C*').map { |x| x.to_s(2).rjust(8, '0') }.join
end
def bin2str(bin)
bin.scan(/.{8}/).map { |x| x.to_i(2) }.pack('C*')
end
def padding_block(bin, length)
while (bin.length < length)
bin = '0' + bin
end
bin
end
def cut(bin, length)
if bin.length > length:
bin = bin[(bin.length - length), length]
end
bin
end
def bitmask(bits)
( 1 << bits ) - 1
end
def shift_left_width(value, register_width, bits)
( value << bits ) & bitmask(register_width)
end
def circular_shift_right(value, register_width, bits)
remaining_bits = register_width - bits
top = shift_left_width(value, register_width, remaining_bits)
bottom = value >> bits
top | bottom
end
def circular_shift_left(value, register_width, bits)
remaining_bits = register_width - bits
top = shift_left_width(value, register_width, bits)
bottom = value >> remaining_bits
top | bottom
end
VERSION = 0.2
end
BLOCKSIZE = 8
PATH_FILE = 'crypsh-0.2-global.rb'
require PATH_FILE
#require 'crypsh-0.1'
include Crypsh
#a = hash(ARGV[0])
#puts "#{a}"
puts '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
puts '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">'
puts '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" height="100%">'
puts "<desc>Crypsh coordinate map on #{BLOCKSIZE} bits</desc>"
puts '<g id="coordinatemap">'
results = Array.new(2**BLOCKSIZE)
(2**BLOCKSIZE).times { |cpt|
results[cpt] = hash(cpt.to_s(2), 'bin')
#puts "<!-- "
#puts " results[cpt]: #{results[cpt]}"
#puts " results[cpt].to_i(16): #{results[cpt].to_i(16)}"
#puts " -->"
puts "<circle cx=\"#{cpt}\" cy=\"#{results[cpt].to_i(16)}\" r=\"1\" fill=\"yellow\" fill-opacity=\"1\" stroke=\"green\" stroke-width=\"1\"/>"
}
reference = Array.new
nb_of_collision = 0
(2**BLOCKSIZE).times { |cpt|
(2**BLOCKSIZE).times { |cpt_bit|
if ((results[cpt] == results[cpt_bit]) && cpt != cpt_bit) then
# now we just control that there this collision is not yet refered
add_this = true
(reference.length).times do |cpt_scan|
add_this = false if results[cpt] == reference[cpt_scan]
end
if add_this == true:
reference[nb_of_collision] = results[cpt]
nb_of_collision += 1
print "<circle cx=\"#{cpt}\" cy=\"#{results[cpt].to_i(16)}\" r=\"1\" fill=\"red\" fill-opacity=\"1\" stroke=\"red\" stroke-width=\"1\"/>"
puts "<!-- Collision detected on #{results[cpt]} with: #{cpt} and #{cpt_bit} -->"
end
end
}
}
puts '</g>'
puts '</svg>'
puts "<!-- collision: #{nb_of_collision} -->"
=begin
* A Ruby implementation of Crypsh (CRYPtographic haSH)
* Copyright (c) 2006 Cyril Kato
* Code licensed under the BSD License:
http://www.opensource.org/licenses/bsd-license.php
* version: 0.0.1
=end
class Hash
def initialize(message="")
@message = message
end
def publish
def to_hex(string)
hex_blob = ""
string.each_byte do |c|
hex_blob << format("%02X", c)
end
return hex_blob
end
def multiplication(string)
big_string = string.to_i << 1024
end
def cut(string)
block = string.to_s.reverse.slice(9..16)
end
tmp = to_hex(@message)
tmp = multiplication(tmp)
tmp = to_hex(tmp.to_s).hex.to_s(2)
tmp = cut(tmp)
return tmp
end
end
print "Please, enter a value : "
my_hash = Hash.new(gets.chomp)
puts "Hash = #{my_hash.publish}"
=begin
* A Ruby implementation of Crypsh (CRYPtographic haSH)
* Copyright (c) 2006 Cyril Kato
* Code licensed under the BSD License:
http://www.opensource.org/licenses/bsd-license.php
* version: 0.0.2
=end
class Hash
def initialize(message="")
@message = message
# size of each block : 8 bits
# size of the hash : 8 bits
end
def publish
def to_hex(string)
hex_blob = ""
string.each_byte do |c|
hex_blob << format("%02X", c)
end
return hex_blob
end
def horizon_vector(block)
bit_1 = block.to_s.slice(0..0)
bit_2 = block.to_s.slice(1..1)
bit_3 = block.to_s.slice(2..2)
bit_4 = block.to_s.slice(3..3)
bit_5 = block.to_s.slice(4..4)
bit_6 = block.to_s.slice(5..5)
bit_7 = block.to_s.slice(6..6)
bit_8 = block.to_s.slice(7..7)
@the_vector_horizon = (bit_1.to_s.to_i ^ bit_2.to_s.to_i) ^ (bit_3.to_s.to_i ^ bit_4.to_s.to_i) ^ (bit_5.to_s.to_i ^ bit_6.to_s.to_i) ^ (bit_7.to_s.to_i ^ bit_8.to_s.to_i)
block = (bit_1.to_i ^ @the_vector_horizon).to_s +
(bit_2.to_i ^ @the_vector_horizon).to_s +
(bit_3.to_i ^ @the_vector_horizon).to_s +
(bit_4.to_i ^ @the_vector_horizon).to_s +
(bit_5.to_i ^ @the_vector_horizon).to_s +
(bit_6.to_i ^ @the_vector_horizon).to_s +
(bit_7.to_i ^ @the_vector_horizon).to_s +
(bit_8.to_i ^ @the_vector_horizon).to_s
return block
end
def vertical_vector(block)
@the_vector_vertical = 0
@the_vector_vertical = @the_vector_vertical + block.to_i % 2
@the_vector_vertical = @the_vector_vertical + ((block.to_s.slice(1..1) + block.to_s.slice(2..2)).to_i % 2) * 2
if @the_vector_vertical == 0
bit_1 = block.to_s.slice(0..0)
bit_2 = block.to_s.slice(1..1)
bit_3 = block.to_s.slice(2..2)
bit_4 = block.to_s.slice(3..3)
bit_5 = block.to_s.slice(4..4)
bit_6 = block.to_s.slice(5..5)
bit_7 = block.to_s.slice(6..6)
bit_8 = block.to_s.slice(7..7)
bit_8 = block.to_s.slice(7..7)
elsif @the_vector_vertical == 1
bit_2 = block.to_s.slice(0..0)
bit_3 = block.to_s.slice(1..1)
bit_4 = block.to_s.slice(2..2)
bit_5 = block.to_s.slice(3..3)
bit_6 = block.to_s.slice(4..4)
bit_7 = block.to_s.slice(5..5)
bit_8 = block.to_s.slice(6..6)
bit_1 = block.to_s.slice(7..7)
elsif @the_vector_vertical == 2
bit_3 = block.to_s.slice(0..0)
bit_4 = block.to_s.slice(1..1)
bit_5 = block.to_s.slice(2..2)
bit_6 = block.to_s.slice(3..3)
bit_7 = block.to_s.slice(4..4)
bit_8 = block.to_s.slice(5..5)
bit_1 = block.to_s.slice(6..6)
bit_2 = block.to_s.slice(7..7)
elsif @the_vector_vertical == 3
bit_4 = block.to_s.slice(0..0)
bit_5 = block.to_s.slice(1..1)
bit_6 = block.to_s.slice(2..2)
bit_7 = block.to_s.slice(3..3)
bit_8 = block.to_s.slice(4..4)
bit_1 = block.to_s.slice(5..5)
bit_2 = block.to_s.slice(6..6)
bit_3 = block.to_s.slice(7..7)
elsif @the_vector_vertical == 4
bit_5 = block.to_s.slice(0..0)
bit_6 = block.to_s.slice(1..1)
bit_7 = block.to_s.slice(2..2)
bit_8 = block.to_s.slice(3..3)
bit_1 = block.to_s.slice(4..4)
bit_2 = block.to_s.slice(5..5)
bit_3 = block.to_s.slice(6..6)
bit_4 = block.to_s.slice(7..7)
elsif @the_vector_vertical == 5
bit_6 = block.to_s.slice(0..0)
bit_7 = block.to_s.slice(1..1)
bit_8 = block.to_s.slice(2..2)
bit_1 = block.to_s.slice(3..3)
bit_2 = block.to_s.slice(4..4)
bit_3 = block.to_s.slice(5..5)
bit_4 = block.to_s.slice(6..6)
bit_5 = block.to_s.slice(7..7)
elsif @the_vector_vertical == 6
bit_7 = block.to_s.slice(0..0)
bit_8 = block.to_s.slice(1..1)
bit_1 = block.to_s.slice(2..2)
bit_2 = block.to_s.slice(3..3)
bit_3 = block.to_s.slice(4..4)
bit_4 = block.to_s.slice(5..5)
bit_5 = block.to_s.slice(6..6)
bit_6 = block.to_s.slice(7..7)
else @the_vector_vertical == 7
bit_8 = block.to_s.slice(0..0)
bit_1 = block.to_s.slice(1..1)
bit_2 = block.to_s.slice(2..2)
bit_3 = block.to_s.slice(3..3)
bit_4 = block.to_s.slice(4..4)
bit_5 = block.to_s.slice(5..5)
bit_6 = block.to_s.slice(6..6)
bit_7 = block.to_s.slice(7..7)
end
block = (bit_1 + bit_2 + bit_3 + bit_4 + bit_5 + bit_6 + bit_7 + bit_8)
return block
end
def block_xor_block(block_a, block_b)
bit_1 = block_a.to_s.slice(0..0).to_i ^ block_b.to_s.slice(0..0).to_i
bit_2 = block_a.to_s.slice(1..1).to_i ^ block_b.to_s.slice(1..1).to_i
bit_3 = block_a.to_s.slice(2..2).to_i ^ block_b.to_s.slice(2..2).to_i
bit_4 = block_a.to_s.slice(3..3).to_i ^ block_b.to_s.slice(3..3).to_i
bit_5 = block_a.to_s.slice(4..4).to_i ^ block_b.to_s.slice(4..4).to_i
bit_6 = block_a.to_s.slice(5..5).to_i ^ block_b.to_s.slice(5..5).to_i
bit_7 = block_a.to_s.slice(6..6).to_i ^ block_b.to_s.slice(6..6).to_i
bit_8 = block_a.to_s.slice(7..7).to_i ^ block_b.to_s.slice(7..7).to_i
block = bit_1.to_s + bit_2.to_s + bit_3.to_s + bit_4.to_s + bit_5.to_s + bit_6.to_s + bit_7.to_s + bit_8.to_s
return block
end
tmp = to_hex(@message)
@block = tmp.hex.to_s(2)
until @block.to_s.length % 8 == 0
@block = "0" + @block
end
until @block.to_s.length >= 8
@block = "0" + @block
end
@block = @block.scan /(.{1,8})/
nb_block = (@block.to_s.length/8)
lol = 0
nb_block.times {
lol += 1
}
lol = 0
nb_block.times {
@block[lol] = horizon_vector(@block[lol])
@block[lol] = vertical_vector(@block[lol])
lol += 1
}
block_final = @block[0]
tmp = 1
(nb_block-1).times do
block_final = block_xor_block(block_final, @block[tmp])
tmp += 1
end
@block = block_final
return @block
end
end
print "Please, enter a value : "
my_hash = Hash.new(gets.chomp)
puts "Hash = #{my_hash.publish}"
=begin
* A Ruby implementation of Crypsh (CRYPtographic haSH)
* Copyright (c) 2007 Cyril Kato
* Code licensed under the BSD License:
http://www.opensource.org/licenses/bsd-license.php
* version: 0.0.3.3
=end
class Crypsh
def initialize(message="")
@message = message
@size = 128
@nb_of_bit = ( Math.log(@size) / Math.log(2) ).to_i
puts "@nb_of_bit = #{@nb_of_bit}"
end
def generate
def to_hex(string)
hex_blob = ""
string.each_byte do |c|
hex_blob << format("%02X", c)
end
return hex_blob
end
tmp = to_hex(@message)
puts "valeur hexadecimale = #{tmp}"
tmp = tmp.hex.to_s(2)
puts "valeur binaire = #{tmp}"
# on veut avoir une longeur de chaine multiple de @size
until tmp.to_s.length % @size == 0
tmp = "0" + tmp
end
puts "\n---"
##################################################
# 1. Decoupage en M.length / N bloc(s) de n bits #
##################################################
puts "1. Decoupage en M.length / N bloc(s) de n bits"
puts "\n"
@block_v1 = tmp.scan /(.{1,#{@size}})/
# (begin) visionneur de bloc
puts "\n"
puts " Visionneur de bloc"
cpt = 0
(@block_v1.length).times {
puts " Bloc numero #{cpt}: #{@block_v1[cpt]}"
cpt += 1
}
puts "\n"
# (end) visionneur de bloc
puts "\n---"
############################################
# 2. Modification dynamique de chaque bloc #
############################################
puts "2. Modification dynamique de chaque bloc"
puts "\n"
# travaille bloc par bloc
# selection d un bloc
@block_v2 = [ 0 ]
cpt = 0
(@block_v1.length).times {
#
# MEMORISATION
#
firt_bit = @size - @nb_of_bit
last_bit = @size - 1
dynamic_vector = @block_v1[cpt].to_s.slice(firt_bit..last_bit).to_i
dynamic_vector = "0b" + dynamic_vector.to_s
dynamic_vector = dynamic_vector.to_i(2)
puts "lal, le vecteur: #{dynamic_vector}"
tmp = @block_v1[cpt].to_s.to_i(2)
#
# DECALAGE
#
@block_v2[cpt] = (tmp + cpt).to_s(2)
puts "lal, apres decalage: #{@block_v2[cpt]}"
puts "lal, apres decalage: #{@block_v2[cpt].to_s.to_i(2)}"
# on veut avoir une longeur de chaine multiple de @size
while @block_v2[cpt].to_s.length < @size
@block_v2[cpt] = "0" + @block_v2[cpt].to_s
puts "lal"
end
puts "lal, apres decalage: #{@block_v2[cpt]}"
#
# CREATION DU MASQUE
#
string = @block_v2[cpt]
occur_mask = ""
i = 0
(@size).times {
indice = ( i + dynamic_vector ).to_s.slice(0...@nb_of_bit).to_i
if(indice >= @size)
then indice = indice - @size
end
puts "indice #{i}: #{indice}"
occur_mask += string.to_s.slice(indice..indice)
i += 1
}
puts "lal: #{occur_mask.to_i}"
puts " le block #{@block_v2[cpt]}"
puts " le mask #{occur_mask}"
puts " XOR --------"
buffer = ""
bit = 0
@size.times {
buffer = buffer + ( @block_v2[cpt].to_s.slice(bit..bit).to_i ^ occur_mask.to_s.slice(bit..bit).to_i ).to_s
bit += 1
}
@block_v2[cpt] = buffer
puts "-> block_v2 #{@block_v2[cpt]}"
#@block_v2[cpt] = occur_mask
# on veut avoir une longeur du bloc egale a @size
while(@block_v2[cpt].to_s.length < @size)
@block_v2[cpt] = "0" + @block_v2[cpt]
end
# dans l eventualite ou @block[cpt].length est > que @size
if @block_v2[cpt].to_s.length > @size then
puts " a couper"
@block_v2[cpt] = @block_v2[cpt].to_s.slice(1..@size)
end
cpt += 1
}
# (begin) visionneur de bloc
puts "\n"
puts " Visionneur de bloc"
cpt = 0
(@block_v2.length).times {
puts " Bloc numero #{cpt}: #{@block_v2[cpt]}"
cpt += 1
}
puts "\n"
# (end) visionneur de bloc
puts "\n---"
#################################
# 3. Compression de chaque bloc #
#################################
puts "3. Compression de chaque bloc"
puts "\n"
@block_v4 = @block_v2[0]
cpt = 1
(@block_v2.length - 1).times {
tmp = @block_v4.to_i(2)
tmp ^= @block_v2[cpt].to_s.to_i(2)
@block_v4 = tmp.to_s(2)
cpt += 1
}
# (begin) visionneur de bloc
puts "\n"
puts " Visionneur de bloc"
puts " Bloc: #{@block_v4}"
puts "\n"
# (end) visionneur de bloc
puts "\n---"
return @block_v4.to_i(2).to_s(16)
end
end
print "Please, enter a value : "
my_hash = Crypsh.new(gets.chomp)
print "Hash = #{my_hash.generate}"
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
=begin
* A Ruby implementation of Crypsh (CRYPtographic haSH)
* Copyright (c) 2007 Cyril Kato
* Code licensed under the BSD License:
http://www.opensource.org/licenses/bsd-license.php
* version: 0.0.4
=end
class Crypsh
def initialize(message="")
@message = message
@size = 128
@nb_of_bit = ( Math.log(@size) / Math.log(2) ).to_i
puts "@nb_of_bit = #{@nb_of_bit}"
end
def generate
def to_hex(string)
hex_blob = ""
string.each_byte do |c|
hex_blob << format("%02X", c)
end
return hex_blob
end
tmp = to_hex(@message)
puts "valeur hexadecimale = #{tmp}"
tmp = tmp.hex.to_s(2)
puts "valeur binaire = #{tmp}"
# on veut avoir une longeur de chaine multiple de @size
until tmp.to_s.length % @size == 0
tmp = "0" + tmp
end
puts "\n---"
##################################################
# 1. Decoupage en M.length / N bloc(s) de n bits #
##################################################
puts "1. Decoupage en M.length / N bloc(s) de n bits"
puts "\n"
@block_v1 = tmp.scan /(.{1,#{@size}})/
# (begin) visionneur de bloc
puts "\n"
puts " Visionneur de bloc"
cpt = 0
(@block_v1.length).times {
puts " Bloc numero #{cpt}: #{@block_v1[cpt]}"
cpt += 1
}
puts "\n"
# (end) visionneur de bloc
puts "\n---"
############################################
# 2. Modification dynamique de chaque bloc #
############################################
puts "2. Modification dynamique de chaque bloc"
puts "\n"
# travaille bloc par bloc
# selection d un bloc
@block_v2 = [ 0 ]
cpt = 0
(@block_v1.length).times {
#
# CONSTANTE
#
constante = cpt + @nb_of_bit
#
# DECALAGE
#
tmp = @block_v1[cpt].to_s.to_i(2)
@block_v2[cpt] = (tmp + constante).to_s(2)
puts "lal, apres decalage: #{@block_v2[cpt]}"
puts "lal, apres decalage: #{@block_v2[cpt].to_s.to_i(2)}"
# on veut avoir une longeur de chaine multiple de @size
while @block_v2[cpt].to_s.length < @size
@block_v2[cpt] = "0" + @block_v2[cpt].to_s
puts "lal"
end
puts "lal, apres decalage: #{@block_v2[cpt]}"
#
# CREATION DU MASQUE
#
string = @block_v2[cpt]
occur_mask = ""
i = 0
(@size).times {
indice = ( i + constante ).to_s.slice(0...@nb_of_bit).to_i
until indice < @size
puts "done"
indice = indice - @size
end
puts "indice #{i}: #{indice}"
occur_mask += string[indice..indice]
i += 1
}
@block_v2[cpt] = occur_mask
puts "-> block_v2 #{@block_v2[cpt]}"
# on veut avoir une longeur du bloc egale a @size
while(@block_v2[cpt].to_s.length < @size)
@block_v2[cpt] = "0" + @block_v2[cpt]
end
# dans l eventualite ou @block[cpt].length est > que @size
if @block_v2[cpt].to_s.length > @size then
puts " a couper"
@block_v2[cpt] = @block_v2[cpt].to_s.slice(1..@size)
end
cpt += 1
}
# (begin) visionneur de bloc
puts "\n"
puts " Visionneur de bloc"
cpt = 0
(@block_v2.length).times {
puts " Bloc numero #{cpt}: #{@block_v2[cpt]}"
cpt += 1
}
puts "\n"
# (end) visionneur de bloc
puts "\n---"
#################################
# 3. Compression de chaque bloc #
#################################
puts "3. Compression de chaque bloc"
puts "\n"
@block_v4 = @block_v2[0]
cpt = 1
(@block_v2.length - 1).times {
tmp = @block_v4.to_i(2)
tmp ^= @block_v2[cpt].to_s.to_i(2)
@block_v4 = tmp.to_s(2)
cpt += 1
}
# (begin) visionneur de bloc
puts "\n"
puts " Visionneur de bloc"
puts " Bloc: #{@block_v4}"
puts "\n"
# (end) visionneur de bloc
puts "\n---"
return @block_v4.to_i(2).to_s(16)
end
end
print "Please, enter a value : "
my_hash = Crypsh.new(gets.chomp)
print "Hash = #{my_hash.generate}"
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
=begin
* A Ruby implementation of Crypsh (CRYPtographic haSH)
* Copyright (c) 2007 Cyril Kato
* Code licensed under the BSD License:
http://www.opensource.org/licenses/bsd-license.php
* version: 0.0.5
=end
class Crypsh
def initialize(size=128)
@length_of_each_block = size
@nb_of_bit = ( Math.log(@length_of_each_block) / Math.log(2) ).to_i
end
def to_hex(string)
hex_blob = ""
string.each_byte do |c|
hex_blob << format("%02X", c)
end
return hex_blob
end
def padding(binary_string)
binary_string = binary_string.to_s
until binary_string.length % @length_of_each_block == 0
binary_string = "0" + binary_string
end
return binary_string
end
def size_length(binary_string)
binary_string = binary_string.to_s
if(binary_string.length < @length_of_each_block) then
while(binary_string.length < @length_of_each_block)
binary_string = "0" + binary_string
end
end
return binary_string
end
def cut(binary_string)
binary_string = binary_string.to_s
if binary_string.length > @length_of_each_block then
i_begin = binary_string.length - @length_of_each_block
i_end = i_begin + @length_of_each_block
binary_string = binary_string.to_s.slice(i_begin...i_end)
end
return size_length(binary_string)
end
def shift(binary_string, constant)
binary_string = size_length(binary_string)
constant = constant.to_i(2)
buffer = ""
(@length_of_each_block).times { |i|
indice = ( i + constant )
while(indice >= @length_of_each_block)
indice = indice - @length_of_each_block
end
buffer = buffer + binary_string.slice(indice..indice)
}
binary_string = buffer
return size_length(binary_string)
end
def compression(binary_string, block)
block = block.to_i(2)
binary_string = binary_string.to_i(2)
binary_string ^= block
return binary_string.to_s(2)
end
def avalanche(binary_string)
binary_string = binary_string.to_i(2)
binary_string += binary_string << 1
return cut(binary_string.to_s(2))
end
def addition(binary_string, constant)
binary_string = binary_string.to_i(2) + constant
return cut(size_length(binary_string.to_s(2)))
end
def make(hash)
binary_string = '0'
(hash.length / @length_of_each_block ).times do |i|
i_begin = i * @length_of_each_block
i_end = (i + 1) * @length_of_each_block
block = hash.slice(i_begin...i_end)
binary_string = compression(binary_string, block)
binary_string = avalanche(binary_string)
i_begin = @length_of_each_block - @nb_of_bit
i_end = @length_of_each_block
constant_dynamic = hash.slice(i_begin..i_end)
binary_string = shift(binary_string, constant_dynamic)
binary_string = compression(binary_string, block)
end
return binary_string.to_i(2).to_s(16)
end
def publish(input='Message', type='str')
input = to_hex( input.to_s ).hex.to_s(2) if type != 'bin'
print make( padding( input ) )
end
end
my_hash = Crypsh.new(128)
my_hash.publish(ARGV[0], ARGV[1])
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
=begin
* A Ruby implementation of Crypsh (CRYPtographic haSH)
* Copyright (c) 2008 Cyril Kato
* Code licensed under the BSD License:
http://www.opensource.org/licenses/bsd-license.php
* version: 0.0.6
=end
class Crypsh
def initialize(size=256)
@length_of_each_block = size
@nb_of_bit = ( Math.log(@length_of_each_block) / Math.log(2) ).to_i
end
def str2bin(str)
str.unpack('c*').collect { |x| sprintf('%02X', x) }.to_s.hex.to_s(2)
end
def padding_on_the_right(bin, length=2 * @length_of_each_block)
if (bin.length < length):
while (bin.length < length)
bin += '0'
end
end
return bin
end
def padding_on_the_left(bin, length)
if (bin.length < length):
while (bin.length < length)
bin = '0' + bin
end
end
return bin
end
def auto_padding_on_the_left(bin)
exp = 1
until bin.length <= exp
exp *= 2
end
until bin.length % exp == 0
bin = '0' + bin
end
return bin
end
def cut(bin, length=@length_of_each_block)
if bin.length > length:
bin = bin[(bin.length - length), length]
end
return bin
end
def compression(bin1, bin2)
int1 = bin1.to_i(2)
int2 = bin2.to_i(2)
bin = (int1 ^ int2).to_s(2)
bin = padding_on_the_left(bin, bin1.length)
return bin
end
def avalanche(bin)
length = bin.length
int = bin.to_i(2)
int += int << 1
bin = cut(int.to_s(2), length)
bin = padding_on_the_left(bin, length)
return bin
end
def substr_1(bin)
bin[0, (bin.length / 2)]
end
def substr_2(bin)
bin[(bin.length / 2), (bin.length)]
end
def make(hash)
hash = padding_on_the_left( hash, 2 * @length_of_each_block )
hash = auto_padding_on_the_left( hash )
hash = compression( avalanche(substr_1(hash)),
avalanche(substr_2(hash)).reverse )
if auto_padding_on_the_left(hash).length != @length_of_each_block:
make(hash)
else
return hash.to_i(2).to_s(16)
end
end
def publish(message='Message', type='str')
message = str2bin( message.to_s ) if type != 'bin'
hash = make( message )
print hash
end
end
my_hash = Crypsh.new(128)
my_hash.publish(ARGV[0], ARGV[1])
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
=begin
* A Ruby implementation of Crypsh (CRYPtographic haSH)
* Copyright (c) 2008 Cyril Kato
* Code licensed under the BSD License:
http://www.opensource.org/licenses/bsd-license.php
* version: 0.1
=end
class Crypsh
require '../library/64sbox_6x4-1'
require '../library/binary_methods-0.1'
include BinaryMethods
def initialize(message='The quick brown fox jumps over the lazy dog')
message = str2bin(message)
message = length_padding(message)
@hash = construction(message, '10' * (128 / 2))
end
public
def digest
@hash
end
def hexdigest
@hash.to_i(2).to_s(16)
end
private
def length_padding(message)
message += '1'
message += '0' until message.length % (128 * 4) == 0
message
end
def construction(message, iv)
image = iv
block = message.scan(/([01]{1,128})/)
block.length.times do |id|
preimage = image
pleintext = padding_block( cut((block[id].to_s.to_i(2) + id).to_s(2), 128), 128)
image = compression(pleintext, preimage)
end
image
end
def compression(block, preimage)
xor(e(block, g(preimage)), block, preimage)
end
def xor(bin_a, bin_b, bin_c='0')
int_a = bin_a.to_i(2)
int_b = bin_b.to_i(2)
int_c = bin_c.to_i(2)
padding_block( (int_a ^ int_b ^ int_c).to_s(2), bin_a.length )
end
def g(preimage)
keycipher = circular_shift_left(preimage.to_i(2), 128, 1).to_s(2)
padding_block(keycipher, 128)
end
def e(blocktext, keycipher)
16.times do
blocktext = circular_shift_left(blocktext.to_i(2), 128, 8 / 2).to_s(2)
blocktext = padding_block(blocktext, 128)
blocktext = round(blocktext, keycipher)
end
padding_block(blocktext, 128)
end
def round(blocktext, keycipher)
sub_msg = blocktext.scan(/([01]{1,8})/)
sub_key = keycipher.scan(/([01]{1,8})/)
ciphertext = ''
16.times { |i| ciphertext += feistel_cipher(i, sub_msg[i].to_s, sub_key[i].to_s) }
ciphertext
end
def feistel_cipher(id, plaintext, keycipher)
a = plaintext[0 * 4, 4]
b = plaintext[1 * 4, 4]
4.times do |i|
a = tuple(i + (id * 4), a, b + keycipher[i * 2, 2])
a, b = b, a
end
a + b
end
def tuple(id, a, input)
output = sbox(id, input)
xor(a, output)
end
def sbox(id, input)
row = (input[0, 1] + input[6 - 1, 1]).to_i(2)
col = input[1, 4].to_i(2)
SBOX[id][row][col].to_s(2)
end
VERSION = 0.1
end
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
=begin
* A Ruby implementation of Crypsh (CRYPtographic haSH)
* Copyright (c) 2008 Cyril Kato
* Code licensed under the BSD License:
http://www.opensource.org/licenses/bsd-license.php
* version: 0.2
=end
class Crypsh
require '../library/64sbox_6x4-1'
require '../library/binary_methods-0.2'
include BinaryMethods
def initialize(message='The quick brown fox jumps over the lazy dog')
message = str2bin(message)
message = length_padding(message)
@hash = construction(message, '10' * (BLOCKSIZE / 2))
end
public
def digest
@hash
end
def hexdigest
@hash.to_i(2).to_s(16)
end
private
def length_padding(message)
message += '1'
message += '0' until message.length % (BLOCKSIZE * BLOCK_OF_SBOX) == 0
message
end
# Merkle Damgard construction
def construction(message, iv)
image = iv
block = message.scan(/([01]{1,#{BLOCKSIZE}})/)
block.length.times do |id|
preimage = image
pleintext = padding_block( cut((block[id].to_s.to_i(2) + id).to_s(2), BLOCKSIZE), BLOCKSIZE)
image = compression(pleintext, preimage)
end
image
end
# Miyaguchi Preneel compression
def compression(block, preimage)
xor(e(block, g(preimage)), block, preimage)
end
def xor(bin_a, bin_b, bin_c='0')
int_a = bin_a.to_i(2)
int_b = bin_b.to_i(2)
int_c = bin_c.to_i(2)
padding_block( (int_a ^ int_b ^ int_c).to_s(2), bin_a.length )
end
def g(preimage)
keycipher = circular_shift_left(preimage.to_i(2), BLOCKSIZE, 1).to_s(2)
padding_block(keycipher, BLOCKSIZE)
end
def e(blocktext, keycipher)
NB_FEISTELNETWORK.times do
blocktext = circular_shift_left(blocktext.to_i(2), BLOCKSIZE, FEISTELNETWORK / 2).to_s(2)
blocktext = padding_block(blocktext, BLOCKSIZE)
blocktext = round(blocktext, keycipher)
end
padding_block(blocktext, BLOCKSIZE)
end
def round(blocktext, keycipher)
sub_msg = blocktext.scan(/([01]{1,#{FEISTELNETWORK}})/)
sub_key = keycipher.scan(/([01]{1,#{FEISTELNETWORK}})/)
ciphertext = ''
NB_FEISTELNETWORK.times { |i| ciphertext += feistel_cipher(i, sub_msg[i].to_s, sub_key[i].to_s) }
ciphertext
end
def feistel_cipher(id, plaintext, keycipher)
a = plaintext[0 * BLOCK_OF_SBOX, BLOCK_OF_SBOX]
b = plaintext[1 * BLOCK_OF_SBOX, BLOCK_OF_SBOX]
NB_SBOX_BY_FEISTELNETWORK.times do |i|
a = tuple(i + (id * NB_SBOX_BY_FEISTELNETWORK), a, b + keycipher[i * KEY_OF_SBOX, KEY_OF_SBOX])
a, b = b, a
end
a + b
end
def tuple(id, a, input)
output = sbox(id, input)
xor(a, output)
end
def sbox(id, input)
# row take the first and the last(s) bit(s) of input
row = (input[0, 1] + input[INPUT_BY_SBOX - 1, 1]).to_i(2)
#row = input[0, ROW_BY_SBOX].to_i(2)
# col take some bits from the second bit of input
col = input[1, OUTPUT_BY_SBOX].to_i(2)
#col = input[ROW_BY_SBOX, OUTPUT_BY_SBOX].to_i(2)
SBOX[id][row][col].to_s(2)
end
#
# length of main blocks
# unit: bit
# minimum: FEISTELNETWORK (because BLOCKSIZE need to be >= FEISTELNETWORK)
# BLOCKSIZE
#
BLOCKSIZE = 128
#
# size of s-box block
# unit: bit
# default value: 4
#
BLOCK_OF_SBOX = 4
#
# size of Feistel network block
# unit: bit
# default value: 2 * BLOCK_OF_SBOX
#
FEISTELNETWORK = 2 * BLOCK_OF_SBOX
#
# size of all s-box key
# unit: bit
# default value: FEISTELNETWORK / 4
#
KEY_OF_SBOX = FEISTELNETWORK / 4
#
# nb of s-box by Feistel network
# unit: bit
#
NB_SBOX_BY_FEISTELNETWORK = FEISTELNETWORK / KEY_OF_SBOX
#
# nb of Feistel network
# unit: bit
#
NB_FEISTELNETWORK = BLOCKSIZE / FEISTELNETWORK
#
# nb of s-box
# unit: bit
#
NB_SBOX = NB_SBOX_BY_FEISTELNETWORK * NB_FEISTELNETWORK
OUTPUT_BY_SBOX = BLOCK_OF_SBOX
INPUT_BY_SBOX = OUTPUT_BY_SBOX + KEY_OF_SBOX
ROW_BY_SBOX = INPUT_BY_SBOX - OUTPUT_BY_SBOX
COL_BY_SBOX = OUTPUT_BY_SBOX
VERSION = 0.2
end
=begin
* A Ruby implementation of Crypsh (CRYPtographic haSH)
* Copyright (c) 2008 Cyril Kato
* Code licensed under the BSD License:
http://www.opensource.org/licenses/bsd-license.php
* version: 0.2
=end
class Crypsh
require '../library/64sbox_6x4-1'
require '../library/binary_methods-0.2'
include BinaryMethods
def initialize(message='The quick brown fox jumps over the lazy dog')
message = str2bin(message)
message = length_padding(message)
@hash = construction(message, '10' * (128 / 2))
end
public
def digest
@hash
end
def hexdigest
@hash.to_i(2).to_s(16)
end
private
def length_padding(message)
message += '1'
message += '0' until message.length % (128 * 4) == 0
message
end
def construction(message, iv)
image = iv
block = message.scan(/([01]{1,128})/)
block.length.times do |id|
preimage = image
pleintext = padding_block( cut((block[id].to_s.to_i(2) + id).to_s(2), 128), 128)
image = compression(pleintext, preimage)
end
image
end
def compression(block, preimage)
xor(e(block, g(preimage)), block, preimage)
end
def xor(bin_a, bin_b, bin_c='0')
int_a = bin_a.to_i(2)
int_b = bin_b.to_i(2)
int_c = bin_c.to_i(2)
padding_block( (int_a ^ int_b ^ int_c).to_s(2), bin_a.length )
end
def g(preimage)
keycipher = circular_shift_left(preimage.to_i(2), 128, 1).to_s(2)
padding_block(keycipher, 128)
end
def e(blocktext, keycipher)
16.times do
blocktext = circular_shift_left(blocktext.to_i(2), 128, 8 / 2).to_s(2)
blocktext = padding_block(blocktext, 128)
blocktext = round(blocktext, keycipher)
end
padding_block(blocktext, 128)
end
def round(blocktext, keycipher)
sub_msg = blocktext.scan(/([01]{1,8})/)
sub_key = keycipher.scan(/([01]{1,8})/)
ciphertext = ''
16.times { |i| ciphertext += feistel_cipher(i, sub_msg[i].to_s, sub_key[i].to_s) }
ciphertext
end
def feistel_cipher(id, plaintext, keycipher)
a = plaintext[0 * 4, 4]
b = plaintext[1 * 4, 4]
4.times do |i|
a = tuple(i + (id * 4), a, b + keycipher[i * 2, 2])
a, b = b, a
end
a + b
end
def tuple(id, a, input)
output = sbox(id, input)
xor(a, output)
end
def sbox(id, input)
row = (input[0, 1] + input[6 - 1, 1]).to_i(2)
col = input[1, 4].to_i(2)
SBOX[id][row][col].to_s(2)
end
VERSION = 0.2
end
=begin
nb of digit: 32 801
=end
PI = '3' +
'1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679' +
'8214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196' +
'4428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273' +
'7245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094' +
'3305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912' +
'9833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132' +
'0005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235' +
'4201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859' +
'5024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303' +
'5982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989' +
'3809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151' +
'5574857242454150695950829533116861727855889075098381754637464939319255060400927701671139009848824012' +
'8583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912' +
'9331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279' +
'6782354781636009341721641219924586315030286182974555706749838505494588586926995690927210797509302955' +
'3211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000' +
'8164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333' +
'4547762416862518983569485562099219222184272550254256887671790494601653466804988627232791786085784383' +
'8279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863' +
'0674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802759009' +
'9465764078951269468398352595709825822620522489407726719478268482601476990902640136394437455305068203' +
'4962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382' +
'6868386894277415599185592524595395943104997252468084598727364469584865383673622262609912460805124388' +
'4390451244136549762780797715691435997700129616089441694868555848406353422072225828488648158456028506' +
'0168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125' +
'1507606947945109659609402522887971089314566913686722874894056010150330861792868092087476091782493858' +
'9009714909675985261365549781893129784821682998948722658804857564014270477555132379641451523746234364' +
'5428584447952658678210511413547357395231134271661021359695362314429524849371871101457654035902799344' +
'0374200731057853906219838744780847848968332144571386875194350643021845319104848100537061468067491927' +
'8191197939952061419663428754440643745123718192179998391015919561814675142691239748940907186494231961' +
'5679452080951465502252316038819301420937621378559566389377870830390697920773467221825625996615014215' +
'0306803844773454920260541466592520149744285073251866600213243408819071048633173464965145390579626856' +
'1005508106658796998163574736384052571459102897064140110971206280439039759515677157700420337869936007' +
'2305587631763594218731251471205329281918261861258673215791984148488291644706095752706957220917567116' +
'7229109816909152801735067127485832228718352093539657251210835791513698820914442100675103346711031412' +
'6711136990865851639831501970165151168517143765761835155650884909989859982387345528331635507647918535' +
'8932261854896321329330898570642046752590709154814165498594616371802709819943099244889575712828905923' +
'2332609729971208443357326548938239119325974636673058360414281388303203824903758985243744170291327656' +
'1809377344403070746921120191302033038019762110110044929321516084244485963766983895228684783123552658' +
'2131449576857262433441893039686426243410773226978028073189154411010446823252716201052652272111660396' +
'6655730925471105578537634668206531098965269186205647693125705863566201855810072936065987648611791045' +
'3348850346113657686753249441668039626579787718556084552965412665408530614344431858676975145661406800' +
'7002378776591344017127494704205622305389945613140711270004078547332699390814546646458807972708266830' +
'6343285878569830523580893306575740679545716377525420211495576158140025012622859413021647155097925923' +
'0990796547376125517656751357517829666454779174501129961489030463994713296210734043751895735961458901' +
'9389713111790429782856475032031986915140287080859904801094121472213179476477726224142548545403321571' +
'8530614228813758504306332175182979866223717215916077166925474873898665494945011465406284336639379003' +
'9769265672146385306736096571209180763832716641627488880078692560290228472104031721186082041900042296' +
'6171196377921337575114959501566049631862947265473642523081770367515906735023507283540567040386743513' +
'6222247715891504953098444893330963408780769325993978054193414473774418426312986080998886874132604721' +
'5695162396586457302163159819319516735381297416772947867242292465436680098067692823828068996400482435' +
'4037014163149658979409243237896907069779422362508221688957383798623001593776471651228935786015881617' +
'5578297352334460428151262720373431465319777741603199066554187639792933441952154134189948544473456738' +
'3162499341913181480927777103863877343177207545654532207770921201905166096280490926360197598828161332' +
'3166636528619326686336062735676303544776280350450777235547105859548702790814356240145171806246436267' +
'9456127531813407833033625423278394497538243720583531147711992606381334677687969597030983391307710987' +
'0408591337464144282277263465947047458784778720192771528073176790770715721344473060570073349243693113' +
'8350493163128404251219256517980694113528013147013047816437885185290928545201165839341965621349143415' +
'9562586586557055269049652098580338507224264829397285847831630577775606888764462482468579260395352773' +
'4803048029005876075825104747091643961362676044925627420420832085661190625454337213153595845068772460' +
'2901618766795240616342522577195429162991930645537799140373404328752628889639958794757291746426357455' +
'2540790914513571113694109119393251910760208252026187985318877058429725916778131496990090192116971737' +
'2784768472686084900337702424291651300500516832336435038951702989392233451722013812806965011784408745' +
'1960121228599371623130171144484640903890644954440061986907548516026327505298349187407866808818338510' +
'2283345085048608250393021332197155184306354550076682829493041377655279397517546139539846833936383047' +
'4611996653858153842056853386218672523340283087112328278921250771262946322956398989893582116745627010' +
'2183564622013496715188190973038119800497340723961036854066431939509790190699639552453005450580685501' +
'9567302292191393391856803449039820595510022635353619204199474553859381023439554495977837790237421617' +
'2711172364343543947822181852862408514006660443325888569867054315470696574745855033232334210730154594' +
'0516553790686627333799585115625784322988273723198987571415957811196358330059408730681216028764962867' +
'4460477464915995054973742562690104903778198683593814657412680492564879855614537234786733039046883834' +
'3634655379498641927056387293174872332083760112302991136793862708943879936201629515413371424892830722' +
'0126901475466847653576164773794675200490757155527819653621323926406160136358155907422020203187277605' +
'2772190055614842555187925303435139844253223415762336106425063904975008656271095359194658975141310348' +
'2276930624743536325691607815478181152843667957061108615331504452127473924544945423682886061340841486' +
'3776700961207151249140430272538607648236341433462351897576645216413767969031495019108575984423919862' +
'9164219399490723623464684411739403265918404437805133389452574239950829659122850855582157250310712570' +
'1266830240292952522011872676756220415420516184163484756516999811614101002996078386909291603028840026' +
'9104140792886215078424516709087000699282120660418371806535567252532567532861291042487761825829765157' +
'9598470356222629348600341587229805349896502262917487882027342092222453398562647669149055628425039127' +
'5771028402799806636582548892648802545661017296702664076559042909945681506526530537182941270336931378' +
'5178609040708667114965583434347693385781711386455873678123014587687126603489139095620099393610310291' +
'6161528813843790990423174733639480457593149314052976347574811935670911013775172100803155902485309066' +
'9203767192203322909433467685142214477379393751703443661991040337511173547191855046449026365512816228' +
'8244625759163330391072253837421821408835086573917715096828874782656995995744906617583441375223970968' +
'3408005355984917541738188399944697486762655165827658483588453142775687900290951702835297163445621296' +
'4043523117600665101241200659755851276178583829204197484423608007193045761893234922927965019875187212' +
'7267507981255470958904556357921221033346697499235630254947802490114195212382815309114079073860251522' +
'7429958180724716259166854513331239480494707911915326734302824418604142636395480004480026704962482017' +
'9289647669758318327131425170296923488962766844032326092752496035799646925650493681836090032380929345' +
'9588970695365349406034021665443755890045632882250545255640564482465151875471196218443965825337543885' +
'6909411303150952617937800297412076651479394259029896959469955657612186561967337862362561252163208628' +
'6922210327488921865436480229678070576561514463204692790682120738837781423356282360896320806822246801' +
'2248261177185896381409183903673672220888321513755600372798394004152970028783076670944474560134556417' +
'2543709069793961225714298946715435784687886144458123145935719849225284716050492212424701412147805734' +
'5510500801908699603302763478708108175450119307141223390866393833952942578690507643100638351983438934' +
'1596131854347546495569781038293097164651438407007073604112373599843452251610507027056235266012764848' +
'3084076118301305279320542746286540360367453286510570658748822569815793678976697422057505968344086973' +
'5020141020672358502007245225632651341055924019027421624843914035998953539459094407046912091409387001' +
'2645600162374288021092764579310657922955249887275846101264836999892256959688159205600101655256375678' +
'5667227966198857827948488558343975187445455129656344348039664205579829368043522027709842942325330225' +
'7634180703947699415979159453006975214829336655566156787364005366656416547321704390352132954352916941' +
'4599041608753201868379370234888689479151071637852902345292440773659495630510074210871426134974595615' +
'1384987137570471017879573104229690666702144986374645952808243694457897723300487647652413390759204340' +
'1963403911473202338071509522201068256342747164602433544005152126693249341967397704159568375355516673' +
'0273900749729736354964533288869844061196496162773449518273695588220757355176651589855190986665393549' +
'4810688732068599075407923424023009259007017319603622547564789406475483466477604114632339056513433068' +
'4495397907090302346046147096169688688501408347040546074295869913829668246818571031887906528703665083' +
'2431974404771855678934823089431068287027228097362480939962706074726455399253994428081137369433887294' +
'0630792615959954626246297070625948455690347119729964090894180595343932512362355081349490043642785271' +
'3831591256898929519642728757394691427253436694153236100453730488198551706594121735246258954873016760' +
'0298865925786628561249665523533829428785425340483083307016537228563559152534784459818313411290019992' +
'0598135220511733658564078264849427644113763938669248031183644536985891754426473998822846218449008777' +
'6977631279572267265556259628254276531830013407092233436577916012809317940171859859993384923549564005' +
'7099558561134980252499066984233017350358044081168552653117099570899427328709258487894436460050410892' +
'2669178352587078595129834417295351953788553457374260859029081765155780390594640873506123226112009373' +
'1080485485263572282576820341605048466277504500312620080079980492548534694146977516493270950493463938' +
'2432227188515974054702148289711177792376122578873477188196825462981268685817050740272550263329044976' +
'2778944236216741191862694396506715157795867564823993917604260176338704549901761436412046921823707648' +
'8783419689686118155815873606293860381017121585527266830082383404656475880405138080163363887421637140' +
'6435495561868964112282140753302655100424104896783528588290243670904887118190909494533144218287661810' +
'3100735477054981596807720094746961343609286148494178501718077930681085469000944589952794243981392135' +
'0558642219648349151263901280383200109773868066287792397180146134324457264009737425700735921003154150' +
'8936793008169980536520276007277496745840028362405346037263416554259027601834840306811381855105979705' +
'6640075094260878857357960373245141467867036880988060971642584975951380693094494015154222219432913021' +
'7391253835591503100333032511174915696917450271494331515588540392216409722910112903552181576282328318' +
'2342548326111912800928252561902052630163911477247331485739107775874425387611746578671169414776421441' +
'1112635835538713610110232679877564102468240322648346417663698066378576813492045302240819727856471983' +
'9630878154322116691224641591177673225326433568614618654522268126887268445968442416107854016768142080' +
'8850280054143613146230821025941737562389942075713627516745731891894562835257044133543758575342698699' +
'4725470316566139919996826282472706413362221789239031760854289437339356188916512504244040089527198378' +
'7386480584726895462438823437517885201439560057104811949884239060613695734231559079670346149143447886' +
'3604103182350736502778590897578272731305048893989009923913503373250855982655867089242612429473670193' +
'9077271307068691709264625484232407485503660801360466895118400936686095463250021458529309500009071510' +
'5823626729326453738210493872499669933942468551648326113414611068026744663733437534076429402668297386' +
'5220935701626384648528514903629320199199688285171839536691345222444708045923966028171565515656661113' +
'5982311225062890585491450971575539002439315351909021071194573002438801766150352708626025378817975194' +
'7806101371500448991721002220133501310601639154158957803711779277522597874289191791552241718958536168' +
'0594741234193398420218745649256443462392531953135103311476394911995072858430658361935369329699289837' +
'9149419394060857248639688369032655643642166442576079147108699843157337496488352927693282207629472823' +
'8153740996154559879825989109371712621828302584811238901196822142945766758071865380650648702613389282' +
'2994972574530332838963818439447707794022843598834100358385423897354243956475556840952248445541392394' +
'1000162076936368467764130178196593799715574685419463348937484391297423914336593604100352343777065888' +
'6778113949861647874714079326385873862473288964564359877466763847946650407411182565837887845485814896' +
'2961273998413442726086061872455452360643153710112746809778704464094758280348769758948328241239292960' +
'5829486191966709189580898332012103184303401284951162035342801441276172858302435598300320420245120728' +
'7253558119584014918096925339507577840006746552603144616705082768277222353419110263416315714740612385' +
'0425845988419907611287258059113935689601431668283176323567325417073420817332230462987992804908514094' +
'7903688786878949305469557030726190095020764334933591060245450864536289354568629585313153371838682656' +
'1786227363716975774183023986006591481616404944965011732131389574706208847480236537103115089842799275' +
'4426853277974311395143574172219759799359685252285745263796289612691572357986620573408375766873884266' +
'4059909935050008133754324546359675048442352848747014435454195762584735642161981340734685411176688311' +
'8654489377697956651727966232671481033864391375186594673002443450054499539974237232871249483470604406' +
'3471606325830649829795510109541836235030309453097335834462839476304775645015008507578949548931393944' +
'8992161255255977014368589435858775263796255970816776438001254365023714127834679261019955852247172201' +
'7772370041780841942394872540680155603599839054898572354674564239058585021671903139526294455439131663' +
'1345308939062046784387785054239390524731362012947691874975191011472315289326772533918146607300089027' +
'7689631148109022097245207591672970078505807171863810549679731001678708506942070922329080703832634534' +
'5203802786099055690013413718236837099194951648960075504934126787643674638490206396401976668559233565' +
'4639138363185745698147196210841080961884605456039038455343729141446513474940784884423772175154334260' +
'3066988317683310011331086904219390310801437843341513709243530136776310849135161564226984750743032971' +
'6746964066653152703532546711266752246055119958183196376370761799191920357958200759560530234626775794' +
'3936307463056901080114942714100939136913810725813781357894005599500183542511841721360557275221035268' +
'0373572652792241737360575112788721819084490061780138897107708229310027976659358387589093956881485602' +
'6322439372656247277603789081445883785501970284377936240782505270487581647032458129087839523245323789' +
'6029841669225489649715606981192186584926770403956481278102179913217416305810554598801300484562997651' +
'1212415363745150056350701278159267142413421033015661653560247338078430286552572227530499988370153487' +
'9300806260180962381516136690334111138653851091936739383522934588832255088706450753947395204396807906' +
'7086806445096986548801682874343786126453815834280753061845485903798217994599681154419742536344399602' +
'9025100158882721647450068207041937615845471231834600726293395505482395571372568402322682130124767945' +
'2264482091023564775272308208106351889915269288910845557112660396503439789627825001611015323516051965' +
'5904211844949907789992007329476905868577878720982901352956613978884860509786085957017731298155314951' +
'6814671769597609942100361835591387778176984587581044662839988060061622984861693533738657877359833616' +
'1338413385368421197893890018529569196780455448285848370117096721253533875862158231013310387766827211' +
'5726949518179589754693992642197915523385766231676275475703546994148929041301863861194391962838870543' +
'6777432242768091323654494853667680000010652624854730558615989991401707698385483188750142938908995068' +
'5453076511680333732226517566220752695179144225280816517166776672793035485154204023817460892328391703' +
'2754257508676551178593950027933895920576682789677644531840404185540104351348389531201326378369283580' +
'8271937831265496174599705674507183320650345566440344904536275600112501843356073612227659492783937064' +
'7842645676338818807565612168960504161139039063960162022153684941092605387688714837989559999112099164' +
'6464411918568277004574243434021672276445589330127781586869525069499364610175685060167145354315814801' +
'0545886056455013320375864548584032402987170934809105562116715468484778039447569798042631809917564228' +
'0987399876697323769573701580806822904599212366168902596273043067931653114940176473769387351409336183' +
'3216142802149763399189835484875625298752423873077559555955465196394401821840998412489826236737714672' +
'2606163364329640633572810707887581640438148501884114318859882769449011932129682715888413386943468285' +
'9006664080631407775772570563072940049294030242049841656547973670548558044586572022763784046682337985' +
'2827105784319753541795011347273625774080213476826045022851579795797647467022840999561601569108903845' +
'8245026792659420555039587922981852648007068376504183656209455543461351341525700659748819163413595567' +
'1964965403218727160264859304903978748958906612725079482827693895352175362185079629778514618843271922' +
'3223810158744450528665238022532843891375273845892384422535472653098171578447834215822327020690287232' +
'3300538621634798850946954720047952311201504329322662827276321779088400878614802214753765781058197022' +
'2630971749507212724847947816957296142365859578209083073323356034846531873029302665964501371837542889' +
'7557971449924654038681799213893469244741985097334626793321072686870768062639919361965044099542167627' +
'8409146698569257150743157407938053239252394775574415918458215625181921552337096074833292349210345146' +
'2643744980559610330799414534778457469999212859999939961228161521931488876938802228108300198601654941' +
'6542616968586788372609587745676182507275992950893180521872924610867639958916145855058397274209809097' +
'8172932393010676638682404011130402470073508578287246271349463685318154696904669686939254725194139929' +
'1465242385776255004748529547681479546700705034799958886769501612497228204030399546327883069597624936' +
'1510102436555352230690612949388599015734661023712235478911292547696176005047974928060721268039226911' +
'0277722610254414922157650450812067717357120271802429681062037765788371669091094180744878140490755178' +
'2038565390991047759414132154328440625030180275716965082096427348414695726397884256008453121406593580' +
'9041271135920041975985136254796160632288736181367373244506079244117639975974619383584574915988097667' +
'4470930065463424234606342374746660804317012600520559284936959414340814685298150539471789004518357551' +
'5412522359059068726487863575254191128887737176637486027660634960353679470269232297186832771739323619' +
'2007774522126247518698334951510198642698878471719396649769070825217423365662725928440620430214113719' +
'9227852699846988477023238238400556555178890876613601304770984386116870523105531491625172837327286760' +
'0724817298763756981633541507460883866364069347043720668865127568826614973078865701568501691864748854' +
'1679154596507234287730699853713904300266530783987763850323818215535597323530686043010675760838908627' +
'0498418885951380910304235957824951439885901131858358406674723702971497850841458530857813391562707603' +
'5639076394731145549583226694570249413983163433237897595568085683629725386791327505554252449194358912' +
'8405045226953812179131914513500993846311774017971512283785460116035955402864405902496466930707769055' +
'4810288502080858008781157738171917417760173307385547580060560143377432990127286772530431825197579167' +
'9296996504146070664571258883469797964293162296552016879730003564630457930884032748077181155533090988' +
'7025505207680463034608658165394876951960044084820659673794731680864156456505300498816164905788311543' +
'4548505266006982309315777650037807046612647060214575057932709620478256152471459189652236083966456241' +
'0519551052235723973951288181640597859142791481654263289200428160913693777372229998332708208296995573' +
'7727375667615527113922588055201898876201141680054687365580633471603734291703907986396522961312801782' +
'6797172898229360702880690877686605932527463784053976918480820410219447197138692560841624511239806201' +
'1318454124478205011079876071715568315407886543904121087303240201068534194723047666672174986986854707' +
'6781205124736792479193150856444775379853799732234456122785843296846647513336573692387201464723679427' +
'8700425032555899268843495928761240075587569464137056251400117971331662071537154360068764773186755871' +
'4878398908107429530941060596944315847753970094398839491443235366853920994687964506653398573888786614' +
'7629443414010498889931600512076781035886116602029611936396821349607501116498327856353161451684576956' +
'8710900299976984126326650234771672865737857908574664607722834154031144152941880478254387617707904300' +
'0156698677679576090996693607559496515273634981189641304331166277471233881740603731743970540670310967' +
'6765748695358789670031925866259410510533584384656023391796749267844763708474978333655579007384191473' +
'1988627135259546251816043422537299628632674968240580602964211463864368642247248872834341704415734824' +
'8183330164056695966886676956349141632842641497453334999948000266998758881593507357815195889900539512' +
'0853510357261373640343675347141048360175464883004078464167452167371904831096767113443494819262681110' +
'7399482506073949507350316901973185211955263563258433909982249862406703107683184466072912487475403161' +
'7969941139738776589986855417031884778867592902607004321266617919223520938227878880988633599116081923' +
'5355570464634911320859189796132791319756490976000139962344455350143464268604644958624769094347048293' +
'2941404111465409239883444351591332010773944111840741076849810663472410482393582740194493566516108846' +
'3125678529776973468430306146241803585293315973458303845541033701091676776374276210213701354854450926' +
'3071901147318485749233181672072137279355679528443925481560913728128406333039373562420016045664557414' +
'5881660521666087387480472433912129558777639069690370788285277538940524607584962315743691711317613478' +
'3882719416860662572103685132156647800147675231039357860689611125996028183930954870905907386135191459' +
'1819510297327875571049729011487171897180046961697770017913919613791417162707018958469214343696762927' +
'4591099400600849835684252019155937037010110497473394938778859894174330317853487076032219829705797511' +
'9144051099423588303454635349234982688362404332726741554030161950568065418093940998202060999414021689' +
'0900708213307230896621197755306659188141191577836272927461561857103721724710095214236964830864102592' +
'8874579993223749551912219519034244523075351338068568073544649951272031744871954039761073080602699062' +
'5807602029273145525207807991418429063884437349968145827337207266391767020118300464819000241308350884' +
'6584152148991276106513741539435657211390328574918769094413702090517031487773461652879848235338297260' +
'1361109845148418238081205409961252745808810994869722161285248974255555160763716750548961730168096138' +
'0381191436114399210638005083214098760459930932485102516829446726066613815174571255975495358023998314' +
'6982203613380828499356705575524712902745397762140493182014658008021566536067765508783804304134310591' +
'8046068008345911366408348874080057412725867047922583191274157390809143831384564241509408491339180968' +
'4025116399193685322555733896695374902662092326131885589158083245557194845387562878612885900410600607' +
'3746501402627824027346962528217174941582331749239683530136178653673760642166778137739951006589528877' +
'4276626368418306801908046098498094697636673356622829151323527888061577682781595886691802389403330764' +
'4191240341202231636857786035727694154177882643523813190502808701857504704631293335375728538660588890' +
'4583111450773942935201994321971171642235005644042979892081594307167019857469273848653833436145794634' +
'1759225738985880016980147574205429958012429581054565108310462972829375841611625325625165724980784920' +
'9989799062003593650993472158296517413579849104711166079158743698654122234834188772292944633517865385' +
'6731962559852026072947674072616767145573649812105677716893484917660771705277187601199908144113058645' +
'5779105256843048114402619384023224709392498029335507318458903553971330884461741079591625117148648744' +
'6861124760542867343670904667846867027409188101424971114965781772427934707021668829561087779440504843' +
'7528443375108828264771978540006509704033021862556147332117771174413350281608840351781452541964320309' +
'5760186946490886815452856213469883554445602495566684366029221951248309106053772019802183101032704178' +
'3866544718126039719068846237085751808003532704718565949947612424811099928867915896904956394762460842' +
'4065930948621507690314987020673533848349550836366017848771060809804269247132410009464014373603265645' +
'1845667924566695510015022983307984960799498824970617236744936122622296179081431141466094123415935930' +
'9585407913908720832273354957208075716517187659944985693795623875551617575438091780528029464200447215' +
'3962807463602113294255916002570735628126387331060058910652457080244749375431841494014821199962764531' +
'0680066311838237616396631809314446712986155275982014514102756006892975024630401735148919457636078935' +
'2855505317331416457050499644389093630843874484783961684051845273288403234520247056851646571647713932' +
'3775517294795126132398229602394548579754586517458787713318138752959809412174227300352296508089177705' +
'0682592488223221549380483714547816472139768209633205083056479204820859204754998573203888763916019952' +
'4091893894557676874973085695595801065952650303626615975066222508406742889826590751063756356996821151' +
'0949669744580547288693631020367823250182323708459790111548472087618212477813266330412076216587312970' +
'8112307581598212486398072124078688781145016558251361789030708608701989758898074566439551574153631931' +
'9198107057533663373803827215279884935039748001589051942087971130805123393322190346624991716915094854' +
'1401871060354603794643379005890957721180804465743962806186717861017156740967662080295766577051291209' +
'9079443046328929473061595104309022214393718495606340561893425130572682914657832933405246350289291754' +
'7087256484260034962961165413823007731332729830500160256724014185152041890701154288579920812198449315' +
'6999059182011819733500126187728036812481995877070207532406361259313438595542547781961142935163561223' +
'4966615226147353996740515849986035529533292457523888101362023476246690558164389678630976273655047243' +
'4864307121849437348530060638764456627218666170123812771562137974614986132874411771455244470899714452' +
'2885662942440230184791205478498574521634696448973892062401943518310088283480249249085403077863875165' +
'9113028739587870981007727182718745290139728366148421428717055317965430765045343246005363614726181809' +
'6997693348626407743519992868632383508875668359509726557481543194019557685043724800102041374983187225' +
'9677387154958399718444907279141965845930083942637020875635398216962055324803212267498911402678528599' +
'6734052420310917978999057188219493913207534317079800237365909853755202389116434671855829068537118979' +
'5262623449248339249634244971465684659124891855662958932990903523923333364743520370770101084388003290' +
'7598342170185542283861617210417603011645918780539367447472059985023582891833692922337323999480437108' +
'4196594731626548257480994825099918330069765693671596893644933488647442135008407006608835972350395323' +
'4017958255703601693699098867113210979889707051728075585519126993067309925070407024556850778679069476' +
'6126298082251633136399521170984528092630375922426742575599892892783704744452189363203489415521044597' +
'2618838003006776179313813991620580627016510244588692476492468919246121253102757313908404700071435613' +
'6231699237169484813255420091453041037135453296620639210547982439212517254013231490274058589206321758' +
'9494345489068463993137570910346332714153162232805522972979538018801628590735729554162788676498274186' +
'1642187898857410716490691918511628152854867941736389066538857642291583425006736124538491606741373401' +
'7357277995634104332688356950781493137800736235418007061918026732855119194267609122103598746924117283' +
'7493126163395001239599240508454375698507957046222664619000103500490183034153545842833764378111988556' +
'3187777925372011667185395418359844383052037628194407615941068207169703022851522505731260930468984234' +
'3315273213136121658280807521263154773060442377475350595228717440266638914881717308643611138906942027' +
'9088143119448799417154042103412190847094080254023932942945493878640230512927119097513536000921971105' +
'4120966831115163287054230284700731206580326264171161659576132723515666625366727189985341998952368848' +
'3099930275741991646384142707798870887422927705389122717248632202889842512528721782603050099451082478' +
'3572905691988555467886079462805371227042466543192145281760741482403827835829719301017888345674167811' +
'3989547504483393146896307633966572267270433932167454218245570625247972199786685427989779923395790575' +
'8189062252547358220523642485078340711014498047872669199018643882293230538231855973286978092225352959' +
'1017341407334884761005564018242392192695062083183814546983923664613639891012102177095976704908305081' +
'8547041946643713122996923588953849301363565761861060622287055994233716310212784574464639897381885667' +
'4626087948201864748767272722206267646533809980196688368099415907577685263986514625333631245053640261' +
'0569605513183813174261184420189088853196356986962795036738424313011331753305329802016688817481342988' +
'6815855778103432317530647849832106297184251843855344276201282345707169885305183261796411785796088881' +
'5032960229070561447622091509473903594664691623539680920139457817589108893199211226007392814916948161' +
'5273842736264298098234063200244024495894456129167049508235812487391799648641133480324757775219708932' +
'7722623494860150466526814398770516153170266969297049283162855042128981467061953319702695072143782304' +
'7687528028735412616639170824592517001071418085480063692325946201900227808740985977192180515853214739' +
'2653251559035410209284665925299914353791825314545290598415817637058927906909896911164381187809435371' +
'5213322614436253144901274547726957393934815469163116249288735747188240715039950094467319543161938554' +
'8520766573882513963916357672315100555603726339486720820780865373494244011579966750736071115935133195' +
'9197120948964717553024531364770942094635696982226673775209945168450643623824211853534887989395673187' +
'8066061078854400055082765703055874485418057788917192078814233511386629296671796434687600770479995378' +
'8338787034871802184243734211227394025571769081960309201824018842705704609262256417837526526335832424' +
'0661253311529423457965569502506810018310900411245379015332966156970522379210325706937051090830789479' +
'9990049993953221536227484766036136776979785673865846709366795885837887956259464648913766521995882869' +
'3380183601193236857855855819555604215625088365020332202451376215820461810670519533065306060650105488' +
'7167245377942831338871631395596905832083416898476065607118347136218123246227258841990286142087284956' +
'8796393254642853430753011052857138296437099903569488852851904029560473461311382638788975517885604249' +
'9874831638280404684861893818959054203988987265069762020199554841265000539442820393012748163815853039' +
'6439925470201672759328574366661644110962566337305409219519675148328734808957477775278344221091073111' +
'3518280460363471981856555729571447476825528578633493428584231187494400032296906977583159038580393535' +
'2135886007960034209754739229673331064939560181223781285458431760556173386112673478074585067606304822' +
'9409653041118306671081893031108871728167519579675347188537229309616143204006381322465841111157758358'
require 'pi.32801'
class SboxMaker
def initialize(input=256, output=input-2)
@input = input
@output = output
@sbox = Array.new((2**(@input - @output)) * 2**@output)
end
public
def init(constant, length=@input, prompt=0)
###########################################################################
# FOR EACH CASE, SAVE A CONSTANTS
#puts "#prompt: #{prompt}"
rows = 2**(@input - @output)
cols = 2**@output
box = Array.new(rows * cols)
(rows * cols).times do |id|
box[id] = constant[prompt, length]
collision = false
loop do
prompt += length
box.each do |this_case|
collision = true if this_case == constant[prompt, length]
end
break if collision === false
end
end
#puts "#prompt: #{prompt}"
###########################################################################
# FOR EACH LINE, BUILD A TABLE
#line_rand = Array.new
#line_sort = Array.new
row = Array.new(rows)
#col = Array.new(cols)
#indice = 0
rows.times do |id|
row[id] = box.slice( (id * cols), cols)
#line_sort[id] = line_rand[id].sort
#indice += 1
end
###########################################################################
# FOR EACH CONSTANT, SAVE A VALUE BETWEEN 0 AND @output
indice = 0
rows.times do |occur_line|
#puts "-> LIGNE n#{occur_line}:\n"
cpt = 0
id_value = 0
#(2**@output).times do |i|
rang = 0
row[occur_line].each do |i|
#i = column_i + (2**@output * occur_line)
#puts "\n\n FOCUS ON #{i}\n"
#(2**@output).times do |j|
pos = 0
row[occur_line].sort.each do |j|
#j = column_j + (2**@output * occur_line)
#print "\n IF j == #{j}? "
if i == j:
cpt = j
#puts "'#{cpt}'"
#@sbox[indice] = padding_block(cpt.to_s(2), @output)
#puts " OUI!\n"
#print " Enregistrement n#{indice}... "
@sbox[indice] = padding_block(pos.to_s(2), @output)
#print "Done! @sbox[#{indice}] = #{@sbox[indice].to_i(2)}"
indice += 1
id_value += 1
break
end
pos += 1
end
rang += 1
end
end
end
def display
id = 0
(2**(@input - @output)).times do |x|
print ' ' if x == 0
puts '['
(2**@output).times do |y|
print ' ' if (y == 0)
#i = x + y
#print '0b' + "#{@sbox[i]}, "
#print "'#{@sbox[i]}'"
#print "\n " if (y % 8 == 0)
#print "0x#{padding_block(@sbox[id].to_s.to_i(2).to_s(16), 2)}"
print @sbox[id].to_s.to_i(2).to_s
print ', ' if y != 2**@output - 1
print "\n" if y == 2**@output - 1
id += 1
end
print ' ]'
print ', ' if x != 2**(@input - @output) - 1
#print "\n"
end
end
private
def padding_block(str, length=@output)
if (str.length < length):
while (str.length < length)
str = '0' + str
end
end
return str
end
end
#
# length of main blocks
# unit: bit
# minimum: FEISTELNETWORK (because BLOCKSIZE need to be >= FEISTELNETWORK)
#
BLOCKSIZE = 128
#
# size of s-box block
# unit: bit
#
BLOCK_BY_SBOX = 4
#
# size of Feistel network block
# unit: bit
#
FEISTELNETWORK = 2 * BLOCK_BY_SBOX
#
# size of all s-box key
# unit: bit
#
KEY_BY_SBOX = FEISTELNETWORK / 4 # on choisit arbitrairement de diviser par 4
output = BLOCK_BY_SBOX
input = output + KEY_BY_SBOX
#
# nb of s-box by Feistel network
# unit: bit
#
NB_SBOX_BY_FEISTELNETWORK = FEISTELNETWORK / KEY_BY_SBOX
#
# nb of Feistel network
# unit: bit
#
NB_FEISTELNETWORK = BLOCKSIZE / FEISTELNETWORK
#
# nb of s-box
# unit: bit
#
NB_SBOX = NB_SBOX_BY_FEISTELNETWORK * NB_FEISTELNETWORK
sbox = SboxMaker.new(input, output)
constant = PI
length_of_constant = input
puts '=begin'
puts " BLOCKSIZE = #{BLOCKSIZE}"
puts " BLOCK_BY_SBOX = #{BLOCK_BY_SBOX}"
puts " FEISTELNETWORK = #{FEISTELNETWORK}"
puts " KEY_BY_SBOX = #{KEY_BY_SBOX}"
puts " NB_SBOX_BY_FEISTELNETWORK = #{NB_SBOX_BY_FEISTELNETWORK}"
puts " NB_FEISTELNETWORK = #{NB_FEISTELNETWORK}"
puts " NB_SBOX = #{NB_SBOX}"
puts " input = #{input}"
puts " output = #{output}"
puts " constant = #{constant[0..10]}..."
puts " constant length = #{length_of_constant}"
puts '=end'
nb_of_sbox = NB_SBOX
puts "\n"
puts '#'
puts "# Table of #{nb_of_sbox} s-boxes"
puts '# name: ' + "#{nb_of_sbox}" + 'sbox_' + "#{input}" + 'x' + "#{output}"
puts '#'
puts 'SBOX = ['
nb_of_sbox.times do |i|
print ' ' if i == 0
puts '['
prompt = i * (((2**output) * (2**(input - output))) * length_of_constant)
sbox.init(constant, length_of_constant, prompt)
sbox.display
print "\n" + ' ]'
print ', ' if i != (nb_of_sbox - 1)
print "\n" if i == (nb_of_sbox - 1)
end
puts ']'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment