[ Index ] |
PHP Cross Reference of DokuWiki |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Curves over a*x^2 + y^2 = 1 + d*x^2*y^2 5 * 6 * http://www.secg.org/SEC2-Ver-1.0.pdf provides for curves with custom parameters. 7 * ie. the coefficients can be arbitrary set through specially formatted keys, etc. 8 * As such, Prime.php is built very generically and it's not able to take full 9 * advantage of curves with 0 coefficients to produce simplified point doubling, 10 * point addition. Twisted Edwards curves, in contrast, do not have a way, currently, 11 * to customize them. As such, we can omit the super generic stuff from this class 12 * and let the named curves (Ed25519 and Ed448) define their own custom tailored 13 * point addition and point doubling methods. 14 * 15 * More info: 16 * 17 * https://en.wikipedia.org/wiki/Twisted_Edwards_curve 18 * 19 * PHP version 5 and 7 20 * 21 * @author Jim Wigginton <terrafrost@php.net> 22 * @copyright 2017 Jim Wigginton 23 * @license http://www.opensource.org/licenses/mit-license.html MIT License 24 * @link http://pear.php.net/package/Math_BigInteger 25 */ 26 27 namespace phpseclib3\Crypt\EC\BaseCurves; 28 29 use phpseclib3\Math\BigInteger; 30 use phpseclib3\Math\PrimeField; 31 use phpseclib3\Math\PrimeField\Integer as PrimeInteger; 32 33 /** 34 * Curves over a*x^2 + y^2 = 1 + d*x^2*y^2 35 * 36 * @author Jim Wigginton <terrafrost@php.net> 37 */ 38 class TwistedEdwards extends Base 39 { 40 /** 41 * The modulo 42 * 43 * @var BigInteger 44 */ 45 protected $modulo; 46 47 /** 48 * Cofficient for x^2 49 * 50 * @var object 51 */ 52 protected $a; 53 54 /** 55 * Cofficient for x^2*y^2 56 * 57 * @var object 58 */ 59 protected $d; 60 61 /** 62 * Base Point 63 * 64 * @var object[] 65 */ 66 protected $p; 67 68 /** 69 * The number zero over the specified finite field 70 * 71 * @var object 72 */ 73 protected $zero; 74 75 /** 76 * The number one over the specified finite field 77 * 78 * @var object 79 */ 80 protected $one; 81 82 /** 83 * The number two over the specified finite field 84 * 85 * @var object 86 */ 87 protected $two; 88 89 /** 90 * Sets the modulo 91 */ 92 public function setModulo(BigInteger $modulo) 93 { 94 $this->modulo = $modulo; 95 $this->factory = new PrimeField($modulo); 96 $this->zero = $this->factory->newInteger(new BigInteger(0)); 97 $this->one = $this->factory->newInteger(new BigInteger(1)); 98 $this->two = $this->factory->newInteger(new BigInteger(2)); 99 } 100 101 /** 102 * Set coefficients a and b 103 */ 104 public function setCoefficients(BigInteger $a, BigInteger $d) 105 { 106 if (!isset($this->factory)) { 107 throw new \RuntimeException('setModulo needs to be called before this method'); 108 } 109 $this->a = $this->factory->newInteger($a); 110 $this->d = $this->factory->newInteger($d); 111 } 112 113 /** 114 * Set x and y coordinates for the base point 115 */ 116 public function setBasePoint($x, $y) 117 { 118 switch (true) { 119 case !$x instanceof BigInteger && !$x instanceof PrimeInteger: 120 throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); 121 case !$y instanceof BigInteger && !$y instanceof PrimeInteger: 122 throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); 123 } 124 if (!isset($this->factory)) { 125 throw new \RuntimeException('setModulo needs to be called before this method'); 126 } 127 $this->p = [ 128 $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, 129 $y instanceof BigInteger ? $this->factory->newInteger($y) : $y 130 ]; 131 } 132 133 /** 134 * Returns the a coefficient 135 * 136 * @return \phpseclib3\Math\PrimeField\Integer 137 */ 138 public function getA() 139 { 140 return $this->a; 141 } 142 143 /** 144 * Returns the a coefficient 145 * 146 * @return \phpseclib3\Math\PrimeField\Integer 147 */ 148 public function getD() 149 { 150 return $this->d; 151 } 152 153 /** 154 * Retrieve the base point as an array 155 * 156 * @return array 157 */ 158 public function getBasePoint() 159 { 160 if (!isset($this->factory)) { 161 throw new \RuntimeException('setModulo needs to be called before this method'); 162 } 163 /* 164 if (!isset($this->p)) { 165 throw new \RuntimeException('setBasePoint needs to be called before this method'); 166 } 167 */ 168 return $this->p; 169 } 170 171 /** 172 * Returns the affine point 173 * 174 * @return \phpseclib3\Math\PrimeField\Integer[] 175 */ 176 public function convertToAffine(array $p) 177 { 178 if (!isset($p[2])) { 179 return $p; 180 } 181 list($x, $y, $z) = $p; 182 $z = $this->one->divide($z); 183 return [ 184 $x->multiply($z), 185 $y->multiply($z) 186 ]; 187 } 188 189 /** 190 * Returns the modulo 191 * 192 * @return \phpseclib3\Math\BigInteger 193 */ 194 public function getModulo() 195 { 196 return $this->modulo; 197 } 198 199 /** 200 * Tests whether or not the x / y values satisfy the equation 201 * 202 * @return boolean 203 */ 204 public function verifyPoint(array $p) 205 { 206 list($x, $y) = $p; 207 $x2 = $x->multiply($x); 208 $y2 = $y->multiply($y); 209 210 $lhs = $this->a->multiply($x2)->add($y2); 211 $rhs = $this->d->multiply($x2)->multiply($y2)->add($this->one); 212 213 return $lhs->equals($rhs); 214 } 215 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body