热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ecc签名体制c语言代码大全,ECC算法C语言实现Go语言中文社区

密码学实验:ECC算法实现1.实验内容2.运行结果:1.椭圆曲线上的点集2.椭圆曲线生成元以及对应的阶3.加解密算法代码如下:*(1)编程

密码学实验:ECC算法实现

1.实验内容

34cce5ed691ebcb4e62d5923d44e281f.png

2.运行结果:

1.椭圆曲线上的点集

d41fd68de285bb1bffe07086936f0dc9.png

2.椭圆曲线生成元以及对应的阶

dc7fa6c64f52dc5ad0b18c0e1021daa2.png

3.加解密算法

d025d6a2ac48cc0d01095ba2bf33094c.png

代码如下:

/*

(1)编程计算该椭圆曲线上所有在有限域GF(89)上的点;

(2)编程实现椭圆曲线上任意一个点P(例如P=(12,5))的倍点运算的递归算法,即计算k*P( k=2,3,…);(重点!)

(3)利用此递归算法找出椭圆曲线上的所有生成元G以及它们的阶n,即满足n*G=O;

(4)设计实现某一用户B的公钥、私钥算法,即得到public key=(n, G, PB, Ep(a, b))

secure key=nB(小于n)

(5)假如用户A发送明文消息“yes”并加密传输给用户B,用户B接收消息后要能解密为明文。试用ECC密码体制实现此功能。

*/

#include

#include

#include

#include

#include

#define MAX 100

typedef struct point{

int point_x;

int point_y;

}Point;

typedef struct ecc{

struct point p[MAX];

int len;

}ECCPoint;

typedef struct generator{

Point p;

int p_class;

}GENE_SET;

void get_all_points();

int int_sqrt(int s);

Point timesPiont(int k,Point p);

Point add_two_points(Point p1,Point p2);

int inverse(int n,int b);

void get_generetor_class();

void encrypt_ecc();

void decrypt_ecc();

int mod_p(int s);

void print();

int isPrime(int n);

char alphabet[26]="abcdefghijklmnopqrstuvwxyz";

int a=-1,b=0,p=89;//椭圆曲线为E89(-1,0): y2=x3-x (mod 89)

ECCPoint eccPoint;

GENE_SET geneSet[MAX];

int geneLen;

char plain[]="yes";

int m[MAX];

int cipher[MAX];

int nB;//私钥

Point P1,P2,Pt,G,PB;

Point Pm;

int C[MAX];

int main()

{

get_generetor_class();

encrypt_ecc();

decrypt_ecc();

return 0;

}

//task4:加密

void encrypt_ecc()

