软件工程与应用第七篇报告

2021SC@SDUSC

2021-11-14

第七周完成事项

工作内容

这周的工作分配如下:

高跃在之前已经对公钥私钥的形成以及加密参数的生成已经有了一定的了解,所以这次负责分析encryptor(加密)部分

李东晓之前主要分析的ntt(快速数论变换)和numth(整数运算),这次负责分析rns(剩余数系统),因为这三个部分都是为了加快加密和解密过程的。

我这次分析的是blake算法——经典的哈希算法。我之前分析的是RLWE(带错误的环运算)以及与李东晓共同分析的numth,这次分析哈希算法也是一次新方向的开拓。

在代码中总共引用了三种哈希算法,分别是blake2、blake2b以及SHA-3。这次主要分析blake2

与全同态加密的关系

全同态加密的宗旨就是保证内容(也就是明文)在传输过程中的安全性,通过加密,将明文转化成密文,然后发送给另一端,因为是全同态加密,可以在是密文的时候就进行数据分析。但是在这个过程中的安全性如何验证呢?这时候哈希算法就派上了用场,据我们的知识所了解,加密解密是互为可逆过程的,也就是说,通过公钥和私钥,可以将明文转化成密文,也可以将密文转化成明文,这个过程是双向的,但是哈希是不可逆的,只能是单向的。我们可以利用哈希的这个特性,在传输密文的同时,通过哈希将明文生成一段序列作为密文的标签,如果接收方接受到密文的时候标签的完整的,就可以说明整个传输过程是安全的,对此,一个出色的哈希算法是至关重要的。

目前已知的哈希算法有MD5、SHA-1、SHA-2、blake等算法,哈希算法的目的是将不同长度的输入内容转化成统一长度哈希码,这个时候我们就会想如果输入长度大于输出长度,是不是说明一定会有两个输入内容得到相同的输出结果,这个现象有一个专门的名称,叫做哈希碰撞,最著名的哈希碰撞案例来自于山东大学王小云教授成功破解了MD5。在王小云教授的报告上,通过 2 40 2^{40} 240次hash运算可以找出SHA-0的碰撞,并且在报告中对四种Hash函数都给出了碰撞。但是这个概率是相对较小的,也就是在一般情况下,大部分哈希算法是比较安全的。通过哈希算法,将不等长的输入数据不可逆地转化成等长的哈希码,作为密文传输的标签。当密文被尝试破解的时候,必然会改变标签的内容,从而可以将此作为判断密文是否安全的证明。

Blake以及Blake2算法

BLAKE算法于2008年提出,它包含两个版本,一种基于32位word用于产生最长256位的哈希结果,一种基于64位word用于产生最长512位的哈希结果,BLAKE算法核心操作是不断地将8个散列中间结果和16个输入word进行组合,从而产生下一轮组合的8个中间结果。按照最终截断的哈希长度,BLAKE-256和BLAKE-224使用32位字分别产生256位和224位的哈希结果(也称消息摘要),而BLAKE-512和BLAKE-384使用64位字并产生512位和384位哈希结果。

BLAKE2算法基于BLAKE算法,于2012年被提出,BLAKE2不再向blake round函数中对输入字添加常量,修改了两个旋转常量及padding等,并在BLAKE2b(对应BLAKE-512)中将rounds的数量由16减少为12,在BLAKE2s(对应BLAKE-256)中将rounds数量由14减少为10,同样的,BLAKE2b产生1到64字节的消息摘要,BLAKE2s产生1到32字节的消息摘要,同时这两种算法也由对应的多核并行版本BLAKE2bp(4路并行)和BLAKE2sp(8路并行)。除了以上几种算法变种,BLAKE2还有一种BLAKE2x的变种,这种算法可以产生任意长度的消息摘要。除了安全性方面的优势,据称BLAKE2算法在Intel CPU第六代微处理架构(Skylake)中的处理速度要优于MD5,SHA-1,SHA-2和SHA-3等算法,如图所示:

img

代码分析

在这里插入图片描述

这是这两周主要分析的内容这次首先是对blake2.h进行代码分析。

enum blake2s_constant
{
	BLAKE2S_BLOCKBYTES = 64,
    BLAKE2S_OUTBYTES = 32,
    BLAKE2S_KEYBYTES = 32,
    BLAKE2S_SALTBYTES = 8,
    BLAKE2S_PERSONALBYTES = 8
};
enum blake2b_constant
{
	BLAKE2B_BLOCKBYTES = 128,
	BLAKE2B_OUTBYTES = 64,
    BLAKE2B_KEYBYTES = 64,
    BLAKE2B_SALTBYTES = 16,
    BLAKE2B_PERSONALBYTES = 16
};

对于blake2s和blake2b哈希算法的使用到的常数变量的定义

typedef struct blake2s_state__
{
	uint32_t h[8];
    uint32_t t[2];
    uint32_t f[2];
    uint8_t buf[BLAKE2S_BLOCKBYTES];
    size_t buflen;
    size_t outlen;
    uint8_t last_node;
} blake2s_state;

