摘要

本文主要是使用MATLAB演示橢圓曲線加密演算法(ECC)的加密/解密過程,內容包括金鑰、公鑰生成,以及通過加密並解密一個簡單數字的過程來描述其使用方法。
本文實際是對以下兩篇文章的一個MATLAB實現,並且提供了兩個實用的MATLAB工具函式以便在閱讀過程中可以隨時檢驗計算的結果。本文不講ECC數學原理,但程式碼中又實際用到其數學規則,所以讀者應該結合下面兩篇文章閱讀本文。(本文更像是對下面第一篇文章內容的一個檢驗)
- 《ECC橢圓曲線詳解(有具體例項)
- 《Elliptic Curve Cryptography: a gentle introduction

工具

當指定x的值時,計算區間[0,p]內所有y的值。

這個工具功能很容易理解,通俗點說就是給定x求y,y的取值範圍為[0,p]

%file:ECCCal.m
%a,b為橢圓引數,p為質數,x為給定的值 
function [ y ] = ECCCal( a,b,p,x )
y=[];

mm = mod(x^3+a*x+b,p);

index = 1;

for yy = 0:1:p
    if mod(yy^2,p) == mm
        y(index)=yy;
        index=index+1;
    end
end

end

如計算ECCCal(1,1,23,3)可以得到兩個結果 1013 (有多個結果是正常的不用在意,如果不限定y的範圍,理論上是有無數個的)

計算(0,0)->(p,p)正方形範圍內所有滿足“橢圓公式“的點

使用這個工具可以方便我們將該範圍內所有滿足“橢圓公式”(如果看了上邊說的兩篇文章就知道這裡的橢圓公式可不是指傳統意義上的橢圓公式)的點,並將其打印出來。


%file:ECCPlot.m
%a,b分別為橢圓的引數,p為一個質數
function [x,y] =  ECCPlot( a,b,p)

x=[];
y=[];
index = 1;
for xr = 0:1:p
    mm = mod(xr^3+a*xr+b ,p);    
    for yr=0:1:p
        if mod(yr^2,p) == mm
            x(index)=xr;
            y(index)=yr;
            index = index+1;
        end
    end
end
plot(x,y,'*')
hold on
grid on
end

例如我們在MATLAB終端呼叫ECCPlot(1,1,23)可以看到如下圖片
這裡寫圖片描述
跟推薦的第一篇文章裡的圖點的座標位置是一樣的

基本操作方法的MATLAB實現

因為橢圓曲線加密演算法的特殊性我們需要自己實現幾個操作方法

分數的模運算

我們很容易知道 2對23取模的結果是2,但12對23的模是多少呢?MATLAB裡本身是沒有這種計算的方法的(也許是因為我沒找到?)所以這裡我們需要自己實現

%file:modfrac.m
% n 分子  d 分母   m 模數
function y = modfrac( n,d,m )

n=mod(n,m);
d=mod(d,m);


i=1;
while mod(d*i,m) ~=1
    i=i+1;
end

y=mod(n*i,m);
end

其實這裡還有一個隱藏的陷阱:很多人理解求模就是求除法的餘數,但這樣是不對的。例如 -2 mod 23 求餘數 -2%23=-2但求模mod(-2,23)=21,一定要知道求模運算不能簡單的理解為求餘數,至少不能用%來計算。

加法運算

我們還需要自定義滿足橢圓曲線方法的兩個點的加法運算,具體規則此處不再贅述了,請檢視摘要中提到的兩篇文章。

%file:Add.m
%a,b 橢圓引數  p 質數 x1,y1 第一個點的座標 x2,y2 第二個點的座標
function [ resx,resy ] = Add( a,b,p,x1,y1,x2,y2 )

if x1==x2 && y1==y2
    k=modfrac(3*x1^2+a,2*y1,p);
    resx = mod(k^2-x1-x2,p);
    resy = mod(k*(x1-resx)-y1,p);
end

if x1==x2 && y1~=y2
    resx = inf;
    resy = inf;
end

if x1 ~= x2
    k=modfrac(y2-y1,x2-x1,p);
    resx = mod(k^2-x1-x2,p);
    resy = mod(k*(x1-resx)-y1,p);    
end
end

