비트코인/비트코인 구조

[비트코인 구조] BIP39: 니모닉(Mnemonic)과 시드(Seed)

라이튼 2023. 1. 9. 17:01

미리 알아야 할 내용들


 

[블록체인 용어] 니모닉(Mnemonic)

코인을 보관하기 위해 개인 지갑을 이용하는 경우 사용자는 블록체인 계좌의 통장 비밀번호라고 할 수 있는 개인키를 직접 보관해야 합니다. 보관된 개인키는 블록체인 상의 자신의 계좌에 접

kwjdnjs.tistory.com

 

[비트코인 구조] 비트코인 해시 함수(sha-256, hash256, hash160)

비트코인 해시 함수(sha-256, hash256, hash160) 해시 함수는 입력 데이터를 고정된 길이의 해시값으로 변환하는 함수를 말합니다. 비트코인에서는 기본적인 해시 함수인 sha-256과 이를 응용한 hash256, has

kwjdnjs.tistory.com


BIP39: 니모닉(Mnemonic)과 시드(Seed)

 

 비트코인에서 사용하는 개인키는 복잡한 형태를 띠고 있기 때문에 키를 보관하거나 암기하기 어렵습니다. 이러한 문제를 해결하기 위해 니모닉이 등장했습니다.

 

 니모닉은 2048개의 단어를 12~24개씩 무작위로 추출한 후 이 단어들을 사용하는 방식입니다. 특정한 단어들의 조합은 특정한 값을 파생시키고 이 값을 이용하면 여러 개의 개인키를 파생시킬 수 있습니다. 다음과 같은 단어들의 집합이 바로 니모닉입니다. 실제로 사용될 수 있는 니모닉 단어들이며, 보안을 위해서 사용하지 마시기 바랍니다.

 

velvet angle worry poem coconut gravity outdoor thought piece copy immense zebra

 

 지금부터는 이러한 니모닉 단어들의 조합을 구하는 과정에 대해서 알아보겠습니다.

 

 니모닉 단어들을 생성하기 위한 가장 첫 단계는 128~256비트 길이의 랜덤한 값을 생성하는 일입니다. 128비트 길이의 값으로 생성할 경우 12개의 단어가, 256비트 길이의 값으로 생성할 경우 24개의 단어가 나옵니다. 이번 글에서는 128비트 길이의 값을 이용하겠습니다.

 

 생성 과정에서 16바이트 길이의 문장인 'hellobitcoinhihi'을 이용하겠습니다. 실제로 사용할 니모닉 단어들을 생성하기 위한 값을 구할 때에는 완전히 랜덤 한 값을 사용해야 합니다.

 

 특정한 길의 값을 구했다면 체크섬을 구해야합니다. 체크섬의 길이는 생성에 사용한 값의 길이를 32비트로 나눈 값입니다. 여기에서는 128비트를 32비트로 나눈 4비트입니다. sha-256 해시함수를 이용해 체크섬을 구한 후 첫 4비트를 구합니다. 다음은 해당 값을 구하는 파이썬 코드입니다.

 

import hashlib

s = b'hellobitcoinhihi'
h = hashlib.sha256(s)

# byte 값을 bit로 변환
def bits(bytes):
    result = ''
    for b in bytes:
        temp = ''
        for i in range(8):
            temp += str((b >> i) & 1)
        result += (temp[::-1])

    return result


print(bits(h.digest())[:4])

 

결과 값은 다음과 같습니다.

 

체크섬: 1001

 

구한 체크섬을 맨 뒤에 붙입니다. 다음은 전체 값입니다.

 

011010000110010101101100011011000110111101100010011010010111010001100011011011110110100101101110011010000110100101101000011010011001

 

 이제 위 값을 11bit 단위로 쪼갭니다. 그리고 쪼개진 값들에 해당하는 단어들을 구합니다. 이 결과가 바로 니모닉 단어들입니다. 다음은 11bit 단위로 쪼갠 후 해당 하는 값에 대한 단어들을 구하는 파이썬 코드입니다. words.txt에 해당하는 단어 목록은 아래 위치한 링크에서 받을 수 있습니다.

 

GitHub - bitcoin/bips: Bitcoin Improvement Proposals

Bitcoin Improvement Proposals. Contribute to bitcoin/bips development by creating an account on GitHub.

github.com

b = '011010000110010101101100011011000110111101100010011010010111010001100011011011110110100101101110011010000110100101101000011010011001'

b11 = [b[i:i+11] for i in range(0, len(b), 11)]
print(b11)

bi = [int(b11[i],2) for i in range(len(b11))]
print(bi)

f = open('words.txt', 'r')
words = f.readlines()
f.close()

n = [words[bi[i]].strip() for i in range(len(bi))]
print(n)

 

결과는 다음과 같습니다.

 

['01101000011', '00101011011', '00011011000', '11011110110', '00100110100', '10111010001', '10001101101', '11101101001', '01101110011', '01000011010', '01011010000', '11010011001']
[835, 347, 216, 1782, 308, 1489, 1133, 1897, 883, 538, 720, 1689]
['half', 'clock', 'brand', 'tell', 'charge', 'riot', 'misery', 'unfold', 'hover', 'drive', 'foam', 'spring']

 

half clock brand tell charge riot misery unfold hover drive foam spring

 

 위 단어들이 바로 니모닉 단어들입니다. 이 단어들을 이용하면 니모닉 시드를 구할 수 있습니다. 그리고 이 시드를 이용하면 개인키를 파생시킬 수 있습니다. 따라서 가장 마지막 과정으로 니모닉 시드를 구해보겠습니다.

 

 니모닉 시드는 PBKDF2 알고리즘을 이용해 구할 수 있습니다. PBKDF2 알고리즘에 니모닉 단어들과 솔트(Salt) 값을 대입한 후 HMAC-SHA512로 2048번 해싱하면, 512비트 값을 구할 수 있습니다. 이 값이 바로 니모닉 시드입니다. PBKDF2에 추가로 사용하는 솔트값은 옵션입니다. 기본적으로 ' mnemonic'을 사용하며, 보안을 위해서 사용자가 원하는 값을 비밀번호처럼 추가로 이어 붙여 사용할 수 있습니다.

 

 실제로 니모닉 시드를 구해보겠습니다. 다음은 니모닉 시드를 구하는 파이썬 코드입니다.

 

from hashlib import pbkdf2_hmac

b = b'half clock brand tell charge riot misery unfold hover drive foam spring'
salt = b'mnemonic'

dk = pbkdf2_hmac('sha512', b, salt, 2048)
print(dk.hex())

 

 아래는 생성된 시드입니다.

 

시드: 5654edaa75b4e9278d90d496df8776b3c902eb7f9c963054a6b527770da15b834e6ad5c42e8332d875ba2dcb382068e6d47307203be8e8d3ad71b0dab0499e77

 

 지금까지 니모닉과 시드에 대해 알아봤습니다. 감사합니다.

 

 

이어지는 글들


 

[비트코인 구조] BIP32: HD지갑(Hierarchical Deterministic Wallet)

미리 알아야 할 내용들 [비트코인 구조] BIP39: 니모닉(Mnemonic)과 시드(Seed) 미리 알아야 할 내용들 [블록체인 용어] 니모닉(Mnemonic) 코인을 보관하기 위해 개인 지갑을 이용하는 경우 사용자는 블록

kwjdnjs.tistory.com