File Coverage

curve25519_i64.h
Criterion Covered Total %
statement 5 5 100.0
branch n/a
condition n/a
subroutine n/a
pod n/a
total 5 5 100.0


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