- 2022-08-13 发布 |
- 37.5 KB |
- 28页
文档介绍
计算机密码学实验指导书
目录实验1仿射密码设计2实验2DES对称加密设计4实验3RSA公钥密码设计9实验4MD5摘要与校验12实验5数字签名算法DSS1628\n实验1仿射密码设计一、实验目的通过编程实现替代密码算法——仿射密码和简单置换密码算法,加深对古典密码体制的了解,为深入学习密码学奠定基础。二、实验原理古典密码算法曾被广泛应用,大都比较简单,使用手工和机械操作来实现加密和解密。它的主要应用对象是文字信息,利用密码算法实现文字信息的加密和解密。下面介绍两种常见的具有代表性的古典密码算法,以帮助同学们对密码算法建立一个初步的印象。1.替代密码——仿射密码替代密码算法的原理是使用替代法进行加密,就是将明文中的字符用其它字符替代后形成密文。例如,明文字母a、b、c、d,用D、E、F、G做对应替换后形成密文。替代密码包括多种类型,如单表替代密码、多表替代密码等。下面介绍一种典型的单表替代密码——仿射密码。它的加密、解密过程可以表示为下面的函数:加密:解密:仿射加密要求,否则就褪化为。故密钥空间大小为:例如:密钥k=(7,3),7-1(mod26)=15加密函数:解密函数:设明文:China,首先转换为数字:2,7,8,13,0加密:“China”经仿射加密变换成“RAHQD”解密:原始消息“China”得到恢复28\n三、实验环境运行Windows或Linux操作系统的PC机,具有gcc(Linux)、VC或TC(Windows)等C语言编译环境。四、实验内容和步骤根据仿射密码的实现原理,利用C语言实现利用仿射密码进行加密和解密的程序。(1)设计加密程序:能够根据用户输入明文的内容产生加密的密文并输出(2)设计解密程序:能够对输入的密文内容破解并输出得到其对应的明文。28\n实验2DES对称加密设计一、实验目的通过用DES算法对实际的数据进行加密和解密来深刻了解DES的运行原理。二、实验原理信息加密根据采用的密钥类型可以划分为对称密码算法和非对称密码算法。对称密码算法是指加密系统的加密密钥和解密密钥相同,或者虽然不同,但是可以从其中任意一个推导出另一个,更形象的说就是用同一把钥匙开锁和解锁。在对称密码算法的发展历史中曾出现过多种优秀的算法,包括DES、3DES、AES等。下面我们以DES算法为例介绍对称密码算法的实现机制。DES算法是由美国IBM公司在20世纪70年代提出,并被美国政府、美国国家标准局和美国国家标准协会采纳和承认的一种标准加密算法。它属于分组加密算法,即在明文加密和密文解密过程中,信息都是按照固定长度分组后进行处理的。混淆和扩散是它采用的两个最重要的安全特性。混淆是指通过密码算法使明文和密文以及密钥的关系非常复杂,无法从数学上描述或者统计。扩散是指明文和密钥中每一位信息的变动,都会影响到密文中许多位信息的变动,从而隐藏统计上的特性,增加密码的安全。DES算法将明文分成64位大小的众多数据块,即分组长度为64位。同时用56位密钥对64位明文信息加密,最终形成64位的密文。如果明文长度不足64位,则将其扩展为64位(如补零等方法)。具体加密过程首先是将输入的数据进行初始换位(IP),即将明文M中数据的排列顺序按一定的规则重新排列,生成新的数据序列,以打乱原来的次序。然后将变换后的数据平分成左右两部分,左边记为L0,右边记为R0,然后对R0实行在子密钥(由加密密钥产生)控制下的变换f,结果记为f(R0,K1),再与L0做逐位异或运算,其结果记为R1,R0则作为下一轮的L1。如此循环16轮,最后得到L16、R16,再对L16、R16实行逆初始置换IP-1,即可得到加密数据。解密过程与此类似,不同之处仅在于子密钥的使用顺序正好相反。DES全部16轮的加密过程如图2.1所示。DES的加密算法包括3个基本函数。1.初始换位(IP)它的作用是把输入的64位数据块的排列顺序打乱,每位数据按照下面换位规则重新组合,即将第58位换到第1位,第50位换到第2位,……,依次类推。重组后的64位输出分为L0、R0(左、右)两部分,每部分分别为32位。58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,462,54,46,38,30,22,14,6,64,56,48,40,32,24,16,857,49,41,33,25,17,9,1,59,51,43,35,27,19,11,361,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7R0和K1经过f(R0,K1)变换后的输出结果,再和L0进行异或运算,输出结果做为R1,R0则赋给L1。L1和Rl同样再做类似运算生成L2和R2,……,经过16次运算后生成L16和R16。2.f函数28\nf函数是多个置换函数和替代函数的组合函数,它将32位比特的输入变换为32位的输出,如图2.2所示。Ri经过扩展运算E变换后扩展为48位的E(Ri),与Ki+1进行异或运算后输出的结果分成8组,每组6比特的并联B,B=BlB2B3B4B5B6B7B8,再经过8个S盒的选择压缩运算转换为4位,8个4位合并为32位后再经过P变换输出为32位的f(Ri,Ki+1)。其中,扩展运算E与置换P主要作用是增加算法的扩散效果。图2.1DES加密解密过程图2.2f函数处理流程28\n3.逆初始置换函数IP-1它将L16和R16作为输入,进行逆初始换位得到密文输出。逆初始换位是初始换位的逆运算,换位规则如下所列:DES的加密算法中除了上面介绍的3个基本函数,还有一个非常重要的功能模块,即子密钥的生成模块,具体子密钥的产生流程如图2.3所示。图2.3子密钥产生流程输入的初始密钥值为64位,但DES算法规定,其中第8、16、……、64位是奇偶校验位,不参与DES运算。所以,实际可用位数只有56位,经过缩小选择换位表1(表2-2)即密钥置换PC-1的变换后,初始密钥的位数由64位变成了56位,将其平分为两部分C0、D0,然后分别进行第1次循环左移,得到Cl、Dl,将Cl(28位)、Dl(28位)合并后得到56位的输出结果,再经过缩小选择换位表2(表2-3)即密钥置换PC-2,从而得到了密钥K1(48位)。依次类推,便可得到K2、……、K16。需要注意的是,16次循环左移对应的左移位数要依据表2-1的规则进行。表2-1左移位数规则il2345678910ll1213141516LSi112222221222222128\n表2-2缩小选择换位表1表2-3缩小选择换位表257494133251791585042342618102595l4335271911360524436635547393l2315762544638302214661534537292l135282012414171124153281562l102319124268167272013241523l37475530405l453348444939563453464250362932三、实验环境运行Windows或Linux操作系统的PC机,具有gcc(Linux)、VC或TC(Windows)等C语言编译环境。四、实验内容和步骤1.算法分析在附录中附加了有关DES算法的函数程序,根据所提供的程序分析DES算法的实现过程。DES程序包括一个头文件和一个实现DES算法的C文件。头文件里主要是一些宏定义和函数声明,其中还包括保证可移植性的一些定义。DES程序通过宏定义可选择小代码模式(#definesmall_code)或者选择大代码模式。在大代码模式下,程序定义了多个表,从而使DES算法中的很多运算都可以通过查表实现,速度较快,但要求有较多的存储空间;在小代码模式运行时,可以不查表,从而节省了存储空间,但是速度较慢。读者可以根据自己的需求来选择不同的运行模式。加密解密时主要用到下面5个函数。(1)intdes_setup(constunsignedchar*key,intkeylen,intnum_rounds,des_key*skey)函数名称:密钥生成函数。参数说明:key是一个指针,指向用户输入的初始密钥。keylen是输入密钥的长度,以字节为单位。num_rounds是加密轮数,当输入O时,使用算法默认的轮数。skey是一个指向结构体变量的指针,变量里面存储加密和解密时每轮使用的子密钥。当密钥生成时,返回值为CRYPT_OK(0),结果保留在skey指向的结构体。des_key的定义如下:typedefstructdes_key{ulong32ek[32],dk[32];)des_key;28\n结构体里的ek存储加密时用的子密钥,dk存储解密时用的子密钥。结构体中用2个32位的整数来存储一轮的48位密钥,每一个32位整数被分成4个8位,每个8位的第6位存储密钥。如果把48位密钥分成8组,则这8组按存储的顺序从高到低分别为l、3、5、7、2、4、6、8。这样做是为了加密时可以把扩展和查表运算结合进行。(2)voiddes_ecb_encrypt(constunsignedchar*pt,unsignedchar*ct,des_key*key)函数名称:加密函数。参数说明:pt是指向待加密的明文数组的指针。ct是指向存储加密结果的指针。key是调用密钥生成函数后存储每一轮子密钥的结构体变量。加密成功时,返回CRYPT_OK。(3)voiddes_ecb_decrypt(constunsignedchar*ct,unsignedcha*pt,des_key*key)函数名称:解密函数。。参数说明:ct是指向待解密的密文数组的指针。pt是指向存储解密结果的指针。key是调用密钥生成函数后存储每一轮子密钥的结构体变量。解密成功时,返回CRYPT_OK。加密和解密时,pt和ct可以指向同一块内存。(4)intdes_test(void)函数名称:测试函数。这个函数用来对加密算法进行测试。函数体内部定义了对应的明文和密文数组,并且进行了多轮加密和解密。这个函数还可以用来测试函数的运行时间。(5)intdes_keysize(int*desired_keysize、函数名称:密钥长度检验函数。参数说明:desired_keysize是使用者所想要的密钥长度。当密钥长度小于所需密钥长度时,返回值为CRYPT_INVALID_KEYSIZE,否则,desired_keysize指向的变量被置为8。2.设计一个程序可以利用DES算法进行加密和解密。28\n实验3RSA公钥密码设计一、实验目的通过实际编程了解非对称密码算法RSA的加密和解密过程,加深对非对称密码算法的认识。二、实验原理对称密码算法要求通信双方通过交换密钥实现使用同一个密钥,这在密钥的管理、发布和安全性方面存在很多问题,而非对称密码算法解决了这个问题。非对称密码算法是指一个加密系统的加密密钥和解密密钥是不同的,或者说不能用其中一个推导出另一个。在非对称密码算法的两个密钥中,一个是用于加密的密钥,它是可以公开的,称为公钥;另一个是用于解密的密钥,是保密的,称为私钥。非对称密码算法解决了对称密码体制中密钥管理的难题,并提供了对信息发送人的身份进行验证的手段,是现代密码学最重要的发明。RSA密码体制是目前为止最成功的非对称密码算法,它是在1977年由Rivest、Shamir和Adleman提出的第一个比较完善的非对称密码算法。它的安全性是建立在“大数分解和素性检测”这个数论难题的基础上,即将两个大素数相乘在计算上容易实现,而将该乘积分解为两个大素数因子的计算量相当大。虽然它的安全性还未能得到理论证明,但经过20多年的密码分析和攻击,迄今仍然被实践证明是安全的。RSA算法描述如下:1.公钥选择两个互异的大素数p和q,n是二者的乘积,即n=pq,使Ф(n)=(p-1)(q-1),Ф(n)为欧拉函数。随机选取正整数e,使其满足gcd(e,Ф(n))=1,即e和Ф(n)互质,则将(n,e)作为公钥。2.私钥求出正数d,使其满足e×d=lmodФ(n),则将(n,d)作为私钥。3.加密算法对于明文M,由C=Memodn,得到密文C。4.解密算法对于密文C,由M=Cdmodn,得到明文M。如果窃密者获得了n、e和密文C,为了破解密文必须计算出私钥d,为此需要先分解n。为了提高破解难度,达到更高的安全性,一般商业应用要求n的长度不小于1024位,更重要的场合不小于2048位。三、实验环境运行Windows或Linux操作系统的PC机,具有gcc(Linux)、VC或TC(Windows)等C语言编译环境。四、实验内容和步骤(1)为了加深对RSA算法的了解,根据已知参数:p=3,q=1128\n,M=2,手工计算公私钥,并对明文进行加密,然后对密文进行解密。(2)编写一个程序,随机选择3个较大的数x、e、n,然后计算xemodn,记录程序运行时间。实际中应用的素数为512位,n也就为1024位。这样的大数在计算机上如何表示、如何进行运算,利用课外时间,查阅相关资料。(3)尝试着加密一大段文字,记录程序的运行时间。使用DES算法加密相同的文字,比较两种算法加密的速度。(4)附录中给出了一个RSA算法实现的主要函数rsa_make_key,rsa_encrypt_key,rsa_decrypt_key,编写一段基于标准输入输出的用RSA加密文件的程序。下面是有关RSA接口调用的示例程序,写程序时可以参考。#includeek);deskey(key,DE1,skey->dk);returnCRYPT_OK;}2.des_ecb_encrypt函数voiddes_ecb_encrypt(constunsignedchar*pt,unsignedchar*ct,des_key*key){ulong32work[2];_ARGCHK(pt!=NULL);_ARGCHK(ct!=NULL);_ARGCHK(key!=NULL);LOAD32H(work[0],pt+0);LOAD32H(work[1],pt+4);desfunc(work,key->ek);STORE32H(work[0],ct+0);STORE32H(work[1],ct+4);}3.des_ecb_decrypt函数voiddes_ecb_decrypt(constunsignedchar*ct,unsignedchar*pt,des_key*key){ulong32work[2];_ARGCHK(pt!=NULL);_ARGCHK(ct!=NULL);_ARGCHK(key!=NULL);LOAD32H(work[0],ct+0);LOAD32H(work[1],ct+4);desfunc(work,key->dk);STORE32H(work[0],pt+0);STORE32H(work[1],pt+4);}intdes_test(void){#ifndefLTC_TESTreturnCRYPT_NOP;#elseinterr;staticconststructdes_test_case{intnum,mode;//mode1=encryptunsignedcharkey[8],txt[8],out[8];}cases[]={{1,1,{0x10,0x31,0x6E,0x02,0x8C,0x8F,0x3B,0x4A},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},{0x82,0xDC,0xBA,0xFB,0xDE,0xAB,0x66,0x02}},{2,1,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00},28\n{0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},{3,1,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0xDD,0x7F,0x12,0x1C,0xA5,0x01,0x56,0x19},{0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},{4,1,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x2E,0x86,0x53,0x10,0x4F,0x38,0x34,0xEA},{0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},{5,1,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x4B,0xD3,0x88,0xFF,0x6C,0xD8,0x1D,0x4F},{0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},{6,1,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x20,0xB9,0xE7,0x67,0xB2,0xFB,0x14,0x56},{0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},{7,1,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x55,0x57,0x93,0x80,0xD7,0x71,0x38,0xEF},{0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},{8,1,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x6C,0xC5,0xDE,0xFA,0xAF,0x04,0x51,0x2F},{0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},{9,1,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x0D,0x9F,0x27,0x9B,0xA5,0xD8,0x72,0x60},{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},{10,1,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0xD9,0x03,0x1B,0x02,0x71,0xBD,0x5A,0x0A},{0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00}},{1,0,{0x10,0x31,0x6E,0x02,0x8C,0x8F,0x3B,0x4A},{0x82,0xDC,0xBA,0xFB,0xDE,0xAB,0x66,0x02},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},{2,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00},{0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00}},{3,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00},{0xDD,0x7F,0x12,0x1C,0xA5,0x01,0x56,0x19}},{4,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00},{0x2E,0x86,0x53,0x10,0x4F,0x38,0x34,0xEA}},{5,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00},{0x4B,0xD3,0x88,0xFF,0x6C,0xD8,0x1D,0x4F}},{6,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00},{0x20,0xB9,0xE7,0x67,0xB2,0xFB,0x14,0x56}},{7,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00},{0x55,0x57,0x93,0x80,0xD7,0x71,0x38,0xEF}},{8,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00},{0x6C,0xC5,0xDE,0xFA,0xAF,0x04,0x51,0x2F}},{9,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},{0x0D,0x9F,0x27,0x9B,0xA5,0xD8,0x72,0x60}},{10,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},{0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00},{0xD9,0x03,0x1B,0x02,0x71,0xBD,0x5A,0x0A}}/***moretestcasesyoucouldaddifyouarenotconvinced(theabovetestcasesaren'treallytoogood):keyplaintextciphertext000000000000000000000000000000008CA64DE9C1B123A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7359B2163E4EDC5830000000000000001000000000000001958E6E627A05557B11111111111111111111111111111111F40379AB9E0EC5330123456789ABCDEF111111111111111117668DFC7292532D11111111111111110123456789ABCDEF8A5AE1F81AB8F2DD000000000000000000000000000000008CA64DE9C1B123A7FEDCBA98765432100123456789ABCDEFED39D950FA74BCC47CA110454A1A6E5701A1D6D039776742690F5B0D9A26939B28\n0131D9619DC1376E5CD54CA83DEF57DA7A389D10354BD27107A1133E4A0B26860248D43806F67172868EBB51CAB4599A3849674C2602319E51454B582DDF440A7178876E01F19B2A04B915BA43FEB5B642FD443059577FA2AF37FB421F8C40950113B970FD34F2CE059B5E0851CF143A86A560F10EC6D85B0170F175468FB5E60756D8E0774761D20CD3DA020021DC0943297FAD38E373FE762514B829BF486AEA676B2CB7DB2B7A07A7137045DA2A163BDD119049372802DFD64A815CAF1A0F04689104C2FD3B2F26955F6835AF609A5C513C9C4886C08837D06BB516CB7546164D5E404F2752320A2AEEAE3FF4AB771F08260D1AC2465E6B056E18759F5CCAEF1BF03E5DFA575A584023641ABA6176004BD6EF0917606288BF0DB6D70DEE56025816164629B007480D39006EE762F2A1F9915541020B5649793EBC79B3258F437540C8698F3CFA6FBF1CAFCFFD05564FB05E1515AB73A7072D43A0770752922F22E49BAB7CA1AC49E95D6D4CA229BF02FE55778117F12A5A6B612CC26CCE4A018310DC409B26D61D9D5C5018F728C25F4C038ED12B2E411C587F1C13924FEF305532286D6F295A63FAC0D034D9F79301010101010101010123456789ABCDEF617B3A0CE8F071001F1F1F1F0E0E0E0E0123456789ABCDEFDB958605F8C8C606E0FEE0FEF1FEF1FE0123456789ABCDEFEDBFD1C66C29CCC70000000000000000FFFFFFFFFFFFFFFF355550B2150E2451FFFFFFFFFFFFFFFF0000000000000000CAAAAF4DEAF1DBAE0123456789ABCDEF0000000000000000D5D44FF720683D0DFEDCBA9876543210FFFFFFFFFFFFFFFF2A2BB008DF97C2F2http://www.ecs.soton.ac.uk/~prw99r/ez438/vectors.txt***/};inti,y;unsignedchartmp[8];des_keydes;for(i=0;i<(int)(sizeof(cases)/sizeof(cases[0]));i++){if((err=des_setup(cases[i].key,8,0,&des))!=CRYPT_OK){returnerr;}if(cases[i].mode!=0){des_ecb_encrypt(cases[i].txt,tmp,&des);}else{des_ecb_decrypt(cases[i].txt,tmp,&des);}if(memcmp(cases[i].out,tmp,sizeof(tmp))!=0){returnCRYPT_FAIL_TESTVECTOR;}/*nowseeifwecanencryptallzerobytes1000times,decryptandcomebackwherewestarted*/for(y=0;y<8;y++)tmp[y]=0;for(y=0;y<1000;y++)des_ecb_encrypt(tmp,tmp,&des);for(y=0;y<1000;y++)des_ecb_decrypt(tmp,tmp,&des);for(y=0;y<8;y++)if(tmp[y]!=0)returnCRYPT_FAIL_TESTVECTOR;}returnCRYPT_OK;#endif}intdes_keysize(int*desired_keysize){_ARGCHK(desired_keysize!=NULL);if(*desired_keysize<8){returnCRYPT_INVALID_KEYSIZE;}*desired_keysize=8;returnCRYPT_OK;}28\n4.rsa_make_key函数intrsa_make_key(prng_state*prng,intwprng,intsize,longe,rsa_key*key){mp_intp,q,tmp1,tmp2,tmp3;interr;_ARGCHK(key!=NULL);if((size<(MIN_RSA_SIZE/8))||(size>(MAX_RSA_SIZE/8))){returnCRYPT_INVALID_KEYSIZE;}if((e<3)||((e&1)==0)){returnCRYPT_INVALID_ARG;}if((err=prng_is_valid(wprng))!=CRYPT_OK){returnerr;}if((err=mp_init_multi(&p,&q,&tmp1,&tmp2,&tmp3,NULL))!=MP_OKAY){returnmpi_to_ltc_error(err);}/*makeprimespandq(optimizationprovidedbyWayneScott)*/if((err=mp_set_int(&tmp3,e))!=MP_OKAY){gotoerror;}/*tmp3=e*//*makeprime"p"*/do{if((err=rand_prime(&p,size*4,prng,wprng))!=CRYPT_OK){gotodone;}if((err=mp_sub_d(&p,1,&tmp1))!=MP_OKAY){gotoerror;}/*tmp1=p-1*/if((err=mp_gcd(&tmp1,&tmp3,&tmp2))!=MP_OKAY){gotoerror;}/*tmp2=gcd(p-1,e)*/}while(mp_cmp_d(&tmp2,1)!=0);/*whileedividesp-1*//*makeprime"q"*/do{if((err=rand_prime(&q,size*4,prng,wprng))!=CRYPT_OK){gotodone;}if((err=mp_sub_d(&q,1,&tmp1))!=MP_OKAY){gotoerror;}/*tmp1=q-1*/if((err=mp_gcd(&tmp1,&tmp3,&tmp2))!=MP_OKAY){gotoerror;}/*tmp2=gcd(q-1,e)*/}while(mp_cmp_d(&tmp2,1)!=0);/*whileedividesq-1*//*tmp1=lcm(p-1,q-1)*/if((err=mp_sub_d(&p,1,&tmp2))!=MP_OKAY){gotoerror;}/*tmp2=p-1*//*tmp1=q-1(previousdo/whileloop)*/if((err=mp_lcm(&tmp1,&tmp2,&tmp1))!=MP_OKAY){gotoerror;}/*tmp1=lcm(p-1,q-1)*//*makekey*/if((err=mp_init_multi(&key->e,&key->d,&key->N,&key->dQ,&key->dP,&key->qP,&key->pQ,&key->p,&key->q,NULL))!=MP_OKAY){gotoerror;}if((err=mp_set_int(&key->e,e))!=MP_OKAY){gotoerror2;}/*key->e=e*/if((err=mp_invmod(&key->e,&tmp1,&key->d))!=MP_OKAY){gotoerror2;}/*key->d=1/emodlcm(p-1,q-1)*/if((err=mp_mul(&p,&q,&key->N))!=MP_OKAY){gotoerror2;}/*key->N=pq*//*optimizeforCRTnow*//*finddmodq-1anddmodp-1*/if((err=mp_sub_d(&p,1,&tmp1))!=MP_OKAY){gotoerror2;}/*tmp1=q-1*/if((err=mp_sub_d(&q,1,&tmp2))!=MP_OKAY){gotoerror2;}/*tmp2=p-1*/if((err=mp_mod(&key->d,&tmp1,&key->dP))!=MP_OKAY){gotoerror2;}/*dP=dmodp-1*/if((err=mp_mod(&key->d,&tmp2,&key->dQ))!=MP_OKAY){gotoerror2;}/*dQ=dmodq-1*/if((err=mp_invmod(&q,&p,&key->qP))!=MP_OKAY){gotoerror2;}/*qP=1/qmodp*/if((err=mp_mulmod(&key->qP,&q,&key->N,&key->qP))!=MP_OKAY){gotoerror2;}/*qP=q*(1/qmodp)modN*/28\nif((err=mp_invmod(&p,&q,&key->pQ))!=MP_OKAY){gotoerror2;}/*pQ=1/pmodq*/if((err=mp_mulmod(&key->pQ,&p,&key->N,&key->pQ))!=MP_OKAY){gotoerror2;}/*pQ=p*(1/pmodq)modN*/if((err=mp_copy(&p,&key->p))!=MP_OKAY){gotoerror2;}if((err=mp_copy(&q,&key->q))!=MP_OKAY){gotoerror2;}/*shrinkramrequired*/if((err=mp_shrink(&key->e))!=MP_OKAY){gotoerror2;}if((err=mp_shrink(&key->d))!=MP_OKAY){gotoerror2;}if((err=mp_shrink(&key->N))!=MP_OKAY){gotoerror2;}if((err=mp_shrink(&key->dQ))!=MP_OKAY){gotoerror2;}if((err=mp_shrink(&key->dP))!=MP_OKAY){gotoerror2;}if((err=mp_shrink(&key->qP))!=MP_OKAY){gotoerror2;}if((err=mp_shrink(&key->pQ))!=MP_OKAY){gotoerror2;}if((err=mp_shrink(&key->p))!=MP_OKAY){gotoerror2;}if((err=mp_shrink(&key->q))!=MP_OKAY){gotoerror2;}err=CRYPT_OK;key->type=PK_PRIVATE_OPTIMIZED;gotodone;error2:mp_clear_multi(&key->d,&key->e,&key->N,&key->dQ,&key->dP,&key->qP,&key->pQ,&key->p,&key->q,NULL);error:err=mpi_to_ltc_error(err);done:mp_clear_multi(&tmp3,&tmp2,&tmp1,&p,&q,NULL);returnerr;}5.rsa_encrypt_key函数intrsa_encrypt_key(constunsignedchar*inkey,unsignedlonginlen,unsignedchar*outkey,unsignedlong*outlen,constunsignedchar*lparam,unsignedlonglparamlen,prng_state*prng,intprng_idx,inthash_idx,rsa_key*key){unsignedlongmodulus_bitlen,modulus_bytelen,x;interr;_ARGCHK(inkey!=NULL);_ARGCHK(outkey!=NULL);_ARGCHK(outlen!=NULL);_ARGCHK(key!=NULL);/*validprngandhash?*/if((err=prng_is_valid(prng_idx))!=CRYPT_OK){returnerr;}if((err=hash_is_valid(hash_idx))!=CRYPT_OK){returnerr;}/*getmodulusleninbits*/modulus_bitlen=mp_count_bits(&(key->N));/*outlenmustbeatleastthesizeofthemodulus*/modulus_bytelen=mp_unsigned_bin_size(&(key->N));if(modulus_bytelen>*outlen){returnCRYPT_BUFFER_OVERFLOW;}/*OAEPpadthekey*/x=*outlen;if((err=pkcs_1_oaep_encode(inkey,inlen,lparam,lparamlen,modulus_bitlen,prng,prng_idx,hash_idx,outkey,&x))!=CRYPT_OK){returnerr;}28\n/*rsaexptmodtheOAEPpad*/returnrsa_exptmod(outkey,x,outkey,outlen,PK_PUBLIC,prng,prng_idx,key);}6.md5_init函数voidmd5_init(hash_state*md){_ARGCHK(md!=NULL);md->md5.state[0]=0x67452301UL;md->md5.state[1]=0xefcdab89UL;md->md5.state[2]=0x98badcfeUL;md->md5.state[3]=0x10325476UL;md->md5.curlen=0;md->md5.length=0;}7.md5_process函数intmd5_process(md5_state*md,constunsignedchar*buf,unsignedlonglen){unsignedlongn;_ARGCHK(md!=NULL);_ARGCHK(buf!=NULL);if(md->curlen>sizeof(md->buf)){returnCRYPT_INVALID_ARG;}while(len>0){if(md->curlen==0&&len>=len){md5_compress(md,(unsignedchar*)buf);md->length+=len*8;buf+=len;len-=len;}else{n=MIN(len,(len-md->curlen));memcpy(md->buf+md->curlen,buf,(size_t)n);md->curlen+=n;buf+=n;len-=n;if(md->curlen==len){md5_compress(md,md->buf);md->length+=8*len;md->curlen=0;}}}returnCRYPT_OK;}8.md5_done函数intmd5_done(hash_state*md,unsignedchar*hash){inti;_ARGCHK(md!=NULL);_ARGCHK(hash!=NULL);if(md->md5.curlen>=sizeof(md->md5.buf)){returnCRYPT_INVALID_ARG;}/*increasethelengthofthemessage*/md->md5.length+=md->md5.curlen*8;/*appendthe'1'bit*/md->md5.buf[md->md5.curlen++]=(unsignedchar)0x80;/*ifthelengthiscurrentlyabove56bytesweappendzeros*thencompress.Thenwecanfallbacktopaddingzerosandlength*encodinglikenormal.*/28\nif(md->md5.curlen>56){while(md->md5.curlen<64){md->md5.buf[md->md5.curlen++]=(unsignedchar)0;}md5_compress(md,md->md5.buf);md->md5.curlen=0;}/*padupto56bytesofzeroes*/while(md->md5.curlen<56){md->md5.buf[md->md5.curlen++]=(unsignedchar)0;}/*storelength*/STORE64L(md->md5.length,md->md5.buf+56);md5_compress(md,md->md5.buf);/*copyoutput*/for(i=0;i<4;i++){STORE32L(md->md5.state[i],hash+(4*i));}#ifdefCLEAN_STACKzeromem(md,sizeof(hash_state));#endifreturnCRYPT_OK;}9.md5_test函数intmd5_test(void){#ifndefLTC_TESTreturnCRYPT_NOP;#elsestaticconststruct{char*msg;unsignedcharhash[16];}tests[]={{"",{0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e}},{"a",{0x0c,0xc1,0x75,0xb9,0xc0,0xf1,0xb6,0xa8,0x31,0xc3,0x99,0xe2,0x69,0x77,0x26,0x61}},{"abc",{0x90,0x01,0x50,0x98,0x3c,0xd2,0x4f,0xb0,0xd6,0x96,0x3f,0x7d,0x28,0xe1,0x7f,0x72}},{"messagedigest",{0xf9,0x6b,0x69,0x7d,0x7c,0xb7,0x93,0x8d,0x52,0x5a,0x2f,0x31,0xaa,0xf1,0x61,0xd0}},{"abcdefghijklmnopqrstuvwxyz",{0xc3,0xfc,0xd3,0xd7,0x61,0x92,0xe4,0x00,0x7d,0xfb,0x49,0x6c,0xca,0x67,0xe1,0x3b}},{"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",{0xd1,0x74,0xab,0x98,0xd2,0x77,0xd9,0xf5,0xa5,0x61,0x1c,0x2c,0x9f,0x41,0x9d,0x9f}},{"12345678901234567890123456789012345678901234567890123456789012345678901234567890",{0x57,0xed,0xf4,0xa2,0x2b,0xe3,0xc9,0x55,0xac,0x49,0xda,0x2e,0x21,0x07,0xb6,0x7a}},{NULL,{0}}};inti;unsignedchartmp[16];hash_statemd;for(i=0;tests[i].msg!=NULL;i++){md5_init(&md);md5_process(&md,(unsignedchar*)tests[i].msg,(unsignedlong)strlen(tests[i].msg));md5_done(&md,tmp);if(memcmp(tmp,tests[i].hash,16)!=0){28\nreturnCRYPT_FAIL_TESTVECTOR;}}returnCRYPT_OK;#endif}10.sha1.c#include"mycrypt.h"#ifdefSHA1conststruct_hash_descriptorsha1_desc={"sha1",2,20,64,/*DERidentifier*/{0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14},15,&sha1_init,&sha1_process,&sha1_done,&sha1_test};#defineF0(x,y,z)(z^(x&(y^z)))#defineF1(x,y,z)(x^y^z)#defineF2(x,y,z)((x&y)|(z&(x|y)))#defineF3(x,y,z)(x^y^z)#ifdefCLEAN_STACKstaticvoid_sha1_compress(hash_state*md,unsignedchar*buf)#elsestaticvoidsha1_compress(hash_state*md,unsignedchar*buf)#endif{ulong32a,b,c,d,e,W[80],i;#ifdefSMALL_CODEulong32t;#endif/*copythestateinto512-bitsintoW[0..15]*/for(i=0;i<16;i++){LOAD32H(W[i],buf+(4*i));}/*copystate*/a=md->sha1.state[0];b=md->sha1.state[1];c=md->sha1.state[2];d=md->sha1.state[3];e=md->sha1.state[4];/*expandit*/for(i=16;i<80;i++){W[i]=ROL(W[i-3]^W[i-8]^W[i-14]^W[i-16],1);}/*compress*//*roundone*/#defineFF0(a,b,c,d,e,i)e=(ROL(a,5)+F0(b,c,d)+e+W[i]+0x5a827999UL);b=ROL(b,30);#defineFF1(a,b,c,d,e,i)e=(ROL(a,5)+F1(b,c,d)+e+W[i]+0x6ed9eba1UL);b=ROL(b,30);#defineFF2(a,b,c,d,e,i)e=(ROL(a,5)+F2(b,c,d)+e+W[i]+0x8f1bbcdcUL);b=ROL(b,30);#defineFF3(a,b,c,d,e,i)e=(ROL(a,5)+F3(b,c,d)+e+W[i]+0xca62c1d6UL);b=ROL(b,30);28\n#ifdefSMALL_CODEfor(i=0;i<20;){FF0(a,b,c,d,e,i++);t=e;e=d;d=c;c=b;b=a;a=t;}for(;i<40;){FF1(a,b,c,d,e,i++);t=e;e=d;d=c;c=b;b=a;a=t;}for(;i<60;){FF2(a,b,c,d,e,i++);t=e;e=d;d=c;c=b;b=a;a=t;}for(;i<80;){FF3(a,b,c,d,e,i++);t=e;e=d;d=c;c=b;b=a;a=t;}#elsefor(i=0;i<20;){FF0(a,b,c,d,e,i++);FF0(e,a,b,c,d,i++);FF0(d,e,a,b,c,i++);FF0(c,d,e,a,b,i++);FF0(b,c,d,e,a,i++);}/*roundtwo*/for(;i<40;){FF1(a,b,c,d,e,i++);FF1(e,a,b,c,d,i++);FF1(d,e,a,b,c,i++);FF1(c,d,e,a,b,i++);FF1(b,c,d,e,a,i++);}/*roundthree*/for(;i<60;){FF2(a,b,c,d,e,i++);FF2(e,a,b,c,d,i++);FF2(d,e,a,b,c,i++);FF2(c,d,e,a,b,i++);FF2(b,c,d,e,a,i++);}/*roundfour*/for(;i<80;){FF3(a,b,c,d,e,i++);FF3(e,a,b,c,d,i++);FF3(d,e,a,b,c,i++);FF3(c,d,e,a,b,i++);FF3(b,c,d,e,a,i++);}#endif#undefFF0#undefFF1#undefFF2#undefFF3/*store*/md->sha1.state[0]=md->sha1.state[0]+a;md->sha1.state[1]=md->sha1.state[1]+b;md->sha1.state[2]=md->sha1.state[2]+c;md->sha1.state[3]=md->sha1.state[3]+d;md->sha1.state[4]=md->sha1.state[4]+e;}28\n#ifdefCLEAN_STACKstaticvoidsha1_compress(hash_state*md,unsignedchar*buf){_sha1_compress(md,buf);burn_stack(sizeof(ulong32)*87);}#endifvoidsha1_init(hash_state*md){_ARGCHK(md!=NULL);md->sha1.state[0]=0x67452301UL;md->sha1.state[1]=0xefcdab89UL;md->sha1.state[2]=0x98badcfeUL;md->sha1.state[3]=0x10325476UL;md->sha1.state[4]=0xc3d2e1f0UL;md->sha1.curlen=0;md->sha1.length=0;}HASH_PROCESS(sha1_process,sha1_compress,sha1,64)intsha1_done(hash_state*md,unsignedchar*hash){inti;_ARGCHK(md!=NULL);_ARGCHK(hash!=NULL);if(md->sha1.curlen>=sizeof(md->sha1.buf)){returnCRYPT_INVALID_ARG;}/*increasethelengthofthemessage*/md->sha1.length+=md->sha1.curlen*8;/*appendthe'1'bit*/md->sha1.buf[md->sha1.curlen++]=(unsignedchar)0x80;/*ifthelengthiscurrentlyabove56bytesweappendzeros*thencompress.Thenwecanfallbacktopaddingzerosandlength*encodinglikenormal.*/if(md->sha1.curlen>56){while(md->sha1.curlen<64){md->sha1.buf[md->sha1.curlen++]=(unsignedchar)0;}sha1_compress(md,md->sha1.buf);md->sha1.curlen=0;}/*padupto56bytesofzeroes*/while(md->sha1.curlen<56){md->sha1.buf[md->sha1.curlen++]=(unsignedchar)0;}/*storelength*/STORE64H(md->sha1.length,md->sha1.buf+56);sha1_compress(md,md->sha1.buf);/*copyoutput*/for(i=0;i<5;i++){STORE32H(md->sha1.state[i],hash+(4*i));}#ifdefCLEAN_STACKzeromem(md,sizeof(hash_state));#endifreturnCRYPT_OK;}28\nintsha1_test(void){#ifndefLTC_TESTreturnCRYPT_NOP;#elsestaticconststruct{char*msg;unsignedcharhash[20];}tests[]={{"abc",{0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,0xba,0x3e,0x25,0x71,0x78,0x50,0xc2,0x6c,0x9c,0xd0,0xd8,0x9d}},{"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",{0x84,0x98,0x3E,0x44,0x1C,0x3B,0xD2,0x6E,0xBA,0xAE,0x4A,0xA1,0xF9,0x51,0x29,0xE5,0xE5,0x46,0x70,0xF1}}};inti;unsignedchartmp[20];hash_statemd;for(i=0;i<(int)(sizeof(tests)/sizeof(tests[0]));i++){sha1_init(&md);sha1_process(&md,(unsignedchar*)tests[i].msg,(unsignedlong)strlen(tests[i].msg));sha1_done(&md,tmp);if(memcmp(tmp,tests[i].hash,20)!=0){returnCRYPT_FAIL_TESTVECTOR;}}returnCRYPT_OK;#endif}#endif28