@arcium-hq/client 0.1.46 → 0.1.47
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 +15 -8
- package/build/index.cjs +695 -83
- package/build/index.d.ts +432 -23
- package/build/index.mjs +685 -77
- package/package.json +1 -1
package/build/index.cjs
CHANGED
|
@@ -6,6 +6,8 @@ var ed25519 = require('@noble/curves/ed25519');
|
|
|
6
6
|
var anchor = require('@coral-xyz/anchor');
|
|
7
7
|
var sha3 = require('@noble/hashes/sha3');
|
|
8
8
|
var modular = require('@noble/curves/abstract/modular');
|
|
9
|
+
var utils = require('@noble/hashes/utils');
|
|
10
|
+
var edwards = require('@noble/curves/abstract/edwards');
|
|
9
11
|
var web3_js = require('@solana/web3.js');
|
|
10
12
|
|
|
11
13
|
function _interopNamespaceDefault(e) {
|
|
@@ -27,7 +29,12 @@ function _interopNamespaceDefault(e) {
|
|
|
27
29
|
|
|
28
30
|
var anchor__namespace = /*#__PURE__*/_interopNamespaceDefault(anchor);
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Converts a bigint to an array of bits (least significant to most significant, in 2's complement representation).
|
|
34
|
+
* @param x - The bigint to convert.
|
|
35
|
+
* @param binSize - The number of bits to use in the representation.
|
|
36
|
+
* @returns An array of booleans representing the bits of x.
|
|
37
|
+
*/
|
|
31
38
|
function toBinLE(x, binSize) {
|
|
32
39
|
const res = [];
|
|
33
40
|
for (let i = 0; i < binSize; ++i) {
|
|
@@ -35,7 +42,11 @@ function toBinLE(x, binSize) {
|
|
|
35
42
|
}
|
|
36
43
|
return res;
|
|
37
44
|
}
|
|
38
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Converts an array of bits (least significant to most significant, in 2's complement representation) to a bigint.
|
|
47
|
+
* @param xBin - The array of bits to convert.
|
|
48
|
+
* @returns The bigint represented by the bit array.
|
|
49
|
+
*/
|
|
39
50
|
function fromBinLE(xBin) {
|
|
40
51
|
let res = 0n;
|
|
41
52
|
for (let i = 0; i < xBin.length - 1; ++i) {
|
|
@@ -43,8 +54,14 @@ function fromBinLE(xBin) {
|
|
|
43
54
|
}
|
|
44
55
|
return res - (BigInt(xBin[xBin.length - 1]) << BigInt(xBin.length - 1));
|
|
45
56
|
}
|
|
46
|
-
|
|
47
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Binary adder between x and y (assumes xBin and yBin are of the same length and large enough to represent the sum).
|
|
59
|
+
* @param xBin - The first operand as a bit array.
|
|
60
|
+
* @param yBin - The second operand as a bit array.
|
|
61
|
+
* @param carryIn - The initial carry-in value.
|
|
62
|
+
* @param binSize - The number of bits to use in the operation.
|
|
63
|
+
* @returns The sum as a bit array.
|
|
64
|
+
*/
|
|
48
65
|
function adder(xBin, yBin, carryIn, binSize) {
|
|
49
66
|
const res = [];
|
|
50
67
|
let carry = carryIn;
|
|
@@ -59,12 +76,24 @@ function adder(xBin, yBin, carryIn, binSize) {
|
|
|
59
76
|
}
|
|
60
77
|
return res;
|
|
61
78
|
}
|
|
62
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Constant-time addition of two bigints, using 2's complement representation.
|
|
81
|
+
* @param x - The first operand.
|
|
82
|
+
* @param y - The second operand.
|
|
83
|
+
* @param binSize - The number of bits to use in the operation.
|
|
84
|
+
* @returns The sum as a bigint.
|
|
85
|
+
*/
|
|
63
86
|
function ctAdd(x, y, binSize) {
|
|
64
87
|
const resBin = adder(toBinLE(x, binSize), toBinLE(y, binSize), false, binSize);
|
|
65
88
|
return fromBinLE(resBin);
|
|
66
89
|
}
|
|
67
|
-
|
|
90
|
+
/**
|
|
91
|
+
* Constant-time subtraction of two bigints, using 2's complement representation.
|
|
92
|
+
* @param x - The first operand.
|
|
93
|
+
* @param y - The second operand.
|
|
94
|
+
* @param binSize - The number of bits to use in the operation.
|
|
95
|
+
* @returns The difference as a bigint.
|
|
96
|
+
*/
|
|
68
97
|
function ctSub(x, y, binSize) {
|
|
69
98
|
const yBin = toBinLE(y, binSize);
|
|
70
99
|
const yBinNot = [];
|
|
@@ -74,23 +103,44 @@ function ctSub(x, y, binSize) {
|
|
|
74
103
|
const resBin = adder(toBinLE(x, binSize), yBinNot, true, binSize);
|
|
75
104
|
return fromBinLE(resBin);
|
|
76
105
|
}
|
|
77
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Returns the sign bit of a bigint in constant time.
|
|
108
|
+
* @param x - The bigint to check.
|
|
109
|
+
* @param binSize - The bit position to check (typically the highest bit).
|
|
110
|
+
* @returns True if the sign bit is set, false otherwise.
|
|
111
|
+
*/
|
|
78
112
|
function ctSignBit(x, binSize) {
|
|
79
113
|
return ((x >> binSize) & 1n) === 1n;
|
|
80
114
|
}
|
|
81
|
-
|
|
115
|
+
/**
|
|
116
|
+
* Constant-time less-than comparison for two bigints.
|
|
117
|
+
* @param x - The first operand.
|
|
118
|
+
* @param y - The second operand.
|
|
119
|
+
* @param binSize - The number of bits to use in the operation.
|
|
120
|
+
* @returns True if x < y, false otherwise.
|
|
121
|
+
*/
|
|
82
122
|
function ctLt(x, y, binSize) {
|
|
83
123
|
return ctSignBit(ctSub(x, y, binSize), binSize);
|
|
84
124
|
}
|
|
85
|
-
|
|
125
|
+
/**
|
|
126
|
+
* Constant-time select between two bigints based on a boolean condition.
|
|
127
|
+
* @param b - The condition; if true, select x, otherwise select y.
|
|
128
|
+
* @param x - The value to select if b is true.
|
|
129
|
+
* @param y - The value to select if b is false.
|
|
130
|
+
* @param binSize - The number of bits to use in the operation.
|
|
131
|
+
* @returns The selected bigint.
|
|
132
|
+
*/
|
|
86
133
|
function ctSelect(b, x, y, binSize) {
|
|
87
134
|
return ctAdd(y, BigInt(b) * (ctSub(x, y, binSize)), binSize);
|
|
88
135
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
136
|
+
/**
|
|
137
|
+
* Checks if a bigint fits in the range -2^binSize <= x < 2^binSize.
|
|
138
|
+
* Not constant-time for arbitrary x, but is constant-time for all inputs for which the function returns true.
|
|
139
|
+
* If you assert your inputs satisfy verifyBinSize(x, binSize), you need not care about the non constant-timeness of this function.
|
|
140
|
+
* @param x - The bigint to check.
|
|
141
|
+
* @param binSize - The number of bits to use in the check.
|
|
142
|
+
* @returns True if x fits in the range, false otherwise.
|
|
143
|
+
*/
|
|
94
144
|
function verifyBinSize(x, binSize) {
|
|
95
145
|
const bin = (x >> binSize).toString(2);
|
|
96
146
|
return bin === '0' || bin === '-1';
|
|
@@ -278,10 +328,17 @@ function randMatrix(field, nrows, ncols) {
|
|
|
278
328
|
return new Matrix(field, data);
|
|
279
329
|
}
|
|
280
330
|
|
|
331
|
+
/**
|
|
332
|
+
* Curve25519 base field as an IField instance.
|
|
333
|
+
*/
|
|
281
334
|
const CURVE25519_BASE_FIELD = ed25519.ed25519.CURVE.Fp;
|
|
282
335
|
// hardcode security level to 128 bits
|
|
283
336
|
const SECURITY_LEVEL = 128;
|
|
284
337
|
// We refer to https://tosc.iacr.org/index.php/ToSC/article/view/8695/8287 for more details.
|
|
338
|
+
/**
|
|
339
|
+
* Description and parameters for the Rescue cipher or hash function, including round constants, MDS matrix, and key schedule.
|
|
340
|
+
* See: https://tosc.iacr.org/index.php/ToSC/article/view/8695/8287
|
|
341
|
+
*/
|
|
285
342
|
class RescueDesc {
|
|
286
343
|
mode;
|
|
287
344
|
field;
|
|
@@ -297,6 +354,12 @@ class RescueDesc {
|
|
|
297
354
|
mdsMatInverse;
|
|
298
355
|
// The round keys, needed for encryption and decryption.
|
|
299
356
|
roundKeys;
|
|
357
|
+
/**
|
|
358
|
+
* Constructs a RescueDesc for a given field and mode (cipher or hash).
|
|
359
|
+
* Initializes round constants, MDS matrix, and key schedule.
|
|
360
|
+
* @param field - The field to use (e.g., CURVE25519_BASE_FIELD).
|
|
361
|
+
* @param mode - The mode: block cipher or hash function.
|
|
362
|
+
*/
|
|
300
363
|
constructor(field, mode) {
|
|
301
364
|
this.field = field;
|
|
302
365
|
this.mode = mode;
|
|
@@ -342,6 +405,11 @@ class RescueDesc {
|
|
|
342
405
|
}
|
|
343
406
|
}
|
|
344
407
|
}
|
|
408
|
+
/**
|
|
409
|
+
* Samples round constants for the Rescue permutation, using SHAKE256.
|
|
410
|
+
* @param nRounds - The number of rounds.
|
|
411
|
+
* @returns An array of round constant matrices.
|
|
412
|
+
*/
|
|
345
413
|
sampleConstants(nRounds) {
|
|
346
414
|
const field = this.field;
|
|
347
415
|
const m = this.m;
|
|
@@ -415,9 +483,19 @@ class RescueDesc {
|
|
|
415
483
|
default: return [];
|
|
416
484
|
}
|
|
417
485
|
}
|
|
486
|
+
/**
|
|
487
|
+
* Applies the Rescue permutation to a state matrix.
|
|
488
|
+
* @param state - The input state matrix.
|
|
489
|
+
* @returns The permuted state matrix.
|
|
490
|
+
*/
|
|
418
491
|
permute(state) {
|
|
419
492
|
return rescuePermutation(this.mode, this.alpha, this.alphaInverse, this.mdsMat, this.roundKeys, state)[2 * this.nRounds];
|
|
420
493
|
}
|
|
494
|
+
/**
|
|
495
|
+
* Applies the inverse Rescue permutation to a state matrix.
|
|
496
|
+
* @param state - The input state matrix.
|
|
497
|
+
* @returns The inverse-permuted state matrix.
|
|
498
|
+
*/
|
|
421
499
|
permuteInverse(state) {
|
|
422
500
|
return rescuePermutationInverse(this.mode, this.alpha, this.alphaInverse, this.mdsMatInverse, this.roundKeys, state)[2 * this.nRounds];
|
|
423
501
|
}
|
|
@@ -589,7 +667,17 @@ function toVec(data) {
|
|
|
589
667
|
return dataVec;
|
|
590
668
|
}
|
|
591
669
|
|
|
670
|
+
/**
|
|
671
|
+
* Number of mantissa bits for double-precision floating point values.
|
|
672
|
+
*/
|
|
592
673
|
const DOUBLE_PRECISION_MANTISSA = 52;
|
|
674
|
+
/**
|
|
675
|
+
* Encodes a value as a bigint suitable for Rescue encryption, handling booleans, bigints, and numbers.
|
|
676
|
+
* The encoding is performed in constant-time to avoid leaking information through timing side-channels.
|
|
677
|
+
* Throws if the value is out of the supported range for the field.
|
|
678
|
+
* @param v - The value to encode (MScalar, MFloat, or MBoolean).
|
|
679
|
+
* @returns The encoded value as a bigint.
|
|
680
|
+
*/
|
|
593
681
|
function encodeAsRescueEncryptable(v) {
|
|
594
682
|
if (typeof v === 'boolean') {
|
|
595
683
|
return v ? 1n : 0n;
|
|
@@ -618,6 +706,13 @@ function encodeAsRescueEncryptable(v) {
|
|
|
618
706
|
// but typescript kept thinking ixInput: readonly null[] and I can't figure out why, so we do this hack
|
|
619
707
|
// for now.
|
|
620
708
|
// TODO: Revisit and fix the types correctly.
|
|
709
|
+
/**
|
|
710
|
+
* Secret-shares the inputs for a confidential instruction, encoding each value as needed and splitting it for each node's public key.
|
|
711
|
+
* @param ixInput - The array of input values to secret-share.
|
|
712
|
+
* @param nodeX25519Keys - The array of node X25519 public keys to share with.
|
|
713
|
+
* @returns A 2D array of SecretShare objects, one array per input value.
|
|
714
|
+
* @throws Error if an input type cannot be parsed.
|
|
715
|
+
*/
|
|
621
716
|
function secretShareInputs(ixInput, nodeX25519Keys) {
|
|
622
717
|
const shares = [];
|
|
623
718
|
// Need to explicitly tell typescript input can be any of these, else it only thinks {} is possible
|
|
@@ -669,9 +764,16 @@ function getBinSize(max) {
|
|
|
669
764
|
return BigInt(Math.floor(Math.log2(Number(max)))) + 3n;
|
|
670
765
|
}
|
|
671
766
|
|
|
672
|
-
|
|
767
|
+
/**
|
|
768
|
+
* Scalar field prime modulus for Curve25519: 2^252 + 27742317777372353535851937790883648493
|
|
769
|
+
*/
|
|
673
770
|
const CURVE25519_SCALAR_FIELD_MODULUS = ed25519.ed25519.CURVE.n;
|
|
674
|
-
|
|
771
|
+
/**
|
|
772
|
+
* Encrypts a value into the format expected by the DA layer, using secret sharing and encryption for each node's public key.
|
|
773
|
+
* @param val - The value to secret-share and encrypt.
|
|
774
|
+
* @param nodeX25519Keys - The array of node X25519 public keys.
|
|
775
|
+
* @returns An array of SecretShare objects, one for each node.
|
|
776
|
+
*/
|
|
675
777
|
function secretShareValue(val, nodeX25519Keys) {
|
|
676
778
|
const rawShares = genRawShares(val, nodeX25519Keys.length, CURVE25519_SCALAR_FIELD_MODULUS);
|
|
677
779
|
return zip(rawShares, nodeX25519Keys).map(([share, key]) => encryptForDA(key, share, CURVE25519_SCALAR_FIELD_MODULUS));
|
|
@@ -690,10 +792,10 @@ function newSecretShare(ciphertext, nonce, ephemeralPublicKey) {
|
|
|
690
792
|
}
|
|
691
793
|
/**
|
|
692
794
|
* Generates secret shares for a given value in the Curve25519 field.
|
|
693
|
-
* @param secret The secret value to be shared (as a BigInt)
|
|
694
|
-
* @param n The number of shares to generate
|
|
695
|
-
* @param mod The modulo of the field over which to generate shares
|
|
696
|
-
* @returns An array of n secret shares
|
|
795
|
+
* @param secret - The secret value to be shared (as a BigInt).
|
|
796
|
+
* @param n - The number of shares to generate.
|
|
797
|
+
* @param mod - The modulo of the field over which to generate shares (default: CURVE25519_SCALAR_FIELD_MODULUS).
|
|
798
|
+
* @returns An array of n secret shares as bigints.
|
|
697
799
|
*/
|
|
698
800
|
function genRawShares(secret, n, mod = CURVE25519_SCALAR_FIELD_MODULUS) {
|
|
699
801
|
const shares = [];
|
|
@@ -709,11 +811,11 @@ function genRawShares(secret, n, mod = CURVE25519_SCALAR_FIELD_MODULUS) {
|
|
|
709
811
|
}
|
|
710
812
|
/// ENCRYPTION
|
|
711
813
|
/**
|
|
712
|
-
* Encrypts a field element for the DA layer.
|
|
713
|
-
* @param publicKey The recipient's x25519 public key
|
|
714
|
-
* @param valueToEncrypt The bigint value to encrypt
|
|
715
|
-
* @param modulo Bound on the value
|
|
716
|
-
* @returns An object containing the ciphertext and ephemeral public key.
|
|
814
|
+
* Encrypts a field element for the DA layer using the recipient's x25519 public key.
|
|
815
|
+
* @param publicKey - The recipient's x25519 public key.
|
|
816
|
+
* @param valueToEncrypt - The bigint value to encrypt.
|
|
817
|
+
* @param modulo - Bound on the value (default: CURVE25519_SCALAR_FIELD_MODULUS).
|
|
818
|
+
* @returns An object containing the ciphertext, nonce, and ephemeral public key.
|
|
717
819
|
*/
|
|
718
820
|
function encryptForDA(publicKey, valueToEncrypt, modulo = CURVE25519_SCALAR_FIELD_MODULUS) {
|
|
719
821
|
// Check if the value to encrypt is smaller than the modulo
|
|
@@ -729,6 +831,12 @@ function encryptForDA(publicKey, valueToEncrypt, modulo = CURVE25519_SCALAR_FIEL
|
|
|
729
831
|
const { ciphertext, nonce } = aesCtrEncrypt(valueToEncrypt, sharedSecret);
|
|
730
832
|
return newSecretShare(ciphertext, nonce, ephemeralPublicKey);
|
|
731
833
|
}
|
|
834
|
+
/**
|
|
835
|
+
* Computes a shared encryption key using ECDH (x25519) and hashes it with blake2s.
|
|
836
|
+
* @param privKey - The private key as a Uint8Array.
|
|
837
|
+
* @param pubKey - The public key as a Uint8Array.
|
|
838
|
+
* @returns The derived encryption key as a Uint8Array.
|
|
839
|
+
*/
|
|
732
840
|
function getEncryptionKey(privKey, pubKey) {
|
|
733
841
|
const sharedSecret = ed25519.x25519.getSharedSecret(privKey, pubKey);
|
|
734
842
|
return blake2s.blake2s(sharedSecret);
|
|
@@ -762,9 +870,10 @@ function aesCtrEncrypt(val, key) {
|
|
|
762
870
|
}
|
|
763
871
|
/// HELPERS
|
|
764
872
|
/**
|
|
765
|
-
* Generates a random
|
|
873
|
+
* Generates a random value within the field bound by q.
|
|
874
|
+
* @param q - The upper bound (exclusive) for the random value.
|
|
766
875
|
* @returns A random bigint value between 0 and q-1.
|
|
767
|
-
*/
|
|
876
|
+
*/
|
|
768
877
|
function generateRandomFieldElem(q) {
|
|
769
878
|
const byteLength = (q.toString(2).length + 7) >> 3;
|
|
770
879
|
let r;
|
|
@@ -774,10 +883,22 @@ function generateRandomFieldElem(q) {
|
|
|
774
883
|
} while (r >= q);
|
|
775
884
|
return r;
|
|
776
885
|
}
|
|
777
|
-
|
|
886
|
+
/**
|
|
887
|
+
* Computes the positive modulo of a over m.
|
|
888
|
+
* @param a - The dividend.
|
|
889
|
+
* @param m - The modulus.
|
|
890
|
+
* @returns The positive remainder of a mod m.
|
|
891
|
+
*/
|
|
778
892
|
function positiveModulo(a, m) {
|
|
779
893
|
return ((a % m) + m) % m;
|
|
780
894
|
}
|
|
895
|
+
/**
|
|
896
|
+
* Serializes a bigint to a little-endian Uint8Array of the specified length.
|
|
897
|
+
* @param val - The bigint value to serialize.
|
|
898
|
+
* @param lengthInBytes - The desired length of the output array.
|
|
899
|
+
* @returns The serialized value as a Uint8Array.
|
|
900
|
+
* @throws Error if the value is too large for the specified length.
|
|
901
|
+
*/
|
|
781
902
|
function serializeLE(val, lengthInBytes) {
|
|
782
903
|
const result = new Uint8Array(lengthInBytes);
|
|
783
904
|
let tempVal = val;
|
|
@@ -790,6 +911,11 @@ function serializeLE(val, lengthInBytes) {
|
|
|
790
911
|
}
|
|
791
912
|
return result;
|
|
792
913
|
}
|
|
914
|
+
/**
|
|
915
|
+
* Deserializes a little-endian Uint8Array to a bigint.
|
|
916
|
+
* @param bytes - The Uint8Array to deserialize.
|
|
917
|
+
* @returns The deserialized bigint value.
|
|
918
|
+
*/
|
|
793
919
|
function deserializeLE(bytes) {
|
|
794
920
|
let result = BigInt(0);
|
|
795
921
|
for (let i = 0; i < bytes.length; i++) {
|
|
@@ -798,6 +924,11 @@ function deserializeLE(bytes) {
|
|
|
798
924
|
return result;
|
|
799
925
|
}
|
|
800
926
|
// GENERAL
|
|
927
|
+
/**
|
|
928
|
+
* Computes the SHA-256 hash of an array of Uint8Arrays.
|
|
929
|
+
* @param byteArrays - The arrays to hash.
|
|
930
|
+
* @returns The SHA-256 hash as a Buffer.
|
|
931
|
+
*/
|
|
801
932
|
function sha256(byteArrays) {
|
|
802
933
|
const hash = crypto.createHash('sha256');
|
|
803
934
|
byteArrays.forEach((byteArray) => {
|
|
@@ -806,19 +937,28 @@ function sha256(byteArrays) {
|
|
|
806
937
|
return hash.digest();
|
|
807
938
|
}
|
|
808
939
|
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
940
|
+
/**
|
|
941
|
+
* The Rescue-Prime hash function, as described in https://eprint.iacr.org/2020/1143.pdf.
|
|
942
|
+
* Used with fixed m = 6 and capacity = 1 (rate = 5). According to Section 2.2, this offers log2(CURVE25519_BASE_FIELD.ORDER) / 2 bits of security against collision, preimage, and second-preimage attacks.
|
|
943
|
+
* See the referenced paper for further details.
|
|
944
|
+
*/
|
|
813
945
|
class RescuePrimeHash {
|
|
814
946
|
desc;
|
|
815
947
|
rate;
|
|
948
|
+
/**
|
|
949
|
+
* Constructs a RescuePrimeHash instance with m = 6 and capacity = 1.
|
|
950
|
+
*/
|
|
816
951
|
constructor() {
|
|
817
952
|
this.desc = new RescueDesc(CURVE25519_BASE_FIELD, { kind: 'hash', m: 6, capacity: 1 });
|
|
818
953
|
this.rate = 6 - 1;
|
|
819
954
|
}
|
|
820
955
|
// This is Algorithm 1 from https://eprint.iacr.org/2020/1143.pdf, though with the padding (see Algorithm 2).
|
|
821
956
|
// The hash function outputs this.rate elements.
|
|
957
|
+
/**
|
|
958
|
+
* Computes the Rescue-Prime hash of a message, with padding as described in Algorithm 2 of the paper.
|
|
959
|
+
* @param message - The input message as an array of bigints.
|
|
960
|
+
* @returns The hash output as an array of bigints (length = rate).
|
|
961
|
+
*/
|
|
822
962
|
digest(message) {
|
|
823
963
|
message.push(1n);
|
|
824
964
|
while (message.length % this.rate !== 0) {
|
|
@@ -848,21 +988,33 @@ class RescuePrimeHash {
|
|
|
848
988
|
}
|
|
849
989
|
}
|
|
850
990
|
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
991
|
+
/**
|
|
992
|
+
* HMACRescuePrime provides a message authentication code (MAC) using the Rescue-Prime hash function.
|
|
993
|
+
* Rescue-Prime is based on the sponge construction, which allows the use of a simpler MAC in place of the traditional HMAC.
|
|
994
|
+
* For more details and explanations, see: https://keccak.team/files/SpongeFunctions.pdf (Appendix B) or https://keccak.team/keccak_strengths.html.
|
|
995
|
+
*/
|
|
855
996
|
class HMACRescuePrime {
|
|
856
997
|
hasher;
|
|
998
|
+
/**
|
|
999
|
+
* Constructs a new HMACRescuePrime instance.
|
|
1000
|
+
*/
|
|
857
1001
|
constructor() {
|
|
858
1002
|
this.hasher = new RescuePrimeHash();
|
|
859
1003
|
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Computes the HMAC (or MAC) digest of a message with a given key using Rescue-Prime.
|
|
1006
|
+
* The key is padded to the hash function's rate, then concatenated with the message.
|
|
1007
|
+
* @param key - The key as an array of bigints.
|
|
1008
|
+
* @param message - The message as an array of bigints.
|
|
1009
|
+
* @returns The MAC digest as an array of bigints.
|
|
1010
|
+
* @throws Error if the key is longer than the hash function's rate.
|
|
1011
|
+
*/
|
|
860
1012
|
digest(key, message) {
|
|
861
1013
|
// HMAC-digest(key, message) = hasher.digest(key || message), since Rescue-Prime is based on
|
|
862
1014
|
// the sponge construction.
|
|
863
1015
|
// We follow https://datatracker.ietf.org/doc/html/rfc2104, though since Rescue-Prime is not based
|
|
864
1016
|
// on the Merkle-Damgard construction we cannot have an exact anology between the
|
|
865
|
-
// parameters. For our purpose, we set B = L = hasher.rate
|
|
1017
|
+
// parameters. For our purpose, we set B = L = hasher.rate.
|
|
866
1018
|
if (key.length > this.hasher.rate) {
|
|
867
1019
|
throw Error(`length of key is supposed to be at most the hash function's rate (found ${key.length} and ${this.hasher.rate})`);
|
|
868
1020
|
}
|
|
@@ -875,39 +1027,82 @@ class HMACRescuePrime {
|
|
|
875
1027
|
}
|
|
876
1028
|
}
|
|
877
1029
|
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
1030
|
+
/**
|
|
1031
|
+
* HKDF (HMAC-based Extract-and-Expand Key Derivation Function) using the Rescue-Prime hash function.
|
|
1032
|
+
* Follows RFC 5869. Only supports L = HashLen.
|
|
1033
|
+
*/
|
|
882
1034
|
class HKDFRescuePrime {
|
|
883
1035
|
hmac;
|
|
1036
|
+
/**
|
|
1037
|
+
* Constructs a new HKDFRescuePrime instance.
|
|
1038
|
+
*/
|
|
884
1039
|
constructor() {
|
|
885
1040
|
this.hmac = new HMACRescuePrime();
|
|
886
1041
|
}
|
|
1042
|
+
/**
|
|
1043
|
+
* HKDF-Extract step: derives a pseudorandom key (PRK) from the input keying material (IKM) and salt.
|
|
1044
|
+
* @param salt - The salt value as an array of bigints.
|
|
1045
|
+
* @param ikm - The input keying material as an array of bigints.
|
|
1046
|
+
* @returns The pseudorandom key (PRK) as an array of bigints.
|
|
1047
|
+
*/
|
|
887
1048
|
extract(salt, ikm) {
|
|
1049
|
+
if (salt.length === 0) {
|
|
1050
|
+
// HashLen = hasher.rate for Rescue-Prime
|
|
1051
|
+
for (let i = 0; i < this.hmac.hasher.rate; ++i) {
|
|
1052
|
+
salt.push(0n);
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
888
1055
|
return this.hmac.digest(salt, ikm);
|
|
889
1056
|
}
|
|
1057
|
+
/**
|
|
1058
|
+
* HKDF-Expand step: expands the pseudorandom key (PRK) with info to produce output keying material (OKM).
|
|
1059
|
+
* Only supports L = HashLen = 5, i.e. N = 1.
|
|
1060
|
+
* @param prk - The pseudorandom key as an array of bigints.
|
|
1061
|
+
* @param info - The context and application specific information as an array of bigints.
|
|
1062
|
+
* @returns The output keying material (OKM) as an array of bigints.
|
|
1063
|
+
*/
|
|
890
1064
|
expand(prk, info) {
|
|
891
|
-
// we
|
|
1065
|
+
// we only support L = HashLen = 5, i.e. N = 1
|
|
1066
|
+
// message = empty string | info | 0x01
|
|
892
1067
|
info.push(1n);
|
|
893
1068
|
return this.hmac.digest(prk, info);
|
|
894
1069
|
}
|
|
1070
|
+
/**
|
|
1071
|
+
* Performs the full HKDF (extract and expand) to derive output keying material (OKM).
|
|
1072
|
+
* @param salt - The salt value as an array of bigints.
|
|
1073
|
+
* @param ikm - The input keying material as an array of bigints.
|
|
1074
|
+
* @param info - The context and application specific information as an array of bigints.
|
|
1075
|
+
* @returns The output keying material (OKM) as an array of bigints.
|
|
1076
|
+
*/
|
|
895
1077
|
okm(salt, ikm, info) {
|
|
896
1078
|
const prk = this.extract(salt, ikm);
|
|
897
1079
|
return this.expand(prk, info);
|
|
898
1080
|
}
|
|
899
1081
|
}
|
|
900
1082
|
|
|
901
|
-
|
|
902
|
-
|
|
1083
|
+
/**
|
|
1084
|
+
* The Rescue cipher in Counter (CTR) mode, with a fixed block size m = 5.
|
|
1085
|
+
* See: https://tosc.iacr.org/index.php/ToSC/article/view/8695/8287
|
|
1086
|
+
*/
|
|
903
1087
|
class RescueCipher {
|
|
904
1088
|
desc;
|
|
1089
|
+
/**
|
|
1090
|
+
* Constructs a RescueCipher instance using a shared secret.
|
|
1091
|
+
* The key is derived using HKDF-RescuePrime and used to initialize the RescueDesc.
|
|
1092
|
+
* @param sharedSecret - The shared secret to derive the cipher key from.
|
|
1093
|
+
*/
|
|
905
1094
|
constructor(sharedSecret) {
|
|
906
1095
|
const hkdf = new HKDFRescuePrime();
|
|
907
|
-
const rescueKey = hkdf.okm([
|
|
1096
|
+
const rescueKey = hkdf.okm([], [deserializeLE(sharedSecret)], []);
|
|
908
1097
|
this.desc = new RescueDesc(CURVE25519_BASE_FIELD, { kind: 'cipher', key: rescueKey });
|
|
909
1098
|
}
|
|
910
|
-
|
|
1099
|
+
/**
|
|
1100
|
+
* Encrypts the plaintext vector in Counter (CTR) mode (raw, returns bigints).
|
|
1101
|
+
* @param plaintext - The array of plaintext bigints to encrypt.
|
|
1102
|
+
* @param nonce - A 16-byte nonce for CTR mode.
|
|
1103
|
+
* @returns The ciphertext as an array of bigints.
|
|
1104
|
+
* @throws Error if the nonce is not 16 bytes long.
|
|
1105
|
+
*/
|
|
911
1106
|
encrypt_raw(plaintext, nonce) {
|
|
912
1107
|
if (nonce.length !== 16) {
|
|
913
1108
|
throw Error(`nonce must be of length 16 (found ${nonce.length})`);
|
|
@@ -940,11 +1135,22 @@ class RescueCipher {
|
|
|
940
1135
|
}
|
|
941
1136
|
return ciphertext;
|
|
942
1137
|
}
|
|
943
|
-
|
|
1138
|
+
/**
|
|
1139
|
+
* Encrypts the plaintext vector in Counter (CTR) mode and serializes each block.
|
|
1140
|
+
* @param plaintext - The array of plaintext bigints to encrypt.
|
|
1141
|
+
* @param nonce - A 16-byte nonce for CTR mode.
|
|
1142
|
+
* @returns The ciphertext as an array of arrays of numbers (each 32 bytes).
|
|
1143
|
+
*/
|
|
944
1144
|
encrypt(plaintext, nonce) {
|
|
945
1145
|
return this.encrypt_raw(plaintext, nonce).map((c) => Array.from(serializeLE(c, 32)));
|
|
946
1146
|
}
|
|
947
|
-
|
|
1147
|
+
/**
|
|
1148
|
+
* Decrypts the ciphertext vector in Counter (CTR) mode (raw, expects bigints).
|
|
1149
|
+
* @param ciphertext - The array of ciphertext bigints to decrypt.
|
|
1150
|
+
* @param nonce - A 16-byte nonce for CTR mode.
|
|
1151
|
+
* @returns The decrypted plaintext as an array of bigints.
|
|
1152
|
+
* @throws Error if the nonce is not 16 bytes long.
|
|
1153
|
+
*/
|
|
948
1154
|
decrypt_raw(ciphertext, nonce) {
|
|
949
1155
|
if (nonce.length !== 16) {
|
|
950
1156
|
throw Error(`nonce must be of length 16 (found ${nonce.length})`);
|
|
@@ -974,7 +1180,12 @@ class RescueCipher {
|
|
|
974
1180
|
}
|
|
975
1181
|
return decrypted;
|
|
976
1182
|
}
|
|
977
|
-
|
|
1183
|
+
/**
|
|
1184
|
+
* Deserializes and decrypts the ciphertext vector in Counter (CTR) mode.
|
|
1185
|
+
* @param ciphertext - The array of arrays of numbers (each 32 bytes) to decrypt.
|
|
1186
|
+
* @param nonce - A 16-byte nonce for CTR mode.
|
|
1187
|
+
* @returns The decrypted plaintext as an array of bigints.
|
|
1188
|
+
*/
|
|
978
1189
|
decrypt(ciphertext, nonce) {
|
|
979
1190
|
return this.decrypt_raw(ciphertext.map((c) => {
|
|
980
1191
|
if (c.length !== 32) {
|
|
@@ -984,6 +1195,12 @@ class RescueCipher {
|
|
|
984
1195
|
}), nonce);
|
|
985
1196
|
}
|
|
986
1197
|
}
|
|
1198
|
+
/**
|
|
1199
|
+
* Generates the counter values for Rescue cipher CTR mode.
|
|
1200
|
+
* @param nonce - The initial nonce as a bigint.
|
|
1201
|
+
* @param nBlocks - The number of blocks to generate counters for.
|
|
1202
|
+
* @returns An array of counter values as bigints.
|
|
1203
|
+
*/
|
|
987
1204
|
function getCounter(nonce, nBlocks) {
|
|
988
1205
|
const counter = [];
|
|
989
1206
|
for (let i = 0n; i < nBlocks; ++i) {
|
|
@@ -996,10 +1213,203 @@ function getCounter(nonce, nBlocks) {
|
|
|
996
1213
|
return counter;
|
|
997
1214
|
}
|
|
998
1215
|
|
|
1216
|
+
// The arcisEd25519 signature scheme. This is essentially ed25519 but we use the hash function
|
|
1217
|
+
// SHA3-512 instead of SHA-512 since its multiplicative depth is much lower, which
|
|
1218
|
+
// makes it much better suited to be evaluated in MPC.
|
|
1219
|
+
// Those are the parameters specified [here](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1)
|
|
1220
|
+
// (except for the hash function, see above). The below is copied from [here](https://github.com/paulmillr/noble-curves/blob/main/src/ed25519.ts#L111).
|
|
1221
|
+
const arcisEd25519Defaults = (() => ({
|
|
1222
|
+
a: BigInt(-1),
|
|
1223
|
+
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
|
1224
|
+
Fp: ed25519.ed25519.CURVE.Fp,
|
|
1225
|
+
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
|
1226
|
+
h: BigInt(8),
|
|
1227
|
+
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
|
1228
|
+
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
|
1229
|
+
hash: sha3.sha3_512,
|
|
1230
|
+
randomBytes: utils.randomBytes,
|
|
1231
|
+
adjustScalarBytes,
|
|
1232
|
+
uvRatio,
|
|
1233
|
+
}))();
|
|
1234
|
+
/**
|
|
1235
|
+
* Clamps a 32-byte scalar as required by the Ed25519 signature scheme.
|
|
1236
|
+
* See: https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.5
|
|
1237
|
+
* @param bytes - The 32-byte scalar to clamp.
|
|
1238
|
+
* @returns The clamped scalar as a Uint8Array.
|
|
1239
|
+
*/
|
|
1240
|
+
function adjustScalarBytes(bytes) {
|
|
1241
|
+
const clamped = bytes;
|
|
1242
|
+
clamped[0] &= 248;
|
|
1243
|
+
clamped[31] &= 127;
|
|
1244
|
+
clamped[31] |= 64;
|
|
1245
|
+
return clamped;
|
|
1246
|
+
}
|
|
1247
|
+
/**
|
|
1248
|
+
* Dummy function for compatibility; not used in the ArcisEd25519 signature scheme.
|
|
1249
|
+
* Always returns { isValid: true, value: 0n }.
|
|
1250
|
+
* @returns An object with isValid: true and value: 0n.
|
|
1251
|
+
*/
|
|
1252
|
+
function uvRatio() {
|
|
1253
|
+
return { isValid: true, value: 0n };
|
|
1254
|
+
}
|
|
1255
|
+
/**
|
|
1256
|
+
* Ed25519 curve instance using SHA3-512 for hashing, suitable for MPC (ArcisEd25519 signature scheme).
|
|
1257
|
+
* This is essentially Ed25519 but with SHA3-512 instead of SHA-512 for lower multiplicative depth.
|
|
1258
|
+
* See: https://datatracker.ietf.org/doc/html/rfc8032#section-5.1
|
|
1259
|
+
*/
|
|
1260
|
+
const arcisEd25519 = (() => edwards.twistedEdwards(arcisEd25519Defaults))();
|
|
1261
|
+
|
|
1262
|
+
/**
|
|
1263
|
+
* AES-128 cipher in Counter (CTR) mode, using HKDF-SHA3-256 to derive the key from a shared secret.
|
|
1264
|
+
* See: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf (Section 6.5) for details on CTR mode.
|
|
1265
|
+
*/
|
|
1266
|
+
class Aes128Cipher {
|
|
1267
|
+
key;
|
|
1268
|
+
/**
|
|
1269
|
+
* Constructs an AES-128 cipher instance using a shared secret.
|
|
1270
|
+
* The key is derived using HKDF-SHA3-256.
|
|
1271
|
+
* @param sharedSecret - The shared secret to derive the AES key from.
|
|
1272
|
+
*/
|
|
1273
|
+
constructor(sharedSecret) {
|
|
1274
|
+
const aesKey = crypto.hkdfSync('sha3-256', sharedSecret, new Uint8Array(), new Uint8Array(), 16);
|
|
1275
|
+
this.key = new Uint8Array(aesKey);
|
|
1276
|
+
}
|
|
1277
|
+
/**
|
|
1278
|
+
* Encrypts the plaintext array in Counter (CTR) mode.
|
|
1279
|
+
* @param plaintext - The data to encrypt.
|
|
1280
|
+
* @param nonce - An 8-byte nonce for CTR mode.
|
|
1281
|
+
* @returns The encrypted ciphertext as a Uint8Array.
|
|
1282
|
+
* @throws Error if the nonce is not 8 bytes long.
|
|
1283
|
+
*/
|
|
1284
|
+
encrypt(plaintext, nonce) {
|
|
1285
|
+
if (nonce.length !== 8) {
|
|
1286
|
+
throw Error(`nonce must be of length 8 (found ${nonce.length})`);
|
|
1287
|
+
}
|
|
1288
|
+
const paddedNonce = Buffer.concat([nonce, Buffer.alloc(16 - nonce.length, 0)]);
|
|
1289
|
+
const cipher = crypto.createCipheriv('aes-128-ctr', this.key, paddedNonce);
|
|
1290
|
+
const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
1291
|
+
return new Uint8Array(ciphertext);
|
|
1292
|
+
}
|
|
1293
|
+
/**
|
|
1294
|
+
* Decrypts the ciphertext array in Counter (CTR) mode.
|
|
1295
|
+
* @param ciphertext - The data to decrypt.
|
|
1296
|
+
* @param nonce - An 8-byte nonce for CTR mode.
|
|
1297
|
+
* @returns The decrypted plaintext as a Uint8Array.
|
|
1298
|
+
* @throws Error if the nonce is not 8 bytes long.
|
|
1299
|
+
*/
|
|
1300
|
+
decrypt(ciphertext, nonce) {
|
|
1301
|
+
if (nonce.length !== 8) {
|
|
1302
|
+
throw Error(`nonce must be of length 8 (found ${nonce.length})`);
|
|
1303
|
+
}
|
|
1304
|
+
const paddedNonce = Buffer.concat([nonce, Buffer.alloc(16 - nonce.length, 0)]);
|
|
1305
|
+
const cipher = crypto.createDecipheriv('aes-128-ctr', this.key, paddedNonce);
|
|
1306
|
+
const decrypted = Buffer.concat([cipher.update(ciphertext), cipher.final()]);
|
|
1307
|
+
return new Uint8Array(decrypted);
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
/**
|
|
1312
|
+
* AES-192 cipher in Counter (CTR) mode, using HKDF-SHA3-256 to derive the key from a shared secret.
|
|
1313
|
+
* See: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf (Section 6.5) for details on CTR mode.
|
|
1314
|
+
*/
|
|
1315
|
+
class Aes192Cipher {
|
|
1316
|
+
key;
|
|
1317
|
+
/**
|
|
1318
|
+
* Constructs an AES-192 cipher instance using a shared secret.
|
|
1319
|
+
* The key is derived using HKDF-SHA3-256.
|
|
1320
|
+
* @param sharedSecret - The shared secret to derive the AES key from.
|
|
1321
|
+
*/
|
|
1322
|
+
constructor(sharedSecret) {
|
|
1323
|
+
const aesKey = crypto.hkdfSync('sha3-256', sharedSecret, new Uint8Array(), new Uint8Array(), 24);
|
|
1324
|
+
this.key = new Uint8Array(aesKey);
|
|
1325
|
+
}
|
|
1326
|
+
/**
|
|
1327
|
+
* Encrypts the plaintext array in Counter (CTR) mode.
|
|
1328
|
+
* @param plaintext - The data to encrypt.
|
|
1329
|
+
* @param nonce - An 8-byte nonce for CTR mode.
|
|
1330
|
+
* @returns The encrypted ciphertext as a Uint8Array.
|
|
1331
|
+
* @throws Error if the nonce is not 8 bytes long.
|
|
1332
|
+
*/
|
|
1333
|
+
encrypt(plaintext, nonce) {
|
|
1334
|
+
if (nonce.length !== 8) {
|
|
1335
|
+
throw Error(`nonce must be of length 8 (found ${nonce.length})`);
|
|
1336
|
+
}
|
|
1337
|
+
const paddedNonce = Buffer.concat([nonce, Buffer.alloc(16 - nonce.length, 0)]);
|
|
1338
|
+
const cipher = crypto.createCipheriv('aes-192-ctr', this.key, paddedNonce);
|
|
1339
|
+
const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
1340
|
+
return new Uint8Array(ciphertext);
|
|
1341
|
+
}
|
|
1342
|
+
/**
|
|
1343
|
+
* Decrypts the ciphertext array in Counter (CTR) mode.
|
|
1344
|
+
* @param ciphertext - The data to decrypt.
|
|
1345
|
+
* @param nonce - An 8-byte nonce for CTR mode.
|
|
1346
|
+
* @returns The decrypted plaintext as a Uint8Array.
|
|
1347
|
+
* @throws Error if the nonce is not 8 bytes long.
|
|
1348
|
+
*/
|
|
1349
|
+
decrypt(ciphertext, nonce) {
|
|
1350
|
+
if (nonce.length !== 8) {
|
|
1351
|
+
throw Error(`nonce must be of length 8 (found ${nonce.length})`);
|
|
1352
|
+
}
|
|
1353
|
+
const paddedNonce = Buffer.concat([nonce, Buffer.alloc(16 - nonce.length, 0)]);
|
|
1354
|
+
const cipher = crypto.createDecipheriv('aes-192-ctr', this.key, paddedNonce);
|
|
1355
|
+
const decrypted = Buffer.concat([cipher.update(ciphertext), cipher.final()]);
|
|
1356
|
+
return new Uint8Array(decrypted);
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
/**
|
|
1361
|
+
* AES-256 cipher in Counter (CTR) mode, using HKDF-SHA3-256 to derive the key from a shared secret.
|
|
1362
|
+
* See: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf (Section 6.5) for details on CTR mode.
|
|
1363
|
+
*/
|
|
1364
|
+
class Aes256Cipher {
|
|
1365
|
+
key;
|
|
1366
|
+
/**
|
|
1367
|
+
* Constructs an AES-256 cipher instance using a shared secret.
|
|
1368
|
+
* The key is derived using HKDF-SHA3-256.
|
|
1369
|
+
* @param sharedSecret - The shared secret to derive the AES key from.
|
|
1370
|
+
*/
|
|
1371
|
+
constructor(sharedSecret) {
|
|
1372
|
+
const aesKey = crypto.hkdfSync('sha3-256', sharedSecret, new Uint8Array(), new Uint8Array(), 32);
|
|
1373
|
+
this.key = new Uint8Array(aesKey);
|
|
1374
|
+
}
|
|
1375
|
+
/**
|
|
1376
|
+
* Encrypts the plaintext array in Counter (CTR) mode.
|
|
1377
|
+
* @param plaintext - The data to encrypt.
|
|
1378
|
+
* @param nonce - An 8-byte nonce for CTR mode.
|
|
1379
|
+
* @returns The encrypted ciphertext as a Uint8Array.
|
|
1380
|
+
* @throws Error if the nonce is not 8 bytes long.
|
|
1381
|
+
*/
|
|
1382
|
+
encrypt(plaintext, nonce) {
|
|
1383
|
+
if (nonce.length !== 8) {
|
|
1384
|
+
throw Error(`nonce must be of length 8 (found ${nonce.length})`);
|
|
1385
|
+
}
|
|
1386
|
+
const paddedNonce = Buffer.concat([nonce, Buffer.alloc(16 - nonce.length, 0)]);
|
|
1387
|
+
const cipher = crypto.createCipheriv('aes-256-ctr', this.key, paddedNonce);
|
|
1388
|
+
const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
1389
|
+
return new Uint8Array(ciphertext);
|
|
1390
|
+
}
|
|
1391
|
+
/**
|
|
1392
|
+
* Decrypts the ciphertext array in Counter (CTR) mode.
|
|
1393
|
+
* @param ciphertext - The data to decrypt.
|
|
1394
|
+
* @param nonce - An 8-byte nonce for CTR mode.
|
|
1395
|
+
* @returns The decrypted plaintext as a Uint8Array.
|
|
1396
|
+
* @throws Error if the nonce is not 8 bytes long.
|
|
1397
|
+
*/
|
|
1398
|
+
decrypt(ciphertext, nonce) {
|
|
1399
|
+
if (nonce.length !== 8) {
|
|
1400
|
+
throw Error(`nonce must be of length 8 (found ${nonce.length})`);
|
|
1401
|
+
}
|
|
1402
|
+
const paddedNonce = Buffer.concat([nonce, Buffer.alloc(16 - nonce.length, 0)]);
|
|
1403
|
+
const cipher = crypto.createDecipheriv('aes-256-ctr', this.key, paddedNonce);
|
|
1404
|
+
const decrypted = Buffer.concat([cipher.update(ciphertext), cipher.final()]);
|
|
1405
|
+
return new Uint8Array(decrypted);
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
|
|
999
1409
|
var address = "BKck65TgoKRokMjQM3datB9oRwJ8rAj2jxPXvHXUvcL6";
|
|
1000
1410
|
var metadata = {
|
|
1001
1411
|
name: "arcium",
|
|
1002
|
-
version: "0.1.
|
|
1412
|
+
version: "0.1.47",
|
|
1003
1413
|
spec: "0.1.0",
|
|
1004
1414
|
description: "The Arcium program"
|
|
1005
1415
|
};
|
|
@@ -11541,32 +11951,75 @@ var ARCIUM_IDL = /*#__PURE__*/Object.freeze({
|
|
|
11541
11951
|
types: types
|
|
11542
11952
|
});
|
|
11543
11953
|
|
|
11954
|
+
/**
|
|
11955
|
+
* The deployed address of the Arcium program, as specified in the IDL.
|
|
11956
|
+
*/
|
|
11544
11957
|
const ARCIUM_ADDR = address;
|
|
11545
11958
|
|
|
11546
|
-
|
|
11959
|
+
/**
|
|
11960
|
+
* Seed for ClockAccount PDA
|
|
11961
|
+
* @constant {string}
|
|
11962
|
+
*/
|
|
11547
11963
|
const CLOCK_ACC_SEED = 'ClockAccount';
|
|
11548
|
-
|
|
11964
|
+
/**
|
|
11965
|
+
* Seed for StakingPoolAccount PDA
|
|
11966
|
+
* @constant {string}
|
|
11967
|
+
*/
|
|
11549
11968
|
const POOL_ACC_SEED = 'StakingPoolAccount';
|
|
11550
|
-
|
|
11969
|
+
/**
|
|
11970
|
+
* Seed for ComputationAccount PDA
|
|
11971
|
+
* @constant {string}
|
|
11972
|
+
*/
|
|
11551
11973
|
const COMPUTATION_ACC_SEED = 'ComputationAccount';
|
|
11552
|
-
|
|
11974
|
+
/**
|
|
11975
|
+
* Seed for Mempool PDA
|
|
11976
|
+
* @constant {string}
|
|
11977
|
+
*/
|
|
11553
11978
|
const MEMPOOL_ACC_SEED = 'Mempool';
|
|
11554
|
-
|
|
11979
|
+
/**
|
|
11980
|
+
* Seed for ExecutingPoolAccount PDA
|
|
11981
|
+
* @constant {string}
|
|
11982
|
+
*/
|
|
11555
11983
|
const EXEC_POOL_ACC_SEED = 'Execpool';
|
|
11556
|
-
|
|
11984
|
+
/**
|
|
11985
|
+
* Seed for ClusterAccount PDA
|
|
11986
|
+
* @constant {string}
|
|
11987
|
+
*/
|
|
11557
11988
|
const CLUSTER_ACC_SEED = 'Cluster';
|
|
11558
|
-
|
|
11989
|
+
/**
|
|
11990
|
+
* Seed for ArxNodeAccount PDA
|
|
11991
|
+
* @constant {string}
|
|
11992
|
+
*/
|
|
11559
11993
|
const ARX_NODE_ACC_SEED = 'ArxNode';
|
|
11560
|
-
|
|
11994
|
+
/**
|
|
11995
|
+
* Seed for MXEAccAccount PDA
|
|
11996
|
+
* @constant {string}
|
|
11997
|
+
*/
|
|
11561
11998
|
const MXE_ACC_ACC_SEED = 'PersistentMXEAccount';
|
|
11562
|
-
|
|
11999
|
+
/**
|
|
12000
|
+
* Seed for CompDefAccount PDA
|
|
12001
|
+
* @constant {string}
|
|
12002
|
+
*/
|
|
11563
12003
|
const COMP_DEF_ACC_SEED = 'ComputationDefinitionAccount';
|
|
12004
|
+
/**
|
|
12005
|
+
* Maximum number of bytes that can be reallocated per instruction.
|
|
12006
|
+
* @constant {number}
|
|
12007
|
+
*/
|
|
11564
12008
|
const MAX_REALLOC_PER_IX = 10240;
|
|
11565
|
-
|
|
12009
|
+
/**
|
|
12010
|
+
* Maximum number of bytes that can be uploaded in a single transaction with the upload instruction.
|
|
12011
|
+
* @constant {number}
|
|
12012
|
+
*/
|
|
11566
12013
|
const MAX_UPLOAD_PER_TX_BYTES = 814;
|
|
11567
|
-
|
|
11568
|
-
|
|
11569
|
-
|
|
12014
|
+
/**
|
|
12015
|
+
* Maximum size of an account in bytes (10MB = 10 * 1024 * 1024).
|
|
12016
|
+
* @constant {number}
|
|
12017
|
+
*/
|
|
12018
|
+
const MAX_ACCOUNT_SIZE = 10485760;
|
|
12019
|
+
/**
|
|
12020
|
+
* Maximum number of arcium embiggen instructions allowed in a single transaction (due to compute unit limits).
|
|
12021
|
+
* @constant {number}
|
|
12022
|
+
*/
|
|
11570
12023
|
const MAX_EMBIGGEN_IX_PER_TX = 18;
|
|
11571
12024
|
|
|
11572
12025
|
const TINY_MEMPOOL_ACC_NAME = 'tinyMempool';
|
|
@@ -11669,9 +12122,19 @@ const EXECPOOL_DISCRIMINATOR_MAP = {
|
|
|
11669
12122
|
[MEDIUM_EXECPOOL_DISCRIMINATOR.toString()]: MEDIUM_EXECPOOL_ACC_NAME,
|
|
11670
12123
|
[LARGE_EXECPOOL_DISCRIMINATOR.toString()]: LARGE_EXECPOOL_ACC_NAME,
|
|
11671
12124
|
};
|
|
12125
|
+
/**
|
|
12126
|
+
* Returns the public key of the deployed Arcium program on Solana.
|
|
12127
|
+
* @returns The Arcium program's public key.
|
|
12128
|
+
*/
|
|
11672
12129
|
function getArciumProgAddress() {
|
|
11673
12130
|
return new anchor__namespace.web3.PublicKey(ARCIUM_ADDR);
|
|
11674
12131
|
}
|
|
12132
|
+
/**
|
|
12133
|
+
* Fetches the DA (Data Availability) info for all nodes in a cluster.
|
|
12134
|
+
* @param provider - The Anchor provider to use for fetching accounts.
|
|
12135
|
+
* @param clusterAddr - The public key of the cluster account.
|
|
12136
|
+
* @returns An array of NodeDAInfo objects for each node in the cluster.
|
|
12137
|
+
*/
|
|
11675
12138
|
async function getClusterDAInfo(provider, clusterAddr) {
|
|
11676
12139
|
const program = getArciumProgram(provider);
|
|
11677
12140
|
const clusterAcc = await program.account.cluster.fetch(clusterAddr);
|
|
@@ -11682,6 +12145,13 @@ async function getClusterDAInfo(provider, clusterAddr) {
|
|
|
11682
12145
|
return { solanaPubkey: nodeAccPubkey, x25519Pubkey: Uint8Array.from(nodeAcc.encryptionPubkey) };
|
|
11683
12146
|
}));
|
|
11684
12147
|
}
|
|
12148
|
+
/**
|
|
12149
|
+
* Fetches and decodes the mempool account data for any mempool account size.
|
|
12150
|
+
* @param provider - The Anchor provider to use for fetching accounts.
|
|
12151
|
+
* @param mempoolAccPubkey - The public key of the mempool account.
|
|
12152
|
+
* @returns The decoded mempool account data.
|
|
12153
|
+
* @throws Error if the account cannot be fetched or the discriminator is unknown.
|
|
12154
|
+
*/
|
|
11685
12155
|
async function getMempoolAccData(provider, mempoolAccPubkey) {
|
|
11686
12156
|
const accData = await provider.connection.getAccountInfo(mempoolAccPubkey);
|
|
11687
12157
|
if (accData === null) {
|
|
@@ -11695,6 +12165,13 @@ async function getMempoolAccData(provider, mempoolAccPubkey) {
|
|
|
11695
12165
|
const program = getArciumProgram(provider);
|
|
11696
12166
|
return program.coder.accounts.decode(accName, accData.data);
|
|
11697
12167
|
}
|
|
12168
|
+
/**
|
|
12169
|
+
* Fetches and decodes the executing pool account data for any pool size.
|
|
12170
|
+
* @param provider - The Anchor provider to use for fetching accounts.
|
|
12171
|
+
* @param executingPoolAccPubkey - The public key of the executing pool account.
|
|
12172
|
+
* @returns The decoded executing pool account data.
|
|
12173
|
+
* @throws Error if the account cannot be fetched or the discriminator is unknown.
|
|
12174
|
+
*/
|
|
11698
12175
|
async function getExecutingPoolAccData(provider, executingPoolAccPubkey) {
|
|
11699
12176
|
const accData = await provider.connection.getAccountInfo(executingPoolAccPubkey);
|
|
11700
12177
|
if (accData === null) {
|
|
@@ -11708,6 +12185,16 @@ async function getExecutingPoolAccData(provider, executingPoolAccPubkey) {
|
|
|
11708
12185
|
const program = getArciumProgram(provider);
|
|
11709
12186
|
return program.coder.accounts.decode(accName, accData.data);
|
|
11710
12187
|
}
|
|
12188
|
+
/**
|
|
12189
|
+
* Uploads a circuit to the blockchain, splitting it into multiple accounts if necessary.
|
|
12190
|
+
* @param provider - The Anchor provider to use for transactions.
|
|
12191
|
+
* @param circuitName - The name of the circuit.
|
|
12192
|
+
* @param mxeProgramID - The public key of the MXE program.
|
|
12193
|
+
* @param rawCircuit - The raw circuit data as a Uint8Array.
|
|
12194
|
+
* @param logging - Whether to log progress (default: true).
|
|
12195
|
+
* @param chunkSize - The number of upload transactions to send in parallel (default: 500).
|
|
12196
|
+
* @returns An array of transaction signatures for all upload and finalize transactions.
|
|
12197
|
+
*/
|
|
11711
12198
|
async function uploadCircuit(provider, circuitName, mxeProgramID, rawCircuit, logging = true, chunkSize = 500) {
|
|
11712
12199
|
const numAccs = Math.ceil(rawCircuit.length / (MAX_ACCOUNT_SIZE - 9));
|
|
11713
12200
|
const compDefAccInfo = getCompDefAccInfo(circuitName, mxeProgramID);
|
|
@@ -11722,6 +12209,13 @@ async function uploadCircuit(provider, circuitName, mxeProgramID, rawCircuit, lo
|
|
|
11722
12209
|
sigs.push(await signAndSendWithBlockhash(provider, finalizeCompDefTx, await provider.connection.getLatestBlockhash()));
|
|
11723
12210
|
return sigs;
|
|
11724
12211
|
}
|
|
12212
|
+
/**
|
|
12213
|
+
* Builds a transaction to finalize a computation definition.
|
|
12214
|
+
* @param provider - The Anchor provider to use for transactions.
|
|
12215
|
+
* @param compDefOffset - The offset of the computation definition.
|
|
12216
|
+
* @param mxeProgramID - The public key of the MXE program.
|
|
12217
|
+
* @returns The transaction to finalize the computation definition.
|
|
12218
|
+
*/
|
|
11725
12219
|
async function buildFinalizeCompDefTx(provider, compDefOffset, mxeProgramID) {
|
|
11726
12220
|
const program = getArciumProgram(provider);
|
|
11727
12221
|
const compDefOffsetBuffer = Buffer.alloc(4);
|
|
@@ -11823,35 +12317,78 @@ async function signAndSendWithBlockhash(provider, tx, block) {
|
|
|
11823
12317
|
tx.lastValidBlockHeight = block.lastValidBlockHeight;
|
|
11824
12318
|
return provider.sendAndConfirm(tx, [], { commitment: 'confirmed' });
|
|
11825
12319
|
}
|
|
12320
|
+
/**
|
|
12321
|
+
* Returns the base seed for an Arcium account, given its name.
|
|
12322
|
+
* @param accName - The name of the account.
|
|
12323
|
+
* @returns The base seed as a Uint8Array.
|
|
12324
|
+
*/
|
|
11826
12325
|
function getArciumAccountBaseSeed(accName) {
|
|
11827
12326
|
return Buffer.from(accName, 'utf-8');
|
|
11828
12327
|
}
|
|
12328
|
+
/**
|
|
12329
|
+
* Computes the offset for a computation definition account, based on the circuit name.
|
|
12330
|
+
* @param circuitName - The name of the circuit.
|
|
12331
|
+
* @returns The offset as a 4-byte Uint8Array.
|
|
12332
|
+
*/
|
|
11829
12333
|
function getCompDefAccOffset(circuitName) {
|
|
11830
12334
|
const hash = new Uint8Array(sha256([Buffer.from(circuitName, 'utf-8')]));
|
|
11831
12335
|
return hash.slice(0, 4);
|
|
11832
12336
|
}
|
|
12337
|
+
/**
|
|
12338
|
+
* Returns an Anchor program instance for the Arcium program.
|
|
12339
|
+
* @param provider - The Anchor provider to use.
|
|
12340
|
+
* @returns The Anchor program instance for Arcium.
|
|
12341
|
+
*/
|
|
11833
12342
|
function getArciumProgram(provider) {
|
|
11834
12343
|
return new anchor.Program(ARCIUM_IDL, provider);
|
|
11835
12344
|
}
|
|
12345
|
+
/**
|
|
12346
|
+
* Returns a read-only Anchor program instance for the Arcium program.
|
|
12347
|
+
* @param provider - The Anchor provider to use.
|
|
12348
|
+
* @returns The Anchor program instance for Arcium.
|
|
12349
|
+
*/
|
|
11836
12350
|
function getArciumProgramReadonly(provider) {
|
|
11837
12351
|
return new anchor.Program(ARCIUM_IDL, provider);
|
|
11838
12352
|
}
|
|
12353
|
+
/**
|
|
12354
|
+
* Returns the PDA (program-derived address) for an ArxNode account given the program ID and node offset.
|
|
12355
|
+
* @param arciumProgramID - The public key of the Arcium program.
|
|
12356
|
+
* @param nodeOffset - The offset of the node.
|
|
12357
|
+
* @returns The PDA for the ArxNode account.
|
|
12358
|
+
*/
|
|
11839
12359
|
function getArxAccPDA(arciumProgramID, nodeOffset) {
|
|
11840
12360
|
const nodeOffsetBuffer = Buffer.alloc(4);
|
|
11841
12361
|
nodeOffsetBuffer.writeUInt32LE(nodeOffset, 0);
|
|
11842
12362
|
return anchor__namespace.web3.PublicKey.findProgramAddressSync([Buffer.from('ArxNode', 'utf-8'), nodeOffsetBuffer], arciumProgramID)[0];
|
|
11843
12363
|
}
|
|
12364
|
+
/**
|
|
12365
|
+
* Returns the public key and offset for a computation definition account, given the circuit name and MXE program ID.
|
|
12366
|
+
* @param circuitName - The name of the circuit.
|
|
12367
|
+
* @param mxeProgramID - The public key of the MXE program.
|
|
12368
|
+
* @returns An object containing the public key and offset for the computation definition account.
|
|
12369
|
+
*/
|
|
11844
12370
|
function getCompDefAccInfo(circuitName, mxeProgramID) {
|
|
11845
12371
|
const offset = getCompDefAccOffset(circuitName);
|
|
11846
12372
|
const pda = getCompDefAccPDA(getArciumProgAddress(), mxeProgramID, offset);
|
|
11847
12373
|
return { pubkey: pda, offset: Buffer.from(offset).readUInt32LE(0) };
|
|
11848
12374
|
}
|
|
12375
|
+
/**
|
|
12376
|
+
* Returns the PDA for a computation definition account, given the program ID, MXE program ID, and offset.
|
|
12377
|
+
* @param arciumProgramID - The public key of the Arcium program.
|
|
12378
|
+
* @param mxeProgramID - The public key of the MXE program.
|
|
12379
|
+
* @param offset - The offset as a Uint8Array.
|
|
12380
|
+
* @returns The PDA for the computation definition account.
|
|
12381
|
+
*/
|
|
11849
12382
|
function getCompDefAccPDA(arciumProgramID, mxeProgramID, offset) {
|
|
11850
12383
|
return anchor__namespace.web3.PublicKey.findProgramAddressSync([Buffer.from('ComputationDefinitionAccount', 'utf-8'), mxeProgramID.toBuffer(), offset], arciumProgramID)[0];
|
|
11851
12384
|
}
|
|
11852
12385
|
|
|
11853
|
-
|
|
11854
|
-
|
|
12386
|
+
/**
|
|
12387
|
+
* Reads local Arcium environment information from environment variables.
|
|
12388
|
+
* Only available in Node.js and when testing locally.
|
|
12389
|
+
* @returns The local Arcium environment configuration.
|
|
12390
|
+
* @throws Error if called in a browser or if required environment variables are missing or invalid.
|
|
12391
|
+
*/
|
|
11855
12392
|
function getArciumEnv() {
|
|
11856
12393
|
if (isBrowser()) {
|
|
11857
12394
|
throw new Error('Arcium local env is not available in browser.');
|
|
@@ -12109,12 +12646,29 @@ class LogScanner {
|
|
|
12109
12646
|
}
|
|
12110
12647
|
}
|
|
12111
12648
|
|
|
12649
|
+
/**
|
|
12650
|
+
* Waits for the finalization of a computation by listening for the finalizeComputationEvent.
|
|
12651
|
+
* Resolves with the transaction signature once the computation is finalized.
|
|
12652
|
+
* @param provider - The Anchor provider to use for event listening.
|
|
12653
|
+
* @param computationOffset - The offset of the computation to wait for.
|
|
12654
|
+
* @param mxeProgramId - The public key of the MXE program.
|
|
12655
|
+
* @param commitment - (Optional) The desired finality/commitment level (default: 'confirmed').
|
|
12656
|
+
* @returns The transaction signature of the finalization event.
|
|
12657
|
+
*/
|
|
12112
12658
|
async function awaitComputationFinalization(provider, computationOffset, mxeProgramId, commitment = 'confirmed') {
|
|
12113
12659
|
const arciumProgram = getArciumProgram(provider);
|
|
12114
12660
|
const eventListener = new EventManager(arciumProgram.programId, provider, arciumProgram.coder);
|
|
12115
12661
|
const finalizeComp = await awaitEvent(eventListener, 'finalizeComputationEvent', (e) => mxeProgramId.equals(e.mxeProgramId) && e.computationOffset.eq(computationOffset), commitment);
|
|
12116
12662
|
return finalizeComp.sig;
|
|
12117
12663
|
}
|
|
12664
|
+
/**
|
|
12665
|
+
* Waits for a specific event to occur, matching a custom check, and returns the event and its signature.
|
|
12666
|
+
* @param eventListener - The EventManager instance to use for listening.
|
|
12667
|
+
* @param eventName - The name of the event to listen for.
|
|
12668
|
+
* @param eventCheck - A predicate function to check if the event matches the desired criteria.
|
|
12669
|
+
* @param commitment - (Optional) The desired finality/commitment level (default: 'confirmed').
|
|
12670
|
+
* @returns An object containing the event and its transaction signature.
|
|
12671
|
+
*/
|
|
12118
12672
|
async function awaitEvent(eventListener, eventName, eventCheck, commitment = 'confirmed') {
|
|
12119
12673
|
const foundEvent = await new Promise((res) => {
|
|
12120
12674
|
const listenerId = eventListener.addEventListener(eventName, (event, _slot, signature) => {
|
|
@@ -12126,51 +12680,105 @@ async function awaitEvent(eventListener, eventName, eventCheck, commitment = 'co
|
|
|
12126
12680
|
return { event: foundEvent[0], sig: foundEvent[1] };
|
|
12127
12681
|
}
|
|
12128
12682
|
|
|
12683
|
+
/**
|
|
12684
|
+
* Returns the public key of the deployed Arcium program on Solana.
|
|
12685
|
+
* @returns The Arcium program's public key.
|
|
12686
|
+
*/
|
|
12129
12687
|
function getArciumProgramId() {
|
|
12130
12688
|
return new web3_js.PublicKey('BKck65TgoKRokMjQM3datB9oRwJ8rAj2jxPXvHXUvcL6');
|
|
12131
12689
|
}
|
|
12132
|
-
|
|
12690
|
+
/**
|
|
12691
|
+
* Derives the computation account address for a given MXE program ID and offset.
|
|
12692
|
+
* @param mxeProgramId - The public key of the MXE program.
|
|
12693
|
+
* @param offset - The computation offset as an anchor.BN.
|
|
12694
|
+
* @returns The derived computation account public key.
|
|
12695
|
+
*/
|
|
12696
|
+
function getComputationAccAddress(mxeProgramId, offset) {
|
|
12133
12697
|
const seeds = [Buffer.from(COMPUTATION_ACC_SEED), mxeProgramId.toBuffer(), offset.toArrayLike(Buffer, 'le', 8)];
|
|
12134
12698
|
return generateArciumPDAFrom(seeds)[0];
|
|
12135
12699
|
}
|
|
12136
|
-
|
|
12700
|
+
/**
|
|
12701
|
+
* Derives the mempool account address for a given MXE program ID.
|
|
12702
|
+
* @param mxeProgramId - The public key of the MXE program.
|
|
12703
|
+
* @returns The derived mempool account public key.
|
|
12704
|
+
*/
|
|
12705
|
+
function getMempoolAccAddress(mxeProgramId) {
|
|
12137
12706
|
const seeds = [Buffer.from(MEMPOOL_ACC_SEED), mxeProgramId.toBuffer()];
|
|
12138
12707
|
return generateArciumPDAFrom(seeds)[0];
|
|
12139
12708
|
}
|
|
12140
|
-
|
|
12709
|
+
/**
|
|
12710
|
+
* Derives the executing pool account address for a given MXE program ID.
|
|
12711
|
+
* @param mxeProgramId - The public key of the MXE program.
|
|
12712
|
+
* @returns The derived executing pool account public key.
|
|
12713
|
+
*/
|
|
12714
|
+
function getExecutingPoolAccAddress(mxeProgramId) {
|
|
12141
12715
|
const seeds = [Buffer.from(EXEC_POOL_ACC_SEED), mxeProgramId.toBuffer()];
|
|
12142
12716
|
return generateArciumPDAFrom(seeds)[0];
|
|
12143
12717
|
}
|
|
12144
|
-
|
|
12718
|
+
/**
|
|
12719
|
+
* Derives the staking pool account address.
|
|
12720
|
+
* @returns The derived staking pool account public key.
|
|
12721
|
+
*/
|
|
12722
|
+
function getStakingPoolAccAddress() {
|
|
12145
12723
|
const seeds = [Buffer.from(POOL_ACC_SEED)];
|
|
12146
12724
|
return generateArciumPDAFrom(seeds)[0];
|
|
12147
12725
|
}
|
|
12148
|
-
|
|
12726
|
+
/**
|
|
12727
|
+
* Derives the clock account address.
|
|
12728
|
+
* @returns The derived clock account public key.
|
|
12729
|
+
*/
|
|
12730
|
+
function getClockAccAddress() {
|
|
12149
12731
|
const seeds = [Buffer.from(CLOCK_ACC_SEED)];
|
|
12150
12732
|
return generateArciumPDAFrom(seeds)[0];
|
|
12151
12733
|
}
|
|
12152
|
-
|
|
12734
|
+
/**
|
|
12735
|
+
* Derives the cluster account address for a given offset.
|
|
12736
|
+
* @param offset - The cluster offset as a number.
|
|
12737
|
+
* @returns The derived cluster account public key.
|
|
12738
|
+
*/
|
|
12739
|
+
function getClusterAccAddress(offset) {
|
|
12153
12740
|
const offsetBuffer = Buffer.alloc(4);
|
|
12154
12741
|
offsetBuffer.writeUInt32LE(offset, 0);
|
|
12155
12742
|
const seeds = [Buffer.from(CLUSTER_ACC_SEED), offsetBuffer];
|
|
12156
12743
|
return generateArciumPDAFrom(seeds)[0];
|
|
12157
12744
|
}
|
|
12158
|
-
|
|
12745
|
+
/**
|
|
12746
|
+
* Derives the ArxNode account address for a given offset.
|
|
12747
|
+
* @param offset - The ArxNode offset as a number.
|
|
12748
|
+
* @returns The derived ArxNode account public key.
|
|
12749
|
+
*/
|
|
12750
|
+
function getArxNodeAccAddress(offset) {
|
|
12159
12751
|
const offsetBuffer = Buffer.alloc(4);
|
|
12160
12752
|
offsetBuffer.writeUInt32LE(offset, 0);
|
|
12161
12753
|
const seeds = [Buffer.from(ARX_NODE_ACC_SEED), offsetBuffer];
|
|
12162
12754
|
return generateArciumPDAFrom(seeds)[0];
|
|
12163
12755
|
}
|
|
12164
|
-
|
|
12756
|
+
/**
|
|
12757
|
+
* Derives the MXE account address for a given MXE program ID.
|
|
12758
|
+
* @param mxeProgramId - The public key of the MXE program.
|
|
12759
|
+
* @returns The derived MXE account public key.
|
|
12760
|
+
*/
|
|
12761
|
+
function getMXEAccAddress(mxeProgramId) {
|
|
12165
12762
|
const seeds = [Buffer.from(MXE_ACC_ACC_SEED), mxeProgramId.toBuffer()];
|
|
12166
12763
|
return generateArciumPDAFrom(seeds)[0];
|
|
12167
12764
|
}
|
|
12168
|
-
|
|
12765
|
+
/**
|
|
12766
|
+
* Derives the computation definition account address for a given MXE program ID and offset.
|
|
12767
|
+
* @param mxeProgramId - The public key of the MXE program.
|
|
12768
|
+
* @param offset - The computation definition offset as a number.
|
|
12769
|
+
* @returns The derived computation definition account public key.
|
|
12770
|
+
*/
|
|
12771
|
+
function getCompDefAccAddress(mxeProgramId, offset) {
|
|
12169
12772
|
const offsetBuffer = Buffer.alloc(4);
|
|
12170
12773
|
offsetBuffer.writeUInt32LE(offset, 0);
|
|
12171
12774
|
const seeds = [Buffer.from(COMP_DEF_ACC_SEED), mxeProgramId.toBuffer(), offsetBuffer];
|
|
12172
12775
|
return generateArciumPDAFrom(seeds)[0];
|
|
12173
12776
|
}
|
|
12777
|
+
/**
|
|
12778
|
+
* Generates a program-derived address (PDA) from the provided seeds and the Arcium program ID.
|
|
12779
|
+
* @param seeds - An array of Buffer seeds used for PDA derivation.
|
|
12780
|
+
* @returns A tuple containing the derived public key and the bump seed.
|
|
12781
|
+
*/
|
|
12174
12782
|
function generateArciumPDAFrom(seeds) {
|
|
12175
12783
|
const programId = getArciumProgramId();
|
|
12176
12784
|
return web3_js.PublicKey.findProgramAddressSync(seeds, programId);
|
|
@@ -12182,6 +12790,9 @@ Object.defineProperty(exports, "x25519", {
|
|
|
12182
12790
|
});
|
|
12183
12791
|
exports.ARCIUM_ADDR = ARCIUM_ADDR;
|
|
12184
12792
|
exports.ARCIUM_IDL = ARCIUM_IDL;
|
|
12793
|
+
exports.Aes128Cipher = Aes128Cipher;
|
|
12794
|
+
exports.Aes192Cipher = Aes192Cipher;
|
|
12795
|
+
exports.Aes256Cipher = Aes256Cipher;
|
|
12185
12796
|
exports.CURVE25519_BASE_FIELD = CURVE25519_BASE_FIELD;
|
|
12186
12797
|
exports.CURVE25519_SCALAR_FIELD_MODULUS = CURVE25519_SCALAR_FIELD_MODULUS;
|
|
12187
12798
|
exports.DOUBLE_PRECISION_MANTISSA = DOUBLE_PRECISION_MANTISSA;
|
|
@@ -12189,6 +12800,7 @@ exports.Matrix = Matrix;
|
|
|
12189
12800
|
exports.RescueCipher = RescueCipher;
|
|
12190
12801
|
exports.RescueDesc = RescueDesc;
|
|
12191
12802
|
exports.RescuePrimeHash = RescuePrimeHash;
|
|
12803
|
+
exports.arcisEd25519 = arcisEd25519;
|
|
12192
12804
|
exports.awaitComputationFinalization = awaitComputationFinalization;
|
|
12193
12805
|
exports.buildFinalizeCompDefTx = buildFinalizeCompDefTx;
|
|
12194
12806
|
exports.deserializeLE = deserializeLE;
|
|
@@ -12202,20 +12814,20 @@ exports.getArciumProgAddress = getArciumProgAddress;
|
|
|
12202
12814
|
exports.getArciumProgram = getArciumProgram;
|
|
12203
12815
|
exports.getArciumProgramId = getArciumProgramId;
|
|
12204
12816
|
exports.getArciumProgramReadonly = getArciumProgramReadonly;
|
|
12205
|
-
exports.
|
|
12206
|
-
exports.
|
|
12207
|
-
exports.
|
|
12817
|
+
exports.getArxNodeAccAddress = getArxNodeAccAddress;
|
|
12818
|
+
exports.getClockAccAddress = getClockAccAddress;
|
|
12819
|
+
exports.getClusterAccAddress = getClusterAccAddress;
|
|
12208
12820
|
exports.getClusterDAInfo = getClusterDAInfo;
|
|
12209
|
-
exports.
|
|
12821
|
+
exports.getCompDefAccAddress = getCompDefAccAddress;
|
|
12210
12822
|
exports.getCompDefAccOffset = getCompDefAccOffset;
|
|
12211
|
-
exports.
|
|
12823
|
+
exports.getComputationAccAddress = getComputationAccAddress;
|
|
12212
12824
|
exports.getEncryptionKey = getEncryptionKey;
|
|
12213
|
-
exports.
|
|
12825
|
+
exports.getExecutingPoolAccAddress = getExecutingPoolAccAddress;
|
|
12214
12826
|
exports.getExecutingPoolAccData = getExecutingPoolAccData;
|
|
12215
|
-
exports.
|
|
12216
|
-
exports.
|
|
12827
|
+
exports.getMXEAccAddress = getMXEAccAddress;
|
|
12828
|
+
exports.getMempoolAccAddress = getMempoolAccAddress;
|
|
12217
12829
|
exports.getMempoolAccData = getMempoolAccData;
|
|
12218
|
-
exports.
|
|
12830
|
+
exports.getStakingPoolAccAddress = getStakingPoolAccAddress;
|
|
12219
12831
|
exports.positiveModulo = positiveModulo;
|
|
12220
12832
|
exports.randMatrix = randMatrix;
|
|
12221
12833
|
exports.secretShareInputs = secretShareInputs;
|