1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * you may not use this file except in compliance with the License. 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * You may obtain a copy of the License at 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 17abf945fb9ce99d8c2769ac5b2691b2732fa59887Elliott Hughes#define LOG_TAG "NativeBN" 18abf945fb9ce99d8c2769ac5b2691b2732fa59887Elliott Hughes 1999c59bfa432e36933a7a5033fba8b89209f737bcElliott Hughes#include "JNIHelp.h" 20e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes#include "JniConstants.h" 2166e740b765384686ce87003608412e940ab5d489Elliott Hughes#include "JniException.h" 2299c59bfa432e36933a7a5033fba8b89209f737bcElliott Hughes#include "ScopedPrimitiveArray.h" 2305960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes#include "ScopedUtfChars.h" 2499c59bfa432e36933a7a5033fba8b89209f737bcElliott Hughes#include "jni.h" 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include <openssl/bn.h> 2699c59bfa432e36933a7a5033fba8b89209f737bcElliott Hughes#include <openssl/crypto.h> 2799c59bfa432e36933a7a5033fba8b89209f737bcElliott Hughes#include <openssl/err.h> 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include <stdio.h> 29b3aacde3d8af759ee4a7b395c636ea360547d92dIan Rogers#include <memory> 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 318383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley#if defined(OPENSSL_IS_BORINGSSL) 328383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley/* BoringSSL no longer exports |bn_check_top|. */ 338383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langleystatic void bn_check_top(const BIGNUM* bn) { 348383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley /* This asserts that |bn->top| (which contains the number of elements of 358383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley * |bn->d| that are valid) is minimal. In other words, that there aren't 368383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley * superfluous zeros. */ 378383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley if (bn != NULL && bn->top != 0 && bn->d[bn->top-1] == 0) { 388383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley abort(); 398383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley } 408383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley} 418383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley#endif 428383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley 4363710430c17f7c0a1e74b926cd21248fde8e9589Elliott Hughesstruct BN_CTX_Deleter { 4466e740b765384686ce87003608412e940ab5d489Elliott Hughes void operator()(BN_CTX* p) const { 4566e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_CTX_free(p); 4666e740b765384686ce87003608412e940ab5d489Elliott Hughes } 4763710430c17f7c0a1e74b926cd21248fde8e9589Elliott Hughes}; 48b3aacde3d8af759ee4a7b395c636ea360547d92dIan Rogerstypedef std::unique_ptr<BN_CTX, BN_CTX_Deleter> Unique_BN_CTX; 4963710430c17f7c0a1e74b926cd21248fde8e9589Elliott Hughes 50a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic BIGNUM* toBigNum(jlong address) { 51a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return reinterpret_cast<BIGNUM*>(static_cast<uintptr_t>(address)); 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 5466e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic bool throwExceptionIfNecessary(JNIEnv* env) { 5566e740b765384686ce87003608412e940ab5d489Elliott Hughes long error = ERR_get_error(); 5666e740b765384686ce87003608412e940ab5d489Elliott Hughes if (error == 0) { 5766e740b765384686ce87003608412e940ab5d489Elliott Hughes return false; 5866e740b765384686ce87003608412e940ab5d489Elliott Hughes } 5966e740b765384686ce87003608412e940ab5d489Elliott Hughes char message[256]; 6066e740b765384686ce87003608412e940ab5d489Elliott Hughes ERR_error_string_n(error, message, sizeof(message)); 6166e740b765384686ce87003608412e940ab5d489Elliott Hughes int reason = ERR_GET_REASON(error); 6266e740b765384686ce87003608412e940ab5d489Elliott Hughes if (reason == BN_R_DIV_BY_ZERO) { 6366e740b765384686ce87003608412e940ab5d489Elliott Hughes jniThrowException(env, "java/lang/ArithmeticException", "BigInteger division by zero"); 6466e740b765384686ce87003608412e940ab5d489Elliott Hughes } else if (reason == BN_R_NO_INVERSE) { 6566e740b765384686ce87003608412e940ab5d489Elliott Hughes jniThrowException(env, "java/lang/ArithmeticException", "BigInteger not invertible"); 6666e740b765384686ce87003608412e940ab5d489Elliott Hughes } else if (reason == ERR_R_MALLOC_FAILURE) { 6766e740b765384686ce87003608412e940ab5d489Elliott Hughes jniThrowOutOfMemoryError(env, message); 6866e740b765384686ce87003608412e940ab5d489Elliott Hughes } else { 6966e740b765384686ce87003608412e940ab5d489Elliott Hughes jniThrowException(env, "java/lang/ArithmeticException", message); 7066e740b765384686ce87003608412e940ab5d489Elliott Hughes } 7166e740b765384686ce87003608412e940ab5d489Elliott Hughes return true; 7266e740b765384686ce87003608412e940ab5d489Elliott Hughes} 73a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes 74a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic int isValidHandle(JNIEnv* env, jlong handle, const char* message) { 75a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (handle == 0) { 76a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes jniThrowNullPointerException(env, message); 77a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return JNI_FALSE; 78a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 79a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return JNI_TRUE; 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 82a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic int oneValidHandle(JNIEnv* env, jlong a) { 83a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return isValidHandle(env, a, "Mandatory handle (first) passed as null"); 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 86a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic int twoValidHandles(JNIEnv* env, jlong a, jlong b) { 87a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!oneValidHandle(env, a)) return JNI_FALSE; 88a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return isValidHandle(env, b, "Mandatory handle (second) passed as null"); 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 91a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic int threeValidHandles(JNIEnv* env, jlong a, jlong b, jlong c) { 92a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!twoValidHandles(env, a, b)) return JNI_FALSE; 93a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return isValidHandle(env, c, "Mandatory handle (third) passed as null"); 94a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes} 95a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes 96a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic int fourValidHandles(JNIEnv* env, jlong a, jlong b, jlong c, jlong d) { 97a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!threeValidHandles(env, a, b, c)) return JNI_FALSE; 98a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return isValidHandle(env, d, "Mandatory handle (fourth) passed as null"); 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 10166e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic jlong NativeBN_BN_new(JNIEnv* env, jclass) { 10266e740b765384686ce87003608412e940ab5d489Elliott Hughes jlong result = static_cast<jlong>(reinterpret_cast<uintptr_t>(BN_new())); 10366e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 10466e740b765384686ce87003608412e940ab5d489Elliott Hughes return result; 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 10733fc9556dfda6298fcd7c119f68a7375e13cbed9Richard Uhlerstatic jlong NativeBN_getNativeFinalizer(JNIEnv*, jclass) { 10833fc9556dfda6298fcd7c119f68a7375e13cbed9Richard Uhler return static_cast<jlong>(reinterpret_cast<uintptr_t>(&BN_free)); 10933fc9556dfda6298fcd7c119f68a7375e13cbed9Richard Uhler} 11033fc9556dfda6298fcd7c119f68a7375e13cbed9Richard Uhler 111a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic void NativeBN_BN_free(JNIEnv* env, jclass, jlong a) { 112a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!oneValidHandle(env, a)) return; 113a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BN_free(toBigNum(a)); 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 116a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic int NativeBN_BN_cmp(JNIEnv* env, jclass, jlong a, jlong b) { 117a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!twoValidHandles(env, a, b)) return 1; 118a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return BN_cmp(toBigNum(a), toBigNum(b)); 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 12166e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_BN_copy(JNIEnv* env, jclass, jlong to, jlong from) { 12266e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!twoValidHandles(env, to, from)) return; 12366e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_copy(toBigNum(to), toBigNum(from)); 12466e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 127a961d0b42b313aae32f340d9bf7de18e638da2cbColin Crossstatic void NativeBN_putULongInt(JNIEnv* env, jclass, jlong a0, jlong java_dw, jboolean neg) { 1288383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley if (!oneValidHandle(env, a0)) return; 129a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross 1308383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley uint64_t dw = java_dw; 1318383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley BIGNUM* a = toBigNum(a0); 1328383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley int ok; 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1348383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley static_assert(sizeof(dw) == sizeof(BN_ULONG) || 1358383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley sizeof(dw) == 2*sizeof(BN_ULONG), "Unknown BN configuration"); 1368383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley 1378383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley if (sizeof(dw) == sizeof(BN_ULONG)) { 1388383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley ok = BN_set_word(a, dw); 1398383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley } else if (sizeof(dw) == 2 * sizeof(BN_ULONG)) { 1408383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley ok = (bn_wexpand(a, 2) != NULL); 1418383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley if (ok) { 142a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross a->d[0] = dw; 1438383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley a->d[1] = dw >> 32; 1448383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley a->top = 2; 14566e740b765384686ce87003608412e940ab5d489Elliott Hughes bn_correct_top(a); 14666e740b765384686ce87003608412e940ab5d489Elliott Hughes } 1478383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley } 1488383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley 1498383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley BN_set_negative(a, neg); 1508383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley 1518383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley if (!ok) { 1528383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley throwExceptionIfNecessary(env); 1538383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley } 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 156a961d0b42b313aae32f340d9bf7de18e638da2cbColin Crossstatic void NativeBN_putLongInt(JNIEnv* env, jclass cls, jlong a, jlong dw) { 157a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (dw >= 0) { 15866e740b765384686ce87003608412e940ab5d489Elliott Hughes NativeBN_putULongInt(env, cls, a, dw, JNI_FALSE); 159a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } else { 16066e740b765384686ce87003608412e940ab5d489Elliott Hughes NativeBN_putULongInt(env, cls, a, -dw, JNI_TRUE); 161a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 164a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic int NativeBN_BN_dec2bn(JNIEnv* env, jclass, jlong a0, jstring str) { 165a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!oneValidHandle(env, a0)) return -1; 166a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes ScopedUtfChars chars(env, str); 167a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (chars.c_str() == NULL) { 168a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return -1; 169a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 170a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BIGNUM* a = toBigNum(a0); 17166e740b765384686ce87003608412e940ab5d489Elliott Hughes int result = BN_dec2bn(&a, chars.c_str()); 17266e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 17366e740b765384686ce87003608412e940ab5d489Elliott Hughes return result; 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 176a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic int NativeBN_BN_hex2bn(JNIEnv* env, jclass, jlong a0, jstring str) { 177a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!oneValidHandle(env, a0)) return -1; 178a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes ScopedUtfChars chars(env, str); 179a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (chars.c_str() == NULL) { 180a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return -1; 181a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 182a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BIGNUM* a = toBigNum(a0); 18366e740b765384686ce87003608412e940ab5d489Elliott Hughes int result = BN_hex2bn(&a, chars.c_str()); 18466e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 18566e740b765384686ce87003608412e940ab5d489Elliott Hughes return result; 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18866e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_BN_bin2bn(JNIEnv* env, jclass, jbyteArray arr, int len, jboolean neg, jlong ret) { 18966e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!oneValidHandle(env, ret)) return; 190a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes ScopedByteArrayRO bytes(env, arr); 191a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (bytes.get() == NULL) { 19266e740b765384686ce87003608412e940ab5d489Elliott Hughes return; 193a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 19466e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_bin2bn(reinterpret_cast<const unsigned char*>(bytes.get()), len, toBigNum(ret)); 19566e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!throwExceptionIfNecessary(env) && neg) { 19666e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_set_negative(toBigNum(ret), true); 197a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 20199c59bfa432e36933a7a5033fba8b89209f737bcElliott Hughes * Note: 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This procedure directly writes the internal representation of BIGNUMs. 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * We do so as there is no direct interface based on Little Endian Integer Arrays. 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Also note that the same representation is used in the Cordoba Java Implementation of BigIntegers, 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * whereof certain functionality is still being used. 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 20766e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_litEndInts2bn(JNIEnv* env, jclass, jintArray arr, int len, jboolean neg, jlong ret0) { 20866e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!oneValidHandle(env, ret0)) return; 209a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BIGNUM* ret = toBigNum(ret0); 210a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes bn_check_top(ret); 211a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (len > 0) { 212a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes ScopedIntArrayRO scopedArray(env, arr); 213a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (scopedArray.get() == NULL) { 21466e740b765384686ce87003608412e940ab5d489Elliott Hughes return; 215a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 216a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#ifdef __LP64__ 217a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross const int wlen = (len + 1) / 2; 218a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#else 219a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross const int wlen = len; 220a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#endif 221a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross const unsigned int* tmpInts = reinterpret_cast<const unsigned int*>(scopedArray.get()); 222a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross if ((tmpInts != NULL) && (bn_wexpand(ret, wlen) != NULL)) { 223a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#ifdef __LP64__ 224a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross if (len % 2) { 225a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross ret->d[wlen - 1] = tmpInts[--len]; 226a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross } 227a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross if (len > 0) { 228a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross for (int i = len - 2; i >= 0; i -= 2) { 229a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross ret->d[i/2] = ((unsigned long long)tmpInts[i+1] << 32) | tmpInts[i]; 230a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross } 231a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross } 232a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#else 233a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes int i = len; do { i--; ret->d[i] = tmpInts[i]; } while (i > 0); 234a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#endif 2356bc20cd8fc6784a75158d8f1db27802a12b28f94Serguei Katkov ret->top = wlen; 236a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes ret->neg = neg; 237a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes // need to call this due to clear byte at top if avoiding 238a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes // having the top bit set (-ve number) 239a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes // Basically get rid of top zero ints: 240a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes bn_correct_top(ret); 241a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } else { 24266e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 24399c59bfa432e36933a7a5033fba8b89209f737bcElliott Hughes } 244a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } else { // (len = 0) means value = 0 and sign will be 0, too. 245a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes ret->top = 0; 246a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 250a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#ifdef __LP64__ 251a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#define BYTES2ULONG(bytes, k) \ 252a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross ((bytes[k + 7] & 0xffULL) | (bytes[k + 6] & 0xffULL) << 8 | (bytes[k + 5] & 0xffULL) << 16 | (bytes[k + 4] & 0xffULL) << 24 | \ 253a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross (bytes[k + 3] & 0xffULL) << 32 | (bytes[k + 2] & 0xffULL) << 40 | (bytes[k + 1] & 0xffULL) << 48 | (bytes[k + 0] & 0xffULL) << 56) 254a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#else 255a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#define BYTES2ULONG(bytes, k) \ 256a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes ((bytes[k + 3] & 0xff) | (bytes[k + 2] & 0xff) << 8 | (bytes[k + 1] & 0xff) << 16 | (bytes[k + 0] & 0xff) << 24) 257a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#endif 25866e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void negBigEndianBytes2bn(JNIEnv*, jclass, const unsigned char* bytes, int bytesLen, jlong ret0) { 259a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BIGNUM* ret = toBigNum(ret0); 260a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes 261a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes bn_check_top(ret); 262a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes // FIXME: assert bytesLen > 0 2638383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley int wLen = (bytesLen + sizeof(BN_ULONG) - 1) / sizeof(BN_ULONG); 264a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes int firstNonzeroDigit = -2; 265a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross if (bn_wexpand(ret, wLen) != NULL) { 266a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BN_ULONG* d = ret->d; 267a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BN_ULONG di; 268a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross ret->top = wLen; 2698383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley int highBytes = bytesLen % sizeof(BN_ULONG); 270a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes int k = bytesLen; 271a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes // Put bytes to the int array starting from the end of the byte array 272a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes int i = 0; 273a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes while (k > highBytes) { 2748383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley k -= sizeof(BN_ULONG); 275a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross di = BYTES2ULONG(bytes, k); 276a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (di != 0) { 277a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes d[i] = -di; 278a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes firstNonzeroDigit = i; 279a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes i++; 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (k > highBytes) { 2818383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley k -= sizeof(BN_ULONG); 282a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross d[i] = ~BYTES2ULONG(bytes, k); 283a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes i++; 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 285a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes break; 286a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } else { 287a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes d[i] = 0; 288a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes i++; 289a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 291a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (highBytes != 0) { 292a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes di = -1; 293a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes // Put the first bytes in the highest element of the int array 294a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (firstNonzeroDigit != -2) { 295a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes for (k = 0; k < highBytes; k++) { 296a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes di = (di << 8) | (bytes[k] & 0xFF); 297a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 298a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes d[i] = ~di; 299a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } else { 300a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes for (k = 0; k < highBytes; k++) { 301a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes di = (di << 8) | (bytes[k] & 0xFF); 302a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 303a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes d[i] = -di; 304a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3061d6c936ab01da702aab6c7e578e2c74cdc90b8a4Kenny Root // The top may have superfluous zeros, so fix it. 3071d6c936ab01da702aab6c7e578e2c74cdc90b8a4Kenny Root bn_correct_top(ret); 308a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 309a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes} 310a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes 31166e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_twosComp2bn(JNIEnv* env, jclass cls, jbyteArray arr, int bytesLen, jlong ret0) { 31266e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!oneValidHandle(env, ret0)) return; 313a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BIGNUM* ret = toBigNum(ret0); 314a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes 315a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes ScopedByteArrayRO bytes(env, arr); 316a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (bytes.get() == NULL) { 31766e740b765384686ce87003608412e940ab5d489Elliott Hughes return; 318a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 319a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes const unsigned char* s = reinterpret_cast<const unsigned char*>(bytes.get()); 320a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if ((bytes[0] & 0X80) == 0) { // Positive value! 321a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes // 322a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes // We can use the existing BN implementation for unsigned big endian bytes: 323a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes // 32466e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_bin2bn(s, bytesLen, ret); 32566e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_set_negative(ret, false); 326a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } else { // Negative value! 327a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes // 328a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes // We need to apply two's complement: 329a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes // 33066e740b765384686ce87003608412e940ab5d489Elliott Hughes negBigEndianBytes2bn(env, cls, s, bytesLen, ret0); 33166e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_set_negative(ret, true); 332a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 33366e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 334a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes} 335a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes 336a961d0b42b313aae32f340d9bf7de18e638da2cbColin Crossstatic jlong NativeBN_longInt(JNIEnv* env, jclass, jlong a0) { 337a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!oneValidHandle(env, a0)) return -1; 338a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross 339a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BIGNUM* a = toBigNum(a0); 340a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes bn_check_top(a); 341a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross int wLen = a->top; 342a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross if (wLen == 0) { 343a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross return 0; 344a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross } 345a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross 346a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#ifdef __LP64__ 347a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross jlong result = a->d[0]; 348a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#else 349a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross jlong result = static_cast<jlong>(a->d[0]) & 0xffffffff; 350a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross if (wLen > 1) { 351a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross result |= static_cast<jlong>(a->d[1]) << 32; 352a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 353a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#endif 354a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross return a->neg ? -result : result; 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectstatic char* leadingZerosTrimmed(char* s) { 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char* p = s; 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (*p == '-') { 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project p++; 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while ((*p == '0') && (*(p + 1) != 0)) { p++; } 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project p--; 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *p = '-'; 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while ((*p == '0') && (*(p + 1) != 0)) { p++; } 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return p; 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 370a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic jstring NativeBN_BN_bn2dec(JNIEnv* env, jclass, jlong a) { 371a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!oneValidHandle(env, a)) return NULL; 372a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes char* tmpStr = BN_bn2dec(toBigNum(a)); 373a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (tmpStr == NULL) { 374a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return NULL; 375a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 376a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes char* retStr = leadingZerosTrimmed(tmpStr); 377a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes jstring returnJString = env->NewStringUTF(retStr); 378a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes OPENSSL_free(tmpStr); 379a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return returnJString; 380a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes} 381a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes 382a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic jstring NativeBN_BN_bn2hex(JNIEnv* env, jclass, jlong a) { 383a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!oneValidHandle(env, a)) return NULL; 384a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes char* tmpStr = BN_bn2hex(toBigNum(a)); 385a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (tmpStr == NULL) { 386a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return NULL; 387a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 388a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes char* retStr = leadingZerosTrimmed(tmpStr); 389a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes jstring returnJString = env->NewStringUTF(retStr); 390a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes OPENSSL_free(tmpStr); 391a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return returnJString; 392a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes} 393a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes 394a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic jbyteArray NativeBN_BN_bn2bin(JNIEnv* env, jclass, jlong a0) { 395a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!oneValidHandle(env, a0)) return NULL; 396a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BIGNUM* a = toBigNum(a0); 397a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes jbyteArray result = env->NewByteArray(BN_num_bytes(a)); 398a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (result == NULL) { 399a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return NULL; 400a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 401a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes ScopedByteArrayRW bytes(env, result); 402a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (bytes.get() == NULL) { 403a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return NULL; 404a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 405a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BN_bn2bin(a, reinterpret_cast<unsigned char*>(bytes.get())); 406a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return result; 407a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes} 408a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes 409a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic jintArray NativeBN_bn2litEndInts(JNIEnv* env, jclass, jlong a0) { 410a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!oneValidHandle(env, a0)) return NULL; 411a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BIGNUM* a = toBigNum(a0); 412a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes bn_check_top(a); 413a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross int wLen = a->top; 414a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross if (wLen == 0) { 415a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return NULL; 416a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 4178383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley jintArray result = env->NewIntArray(wLen * sizeof(BN_ULONG)/sizeof(unsigned int)); 418a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (result == NULL) { 419a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return NULL; 420a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 421a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes ScopedIntArrayRW ints(env, result); 422a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (ints.get() == NULL) { 423a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return NULL; 424a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 425a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross unsigned int* uints = reinterpret_cast<unsigned int*>(ints.get()); 426a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross if (uints == NULL) { 427a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return NULL; 428a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 429a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#ifdef __LP64__ 430a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross int i = wLen; do { i--; uints[i*2+1] = a->d[i] >> 32; uints[i*2] = a->d[i]; } while (i > 0); 431a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#else 432a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross int i = wLen; do { i--; uints[i] = a->d[i]; } while (i > 0); 433a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross#endif 434a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return result; 435a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes} 436a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes 437a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic int NativeBN_sign(JNIEnv* env, jclass, jlong a) { 438a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!oneValidHandle(env, a)) return -2; 439a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (BN_is_zero(toBigNum(a))) { 440a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return 0; 441a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } else if (BN_is_negative(toBigNum(a))) { 442a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return -1; 443a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 444a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return 1; 445a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes} 446a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes 447a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic void NativeBN_BN_set_negative(JNIEnv* env, jclass, jlong b, int n) { 448a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!oneValidHandle(env, b)) return; 449a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BN_set_negative(toBigNum(b), n); 450a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes} 451a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes 452a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic int NativeBN_bitLength(JNIEnv* env, jclass, jlong a0) { 453a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!oneValidHandle(env, a0)) return JNI_FALSE; 454a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BIGNUM* a = toBigNum(a0); 455a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes bn_check_top(a); 456a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross int wLen = a->top; 457a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross if (wLen == 0) return 0; 458a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BN_ULONG* d = a->d; 459a961d0b42b313aae32f340d9bf7de18e638da2cbColin Cross int i = wLen - 1; 460a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes BN_ULONG msd = d[i]; // most significant digit 461a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (a->neg) { 462a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes // Handle negative values correctly: 463a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes // i.e. decrement the msd if all other digits are 0: 464a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes // while ((i > 0) && (d[i] != 0)) { i--; } 465a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes do { i--; } while (!((i < 0) || (d[i] != 0))); 466a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (i < 0) msd--; // Only if all lower significant digits are 0 we decrement the most significant one. 467a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes } 4688383f343119f7a98cbe3b4a5bddc89038ac5c166Adam Langley return (wLen - 1) * sizeof(BN_ULONG) * 8 + BN_num_bits_word(msd); 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 471a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic jboolean NativeBN_BN_is_bit_set(JNIEnv* env, jclass, jlong a, int n) { 472a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!oneValidHandle(env, a)) return JNI_FALSE; 473a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes return BN_is_bit_set(toBigNum(a), n); 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 47666e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_BN_shift(JNIEnv* env, jclass, jlong r, jlong a, int n) { 47766e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!twoValidHandles(env, r, a)) return; 47866e740b765384686ce87003608412e940ab5d489Elliott Hughes if (n >= 0) { 47966e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_lshift(toBigNum(r), toBigNum(a), n); 48066e740b765384686ce87003608412e940ab5d489Elliott Hughes } else { 48166e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_rshift(toBigNum(r), toBigNum(a), -n); 48266e740b765384686ce87003608412e940ab5d489Elliott Hughes } 48366e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 48666e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_BN_add_word(JNIEnv* env, jclass, jlong a, BN_ULONG w) { 48766e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!oneValidHandle(env, a)) return; 48866e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_add_word(toBigNum(a), w); 48966e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 49266e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_BN_mul_word(JNIEnv* env, jclass, jlong a, BN_ULONG w) { 49366e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!oneValidHandle(env, a)) return; 49466e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_mul_word(toBigNum(a), w); 49566e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 498a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughesstatic BN_ULONG NativeBN_BN_mod_word(JNIEnv* env, jclass, jlong a, BN_ULONG w) { 49966e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!oneValidHandle(env, a)) return 0; 50066e740b765384686ce87003608412e940ab5d489Elliott Hughes int result = BN_mod_word(toBigNum(a), w); 50166e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 50266e740b765384686ce87003608412e940ab5d489Elliott Hughes return result; 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 50566e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_BN_add(JNIEnv* env, jclass, jlong r, jlong a, jlong b) { 50666e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!threeValidHandles(env, r, a, b)) return; 50766e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_add(toBigNum(r), toBigNum(a), toBigNum(b)); 50866e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 51166e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_BN_sub(JNIEnv* env, jclass, jlong r, jlong a, jlong b) { 51266e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!threeValidHandles(env, r, a, b)) return; 51366e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_sub(toBigNum(r), toBigNum(a), toBigNum(b)); 51466e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 51766e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_BN_gcd(JNIEnv* env, jclass, jlong r, jlong a, jlong b) { 51866e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!threeValidHandles(env, r, a, b)) return; 519a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes Unique_BN_CTX ctx(BN_CTX_new()); 52066e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_gcd(toBigNum(r), toBigNum(a), toBigNum(b), ctx.get()); 52166e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 52466e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_BN_mul(JNIEnv* env, jclass, jlong r, jlong a, jlong b) { 52566e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!threeValidHandles(env, r, a, b)) return; 526a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes Unique_BN_CTX ctx(BN_CTX_new()); 52766e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_mul(toBigNum(r), toBigNum(a), toBigNum(b), ctx.get()); 52866e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 53166e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_BN_exp(JNIEnv* env, jclass, jlong r, jlong a, jlong p) { 53266e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!threeValidHandles(env, r, a, p)) return; 533a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes Unique_BN_CTX ctx(BN_CTX_new()); 53466e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_exp(toBigNum(r), toBigNum(a), toBigNum(p), ctx.get()); 53566e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 53866e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_BN_div(JNIEnv* env, jclass, jlong dv, jlong rem, jlong m, jlong d) { 53966e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!fourValidHandles(env, (rem ? rem : dv), (dv ? dv : rem), m, d)) return; 540a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes Unique_BN_CTX ctx(BN_CTX_new()); 54166e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_div(toBigNum(dv), toBigNum(rem), toBigNum(m), toBigNum(d), ctx.get()); 54266e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 54566e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_BN_nnmod(JNIEnv* env, jclass, jlong r, jlong a, jlong m) { 54666e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!threeValidHandles(env, r, a, m)) return; 547a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes Unique_BN_CTX ctx(BN_CTX_new()); 54866e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_nnmod(toBigNum(r), toBigNum(a), toBigNum(m), ctx.get()); 54966e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 55266e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_BN_mod_exp(JNIEnv* env, jclass, jlong r, jlong a, jlong p, jlong m) { 55366e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!fourValidHandles(env, r, a, p, m)) return; 554a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes Unique_BN_CTX ctx(BN_CTX_new()); 55566e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_mod_exp(toBigNum(r), toBigNum(a), toBigNum(p), toBigNum(m), ctx.get()); 55666e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 55966e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_BN_mod_inverse(JNIEnv* env, jclass, jlong ret, jlong a, jlong n) { 56066e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!threeValidHandles(env, ret, a, n)) return; 561a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes Unique_BN_CTX ctx(BN_CTX_new()); 56266e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_mod_inverse(toBigNum(ret), toBigNum(a), toBigNum(n), ctx.get()); 56366e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 56666e740b765384686ce87003608412e940ab5d489Elliott Hughesstatic void NativeBN_BN_generate_prime_ex(JNIEnv* env, jclass, jlong ret, int bits, 56766e740b765384686ce87003608412e940ab5d489Elliott Hughes jboolean safe, jlong add, jlong rem, jlong cb) { 56866e740b765384686ce87003608412e940ab5d489Elliott Hughes if (!oneValidHandle(env, ret)) return; 56966e740b765384686ce87003608412e940ab5d489Elliott Hughes BN_generate_prime_ex(toBigNum(ret), bits, safe, toBigNum(add), toBigNum(rem), 57066e740b765384686ce87003608412e940ab5d489Elliott Hughes reinterpret_cast<BN_GENCB*>(cb)); 57166e740b765384686ce87003608412e940ab5d489Elliott Hughes throwExceptionIfNecessary(env); 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 5740a08bbe70ef43ed29cba241e95aa5c338349b021Chris Dearmanstatic jboolean NativeBN_BN_is_prime_ex(JNIEnv* env, jclass, jlong p, int nchecks, jlong cb) { 575a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes if (!oneValidHandle(env, p)) return JNI_FALSE; 576a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes Unique_BN_CTX ctx(BN_CTX_new()); 5770a08bbe70ef43ed29cba241e95aa5c338349b021Chris Dearman return BN_is_prime_ex(toBigNum(p), nchecks, ctx.get(), reinterpret_cast<BN_GENCB*>(cb)); 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 58063710430c17f7c0a1e74b926cd21248fde8e9589Elliott Hughesstatic JNINativeMethod gMethods[] = { 58166e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, BN_add, "(JJJ)V"), 58266e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, BN_add_word, "(JI)V"), 58366e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, BN_bin2bn, "([BIZJ)V"), 584a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, BN_bn2bin, "(J)[B"), 585a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, BN_bn2dec, "(J)Ljava/lang/String;"), 586a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, BN_bn2hex, "(J)Ljava/lang/String;"), 587a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, BN_cmp, "(JJ)I"), 58866e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, BN_copy, "(JJ)V"), 589a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, BN_dec2bn, "(JLjava/lang/String;)I"), 59066e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, BN_div, "(JJJJ)V"), 59166e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, BN_exp, "(JJJ)V"), 592a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, BN_free, "(J)V"), 59366e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, BN_gcd, "(JJJ)V"), 59466e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, BN_generate_prime_ex, "(JIZJJJ)V"), 595a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, BN_hex2bn, "(JLjava/lang/String;)I"), 596a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, BN_is_bit_set, "(JI)Z"), 597a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, BN_is_prime_ex, "(JIJ)Z"), 59866e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, BN_mod_exp, "(JJJJ)V"), 59966e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, BN_mod_inverse, "(JJJ)V"), 600a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, BN_mod_word, "(JI)I"), 60166e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, BN_mul, "(JJJ)V"), 60266e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, BN_mul_word, "(JI)V"), 603a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, BN_new, "()J"), 60466e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, BN_nnmod, "(JJJ)V"), 605a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, BN_set_negative, "(JI)V"), 60666e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, BN_shift, "(JJI)V"), 60766e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, BN_sub, "(JJJ)V"), 608a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, bitLength, "(J)I"), 609a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, bn2litEndInts, "(J)[I"), 61033fc9556dfda6298fcd7c119f68a7375e13cbed9Richard Uhler NATIVE_METHOD(NativeBN, getNativeFinalizer, "()J"), 61166e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, litEndInts2bn, "([IIZJ)V"), 612a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, longInt, "(J)J"), 61366e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, putLongInt, "(JJ)V"), 61466e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, putULongInt, "(JJZ)V"), 615a125dded8ab0490d05e2fa9ec2e821ef1ae6facdElliott Hughes NATIVE_METHOD(NativeBN, sign, "(J)I"), 61666e740b765384686ce87003608412e940ab5d489Elliott Hughes NATIVE_METHOD(NativeBN, twosComp2bn, "([BIJ)V"), 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}; 6187cd6760f7045d771faae8080a8c6150bf678f679Elliott Hughesvoid register_java_math_NativeBN(JNIEnv* env) { 6197cd6760f7045d771faae8080a8c6150bf678f679Elliott Hughes jniRegisterNativeMethods(env, "java/math/NativeBN", gMethods, NELEM(gMethods)); 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 621