Thanks, Ron,
I've found that, at least for the 521-bit NIST curve, which is what I'm using in ECC, there is a very easy way to extract the square root, based on the Tonelli-Shanks algorithm, which has a trivial case when the prime field mod 8 is 7.
if y2 is the square of y and p is the prime number on which the curve is based, the square root is:
y = (y2)^ ((p+1)/4) mod p
in SJCL, I can implement this as:
curve = sjcl.ecc.curves['c521']
p = curve.field.modulus //13th Mersenne prime = 2^521 -1, as a bn object
q = "8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
q = sjcl.bn.fromBits(sjcl.codec.hex.toBits(q)) //I wish there was an easy way to do (p+1)/4
//let's say y2 is obtained this way:
y2 = y.square() //where y is an object containing the y coordinate, then
y2sqrt = y2.powermod(q,p)
//returns an object containing the same data as the original y.
The problem is that the powermod operation is very slow, even slower than the regular ecc public key derivation.
I've taken a look at the Bernstein program, but the algorithm looks so different from those in the current ecc.js that I'm afraid I'd have to rebuild everything. Plus it's for a different curve and it's not obvious to me how to adapt it for the 521-bit NIST curve.
Is there a faster version of powermod? If I were to use the Bernstein code, how would I implement the 521-bit curve?
Many thanks!