/* sharnd.c - Create cryptographically secure random file (C) 2004, Matt Mahoney, mmahoney@cs.fit.edu This is free software under GPL, http://www.gnu.org/licenses/gpl.txt The command: sharnd key prints the SHA1 hash of the key, which can be any ASCII string. If the string has spaces, then enclose it in quotes. sharnd key n works as above and also creates the file sharnd.out with length n bytes containing cryptographically secure pseudo random numbers. Given all but one bit of the file, it is not possible to guess the remaining bit with probability greater than 1/2 unless you know the key. The output is a series of 20 byte strings, x[1], x[2], ... x[n/20] such that: x[i] = SHA1(x[i-1] + key) where x[0] is a string of 0 bytes, and + denotes concatenation. For example, "sharnd abc 50" will print: Key hash = A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D Writing 50 random bytes to sharnd.out... The contents of sharnd.out should be: 7D DF 37 9E DB 9F 0E 14 1F 6D AD EF EC 28 F0 60 2B 2A 76 A8 49 54 13 F2 6E DA 0F 19 CD D9 26 6C 46 8A 2D 17 8B 76 24 C0 0D D1 80 4F E7 22 6C 2A 9A C9 To compile, first get sha1.h and sha1.c from RFC3174, http://www.faqs.org/rfcs/rfc3174.html If you don't have then replace the following line in sha1.h #include with the following 3 lines: typedef unsigned long uint32_t; typedef unsigned char uint8_t; typedef int int_least16_t; Then compile as follows (for DJGPP or Borland) gcc -O sharnd.c sha1.c -o sharnd.exe bcc32 -O sharnd.c sha1.c */ #include #include #include #include "sha1.h" /* from RFC3174 */ /* Test for nonzero error code, exit with message if so */ void test(int err, const char* msg) { if (err) { fprintf(stderr, "%s: error %d\n", msg, err); exit(1); } } int main(int argc, char** argv) { int n, i, len; FILE* f; static unsigned char buf[20] = {0}; SHA1Context sha; /* Get args */ if (argc < 2) { fprintf(stderr, "To generate n secure random bytes: sharnd key n\n"); exit(1); } n = argc > 2 ? atoi(argv[2]) : 0; /* Number of bytes to output */ /* Print a hash of the key */ len = strlen(argv[1]); /* key length */ test(SHA1Reset(&sha), "SHA1Reset"); test(SHA1Input(&sha, argv[1], len), "SHA1Input"); test(SHA1Result(&sha, buf), "SHA1Result"); printf("Key hash ="); for (i=0; i<20; ++i) printf(" %02X", buf[i]); printf("\n"); /* Open output file */ if (n < 1) return 0; f = fopen("sharnd.out", "wb"); if (!f) { perror("sharnd.out"); exit(1); } /* Generate random data */ printf("Writing %d random bytes to sharnd.out...\n", n); while (n > 0) { test(SHA1Reset(&sha), "SHA1Reset"); test(SHA1Input(&sha, buf, 20), "SHA1Input hash"); test(SHA1Input(&sha, argv[1], len), "SHA1Input key"); test(SHA1Result(&sha, buf), "SHA1Result"); fwrite(buf, 1, (n > 20 ? 20 : n), f); n -= 20; } fclose(f); return 0; }