/**
 * 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;
    }
}
Example #2
0
/**
 * 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?
}
extern "C" void Java_java_math_NativeBN_BN_1generate_1prime_1ex(JNIEnv* env, jclass, jlong ret, int bits,
                                          jboolean safe, jlong add, jlong rem, jlong cb) {
  if (!oneValidHandle(env, ret)) return;
  BN_generate_prime_ex(toBigNum(ret), bits, safe, toBigNum(add), toBigNum(rem),
                       reinterpret_cast<BN_GENCB*>(cb));
  throwExceptionIfNecessary(env);
}
Example #4
0
/**
 * 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 cls, jintArray arr, int len, jboolean neg, BIGNUM* ret) {
    if (!oneValidHandle(env, ret)) return FALSE;
    bn_check_top(ret);
	if (len > 0) {
        BN_ULONG* tmpInts; // BN_ULONG is 4 Bytes on this system for sure, i.e. same as jint!
        tmpInts = (BN_ULONG*)((*env)->GetPrimitiveArrayCritical(env, arr, 0));
        if ((tmpInts != NULL) && (bn_wexpand(ret, len) != NULL)) {
            int i = len; do { i--; ret->d[i] = tmpInts[i]; } while (i > 0);
            (*env)->ReleasePrimitiveArrayCritical(env, arr, tmpInts, JNI_ABORT);
            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 TRUE;
        }
        else {
            if (tmpInts != NULL)
                (*env)->ReleasePrimitiveArrayCritical(env, arr, tmpInts, JNI_ABORT);
            return FALSE;
        }
	}
	else { // (len = 0) means value = 0 and sign will be 0, too.
		ret->top = 0;
    	return TRUE;
	}
}
static int NativeBN_BN_hex2bn(JNIEnv* env, jclass, BIGNUM* a, jstring str) {
    if (!oneValidHandle(env, a)) return -1;
    ScopedUtfChars chars(env, str);
    if (chars.c_str() == NULL) {
        return -1;
    }
    return BN_hex2bn(&a, chars.c_str());
}
extern "C" int Java_java_math_NativeBN_sign(JNIEnv* env, jclass, jlong a) {
  if (!oneValidHandle(env, a)) return -2;
  if (BN_is_zero(toBigNum(a))) {
      return 0;
  } else if (BN_is_negative(toBigNum(a))) {
    return -1;
  }
  return 1;
}
Example #7
0
/**
 * public static native int BN_hex2bn(int, java.lang.String)
 */
static int NativeBN_BN_hex2bn(JNIEnv* env, jclass cls, BIGNUM* a, jstring str) {
   if (!oneValidHandle(env, a)) return -1;
    char* tmpStr = (char*)(*env)->GetStringUTFChars(env, str, NULL);
    if (tmpStr != NULL) {
        int len = BN_hex2bn(&a, tmpStr);
        (*env)->ReleaseStringUTFChars(env, str, tmpStr);
        return len; // len == 0: Error
    }
    else return -1; // Error outside BN.
}
extern "C" int Java_java_math_NativeBN_BN_1hex2bn(JNIEnv* env, jclass, jlong a0, jstring str) {
  if (!oneValidHandle(env, a0)) return -1;
  ScopedUtfChars chars(env, str);
  if (chars.c_str() == NULL) {
    return -1;
  }
  BIGNUM* a = toBigNum(a0);
  int result = BN_hex2bn(&a, chars.c_str());
  throwExceptionIfNecessary(env);
  return result;
}
extern "C" jstring Java_java_math_NativeBN_BN_1bn2hex(JNIEnv* env, jclass, jlong a) {
  if (!oneValidHandle(env, a)) return NULL;
  char* tmpStr = BN_bn2hex(toBigNum(a));
  if (tmpStr == NULL) {
    return NULL;
  }
  char* retStr = leadingZerosTrimmed(tmpStr);
  jstring returnJString = env->NewStringUTF(retStr);
  OPENSSL_free(tmpStr);
  return returnJString;
}
extern "C" void Java_java_math_NativeBN_BN_1bin2bn(JNIEnv* env, jclass, jbyteArray arr, int len, jboolean neg, jlong ret) {
  if (!oneValidHandle(env, ret)) return;
  ScopedByteArrayRO bytes(env, arr);
  if (bytes.get() == NULL) {
    return;
  }
  BN_bin2bn(reinterpret_cast<const unsigned char*>(bytes.get()), len, toBigNum(ret));
  if (!throwExceptionIfNecessary(env) && neg) {
    BN_set_negative(toBigNum(ret), true);
  }
}
Example #11
0
/**
 * public static native void modifyBit(int, int, int)
 */
