You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
funcsqrt_invsqrt_tonelli_shanks[C](
sqrt, invsqrt: varFp[C],
a, a_pre_exp: Fp[C]) =## Compute the square_root and inverse_square_root## of `a` via constant-time Tonelli-Shanks#### a_pre_exp is a precomputation a^((p-1-2^e)/(2*2^e))templatez: untyped= a_pre_exp
templater: untyped= invsqrt
var t {.noInit.}: Fp[C]
const e = C.tonelliShanks(twoAdicity)
t.square(z)
t *= a
r = z
var b = t
var root = C.tonelliShanks(root_of_unity)
var buf {.noInit.}: Fp[C]
for i incountdown(e, 2, 1):
for j in1.. i-2:
b.square()
let bNotOne =not b.isOne()
buf.prod(r, root)
r.ccopy(buf, bNotOne)
root.square()
buf.prod(t, root)
t.ccopy(buf, bNotOne)
b = t
sqrt.prod(invsqrt, a)
defsqrt_inv_sqrt_tonelli_shanks_impl(a, a_pre_exp, s, e, root_of_unity):
## Square root and inverse square root for any `a` in a field of prime characteristic p#### a_pre_exp = a^((q-1-2^e)/(2*2^e))## with## s and e, precomputed values## such as q == s * 2^e + 1# Implementation# 1/√a * a = √a# Notice that in Tonelli Shanks, the result `r` is bootstrapped by "z*a"# We bootstrap it instead by just z to get invsqrt for freez=a_pre_expt=z*z*ar=zb=troot=root_of_unityforiinrange(e, 1, -1): # e .. 2forjinrange(1, i-1): # 1 .. i-2b*=bdoCopy=b!=1r=ccopy(r, r*root, doCopy)
root*=roott=ccopy(t, t*root, doCopy)
b=treturnr*a, r
The text was updated successfully, but these errors were encountered:
That's very neat! In fact I wasn't computing the sqrt and the inverse completely separately, as they both share the same "hint" value which does most of the heavy lifting. But what you suggest would be even faster.
I've noticed that you integrated hash-to-G2 from the H2C draft and are computing sqrt and invsqrt in a separate manner here:
core/c/fp2.c
Lines 456 to 458 in bed0047
Instead you can compute sqrt and invsqrt in a fused manner by modifying your Tonelli Shanks algorithm by not multiplying Line 799
core/c/fp.c
Lines 782 to 817 in bed0047
Then r will hold invsqrt(a) at the end of the Tonelli Shanks, and you can multiply that by a and return both sqrt and invsqrt in a fused manner.
My own implementation (in Nim):
https://github.com/mratsim/constantine/blob/0effd66d/constantine/arithmetic/finite_fields_square_root.nim#L147-L180
Sage script for BLS12-377
https://github.com/mratsim/constantine/blob/0effd66d/sage/square_root_bls12_377.sage
The text was updated successfully, but these errors were encountered: