본문 바로가기
Block Chain/Web3 Series

[Wallet Series #1]이더리움의 디지털 서명과 타원곡선 함수

by 개발이 체질인 나그네 2023. 4. 11.
반응형

안녕하세요. 스마트컨트렉트 개발자 최원혁입니다.

오늘 블록체인 회사 면접을 보고왔습니다. 스스로 많이 부족한 점을 느낄 수 있었던 계기가 됬네요... 기술 질문에서 답변하지 못하거나 논리정연하게 답하지 못한 내용이 있습니다. 그중 하나가 solidity의 ecrecover에 대한 내용이였습니다.

이를 이해하기 위해선 이더리움이 활용하는 디지털 서명과 타원 곡선 함수에 대한 이해가 필요했습니다. 오늘 공부하면서 정리한 내용을 적어볼까합니다.

 

# 1. 디지털 서명 이란?

디지털 서명이란 내가 만든 데이터를 내가 만들었음을 증명하는 기술입니다.

EXAMPLE : 
    {
        nonce: ‘0xc9’,
        gasPrice: ‘0x4a817c800’,
        gasLimit: ‘0x61a80’,
        from:'영애',
        to: '철수',
        value: ‘100이더’,
        data: ‘0xd08773616e746f6e7982697384636f6f6c’,
        chainId: 3
    }

블록체인의 트랜잭션에는 위와 같은 데이터가 담겨 있습니다. 데이터로 봤을 때, 영애가 철수에게 100 이더를 전송하는 내용 같습니다.

하지만 트랜잭션 데이터가 정말로 영애가 작성한게 맞는지는 검증되지 않습니다. *저는 '원혁'이지만 from에 '영애'를 적어 영애가 보낸것처럼 꾸며낼 수도 있겠네요.

그렇기 때문에 해당 데이터에 '영애'의 싸인(서명)을 적어 '영애'가 작성한 데이터임을 증명하는것이 디지털 서명의 역할입니다.

하지만 단순히 자기 싸인(서명)만 적었다고 해서 끝나면, 검증의 의미가 없겠죠. 디지털 서명이 어떻게 디지털적으로 이를 증명하고 검증하는지 지금부터 알아보겠습니다.

 

 

#2. 이더리움의 타원 곡선 함수란?

디지털 서명의 과정을 추가로 설명드리자면, A라는 사람이 '개인키'를 이용해서 내가 만든 데이터에 서명을 하고, 데이터를 검증하는 사람은 A라는 사람의 '공개키'를 통해 진짜로 A라는 사람이 서명한게 맞는지 검증을 합니다.

 

개인키와 공개키를 통해 위와 같은 검증과정을 만들 수 있는 이유는 바로 '타원 곡선 함수' 때문입니다.

ECDSA(Eliptic Curve Digital Signature Algorithm)의 타원 곡선 함수 : 
ECDSA(Eliptic Curve Digital Signature Algorithm) 타원 곡선 함수는 암호학에서 사용되는 공식이며, 암호화된 데이터를 다시 복호화할 수 없는 해시 암호 함수중 하나입니다.

ECDSA 타원 곡선 함수

 

타원 곡선 함수는 생성점 G(Generator Point:생성점)에 따라 활용도가 달라집니다.

이더리움과 비트코인은 a=0 b=7을 대입하여 G = 02 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798 로 정의했습니다.

secp256k1 타원 곡선 함수

이렇게 G값이 정의된 타원곡선 함수에 secp256k1라는 칭호를 붙혀 사용하고 있습니다.

서명과 검증절차를 위한 개인키와 공개키는 secp256k1 타원 곡선 함수의 영향을 받습니다. 지금부터 각 절차에 어떤 영향을 받는지 알아보겠습니다.

 

# 3. 개인키를 활용한 서명 과정

우리가 서명을 위해 사용하는 개인키의 생성 원리를 잠깐 알아보겠습니다.

이더리움은 기본 운영체제의 난수 생성기(RNG : Random Number Generator)를 통해 1 ~ 1.157920892373162e+77 사이의 숫자중 하나를 무작위로 선택합니다. 그리고 선택한 숫자를 16진수로 표현하면 우리가 사용하는 개인키가 됩니다.

1 ~ 1.157920892373162e+77의 범위는 SECP256K1 타원곡선 하에 정의된 범위입니다. 실제로 이 범위를 벗어난 개인키를 이더리움에서 사용하게되면 "올바르지 않은 기인키"라는 애러를 볼 수 있습니다. 이는 마이이더월렛에서 확인할 수 있습니다.

개인키는 지갑주소를 찾아 낼 수 있고, 해당 지갑주소의 주인행세를 할 수 있기 때문에, 절때 공개되선 안되는 데이터입니다.

공개키 = 개인키 * G(생성점)

때문에 개인키를 직접 적어서 서명하지 않고, 이를 통해 두가지 서명(r,s)을 만들어서 사용합니다.

 

· 서명 r 만들기

서명 r을 만들기 위해, 개인키를 생성했던것 처럼 1 ~ 1.157920892373162e+77사이에서 무작위로 정수 하나를 고릅니다. 이 값을 k라고 하겠습니다.

타원 곡선 함수는 특별한 특성이 존재합니다. 바로 함수 곡선 위의 점에 상수를 곱하면, 무조건 곡선 위의 어느 한점이 나타나게 됩니다.

r값은 이런 타원 곡선 함수의 특성을 이용해 곡선위의 한 점 G와 랜덤으로 생성한 정수 k를 곱하여 곡선위의 한점을 알아냅니다. 그리고 그값의 x축 좌표가 바로 r이 됩니다.

 

 

· 서명 s 만들기

서명 s 공식

  • k : 서명 r만들때 생성된 랜덤 숫자
  • z : 트랜잭션 데이터를 RLP 인코딩한 값
  • r : 서명 r 값
  • p : 개인키(Private Key)

서명 s 값은 간단하게 위 공식을 통해 생성됩니다. 여기서 핵심은 서명 s를 개인키를 활용하여 만들었다는 점입니다.

이는 곡선 위의 한점을 활용했다는 뜻이며, 나중게 공개키를 활용하여 검증단계에서 활용됩니다.

 

# 4. 공개키를 활용한 서명 검증 과정

· 복구키 v

사용자가 트랜잭션을 전송할 때, 서명s, 서명r 그리고 복구키 v를 트랜잭션에 포함한 후 RLP 인코딩하여 전송합니다.

여기서 사용자가 보낸 트랜잭션에는 공개키가 포함되어 있지 않습니다. 대신 v(공개키 복구키) 값을 같이 전달하여 공개키를 복구할 수 있도록 합니다. EIP-155에서 v는 다음과 같이 정의했습니다.

v = CHAIN_ID * 2 + 35 OR v = CHAIN_ID * 2 + 36

이는 메인넷 기준으로 37 OR 38이 나옵니다. 또한 0 + 27 또는 1 + 27을 사용하기도 합니다.

 

· 서명 검증

사용자가 보낸 서명이 진짜 본인이 작성한 서명인지 검증하는 과정은 간단합니다.

서명 검증 공식

  • w = s⁻¹ mod n
  • U1 = z * w mod n
  • U2 = r * w mod n

공개키가 포함된 위 공식의 값과 r의 값이 같으면 당사자가 서명한 데이터가 맞다는 사실이 검증됩니다.

 

 

# 5. Solidity ecrecover란?

Solidity에는 ecrecover라는 함수를 지원합니다. 여기서 ecrecover는 위에서 서명 검증 과정을 실행해주는 함수입니다.

공식 문서를 보면 함수 파라미터로 RLP 인코딩된 해쉬(hash)와 서명데이터 v,r,s를 넣게 되있습니다. 복구키 v를 통해 공개키를 얻어 서명을 검증하고, 만약 검증이 성공했으면 공개키 주소를 리턴하고, 실패했다면 zero address를 리턴합니다.

 

| Solidity ecrecover 공식문서

 

Units and Globally Available Variables — Solidity 0.8.0 documentation

Warning If you use ecrecover, be aware that a valid signature can be turned into a different valid signature without requiring knowledge of the corresponding private key. In the Homestead hard fork, this issue was fixed for _transaction_ signatures (see EI

docs.soliditylang.org

 

# 5. 한줄 정리 :

1. 디지털 서명이란 내가 만든 데이터를 내가 만들었음을 증명하는 기술

2. 디지털 서명을 위해 ECDSA 타원 곡선 함수를 활용

3. 이더리움은 ECDSA 타원 곡선 함수 중 secp256k1를 사용

4. secp256k1를 통해 개인키와 서명에 필요한 s, r 서명 값 생성

5. 서명 s, r와 공개키를 복구하는 복구키 vRLP인코딩하여 트랜잭션 전달

6. 검증자는 복구키v를 통해 공개키 복구 후, s,r,공개키를 활용하여 서명 검증

 

 

지금까지 이더리움에서 사용하는 디지털 서명과 타원 곡선 함수에 대해 알아봤습니다. 감사합니다.

 


Reference :

| 타원곡선과 블록체인 by. 김훈일

| [ethereum] 개인키와 공개키 그리고 트랜잭션 서명 by. 멍개.

반응형

댓글