【botan源码阅读】MD结构源码阅读

admin 2022年11月13日16:39:59安全开发评论5 views31672字阅读105分34秒阅读模式

【botan源码阅读】MD结构源码阅读

【botan源码阅读】MD结构源码阅读

山有木兮木有枝,心悦君兮君不知。——《越人歌》

这里建议,如果说没有看过那篇MD5解析的读者先看一下上一篇文章,这里重复的内容就不再次解读了。这一篇文章呢,我们会来直接解读在源码当中试用过Merkle-Damgård 结构的一系列哈希函数,因为他们本身的结构都是相似的,所以干脆就在一块讲了,主要涉及到的源码目录如下:

src/lib/hash/md4
src/lib/hash/rmd160
src/lib/hash/sha1
src/lib/hash/sha2_32
src/lib/hash/sha2_64
src/lib/hash/sm3
src/lib/hash/whirlpool

MD4

我们来看,这里和md5不一样的地方,核心的分析点还是在于压缩函数上。

/*
* MD4 Compression Function
*/

void MD4::compress_n(const uint8_t input[], size_t blocks)
   
{
   uint32_t A = m_digest[0], B = m_digest[1], C = m_digest[2], D = m_digest[3];

   for(size_t i = 0; i != blocks; ++i)
      {
      // 加载数据
      uint32_t M00 = load_le<uint32_t>(input, 0);
      uint32_t M01 = load_le<uint32_t>(input, 1);
      uint32_t M02 = load_le<uint32_t>(input, 2);
      uint32_t M03 = load_le<uint32_t>(input, 3);
      uint32_t M04 = load_le<uint32_t>(input, 4);
      uint32_t M05 = load_le<uint32_t>(input, 5);
      uint32_t M06 = load_le<uint32_t>(input, 6);
      uint32_t M07 = load_le<uint32_t>(input, 7);
      uint32_t M08 = load_le<uint32_t>(input, 8);
      uint32_t M09 = load_le<uint32_t>(input, 9);
      uint32_t M10 = load_le<uint32_t>(input, 10);
      uint32_t M11 = load_le<uint32_t>(input, 11);
      uint32_t M12 = load_le<uint32_t>(input, 12);
      uint32_t M13 = load_le<uint32_t>(input, 13);
      uint32_t M14 = load_le<uint32_t>(input, 14);
      uint32_t M15 = load_le<uint32_t>(input, 15);

      // 执行对应的压缩函数
      FF4(A, B, C, D, M00, M01, M02, M03);
      FF4(A, B, C, D, M04, M05, M06, M07);
      FF4(A, B, C, D, M08, M09, M10, M11);
      FF4(A, B, C, D, M12, M13, M14, M15);

      GG4(A, B, C, D, M00, M04, M08, M12);
      GG4(A, B, C, D, M01, M05, M09, M13);
      GG4(A, B, C, D, M02, M06, M10, M14);
      GG4(A, B, C, D, M03, M07, M11, M15);

      HH4(A, B, C, D, M00, M08, M04, M12);
      HH4(A, B, C, D, M02, M10, M06, M14);
      HH4(A, B, C, D, M01, M09, M05, M13);
      HH4(A, B, C, D, M03, M11, M07, M15);

      A = (m_digest[0] += A);
      B = (m_digest[1] += B);
      C = (m_digest[2] += C);
      D = (m_digest[3] += D);

      input += hash_block_size();
      }
   }

这个写法呢,看起来和上一篇有一点点的不同,似乎沿用md5的写法也没有什么问题,这里为什么要在加载的时候去分成了16个参数,这波操作诡异了,一波差点给我带走,如果按照原来md5的写法,我们很容易写出来下面的代码。

// md4.h
class MD4 final : public MDx_HashFunction {
public:
    size_t output_length() const override return 16; }

    void clear() override;

    MD4() : MDx_HashFunction(64falsetrue), m_M(16), m_digest(4) { clear(); }

private:
    void compress_n(const uint8_t input[], size_t blocks) override;

    void copy_out(uint8_t[]) override;


    /**
    * The message buffer
    */

    std::vector<uint32_t> m_M;

    /**
    * The digest value
    */

    std::vector<uint32_t> m_digest;
};
// md4.cpp
namespace {
    /*
    * MD4 FF Function
    */

    template<size_t S>
    inline void FF4(uint32_t &A, uint32_t B, uint32_t C, uint32_t D, uint32_t M) 
{
        A += choose(B, C, D) + M;
        A = rotl<S>(A);
    }

    /*
    * MD4 GG Function
    */

    template<size_t S>
    inline void GG4(uint32_t &A, uint32_t B, uint32_t C, uint32_t D, uint32_t M) 
{
        A += ((B & C) | (D & (B | C))) + M + 0x5A827999;
        A = rotl<S>(A);
    }

    /*
    * MD4 HH Function
    */

    template<size_t S>
    inline void HH4(uint32_t &A, uint32_t B, uint32_t C, uint32_t D, uint32_t M) 
{
        A += (B ^ C ^ D) + M + 0x6ED9EBA1;
        A = rotl<S>(A);
    }
}

#pragma clang diagnostic push
#pragma ide diagnostic ignored "ArgumentSelectionDefects"

/*
* MD4 Compression Function
*/

