int main(int argc, char *argv[]) { int ix; mp_int a, b, c, d; mp_digit r; mp_err res; if(argc < 3) { fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); return 1; } printf("Test 3: Multiplication and division\n\n"); srand(time(NULL)); mp_init(&a); mp_init(&b); mp_read_radix(&a, argv[1], 10); mp_read_radix(&b, argv[2], 10); printf("a = "); mp_print(&a, stdout); fputc('\n', stdout); printf("b = "); mp_print(&b, stdout); fputc('\n', stdout); mp_init(&c); printf("\nc = a * b\n"); mp_mul(&a, &b, &c); printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); printf("\nc = b * 32523\n"); mp_mul_d(&b, 32523, &c); printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); mp_init(&d); printf("\nc = a / b, d = a mod b\n"); mp_div(&a, &b, &c, &d); printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); printf("d = "); mp_print(&d, stdout); fputc('\n', stdout); ix = rand() % 256; printf("\nc = a / %d, r = a mod %d\n", ix, ix); mp_div_d(&a, (mp_digit)ix, &c, &r); printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); printf("r = %04X\n", r); #if EXPT printf("\nc = a ** b\n"); mp_expt(&a, &b, &c); printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); #endif ix = rand() % 256; printf("\nc = 2^%d\n", ix); mp_2expt(&c, ix); printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); #if SQRT printf("\nc = sqrt(a)\n"); if((res = mp_sqrt(&a, &c)) != MP_OKAY) { printf("mp_sqrt: %s\n", mp_strerror(res)); } else { printf("c = "); mp_print(&c, stdout); fputc('\n', stdout); mp_sqr(&c, &c); printf("c^2 = "); mp_print(&c, stdout); fputc('\n', stdout); } #endif mp_clear(&d); mp_clear(&c); mp_clear(&b); mp_clear(&a); return 0; }
int main(int argc, char *argv[]) { mp_int a, m, p, k; if(argc < 3) { fprintf(stderr, "Usage: %s <a> <m>\n", argv[0]); return 1; } mp_init(&a); mp_init(&m); mp_init(&p); mp_add_d(&p, 1, &p); mp_read_radix(&a, argv[1], 10); mp_read_radix(&m, argv[2], 10); mp_init_copy(&k, &a); signal(SIGINT, sig_catch); #ifndef __OS2__ signal(SIGHUP, sig_catch); #endif signal(SIGTERM, sig_catch); while(mp_cmp(&p, &m) < 0) { if(g_quit) { int len; char *buf; len = mp_radix_size(&p, 10); buf = malloc(len); mp_toradix(&p, buf, 10); fprintf(stderr, "Terminated at: %s\n", buf); free(buf); return 1; } if(mp_cmp_d(&k, 1) == 0) { int len; char *buf; len = mp_radix_size(&p, 10); buf = malloc(len); mp_toradix(&p, buf, 10); printf("%s\n", buf); free(buf); break; } mp_mulmod(&k, &a, &m, &k); mp_add_d(&p, 1, &p); } if(mp_cmp(&p, &m) >= 0) printf("No annihilating power.\n"); mp_clear(&p); mp_clear(&m); mp_clear(&a); return 0; }
/* Construct ECGroup from hex parameters and name, if any. Called by * ECGroup_fromHex and ECGroup_fromName. */ ECGroup * ecgroup_fromNameAndHex(const ECCurveName name, const ECCurveParams * params) { mp_int irr, curvea, curveb, genx, geny, order; int bits; ECGroup *group = NULL; mp_err res = MP_OKAY; /* initialize values */ MP_DIGITS(&irr) = 0; MP_DIGITS(&curvea) = 0; MP_DIGITS(&curveb) = 0; MP_DIGITS(&genx) = 0; MP_DIGITS(&geny) = 0; MP_DIGITS(&order) = 0; MP_CHECKOK(mp_init(&irr)); MP_CHECKOK(mp_init(&curvea)); MP_CHECKOK(mp_init(&curveb)); MP_CHECKOK(mp_init(&genx)); MP_CHECKOK(mp_init(&geny)); MP_CHECKOK(mp_init(&order)); MP_CHECKOK(mp_read_radix(&irr, params->irr, 16)); MP_CHECKOK(mp_read_radix(&curvea, params->curvea, 16)); MP_CHECKOK(mp_read_radix(&curveb, params->curveb, 16)); MP_CHECKOK(mp_read_radix(&genx, params->genx, 16)); MP_CHECKOK(mp_read_radix(&geny, params->geny, 16)); MP_CHECKOK(mp_read_radix(&order, params->order, 16)); /* determine number of bits */ bits = mpl_significant_bits(&irr) - 1; if (bits < MP_OKAY) { res = bits; goto CLEANUP; } /* determine which optimizations (if any) to use */ if (params->field == ECField_GFp) { #ifdef NSS_ECC_MORE_THAN_SUITE_B switch (name) { #ifdef ECL_USE_FP case ECCurve_SECG_PRIME_160R1: group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } MP_CHECKOK(ec_group_set_secp160r1_fp(group)); break; #endif case ECCurve_SECG_PRIME_192R1: #ifdef ECL_USE_FP group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } MP_CHECKOK(ec_group_set_nistp192_fp(group)); #else group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } MP_CHECKOK(ec_group_set_gfp192(group, name)); #endif break; case ECCurve_SECG_PRIME_224R1: #ifdef ECL_USE_FP group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } MP_CHECKOK(ec_group_set_nistp224_fp(group)); #else group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } MP_CHECKOK(ec_group_set_gfp224(group, name)); #endif break; case ECCurve_SECG_PRIME_256R1: group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } MP_CHECKOK(ec_group_set_gfp256(group, name)); break; case ECCurve_SECG_PRIME_521R1: group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } MP_CHECKOK(ec_group_set_gfp521(group, name)); break; default: /* use generic arithmetic */ #endif group = ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } #ifdef NSS_ECC_MORE_THAN_SUITE_B } } else if (params->field == ECField_GF2m) { group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, &geny, &order, params->cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } if ((name == ECCurve_NIST_K163) || (name == ECCurve_NIST_B163) || (name == ECCurve_SECG_CHAR2_163R1)) { MP_CHECKOK(ec_group_set_gf2m163(group, name)); } else if ((name == ECCurve_SECG_CHAR2_193R1) || (name == ECCurve_SECG_CHAR2_193R2)) { MP_CHECKOK(ec_group_set_gf2m193(group, name)); } else if ((name == ECCurve_NIST_K233) || (name == ECCurve_NIST_B233)) { MP_CHECKOK(ec_group_set_gf2m233(group, name)); } #endif } else { res = MP_UNDEF; goto CLEANUP; } /* set name, if any */ if ((group != NULL) && (params->text != NULL)) { group->text = strdup(params->text); if (group->text == NULL) { res = MP_MEM; } } CLEANUP: mp_clear(&irr); mp_clear(&curvea); mp_clear(&curveb); mp_clear(&genx); mp_clear(&geny); mp_clear(&order); if (res != MP_OKAY) { ECGroup_free(group); return NULL; } return group; }
/** Sign a message digest @param in The message digest to sign @param inlen The length of the digest @param out [out] The destination for the signature @param outlen [in/out] The max size and resulting size of the signature @param prng An active PRNG state @param wprng The index of the PRNG you wish to use @param key A private ECC key @return CRYPT_OK if successful */ int ecc_sign_hash(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, ecc_key *key) { ecc_key pubkey; void *r, *s, *e, *p; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* is this a private key? */ if (key->type != PK_PRIVATE) { return CRYPT_PK_NOT_PRIVATE; } /* is the IDX valid ? */ if (ltc_ecc_is_valid_idx(key->idx) != 1) { return CRYPT_PK_INVALID_TYPE; } if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } /* get the hash and load it as a bignum into 'e' */ /* init the bignums */ if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) { return err; } if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errnokey; } if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto errnokey; } /* make up a key and export the public copy */ for (;;) { if ((err = ecc_make_key_ex(prng, wprng, &pubkey, key->dp)) != CRYPT_OK) { goto errnokey; } /* find r = x1 mod n */ if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK) { goto error; } if (mp_iszero(r) == LTC_MP_YES) { ecc_free(&pubkey); } else { /* find s = (e + xr)/k */ if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; /* k = 1/k */ } if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK) { goto error; /* s = xr */ } if ((err = mp_add(e, s, s)) != CRYPT_OK) { goto error; /* s = e + xr */ } if ((err = mp_mod(s, p, s)) != CRYPT_OK) { goto error; /* s = e + xr */ } if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK) { goto error; /* s = (e + xr)/k */ } ecc_free(&pubkey); if (mp_iszero(s) == LTC_MP_NO) { break; } } } /* store as SEQUENCE { r, s -- integer } */ err = der_encode_sequence_multi(out, outlen, LTC_ASN1_INTEGER, 1UL, r, LTC_ASN1_INTEGER, 1UL, s, LTC_ASN1_EOL, 0UL, NULL); goto errnokey; error: ecc_free(&pubkey); errnokey: mp_clear_multi(r, s, p, e, NULL); return err; }