/** * EMSA-PKCS1-V1_5-ENCODE * * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}. * * @access private * @param String $m * @param Integer $emLen * @return String */ function _emsa_pkcs1_v1_5_encode($m, $emLen) { $h = $this->hash->hash($m); if ($h === false) { return false; } // see http://tools.ietf.org/html/rfc3447#page-43 switch ($this->hashName) { case 'md2': $t = pack('H*', '3020300c06082a864886f70d020205000410'); break; case 'md5': $t = pack('H*', '3020300c06082a864886f70d020505000410'); break; case 'sha1': $t = pack('H*', '3021300906052b0e03021a05000414'); break; case 'sha256': $t = pack('H*', '3031300d060960864801650304020105000420'); break; case 'sha384': $t = pack('H*', '3041300d060960864801650304020205000430'); break; case 'sha512': $t = pack('H*', '3051300d060960864801650304020305000440'); } $t .= $h; $tLen = strlen($t); if ($emLen < $tLen + 11) { user_error('Intended encoded message length too short', E_USER_NOTICE); return false; } $ps = str_repeat(chr(0xff), $emLen - $tLen - 3); $em = "{$ps}{$t}"; return $em; }
/** * DSA verify * * @param string $message message * @param string $hash_alg hash algorithm * @param MathBigInteger $r r * @param MathBigInteger $s s * @param MathBigInteger $p p * @param MathBigInteger $q q * @param MathBigInteger $g g * @param MathBigInteger $y public key * @return bool */ public static function verify($message, $hash_alg, $r, $s, $p, $q, $g, $y) { $hash = new CryptHash($hash_alg); $hash_m = new MathBigInteger($hash->hash($message), 256); $w = $s->modInverse($q); $hash_m_mul = $hash_m->multiply($w); $u1_base = $hash_m_mul->divide($q); $u1 = $u1_base[1]; $r_mul = $r->multiply($w); $u2_base = $r_mul->divide($q); $u2 = $u2_base[1]; $g_pow = $g->modPow($u1, $p); $y_pow = $y->modPow($u2, $p); $g_pow_mul = $g_pow->multiply($y_pow); $g_pow_mul_mod_base = $g_pow_mul->divide($p); $g_pow_mul_mod = $g_pow_mul_mod_base[1]; $v_base = $g_pow_mul_mod->divide($q); $v = $v_base[1]; return $v->compare($r) == 0; }