Sha3算法Word文档下载推荐.docx
《Sha3算法Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Sha3算法Word文档下载推荐.docx(22页珍藏版)》请在冰点文库上搜索。
深入Keccak
在写作的时候,NIST还没有发布SHA-3(FIPS180-5)的官方文档。
因此,下面的资料收集于Keccak的参考文档和来源于第三方。
这里有Keccak算法的三个部分(图1).
图1:
Keccak散列函数的基本模块。
Hash()函数作为入口函数。
它需要4个输入参数:
散列位大小(n),消息文本(M)和它的位大小(N),和一个哈希变量(H).这个哈希变量必须有下面的malloc()函数创建:
viewsource
print?
1
HashReturnE;
2
char*H;
3
n=224;
4
H=(char*)malloc(sizeof(char)*n/8);
5
//...
6
E=Hash(n,M,N,H);
Init()函数为指定的哈希大小准备内部状态(S)。
Update()函数开始压缩或吸收相。
在这里根据内部状态组合消息文本,然后置换.Final()函数开始提取或压缩相。
这是位从内部状态提取和组装形成的散列值。
第一个n位组装的散列然后作为消息散列。
四个函数都返回一个错误的结果,返回0说明函数没有出错地执行结束。
图2显示了内部状态的数据结构。
命名为spongeState的这个C结构包含8个域,其中两个是固定数组(以红色标出)。
state数组域存储真正的状态字节,而dataQueue数组域存储着将被组合和变换的消息字节。
图2:
保存Keccak哈希函数的内部状态的结构
capacity域是散列容量(用c表示)。
它的值设置为散列大小的两倍(2*n)。
rate域是每个循环处理的消息位长度。
它设置为1600-c这个值。
bitInQueue域是保留在dataQueue数组域中的消息位长度。
fixedOutputlength域是期望的散列大小(用n表示)。
squeezing域是模式标志。
当设置为0时,keccak处在压缩模式。
当设置为1时,keccak是处在解压缩模式。
另外filedbitsAvailableForSqueezing保存的是组合为最终消息散列的状态位长度。
Keccak使用了24个变换循环来缩减消息文本为散列值。
每个循环连续调用了五个模块,如图3所示。
图3:
每个变换循环调用的模块
θ模块把内部状态转化为5x5的每个元素为64位的数组。
它计算每列中同位的部分,然后使用异或(XOR)操作符对它们进行组合。
然后它按照下面的方式把获得的同位结果和每个状态位异或:
S[i][j][k]^=parity(S[0...4][j-1][k])
^parity(S[0...4][j+1][k-1])
wherei=0...4;
j=0...4;
k=0...63
ρ模块按照三角数的排列对每个64位元素循环移动。
不过循环移动把元素S[0][0]排除在外。
φ模块变换64位元素。
变换遵循下面所示的固定赋值模式:
S[j][2*i+3*j]=S[i][j]
χ模块给变换循环增加了非线性特性。
它仅仅使用了三个逐位操作符:
与(AND),非(NOT)和异或(XOR)来组合行元素。
然后按照下面的方式把结果写入状态数组里:
S[i][j][k]^=~S[i][j+1][k]&
S[i][j+2][k]
ι模块打破了由其他模块所产生的任何对称。
它是这样做的,把数组中的一个元素与一循环常量异或。
这个模块有24个循环常量供选择。
这些常量由Keccak内部定义。
不过,由于Keccak的C源代码太大不能全部罗列在这儿了。
SHA-3评估
那么SHA-3与它的前任SHA-1和SHA-2比较又如何呢?
为了回答这个问题,我对这三个哈希函数进行四个独立的测试:
∙第一个测试是冲突测试。
这儿,我准备了一些消息文本,并且让这些哈希函数处理每个文本。
一个良好设计的哈希函数应当对每个文本生成一个唯一的散列值,甚至在两个文本仅仅有一个字符的差别时。
如果冲突发生了,那么冲突应该是非常罕见的,并且复杂度至少是2n。
∙第二个测试是运行位测试。
这个测试揭示了位怎样分布在哈希值上才是良好的。
理想情况下,一个哈希值应当具有相互平衡数目的1和0。
如果我们把哈希划分为两相等的部分,并计算每一半中1的数目,我们应当得到相等的数量。
如果有一半比另一半多出1的数量,这意味着有一个潜在的不对称,它可能转换为一个可能的冲突。
∙下一个测试是雪崩或者瀑布测试。
这个测试用于测量哈希函数对文本信息变化的反应能力。
理想情况下,一个消息字节的变化应该能引起约半个散列字节的变化;
并且这个变化应当顺着哈希值一致地发生。
太大或者太小的变化就可能说明有冲突。
∙最后一个测试是耗时测试。
这个用来测量哈希函数处理消息文本的速度。
一个良好的哈希函数处理一个大信息文本耗时不超过半秒。
更长的哈希耗时是不期望的,除非这个函数做为高流量服务的一部分。
表1显示了SHA-3与前两任相比较的情况。
测试的机器是苹果的MacBook,带有2G赫兹的Intel酷睿2Duo处理器和2GB的DDR2内存。
操作系统是MacOSX10.6.7。
测试的消息是来自威廉.莎士比亚的戏剧哈姆雷特的摘要-"
生存还是死亡"
独白,由33行文本总共260个单词组成。
由于SHA-1仅仅生成160位散列值,而SHA-2和SHA-3的输出限制在224位,所以它们生成大小相比较最接近。
表1:
比较SHA-3与其前任
与SHA-1和SHA-2相比较,SHA-3有一个更小点的联动率。
对每个消息字节的更改它仅仅更改三个哈希字节。
SHA-3显示轻微的位倾斜。
它的消息散列的右半部分比左半部分多出12个1位。
SHA-3比SHA-2快些,哈希测试文本少花费了2.80纳秒。
表2显示了当生成四个不同大小的散列的时候SHA-3的执行情况。
使用同样的机器和同样的消息文本获得的测试结果。
表2:
生成四个不同大小的散列时SHA-3的执行情况
这儿,对所有四个大小的散列SHA-3仍然显示了小的联动率。
这似乎是Keccak和它的海绵引擎的特性。
SHA-3也显示了轻微的倾斜。
消息散列的三个都是右半部分比左半部分有更多的1位。
然而,512位散列值的左半部分比右半部分有更多的1位。
SHA-3仍然快些,产生512位消息散列花费了2.010纳秒。
这比256位的SHA-2快2.003纳秒。
这个表没有显示任何冲突测试结果,因为测试本身没有发现冲突。
测试的消息可能太短或者太多变化而不能引起冲突。
不过,更大点的文本,尤其是具有微小变化的更大文本,对这些哈希函数的一个可能引起至少一个冲突。
Xcode项目FooSHA3可用做参考。
部署SHA-3
SHA-3仍然没有进入大多数主流平台。
某些平台(如MacOSX和IOS)仍然依赖libcrypto库,这个库只支持SHA-1和SHA-2。
把SHA-3部署到你所期望的平台的一种方法是编译这个哈希算法为静态库。
然后把新的库安装到/urs/lib或者/usr/share目录下,在这儿假设你对这些目录具有写的权限。
不过还有另一种方法去部署SHA-3,这种方法可以工作在MacOSX和IOS上,即以框架捆绑包的形式部署。
框架捆绑包是一个层次性的文件集合,这些文件一起才形成一个动态库。
不像大多数捆绑包,框架捆绑包是透明的;
它的内容像其他普通目录的内容一样可以随意浏览。
框架捆绑包可以位于常见的目录(比如~/Libray/Framworks),或者把框架捆绑包拷贝到应用捆绑包里,然后把它当作私有资源来用。
对框架捆绑包的访问是通过NSBunble类或者通过核心基础的捆绑服务来实现的。
清单1显示了如何给NSString类增加SHA-3支持。
这儿,类SHA3String声明了两个方法原型(行8-9)。
类方法sha3AsCstring使用实例方法cStringUsingEncoding:
(行25)提取原始的消息字节。
它声明标准的ASCII做为所期望的文本编码。
这个方法计算了消息字节数,并且创建哈希变量tHash(行29-30)。
然后传递字节数,消息文本和哈希变量给入口函数Hash()(行33)。
Hash()函数返回512位的消息散列值,接着sha3AsCstring重新强制转换这个散列值为一个常量字符串(行36)。
顺便说明一下,BitSequence是Keccak对char类型的自定义。
清单1
01
<
STRONG>
//--File:
SHA3Category.h
02
//
03
#import<
Cocoa/Cocoa.h>
04
string.h>
05
#import"
KeccakNISTInterface.h"
06
07
@interfaceNSString(SHA3String)
08
-(constchar*)sha3AsCstring;
09
-(NSData*)sha3AsData;
10
11
@end
12
13
SHA3Category.m
14
15
@implementationNSString(SHA3String)
16
//ReturntheSHA-3hashasaC-string
17
-(constchar*)sha3AsCstring
18
{
19
constchar*tTemp;
20
constBitSequence*tData;
21
BitSequence*tHash;
22
NSUIntegertLen;
23
24
//extractthemessagedata
25
tTemp=[selfcStringUsingEncoding:
NSASCIIStringEncoding];
26
tData=(constBitSequence*)tTemp;
27
28
//preparethehashvariable
29
tLen=strlen(tTemp);
30
tHash=malloc(sizeof(BitSequence)*32);
31
32
//hashthemessagedata
33
Hash(512,tData,tLen,tHash);
34
35
//returnthehashresult
36
tTemp=(constchar*)tHash;
37
return(tTemp);
38
}
39
40
//ReturntheSHA-3hashasanNSDataobject
41
-(NSData*)sha3AsData
42
43
constchar*tHash;
44
45
NSData*tData;
46
47
//generatetheSHA-3hash
48
tHash=[selfsha3AsCstring];
49
50
//preparethehashobject
51
tLen=strlen(tHash);
52
tData=[NSDatadataWithBytes:
tHash
53
length:
tLen];
54
55
//returnthehashobject
56
return(tData);
57
58
59
60
@end<
/STRONG>
类方法sha3AsData返回NSData对象形式的消息散列值。
它依靠sha3AsCstring来处理消息字节(行48)。
然后使用工厂方法dataWithBytes:
创建这个对象(行52-53)。
清单2显示出SHA-3是一个单例模式的类.单例模式提供一个公共的全局访问点来访问SHA-3算法。
它自己操纵自己的内存管理,所以,不需要显式的处理。
清单2
001
SHA3Single.h
002
003
004
005
006
//Definetheenumconstants
007
typedefenum_SHA3_SIZE
008
{SIZE_224=224,SIZE_256=256,
009
SIZE_384=384,SIZE_512=512}
010
SHA3_SIZE;
011
012
013
//Declaretheclassinterface
014
@interfaceSHA3Single:
NSObject
015
016
@private
017
NSUIntegerpSize;
018
019
@property(readwrite)NSUIntegerhashSize;
020
021
+(id)defaultGenerator;
022
+(id)generatorForSize:
(NSUInteger)aSize;
023
024
-(void)hashMessage:
(constchar*)aMesg
025
into:
(BitSequence*)aHash;
026
-(void)hashObject:
(id)aMesg
027
028
029
030
SHA3Single.m
031
032
//Declarethestaticglobal
033
staticSHA3Single*gHash;
034
035
//Definethesingletonclass
036
@implementationSHA3Single
037
@synthesizehashSize=pSize;
038
039
//CreatethedefaultSHA3generator
040
+(id)defaultGenerator
041
042
@synchronized(self)
043
044
//checkthestaticglobal
045
if(gHash==nil)
046
047
//createtheinstance
048
gHash=[[superalloc]init];
049
050
//settheoutputhashsize
051
gHash.hashSize=SIZE_512;
052
053
054
055
//returnthesingletoninstance
056
return(gHash);
057
058
059
//Createa"
custom"
SHA3generator
060
(NSUInteger)aSize
061
062
063
064
065
066
067
068
069
070
071
gHash.hashSize=aSize;
072
073
074
075
076
077
078
079
080
(BitSequence*)aHash
081
082
083
084
085
tLen=strlen(aMesg);
086
Hash(self.hashSize,
087
(constBitSequen