2 * NaCl/Sodium-compatible API for Curve25519 cryptography.
4 * Copyright (c) 2018, Peter Wu <peter@lekensteyn.nl>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "curve25519.h"
17 copy_and_reverse(unsigned char *dest
, const unsigned char *src
, size_t n
)
19 for (size_t i
= 0; i
< n
; i
++) {
20 dest
[n
- 1 - i
] = src
[i
];
25 x25519_mpi(unsigned char *q
, const unsigned char *n
, gcry_mpi_t mpi_p
)
27 unsigned char priv_be
[32];
28 unsigned char result_be
[32];
29 size_t result_len
= 0;
30 gcry_mpi_t mpi
= NULL
;
31 gcry_ctx_t ctx
= NULL
;
32 gcry_mpi_point_t P
= NULL
;
33 gcry_mpi_point_t Q
= NULL
;
36 /* Default to infinity (all zeroes). */
39 /* Keys are in little-endian, but gcry_mpi_scan expects big endian. Convert
40 * keys and ensure that the result is a valid Curve25519 secret scalar. */
41 copy_and_reverse(priv_be
, n
, 32);
45 gcry_mpi_scan(&mpi
, GCRYMPI_FMT_USG
, priv_be
, 32, NULL
);
47 if (gcry_mpi_ec_new(&ctx
, NULL
, "Curve25519")) {
48 /* Should not happen, possibly out-of-memory. */
53 Q
= gcry_mpi_point_new(0);
54 P
= gcry_mpi_point_set(NULL
, mpi_p
, NULL
, GCRYMPI_CONST_ONE
);
55 gcry_mpi_ec_mul(Q
, mpi
, P
, ctx
);
57 /* Note: mpi is reused to store the result. */
58 if (gcry_mpi_ec_get_affine(mpi
, NULL
, Q
, ctx
)) {
63 if (gcry_mpi_print(GCRYMPI_FMT_USG
, result_be
, 32, &result_len
, mpi
)) {
64 /* Should not happen, possibly out-of-memory. */
67 copy_and_reverse(q
, result_be
, result_len
);
71 gcry_mpi_point_release(P
);
72 gcry_mpi_point_release(Q
);
73 gcry_ctx_release(ctx
);
74 gcry_mpi_release(mpi
);
75 /* XXX erase priv_be and result_be */
80 crypto_scalarmult_curve25519(unsigned char *q
, const unsigned char *n
,
81 const unsigned char *p
)
83 unsigned char p_be
[32];
84 gcry_mpi_t mpi_p
= NULL
;
86 copy_and_reverse(p_be
, p
, 32);
87 /* Clear unused bit. */
89 gcry_mpi_scan(&mpi_p
, GCRYMPI_FMT_USG
, p_be
, 32, NULL
);
90 int r
= x25519_mpi(q
, n
, mpi_p
);
91 gcry_mpi_release(mpi_p
);
96 crypto_scalarmult_curve25519_base(unsigned char *q
, const unsigned char *n
)
98 gcry_mpi_t mpi_basepoint_x
= gcry_mpi_set_ui(NULL
, 9);
99 int r
= x25519_mpi(q
, n
, mpi_basepoint_x
);
100 gcry_mpi_release(mpi_basepoint_x
);