mirror of
https://codeberg.org/scip/pcp.git
synced 2025-12-17 03:50:57 +01:00
initial commit
This commit is contained in:
101
libpcp/randomart.c
Normal file
101
libpcp/randomart.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "randomart.h"
|
||||
|
||||
#define FLDSIZE_Y 8
|
||||
#define FLDSIZE_X FLDSIZE_Y * 2
|
||||
|
||||
char *key_fingerprint_randomart(unsigned char *dgst_raw, unsigned int dgst_raw_len)
|
||||
{
|
||||
/*
|
||||
* Chars to be used after each other every time the worm
|
||||
* intersects with itself. Matter of taste.
|
||||
*/
|
||||
char *augmentation_string = " .o+=*BOX@%&#/^";
|
||||
char *retval, *p;
|
||||
char field[FLDSIZE_X][FLDSIZE_Y];
|
||||
unsigned int i, b;
|
||||
int x, y;
|
||||
|
||||
retval = ucmalloc((FLDSIZE_X + 3) * (FLDSIZE_Y + 2));
|
||||
|
||||
/* initialize field */
|
||||
memset(field, ' ', FLDSIZE_X * FLDSIZE_Y * sizeof(char));
|
||||
x = FLDSIZE_X / 2;
|
||||
y = FLDSIZE_Y / 2;
|
||||
field[x][y] = '.';
|
||||
|
||||
/* 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 */
|
||||
p = strchr(augmentation_string, field[x][y]);
|
||||
if (*++p != '\0')
|
||||
field[x][y] = *p;
|
||||
|
||||
input = input >> 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* fill in retval */
|
||||
p = retval;
|
||||
|
||||
/* output upper border */
|
||||
*p++ = '+';
|
||||
for (i = 0; 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++ = field[x][y];
|
||||
*p++ = '|';
|
||||
*p++ = '\n';
|
||||
}
|
||||
|
||||
/* output lower border */
|
||||
*p++ = '+';
|
||||
for (i = 0; i < FLDSIZE_X; i++)
|
||||
*p++ = '-';
|
||||
*p++ = '+';
|
||||
|
||||
return retval;
|
||||
}
|
||||
Reference in New Issue
Block a user