ECC加密算法C简单实现

ECC加密算法 c完成

ECC加密算法的理解

本文主要参照:ECC椭圆曲线加解密原理详解(配图)

  1. 先理解一下这篇博客ECC椭圆曲线加解密原理详解(配图)
  2. 通过对博客里面的有限域的椭圆曲线来进行实现里面的公式
  3. 下面是我的文档报告直接附上,可能有没有表述清楚的可以在评论区评论。代码部分只提供生成公钥的,前面博客中提到的编码到一个点上可以在网上搜索,以及博客中4,5, 6,步骤我会告诉你怎么做。

3.2 ECC算法
3.2.1 ECC算法简介
与 RSA(Ron Rivest,Adi Shamir,Len Adleman 三位天才的名字)一样,ECC(Elliptic Curves Cryptography,椭圆曲线加密)也属于公开密钥算法。

3.2.2 ECC算法中的关键变量
① 基点:基点G,G为椭圆曲线Ep(a,b)上的点
② 阶:如果椭圆曲线上一点P,存在最小的正整数n使得数乘n P = O ∞ ,则将n称为P的阶,若n不存在,则P是无限阶的.
③ 公钥K:则给定私钥k和基点G,根据加法法则,计算K很容易但反过来,给定K和G,求k就非常困难。因为实际使用中的ECC原则上把p取得相当大,n也相当大,要把n个解点逐一算出来列成上表是不可能的。

3.2.4 有限域上的椭圆运算算法
根据3.1.2的相关资料,我们只需要用代码实现算术式,但编程语言中分数和负数是不能对一个数取余的,因此我们需要进行一些转换和计算来将取余的值算出来。

图3-6 椭圆曲线上的加法运算
如图3-6中的k的计算,当P等于Q时需要注意y1可能为0,后面计算阶会对这种情况进行处理说明;计算k时:先判断分子分母的符号,判断是否同号,再将其全部转化为正数,然后判断分子大还是分母大,来计算最大因子,然后化简,化简后再来根据分母当做这个b × b − 1 ≡ 1 ( m o d p )公式的b;来将b的-1次方算出,然后根据分子分母是否同号,给他们附上符号,这样就是分母乘以分子的-1次方来mod p,求一个与他们同余的数字。这就是k。
计算x,y时只需要考虑负数的问题,将负数加上p的倍数就可以转换为一个正数来算出它取余p的值,这个负数的取余计算k也会用到。
对于计算阶-p逆元计算以及np的加法放在后面说,这里主要说一下P+Q当Q与P无任何联系的时候,就直接用上面的公式计算。这个会单独写个函数addDif出来给后面加密用。还会单独再写一个函数 everynp来给直接计算kC2,这是给后面解密用的,因为C2是结构体里没有的,不能直接调用,思想是一样的。计算阶的也会分两个函数写,详细的看3.2.5。

3.2.5 产生生成元和阶
代码会用到两个结构体,一个结构体用来装在有限域上的椭圆,里面的变量有他们的阶,x,y,序号,还有另外的一个结构体数组,这是来装这些点对应的mP的坐标,这里的m从-1到阶 没有 0 ,这个数组的下标就是m ,m为0 对应-P,这样将他的所有mP 保存起来,用于计算阶,以及后面的加密需要用到mp 。
先生成一个有限域椭圆曲线方程式y 2 ≡ x 3 + a x + b ( m o d p ),a,b得是大于0的整数,p需要是大素数
计算生成元就是椭圆曲线在有限域上的点。将0到p之间的x代入y 2 ≡ x 3 + a x + b ( m o d p )来计算这里的,y是小于p的整数,所以y的2次方是小于等于p-1的2次方的,这是一个限定条件,这样来找与x 3 + a x + b 同余的数。
找到生成元后来找阶,阶的定义是如果椭圆曲线上一点P,存在最小的正整数n使得数乘n P = O ∞ ,则将n称为P的阶,根据P + ( − P ) = O ∞ 就是找到mP=-P;P(x,y)的负元是 (x,-y mod p)= (x,p-y) ;若P的y的值为0则将它的阶设置为1024,视为无限阶,以及选择私钥也不能选择这个点,后面任意需要选点的情况都不能选择这个点。阶的话是要用到之前的1P,2P…mP的,因为3P=P+2P,需要两个函数,一个计算同点addsame和不同点 addnp,当点相同时,则从结构体调用m/2P的坐标来计算,不同点则调用m/2P+m/2+1P来计算,把他们保存起来,调用函数找,直到找到m 可以满足cP=-P 否则m为1024就不找了,视作无限阶。根据P + ( − P ) = O ∞推出这个点的阶=m+1;
3.2.6选择基点确定私钥产生公钥
选择一个椭圆上的点作为基点,然后选择一个私钥,私钥k小于这个基点的阶n,生成公开密钥K=kG。这里选择基点是靠输入基点的序号,根据序号找到基点,在调取基点结构体中的数组,找到下标为k的数组,里面的坐标就是kG,因为计算了阶,所以已经有kG的值了。

