Argon2id 작업 증명 해설

· 읽는 데 8분

이 글에서는 Argon2id가 무엇인지, Blocknet이 이를 어떻게 작업 증명으로 사용하는지, 왜 빠른 메모리가 많을수록 유리한지, 그리고 seine가 실행되는 CPU마다 어떻게 최대한 많은 해시를 끌어내는지 설명합니다.

Argon2id란 무엇입니까?

짧은 답변

Argon2id는 비밀번호 해싱과 작업 증명을 위해 RFC 9106에 정의된 메모리 하드 해시 함수입니다. 넓은 메모리 영역을 1 KiB 블록으로 채우는데, 각 블록은 바로 앞 블록과 메모리의 다른 곳에서 고른 이전 블록으로 만들어집니다. 그래서 해시 하나를 계산하는 데 프로세서 시간뿐 아니라 실제 메모리도 필요합니다.

IRTF의 Crypto Forum Research Group이 2021년에 발표한 RFC 9106은 “비밀번호 해싱과 작업 증명 용도를 위한 Argon2 메모리 하드 함수”를 설명합니다. Argon2에는 세 가지 변형이 있습니다.

내부적으로 Argon2는 메모리를 1,024바이트 블록이 길게 이어진 것으로 다룹니다. 새 블록은 두 입력, 즉 바로 앞 블록과 메모리 앞쪽의 참조 블록에 압축 함수 G를 적용한 결과입니다. G는 BLAKE2b 해시 함수의 혼합 라운드를 바탕으로 하며, 64비트 워드에 대해 덧셈, XOR, 회전 연산을 수행합니다.

Blocknet은 Argon2id를 어떻게 작업 증명으로 사용합니까?

Blocknet은 합의 코드에서 Argon2id의 모든 설정을 고정하므로, 모든 채굴기와 모든 노드가 정확히 같은 함수를 계산합니다.

매개변수 Blocknet 값 의미
변형 Argon2id, 버전 1.3 RFC 9106의 기본 변형
메모리 2 GiB (2,097,152 KiB) 해시마다 1 KiB 블록 2,097,152개를 채움
반복 1 메모리에 대한 패스 1회
병렬도 1 레인 하나, 따라서 해시 하나가 스레드 하나에서 실행
출력 32바이트 목표값과 비교하는 값
비밀번호 8바이트 논스, 리틀 엔디언 채굴기가 시도할 때마다 바꾸는 숫자
솔트 논스를 뺀 블록 헤더 해시를 하나의 블록 템플릿에 묶음

채굴은 탐색입니다. 채굴기는 게시하려는 블록 헤더를 가져와 논스를 하나 고르고 Argon2id 해시를 계산합니다. 32바이트 결과를 숫자로 읽었을 때 네트워크의 목표값 이하이면 블록이 유효합니다. 그렇지 않으면 다음 논스를 시도합니다.

목표값은 난이도에서 바로 나옵니다. (2^256 − 1)을 난이도로 나눈 값입니다. 따라서 난이도는 블록 하나를 찾기 위해 네트워크 전체가 계산할 것으로 예상되는 해시 수와 거의 같습니다. Blocknet은 5분마다 블록 하나를 목표로 하므로, 네트워크 해시레이트는 대략 난이도를 300초로 나눈 값입니다. 난이도 자체는 60블록 가중 이동 평균을 통해 최근 블록 시간을 따라갑니다.

채굴 풀도 같은 방식으로 동작하며, 목표값만 더 쉽습니다. bntpool.com에서 seine는 연결별로 정해진 더 낮은 난이도를 충족하는 셰어를 제출하며, 그중 네트워크 목표값까지 충족하는 셰어가 곧 찾은 블록입니다.

메모리 하드 작업 증명은 왜 일반 컴퓨터에 잘 맞습니까?

위 설정은 메모리를 모든 해시의 중심에 둡니다. 패스 1회, 레인 하나이므로 패스의 후반부는 데이터에 의존합니다. 각 블록의 참조 위치는 바로 앞에서 계산한 블록의 첫 64비트 워드에서 정해집니다. 채굴기는 어떤 이전 블록이 필요할지 그 순간이 되어야 알 수 있으므로 2 GiB 영역 전체를 메모리에 유지합니다.