void MD4::compress_n(const uint8_t input[], size_t blocks) {
    uint32_t A = m_digest[0], B = m_digest[1], C = m_digest[2], D = m_digest[3];

    for (size_t i = 0; i != blocks; ++i) {
        load_le(m_M.data(), input, m_M.size());

        FF4<3>(A, B, C, D, m_M[0]);
        FF4<7>(D, A, B, C, m_M[1]);
        FF4<11>(C, D, A, B, m_M[2]);
        FF4<19>(B, C, D, A, m_M[3]);
        FF4<3>(A, B, C, D, m_M[4]);
        FF4<7>(D, A, B, C, m_M[5]);
        FF4<11>(C, D, A, B, m_M[6]);
        FF4<19>(B, C, D, A, m_M[7]);
        FF4<3>(A, B, C, D, m_M[8]);
        FF4<7>(D, A, B, C, m_M[9]);
        FF4<11>(C, D, A, B, m_M[10]);
        FF4<19>(B, C, D, A, m_M[11]);
        FF4<3>(A, B, C, D, m_M[12]);
        FF4<7>(D, A, B, C, m_M[13]);
        FF4<11>(C, D, A, B, m_M[14]);
        FF4<19>(B, C, D, A, m_M[15]);

        GG4<3>(A, B, C, D, m_M[0]);
        GG4<5>(D, A, B, C, m_M[4]);
        GG4<9>(C, D, A, B, m_M[8]);
        GG4<13>(B, C, D, A, m_M[12]);
        GG4<3>(A, B, C, D, m_M[1]);
        GG4<5>(D, A, B, C, m_M[5]);
        GG4<9>(C, D, A, B, m_M[9]);
        GG4<13>(B, C, D, A, m_M[13]);
        GG4<3>(A, B, C, D, m_M[2]);
        GG4<5>(D, A, B, C, m_M[6]);
        GG4<9>(C, D, A, B, m_M[10]);
        GG4<13>(B, C, D, A, m_M[14]);
        GG4<3>(A, B, C, D, m_M[3]);
        GG4<5>(D, A, B, C, m_M[7]);
        GG4<9>(C, D, A, B, m_M[11]);
        GG4<13>(B, C, D, A, m_M[15]);

        HH4<3>(A, B, C, D, m_M[0]);
        HH4<9>(D, A, B, C, m_M[8]);
        HH4<11>(C, D, A, B, m_M[4]);
        HH4<15>(B, C, D, A, m_M[12]);
        HH4<3>(A, B, C, D, m_M[2]);
        HH4<9>(D, A, B, C, m_M[10]);
        HH4<11>(C, D, A, B, m_M[6]);
        HH4<15>(B, C, D, A, m_M[14]);
        HH4<3>(A, B, C, D, m_M[1]);
        HH4<9>(D, A, B, C, m_M[9]);
        HH4<11>(C, D, A, B, m_M[5]);
        HH4<15>(B, C, D, A, m_M[13]);
        HH4<3>(A, B, C, D, m_M[3]);
        HH4<9>(D, A, B, C, m_M[11]);
        HH4<11>(C, D, A, B, m_M[7]);
        HH4<15>(B, C, D, A, m_M[15]);

        A = (m_digest[0] += A);
        B = (m_digest[1] += B);
        C = (m_digest[2] += C);
        D = (m_digest[3] += D);

        input += hash_block_size();
    }
}

#pragma clang diagnostic pop

/*
* Copy out the digest
*/

void MD4::copy_out(uint8_t output[]) {
    copy_out_vec_le(output, output_length(), m_digest);
}

/*
* Clear memory of sensitive data
*/

void MD4::clear() {
    MDx_HashFunction::clear();
    m_digest[0] = 0x67452301;
    m_digest[1] = 0xEFCDAB89;
    m_digest[2] = 0x98BADCFE;
    m_digest[3] = 0x10325476;
}


然后这就勾起了我的好奇心,为什么作者对于md4和md5的实现的方法大相径庭,然后我先看了下这这两部分的作者,发现提交者都是一位,并且时间也是相同的。

【botan源码阅读】MD结构源码阅读

这就很迷了,为什么作者会选择两种实现方案呢,实话说到本文之前我是没想明白,如果读者大佬们有什么好的看法,也欢迎和我交流。

好了,有关于md4的具体的压缩函数的设计,可以去参考下相关rfc或者我之前写过的文章,在这里不在展开来讲了。

RIPEMD-160

这个对于压缩函数的实现,看看起来就比较中规中矩了,目前没发现比较特别的写法,因此呢在这里不展开来聊了,有兴趣的读者可以自行阅读一下细节,在这里贴心的贴一下代码,防止读者不想打开对应的源码(才不是为了凑字数)。

/*
* RIPEMD-160
* (C) 1999-2007 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/


#include <botan/internal/rmd160.h>
#include <botan/internal/loadstor.h>
#include <botan/internal/rotate.h>
#include <botan/internal/bit_ops.h>

namespace Botan {

namespace {

/*
* RIPEMD-160 F1 Function
*/

template<size_t S>
inline void F1(uint32_t& A, uint32_t B, uint32_t& C, uint32_t D, uint32_t E,
               uint32_t M)

   
{
   A += (B ^ C ^ D) + M;
   A  = rotl<S>(A) + E;
   C  = rotl<10>(C);
   }

/*
* RIPEMD-160 F2 Function
*/

template<size_t S>
inline void F2(uint32_t& A, uint32_t B, uint32_t& C, uint32_t D, uint32_t E,
               uint32_t M)

   
{
   A += choose(B, C, D) + M;
   A  = rotl<S>(A) + E;
   C  = rotl<10>(C);
   }

/*
* RIPEMD-160 F3 Function
*/

template<size_t S>
inline void F3(uint32_t& A, uint32_t B, uint32_t& C, uint32_t D, uint32_t E,
               uint32_t M)

   
{
   A += (D ^ (B | ~C)) + M;
   A  = rotl<S>(A) + E;
   C  = rotl<10>(C);
   }

/*
* RIPEMD-160 F4 Function
*/

template<size_t S>
inline void F4(uint32_t& A, uint32_t B, uint32_t& C, uint32_t D, uint32_t E,
               uint32_t M)

   
{
   A += choose(D, B, C) + M;
   A  = rotl<S>(A) + E;
   C  = rotl<10>(C);
   }

/*
* RIPEMD-160 F5 Function
*/

template<size_t S>
inline void F5(uint32_t& A, uint32_t B, uint32_t& C, uint32_t D, uint32_t E,
               uint32_t M)

   
{
   A += (B ^ (C | ~D)) + M;
   A  = rotl<S>(A) + E;
   C  = rotl<10>(C);
   }

}

/*
* RIPEMD-160 Compression Function
*/

void RIPEMD_160::compress_n(const uint8_t input[], size_t blocks)
   
