본문 바로가기

Blockchain/ETC

HD Wallet: Key Derivation

키를 유도하는 방식은 크게 3가지로 나누어진다. 첫번째는 부모 개인키에서 자식 개인키를 유도하는 경우, 두번째는 부모 공개키에서 자식 공개키를 유도하는 경우, 세번째는 부모 개인키에서 자식 공개키를 유도하는 경우이다.

 

부모 개인키에서 자식 개인키 유도

부모 개인키에서 유도할 때는 강화된 방식으로 유도하는 경우 부모의 개인키를 직접적으로 해시 함수의 입력값으로 사용하지만 일반 유도 방식에서는 부모의 개인키를 공개키로 전환하여 공개키를 입력 값으로 하여 자식키를 유도한다. 키를 유도할 때는 부모의 확장된 키(부모키, 부모의 체인 코드), 인덱스가 사용된다.
CKDpriv((kpar, cpar), i) → (ki, ci) (kpar: 부모의 개인키, cpar: 부모의 체인 코드, i: 인덱스, ki: i번째 자식의 개인키, ci: i번째 자식의 체인코드)
Check whether i ≥ 2^31 (유도하려는 자식의 인덱스 범위가 강화된 유도에 해당하는지 확인).

- If so (hardened child): let I = HMAC-SHA512(Key = cpar, Data = 0x00 || ser256(kpar) || ser32(i)). (HMAC-SHA512(Key, Data): 입력값을 512bit 정수로 변환하는 해시 함수, ser256(p): 정수 p를 32byte 시퀀스로 직렬화, ser32(p): 32bit의 unsigned 정수 p를 4byte 시퀀스로 직렬화)
- If not (normal child): let I = HMAC-SHA512(Key = cpar, Data = serP(point(kpar)) || ser32(i)). (point(p): 정수 p만큼 secp256k1 곡선 상에서 곱해진 결과(일반적으로 공개키), serP(P): 타원곡선상 한점인 P=(x,y)를 직렬화)
HMAC-SHA512 결과 I는 64byte이며, 이를 32byte로 나눠 앞부분을 IL, 뒷부분을 IR로 표시
HMAC-SHA512 반환값 중 IL은 parse256(IL) + kpar (mod n)의 연산 결과로 ki (i번째 자식의 개인키)
HMAC-SHA512 반환값 중 IR은 ci (i번째 자식의 체인코드)
parse256(IL) ≥ n 이거나 ki = 0인 경우, 결과는 유효하지 않은 것으로 간주하여 인덱스 값을 증가시켜 다음 자식키를 유도한다. (Note: 이러한 이슈가 발생할 확률은 1/2^127보다 낮음.)

 

부모 공개키에서 자식 공개키 유도

부모 공개키에서 자식의 공개키를 유도하는 경우 개인키를 사용할 수 없기 때문에 강화된 방식으로는 유도가 불가능하다. 키를 유도할 때는 부모의 확장된 공개키(부모의 공개키, 부모의 체인코드), 인덱스가 사용된다.
CKDpub((Kpar, cpar), i) → (Ki, ci) (Kpar: 부모의 공개키, cpar: 부모의 체인 코드, i: 인덱스, Ki: i번째 자식의 공개키, ci: i번째 자식의 체인코드)
Check whether i ≥ 2^31 (유도하려는 자식의 인덱스 범위가 강화된 유도에 해당하는지 확인).
- If so (hardened child): return failure
- If not (normal child): let I = HMAC-SHA512(Key = cpar, Data = serP(Kpar) || ser32(i)). ((HMAC-SHA512(Key, Data): 입력값을 512bit 정수로 변환하는 해시 함수, serP(P): 타원곡선상 한점인 P=(x,y)를 직렬, ser32(p): 32bit의 unsigned 정수 p를 4byte 시퀀스로 직렬화)
HMAC-SHA512 결과 I는 64byte이며, 이를 32byte로 나눠 앞부분을 IL, 뒷부분을 IR로 표시
HMAC-SHA512 반환값 중 IL은 point(parse256(IL)) + Kpar의 연산 결과로 Ki (i번째 자식의 개인키).
HMAC-SHA512 반환값 중 IR은 ci (i번째 자식의 체인코드)
parse256(IL) ≥ n 이거나 Ki가 무한대를 나타내는 경우, 결과는 유효하지 않은 것으로 간주하여 인덱스 값을 증가시켜 다음 자식키를 유도한다.

 

부모 개인키에서 자식 공개키 유도

N((k, c)) → (K, c) (K: point(k)를 의미, returned c: 결과값의 체인 코드 c는 단순히 입력에서 전달된 값)
부모의 개인키에서 자식의 공개키 유도 방식
- N(CKDpriv((kpar, cpar), i)) (강화된 유도, 일반 유도 모두 가능).
- CKDpub(N(kpar, cpar), i) (일반 유도 방식만 가능).

'Blockchain > ETC' 카테고리의 다른 글

Diffie-Hellman key exchange with elliptic curves  (0) 2021.02.21