将空向量聚合或池化为最大的空向量

Aggregate or pool null vectors into largest null vector?

本文关键字:向量      更新时间:2023-10-16

我有一个c++头文件模板类,它使用空向量(0的字符串)。字符串的长度由模板参数决定(它是一个HKDF实现,长度取决于底层哈希摘要的大小)。

template < class HASH >
class HKDF
{
  ...
  private:
    typedef byte NullVector[HASH::DIGESTSIZE];
    static const NullVector m_vec;
};

可以聚合各种NullVector,并且所有实例化类都可以使用摘要大小最大的NullVector。例如,MD5的摘要长度为16字节,SHA-512的摘要长度为64字节。因此,工具链可以生成一个64字节的向量,然后所有类,如MD5, SHA-1, Whirlpool和SHA-512都可以使用它。

这类似于字符串池,但我不希望编译器或链接器观察到这种情况或看到这种模式(但我可能错了)。所以我想给这些工具一个提示。

是否有可能告诉编译器或链接器聚合或池NullVectors,并且只输出最终二进制中的最大值?如果有,怎么做?

我经常使用MSVC, GCC, ICC和Clang。我对为gcc兼容的编译器做这件事特别感兴趣,因为它涵盖了大多数用例。因此,如果需要,我很乐意使用特定于gcc的扩展。


这里有更多的背景故事…迭代哈希,如MD5, SHA1到SHA512和Whirlpool都有固定的块大小。对于这些哈希,共享一个64字节的0数组应该没问题。我从未见过块大小大于64字节的迭代哈希,但我需要注意它。

递归散列,如SHA-3,本身没有块大小。我甚至不确定如何使经典的HMAC和HKDF的工作为SHA3和其他递归哈希。

不过,你可以用迭代哈希和递归哈希做同样的事情。显然,您可以消化一条消息。但是作为一个更复杂的例子,由于扩展攻击,HMAC必须将ipadopad添加到迭代散列中,但是您可以生成键文摘或验证标记。对于递归散列,只需将键与消息连接起来,以生成键摘要或验证标记。不需要使用递归散列进行内部或外部填充。

这里有一个可能的解决方案,使您更接近,但您仍然需要决定最大尺寸应该是什么:

编辑:由于c++03标签而更新。以前的代码需要c++11.

#include <cassert>
#include <cstdlib>
struct NullContainer                                                            
{                                                                               
    static const size_t LARGEST_SIZE = 1024 ;                               
    typedef unsigned char LargeNullVector[LARGEST_SIZE] ;                             
    static const LargeNullVector m_vec ;                                        
} ;             
const NullContainer::LargeNullVector NullContainer::m_vec = {0} ;
template < class HASH >                                                         
class HKDF : public NullContainer                                               
{                                                                               
} ;                                                                                              
int main()                                                                      
{                                                                               
    assert( &HKDF<int>::m_vec == &HKDF<char>::m_vec ) ;                         
    return 0;                                                                   
}   

当然,在这种情况下,您可能希望使用私有继承