X25519 the ugly way
ActivePublic

Authored by werner on Oct 25 2018, 1:15 PM.
1
2static gpg_error_t
3compute_master_secret (unsigned char *master, size_t masterlen,
4const unsigned char *sk_a, size_t sk_a_len,
5const unsigned char *pk_b, size_t pk_b_len)
6{
7gpg_error_t err;
8gcry_sexp_t s_sk_a = NULL;
9gcry_sexp_t s_pk_b = NULL;
10gcry_sexp_t s_shared = NULL;
11gcry_sexp_t s_tmp;
12const char *s;
13size_t n;
14
15log_assert (masterlen == 32);
16
17err = gcry_sexp_build (&s_sk_a, NULL, "%b", (int)sk_a_len, sk_a);
18if (!err)
19err = gcry_sexp_build (&s_pk_b, NULL,
20"(public-key(ecdh(curve Curve25519)"
21" (flags djb-tweak)(q%b)))",
22(int)pk_b_len, pk_b);
23if (err)
24{
25log_error ("error building S-expression: %s\n", gpg_strerror (err));
26goto leave;
27}
28
29err = gcry_pk_encrypt (&s_shared, s_sk_a, s_pk_b);
30if (err)
31{
32log_error ("error computing DH: %s\n", gpg_strerror (err));
33goto leave;
34}
35/* gcry_log_debugsxp ("sk_a", s_sk_a); */
36/* gcry_log_debugsxp ("pk_b", s_pk_b); */
37/* gcry_log_debugsxp ("shared", s_shared); */
38
39s_tmp = gcry_sexp_find_token (s_shared, "s", 0);
40if (!s_tmp || !(s = gcry_sexp_nth_data (s_tmp, 1, &n))
41|| n != 33 || s[0] != 0x40)
42{
43err = gpg_error (GPG_ERR_INTERNAL);
44log_error ("error computing DH: %s\n", gpg_strerror (err));
45goto leave;
46}
47memcpy (master, s+1, 32);
48
49
50leave:
51gcry_sexp_release (s_sk_a);
52gcry_sexp_release (s_pk_b);
53gcry_sexp_release (s_shared);
54return err;
55}