/** * Performs Karatsuba multiplication on two BigIntegers * * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}. * * @param Math_BigInteger $y * @return Math_BigInteger * @access private */ function _karatsuba($y) { $x = $this->copy(); $m = min(count($x->value) >> 1, count($y->value) >> 1); if ($m < MATH_BIGINTEGER_KARATSUBA_CUTOFF) { return $x->_multiply($y); } $x1 = new Math_BigInteger(); $x0 = new Math_BigInteger(); $y1 = new Math_BigInteger(); $y0 = new Math_BigInteger(); $x1->value = array_slice($x->value, $m); $x0->value = array_slice($x->value, 0, $m); $y1->value = array_slice($y->value, $m); $y0->value = array_slice($y->value, 0, $m); $z2 = $x1->_karatsuba($y1); $z0 = $x0->_karatsuba($y0); $z1 = $x1->add($x0); $z1 = $z1->_karatsuba($y1->add($y0)); $z1 = $z1->subtract($z2->add($z0)); $z2->value = array_merge(array_fill(0, 2 * $m, 0), $z2->value); $z1->value = array_merge(array_fill(0, $m, 0), $z1->value); $xy = $z2->add($z1); $xy = $xy->add($z0); return $xy; }