1 #ifndef SHA1_H_
2 #define SHA1_H_
3 
4 /*
5    SHA-1 in C
6    By Steve Reid <steve@edmweb.com>
7    100% Public Domain
8 
9    small edits for cado-nfs by E. Thomé. Still PD.
10  */
11 
12 #include <stdint.h>
13 
14 typedef struct
15 {
16     uint32_t state[5];
17     uint32_t count[2];
18     unsigned char buffer[64];
19 } SHA1_CTX;
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]);
26 void SHA1Init(SHA1_CTX * context);
27 void SHA1Update(SHA1_CTX * context, const unsigned char *data, uint32_t len);
28 void SHA1Final(unsigned char digest[20], SHA1_CTX * context);
29 void SHA1(char *hash_out, const char *str, int len);
30 
31 #ifdef __cplusplus
32 }
33 #endif
34 
35 /* end "SHA-1 in C" PD interface */
36 
37 #ifdef __cplusplus
38 #include <streambuf>
39 #include <ostream>
40 /* mock streambuf implementation that just computes the sha-1 sum of what
41  * it gets fed.
42  *
43  * idea of hacking around streambufs picked from
44  * http://wordaligned.org/articles/cpp-streambufs (PD)
45  *
46  */
47 template <typename char_type,
48           typename traits = std::char_traits<char_type> >
49 class sha1_checksumming_streambuf: public std::basic_streambuf<char_type, traits>
50 {
51     SHA1_CTX ctx;
52 public:
53     typedef typename traits::int_type int_type;
sha1_checksumming_streambuf()54     sha1_checksumming_streambuf() { SHA1Init(&ctx); }
checksum(char out[41])55     void checksum(char out[41])
56     {
57         SHA1_CTX ctx1;
58         memcpy(&ctx1, &ctx, sizeof(SHA1_CTX));
59         uint8_t dest[20];
60         SHA1Final(dest, &ctx1);
61         for(int i = 0 ; i < 20 ; i++)
62             snprintf(out + 2*i, 3, "%02x", (unsigned int) dest[i]);
63     }
64 private:
overflow(int_type c)65     virtual int_type overflow(int_type c) {
66         if (traits::eq_int_type(c, traits::eof()))
67             return traits::not_eof(c);
68         char_type const ch = traits::to_char_type(c);
69         SHA1Update(&ctx, (unsigned char*) &ch, sizeof(char_type));
70         return c;
71     }
72 };
73 
74 class sha1_checksumming_stream : public std::ostream
75 {
76     sha1_checksumming_streambuf<char> cbuf;
77 public:
sha1_checksumming_stream()78     sha1_checksumming_stream() : std::ostream(&cbuf) {}
checksum(char out[41])79     void checksum(char out[41]) { cbuf.checksum(out); }
80 };
81 #endif
82 
83 
84 #endif	/* SHA1_H_ */
85 
86