/**
 * public static native boolean litEndInts2bn(int[], int, int, int)
 * Note:
 * This procedure directly writes the internal representation of BIGNUMs.
 * We do so as there is no direct interface based on Little Endian Integer Arrays.
 * Also note that the same representation is used in the Cordoba Java Implementation of BigIntegers,
 *        whereof certain functionality is still being used.
 */
static jboolean NativeBN_litEndInts2bn(JNIEnv* env, jclass, jintArray arr, int len, jboolean neg, BIGNUM* ret) {
    if (!oneValidHandle(env, ret)) return JNI_FALSE;
    bn_check_top(ret);
    if (len > 0) {
        ScopedIntArrayRO scopedArray(env, arr);
        if (scopedArray.get() == NULL) {
            return JNI_FALSE;
        }

        STATIC_ASSERT(sizeof(BN_ULONG) == sizeof(jint), BN_ULONG_not_32_bit);
        const BN_ULONG* tmpInts = reinterpret_cast<const BN_ULONG*>(scopedArray.get());
        if ((tmpInts != NULL) && (bn_wexpand(ret, len) != NULL)) {
            int i = len; do { i--; ret->d[i] = tmpInts[i]; } while (i > 0);
            ret->top = len;
            ret->neg = neg;
            // need to call this due to clear byte at top if avoiding
            // having the top bit set (-ve number)
            // Basically get rid of top zero ints:
            bn_correct_top(ret);
            return JNI_TRUE;
        } else {
            return JNI_FALSE;
        }
    } else { // (len = 0) means value = 0 and sign will be 0, too.
        ret->top = 0;
        return JNI_TRUE;
    }
}
std::vector<uint8_t> getData(JNIEnv* env, jbyteArray javaArray) {
    std::vector<uint8_t> data;
    if (javaArray == nullptr) {
        return data;
    }

    ScopedByteArrayRO scopedArray(env, javaArray);
    size_t size = scopedArray.size();
    data.reserve(size);
    for (size_t i = 0; i < size; i++) {
        data.push_back(static_cast<uint8_t>(scopedArray[i]));
    }
    return data;
}