|
|
@ -8,6 +8,8 @@ import ( |
|
|
|
"crypto/rand" |
|
|
|
"crypto/rand" |
|
|
|
"crypto/sha256" |
|
|
|
"crypto/sha256" |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
|
|
|
|
|
"io" |
|
|
|
|
|
|
|
"os" |
|
|
|
|
|
|
|
|
|
|
|
"encoding/hex" |
|
|
|
"encoding/hex" |
|
|
|
"encoding/json" |
|
|
|
"encoding/json" |
|
|
@ -99,6 +101,32 @@ func FromECDSAPub(pub *ecdsa.PublicKey) []byte { |
|
|
|
return elliptic.Marshal(S256(), pub.X, pub.Y) |
|
|
|
return elliptic.Marshal(S256(), pub.X, pub.Y) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// HexToECDSA parses a secp256k1 private key.
|
|
|
|
|
|
|
|
func HexToECDSA(hexkey string) (*ecdsa.PrivateKey, error) { |
|
|
|
|
|
|
|
b, err := hex.DecodeString(hexkey) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return nil, errors.New("invalid hex string") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if len(b) != 32 { |
|
|
|
|
|
|
|
return nil, errors.New("invalid length, need 256 bits") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return ToECDSA(b), nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// LoadECDSA loads a secp256k1 private key from the given file.
|
|
|
|
|
|
|
|
func LoadECDSA(file string) (*ecdsa.PrivateKey, error) { |
|
|
|
|
|
|
|
buf := make([]byte, 32) |
|
|
|
|
|
|
|
fd, err := os.Open(file) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
defer fd.Close() |
|
|
|
|
|
|
|
if _, err := io.ReadFull(fd, buf); err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return ToECDSA(buf), nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func GenerateKey() (*ecdsa.PrivateKey, error) { |
|
|
|
func GenerateKey() (*ecdsa.PrivateKey, error) { |
|
|
|
return ecdsa.GenerateKey(S256(), rand.Reader) |
|
|
|
return ecdsa.GenerateKey(S256(), rand.Reader) |
|
|
|
} |
|
|
|
} |
|
|
|