[마스터링 이더리움] 4장: 암호학

728x90

 

  • 이더리움의 기반 기술 중 하나는 수학의 한 분야인 암호학(Cryptography)
    • 단순히 암호화(encryption)하는 것 이상으로 비밀을 밝히지 않고 비밀의 지식을 증명하거나, 데이터의 진위성을 증명하는 데 사용가능
  • 영지식 증명 (zero knowledge proof)
  • 동형 암호화 (homomorphic encryption)
  • 이번 장에서 개인키와 주소의 형태로 자금의 소유권을 제어하는 데 사용되는 공개키 암호화(Public Key Cryptography, PKC)에 대해서 배울 게 될 것

 

키와 주소

  • EOA의 경우, 아래 3가지를 통해 이더 소유권을 확립한다.
    • 디지털 개인키(private key)
    • 이더리움 주소(Ethereum address)
    • 디지털 서명(digital signature) → 개인키를 사용하여 생성하고 개인키의 소유권을 증명
  • 계정 주소는 개인키에서 직접 파생되고, 개인키는 계정이라고도 불리는 단일 이더리움 주소를 고유하게 결정
  • 이더리움 시스템에서 개인키를 직접 사용하진 않음
    • 개인키는 비공개로 유지되어야 하고, 네트워크로 전달된 메세지나 체인에 저장되어서도 안된다.
    • 계정 주소와 디지털 서명만이 이더리움 시스템에 전송되고 저장된다.
  • 이더리움은 공개키 암호화 기반 시스템으로 개인키(계정 제어권)공개키(계정 식별)로 구성된 쌍으로 제공한다.
  • 개인키 자체는 이더리움 사용자에게 드러나는 경우가 거의 없다. 대부분 암호화된 형태의 특수 파일로 저장한다.
  • 트랜잭션의 지급 부분에서 지정된 수신자는 이더리움 주소로 표현하는 데 이건 공개키 부분에서 생성한다.

 

공개키 암호화와 암호화폐

  • 공개키 암호화 = 비대칭 암호화
  • 공개키 암호화는 고유한 키를 사용하여 정보를 보호
    • 트랩 도어 함수(trapdoor function)를 바탕으로 디지털 비밀과 위조 불가능한 디지털 서명 만듦
💡 트랩 도어 함수란?
계산하기는 쉽지만 그 역을 계산하기는 어려운 함수로,
역산하기 위한 단축키로 사용할 수 있는 비밀 정보(트랩도어)가 없으면 거꾸로 계산하기 어려운 함수

예) 8018009는 두 소수의 곱셈이다. 두 수소를 찾아라. → 어려움
소인수 중 하나가 2003이다. → 트랩도어가 주어졌으므로 나머지 소인수도 쉽게 찾을 수 있음 (8018009/2003 = 4003)
  • 암호학에서 좀 더 발전된 범주의 수학 함수는 타원 곡선의 산술 연산을 바탕으로 함
    • 타원 곡선 산술에서 소수로 나눈 나머지를 곱하는 것은 간단하지만, 나눗셈(역함수)는 사실상 불가능
    • 이것을 이산 로그 문제(discrete logarithm problem)이라고 하며, 현재 알려진 트랩도어 없음
    • 현재 이더리움에서 개인키와 디지털 서명을 사용하는 기초가 됨
  • 공개키는 개인키에서 파생되므로 공개키+개인키 = ‘키쌍’으로 간주
    • 대부분 지갑 구현에서 개인키와 공개키는 키 쌍(key pair)로 함께 저장.
    • 공개키는 개인키로부터 간단하게 계산될 수 있으므로 개인키만 저장하는 것도 가능.
  • ‘키쌍’은 공개적으로 접근할 수 있는 계정 핸들(주소)과 계정의 이더에 대한 접근 권한, 스마트 컨트랙트를 사용할 때 계정이 필요로 하는 모든 인정에 대한 사적 제어권을 제공함으로써 이더리움 계정을 나타냄
  • 개인키는 계정에서 자금을 지출하기 위해 트랜잭션에 서명해야 하는 디지털 서명(digital signature)을 만드는 데 필요한 고유한 정보의 접근을 제어
  • 이더리움 트랜잭션은 트랜잭션 자체의 세부사항이 메시지로 사용되고, 타원 곡선 암호화는 메시지를 개인키와 결합하여 개인키를 알아야만 만들 수 있는 코드 생성 방법을 제공한다. 이 코드를 디지털 서명이라고 한다.

