키 생성부터 사인 검증까지
func Start() {
// generate keypair
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
utils.HandleErr(err)
// input message and trans to hash
message := "Isaac Lim"
hashedMessage := utils.Hash(message)
fmt.Println("hash MSG : ", hashedMessage)
hashAsBytes, err := hex.DecodeString(hashedMessage)
utils.HandleErr(err)
// sign hash using private key
r, s, err := ecdsa.Sign(rand.Reader, privateKey, hashAsBytes)
utils.HandleErr(err)
fmt.Printf("R: %d\\nS: %d\\n", r, s)
// verifiy sign using public key
ok := ecdsa.Verify(&privateKey.PublicKey, hashAsBytes, r, s)
fmt.Println(ok)
}
결론 : !! signature 은 r과 s 2개의 32bytes slice로 append된 값
sign := [[32][32]]
const (
privateKey string = "307702010104206cdfc4926161746c0f42cf7a21f9ee16223f13f454b8bf306688578c26caceb5a00a06082a8648ce3d030107a144034200047f22c3d34d9c13a26915417015c228f48cb47600fca57a1825ab5a37b2babf125e1aeec895b5e6e5f6012e26770548424a7dcbb817f9c3a68c7f7e4b3508f784"
hashedMessage string = "d221fff55b0679716ba32e386caa67b16635d8ea8a3d24a932fef179789c0a3e"
signature string = "a0cf131d85659cfd030d2a11182534ab2482ca8d1af98d4829b1a63124c8469603a601a31cc019756549fcbb6c2d6175a0c6f0761a9916f5933836c963791080"
)
func Start() {
// generate keypair
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
keyAsBytes, err := x509.MarshalECPrivateKey(privateKey)
fmt.Printf("private key : %x\\n\\n", keyAsBytes)
utils.HandleErr(err)
// input message and trans to hash
fmt.Println("hash MSG : ", hashedMessage)
hashAsBytes, err := hex.DecodeString(hashedMessage)
utils.HandleErr(err)
// sign hash using private key
r, s, err := ecdsa.Sign(rand.Reader, privateKey, hashAsBytes)
utils.HandleErr(err)
fmt.Printf("R: %d\\nS: %d\\n", r, s)
fmt.Println(r.Bytes(), s.Bytes())
signature := append(r.Bytes(), s.Bytes()...)
fmt.Printf("%x\\n", signature)
// verifiy sign using public key
// ok := ecdsa.Verify(&privateKey.PublicKey, hashAsBytes, r, s)
// fmt.Println(ok)
}
코드 3 :
byte타입의 private key를 원래의 모습인 ecdsa.PrivateKey 형태로 변경
hex string 타입의 signature를 []byte 형태로 변환(이때, signature값에 오류가 있는지 검사) 후, []byte 값의 signature를 r값과 s값으로 나눔(signature는 r []bytes + s []bytes으로 이루어짐) 각각의 r과 s값을 big.Int 로 변경
const (
privateKey string = "307702010104206cdfc4926161746c0f42cf7a21f9ee16223f13f454b8bf306688578c26caceb5a00a06082a8648ce3d030107a144034200047f22c3d34d9c13a26915417015c228f48cb47600fca57a1825ab5a37b2babf125e1aeec895b5e6e5f6012e26770548424a7dcbb817f9c3a68c7f7e4b3508f784"
hashedMessage string = "d221fff55b0679716ba32e386caa67b16635d8ea8a3d24a932fef179789c0a3e" // 16진수 문자열값
signature string = "a0cf131d85659cfd030d2a11182534ab2482ca8d1af98d4829b1a63124c8469603a601a31cc019756549fcbb6c2d6175a0c6f0761a9916f5933836c963791080"
)
func Start() {
privateByte, err := hex.DecodeString(privateKey)
utils.HandleErr(err)
//byte값의 private key를 받아 ecdsa.PrivateKey 형태의 private key로 반환
restoredKey, err := x509.ParseECPrivateKey(privateByte)
utils.HandleErr(err)
fmt.Println(restoredKey)
signBytes, err := hex.DecodeString(signature)
rBytes := signBytes[:len(signBytes)/2]
sBytes := signBytes[len(signBytes)/2:]
fmt.Printf("%d\\n\\n%d\\n\\n%d\\n\\n", signBytes, rBytes, sBytes)
var bigR, bigS = big.Int{}, big.Int{}
bigR.SetBytes(rBytes)
bigS.SetBytes(sBytes)
fmt.Println(bigR, bigS)
}
// 참고사항! : sign := [[32][32]] 이며 [r[32]/s[32]] 나눔