{
   const uint32_t MAGIC2 = 0x5A827999, MAGIC3 = 0x6ED9EBA1,
                  MAGIC4 = 0x8F1BBCDC, MAGIC5 = 0xA953FD4E,
                  MAGIC6 = 0x50A28BE6, MAGIC7 = 0x5C4DD124,
                  MAGIC8 = 0x6D703EF3, MAGIC9 = 0x7A6D76E9;

   for(size_t i = 0; i != blocks; ++i)
      {
      load_le(m_M.data(), input, m_M.size());

      uint32_t A1 = m_digest[0], A2 = A1,
               B1 = m_digest[1], B2 = B1,
               C1 = m_digest[2], C2 = C1,
               D1 = m_digest[3], D2 = D1,
               E1 = m_digest[4], E2 = E1;

      F1<11>(A1,B1,C1,D1,E1,m_M[ 0]       );  F5< 8>(A2,B2,C2,D2,E2,m_M[ 5]+MAGIC6);
      F1<14>(E1,A1,B1,C1,D1,m_M[ 1]       );  F5< 9>(E2,A2,B2,C2,D2,m_M[14]+MAGIC6);
      F1<15>(D1,E1,A1,B1,C1,m_M[ 2]       );  F5< 9>(D2,E2,A2,B2,C2,m_M[ 7]+MAGIC6);
      F1<12>(C1,D1,E1,A1,B1,m_M[ 3]       );  F5<11>(C2,D2,E2,A2,B2,m_M[ 0]+MAGIC6);
      F1< 5>(B1,C1,D1,E1,A1,m_M[ 4]       );  F5<13>(B2,C2,D2,E2,A2,m_M[ 9]+MAGIC6);
      F1< 8>(A1,B1,C1,D1,E1,m_M[ 5]       );  F5<15>(A2,B2,C2,D2,E2,m_M[ 2]+MAGIC6);
      F1< 7>(E1,A1,B1,C1,D1,m_M[ 6]       );  F5<15>(E2,A2,B2,C2,D2,m_M[11]+MAGIC6);
      F1< 9>(D1,E1,A1,B1,C1,m_M[ 7]       );  F5< 5>(D2,E2,A2,B2,C2,m_M[ 4]+MAGIC6);
      F1<11>(C1,D1,E1,A1,B1,m_M[ 8]       );  F5< 7>(C2,D2,E2,A2,B2,m_M[13]+MAGIC6);
      F1<13>(B1,C1,D1,E1,A1,m_M[ 9]       );  F5< 7>(B2,C2,D2,E2,A2,m_M[ 6]+MAGIC6);
      F1<14>(A1,B1,C1,D1,E1,m_M[10]       );  F5< 8>(A2,B2,C2,D2,E2,m_M[15]+MAGIC6);
      F1<15>(E1,A1,B1,C1,D1,m_M[11]       );  F5<11>(E2,A2,B2,C2,D2,m_M[ 8]+MAGIC6);
      F1< 6>(D1,E1,A1,B1,C1,m_M[12]       );  F5<14>(D2,E2,A2,B2,C2,m_M[ 1]+MAGIC6);
      F1< 7>(C1,D1,E1,A1,B1,m_M[13]       );  F5<14>(C2,D2,E2,A2,B2,m_M[10]+MAGIC6);
      F1< 9>(B1,C1,D1,E1,A1,m_M[14]       );  F5<12>(B2,C2,D2,E2,A2,m_M[ 3]+MAGIC6);
      F1< 8>(A1,B1,C1,D1,E1,m_M[15]       );  F5< 6>(A2,B2,C2,D2,E2,m_M[12]+MAGIC6);

      F2< 7>(E1,A1,B1,C1,D1,m_M[ 7]+MAGIC2);  F4< 9>(E2,A2,B2,C2,D2,m_M[ 6]+MAGIC7);
      F2< 6>(D1,E1,A1,B1,C1,m_M[ 4]+MAGIC2);  F4<13>(D2,E2,A2,B2,C2,m_M[11]+MAGIC7);
      F2< 8>(C1,D1,E1,A1,B1,m_M[13]+MAGIC2);  F4<15>(C2,D2,E2,A2,B2,m_M[ 3]+MAGIC7);
      F2<13>(B1,C1,D1,E1,A1,m_M[ 1]+MAGIC2);  F4< 7>(B2,C2,D2,E2,A2,m_M[ 7]+MAGIC7);
      F2<11>(A1,B1,C1,D1,E1,m_M[10]+MAGIC2);  F4<12>(A2,B2,C2,D2,E2,m_M[ 0]+MAGIC7);
      F2< 9>(E1,A1,B1,C1,D1,m_M[ 6]+MAGIC2);  F4< 8>(E2,A2,B2,C2,D2,m_M[13]+MAGIC7);
      F2< 7>(D1,E1,A1,B1,C1,m_M[15]+MAGIC2);  F4< 9>(D2,E2,A2,B2,C2,m_M[ 5]+MAGIC7);
      F2<15>(C1,D1,E1,A1,B1,m_M[ 3]+MAGIC2);  F4<11>(C2,D2,E2,A2,B2,m_M[10]+MAGIC7);
      F2< 7>(B1,C1,D1,E1,A1,m_M[12]+MAGIC2);  F4< 7>(B2,C2,D2,E2,A2,m_M[14]+MAGIC7);
      F2<12>(A1,B1,C1,D1,E1,m_M[ 0]+MAGIC2);  F4< 7>(A2,B2,C2,D2,E2,m_M[15]+MAGIC7);
      F2<15>(E1,A1,B1,C1,D1,m_M[ 9]+MAGIC2);  F4<12>(E2,A2,B2,C2,D2,m_M[ 8]+MAGIC7);
      F2< 9>(D1,E1,A1,B1,C1,m_M[ 5]+MAGIC2);  F4< 7>(D2,E2,A2,B2,C2,m_M[12]+MAGIC7);
      F2<11>(C1,D1,E1,A1,B1,m_M[ 2]+MAGIC2);  F4< 6>(C2,D2,E2,A2,B2,m_M[ 4]+MAGIC7);
      F2< 7>(B1,C1,D1,E1,A1,m_M[14]+MAGIC2);  F4<15>(B2,C2,D2,E2,A2,m_M[ 9]+MAGIC7);
      F2<13>(A1,B1,C1,D1,E1,m_M[11]+MAGIC2);  F4<13>(A2,B2,C2,D2,E2,m_M[ 1]+MAGIC7);
      F2<12>(E1,A1,B1,C1,D1,m_M[ 8]+MAGIC2);  F4<11>(E2,A2,B2,C2,D2,m_M[ 2]+MAGIC7);

      F3<11>(D1,E1,A1,B1,C1,m_M[ 3]+MAGIC3);  F3< 9>(D2,E2,A2,B2,C2,m_M[15]+MAGIC8);
      F3<13>(C1,D1,E1,A1,B1,m_M[10]+MAGIC3);  F3< 7>(C2,D2,E2,A2,B2,m_M[ 5]+MAGIC8);
      F3< 6>(B1,C1,D1,E1,A1,m_M[14]+MAGIC3);  F3<15>(B2,C2,D2,E2,A2,m_M[ 1]+MAGIC8);
      F3< 7>(A1,B1,C1,D1,E1,m_M[ 4]+MAGIC3);  F3<11>(A2,B2,C2,D2,E2,m_M[ 3]+MAGIC8);
      F3<14>(E1,A1,B1,C1,D1,m_M[ 9]+MAGIC3);  F3< 8>(E2,A2,B2,C2,D2,m_M[ 7]+MAGIC8);
      F3< 9>(D1,E1,A1,B1,C1,m_M[15]+MAGIC3);  F3< 6>(D2,E2,A2,B2,C2,m_M[14]+MAGIC8);
      F3<13>(C1,D1,E1,A1,B1,m_M[ 8]+MAGIC3);  F3< 6>(C2,D2,E2,A2,B2,m_M[ 6]+MAGIC8);
      F3<15>(B1,C1,D1,E1,A1,m_M[ 1]+MAGIC3);  F3<14>(B2,C2,D2,E2,A2,m_M[ 9]+MAGIC8);
      F3<14>(A1,B1,C1,D1,E1,m_M[ 2]+MAGIC3);  F3<12>(A2,B2,C2,D2,E2,m_M[11]+MAGIC8);
      F3< 8>(E1,A1,B1,C1,D1,m_M[ 7]+MAGIC3);  F3<13>(E2,A2,B2,C2,D2,m_M[ 8]+MAGIC8);
      F3<13>(D1,E1,A1,B1,C1,m_M[ 0]+MAGIC3);  F3< 5>(D2,E2,A2,B2,C2,m_M[12]+MAGIC8);
      F3< 6>(C1,D1,E1,A1,B1,m_M[ 6]+MAGIC3);  F3<14>(C2,D2,E2,A2,B2,m_M[ 2]+MAGIC8);
      F3< 5>(B1,C1,D1,E1,A1,m_M[13]+MAGIC3);  F3<13>(B2,C2,D2,E2,A2,m_M[10]+MAGIC8);
      F3<12>(A1,B1,C1,D1,E1,m_M[11]+MAGIC3);  F3<13>(A2,B2,C2,D2,E2,m_M[ 0]+MAGIC8);
      F3< 7>(E1,A1,B1,C1,D1,m_M[ 5]+MAGIC3);  F3< 7>(E2,A2,B2,C2,D2,m_M[ 4]+MAGIC8);
      F3< 5>(D1,E1,A1,B1,C1,m_M[12]+MAGIC3);  F3< 5>(D2,E2,A2,B2,C2,m_M[13]+MAGIC8);

      F4<11>(C1,D1,E1,A1,B1,m_M[ 1]+MAGIC4);  F2<15>(C2,D2,E2,A2,B2,m_M[ 8]+MAGIC9);
      F4<12>(B1,C1,D1,E1,A1,m_M[ 9]+MAGIC4);  F2< 5>(B2,C2,D2,E2,A2,m_M[ 6]+MAGIC9);
      F4<14>(A1,B1,C1,D1,E1,m_M[11]+MAGIC4);  F2< 8>(A2,B2,C2,D2,E2,m_M[ 4]+MAGIC9);
      F4<15>(E1,A1,B1,C1,D1,m_M[10]+MAGIC4);  F2<11>(E2,A2,B2,C2,D2,m_M[ 1]+MAGIC9);
      F4<14>(D1,E1,A1,B1,C1,m_M[ 0]+MAGIC4);  F2<14>(D2,E2,A2,B2,C2,m_M[ 3]+MAGIC9);
      F4<15>(C1,D1,E1,A1,B1,m_M[ 8]+MAGIC4);  F2<14>(C2,D2,E2,A2,B2,m_M[11]+MAGIC9);
      F4< 9>(B1,C1,D1,E1,A1,m_M[12]+MAGIC4);  F2< 6>(B2,C2,D2,E2,A2,m_M[15]+MAGIC9);
      F4< 8>(A1,B1,C1,D1,E1,m_M[ 4]+MAGIC4);  F2<14>(A2,B2,C2,D2,E2,m_M[ 0]+MAGIC9);
      F4< 9>(E1,A1,B1,C1,D1,m_M[13]+MAGIC4);  F2< 6>(E2,A2,B2,C2,D2,m_M[ 5]+MAGIC9);
      F4<14>(D1,E1,A1,B1,C1,m_M[ 3]+MAGIC4);  F2< 9>(D2,E2,A2,B2,C2,m_M[12]+MAGIC9);
      F4< 5>(C1,D1,E1,A1,B1,m_M[ 7]+MAGIC4);  F2<12>(C2,D2,E2,A2,B2,m_M[ 2]+MAGIC9);
      F4< 6>(B1,C1,D1,E1,A1,m_M[15]+MAGIC4);  F2< 9>(B2,C2,D2,E2,A2,m_M[13]+MAGIC9);
      F4< 8>(A1,B1,C1,D1,E1,m_M[14]+MAGIC4);  F2<12>(A2,B2,C2,D2,E2,m_M[ 9]+MAGIC9);
      F4< 6>(E1,A1,B1,C1,D1,m_M[ 5]+MAGIC4);  F2< 5>(E2,A2,B2,C2,D2,m_M[ 7]+MAGIC9);
      F4< 5>(D1,E1,A1,B1,C1,m_M[ 6]+MAGIC4);  F2<15>(D2,E2,A2,B2,C2,m_M[10]+MAGIC9);
      F4<12>(C1,D1,E1,A1,B1,m_M[ 2]+MAGIC4);  F2< 8>(C2,D2,E2,A2,B2,m_M[14]+MAGIC9);

      F5< 9>(B1,C1,D1,E1,A1,m_M[ 4]+MAGIC5);  F1< 8>(B2,C2,D2,E2,A2,m_M[12]       );
      F5<15>(A1,B1,C1,D1,E1,m_M[ 0]+MAGIC5);  F1< 5>(A2,B2,C2,D2,E2,m_M[15]       );
      F5< 5>(E1,A1,B1,C1,D1,m_M[ 5]+MAGIC5);  F1<12>(E2,A2,B2,C2,D2,m_M[10]       );
      F5<11>(D1,E1,A1,B1,C1,m_M[ 9]+MAGIC5);  F1< 9>(D2,E2,A2,B2,C2,m_M[ 4]       );
      F5< 6>(C1,D1,E1,A1,B1,m_M[ 7]+MAGIC5);  F1<12>(C2,D2,E2,A2,B2,m_M[ 1]       );
      F5< 8>(B1,C1,D1,E1,A1,m_M[12]+MAGIC5);  F1< 5>(B2,C2,D2,E2,A2,m_M[ 5]       );
      F5<13>(A1,B1,C1,D1,E1,m_M[ 2]+MAGIC5);  F1<14>(A2,B2,C2,D2,E2,m_M[ 8]       );
      F5<12>(E1,A1,B1,C1,D1,m_M[10]+MAGIC5);  F1< 6>(E2,A2,B2,C2,D2,m_M[ 7]       );
      F5< 5>(D1,E1,A1,B1,C1,m_M[14]+MAGIC5);  F1< 8>(D2,E2,A2,B2,C2,m_M[ 6]       );
      F5<12>(C1,D1,E1,A1,B1,m_M[ 1]+MAGIC5);  F1<13>(C2,D2,E2,A2,B2,m_M[ 2]       );
      F5<13>(B1,C1,D1,E1,A1,m_M[ 3]+MAGIC5);  F1< 6>(B2,C2,D2,E2,A2,m_M[13]       );
      F5<14>(A1,B1,C1,D1,E1,m_M[ 8]+MAGIC5);  F1< 5>(A2,B2,C2,D2,E2,m_M[14]       );
      F5<11>(E1,A1,B1,C1,D1,m_M[11]+MAGIC5);  F1<15>(E2,A2,B2,C2,D2,m_M[ 0]       );
      F5< 8>(D1,E1,A1,B1,C1,m_M[ 6]+MAGIC5);  F1<13>(D2,E2,A2,B2,C2,m_M[ 3]       );
      F5< 5>(C1,D1,E1,A1,B1,m_M[15]+MAGIC5);  F1<11>(C2,D2,E2,A2,B2,m_M[ 9]       );
      F5< 6>(B1,C1,D1,E1,A1,m_M[13]+MAGIC5);  F1<11>(B2,C2,D2,E2,A2,m_M[11]       );

      C1          = m_digest[1] + C1 + D2;
      m_digest[1] = m_digest[2] + D1 + E2;
      m_digest[2] = m_digest[3] + E1 + A2;
      m_digest[3] = m_digest[4] + A1 + B2;
      m_digest[4] = m_digest[0] + B1 + C2;
      m_digest[0] = C1;

      input += hash_block_size();
      }
   }