참고: 공개키 암호(Public Key Cryptography)

 

 

개인키

  • 개인키는 …
    • 단순히 무작위로 선택한 숫자
    • 트랜잭션에 쓰이는 자금의 소유권을 증명함으로써 이더를 소비하는 데 필요한 서명을 만드는 데 사용
    • 잃어버리면 되찾을 수 없으며, 해당 키로 확보한 자금도 영원히 잃어버리게 됨

 

난수로 개인키 생성

  • 키를 생성하는 가장 중요한 첫 번째 단계는 엔트로피, 즉 무작위성을 확보하는 것이다.
  • 이더리움에서 개인키를 생성하는 것은 기본적으로 1에서 2^256 사이의 숫자를 선택하는 것이라고 볼 수 있다.
    • 따라서 숫자 선택이 예측 가능하거나 결정적(deterministic)이라면 문제가 된다.
  • 이더리움 소프트웨어는 기본 운영체제의 난수 생성기(RNG, Random Number Generator)를 사용하여 256개의 임의 비트를 생성한다. 일반적으로 OS 난수 생성기는 사람이 무작위의 소스가 되어 초기화되므로 본인이 난수를 생성할 때, 몇 초 동안 마우스를 움직이거나 키보드에서 임의의 키를 누르라는 요청을 받게 되는 것이다. 혹은 컴퓨터의 마이크로폰 채널에서 나오는 우주 방사선 노이즈가 대신할 수도 있다. ▶️ 여기 페이지(비트코인 난수 생성기)를 통해 알 수 있음.

 

  • 개인키는 0이 아니고 2^256보다 약간 작은 (절대적으로 봤을 때는 매우 큰) 숫자까지 가능하다.
    • 참고: 78자리 숫자이며 대략 1.158*10^77까지 가능.
    • 정확하게 말하면 앞 38자리는 2^256의 앞 38자리와 똑같고, 이더리움에서 사용된 타원 곡선의 규칙으로 정의한다.
  • 비공개키를 생성하기 위해 256비트 숫자를 무작위로 추출하여 유효한 범위 내에 있는 지 확인한다.
    • 어떻게 256 비트 숫자를 추출하냐?
    • (암호학적으로 안전한 소스에서 수집한) 일반적으로 더 긴 임의의 비트 문자열을 Keccak-256 또는 SHA-256 같은 256비트 해시 알고리즘에 넣고 돌려서 나온 결과(256비트의 숫자)가 유효한 범위 내에 있다면 개인키로 채택하고 아니라면 다른 숫자로 다시 시도한다.
  • 개인키 생성 프로세스는 오프라인 프로세스다. 따라서 아무도 선택할 수 없는 숫자를 선택하려면 정말로 무작위적이어야 한다.
    • 프로그래밍 언어에 있는 대부분의 의사 난수 rand 함수는 무작위적이지 않음.

 

공개키

이더리움 공개키는 타원 곡선에 있는 점으로 타원 곡선 방정식을 만족하는 x와 y 좌표의 집합을 의미한다.

  • 즉, 함께 결합된 2개의 숫자이고이는 개인키로부터 ‘단방향으로만’ 계산할 수 있다.
💡 공개키 계산
공개키는 비가역적인 타원 곡선 곱셈을 사용하여 개인키로부터 계산된다.
  K = k * G  
▶️  k는 개인키,
▶️ G는 생성자 점, generator point라고 불리는 상수,
▶️ K는 결과로 나오는 공개키
▶️ * 은 특수 타원 곡선 ‘곱하기’ 연산으로 일반적인 곱셈과 같지 않다.
‘이산 로그 찾기(K를 알고 k를 계산)’하는 것은 가능한 모든 k값을 시도하는 것만큼 힘듦(우주가 허용하는 것보다 더 많은 시간이 걸리는 무차별 대입 탐색)

