line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#ifndef CURVE25519_I64_H |
2
|
|
|
|
|
|
|
#define CURVE25519_I64_H 1 |
3
|
|
|
|
|
|
|
/* |
4
|
|
|
|
|
|
|
Modified by mko. |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
*/ |
7
|
|
|
|
|
|
|
/* Generic 64-bit integer implementation of Curve25519 ECDH |
8
|
|
|
|
|
|
|
* Written by Matthijs van Duin, 200608242056 |
9
|
|
|
|
|
|
|
* Public domain. |
10
|
|
|
|
|
|
|
* |
11
|
|
|
|
|
|
|
* Based on work by Daniel J Bernstein, http://cr.yp.to/ecdh.html |
12
|
|
|
|
|
|
|
*/ |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
#include |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
typedef unsigned char k25519[32]; /* any type of key */ |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
extern const k25519 zero25519; /* 0 */ |
19
|
|
|
|
|
|
|
extern const k25519 prime25519; /* the prime 2^255-19 */ |
20
|
|
|
|
|
|
|
extern const k25519 order25519; /* group order (a prime near 2^252+2^124) */ |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
typedef k25519 pub25519; /* public key */ |
24
|
|
|
|
|
|
|
typedef k25519 priv25519; /* private key (for key agreement) */ |
25
|
|
|
|
|
|
|
typedef k25519 spriv25519; /* private key for signing */ |
26
|
|
|
|
|
|
|
typedef k25519 sec25519; /* shared secret */ |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
/********* KEY AGREEMENT *********/ |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
/* internal function - do not use directly */ |
33
|
|
|
|
|
|
|
void core25519(k25519 P, spriv25519 s, const priv25519 k, const k25519 G); |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
/* Private key clamping |
37
|
|
|
|
|
|
|
* k [out] your private key for key agreement |
38
|
|
|
|
|
|
|
* k [in] 32 random bytes |
39
|
|
|
|
|
|
|
*/ |
40
|
|
|
|
|
|
|
static inline |
41
|
6
|
|
|
|
|
|
void clamp25519(priv25519 k) { |
42
|
6
|
|
|
|
|
|
k[31] &= 0x7F; |
43
|
6
|
|
|
|
|
|
k[31] |= 0x40; |
44
|
6
|
|
|
|
|
|
k[ 0] &= 0xF8; |
45
|
6
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
/* Key-pair generation |
50
|
|
|
|
|
|
|
* P [out] your public key |
51
|
|
|
|
|
|
|
* s [out] your private key for signing |
52
|
|
|
|
|
|
|
* k [out] your private key for key agreement |
53
|
|
|
|
|
|
|
* k [in] 32 random bytes |
54
|
|
|
|
|
|
|
* s may be NULL if you don't care |
55
|
|
|
|
|
|
|
* |
56
|
|
|
|
|
|
|
* WARNING: if s is not NULL, this function has data-dependent timing */ |
57
|
|
|
|
|
|
|
static inline |
58
|
|
|
|
|
|
|
void keygen25519(pub25519 P, spriv25519 s, priv25519 k) { |
59
|
|
|
|
|
|
|
clamp25519(k); |
60
|
|
|
|
|
|
|
core25519(P, s, k, NULL); |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
/* Key agreement |
66
|
|
|
|
|
|
|
* Z [out] shared secret (needs hashing before use) |
67
|
|
|
|
|
|
|
* k [in] your private key for key agreement |
68
|
|
|
|
|
|
|
* P [in] peer's public key |
69
|
|
|
|
|
|
|
* Buffers may overlap. */ |
70
|
|
|
|
|
|
|
static inline |
71
|
|
|
|
|
|
|
void curve25519(sec25519 Z, const priv25519 k, const pub25519 P) { |
72
|
|
|
|
|
|
|
core25519(Z, NULL, k, P); |
73
|
|
|
|
|
|
|
} |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
/********* DIGITAL SIGNATURES *********/ |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
/* deterministic EC-KCDSA |
79
|
|
|
|
|
|
|
* |
80
|
|
|
|
|
|
|
* s is the private key for signing |
81
|
|
|
|
|
|
|
* P is the corresponding public key |
82
|
|
|
|
|
|
|
* Z is the context data (signer public key or certificate, etc) |
83
|
|
|
|
|
|
|
* |
84
|
|
|
|
|
|
|
* signing: |
85
|
|
|
|
|
|
|
* |
86
|
|
|
|
|
|
|
* m = hash(Z, message) |
87
|
|
|
|
|
|
|
* x = hash(m, s) |
88
|
|
|
|
|
|
|
* keygen25519(Y, NULL, x); |
89
|
|
|
|
|
|
|
* r = hash(Y); |
90
|
|
|
|
|
|
|
* h = m XOR r |
91
|
|
|
|
|
|
|
* sign25519(v, h, x, s); |
92
|
|
|
|
|
|
|
* |
93
|
|
|
|
|
|
|
* output (v,r) as the signature |
94
|
|
|
|
|
|
|
* |
95
|
|
|
|
|
|
|
* verification: |
96
|
|
|
|
|
|
|
* |
97
|
|
|
|
|
|
|
* m = hash(Z, message); |
98
|
|
|
|
|
|
|
* h = m XOR r |
99
|
|
|
|
|
|
|
* verify25519(Y, v, h, P) |
100
|
|
|
|
|
|
|
* |
101
|
|
|
|
|
|
|
* confirm r == hash(Y) |
102
|
|
|
|
|
|
|
* |
103
|
|
|
|
|
|
|
* It would seem to me that it would be simpler to have the signer directly do |
104
|
|
|
|
|
|
|
* h = hash(m, Y) and send that to the recipient instead of r, who can verify |
105
|
|
|
|
|
|
|
* the signature by checking h == hash(m, Y). If there are any problems with |
106
|
|
|
|
|
|
|
* such a scheme, please let me know. |
107
|
|
|
|
|
|
|
* |
108
|
|
|
|
|
|
|
* Also, EC-KCDSA (like most DS algorithms) picks x random, which is a waste of |
109
|
|
|
|
|
|
|
* perfectly good entropy, but does allow Y to be calculated in advance of (or |
110
|
|
|
|
|
|
|
* parallel to) hashing the message. |
111
|
|
|
|
|
|
|
*/ |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
/* Signature generation primitive, calculates (x-h)s mod q |
115
|
|
|
|
|
|
|
* v [out] signature value |
116
|
|
|
|
|
|
|
* h [in] signature hash (of message, signature pub key, and context data) |
117
|
|
|
|
|
|
|
* x [in] signature private key |
118
|
|
|
|
|
|
|
* s [in] private key for signing |
119
|
|
|
|
|
|
|
* returns true on success, false on failure (use different x or h) |
120
|
|
|
|
|
|
|
*/ |
121
|
|
|
|
|
|
|
int sign25519(k25519 v, const k25519 h, const priv25519 x, const spriv25519 s); |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
/* Signature verification primitive, calculates Y = vP + hG |
125
|
|
|
|
|
|
|
* Y [out] signature public key |
126
|
|
|
|
|
|
|
* v [in] signature value |
127
|
|
|
|
|
|
|
* h [in] signature hash |
128
|
|
|
|
|
|
|
* P [in] public key |
129
|
|
|
|
|
|
|
*/ |
130
|
|
|
|
|
|
|
void verify25519(pub25519 Y, const k25519 v, const k25519 h, const pub25519 P); |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
#endif |