Files
martin 30c452b69c chore: update docs (#5439)
* docs: general update

* docs: more info about tests
2022-05-23 17:30:52 +02:00

85 lines
2.2 KiB
Go

package main
import (
_sha256 "crypto/sha256"
"encoding/hex"
"errors"
"fmt"
"log"
"github.com/btcsuite/btcd/btcec"
)
func main() {
challengeHidden := "cd8552569d6e4509266ef137584d1e62c7579b5b8ed69bbafa4b864c6521e7c2" // Use random value
challengeVisual := "2015-03-23 17:39:22"
publicKey := "023a472219ad3327b07c18273717bb3a40b39b743756bf287fbd5fa9d263237f45"
signature := "20f2d1a42d08c3a362be49275c3ffeeaa415fc040971985548b9f910812237bb41770bf2c8d488428799fbb7e52c11f1a3404011375e4080e077e0e42ab7a5ba02"
err := verify(challengeHidden, challengeVisual, publicKey, signature, 2)
if err != nil {
log.Fatalln(err)
}
println("signature is valid")
}
func verify(challengeHidden, challengeVisual, publicKey, signature string, version int) error {
challengeHiddenBytes, err := hex.DecodeString(challengeHidden)
if err != nil {
return fmt.Errorf("failed to decode challenge hidden: %v", err)
}
challengeVisualBytes := []byte(challengeVisual)
publicKeyBytes, err := hex.DecodeString(publicKey)
if err != nil {
return fmt.Errorf("failed to decode public key: %v", err)
}
pubKey, err := btcec.ParsePubKey(publicKeyBytes, btcec.S256())
if err != nil {
return fmt.Errorf("failed to parse public key: %v", err)
}
signatureBytes, err := hex.DecodeString(signature)
if err != nil {
return fmt.Errorf("failed to decode signature: %v", err)
}
var challenge []byte
switch version {
case 1:
challenge = append(challengeHiddenBytes, challengeVisualBytes...)
case 2:
challenge = append(sha256(challengeHiddenBytes), sha256(challengeVisualBytes)...)
default:
return fmt.Errorf("unknown version: %d", version)
}
magicBytes := []byte("Bitcoin Signed Message:\n")
var msg []byte
msg = append(msg, byte(len(magicBytes)))
msg = append(msg, magicBytes...)
msg = append(msg, byte(len(challenge)))
msg = append(msg, challenge...)
hash := sha256(sha256(msg))
recoveredKey, _, err := btcec.RecoverCompact(btcec.S256(), signatureBytes, hash)
if err != nil {
return errors.New("failed to verify signature")
}
if !recoveredKey.IsEqual(pubKey) {
return errors.New("signature does not match public key or challenge")
}
return nil
}
func sha256(msg []byte) []byte {
hash := _sha256.Sum256(msg)
return hash[:]
}