离散对数计算的Sherwood 算法

 

   问题描述:设 a=g^x mod p,记 log g,p a=x,称 x 为 a 的(以 g 为底模除 p)对数。从 p,g,a 计算 x 称为离散对数问题。
  问题在于:给出 p,g,a,怎么求 x

  

  简单算法:
1 ∀x, 计算 g ^x
最多计算 0≤x≤ p-1 或 1≤x≤p,因为实际上离散对数是循环群;
2 验证 a=g ^x mod p 是否成立。

dlog(g, a, p) {                // 当这样的对数不存在时,算法返回 p
     x ← 0; y ← 1;
    do {
        x++;
        y ← y*g;       // 计算 y=g^ x
    }  while ( a ≠ y mod p) and (x ≠ p);
    return x
}

问题:最坏 O(p),若 P 很大怎么办?所以简单算法不行,而且 x 的算出来的快慢取决于 a 的取值, a 的取值能够让算法较早找到正确的 x,则算法很快就完了,否则很慢,直到 p。


Sherwood 算法解决方法

算法f(x)可改造为Sherwood算法:
RH(x) {
     // 用Sherwood算法计算f(x)
     n ← length[x];             // x的size为n
     r ← uniform(A n );           // 随机取一元素
     y ← u(x, r);                 //将原实例x转化为随机实例y
     s ← f(y);                  // 用确定算法求y的解s
     return v(r, s);                 // 将s的解变换为x的解
}

Sherwood算法的核是找到u,v方法

应用上面这个算法框架 我们可以来改写这个离散对数计算的Sherwood 算法

根据上面的分析,Sherwood 算法应该使得这个算法不会根据 a,p 的取值影响算法的快慢

算法依据的定理:
1. Log g,p (st mod p) = (log g,p s + log g,p t) mod (p - 1)
2. Log g,p (g ^r mod p) = r, 0 <= r <= p – 2

dlogRH(g, a p) {           // 求 log g,p a, a = g^x mod p,求 x          Sherwood算法

     r ← uniform(0..p-2);
    b ← ModularExponent(g, r, p);    //求幂模 b=g^r mod p,定理 1 真数的一部分
    c ← ba mod p;        //((g^r modp)(g^x modp))modp=g ^(r+x)modp=c, 定理 2 中的真数
    y ← log g,p c;            // 使用确定性算法求 log p,g c, y=r+x,定理 2

    return (y-r)mod(p-1);      //求x,定理1

}

在这里,唯一耗费时间的是 b ← ModularExponent(g, r, p),它的执行时间与a,p 的取值无关,只与随机取出的 r 有关


实现代码如下:

//编程计算离散对数
//定义:设 a=g^x mod p,记 log g,p a=x,称x为a的(以g为底模除p)对数。

#include
#include
#include
#include

int dlog(int g,int a,int p);  //求离散对数的确定性算法
int dlogRH(int g,int a,int p);//求a的(以g为底模除p)对数的Sherwood算法
int ModularExponent(int g,int r,int p); //求 g^r mod p

int main()
{
        int p,g,a,x;
        printf("计算离散对数的Sherwood算法\n");
        printf("要求x  输入a,g,p的值,a=g^x mod p\n");

        scanf("%d %d %d",&a,&g,&p);

        x = dlogRH(g,a,p);
        printf("求a的(以g为底模除p)对数x的值为 %d \n",x);

        return 0;
}

int dlog(int g,int a,int p)
{
        int x =0,y=1;
        do{
                x++;
                y = y*g;
          }while((a != y%p)&&(x != p));
        return x;
}
int dlogRH(int g,int a,int p)
{
        int r,y,c,b;
        int i = 0,j= p-2;

        srand((unsigned)time(NULL));
        r = rand()%(j-i+1)+i;

        b = ModularExponent(g,r,p);
        c = (a*b)%p;

        y = dlog(g,c,p);

        return (y-r)%(p-1);
}
int ModularExponent(int g,int r,int p)
{
        int y = 1;
        while(r--)
                y = y*g;
        return y%p;
}



你可能感兴趣的:(算法学习)