1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
/**
* EdDSA-Java by str4d
*
* To the extent possible under law, the person who associated CC0 with
* EdDSA-Java has waived all copyright and related or neighboring rights
* to EdDSA-Java.
*
* You should have received a copy of the CC0 legalcode along with this
* work. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package net.i2p.crypto.eddsa.math.bigint;
import java.io.Serializable;
import java.math.BigInteger;
import net.i2p.crypto.eddsa.math.Field;
import net.i2p.crypto.eddsa.math.FieldElement;
/**
* A particular element of the field \Z/(2^255-19).
* @author str4d
*
*/
public class BigIntegerFieldElement extends FieldElement implements Serializable {
private static final long serialVersionUID = 4890398908392808L;
/**
* Variable is package private for encoding.
*/
final BigInteger bi;
public BigIntegerFieldElement(Field f, BigInteger bi) {
super(f);
this.bi = bi;
}
public boolean isNonZero() {
return !bi.equals(BigInteger.ZERO);
}
public FieldElement add(FieldElement val) {
return new BigIntegerFieldElement(f, bi.add(((BigIntegerFieldElement)val).bi)).mod(f.getQ());
}
@Override
public FieldElement addOne() {
return new BigIntegerFieldElement(f, bi.add(BigInteger.ONE)).mod(f.getQ());
}
public FieldElement subtract(FieldElement val) {
return new BigIntegerFieldElement(f, bi.subtract(((BigIntegerFieldElement)val).bi)).mod(f.getQ());
}
@Override
public FieldElement subtractOne() {
return new BigIntegerFieldElement(f, bi.subtract(BigInteger.ONE)).mod(f.getQ());
}
public FieldElement negate() {
return f.getQ().subtract(this);
}
@Override
public FieldElement divide(FieldElement val) {
return divide(((BigIntegerFieldElement)val).bi);
}
public FieldElement divide(BigInteger val) {
return new BigIntegerFieldElement(f, bi.divide(val)).mod(f.getQ());
}
public FieldElement multiply(FieldElement val) {
return new BigIntegerFieldElement(f, bi.multiply(((BigIntegerFieldElement)val).bi)).mod(f.getQ());
}
public FieldElement square() {
return multiply(this);
}
public FieldElement squareAndDouble() {
FieldElement sq = square();
return sq.add(sq);
}
public FieldElement invert() {
// Euler's theorem
//return modPow(f.getQm2(), f.getQ());
return new BigIntegerFieldElement(f, bi.modInverse(((BigIntegerFieldElement)f.getQ()).bi));
}
public FieldElement mod(FieldElement m) {
return new BigIntegerFieldElement(f, bi.mod(((BigIntegerFieldElement)m).bi));
}
public FieldElement modPow(FieldElement e, FieldElement m) {
return new BigIntegerFieldElement(f, bi.modPow(((BigIntegerFieldElement)e).bi, ((BigIntegerFieldElement)m).bi));
}
public FieldElement pow(FieldElement e){
return modPow(e, f.getQ());
}
public FieldElement pow22523(){
return pow(f.getQm5d8());
}
@Override
public FieldElement cmov(FieldElement val, int b) {
// Not constant-time, but it doesn't really matter because none of the underlying BigInteger operations
// are either, so there's not much point in trying hard here ...
return b == 0 ? this : val;
}
@Override
public int hashCode() {
return bi.hashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof BigIntegerFieldElement))
return false;
BigIntegerFieldElement fe = (BigIntegerFieldElement) obj;
return bi.equals(fe.bi);
}
@Override
public String toString() {
return "[BigIntegerFieldElement val="+bi+"]";
}
}
|