private function gpg_session($key_id, $key_type, $session_key, $public_key)
{
$mod = array();
$exp = array();
$enc = "";
$s = base64_decode($public_key);
$l = floor((ord($s[0]) * 256 + ord($s[1]) + 7) / 8);
$mod = mpi2b(substr($s, 0, $l + 2));
if ($key_type) {
$grp = array();
$y = array();
$B = array();
$C = array();
$l2 = floor((ord($s[$l + 2]) * 256 + ord($s[$l + 3]) + 7) / 8) + 2;
$grp = mpi2b(substr($s, $l + 2, $l2));
$y = mpi2b(substr($s, $l + 2 + $l2));
$exp[0] = $this->el[GPG_Utility::c_random() & 7];
$B = bmodexp($grp, $exp, $mod);
$C = bmodexp($y, $exp, $mod);
} else {
$exp = mpi2b(substr($s, $l + 2));
}
$c = 0;
$lsk = strlen($session_key);
for ($i = 0; $i < $lsk; $i++) {
$c += ord($session_key[$i]);
}
$c &= 0xffff;
$lm = ($l - 2) * 8 + 2;
$m = chr($lm / 256) . chr($lm % 256) . chr(2) . GPG_Utility::s_random($l - $lsk - 6, 1) . "" . chr(7) . $session_key . chr($c / 256) . chr($c & 0xff);
if ($key_type) {
$enc = b2mpi($B) . b2mpi(bmod(bmul(mpi2b($m), $C), $mod));
return $this->gpg_header(0x84, strlen($enc) + 10) . chr(3) . $key_id . chr(16) . $enc;
} else {
$enc = b2mpi(bmodexp(mpi2b($m), $exp, $mod));
return $this->gpg_header(0x84, strlen($enc) + 10) . chr(3) . $key_id . chr(1) . $enc;
}
}