mirror of
https://github.com/sonr-io/crypto.git
synced 2026-01-11 20:08:57 +00:00
117 lines
3.0 KiB
Go
117 lines
3.0 KiB
Go
package spec
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"fmt"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
"github.com/sonr-io/crypto/mpc"
|
|
)
|
|
|
|
// MPCSigningMethod implements the SigningMethod interface for MPC-based signing
|
|
type MPCSigningMethod struct {
|
|
Name string
|
|
enclave mpc.Enclave
|
|
}
|
|
|
|
// NewJWTSigningMethod creates a new MPC signing method with the given enclave
|
|
func NewJWTSigningMethod(name string, enclave mpc.Enclave) *MPCSigningMethod {
|
|
return &MPCSigningMethod{
|
|
Name: name,
|
|
enclave: enclave,
|
|
}
|
|
}
|
|
|
|
// WithEnclave sets the enclave for an existing signing method
|
|
func (m *MPCSigningMethod) WithEnclave(enclave mpc.Enclave) *MPCSigningMethod {
|
|
return &MPCSigningMethod{
|
|
Name: m.Name,
|
|
enclave: enclave,
|
|
}
|
|
}
|
|
|
|
// NewMPCSigningMethod is an alias for NewJWTSigningMethod for compatibility
|
|
func NewMPCSigningMethod(name string, enclave mpc.Enclave) *MPCSigningMethod {
|
|
return NewJWTSigningMethod(name, enclave)
|
|
}
|
|
|
|
// Alg returns the signing method's name
|
|
func (m *MPCSigningMethod) Alg() string {
|
|
return m.Name
|
|
}
|
|
|
|
// Verify verifies the signature using the MPC public key
|
|
func (m *MPCSigningMethod) Verify(signingString string, signature []byte, key any) error {
|
|
// Check if enclave is available
|
|
if m.enclave == nil {
|
|
return fmt.Errorf("MPC enclave not available for signature verification")
|
|
}
|
|
|
|
// Decode the signature
|
|
sig, err := base64.RawURLEncoding.DecodeString(string(signature))
|
|
if err != nil {
|
|
return fmt.Errorf("failed to decode signature: %w", err)
|
|
}
|
|
|
|
// Hash the signing string using SHA-256
|
|
hasher := sha256.New()
|
|
hasher.Write([]byte(signingString))
|
|
digest := hasher.Sum(nil)
|
|
|
|
// Use MPC enclave to verify signature
|
|
valid, err := m.enclave.Verify(digest, sig)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to verify signature: %w", err)
|
|
}
|
|
|
|
if !valid {
|
|
return fmt.Errorf("signature verification failed")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Sign signs the data using MPC
|
|
func (m *MPCSigningMethod) Sign(signingString string, key any) ([]byte, error) {
|
|
// Check if enclave is available
|
|
if m.enclave == nil {
|
|
return nil, fmt.Errorf("MPC enclave not available for signing")
|
|
}
|
|
|
|
// Hash the signing string using SHA-256
|
|
hasher := sha256.New()
|
|
hasher.Write([]byte(signingString))
|
|
digest := hasher.Sum(nil)
|
|
|
|
// Use MPC enclave to sign the digest
|
|
sig, err := m.enclave.Sign(digest)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to sign with MPC: %w", err)
|
|
}
|
|
|
|
// Encode the signature as base64url
|
|
encoded := base64.RawURLEncoding.EncodeToString(sig)
|
|
return []byte(encoded), nil
|
|
}
|
|
|
|
func init() {
|
|
// Register the MPC signing method factory
|
|
jwt.RegisterSigningMethod("MPC256", func() jwt.SigningMethod {
|
|
// This factory creates a new instance without enclave
|
|
// The enclave will be provided when creating tokens
|
|
return &MPCSigningMethod{
|
|
Name: "MPC256",
|
|
}
|
|
})
|
|
}
|
|
|
|
// RegisterMPCMethod registers an MPC signing method for the given algorithm name
|
|
func RegisterMPCMethod(alg string) {
|
|
jwt.RegisterSigningMethod(alg, func() jwt.SigningMethod {
|
|
return &MPCSigningMethod{
|
|
Name: alg,
|
|
}
|
|
})
|
|
}
|