{

int num,i,j;

int gene_class;

int num_t;

int k;

srand(time(NULL));

//明文转换过程

for(i=0;i

{

for(j&#61;0;j<26;j&#43;&#43;) //for(j&#61;0;j<26;j&#43;&#43;)

{

if(plain[i]&#61;&#61;alphabet[j])

{

m[i]&#61;j;//将字符串明文换成数字&#xff0c;并存到整型数组m里面

}

}

}

//选择生成元

num&#61;rand()%geneLen;

gene_class&#61;geneSet[num].p_class;

while(isPrime(gene_class)&#61;&#61;-1)//不是素数

{

num&#61;rand()%(geneLen-3)&#43;3;

gene_class&#61;geneSet[num].p_class;

}

//printf("gene_class&#61;%dn",gene_class);

G&#61;geneSet[num].p;

//printf("G:(%d,%d)n",geneSet[num].p.point_x,geneSet[num].p.point_y);

nB&#61;rand()%(gene_class-1)&#43;1;//选择私钥

PB&#61;timesPiont(nB,G);

printf("n公钥&#xff1a;n");

printf("{y^2&#61;x^3%d*x&#43;%d,%d,(%d,%d),(%d,%d)}n",a,b,gene_class,G.point_x,G.point_y,PB.point_x,PB.point_y);

printf("私钥&#xff1a;n");

printf("nB&#61;%dn",nB);

//加密

//

k&#61;rand()%(gene_class-2)&#43;1;

P1&#61;timesPiont(k,G);

//

num_t&#61;rand()%eccPoint.len; //选择映射点

Pt&#61;eccPoint.p[num_t];

//printf("Pt:(%d,%d)n",Pt.point_x,Pt.point_y);

P2&#61;timesPiont(k,PB);

Pm&#61;add_two_points(Pt,P2);

printf("加密数据&#xff1a;n");

printf("kG&#61;(%d,%d),Pt&#43;kPB&#61;(%d,%d),C&#61;{",P1.point_x,P1.point_y,Pm.point_x,Pm.point_y);

for(i&#61;0;i

{

//num_t&#61;rand()%eccPoint.len; //选择映射点

//Pt&#61;eccPoint.p[num_t];

C[i]&#61;m[i]*Pt.point_x&#43;Pt.point_y;

printf("{%d}",C[i]);

}

printf("}n");

}

//task5:解密

void decrypt_ecc()

{

Point temp,temp1;

int m,i;

temp&#61;timesPiont(nB,P1);

temp.point_y&#61;0-temp.point_y;

temp1&#61;add_two_points(Pm,temp);//求解Pt

//printf("(%d,%d)n",temp.point_x,temp.point_y);

//printf("(%d,%d)n",temp1.point_x,temp1.point_y);

printf("n解密结果&#xff1a;n");

for(i&#61;0;i

{

m&#61;(C[i]-temp1.point_y)/temp1.point_x;

printf("%c",alphabet[m]);//输出密文

}

printf("n");

}

//判断是否为素数

int isPrime(int n)

{

int i,k;

k &#61; sqrt(n);

for (i &#61; 2; i <&#61; k;i&#43;&#43;)

{

if (n%i &#61;&#61; 0)

break;

}

if (i <&#61;k){

return -1;

}

else {

return 0;

}

}

//task3:求生成元以及阶

void get_generetor_class()

{

int i,j&#61;0;

int count&#61;1;

Point p1,p2;

get_all_points();

//p1.point_x&#61;p2.point_x&#61;3;

//p1.point_y&#61;p2.point_y&#61;2;

//while(1)

//{

//printf("(%d,%d)&#43;(%d,%d)---%dn",p1.point_x,p1.point_y,p2.point_x,p2.point_y,count);

//p2&#61;add_two_points(p1,p2);

//count&#43;&#43;;

//if(p2.point_x&#61;&#61;-1 && p2.point_y&#61;&#61;-1)

//{

//break;

//}

//}

//printf("nn(%d,%d)---%dn",p1.point_x,p1.point_y,count);

//

//do{

//printf("(%d,%d)&#43;(%d,%d)---%dn",p1.point_x,p1.point_y,p2.point_x,p2.point_y,count);

//p2&#61;add_two_points(p1,p2);

//count&#43;&#43;;

//

//} while(!((p2.point_x&#61;&#61;p1.point_x)&&(p2.point_y&#61;&#61;p1.point_y)));

//printf("(%d,%d)&#43;(%d,%d)---%dn",p1.point_x,p1.point_y,p2.point_x,p2.point_y,count);

//count &#43;&#43; ;

//printf("nn(%d,%d)---%dn",p1.point_x,p1.point_y,count);

printf("n**********************************输出生成元以及阶&#xff1a;*************************************n");

for(i&#61;0;i

{

count&#61;1;

p1.point_x&#61;p2.point_x&#61;eccPoint.p[i].point_x;

p1.point_y&#61;p2.point_y&#61;eccPoint.p[i].point_y;

while(1)

{

p2&#61;add_two_points(p1,p2);

if(p2.point_x&#61;&#61;-1 && p2.point_y&#61;&#61;-1)

{

break;

}

count&#43;&#43;;

if(p2.point_x&#61;&#61;p1.point_x)

{

break;

}

}

count&#43;&#43;;

if(count<&#61;eccPoint.len&#43;1)

{

geneSet[j].p.point_x&#61;p1.point_x;

geneSet[j].p.point_y&#61;p1.point_y;

geneSet[j].p_class&#61;count;

printf("(%d,%d)--->>%dt",geneSet[j].p.point_x,geneSet[j].p.point_y,geneSet[j].p_class);

j&#43;&#43;;

if(j % 6 &#61;&#61;0){

printf("n");

}

}

geneLen&#61;j;

}

}

//task2:倍点运算的递归算法

Point timesPiont(int k,Point p0)

{

if(k&#61;&#61;1){

return p0;

}

else if(k&#61;&#61;2){

return add_two_points(p0,p0);

}else{

return add_two_points(p0,timesPiont(k-1,p0));

}

}

//两点的加法运算

Point add_two_points(Point p1,Point p2)

{

long t;

int x1&#61;p1.point_x;

int y1&#61;p1.point_y;

int x2&#61;p2.point_x;

int y2&#61;p2.point_y;

int tx,ty;

int x3,y3;

int flag&#61;0;

//求

if((x2&#61;&#61;x1)&& (y2&#61;&#61;y1) )

{

//相同点相加

if(y1&#61;&#61;0)

{

flag&#61;1;

}else{

t&#61;(3*x1*x1&#43;a)*inverse(p,2*y1) % p;

}

//printf("inverse(p,2*y1)&#61;%dn",inverse(p,2*y1));

}else{

//不同点相加

ty&#61;y2-y1;

tx&#61;x2-x1;

while(ty<0)

{

ty&#43;&#61;p;

}

while(tx<0)

{

tx&#43;&#61;p;

}

if(tx&#61;&#61;0 && ty !&#61;0)

{

flag&#61;1;

}else{

t&#61;ty*inverse(p,tx) % p;

}

}

if(flag&#61;&#61;1)

{

p2.point_x&#61;-1;

p2.point_y&#61;-1;

}else{

x3&#61;(t*t-x1-x2) % p;

y3&#61;(t*(x1-x3)-y1) % p;

//使结果在有限域GF(P)上

while(x3<0)

{

x3&#43;&#61;p;

}

while(y3<0)

{

y3&#43;&#61;p;

}

p2.point_x&#61;x3;

p2.point_y&#61;y3;

}

return p2;

}

//求b关于n的逆元

int inverse(int n,int b)

{

int q,r,r1&#61;n,r2&#61;b,t,t1&#61;0,t2&#61;1,i&#61;1;

while(r2>0)

{

q&#61;r1/r2;

r&#61;r1%r2;

r1&#61;r2;

r2&#61;r;

t&#61;t1-q*t2;

t1&#61;t2;

t2&#61;t;

}

if(t1>&#61;0)

return t1%n;

else{

while((t1&#43;i*n)<0)

i&#43;&#43;;

return t1&#43;i*n;

}

}

//task1:求出椭圆曲线上所有点

void get_all_points()

{

int i&#61;0;

int j&#61;0;

int s,y&#61;0;

int n&#61;0,q&#61;0;

int modsqrt&#61;0;

int flag&#61;0;

if (4 * a * a * a &#43; 27 * b * b !&#61; 0)

{

for(i&#61;0;i<&#61;p-1;i&#43;&#43;)

{

flag&#61;0;

n&#61;1;

y&#61;0;

s&#61; i * i * i &#43; a * i &#43; b;

while(s<0)

{

s&#43;&#61;p;

}

s&#61;mod_p(s);

modsqrt&#61;int_sqrt(s);

if(modsqrt!&#61;-1)

{

flag&#61;1;

y&#61;modsqrt;

}else{

while(n<&#61;p-1)

{

q&#61;s&#43;n*p;

modsqrt&#61;int_sqrt(q);

if(modsqrt!&#61;-1)

{

y&#61;modsqrt;

flag&#61;1;

break;

}

flag&#61;0;

n&#43;&#43;;

}

}

if(flag&#61;&#61;1)

{

eccPoint.p[j].point_x&#61;i;

eccPoint.p[j].point_y&#61;y;

j&#43;&#43;;

if(y!&#61;0)

{

eccPoint.p[j].point_x&#61;i;

eccPoint.p[j].point_y&#61;(p-y) % p;

j&#43;&#43;;

}

}

}

eccPoint.len&#61;j;//点集个数

print(); //打印点集

}

}

//取模函数

int mod_p(int s)

{

int i;//保存s/p的倍数

int result;//模运算的结果

i &#61; s / p;

result &#61; s - i * p;

if (result >&#61; 0)

{

return result;

}

else

{

return result &#43; p;

}

}

//判断平方根是否为整数

int int_sqrt(int s)

{

int temp;

temp&#61;(int)sqrt(s);//转为整型

if(temp*temp&#61;&#61;s)

{

return temp;

}else{

return -1;

}

}

//打印点集

void print()

{

int i;

int len&#61;eccPoint.len;

printf("n该椭圆曲线上共有%d个点(包含无穷远点)n",len&#43;1);

for(i&#61;0;i

{

if(i % 8&#61;&#61;0)

{

printf("n");

}

printf("(%2d,%2d)t",eccPoint.p[i].point_x,eccPoint.p[i].point_y);

}

printf("n");

}



推荐阅读
  • 本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 使用GDI的一些AIP函数我们可以轻易的绘制出简 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • 本文探讨了 C++ 中普通数组和标准库类型 vector 的初始化方法。普通数组具有固定长度,而 vector 是一种可扩展的容器,允许动态调整大小。文章详细介绍了不同初始化方式及其应用场景,并提供了代码示例以加深理解。 ... [详细]
  • 本实验主要探讨了二叉排序树(BST)的基本操作,包括创建、查找和删除节点。通过具体实例和代码实现,详细介绍了如何使用递归和非递归方法进行关键字查找,并展示了删除特定节点后的树结构变化。 ... [详细]
  • 本文详细介绍了C语言中链表的两种动态创建方法——头插法和尾插法,包括具体的实现代码和运行示例。通过这些内容,读者可以更好地理解和掌握链表的基本操作。 ... [详细]
  • 本文详细探讨了VxWorks操作系统中双向链表和环形缓冲区的实现原理及使用方法,通过具体示例代码加深理解。 ... [详细]
  • 本教程涵盖OpenGL基础操作及直线光栅化技术,包括点的绘制、简单图形绘制、直线绘制以及DDA和中点画线算法。通过逐步实践,帮助读者掌握OpenGL的基本使用方法。 ... [详细]
  • 在多线程编程环境中,线程之间共享全局变量可能导致数据竞争和不一致性。为了解决这一问题,Linux提供了线程局部存储(TLS),使每个线程可以拥有独立的变量副本,确保线程间的数据隔离与安全。 ... [详细]
author-avatar
落地有声800_491_431
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有