#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 4015 -rw-r--r-- README
# 1320 -rw-r--r-- makefile
# 1561 -rw-r--r-- randbyte.c
# 5428 -rw-r--r-- unix_truerand.c
# 1425 -rw-r--r-- nt_truerand.c
# 6749 -rw-r--r-- qshs.c
#
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
shar_touch=touch
else
shar_touch=:
echo
echo 'WARNING: not restoring timestamps. Consider getting and'
echo "installing GNU \`touch', distributed in GNU File Utilities..."
echo
fi
rm -f 1231235999 $$.touch
#
# ============= README ==============
if test -f 'README' && test X"$1" != X"-c"; then
echo 'x - skipping README (file already exists)'
else
echo 'x - extracting README (text)'
sed 's/^X//' << 'SHAR_EOF' > 'README' &&
/*
X * Almost "true" random numbers (very nearly uniform)
X * Based on code by D. P. Mitchell
X * Modified by Matt Blaze 7/95, 11/96
X * Version 2.1
X *
X * This is completely unsupported software.
X *
X * The authors of this software are Don Mitchell and Matt Blaze.
X * Copyright (c) 1995, 1996 by AT&T.
X * Permission to use, copy, and modify this software without fee
X * is hereby granted, provided that this entire notice is included in
X * all copies of any software which is or includes a copy or
X * modification of this software and in all copies of the supporting
X * documentation for such software.
X
X *
X * This software may be subject to United States export controls.
X *
X * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
X * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
X * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
X * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X */
X
/*
X * Truerand is a dubious, unproven hack for generating "true" random
X * numbers in software. It is at best a good "method of last resort"
X * for generating key material in environments where there is no (or
X * only an insufficient) source of better-understood randomness. It
X * can also be used to augment unreliable randomness sources (such as
X * input from a human operator).
X *
X * The basic idea behind truerand is that between clock "skew" and
X * various hard-to-predict OS event arrivals, counting a tight loop
X * will yield a little bit (maybe one bit or so) of "good" randomness
X * per interval clock tick. This seems to work well in practice even
X * on unloaded machines. If there is a human operator at the machine,
X * you should augment trand with other measurements, such as keyboard
X * event timing. On server machines (e.g., where you need to generate
X * a Diffie-Hellman secret but have no operator to type keys) trand
X * alone may (or may not) be sufficient.
X *
X * Because the randomness source is not well-understood, I've made
X * fairly conservative assumptions about how much randomness can be
X * extracted in any given interval. Based on a cursory analysis of
X * the BSD kernel, there seem to be about 100-200 bits of unexposed
X * "state" that changes each time a system call occurs and that affect
X * the exact handling of interrupt scheduling, plus a great deal of
X * slower-changing but still hard-to-model state based on, e.g., the
X * process table, the VM state, etc. There is no proof or guarantee
X * that some of this state couldn't be easily reconstructed, modeled
X * or influenced by an attacker, however, so we keep a large margin
X * for error. The truerand API assumes only 0.3 bits of entropy per
X * interval interrupt, amortized over 24 intervals and whitened with
X * SHA.
X *
X * The truerand API is in randbyte.c, and consists of trand8(),
X * trand16(), and trand32(). Do not use raw_truerand() directly.
X *
X * WARNING: depending on the particular platform, raw_truerand()
X * output may be biased or correlated. In general, you can expect no
X * more than 8-16 bits of "pseudo-entropy" out of each 32 bit word.
X * Always run the output through a good post-whitening function (like
X * SHA, MD5 or DES or whatever) before using it to generate key
X * material. The API does this for you, providing 8, 16, and 32 bit
X * properly "whitened" random numbers (trand8(), trand16(), and
X * trand32(), respectively). Use the trand calls instead of calling
X * raw_truerand() directly.
X *
X * Test truerand on your own platform before fielding a system based
X * on this software or these techniques.
X *
X * This software seems to work well (at 10 or so bits per
X * raw_truerand() call) on a Sun Sparc-20 under SunOS 4.1.3 and on a
X * P100 under BSDI 2.0. You're on your own elsewhere.
X *
X * This version of truerand doesn't clobber the ITIMER, so any
X * scheduled alarms will still occur (though alarms cannot occur while
X * raw_truerand is running and will be delayed by about 250ms per
X * raw_truerand call.
X */
SHAR_EOF
$shar_touch -am 1116142396 'README' &&
chmod 0644 'README' ||
echo 'restore of README failed'
shar_count="`wc -c < 'README'`"
test 4015 -eq "$shar_count" ||
echo "README: original size 4015, current size $shar_count"
fi
# ============= makefile ==============
if test -f 'makefile' && test X"$1" != X"-c"; then
echo 'x - skipping makefile (file already exists)'
else
echo 'x - extracting makefile (text)'
sed 's/^X//' << 'SHAR_EOF' > 'makefile' &&
# makefile for librand
# tested on Sparc-20 (SunOS 4.x) and P100 (BSDI) only.
# You're on your own elsewhere. Read the comments for scary warnings.
# nt_truerand.c is included but untested. Figure out how to use it
# youself, and don't say we didn't warn you.
#
# Usage: unsigned long trand8(), trand16(), trand32();
#
#* The authors of this software are Don Mitchell, Matt Blaze & Jack Lacy.
#* Copyright (c) 1995 by AT&T.
#* Permission to use, copy, and modify this software without fee
#* is hereby granted, provided that this entire notice is included in
#* all copies of any software which is or includes a copy or
#* modification of this software and in all copies of the supporting
#* documentation for such software.
#*
#* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
#* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
#* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
X
SRCS=randbyte.c unix_truerand.c nt_truerand.c qshs.c
OBJS=randbyte.o unix_truerand.o qshs.o
CC=gcc
CFLAGS=
# No -O in CFLAGS! On some compilers, this optimizes out the counter...
X
librand.a: $(OBJS)
X ar rcv librand.a $(OBJS)
X ranlib librand.a
X
librand.shar: README makefile $(SRCS)
X shar README makefile $(SRCS) > librand.shar
X
clean:
X rm -f $(OBJS) librand.a
SHAR_EOF
$shar_touch -am 1116142496 'makefile' &&
chmod 0644 'makefile' ||
echo 'restore of makefile failed'
shar_count="`wc -c < 'makefile'`"
test 1320 -eq "$shar_count" ||
echo "makefile: original size 1320, current size $shar_count"
fi
# ============= randbyte.c ==============
if test -f 'randbyte.c' && test X"$1" != X"-c"; then
echo 'x - skipping randbyte.c (file already exists)'
else
echo 'x - extracting randbyte.c (text)'
sed 's/^X//' << 'SHAR_EOF' > 'randbyte.c' &&
/*
X * Random byte interface to truerand()
X * Matt Blaze 9/95
X * 8, 16, 32 really random bits, at about .35 bits per clock
X * interrupt.
X *
X * usage:
X * unsigned char r8;
X * unsigned short r16;
X * unsigned long r32;
X * unsigned long trand8(), trand16(), trand32();
X * r8=trand8();
X * r16=trand16();
X * r32=trand32();
X *
X * randbyte() is the same as trand8().
X * trand8() takes about .3 seconds on most machines.
X */
/*
X * The author of this software is Matt Blaze.
X * Copyright (c) 1995 by AT&T.
X * Permission to use, copy, and modify this software without fee
X * is hereby granted, provided that this entire notice is included in
X * all copies of any software which is or includes a copy or
X * modification of this software and in all copies of the supporting
X * documentation for such software.
X *
X * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
X * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
X * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
X * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X */
X
unsigned long randbyte()
{
X unsigned long raw_truerand();
X unsigned char *qshs();
X unsigned long r[2];
X unsigned char *hash;
X
X r[0]=raw_truerand(); r[1]=raw_truerand();
X hash = qshs(r,sizeof(r));
X return ((int) (*hash)) & 0xff;
}
X
unsigned long trand8()
{
X return randbyte();
}
X
unsigned long trand16()
{
X return randbyte() ^ (randbyte()<<8);
}
X
unsigned long trand32()
{
X return randbyte() ^ (randbyte()<<8)
X ^ (randbyte()<<16) ^ (randbyte()<<24);
}
X
SHAR_EOF
$shar_touch -am 1207151295 'randbyte.c' &&
chmod 0644 'randbyte.c' ||
echo 'restore of randbyte.c failed'
shar_count="`wc -c < 'randbyte.c'`"
test 1561 -eq "$shar_count" ||
echo "randbyte.c: original size 1561, current size $shar_count"
fi
# ============= unix_truerand.c ==============
if test -f 'unix_truerand.c' && test X"$1" != X"-c"; then
echo 'x - skipping unix_truerand.c (file already exists)'
else
echo 'x - extracting unix_truerand.c (text)'
sed 's/^X//' << 'SHAR_EOF' > 'unix_truerand.c' &&
/*
X * Almost "true" random numbers (very nearly uniform)
X * Based on code by D. P. Mitchell
X * Modified by Matt Blaze 7/95, 11/96
X * Version 2.1
X *
X * This is completely unsupported software.
X *
X */
/*
X * The authors of this software are Don Mitchell and Matt Blaze.
X * Copyright (c) 1995, 1996 by AT&T.
X * Permission to use, copy, and modify this software without fee
X * is hereby granted, provided that this entire notice is included in
X * all copies of any software which is or includes a copy or
X * modification of this software and in all copies of the supporting
X * documentation for such software.
X
X *
X * This software may be subject to United States export controls.
X *
X * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
X * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
X * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
X * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X */
X
/*
X * Truerand is a dubious, unproven hack for generating "true" random
X * numbers in software. It is at best a good "method of last resort"
X * for generating key material in environments where there is no (or
X * only an insufficient) source of better-understood randomness. It
X * can also be used to augment unreliable randomness sources (such as
X * input from a human operator).
X *
X * The basic idea behind truerand is that between clock "skew" and
X * various hard-to-predict OS event arrivals, counting a tight loop
X * will yield a little bit (maybe one bit or so) of "good" randomness
X * per interval clock tick. This seems to work well in practice even
X * on unloaded machines. If there is a human operator at the machine,
X * you should augment trand with other measurements, such as keyboard
X * event timing. On server machines (e.g., where you need to generate
X * a Diffie-Hellman secret but have no operator to type keys) trand
X * alone may (or may not) be sufficient.
X *
X * Because the randomness source is not well-understood, I've made
X * fairly conservative assumptions about how much randomness can be
X * extracted in any given interval. Based on a cursory analysis of
X * the BSD kernel, there seem to be about 100-200 bits of unexposed
X * "state" that changes each time a system call occurs and that affect
X * the exact handling of interrupt scheduling, plus a great deal of
X * slower-changing but still hard-to-model state based on, e.g., the
X * process table, the VM state, etc. There is no proof or guarantee
X * that some of this state couldn't be easily reconstructed, modeled
X * or influenced by an attacker, however, so we keep a large margin
X * for error. The truerand API assumes only 0.3 bits of entropy per
X * interval interrupt, amortized over 24 intervals and whitened with
X * SHA.
X *
X * The trurand API is in randbyte.c, and consists of trand8(),
X * trand16(), and trand32(). Do not use raw_truerand() directly.
X *
X * WARNING: depending on the particular platform, raw_truerand()
X * output may be biased or correlated. In general, you can expect no
X * more than 8-16 bits of "pseudo-entropy" out of each 32 bit word.
X * Always run the output through a good post-whitening function (like
X * SHA, MD5 or DES or whatever) before using it to generate key
X * material. The API does this for you, providing 8, 16, and 32 bit
X * properly "whitened" random numbers (trand8(), trand16(), and
X * trand32(), respectively). Use the trand calls instead of calling
X * raw_truerand() directly.
X *
X * Test truerand on your own platform before fielding a system based
X * on this software or these techniques.
X *
X * This software seems to work well (at 10 or so bits per
X * raw_truerand() call) on a Sun Sparc-20 under SunOS 4.1.3 and on a
X * P100 under BSDI 2.0. You're on your own elsewhere.
X *
X * This version of truerand doesn't clobber the ITIMER, so any
X * scheduled alarms will still occur (though alarms cannot occur while
X * raw_truerand is running and will be delayed by about 250ms per
X * raw_truerand call.
X */
X
#include
#include
#include
#include
#include
X
static jmp_buf env;
static unsigned count;
static unsigned ocount;
static unsigned buffer;
X
static int
tick()
{
X struct itimerval it;
X
X timerclear(&it.it_interval);
X it.it_value.tv_sec = 0;
X it.it_value.tv_usec = 16665;
X if (setitimer(ITIMER_REAL, &it, NULL) < 0)
X perror("tick");
}
X
static void
interrupt()
{
X if (count)
X longjmp(env, 1);
X (void) signal(SIGALRM, interrupt);
X tick();
}
X
static unsigned long
roulette()
{
X if (setjmp(env))
X return count;
X (void) signal(SIGALRM, interrupt);
X count = 0;
X tick();
X for (;;)
X count++; /* about 1 MHz on VAX 11/780 */
}
X
/*
X * basic interface to 32 bit truerand.
X * note that any scheduled SIGNALRM will be delayed by about .3 secs.
X */
unsigned long
raw_truerand()
{
X void (*oldalrm)();
X struct itimerval it;
X unsigned long counts[12];
X unsigned char *qshs();
X unsigned char *r;
X unsigned long buf;
X int i;
X
X getitimer(ITIMER_REAL, &it);
X oldalrm = signal(SIGALRM, SIG_IGN);
X for (i=0; i<12; i++) {
X counts[i]=0;
X while ((counts[i] += roulette()) < 512)
X ;
X }
X signal(SIGALRM, oldalrm);
X setitimer(ITIMER_REAL, &it, NULL);
X
X r = qshs(counts,sizeof(counts));
X buf = *((unsigned long *) r);
X
X return buf;
}
X
int
raw_n_truerand(n)
int n;
{
X int slop, v;
X
X slop = 0x7FFFFFFF % n;
X do {
X v = raw_truerand() >> 1;
X } while (v <= slop);
X return v % n;
}
X
X
X
SHAR_EOF
$shar_touch -am 1116142296 'unix_truerand.c' &&
chmod 0644 'unix_truerand.c' ||
echo 'restore of unix_truerand.c failed'
shar_count="`wc -c < 'unix_truerand.c'`"
test 5428 -eq "$shar_count" ||
echo "unix_truerand.c: original size 5428, current size $shar_count"
fi
# ============= nt_truerand.c ==============
if test -f 'nt_truerand.c' && test X"$1" != X"-c"; then
echo 'x - skipping nt_truerand.c (file already exists)'
else
echo 'x - extracting nt_truerand.c (text)'
sed 's/^X//' << 'SHAR_EOF' > 'nt_truerand.c' &&
#include
#include
#include
#include
#include
#include
/* #include "libcrypt.h" */
X
volatile unsigned long count, ocount, randbuf;
volatile int dontstop;
char outbuf[1024], *bufp;
X
static void counter() {
X while (dontstop)
X count++;
X _endthread();
}
X
X
static unsigned long roulette() {
X unsigned long thread;
X
X count = 0;
X dontstop= 1;
X while ((thread = _beginthread((void *)counter, 1024, NULL)) < 0)
X ;
X
X Sleep(16);
X dontstop = 0;
X Sleep(1);
X
X count ^= (count>>3) ^ (count>>6) ^ (ocount);
X count &= 0x7;
X ocount = count;
X randbuf = (randbuf<<3) ^ count;
X return randbuf;
}
X
X
unsigned long raw_truerand() {
X int ii;
X
X roulette();
X roulette();
X roulette();
X roulette();
X roulette();
X roulette();
X roulette();
X roulette();
X roulette();
X roulette();
X return roulette();
}
X
#ifdef RAND_DEBUG
int WINAPI WinMain(HINSTANCE hins, HINSTANCE hprevins, LPSTR cmdline, int cmdshow)
{
X int i, j;
X unsigned char randbuf[1024];
X FILE *fp;
X
#ifdef nodef
X bufp = outbuf;
X memset(outbuf, 0, 1024);
X for (i=0; i<25; i++)
X bufp += sprintf(bufp, "%08lx\n", raw_truerand());
X MessageBox(NULL, outbuf, "TEST", MB_ABORTRETRYIGNORE);
X return 1;
#endif
X
X fp = fopen("/users/lacy/newrand.out","wb");
X
X for (i=0; i<1024; i++) {
X for (j=0; j<1024; j++) {
X randbuf[j] = (unsigned char)(truebyte() & 0xff);
X }
X fwrite(randbuf, 1, 1024, fp);
X }
X fclose(fp);
X
X return 1;
}
#endif
SHAR_EOF
$shar_touch -am 1205150095 'nt_truerand.c' &&
chmod 0644 'nt_truerand.c' ||
echo 'restore of nt_truerand.c failed'
shar_count="`wc -c < 'nt_truerand.c'`"
test 1425 -eq "$shar_count" ||
echo "nt_truerand.c: original size 1425, current size $shar_count"
fi
# ============= qshs.c ==============
if test -f 'qshs.c' && test X"$1" != X"-c"; then
echo 'x - skipping qshs.c (file already exists)'
else
echo 'x - extracting qshs.c (text)'
sed 's/^X//' << 'SHAR_EOF' > 'qshs.c' &&
/*
X * The authors of this software are Jim Reeds and Jack Lacy
X * Copyright (c) 1992, 1994 by AT&T.
X * Permission to use, copy, and modify this software without fee
X * is hereby granted, provided that this entire notice is included in
X * all copies of any software which is or includes a copy or
X * modification of this software and in all copies of the supporting
X * documentation for such software.
X *
X * This software may be subject to United States export controls.
X *
X * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
X * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
X * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
X * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X */
X
/*
X * Secure Hash Standard
X * proposed NIST SHS
X * coded for byte strings: number of bits is a multiple of 8
X *
X * Copyright (c) 1992, 1994 AT&T Bell Laboratories
X * Coded by Jim Reeds 5 Feb 1992
X * Enhanced by Jack Lacy 1993, 1994
X */
X
/*
X * unsigned char * shs(char *s, int n);
X *
X * input:
X * s character array to be hashed
X * n length of s in BYTES
X * output:
X * return value: address of 5 unsigned longs holding hash
X *
X * machine dependencies:
X * assumes a char is 8 bits
X */
X
/*
X * passes test on:
X * gauss (vax)
X * 3k (cray)
X * slepian (MIPS)
X * bird (sparcstation II)
X */
X
#include
#include
X
typedef struct {
X long totalLength;
X unsigned long h[5];
X unsigned long w[80];
} SHS_CTX;
X
unsigned char *qshs();
#ifdef SOLARIS2X
#define bzero(b, l) memset(b, 0, l)
#define bcopy(s, d, l) memcpy(d, s, l)
#define bcmp(s, d, l) (memcmp(s, d, l)? 1 : 0)
#endif
X
static long nbits;
static unsigned long *h;
static unsigned long *w;
static void shs1();
/*
static void packl (unsigned long);
static void pack (unsigned char, unsigned char, unsigned char, unsigned char);
static void shs1(void);
static void opack(unsigned char);
*/
X
#define MASK (unsigned long)0xffffffffL /* in case more than 32 bits per long */
X
/*
X * stick one byte into the current block; process the block when full
X */
static void opack(c)
X unsigned char c;
{
X int n32, nd32, shiftbits;
X register unsigned long x, mask, y;
X
X nd32 = (int)(nbits >> 5); /* nbits/32 */
X n32 = (int)(nbits & 0x1f); /* nbits%32 */
X shiftbits = 24-n32;
X
X x = (unsigned long)(c<> 5);
X w[nd32] = (u_long)(((u_long)c0<<24) | ((u_long)c1<<16) | ((u_long)c2<<8) | (u_long)c3);
X
X nbits += 32;
X if(nbits==512){
X nbits = 0;
X shs1();
X }
}
X
/*
X * stick a 4 byte number into the current block
X */
static void
packl(x)
X unsigned long x;
{
X pack((unsigned char)(x>>24), (unsigned char)(x>>16),
X (unsigned char)(x>>8), (unsigned char)(x>>0));
}
X
/*
X * process one block
X */
static void
shs1()
{
X unsigned long *wp;
X unsigned long temp;
X unsigned long A, B, C, D, E;
X int t;
X
#define S(n,x) (u_long)(((x)<<(n))|((MASK&(x))>>(32-(n))))
X
X wp = w;
X t = 8;
X do {
X wp[16] = S(1, (u_long)(wp[13]^wp[8]^wp[2]^wp[0]));
X wp[17] = S(1, (u_long)(wp[14]^wp[9]^wp[3]^wp[1]));
X wp[18] = S(1, (u_long)(wp[15]^wp[10]^wp[4]^wp[2]));
X wp[19] = S(1, (u_long)(wp[16]^wp[11]^wp[5]^wp[3]));
X wp[20] = S(1, (u_long)(wp[17]^wp[12]^wp[6]^wp[4]));
X wp[21] = S(1, (u_long)(wp[18]^wp[13]^wp[7]^wp[5]));
X wp[22] = S(1, (u_long)(wp[19]^wp[14]^wp[8]^wp[6]));
X wp[23] = S(1, (u_long)(wp[20]^wp[15]^wp[9]^wp[7]));
X wp += 8;
X t--;
X } while (t > 0);
X
X A = h[0];
X B = h[1];
X C = h[2];
X D = h[3];
X E = h[4];
X
X t = 0;
X while (t<20) {
X temp = S(5,A) + E + w[t++];
X temp += (unsigned long)0x5a827999L + ((B&C)|(D&~B));
X E = D; D = C; C = S(30,B); B = A; A = temp;
X }
X while (t<40) {
X temp = S(5,A) + E + w[t++];
X temp += (unsigned long)0x6ed9eba1L + (B^C^D);
X E = D; D = C; C = S(30,B); B = A; A = temp;
X }
X while (t<60) {
X temp = S(5,A) + E + w[t++];
X temp += (unsigned long)0x8f1bbcdcL + ((B&C)|(B&D)|(C&D));
X E = D; D = C; C = S(30,B); B = A; A = temp;
X }
X while (t<80) {
X temp = S(5,A) + E + w[t++];
X temp += (unsigned long)0xca62c1d6L + (B^C^D);
X E = D; D = C; C = S(30,B); B = A; A = temp;
X }
X h[0] = MASK&(h[0] + A);
X h[1] = MASK&(h[1] + B);
X h[2] = MASK&(h[2] + C);
X h[3] = MASK&(h[3] + D);
X h[4] = MASK&(h[4] + E);
}
X
#define CHARSTOLONG(wp,s,i) {*wp++ = (u_long)((((u_long)(s[i])&0xff)<<24)|(((u_long)(s[i+1])&0xff)<<16)|(((u_long)(s[i+2])&0xff)<<8)|(u_long)(s[i+3]&0xff));}
X
X
static void
shsInit(mdContext)
X SHS_CTX *mdContext;
{
X nbits = 0;
X mdContext->h[0] = (unsigned long)0x67452301L;
X mdContext->h[1] = (unsigned long)0xefcdab89L;
X mdContext->h[2] = (unsigned long)0x98badcfeL;
X mdContext->h[3] = (unsigned long)0x10325476L;
X mdContext->h[4] = (unsigned long)0xc3d2e1f0L;
X mdContext->totalLength = 0;
}
X
X
static void
shsUpdate(mdContext, s, n)
X SHS_CTX *mdContext;
X unsigned char *s;
X unsigned int n;
{
X register unsigned long *wp;
X long nn = n;
X long i;
X
X w = mdContext->w;
X h = mdContext->h;
X mdContext->totalLength += n;
X
X nbits = 0;
X n = n/(u_long)64;
X wp = w;
X
X while(n>0){
X CHARSTOLONG(wp,s,0);
X CHARSTOLONG(wp,s,4);
X CHARSTOLONG(wp,s,8);
X CHARSTOLONG(wp,s,12);
X CHARSTOLONG(wp,s,16);
X CHARSTOLONG(wp,s,20);
X CHARSTOLONG(wp,s,24);
X CHARSTOLONG(wp,s,28);
X CHARSTOLONG(wp,s,32);
X CHARSTOLONG(wp,s,36);
X CHARSTOLONG(wp,s,40);
X CHARSTOLONG(wp,s,44);
X CHARSTOLONG(wp,s,48);
X CHARSTOLONG(wp,s,52);
X CHARSTOLONG(wp,s,56);
X CHARSTOLONG(wp,s,60);
X n--;
X wp = w;
X s = (s + 64);
X shs1();
X }
X i=nn%64;
X while(i>3) {
X CHARSTOLONG(wp,s,0);
X s = (s + 4);
X nbits += (u_long)32;
X i -= 4;
X }
X while (i) {
X opack((unsigned char)*s++);
X i--;
X }
}
X
static void
shsFinal(mdContext)
X SHS_CTX *mdContext;
{
X long nn = mdContext->totalLength;
X w = mdContext->w;
X h = mdContext->h;
X
X opack(128);
X while(nbits != 448)opack(0);
X packl((unsigned long)(nn>>29));
X packl((unsigned long)(nn<<3));
X
X /* if(nbits != 0)
X handle_exception(CRITICAL,"shsFinal(): nbits != 0\n");*/
}
X
unsigned char *
qshs(s, n)
X unsigned char *s;
X long n;
{
X SHS_CTX *mdContext;
X static SHS_CTX mdC;
X static unsigned char ret[20];
X int i;
X
X mdContext = &mdC;
X
X shsInit(mdContext);
X shsUpdate(mdContext, s, n);
X shsFinal(mdContext);
X for (i=0; i<5; i++) {
X ret[i*4] = (mdContext->h[i]>>24)&0xff;
X ret[i*4+1] = (mdContext->h[i]>>16)&0xff;
X ret[i*4+2] = (mdContext->h[i]>>8)&0xff;
X ret[i*4+3] = (mdContext->h[i])&0xff;
X }
X
X return ret;
}
X
SHAR_EOF
$shar_touch -am 1205134895 'qshs.c' &&
chmod 0644 'qshs.c' ||
echo 'restore of qshs.c failed'
shar_count="`wc -c < 'qshs.c'`"
test 6749 -eq "$shar_count" ||
echo "qshs.c: original size 6749, current size $shar_count"
fi
exit 0