我需要使用SHA-1作为PRNG,所以这就是为什么它需要一些密钥的原因,但是在诸如hashlib和pycryptodome之类的python库中,我没有找到任何机会。有没有现成的解决方案?或者,也许还有另一种在Python中使用SHA-1作为PRNG的方法?之所以问这个问题是因为NIST测试中的SHA-1 PRNG代码让我有些困惑(该代码来自NIST测试,最终位于sts-2.1.2 / sts-2.1.2 / src / generators.c中)。老实说,我希望SHA-1 PRNG的工作方式如下:
r=sha1(x)
r=sha1(r)
但是使用该NIST代码,我真的不了解如何在python上实现SHA-1 PRNG。 // Uses 160 bit Xkey and no XSeed (b=160)
// This is the generic form of the generator found on the last page of the Change Notice for FIPS 186-2
void
SHA1()
{
ULONG A, B, C, D, E, temp, Wbuff[16];
BYTE Xkey[20], G[20], M[64];
BYTE One[1] = { 0x01 };
int i, num_0s, num_1s, bitsRead;
int done;
ULONG tx[5] = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 };
if ( ((epsilon = (BitSequence *) calloc(tp.n,sizeof(BitSequence))) == NULL) ) {
printf("Insufficient memory available.\n");
exit(1);
}
ahtopb("ec822a619d6ed5d9492218a7a4c5b15d57c61601", Xkey, 20);
// ahtopb("E65097BAEC92E70478CAF4ED0ED94E1C94B15446", Xkey, 20);
// ahtopb("6BFB9EC9BE37B2B0FF8526C222B76E0E91501753", Xkey, 20);
// ahtopb("5AE8B9207250257D0A0C87C0DACEF78E17D1EF9D", Xkey, 20);
// ahtopb("D99CB53DD5FA9BC1D0176F5DF8D9110FD16EE21F", Xkey, 20);
for ( i=0; i<tp.numOfBitStreams; i++ ) {
num_0s = 0;
num_1s = 0;
bitsRead = 0;
do {
memcpy(M, Xkey, 20);
memset(M+20, 0x00, 44);
// Start: SHA Steps A-E
A = tx[0];
B = tx[1];
C = tx[2];
D = tx[3];
E = tx[4];
memcpy((BYTE *)Wbuff, M, 64);
#ifdef LITTLE_ENDIAN
byteReverse(Wbuff, 20);
#endif
sub1Round1( 0 ); sub1Round1( 1 ); sub1Round1( 2 ); sub1Round1( 3 );
sub1Round1( 4 ); sub1Round1( 5 ); sub1Round1( 6 ); sub1Round1( 7 );
sub1Round1( 8 ); sub1Round1( 9 ); sub1Round1( 10 ); sub1Round1( 11 );
sub1Round1( 12 ); sub1Round1( 13 ); sub1Round1( 14 ); sub1Round1( 15 );
sub2Round1( 16 ); sub2Round1( 17 ); sub2Round1( 18 ); sub2Round1( 19 );
Round2( 20 ); Round2( 21 ); Round2( 22 ); Round2( 23 );
Round2( 24 ); Round2( 25 ); Round2( 26 ); Round2( 27 );
Round2( 28 ); Round2( 29 ); Round2( 30 ); Round2( 31 );
Round2( 32 ); Round2( 33 ); Round2( 34 ); Round2( 35 );
Round2( 36 ); Round2( 37 ); Round2( 38 ); Round2( 39 );
Round3( 40 ); Round3( 41 ); Round3( 42 ); Round3( 43 );
Round3( 44 ); Round3( 45 ); Round3( 46 ); Round3( 47 );
Round3( 48 ); Round3( 49 ); Round3( 50 ); Round3( 51 );
Round3( 52 ); Round3( 53 ); Round3( 54 ); Round3( 55 );
Round3( 56 ); Round3( 57 ); Round3( 58 ); Round3( 59 );
Round4( 60 ); Round4( 61 ); Round4( 62 ); Round4( 63 );
Round4( 64 ); Round4( 65 ); Round4( 66 ); Round4( 67 );
Round4( 68 ); Round4( 69 ); Round4( 70 ); Round4( 71 );
Round4( 72 ); Round4( 73 ); Round4( 74 ); Round4( 75 );
Round4( 76 ); Round4( 77 ); Round4( 78 ); Round4( 79 );
A += tx[0];
B += tx[1];
C += tx[2];
D += tx[3];
E += tx[4];
memcpy(G, (BYTE *)&A, 4);
memcpy(G+4, (BYTE *)&B, 4);
memcpy(G+8, (BYTE *)&C, 4);
memcpy(G+12, (BYTE *)&D, 4);
memcpy(G+16, (BYTE *)&E, 4);
#ifdef LITTLE_ENDIAN
byteReverse((ULONG *)G, 20);
#endif
// End: SHA Steps A-E
done = convertToBits(G, 160, tp.n, &num_0s, &num_1s, &bitsRead);
add(Xkey, 20, G, 20);
add(Xkey, 20, One, 1);
} while ( !done );
fprintf(freqfp, "\t\tBITSREAD = %d 0s = %d 1s = %d\n", bitsRead, num_0s, num_1s); fflush(freqfp);
nist_test_suite();
}
free(epsilon);
}