public int sign() { if (isZero()) return 0; if (field.isOrderOdd()) { return BigIntegerUtils.isOdd(value) ? 1 : -1; } else { return value.add(value).compareTo(field.order); } }
public ZrElement sqrt() { // Apply the Tonelli-Shanks Algorithm Element e0 = field.newElement(); Element nqr = field.getNqr(); Element gInv = nqr.duplicate().invert(); // let q be the field.order of the field // q - 1 = 2^s t, for some t odd BigInteger t = field.order.subtract(BigInteger.ONE); int s = BigIntegerUtils.scanOne(t, 0); t = t.divide(BigInteger.valueOf(2 << (s - 1))); BigInteger e = BigInteger.ZERO; BigInteger orderMinusOne = field.order.subtract(BigInteger.ONE); for (int i = 2; i <= s; i++) { e0.set(gInv).pow(e); e0.mul(this).pow(orderMinusOne.divide(BigInteger.valueOf(2 << (i - 1)))); if (!e0.isOne()) e = e.setBit(i - 1); } e0.set(gInv).pow(e); e0.mul(this); t = t.add(BigInteger.ONE); t = t.divide(BigIntegerUtils.TWO); e = e.divide(BigIntegerUtils.TWO); // TODO(-): // (suggested by Hovav Shacham) replace next three lines with // element_pow2_mpz(x, e0, t, nqr, e); // once sliding windows are implemented for pow2 e0.pow(t); set(nqr).pow(e).mul(e0); return this; }
public ZrElement setToRandom() { this.value = BigIntegerUtils.getRandom(field.order, field.getRandom()); return this; }
public boolean isSqr() { return BigInteger.ZERO.equals(value) || BigIntegerUtils.legendre(value, field.order) == 1; }