You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

118 lines
2.3 KiB

const bigInt = require("big-integer");
const assert = require("assert");
module.exports = class ZqField {
constructor(p) {
this.one = bigInt.one;
this.zero = bigInt.zero;
this.p = p;
this.bitLength = p.bitLength();
this.mask = bigInt.one.shiftLeft(this.bitLength - 1).minus(bigInt.one);
}
add(a, b) {
let res = a.add(b);
if (res.geq(this.p)) {
res = res.minus(this.p);
}
return res;
}
sub(a, b) {
if (a.geq(b)) {
return a.minus(b);
} else {
return this.p.minus(b.minus(a));
}
}
neg(a) {
if (a.isZero()) return a;
return this.p.minus(a);
}
mul(a, b) {
return a.times(b).mod(this.p);
}
lt(a, b) {
return a.lt(b) ? bigInt(1) : bigInt(0);
}
eq(a, b) {
return a.eq(b) ? bigInt(1) : bigInt(0);
}
gt(a, b) {
return a.gt(b) ? bigInt(1) : bigInt(0);
}
leq(a, b) {
return a.leq(b) ? bigInt(1) : bigInt(0);
}
geq(a, b) {
return a.geq(b) ? bigInt(1) : bigInt(0);
}
neq(a, b) {
return a.neq(b) ? bigInt(1) : bigInt(0);
}
div(a, b) {
assert(!b.isZero(), "Division by zero");
return a.times(b.modInv(this.p)).mod(this.p);
}
idiv(a, b) {
assert(!b.isZero(), "Division by zero");
return a.divide(b);
}
mod(a, b) {
return a.mod(b);
}
pow(a, b) {
return a.modPow(b, this.p);
}
band(a, b) {
return a.and(b).and(this.mask);
}
bor(a, b) {
return a.or(b).and(this.mask);
}
bxor(a, b) {
return a.xor(b).and(this.mask);
}
bnot(a) {
return a.xor(this.mask).and(this.mask);
}
shl(a, b) {
if (b.geq(this.bitLength)) return bigInt.zero;
return a.shiftLeft(b).and(this.mask);
}
shr(a, b) {
if (b.geq(this.bitLength)) return bigInt.zero;
return a.shiftRight(b).and(this.mask);
}
land(a, b) {
return (a.isZero() || b.isZero) ? bigInt.zero : bigInt.one;
}
lor(a, b) {
return (a.isZero() && b.isZero) ? bigInt.zero : bigInt.one;
}
lnot(a) {
return a.isZero() ? bigInt.one : bigInt.zero;
}
};