/*
* Copy out the digest
*/

void RIPEMD_160::copy_out(uint8_t output[])
   
{
   copy_out_vec_le(output, output_length(), m_digest);
   }

/*
* Clear memory of sensitive data
*/

void RIPEMD_160::clear()
   
{
   MDx_HashFunction::clear();
   zeroise(m_M);
   m_digest[0] = 0x67452301;
   m_digest[1] = 0xEFCDAB89;
   m_digest[2] = 0x98BADCFE;
   m_digest[3] = 0x10325476;
   m_digest[4] = 0xC3D2E1F0;
   }

}

SHA1

我们接着来看下一个md结构的的哈希函数,这个就不展开讲具体的压缩函数的设计了,说一下这块和之前我们看过的md5以及md4的一个不同,我们来看一下头文件,这里多了一个汇编的写法,如果是开启了对应的处理器指令,则会走对应的汇编,由于汇编不再本系列源码解析的范畴之内,因此呢咱们直接去看对应的软件实现,所以后文如果牵扯到有关汇编的写法,这里会直接给略过,不再展开来讲了。

// 路径: src/lib/hash/sha1/sha160.h
/*
* SHA-160
* (C) 1999-2007,2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/


#ifndef BOTAN_SHA_160_H_
#define BOTAN_SHA_160_H_

#include <botan/internal/mdx_hash.h>

namespace Botan {

/**
* NIST's SHA-160
*/

