Files
freeCodeCamp/curriculum/challenges/japanese/10-coding-interview-prep/project-euler/problem-182-rsa-encryption.md
2022-01-20 20:30:18 +01:00

3.2 KiB

id, title, challengeType, forumTopicId, dashedName
id title challengeType forumTopicId dashedName
5900f4231000cf542c50ff35 問題 182: RSA 暗号化 5 301818 problem-182-rsa-encryption

--description--

RSA 暗号化は次の手順で行われます。

2 つの相異なる素数 pq を生成します。 n=p*qφ=(p-1)(q-1) を計算します。 1 < e < φ に対して、gcd(e,φ) = 1 となる整数 e を見つけます。

この方式におけるメッセージは、区間 [0,n-1] の中の数です。 次に、暗号化される文は何らかの形でメッセージ (区間 [0,n-1] の中の数) に変換されます。 文を暗号化するために、メッセージごとに m, c=me mod n が計算されます。

文を復号するには、ed=1 mod φ となるような d を計算し、暗号化されたメッセージ c ごとに、m=cd mod n を計算するという手順が必要です。

me mod n = m となるような em の値が存在します。 me mod n = m となるメッセージ m を非隠蔽メッセージと呼びます。

e を選択する際の問題は、非隠蔽メッセージが多すぎてはいけないという点です。 例えば、p=19, q=37 とします。 このとき、n=19*37=703, φ=18*36=648 となります。 e=181 を選択した場合、gcd(181,648)=1 ですが、me mod n の計算時に、考えられるすべてのメッセージ m (0≤m≤n-1) が非隠蔽メッセージとなります。 e についてどのような有効な選択を行っても、非隠蔽メッセージがいくつか存在します。 非隠蔽メッセージの数が最小限であることが重要です。

1 < e < φ(p,q) かつ gcd(e,φ)=1 のとき、与えられた任意の pq について、e 値に対する非隠蔽メッセージの数が最小になるような e 値の総和を求めなさい。

--hints--

RSAEncryption は関数でなければなりません。

assert(typeof RSAEncryption === 'function')

RSAEncryption は数値を返す必要があります。

assert.strictEqual(typeof RSAEncryption(19, 37), 'number');

RSAEncryption(19, 37)17766 を返す必要があります。

assert.strictEqual(RSAEncryption(19, 37), 17766);

RSAEncryption(283, 409)466196580 を返す必要があります。

assert.strictEqual(RSAEncryption(283, 409), 466196580);

RSAEncryption(1009, 3643)399788195976 を返す必要があります。

assert.strictEqual(RSAEncryption(19, 37), 17766);

--seed--

--seed-contents--

function RSAEncryption(p, q) {

  return true;
}

RSAEncryption(19, 37);

--solutions--

function gcd(a, b) {
    if (b)
        return gcd(b, a % b);
    else
        return a;
}

function RSAEncryption(p, q) {
    let phi = (p - 1) * (q - 1);

    let best = Number.MAX_SAFE_INTEGER;
    let sum = 0;

    for (let e = 0; e < phi; ++e) {
        if (!(gcd(e, phi) == 1))
            continue;

        let msg = (gcd(p - 1, e - 1) + 1) * (gcd(q - 1, e - 1) + 1);

        if (best == msg) {
            sum += e;
        } else if (best > msg) {
            best = msg;
            sum = e;
        }
    }

    return sum;
}