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