【CTF基础】有限域椭圆曲线定义与计算方式

定义与基础运算

有限域椭圆曲线定义

Ep(a, b)表示椭圆曲线方程y**2 = x**3 + a*x + b,在有限域Fp中,表示所有在同余意义上满足该方程的(x, y)点,例如下图:(图片来自网络)
【CTF基础】有限域椭圆曲线定义与计算方式_第1张图片
对椭圆曲线E23(1, 1),点P(3, 10)满足y**2 = 100 = 31 = x**3 + x + 1 (mod 23),故点P(3, 10)在曲线上

有限域椭圆曲线计算关系

椭圆曲线上两点P(x1, y1)和Q(x2, y2)的计算关系如下:
(1) -P:-P = (x1, -y1) = (x1, p-y1)
(2) P+Q:首先需要计算参数k,定义为:
当P=Q时,k = (3*x1**2+a) / (2*y1) = (3*x1**2+a) * inv((2*y1), p) (mod p)
当P!=Q时,k = (y2-y1) / (x2-x1) = (y2-y1) * inv((x2-x1), p) (mod p)
然后计算x3, y3满足
x3 = k2 - x1 - x2 (mod p)
y3 = k * (x1 - x3) - y1 (mod p)
定义为P(x1, y1) + Q(x2, y2) = R(x3, y3)

例题:

已知椭圆曲线E23(1, 1)上两点P(3, 10),Q(9, 7),求(1) -P,(2)P+Q,(3)2P

解答:

(1) -P = (3, -10) (mod 23) = (3, 13)
(2) k = (7-10) * inv((9-3), 23) (mod 23) = (-3) * 4 (mod 23) = 11
x3 = k2 - x1 - x2 (mod p) = 109 (mod 23) = 17
y3 = k * (x1 - x3) - y1 (mod p) = 89 (mod 23) = 20,P + Q = (17, 20)
(3) k = (3*3**2+1) * inv((2*10), 23) (mod 23) = 5 * 15 (mod 23) = 6
x3 = k2 - x1 - x2 (mod p) = 30 (mod 23) = 7
y3 = k * (x1 - x3) - y1 (mod p) =-34 (mod 23) = 12,2P = (7, 12)

有限域椭圆曲线的阶

接下来定义有限域椭圆曲线的阶。对于曲线上一点P,若存在最小的正整数n,使得nP = O(无穷远点),则称n为P的阶。例如,在曲线E23(1, 1)中,点P(3, 13)可计算的27P = (3, -13) = -P,因此28P = O,P的阶为28。所有形如kP的点构成了一个循环阿贝尔群,其阶数为29,其中生成元为P,如下图所示:(图片来自网络)
【CTF基础】有限域椭圆曲线定义与计算方式_第2张图片
可见这些点分布是杂乱无章的,利用这一性质诞生出椭圆曲线加密的算法

有限域椭圆曲线加密算法

考虑K = kG,其中K、G为椭圆曲线Ep(a, b)上的点,n为G的阶(即nG = O),k为小于n的整数。根据加法法则,给定k、G计算K很容易;但反过来给定K、G,计算k则非常困难。实际使用中,p与n都会相当大,因此把n个解点逐一算出来是不可能的。上述描述中,称G为基点,k为私有密钥,K为公开密钥。通信算法如下:

  • 1.Alice选定一条椭圆曲线E,并取椭圆曲线上一点作为基点G 假设选定E29(4,20),基点G(13,23) , 基点G的阶数n=37
  • 2.Alice选择一个私有密钥k(k 例如k = 25,K= kG = 25G = (14,6)
  • 3.Alice将E和点K、G传给Bob
  • 4.Bob收到信息后,将待传输的明文编码到上的一点M(编码方法略),并产生一个随机整数r(r 例如r=6,要加密的信息为m=3,因为M也要在E29(4,20)上,所以M=(3,28)
  • 5.Bob计算点C1=M+rK和C2=rG
    C1 = M + 6K = M + 6 * 25 * G = M + 2G = (3,28) + (27,27) = (6,12)
    C2 = 6G = (5,7)
  • 6.Bob将C1、C2传给Alice
  • 7.Alice收到信息后,计算C1-kC2,结果就是点M
    C1 - kC2 = (6,12) - 25C2 = (6,12) - 25 * (5,7)
    = (6,12) - (27,27) = (6,12) + (27,2) = (3,28)

可以这样做的原因是:
C1 - kC2 = M + rK - krG = M + rkG - krG = M
通常将Fp上的一条椭圆曲线描述为T=(p,a,b,G,n,h)。其中p、a、b确定一条椭圆曲线;G为基点;n为点G的阶;h是椭圆曲线上所有点的个数m与n相除的商的整数部分。

例题:

已知椭圆曲线加密Ep(a,b)参数为
p = 15424654874903,a = 16546484,b = 4548674875,
G(6478678675,5636379357093),私钥为k = 546768,求公钥K(x,y)

解答:

主要功能代码部分见下:

#!/usr/bin/python
#encoding=utf-8
from gmpy2 import invert

def ECCnegative(x, y, p):
    return x, p-y

def ECCadd(x1, y1, x2, y2, p, a):
    if(x1==x2):
        if((y1+y2)%p==0):
            return -1, -1 # infinity return
        elif(y1!=y2):
            print ("Input Error, Please check the input!")
            return -2, -2 # error input return
        else:
            k = ((3 * x1 * x1 + a) * invert(2 * y1, p)) % p
            x3 = (k * k - x1 - x2) % p
            y3 = (k * (x1 - x3) - y1) % p
            return int(x3), int(y3)
    else:
        k = ((y2 - y1) * invert(x2 - x1, p))%p
        x3 = (k * k - x1 - x2) % p
        y3 = (k * (x1 - x3) - y1) % p
        return int(x3), int(y3)

def ECCmul(k, x, y, p, a):
    tempx, tempy = -1, -1
    nowx, nowy = x, y
    while(k != 0):
        mark = k & 1
        k = k >> 1
        if(mark == 1):
            if(tempx == -1):
                tempx, tempy = nowx, nowy
            else:
                tempx, tempy = ECCadd(tempx, tempy, nowx, nowy, p, a)
        nowx, nowy = ECCadd(nowx, nowy, nowx, nowy, p, a)
    return tempx, tempy

结果为(13957031351290, 5520194834100)
(备注:本题为XUSTCTF2016原题,网上部分公开的代码是错误的,因为里边一个写法问题,导致and判断被当成了与运算,如下所示:
print (-1<0 & -1<0) False(代码中写法)
print (-1<0 and -1<0) True(正确写法)
在xctf平台刷题的时候请注意需要填写错误答案)

你可能感兴趣的:(【CTF基础】有限域椭圆曲线定义与计算方式)