add support for P256Key2021

This commit is contained in:
Michael Muré
2025-07-03 15:49:47 +02:00
parent f97dbe76a2
commit 15a5d2f5f9
2 changed files with 141 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
package p256vm
import (
"encoding/json"
"errors"
"fmt"
"github.com/mr-tron/base58"
"github.com/INFURA/go-did"
"github.com/INFURA/go-did/crypto"
"github.com/INFURA/go-did/crypto/p256"
)
// Specification: missing
const (
JsonLdContext2021 = "https://w3id.org/security/suites/multikey-2021/v1"
Type2021 = "P256Key2021"
)
var _ did.VerificationMethodSignature = &Key2021{}
var _ did.VerificationMethodKeyAgreement = &Key2021{}
type Key2021 struct {
id string
pubkey *p256.PublicKey
controller string
}
func NewKey2021(id string, pubkey *p256.PublicKey, controller did.DID) *Key2021 {
return &Key2021{
id: id,
pubkey: pubkey,
controller: controller.String(),
}
}
func (m Key2021) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
ID string `json:"id"`
Type string `json:"type"`
Controller string `json:"controller"`
PublicKeyBase58 string `json:"publicKeyBase58"`
}{
ID: m.ID(),
Type: m.Type(),
Controller: m.Controller(),
PublicKeyBase58: base58.Encode(m.pubkey.ToBytes()),
})
}
func (m *Key2021) UnmarshalJSON(bytes []byte) error {
aux := struct {
ID string `json:"id"`
Type string `json:"type"`
Controller string `json:"controller"`
PublicKeyBase58 string `json:"publicKeyBase58"`
}{}
err := json.Unmarshal(bytes, &aux)
if err != nil {
return err
}
if aux.Type != m.Type() {
return errors.New("invalid type")
}
m.id = aux.ID
if len(m.id) == 0 {
return errors.New("invalid id")
}
m.controller = aux.Controller
if !did.HasValidDIDSyntax(m.controller) {
return errors.New("invalid controller")
}
pubBytes, err := base58.Decode(aux.PublicKeyBase58)
if err != nil {
return fmt.Errorf("invalid publicKeyBase58: %w", err)
}
m.pubkey, err = p256.PublicKeyFromBytes(pubBytes)
if err != nil {
return fmt.Errorf("invalid publicKeyBase58: %w", err)
}
return nil
}
func (m Key2021) ID() string {
return m.id
}
func (m Key2021) Type() string {
return Type2021
}
func (m Key2021) Controller() string {
return m.controller
}
func (m Key2021) JsonLdContext() string {
return JsonLdContext2021
}
func (m Key2021) Verify(data []byte, sig []byte) (bool, error) {
return m.pubkey.VerifyBytes(data, sig), nil
}
func (m Key2021) PrivateKeyIsCompatible(local crypto.PrivateKeyKeyExchange) bool {
return local.PublicKeyIsCompatible(m.pubkey)
}
func (m Key2021) KeyExchange(local crypto.PrivateKeyKeyExchange) ([]byte, error) {
return local.KeyExchange(m.pubkey)
}

View File

@@ -0,0 +1,27 @@
package p256vm_test
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
p256vm "github.com/INFURA/go-did/verifications/p256"
)
func TestJsonRoundTrip(t *testing.T) {
data := `{
"id": "did:key:zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb#zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb",
"type": "P256Key2021",
"controller": "did:key:zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb",
"publicKeyBase58": "ekVhkcBFq3w7jULLkBVye6PwaTuMbhJYuzwFnNcgQAPV"
}`
var mk p256vm.Key2021
err := json.Unmarshal([]byte(data), &mk)
require.NoError(t, err)
bytes, err := json.Marshal(mk)
require.NoError(t, err)
require.JSONEq(t, data, string(bytes))
}