1<?php 2 3/** 4 * Prime Finite Fields 5 * 6 * Utilizes the factory design pattern 7 * 8 * PHP version 5 and 7 9 * 10 * @category Math 11 * @package BigInteger 12 * @author Jim Wigginton <terrafrost@php.net> 13 * @copyright 2017 Jim Wigginton 14 * @license http://www.opensource.org/licenses/mit-license.html MIT License 15 * @link http://pear.php.net/package/Math_BigInteger 16 */ 17 18namespace phpseclib3\Math; 19 20use phpseclib3\Math\Common\FiniteField; 21use phpseclib3\Math\PrimeField\Integer; 22 23/** 24 * Prime Finite Fields 25 * 26 * @package Math 27 * @author Jim Wigginton <terrafrost@php.net> 28 * @access public 29 */ 30class PrimeField extends FiniteField 31{ 32 /** 33 * Instance Counter 34 * 35 * @var int 36 */ 37 private static $instanceCounter = 0; 38 39 /** 40 * Keeps track of current instance 41 * 42 * @var int 43 */ 44 protected $instanceID; 45 46 /** 47 * Default constructor 48 */ 49 public function __construct(BigInteger $modulo) 50 { 51 //if (!$modulo->isPrime()) { 52 // throw new \UnexpectedValueException('PrimeField requires a prime number be passed to the constructor'); 53 //} 54 55 $this->modulo = $modulo; 56 57 $this->instanceID = self::$instanceCounter++; 58 Integer::setModulo($this->instanceID, $modulo); 59 Integer::setRecurringModuloFunction($this->instanceID, $modulo->createRecurringModuloFunction()); 60 } 61 62 /** 63 * Use a custom defined modular reduction function 64 * 65 * @return void 66 */ 67 public function setReduction(\Closure $func) 68 { 69 $this->reduce = $func->bindTo($this, $this); 70 } 71 72 /** 73 * Returns an instance of a dynamically generated PrimeFieldInteger class 74 * 75 * @return Integer 76 */ 77 public function newInteger(BigInteger $num) 78 { 79 return new Integer($this->instanceID, $num); 80 } 81 82 /** 83 * Returns an integer on the finite field between one and the prime modulo 84 * 85 * @return Integer 86 */ 87 public function randomInteger() 88 { 89 static $one; 90 if (!isset($one)) { 91 $one = new BigInteger(1); 92 } 93 94 return new Integer($this->instanceID, BigInteger::randomRange($one, Integer::getModulo($this->instanceID))); 95 } 96 97 /** 98 * Returns the length of the modulo in bytes 99 * 100 * @return int 101 */ 102 public function getLengthInBytes() 103 { 104 return Integer::getModulo($this->instanceID)->getLengthInBytes(); 105 } 106 107 /** 108 * Returns the length of the modulo in bits 109 * 110 * @return int 111 */ 112 public function getLength() 113 { 114 return Integer::getModulo($this->instanceID)->getLength(); 115 } 116 117 /** 118 * Destructor 119 */ 120 public function __destruct() 121 { 122 Integer::cleanupCache($this->instanceID); 123 } 124} 125