/* S = (B - k*g^x) ^ (a + u * x) % N * this is our shared key (client premaster secret) */ bigint_t _gnutls_calc_srp_S2 (bigint_t B, bigint_t g, bigint_t x, bigint_t a, bigint_t u, bigint_t n) { bigint_t S = NULL, tmp1 = NULL, tmp2 = NULL; bigint_t tmp4 = NULL, tmp3 = NULL, k = NULL; S = _gnutls_mpi_alloc_like (n); if (S == NULL) return NULL; tmp1 = _gnutls_mpi_alloc_like (n); tmp2 = _gnutls_mpi_alloc_like (n); tmp3 = _gnutls_mpi_alloc_like (n); if (tmp1 == NULL || tmp2 == NULL || tmp3 == NULL) { goto freeall; } k = _gnutls_calc_srp_u (n, g, n); if (k == NULL) { gnutls_assert (); goto freeall; } _gnutls_mpi_powm (tmp1, g, x, n); /* g^x */ _gnutls_mpi_mulm (tmp3, tmp1, k, n); /* k*g^x mod n */ _gnutls_mpi_subm (tmp2, B, tmp3, n); tmp4 = _gnutls_mpi_alloc_like (n); if (tmp4 == NULL) goto freeall; _gnutls_mpi_mul (tmp1, u, x); _gnutls_mpi_add (tmp4, a, tmp1); _gnutls_mpi_powm (S, tmp2, tmp4, n); _gnutls_mpi_release (&tmp1); _gnutls_mpi_release (&tmp2); _gnutls_mpi_release (&tmp3); _gnutls_mpi_release (&tmp4); _gnutls_mpi_release (&k); return S; freeall: _gnutls_mpi_release (&k); _gnutls_mpi_release (&tmp1); _gnutls_mpi_release (&tmp2); _gnutls_mpi_release (&tmp3); _gnutls_mpi_release (&tmp4); _gnutls_mpi_release (&S); return NULL; }
/* S = (B - k*g^x) ^ (a + u * x) % N * this is our shared key (client premaster secret) */ bigint_t _gnutls_calc_srp_S2(bigint_t B, bigint_t g, bigint_t x, bigint_t a, bigint_t u, bigint_t n) { bigint_t S = NULL, tmp1 = NULL, tmp2 = NULL; bigint_t tmp4 = NULL, tmp3 = NULL, k = NULL; int ret; ret = _gnutls_mpi_init_multi(&S, &tmp1, &tmp2, &tmp3, &tmp4, NULL); if (ret < 0) return NULL; k = _gnutls_calc_srp_u(n, g, n); if (k == NULL) { gnutls_assert(); goto freeall; } ret = _gnutls_mpi_powm(tmp1, g, x, n); /* g^x */ if (ret < 0) { gnutls_assert(); goto freeall; } ret = _gnutls_mpi_mulm(tmp3, tmp1, k, n); /* k*g^x mod n */ if (ret < 0) { gnutls_assert(); goto freeall; } ret = _gnutls_mpi_subm(tmp2, B, tmp3, n); if (ret < 0) { gnutls_assert(); goto freeall; } ret = _gnutls_mpi_mul(tmp1, u, x); if (ret < 0) { gnutls_assert(); goto freeall; } ret = _gnutls_mpi_add(tmp4, a, tmp1); if (ret < 0) { gnutls_assert(); goto freeall; } ret = _gnutls_mpi_powm(S, tmp2, tmp4, n); if (ret < 0) { gnutls_assert(); goto freeall; } _gnutls_mpi_release(&tmp1); _gnutls_mpi_release(&tmp2); _gnutls_mpi_release(&tmp3); _gnutls_mpi_release(&tmp4); _gnutls_mpi_release(&k); return S; freeall: _gnutls_mpi_release(&k); _gnutls_mpi_release(&tmp1); _gnutls_mpi_release(&tmp2); _gnutls_mpi_release(&tmp3); _gnutls_mpi_release(&tmp4); _gnutls_mpi_release(&S); return NULL; }