Ch 4. Cryptography

업데이트:

Public Key Cryptography에 대해서 설명한다.

Key and Addresses

  • 두 가지 유형의 이더리움 계정
    • Externally Owned Account (EOA)
    • Contract
  • Private Key, Ethereum Address, Digitial signature
    • 위의 3가지를 이용해 이더 소유권 확립
    • 계정 주소는 개인키에서 파생
    • 개인키는 account라 불리는 단일 이더리움 주소 결정
  • Public Key: 계좌번호 / Private Key: PIN 번호
    • 계좌번호는 식별, PIN 번호는 제어

Public Key Cryptography and Cryptocurrency

  • 암호화는 소인수 분해 (prime factorization)에 기반
    • 8,018,009라는 두 소수의 결과를 제시했을 떄, 두 소수를 찾는것은 소수를 곱하는 것 보다 어려움
    • Trapdoor function: 단, 한쪽의 수라도 알면 쉽게 계산할 수 있음
  • 더 발전된 암호화는 타원 곡선 암호화 (elliptic curve cryptography)를 이용
    • 소수로 나눈 나머지를 곱하는 것은 간단
    • 역함수는 사실상 불가능
  • 개인키는 digital signature를 만드는데 필요한 고유한 정보의 접근을 제어
  • Digital signature는 소유자 또는 컨트랙트 사용자 인증

Private Key

  • 개인키는 자금의 소유권을 증명함으로써 Ether를 소비하는데 필요한 서명을 만드는데 사용
    • 개인키를 공개하는것은 모든 권한을 제 3자에게 넘기는 것

Generating a Private Key from a Random Number

  • 이더리움 개인키는 1에서 2^256 사이의 숫자를 선택
  • 현재로서 하나의 개인키를 무작위로 선택했을 떄 그것의 값을 추측할 수 있는 방법은 없음

Public Key

  • $K$를 구하기 위해서 $G$와 $k$를 연산하는 것은 쉬움
  • $K$와 $G$를 안다고 $k$를 구하기는 어려움 \(K=k*G\)
    • $K$ : public key
    • $k$ : private key
    • $G$ : Generator point
    • $*$ : special elliptic curve “multiplication” operator
  • 이것이 one-way methematical function

Elliptical Curve Cryptography Explained

  • 이더리움은 미국 표준기술연구소(National Institute of Standards and Technology, NIST)에서 제정한 secp256k1 표준에 따라 특정 타원 곡선과 수학 상수 집합을 사용

  • secp256k1 \(y^2 = (x^3+7) \; \text{over} \; (\mathbb{F}_p)\) or: \(y^2 \; \text{mod} \; p=(x^3+7) \; \text{mod} \; p\)
  • $\text{mod} \; p$ : 소수 $p$로 나눈 나머지
  • $\mathbb{F}_p$: 유한한 소수 $p$의 범위로 한정 지어줌
    • 그래서 curve가 무한하지 않고 유한함
  • $y^2$을 소수 $p$로 나눴을 때의 나머지와 $x^3+7$을 소수 $p$로 나눴을 떄의 나머지가 동일한 경우 point Q가 된다.

  • point가 eliptic curve 위에 있는 점임을 python으로 검증
      C:\Users\user>python
      Python 3.10.10 (tags/v3.10.10:aad5f6a, Feb  7 2023, 17:20:36) [MSC v.1929 64 bit (AMD64)] on win32
      Type "help", "copyright", "credits" or "license" for more information.
      >>> p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
      >>> x = 49790390825249384486033144355916864607616083520101638681403973749255924539515
      >>> y = 59574132161899900045862086493921015780032175291755807399284007721050341297360
      >>> (x ** 3 + 7 - y**2) % p
      0
    

Elliptic Curve Arithmetic Operations

  • 타원 곡선에서의 연산은 정수 산술과 흡사
    • + 연산자를 정의 가능
    • 덧셈을 특이하게 정의함
  • 타원 점의 집합 G는 아래의 조건을 만족 1) G에 속한 임의점 P, Q에 대해서 P+Q 또한 G에 속한다 2) (P+Q)+R=P+(Q+R) 3) ideal point 0이 있으며, P+0=0+P=P 4) Q가 P의 역원이면 P+Q=0 5) P+Q=Q+P

  • 앞서 덧셈이 정의 되었는데, 덧셈을 확장하여 곱셈을 정의 가능
    • G의 원소 P에 대해 k가 정수이면 k*P = P+P+P+…+P (k번 반복)

Generating a Public Key

\(K=k*G\)

  • $K$ : public key
  • $k$ : private key (Random generation)
  • $G$ : Generator point
    • Generator point는 secp256k1 표준의 일부로 지정
    • 모든 이더리움 사용자에 대해 G는 항상 동일
  • $*$ : special elliptic curve “multiplication” operator

