-
Notifications
You must be signed in to change notification settings - Fork 968
/
ECDH.cpp
75 lines (67 loc) · 2.03 KB
/
ECDH.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Copyright 2015 Stellar Development Foundation and contributors. Licensed
// under the Apache License, Version 2.0. See the COPYING file at the root
// of this distribution or at http://www.apache.org/licenses/LICENSE-2.0
#include "crypto/ECDH.h"
#include "crypto/SHA.h"
#include "util/HashOfHash.h"
#include <functional>
#include <sodium.h>
#ifdef MSAN_ENABLED
#include <sanitizer/msan_interface.h>
#endif
namespace stellar
{
Curve25519Secret
EcdhRandomSecret()
{
Curve25519Secret out;
randombytes_buf(out.key.data(), out.key.size());
#ifdef MSAN_ENABLED
__msan_unpoison(out.key.data(), out.key.size());
#endif
return out;
}
Curve25519Public
EcdhDerivePublic(Curve25519Secret const& sec)
{
Curve25519Public out;
if (crypto_scalarmult_base(out.key.data(), sec.key.data()) != 0)
{
throw std::runtime_error("Could not derive key (mult_base)");
}
return out;
}
HmacSha256Key
EcdhDeriveSharedKey(Curve25519Secret const& localSecret,
Curve25519Public const& localPublic,
Curve25519Public const& remotePublic, bool localFirst)
{
auto const& publicA = localFirst ? localPublic : remotePublic;
auto const& publicB = localFirst ? remotePublic : localPublic;
unsigned char q[crypto_scalarmult_BYTES];
if (crypto_scalarmult(q, localSecret.key.data(), remotePublic.key.data()) !=
0)
{
throw std::runtime_error("Could not derive shared key (mult)");
}
#ifdef MSAN_ENABLED
__msan_unpoison(q, crypto_scalarmult_BYTES);
#endif
std::vector<uint8_t> buf;
buf.reserve(crypto_scalarmult_BYTES + publicA.key.size() +
publicB.key.size());
buf.insert(buf.end(), q, q + crypto_scalarmult_BYTES);
buf.insert(buf.end(), publicA.key.begin(), publicA.key.end());
buf.insert(buf.end(), publicB.key.begin(), publicB.key.end());
return hkdfExtract(buf);
}
}
namespace std
{
size_t
hash<stellar::Curve25519Public>::
operator()(stellar::Curve25519Public const& k) const noexcept
{
return std::hash<stellar::uint256>()(k.key);
}
}