From 849e805f80b427d5ae55836a745a3d7a335f8d6c Mon Sep 17 00:00:00 2001 From: maze Date: Sat, 14 Feb 2026 17:48:51 +0100 Subject: [PATCH] Make sizes public and add DecodePublicKey function --- protocol/meshcore/crypto/ed25519.go | 60 ++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/protocol/meshcore/crypto/ed25519.go b/protocol/meshcore/crypto/ed25519.go index ecb028e..0a36029 100644 --- a/protocol/meshcore/crypto/ed25519.go +++ b/protocol/meshcore/crypto/ed25519.go @@ -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.