Any finite field Z p \mathbb{Z}_pWITHp, The generator is (p − 1) (p-1)(p−1 ) -th root of unity, the corresponding sagemath script is: [anyxxwithin a limited domainx , itsxp − 1 ≡ 1 mod px^{p-1}\equiv 1\mod pxp−1≡1modp Heng was established. 】
generator = primitive_root(p)
When the finite field Z p \mathbb{Z}_pWITHpWhen used in polynomial calculation, if the finite field Z p \mathbb{Z}_pWITHpIf it is FFT friendly, you can use (I)FFT to speed up polynomial operations, which requires ppp satisfies:
factor(p-1) = 2^s * t
Where 2 s 2^s2The s value represents the highest order of the polynomial allowed.
Corresponding2 s 2^s2The calculation method of s -th root of unity is:
power_mod(generator, t, p)
For curve25519, the s value of the Fr field is only 2 and the generator does not return (whether based on magma or sagemath), so it is not an FFT friendly field. If you want to use it for polynomial operations, you cannot use FFT for acceleration . Therefore, in the actual selection, curve25519 is generally not used to express polynomial commitment and so on.
In Lagrange polynomial sage and rust code implementation , there are:
/*
Lagrange interpolation polynomials in our evaluation domain:
,-------------------------------. ,-------------------------------. ,-------------------------------.
| A TERM | | B TERM | | C TERM |
`-------------------------------. `-------------------------------' `-------------------------------'
| a_0 | a_1 | a_2 | a_3 | | a_0 | a_1 | a_2 | a_3 | | a_0 | a_1 | a_2 | a_3 |
| 1 | 0 | 64512 | 0 | | 0 | 0 | 1 | 0 | | 0 | 0 | 0 | 0 |
| 1 | 0 | 0 | 64512 | | 0 | 0 | 0 | 1 | | 0 | 0 | 0 | 0 |
| 0 | 0 | 2 | 0 | | 0 | 0 | 0 | 1 | | 0 | 64512 | 1 | 1 |
| 1 | 0 | 0 | 0 | | 0 | 0 | 0 | 0 | | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 0 | | 0 | 0 | 0 | 0 | | 0 | 0 | 0 | 0 |
`-------'-------'-------'-------' `-------'-------'-------'-------' `-------'-------'-------'-------'
Example for u_0:
sage: r = 64513
sage: Fr = GF(r)
sage: omega = (Fr(5)^63)^(2^7)
sage: tau = Fr(3673)
sage: R.<x> = PolynomialRing(Fr, 'x')
sage: def eval(tau, c0, c1, c2, c3, c4):
....: p = R.lagrange_polynomial([(omega^0, c0), (omega^1, c1), (omega^2, c2), (omega^3, c3), (omega^4, c4), (omega^5, 0), (omega^6, 0), (omega^7, 0)])
....: return p.substitute(tau)
sage: eval(tau, 1, 1, 0, 1, 0)
59158
sage: eval(tau, 0,0,0,0,1)
48317
sage: omega^8 //n=2^3=8,插值点为:w_{n}^{0},\cdots, w_{n}^{n-1}
1
*/
Reference materials:
[1] Fast Fourier (inverse) transform algorithm (I)FFT in Halo
[2] FFT rust code implementation
[3] Lagrange polynomial sage and rust code implementation
[4] curve25519 torsion points