class SHA_160 final : public MDx_HashFunction
   {
   public:
      std::string name() const override return "SHA-160"; }
      size_t output_length() const override return 20; }
      std::unique_ptr<HashFunction> new_object() const override return std::make_unique<SHA_160>(); }
      std::unique_ptr<HashFunction> copy_state() const override;

      void clear() override;

      SHA_160() : MDx_HashFunction(64truetrue), m_digest(5)
         {
         clear();
         }

   private:
      void compress_n(const uint8_t[], size_t blocks) override;
// 这里因为有了汇编的写法,因此如果开启汇编的话,会走汇编的流程
#if defined(BOTAN_HAS_SHA1_ARMV8)
      static void sha1_armv8_compress_n(secure_vector<uint32_t>& digest,
                                        const uint8_t blocks[],
                                        size_t block_count)
;
#endif

#if defined(BOTAN_HAS_SHA1_SSE2)
      static void sse2_compress_n(secure_vector<uint32_t>& digest,
                                  const uint8_t blocks[],
                                  size_t block_count)
;
#endif

#if defined(BOTAN_HAS_SHA1_X86_SHA_NI)
      // Using x86 SHA instructions in Intel Goldmont and Cannonlake
      static void sha1_compress_x86(secure_vector<uint32_t>& digest,
                                    const uint8_t blocks[],
                                    size_t block_count)
;
#endif


      void copy_out(uint8_t[]) override;

      /**
      * The digest value
      */

      secure_vector<uint32_t> m_digest;

      /**
      * The message buffer
      */

      secure_vector<uint32_t> m_W;
   };

typedef SHA_160 SHA_1;

}

#endif

剩下的就不介绍了,压缩函数具体的内容在源码阅读当中就不展开来讲了,不熟悉的读者可以参考rfc

SHA2

熟悉sha2系列算法的读者应该清楚,对于sha2系列算法可以根据输出长度分为两类,第一类是SHA224和SHA256,第二类是SHA384和SHA512,他们所采用的缓冲区的大小不同,前者是32位后者是64位,因此我们可以看到在botan对于这个的实现当中也是分为两类来实现的,因为本身的结构是一样的,只不过是buffer和表以及初始化向量有所不同,因此呢,咱们只以32位为例来看一下,对于64位实际上和32位的代码是几乎一样的。

