日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ECC加密算法C简单实现

發布時間:2024/1/1 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ECC加密算法C简单实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ECC加密算法 c完成

ECC加密算法的理解

本文主要參照:ECC橢圓曲線加解密原理詳解(配圖)

  • 先理解一下這篇博客 ,ECC橢圓曲線加解密原理詳解(配圖)
  • 通過對博客里面的有限域的橢圓曲線來進行實現里面的公式
  • 下面是我的文檔報告直接附上,可能有沒有表述清楚的可以在評論區評論。代碼部分只提供生成公鑰的,前面博客中提到的編碼到一個點上可以在網上搜索,以及博客中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!=0){ d=d*(-1);//符號不一樣}k=modsame(x1*d);//求同余return k; } struct pos fup(struct pos co1)//計算-p,保存-p,p到結構體數組中 {struct pos co=co1;int i=0;co.np[0].x=co.x;co.np[0].y=p-co.y;co.np[1].x=co.x;co.np[1].y=co.y;return co; } struct pos addnp(struct pos co1,int jie)//計算相同兩個點的加法,不過是為算出階所寫的算法需要通過此算法得到前面的點才能算出后面的點5P=3P+2P得先調用后面addsame(p,2)再調用addnp(p,3),再add(p,5)這樣得到5P。 {struct pos co=co1;int i=0;int x1,y1,x2,y2;if(jie==1){return co;}x1=co.np[jie/2].x;y1=co.np[jie/2].y;x2=co.np[jie/2+1].x;y2=co.np[jie/2+1].y;int k=calk(y2-y1,x2-x1);co.np[jie].x=modsame(k*k-x1-x2);co.np[jie].y=modsame(k*(x1-co.np[jie].x)-y1);return co; }struct pos addsame(struct pos co1,int jie)//計算偶數個P的加法。是在之前P算出的基礎上計算的。 {struct pos co=co1;int i=0;int x,y;x=co.np[jie/2].x;y=co.np[jie/2].y;int k=calk(3*x*x+a,2*y);co.np[jie].x=modsame(k*k-2*x);co.np[jie].y=modsame(k*(x-co.np[jie].x)-y);return co; } struct pos everynp(struct pos c,int r)//任意一個點的r需要將前面的也算出來后才可以得到np。 {struct pos c2=c;int k=r;for(int j=2;j<=k;j++){if(j%2==0){c2=addsame(c2,j);}else{c2=addnp(c2,j);} }return c2; }struct pos addDif(struct pos co1,struct pos co2)//任意兩個點相加 {struct pos co=co1;struct pos co3=co2;int i=0;int x1,y1,x2,y2;x1=co.x;y1=co.y;x2=co3.x;y2=co3.y;int k=calk(y2-y1,x2-x1);co.x=modsame(k*k-x1-x2);co.y=modsame(k*(x1-co.x)-y1);return co; }

    4.3 功能模塊
    4.3.1 產生生成元和階

    void scy()//求生成元 {int i,next,xvlue;i=0;xvlue=-1;next=0;count=0;while(1){printf("請輸入a(a>0且整數):");scanf("%d",&a);printf("請輸入b(b>0且整數):");scanf("%d",&b);printf("請輸入p(p為大素數):");scanf("%d",&p);if(scanistrue()==0)break;elseprintf("輸入不符合條件請重新輸入\n");}printf("y2=x3+%dx+%d(mod %d)\n",a,b,p);for(int j=0;xvlue<p-1;j++){int re;xvlue++;coor[j].x=xvlue;re=int(pow(coor[j].x,3)+a*coor[j].x+b)%p;if (re==0){ coor[j].y=0;count++;xvlue++;}else{for(i=0;i<=(p-1)*(p-1);i++){if((i%p)==re){int n=0;for( n=0;n<i;n++){if(n*n==i) break;}if(n==i){continue;}coor[j].y=n;coor[j].x=xvlue;next=j;next++;coor[next].x=xvlue;coor[next].y=p-n;j++;count=count+2;break;}}if(i==(p-1)*(p-1)+1)j--;}}for(int k=0;k<count;k++){coor[k].num=k+1;coor[k].jie=1024;} }void everyPointandjie()//調用生成生成元的函數和生成階 {scy();int i=0;for( i=0;i<count;i++){coor[i]=fup(coor[i]);}for(i=0;i<count;i++){for(int j=2;j<1024;j++){if(j%2==0){coor[i]=addsame(coor[i],j);}else{coor[i]=addnp(coor[i],j);}if((coor[i].np[0].x==coor[i].np[j].x)&&(coor[i].np[0].y==coor[i].np[j].y)){coor[i].jie=j+1;break;}}}for(i=0;i<count;i++){if(coor[i].y==0)coor[i].jie=1024;printf("%d:(%d,%d)-->階:%d\t",coor[i].num,coor[i].x,coor[i].y,coor[i].jie);if((i+1)%3==0){printf("\n");}}}//4.4.2 選擇基點產生私鑰產生公鑰 void pkout() {int i=0;printf("\n選擇基點G的序號:");scanf("%d",&Gnum);for(i=0;i<count;i++){if(Gnum==coor[i].num)break;}printf("\n基點G:(%d,%d)\n",coor[Gnum-1].x,coor[Gnum-1].y); // printf("\n---基點G:(%d,%d)\n",coor[i].x,coor[i].y);printf("輸入私鑰(key<%d):",coor[i].jie);scanf("%d",&skey);pk=coor[i];pk.x=coor[i].np[skey].x;pk.y=coor[i].np[skey].y;printf("生成公鑰:(%d,%d)",pk.x,pk.y); }

    效果圖

    因為編碼到點是另外同學寫的就不把代碼傳上來了,編碼方式多種可以去網上搜索,接下來4,5,6,步算法設計
    **第四步:**隨機生成一個r,r的值是小于你選擇的績點的階的。
    **第五步:**計算C =M+rK,先調用公鑰K的結構體里面的數組np 下標為r 的x,y 這就是點rk 的坐標 ,然后再調用addDif(M,rK),計算C 2 = r G,調用基點G的結構體里面的數組np的下標為r的x,y就是G的坐標;
    第六步: C 1? ?kC 2 先調用fup 函數 將-C2和C2本身的值存入C2結構體的np數組里面,算出kC2 調用 everynp(C2,r)這里的r要從2到k循環,因為要kC2是在算出C2,2C2,3C2…才能算出KC2再對KC2來求逆元調用fup函數,再用任意兩個數addDif加法的函數來算出C1-KC2得到M
    再對M解碼得到明文。
    總結
    我知道其實遞歸以及在每個函數的里面加上循環不用每次循環調用函數來達到計算前面的值,但我懶得改。以及遞歸不怎么寫,我隱隱覺得遞歸容易犯錯。

    總結

    以上是生活随笔為你收集整理的ECC加密算法C简单实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。