code: func (x *XC) decryptSessionKey(ctx context.Context, hdr *xcpb.Header) ([]byte, error) {
  	// find a suiteable decryption key, i.e. a recipient entry which was encrypted
  	// for one of our private keys
  	recp, err := x.findDecryptionKey(hdr)
  	if err != nil {
  		return nil, errors.Wrapf(err, "unable to find decryption key")
  	}
  
  	// we need the senders public key to decrypt/verify the message, since the
  	// box algorithm ties successful decryption to successful verification
  	sender, err := x.findPublicKey(hdr.Sender)
  	if err != nil {
  		return nil, errors.Wrapf(err, "unable to find sender pub key for signature verification: %s", hdr.Sender)
  	}
  
  	// unlock recipient key
  	if err := x.decryptPrivateKey(ctx, recp); err != nil {
  		return nil, err
  	}
  
  	// this is the per recipient ciphertext, we need to decrypt it to extract
  	// the session key
  	ciphertext := hdr.Recipients[recp.Fingerprint()]
  
  	// since box works with byte arrays (or: pointers thereof) we need to copy
  	// the slice to fixed arrays
  	var nonce [24]byte
  	copy(nonce[:], ciphertext[:24])
  
  	var privKey [32]byte
  	pk := recp.PrivateKey()
  	copy(privKey[:], pk[:])
  
  	// now we can try to decrypt/verify the ciphertext. unfortunately box doesn't give
  	// us any diagnostic information in case it fails, i.e. we can't discern between
  	// a failed decryption and a failed verification
  	decrypted, ok := box.Open(nil, ciphertext[24:], &nonce, &sender.PublicKey, &privKey)
  	if !ok {
  		return nil, fmt.Errorf("failed to decrypt session key")
  	}
  	return decrypted, nil
  }
docs: // decryptSessionKey will attempt to find a readable recipient entry in the
  // header and decrypt it's session key