static jboolean NativeBN_modifyBit(JNIEnv* env, jclass cls, BIGNUM* a, int n, int op) {
// LOGD("NativeBN_BN_modifyBit");
    if (!oneValidHandle(env, a)) return FALSE;
    switch (op) {
    case 1: return BN_set_bit(a, n);
    case 0: return BN_clear_bit(a, n);
    case -1:
        if (BN_is_bit_set(a, n)) return BN_clear_bit(a, n);
        else return BN_set_bit(a, n);
    }
    return FALSE;
}
static jboolean NativeBN_BN_bin2bn(JNIEnv* env, jclass, jbyteArray arr, int len, jboolean neg, BIGNUM* ret) {
    if (!oneValidHandle(env, ret)) return JNI_FALSE;
    ScopedByteArrayRO bytes(env, arr);
    if (bytes.get() == NULL) {
        return -1;
    }
    jboolean success = (BN_bin2bn(reinterpret_cast<const unsigned char*>(bytes.get()), len, ret) != NULL);
    if (success && neg) {
        BN_set_negative(ret, 1);
    }
    return success;
}
Example #13
0
/**
 * public static native java.lang.String BN_bn2hex(int)
 */
static jstring NativeBN_BN_bn2hex(JNIEnv* env, jclass cls, BIGNUM* a) {
    if (!oneValidHandle(env, a)) return NULL;
    char* tmpStr;
    char* retStr;
    tmpStr = BN_bn2hex(a);
    if (tmpStr != NULL) {
        retStr = leadingZerosTrimmed(tmpStr);
        jstring returnJString = ((*env)->NewStringUTF(env, (mcSignednessBull)retStr));
        OPENSSL_free(tmpStr);
        return returnJString;
    }
    else return NULL;
}
static jbyteArray NativeBN_BN_bn2bin(JNIEnv* env, jclass, BIGNUM* a) {
    if (!oneValidHandle(env, a)) return NULL;
    jbyteArray result = env->NewByteArray(BN_num_bytes(a));
    if (result == NULL) {
        return NULL;
    }
    ScopedByteArrayRW bytes(env, result);
    if (bytes.get() == NULL) {
        return NULL;
    }
    BN_bn2bin(a, reinterpret_cast<unsigned char*>(bytes.get()));
    return result;
}
static jstring NativeBN_BN_bn2dec(JNIEnv* env, jclass, BIGNUM* a) {
    if (!oneValidHandle(env, a)) return NULL;
    char* tmpStr;
    char* retStr;
    tmpStr = BN_bn2dec(a);
    if (tmpStr != NULL) {
        retStr = leadingZerosTrimmed(tmpStr);
        jstring returnJString = env->NewStringUTF(retStr);
        OPENSSL_free(tmpStr);
        return returnJString;
    }
    else return NULL;
}
extern "C" jbyteArray Java_java_math_NativeBN_BN_1bn2bin(JNIEnv* env, jclass, jlong a0) {
  if (!oneValidHandle(env, a0)) return NULL;
  BIGNUM* a = toBigNum(a0);
  jbyteArray result = env->NewByteArray(BN_num_bytes(a));
  if (result == NULL) {
    return NULL;
  }
  ScopedByteArrayRW bytes(env, result);
  if (bytes.get() == NULL) {
    return NULL;
  }
  BN_bn2bin(a, reinterpret_cast<unsigned char*>(bytes.get()));
  return result;
}
Example #17
0
/**
 * public static native boolean BN_bin2bn(byte[], int, int, int)
 */
