func (p *Packer) Unpack(envelope []byte) (*transport.Envelope, error) {
	jwe, _, _, err := deserializeEnvelope(envelope)
	if err != nil {
		return nil, fmt.Errorf("failed to deserialize envelope: %w", err)
	}
	for i := range jwe.Recipients {
		var (
			recKey *cryptoapi.PublicKey
			pt     []byte
			recKID string
			env    *transport.Envelope
		)
		recKey, recKID, err = p.pubKey(i, jwe)
		if err != nil {
			return nil, fmt.Errorf("authcrypt Unpack: %w", err)
		}
		_, err = p.kms.Get(recKey.KID)
		if err != nil {
			if errors.Is(err, storage.ErrDataNotFound) {
				retriesMsg := ""
				if i < len(jwe.Recipients) {
					retriesMsg = ", will try another recipient"
				}
				logger.Debugf("authcrypt Unpack: recipient keyID not found in KMS: %v%s", recKey.KID, retriesMsg)
				continue
			}
			return nil, fmt.Errorf("authcrypt Unpack: failed to get key from kms: %w", err)
		}
		jweDecrypter := jose.NewJWEDecrypt(p.kidResolvers, p.cryptoService, p.kms)
		pt, err = jweDecrypter.Decrypt(jwe)
		if err != nil {
			return nil, fmt.Errorf("authcrypt Unpack: failed to decrypt JWE envelope: %w", err)
		}
		env, err = p.buildEnvelope(recKey, recKID, pt, jwe)
		if err != nil {
			return nil, fmt.Errorf("authcrypt Unpack: %w", err)
		}
		return env, nil
	}
	return nil, fmt.Errorf("authcrypt Unpack: no matching recipient in envelope")
}
Unpack will decode the envelope using a standard format. Using either did:key KID resolver or the
DIDDoc.KeyAgreement[].VerificationMethod.ID resolver which are set in p.resolvers.
package authcrypt
import (
	"encoding/json"
	"errors"
	"fmt"
	"strings"
	"github.com/google/tink/go/keyset"
	"github.com/hyperledger/aries-framework-go/pkg/common/log"
	cryptoapi "github.com/hyperledger/aries-framework-go/pkg/crypto"
	"github.com/hyperledger/aries-framework-go/pkg/didcomm/packer"
	"github.com/hyperledger/aries-framework-go/pkg/didcomm/transport"
	"github.com/hyperledger/aries-framework-go/pkg/doc/jose"
	"github.com/hyperledger/aries-framework-go/pkg/doc/jose/kid/resolver"
	"github.com/hyperledger/aries-framework-go/pkg/kms"
	"github.com/hyperledger/aries-framework-go/spi/storage"
)
var logger = log.New("aries-framework/pkg/didcomm/packer/authcrypt")
type Packer struct {
	kms           kms.KeyManager
	encAlg        jose.EncAlg
	cryptoService cryptoapi.Crypto
	kidResolvers  []resolver.KIDResolver
}
func New(ctx packer.Provider, encAlg jose.EncAlg) (*Packer, error) {
	err := validateEncAlg(encAlg)
	if err != nil {
		return nil, fmt.Errorf("authcrypt: %w", err)
	}
	k := ctx.KMS()
	if k == nil {
		return nil, errors.New("authcrypt: failed to create packer because KMS is empty")
	}
	c := ctx.Crypto()
	if c == nil {
		return nil, errors.New("authcrypt: failed to create packer because crypto service is empty")
	}
	vdrReg := ctx.VDRegistry()
	if vdrReg == nil {
		return nil, errors.New("authcrypt: failed to create packer because vdr registry is empty")
	}
	var kidResolvers []resolver.KIDResolver
	kidResolvers = append(kidResolvers, &resolver.DIDKeyResolver{}, &resolver.DIDDocResolver{VDRRegistry: vdrReg})
	return &Packer{
		kms:           k,
		encAlg:        encAlg,
		cryptoService: c,
		kidResolvers:  kidResolvers,
	}, nil
}
func validateEncAlg(alg jose.EncAlg) error {
	switch alg {
	case jose.A128CBCHS256, jose.A192CBCHS384ALG, jose.A256CBCHS384, jose.A256CBCHS512, jose.XC20P:
		return nil
	default:
		return fmt.Errorf("unsupported content encrytpion algorithm: %v", alg)
	}
}
func (p *Packer) Pack(contentType string, payload, senderID []byte, recipientsPubKeys [][]byte) ([]byte, error) {
	if len(recipientsPubKeys) == 0 {
		return nil, fmt.Errorf("authcrypt Pack: empty recipientsPubKeys")
	}
	recECKeys, aad, err := unmarshalRecipientKeys(recipientsPubKeys)
	if err != nil {
		return nil, fmt.Errorf("authcrypt Pack: failed to convert recipient keys: %w", err)
	}
	senderKID := string(senderID)
	skid := senderKID
	if idx := strings.Index(senderKID, "."); idx > 0 {
		senderKID = senderKID[:idx]  
		skid = skid[idx+1:]          
	}
	kh, err := p.kms.Get(senderKID)
	if err != nil {
		return nil, fmt.Errorf("authcrypt Pack: failed to get sender key from KMS: %w", err)
	}
	jweEncrypter, err := jose.NewJWEEncrypt(p.encAlg, p.EncodingType(), contentType, skid,
		kh.(*keyset.Handle), recECKeys, p.cryptoService)
	if err != nil {
		return nil, fmt.Errorf("authcrypt Pack: failed to new JWEEncrypt instance: %w", err)
	}
	jwe, err := jweEncrypter.EncryptWithAuthData(payload, aad)
	if err != nil {
		return nil, fmt.Errorf("authcrypt Pack: failed to encrypt payload: %w", err)
	}
	mPh, err := json.Marshal(jwe.ProtectedHeaders)
	if err != nil {
		return nil, fmt.Errorf("anoncrypt Pack: %w", err)
	}
	logger.Debugf("protected headers: %s", mPh)
	var s string
	if len(recipientsPubKeys) == 1 {
		s, err = jwe.CompactSerialize(json.Marshal)
	} else {
		s, err = jwe.FullSerialize(json.Marshal)
	}
	if err != nil {
		return nil, fmt.Errorf("authcrypt Pack: failed to serialize JWE message: %w", err)
	}
	return []byte(s), nil
}
func unmarshalRecipientKeys(keys [][]byte) ([]*cryptoapi.PublicKey, []byte, error) {
	var (
		pubKeys []*cryptoapi.PublicKey
		aad     []byte
	)
	for _, key := range keys {
		var ecKey *cryptoapi.PublicKey
		err := json.Unmarshal(key, &ecKey)
		if err != nil {
			return nil, nil, err
		}
		pubKeys = append(pubKeys, ecKey)
	}
	return pubKeys, aad, nil
}