typedef struct blake2b_state__
{
	uint64_t h[8];
    uint64_t t[2];
    uint64_t f[2];
    uint8_t buf[BLAKE2B_BLOCKBYTES];
    size_t buflen;
    size_t outlen;
    uint8_t last_node;
} blake2b_state;

typedef struct blake2sp_state__
{
    blake2s_state S[8][1];
    blake2s_state R[1];
    uint8_t buf[8 * BLAKE2S_BLOCKBYTES];
    size_t buflen;
    size_t outlen;
} blake2sp_state;

typedef struct blake2bp_state__
{
    blake2b_state S[4][1];
	blake2b_state R[1];
    uint8_t buf[4 * BLAKE2B_BLOCKBYTES];
    size_t buflen;
    size_t outlen;
} blake2bp_state;

对于blake2s、blake2b、blake2sp以及blake2bp四种哈希算法使用到的数据结构的定义。

blake2.h剩下的内容也是对于哈希算法参数初始化的定义在这里不过多赘述。接下来主要分析blake2b.c的代码。

/* inlen, at least, should be uint64_t. Others can be size_t. */
int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
{
  blake2b_state S[1];

  /* Verify parameters */
  if ( NULL == in && inlen > 0 ) return -1;

  if ( NULL == out ) return -1;

  if( NULL == key && keylen > 0 ) return -1;

  if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;

  if( keylen > BLAKE2B_KEYBYTES ) return -1;

  if( keylen > 0 )
  {
    if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
  }
  else
  {
    if( blake2b_init( S, outlen ) < 0 ) return -1;
  }

  blake2b_update( S, ( const uint8_t * )in, inlen );
  blake2b_final( S, out, outlen );
  return 0;
}

int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) {
  return blake2b(out, outlen, in, inlen, key, keylen);
}

上面是blake2的主要算法,整体思路是先判断参数,然后初始化数据,更新输入内容,更新输出内容,结束算法。我们一步一步分析其中的关键,首先进行一系列参数的验证,当输入内容为空并且输入长度大于零的时候,或者输出内容为空,或者算法密钥为空并且算法密钥长度大于零等等特殊情况,如果这些都没有问题的时候,就进行到下一步。

首先判断算法密钥长度是否大于零,如果大于零,就执行blake2b_init_key( S, outlen, key, keylen )算法初始化密钥;如果长度不大于零,就进行blake2b_init( S, outlen )blake2b的初始化。这里我们先来看一下blake2b_init_key函数。

int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
{
  blake2b_param P[1];

  if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;

  if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;

  P->digest_length = (uint8_t)outlen;
  P->key_length    = (uint8_t)keylen;
  P->fanout        = 1;
  P->depth         = 1;
  store32( &P->leaf_length, 0 );
  store32( &P->node_offset, 0 );
  store32( &P->xof_length, 0 );
  P->node_depth    = 0;
  P->inner_length  = 0;
  memset( P->reserved, 0, sizeof( P->reserved ) );
  memset( P->salt,     0, sizeof( P->salt ) );
  memset( P->personal, 0, sizeof( P->personal ) );

  if( blake2b_init_param( S, P ) < 0 ) return -1;

  {
    uint8_t block[BLAKE2B_BLOCKBYTES];
    memset( block, 0, BLAKE2B_BLOCKBYTES );
    memcpy( block, key, keylen );
    blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
    secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
  }
  return 0;
}

首先创建一个参数变量结构体blake2b_param P[1],然后进行输入变量的判断,判断输出长度是否符合要求以及密钥和长度的分析。

blake2b_param P[1];

if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;

if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;

接下来是对变量P的内容进行初始化。

P->digest_length = (uint8_t)outlen;
P->key_length    = (uint8_t)keylen;
P->fanout        = 1;
P->depth         = 1;
store32( &P->leaf_length, 0 );
store32( &P->node_offset, 0 );
store32( &P->xof_length, 0 );
P->node_depth    = 0;
P->inner_length  = 0;
memset( P->reserved, 0, sizeof( P->reserved ) );
memset( P->salt,     0, sizeof( P->salt ) );
memset( P->personal, 0, sizeof( P->personal ) );

然后是对通过传进来的变量S以及在前面设置的P对blake2b的参数进行初始化并判断是否符合要求。

if( blake2b_init_param( S, P ) < 0 ) return -1;

最后是使用blake2b_update进行初步生成并销毁算法密钥。

{
  uint8_t block[BLAKE2B_BLOCKBYTES];
  memset( block, 0, BLAKE2B_BLOCKBYTES );
  memcpy( block, key, keylen );
  blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
  secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
}

由于篇幅的问题,接下来的内容我们留到下周进行分析。

总结

这次分析了blake2算法,对于哈希算法有了一定的了解,同时也明白了为什么全同态加密算法会在保持良好的保密性的同时,效率还特别高。

最后,感谢孔老师的指导,感谢戴老师和其他审核老师的阅读!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值