22 public function __construct($x = null, $y = null)
24 $this->coordinates = array(
33 public function __get($name)
38 public function __set($name, $value)
40 $this[$name] = $value;
45 return array_key_exists($offset, $this->coordinates);
50 if (!array_key_exists($offset, $this->coordinates)) {
51 throw new \InvalidArgumentException();
54 return $this->coordinates[$offset];
59 if (!array_key_exists($offset, $this->coordinates)) {
60 throw new \InvalidArgumentException();
63 if (!(is_null($value) ||
64 (is_resource($value) && get_resource_type($value) ===
'GMP integer') ||
65 (is_object($value) && ($value instanceof \GMP)))) {
66 $value = @gmp_init($value);
67 if ($value ===
false) {
68 throw new \InvalidArgumentException();
72 $this->coordinates[$offset] = $value;
77 throw new \InvalidArgumentException();
82 if ($this->coordinates[
'x'] === null ||
83 $this->coordinates[
'y'] === null) {
87 $mlen = gmp_init(strlen(gmp_strval($curve->getModulus(), 2)));
88 $mlen = gmp_intval(gmp_div_q($mlen, 8, GMP_ROUND_PLUSINF)) * 2;
90 $x = gmp_strval($this->coordinates[
'x'], 16);
91 $x = pack(
'H*', str_pad($x, $mlen,
'0', STR_PAD_LEFT));
93 $y = gmp_strval($this->coordinates[
'y'], 16);
94 $y = pack(
'H*', str_pad($y, $mlen,
'0', STR_PAD_LEFT));
96 return "\x04" . $x . $y;
99 public static function unserialize(\
fpoirotte\Pssht\ECC\
Curve $curve, $s)
104 throw new \InvalidArgumentException();
107 if ($s[0] ===
"\x00" && $len === 1) {
108 return new static(null, null);
113 if ($s[0] !==
"\x04") {
114 throw new \InvalidArgumentException();
117 $mod = $curve->getModulus();
118 $mlen = gmp_init(strlen(gmp_strval($mod, 2)));
119 $mlen = gmp_intval(gmp_div_q($mlen, 8, GMP_ROUND_PLUSINF)) * 2;
121 if ($len !== $mlen + 1) {
122 throw new \InvalidArgumentException();
125 $x = gmp_init(bin2hex(substr($s, 1, $mlen / 2)), 16);
126 $y = gmp_init(bin2hex(substr($s, 1 + $mlen / 2)), 16);
127 if (gmp_cmp($x, $mod) >= 0 || gmp_cmp($y, $mod) >= 0) {
128 throw new \InvalidArgumentException();
131 return new static($x, $y);
134 public static function add(
139 $mod = $curve->getModulus();
140 $xP = $P->coordinates[
'x'];
141 $yP = $P->coordinates[
'y'];
142 $xQ = $Q->coordinates[
'x'];
143 $yQ = $Q->coordinates[
'y'];
145 if (!gmp_cmp($xP, $xQ) && !gmp_cmp($yP, $yQ)) {
146 $alphanum = gmp_add(gmp_mul(
'3', gmp_pow($xP,
'2')), $curve->getA());
147 $alphaden = gmp_mul(
'2', $yP);
149 $alphanum = gmp_sub($yQ, $yP);
150 $alphaden = gmp_sub($xQ, $xP);
153 $bezout = gmp_gcdext($alphaden, $mod);
154 $alpha = gmp_mod(gmp_mul($alphanum, $bezout[
's']), $mod);
155 $xR = gmp_sub(gmp_sub(gmp_pow($alpha,
'2'), $xP), $xQ);
156 $yR = gmp_sub(gmp_mul($alpha, gmp_sub($xP, $xR)), $yP);
159 gmp_mod(gmp_add($xR, $mod), $mod),
160 gmp_mod(gmp_add($yR, $mod), $mod)
166 if (!((is_resource($n) && get_resource_type($n) ===
'GMP integer') ||
167 (is_object($n) && ($n instanceof \GMP)))) {
170 throw new \InvalidArgumentException();
174 if (gmp_cmp($n,
'1') === 0) {
178 $s = gmp_strval($n, 2);
182 for ($i = 1; $i < $len; $i++) {
183 $res = static::add($curve, $res, $res);
184 if ($s[$i] ===
'1') {
185 $res = static::add($curve, $res, $this);
193 $n = self::multiply($curve, 2);
194 return (!gmp_cmp($this[
'x'], $n[
'x']) &&
195 !gmp_cmp($this[
'y'], $n[
'y']));
Interface to provide accessing objects as arrays.
offsetSet($offset, $value)
$coordinates
The points coordinates (x, y).