手工推算 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();
	}
}
posted @ 2020-03-31 23:17  poziiey  阅读(481)  评论(0编辑  收藏  举报