/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ │vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ │ Copyright 2021 Justine Alexandra Roberts Tunney │ │ │ │ Permission to use, copy, modify, and/or distribute this software for │ │ any purpose with or without fee is hereby granted, provided that the │ │ above copyright notice and this permission notice appear in all copies. │ │ │ │ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ │ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ │ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ │ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ │ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ │ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/bits.h" #include "libc/bits/bswap.h" #include "libc/macros.internal.h" #include "libc/nexgen32e/nexgen32e.h" #include "libc/nexgen32e/x86feature.h" #include "libc/nt/typedef/imagetlscallback.h" #include "libc/rand/rand.h" #include "libc/runtime/gc.internal.h" #include "libc/runtime/runtime.h" #include "libc/testlib/ezbench.h" #include "libc/testlib/hyperion.h" #include "libc/testlib/testlib.h" #include "libc/x/x.h" #include "third_party/mbedtls/aes.h" #include "third_party/mbedtls/base64.h" #include "third_party/mbedtls/bignum.h" #include "third_party/mbedtls/bignum_internal.h" #include "third_party/mbedtls/chacha20.h" #include "third_party/mbedtls/chachapoly.h" #include "third_party/mbedtls/ctr_drbg.h" #include "third_party/mbedtls/des.h" #include "third_party/mbedtls/dhm.h" #include "third_party/mbedtls/ecp.h" #include "third_party/mbedtls/entropy.h" #include "third_party/mbedtls/error.h" #include "third_party/mbedtls/gcm.h" #include "third_party/mbedtls/hmac_drbg.h" #include "third_party/mbedtls/math.h" #include "third_party/mbedtls/md5.h" #include "third_party/mbedtls/memory_buffer_alloc.h" #include "third_party/mbedtls/nist_kw.h" #include "third_party/mbedtls/pkcs5.h" #include "third_party/mbedtls/poly1305.h" #include "third_party/mbedtls/profile.h" #include "third_party/mbedtls/rsa.h" #include "third_party/mbedtls/select.h" #include "third_party/mbedtls/sha1.h" #include "third_party/mbedtls/sha256.h" #include "third_party/mbedtls/sha512.h" #include "third_party/mbedtls/x509.h" #include "third_party/quickjs/libbf.h" uint64_t rng[12]; mbedtls_ecp_group grp; int GetEntropy(void *c, unsigned char *p, size_t n) { rngset(p, n, rand64, -1); return 0; } void SetUp(void) { rngset(rng, sizeof(rng), rand64, -1); } #ifdef MBEDTLS_SELF_TEST TEST(mbedtls, selfTest) { #ifdef MBEDTLS_DES_C EXPECT_EQ(0, mbedtls_des_self_test(0)); #endif #ifdef MBEDTLS_CTR_DRBG_C EXPECT_EQ(0, mbedtls_ctr_drbg_self_test(0)); #endif #ifdef MBEDTLS_HMAC_DRBG_C EXPECT_EQ(0, mbedtls_hmac_drbg_self_test(0)); #endif #ifdef MBEDTLS_ENTROPY_C EXPECT_EQ(0, mbedtls_entropy_self_test(0)); #endif #ifdef MBEDTLS_POLY1305_C EXPECT_EQ(0, mbedtls_poly1305_self_test(0)); #endif #ifdef MBEDTLS_RSA_C EXPECT_EQ(0, mbedtls_rsa_self_test(0)); #endif #ifdef MBEDTLS_BIGNUM_C EXPECT_EQ(0, mbedtls_mpi_self_test(0)); #endif #ifdef MBEDTLS_PKCS5_C EXPECT_EQ(0, mbedtls_pkcs5_self_test(0)); #endif #ifdef MBEDTLS_DHM_C EXPECT_EQ(0, mbedtls_dhm_self_test(0)); #endif #ifdef MBEDTLS_GCM_C EXPECT_EQ(0, mbedtls_gcm_self_test(0)); #endif #ifdef MBEDTLS_X509_USE_C EXPECT_EQ(0, mbedtls_x509_self_test(0)); #endif #ifdef MBEDTLS_CHACHA20_C EXPECT_EQ(0, mbedtls_chacha20_self_test(0)); #endif #ifdef MBEDTLS_CHACHAPOLY_C EXPECT_EQ(0, mbedtls_chachapoly_self_test(0)); #endif #ifdef MBEDTLS_MEMORY_BUFFER_ALLOC_C EXPECT_EQ(0, mbedtls_memory_buffer_alloc_self_test(0)); #endif #ifdef MBEDTLS_AES_C EXPECT_EQ(0, mbedtls_aes_self_test(0)); #endif #ifdef MBEDTLS_BASE64_C EXPECT_EQ(0, mbedtls_base64_self_test(0)); #endif #ifdef MBEDTLS_ECP_C EXPECT_EQ(0, mbedtls_ecp_self_test(0)); #endif #ifdef MBEDTLS_MD5_C EXPECT_EQ(0, mbedtls_md5_self_test(0)); #endif #ifdef MBEDTLS_SHA1_C EXPECT_EQ(0, mbedtls_sha1_self_test(0)); #endif #ifdef MBEDTLS_SHA256_C EXPECT_EQ(0, mbedtls_sha256_self_test(0)); #endif #ifdef MBEDTLS_SHA512_C EXPECT_EQ(0, mbedtls_sha512_self_test(0)); #endif #ifdef MBEDTLS_NIST_KW_C EXPECT_EQ(0, mbedtls_nist_kw_self_test(0)); #endif } #endif /* MBEDTLS_SELF_TEST */ static void P256_MPI(mbedtls_mpi *N) { memcpy(N->p, rng, 8 * 8); ASSERT_EQ(0, mbedtls_mpi_mod_mpi(N, N, &grp.P)); } static void P256_JUSTINE(mbedtls_mpi *N) { memcpy(N->p, rng, 8 * 8); ecp_mod_p256(N); } static void P384_MPI(mbedtls_mpi *N) { memcpy(N->p, rng, 8 * 8); ASSERT_EQ(0, mbedtls_mpi_mod_mpi(N, N, &grp.P)); } static void P384_JUSTINE(mbedtls_mpi *N) { memcpy(N->p, rng, 8 * 8); ecp_mod_p384(N); } BENCH(p256, bench) { #ifdef MBEDTLS_ECP_C mbedtls_ecp_group_init(&grp); mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1); mbedtls_mpi x = {1, 8, gc(calloc(8, 8))}; EZBENCH2("P-256 modulus MbedTLS MPI lib", donothing, P256_MPI(&x)); EZBENCH2("P-256 modulus Justine rewrite", donothing, P256_JUSTINE(&x)); mbedtls_ecp_group_free(&grp); #endif } BENCH(p384, bench) { #ifdef MBEDTLS_ECP_C mbedtls_ecp_group_init(&grp); mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP384R1); mbedtls_mpi x = {1, 12, gc(calloc(12, 8))}; EZBENCH2("P-384 modulus MbedTLS MPI lib", donothing, P384_MPI(&x)); EZBENCH2("P-384 modulus Justine rewrite", donothing, P384_JUSTINE(&x)); rngset(x.p, 12 * 8, rand64, -1); mbedtls_ecp_group_free(&grp); #endif } TEST(md5, test) { uint8_t d[16]; uint8_t want[16] = {0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72}; mbedtls_md5_ret("abc", 3, d); EXPECT_EQ(0, memcmp(want, d, 16)); } TEST(sha1, test) { uint8_t d[20]; uint8_t want[20] = {0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D}; mbedtls_sha1_ret("abc", 3, d); EXPECT_EQ(0, memcmp(want, d, 20)); } TEST(sha224, test) { uint8_t d[28]; uint8_t want[28] = {0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22, 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3, 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7, 0xE3, 0x6C, 0x9D, 0xA7}; mbedtls_sha256_ret("abc", 3, d, 1); EXPECT_EQ(0, memcmp(want, d, 28)); } TEST(sha256, test) { uint8_t d[32]; uint8_t want[32] = {0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD}; mbedtls_sha256_ret("abc", 3, d, 0); EXPECT_EQ(0, memcmp(want, d, 32)); } TEST(sha384, test) { uint8_t d[48]; uint8_t want[48] = { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B, 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07, 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63, 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED, 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23, 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7}; mbedtls_sha512_ret("abc", 3, d, 1); EXPECT_EQ(0, memcmp(want, d, 48)); } TEST(sha512, test) { uint8_t d[64]; uint8_t want[64] = { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31, 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2, 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A, 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8, 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD, 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E, 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F}; mbedtls_sha512_ret("abc", 3, d, 0); EXPECT_EQ(0, memcmp(want, d, 64)); } BENCH(mbedtls, bench) { uint8_t d[64]; EZBENCH2("md5", donothing, mbedtls_md5_ret(kHyperion, kHyperionSize, d)); EZBENCH2("sha1", donothing, mbedtls_sha1_ret(kHyperion, kHyperionSize, d)); EZBENCH2("sha256", donothing, mbedtls_sha256_ret(kHyperion, kHyperionSize, d, 0)); EZBENCH2("sha384", donothing, mbedtls_sha512_ret(kHyperion, kHyperionSize, d, 1)); EZBENCH2("sha512", donothing, mbedtls_sha512_ret(kHyperion, kHyperionSize, d, 0)); } char *mpi2str(mbedtls_mpi *m) { size_t n; char s[1024]; ASSERT_EQ(0, mbedtls_mpi_write_string(m, 10, s, sizeof(s), &n)); return xasprintf("%.*s", n, s); } mbedtls_mpi *str2mpi(const char *s) { size_t n; mbedtls_mpi *m; m = calloc(1, sizeof(mbedtls_mpi)); ASSERT_EQ(0, mbedtls_mpi_read_string(m, 10, s)); return m; } char *mpi2str16(mbedtls_mpi *m) { size_t n; char s[1024]; ASSERT_EQ(0, mbedtls_mpi_write_string(m, 16, s, sizeof(s), &n)); return xasprintf("%.*s", n, s); } mbedtls_mpi *str2mpi16(const char *s) { size_t n; mbedtls_mpi *m; m = calloc(1, sizeof(mbedtls_mpi)); ASSERT_EQ(0, mbedtls_mpi_read_string(m, 16, s)); return m; } void CtrDrbgOverhead(void) { mbedtls_ctr_drbg_context rng; mbedtls_ctr_drbg_init(&rng); ASSERT_EQ(0, mbedtls_ctr_drbg_seed(&rng, GetEntropy, 0, "justine", 7)); mbedtls_ctr_drbg_free(&rng); } void CtrDrbgReseed(mbedtls_ctr_drbg_context *rng) { ASSERT_EQ(0, mbedtls_ctr_drbg_reseed( rng, "justinejustinejustinejustinejustinejustinejustinejustinejus" "tinejustinejustinejustinejustine", 64)); } BENCH(CtrDrbg, bench) { mbedtls_ctr_drbg_context rng; mbedtls_ctr_drbg_init(&rng); ASSERT_EQ(0, mbedtls_ctr_drbg_seed(&rng, GetEntropy, 0, "justine", 7)); /* EZBENCH2("CtrDrbgOverhead", donothing, CtrDrbgOverhead()); */ /* EZBENCH2("CtrDrbgReseed", donothing, CtrDrbgReseed(&rng)); */ mbedtls_ctr_drbg_free(&rng); } static void *realloc3(void *opaque, void *ptr, size_t size) { return realloc(ptr, size); } #if 0 BENCH(quickjs_remainder, bench) { char *t; bf_context_t s; bfdec_t x, y, r; bf_context_init(&s, realloc3, 0); bfdec_init(&s, &x); bfdec_init(&s, &y); bfdec_init(&s, &r); bfdec_atof( &x, "131820409343094310010388979423659136318401916109327276909280345024175692" "811283445510797521231721220331409407564807168230384468176942405812817310" "624525121840385446744443868889563289706427719939300365865529242495144888" "321833894158323756200092849226089461110385787540779132654409185831255860" "504316472846036364908238500078268116724689002106891044880894853471921527" "088201197650061259448583977618746693012787452335047965869945140544352170" "538037327032402834008159261693483647994727160945768940072431686625688866" "030658324868306061250176433564697324072528745672177336948242366753233417" "556818392219546938204560720202538843712268268448586361942128751395665874" "453900680147479758139717481147704392488266886671292379541285558418744606" "657296304926586001793382725791100208812287673612006034789731201688939975" "743537276539989692230927982557016660679726989062369216287647728379155260" "864643891615705346169567037448405029752790940875872989684235165316260908" "983893514490200568512210790489667188789433092320719785756398772086212370" "409401269127676106581410793787580434036114254547441805771508552049371634" "609025127325512605396392214570059772472666763440181556475095153967113514" "87546062479444592779055555421362722504575706910949375", NULL, BF_PREC_INF, BF_RNDZ | BF_ATOF_NO_NAN_INF); bfdec_atof( &y, "402702961953621844286950607555369624422784868935557056881131335461307658" "701727371551406721502307932123276358395008895125652043531209418099658895" "323804953421455502359439932416245276659698167468088937570774479761417692" "998541764456595941884384880600102787969744607942278005344329659944902212" "055120534831056155566296908941240558524043054812784309119298489621361046" "430678313566109525110538452853054430839857155846105630169165566758950183" "947324955260740763926892668470396323574248496692684009312249052922911490" "770564765036629340924434941440277974966684311625406958698534967519709470" "161586090763966964691950363765288731535684692199342872936240602328625671" "612857527958722799557444770545725755417136296135977255647153119878181440" "110593529655379472903525700943247456832124407971558524965730661045026185" "674462056105044630573746839553952570745211879290387589347246867522065584" "726369942916093728137773105488374703562705889962546268226061545128021323" "184760695318697037612212579413382773618361971983327301685232523283210570" "2331094682317528819996876363073536047370469375", NULL, BF_PREC_INF, BF_RNDZ | BF_ATOF_NO_NAN_INF); bfdec_rem(&r, &x, &y, BF_PREC_INF, 0, BF_RNDF); t = gc(bfdec_ftoa(0, &r, BF_PREC_INF, BF_RNDZ | BF_FTOA_FORMAT_FREE)); ASSERT_STREQ("327339060789614187001318969682759915221664204604306478" "948329136809613379640467455488327009232590415715088668" "4127560071009217256545885393053328527589375", t); EZBENCH2("quickjs remainder", donothing, bfdec_rem(&r, &x, &y, BF_PREC_INF, 0, BF_RNDF)); bfdec_delete(&r); bfdec_delete(&y); bfdec_delete(&x); bf_context_end(&s); } #endif BENCH(mpi_remainder, bench) { mbedtls_mpi *x, *y, r; x = str2mpi( "131820409343094310010388979423659136318401916109327276909280345024175692" "811283445510797521231721220331409407564807168230384468176942405812817310" "624525121840385446744443868889563289706427719939300365865529242495144888" "321833894158323756200092849226089461110385787540779132654409185831255860" "504316472846036364908238500078268116724689002106891044880894853471921527" "088201197650061259448583977618746693012787452335047965869945140544352170" "538037327032402834008159261693483647994727160945768940072431686625688866" "624525121840385446744443868889563289706427719939300365865529242495144888" "321833894158323756200092849226089461110385787540779132654409185831255860" "504316472846036364908238500078268116724689002106891044880894853471921527" "088201197650061259448583977618746693012787452335047965869945140544352170" "538037327032402834008159261693483647994727160945768940072431686625688866" "624525121840385446744443868889563289706427719939300365865529242495144888" "321833894158323756200092849226089461110385787540779132654409185831255860" "504316472846036364908238500078268116724689002106891044880894853471921527" "088201197650061259448583977618746693012787452335047965869945140544352170" "538037327032402834008159261693483647994727160945768940072431686625688866" "624525121840385446744443868889563289706427719939300365865529242495144888" "321833894158323756200092849226089461110385787540779132654409185831255860" "504316472846036364908238500078268116724689002106891044880894853471921527" "088201197650061259448583977618746693012787452335047965869945140544352170" "538037327032402834008159261693483647994727160945768940072431686625688866" "030658324868306061250176433564697324072528745672177336948242366753233417" "556818392219546938204560720202538843712268268448586361942128751395665874" "453900680147479758139717481147704392488266886671292379541285558418744606" "657296304926586001793382725791100208812287673612006034789731201688939975" "743537276539989692230927982557016660679726989062369216287647728379155260" "864643891615705346169567037448405029752790940875872989684235165316260908" "430678313566109525110538452853054430839857155846105630169165566758950183" "947324955260740763926892668470396323574248496692684009312249052922911490" "770564765036629340924434941440277974966684311625406958698534967519709470" "161586090763966964691950363765288731535684692199342872936240602328625671" "612857527958722799557444770545725755417136296135977255647153119878181440" "430678313566109525110538452853054430839857155846105630169165566758950183" "947324955260740763926892668470396323574248496692684009312249052922911490" "770564765036629340924434941440277974966684311625406958698534967519709470" "161586090763966964691950363765288731535684692199342872936240602328625671" "612857527958722799557444770545725755417136296135977255647153119878181440" "983893514490200568512210790489667188789433092320719785756398772086212370" "409401269127676106581410793787580434036114254547441805771508552049371634" "609025127325512605396392214570059772472666763440181556475095153967113514" "87546062479444592779055555421362722504575706910949375"); y = str2mpi( "402702961953621844286950607555369624422784868935557056881131335461307658" "701727371551406721502307932123276358395008895125652043531209418099658895" "323804953421455502359439932416245276659698167468088937570774479761417692" "998541764456595941884384880600102787969744607942278005344329659944902212" "055120534831056155566296908941240558524043054812784309119298489621361046" "430678313566109525110538452853054430839857155846105630169165566758950183" "947324955260740763926892668470396323574248496692684009312249052922911490" "770564765036629340924434941440277974966684311625406958698534967519709470" "161586090763966964691950363765288731535684692199342872936240602328625671" "612857527958722799557444770545725755417136296135977255647153119878181440" "430678313566109525110538452853054430839857155846105630169165566758950183" "947324955260740763926892668470396323574248496692684009312249052922911490" "770564765036629340924434941440277974966684311625406958698534967519709470" "161586090763966964691950363765288731535684692199342872936240602328625671" "612857527958722799557444770545725755417136296135977255647153119878181440" "430678313566109525110538452853054430839857155846105630169165566758950183" "947324955260740763926892668470396323574248496692684009312249052922911490" "770564765036629340924434941440277974966684311625406958698534967519709470" "161586090763966964691950363765288731535684692199342872936240602328625671" "612857527958722799557444770545725755417136296135977255647153119878181440" "110593529655379472903525700943247456832124407971558524965730661045026185" "674462056105044630573746839553952570745211879290387589347246867522065584" "726369942916093728137773105488374703562705889962546268226061545128021323" "184760695318697037612212579413382773618361971983327301685232523283210570" "2331094682317528819996876363073536047370469375"); mbedtls_mpi_init(&r); EZBENCH2("mpi_remainder", donothing, mbedtls_mpi_mod_mpi(&r, x, y)); mbedtls_mpi_free(&r); mbedtls_mpi_free(x); mbedtls_mpi_free(y); } BENCH(mpi_mul_int, bench) { mbedtls_mpi *x, y; x = str2mpi( "131820409343094310010388979423659136318401916109327276909280345024175692" "811283445510797521231721220331409407564807168230384468176942405812817310" "624525121840385446744443868889563289706427719939300365865529242495144888" "321833894158323756200092849226089461110385787540779132654409185831255860" "504316472846036364908238500078268116724689002106891044880894853471921527" "088201197650061259448583977618746693012787452335047965869945140544352170" "538037327032402834008159261693483647994727160945768940072431686625688866" "624525121840385446744443868889563289706427719939300365865529242495144888" "321833894158323756200092849226089461110385787540779132654409185831255860" "504316472846036364908238500078268116724689002106891044880894853471921527" "088201197650061259448583977618746693012787452335047965869945140544352170" "538037327032402834008159261693483647994727160945768940072431686625688866" "624525121840385446744443868889563289706427719939300365865529242495144888" "321833894158323756200092849226089461110385787540779132654409185831255860" "504316472846036364908238500078268116724689002106891044880894853471921527" "088201197650061259448583977618746693012787452335047965869945140544352170" "538037327032402834008159261693483647994727160945768940072431686625688866" "624525121840385446744443868889563289706427719939300365865529242495144888" "321833894158323756200092849226089461110385787540779132654409185831255860" "504316472846036364908238500078268116724689002106891044880894853471921527" "088201197650061259448583977618746693012787452335047965869945140544352170" "538037327032402834008159261693483647994727160945768940072431686625688866" "030658324868306061250176433564697324072528745672177336948242366753233417" "556818392219546938204560720202538843712268268448586361942128751395665874" "453900680147479758139717481147704392488266886671292379541285558418744606" "657296304926586001793382725791100208812287673612006034789731201688939975" "743537276539989692230927982557016660679726989062369216287647728379155260" "864643891615705346169567037448405029752790940875872989684235165316260908" "430678313566109525110538452853054430839857155846105630169165566758950183" "947324955260740763926892668470396323574248496692684009312249052922911490" "770564765036629340924434941440277974966684311625406958698534967519709470" "161586090763966964691950363765288731535684692199342872936240602328625671" "612857527958722799557444770545725755417136296135977255647153119878181440" "430678313566109525110538452853054430839857155846105630169165566758950183" "947324955260740763926892668470396323574248496692684009312249052922911490" "770564765036629340924434941440277974966684311625406958698534967519709470" "161586090763966964691950363765288731535684692199342872936240602328625671" "612857527958722799557444770545725755417136296135977255647153119878181440" "983893514490200568512210790489667188789433092320719785756398772086212370" "409401269127676106581410793787580434036114254547441805771508552049371634" "609025127325512605396392214570059772472666763440181556475095153967113514" "87546062479444592779055555421362722504575706910949375"); mbedtls_mpi_init(&y); EZBENCH2("mpi_mul_int", donothing, ({ mbedtls_mpi_copy(&y, x); mbedtls_mpi_mul_int(&y, &y, 31337); })); EZBENCH2("mpi_mul_mpi (scalar)", donothing, ({ mbedtls_mpi b = {1, 1, (uint64_t[]){31337}}; mbedtls_mpi_copy(&y, x); mbedtls_mpi_mul_mpi(&y, &y, &b); })); mbedtls_mpi_free(&y); mbedtls_mpi_free(x); } BENCH(mpi_shift_r, bench) { mbedtls_mpi x; mbedtls_mpi_init(&x); mbedtls_mpi_fill_random(&x, 2048 / 8, GetEntropy, 0); EZBENCH2("mpi_shift_r (0)", donothing, mbedtls_mpi_shift_r(&x, 0)); EZBENCH2("mpi_shift_r (1)", donothing, mbedtls_mpi_shift_r(&x, 1)); EZBENCH2("mpi_shift_r (65)", donothing, mbedtls_mpi_shift_r(&x, 65)); EZBENCH2("mpi_shift_r (1024)", donothing, mbedtls_mpi_shift_r(&x, 1024)); EZBENCH2("mpi_shift_r (1983)", donothing, mbedtls_mpi_shift_r(&x, 1983)); EZBENCH2("mpi_shift_r (2047)", donothing, mbedtls_mpi_shift_r(&x, 2047)); EZBENCH2("mpi_shift_r (2048)", donothing, mbedtls_mpi_shift_r(&x, 2048)); mbedtls_mpi_free(&x); } TEST(mpi_shift_r, doesntCrash_dontUnderstandWeirdUpstreamBehavior) { mbedtls_mpi x = {1, 0, 0}; EXPECT_EQ(0, mbedtls_mpi_shift_r(&x, 1)); } TEST(mpi_shift_l, doesntCrash_dontUnderstandWeirdUpstreamBehavior) { mbedtls_mpi x = {1, 0, 0}; EXPECT_EQ(0, mbedtls_mpi_shift_l(&x, 1)); } TEST(mpi_shift_r, fun0) { mbedtls_mpi x = {1, 1, (uint64_t[]){2}}; EXPECT_EQ(0, mbedtls_mpi_shift_r(&x, 1)); EXPECT_EQ(1, x.n); EXPECT_EQ(1, x.p[0]); } TEST(mpi_shift_r, fun1) { mbedtls_mpi x = {1, 7, (uint64_t[]){2, 4, 8, 16, 32, 64, 128}}; EXPECT_EQ(0, mbedtls_mpi_shift_r(&x, 129)); EXPECT_EQ(7, x.n); EXPECT_EQ(4, x.p[0]); EXPECT_EQ(8, x.p[1]); EXPECT_EQ(16, x.p[2]); EXPECT_EQ(32, x.p[3]); EXPECT_EQ(64, x.p[4]); EXPECT_EQ(0, x.p[5]); EXPECT_EQ(0, x.p[6]); } TEST(mpi_shift_r, fun2) { mbedtls_mpi x = {1, 3, (uint64_t[]){0, 1, 0}}; EXPECT_EQ(0, mbedtls_mpi_shift_r(&x, 1)); EXPECT_EQ(3, x.n); EXPECT_EQ(0x8000000000000000, x.p[0]); EXPECT_EQ(0, x.p[1]); EXPECT_EQ(0, x.p[2]); } TEST(mpi_shift_l, fun0) { mbedtls_mpi x = {1, 1, (uint64_t[]){2}}; EXPECT_EQ(0, mbedtls_mpi_shift_l(&x, 1)); EXPECT_EQ(1, x.n); EXPECT_EQ(4, x.p[0]); } TEST(mpi_shift_r, funbye) { mbedtls_mpi x = {1, 1, (uint64_t[]){2}}; EXPECT_EQ(0, mbedtls_mpi_shift_r(&x, 100)); EXPECT_EQ(1, x.n); EXPECT_EQ(0, x.p[0]); } TEST(mpi_shift_l, fun1) { mbedtls_mpi w = {1, 9, (uint64_t[]){0, 0, 2 << 1, 4 << 1, 8 << 1, 16 << 1, 32 << 1, 64 << 1, 128 << 1}}; mbedtls_mpi x = {1, 9, (uint64_t[]){2, 4, 8, 16, 32, 64, 128, 0, 0}}; EXPECT_EQ(0, mbedtls_mpi_shift_l(&x, 129)); EXPECT_EQ(9, x.n); EXPECT_EQ(0, x.p[0]); EXPECT_EQ(0, x.p[1]); EXPECT_EQ(2 << 1, x.p[2]); EXPECT_EQ(4 << 1, x.p[3]); EXPECT_EQ(8 << 1, x.p[4]); EXPECT_EQ(16 << 1, x.p[5]); EXPECT_EQ(32 << 1, x.p[6]); EXPECT_EQ(64 << 1, x.p[7]); EXPECT_EQ(128 << 1, x.p[8]); } TEST(mpi_shift_l, fun2) { mbedtls_mpi o = {1, 3, (uint64_t[9]){0x8000000000000000, 0, 0}}; mbedtls_mpi w = {1, 3, (uint64_t[9]){0, 1, 0}}; mbedtls_mpi x = {1, 3, (uint64_t[9]){ 0x8000000000000003, 0x8000000000000002, 0x0000000000000001, }}; EXPECT_EQ(0, mbedtls_mpi_shift_l(&x, 1)); EXPECT_EQ(3, x.n); EXPECT_EQ(6, x.p[0]); EXPECT_EQ(5, x.p[1]); EXPECT_EQ(3, x.p[2]); EXPECT_EQ(0, x.p[3]); } int BenchShiftLeft(mbedtls_mpi *X, size_t k) { X->n = 2048 / 64; X->p[X->n - 1] |= 1; return mbedtls_mpi_shift_l(X, k); } BENCH(mpi_shift_l, bench) { mbedtls_mpi x; mbedtls_mpi_init(&x); mbedtls_mpi_fill_random(&x, 2048 / 8, GetEntropy, 0); EZBENCH2("mpi_shift_l (0)", donothing, BenchShiftLeft(&x, 0)); EZBENCH2("mpi_shift_l (1)", donothing, BenchShiftLeft(&x, 1)); EZBENCH2("mpi_shift_l (65)", donothing, BenchShiftLeft(&x, 65)); EZBENCH2("mpi_shift_l (1024)", donothing, BenchShiftLeft(&x, 1024)); EZBENCH2("mpi_shift_l (1983)", donothing, BenchShiftLeft(&x, 1983)); EZBENCH2("mpi_shift_l (2047)", donothing, BenchShiftLeft(&x, 2047)); EZBENCH2("mpi_shift_l (2048)", donothing, BenchShiftLeft(&x, 2048)); mbedtls_mpi_free(&x); } BENCH(gcd, bench) { mbedtls_mpi g = {1, 16, (uint64_t[32]){0}}; mbedtls_mpi x = {1, 16, (uint64_t[32]){1500}}; mbedtls_mpi y = {1, 16, (uint64_t[32]){700}}; mbedtls_mpi_gcd(&g, &x, &y); EXPECT_EQ(100, g.p[0]); mbedtls_mpi_fill_random(&x, 16 * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&y, 16 * 8, GetEntropy, 0); EZBENCH2("mbedtls_mpi_gcd (16)", donothing, mbedtls_mpi_gcd(&g, &x, &y)); } BENCH(inv_mod, bench3) { mbedtls_mpi g = {0}; mbedtls_mpi *x = str2mpi16( "837B3E23091602B5D14D619D9B2CD79DD039BC9A9F46F0CA1FFD01B398EE42C8EE2142CB" "B295109FC4278DB8AB84A6ADBF319D3297216C349D0EB92925E2794C5FF1AAF664034CB2" "5C15CDA49B7947278AA96BEF9D995C5F99AA4809B12568A1513D8E0A37BB338DC44A1722" "F7821CFB11EBF2578151A3C8ECA1280AA4B1500463777FBBC00AE603A1A8F3C099524622" "7AFFD15FB66B320DF53CEA4D6C9935D0593BFC7A75ABAFDD3016F7C596FA58248BC041CF" "68ED274FA7F7D5BC3E014DDC7BEA4A60DF24805B5F94C998CAF28441FB4A5831755CE935" "2F17F5416647A81A78899E5B2C4D3F6C84A81CEB463C1593392ABCF6BF708A55578EB0EF" "E9ABF572"); mbedtls_mpi *y = str2mpi16( "C14DA3DDE7CD1DD104D74972B899AC0E78E43A3C4ACF3A1316D05AE4CDA30088A7EE1E6B" "96A752B490EF2D727A3E249AFCB634AC24F577E026648C9CB0287DA1DAEA8CE6C91C96BC" "FEC10452B336D4A3FAE1B176D890C161B4665236A22653AAAB745E077D1982DB2AD81FA0" "D90D1C2D4966F75B257346E80B8A4F690CB50090E1DA8210667DAE542B8B657991A1E261" "C3CD404908EE680CF18B86D246BFD0B8AA11031E7F56A81A1E44180F0F858BDA8B445EE2" "18C6622FC7668DFA5DD87DF327892901C5900E3F27F130C84A0EEFD6DEC7C7276BC7053D" "7AC4023C9A1D3E0FE834985BCB734B5296D811A22C808869395AD30FB0DE592F11C7F7EA" "12013097"); mbedtls_mpi_inv_mod(&g, x, y); EZBENCH2("mbedtls_mpi_inv_mod (actual)", donothing, mbedtls_mpi_inv_mod(&g, x, y)); mbedtls_mpi_free(&g); mbedtls_mpi_free(x); mbedtls_mpi_free(y); } TEST(ShiftRightAvx, test1) { int i; for (i = 0; i < 10; ++i) { uint64_t mem[1] = {rand64()}; uint64_t want[1]; uint64_t got[1]; memcpy(want, mem, sizeof(mem)); memcpy(got, mem, sizeof(mem)); ShiftRightPure(want, 1, 1); ShiftRightAvx(got, 1, 1); EXPECT_EQ(want[0], got[0]); } } TEST(ShiftRightAvx, test2) { int i; for (i = 0; i < 10; ++i) { uint64_t mem[2] = {rand64(), rand64()}; uint64_t want[2]; uint64_t got[2]; memcpy(want, mem, sizeof(mem)); memcpy(got, mem, sizeof(mem)); ShiftRightPure(want, 2, 1); ShiftRightAvx(got, 2, 1); EXPECT_EQ(want[0], got[0]); EXPECT_EQ(want[1], got[1]); } } TEST(ShiftRightAvx, test3) { int i; for (i = 0; i < 10; ++i) { uint64_t mem[3] = {rand64(), rand64(), rand64()}; uint64_t want[3]; uint64_t got[3]; memcpy(want, mem, sizeof(mem)); memcpy(got, mem, sizeof(mem)); ShiftRightPure(want, 3, 1); ShiftRightAvx(got, 3, 1); EXPECT_EQ(want[0], got[0]); EXPECT_EQ(want[1], got[1]); EXPECT_EQ(want[2], got[2]); } } TEST(ShiftRightAvx, test4) { int i; for (i = 0; i < 10; ++i) { uint64_t mem[4] = {rand64(), rand64(), rand64(), rand64()}; uint64_t want[4]; uint64_t got[4]; memcpy(want, mem, sizeof(mem)); memcpy(got, mem, sizeof(mem)); ShiftRightPure(want, 4, 1); ShiftRightAvx(got, 4, 1); EXPECT_EQ(want[0], got[0]); EXPECT_EQ(want[1], got[1]); EXPECT_EQ(want[2], got[2]); EXPECT_EQ(want[3], got[3]); } } TEST(ShiftRightAvx, test8) { int i; for (i = 0; i < 10; ++i) { uint64_t mem[8] = {rand64(), rand64(), rand64(), rand64(), rand64(), rand64(), rand64(), rand64()}; uint64_t want[8]; uint64_t got[8]; memcpy(want, mem, sizeof(mem)); memcpy(got, mem, sizeof(mem)); ShiftRightPure(want, 8, 1); ShiftRightAvx(got, 8, 1); EXPECT_EQ(want[0], got[0]); EXPECT_EQ(want[1], got[1]); EXPECT_EQ(want[2], got[2]); EXPECT_EQ(want[3], got[3]); EXPECT_EQ(want[4], got[4]); EXPECT_EQ(want[5], got[5]); EXPECT_EQ(want[6], got[6]); EXPECT_EQ(want[7], got[7]); } } TEST(ShiftRightAvx, test9) { int i; for (i = 0; i < 10; ++i) { uint64_t mem[9] = {rand64(), rand64(), rand64(), rand64(), rand64(), rand64(), rand64(), rand64(), rand64()}; uint64_t want[9]; uint64_t got[9]; memcpy(want, mem, sizeof(mem)); memcpy(got, mem, sizeof(mem)); ShiftRightPure(want, 9, 1); ShiftRightAvx(got, 9, 1); EXPECT_EQ(want[0], got[0]); EXPECT_EQ(want[1], got[1]); EXPECT_EQ(want[2], got[2]); EXPECT_EQ(want[3], got[3]); } } BENCH(ShiftRight, bench) { uint64_t x[64]; rngset(x, sizeof(x), rand64, -1); EZBENCH2("ShiftRight", donothing, ShiftRight(x, 64, 1)); EZBENCH2("ShiftRightAvx", donothing, ShiftRightAvx(x, 64, 1)); EZBENCH2("ShiftRightPure", donothing, ShiftRightPure(x, 64, 1)); } BENCH(Zeroize, bench) { uint64_t x[64]; rngset(x, sizeof(x), rand64, -1); EZBENCH2("memset (64)", donothing, memset(x, 0, sizeof(x))); EZBENCH2("Zeroize (64)", donothing, mbedtls_platform_zeroize(x, 64)); } int mbedtls_mpi_read_binary2(mbedtls_mpi *X, const unsigned char *p, size_t n); TEST(endian, big1) { /* uint8_t b[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, */ /* 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; */ uint8_t b[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, // 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x03, // }; mbedtls_mpi x; mbedtls_mpi_init(&x); ASSERT_EQ(0, mbedtls_mpi_read_binary(&x, b, ARRAYLEN(b))); EXPECT_GE(x.n, 3); EXPECT_EQ(0x0000000000000003, x.p[0]); EXPECT_EQ(0x0000000000000702, x.p[1]); EXPECT_EQ(0x0000000000000001, x.p[2]); mbedtls_mpi_free(&x); } TEST(endian, big2) { uint8_t b[] = { 0x01, // }; mbedtls_mpi x; mbedtls_mpi_init(&x); ASSERT_EQ(0, mbedtls_mpi_read_binary(&x, b, ARRAYLEN(b))); EXPECT_EQ(1, x.n); EXPECT_EQ(0x0000000000000001, x.p[0]); mbedtls_mpi_free(&x); } TEST(endian, big3) { uint8_t b[] = { 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x01, 0x02, // }; mbedtls_mpi x; mbedtls_mpi_init(&x); ASSERT_EQ(0, mbedtls_mpi_read_binary(&x, b, ARRAYLEN(b))); EXPECT_EQ(2, x.n); EXPECT_EQ(0x0101010101010102, x.p[0]); EXPECT_EQ(0x0000000000000102, x.p[1]); mbedtls_mpi_free(&x); } TEST(endian, big4) { uint8_t b[] = { 0x11, 0x68, 0x5b, 0xb5, 0x76, 0x6f, 0xb5, 0x72, // 0x43, 0xd2, 0x3f, 0xd6, 0xc0, 0x1b, 0xa3, 0x2e, // 0x40, 0x77, 0x12, 0xc8, 0x59, 0x4e, 0x63, 0xab, // 0xea, 0xeb, 0x4a, 0x58, 0x50, 0xbd, 0xed, 0x30, // 0x10, 0x76, 0xa9, 0xfa, 0x01, 0xa1, 0x07, 0xe8, // 0xa3, 0xd5, 0xaf, 0x4e, 0x1f, 0xf6, 0xaf, // }; mbedtls_mpi x; mbedtls_mpi_init(&x); ASSERT_EQ(0, mbedtls_mpi_read_binary(&x, b, ARRAYLEN(b))); EXPECT_GE(x.n, 6); EXPECT_EQ(0xe8a3d5af4e1ff6af, x.p[0]); EXPECT_EQ(0x301076a9fa01a107, x.p[1]); EXPECT_EQ(0xabeaeb4a5850bded, x.p[2]); EXPECT_EQ(0x2e407712c8594e63, x.p[3]); EXPECT_EQ(0x7243d23fd6c01ba3, x.p[4]); mbedtls_mpi_free(&x); } TEST(Mul4x4, test) { int i, j, N, M; mbedtls_mpi A, B, C, D; if (!X86_HAVE(BMI2) || !X86_HAVE(ADX)) return; N = 4; M = 4; mbedtls_mpi_init(&A); mbedtls_mpi_init(&B); mbedtls_mpi_init(&C); mbedtls_mpi_init(&D); mbedtls_mpi_fill_random(&A, N * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&B, M * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&C, (N + M) * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&D, (N + M) * 8, GetEntropy, 0); mbedtls_mpi_mul_mpi(&C, &A, &B); Mul4x4(D.p, A.p, B.p); EXPECT_EQ(0, memcmp(D.p, C.p, (N + M) * 8)); mbedtls_mpi_free(&D); mbedtls_mpi_free(&C); mbedtls_mpi_free(&B); mbedtls_mpi_free(&A); } BENCH(Mul4x4, bench) { int i, j, N, M; mbedtls_mpi A, B, C, D, E; if (!X86_HAVE(BMI2) || !X86_HAVE(ADX)) return; N = 4; M = 4; mbedtls_mpi_init(&A); mbedtls_mpi_init(&B); mbedtls_mpi_init(&C); mbedtls_mpi_init(&D); mbedtls_mpi_init(&E); mbedtls_mpi_fill_random(&A, N * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&B, M * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&C, (N + M) * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&D, (N + M) * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&E, (N + M) * 8, GetEntropy, 0); Mul(C.p, A.p, N, B.p, M); Mul4x4Adx(D.p, A.p, B.p); Mul4x4Pure(E.p, A.p, B.p); if (memcmp(E.p, C.p, (N + M) * 8)) { printf("\n"); printf( "# X Y MPI RESULT PURE " "RESULT\n"); for (i = 0; i < N + M; ++i) { printf("0x%016lx * 0x%016lx = 0x%016lx vs. 0x%016lx %d\n", i < N ? A.p[i] : 0, i < M ? B.p[i] : 0, E.p[i], C.p[i], E.p[i] == C.p[i]); } printf("\n"); } if (memcmp(D.p, C.p, (N + M) * 8)) { printf("\n"); printf("# X Y MPI RESULT ADX " "RESULT\n"); for (i = 0; i < N + M; ++i) { printf("0x%016lx * 0x%016lx = 0x%016lx vs. 0x%016lx %d\n", i < N ? A.p[i] : 0, i < M ? B.p[i] : 0, D.p[i], C.p[i], D.p[i] == C.p[i]); } printf("\n"); } EXPECT_EQ(0, memcmp(D.p, C.p, (N + M) * 8)); EXPECT_EQ(0, memcmp(E.p, C.p, (N + M) * 8)); EZBENCH2("orig multiply 4x4", donothing, Mul(C.p, A.p, N, B.p, M)); EZBENCH2("mpi multiply 4x4", donothing, mbedtls_mpi_mul_mpi(&C, &A, &B)); EZBENCH2("Mul4x4Adx", donothing, Mul4x4Adx(D.p, A.p, B.p)); EZBENCH2("Mul4x4Pure", donothing, Mul4x4Pure(E.p, A.p, B.p)); mbedtls_mpi_free(&E); mbedtls_mpi_free(&D); mbedtls_mpi_free(&C); mbedtls_mpi_free(&B); mbedtls_mpi_free(&A); } BENCH(Mul6x6, bench) { int i, j, N, M; mbedtls_mpi A, B, C, D; if (!X86_HAVE(BMI2) || !X86_HAVE(ADX)) return; N = 6; M = 6; mbedtls_mpi_init(&A); mbedtls_mpi_init(&B); mbedtls_mpi_init(&C); mbedtls_mpi_init(&D); mbedtls_mpi_fill_random(&A, N * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&B, M * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&C, (N + M) * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&D, (N + M) * 8, GetEntropy, 0); Mul(C.p, A.p, N, B.p, M); Mul6x6Adx(D.p, A.p, B.p); if (memcmp(D.p, C.p, (N + M) * 8)) { printf("\n"); printf("# X Y MPI RESULT ADX " "RESULT\n"); for (i = 0; i < N + M; ++i) { printf("0x%016lx * 0x%016lx = 0x%016lx vs. 0x%016lx %d\n", i < N ? A.p[i] : 0, i < M ? B.p[i] : 0, D.p[i], C.p[i], D.p[i] == C.p[i]); } printf("\n"); } EXPECT_EQ(0, memcmp(D.p, C.p, (N + M) * 8)); EZBENCH2("orig multiply 6x6", donothing, Mul(C.p, A.p, N, B.p, M)); EZBENCH2("mpi multiply 6x6", donothing, mbedtls_mpi_mul_mpi(&C, &A, &B)); EZBENCH2("Mul6x6Adx", donothing, Mul6x6Adx(D.p, A.p, B.p)); mbedtls_mpi_free(&D); mbedtls_mpi_free(&C); mbedtls_mpi_free(&B); mbedtls_mpi_free(&A); } BENCH(Mul10x10, bench) { int i, j, N, M; mbedtls_mpi A, B, C, D; if (!X86_HAVE(BMI2) || !X86_HAVE(ADX)) return; N = 10; M = 10; mbedtls_mpi_init(&A); mbedtls_mpi_init(&B); mbedtls_mpi_init(&C); mbedtls_mpi_fill_random(&A, N * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&B, M * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&C, (N + M) * 8, GetEntropy, 0); mbedtls_mpi_mul_mpi(&C, &A, &B); EZBENCH2("mpi multiply 10x10", donothing, mbedtls_mpi_mul_mpi(&C, &A, &B)); mbedtls_mpi_free(&C); mbedtls_mpi_free(&B); mbedtls_mpi_free(&A); } BENCH(Mul16x16, bench) { int i, j, N, M; mbedtls_mpi A, B, C, D; if (!X86_HAVE(BMI2) || !X86_HAVE(ADX)) return; N = 16; M = 16; mbedtls_mpi_init(&A); mbedtls_mpi_init(&B); mbedtls_mpi_init(&C); mbedtls_mpi_fill_random(&A, N * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&B, M * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&C, (N + M) * 8, GetEntropy, 0); mbedtls_mpi_mul_mpi(&C, &A, &B); EZBENCH2("mpi multiply 16x16", donothing, mbedtls_mpi_mul_mpi(&C, &A, &B)); mbedtls_mpi_free(&C); mbedtls_mpi_free(&B); mbedtls_mpi_free(&A); } BENCH(Mul32x32, bench) { int i, j, N, M; mbedtls_mpi A, B, C, D, K; if (!X86_HAVE(BMI2) || !X86_HAVE(ADX)) return; N = 32; M = 32; mbedtls_mpi_init(&A); mbedtls_mpi_init(&B); mbedtls_mpi_init(&C); mbedtls_mpi_init(&D); mbedtls_mpi_init(&K); for (i = 0; i < 8; ++i) { mbedtls_mpi_fill_random(&A, N * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&B, M * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&C, (N + M) * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&D, (N + M) * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&K, (N + M) * 2 * 8, GetEntropy, 0); mbedtls_mpi_mul_mpi(&C, &A, &B); Karatsuba(D.p, A.p, B.p, N, K.p); if (memcmp(D.p, C.p, (N + M) * 8)) { printf("\n"); printf("# X Y MPI RESULT OTH " "RESULT\n"); for (i = 0; i < N + M; ++i) { printf("0x%016lx * 0x%016lx = 0x%016lx vs. 0x%016lx %d\n", i < N ? A.p[i] : 0, i < M ? B.p[i] : 0, D.p[i], C.p[i], D.p[i] == C.p[i]); } printf("\n"); exit(1); } } EZBENCH2("mpi multiply 32x32", donothing, mbedtls_mpi_mul_mpi(&C, &A, &B)); EZBENCH2("karatsuba 32x32", donothing, Karatsuba(C.p, A.p, B.p, N, K.p)); mbedtls_mpi_free(&K); mbedtls_mpi_free(&D); mbedtls_mpi_free(&C); mbedtls_mpi_free(&B); mbedtls_mpi_free(&A); } BENCH(Mul16x1, bench) { int i, j, N, M; mbedtls_mpi A, B, C, D; if (!X86_HAVE(BMI2) || !X86_HAVE(ADX)) return; N = 16; M = 1; mbedtls_mpi_init(&A); mbedtls_mpi_init(&B); mbedtls_mpi_init(&C); mbedtls_mpi_fill_random(&A, N * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&B, M * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&C, (N + M) * 8, GetEntropy, 0); mbedtls_mpi_mul_mpi(&C, &A, &B); EZBENCH2("mpi multiply 16x1", donothing, mbedtls_mpi_mul_mpi(&C, &A, &B)); mbedtls_mpi_free(&C); mbedtls_mpi_free(&B); mbedtls_mpi_free(&A); } BENCH(Mul32x1, bench) { int i, j, N, M; mbedtls_mpi A, B, C, D; if (!X86_HAVE(BMI2) || !X86_HAVE(ADX)) return; N = 32; M = 1; mbedtls_mpi_init(&A); mbedtls_mpi_init(&B); mbedtls_mpi_init(&C); mbedtls_mpi_fill_random(&A, N * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&B, M * 8, GetEntropy, 0); mbedtls_mpi_fill_random(&C, (N + M) * 8, GetEntropy, 0); mbedtls_mpi_mul_mpi(&C, &A, &B); EZBENCH2("mpi multiply 32x1", donothing, mbedtls_mpi_mul_mpi(&C, &A, &B)); mbedtls_mpi_free(&C); mbedtls_mpi_free(&B); mbedtls_mpi_free(&A); } BENCH(isprime, bench1024) { mbedtls_mpi P; mbedtls_mpi_init(&P); EXPECT_EQ(0, mbedtls_mpi_gen_prime(&P, 1024, 0, GetEntropy, 0)); EXPECT_EQ(0, mbedtls_mpi_is_prime_ext(&P, 3, GetEntropy, 0)); EZBENCH2("isprime (1024)", donothing, mbedtls_mpi_is_prime_ext(&P, 3, GetEntropy, 0)); mbedtls_mpi_free(&P); } BENCH(cmpint, bench) { mbedtls_mpi x = {1, 8, (uint64_t[8]){0}}; mbedtls_mpi y = {1, 8, (uint64_t[8]){1}}; mbedtls_mpi z = {1, 8, (uint64_t[8]){1, 1, 1, 1, 1, 1, 1, 1}}; EZBENCH2("cmpint 1.1", donothing, mbedtls_mpi_cmp_int(&x, 0)); EZBENCH2("cmpint 1.2", donothing, mbedtls_mpi_cmp_int(&x, 1)); EZBENCH2("cmpint 2.1", donothing, mbedtls_mpi_cmp_int(&y, 0)); EZBENCH2("cmpint 2.2", donothing, mbedtls_mpi_cmp_int(&y, 1)); EZBENCH2("cmpint 3.1", donothing, mbedtls_mpi_cmp_int(&z, 0)); EZBENCH2("cmpint 3.2", donothing, mbedtls_mpi_cmp_int(&z, 1)); }