runEuclideanAlgorithm(a, b, R) {
			// Assume a's degree is >= b's
			if (a.getDegree() < b.getDegree()) {
				let temp = a;
				a = b;
				b = temp;
			}
			let rLast = a;
			let r = b;
			let tLast = this.field.getZero();
			let t = this.field.getOne();
			// Run Euclidean algorithm until r's degree is less than R/2
			while (r.getDegree() >= Math.round(R / 2)) {
				let rLastLast = rLast;
				let tLastLast = tLast;
				rLast = r;
				tLast = t;
				// Divide rLastLast by rLast, with quotient in q and remainder in r
				if (rLast.isZero()) {
					// Oops, Euclidean algorithm already terminated?
					throw ChecksumException.getChecksumInstance();
				}
				r = rLastLast;
				let q = this.field.getZero();
				let denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree());
				let dltInverse = this.field.inverse(denominatorLeadingTerm);
				while (r.getDegree() >= rLast.getDegree() && !r.isZero()) {
					let degreeDiff = r.getDegree() - rLast.getDegree();
					let scale = this.field.multiply(r.getCoefficient(r.getDegree()), dltInverse);
					q = q.add(this.field.buildMonomial(degreeDiff, scale));
					r = r.subtract(rLast.multiplyByMonomial(degreeDiff, scale));
				}
				t = q.multiply(tLast).subtract(tLastLast).negative();
			}
			let sigmaTildeAtZero = t.getCoefficient(0);
			if (sigmaTildeAtZero === 0) {
				throw ChecksumException.getChecksumInstance();
			}
			let inverse = this.field.inverse(sigmaTildeAtZero);
			let sigma = t.multiply(inverse);
			let omega = r.multiply(inverse);
			return [sigma, omega];
		}
@param ModulusPoly
@param a
@param ModulusPoly
@param b
@param int
@param R
@throws ChecksumException