edouard@3940: /* MD5
edouard@3940: 
edouard@3940:     Modified in 2024 for use in Beremiz by Edouard Tisserant
edouard@3940: 
edouard@3940:     converted to C++ class by Frank Thilo (thilo@unix-ag.org)
edouard@3940:     for bzflag (http://www.bzflag.org)
edouard@3940: 
edouard@3940:     based on:
edouard@3940: 
edouard@3940:     md5.h and md5.c
edouard@3940:     reference implementation of RFC 1321
edouard@3940: 
edouard@3940:     Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
edouard@3940: rights reserved.
edouard@3940: 
edouard@3940: License to copy and use this software is granted provided that it
edouard@3940: is identified as the "RSA Data Security, Inc. MD5 Message-Digest
edouard@3940: Algorithm" in all material mentioning or referencing this software
edouard@3940: or this function.
edouard@3940: 
edouard@3940: License is also granted to make and use derivative works provided
edouard@3940: that such works are identified as "derived from the RSA Data
edouard@3940: Security, Inc. MD5 Message-Digest Algorithm" in all material
edouard@3940: mentioning or referencing the derived work.
edouard@3940: 
edouard@3940: RSA Data Security, Inc. makes no representations concerning either
edouard@3940: the merchantability of this software or the suitability of this
edouard@3940: software for any particular purpose. It is provided "as is"
edouard@3940: without express or implied warranty of any kind.
edouard@3940: 
edouard@3940: These notices must be retained in any copies of any part of this
edouard@3940: documentation and/or software.
edouard@3940: 
edouard@3940: */
edouard@3940: 
edouard@3940: #ifndef BZF_MD5_H
edouard@3940: #define BZF_MD5_H
edouard@3940: 
edouard@3940: #include <cstdint>
edouard@3940: 
edouard@3940: // a small class for calculating MD5 hashes of strings or byte arrays
edouard@3940: // it is not meant to be fast or secure
edouard@3940: //
edouard@3940: // usage: 1) feed it blocks of uchars with update()
edouard@3940: //        2) get digest() data
edouard@3940: //
edouard@3940: // assumes that char is 8 bit and int is 32 bit
edouard@3940: class MD5
edouard@3940: {
edouard@3940: public:
edouard@3940:     typedef unsigned int size_type; // must be 32bit
edouard@3940: 
edouard@3940:     MD5();
edouard@3940:     void update(const unsigned char *buf, size_type length);
edouard@3940:     typedef struct {
edouard@3940:         uint8_t data[16];
edouard@3940:     } digest_t;
edouard@3940:     digest_t digest();
edouard@3940:     enum
edouard@3940:     {
edouard@3940:         blocksize = 64,
edouard@3940:         digestsize = 16
edouard@3940:     };    
edouard@3940: 
edouard@3940: private:
edouard@3940:     void init();
edouard@3940: 
edouard@3940:     void transform(const uint8_t block[blocksize]);
edouard@3940:     static void decode(uint32_t output[], const uint8_t input[], size_type len);
edouard@3940:     static void encode(uint8_t output[], const uint32_t input[], size_type len);
edouard@3940:     
edouard@3940:     uint8_t buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk
edouard@3940:     uint32_t count[2];          // 64bit counter for number of bits (lo, hi)
edouard@3940:     uint32_t state[4];          // digest so far
edouard@3940: 
edouard@3940:     // low level logic operations
edouard@3940:     static inline uint32_t F(uint32_t x, uint32_t y, uint32_t z);
edouard@3940:     static inline uint32_t G(uint32_t x, uint32_t y, uint32_t z);
edouard@3940:     static inline uint32_t H(uint32_t x, uint32_t y, uint32_t z);
edouard@3940:     static inline uint32_t I(uint32_t x, uint32_t y, uint32_t z);
edouard@3940:     static inline uint32_t rotate_left(uint32_t x, int n);
edouard@3940:     static inline void FF(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac);
edouard@3940:     static inline void GG(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac);
edouard@3940:     static inline void HH(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac);
edouard@3940:     static inline void II(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac);
edouard@3940: };
edouard@3940: 
edouard@3940: #endif