Path: blob/master/libs/tomcrypt/src/pk/ecc/ltc_ecc_mul2add.c
4396 views
/* LibTomCrypt, modular cryptographic library -- Tom St Denis1*2* LibTomCrypt is a library that provides various cryptographic3* algorithms in a highly modular and flexible manner.4*5* The library is free for all purposes without any express6* guarantee it works.7*/89/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b10*11* All curves taken from NIST recommendation paper of July 199912* Available at http://csrc.nist.gov/cryptval/dss.htm13*/14#include "tomcrypt.h"1516/**17@file ltc_ecc_mul2add.c18ECC Crypto, Shamir's Trick, Tom St Denis19*/2021#ifdef LTC_MECC2223#ifdef LTC_ECC_SHAMIR2425/** Computes kA*A + kB*B = C using Shamir's Trick26@param A First point to multiply27@param kA What to multiple A by28@param B Second point to multiply29@param kB What to multiple B by30@param C [out] Destination point (can overlap with A or B31@param modulus Modulus for curve32@return CRYPT_OK on success33*/34int ltc_ecc_mul2add(ecc_point *A, void *kA,35ecc_point *B, void *kB,36ecc_point *C,37void *modulus)38{39ecc_point *precomp[16];40unsigned bitbufA, bitbufB, lenA, lenB, len, x, y, nA, nB, nibble;41unsigned char *tA, *tB;42int err, first;43void *mp, *mu;4445/* argchks */46LTC_ARGCHK(A != NULL);47LTC_ARGCHK(B != NULL);48LTC_ARGCHK(C != NULL);49LTC_ARGCHK(kA != NULL);50LTC_ARGCHK(kB != NULL);51LTC_ARGCHK(modulus != NULL);5253/* allocate memory */54tA = XCALLOC(1, ECC_BUF_SIZE);55if (tA == NULL) {56return CRYPT_MEM;57}58tB = XCALLOC(1, ECC_BUF_SIZE);59if (tB == NULL) {60XFREE(tA);61return CRYPT_MEM;62}6364/* get sizes */65lenA = mp_unsigned_bin_size(kA);66lenB = mp_unsigned_bin_size(kB);67len = MAX(lenA, lenB);6869/* sanity check */70if ((lenA > ECC_BUF_SIZE) || (lenB > ECC_BUF_SIZE)) {71err = CRYPT_INVALID_ARG;72goto ERR_T;73}7475/* extract and justify kA */76mp_to_unsigned_bin(kA, (len - lenA) + tA);7778/* extract and justify kB */79mp_to_unsigned_bin(kB, (len - lenB) + tB);8081/* allocate the table */82for (x = 0; x < 16; x++) {83precomp[x] = ltc_ecc_new_point();84if (precomp[x] == NULL) {85for (y = 0; y < x; ++y) {86ltc_ecc_del_point(precomp[y]);87}88err = CRYPT_MEM;89goto ERR_T;90}91}9293/* init montgomery reduction */94if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {95goto ERR_P;96}97if ((err = mp_init(&mu)) != CRYPT_OK) {98goto ERR_MP;99}100if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {101goto ERR_MU;102}103104/* copy ones ... */105if ((err = mp_mulmod(A->x, mu, modulus, precomp[1]->x)) != CRYPT_OK) { goto ERR_MU; }106if ((err = mp_mulmod(A->y, mu, modulus, precomp[1]->y)) != CRYPT_OK) { goto ERR_MU; }107if ((err = mp_mulmod(A->z, mu, modulus, precomp[1]->z)) != CRYPT_OK) { goto ERR_MU; }108109if ((err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x)) != CRYPT_OK) { goto ERR_MU; }110if ((err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y)) != CRYPT_OK) { goto ERR_MU; }111if ((err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z)) != CRYPT_OK) { goto ERR_MU; }112113/* precomp [i,0](A + B) table */114if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }115if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }116117/* precomp [0,i](A + B) table */118if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }119if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }120121/* precomp [i,j](A + B) table (i != 0, j != 0) */122for (x = 1; x < 4; x++) {123for (y = 1; y < 4; y++) {124if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }125}126}127128nibble = 3;129first = 1;130bitbufA = tA[0];131bitbufB = tB[0];132133/* for every byte of the multiplicands */134for (x = 0;; ) {135/* grab a nibble */136if (++nibble == 4) {137if (x == len) break;138bitbufA = tA[x];139bitbufB = tB[x];140nibble = 0;141++x;142}143144/* extract two bits from both, shift/update */145nA = (bitbufA >> 6) & 0x03;146nB = (bitbufB >> 6) & 0x03;147bitbufA = (bitbufA << 2) & 0xFF;148bitbufB = (bitbufB << 2) & 0xFF;149150/* if both zero, if first, continue */151if ((nA == 0) && (nB == 0) && (first == 1)) {152continue;153}154155/* double twice, only if this isn't the first */156if (first == 0) {157/* double twice */158if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }159if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }160}161162/* if not both zero */163if ((nA != 0) || (nB != 0)) {164if (first == 1) {165/* if first, copy from table */166first = 0;167if ((err = mp_copy(precomp[nA + (nB<<2)]->x, C->x)) != CRYPT_OK) { goto ERR_MU; }168if ((err = mp_copy(precomp[nA + (nB<<2)]->y, C->y)) != CRYPT_OK) { goto ERR_MU; }169if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; }170} else {171/* if not first, add from table */172if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }173}174}175}176177/* reduce to affine */178err = ltc_ecc_map(C, modulus, mp);179180/* clean up */181ERR_MU:182mp_clear(mu);183ERR_MP:184mp_montgomery_free(mp);185ERR_P:186for (x = 0; x < 16; x++) {187ltc_ecc_del_point(precomp[x]);188}189ERR_T:190#ifdef LTC_CLEAN_STACK191zeromem(tA, ECC_BUF_SIZE);192zeromem(tB, ECC_BUF_SIZE);193#endif194XFREE(tA);195XFREE(tB);196197return err;198}199200#endif201#endif202203204