bool_t ecIsPointAffine(const EcDomainParameters *params, const EcPoint *s) { error_t error; Mpi t1; Mpi t2; //Initialize multiple precision integers mpiInit(&t1); mpiInit(&t2); //Compute t1 = (Sx^3 + a * Sx + b) mod p EC_CHECK(ecSqrMod(params, &t1, &s->x)); EC_CHECK(ecMulMod(params, &t1, &t1, &s->x)); EC_CHECK(ecMulMod(params, &t2, ¶ms->a, &s->x)); EC_CHECK(ecAddMod(params, &t1, &t1, &t2)); EC_CHECK(ecAddMod(params, &t1, &t1, ¶ms->b)); //Compute t2 = Sy^2 EC_CHECK(ecSqrMod(params, &t2, &s->y)); //Check whether the point is on the elliptic curve if(mpiComp(&t1, &t2)) error = ERROR_FAILURE; end: //Release multiple precision integers mpiFree(&t1); mpiFree(&t2); //Return TRUE if the affine point S is on the curve, else FALSE return error ? FALSE : TRUE; }
error_t dhCheckPublicKey(DhParameters *params, const Mpi *publicKey) { error_t error; Mpi a; //Initialize multiple precision integer mpiInit(&a); //Precompute p - 1 error = mpiSubInt(&a, ¶ms->p, 1); //Check status if(!error) { //Reject weak public values 1 and p - 1 if(mpiCompInt(publicKey, 1) <= 0) error = ERROR_ILLEGAL_PARAMETER; else if(mpiComp(publicKey, &a) >= 0) error = ERROR_ILLEGAL_PARAMETER; } //Free previously allocated resources mpiFree(&a); //Return status code return error; }
error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m) { error_t error; Mpi m1; Mpi m2; Mpi h; //The ciphertext representative c shall be between 0 and n - 1 if(mpiCompInt(c, 0) < 0 || mpiComp(c, &key->n) >= 0) return ERROR_OUT_OF_RANGE; //Initialize multiple-precision integers mpiInit(&m1); mpiInit(&m2); mpiInit(&h); //Use the Chinese remainder algorithm? if(key->n.size && key->p.size && key->q.size && key->dp.size && key->dq.size && key->qinv.size) { //Compute m1 = c ^ dP mod p MPI_CHECK(mpiExpMod(&m1, c, &key->dp, &key->p)); //Compute m2 = c ^ dQ mod q MPI_CHECK(mpiExpMod(&m2, c, &key->dq, &key->q)); //Let h = (m1 - m2) * qInv mod p MPI_CHECK(mpiSub(&h, &m1, &m2)); MPI_CHECK(mpiMulMod(&h, &h, &key->qinv, &key->p)); //Let m = m2 + q * h MPI_CHECK(mpiMul(m, &key->q, &h)); MPI_CHECK(mpiAdd(m, m, &m2)); } //Use modular exponentiation? else if(key->n.size && key->d.size) { //Let m = c ^ d mod n error = mpiExpMod(m, c, &key->d, &key->n); } //Invalid parameters? else { //Report an error error = ERROR_INVALID_PARAMETER; } end: //Free previously allocated memory mpiFree(&m1); mpiFree(&m2); mpiFree(&h); //Return status code return error; }
error_t rsaep(const RsaPublicKey *key, const Mpi *m, Mpi *c) { //Ensure the RSA public key is valid if(!key->n.size || !key->e.size) return ERROR_INVALID_PARAMETER; //The message representative m shall be between 0 and n - 1 if(mpiCompInt(m, 0) < 0 || mpiComp(m, &key->n) >= 0) return ERROR_OUT_OF_RANGE; //Perform modular exponentiation (c = m ^ e mod n) return mpiExpMod(c, m, &key->e, &key->n); }
error_t dhGenerateKeyPair(DhContext *context, const PrngAlgo *prngAlgo, void *prngContext) { error_t error; uint_t k; //Debug message TRACE_DEBUG("Generating Diffie-Hellman key pair...\r\n"); //Get the length in bits of the prime p k = mpiGetBitLength(&context->params.p); //Ensure the length is valid if(!k) return ERROR_INVALID_PARAMETER; //The private value shall be randomly generated error = mpiRand(&context->xa, k, prngAlgo, prngContext); //Any error to report? if(error) return error; //The private value shall be less than p if(mpiComp(&context->xa, &context->params.p) >= 0) { //Shift value to the right error = mpiShiftRight(&context->xa, 1); //Any error to report? if(error) return error; } //Debug message TRACE_DEBUG(" Private value:\r\n"); TRACE_DEBUG_MPI(" ", &context->xa); //Calculate the corresponding public value (ya = g ^ xa mod p) error = mpiExpMod(&context->ya, &context->params.g, &context->xa, &context->params.p); //Any error to report? if(error) return error; //Debug message TRACE_DEBUG(" Public value:\r\n"); TRACE_DEBUG_MPI(" ", &context->ya); //Check public value error = dhCheckPublicKey(&context->params, &context->ya); //Weak public value? if(error) return error; //Public value successfully generated return NO_ERROR; }
error_t ecAddMod(const EcDomainParameters *params, Mpi *r, const Mpi *a, const Mpi *b) { error_t error; //Compute R = A + B MPI_CHECK(mpiAdd(r, a, b)); //Compute R = (A + B) mod p if(mpiComp(r, ¶ms->p) >= 0) { MPI_CHECK(mpiSub(r, r, ¶ms->p)); } end: //Return status code return error; }