1.实验内容
我们谈谈以下几个基本概念。
1.原根
原根是一种数学符号,设m是正整数,a是整数,若a模m的阶等于φ(m),则称a为模m的一个原根。(其中φ(m)表示m的欧拉函数)
假设一个数g是P的原根,那么g^i mod P的结果两两不同,且有 1
2.群
基本概念可以看这里。群环域
- 上图思路是老师给出的思路,我自己实现了下,我跑了两个小时,跑了两个小时跑不出来结果,最后系统崩溃。
/*
* create hash table
*/
void createSearchTable(unordered_map& searchTable,const mpz_class& h,const mpz_class& g,const mpz_class& p )
{
int x_max = pow(2,20);
mpz_class g_x1 = 1;
mpz_class hDivGx_1 = h;
for(int x_1 = 0;x_1& searchTable,const mpz_class& g,const mpz_class& p,int & result_x_1, int& result_x_0){
mpz_class result("0",10);
int x_0;
int x_max = pow(2,20);
//计算g**B
mpz_class gB = 1;
for(int i = 0; i < x_max; i++) {
gB = gB *g%p;
}
mpz_class gbx = 1;
for(int x_0 =0;x_0second + x_0*pow(2,20);
result_x_1 = it->second;
result_x_0 = x_0;
break;
}
}
return result;
}
2.转换思路
我测试了下计算时间主要用于$g^{x1}$的逆元就算,主要在这一步代码
hDivGx_1 = h/g_x1 % p;
g_x1 =g_x1*g;
我记得在《区块链》这门课上好像讲到过这个内容,后面我查了下资料,发现这里面是存在小技巧的。
上图给的思路是
\[x = x0B + x1 其中B =2^{20} 0\leq x0,x1\leq 2^{20}-1 \]
当两边同时除以x1时候,需要求\(g^{x1}\)的逆元\(g^{-x1}\),
那么就需要重新思考这个问题。我们假设 \(x = x0B - x1 其中B =2^{20} 0\leq x1\leq 2^{20}-1 0\leq x0\leq 2^{20}+1\),这时候式子就变成了了.
\[h*g^{x1} = g^{x0*B} \]
这时候就不需要求逆元了。
那么我们重新更换代码吧。
/*
* create hash table
*/
void createSearchTable(unordered_map& searchTable,const mpz_class& h,const mpz_class& g,const mpz_class& p )
{
int x_max = pow(2,20);
mpz_class g_x1 = 1;
mpz_class hDivGx_1 = h;
for(int x_1 = 0;x_1& searchTable,const mpz_class& g,const mpz_class& p,int & result_x_1, int& result_x_0){
mpz_class result("0",10);
int x_0;
int x_max = pow(2,20);
//计算g**B
mpz_class gB = 1;
for(int i = 0; i < x_max; i++) {
gB = gB *g%p;
}
mpz_class gbx = 1;
for(int x_0 =0;x_0second;
result_x_1 = it->second;
result_x_0 = x_0;
break;
}
gbx = gbx * gB %p;
}
return result;
}