/** * public static native boolean twosComp2bn(byte[], int, int) */ static jboolean NativeBN_twosComp2bn(JNIEnv* env, jclass cls, jbyteArray arr, int bytesLen, BIGNUM* ret) { if (!oneValidHandle(env, ret)) return FALSE; jboolean success; unsigned char* tmpBytes; tmpBytes = (unsigned char*)((*env)->GetPrimitiveArrayCritical(env, arr, 0)); if (tmpBytes != NULL) { if ((tmpBytes[0] & 0X80) == 0) { // Positive value! // // We can use the existing BN implementation for unsigned big endian bytes: // success = (BN_bin2bn(tmpBytes, bytesLen, ret) != NULL); BN_set_negative(ret, FALSE); } else { // Negative value! // // We need to apply two's complement: // success = negBigEndianBytes2bn(env, cls, tmpBytes, bytesLen, ret); BN_set_negative(ret, TRUE); } (*env)->ReleasePrimitiveArrayCritical(env, arr, tmpBytes, JNI_ABORT); return success; } else return -1; // Error outside BN. mc FIXME: what to do in this case? Does JNI throw exception itself? }
static jboolean NativeBN_twosComp2bn(JNIEnv* env, jclass cls, jbyteArray arr, int bytesLen, BIGNUM* ret) { if (!oneValidHandle(env, ret)) return JNI_FALSE; ScopedByteArrayRO bytes(env, arr); if (bytes.get() == NULL) { return -1; } jboolean success; const unsigned char* s = reinterpret_cast<const unsigned char*>(bytes.get()); if ((bytes[0] & 0X80) == 0) { // Positive value! // // We can use the existing BN implementation for unsigned big endian bytes: // success = (BN_bin2bn(s, bytesLen, ret) != NULL); BN_set_negative(ret, JNI_FALSE); } else { // Negative value! // // We need to apply two's complement: // success = negBigEndianBytes2bn(env, cls, s, bytesLen, ret); BN_set_negative(ret, JNI_TRUE); } return success; }
extern "C" void Java_java_math_NativeBN_twosComp2bn(JNIEnv* env, jclass cls, jbyteArray arr, int bytesLen, jlong ret0) { if (!oneValidHandle(env, ret0)) return; BIGNUM* ret = toBigNum(ret0); ScopedByteArrayRO bytes(env, arr); if (bytes.get() == NULL) { return; } const unsigned char* s = reinterpret_cast<const unsigned char*>(bytes.get()); if ((bytes[0] & 0X80) == 0) { // Positive value! // // We can use the existing BN implementation for unsigned big endian bytes: // BN_bin2bn(s, bytesLen, ret); BN_set_negative(ret, false); } else { // Negative value! // // We need to apply two's complement: // negBigEndianBytes2bn(env, cls, s, bytesLen, ret0); BN_set_negative(ret, true); } throwExceptionIfNecessary(env); }