- Timestamp:
- 05/17/2019 10:57:19 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/sodium_compat/src/Core32/Int32.php
r44953 r45344 152 152 153 153 /** 154 * @param array<int, int> $a 155 * @param array<int, int> $b 156 * @param int $baseLog2 157 * @return array<int, int> 158 */ 159 public function multiplyLong(array $a, array $b, $baseLog2 = 16) 160 { 161 $a_l = count($a); 162 $b_l = count($b); 163 /** @var array<int, int> $r */ 164 $r = array_fill(0, $a_l + $b_l + 1, 0); 165 $base = 1 << $baseLog2; 166 for ($i = 0; $i < $a_l; ++$i) { 167 $a_i = $a[$i]; 168 for ($j = 0; $j < $a_l; ++$j) { 169 $b_j = $b[$j]; 170 $product = ($a_i * $b_j) + $r[$i + $j]; 171 $carry = ($product >> $baseLog2 & 0xffff); 172 $r[$i + $j] = ($product - (int) ($carry * $base)) & 0xffff; 173 $r[$i + $j + 1] += $carry; 174 } 175 } 176 return array_slice($r, 0, 5); 177 } 178 179 /** 180 * @param int $int 181 * @return ParagonIE_Sodium_Core32_Int32 182 */ 183 public function mulIntFast($int) 184 { 185 // Handle negative numbers 186 $aNeg = ($this->limbs[0] >> 15) & 1; 187 $bNeg = ($int >> 31) & 1; 188 $a = array_reverse($this->limbs); 189 $b = array( 190 $int & 0xffff, 191 ($int >> 16) & 0xffff 192 ); 193 if ($aNeg) { 194 for ($i = 0; $i < 2; ++$i) { 195 $a[$i] = ($a[$i] ^ 0xffff) & 0xffff; 196 } 197 ++$a[0]; 198 } 199 if ($bNeg) { 200 for ($i = 0; $i < 2; ++$i) { 201 $b[$i] = ($b[$i] ^ 0xffff) & 0xffff; 202 } 203 ++$b[0]; 204 } 205 // Multiply 206 $res = $this->multiplyLong($a, $b); 207 208 // Re-apply negation to results 209 if ($aNeg !== $bNeg) { 210 for ($i = 0; $i < 2; ++$i) { 211 $res[$i] = (0xffff ^ $res[$i]) & 0xffff; 212 } 213 // Handle integer overflow 214 $c = 1; 215 for ($i = 0; $i < 2; ++$i) { 216 $res[$i] += $c; 217 $c = $res[$i] >> 16; 218 $res[$i] &= 0xffff; 219 } 220 } 221 222 // Return our values 223 $return = new ParagonIE_Sodium_Core32_Int32(); 224 $return->limbs = array( 225 $res[1] & 0xffff, 226 $res[0] & 0xffff 227 ); 228 if (count($res) > 2) { 229 $return->overflow = $res[2] & 0xffff; 230 } 231 $return->unsignedInt = $this->unsignedInt; 232 return $return; 233 } 234 235 /** 236 * @param ParagonIE_Sodium_Core32_Int32 $right 237 * @return ParagonIE_Sodium_Core32_Int32 238 */ 239 public function mulInt32Fast(ParagonIE_Sodium_Core32_Int32 $right) 240 { 241 $aNeg = ($this->limbs[0] >> 15) & 1; 242 $bNeg = ($right->limbs[0] >> 15) & 1; 243 244 $a = array_reverse($this->limbs); 245 $b = array_reverse($right->limbs); 246 if ($aNeg) { 247 for ($i = 0; $i < 2; ++$i) { 248 $a[$i] = ($a[$i] ^ 0xffff) & 0xffff; 249 } 250 ++$a[0]; 251 } 252 if ($bNeg) { 253 for ($i = 0; $i < 2; ++$i) { 254 $b[$i] = ($b[$i] ^ 0xffff) & 0xffff; 255 } 256 ++$b[0]; 257 } 258 $res = $this->multiplyLong($a, $b); 259 if ($aNeg !== $bNeg) { 260 if ($aNeg !== $bNeg) { 261 for ($i = 0; $i < 2; ++$i) { 262 $res[$i] = ($res[$i] ^ 0xffff) & 0xffff; 263 } 264 $c = 1; 265 for ($i = 0; $i < 2; ++$i) { 266 $res[$i] += $c; 267 $c = $res[$i] >> 16; 268 $res[$i] &= 0xffff; 269 } 270 } 271 } 272 $return = new ParagonIE_Sodium_Core32_Int32(); 273 $return->limbs = array( 274 $res[1] & 0xffff, 275 $res[0] & 0xffff 276 ); 277 if (count($res) > 2) { 278 $return->overflow = $res[2]; 279 } 280 return $return; 281 } 282 283 /** 154 284 * @param int $int 155 285 * @param int $size … … 162 292 ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1); 163 293 ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2); 294 if (ParagonIE_Sodium_Compat::$fastMult) { 295 return $this->mulIntFast((int) $int); 296 } 164 297 /** @var int $int */ 165 298 $int = (int) $int; … … 219 352 { 220 353 ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2); 354 if (ParagonIE_Sodium_Compat::$fastMult) { 355 return $this->mulInt32Fast($int); 356 } 221 357 if (!$size) { 222 358 $size = 31; … … 492 628 return $this->shiftLeft(-$c); 493 629 } else { 494 if ( is_null($c)) {630 if (!is_int($c)) { 495 631 throw new TypeError(); 496 632 }
Note: See TracChangeset
for help on using the changeset viewer.