/*
* SHA-{224,256}
* (C) 1999-2011 Jack Lloyd
*     2007 FlexSecure GmbH
*
* Botan is released under the Simplified BSD License (see license.txt)
*/


#ifndef BOTAN_SHA_224_256_H_
#define BOTAN_SHA_224_256_H_

#include <botan/internal/mdx_hash.h>

namespace Botan {

/**
* SHA-224
*/

class SHA_224 final : public MDx_HashFunction
   {
   public:
      std::string name() const override return "SHA-224"; }
      size_t output_length() const override return 28; }
      std::unique_ptr<HashFunction> new_object() const override return std::make_unique<SHA_224>(); }
      std::unique_ptr<HashFunction> copy_state() const override;

      void clear() override;

      std::string provider() const override;

      SHA_224() : MDx_HashFunction(64truetrue), m_digest(8)
         { clear(); }
   private:
      void compress_n(const uint8_t[], size_t blocks) override;
      void copy_out(uint8_t[]) override;

      secure_vector<uint32_t> m_digest;
   };

/**
* SHA-256
*/

class SHA_256 final : public MDx_HashFunction
   {
   public:
      std::string name() const override return "SHA-256"; }
      size_t output_length() const override return 32; }
      std::unique_ptr<HashFunction> new_object() const override return std::make_unique<SHA_256>(); }
      std::unique_ptr<HashFunction> copy_state() const override;

      void clear() override;

      std::string provider() const override;

      SHA_256() : MDx_HashFunction(64truetrue), m_digest(8)
         { clear(); }

      /*
      * Perform a SHA-256 compression. For internal use
      * 实际上在SHA224内部调用的也是这一个函数
      */

      static void compress_digest(secure_vector<uint32_t>& digest,
                                  const uint8_t input[],
                                  size_t blocks)
;

   private:
      void compress_n(const uint8_t[], size_t blocks) override;
      void copy_out(uint8_t[]) override;

      secure_vector<uint32_t> m_digest;
   };

}

#endif

我们可以看到,在这个头文件当中SHA224和SHA256是写在一起的,然后相比于我们之前所看到的哈希函数,这个多了一个私有的函数 compress_digest,这个函数实际上是执行压缩函数的地方,我们可以看到无论是SHA224还是SHA256调用的都是他。

/*
* SHA-224 compression function
*/

void SHA_224::compress_n(const uint8_t input[], size_t blocks)
   
{
   SHA_256::compress_digest(m_digest, input, blocks);
   }

/*
* SHA-256 compression function
*/

void SHA_256::compress_n(const uint8_t input[], size_t blocks)
   
{
   SHA_256::compress_digest(m_digest, input, blocks);
   }

这里对于实际的压缩函数的处理,和其他的有一些不太一样,这里用了一个宏,就把所有的整个处理函数写到一起了。

/*
* SHA-256 F1 Function
*
* Use a macro as many compilers won't inline a function this big,
* even though it is much faster if inlined.
*/

#define SHA2_32_F(A, B, C, D, E, F, G, H, M1, M2, M3, M4, magic) do {   
   uint32_t A_rho = rotr<2>(A) ^ rotr<13>(A) ^ rotr<22>(A);             

   uint32_t E_rho = rotr<6>(E) ^ rotr<11>(E) ^ rotr<25>(E);             
   uint32_t M2_sigma = rotr<17>(M2) ^ rotr<19>(M2) ^ (M2 >> 10);        
   uint32_t M4_sigma = rotr<7>(M4) ^ rotr<18>(M4) ^ (M4 >> 3);          
   H += magic + E_rho + choose(E, F, G) + M1;                           
   D += H;                                                              
   H += A_rho + majority(A, B, C);                                      
   M1 += M2_sigma + M3 + M4_sigma;                                      
   } while(0);

我们知道,实际上宏是对代码的一个直接替换,然后作者也解释这么搞的原因了,因为大多数的编译器都无法内联这么大的函数,尽管是内联的速度要快,因此这里用宏来替代了,这是个和我们之前所看到的前面的几个算法的一个不同。

SM3

接下来,我们再来看一下,这个密码库居然实现了国密算法,给个好评,这个的写法和MD4在风格上有一些相似。

/*
* SM3
* (C) 2017 Ribose Inc.
* (C) 2021 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/


#include <botan/internal/sm3.h>
#include <botan/internal/loadstor.h>
#include <botan/internal/rotate.h>
#include <botan/internal/bit_ops.h>

namespace Botan {

namespace {

const uint32_t SM3_IV[] = {
   0x7380166fUL, 0x4914b2b9UL, 0x172442d7UL, 0xda8a0600UL,
   0xa96f30bcUL, 0x163138aaUL, 0xe38dee4dUL, 0xb0fb0e4eUL
};

inline uint32_t P0(uint32_t X)
   
{
   return X ^ rotl<9>(X) ^ rotl<17>(X);
   }

inline void R1(uint32_t A, uint32_t& B, uint32_t C, uint32_t& D,
               uint32_t E, uint32_t& F, uint32_t G, uint32_t& H,
               uint32_t TJ, uint32_t Wi, uint32_t Wj)

   
{
   const uint32_t A12 = rotl<12>(A);
   const uint32_t SS1 = rotl<7>(A12 + E + TJ);
   const uint32_t TT1 = (A ^ B ^ C) + D + (SS1 ^ A12) + Wj;
   const uint32_t TT2 = (E ^ F ^ G) + H + SS1 + Wi;

   B = rotl<9>(B);
   D = TT1;
   F = rotl<19>(F);
   H = P0(TT2);
   }

inline void R2(uint32_t A, uint32_t& B, uint32_t C, uint32_t& D,
               uint32_t E, uint32_t& F, uint32_t G, uint32_t& H,
               uint32_t TJ, uint32_t Wi, uint32_t Wj)

   
{
   const uint32_t A12 = rotl<12>(A);
   const uint32_t SS1 = rotl<7>(A12 + E + TJ);
   const uint32_t TT1 = majority(A, B, C) + D + (SS1 ^ A12) + Wj;
   const uint32_t TT2 = choose(E, F, G) + H + SS1 + Wi;

   B = rotl<9>(B);
   D = TT1;
   F = rotl<19>(F);
   H = P0(TT2);
   }

inline uint32_t P1(uint32_t X)
   
{
   return X ^ rotl<15>(X) ^ rotl<23>(X);
   }

inline uint32_t SM3_E(uint32_t W0, uint32_t W7, uint32_t W13, uint32_t W3, uint32_t W10)
   
{
   return P1(W0 ^ W7 ^ rotl<15>(W13)) ^ rotl<7>(W3) ^ W10;
   }

}

/*
* SM3 Compression Function
*/

