forked from microsoft/PQCrypto-SIDH
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSIDH_api.h
192 lines (154 loc) · 13.1 KB
/
SIDH_api.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
/********************************************************************************************
* SIDH: an efficient supersingular isogeny-based cryptography library for ephemeral
* Diffie-Hellman key exchange.
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*
* Abstract: API header file
*
*********************************************************************************************/
#ifndef __SIDH_API_H__
#define __SIDH_API_H__
// For C++
#ifdef __cplusplus
extern "C" {
#endif
#include "SIDH.h"
/*********************** Ephemeral key exchange API ***********************/
// SECURITY NOTE: SIDH supports ephemeral Diffie-Hellman key exchange. It is NOT secure to use it with static keys.
// See "On the Security of Supersingular Isogeny Cryptosystems", S.D. Galbraith, C. Petit, B. Shani and Y.B. Ti, in ASIACRYPT 2016, 2016.
// Extended version available at: http://eprint.iacr.org/2016/859
// Alice's ephemeral key-pair generation
// It produces a private key pPrivateKeyA and computes the public key pPublicKeyA.
// The private key is an even integer in the range [2, oA-2], where oA = 2^372 (i.e., 372 bits in total).
// The public key consists of 3 elements in GF(p751^2), i.e., 564 bytes.
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
// batch is a struct enabling batched inversion in parallel
CRYPTO_STATUS EphemeralKeyGeneration_A(unsigned char* pPrivateKeyA, unsigned char* pPublicKeyA, PCurveIsogenyStruct CurveIsogeny);
// Bob's ephemeral key-pair generation
// It produces a private key pPrivateKeyB and computes the public key pPublicKeyB.
// The private key is an integer in the range [1, oB-1], where oA = 3^239 (i.e., 379 bits in total).
// The public key consists of 3 elements in GF(p751^2), i.e., 564 bytes.
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
CRYPTO_STATUS EphemeralKeyGeneration_B(unsigned char* pPrivateKeyB, unsigned char* pPublicKeyB, PCurveIsogenyStruct CurveIsogeny);
// Alice's ephemeral shared secret computation
// It produces a shared secret key pSharedSecretA using her secret key pPrivateKeyA and Bob's public key pPublicKeyB
// Inputs: Alice's pPrivateKeyA is an even integer in the range [2, oA-2], where oA = 2^372 (i.e., 372 bits in total).
// Bob's pPublicKeyB consists of 3 elements in GF(p751^2), i.e., 564 bytes.
// Output: a shared secret pSharedSecretA that consists of one element in GF(p751^2), i.e., 1502 bits in total.
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
// batch is a struct enabling batched inversion in parallel
CRYPTO_STATUS EphemeralSecretAgreement_A(const unsigned char* pPrivateKeyA, const unsigned char* pPublicKeyB, unsigned char* pSharedSecretA, PCurveIsogenyStruct CurveIsogeny);
// Bob's ephemeral shared secret computation
// It produces a shared secret key pSharedSecretB using his secret key pPrivateKeyB and Alice's public key pPublicKeyA
// Inputs: Bob's pPrivateKeyB is an integer in the range [1, oB-1], where oA = 3^239 (i.e., 379 bits in total).
// Alice's pPublicKeyA consists of 3 elements in GF(p751^2), i.e., 564 bytes.
// Output: a shared secret pSharedSecretB that consists of one element in GF(p751^2), i.e., 1502 bits in total.
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
// batch is a struct enabling batched inversion in parallel
CRYPTO_STATUS EphemeralSecretAgreement_B(const unsigned char* pPrivateKeyB, const unsigned char* pPublicKeyA, unsigned char* pSharedSecretB, PCurveIsogenyStruct CurveIsogeny);
/*********************** Ephemeral key exchange API with compressed public keys ***********************/
// Alice's public key compression
// It produces a compressed output that consists of three elements in Z_orderB and one field element
// Input : Alice's public key PublicKeyA, which consists of 3 elements in GF(p751^2).
// Output: a compressed value CompressedPKA that consists of three elements in Z_orderB and one element in GF(p751^2).
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
void PublicKeyCompression_A(const unsigned char* PublicKeyA, unsigned char* CompressedPKA, PCurveIsogenyStruct CurveIsogeny);
// Alice's public key value decompression computed by Bob
// Inputs: Bob's private key SecretKeyB, and
// Alice's compressed public key data CompressedPKA, which consists of three elements in Z_orderB and one element in GF(p751^2),
// Output: a point point_R in coordinates (X:Z) and the curve parameter param_A in GF(p751^2). Outputs are stored in Montgomery representation.
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
void PublicKeyADecompression_B(const unsigned char* SecretKeyB, const unsigned char* CompressedPKA, unsigned char* point_R, unsigned char* param_A, PCurveIsogenyStruct CurveIsogeny);
// Alice's ephemeral shared secret computation
// It produces a shared secret key SharedSecretA using her secret key PrivateKeyA and Bob's public key PublicKeyB
// Inputs: Alice's PrivateKeyA is an even integer in the range [2, oA-2], where oA = 2^372 (i.e., 372 bits in total).
// Bob's PublicKeyB consists of 3 elements in GF(p751^2), i.e., 564 bytes.
// Output: a shared secret SharedSecretA that consists of one element in GF(p751^2), i.e., 1502 bits in total.
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
CRYPTO_STATUS EphemeralSecretAgreement_Compression_A(const unsigned char* PrivateKeyA, const unsigned char* point_R, const unsigned char* param_A, unsigned char* SharedSecretA, PCurveIsogenyStruct CurveIsogeny);
// Bob's public key compression
// It produces a compressed output that consists of three elements in Z_orderA and one field element
// Input : Bob's public key PublicKeyB, which consists of 3 elements in GF(p751^2).
// Output: a compressed value CompressedPKB that consists of three elements in Z_orderA and one element in GF(p751^2).
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
void PublicKeyCompression_B(const unsigned char* PublicKeyB, unsigned char* CompressedPKB, PCurveIsogenyStruct CurveIsogeny);
// Bob's public key value decompression computed by Alice
// Inputs: Alice's private key SecretKeyA, and
// Bob's compressed public key data CompressedPKB, which consists of three elements in Z_orderA and one element in GF(p751^2).
// Output: a point point_R in coordinates (X:Z) and the curve parameter param_A in GF(p751^2). Outputs are stored in Montgomery representation.
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
void PublicKeyBDecompression_A(const unsigned char* SecretKeyA, const unsigned char* CompressedPKB, unsigned char* point_R, unsigned char* param_A, PCurveIsogenyStruct CurveIsogeny);
// Bob's ephemeral shared secret computation
// It produces a shared secret key SharedSecretB using his secret key PrivateKeyB and Alice's decompressed data point_R and param_A
// Inputs: Bob's PrivateKeyB is an integer in the range [1, oB-1], where oB = 3^239.
// Alice's decompressed data consists of point_R in (X:Z) coordinates and the curve paramater param_A in GF(p751^2).
// Output: a shared secret SharedSecretB that consists of one element in GF(p751^2).
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
CRYPTO_STATUS EphemeralSecretAgreement_Compression_B(const unsigned char* PrivateKeyB, const unsigned char* point_R, const unsigned char* param_A, unsigned char* SharedSecretB, PCurveIsogenyStruct CurveIsogeny);
// Compression of value psi(S) for isogeny based signatures
CRYPTO_STATUS compressPsiS(const point_proj* psiS, unsigned char* CompressedPsiS, int* compBit, const f2elm_t A, PCurveIsogenyStruct CurveIsogeny, batch_struct* batch);
// Decompression of value psi(S) and calculation of the points degree
CRYPTO_STATUS decompressPsiS(const unsigned char* CompressedPsiS, point_proj* psiS, int compBit, const f2elm_t A, PCurveIsogenyStruct CurveIsogeny, batch_struct* batch);
CRYPTO_STATUS compressPsiS_test(const point_proj* psiS, unsigned char* CompressedPsiS, int* compBit, const f2elm_t A, PCurveIsogenyStruct CurveIsogeny, batch_struct* batch, digit_t* a, digit_t* b);
CRYPTO_STATUS decompressPsiS_test(const unsigned char* CompressedPsiS, point_proj* S, int compBit, const f2elm_t A, PCurveIsogenyStruct CurveIsogeny, digit_t* a, digit_t* b);
/*********************** SIDH 1.0 Key exchange API ***********************/
// Alice's key-pair generation
// It produces a private key pPrivateKeyA and computes the public key pPublicKeyA.
// The private key is an even integer in the range [2, oA-2], where oA = 2^372 (i.e., 372 bits in total).
// The public key consists of 4 elements in GF(p751^2), i.e., 751 bytes in total.
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
// batch is a struct enabling batched inversion in parallel
CRYPTO_STATUS KeyGeneration_A(unsigned char* pPrivateKeyA, unsigned char* pPublicKeyA, PCurveIsogenyStruct CurveIsogeny, bool GenerateRandom, batch_struct* batch);
// Bob's key-pair generation
// It produces a private key pPrivateKeyB and computes the public key pPublicKeyB.
// The private key is an integer in the range [1, oB-1], where oA = 3^239 (i.e., 379 bits in total).
// The public key consists of 4 elements in GF(p751^2), i.e., 751 bytes in total.
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
CRYPTO_STATUS KeyGeneration_B(unsigned char* pPrivateKeyB, unsigned char* pPublicKeyB, PCurveIsogenyStruct CurveIsogeny);
// Validation of Alice's public key (ran by Bob)
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
CRYPTO_STATUS Validate_PKA(unsigned char* pPublicKeyA, bool* valid, PCurveIsogenyStruct CurveIsogeny);
// Validation of Bob's public key (ran by Alice)
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
CRYPTO_STATUS Validate_PKB(unsigned char* pPublicKeyB, bool* valid, PCurveIsogenyStruct CurveIsogeny);
// Alice's shared secret generation
// It produces a shared secret key pSharedSecretA using her secret key pPrivateKeyA and Bob's public key pPublicKeyB
// Inputs: Alice's pPrivateKeyA is an even integer in the range [2, oA-2], where oA = 2^372 (i.e., 372 bits in total).
// Bob's pPublicKeyB consists of 4 elements in GF(p751^2), i.e., 751 bytes in total.
// Output: a shared secret pSharedSecretA that consists of one element in GF(p751^2), i.e., 1502 bits in total.
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
// batch is a struct enabling batched inversion in parallel
CRYPTO_STATUS SecretAgreement_A(unsigned char* pPrivateKeyA, unsigned char* pPublicKeyB, unsigned char* pSharedSecretA, PCurveIsogenyStruct CurveIsogeny, point_proj_t kerngen, batch_struct* batch);
// Bob's shared secret generation
// It produces a shared secret key pSharedSecretB using his secret key pPrivateKeyB and Alice's public key pPublicKeyA
// Inputs: Bob's pPrivateKeyB is an integer in the range [1, oB-1], where oA = 3^239 (i.e., 379 bits in total).
// Alice's pPublicKeyA consists of 4 elements in GF(p751^2), i.e., 751 bytes in total.
// Output: a shared secret pSharedSecretB that consists of one element in GF(p751^2), i.e., 1502 bits in total.
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
// batch is a struct enabling batched inversion in parallel
CRYPTO_STATUS SecretAgreement_B(unsigned char* pPrivateKeyB, unsigned char* pPublicKeyA, unsigned char* pSharedSecretB, PCurveIsogenyStruct CurveIsogeny, point_proj_t kerngen, point_proj_t extractpoint, batch_struct* batch);
/*********************** Scalar multiplication API using BigMont ***********************/
// BigMont's scalar multiplication using the Montgomery ladder
// Inputs: x, the affine x-coordinate of a point P on BigMont: y^2=x^3+A*x^2+x,
// scalar m.
// Output: xout, the affine x-coordinate of m*(x:1)
// CurveIsogeny must be set up in advance using SIDH_curve_initialize().
CRYPTO_STATUS BigMont_ladder(unsigned char* x, digit_t* m, unsigned char* xout, PCurveIsogenyStruct CurveIsogeny);
// Encoding of keys for isogeny system "SIDHp751" (wire format):
// ------------------------------------------------------------
// Elements over GF(p751) are encoded in 96 octets in little endian format (i.e., the least significant octet located at the leftmost position).
// Elements (a+b*i) over GF(p751^2), where a and b are defined over GF(p751), are encoded as {b, a}, with b in the least significant position.
// Elements over Z_oA and Z_oB are encoded in 48 octets in little endian format.
//
// Private keys pPrivateKeyA and pPrivateKeyB are defined in Z_oA and Z_oB (resp.) and can have values in the range [2, 2^372-2] and [1, 3^239-1], resp.
// In the key exchange API, they are encoded in 48 octets in little endian format.
// Public keys pPublicKeyA and pPublicKeyB consist of four elements in GF(p751^2). In the key exchange API, they are encoded in 768 octets in little
// endian format.
// Shared keys pSharedSecretA and pSharedSecretB consist of one element in GF(p751^2). In the key exchange API, they are encoded in 192 octets in little
// endian format.
#ifdef __cplusplus
}
#endif
#endif