✅ 타원 곡선에 대한 산술 연산은 ‘정규’ 정수 연산과 다르다. 나눗셈 같은 연산이 존재하지 않으므로 공개키 K를 G 점으로 간단히 ‘나누어서’ 개인키 k를 계산할 수 없다.
✅ 공개키 암호화를 할 때 사용하는 단방향 수학 함수이다. 

타원 곡선 곱셈은 암호학자가 ‘단반향’ 함수라고 부르는 함수 유형이다. 한 방향(곱하기)으로는 수행하기 쉽고 반대 방향(나누기)으로는 수행하기가 어렵다.

 

이 수학적 트릭은 이더리움 자금의 소유권과 계약 관리를 입증하는 위조 불가능하고 안전한 디지털 서명의 기초가 된다.

 

타원 곡선 암호화 설명

타원 곡선 암호화는 타원 곡선의 점에 더하기와 곱셈으로 표현되는 이산 대수 문제를 바탕으로 한 비대칭 또는 공개키 암호화 유형이다.

타원 곡선

 secp256k1  곡선은 타원 곡선을 생성하는 아래 함수(두 가지 동치)로 정의한다.

타원 곡선 함수

  • mod p는 이 곡선이 Fp(소수 차수 p의 유한체) 상에 있음을 나타냄. 여기서 p는 매우 큰 소수 
  • 이 곡선은 2차원으로 흩어져 있는 점들의 패턴처럼 보이지만 헤아릴 수 없을 만큼 큰 좌표에서 훨씬 더 복잡한 점 패턴으로 생각할 수 있다.

 

타원 곡선 산술 연산

비특이 타원 곡선 성질 (블록체인에서 사용하는 타원이 비특이 타원)

  1. 타원 곡선에서는 위와 같이 첨점(sharp point), 교차점(intersection point)이 존재하면 안 된다.
  2. 반드시 x축과 대칭하는 y값이 존재한다.
  3. 임의이 두 점 P와 Q를 연결하는 직선은 타원곡선 위의 또 다른 점을 포함한다. (즉, 총 세 개의 점이 직선 위에 존재)

첨점(왼)과 교차점(오)의 예시

  • 타원 곡선에 두 점 P1, P2가 주어지면 세 번째 점 P3 = P1 + P2가 타원 곡선 위에 있도록 타원 곡선 덧셈을 정의한다.
    • 즉, 모든 P는 타원 곡선 위에 있음.
    • 기하학적으로 이 세 번째 점 P3은 P1과 P2 사이에 선을 그려서 계산한다. 이 선은 점P와 점Q를 제외하고 정확하게 타원 곡선과 하나의 점에서 교차하게 된다. (1 & 2번 성질)
    • 이 점을 P’ = (x,y)라고 하면, 이 점을 x축 대칭시킨 점 (x,-y)가 P3가 된다. (3번 성질)

🔽 그림으로 덧셈의 정의에 대해서 자세히 알아보면

타원 곡선 덧셈의 정의 설명

  • P, Q가 타원 위의 점이라고 한다. (위 정의에서 P1, P2에 해당)
  • a의 경우, P, Q는 타원 위에 있는 서로 다른 점이다.
    • 이 경우는 위에서 설명한 거처럼 두 점 P, Q를 잇는 직선이 다른 타원곡선과 만나는 점인 -R을 x축 대칭시킨 R이 P3이다.
  • b의 경우, P와 Q는 동일한 점이다.
    • 이 경우, 두 점을 잇는 선분은 타원의 접선이 되고 이 접선은 마찬가지고 타원 곡선의 다른 한 점 (-R)과 교차하게 되고, 이 점을 x축 대칭시킨 점 R이 P3가 된다.
  • c의 경우, P와 Q는 x축에 서로 대칭인 점이다.
    •  무한대 점 이라는 개념이 필요하다
