sqrtRatioGeneric<F extends CryptoField<F> > static method
FieldSqrtResult<F>
sqrtRatioGeneric<F extends CryptoField<F> >({
- required F num,
- required F div,
- required F zero,
- required F rootOfUnity,
Implementation
static FieldSqrtResult<F> sqrtRatioGeneric<F extends CryptoField<F>>({
required F num,
required F div,
required F zero,
required F rootOfUnity,
}) {
// a = num * inv0(div)
// inv0(div) = 0 if div == 0
F a;
final F? inv = div.invert();
if (inv == null) {
a = zero;
} else {
a = inv * num;
}
// b = a * ROOT_OF_UNITY
final F b = a * rootOfUnity;
// sqrt candidates
final sqrtA = a.sqrt(); // returns null if a is nonsquare
final sqrtB = b.sqrt(); // returns null if b is nonsquare
final bool numIsZero = num.isZero();
final bool divIsZero = div.isZero();
final bool isSquare = sqrtA.isSquare;
final bool isNonSquare = sqrtB.isSquare;
// Safety check from Rust:
// num == 0 OR div == 0 OR exactly one of a,b is square.
assert(numIsZero || divIsZero || (isSquare != isNonSquare));
// Boolean condition:
// is_square & (num_is_zero || !div_is_zero)
final bool resultIsSquare = isSquare && (numIsZero || !divIsZero);
// Pick sqrt: if a is square, pick sqrtA, else pick sqrtB
final F chosen = isSquare ? sqrtA.result : sqrtB.result;
return FieldSqrtResult(chosen, resultIsSquare);
}