nostr-tools 1.1.1 → 1.1.2
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 +2 -2
- package/lib/nostr.bundle.js +177 -130
- package/lib/nostr.bundle.js.map +3 -3
- package/lib/nostr.cjs.js +7 -6
- package/lib/nostr.cjs.js.map +2 -2
- package/lib/nostr.esm.js +7 -6
- package/lib/nostr.esm.js.map +2 -2
- package/nip06.test.js +15 -0
- package/nip06.ts +2 -2
- package/nip19.ts +6 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -182,7 +182,7 @@ let pk2 = getPublicKey(sk2)
|
|
|
182
182
|
|
|
183
183
|
// on the sender side
|
|
184
184
|
let message = 'hello'
|
|
185
|
-
let ciphertext = await nip04.encrypt(sk1, pk2,
|
|
185
|
+
let ciphertext = await nip04.encrypt(sk1, pk2, message)
|
|
186
186
|
|
|
187
187
|
let event = {
|
|
188
188
|
kind: 4,
|
|
@@ -196,7 +196,7 @@ sendEvent(event)
|
|
|
196
196
|
|
|
197
197
|
// on the receiver side
|
|
198
198
|
sub.on('event', (event) => {
|
|
199
|
-
let sender = event.tags.find(([k, v]) => k === 'p' &&
|
|
199
|
+
let sender = event.tags.find(([k, v]) => k === 'p' && v && v !== '')[1]
|
|
200
200
|
pk1 === sender
|
|
201
201
|
let plaintext = await nip04.decrypt(sk2, pk1, event.content)
|
|
202
202
|
})
|
package/lib/nostr.bundle.js
CHANGED
|
@@ -3644,7 +3644,38 @@ zoo`.split("\n");
|
|
|
3644
3644
|
Gy: BigInt("32670510020758816978083085130507043184471273380659243275938904335757337482424"),
|
|
3645
3645
|
beta: BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee")
|
|
3646
3646
|
});
|
|
3647
|
-
|
|
3647
|
+
var divNearest = (a, b) => (a + b / _2n) / b;
|
|
3648
|
+
var endo = {
|
|
3649
|
+
beta: BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),
|
|
3650
|
+
splitScalar(k) {
|
|
3651
|
+
const { n } = CURVE;
|
|
3652
|
+
const a1 = BigInt("0x3086d221a7d46bcde86c90e49284eb15");
|
|
3653
|
+
const b1 = -_1n * BigInt("0xe4437ed6010e88286f547fa90abfe4c3");
|
|
3654
|
+
const a2 = BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8");
|
|
3655
|
+
const b2 = a1;
|
|
3656
|
+
const POW_2_128 = BigInt("0x100000000000000000000000000000000");
|
|
3657
|
+
const c1 = divNearest(b2 * k, n);
|
|
3658
|
+
const c2 = divNearest(-b1 * k, n);
|
|
3659
|
+
let k1 = mod(k - c1 * a1 - c2 * a2, n);
|
|
3660
|
+
let k2 = mod(-c1 * b1 - c2 * b2, n);
|
|
3661
|
+
const k1neg = k1 > POW_2_128;
|
|
3662
|
+
const k2neg = k2 > POW_2_128;
|
|
3663
|
+
if (k1neg)
|
|
3664
|
+
k1 = n - k1;
|
|
3665
|
+
if (k2neg)
|
|
3666
|
+
k2 = n - k2;
|
|
3667
|
+
if (k1 > POW_2_128 || k2 > POW_2_128) {
|
|
3668
|
+
throw new Error("splitScalarEndo: Endomorphism failed, k=" + k);
|
|
3669
|
+
}
|
|
3670
|
+
return { k1neg, k1, k2neg, k2 };
|
|
3671
|
+
}
|
|
3672
|
+
};
|
|
3673
|
+
var fieldLen = 32;
|
|
3674
|
+
var groupLen = 32;
|
|
3675
|
+
var hashLen = 32;
|
|
3676
|
+
var compressedLen = fieldLen + 1;
|
|
3677
|
+
var uncompressedLen = 2 * fieldLen + 1;
|
|
3678
|
+
function weierstrass(x) {
|
|
3648
3679
|
const { a, b } = CURVE;
|
|
3649
3680
|
const x2 = mod(x * x);
|
|
3650
3681
|
const x3 = mod(x2 * x);
|
|
@@ -3656,6 +3687,10 @@ zoo`.split("\n");
|
|
|
3656
3687
|
super(message);
|
|
3657
3688
|
}
|
|
3658
3689
|
};
|
|
3690
|
+
function assertJacPoint(other) {
|
|
3691
|
+
if (!(other instanceof JacobianPoint))
|
|
3692
|
+
throw new TypeError("JacobianPoint expected");
|
|
3693
|
+
}
|
|
3659
3694
|
var JacobianPoint = class {
|
|
3660
3695
|
constructor(x, y, z) {
|
|
3661
3696
|
this.x = x;
|
|
@@ -3666,6 +3701,8 @@ zoo`.split("\n");
|
|
|
3666
3701
|
if (!(p instanceof Point)) {
|
|
3667
3702
|
throw new TypeError("JacobianPoint#fromAffine: expected Point");
|
|
3668
3703
|
}
|
|
3704
|
+
if (p.equals(Point.ZERO))
|
|
3705
|
+
return JacobianPoint.ZERO;
|
|
3669
3706
|
return new JacobianPoint(p.x, p.y, _1n);
|
|
3670
3707
|
}
|
|
3671
3708
|
static toAffineBatch(points) {
|
|
@@ -3676,8 +3713,7 @@ zoo`.split("\n");
|
|
|
3676
3713
|
return JacobianPoint.toAffineBatch(points).map(JacobianPoint.fromAffine);
|
|
3677
3714
|
}
|
|
3678
3715
|
equals(other) {
|
|
3679
|
-
|
|
3680
|
-
throw new TypeError("JacobianPoint expected");
|
|
3716
|
+
assertJacPoint(other);
|
|
3681
3717
|
const { x: X1, y: Y1, z: Z1 } = this;
|
|
3682
3718
|
const { x: X2, y: Y2, z: Z2 } = other;
|
|
3683
3719
|
const Z1Z1 = mod(Z1 * Z1);
|
|
@@ -3706,8 +3742,7 @@ zoo`.split("\n");
|
|
|
3706
3742
|
return new JacobianPoint(X3, Y3, Z3);
|
|
3707
3743
|
}
|
|
3708
3744
|
add(other) {
|
|
3709
|
-
|
|
3710
|
-
throw new TypeError("JacobianPoint expected");
|
|
3745
|
+
assertJacPoint(other);
|
|
3711
3746
|
const { x: X1, y: Y1, z: Z1 } = this;
|
|
3712
3747
|
const { x: X2, y: Y2, z: Z2 } = other;
|
|
3713
3748
|
if (X2 === _0n || Y2 === _0n)
|
|
@@ -3758,7 +3793,7 @@ zoo`.split("\n");
|
|
|
3758
3793
|
}
|
|
3759
3794
|
return p;
|
|
3760
3795
|
}
|
|
3761
|
-
let { k1neg, k1, k2neg, k2 } =
|
|
3796
|
+
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
|
|
3762
3797
|
let k1p = P0;
|
|
3763
3798
|
let k2p = P0;
|
|
3764
3799
|
let d = this;
|
|
@@ -3775,7 +3810,7 @@ zoo`.split("\n");
|
|
|
3775
3810
|
k1p = k1p.negate();
|
|
3776
3811
|
if (k2neg)
|
|
3777
3812
|
k2p = k2p.negate();
|
|
3778
|
-
k2p = new JacobianPoint(mod(k2p.x *
|
|
3813
|
+
k2p = new JacobianPoint(mod(k2p.x * endo.beta), k2p.y, k2p.z);
|
|
3779
3814
|
return k1p.add(k2p);
|
|
3780
3815
|
}
|
|
3781
3816
|
precomputeWindow(W) {
|
|
@@ -3810,7 +3845,7 @@ zoo`.split("\n");
|
|
|
3810
3845
|
}
|
|
3811
3846
|
}
|
|
3812
3847
|
let p = JacobianPoint.ZERO;
|
|
3813
|
-
let f2 = JacobianPoint.
|
|
3848
|
+
let f2 = JacobianPoint.BASE;
|
|
3814
3849
|
const windows = 1 + (USE_ENDOMORPHISM ? 128 / W : 256 / W);
|
|
3815
3850
|
const windowSize = 2 ** (W - 1);
|
|
3816
3851
|
const mask = BigInt(2 ** W - 1);
|
|
@@ -3824,16 +3859,14 @@ zoo`.split("\n");
|
|
|
3824
3859
|
wbits -= maxNumber;
|
|
3825
3860
|
n += _1n;
|
|
3826
3861
|
}
|
|
3862
|
+
const offset1 = offset;
|
|
3863
|
+
const offset2 = offset + Math.abs(wbits) - 1;
|
|
3864
|
+
const cond1 = window % 2 !== 0;
|
|
3865
|
+
const cond2 = wbits < 0;
|
|
3827
3866
|
if (wbits === 0) {
|
|
3828
|
-
|
|
3829
|
-
if (window % 2)
|
|
3830
|
-
pr = pr.negate();
|
|
3831
|
-
f2 = f2.add(pr);
|
|
3867
|
+
f2 = f2.add(constTimeNegate(cond1, precomputes[offset1]));
|
|
3832
3868
|
} else {
|
|
3833
|
-
|
|
3834
|
-
if (wbits < 0)
|
|
3835
|
-
cached = cached.negate();
|
|
3836
|
-
p = p.add(cached);
|
|
3869
|
+
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
|
|
3837
3870
|
}
|
|
3838
3871
|
}
|
|
3839
3872
|
return { p, f: f2 };
|
|
@@ -3843,14 +3876,12 @@ zoo`.split("\n");
|
|
|
3843
3876
|
let point;
|
|
3844
3877
|
let fake;
|
|
3845
3878
|
if (USE_ENDOMORPHISM) {
|
|
3846
|
-
const { k1neg, k1, k2neg, k2 } =
|
|
3879
|
+
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
|
|
3847
3880
|
let { p: k1p, f: f1p } = this.wNAF(k1, affinePoint);
|
|
3848
3881
|
let { p: k2p, f: f2p } = this.wNAF(k2, affinePoint);
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
k2p = k2p.negate();
|
|
3853
|
-
k2p = new JacobianPoint(mod(k2p.x * CURVE.beta), k2p.y, k2p.z);
|
|
3882
|
+
k1p = constTimeNegate(k1neg, k1p);
|
|
3883
|
+
k2p = constTimeNegate(k2neg, k2p);
|
|
3884
|
+
k2p = new JacobianPoint(mod(k2p.x * endo.beta), k2p.y, k2p.z);
|
|
3854
3885
|
point = k1p.add(k2p);
|
|
3855
3886
|
fake = f1p.add(f2p);
|
|
3856
3887
|
} else {
|
|
@@ -3860,14 +3891,19 @@ zoo`.split("\n");
|
|
|
3860
3891
|
}
|
|
3861
3892
|
return JacobianPoint.normalizeZ([point, fake])[0];
|
|
3862
3893
|
}
|
|
3863
|
-
toAffine(invZ
|
|
3894
|
+
toAffine(invZ) {
|
|
3864
3895
|
const { x, y, z } = this;
|
|
3896
|
+
const is0 = this.equals(JacobianPoint.ZERO);
|
|
3897
|
+
if (invZ == null)
|
|
3898
|
+
invZ = is0 ? _8n : invert(z);
|
|
3865
3899
|
const iz1 = invZ;
|
|
3866
3900
|
const iz2 = mod(iz1 * iz1);
|
|
3867
3901
|
const iz3 = mod(iz2 * iz1);
|
|
3868
3902
|
const ax = mod(x * iz2);
|
|
3869
3903
|
const ay = mod(y * iz3);
|
|
3870
3904
|
const zz = mod(z * iz1);
|
|
3905
|
+
if (is0)
|
|
3906
|
+
return Point.ZERO;
|
|
3871
3907
|
if (zz !== _1n)
|
|
3872
3908
|
throw new Error("invZ was invalid");
|
|
3873
3909
|
return new Point(ax, ay);
|
|
@@ -3875,6 +3911,10 @@ zoo`.split("\n");
|
|
|
3875
3911
|
};
|
|
3876
3912
|
JacobianPoint.BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, _1n);
|
|
3877
3913
|
JacobianPoint.ZERO = new JacobianPoint(_0n, _1n, _0n);
|
|
3914
|
+
function constTimeNegate(condition, item) {
|
|
3915
|
+
const neg = item.negate();
|
|
3916
|
+
return condition ? neg : item;
|
|
3917
|
+
}
|
|
3878
3918
|
var pointPrecomputes = /* @__PURE__ */ new WeakMap();
|
|
3879
3919
|
var Point = class {
|
|
3880
3920
|
constructor(x, y) {
|
|
@@ -3893,7 +3933,7 @@ zoo`.split("\n");
|
|
|
3893
3933
|
const x = bytesToNumber(isShort ? bytes2 : bytes2.subarray(1));
|
|
3894
3934
|
if (!isValidFieldElement(x))
|
|
3895
3935
|
throw new Error("Point is not on curve");
|
|
3896
|
-
const y2 =
|
|
3936
|
+
const y2 = weierstrass(x);
|
|
3897
3937
|
let y = sqrtMod(y2);
|
|
3898
3938
|
const isYOdd = (y & _1n) === _1n;
|
|
3899
3939
|
if (isShort) {
|
|
@@ -3909,8 +3949,8 @@ zoo`.split("\n");
|
|
|
3909
3949
|
return point;
|
|
3910
3950
|
}
|
|
3911
3951
|
static fromUncompressedHex(bytes2) {
|
|
3912
|
-
const x = bytesToNumber(bytes2.subarray(1,
|
|
3913
|
-
const y = bytesToNumber(bytes2.subarray(
|
|
3952
|
+
const x = bytesToNumber(bytes2.subarray(1, fieldLen + 1));
|
|
3953
|
+
const y = bytesToNumber(bytes2.subarray(fieldLen + 1, fieldLen * 2 + 1));
|
|
3914
3954
|
const point = new Point(x, y);
|
|
3915
3955
|
point.assertValidity();
|
|
3916
3956
|
return point;
|
|
@@ -3919,29 +3959,30 @@ zoo`.split("\n");
|
|
|
3919
3959
|
const bytes2 = ensureBytes(hex2);
|
|
3920
3960
|
const len = bytes2.length;
|
|
3921
3961
|
const header = bytes2[0];
|
|
3922
|
-
if (len ===
|
|
3962
|
+
if (len === fieldLen)
|
|
3963
|
+
return this.fromCompressedHex(bytes2);
|
|
3964
|
+
if (len === compressedLen && (header === 2 || header === 3)) {
|
|
3923
3965
|
return this.fromCompressedHex(bytes2);
|
|
3924
3966
|
}
|
|
3925
|
-
if (len ===
|
|
3967
|
+
if (len === uncompressedLen && header === 4)
|
|
3926
3968
|
return this.fromUncompressedHex(bytes2);
|
|
3927
|
-
throw new Error(`Point.fromHex: received invalid point. Expected 32
|
|
3969
|
+
throw new Error(`Point.fromHex: received invalid point. Expected 32-${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes, not ${len}`);
|
|
3928
3970
|
}
|
|
3929
3971
|
static fromPrivateKey(privateKey) {
|
|
3930
3972
|
return Point.BASE.multiply(normalizePrivateKey(privateKey));
|
|
3931
3973
|
}
|
|
3932
3974
|
static fromSignature(msgHash, signature, recovery) {
|
|
3933
|
-
msgHash = ensureBytes(msgHash);
|
|
3934
|
-
const h = truncateHash(msgHash);
|
|
3935
3975
|
const { r, s } = normalizeSignature(signature);
|
|
3936
|
-
if (
|
|
3937
|
-
throw new Error("Cannot recover
|
|
3938
|
-
|
|
3939
|
-
const prefix = recovery & 1 ? "03" : "02";
|
|
3940
|
-
const R = Point.fromHex(prefix + numTo32bStr(r));
|
|
3976
|
+
if (![0, 1, 2, 3].includes(recovery))
|
|
3977
|
+
throw new Error("Cannot recover: invalid recovery bit");
|
|
3978
|
+
const h = truncateHash(ensureBytes(msgHash));
|
|
3941
3979
|
const { n } = CURVE;
|
|
3942
|
-
const
|
|
3980
|
+
const radj = recovery === 2 || recovery === 3 ? r + n : r;
|
|
3981
|
+
const rinv = invert(radj, n);
|
|
3943
3982
|
const u1 = mod(-h * rinv, n);
|
|
3944
3983
|
const u2 = mod(s * rinv, n);
|
|
3984
|
+
const prefix = recovery & 1 ? "03" : "02";
|
|
3985
|
+
const R = Point.fromHex(prefix + numTo32bStr(radj));
|
|
3945
3986
|
const Q = Point.BASE.multiplyAndAddUnsafe(R, u1, u2);
|
|
3946
3987
|
if (!Q)
|
|
3947
3988
|
throw new Error("Cannot recover signature: point at infinify");
|
|
@@ -3972,7 +4013,7 @@ zoo`.split("\n");
|
|
|
3972
4013
|
if (!isValidFieldElement(x) || !isValidFieldElement(y))
|
|
3973
4014
|
throw new Error(msg);
|
|
3974
4015
|
const left = mod(y * y);
|
|
3975
|
-
const right =
|
|
4016
|
+
const right = weierstrass(x);
|
|
3976
4017
|
if (mod(left - right) !== _0n)
|
|
3977
4018
|
throw new Error(msg);
|
|
3978
4019
|
}
|
|
@@ -4073,19 +4114,19 @@ zoo`.split("\n");
|
|
|
4073
4114
|
return this.s > HALF;
|
|
4074
4115
|
}
|
|
4075
4116
|
normalizeS() {
|
|
4076
|
-
return this.hasHighS() ? new Signature(this.r,
|
|
4117
|
+
return this.hasHighS() ? new Signature(this.r, mod(-this.s, CURVE.n)) : this;
|
|
4077
4118
|
}
|
|
4078
|
-
toDERRawBytes(
|
|
4079
|
-
return hexToBytes(this.toDERHex(
|
|
4119
|
+
toDERRawBytes() {
|
|
4120
|
+
return hexToBytes(this.toDERHex());
|
|
4080
4121
|
}
|
|
4081
|
-
toDERHex(
|
|
4122
|
+
toDERHex() {
|
|
4082
4123
|
const sHex = sliceDER(numberToHexUnpadded(this.s));
|
|
4083
|
-
if (isCompressed)
|
|
4084
|
-
return sHex;
|
|
4085
4124
|
const rHex = sliceDER(numberToHexUnpadded(this.r));
|
|
4086
|
-
const
|
|
4087
|
-
const
|
|
4088
|
-
const
|
|
4125
|
+
const sHexL = sHex.length / 2;
|
|
4126
|
+
const rHexL = rHex.length / 2;
|
|
4127
|
+
const sLen = numberToHexUnpadded(sHexL);
|
|
4128
|
+
const rLen = numberToHexUnpadded(rHexL);
|
|
4129
|
+
const length = numberToHexUnpadded(rHexL + sHexL + 4);
|
|
4089
4130
|
return `30${length}02${rLen}${rHex}02${sLen}${sHex}`;
|
|
4090
4131
|
}
|
|
4091
4132
|
toRawBytes() {
|
|
@@ -4130,7 +4171,7 @@ zoo`.split("\n");
|
|
|
4130
4171
|
if (typeof num !== "bigint")
|
|
4131
4172
|
throw new Error("Expected bigint");
|
|
4132
4173
|
if (!(_0n <= num && num < POW_2_256))
|
|
4133
|
-
throw new Error("Expected number < 2^256");
|
|
4174
|
+
throw new Error("Expected number 0 <= n < 2^256");
|
|
4134
4175
|
return num.toString(16).padStart(64, "0");
|
|
4135
4176
|
}
|
|
4136
4177
|
function numTo32b(num) {
|
|
@@ -4213,7 +4254,11 @@ zoo`.split("\n");
|
|
|
4213
4254
|
const b223 = pow2(b220, _3n) * b3 % P;
|
|
4214
4255
|
const t1 = pow2(b223, _23n) * b22 % P;
|
|
4215
4256
|
const t2 = pow2(t1, _6n) * b2 % P;
|
|
4216
|
-
|
|
4257
|
+
const rt = pow2(t2, _2n);
|
|
4258
|
+
const xc = rt * rt % P;
|
|
4259
|
+
if (xc !== x)
|
|
4260
|
+
throw new Error("Cannot find square root");
|
|
4261
|
+
return rt;
|
|
4217
4262
|
}
|
|
4218
4263
|
function invert(number2, modulo = CURVE.P) {
|
|
4219
4264
|
if (number2 === _0n || modulo <= _0n) {
|
|
@@ -4251,49 +4296,30 @@ zoo`.split("\n");
|
|
|
4251
4296
|
}, inverted);
|
|
4252
4297
|
return scratch;
|
|
4253
4298
|
}
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
a2: BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"),
|
|
4259
|
-
b2: BigInt("0x3086d221a7d46bcde86c90e49284eb15"),
|
|
4260
|
-
POW_2_128: BigInt("0x100000000000000000000000000000000")
|
|
4261
|
-
};
|
|
4262
|
-
function splitScalarEndo(k) {
|
|
4263
|
-
const { n } = CURVE;
|
|
4264
|
-
const { a1, b1, a2, b2, POW_2_128 } = ENDO;
|
|
4265
|
-
const c1 = divNearest(b2 * k, n);
|
|
4266
|
-
const c2 = divNearest(-b1 * k, n);
|
|
4267
|
-
let k1 = mod(k - c1 * a1 - c2 * a2, n);
|
|
4268
|
-
let k2 = mod(-c1 * b1 - c2 * b2, n);
|
|
4269
|
-
const k1neg = k1 > POW_2_128;
|
|
4270
|
-
const k2neg = k2 > POW_2_128;
|
|
4271
|
-
if (k1neg)
|
|
4272
|
-
k1 = n - k1;
|
|
4273
|
-
if (k2neg)
|
|
4274
|
-
k2 = n - k2;
|
|
4275
|
-
if (k1 > POW_2_128 || k2 > POW_2_128) {
|
|
4276
|
-
throw new Error("splitScalarEndo: Endomorphism failed, k=" + k);
|
|
4277
|
-
}
|
|
4278
|
-
return { k1neg, k1, k2neg, k2 };
|
|
4299
|
+
function bits2int_2(bytes2) {
|
|
4300
|
+
const delta = bytes2.length * 8 - groupLen * 8;
|
|
4301
|
+
const num = bytesToNumber(bytes2);
|
|
4302
|
+
return delta > 0 ? num >> BigInt(delta) : num;
|
|
4279
4303
|
}
|
|
4280
|
-
function truncateHash(hash2) {
|
|
4304
|
+
function truncateHash(hash2, truncateOnly = false) {
|
|
4305
|
+
const h = bits2int_2(hash2);
|
|
4306
|
+
if (truncateOnly)
|
|
4307
|
+
return h;
|
|
4281
4308
|
const { n } = CURVE;
|
|
4282
|
-
|
|
4283
|
-
const delta = byteLength * 8 - 256;
|
|
4284
|
-
let h = bytesToNumber(hash2);
|
|
4285
|
-
if (delta > 0)
|
|
4286
|
-
h = h >> BigInt(delta);
|
|
4287
|
-
if (h >= n)
|
|
4288
|
-
h -= n;
|
|
4289
|
-
return h;
|
|
4309
|
+
return h >= n ? h - n : h;
|
|
4290
4310
|
}
|
|
4291
4311
|
var _sha256Sync;
|
|
4292
4312
|
var _hmacSha256Sync;
|
|
4293
4313
|
var HmacDrbg = class {
|
|
4294
|
-
constructor() {
|
|
4295
|
-
this.
|
|
4296
|
-
this.
|
|
4314
|
+
constructor(hashLen2, qByteLen) {
|
|
4315
|
+
this.hashLen = hashLen2;
|
|
4316
|
+
this.qByteLen = qByteLen;
|
|
4317
|
+
if (typeof hashLen2 !== "number" || hashLen2 < 2)
|
|
4318
|
+
throw new Error("hashLen must be a number");
|
|
4319
|
+
if (typeof qByteLen !== "number" || qByteLen < 2)
|
|
4320
|
+
throw new Error("qByteLen must be a number");
|
|
4321
|
+
this.v = new Uint8Array(hashLen2).fill(1);
|
|
4322
|
+
this.k = new Uint8Array(hashLen2).fill(0);
|
|
4297
4323
|
this.counter = 0;
|
|
4298
4324
|
}
|
|
4299
4325
|
hmac(...values) {
|
|
@@ -4330,14 +4356,28 @@ zoo`.split("\n");
|
|
|
4330
4356
|
}
|
|
4331
4357
|
async generate() {
|
|
4332
4358
|
this.incr();
|
|
4333
|
-
|
|
4334
|
-
|
|
4359
|
+
let len = 0;
|
|
4360
|
+
const out = [];
|
|
4361
|
+
while (len < this.qByteLen) {
|
|
4362
|
+
this.v = await this.hmac(this.v);
|
|
4363
|
+
const sl = this.v.slice();
|
|
4364
|
+
out.push(sl);
|
|
4365
|
+
len += this.v.length;
|
|
4366
|
+
}
|
|
4367
|
+
return concatBytes(...out);
|
|
4335
4368
|
}
|
|
4336
4369
|
generateSync() {
|
|
4337
4370
|
this.checkSync();
|
|
4338
4371
|
this.incr();
|
|
4339
|
-
|
|
4340
|
-
|
|
4372
|
+
let len = 0;
|
|
4373
|
+
const out = [];
|
|
4374
|
+
while (len < this.qByteLen) {
|
|
4375
|
+
this.v = this.hmacSync(this.v);
|
|
4376
|
+
const sl = this.v.slice();
|
|
4377
|
+
out.push(sl);
|
|
4378
|
+
len += this.v.length;
|
|
4379
|
+
}
|
|
4380
|
+
return concatBytes(...out);
|
|
4341
4381
|
}
|
|
4342
4382
|
};
|
|
4343
4383
|
function isWithinCurveOrder(num) {
|
|
@@ -4346,20 +4386,25 @@ zoo`.split("\n");
|
|
|
4346
4386
|
function isValidFieldElement(num) {
|
|
4347
4387
|
return _0n < num && num < CURVE.P;
|
|
4348
4388
|
}
|
|
4349
|
-
function kmdToSig(kBytes, m, d) {
|
|
4350
|
-
const
|
|
4389
|
+
function kmdToSig(kBytes, m, d, lowS = true) {
|
|
4390
|
+
const { n } = CURVE;
|
|
4391
|
+
const k = truncateHash(kBytes, true);
|
|
4351
4392
|
if (!isWithinCurveOrder(k))
|
|
4352
4393
|
return;
|
|
4353
|
-
const
|
|
4394
|
+
const kinv = invert(k, n);
|
|
4354
4395
|
const q = Point.BASE.multiply(k);
|
|
4355
4396
|
const r = mod(q.x, n);
|
|
4356
4397
|
if (r === _0n)
|
|
4357
4398
|
return;
|
|
4358
|
-
const s = mod(
|
|
4399
|
+
const s = mod(kinv * mod(m + d * r, n), n);
|
|
4359
4400
|
if (s === _0n)
|
|
4360
4401
|
return;
|
|
4361
|
-
|
|
4362
|
-
|
|
4402
|
+
let sig = new Signature(r, s);
|
|
4403
|
+
let recovery = (q.x === sig.r ? 0 : 2) | Number(q.y & _1n);
|
|
4404
|
+
if (lowS && sig.hasHighS()) {
|
|
4405
|
+
sig = sig.normalizeS();
|
|
4406
|
+
recovery ^= 1;
|
|
4407
|
+
}
|
|
4363
4408
|
return { sig, recovery };
|
|
4364
4409
|
}
|
|
4365
4410
|
function normalizePrivateKey(key) {
|
|
@@ -4369,11 +4414,11 @@ zoo`.split("\n");
|
|
|
4369
4414
|
} else if (typeof key === "number" && Number.isSafeInteger(key) && key > 0) {
|
|
4370
4415
|
num = BigInt(key);
|
|
4371
4416
|
} else if (typeof key === "string") {
|
|
4372
|
-
if (key.length !==
|
|
4417
|
+
if (key.length !== 2 * groupLen)
|
|
4373
4418
|
throw new Error("Expected 32 bytes of private key");
|
|
4374
4419
|
num = hexToNumber(key);
|
|
4375
4420
|
} else if (key instanceof Uint8Array) {
|
|
4376
|
-
if (key.length !==
|
|
4421
|
+
if (key.length !== groupLen)
|
|
4377
4422
|
throw new Error("Expected 32 bytes of private key");
|
|
4378
4423
|
num = bytesToNumber(key);
|
|
4379
4424
|
} else {
|
|
@@ -4410,9 +4455,9 @@ zoo`.split("\n");
|
|
|
4410
4455
|
const str = typeof item === "string";
|
|
4411
4456
|
const len = (arr || str) && item.length;
|
|
4412
4457
|
if (arr)
|
|
4413
|
-
return len ===
|
|
4458
|
+
return len === compressedLen || len === uncompressedLen;
|
|
4414
4459
|
if (str)
|
|
4415
|
-
return len ===
|
|
4460
|
+
return len === compressedLen * 2 || len === uncompressedLen * 2;
|
|
4416
4461
|
if (item instanceof Point)
|
|
4417
4462
|
return true;
|
|
4418
4463
|
return false;
|
|
@@ -4427,7 +4472,7 @@ zoo`.split("\n");
|
|
|
4427
4472
|
return b.multiply(normalizePrivateKey(privateA)).toRawBytes(isCompressed);
|
|
4428
4473
|
}
|
|
4429
4474
|
function bits2int(bytes2) {
|
|
4430
|
-
const slice = bytes2.length >
|
|
4475
|
+
const slice = bytes2.length > fieldLen ? bytes2.slice(0, fieldLen) : bytes2;
|
|
4431
4476
|
return bytesToNumber(slice);
|
|
4432
4477
|
}
|
|
4433
4478
|
function bits2octets(bytes2) {
|
|
@@ -4446,10 +4491,10 @@ zoo`.split("\n");
|
|
|
4446
4491
|
const seedArgs = [int2octets(d), bits2octets(h1)];
|
|
4447
4492
|
if (extraEntropy != null) {
|
|
4448
4493
|
if (extraEntropy === true)
|
|
4449
|
-
extraEntropy = utils.randomBytes(
|
|
4494
|
+
extraEntropy = utils.randomBytes(fieldLen);
|
|
4450
4495
|
const e = ensureBytes(extraEntropy);
|
|
4451
|
-
if (e.length !==
|
|
4452
|
-
throw new Error(
|
|
4496
|
+
if (e.length !== fieldLen)
|
|
4497
|
+
throw new Error(`sign: Expected ${fieldLen} bytes of extra data`);
|
|
4453
4498
|
seedArgs.push(e);
|
|
4454
4499
|
}
|
|
4455
4500
|
const seed = concatBytes(...seedArgs);
|
|
@@ -4457,21 +4502,17 @@ zoo`.split("\n");
|
|
|
4457
4502
|
return { seed, m, d };
|
|
4458
4503
|
}
|
|
4459
4504
|
function finalizeSig(recSig, opts) {
|
|
4460
|
-
|
|
4461
|
-
const {
|
|
4462
|
-
if (canonical && sig.hasHighS()) {
|
|
4463
|
-
sig = sig.normalizeS();
|
|
4464
|
-
recovery ^= 1;
|
|
4465
|
-
}
|
|
4505
|
+
const { sig, recovery } = recSig;
|
|
4506
|
+
const { der, recovered } = Object.assign({ canonical: true, der: true }, opts);
|
|
4466
4507
|
const hashed = der ? sig.toDERRawBytes() : sig.toCompactRawBytes();
|
|
4467
4508
|
return recovered ? [hashed, recovery] : hashed;
|
|
4468
4509
|
}
|
|
4469
4510
|
function signSync(msgHash, privKey, opts = {}) {
|
|
4470
4511
|
const { seed, m, d } = initSigArgs(msgHash, privKey, opts.extraEntropy);
|
|
4471
|
-
|
|
4472
|
-
const drbg = new HmacDrbg();
|
|
4512
|
+
const drbg = new HmacDrbg(hashLen, groupLen);
|
|
4473
4513
|
drbg.reseedSync(seed);
|
|
4474
|
-
|
|
4514
|
+
let sig;
|
|
4515
|
+
while (!(sig = kmdToSig(drbg.generateSync(), m, d, opts.canonical)))
|
|
4475
4516
|
drbg.reseedSync();
|
|
4476
4517
|
return finalizeSig(sig, opts);
|
|
4477
4518
|
}
|
|
@@ -4672,8 +4713,10 @@ zoo`.split("\n");
|
|
|
4672
4713
|
_normalizePrivateKey: normalizePrivateKey,
|
|
4673
4714
|
hashToPrivateKey: (hash2) => {
|
|
4674
4715
|
hash2 = ensureBytes(hash2);
|
|
4675
|
-
|
|
4676
|
-
|
|
4716
|
+
const minLen = groupLen + 8;
|
|
4717
|
+
if (hash2.length < minLen || hash2.length > 1024) {
|
|
4718
|
+
throw new Error(`Expected valid bytes of private key as per FIPS 186`);
|
|
4719
|
+
}
|
|
4677
4720
|
const num = mod(bytesToNumber(hash2), CURVE.n - _1n) + _1n;
|
|
4678
4721
|
return numTo32b(num);
|
|
4679
4722
|
},
|
|
@@ -4687,8 +4730,12 @@ zoo`.split("\n");
|
|
|
4687
4730
|
throw new Error("The environment doesn't have randomBytes function");
|
|
4688
4731
|
}
|
|
4689
4732
|
},
|
|
4690
|
-
randomPrivateKey: () =>
|
|
4691
|
-
|
|
4733
|
+
randomPrivateKey: () => utils.hashToPrivateKey(utils.randomBytes(groupLen + 8)),
|
|
4734
|
+
precompute(windowSize = 8, point = Point.BASE) {
|
|
4735
|
+
const cached = point === Point.BASE ? point : new Point(point.x, point.y);
|
|
4736
|
+
cached._setWindowSize(windowSize);
|
|
4737
|
+
cached.multiply(_3n);
|
|
4738
|
+
return cached;
|
|
4692
4739
|
},
|
|
4693
4740
|
sha256: async (...messages) => {
|
|
4694
4741
|
if (crypto2.web) {
|
|
@@ -4740,12 +4787,7 @@ zoo`.split("\n");
|
|
|
4740
4787
|
}
|
|
4741
4788
|
return _sha256Sync(tagP, ...messages);
|
|
4742
4789
|
},
|
|
4743
|
-
|
|
4744
|
-
const cached = point === Point.BASE ? point : new Point(point.x, point.y);
|
|
4745
|
-
cached._setWindowSize(windowSize);
|
|
4746
|
-
cached.multiply(_3n);
|
|
4747
|
-
return cached;
|
|
4748
|
-
}
|
|
4790
|
+
_JacobianPoint: JacobianPoint
|
|
4749
4791
|
};
|
|
4750
4792
|
Object.defineProperties(utils, {
|
|
4751
4793
|
sha256Sync: {
|
|
@@ -7004,7 +7046,11 @@ zoo`.split("\n");
|
|
|
7004
7046
|
}
|
|
7005
7047
|
opt.privateKey = added;
|
|
7006
7048
|
} else {
|
|
7007
|
-
|
|
7049
|
+
const added = Point.fromHex(this.pubKey).add(Point.fromPrivateKey(childTweak));
|
|
7050
|
+
if (added.equals(Point.ZERO)) {
|
|
7051
|
+
throw new Error("The tweak was equal to negative P, which made the result key invalid");
|
|
7052
|
+
}
|
|
7053
|
+
opt.publicKey = added.toRawBytes(true);
|
|
7008
7054
|
}
|
|
7009
7055
|
return new HDKey(opt);
|
|
7010
7056
|
} catch (err) {
|
|
@@ -7059,8 +7105,8 @@ zoo`.split("\n");
|
|
|
7059
7105
|
};
|
|
7060
7106
|
|
|
7061
7107
|
// nip06.ts
|
|
7062
|
-
function privateKeyFromSeedWords(mnemonic) {
|
|
7063
|
-
let root = HDKey.fromMasterSeed((0, import_bip39.mnemonicToSeedSync)(mnemonic));
|
|
7108
|
+
function privateKeyFromSeedWords(mnemonic, passphrase) {
|
|
7109
|
+
let root = HDKey.fromMasterSeed((0, import_bip39.mnemonicToSeedSync)(mnemonic, passphrase));
|
|
7064
7110
|
let privateKey = root.derive(`m/44'/1237'/0'/0/0`).privateKey;
|
|
7065
7111
|
if (!privateKey)
|
|
7066
7112
|
throw new Error("could not derive private key");
|
|
@@ -7084,8 +7130,9 @@ zoo`.split("\n");
|
|
|
7084
7130
|
nsecEncode: () => nsecEncode
|
|
7085
7131
|
});
|
|
7086
7132
|
init_define_process();
|
|
7133
|
+
var Bech32MaxSize = 5e3;
|
|
7087
7134
|
function decode(nip19) {
|
|
7088
|
-
let { prefix, words } = bech32.decode(nip19,
|
|
7135
|
+
let { prefix, words } = bech32.decode(nip19, Bech32MaxSize);
|
|
7089
7136
|
let data = new Uint8Array(bech32.fromWords(words));
|
|
7090
7137
|
if (prefix === "nprofile") {
|
|
7091
7138
|
let tlv = parseTLV(data);
|
|
@@ -7147,7 +7194,7 @@ zoo`.split("\n");
|
|
|
7147
7194
|
function encodeBytes(prefix, hex2) {
|
|
7148
7195
|
let data = utils.hexToBytes(hex2);
|
|
7149
7196
|
let words = bech32.toWords(data);
|
|
7150
|
-
return bech32.encode(prefix, words,
|
|
7197
|
+
return bech32.encode(prefix, words, Bech32MaxSize);
|
|
7151
7198
|
}
|
|
7152
7199
|
function nprofileEncode(profile) {
|
|
7153
7200
|
let data = encodeTLV({
|
|
@@ -7155,7 +7202,7 @@ zoo`.split("\n");
|
|
|
7155
7202
|
1: (profile.relays || []).map((url) => utf8Encoder.encode(url))
|
|
7156
7203
|
});
|
|
7157
7204
|
let words = bech32.toWords(data);
|
|
7158
|
-
return bech32.encode("nprofile", words,
|
|
7205
|
+
return bech32.encode("nprofile", words, Bech32MaxSize);
|
|
7159
7206
|
}
|
|
7160
7207
|
function neventEncode(event) {
|
|
7161
7208
|
let data = encodeTLV({
|
|
@@ -7163,7 +7210,7 @@ zoo`.split("\n");
|
|
|
7163
7210
|
1: (event.relays || []).map((url) => utf8Encoder.encode(url))
|
|
7164
7211
|
});
|
|
7165
7212
|
let words = bech32.toWords(data);
|
|
7166
|
-
return bech32.encode("nevent", words,
|
|
7213
|
+
return bech32.encode("nevent", words, Bech32MaxSize);
|
|
7167
7214
|
}
|
|
7168
7215
|
function encodeTLV(tlv) {
|
|
7169
7216
|
let entries = [];
|