20 const DER_HEADER =
"\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14";
61 $encoder->encodeString(self::getName());
62 $encoder->encodeMpint($this->e);
63 $encoder->encodeMpint($this->n);
66 public static function unserialize(\
fpoirotte\Pssht\Wire\
Decoder $decoder, $private = null)
68 $e = $decoder->decodeMpint();
69 $n = $decoder->decodeMpint();
72 throw new \InvalidArgumentException();
74 return new static(
$n,
$e, $private);
77 public function sign($message)
79 if ($this->d === null) {
80 throw new \RuntimeException();
83 $bits = strlen(gmp_strval($this->n, 2));
84 $H = sha1($message,
true);
85 $T = self::DER_HEADER . $H;
87 $emLen = ($bits + 7) >> 3;
88 if ($emLen < $tLen + 11) {
89 throw new \RuntimeException();
91 $PS = str_repeat(
"\xFF", $emLen - $tLen - 3);
92 $EM = gmp_init(bin2hex(
"\x00\x01" . $PS .
"\x00" . $T), 16);
93 if (gmp_cmp($EM, $this->n) >= 0) {
94 throw new \RuntimeException();
97 gmp_strval(gmp_powm($EM, $this->d, $this->n), 16),
102 return pack(
'H*', $s);
105 public function check($message, $signature)
108 $bits = strlen(gmp_strval($this->n, 2));
109 $emLen = ($bits + 7) >> 3;
110 if (strlen($signature) !== $emLen) {
111 throw new \InvalidArgumentException();
113 $s = gmp_init(bin2hex($signature), 16);
114 if (gmp_cmp($s, $this->n) >= 0) {
115 throw new \InvalidArgumentException();
117 $m = gmp_powm($s, $this->e, $this->n);
118 $EM = bin2hex(pack(
'H*', str_pad(gmp_strval($m, 16), $emLen * 2,
'0', STR_PAD_LEFT)));
121 $H = sha1($message,
true);
122 $T = self::DER_HEADER . $H;
124 if ($emLen < $tLen + 11) {
125 throw new \RuntimeException();
127 $PS = str_repeat(
"\xFF", $emLen - $tLen - 3);
128 $EMb = bin2hex(
"\x00\x01" . $PS .
"\x00" . $T);
131 return ($EM === $EMb);
__construct($n, $e, $d=null)
check($message, $signature)
const DER_HEADER
DER header for RSA.
serialize(\fpoirotte\Pssht\Wire\Encoder $encoder)
static getName()
Return the name of the algorithm.