C 我能';我不明白这个霍纳';扩展域GF(p^n)中的s规则实现

C 我能';我不明白这个霍纳';扩展域GF(p^n)中的s规则实现,c,algorithm,math,gmp,C,Algorithm,Math,Gmp,我试图了解Shamir的秘密共享方案的实现,我正在与扩展域GF(p^n)中的Horner规则作斗争: 为什么add首先出现,然后才是mult?算法是什么?为什么不这样做呢: mpz_set(y,coeff[n-1]); for(i = n - 2; i!=-1; i--) { field_mult(y, y, x); field_add(y,y,coeff[i]); } 将这个horner函数与普通的加法和乘法符号进行转换,我们得到: y = x;

我试图了解Shamir的秘密共享方案的实现,我正在与扩展域GF(p^n)中的Horner规则作斗争:

为什么
add
首先出现,然后才是
mult
?算法是什么?为什么不这样做呢:

  mpz_set(y,coeff[n-1]);
  for(i = n - 2; i!=-1; i--) {
    field_mult(y, y, x);
    field_add(y,y,coeff[i]);
  }

将这个
horner
函数与普通的加法和乘法符号进行转换,我们得到:

y = x;                     // mpz_set(y, x);
for(i = n - 1; i; i--) {
    y = y + coeff[i];      // field_add(y, y, coeff[i]);
    y = y * x              // field_mult(y, y, x);
}
y = y + coeff[0]           // field_add(y, y, coeff[0]);
因此,这将计算以下内容:

您可以看到它不计算任何多项式,但它是Horner算法的一个变体,用于计算多项式

现在你的建议是:

y = coeff[n-1];               // mpz_set(y,coeff[n-1]);
for(i = n - 2; i!=-1; i--) {
    y = y * x;                // field_mult(y, y, x);
    y = y + coeff[i];         // field_add(y,y,coeff[i]);
}
因此,您可以计算以下内容:

您可以看到缺少最高阶项

如果希望所有操作都在循环体中,可以。 毕竟,对一系列交替指令进行不同分解只有两种方法:

operation    value of y                                    loop iteration
                                                 add-mult loop      mult-add loop
                x                               initialization         n-1
add       x + coeff[n-1]                             n-1               n-1
mult     (x + coeff[n-1]) * x                        n-1               n-2
add      (x + coeff[n-1]) * x + coeff[n-2]           n-2               n-2
mult    ((x + coeff[n-1]) * x + coeff[n-2]) * x      n-2               n-3
          ...etc...
但是您需要显式地将
y
初始化为值
1
(这是隐式的
coeff[n]
),这样您就可以开始乘以
x
,得到正确的最高阶项

y = 1;                        // mpz_set(y,1);
for(i = n - 1; i!=-1; i--) {  // NOTICE n - 1 NOT n - 2
    y = y * x;                // field_mult(y, y, x);
    y = y + coeff[i];         // field_add(y,y,coeff[i]);
}
您可以计算您现在执行了一次以上的乘法,并且它正在乘法
1*x
。在有限域上,这通常是通过log和antilog表来完成的,所以您最好避免这种无用的乘法,特别是如果您要对多项式进行大量求值的话


TL;DR:这种编写Horner算法的方法将最后一个加法和第一个乘法放在循环体之外。因为最高阶系数是
1
,所以此乘法将被完全删除。


澄清:保留最高阶项,但随后是
x^n
,而不是
1*x^n
。为了得到完全相同的结果,您可以使用一次乘法。

第二个变量缺少x^n项。主要问题:为什么在本例中使用()?“因为最高阶系数为1,所以此乘法将被完全删除。”如果删除,为什么在上面的公式中需要“x^n”?和系数1一样,它被去掉了?是我无法理解的。。。n=3:y=((1x+C[2])x+C[1])x+C[0]=x^3+C[2]x^2+C[1]x+C[0]。“x^3”发生了什么?谢谢。是的,明白了:mpz_集ui(y,1)而不是mpz_集(y,x),我的意思是:as:f(x)=a0+a1x+a2x2+…+akxk=a[k]x^k之和。x^n是从哪里来的?n=3:y=((x+C[2])x+C[1])x+C[0]=**x^3**+C[2]x^2+C[1]x+C[0]。x=2:*8**+4C[2]+2C[1]+C[0]不同的4C[2]+2C[1]+C[0]。您的表达式在一般情况下有效。在这个具体的实现中,您看到的是一个函数,它总是返回一个多项式,其中a[n]=1。很抱歉,我仍然无法理解为什么在这个实现中x^n没有系数c[n],即x^n+sum c[I]x^I,0..n-1而不是sum c[I]x^I 0..n。如果您看到这个函数,没有什么原因。为什么是这样写的?因为程序员需要。他为什么需要这个?好吧,你得问问他或者看看剩下的算法。但是现在,你知道这个函数到底做什么了。
y = 1;                        // mpz_set(y,1);
for(i = n - 1; i!=-1; i--) {  // NOTICE n - 1 NOT n - 2
    y = y * x;                // field_mult(y, y, x);
    y = y + coeff[i];         // field_add(y,y,coeff[i]);
}