// Path: src/main/java/org/abstractj/kalium/encoders/Encoder.java
// public interface Encoder {
// 
//     public static final Charset CHARSET = Charset.forName("US-ASCII");
// 
//     public static final Hex HEX = new Hex();
//     public static final Raw RAW = new Raw();
// 
//     public byte[] decode(String data);
// 
//     public String encode(final byte[] data);
// }
// 
// Path: src/main/java/org/abstractj/kalium/NaCl.java
// public static Sodium sodium() {
//     Sodium sodium = SingletonHolder.SODIUM_INSTANCE;
//     checkVersion(sodium);
//     return sodium;
// }
// 
// Path: src/main/java/org/abstractj/kalium/crypto/Util.java
// public static boolean isValid(int status, String message) {
//     if (status != 0)
//         throw new RuntimeException(message);
//     return true;
// }


import org.abstractj.kalium.encoders.Encoder;
import static org.abstractj.kalium.NaCl.Sodium.CRYPTO_BOX_SEALBYTES;
import static org.abstractj.kalium.NaCl.sodium;
import static org.abstractj.kalium.crypto.Util.isValid;
    }

    public SealedBox(String publicKey, Encoder encoder) {
        this(encoder.decode(publicKey));
    }

    public SealedBox(byte[] publicKey, byte[] privateKey) {
        this.publicKey = publicKey;
        this.privateKey = privateKey;
    }

    public SealedBox(String publicKey, String privateKey, Encoder encoder) {
        this(encoder.decode(publicKey), encoder.decode(privateKey));
    }

    public byte[] encrypt(byte[] message) {
        if (publicKey == null)
            throw new RuntimeException("Encryption failed. Public key not available.");
        byte[] ct = new byte[message.length + CRYPTO_BOX_SEALBYTES];
        isValid(sodium().crypto_box_seal(
                        ct, message, message.length, publicKey),
                "Encryption failed");
        return ct;
    }

    public byte[] decrypt(byte[] ciphertext) {
        if (privateKey == null)
            throw new RuntimeException("Decryption failed. Private key not available.");

        byte[] message = new byte[ciphertext.length - CRYPTO_BOX_SEALBYTES];
// Path: src/main/java/org/abstractj/kalium/encoders/Encoder.java
// public interface Encoder {
// 
//     public static final Charset CHARSET = Charset.forName("US-ASCII");
// 
//     public static final Hex HEX = new Hex();
//     public static final Raw RAW = new Raw();
// 
//     public byte[] decode(String data);
// 
//     public String encode(final byte[] data);
// }
// 
// Path: src/main/java/org/abstractj/kalium/NaCl.java
// public static Sodium sodium() {
//     Sodium sodium = SingletonHolder.SODIUM_INSTANCE;
//     checkVersion(sodium);
//     return sodium;
// }
// 
// Path: src/main/java/org/abstractj/kalium/crypto/Util.java
// public static boolean isValid(int status, String message) {
//     if (status != 0)
//         throw new RuntimeException(message);
//     return true;
// }


// Path: src/main/java/org/abstractj/kalium/crypto/SealedBox.java
import org.abstractj.kalium.encoders.Encoder;
import static org.abstractj.kalium.NaCl.Sodium.CRYPTO_BOX_SEALBYTES;
import static org.abstractj.kalium.NaCl.sodium;
import static org.abstractj.kalium.crypto.Util.isValid;

    }

    public SealedBox(String publicKey, Encoder encoder) {
        this(encoder.decode(publicKey));
    }

    public SealedBox(byte[] publicKey, byte[] privateKey) {
        this.publicKey = publicKey;
        this.privateKey = privateKey;
    }

    public SealedBox(String publicKey, String privateKey, Encoder encoder) {
        this(encoder.decode(publicKey), encoder.decode(privateKey));
    }

    public byte[] encrypt(byte[] message) {
        if (publicKey == null)
            throw new RuntimeException("Encryption failed. Public key not available.");
        byte[] ct = new byte[message.length + CRYPTO_BOX_SEALBYTES];
        isValid(sodium().crypto_box_seal(
                        ct, message, message.length, publicKey),
                "Encryption failed");
        return ct;
    }

    public byte[] decrypt(byte[] ciphertext) {
        if (privateKey == null)
            throw new RuntimeException("Decryption failed. Private key not available.");

        byte[] message = new byte[ciphertext.length - CRYPTO_BOX_SEALBYTES];
        isValid(sodium().crypto_box_seal_open(