RSA暗号

function rsa_key_generate (
  $p,
  $q
){
  if ($p == $q) {
    return false;
  }

  $n = (string)gmp_mul($p, $q); //mul-> 乗算
  $n_ gmp_mul(gmp_sub($p, '1'), gmp_sub($q, '1')); // 減算(p-1)(q-1)
  $rand = gmp_random_range(0, gmp_sub($n_, '1')); // random_range -> ランダムな数 0 ~ (n')

  while(true) {
    $coprime_numbers = (string)gmp_gcd($rand, $_n); // gcd -> 最大公約数を返す

    // 最大公約数が1なら互いに素な数
    if($coprime_numbers === '1') {
      $e = (string)$rand;
      break;
    }
    // 非互に素な数減算し再計算
    $rand = gmp_sub($rand, '1');
  }

  $d = (string)gmp_invert($e, $n_); // n'を法としたeの逆数

  // 秘密鍵:d 公開鍵:n, e
  return [$d, $n, $e];
}

function rsa_encryption (
  $a, //暗号化対象の平文
  $n, //公開鍵1
  $e //公開鍵2
){
  $b = [];
  foreach ($a as $value) {
    // aの一つを2乗
    $a_e = gmp_pow($value, $e);
    // e乗した値をnで割った余りを格納
    $b[] = (string)gmp_div_r($a_e, $n);
  }
  return $b;
}

function composite (
  $b, // 暗号文
  $d, // 秘密鍵
  $n // 公開鍵
){
    $a = [];
    foreach ($b as $value) {
      // bの一つをd乗する
      $b_d = gmp_pow($value, $d); // 
      // d乗した値をnで割った余りを格納
      $a[] = (string)gmp_div_r($b_d, $n);
    }
    return $a;
  }
  return $b;
}

// 平文を数値配列に変換
function convert_string_to_integer(
  $str
){
  // 初期配列
  $ord_array = [];

  for ($i = 0; $i < mb_strlen($str); $i ++) {
    $value = mb_substr($str, $i, 1);
    $ord_array[] = mb_ord($value);
  }
  return $ord_array;
}

// 数値配列を文字列に変換
function convert_integer_to_string (
  $int_array
) {
  // 初期文字列
  $chr = '';
  // 配列の数値を全て文字列に変換
  foreach ($int_array as $value){
    // 数値を文字列に
    $chr .= mb_char($value);
  }
  return $chr;
}