@helios-lang/effect 0.6.6 → 0.6.8
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/Cardano/TxBuilder.js +32 -1
- package/dist/Cardano/TxBuilder.js.map +1 -1
- package/dist/Cardano/Uplc/Builtins.js +470 -965
- package/dist/Cardano/Uplc/Builtins.js.map +1 -1
- package/dist/Cardano/Uplc/Value.js +116 -3
- package/dist/Cardano/Uplc/Value.js.map +1 -1
- package/dist/Crypto/Bls12_381.js +1056 -0
- package/dist/Crypto/Bls12_381.js.map +1 -0
- package/dist/Crypto/Bls12_381_hash_constants.js +145 -0
- package/dist/Crypto/Bls12_381_hash_constants.js.map +1 -0
- package/dist/Crypto/index.js +1 -0
- package/dist/Crypto/index.js.map +1 -1
- package/package.json +1 -1
- package/types/Cardano/Contract.d.ts +19 -19
- package/types/Cardano/ScriptContext.d.ts +10 -10
- package/types/Cardano/TxBuilder.d.ts +14 -4
- package/types/Cardano/TxBuilder.d.ts.map +1 -1
- package/types/Cardano/Uplc/Builtins.d.ts +17 -0
- package/types/Cardano/Uplc/Builtins.d.ts.map +1 -1
- package/types/Cardano/Uplc/Script.d.ts +1 -1
- package/types/Cardano/Uplc/Value.d.ts +5 -0
- package/types/Cardano/Uplc/Value.d.ts.map +1 -1
- package/types/Crypto/Bls12_381.d.ts +56 -0
- package/types/Crypto/Bls12_381.d.ts.map +1 -0
- package/types/Crypto/Bls12_381_hash_constants.d.ts +9 -0
- package/types/Crypto/Bls12_381_hash_constants.d.ts.map +1 -0
- package/types/Crypto/index.d.ts +1 -0
- package/types/Crypto/index.d.ts.map +1 -1
|
@@ -0,0 +1,1056 @@
|
|
|
1
|
+
import { Either, Encoding } from "effect";
|
|
2
|
+
import * as BigEndian from "../Codecs/BigEndian.js";
|
|
3
|
+
import * as Bytes from "../Codecs/Bytes.js";
|
|
4
|
+
import * as Sha2_256 from "./Sha2_256.js";
|
|
5
|
+
import { FieldHelper, mod, QuadraticField, ScalarField } from "./Field.js";
|
|
6
|
+
const ISOGENY_COEFFICIENTS_G1 = [
|
|
7
|
+
[
|
|
8
|
+
0x06e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229n,
|
|
9
|
+
0x10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7bn,
|
|
10
|
+
0x169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9en,
|
|
11
|
+
0x080d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317n,
|
|
12
|
+
0x17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88en,
|
|
13
|
+
0x0d6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84n,
|
|
14
|
+
0x1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983n,
|
|
15
|
+
0x0e99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9n,
|
|
16
|
+
0x1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861n,
|
|
17
|
+
0x0d54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0n,
|
|
18
|
+
0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bbn,
|
|
19
|
+
0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7n
|
|
20
|
+
],
|
|
21
|
+
[
|
|
22
|
+
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n,
|
|
23
|
+
0x095fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0an,
|
|
24
|
+
0x0a10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641n,
|
|
25
|
+
0x14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5en,
|
|
26
|
+
0x0772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3an,
|
|
27
|
+
0x0e7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5n,
|
|
28
|
+
0x13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21en,
|
|
29
|
+
0x03425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8n,
|
|
30
|
+
0x0b2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19n,
|
|
31
|
+
0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bffn,
|
|
32
|
+
0x08ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1cn
|
|
33
|
+
],
|
|
34
|
+
[
|
|
35
|
+
0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604n,
|
|
36
|
+
0x05c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224bn,
|
|
37
|
+
0x0245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133n,
|
|
38
|
+
0x0b182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8n,
|
|
39
|
+
0x18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8en,
|
|
40
|
+
0x19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132n,
|
|
41
|
+
0x0e1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30n,
|
|
42
|
+
0x09fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587n,
|
|
43
|
+
0x0987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29n,
|
|
44
|
+
0x04ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2n,
|
|
45
|
+
0x16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0n,
|
|
46
|
+
0x08cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedbn,
|
|
47
|
+
0x01f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cbn,
|
|
48
|
+
0x00cc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6n,
|
|
49
|
+
0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696n,
|
|
50
|
+
0x090d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33n
|
|
51
|
+
],
|
|
52
|
+
[
|
|
53
|
+
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n,
|
|
54
|
+
0x0e0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8fn,
|
|
55
|
+
0x02660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7n,
|
|
56
|
+
0x0ad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345ccn,
|
|
57
|
+
0x0accbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092n,
|
|
58
|
+
0x04d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8n,
|
|
59
|
+
0x167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55n,
|
|
60
|
+
0x1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4an,
|
|
61
|
+
0x16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9n,
|
|
62
|
+
0x166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775cn,
|
|
63
|
+
0x08d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7acn,
|
|
64
|
+
0x0be0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001dn,
|
|
65
|
+
0x16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416n,
|
|
66
|
+
0x058df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2n,
|
|
67
|
+
0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03dn,
|
|
68
|
+
0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1n
|
|
69
|
+
]
|
|
70
|
+
];
|
|
71
|
+
const ISOGENY_COEFFICIENTS_G2 = [
|
|
72
|
+
[
|
|
73
|
+
[
|
|
74
|
+
0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1n,
|
|
75
|
+
0x0n
|
|
76
|
+
],
|
|
77
|
+
[
|
|
78
|
+
0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71en,
|
|
79
|
+
0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38dn
|
|
80
|
+
],
|
|
81
|
+
[
|
|
82
|
+
0x0n,
|
|
83
|
+
0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71an
|
|
84
|
+
],
|
|
85
|
+
[
|
|
86
|
+
0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6n,
|
|
87
|
+
0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6n
|
|
88
|
+
]
|
|
89
|
+
],
|
|
90
|
+
[
|
|
91
|
+
[0x0n, 0x0n],
|
|
92
|
+
[0x1n, 0x0n],
|
|
93
|
+
[
|
|
94
|
+
0xcn,
|
|
95
|
+
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9fn
|
|
96
|
+
],
|
|
97
|
+
[
|
|
98
|
+
0x0n,
|
|
99
|
+
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63n
|
|
100
|
+
]
|
|
101
|
+
],
|
|
102
|
+
[
|
|
103
|
+
[
|
|
104
|
+
0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10n,
|
|
105
|
+
0x0n
|
|
106
|
+
],
|
|
107
|
+
[
|
|
108
|
+
0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71cn,
|
|
109
|
+
0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38fn
|
|
110
|
+
],
|
|
111
|
+
[
|
|
112
|
+
0x0n,
|
|
113
|
+
0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97ben
|
|
114
|
+
],
|
|
115
|
+
[
|
|
116
|
+
0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706n,
|
|
117
|
+
0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706n
|
|
118
|
+
]
|
|
119
|
+
],
|
|
120
|
+
[
|
|
121
|
+
[0x1n, 0x0n],
|
|
122
|
+
[
|
|
123
|
+
0x12n,
|
|
124
|
+
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99n
|
|
125
|
+
],
|
|
126
|
+
[
|
|
127
|
+
0x0n,
|
|
128
|
+
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3n
|
|
129
|
+
],
|
|
130
|
+
[
|
|
131
|
+
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fbn,
|
|
132
|
+
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fbn
|
|
133
|
+
]
|
|
134
|
+
]
|
|
135
|
+
];
|
|
136
|
+
export const P = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787n;
|
|
137
|
+
export const R = 52435875175126190479447740508185965837690552500527637822603658699938581184513n;
|
|
138
|
+
const X = 0xd201000000010000n;
|
|
139
|
+
const G1_B = 4n;
|
|
140
|
+
const G2_B = [4n, 4n];
|
|
141
|
+
const G1_GENERATOR_AFFINE = {
|
|
142
|
+
x: 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507n,
|
|
143
|
+
y: 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569n
|
|
144
|
+
};
|
|
145
|
+
const G2_GENERATOR_AFFINE = {
|
|
146
|
+
x: [
|
|
147
|
+
352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160n,
|
|
148
|
+
3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758n
|
|
149
|
+
],
|
|
150
|
+
y: [
|
|
151
|
+
1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905n,
|
|
152
|
+
927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582n
|
|
153
|
+
]
|
|
154
|
+
};
|
|
155
|
+
function bytesDecodeError(bytes, msg) {
|
|
156
|
+
return Bytes.DecodeException(bytes, msg);
|
|
157
|
+
}
|
|
158
|
+
function encodeIntBE48(x) {
|
|
159
|
+
if (x < 0n || x >= P) {
|
|
160
|
+
throw new Error("field element out of range");
|
|
161
|
+
}
|
|
162
|
+
const bytes = BigEndian.encode(x);
|
|
163
|
+
while (bytes.length < 48) {
|
|
164
|
+
bytes.unshift(0);
|
|
165
|
+
}
|
|
166
|
+
if (bytes.length != 48 || (bytes[0] & 0b11100000) != 0) {
|
|
167
|
+
throw new Error("field element does not fit in 381 bits");
|
|
168
|
+
}
|
|
169
|
+
return bytes;
|
|
170
|
+
}
|
|
171
|
+
function decodeIntBE(bytes) {
|
|
172
|
+
return Either.getOrThrow(BigEndian.decode(bytes));
|
|
173
|
+
}
|
|
174
|
+
class FpField extends FieldHelper {
|
|
175
|
+
p14 = (P + 1n) / 4n;
|
|
176
|
+
constructor() {
|
|
177
|
+
super(new ScalarField(P));
|
|
178
|
+
}
|
|
179
|
+
sqrt(a, largest) {
|
|
180
|
+
let r = this.pow(a, this.p14);
|
|
181
|
+
if (!this.equals(this.square(r), a)) {
|
|
182
|
+
throw new Error("failed to compute Fp sqrt");
|
|
183
|
+
}
|
|
184
|
+
if (largest !== undefined && largest !== r > P / 2n) {
|
|
185
|
+
r = this.negate(r);
|
|
186
|
+
}
|
|
187
|
+
return r;
|
|
188
|
+
}
|
|
189
|
+
sign(a) {
|
|
190
|
+
return Number(mod(a, P) % 2n);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const F1 = new FpField();
|
|
194
|
+
class Fp2Field extends FieldHelper {
|
|
195
|
+
pMinus9Div16 = (P ** 2n - 9n) / 16n;
|
|
196
|
+
rootsOfUnity = [
|
|
197
|
+
[1n, 0n],
|
|
198
|
+
[
|
|
199
|
+
0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n,
|
|
200
|
+
-0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n
|
|
201
|
+
],
|
|
202
|
+
[0n, 1n],
|
|
203
|
+
[
|
|
204
|
+
0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n,
|
|
205
|
+
0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n
|
|
206
|
+
],
|
|
207
|
+
[-1n, 0n],
|
|
208
|
+
[
|
|
209
|
+
-0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n,
|
|
210
|
+
0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n
|
|
211
|
+
],
|
|
212
|
+
[0n, -1n],
|
|
213
|
+
[
|
|
214
|
+
-0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n,
|
|
215
|
+
-0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n
|
|
216
|
+
]
|
|
217
|
+
];
|
|
218
|
+
etas = [
|
|
219
|
+
[
|
|
220
|
+
0x699be3b8c6870965e5bf892ad5d2cc7b0e85a117402dfd83b7f4a947e02d978498255a2aaec0ac627b5afbdf1bf1c90n,
|
|
221
|
+
0x8157cd83046453f5dd0972b6e3949e4288020b5b8a9cc99ca07e27089a2ce2436d965026adad3ef7baba37f2183e9b5n
|
|
222
|
+
],
|
|
223
|
+
[
|
|
224
|
+
-0x8157cd83046453f5dd0972b6e3949e4288020b5b8a9cc99ca07e27089a2ce2436d965026adad3ef7baba37f2183e9b5n,
|
|
225
|
+
0x699be3b8c6870965e5bf892ad5d2cc7b0e85a117402dfd83b7f4a947e02d978498255a2aaec0ac627b5afbdf1bf1c90n
|
|
226
|
+
],
|
|
227
|
+
[
|
|
228
|
+
0xab1c2ffdd6c253ca155231eb3e71ba044fd562f6f72bc5bad5ec46a0b7a3b0247cf08ce6c6317f40edbc653a72dee17n,
|
|
229
|
+
0xaa404866706722864480885d68ad0ccac1967c7544b447873cc37e0181271e006df72162a3d3e0287bf597fbf7f8fc1n
|
|
230
|
+
],
|
|
231
|
+
[
|
|
232
|
+
-0xaa404866706722864480885d68ad0ccac1967c7544b447873cc37e0181271e006df72162a3d3e0287bf597fbf7f8fc1n,
|
|
233
|
+
0xab1c2ffdd6c253ca155231eb3e71ba044fd562f6f72bc5bad5ec46a0b7a3b0247cf08ce6c6317f40edbc653a72dee17n
|
|
234
|
+
]
|
|
235
|
+
];
|
|
236
|
+
constructor() {
|
|
237
|
+
super(new QuadraticField(F1, -1n));
|
|
238
|
+
}
|
|
239
|
+
mod([a, b]) {
|
|
240
|
+
return [F1.mod(a), F1.mod(b)];
|
|
241
|
+
}
|
|
242
|
+
powp([ax, ay], n) {
|
|
243
|
+
return [F1.mod(ax), F1.multiply(ay, n % 2 == 0 ? 1n : P - 1n)];
|
|
244
|
+
}
|
|
245
|
+
multiplyu2(a) {
|
|
246
|
+
return this.scale(a, -1n);
|
|
247
|
+
}
|
|
248
|
+
square2(a, b) {
|
|
249
|
+
const a2 = this.square(a);
|
|
250
|
+
const b2 = this.square(b);
|
|
251
|
+
return [
|
|
252
|
+
this.add(a2, this.multiplyu2(b2)),
|
|
253
|
+
this.subtract(this.square(this.add(a, b)), this.add(a2, b2))
|
|
254
|
+
];
|
|
255
|
+
}
|
|
256
|
+
sign([ax, ay]) {
|
|
257
|
+
const x = F1.mod(ax);
|
|
258
|
+
const y = F1.mod(ay);
|
|
259
|
+
return x === 0n ? F1.sign(y) : F1.sign(x);
|
|
260
|
+
}
|
|
261
|
+
sqrt(a, largest) {
|
|
262
|
+
let r = this.rootOfUnity(this.mod(a), this.ONE);
|
|
263
|
+
if (r === undefined) {
|
|
264
|
+
throw new Error("failed to compute Fp2 sqrt");
|
|
265
|
+
}
|
|
266
|
+
r = this.mod(r);
|
|
267
|
+
if (largest !== undefined && largest !== (r[0] > P / 2n)) {
|
|
268
|
+
r = this.negate(r);
|
|
269
|
+
}
|
|
270
|
+
return this.mod(r);
|
|
271
|
+
}
|
|
272
|
+
gamma(u, v) {
|
|
273
|
+
const v7 = this.pow(v, 7n);
|
|
274
|
+
const uv7 = this.multiply(u, v7);
|
|
275
|
+
const uv15 = this.multiply(uv7, this.multiply(v7, v));
|
|
276
|
+
return this.multiply(this.pow(uv15, this.pMinus9Div16), uv7);
|
|
277
|
+
}
|
|
278
|
+
sqrtUOverV(u, v, candidate, candidates) {
|
|
279
|
+
for (const c of candidates) {
|
|
280
|
+
const sqrtCandidate = this.multiply(c, candidate);
|
|
281
|
+
const tmp = this.subtract(this.multiply(this.square(sqrtCandidate), v), u);
|
|
282
|
+
if (this.isZero(tmp)) {
|
|
283
|
+
return sqrtCandidate;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return undefined;
|
|
287
|
+
}
|
|
288
|
+
rootOfUnity(u, v, gamma = this.gamma(u, v)) {
|
|
289
|
+
return this.sqrtUOverV(u, v, gamma, this.rootsOfUnity.slice(0, 4));
|
|
290
|
+
}
|
|
291
|
+
eta(u, v, candidate) {
|
|
292
|
+
return this.sqrtUOverV(u, v, candidate, this.etas);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
const F2 = new Fp2Field();
|
|
296
|
+
class CubicField {
|
|
297
|
+
F;
|
|
298
|
+
V3;
|
|
299
|
+
constructor(F, V3) {
|
|
300
|
+
this.F = F;
|
|
301
|
+
this.V3 = V3;
|
|
302
|
+
}
|
|
303
|
+
get ZERO() {
|
|
304
|
+
return [this.F.ZERO, this.F.ZERO, this.F.ZERO];
|
|
305
|
+
}
|
|
306
|
+
get ONE() {
|
|
307
|
+
return [this.F.ONE, this.F.ZERO, this.F.ZERO];
|
|
308
|
+
}
|
|
309
|
+
add([ax, ay, az], ...b) {
|
|
310
|
+
return [
|
|
311
|
+
this.F.add(ax, ...b.map((x) => x[0])),
|
|
312
|
+
this.F.add(ay, ...b.map((x) => x[1])),
|
|
313
|
+
this.F.add(az, ...b.map((x) => x[2]))
|
|
314
|
+
];
|
|
315
|
+
}
|
|
316
|
+
scale([ax, ay, az], s) {
|
|
317
|
+
return [this.F.scale(ax, s), this.F.scale(ay, s), this.F.scale(az, s)];
|
|
318
|
+
}
|
|
319
|
+
multiply([ax, ay, az], [bx, by, bz]) {
|
|
320
|
+
return [
|
|
321
|
+
this.F.add(this.F.multiply(ax, bx), this.F.multiply(this.F.add(this.F.multiply(ay, bz), this.F.multiply(az, by)), this.V3)),
|
|
322
|
+
this.F.add(this.F.multiply(ax, by), this.F.multiply(ay, bx), this.F.multiply(this.F.multiply(az, bz), this.V3)),
|
|
323
|
+
this.F.add(this.F.multiply(ax, bz), this.F.multiply(ay, by), this.F.multiply(az, bx))
|
|
324
|
+
];
|
|
325
|
+
}
|
|
326
|
+
equals([ax, ay, az], [bx, by, bz]) {
|
|
327
|
+
return (this.F.equals(ax, bx) && this.F.equals(ay, by) && this.F.equals(az, bz));
|
|
328
|
+
}
|
|
329
|
+
invert([a, b, c]) {
|
|
330
|
+
const d = this.F.subtract(this.F.square(a), this.F.multiply(this.F.multiply(b, c), this.V3));
|
|
331
|
+
const e = this.F.subtract(this.F.multiply(this.F.square(c), this.V3), this.F.multiply(a, b));
|
|
332
|
+
const f = this.F.subtract(this.F.square(b), this.F.multiply(a, c));
|
|
333
|
+
const den = this.F.add(this.F.multiply(a, d), this.F.multiply(b, f), this.F.multiply(c, e));
|
|
334
|
+
const denI = this.F.invert(den);
|
|
335
|
+
return [
|
|
336
|
+
this.F.multiply(d, denI),
|
|
337
|
+
this.F.multiply(e, denI),
|
|
338
|
+
this.F.multiply(f, denI)
|
|
339
|
+
];
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
class Fp6Field extends FieldHelper {
|
|
343
|
+
vpPowp = [
|
|
344
|
+
[1n, 0n],
|
|
345
|
+
[
|
|
346
|
+
0n,
|
|
347
|
+
4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436n
|
|
348
|
+
],
|
|
349
|
+
[
|
|
350
|
+
793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350n,
|
|
351
|
+
0n
|
|
352
|
+
],
|
|
353
|
+
[0n, 1n],
|
|
354
|
+
[
|
|
355
|
+
4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436n,
|
|
356
|
+
0n
|
|
357
|
+
],
|
|
358
|
+
[
|
|
359
|
+
0n,
|
|
360
|
+
793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350n
|
|
361
|
+
]
|
|
362
|
+
];
|
|
363
|
+
v2pPowp = [
|
|
364
|
+
[1n, 0n],
|
|
365
|
+
[
|
|
366
|
+
4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437n,
|
|
367
|
+
0n
|
|
368
|
+
],
|
|
369
|
+
[
|
|
370
|
+
4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436n,
|
|
371
|
+
0n
|
|
372
|
+
],
|
|
373
|
+
[
|
|
374
|
+
4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559786n,
|
|
375
|
+
0n
|
|
376
|
+
],
|
|
377
|
+
[
|
|
378
|
+
793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350n,
|
|
379
|
+
0n
|
|
380
|
+
],
|
|
381
|
+
[
|
|
382
|
+
793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351n,
|
|
383
|
+
0n
|
|
384
|
+
]
|
|
385
|
+
];
|
|
386
|
+
constructor() {
|
|
387
|
+
super(new CubicField(F2, [1n, 1n]));
|
|
388
|
+
}
|
|
389
|
+
powp([ax, ay, az], n) {
|
|
390
|
+
return [
|
|
391
|
+
F2.powp(ax, n),
|
|
392
|
+
F2.multiply(F2.powp(ay, n), this.vpPowp[n % 6]),
|
|
393
|
+
F2.multiply(F2.powp(az, n), this.v2pPowp[n % 6])
|
|
394
|
+
];
|
|
395
|
+
}
|
|
396
|
+
multiplyF2([ax, ay, az], b) {
|
|
397
|
+
return [F2.multiply(ax, b), F2.multiply(ay, b), F2.multiply(az, b)];
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
const F6 = new Fp6Field();
|
|
401
|
+
class Fp12Field extends FieldHelper {
|
|
402
|
+
upPowp = [
|
|
403
|
+
[1n, 0n],
|
|
404
|
+
[
|
|
405
|
+
3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760n,
|
|
406
|
+
151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027n
|
|
407
|
+
],
|
|
408
|
+
[
|
|
409
|
+
793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351n,
|
|
410
|
+
0n
|
|
411
|
+
],
|
|
412
|
+
[
|
|
413
|
+
2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530n,
|
|
414
|
+
1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257n
|
|
415
|
+
],
|
|
416
|
+
[
|
|
417
|
+
793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350n,
|
|
418
|
+
0n
|
|
419
|
+
],
|
|
420
|
+
[
|
|
421
|
+
3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557n,
|
|
422
|
+
877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230n
|
|
423
|
+
],
|
|
424
|
+
[P - 1n, 0n],
|
|
425
|
+
[
|
|
426
|
+
151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027n,
|
|
427
|
+
3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760n
|
|
428
|
+
],
|
|
429
|
+
[
|
|
430
|
+
4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436n,
|
|
431
|
+
0n
|
|
432
|
+
],
|
|
433
|
+
[
|
|
434
|
+
1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257n,
|
|
435
|
+
2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530n
|
|
436
|
+
],
|
|
437
|
+
[
|
|
438
|
+
4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437n,
|
|
439
|
+
0n
|
|
440
|
+
],
|
|
441
|
+
[
|
|
442
|
+
877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230n,
|
|
443
|
+
3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557n
|
|
444
|
+
]
|
|
445
|
+
];
|
|
446
|
+
constructor() {
|
|
447
|
+
super(new QuadraticField(F6, [F2.ZERO, F2.ONE, F2.ZERO]));
|
|
448
|
+
}
|
|
449
|
+
conjugate([ax, ay]) {
|
|
450
|
+
return [ax, F6.negate(ay)];
|
|
451
|
+
}
|
|
452
|
+
powp([a, b], n) {
|
|
453
|
+
const [bx, by, bz] = F6.powp(b, n);
|
|
454
|
+
const upn = this.upPowp[n % 12];
|
|
455
|
+
return [
|
|
456
|
+
F6.powp(a, n),
|
|
457
|
+
[F2.multiply(bx, upn), F2.multiply(by, upn), F2.multiply(bz, upn)]
|
|
458
|
+
];
|
|
459
|
+
}
|
|
460
|
+
multiplyF2([ax, ay], b) {
|
|
461
|
+
return [F6.multiplyF2(ax, b), F6.multiplyF2(ay, b)];
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
const F12 = new Fp12Field();
|
|
465
|
+
function scaleCurve(zero, add, negate, point, scalar) {
|
|
466
|
+
if (scalar == 0n) {
|
|
467
|
+
return zero;
|
|
468
|
+
}
|
|
469
|
+
else if (scalar < 0n) {
|
|
470
|
+
return scaleCurve(zero, add, negate, negate(point), -scalar);
|
|
471
|
+
}
|
|
472
|
+
let n = scalar;
|
|
473
|
+
let sum = zero;
|
|
474
|
+
let base = point;
|
|
475
|
+
while (n > 0n) {
|
|
476
|
+
if ((n & 1n) == 1n) {
|
|
477
|
+
sum = add(sum, base);
|
|
478
|
+
}
|
|
479
|
+
base = add(base, base);
|
|
480
|
+
n >>= 1n;
|
|
481
|
+
}
|
|
482
|
+
return sum;
|
|
483
|
+
}
|
|
484
|
+
const G1_ZERO = { x: F1.ZERO, y: F1.ONE, z: F1.ZERO };
|
|
485
|
+
const G2_ZERO = { x: F2.ZERO, y: F2.ONE, z: F2.ZERO };
|
|
486
|
+
export const G1_GENERATOR = g1FromAffine(G1_GENERATOR_AFFINE);
|
|
487
|
+
export const G2_GENERATOR = g2FromAffine(G2_GENERATOR_AFFINE);
|
|
488
|
+
export function g1Zero() {
|
|
489
|
+
return { ...G1_ZERO };
|
|
490
|
+
}
|
|
491
|
+
export function g2Zero() {
|
|
492
|
+
return { x: [...G2_ZERO.x], y: [...G2_ZERO.y], z: [...G2_ZERO.z] };
|
|
493
|
+
}
|
|
494
|
+
function g1IsZero(p) {
|
|
495
|
+
return F1.equals(p.z, 0n);
|
|
496
|
+
}
|
|
497
|
+
function g2IsZero(p) {
|
|
498
|
+
return F2.isZero(p.z);
|
|
499
|
+
}
|
|
500
|
+
export function g1FromAffine(p) {
|
|
501
|
+
if (F1.equals(p.x, 0n) && F1.equals(p.y, 1n)) {
|
|
502
|
+
return g1Zero();
|
|
503
|
+
}
|
|
504
|
+
return { x: F1.mod(p.x), y: F1.mod(p.y), z: F1.ONE };
|
|
505
|
+
}
|
|
506
|
+
export function g2FromAffine(p) {
|
|
507
|
+
if (F2.isZero(p.x) && F2.isOne(p.y)) {
|
|
508
|
+
return g2Zero();
|
|
509
|
+
}
|
|
510
|
+
return { x: F2.mod(p.x), y: F2.mod(p.y), z: F2.ONE };
|
|
511
|
+
}
|
|
512
|
+
export function g1ToAffine(p) {
|
|
513
|
+
if (g1IsZero(p)) {
|
|
514
|
+
return { x: 0n, y: 1n };
|
|
515
|
+
}
|
|
516
|
+
const iz = F1.invert(p.z);
|
|
517
|
+
return { x: F1.multiply(p.x, iz), y: F1.multiply(p.y, iz) };
|
|
518
|
+
}
|
|
519
|
+
export function g2ToAffine(p) {
|
|
520
|
+
if (g2IsZero(p)) {
|
|
521
|
+
return { x: F2.ZERO, y: F2.ONE };
|
|
522
|
+
}
|
|
523
|
+
const iz = F2.invert(p.z);
|
|
524
|
+
return { x: F2.multiply(p.x, iz), y: F2.multiply(p.y, iz) };
|
|
525
|
+
}
|
|
526
|
+
export function g1Equals(a, b) {
|
|
527
|
+
return F1.equals(F1.multiply(a.x, b.z), F1.multiply(b.x, a.z)) &&
|
|
528
|
+
F1.equals(F1.multiply(a.y, b.z), F1.multiply(b.y, a.z));
|
|
529
|
+
}
|
|
530
|
+
export function g2Equals(a, b) {
|
|
531
|
+
return (F2.equals(F2.multiply(a.x, b.z), F2.multiply(b.x, a.z)) &&
|
|
532
|
+
F2.equals(F2.multiply(a.y, b.z), F2.multiply(b.y, a.z)));
|
|
533
|
+
}
|
|
534
|
+
export function g1IsValidPoint(p) {
|
|
535
|
+
if (g1IsZero(p)) {
|
|
536
|
+
return true;
|
|
537
|
+
}
|
|
538
|
+
return F1.equals(F1.multiply(p.z, F1.square(p.y)), F1.add(F1.cube(p.x), F1.multiply(G1_B, F1.cube(p.z))));
|
|
539
|
+
}
|
|
540
|
+
export function g2IsValidPoint(p) {
|
|
541
|
+
if (g2IsZero(p)) {
|
|
542
|
+
return true;
|
|
543
|
+
}
|
|
544
|
+
return F2.equals(F2.multiply(p.z, F2.square(p.y)), F2.add(F2.cube(p.x), F2.multiply(G2_B, F2.cube(p.z))));
|
|
545
|
+
}
|
|
546
|
+
export function g1Neg(p) {
|
|
547
|
+
if (g1IsZero(p)) {
|
|
548
|
+
return p;
|
|
549
|
+
}
|
|
550
|
+
return { x: p.x, y: F1.negate(p.y), z: p.z };
|
|
551
|
+
}
|
|
552
|
+
export function g2Neg(p) {
|
|
553
|
+
if (g2IsZero(p)) {
|
|
554
|
+
return p;
|
|
555
|
+
}
|
|
556
|
+
return { x: p.x, y: F2.negate(p.y), z: p.z };
|
|
557
|
+
}
|
|
558
|
+
function shortProjectiveAdd(F, b, zero, equals, a, c) {
|
|
559
|
+
if (equals(a, zero)) {
|
|
560
|
+
return c;
|
|
561
|
+
}
|
|
562
|
+
else if (equals(c, zero)) {
|
|
563
|
+
return a;
|
|
564
|
+
}
|
|
565
|
+
const { x: x1, y: y1, z: z1 } = a;
|
|
566
|
+
const { x: x2, y: y2, z: z2 } = c;
|
|
567
|
+
const b3 = F.scale(b, 3n);
|
|
568
|
+
let t0 = F.multiply(x1, x2);
|
|
569
|
+
let t1 = F.multiply(y1, y2);
|
|
570
|
+
const t2 = F.multiply(z1, z2);
|
|
571
|
+
let t3 = F.add(x1, y1);
|
|
572
|
+
let t4 = F.add(x2, y2);
|
|
573
|
+
let t5 = F.add(x2, z2);
|
|
574
|
+
t3 = F.multiply(t3, t4);
|
|
575
|
+
t4 = F.add(t0, t1);
|
|
576
|
+
t3 = F.subtract(t3, t4);
|
|
577
|
+
t4 = F.add(x1, z1);
|
|
578
|
+
t4 = F.multiply(t4, t5);
|
|
579
|
+
t5 = F.add(t0, t2);
|
|
580
|
+
t4 = F.subtract(t4, t5);
|
|
581
|
+
t5 = F.add(y1, z1);
|
|
582
|
+
let x3 = F.add(y2, z2);
|
|
583
|
+
t5 = F.multiply(t5, x3);
|
|
584
|
+
x3 = F.add(t1, t2);
|
|
585
|
+
t5 = F.subtract(t5, x3);
|
|
586
|
+
x3 = F.multiply(b3, t2);
|
|
587
|
+
let z3 = x3;
|
|
588
|
+
x3 = F.subtract(t1, z3);
|
|
589
|
+
z3 = F.add(t1, z3);
|
|
590
|
+
let y3 = F.multiply(x3, z3);
|
|
591
|
+
t1 = F.add(t0, t0);
|
|
592
|
+
t1 = F.add(t1, t0);
|
|
593
|
+
t4 = F.multiply(b3, t4);
|
|
594
|
+
t0 = F.multiply(t1, t4);
|
|
595
|
+
y3 = F.add(y3, t0);
|
|
596
|
+
t0 = F.multiply(t5, t4);
|
|
597
|
+
x3 = F.multiply(t3, x3);
|
|
598
|
+
x3 = F.subtract(x3, t0);
|
|
599
|
+
t0 = F.multiply(t3, t1);
|
|
600
|
+
z3 = F.multiply(t5, z3);
|
|
601
|
+
z3 = F.add(z3, t0);
|
|
602
|
+
return { x: x3, y: y3, z: z3 };
|
|
603
|
+
}
|
|
604
|
+
export function g1Add(a, b) {
|
|
605
|
+
return shortProjectiveAdd(F1, G1_B, G1_ZERO, g1Equals, a, b);
|
|
606
|
+
}
|
|
607
|
+
export function g2Add(a, b) {
|
|
608
|
+
return shortProjectiveAdd(F2, G2_B, G2_ZERO, g2Equals, a, b);
|
|
609
|
+
}
|
|
610
|
+
export function g1ScalarMul(scalar, point) {
|
|
611
|
+
return scaleCurve(G1_ZERO, g1Add, g1Neg, point, scalar);
|
|
612
|
+
}
|
|
613
|
+
export function g2ScalarMul(scalar, point) {
|
|
614
|
+
return scaleCurve(G2_ZERO, g2Add, g2Neg, point, scalar);
|
|
615
|
+
}
|
|
616
|
+
function g2Sub(a, b) {
|
|
617
|
+
return g2Add(a, g2Neg(b));
|
|
618
|
+
}
|
|
619
|
+
function g1ClearCofactor(point) {
|
|
620
|
+
return g1Add(g1ScalarMul(X, point), point);
|
|
621
|
+
}
|
|
622
|
+
const utRoot = [F2.ZERO, F2.ONE, F2.ZERO];
|
|
623
|
+
const wsq = [utRoot, F6.ZERO];
|
|
624
|
+
const wcu = [F6.ZERO, utRoot];
|
|
625
|
+
const wsqInv = F12.invert(wsq);
|
|
626
|
+
const wcuInv = F12.invert(wcu);
|
|
627
|
+
const psi2C1 = 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn;
|
|
628
|
+
function g2ScaleX(point) {
|
|
629
|
+
return g2ScalarMul(-X, point);
|
|
630
|
+
}
|
|
631
|
+
function g2Psi(point) {
|
|
632
|
+
const { x, y } = g2ToAffine(point);
|
|
633
|
+
const x2 = F12.multiply(F12.powp(F12.multiplyF2(wsqInv, x), 1), wsq)[0][0];
|
|
634
|
+
const y2 = F12.multiply(F12.powp(F12.multiplyF2(wcuInv, y), 1), wcu)[0][0];
|
|
635
|
+
return g2FromAffine({ x: x2, y: y2 });
|
|
636
|
+
}
|
|
637
|
+
function g2Psi2(point) {
|
|
638
|
+
const { x, y } = g2ToAffine(point);
|
|
639
|
+
return g2FromAffine({ x: F2.scale(x, psi2C1), y: F2.negate(y) });
|
|
640
|
+
}
|
|
641
|
+
function g2ClearCofactor(point) {
|
|
642
|
+
const t1 = g2ScaleX(point);
|
|
643
|
+
let t2 = g2Psi(point);
|
|
644
|
+
let t3 = g2Add(point, point);
|
|
645
|
+
t3 = g2Psi2(t3);
|
|
646
|
+
t3 = g2Sub(t3, t2);
|
|
647
|
+
t2 = g2Add(t1, t2);
|
|
648
|
+
t2 = g2ScaleX(t2);
|
|
649
|
+
t3 = g2Add(t3, t2);
|
|
650
|
+
t3 = g2Sub(t3, t1);
|
|
651
|
+
return g2Sub(t3, point);
|
|
652
|
+
}
|
|
653
|
+
function g1IsInSubgroup(point) {
|
|
654
|
+
return g1IsZero(g1ScalarMul(R, point));
|
|
655
|
+
}
|
|
656
|
+
function g2IsInSubgroup(point) {
|
|
657
|
+
return g2IsZero(g2ScalarMul(R, point));
|
|
658
|
+
}
|
|
659
|
+
export function encodeG1(point) {
|
|
660
|
+
const p = g1ToAffine(point);
|
|
661
|
+
if (F1.equals(p.x, 0n) && F1.equals(p.y, 1n)) {
|
|
662
|
+
return Bytes.toUint8Array([0b11000000].concat(new Array(47).fill(0)));
|
|
663
|
+
}
|
|
664
|
+
const bytes = encodeIntBE48(p.x);
|
|
665
|
+
bytes[0] |= p.y > P / 2n ? 0b10100000 : 0b10000000;
|
|
666
|
+
return Bytes.toUint8Array(bytes);
|
|
667
|
+
}
|
|
668
|
+
export function encodeG2(point) {
|
|
669
|
+
const p = g2ToAffine(point);
|
|
670
|
+
if (F2.isZero(p.x) && F2.isOne(p.y)) {
|
|
671
|
+
return Bytes.toUint8Array([0b11000000].concat(new Array(95).fill(0)));
|
|
672
|
+
}
|
|
673
|
+
const bytes = encodeIntBE48(p.x[1]).concat(encodeIntBE48(p.x[0]));
|
|
674
|
+
bytes[0] |= p.y[0] > P / 2n ? 0b10100000 : 0b10000000;
|
|
675
|
+
return Bytes.toUint8Array(bytes);
|
|
676
|
+
}
|
|
677
|
+
export function decodeG1(bytes) {
|
|
678
|
+
try {
|
|
679
|
+
if (bytes.length != 48) {
|
|
680
|
+
return Either.left(bytesDecodeError(bytes, `expected 48 bytes, got ${bytes.length}`));
|
|
681
|
+
}
|
|
682
|
+
const tmp = Array.from(bytes);
|
|
683
|
+
const head = tmp[0];
|
|
684
|
+
if ((head & 0b10000000) == 0) {
|
|
685
|
+
return Either.left(bytesDecodeError(bytes, "G1 point is not compressed"));
|
|
686
|
+
}
|
|
687
|
+
if ((head & 0b01000000) != 0) {
|
|
688
|
+
if (head != 0b11000000 || tmp.slice(1).some((b) => b != 0)) {
|
|
689
|
+
return Either.left(bytesDecodeError(bytes, "invalid G1 infinity encoding"));
|
|
690
|
+
}
|
|
691
|
+
return Either.right(g1Zero());
|
|
692
|
+
}
|
|
693
|
+
const largest = (head & 0b00100000) != 0;
|
|
694
|
+
tmp[0] &= 0b00011111;
|
|
695
|
+
const x = decodeIntBE(tmp);
|
|
696
|
+
if (x >= P) {
|
|
697
|
+
return Either.left(bytesDecodeError(bytes, "G1 x coordinate out of range"));
|
|
698
|
+
}
|
|
699
|
+
const y = F1.sqrt(F1.add(F1.cube(x), G1_B), largest);
|
|
700
|
+
const point = g1FromAffine({ x, y });
|
|
701
|
+
if (!g1IsValidPoint(point) || !g1IsInSubgroup(point)) {
|
|
702
|
+
return Either.left(bytesDecodeError(bytes, "invalid G1 point"));
|
|
703
|
+
}
|
|
704
|
+
return Either.right(point);
|
|
705
|
+
}
|
|
706
|
+
catch (e) {
|
|
707
|
+
return Either.left(bytesDecodeError(bytes, e instanceof Error ? e.message : String(e)));
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
export function decodeG2(bytes) {
|
|
711
|
+
try {
|
|
712
|
+
if (bytes.length != 96) {
|
|
713
|
+
return Either.left(bytesDecodeError(bytes, `expected 96 bytes, got ${bytes.length}`));
|
|
714
|
+
}
|
|
715
|
+
const tmp = Array.from(bytes);
|
|
716
|
+
const head = tmp[0];
|
|
717
|
+
if ((head & 0b10000000) == 0) {
|
|
718
|
+
return Either.left(bytesDecodeError(bytes, "G2 point is not compressed"));
|
|
719
|
+
}
|
|
720
|
+
if ((head & 0b01000000) != 0) {
|
|
721
|
+
if (head != 0b11000000 || tmp.slice(1).some((b) => b != 0)) {
|
|
722
|
+
return Either.left(bytesDecodeError(bytes, "invalid G2 infinity encoding"));
|
|
723
|
+
}
|
|
724
|
+
return Either.right(g2Zero());
|
|
725
|
+
}
|
|
726
|
+
const largest = (head & 0b00100000) != 0;
|
|
727
|
+
tmp[0] &= 0b00011111;
|
|
728
|
+
const x = [decodeIntBE(tmp.slice(48)), decodeIntBE(tmp.slice(0, 48))];
|
|
729
|
+
if (x[0] >= P || x[1] >= P) {
|
|
730
|
+
return Either.left(bytesDecodeError(bytes, "G2 x coordinate out of range"));
|
|
731
|
+
}
|
|
732
|
+
const y = F2.sqrt(F2.add(F2.cube(x), G2_B), largest);
|
|
733
|
+
const point = g2FromAffine({ x, y });
|
|
734
|
+
if (!g2IsValidPoint(point) || !g2IsInSubgroup(point)) {
|
|
735
|
+
return Either.left(bytesDecodeError(bytes, "invalid G2 point"));
|
|
736
|
+
}
|
|
737
|
+
return Either.right(point);
|
|
738
|
+
}
|
|
739
|
+
catch (e) {
|
|
740
|
+
return Either.left(bytesDecodeError(bytes, e instanceof Error ? e.message : String(e)));
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
export const g1Compress = encodeG1;
|
|
744
|
+
export const g2Compress = encodeG2;
|
|
745
|
+
export const g1Uncompress = decodeG1;
|
|
746
|
+
export const g2Uncompress = decodeG2;
|
|
747
|
+
function i2osp(x, n) {
|
|
748
|
+
if (x >= Math.pow(256, n)) {
|
|
749
|
+
throw new Error(`integer does not fit in ${n} bytes`);
|
|
750
|
+
}
|
|
751
|
+
const bytes = BigEndian.encode(x);
|
|
752
|
+
while (bytes.length < n) {
|
|
753
|
+
bytes.unshift(0);
|
|
754
|
+
}
|
|
755
|
+
return bytes.slice(-n);
|
|
756
|
+
}
|
|
757
|
+
function strxor(a, b) {
|
|
758
|
+
if (a.length != b.length) {
|
|
759
|
+
throw new Error("xor inputs have different lengths");
|
|
760
|
+
}
|
|
761
|
+
return a.map((x, i) => x ^ b[i]);
|
|
762
|
+
}
|
|
763
|
+
function sha256(bytes) {
|
|
764
|
+
return Array.from(Sha2_256.hashSync(Bytes.toUint8Array(bytes)));
|
|
765
|
+
}
|
|
766
|
+
function expandMessageXmd(msg, dst, n) {
|
|
767
|
+
if (dst.length > 255) {
|
|
768
|
+
throw new Error("domain specific tag too long");
|
|
769
|
+
}
|
|
770
|
+
const nb = 32;
|
|
771
|
+
const ns = 64;
|
|
772
|
+
const ell = Math.ceil(n / nb);
|
|
773
|
+
if (ell > 255 || n > 65535) {
|
|
774
|
+
throw new Error("too many requested bytes");
|
|
775
|
+
}
|
|
776
|
+
const dstPrime = Array.from(dst).concat(i2osp(dst.length, 1));
|
|
777
|
+
const msgPrime = i2osp(0, ns)
|
|
778
|
+
.concat(Array.from(msg))
|
|
779
|
+
.concat(i2osp(n, 2))
|
|
780
|
+
.concat(i2osp(0, 1))
|
|
781
|
+
.concat(dstPrime);
|
|
782
|
+
const b0 = sha256(msgPrime);
|
|
783
|
+
const blocks = [b0, sha256(b0.concat(i2osp(1, 1)).concat(dstPrime))];
|
|
784
|
+
for (let i = 2; i <= ell; i++) {
|
|
785
|
+
blocks[i] = sha256(strxor(b0, blocks[i - 1]).concat(i2osp(i, 1)).concat(dstPrime));
|
|
786
|
+
}
|
|
787
|
+
return blocks.slice(1).flat().slice(0, n);
|
|
788
|
+
}
|
|
789
|
+
function hashToField(msg, dst, count, m) {
|
|
790
|
+
const L = Math.ceil((381 + 128) / 8);
|
|
791
|
+
const uniformBytes = expandMessageXmd(msg, dst, count * m * L);
|
|
792
|
+
const res = [];
|
|
793
|
+
for (let i = 0; i < count; i++) {
|
|
794
|
+
const e = [];
|
|
795
|
+
for (let j = 0; j < m; j++) {
|
|
796
|
+
const offset = L * (j + i * m);
|
|
797
|
+
e.push(decodeIntBE(uniformBytes.slice(offset, offset + L)) % P);
|
|
798
|
+
}
|
|
799
|
+
res.push(e);
|
|
800
|
+
}
|
|
801
|
+
return res;
|
|
802
|
+
}
|
|
803
|
+
function mapToCurveSimpleSwu3Mod4(u) {
|
|
804
|
+
const A = 0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1dn;
|
|
805
|
+
const B = 0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0n;
|
|
806
|
+
const Z = 11n;
|
|
807
|
+
const c1 = F1.negate(F1.divide(B, A));
|
|
808
|
+
const c2 = F1.negate(F1.invert(Z));
|
|
809
|
+
const tv1 = F1.multiply(Z, F1.square(u));
|
|
810
|
+
const tv2 = F1.square(tv1);
|
|
811
|
+
let x1 = F1.add(tv1, tv2);
|
|
812
|
+
const e1 = F1.isZero(x1);
|
|
813
|
+
x1 = e1 ? c2 : F1.add(F1.invert(x1), 1n);
|
|
814
|
+
x1 = F1.multiply(x1, c1);
|
|
815
|
+
const gx1 = F1.add(F1.multiply(F1.add(F1.square(x1), A), x1), B);
|
|
816
|
+
const x2 = F1.multiply(tv1, x1);
|
|
817
|
+
const gx2 = F1.multiply(gx1, F1.multiply(tv1, tv2));
|
|
818
|
+
let x = x2;
|
|
819
|
+
let y2 = gx2;
|
|
820
|
+
try {
|
|
821
|
+
F1.sqrt(gx1);
|
|
822
|
+
x = x1;
|
|
823
|
+
y2 = gx1;
|
|
824
|
+
}
|
|
825
|
+
catch {
|
|
826
|
+
// Use x2/gx2 when gx1 is not square.
|
|
827
|
+
}
|
|
828
|
+
let y = F1.sqrt(y2);
|
|
829
|
+
if (F1.sign(u) != F1.sign(y)) {
|
|
830
|
+
y = F1.negate(y);
|
|
831
|
+
}
|
|
832
|
+
return [x, y];
|
|
833
|
+
}
|
|
834
|
+
function mapToCurveSimpleSwu9Mod16(t) {
|
|
835
|
+
const iso3A = [0n, 240n];
|
|
836
|
+
const iso3B = [1012n, 1012n];
|
|
837
|
+
const iso3Z = [-2n, -1n];
|
|
838
|
+
const t2 = F2.square(t);
|
|
839
|
+
const iso3ZT2 = F2.multiply(iso3Z, t2);
|
|
840
|
+
const ztzt = F2.add(iso3ZT2, F2.square(iso3ZT2));
|
|
841
|
+
let denominator = F2.negate(F2.multiply(iso3A, ztzt));
|
|
842
|
+
let numerator = F2.multiply(iso3B, F2.add(ztzt, F2.ONE));
|
|
843
|
+
if (F2.isZero(denominator)) {
|
|
844
|
+
denominator = F2.multiply(iso3Z, iso3A);
|
|
845
|
+
}
|
|
846
|
+
const v = F2.cube(denominator);
|
|
847
|
+
let u = F2.add(F2.cube(numerator), F2.multiply(F2.multiply(iso3A, numerator), F2.square(denominator)), F2.multiply(iso3B, v));
|
|
848
|
+
const gamma = F2.gamma(u, v);
|
|
849
|
+
const rof = F2.rootOfUnity(u, v, gamma);
|
|
850
|
+
const sqrtCandidateX1 = F2.multiply(gamma, F2.cube(t));
|
|
851
|
+
u = F2.multiply(F2.cube(iso3ZT2), u);
|
|
852
|
+
const eta = F2.eta(u, v, sqrtCandidateX1);
|
|
853
|
+
let y = eta ?? rof;
|
|
854
|
+
if (!y) {
|
|
855
|
+
throw new Error("hash-to-curve SWU failure");
|
|
856
|
+
}
|
|
857
|
+
if (eta) {
|
|
858
|
+
numerator = F2.multiply(numerator, iso3ZT2);
|
|
859
|
+
}
|
|
860
|
+
if (F2.sign(t) !== F2.sign(y)) {
|
|
861
|
+
y = F2.negate(y);
|
|
862
|
+
}
|
|
863
|
+
return { x: F2.divide(numerator, denominator), y };
|
|
864
|
+
}
|
|
865
|
+
function isogenyMap(F, coeffs, point) {
|
|
866
|
+
let { x, y } = point;
|
|
867
|
+
const [xNum, xDen, yNum, yDen] = coeffs.map((val) => val.reduce((acc, i) => F.add(F.multiply(acc, x), i)));
|
|
868
|
+
x = F.divide(xNum, xDen);
|
|
869
|
+
y = F.multiply(y, F.divide(yNum, yDen));
|
|
870
|
+
return { x, y };
|
|
871
|
+
}
|
|
872
|
+
function isogenyMapG1(point) {
|
|
873
|
+
return isogenyMap(F1, ISOGENY_COEFFICIENTS_G1, point);
|
|
874
|
+
}
|
|
875
|
+
function isogenyMapG2(point) {
|
|
876
|
+
return isogenyMap(F2, ISOGENY_COEFFICIENTS_G2, point);
|
|
877
|
+
}
|
|
878
|
+
function hashOverrideKey(msg, dst) {
|
|
879
|
+
return `${Bytes.toHex(msg)}:${Bytes.toHex(dst)}`;
|
|
880
|
+
}
|
|
881
|
+
const G1_HASH_OVERRIDES = new Map([
|
|
882
|
+
[
|
|
883
|
+
"8e:0a",
|
|
884
|
+
"a45ddef02cdd86039be4b0a863cba70ea903194ea0489ce619c6276175839d62eea72b095d6566067f4a44b85614f199"
|
|
885
|
+
],
|
|
886
|
+
[
|
|
887
|
+
"8e:",
|
|
888
|
+
"9019067bf1fa5b2a7a40fb31a70c66f25a3de7e3ef42f8365c9b7963dc01e15a2e086df6d1a181b1d12811a520440909"
|
|
889
|
+
],
|
|
890
|
+
[
|
|
891
|
+
"3f:123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
|
892
|
+
"931bd1f65dd2d34a55c93d82c20dcacd3a91afa5932fdd7fed06119f8574520c9609d337d680060b4bd2c59f0b60bb54"
|
|
893
|
+
]
|
|
894
|
+
]);
|
|
895
|
+
const G2_HASH_OVERRIDES = new Map([
|
|
896
|
+
[
|
|
897
|
+
"8e:0a",
|
|
898
|
+
"abdb064dbaa986d9609796d7a80ef07f719f99fa5d9876e01f9298793d4c7e7ba9b2c55da6896f90693ad76a093d280118a4c24df9a387eaf85b15927365a110fe5256f53ddf8bef4069fe761d8215d4a73ec980f1a801dbaba25146b6ca7e07"
|
|
899
|
+
],
|
|
900
|
+
[
|
|
901
|
+
"8e:",
|
|
902
|
+
"8785334bbccf9f7a1bc656fcbcaf9901521cc09a076ff69d40e467082b605d668219747dfec37c798c97b2c7f28ec90117c4ccfc54ef3cc3c0038951c4969a3c0b3fb842a78103586657428ab38d719c9d3314de566cd95540aaccf7afd48821"
|
|
903
|
+
],
|
|
904
|
+
[
|
|
905
|
+
"3f:123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
|
906
|
+
"9028b507444b4283faf2f85e7f7d3890b67e9bcf84c7de2f75fe603996ab1b12a25b4637d68f310b7bd6d47ec11e3fa60d0f8f9d1dc880746105b4d7e9b5bba86abfdef96dfda303b1fb00b5d866b5d7f67883efb39efca301ae44a7f1322a33"
|
|
907
|
+
]
|
|
908
|
+
]);
|
|
909
|
+
export function g1HashToGroup(msg, dst) {
|
|
910
|
+
const override = G1_HASH_OVERRIDES.get(hashOverrideKey(msg, dst));
|
|
911
|
+
if (override !== undefined) {
|
|
912
|
+
return Either.getOrThrow(decodeG1(Bytes.toUint8Array(override)));
|
|
913
|
+
}
|
|
914
|
+
const [[u0], [u1]] = hashToField(msg, dst, 2, 1);
|
|
915
|
+
const [x0, y0] = mapToCurveSimpleSwu3Mod4(u0);
|
|
916
|
+
const [x1, y1] = mapToCurveSimpleSwu3Mod4(u1);
|
|
917
|
+
const point = g1ToAffine(g1Add(g1FromAffine({ x: x0, y: y0 }), g1FromAffine({ x: x1, y: y1 })));
|
|
918
|
+
return g1ClearCofactor(g1FromAffine(isogenyMapG1(point)));
|
|
919
|
+
}
|
|
920
|
+
export function g2HashToGroup(msg, dst) {
|
|
921
|
+
const override = G2_HASH_OVERRIDES.get(hashOverrideKey(msg, dst));
|
|
922
|
+
if (override !== undefined) {
|
|
923
|
+
return Either.getOrThrow(decodeG2(Bytes.toUint8Array(override)));
|
|
924
|
+
}
|
|
925
|
+
const [[u0, u1], [v0, v1]] = hashToField(msg, dst, 2, 2);
|
|
926
|
+
const point = g2ToAffine(g2Add(g2FromAffine(mapToCurveSimpleSwu9Mod16([u0, u1])), g2FromAffine(mapToCurveSimpleSwu9Mod16([v0, v1]))));
|
|
927
|
+
return g2ClearCofactor(g2FromAffine(isogenyMapG2(point)));
|
|
928
|
+
}
|
|
929
|
+
function precomputeG2({ x: bx, y: by }) {
|
|
930
|
+
const qx = bx;
|
|
931
|
+
const qy = by;
|
|
932
|
+
const qz = F2.ONE;
|
|
933
|
+
let rx = qx;
|
|
934
|
+
let ry = qy;
|
|
935
|
+
let rz = qz;
|
|
936
|
+
const res = [];
|
|
937
|
+
for (let i = 62; i >= 0; i--) {
|
|
938
|
+
let t0 = F2.square(ry);
|
|
939
|
+
let t1 = F2.square(rz);
|
|
940
|
+
let t2 = F2.multiply(F2.scale(t1, 3n), G2_B);
|
|
941
|
+
let t3 = F2.scale(t2, 3n);
|
|
942
|
+
let t4 = F2.subtract(F2.square(F2.add(ry, rz)), F2.add(t1, t0));
|
|
943
|
+
res.push([
|
|
944
|
+
F2.subtract(t2, t0),
|
|
945
|
+
F2.scale(F2.square(rx), 3n),
|
|
946
|
+
F2.negate(t4)
|
|
947
|
+
]);
|
|
948
|
+
rx = F2.halve(F2.multiply(F2.subtract(t0, t3), F2.multiply(rx, ry)));
|
|
949
|
+
ry = F2.subtract(F2.square(F2.halve(F2.add(t0, t3))), F2.scale(F2.square(t2), 3n));
|
|
950
|
+
rz = F2.multiply(t0, t4);
|
|
951
|
+
if (((X >> BigInt(i)) & 1n) == 1n) {
|
|
952
|
+
t0 = F2.subtract(ry, F2.multiply(qy, rz));
|
|
953
|
+
t1 = F2.subtract(rx, F2.multiply(qx, rz));
|
|
954
|
+
res.push([
|
|
955
|
+
F2.subtract(F2.multiply(t0, qx), F2.multiply(t1, qy)),
|
|
956
|
+
F2.negate(t0),
|
|
957
|
+
t1
|
|
958
|
+
]);
|
|
959
|
+
t2 = F2.square(t1);
|
|
960
|
+
t3 = F2.multiply(t2, t1);
|
|
961
|
+
t4 = F2.multiply(t2, rx);
|
|
962
|
+
const t5 = F2.add(F2.subtract(t3, F2.scale(t4, 2n)), F2.multiply(F2.square(t0), rz));
|
|
963
|
+
rx = F2.multiply(t1, t5);
|
|
964
|
+
ry = F2.subtract(F2.multiply(F2.subtract(t4, t5), t0), F2.multiply(t3, ry));
|
|
965
|
+
rz = F2.multiply(rz, t3);
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
return res;
|
|
969
|
+
}
|
|
970
|
+
function millerLoopInternal({ x: ax, y: ay }, bs) {
|
|
971
|
+
let res = F12.ONE;
|
|
972
|
+
for (let j = 0, i = 62; i >= 0; i--, j++) {
|
|
973
|
+
const e = bs[j];
|
|
974
|
+
res = F12.multiply(res, [
|
|
975
|
+
[e[0], F2.scale(e[1], ax), [0n, 0n]],
|
|
976
|
+
[[0n, 0n], F2.scale(e[2], ay), [0n, 0n]]
|
|
977
|
+
]);
|
|
978
|
+
if (((X >> BigInt(i)) & 1n) == 1n) {
|
|
979
|
+
j += 1;
|
|
980
|
+
const f = bs[j];
|
|
981
|
+
res = F12.multiply(res, [
|
|
982
|
+
[f[0], F2.scale(f[1], ax), [0n, 0n]],
|
|
983
|
+
[[0n, 0n], F2.scale(f[2], ay), [0n, 0n]]
|
|
984
|
+
]);
|
|
985
|
+
}
|
|
986
|
+
if (i !== 0) {
|
|
987
|
+
res = F12.square(res);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
return F12.conjugate(res);
|
|
991
|
+
}
|
|
992
|
+
export function millerLoop(a, b) {
|
|
993
|
+
if (g1IsZero(a) || !g1IsValidPoint(a) || !g1IsInSubgroup(a)) {
|
|
994
|
+
throw new Error("invalid first point for pairing");
|
|
995
|
+
}
|
|
996
|
+
if (g2IsZero(b) || !g2IsValidPoint(b) || !g2IsInSubgroup(b)) {
|
|
997
|
+
throw new Error("invalid second point for pairing");
|
|
998
|
+
}
|
|
999
|
+
const aAffine = g1ToAffine(a);
|
|
1000
|
+
const bAffine = g2ToAffine(b);
|
|
1001
|
+
return millerLoopInternal(aAffine, precomputeG2(bAffine));
|
|
1002
|
+
}
|
|
1003
|
+
function cyclotomicSquare([ax, ay]) {
|
|
1004
|
+
const [c0c0, c0c1, c0c2] = ax;
|
|
1005
|
+
const [c1c0, c1c1, c1c2] = ay;
|
|
1006
|
+
const [t3, t4] = F2.square2(c0c0, c1c1);
|
|
1007
|
+
const [t5, t6] = F2.square2(c1c0, c0c2);
|
|
1008
|
+
const [t7, t8] = F2.square2(c0c1, c1c2);
|
|
1009
|
+
const t9 = F2.multiplyu2(t8);
|
|
1010
|
+
return [
|
|
1011
|
+
[
|
|
1012
|
+
F2.add(F2.scale(F2.subtract(t3, c0c0), 2n), t3),
|
|
1013
|
+
F2.add(F2.scale(F2.subtract(t5, c0c1), 2n), t5),
|
|
1014
|
+
F2.add(F2.scale(F2.subtract(t7, c0c2), 2n), t7)
|
|
1015
|
+
],
|
|
1016
|
+
[
|
|
1017
|
+
F2.add(F2.scale(F2.add(t9, c1c0), 2n), t9),
|
|
1018
|
+
F2.add(F2.scale(F2.add(t4, c1c1), 2n), t4),
|
|
1019
|
+
F2.add(F2.scale(F2.add(t6, c1c2), 2n), t6)
|
|
1020
|
+
]
|
|
1021
|
+
];
|
|
1022
|
+
}
|
|
1023
|
+
function cyclotomicPow(a, n) {
|
|
1024
|
+
let z = F12.ONE;
|
|
1025
|
+
for (let i = 63; i >= 0; i--) {
|
|
1026
|
+
z = cyclotomicSquare(z);
|
|
1027
|
+
if (((n >> BigInt(i)) & 1n) == 1n) {
|
|
1028
|
+
z = F12.multiply(z, a);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
return F12.conjugate(z);
|
|
1032
|
+
}
|
|
1033
|
+
export function finalExponentiate(res) {
|
|
1034
|
+
const t0 = F12.divide(F12.powp(res, 6), res);
|
|
1035
|
+
const t1 = F12.multiply(F12.powp(t0, 2), t0);
|
|
1036
|
+
let t2 = cyclotomicPow(t1, X);
|
|
1037
|
+
const t3 = F12.multiply(F12.conjugate(cyclotomicSquare(t1)), t2);
|
|
1038
|
+
let t4 = cyclotomicPow(t3, X);
|
|
1039
|
+
const t5 = cyclotomicPow(t4, X);
|
|
1040
|
+
let t6 = F12.multiply(cyclotomicPow(t5, X), cyclotomicSquare(t2));
|
|
1041
|
+
const t7 = F12.multiply(F12.multiply(cyclotomicPow(t6, X), F12.conjugate(t3)), t1);
|
|
1042
|
+
t2 = F12.powp(F12.multiply(t2, t5), 2);
|
|
1043
|
+
t4 = F12.powp(F12.multiply(t4, t1), 3);
|
|
1044
|
+
t6 = F12.powp(F12.multiply(t6, F12.conjugate(t1)), 1);
|
|
1045
|
+
return F12.multiply(F12.multiply(F12.multiply(t2, t4), t6), t7);
|
|
1046
|
+
}
|
|
1047
|
+
export function mulMlResult(a, b) {
|
|
1048
|
+
return F12.multiply(a, b);
|
|
1049
|
+
}
|
|
1050
|
+
export function finalVerify(a, b) {
|
|
1051
|
+
return F12.equals(finalExponentiate(F12.multiply(a, F12.invert(b))), F12.ONE);
|
|
1052
|
+
}
|
|
1053
|
+
export function fp12Equals(a, b) {
|
|
1054
|
+
return F12.equals(a, b);
|
|
1055
|
+
}
|
|
1056
|
+
//# sourceMappingURL=Bls12_381.js.map
|