💡 무한대 점이란?
 ▶️ 어떤 직선이 y축과 평행할 때 만나는 점을 무한점이라고 한다.
 ▶️ 만나는 점이 없이 무한대로 뻗어나가서 그 점을 무한점이라고 정의한 것이다.
 ▶️ 이 점은 간략하게 숫자 0의 역할을 한다.
    • 이 경우, Q = -P 이므로, P + Q = P + (-P) = 0 이고, 두 점을 잇는 직선은 y축에 평행하다.
    • 따라서 이 때, P3은 무한대 점이 된다.
    • 만일 어떤 점이 무한대 점이라면 그 점은 0으로 취급가능하다.
      • 예를 들어, P1이 무한대 점일 경우, P1 + P2 = P2 라는 결과가 도출된다.

덧셈을 정의했으므로 이를 확장해 곱셈을 정의해보면, k*P = P + P + P + …+ P (k번 반복)이 된다.

 

 

공개키 생성

위에서 언급했던 공개키 계산  K = k * G  을 보면, 무작위로 생성한 숫자 k 형태의 개인키로 시작해 생성자 점 G라고 하는 곡선의 미리 결정된 점에 개인키를 곱하여 곡선 상의 다른 점, 즉 대응하는 공개키 K를 생성한다.
(타원곡선의 성질에 의해 곱셈은 덧셈의 확장이고, 덧셈을 통해 타원 곡선 위의 다른 점 생성 가능.)

  • 생성자 점은 scep256k1 표준의 일부로 지정되어 있다.
  • scep256k1의 모든 구현에서 동일하며, 해당 곡선에서 파생된 모든 키는 동일한 점 G를 사용한다.
  • 즉, 생성자 점은 모든 이더리움 사용자에 대해 항상 동일하기 때문에 공개키를 구하는 과정은 모두 동일하다.

하지만 k(개인키)에서 K(공개키)로 단방향 계산만 가능하고, 역방향 계산은 불가능하기 때문에 이런 이유로 이더리움 주소(K에서 파생된 공개키)를 모든 사람과 공유할 수 있다. 
** K = k * G 는 단방향 함수이기 때문

계산 실습은 생략 (2회독에 할 것)

 

 

 

타원 곡선 라이브러리

암호화폐와 관련된 프로젝트에 사용되는 scep256k1 타원 곡선을 구현한 것이 몇 가지 있음

아래 참고:

 

 

암호화 해시 함수

암호화 해시 함수는 이더리움 전반에 걸쳐 사용되고, 거의 모든 암호학적 시스템에서 광범위하게 사용되고 있다.

  • 해시 함수는 어디서 사용하는 가?
    • 이더리움 공개키를 주소로 변환하는 작업에서 해시 함수가 일부분을 차지함.
    • 데이터 확인에 도움이 되는 디지털 지문을 만드는 데 사용할 수도 있음
  • 해시 함수란?
    • 임의 크기의 데이터를 고정된 크기의 데이터로 매핑하는 데 사용할 수 있는 모든 함수
    • 입력 : 하위 3개 중 하나
      • 사전 이미지 (pre-image)
      • 메시지 (message)
      • 입력 데이터 (input data)
    • 결과 = 해시 (hash)
  • 암호화 해시 함수(cryptographic hash function)란?
    • 이더리움 같은 플랫폼을 보호하는 데 유용한 특정 속성을 갖는 해시함수의 특별한 하위 범주
    • 임의 크기의 데이터를 고정 크기의 비트 열로 매핑하는 단방향 해시 함수
    • 단방향 해시 함수인 이유는 결과값 해시만 알고 있을 때, 입력 데이터를 다시 작성하는 것이 계산적으로 불가능하기 때문이다.
    • 가능한 입력을 결정하는 유일한 방법은 각 후보에 일치하는 결과가 있는 지 확인하면서 무차별 대입 검색을 수행하는 것인데, 검색 공간이 사실상 무한하기 때문에 이는 불가능하다고 판단됨.
    • 만약 하나, 일치하는 해시를 만든 일부 입력 데이터를 찾는다고 해도 원본 입력 데이터가 아닐 가능성이 큼. 
      • 해시함수는 ‘다대일’ 함수이기 때문에 해시 충돌이 발생한다.
💡 해시 충돌이란?
▶️ 다른 입력값이어도 동일한 해시값이 결과로 나와서 결과 해시값이 충돌하는 것.
▶️ 예를 들어, A와 B를 각각 해시함수에 넣었는데 둘 다 C라는 해시를 얻은 것.
▶️ 좋은 해시 함수일 수록 충돌이 덜 발생하고, 이더리움의 경우 충돌이 발생하지 않는다.

 

  • 암호화 해시 함수의 주요 속성
    • 결정론(determinisim) - 주어진 입력 메시지는 항상 동일한 해시 결과를 생성한다. (같은 입력에는 항상 같은 결과값)
    • 검증성(verifiability) - 메시지의 해시 계산은 효율적이다. (선형 복잡도를 가짐.)
    • 비상관성(noncorrelation) - 메시지에 대한 작은 변화(1비트 변화일지라도) 결과값은 매우 크게 달라지기 때문에 원본 메시지의 해시와는 전혀 달라짐.
    • 비가역성(irreversibility) - 해시(결과값)으로부터 메시지(입력값)을 계산하는 방법은 무차별 검색을 제외하고는 없다. 즉, 불가능하다.
    • 충돌 방지(collision protection) - 같은 해시 결과를 생성하는 2개의 서로 다른 메시지를 계산하는 것은 불가능하다.

해시 충돌에 대한 저항은 이더리움에서 디지털 서명 위조를 피하기 위한 중요한 속성이다.

 

위와 같은 속성을 이용해 다음과 같은 보안 애플리케이션을 만들 수 있다 :

  • 데이터 핑거프린팅
  • 메시지 무결성(오류 감지)
  • 작업증명
  • 인증(암호 해싱 및 키 스트레칭)
  • 의사 난수 생성기
  • 메시지 커밋 (커밋-공개 메커니즘)
  • 고유 식별자

 

 

이더리움의 암호화 해시 함수: Keccak-256

이더리움 재단은 NIST(미국 표준기술연구소)에서 수정한 SHA-3 표준이 아닌, 알고리즘의 발명가들이 제안한 대로 원래 Keccak(SHA-3) 알고리즘을 구현하기로 결정해서 사용 중이다.

  • SHA-3
    • FIPS-202 SHA-3 (최종 NIST 표준)
    • Keccak-256

알고리즘이 다르기 때문에 두 개는 동일한 입력에 대해 다른 해시 결과를 생성하고, 이더리움은 거의 Keccak-256을 참고한다.

 

 

 

어떤 해시 함수를 사용하고 있는가?

사용 중인 소프트웨어 라이브러리가 FIPS-202 SHA-3 와 Keccak-256 중에 어떤 것을 구현하는 지 알 수 있는 방법으로는 테스트 벡터(test vector)를 사용하는 방법이 있다.

 

해시 함수에 가장 일반적으로 사용되는 테스트는 빈 입력(empty input)이고, 아래와 같은 결과가 나온다. 

 

SHA3("") = a7ffc6f8bfled76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a

Keccak256("”) = a7ffc6f8bfled76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a

 

 

 

이더리움 주소

Keccak-256의 첫 번째 애플리케이션으로, 이더리움 주소는 Keccak-256 단반향 해시 함수를 사용하는 공개키 또는 컨트랙트에서 파생한 고유 식별자다.

 

이더리움 주소를 만드는 방법

  1.  K = k * G  공개키를 만드는 이 식을 통해 나온 16진수로 표시된 K 를 Keccak-256을 사용해 해시 계산을 진행한다.
    K = 6e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae…
    Keccak256(K) = 2a5bc342ed616b5ba5732269001d3f1ef827552ae1114027bd3ecf1f086ba0f9
  2. 그런 다음, 이더리움 주소인 마지막 20바이트(최하위 바이트)만 유지한다.
    001d3flef827552ae1114027bd3ecf1f086ba0f9
  3. 여기서 종종 이더리움 주소 앞에 0x가 붙어 16진수로 인코딩된 것을 볼 것이다.
    ▶️ 0x001d3flef827552ae1114027bd3ecf1f086ba0f9

 

 

이더리움 주소 형식

위에서 봤듯이, 이더리움 주소는 16진수이며, 공개키 Keccak-256 해시의 마지막 20바이트에서 파생한 식별자이다.

 

비트코인 주소 vs 이더리움 주소

  • 비트코인 주소: 모든 클라이언트의 사용자 인터페이스에 내장된 체크섬을 포함하여 잘못 입력된 주소를 보호하도록 인코딩됨
  • 이더리움 주소: 체크섬이 없는 원시 16진수
💡 초기에 체크섬이 없었던 이유
결국 시스템의 상위 계층에서 추상화(Name Service, 이름 서비스)에 숨겨지고 필요하다면 상위 계층에 체크섬을 추가해야 하기 때문

하지만.. 상위 계층의 개발이 너무 느려서 여러 문제가 발생

그에따라 대체 인코딩 옵션들이 나옴

 

 

 

클라이언트 주소 상호교환 프로토콜 (Inter Exchange Client Address Protocol)

클라이언트 주소 상호교호나 프로토콜은 인코딩 옵션 중에 하나로, 국제 은행 계좌 번호 (IBAN, International Bank Account Number) 인코딩과 부분적으로 호환되는 이더리움 주소 인코딩이다.

 

특징은 아래와 같다.

  • 이더리움 주소에 대해 다목적의 체크섬이 가능하고 상호운용 가능한 인코딩을 제공
  • 중앙 집중적이고 엄격하게 규제되는 IBAN에 비해, ICAP은 탈중앙화형이고 이더리움 주소에 대해 호환 가능

 

IBAN의 구성

  • 국가 코드, 체크섬 및 은행 계좌 식별자(국가별)를 포함하는 최대 34개의 영숫자(대소문 구분 없음)로 구성된 문자열

 

ICAP 주소는 이더리움 이름 레지스트리에 등록한 이더리움 주소 또는 일반 이름을 인코딩 할 수 있음

  • ‘이더리움’을 나타내는 비표준 국가 코드 ‘XE’를 도입한 후에 두 문자 체크섬계정 식별자의 세 가지 가능한 변형을 도입하여 동일한 구조를 사용 :
    • 직접(Direct)
      • 이더리움 주소의 최하위 비트 155개를 나타내는 최대 30자의 영숫자로 구성된 빅엔디안(big-endian) base36 정수다.
      • 이 인코딩 방법은 이더리움 전체 주소 160비트(20 byte*8 = 160 bits)보다 적기 때문에 하나 이상의 0바이트(8비트가 빠지는 셈)로 시작하는 이더리움 주소에서만 동작한다.
      • 장점: 필드 길이와 체크섬 측면에서 IBAN과 호환
      • 인코딩하면 33자.
    • 기본(Basic)
      • 직접 인코딩과 동일하지만 길이는 31자다. 이렇게 하면 이더리움 주소를 인코딩할 수 있지만 IAN 필드 유효성 검사와 호환되지는 않는다.
      • 인코딩하면 35자.
    • 간접(Indirect)
      • 이름 레지스트리 공급자를 통해 이더리움 주소로 확인되는 식별자를 인코딩한다.
      • 자산 식별자(asset identifier, 예: ETH), 이름 서비스(예: XREG) 및 사람이 읽을 수 있는 9자의 이름으로 구성된 16개의 영숫자를 사용한다.
      • 예) XE##ETHXREGKITTYCATS (##은 계산된 2개의 체크섬 문자)

ICAP는 불행히도 몇 가지 지갑에서만 지원한다.

 

 

 

대문자로 16진수 인코딩된 체크섬(EIP-55)

ICAP과 네임 서비스의 느린 배포 때문에 이더리움 개선 제안(EIP)에서 EIP-55 표준을 제안했다.

  •   EIP-55  
    • 16진수 주소의 대소문자를 수정하여 이더리움 주소에 대해 이전 버전과 호환되는 체크섬을 제공한다.
    • 이더리움 주소는 대소문자를 구분하지 않으며, 모든 지갑은 해석의 차이 없이 대문자 또는 소문자로 표현된 이더리움 주소를 수용해야 한다는 것.

