Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimizated calculation of shared power of 2 in bn_gcd #24332

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 22 additions & 11 deletions crypto/bn/bn_gcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "internal/cryptlib.h"
#include "bn_local.h"
#include "internal/constant_time.h"

/*
* bn_mod_inverse_no_branch is a special version of BN_mod_inverse. It does
Expand Down Expand Up @@ -580,8 +581,8 @@ int BN_are_coprime(BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
{
BIGNUM *g, *temp = NULL;
BN_ULONG mask = 0;
int i, j, top, rlen, glen, m, bit = 1, delta = 1, cond = 0, shifts = 0, ret = 0;
BN_ULONG pow2_numbits, pow2_numbits_temp, pow2_condition_mask;
int i, j, top, rlen, glen, m, delta = 1, cond = 0, pow2_shifts, ret = 0, pow2_flag;
landgrafhomyak marked this conversation as resolved.
Show resolved Hide resolved

/* Note 2: zero input corner cases are not constant-time since they are
* handled immediately. An attacker can run an attack under this
Expand Down Expand Up @@ -611,18 +612,28 @@ int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
goto err;

/* find shared powers of two, i.e. "shifts" >= 1 */
pow2_flag = 1;
pow2_shifts = 0;
pow2_numbits = 0;
for (i = 0; i < r->dmax && i < g->dmax; i++) {
mask = ~(r->d[i] | g->d[i]);
for (j = 0; j < BN_BITS2; j++) {
bit &= mask;
shifts += bit;
mask >>= 1;
}
pow2_numbits_temp = r->d[i] | g->d[i];
pow2_condition_mask = ~(constant_time_is_zero_bn(pow2_flag)) & ~(constant_time_is_zero_bn(pow2_numbits_temp));
pow2_flag &= ~pow2_condition_mask;
bernd-edlinger marked this conversation as resolved.
Show resolved Hide resolved
pow2_shifts += 1 & pow2_flag;
landgrafhomyak marked this conversation as resolved.
Show resolved Hide resolved
pow2_numbits = constant_time_select_bn(pow2_condition_mask, pow2_numbits_temp, pow2_numbits);
}
pow2_numbits = ~pow2_numbits;
pow2_shifts *= BN_BITS2;
pow2_flag = 1;
for (j = 0; j < BN_BITS2; j++) {
pow2_flag &= pow2_numbits;
landgrafhomyak marked this conversation as resolved.
Show resolved Hide resolved
pow2_shifts += pow2_flag;
pow2_numbits >>= 1;
}

/* subtract shared powers of two; shifts >= 1 */
if (!BN_rshift(r, r, shifts)
|| !BN_rshift(g, g, shifts))
if (!BN_rshift(r, r, pow2_shifts)
|| !BN_rshift(g, g, pow2_shifts))
goto err;

/* expand to biggest nword, with room for a possible extra word */
Expand Down Expand Up @@ -665,7 +676,7 @@ int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
/* remove possible negative sign */
r->neg = 0;
/* add powers of 2 removed, then correct the artificial shift */
if (!BN_lshift(r, r, shifts)
if (!BN_lshift(r, r, pow2_shifts)
|| !BN_rshift1(r, r))
goto err;

Expand Down
18 changes: 18 additions & 0 deletions include/internal/constant_time.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,17 @@ static ossl_inline uint64_t constant_time_lt_64(uint64_t a, uint64_t b)
}

#ifdef BN_ULONG
static ossl_inline BN_ULONG value_barrier_bn(BN_ULONG a)
{
#if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
BN_ULONG r;
__asm__("" : "=r"(r) : "0"(a));
#else
volatile BN_ULONG r = a;
#endif
return r;
}