Example of Public Key Generation

  • Public key를 다음과 같이 생성한다.
      K = f8f8a2f43c8376ccb0871305060d7b27b0554d2cc72bccf41b2705608452f315 * G
    
  • 이때 K는 다음과 같은 점으로 정의
      K=(x,y)
      x = 6e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b
      y = 83b5c38e5e2b0c8529d7fa3f64d46daa1ece2d9ac14cab9477d042c84c32ccd0
    
  • 이더리움에서는 130개의 serialization으로 공개키가 표시 |Prefix |Meaning|Length(byte counting prefix) | |——-|——————-|——————————-| |0x00 |무한대 |1 | |0x04 |압축되지 않은 지점 |65 | |0x02 |짝수 y의 압축된 점 |33 | |0x03 |짝수 x의 압축된 점 |33 |
  • 이더리움은 압축되지 않은 공개키만을 사용
    • 관련된 유일한 접두어는 04
    • Serialization은 공개키의 x와 y좌표를 연결
        04 + x좌표(32바이트/64(16진수)) + y좌표(32바이트/64(16진수))
      
  • 계산된 공개키는 다음과 같음
      04 + 
      6e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b + 
      83b5c38e5e2b0c8529d7fa3f64d46daa1ece2d9ac14cab9477d042c84c32ccd0
    

Elliptic Curve Libraries

암호화폐 관련 프로젝트에 사용되는 secp256k1 elliptic curve를 구현한 라이브러리들

  • OpenSSL
    • secp256k1의 전체 구현을 포함한 포괄적인 암호학적 기반요소 제공
  • libsecp256k1
    • Bitcoin Core에서 제작
    • Elliptical Curve 및 기타 암호화 기초 요소를 C언어로 구현
    • OpenSSL 대체를 위해 완전히 새로 작성

Cryptographic Hash Functions

  • Hash function: 임의 크기의 데이터를 고정된 크기의 데이터로 매핑하는 데 사용할 수 있는 모든 함수
    • 함수에 대한 입력(pre-image, message, input data)를 모두 hash로 매핑
  • 암호 hash function은 단방향 해시 함수
    • 사실상 일치하는 해시를 찾기는 불가능
    • 해시 함수가 좋을 수록 해시 충돌이 덜 발생
  • 특징
    • Determinism: 항상 동일한 해시 결과 생성
    • Verifiability: 메시지의 해시 계산은 효율적
    • Noncorrelation: 원본 메시지와 관계성이 없다
    • Irreversibility: 역으로 메시지를 계산해내는 것은 불가능
    • Collision protection: 사실상 같은 해시를 생성하는 2개의 메시지를 계산하는 것은 불가능

Ethereum’s Cryptographic Hash Function: Keccak-256

  • Keccak-256 : 국립 과학 기술 연구소(National Institute of Science and Technology)에서 개최한 SHA-3 암호화 해시 함수 경쟁 대회(SHA-3 Cryptographic Hash Function Competition)의 후보로 설계
    • Keccak은 우승한 알고리즘으로, FIPS202로 표준화 됨
    • 표준화 과정에서 난수 생성기 표준을 의도적으로 약화시켜 표준 난수 생성기에 백도어를 효과적으로 배치했다는 내부 고발
    • Ethereum은 원래 Keccak을 채택

Which Hash Function Am I Using?

  • 주어진 입력에 대해 예상되는 결과인 test vector를 이용
    • 가장 일반적으로는 empty input을 넣어서 확인 ``` Keccak256(“”) = c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470

    SHA3(“”) = a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a ```

  • Keccak-256과 표준 SHA-3 사이에서 해시 함수 차이로 인한 혼란이 있기 때문에 모든 opcode 및 라이브러리 sha3 인스턴스를 모두 keccak256으로 개명하기 위한 노력이 진행중이다. (ERC59)

Ethereum Addresses

  • 이더리움 주소는 Keccak-256 단방향 해시 함수를 사용하는 공개키/컨트랙트에서 파생한 고유 식별자이다.

  • 이전 예제는 개인키 k로 시작해서 공개키 K를 만듬
      k = f8f8a2f43c8376ccb0871305060d7b27b0554d2cc72bccf41b2705608452f315
      K = k * Gz
      K = 6e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b83b5c38e5e...
    
  • Keccak-256을 이용해 공개키의 해시를 계산
      Keccak256(K) = 2a5bc342ed616b5ba5732269001d3f1ef827552ae1114027bd3ecf1f086ba0f9
    
  • 이더리움의 최하위 20바이트를 유지한다
      001d3f1ef827552ae1114027bd3ecf1f086ba0f9
    
  • 종종 이더리움 주소가 접두어 0x로 표시
      0x001d3f1ef827552ae1114027bd3ecf1f086ba0f9
    

Ethereum Address Format

  • 공개키 해시의 마지막 20비트에서 파생된 식별자
  • 체크섬이 없는 원시 16진수
    • 이더리움의 주소가 결국 상위 계층에서 추상화에 숨겨짐
    • 필요하다면 상위 계층에 checksum 추가
  • 상위 계층이 너무 천천히 개발되어 초반의 생태계에 많은 문제점을 자아냄

