Created
October 22, 2014 20:20
-
-
Save robertodecurnex/27aea000d935d63e0959 to your computer and use it in GitHub Desktop.
Randomart generation (from the openssh-client)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Draw an ASCII-Art representing the fingerprint so human brain can | |
* profit from its built-in pattern recognition ability. | |
* This technique is called "random art" and can be found in some | |
* scientific publications like this original paper: | |
* | |
* "Hash Visualization: a New Technique to improve Real-World Security", | |
* Perrig A. and Song D., 1999, International Workshop on Cryptographic | |
* Techniques and E-Commerce (CrypTEC '99) | |
* sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf | |
* | |
* The subject came up in a talk by Dan Kaminsky, too. | |
* | |
* If you see the picture is different, the key is different. | |
* If the picture looks the same, you still know nothing. | |
* | |
* The algorithm used here is a worm crawling over a discrete plane, | |
* leaving a trace (augmenting the field) everywhere it goes. | |
* Movement is taken from dgst_raw 2bit-wise. Bumping into walls | |
* makes the respective movement vector be ignored for this turn. | |
* Graphs are not unambiguous, because circles in graphs can be | |
* walked in either direction. | |
*/ | |
/* | |
* Field sizes for the random art. Have to be odd, so the starting point | |
* can be in the exact middle of the picture, and FLDBASE should be >=8 . | |
* Else pictures would be too dense, and drawing the frame would | |
* fail, too, because the key type would not fit in anymore. | |
*/ | |
#define FLDBASE 8 | |
#define FLDSIZE_Y (FLDBASE + 1) | |
#define FLDSIZE_X (FLDBASE * 2 + 1) | |
static char * | |
key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k) | |
{ | |
/* | |
* Chars to be used after each other every time the worm | |
* intersects with itself. Matter of taste. | |
*/ | |
char *augmentation_string = " .o+=*BOX@%&#/^SE"; | |
char *retval, *p; | |
u_char field[FLDSIZE_X][FLDSIZE_Y]; | |
u_int i, b; | |
int x, y; | |
size_t len = strlen(augmentation_string) - 1; | |
retval = xcalloc(1, (FLDSIZE_X + 3) * (FLDSIZE_Y + 2)); | |
/* initialize field */ | |
memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char)); | |
x = FLDSIZE_X / 2; | |
y = FLDSIZE_Y / 2; | |
/* process raw key */ | |
for (i = 0; i < dgst_raw_len; i++) { | |
int input; | |
/* each byte conveys four 2-bit move commands */ | |
input = dgst_raw[i]; | |
for (b = 0; b < 4; b++) { | |
/* evaluate 2 bit, rest is shifted later */ | |
x += (input & 0x1) ? 1 : -1; | |
y += (input & 0x2) ? 1 : -1; | |
/* assure we are still in bounds */ | |
x = MAX(x, 0); | |
y = MAX(y, 0); | |
x = MIN(x, FLDSIZE_X - 1); | |
y = MIN(y, FLDSIZE_Y - 1); | |
/* augment the field */ | |
if (field[x][y] < len - 2) | |
field[x][y]++; | |
input = input >> 2; | |
} | |
} | |
/* mark starting point and end point*/ | |
field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1; | |
field[x][y] = len; | |
/* fill in retval */ | |
snprintf(retval, FLDSIZE_X, "+--[%4s %4u]", key_type(k), key_size(k)); | |
p = strchr(retval, '\0'); | |
/* output upper border */ | |
for (i = p - retval - 1; i < FLDSIZE_X; i++) | |
*p++ = '-'; | |
*p++ = '+'; | |
*p++ = '\n'; | |
/* output content */ | |
for (y = 0; y < FLDSIZE_Y; y++) { | |
*p++ = '|'; | |
for (x = 0; x < FLDSIZE_X; x++) | |
*p++ = augmentation_string[MIN(field[x][y], len)]; | |
*p++ = '|'; | |
*p++ = '\n'; | |
} | |
/* output lower border */ | |
*p++ = '+'; | |
for (i = 0; i < FLDSIZE_X; i++) | |
*p++ = '-'; | |
*p++ = '+'; | |
return retval; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment