17eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* SHA module */
27eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
37eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* This module provides an interface to NIST's Secure Hash Algorithm */
47eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
57eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* See below for information about the original code this module was
67eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   based upon. Additional work performed by:
77eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
87eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Andrew Kuchling (amk@amk.ca)
97eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Greg Stein (gstein@lyra.org)
107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Copyright (C) 2005   Gregory P. Smith (greg@krypto.org)
127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Licensed to PSF under a Contributor Agreement.
137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel*/
157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* SHA objects */
177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "Python.h"
197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "structmember.h"
207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Endianness testing and definitions */
237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define TestEndianness(variable) {int i=1; variable=PCT_BIG_ENDIAN;\
247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (*((char*)&i)==1) variable=PCT_LITTLE_ENDIAN;}
257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PCT_LITTLE_ENDIAN 1
277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PCT_BIG_ENDIAN 0
287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Some useful types */
307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef unsigned char SHA_BYTE;
327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#if SIZEOF_INT == 4
347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef unsigned int SHA_INT32; /* 32-bit integer */
357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* not defined. compilation will die. */
377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* The SHA block size and message digest sizes, in bytes */
407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define SHA_BLOCKSIZE    64
427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define SHA_DIGESTSIZE  20
437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* The structure for storing SHS info */
457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef struct {
477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject_HEAD
487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHA_INT32 digest[5];                /* Message digest */
497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHA_INT32 count_lo, count_hi;       /* 64-bit bit count */
507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHA_BYTE data[SHA_BLOCKSIZE];       /* SHA data buffer */
517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int Endianness;
527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int local;                          /* unprocessed amount in data */
537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} SHAobject;
547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* When run on a little-endian CPU we need to perform byte reversal on an
567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   array of longwords. */
577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void longReverse(SHA_INT32 *buffer, int byteCount, int Endianness)
597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHA_INT32 value;
617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if ( Endianness == PCT_BIG_ENDIAN )
637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return;
647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    byteCount /= sizeof(*buffer);
667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    while (byteCount--) {
677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        value = *buffer;
687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        value = ( ( value & 0xFF00FF00L ) >> 8  ) | \
697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ( ( value & 0x00FF00FFL ) << 8 );
707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        *buffer++ = ( value << 16 ) | ( value >> 16 );
717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void SHAcopy(SHAobject *src, SHAobject *dest)
757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    dest->Endianness = src->Endianness;
777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    dest->local = src->local;
787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    dest->count_lo = src->count_lo;
797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    dest->count_hi = src->count_hi;
807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    memcpy(dest->digest, src->digest, sizeof(src->digest));
817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    memcpy(dest->data, src->data, sizeof(src->data));
827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* ------------------------------------------------------------------------
867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * This code for the SHA algorithm was noted as public domain. The original
887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * headers are pasted below.
897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * Several changes have been made to make it more compatible with the
917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * Python environment and desired interface.
927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* NIST Secure Hash Algorithm */
967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* heavily modified by Uwe Hollerbach <uh@alumni.caltech edu> */
977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* from Peter C. Gutmann's implementation as found in */
987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Applied Cryptography by Bruce Schneier */
997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Further modifications to include the "UNRAVEL" stuff, below */
1007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* This code is in the public domain */
1027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* UNRAVEL should be fastest & biggest */
1047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* UNROLL_LOOPS should be just as big, but slightly slower */
1057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* both undefined should be smallest and slowest */
1067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define UNRAVEL
1087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* #define UNROLL_LOOPS */
1097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* The SHA f()-functions.  The f1 and f3 functions can be optimized to
1117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   save one boolean operation each - thanks to Rich Schroeppel,
1127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   rcs@cs.arizona.edu for discovering this */
1137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*#define f1(x,y,z)     ((x & y) | (~x & z))            // Rounds  0-19 */
1157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define f1(x,y,z)       (z ^ (x & (y ^ z)))             /* Rounds  0-19 */
1167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define f2(x,y,z)       (x ^ y ^ z)                     /* Rounds 20-39 */
1177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*#define f3(x,y,z)     ((x & y) | (x & z) | (y & z))   // Rounds 40-59 */
1187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define f3(x,y,z)       ((x & y) | (z & (x | y)))       /* Rounds 40-59 */
1197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define f4(x,y,z)       (x ^ y ^ z)                     /* Rounds 60-79 */
1207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* SHA constants */
1227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define CONST1          0x5a827999L                     /* Rounds  0-19 */
1247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define CONST2          0x6ed9eba1L                     /* Rounds 20-39 */
1257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define CONST3          0x8f1bbcdcL                     /* Rounds 40-59 */
1267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define CONST4          0xca62c1d6L                     /* Rounds 60-79 */
1277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* 32-bit rotate */
1297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define R32(x,n)        ((x << n) | (x >> (32 - n)))
1317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* the generic case, for when the overall rotation is not unraveled */
1337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define FG(n)   \
1357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    T = R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n;  \
1367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    E = D; D = C; C = R32(B,30); B = A; A = T
1377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* specific cases, for when the overall rotation is unraveled */
1397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define FA(n)   \
1417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    T = R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n; B = R32(B,30)
1427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define FB(n)   \
1447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    E = R32(T,5) + f##n(A,B,C) + D + *WP++ + CONST##n; A = R32(A,30)
1457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define FC(n)   \
1477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    D = R32(E,5) + f##n(T,A,B) + C + *WP++ + CONST##n; T = R32(T,30)
1487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define FD(n)   \
1507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    C = R32(D,5) + f##n(E,T,A) + B + *WP++ + CONST##n; E = R32(E,30)
1517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define FE(n)   \
1537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    B = R32(C,5) + f##n(D,E,T) + A + *WP++ + CONST##n; D = R32(D,30)
1547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define FT(n)   \
1567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    A = R32(B,5) + f##n(C,D,E) + T + *WP++ + CONST##n; C = R32(C,30)
1577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* do SHA transformation */
1597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
1617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielsha_transform(SHAobject *sha_info)
1627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i;
1647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHA_INT32 T, A, B, C, D, E, W[80], *WP;
1657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    memcpy(W, sha_info->data, sizeof(sha_info->data));
1677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    longReverse(W, (int)sizeof(sha_info->data), sha_info->Endianness);
1687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 16; i < 80; ++i) {
1707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
1717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* extra rotation fix */
1737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        W[i] = R32(W[i], 1);
1747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    A = sha_info->digest[0];
1767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    B = sha_info->digest[1];
1777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    C = sha_info->digest[2];
1787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    D = sha_info->digest[3];
1797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    E = sha_info->digest[4];
1807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    WP = W;
1817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef UNRAVEL
1827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1);
1837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1);
1847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2);
1857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2);
1867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3);
1877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3);
1887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4);
1897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4);
1907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->digest[0] += E;
1917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->digest[1] += T;
1927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->digest[2] += A;
1937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->digest[3] += B;
1947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->digest[4] += C;
1957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else /* !UNRAVEL */
1967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef UNROLL_LOOPS
1977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
1987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
1997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
2007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
2017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
2027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
2037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
2047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
2057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else /* !UNROLL_LOOPS */
2067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i =  0; i < 20; ++i) { FG(1); }
2077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 20; i < 40; ++i) { FG(2); }
2087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 40; i < 60; ++i) { FG(3); }
2097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 60; i < 80; ++i) { FG(4); }
2107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif /* !UNROLL_LOOPS */
2117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->digest[0] += A;
2127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->digest[1] += B;
2137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->digest[2] += C;
2147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->digest[3] += D;
2157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->digest[4] += E;
2167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif /* !UNRAVEL */
2177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* initialize the SHA digest */
2207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
2227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielsha_init(SHAobject *sha_info)
2237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    TestEndianness(sha_info->Endianness)
2257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->digest[0] = 0x67452301L;
2277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->digest[1] = 0xefcdab89L;
2287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->digest[2] = 0x98badcfeL;
2297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->digest[3] = 0x10325476L;
2307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->digest[4] = 0xc3d2e1f0L;
2317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->count_lo = 0L;
2327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->count_hi = 0L;
2337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->local = 0;
2347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* update the SHA digest */
2377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
2397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielsha_update(SHAobject *sha_info, SHA_BYTE *buffer, unsigned int count)
2407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned int i;
2427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHA_INT32 clo;
2437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    clo = sha_info->count_lo + ((SHA_INT32) count << 3);
2457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (clo < sha_info->count_lo) {
2467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ++sha_info->count_hi;
2477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->count_lo = clo;
2497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->count_hi += (SHA_INT32) count >> 29;
2507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (sha_info->local) {
2517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        i = SHA_BLOCKSIZE - sha_info->local;
2527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (i > count) {
2537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            i = count;
2547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
2557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i);
2567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        count -= i;
2577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        buffer += i;
2587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        sha_info->local += i;
2597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (sha_info->local == SHA_BLOCKSIZE) {
2607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            sha_transform(sha_info);
2617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
2627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
2637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return;
2647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
2657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    while (count >= SHA_BLOCKSIZE) {
2677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
2687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        buffer += SHA_BLOCKSIZE;
2697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        count -= SHA_BLOCKSIZE;
2707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        sha_transform(sha_info);
2717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    memcpy(sha_info->data, buffer, count);
2737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->local = count;
2747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* finish computing the SHA digest */
2777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
2797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielsha_final(unsigned char digest[20], SHAobject *sha_info)
2807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int count;
2827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHA_INT32 lo_bit_count, hi_bit_count;
2837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    lo_bit_count = sha_info->count_lo;
2857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    hi_bit_count = sha_info->count_hi;
2867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    count = (int) ((lo_bit_count >> 3) & 0x3f);
2877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ((SHA_BYTE *) sha_info->data)[count++] = 0x80;
2887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (count > SHA_BLOCKSIZE - 8) {
2897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        memset(((SHA_BYTE *) sha_info->data) + count, 0,
2907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               SHA_BLOCKSIZE - count);
2917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        sha_transform(sha_info);
2927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 8);
2937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
2957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        memset(((SHA_BYTE *) sha_info->data) + count, 0,
2967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               SHA_BLOCKSIZE - 8 - count);
2977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* GJS: note that we add the hi/lo in big-endian. sha_transform will
3007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       swap these values into host-order. */
3017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->data[56] = (hi_bit_count >> 24) & 0xff;
3027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->data[57] = (hi_bit_count >> 16) & 0xff;
3037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->data[58] = (hi_bit_count >>  8) & 0xff;
3047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->data[59] = (hi_bit_count >>  0) & 0xff;
3057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->data[60] = (lo_bit_count >> 24) & 0xff;
3067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->data[61] = (lo_bit_count >> 16) & 0xff;
3077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->data[62] = (lo_bit_count >>  8) & 0xff;
3087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_info->data[63] = (lo_bit_count >>  0) & 0xff;
3097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_transform(sha_info);
3107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
3117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
3127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[ 2] = (unsigned char) ((sha_info->digest[0] >>  8) & 0xff);
3137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[ 3] = (unsigned char) ((sha_info->digest[0]      ) & 0xff);
3147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
3157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
3167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[ 6] = (unsigned char) ((sha_info->digest[1] >>  8) & 0xff);
3177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[ 7] = (unsigned char) ((sha_info->digest[1]      ) & 0xff);
3187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
3197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
3207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[10] = (unsigned char) ((sha_info->digest[2] >>  8) & 0xff);
3217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[11] = (unsigned char) ((sha_info->digest[2]      ) & 0xff);
3227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
3237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
3247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[14] = (unsigned char) ((sha_info->digest[3] >>  8) & 0xff);
3257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[15] = (unsigned char) ((sha_info->digest[3]      ) & 0xff);
3267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
3277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
3287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[18] = (unsigned char) ((sha_info->digest[4] >>  8) & 0xff);
3297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    digest[19] = (unsigned char) ((sha_info->digest[4]      ) & 0xff);
3307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
3337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * End of copied SHA code.
3347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
3357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * ------------------------------------------------------------------------
3367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
3377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyTypeObject SHAtype;
3397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic SHAobject *
3427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielnewSHAobject(void)
3437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (SHAobject *)PyObject_New(SHAobject, &SHAtype);
3457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Internal methods for a hashing object */
3487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
3507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielSHA_dealloc(PyObject *ptr)
3517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject_Del(ptr);
3537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* External methods for a hashing object */
3577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(SHA_copy__doc__, "Return a copy of the hashing object.");
3597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
3617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielSHA_copy(SHAobject *self, PyObject *unused)
3627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHAobject *newobj;
3647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if ( (newobj = newSHAobject())==NULL)
3667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
3677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHAcopy(self, newobj);
3697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (PyObject *)newobj;
3707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(SHA_digest__doc__,
3737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Return the digest value as a string of binary data.");
3747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
3767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielSHA_digest(SHAobject *self, PyObject *unused)
3777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned char digest[SHA_DIGESTSIZE];
3797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHAobject temp;
3807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHAcopy(self, &temp);
3827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_final(digest, &temp);
3837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyString_FromStringAndSize((const char *)digest, sizeof(digest));
3847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(SHA_hexdigest__doc__,
3877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Return the digest value as a string of hexadecimal digits.");
3887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
3907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielSHA_hexdigest(SHAobject *self, PyObject *unused)
3917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned char digest[SHA_DIGESTSIZE];
3937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHAobject temp;
3947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *retval;
3957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char *hex_digest;
3967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i, j;
3977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Get the raw (binary) digest value */
3997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHAcopy(self, &temp);
4007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_final(digest, &temp);
4017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Create a new string */
4037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    retval = PyString_FromStringAndSize(NULL, sizeof(digest) * 2);
4047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!retval)
4057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
4067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    hex_digest = PyString_AsString(retval);
4077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!hex_digest) {
4087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_DECREF(retval);
4097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
4107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Make hex version of the digest */
4137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for(i=j=0; i<sizeof(digest); i++) {
4147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        char c;
4157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        c = (digest[i] >> 4) & 0xf;
4167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        c = (c>9) ? c+'a'-10 : c + '0';
4177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hex_digest[j++] = c;
4187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        c = (digest[i] & 0xf);
4197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        c = (c>9) ? c+'a'-10 : c + '0';
4207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hex_digest[j++] = c;
4217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return retval;
4237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(SHA_update__doc__,
4267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Update this hashing object's state with the provided string.");
4277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
4297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielSHA_update(SHAobject *self, PyObject *args)
4307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
4317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_buffer view;
4327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t n;
4337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned char *buf;
4347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTuple(args, "s*:update", &view))
4367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
4377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    n = view.len;
4397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    buf = (unsigned char *) view.buf;
4407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    while (n > 0) {
4417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_ssize_t nbytes;
4427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (n > INT_MAX)
4437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            nbytes = INT_MAX;
4447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
4457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            nbytes = n;
4467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        sha_update(self, buf,
4477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   Py_SAFE_DOWNCAST(nbytes, Py_ssize_t, unsigned int));
4487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        buf += nbytes;
4497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        n -= nbytes;
4507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyBuffer_Release(&view);
4537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_RETURN_NONE;
4547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyMethodDef SHA_methods[] = {
4577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"copy",      (PyCFunction)SHA_copy,      METH_NOARGS,  SHA_copy__doc__},
4587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"digest",    (PyCFunction)SHA_digest,    METH_NOARGS,  SHA_digest__doc__},
4597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"hexdigest", (PyCFunction)SHA_hexdigest, METH_NOARGS,  SHA_hexdigest__doc__},
4607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"update",    (PyCFunction)SHA_update,    METH_VARARGS, SHA_update__doc__},
4617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {NULL,        NULL}         /* sentinel */
4627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
4637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
4657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielSHA_get_block_size(PyObject *self, void *closure)
4667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
4677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyInt_FromLong(SHA_BLOCKSIZE);
4687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
4717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielSHA_get_digest_size(PyObject *self, void *closure)
4727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
4737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyInt_FromLong(SHA_DIGESTSIZE);
4747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
4777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielSHA_get_name(PyObject *self, void *closure)
4787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
4797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyString_FromStringAndSize("SHA1", 4);
4807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyGetSetDef SHA_getseters[] = {
4837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"digest_size",
4847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (getter)SHA_get_digest_size, NULL,
4857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     NULL,
4867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     NULL},
4877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"block_size",
4887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (getter)SHA_get_block_size, NULL,
4897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     NULL,
4907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     NULL},
4917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"name",
4927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (getter)SHA_get_name, NULL,
4937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     NULL,
4947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     NULL},
4957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* the old md5 and sha modules support 'digest_size' as in PEP 247.
4967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     * the old sha module also supported 'digestsize'.  ugh. */
4977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"digestsize",
4987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (getter)SHA_get_digest_size, NULL,
4997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     NULL,
5007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     NULL},
5017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {NULL}  /* Sentinel */
5027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
5037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyTypeObject SHAtype = {
5057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyVarObject_HEAD_INIT(NULL, 0)
5067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    "_sha.sha",         /*tp_name*/
5077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sizeof(SHAobject),  /*tp_size*/
5087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_itemsize*/
5097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* methods */
5107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHA_dealloc,        /*tp_dealloc*/
5117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_print*/
5127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_getattr*/
5137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_setattr*/
5147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_compare*/
5157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_repr*/
5167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_as_number*/
5177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_as_sequence*/
5187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_as_mapping*/
5197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_hash*/
5207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_call*/
5217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_str*/
5227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_getattro*/
5237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_setattro*/
5247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_as_buffer*/
5257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_TPFLAGS_DEFAULT, /*tp_flags*/
5267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_doc*/
5277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_traverse*/
5287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_clear*/
5297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_richcompare*/
5307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_weaklistoffset*/
5317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_iter*/
5327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /*tp_iternext*/
5337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHA_methods,        /* tp_methods */
5347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                  /* tp_members */
5357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHA_getseters,      /* tp_getset */
5367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
5377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* The single module-level function: new() */
5407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(SHA_new__doc__,
5427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Return a new SHA hashing object.  An optional string argument\n\
5437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielmay be provided; if present, this string will be automatically\n\
5447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielhashed.");
5457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
5477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielSHA_new(PyObject *self, PyObject *args, PyObject *kwdict)
5487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
5497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static char *kwlist[] = {"string", NULL};
5507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SHAobject *new;
5517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_buffer view = { 0 };
5527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t n;
5537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned char *buf;
5547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s*:new", kwlist,
5567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                     &view)) {
5577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
5587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if ((new = newSHAobject()) == NULL) {
5617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyBuffer_Release(&view);
5627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
5637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sha_init(new);
5667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyErr_Occurred()) {
5687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(new);
5697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyBuffer_Release(&view);
5707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
5717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    n = view.len;
5747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    buf = (unsigned char *) view.buf;
5757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    while (n > 0) {
5767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_ssize_t nbytes;
5777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (n > INT_MAX)
5787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            nbytes = INT_MAX;
5797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
5807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            nbytes = n;
5817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        sha_update(new, buf,
5827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   Py_SAFE_DOWNCAST(nbytes, Py_ssize_t, unsigned int));
5837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        buf += nbytes;
5847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        n -= nbytes;
5857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyBuffer_Release(&view);
5887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (PyObject *)new;
5907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
5917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* List of functions exported by this module */
5947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic struct PyMethodDef SHA_functions[] = {
5967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"new", (PyCFunction)SHA_new, METH_VARARGS|METH_KEYWORDS, SHA_new__doc__},
5977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {NULL,      NULL}            /* Sentinel */
5987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
5997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Initialize this module. */
6027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
6047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyMODINIT_FUNC
6067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielinit_sha(void)
6077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
6087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *m;
6097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_TYPE(&SHAtype) = &PyType_Type;
6117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyType_Ready(&SHAtype) < 0)
6127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return;
6137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    m = Py_InitModule("_sha", SHA_functions);
6147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (m == NULL)
6157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return;
6167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Add some symbolic constants to the module */
6187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    insint("blocksize", 1);  /* For future use, in case some hash
6197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                functions require an integral number of
6207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                blocks */
6217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    insint("digestsize", 20);
6227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    insint("digest_size", 20);
6237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
624