Make sizes public and add DecodePublicKey function

This commit is contained in:
2026-02-14 17:48:51 +01:00
parent f1ecbfaf8d
commit 849e805f80

View File

@@ -13,23 +13,24 @@ import (
"filippo.io/edwards25519"
)
// Byte sizes of key material.
const (
seedSize = 32
publicKeySize = 32
privateKeySize = seedSize + publicKeySize
SeedSize = 32
PublicKeySize = 32
PrivateKeySize = SeedSize + PublicKeySize
signatureSize = 64
sha512Size = 64
)
type PrivateKey struct {
seed [seedSize]byte
pub [publicKeySize]byte
seed [SeedSize]byte
pub [PublicKeySize]byte
s edwards25519.Scalar
prefix [sha512Size / 2]byte
}
func (priv *PrivateKey) Bytes() []byte {
k := make([]byte, 0, privateKeySize)
k := make([]byte, 0, PrivateKeySize)
k = append(k, priv.seed[:]...)
k = append(k, priv.pub[:]...)
return k
@@ -116,7 +117,7 @@ func NewPrivateKeyFromSeed(seed []byte) (*PrivateKey, error) {
}
func newPrivateKeyFromSeed(priv *PrivateKey, seed []byte) (*PrivateKey, error) {
if l := len(seed); l != seedSize {
if l := len(seed); l != SeedSize {
return nil, errors.New("ed25519: bad seed length: " + strconv.Itoa(l))
}
copy(priv.seed[:], seed)
@@ -124,6 +125,47 @@ func newPrivateKeyFromSeed(priv *PrivateKey, seed []byte) (*PrivateKey, error) {
return priv, nil
}
func DecodePrivateKey(s string) (*PrivateKey, error) {
var (
b []byte
err error
)
switch len(s) {
case hex.EncodedLen(SeedSize):
if b, err = hex.DecodeString(s); err != nil {
return nil, err
}
return NewPrivateKeyFromSeed(b)
case hex.EncodedLen(PrivateKeySize):
if b, err = hex.DecodeString(s); err != nil {
return nil, err
}
return NewPrivateKey(b)
case base64.RawStdEncoding.EncodedLen(SeedSize):
if b, err = base64.RawStdEncoding.DecodeString(s); err != nil {
return nil, err
}
return NewPrivateKeyFromSeed(b)
case base64.RawStdEncoding.EncodedLen(PrivateKeySize):
if b, err = base64.RawStdEncoding.DecodeString(s); err != nil {
return nil, err
}
return NewPrivateKey(b)
case base64.StdEncoding.EncodedLen(SeedSize):
if b, err = base64.StdEncoding.DecodeString(s); err != nil {
return nil, err
}
return NewPrivateKeyFromSeed(b)
case base64.StdEncoding.EncodedLen(PrivateKeySize):
if b, err = base64.StdEncoding.DecodeString(s); err != nil {
return nil, err
}
return NewPrivateKey(b)
default:
return nil, errors.New("ed25519: unknown private key encoding")
}
}
func precomputePrivateKey(priv *PrivateKey) {
hs := sha512.New()
hs.Write(priv.seed[:])
@@ -145,7 +187,7 @@ func NewPrivateKey(priv []byte) (*PrivateKey, error) {
}
func newPrivateKey(priv *PrivateKey, privBytes []byte) (*PrivateKey, error) {
if l := len(privBytes); l != privateKeySize {
if l := len(privBytes); l != PrivateKeySize {
return nil, errors.New("ed25519: bad private key length: " + strconv.Itoa(l))
}
@@ -196,7 +238,7 @@ func NewPublicKey(pub []byte) (*PublicKey, error) {
}
func newPublicKey(pub *PublicKey, pubBytes []byte) (*PublicKey, error) {
if l := len(pubBytes); l != publicKeySize {
if l := len(pubBytes); l != PublicKeySize {
return nil, errors.New("ed25519: bad public key length: " + strconv.Itoa(l))
}
// SetBytes checks that the point is on the curve.