椭圆曲线密码的C语言设计与实现
一种椭圆曲线密码加密算法及其实现

"
引 言
( -/012(3.)45/63,78154) 算法自提出以来一 -., 直是公开密钥密码编码学的经典算法。但最近, 一 种新 的 椭 圆 曲 线 密 码 编 码 学 9::( 988/;(/< :=601 :6>;(’?64;)>)逐步显示出它的竞争力。 9:: 关注的
[@] 是一条定义在有限域上的椭圆曲线 。有限域是包
龚
书等: 一种椭圆曲线密码加密算法及其实现
一种椭圆曲线密码加密算法及其实现 !
龚 书" 刘文江 戎蒙恬
上海 !"""#") (上海交通大学电子工程系
摘
提出了一种在椭圆曲线有限域求取 $ ・% 的算法及其实现。该算法将改进的 大大地降低了迭代次数和有限域运算。 $ ・% 核心结构的设计使 &’’() 算法嵌入传统算法,
图! ・ " # 总体结构
$*$ &*&*+
各部分的实现 外部引脚 ・ 如图 & 所示。 ./0 高 定义 , - 核心有 ’ 个引脚,
(&) 式的乘法单位电路的结构, ( 是基于 ! 代表逻辑 或门, &’ 为开关。由该结构可方便地 得 到 ()*)+ 和 从而使有限域乘法的时间减半。 (,-- 的电路结构图, 如果使用与传统乘法器相同的资源, 该乘法器可将 速度提高 + * A 倍, 因此并没有必要花费两倍的资源 来获得两倍的速度提高。
要
各硬件部分独立于数据长度和乘除法算法, 增强了系统的可移植性。系统采用 *%+, 实 现, 可以方便地应用于加解密和数字签名。 关键词 椭圆曲线密码学, 有限域乘法器, 有限域乘法逆元, ・ $ % 实现 最关键部分。本部分先改写在伽罗瓦域的多项式乘 法公式, 然后提出一种新的有限域乘法器结构。 我们 在 +* ( !! ) 考 虑 算 术 操 作。 若 * ( .) /
椭圆曲线加密算法的研究与实现

椭圆曲线加密算法的研究与实现椭圆曲线加密算法(Elliptic Curve Cryptography,ECC)是一种基于数论的加密算法,可用于保护数据的机密性和完整性。
相较于传统的RSA和DSA等加密算法,ECC在提供相同的安全性的情况下,使用更短的密钥长度,计算速度更快,适用于资源受限的环境,如移动设备和物联网。
1.参数选择:选择一条合适的椭圆曲线,确定椭圆曲线上的基点以及有限域的大小。
2.密钥生成:随机选择一个私钥,计算公钥。
3.加密:选择一个随机数作为加密密钥,将原始数据转换成椭圆曲线上的点,使用公钥和随机数进行数乘运算得到加密后的点,并将其转换为密文。
4.解密:使用私钥对密文进行解密,即进行数乘运算得到明文点,并将其转换为原始数据。
5.密钥交换:两个通信方通过交换公钥来协商密钥。
在实际应用中,ECC已被广泛应用于数字签名、密钥交换、公钥加密等方面。
比如,ECC在TLS/SSL协议中的使用可以提供安全的通信。
以及在密码芯片等硬件设备中,也广泛使用ECC算法来提供安全的数据存储和通信。
对于椭圆曲线加密算法的实现,需要考虑如下几个方面:1.参数选择:选择合适的椭圆曲线参数,如曲线方程、取模素数、基点等。
2.有限域运算:实现有限域上的点加法和数乘运算,包括点相加的算法、点相乘的算法。
3.密钥生成:实现私钥的生成以及公钥的计算。
4.加密和解密:实现明文数据到椭圆曲线上的点的转换,以及椭圆曲线上的点到密文数据的转换,同时实现数乘运算。
5.密钥交换:实现公钥的传递和协商密钥的过程。
对于实现椭圆曲线加密算法,可以选择使用编程语言提供的大数运算库来处理大整数运算,这样可以方便地进行椭圆曲线上的运算。
常用的编程语言,如C++、Java、Python等都有相应的大数运算库可供使用。
总结而言,椭圆曲线加密算法是一种高效且安全的加密算法,其在多个领域具有广泛的应用前景。
实现椭圆曲线加密算法需要对椭圆曲线的数学原理有深入理解,同时需要实现各种运算和参数选择的算法。
ecc算法c语言实现

ecc算法c语言实现一、介绍ECC(Elliptic Curve Cryptography)椭圆曲线加密算法是一种公钥密码学,它利用椭圆曲线上的数学原理,实现了比传统RSA算法更高的安全性和更小的密钥长度。
ECC算法已经被广泛应用于移动设备、物联网等领域。
二、椭圆曲线基础知识1. 椭圆曲线方程椭圆曲线可以用如下的方程表示:y² = x³ + ax + b其中a和b是常数,x和y是变量。
这个方程描述了一个平面上的点集合,这个点集合形成了一个封闭的曲线。
2. 椭圆曲线上的运算在椭圆曲线上有两种运算:加法和乘法。
加法:两个不同点P(x1, y1)和Q(x2, y2)相加得到R(x3, y3),其中x3 = λ² - x1 - x2,y3 = λ(x1 - x3) - y1,λ = (y2 - y1) / (x2 - x1)乘法:将点P与一个整数k相乘得到另一个点Q,即Q = kP。
三、ECC算法实现步骤1. 寻找合适的椭圆曲线选择一个合适的椭圆曲线是ECC算法的第一步。
通常情况下,我们会选择一条已经被广泛使用并且被认为是安全的椭圆曲线。
2. 生成公私钥对在ECC算法中,公钥由椭圆曲线上的一个点P和一个整数n组成,私钥由一个整数d组成。
其中n是P点的阶(即nP = O),d是一个随机数。
3. 加密和解密加密:将明文M转换为椭圆曲线上的点P,然后选择一个随机数k,并计算C1 = kP和C2 = kQ + M,其中Q是接收者的公钥。
最终加密结果为(C1, C2)。
解密:接收到加密数据(C1, C2)后,用私钥d计算出Q = dP,并将C1乘以d得到C1' = dC1。
然后用C1'减去C2得到明文M。
四、ECC算法C语言实现以下是ECC算法在C语言中的实现代码:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <openssl/ec.h>#include <openssl/ecdsa.h>#include <openssl/obj_mac.h>int main(){// 生成公私钥对EC_KEY *key;key = EC_KEY_new_by_curve_name(NID_secp256k1);EC_KEY_generate_key(key);const EC_GROUP *group = EC_KEY_get0_group(key);const BIGNUM *priv_key = EC_KEY_get0_private_key(key); const EC_POINT *pub_key = EC_KEY_get0_public_key(key);// 显示公私钥char *priv_hex = BN_bn2hex(priv_key);printf("Private key: %s\n", priv_hex);char *pub_hex = EC_POINT_point2hex(group, pub_key, POINT_CONVERSION_UNCOMPRESSED, NULL);printf("Public key: %s\n", pub_hex);// 加密和解密unsigned char plaintext[] = "Hello world";size_t plaintext_len = strlen(plaintext);// 加密unsigned char ciphertext[128];size_t ciphertext_len;ECDSA_SIG *sig;do {sig = ECDSA_do_sign(plaintext, plaintext_len, key); if (sig == NULL) {printf("Error signing message\n");break;}int r_len = BN_num_bytes(sig->r);int s_len = BN_num_bytes(sig->s);if (r_len + s_len > 127) {printf("Error: signature too long\n");break;}memset(ciphertext, 0, sizeof(ciphertext));memcpy(ciphertext, sig->r, r_len);memcpy(ciphertext + r_len, sig->s, s_len);ciphertext_len = r_len + s_len;printf("Encrypted data: ");for (int i=0; i<ciphertext_len; i++) {printf("%02x", ciphertext[i]);}printf("\n");// 解密sig->r = BN_bin2bn(ciphertext, r_len, sig->r);sig->s = BN_bin2bn(ciphertext + r_len, s_len, sig->s);int verify_result = ECDSA_do_verify(plaintext, plaintext_len, sig, key);if (verify_result == 1) {printf("Decrypted data: %s\n", plaintext);} else {printf("Error decrypting data\n");}} while(0);// 释放资源EC_KEY_free(key);free(priv_hex);free(pub_hex);return 0;}以上代码使用了OpenSSL库中的ECDSA函数来实现ECC算法。
椭圆曲线加密算法的研究与实现

椭圆曲线加密算法的研究与实现椭圆曲线加密算法是目前应用最广泛的公钥加密算法,具有难以破解、高效快速、安全稳定等特点,是构建安全的密钥交换协议和数据传输机制的基础,目前在军事、政府、金融、电信等领域应用越来越广泛,因此,研究椭圆曲线加密算法具有重要的现实意义。
一、椭圆曲线加密算法的基础原理椭圆曲线加密算法是建立在参数检验上的一种数论函数的安全加密算法。
它的基本思想是,在一个高维空间,首先选定一条椭圆曲线,然后根据其参数定义一个数位函数,最后用这个函数来进行加密解密。
其参数包括椭圆曲线上的整数点、椭圆曲线的参数、离散对数求解器、变换矩阵、模量等。
椭圆曲线加密算法通过对椭圆曲线参数的不同构造出不同的密钥,每次传输都可以构造出不同的加密算法,保证了每次传输的安全性。
二、椭圆曲线加密算法的研究及实现(一)研究1.椭圆曲线原理的研究:研究椭圆曲线的定义,研究椭圆曲线参数的等价定义,研究椭圆曲线参数对密钥安全性的影响;2.椭圆曲线算法实现的研究:研究加密算法的矩阵变换过程,研究其实现中的算法、数据结构;3.椭圆曲线算法安全性的研究:研究不同的攻击策略,探究破解椭圆曲线加密算法的方法;4.椭圆曲线密钥的优化研究:探究优化椭圆曲线密钥的有效方法;(二)实现1.建加密编码结构:建立椭圆曲线参数的数据结构;2.写加密解密程序代码:编写算法实现加密解密程序,代码实现矩阵变换;3.试椭圆曲线加密算法:测试算法对密钥安全性、加密效率、传输安全性等的效果,并对结果做出评估;4.椭圆曲线加密算法进行优化:对椭圆曲线的参数进行分析,通过优化参数提高椭圆曲线算法的安全性。
三、结论椭圆曲线加密算法是目前应用最为广泛的公钥加密算法,对于建立安全的密钥交换协议和数据传输机制具有重要的现实意义。
研究者应该深入研究椭圆曲线加密算法的原理、实现、安全性和优化,为椭圆曲线加密算法的应用提供保障和支持。
c语言实现椭圆曲线密钥交换

椭圆曲线密钥交换(ECDH)是一种在公开通信通道上安全地生成共享密钥的方法。
以下是使用C语言实现椭圆曲线密钥交换的步骤:1. 引入必要的头文件。
2. 定义椭圆曲线参数,如p、a、b和G。
3. 生成私钥和公钥。
4. 计算共享密钥。
以下是一个简单的示例代码:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <openssl/ecdsa.h>#include <openssl/obj_mac.h>#include <openssl/bn.h>#define CURVE_NAME "secp256r1"#define PRIVATE_KEY_LENGTH 32#define PUBLIC_KEY_LENGTH 64#define SHARED_KEY_LENGTH 32void generate_keypair(unsigned char *private_key, unsigned char *public_key) { EC_KEY *key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);if (!key) {printf("Error generating key pair");exit(1);}if (!EC_KEY_generate_key(key)) {printf("Error generating key pair");EC_KEY_free(key);exit(1);}const BIGNUM *priv_num = EC_KEY_get0_private_key(key);BN_bn2bin(priv_num, private_key);const EC_POINT *pub_point = EC_KEY_get0_public_key(key);const EC_GROUP *group = EC_KEY_get0_group(key);ECDSA_SIG *sig = ECDSA_do_sign(NULL, NULL, strlen("message"), (unsigned char*)"message", strlen("message"), NULL, NULL);ECDSA_SIG_to_string(sig, (unsigned char *)public_key, PUBLIC_KEY_LENGTH);EC_KEY_free(key);}void calculate_shared_key(unsigned char *private_key, unsigned char *public_key, unsigned char *shared_key) {EC_KEY *key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);if (!key) {printf("Error calculating shared key");exit(1);}if (!EC_KEY_set_private_key(key, BN_bin2bn(private_key, PRIVATE_KEY_LENGTH, NULL))) {printf("Error setting private key");EC_KEY_free(key);exit(1);}const EC_POINT *pub_point = EC_POINT_new(EC_KEY_get0_group(key));BN_bin2bn(public_key, PUBLIC_KEY_LENGTH, pub_point);const BIGNUM *priv_num = EC_KEY_get0_private_key(key);const EC_GROUP *group = EC_KEY_get0_group(key);ECDSA_SIG *sig = ECDSA_do_sign(NULL, NULL, strlen("message"), (unsigned char *)"message", strlen("message"), NULL, NULL);ECDSA_SIG_to_string(sig, (unsigned char *)shared_key, SHARED_KEY_LENGTH);EC_POINT_free(pub_point);EC_KEY_free(key);}int main() {unsigned char private_key[PRIVATE_KEY_LENGTH];unsigned char public_key[PUBLIC_KEY_LENGTH];unsigned char shared_key[SHARED_KEY_LENGTH];generate_keypair(private_key, public_key);calculate_shared_key(private_key, public_key, shared_key);printf("Private Key: %s", private_key);printf("Public Key: %s", public_key);printf("Shared Key: %s", shared_key);return 0;}```注意:这个示例代码使用了OpenSSL库,你需要在你的项目中包含并链接这个库。
利用C语言实现基于椭圆加密曲线算法的密钥交换

利用c语言实现基于椭圆加密曲线算法的密钥交换牛佳辉(同济大学汽车学院,上海201804)摘要:在密码学的实际应用中,主要以R S A算法和椭圆曲线加密算法为主,R S A算法是现代公钥密码体制事实上的标 准,既能用于数据的加解密计算也能用于签名。
但椭圆曲线加密算法与它相比,安全性高、处理速度快、存储空间占用小 和对宽带要求低等优点,更适合使用在汽车方面。
文章重点介绍椭圆曲线加密算法原理,研究在密钥交换方面的应用以 及在C语言中具体实现过程。
关键词:椭圆曲线加密算法;密钥交换(ECDH);C语言;应用中图分类号:TP309.7 文献标识码:A文章编号=1673-1131(2017)04-0023-02〇引言随着物联网概念的提出和相关研究的不断拓展,车联网 作为物联网在智能交通领域的应用,越来越受到人们的重视。
交通信息共享是车辆自组网的最基本最核心的应用。
但是,由于车联网中数以亿计的流动设备接入和管理、海量的数据 和信息、大量异构网络、众多复杂的应用业务和用户群的存在 使得信息通信安全面临着更为严峻的挑战,因此,本文将利用 密码学的相关知识运用到车辆内部数据传输之间,阻止黑客 对汽车的远程攻击和物理攻击。
1密码学的加密算法介绍加密算法按照密钥形式而言分类,一般分为两种,一种是 对称加密算法,另一种是非对称加密算法。
对称加密算法和 非对称加密算法之间的不同,在于加解密时对于密钥的使用 方式的不同。
采用对称加密时,通信的双方只需要相同的密 钥,发送方使用该密钥对发送的数据加密,接收方使用该密钥 对接收的数据解密,发送和接收双方都需要知道该密钥,该密 钥在发送双方之间传输的过程中被第三方获取,我们对数据 加密就没有任何意义了,因此对称密钥如何将密钥安全地发 送到对方手里,也成为了该算法的难题。
而非对称加密算法需要一对密钥,一个叫做公钥,另一个 叫做私钥。
这对密钥总是成对出现的,如果用公钥加密就需 要私钥解密,如果用私钥加密就需要公钥解密。
椭圆曲线公钥密码加密方法的C语言实现

2007 年 第 10 期
椭圆曲线公钥密码加密方法的 C 语言实现
郭其标 ( 嘉应学院计算中心 广东 梅州 514031)
摘要: 随着计算机网络与通信技术的迅速发展, 信息安全问题日益突出。解决此问题的一种有效方法是数据加密与解密技术。本文从实现 的角度, 对椭圆曲线公钥密码加密方法进行了研究。论述了椭圆曲线运算的数学背景, 以及椭圆曲线加密算法的原理, 我的主要工作是用 C 语 言编程实现了该方法。
椭圆曲线加密算法的C语言设计和实现

椭圆曲线加密算法的C语言设计和实现椭圆曲线加密算法于1985年提出,由于自身优点,它一出现便受到关注,现在密码学界普遍认为它将替代RSA加密算法成为通用的公钥加密算法。
那么我们今天就来看看椭圆曲线加密算法是如何通过C语言来设计实现的。
一、椭圆曲线加密算法的C语言设计1、椭圆曲线加密系统的基本结构椭圆曲线的加解密流程如图1所示:椭圆曲线进行加密通信的过程如下:首先选定一个适合加密的椭圆曲线Ep(a,b),并取椭圆曲线上的一点作为基点G。
选择一个私有密钥k,并生成公开密钥K=kG。
加密时,将明文编码到Ep(a,b)上的一点M,并产生一个随机整数r(r<n)。
计算点C1=M+rK,C2=rGo将C1、C2存入密文。
解密时,从密文中读出CI、C2,计算C1-kC2,根据C1-kC2=M+rK-k( rG)=M+rK-r( kG)=M,解得的结果就是点M,即明文。
2、高精度整数的表示加密算法几乎都是建立在高精度大整数的运算上,而一般的程序语言都不提供大整数的结构,因此要表示上百位的高精度整数需另辟蹊径。
本文使用了LibT omMath库的高精度整数结构。
LibTomMath是一个计算高精度整数的库的开源软件,由加拿大人汤姆St.丹尼斯编写,用标准C语言写了几乎所有标准的密码算法模块,并且在几乎所有的操作系统下都可执行。
LibT omMath库对高精度大整数的表示是该库最大的一个特点。
在LibT omMath库中的高精度大整数表示如下:在32位机上unsigned long为32bit,用mp_digit表示这个类型:typedef unsigned_long mp_digit;实际使用了32位的28位,少用4位,因此用16进制表示一个mp_digit为0XXXXXXX,其中X为16进制数字,将这个32位bit串称为一个mp_digit单元,若干个mp_digit单元构成一个大整数,结构定义一个大整数mpint如下:typeclef struct {inl used,alloc,sign;mp_digit *dp;) mp_int;其中:dp是存放大整数的地址,将大整数(二进比特串)分段(mp_digit单元)存放在从该地址起的内存里,缺省时分配dp为MP_PREC=64个mp_digit单元,即alloc =64;used 为实际使用的mp_digit单元;sign=0表示非负数,为1表示负数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机研究生开放研究《椭圆曲线密码的C语言设计与实现》美国GeneChiu基金资助基于TOM算法库的ECC加密算法的C语言设计与实现研究生徐立均内容:一、源代码下载二、ECC算法的设计思想三、椭圆曲线参数的选取和基点的确定四、椭圆曲线的点加和纯量乘法五、加密文件的读入与输出六、密文的存取和读入七、ECC加密的实现八、ECC解密的实现九、测试结果及分析一、源代码下载本文使用了TOM算法库实现了椭圆曲线公钥密码体制,能对各类不同的磁盘文件进行加密和解密。
1 请下载可执行程序MY_ECC.exe,此程序无需任何额外的LIB或DLL,可在Windows下独立运行,运行情况如下:2 请下载源代码source.rar:编译此源代码需要使用TOM的高精度算法库MathLib.lib和相关的头文件tommath.htommath_class.htommath_superclass.h一并打包在source.rar中,请下载3 对于TOM的高精度算法库的详细说明,请看本站C语言:二、 ECC算法的设计思想根据椭圆曲线进行加密通信的过程,首先选定一个适合加密的椭圆曲线Ep(a,b),并取椭圆曲线上一点,作为基点G。
选择一个私有密钥k,并生成公开密钥K=kG。
加密时,将明文编码到Ep(a,b)上一点M,并产生一个随机整数r(r < n)。
计算点C1=M+rK;C2=rG。
将C1、C2存入密文。
解密时,从密文中读出C1、C2,计算C1-kC2,根据:C1-kC2=M+rK-k(rG)=M+rK-r(kG)=M,解得的结果就是点M,即明文。
三、椭圆曲线参数的选取和基点的确定并不是所有的椭圆曲线都适合加密,y^2=x^3+ax+b是一类可以用来加密的椭圆曲线,也是最为简单的一类。
下面我们就选用y^2=x^3+ax+b作为我们的加密曲线。
这条曲线定义在Fp上:两个满足下列条件的小于p(p为素数)的非负整数a、b:4a3+27b2≠0 (mod p) 则满足下列方程的所有点(x,y),再加上无穷远点∞ ,构成一条椭圆曲线。
y^2=x^3+ax+b(mod p) 其中 x,y属于0到p-1间的整数,并将这条椭圆曲线记为Ep(a,b)。
参数P的选取:p 当然越大越安全,但越大,计算速度会变慢,200位左右可以满足一般安全要求;我们将p取为200比特位的素数。
参数a、b的选取:先随机产生小于P-1的正整数作为参数a,依据条件4a3+27b2≠0 (mod p)判断随机产生的小于P-1的正整数是否适合作为参数b.基点的确定:随着参数a,b,p确定,这条曲线y^2=x^3+ax+b就定下来了。
先随机产生0到p-1间的整数作为基点x坐标,计算x^3+ax+b 的结果再开方就得出基点y坐标。
上述具体程序实现如下:……while(1){//4a3+27b2≠0 (mod p)GetPrime(b,40);//先随机产生一个参数Bmp_expt_d(a, 3, &temp1);mp_sqr(b, &temp2);mp_mul_d(&temp1, 4, &temp3);mp_mul_d(&temp2, 27, &temp4);mp_add(&temp3, &temp4, &temp5);mp_mod(&temp5,p,&temp);if(mp_cmp(&temp, &compare)!=0 ){break; //满足条件跳出循环}}//y2=x3+ax+b,随机产生X坐标,根据X坐标计算Y坐标GetPrime(x1,30);// 随机产生30比特长的X坐标mp_expt_d(x1, 3, &temp6);mp_mul(a, x1, &temp7);mp_add(&temp6, &temp7, &temp8);mp_add(&temp8, b, &tempx);mp_sqrt(&tempx, y1);//得到Y坐标……..私钥的确定:随机选取1到P-1之间的素数作为私钥d.公钥的确定:由d乘我们所确定的基点得到公钥K,即K=dG。
四、椭圆曲线的点加和纯量乘法对于一般的椭圆曲线方程y^2+a1xy+a3y=x^3+a2x^2+a4x+a6, 设点P(x1,y1),Q(x2,y2)的和R(x3,y3)的坐标。
R(x3,y3)的计算公式如下:x3=k^2+ka1+a2+x1+x2;y3=k(x1-x4)-y1-a1x4-a3;其中k= (y1-y2)/(x1-x2)当P≠Q时k=(3x2+2a2x+a4 -a1y) /(2y+a1x+a3)当P=Q时,对于椭圆曲线方程Y^2=X^3+aX+b,上述的公式变为:x3=θ2- x1-x2;y3=θ(x1-x3)-y1其中θ=(y1-y2)/(x1-x2) 当P≠Q时;θ=(3x1^2-a)/2y1 当P=Q时由上述运算公式,可以得出点积mP的运算,即mP=P+P+…+P,共m个P相加,这里m∈N.具体算法为:设m的二进制表示为m=(m_n-1m_n-2…m1m0),其中m_n-1=1,Q=P,从左到右依次计算:for(I=n-2 to 0){ Q=2Q;if(mi ==1) Q=Q+P;}则Q=mP.Return ;函数原形为:bool Ecc_points_mul(mp_int *qx,mp_int *qy, mp_int *px, mp_int *py,mp_int *d,mp_int*a,mp_int *p)成功返回true。
int Two_points_add(mp_int *x1,mp_int *y1,mp_int *x2,mp_int*y2,mp_int *x3,mp_int*y3,mp_int *a,bool zero,mp_int *p)成功返回1。
五、加密文件的读入与输出mp_digit只用28比特,因此一个单元最多可存放三个半字节。
为充分利用存取空间,采用一个单元放三个半字节。
1.函数putin()实现将明文的二进制比特串赋给mp_int数a:主要循环部分及说明如下://chlong为要存入的字符数组长for(j=0;j<<="(mp_digit)CHAR_BIT;" *temp 存入字符 255); 左移8位存入高8位并向左移8位,以便放入下一个字符 temp跳过前一个单元,先存入后一单元 *++temp 每次跳七个字符 i+="7;" 的两个单元中以7个字符为单元循环,把七个字符放入的mp_int 7;j++){>> 4); //存放被切分的字符的高四位,temp跳回前一个单元//存入第一单元*temp |= (mp_digit)(ch[i-4] & yy); //存放被切分的字符的低四位,yy=(mp_digit)15*temp <<= (mp_digit)CHAR_BIT; //向左移8位,以便放入下一个字符*temp |= (mp_digit)(ch[i-5] & 255); //存入字符*temp <<= (mp_digit)CHAR_BIT; //左移8位 *temp |= (mp_digit)(ch[i-6] & 255); //存入字符*temp <<= (mp_digit)CHAR_BIT; //左移8位 *temp++ |= (mp_digit)(ch[i-7] & 255); //存放被切分的字符的低四位,temp跳到后一个单元temp++; //再向后跳一单元,这样和下次的++temp实现每次循环跳两个单元}函数原型为:int putin(mp_int *a,char *ch,int chlong)成功返回02.函数chdraw()实现将mp_int数a中的比特串还原为字符串并赋给字符串ch:chdraw和putin是相反过程,将putin存入字符的过程反过来取出字符。
函数原型为:int chdraw(mp_int *a,char *ch)成功返回0六、密文的存取和读入此过程难点是如何保证存入文件后,再从文件中读取密文并存入mp_int型数后,和原存放密文的mp_int型数不能有一个比特位的改变。
存取时先存*mp->dp的最高8位,再依次往下存后面3个8位。
依据*mp->dp的特点,最高8位为0000xxxx,因此,可将255作为一个密文段的结束标志,把前一密文段和后一密文段区分开。
这样在密文文件中,密文的存取结构为:0000xxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|0000xxxx|……|11111111|00 00xxxx|xxxxxxxx|…..0字节 1字节 2字节 3字节 4字节 4x字节下一加密段x为1或0利用fgetc每次读取一个字符,并赋值给一个字符数组。
当a[i]=255,且i%4=0时截止。
读出之后赋值就简单了。
存密文:int chmistore(mp_int *a,FILE *fp) 成功返回0把密文赋给mp_int型数a:int miwendraw(mp_int *a,char *ch,int chlong) 成功返回0七、ECC加密的实现加密时因P长度取值为200比特,所以所取明文长度应在0到199比特之间,另外需要一个附加的标志字节char(255),所以一次取明文最大长为191比特。
在本程序中一次取20字节。
和RSA不同,ECC运算是基于点的运算。
一个点有两个参数,一个X坐标,一个Y坐标。
所以取明文时需一次取两段,前一段做X坐标,后一段做Y坐标。
因此,一次加密明文为40字节。
由于每次加密要取两段,引发了另外一个问题:当加密文件末尾所剩明文长度小于20字节时的处理。
在本程序中,我们的解决是将剩余明文取作X,而将Y取作0,且不加标志字节char(255),这样解密时,程序在Y中找不到标志字节char(255),就不会往解密文中存任何东西。
取得明文后,产生一个随机整数r(r<有限域p),计算点C1=M+rK;C2=rG。
将点C1、C2坐标c1x,c1y,c2x,c2y依次存入密文文件。
for(i=0; i 0)// Residue为剩余字符数{if (Residue <= enlongtemp ){fread(miwenx,1,Residue,fp);//读入字符串miwenx[Residue]=char(255);putin(&mx, miwenx,Residue+1);//文件存入mp_zero(&my);}else{fread(miwenx,1,enlongtemp,fp);//读入字符串miwenx[enlongtemp]=char(255);fread(miweny,1,Residue-enlongtemp,fp);//读入字符串miweny[Residue-enlongtemp]=char(255);putin(&mx, miwenx,enlongtemp+1);//文件存入putin(&my,miweny,Residue-enlongtemp+1);//文件存入}//加密Ecc_points_mul(&c2x,&c2y,px,py,&r,a,p); //C2=rG Ecc_points_mul(&tempx,&tempy,qx,qy,&r,a,p); // rKTwo_points_add(&mx,&my,&tempx,&tempy,&c1x,&c1y,a,zero, p);// C1=M+rK//保存密文chmistore(&c1x,fq);chmistore(&c1y,fq);chmistore(&c2x,fq);chmistore(&c2y,fq);}函数原型为:void Ecc_encipher(mp_int *qx,mp_int *qy, mp_int *px, mp_int *py,mp_int*a,mp_int *p);八、ECC解密的实现解密时,依据存密文时放入的结束标志255,读入密文。