Inter Exchange Cilent Address Protocol

  • 클라이언트 주소 상호교환 프로토콜(Inter exchange Client Address Protocol, ICAP)
    • 국제 은행 계좌 번호(International Bank Account Number, IBAN) 인코딩과 부분적으로 호환되는 이더리움 주소 인코딩
    • 이더리움 주소에 대해 다목적의 체크섬 가능
    • 상호운용 가능한 인코딩 제공
  • IBAN
    • 중앙 집중적
    • 은행 계좌 번호 식별을 위한 국제 표준
    • 국가코드/체크섬/은행 계좌 식별자 를 포함하는 34개의 문자열
  • ICAP
    • 이더리움을 나타내는 비표준 국가 코드 XE 도임
    • 두 문자 체크섬/계정 식별자의 세가지 가능한 변형 도입

Direct

  • 이더리움 주소의 최하위 비트 155개를 나타내는 최대 30자의 영숫자로 구성된 빅엔디안(big-endian) base36 정수
  • 장점: 필드 길이와 체크섬 측면에서 IBAN과 호환
  • 예: XE60HAMICDXSV5QXVJA7TJW47Q9CHWKJD (33자 길이)

Basic

  • 직접 인코딩과 동일하지만 길이는 31자
  • 이더리움 주소를 인코딩할 수 있지만 IBAN 필드 유효성 검사와 호환 X
  • 예: XE18CHDJBPLTBCJ03FE9O2NS0BPOJVQCU2P (35자 길이)

Indirect

  • 이름 레지스트리 공급자를 통해 이더리움 주소로 확인되는 식별자를 인코딩
  • 자산 식별자(asset identifier, 예: ETH), 이름 서비스(예: XREG) 및 사람이 읽을 수 있는 9자의 이름(예: KITTYCATS)으로 구성된 16개의 영숫자 사용
  • 예: XE##ETHXREGKITTYCATS (20자 길이)
    • ##은 checksum

Hex Encoding with Checksum in Capitalization (EIP-55)

ICAP와 네임 서비스의 느린 배포 때문에 EIP-55에서 표준을 제안했다.

  • 16진수 주소의 대문자를 수정하여 이전 버전과 호환되는 체크섬 제공
  • 이더리움 주소는 대소문자를 구분하지 않는다.
  • 모든 지갑은 해석의 차이 없이 대/소문자로 표현된 이더리움 주소를 수용
  • EIP-55 체크섬을 지원하는 지갑은 99.986%의 정확도로 오류 감지
# EIP-55 적용 전
0x001d3f1ef827552ae1114027bd3ecf1f086ba0f9

# EIP-55 적용 후
0x001d3F1ef827552Ae1114027BD3ECF1f086bA0F9
  • 16진수 인코딩 알파벳의 일부 알파벳(A~F) 문자는 대문자
  • 그 밖의 문자는 소문자

EIP-55 구현

  1. 0x 접두어 없이 소문자 주소 해시 처리
     Keccak256("001d3f1ef827552ae1114027bd3ecf1f086ba0f9") = 23a69c1653e4ebbb619b0b2cb8a9bad49892a8b9695d9a19d8f673ca991deae1
    
  2. 해시의 해당 16진수가 0x8 이상인 경우, 각 알파벳 문자를 대문자로 변환
     # 변환 전
     Address: 001d3f1ef827552ae1114027bd3ecf1f086ba0f9
     Hash   : 23a69c1653e4ebbb619b0b2cb8a9bad49892a8b9...
    
     # 변환 후
     Address: 001d3F1ef827552Ae1114027BD3ECF1f086bA0F9
     Hash   : 23a69c1653e4ebbb619b0b2cb8a9bad49892a8b9...
    

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

  1. 다음은 EIP-55로 인코딩된 이더리움 주소이다.
     0x001d3F1ef827552Ae1114027BD3ECF1f086bA0F9
    
  2. 주소를 읽는데 있어서 마지막 F를 E로 잘못 읽었다 가정한다.
     0x001d3F1ef827552Ae1114027BD3ECF1f086bA0E9
    
  3. 주소의 유효성 검사를 위해 소문자로 변환하고 checksum hash를 계산
     Keccak256("001d3f1ef827552ae1114027bd3ecf1f086ba0e9") = 5429b5d9460122fb4b11af9cb88b7bb76d8928862e0a57d46dd18dd8e08a6927
    
  4. 주소와 hash를 비교한다.
     001d3F1ef827552Ae1114027BD3ECF1f086bA0E9
     5429b5d9460122fb4b11af9cb88b7bb76d892886...
    
  5. 입력한 주소의 대문자 사용이 계산된 checksum과 일치하지 않음으로 오류가 발생했다.

Reference

카테고리:

업데이트:

댓글남기기