-
Notifications
You must be signed in to change notification settings - Fork 1
/
ed448.h
executable file
·294 lines (264 loc) · 11.3 KB
/
ed448.h
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
/**
* @file goldilocks/ed448.h
* @author Mike Hamburg
*
* @copyright
* Copyright (c) 2015-2016 Cryptography Research, Inc. \n
* Copyright (c) 2018 the libgoldilocks contributors. \n
* Released under the MIT License. See LICENSE.txt for license information.
*
* @brief A group of prime order p, based on Ed448-Goldilocks.
*/
#ifndef __GOLDILOCKS_ED448_H__
#define __GOLDILOCKS_ED448_H__ 1
#include <./point_448.h>
#include <./shake.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Number of bytes in an EdDSA public key. */
#define GOLDILOCKS_EDDSA_448_PUBLIC_BYTES 57
/** Number of bytes in an EdDSA private key. */
#define GOLDILOCKS_EDDSA_448_PRIVATE_BYTES GOLDILOCKS_EDDSA_448_PUBLIC_BYTES
/** Number of bytes in an EdDSA signature. */
#define GOLDILOCKS_EDDSA_448_SIGNATURE_BYTES (GOLDILOCKS_EDDSA_448_PUBLIC_BYTES + GOLDILOCKS_EDDSA_448_PRIVATE_BYTES)
/** Does EdDSA support non-contextual signatures? */
#define GOLDILOCKS_EDDSA_448_SUPPORTS_CONTEXTLESS_SIGS 0
/** Prehash context (raw), because each EdDSA instance has a different prehash. */
#define goldilocks_ed448_prehash_ctx_s goldilocks_shake256_ctx_s
/** Prehash context, array[1] form. */
#define goldilocks_ed448_prehash_ctx_p goldilocks_shake256_ctx_p
/** Prehash update. */
#define goldilocks_ed448_prehash_update goldilocks_shake256_update
/** Prehash destroy. */
#define goldilocks_ed448_prehash_destroy goldilocks_shake256_destroy
/** EdDSA encoding ratio. */
#define GOLDILOCKS_448_EDDSA_ENCODE_RATIO 4
/** EdDSA decoding ratio. */
#define GOLDILOCKS_448_EDDSA_DECODE_RATIO (4 / 4)
/**
* @brief EdDSA key secret key generation. This function uses a different (non-Decaf)
* encoding. It is used for libotrv4.
*
* @param [out] secret The secret key.
* @param [in] privkey The private key.
*/
void goldilocks_ed448_derive_secret_scalar (
goldilocks_448_scalar_p secret,
const uint8_t privkey[GOLDILOCKS_EDDSA_448_PRIVATE_BYTES]
) GOLDILOCKS_API_VIS GOLDILOCKS_NONNULL GOLDILOCKS_NOINLINE;
/**
* @brief EdDSA key generation. This function uses a different (non-Decaf)
* encoding.
*
* @param [out] pubkey The public key.
* @param [in] privkey The private key.
*/
void goldilocks_ed448_derive_public_key (
uint8_t pubkey[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES],
const uint8_t privkey[GOLDILOCKS_EDDSA_448_PRIVATE_BYTES]
) GOLDILOCKS_API_VIS GOLDILOCKS_NONNULL GOLDILOCKS_NOINLINE;
/**
* @brief EdDSA signing.
*
* @param [out] signature The signature.
* @param [in] privkey The private key.
* @param [in] pubkey The public key.
* @param [in] message The message to sign.
* @param [in] message_len The length of the message.
* @param [in] prehashed Nonzero if the message is actually the hash of something you want to sign.
* @param [in] context A "context" for this signature of up to 255 bytes.
* @param [in] context_len Length of the context.
*
* @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed
* messages, at least without some very careful protocol-level disambiguation. For Ed448 it is
* safe. The C++ wrapper is designed to make it harder to screw this up, but this C code gives
* you no seat belt.
*/
void goldilocks_ed448_sign (
uint8_t signature[GOLDILOCKS_EDDSA_448_SIGNATURE_BYTES],
const uint8_t privkey[GOLDILOCKS_EDDSA_448_PRIVATE_BYTES],
const uint8_t pubkey[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES],
const uint8_t *message,
size_t message_len,
uint8_t prehashed,
const uint8_t *context,
uint8_t context_len
) GOLDILOCKS_API_VIS __attribute__((nonnull(1,2,3))) GOLDILOCKS_NOINLINE;
/**
* @brief EdDSA signing with prehash.
*
* @param [out] signature The signature.
* @param [in] privkey The private key.
* @param [in] pubkey The public key.
* @param [in] hash The hash of the message. This object will not be modified by the call.
* @param [in] context A "context" for this signature of up to 255 bytes. Must be the same as what was used for the prehash.
* @param [in] context_len Length of the context.
*
* @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed
* messages, at least without some very careful protocol-level disambiguation. For Ed448 it is
* safe. The C++ wrapper is designed to make it harder to screw this up, but this C code gives
* you no seat belt.
*/
void goldilocks_ed448_sign_prehash (
uint8_t signature[GOLDILOCKS_EDDSA_448_SIGNATURE_BYTES],
const uint8_t privkey[GOLDILOCKS_EDDSA_448_PRIVATE_BYTES],
const uint8_t pubkey[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES],
const goldilocks_ed448_prehash_ctx_p hash,
const uint8_t *context,
uint8_t context_len
) GOLDILOCKS_API_VIS __attribute__((nonnull(1,2,3,4))) GOLDILOCKS_NOINLINE;
/**
* @brief Prehash initialization, with contexts if supported.
*
* @param [out] hash The hash object to be initialized.
*/
void goldilocks_ed448_prehash_init (
goldilocks_ed448_prehash_ctx_p hash
) GOLDILOCKS_API_VIS __attribute__((nonnull(1))) GOLDILOCKS_NOINLINE;
/**
* @brief EdDSA signature verification.
*
* Uses the standard (i.e. less-strict) verification formula.
*
* @param [in] signature The signature.
* @param [in] pubkey The public key.
* @param [in] message The message to verify.
* @param [in] message_len The length of the message.
* @param [in] prehashed Nonzero if the message is actually the hash of something you want to verify.
* @param [in] context A "context" for this signature of up to 255 bytes.
* @param [in] context_len Length of the context.
*
* @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed
* messages, at least without some very careful protocol-level disambiguation. For Ed448 it is
* safe. The C++ wrapper is designed to make it harder to screw this up, but this C code gives
* you no seat belt.
*/
goldilocks_error_t goldilocks_ed448_verify (
const uint8_t signature[GOLDILOCKS_EDDSA_448_SIGNATURE_BYTES],
const uint8_t pubkey[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES],
const uint8_t *message,
size_t message_len,
uint8_t prehashed,
const uint8_t *context,
uint8_t context_len
) GOLDILOCKS_API_VIS __attribute__((nonnull(1,2))) GOLDILOCKS_NOINLINE;
/**
* @brief EdDSA signature verification.
*
* Uses the standard (i.e. less-strict) verification formula.
*
* @param [in] signature The signature.
* @param [in] pubkey The public key.
* @param [in] hash The hash of the message. This object will not be modified by the call.
* @param [in] context A "context" for this signature of up to 255 bytes. Must be the same as what was used for the prehash.
* @param [in] context_len Length of the context.
*
* @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed
* messages, at least without some very careful protocol-level disambiguation. For Ed448 it is
* safe. The C++ wrapper is designed to make it harder to screw this up, but this C code gives
* you no seat belt.
*/
goldilocks_error_t goldilocks_ed448_verify_prehash (
const uint8_t signature[GOLDILOCKS_EDDSA_448_SIGNATURE_BYTES],
const uint8_t pubkey[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES],
const goldilocks_ed448_prehash_ctx_p hash,
const uint8_t *context,
uint8_t context_len
) GOLDILOCKS_API_VIS __attribute__((nonnull(1,2))) GOLDILOCKS_NOINLINE;
/**
* @brief EdDSA point encoding. Used internally, exposed externally.
* Multiplies by GOLDILOCKS_448_EDDSA_ENCODE_RATIO first.
*
* The multiplication is required because the EdDSA encoding represents
* the cofactor information, but the Decaf encoding ignores it (which
* is the whole point). So if you decode from EdDSA and re-encode to
* EdDSA, the cofactor info must get cleared, because the intermediate
* representation doesn't track it.
*
* The way libgoldilocks handles this is to multiply by
* GOLDILOCKS_448_EDDSA_DECODE_RATIO when decoding, and by
* GOLDILOCKS_448_EDDSA_ENCODE_RATIO when encoding. The product of these
* ratios is always exactly the cofactor 4, so the cofactor
* ends up cleared one way or another. But exactly how that shakes
* out depends on the base points specified in RFC 8032.
*
* The upshot is that if you pass the base point to
* this function, you will get GOLDILOCKS_448_EDDSA_ENCODE_RATIO times the
* EdDSA base point.
*
* @param [out] enc The encoded point.
* @param [in] p The point.
*/
void goldilocks_448_point_mul_by_ratio_and_encode_like_eddsa (
uint8_t enc[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES],
const goldilocks_448_point_p p
) GOLDILOCKS_API_VIS GOLDILOCKS_NONNULL GOLDILOCKS_NOINLINE;
/**
* @brief EdDSA point decoding. Multiplies by GOLDILOCKS_448_EDDSA_DECODE_RATIO,
* and ignores cofactor information.
*
* See notes on goldilocks_448_point_mul_by_ratio_and_encode_like_eddsa
*
* @param [out] enc The encoded point.
* @param [in] p The point.
*/
goldilocks_error_t goldilocks_448_point_decode_like_eddsa_and_mul_by_ratio (
goldilocks_448_point_p p,
const uint8_t enc[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES]
) GOLDILOCKS_API_VIS GOLDILOCKS_NONNULL GOLDILOCKS_NOINLINE;
/**
* @brief EdDSA to ECDH public key conversion
* Deserialize the point to get y on Edwards curve,
* Convert it to u coordinate on Montgomery curve.
*
* @warning This function does not check that the public key being converted
* is a valid EdDSA public key (FUTURE?)
*
* @param[out] x The ECDH public key as in RFC7748(point on Montgomery curve)
* @param[in] ed The EdDSA public key(point on Edwards curve)
*/
void goldilocks_ed448_convert_public_key_to_x448 (
uint8_t x[GOLDILOCKS_X448_PUBLIC_BYTES],
const uint8_t ed[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES]
) GOLDILOCKS_API_VIS GOLDILOCKS_NONNULL GOLDILOCKS_NOINLINE;
/**
* @brief EdDSA to ECDH private key conversion
* Using the appropriate hash function, hash the EdDSA private key
* and keep only the lower bytes to get the ECDH private key
*
* @param[out] x The ECDH private key as in RFC7748
* @param[in] ed The EdDSA private key
*/
void goldilocks_ed448_convert_private_key_to_x448 (
uint8_t x[GOLDILOCKS_X448_PRIVATE_BYTES],
const uint8_t ed[GOLDILOCKS_EDDSA_448_PRIVATE_BYTES]
) GOLDILOCKS_API_VIS GOLDILOCKS_NONNULL GOLDILOCKS_NOINLINE;
void goldilocks_ed448_private_to_secretkey (
uint8_t secretkey[GOLDILOCKS_EDDSA_448_PRIVATE_BYTES],
const uint8_t privkey[GOLDILOCKS_EDDSA_448_PRIVATE_BYTES]
) GOLDILOCKS_API_VIS GOLDILOCKS_NONNULL GOLDILOCKS_NOINLINE;
void goldilocks_ed448_sign_with_secretkey_and_prenonce (
uint8_t signature[GOLDILOCKS_EDDSA_448_SIGNATURE_BYTES],
const uint8_t secretkey[GOLDILOCKS_EDDSA_448_PRIVATE_BYTES],
const uint8_t seed[GOLDILOCKS_EDDSA_448_PRIVATE_BYTES],
const uint8_t pubkey[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES],
const uint8_t *message,
size_t message_len,
uint8_t prehashed,
const uint8_t *context,
uint8_t context_len
) GOLDILOCKS_API_VIS __attribute__((nonnull(1,2,3,4))) GOLDILOCKS_NOINLINE;
void goldilocks_ed448_derive_public_key_from_secretkey (
uint8_t pubkey[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES],
const uint8_t secretkey[GOLDILOCKS_EDDSA_448_PRIVATE_BYTES]
) GOLDILOCKS_API_VIS GOLDILOCKS_NONNULL GOLDILOCKS_NOINLINE;
void goldilocks_ed448_add_two_publickeys (
uint8_t pubkey[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES],
const uint8_t publickey1[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES],
const uint8_t publickey2[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES]
) GOLDILOCKS_API_VIS GOLDILOCKS_NONNULL GOLDILOCKS_NOINLINE;
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __GOLDILOCKS_ED448_H__ */