프로그래밍/Block Chain

[Bitcoin] 지갑 1

YuminK 2025. 4. 20. 12:54

지갑

지갑은 개인키를 담는 곳으로 대게 구조화된 파일이나 데이터베이스 형태로 구현되어 있다. 결정적 키 생성법을 이용하여 이전 개인키로부터 새로운 개인키를 각각 생성하며, 개인키들을 차례대로 연결할 수 있다. 이러한 배열을 계속 만들어 내는 최초의 키(Seed)만 있으면 배열상의 모든 개인키를 생성해 낼 수 있다. 사용자들은 개인키를 이용하여 거래에 서명하여 거래출력값(비트코인)을 가지고 있음을 증명한다. 

 

비결정적 지갑

단순히 무작위로 생성된 개인키를 모아놓은 것이다. 유형-0 비결정적 지갑이라고 부른다. 무작위로 선택한 개인키 100개를 미리 생성한 후 필요한 만큼 추가로 생성하기 때문에 각 키들은 단 한번만 사용된다. 키가 생성된 후에는 복사본을 보관해야 하므로 자주 데이터를 백업해야 한다. 관리가 복잡하기 때문에 결정적 지갑을 사용하는 추세다.

 

결정적 지갑

결정적 지갑(혹은 시드지갑)에서는 common seed에서 얻은 개인키들이 담겨 있다. 시드는 개인키를 생성하기 위해 색인번호나 '체인코드' 등의 여러 데이터와 무작위로 생성된 숫자가 결합되어 있는 형태다. seed만 있으면 추출키 전부를 복원할 수 있는 특징이 있다. 

 

연상기호 코드 워드

연상기호 코드는 결정적 지갑을 얻기 위해, 시드를 이용한 난수를 표현하는(인코딩하는) 영어 단어열이다. 단어열만 있으면 seed를 재현할 수 있고, 시드에서 지갑과 추출키 전부를 재현할 수 있다. 연상기호 코드를 이용해 결정적 지갑을 실행하는 지갑 어플리케이션은, 지갑 생성시 12~24단어로 구성된 단어열을 사용자에게 보여준다. 단어열은 지갑을 백업할 때 사용한다. (bip39에서 연상기호 코드를 정의하고 있다) 

 

bip39에서 연상기호와 시드의 생성 과정을 다음과 같이 규정한다. 

1. 128~256비트의 무작위열(엔트로피)을 생성한다. 

2. 생성된 열의 SHA256 중 첫 몇 비트를 따서 무작위열의 검사합을 생성한다. 

3. 생성된 검사합을 무작위열의 끝에 붙인다.

4. 무작위열을 11비트씩 나눈 후 미리 정해진 단어 2048개로 구성된 사전의 색인으로 사용한다. 

5. 연상기호 코드를 표현하는 12~24단어를 생성한다.

 

계층 결정적 지갑(bip32, 44)

계층 결정적 지갑(HD지갑)은 bip32 표준에서 규정하고 있다. 트리 구조에서 생성된 키를 담고 있다. 부모키가 자식키 열을 만들어 낼 수 있고, 각각의 자식 키는 손자 키 열을 만들어 낼 수 있다. (이 과정이 무한대로 반복된다.) 

 

HD지갑의 2가지 장점

1. 목적에 따라 트리 구조로 분리하여 사용하기에 좋다.

2. 사용자들이 공개키에 대응하는 개인키에 접근하지 않고도 공개키 열을 생성할 수 있다. 

 

시드로부터 HD지갑 생성하기

HD지갑은 128, 256, 512 비트 크기의 무작위 숫자인 root seed 한 개로부터 생성된다. root seed는 연상기호 단어열로 가장 흔하게 표현된다. root seed는 HMAC-SHA512 함수에 입력되고 해시값을 이용하여 마스터 개인키(m)와 마스터 체인코드를 생성한다. 표준 타원곡선 곱셈법(공개키를 구할 때 사용) m * G를 사용하여 마스터 공개키(M)을 구한다. 

 

개인 자식 키 유도하기

계층 결정적 지갑은 부모키로부터 자식키를 얻기 위해 자식키 유도(CKD) 함수를 사용한다. 자식 키 유도 함수는 해시 함수를 기반으로 하고 있으며 다음 항목들을 포함한다. 

1. 부모 개인키 혹은 부모 공개키

2. 체인코드 종자(256비트)

3. 색인번호(32비트)


체인코드 정보가 없는 경우 자식키만으로 또 다른 자식키를 생성하는 것이 불가능하다. 최초의 체인코드(마스터 체인코드)는 무작위 데이터에서 만들어지지만 두 번째 체인코드부터는 부모의 체인코드에서 얻어진다.

 

부모 공개키, 체인코드, 색인번호를 이용하여 HAMC-SHA512 함수를 호출하여 해시값을 구한다. 해시결과 값은 반으로 쪼개지는데, 왼쪽 256비트는 자식 개인키, 오른쪽 256비트는 자식 체인코드가 된다. 색인 번호를 변경하게 되면, 새로운 자식키를 생성하는 것이 가능하다. 이러한 과정을 반복하며 각 자식키의 자식을 구하는 것도 가능하다. 

 

자식키는 어디에 사용되는가? 

공개키와 비트코인 주소를 만드는 데 사용된다. 자식 개인키는 해당 주소로 지불된 비트코인을 소비하는데 이용된다. (서명)

 

출처: 마스터링 비트코인 챕터 4