4 相关算法及实现步骤

4.1坐标结构体和NP结构体

struct add
{
   
	int x;
	int y;
	//int jie;
};

struct pos
{
   
	 struct add np[1024];
	 int x;
	 int y;
	 int num;
	 int jie; 
	 int a;
};

4.2 有限域上的椭圆运算算法

int calk(int x,int y)//计算k
{
   
	int x1=x;
	int y1=y;

	int d=1;
	int t=0;
	int k=0;

	if(x1==0||y1==0)
		return 0;
	if(x1<0)
	{
   
		x1=x1*(-1);
		t++;
	}
	if(y1<0)
	{
   
		y1=y1*(-1);
		t++;
	}
	// printf("%d,%d\n",x1,y1);
	int i=1;
	int m,n;

	if(x1>y1)
	{
   
		m=x1;
	    n=y1;
	}
	else
	{
   
		m=y1;
		n=x1;
	}

	while((i=m%n))
	{
   
	   m=n;
	   n=i;
	}

	x1=x1/n;
	y1=y1/n;
	

	if(y1!=1)
	{
   	
		for(d=0;;d++)
		{
   
			if((d*y1)%p==1)
			{
   
				break;
			}
		}

	}

	if(t%2
  • 3
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
ecc椭圆曲线加密算法是一种公钥加密算法,基于数学上的椭圆曲线离散对数问题,其主要思想是利用椭圆曲线上的点进行加密和解密操作。以下是一个简单C语言实现: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <openssl/bn.h> #include <openssl/ec.h> #include <openssl/objects.h> #include <openssl/ecdsa.h> void ecc_encrypt_decrypt_demo() { EC_KEY *key = NULL; const EC_GROUP *group = NULL; BIGNUM *bn = NULL; EC_POINT *pub_key = NULL, *res = NULL; unsigned char *msg = NULL, *ciphertext = NULL, *plaintext = NULL; size_t msg_len = 0, ciphertext_len = 0, plaintext_len = 0; // 生成随机数 bn = BN_new(); BN_rand(bn, 256, 0, 0); // 生成密钥对 key = EC_KEY_new_by_curve_name(NID_secp256k1); EC_KEY_generate_key(key); // 获取密钥对的公钥和椭圆曲线参数 group = EC_KEY_get0_group(key); pub_key = EC_KEY_get0_public_key(key); // 明文长度为32字节 msg_len = 32; msg = (unsigned char *)malloc(msg_len); memset(msg, 0x01, msg_len); // 加密操作 ciphertext_len = ECDSA_size(key); ciphertext = (unsigned char *)malloc(ciphertext_len); res = EC_POINT_new(group); EC_POINT_mul(group, res, bn, NULL, NULL, NULL); EC_KEY_set_private_key(key, bn); EC_KEY_set_public_key(key, res); ECDSA_do_encrypt(msg, msg_len, key, ciphertext); // 解密操作 plaintext_len = ECDSA_size(key); plaintext = (unsigned char *)malloc(plaintext_len); ECDSA_do_decrypt(plaintext, plaintext_len, ciphertext, ciphertext_len, key); // 打印结果 printf("Plaintext: "); for (int i = 0; i < msg_len; i++) { printf("%02x", msg[i]); } printf("\n"); printf("Ciphertext: "); for (int i = 0; i < ciphertext_len; i++) { printf("%02x", ciphertext[i]); } printf("\n"); printf("Decrypted plaintext: "); for (int i = 0; i < plaintext_len; i++) { printf("%02x", plaintext[i]); } printf("\n"); // 释放内存 BN_free(bn); EC_KEY_free(key); EC_POINT_free(pub_key); EC_POINT_free(res); free(msg); free(ciphertext); free(plaintext); } int main() { ecc_encrypt_decrypt_demo(); return 0; } ``` 以上代码实现了一个简单ecc加密解密过程,其中使用了openssl库提供的相关函数。需要注意的是,ecc算法的安全性与密钥长度相关,选择合适的密钥长度是非常重要的。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值