Bootstrap

椭圆曲线加密(ECC)明文编码方法及代码实现

编码原理

 将m转化为B进制,即
m = m 0 + m 1 B + m 2 B 2 + ⋯ + m N B N  (当中 B N + 1 ⩽ n ) m=m_0+m_1B+m_2B^2+\cdots+m_NB^N \text{ (当中}B^{N+1}\leqslant n\text{)} m=m0+m1B+m2B2++mNBN (当中BN+1n  椭圆曲线:
E : y 2 ≡ x 3 + a x + b   ( m o d   p ) E: y^2\equiv x^3+ax+b \text{ } (mod \text{ } p) E:y2x3+ax+b (mod p) 将明文m对应到椭圆曲线 E ( F p ) E(\mathbb{F}_p) E(Fp)某点的x坐标值。但是 m 3 + a m + b m^3+am+b m3+am+b为完全平方数的概率为 1 2 \frac{1}{2} 21(不知道这个概率怎么来的)。所以添加若干位在m上,即
m ′ = m K + j   ( j = 0 , ⋯   , K − 1 ) m'=mK+j\text{ }(j=0,\cdots,K-1) m=mK+j (j=0,,K1) 使 x 3 + a x + b x^3+ax+b x3+ax+b为完全平方数,如此便可对应到 E ( F p ) E(\mathbb{F}_p) E(Fp)上的一点。而失败的概率,即m’无法对应到 E ( F p ) E(\mathbb{F}_p) E(Fp)的概率为 2 − K 2^{-K} 2K(m可以对应K个m’,每个m’失败的概率为1/2$,全部失败的概率 2 − K 2^{-K} 2K,其中(m+1)K<p。
 而解码 P m P_m Pm=(x,y),只需要
m = ⌊ x K ⌋ m=\lfloor \frac{x}{K} \rfloor m=Kx

示例

E : y 2 ≡ x 3 + 82 x + 502773   ( m o d   502807 ) E: y^2\equiv x^3+82x+502773 \text{ } (mod \text{ } 502807) E:y2x3+82x+502773 (mod 502807)
将m="coding"用曲线上的点表达,表达失败概率为 1 2 20 \frac{1}{2^{20}} 2201,所以取K=20。约定编码为:空白=0,a=1,……,z=26,所以有27个符号(看作27进制)
⌊ log ⁡ 27 502807 20 ⌋ = 3 ( 求 ⌊ log ⁡ B p K ⌋ ) \lfloor \log_{27}\frac{502807}{20} \rfloor=3 \qquad (\text{求}\lfloor \log_{B}\frac{p}{K} \rfloor) log2720502807=3(logBKp) 所以每3个字母区块编码
m = " c o d i n g " = ( m 1 , m 2 ) = ( ( 3 , 15 , 4 ) 27 , ( 9 , 14 , 7 ) 27 ) = ( 2596 , 1047 ) \begin{aligned} m&="coding" \\ &=(m_1,m_2) \\ &=((3,15,4)_{27},(9,14,7)_{27}) \\ &=(2596,1047) \end{aligned} m="coding"=(m1,m2)=((3,15,4)27,(9,14,7)27)=(2596,1047)以上均为书上内容(见文末参考),但是之后的内容我看不懂了,就直接写我的想法了。
 1. 对于 m 1 m_1 m1 x ( P m 1 ) = 20 m 1 = 51920 x(P_{m_1})=20m_1=51920 x(Pm1)=20m1=51920,代入椭圆曲线方程,算出 y 2   ( m o d   p ) ≡ 465711 y^2 \text{ } (mod \text{ } p)\equiv 465711 y2 (mod p)465711 2. 另外由于 p ≡ 3   ( m o d   4 ) p\equiv 3 \text{ } (mod \text{ } 4) p3 (mod 4),计算
y ( P m 1 ) = 46571 1 p + 1 4   ( m o d   p ) = 309270 y(P_{m_1})=465711^{\frac{p+1}{4}} \text{ } (mod \text{ } p)=309270 y(Pm1)=4657114p+1 (mod p)=309270 这一步书上写的是错的,我怎么算都算不出来。另外,这步我也看不懂,跟着做就完事了。
 3. 验证309270是否是y值,计算
30927 0 2   ( m o d   p ) = 465711 309270^2 \text{ } (mod \text{ } p)=465711 3092702 (mod p)=465711  得到曲线点
P m 1 = ( 51920 , 309270 ) P_{m_1}=(51920,309270) Pm1=(51920,309270) 对于 m 2 m_2 m2 x ( P m 2 ) = 20 m 2 + 3 = 20943 x(P_{m_2})=20m_2+3=20943 x(Pm2)=20m2+3=20943,我觉得这个+3是遍历得到的,m’+=1,重复以上的三步并验证。

sage代码实现

 怎么把明文字符串和int相互转换就不介绍了(我也不知道在sage里要怎么转换),比如在python里先encode/decode,再Crypto.Util.number库里的bytes_to_long/long_to_bytes就能实现。

# encode int m to a point on E
def curveEncode(m):
    m *= K
    while(1):
    	# step 1
        f = pow(m,3,p)+7 # secp256k1, change it to your curve
        f = f%p
        # step 2
        y = pow(f,(p+1)//4,p) # p+1 because p mod 4 = 3, to be changed
        # step 3: check
        if(f==pow(y,2,p)):
            return E(m,y) # return the point
        m += 1

def curveDecode(Pm):
    m = int(Pm[0])//K # convert Pm[0] into int type
    return m

参考:《密码学——加密演算法》邓安文编著 10.6 将信息转化为椭圆曲线代码

;