椭圆曲线密码的C语言设计与实现

合集下载

一种椭圆曲线密码加密算法及其实现

一种椭圆曲线密码加密算法及其实现
!0 @ !0 @
"
引 言
( -/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算法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语言实现椭圆曲线密钥交换

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语言实现基于椭圆加密曲线算法的密钥交换

利用c语言实现基于椭圆加密曲线算法的密钥交换牛佳辉(同济大学汽车学院,上海201804)摘要:在密码学的实际应用中,主要以R S A算法和椭圆曲线加密算法为主,R S A算法是现代公钥密码体制事实上的标 准,既能用于数据的加解密计算也能用于签名。

但椭圆曲线加密算法与它相比,安全性高、处理速度快、存储空间占用小 和对宽带要求低等优点,更适合使用在汽车方面。

文章重点介绍椭圆曲线加密算法原理,研究在密钥交换方面的应用以 及在C语言中具体实现过程。

关键词:椭圆曲线加密算法;密钥交换(ECDH);C语言;应用中图分类号:TP309.7 文献标识码:A文章编号=1673-1131(2017)04-0023-02〇引言随着物联网概念的提出和相关研究的不断拓展,车联网 作为物联网在智能交通领域的应用,越来越受到人们的重视。

交通信息共享是车辆自组网的最基本最核心的应用。

但是,由于车联网中数以亿计的流动设备接入和管理、海量的数据 和信息、大量异构网络、众多复杂的应用业务和用户群的存在 使得信息通信安全面临着更为严峻的挑战,因此,本文将利用 密码学的相关知识运用到车辆内部数据传输之间,阻止黑客 对汽车的远程攻击和物理攻击。

1密码学的加密算法介绍加密算法按照密钥形式而言分类,一般分为两种,一种是 对称加密算法,另一种是非对称加密算法。

对称加密算法和 非对称加密算法之间的不同,在于加解密时对于密钥的使用 方式的不同。

采用对称加密时,通信的双方只需要相同的密 钥,发送方使用该密钥对发送的数据加密,接收方使用该密钥 对接收的数据解密,发送和接收双方都需要知道该密钥,该密 钥在发送双方之间传输的过程中被第三方获取,我们对数据 加密就没有任何意义了,因此对称密钥如何将密钥安全地发 送到对方手里,也成为了该算法的难题。

而非对称加密算法需要一对密钥,一个叫做公钥,另一个 叫做私钥。

这对密钥总是成对出现的,如果用公钥加密就需 要私钥解密,如果用私钥加密就需要公钥解密。

椭圆曲线公钥密码加密方法的C语言实现

椭圆曲线公钥密码加密方法的C语言实现
{for (i=0;i<fq&&(mw1.c! =(p2.x*i)%fq);i++); m=i; } return m; } 3.6 结果分析:在程序调试是添加主函数 main ( )即可。 例 1: 从键盘输入“I am a student”, 基点是(3,44), 加密得到的密文 是: (29,17,Ω) (29,17,!) (29,17,!) (29,17,") (29,17,!) (88,98,S) (88,98, ▲) (29,17,¢) (29,17,∑) (29,17, █ ) (29,17,J) (88,98,7) (88,98,w) (29,17, ∑) 解密后输出的结果是: I am a atudent。结果证明, 本程序是正确 的, 可以用于加密和解密。 4.结论 本设计达到了预期的基本功能, 但在程序设计中依然存在不少问 题。以下是本程序需要改进的地方。 (1)程 序 设 计 时 的 有 限 域 的 选 取 并 未 按 要 求 取 大 素 数 , 而 是 小 素 数。 (2)求 椭 圆 点 的 倍 数 及 计 算 曲 线 的 阶 的 实 现 不 理 想 , 因 为 若 是 选 取大素数时, 使用该程序需要较长的计算时间, 在算法的时间度上需 要改进。 (3)随机数的选取是直接利用标准 C 中的库函数 rand()。该函数产 生的是有规律的伪随机数, 不是真正的随机。若要随机选取一个数, 则 需用户写一个随机数产生函数。科
2007 年 第 10 期
椭圆曲线公钥密码加密方法的 C 语言实现
郭其标 ( 嘉应学院计算中心 广东 梅州 514031)
摘要: 随着计算机网络与通信技术的迅速发展, 信息安全问题日益突出。解决此问题的一种有效方法是数据加密与解密技术。本文从实现 的角度, 对椭圆曲线公钥密码加密方法进行了研究。论述了椭圆曲线运算的数学背景, 以及椭圆曲线加密算法的原理, 我的主要工作是用 C 语 言编程实现了该方法。

椭圆曲线加密算法的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表示负数。

二元域椭圆曲线加密算法

二元域椭圆曲线加密算法

二元域椭圆曲线加密算法(ECC)C语言实现dajiangwan@2013-9-221.前言 (1)2.BN定义 (2)3.BN算法 (5)3.1.单宽度整数乘法 (5)3.2.单宽度整数除法 (6)3.3.中间计算结果函数 (7)3.4.计算大数位数的函数 (9)3.5.大数转换函数 (10)3.6.大数赋值函数 (11)3.7.大数比较函数 (12)3.8.大数移位函数 (13)3.9.大数加减函数 (14)3.10.大数乘法函数 (15)3.11.大数除法函数 (16)3.12.大数取模函数 (17)3.13.大数乘法取模函数 (17)3.14.大数求倒数取模函数 (18)3.15.大数其他函数 (19)4.HASH函数 (21)5.ECC算法 (25)5.1.ECC算法头文件 (25)5.2.ECC算法实现 (26)6.附录 (45)7.参考资料 (48)1.前言二元域的椭圆加密算法在工作中会遇到,由于该算法涉及到许多数学理论,要理解算法不是太容易。

ECC在PC机上有很多实现,比如openssl、tomcrypto以及gcrypto等;以上的算法由于要考虑运行效率,使用了很多加速算法,导致阅读时不易理解。

为了理解该算法的关键部分,本文依照RSA提供的大数算法,对TinyBECC的源码进行整理修改,实现了ECC加密算法的ECDSA。

该代码可以在Windows下使用Microsoft VC6.0进行编译,也可以在Fedora Linux下的使用gcc进行编译。

为了验证算法的正确性,可以通过openssl进行对比测试。

作为一个示例性的程序,性能较差,只能用来了解ECC算法的原理。

2.BN 定义ECC 使用大数进行运算,在计算机表示大数时,一般采用多个字节来存储。

在C 语言中使用整数数组来存储大数。

以下代码假设计算机的整数宽度为32Bit,存储时先存储低端数据,后存储高端数据。

以下代码是从RSA 提供的RSA 算法实现参考中(BN.h 和BN.c)复制出来的,然后进行了一些修改。

椭圆曲线加密算法(ECC)原理和C++实现源码(摘录)

椭圆曲线加密算法(ECC)原理和C++实现源码(摘录)

椭圆曲线加密算法(ECC)原理和C++实现源码(摘录)/* 1、⽤户A选定⼀条适合加密的椭圆曲线Ep(a,b)(如:y2=x3+ax+b),并取椭圆曲线上⼀点,作为基点G。

2、⽤户A选择⼀个私有密钥k,并⽣成公开密钥K=kG。

3、⽤户A将Ep(a,b)和点K,G传给⽤户B。

4、⽤户B接到信息后,将待传输的明⽂编码到Ep(a,b)上⼀点M,并产⽣⼀个随机整数r(r<n)。

5、⽤户B计算点C1=M+rK;C2=rG。

6、⽤户B将C1、C2传给⽤户A。

7、⽤户A接到信息后,计算C1-kC2,结果就是点M。

因为C1-kC2=M+rK-k(rG)=M+rK-r(kG)=M 再对点M进⾏解码就可以得到明⽂。

密码学中,描述⼀条Fp上的椭圆曲线,常⽤到六个参量:T=(p,a,b,G,n,h)。

(p 、a 、b ⽤来确定⼀条椭圆曲线,G为基点,n为点G的阶,h 是椭圆曲线上所有点的个数m与n相除的整数部分) 这⼏个参量取值的选择,直接影响了加密的安全性。

参量值⼀般要求满⾜以下⼏个条件: 1、p 当然越⼤越安全,但越⼤,计算速度会变慢,200位左右可以满⾜⼀般安全要求; 2、p≠n×h; 3、pt≠1 (mod n),1≤t<20; 4、4a3+27b2≠0 (mod p); 5、n 为素数; 6、h≤4。

*/#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream.h>#include "tommath.h"#include <time.h>#define BIT_LEN 800#define KEY_LONG 128 //私钥⽐特长#define P_LONG 200 //有限域P⽐特长#define EN_LONG 40 //⼀次取明⽂字节数(x,20)(y,20)//得到lon⽐特长素数int GetPrime(mp_int *m,int lon);//得到B和G点X坐标G点Y坐标void Get_B_X_Y(mp_int *x1,mp_int *y1,mp_int *b, mp_int *a, mp_int *p);//点乘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);//点加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);//⼆进制存储密⽂int chmistore(mp_int *a,FILE *fp);//把读取的字符存⼊mp_int型数int putin(mp_int *a,char *ch,int chlong);//ECC加密void Ecc_encipher(mp_int *qx,mp_int *qy, mp_int *px, mp_int *py,mp_int *a,mp_int *p);//ECC解密void Ecc_decipher(mp_int *k, mp_int *a,mp_int *p);//实现将mp_int数a中的⽐特串还原为字符串并赋给字符串ch:int chdraw(mp_int *a,char *ch);//取密⽂int miwendraw(mp_int *a,char *ch,int chlong);int myrng(unsigned char *dst, int len, void *dat){int x;for (x = 0; x < len; x++) dst[x] = rand() & 0xFF;return len;}void main(){cout<<"\n 本程序实现椭圆曲线的加密解密"<<endl;cout<<"\n------------------------------------------------------------------------\n"<<endl;mp_int GX;mp_int GY;mp_int K;//私有密钥mp_int A;mp_int QX;mp_int QY;mp_int P;//Fp中的p(有限域P)mp_init(&GX);mp_init(&GY);mp_init(&K);mp_init(&A);mp_init(&B);mp_init(&QX);mp_init(&QY);mp_init(&P);time_t t;srand( (unsigned) time( &t ) );printf("椭圆曲线的参数如下(以⼗进制显⽰):\n");GetPrime(&P,P_LONG);printf("有限域 P 是:\n");char temp[800]={0};mp_toradix(&P,temp,10);printf("%s\n",temp);GetPrime(&A,30);char tempA[800]={0};printf("曲线参数 A 是:\n");mp_toradix(&A,tempA,10);printf("%s\n",tempA);Get_B_X_Y(&GX,&GY,&B,&A,&P);char tempB[800]={0};printf("曲线参数 B 是:\n");mp_toradix(&B,tempB,10);printf("%s\n",tempB);char tempGX[800]={0};printf("曲线G点X坐标是:\n");mp_toradix(&GX,tempGX,10);printf("%s\n",tempGX);char tempGY[800]={0};printf("曲线G点Y坐标是:\n");mp_toradix(&GY,tempGY,10);printf("%s\n",tempGY);//------------------------------------------------------------------GetPrime(&K,KEY_LONG);char tempK[800]={0};printf("私钥 K 是:\n");mp_toradix(&K,tempK,10);printf("%s\n",tempK);Ecc_points_mul(&QX,&QY,&GX,&GY,&K,&A,&P);char tempQX[800]={0};printf("公钥X坐标是:\n");mp_toradix(&QX,tempQX,10);printf("%s\n",tempQX);char tempQY[800]={0};printf("公钥Y坐标是:\n");mp_toradix(&QY,tempQY,10);printf("%s\n",tempQY);printf("\n------------------------------------------------------------------------\n"); Ecc_encipher(&QX,&QY,&GX,&GY,&A,&P);//加密printf("\n------------------------------------------------------------------------\n"); Ecc_decipher(&K,&A,&P);//解密printf("\n------------------------------------------------------------------------\n"); char cc;cout<<"\n\n请击⼀键退出!\n";mp_clear(&GX);mp_clear(&GY);mp_clear(&K);//私有密钥mp_clear(&A);mp_clear(&B);mp_clear(&QX);mp_clear(&QY);mp_clear(&P);//Fp中的p(有限域P)}int GetPrime(mp_int *m,int lon){mp_prime_random_ex(m, 10, lon,(rand()&1)?LTM_PRIME_2MSB_OFF:LTM_PRIME_2MSB_ON, myrng, NULL); return MP_OKAY;}void Get_B_X_Y(mp_int *x1,mp_int *y1,mp_int *b, mp_int *a, mp_int *p){mp_int tempx,tempy;mp_int temp;mp_int compare;mp_int temp1;mp_int temp2;mp_int temp3;mp_int temp4;mp_int temp5;mp_int temp6;mp_int temp7;mp_int temp8;mp_init_set_int (&compare, 0);mp_init(&tempx);mp_init(&tempy);mp_init(&temp);mp_init(&temp1);mp_init(&temp2);mp_init(&temp3);mp_init(&temp4);mp_init(&temp5);mp_init(&temp6);mp_init(&temp7);mp_init(&temp8);while(1){//4a3+27b2≠0 (mod p)GetPrime(b,40);mp_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);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);mp_clear(&tempx);mp_clear(&tempy);mp_clear(&temp);mp_clear(&temp1);mp_clear(&temp2);mp_clear(&temp3);mp_clear(&temp4);mp_clear(&temp5);mp_clear(&temp8);}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){mp_int X1, Y1;mp_int X2, Y2;mp_int X3, Y3;mp_int XX1, YY1;mp_int A,P;int i;bool zero=false;char Bt_array[800]={0};char cm='1';mp_toradix(d,Bt_array,2);mp_init_set_int(&X3, 0);mp_init_set_int(&Y3, 0);mp_init_copy(&X1, px);mp_init_copy(&X2, px);mp_init_copy(&XX1, px);mp_init_copy(&Y1, py);mp_init_copy(&Y2, py);mp_init_copy(&YY1, py);mp_init_copy(&A, a);mp_init_copy(&P, p);for(i=1;i<=KEY_LONG-1;i++){mp_copy(&X2, &X1);mp_copy(&Y2, &Y1);Two_points_add(&X1,&Y1,&X2,&Y2,&X3,&Y3,&A,zero,&P);mp_copy(&X3, &X2);mp_copy(&Y3, &Y2);if(Bt_array[i]==cm){mp_copy(&XX1, &X1);mp_copy(&YY1, &Y1);Two_points_add(&X1,&Y1,&X2,&Y2,&X3,&Y3,&A,zero,&P);mp_copy(&X3, &X2);mp_copy(&Y3, &Y2);}}if(zero){cout<<"It is Zero_Unit!";return false;//如果Q为零从新产⽣D}mp_copy(&X3, qx);mp_copy(&Y3, qy);mp_clear(&X1);mp_clear(&Y1);mp_clear(&X2);mp_clear(&Y2);mp_clear(&X3);mp_clear(&Y3);mp_clear(&XX1);mp_clear(&YY1);mp_clear(&A);mp_clear(&P);return 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) {mp_int x2x1;mp_int y2y1;mp_int tempk;mp_int tempy;mp_int temp1;mp_int temp2;mp_int temp3;mp_int temp4;mp_int temp5;mp_int temp6;mp_int temp7;mp_int temp8;mp_int temp9;mp_int temp10;mp_init(&x2x1);mp_init(&y2y1);mp_init(&tempk);mp_init(&tempy);mp_init(&tempzero);mp_init(&k);mp_init(&temp1);mp_init(&temp2);mp_init_set(&temp3,2);mp_init(&temp4);mp_init(&temp5);mp_init(&temp6);mp_init(&temp7);mp_init(&temp8);mp_init(&temp9);mp_init(&temp10);if(zero){mp_copy(x1, x3);mp_copy(y1, y3);zero=false;goto L;}mp_zero(&tempzero);mp_sub(x2, x1, &x2x1);if(mp_cmp(&x2x1,&tempzero)==-1){mp_add(&x2x1, p, &temp1);mp_zero(&x2x1);mp_copy(&temp1, &x2x1);}mp_sub(y2, y1, &y2y1);if(mp_cmp(&y2y1,&tempzero)==-1){mp_add(&y2y1, p, &temp2);mp_zero(&y2y1);mp_copy(&temp2, &y2y1);}if(mp_cmp(&x2x1, &tempzero)!=0){mp_invmod(&x2x1,p,&tempk);mp_mulmod(&y2y1, &tempk, p, &k);}else{if(mp_cmp(&y2y1, &tempzero)==0){mp_mulmod(&temp3,y1,p,&tempy); mp_invmod(&tempy,p,&tempk);mp_sqr(x1, &temp4);mp_mul_d(&temp4, 3, &temp5);mp_add(&temp5, a, &temp6);mp_mulmod(&temp6, &tempk, p, &k); }else{zero=true;goto L;}}mp_sqr(&k, &temp7);mp_sub(x1, x3, &temp9);mp_mul(&temp9, &k, &temp10);mp_submod(&temp10, y1, p, y3);L:mp_clear(&x2x1);mp_clear(&y2y1);mp_clear(&tempk);mp_clear(&tempy);mp_clear(&tempzero);mp_clear(&k);mp_clear(&temp1);mp_clear(&temp2);mp_clear(&temp3);mp_clear(&temp4);mp_clear(&temp5);mp_clear(&temp6);mp_clear(&temp7);mp_clear(&temp8);mp_clear(&temp9);mp_clear(&temp10);return1;}//⼆进制存储密⽂int chmistore(mp_int *a,FILE *fp){int i,j;char ch;char chtem[4];mp_digit yy=(mp_digit)255;for (i=0; i <= a->used - 1; i++) {chtem[3]=(char)(a->dp[i] & yy);chtem[2]=(char)((a->dp[i] >> (mp_digit)8) & yy); chtem[1]=(char)((a->dp[i] >> (mp_digit)16) & yy); chtem[0]=(char)((a->dp[i] >> (mp_digit)24) & yy);for(j=0;j<4;j++){fprintf(fp,"%c",chtem[j]);}}ch=char(255);fprintf(fp, "%c", ch);return MP_OKAY;}//把读取的字符存⼊mp_int型数int putin(mp_int *a,char *ch,int chlong){mp_digit *temp,yy;int i,j,res;if(a->alloc<chlong*2/7+2){if((res=mp_grow(a,chlong*2/7+2))!=MP_OKAY)return res;}a->sign=0;mp_zero(a);temp=a->dp;i=0;yy=(mp_digit)15;if(chlong<4){for(j=chlong-1;j>=0;j--){*temp |= (mp_digit)(ch[j] & 255);*temp <<= (mp_digit)CHAR_BIT;}return MP_OKAY;}if(chlong<7){i+=4;*++temp |= (mp_digit)(ch[i-1] & yy);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-2] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-3] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp-- |= (mp_digit)(ch[i-4] & 255); //存放被切分的字符的低四位for(j=chlong-1;j>=i;j--){*temp |= (mp_digit)(ch[j] & 255);*temp <<= (mp_digit)CHAR_BIT;}*temp >>= (mp_digit)4;*temp |= (mp_digit)((ch[i-1] & 255) >> 4); //存放被切分的字符的⾼四位 a->used=2;return MP_OKAY;}//以7个字符为单元循环,把七个字符放⼊的mp_int 的两个单元中for(j=0;j<chlong/7;j++){i+=7;*++temp |= (mp_digit)(ch[i-1] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-2] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-3] & 255);*temp <<= (mp_digit)4;*temp-- |= (mp_digit)((ch[i-4] & 255) >> 4); //存放被切分的字符的⾼四位 *temp |= (mp_digit)(ch[i-4] & yy); //存放被切分的字符的低四位*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-5] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-6] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp++ |= (mp_digit)(ch[i-7] & 255);temp++;}if((chlong>=7)&&(chlong%7!=0)) //剩余字符的存放{if(chlong%7 < 4) //剩余字符少余4个时,只需⼀个mp_digit单元存放 {for(j=chlong-1;j>=i;j--){*temp |= (mp_digit)(ch[j] & 255);*temp <<= (mp_digit)CHAR_BIT;}*temp >>= (mp_digit)8;a->used=chlong*2/7+1;}else{ //剩余字符不⼩于4个时,需两个mp_digit单元存放i+=4;*temp |= (mp_digit)(ch[i-1] & yy);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-2] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-3] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp++ |= (mp_digit)(ch[i-4] & 255); //存放被切分的字符的低四位for(j=chlong-1;j>=i;j--){*temp |= (mp_digit)(ch[j] & 255);*temp <<= (mp_digit)CHAR_BIT;}*temp >>= (mp_digit)4;*temp |= (mp_digit)((ch[i-1] & 255) >> 4); //存放被切分的字符的⾼四位}}else{a->used=chlong*2/7;}return MP_OKAY;}void Ecc_encipher(mp_int *qx,mp_int *qy, mp_int *px, mp_int *py,mp_int *a,mp_int *p){ //公钥X、Y坐标,曲线G点X、Y坐标,曲线参数A,有限域P mp_int mx, my;mp_int c1x, c1y;mp_int c2x, c2y;mp_int r;mp_int tempx, tempy;bool zero=false;FILE *fp,*fq;int i;char miwenx[280]={0};char miweny[280]={0};char stemp[650]={0};mp_init(&mx);mp_init(&my);mp_init(&c1x);mp_init(&c1y);mp_init(&c2x);mp_init(&c2y);mp_init(&r);mp_init(&tempx);mp_init(&tempy);GetPrime(&r, 100);char filehead[60],filefoot[20],filename[85]={0};cout<<"请输⼊您要加密⽂件的存放路径和⽂件名(如: c:\\000\\⼤整数运算 ):"<<endl;cin>>filehead;cout<<"请输⼊您要加密⽂件的扩展名(如: .doc ):"<<endl;cin>>filefoot;strcpy(filename,filehead);strcat(filename,filefoot);//打开要加密⽂件if((fp=fopen(filename,"rb"))==NULL){printf("can not open the file!");exit(1);}unsigned int FileLong=0;//⽂件字符长度char ChTem;//临时字符变int Frequency=0;int Residue=0;while( !feof(fp) )//找⽂件字符长度{ChTem = fgetc( fp );FileLong++;}--FileLong;Frequency = FileLong/EN_LONG;Residue = FileLong%EN_LONG;int enlongtemp=EN_LONG/2;//printf("%d\n",Frequency);//printf("%d\n",Residue);char filemi[85];strcpy(filemi,filehead);strcat(filemi,"密⽂");strcat(filemi,filefoot);//打开保存密⽂⽂件if((fq=fopen(filemi,"wb"))==NULL)exit(1);}printf("\n开始加密...\n");rewind(fp);for(i=0; i<Frequency; i++){fread(miwenx,1,enlongtemp,fp);//读⼊字符串miwenx[enlongtemp]=char(255);fread(miweny,1,enlongtemp,fp);//读⼊字符串miweny[enlongtemp]=char(255);putin(&mx, miwenx,enlongtemp+1);//⽂件存⼊putin(&my, miweny,enlongtemp+1);//⽂件存⼊Ecc_points_mul(&c2x,&c2y,px,py,&r,a,p);//加密Ecc_points_mul(&tempx,&tempy,qx,qy,&r,a,p);Two_points_add(&mx,&my,&tempx,&tempy,&c1x,&c1y,a,zero,p);//保存密⽂chmistore(&c1x,fq);chmistore(&c1y,fq);chmistore(&c2x,fq);chmistore(&c2y,fq);}//剩余字符处理if ( Residue > 0){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);//加密Ecc_points_mul(&tempx,&tempy,qx,qy,&r,a,p);Two_points_add(&mx,&my,&tempx,&tempy,&c1x,&c1y,a,zero,p);//保存密⽂chmistore(&c1x,fq);chmistore(&c1y,fq);chmistore(&c2x,fq);chmistore(&c2y,fq);}cout<<"\nok!加密完毕!"<<endl;cout<<"密⽂以⼆进制保存"<<endl;cout<<"密⽂存放路径为 "<<filemi<<endl ;mp_clear(&mx);mp_clear(&my);mp_clear(&c1x);mp_clear(&c1y);mp_clear(&c2x);mp_clear(&c2y);mp_clear(&r);mp_clear(&tempx);mp_clear(&tempy);}//取密⽂int miwendraw(mp_int *a,char *ch,int chlong){mp_digit *temp;int i,j,res;if(a->alloc<chlong/4){if((res=mp_grow(a,chlong/4))!=MP_OKAY)return res;}a->alloc=chlong/4;a->sign=0;mp_zero(a);temp=a->dp;i=0;for(j=0;j<chlong/4;j++){i+=4;*temp |= (mp_digit)(ch[i-4] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-3] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp |= (mp_digit)(ch[i-2] & 255);*temp <<= (mp_digit)CHAR_BIT;*temp++ |= (mp_digit)(ch[i-1] & 255);}a->used=chlong/4;return MP_OKAY;}//实现将mp_int数a中的⽐特串还原为字符串并赋给字符串ch:int chdraw(mp_int *a,char *ch){int i,j;mp_digit *temp,xx,yy;temp=a->dp;i=0;yy=(mp_digit)255; //⽤于位与运算,取⼋位⽐特串xx=(mp_digit)15; //⽤于位与运算,取四位⽐特串for(j=0;j<a->used/2;j++) //以两个单元为循环,把两个单元的⽐特串赋给7个字符 {i+=7;ch[i-4]=(char)(*++temp & xx);ch[i-3]=(char)((*temp >> (mp_digit)4) & yy);ch[i-2]=(char)((*temp >> (mp_digit)12) & yy);ch[i-1]=(char)((*temp-- >> (mp_digit)20) & yy);ch[i-7]=(char)(*temp & yy);ch[i-6]=(char)((*temp >> (mp_digit)8) & yy);ch[i-5]=(char)((*temp >> (mp_digit)16) & yy);ch[i-4] <<= 4;ch[i-4]+=(char)((*temp++ >> (mp_digit)24) & xx);temp++;}if(a->used%2!=0) //剩于⼀个单元的处理{ch[i++] = (char)(*temp & yy);ch[i++] = (char)((*temp >> (mp_digit)8) & yy);ch[i++] = (char)((*temp >> (mp_digit)16) & yy);}--i;while(int(ch[i]&0xFF) != 255 && i>0) i--;return i;void Ecc_decipher(mp_int *k, mp_int *a,mp_int *p){mp_int c1x, c1y;mp_int c2x, c2y;mp_int tempx, tempy;mp_int mx, my;mp_int temp;mp_init(&temp);mp_init(&c1x);mp_init(&c1y);mp_init(&c2x);mp_init(&c2y);mp_init(&tempx);mp_init(&tempy);mp_init(&mx);mp_init(&my);mp_int tempzero;mp_init(&tempzero);int i;char stemp[700]={0};FILE *fp,*fq;bool zero=false;char filehead[60],filefoot[20],filename[85]={0};cout<<"请输⼊您要解密的⽂件的存放路径和⽂件名(如: c:\\000\\⼤整数运算 ):"<<endl; cin>>filehead;cout<<"请输⼊您要解密的⽂件的扩展名(如: .doc ):"<<endl;cin>>filefoot;strcpy(filename,filehead);strcat(filename,filefoot);printf("\n开始解密\n");if((fp=fopen(filename,"rb"))==NULL){printf("can not open the file!");exit(1);}//打开保存解密结果⽂件char filemi[80];strcpy(filemi, filehead);strcat(filemi, "解密");strcat(filemi, filefoot);if((fq=fopen(filemi,"wb"))==NULL){printf("can not open the file!");exit(1);}rewind(fp);while(!feof(fp)){i=0;while(1){stemp[i]=fgetc(fp);if(i%4==0){if(int(stemp[i]&0xFF) == 255 ) goto L1;}i++;}L1: miwendraw(&c1x, stemp, i);i=0;while(1){stemp[i]=fgetc(fp);if(i%4==0){if(int(stemp[i]&0xFF) == 255 ) goto L2;}i++;}L2: miwendraw(&c1y, stemp, i);i=0;while(1){stemp[i]=fgetc(fp);if(i%4==0){if(int(stemp[i]&0xFF) == 255 ) goto L3;}i++;}L3: miwendraw(&c2x, stemp, i);i=0;while(1){stemp[i]=fgetc(fp);if(i%4==0){if(int(stemp[i]&0xFF) == 255 ) goto L4;}i++;}L4: miwendraw(&c2y, stemp, i);mp_zero(&tempzero);if(mp_cmp(&c1x, &tempzero)==0) break;Ecc_points_mul(&tempx, &tempy, &c2x, &c2y, k, a, p);mp_neg(&tempy, &temp);Two_points_add(&c1x,&c1y,&tempx,&temp,&mx,&my,a,zero,p);int chtem;chtem=chdraw(&mx,stemp);//从ming中取出字符串//保存解密结果for(int kk=0;kk<chtem;kk++){fprintf(fq,"%c",stemp[kk]);}chtem=chdraw(&my,stemp);//从ming中取出字符串//保存解密结果for(kk=0;kk<chtem;kk++){fprintf(fq,"%c",stemp[kk]);}}cout<<"\nok!解密完毕!"<<endl;cout<<"解密后的⽂字存放路径为 "<<filemi<<endl;fclose(fq);fclose(fp);mp_clear(&c1x);mp_clear(&c1y);mp_clear(&c2x);mp_clear(&c2y);mp_clear(&tempx);mp_clear(&tempy);mp_clear(&mx);mp_clear(&my);mp_clear(&temp);}。

c语言实现ECC算法的探索

c语言实现ECC算法的探索

c语言实现ECC算法的探索C语言实现ECC算法的探索1. 引言椭圆曲线密码学(Elliptic Curve Cryptography, ECC)是一种基于数论的公钥密码学算法,其安全性与传统的RSA、DSA等算法相当,但具有更高的效率和较短的密钥长度。

在现代密码学中,ECC已成为一种重要而广泛应用的加密技术。

本文将探讨如何使用C语言实现ECC 算法,并展示其在信息安全领域的应用前景。

2. ECC算法概述ECC算法是基于椭圆曲线上点的加法和倍乘运算实现的。

其中,曲线上的点是由一组满足特定数学方程的椭圆曲线上的点集合构成的。

ECC算法通过利用这些点的数学性质,实现了一种安全可靠的加密方法。

3. C语言实现ECC算法的步骤3.1 ECC加密算法ECC加密算法的步骤包括密钥生成、加密和解密。

在C语言中实现ECC加密算法时,我们需要注意以下几个方面:- 随机数生成:ECC算法的密钥生成过程依赖于随机数,C语言提供了伪随机数生成函数,如rand(),可以使用这些函数生成所需的随机数。

- 椭圆曲线参数选择:ECC算法中使用的椭圆曲线参数需要进行合理的选择,C语言可以通过定义结构体来表示椭圆曲线,在程序中使用这些参数进行运算。

- 点的加法和倍乘运算:C语言可以通过定义结构体来表示椭圆曲线上的点,并实现对这些点的加法和倍乘运算。

- 密钥的管理:在实现ECC加密算法时,需要设计合理的数据结构来管理公钥和私钥,并提供相应的函数进行生成和存储。

3.2 ECC解密算法ECC解密算法的步骤与加密算法相反,主要包括密钥生成、加密和解密。

当接收到密文后,使用私钥进行解密,获取原始明文数据。

4. ECC算法的应用前景ECC算法具有较高的安全性和较短的密钥长度,在信息安全领域有着广泛的应用前景。

以下是几个常见应用领域:- 数字签名:ECC算法可以实现数字签名,用于验证消息的来源和完整性,常用于保护电子文档的安全性。

- 数据加密:ECC算法可以用于对重要数据进行加密,在数据传输和存储过程中提供保护。

椭圆曲线加密算法步骤

椭圆曲线加密算法步骤

椭圆曲线加密算法步骤
椭圆曲线加密算法是一种非对称加密算法,其加密过程基于椭圆曲线上的数学问题。

以下是椭圆曲线加密算法的步骤:
1. 选取一条椭圆曲线E和一个基点G。

这里的椭圆曲线是一个
特殊的函数,而G是一个点在这个函数上的坐标。

2. 选取一个随机数k,作为私钥。

3. 将私钥k乘以基点G,得到公钥P=kG。

公钥P是一个点在椭
圆曲线上的坐标。

4. 要对明文进行加密,需要将明文转换为曲线上的点Q。

这可
以通过将明文的二进制表示形式解释为一个整数,然后将其乘以基点
G来实现。

5. 选取一个随机数r,作为加密算法的参数。

6. 计算密文C1=rG,C2=Q+rP。

C1和C2就是加密后的密文。

7. 要解密密文,需要使用私钥k来计算P=kC1。

然后,计算Q=C2-P,得到明文的点。

8. 最后,将明文点转换为明文的二进制表示形式,并进行解密。

椭圆曲线加密算法具有高度的安全性和效率,适用于各种加密应用场景。

- 1 -。

c语言实现椭圆曲线

c语言实现椭圆曲线

c语言实现椭圆曲线椭圆曲线是一种数学概念,也是密码学领域中常用的加密算法。

它在很多安全通信协议中被广泛应用,如数字签名、密钥协商等。

本文将详细介绍椭圆曲线在C语言中的实现方法。

在开始实现椭圆曲线之前,我们需要明确一些概念。

椭圆曲线可以通过方程来描述,一般的椭圆曲线方程为y^2 = x^3 + ax + b,其中a和b是常数。

在C语言中,我们可以使用结构体来表示一个椭圆曲线的参数。

接下来,我们需要实现椭圆曲线上的点的运算。

点的加法运算是椭圆曲线算法的核心,它定义了两个点相加后得到的结果是另一个点。

在C语言中,我们可以使用结构体或者数组来表示一个点,然后实现点的加法运算。

在进行点的加法运算时,我们需要考虑点的特殊情况,如点与自身相加、点与无穷远点相加等。

在C语言中,我们可以使用条件语句来处理这些特殊情况。

除了点的加法运算之外,我们还可以实现点的乘法运算。

点的乘法运算是指一个点与一个数相乘的运算,得到的结果是将这个点与自身相加多次得到的。

在实现椭圆曲线算法时,我们还需要考虑一些边界条件和安全性问题。

例如,我们需要限定在一个有限的范围内进行运算,以防止数值溢出;同时,我们还需要考虑实现高效的算法,以提高计算速度。

总结起来,实现椭圆曲线算法的基本步骤包括定义椭圆曲线参数、实现点的加法运算、实现点的乘法运算、处理特殊情况和考虑边界条件等。

在C语言中,我们可以利用结构体、数组和条件语句等语言特性来实现这些功能。

通过上述步骤,我们可以在C语言中实现椭圆曲线算法,从而为密码学领域的安全通信协议提供坚实的基础。

椭圆曲线算法的广泛应用,使得我们更加需要深入了解和掌握这一算法。

希望本文对读者对椭圆曲线算法的理解和实践有所帮助。

椭圆曲线加密算法代码

椭圆曲线加密算法代码

椭圆曲线加密算法代码及解析在椭圆曲线加密中,利用了某种特殊形式的椭圆曲线,即定义在有限域上的椭圆曲线。

其方程如下:y2=x3+ax+b(mod p)这里p是素数,a和b为两个小于p的非负整数,它们满足:4a3+27b2(mod p)≠0 其中,x,y,a,b ∈Fp,则满足式(2)的点(x,y)和一个无穷点O就组成了椭圆曲线E。

椭圆曲线离散对数问题ECDLP定义如下:给定素数p和椭圆曲线E,对 Q=kP,在已知P,Q的情况下求出小于p的正整数k。

现在我们描述一个利用椭圆曲线进行加密通信的过程:1、用户A选定一条椭圆曲线Ep(a,b),并取椭圆曲线上一点,作为基点G。

2、用户A选择一个私有密钥k,并生成公开密钥K=kG。

3、用户A将Ep(a,b)和点K,G传给用户B。

4、用户B接到信息后,将待传输的明文编码到Ep(a,b)上一点M(将M转化为十进制整数m,然后令椭圆曲线中点的横坐标为m,根据曲线方程计算出纵坐标,便得到了一个点。

),并产生一个随机整数r(r<n)。

5、用户B计算点C1=M+rK;C2=rG。

6、用户B将C1、C2传给用户A。

7、用户A接到信息后,计算C1-kC2,结果就是点M。

因为C1-kC2=M+rK-k(rG)=M+rK-r(kG)=M再对点M进行解码就可以得到明文。

过程分析:1、将给出的椭圆上的两点G,K相加求得第三点M。

P跟Q有两种情况。

分P=Q 和P不等于Q时。

2、求M的过程中进行求模运算。

第一,将分数利用最小公倍数求模。

第二,负数求模,先将负号拿出来,求完再将负号加上。

根据公式将λ解出。

3、将X3Y3求出。

循环算出nG,求出C1C2(密文)。

C1=rG,C2=M+rK。

M为明文,公开密钥K=kG代码部分:#include <iostream>using namespace std;//求两数的最小公倍数int f1(int a, int b){int c=a;while( c%a!=0 || c%b!=0)c++;return c;}//求modint mod (int a, int b){int c;if(a>0)c=a%b;else{while(a<b)a=a+b;c=a%b;}return c;}//求λint f2(int x1,int y1,int x2,int y2,int a,int p) {int b,b1,b2,q;//b1为分子,b2为分母if( x1==x2 && y1==y2)//如果λ两点相等{b1=3*x1*x1+a;b2=2*y1;if(b1<0)b1=-mod(-b1,p);elseb1=mod(b1,p);if(b2<0){b2=mod(-b2,p);q=-f1(b2,p+1)/b2;}else{b2=mod(b2,p);q=f1(b2,p+1)/b2;}b2=f1(b2,p+1)/b2;b=b1*b2;b=mod(b,p);}else{b1=y2-y1;b2=x2-x1;if(b1<0)b1=-mod(-b1,p);elseb1=mod(b1,p);if(b2<0){b2=mod(-b2,p);q=-f1(b2,p+1)/b2;}else{b2=mod(b2,p);q=f1(b2,p+1)/b2;}b=b1*q;b=mod(b,p);}return b;}//求两点横坐标的和int sumx(int x1,int y1,int x2,int y2,int k,int a,int p){int x3,y3,i;if(k==1){x3=(f2(x1,y1,x2,y2,a,p))*(f2(x1,y1,x2,y2,a,p))-x1-x2;x3=mod(x3,p);}else{for(i=1;i<=k-1;i++){x3=(f2(x1,y1,x2,y2,a,p))*(f2(x1,y1,x2,y2,a,p))-x1-x2;x3=mod(x3,p);y3=(f2(x1,y1,x2,y2,a,p)*(x1-x3))-y1;y3=mod(y3,p);x2=x1;x1=x3;y2=y1;y1=y3;}}return x3;}//求两点纵坐标的和int sumy(int x1,int y1,int x2,int y2,int k,int a,int p){int x3,y3,i,u=x1,v=y1,m=x2,n=y2;if(k==1){x3=f2(u,v,m,n,a,p)*f2(u,v,m,n,a,p)-u-m;x3=mod(x3,p);y3=f2(u,v,m,n,a,p)*(u-x3)-v;y3=mod(y3,p);}else{for(i=1;i<=k-1;i++){x3=f2(u,v,m,n,a,p)*f2(u,v,m,n,a,p)-u-m;x3=mod(x3,p);y3=f2(u,v,m,n,a,p)*(u-x3)-v;y3=mod(y3,p);m=x1;u=x3;n=y1;v=y3;}}return y3;}//加密过程void encry(int x1,int y1,int x2,int y2,int k, int a, int p,int r) {int c1x,c1y,bx,by,bx1,by1,mbx,mby;c1x=sumx(x1,y1,x1,y1,r,a,p);c1y=sumy(x1,y1,x1,y1,r,a,p);bx1=sumx(x1,y1,x1,y1,k,a,p);by1=sumy(x1,y1,x1,y1,k,a,p);bx=sumx(sumx(x1,y1,x1,y1,k,a,p),sumy(x1,y1,x1,y1,k,a,p),sumx(x1,y 1,x1,y1,k,a,p),sumy(x1,y1,x1,y1,k,a,p),r,a,p);by=sumy(sumx(x1,y1,x1,y1,k,a,p),sumy(x1,y1,x1,y1,k,a,p),sumx(x1,y 1,x1,y1,k,a,p),sumy(x1,y1,x1,y1,k,a,p),r,a,p);mbx=sumx(x2,y2,bx,by,1,a,p);mby=sumy(x2,y2,bx,by,1,a,p);cout<<"(C1,C2)="<<"(("<<c1x<<","<<c1y<<"),("<<mbx<<","<<mby<<"))" ;}void main(){cout<<"令曲线方程格式为y^2=x^3+ax+b"<<endl;int a,b,c,d,m,n,x,y,r;cout<<"请输入a的值:";cin>>a;cout<<"请输入b的值:";cin>>b;cout<<"请给定一个素数P:";cin>>c;cout<<"请给定一个秘密正数k:";cin>>d;cout<<"令曲线上点的格式为(x1,y1):"<<endl;cout<<"请输入x1的值:";cin>>m;cout<<"请输入y1的值:";cin>>n;cout<<"令消息的格式为(x2,y2)"<<endl;cout<<"请输入x2的值:";cin>>x;cout<<"请输入y2的值:";cin>>y;cout<<"请任选一个整数r:";cin>>r;cout<<"加密消息为:";encry(m,n,x,y,d,a,c,r);cout<<endl;}程序开始运行的界面:。

ecc算法源码

ecc算法源码

ecc算法源码椭圆曲线密码算法(Elliptic Curve Cryptography, ECC)是一种基于椭圆曲线数学问题的非对称加密算法,被广泛应用于互联网安全领域。

在本文中,将介绍ECC算法的基本原理,并提供一段C语言源码作为示例,帮助读者更好地理解和应用ECC算法。

一、ECC算法基本原理ECC算法基于椭圆曲线离散对数问题,通过选择合适的曲线参数和基点,实现对消息的加密与解密操作。

在ECC算法中,公钥由椭圆曲线上的一点表示,私钥是一个随机选择的整数。

加密时,将待加密的消息映射到椭圆曲线上的一点,然后利用私钥和基点的乘法运算求得密文。

解密时,利用私钥和密文进行乘法运算,得到加密前的消息。

二、ECC算法源码示例下面是一个简化的ECC算法源码示例,使用C语言实现:```c#include <stdio.h>#include <string.h>#include <openssl/ec.h>#include <openssl/rand.h>int main() {EC_KEY *ec_key;EC_GROUP *ec_group;const EC_POINT *public_key;BIGNUM *private_key;const EC_POINT *derived_public_key;unsigned char message[] = "Hello, ECC!";unsigned char ciphertext[100];unsigned char decrypted[100];int ciphertext_len, decrypted_len;// 生成椭圆曲线密钥对ec_key = EC_KEY_new_by_curve_name(NID_secp256k1); EC_KEY_generate_key(ec_key);// 获取公钥和私钥ec_group = EC_KEY_get0_group(ec_key);public_key = EC_KEY_get0_public_key(ec_key);private_key = BN_new();BN_copy(private_key,EC_KEY_get0_private_key(ec_key));// 加密derived_public_key = EC_POINT_new(ec_group);EC_POINT_mul(ec_group, derived_public_key,private_key, NULL, NULL, NULL);EC_POINT_point2oct(ec_group, derived_public_key, POINT_CONVERSION_UNCOMPRESSED, ciphertext, sizeof(ciphertext), NULL);ciphertext_len = strlen(ciphertext);// 解密decrypted_len = ECIES_decrypt(private_key, ciphertext, ciphertext_len, decrypted);// 打印解密结果printf("Decrypted message: %s\n", decrypted);// 释放内存EC_POINT_free(derived_public_key);EC_KEY_free(ec_key);BN_free(private_key);return 0;}```以上示例中,首先使用OpenSSL库的函数生成椭圆曲线密钥对,利用私钥和基点进行加密操作,并将得到的密文存储在`ciphertext`数组中。

椭圆曲线数字签名系统的模块设计与实现

椭圆曲线数字签名系统的模块设计与实现
C HEN a g,Y Li n OU i Ln
( c o l fC mm nc t n E gn ei H n z o in i nvr t , n zo 1 0 8 C i S h o o u i i n ier g, a g h uD a z U i sy Ha g h u3 0 1 , hn o ao n ei a)
上 的加与倍 加运算 模块 、 有理 点群 的 阶的计算模 块 、 有理 点群上 的标 量乘 计 算 模块 、 名模 块 和 加密 模 签
还没 有 找 到 解 决 次 问 题 的次 ( ) 数 时 间 算 法 。 亚 指 E C与其 它密码体制相 比有 着超强的优点 : 同安 C 在相
全 系数下系统 参 数 和密 钥 比特 选择 较 短 , 如 : C 例 EC
L n ua e f l a g g i l na y,wh c i e r e p f rECDS t o is’r s a c n r ci a p lc to i h gv s mo e h l o A he re e e r h a d p a t la p i ain. c Ke r s:elp i u v y wo d l tc c r e;ECDS i A;mo u e;smu a in dl i l to
有 限域 F 上定 义椭 圆 曲线 E, 。 规定 E的 Y轴方 向上 的无 穷远 点 的 记 作 O点 , irrs 程 ( ) 有 We s as方 et 1所 解组 成 的集 合 是 ( Y , )∈F ×F , 里 表 示 有 限 q q这 域, 的代 数 闭包 。
y +al y +a3 x Y= 戈 + a + a +0 2 4 6 r , 2, , 4, z a a3 。 a6∈ F l

ecc椭圆曲线加密算法 源码

ecc椭圆曲线加密算法 源码

ecc椭圆曲线加密算法源码一、概述本文档详细介绍了椭圆曲线加密算法(Elliptic Curve Cryptography,ECC)的源代码实现,包括算法原理、代码实现、测试用例等内容。

该算法广泛应用于现代密码学中,具有高安全性、低计算复杂度等优点。

二、算法原理椭圆曲线加密算法基于椭圆曲线数学理论,利用椭圆曲线上的点加法、标量乘法等运算实现加密和解密过程。

在该算法中,密钥由一对椭圆曲线参数生成,分为私钥和公钥,分别用于加密和解密操作。

私钥用于生成签名,公钥用于解密和验证签名。

三、代码实现本代码实现使用C语言编写,基于OpenSSL库。

以下是主要代码模块:1. 椭圆曲线参数定义2. 密钥生成与存储3. 加密和解密操作4. 签名和验证操作5. 测试用例四、源代码展示以下是部分关键代码的展示,以供参考:1. 椭圆曲线参数定义:```c#include <openssl/ec.h>// 定义椭圆曲线参数EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_X9_62_prime_field);// ...```2. 密钥生成与存储:```c// 生成私钥和公钥EC_POINT *point = EC_POINT_new(group);BN_set_word(privKey, rand()); // 生成随机私钥EC_POINT_mul(group, point, privKey, NULL, NULL, NULL); // 计算公钥// ...```3. 加密和解密操作:```c// 加密数据unsigned char *ciphertext = malloc(ENCRYPT_LENGTH); // 假设加密长度为ENCRYPT_LENGTHEC_POINT_point_mul(group, point, privKey, data, NULL,EC_GROUP_get_degree(group)); // 加法运算加密数据// ...// 解密数据unsigned char decrypted[DECRYPT_LENGTH]; // 解密长度与加密长度相同EC_POINT_free(point); // 释放临时生成的点对象point = EC_POINT_new(group); // 重新生成点对象BN_new(); // 重新生成随机数对象EC_POINT_mul(group, point, pubKey, NULL, NULL, NULL); // 加法运算解密数据,得到原始数据memcpy(decrypted, point->data, DECRYPT_LENGTH); // 将解密结果保存到数组中free(point); // 释放点对象```4. 签名和验证操作:使用OpenSSL库提供的相关函数进行操作,这里不再展示。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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,读入密文。

相关文档
最新文档