static ossl_inline BN_ULONG constant_time_msb_bn(BN_ULONG a)
{
return 0 - (a >> (sizeof(a) * 8 - 1));
Expand All @@ -161,6 +172,13 @@ static ossl_inline BN_ULONG constant_time_eq_bn(BN_ULONG a,
{
return constant_time_is_zero_bn(a ^ b);
}

static ossl_inline BN_ULONG constant_time_select_bn(BN_ULONG mask,
BN_ULONG a,
BN_ULONG b)
{
return (value_barrier_bn(mask) & a) | (value_barrier_bn(~mask) & b);
}
#endif

static ossl_inline unsigned int constant_time_ge(unsigned int a,
Expand Down
151 changes: 151 additions & 0 deletions test/recipes/10-test_bn_data/bngcd.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17177,3 +17177,154 @@ GCD = 40000000000000000000000000000000000000000000000000000000000000000000000000
A = 58b6214f1521e171d06d7e3c30d35f05bab6a3b2eab879284e28e7a4d847a1cbaa9f9ed1eec0a6e71ceabfccad751936c9050ab89be2952d73196c4ae6df4b876ee2534267fb17514b5494cad0c66a9d44f5568107be450663d46b1f5bf39bfde15a781f98e861c0bad9eb1e3e5fd718e35b1c04a7b5501bec2145d9e0175230cd6ac68d112b591a9b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
B = 20d05fc0686051297fef03b2e53ef9eec2d2a0cd3aa4de878311aaa7f544ad19c04fd2b79800bbcb742732aa39a16a59695a0464a4faac7e6ce87018408e89ae96266058b0448722c5b04d8c30e1d619a2c644528afd132a6975cc1023dd2cafae93bf2d6ed9508a8832ed41934cbb11c3bcb51db4de08e934edc941d369dac0aa54ddc2eefa3e1d65000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
GCD = 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000


# tests for shared pow of 2 calculation

A = a599ed2713b687266bbb7387c7138d9f000000000000000000000000000077b22d12a1550a66a27ea8047e1c1314
B = a7d3501b485990e3e5284f5fda5ceda300000000000000000000000000008603e0ae1b5287a0b74c67ecb3357bbf
GCD = 1

A = 516afa2dabf3e076df5a97c14cd1048a0000000000000000000000000000ac7a909728bafa5d08248e1bc4ea2478
B = cf500f6be20732d3ebc1bcf5286babf90000000000000000000000000000571228d8b12290ed4121dd34dd036c86
GCD = 1a

A = f1c727cc79d33ffeab24ef7b059beddf00000000000000000000000000000000667bdd6ac05bb2633d4376c7f616071b
B = a53fa1d115d399d7decaa64e52ae7928000000000000000000000000000000007896bc648b7b64e3f21926f0222c9bb6
GCD = 5

A = b21a4002a406fd7f0ab021f537c8d5a20000000000000000000000000000000033c3b8f18952effa89c0557a61236769
B = 832d1ffec50bec1979071687348c0e9e00000000000000000000000000000000907adb518b7e7d895d846f86ddbd2d53
GCD = 1

A = 8263d2d19f6aa93f9c989237e15bb00500000000000000000000000000000000c737cb949066346d77679fc03ab4763a
B = 1e110fe2d29b1d06b68aad6b0431958000000000000000000000000000000000601ba7bd1c6ddb762dd44f1e08e70268
GCD = 2

A = 47ff5bfcbec8dece7781db5ae7745a3900000000000000000000000000000000c61426b070d6399c352eb47d9f407bc0
B = 8e5afc09c691d39cd38e6f6206da20c90000000000000000000000000000000013ba9e00633e65490ac98bdf2e1c028c
GCD = 4

A = ee6fe3fcb8a7b90459bac2716d31744e00000000000000000000000000000000fe69590ad7cf320d7b05d1ec21a17aec
B = b64d178a66233f1559f0f37df3fd40b700000000000000000000000000000000bc882d1d224a37567895b4795cbde675
GCD = 1

A = ff3b8f0f011790d216cac27883b5f3ed00000000000000000000000000000000464d6d60e6a7d9b208e188ea3e881481
B = 3d703d9c75a20e83dd41831fc96ae338000000000000000000000000000000001ef846d7a67252c7d0356dd88af99bda
GCD = 1

A = 9f3061cbd46fe9d950f0aa917fe8016a000000000000000000000000000000007092e39710a0ce2646eea198cbf1ff66
B = 32987d4eb8732c22e397df917d9953bb000000000000000000000000000000001b9cd9e1ea3698ee86a22fc3509e041d
GCD = 1

A = 9b1c01fcb99a7dbfc0bc6c20165e9f0100000000000000000000000000000000cc04125a9957537456281a6a118f27cc
B = bc3f4bf4c8ff8cf402a4da5c2e30e00f000000000000000000000000000000003fcbf7d35c9b8f9c279115eec8f11ac9
GCD = 3

A = 70f06aa9d02479c106bd7be5af59bc98674dedac03348e554d0ca1094e38aacc000000000000000000000000000000002563139f6bcba65a102df9a33ff81837
B = abf0e80d6cf5a3a572516d851c9471ba000000000000000000000000000000008d0e49c532867f23b095aaa6cb7fb8e33148261c738ad807e129b8c63540ddcc
GCD = 1

A = e16b46d2c83a380eb1b0583a017fdb0247c63f23c787e70c35298c451022a70a00000000000000000000000000000000b6f1921fd80f3ec56e13484d733e6820
B = d5e8cb03f28f67edff1368bba27ee64f00000000000000000000000000000000d22e91286568c55f5b083d7f5f8a94f7e42e9cecea53bafc59bf20a0632967ee
GCD = 2

A = 9b0e14bc505d982210119f86375038e3c7a1396f2e7469a80e13f9de86b70cfd000000000000000000000000000000008cbae5a000165d381ef454c8e3a08fb3
B = 886a372f68fdd3d56cb199ec980cc34e0000000000000000000000000000000041a913d07b9795bff0dd80e0228401a04b05f0d19163ec525726ad3465fd719a
GCD = 3

A = 921c699de90190ae9b7877adffa38ef32216c107d4c9f7e13cc1253139983c0b000000000000000000000000000000002312276da564839f958def57df6e6188
B = a9deca82a2b65bfc3f2b204ceae03d8c00000000000000000000000000000000154c009d6f929803af910b14bb3682e98482df68da31f76fe8c450e04e19d747
GCD = 1

A = bbf45d086b95732506609a3a1de14e5b659235166c6670c50cd7d47bbd85c2be000000000000000000000000000000009638621c88ac6fe737101af05511965c
B = 8646f475f45d84c463bae1538ab31e400000000000000000000000000000000018b893b827435b0b4ddf66328853aa4447d7f325dcd9d1701a7bdc62bed44942
GCD = 2

A = 625a6c9f944566942e300c38ae8f6a9b6f7981faa65da5d7d7a34114e07f1f030000000000000000000000000000000090f58d8f90a853db6b5382faa495668b
B = cfdbd7426f57129563b3b629de14c30d000000000000000000000000000000001e30550d8bd5f99ce1f6e0f503f42ea0eee33cc94a33f82ef71a33fb82dfe36e
GCD = 3

A = a3510a39f48ccb5842989e5e6ef7e8aac4e4a1df9adde2f816583ce379d6658c000000000000000000000000000000007bdac360657ed8e3712ee5d8fe142779
B = e376626e1c68d7544e5f906d100c7ea800000000000000000000000000000000afe91481cdd5dc165af0af9eee64b0faadd888835f4ad743288972ad18b620ef
GCD = 1

A = a779a2eb3ae70edff3e542e70a0631b48d03db0f6e87020b52d44b941b7d0885000000000000000000000000000000006ef7755ed2b6e61e3308c26494926f43
B = 41ecf75d424681d1eb5727026450f2c3000000000000000000000000000000003a04d696999d29cb915d80ccad4c2498dae654c8971765c88550df458f97d52f
GCD = 31

A = f132afba9288e09f346b48b2ed3c7dea507a9b0d04834173c371990b53fb6b3a00000000000000000000000000000000f1218a4ded6dd5305734e796a38b98bb
B = 46e488f84f768156db17e3337b1ba73200000000000000000000000000000000b2f7692918becc971c26b78c5562e2526e26cf16e1f93c27bd32b70f1940dc7f
GCD = 1

A = 7f58adeb17bc5e0d17cb95d0e689762c4abdd3145cc51a9df11e5a3df2008d2900000000000000000000000000000000993d76a76e32eacd9bd65fe96bcf6ae9
B = b97340f588d736b20a743c768082f6f100000000000000000000000000000000638d904855ca97ce2205d0a10750dd5ecd7fa873a741e1695c826d8857cd41d1
GCD = 1

A = fe58b009d101061f826df5f61c758d0d2ec97f2ef4f273b0d1d49f068f41cecd00000000000000000000000000000000b3ff6ca10a5943d7f9524664a91b0aa9
B = 5bba4f0175ba308046832e893bdaedf500000000000000000000000000000000c5ced5452d3a33426ef2126770807174e1db5d6002dca8486edbbf32804a34aa
GCD = 5

A = 8d5fe35940c048d82043475a4b1beb70833ca9a25f1a648cbe0ab0bbb5a64d55000000000000000000000000000000008ab382d911038e3935960d03a25f50d8
B = 813e2b4c88c056999c9068f11a21092400000000000000000000000000000000d84e0941f34cc3757be34ad1c08df143f38bee26e934a419ce906429717132a8
GCD = 8

A = 5e9f96db8871d4ee8d2fb8134708bf67a79eef310cc9d7a95b0dbaf99cbcf9df7e3b9563159f21952a11fd9ba483adc300000000000000000000000000000000c15c598c93683ee8df65ae6a88c804f8
B = 41f154265fc06480569adc472b9caaf900000000000000000000000000000000987f22fab89e45edc9a86aa1e3fd5b06887bec647b4652accecc9ee9b7f4c582ae7935dfc313e719ae6f45effab637ab
GCD = 3

A = a893c172b1eabf99e2a0a314e1cce17029ab8a70a9eac4e4bbb395516bc2cf3bd70b317d2639233eadc2dc135f2401c1000000000000000000000000000000008588edbebd10f95b71ea959e23bc8eaf
B = fd8c545781c244e2ebab0b7338cfeb0b0000000000000000000000000000000012e9c8b846b68b4724c4c88281c5532276fd550e93f5efce3471c6f912aea9e87f9d349347c1d44c301d77158ff9ba03
GCD = 1

A = 43b42a6ce2c89a98cb0946e2e4a0d927143b743d5cbe531f5b87964ef781e6d77a4beae116ff11db9d02304214312c2700000000000000000000000000000000f103e7668b2c97cc84407d383fc6449d
B = a224aef269134ce2d6428262fb8f5884000000000000000000000000000000005851cbdf9e61a9865fb7b2a0fa6179d6c98918f7043544a6ebfecadc79acbb65b9a8c345372ec5b71417e0d5358aab48
GCD = 1

A = fbec20bb3a2a5eefdd9d2345f1f8c72649967986fa8873ad007e1f01618b4047968400bbf0a2f57d556b6d49898e365d0000000000000000000000000000000015570b6e85b7bf5c9fe2bdebd0776440
B = 52bd3a3c4126be2ccaeb6cea501be44d00000000000000000000000000000000c447b8e8da3364b12fe33180d3576df8e0a9611cae259ba1af5b9b8f09db1baccef4e6b841448735a25f7a6ff6180d3c
GCD = 4

A = d6a75feed0233f66484124781ce3e799b6122ef88fef6e791a7300fa21908ad2ab773bb845a0a409f491bf553df9ad560000000000000000000000000000000062d2bc6ab15a99f8944e294e6c34dad8
B = 72906ece088bf07e48b6cfd2a5c599ee00000000000000000000000000000000481bc91d99a172b7e134876b5d2df765c7a56ed005481f859413e92448cc4988c539a18cac6e3d82d846ee931504bcf2
GCD = 2

A = ba1d3f4f0c79bcd68450dbfeb8a0437fa1e10ca7f57fa4d077f354b6ab5b8f6ddc9e3b2217c4b63daeab7be16e2bd23200000000000000000000000000000000c498dce6c703b006be1a160e9b4b0ba9
B = 4d4473550153422281e5d9b3570a5aa10000000000000000000000000000000087f383c1132ba230cda0f7a45ef9741781216a78de7a5779d7704d3e9a79efb13e3b15a69cad9fe68c9183605867403e
GCD = 1

A = 686b5bedf648365aa260fb3735e8a3a63d4eb97d7a095d6c4364595eef0fbc7f81a4d2d5731a4df9d66718ef2dc520a800000000000000000000000000000000f65f1e08376077a18c8172d17b4aec2c
B = cb630b746c4f9d7672ea0a95663ad91a00000000000000000000000000000000e7c440d34ba295a7a17a24d98d569b2a57e1fcf1267b1042f471eb7c797c33f3ecd882dd89e7ac54e360363d6736bc24
GCD = 1c

A = a0b1b319e1841d6a48f75bdc9c26c47c46b408dc86d9e611e27967194e0abdb3baec6cd369924b41e9006a4f8ff1d7eb00000000000000000000000000000000a92d26208ca3d82a462b90b3c6f42725
B = f78162c60cc5f0d1a366d876c44ee30a000000000000000000000000000000002d1b2fc1676cda2bec02f68358a73b40a5ac6b3597e55e7ee7ca3e4778ee3590c36a84ac347922483524575ebce8655f
GCD = 15

A = 3cda15bcaf63424bb09e3387f6b9383875347b1f4dcf8986597a5ddbc89b630f7dc895861cfee2d46dec73a727bebc5200000000000000000000000000000000c8d731e99cc7fe91a109569228c83873
B = e14f25dff7d086b57dcaf3a0cace4a9700000000000000000000000000000000d799c90a2f6b354a6bc022d1223df178ea4b2139a470845588a06b65a3b922e6cebc2aa67ba40c233731dea133e574a2
GCD = 3

A = 9d650c05f9bb5aea0fad6cb29a4195b65f21be3e33f944a79c62edbdd88ddaf44126cabdba0cc664d7bee119450d04d700000000000000000000000000000000c6e6465cca81ab4e08eff021b5500465
B = 73626f946e5b2155ed2571b67aec585f000000000000000000000000000000005c40649c401527dc708a24a0d8115fcd9ad646ed550f73cc6092c07df729e50f833075a236b294a2b208fd9663af5461
GCD = 5

A = 6d88c4cc98dd2b43e6fdb5f7f538383e88525712691cc58fa4628d151010c79b86a233def4ec44e05f6a808f680d2ff20000000000000000000000000000000066991b9d4f8275af5abd7a8154b98217
B = ed7e25fb1918d8f3f01a9074463b9d3300000000000000000000000000000000b5207d51f4390f8e67af515b2c36699f3280e6d61f27ac263c4c0bad8aac00e4ab3c29d5141c7dfb59d56fede9535aea
GCD = 19

A = de647afe24543a31c9eb639ef61a2b808c7a190fbd614dfeb664f64300d656c9b4253070f9cb33f90eaed8b860c031c9000000000000000000000000000000004c671a089eaa353d53cf13895cbdeb93
B = b8b76e7f2e471b82110e707c1cd1d81b000000000000000000000000000000003ae628d9858c3bce2d3ea432b27dddecb54b36946b41fd28322e82b3fc2811cb56fc3e5fafdc68d9d10024e5e15f5acf
GCD = 1

A = 173f3a57393657f5387f8fa34e9823dd1c6e37786f6f62fad48c3edeccff425ce4000c05e8c8780156eb509ce2e7f12900000000000000000000000000000000235de2f2d749456ffe50e84593e8b25e
B = db9b5cbf2a1c04ba7856ef09302d8e5d0000000000000000000000000000000093e0a6f7021eae0cc212d84ab0adb01e1168557462adfe81286fda320fff68599ad449956d9948b064ca2510c945e4c9
GCD = 1

A = afa0643df67646be7f8d69c65ad6e4a168ecf3b5f3a932c62d77426aed526066b4d754c66317b969df72015b372de52a000000000000000000000000000000005a4825219aaa05263849a0cb5244560b
B = 5e32cb16ba43203c3e18c95e6f0494e300000000000000000000000000000000b7ea981d3fbc567c617142c2986800c3bc63ef4d8c6a402532ce87dbcf239ed4cc1bfd0d726603c80ee85e7063c4a2a7
GCD = 1

A = 792a1d3ba80c6134e1b610b82429adab8212084ff66fcceb3c01f735cc6b84f8c123d2e8ae3c9f375040e9dbe0fbd54c00000000000000000000000000000000377a2d6f6385fdf7b2b48d97d639a0a6
B = 18a68ed3ce626204cd6371f981ceb812000000000000000000000000000000007c16a303a092ae791b4989d85caf6027b9627cce8c5b6be6915cbb855435802143c6294c757ec9d15af65c72adeb3fbe
GCD = 2