-
Notifications
You must be signed in to change notification settings - Fork 1
/
pre.js
216 lines (199 loc) · 6.48 KB
/
pre.js
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
/*
* Copyright (c) 2021, Alden Torres
*
* Licensed under the terms of the MIT license.
* Copy of the license at https://opensource.org/licenses/MIT
*/
import libecc_module from "./libecc.js";
/**
* Generates a random message suitable to use in the protocol.
*
* The output can be used in other key derivation algorithms for other
* symmetric encryption protocols.
*
* @return {Uint8Array} a random plaintext message
*/
export async function pre_schema1_MessageGen() {
const libecc = await libecc_module();
let m = new Uint8Array(libecc.ecc_pre_schema1_MESSAGESIZE);
await libecc.ecc_pre_schema1_MessageGen(m);
return m;
}
/**
* Generate a public/private key pair.
*
* @return {object} a random public/private key pair
*/
export async function pre_schema1_KeyGen() {
const libecc = await libecc_module();
let pk = new Uint8Array(libecc.ecc_pre_schema1_PUBLICKEYSIZE);
let sk = new Uint8Array(libecc.ecc_pre_schema1_PRIVATEKEYSIZE);
await libecc.ecc_pre_schema1_KeyGen(pk, sk);
return {pk: pk, sk: sk};
}
/**
* Generate a signing public/private key pair.
*
* @return {object} a random signing public/private key pair
*/
export async function pre_schema1_SigningKeyGen() {
const libecc = await libecc_module();
let spk = new Uint8Array(libecc.ecc_pre_schema1_SIGNINGPUBLICKEYSIZE);
let ssk = new Uint8Array(libecc.ecc_pre_schema1_SIGNINGPRIVATEKEYSIZE);
await libecc.ecc_pre_schema1_SigningKeyGen(spk, ssk);
return {spk: spk, ssk: ssk};
}
/**
* Encrypt a message `m` to delegatee j, given j’s public key (pk_j) and the
* sender i’s signing key pair (signing_i). Produces a ciphertext C_j.
*
* This is also called encryption of level 1, since it's used to encrypt to
* itself (i.e j == i), in order to have later the ciphertext re-encrypted
* by the proxy with the re-encryption key (level 2).
*
* @param {Uint8Array} m the plaintext message
* @param {Uint8Array} pk_j delegatee's public key
* @param {object} signing_i sender signing public/private key
* @return a CiphertextLevel1_t structure
*/
export async function pre_schema1_Encrypt(
m,
pk_j,
signing_i
) {
const libecc = await libecc_module();
let C_j_raw = new Uint8Array(libecc.ecc_pre_schema1_CIPHERTEXTLEVEL1SIZE);
await libecc.ecc_pre_schema1_Encrypt(
C_j_raw,
m,
pk_j,
signing_i.spk,
signing_i.ssk
);
return C_j_raw;
}
/**
* Generate a re-encryption key from user i (the delegator) to user j (the delegatee).
*
* Requires the delegator’s private key (sk_i), the delegatee’s public key (pk_j), and
* the delegator’s signing key pair (signing_i).
*
* @param {Uint8Array} sk_i delegator’s private key
* @param {Uint8Array} pk_j delegatee’s public key
* @param {object} signing_i delegator’s signing public/private key
* @return a ReKey_t structure
*/
export async function pre_schema1_ReKeyGen(
sk_i,
pk_j,
signing_i
) {
const libecc = await libecc_module();
let tk_i_j_raw = new Uint8Array(libecc.ecc_pre_schema1_REKEYSIZE);
await libecc.ecc_pre_schema1_ReKeyGen(
tk_i_j_raw,
sk_i,
pk_j,
signing_i.spk,
signing_i.ssk
);
return tk_i_j_raw;
}
/**
* Re-encrypt a ciphertext encrypted to i (C_i) into a ciphertext encrypted
* to j (C_j), given a re-encryption key (tk_i_j) and the proxy’s signing key
* pair (spk, ssk).
*
* This operation is performed by the proxy and is also called encryption of
* level 2, since it takes a ciphertext from a level 1 and re-encrypt it.
*
* It also validate the signature on the encrypted ciphertext and re-encryption key.
*
* @param {Uint8Array} C_i_raw a CiphertextLevel1_t structure
* @param {Uint8Array} tk_i_j_raw a ReKey_t structure
* @param {Uint8Array} spk_i delegator’s signing public key
* @param {Uint8Array} pk_j delegatee’s public key
* @param {object} signing proxy’s signing public/private key
* @return {Uint8Array} a CiphertextLevel2_t structure if all the signatures are
* valid, null if there is an error
*/
export async function pre_schema1_ReEncrypt(
C_i_raw,
tk_i_j_raw,
spk_i,
pk_j,
signing
) {
const libecc = await libecc_module();
let C_j_raw = new Uint8Array(libecc.ecc_pre_schema1_CIPHERTEXTLEVEL2SIZE);
const r = await libecc.ecc_pre_schema1_ReEncrypt(
C_j_raw,
C_i_raw,
tk_i_j_raw,
spk_i,
pk_j,
signing.spk,
signing.ssk
);
return r === 0 ? C_j_raw : null;
}
/**
* Decrypt a signed ciphertext (C_i) given the private key of the recipient
* i (sk_i). Returns the original message that was encrypted, m.
*
* This operations is usually performed by the delegator, since it encrypted
* the message just to be stored and later be re-encrypted by the proxy.
*
* It also validate the signature on the encrypted ciphertext.
*
* @param {Uint8Array} C_i_raw a CiphertextLevel1_t structure
* @param {Uint8Array} sk_i recipient private key
* @param {Uint8Array} spk_i recipient signing public key
* @return {Uint8Array} the original plaintext message if all the signatures are
* valid, null if there is an error
*/
export async function pre_schema1_DecryptLevel1(
C_i_raw,
sk_i,
spk_i
) {
const libecc = await libecc_module();
let m = new Uint8Array(libecc.ecc_pre_schema1_MESSAGESIZE);
const r = await libecc.ecc_pre_schema1_DecryptLevel1(
m,
C_i_raw,
sk_i,
spk_i
);
return r === 0 ? m : null;
}
/**
* Decrypt a signed ciphertext (C_j) given the private key of the recipient
* j (sk_j). Returns the original message that was encrypted, m.
*
* This operations is usually performed by the delegatee, since it is the proxy
* that re-encrypt the message and send the ciphertext to the final recipient.
*
* It also validate the signature on the encrypted ciphertext.
*
* @param {Uint8Array} C_j_raw a CiphertextLevel2_t structure
* @param {Uint8Array} sk_j recipient private key
* @param {Uint8Array} spk proxy’s signing public key
* @return {Uint8Array} the original plaintext message if all the signatures are
* valid, null if there is an error
*/
export async function pre_schema1_DecryptLevel2(
C_j_raw,
sk_j,
spk
) {
const libecc = await libecc_module();
let m = new Uint8Array(libecc.ecc_pre_schema1_MESSAGESIZE);
const r = await libecc.ecc_pre_schema1_DecryptLevel2(
m,
C_j_raw,
sk_j,
spk
);
return r === 0 ? m : null;
}