func SignMessage(privKey string, message string, compress bool) string { prefixBytes := []byte("Bitcoin Signed Message:\n") messageBytes := []byte(message) bytes := []byte{} bytes = append(bytes, byte(len(prefixBytes))) bytes = append(bytes, prefixBytes...) bytes = append(bytes, byte(len(messageBytes))) bytes = append(bytes, messageBytes...) privKeyBytes := HexDecode(privKey) x, y := btcec.S256().ScalarBaseMult(privKeyBytes) ecdsaPubKey := ecdsa.PublicKey{ Curve: btcec.S256(), X: x, Y: y, } ecdsaPrivKey := &ecdsa.PrivateKey{ PublicKey: ecdsaPubKey, D: new(big.Int).SetBytes(privKeyBytes), } sigbytes, err := btcec.SignCompact(btcec.S256(), ecdsaPrivKey, btcwire.DoubleSha256(bytes), compress) if err != nil { panic(err) } return base64.StdEncoding.EncodeToString(sigbytes) }
func testSignCompact(t *testing.T, tag string, curve *btcec.KoblitzCurve, data []byte, isCompressed bool) { priv, _ := ecdsa.GenerateKey(curve, rand.Reader) hashed := []byte("testing") sig, err := btcec.SignCompact(curve, priv, hashed, isCompressed) if err != nil { t.Errorf("%s: error signing: %s", tag, err) return } pk, wasCompressed, err := btcec.RecoverCompact(curve, sig, hashed) if err != nil { t.Errorf("%s: error recovering: %s", tag, err) return } if pk.X.Cmp(priv.X) != 0 || pk.Y.Cmp(priv.Y) != 0 { t.Errorf("%s: recovered pubkey doesn't match original "+ "(%v,%v) vs (%v,%v) ", tag, pk.X, pk.Y, priv.X, priv.Y) return } if wasCompressed != isCompressed { t.Errorf("%s: recovered pubkey doesn't match compressed state "+ "(%v vs %v)", tag, isCompressed, wasCompressed) return } // If we change the compressed bit we should get the same key back, // but the compressed flag should be reversed. if isCompressed { sig[0] -= 4 } else { sig[0] += 4 } pk, wasCompressed, err = btcec.RecoverCompact(curve, sig, hashed) if err != nil { t.Errorf("%s: error recovering (2): %s", tag, err) return } if pk.X.Cmp(priv.X) != 0 || pk.Y.Cmp(priv.Y) != 0 { t.Errorf("%s: recovered pubkey (2) doesn't match original "+ "(%v,%v) vs (%v,%v) ", tag, pk.X, pk.Y, priv.X, priv.Y) return } if wasCompressed == isCompressed { t.Errorf("%s: recovered pubkey doesn't match reversed "+ "compressed state (%v vs %v)", tag, isCompressed, wasCompressed) return } }