pssht  latest
SSH server library written in PHP
ED25519.php
1 <?php
2 
3 /*
4 * This file is part of pssht.
5 *
6 * (c) François Poirotte <clicky@erebot.net>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11 
12 namespace fpoirotte\Pssht\ECC;
13 
21 class ED25519
22 {
24  protected static $instance = null;
25 
27  protected $params = array();
28 
29  protected function __construct()
30  {
31  $this->params['q'] = gmp_sub(gmp_pow(2, 255), 19);
32  $this->params['l'] = gmp_add(gmp_pow(2, 252), '27742317777372353535851937790883648493');
33  $this->params['d'] = gmp_mul(-121665, $this->inv(121666));
34  $this->params['I'] = gmp_powm(
35  2,
36  gmp_div_q(gmp_sub($this->params['q'], 1), 4),
37  $this->params['q']
38  );
39  $By = gmp_mul(4, $this->inv(5));
40  $Bx = $this->xrecover($By);
41  $this->params['B'] = array($Bx, $By);
42  }
43 
44  public static function getInstance()
45  {
46  if (self::$instance === null) {
47  self::$instance = new static();
48  }
49  return self::$instance;
50  }
51 
52  public function __get($name)
53  {
54  return $this->params[$name];
55  }
56 
57  public function __isset($name)
58  {
59  return isset($this->params[$name]);
60  }
61 
62  protected function inv($x)
63  {
64  return gmp_powm($x, gmp_sub($this->params['q'], 2), $this->params['q']);
65  }
66 
67  public function xrecover($y)
68  {
69  $xx = gmp_mul(
70  gmp_sub(gmp_mul($y, $y), 1),
71  $this->inv(gmp_add(gmp_mul(gmp_mul($this->params['d'], $y), $y), 1))
72  );
73  $x = gmp_powm($xx, gmp_div_q(gmp_add($this->params['q'], 3), 8), $this->params['q']);
74  $t = gmp_mod(gmp_sub(gmp_mul($x, $x), $xx), $this->params['q']);
75  if (gmp_cmp($t, 0)) {
76  $x = gmp_mod(gmp_mul($x, $this->params['I']), $this->params['q']);
77  }
78  if (gmp_cmp(gmp_mod($x, 2), 0)) {
79  $x = gmp_sub($this->params['q'], $x);
80  }
81  return $x;
82  }
83 
84  public function edwards($P, $Q)
85  {
86  $x1 = $P[0];
87  $y1 = $P[1];
88  $x2 = $Q[0];
89  $y2 = $Q[1];
90  $t = gmp_mul(
91  $this->params['d'],
92  gmp_mul(
93  gmp_mul($x1, $x2),
94  gmp_mul($y1, $y2)
95  )
96  );
97 
98  $x3 = gmp_mul(
99  gmp_add(gmp_mul($x1, $y2), gmp_mul($x2, $y1)),
100  $this->inv(gmp_add(1, $t))
101  );
102  $y3 = gmp_mul(
103  gmp_add(gmp_mul($y1, $y2), gmp_mul($x1, $x2)),
104  $this->inv(gmp_sub(1, $t))
105  );
106 
107  return array(
108  gmp_mod($x3, $this->params['q']),
109  gmp_mod($y3, $this->params['q'])
110  );
111  }
112 
113  public function scalarmult($P, $e)
114  {
115  if (!is_array($P)) {
116  throw new \InvalidArgumentException();
117  }
118 
119  foreach (array($P[0], $P[1], $e) as $t) {
120  if (!((is_resource($t) && get_resource_type($t) === 'GMP integer') ||
121  (is_object($t) && ($t instanceof \GMP)))) {
122  throw new \InvalidArgumentException();
123  }
124  }
125 
126  $s = gmp_strval($e, 2);
127  $len = strlen($s);
128  $res = array(gmp_init(0), gmp_init(1));
129 
130  for ($i = 0; $i < $len; $i++) {
131  $res = $this->edwards($res, $res);
132  if ($s[$i] === '1') {
133  $res = $this->edwards($res, $P);
134  }
135  }
136 
137  return $res;
138  }
139 }
$params
Holds various parameters for the curve (q, l, d, I, B).
Definition: ED25519.php:27
static $instance
Singleton instance.
Definition: ED25519.php:24