HD 지갑과 니모닉(mnemonic) 코드

Asterisk
Asterisk
Sep 2, 2018 · 6 min read

본 글은 암호화폐 지갑의 키 관리에 사용되는 니모닉(mnemonic) 코드에 대한 글 입니다.

제가 앞서 작성한 두 개의 글을 읽어보시면 도움이 됩니다.
(1) 비트코인에서 개인키, 공개키, 주소를 생성하는 방식
(2) 지갑(Wallet)에 대한 고찰

니모닉(mnemonic) 코드에 앞서 결정성이 있는 지갑(Deterministic Wallet)과 시드의 관계를 되짚어봅시다.


시드(seed)

결정성이 있는 지갑(Deterministic wallet)은 마스터 시드(Master Seed)로부터 개인키를 계층적으로 생성합니다. 그렇기 때문에 지갑 내의 모든 키를 기억할 필요가 없이 마스터 시드만 기억(혹은 기록)하고 있으면 모든 하위 키들을 재생성하여 지갑 전체를 복원할 수 있습니다. 그런데 아래와 같이 32자리의 16진수로 표현되는 시드를 잘 기억(혹은 기록)할 수 있을까요?

0C1E24E5917779D297E14D45F14E1A1A

니모닉 (Mnemonic) 코드

32자리의 16진수로 표현되는 시드는 기억(혹은 기록)하기 쉬운 형태가 아니기 때문에 비트코인 개발자들은 그것을 생성하는 기억(혹은 기록)하기 쉬운 무언가를 만들기로 제안합니다. 그것이 바로 BIP-0039입니다.

BIP: 39
Layer: Applications
Title: Mnemonic code for generating deterministic keys
Author: Marek Palatinus <slush@satoshilabs.com>
Pavol Rusnak <stick@satoshilabs.com>
Aaron Voisine <voisine@gmail.com>
Sean Bowe <ewillbefull@gmail.com>
Comments-Summary: Unanimously Discourage for implementation
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0039
Status: Proposed
Type: Standards Track
Created: 2013-09-10

니모닉 코드는 사람이 읽을 수 있는 텍스트로 표현됩니다. 사용자는 이것을 쉽게 기록하고 지갑을 복원하는데 사용할 수 있습니다. 이러한 특성으로 비트코인 지갑 뿐만아니라 현재 거의 모든 암호화폐의 지갑들 중 대다수가 이것을 사용할 수 있는 기능을 지원하고 있습니다.


니모닉 코드 생성하기

니모닉 코드 생성은 임의의 값을 선택하는 것에서부터 시작합니다.

  1. 128(160, 192, 224, 256)비트 길이의 임의의 값을 생성합니다.
  2. 1.에서 생성한 값에 SHA-256 해시를 적용한 값에, 앞 4(5, 6, 7, 8) 비트로 체크섬(checksum)을 생성합니다.
  3. 1.에서 생성한 값에 2.에서 생성한 체크섬을 이어붙입니다.
  4. 3.에서 생성한 결과를 11비트 길이 세그먼트로 나눕니다.
  5. 각 11비트 값을 사전에 정의된 단어 리스트에 매핑합니다.
Figure 6. Generating entropy and encoding as mnemonic words

니모닉 코드로부터 마스터 시드 생성하기

니모닉 코드로부터 마스터 시드를 생성하기 위해서 키 스트레칭 과정을 거칩니다.

키 스트레칭(key stretching)이란 입력한 패스워드(여기서는 니모닉 코드)에 대해 특정 해시 함수를 통해 다이제스트를 생성하는 것을 재귀적으로 반복함을 말합니다.
비트코인(및 대다수의 암호화폐)에서는 PBKDF2라는 키 스트레칭 방식을 사용합니다.

PBKDF2는 아래와 같이 5개의 파라메터가 사용되며,

Derived key = PBKDF2(
Pseudorandom function,
Password,
Salt,
The number of iteration,
length of Derived key
)

실제로 시드가 생성되는 방식은 아래와 같습니다.

