手工推算 Dual-EC-DRBG 序列

已知 (F_{11}) 上的椭圆曲线 (E : y ^2 = x ^3 + x + 6), 以及 (E) 上的有理点群
(E(F_{11} ) =) { (O,(2,7),(5,2),(8,3),(10,2),(3,6),(7,9),(7,2),(3,5),(10,9),(8,8),(5,9),(2,4))}​

手工推算出一段 (Dual-EC-DRBG) 伪随机数样本序列(在此我们不涉及安全性问题),自己设定参数。

概念回顾

(11)的二进制数为(1011),即这里的(p)(4)

(R=(x,y)∈E) 则记 (χ (R)=x) (横坐标,视为整数,这里是(4)比特)

(Trunc(x,m))表示(x)的低(p-m)比特

参数选取

取种子(S_0 = 4(0100))

(m = 2)

推算过程

(E(F_{11} ))={ (O,(2,7),(5,2),(8,3),(10,2),(3,6),(7,9),(7,2),(3,5),(10,9),(8,8),(5,9),(2,4))}

倍点计算后面再说,这里直接写结果了。

(P(2,7) Q(5,2))

输出随机数(Trunc(χ (S_0Q),m) = Trunc(χ (4*(5,2)),m) = Trunc(0011,2))

(0011)的低(2)比特即输出(11)

更新(S_1 = χ (S_0P) = 10)

(P(8,3) Q(10,2))

输出随机数(,Trunc(χ (S_1Q),m) = Trunc(χ (10*(10,2),m) = Trunc(0010,2))

(0010)的低(2)比特即输出(10)

更新(S_2 = χ (S_1P) = 10)

(P(3,6)Q(7,9))

输出随机数(Trunc(χ (S_2Q),m) = Trunc(χ (10(7,9)),m) = Trunc(0011,2))

(0011)的低(2)比特即输出(11)

更新(S_3 = χ (S_2P) = 5)

(P(7,2)Q(3,5))

输出随机数(Trunc(χ (S_3Q),m) = Trunc(χ (5*(3,5)),m) = Trunc(0010,2))

(0010)的低(2)比特即输出(10)

更新(S_4 = χ (S_3P) = 10)

(P(10,9)Q(8,8))

输出随机数(Trunc(χ (S_4Q),m) = Trunc(χ (10*(8,8)),m) = Trunc(1010,2))

(1010)的低(2)比特即输出(10)

更新(S_5 = χ (S_4P) = 2)

(P(5,9)Q(2,4))

输出随机数(Trunc(χ (S_5Q),m) = Trunc(χ (2*(2,4)),m) = Trunc(0101,2))

(0101)的低(2)比特即输出(01)

则推算出 (Dual-EC-DRBG) 序列为(111011101001)

倍点计算举例

已知(G(2,7))在上述椭圆曲线上,求(2G)

步骤:求(G)与曲线相切时的斜率(求导),得到直线方程;将直线方程代入曲线方程,解三次方程。

计算时注意(P+Q)并不在(PQ)上,而是在(-PQ)上。

(P(x_1,y_1)Q(x_2,y_2)R(x_3,y_3)) 椭圆曲线(y^2 = x^3+ax+b)

(PQ)斜率:

(K = frac{y_2-y_1}{x_2-x_1}) (P≠Q)

(K = frac{3x^2+a}{2y}) (P=Q)

此时我们算的是(2G)(P = Q)化简可得(y_3 = kx_3 + C)

(y_3)代入椭圆曲线方程解得

(y_3 = k(x_1-x_3)-y_1)

(x_3 = k^2 - x_2 -x_1)

(G(2,7))代入解得(K = frac{12+1}{2x7} = frac{13}{14} mod11)

关于分数求模可参考链接 https://wenku.baidu.com/view/6f2879cca1c7aa00b52acb5f.html

解得(K= 8),代入 ((x_3,y_3)) 可得 (2G)((5,2))

倍点计算代码展示

参考链接 https://wenku.baidu.com/view/5e2cce4d767f5acfa1c7cd3b.html

import java.io.*;
public class ecc{
	public static int x,y,n,a,p;
	public static int getX(int x)
	{
	  int i=1;
	  while(true)
	  {
		  if(modP(x*i)==1)
		  {
			  break;
		  }
		  i++;
	  }
	  return i;
	}
	public static int modP(int x)
	{
		if(x<0)
		{
			while(x<0)
			{
				x=x+p;
			}
		}
		else
			x=x%p;
		return x;
	}
	public static void getR()
	{
		int X=x,Y=y;
		for(int i=1;i<n;i++)
		{
			if(X==x&Y==y)
			{
				int k=getK(a,x,y);
				X=modP(k*k-x-X);
				Y=modP(k*(x-X)-y);
			}
			else
			{
				int k=getk(x,y,X,Y);
				X=modP(k*k-x-X);
				Y=modP(k*(x-X)-y);
			}
		}
		System.out.println("("+X+","+Y+")");
	}
	public static int getK(int a,int x,int y)
	{
		int k=(3*x*x+a)*getX(2*y);
		return modP(k);
	}
	public static int getk(int x1,int y1,int x2,int y2)
	{
		int k=(y2-y1)*getX(x2-x1);
		return modP(k);
	}
	public static void main(String args[]) throws IOException
	{
		BufferedReader f=new BufferedReader(new InputStreamReader(System.in));
		System.out.println("按如下格式输入要计算的倍点:");
		System.out.println("椭圆曲线方程:y^2=aX^3+bx+c,请输入:a");
		String s=f.readLine();
		a=Integer.parseInt(s);
		System.out.println("所求坐标Q(x,y),输入x,y");
		s=f.readLine();
		x=Integer.parseInt(s);
		s=f.readLine();
		y=Integer.parseInt(s);
		System.out.println("输入素数p");
		s=f.readLine();
		p=Integer.parseInt(s);
		System.out.println("倍点nQ,输入n");
		s=f.readLine();
		n=Integer.parseInt(s);
		System.out.println("点Q("+x+","+y+")的"+n+"倍点结果"+n+"Q是");
		getR();
	}
}
原文地址:https://www.cnblogs.com/poziiey/p/12598690.html