static jboolean NativeBN_BN_bin2bn(JNIEnv* env, jclass cls, jbyteArray arr, int len, jboolean neg, BIGNUM* ret) {
    if (!oneValidHandle(env, ret)) return FALSE;
    jboolean success;
    unsigned char * tmpBytes;
    tmpBytes = (unsigned char *)((*env)->GetPrimitiveArrayCritical(env, arr, 0));
    if (tmpBytes != NULL) {
        success = (BN_bin2bn(tmpBytes, len, ret) != NULL);
        if (neg) {
            BN_set_negative(ret, 1);
        }
        (*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?
}
Example #18
0
/**
 * public static native long longInt(int)
 */
static long long NativeBN_longInt(JNIEnv* env, jclass cls, BIGNUM* a) {
    if (!oneValidHandle(env, a)) return -1;
    bn_check_top(a);
    int intLen = a->top;
    BN_ULONG* d = a->d;
    switch (intLen) {
    case 0:
        return 0;
    case 1:
        if (!a->neg) return d[0] & 0X00000000FFFFFFFFLL;
        else return -(d[0] & 0X00000000FFFFFFFFLL);
    default:
        if (!a->neg) return ((long long)d[1] << 32) | (d[0] & 0XFFFFFFFFLL);
        else return -(((long long)d[1] << 32) | (d[0] & 0XFFFFFFFFLL));
    }
}
Example #19
0
/**
 * public static native byte[] BN_bn2bin(int, byte[])
 */
static jbyteArray NativeBN_BN_bn2bin(JNIEnv* env, jclass cls, BIGNUM* a, jbyteArray to) {
    if (!oneValidHandle(env, a)) return NULL;
    jbyteArray returnJBytes = to;
    unsigned char * tmpBytes;
    int len, byteCnt;
    byteCnt = BN_num_bytes(a);
// FIXME: Currently ignoring array passed in to:
    returnJBytes = (*env)->NewByteArray(env, byteCnt);
// FIXME: is it neccessary to check for returnJBytes != NULL?
    tmpBytes = (unsigned char *)((*env)->GetPrimitiveArrayCritical(env, returnJBytes, NULL));
    if (tmpBytes != NULL) {
        len = BN_bn2bin(a, tmpBytes);
        (*env)->ReleasePrimitiveArrayCritical(env, returnJBytes, tmpBytes, 0);
        return returnJBytes;
    }
    else return NULL;
}
Example #20
0
/**
 * public static native int putULongInt(int, long, int)
 */
static jboolean NativeBN_putULongInt(JNIEnv* env, jclass cls, BIGNUM* a, unsigned long long dw, jboolean neg) {
    if (!oneValidHandle(env, a)) return FALSE;
    unsigned int hi = dw >> 32; // This shifts without sign extension.
    int lo = (int)dw; // This truncates implicitely.

    // cf. litEndInts2bn:
    bn_check_top(a);
        if (bn_wexpand(a, 2) != NULL) {
            a->d[0] = lo;
            a->d[1] = hi;
            a->top = 2;
            a->neg = neg;
            bn_correct_top(a);
            return TRUE;
        }
        else return FALSE;
}
extern "C" void Java_java_math_NativeBN_putULongInt(JNIEnv* env, jclass, jlong a0, unsigned long long dw, jboolean neg) {
    if (!oneValidHandle(env, a0)) return;
    unsigned int hi = dw >> 32; // This shifts without sign extension.
    int lo = (int)dw; // This truncates implicitly.

    // cf. litEndInts2bn:
    BIGNUM* a = toBigNum(a0);
    bn_check_top(a);
    if (bn_wexpand(a, 2) != NULL) {
      a->d[0] = lo;
      a->d[1] = hi;
      a->top = 2;
      a->neg = neg;
      bn_correct_top(a);
    } else {
      throwExceptionIfNecessary(env);
    }
}
Example #22
0
/**
 * public static native int bitLength(int)
 */
static int NativeBN_bitLength(JNIEnv* env, jclass cls, BIGNUM* a) {
// We rely on: (BN_BITS2 == 32), i.e. BN_ULONG is unsigned int and has 4 bytes:
//
    if (!oneValidHandle(env, a)) return FALSE;
    bn_check_top(a);
    int intLen = a->top;
    if (intLen == 0) return 0;
    BN_ULONG* d = a->d;
    int i = intLen - 1;
    BN_ULONG msd = d[i]; // most significant digit
        if (a->neg) {
            // Handle negative values correctly:
            // i.e. decrement the msd if all other digits are 0:
            // while ((i > 0) && (d[i] != 0)) { i--; }
            do { i--; } while (!((i < 0) || (d[i] != 0)));
            if (i < 0) msd--; // Only if all lower significant digits are 0 we decrement the most significant one.
        }
        return (intLen - 1) * 32 + BN_num_bits_word(msd);
}
static void NativeBN_putULongInt(JNIEnv* env, jclass, jlong a0, jlong java_dw, jboolean neg) {
    if (!oneValidHandle(env, a0)) return;

    uint64_t dw = java_dw;

    // cf. litEndInts2bn:
    BIGNUM* a = toBigNum(a0);
    bn_check_top(a);
    if (bn_wexpand(a, 8/BN_BYTES) != NULL) {
#ifdef __LP64__
      a->d[0] = dw;
#else
      unsigned int hi = dw >> 32; // This shifts without sign extension.
      int lo = (int)dw; // This truncates implicitly.
      a->d[0] = lo;
      a->d[1] = hi;
#endif
      a->top = 8 / BN_BYTES;
      a->neg = neg;
      bn_correct_top(a);
    } else {
Example #24
0
/**
 * public static native int[] bn2litEndInts(int, int[])
 * cf. litEndInts2bn
 */
static jintArray NativeBN_bn2litEndInts(JNIEnv* env, jclass cls, BIGNUM* a, jintArray to) {
    if (!oneValidHandle(env, a)) return NULL;
    jintArray returnJInts = to;
    bn_check_top(a);
    int len = a->top;
    if (len > 0) {
// FIXME: Currently ignoring array passed in to:
        returnJInts = (*env)->NewIntArray(env, len);
// FIXME: is it neccessary to check for returnJBytes != NULL?
        BN_ULONG* tmpInts = (BN_ULONG*)((*env)->GetPrimitiveArrayCritical(env, returnJInts, NULL));
        if (tmpInts != NULL) {
            int i = len; do { i--; tmpInts[i] = a->d[i]; } while (i > 0);
            (*env)->ReleasePrimitiveArrayCritical(env, returnJInts, tmpInts, 0);
            return returnJInts;
        }
        else return NULL;
    }
    else { // value = 0
        return NULL; // Client should not call when sign = 0!
    }
}
static jintArray NativeBN_bn2litEndInts(JNIEnv* env, jclass, BIGNUM* a) {
    if (!oneValidHandle(env, a)) return NULL;
    bn_check_top(a);
    int len = a->top;
    if (len == 0) {
        return NULL;
    }
    jintArray result = env->NewIntArray(len);
    if (result == NULL) {
        return NULL;
    }
    ScopedIntArrayRW ints(env, result);
    if (ints.get() == NULL) {
        return NULL;
    }
    BN_ULONG* ulongs = reinterpret_cast<BN_ULONG*>(ints.get());
    if (ulongs == NULL) {
        return NULL;
    }
    int i = len; do { i--; ulongs[i] = a->d[i]; } while (i > 0);
    return result;
}
extern "C" long long Java_java_math_NativeBN_longInt(JNIEnv* env, jclass, jlong a0) {
  if (!oneValidHandle(env, a0)) return -1;
  BIGNUM* a = toBigNum(a0);
  bn_check_top(a);
  int intLen = a->top;
  BN_ULONG* d = a->d;
  switch (intLen) {
    case 0:
      return 0;
    case 1:
      if (!a->neg) {
        return d[0] & 0X00000000FFFFFFFFLL;
      } else {
        return -(d[0] & 0X00000000FFFFFFFFLL);
      }
    default:
      if (!a->neg) {
        return ((long long)d[1] << 32) | (d[0] & 0XFFFFFFFFLL);
      } else {
        return -(((long long)d[1] << 32) | (d[0] & 0XFFFFFFFFLL));
      }
  }
}
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);
}
static void NativeBN_BN_free(JNIEnv* env, jclass, jlong a) {
  if (!oneValidHandle(env, a)) return;
  BN_free(toBigNum(a));
}
static int twoValidHandles(JNIEnv* env, jlong a, jlong b) {
  if (!oneValidHandle(env, a)) return JNI_FALSE;
  return isValidHandle(env, b, "Mandatory handle (second) passed as null");
}