static int test_add (void) { gcry_mpi_t one; gcry_mpi_t two; gcry_mpi_t ff; gcry_mpi_t result; unsigned char* pc; gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL); gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL); gcry_mpi_scan(&ff, GCRYMPI_FMT_USG, manyff, sizeof(manyff), NULL); result = gcry_mpi_new(0); gcry_mpi_add(result, one, two); gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); if (verbose) printf("Result of one plus two:\n%s\n", pc); gcry_free(pc); gcry_mpi_add(result, ff, one); gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); if (verbose) printf("Result of ff plus one:\n%s\n", pc); gcry_free(pc); gcry_mpi_release(one); gcry_mpi_release(two); gcry_mpi_release(ff); gcry_mpi_release(result); return 1; }
/* compute 2^m (mod phi(p)), for a prime p */ static gcry_mpi_t twopowmodphi(uint64_t m, const gcry_mpi_t p) { gcry_mpi_t phi, r; int n; phi = gcry_mpi_new(0); gcry_mpi_sub_ui(phi, p, 1); /* count number of used bits in m */ for (n = 0; ((uint64_t)1 << n) <= m; n++) ; r = gcry_mpi_new(0); gcry_mpi_set_ui(r, 1); while (n) { /* square and multiply algorithm for fast exponentiation */ n--; gcry_mpi_mulm(r, r, r, phi); if (m & ((uint64_t)1 << n)) { gcry_mpi_add(r, r, r); if (gcry_mpi_cmp(r, phi) >= 0) gcry_mpi_sub(r, r, phi); } } gcry_mpi_release(phi); return r; }
void gcry_mpi_sub(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) { gcry_mpi_t vv = mpi_copy (v); vv->sign = ! vv->sign; gcry_mpi_add (w, u, vv); mpi_free (vv); }
unsigned char* add(unsigned char* x, unsigned char* y){ size_t scanned; unsigned char *result; gcry_mpi_t a = gcry_mpi_new(0); gcry_mpi_t b = gcry_mpi_new(0); gcry_mpi_scan(&a, GCRYMPI_FMT_HEX, x, 0, &scanned); gcry_mpi_scan(&b, GCRYMPI_FMT_HEX, y, 0, &scanned); gcry_mpi_add(a, a, b); gcry_mpi_aprint(GCRYMPI_FMT_HEX, &result, NULL, a); return result; }
static bigint_t wrap_gcry_mpi_add (bigint_t w, const bigint_t a, const bigint_t b) { if (w == NULL) w = _gnutls_mpi_alloc_like (b); if (w == NULL) return NULL; gcry_mpi_add (w, a, b); return w; }
/* Compose $(xp,xq) \in Z_p \times Z_q$ into $x \in Z_n$ using Chinese Remainder Theorem */ static void CRT_compose(gcry_mpi_t *x, const gcry_mpi_t xp, const gcry_mpi_t xq, const gcry_mpi_t p, const gcry_mpi_t q) { gcry_mpi_t a, u; a = gcry_mpi_new(0); u = gcry_mpi_new(0); *x = gcry_mpi_new(0); gcry_mpi_subm(a, xq, xp, q); gcry_mpi_invm(u, p, q); gcry_mpi_mulm(a, a, u, q); /* a = (xq - xp) / p (mod q) */ gcry_mpi_mul(*x, p, a); gcry_mpi_add(*x, *x, xp); /* x = p * ((xq - xp) / p mod q) + xp */ gcry_mpi_release(a); gcry_mpi_release(u); }
void compress_to_string(char *buf, enum disp_format df, const struct affine_point *P, const struct curve_params *cp) { int outlen = (df == DF_COMPACT) ? cp->pk_len_compact : cp->pk_len_bin; if (point_compress(P)) { gcry_mpi_t x; x = gcry_mpi_snew(0); gcry_mpi_add(x, P->x, cp->dp.m); serialize_mpi(buf, outlen, df, x); gcry_mpi_release(x); } else serialize_mpi(buf, outlen, df, P->x); }
/* Algorithms 4.29 and 4.30 in the "Guide to Elliptic Curve Cryptography" */ gcry_mpi_t ECDSA_sign(const char *msg, const gcry_mpi_t d, const struct curve_params *cp) { struct affine_point p1; gcry_mpi_t e, k, r, s; #if ECDSA_DETERMINISTIC struct aes256cprng *cprng; cprng = ecdsa_cprng_init(msg, d, cp); #endif r = gcry_mpi_snew(0); s = gcry_mpi_snew(0); Step1: #if ECDSA_DETERMINISTIC k = ecdsa_cprng_get_exponent(cprng, cp); #else k = get_random_exponent(cp); #endif p1 = pointmul(&cp->dp.base, k, &cp->dp); gcry_mpi_mod(r, p1.x, cp->dp.order); point_release(&p1); if (! gcry_mpi_cmp_ui(r, 0)) { gcry_mpi_release(k); goto Step1; } gcry_mpi_scan(&e, GCRYMPI_FMT_USG, msg, 64, NULL); gcry_mpi_set_flag(e, GCRYMPI_FLAG_SECURE); gcry_mpi_mod(e, e, cp->dp.order); gcry_mpi_mulm(s, d, r, cp->dp.order); gcry_mpi_addm(s, s, e, cp->dp.order); gcry_mpi_invm(e, k, cp->dp.order); gcry_mpi_mulm(s, s, e, cp->dp.order); gcry_mpi_release(e); gcry_mpi_release(k); if (! gcry_mpi_cmp_ui(s, 0)) goto Step1; gcry_mpi_mul(s, s, cp->dp.order); gcry_mpi_add(s, s, r); gcry_mpi_release(r); #if ECDSA_DETERMINISTIC ecdsa_cprng_done(cprng); #endif return s; }
void _gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor ) { int divisor_sign = divisor->sign; gcry_mpi_t temp_divisor = NULL; if( quot == divisor || rem == divisor ) { temp_divisor = mpi_copy( divisor ); divisor = temp_divisor; } _gcry_mpi_tdiv_qr( quot, rem, dividend, divisor ); if( (divisor_sign ^ dividend->sign) && rem->nlimbs ) { gcry_mpi_sub_ui( quot, quot, 1 ); gcry_mpi_add( rem, rem, divisor); } if( temp_divisor ) mpi_free(temp_divisor); }
void _gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor ) { int divisor_sign = divisor->sign; gcry_mpi_t temp_divisor = NULL; /* We need the original value of the divisor after the remainder has been * preliminary calculated. We have to copy it to temporary space if it's * the same variable as REM. */ if( rem == divisor ) { temp_divisor = mpi_copy( divisor ); divisor = temp_divisor; } _gcry_mpi_tdiv_r( rem, dividend, divisor ); if( ((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs ) gcry_mpi_add( rem, rem, divisor); if( temp_divisor ) mpi_free(temp_divisor); }
static int generate_key_or_iv(unsigned int id, tvbuff_t *salt_tvb, unsigned int iter, const char *pw, unsigned int req_keylen, char * keybuf) { int rc; unsigned int i, j; gcry_md_hd_t md; gcry_mpi_t num_b1 = NULL; size_t pwlen; char hash[20], buf_b[64], buf_i[128], *p; char *salt_p; int salt_size; size_t cur_keylen; size_t n; gcry_error_t err; cur_keylen = 0; salt_size = tvb_captured_length(salt_tvb); salt_p = (char *)tvb_memdup(wmem_packet_scope(), salt_tvb, 0, salt_size); if (pw == NULL) pwlen = 0; else pwlen = strlen(pw); if (pwlen > 63 / 2) { return FALSE; } /* Store salt and password in BUF_I */ p = buf_i; for (i = 0; i < 64; i++) *p++ = salt_p[i % salt_size]; if (pw) { for (i = j = 0; i < 64; i += 2) { *p++ = 0; *p++ = pw[j]; if (++j > pwlen) /* Note, that we include the trailing zero */ j = 0; } } else memset (p, 0, 64); for (;;) { err = gcry_md_open(&md, GCRY_MD_SHA1, 0); if (gcry_err_code(err)) { return FALSE; } for (i = 0; i < 64; i++) { unsigned char lid = id & 0xFF; gcry_md_write (md, &lid, 1); } gcry_md_write(md, buf_i, pw ? 128 : 64); gcry_md_final (md); memcpy (hash, gcry_md_read (md, 0), 20); gcry_md_close (md); for (i = 1; i < iter; i++) gcry_md_hash_buffer (GCRY_MD_SHA1, hash, hash, 20); for (i = 0; i < 20 && cur_keylen < req_keylen; i++) keybuf[cur_keylen++] = hash[i]; if (cur_keylen == req_keylen) { gcry_mpi_release (num_b1); return TRUE; /* ready */ } /* need more bytes. */ for (i = 0; i < 64; i++) buf_b[i] = hash[i % 20]; n = 64; rc = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, n, &n); if (rc != 0) { return FALSE; } gcry_mpi_add_ui (num_b1, num_b1, 1); for (i = 0; i < 128; i += 64) { gcry_mpi_t num_ij; n = 64; rc = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, n, &n); if (rc != 0) { return FALSE; } gcry_mpi_add (num_ij, num_ij, num_b1); gcry_mpi_clear_highbit (num_ij, 64 * 8); n = 64; rc = gcry_mpi_print (GCRYMPI_FMT_USG, buf_i + i, n, &n, num_ij); if (rc != 0) { return FALSE; } gcry_mpi_release (num_ij); } } }
void gcry_mpi_addm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) { gcry_mpi_add(w, u, v); _gcry_mpi_fdiv_r( w, w, m ); }