void SM3::compress_n(const uint8_t input[], size_t blocks)
   
{
   uint32_t A = m_digest[0], B = m_digest[1], C = m_digest[2], D = m_digest[3],
            E = m_digest[4], F = m_digest[5], G = m_digest[6], H = m_digest[7];

   for(size_t i = 0; i != blocks; ++i)
      {
      uint32_t W00 = load_be<uint32_t>(input, 0);
      uint32_t W01 = load_be<uint32_t>(input, 1);
      uint32_t W02 = load_be<uint32_t>(input, 2);
      uint32_t W03 = load_be<uint32_t>(input, 3);
      uint32_t W04 = load_be<uint32_t>(input, 4);
      uint32_t W05 = load_be<uint32_t>(input, 5);
      uint32_t W06 = load_be<uint32_t>(input, 6);
      uint32_t W07 = load_be<uint32_t>(input, 7);
      uint32_t W08 = load_be<uint32_t>(input, 8);
      uint32_t W09 = load_be<uint32_t>(input, 9);
      uint32_t W10 = load_be<uint32_t>(input, 10);
      uint32_t W11 = load_be<uint32_t>(input, 11);
      uint32_t W12 = load_be<uint32_t>(input, 12);
      uint32_t W13 = load_be<uint32_t>(input, 13);
      uint32_t W14 = load_be<uint32_t>(input, 14);
      uint32_t W15 = load_be<uint32_t>(input, 15);

      R1(A, B, C, D, E, F, G, H, 0x79CC4519, W00, W00 ^ W04);
      W00 = SM3_E(W00, W07, W13, W03, W10);
      R1(D, A, B, C, H, E, F, G, 0xF3988A32, W01, W01 ^ W05);
      W01 = SM3_E(W01, W08, W14, W04, W11);
      R1(C, D, A, B, G, H, E, F, 0xE7311465, W02, W02 ^ W06);
      W02 = SM3_E(W02, W09, W15, W05, W12);
      R1(B, C, D, A, F, G, H, E, 0xCE6228CB, W03, W03 ^ W07);
      W03 = SM3_E(W03, W10, W00, W06, W13);
      R1(A, B, C, D, E, F, G, H, 0x9CC45197, W04, W04 ^ W08);
      W04 = SM3_E(W04, W11, W01, W07, W14);
      R1(D, A, B, C, H, E, F, G, 0x3988A32F, W05, W05 ^ W09);
      W05 = SM3_E(W05, W12, W02, W08, W15);
      R1(C, D, A, B, G, H, E, F, 0x7311465E, W06, W06 ^ W10);
      W06 = SM3_E(W06, W13, W03, W09, W00);
      R1(B, C, D, A, F, G, H, E, 0xE6228CBC, W07, W07 ^ W11);
      W07 = SM3_E(W07, W14, W04, W10, W01);
      R1(A, B, C, D, E, F, G, H, 0xCC451979, W08, W08 ^ W12);
      W08 = SM3_E(W08, W15, W05, W11, W02);
      R1(D, A, B, C, H, E, F, G, 0x988A32F3, W09, W09 ^ W13);
      W09 = SM3_E(W09, W00, W06, W12, W03);
      R1(C, D, A, B, G, H, E, F, 0x311465E7, W10, W10 ^ W14);
      W10 = SM3_E(W10, W01, W07, W13, W04);
      R1(B, C, D, A, F, G, H, E, 0x6228CBCE, W11, W11 ^ W15);
      W11 = SM3_E(W11, W02, W08, W14, W05);
      R1(A, B, C, D, E, F, G, H, 0xC451979C, W12, W12 ^ W00);
      W12 = SM3_E(W12, W03, W09, W15, W06);
      R1(D, A, B, C, H, E, F, G, 0x88A32F39, W13, W13 ^ W01);
      W13 = SM3_E(W13, W04, W10, W00, W07);
      R1(C, D, A, B, G, H, E, F, 0x11465E73, W14, W14 ^ W02);
      W14 = SM3_E(W14, W05, W11, W01, W08);
      R1(B, C, D, A, F, G, H, E, 0x228CBCE6, W15, W15 ^ W03);
      W15 = SM3_E(W15, W06, W12, W02, W09);
      R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04);
      W00 = SM3_E(W00, W07, W13, W03, W10);
      R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05);
      W01 = SM3_E(W01, W08, W14, W04, W11);
      R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06);
      W02 = SM3_E(W02, W09, W15, W05, W12);
      R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07);
      W03 = SM3_E(W03, W10, W00, W06, W13);
      R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08);
      W04 = SM3_E(W04, W11, W01, W07, W14);
      R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09);
      W05 = SM3_E(W05, W12, W02, W08, W15);
      R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10);
      W06 = SM3_E(W06, W13, W03, W09, W00);
      R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11);
      W07 = SM3_E(W07, W14, W04, W10, W01);
      R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12);
      W08 = SM3_E(W08, W15, W05, W11, W02);
      R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13);
      W09 = SM3_E(W09, W00, W06, W12, W03);
      R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14);
      W10 = SM3_E(W10, W01, W07, W13, W04);
      R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15);
      W11 = SM3_E(W11, W02, W08, W14, W05);
      R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00);
      W12 = SM3_E(W12, W03, W09, W15, W06);
      R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01);
      W13 = SM3_E(W13, W04, W10, W00, W07);
      R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02);
      W14 = SM3_E(W14, W05, W11, W01, W08);
      R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03);
      W15 = SM3_E(W15, W06, W12, W02, W09);
      R2(A, B, C, D, E, F, G, H, 0x7A879D8A, W00, W00 ^ W04);
      W00 = SM3_E(W00, W07, W13, W03, W10);
      R2(D, A, B, C, H, E, F, G, 0xF50F3B14, W01, W01 ^ W05);
      W01 = SM3_E(W01, W08, W14, W04, W11);
      R2(C, D, A, B, G, H, E, F, 0xEA1E7629, W02, W02 ^ W06);
      W02 = SM3_E(W02, W09, W15, W05, W12);
      R2(B, C, D, A, F, G, H, E, 0xD43CEC53, W03, W03 ^ W07);
      W03 = SM3_E(W03, W10, W00, W06, W13);
      R2(A, B, C, D, E, F, G, H, 0xA879D8A7, W04, W04 ^ W08);
      W04 = SM3_E(W04, W11, W01, W07, W14);
      R2(D, A, B, C, H, E, F, G, 0x50F3B14F, W05, W05 ^ W09);
      W05 = SM3_E(W05, W12, W02, W08, W15);
      R2(C, D, A, B, G, H, E, F, 0xA1E7629E, W06, W06 ^ W10);
      W06 = SM3_E(W06, W13, W03, W09, W00);
      R2(B, C, D, A, F, G, H, E, 0x43CEC53D, W07, W07 ^ W11);
      W07 = SM3_E(W07, W14, W04, W10, W01);
      R2(A, B, C, D, E, F, G, H, 0x879D8A7A, W08, W08 ^ W12);
      W08 = SM3_E(W08, W15, W05, W11, W02);
      R2(D, A, B, C, H, E, F, G, 0x0F3B14F5, W09, W09 ^ W13);
      W09 = SM3_E(W09, W00, W06, W12, W03);
      R2(C, D, A, B, G, H, E, F, 0x1E7629EA, W10, W10 ^ W14);
      W10 = SM3_E(W10, W01, W07, W13, W04);
      R2(B, C, D, A, F, G, H, E, 0x3CEC53D4, W11, W11 ^ W15);
      W11 = SM3_E(W11, W02, W08, W14, W05);
      R2(A, B, C, D, E, F, G, H, 0x79D8A7A8, W12, W12 ^ W00);
      W12 = SM3_E(W12, W03, W09, W15, W06);
      R2(D, A, B, C, H, E, F, G, 0xF3B14F50, W13, W13 ^ W01);
      W13 = SM3_E(W13, W04, W10, W00, W07);
      R2(C, D, A, B, G, H, E, F, 0xE7629EA1, W14, W14 ^ W02);
      W14 = SM3_E(W14, W05, W11, W01, W08);
      R2(B, C, D, A, F, G, H, E, 0xCEC53D43, W15, W15 ^ W03);
      W15 = SM3_E(W15, W06, W12, W02, W09);
      R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04);
      W00 = SM3_E(W00, W07, W13, W03, W10);
      R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05);
      W01 = SM3_E(W01, W08, W14, W04, W11);
      R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06);
      W02 = SM3_E(W02, W09, W15, W05, W12);
      R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07);
      W03 = SM3_E(W03, W10, W00, W06, W13);
      R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08);
      R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09);
      R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10);
      R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11);
      R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12);
      R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13);
      R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14);
      R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15);
      R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00);
      R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01);
      R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02);
      R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03);

      A = (m_digest[0] ^= A);
      B = (m_digest[1] ^= B);
      C = (m_digest[2] ^= C);
      D = (m_digest[3] ^= D);
      E = (m_digest[4] ^= E);
      F = (m_digest[5] ^= F);
      G = (m_digest[6] ^= G);
      H = (m_digest[7] ^= H);

      input += hash_block_size();
      }
   }

