## Coverage Report

#### Created: 2023-09-25 06:11

`/src/dropbear/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c`
 `Line` `Count` `Source (jump to first uncovered line)` `1` `/* LibTomCrypt, modular cryptographic library -- Tom St Denis` `2` ` *` `3` ` * LibTomCrypt is a library that provides various cryptographic` `4` ` * algorithms in a highly modular and flexible manner.` `5` ` *` `6` ` * The library is free for all purposes without any express` `7` ` * guarantee it works.` `8` ` */` `9` `10` `/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b` `11` ` *` `12` ` * All curves taken from NIST recommendation paper of July 1999` `13` ` * Available at http://csrc.nist.gov/cryptval/dss.htm` `14` ` */` `15` `#include "tomcrypt.h"` `16` `17` `/**` `18` ` @file ltc_ecc_mul2add.c` `19` ` ECC Crypto, Shamir's Trick, Tom St Denis` `20` `*/` `21` `22` `#ifdef LTC_MECC` `23` `24` `#ifdef LTC_ECC_SHAMIR` `25` `26` `/** Computes kA*A + kB*B = C using Shamir's Trick` `27` ` @param A First point to multiply` `28` ` @param kA What to multiple A by` `29` ` @param B Second point to multiply` `30` ` @param kB What to multiple B by` `31` ` @param C [out] Destination point (can overlap with A or B` `32` ` @param modulus Modulus for curve` `33` ` @return CRYPT_OK on success` `34` `*/` `35` `int ltc_ecc_mul2add(ecc_point *A, void *kA,` `36` ` ecc_point *B, void *kB,` `37` ` ecc_point *C,` `38` ` void *modulus)` `39` `273` `{` `40` `273` ` ecc_point *precomp[16];` `41` `273` ` unsigned bitbufA, bitbufB, lenA, lenB, len, x, y, nA, nB, nibble;` `42` `273` ` unsigned char *tA, *tB;` `43` `273` ` int err, first;` `44` `273` ` void *mp, *mu;` `45` `46` ` /* argchks */` `47` `273` ` LTC_ARGCHK(A != NULL);` `48` `273` ` LTC_ARGCHK(B != NULL);` `49` `273` ` LTC_ARGCHK(C != NULL);` `50` `273` ` LTC_ARGCHK(kA != NULL);` `51` `273` ` LTC_ARGCHK(kB != NULL);` `52` `273` ` LTC_ARGCHK(modulus != NULL);` `53` `54` ` /* allocate memory */` `55` `273` ` tA = XCALLOC(1, ECC_BUF_SIZE);` `56` `273` ` if (tA == NULL) {` `57` `0` ` return CRYPT_MEM;` `58` `0` ` }` `59` `273` ` tB = XCALLOC(1, ECC_BUF_SIZE);` `60` `273` ` if (tB == NULL) {` `61` `0` ` XFREE(tA);` `62` `0` ` return CRYPT_MEM;` `63` `0` ` }` `64` `65` ` /* get sizes */` `66` `273` ` lenA = mp_unsigned_bin_size(kA);` `67` `273` ` lenB = mp_unsigned_bin_size(kB);` `68` `273` ` len = MAX(lenA, lenB);` `69` `70` ` /* sanity check */` `71` `273` ` if ((lenA > ECC_BUF_SIZE) || (lenB > ECC_BUF_SIZE)) {` `72` `0` ` err = CRYPT_INVALID_ARG;` `73` `0` ` goto ERR_T;` `74` `0` ` }` `75` `76` ` /* extract and justify kA */` `77` `273` ` mp_to_unsigned_bin(kA, (len - lenA) + tA);` `78` `79` ` /* extract and justify kB */` `80` `273` ` mp_to_unsigned_bin(kB, (len - lenB) + tB);` `81` `82` ` /* allocate the table */` `83` `4.64k` ` for (x = 0; x < 16; x++) {` `84` `4.36k` ` precomp[x] = ltc_ecc_new_point();` `85` `4.36k` ` if (precomp[x] == NULL) {` `86` `0` ` for (y = 0; y < x; ++y) {` `87` `0` ` ltc_ecc_del_point(precomp[y]);` `88` `0` ` }` `89` `0` ` err = CRYPT_MEM;` `90` `0` ` goto ERR_T;` `91` `0` ` }` `92` `4.36k` ` }` `93` `94` ` /* init montgomery reduction */` `95` `273` ` if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {` `96` `0` ` goto ERR_P;` `97` `0` ` }` `98` `273` ` if ((err = mp_init(&mu)) != CRYPT_OK) {` `99` `0` ` goto ERR_MP;` `100` `0` ` }` `101` `273` ` if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {` `102` `0` ` goto ERR_MU;` `103` `0` ` }` `104` `105` ` /* copy ones ... */` `106` `273` ` if ((err = mp_mulmod(A->x, mu, modulus, precomp[1]->x)) != CRYPT_OK) { goto ERR_MU; }` `107` `273` ` if ((err = mp_mulmod(A->y, mu, modulus, precomp[1]->y)) != CRYPT_OK) { goto ERR_MU; }` `108` `273` ` if ((err = mp_mulmod(A->z, mu, modulus, precomp[1]->z)) != CRYPT_OK) { goto ERR_MU; }` `109` `110` `273` ` if ((err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x)) != CRYPT_OK) { goto ERR_MU; }` `111` `273` ` if ((err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y)) != CRYPT_OK) { goto ERR_MU; }` `112` `273` ` if ((err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z)) != CRYPT_OK) { goto ERR_MU; }` `113` `114` ` /* precomp [i,0](A + B) table */` `115` `273` ` if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }` `116` `273` ` if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }` `117` `118` ` /* precomp [0,i](A + B) table */` `119` `273` ` if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }` `120` `273` ` if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }` `121` `122` ` /* precomp [i,j](A + B) table (i != 0, j != 0) */` `123` `1.09k` ` for (x = 1; x < 4; x++) {` `124` `3.27k` ` for (y = 1; y < 4; y++) {` `125` `2.45k` ` if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }` `126` `2.45k` ` }` `127` `819` ` }` `128` `129` `273` ` nibble = 3;` `130` `273` ` first = 1;` `131` `273` ` bitbufA = tA[0];` `132` `273` ` bitbufB = tB[0];` `133` `134` ` /* for every byte of the multiplicands */` `135` `51.0k` ` for (x = 0;; ) {` `136` ` /* grab a nibble */` `137` `51.0k` ` if (++nibble == 4) {` `138` `12.9k` ` if (x == len) break;` `139` `12.7k` ` bitbufA = tA[x];` `140` `12.7k` ` bitbufB = tB[x];` `141` `12.7k` ` nibble = 0;` `142` `12.7k` ` ++x;` `143` `12.7k` ` }` `144` `145` ` /* extract two bits from both, shift/update */` `146` `50.8k` ` nA = (bitbufA >> 6) & 0x03;` `147` `50.8k` ` nB = (bitbufB >> 6) & 0x03;` `148` `50.8k` ` bitbufA = (bitbufA << 2) & 0xFF;` `149` `50.8k` ` bitbufB = (bitbufB << 2) & 0xFF;` `150` `151` ` /* if both zero, if first, continue */` `152` `50.8k` ` if ((nA == 0) && (nB == 0) && (first == 1)) {` `153` `247` ` continue;` `154` `247` ` }` `155` `156` ` /* double twice, only if this isn't the first */` `157` `50.5k` ` if (first == 0) {` `158` ` /* double twice */` `159` `50.3k` ` if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }` `160` `50.3k` ` if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }` `161` `50.3k` ` }` `162` `163` ` /* if not both zero */` `164` `50.5k` ` if ((nA != 0) || (nB != 0)) {` `165` `45.4k` ` if (first == 1) {` `166` ` /* if first, copy from table */` `167` `273` ` first = 0;` `168` `273` ` if ((err = mp_copy(precomp[nA + (nB<<2)]->x, C->x)) != CRYPT_OK) { goto ERR_MU; }` `169` `273` ` if ((err = mp_copy(precomp[nA + (nB<<2)]->y, C->y)) != CRYPT_OK) { goto ERR_MU; }` `170` `273` ` if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; }` `171` `45.1k` ` } else {` `172` ` /* if not first, add from table */` `173` `45.1k` ` if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }` `174` `45.1k` ` }` `175` `45.4k` ` }` `176` `50.5k` ` }` `177` `178` ` /* reduce to affine */` `179` `273` ` err = ltc_ecc_map(C, modulus, mp);` `180` `181` ` /* clean up */` `182` `273` `ERR_MU:` `183` `273` ` mp_clear(mu);` `184` `273` `ERR_MP:` `185` `273` ` mp_montgomery_free(mp);` `186` `273` `ERR_P:` `187` `4.64k` ` for (x = 0; x < 16; x++) {` `188` `4.36k` ` ltc_ecc_del_point(precomp[x]);` `189` `4.36k` ` }` `190` `273` `ERR_T:` `191` `#ifdef LTC_CLEAN_STACK` `192` ` zeromem(tA, ECC_BUF_SIZE);` `193` ` zeromem(tB, ECC_BUF_SIZE);` `194` `#endif` `195` `273` ` XFREE(tA);` `196` `273` ` XFREE(tB);` `197` `198` `273` ` return err;` `199` `273` `}` `200` `201` `#endif` `202` `#endif` `203` `204` `/* ref: \$Format:%D\$ */` `205` `/* git commit: \$Format:%H\$ */` `206` `/* commit time: \$Format:%ai\$ */`