Add BN_set_u64.

Android currently implements this manually (see NativeBN_putULongInt) by
reaching into BIGNUM's internals. BN_ULONG is a somewhat unfortunate API
anyway as the size is platform-dependent, so add a platform-independent
way to do this.

The other things Android needs are going to need more work, but this
one's easy.

BUG=97

Change-Id: I4af4dc29f9845bdce0f0663c379b4b5d3e1dc46e
Reviewed-on: https://boringssl-review.googlesource.com/11088
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
David Benjamin 2016-08-23 20:53:12 -07:00 committed by CQ bot account: commit-bot@chromium.org
parent c446ce5294
commit 40a63113e4
3 changed files with 55 additions and 1 deletions

View File

@ -266,6 +266,28 @@ int BN_set_word(BIGNUM *bn, BN_ULONG value) {
return 1;
}
int BN_set_u64(BIGNUM *bn, uint64_t value) {
#if BN_BITS2 == 64
return BN_set_word(bn, value);
#elif BN_BITS2 == 32
if (value <= BN_MASK2) {
return BN_set_word(bn, (BN_ULONG)value);
}
if (bn_wexpand(bn, 2) == NULL) {
return 0;
}
bn->neg = 0;
bn->d[0] = (BN_ULONG)value;
bn->d[1] = (BN_ULONG)(value >> 32);
bn->top = 2;
return 1;
#else
#error "BN_BITS2 must be 32 or 64."
#endif
}
int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num) {
if (bn_wexpand(bn, num) == NULL) {
return 0;

View File

@ -1437,6 +1437,33 @@ static bool TestBN2Dec() {
return true;
}
static bool TestBNSetU64() {
static const struct {
const char *hex;
uint64_t value;
} kU64Tests[] = {
{"0", UINT64_C(0x0)},
{"1", UINT64_C(0x1)},
{"ffffffff", UINT64_C(0xffffffff)},
{"100000000", UINT64_C(0x100000000)},
{"ffffffffffffffff", UINT64_C(0xffffffffffffffff)},
};
for (const auto& test : kU64Tests) {
bssl::UniquePtr<BIGNUM> bn(BN_new()), expected;
if (!bn ||
!BN_set_u64(bn.get(), test.value) ||
!HexToBIGNUM(&expected, test.hex) ||
BN_cmp(bn.get(), expected.get()) != 0) {
fprintf(stderr, "BN_set_u64 test failed for 0x%s.\n", test.hex);
ERR_print_errors_fp(stderr);
return false;
}
}
return true;
}
int main(int argc, char *argv[]) {
CRYPTO_library_init();
@ -1462,7 +1489,8 @@ int main(int argc, char *argv[]) {
!TestExpModZero() ||
!TestSmallPrime(ctx.get()) ||
!TestCmpWord() ||
!TestBN2Dec()) {
!TestBN2Dec() ||
!TestBNSetU64()) {
return 1;
}

View File

@ -221,6 +221,10 @@ OPENSSL_EXPORT int BN_one(BIGNUM *bn);
* allocation failure. */
OPENSSL_EXPORT int BN_set_word(BIGNUM *bn, BN_ULONG value);
/* BN_set_u64 sets |bn| to |value|. It returns one on success or zero on
* allocation failure. */
OPENSSL_EXPORT int BN_set_u64(BIGNUM *bn, uint64_t value);
/* BN_set_negative sets the sign of |bn|. */
OPENSSL_EXPORT void BN_set_negative(BIGNUM *bn, int sign);