"이거 진짜 너가 보낸 트랜잭션 맞아?"
시작하기 전에
이 글은 블록체인에 타원곡선이 어떤 식으로 이용되는지에 초점을 둔 글 입니다. 주제의 특성상 너무 기술적으로 들어가는 부분들이 있는데요. 원래 어려울 수 있는 내용이기 때문에 *경보* 표시를 따로 해두었습니다. 읽다가 이해가 안되더라도 실망하시지 마시고 이건 좀 기술적인 내용이군~ 하고 가볍게 읽어주시면 감사하겠습니다. :)
#1. 타원곡선을 경험해 본 적이 있나요?
밑에 나오는 세 가지 사례에 경험이 있는지 생각해보세요.
i) 내 이더리움 지갑주소를 잃어버렸었는데, 다행히도 개인 키(private key)를 통해서 다시 내 지갑주소를 찾은 경험이 있으신가요?
ii) 솔리디티를 개발하면서 이런 함수를 본 적이 있으신가요? ecrecover, ecsign
iii) 혹시 이더리움의 트랜잭션에서 v, r, s라고 적혀있는 값의 정체에 대해 궁금해 해보신 적이 있으신가요?
위의 경우 중 단 하나라도 경험이 있으시다면 당신은 이미 타원곡선을 이용하신 경험이 있으신 것입니다! :)
보신 것 처럼 위의 사례 외에도 타원곡선을 이용한 여러 사례들이 있는데요, 블록체인에서의 타원곡선의 역할은 아주 명확하고 간단합니다.
"이거 진짜 니가 한 거 맞어?"
#2. 이거 진짜 니가 한 거 맞어? (디지털서명)
"이거 진짜 니가 한 거 맞어?" 를 좀 더 기술적인 용어로 바꿔보면 "디지털 서명"이 됩니다.
디지털 서명이란?
A 라는 사람이 개인 키를 이용해서 내가 보내려는 데이터에 서명을 하고, 받은 사람은 A의 공개 키를 이용하여 그 서명이 진짜 A의 서명인지 확인하는 기술을 말합니다. *경보*
그러면 블록체인에서 이 디지털 서명이란게 왜 필요한걸까요?
바로 트랜잭션 때문입니다. (트랜잭션 용어가 생소하시다면 "트랜잭션과 상태변경" 이라는 글을 참고해주세요.)
이더리움에서의 트랜잭션은 송신자, 수신자, 보낼 양, 수수료, 데이터 등등의 정보를 기입해넣게 되어있는데요.
트랜잭션을 간단한 형태로 보여드리면 우측과 비슷하게 생겼습니다.
송신자가 비탈릭으로 되어있으니, 아까 말했던 디지털 서명 기술에 적용해보면 "야 비탈릭~! 이 트랜잭션 너가 보낸거 맞아?" 가 되겠네요.
비탈릭이 벙찔만도 합니다. 저런 종이 쪼가리(실제로는 컴퓨터 상의 데이터 쪼가리겠죠?)에
"송신자: 비탈릭" 이렇게 쓴다고 해서 비탈릭의 잔고에 있는 이더를 전혀 모르는 사람에게 보낼 수 있다는 것은 이상하죠. 결국 이 종이 쪼가리(트랜잭션)의 진위 여부가 중요합니다.
그렇기 때문에 종이쪼가리에 최소한의 싸인(서명)이라도 있어야 되는거고, 이 싸인은 "이 종이 쪼가리(트랜잭션)에 쓰여진 송신자가 진짜 나에요." 라는 의미를 담아야 됩니다.
그렇다면 단순한 싸인이면 될까요?
#3. 트랜잭션에 쓸 싸인(서명)은 어떤 형태를 가져야하는가?
이 싸인의 형태는
i) 보내는 사람, 즉 송신자만이 가지고 있는 자기만의 고유한 특수 볼펜(개인 키)로만 싸인(디지털 서명)을 만들어 낼 수 있어야 하며
ii) 싸인(디지털 서명)을 받은 사람이 손쉽게 이 싸인이 송신자의 것이 맞다는 것을 확인할 수 있어야 합니다.
위 두 가지 조건을 만족해야 실제로 트랜잭션에 쓸 수 있는 형태의 싸인이 될 것 입니다.
그리고 바로, 이 형태의 싸인을 만들 수 있는 기술이 '타원곡선'입니다.
기존에 블록체인 기술에 관심이 있으시거나, 암호화폐 투자를 해보셨다면, 개인 키(private key), 공개 키, 지갑 주소 같은 용어들을 들어보셨을 것입니다.
이 타원곡선을 알고나면 드디어 얘네들의 진짜 정체에 대해서 알게 되실 것입니다. 그런데 안타깝게도.. 얘네의 근원을 만든 분들이 수학자분들이셔서 조금의 수학을 아주 얕게라도 짚고 넘어가야합니다.
#4. 타원곡선 수학
0) 타원곡선 방정식 - 수학에서의 타원곡선이란?
타원곡선은
의 방정식을 만족하는 곡선입니다. *경보*
1) 점과 점의 덧셈 (타원곡선의 덧셈 연산 ex: P + Q )
어렵지 않습니다! 점 P와 점 Q를 더하는 방법은
얘네들을 잇는 직선을 쭉 긋고, 나머지 교점 (R) 의 x축대칭을 시키게 되면 그 점이 바로 P+Q의 점입니다.
2) 점에 상수를 곱하기 (타원곡선의 곱셈 ex: 2P )
위에 덧셈연산을 이해하셨다면 이것도 어렵지 않습니다! '2P' 즉, P에 2라는 상수를 곱한다는 의미는
결국 P + P 이기 때문에, P와 P를 잇는 직선(위의 그림 참조)과 나머지 교점(R)의 x축대칭을 시키게 되면 그게 2P입니다. 그렇다면 3P는? 3P는 2P + P 이기 때문에, 우리가 찾은 점 2P와 점 P의 덧셈연산을 진행하면 그 것이 바로 3P입니다.
#5. 비트코인과 이더리움에서 사용되는 타원곡선
사실 위에서 보신 #4. 타원곡선 수학은 정말 수학적으로 타원곡선을 다루는 것을 보신 것이고, 다시금 글의 목적을 다잡아보면 우리는 이것을 가지고 "이거 진짜 너가 보낸 트랜잭션 맞아?"를 가능하게 하는 것에 관심이 있는 것입니다.
사실 이것을 하려면 송신자와 수신자, 아니 블록체인을 이용하는 모든 사용자들이 공통적으로 타원곡선위의 어느 한 점을 알고있어야 합니다. 바로 이 점을 타원곡선의 기준점(base point), G 라고 부릅니다.
여기서 잠시, 너무 일반적인 타원곡선에 대해서 계속해서 얘기해나가는 것은 와닿지도 않고, 재미가 없으니까, 진짜 이더리움, 비트코인에서 쓰이는 타원곡선을 가지고 이야기를 해보겠습니다.
아까 #4. 타원곡선 수학에서 타원곡선의 방정식을 봤습니다.
여기서 a와 b에 어떤 값을 주더라도 당연히 얘는 타원곡선입니다.
암호학자들은 이렇게 a와 b에 어떻게 값을 주느냐, 또 여기에 추가적으로 방금 언급한 타원곡선의 기준점 G의 좌표가 무엇이냐에 따라 타원곡선에 별명을 붙여주는데요,
이더리움과 비트코인에 사용되는 타원곡선은
으로, a가 0이고 b가 7이며 기준점 G가 *경보* "02 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798"인 타원곡선을 말합니다. 별명이라고 해서 부르기 쉬운 이름은 아니고 "SECP256K1"이라는 심각하게 암호학자 티를 내는 별명을 가지고 있습니다.
#6. 타원곡선으로 "이것 진짜 너가 보낸거 맞아?"를 확인하는 스텝
이제 모든 준비가 다 끝났습니다. 이제 이 타원곡선 SECP256K1을 가지고 "이 트랜잭션 너가 보낸 것 맞니?"를 할것인데요. 완전 처음부터 스텝바이스텝으로 해보겠습니다.
우선 서명을 보내는 쪽과 서명을 받아서 검증하는 쪽의 스텝으로 나눌 것인데요. 먼저 서명을 보내는 쪽의 스텝입니다.
싸인(서명)을 보내는 사람의 절차
- 보내는 쪽의 GOAL: 서명을 만들어서 트랜잭션과 함께 보낸다. 서명을 만드는 것이 보내는 쪽의 GOAL입니다!
1. 종이 쪼가리(트랜잭션)를 만든다.
2. 나만의 서명용 볼펜(개인 키)을 타원곡선이 지정해주는 범위 내에서 정한다.
- 사실 서명용 볼펜(개인 키)라는 것은 1 ~ n - 1 까지의 정수 중 하나입니다. 즉 개인키는 그냥 단순히 숫자입니다.
*경보* 여기서 n은 SECP256K1 타원곡선 하에서 1.157920892373162e+77 라는 값으로 정의되어있는데,
16진수로 표현하면 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141입니다. 즉, 개인키는
1 ~ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140 까지의 숫자의 범위 중 하나를 골라서 쓰는 것입니다. 주의할점은 1 ~ n까지의 범위가 아니라, 1 ~ n - 1 까지의 범위라는 것입니다. 그래서 FFFF....4141 에서 1을 빼서 FFFF....4140 까지의 범위입니다. 이 범위를 벗어나면 이더리움에서 올바르지 않은 개인 키라고 에러를 뱉는데요, 확인해보고 싶으시면 마이이더월렛 페이지에서 위의 범위를 초과하는 값을 개인키로 줘보세요. "올바르지 않은 개인 키입니다." 라는 에러를 볼 수 있습니다.
여튼 개인 키(숫자)를 정해보죠! 지금 글을 쓰고 있는 시간이 201808180457 이니까 앞 자리는 그냥 F으로 채워놓고 맨 뒤를 저 숫자로 채우겠습니다. 16진수로 표현해보면 이렇게 되겠습니다.
'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF201808180457'
제 개인키입니다.
다음 스텝에 들어가기 앞서, 우리는 지금 싸인을 만드는 작업을 하기 위해서 스텝을 밟고 있습니다. 그런데 사실 우리가 만드는 서명은 사실 2개가 필요한데요. 첫 번째 찾을 싸인을 서명 r, 두 번째로 찾을 싸인을 서명 s 라고 부르겠습니다.
3. 서명 r 찾기
여기서 조금 특이한 것을 하는데요, 아까 우리가 개인 키를 골랐을 때 처럼 1 ~ n - 1 범위의 정수를 '랜덤하게' 하나 더 고릅니다. 개인 키는 한번 고르면 평생 그 키만 쓰는데에 비해서, 이 값은 트랜잭션을 보낼 때 마다 랜덤하게 선정해서 골라야 합니다. 당연히 여러분이 직접 고르는 것은 아니고 컴퓨터가 지 맘대로 랜덤하게 뽑아서 넣어줍니다. 이 값을 k라고 하는데요. 얘를 구했으면 서명 r을 구해낼 수 있습니다.
k * G
(k 곱하기 기준점 G)
혹시 어디서 한 번 본 식 아닌가요? 맞습니다. #4. 타원곡선 수학에서 보았던 타원곡선에서 "점에 상수를 곱하기"입니다. 점에 상수를 곱해도 타원곡선위의 점이 되는 것을 우리는 위에서 학습했습니다. 이 점의 x 좌표가 바로 우리가 찾는 서명 r 입니다.
4. 서명 s 찾기
얘는 좀 복잡합니다. 그냥 바로 공식으로 보겠습니다.
서명 s는 이렇게 찾을 수 있습니다. 하나 하나씩 떼어서 볼까요.
k - k는 우리가 아까 랜덤하게 선택했던 그 값입니다.
z - 우리가 만든 트랜잭션 정보가 담긴 값입니다.
r - 우리가 찾았던 서명 r 입니다.
private key - 우리가 정한 개인키입니다. 아까 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF201808180457' 를 선택했었죠.
mod n - n 으로 나눈 나머지라는 뜻입니다.
공식을 직접 값을 넣어가며 연산하는 것은 이 글의 목적과 맞지 않으니, 핵심만 보겠습니다.
핵심은 이것입니다. "어쨌든 서명 s를 만드는데에 내 개인키를 써서 만들었다."
이제 보내는 쪽은 끝났습니다. 트랜잭션을 전송하면 됩니다.
종이쪼가리(트랜잭션)과 싸인(서명r 과 서명 s)을 보냅니다.
싸인(서명)을 받는 사람의 절차
- 받는 쪽의 GOAL: 받은 서명을 통해서 "이거 진짜 너가 보낸거 맞아?"를 확인한다.
*받는 사람의 절차는 매우매우 간단하지만 매우매우 복잡한 식 한 줄로 끝납니다. 따라서 보고 그냥 받아들여주시면 되겠습니다. :)
1. 다음 식의 결과가 받은 서명 r과 같은지 비교한다.
끝입니다.
저 위에 나와있는 식은 사실 분해해보면 또 타원곡선의 연산인데요, 결국 결과가 '타원곡선 위의 점'이 나오게 되는데 그 점의 x 좌표가 내가 받은 서명 r과 같은지 비교하면 됩니다.
*경보* 식 자체가 좀 어려운데요, 이건 정말 완전히 몰라도 되는 내용입니다만 조금 분해해보겠습니다.
w, U1, U2의 값은 각각 위와 같이 정의됩니다. 식을 연산하는것은 중요하지 않고 결국 핵심은 내가 받은 서명 s를 이용해서 뭔가를 하고 있다. 내가 받은 트랜잭션 정보가 담긴 z를 가지고 뭔가를 하고 있다. U2를 보면 내가 받은 서명 r을 이용해서 뭔가를 하고 있다. 정도만 파악하시면 됩니다.
그리고 마지막 나오는 Public Key의 정체는 무엇일까요? 바로 보낸 사람의 공개키인데요.
그런데, 우리가 아까 보내는 사람의 스텝에서 공개키라는 것을 보낸 적이 있었나요?
그렇다면 받는 사람은 대체 공개키가 어디서 난걸까요?
*경보* 사실 공개키는 보내는 사람 측에서 줄 수도 있지만 이더리움에서는 그렇게 하지 않습니다.
원래 '공개 키'라는 것은 '복구 키'를 이용하면 구할 수 있는데요. 이더리움에서는 얘를 '27 혹은 28'이라는 값으로 약속하자. 라고 해두었기 때문에 쉽게 서명만 가지고도 복구키를 이용해서 보낸 사람의 공개키를 추출해 낼 수 있습니다. 이 복구 키를 v 라고 합니다.
복잡한 수학 식이 많습니다만 결국 핵심은 명확하게 받은 서명과 트랜잭션을 가지고 "공개 키"를 이용해서 이 서명을 검증했다는 것입니다.
#7. 절차 정리
이제 정말 모든 과정이 끝났는데요. 과정을 복기하면서 타원곡선이 어떻게 쓰였는지 정리해보겠습니다.
보내는 사람 절차
1. 트랜잭션을 만든다 - 타원곡선이 사용되지 않습니다.
2. 개인 키를 정한다 - 타원곡선 SECP256K1 에 의해 정해진 범위 내에서 골라야 하니 타원곡선이 이용된다고 볼 수 있습니다.
3. 서명 r을 만든다 - 랜덤 값 k가 타원곡선 SECP256K1에 의해 정해진 범위 내에서 골라야 하니 타원곡선이 이용된다고 볼 수 있습니다.
4. 서명 s를 만든다 - 서명 s는 서명 r을 이용해서 만들기 때문에 결국 얘도 타원곡선을 이용합니다.
받는 사람 절차
1. " U1 * G + U2 * 공개키 " 의 x 좌표를 구해서 서명 r의 값과 같은지 비교한다. - 언급을 하진 않았지만 개인키는 단순히 숫자인 반면 공개키는 사실 타원곡선 위의 점입니다. 그렇게 놓고 보면 "U1 * G + U2 * 공개키"는 사실 타원곡선의 점의 연산이라고 볼 수 있습니다. 즉 타원곡선이 이용됩니다.
#8. 마치며
그럼 맨 처음에 #1. 타원곡선을 경험해 본 적이 있나요? 라는 사례들을 하나하나씩 각개격파 하면서 글을 마무리 짓도록 하겠습니다.
i) 내 이더리움 지갑주소를 잃어버렸었는데, 다행히도 개인 키(private key)를 통해서 다시 내 지갑주소를 찾은 경험이 있으신가요?
=> 개인 키는 타원곡선 SECP256K1에 의해 범위가 한정지어진 단순한 정수중 하나라고 했습니다. 하지만 이 개인 키에는 특수한 힘이 있는데요. 바로 타원곡선의 기준점 G와 곱하게 되면 어느 한 점이 나오게 되는데, 사실 그것이 바로 공개키입니다. 아까 트랜잭션을 보낼 때 공개키를 따로 보내지 않았었는데, 굳이 보내고 싶다면 이런 식으로 개인 키 * G 를 해서 나온 공개키를 같이 실어보내줄 수도 있습니다. 물론 안 보낸 경우에는, 앞서 말했듯 받는 사람이 서명과 v 값을 가지고 공개키를 추출해내게됩니다.
또 하나, 사실 우리가 쓰고 있는 이더리움 지갑 주소는 공개키를 통해 만들 수 있는데요. 아주 간단합니다.
공개키의 가장 오른쪽으로 부터 40자리를 짜르면 그것이 바로 우리의 이더리움 지갑주소입니다.
이렇게 보면 왜 이더리움 지갑주소를 잃어버렸어도 개인 키만 있으면 지갑주소를 찾아내는지 파악이 가능하시죠? 개인키 -> 공개키 -> 공개키에서 오른쪽 40자리만 추출 -> 지갑주소 이 흐름이 가능하기 때문에 개인키만 있어도 모든 것을 다시 찾아낼 수 있는 것입니다. :)
ii) 솔리디티를 개발하면서 이런 함수를 본 적이 있으신가요? ecrecover, ecsign
=> ecsign은 앞서 언급했던 '보내는 사람이 서명을 만드는 절차'에서 하는 행위와 같으며, ecrecover는 '받는 사람이 서명을 통해 연산한 식의 x 좌표가 서명 r과 같은지 확인하는 절차와 같습니다.' 즉, ecrecover나 ecsign은 모두 타원곡선을 이용한 사례라고 할 수 있습니다.
iii) 혹시 이더리움의 트랜잭션에서 v, r, s라고 적혀있는 값의 정체에 대해 궁금해 해보신 적이 있으신가요?
트랜잭션에 있는 r, s는 사실 앞서 얘기했던 서명 r과 서명 s 입니다. 또 v는 '복구 키'로 이더리움에서는 보통 27아니면 28이라는 값으로 하기로 약속되어 있습니다.
그럼 지금까지 엄청나게 길고 머리아픈 주제일수도 있는 '타원곡선'. 실제로 블록체인에서는 어떻게 적용되는 것일까? 에 대해서 알아보았습니다. 감사합니다. :)
#9. 부록 - 코드로 살펴보기.
저는 사실 개발자이다보니까 글로 이해하는 것보다 코드를 보면서 완전히 제 눈으로 직접 경험하는걸 좋아해서 위의 과정을 코드레벨로 정리를 해보겠습니다. 개발자가 아니더라도 드래그 쳐져있는 부분만 가볍게 읽어주시면 될 것 같습니다.
0. 타원곡선 SECP256K1을 가져온다. (컨텍스트: 타원곡선 - elliptic)
드래그 한 부분만 봐주시면 됩니다. a값이 0, b 값이 7, 그리고 n 값이 엄청나게 큰 숫자로 정의되어있으며, 그 곡선에 대해서 'secp256k1' 이라는 이름으로 정의(define)했다는 코드입니다.
1. 보내는 사람이 트랜잭션을 만든다.
from - 송신자입니다.
to - 수신자입니다.
value - 보낼 금액의 양입니다.
gasPrice - 수수료입니다. (사실 gasPrice * usedGas 가 정확한 수수료이긴 합니다만 넘어가겠습니다.)
data - 보낼 데이터입니다.
2. 보내는 사람이 개인키를 정한다. (이것은 코드상에서 정한다기보다는 해당범위 내에서 직접 고르는 숫자이기 때문에 코드를 따로 보진 않겠습니다.)
3. 서명 r, s를 만든다. (컨텍스트: 타원곡선 - elliptic)
3-1. 1 ~ n - 1 범위의 임의의 값 k를 구한다.
3-2. k와 타원곡선의 기준점 G를 곱한다. (k * G)
3-3. k * G 점의 x 좌표를 구한다.
3-4. k * G 점의 x 좌표를 서명 r로 한다.
3-5. k^-1 * (z + r * 개인 키) mod n 식을 연산한다.
드래그 되어서 하이라이트 되어있는 부분들과 주석만 보시면 됩니다. k는 랜덤한 값을 뽑아낸다고 하였는데, 드래그 되어있는 영역 세번째 줄을 보시면 drbg.generate라는 함수가 있습니다. 바로 이 값이 랜덤한 값을 뽑아주는 애입니다. 앞서 글에서 이 k 값은 개인 키와는 달리 우리가 직접 정하는 값이 아니라고 했었습니다. 바로 이렇게 컴퓨터에서 랜덤하게 뽑아서 줍니다.
4. 트랜잭션을 전송한다. (컨텍스트: web3)
4-1. 이더리움의 JSON-RPC 전송용 클라이언트 web3를 이용해 web3.eth.sendTransaction
함수를 호출한다.
4-2. 개인 키를 이용해서 트랜잭션에 서명한다. (코드의 깊이에 따라 설명하다보니 순서가 뒤바뀌었는데, 서명하면서 3.서명 r, s를 만든다 에서 보여드렸던 그 코드를 실행하게 됩니다.)
web3-core-method/src/index.js 에 있는 sendRequest 함수를 호출하게 된다.
4-3. 서명절차를 끝내고 트랜잭션을 RPC 콜을 통해서 이더리움 노드로 전송한다.
5. 트랜잭션을 받는다. (컨텍스트: go-ethereum - 이더리움 노드)
5-1. web3에서 날린 RPC 콜(eth_sendRawTransaction)을 통해 트랜잭션을 전송하면서, 전송된 트랜잭션 데이터와 함께 go-ethereum의 internal/ethapi/api.go의 SendRawTransaction 함수가 호출되게 된다.
이 함수는 submitTransaction 함수를 호출한다.
5-2. internal/ethapi/api.go의 submitTransaction 함수가 호출되면서 eth/api_backend.go의 SendTx 함수를 호출하게 된다.
5-3. eth/api_backend.go의 SendTx 함수가 호출되면서 core/tx_pool.go의 AddLocal 함수를 호출하게 된다.
5-4. core/tx_pool.go의 AddLocal 함수가 호출되면서 core/tx_pool.go의 addTx 함수가 호출된다.
5-5. core/tx_pool.go의 addTx 함수가 호출되면서 pool.add 함수를 호출합니다.
5-6. core/tx_pool.go의 add 함수가 호출되면서 pool.validateTx 함수를 호출합니다.
5-7. core/tx_pool.go의 validateTx 함수가 호출되면서 crypto/types/transaction_signing.go의 Sender 함수를 호출합니다.
5-8. crypto/types/transaction_signing.go의 Sender 함수가 호출되면서 같은 파일에 있는 EIP155Signer Sender를 호출합니다.
5-9. crypto/types/transaction_signing.go에 있는 EIP155Signer Sender 함수가 호출되면서 같은 폴더에 있는 recoverPlain 함수를 호출합니다.
5-10. crypto/types/transaction_signing.go에 있는 recoverPlain 함수가 호출되면서 crypto/signature_cgo.go의 Ecrecover 함수를 호출합니다.
5-11. crypto/signature_cgo.go의 Ecrecover 함수를 호출하면서 crypto/secp256k1/secp256.go 에 있는 RecoverPubKey 함수를 호출하게 됩니다.
5-12. crypto/secp256k1/secp256.go의 RecoverPubKey 함수를 호출하면서 C.secp256k1_ext_ecdsa_recover 함수를 부르게 됩니다.
드디어 C 코드까지 호출하면서 거의 최종 함수를 부르게 되는데요. 이 함수까지 오면서 트랜잭션 풀에 트랜잭션을 넣거나 등등의 과정이 있었지만 글 주제 자체가 타원곡선, 디지털 서명이다보니까 다 무시하고 한 길로 쭉 왔습니다. 이 함수에 데이터로 온 것은
1) 공개키 - &pubkey[0]
2)서명 r, s - sigdta
3) 트랜잭션입니다. - msgdata
이제 이 재료들이 있으니
이 식을 계산해서 "이 트랜잭션 진짜 너가 보낸거 맞아?" 를 할 수 있게 됩니다.
참 먼길을 왔는데요, 결국 우리는 트랜잭션의 생성부터, 서명이 들어가는 시기, 라이브러리 코드, 서명을 검증하는 시기, 그에 해당하는 내용까지 모두 코드레벨로 살펴 보았습니다.
고생하셨습니다!!
참고한 글)
http://www.secg.org/sec2-v2.pdf
http://nlitsme.github.io/posts/2014-06-19-ecdsa-explanation/
https://www.reddit.com/r/Bitcoin/comments/1nvsn7/elliptic_curve_secp256k1_vulnerability/
https://www.instructables.com/id/Understanding-how-ECDSA-protects-your-data/
http://kowon.dongseo.ac.kr/~lbg/web_lecture/it/lec5/lec5.htm