threshold-elgamal 0.1.26 → 0.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -29
- package/dist/thresholdElgamal.d.ts +1 -1
- package/dist/thresholdElgamal.js +1 -1
- package/dist/utils/testUtils.d.ts +1 -1
- package/dist/utils/testUtils.js +8 -8
- package/dist/utils/utils.d.ts +1 -1
- package/dist/utils/utils.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -97,28 +97,24 @@ import {
|
|
|
97
97
|
thresholdDecrypt,
|
|
98
98
|
} from "threshold-elgamal";
|
|
99
99
|
|
|
100
|
-
const primeBits = 2048; // Bit length of the prime modulus
|
|
101
100
|
const threshold = 3; // A scenario for 3 participants with a threshold of 3
|
|
102
|
-
const { prime, generator } = getGroup(
|
|
101
|
+
const { prime, generator } = getGroup(); // 2048-bit by default
|
|
103
102
|
|
|
104
103
|
// Each participant generates their public key share and private key individually
|
|
105
|
-
const participant1Keys = generateKeys(1, threshold
|
|
106
|
-
const participant2Keys = generateKeys(2, threshold
|
|
107
|
-
const participant3Keys = generateKeys(3, threshold
|
|
104
|
+
const participant1Keys = generateKeys(1, threshold);
|
|
105
|
+
const participant2Keys = generateKeys(2, threshold);
|
|
106
|
+
const participant3Keys = generateKeys(3, threshold);
|
|
108
107
|
|
|
109
108
|
// Combine the public keys to form a single public key
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
],
|
|
116
|
-
prime,
|
|
117
|
-
);
|
|
109
|
+
const commonPublicKey = combinePublicKeys([
|
|
110
|
+
participant1Keys.publicKey,
|
|
111
|
+
participant2Keys.publicKey,
|
|
112
|
+
participant3Keys.publicKey,
|
|
113
|
+
]);
|
|
118
114
|
|
|
119
115
|
// Encrypt a message using the combined public key
|
|
120
116
|
const secret = 42;
|
|
121
|
-
const encryptedMessage = encrypt(secret, prime, generator,
|
|
117
|
+
const encryptedMessage = encrypt(secret, prime, generator, commonPublicKey);
|
|
122
118
|
|
|
123
119
|
// Decryption shares
|
|
124
120
|
const decryptionShares = [
|
|
@@ -139,6 +135,7 @@ const thresholdDecryptedMessage = thresholdDecrypt(
|
|
|
139
135
|
prime,
|
|
140
136
|
);
|
|
141
137
|
console.log(thresholdDecryptedMessage); // 42
|
|
138
|
+
expect(thresholdDecryptedMessage).toBe(secret);
|
|
142
139
|
```
|
|
143
140
|
|
|
144
141
|
### Voting and multiplication with threshold scheme for 3 participants
|
|
@@ -157,24 +154,20 @@ import {
|
|
|
157
154
|
getGroup,
|
|
158
155
|
} from "threshold-elgamal";
|
|
159
156
|
|
|
160
|
-
const primeBits = 2048; // Bit length of the prime modulus
|
|
161
157
|
const threshold = 3; // A scenario for 3 participants with a threshold of 3
|
|
162
|
-
const { prime, generator } = getGroup(
|
|
158
|
+
const { prime, generator } = getGroup(); // 2048-bit by default
|
|
163
159
|
|
|
164
160
|
// Each participant generates their public key share and private key individually
|
|
165
|
-
const participant1Keys = generateKeys(1, threshold
|
|
166
|
-
const participant2Keys = generateKeys(2, threshold
|
|
167
|
-
const participant3Keys = generateKeys(3, threshold
|
|
161
|
+
const participant1Keys = generateKeys(1, threshold);
|
|
162
|
+
const participant2Keys = generateKeys(2, threshold);
|
|
163
|
+
const participant3Keys = generateKeys(3, threshold);
|
|
168
164
|
|
|
169
165
|
// Combine the public keys to form a single public key
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
],
|
|
176
|
-
prime,
|
|
177
|
-
);
|
|
166
|
+
const commonPublicKey = combinePublicKeys([
|
|
167
|
+
participant1Keys.publicKey,
|
|
168
|
+
participant2Keys.publicKey,
|
|
169
|
+
participant3Keys.publicKey,
|
|
170
|
+
]);
|
|
178
171
|
|
|
179
172
|
// Participants cast their encrypted votes for two options
|
|
180
173
|
const voteOption1 = [6, 7, 1]; // Votes for option 1 by participants 1, 2, and 3
|
|
@@ -182,10 +175,10 @@ const voteOption2 = [10, 7, 4]; // Votes for option 2 by participants 1, 2, and
|
|
|
182
175
|
|
|
183
176
|
// Encrypt votes for both options
|
|
184
177
|
const encryptedVotesOption1 = voteOption1.map((vote) =>
|
|
185
|
-
encrypt(vote, prime, generator,
|
|
178
|
+
encrypt(vote, prime, generator, commonPublicKey),
|
|
186
179
|
);
|
|
187
180
|
const encryptedVotesOption2 = voteOption2.map((vote) =>
|
|
188
|
-
encrypt(vote, prime, generator,
|
|
181
|
+
encrypt(vote, prime, generator, commonPublicKey),
|
|
189
182
|
);
|
|
190
183
|
|
|
191
184
|
// Multiply encrypted votes together to aggregate
|
|
@@ -39,7 +39,7 @@ export declare const generateKeyShares: (n: number, threshold: number, primeBits
|
|
|
39
39
|
* @param {bigint} prime - The prime modulus used in the ElGamal system.
|
|
40
40
|
* @returns {bigint} The combined public key.
|
|
41
41
|
*/
|
|
42
|
-
export declare const combinePublicKeys: (publicKeys: bigint[], prime
|
|
42
|
+
export declare const combinePublicKeys: (publicKeys: bigint[], prime?: bigint) => bigint;
|
|
43
43
|
/**
|
|
44
44
|
* Performs a partial decryption on a ciphertext using an individual's private key share.
|
|
45
45
|
*
|
package/dist/thresholdElgamal.js
CHANGED
|
@@ -59,7 +59,7 @@ export const generateKeyShares = (n, threshold, primeBits = 2048) => {
|
|
|
59
59
|
* @param {bigint} prime - The prime modulus used in the ElGamal system.
|
|
60
60
|
* @returns {bigint} The combined public key.
|
|
61
61
|
*/
|
|
62
|
-
export const combinePublicKeys = (publicKeys, prime) => publicKeys.reduce((acc, current) => (acc * current) % prime, 1n);
|
|
62
|
+
export const combinePublicKeys = (publicKeys, prime = getGroup(2048).prime) => publicKeys.reduce((acc, current) => (acc * current) % prime, 1n);
|
|
63
63
|
/**
|
|
64
64
|
* Performs a partial decryption on a ciphertext using an individual's private key share.
|
|
65
65
|
*
|
package/dist/utils/testUtils.js
CHANGED
|
@@ -7,12 +7,12 @@ export const thresholdSetup = (partiesCount, threshold, primeBits = 2048) => {
|
|
|
7
7
|
const { prime, generator } = getGroup(primeBits);
|
|
8
8
|
const keyShares = generateKeyShares(partiesCount, threshold, primeBits);
|
|
9
9
|
const publicKeys = keyShares.map((ks) => ks.publicKey);
|
|
10
|
-
const
|
|
11
|
-
return { keyShares,
|
|
10
|
+
const commonPublicKey = combinePublicKeys(publicKeys, prime);
|
|
11
|
+
return { keyShares, commonPublicKey, prime, generator };
|
|
12
12
|
};
|
|
13
13
|
export const testSecureEncryptionAndDecryption = (participantsCount, threshold, secret) => {
|
|
14
|
-
const { keyShares,
|
|
15
|
-
const encryptedMessage = encrypt(secret, prime, generator,
|
|
14
|
+
const { keyShares, commonPublicKey, prime, generator } = thresholdSetup(participantsCount, threshold);
|
|
15
|
+
const encryptedMessage = encrypt(secret, prime, generator, commonPublicKey);
|
|
16
16
|
const selectedDecryptionShares = keyShares
|
|
17
17
|
.sort(() => Math.random() - 0.5)
|
|
18
18
|
.slice(0, threshold)
|
|
@@ -23,8 +23,8 @@ export const testSecureEncryptionAndDecryption = (participantsCount, threshold,
|
|
|
23
23
|
};
|
|
24
24
|
export const homomorphicMultiplicationTest = (participantsCount, threshold, messages) => {
|
|
25
25
|
const expectedProduct = messages.reduce((product, secret) => product * secret, 1);
|
|
26
|
-
const { keyShares,
|
|
27
|
-
const encryptedMessages = messages.map((secret) => encrypt(secret, prime, generator,
|
|
26
|
+
const { keyShares, commonPublicKey, prime, generator } = thresholdSetup(participantsCount, threshold);
|
|
27
|
+
const encryptedMessages = messages.map((secret) => encrypt(secret, prime, generator, commonPublicKey));
|
|
28
28
|
const encryptedProduct = encryptedMessages.reduce((product, encryptedMessage) => multiplyEncryptedValues(product, encryptedMessage, prime), { c1: 1n, c2: 1n });
|
|
29
29
|
const selectedDecryptionShares = keyShares
|
|
30
30
|
.sort(() => Math.random() - 0.5)
|
|
@@ -35,10 +35,10 @@ export const homomorphicMultiplicationTest = (participantsCount, threshold, mess
|
|
|
35
35
|
expect(decryptedProduct).toBe(expectedProduct);
|
|
36
36
|
};
|
|
37
37
|
export const votingTest = (participantsCount, threshold, candidatesCount) => {
|
|
38
|
-
const { keyShares,
|
|
38
|
+
const { keyShares, commonPublicKey, prime, generator } = thresholdSetup(participantsCount, threshold);
|
|
39
39
|
const votesMatrix = Array.from({ length: participantsCount }, () => Array.from({ length: candidatesCount }, () => getRandomScore(1, 10)));
|
|
40
40
|
const expectedProducts = Array.from({ length: candidatesCount }, (_, candidateIndex) => votesMatrix.reduce((product, votes) => product * votes[candidateIndex], 1));
|
|
41
|
-
const encryptedVotesMatrix = votesMatrix.map((votes) => votes.map((vote) => encrypt(vote, prime, generator,
|
|
41
|
+
const encryptedVotesMatrix = votesMatrix.map((votes) => votes.map((vote) => encrypt(vote, prime, generator, commonPublicKey)));
|
|
42
42
|
const encryptedProducts = Array.from({ length: candidatesCount }, (_, candidateIndex) => encryptedVotesMatrix.reduce((product, encryptedVotes) => multiplyEncryptedValues(product, encryptedVotes[candidateIndex], prime), { c1: 1n, c2: 1n }));
|
|
43
43
|
const partialDecryptionsMatrix = encryptedProducts.map((product) => keyShares
|
|
44
44
|
.slice(0, threshold)
|
package/dist/utils/utils.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export declare const randomBigint: (bits: number) => bigint;
|
|
|
21
21
|
* @param {2048 | 3072 | 4096} primeBits - The bit length of the prime modulus (2048, 3072, or 4096).
|
|
22
22
|
* @returns {Object} The group parameters including prime and generator.
|
|
23
23
|
*/
|
|
24
|
-
export declare const getGroup: (primeBits
|
|
24
|
+
export declare const getGroup: (primeBits?: 2048 | 3072 | 4096) => {
|
|
25
25
|
prime: bigint;
|
|
26
26
|
generator: bigint;
|
|
27
27
|
};
|
package/dist/utils/utils.js
CHANGED
|
@@ -37,7 +37,7 @@ export const randomBigint = (bits) => {
|
|
|
37
37
|
* @param {2048 | 3072 | 4096} primeBits - The bit length of the prime modulus (2048, 3072, or 4096).
|
|
38
38
|
* @returns {Object} The group parameters including prime and generator.
|
|
39
39
|
*/
|
|
40
|
-
export const getGroup = (primeBits) => {
|
|
40
|
+
export const getGroup = (primeBits = 2048) => {
|
|
41
41
|
switch (primeBits) {
|
|
42
42
|
case 2048:
|
|
43
43
|
return GROUPS.ffdhe2048;
|