cli: change the module name of the cli (#1431)

This commit is contained in:
eball
2025-06-11 23:06:24 +08:00
committed by GitHub
parent f9072c9312
commit d484e41bbd
301 changed files with 6680 additions and 1059 deletions

View File

@@ -0,0 +1,82 @@
package eddsa
import (
_ed25519 "crypto/ed25519"
"crypto/rand"
"encoding/base64"
"errors"
"fmt"
"olares-cli/pkg/web5/jwk"
)
const (
ED25519JWACurve string = "Ed25519"
ED25519AlgorithmID string = ED25519JWACurve
)
// ED25519GeneratePrivateKey generates a new ED25519 private key
func ED25519GeneratePrivateKey() (jwk.JWK, error) {
publicKey, privateKey, err := _ed25519.GenerateKey(rand.Reader)
if err != nil {
return jwk.JWK{}, err
}
privKeyJwk := jwk.JWK{
KTY: KeyType,
CRV: ED25519JWACurve,
D: base64.RawURLEncoding.EncodeToString(privateKey),
X: base64.RawURLEncoding.EncodeToString(publicKey),
}
return privKeyJwk, nil
}
// ED25519Sign signs the given payload with the given private key
func ED25519Sign(payload []byte, privateKey jwk.JWK) ([]byte, error) {
privateKeyBytes, err := base64.RawURLEncoding.DecodeString(privateKey.D)
if err != nil {
return nil, fmt.Errorf("failed to decode d %w", err)
}
signature := _ed25519.Sign(privateKeyBytes, payload)
return signature, nil
}
// ED25519Verify verifies the given signature against the given payload using the given public key
func ED25519Verify(payload []byte, signature []byte, publicKey jwk.JWK) (bool, error) {
publicKeyBytes, err := base64.RawURLEncoding.DecodeString(publicKey.X)
if err != nil {
return false, err
}
legit := _ed25519.Verify(publicKeyBytes, payload, signature)
return legit, nil
}
// ED25519BytesToPublicKey deserializes the byte array into a jwk.JWK public key
func ED25519BytesToPublicKey(input []byte) (jwk.JWK, error) {
if len(input) != _ed25519.PublicKeySize {
return jwk.JWK{}, errors.New("invalid public key")
}
return jwk.JWK{
KTY: KeyType,
CRV: ED25519JWACurve,
X: base64.RawURLEncoding.EncodeToString(input),
}, nil
}
// ED25519PublicKeyToBytes serializes the given public key int a byte array
func ED25519PublicKeyToBytes(publicKey jwk.JWK) ([]byte, error) {
if publicKey.X == "" {
return nil, errors.New("x must be set")
}
publicKeyBytes, err := base64.RawURLEncoding.DecodeString(publicKey.X)
if err != nil {
return nil, fmt.Errorf("failed to decode x %w", err)
}
return publicKeyBytes, nil
}

View File

@@ -0,0 +1,68 @@
package eddsa_test
import (
"encoding/base64"
"encoding/hex"
"testing"
"olares-cli/pkg/web5/crypto/dsa/eddsa"
"olares-cli/pkg/web5/jwk"
"github.com/alecthomas/assert/v2"
)
func TestED25519BytesToPublicKey_Bad(t *testing.T) {
publicKeyBytes := []byte{0x00, 0x01, 0x02, 0x03}
_, err := eddsa.ED25519BytesToPublicKey(publicKeyBytes)
assert.Error(t, err)
}
func TestED25519BytesToPublicKey_Good(t *testing.T) {
// vector taken from https://github.com/decentralized-identity/web5-js/blob/dids-new-crypto/packages/crypto/tests/fixtures/test-vectors/ed25519/bytes-to-public-key.json
pubKeyHex := "7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa"
pubKeyBytes, err := hex.DecodeString(pubKeyHex)
assert.NoError(t, err)
jwk, err := eddsa.ED25519BytesToPublicKey(pubKeyBytes)
assert.NoError(t, err)
assert.Equal(t, eddsa.KeyType, jwk.KTY)
assert.Equal(t, eddsa.ED25519JWACurve, jwk.CRV)
assert.Equal(t, "fU0Of2FTpptiQrUiq77mhf2kQg-INLEIw72uNp71Sfo", jwk.X)
}
func TestED25519PublicKeyToBytes(t *testing.T) {
// vector taken from: https://github.com/decentralized-identity/web5-spec/blob/main/test-vectors/crypto_ed25519/sign.json
jwk := jwk.JWK{
KTY: "OKP",
CRV: eddsa.ED25519JWACurve,
X: "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo",
}
pubKeyBytes, err := eddsa.ED25519PublicKeyToBytes(jwk)
assert.NoError(t, err)
pubKeyB64URL := base64.RawURLEncoding.EncodeToString(pubKeyBytes)
assert.Equal(t, jwk.X, pubKeyB64URL)
}
func TestED25519PublicKeyToBytes_Bad(t *testing.T) {
vectors := []jwk.JWK{
{
KTY: "OKP",
CRV: eddsa.ED25519JWACurve,
},
{
KTY: "OKP",
CRV: eddsa.ED25519JWACurve,
X: "=/---",
},
}
for _, jwk := range vectors {
pubKeyBytes, err := eddsa.ED25519PublicKeyToBytes(jwk)
assert.Error(t, err)
assert.Equal(t, nil, pubKeyBytes)
}
}

View File

@@ -0,0 +1,116 @@
// Package eddsa implements the EdDSA signature schemes as per RFC 8032
// https://tools.ietf.org/html/rfc8032. Note: Currently only Ed25519 is supported
package eddsa
import (
"errors"
"fmt"
"olares-cli/pkg/web5/jwk"
)
const (
JWA string = "EdDSA"
KeyType string = "OKP"
)
var algorithmIDs = map[string]bool{
ED25519AlgorithmID: true,
}
// GeneratePrivateKey generates an EdDSA private key for the given algorithm
func GeneratePrivateKey(algorithmID string) (jwk.JWK, error) {
switch algorithmID {
case ED25519AlgorithmID:
return ED25519GeneratePrivateKey()
default:
return jwk.JWK{}, fmt.Errorf("unsupported algorithm: %s", algorithmID)
}
}
// GetPublicKey builds an EdDSA public key from the given EdDSA private key
func GetPublicKey(privateKey jwk.JWK) jwk.JWK {
return jwk.JWK{
KTY: privateKey.KTY,
CRV: privateKey.CRV,
X: privateKey.X,
}
}
// Sign generates a cryptographic signature for the given payload with the given private key
//
// # Note
//
// The function will automatically detect the given EdDSA cryptographic curve from the given private key
func Sign(payload []byte, privateKey jwk.JWK) ([]byte, error) {
if privateKey.D == "" {
return nil, errors.New("d must be set")
}
switch privateKey.CRV {
case ED25519JWACurve:
return ED25519Sign(payload, privateKey)
default:
return nil, fmt.Errorf("unsupported curve: %s", privateKey.CRV)
}
}
// Verify verifies the given signature over a given payload by the given public key
//
// # Note
//
// The function will automatically detect the given EdDSA cryptographic curve from the given public key
func Verify(payload []byte, signature []byte, publicKey jwk.JWK) (bool, error) {
switch publicKey.CRV {
case ED25519JWACurve:
return ED25519Verify(payload, signature, publicKey)
default:
return false, fmt.Errorf("unsupported curve: %s", publicKey.CRV)
}
}
// GetJWA returns the [JWA] for the given EdDSA key
//
// # Note
//
// The only supported [JWA] is "EdDSA"
//
// [JWA]: https://datatracker.ietf.org/doc/html/rfc7518
func GetJWA(jwk jwk.JWK) (string, error) {
return JWA, nil
}
// BytesToPublicKey deserializes the given byte array into a jwk.JWK for the given cryptographic algorithm
func BytesToPublicKey(algorithmID string, input []byte) (jwk.JWK, error) {
switch algorithmID {
case ED25519AlgorithmID:
return ED25519BytesToPublicKey(input)
default:
return jwk.JWK{}, fmt.Errorf("unsupported algorithm: %s", algorithmID)
}
}
// PublicKeyToBytes serializes the given public key into a byte array
func PublicKeyToBytes(publicKey jwk.JWK) ([]byte, error) {
switch publicKey.CRV {
case ED25519JWACurve:
return ED25519PublicKeyToBytes(publicKey)
default:
return nil, fmt.Errorf("unsupported curve: %s", publicKey.CRV)
}
}
// SupportsAlgorithmID informs as to whether or not the given algorithm ID is supported by this package
func SupportsAlgorithmID(id string) bool {
return algorithmIDs[id]
}
// AlgorithmID returns the algorithm ID for the given jwk.JWK
func AlgorithmID(jwk *jwk.JWK) (string, error) {
switch jwk.CRV {
case ED25519JWACurve:
return ED25519AlgorithmID, nil
default:
return "", fmt.Errorf("unsupported curve: %s", jwk.CRV)
}
}