# Class BSV::Auth::MasterCertificate <a id="class-BSV-Auth-MasterCertificate"></a>

**Inherits:** `BSV::Auth::Certificate`

A Certificate subclass that manages a master keyring for certificate issuance
and selective field disclosure.

MasterCertificate adds a `master_keyring` to the base Certificate. The master
keyring maps each field name to a Base64-encoded encrypted symmetric key that
was used to encrypt that field's value. This allows the certificate holder to:

1.  Decrypt all fields via {.decrypt_fields}.
2.  Re-encrypt individual field keys for a specific verifier via
    {.create_keyring_for_verifier}, producing a {VerifiableCertificate}.

## Protocol details

Field encryption uses BRC-42 key derivation:

*   Protocol:    +[2, 'certificate field encryption']+
*   Master key ID (no serial):  `field_name`
*   Verifier key ID (with serial): +"#{serial_number} #{field_name}"+

Wallet parameters are duck-typed — any object responding to
<code>:encrypt</code>, <code>:decrypt</code>, and <code>:get_public_key</code>
is accepted.

- **@see** `BSV::Auth::Certificate` base class
- **@see** `BSV::Auth::VerifiableCertificate` consumer of verifier keyrings

## Attributes
### `master_keyring` [R] <a id="attribute-i-master_keyring"></a> <a id="master_keyring-instance_method"></a>
- **@return** [Hash] mapping field names to Base64-encoded encrypted symmetric keys

## Public Class Methods
### `create_certificate_fields(creator_wallet, certifier_or_subject, fields, privileged: = false, privileged_reason: = nil)` <a id="method-c-create_certificate_fields"></a> <a id="create_certificate_fields-class_method"></a>
Encrypts certificate fields and generates a master keyring.

For each field:
1.  Generates a random {BSV::Primitives::SymmetricKey}.
2.  Encrypts the field value with that key.
3.  Encrypts the symmetric key bytes for `certifier_or_subject` using BRC-42
    with key_id = `field_name` (no serial number).
