Upgrade to Pro — share decks privately, control downloads, hide ads and more …

デデンネでもわかる RSA

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest. →
Avatar for QUANON QUANON
August 27, 2020

デデンネでもわかる RSA

Avatar for QUANON

QUANON

August 27, 2020

More Decks by QUANON

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ • Shinpei Noda (@quanon_jp) • Money Forward, Inc. •

    αʔόαΠυΤϯδχΞ • Ruby/Rails • ಡॻ͕େ޷͖ • ଜ্य़थओٛऀ
  2. ҉߸Խɾ෮߸ • ҉߸Խ: • ෮߸: • ެ։伴: • ൿີ伴: ciphertext

    = plaintextE mod N plaintext = ciphertextD mod N {E, N} {D, N}
  3. 伴ϖΞ • ެ։伴: , ൿີ伴: • ͜ͷ ΛٻΊΔʹ͸ 2 ͭͷૉ਺

    Λ࢖͏ • ࡐྉ͸ͨͬͨ͜Ε͚ͩʂ {E, N} {D, N} E, D, N p, q
  4. 伴ϖΞ • ( ) • ͱ͸࠷େެ໿਺ (Greatest Common Divisor) ͷ͜ͱ

    • ͭ·Γ ͸ޓ͍ʹૉͳ೚ҙͷ੔਺ • ( ) • ͭ·Γ ͸ ͱͷੵͷ৒༨͕ 1 ͱͳΔ೚ҙͷ੔਺ gcd(E, L) = 1 1 < E < L gcd E, L (E ⋅ D) mod L = 1 1 < D < L D E
  5. RSA ͷ҆શੑ • ൿີ伴Λ࢖Θͣʹ҉߸Խͷࡍͷ ͱ͍͏ࣜ Λղ͍ͯ҉߸จ (ciphertext) ͔Βฏจ (plaintext) ΛಘΔͷ͸೉͍͠

    • ཭ࢄର਺໰୊ Λղ͘ͷ͸ແཧήʔ • ͷ ΛૉҼ਺෼ղͯ͠ ΛಘͯɺͦΕ͔Β ΛٻΊΔͱ͍ ͏ղಡํ๏΋ߟ͑ΒΕΔ͕…… • ඇৗʹେ͖ͳ੔਺ Λ ૉҼ਺෼ղ ͢Δͷ͸ແཧήʔ ciphertext = plaintextE mod N N = p ⋅ q N p ⋅ q D N
  6. Ruby Ͱ࣮૷ͯ͠ΈΑ͏ # 平文 plain_text = '夜は短し歩けよ乙女' plain_integers = plain_text.each_codepoint

    plain_integers.to_a #=> [22812, 12399, 30701, 12375, 27497, 12369, 12424, 20057, 22899]
  7. Ruby Ͱ࣮૷ͯ͠ΈΑ͏ n = p * q #=> 692033 l

    = (p - 1).lcm(q - 1) #=> 343650 e = (2...l).find { |i| i.gcd(l) == 1 } #=> 7 d = (2...l).find { |i| (e * i) % l == 1 } #=> 49093
  8. Ruby Ͱ࣮૷ͯ͠ΈΑ͏ # 公開鍵 [e,n] で暗号化 encrypted_integers = plain_integers.map {

    |i| i.pow(e, n) } #=> [79745, 636262, 150603, 188308, 444550, 549324, 383889, 180314, 632474] # 暗号文 (無理やり文字列にしてみる) cipher_text = encrypted_integers.map(&:chr).join #=> "\u{13781}\u{9B566} \u{6C886}\u{861CC}\u{5DB91} \u{9A69A}"
  9. Ruby Ͱ࣮૷ͯ͠ΈΑ͏ # 秘密鍵 [d, n] で復号 decrypted_intergers = encrypted_integers.map

    { |i| i.pow(d, n) } #=> [22812, 12399, 30701, 12375, 27497, 12369, 12424, 20057, 22899] # 平文 decrypted_intergers.map(&:chr).join #=> "夜は短し歩けよ乙女"
  10. খωλ: Integer#pow ʹ͍ͭͯ 123_456_789 ** 999_999_999 % 7_777 # warning:

    in a**b, b may be too big #=> NaN 123_456_789.pow(999_999_999, 7_777) #=> 4453