채굴기가 블록을 덜 저장하고 빠진 블록을 필요할 때 다시 계산하려 할 수도 있습니다. RFC 9106은 이를 시간-메모리 트레이드오프라고 부릅니다. 메모리를 아끼는 대신 “내부 압축 함수를 더 많이 호출하는 비용”을 치르는 방식입니다. 영역에서 뺀 블록 하나하나마다 추가 연산이라는 대가를 다시 치러야 합니다.

바로 이 점이 이 설계를 일반 하드웨어에 친화적으로 만듭니다. 데스크톱, 노트북, 서버는 이미 수 기가바이트의 RAM과 이를 공급하도록 만든 메모리 컨트롤러를 갖추고 있습니다. 해시 계산 전용으로 설계한 칩도 해시 코어 옆에 수 기가바이트의 빠른 메모리가 필요합니다. RFC 9106의 첫 번째 권장 설정은 2 GiB 메모리에 대한 패스 1회의 Argon2id로, Blocknet이 쓰는 패스 횟수와 메모리 크기와 같으며, RFC는 이 설정이 “전용 무차별 대입 하드웨어에 대한 공격자 비용을 최대화한다”고 말합니다. Blocknet의 데몬 코드는 이 선택을 “ASIC에 저항하고 공정한 채굴을 보장하기 위한” 메모리 하드 작업 증명이라고 설명합니다. Argon2id는 ASIC에 저항하도록 설계되었고 2 GiB 설정이 그 설계를 실제로 작동시키므로, 사람들이 이미 가진 컴퓨터로도 계속 채굴할 수 있습니다. 스테이킹과의 비교는 작업 증명과 지분 증명 가이드에서 설명합니다.

왜 RAM과 메모리 대역폭이 해시레이트를 결정합니까?

짧은 답변

채굴 스레드마다 자체 2 GiB 영역을 사용하므로, RAM 용량이 실행할 수 있는 스레드 수를 정합니다. 또한 해시마다 2 GiB를 쓰고 거의 같은 양을 여러 위치에서 다시 읽으므로, 메모리의 속도와 지연 시간이 스레드의 처리 속도를 정합니다. 메모리는 코어 수만큼 중요합니다.

RAM이 스레드 수를 정합니다. 병렬도 1은 해시 하나가 스레드 하나에서 실행된다는 뜻이고, 스레드마다 전용 2 GiB 영역이 통째로 필요합니다. 16 GB 컴퓨터는 시스템용 여유를 남기고 대략 6~7개의 스레드를 돌릴 수 있습니다. seine는 메모리를 측정해 5%를 예비로 남기고 스레드 수를 대신 정해 줍니다.

대역폭과 지연 시간이 스레드별 속도를 정합니다. 해시 하나는 새 블록 2,097,152개를 만들고, 블록마다 영역 어딘가에서 1 KiB 참조 블록을 읽습니다. 계산하면 해시마다 약 2 GiB를 쓰고 약 2 GiB를 읽습니다. 10 H/s라면 컴퓨터가 매초 약 40 GiB의 데이터를 메모리로 주고받는 셈입니다. 데이터 의존 구간에서는 앞 블록이 끝나야 다음 읽기 주소를 알 수 있으므로, 메모리가 응답하는 시간이 순수 처리량만큼 중요합니다.

그래서 seine의 성능 페이지는 해시레이트가 “코어 수만큼이나 메모리 대역폭과 지연 시간에 좌우된다”고 설명합니다. Blocknet 채굴 하드웨어 가이드에서 하드웨어 세대별 최고 결과를 볼 수 있습니다.

휴즈 페이지가 도움이 되는 것도 같은 이유입니다. 2 GiB 영역은 일반 4 KiB 페이지로 524,288개, 2 MiB 페이지로는 1,024개에 해당합니다. 페이지가 더 적고 크면 흩어진 읽기에서 주소 변환 미스가 줄어들며, seine의 검증 머신에서 약 4–6%의 향상이 있었습니다. 설정 방법은 휴즈 페이지 가이드에 있습니다.