/*
* Copy out the digest
*/

void SM3::copy_out(uint8_t output[])
   
{
   copy_out_vec_be(output, output_length(), m_digest);
   }

/*
* Clear memory of sensitive data
*/

void SM3::clear()
   
{
   MDx_HashFunction::clear();
   std::copy(std::begin(SM3_IV), std::end(SM3_IV), m_digest.begin());
   }

}

虽然有一些疑惑,但是吧实现起来也没啥毛病,对于SM3的初始化向量东西也不多啊,这为啥前面都是写的固定值,到了这里用了个std里面的copy函数,真的惊了,然后看了一眼,这俩作者不是同一位大佬,哈哈,其实看看这些源码有时候发现欢乐还是蛮多的。

【botan源码阅读】MD结构源码阅读

Whirlpool

这一个算法呢比较特殊,虽然他也是Merkle-Damgård 结构的哈希函数,但是呢,如果按照标准实现来看botan源码当中的实现,你会发现,这。。。这还是原来的那个算法吗,如果你能理解之前AES的查表法的话,再返回来看这个的源码实现,就会发现清晰不少,在这里呢,本文的重点不在于每个具体的哈希函数的解析上,因此在这里就不去展开来聊这个的实现细节了,顺道在这里给自己挖一个坑,感觉自己好像是挖了不少的坑,还有好多还没填,不过不要紧,先挖了再说,等着来一篇文章来写一下botan源码当中whirlpool的实现,单独来聊聊这件事中,溜了溜啦。

结束语

本篇文章其实讲的比较水,开始写这一系列的文章,本以为可能会写比较多的内容,但是发现呢,事实并不是这样,还是因为本身密码学相关库的一个特殊性,因为密码算法本身是比较分散的,他们之间的独立性不是特别的强,而且每个密码算法里面涉及到的结构有都是相对独立的,因此呢感觉写着写着就没什么可写的情况,有点难受啊,所以这个系列目前可能,大概率,也许会搁浅一段时间,等我想想有没有什么好的思路来去讲这个的源码,需要考虑的点主要有两个,第一个是如何权衡细节和整体代码分析的一个权重,如果过分去关注细节,那么就和直接去聊某个特定算法是一样的了,如果不去看细节,有些算法的实现中会有一些的小trick,和一些变形的技巧,和我们在教科书当中学到的不是完全一致的,这可能会导致读者的疑惑,哎,太难了,第二个就是密码学库里面的关联性实在是不强,这有好处,也有坏处,好处就是我们可以随便找一个算法来看,不用太关注其他文件下面的东西,坏处就是没什么关联性,也就没什么顺序和逻辑可言了,蓝瘦香菇,我在结束语又啰嗦这么半天,其实目的就一个,这个系列暂时要咕咕一段时间了,咱们有缘再见 ~~。

参考资料

  • https://datatracker.ietf.org/doc/html/rfc1320[1]

Reference

[1]

https://datatracker.ietf.org/doc/html/rfc1320: https://datatracker.ietf.org/doc/html/rfc1320


原文始发于微信公众号(Coder小Q):【botan源码阅读】MD结构源码阅读

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年11月13日16:39:59
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  【botan源码阅读】MD结构源码阅读 http://cn-sec.com/archives/1406379.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: