diff options
Diffstat (limited to 'vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp')
-rw-r--r-- | vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp | 345 |
1 files changed, 187 insertions, 158 deletions
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp index 97193849b..1830936f0 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp @@ -6,36 +6,124 @@ @license modified new BSD license http://opensource.org/licenses/BSD-3-Clause */ -#include <cybozu/endian.hpp> +#if !defined(CYBOZU_DONT_USE_OPENSSL) && !defined(MCL_DONT_USE_OPENSSL) + #define CYBOZU_USE_OPENSSL_SHA +#endif + #ifndef CYBOZU_DONT_USE_STRING -#include <cybozu/itoa.hpp> #include <string> #endif -#include <memory.h> -#include <assert.h> -namespace cybozu { +#ifdef CYBOZU_USE_OPENSSL_SHA +#ifdef __APPLE__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif +#include <openssl/sha.h> +#ifdef _MSC_VER + #include <cybozu/link_libeay32.hpp> +#endif -namespace sha2_local { +#ifdef __APPLE__ + #pragma GCC diagnostic pop +#endif -template<class T> -T min_(T x, T y) { return x < y ? x : y;; } +namespace cybozu { +class Sha256 { + SHA256_CTX ctx_; +public: + Sha256() + { + clear(); + } + void clear() + { + SHA256_Init(&ctx_); + } + void update(const void *buf, size_t bufSize) + { + SHA256_Update(&ctx_, buf, bufSize); + } + size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize) + { + if (mdSize < SHA256_DIGEST_LENGTH) return 0; + update(buf, bufSize); + SHA256_Final(reinterpret_cast<uint8_t*>(md), &ctx_); + return SHA256_DIGEST_LENGTH; + } #ifndef CYBOZU_DONT_USE_STRING -inline void uint32toHexStr(char *buf, const uint32_t *x, size_t n) -{ - for (size_t i = 0; i < n; i++) { - cybozu::itohex(buf + i * 8, 8, x[i], false); + void update(const std::string& buf) + { + update(buf.c_str(), buf.size()); } -} + std::string digest(const std::string& buf) + { + return digest(buf.c_str(), buf.size()); + } + std::string digest(const void *buf, size_t bufSize) + { + std::string md(SHA256_DIGEST_LENGTH, 0); + digest(&md[0], md.size(), buf, bufSize); + return md; + } +#endif +}; -inline void uint64toHexStr(char *buf, const uint64_t *x, size_t n) -{ - for (size_t i = 0; i < n; i++) { - cybozu::itohex(buf + i * 16, 16, x[i], false); +class Sha512 { + SHA512_CTX ctx_; +public: + Sha512() + { + clear(); + } + void clear() + { + SHA512_Init(&ctx_); + } + void update(const void *buf, size_t bufSize) + { + SHA512_Update(&ctx_, buf, bufSize); + } + size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize) + { + if (mdSize < SHA512_DIGEST_LENGTH) return 0; + update(buf, bufSize); + SHA512_Final(reinterpret_cast<uint8_t*>(md), &ctx_); + return SHA512_DIGEST_LENGTH; + } +#ifndef CYBOZU_DONT_USE_STRING + void update(const std::string& buf) + { + update(buf.c_str(), buf.size()); + } + std::string digest(const std::string& buf) + { + return digest(buf.c_str(), buf.size()); + } + std::string digest(const void *buf, size_t bufSize) + { + std::string md(SHA512_DIGEST_LENGTH, 0); + digest(&md[0], md.size(), buf, bufSize); + return md; } -} #endif +}; + +} // cybozu + +#else + +#include <cybozu/endian.hpp> +#include <memory.h> +#include <assert.h> + +namespace cybozu { + +namespace sha2_local { + +template<class T> +T min_(T x, T y) { return x < y ? x : y;; } inline uint32_t rot32(uint32_t x, int s) { @@ -55,12 +143,64 @@ inline uint64_t rot64(uint64_t x, int s) #endif } +template<class T> +struct Common { + void term(const char *buf, size_t bufSize) + { + assert(bufSize < T::blockSize_); + T& self = static_cast<T&>(*this); + const uint64_t totalSize = self.totalSize_ + bufSize; + + uint8_t last[T::blockSize_]; + memcpy(last, buf, bufSize); + last[bufSize] = uint8_t(0x80); /* top bit = 1 */ + memset(&last[bufSize + 1], 0, T::blockSize_ - bufSize - 1); + if (bufSize >= T::blockSize_ - T::msgLenByte_) { + self.round(reinterpret_cast<const char*>(last)); + memset(last, 0, sizeof(last)); // clear stack + } + cybozu::Set64bitAsBE(&last[T::blockSize_ - 8], totalSize * 8); + self.round(reinterpret_cast<const char*>(last)); + } + void inner_update(const char *buf, size_t bufSize) + { + T& self = static_cast<T&>(*this); + if (bufSize == 0) return; + if (self.roundBufSize_ > 0) { + size_t size = sha2_local::min_(T::blockSize_ - self.roundBufSize_, bufSize); + memcpy(self.roundBuf_ + self.roundBufSize_, buf, size); + self.roundBufSize_ += size; + buf += size; + bufSize -= size; + } + if (self.roundBufSize_ == T::blockSize_) { + self.round(self.roundBuf_); + self.roundBufSize_ = 0; + } + while (bufSize >= T::blockSize_) { + assert(self.roundBufSize_ == 0); + self.round(buf); + buf += T::blockSize_; + bufSize -= T::blockSize_; + } + if (bufSize > 0) { + assert(bufSize < T::blockSize_); + assert(self.roundBufSize_ == 0); + memcpy(self.roundBuf_, buf, bufSize); + self.roundBufSize_ = bufSize; + } + assert(self.roundBufSize_ < T::blockSize_); + } +}; + } // cybozu::sha2_local -class Sha256 { +class Sha256 : public sha2_local::Common<Sha256> { + friend struct sha2_local::Common<Sha256>; private: static const size_t blockSize_ = 64; static const size_t hSize_ = 8; + static const size_t msgLenByte_ = 8; uint64_t totalSize_; size_t roundBufSize_; char roundBuf_[blockSize_]; @@ -117,38 +257,13 @@ private: h_[5] += f; h_[6] += g; h_[7] += h; - totalSize_ += 64; - } - /* - final phase - */ - void term(const char *buf, size_t bufSize) - { - assert(bufSize < blockSize_); - const uint64_t totalSize = totalSize_ + bufSize; - - uint8_t last[blockSize_]; - memcpy(last, buf, bufSize); - memset(&last[bufSize], 0, blockSize_ - bufSize); - last[bufSize] = uint8_t(0x80); /* top bit = 1 */ - if (bufSize >= blockSize_ - 8) { - round(reinterpret_cast<const char*>(last)); - memset(last, 0, sizeof(last)); // clear stack - } - cybozu::Set32bitAsBE(&last[56], uint32_t(totalSize >> 29)); - cybozu::Set32bitAsBE(&last[60], uint32_t(totalSize * 8)); - round(reinterpret_cast<const char*>(last)); + totalSize_ += blockSize_; } public: Sha256() { clear(); } - Sha256(const void *buf, size_t bufSize) - { - clear(); - digest(buf, bufSize); - } void clear() { static const uint32_t kTbl[] = { @@ -173,43 +288,16 @@ public: h_[6] = 0x1f83d9ab; h_[7] = 0x5be0cd19; } - void update(const void *buf_, size_t bufSize) + void update(const void *buf, size_t bufSize) { - const char *buf = reinterpret_cast<const char*>(buf_); - if (bufSize == 0) return; - if (roundBufSize_ > 0) { - size_t size = sha2_local::min_(blockSize_ - roundBufSize_, bufSize); - memcpy(roundBuf_ + roundBufSize_, buf, size); - roundBufSize_ += size; - buf += size; - bufSize -= size; - } - if (roundBufSize_ == blockSize_) { - round(roundBuf_); - roundBufSize_ = 0; - } - while (bufSize >= blockSize_) { - assert(roundBufSize_ == 0); - round(buf); - buf += blockSize_; - bufSize -= blockSize_; - } - if (bufSize > 0) { - assert(bufSize < blockSize_); - assert(roundBufSize_ == 0); - memcpy(roundBuf_, buf, bufSize); - roundBufSize_ = bufSize; - } - assert(roundBufSize_ < blockSize_); + inner_update(reinterpret_cast<const char*>(buf), bufSize); } - void digest(const void *buf, size_t bufSize) + size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize) { + if (mdSize < outByteSize_) return 0; update(buf, bufSize); term(roundBuf_, roundBufSize_); - } - size_t get(void *out) const - { - char *p = reinterpret_cast<char*>(out); + char *p = reinterpret_cast<char*>(md); for (size_t i = 0; i < hSize_; i++) { cybozu::Set32bitAsBE(&p[i * sizeof(h_[0])], h_[i]); } @@ -220,29 +308,25 @@ public: { update(buf.c_str(), buf.size()); } - void digest(const std::string& str = "") + std::string digest(const std::string& buf) { - digest(str.c_str(), str.size()); + return digest(buf.c_str(), buf.size()); } - std::string get() const + std::string digest(const void *buf, size_t bufSize) { - char out[outByteSize_]; - get(out); - return std::string(out, sizeof(out)); - } - std::string toHexStr() const - { - char buf[outByteSize_ * 2]; - sha2_local::uint32toHexStr(buf, h_, hSize_); - return std::string(buf, sizeof(buf)); + std::string md(outByteSize_, 0); + digest(&md[0], md.size(), buf, bufSize); + return md; } #endif }; -class Sha512 { +class Sha512 : public sha2_local::Common<Sha512> { + friend struct sha2_local::Common<Sha512>; private: static const size_t blockSize_ = 128; static const size_t hSize_ = 8; + static const size_t msgLenByte_ = 16; uint64_t totalSize_; size_t roundBufSize_; char roundBuf_[blockSize_]; @@ -308,35 +392,11 @@ private: } totalSize_ += blockSize_; } - /* - final phase - */ - void term(const char *buf, size_t bufSize) - { - assert(bufSize < blockSize_); - const uint64_t totalSize = totalSize_ + bufSize; - - uint8_t last[blockSize_]; - memcpy(last, buf, bufSize); - memset(&last[bufSize], 0, blockSize_ - bufSize); - last[bufSize] = uint8_t(0x80); /* top bit = 1 */ - if (bufSize >= blockSize_ - 16) { - round(reinterpret_cast<const char*>(last)); - memset(last, 0, sizeof(last)); // clear stack - } - cybozu::Set64bitAsBE(&last[blockSize_ - 8], totalSize * 8); - round(reinterpret_cast<const char*>(last)); - } public: Sha512() { clear(); } - Sha512(const void *buf, size_t bufSize) - { - clear(); - digest(buf, bufSize); - } void clear() { static const uint64_t kTbl[] = { @@ -369,70 +429,39 @@ public: h_[6] = 0x1f83d9abfb41bd6bull; h_[7] = 0x5be0cd19137e2179ull; } - void update(const void *buf_, size_t bufSize) + void update(const void *buf, size_t bufSize) { - const char *buf = reinterpret_cast<const char*>(buf_); - if (bufSize == 0) return; - if (roundBufSize_ > 0) { - size_t size = sha2_local::min_(blockSize_ - roundBufSize_, bufSize); - memcpy(roundBuf_ + roundBufSize_, buf, size); - roundBufSize_ += size; - buf += size; - bufSize -= size; - } - if (roundBufSize_ == blockSize_) { - round(roundBuf_); - roundBufSize_ = 0; - } - while (bufSize >= blockSize_) { - assert(roundBufSize_ == 0); - round(buf); - buf += blockSize_; - bufSize -= blockSize_; - } - if (bufSize > 0) { - assert(bufSize < blockSize_); - assert(roundBufSize_ == 0); - memcpy(roundBuf_, buf, bufSize); - roundBufSize_ = bufSize; - } - assert(roundBufSize_ < blockSize_); + inner_update(reinterpret_cast<const char*>(buf), bufSize); } - void digest(const void *buf, size_t bufSize) + size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize) { + if (mdSize < outByteSize_) return 0; update(buf, bufSize); term(roundBuf_, roundBufSize_); - } - size_t get(void *out) const - { - char *p = reinterpret_cast<char*>(out); + char *p = reinterpret_cast<char*>(md); for (size_t i = 0; i < hSize_; i++) { cybozu::Set64bitAsBE(&p[i * sizeof(h_[0])], h_[i]); } return outByteSize_; } #ifndef CYBOZU_DONT_USE_STRING - void digest(const std::string& str = "") - { - digest(str.c_str(), str.size()); - } void update(const std::string& buf) { update(buf.c_str(), buf.size()); } - std::string get() const + std::string digest(const std::string& buf) { - char out[outByteSize_]; - get(out); - return std::string(out, sizeof(out)); + return digest(buf.c_str(), buf.size()); } - std::string toHexStr() const + std::string digest(const void *buf, size_t bufSize) { - char buf[outByteSize_ * 2]; - sha2_local::uint64toHexStr(buf, h_, hSize_); - return std::string(buf, sizeof(buf)); + std::string md(outByteSize_, 0); + digest(&md[0], md.size(), buf, bufSize); + return md; } #endif }; } // cybozu + +#endif |