// Path: underbar.ocho/src/main/java/com/tailoredshapes/underbar/ocho/Die.java
// public static void dieIf(boolean condition, Supplier<String> message) {
//     if (condition) {
//         die(message.get());
//     }
// }
// 
// Path: underbar.ocho/src/main/java/com/tailoredshapes/underbar/ocho/Die.java
// public static void rethrow(RunnableWithOops runnable, Supplier<String> errorMessage) {
//     try {
//         runnable.run();
//     } catch (Throwable e) {
//         die(e, errorMessage.get());
//     }
// }
// 
// Path: underbar.ocho/src/main/java/com/tailoredshapes/underbar/ocho/UnderBar.java
// static <T> List<T> filter(Iterable<T> ts, Predicate<T> predicate) {
//     return stream(ts).filter(predicate).collect(toList());
// }
// 
// Path: underbar.ocho/src/main/java/com/tailoredshapes/underbar/ocho/UnderBar.java
// @SafeVarargs
// static <T> List<T> list(T... ts) {
//     return Arrays.asList(ts);
// }


import javax.crypto.Cipher;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.Base64;
import static com.tailoredshapes.underbar.ocho.Die.dieIf;
import static com.tailoredshapes.underbar.ocho.Die.rethrow;
import static com.tailoredshapes.underbar.ocho.UnderBar.filter;
import static com.tailoredshapes.underbar.ocho.UnderBar.list;

        byte[] exponent = new byte[rethrow(in::readInt)];
        rethrow(() -> in.readFully(exponent));
        BigInteger e = new BigInteger(exponent);

        byte[] modulo = new byte[rethrow(in::readInt)];
        rethrow(() -> in.readFully(modulo));
        BigInteger m = new BigInteger(modulo);

        RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(m, e);
        return rethrow(() -> KeyFactory.getInstance("RSA").generatePublic(rsaPublicKeySpec));
    }

    static byte[] encrypt(PublicKey key, byte[] message){
        Cipher rsa = rethrow( () -> Cipher.getInstance("RSA"));
        rethrow(() -> rsa.init(Cipher.ENCRYPT_MODE, key));
        return rethrow(() -> rsa.doFinal(message));
    }

    static byte[] decrypt(PrivateKey key, byte[] cipher){
        Cipher rsa = rethrow( () -> Cipher.getInstance("RSA"));
        rethrow(() -> rsa.init(Cipher.DECRYPT_MODE, key));
        return rethrow(() -> rsa.doFinal(cipher));
    }

    static String encrypt(PublicKey key, String message, boolean isUrlSafe){
        return isUrlSafe ? Base64.getUrlEncoder().encodeToString(encrypt(key, message.getBytes())) :
                Base64.getEncoder().encodeToString(encrypt(key, message.getBytes()));
    }

// Path: underbar.ocho/src/main/java/com/tailoredshapes/underbar/ocho/Die.java
// public static void dieIf(boolean condition, Supplier<String> message) {
//     if (condition) {
//         die(message.get());
//     }
// }
// 
// Path: underbar.ocho/src/main/java/com/tailoredshapes/underbar/ocho/Die.java
// public static void rethrow(RunnableWithOops runnable, Supplier<String> errorMessage) {
//     try {
//         runnable.run();
//     } catch (Throwable e) {
//         die(e, errorMessage.get());
//     }
// }
// 
// Path: underbar.ocho/src/main/java/com/tailoredshapes/underbar/ocho/UnderBar.java
// static <T> List<T> filter(Iterable<T> ts, Predicate<T> predicate) {
//     return stream(ts).filter(predicate).collect(toList());
// }
// 
// Path: underbar.ocho/src/main/java/com/tailoredshapes/underbar/ocho/UnderBar.java
// @SafeVarargs
// static <T> List<T> list(T... ts) {
//     return Arrays.asList(ts);
// }


// Path: underbar.crypto/src/main/java/com/tailoredshapes/underbar/crypto/RSA.java
import javax.crypto.Cipher;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.Base64;
import static com.tailoredshapes.underbar.ocho.Die.dieIf;
import static com.tailoredshapes.underbar.ocho.Die.rethrow;
import static com.tailoredshapes.underbar.ocho.UnderBar.filter;
import static com.tailoredshapes.underbar.ocho.UnderBar.list;


        byte[] exponent = new byte[rethrow(in::readInt)];
        rethrow(() -> in.readFully(exponent));
        BigInteger e = new BigInteger(exponent);

        byte[] modulo = new byte[rethrow(in::readInt)];
        rethrow(() -> in.readFully(modulo));
        BigInteger m = new BigInteger(modulo);

        RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(m, e);
        return rethrow(() -> KeyFactory.getInstance("RSA").generatePublic(rsaPublicKeySpec));
    }

    static byte[] encrypt(PublicKey key, byte[] message){
        Cipher rsa = rethrow( () -> Cipher.getInstance("RSA"));
        rethrow(() -> rsa.init(Cipher.ENCRYPT_MODE, key));
        return rethrow(() -> rsa.doFinal(message));
    }

    static byte[] decrypt(PrivateKey key, byte[] cipher){
        Cipher rsa = rethrow( () -> Cipher.getInstance("RSA"));
        rethrow(() -> rsa.init(Cipher.DECRYPT_MODE, key));
        return rethrow(() -> rsa.doFinal(cipher));
    }

    static String encrypt(PublicKey key, String message, boolean isUrlSafe){
        return isUrlSafe ? Base64.getUrlEncoder().encodeToString(encrypt(key, message.getBytes())) :
                Base64.getEncoder().encodeToString(encrypt(key, message.getBytes()));
    }

    static String encrypt(PublicKey key, String message){