implement packet compression, implement player controller, implement join server authentication, add cobblestone, implement chunk provider, implement block position, implement session, implement movement, chunk, chat and block update packets, version 1.1.5
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
// https://github.com/juanelas/bigint-mod-arith
|
||||
|
||||
window["bigint-mod-arith"] = function () {
|
||||
/**
|
||||
* Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0
|
||||
*
|
||||
* @param a
|
||||
*
|
||||
* @returns The absolute value of a
|
||||
*/
|
||||
function abs(a) {
|
||||
return (a >= 0) ? a : -a;
|
||||
}
|
||||
|
||||
/**
|
||||
* An iterative implementation of the extended euclidean algorithm or extended greatest common divisor algorithm.
|
||||
* Take positive integers a, b as input, and return a triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
*
|
||||
* @param a
|
||||
* @param b
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* This excepction is thrown if a or b are less than 0
|
||||
*
|
||||
* @returns A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
*/
|
||||
function eGcd(a, b) {
|
||||
if (typeof a === 'number')
|
||||
a = BigInt(a);
|
||||
if (typeof b === 'number')
|
||||
b = BigInt(b);
|
||||
if (a <= 0n || b <= 0n)
|
||||
throw new RangeError('a and b MUST be > 0'); // a and b MUST be positive
|
||||
let x = 0n;
|
||||
let y = 1n;
|
||||
let u = 1n;
|
||||
let v = 0n;
|
||||
while (a !== 0n) {
|
||||
const q = b / a;
|
||||
const r = b % a;
|
||||
const m = x - (u * q);
|
||||
const n = y - (v * q);
|
||||
b = a;
|
||||
a = r;
|
||||
x = u;
|
||||
y = v;
|
||||
u = m;
|
||||
v = n;
|
||||
}
|
||||
return {
|
||||
g: b,
|
||||
x: x,
|
||||
y: y
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the smallest positive element that is congruent to a in modulo n
|
||||
*
|
||||
* @remarks
|
||||
* a and b must be the same type, either number or bigint
|
||||
*
|
||||
* @param a - An integer
|
||||
* @param n - The modulo
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* Excpeption thrown when n is not > 0
|
||||
*
|
||||
* @returns A bigint with the smallest positive representation of a modulo n
|
||||
*/
|
||||
function toZn(a, n) {
|
||||
if (typeof a === 'number')
|
||||
a = BigInt(a);
|
||||
if (typeof n === 'number')
|
||||
n = BigInt(n);
|
||||
if (n <= 0n) {
|
||||
throw new RangeError('n must be > 0');
|
||||
}
|
||||
const aZn = a % n;
|
||||
return (aZn < 0n) ? aZn + n : aZn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular inverse.
|
||||
*
|
||||
* @param a The number to find an inverse for
|
||||
* @param n The modulo
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* Excpeption thorwn when a does not have inverse modulo n
|
||||
*
|
||||
* @returns The inverse modulo n
|
||||
*/
|
||||
function modInv(a, n) {
|
||||
const egcd = eGcd(toZn(a, n), n);
|
||||
if (egcd.g !== 1n) {
|
||||
throw new RangeError(`${a.toString()} does not have inverse modulo ${n.toString()}`); // modular inverse does not exist
|
||||
} else {
|
||||
return toZn(egcd.x, n);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular exponentiation b**e mod n. Currently using the right-to-left binary method
|
||||
*
|
||||
* @param b base
|
||||
* @param e exponent
|
||||
* @param n modulo
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* Excpeption thrown when n is not > 0
|
||||
*
|
||||
* @returns b**e mod n
|
||||
*/
|
||||
function modPow(b, e, n) {
|
||||
if (typeof b === 'number')
|
||||
b = BigInt(b);
|
||||
if (typeof e === 'number')
|
||||
e = BigInt(e);
|
||||
if (typeof n === 'number')
|
||||
n = BigInt(n);
|
||||
if (n <= 0n) {
|
||||
throw new RangeError('n must be > 0');
|
||||
} else if (n === 1n) {
|
||||
return 0n;
|
||||
}
|
||||
b = toZn(b, n);
|
||||
if (e < 0n) {
|
||||
return modInv(modPow(b, abs(e), n), n);
|
||||
}
|
||||
let r = 1n;
|
||||
while (e > 0) {
|
||||
if ((e % 2n) === 1n) {
|
||||
r = r * b % n;
|
||||
}
|
||||
e = e / 2n;
|
||||
b = b ** 2n % n;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
function bytesToBigInt(bytes) {
|
||||
return BigInt("0x" + Array.from(bytes, byte => {
|
||||
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
|
||||
}).join(''));
|
||||
}
|
||||
|
||||
function bigIntToBytes(bigInt) {
|
||||
let hex = bigInt.toString(16);
|
||||
|
||||
// Convert hex to bytes
|
||||
let bytes = [];
|
||||
for (let c = 0; c < hex.length; c += 2) {
|
||||
bytes.push(parseInt(hex.substr(c, 2), 16));
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
return {bigIntToBytes, bytesToBigInt, modPow};
|
||||
}();
|
||||
Reference in New Issue
Block a user