비트코인 머클 트리 알고리즘의 취약점과 우회방안

비트코인 마이너는 블록에 포함될 트랜잭션들의 머클 루트를 계산하여 블록 헤더에 넣고 블록을 생성합니다. 다른 비트코인 풀 노드들은 블록 헤더의 머클 루트가 스스로 계산한 머클 루트와 같은지 비교하여 해당 블록의 유효성을 검사합니다.

머클 루트는 세부적인 구현에서 약간씩 차이가 나는데, 비트코인은 각 라운드의 해시가 홀수 개이면 마지막 해시를 한 번 중복해서 넣는 방식으로 짝수로 만들고 계산을 합니다. 일례로 1 2 3 해시의 머클 루트를 계산하기 위해서는 1 2 해시를 합쳐서 A를 만들고 남은 해시가 홀수 개니 3을 하나 더 추가해서 3 3 해시를 합쳐서 B를 만드는 방식입니다. 그런 다음 A B를 합쳐서 해시를 계산하면 머클 루트가 나옵니다.

그런데 이런 방식으로 머클 루트를 만들면 트랜잭션을 중복해서 넣는 방식으로 머클 루트가 같은 블록을 쉽게 만들어 낼 수 있는 문제가 있습니다. 예를 들어, 아래 그림처럼 1 2 3 4 5 6 해시의 머클 루트가 A라고 하면 5 6해시를 중복해서 한 번 더 넣은 1 2 3 4 5 6 5 6의 머클 루트도 A가 됩니다. 다음 라운드에서 F가 하나인 것과 F가 두 개인 것이 해시 값이 C로 동일하기 때문입니다.

누군가가 고의로 머클 루트는 같지만 validation이 실패하는 블록을 고의로 보내게 되면, 이 블록을 받은 노드는 이후 정상적인 블록을을 invalid하다고 판단하게 되므로 심각한 DoS 공격이 가능해집니다.

비트코인 이 문제를 인지하고 해시 목록의 마지막에 두 개의 동일한 해시가 나오는 경우를 머클 루트가 invalid한 것과 동일하게 취급하는 방법으로 우회하고 있습니다. (호환성 때문에 머클 트리 알고리즘을 바꿀 수는 없었습니다.) 1 2 3 4 5 6 5 6의 경우 해시를 계산하고 나면 D E F F가 나오는데 마지막에 F가 2번 나오므로 invalid하다고 판단하는 방식입니다.

이는 머클 트리 구현 편의를 위해 선택한 간단한 구현 세부사항이 어떤 식으로 보안 문제를 일으킬 수 있는지를 보여주는 아주 좋은 예입니다. 참고로 이 문제는 CVE-2012-2459로 리포트되어 있습니다.

비트코인 코어 지갑의 UTXO 사용법

Bitcoin Core 지갑이 UTXO를 어떤 로직에 따라 사용하는지 궁금해서 찾아봤습니다.

  1. 하나의 UTXO가 사용할 금액(타겟)을 정확히 만족시키면 해당 UTXO를 사용.

  2. 타겟보다 작은 여러 개의 UTXO의 총합이 타겟을 정확히 만족시키면 해당 UTXO들을 사용.

  3. 타겟보다 작은 여러 개의 UTXO의 총합이 타겟보다 작으면 타겟보다 큰 UTXO 중에 가장 작은 UTXO를 사용.

  4. 랜덤하게 선택한 UTXO들 조합의 총합이 타겟과 같거나 클때까지 1000번 시도. 총합이 타겟을 정확히 만족시키면 즉시 종료.

  5. (1) 타겟보다 큰 UTXO 중 가장 작은 UTXO
    (2) 4번에서 찾은 UTXO 조합 중 총합이 가장 작은 조합.
    (1), (2)를 비교해서 작은 쪽을 선택

Bitcoin Core 지갑은 아웃풋 크기를 최소화하는 방법으로 최적화되어 있는 걸 알 수 있습니다.

물론 이 방법이 항상 정답은 아닙니다. 지갑을 만드는 엔지니어가 UTXO 아웃풋 크기, 성능, 보안 등 어떤 면을 강조하느냐에 따라 다양한 알고리즘이 가능한 영역입니다.

관련 코드는 Bitcoin Core 코드에서 확인 가능합니다.

스마트 컨트랙트 개발자의 특성과 커리어

스마트 컨트랙트 개발자의 특성과 커리어에 대해 잘 정리한 글이 있어서 공유합니다.

  • 1년 이하의 개발자의 연봉도 무척 높다. 스마트 컨트랙트를 2년 이상한 개발자는 이미 너무 부자라서 고용 시장에는 없다. 다만, 현재 투자 열풍과 ICO 붐이 꺼진 후에는 거품이 꺼질 수 있다.
  • 스마트 컨트랙트 개발자가 되기 위해 암호학, 게임 이론, 프로토콜 설계, 분산 시스템 등을 다 이해해야 하는 것이 아니다. 웹 개발자가 HTTPS나 TCP/IP가 어떻게 동작하는지 알 필요가 없는 것과 마찬가지다.
  • 기술 자체는 어렵지 않지만, 작은 문제를 하나 해결하기 위해 많은 수고를 할 각오를 해야 한다. 문서도 없고 스택오버플로에 제대로 답변도 없고, 언어나 개발 도구 등도 모두 아직 성숙하지 않은 상태이기 때문이다.
  • 출시하기 전에 검증 및 테스트를 엄격하게 해야 한다는 측면에서 소프트웨어 개발보다는 하드웨어 개발과 유사한 점이 있다.