threshold-elgamal 0.1.19 → 0.1.21

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/dist/constants.js CHANGED
@@ -1,6 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GROUPS = void 0;
4
1
  /*
5
2
  The GROUPS object defines cryptographic parameters for different levels
6
3
  of finite field Diffie-Hellman (FFDHE) key exchanges.
@@ -14,7 +11,7 @@ exports.GROUPS = void 0;
14
11
 
15
12
  Reference: https://datatracker.ietf.org/doc/rfc7919/
16
13
  */
17
- exports.GROUPS = {
14
+ export const GROUPS = {
18
15
  // Parameters for 2048-bit prime modulus group
19
16
  ffdhe2048: {
20
17
  primeBits: 2048, // Size of the prime in bits, default security level suitable for current applications
package/dist/elgamal.js CHANGED
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.decrypt = exports.encrypt = exports.generateParameters = void 0;
4
- const bigint_mod_arith_1 = require("bigint-mod-arith");
5
- const utils_1 = require("./utils");
1
+ import { modPow, modInv } from 'bigint-mod-arith';
2
+ import { getRandomBigIntegerInRange, getGroup } from './utils';
6
3
  /**
7
4
  * Generates the parameters for the ElGamal encryption, including the prime, generator,
8
5
  * and key pair (public and private keys).
@@ -10,13 +7,12 @@ const utils_1 = require("./utils");
10
7
  * @param {2048 | 3072 | 4096} primeBits - The bit length for the prime number. Supports 2048, 3072, or 4096 bits.
11
8
  * @returns {Parameters} The generated parameters including the prime, generator, publicKey, and privateKey.
12
9
  */
13
- const generateParameters = (primeBits = 2048) => {
14
- const { prime, generator } = (0, utils_1.getGroup)(primeBits); // Use getGroup to fetch the prime and generator
15
- const privateKey = (0, utils_1.getRandomBigIntegerInRange)(2n, prime - 1n);
16
- const publicKey = (0, bigint_mod_arith_1.modPow)(generator, privateKey, prime);
10
+ export const generateParameters = (primeBits = 2048) => {
11
+ const { prime, generator } = getGroup(primeBits); // Use getGroup to fetch the prime and generator
12
+ const privateKey = getRandomBigIntegerInRange(2n, prime - 1n);
13
+ const publicKey = modPow(generator, privateKey, prime);
17
14
  return { prime, generator, publicKey, privateKey };
18
15
  };
19
- exports.generateParameters = generateParameters;
20
16
  /**
21
17
  * Encrypts a secret using ElGamal encryption.
22
18
  *
@@ -26,17 +22,16 @@ exports.generateParameters = generateParameters;
26
22
  * @param {bigint} publicKey - The public key used for encryption.
27
23
  * @returns {EncryptedMessage} The encrypted secret, consisting of two BigIntegers (c1 and c2).
28
24
  */
29
- const encrypt = (secret, prime, generator, publicKey) => {
25
+ export const encrypt = (secret, prime, generator, publicKey) => {
30
26
  if (secret >= Number(prime)) {
31
27
  throw new Error('Message is too large for direct encryption');
32
28
  }
33
- const randomNumber = (0, utils_1.getRandomBigIntegerInRange)(1n, prime - 1n);
34
- const c1 = (0, bigint_mod_arith_1.modPow)(generator, randomNumber, prime);
29
+ const randomNumber = getRandomBigIntegerInRange(1n, prime - 1n);
30
+ const c1 = modPow(generator, randomNumber, prime);
35
31
  const messageBigInt = BigInt(secret);
36
- const c2 = ((0, bigint_mod_arith_1.modPow)(publicKey, randomNumber, prime) * messageBigInt) % prime;
32
+ const c2 = (modPow(publicKey, randomNumber, prime) * messageBigInt) % prime;
37
33
  return { c1, c2 };
38
34
  };
39
- exports.encrypt = encrypt;
40
35
  /**
41
36
  * Decrypts an ElGamal encrypted secret.
42
37
  *
@@ -45,9 +40,8 @@ exports.encrypt = encrypt;
45
40
  * @param {bigint} privateKey - The private key used for decryption.
46
41
  * @returns {number} The decrypted secret as an integer.
47
42
  */
48
- const decrypt = (encryptedMessage, prime, privateKey) => {
49
- const ax = (0, bigint_mod_arith_1.modPow)(encryptedMessage.c1, privateKey, prime);
50
- const plaintext = ((0, bigint_mod_arith_1.modInv)(ax, prime) * encryptedMessage.c2) % prime;
43
+ export const decrypt = (encryptedMessage, prime, privateKey) => {
44
+ const ax = modPow(encryptedMessage.c1, privateKey, prime);
45
+ const plaintext = (modInv(ax, prime) * encryptedMessage.c2) % prime;
51
46
  return Number(plaintext);
52
47
  };
53
- exports.decrypt = decrypt;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- export { generateParameters, encrypt, decrypt } from './elgamal';
2
- export { generateSingleKeyShare, generateKeyShares, combinePublicKeys, createDecryptionShare, combineDecryptionShares, thresholdDecrypt, } from './thresholdElgamal';
3
- export { getRandomBigIntegerInRange, multiplyEncryptedValues, getGroup, } from './utils';
4
- export type { EncryptedMessage, Parameters, KeyPair, PartyKeyPair, } from './types';
1
+ import { generateParameters, encrypt, decrypt } from './elgamal';
2
+ import { generateSingleKeyShare, generateKeyShares, combinePublicKeys, createDecryptionShare, combineDecryptionShares, thresholdDecrypt } from './thresholdElgamal';
3
+ import type { EncryptedMessage, Parameters, KeyPair, PartyKeyPair } from './types';
4
+ import { getRandomBigIntegerInRange, multiplyEncryptedValues, getGroup } from './utils';
5
+ export { generateParameters, encrypt, decrypt, generateSingleKeyShare, generateKeyShares, combinePublicKeys, createDecryptionShare, combineDecryptionShares, thresholdDecrypt, getRandomBigIntegerInRange, multiplyEncryptedValues, getGroup, };
6
+ export type { EncryptedMessage, Parameters, KeyPair, PartyKeyPair };
package/dist/index.js CHANGED
@@ -1,18 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getGroup = exports.multiplyEncryptedValues = exports.getRandomBigIntegerInRange = exports.thresholdDecrypt = exports.combineDecryptionShares = exports.createDecryptionShare = exports.combinePublicKeys = exports.generateKeyShares = exports.generateSingleKeyShare = exports.decrypt = exports.encrypt = exports.generateParameters = void 0;
4
- var elgamal_1 = require("./elgamal");
5
- Object.defineProperty(exports, "generateParameters", { enumerable: true, get: function () { return elgamal_1.generateParameters; } });
6
- Object.defineProperty(exports, "encrypt", { enumerable: true, get: function () { return elgamal_1.encrypt; } });
7
- Object.defineProperty(exports, "decrypt", { enumerable: true, get: function () { return elgamal_1.decrypt; } });
8
- var thresholdElgamal_1 = require("./thresholdElgamal");
9
- Object.defineProperty(exports, "generateSingleKeyShare", { enumerable: true, get: function () { return thresholdElgamal_1.generateSingleKeyShare; } });
10
- Object.defineProperty(exports, "generateKeyShares", { enumerable: true, get: function () { return thresholdElgamal_1.generateKeyShares; } });
11
- Object.defineProperty(exports, "combinePublicKeys", { enumerable: true, get: function () { return thresholdElgamal_1.combinePublicKeys; } });
12
- Object.defineProperty(exports, "createDecryptionShare", { enumerable: true, get: function () { return thresholdElgamal_1.createDecryptionShare; } });
13
- Object.defineProperty(exports, "combineDecryptionShares", { enumerable: true, get: function () { return thresholdElgamal_1.combineDecryptionShares; } });
14
- Object.defineProperty(exports, "thresholdDecrypt", { enumerable: true, get: function () { return thresholdElgamal_1.thresholdDecrypt; } });
15
- var utils_1 = require("./utils");
16
- Object.defineProperty(exports, "getRandomBigIntegerInRange", { enumerable: true, get: function () { return utils_1.getRandomBigIntegerInRange; } });
17
- Object.defineProperty(exports, "multiplyEncryptedValues", { enumerable: true, get: function () { return utils_1.multiplyEncryptedValues; } });
18
- Object.defineProperty(exports, "getGroup", { enumerable: true, get: function () { return utils_1.getGroup; } });
1
+ import { generateParameters, encrypt, decrypt } from './elgamal';
2
+ import { generateSingleKeyShare, generateKeyShares, combinePublicKeys, createDecryptionShare, combineDecryptionShares, thresholdDecrypt, } from './thresholdElgamal';
3
+ import { getRandomBigIntegerInRange, multiplyEncryptedValues, getGroup, } from './utils';
4
+ export { generateParameters, encrypt, decrypt, generateSingleKeyShare, generateKeyShares, combinePublicKeys, createDecryptionShare, combineDecryptionShares, thresholdDecrypt, getRandomBigIntegerInRange, multiplyEncryptedValues, getGroup, };
package/dist/testUtils.js CHANGED
@@ -1,60 +1,52 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.votingTest = exports.homomorphicMultiplicationTest = exports.testSecureEncryptionAndDecryption = exports.thresholdSetup = exports.getRandomScore = void 0;
4
- const vitest_1 = require("vitest");
5
- const elgamal_1 = require("./elgamal");
6
- const thresholdElgamal_1 = require("./thresholdElgamal");
7
- const utils_1 = require("./utils");
8
- const getRandomScore = (min = 1, max = 10) => Math.floor(Math.random() * (max - min + 1)) + min;
9
- exports.getRandomScore = getRandomScore;
10
- const thresholdSetup = (partiesCount, threshold, primeBits = 2048) => {
11
- const { prime, generator } = (0, utils_1.getGroup)(primeBits);
12
- const keyShares = (0, thresholdElgamal_1.generateKeyShares)(partiesCount, threshold, primeBits);
1
+ import { expect } from 'vitest';
2
+ import { encrypt } from './elgamal';
3
+ import { generateKeyShares, combinePublicKeys, createDecryptionShare, combineDecryptionShares, thresholdDecrypt, } from './thresholdElgamal';
4
+ import { multiplyEncryptedValues, getGroup } from './utils';
5
+ export const getRandomScore = (min = 1, max = 10) => Math.floor(Math.random() * (max - min + 1)) + min;
6
+ export const thresholdSetup = (partiesCount, threshold, primeBits = 2048) => {
7
+ const { prime, generator } = getGroup(primeBits);
8
+ const keyShares = generateKeyShares(partiesCount, threshold, primeBits);
13
9
  const publicKeys = keyShares.map((ks) => ks.partyPublicKey);
14
- const combinedPublicKey = (0, thresholdElgamal_1.combinePublicKeys)(publicKeys, prime);
10
+ const combinedPublicKey = combinePublicKeys(publicKeys, prime);
15
11
  return { keyShares, combinedPublicKey, prime, generator };
16
12
  };
17
- exports.thresholdSetup = thresholdSetup;
18
- const testSecureEncryptionAndDecryption = (participantsCount, threshold, secret) => {
19
- const { keyShares, combinedPublicKey, prime, generator } = (0, exports.thresholdSetup)(participantsCount, threshold);
20
- const encryptedMessage = (0, elgamal_1.encrypt)(secret, prime, generator, combinedPublicKey);
13
+ export const testSecureEncryptionAndDecryption = (participantsCount, threshold, secret) => {
14
+ const { keyShares, combinedPublicKey, prime, generator } = thresholdSetup(participantsCount, threshold);
15
+ const encryptedMessage = encrypt(secret, prime, generator, combinedPublicKey);
21
16
  const selectedDecryptionShares = keyShares
22
17
  .sort(() => Math.random() - 0.5)
23
18
  .slice(0, threshold)
24
- .map((keyShare) => (0, thresholdElgamal_1.createDecryptionShare)(encryptedMessage, keyShare.partyPrivateKey, prime));
25
- const combinedDecryptionShares = (0, thresholdElgamal_1.combineDecryptionShares)(selectedDecryptionShares, prime);
26
- const decryptedMessage = (0, thresholdElgamal_1.thresholdDecrypt)(encryptedMessage, combinedDecryptionShares, prime);
27
- (0, vitest_1.expect)(decryptedMessage).toBe(secret);
19
+ .map((keyShare) => createDecryptionShare(encryptedMessage, keyShare.partyPrivateKey, prime));
20
+ const combinedDecryptionShares = combineDecryptionShares(selectedDecryptionShares, prime);
21
+ const decryptedMessage = thresholdDecrypt(encryptedMessage, combinedDecryptionShares, prime);
22
+ expect(decryptedMessage).toBe(secret);
28
23
  };
29
- exports.testSecureEncryptionAndDecryption = testSecureEncryptionAndDecryption;
30
- const homomorphicMultiplicationTest = (participantsCount, threshold, messages) => {
24
+ export const homomorphicMultiplicationTest = (participantsCount, threshold, messages) => {
31
25
  const expectedProduct = messages.reduce((product, secret) => product * secret, 1);
32
- const { keyShares, combinedPublicKey, prime, generator } = (0, exports.thresholdSetup)(participantsCount, threshold);
33
- const encryptedMessages = messages.map((secret) => (0, elgamal_1.encrypt)(secret, prime, generator, combinedPublicKey));
34
- const encryptedProduct = encryptedMessages.reduce((product, encryptedMessage) => (0, utils_1.multiplyEncryptedValues)(product, encryptedMessage, prime), { c1: 1n, c2: 1n });
26
+ const { keyShares, combinedPublicKey, prime, generator } = thresholdSetup(participantsCount, threshold);
27
+ const encryptedMessages = messages.map((secret) => encrypt(secret, prime, generator, combinedPublicKey));
28
+ const encryptedProduct = encryptedMessages.reduce((product, encryptedMessage) => multiplyEncryptedValues(product, encryptedMessage, prime), { c1: 1n, c2: 1n });
35
29
  const selectedDecryptionShares = keyShares
36
30
  .sort(() => Math.random() - 0.5)
37
31
  .slice(0, threshold)
38
- .map((keyShare) => (0, thresholdElgamal_1.createDecryptionShare)(encryptedProduct, keyShare.partyPrivateKey, prime));
39
- const combinedDecryptionShares = (0, thresholdElgamal_1.combineDecryptionShares)(selectedDecryptionShares, prime);
40
- const decryptedProduct = (0, thresholdElgamal_1.thresholdDecrypt)(encryptedProduct, combinedDecryptionShares, prime);
41
- (0, vitest_1.expect)(decryptedProduct).toBe(expectedProduct);
32
+ .map((keyShare) => createDecryptionShare(encryptedProduct, keyShare.partyPrivateKey, prime));
33
+ const combinedDecryptionShares = combineDecryptionShares(selectedDecryptionShares, prime);
34
+ const decryptedProduct = thresholdDecrypt(encryptedProduct, combinedDecryptionShares, prime);
35
+ expect(decryptedProduct).toBe(expectedProduct);
42
36
  };
43
- exports.homomorphicMultiplicationTest = homomorphicMultiplicationTest;
44
- const votingTest = (participantsCount, threshold, candidatesCount) => {
45
- const { keyShares, combinedPublicKey, prime, generator } = (0, exports.thresholdSetup)(participantsCount, threshold);
46
- const votesMatrix = Array.from({ length: participantsCount }, () => Array.from({ length: candidatesCount }, () => (0, exports.getRandomScore)(1, 10)));
37
+ export const votingTest = (participantsCount, threshold, candidatesCount) => {
38
+ const { keyShares, combinedPublicKey, prime, generator } = thresholdSetup(participantsCount, threshold);
39
+ const votesMatrix = Array.from({ length: participantsCount }, () => Array.from({ length: candidatesCount }, () => getRandomScore(1, 10)));
47
40
  const expectedProducts = Array.from({ length: candidatesCount }, (_, candidateIndex) => votesMatrix.reduce((product, votes) => product * votes[candidateIndex], 1));
48
- const encryptedVotesMatrix = votesMatrix.map((votes) => votes.map((vote) => (0, elgamal_1.encrypt)(vote, prime, generator, combinedPublicKey)));
49
- const encryptedProducts = Array.from({ length: candidatesCount }, (_, candidateIndex) => encryptedVotesMatrix.reduce((product, encryptedVotes) => (0, utils_1.multiplyEncryptedValues)(product, encryptedVotes[candidateIndex], prime), { c1: 1n, c2: 1n }));
41
+ const encryptedVotesMatrix = votesMatrix.map((votes) => votes.map((vote) => encrypt(vote, prime, generator, combinedPublicKey)));
42
+ const encryptedProducts = Array.from({ length: candidatesCount }, (_, candidateIndex) => encryptedVotesMatrix.reduce((product, encryptedVotes) => multiplyEncryptedValues(product, encryptedVotes[candidateIndex], prime), { c1: 1n, c2: 1n }));
50
43
  const partialDecryptionsMatrix = encryptedProducts.map((product) => keyShares
51
44
  .slice(0, threshold)
52
- .map((keyShare) => (0, thresholdElgamal_1.createDecryptionShare)(product, keyShare.partyPrivateKey, prime)));
45
+ .map((keyShare) => createDecryptionShare(product, keyShare.partyPrivateKey, prime)));
53
46
  const decryptedProducts = partialDecryptionsMatrix.map((decryptionShares) => {
54
- const combinedDecryptionShares = (0, thresholdElgamal_1.combineDecryptionShares)(decryptionShares, prime);
47
+ const combinedDecryptionShares = combineDecryptionShares(decryptionShares, prime);
55
48
  const encryptedProduct = encryptedProducts[partialDecryptionsMatrix.indexOf(decryptionShares)];
56
- return (0, thresholdElgamal_1.thresholdDecrypt)(encryptedProduct, combinedDecryptionShares, prime);
49
+ return thresholdDecrypt(encryptedProduct, combinedDecryptionShares, prime);
57
50
  });
58
- (0, vitest_1.expect)(decryptedProducts).toEqual(expectedProducts);
51
+ expect(decryptedProducts).toEqual(expectedProducts);
59
52
  };
60
- exports.votingTest = votingTest;
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.thresholdDecrypt = exports.combineDecryptionShares = exports.createDecryptionShare = exports.combinePublicKeys = exports.generateKeyShares = exports.generateSingleKeyShare = exports.evaluatePolynomial = void 0;
4
- const bigint_mod_arith_1 = require("bigint-mod-arith");
5
- const utils_1 = require("./utils");
1
+ import { modPow, modInv } from 'bigint-mod-arith';
2
+ import { generatePolynomial, getGroup } from './utils';
6
3
  /**
7
4
  * Evaluates a polynomial at a given point using modular arithmetic.
8
5
  *
@@ -11,14 +8,13 @@ const utils_1 = require("./utils");
11
8
  * @param {bigint} prime - The prime modulus.
12
9
  * @returns {bigint} The result of the polynomial evaluation.
13
10
  */
14
- const evaluatePolynomial = (polynomial, x, prime) => {
11
+ export const evaluatePolynomial = (polynomial, x, prime) => {
15
12
  let result = 0n;
16
13
  for (let i = 0; i < polynomial.length; i++) {
17
14
  result = (result + polynomial[i] * BigInt(x) ** BigInt(i)) % prime;
18
15
  }
19
16
  return result;
20
17
  };
21
- exports.evaluatePolynomial = evaluatePolynomial;
22
18
  /**
23
19
  * Generates a single key share for a participant in a threshold ElGamal cryptosystem.
24
20
  *
@@ -27,20 +23,19 @@ exports.evaluatePolynomial = evaluatePolynomial;
27
23
  * @param {2048 | 3072 | 4096} primeBits - The bit length of the prime modulus (default: 2048).
28
24
  * @returns {PartyKeyPair} The key share containing a private and public key share for the participant.
29
25
  */
30
- const generateSingleKeyShare = (index, threshold, primeBits = 2048) => {
31
- const group = (0, utils_1.getGroup)(primeBits);
26
+ export const generateSingleKeyShare = (index, threshold, primeBits = 2048) => {
27
+ const group = getGroup(primeBits);
32
28
  const prime = group.prime;
33
29
  const generator = group.generator;
34
- const polynomial = (0, utils_1.generatePolynomial)(threshold, prime);
35
- let partyPrivateKey = (0, exports.evaluatePolynomial)(polynomial, index, prime);
30
+ const polynomial = generatePolynomial(threshold, prime);
31
+ let partyPrivateKey = evaluatePolynomial(polynomial, index, prime);
36
32
  // Ensure non-zero private key, adjusting index if necessary
37
33
  while (partyPrivateKey === 0n) {
38
- partyPrivateKey = (0, exports.evaluatePolynomial)(polynomial, index + 1, prime);
34
+ partyPrivateKey = evaluatePolynomial(polynomial, index + 1, prime);
39
35
  }
40
- const partyPublicKey = (0, bigint_mod_arith_1.modPow)(generator, partyPrivateKey, prime);
36
+ const partyPublicKey = modPow(generator, partyPrivateKey, prime);
41
37
  return { partyPrivateKey, partyPublicKey };
42
38
  };
43
- exports.generateSingleKeyShare = generateSingleKeyShare;
44
39
  /**
45
40
  * Generates key shares for a threshold ElGamal cryptosystem.
46
41
  *
@@ -49,15 +44,14 @@ exports.generateSingleKeyShare = generateSingleKeyShare;
49
44
  * @param {2048 | 3072 | 4096} primeBits - The bit length of the prime modulus (default: 2048).
50
45
  * @returns {PartyKeyPair[]} An array of key shares, each containing a private and public key share.
51
46
  */
52
- const generateKeyShares = (n, threshold, primeBits = 2048) => {
47
+ export const generateKeyShares = (n, threshold, primeBits = 2048) => {
53
48
  const keyShares = [];
54
49
  for (let i = 1; i <= n; i++) {
55
- const keyShare = (0, exports.generateSingleKeyShare)(i, threshold, primeBits);
50
+ const keyShare = generateSingleKeyShare(i, threshold, primeBits);
56
51
  keyShares.push(keyShare);
57
52
  }
58
53
  return keyShares;
59
54
  };
60
- exports.generateKeyShares = generateKeyShares;
61
55
  /**
62
56
  * Combines multiple public keys into a single public key.
63
57
  *
@@ -65,8 +59,7 @@ exports.generateKeyShares = generateKeyShares;
65
59
  * @param {bigint} prime - The prime modulus used in the ElGamal system.
66
60
  * @returns {bigint} The combined public key.
67
61
  */
68
- const combinePublicKeys = (publicKeys, prime) => publicKeys.reduce((acc, current) => (acc * current) % prime, 1n);
69
- exports.combinePublicKeys = combinePublicKeys;
62
+ export const combinePublicKeys = (publicKeys, prime) => publicKeys.reduce((acc, current) => (acc * current) % prime, 1n);
70
63
  /**
71
64
  * Performs a partial decryption on a ciphertext using an individual's private key share.
72
65
  *
@@ -75,8 +68,7 @@ exports.combinePublicKeys = combinePublicKeys;
75
68
  * @param {bigint} prime - The prime modulus used in the ElGamal system.
76
69
  * @returns {bigint} The result of the partial decryption.
77
70
  */
78
- const createDecryptionShare = (encryptedMessage, partyPrivateKey, prime) => (0, bigint_mod_arith_1.modPow)(encryptedMessage.c1, partyPrivateKey, prime);
79
- exports.createDecryptionShare = createDecryptionShare;
71
+ export const createDecryptionShare = (encryptedMessage, partyPrivateKey, prime) => modPow(encryptedMessage.c1, partyPrivateKey, prime);
80
72
  /**
81
73
  * Combines partial decryptions from multiple parties into a single decryption factor.
82
74
  *
@@ -84,14 +76,13 @@ exports.createDecryptionShare = createDecryptionShare;
84
76
  * @param {bigint} prime - The prime modulus used in the ElGamal system.
85
77
  * @returns {bigint} The combined decryption factor.
86
78
  */
87
- const combineDecryptionShares = (decryptionShares, prime) => {
79
+ export const combineDecryptionShares = (decryptionShares, prime) => {
88
80
  let result = 1n;
89
81
  for (const partialDecryption of decryptionShares) {
90
82
  result = (result * partialDecryption) % prime;
91
83
  }
92
84
  return result;
93
85
  };
94
- exports.combineDecryptionShares = combineDecryptionShares;
95
86
  /**
96
87
  * Decrypts an encrypted secret using the combined partial decryptions in a threshold ElGamal scheme.
97
88
  *
@@ -100,9 +91,8 @@ exports.combineDecryptionShares = combineDecryptionShares;
100
91
  * @param {bigint} prime - The prime modulus used in the ElGamal system.
101
92
  * @returns {number} The decrypted secret, assuming it was small enough to be directly encrypted.
102
93
  */
103
- const thresholdDecrypt = (encryptedMessage, combinedDecryptionShares, prime) => {
104
- const combinedDecryptionInverse = (0, bigint_mod_arith_1.modInv)(combinedDecryptionShares, prime);
94
+ export const thresholdDecrypt = (encryptedMessage, combinedDecryptionShares, prime) => {
95
+ const combinedDecryptionInverse = modInv(combinedDecryptionShares, prime);
105
96
  const plaintext = (encryptedMessage.c2 * combinedDecryptionInverse) % prime;
106
97
  return Number(plaintext);
107
98
  };
108
- exports.thresholdDecrypt = thresholdDecrypt;
package/dist/types.js CHANGED
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
package/dist/utils.js CHANGED
@@ -1,48 +1,40 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.generatePolynomial = exports.multiplyEncryptedValues = exports.getRandomBigIntegerInRange = exports.getGroup = void 0;
7
- const random_bigint_1 = __importDefault(require("random-bigint"));
8
- const constants_1 = require("./constants");
1
+ import randomBigint from 'random-bigint';
2
+ import { GROUPS } from './constants';
9
3
  /**
10
4
  * Retrieves the group parameters for a given prime bit length.
11
5
  *
12
6
  * @param {2048 | 3072 | 4096} primeBits - The bit length of the prime modulus (2048, 3072, or 4096).
13
7
  * @returns {Object} The group parameters including prime and generator.
14
8
  */
15
- const getGroup = (primeBits) => {
9
+ export const getGroup = (primeBits) => {
16
10
  switch (primeBits) {
17
11
  case 2048:
18
- return constants_1.GROUPS.ffdhe2048;
12
+ return GROUPS.ffdhe2048;
19
13
  case 3072:
20
- return constants_1.GROUPS.ffdhe3072;
14
+ return GROUPS.ffdhe3072;
21
15
  case 4096:
22
- return constants_1.GROUPS.ffdhe4096;
16
+ return GROUPS.ffdhe4096;
23
17
  default:
24
18
  throw new Error('Unsupported bit length');
25
19
  }
26
20
  };
27
- exports.getGroup = getGroup;
28
21
  /**
29
22
  * Generates a random bigint within a specified range.
30
23
  * @param {bigint} min - The minimum value (inclusive).
31
24
  * @param {bigint} max - The maximum value (exclusive).
32
25
  * @returns {bigint} A random bigint within the specified range.
33
26
  */
34
- const getRandomBigIntegerInRange = (min, max) => {
27
+ export const getRandomBigIntegerInRange = (min, max) => {
35
28
  const range = max - min + 1n;
36
29
  // Determine the number of bits needed for the range
37
30
  const bitsNeeded = range.toString(2).length;
38
31
  // Generate a random bigint within the calculated bits
39
- let num = (0, random_bigint_1.default)(bitsNeeded);
32
+ let num = randomBigint(bitsNeeded);
40
33
  // Adjust the number to our range
41
34
  num = num % range;
42
35
  // Add the minimum to align with our desired range
43
36
  return min + num;
44
37
  };
45
- exports.getRandomBigIntegerInRange = getRandomBigIntegerInRange;
46
38
  /**
47
39
  * Performs homomorphic multiplication on two encrypted values, allowing for encrypted arithmetic operations.
48
40
  * @param {EncryptedMessage} value1 - The first encrypted value.
@@ -50,12 +42,11 @@ exports.getRandomBigIntegerInRange = getRandomBigIntegerInRange;
50
42
  * @param {bigint} prime - The prime modulus used in the encryption system.
51
43
  * @returns {EncryptedMessage} The result of the multiplication, as a new encrypted message.
52
44
  */
53
- const multiplyEncryptedValues = (value1, value2, prime) => {
45
+ export const multiplyEncryptedValues = (value1, value2, prime) => {
54
46
  const c1Multiplied = (value1.c1 * value2.c1) % prime;
55
47
  const c2Multiplied = (value1.c2 * value2.c2) % prime;
56
48
  return { c1: c1Multiplied, c2: c2Multiplied };
57
49
  };
58
- exports.multiplyEncryptedValues = multiplyEncryptedValues;
59
50
  /**
60
51
  * Generates a random polynomial of a specified degree, to be used in Shamir's Secret Sharing scheme.
61
52
  * The polynomial is of the form f(x) = a0 + a1*x + a2*x^2 + ... + a_{threshold-1}*x^{threshold-1},
@@ -64,11 +55,10 @@ exports.multiplyEncryptedValues = multiplyEncryptedValues;
64
55
  * @param {bigint} prime - The prime modulus used in the system, to ensure operations are performed in a finite field.
65
56
  * @returns {bigint[]} An array representing the polynomial coefficients `[a0, a1, ..., a_{threshold-1}]`.
66
57
  */
67
- const generatePolynomial = (threshold, prime) => {
68
- const polynomial = [(0, exports.getRandomBigIntegerInRange)(2n, prime - 1n)]; // constant term is the "master" private key
58
+ export const generatePolynomial = (threshold, prime) => {
59
+ const polynomial = [getRandomBigIntegerInRange(2n, prime - 1n)]; // constant term is the "master" private key
69
60
  for (let i = 1; i < threshold; i++) {
70
- polynomial.push((0, exports.getRandomBigIntegerInRange)(0n, prime - 1n)); // random coefficients
61
+ polynomial.push(getRandomBigIntegerInRange(0n, prime - 1n)); // random coefficients
71
62
  }
72
63
  return polynomial;
73
64
  };
74
- exports.generatePolynomial = generatePolynomial;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "threshold-elgamal",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "author": "Piotr Piech <piotr@piech.dev>",
5
5
  "license": "MIT",
6
6
  "description": "Threshold ElGamal in TypeScript",