지갑 주소의 전달 오류로 발생할 수 있는 문제를 개선한 것으로 이전 이더리움 주소를 그대로 사용하기 때문에 호환 가능하다.

주소의 알파벳 대소문자를 수정함으로써 입력의 무결성을 보호하기 위해 사용할 수 있는 체크섬을 전달할 수 있다.

 

아래 두 주소를 보자면 차이가 매우 미묘해서 인식하기 힘들지만 끝에서 2번째 f가 소문자와 대문자로 다른 것을 확인할 수 있다.

즉, 일부 인코딩된 알파벳 문자는 대문자고 나머지는 소문자다.

 

0x001d3f1ef827552ae1114027bd3ecf1f086ba0f9

0x001d3F1ef827552Ae1114027BD3ECF1f086bA0F9

 

EIP-55는 어떻게 구현하는 가?

소문자 16진수 주소에 대해 한 번 더 Keccak-256 해시를 사용함으로써 해당 해시는 주소의 디지털 지문 역할을 해 편리한 체크섬을 제공한다.

 

자세한 순서는 아래와 같다.

 

1. 0x 접두어 없이 소문자 주소를 해시 처리한다.

Keccak256("001d3f1ef827552ae1114027bd3ecf1f086ba0f9") = 23a69c1653e4ebbb619b0b2cb8a9bad49892a8b9695d9a19d8f673ca991deae1

2. 해시와 해당 16진수를 비교했을 때, 해시에 해당 하는 16진수가 0x8 이상인 경우, 각 알파벳 문자를 대문자로 만든다.

      Address  : 001d3f1ef827552ae1114027bd3ecf1f086ba0f9 
      Hash       : 23a69c1653e4ebbb619b0b2cb8a9bad49892a8b9....

  • 40자의 해시 중 첫 20바이트만 체크섬으로 사용한다.
  • 우리 주소의 4번째 파란색 d에 상응하는 해시는 6임을 알 수 있고 이는 8보다 작다. 따라서 소문자 d를 그대로 둔다.
  • 우리 주소의 6번째 빨간색 f에 상응하는 해시는 c임을 알 수 있고 이는 8보다 크다. 따라서 소문자 f를 대문자 F로 바꾼다.

 ➡️ 최종적으로 얻는 주소 값은 다음과 같다:  001d3F1ef827552Ae1114027BD3ECF1f086bA0F9 

 

 

 

EIP-55로 인코딩된 주소의 오류 감지

EIP-55 주소가 오류를 찾는 데 어떻게 도움이 되는 지 살펴봅시다.

 

위에서 EIP-55로 인코딩한 001d3F1ef827552Ae1114027BD3ECF1f086bA0F9를 읽는데 있어 마지막에서 두번째 F를

다음과 같이 0x001d3F1ef827552Ae1114027BD3ECF1f086bA0E9 E로 잘못 읽었다고 가정해보자.

  • 지갑은 EIP-55를 준수하기 때문에 대소문자가 혼용됐음을 확인하고 주소의 유효성 검사를 한다.
    • 즉, 소문자로 변환하고 체크섬 해시를 계산해 처음에 전달받은 주소와 동일한지 확인한다.
Keccak256("001d3f1ef827552ae1114027bd3ecf1f086ba0e9") = 5429b5d9460122fb4b11af9cb88b7bb76d8928862e0a57d46dd18dd8e08a6927
  • 위에서 구한 해시로 주소를 대문자화 해본다.

       Address : 001d3f1ef827552ae1114027bd3ecf1f086ba0e9

       Hash      : 5429b5d9460122fb4b11af9cb88b7bb76d892886....

 

  • 빨간색 표시한 4번째 부분의 해시는 9임에도 불구하고 주소는 소문자 d라고 쓰여져있다.
  • 이는 잘못된 것으로 오류가 발생한 것으로 판단한다.
    즉, 입력한 주소의 대문자 사용은 계산된 체크섬과 일치하지 않으므로 주소가 변경되어 오류가 발생했다.
  •  
  •