# Class BSV::Primitives::SymmetricKey <a id="class-BSV-Primitives-SymmetricKey"></a>

**Inherits:** `Object`

AES-256-GCM symmetric encryption.

Provides authenticated encryption matching the interface used by the TS, Go,
and Python reference SDKs. The wire format is:

    |--- 32-byte IV ---|--- ciphertext ---|--- 16-byte auth tag ---|

All three reference SDKs use a 32-byte IV (non-standard but cross-SDK
compatible) and 16-byte authentication tag.

**@example Round-trip encryption**
```ruby
key = BSV::Primitives::SymmetricKey.from_random
encrypted = key.encrypt('hello world')
key.decrypt(encrypted) #=> "hello world"
```

## Constants
### `IV_SIZE` <a id="constant-IV_SIZE"></a> <a id="IV_SIZE-constant"></a>
Not documented.

### `KEY_SIZE` <a id="constant-KEY_SIZE"></a> <a id="KEY_SIZE-constant"></a>
Not documented.

### `TAG_SIZE` <a id="constant-TAG_SIZE"></a> <a id="TAG_SIZE-constant"></a>
Not documented.

## Public Class Methods
### `from_ecdh(private_key, public_key)` <a id="method-c-from_ecdh"></a> <a id="from_ecdh-class_method"></a>
Derive a symmetric key from an ECDH shared secret.

Computes the shared point between the two parties and uses the X-coordinate as
the key material. The X-coordinate may be 31 or 32 bytes; shorter values are
left-zero-padded automatically.
- **@param** `private_key` [PrivateKey] one party's private key
- **@param** `public_key` [PublicKey] the other party's public key
- **@return** [SymmetricKey]

**@example Alice and Bob derive the same key**
```ruby
alice_key = SymmetricKey.from_ecdh(alice_priv, bob_pub)
bob_key   = SymmetricKey.from_ecdh(bob_priv, alice_pub)
alice_key.to_bytes == bob_key.to_bytes #=> true
```

### `from_random()` <a id="method-c-from_random"></a> <a id="from_random-class_method"></a>
Generate a random symmetric key.
- **@return** [SymmetricKey]

## Public Instance Methods
### `decrypt(data)` <a id="method-i-decrypt"></a> <a id="decrypt-instance_method"></a>
Decrypt an AES-256-GCM encrypted message.

Expects the wire format: IV (32) + ciphertext + auth tag (16).
- **@param** `data` [String] the encrypted message
- **@raise** [ArgumentError] if the data is too short
- **@raise** [OpenSSL::Cipher::CipherError] if authentication fails (wrong key or tampered data)
- **@return** [String] the decrypted plaintext (binary)

### `encrypt(plaintext)` <a id="method-i-encrypt"></a> <a id="encrypt-instance_method"></a>
Encrypt a message with AES-256-GCM.

Generates a random 32-byte IV per call. Returns the concatenation of IV,
ciphertext, and 16-byte authentication tag.
- **@param** `plaintext` [String] the message to encrypt
- **@return** [String] binary string: IV (32) + ciphertext + auth tag (16)

### `initialize(key_bytes)` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
- **@param** `key_bytes` [String] 32-byte binary key (shorter keys are left-zero-padded)
- **@raise** [ArgumentError] if key is empty or longer than 32 bytes
- **@return** [SymmetricKey] a new instance of SymmetricKey

### `to_bytes()` <a id="method-i-to_bytes"></a> <a id="to_bytes-instance_method"></a>
Return the raw key bytes.
- **@return** [String] 32-byte binary key
