package org.bouncycastle.math.ec;
import java.math.BigInteger;
public abstract class ECFieldElement
implements ECConstants
{
BigInteger x;
BigInteger p;
protected ECFieldElement(BigInteger q, BigInteger x)
{
if (x.compareTo(q) >= 0)
{
throw new IllegalArgumentException("x value too large in field element");
}
this.x = x;
this.p = q; // curve.getQ();
}
public BigInteger toBigInteger()
{
return x;
}
public boolean equals(Object other)
{
if ( other == this )
return true;
if ( !(other instanceof ECFieldElement) )
return false;
ECFieldElement o = (ECFieldElement)other;
return p.equals(o.p) && x.equals(o.x);
}
public abstract String getFieldName();
public abstract ECFieldElement add(ECFieldElement b);
public abstract ECFieldElement subtract(ECFieldElement b);
public abstract ECFieldElement multiply(ECFieldElement b);
public abstract ECFieldElement divide(ECFieldElement b);
public abstract ECFieldElement negate();
public abstract ECFieldElement square();
public abstract ECFieldElement invert();
public abstract ECFieldElement sqrt();
public static class Fp extends ECFieldElement
{
/**
* return the field name for this field.
*
* @return the string "Fp".
*/
public String getFieldName()
{
return "Fp";
}
public Fp(BigInteger q, BigInteger x)
{
super(q, x);
}
public ECFieldElement add(ECFieldElement b)
{
return new Fp(p, x.add(b.x).mod(p));
}
public ECFieldElement subtract(ECFieldElement b)
{
return new Fp(p, x.subtract(b.x).mod(p));
}
public ECFieldElement multiply(ECFieldElement b)
{
return new Fp(p, x.multiply(b.x).mod(p));
}
public ECFieldElement divide(ECFieldElement b)
{
return new Fp(p, x.multiply(b.x.modInverse(p)).mod(p));
}
public ECFieldElement negate()
{
return new Fp(p, x.negate().mod(p));
}
public ECFieldElement square()
{
return new Fp(p, x.multiply(x).mod(p));
}
public ECFieldElement invert()
{
return new Fp(p, x.modInverse(p));
}
// D.1.4 91
/**
* return a sqrt root - the routine verifies that the calculation
* returns the right value - if none exists it returns null.
*/
public ECFieldElement sqrt()
{
// p mod 4 == 3
if ( p.testBit(1) )
{
// z = g^(u+1) + p, p = 4u + 3
ECFieldElement z = new Fp(p, x.modPow(p.shiftRight(2).add(ONE), p));
return z.square().equals(this) ? z : null;
}
throw new RuntimeException("not done yet");
}
}
}