编码原理
将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+1⩽n) 椭圆曲线:
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:y2≡x3+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,⋯,K−1) 使
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}
2−K(m可以对应K个m’,每个m’失败的概率为1/2$,全部失败的概率
2
−
K
2^{-K}
2−K),其中(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:y2≡x3+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)
p≡3 (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 将信息转化为椭圆曲线代码