21 const DER_HEADER =
"\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10";
76 $encoder->encodeString(self::getName());
77 $encoder->encodeMpint($this->p);
78 $encoder->encodeMpint($this->q);
79 $encoder->encodeMpint($this->g);
80 $encoder->encodeMpint($this->y);
83 public static function unserialize(\
fpoirotte\Pssht\Wire\
Decoder $decoder, $private = null)
85 $p = $decoder->decodeMpint();
86 $q = $decoder->decodeMpint();
87 $g = $decoder->decodeMpint();
88 $y = $decoder->decodeMpint();
90 throw new \InvalidArgumentException();
92 return new static(
$p,
$q,
$g,
$y, $private);
95 public function sign($message)
97 if ($this->x === null) {
98 throw new \RuntimeException();
101 $H = gmp_init(sha1($message,
false), 16);
105 $k = openssl_random_pseudo_bytes(20);
108 if (ltrim($k,
"\0") ===
'') {
115 if (ord($k[0]) & 0x80) {
116 $k[0] = chr(ord($k[0]) & 0x7F);
119 $k = gmp_init(bin2hex($k), 16);
120 $k_1 = gmp_invert($k, $this->q);
121 }
while ($k_1 ===
false);
123 $r = gmp_mod(gmp_powm($this->g, $k, $this->p), $this->q);
124 $s = gmp_mod(gmp_mul($k_1, gmp_add($H, gmp_mul($this->x, $r))), $this->q);
125 }
while ($r === 0 || $s === 0);
127 $r = str_pad(gmp_strval($r, 16), 20,
'0', STR_PAD_LEFT);
128 $s = str_pad(gmp_strval($s, 16), 20,
'0', STR_PAD_LEFT);
129 }
while ($this->
check($message, pack(
'H*H*', $r, $s)) ===
false);
131 return pack(
'H*H*', $r, $s);
134 public function check($message, $signature)
138 if (strlen($signature) != 2 * 20) {
139 throw new \InvalidArgumentException();
142 $H = gmp_init(sha1($message,
false), 16);
143 $rp = gmp_init(bin2hex(substr($signature, 0, 20)), 16);
144 $sp = gmp_init(bin2hex(substr($signature, 20)), 16);
145 $w = gmp_invert($sp, $this->q);
146 $g_u1 = gmp_powm($this->g, gmp_mod(gmp_mul($H, $w), $this->q), $this->p);
147 $y_u2 = gmp_powm($this->y, gmp_mod(gmp_mul($rp, $w), $this->q), $this->p);
148 $v = gmp_mod(gmp_mod(gmp_mul($g_u1, $y_u2), $this->p), $this->q);
149 return (gmp_cmp($v, $rp) === 0);
const DER_HEADER
DER header for DSA.
static getName()
Return the name of the algorithm.
serialize(\fpoirotte\Pssht\Wire\Encoder $encoder)
check($message, $signature)
__construct($p, $q, $g, $y, $x=null)