calculate_merkle_root 내부 동작 방식 관련

calculate_merkle_root 함수에서 두 hash를 합치는 방식이 어떻게 정의되어있나요?
예시로, H_a, H_b에서 H_ab를 만들때
sha256((H_a+H_b).encode())처럼 붙이는지
sha256(bytes.fromhex(H_a+H_b))처럼 붙이는지 궁금합니다.

#crypto
작성자 정보
답변 2
avatar
snwo
CTF First Place

unhexlify 된 두 항목을 합친뒤 두번 해시하는식으로 진행되더라구요

2021.12.27. 18:51
2dedce
워게임 고인물

해시에는 절대 문자열이 들어가지 않고 바이너리 값(문자열로 보기 힘든 값)이 들어가고요.
알아보니까 비트코인에서 사용하는 해시는 sha256(x)이 아니라 sha256(sha256(x))로 double SHA-256라 합니다.

H_a, H_b를 각각 헥스로된 문자열이라고 한다면 이거를 바이너리 값으로 만들어주어야 하므로
H_a.encode()가 아니라 bytes.fromhex(H_a)로 변환하고요 비트코인의 세계에서는 헥스문자열과 실제 바이너리값의 상호 변환은 파이썬처럼 빅엔디안 방식이 아니라 리틀엔디안이라 bytes.fromhex(H_a)[::-1]으로 바꾸어야 합니다.

sha256((H_a+H_b).encode())이나 sha256(bytes.fromhex(H_a+H_b))가 아니라

from hashlib import sha256

H_a = 'adcc7b631011debe749ee4f97efaa4fe55d321e2153e460ae0b798369d033b7f'
H_b = 'a8f0f38acc57d76e4dc1e549d20599da6339fe7269b4b4a838ab733e36e4aacb'
def htob(x):
    return bytes.fromhex(x)[::-1]
    # 또는 아래도 맞음
    return int(x, 16).to_bytes(length=32, byteorder='little')

print( sha256(sha256(htob(H_a)+htob(H_b)).digest()).digest().hex()[::-1] )

가 맞습니다. https://www.blockchain.com/btc/block/63480 에 들어가면 옛날 거래수가 적었던 실제 블럭을 통해 검증할 수 있습니다.

2021.12.27. 19:16
질문에 대한 답을 알고 계신가요?
지식을 나누고 포인트를 획득해보세요.
답변하고 포인트 받기