如兩點P(3,10)Q(9,7) 計算P+Q[x,y]=Add(1,1,23,3,10,9,7)得到結果 x=17,y=20(跟第一篇文章中給的示例的結果是一樣的)

常量乘法

什麼是常量乘法呢?實際上就是N(N為正整數)乖以點P。具體邏輯也需要檢視摘要中的文章,如果您閱讀的比較詳細還會發現第1篇文章給的示例中在求2P的過程中有一處錯誤。同時也需要說明的是下邊MATLAB的實現並沒有使用第2篇文章中提到的更快速的演算法(為了簡單,使用了遞迴累加的計算方法)

%file:NP.m
%a,b 橢圓引數,p 質數,n表示 n個點P相加也就是n*P ,x,y 表示P點的橫縱座標
function [resx,resy] = NP( a,b,p,n,x,y )

if n ==1
    resx = x;
    resy = y;
    return;
end
if n>=2
    [xsub,ysub]=NP(a,b,p,n-1,x,y);
    if xsub==Inf && ysub == Inf 
        resx=Inf;
        resy=Inf;
    else
        [resx,resy]=Add(a,b,p,x,y,xsub,ysub);
    end
end
end

[x,y]=NP(1,1,23,2,3,10)結果x=7,y=12,[x,y]=NP(1,1,23,3,3,10)結果x=19,y=5

加密解密過程

至此我們加密解密需要的所有演算法模組就全部足夠了。
流程以摘要中提到的第一篇文章中給的示例為例(我結合本文的程式碼對其表述進行了修改)

  1. Alice選定一條橢圓曲線E,並取橢圓曲線上一點作為基點G 假設選定的橢圓為a=4,b=20,p=29所示示的橢圓,基點G(13,23) , 基點G的階數n=37(階數的概念本文沒提,你可以理解為在進行常量乘法運算的時候常量的最大值要小於n
  2. Alice選擇一個私有金鑰k(k<n)並生成公開金鑰K=kG 比如k=25, K= kG = 25G = (14,6)(使用我們的乘法運算函式去測試一下)
  3. Alice將E和點KG傳給Bob ( 這沒什麼說的,E,K,G 共同組成了公鑰,需要把公鑰發給對方)
  4. Bob收到資訊後,將待傳輸的明文編碼到上的一點M(編碼方法略),併產生一個隨機整數r(r<n,n為G的階數) 假設r=6 要加密的資訊為3,因為該資訊也需要滿足曲線方程E,所以我們很容易能夠選取到一點(3,28)(其他的點如(3,1)也是可以的)
  5. Bob計算點C1=M+rKC2=rG
  6. Bob將C1、C2傳給Alice(容易理解,將加密資訊傳回給Bob,由Bob解密以知道Alice給他傳的是啥)
  7. Alice收到資訊後,計算C1-kC2得到的結果應該是(3,28) (解密過程)

至此橢圓曲線加密、解密的整個流程就結束了。將其寫成一個MATLAB指令碼 如下:

%file:ECC.m
%演示曲線加密演算法加/解密過程
a=4;
b=20;
p=29;
GX=13;
GY=23;
k=25;
[KX,KY]=NP(a,b,p,k,GX,GY)

r=6

MX = 3
MY = 28

[rKX,rKY] = NP(a,b,p,r,KX,KY)

[C1X,C1Y]=Add(a,b,p,MX,MY,rKX,rKY)

[C2X,C2Y]=NP(a,b,p,r,GX,GY)


[kC2X,kC2Y]=NP(a,b,p,k,C2X,C2Y);

kC2Y=mod(-1*kC2Y,p)

[resx,resy]=Add(a,b,p,C1X,C1Y,kC2X,kC2Y)

我們執行一下可以看到輸出結果 resx=3,resy=28這裡的3正是Bob給Alice傳的數字內容,其他人因為沒有私鑰k所以無法像Alice那樣簡單地還原出數字3

總結

慣例文章最後總是要說點什麼,我就說說自己的感受吧。
橢圓加密演算法看似簡單(僅僅通過一個加法運算和一個常量乘法運算便完成了加密解密演算法)但其背後隱藏了很深的數學知識。本文僅僅是起演示功能,真正在實際生產中所使用的實現方式以及加密解密過程還需要進行深入地學習。