dsfx/pkg/crypto/identity/ecdsa.go

87 lines
2.1 KiB
Go
Raw Normal View History

2025-03-09 15:52:33 -04:00
package identity
2025-03-07 21:05:37 -05:00
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
2025-03-09 12:33:27 -04:00
"crypto/x509"
2025-03-07 21:05:37 -05:00
"encoding/json"
2025-03-09 12:33:27 -04:00
"encoding/pem"
"fmt"
2025-03-07 21:05:37 -05:00
"math/big"
2025-03-09 12:33:27 -04:00
"os"
2025-03-07 21:05:37 -05:00
)
var (
// DefaultSigningCurve is the default elliptic curve used for signing.
DefaultSigningCurve = elliptic.P384
)
2025-03-09 12:33:27 -04:00
func LoadSigningKeyFromFile(filePath string) (*ecdsa.PrivateKey, error) {
masterKeyFile, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}
// The second argument is not an error.
derEncoded, _ := pem.Decode(masterKeyFile)
if derEncoded == nil {
return nil, fmt.Errorf("failed to decode master key file")
}
masterKey, err := x509.ParseECPrivateKey(derEncoded.Bytes)
if err != nil {
return nil, err
}
return masterKey, nil
}
2025-03-07 21:05:37 -05:00
// GenerateSigningKey generates a new ECDSA private key for signing.
func GenerateSigningKey() (*ecdsa.PrivateKey, error) {
return ecdsa.GenerateKey(DefaultSigningCurve(), rand.Reader)
}
// Sign signs the data with the private key.
func Sign(priv *ecdsa.PrivateKey, data []byte) ([]byte, error) {
return ecdsa.SignASN1(rand.Reader, priv, data)
}
// Verify verifies the signature of the data with the public key.
func Verify(pub *ecdsa.PublicKey, data, signature []byte) bool {
return ecdsa.VerifyASN1(pub, data, signature)
}
// ExportPublicSigningKey exports the public key as a byte slice.
func ExportPublicSigningKey(pub *ecdsa.PublicKey) ([]byte, error) {
data := struct {
N []byte `json:"n"`
PubX []byte `json:"pub_x"`
PubY []byte `json:"pub_y"`
}{
N: pub.Curve.Params().N.Bytes(),
PubX: pub.X.Bytes(),
PubY: pub.Y.Bytes(),
}
return json.Marshal(data)
}
// ImportPublicSigningKey imports the public key from a byte slice.
func ImportPublicSigningKey(pubBytes []byte) (*ecdsa.PublicKey, error) {
var data struct {
N []byte `json:"n"`
PubX []byte `json:"pub_x"`
PubY []byte `json:"pub_y"`
}
if err := json.Unmarshal(pubBytes, &data); err != nil {
return nil, err
}
params := new(ecdsa.PublicKey)
params.Curve = DefaultSigningCurve()
params.X = new(big.Int).SetBytes(data.PubX)
params.Y = new(big.Int).SetBytes(data.PubY)
return params, nil
}