seine의 CPU 커널은 Argon2id를 어떻게 최대한 활용합니까?

커널은 블록을 계산하는 내부 루프입니다. seine의 x86 빌드에는 스칼라, AVX2, AVX-512 커널과 스트리밍 변형이 들어 있고, Arm 빌드에는 SHA3 고속 경로를 갖춘 NEON 커널이 들어 있습니다. 각 커널은 메모리가 병목인 작업을 서로 다른 방식으로 공략합니다.

저희가 테스트한 하드웨어에서는 알맞은 커널을 고르는 것만으로 큰 차이가 났습니다. 다음은 seine 성능 페이지에 실린, 같은 컴퓨터와 같은 스레드 수로 짝지어 측정한 결과입니다.

컴퓨터 커널 변경 향상
AWS Graviton4 (Neoverse V2), 16 스레드 NEON에서 프리페치 적용 SHA3로 +56% (13.80 → 21.50 H/s)
AWS Graviton3 (Neoverse V1), 16 스레드 NEON에서 프리페치 적용 SHA3로 +45% (12.52 → 18.17 H/s)
AMD EPYC 9R45 (Zen 5), 24 스레드 AVX2에서 스트리밍으로 +30% (34.47 → 44.74 H/s)
Intel Xeon 8375C (Ice Lake), 1–4 스레드 AVX2에서 AVX-512로 +21–29%

이 중 어느 것도 직접 고를 필요가 없습니다. seine는 CPU가 지원하는 커널을 실제 채굴 작업으로 비교하고, 성능 향상이 두 번 확인된 뒤에만 전환하며, 가장 빠른 커널을 캐시해 다음 실행 때 사용합니다. 최적의 커널은 스레드 수, 페이지 크기, CPU 배치에 따라 달라지므로, seine는 선택을 코드에 고정하지 않고 사용자의 컴퓨터에서 직접 측정합니다.

내 메모리로 채굴하려면 seine를 다운로드해 실행하고 주소를 붙여 넣으세요. 나머지는 채굴 가이드에서 안내합니다.

자주 묻는 질문

Blocknet은 작업 증명에 어떤 Argon2id 매개변수를 사용합니까?

Blocknet은 Argon2id 버전 1.3을 2 GiB 메모리, 반복 1회, 병렬도 1, 32바이트 출력으로 실행합니다. 8바이트 논스가 비밀번호이고, 논스를 뺀 블록 헤더가 솔트입니다. 해시가 네트워크 난이도로 정해진 목표값 이하이면 블록을 찾은 것입니다.

Blocknet 채굴 스레드 하나에 왜 2 GB의 RAM이 필요합니까?

Argon2id 해시 하나는 1 KiB 블록으로 이루어진 2 GiB 영역을 채우며, 그 패스의 후반부에서는 새 블록마다 채굴기가 예측할 수 없는 데이터로 고른 이전 블록을 읽습니다. 스레드는 영역 전체를 메모리에 유지해야 하므로 스레드 하나당 약 2 GB의 RAM이 필요합니다.

Argon2id는 왜 ASIC에 저항하도록 설계되었습니까?

Argon2id는 모든 해시에서 메모리를 가장 비싼 요소로 만듭니다. Blocknet 해시 하나에는 2 GiB의 빠른 메모리가 필요하고 그 안에서 수 기가바이트의 데이터가 오가므로, 해시 계산 전용 칩도 코어마다 많은 RAM이 필요합니다. 데몬 코드는 이 선택을 ASIC에 저항하고 공정한 채굴을 보장하기 위한 메모리 하드 작업 증명이라고 설명합니다.

그래픽 카드로 Blocknet의 Argon2id를 채굴할 수 있습니까?

네. Windows와 Linux에서 seine는 CPU와 동시에 컴퓨터의 모든 NVIDIA 그래픽 카드로 채굴하며, 해시레이트가 합산됩니다. 커널은 시작할 때 컴파일되고, 첫 실행에서 카드마다 튜닝한 결과를 캐시하므로 시작 전에 설정할 것이 없습니다.