- **@param** `creator_wallet` [#encrypt] wallet used to encrypt field keys
- **@param** `certifier_or_subject` [String] counterparty pubkey hex, +'self'+,
or +'anyone'+ — the party who will later decrypt the master keyring
- **@param** `fields` [Hash] plain-text field name → plain-text field value
- **@param** `privileged` [Boolean] whether this is a privileged operation
- **@param** `privileged_reason` [String, nil] reason for privileged access
- **@return** [Hash] +{ certificate_fields: Hash, master_keyring: Hash }+

### `create_keyring_for_verifier(subject_wallet, certifier:, verifier:, fields:, fields_to_reveal:, master_keyring:, serial_number:, privileged: = false, privileged_reason: = nil)` <a id="method-c-create_keyring_for_verifier"></a> <a id="create_keyring_for_verifier-class_method"></a>
Creates a verifier-specific keyring for selective field disclosure.

For each field in `fields_to_reveal`:
1.  Decrypts the master symmetric key (counterparty = certifier, key_id =
    field_name only).
2.  Verifies the decrypted key actually decrypts the field value.
3.  Re-encrypts the key for the verifier with key_id = +"#{serial_number}
    #{field_name}"+.

The resulting keyring is suitable for constructing a {VerifiableCertificate}.
- **@param** `subject_wallet` [#encrypt, #decrypt] subject's wallet
- **@param** `certifier` [String] certifier pubkey hex, +'self'+, or +'anyone'+
- **@param** `verifier` [String] verifier pubkey hex, +'self'+, or +'anyone'+
- **@param** `fields` [Hash] field name → encrypted field value (Base64)
- **@param** `fields_to_reveal` [Array<String>] subset of field names to expose
- **@param** `master_keyring` [Hash] field name → Base64 encrypted symmetric key
- **@param** `serial_number` [String] certificate serial number (Base64)
- **@param** `privileged` [Boolean] whether this is a privileged operation
- **@param** `privileged_reason` [String, nil] reason for privileged access
- **@raise** [ArgumentError] if +fields_to_reveal+ is not an Array
- **@raise** [ArgumentError] if a field to reveal does not exist in +fields+
- **@return** [Hash] field name → Base64 encrypted key (verifier-specific)

### `decrypt_field(wallet, master_keyring, field_name, field_value, counterparty, privileged: = false, privileged_reason: = nil)` <a id="method-c-decrypt_field"></a> <a id="decrypt_field-class_method"></a>
Decrypts a single certificate field.

1.  Decrypts the encrypted symmetric key from `master_keyring` for
    `field_name`.
2.  Uses the decrypted key bytes as a {BSV::Primitives::SymmetricKey}.
3.  Decrypts the field value and returns both the key and plaintext.
- **@param** `wallet` [#decrypt] subject's or certifier's wallet
- **@param** `master_keyring` [Hash] field name → Base64 encrypted symmetric key
- **@param** `field_name` [String] name of the field to decrypt
- **@param** `field_value` [String] Base64-encoded encrypted field value
- **@param** `counterparty` [String] pubkey hex, +'self'+, or +'anyone'+
- **@param** `privileged` [Boolean] whether this is a privileged operation
- **@param** `privileged_reason` [String, nil] reason for privileged access
- **@raise** [ArgumentError] if +master_keyring+ is nil or empty
- **@raise** [RuntimeError] if decryption fails
- **@return** [Hash] +{ field_revelation_key: Array<Integer>, decrypted_field_value: String }+

### `decrypt_fields(wallet, master_keyring, fields, counterparty, privileged: = false, privileged_reason: = nil)` <a id="method-c-decrypt_fields"></a> <a id="decrypt_fields-class_method"></a>
Decrypts all fields in the certificate using a master keyring.
- **@param** `wallet` [#decrypt] subject's or certifier's wallet
- **@param** `master_keyring` [Hash] field name → Base64 encrypted symmetric key
- **@param** `fields` [Hash] field name → Base64 encrypted field value
- **@param** `counterparty` [String] pubkey hex, +'self'+, or +'anyone'+
- **@param** `privileged` [Boolean] whether this is a privileged operation
- **@param** `privileged_reason` [String, nil] reason for privileged access
- **@raise** [ArgumentError] if +master_keyring+ is nil or empty
- **@raise** [RuntimeError] if decryption fails for any field
- **@return** [Hash] field name → decrypted plaintext string

### `from_hash(hash)` <a id="method-c-from_hash"></a> <a id="from_hash-class_method"></a>
Construct a MasterCertificate from a plain Hash.

Accepts both snake_case and camelCase key variants.
- **@param** `hash` [Hash] certificate data
- **@return** [MasterCertificate]

### `issue_certificate_for_subject(certifier_wallet, subject, fields, certificate_type, get_revocation_outpoint: = nil, serial_number: = nil)` <a id="method-c-issue_certificate_for_subject"></a> <a id="issue_certificate_for_subject-class_method"></a>
Issues a signed MasterCertificate for a subject.

1.  Generates a random 32-byte serial_number if none provided.
2.  Calls {.create_certificate_fields} to encrypt fields and build the master
    keyring.
3.  Resolves +'self'+ subject to the certifier's identity key.
4.  Obtains a revocation outpoint (via callback or default placeholder).
5.  Constructs and signs the MasterCertificate.
- **@param** `certifier_wallet` [#encrypt, #create_signature, #get_public_key] certifier's wallet
- **@param** `subject` [String] subject pubkey hex, +'self'+, or +'anyone'+
- **@param** `fields` [Hash] plain-text field name → plain-text field value
- **@param** `certificate_type` [String] Base64-encoded type (32 bytes decoded)
- **@param** `get_revocation_outpoint` [Proc, nil] called with serial_number; returns outpoint string
- **@param** `serial_number` [String, nil] custom serial_number (Base64); randomly generated if nil
- **@return** [MasterCertificate] signed certificate

## Public Instance Methods
### `initialize(type:, serial_number:, subject:, certifier:, revocation_outpoint:, fields:, master_keyring:, signature: = nil)` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
- **@param** `type` [String] Base64 string (32 bytes decoded)
- **@param** `serial_number` [String] Base64 string (32 bytes decoded)
- **@param** `subject` [String] compressed public key hex
- **@param** `certifier` [String] compressed public key hex
- **@param** `revocation_outpoint` [String] +"<txid_hex>.<output_index>"+
- **@param** `fields` [Hash] field name strings to encrypted value strings (Base64)
- **@param** `master_keyring` [Hash] field name strings to Base64-encoded encrypted symmetric keys
- **@param** `signature` [String, nil] DER-encoded signature hex, or nil
- **@raise** [ArgumentError] if any field in +fields+ is missing from +master_keyring+
- **@return** [MasterCertificate] a new instance of MasterCertificate

### `to_h()` <a id="method-i-to_h"></a> <a id="to_h-instance_method"></a>
Return the certificate as a plain Hash with snake_case keys, including
`master_keyring`.
- **@return** [Hash]
