refactor/internal (#1216)

* refactor: update import paths in gateway handlers

* refactor: remove obsolete devtools Makefile and README

* build: optimize build process for improved efficiency

* refactor: remove obsolete pkl files related to Matrix and Sonr network configurations

* refactor: move embed code to x/dwn/types
This commit is contained in:
Prad Nukala
2024-12-24 16:10:20 +00:00
committed by GitHub
parent 0ec2f7d86a
commit 47c3a53080
356 changed files with 402 additions and 1613 deletions
-42
View File
@@ -1,42 +0,0 @@
package mpc
import (
"github.com/onsonr/sonr/crypto/core/curves"
"github.com/onsonr/sonr/crypto/core/protocol"
"github.com/onsonr/sonr/crypto/keys"
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1/dkg"
)
// ╭───────────────────────────────────────────────────────────╮
// │ Exported Generics │
// ╰───────────────────────────────────────────────────────────╯
type (
AliceOut *dkg.AliceOutput
BobOut *dkg.BobOutput
Point curves.Point
Role string // Role is the type for the role
Message *protocol.Message // Message is the protocol.Message that is used for MPC
Signature *curves.EcdsaSignature // Signature is the type for the signature
RefreshFunc interface{ protocol.Iterator } // RefreshFunc is the type for the refresh function
SignFunc interface{ protocol.Iterator } // SignFunc is the type for the sign function
)
const (
RoleVal = "validator"
RoleUser = "user"
)
// Enclave defines the interface for key management operations
type Enclave interface {
Address() string // Address returns the Sonr address of the keyEnclave
DID() keys.DID // DID returns the DID of the keyEnclave
Export(key []byte) ([]byte, error) // Export returns encrypted enclave data
Import(data []byte, key []byte) error // Import decrypts and loads enclave data
IsValid() bool // IsValid returns true if the keyEnclave is valid
PubKey() keys.PubKey // PubKey returns the public key of the keyEnclave
Refresh() (Enclave, error) // Refresh returns a new keyEnclave
Serialize() ([]byte, error) // Serialize returns the serialized keyEnclave
Sign(data []byte) ([]byte, error) // Sign returns the signature of the data
Verify(data []byte, sig []byte) (bool, error) // Verify returns true if the signature is valid
}
-160
View File
@@ -1,160 +0,0 @@
package mpc
import (
"crypto/rand"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func randNonce() []byte {
nonce := make([]byte, 12)
rand.Read(nonce)
return nonce
}
func TestKeyShareGeneration(t *testing.T) {
t.Run("Generate Valid Enclave", func(t *testing.T) {
nonce := randNonce()
// Generate enclave
enclave, err := GenEnclave(nonce)
require.NoError(t, err)
require.NotNil(t, enclave)
// Validate enclave contents
assert.True(t, enclave.IsValid())
})
t.Run("Export and Import", func(t *testing.T) {
nonce := randNonce()
// Generate original enclave
original, err := GenEnclave(nonce)
require.NoError(t, err)
// Test key for encryption/decryption (32 bytes)
testKey := []byte("test-key-12345678-test-key-123456")
// Test Export/Import
t.Run("Full Enclave", func(t *testing.T) {
// Export enclave
data, err := original.Export(testKey)
require.NoError(t, err)
require.NotEmpty(t, data)
// Create new empty enclave
newEnclave, err := GenEnclave(nonce)
require.NoError(t, err)
// Import enclave
err = newEnclave.Import(data, testKey)
require.NoError(t, err)
// Verify the imported enclave works by signing
testData := []byte("test message")
sig, err := newEnclave.Sign(testData)
require.NoError(t, err)
valid, err := newEnclave.Verify(testData, sig)
require.NoError(t, err)
assert.True(t, valid)
})
// Test Invalid Key
t.Run("Invalid Key", func(t *testing.T) {
data, err := original.Export(testKey)
require.NoError(t, err)
wrongKey := []byte("wrong-key-12345678")
err = original.Import(data, wrongKey)
assert.Error(t, err)
})
})
}
func TestEnclaveOperations(t *testing.T) {
t.Run("Signing and Verification", func(t *testing.T) {
nonce := randNonce()
// Generate valid enclave
enclave, err := GenEnclave(nonce)
require.NoError(t, err)
// Test signing
testData := []byte("test message")
signature, err := enclave.Sign(testData)
require.NoError(t, err)
require.NotNil(t, signature)
// Verify the signature
valid, err := enclave.Verify(testData, signature)
require.NoError(t, err)
assert.True(t, valid)
// Test invalid data verification
invalidData := []byte("wrong message")
valid, err = enclave.Verify(invalidData, signature)
require.NoError(t, err)
assert.False(t, valid)
})
t.Run("Address and Public Key", func(t *testing.T) {
nonce := randNonce()
enclave, err := GenEnclave(nonce)
require.NoError(t, err)
// Test Address
addr := enclave.Address()
assert.NotEmpty(t, addr)
assert.True(t, strings.HasPrefix(addr, "idx"))
// Test Public Key
pubKey := enclave.PubKey()
assert.NotNil(t, pubKey)
assert.NotEmpty(t, pubKey.Bytes())
})
t.Run("Refresh Operation", func(t *testing.T) {
nonce := randNonce()
enclave, err := GenEnclave(nonce)
require.NoError(t, err)
// Test refresh
refreshedEnclave, err := enclave.Refresh()
require.NoError(t, err)
require.NotNil(t, refreshedEnclave)
// Verify refreshed enclave is valid
assert.True(t, refreshedEnclave.IsValid())
// Verify it maintains the same address
assert.Equal(t, enclave.Address(), refreshedEnclave.Address())
})
}
func TestEnclaveSerialization(t *testing.T) {
t.Run("Marshal and Unmarshal", func(t *testing.T) {
nonce := randNonce()
// Generate original enclave
original, err := GenEnclave(nonce)
require.NoError(t, err)
require.NotNil(t, original)
// Marshal
keyclave, ok := original.(*keyEnclave)
require.True(t, ok)
data, err := keyclave.Serialize()
require.NoError(t, err)
require.NotEmpty(t, data)
// Unmarshal
restored := &keyEnclave{}
err = restored.Unmarshal(data)
require.NoError(t, err)
// Verify restored enclave
assert.Equal(t, keyclave.Addr, restored.Addr)
assert.True(t, keyclave.PubPoint.Equal(restored.PubPoint))
assert.True(t, restored.IsValid())
})
}
-179
View File
@@ -1,179 +0,0 @@
package mpc
import (
"crypto/aes"
"crypto/cipher"
"crypto/ecdsa"
"encoding/json"
"fmt"
"github.com/onsonr/sonr/crypto/core/curves"
"github.com/onsonr/sonr/crypto/keys"
"golang.org/x/crypto/sha3"
)
// keyEnclave implements the Enclave interface
type keyEnclave struct {
// Serialized fields
Addr string `json:"address"`
PubPoint curves.Point `json:"-"`
PubBytes []byte `json:"pub_key"`
ValShare Message `json:"val_share"`
UserShare Message `json:"user_share"`
// Extra fields
nonce []byte
}
func newEnclave(valShare, userShare Message, nonce []byte) (Enclave, error) {
pubPoint, err := getAlicePubPoint(valShare)
if err != nil {
return nil, err
}
addr, err := computeSonrAddr(pubPoint)
if err != nil {
return nil, err
}
return &keyEnclave{
Addr: addr,
PubPoint: pubPoint,
ValShare: valShare,
UserShare: userShare,
nonce: nonce,
}, nil
}
// Address returns the Sonr address of the keyEnclave
func (k *keyEnclave) Address() string {
return k.Addr
}
// DID returns the DID of the keyEnclave
func (k *keyEnclave) DID() keys.DID {
return keys.NewFromPubKey(k.PubKey())
}
// Export returns encrypted enclave data
func (k *keyEnclave) Export(key []byte) ([]byte, error) {
data, err := k.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize enclave: %w", err)
}
hashedKey := hashKey(key)
block, err := aes.NewCipher(hashedKey)
if err != nil {
return nil, err
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
return aesgcm.Seal(nil, k.nonce, data, nil), nil
}
// Import decrypts and loads enclave data
func (k *keyEnclave) Import(data []byte, key []byte) error {
hashedKey := hashKey(key)
block, err := aes.NewCipher(hashedKey)
if err != nil {
return err
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return err
}
decrypted, err := aesgcm.Open(nil, k.nonce, data, nil)
if err != nil {
return err
}
return k.Unmarshal(decrypted)
}
// IsValid returns true if the keyEnclave is valid
func (k *keyEnclave) IsValid() bool {
return k.PubPoint != nil && k.ValShare != nil && k.UserShare != nil && k.Addr != ""
}
// PubKey returns the public key of the keyEnclave
func (k *keyEnclave) PubKey() keys.PubKey {
return keys.NewPubKey(k.PubPoint)
}
// Refresh returns a new keyEnclave
func (k *keyEnclave) Refresh() (Enclave, error) {
refreshFuncVal, err := valRefreshFunc(k)
if err != nil {
return nil, err
}
refreshFuncUser, err := userRefreshFunc(k)
if err != nil {
return nil, err
}
return ExecuteRefresh(refreshFuncVal, refreshFuncUser, k.nonce)
}
// Sign returns the signature of the data
func (k *keyEnclave) Sign(data []byte) ([]byte, error) {
userSign, err := userSignFunc(k, data)
if err != nil {
return nil, err
}
valSign, err := valSignFunc(k, data)
if err != nil {
return nil, err
}
return ExecuteSigning(valSign, userSign)
}
// Verify returns true if the signature is valid
func (k *keyEnclave) Verify(data []byte, sig []byte) (bool, error) {
edSig, err := deserializeSignature(sig)
if err != nil {
return false, err
}
ePub, err := getEcdsaPoint(k.PubPoint.ToAffineUncompressed())
if err != nil {
return false, err
}
pk := &ecdsa.PublicKey{
Curve: ePub.Curve,
X: ePub.X,
Y: ePub.Y,
}
// Hash the message using SHA3-256
hash := sha3.New256()
hash.Write(data)
digest := hash.Sum(nil)
return ecdsa.Verify(pk, digest, edSig.R, edSig.S), nil
}
// Marshal returns the JSON encoding of keyEnclave
func (k *keyEnclave) Serialize() ([]byte, error) {
// Store compressed public point bytes before marshaling
k.PubBytes = k.PubPoint.ToAffineCompressed()
return json.Marshal(k)
}
// Unmarshal parses the JSON-encoded data and stores the result
func (k *keyEnclave) Unmarshal(data []byte) error {
if err := json.Unmarshal(data, k); err != nil {
return err
}
// Reconstruct Point from bytes
curve := curves.K256()
point, err := curve.NewIdentityPoint().FromAffineCompressed(k.PubBytes)
if err != nil {
return err
}
k.PubPoint = point
return nil
}
-88
View File
@@ -1,88 +0,0 @@
package mpc
import (
"github.com/onsonr/sonr/crypto/core/curves"
"github.com/onsonr/sonr/crypto/core/protocol"
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1"
)
// GenEnclave generates a new MPC keyshare
func GenEnclave(nonce []byte) (Enclave, error) {
curve := curves.K256()
valKs := dklsv1.NewAliceDkg(curve, protocol.Version1)
userKs := dklsv1.NewBobDkg(curve, protocol.Version1)
aErr, bErr := RunProtocol(userKs, valKs)
if err := checkIteratedErrors(aErr, bErr); err != nil {
return nil, err
}
valRes, err := valKs.Result(protocol.Version1)
if err != nil {
return nil, err
}
userRes, err := userKs.Result(protocol.Version1)
if err != nil {
return nil, err
}
return newEnclave(valRes, userRes, nonce)
}
// ExecuteSigning runs the MPC signing protocol
func ExecuteSigning(signFuncVal SignFunc, signFuncUser SignFunc) ([]byte, error) {
aErr, bErr := RunProtocol(signFuncVal, signFuncUser)
if err := checkIteratedErrors(aErr, bErr); err != nil {
return nil, err
}
out, err := signFuncUser.Result(protocol.Version1)
if err != nil {
return nil, err
}
s, err := dklsv1.DecodeSignature(out)
if err != nil {
return nil, err
}
sig, err := serializeSignature(s)
if err != nil {
return nil, err
}
return sig, nil
}
// ExecuteRefresh runs the MPC refresh protocol
func ExecuteRefresh(refreshFuncVal RefreshFunc, refreshFuncUser RefreshFunc, nonce []byte) (Enclave, error) {
aErr, bErr := RunProtocol(refreshFuncVal, refreshFuncUser)
if err := checkIteratedErrors(aErr, bErr); err != nil {
return nil, err
}
valRefreshResult, err := refreshFuncVal.Result(protocol.Version1)
if err != nil {
return nil, err
}
userRefreshResult, err := refreshFuncUser.Result(protocol.Version1)
if err != nil {
return nil, err
}
return newEnclave(valRefreshResult, userRefreshResult, nonce)
}
// For DKG bob starts first. For refresh and sign, Alice starts first.
func RunProtocol(firstParty protocol.Iterator, secondParty protocol.Iterator) (error, error) {
var (
message *protocol.Message
aErr error
bErr error
)
for aErr != protocol.ErrProtocolFinished || bErr != protocol.ErrProtocolFinished {
// Crank each protocol forward one iteration
message, bErr = firstParty.Next(message)
if bErr != nil && bErr != protocol.ErrProtocolFinished {
return nil, bErr
}
message, aErr = secondParty.Next(message)
if aErr != nil && aErr != protocol.ErrProtocolFinished {
return aErr, nil
}
}
return aErr, bErr
}
-83
View File
@@ -1,83 +0,0 @@
package spec
import (
"crypto/sha256"
"github.com/golang-jwt/jwt"
)
// MPCSigningMethod implements the SigningMethod interface for MPC-based signing
type MPCSigningMethod struct {
Name string
ks ucanKeyshare
}
// NewJWTSigningMethod creates a new MPC signing method with the given keyshare source
func NewJWTSigningMethod(name string, ks ucanKeyshare) *MPCSigningMethod {
return &MPCSigningMethod{
Name: name,
ks: ks,
}
}
// 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, signature string, key interface{}) error {
// // Decode the signature
// sig, err := base64.RawURLEncoding.DecodeString(signature)
// if err != nil {
// return err
// }
//
// // Hash the signing string
// hasher := sha256.New()
// hasher.Write([]byte(signingString))
// digest := hasher.Sum(nil)
// valid, err := m.ks.valShare.PublicKey().Verify(digest, sig)
// if !valid || err != nil {
// return fmt.Errorf("invalid signature")
// }
return nil
}
// Sign signs the data using MPC
func (m *MPCSigningMethod) Sign(signingString string, key interface{}) (string, error) {
// Hash the signing string
hasher := sha256.New()
hasher.Write([]byte(signingString))
// digest := hasher.Sum(nil)
//
// // Create signing functions
// signFunc, err := m.ks.userShare.SignFunc(digest)
// if err != nil {
// return "", fmt.Errorf("failed to create sign function: %w", err)
// }
//
// valSignFunc, err := m.ks.valShare.SignFunc(digest)
// if err != nil {
// return "", fmt.Errorf("failed to create validator sign function: %w", err)
// }
// // Run the signing protocol
// sig, err := mpc.ExecuteSigning(valSignFunc, signFunc)
// if err != nil {
// return "", fmt.Errorf("failed to run sign protocol: %w", err)
// }
// Encode the signature
// encoded := base64.RawURLEncoding.EncodeToString(sig)
return "", nil
}
func init() {
// Register the MPC signing method
jwt.RegisterSigningMethod("MPC256", func() jwt.SigningMethod {
return &MPCSigningMethod{
Name: "MPC256",
}
})
}
-126
View File
@@ -1,126 +0,0 @@
package spec
import (
"context"
"fmt"
"time"
"github.com/onsonr/sonr/crypto/keys"
"github.com/onsonr/sonr/crypto/ucan"
"lukechampine.com/blake3"
)
type KeyshareSource interface {
ucan.Source
Address() string
Issuer() string
ChainCode() ([]byte, error)
OriginToken() (*Token, error)
SignData(data []byte) ([]byte, error)
VerifyData(data []byte, sig []byte) (bool, error)
UCANParser() *ucan.TokenParser
}
// func NewSource(ks mpc.KeyEnclave) (KeyshareSource, error) {
// iss, addr, err := getIssuerDID(val.PublicKey())
// if err != nil {
// return nil, err
// }
//
// return ucanKeyshare{
// issuerDID: iss,
// addr: addr,
// }, nil
// }
//
// Address returns the address of the keyshare
func (k ucanKeyshare) Address() string {
return k.addr
}
// Issuer returns the DID of the issuer of the keyshare
func (k ucanKeyshare) Issuer() string {
return k.issuerDID
}
// ChainCode returns the chain code of the keyshare
func (k ucanKeyshare) ChainCode() ([]byte, error) {
sig, err := k.SignData([]byte(k.addr))
if err != nil {
return nil, err
}
hash := blake3.Sum256(sig)
// Return the first 32 bytes of the hash
return hash[:32], nil
}
// DefaultOriginToken returns a default token with the keyshare's issuer as the audience
func (k ucanKeyshare) OriginToken() (*Token, error) {
// att := ucan.NewSmartAccount(k.addr)
zero := time.Time{}
// return k.NewOriginToken(k.issuerDID, att, nil, zero, zero)
return k.newToken(k.issuerDID, nil, nil, nil, zero, zero)
}
func (k ucanKeyshare) SignData(data []byte) ([]byte, error) {
// // Create signing functions
// signFunc, err := k.userShare.SignFunc(data)
// if err != nil {
// return nil, fmt.Errorf("failed to create sign function: %w", err)
// }
//
// valSignFunc, err := k.valShare.SignFunc(data)
// if err != nil {
// return nil, fmt.Errorf("failed to create validator sign function: %w", err)
// }
// Run the signing protocol
// return mpc.ExecuteSigning(valSignFunc, signFunc)
return nil, nil
}
func (k ucanKeyshare) VerifyData(data []byte, sig []byte) (bool, error) {
return false, nil
// return k.valShare.PublicKey().Verify(data, sig)
}
// TokenParser returns a token parser that can be used to parse tokens
func (k ucanKeyshare) UCANParser() *ucan.TokenParser {
caps := ucan.AccountPermissions.GetCapabilities()
ac := func(m map[string]interface{}) (ucan.Attenuation, error) {
var (
cap string
rsc ucan.Resource
)
for key, vali := range m {
val, ok := vali.(string)
if !ok {
return ucan.Attenuation{}, fmt.Errorf(`expected attenuation value to be a string`)
}
if key == ucan.CapKey {
cap = val
} else {
}
}
return ucan.Attenuation{
Rsc: rsc,
Cap: caps.Cap(cap),
}, nil
}
store := ucan.NewMemTokenStore()
return ucan.NewTokenParser(ac, customDIDPubKeyResolver{}, store.(ucan.CIDBytesResolver))
}
// customDIDPubKeyResolver implements the DIDPubKeyResolver interface without
// any network backing. Works if the key string given contains the public key
// itself
type customDIDPubKeyResolver struct{}
// ResolveDIDKey extracts a public key from a did:key string
func (customDIDPubKeyResolver) ResolveDIDKey(ctx context.Context, didStr string) (keys.DID, error) {
return keys.Parse(didStr)
}
-103
View File
@@ -1,103 +0,0 @@
// go:build jwx_es256k
package spec
import (
"fmt"
"time"
"github.com/cosmos/cosmos-sdk/types/bech32"
"github.com/golang-jwt/jwt"
"github.com/onsonr/sonr/crypto/keys"
"github.com/onsonr/sonr/crypto/ucan"
)
type (
Token = ucan.Token
Claims = ucan.Claims
Proof = ucan.Proof
Attenuations = ucan.Attenuations
Fact = ucan.Fact
)
var (
UCANVersion = ucan.UCANVersion
UCANVersionKey = ucan.UCANVersionKey
PrfKey = ucan.PrfKey
FctKey = ucan.FctKey
AttKey = ucan.AttKey
CapKey = ucan.CapKey
)
type ucanKeyshare struct {
addr string
issuerDID string
}
func (k ucanKeyshare) NewOriginToken(audienceDID string, att Attenuations, fct []Fact, notBefore, expires time.Time) (*ucan.Token, error) {
return k.newToken(audienceDID, nil, att, fct, notBefore, expires)
}
func (k ucanKeyshare) NewAttenuatedToken(parent *Token, audienceDID string, att ucan.Attenuations, fct []ucan.Fact, nbf, exp time.Time) (*Token, error) {
if !parent.Attenuations.Contains(att) {
return nil, fmt.Errorf("scope of ucan attenuations must be less than it's parent")
}
return k.newToken(audienceDID, append(parent.Proofs, Proof(parent.Raw)), att, fct, nbf, exp)
}
func (k ucanKeyshare) newToken(audienceDID string, prf []Proof, att Attenuations, fct []Fact, nbf, exp time.Time) (*ucan.Token, error) {
t := jwt.New(NewJWTSigningMethod("MPC256", k))
// if _, err := did.Parse(audienceDID); err != nil {
// return nil, fmt.Errorf("invalid audience DID: %w", err)
// }
t.Header[UCANVersionKey] = UCANVersion
var (
nbfUnix int64
expUnix int64
)
if !nbf.IsZero() {
nbfUnix = nbf.Unix()
}
if !exp.IsZero() {
expUnix = exp.Unix()
}
// set our claims
t.Claims = &Claims{
StandardClaims: &jwt.StandardClaims{
Issuer: k.issuerDID,
Audience: audienceDID,
NotBefore: nbfUnix,
// set the expire time
// see http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4.1.4
ExpiresAt: expUnix,
},
Attenuations: att,
Facts: fct,
Proofs: prf,
}
raw, err := t.SignedString(nil)
if err != nil {
return nil, err
}
return &Token{
Raw: raw,
Attenuations: att,
Facts: fct,
Proofs: prf,
}, nil
}
func getIssuerDID(pk keys.PubKey) (string, string, error) {
addr, err := bech32.ConvertAndEncode("idx", pk.Bytes())
if err != nil {
return "", "", err
}
return fmt.Sprintf("did:sonr:%s", addr), addr, nil
}
-170
View File
@@ -1,170 +0,0 @@
package mpc
import (
"crypto/aes"
"crypto/cipher"
"errors"
"fmt"
"math/big"
"github.com/cosmos/cosmos-sdk/types/bech32"
"github.com/onsonr/sonr/crypto/core/curves"
"github.com/onsonr/sonr/crypto/core/protocol"
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1"
"golang.org/x/crypto/sha3"
)
func checkIteratedErrors(aErr, bErr error) error {
if aErr == protocol.ErrProtocolFinished && bErr == protocol.ErrProtocolFinished {
return nil
}
if aErr != protocol.ErrProtocolFinished {
return aErr
}
if bErr != protocol.ErrProtocolFinished {
return bErr
}
return nil
}
func computeSonrAddr(pp Point) (string, error) {
pk := pp.ToAffineCompressed()
sonrAddr, err := bech32.ConvertAndEncode("idx", pk)
if err != nil {
return "", err
}
return sonrAddr, nil
}
func hashKey(key []byte) []byte {
hash := sha3.New256()
hash.Write(key)
return hash.Sum(nil)[:32] // Use first 32 bytes of hash
}
func decryptKeyshare(msg []byte, key []byte, nonce []byte) ([]byte, error) {
hashedKey := hashKey(key)
block, err := aes.NewCipher(hashedKey)
if err != nil {
return nil, err
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
plaintext, err := aesgcm.Open(nil, nonce, msg, nil)
if err != nil {
return nil, err
}
return plaintext, nil
}
func encryptKeyshare(msg Message, key []byte, nonce []byte) ([]byte, error) {
hashedKey := hashKey(key)
msgBytes, err := protocol.EncodeMessage(msg)
if err != nil {
return nil, err
}
block, err := aes.NewCipher(hashedKey)
if err != nil {
return nil, err
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
ciphertext := aesgcm.Seal(nil, nonce, []byte(msgBytes), nil)
return ciphertext, nil
}
func getAliceOut(msg *protocol.Message) (AliceOut, error) {
return dklsv1.DecodeAliceDkgResult(msg)
}
func getAlicePubPoint(msg *protocol.Message) (Point, error) {
out, err := dklsv1.DecodeAliceDkgResult(msg)
if err != nil {
return nil, err
}
return out.PublicKey, nil
}
func getBobOut(msg *protocol.Message) (BobOut, error) {
return dklsv1.DecodeBobDkgResult(msg)
}
func getBobPubPoint(msg *protocol.Message) (Point, error) {
out, err := dklsv1.DecodeBobDkgResult(msg)
if err != nil {
return nil, err
}
return out.PublicKey, nil
}
// getEcdsaPoint builds an elliptic curve point from a compressed byte slice
func getEcdsaPoint(pubKey []byte) (*curves.EcPoint, error) {
crv := curves.K256()
x := new(big.Int).SetBytes(pubKey[1:33])
y := new(big.Int).SetBytes(pubKey[33:])
ecCurve, err := crv.ToEllipticCurve()
if err != nil {
return nil, fmt.Errorf("error converting curve: %v", err)
}
return &curves.EcPoint{X: x, Y: y, Curve: ecCurve}, nil
}
func serializeSignature(sig *curves.EcdsaSignature) ([]byte, error) {
if sig == nil {
return nil, errors.New("nil signature")
}
rBytes := sig.R.Bytes()
sBytes := sig.S.Bytes()
// Ensure both components are 32 bytes
rPadded := make([]byte, 32)
sPadded := make([]byte, 32)
copy(rPadded[32-len(rBytes):], rBytes)
copy(sPadded[32-len(sBytes):], sBytes)
// Concatenate R and S
result := make([]byte, 64)
copy(result[0:32], rPadded)
copy(result[32:64], sPadded)
return result, nil
}
func deserializeSignature(sigBytes []byte) (*curves.EcdsaSignature, error) {
if len(sigBytes) != 64 {
return nil, fmt.Errorf("invalid signature length: expected 64 bytes, got %d", len(sigBytes))
}
r := new(big.Int).SetBytes(sigBytes[:32])
s := new(big.Int).SetBytes(sigBytes[32:])
return &curves.EcdsaSignature{
R: r,
S: s,
}, nil
}
func userSignFunc(k *keyEnclave, bz []byte) (SignFunc, error) {
curve := curves.K256()
return dklsv1.NewBobSign(curve, sha3.New256(), bz, k.UserShare, protocol.Version1)
}
func userRefreshFunc(k *keyEnclave) (RefreshFunc, error) {
curve := curves.K256()
return dklsv1.NewBobRefresh(curve, k.UserShare, protocol.Version1)
}
func valSignFunc(k *keyEnclave, bz []byte) (SignFunc, error) {
curve := curves.K256()
return dklsv1.NewAliceSign(curve, sha3.New256(), bz, k.ValShare, protocol.Version1)
}
func valRefreshFunc(k *keyEnclave) (RefreshFunc, error) {
curve := curves.K256()
return dklsv1.NewAliceRefresh(curve, k.ValShare, protocol.Version1)
}