Seed = PBKDF2(
HMAC-SHA512,
{Mnemonic code words},
"mnemonic" + {optional passphrase},
2048,
512
)

무작위 대입을 통한 시드 획득

니모닉 코드에서 시드를 생성하는 방식이 생각보다 간단해보여서 시드를 임의로 생성하여 다른 사람의 자산을 가로챌수도 있다는 착각을 하는 분들이 간혹 있습니다.

하지만 이것이 착각일 뿐이라는걸 증명하기 위해서 단계별로 경우의 수를 생각해봅시다. 시드에 대해 무작위 대입 (broute-force) 공격을 한다고 가정해봅시다.

  1. 엔트로피의 길이가 128이기 때문에 엔트로피는 2¹²⁸ 의 경우의 수를 가집니다.
    (2¹²⁸는 340,282,366,920,938,463,463,374,607,431,768,211,456입니다.)
  2. 그만 알아봅시다.

…는 농담이고 다시 진지하게 가정해보면,

  1. 8x Nvidia GTX 1080에 Hashcat을 사용하여 벤치마크를 수행한 결과 PBKDF2-HMAC-SHA512에 대해서 3450.1 kH/s 수준의 성능을 확인 할 수 있었습니다.
  2. 3450.1 kH/s 의 성능으로 1년간 생성 할 수 있는 시드의 수는 108,802,354M(2⁴⁷)개에도 미치지 않기 때문에 2⁸¹년 이상의 시간이 필요합니다.
  3. GTX 1080을 8,000개씩 공수한 사람들 1,000명이 모여 연합을 결성했다고 가정해봐도 2⁶¹년 이상의 시간이 필요합니다.

그리고 사실 제가 말은 안했지만, 벤치마크 상의 반복횟수는 2048이 아닌 1000으로 실제 시드를 생성하는데에는 2배 이상의 시간이 소요됩니다.
게다가 거의 모든 암호화폐 지갑 서비스들이 8글자 이상의 passpharase를 강제하고 있어서 passpharase 없이 생성된 지갑의 숫자는 많지 않을 것으로 추정됩니다.
때문에 무작위 대입을 통해 지갑을 탈취하려는 노력을 할바엔 정상적으로 채굴을 하는게 더 기대수익이 높습니다.


니모닉 코드와 개인키의 관계

니모닉 코드와 개인키의 관계를 곡해하시는 사람들이 많습니다.
거의 대다수가 개인키가 먼저 생성되고 그것으로부터 니모닉 코드를 도출한다는 식으로 이야기를 하더군요.

결정성이 있는 지갑에서 개인키가 생성되는 과정을 다시 한번 간단하게 살펴봅시다.

  1. 128(160, 192, 224, 256)비트 길이의 임의의 값(엔트로피) 생성
  2. 엔트로피로부터 니모닉 코드 생성
  3. 니모닉 코드와 passphrase로 마스터 시드 생성
  4. 마스터 시드로부터 개인키 생성

위의 과정을 보면 알 수 있듯이 엔트로피로부터 니모닉 코드가 먼저 생성됩니다.

사실 개인키 / 지갑 / 니모닉 코드에 대한 글을 연이어 쓰게된 이유의
첫번째로 자신이 자산을 넣어둔 암호화폐 지갑이 HD 지갑이라는 특수한 형태라는 것을 모르는 사람이 대다수라는 것과
두번째로 니모닉 코드와 개인키와의 관계를 잘못 알고 있는 사람이 너무 많다는 것이었습니다.

암호화폐는 기존의 은행이나 카드사와 같이 관리의 주체가 중앙화되어있지 않습니다. 때문에 사용자 개인이 자신의 자산을 더 안전하게 보호할 수 있도록 노력해야만 합니다. 그러기 위해서는 자신이 사용하는 지갑과 개인키를 관리하는 방식에 대한 이해가 필수적입니다.
부디 이 글이 암호화폐와 관련된 직업을 가진 사람들 뿐만 아니라 사용자 모두에게 도움이 되었으면 합니다.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade