티스토리 뷰
1. 타원곡선 디지털 서명 알고리즘(ECDSA)
2. 타원곡선 사용 코드 예시
1. 타원곡선 디지털 서명 알고리즘(ECDSA)
타원곡선 디지털서명 알고리즘(ECDSA, Elliptic Curve Digital Signature Algorithm)은 타원곡선암호를 전자서명에 접목시킨 암호 알고리즘이다. 이는 비트코인, 이더리움 등의 암호화폐 거래 시 정당한 소유주만이 자금을 쓸 수 있도록 하기 위해 사용된다.
타원곡선 디지털서명 알고리즘은 1985년 닐 코블리츠(Neal Koblitz)와 빅터 밀러(Victor Miller)가 제안한 타원곡선암호(ECC, Elliptic Curve Cryptosystem)에 기반을 둔 전자서명 알고리즘이다.
블록체인 네트워크에서 트랜잭션을 주고 받을 때, 수신자가 인증자의 공개키로 메시지가 진짜인지 검증하기 위해서는 전자서명을 필요로 한다. 이 전자서명은 개인키로만 생성 가능하고 수신인이 트랜잭션에 쓰여있는 전자서명이 진짜 발신인의 전자서명이 맞는지 확인할 수 있어야 하는데, 이 두 조건을 고루 만족시키는 기술이 타원곡선암호이다.
비트코인과 이더리움에서 사용되는 타원곡선의 매개변수는 secp256k1으로 SEC(Serticom Research)에 정의되어 있다.
a = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000007
유한군 p값 = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F
private key 값 = n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141
기준점 G = 02 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798
위의 조건을 만족하는 타원 곡선 방정식은 아래와 같다.
y^2 = x^3 + 7
송신자가 서명을 생성해 보내는 절차는 다음과 같다.
- Step1 : 트랜잭션 만들기
- Step2 : 개인키를 타원곡선이 지정하는 범위 내에서 정하기
secp256k1에 정의되어 있는 범위 1 ~ FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364140 내에서 고른다. 이때 유의해야 할 것은 1 ~ n 까지의 범위가 아니라 1 ~ n-1 까지의 범위기 때문에 위에 적어둔 n 값의 마지막 D0364141까지가 아닌 D0364140까지이다.
- Step3 : 서명 r 구하기
기준점 G 값 중 랜덤한 수를 하나 고르고 그 숫자에 G를 곱해준다. 계산된 값이 서명 r이 된다.
- Step4 : 서명 s 구하기
서명 s를 구하는 공식은 아래와 같다.
k^-1(z + r * private key) mod n
k = 서명 r을 구할 때 고른 랜덤한 수
z = 트랜잭션 정보를 직렬 정렬한 값
r = 위에서 구한 서명 r값
private key = 개인키 값
이때 유의해야 할 것은 계산값은 0이 아닌 다른 값이어야 한다는 것이다. 만약 계산값이 0이 나오는 경우 난수 k를 새롭게 생성하고 다시 계산해야 한다.
수신자가 서명을 받고 검증하는 절차는 다음과 같다.
서명 검증은 인증자의 공개키를 사용해 메시지가 진짜인지 검증하는 목적을 갖는데, 서명을 생성할 때와 동일한 해시 알고리즘을 이용해 인증자에 의해 서명된 메시지 다이제스트를 공개키 및 구성요소와 함께 계산한다. 서명을 확인하는 공식은 아래와 같다.
U1 * G + U2 * public key
U1 = z * w mod n
U2 = r * w mod n
w = s^-1 mod n
publick key는 공개키이자 복구키로 이더리움에서는 서명값이 아닌 정수 27 또는 28을 사용한다.
계산해낸 p의 x 좌표값과 서명 r의 값이 같다면 송신자의 서명이 맞다는 의미로 확인이 끝난다.
여기서 주목할 점은 개인키는 단순한 숫자에 불과하지만, 공개키는 타원곡선 위의 점이다. 따라서 U1 * G + U2 * public key 값은 타원곡선 위의 점을 연산한 값이다.
2. 타원곡선 사용 코드 예시
import { randomBytes } from 'crypto'
import { SHA256 } from 'crypto-js'
import elliptic from 'elliptic'
const ec = new elliptic.ec('secp256k1')
describe('wallet basis', () => {
let privKey: string, pubKey: string
let signature: elliptic.ec.Signature
const hash = SHA256('jenny').toString()
it('Private Key', () => {
privKey = randomBytes(32).toString('hex')
console.log(privKey) // ebb7d56b596131f99d1e5c734b294b16c81fd5ec283d7a836c5d846fb4160adc
})
it('Public Key', () => {
const keyPair = ec.keyFromPrivate(privKey)
pubKey = keyPair.getPublic().encode('hex', true)
console.log(pubKey) // 03c70c5b2693a9a48379247cb6a21cae3d8266ad80268752b4211f2770c928977f
})
it('Digital Signature', () => {
const keyPair = ec.keyFromPrivate(privKey)
signature = keyPair.sign(hash, 'hex')
console.log(signature)
})
it('Verification', () => {
const verify = ec.verify(hash, signature, ec.keyFromPublic(pubKey, 'hex'))
console.log(verify) // true
})
it('Address', () => {
const address = pubKey.slice(24)
console.log(address) // b6a21cae3d8266ad80268752b4211f2770c928977f
})
})
위 코드는 wallet.test.ts 파일의 내용이다.
먼저, privateKey는 randomBytes로 랜덤한 32Byte 값을 hex로 나타낸 값이다.
publicKey는 privateKey를 인자값으로 하여 keyFromPrivate()과 getPublic() 메소드를 통해 생성한다. publicKey는 signature를 생성하는데 쓰이지 않지만 signature를 검증할 때 필요로 한다.
signature는 sign()메소드를 써서 hash 값을 인자로 넣어서 생성한다.
signature를 검증하는 과정에서는 hash 값과 signature, publicKey를 인자값으로 하여 verify() 메소드를 써서 검증한다.
address는 암호화폐 지갑 주소로, 공개키의 앞에서부터 24글자를 제거한 것이 된다.
'BlockChain' 카테고리의 다른 글
[BlockChain] web3 설치 및 테스트 (0) | 2022.06.28 |
---|---|
[BlockChain] ganache-cli, MetaMask 설치 (0) | 2022.06.28 |
[BlockChain] UTXO vs. Account Model (0) | 2022.06.21 |
블록체인 기초 (0) | 2022.06.10 |
- Total
- Today
- Yesterday
- stdio.h
- int
- c언어
- Char
- Screen 객체
- bom
- location 객체
- short
- keyword
- 키워드
- long
- Browser Object Model
- gcc
- Document Object Model
- window 객체
- 자료형
- Navigator 객체
- History 객체
- 리액트 #React #props #state #javascript
- DOM
- 변수
- 컴파일
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |