forked from
tangled.org/core
fork
Configure Feed
Select the types of activity you want to include in your feed.
Monorepo for Tangled
fork
Configure Feed
Select the types of activity you want to include in your feed.
1package randomart
2
3/*
4 * Draw an ASCII-Art representing the fingerprint so human brain can
5 * profit from its built-in pattern recognition ability.
6 * This technique is called "random art" and can be found in some
7 * scientific publications like this original paper:
8 *
9 * "Hash Visualization: a New Technique to improve Real-World Security",
10 * Perrig A. and Song D., 1999, International Workshop on Cryptographic
11 * Techniques and E-Commerce (CrypTEC '99)
12 * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
13 *
14 * The subject came up in a talk by Dan Kaminsky, too.
15 *
16 * If you see the picture is different, the key is different.
17 * If the picture looks the same, you still know nothing.
18 *
19 * The algorithm used here is a worm crawling over a discrete plane,
20 * leaving a trace (augmenting the field) everywhere it goes.
21 * Movement is taken from dgst_raw 2bit-wise. Bumping into walls
22 * makes the respective movement vector be ignored for this turn.
23 * Graphs are not unambiguous, because circles in graphs can be
24 * walked in either direction.
25 */
26
27import (
28 "os"
29)
30
31func MAX(a, b int) int {
32 if a > b {
33 return a
34 }
35 return b
36}
37
38func MIN(a, b int) int {
39 if a < b {
40 return a
41 }
42 return b
43}
44
45/*
46 * Field sizes for the random art. Have to be odd, so the starting point
47 * can be in the exact middle of the picture, and FLDBASE should be >=8 .
48 * Else pictures would be too dense, and drawing the frame would
49 * fail, too, because the key type would not fit in anymore.
50 */
51const (
52 FLDBASE = 8
53 FLDSIZE_Y = (FLDBASE + 1)
54 FLDSIZE_X = (FLDBASE*2 + 1)
55)
56
57func FromString(str string) string {
58 ch := make(chan byte)
59
60 go func() {
61 defer close(ch)
62 for _, v := range []byte(str) {
63 ch <- v
64 }
65 }()
66 return key_fingerprint_randomart(ch)
67}
68
69func FromFile(file *os.File) string {
70 ch := make(chan byte)
71
72 go func() {
73 defer close(ch)
74 // TODO make input a 1 element byte array
75 input := make([]byte, 1)
76 nread, err := file.Read(input)
77 for err == nil && nread > 0 {
78 ch <- input[0]
79 nread, err = file.Read(input)
80 }
81 }()
82 return key_fingerprint_randomart(ch)
83}
84
85func key_fingerprint_randomart(ch chan byte) string {
86 /*
87 * Chars to be used after each other every time the worm
88 * intersects with itself. Matter of taste.
89 */
90 augment_string := " .o+=*BOX@%&#/^SE"
91 var field [FLDSIZE_X][FLDSIZE_Y]byte
92 len_aug := len(augment_string) - 1
93 var retval [(FLDSIZE_X + 3) * (FLDSIZE_Y + 2)]byte
94
95 /* initialize field */
96 x := FLDSIZE_X / 2
97 y := FLDSIZE_Y / 2
98
99 /* process raw key */
100 for input, ok := <-ch; ok; input, ok = <-ch {
101 /* each byte conveys four 2-bit move commands */
102 for b := 0; b < 4; b++ {
103 /* evaluate 2 bit, rest is shifted later */
104 if input&0x1 > 0 {
105 x += 1
106 } else {
107 x += -1
108 }
109
110 if input&0x2 > 0 {
111 y++
112 } else {
113 y--
114 }
115
116 /* assure we are still in bounds */
117 x = MAX(x, 0)
118 y = MAX(y, 0)
119 x = MIN(x, FLDSIZE_X-1)
120 y = MIN(y, FLDSIZE_Y-1)
121
122 /* augment the field */
123 if int(field[x][y]) < len_aug-2 {
124 field[x][y]++
125 }
126 input = input >> 2
127 }
128 }
129
130 /* mark starting point and end point*/
131 field[FLDSIZE_X/2][FLDSIZE_Y/2] = byte(len_aug - 1)
132 field[x][y] = byte(len_aug)
133
134 i := 0
135 retval[i] = '+'
136 i++
137
138 /* output upper border */
139 for x := 0; x < FLDSIZE_X; x++ {
140 retval[i] = '-'
141 i++
142 }
143 retval[i] = '+'
144 i++
145 retval[i] = '\n'
146 i++
147
148 /* output content */
149 for y := 0; y < FLDSIZE_Y; y++ {
150 retval[i] = '|'
151 i++
152 for x := 0; x < FLDSIZE_X; x++ {
153 retval[i] = augment_string[MIN(int(field[x][y]), len_aug)]
154 i++
155 }
156 retval[i] = '|'
157 i++
158 retval[i] = '\n'
159 i++
160 }
161
162 /* output lower border */
163 retval[i] = '+'
164 i++
165 for j := 0; j < FLDSIZE_X; j++ {
166 retval[i] = '-'
167 i++
168 }
169 retval[i] = '+'
170 i++
171
172 return string(retval[0:i])
173}